From d6aaf610fa97b76077cacade2fca306dbe1e8c80 Mon Sep 17 00:00:00 2001 From: Subham Sinha <35077434+sinhasubham@users.noreply.github.com> Date: Tue, 2 Jun 2026 18:35:38 +0530 Subject: [PATCH 001/174] feat(spanner): add asynchronous code snippets and minor cleanup changes (#17337) ### 1. Partition Deserialization Simplification Addressing post merge minor comments from: https://github.com/googleapis/google-cloud-python/pull/17014 2. Asynchronous Code Snippets & Integration Tests New Async Samples (async_snippets.py): Added standard asynchronous code snippets. New Integration Tests (async_snippets_test.py): Introduced integration tests using pytest-asyncio to sequentially execute and assert the output of all five asynchronous code snippets against a mock/live instance. --- .../cloud/spanner_dbapi/partition_helper.py | 21 +--- .../samples/samples/async_snippets.py | 117 ++++++++++++++++++ .../samples/samples/async_snippets_test.py | 77 ++++++++++++ .../test_dbapi_partition_query.py | 3 +- .../spanner_dbapi/test_partition_helper.py | 3 +- 5 files changed, 197 insertions(+), 24 deletions(-) create mode 100644 packages/google-cloud-spanner/samples/samples/async_snippets.py create mode 100644 packages/google-cloud-spanner/samples/samples/async_snippets_test.py diff --git a/packages/google-cloud-spanner/google/cloud/spanner_dbapi/partition_helper.py b/packages/google-cloud-spanner/google/cloud/spanner_dbapi/partition_helper.py index 84fb66068a80..bbb5288f8e22 100644 --- a/packages/google-cloud-spanner/google/cloud/spanner_dbapi/partition_helper.py +++ b/packages/google-cloud-spanner/google/cloud/spanner_dbapi/partition_helper.py @@ -90,23 +90,6 @@ def _deserialize_value(val: Any) -> Any: return val -def _unpack_value_pb(value): - which = value.WhichOneof("kind") - if which == "null_value": - return None - elif which == "number_value": - return value.number_value - elif which == "string_value": - return value.string_value - elif which == "bool_value": - return value.bool_value - elif which == "struct_value": - return {k: _unpack_value_pb(v) for k, v in value.struct_value.fields.items()} - elif which == "list_value": - return [_unpack_value_pb(v) for v in value.list_value.values] - return None - - def decode_from_string(encoded_partition_id): gzip_bytes = base64.b64decode(bytes(encoded_partition_id, "utf-8")) partition_id_bytes = gzip.decompress(gzip_bytes) @@ -124,9 +107,7 @@ def decode_from_string(encoded_partition_id): if "query" in partition_result and "params" in partition_result["query"]: params_pb = partition_result["query"]["params"] if params_pb: - partition_result["query"]["params"] = { - k: _unpack_value_pb(v) for k, v in params_pb.fields.items() - } + partition_result["query"]["params"] = MessageToDict(params_pb) return PartitionId(btid, partition_result) diff --git a/packages/google-cloud-spanner/samples/samples/async_snippets.py b/packages/google-cloud-spanner/samples/samples/async_snippets.py new file mode 100644 index 000000000000..6ec5580447eb --- /dev/null +++ b/packages/google-cloud-spanner/samples/samples/async_snippets.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python + +# Copyright 2026 Google LLC All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""This application demonstrates how to do basic asynchronous operations using +Cloud Spanner. +""" + +import asyncio +from google.cloud.spanner_v1 import AsyncClient +from google.cloud.spanner_v1 import KeySet + +# [START spanner_async_create_client] +async def async_create_client(instance_id, database_id): + """Instantiates an asynchronous Spanner client.""" + spanner_client = AsyncClient() + instance = spanner_client.instance(instance_id) + database = instance.database(database_id) + + print("Async Spanner client instantiated successfully.") + return database +# [END spanner_async_create_client] + + +# [START spanner_async_query_data] +async def async_query_data(instance_id, database_id): + """Queries sample data from the database using asynchronous SQL.""" + spanner_client = AsyncClient() + instance = spanner_client.instance(instance_id) + database = instance.database(database_id) + + async with database.snapshot() as snapshot: + results = await snapshot.execute_sql( + "SELECT SingerId, AlbumId, AlbumTitle FROM Albums" + ) + + async for row in results: + print("SingerId: {}, AlbumId: {}, AlbumTitle: {}".format(*row)) +# [END spanner_async_query_data] + + +# [START spanner_async_insert_data] +async def async_insert_data(instance_id, database_id): + """Inserts sample data into the database using DML asynchronously.""" + spanner_client = AsyncClient() + instance = spanner_client.instance(instance_id) + database = instance.database(database_id) + + async def insert_singers(transaction): + dml = ( + "INSERT INTO Singers (SingerId, FirstName, LastName) VALUES " + "(12, 'Melissa', 'Garcia'), " + "(13, 'Russell', 'Morales')" + ) + await transaction.execute_update(dml) + + await database.run_in_transaction(insert_singers) + print("Async DML Insert transaction complete.") +# [END spanner_async_insert_data] + + +# [START spanner_async_read_write_transaction] +async def async_read_write_transaction(instance_id, database_id): + """Performs an asynchronous read-write transaction.""" + spanner_client = AsyncClient() + instance = spanner_client.instance(instance_id) + database = instance.database(database_id) + + async def update_singer_lastname(transaction): + # Retrieve current name + results = await transaction.execute_sql( + "SELECT SingerId, FirstName, LastName FROM Singers WHERE SingerId = 12" + ) + async for row in results: + print("Before Update - SingerId: {}, FirstName: {}, LastName: {}".format(*row)) + + # Update LastName + await transaction.execute_update( + "UPDATE Singers SET LastName = 'Jackson' WHERE SingerId = 12" + ) + + await database.run_in_transaction(update_singer_lastname) + print("Async read-write transaction complete.") +# [END spanner_async_read_write_transaction] + + +# [START spanner_async_read_only_transaction] +async def async_read_only_transaction(instance_id, database_id): + """Performs an asynchronous read-only transaction.""" + spanner_client = AsyncClient() + instance = spanner_client.instance(instance_id) + database = instance.database(database_id) + + async with database.snapshot() as snapshot: + # Execute a read using standard KeySet + keyset = KeySet(all_=True) + results = await snapshot.read( + table="Singers", + columns=("SingerId", "FirstName", "LastName"), + keyset=keyset, + ) + + async for row in results: + print("Read Row - SingerId: {}, FirstName: {}, LastName: {}".format(*row)) +# [END spanner_async_read_only_transaction] diff --git a/packages/google-cloud-spanner/samples/samples/async_snippets_test.py b/packages/google-cloud-spanner/samples/samples/async_snippets_test.py new file mode 100644 index 000000000000..8405e1c8f22f --- /dev/null +++ b/packages/google-cloud-spanner/samples/samples/async_snippets_test.py @@ -0,0 +1,77 @@ +# Copyright 2026 Google LLC All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pytest +import async_snippets + +@pytest.fixture(scope="module") +def database_ddl(): + """DDL statements to set up the database for testing async snippets.""" + return [ + """CREATE TABLE Singers ( + SingerId INT64 NOT NULL, + FirstName STRING(1024), + LastName STRING(1024), + SingerInfo BYTES(MAX) + ) PRIMARY KEY (SingerId)""", + """CREATE TABLE Albums ( + SingerId INT64 NOT NULL, + AlbumId INT64 NOT NULL, + AlbumTitle STRING(MAX) + ) PRIMARY KEY (SingerId, AlbumId), + INTERLEAVE IN PARENT Singers ON DELETE CASCADE""" + ] + + +@pytest.mark.asyncio +async def test_async_snippets_flow(capsys, instance_id, sample_database): + # 1. Test Async Spanner Client Creation + db = await async_snippets.async_create_client(instance_id, sample_database.database_id) + assert db is not None + out, _ = capsys.readouterr() + assert "Async Spanner client instantiated successfully." in out + + # 2. Test Async DML Insert + await async_snippets.async_insert_data(instance_id, sample_database.database_id) + out, _ = capsys.readouterr() + assert "Async DML Insert transaction complete." in out + + # 3. Seed additional albums data via sync batch write for query testing + with sample_database.batch() as batch: + batch.insert( + table="Albums", + columns=("SingerId", "AlbumId", "AlbumTitle"), + values=[ + (12, 1, "Total Junk"), + (13, 2, "Go, Go, Go"), + ], + ) + + # 4. Test Async Query Data + await async_snippets.async_query_data(instance_id, sample_database.database_id) + out, _ = capsys.readouterr() + assert "SingerId: 12, AlbumId: 1, AlbumTitle: Total Junk" in out + assert "SingerId: 13, AlbumId: 2, AlbumTitle: Go, Go, Go" in out + + # 5. Test Async Read-Write Transaction + await async_snippets.async_read_write_transaction(instance_id, sample_database.database_id) + out, _ = capsys.readouterr() + assert "Before Update - SingerId: 12, FirstName: Melissa, LastName: Garcia" in out + assert "Async read-write transaction complete." in out + + # 6. Test Async Read-Only Transaction + await async_snippets.async_read_only_transaction(instance_id, sample_database.database_id) + out, _ = capsys.readouterr() + assert "Read Row - SingerId: 12, FirstName: Melissa, LastName: Jackson" in out + assert "Read Row - SingerId: 13, FirstName: Russell, LastName: Morales" in out diff --git a/packages/google-cloud-spanner/tests/mockserver_tests/test_dbapi_partition_query.py b/packages/google-cloud-spanner/tests/mockserver_tests/test_dbapi_partition_query.py index 7eea593e7b54..b3fd6fb4db1c 100644 --- a/packages/google-cloud-spanner/tests/mockserver_tests/test_dbapi_partition_query.py +++ b/packages/google-cloud-spanner/tests/mockserver_tests/test_dbapi_partition_query.py @@ -1,5 +1,4 @@ -# Copyright 2024 Google LLC All rights reserved. -# +# Copyright 2026 Google LLC All rights reserved. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/packages/google-cloud-spanner/tests/unit/spanner_dbapi/test_partition_helper.py b/packages/google-cloud-spanner/tests/unit/spanner_dbapi/test_partition_helper.py index a5a8a4809d62..def5530a64e1 100644 --- a/packages/google-cloud-spanner/tests/unit/spanner_dbapi/test_partition_helper.py +++ b/packages/google-cloud-spanner/tests/unit/spanner_dbapi/test_partition_helper.py @@ -1,5 +1,4 @@ -# Copyright 2024 Google LLC All rights reserved. -# +# Copyright 2026 Google LLC All rights reserved. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at From b6e857d7eadaf6196943562da7a990e77e66e9fa Mon Sep 17 00:00:00 2001 From: Heba Alazzeh <137334116+hebaalazzeh@users.noreply.github.com> Date: Tue, 2 Jun 2026 07:56:51 -0700 Subject: [PATCH 002/174] chore: add prerelease_deps nox sessions (#17267) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR implements nox sessions for `core_deps_from_source` and `prerelease_deps`. Fixes #16013🦕 --- packages/google-auth/noxfile.py | 94 +++++++++++++++++++++++++++++---- 1 file changed, 85 insertions(+), 9 deletions(-) diff --git a/packages/google-auth/noxfile.py b/packages/google-auth/noxfile.py index 70c113a98014..5962f96bf094 100644 --- a/packages/google-auth/noxfile.py +++ b/packages/google-auth/noxfile.py @@ -14,6 +14,7 @@ import os import pathlib +import re import shutil import nox @@ -33,6 +34,12 @@ ] DEFAULT_PYTHON_VERSION = "3.14" + +# TODO(https://github.com/googleapis/gapic-generator-python/issues/2450): +# Switch this to Python 3.15 alpha1 +# https://peps.python.org/pep-0790/ +PREVIEW_PYTHON_VERSION = "3.14" + UNIT_TEST_PYTHON_VERSIONS = [ "3.10", "3.11", @@ -42,6 +49,15 @@ ] ALL_PYTHON = UNIT_TEST_PYTHON_VERSIONS.copy() +UNIT_TEST_STANDARD_DEPENDENCIES = [ + "mock", + "asyncmock", + "pytest", + "pytest-cov", + "pytest-asyncio", +] +UNIT_TEST_EXTERNAL_DEPENDENCIES: list[str] = [] + # Error if a python version is missing nox.options.error_on_missing_interpreters = True @@ -220,16 +236,78 @@ def docfx(session): session.skip("This package does not have documentation in cloud.google.com") -@nox.session(python=DEFAULT_PYTHON_VERSION) -def prerelease_deps(session): - """Run all tests with pre-release versions of dependencies installed +@nox.session(python=PREVIEW_PYTHON_VERSION) +@nox.parametrize( + "protobuf_implementation", + ["python", "upb"], +) +def prerelease_deps(session, protobuf_implementation): + """ + Run all tests with pre-release versions of dependencies installed rather than the standard non pre-release versions. Pre-release versions can be installed using `pip install --pre `. """ - # TODO(https://github.com/googleapis/google-cloud-python/issues/16013): - # Add prerelease tests - session.skip("Prerelease tests are not yet supported") + + # Install all dependencies + session.install("-e", ".[testing,rsa]") + session.install("oauth2client") + + # Install dependencies for the unit test environment + unit_deps_all = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_EXTERNAL_DEPENDENCIES + session.install(*unit_deps_all) + + # Because we test minimum dependency versions on the minimum Python + # version, the first version we test with in the unit tests sessions has a + # constraints file containing all dependencies and extras. + with open( + CURRENT_DIRECTORY / "testing" / f"constraints-{ALL_PYTHON[0]}.txt", + encoding="utf-8", + ) as constraints_file: + constraints_text = constraints_file.read() + + # Ignore leading whitespace and comment lines. + constraints_deps = [ + match.group(1) + for match in re.finditer( + r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE + ) + ] + + # Install dependencies specified in `testing/constraints-X.txt`. + session.install(*constraints_deps) + + # Note: If a dependency is added to the `prerel_deps` list, + # the `core_dependencies_from_source` list in the `core_deps_from_source` + # nox session should also be updated. + prerel_deps = [ + # Note: We use --no-deps below to prevent prerelease updates. + # However, aiohttp 3.10+ introduced aiohappyeyeballs as a strict requirement. + # We must manually inject it here so the aiohttp pre-release doesn't crash on import. + "aiohappyeyeballs", + "aiohttp", + "cryptography", + "grpcio", + "pyasn1-modules", + "pyjwt", + "pyopenssl", + "requests", + "rsa", + "urllib3", + ] + + for dep in prerel_deps: + session.install("--pre", "--no-deps", "--ignore-installed", dep) + print(f"Installed {dep}") + + session.run( + "py.test", + "tests", + "tests_async", + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) @nox.session(python=DEFAULT_PYTHON_VERSION) @@ -237,6 +315,4 @@ def core_deps_from_source(session): """Run all tests with core dependencies installed from source rather than pulling the dependencies from PyPI. """ - # TODO(https://github.com/googleapis/google-cloud-python/issues/16013): - # Add prerelease tests - session.skip("Prerelease tests are not yet supported") + session.skip("Skipping: Not applicable for google-auth.") From 7f988fff491705015f3ebd1ae3e2552647b6bf42 Mon Sep 17 00:00:00 2001 From: Chalmer Lowe Date: Tue, 2 Jun 2026 13:27:21 -0400 Subject: [PATCH 003/174] chore(ndb): add missing format session and modernize lint and blacken sessions (#17342) This PR adds missing `format` nox session and modernizes `lint` and `blacken` sessions to use Ruff for this package. ### Additional changes: * Also marks `blacken` as deprecated. * Runs Ruff formatter and thus incorporates linting changes. Changes to each nox session are based on the versions found in the **gapic-generator** [`noxfile.py.j2` template](https://github.com/googleapis/google-cloud-python/blob/main/packages/gapic-generator/gapic/templates/noxfile.py.j2). Fixes #17049 --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- .../google/cloud/ndb/__init__.py | 207 +++++++++--------- .../google/cloud/ndb/_cache.py | 4 +- .../google/cloud/ndb/_datastore_api.py | 20 +- .../google/cloud/ndb/_datastore_query.py | 11 +- .../google/cloud/ndb/_datastore_types.py | 8 +- .../google/cloud/ndb/_eventloop.py | 6 +- .../google-cloud-ndb/google/cloud/ndb/_gql.py | 5 +- .../cloud/ndb/_legacy_protocol_buffer.py | 1 - .../google/cloud/ndb/_options.py | 7 +- .../google/cloud/ndb/_remote.py | 3 +- .../google/cloud/ndb/_retry.py | 6 +- .../google/cloud/ndb/_transaction.py | 10 +- .../google/cloud/ndb/blobstore.py | 6 +- .../google/cloud/ndb/client.py | 11 +- .../google/cloud/ndb/context.py | 3 +- .../google/cloud/ndb/django_middleware.py | 1 - .../google/cloud/ndb/exceptions.py | 1 - .../google/cloud/ndb/global_cache.py | 6 +- .../google-cloud-ndb/google/cloud/ndb/key.py | 23 +- .../google/cloud/ndb/metadata.py | 4 +- .../google/cloud/ndb/model.py | 73 +++--- .../google/cloud/ndb/msgprop.py | 1 - .../google/cloud/ndb/polymodel.py | 1 - .../google/cloud/ndb/query.py | 44 ++-- .../google/cloud/ndb/stats.py | 1 - .../google/cloud/ndb/tasklets.py | 5 +- .../google/cloud/ndb/utils.py | 1 - packages/google-cloud-ndb/noxfile.py | 84 +++++-- packages/google-cloud-ndb/setup.py | 8 +- packages/google-cloud-ndb/tests/conftest.py | 13 +- .../google-cloud-ndb/tests/system/conftest.py | 6 +- .../tests/system/test_crud.py | 9 +- .../tests/system/test_metadata.py | 5 +- .../tests/system/test_misc.py | 10 +- .../tests/system/test_query.py | 21 +- .../tests/unit/test__batch.py | 3 +- .../tests/unit/test__cache.py | 4 +- .../tests/unit/test__datastore_api.py | 14 +- .../tests/unit/test__datastore_query.py | 7 +- .../tests/unit/test__datastore_types.py | 3 +- .../tests/unit/test__eventloop.py | 4 +- .../google-cloud-ndb/tests/unit/test__gql.py | 17 +- .../tests/unit/test__legacy_entity_pb.py | 13 +- .../tests/unit/test__options.py | 4 +- .../tests/unit/test__remote.py | 4 +- .../tests/unit/test__retry.py | 6 +- .../tests/unit/test__transaction.py | 7 +- .../tests/unit/test_blobstore.py | 4 +- .../tests/unit/test_client.py | 9 +- .../tests/unit/test_concurrency.py | 3 +- .../tests/unit/test_context.py | 9 +- .../tests/unit/test_global_cache.py | 1 - .../google-cloud-ndb/tests/unit/test_key.py | 11 +- .../tests/unit/test_metadata.py | 4 +- .../google-cloud-ndb/tests/unit/test_model.py | 43 ++-- .../tests/unit/test_polymodel.py | 6 +- .../google-cloud-ndb/tests/unit/test_query.py | 14 +- .../google-cloud-ndb/tests/unit/test_stats.py | 5 +- .../tests/unit/test_tasklets.py | 10 +- .../google-cloud-ndb/tests/unit/test_utils.py | 1 - 60 files changed, 394 insertions(+), 437 deletions(-) diff --git a/packages/google-cloud-ndb/google/cloud/ndb/__init__.py b/packages/google-cloud-ndb/google/cloud/ndb/__init__.py index 3bd2c035ee6b..153ff9d1db7c 100644 --- a/packages/google-cloud-ndb/google/cloud/ndb/__init__.py +++ b/packages/google-cloud-ndb/google/cloud/ndb/__init__.py @@ -25,110 +25,115 @@ __version__: str = version.__version__ +from google.cloud.ndb._datastore_api import EVENTUAL, EVENTUAL_CONSISTENCY, STRONG +from google.cloud.ndb._datastore_query import Cursor, QueryIterator +from google.cloud.ndb._transaction import ( + in_transaction, + non_transactional, + transaction, + transaction_async, + transactional, + transactional_async, + transactional_tasklet, +) from google.cloud.ndb.client import Client -from google.cloud.ndb.context import AutoBatcher -from google.cloud.ndb.context import Context -from google.cloud.ndb.context import ContextOptions -from google.cloud.ndb.context import get_context -from google.cloud.ndb.context import get_toplevel_context -from google.cloud.ndb.context import TransactionOptions -from google.cloud.ndb._datastore_api import EVENTUAL -from google.cloud.ndb._datastore_api import EVENTUAL_CONSISTENCY -from google.cloud.ndb._datastore_api import STRONG -from google.cloud.ndb._datastore_query import Cursor -from google.cloud.ndb._datastore_query import QueryIterator -from google.cloud.ndb.global_cache import GlobalCache -from google.cloud.ndb.global_cache import MemcacheCache -from google.cloud.ndb.global_cache import RedisCache +from google.cloud.ndb.context import ( + AutoBatcher, + Context, + ContextOptions, + TransactionOptions, + get_context, + get_toplevel_context, +) +from google.cloud.ndb.global_cache import GlobalCache, MemcacheCache, RedisCache from google.cloud.ndb.key import Key -from google.cloud.ndb.model import BlobKey -from google.cloud.ndb.model import BlobKeyProperty -from google.cloud.ndb.model import BlobProperty -from google.cloud.ndb.model import BooleanProperty -from google.cloud.ndb.model import ComputedProperty -from google.cloud.ndb.model import ComputedPropertyError -from google.cloud.ndb.model import DateProperty -from google.cloud.ndb.model import DateTimeProperty -from google.cloud.ndb.model import delete_multi -from google.cloud.ndb.model import delete_multi_async -from google.cloud.ndb.model import Expando -from google.cloud.ndb.model import FloatProperty -from google.cloud.ndb.model import GenericProperty -from google.cloud.ndb.model import GeoPt -from google.cloud.ndb.model import GeoPtProperty -from google.cloud.ndb.model import get_indexes -from google.cloud.ndb.model import get_indexes_async -from google.cloud.ndb.model import get_multi -from google.cloud.ndb.model import get_multi_async -from google.cloud.ndb.model import Index -from google.cloud.ndb.model import IndexProperty -from google.cloud.ndb.model import IndexState -from google.cloud.ndb.model import IntegerProperty -from google.cloud.ndb.model import InvalidPropertyError -from google.cloud.ndb.model import BadProjectionError -from google.cloud.ndb.model import JsonProperty -from google.cloud.ndb.model import KeyProperty -from google.cloud.ndb.model import KindError -from google.cloud.ndb.model import LocalStructuredProperty -from google.cloud.ndb.model import make_connection -from google.cloud.ndb.model import MetaModel -from google.cloud.ndb.model import Model -from google.cloud.ndb.model import ModelAdapter -from google.cloud.ndb.model import ModelAttribute -from google.cloud.ndb.model import ModelKey -from google.cloud.ndb.model import PickleProperty -from google.cloud.ndb.model import Property -from google.cloud.ndb.model import put_multi -from google.cloud.ndb.model import put_multi_async -from google.cloud.ndb.model import ReadonlyPropertyError -from google.cloud.ndb.model import Rollback -from google.cloud.ndb.model import StringProperty -from google.cloud.ndb.model import StructuredProperty -from google.cloud.ndb.model import TextProperty -from google.cloud.ndb.model import TimeProperty -from google.cloud.ndb.model import UnprojectedPropertyError -from google.cloud.ndb.model import User -from google.cloud.ndb.model import UserNotFoundError -from google.cloud.ndb.model import UserProperty +from google.cloud.ndb.model import ( + BadProjectionError, + BlobKey, + BlobKeyProperty, + BlobProperty, + BooleanProperty, + ComputedProperty, + ComputedPropertyError, + DateProperty, + DateTimeProperty, + Expando, + FloatProperty, + GenericProperty, + GeoPt, + GeoPtProperty, + Index, + IndexProperty, + IndexState, + IntegerProperty, + InvalidPropertyError, + JsonProperty, + KeyProperty, + KindError, + LocalStructuredProperty, + MetaModel, + Model, + ModelAdapter, + ModelAttribute, + ModelKey, + PickleProperty, + Property, + ReadonlyPropertyError, + Rollback, + StringProperty, + StructuredProperty, + TextProperty, + TimeProperty, + UnprojectedPropertyError, + User, + UserNotFoundError, + UserProperty, + delete_multi, + delete_multi_async, + get_indexes, + get_indexes_async, + get_multi, + get_multi_async, + make_connection, + put_multi, + put_multi_async, +) from google.cloud.ndb.polymodel import PolyModel -from google.cloud.ndb.query import ConjunctionNode -from google.cloud.ndb.query import AND -from google.cloud.ndb.query import DisjunctionNode -from google.cloud.ndb.query import OR -from google.cloud.ndb.query import FalseNode -from google.cloud.ndb.query import FilterNode -from google.cloud.ndb.query import gql -from google.cloud.ndb.query import Node -from google.cloud.ndb.query import Parameter -from google.cloud.ndb.query import ParameterizedFunction -from google.cloud.ndb.query import ParameterizedThing -from google.cloud.ndb.query import ParameterNode -from google.cloud.ndb.query import PostFilterNode -from google.cloud.ndb.query import Query -from google.cloud.ndb.query import QueryOptions -from google.cloud.ndb.query import RepeatedStructuredPropertyPredicate -from google.cloud.ndb.tasklets import add_flow_exception -from google.cloud.ndb.tasklets import Future -from google.cloud.ndb.tasklets import make_context -from google.cloud.ndb.tasklets import make_default_context -from google.cloud.ndb.tasklets import QueueFuture -from google.cloud.ndb.tasklets import ReducingFuture -from google.cloud.ndb.tasklets import Return -from google.cloud.ndb.tasklets import SerialQueueFuture -from google.cloud.ndb.tasklets import set_context -from google.cloud.ndb.tasklets import sleep -from google.cloud.ndb.tasklets import synctasklet -from google.cloud.ndb.tasklets import tasklet -from google.cloud.ndb.tasklets import toplevel -from google.cloud.ndb.tasklets import wait_all -from google.cloud.ndb.tasklets import wait_any -from google.cloud.ndb._transaction import in_transaction -from google.cloud.ndb._transaction import transaction -from google.cloud.ndb._transaction import transaction_async -from google.cloud.ndb._transaction import transactional -from google.cloud.ndb._transaction import transactional_async -from google.cloud.ndb._transaction import transactional_tasklet -from google.cloud.ndb._transaction import non_transactional +from google.cloud.ndb.query import ( + AND, + OR, + ConjunctionNode, + DisjunctionNode, + FalseNode, + FilterNode, + Node, + Parameter, + ParameterizedFunction, + ParameterizedThing, + ParameterNode, + PostFilterNode, + Query, + QueryOptions, + RepeatedStructuredPropertyPredicate, + gql, +) +from google.cloud.ndb.tasklets import ( + Future, + QueueFuture, + ReducingFuture, + Return, + SerialQueueFuture, + add_flow_exception, + make_context, + make_default_context, + set_context, + sleep, + synctasklet, + tasklet, + toplevel, + wait_all, + wait_any, +) __all__ = [ "__version__", diff --git a/packages/google-cloud-ndb/google/cloud/ndb/_cache.py b/packages/google-cloud-ndb/google/cloud/ndb/_cache.py index 0f49d7329384..7e847ef94555 100644 --- a/packages/google-cloud-ndb/google/cloud/ndb/_cache.py +++ b/packages/google-cloud-ndb/google/cloud/ndb/_cache.py @@ -20,10 +20,8 @@ from google.api_core import retry as core_retry -from google.cloud.ndb import _batch +from google.cloud.ndb import _batch, tasklets, utils from google.cloud.ndb import context as context_module -from google.cloud.ndb import tasklets -from google.cloud.ndb import utils _LOCKED_FOR_READ = b"0-" _LOCKED_FOR_WRITE = b"00" diff --git a/packages/google-cloud-ndb/google/cloud/ndb/_datastore_api.py b/packages/google-cloud-ndb/google/cloud/ndb/_datastore_api.py index 96150e84f971..6e210cccf787 100644 --- a/packages/google-cloud-ndb/google/cloud/ndb/_datastore_api.py +++ b/packages/google-cloud-ndb/google/cloud/ndb/_datastore_api.py @@ -14,25 +14,27 @@ """Functions that interact with Datastore backend.""" -import grpc import itertools import logging +import grpc from google.api_core import exceptions as core_exceptions from google.api_core import gapic_v1 from google.cloud.datastore import helpers from google.cloud.datastore_v1.types import datastore as datastore_pb2 from google.cloud.datastore_v1.types import entity as entity_pb2 +from google.cloud.ndb import ( + _batch, + _cache, + _eventloop, + _options, + _remote, + _retry, + tasklets, + utils, +) from google.cloud.ndb import context as context_module -from google.cloud.ndb import _batch -from google.cloud.ndb import _cache -from google.cloud.ndb import _eventloop -from google.cloud.ndb import _options -from google.cloud.ndb import _remote -from google.cloud.ndb import _retry -from google.cloud.ndb import tasklets -from google.cloud.ndb import utils EVENTUAL = datastore_pb2.ReadOptions.ReadConsistency.EVENTUAL EVENTUAL_CONSISTENCY = EVENTUAL # Legacy NDB diff --git a/packages/google-cloud-ndb/google/cloud/ndb/_datastore_query.py b/packages/google-cloud-ndb/google/cloud/ndb/_datastore_query.py index 8da0238bfdc4..744129526740 100644 --- a/packages/google-cloud-ndb/google/cloud/ndb/_datastore_query.py +++ b/packages/google-cloud-ndb/google/cloud/ndb/_datastore_query.py @@ -20,20 +20,15 @@ import logging import os -from google.cloud import environment_vars - +from google.cloud.datastore import Key, helpers from google.cloud.datastore_v1.types import datastore as datastore_pb2 from google.cloud.datastore_v1.types import entity as entity_pb2 from google.cloud.datastore_v1.types import query as query_pb2 -from google.cloud.datastore import helpers, Key +from google.cloud import environment_vars +from google.cloud.ndb import _datastore_api, exceptions, model, tasklets, utils from google.cloud.ndb import context as context_module -from google.cloud.ndb import _datastore_api -from google.cloud.ndb import exceptions from google.cloud.ndb import key as key_module -from google.cloud.ndb import model -from google.cloud.ndb import tasklets -from google.cloud.ndb import utils log = logging.getLogger(__name__) diff --git a/packages/google-cloud-ndb/google/cloud/ndb/_datastore_types.py b/packages/google-cloud-ndb/google/cloud/ndb/_datastore_types.py index 7692040929ad..06821fcdc7b3 100644 --- a/packages/google-cloud-ndb/google/cloud/ndb/_datastore_types.py +++ b/packages/google-cloud-ndb/google/cloud/ndb/_datastore_types.py @@ -24,7 +24,6 @@ from google.cloud.ndb import exceptions - _MAX_STRING_LENGTH = 1500 @@ -55,12 +54,13 @@ def __init__(self, blob_key): if isinstance(blob_key, bytes): if len(blob_key) > _MAX_STRING_LENGTH: raise exceptions.BadValueError( - "blob key must be under {:d} " "bytes.".format(_MAX_STRING_LENGTH) + "blob key must be under {:d} bytes.".format(_MAX_STRING_LENGTH) ) elif blob_key is not None: raise exceptions.BadValueError( - "blob key should be bytes; received " - "{} (a {})".format(blob_key, type(blob_key).__name__) + "blob key should be bytes; received {} (a {})".format( + blob_key, type(blob_key).__name__ + ) ) self._blob_key = blob_key diff --git a/packages/google-cloud-ndb/google/cloud/ndb/_eventloop.py b/packages/google-cloud-ndb/google/cloud/ndb/_eventloop.py index e71dc0c12b58..5e2d754c5e04 100644 --- a/packages/google-cloud-ndb/google/cloud/ndb/_eventloop.py +++ b/packages/google-cloud-ndb/google/cloud/ndb/_eventloop.py @@ -16,12 +16,12 @@ This should handle both asynchronous ``ndb`` objects and arbitrary callbacks. """ + import collections import logging -import uuid -import time - import queue +import time +import uuid from google.cloud.ndb import utils diff --git a/packages/google-cloud-ndb/google/cloud/ndb/_gql.py b/packages/google-cloud-ndb/google/cloud/ndb/_gql.py index 9a6b225ec0ab..1e9a006da1dd 100644 --- a/packages/google-cloud-ndb/google/cloud/ndb/_gql.py +++ b/packages/google-cloud-ndb/google/cloud/ndb/_gql.py @@ -3,12 +3,9 @@ import time from typing import Any +from google.cloud.ndb import _datastore_query, exceptions, key, model from google.cloud.ndb import context as context_module -from google.cloud.ndb import exceptions from google.cloud.ndb import query as query_module -from google.cloud.ndb import key -from google.cloud.ndb import model -from google.cloud.ndb import _datastore_query class GQL(object): diff --git a/packages/google-cloud-ndb/google/cloud/ndb/_legacy_protocol_buffer.py b/packages/google-cloud-ndb/google/cloud/ndb/_legacy_protocol_buffer.py index 7431b288f1de..efcadebc9ece 100644 --- a/packages/google-cloud-ndb/google/cloud/ndb/_legacy_protocol_buffer.py +++ b/packages/google-cloud-ndb/google/cloud/ndb/_legacy_protocol_buffer.py @@ -16,7 +16,6 @@ import array import struct - # Python 3 doesn't have "long" anymore long = int diff --git a/packages/google-cloud-ndb/google/cloud/ndb/_options.py b/packages/google-cloud-ndb/google/cloud/ndb/_options.py index 92ab694b354e..11b137621523 100644 --- a/packages/google-cloud-ndb/google/cloud/ndb/_options.py +++ b/packages/google-cloud-ndb/google/cloud/ndb/_options.py @@ -17,9 +17,9 @@ import functools import itertools import logging +from typing import Any from google.cloud.ndb import exceptions -from typing import Any log = logging.getLogger(__name__) @@ -135,8 +135,7 @@ def __init__(self, config=None, **kwargs): global_cache_timeout = kwargs.get("global_cache_timeout") if global_cache_timeout is not None: raise TypeError( - "Can't specify both 'memcache_timeout' and " - "'global_cache_timeout'" + "Can't specify both 'memcache_timeout' and 'global_cache_timeout'" ) kwargs["global_cache_timeout"] = memcache_timeout @@ -223,7 +222,7 @@ def __init__(self, config=None, **kwargs): ) if kwargs.get("read_consistency"): raise TypeError( - "Cannot use both 'read_policy' and 'read_consistency' " "options." + "Cannot use both 'read_policy' and 'read_consistency' options." ) kwargs["read_consistency"] = read_policy diff --git a/packages/google-cloud-ndb/google/cloud/ndb/_remote.py b/packages/google-cloud-ndb/google/cloud/ndb/_remote.py index c422af249058..4107c473a31a 100644 --- a/packages/google-cloud-ndb/google/cloud/ndb/_remote.py +++ b/packages/google-cloud-ndb/google/cloud/ndb/_remote.py @@ -16,9 +16,10 @@ # In its own module to avoid circular import between _datastore_api and # tasklets modules. -import grpc import time +import grpc + from google.cloud.ndb import exceptions diff --git a/packages/google-cloud-ndb/google/cloud/ndb/_retry.py b/packages/google-cloud-ndb/google/cloud/ndb/_retry.py index 44494fffab14..2078b515284f 100644 --- a/packages/google-cloud-ndb/google/cloud/ndb/_retry.py +++ b/packages/google-cloud-ndb/google/cloud/ndb/_retry.py @@ -17,10 +17,10 @@ import functools import itertools -from google.api_core import retry as core_retry from google.api_core import exceptions as core_exceptions -from google.cloud.ndb import exceptions -from google.cloud.ndb import tasklets +from google.api_core import retry as core_retry + +from google.cloud.ndb import exceptions, tasklets _DEFAULT_INITIAL_DELAY = 1.0 # seconds _DEFAULT_MAXIMUM_DELAY = 60.0 # seconds diff --git a/packages/google-cloud-ndb/google/cloud/ndb/_transaction.py b/packages/google-cloud-ndb/google/cloud/ndb/_transaction.py index 637d4b200d60..d98732b97771 100644 --- a/packages/google-cloud-ndb/google/cloud/ndb/_transaction.py +++ b/packages/google-cloud-ndb/google/cloud/ndb/_transaction.py @@ -15,10 +15,7 @@ import functools import logging -from google.cloud.ndb import exceptions -from google.cloud.ndb import _retry -from google.cloud.ndb import tasklets -from google.cloud.ndb import utils +from google.cloud.ndb import _retry, exceptions, tasklets, utils log = logging.getLogger(__name__) @@ -50,8 +47,9 @@ def __init__(self, propagation, join=None): self.propagation = propagation else: raise ValueError( - "Unexpected value for propagation. Got: {}. Expected one of: " - "{}".format(propagation, propagation_options) + "Unexpected value for propagation. Got: {}. Expected one of: {}".format( + propagation, propagation_options + ) ) propagation_names = context_module.TransactionOptions._INT_TO_NAME diff --git a/packages/google-cloud-ndb/google/cloud/ndb/blobstore.py b/packages/google-cloud-ndb/google/cloud/ndb/blobstore.py index e2dc50280417..a62903f0cd6a 100644 --- a/packages/google-cloud-ndb/google/cloud/ndb/blobstore.py +++ b/packages/google-cloud-ndb/google/cloud/ndb/blobstore.py @@ -20,11 +20,7 @@ No longer supported. """ - -from google.cloud.ndb import _datastore_types -from google.cloud.ndb import model -from google.cloud.ndb import exceptions - +from google.cloud.ndb import _datastore_types, exceptions, model __all__ = [ "BLOB_INFO_KIND", diff --git a/packages/google-cloud-ndb/google/cloud/ndb/client.py b/packages/google-cloud-ndb/google/cloud/ndb/client.py index 8c2ae57860f6..d7f70753dd19 100644 --- a/packages/google-cloud-ndb/google/cloud/ndb/client.py +++ b/packages/google-cloud-ndb/google/cloud/ndb/client.py @@ -15,25 +15,22 @@ """A client for NDB which manages credentials, project, namespace, and database.""" import contextlib -import grpc import os -import requests import google.api_core.client_options - +import grpc +import requests from google.api_core.gapic_v1 import client_info -from google.cloud import environment_vars -from google.cloud import _helpers -from google.cloud import client as google_client from google.cloud.datastore_v1.services.datastore.transports import ( grpc as datastore_grpc, ) +from google.cloud import _helpers, environment_vars +from google.cloud import client as google_client from google.cloud.ndb import __version__ from google.cloud.ndb import context as context_module from google.cloud.ndb import key as key_module - _CLIENT_INFO = client_info.ClientInfo( user_agent="google-cloud-ndb/{}".format(__version__) ) diff --git a/packages/google-cloud-ndb/google/cloud/ndb/context.py b/packages/google-cloud-ndb/google/cloud/ndb/context.py index 25e90763b5bc..99ddbcce1dc9 100644 --- a/packages/google-cloud-ndb/google/cloud/ndb/context.py +++ b/packages/google-cloud-ndb/google/cloud/ndb/context.py @@ -24,8 +24,7 @@ import uuid from typing import Any, cast -from google.cloud.ndb import _eventloop -from google.cloud.ndb import exceptions +from google.cloud.ndb import _eventloop, exceptions from google.cloud.ndb import key as key_module diff --git a/packages/google-cloud-ndb/google/cloud/ndb/django_middleware.py b/packages/google-cloud-ndb/google/cloud/ndb/django_middleware.py index 361c2a00751d..2343339ee842 100644 --- a/packages/google-cloud-ndb/google/cloud/ndb/django_middleware.py +++ b/packages/google-cloud-ndb/google/cloud/ndb/django_middleware.py @@ -20,7 +20,6 @@ https://cloud.google.com/appengine/docs/standard/python3/migrating-to-cloud-ndb#using_a_runtime_context_with_django """ - __all__ = ["NdbDjangoMiddleware"] diff --git a/packages/google-cloud-ndb/google/cloud/ndb/exceptions.py b/packages/google-cloud-ndb/google/cloud/ndb/exceptions.py index 6c4b726292d3..236f234dc170 100644 --- a/packages/google-cloud-ndb/google/cloud/ndb/exceptions.py +++ b/packages/google-cloud-ndb/google/cloud/ndb/exceptions.py @@ -19,7 +19,6 @@ legacy Google App Engine runtime. """ - __all__ = [ "Error", "ContextError", diff --git a/packages/google-cloud-ndb/google/cloud/ndb/global_cache.py b/packages/google-cloud-ndb/google/cloud/ndb/global_cache.py index 74202c7c13d5..a8e1c047f92c 100644 --- a/packages/google-cloud-ndb/google/cloud/ndb/global_cache.py +++ b/packages/google-cloud-ndb/google/cloud/ndb/global_cache.py @@ -18,15 +18,15 @@ import base64 import hashlib import os -import pymemcache.exceptions -import redis.exceptions import threading import time import warnings +from typing import Any import pymemcache +import pymemcache.exceptions import redis as redis_module -from typing import Any +import redis.exceptions # Python 2.7 doesn't have ConnectionError. In Python 3, ConnectionError is subclass of # OSError, which Python 2.7 does have. diff --git a/packages/google-cloud-ndb/google/cloud/ndb/key.py b/packages/google-cloud-ndb/google/cloud/ndb/key.py index c3043ff7e135..fb98a2c4e067 100644 --- a/packages/google-cloud-ndb/google/cloud/ndb/key.py +++ b/packages/google-cloud-ndb/google/cloud/ndb/key.py @@ -87,19 +87,15 @@ namespace. To explicitly select the empty namespace pass ``namespace=""``. """ - -import typing import base64 import functools +import typing +import google.cloud.datastore from google.cloud.datastore import _app_engine_key_pb2 from google.cloud.datastore import key as _key_module -import google.cloud.datastore -from google.cloud.ndb import exceptions -from google.cloud.ndb import _options -from google.cloud.ndb import tasklets -from google.cloud.ndb import utils +from google.cloud.ndb import _options, exceptions, tasklets, utils __all__ = ["Key", "UNDEFINED"] _APP_ID_ENVIRONMENT = "APPLICATION_ID" @@ -918,9 +914,8 @@ def get_async( :class:`~google.cloud.ndb.tasklets.Future` """ # Avoid circular import in Python 2.7 - from google.cloud.ndb import model + from google.cloud.ndb import _datastore_api, model from google.cloud.ndb import context as context_module - from google.cloud.ndb import _datastore_api cls = model.Model._kind_map.get(self.kind()) @@ -1054,9 +1049,8 @@ def delete_async( force_writes (bool): No longer supported. """ # Avoid circular import in Python 2.7 - from google.cloud.ndb import model + from google.cloud.ndb import _datastore_api, model from google.cloud.ndb import context as context_module - from google.cloud.ndb import _datastore_api cls = model.Model._kind_map.get(self.kind()) if cls: @@ -1317,7 +1311,7 @@ def _parse_from_ref( app=None, namespace=None, database: typing.Optional[str] = None, - **kwargs + **kwargs, ): """Construct a key from a Reference. @@ -1361,7 +1355,7 @@ def _parse_from_ref( if kwargs or not _exactly_one_specified(reference, serialized, urlsafe): raise TypeError( - "Cannot construct Key reference from incompatible " "keyword arguments." + "Cannot construct Key reference from incompatible keyword arguments." ) if reference: @@ -1528,8 +1522,7 @@ def _clean_flat_path(flat): flat[i] = kind if not isinstance(kind, str): raise TypeError( - "Key kind must be a string or Model class; " - "received {!r}".format(kind) + "Key kind must be a string or Model class; received {!r}".format(kind) ) # Make sure the ``id_`` is either a string or int. In the special case # of a partial key, ``id_`` can be ``None`` for the last pair. diff --git a/packages/google-cloud-ndb/google/cloud/ndb/metadata.py b/packages/google-cloud-ndb/google/cloud/ndb/metadata.py index d9fc40d685b7..f8ad6f5a5928 100644 --- a/packages/google-cloud-ndb/google/cloud/ndb/metadata.py +++ b/packages/google-cloud-ndb/google/cloud/ndb/metadata.py @@ -38,11 +38,9 @@ limit the query to a range of names, such that start <= name < end. """ -from google.cloud.ndb import exceptions -from google.cloud.ndb import model +from google.cloud.ndb import exceptions, model from google.cloud.ndb import query as query_module - __all__ = [ "get_entity_group_version", "get_kinds", diff --git a/packages/google-cloud-ndb/google/cloud/ndb/model.py b/packages/google-cloud-ndb/google/cloud/ndb/model.py index cd636dfd2df7..8d19dded179a 100644 --- a/packages/google-cloud-ndb/google/cloud/ndb/model.py +++ b/packages/google-cloud-ndb/google/cloud/ndb/model.py @@ -250,32 +250,31 @@ class Person(Model): :class:`Property` class. """ - -import typing import copy import datetime import functools import inspect import json import pickle +import typing import zlib import pytz - from google.cloud.datastore import entity as ds_entity_module from google.cloud.datastore import helpers from google.cloud.datastore_v1.types import entity as entity_pb2 -from google.cloud.ndb import _legacy_entity_pb -from google.cloud.ndb import _datastore_types -from google.cloud.ndb import exceptions -from google.cloud.ndb import key as key_module +from google.cloud.ndb import ( + _datastore_types, + _legacy_entity_pb, + _transaction, + exceptions, + tasklets, + utils, +) from google.cloud.ndb import _options as options_module +from google.cloud.ndb import key as key_module from google.cloud.ndb import query as query_module -from google.cloud.ndb import _transaction -from google.cloud.ndb import tasklets -from google.cloud.ndb import utils - __all__ = [ "Key", @@ -1439,8 +1438,9 @@ def _do_validate(self, value): if self._choices is not None: if value not in self._choices: raise exceptions.BadValueError( - "Value {!r} for property {} is not an allowed " - "choice".format(value, self._name) + "Value {!r} for property {} is not an allowed choice".format( + value, self._name + ) ) return value @@ -2295,8 +2295,9 @@ def _validate_key(value, entity=None): if entity and type(entity) not in (Model, Expando): if value.kind() != entity._get_kind(): raise KindError( - "Expected Key kind to be {}; received " - "{}".format(entity._get_kind(), value.kind()) + "Expected Key kind to be {}; received {}".format( + entity._get_kind(), value.kind() + ) ) return value @@ -2625,8 +2626,9 @@ def _validate(self, value): if self._indexed and len(value) > _MAX_STRING_LENGTH: raise exceptions.BadValueError( - "Indexed value {} must be at most {:d} " - "bytes".format(self._name, _MAX_STRING_LENGTH) + "Indexed value {} must be at most {:d} bytes".format( + self._name, _MAX_STRING_LENGTH + ) ) def _to_base_type(self, value): @@ -2993,8 +2995,9 @@ def _validate(self, value): if self._indexed and encoded_length > _MAX_STRING_LENGTH: raise exceptions.BadValueError( - "Indexed value {} must be at most {:d} " - "bytes".format(self._name, _MAX_STRING_LENGTH) + "Indexed value {} must be at most {:d} bytes".format( + self._name, _MAX_STRING_LENGTH + ) ) def _to_base_type(self, value): @@ -3742,8 +3745,9 @@ def _validate(self, value): if self._kind is not None: if value.kind() != self._kind: raise exceptions.BadValueError( - "In field {}, expected Key with kind={!r}, got " - "{!r}".format(self._name, self._kind, value) + "In field {}, expected Key with kind={!r}, got {!r}".format( + self._name, self._kind, value + ) ) def _to_base_type(self, value): @@ -4030,8 +4034,9 @@ def _to_base_type(self, value): """ if not isinstance(value, datetime.date): raise TypeError( - "Cannot convert to datetime expected date value; " - "received {}".format(value) + "Cannot convert to datetime expected date value; received {}".format( + value + ) ) return datetime.datetime(value.year, value.month, value.day) @@ -4090,8 +4095,9 @@ def _to_base_type(self, value): """ if not isinstance(value, datetime.time): raise TypeError( - "Cannot convert to datetime expected time value; " - "received {}".format(value) + "Cannot convert to datetime expected time value; received {}".format( + value + ) ) return datetime.datetime( 1970, @@ -4205,8 +4211,11 @@ def _comparison(self, op, value): "Cannot query for unindexed StructuredProperty %s" % self._name ) # Import late to avoid circular imports. - from .query import ConjunctionNode, PostFilterNode - from .query import RepeatedStructuredPropertyPredicate + from .query import ( + ConjunctionNode, + PostFilterNode, + RepeatedStructuredPropertyPredicate, + ) if value is None: from .query import ( @@ -4520,8 +4529,9 @@ def _to_base_type(self, value): raise TypeError("self._model_class cannot be None") if not isinstance(value, self._model_class): raise TypeError( - "Cannot convert to bytes expected {} value; " - "received {}".format(self._model_class.__name__, value) + "Cannot convert to bytes expected {} value; received {}".format( + self._model_class.__name__, value + ) ) return _entity_to_protobuf( value, set_key=self._keep_keys @@ -5567,8 +5577,8 @@ def _put_async(self, **kwargs): entity. This is always a complete key. """ # Avoid Python 2.7 circular import - from google.cloud.ndb import context as context_module from google.cloud.ndb import _datastore_api + from google.cloud.ndb import context as context_module self._pre_put_hook() @@ -6402,8 +6412,7 @@ def __delattr__(self, name): base_props = super(Expando, self)._properties if base_props is not None and name in base_props: raise RuntimeError( - "Property %s still in the list of properties for the " - "base class." % name + "Property %s still in the list of properties for the base class." % name ) del self._properties[name] diff --git a/packages/google-cloud-ndb/google/cloud/ndb/msgprop.py b/packages/google-cloud-ndb/google/cloud/ndb/msgprop.py index 7cbfa644069b..d83aa50a7317 100644 --- a/packages/google-cloud-ndb/google/cloud/ndb/msgprop.py +++ b/packages/google-cloud-ndb/google/cloud/ndb/msgprop.py @@ -17,7 +17,6 @@ These classes are not implemented. """ - __all__ = ["EnumProperty", "MessageProperty"] diff --git a/packages/google-cloud-ndb/google/cloud/ndb/polymodel.py b/packages/google-cloud-ndb/google/cloud/ndb/polymodel.py index f69a6b6271af..d2620e8c326a 100644 --- a/packages/google-cloud-ndb/google/cloud/ndb/polymodel.py +++ b/packages/google-cloud-ndb/google/cloud/ndb/polymodel.py @@ -31,7 +31,6 @@ from google.cloud.ndb import model - __all__ = ["PolyModel"] _CLASS_KEY_PROPERTY = "class" diff --git a/packages/google-cloud-ndb/google/cloud/ndb/query.py b/packages/google-cloud-ndb/google/cloud/ndb/query.py index ab4f11dcdcef..7610f6da4ed3 100644 --- a/packages/google-cloud-ndb/google/cloud/ndb/query.py +++ b/packages/google-cloud-ndb/google/cloud/ndb/query.py @@ -137,16 +137,12 @@ def ranked(cls, rank): print(emp.name, emp.age) """ -import typing import functools import logging +import typing +from google.cloud.ndb import _options, exceptions, tasklets, utils from google.cloud.ndb import context as context_module -from google.cloud.ndb import exceptions -from google.cloud.ndb import _options -from google.cloud.ndb import tasklets -from google.cloud.ndb import utils - __all__ = [ "QueryOptions", @@ -651,8 +647,9 @@ def __new__(cls, name, opsymbol, value, server_op=False): if opsymbol == _IN_OP: if not isinstance(value, (list, tuple, set, frozenset)): raise TypeError( - "in expected a list, tuple or set of values; " - "received {!r}".format(value) + "in expected a list, tuple or set of values; received {!r}".format( + value + ) ) nodes = [FilterNode(name, _EQ_OP, sub_value) for sub_value in value] if not nodes: @@ -1145,8 +1142,8 @@ def _query_options(wrapped): @functools.wraps(wrapped) def wrapper(self, *args, **kwargs): # Avoid circular import in Python 2.7 - from google.cloud.ndb import context as context_module from google.cloud.ndb import _datastore_api + from google.cloud.ndb import context as context_module # Maybe we already did this (in the case of X calling X_async) if "_options" in kwargs: @@ -1355,8 +1352,9 @@ def __init__( if not isinstance(default_options, QueryOptions): raise TypeError( - "default_options must be QueryOptions or None; " - "received {}".format(default_options) + "default_options must be QueryOptions or None; received {}".format( + default_options + ) ) # Not sure why we're doing all this checking just for this one @@ -1392,12 +1390,12 @@ def __init__( if isinstance(ancestor, ParameterizedFunction): if ancestor.func != "key": raise TypeError( - "ancestor cannot be a GQL function" "other than Key" + "ancestor cannot be a GQL function other than Key" ) else: if not isinstance(ancestor, model.Key): raise TypeError( - "ancestor must be a Key; " "received {}".format(ancestor) + "ancestor must be a Key; received {}".format(ancestor) ) if not ancestor.id(): raise ValueError("ancestor cannot be an incomplete key") @@ -1424,8 +1422,7 @@ def __init__( if filters is not None: if not isinstance(filters, Node): raise TypeError( - "filters must be a query Node or None; " - "received {}".format(filters) + "filters must be a query Node or None; received {}".format(filters) ) if order_by is not None and orders is not None: raise TypeError( @@ -1437,8 +1434,9 @@ def __init__( if order_by is not None: if not isinstance(order_by, (list, tuple)): raise TypeError( - "order must be a list, a tuple or None; " - "received {}".format(order_by) + "order must be a list, a tuple or None; received {}".format( + order_by + ) ) order_by = self._to_property_orders(order_by) @@ -1459,8 +1457,9 @@ def __init__( raise TypeError("projection argument cannot be empty") if not isinstance(projection, (tuple, list)): raise TypeError( - "projection must be a tuple, list or None; " - "received {}".format(projection) + "projection must be a tuple, list or None; received {}".format( + projection + ) ) projection = _to_property_names(projection) _check_properties(self.kind, projection) @@ -1480,8 +1479,9 @@ def __init__( raise TypeError("distinct_on argument cannot be empty") if not isinstance(distinct_on, (tuple, list)): raise TypeError( - "distinct_on must be a tuple, list or None; " - "received {}".format(distinct_on) + "distinct_on must be a tuple, list or None; received {}".format( + distinct_on + ) ) distinct_on = _to_property_names(distinct_on) _check_properties(self.kind, distinct_on) @@ -2371,7 +2371,7 @@ def _to_property_names(properties): fixed.append(prop._name) else: raise TypeError( - "Unexpected property {}; " "should be string or Property".format(prop) + "Unexpected property {}; should be string or Property".format(prop) ) return fixed diff --git a/packages/google-cloud-ndb/google/cloud/ndb/stats.py b/packages/google-cloud-ndb/google/cloud/ndb/stats.py index 4eda7649ebf2..fe4ad1ade81d 100644 --- a/packages/google-cloud-ndb/google/cloud/ndb/stats.py +++ b/packages/google-cloud-ndb/google/cloud/ndb/stats.py @@ -20,7 +20,6 @@ from google.cloud.ndb import model - __all__ = [ "BaseKindStatistic", "BaseStatistic", diff --git a/packages/google-cloud-ndb/google/cloud/ndb/tasklets.py b/packages/google-cloud-ndb/google/cloud/ndb/tasklets.py index c62ae97584f4..f3dd8632dd95 100644 --- a/packages/google-cloud-ndb/google/cloud/ndb/tasklets.py +++ b/packages/google-cloud-ndb/google/cloud/ndb/tasklets.py @@ -72,12 +72,11 @@ def main(): eventloop.run() # Run until no tasklets left to do f.done() # Returns True """ + import functools import types -from google.cloud.ndb import _eventloop -from google.cloud.ndb import exceptions -from google.cloud.ndb import _remote +from google.cloud.ndb import _eventloop, _remote, exceptions __all__ = [ "add_flow_exception", diff --git a/packages/google-cloud-ndb/google/cloud/ndb/utils.py b/packages/google-cloud-ndb/google/cloud/ndb/utils.py index a424532044c2..aecf861cd52c 100644 --- a/packages/google-cloud-ndb/google/cloud/ndb/utils.py +++ b/packages/google-cloud-ndb/google/cloud/ndb/utils.py @@ -14,7 +14,6 @@ """Low-level utilities used internally by ``ndb``""" - import functools import inspect import os diff --git a/packages/google-cloud-ndb/noxfile.py b/packages/google-cloud-ndb/noxfile.py index 9234e413582a..47c4a4359e77 100644 --- a/packages/google-cloud-ndb/noxfile.py +++ b/packages/google-cloud-ndb/noxfile.py @@ -33,6 +33,8 @@ CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() BLACK_VERSION = "black[jupyter]==23.7.0" +RUFF_VERSION = "ruff==0.14.14" +LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] UNIT_TEST_STANDARD_DEPENDENCIES = [ "mock", "asyncmock", @@ -241,40 +243,76 @@ def _run_emulator(session, emulator_args): emulator.wait(timeout=2) -def run_black(session, use_check=False): - args = ["black"] - if use_check: - args.append("--check") - - args.extend( - [ - get_path("docs"), - get_path("noxfile.py"), - get_path("google"), - get_path("tests"), - ] - ) - - session.run(*args) - - @nox.session(py=DEFAULT_INTERPRETER) def lint(session): """Run linters. + Returns a failure if the linters find linting errors or sufficiently serious code quality issues. """ - session.install("flake8", BLACK_VERSION) - run_black(session, use_check=True) + session.install("flake8", RUFF_VERSION) + + # 2. Check formatting + session.run( + "ruff", + "format", + "--check", + f"--target-version=py{ALL_INTERPRETERS[0].replace('.', '')}", + "--line-length=88", + *LINT_PATHS, + ) + session.run("flake8", "google", "tests") @nox.session(py=DEFAULT_INTERPRETER) def blacken(session): - # Install all dependencies. - session.install(BLACK_VERSION) - # Run ``black``. - run_black(session) + """(Deprecated) Legacy session. Please use 'nox -s format'.""" + session.log( + "WARNING: The 'blacken' session is deprecated and will be removed in a future release. Please use 'nox -s format' in the future." + ) + + # Just run the ruff formatter (keeping legacy behavior of only formatting, not sorting imports) + session.install(RUFF_VERSION) + session.run( + "ruff", + "format", + f"--target-version=py{ALL_INTERPRETERS[0].replace('.', '')}", + "--line-length=88", + *LINT_PATHS, + ) + + +@nox.session(python=DEFAULT_INTERPRETER) +def format(session): + """ + Run ruff to sort imports and format code. + """ + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports + # check --select I: Enables strict import sorting + # --fix: Applies the changes automatically + session.run( + "ruff", + "check", + "--select", + "I", + "--fix", + f"--target-version=py{ALL_INTERPRETERS[0].replace('.', '')}", + "--line-length=88", # Standard Black line length + *LINT_PATHS, + ) + + # 3. Run Ruff to format code + session.run( + "ruff", + "format", + f"--target-version=py{ALL_INTERPRETERS[0].replace('.', '')}", + "--line-length=88", # Standard Black line length + *LINT_PATHS, + ) @nox.session(py="3.10") diff --git a/packages/google-cloud-ndb/setup.py b/packages/google-cloud-ndb/setup.py index b0789437289f..8c22f5349b16 100644 --- a/packages/google-cloud-ndb/setup.py +++ b/packages/google-cloud-ndb/setup.py @@ -18,7 +18,6 @@ import setuptools - PACKAGE_ROOT = os.path.abspath(os.path.dirname(__file__)) version = None @@ -34,6 +33,7 @@ if package.startswith("google") ] + def main(): package_root = os.path.abspath(os.path.dirname(__file__)) readme_filename = os.path.join(package_root, "README.md") @@ -50,7 +50,7 @@ def main(): setuptools.setup( name="google-cloud-ndb", - version = version, + version=version, description="NDB library for Google Cloud Datastore", long_description=readme, long_description_content_type="text/markdown", @@ -59,8 +59,8 @@ def main(): license="Apache 2.0", url="https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-ndb", project_urls={ - 'Documentation': 'https://googleapis.dev/python/python-ndb/latest', - 'Issue Tracker': 'https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-ndb/issues' + "Documentation": "https://googleapis.dev/python/python-ndb/latest", + "Issue Tracker": "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-ndb/issues", }, classifiers=[ "Development Status :: 5 - Production/Stable", diff --git a/packages/google-cloud-ndb/tests/conftest.py b/packages/google-cloud-ndb/tests/conftest.py index c8d6b07dd358..98163b5b15db 100644 --- a/packages/google-cloud-ndb/tests/conftest.py +++ b/packages/google-cloud-ndb/tests/conftest.py @@ -19,17 +19,14 @@ """ import os +from unittest import mock + +import pytest from google.cloud import environment_vars +from google.cloud.ndb import _eventloop, model, utils from google.cloud.ndb import context as context_module -from google.cloud.ndb import _eventloop from google.cloud.ndb import global_cache as global_cache_module -from google.cloud.ndb import model -from google.cloud.ndb import utils - -import pytest - -from unittest import mock utils.DEBUG = True @@ -98,7 +95,7 @@ def context(**kwargs): eventloop=TestingEventLoop(), datastore_policy=True, legacy_data=False, - **kwargs + **kwargs, ) return context diff --git a/packages/google-cloud-ndb/tests/system/conftest.py b/packages/google-cloud-ndb/tests/system/conftest.py index 82e61762f2e1..4153318e64bd 100644 --- a/packages/google-cloud-ndb/tests/system/conftest.py +++ b/packages/google-cloud-ndb/tests/system/conftest.py @@ -6,9 +6,7 @@ import pytest import requests -from google.cloud import datastore -from google.cloud import ndb - +from google.cloud import datastore, ndb from google.cloud.ndb import global_cache as global_cache_module from . import KIND, OTHER_KIND, _helpers @@ -138,7 +136,7 @@ def fix_key_db(key, database): *key.flat_path, project=key.project, database=database, - namespace=key.namespace + namespace=key.namespace, ) # If the current parent has already been set, we re-use # the same instance diff --git a/packages/google-cloud-ndb/tests/system/test_crud.py b/packages/google-cloud-ndb/tests/system/test_crud.py index 66d7d1dce830..eea78fcfec7a 100644 --- a/packages/google-cloud-ndb/tests/system/test_crud.py +++ b/packages/google-cloud-ndb/tests/system/test_crud.py @@ -15,25 +15,24 @@ """ System tests for Create, Update, Delete. (CRUD) """ + import datetime import os import pickle -import pytz import random import threading import zlib - from unittest import mock import pytest - +import pytz import test_utils.system from google.cloud import ndb from google.cloud.ndb import _cache from google.cloud.ndb import global_cache as global_cache_module -from . import KIND, eventually, equals +from . import KIND, equals, eventually USE_REDIS_CACHE = bool(os.environ.get("REDIS_CACHE_URL")) USE_MEMCACHE = bool(os.environ.get("MEMCACHED_HOSTS")) @@ -1174,7 +1173,7 @@ class SomeKind(ndb.Model): ds_entity( KIND, entity_id, - **{"foo": 42, "bar.one": ["hi", "hello"], "bar.two": ["mom", "dad"]} + **{"foo": 42, "bar.one": ["hi", "hello"], "bar.two": ["mom", "dad"]}, ) key = ndb.Key(KIND, entity_id) diff --git a/packages/google-cloud-ndb/tests/system/test_metadata.py b/packages/google-cloud-ndb/tests/system/test_metadata.py index 3d0eee610401..314c1e11b15e 100644 --- a/packages/google-cloud-ndb/tests/system/test_metadata.py +++ b/packages/google-cloud-ndb/tests/system/test_metadata.py @@ -15,14 +15,13 @@ """ System tests for metadata. """ -import pytest from importlib import reload -from google.cloud import ndb - +import pytest from test_utils import retry +from google.cloud import ndb _retry_assertion_errors = retry.RetryErrors(AssertionError) diff --git a/packages/google-cloud-ndb/tests/system/test_misc.py b/packages/google-cloud-ndb/tests/system/test_misc.py index 3cb2e3d5e500..47a66524ee0d 100644 --- a/packages/google-cloud-ndb/tests/system/test_misc.py +++ b/packages/google-cloud-ndb/tests/system/test_misc.py @@ -15,24 +15,22 @@ """ Difficult to classify regression tests. """ + import os import pickle import threading import time import traceback - -import redis - from unittest import mock import pytest - +import redis import test_utils.system - from google.api_core import exceptions as core_exceptions + from google.cloud import ndb -from . import eventually, length_equals, KIND +from . import KIND, eventually, length_equals USE_REDIS_CACHE = bool(os.environ.get("REDIS_CACHE_URL")) diff --git a/packages/google-cloud-ndb/tests/system/test_query.py b/packages/google-cloud-ndb/tests/system/test_query.py index 8e40acb3c0e4..ceeb70747e2f 100644 --- a/packages/google-cloud-ndb/tests/system/test_query.py +++ b/packages/google-cloud-ndb/tests/system/test_query.py @@ -23,14 +23,13 @@ import pytest import pytz - import test_utils.system - from google.api_core import exceptions as core_exceptions -from google.cloud import ndb from google.cloud.datastore import key as ds_key_module -from . import KIND, eventually, equals, length_equals +from google.cloud import ndb + +from . import KIND, equals, eventually, length_equals @pytest.mark.usefixtures("client_context") @@ -1097,14 +1096,14 @@ class SomeKind(ndb.Model): ds_entity( KIND, entity_id, - **{"foo": 1, "bar.one": "pish", "bar.two": "posh", "bar.three": "pash"} + **{"foo": 1, "bar.one": "pish", "bar.two": "posh", "bar.three": "pash"}, ) entity_id = test_utils.system.unique_resource_id() ds_entity( KIND, entity_id, - **{"foo": 2, "bar.one": "pish", "bar.two": "posh", "bar.three": "push"} + **{"foo": 2, "bar.one": "pish", "bar.two": "posh", "bar.three": "push"}, ) entity_id = test_utils.system.unique_resource_id() @@ -1116,7 +1115,7 @@ class SomeKind(ndb.Model): "bar.one": "pish", "bar.two": "moppish", "bar.three": "pass the peas", - } + }, ) eventually(SomeKind.query().fetch, length_equals(3)) @@ -1647,7 +1646,7 @@ class SomeKind(ndb.Model): "bar.one": ["pish", "bish"], "bar.two": ["posh", "bosh"], "bar.three": ["pash", "bash"], - } + }, ) entity_id = test_utils.system.unique_resource_id() @@ -1659,7 +1658,7 @@ class SomeKind(ndb.Model): "bar.one": ["bish", "pish"], "bar.two": ["bosh", "posh"], "bar.three": ["bass", "pass"], - } + }, ) entity_id = test_utils.system.unique_resource_id() @@ -1671,7 +1670,7 @@ class SomeKind(ndb.Model): "bar.one": ["pish", "bish"], "bar.two": ["fosh", "posh"], "bar.three": ["fash", "bash"], - } + }, ) eventually(SomeKind.query().fetch, length_equals(3)) @@ -1710,7 +1709,7 @@ class SomeKind(ndb.Model): "b.one": ["pish", "bish"], "b.two": ["posh", "bosh"], "b.three": ["pash", "bash"], - } + }, ) eventually(SomeKind.query().fetch, length_equals(1)) diff --git a/packages/google-cloud-ndb/tests/unit/test__batch.py b/packages/google-cloud-ndb/tests/unit/test__batch.py index 8f370706f8ec..6c0c65b4402e 100644 --- a/packages/google-cloud-ndb/tests/unit/test__batch.py +++ b/packages/google-cloud-ndb/tests/unit/test__batch.py @@ -14,8 +14,7 @@ import pytest -from google.cloud.ndb import _batch -from google.cloud.ndb import _eventloop +from google.cloud.ndb import _batch, _eventloop @pytest.mark.usefixtures("in_context") diff --git a/packages/google-cloud-ndb/tests/unit/test__cache.py b/packages/google-cloud-ndb/tests/unit/test__cache.py index c0b3e426ebf1..1c9ec76a2ade 100644 --- a/packages/google-cloud-ndb/tests/unit/test__cache.py +++ b/packages/google-cloud-ndb/tests/unit/test__cache.py @@ -13,13 +13,11 @@ # limitations under the License. import warnings - from unittest import mock import pytest -from google.cloud.ndb import _cache -from google.cloud.ndb import tasklets +from google.cloud.ndb import _cache, tasklets def future_result(result): diff --git a/packages/google-cloud-ndb/tests/unit/test__datastore_api.py b/packages/google-cloud-ndb/tests/unit/test__datastore_api.py index 0db656a32d26..443e8733032f 100644 --- a/packages/google-cloud-ndb/tests/unit/test__datastore_api.py +++ b/packages/google-cloud-ndb/tests/unit/test__datastore_api.py @@ -16,23 +16,17 @@ import grpc import pytest - from google.api_core import client_info from google.api_core import exceptions as core_exceptions -from google.cloud.datastore import entity -from google.cloud.datastore import helpers +from google.cloud.datastore import entity, helpers from google.cloud.datastore import key as ds_key_module from google.cloud.datastore_v1.types import datastore as datastore_pb2 from google.cloud.datastore_v1.types import entity as entity_pb2 -from google.cloud.ndb import _batch -from google.cloud.ndb import _cache -from google.cloud.ndb import context as context_module + +from google.cloud.ndb import __version__, _batch, _cache, _options, model, tasklets from google.cloud.ndb import _datastore_api as _api +from google.cloud.ndb import context as context_module from google.cloud.ndb import key as key_module -from google.cloud.ndb import model -from google.cloud.ndb import _options -from google.cloud.ndb import tasklets -from google.cloud.ndb import __version__ from . import utils diff --git a/packages/google-cloud-ndb/tests/unit/test__datastore_query.py b/packages/google-cloud-ndb/tests/unit/test__datastore_query.py index 83d2554633de..36c36fac35ae 100644 --- a/packages/google-cloud-ndb/tests/unit/test__datastore_query.py +++ b/packages/google-cloud-ndb/tests/unit/test__datastore_query.py @@ -13,22 +13,17 @@ # limitations under the License. import base64 - from unittest import mock import pytest - from google.cloud.datastore_v1.types import datastore as datastore_pb2 from google.cloud.datastore_v1.types import entity as entity_pb2 from google.cloud.datastore_v1.types import query as query_pb2 -from google.cloud.ndb import _datastore_query +from google.cloud.ndb import _datastore_query, exceptions, model, tasklets from google.cloud.ndb import context as context_module -from google.cloud.ndb import exceptions from google.cloud.ndb import key as key_module -from google.cloud.ndb import model from google.cloud.ndb import query as query_module -from google.cloud.ndb import tasklets from . import utils diff --git a/packages/google-cloud-ndb/tests/unit/test__datastore_types.py b/packages/google-cloud-ndb/tests/unit/test__datastore_types.py index f24b677a5d7f..a6c925550ace 100644 --- a/packages/google-cloud-ndb/tests/unit/test__datastore_types.py +++ b/packages/google-cloud-ndb/tests/unit/test__datastore_types.py @@ -16,8 +16,7 @@ import pytest -from google.cloud.ndb import _datastore_types -from google.cloud.ndb import exceptions +from google.cloud.ndb import _datastore_types, exceptions class TestBlobKey: diff --git a/packages/google-cloud-ndb/tests/unit/test__eventloop.py b/packages/google-cloud-ndb/tests/unit/test__eventloop.py index 2662008817c5..8e755e9c819a 100644 --- a/packages/google-cloud-ndb/tests/unit/test__eventloop.py +++ b/packages/google-cloud-ndb/tests/unit/test__eventloop.py @@ -13,14 +13,12 @@ # limitations under the License. import collections - from unittest import mock import grpc import pytest -from google.cloud.ndb import exceptions -from google.cloud.ndb import _eventloop +from google.cloud.ndb import _eventloop, exceptions def _Event(when=0, what="foo", args=(), kw={}): diff --git a/packages/google-cloud-ndb/tests/unit/test__gql.py b/packages/google-cloud-ndb/tests/unit/test__gql.py index 3c96d4fe6d0a..430ca5ea10e5 100644 --- a/packages/google-cloud-ndb/tests/unit/test__gql.py +++ b/packages/google-cloud-ndb/tests/unit/test__gql.py @@ -13,15 +13,13 @@ # limitations under the License. import datetime + import pytest -from google.cloud.ndb import exceptions -from google.cloud.ndb import key -from google.cloud.ndb import model from google.cloud.ndb import _gql as gql_module +from google.cloud.ndb import exceptions, key, model from google.cloud.ndb import query as query_module - GQL_QUERY = """ SELECT prop1, prop2 FROM SomeKind WHERE prop3>5 and prop2='xxx' ORDER BY prop4, prop1 DESC LIMIT 10 OFFSET 5 HINT ORDER_FIRST @@ -475,8 +473,7 @@ class SomeKind(model.Model): prop1 = model.DateTimeProperty() gql = gql_module.GQL( - "SELECT prop1 FROM SomeKind WHERE prop1 = DateTime(2020, 3, 26," - "12, 45, 5)" + "SELECT prop1 FROM SomeKind WHERE prop1 = DateTime(2020, 3, 26,12, 45, 5)" ) query = gql.get_query() assert query.filters == query_module.FilterNode( @@ -490,8 +487,7 @@ class SomeKind(model.Model): prop1 = model.DateTimeProperty() gql = gql_module.GQL( - "SELECT prop1 FROM SomeKind WHERE prop1 = " - "DateTime('2020-03-26 12:45:05')" + "SELECT prop1 FROM SomeKind WHERE prop1 = DateTime('2020-03-26 12:45:05')" ) query = gql.get_query() assert query.filters == query_module.FilterNode( @@ -667,7 +663,7 @@ class SomeKind(model.Model): prop1 = model.GeoPtProperty() gql = gql_module.GQL( - "SELECT prop1 FROM SomeKind WHERE prop1 = " "GeoPt(20.67,-100.32, 1.5)" + "SELECT prop1 FROM SomeKind WHERE prop1 = GeoPt(20.67,-100.32, 1.5)" ) with pytest.raises(exceptions.BadQueryError): gql.get_query() @@ -679,8 +675,7 @@ class SomeKind(model.Model): prop1 = model.KeyProperty() gql = gql_module.GQL( - "SELECT prop1 FROM SomeKind WHERE prop1 = Key('parent', 'c', " - "'child', 42)" + "SELECT prop1 FROM SomeKind WHERE prop1 = Key('parent', 'c', 'child', 42)" ) query = gql.get_query() assert query.filters == query_module.FilterNode( diff --git a/packages/google-cloud-ndb/tests/unit/test__legacy_entity_pb.py b/packages/google-cloud-ndb/tests/unit/test__legacy_entity_pb.py index 3cbf37b58e02..ebb83fac63d3 100644 --- a/packages/google-cloud-ndb/tests/unit/test__legacy_entity_pb.py +++ b/packages/google-cloud-ndb/tests/unit/test__legacy_entity_pb.py @@ -13,6 +13,7 @@ # limitations under the License. import array + import pytest from google.cloud.ndb import _legacy_entity_pb as entity_module @@ -106,7 +107,7 @@ def test_TryMerge_mutable_key_path_not_bytes(): def test_TryMerge_mutable_key_path_with_skip_data(): entity = entity_module.EntityProto() d = _get_decoder( - b"\x6a\x0f\x72\x0d\x02\x01\x01\x0b\x12\x01\x44\x18\x01\x22\x01" b"\x45\x0c" + b"\x6a\x0f\x72\x0d\x02\x01\x01\x0b\x12\x01\x44\x18\x01\x22\x01\x45\x0c" ) entity.TryMerge(d) assert entity.key().has_path() @@ -122,7 +123,7 @@ def test_TryMerge_mutable_key_path_truncated(): def test_TryMerge_mutable_key_path_element_with_skip_data(): entity = entity_module.EntityProto() d = _get_decoder( - b"\x6a\x0f\x72\x0d\x0b\x02\x01\x01\x12\x01\x44\x18\x01\x22\x01" b"\x45\x0c" + b"\x6a\x0f\x72\x0d\x0b\x02\x01\x01\x12\x01\x44\x18\x01\x22\x01\x45\x0c" ) entity.TryMerge(d) assert entity.key().has_path() @@ -329,7 +330,7 @@ def test_TryMerge_property_reference_pathelement_truncated(): @staticmethod def test_TryMerge_property_reference_name_space(): entity = entity_module.EntityProto() - d = _get_decoder(b"\x72\x0b\x1a\x01\x46\x2a\x06\x63\xa2\x01\x01\x41" b"\x64") + d = _get_decoder(b"\x72\x0b\x1a\x01\x46\x2a\x06\x63\xa2\x01\x01\x41\x64") entity.TryMerge(d) assert entity.entity_props()["F"].has_name_space() assert entity.entity_props()["F"].name_space().decode() == "A" @@ -337,7 +338,7 @@ def test_TryMerge_property_reference_name_space(): @staticmethod def test_TryMerge_property_reference_database_id(): entity = entity_module.EntityProto() - d = _get_decoder(b"\x72\x0b\x1a\x01\x46\x2a\x06\x63\xba\x01\x01\x41" b"\x64") + d = _get_decoder(b"\x72\x0b\x1a\x01\x46\x2a\x06\x63\xba\x01\x01\x41\x64") entity.TryMerge(d) assert entity.entity_props()["F"].has_database_id() assert entity.entity_props()["F"].database_id().decode() == "A" @@ -346,7 +347,7 @@ def test_TryMerge_property_reference_database_id(): def test_TryMerge_property_reference_skip_data(): entity = entity_module.EntityProto() d = _get_decoder( - b"\x72\x0d\x1a\x01\x46\x2a\x08\x63\x02\x01\x01\x6a" b"\x01\x41\x64" + b"\x72\x0d\x1a\x01\x46\x2a\x08\x63\x02\x01\x01\x6a\x01\x41\x64" ) entity.TryMerge(d) assert entity.entity_props()["F"].has_app() @@ -383,7 +384,7 @@ def test_TryMerge_raw_property_string(): @staticmethod def test_TryMerge_with_skip_data(): entity = entity_module.EntityProto() - d = _get_decoder(b"\x02\x01\x01\x7a\x08\x1a\x01\x46\x2a\x03\x1a\x01" b"\x47") + d = _get_decoder(b"\x02\x01\x01\x7a\x08\x1a\x01\x46\x2a\x03\x1a\x01\x47") entity.TryMerge(d) assert entity.entity_props()["F"].decode() == "G" diff --git a/packages/google-cloud-ndb/tests/unit/test__options.py b/packages/google-cloud-ndb/tests/unit/test__options.py index a0d00017c4de..2f484717c120 100644 --- a/packages/google-cloud-ndb/tests/unit/test__options.py +++ b/packages/google-cloud-ndb/tests/unit/test__options.py @@ -14,9 +14,7 @@ import pytest -from google.cloud.ndb import _datastore_api -from google.cloud.ndb import _options -from google.cloud.ndb import utils +from google.cloud.ndb import _datastore_api, _options, utils class MyOptions(_options.Options): diff --git a/packages/google-cloud-ndb/tests/unit/test__remote.py b/packages/google-cloud-ndb/tests/unit/test__remote.py index 0c0bf19ead5c..420db23c068e 100644 --- a/packages/google-cloud-ndb/tests/unit/test__remote.py +++ b/packages/google-cloud-ndb/tests/unit/test__remote.py @@ -17,9 +17,7 @@ import grpc import pytest -from google.cloud.ndb import exceptions -from google.cloud.ndb import _remote -from google.cloud.ndb import tasklets +from google.cloud.ndb import _remote, exceptions, tasklets class TestRemoteCall: diff --git a/packages/google-cloud-ndb/tests/unit/test__retry.py b/packages/google-cloud-ndb/tests/unit/test__retry.py index 35eddb27959b..5db170a35a23 100644 --- a/packages/google-cloud-ndb/tests/unit/test__retry.py +++ b/packages/google-cloud-ndb/tests/unit/test__retry.py @@ -13,14 +13,12 @@ # limitations under the License. import itertools - from unittest import mock import pytest - from google.api_core import exceptions as core_exceptions -from google.cloud.ndb import _retry -from google.cloud.ndb import tasklets + +from google.cloud.ndb import _retry, tasklets from . import utils diff --git a/packages/google-cloud-ndb/tests/unit/test__transaction.py b/packages/google-cloud-ndb/tests/unit/test__transaction.py index c18590edca22..cb905961ab4e 100644 --- a/packages/google-cloud-ndb/tests/unit/test__transaction.py +++ b/packages/google-cloud-ndb/tests/unit/test__transaction.py @@ -14,16 +14,13 @@ import itertools import logging - from unittest import mock import pytest - from google.api_core import exceptions as core_exceptions + +from google.cloud.ndb import _transaction, exceptions, tasklets from google.cloud.ndb import context as context_module -from google.cloud.ndb import exceptions -from google.cloud.ndb import tasklets -from google.cloud.ndb import _transaction class Test_in_transaction: diff --git a/packages/google-cloud-ndb/tests/unit/test_blobstore.py b/packages/google-cloud-ndb/tests/unit/test_blobstore.py index 7a75c83a6e8e..3cb6ce941157 100644 --- a/packages/google-cloud-ndb/tests/unit/test_blobstore.py +++ b/packages/google-cloud-ndb/tests/unit/test_blobstore.py @@ -14,9 +14,7 @@ import pytest -from google.cloud.ndb import _datastore_types -from google.cloud.ndb import blobstore -from google.cloud.ndb import model +from google.cloud.ndb import _datastore_types, blobstore, model from . import utils diff --git a/packages/google-cloud-ndb/tests/unit/test_client.py b/packages/google-cloud-ndb/tests/unit/test_client.py index 8f647b2a6095..458716a813d9 100644 --- a/packages/google-cloud-ndb/tests/unit/test_client.py +++ b/packages/google-cloud-ndb/tests/unit/test_client.py @@ -13,18 +13,17 @@ # limitations under the License. import contextlib -import pytest - from unittest import mock -from google.auth import credentials +import pytest from google.api_core.client_options import ClientOptions -from google.cloud import environment_vars +from google.auth import credentials from google.cloud.datastore import _http +from google.cloud import environment_vars +from google.cloud.ndb import _eventloop from google.cloud.ndb import client as client_module from google.cloud.ndb import context as context_module -from google.cloud.ndb import _eventloop @contextlib.contextmanager diff --git a/packages/google-cloud-ndb/tests/unit/test_concurrency.py b/packages/google-cloud-ndb/tests/unit/test_concurrency.py index 0de03c49cb65..2b9bb167f3af 100644 --- a/packages/google-cloud-ndb/tests/unit/test_concurrency.py +++ b/packages/google-cloud-ndb/tests/unit/test_concurrency.py @@ -17,9 +17,8 @@ import pytest -from google.cloud.ndb import _cache +from google.cloud.ndb import _cache, tasklets from google.cloud.ndb import global_cache as global_cache_module -from google.cloud.ndb import tasklets try: from test_utils import orchestrate diff --git a/packages/google-cloud-ndb/tests/unit/test_context.py b/packages/google-cloud-ndb/tests/unit/test_context.py index e65338e93610..73b2fb822985 100644 --- a/packages/google-cloud-ndb/tests/unit/test_context.py +++ b/packages/google-cloud-ndb/tests/unit/test_context.py @@ -12,17 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. -import pytest import threading - from unittest import mock +import pytest + +from google.cloud.ndb import _eventloop, _options, exceptions, model from google.cloud.ndb import context as context_module -from google.cloud.ndb import _eventloop -from google.cloud.ndb import exceptions from google.cloud.ndb import key as key_module -from google.cloud.ndb import model -from google.cloud.ndb import _options class Test_get_context: diff --git a/packages/google-cloud-ndb/tests/unit/test_global_cache.py b/packages/google-cloud-ndb/tests/unit/test_global_cache.py index c7c73962c58b..b049c8ac758d 100644 --- a/packages/google-cloud-ndb/tests/unit/test_global_cache.py +++ b/packages/google-cloud-ndb/tests/unit/test_global_cache.py @@ -13,7 +13,6 @@ # limitations under the License. import collections - from unittest import mock import pytest diff --git a/packages/google-cloud-ndb/tests/unit/test_key.py b/packages/google-cloud-ndb/tests/unit/test_key.py index 58dbed48af8f..3d14107eb5b9 100644 --- a/packages/google-cloud-ndb/tests/unit/test_key.py +++ b/packages/google-cloud-ndb/tests/unit/test_key.py @@ -14,18 +14,14 @@ import base64 import pickle - from unittest import mock -from google.cloud.datastore import _app_engine_key_pb2 import google.cloud.datastore import pytest +from google.cloud.datastore import _app_engine_key_pb2 -from google.cloud.ndb import exceptions +from google.cloud.ndb import _options, exceptions, model, tasklets from google.cloud.ndb import key as key_module -from google.cloud.ndb import model -from google.cloud.ndb import _options -from google.cloud.ndb import tasklets from . import utils @@ -1102,8 +1098,7 @@ class Test__from_urlsafe: @staticmethod def test_basic(): urlsafe = ( - "agxzfnNhbXBsZS1hcHByHgsSBlBhcmVudBg7DAsSBUNoaWxkIgdGZ" - "WF0aGVyDKIBBXNwYWNl" + "agxzfnNhbXBsZS1hcHByHgsSBlBhcmVudBg7DAsSBUNoaWxkIgdGZWF0aGVyDKIBBXNwYWNl" ) urlsafe_bytes = urlsafe.encode("ascii") for value in (urlsafe, urlsafe_bytes): diff --git a/packages/google-cloud-ndb/tests/unit/test_metadata.py b/packages/google-cloud-ndb/tests/unit/test_metadata.py index a3aa5c85f8ab..5f46191b647e 100644 --- a/packages/google-cloud-ndb/tests/unit/test_metadata.py +++ b/packages/google-cloud-ndb/tests/unit/test_metadata.py @@ -16,10 +16,8 @@ import pytest -from google.cloud.ndb import exceptions -from google.cloud.ndb import metadata +from google.cloud.ndb import exceptions, metadata, tasklets from google.cloud.ndb import key as key_module -from google.cloud.ndb import tasklets from . import utils diff --git a/packages/google-cloud-ndb/tests/unit/test_model.py b/packages/google-cloud-ndb/tests/unit/test_model.py index 14ae8efbe610..cb6af3f042d7 100644 --- a/packages/google-cloud-ndb/tests/unit/test_model.py +++ b/packages/google-cloud-ndb/tests/unit/test_model.py @@ -14,30 +14,31 @@ import datetime import pickle -import pytz import types import zlib - from unittest import mock -from google.cloud import datastore +import pytest +import pytz from google.cloud.datastore import entity as entity_module -from google.cloud.datastore import key as ds_key_module from google.cloud.datastore import helpers +from google.cloud.datastore import key as ds_key_module from google.cloud.datastore_v1 import types as ds_types from google.cloud.datastore_v1.types import entity as entity_pb2 -import pytest -from google.cloud.ndb import _datastore_types -from google.cloud.ndb import exceptions +from google.cloud import datastore +from google.cloud.ndb import ( + _datastore_types, + _legacy_entity_pb, + _options, + exceptions, + model, + polymodel, + tasklets, +) from google.cloud.ndb import key as key_module -from google.cloud.ndb import model -from google.cloud.ndb import _options -from google.cloud.ndb import polymodel from google.cloud.ndb import query as query_module -from google.cloud.ndb import tasklets from google.cloud.ndb import utils as ndb_utils -from google.cloud.ndb import _legacy_entity_pb from . import utils @@ -2286,7 +2287,7 @@ def test__to_base_type(): def test__to_base_type_converted(): prop = model.CompressedTextProperty(name="text") value = b"\xe2\x98\x83" - assert prop._to_base_type("\N{snowman}") == value + assert prop._to_base_type("\N{SNOWMAN}") == value @staticmethod def test__from_base_type(): @@ -2297,7 +2298,7 @@ def test__from_base_type(): def test__from_base_type_converted(): prop = model.CompressedTextProperty(name="text") value = b"\xe2\x98\x83" - assert prop._from_base_type(value) == "\N{snowman}" + assert prop._from_base_type(value) == "\N{SNOWMAN}" @staticmethod def test__from_base_type_cannot_convert(): @@ -2366,7 +2367,7 @@ def test__to_base_type(): @staticmethod def test__to_base_type_converted(): prop = model.TextProperty(name="text") - value = "\N{snowman}" + value = "\N{SNOWMAN}" assert prop._to_base_type(b"\xe2\x98\x83") == value @staticmethod @@ -2378,7 +2379,7 @@ def test__from_base_type(): def test__from_base_type_converted(): prop = model.TextProperty(name="text") value = b"\xe2\x98\x83" - assert prop._from_base_type(value) == "\N{snowman}" + assert prop._from_base_type(value) == "\N{SNOWMAN}" @staticmethod def test__from_base_type_cannot_convert(): @@ -2529,7 +2530,7 @@ def test__validate_incorrect_type(): @staticmethod def test__to_base_type(): prop = model.JsonProperty(name="json-val") - value = [14, [15, 16], {"seventeen": 18}, "\N{snowman}"] + value = [14, [15, 16], {"seventeen": 18}, "\N{SNOWMAN}"] expected = b'[14,[15,16],{"seventeen":18},"\\u2603"]' assert prop._to_base_type(value) == expected @@ -2537,14 +2538,14 @@ def test__to_base_type(): def test__from_base_type(): prop = model.JsonProperty(name="json-val") value = b'[14,true,{"a":null,"b":"\\u2603"}]' - expected = [14, True, {"a": None, "b": "\N{snowman}"}] + expected = [14, True, {"a": None, "b": "\N{SNOWMAN}"}] assert prop._from_base_type(value) == expected @staticmethod def test__from_base_type_str(): prop = model.JsonProperty(name="json-val") value = '[14,true,{"a":null,"b":"\\u2603"}]' - expected = [14, True, {"a": None, "b": "\N{snowman}"}] + expected = [14, True, {"a": None, "b": "\N{SNOWMAN}"}] assert prop._from_base_type(value) == expected @@ -4330,7 +4331,7 @@ class Mine(model.Model): second = model.StringProperty() expected = ( - "Mine" + "Mine" ) assert repr(Mine) == expected @@ -4549,7 +4550,7 @@ def test_repr_with_property_named_key_not_set(): ManyFields = ManyFieldsFactory() entity = ManyFields(self=909, id="hi", value=None, _id=78) expected = ( - "ManyFields(_key=Key('ManyFields', 78), id='hi', " "self=909, value=None)" + "ManyFields(_key=Key('ManyFields', 78), id='hi', self=909, value=None)" ) assert repr(entity) == expected diff --git a/packages/google-cloud-ndb/tests/unit/test_polymodel.py b/packages/google-cloud-ndb/tests/unit/test_polymodel.py index d217279b08ff..ffb0b0fba178 100644 --- a/packages/google-cloud-ndb/tests/unit/test_polymodel.py +++ b/packages/google-cloud-ndb/tests/unit/test_polymodel.py @@ -15,12 +15,10 @@ from unittest import mock import pytest +from google.cloud.datastore import helpers from google.cloud import datastore -from google.cloud.datastore import helpers -from google.cloud.ndb import model -from google.cloud.ndb import polymodel -from google.cloud.ndb import query +from google.cloud.ndb import model, polymodel, query from . import utils diff --git a/packages/google-cloud-ndb/tests/unit/test_query.py b/packages/google-cloud-ndb/tests/unit/test_query.py index 33b560b42e82..e8233afac84a 100644 --- a/packages/google-cloud-ndb/tests/unit/test_query.py +++ b/packages/google-cloud-ndb/tests/unit/test_query.py @@ -13,21 +13,21 @@ # limitations under the License. import pickle - from unittest import mock import pytest - from google.cloud.datastore import entity as datastore_entity from google.cloud.datastore import helpers -from google.cloud.ndb import _datastore_api -from google.cloud.ndb import _datastore_query -from google.cloud.ndb import exceptions +from google.cloud.ndb import ( + _datastore_api, + _datastore_query, + exceptions, + model, + tasklets, +) from google.cloud.ndb import key as key_module -from google.cloud.ndb import model from google.cloud.ndb import query as query_module -from google.cloud.ndb import tasklets from . import utils diff --git a/packages/google-cloud-ndb/tests/unit/test_stats.py b/packages/google-cloud-ndb/tests/unit/test_stats.py index 265d45e629c0..6d3b9a04a9ad 100644 --- a/packages/google-cloud-ndb/tests/unit/test_stats.py +++ b/packages/google-cloud-ndb/tests/unit/test_stats.py @@ -18,7 +18,6 @@ from . import utils - DEFAULTS = { "bytes": 4, "count": 2, @@ -215,7 +214,7 @@ def test_constructor(): kind_name="test_stat", property_name="test_name", property_type="test_type", - **DEFAULTS + **DEFAULTS, ) assert stat.bytes == 4 assert stat.count == 2 @@ -306,7 +305,7 @@ def test_constructor(): kind_name="test_stat", property_name="test_name", property_type="test_type", - **DEFAULTS + **DEFAULTS, ) assert stat.bytes == 4 assert stat.count == 2 diff --git a/packages/google-cloud-ndb/tests/unit/test_tasklets.py b/packages/google-cloud-ndb/tests/unit/test_tasklets.py index b88c1af2c561..9c9d9b6a6683 100644 --- a/packages/google-cloud-ndb/tests/unit/test_tasklets.py +++ b/packages/google-cloud-ndb/tests/unit/test_tasklets.py @@ -16,11 +16,8 @@ import pytest +from google.cloud.ndb import _eventloop, _remote, exceptions, tasklets from google.cloud.ndb import context as context_module -from google.cloud.ndb import _eventloop -from google.cloud.ndb import exceptions -from google.cloud.ndb import _remote -from google.cloud.ndb import tasklets from . import utils @@ -451,8 +448,9 @@ def test___repr__(): this, that = (tasklets.Future("this"), tasklets.Future("that")) future = tasklets._MultiFuture((this, that)) assert repr(future) == ( - "_MultiFuture(Future('this') <{}>," - " Future('that') <{}>) <{}>".format(id(this), id(that), id(future)) + "_MultiFuture(Future('this') <{}>, Future('that') <{}>) <{}>".format( + id(this), id(that), id(future) + ) ) @staticmethod diff --git a/packages/google-cloud-ndb/tests/unit/test_utils.py b/packages/google-cloud-ndb/tests/unit/test_utils.py index d22ebc5718ec..571aa5ada0ed 100644 --- a/packages/google-cloud-ndb/tests/unit/test_utils.py +++ b/packages/google-cloud-ndb/tests/unit/test_utils.py @@ -13,7 +13,6 @@ # limitations under the License. import threading - from unittest import mock import pytest From a76861bb526a56552b3fa5a104db42358be0bec0 Mon Sep 17 00:00:00 2001 From: Chalmer Lowe Date: Tue, 2 Jun 2026 13:27:32 -0400 Subject: [PATCH 004/174] chore(spanner): fix event loop leak in unit tests (#17343) This PR resolves leaky asyncio event loops inside the Spanner unit tests that were causing flaky results during local nox testing. The original version of the event loop was not closing out events and we were left with too many open files. Fixes #17049 --- .../tests/unit/gapic/conftest.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/google-cloud-spanner/tests/unit/gapic/conftest.py b/packages/google-cloud-spanner/tests/unit/gapic/conftest.py index 22ba265871d4..529569445c0f 100644 --- a/packages/google-cloud-spanner/tests/unit/gapic/conftest.py +++ b/packages/google-cloud-spanner/tests/unit/gapic/conftest.py @@ -11,10 +11,14 @@ def provide_loop_to_sync_grpc_tests(): If no global loop exists, `grpc.aio` engine crashes during initialization. """ try: - loop = asyncio.get_event_loop() + asyncio.get_running_loop() except RuntimeError: loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) - - yield - # No close here, just ensure existance + try: + yield + finally: + loop.close() + asyncio.set_event_loop(None) + else: + yield From 01dbac53064fc0bbdc5d5925b431d0dffbfd6fed Mon Sep 17 00:00:00 2001 From: Chalmer Lowe Date: Tue, 2 Jun 2026 13:27:59 -0400 Subject: [PATCH 005/174] chore(resumable-media): add prerelease_deps and core_deps_from_source nox sessions (#17341) This PR adds missing `prerelease_deps` and `core_deps_from_source` nox sessions for the google-resumable-media package. Changes to each nox session are based on the versions found in the **gapic-generator** [`noxfile.py.j2` template](https://github.com/googleapis/google-cloud-python/blob/main/packages/gapic-generator/gapic/templates/noxfile.py.j2). Fixes #17053 --- packages/google-resumable-media/noxfile.py | 151 +++++++++++++++++++-- 1 file changed, 141 insertions(+), 10 deletions(-) diff --git a/packages/google-resumable-media/noxfile.py b/packages/google-resumable-media/noxfile.py index 8271d1216b8a..a1c1ae199709 100644 --- a/packages/google-resumable-media/noxfile.py +++ b/packages/google-resumable-media/noxfile.py @@ -15,6 +15,7 @@ from __future__ import absolute_import import os import pathlib +import re import shutil import nox @@ -303,17 +304,147 @@ def cover(session): @nox.session(python=DEFAULT_PYTHON_VERSION) def prerelease_deps(session): - # TODO(https://github.com/googleapis/google-cloud-python/issues/16014): - # Resolve the linked bug once prerelease_deps and core_deps_from_source - # are implemented for this package. - if session.python == DEFAULT_PYTHON_VERSION: - session.skip(f"Skipping prerelease_deps for {DEFAULT_PYTHON_VERSION} until a future release.") + """ + Run all tests with pre-release versions of dependencies installed + rather than the standard non pre-release versions. + Pre-release versions can be installed using + `pip install --pre `. + """ + + # Install standard test dependencies, then install local packages in-place. + session.install("mock", "pytest", "pytest-cov", "pytest-asyncio<=0.14.0", "brotli") + session.install("-e", ".[requests,aiohttp]") + + # Because we test minimum dependency versions on the minimum Python + # version, the first version we test with in the unit tests sessions has a + # constraints file containing all dependencies and extras. + with open( + CURRENT_DIRECTORY / "testing" / f"constraints-{UNIT_TEST_PYTHON_VERSIONS[0]}.txt", + encoding="utf-8", + ) as constraints_file: + constraints_text = constraints_file.read() + + # Ignore leading whitespace and comment lines. + constraints_deps = [ + match.group(1) + for match in re.finditer( + r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE + ) + ] + + # Install dependencies specified in `testing/constraints-X.txt`. + session.install(*constraints_deps) + + # Note: If a dependency is added to the `prerel_deps` list, + # the `core_dependencies_from_source` list in the `core_deps_from_source` + # nox session should also be updated. + prerel_deps = [ + "google-crc32c", + "google-auth", + "cryptography", + "cffi", + "cachetools", + "rsa", + "pyasn1", + ] + + deps_dir = CURRENT_DIRECTORY.parent + while deps_dir.name != "packages" and deps_dir.parent != deps_dir: + deps_dir = deps_dir.parent + + # Extract the base package name, safely ignoring version bounds and spaces + # (e.g., "grpcio>=1.75.1" becomes "grpcio") + parsed_deps = { + dep: re.match(r"^([a-zA-Z0-9_-]+)", dep).group(1) for dep in prerel_deps + } + + # Dynamically sort local packages vs PyPI dependencies + local_paths = [] + pypi_deps = [] + + for dep, pkg_name in parsed_deps.items(): + if (deps_dir / pkg_name).exists(): + local_paths.append(str(deps_dir / pkg_name)) + else: + pypi_deps.append(dep) + + # Batch pip installations to avoid sequential overhead + if local_paths: + session.install(*local_paths, "--no-deps", "--ignore-installed") + if pypi_deps: + session.install(*pypi_deps, "--pre", "--no-deps", "--ignore-installed") + + # Reuse the parsed names for logging and version verification + for dep, pkg_name in parsed_deps.items(): + print(f"Installed {dep}") + + session.run( + "py.test", + os.path.join("tests", "unit"), + os.path.join("tests_async", "unit"), + *session.posargs, + ) @nox.session(python=DEFAULT_PYTHON_VERSION) def core_deps_from_source(session): - ## TODO(https://github.com/googleapis/google-cloud-python/issues/16014): - # Resolve the linked bug once prerelease_deps and core_deps_from_source - # are implemented for this package. - if session.python == DEFAULT_PYTHON_VERSION: - session.skip(f"Skipping core_deps_from_source for {DEFAULT_PYTHON_VERSION} until a future release.") + """Run all tests with core dependencies installed from source + rather than pulling the dependencies from PyPI. + """ + + # Install standard test dependencies, then install local packages in-place. + session.install("mock", "pytest", "pytest-cov", "pytest-asyncio<=0.14.0", "brotli") + session.install("-e", ".[requests,aiohttp]") + + # Because we test minimum dependency versions on the minimum Python + # version, the first version we test with in the unit tests sessions has a + # constraints file containing all dependencies and extras. + with open( + CURRENT_DIRECTORY / "testing" / f"constraints-{UNIT_TEST_PYTHON_VERSIONS[0]}.txt", + encoding="utf-8", + ) as constraints_file: + constraints_text = constraints_file.read() + + # Ignore leading whitespace and comment lines. + constraints_deps = [ + match.group(1) + for match in re.finditer( + r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE + ) + ] + + # Install dependencies specified in `testing/constraints-X.txt`. + session.install(*constraints_deps) + + # Note: If a dependency is added to the `core_dependencies_from_source` list, + # the `prerel_deps` list in the `prerelease_deps` nox session should also be updated. + core_dependencies_from_source = [ + "google-crc32c", + "google-auth", + ] + + deps_dir = CURRENT_DIRECTORY.parent + while deps_dir.name != "packages" and deps_dir.parent != deps_dir: + deps_dir = deps_dir.parent + + # Batch the pip installation to avoid sequential overhead + dep_paths = [str(deps_dir / dep) for dep in core_dependencies_from_source] + + session.install(*dep_paths, "--no-deps", "--ignore-installed") + print(f"Installed {', '.join(core_dependencies_from_source)} locally from {deps_dir}") + + other_deps = [ + "cryptography", + "cffi", + "cachetools", + "rsa", + "pyasn1", + ] + session.install(*other_deps) + + session.run( + "py.test", + os.path.join("tests", "unit"), + os.path.join("tests_async", "unit"), + *session.posargs, + ) From 12817900fd11e68067a5ce9b4254fa8703e864d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Swe=C3=B1a=20=28Swast=29?= Date: Tue, 2 Jun 2026 12:51:24 -0500 Subject: [PATCH 006/174] fix(google-cloud-bigquery): include pyopenssl as a dependency (#17345) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This seems to be required when I do a fresh Python 3.14 install. Also, - updates the pandas tests to relax data type assertions on timestamp/datetime. See internal issue b/516834095#comment8 🦕 --- packages/google-cloud-bigquery/pyproject.toml | 2 +- .../tests/system/test_pandas.py | 18 +++++++++--------- .../tests/unit/test_magics.py | 14 +++++++------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/google-cloud-bigquery/pyproject.toml b/packages/google-cloud-bigquery/pyproject.toml index f342efcbfd63..406872e9d1f4 100644 --- a/packages/google-cloud-bigquery/pyproject.toml +++ b/packages/google-cloud-bigquery/pyproject.toml @@ -42,7 +42,7 @@ classifiers = [ ] dependencies = [ "google-api-core[grpc] >= 2.11.1, < 3.0.0", - "google-auth >= 2.14.1, < 3.0.0", + "google-auth[pyopenssl] >= 2.14.1, < 3.0.0", "google-cloud-core >= 2.4.1, < 3.0.0", "google-resumable-media >= 2.0.0, < 3.0.0", "packaging >= 24.2.0", diff --git a/packages/google-cloud-bigquery/tests/system/test_pandas.py b/packages/google-cloud-bigquery/tests/system/test_pandas.py index 8a0a16475033..d1031436ec32 100644 --- a/packages/google-cloud-bigquery/tests/system/test_pandas.py +++ b/packages/google-cloud-bigquery/tests/system/test_pandas.py @@ -17,8 +17,8 @@ import collections import datetime import decimal -import json import io +import json import operator import warnings @@ -31,12 +31,10 @@ import importlib_metadata as metadata from google.cloud import bigquery - from google.cloud.bigquery import enums from . import helpers - pandas = pytest.importorskip("pandas", minversion="0.23.0") pyarrow = pytest.importorskip("pyarrow") numpy = pytest.importorskip("numpy") @@ -957,8 +955,7 @@ def get_rows(): def test_nested_table_to_dataframe(bigquery_client, dataset_id): - from google.cloud.bigquery.job import SourceFormat - from google.cloud.bigquery.job import WriteDisposition + from google.cloud.bigquery.job import SourceFormat, WriteDisposition SF = bigquery.SchemaField schema = [ @@ -1085,10 +1082,13 @@ def test_list_rows_nullable_scalars_dtypes(bigquery_client, scalars_table, max_r ).to_dataframe() assert df.dtypes["bool_col"].name == "boolean" - assert df.dtypes["datetime_col"].name == "datetime64[ns]" + assert df.dtypes["datetime_col"].name in ("datetime64[us]", "datetime64[ns]") assert df.dtypes["float64_col"].name == "float64" assert df.dtypes["int64_col"].name == "Int64" - assert df.dtypes["timestamp_col"].name == "datetime64[ns, UTC]" + assert df.dtypes["timestamp_col"].name in ( + "datetime64[us, UTC]", + "datetime64[ns, UTC]", + ) assert df.dtypes["date_col"].name == "dbdate" assert df.dtypes["time_col"].name == "dbtime" @@ -1389,8 +1389,8 @@ def test_to_geodataframe(bigquery_client, dataset_id): def test_load_geodataframe(bigquery_client, dataset_id): geopandas = pytest.importorskip("geopandas") import pandas - from shapely import wkt from google.cloud.bigquery.schema import SchemaField + from shapely import wkt df = geopandas.GeoDataFrame( pandas.DataFrame( @@ -1450,8 +1450,8 @@ def test_load_dataframe_w_shapely(bigquery_client, dataset_id): def test_load_dataframe_w_wkb(bigquery_client, dataset_id): wkt = pytest.importorskip("shapely.wkt") - from shapely import wkb from google.cloud.bigquery.schema import SchemaField + from shapely import wkb df = pandas.DataFrame( dict(name=["foo", "bar"], geo=[None, wkb.dumps(wkt.loads("Point(1 1)"))]) diff --git a/packages/google-cloud-bigquery/tests/unit/test_magics.py b/packages/google-cloud-bigquery/tests/unit/test_magics.py index 8eaf944041ac..f679d2806bc1 100644 --- a/packages/google-cloud-bigquery/tests/unit/test_magics.py +++ b/packages/google-cloud-bigquery/tests/unit/test_magics.py @@ -14,22 +14,20 @@ import copy import re +import warnings from concurrent import futures from unittest import mock -import warnings -from google.api_core import exceptions import google.auth.credentials import pytest -from tests.unit.helpers import make_connection -from test_utils.imports import maybe_fail_import - +from google.api_core import exceptions from google.cloud import bigquery from google.cloud.bigquery import exceptions as bq_exceptions -from google.cloud.bigquery import job -from google.cloud.bigquery import table +from google.cloud.bigquery import job, table from google.cloud.bigquery.retry import DEFAULT_TIMEOUT +from test_utils.imports import maybe_fail_import +from tests.unit.helpers import make_connection try: from google.cloud.bigquery.magics import magics @@ -2138,6 +2136,7 @@ def test_bigquery_magic_w_destination_table(monkeypatch): magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) + magics.context._project = "test-project" create_dataset_if_necessary_patch = mock.patch( "google.cloud.bigquery.magics.magics._create_dataset_if_necessary", @@ -2171,6 +2170,7 @@ def test_bigquery_magic_create_dataset_fails(monkeypatch): magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) + magics.context._project = "test-project" create_dataset_if_necessary_patch = mock.patch( "google.cloud.bigquery.magics.magics._create_dataset_if_necessary", From 34ca90e7e741d1599ae58e796a90a9168169023a Mon Sep 17 00:00:00 2001 From: Shenyang Cai Date: Tue, 2 Jun 2026 11:53:42 -0700 Subject: [PATCH 007/174] chore(bigframes): move some ai accessor tests outside the SQLGlot compiler dir (#17318) These tests do not generate golden SQLs, so it makes less sense to place them under the SQLGlot test directory. This is a follow-up to https://github.com/googleapis/google-cloud-python/pull/17302 --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- .../sqlglot/test_dataframe_accessor.py | 292 ------------------ .../tests/unit/extensions/core/__init__.py | 13 + .../core/test_dataframe_accessor.py | 277 +++++++++++++++++ 3 files changed, 290 insertions(+), 292 deletions(-) create mode 100644 packages/bigframes/tests/unit/extensions/core/__init__.py create mode 100644 packages/bigframes/tests/unit/extensions/core/test_dataframe_accessor.py diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/test_dataframe_accessor.py b/packages/bigframes/tests/unit/core/compile/sqlglot/test_dataframe_accessor.py index cae16d522f0c..26e4d1788059 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/test_dataframe_accessor.py +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/test_dataframe_accessor.py @@ -58,295 +58,3 @@ def test_bigframes_sql_scalar(scalar_types_df: bpd.DataFrame, snapshot): # Bigframes implementation returns a bigframes.series.Series sql, _, _ = result.to_frame()._to_sql_query(include_index=True) snapshot.assert_match(sql, "out.sql") - - -def test_ai_forecast(snapshot, monkeypatch): - import bigframes.bigquery.ai - import bigframes.session - - session = mock.create_autospec(bigframes.session.Session) - bf_df = mock.create_autospec(bpd.DataFrame) - session.read_pandas.return_value = bf_df - - def mock_ai_forecast(df, **kwargs): - assert df is bf_df - result_df = mock.create_autospec(bpd.DataFrame) - result_df.to_pandas.return_value = kwargs - return result_df - - import bigframes.bigquery.ai - - monkeypatch.setattr(bigframes.bigquery.ai, "forecast", mock_ai_forecast) - - df = pd.DataFrame({"date": ["2020-01-01"], "value": [1.0]}) - result = df.bigquery.ai.forecast( - timestamp_col="date", - data_col="value", - horizon=5, - session=session, - ) - - session.read_pandas.assert_called_once() - assert result == { - "timestamp_col": "date", - "data_col": "value", - "model": "TimesFM 2.0", - "id_cols": None, - "horizon": 5, - "confidence_level": 0.95, - "context_window": None, - "output_historical_time_series": False, - } - - -def test_bigframes_ai_forecast(snapshot, monkeypatch): - import bigframes.bigquery.ai - import bigframes.session - - session = mock.create_autospec(bigframes.session.Session) - bf_df = mock.create_autospec(bpd.DataFrame) - - def mock_ai_forecast(df, **kwargs): - assert df is bf_df - result_df = mock.create_autospec(bpd.DataFrame) - return result_df - - monkeypatch.setattr(bigframes.bigquery.ai, "forecast", mock_ai_forecast) - - result = bf_df.bigquery.ai.forecast( - timestamp_col="date", - data_col="value", - horizon=5, - session=session, - ) - - session.read_pandas.assert_not_called() - # BigFrames accessor returns the bf_df directly without calling to_pandas - assert result is not None - - -def test_ai_generate(monkeypatch): - import bigframes.bigquery.ai - - def mock_generate(prompt, **kwargs): - result_series = mock.create_autospec(bpd.Series) - result_series.to_pandas.return_value = (prompt, kwargs) - return result_series - - monkeypatch.setattr(bigframes.bigquery.ai, "generate", mock_generate) - - df = pd.DataFrame({"text_input": ["Is this a positive review?"]}) - result = df.bigquery.ai.generate( - df["text_input"], - connection_id="conn", - endpoint="endpoint", - request_type="dedicated", - model_params={"temp": 0.5}, - output_schema={"res": "STRING"}, - ) - - assert result == ( - df["text_input"], - { - "connection_id": "conn", - "endpoint": "endpoint", - "request_type": "dedicated", - "model_params": {"temp": 0.5}, - "output_schema": {"res": "STRING"}, - }, - ) - - -def test_bigframes_ai_generate(scalar_types_df: bpd.DataFrame, monkeypatch): - import bigframes.bigquery.ai - import bigframes.session - - session = mock.create_autospec(bigframes.session.Session) - bf_series = mock.create_autospec(bpd.Series) - - def mock_generate(prompt, **kwargs): - assert prompt is bf_series - result_series = mock.create_autospec(bpd.Series) - return result_series - - monkeypatch.setattr(bigframes.bigquery.ai, "generate", mock_generate) - - result = scalar_types_df.bigquery.ai.generate( - bf_series, - connection_id="conn", - endpoint="endpoint", - request_type="dedicated", - model_params={"temp": 0.5}, - output_schema={"res": "STRING"}, - ) - - session.read_pandas.assert_not_called() - assert result is not None - - -def test_ai_generate_bool(monkeypatch): - import bigframes.bigquery.ai - - def mock_generate_bool(prompt, **kwargs): - result_series = mock.create_autospec(bpd.Series) - result_series.to_pandas.return_value = (prompt, kwargs) - return result_series - - monkeypatch.setattr(bigframes.bigquery.ai, "generate_bool", mock_generate_bool) - - df = pd.DataFrame({"text_input": ["Is this a positive review?"]}) - result = df.bigquery.ai.generate_bool( - df["text_input"], - connection_id="conn", - endpoint="endpoint", - request_type="dedicated", - model_params={"temp": 0.5}, - ) - - assert result == ( - df["text_input"], - { - "connection_id": "conn", - "endpoint": "endpoint", - "request_type": "dedicated", - "model_params": {"temp": 0.5}, - }, - ) - - -def test_bigframes_ai_generate_bool(scalar_types_df: bpd.DataFrame, monkeypatch): - import bigframes.bigquery.ai - import bigframes.session - - session = mock.create_autospec(bigframes.session.Session) - bf_series = mock.create_autospec(bpd.Series) - - def mock_generate_bool(prompt, **kwargs): - assert prompt is bf_series - result_series = mock.create_autospec(bpd.Series) - return result_series - - monkeypatch.setattr(bigframes.bigquery.ai, "generate_bool", mock_generate_bool) - - result = scalar_types_df.bigquery.ai.generate_bool( - bf_series, - connection_id="conn", - endpoint="endpoint", - request_type="dedicated", - model_params={"temp": 0.5}, - ) - - session.read_pandas.assert_not_called() - assert result is not None - - -def test_ai_generate_int(monkeypatch): - import bigframes.bigquery.ai - - def mock_generate_int(prompt, **kwargs): - result_series = mock.create_autospec(bpd.Series) - result_series.to_pandas.return_value = (prompt, kwargs) - return result_series - - monkeypatch.setattr(bigframes.bigquery.ai, "generate_int", mock_generate_int) - - df = pd.DataFrame({"text_input": ["How many legs?"]}) - result = df.bigquery.ai.generate_int( - df["text_input"], - connection_id="conn", - endpoint="endpoint", - request_type="dedicated", - model_params={"temp": 0.5}, - ) - - assert result == ( - df["text_input"], - { - "connection_id": "conn", - "endpoint": "endpoint", - "request_type": "dedicated", - "model_params": {"temp": 0.5}, - }, - ) - - -def test_bigframes_ai_generate_int(scalar_types_df: bpd.DataFrame, monkeypatch): - import bigframes.bigquery.ai - import bigframes.session - - session = mock.create_autospec(bigframes.session.Session) - bf_series = mock.create_autospec(bpd.Series) - - def mock_generate_int(prompt, **kwargs): - assert prompt is bf_series - result_series = mock.create_autospec(bpd.Series) - return result_series - - monkeypatch.setattr(bigframes.bigquery.ai, "generate_int", mock_generate_int) - - result = scalar_types_df.bigquery.ai.generate_int( - bf_series, - connection_id="conn", - endpoint="endpoint", - request_type="dedicated", - model_params={"temp": 0.5}, - ) - - session.read_pandas.assert_not_called() - assert result is not None - - -def test_ai_generate_double(monkeypatch): - import bigframes.bigquery.ai - - def mock_generate_double(prompt, **kwargs): - result_series = mock.create_autospec(bpd.Series) - result_series.to_pandas.return_value = (prompt, kwargs) - return result_series - - monkeypatch.setattr(bigframes.bigquery.ai, "generate_double", mock_generate_double) - - df = pd.DataFrame({"text_input": ["How tall?"]}) - result = df.bigquery.ai.generate_double( - df["text_input"], - connection_id="conn", - endpoint="endpoint", - request_type="dedicated", - model_params={"temp": 0.5}, - ) - - assert result == ( - df["text_input"], - { - "connection_id": "conn", - "endpoint": "endpoint", - "request_type": "dedicated", - "model_params": {"temp": 0.5}, - }, - ) - - -def test_bigframes_ai_generate_double(scalar_types_df: bpd.DataFrame, monkeypatch): - import bigframes.bigquery.ai - import bigframes.session - - session = mock.create_autospec(bigframes.session.Session) - bf_series = mock.create_autospec(bpd.Series) - - def mock_generate_double(prompt, **kwargs): - assert prompt is bf_series - result_series = mock.create_autospec(bpd.Series) - return result_series - - monkeypatch.setattr(bigframes.bigquery.ai, "generate_double", mock_generate_double) - - result = scalar_types_df.bigquery.ai.generate_double( - bf_series, - connection_id="conn", - endpoint="endpoint", - request_type="dedicated", - model_params={"temp": 0.5}, - ) - - session.read_pandas.assert_not_called() - assert result is not None diff --git a/packages/bigframes/tests/unit/extensions/core/__init__.py b/packages/bigframes/tests/unit/extensions/core/__init__.py new file mode 100644 index 000000000000..58d482ea3866 --- /dev/null +++ b/packages/bigframes/tests/unit/extensions/core/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2026 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/packages/bigframes/tests/unit/extensions/core/test_dataframe_accessor.py b/packages/bigframes/tests/unit/extensions/core/test_dataframe_accessor.py new file mode 100644 index 000000000000..914a448700f4 --- /dev/null +++ b/packages/bigframes/tests/unit/extensions/core/test_dataframe_accessor.py @@ -0,0 +1,277 @@ +# Copyright 2026 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 unittest.mock as mock + +import pandas as pd + +import bigframes.bigquery.ai +import bigframes.pandas as bpd +import bigframes.session + + +def test_ai_forecast(monkeypatch): + session = mock.create_autospec(bigframes.session.Session) + bf_df = mock.create_autospec(bpd.DataFrame) + session.read_pandas.return_value = bf_df + + def mock_ai_forecast(df, **kwargs): + assert df is bf_df + result_df = mock.create_autospec(bpd.DataFrame) + result_df.to_pandas.return_value = kwargs + return result_df + + monkeypatch.setattr(bigframes.bigquery.ai, "forecast", mock_ai_forecast) + + df = pd.DataFrame({"date": ["2020-01-01"], "value": [1.0]}) + result = df.bigquery.ai.forecast( + timestamp_col="date", + data_col="value", + horizon=5, + session=session, + ) + + session.read_pandas.assert_called_once() + assert result == { + "timestamp_col": "date", + "data_col": "value", + "model": "TimesFM 2.0", + "id_cols": None, + "horizon": 5, + "confidence_level": 0.95, + "context_window": None, + "output_historical_time_series": False, + } + + +def test_bigframes_ai_forecast(monkeypatch): + session = mock.create_autospec(bigframes.session.Session) + bf_df = mock.create_autospec(bpd.DataFrame) + + def mock_ai_forecast(df, **kwargs): + assert df is bf_df + result_df = mock.create_autospec(bpd.DataFrame) + return result_df + + monkeypatch.setattr(bigframes.bigquery.ai, "forecast", mock_ai_forecast) + + result = bf_df.bigquery.ai.forecast( + timestamp_col="date", + data_col="value", + horizon=5, + session=session, + ) + + session.read_pandas.assert_not_called() + # BigFrames accessor returns the bf_df directly without calling to_pandas + assert result is not None + + +def test_ai_generate(monkeypatch): + def mock_generate(prompt, **kwargs): + result_series = mock.create_autospec(bpd.Series) + result_series.to_pandas.return_value = (prompt, kwargs) + return result_series + + monkeypatch.setattr(bigframes.bigquery.ai, "generate", mock_generate) + + df = pd.DataFrame({"text_input": ["Is this a positive review?"]}) + result = df.bigquery.ai.generate( + df["text_input"], + connection_id="conn", + endpoint="endpoint", + request_type="dedicated", + model_params={"temp": 0.5}, + output_schema={"res": "STRING"}, + ) + + assert result == ( + df["text_input"], + { + "connection_id": "conn", + "endpoint": "endpoint", + "request_type": "dedicated", + "model_params": {"temp": 0.5}, + "output_schema": {"res": "STRING"}, + }, + ) + + +def test_bigframes_ai_generate(scalar_types_df: bpd.DataFrame, monkeypatch): + bf_series = mock.create_autospec(bpd.Series) + result_series = mock.create_autospec(bpd.Series) + + def mock_generate(prompt, **kwargs): + assert prompt is bf_series + return result_series + + monkeypatch.setattr(bigframes.bigquery.ai, "generate", mock_generate) + + result = scalar_types_df.bigquery.ai.generate( + bf_series, + connection_id="conn", + endpoint="endpoint", + request_type="dedicated", + model_params={"temp": 0.5}, + output_schema={"res": "STRING"}, + ) + + assert result is result_series + + +def test_ai_generate_bool(monkeypatch): + def mock_generate_bool(prompt, **kwargs): + result_series = mock.create_autospec(bpd.Series) + result_series.to_pandas.return_value = (prompt, kwargs) + return result_series + + monkeypatch.setattr(bigframes.bigquery.ai, "generate_bool", mock_generate_bool) + + df = pd.DataFrame({"text_input": ["Is this a positive review?"]}) + result = df.bigquery.ai.generate_bool( + df["text_input"], + connection_id="conn", + endpoint="endpoint", + request_type="dedicated", + model_params={"temp": 0.5}, + ) + + assert result == ( + df["text_input"], + { + "connection_id": "conn", + "endpoint": "endpoint", + "request_type": "dedicated", + "model_params": {"temp": 0.5}, + }, + ) + + +def test_bigframes_ai_generate_bool(scalar_types_df: bpd.DataFrame, monkeypatch): + bf_series = mock.create_autospec(bpd.Series) + result_series = mock.create_autospec(bpd.Series) + + def mock_generate_bool(prompt, **kwargs): + assert prompt is bf_series + return result_series + + monkeypatch.setattr(bigframes.bigquery.ai, "generate_bool", mock_generate_bool) + + result = scalar_types_df.bigquery.ai.generate_bool( + bf_series, + connection_id="conn", + endpoint="endpoint", + request_type="dedicated", + model_params={"temp": 0.5}, + ) + + assert result is result_series + + +def test_ai_generate_int(monkeypatch): + def mock_generate_int(prompt, **kwargs): + result_series = mock.create_autospec(bpd.Series) + result_series.to_pandas.return_value = (prompt, kwargs) + return result_series + + monkeypatch.setattr(bigframes.bigquery.ai, "generate_int", mock_generate_int) + + df = pd.DataFrame({"text_input": ["How many legs?"]}) + result = df.bigquery.ai.generate_int( + df["text_input"], + connection_id="conn", + endpoint="endpoint", + request_type="dedicated", + model_params={"temp": 0.5}, + ) + + assert result == ( + df["text_input"], + { + "connection_id": "conn", + "endpoint": "endpoint", + "request_type": "dedicated", + "model_params": {"temp": 0.5}, + }, + ) + + +def test_bigframes_ai_generate_int(scalar_types_df: bpd.DataFrame, monkeypatch): + bf_series = mock.create_autospec(bpd.Series) + result_series = mock.create_autospec(bpd.Series) + + def mock_generate_int(prompt, **kwargs): + assert prompt is bf_series + return result_series + + monkeypatch.setattr(bigframes.bigquery.ai, "generate_int", mock_generate_int) + + result = scalar_types_df.bigquery.ai.generate_int( + bf_series, + connection_id="conn", + endpoint="endpoint", + request_type="dedicated", + model_params={"temp": 0.5}, + ) + + assert result is result_series + + +def test_ai_generate_double(monkeypatch): + def mock_generate_double(prompt, **kwargs): + result_series = mock.create_autospec(bpd.Series) + result_series.to_pandas.return_value = (prompt, kwargs) + return result_series + + monkeypatch.setattr(bigframes.bigquery.ai, "generate_double", mock_generate_double) + + df = pd.DataFrame({"text_input": ["How tall?"]}) + result = df.bigquery.ai.generate_double( + df["text_input"], + connection_id="conn", + endpoint="endpoint", + request_type="dedicated", + model_params={"temp": 0.5}, + ) + + assert result == ( + df["text_input"], + { + "connection_id": "conn", + "endpoint": "endpoint", + "request_type": "dedicated", + "model_params": {"temp": 0.5}, + }, + ) + + +def test_bigframes_ai_generate_double(scalar_types_df: bpd.DataFrame, monkeypatch): + bf_series = mock.create_autospec(bpd.Series) + result_series = mock.create_autospec(bpd.Series) + + def mock_generate_double(prompt, **kwargs): + assert prompt is bf_series + return result_series + + monkeypatch.setattr(bigframes.bigquery.ai, "generate_double", mock_generate_double) + + result = scalar_types_df.bigquery.ai.generate_double( + bf_series, + connection_id="conn", + endpoint="endpoint", + request_type="dedicated", + model_params={"temp": 0.5}, + ) + + assert result is result_series From 0953133e8a7d72b301a0d6582e55618565279521 Mon Sep 17 00:00:00 2001 From: Anthonios Partheniou Date: Tue, 2 Jun 2026 15:40:56 -0400 Subject: [PATCH 008/174] tests(gapic-generator): ensure tests run with Protobuf 7.x (#17348) Towards https://github.com/googleapis/google-cloud-python/issues/16001 --- .../gapic/templates/testing/constraints-3.13.txt.j2 | 2 +- .../gapic/templates/testing/constraints-3.14.txt.j2 | 2 +- .../integration/goldens/asset/testing/constraints-3.13.txt | 2 +- .../integration/goldens/asset/testing/constraints-3.14.txt | 2 +- .../goldens/credentials/testing/constraints-3.13.txt | 2 +- .../goldens/credentials/testing/constraints-3.14.txt | 2 +- .../integration/goldens/eventarc/testing/constraints-3.13.txt | 2 +- .../integration/goldens/eventarc/testing/constraints-3.14.txt | 2 +- .../integration/goldens/logging/testing/constraints-3.13.txt | 2 +- .../integration/goldens/logging/testing/constraints-3.14.txt | 2 +- .../goldens/logging_internal/testing/constraints-3.13.txt | 2 +- .../goldens/logging_internal/testing/constraints-3.14.txt | 2 +- .../integration/goldens/redis/testing/constraints-3.13.txt | 2 +- .../integration/goldens/redis/testing/constraints-3.14.txt | 2 +- .../goldens/redis_selective/testing/constraints-3.13.txt | 2 +- .../goldens/redis_selective/testing/constraints-3.14.txt | 2 +- .../goldens/storagebatchoperations/testing/constraints-3.13.txt | 2 +- .../goldens/storagebatchoperations/testing/constraints-3.14.txt | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/packages/gapic-generator/gapic/templates/testing/constraints-3.13.txt.j2 b/packages/gapic-generator/gapic/templates/testing/constraints-3.13.txt.j2 index c2e7b8a9934c..a2e0a3f4cb1e 100644 --- a/packages/gapic-generator/gapic/templates/testing/constraints-3.13.txt.j2 +++ b/packages/gapic-generator/gapic/templates/testing/constraints-3.13.txt.j2 @@ -10,7 +10,7 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 {% for package_tuple, package_info in pypi_packages.items() %} {# Quick check to make sure `package_info.package_name` is not the package being generated so we don't circularly include this package in its own constraints file. #} {% if api.naming.warehouse_package_name != package_info.package_name %} diff --git a/packages/gapic-generator/gapic/templates/testing/constraints-3.14.txt.j2 b/packages/gapic-generator/gapic/templates/testing/constraints-3.14.txt.j2 index c2e7b8a9934c..a2e0a3f4cb1e 100644 --- a/packages/gapic-generator/gapic/templates/testing/constraints-3.14.txt.j2 +++ b/packages/gapic-generator/gapic/templates/testing/constraints-3.14.txt.j2 @@ -10,7 +10,7 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 {% for package_tuple, package_info in pypi_packages.items() %} {# Quick check to make sure `package_info.package_name` is not the package being generated so we don't circularly include this package in its own constraints file. #} {% if api.naming.warehouse_package_name != package_info.package_name %} diff --git a/packages/gapic-generator/tests/integration/goldens/asset/testing/constraints-3.13.txt b/packages/gapic-generator/tests/integration/goldens/asset/testing/constraints-3.13.txt index c3db09a0c746..f63842dab6f9 100755 --- a/packages/gapic-generator/tests/integration/goldens/asset/testing/constraints-3.13.txt +++ b/packages/gapic-generator/tests/integration/goldens/asset/testing/constraints-3.13.txt @@ -9,7 +9,7 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-cloud-access-context-manager>=0 google-cloud-os-config>=1 grpc-google-iam-v1>=0 diff --git a/packages/gapic-generator/tests/integration/goldens/asset/testing/constraints-3.14.txt b/packages/gapic-generator/tests/integration/goldens/asset/testing/constraints-3.14.txt index c3db09a0c746..f63842dab6f9 100755 --- a/packages/gapic-generator/tests/integration/goldens/asset/testing/constraints-3.14.txt +++ b/packages/gapic-generator/tests/integration/goldens/asset/testing/constraints-3.14.txt @@ -9,7 +9,7 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-cloud-access-context-manager>=0 google-cloud-os-config>=1 grpc-google-iam-v1>=0 diff --git a/packages/gapic-generator/tests/integration/goldens/credentials/testing/constraints-3.13.txt b/packages/gapic-generator/tests/integration/goldens/credentials/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100755 --- a/packages/gapic-generator/tests/integration/goldens/credentials/testing/constraints-3.13.txt +++ b/packages/gapic-generator/tests/integration/goldens/credentials/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/gapic-generator/tests/integration/goldens/credentials/testing/constraints-3.14.txt b/packages/gapic-generator/tests/integration/goldens/credentials/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100755 --- a/packages/gapic-generator/tests/integration/goldens/credentials/testing/constraints-3.14.txt +++ b/packages/gapic-generator/tests/integration/goldens/credentials/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/gapic-generator/tests/integration/goldens/eventarc/testing/constraints-3.13.txt b/packages/gapic-generator/tests/integration/goldens/eventarc/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100755 --- a/packages/gapic-generator/tests/integration/goldens/eventarc/testing/constraints-3.13.txt +++ b/packages/gapic-generator/tests/integration/goldens/eventarc/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/gapic-generator/tests/integration/goldens/eventarc/testing/constraints-3.14.txt b/packages/gapic-generator/tests/integration/goldens/eventarc/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100755 --- a/packages/gapic-generator/tests/integration/goldens/eventarc/testing/constraints-3.14.txt +++ b/packages/gapic-generator/tests/integration/goldens/eventarc/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/gapic-generator/tests/integration/goldens/logging/testing/constraints-3.13.txt b/packages/gapic-generator/tests/integration/goldens/logging/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100755 --- a/packages/gapic-generator/tests/integration/goldens/logging/testing/constraints-3.13.txt +++ b/packages/gapic-generator/tests/integration/goldens/logging/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/gapic-generator/tests/integration/goldens/logging/testing/constraints-3.14.txt b/packages/gapic-generator/tests/integration/goldens/logging/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100755 --- a/packages/gapic-generator/tests/integration/goldens/logging/testing/constraints-3.14.txt +++ b/packages/gapic-generator/tests/integration/goldens/logging/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/gapic-generator/tests/integration/goldens/logging_internal/testing/constraints-3.13.txt b/packages/gapic-generator/tests/integration/goldens/logging_internal/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100755 --- a/packages/gapic-generator/tests/integration/goldens/logging_internal/testing/constraints-3.13.txt +++ b/packages/gapic-generator/tests/integration/goldens/logging_internal/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/gapic-generator/tests/integration/goldens/logging_internal/testing/constraints-3.14.txt b/packages/gapic-generator/tests/integration/goldens/logging_internal/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100755 --- a/packages/gapic-generator/tests/integration/goldens/logging_internal/testing/constraints-3.14.txt +++ b/packages/gapic-generator/tests/integration/goldens/logging_internal/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/gapic-generator/tests/integration/goldens/redis/testing/constraints-3.13.txt b/packages/gapic-generator/tests/integration/goldens/redis/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100755 --- a/packages/gapic-generator/tests/integration/goldens/redis/testing/constraints-3.13.txt +++ b/packages/gapic-generator/tests/integration/goldens/redis/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/gapic-generator/tests/integration/goldens/redis/testing/constraints-3.14.txt b/packages/gapic-generator/tests/integration/goldens/redis/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100755 --- a/packages/gapic-generator/tests/integration/goldens/redis/testing/constraints-3.14.txt +++ b/packages/gapic-generator/tests/integration/goldens/redis/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/gapic-generator/tests/integration/goldens/redis_selective/testing/constraints-3.13.txt b/packages/gapic-generator/tests/integration/goldens/redis_selective/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100755 --- a/packages/gapic-generator/tests/integration/goldens/redis_selective/testing/constraints-3.13.txt +++ b/packages/gapic-generator/tests/integration/goldens/redis_selective/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/gapic-generator/tests/integration/goldens/redis_selective/testing/constraints-3.14.txt b/packages/gapic-generator/tests/integration/goldens/redis_selective/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100755 --- a/packages/gapic-generator/tests/integration/goldens/redis_selective/testing/constraints-3.14.txt +++ b/packages/gapic-generator/tests/integration/goldens/redis_selective/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/testing/constraints-3.13.txt b/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100755 --- a/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/testing/constraints-3.13.txt +++ b/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/testing/constraints-3.14.txt b/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100755 --- a/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/testing/constraints-3.14.txt +++ b/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 From 66422636633e980324877f2ff3805a284001ad38 Mon Sep 17 00:00:00 2001 From: Anthonios Partheniou Date: Tue, 2 Jun 2026 16:07:34 -0400 Subject: [PATCH 009/174] fix: require protobuf 6.33.5 to address CVE-2026-0994 (#17349) Require Protobuf 6.33.5 to address [CVE-2026-0994](https://github.com/advisories/GHSA-7gcm-g887-7qv7). As per https://protobuf.dev/support/version-support/#python and https://protobuf.dev/support/version-support/#duration, Protobuf 5.x is no longer supported. The changes to bump Protobuf in the bazel WORKSPACE file will be done in a [separate PR](https://github.com/googleapis/google-cloud-python/pull/17254). The minimum versions of `google-api-core` and `proto-plus` and others also need to be versions that support Protobuf 6 https://github.com/googleapis/python-api-core/releases/tag/v2.24.2 https://github.com/googleapis/proto-plus-python/releases/tag/v1.26.1 Also see the client library versions which allow Protobuf 6.x in PR https://github.com/googleapis/google-cloud-python/pull/13644 (https://github.com/googleapis/google-cloud-python/blob/release-please--branches--main--release-notes/release-notes.md) Towards b/420641246 --- .../gapic/ads-templates/setup.py.j2 | 6 +++--- .../%name_%version/%sub/__init__.py.j2 | 8 ++++---- .../gapic/templates/_pypi_packages.j2 | 16 ++++++++-------- .../gapic-generator/gapic/templates/setup.py.j2 | 8 +++----- .../testing/constraints-3.10-async-rest.txt.j2 | 6 +++--- .../templates/testing/constraints-3.10.txt.j2 | 6 +++--- packages/gapic-generator/requirements.in | 2 +- packages/gapic-generator/setup.py | 10 +++++----- .../asset/google/cloud/asset_v1/__init__.py | 8 ++++---- .../tests/integration/goldens/asset/setup.py | 13 ++++++------- .../goldens/asset/testing/constraints-3.10.txt | 12 ++++++------ .../google/iam/credentials_v1/__init__.py | 8 ++++---- .../integration/goldens/credentials/setup.py | 7 +++---- .../credentials/testing/constraints-3.10.txt | 6 +++--- .../google/cloud/eventarc_v1/__init__.py | 8 ++++---- .../tests/integration/goldens/eventarc/setup.py | 9 ++++----- .../eventarc/testing/constraints-3.10.txt | 8 ++++---- .../logging/google/cloud/logging_v2/__init__.py | 8 ++++---- .../tests/integration/goldens/logging/setup.py | 7 +++---- .../goldens/logging/testing/constraints-3.10.txt | 6 +++--- .../google/cloud/logging_v2/__init__.py | 8 ++++---- .../goldens/logging_internal/setup.py | 7 +++---- .../testing/constraints-3.10.txt | 6 +++--- .../redis/google/cloud/redis_v1/__init__.py | 8 ++++---- .../tests/integration/goldens/redis/setup.py | 8 +++----- .../testing/constraints-3.10-async-rest.txt | 6 +++--- .../goldens/redis/testing/constraints-3.10.txt | 6 +++--- .../google/cloud/redis_v1/__init__.py | 8 ++++---- .../integration/goldens/redis_selective/setup.py | 8 +++----- .../testing/constraints-3.10-async-rest.txt | 6 +++--- .../redis_selective/testing/constraints-3.10.txt | 6 +++--- .../cloud/storagebatchoperations_v1/__init__.py | 8 ++++---- .../goldens/storagebatchoperations/setup.py | 7 +++---- .../testing/constraints-3.10.txt | 6 +++--- 34 files changed, 124 insertions(+), 136 deletions(-) diff --git a/packages/gapic-generator/gapic/ads-templates/setup.py.j2 b/packages/gapic-generator/gapic/ads-templates/setup.py.j2 index 1684c2de1a61..da9c3b995396 100644 --- a/packages/gapic-generator/gapic/ads-templates/setup.py.j2 +++ b/packages/gapic-generator/gapic/ads-templates/setup.py.j2 @@ -29,12 +29,12 @@ else: release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.10.0, < 3.0.0", + "google-api-core[grpc] >= 2.24.2, < 3.0.0", "google-auth >= 2.14.1, <3.0.0", "googleapis-common-protos >= 1.53.0", "grpcio >= 1.10.0", - "proto-plus >= 1.22.3, <2.0.0", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", {% if api.requires_package(('google', 'iam', 'v1')) %} "grpc-google-iam-v1", {% endif %} diff --git a/packages/gapic-generator/gapic/templates/%namespace/%name_%version/%sub/__init__.py.j2 b/packages/gapic-generator/gapic/templates/%namespace/%name_%version/%sub/__init__.py.j2 index c1e5c715cf71..497592654d20 100644 --- a/packages/gapic-generator/gapic/templates/%namespace/%name_%version/%sub/__init__.py.j2 +++ b/packages/gapic-generator/gapic/templates/%namespace/%name_%version/%sub/__init__.py.j2 @@ -69,7 +69,7 @@ else: # pragma: NO COVER def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -98,9 +98,9 @@ else: # pragma: NO COVER return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn(f"Package {_package_label} depends on " + diff --git a/packages/gapic-generator/gapic/templates/_pypi_packages.j2 b/packages/gapic-generator/gapic/templates/_pypi_packages.j2 index 1495e827fc49..db839ef607db 100644 --- a/packages/gapic-generator/gapic/templates/_pypi_packages.j2 +++ b/packages/gapic-generator/gapic/templates/_pypi_packages.j2 @@ -7,14 +7,14 @@ allowed version. --> {% set pypi_packages = { ("google", "apps", "card", "v1"): {"package_name": "google-apps-card", "lower_bound": "0.3.0", "upper_bound": "1.0.0"}, - ("google", "apps", "script", "type"): {"package_name": "google-apps-script-type", "lower_bound": "0.2.0", "upper_bound": "1.0.0"}, - ("google", "geo", "type"): {"package_name": "google-geo-type", "lower_bound": "0.1.0", "upper_bound": "1.0.0"}, - ("google", "identity", "accesscontextmanager", "v1"): {"package_name": "google-cloud-access-context-manager", "lower_bound": "0.2.0", "upper_bound": "1.0.0"}, - ("google", "cloud", "documentai", "v1"): {"package_name": "google-cloud-documentai", "lower_bound": "2.4.1", "upper_bound": "4.0.0"}, - ("google", "cloud", "kms", "v1"): {"package_name": "google-cloud-kms", "lower_bound": "2.13.0", "upper_bound": "4.0.0"}, - ("google", "cloud", "osconfig", "v1"): {"package_name": "google-cloud-os-config", "lower_bound": "1.13.0", "upper_bound": "2.0.0"}, - ("google", "iam", "v1"): {"package_name": "grpc-google-iam-v1", "lower_bound": "0.14.0", "upper_bound": "1.0.0"}, - ("google", "iam", "v2"): {"package_name": "google-cloud-iam", "lower_bound": "2.12.2", "upper_bound": "3.0.0"}, + ("google", "apps", "script", "type"): {"package_name": "google-apps-script-type", "lower_bound": "0.3.14", "upper_bound": "1.0.0"}, + ("google", "geo", "type"): {"package_name": "google-geo-type", "lower_bound": "0.3.12", "upper_bound": "1.0.0"}, + ("google", "identity", "accesscontextmanager", "v1"): {"package_name": "google-cloud-access-context-manager", "lower_bound": "0.2.2", "upper_bound": "1.0.0"}, + ("google", "cloud", "documentai", "v1"): {"package_name": "google-cloud-documentai", "lower_bound": "3.2.1", "upper_bound": "4.0.0"}, + ("google", "cloud", "kms", "v1"): {"package_name": "google-cloud-kms", "lower_bound": "3.4.1", "upper_bound": "4.0.0"}, + ("google", "cloud", "osconfig", "v1"): {"package_name": "google-cloud-os-config", "lower_bound": "1.20.1", "upper_bound": "2.0.0"}, + ("google", "iam", "v1"): {"package_name": "grpc-google-iam-v1", "lower_bound": "0.14.2", "upper_bound": "1.0.0"}, + ("google", "iam", "v2"): {"package_name": "google-cloud-iam", "lower_bound": "2.18.2", "upper_bound": "3.0.0"}, ("google", "shopping", "type"): {"package_name": "google-shopping-type", "lower_bound": "1.0.0", "upper_bound": "2.0.0"} } %} diff --git a/packages/gapic-generator/gapic/templates/setup.py.j2 b/packages/gapic-generator/gapic/templates/setup.py.j2 index e1927bc48fe0..9834a2884c95 100644 --- a/packages/gapic-generator/gapic/templates/setup.py.j2 +++ b/packages/gapic-generator/gapic/templates/setup.py.j2 @@ -33,16 +33,15 @@ else: release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", + "proto-plus >= 1.26.1, <2.0.0", {# Explicitly exclude protobuf versions mentioned in https://cloud.google.com/support/bulletins#GCP-2022-019 #} - "protobuf >= 4.25.8, < 8.0.0", + "protobuf >= 6.33.5, < 8.0.0", {% for package_tuple, package_info in pypi_packages.items() %} {# Quick check to make sure `package_info.package_name` is not the package being generated so we don't circularly include this package in its own constraints file. #} {% if api.naming.warehouse_package_name != package_info.package_name %} @@ -55,7 +54,6 @@ dependencies = [ extras = { {% if rest_async_io_enabled %} "async_rest": [ - "google-api-core[grpc] >= 2.21.0, < 3.0.0", "google-auth[aiohttp] >= 2.35.0, <3.0.0" ], {% endif %} diff --git a/packages/gapic-generator/gapic/templates/testing/constraints-3.10-async-rest.txt.j2 b/packages/gapic-generator/gapic/templates/testing/constraints-3.10-async-rest.txt.j2 index 9f0051916ec0..a8c43d63aa40 100644 --- a/packages/gapic-generator/gapic/templates/testing/constraints-3.10-async-rest.txt.j2 +++ b/packages/gapic-generator/gapic/templates/testing/constraints-3.10-async-rest.txt.j2 @@ -8,11 +8,11 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.21.0 +google-api-core==2.24.2 google-auth==2.35.0 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 {% for package_tuple, package_info in pypi_packages.items() %} {# Quick check to make sure `package_info.package_name` is not the package being generated so we don't circularly include this package in its own constraints file. #} {% if api.naming.warehouse_package_name != package_info.package_name %} diff --git a/packages/gapic-generator/gapic/templates/testing/constraints-3.10.txt.j2 b/packages/gapic-generator/gapic/templates/testing/constraints-3.10.txt.j2 index 63ad4c20f28b..4d6f7eea3308 100644 --- a/packages/gapic-generator/gapic/templates/testing/constraints-3.10.txt.j2 +++ b/packages/gapic-generator/gapic/templates/testing/constraints-3.10.txt.j2 @@ -5,11 +5,11 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 {% for package_tuple, package_info in pypi_packages.items() %} {# Quick check to make sure `package_info.package_name` is not the package being generated so we don't circularly include this package in its own constraints file. #} {% if api.naming.warehouse_package_name != package_info.package_name %} diff --git a/packages/gapic-generator/requirements.in b/packages/gapic-generator/requirements.in index 2a9d7bb2cdb7..2776bb919bb8 100644 --- a/packages/gapic-generator/requirements.in +++ b/packages/gapic-generator/requirements.in @@ -3,7 +3,7 @@ google-api-core googleapis-common-protos jinja2 MarkupSafe -protobuf>=4.25.8 +protobuf>=6.33.5 # for CVE-2026-0994. See https://github.com/advisories/GHSA-7gcm-g887-7qv7 and https://protobuf.dev/support/version-support/#python pypandoc PyYAML grpc-google-iam-v1 diff --git a/packages/gapic-generator/setup.py b/packages/gapic-generator/setup.py index 8ac2ba041d97..a1646a992684 100644 --- a/packages/gapic-generator/setup.py +++ b/packages/gapic-generator/setup.py @@ -28,17 +28,17 @@ # Ensure that the lower bounds of these dependencies match what we have in the # templated setup.py.j2: https://github.com/googleapis/gapic-generator-python/blob/main/gapic/templates/setup.py.j2 "click >= 6.7", - "google-api-core[grpc] >= 1.34.1, <3.0.0,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*", - "googleapis-common-protos >= 1.55.0", - "grpcio >= 1.24.3", + "google-api-core[grpc] >= 2.24.2, < 3.0.0", + "googleapis-common-protos >= 1.55.0, < 2.0.0", + "grpcio >= 1.24.3, < 2.0.0", # 2.11.0 is required which adds the `default` argument to `jinja-filters.map()` # https://jinja.palletsprojects.com/en/3.0.x/templates/#jinja-filters.map # https://jinja.palletsprojects.com/en/2.11.x/changelog/#version-2-11-0 "jinja2 >= 2.11", - "protobuf >= 4.25.8, < 8.0.0", + "protobuf >= 6.33.5, < 8.0.0", "pypandoc >= 1.4", "PyYAML >= 5.1.1", - "grpc-google-iam-v1 >= 0.14.0, < 1.0.0", + "grpc-google-iam-v1 >= 0.14.2, < 1.0.0", "libcst >= 0.4.9, < 2.0.0", "inflection >= 0.5.1, < 1.0.0", ] diff --git a/packages/gapic-generator/tests/integration/goldens/asset/google/cloud/asset_v1/__init__.py b/packages/gapic-generator/tests/integration/goldens/asset/google/cloud/asset_v1/__init__.py index 4140bfbde694..f272a61b7a4e 100755 --- a/packages/gapic-generator/tests/integration/goldens/asset/google/cloud/asset_v1/__init__.py +++ b/packages/gapic-generator/tests/integration/goldens/asset/google/cloud/asset_v1/__init__.py @@ -129,7 +129,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -158,9 +158,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn(f"Package {_package_label} depends on " + diff --git a/packages/gapic-generator/tests/integration/goldens/asset/setup.py b/packages/gapic-generator/tests/integration/goldens/asset/setup.py index 2a8d122f099c..197a610bff72 100755 --- a/packages/gapic-generator/tests/integration/goldens/asset/setup.py +++ b/packages/gapic-generator/tests/integration/goldens/asset/setup.py @@ -39,18 +39,17 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "google-cloud-access-context-manager >= 0.2.0, <1.0.0", - "google-cloud-os-config >= 1.13.0, <2.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "google-cloud-access-context-manager >= 0.2.2, <1.0.0", + "google-cloud-os-config >= 1.20.1, <2.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = { } diff --git a/packages/gapic-generator/tests/integration/goldens/asset/testing/constraints-3.10.txt b/packages/gapic-generator/tests/integration/goldens/asset/testing/constraints-3.10.txt index 554a13c22f32..ec7b713eaf6f 100755 --- a/packages/gapic-generator/tests/integration/goldens/asset/testing/constraints-3.10.txt +++ b/packages/gapic-generator/tests/integration/goldens/asset/testing/constraints-3.10.txt @@ -4,11 +4,11 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -google-cloud-access-context-manager==0.2.0 -google-cloud-os-config==1.13.0 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +google-cloud-access-context-manager==0.2.2 +google-cloud-os-config==1.20.1 +grpc-google-iam-v1==0.14.2 diff --git a/packages/gapic-generator/tests/integration/goldens/credentials/google/iam/credentials_v1/__init__.py b/packages/gapic-generator/tests/integration/goldens/credentials/google/iam/credentials_v1/__init__.py index b8f62a77a42b..943687313e36 100755 --- a/packages/gapic-generator/tests/integration/goldens/credentials/google/iam/credentials_v1/__init__.py +++ b/packages/gapic-generator/tests/integration/goldens/credentials/google/iam/credentials_v1/__init__.py @@ -56,7 +56,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -85,9 +85,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn(f"Package {_package_label} depends on " + diff --git a/packages/gapic-generator/tests/integration/goldens/credentials/setup.py b/packages/gapic-generator/tests/integration/goldens/credentials/setup.py index cb2edb25790b..4d4533c20e18 100755 --- a/packages/gapic-generator/tests/integration/goldens/credentials/setup.py +++ b/packages/gapic-generator/tests/integration/goldens/credentials/setup.py @@ -39,15 +39,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = { } diff --git a/packages/gapic-generator/tests/integration/goldens/credentials/testing/constraints-3.10.txt b/packages/gapic-generator/tests/integration/goldens/credentials/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100755 --- a/packages/gapic-generator/tests/integration/goldens/credentials/testing/constraints-3.10.txt +++ b/packages/gapic-generator/tests/integration/goldens/credentials/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/gapic-generator/tests/integration/goldens/eventarc/google/cloud/eventarc_v1/__init__.py b/packages/gapic-generator/tests/integration/goldens/eventarc/google/cloud/eventarc_v1/__init__.py index 9885f1e7b375..c2c65d30a333 100755 --- a/packages/gapic-generator/tests/integration/goldens/eventarc/google/cloud/eventarc_v1/__init__.py +++ b/packages/gapic-generator/tests/integration/goldens/eventarc/google/cloud/eventarc_v1/__init__.py @@ -118,7 +118,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -147,9 +147,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn(f"Package {_package_label} depends on " + diff --git a/packages/gapic-generator/tests/integration/goldens/eventarc/setup.py b/packages/gapic-generator/tests/integration/goldens/eventarc/setup.py index 58e6940bcf39..0a0aae863942 100755 --- a/packages/gapic-generator/tests/integration/goldens/eventarc/setup.py +++ b/packages/gapic-generator/tests/integration/goldens/eventarc/setup.py @@ -39,16 +39,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = { } diff --git a/packages/gapic-generator/tests/integration/goldens/eventarc/testing/constraints-3.10.txt b/packages/gapic-generator/tests/integration/goldens/eventarc/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100755 --- a/packages/gapic-generator/tests/integration/goldens/eventarc/testing/constraints-3.10.txt +++ b/packages/gapic-generator/tests/integration/goldens/eventarc/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/gapic-generator/tests/integration/goldens/logging/google/cloud/logging_v2/__init__.py b/packages/gapic-generator/tests/integration/goldens/logging/google/cloud/logging_v2/__init__.py index 52cae052fcfa..8b559fb0b227 100755 --- a/packages/gapic-generator/tests/integration/goldens/logging/google/cloud/logging_v2/__init__.py +++ b/packages/gapic-generator/tests/integration/goldens/logging/google/cloud/logging_v2/__init__.py @@ -128,7 +128,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -157,9 +157,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn(f"Package {_package_label} depends on " + diff --git a/packages/gapic-generator/tests/integration/goldens/logging/setup.py b/packages/gapic-generator/tests/integration/goldens/logging/setup.py index 0b9176488ae6..38c15878df5e 100755 --- a/packages/gapic-generator/tests/integration/goldens/logging/setup.py +++ b/packages/gapic-generator/tests/integration/goldens/logging/setup.py @@ -39,15 +39,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = { } diff --git a/packages/gapic-generator/tests/integration/goldens/logging/testing/constraints-3.10.txt b/packages/gapic-generator/tests/integration/goldens/logging/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100755 --- a/packages/gapic-generator/tests/integration/goldens/logging/testing/constraints-3.10.txt +++ b/packages/gapic-generator/tests/integration/goldens/logging/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/gapic-generator/tests/integration/goldens/logging_internal/google/cloud/logging_v2/__init__.py b/packages/gapic-generator/tests/integration/goldens/logging_internal/google/cloud/logging_v2/__init__.py index 33ba01d9940d..0469de869617 100755 --- a/packages/gapic-generator/tests/integration/goldens/logging_internal/google/cloud/logging_v2/__init__.py +++ b/packages/gapic-generator/tests/integration/goldens/logging_internal/google/cloud/logging_v2/__init__.py @@ -128,7 +128,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -157,9 +157,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn(f"Package {_package_label} depends on " + diff --git a/packages/gapic-generator/tests/integration/goldens/logging_internal/setup.py b/packages/gapic-generator/tests/integration/goldens/logging_internal/setup.py index 0b9176488ae6..38c15878df5e 100755 --- a/packages/gapic-generator/tests/integration/goldens/logging_internal/setup.py +++ b/packages/gapic-generator/tests/integration/goldens/logging_internal/setup.py @@ -39,15 +39,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = { } diff --git a/packages/gapic-generator/tests/integration/goldens/logging_internal/testing/constraints-3.10.txt b/packages/gapic-generator/tests/integration/goldens/logging_internal/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100755 --- a/packages/gapic-generator/tests/integration/goldens/logging_internal/testing/constraints-3.10.txt +++ b/packages/gapic-generator/tests/integration/goldens/logging_internal/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/gapic-generator/tests/integration/goldens/redis/google/cloud/redis_v1/__init__.py b/packages/gapic-generator/tests/integration/goldens/redis/google/cloud/redis_v1/__init__.py index 0cd59a0dc55f..c2897c61e9d7 100755 --- a/packages/gapic-generator/tests/integration/goldens/redis/google/cloud/redis_v1/__init__.py +++ b/packages/gapic-generator/tests/integration/goldens/redis/google/cloud/redis_v1/__init__.py @@ -75,7 +75,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -104,9 +104,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn(f"Package {_package_label} depends on " + diff --git a/packages/gapic-generator/tests/integration/goldens/redis/setup.py b/packages/gapic-generator/tests/integration/goldens/redis/setup.py index 358f0f73ee87..18e5226c7306 100755 --- a/packages/gapic-generator/tests/integration/goldens/redis/setup.py +++ b/packages/gapic-generator/tests/integration/goldens/redis/setup.py @@ -39,19 +39,17 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = { "async_rest": [ - "google-api-core[grpc] >= 2.21.0, < 3.0.0", "google-auth[aiohttp] >= 2.35.0, <3.0.0" ], } diff --git a/packages/gapic-generator/tests/integration/goldens/redis/testing/constraints-3.10-async-rest.txt b/packages/gapic-generator/tests/integration/goldens/redis/testing/constraints-3.10-async-rest.txt index 4148e63e7dd1..2e5186f9ec6e 100755 --- a/packages/gapic-generator/tests/integration/goldens/redis/testing/constraints-3.10-async-rest.txt +++ b/packages/gapic-generator/tests/integration/goldens/redis/testing/constraints-3.10-async-rest.txt @@ -5,8 +5,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.21.0 +google-api-core==2.24.2 google-auth==2.35.0 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/gapic-generator/tests/integration/goldens/redis/testing/constraints-3.10.txt b/packages/gapic-generator/tests/integration/goldens/redis/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100755 --- a/packages/gapic-generator/tests/integration/goldens/redis/testing/constraints-3.10.txt +++ b/packages/gapic-generator/tests/integration/goldens/redis/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/gapic-generator/tests/integration/goldens/redis_selective/google/cloud/redis_v1/__init__.py b/packages/gapic-generator/tests/integration/goldens/redis_selective/google/cloud/redis_v1/__init__.py index f9ca3ee685f8..043562140c7d 100755 --- a/packages/gapic-generator/tests/integration/goldens/redis_selective/google/cloud/redis_v1/__init__.py +++ b/packages/gapic-generator/tests/integration/goldens/redis_selective/google/cloud/redis_v1/__init__.py @@ -68,7 +68,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -97,9 +97,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn(f"Package {_package_label} depends on " + diff --git a/packages/gapic-generator/tests/integration/goldens/redis_selective/setup.py b/packages/gapic-generator/tests/integration/goldens/redis_selective/setup.py index 358f0f73ee87..18e5226c7306 100755 --- a/packages/gapic-generator/tests/integration/goldens/redis_selective/setup.py +++ b/packages/gapic-generator/tests/integration/goldens/redis_selective/setup.py @@ -39,19 +39,17 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = { "async_rest": [ - "google-api-core[grpc] >= 2.21.0, < 3.0.0", "google-auth[aiohttp] >= 2.35.0, <3.0.0" ], } diff --git a/packages/gapic-generator/tests/integration/goldens/redis_selective/testing/constraints-3.10-async-rest.txt b/packages/gapic-generator/tests/integration/goldens/redis_selective/testing/constraints-3.10-async-rest.txt index 4148e63e7dd1..2e5186f9ec6e 100755 --- a/packages/gapic-generator/tests/integration/goldens/redis_selective/testing/constraints-3.10-async-rest.txt +++ b/packages/gapic-generator/tests/integration/goldens/redis_selective/testing/constraints-3.10-async-rest.txt @@ -5,8 +5,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.21.0 +google-api-core==2.24.2 google-auth==2.35.0 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/gapic-generator/tests/integration/goldens/redis_selective/testing/constraints-3.10.txt b/packages/gapic-generator/tests/integration/goldens/redis_selective/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100755 --- a/packages/gapic-generator/tests/integration/goldens/redis_selective/testing/constraints-3.10.txt +++ b/packages/gapic-generator/tests/integration/goldens/redis_selective/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/google/cloud/storagebatchoperations_v1/__init__.py b/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/google/cloud/storagebatchoperations_v1/__init__.py index 6e2831b029b7..c1ad7c247ae0 100755 --- a/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/google/cloud/storagebatchoperations_v1/__init__.py +++ b/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/google/cloud/storagebatchoperations_v1/__init__.py @@ -76,7 +76,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -105,9 +105,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn(f"Package {_package_label} depends on " + diff --git a/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/setup.py b/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/setup.py index 34dbb3ed7860..56c8e3127f42 100755 --- a/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/setup.py +++ b/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/setup.py @@ -39,15 +39,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = { } diff --git a/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/testing/constraints-3.10.txt b/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100755 --- a/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/testing/constraints-3.10.txt +++ b/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 From f7089cc5b9457e1920c6478e4d7ad0cc403dfef3 Mon Sep 17 00:00:00 2001 From: TrevorBergeron Date: Tue, 2 Jun 2026 14:10:12 -0700 Subject: [PATCH 010/174] test(bigframes): Disable ibis fallback for system tests (#17333) --- .../bigframes/core/compile/sqlglot/expressions/ai_ops.py | 3 ++- packages/bigframes/tests/system/conftest.py | 8 ++++++++ .../snapshots/test_ai_ops/test_ai_classify/None/out.sql | 2 +- .../bigframes-dev.us.bigframes-default-connection/out.sql | 2 +- .../test_ai_classify_multi_with_list_examples/out.sql | 2 +- .../test_ai_ops/test_ai_classify_with_output_mode/out.sql | 2 +- .../test_ai_ops/test_ai_classify_with_params/out.sql | 2 +- .../snapshots/test_ai_ops/test_ai_generate/out.sql | 2 +- .../snapshots/test_ai_ops/test_ai_generate_bool/out.sql | 2 +- .../test_ai_generate_bool_with_connection_id/out.sql | 2 +- .../test_ai_generate_bool_with_model_param/out.sql | 2 +- .../snapshots/test_ai_ops/test_ai_generate_double/out.sql | 2 +- .../test_ai_generate_double_with_connection_id/out.sql | 2 +- .../test_ai_generate_double_with_model_param/out.sql | 2 +- .../snapshots/test_ai_ops/test_ai_generate_int/out.sql | 2 +- .../test_ai_generate_int_with_connection_id/out.sql | 2 +- .../test_ai_generate_int_with_model_param/out.sql | 2 +- .../test_ai_generate_with_connection_id/out.sql | 2 +- .../test_ai_ops/test_ai_generate_with_model_param/out.sql | 2 +- .../test_ai_generate_with_output_schema/out.sql | 2 +- .../snapshots/test_ai_ops/test_ai_if/None/out.sql | 2 +- .../bigframes-dev.us.bigframes-default-connection/out.sql | 2 +- .../test_ai_ops/test_ai_if_with_endpoint/out.sql | 2 +- .../snapshots/test_ai_ops/test_ai_score/None/out.sql | 2 +- .../bigframes-dev.us.bigframes-default-connection/out.sql | 2 +- .../out.sql | 2 +- 26 files changed, 34 insertions(+), 25 deletions(-) diff --git a/packages/bigframes/bigframes/core/compile/sqlglot/expressions/ai_ops.py b/packages/bigframes/bigframes/core/compile/sqlglot/expressions/ai_ops.py index 12a6b9859a2a..d092f662f0f8 100644 --- a/packages/bigframes/bigframes/core/compile/sqlglot/expressions/ai_ops.py +++ b/packages/bigframes/bigframes/core/compile/sqlglot/expressions/ai_ops.py @@ -111,7 +111,8 @@ def _construct_prompt( else: prompt.append(sge.Literal.string(elem)) - return sge.Kwarg(this=param_name, expression=sge.Tuple(expressions=prompt)) + # Need Struct rather than tuple syntax, as tuple syntax is ambiguous for single arg + return sge.Kwarg(this=param_name, expression=sge.Struct(expressions=prompt)) def _construct_named_args(op: ops.ScalarOp) -> list[sge.Kwarg]: diff --git a/packages/bigframes/tests/system/conftest.py b/packages/bigframes/tests/system/conftest.py index 1adcb051c470..f6fbdd0c510d 100644 --- a/packages/bigframes/tests/system/conftest.py +++ b/packages/bigframes/tests/system/conftest.py @@ -1325,6 +1325,14 @@ def usa_names_grouped_table( return session.bqclient.get_table(table_id) +@pytest.fixture(scope="session", autouse=True) +def use_sqlglot_compiler(): + original_setting = bigframes.options.experiments.sql_compiler + bigframes.options.experiments.sql_compiler = "experimental" + yield + bigframes.options.experiments.sql_compiler = original_setting + + @pytest.fixture() def restore_sampling_settings(): enable_downsampling = bigframes.options.sampling.enable_downsampling diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_classify/None/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_classify/None/out.sql index 6771527318fa..fc29d96cc1aa 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_classify/None/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_classify/None/out.sql @@ -1,3 +1,3 @@ SELECT - AI.CLASSIFY(input => (`string_col`), categories => ['greeting', 'rejection']) AS `result` + AI.CLASSIFY(input => STRUCT(`string_col`), categories => ['greeting', 'rejection']) AS `result` FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` AS `bft_0` \ No newline at end of file diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_classify/bigframes-dev.us.bigframes-default-connection/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_classify/bigframes-dev.us.bigframes-default-connection/out.sql index 63c31d94566d..969b946725bc 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_classify/bigframes-dev.us.bigframes-default-connection/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_classify/bigframes-dev.us.bigframes-default-connection/out.sql @@ -1,6 +1,6 @@ SELECT AI.CLASSIFY( - input => (`string_col`), + input => STRUCT(`string_col`), categories => ['greeting', 'rejection'], connection_id => 'bigframes-dev.us.bigframes-default-connection' ) AS `result` diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_classify_multi_with_list_examples/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_classify_multi_with_list_examples/out.sql index a4a7f783da97..74078e986064 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_classify_multi_with_list_examples/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_classify_multi_with_list_examples/out.sql @@ -1,6 +1,6 @@ SELECT AI.CLASSIFY( - input => (`string_col`), + input => STRUCT(`string_col`), categories => ['greeting', 'rejection'], examples => [('hi', ['greeting', 'positive']), ('bye', ['rejection', 'negative'])], output_mode => 'multi' diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_classify_with_output_mode/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_classify_with_output_mode/out.sql index fb3c6af8b0b0..08d7476d77f4 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_classify_with_output_mode/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_classify_with_output_mode/out.sql @@ -1,6 +1,6 @@ SELECT AI.CLASSIFY( - input => (`string_col`), + input => STRUCT(`string_col`), categories => ['greeting', 'rejection'], output_mode => 'multi' ) AS `result` diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_classify_with_params/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_classify_with_params/out.sql index 982b747f8927..30542740a2dc 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_classify_with_params/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_classify_with_params/out.sql @@ -1,6 +1,6 @@ SELECT AI.CLASSIFY( - input => (`string_col`), + input => STRUCT(`string_col`), categories => ['greeting', 'rejection'], examples => [('hi', 'greeting'), ('bye', 'rejection')], endpoint => 'gemini-2.5-flash', diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate/out.sql index 9593347238f8..622782fa7d65 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate/out.sql @@ -1,6 +1,6 @@ SELECT AI.GENERATE( - prompt => (`string_col`, ' is the same as ', `string_col`), + prompt => STRUCT(`string_col`, ' is the same as ', `string_col`), endpoint => 'gemini-2.5-flash', request_type => 'SHARED' ) AS `result` diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_bool/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_bool/out.sql index aebccad12217..a71bce037a5d 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_bool/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_bool/out.sql @@ -1,6 +1,6 @@ SELECT AI.GENERATE_BOOL( - prompt => (`string_col`, ' is the same as ', `string_col`), + prompt => STRUCT(`string_col`, ' is the same as ', `string_col`), endpoint => 'gemini-2.5-flash' ) AS `result` FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` AS `bft_0` \ No newline at end of file diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_bool_with_connection_id/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_bool_with_connection_id/out.sql index 8f501a2cc292..db1ec378aaf9 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_bool_with_connection_id/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_bool_with_connection_id/out.sql @@ -1,6 +1,6 @@ SELECT AI.GENERATE_BOOL( - prompt => (`string_col`, ' is the same as ', `string_col`), + prompt => STRUCT(`string_col`, ' is the same as ', `string_col`), connection_id => 'bigframes-dev.us.bigframes-default-connection', endpoint => 'gemini-2.5-flash' ) AS `result` diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_bool_with_model_param/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_bool_with_model_param/out.sql index 985f5bb255d7..76af8833e639 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_bool_with_model_param/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_bool_with_model_param/out.sql @@ -1,6 +1,6 @@ SELECT AI.GENERATE_BOOL( - prompt => (`string_col`, ' is the same as ', `string_col`), + prompt => STRUCT(`string_col`, ' is the same as ', `string_col`), model_params => JSON '{}' ) AS `result` FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` AS `bft_0` \ No newline at end of file diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_double/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_double/out.sql index 3aed8986e179..1cef75687988 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_double/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_double/out.sql @@ -1,6 +1,6 @@ SELECT AI.GENERATE_DOUBLE( - prompt => (`string_col`, ' is the same as ', `string_col`), + prompt => STRUCT(`string_col`, ' is the same as ', `string_col`), endpoint => 'gemini-2.5-flash' ) AS `result` FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` AS `bft_0` \ No newline at end of file diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_double_with_connection_id/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_double_with_connection_id/out.sql index 19b8c18eec14..d0088721e386 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_double_with_connection_id/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_double_with_connection_id/out.sql @@ -1,6 +1,6 @@ SELECT AI.GENERATE_DOUBLE( - prompt => (`string_col`, ' is the same as ', `string_col`), + prompt => STRUCT(`string_col`, ' is the same as ', `string_col`), connection_id => 'bigframes-dev.us.bigframes-default-connection', endpoint => 'gemini-2.5-flash' ) AS `result` diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_double_with_model_param/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_double_with_model_param/out.sql index 854acc386739..2b50e05b7fe9 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_double_with_model_param/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_double_with_model_param/out.sql @@ -1,6 +1,6 @@ SELECT AI.GENERATE_DOUBLE( - prompt => (`string_col`, ' is the same as ', `string_col`), + prompt => STRUCT(`string_col`, ' is the same as ', `string_col`), model_params => JSON '{}' ) AS `result` FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` AS `bft_0` \ No newline at end of file diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_int/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_int/out.sql index 1ea5d0355cc9..9ef143c8b9e4 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_int/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_int/out.sql @@ -1,6 +1,6 @@ SELECT AI.GENERATE_INT( - prompt => (`string_col`, ' is the same as ', `string_col`), + prompt => STRUCT(`string_col`, ' is the same as ', `string_col`), endpoint => 'gemini-2.5-flash' ) AS `result` FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` AS `bft_0` \ No newline at end of file diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_int_with_connection_id/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_int_with_connection_id/out.sql index b99a8e9a207e..3fa3e8cc05e1 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_int_with_connection_id/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_int_with_connection_id/out.sql @@ -1,6 +1,6 @@ SELECT AI.GENERATE_INT( - prompt => (`string_col`, ' is the same as ', `string_col`), + prompt => STRUCT(`string_col`, ' is the same as ', `string_col`), connection_id => 'bigframes-dev.us.bigframes-default-connection', endpoint => 'gemini-2.5-flash' ) AS `result` diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_int_with_model_param/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_int_with_model_param/out.sql index fb3c9c001013..18adea8a0622 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_int_with_model_param/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_int_with_model_param/out.sql @@ -1,6 +1,6 @@ SELECT AI.GENERATE_INT( - prompt => (`string_col`, ' is the same as ', `string_col`), + prompt => STRUCT(`string_col`, ' is the same as ', `string_col`), model_params => JSON '{}' ) AS `result` FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` AS `bft_0` \ No newline at end of file diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_with_connection_id/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_with_connection_id/out.sql index b122d97b0617..14604cfc8dfd 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_with_connection_id/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_with_connection_id/out.sql @@ -1,6 +1,6 @@ SELECT AI.GENERATE( - prompt => (`string_col`, ' is the same as ', `string_col`), + prompt => STRUCT(`string_col`, ' is the same as ', `string_col`), connection_id => 'bigframes-dev.us.bigframes-default-connection', endpoint => 'gemini-2.5-flash' ) AS `result` diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_with_model_param/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_with_model_param/out.sql index 9d818b8c0cc9..090a42d889f5 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_with_model_param/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_with_model_param/out.sql @@ -1,6 +1,6 @@ SELECT AI.GENERATE( - prompt => (`string_col`, ' is the same as ', `string_col`), + prompt => STRUCT(`string_col`, ' is the same as ', `string_col`), model_params => JSON '{}' ) AS `result` FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` AS `bft_0` \ No newline at end of file diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_with_output_schema/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_with_output_schema/out.sql index 44abe7085c4e..31c179e7b01a 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_with_output_schema/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_generate_with_output_schema/out.sql @@ -1,6 +1,6 @@ SELECT AI.GENERATE( - prompt => (`string_col`, ' is the same as ', `string_col`), + prompt => STRUCT(`string_col`, ' is the same as ', `string_col`), endpoint => 'gemini-2.5-flash', output_schema => 'x INT64, y FLOAT64' ) AS `result` diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_if/None/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_if/None/out.sql index 7696a12c5893..59cf1c02a355 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_if/None/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_if/None/out.sql @@ -1,6 +1,6 @@ SELECT AI.IF( - prompt => (`string_col`, ' is the same as ', `string_col`), + prompt => STRUCT(`string_col`, ' is the same as ', `string_col`), optimization_mode => 'MINIMIZE_COST', max_error_ratio => 0.5 ) AS `result` diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_if/bigframes-dev.us.bigframes-default-connection/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_if/bigframes-dev.us.bigframes-default-connection/out.sql index dc8707487b54..0f26ab3c6ea6 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_if/bigframes-dev.us.bigframes-default-connection/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_if/bigframes-dev.us.bigframes-default-connection/out.sql @@ -1,6 +1,6 @@ SELECT AI.IF( - prompt => (`string_col`, ' is the same as ', `string_col`), + prompt => STRUCT(`string_col`, ' is the same as ', `string_col`), connection_id => 'bigframes-dev.us.bigframes-default-connection', optimization_mode => 'MINIMIZE_COST', max_error_ratio => 0.5 diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_if_with_endpoint/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_if_with_endpoint/out.sql index 5074584bd72d..4dd910528a41 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_if_with_endpoint/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_if_with_endpoint/out.sql @@ -1,6 +1,6 @@ SELECT AI.IF( - prompt => (`string_col`, ' is the same as ', `string_col`), + prompt => STRUCT(`string_col`, ' is the same as ', `string_col`), endpoint => 'gemini-2.5-flash' ) AS `result` FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` AS `bft_0` \ No newline at end of file diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_score/None/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_score/None/out.sql index 6a16276734ee..37590eec4f0f 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_score/None/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_score/None/out.sql @@ -1,3 +1,3 @@ SELECT - AI.SCORE(prompt => (`string_col`, ' is the same as ', `string_col`)) AS `result` + AI.SCORE(prompt => STRUCT(`string_col`, ' is the same as ', `string_col`)) AS `result` FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` AS `bft_0` \ No newline at end of file diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_score/bigframes-dev.us.bigframes-default-connection/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_score/bigframes-dev.us.bigframes-default-connection/out.sql index 92de7cdcdc65..696c7e9f3183 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_score/bigframes-dev.us.bigframes-default-connection/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_score/bigframes-dev.us.bigframes-default-connection/out.sql @@ -1,6 +1,6 @@ SELECT AI.SCORE( - prompt => (`string_col`, ' is the same as ', `string_col`), + prompt => STRUCT(`string_col`, ' is the same as ', `string_col`), connection_id => 'bigframes-dev.us.bigframes-default-connection' ) AS `result` FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` AS `bft_0` \ No newline at end of file diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_score_with_endpoint_and_max_error_ratio/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_score_with_endpoint_and_max_error_ratio/out.sql index d65590d0b66d..a802e5a396bf 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_score_with_endpoint_and_max_error_ratio/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_ai_ops/test_ai_score_with_endpoint_and_max_error_ratio/out.sql @@ -1,6 +1,6 @@ SELECT AI.SCORE( - prompt => (`string_col`, ' is the same as ', `string_col`), + prompt => STRUCT(`string_col`, ' is the same as ', `string_col`), endpoint => 'gemini-2.5-flash', max_error_ratio => 0.5 ) AS `result` From 0a3776e72102e23ab9129e7705ba5621d820d38f Mon Sep 17 00:00:00 2001 From: Daniel Sanche Date: Wed, 3 Jun 2026 02:14:54 -0700 Subject: [PATCH 011/174] chore(auth): re-enable auth releases (#17353) Revert https://github.com/googleapis/google-cloud-python/pull/17335 The system tests had been failing due to an expired credential, which has been manually rotated Fixes https://github.com/googleapis/google-cloud-python/issues/17334 --- .librarian/config.yaml | 3 --- librarian.yaml | 1 - .../system_tests/system_tests_sync/test_service_account.py | 2 +- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/.librarian/config.yaml b/.librarian/config.yaml index f8388dccd344..af751c2626d9 100644 --- a/.librarian/config.yaml +++ b/.librarian/config.yaml @@ -41,8 +41,5 @@ libraries: # TODO(https://github.com/googleapis/google-cloud-python/issues/17327) - id: "google-cloud-bigtable" release_blocked: true - # TODO(https://github.com/googleapis/google-cloud-python/issues/17334) - - id: "google-auth" - release_blocked: true diff --git a/librarian.yaml b/librarian.yaml index 2018678a980d..fb5d376113a1 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -221,7 +221,6 @@ libraries: default_version: v1alpha1 - name: google-auth version: 2.53.0 - skip_release: true python: library_type: AUTH - name: google-auth-httplib2 diff --git a/packages/google-auth/system_tests/system_tests_sync/test_service_account.py b/packages/google-auth/system_tests/system_tests_sync/test_service_account.py index 7fd38d9d7a94..5c859fbf6b0a 100644 --- a/packages/google-auth/system_tests/system_tests_sync/test_service_account.py +++ b/packages/google-auth/system_tests/system_tests_sync/test_service_account.py @@ -57,7 +57,7 @@ def test_iam_signer(http_request, credentials): credentials, credentials.service_account_email ) - + signed_blob = signer.sign("message") assert isinstance(signed_blob, bytes) From e1284887bee015573b43f410e0c5ca077686c5ec Mon Sep 17 00:00:00 2001 From: Daniel Sanche Date: Wed, 3 Jun 2026 02:15:15 -0700 Subject: [PATCH 012/174] chore(bigtable): resolve pytest-asyncio test failures (#17347) Adds an event loop fixture, to support latest version of pytest-asyncio --- .../tests/unit/conftest.py | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 packages/google-cloud-bigtable/tests/unit/conftest.py diff --git a/packages/google-cloud-bigtable/tests/unit/conftest.py b/packages/google-cloud-bigtable/tests/unit/conftest.py new file mode 100644 index 000000000000..59ff118aa71f --- /dev/null +++ b/packages/google-cloud-bigtable/tests/unit/conftest.py @@ -0,0 +1,37 @@ +# Copyright 2026 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 asyncio + +import pytest + + +@pytest.fixture(autouse=True) +def provide_loop_to_sync_grpc_tests(): + """ + GAPIC creates synchronous methods testing Asyncio transports. + If no global loop exists, `grpc.aio` engine crashes during initialization. + """ + try: + asyncio.get_running_loop() + except RuntimeError: + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + try: + yield + finally: + loop.close() + asyncio.set_event_loop(None) + else: + yield From 8b8ac0a3c8e495568d9d8f2a9849200204cddb2a Mon Sep 17 00:00:00 2001 From: Shuowei Li Date: Wed, 3 Jun 2026 14:40:00 +0000 Subject: [PATCH 013/174] test: use gemini-2.5-pro for ai accessor doctests (#17354) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #<519296335> 🦕 --- packages/bigframes/bigframes/operations/ai.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/bigframes/bigframes/operations/ai.py b/packages/bigframes/bigframes/operations/ai.py index c5cc08ae976f..c1c5164e9065 100644 --- a/packages/bigframes/bigframes/operations/ai.py +++ b/packages/bigframes/bigframes/operations/ai.py @@ -50,7 +50,7 @@ def filter( >>> bpd.options.compute.ai_ops_confirmation_threshold = 25 >>> import bigframes.ml.llm as llm - >>> model = llm.GeminiTextGenerator(model_name="gemini-2.0-flash-001") + >>> model = llm.GeminiTextGenerator(model_name="gemini-2.5-pro") >>> df = bpd.DataFrame({"country": ["USA", "Germany"], "city": ["Seattle", "Berlin"]}) >>> df.ai.filter("{city} is the capital of {country}", model) @@ -119,7 +119,7 @@ def map( >>> bpd.options.compute.ai_ops_confirmation_threshold = 25 >>> import bigframes.ml.llm as llm - >>> model = llm.GeminiTextGenerator(model_name="gemini-2.0-flash-001") + >>> model = llm.GeminiTextGenerator(model_name="gemini-2.5-pro") >>> df = bpd.DataFrame({"ingredient_1": ["Burger Bun", "Soy Bean"], "ingredient_2": ["Beef Patty", "Bittern"]}) >>> df.ai.map("What is the food made from {ingredient_1} and {ingredient_2}? One word only.", model=model, output_schema={"food": "string"}) @@ -137,7 +137,7 @@ def map( >>> bpd.options.compute.ai_ops_confirmation_threshold = 25 >>> import bigframes.ml.llm as llm - >>> model = llm.GeminiTextGenerator(model_name="gemini-2.0-flash-001") + >>> model = llm.GeminiTextGenerator(model_name="gemini-2.5-pro") >>> df = bpd.DataFrame({"text": ["Elmo lives at 123 Sesame Street."]}) >>> df.ai.map("{text}", model=model, output_schema={"person": "string", "address": "string"}) @@ -268,7 +268,7 @@ def classify( >>> bpd.options.compute.ai_ops_confirmation_threshold = 25 >>> import bigframes.ml.llm as llm - >>> model = llm.GeminiTextGenerator(model_name="gemini-2.0-flash-001") + >>> model = llm.GeminiTextGenerator(model_name="gemini-2.5-pro") >>> df = bpd.DataFrame({ ... "feedback_text": [ @@ -357,7 +357,7 @@ def join( >>> bpd.options.compute.ai_ops_confirmation_threshold = 25 >>> import bigframes.ml.llm as llm - >>> model = llm.GeminiTextGenerator(model_name="gemini-2.0-flash-001") + >>> model = llm.GeminiTextGenerator(model_name="gemini-2.5-pro") >>> cities = bpd.DataFrame({'city': ['Seattle', 'Ottawa', 'Berlin', 'Shanghai', 'New Delhi']}) >>> continents = bpd.DataFrame({'continent': ['North America', 'Africa', 'Asia']}) From 6cc890b5b9088e19afc7dd3dfbb64c72309feb80 Mon Sep 17 00:00:00 2001 From: Daniel Sanche Date: Wed, 3 Jun 2026 07:43:31 -0700 Subject: [PATCH 014/174] fix(bigtable): ensure deadline is respected for read_rows_sharded (#17352) The read_rows_sharded tests were flaky. It seems this mostly came down to not having a mutex on the timeout generator, which isn't completely thread safe in the sync context. This ensures that the timeout is always accessed sequentially Also increase the timeout in the test, to prevent future flakes --- .../google/cloud/bigtable/data/_async/client.py | 7 +++++-- .../google/cloud/bigtable/data/_sync_autogen/client.py | 4 +++- .../tests/unit/data/_async/test_client.py | 4 ++-- .../tests/unit/data/_sync_autogen/test_client.py | 4 ++-- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/google-cloud-bigtable/google/cloud/bigtable/data/_async/client.py b/packages/google-cloud-bigtable/google/cloud/bigtable/data/_async/client.py index 61cefa6ac1da..5d0a23e54364 100644 --- a/packages/google-cloud-bigtable/google/cloud/bigtable/data/_async/client.py +++ b/packages/google-cloud-bigtable/google/cloud/bigtable/data/_async/client.py @@ -1286,12 +1286,15 @@ async def read_rows_sharded( # limit the number of concurrent requests using a semaphore concurrency_sem = CrossSync.Semaphore(_CONCURRENCY_LIMIT) + # lock to ensure rpc_timeout_generator is thread-safe in sync version + gen_lock = CrossSync.Semaphore(1) @CrossSync.convert async def read_rows_with_semaphore(query): async with concurrency_sem: - # calculate new timeout based on time left in overall operation - shard_timeout = next(rpc_timeout_generator) + async with gen_lock: + # calculate new timeout based on time left in overall operation + shard_timeout = next(rpc_timeout_generator) if shard_timeout <= 0: raise DeadlineExceeded( "Operation timeout exceeded before starting query" diff --git a/packages/google-cloud-bigtable/google/cloud/bigtable/data/_sync_autogen/client.py b/packages/google-cloud-bigtable/google/cloud/bigtable/data/_sync_autogen/client.py index 384f2cbecd1b..6d808fe9719f 100644 --- a/packages/google-cloud-bigtable/google/cloud/bigtable/data/_sync_autogen/client.py +++ b/packages/google-cloud-bigtable/google/cloud/bigtable/data/_sync_autogen/client.py @@ -1049,10 +1049,12 @@ def read_rows_sharded( operation_timeout, operation_timeout ) concurrency_sem = CrossSync._Sync_Impl.Semaphore(_CONCURRENCY_LIMIT) + gen_lock = CrossSync._Sync_Impl.Semaphore(1) def read_rows_with_semaphore(query): with concurrency_sem: - shard_timeout = next(rpc_timeout_generator) + with gen_lock: + shard_timeout = next(rpc_timeout_generator) if shard_timeout <= 0: raise DeadlineExceeded( "Operation timeout exceeded before starting query" diff --git a/packages/google-cloud-bigtable/tests/unit/data/_async/test_client.py b/packages/google-cloud-bigtable/tests/unit/data/_async/test_client.py index b61dad59c709..391c38006df5 100644 --- a/packages/google-cloud-bigtable/tests/unit/data/_async/test_client.py +++ b/packages/google-cloud-bigtable/tests/unit/data/_async/test_client.py @@ -2304,7 +2304,7 @@ async def test_read_rows_sharded_expirary(self): from google.cloud.bigtable.data._helpers import _CONCURRENCY_LIMIT from google.cloud.bigtable.data.exceptions import ShardedReadRowsExceptionGroup - operation_timeout = 0.1 + operation_timeout = 5.0 # let the first batch complete, but the next batch times out num_queries = 15 @@ -2317,7 +2317,7 @@ async def mock_call(*args, **kwargs): if isinstance(next_item, Exception): raise next_item else: - await asyncio.sleep(next_item) + await CrossSync.sleep(next_item) return [mock.Mock()] async with self._make_client() as client: diff --git a/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_client.py b/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_client.py index efd90c7a9c34..f8edea5e1a32 100644 --- a/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_client.py +++ b/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_client.py @@ -1928,7 +1928,7 @@ def test_read_rows_sharded_expirary(self): from google.cloud.bigtable.data._helpers import _CONCURRENCY_LIMIT from google.cloud.bigtable.data.exceptions import ShardedReadRowsExceptionGroup - operation_timeout = 0.1 + operation_timeout = 5.0 num_queries = 15 sleeps = [0] * _CONCURRENCY_LIMIT + [DeadlineExceeded("times up")] * ( num_queries - _CONCURRENCY_LIMIT @@ -1939,7 +1939,7 @@ def mock_call(*args, **kwargs): if isinstance(next_item, Exception): raise next_item else: - asyncio.sleep(next_item) + CrossSync._Sync_Impl.sleep(next_item) return [mock.Mock()] with self._make_client() as client: From a3d93afe74dd2b5ec8a2ae92f91c95962764debe Mon Sep 17 00:00:00 2001 From: TrevorBergeron Date: Wed, 3 Jun 2026 08:12:24 -0700 Subject: [PATCH 015/174] fix(bigframes): Fix IsInOp literal bug with sqlglot (#17356) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly: - [ ] Make sure to open an issue as a [bug/issue](https://github.com/googleapis/google-cloud-python/issues) before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea - [ ] Ensure the tests and linter pass - [ ] Code coverage does not decrease (if any source code was changed) - [ ] Appropriate docs were updated (if necessary) Fixes # 🦕 --- .../sqlglot/expressions/comparison_ops.py | 2 +- .../test_comparison_ops/test_is_in/out.sql | 2 +- .../test_literals/test_float_literals/out.sql | 8 +++++ .../expressions/test_comparison_ops.py | 12 ++++++- .../sqlglot/expressions/test_literals.py | 35 +++++++++++++++++++ 5 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_literals/test_float_literals/out.sql create mode 100644 packages/bigframes/tests/unit/core/compile/sqlglot/expressions/test_literals.py diff --git a/packages/bigframes/bigframes/core/compile/sqlglot/expressions/comparison_ops.py b/packages/bigframes/bigframes/core/compile/sqlglot/expressions/comparison_ops.py index 968c2c4eed83..a3331ce6fb59 100644 --- a/packages/bigframes/bigframes/core/compile/sqlglot/expressions/comparison_ops.py +++ b/packages/bigframes/bigframes/core/compile/sqlglot/expressions/comparison_ops.py @@ -46,7 +46,7 @@ def _(expr: TypedExpr, op: ops.IsInOp) -> sge.Expression: if dtypes.can_compare(expr.dtype, dtype): if must_upcast_bools and dtype == dtypes.BOOL_DTYPE: value = int(value) - values.append(sge.convert(value)) + values.append(sql.literal(value)) sg_lexpr: sge.Expression = expr.expr if expr.dtype == dtypes.BOOL_DTYPE and must_upcast_bools: diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_comparison_ops/test_is_in/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_comparison_ops/test_is_in/out.sql index b6d860d47231..308e6f9cbd7e 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_comparison_ops/test_is_in/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_comparison_ops/test_is_in/out.sql @@ -4,7 +4,7 @@ SELECT `int64_col` IS NULL AS `ints_w_null`, COALESCE(`int64_col` IN (1.0, 2.0, 3.0), FALSE) AS `floats`, FALSE AS `strings`, - COALESCE(`int64_col` IN (2.5, 3), FALSE) AS `mixed`, + COALESCE(`int64_col` IN (2.5, 3, 1e-10, CAST('Infinity' AS FLOAT64), NULL, 0), FALSE) AS `mixed`, FALSE AS `empty`, FALSE AS `empty_wo_match_nulls`, COALESCE(`int64_col` IN (123456), FALSE) AS `ints_wo_match_nulls`, diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_literals/test_float_literals/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_literals/test_float_literals/out.sql new file mode 100644 index 000000000000..030e733edd77 --- /dev/null +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_literals/test_float_literals/out.sql @@ -0,0 +1,8 @@ +SELECT + CAST('Infinity' AS FLOAT64) AS `inf`, + CAST('-Infinity' AS FLOAT64) AS `ninf`, + NULL AS `nan`, + -0.0 AS `neg_zero`, + 1e-05 AS `0.00001`, + 1e-10 AS `1E-10` +FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` AS `bft_0` \ No newline at end of file diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/test_comparison_ops.py b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/test_comparison_ops.py index 4c397bcd70f8..73aceaedeebc 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/test_comparison_ops.py +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/test_comparison_ops.py @@ -35,7 +35,17 @@ def test_is_in(scalar_types_df: bpd.DataFrame, snapshot): int_col ), "strings": ops.IsInOp(values=("1.0", "2.0")).as_expr(int_col), - "mixed": ops.IsInOp(values=("1.0", 2.5, 3)).as_expr(int_col), + "mixed": ops.IsInOp( + values=( + "1.0", + 2.5, + 3, + 1e-10, + float("inf"), + float("nan"), + 0, + ) + ).as_expr(int_col), "empty": ops.IsInOp(values=()).as_expr(int_col), "empty_wo_match_nulls": ops.IsInOp(values=(), match_nulls=False).as_expr( int_col diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/test_literals.py b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/test_literals.py new file mode 100644 index 000000000000..aa0d7a1e5b14 --- /dev/null +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/test_literals.py @@ -0,0 +1,35 @@ +# Copyright 2025 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 pytest + +import bigframes.core.expression as ex +import bigframes.pandas as bpd +from bigframes.testing import utils + +pytest.importorskip("pytest_snapshot") + + +def test_float_literals(scalar_types_df: bpd.DataFrame, snapshot): + bf_df = scalar_types_df[["float64_col"]] + ops_map = { + "inf": ex.const(float("inf")), + "ninf": ex.const(float("-inf")), + "nan": ex.const(float("nan")), + "neg_zero": ex.const(-0.0), + "0.00001": ex.const(0.00001), + "1E-10": ex.const(1e-10), + } + sql = utils._apply_ops_to_sql(bf_df, list(ops_map.values()), list(ops_map.keys())) + snapshot.assert_match(sql, "out.sql") From cdaf2139d26fab2a063b8cc530c7d1a61544e097 Mon Sep 17 00:00:00 2001 From: shokkunrf <19404989+shokkunrf@users.noreply.github.com> Date: Thu, 4 Jun 2026 00:46:22 +0900 Subject: [PATCH 016/174] fix(firestore): remove usage of typing_extensions (#17357) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #17244 🦕 This PR addresses the `google-cloud-firestore` portion of #17244 ("Remove usage of typing_extensions in google-cloud-python") by replacing the only `typing_extensions` import in this package with the stdlib `typing` equivalents. ## Summary `google/cloud/firestore_v1/async_transaction.py` was the sole module in `google-cloud-firestore` importing from `typing_extensions`. All three names it imports (`Concatenate`, `ParamSpec`, `TypeVar`) are available in the stdlib `typing` module since Python 3.10, and `setup.py` declares `python_requires=">=3.10"`, so the import can be moved to the stdlib without any compatibility loss. ## Changes `packages/google-cloud-firestore/google/cloud/firestore_v1/async_transaction.py`: - Add `Concatenate`, `ParamSpec`, `TypeVar` to the existing `from typing import (...)` block (kept alphabetical). - Remove the `from typing_extensions import Concatenate, ParamSpec, TypeVar` line. ## Why this works | Symbol | Stdlib `typing` availability | |---|---| | `Concatenate` | Python 3.10+ | | `ParamSpec` | Python 3.10+ | | `TypeVar` | Always available | ## Verification In a clean venv with only `google-cloud-firestore` installed (no `typing-extensions`), `from google.cloud.firestore_v1 import async_transaction` now succeeds — confirming the dependency on `typing-extensions` is fully removed. ## Scope note Other packages in this monorepo also use `typing_extensions` (`google-api-core`, `google-cloud-bigtable`, `google-cloud-spanner`, `bigframes`). Each has its own `python_requires` and set of imported symbols (notably `Self`, which requires Python 3.11+ in the stdlib), so this PR is scoped to `google-cloud-firestore` only. Let me know if you'd like me to follow up with PRs for any of the others — happy to. --- .../google/cloud/firestore_v1/async_transaction.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/google-cloud-firestore/google/cloud/firestore_v1/async_transaction.py b/packages/google-cloud-firestore/google/cloud/firestore_v1/async_transaction.py index 594edca8a1a0..c1724b69633e 100644 --- a/packages/google-cloud-firestore/google/cloud/firestore_v1/async_transaction.py +++ b/packages/google-cloud-firestore/google/cloud/firestore_v1/async_transaction.py @@ -22,13 +22,15 @@ AsyncGenerator, Awaitable, Callable, + Concatenate, Generic, Optional, + ParamSpec, + TypeVar, ) from google.api_core import exceptions, gapic_v1 from google.api_core import retry_async as retries -from typing_extensions import Concatenate, ParamSpec, TypeVar from google.cloud.firestore_v1 import _helpers, async_batch from google.cloud.firestore_v1.async_document import AsyncDocumentReference From c7bb44c8b7207bfd5668897fe8ff8cd5204a54e9 Mon Sep 17 00:00:00 2001 From: Tomo Suzuki Date: Wed, 3 Jun 2026 13:15:11 -0400 Subject: [PATCH 017/174] chore: update librarian to v0.16.0 (#17361) The changes are from: ``` ~/librarian-2026/google-cloud-python$ go run github.com/googleapis/librarian/cmd/librarian@latest update version ~/librarian-2026/google-cloud-python$ V=$(go run github.com/googleapis/librarian/cmd/librarian@latest config get version) ~/librarian-2026/google-cloud-python$ echo $V v0.16.0 ~/librarian-2026/google-cloud-python$ go run github.com/googleapis/librarian/tool/cmd/builddockerimages@latest --language python --version=${V} ~/librarian-2026/google-cloud-python$ time docker run -u $(id -u):$(id -g) -v .:/repo -v ~/.cache:/.cache -w /repo docker.io/library/librarian-python:${V} generate -v --all ``` --- librarian.yaml | 2 +- .../samples/samples/async_snippets.py | 19 ++++++++++++++++--- .../samples/samples/async_snippets_test.py | 16 ++++++++++++---- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/librarian.yaml b/librarian.yaml index fb5d376113a1..d9bbe6f20b04 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. language: python -version: v0.15.1-0.20260528141105-567c9bf1faa7 +version: v0.16.0 repo: googleapis/google-cloud-python sources: googleapis: diff --git a/packages/google-cloud-spanner/samples/samples/async_snippets.py b/packages/google-cloud-spanner/samples/samples/async_snippets.py index 6ec5580447eb..c8f3887c9000 100644 --- a/packages/google-cloud-spanner/samples/samples/async_snippets.py +++ b/packages/google-cloud-spanner/samples/samples/async_snippets.py @@ -19,8 +19,9 @@ """ import asyncio -from google.cloud.spanner_v1 import AsyncClient -from google.cloud.spanner_v1 import KeySet + +from google.cloud.spanner_v1 import AsyncClient, KeySet + # [START spanner_async_create_client] async def async_create_client(instance_id, database_id): @@ -31,6 +32,8 @@ async def async_create_client(instance_id, database_id): print("Async Spanner client instantiated successfully.") return database + + # [END spanner_async_create_client] @@ -48,6 +51,8 @@ async def async_query_data(instance_id, database_id): async for row in results: print("SingerId: {}, AlbumId: {}, AlbumTitle: {}".format(*row)) + + # [END spanner_async_query_data] @@ -68,6 +73,8 @@ async def insert_singers(transaction): await database.run_in_transaction(insert_singers) print("Async DML Insert transaction complete.") + + # [END spanner_async_insert_data] @@ -84,7 +91,9 @@ async def update_singer_lastname(transaction): "SELECT SingerId, FirstName, LastName FROM Singers WHERE SingerId = 12" ) async for row in results: - print("Before Update - SingerId: {}, FirstName: {}, LastName: {}".format(*row)) + print( + "Before Update - SingerId: {}, FirstName: {}, LastName: {}".format(*row) + ) # Update LastName await transaction.execute_update( @@ -93,6 +102,8 @@ async def update_singer_lastname(transaction): await database.run_in_transaction(update_singer_lastname) print("Async read-write transaction complete.") + + # [END spanner_async_read_write_transaction] @@ -114,4 +125,6 @@ async def async_read_only_transaction(instance_id, database_id): async for row in results: print("Read Row - SingerId: {}, FirstName: {}, LastName: {}".format(*row)) + + # [END spanner_async_read_only_transaction] diff --git a/packages/google-cloud-spanner/samples/samples/async_snippets_test.py b/packages/google-cloud-spanner/samples/samples/async_snippets_test.py index 8405e1c8f22f..397ff3a8fec7 100644 --- a/packages/google-cloud-spanner/samples/samples/async_snippets_test.py +++ b/packages/google-cloud-spanner/samples/samples/async_snippets_test.py @@ -13,8 +13,10 @@ # limitations under the License. import pytest + import async_snippets + @pytest.fixture(scope="module") def database_ddl(): """DDL statements to set up the database for testing async snippets.""" @@ -30,14 +32,16 @@ def database_ddl(): AlbumId INT64 NOT NULL, AlbumTitle STRING(MAX) ) PRIMARY KEY (SingerId, AlbumId), - INTERLEAVE IN PARENT Singers ON DELETE CASCADE""" + INTERLEAVE IN PARENT Singers ON DELETE CASCADE""", ] @pytest.mark.asyncio async def test_async_snippets_flow(capsys, instance_id, sample_database): # 1. Test Async Spanner Client Creation - db = await async_snippets.async_create_client(instance_id, sample_database.database_id) + db = await async_snippets.async_create_client( + instance_id, sample_database.database_id + ) assert db is not None out, _ = capsys.readouterr() assert "Async Spanner client instantiated successfully." in out @@ -65,13 +69,17 @@ async def test_async_snippets_flow(capsys, instance_id, sample_database): assert "SingerId: 13, AlbumId: 2, AlbumTitle: Go, Go, Go" in out # 5. Test Async Read-Write Transaction - await async_snippets.async_read_write_transaction(instance_id, sample_database.database_id) + await async_snippets.async_read_write_transaction( + instance_id, sample_database.database_id + ) out, _ = capsys.readouterr() assert "Before Update - SingerId: 12, FirstName: Melissa, LastName: Garcia" in out assert "Async read-write transaction complete." in out # 6. Test Async Read-Only Transaction - await async_snippets.async_read_only_transaction(instance_id, sample_database.database_id) + await async_snippets.async_read_only_transaction( + instance_id, sample_database.database_id + ) out, _ = capsys.readouterr() assert "Read Row - SingerId: 12, FirstName: Melissa, LastName: Jackson" in out assert "Read Row - SingerId: 13, FirstName: Russell, LastName: Morales" in out From 7d440111d836b94f0ce22f6b08c7ce0e7bf4a38a Mon Sep 17 00:00:00 2001 From: Shuowei Li Date: Wed, 3 Jun 2026 17:35:56 +0000 Subject: [PATCH 018/174] feat: support automatic per-cell execution history filtering and isolated callbacks (#17144) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change introduces scoped query tracking and event callback management for BigQuery DataFrames within interactive notebook environments (Jupyter/Colab). Key Changes - Jupyter Cell Scoping: Resolves and carries the active IPython cell execution count (cell_execution_count) through TableWidget, ExecutionSpec, query executors, and final JobMetadata. - Execution History Filtering: Adds events, job_ids, and all_cells parameters to session.execution_history(). When all_cells=False, it filters query logs down to the current active notebook cell. - Scoped Callback Support: Adds a callback parameter to _read_gbq_colab that automatically subscribes to the query progress publisher during execution and automatically unsubscribes upon completion. - Robustness Fixes: 1. Instantiates expected schema/columns in _ExecutionHistory even when the dataframe is empty to prevent indexing errors. 2. Converts custom option mappings to native Python dicts when assigning query labels to avoid validation errors in the underlying BigQuery client. 3. Captures and propagates query_id in BigQueryFinishedEvent. Verified at: [go/scrcast/NjQzOTAzMTUwMzA2MDk5MnwzZWQ2MTMzYS0xYg](http://goto.google.com/scrcast/NjQzOTAzMTUwMzA2MDk5MnwzZWQ2MTMzYS0xYg) Colab notebook test: screen/7d6Yt3C28BUAKEH Fixes #<513337964> 🦕 --- packages/bigframes/bigframes/core/blocks.py | 2 + packages/bigframes/bigframes/core/events.py | 16 ++- .../bigframes/core/global_session.py | 18 ++- packages/bigframes/bigframes/core/utils.py | 13 ++ packages/bigframes/bigframes/dataframe.py | 4 + .../bigframes/bigframes/display/anywidget.py | 12 +- packages/bigframes/bigframes/pandas/io/api.py | 14 ++- packages/bigframes/bigframes/series.py | 2 + .../bigframes/bigframes/session/__init__.py | 118 ++++++++++++++++-- .../session/_io/bigquery/__init__.py | 75 +++++++---- .../bigframes/session/bigquery_session.py | 2 +- .../bigframes/session/bq_caching_executor.py | 12 +- .../bigframes/session/direct_gbq_execution.py | 4 + .../bigframes/session/execution_spec.py | 14 ++- .../bigframes/bigframes/session/metrics.py | 38 +++++- .../tests/unit/display/test_anywidget.py | 16 +++ .../tests/unit/session/test_metrics.py | 32 +++++ .../tests/unit/session/test_read_gbq_colab.py | 88 +++++++++++++ 18 files changed, 424 insertions(+), 56 deletions(-) diff --git a/packages/bigframes/bigframes/core/blocks.py b/packages/bigframes/bigframes/core/blocks.py index 33f5aaab5c7d..6fb78363fdea 100644 --- a/packages/bigframes/bigframes/core/blocks.py +++ b/packages/bigframes/bigframes/core/blocks.py @@ -696,6 +696,7 @@ def to_pandas_batches( page_size: Optional[int] = None, max_results: Optional[int] = None, allow_large_results: Optional[bool] = None, + cell_execution_count: Optional[int] = None, ) -> PandasBatches: """Download results one message at a time. @@ -713,6 +714,7 @@ def to_pandas_batches( execution_spec.ExecutionSpec( promise_under_10gb=under_10gb, ordered=True, + cell_execution_count=cell_execution_count, ), ) result_batches = execution_result.batches() diff --git a/packages/bigframes/bigframes/core/events.py b/packages/bigframes/bigframes/core/events.py index 61831f4cc399..d6cef860f6d1 100644 --- a/packages/bigframes/bigframes/core/events.py +++ b/packages/bigframes/bigframes/core/events.py @@ -20,7 +20,7 @@ import datetime import threading import uuid -from typing import Any, Callable, Literal, Set +from typing import Any, Callable, Literal, Optional, Set import google.cloud.bigquery._job_helpers import google.cloud.bigquery.job.query @@ -127,8 +127,22 @@ class Event: @dataclasses.dataclass(frozen=True) class EventEnvelope: + """An envelope that wraps an execution event with metadata and display options. + + Attributes: + event: + The actual execution event details (e.g., ExecutionStarted, BigQuerySentEvent). + progress_bar: + Specifies the style of progress bar to display during execution. + cell_execution_count: + The 1-indexed IPython/Jupyter notebook cell execution number (e.g. the 'x' in 'In [x]'). + This is NOT a job count, but rather the sequential number of the cell execution in the + current notebook session, used to group and filter execution history on a per-cell basis. + """ + event: Event progress_bar: ProgressBarType = _DEFAULT + cell_execution_count: Optional[int] = None @dataclasses.dataclass(frozen=True) diff --git a/packages/bigframes/bigframes/core/global_session.py b/packages/bigframes/bigframes/core/global_session.py index 6ffb37ac5acf..a38280e6447e 100644 --- a/packages/bigframes/bigframes/core/global_session.py +++ b/packages/bigframes/bigframes/core/global_session.py @@ -19,7 +19,7 @@ import threading import traceback import warnings -from typing import TYPE_CHECKING, Callable, Optional, TypeVar +from typing import TYPE_CHECKING, Callable, Iterable, Optional, TypeVar import google.auth.exceptions @@ -124,12 +124,20 @@ def with_default_session(func_: Callable[..., _T], *args, **kwargs) -> _T: return func_(get_global_session(), *args, **kwargs) -def execution_history() -> "bigframes.session._ExecutionHistory": - import pandas # noqa: F401 - +def execution_history( + *, + events: Optional[Iterable[bigframes.core.events.Event]] = None, + job_ids: Optional[Iterable[str]] = None, + all_cells: bool = True, +) -> "bigframes.session._ExecutionHistory": import bigframes.session - return with_default_session(bigframes.session.Session.execution_history) + return with_default_session( + bigframes.session.Session.execution_history, + events=events, + job_ids=job_ids, + all_cells=all_cells, + ) class _GlobalSessionContext: diff --git a/packages/bigframes/bigframes/core/utils.py b/packages/bigframes/bigframes/core/utils.py index b219335a516e..641fbcc9ac40 100644 --- a/packages/bigframes/bigframes/core/utils.py +++ b/packages/bigframes/bigframes/core/utils.py @@ -249,3 +249,16 @@ def timedelta_to_micros( ) * 1_000_000 + timedelta.microseconds raise TypeError(f"Unrecognized input type: {type(timedelta)}") + + +def get_ipython_execution_count() -> typing.Optional[int]: + """Returns the current IPython cell execution count if running in a notebook, else None.""" + try: + from IPython.core.interactiveshell import InteractiveShell + + if InteractiveShell.initialized(): + ipy = InteractiveShell.instance() + return getattr(ipy, "execution_count", None) + except (ImportError, NameError): + pass + return None diff --git a/packages/bigframes/bigframes/dataframe.py b/packages/bigframes/bigframes/dataframe.py index cc80dd0af314..6b7922fe9753 100644 --- a/packages/bigframes/bigframes/dataframe.py +++ b/packages/bigframes/bigframes/dataframe.py @@ -1755,6 +1755,7 @@ def to_pandas_batches( max_results: Optional[int] = None, *, allow_large_results: Optional[bool] = None, + cell_execution_count: Optional[int] = None, ) -> blocks.PandasBatches: """Stream DataFrame results to an iterable of pandas DataFrame. @@ -1807,6 +1808,7 @@ def to_pandas_batches( page_size=page_size, max_results=max_results, allow_large_results=allow_large_results, + cell_execution_count=cell_execution_count, ) def _to_pandas_batches( @@ -1815,11 +1817,13 @@ def _to_pandas_batches( max_results: Optional[int] = None, *, allow_large_results: Optional[bool] = None, + cell_execution_count: Optional[int] = None, ) -> blocks.PandasBatches: return self._block.to_pandas_batches( page_size=page_size, max_results=max_results, allow_large_results=allow_large_results, + cell_execution_count=cell_execution_count, ) def _compute_dry_run(self) -> google.cloud.bigquery.job.QueryJob: diff --git a/packages/bigframes/bigframes/display/anywidget.py b/packages/bigframes/bigframes/display/anywidget.py index 90d285d1b0d7..08b19d820173 100644 --- a/packages/bigframes/bigframes/display/anywidget.py +++ b/packages/bigframes/bigframes/display/anywidget.py @@ -92,6 +92,10 @@ def __init__(self, dataframe: bigframes.dataframe.DataFrame): self._dataframe = dataframe + from bigframes.core.utils import get_ipython_execution_count + + self._cell_execution_count = get_ipython_execution_count() + super().__init__() # Initialize attributes that might be needed by observers first @@ -286,7 +290,10 @@ def _reset_batch_cache(self) -> None: def _reset_batches_for_new_page_size(self) -> None: """Reset the batch iterator when page size changes.""" with bigframes.option_context("display.progress_bar", None): - self._batches = self._dataframe.to_pandas_batches(page_size=self.page_size) + self._batches = self._dataframe.to_pandas_batches( + page_size=self.page_size, + cell_execution_count=self._cell_execution_count, + ) self._reset_batch_cache() @@ -318,7 +325,8 @@ def _set_table_html(self) -> None: current_sort_state = _SortState(tuple(sort_columns), tuple(sort_ascending)) if self._last_sort_state != current_sort_state: self._batches = df_to_display.to_pandas_batches( - page_size=self.page_size + page_size=self.page_size, + cell_execution_count=self._cell_execution_count, ) self._reset_batch_cache() self._last_sort_state = current_sort_state diff --git a/packages/bigframes/bigframes/pandas/io/api.py b/packages/bigframes/bigframes/pandas/io/api.py index 6c83095ab3cd..fa0f503a08b8 100644 --- a/packages/bigframes/bigframes/pandas/io/api.py +++ b/packages/bigframes/bigframes/pandas/io/api.py @@ -300,8 +300,9 @@ def _try_read_gbq_colab_sessionless_dry_run( def _read_gbq_colab( # type: ignore[overload-overlap] query_or_table: str, *, - pyformat_args: Optional[Dict[str, Any]] = ..., - dry_run: Literal[False] = ..., + callback: Optional[Callable[[bigframes.core.events.EventEnvelope], None]] = None, + pyformat_args: Optional[Dict[str, Any]] = None, + dry_run: Literal[False] = False, ) -> bigframes.dataframe.DataFrame: ... @@ -309,14 +310,16 @@ def _read_gbq_colab( # type: ignore[overload-overlap] def _read_gbq_colab( query_or_table: str, *, - pyformat_args: Optional[Dict[str, Any]] = ..., - dry_run: Literal[True] = ..., + callback: Optional[Callable[[bigframes.core.events.EventEnvelope], None]] = None, + pyformat_args: Optional[Dict[str, Any]] = None, + dry_run: Literal[True], ) -> pandas.Series: ... def _read_gbq_colab( query_or_table: str, *, + callback: Optional[Callable[[bigframes.core.events.EventEnvelope], None]] = None, pyformat_args: Optional[Dict[str, Any]] = None, dry_run: bool = False, ) -> bigframes.dataframe.DataFrame | pandas.Series: @@ -328,6 +331,8 @@ def _read_gbq_colab( Args: query_or_table (str): SQL query or table ID (table ID not yet supported). + callback (Optional[Callable[[bigframes.core.events.EventEnvelope], None]]): + Callback to receive query execution events. pyformat_args (Optional[Dict[str, Any]]): Parameters to format into the query string. dry_run (bool): @@ -379,6 +384,7 @@ def _read_gbq_colab( return global_session.with_default_session( bigframes.session.Session._read_gbq_colab, query_or_table, + callback=callback, pyformat_args=pyformat_args, dry_run=dry_run, ) diff --git a/packages/bigframes/bigframes/series.py b/packages/bigframes/bigframes/series.py index 0091d0a34b6c..d4e704591b01 100644 --- a/packages/bigframes/bigframes/series.py +++ b/packages/bigframes/bigframes/series.py @@ -760,6 +760,7 @@ def to_pandas_batches( max_results: Optional[int] = None, *, allow_large_results: Optional[bool] = None, + cell_execution_count: Optional[int] = None, ) -> Iterable[pandas.Series]: """Stream Series results to an iterable of pandas Series. @@ -812,6 +813,7 @@ def to_pandas_batches( page_size=page_size, max_results=max_results, allow_large_results=allow_large_results, + cell_execution_count=cell_execution_count, ) return map(lambda df: cast(pandas.Series, df.squeeze(1)), batches) diff --git a/packages/bigframes/bigframes/session/__init__.py b/packages/bigframes/bigframes/session/__init__.py index bbe27b6a795a..e20f61901f9a 100644 --- a/packages/bigframes/bigframes/session/__init__.py +++ b/packages/bigframes/bigframes/session/__init__.py @@ -113,6 +113,18 @@ class _ExecutionHistory: def __init__(self, jobs: list[dict]): self._df = pandas.DataFrame(jobs) + if self._df.empty: + self._df = pandas.DataFrame( + columns=[ + "job_id", + "query_id", + "job_type", + "status", + "query", + "total_bytes_processed", + "job_url", + ] + ) def to_dataframe(self) -> pandas.DataFrame: """Returns the execution history as a pandas DataFrame.""" @@ -200,9 +212,10 @@ def __init__( self._location = context.location or "US" project = "test_project" else: - credentials, project = ( - bigframes._config.auth.resolve_credentials_and_project(context) - ) + ( + credentials, + project, + ) = bigframes._config.auth.resolve_credentials_and_project(context) if context.location is None: with bigquery.Client( project=project, @@ -449,12 +462,79 @@ def slot_millis_sum(self): """The sum of all slot time used by bigquery jobs in this session.""" return self._metrics.slot_millis - def execution_history(self) -> _ExecutionHistory: + def execution_history( + self, + *, + events: Optional[Iterable[bigframes.core.events.Event]] = None, + job_ids: Optional[Iterable[str]] = None, + all_cells: bool = True, + ) -> _ExecutionHistory: """Returns the history of executions initiated by BigFrames in the current session. Use `.to_dataframe()` on the result to get a pandas DataFrame. + + Args: + events (Iterable[Event], optional): + Filter execution history to only include jobs associated with the given events. + job_ids (Iterable[str], optional): + Filter execution history to only include jobs matching the given job IDs. + all_cells (bool, optional): + If True, do not filter execution history by notebook cell. If False, + and running in Colab/Jupyter, automatically filter history to only include + jobs executed within the current cell. Defaults to True. """ - return _ExecutionHistory([job.__dict__ for job in self._metrics.jobs]) + jobs = [job.__dict__ for job in self._metrics.jobs] + + if events is not None: + event_job_ids = { + getattr(event, "job_id", None) + for event in events + if getattr(event, "job_id", None) is not None + } + event_query_ids = { + getattr(event, "query_id", None) + for event in events + if getattr(event, "query_id", None) is not None + } + jobs = [ + job + for job in jobs + if ( + job.get("job_id") is not None and job.get("job_id") in event_job_ids + ) + or ( + job.get("query_id") is not None + and job.get("query_id") in event_query_ids + ) + ] + + elif job_ids is not None: + target_job_ids = set(job_ids) + jobs = [ + job + for job in jobs + if ( + job.get("job_id") is not None + and job.get("job_id") in target_job_ids + ) + or ( + job.get("query_id") is not None + and job.get("query_id") in target_job_ids + ) + ] + + elif not all_cells: + from bigframes.core.utils import get_ipython_execution_count + + current_count = get_ipython_execution_count() + if current_count is not None: + jobs = [ + job + for job in jobs + if job.get("cell_execution_count") == current_count + ] + + return _ExecutionHistory(jobs) @property def _allows_ambiguity(self) -> bool: @@ -601,6 +681,7 @@ def _read_gbq_colab( self, query: str, *, + callback: Optional[Callable[[bigframes.core.events.EventEnvelope], None]] = ..., pyformat_args: Optional[Dict[str, Any]] = None, dry_run: Literal[False] = ..., ) -> dataframe.DataFrame: ... @@ -610,6 +691,7 @@ def _read_gbq_colab( self, query: str, *, + callback: Optional[Callable[[bigframes.core.events.EventEnvelope], None]] = ..., pyformat_args: Optional[Dict[str, Any]] = None, dry_run: Literal[True] = ..., ) -> pandas.Series: ... @@ -618,8 +700,10 @@ def _read_gbq_colab( def _read_gbq_colab( self, query: str, - # TODO: Add a callback parameter that takes some kind of Event object. *, + callback: Optional[ + Callable[[bigframes.core.events.EventEnvelope], None] + ] = None, pyformat_args: Optional[Dict[str, Any]] = None, dry_run: bool = False, ) -> Union[dataframe.DataFrame, pandas.Series]: @@ -632,6 +716,8 @@ def _read_gbq_colab( query (str): A SQL query string to execute. Results (if any) are turned into a DataFrame. + callback (Optional[Callable[[bigframes.core.events.EventEnvelope], None]]): + Callback to receive query execution events. pyformat_args (dict): A dictionary of potential variables to replace in ``query``. Note: strings are _not_ escaped. Use query parameters for these, @@ -651,13 +737,19 @@ def _read_gbq_colab( dry_run=dry_run, ) - return self._loader.read_gbq_query( - query=query, - index_col=bigframes.enums.DefaultIndexKind.NULL, - force_total_order=False, - dry_run=typing.cast(Union[Literal[False], Literal[True]], dry_run), - allow_large_results=allow_large_results, - ) + def _run_query(): + return self._loader.read_gbq_query( + query=query, + index_col=bigframes.enums.DefaultIndexKind.NULL, + force_total_order=False, + dry_run=typing.cast(Union[Literal[False], Literal[True]], dry_run), + allow_large_results=allow_large_results, + ) + + if callback is not None: + with self._publisher.subscribe(callback): + return _run_query() + return _run_query() @overload def read_gbq_query( # type: ignore[overload-overlap] diff --git a/packages/bigframes/bigframes/session/_io/bigquery/__init__.py b/packages/bigframes/bigframes/session/_io/bigquery/__init__.py index 5d985b6e107b..58bd5bd61748 100644 --- a/packages/bigframes/bigframes/session/_io/bigquery/__init__.py +++ b/packages/bigframes/bigframes/session/_io/bigquery/__init__.py @@ -64,6 +64,8 @@ def create_job_configs_labels( ) -> Dict[str, str]: if job_configs_labels is None: job_configs_labels = {} + else: + job_configs_labels = dict(job_configs_labels) if api_methods and "bigframes-api" not in job_configs_labels: job_configs_labels["bigframes-api"] = api_methods[0] @@ -261,7 +263,7 @@ def add_and_trim_labels( ) -def create_bq_event_callback(publisher): +def create_bq_event_callback(publisher, cell_execution_count=None): event_map = { google.cloud.bigquery._job_helpers.QueryFinishedEvent: ( bigframes.core.events.BigQueryFinishedEvent @@ -284,7 +286,9 @@ def publish_bq_event(event): bf_event = bf_type.from_bqclient(event) # type: ignore break envelope = bigframes.core.events.EventEnvelope( - event=bf_event, progress_bar=bigframes.core.events._DEFAULT + event=bf_event, + progress_bar=bigframes.core.events._DEFAULT, + cell_execution_count=cell_execution_count, ) publisher.publish(envelope) @@ -307,10 +311,16 @@ def start_query_with_job( job_retry: google.api_core.retry.Retry = (third_party_gcb_retry.DEFAULT_JOB_RETRY), # noqa: E501 publisher: bigframes.core.events.Publisher, session=None, + cell_execution_count: Optional[int] = None, ) -> Tuple[google.cloud.bigquery.table.RowIterator, bigquery.QueryJob]: """ Starts query job and waits for results. """ + if cell_execution_count is None: + from bigframes.core.utils import get_ipython_execution_count + + cell_execution_count = get_ipython_execution_count() + # Note: Ensure no additional labels are added to job_config after this # point, as `add_and_trim_labels` ensures the label count does not # exceed MAX_LABELS_COUNT. @@ -337,6 +347,7 @@ def start_query_with_job( sql=sql, publisher=publisher, metrics=metrics, + cell_execution_count=cell_execution_count, ) return results_iterator, query_job @@ -357,6 +368,7 @@ def start_query_job_optional( job_retry: google.api_core.retry.Retry = (third_party_gcb_retry.DEFAULT_JOB_RETRY), # noqa: E501 publisher: Optional[bigframes.core.events.Publisher] = None, session=None, + cell_execution_count: Optional[int] = None, ) -> google.cloud.bigquery.table.RowIterator: """ Run a bigquery query, with job optional. @@ -364,6 +376,11 @@ def start_query_job_optional( See: https://docs.cloud.google.com/bigquery/docs/running-queries#optional-job-creation """ + if cell_execution_count is None: + from bigframes.core.utils import get_ipython_execution_count + + cell_execution_count = get_ipython_execution_count() + add_and_trim_labels(job_config, session=session) try: results_iterator = bq_client._query_and_wait_bigframes( @@ -373,12 +390,16 @@ def start_query_job_optional( project=project, api_timeout=timeout, job_retry=job_retry, - callback=create_bq_event_callback(publisher) + callback=create_bq_event_callback( + publisher, cell_execution_count=cell_execution_count + ) if publisher else lambda _: None, ) if metrics is not None: - metrics.count_job_stats(row_iterator=results_iterator) + metrics.count_job_stats( + row_iterator=results_iterator, cell_execution_count=cell_execution_count + ) return results_iterator except google.api_core.exceptions.Forbidden as ex: if "Drive credentials" in ex.message: @@ -392,35 +413,45 @@ def _publish_events( total_rows: Optional[int], publisher: bigframes.core.events.Publisher, metrics: Optional[bigframes.session.metrics.ExecutionMetrics] = None, + cell_execution_count: Optional[int] = None, ): if not query_job.configuration.dry_run: publisher.publish( - bigframes.core.events.BigQuerySentEvent( - sql, - billing_project=query_job.project, - location=query_job.location, - job_id=query_job.job_id, - request_id=None, + bigframes.core.events.EventEnvelope( + event=bigframes.core.events.BigQuerySentEvent( + sql, + billing_project=query_job.project, + location=query_job.location, + job_id=query_job.job_id, + request_id=None, + ), + cell_execution_count=cell_execution_count, ) ) if not query_job.configuration.dry_run: publisher.publish( - bigframes.core.events.BigQueryFinishedEvent( - billing_project=query_job.project, - location=query_job.location, - job_id=query_job.job_id, - destination=query_job.destination, - total_rows=total_rows, - total_bytes_processed=query_job.total_bytes_processed, - slot_millis=query_job.slot_millis, - created=query_job.created, - started=query_job.started, - ended=query_job.ended, + bigframes.core.events.EventEnvelope( + event=bigframes.core.events.BigQueryFinishedEvent( + billing_project=query_job.project, + location=query_job.location, + query_id=query_job.query_id, + job_id=query_job.job_id, + destination=query_job.destination, + total_rows=total_rows, + total_bytes_processed=query_job.total_bytes_processed, + slot_millis=query_job.slot_millis, + created=query_job.created, + started=query_job.started, + ended=query_job.ended, + ), + cell_execution_count=cell_execution_count, ) ) if metrics is not None: - metrics.count_job_stats(query_job=query_job) + metrics.count_job_stats( + query_job=query_job, cell_execution_count=cell_execution_count + ) def delete_tables_matching_session_id( diff --git a/packages/bigframes/bigframes/session/bigquery_session.py b/packages/bigframes/bigframes/session/bigquery_session.py index a39c6136876d..18f8cdeaff49 100644 --- a/packages/bigframes/bigframes/session/bigquery_session.py +++ b/packages/bigframes/bigframes/session/bigquery_session.py @@ -122,7 +122,7 @@ def close(self): # Assume this is being called in the user thread, so we can access # this thread-local config. job_config=bigquery.QueryJobConfig( - labels=bigframes.options.compute.extra_query_labels + labels=dict(bigframes.options.compute.extra_query_labels) ), location=self.location, project=None, diff --git a/packages/bigframes/bigframes/session/bq_caching_executor.py b/packages/bigframes/bigframes/session/bq_caching_executor.py index d7f228b1bc1f..dede318d8132 100644 --- a/packages/bigframes/bigframes/session/bq_caching_executor.py +++ b/packages/bigframes/bigframes/session/bq_caching_executor.py @@ -219,8 +219,9 @@ async def _execute_async( execution_spec, ) await self._publisher.publish_async( - bigframes.core.events.ExecutionFinished( - result=result, + bigframes.core.events.EventEnvelope( + event=bigframes.core.events.ExecutionFinished(result=result), + cell_execution_count=execution_spec.cell_execution_count, ) ) return result @@ -235,8 +236,11 @@ async def _try_execute_semi_executors( maybe_result = await exec.execute(plan, execution_spec) if maybe_result: await self._publisher.publish_async( - bigframes.core.events.ExecutionFinished( - result=maybe_result, + bigframes.core.events.EventEnvelope( + event=bigframes.core.events.ExecutionFinished( + result=maybe_result, + ), + cell_execution_count=execution_spec.cell_execution_count, ) ) return maybe_result diff --git a/packages/bigframes/bigframes/session/direct_gbq_execution.py b/packages/bigframes/bigframes/session/direct_gbq_execution.py index 6b1ac76d28a2..bcfc29ba971c 100644 --- a/packages/bigframes/bigframes/session/direct_gbq_execution.py +++ b/packages/bigframes/bigframes/session/direct_gbq_execution.py @@ -106,6 +106,7 @@ async def execute( job_config=job_config, query_with_job=(not can_skip_job), session=plan.session, + cell_execution_count=spec.cell_execution_count, ) result_bq_data = None if query_job and query_job.destination: @@ -155,6 +156,7 @@ def _run_execute_query( job_config: bq_job.QueryJobConfig, query_with_job: bool, session, + cell_execution_count: Optional[int] = None, ) -> Tuple[bq_table.RowIterator, Optional[bigquery.QueryJob]]: """ Starts BigQuery query job and waits for results. @@ -168,6 +170,7 @@ def _run_execute_query( metrics=self._metrics, publisher=self._publisher, session=session, + cell_execution_count=cell_execution_count, ) else: return ( @@ -178,6 +181,7 @@ def _run_execute_query( metrics=self._metrics, publisher=self._publisher, session=session, + cell_execution_count=cell_execution_count, ), None, ) diff --git a/packages/bigframes/bigframes/session/execution_spec.py b/packages/bigframes/bigframes/session/execution_spec.py index 9a095b23a8d7..89de6eec9021 100644 --- a/packages/bigframes/bigframes/session/execution_spec.py +++ b/packages/bigframes/bigframes/session/execution_spec.py @@ -60,6 +60,7 @@ class ExecutionSpec: # BigQuery specific options bigquery_config: Optional[BqComputeOptions] = None + cell_execution_count: Optional[int] = None def with_bq_labels(self, labels: Mapping[str, str]) -> ExecutionSpec: bq_config = self.bigquery_config or BqComputeOptions() @@ -77,7 +78,18 @@ def with_compute_options(self, compute_options: ComputeOptions) -> ExecutionSpec new_bq_config = new_bq_config.push_labels( dict(self.bigquery_config.extra_query_labels) ) - return dataclasses.replace(self, bigquery_config=new_bq_config) + + cell_execution_count = self.cell_execution_count + if cell_execution_count is None: + from bigframes.core.utils import get_ipython_execution_count + + cell_execution_count = get_ipython_execution_count() + + return dataclasses.replace( + self, + bigquery_config=new_bq_config, + cell_execution_count=cell_execution_count, + ) # Used internally by execution diff --git a/packages/bigframes/bigframes/session/metrics.py b/packages/bigframes/bigframes/session/metrics.py index 3712cce80726..a9a444ecb389 100644 --- a/packages/bigframes/bigframes/session/metrics.py +++ b/packages/bigframes/bigframes/session/metrics.py @@ -51,12 +51,14 @@ class JobMetadata: input_bytes: Optional[int] = None output_rows: Optional[int] = None source_format: Optional[str] = None + cell_execution_count: Optional[int] = None @classmethod def from_job( cls, query_job: Union[QueryJob, LoadJob], exec_seconds: Optional[float] = None, + cell_execution_count: Optional[int] = None, ) -> "JobMetadata": query_text = getattr(query_job, "query", None) if query_text and len(query_text) > 1024: @@ -71,6 +73,11 @@ def from_job( f"{job_id}&page=queryresults" ) + if cell_execution_count is None: + from bigframes.core.utils import get_ipython_execution_count + + cell_execution_count = get_ipython_execution_count() + metadata = cls( job_id=query_job.job_id, location=query_job.location, @@ -84,6 +91,7 @@ def from_job( error_result=query_job.error_result, query=query_text, job_url=job_url, + cell_execution_count=cell_execution_count, ) if isinstance(query_job, QueryJob): metadata.cached = getattr(query_job, "cache_hit", None) @@ -117,6 +125,7 @@ def from_row_iterator( cls, row_iterator: bq_table.RowIterator, exec_seconds: Optional[float] = None, + cell_execution_count: Optional[int] = None, ) -> "JobMetadata": query_text = getattr(row_iterator, "query", None) if query_text and len(query_text) > 1024: @@ -132,6 +141,11 @@ def from_row_iterator( f"project={project}&j=bq:{location}:{job_id}&page=queryresults" ) + if cell_execution_count is None: + from bigframes.core.utils import get_ipython_execution_count + + cell_execution_count = get_ipython_execution_count() + # fmt: off return cls( job_id=job_id, @@ -151,6 +165,7 @@ def from_row_iterator( cached=getattr(row_iterator, "cache_hit", None), query=query_text, job_url=job_url, + cell_execution_count=cell_execution_count, ) # fmt: on @@ -169,6 +184,8 @@ def count_job_stats( self, query_job: Optional[Union[QueryJob, LoadJob]] = None, row_iterator: Optional[bq_table.RowIterator] = None, + *, + cell_execution_count: Optional[int] = None, ): if query_job is None: assert row_iterator is not None @@ -194,7 +211,9 @@ def count_job_stats( self.jobs.append( JobMetadata.from_row_iterator( - row_iterator, exec_seconds=exec_seconds + row_iterator, + exec_seconds=exec_seconds, + cell_execution_count=cell_execution_count, ) ) @@ -225,7 +244,9 @@ def count_job_stats( self.execution_secs += exec_seconds or 0 metadata = JobMetadata.from_job( - query_job, exec_seconds=exec_seconds + query_job, + exec_seconds=exec_seconds, + cell_execution_count=cell_execution_count, ) self.jobs.append(metadata) @@ -237,7 +258,11 @@ def count_job_stats( else None ) self.jobs.append( - JobMetadata.from_job(query_job, exec_seconds=duration) + JobMetadata.from_job( + query_job, + exec_seconds=duration, + cell_execution_count=cell_execution_count, + ) ) # For pytest runs only, log information about the query job @@ -284,6 +309,7 @@ def on_event(self, envelope: Any): # EventEnvelope, ensuring subscribers receive a consistent contract. assert isinstance(envelope, bigframes.core.events.EventEnvelope) event = envelope.event + cell_execution_count = envelope.cell_execution_count if isinstance(event, bigframes.core.events.ExecutionFinished): if event.result and isinstance(event.result, LocalExecuteResult): @@ -291,10 +317,16 @@ def on_event(self, envelope: Any): bytes_processed = event.result.total_bytes_processed or 0 self.bytes_processed += bytes_processed + if cell_execution_count is None: + from bigframes.core.utils import get_ipython_execution_count + + cell_execution_count = get_ipython_execution_count() + metadata = JobMetadata( job_type="polars", status="DONE", total_bytes_processed=bytes_processed, + cell_execution_count=cell_execution_count, ) self.jobs.append(metadata) diff --git a/packages/bigframes/tests/unit/display/test_anywidget.py b/packages/bigframes/tests/unit/display/test_anywidget.py index 5c9fd79a3542..0b9afb5645f2 100644 --- a/packages/bigframes/tests/unit/display/test_anywidget.py +++ b/packages/bigframes/tests/unit/display/test_anywidget.py @@ -177,6 +177,22 @@ def test_page_size_change_resets_sort(mock_df): assert mock_df.to_pandas_batches.call_count >= 2 +def test_cell_execution_count_propagation(mock_df): + """Test that the captured cell_execution_count is propagated to to_pandas_batches.""" + with mock.patch( + "bigframes.core.utils.get_ipython_execution_count", return_value=42 + ): + with bigframes.option_context("display.render_mode", "anywidget"): + widget = TableWidget(mock_df) + + assert widget._cell_execution_count == 42 + + mock_df.to_pandas_batches.assert_called_with( + page_size=widget.page_size, + cell_execution_count=42, + ) + + def test_json_column_converted_to_string_for_display(): mock_block = mock.Mock(spec=Block) mock_block.column_labels = pd.Index(["col_json"]) diff --git a/packages/bigframes/tests/unit/session/test_metrics.py b/packages/bigframes/tests/unit/session/test_metrics.py index ebd6e210fbe2..4e550b1c77a3 100644 --- a/packages/bigframes/tests/unit/session/test_metrics.py +++ b/packages/bigframes/tests/unit/session/test_metrics.py @@ -268,3 +268,35 @@ def test_on_event_with_local_execute_result(): assert execution_metrics.jobs[0].job_type == "polars" assert execution_metrics.jobs[0].status == "DONE" assert execution_metrics.jobs[0].total_bytes_processed == 1024 + + +def test_count_job_stats_with_explicit_cell_execution_count(): + row_iterator = unittest.mock.create_autospec( + bigquery.table.RowIterator, instance=True + ) + row_iterator.total_bytes_processed = 1024 + row_iterator.query = "SELECT * FROM table" + row_iterator.slot_millis = 1234 + execution_metrics = metrics.ExecutionMetrics() + execution_metrics.count_job_stats( + row_iterator=row_iterator, cell_execution_count=42 + ) + + assert len(execution_metrics.jobs) == 1 + assert execution_metrics.jobs[0].cell_execution_count == 42 + + +def test_on_event_with_explicit_cell_execution_count(): + import bigframes.core.events + from bigframes.session.executor import LocalExecuteResult + + local_result = unittest.mock.create_autospec(LocalExecuteResult, instance=True) + local_result.total_bytes_processed = 1024 + + event = bigframes.core.events.ExecutionFinished(result=local_result) + envelope = bigframes.core.events.EventEnvelope(event=event, cell_execution_count=42) + execution_metrics = metrics.ExecutionMetrics() + execution_metrics.on_event(envelope) + + assert len(execution_metrics.jobs) == 1 + assert execution_metrics.jobs[0].cell_execution_count == 42 diff --git a/packages/bigframes/tests/unit/session/test_read_gbq_colab.py b/packages/bigframes/tests/unit/session/test_read_gbq_colab.py index bb2cba0c1093..a168ccbad5e6 100644 --- a/packages/bigframes/tests/unit/session/test_read_gbq_colab.py +++ b/packages/bigframes/tests/unit/session/test_read_gbq_colab.py @@ -126,3 +126,91 @@ def test_read_gbq_colab_doesnt_set_destination_table(): assert query == "SELECT 'my-test-query';" assert config.destination is None + + +def test_read_gbq_colab_with_callback(): + """Make sure callback receives events during execution.""" + session = mocks.create_bigquery_session() + callback = mock.Mock() + + _ = session._read_gbq_colab("SELECT 'my-test-query';", callback=callback) + + assert callback.call_count > 0 + + +def test_read_gbq_colab_filters_by_cell(): + """Verify that callbacks are scoped to individual executions.""" + session = mocks.create_bigquery_session() + callback1 = mock.Mock() + callback2 = mock.Mock() + + _ = session._read_gbq_colab("SELECT 'cell_1_query';", callback=callback1) + callback1_initial_count = callback1.call_count + + _ = session._read_gbq_colab("SELECT 'cell_2_query';", callback=callback2) + + # Verify callback1 was automatically unsubscribed upon completion + # of the first query. + assert callback1.call_count == callback1_initial_count + assert callback2.call_count > 0 + + +def test_execution_history_filtering(): + """Verify that execution_history can be filtered by job_ids or events.""" + from bigframes.session import metrics + + session = mocks.create_bigquery_session() + + job1 = metrics.JobMetadata(job_id="job_1", job_type="query", query="SELECT 1") + job2 = metrics.JobMetadata(job_id="job_2", job_type="query", query="SELECT 2") + session._metrics.jobs.extend([job1, job2]) + + history_job1 = session.execution_history(job_ids=["job_1"]).to_dataframe() + assert len(history_job1) == 1 + assert history_job1.iloc[0]["job_id"] == "job_1" + + event2 = mock.Mock() + event2.job_id = "job_2" + history_job2 = session.execution_history(events=[event2]).to_dataframe() + assert len(history_job2) == 1 + assert history_job2.iloc[0]["job_id"] == "job_2" + + +def test_execution_history_returns_all_executions_by_default(): + """Verify that execution_history returns all executions by default.""" + from bigframes.session import metrics + + session = mocks.create_bigquery_session() + job1 = metrics.JobMetadata( + job_id="job_1", job_type="query", query="SELECT 1", cell_execution_count=10 + ) + job2 = metrics.JobMetadata( + job_id="job_2", job_type="query", query="SELECT 2", cell_execution_count=20 + ) + session._metrics.jobs.extend([job1, job2]) + + history = session.execution_history().to_dataframe() + + assert len(history) == 2 + + +def test_execution_history_filters_by_notebook_cell_when_all_cells_is_false(): + """Verify that execution_history filters to the current cell when all_cells is False.""" + from bigframes.session import metrics + + session = mocks.create_bigquery_session() + job1 = metrics.JobMetadata( + job_id="job_1", job_type="query", query="SELECT 1", cell_execution_count=10 + ) + job2 = metrics.JobMetadata( + job_id="job_2", job_type="query", query="SELECT 2", cell_execution_count=20 + ) + session._metrics.jobs.extend([job1, job2]) + + with mock.patch( + "bigframes.core.utils.get_ipython_execution_count", return_value=20 + ): + history = session.execution_history(all_cells=False).to_dataframe() + + assert len(history) == 1 + assert history.iloc[0]["job_id"] == "job_2" From a9c84e42c5b89b75426b1c8bb081d544f3734fcc Mon Sep 17 00:00:00 2001 From: Tomo Suzuki Date: Wed, 3 Jun 2026 14:41:05 -0400 Subject: [PATCH 019/174] chore: update googleapis and regenerate (#17363) Update googleapis to the latest commit and regenerate all client libraries. --- librarian.yaml | 4 +- .../cloud/bigtable_v2/types/bigtable.py | 14 ++ .../google/cloud/container/__init__.py | 6 + .../google/cloud/container_v1/__init__.py | 6 + .../cloud/container_v1/types/__init__.py | 6 + .../container_v1/types/cluster_service.py | 143 +++++++++++++++++- .../container_v1/test_cluster_manager.py | 4 + .../services/job_controller/async_client.py | 14 +- .../services/job_controller/client.py | 14 +- .../google/cloud/dataproc_v1/types/jobs.py | 31 +++- .../gapic/dataproc_v1/test_job_controller.py | 2 + .../types/common.py | 8 + 12 files changed, 231 insertions(+), 21 deletions(-) diff --git a/librarian.yaml b/librarian.yaml index d9bbe6f20b04..723a7662c330 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -16,8 +16,8 @@ version: v0.16.0 repo: googleapis/google-cloud-python sources: googleapis: - commit: dae2a496666e372c1ebf56ceb54fe7f467a2c10e - sha256: 867490e3ce7818a2011475a888ce5d77c68cb7a13764f47d9aec8cf3038320e0 + commit: c73334a47800ba03cc65e46ade96c07f01db3446 + sha256: 07be59c8bc1dfc420e352db0528641baa23943e7dd1659acac41ca55969fb259 default: output: packages tag_format: '{name}-v{version}' diff --git a/packages/google-cloud-bigtable/google/cloud/bigtable_v2/types/bigtable.py b/packages/google-cloud-bigtable/google/cloud/bigtable_v2/types/bigtable.py index 31f8770ab061..bf63f4d1e12e 100644 --- a/packages/google-cloud-bigtable/google/cloud/bigtable_v2/types/bigtable.py +++ b/packages/google-cloud-bigtable/google/cloud/bigtable_v2/types/bigtable.py @@ -1372,6 +1372,14 @@ class ExecuteQueryRequest(proto.Message): ``PrepareQueryRequest``. Any non-empty ``Value.type`` must match the corresponding ``param_types`` entry, or be rejected with ``INVALID_ARGUMENT``. + view_parameters (MutableMapping[str, google.cloud.bigtable_v2.types.Value]): + Optional. This map provides the runtime values returned by + the VIEW_PARAMETERS() function calls, typically used for + user-level scoping of data based on identity. + + The key is the name of the view parameter e.g. ``user_id``, + and the value is the parameter value e.g. + ``alice@example.com``. """ instance_name: str = proto.Field( @@ -1406,6 +1414,12 @@ class ExecuteQueryRequest(proto.Message): number=7, message=data.Value, ) + view_parameters: MutableMapping[str, data.Value] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=12, + message=data.Value, + ) class ExecuteQueryResponse(proto.Message): diff --git a/packages/google-cloud-container/google/cloud/container/__init__.py b/packages/google-cloud-container/google/cloud/container/__init__.py index f224ab6a676a..3c217158837a 100644 --- a/packages/google-cloud-container/google/cloud/container/__init__.py +++ b/packages/google-cloud-container/google/cloud/container/__init__.py @@ -33,6 +33,7 @@ AddonsConfig, AdvancedDatapathObservabilityConfig, AdvancedMachineFeatures, + AgentSandboxConfig, AnonymousAuthenticationConfig, AuthenticatorGroupsConfig, AutoIpamConfig, @@ -66,9 +67,11 @@ CostManagementConfig, CreateClusterRequest, CreateNodePoolRequest, + CustomImageConfig, DailyMaintenanceWindow, DatabaseEncryption, DatapathProvider, + DataplaneV2Config, DefaultComputeClassConfig, DefaultSnatStatus, DeleteClusterRequest, @@ -257,6 +260,7 @@ "AddonsConfig", "AdvancedDatapathObservabilityConfig", "AdvancedMachineFeatures", + "AgentSandboxConfig", "AnonymousAuthenticationConfig", "AuthenticatorGroupsConfig", "AutoIpamConfig", @@ -290,8 +294,10 @@ "CostManagementConfig", "CreateClusterRequest", "CreateNodePoolRequest", + "CustomImageConfig", "DailyMaintenanceWindow", "DatabaseEncryption", + "DataplaneV2Config", "DefaultComputeClassConfig", "DefaultSnatStatus", "DeleteClusterRequest", diff --git a/packages/google-cloud-container/google/cloud/container_v1/__init__.py b/packages/google-cloud-container/google/cloud/container_v1/__init__.py index 4543b524b21b..b5f5f5dc023c 100644 --- a/packages/google-cloud-container/google/cloud/container_v1/__init__.py +++ b/packages/google-cloud-container/google/cloud/container_v1/__init__.py @@ -33,6 +33,7 @@ AddonsConfig, AdvancedDatapathObservabilityConfig, AdvancedMachineFeatures, + AgentSandboxConfig, AnonymousAuthenticationConfig, AuthenticatorGroupsConfig, AutoIpamConfig, @@ -66,9 +67,11 @@ CostManagementConfig, CreateClusterRequest, CreateNodePoolRequest, + CustomImageConfig, DailyMaintenanceWindow, DatabaseEncryption, DatapathProvider, + DataplaneV2Config, DefaultComputeClassConfig, DefaultSnatStatus, DeleteClusterRequest, @@ -339,6 +342,7 @@ def _get_version(dependency_name): "AddonsConfig", "AdvancedDatapathObservabilityConfig", "AdvancedMachineFeatures", + "AgentSandboxConfig", "AnonymousAuthenticationConfig", "AuthenticatorGroupsConfig", "AutoIpamConfig", @@ -373,10 +377,12 @@ def _get_version(dependency_name): "CostManagementConfig", "CreateClusterRequest", "CreateNodePoolRequest", + "CustomImageConfig", "DNSConfig", "DailyMaintenanceWindow", "DatabaseEncryption", "DatapathProvider", + "DataplaneV2Config", "DefaultComputeClassConfig", "DefaultSnatStatus", "DeleteClusterRequest", diff --git a/packages/google-cloud-container/google/cloud/container_v1/types/__init__.py b/packages/google-cloud-container/google/cloud/container_v1/types/__init__.py index 8e49125b348e..9a7244bc408c 100644 --- a/packages/google-cloud-container/google/cloud/container_v1/types/__init__.py +++ b/packages/google-cloud-container/google/cloud/container_v1/types/__init__.py @@ -22,6 +22,7 @@ AddonsConfig, AdvancedDatapathObservabilityConfig, AdvancedMachineFeatures, + AgentSandboxConfig, AnonymousAuthenticationConfig, AuthenticatorGroupsConfig, AutoIpamConfig, @@ -55,9 +56,11 @@ CostManagementConfig, CreateClusterRequest, CreateNodePoolRequest, + CustomImageConfig, DailyMaintenanceWindow, DatabaseEncryption, DatapathProvider, + DataplaneV2Config, DefaultComputeClassConfig, DefaultSnatStatus, DeleteClusterRequest, @@ -244,6 +247,7 @@ "AddonsConfig", "AdvancedDatapathObservabilityConfig", "AdvancedMachineFeatures", + "AgentSandboxConfig", "AnonymousAuthenticationConfig", "AuthenticatorGroupsConfig", "AutoIpamConfig", @@ -277,8 +281,10 @@ "CostManagementConfig", "CreateClusterRequest", "CreateNodePoolRequest", + "CustomImageConfig", "DailyMaintenanceWindow", "DatabaseEncryption", + "DataplaneV2Config", "DefaultComputeClassConfig", "DefaultSnatStatus", "DeleteClusterRequest", diff --git a/packages/google-cloud-container/google/cloud/container_v1/types/cluster_service.py b/packages/google-cloud-container/google/cloud/container_v1/types/cluster_service.py index 0ffa8e58aa62..f2c13fa6f296 100644 --- a/packages/google-cloud-container/google/cloud/container_v1/types/cluster_service.py +++ b/packages/google-cloud-container/google/cloud/container_v1/types/cluster_service.py @@ -51,6 +51,7 @@ "AdditionalNodeNetworkConfig", "AdditionalPodNetworkConfig", "ShieldedInstanceConfig", + "CustomImageConfig", "SandboxConfig", "GcfsConfig", "ReservationAffinity", @@ -81,6 +82,7 @@ "HighScaleCheckpointingConfig", "LustreCsiDriverConfig", "SlurmOperatorConfig", + "AgentSandboxConfig", "NodeReadinessConfig", "SliceControllerConfig", "RayOperatorConfig", @@ -223,6 +225,7 @@ "NodePoolLoggingConfig", "LoggingVariantConfig", "MonitoringComponentConfig", + "DataplaneV2Config", "ManagedPrometheusConfig", "AutoMonitoringConfig", "PodAutoscaling", @@ -414,7 +417,10 @@ class LinuxNodeConfig(proto.Message): net.core.netdev_max_backlog net.core.rmem_max net.core.rmem_default net.core.wmem_default net.core.wmem_max net.core.optmem_max net.core.somaxconn - net.ipv4.tcp_rmem net.ipv4.tcp_wmem net.ipv4.tcp_tw_reuse + net.ipv4.neigh.default.gc_thresh1 + net.ipv4.neigh.default.gc_thresh2 + net.ipv4.neigh.default.gc_thresh3 net.ipv4.tcp_rmem + net.ipv4.tcp_wmem net.ipv4.tcp_tw_reuse net.ipv4.tcp_mtu_probing net.ipv4.tcp_max_orphans net.ipv4.tcp_max_tw_buckets net.ipv4.tcp_syn_retries net.ipv4.tcp_ecn net.ipv4.tcp_congestion_control @@ -423,7 +429,8 @@ class LinuxNodeConfig(proto.Message): net.netfilter.nf_conntrack_tcp_timeout_close_wait net.netfilter.nf_conntrack_tcp_timeout_time_wait net.netfilter.nf_conntrack_tcp_timeout_established - net.netfilter.nf_conntrack_acct kernel.shmmni kernel.shmmax + net.netfilter.nf_conntrack_acct kernel.keys.maxkeys + kernel.keys.maxbytes kernel.shmmni kernel.shmmax kernel.shmall kernel.perf_event_paranoid kernel.sched_rt_runtime_us kernel.softlockup_panic kernel.yama.ptrace_scope kernel.kptr_restrict @@ -1726,6 +1733,10 @@ class NodeConfig(proto.Message): of it will be used. Please see https://cloud.google.com/kubernetes-engine/docs/concepts/node-images for available image types. + node_image_config (google.cloud.container_v1.types.CustomImageConfig): + The node image configuration to use for this node pool. Note + that this is only applicable for node pools using + image_type=CUSTOM. labels (MutableMapping[str, str]): The Kubernetes labels (key/value pairs) to apply to each node. The values in this field are added to the set of @@ -1986,6 +1997,11 @@ class EffectiveCgroupMode(proto.Enum): proto.STRING, number=5, ) + node_image_config: "CustomImageConfig" = proto.Field( + proto.MESSAGE, + number=90, + message="CustomImageConfig", + ) labels: MutableMapping[str, str] = proto.MapField( proto.STRING, proto.STRING, @@ -2610,6 +2626,27 @@ class ShieldedInstanceConfig(proto.Message): ) +class CustomImageConfig(proto.Message): + r"""CustomImageConfig contains the information r + + Attributes: + image (str): + The name of the image to use for this node. + image_project (str): + The project containing the image to use for + this node. + """ + + image: str = proto.Field( + proto.STRING, + number=1, + ) + image_project: str = proto.Field( + proto.STRING, + number=3, + ) + + class SandboxConfig(proto.Message): r"""SandboxConfig contains configurations of the sandbox to use for the node. @@ -3397,6 +3434,9 @@ class AddonsConfig(proto.Message): slice_controller_config (google.cloud.container_v1.types.SliceControllerConfig): Optional. Configuration for the slice controller add-on. + agent_sandbox_config (google.cloud.container_v1.types.AgentSandboxConfig): + Optional. Configuration for the AgentSandbox + addon. node_readiness_config (google.cloud.container_v1.types.NodeReadinessConfig): Optional. Configuration for NodeReadinessController add-on. @@ -3499,6 +3539,11 @@ class AddonsConfig(proto.Message): number=26, message="SliceControllerConfig", ) + agent_sandbox_config: "AgentSandboxConfig" = proto.Field( + proto.MESSAGE, + number=28, + message="AgentSandboxConfig", + ) node_readiness_config: "NodeReadinessConfig" = proto.Field( proto.MESSAGE, number=29, @@ -3916,6 +3961,21 @@ class SlurmOperatorConfig(proto.Message): ) +class AgentSandboxConfig(proto.Message): + r"""Configuration for the AgentSandbox addon. + + Attributes: + enabled (bool): + Optional. Whether AgentSandbox is enabled for + this cluster. + """ + + enabled: bool = proto.Field( + proto.BOOL, + number=1, + ) + + class NodeReadinessConfig(proto.Message): r"""Configuration for the GKE Node Readiness Controller. @@ -5857,6 +5917,14 @@ class ClusterUpdate(proto.Message): desired_image_type (str): The desired image type for the node pool. NOTE: Set the "desired_node_pool" field as well. + desired_image (str): + The desired name of the image to use for this node. This is + used to create clusters using a custom image. NOTE: Set the + "desired_node_pool" field as well. + desired_image_project (str): + The project containing the desired image to use for this + node. This is used to create clusters using a custom image. + NOTE: Set the "desired_node_pool" field as well. desired_database_encryption (google.cloud.container_v1.types.DatabaseEncryption): Configuration of etcd encryption. desired_workload_identity_config (google.cloud.container_v1.types.WorkloadIdentityConfig): @@ -6185,6 +6253,14 @@ class ClusterUpdate(proto.Message): proto.STRING, number=8, ) + desired_image: str = proto.Field( + proto.STRING, + number=44, + ) + desired_image_project: str = proto.Field( + proto.STRING, + number=45, + ) desired_database_encryption: "DatabaseEncryption" = proto.Field( proto.MESSAGE, number=46, @@ -7314,6 +7390,14 @@ class UpdateNodePoolRequest(proto.Message): The name (project, location, cluster, node pool) of the node pool to update. Specified in the format ``projects/*/locations/*/clusters/*/nodePools/*``. + image (str): + The desired name of the image name to use for + this node. This is used to create clusters using + a custom image. + image_project (str): + The project containing the desired image to + use for this node pool. This is used to create + clusters using a custom image. locations (MutableSequence[str]): The desired list of Google Compute Engine `zones `__ @@ -7478,6 +7562,14 @@ class UpdateNodePoolRequest(proto.Message): proto.STRING, number=8, ) + image: str = proto.Field( + proto.STRING, + number=10, + ) + image_project: str = proto.Field( + proto.STRING, + number=11, + ) locations: MutableSequence[str] = proto.RepeatedField( proto.STRING, number=13, @@ -11015,6 +11107,11 @@ class NetworkConfig(proto.Message): [ClusterUpdate.desired_default_enable_private_nodes][google.container.v1.ClusterUpdate.desired_default_enable_private_nodes] This field is a member of `oneof`_ ``_default_enable_private_nodes``. + dataplane_v2_config (google.cloud.container_v1.types.DataplaneV2Config): + Optional. DataplaneV2Config specifies the + DPv2 configuration. + + This field is a member of `oneof`_ ``_dataplane_v2_config``. disable_l4_lb_firewall_reconciliation (bool): Disable L4 load balancer VPC firewalls to enable firewall policies. @@ -11132,6 +11229,12 @@ class Tier(proto.Enum): number=22, optional=True, ) + dataplane_v2_config: "DataplaneV2Config" = proto.Field( + proto.MESSAGE, + number=23, + optional=True, + message="DataplaneV2Config", + ) disable_l4_lb_firewall_reconciliation: bool = proto.Field( proto.BOOL, number=24, @@ -13266,6 +13369,42 @@ class Component(proto.Enum): ) +class DataplaneV2Config(proto.Message): + r"""DataplaneV2Config is the configuration for DPv2. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + scalability_mode (google.cloud.container_v1.types.DataplaneV2Config.ScalabilityMode): + Optional. Scalability mode for the cluster. + + This field is a member of `oneof`_ ``_scalability_mode``. + """ + + class ScalabilityMode(proto.Enum): + r"""Options on how to scale the cluster. + + Values: + SCALABILITY_MODE_UNSPECIFIED (0): + Default value. + DISABLED (3): + Disables the scale optimized mode for DPv2. + SCALE_OPTIMIZED (4): + Enables the scale optimized mode for DPv2. + """ + + SCALABILITY_MODE_UNSPECIFIED = 0 + DISABLED = 3 + SCALE_OPTIMIZED = 4 + + scalability_mode: ScalabilityMode = proto.Field( + proto.ENUM, + number=1, + optional=True, + enum=ScalabilityMode, + ) + + class ManagedPrometheusConfig(proto.Message): r"""ManagedPrometheusConfig defines the configuration for Google Cloud Managed Service for Prometheus. diff --git a/packages/google-cloud-container/tests/unit/gapic/container_v1/test_cluster_manager.py b/packages/google-cloud-container/tests/unit/gapic/container_v1/test_cluster_manager.py index d0952b16b3e1..1e915cb4b626 100644 --- a/packages/google-cloud-container/tests/unit/gapic/container_v1/test_cluster_manager.py +++ b/packages/google-cloud-container/tests/unit/gapic/container_v1/test_cluster_manager.py @@ -3065,6 +3065,8 @@ def test_update_node_pool_non_empty_request_with_auto_populated_field(): node_version="node_version_value", image_type="image_type_value", name="name_value", + image="image_value", + image_project="image_project_value", etag="etag_value", machine_type="machine_type_value", disk_type="disk_type_value", @@ -3086,6 +3088,8 @@ def test_update_node_pool_non_empty_request_with_auto_populated_field(): node_version="node_version_value", image_type="image_type_value", name="name_value", + image="image_value", + image_project="image_project_value", etag="etag_value", machine_type="machine_type_value", disk_type="disk_type_value", diff --git a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/job_controller/async_client.py b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/job_controller/async_client.py index 1e369d4f7c5d..9e0cee0c39cf 100644 --- a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/job_controller/async_client.py +++ b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/job_controller/async_client.py @@ -793,17 +793,21 @@ async def sample_list_jobs(): [field = value] AND [field [= value]] ... - where **field** is ``status.state`` or ``labels.[KEY]``, - and ``[KEY]`` is a label key. **value** can be ``*`` to - match all values. ``status.state`` can be either - ``ACTIVE`` or ``NON_ACTIVE``. Only the logical ``AND`` + where **field** is ``status.state`` or ``insertTime``, + or ``labels.[KEY]``, and ``[KEY]`` is a label key. + **value** can be ``*`` to match all values. + ``status.state`` can be either ``ACTIVE`` or + ``NON_ACTIVE``. Allows ``insertTime`` to be a timestamp + in RFC 3339 format in double quotes, such as + ``2025-01-01T00:00:00Z``. Only the logical ``AND`` operator is supported; space-separated items are treated as having an implicit ``AND`` operator. Example filter: status.state = ACTIVE AND labels.env = staging AND - labels.starred = \* + labels.starred = \* AND insertTime <= + "2025-01-01T00:00:00Z" This corresponds to the ``filter`` field on the ``request`` instance; if ``request`` is provided, this diff --git a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/job_controller/client.py b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/job_controller/client.py index 12bb303f21af..aa730dfeb8c4 100644 --- a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/job_controller/client.py +++ b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/job_controller/client.py @@ -1200,17 +1200,21 @@ def sample_list_jobs(): [field = value] AND [field [= value]] ... - where **field** is ``status.state`` or ``labels.[KEY]``, - and ``[KEY]`` is a label key. **value** can be ``*`` to - match all values. ``status.state`` can be either - ``ACTIVE`` or ``NON_ACTIVE``. Only the logical ``AND`` + where **field** is ``status.state`` or ``insertTime``, + or ``labels.[KEY]``, and ``[KEY]`` is a label key. + **value** can be ``*`` to match all values. + ``status.state`` can be either ``ACTIVE`` or + ``NON_ACTIVE``. Allows ``insertTime`` to be a timestamp + in RFC 3339 format in double quotes, such as + ``2025-01-01T00:00:00Z``. Only the logical ``AND`` operator is supported; space-separated items are treated as having an implicit ``AND`` operator. Example filter: status.state = ACTIVE AND labels.env = staging AND - labels.starred = \* + labels.starred = \* AND insertTime <= + "2025-01-01T00:00:00Z" This corresponds to the ``filter`` field on the ``request`` instance; if ``request`` is provided, this diff --git a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/types/jobs.py b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/types/jobs.py index 0f59e378ae3e..f30327b0aa60 100644 --- a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/types/jobs.py +++ b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/types/jobs.py @@ -1140,6 +1140,13 @@ class YarnApplication(proto.Message): application-specific information. The URL uses the internal hostname, and requires a proxy server for resolution and, possibly, access. + vcore_seconds (int): + Optional. The cumulative CPU time consumed by + the application for a job, measured in + vcore-seconds. + memory_mb_seconds (int): + Optional. The cumulative memory usage of the + application for a job, measured in mb-seconds. """ class State(proto.Enum): @@ -1194,6 +1201,14 @@ class State(proto.Enum): proto.STRING, number=4, ) + vcore_seconds: int = proto.Field( + proto.INT64, + number=5, + ) + memory_mb_seconds: int = proto.Field( + proto.INT64, + number=6, + ) class Job(proto.Message): @@ -1622,17 +1637,19 @@ class ListJobsRequest(proto.Message): [field = value] AND [field [= value]] ... - where **field** is ``status.state`` or ``labels.[KEY]``, and - ``[KEY]`` is a label key. **value** can be ``*`` to match - all values. ``status.state`` can be either ``ACTIVE`` or - ``NON_ACTIVE``. Only the logical ``AND`` operator is - supported; space-separated items are treated as having an - implicit ``AND`` operator. + where **field** is ``status.state`` or ``insertTime``, or + ``labels.[KEY]``, and ``[KEY]`` is a label key. **value** + can be ``*`` to match all values. ``status.state`` can be + either ``ACTIVE`` or ``NON_ACTIVE``. Allows ``insertTime`` + to be a timestamp in RFC 3339 format in double quotes, such + as ``2025-01-01T00:00:00Z``. Only the logical ``AND`` + operator is supported; space-separated items are treated as + having an implicit ``AND`` operator. Example filter: status.state = ACTIVE AND labels.env = staging AND - labels.starred = \* + labels.starred = \* AND insertTime <= "2025-01-01T00:00:00Z". """ class JobStateMatcher(proto.Enum): diff --git a/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_job_controller.py b/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_job_controller.py index b799a1db0efe..967afafabb48 100644 --- a/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_job_controller.py +++ b/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_job_controller.py @@ -6451,6 +6451,8 @@ def test_update_job_rest_call_success(request_type): "state": 1, "progress": 0.885, "tracking_url": "tracking_url_value", + "vcore_seconds": 1389, + "memory_mb_seconds": 1813, } ], "driver_output_resource_uri": "driver_output_resource_uri_value", diff --git a/packages/google-cloud-saasplatform-saasservicemgmt/google/cloud/saasplatform_saasservicemgmt_v1beta1/types/common.py b/packages/google-cloud-saasplatform-saasservicemgmt/google/cloud/saasplatform_saasservicemgmt_v1beta1/types/common.py index 95ae157c6029..b9f230f9c1fb 100644 --- a/packages/google-cloud-saasplatform-saasservicemgmt/google/cloud/saasplatform_saasservicemgmt_v1beta1/types/common.py +++ b/packages/google-cloud-saasplatform-saasservicemgmt/google/cloud/saasplatform_saasservicemgmt_v1beta1/types/common.py @@ -210,6 +210,12 @@ class Type(proto.Enum): Condition type is operationError. True when the last unit operation fails with a non-ignorable error. + TYPE_APP_CREATED_OR_ALREADY_EXISTS (5): + Indicates if AppHub app has been created or + if Apphub app has already existed. + TYPE_APP_COMPONENTS_REGISTERED (6): + Indicates if services and workloads have been + registered with AppHub. """ TYPE_UNSPECIFIED = 0 @@ -217,6 +223,8 @@ class Type(proto.Enum): TYPE_UPDATING = 2 TYPE_PROVISIONED = 3 TYPE_OPERATION_ERROR = 4 + TYPE_APP_CREATED_OR_ALREADY_EXISTS = 5 + TYPE_APP_COMPONENTS_REGISTERED = 6 status: Status = proto.Field( proto.ENUM, From f9ff3b1baf56980210a7770e54e50711754f1d2d Mon Sep 17 00:00:00 2001 From: Tomo Suzuki Date: Wed, 3 Jun 2026 15:20:11 -0400 Subject: [PATCH 020/174] feat(google-devicesandservices-health): add google-devicesandservices-health (#17365) I manually added the namespaces in librarian.yaml; ``` python: allowed_namespaces: - google.ads - google.apps - google.cloud - google.maps - google.shopping - google.devicesandservices ``` I ran: ``` ~/librarian-2026/google-cloud-python$ go run github.com/googleapis/librarian/cmd/librarian@${V} add google/devicesandservices/health/v4 ~/librarian-2026/google-cloud-python$ docker run -u $(id -u):$(id -g) -v .:/repo -v ~/.cache:/.cache -w /repo docker.io/library/librarian-python:${V} generate -v google-devicesandservices-health ``` --- .librarian/state.yaml | 16 + librarian.yaml | 14 + .../.coveragerc | 13 + .../google-devicesandservices-health/.flake8 | 34 + .../.repo-metadata.json | 16 + .../CHANGELOG.md | 5 + .../google-devicesandservices-health/LICENSE | 202 + .../MANIFEST.in | 20 + .../README.rst | 199 + .../docs/CHANGELOG.md | 1 + .../docs/README.rst | 199 + .../docs/_static/custom.css | 20 + .../docs/_templates/layout.html | 50 + .../docs/conf.py | 417 + .../docs/health_v4/data_points_service.rst | 10 + .../health_v4/data_subscription_service.rst | 10 + .../docs/health_v4/health_profile_service.rst | 10 + .../docs/health_v4/services_.rst | 8 + .../docs/health_v4/types_.rst | 6 + .../docs/index.rst | 23 + .../docs/multiprocessing.rst | 7 + .../devicesandservices/health/__init__.py | 337 + .../health/gapic_version.py | 16 + .../google/devicesandservices/health/py.typed | 2 + .../devicesandservices/health_v4/__init__.py | 415 + .../health_v4/gapic_metadata.json | 441 + .../health_v4/gapic_version.py | 16 + .../devicesandservices/health_v4/py.typed | 2 + .../health_v4/services/__init__.py | 15 + .../services/data_points_service/__init__.py | 22 + .../data_points_service/async_client.py | 1373 +++ .../services/data_points_service/client.py | 1808 +++ .../services/data_points_service/pagers.py | 509 + .../data_points_service/transports/README.rst | 10 + .../transports/__init__.py | 36 + .../data_points_service/transports/base.py | 376 + .../data_points_service/transports/grpc.py | 622 + .../transports/grpc_asyncio.py | 757 ++ .../data_points_service/transports/rest.py | 2183 ++++ .../transports/rest_base.py | 565 + .../data_subscription_service/__init__.py | 22 + .../data_subscription_service/async_client.py | 1496 +++ .../data_subscription_service/client.py | 1946 +++ .../data_subscription_service/pagers.py | 361 + .../transports/README.rst | 10 + .../transports/__init__.py | 39 + .../transports/base.py | 328 + .../transports/grpc.py | 645 + .../transports/grpc_asyncio.py | 743 ++ .../transports/rest.py | 1920 +++ .../transports/rest_base.py | 509 + .../health_profile_service/__init__.py | 22 + .../health_profile_service/async_client.py | 1270 ++ .../services/health_profile_service/client.py | 1730 +++ .../services/health_profile_service/pagers.py | 197 + .../transports/README.rst | 10 + .../transports/__init__.py | 36 + .../health_profile_service/transports/base.py | 338 + .../health_profile_service/transports/grpc.py | 552 + .../transports/grpc_asyncio.py | 678 ++ .../health_profile_service/transports/rest.py | 1891 +++ .../transports/rest_base.py | 487 + .../health_v4/types/__init__.py | 310 + .../health_v4/types/data_coordinates.py | 240 + .../health_v4/types/data_model.py | 4564 +++++++ .../health_v4/types/data_points.py | 2278 ++++ .../health_v4/types/data_source.py | 256 + .../types/data_subscription_service.py | 692 ++ .../health_v4/types/health_profile.py | 977 ++ .../health_v4/types/medical_device_info.py | 74 + .../types/webhook_notification_cloud_log.py | 50 + .../google-devicesandservices-health/mypy.ini | 15 + .../noxfile.py | 639 + ..._service_batch_delete_data_points_async.py | 57 + ...s_service_batch_delete_data_points_sync.py | 57 + ..._points_service_create_data_point_async.py | 57 + ...a_points_service_create_data_point_sync.py | 57 + ...service_daily_roll_up_data_points_async.py | 53 + ..._service_daily_roll_up_data_points_sync.py | 53 + ...oints_service_export_exercise_tcx_async.py | 53 + ...points_service_export_exercise_tcx_sync.py | 53 + ...ata_points_service_get_data_point_async.py | 53 + ...data_points_service_get_data_point_sync.py | 53 + ...a_points_service_list_data_points_async.py | 54 + ...ta_points_service_list_data_points_sync.py | 54 + ...nts_service_reconcile_data_points_async.py | 54 + ...ints_service_reconcile_data_points_sync.py | 54 + ...oints_service_roll_up_data_points_async.py | 54 + ...points_service_roll_up_data_points_sync.py | 54 + ..._points_service_update_data_point_async.py | 55 + ...a_points_service_update_data_point_sync.py | 55 + ...ription_service_create_subscriber_async.py | 62 + ...cription_service_create_subscriber_sync.py | 62 + ...ption_service_create_subscription_async.py | 57 + ...iption_service_create_subscription_sync.py | 57 + ...ription_service_delete_subscriber_async.py | 57 + ...cription_service_delete_subscriber_sync.py | 57 + ...ption_service_delete_subscription_async.py | 50 + ...iption_service_delete_subscription_sync.py | 50 + ...cription_service_list_subscribers_async.py | 54 + ...scription_service_list_subscribers_sync.py | 54 + ...iption_service_list_subscriptions_async.py | 54 + ...ription_service_list_subscriptions_sync.py | 54 + ...ription_service_update_subscriber_async.py | 61 + ...cription_service_update_subscriber_sync.py | 61 + ...ption_service_update_subscription_async.py | 51 + ...iption_service_update_subscription_sync.py | 51 + ...alth_profile_service_get_identity_async.py | 53 + ...ealth_profile_service_get_identity_sync.py | 53 + ...h_profile_service_get_irn_profile_async.py | 53 + ...th_profile_service_get_irn_profile_sync.py | 53 + ...profile_service_get_paired_device_async.py | 53 + ..._profile_service_get_paired_device_sync.py | 53 + ...ealth_profile_service_get_profile_async.py | 53 + ...health_profile_service_get_profile_sync.py | 53 + ...alth_profile_service_get_settings_async.py | 53 + ...ealth_profile_service_get_settings_sync.py | 53 + ...ofile_service_list_paired_devices_async.py | 54 + ...rofile_service_list_paired_devices_sync.py | 54 + ...th_profile_service_update_profile_async.py | 51 + ...lth_profile_service_update_profile_sync.py | 51 + ...h_profile_service_update_settings_async.py | 51 + ...th_profile_service_update_settings_sync.py | 51 + ...a_google.devicesandservices.health.v4.json | 4074 +++++++ .../google-devicesandservices-health/setup.py | 99 + .../testing/constraints-3.10.txt | 11 + .../testing/constraints-3.11.txt | 10 + .../testing/constraints-3.12.txt | 10 + .../testing/constraints-3.13.txt | 12 + .../testing/constraints-3.14.txt | 12 + .../tests/__init__.py | 15 + .../tests/unit/__init__.py | 15 + .../tests/unit/gapic/__init__.py | 15 + .../tests/unit/gapic/health_v4/__init__.py | 15 + .../health_v4/test_data_points_service.py | 10005 ++++++++++++++++ .../test_data_subscription_service.py | 9154 ++++++++++++++ .../health_v4/test_health_profile_service.py | 8818 ++++++++++++++ 137 files changed, 71089 insertions(+) create mode 100644 packages/google-devicesandservices-health/.coveragerc create mode 100644 packages/google-devicesandservices-health/.flake8 create mode 100644 packages/google-devicesandservices-health/.repo-metadata.json create mode 100644 packages/google-devicesandservices-health/CHANGELOG.md create mode 100644 packages/google-devicesandservices-health/LICENSE create mode 100644 packages/google-devicesandservices-health/MANIFEST.in create mode 100644 packages/google-devicesandservices-health/README.rst create mode 120000 packages/google-devicesandservices-health/docs/CHANGELOG.md create mode 100644 packages/google-devicesandservices-health/docs/README.rst create mode 100644 packages/google-devicesandservices-health/docs/_static/custom.css create mode 100644 packages/google-devicesandservices-health/docs/_templates/layout.html create mode 100644 packages/google-devicesandservices-health/docs/conf.py create mode 100644 packages/google-devicesandservices-health/docs/health_v4/data_points_service.rst create mode 100644 packages/google-devicesandservices-health/docs/health_v4/data_subscription_service.rst create mode 100644 packages/google-devicesandservices-health/docs/health_v4/health_profile_service.rst create mode 100644 packages/google-devicesandservices-health/docs/health_v4/services_.rst create mode 100644 packages/google-devicesandservices-health/docs/health_v4/types_.rst create mode 100644 packages/google-devicesandservices-health/docs/index.rst create mode 100644 packages/google-devicesandservices-health/docs/multiprocessing.rst create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health/__init__.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health/gapic_version.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health/py.typed create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/__init__.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/gapic_metadata.json create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/gapic_version.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/py.typed create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/__init__.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/__init__.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/async_client.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/client.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/pagers.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/transports/README.rst create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/transports/__init__.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/transports/base.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/transports/grpc.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/transports/grpc_asyncio.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/transports/rest.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/transports/rest_base.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/__init__.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/async_client.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/client.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/pagers.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/transports/README.rst create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/transports/__init__.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/transports/base.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/transports/grpc.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/transports/grpc_asyncio.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/transports/rest.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/transports/rest_base.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/__init__.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/async_client.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/client.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/pagers.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/transports/README.rst create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/transports/__init__.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/transports/base.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/transports/grpc.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/transports/grpc_asyncio.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/transports/rest.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/transports/rest_base.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/__init__.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/data_coordinates.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/data_model.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/data_points.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/data_source.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/data_subscription_service.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/health_profile.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/medical_device_info.py create mode 100644 packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/webhook_notification_cloud_log.py create mode 100644 packages/google-devicesandservices-health/mypy.ini create mode 100644 packages/google-devicesandservices-health/noxfile.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_batch_delete_data_points_async.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_batch_delete_data_points_sync.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_create_data_point_async.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_create_data_point_sync.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_daily_roll_up_data_points_async.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_daily_roll_up_data_points_sync.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_export_exercise_tcx_async.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_export_exercise_tcx_sync.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_get_data_point_async.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_get_data_point_sync.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_list_data_points_async.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_list_data_points_sync.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_reconcile_data_points_async.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_reconcile_data_points_sync.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_roll_up_data_points_async.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_roll_up_data_points_sync.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_update_data_point_async.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_update_data_point_sync.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_create_subscriber_async.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_create_subscriber_sync.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_create_subscription_async.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_create_subscription_sync.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_delete_subscriber_async.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_delete_subscriber_sync.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_delete_subscription_async.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_delete_subscription_sync.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_list_subscribers_async.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_list_subscribers_sync.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_list_subscriptions_async.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_list_subscriptions_sync.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_update_subscriber_async.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_update_subscriber_sync.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_update_subscription_async.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_update_subscription_sync.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_identity_async.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_identity_sync.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_irn_profile_async.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_irn_profile_sync.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_paired_device_async.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_paired_device_sync.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_profile_async.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_profile_sync.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_settings_async.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_settings_sync.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_list_paired_devices_async.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_list_paired_devices_sync.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_update_profile_async.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_update_profile_sync.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_update_settings_async.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_update_settings_sync.py create mode 100644 packages/google-devicesandservices-health/samples/generated_samples/snippet_metadata_google.devicesandservices.health.v4.json create mode 100644 packages/google-devicesandservices-health/setup.py create mode 100644 packages/google-devicesandservices-health/testing/constraints-3.10.txt create mode 100644 packages/google-devicesandservices-health/testing/constraints-3.11.txt create mode 100644 packages/google-devicesandservices-health/testing/constraints-3.12.txt create mode 100644 packages/google-devicesandservices-health/testing/constraints-3.13.txt create mode 100644 packages/google-devicesandservices-health/testing/constraints-3.14.txt create mode 100644 packages/google-devicesandservices-health/tests/__init__.py create mode 100644 packages/google-devicesandservices-health/tests/unit/__init__.py create mode 100644 packages/google-devicesandservices-health/tests/unit/gapic/__init__.py create mode 100644 packages/google-devicesandservices-health/tests/unit/gapic/health_v4/__init__.py create mode 100644 packages/google-devicesandservices-health/tests/unit/gapic/health_v4/test_data_points_service.py create mode 100644 packages/google-devicesandservices-health/tests/unit/gapic/health_v4/test_data_subscription_service.py create mode 100644 packages/google-devicesandservices-health/tests/unit/gapic/health_v4/test_health_profile_service.py diff --git a/.librarian/state.yaml b/.librarian/state.yaml index fcc0c6bea8fd..3f9c5d638041 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -5386,6 +5386,22 @@ libraries: - packages/google-crc32c/README.rst - packages/google-crc32c/docs/ tag_format: '{id}-v{version}' + - id: google-devicesandservices-health + version: 0.0.0 + last_generated_commit: "" + apis: + - path: google/devicesandservices/health/v4 + source_roots: + - packages/google-devicesandservices-health + preserve_regex: [] + remove_regex: [] + release_exclude_paths: + - packages/google-devicesandservices-health/.repo-metadata.json + - packages/google-devicesandservices-health/noxfile.py + - packages/google-devicesandservices-health/tests/ + - packages/google-devicesandservices-health/README.rst + - packages/google-devicesandservices-health/docs/ + tag_format: '{id}-v{version}' - id: google-geo-type version: 0.7.0 last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd diff --git a/librarian.yaml b/librarian.yaml index 723a7662c330..ceb33c5f2b6e 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -22,6 +22,13 @@ default: output: packages tag_format: '{name}-v{version}' python: + allowed_namespaces: + - google.ads + - google.apps + - google.cloud + - google.maps + - google.shopping + - google.devicesandservices common_gapic_paths: - samples/generated_samples - tests/unit/gapic @@ -2197,6 +2204,13 @@ libraries: skip_release: true python: library_type: OTHER + - name: google-devicesandservices-health + version: 0.0.0 + apis: + - path: google/devicesandservices/health/v4 + copyright_year: "2026" + python: + default_version: v4 - name: google-geo-type version: 0.7.0 apis: diff --git a/packages/google-devicesandservices-health/.coveragerc b/packages/google-devicesandservices-health/.coveragerc new file mode 100644 index 000000000000..7136de07ff66 --- /dev/null +++ b/packages/google-devicesandservices-health/.coveragerc @@ -0,0 +1,13 @@ +[run] +branch = True + +[report] +show_missing = True +omit = + google/devicesandservices/health/__init__.py + google/devicesandservices/health/gapic_version.py +exclude_lines = + # Re-enable the standard pragma + pragma: NO COVER + # Ignore debug-only repr + def __repr__ diff --git a/packages/google-devicesandservices-health/.flake8 b/packages/google-devicesandservices-health/.flake8 new file mode 100644 index 000000000000..f9069a84687b --- /dev/null +++ b/packages/google-devicesandservices-health/.flake8 @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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. +# +[flake8] +# TODO(https://github.com/googleapis/gapic-generator-python/issues/2333): +# Resolve flake8 lint issues +ignore = E203, E231, E266, E501, W503 +exclude = + # TODO(https://github.com/googleapis/gapic-generator-python/issues/2333): + # Ensure that generated code passes flake8 lint + **/gapic/** + **/services/** + **/types/** + # Exclude Protobuf gencode + *_pb2.py + + # Standard linting exemptions. + **/.nox/** + __pycache__, + .git, + *.pyc, + conf.py diff --git a/packages/google-devicesandservices-health/.repo-metadata.json b/packages/google-devicesandservices-health/.repo-metadata.json new file mode 100644 index 000000000000..5a0c891d7012 --- /dev/null +++ b/packages/google-devicesandservices-health/.repo-metadata.json @@ -0,0 +1,16 @@ +{ + "api_description": "The Google Health API lets you view and manage health and fitness metrics\nand measurement data.", + "api_id": "health.googleapis.com", + "api_shortname": "health", + "client_documentation": "https://googleapis.dev/python/google-devicesandservices-health/latest", + "default_version": "v4", + "distribution_name": "google-devicesandservices-health", + "issue_tracker": "https://issuetracker.google.com/issues/new?component=1914241", + "language": "python", + "library_type": "GAPIC_AUTO", + "name": "google-devicesandservices-health", + "name_pretty": "Google Health", + "product_documentation": "https://developers.google.com/health/api", + "release_level": "preview", + "repo": "googleapis/google-cloud-python" +} \ No newline at end of file diff --git a/packages/google-devicesandservices-health/CHANGELOG.md b/packages/google-devicesandservices-health/CHANGELOG.md new file mode 100644 index 000000000000..34808bf0463d --- /dev/null +++ b/packages/google-devicesandservices-health/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +[PyPI History][1] + +[1]: https://pypi.org/project/google-devicesandservices-health/#history diff --git a/packages/google-devicesandservices-health/LICENSE b/packages/google-devicesandservices-health/LICENSE new file mode 100644 index 000000000000..d64569567334 --- /dev/null +++ b/packages/google-devicesandservices-health/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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/packages/google-devicesandservices-health/MANIFEST.in b/packages/google-devicesandservices-health/MANIFEST.in new file mode 100644 index 000000000000..f932577add9d --- /dev/null +++ b/packages/google-devicesandservices-health/MANIFEST.in @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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. +# +include README.rst LICENSE +recursive-include google *.py *.pyi *.json *.proto py.typed +recursive-include tests * +global-exclude *.py[co] +global-exclude __pycache__ diff --git a/packages/google-devicesandservices-health/README.rst b/packages/google-devicesandservices-health/README.rst new file mode 100644 index 000000000000..e83fa4b21a4d --- /dev/null +++ b/packages/google-devicesandservices-health/README.rst @@ -0,0 +1,199 @@ +Python Client for Google Health +=============================== + +|preview| |pypi| |versions| + +`Google Health`_: The Google Health API lets you view and manage health and fitness metrics +and measurement data. + +- `Client Library Documentation`_ +- `Product Documentation`_ + +.. |preview| image:: https://img.shields.io/badge/support-preview-orange.svg + :target: https://github.com/googleapis/google-cloud-python/blob/main/README.rst#stability-levels +.. |pypi| image:: https://img.shields.io/pypi/v/google-devicesandservices-health.svg + :target: https://pypi.org/project/google-devicesandservices-health/ +.. |versions| image:: https://img.shields.io/pypi/pyversions/google-devicesandservices-health.svg + :target: https://pypi.org/project/google-devicesandservices-health/ +.. _Google Health: https://developers.google.com/health/api +.. _Client Library Documentation: https://googleapis.dev/python/google-devicesandservices-health/latest +.. _Product Documentation: https://developers.google.com/health/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 Health.`_ +4. `Set up 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 +.. _Enable the Google Health.: https://developers.google.com/health/api +.. _Set up Authentication.: https://googleapis.dev/python/google-api-core/latest/auth.html + +Installation +~~~~~~~~~~~~ + +Install this library in a virtual environment using `venv`_. `venv`_ is a tool that +creates isolated Python environments. These isolated environments can have separate +versions of Python packages, which allows you to isolate one project's dependencies +from the dependencies of other projects. + +With `venv`_, it's possible to install this library without needing system +install permissions, and without clashing with the installed system +dependencies. + +.. _`venv`: https://docs.python.org/3/library/venv.html + + +Code samples and snippets +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Code samples and snippets live in the `samples/`_ folder. + +.. _samples/: https://github.com/googleapis/google-cloud-python/tree/main/packages/google-devicesandservices-health/samples + + +Supported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^ +Our client libraries are compatible with all current `active`_ and `maintenance`_ versions of +Python. + +Python >= 3.10, including 3.14 + +.. _active: https://devguide.python.org/devcycle/#in-development-main-branch +.. _maintenance: https://devguide.python.org/devcycle/#maintenance-branches + +Unsupported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Python <= 3.9 + + +If you are using an `end-of-life`_ +version of Python, we recommend that you update as soon as possible to an actively supported version. + +.. _end-of-life: https://devguide.python.org/devcycle/#end-of-life-branches + +Mac/Linux +^^^^^^^^^ + +.. code-block:: console + + python3 -m venv + source /bin/activate + pip install google-devicesandservices-health + + +Windows +^^^^^^^ + +.. code-block:: console + + py -m venv + .\\Scripts\activate + pip install google-devicesandservices-health + +Next Steps +~~~~~~~~~~ + +- Read the `Client Library Documentation`_ for Google Health + to see other available methods on the client. +- Read the `Google Health Product documentation`_ to learn + more about the product and see How-to Guides. +- View this `README`_ to see the full list of Cloud + APIs that we cover. + +.. _Google Health Product documentation: https://developers.google.com/health/api +.. _README: https://github.com/googleapis/google-cloud-python/blob/main/README.rst + +Logging +------- + +This library uses the standard Python :code:`logging` functionality to log some RPC events that could be of interest for debugging and monitoring purposes. +Note the following: + +#. Logs may contain sensitive information. Take care to **restrict access to the logs** if they are saved, whether it be on local storage or on Google Cloud Logging. +#. Google may refine the occurrence, level, and content of various log messages in this library without flagging such changes as breaking. **Do not depend on immutability of the logging events**. +#. By default, the logging events from this library are not handled. You must **explicitly configure log handling** using one of the mechanisms below. + +Simple, environment-based configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To enable logging for this library without any changes in your code, set the :code:`GOOGLE_SDK_PYTHON_LOGGING_SCOPE` environment variable to a valid Google +logging scope. This configures handling of logging events (at level :code:`logging.DEBUG` or higher) from this library in a default manner, emitting the logged +messages in a structured format. It does not currently allow customizing the logging levels captured nor the handlers, formatters, etc. used for any logging +event. + +A logging scope is a period-separated namespace that begins with :code:`google`, identifying the Python module or package to log. + +- Valid logging scopes: :code:`google`, :code:`google.cloud.asset.v1`, :code:`google.api`, :code:`google.auth`, etc. +- Invalid logging scopes: :code:`foo`, :code:`123`, etc. + +**NOTE**: If the logging scope is invalid, the library does not set up any logging handlers. + +Environment-Based Examples +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Enabling the default handler for all Google-based loggers + +.. code-block:: console + + export GOOGLE_SDK_PYTHON_LOGGING_SCOPE=google + +- Enabling the default handler for a specific Google module (for a client library called :code:`library_v1`): + +.. code-block:: console + + export GOOGLE_SDK_PYTHON_LOGGING_SCOPE=google.cloud.library_v1 + + +Advanced, code-based configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can also configure a valid logging scope using Python's standard `logging` mechanism. + +Code-Based Examples +^^^^^^^^^^^^^^^^^^^ + +- Configuring a handler for all Google-based loggers + +.. code-block:: python + + import logging + + from google.cloud import library_v1 + + base_logger = logging.getLogger("google") + base_logger.addHandler(logging.StreamHandler()) + base_logger.setLevel(logging.DEBUG) + +- Configuring a handler for a specific Google module (for a client library called :code:`library_v1`): + +.. code-block:: python + + import logging + + from google.cloud import library_v1 + + base_logger = logging.getLogger("google.cloud.library_v1") + base_logger.addHandler(logging.StreamHandler()) + base_logger.setLevel(logging.DEBUG) + +Logging details +~~~~~~~~~~~~~~~ + +#. Regardless of which of the mechanisms above you use to configure logging for this library, by default logging events are not propagated up to the root + logger from the `google`-level logger. If you need the events to be propagated to the root logger, you must explicitly set + :code:`logging.getLogger("google").propagate = True` in your code. +#. You can mix the different logging configurations above for different Google modules. For example, you may want use a code-based logging configuration for + one library, but decide you need to also set up environment-based logging configuration for another library. + + #. If you attempt to use both code-based and environment-based configuration for the same module, the environment-based configuration will be ineffectual + if the code -based configuration gets applied first. + +#. The Google-specific logging configurations (default handlers for environment-based configuration; not propagating logging events to the root logger) get + executed the first time *any* client library is instantiated in your application, and only if the affected loggers have not been previously configured. + (This is the reason for 2.i. above.) diff --git a/packages/google-devicesandservices-health/docs/CHANGELOG.md b/packages/google-devicesandservices-health/docs/CHANGELOG.md new file mode 120000 index 000000000000..04c99a55caae --- /dev/null +++ b/packages/google-devicesandservices-health/docs/CHANGELOG.md @@ -0,0 +1 @@ +../CHANGELOG.md \ No newline at end of file diff --git a/packages/google-devicesandservices-health/docs/README.rst b/packages/google-devicesandservices-health/docs/README.rst new file mode 100644 index 000000000000..e83fa4b21a4d --- /dev/null +++ b/packages/google-devicesandservices-health/docs/README.rst @@ -0,0 +1,199 @@ +Python Client for Google Health +=============================== + +|preview| |pypi| |versions| + +`Google Health`_: The Google Health API lets you view and manage health and fitness metrics +and measurement data. + +- `Client Library Documentation`_ +- `Product Documentation`_ + +.. |preview| image:: https://img.shields.io/badge/support-preview-orange.svg + :target: https://github.com/googleapis/google-cloud-python/blob/main/README.rst#stability-levels +.. |pypi| image:: https://img.shields.io/pypi/v/google-devicesandservices-health.svg + :target: https://pypi.org/project/google-devicesandservices-health/ +.. |versions| image:: https://img.shields.io/pypi/pyversions/google-devicesandservices-health.svg + :target: https://pypi.org/project/google-devicesandservices-health/ +.. _Google Health: https://developers.google.com/health/api +.. _Client Library Documentation: https://googleapis.dev/python/google-devicesandservices-health/latest +.. _Product Documentation: https://developers.google.com/health/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 Health.`_ +4. `Set up 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 +.. _Enable the Google Health.: https://developers.google.com/health/api +.. _Set up Authentication.: https://googleapis.dev/python/google-api-core/latest/auth.html + +Installation +~~~~~~~~~~~~ + +Install this library in a virtual environment using `venv`_. `venv`_ is a tool that +creates isolated Python environments. These isolated environments can have separate +versions of Python packages, which allows you to isolate one project's dependencies +from the dependencies of other projects. + +With `venv`_, it's possible to install this library without needing system +install permissions, and without clashing with the installed system +dependencies. + +.. _`venv`: https://docs.python.org/3/library/venv.html + + +Code samples and snippets +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Code samples and snippets live in the `samples/`_ folder. + +.. _samples/: https://github.com/googleapis/google-cloud-python/tree/main/packages/google-devicesandservices-health/samples + + +Supported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^ +Our client libraries are compatible with all current `active`_ and `maintenance`_ versions of +Python. + +Python >= 3.10, including 3.14 + +.. _active: https://devguide.python.org/devcycle/#in-development-main-branch +.. _maintenance: https://devguide.python.org/devcycle/#maintenance-branches + +Unsupported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Python <= 3.9 + + +If you are using an `end-of-life`_ +version of Python, we recommend that you update as soon as possible to an actively supported version. + +.. _end-of-life: https://devguide.python.org/devcycle/#end-of-life-branches + +Mac/Linux +^^^^^^^^^ + +.. code-block:: console + + python3 -m venv + source /bin/activate + pip install google-devicesandservices-health + + +Windows +^^^^^^^ + +.. code-block:: console + + py -m venv + .\\Scripts\activate + pip install google-devicesandservices-health + +Next Steps +~~~~~~~~~~ + +- Read the `Client Library Documentation`_ for Google Health + to see other available methods on the client. +- Read the `Google Health Product documentation`_ to learn + more about the product and see How-to Guides. +- View this `README`_ to see the full list of Cloud + APIs that we cover. + +.. _Google Health Product documentation: https://developers.google.com/health/api +.. _README: https://github.com/googleapis/google-cloud-python/blob/main/README.rst + +Logging +------- + +This library uses the standard Python :code:`logging` functionality to log some RPC events that could be of interest for debugging and monitoring purposes. +Note the following: + +#. Logs may contain sensitive information. Take care to **restrict access to the logs** if they are saved, whether it be on local storage or on Google Cloud Logging. +#. Google may refine the occurrence, level, and content of various log messages in this library without flagging such changes as breaking. **Do not depend on immutability of the logging events**. +#. By default, the logging events from this library are not handled. You must **explicitly configure log handling** using one of the mechanisms below. + +Simple, environment-based configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To enable logging for this library without any changes in your code, set the :code:`GOOGLE_SDK_PYTHON_LOGGING_SCOPE` environment variable to a valid Google +logging scope. This configures handling of logging events (at level :code:`logging.DEBUG` or higher) from this library in a default manner, emitting the logged +messages in a structured format. It does not currently allow customizing the logging levels captured nor the handlers, formatters, etc. used for any logging +event. + +A logging scope is a period-separated namespace that begins with :code:`google`, identifying the Python module or package to log. + +- Valid logging scopes: :code:`google`, :code:`google.cloud.asset.v1`, :code:`google.api`, :code:`google.auth`, etc. +- Invalid logging scopes: :code:`foo`, :code:`123`, etc. + +**NOTE**: If the logging scope is invalid, the library does not set up any logging handlers. + +Environment-Based Examples +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Enabling the default handler for all Google-based loggers + +.. code-block:: console + + export GOOGLE_SDK_PYTHON_LOGGING_SCOPE=google + +- Enabling the default handler for a specific Google module (for a client library called :code:`library_v1`): + +.. code-block:: console + + export GOOGLE_SDK_PYTHON_LOGGING_SCOPE=google.cloud.library_v1 + + +Advanced, code-based configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can also configure a valid logging scope using Python's standard `logging` mechanism. + +Code-Based Examples +^^^^^^^^^^^^^^^^^^^ + +- Configuring a handler for all Google-based loggers + +.. code-block:: python + + import logging + + from google.cloud import library_v1 + + base_logger = logging.getLogger("google") + base_logger.addHandler(logging.StreamHandler()) + base_logger.setLevel(logging.DEBUG) + +- Configuring a handler for a specific Google module (for a client library called :code:`library_v1`): + +.. code-block:: python + + import logging + + from google.cloud import library_v1 + + base_logger = logging.getLogger("google.cloud.library_v1") + base_logger.addHandler(logging.StreamHandler()) + base_logger.setLevel(logging.DEBUG) + +Logging details +~~~~~~~~~~~~~~~ + +#. Regardless of which of the mechanisms above you use to configure logging for this library, by default logging events are not propagated up to the root + logger from the `google`-level logger. If you need the events to be propagated to the root logger, you must explicitly set + :code:`logging.getLogger("google").propagate = True` in your code. +#. You can mix the different logging configurations above for different Google modules. For example, you may want use a code-based logging configuration for + one library, but decide you need to also set up environment-based logging configuration for another library. + + #. If you attempt to use both code-based and environment-based configuration for the same module, the environment-based configuration will be ineffectual + if the code -based configuration gets applied first. + +#. The Google-specific logging configurations (default handlers for environment-based configuration; not propagating logging events to the root logger) get + executed the first time *any* client library is instantiated in your application, and only if the affected loggers have not been previously configured. + (This is the reason for 2.i. above.) diff --git a/packages/google-devicesandservices-health/docs/_static/custom.css b/packages/google-devicesandservices-health/docs/_static/custom.css new file mode 100644 index 000000000000..b0a295464b23 --- /dev/null +++ b/packages/google-devicesandservices-health/docs/_static/custom.css @@ -0,0 +1,20 @@ +div#python2-eol { + border-color: red; + border-width: medium; +} + +/* Ensure minimum width for 'Parameters' / 'Returns' column */ +dl.field-list > dt { + min-width: 100px +} + +/* Insert space between methods for readability */ +dl.method { + padding-top: 10px; + padding-bottom: 10px +} + +/* Insert empty space between classes */ +dl.class { + padding-bottom: 50px +} diff --git a/packages/google-devicesandservices-health/docs/_templates/layout.html b/packages/google-devicesandservices-health/docs/_templates/layout.html new file mode 100644 index 000000000000..95e9c77fcfe1 --- /dev/null +++ b/packages/google-devicesandservices-health/docs/_templates/layout.html @@ -0,0 +1,50 @@ + +{% extends "!layout.html" %} +{%- block content %} +{%- if theme_fixed_sidebar|lower == 'true' %} +
+ {{ sidebar() }} + {%- block document %} +
+ {%- if render_sidebar %} +
+ {%- endif %} + + {%- block relbar_top %} + {%- if theme_show_relbar_top|tobool %} + + {%- endif %} + {% endblock %} + +
+
+ As of January 1, 2020 this library no longer supports Python 2 on the latest released version. + Library versions released prior to that date will continue to be available. For more information please + visit Python 2 support on Google Cloud. +
+ {% block body %} {% endblock %} +
+ + {%- block relbar_bottom %} + {%- if theme_show_relbar_bottom|tobool %} + + {%- endif %} + {% endblock %} + + {%- if render_sidebar %} +
+ {%- endif %} +
+ {%- endblock %} +
+
+{%- else %} +{{ super() }} +{%- endif %} +{%- endblock %} diff --git a/packages/google-devicesandservices-health/docs/conf.py b/packages/google-devicesandservices-health/docs/conf.py new file mode 100644 index 000000000000..582def549e94 --- /dev/null +++ b/packages/google-devicesandservices-health/docs/conf.py @@ -0,0 +1,417 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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-devicesandservices-health 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 logging +import os +import shlex +import sys +from typing import Any + +# 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("..")) + +# For plugins that can not read conf.py. +# See also: https://github.com/docascode/sphinx-docfx-yaml/issues/85 +sys.path.insert(0, os.path.abspath(".")) + +__version__ = "" + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +needs_sphinx = "4.5.0" + +# 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.doctest", + "sphinx.ext.napoleon", + "sphinx.ext.todo", + "sphinx.ext.viewcode", + "recommonmark", +] + +# autodoc/autosummary flags +autoclass_content = "both" +autodoc_default_options = {"members": True} +autosummary_generate = True + + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# source_suffix = ['.rst', '.md'] +source_suffix = [".rst", ".md"] + +# The encoding of source files. +# source_encoding = 'utf-8-sig' + +# The root toctree document. +root_doc = "index" + +# General information about the project. +project = "google-devicesandservices-health" +copyright = "2026, Google, LLC" +author = "Google APIs" + +# 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", + "**/.nox/**/*", + "samples/AUTHORING_GUIDE.md", + "samples/CONTRIBUTING.md", + "samples/snippets/README.rst", +] + +# 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 Devicesandservices Client Libraries for google-devicesandservices-health", + "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-devicesandservices-health-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 = [ + ( + root_doc, + "google-devicesandservices-health.tex", + "google-devicesandservices-health 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 = [ + ( + root_doc, + "google-devicesandservices-health", + "google-devicesandservices-health 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 = [ + ( + root_doc, + "google-devicesandservices-health", + "google-devicesandservices-health Documentation", + author, + "google-devicesandservices-health", + "google-devicesandservices-health Library", + "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": ("https://python.readthedocs.org/en/latest/", None), + "google-auth": ("https://googleapis.dev/python/google-auth/latest/", None), + "google.api_core": ( + "https://googleapis.dev/python/google-api-core/latest/", + None, + ), + "grpc": ("https://grpc.github.io/grpc/python/", None), + "proto-plus": ("https://proto-plus-python.readthedocs.io/en/latest/", None), + "protobuf": ("https://googleapis.dev/python/protobuf/latest/", None), +} + + +# 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 + + +# Setup for sphinx behaviors such as warning filters. +class UnexpectedUnindentFilter(logging.Filter): + """Filter out warnings about unexpected unindentation following bullet lists.""" + + def filter(self, record: logging.LogRecord) -> bool: + """Filter the log record. + + Args: + record (logging.LogRecord): The log record. + + Returns: + bool: False to suppress the warning, True to allow it. + """ + msg = record.getMessage() + if "Bullet list ends without a blank line" in msg: + return False + return True + + +def setup(app: Any) -> None: + """Setup the Sphinx application. + + Args: + app (Any): The Sphinx application. + """ + # Sphinx's logger is hierarchical. Adding a filter to the + # root 'sphinx' logger will catch warnings from all sub-loggers. + logger = logging.getLogger("sphinx") + logger.addFilter(UnexpectedUnindentFilter()) diff --git a/packages/google-devicesandservices-health/docs/health_v4/data_points_service.rst b/packages/google-devicesandservices-health/docs/health_v4/data_points_service.rst new file mode 100644 index 000000000000..3ffc3f8ad616 --- /dev/null +++ b/packages/google-devicesandservices-health/docs/health_v4/data_points_service.rst @@ -0,0 +1,10 @@ +DataPointsService +----------------------------------- + +.. automodule:: google.devicesandservices.health_v4.services.data_points_service + :members: + :inherited-members: + +.. automodule:: google.devicesandservices.health_v4.services.data_points_service.pagers + :members: + :inherited-members: diff --git a/packages/google-devicesandservices-health/docs/health_v4/data_subscription_service.rst b/packages/google-devicesandservices-health/docs/health_v4/data_subscription_service.rst new file mode 100644 index 000000000000..ae7fff06bfa5 --- /dev/null +++ b/packages/google-devicesandservices-health/docs/health_v4/data_subscription_service.rst @@ -0,0 +1,10 @@ +DataSubscriptionService +----------------------------------------- + +.. automodule:: google.devicesandservices.health_v4.services.data_subscription_service + :members: + :inherited-members: + +.. automodule:: google.devicesandservices.health_v4.services.data_subscription_service.pagers + :members: + :inherited-members: diff --git a/packages/google-devicesandservices-health/docs/health_v4/health_profile_service.rst b/packages/google-devicesandservices-health/docs/health_v4/health_profile_service.rst new file mode 100644 index 000000000000..c69d0cb0d63d --- /dev/null +++ b/packages/google-devicesandservices-health/docs/health_v4/health_profile_service.rst @@ -0,0 +1,10 @@ +HealthProfileService +-------------------------------------- + +.. automodule:: google.devicesandservices.health_v4.services.health_profile_service + :members: + :inherited-members: + +.. automodule:: google.devicesandservices.health_v4.services.health_profile_service.pagers + :members: + :inherited-members: diff --git a/packages/google-devicesandservices-health/docs/health_v4/services_.rst b/packages/google-devicesandservices-health/docs/health_v4/services_.rst new file mode 100644 index 000000000000..a7cb2115e585 --- /dev/null +++ b/packages/google-devicesandservices-health/docs/health_v4/services_.rst @@ -0,0 +1,8 @@ +Services for Google Devicesandservices Health v4 API +==================================================== +.. toctree:: + :maxdepth: 2 + + data_points_service + data_subscription_service + health_profile_service diff --git a/packages/google-devicesandservices-health/docs/health_v4/types_.rst b/packages/google-devicesandservices-health/docs/health_v4/types_.rst new file mode 100644 index 000000000000..54cc9ec84b48 --- /dev/null +++ b/packages/google-devicesandservices-health/docs/health_v4/types_.rst @@ -0,0 +1,6 @@ +Types for Google Devicesandservices Health v4 API +================================================= + +.. automodule:: google.devicesandservices.health_v4.types + :members: + :show-inheritance: diff --git a/packages/google-devicesandservices-health/docs/index.rst b/packages/google-devicesandservices-health/docs/index.rst new file mode 100644 index 000000000000..c9f24c30318f --- /dev/null +++ b/packages/google-devicesandservices-health/docs/index.rst @@ -0,0 +1,23 @@ +.. include:: README.rst + +.. include:: multiprocessing.rst + + +API Reference +------------- +.. toctree:: + :maxdepth: 2 + + health_v4/services_ + health_v4/types_ + + +Changelog +--------- + +For a list of all ``google-devicesandservices-health`` releases: + +.. toctree:: + :maxdepth: 2 + + CHANGELOG diff --git a/packages/google-devicesandservices-health/docs/multiprocessing.rst b/packages/google-devicesandservices-health/docs/multiprocessing.rst new file mode 100644 index 000000000000..536d17b2ea65 --- /dev/null +++ b/packages/google-devicesandservices-health/docs/multiprocessing.rst @@ -0,0 +1,7 @@ +.. note:: + + Because this client uses :mod:`grpc` library, it is safe to + share instances across threads. In multiprocessing scenarios, the best + practice is to create client instances *after* the invocation of + :func:`os.fork` by :class:`multiprocessing.pool.Pool` or + :class:`multiprocessing.Process`. diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health/__init__.py b/packages/google-devicesandservices-health/google/devicesandservices/health/__init__.py new file mode 100644 index 000000000000..784332cdfe19 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health/__init__.py @@ -0,0 +1,337 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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.devicesandservices.health import gapic_version as package_version + +__version__ = package_version.__version__ + + +from google.devicesandservices.health_v4.services.data_points_service.async_client import ( + DataPointsServiceAsyncClient, +) +from google.devicesandservices.health_v4.services.data_points_service.client import ( + DataPointsServiceClient, +) +from google.devicesandservices.health_v4.services.data_subscription_service.async_client import ( + DataSubscriptionServiceAsyncClient, +) +from google.devicesandservices.health_v4.services.data_subscription_service.client import ( + DataSubscriptionServiceClient, +) +from google.devicesandservices.health_v4.services.health_profile_service.async_client import ( + HealthProfileServiceAsyncClient, +) +from google.devicesandservices.health_v4.services.health_profile_service.client import ( + HealthProfileServiceClient, +) +from google.devicesandservices.health_v4.types.data_coordinates import ( + CivilDateTime, + CivilTimeInterval, + ObservationSampleTime, + ObservationTimeInterval, + SessionTimeInterval, +) +from google.devicesandservices.health_v4.types.data_model import ( + ActiveEnergyBurned, + ActiveEnergyBurnedRollupValue, + ActiveMinutes, + ActiveMinutesRollupValue, + ActiveZoneMinutes, + ActiveZoneMinutesRollupValue, + ActivityLevel, + ActivityLevelRollupValue, + Altitude, + AltitudeRollupValue, + BasalEnergyBurned, + BloodGlucose, + BloodGlucoseRollupValue, + BodyFat, + BodyFatRollupValue, + CaloriesInHeartRateZoneRollupValue, + CoreBodyTemperature, + CoreBodyTemperatureRollupValue, + DailyHeartRateVariability, + DailyHeartRateZones, + DailyOxygenSaturation, + DailyRespiratoryRate, + DailyRestingHeartRate, + DailySleepTemperatureDerivations, + DailyVO2Max, + Distance, + DistanceRollupValue, + Electrocardiogram, + EnergyQuantity, + EnergyUnit, + Exercise, + Floors, + FloorsRollupValue, + Food, + FoodAccessLevel, + FoodMeasurementUnit, + HeartRate, + HeartRateRollupValue, + HeartRateVariability, + HeartRateVariabilityPersonalRangeRollupValue, + HeartRateZoneType, + Height, + HydrationLog, + HydrationLogRollupValue, + IrregularRhythmNotification, + MealType, + MetricsSummary, + Nutrient, + NutrientQuantity, + NutritionLog, + NutritionLogRollupValue, + OxygenSaturation, + RespiratoryRateSleepSummary, + RestingHeartRatePersonalRangeRollupValue, + RunVO2Max, + RunVO2MaxRollupValue, + SedentaryPeriod, + SedentaryPeriodRollupValue, + Sleep, + Steps, + StepsRollupValue, + SwimLengthsData, + SwimLengthsDataRollupValue, + TimeInHeartRateZone, + TimeInHeartRateZoneRollupValue, + TotalCaloriesRollupValue, + VO2Max, + VolumeQuantity, + VolumeUnit, + Weight, + WeightQuantity, + WeightRollupValue, + WeightUnit, +) +from google.devicesandservices.health_v4.types.data_points import ( + BatchDeleteDataPointsOperationMetadata, + BatchDeleteDataPointsRequest, + BatchDeleteDataPointsResponse, + CreateDataPointOperationMetadata, + CreateDataPointRequest, + DailyRollupDataPoint, + DailyRollUpDataPointsRequest, + DailyRollUpDataPointsResponse, + DataPoint, + DataType, + ExportExerciseTcxRequest, + ExportExerciseTcxResponse, + GetDataPointRequest, + ListDataPointsRequest, + ListDataPointsResponse, + ReconcileDataPointsRequest, + ReconcileDataPointsResponse, + ReconciledDataPoint, + RollupDataPoint, + RollUpDataPointsRequest, + RollUpDataPointsResponse, + UpdateDataPointOperationMetadata, + UpdateDataPointRequest, +) +from google.devicesandservices.health_v4.types.data_source import DataSource +from google.devicesandservices.health_v4.types.data_subscription_service import ( + CreateSubscriberMetadata, + CreateSubscriberPayload, + CreateSubscriberRequest, + CreateSubscriptionPayload, + CreateSubscriptionRequest, + DeleteSubscriberMetadata, + DeleteSubscriberRequest, + DeleteSubscriptionRequest, + EndpointAuthorization, + ListSubscribersRequest, + ListSubscribersResponse, + ListSubscriptionsRequest, + ListSubscriptionsResponse, + Subscriber, + SubscriberConfig, + Subscription, + UpdateSubscriberMetadata, + UpdateSubscriberRequest, + UpdateSubscriptionRequest, +) +from google.devicesandservices.health_v4.types.health_profile import ( + GetIdentityRequest, + GetIrnProfileRequest, + GetPairedDeviceRequest, + GetProfileRequest, + GetSettingsRequest, + Identity, + IrnProfile, + ListPairedDevicesRequest, + ListPairedDevicesResponse, + PairedDevice, + Profile, + Settings, + UpdateProfileRequest, + UpdateSettingsRequest, + User, +) +from google.devicesandservices.health_v4.types.medical_device_info import ( + MedicalDeviceInfo, +) +from google.devicesandservices.health_v4.types.webhook_notification_cloud_log import ( + WebhookNotificationCloudLog, +) + +__all__ = ( + "DataPointsServiceClient", + "DataPointsServiceAsyncClient", + "DataSubscriptionServiceClient", + "DataSubscriptionServiceAsyncClient", + "HealthProfileServiceClient", + "HealthProfileServiceAsyncClient", + "CivilDateTime", + "CivilTimeInterval", + "ObservationSampleTime", + "ObservationTimeInterval", + "SessionTimeInterval", + "ActiveEnergyBurned", + "ActiveEnergyBurnedRollupValue", + "ActiveMinutes", + "ActiveMinutesRollupValue", + "ActiveZoneMinutes", + "ActiveZoneMinutesRollupValue", + "ActivityLevel", + "ActivityLevelRollupValue", + "Altitude", + "AltitudeRollupValue", + "BasalEnergyBurned", + "BloodGlucose", + "BloodGlucoseRollupValue", + "BodyFat", + "BodyFatRollupValue", + "CaloriesInHeartRateZoneRollupValue", + "CoreBodyTemperature", + "CoreBodyTemperatureRollupValue", + "DailyHeartRateVariability", + "DailyHeartRateZones", + "DailyOxygenSaturation", + "DailyRespiratoryRate", + "DailyRestingHeartRate", + "DailySleepTemperatureDerivations", + "DailyVO2Max", + "Distance", + "DistanceRollupValue", + "Electrocardiogram", + "EnergyQuantity", + "Exercise", + "Floors", + "FloorsRollupValue", + "Food", + "FoodMeasurementUnit", + "HeartRate", + "HeartRateRollupValue", + "HeartRateVariability", + "HeartRateVariabilityPersonalRangeRollupValue", + "Height", + "HydrationLog", + "HydrationLogRollupValue", + "IrregularRhythmNotification", + "MetricsSummary", + "NutrientQuantity", + "NutritionLog", + "NutritionLogRollupValue", + "OxygenSaturation", + "RespiratoryRateSleepSummary", + "RestingHeartRatePersonalRangeRollupValue", + "RunVO2Max", + "RunVO2MaxRollupValue", + "SedentaryPeriod", + "SedentaryPeriodRollupValue", + "Sleep", + "Steps", + "StepsRollupValue", + "SwimLengthsData", + "SwimLengthsDataRollupValue", + "TimeInHeartRateZone", + "TimeInHeartRateZoneRollupValue", + "TotalCaloriesRollupValue", + "VO2Max", + "VolumeQuantity", + "Weight", + "WeightQuantity", + "WeightRollupValue", + "EnergyUnit", + "FoodAccessLevel", + "HeartRateZoneType", + "MealType", + "Nutrient", + "VolumeUnit", + "WeightUnit", + "BatchDeleteDataPointsOperationMetadata", + "BatchDeleteDataPointsRequest", + "BatchDeleteDataPointsResponse", + "CreateDataPointOperationMetadata", + "CreateDataPointRequest", + "DailyRollupDataPoint", + "DailyRollUpDataPointsRequest", + "DailyRollUpDataPointsResponse", + "DataPoint", + "DataType", + "ExportExerciseTcxRequest", + "ExportExerciseTcxResponse", + "GetDataPointRequest", + "ListDataPointsRequest", + "ListDataPointsResponse", + "ReconcileDataPointsRequest", + "ReconcileDataPointsResponse", + "ReconciledDataPoint", + "RollupDataPoint", + "RollUpDataPointsRequest", + "RollUpDataPointsResponse", + "UpdateDataPointOperationMetadata", + "UpdateDataPointRequest", + "DataSource", + "CreateSubscriberMetadata", + "CreateSubscriberPayload", + "CreateSubscriberRequest", + "CreateSubscriptionPayload", + "CreateSubscriptionRequest", + "DeleteSubscriberMetadata", + "DeleteSubscriberRequest", + "DeleteSubscriptionRequest", + "EndpointAuthorization", + "ListSubscribersRequest", + "ListSubscribersResponse", + "ListSubscriptionsRequest", + "ListSubscriptionsResponse", + "Subscriber", + "SubscriberConfig", + "Subscription", + "UpdateSubscriberMetadata", + "UpdateSubscriberRequest", + "UpdateSubscriptionRequest", + "GetIdentityRequest", + "GetIrnProfileRequest", + "GetPairedDeviceRequest", + "GetProfileRequest", + "GetSettingsRequest", + "Identity", + "IrnProfile", + "ListPairedDevicesRequest", + "ListPairedDevicesResponse", + "PairedDevice", + "Profile", + "Settings", + "UpdateProfileRequest", + "UpdateSettingsRequest", + "User", + "MedicalDeviceInfo", + "WebhookNotificationCloudLog", +) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health/gapic_version.py b/packages/google-devicesandservices-health/google/devicesandservices/health/gapic_version.py new file mode 100644 index 000000000000..e89a0031d71b --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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. +# +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health/py.typed b/packages/google-devicesandservices-health/google/devicesandservices/health/py.typed new file mode 100644 index 000000000000..f45ddfa9a8d0 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-devicesandservices-health package uses inline types. diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/__init__.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/__init__.py new file mode 100644 index 000000000000..c6014be40728 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/__init__.py @@ -0,0 +1,415 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 sys + +import google.api_core as api_core + +from google.devicesandservices.health_v4 import gapic_version as package_version + +__version__ = package_version.__version__ + +from importlib import metadata + +from .services.data_points_service import ( + DataPointsServiceAsyncClient, + DataPointsServiceClient, +) +from .services.data_subscription_service import ( + DataSubscriptionServiceAsyncClient, + DataSubscriptionServiceClient, +) +from .services.health_profile_service import ( + HealthProfileServiceAsyncClient, + HealthProfileServiceClient, +) +from .types.data_coordinates import ( + CivilDateTime, + CivilTimeInterval, + ObservationSampleTime, + ObservationTimeInterval, + SessionTimeInterval, +) +from .types.data_model import ( + ActiveEnergyBurned, + ActiveEnergyBurnedRollupValue, + ActiveMinutes, + ActiveMinutesRollupValue, + ActiveZoneMinutes, + ActiveZoneMinutesRollupValue, + ActivityLevel, + ActivityLevelRollupValue, + Altitude, + AltitudeRollupValue, + BasalEnergyBurned, + BloodGlucose, + BloodGlucoseRollupValue, + BodyFat, + BodyFatRollupValue, + CaloriesInHeartRateZoneRollupValue, + CoreBodyTemperature, + CoreBodyTemperatureRollupValue, + DailyHeartRateVariability, + DailyHeartRateZones, + DailyOxygenSaturation, + DailyRespiratoryRate, + DailyRestingHeartRate, + DailySleepTemperatureDerivations, + DailyVO2Max, + Distance, + DistanceRollupValue, + Electrocardiogram, + EnergyQuantity, + EnergyUnit, + Exercise, + Floors, + FloorsRollupValue, + Food, + FoodAccessLevel, + FoodMeasurementUnit, + HeartRate, + HeartRateRollupValue, + HeartRateVariability, + HeartRateVariabilityPersonalRangeRollupValue, + HeartRateZoneType, + Height, + HydrationLog, + HydrationLogRollupValue, + IrregularRhythmNotification, + MealType, + MetricsSummary, + Nutrient, + NutrientQuantity, + NutritionLog, + NutritionLogRollupValue, + OxygenSaturation, + RespiratoryRateSleepSummary, + RestingHeartRatePersonalRangeRollupValue, + RunVO2Max, + RunVO2MaxRollupValue, + SedentaryPeriod, + SedentaryPeriodRollupValue, + Sleep, + Steps, + StepsRollupValue, + SwimLengthsData, + SwimLengthsDataRollupValue, + TimeInHeartRateZone, + TimeInHeartRateZoneRollupValue, + TotalCaloriesRollupValue, + VO2Max, + VolumeQuantity, + VolumeUnit, + Weight, + WeightQuantity, + WeightRollupValue, + WeightUnit, +) +from .types.data_points import ( + BatchDeleteDataPointsOperationMetadata, + BatchDeleteDataPointsRequest, + BatchDeleteDataPointsResponse, + CreateDataPointOperationMetadata, + CreateDataPointRequest, + DailyRollupDataPoint, + DailyRollUpDataPointsRequest, + DailyRollUpDataPointsResponse, + DataPoint, + DataType, + ExportExerciseTcxRequest, + ExportExerciseTcxResponse, + GetDataPointRequest, + ListDataPointsRequest, + ListDataPointsResponse, + ReconcileDataPointsRequest, + ReconcileDataPointsResponse, + ReconciledDataPoint, + RollupDataPoint, + RollUpDataPointsRequest, + RollUpDataPointsResponse, + UpdateDataPointOperationMetadata, + UpdateDataPointRequest, +) +from .types.data_source import DataSource +from .types.data_subscription_service import ( + CreateSubscriberMetadata, + CreateSubscriberPayload, + CreateSubscriberRequest, + CreateSubscriptionPayload, + CreateSubscriptionRequest, + DeleteSubscriberMetadata, + DeleteSubscriberRequest, + DeleteSubscriptionRequest, + EndpointAuthorization, + ListSubscribersRequest, + ListSubscribersResponse, + ListSubscriptionsRequest, + ListSubscriptionsResponse, + Subscriber, + SubscriberConfig, + Subscription, + UpdateSubscriberMetadata, + UpdateSubscriberRequest, + UpdateSubscriptionRequest, +) +from .types.health_profile import ( + GetIdentityRequest, + GetIrnProfileRequest, + GetPairedDeviceRequest, + GetProfileRequest, + GetSettingsRequest, + Identity, + IrnProfile, + ListPairedDevicesRequest, + ListPairedDevicesResponse, + PairedDevice, + Profile, + Settings, + UpdateProfileRequest, + UpdateSettingsRequest, + User, +) +from .types.medical_device_info import MedicalDeviceInfo +from .types.webhook_notification_cloud_log import WebhookNotificationCloudLog + +if hasattr(api_core, "check_python_version") and hasattr( + api_core, "check_dependency_versions" +): # pragma: NO COVER + api_core.check_python_version("google.devicesandservices.health_v4") # type: ignore + api_core.check_dependency_versions("google.devicesandservices.health_v4") # type: ignore +else: # pragma: NO COVER + # An older version of api_core is installed which does not define the + # functions above. We do equivalent checks manually. + try: + import warnings + + _py_version_str = sys.version.split()[0] + _package_label = "google.devicesandservices.health_v4" + if sys.version_info < (3, 10): + warnings.warn( + "You are using a non-supported Python version " + + f"({_py_version_str}). Google will not post any further " + + f"updates to {_package_label} supporting this Python version. " + + "Please upgrade to the latest Python version, or at " + + f"least to Python 3.10, and then update {_package_label}.", + FutureWarning, + ) + + def parse_version_to_tuple(version_string: str): + """Safely converts a semantic version string to a comparable tuple of integers. + Example: "4.25.8" -> (4, 25, 8) + Ignores non-numeric parts and handles common version formats. + Args: + version_string: Version string in the format "x.y.z" or "x.y.z" + Returns: + Tuple of integers for the parsed version string. + """ + parts = [] + for part in version_string.split("."): + try: + parts.append(int(part)) + except ValueError: + # If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here. + # This is a simplification compared to 'packaging.parse_version', but sufficient + # for comparing strictly numeric semantic versions. + break + return tuple(parts) + + def _get_version(dependency_name): + try: + version_string: str = metadata.version(dependency_name) + parsed_version = parse_version_to_tuple(version_string) + return (parsed_version, version_string) + except Exception: + # Catch exceptions from metadata.version() (e.g., PackageNotFoundError) + # or errors during parse_version_to_tuple + return (None, "--") + + _dependency_package = "google.protobuf" + _next_supported_version = "4.25.8" + _next_supported_version_tuple = (4, 25, 8) + _recommendation = " (we recommend 6.x)" + (_version_used, _version_used_string) = _get_version(_dependency_package) + if _version_used and _version_used < _next_supported_version_tuple: + warnings.warn( + f"Package {_package_label} depends on " + + f"{_dependency_package}, currently installed at version " + + f"{_version_used_string}. Future updates to " + + f"{_package_label} will require {_dependency_package} at " + + f"version {_next_supported_version} or higher{_recommendation}." + + " Please ensure " + + "that either (a) your Python environment doesn't pin the " + + f"version of {_dependency_package}, so that updates to " + + f"{_package_label} can require the higher version, or " + + "(b) you manually update your Python environment to use at " + + f"least version {_next_supported_version} of " + + f"{_dependency_package}.", + FutureWarning, + ) + except Exception: + warnings.warn( + "Could not determine the version of Python " + + "currently being used. To continue receiving " + + "updates for {_package_label}, ensure you are " + + "using a supported version of Python; see " + + "https://devguide.python.org/versions/" + ) + +__all__ = ( + "DataPointsServiceAsyncClient", + "DataSubscriptionServiceAsyncClient", + "HealthProfileServiceAsyncClient", + "ActiveEnergyBurned", + "ActiveEnergyBurnedRollupValue", + "ActiveMinutes", + "ActiveMinutesRollupValue", + "ActiveZoneMinutes", + "ActiveZoneMinutesRollupValue", + "ActivityLevel", + "ActivityLevelRollupValue", + "Altitude", + "AltitudeRollupValue", + "BasalEnergyBurned", + "BatchDeleteDataPointsOperationMetadata", + "BatchDeleteDataPointsRequest", + "BatchDeleteDataPointsResponse", + "BloodGlucose", + "BloodGlucoseRollupValue", + "BodyFat", + "BodyFatRollupValue", + "CaloriesInHeartRateZoneRollupValue", + "CivilDateTime", + "CivilTimeInterval", + "CoreBodyTemperature", + "CoreBodyTemperatureRollupValue", + "CreateDataPointOperationMetadata", + "CreateDataPointRequest", + "CreateSubscriberMetadata", + "CreateSubscriberPayload", + "CreateSubscriberRequest", + "CreateSubscriptionPayload", + "CreateSubscriptionRequest", + "DailyHeartRateVariability", + "DailyHeartRateZones", + "DailyOxygenSaturation", + "DailyRespiratoryRate", + "DailyRestingHeartRate", + "DailyRollUpDataPointsRequest", + "DailyRollUpDataPointsResponse", + "DailyRollupDataPoint", + "DailySleepTemperatureDerivations", + "DailyVO2Max", + "DataPoint", + "DataPointsServiceClient", + "DataSource", + "DataSubscriptionServiceClient", + "DataType", + "DeleteSubscriberMetadata", + "DeleteSubscriberRequest", + "DeleteSubscriptionRequest", + "Distance", + "DistanceRollupValue", + "Electrocardiogram", + "EndpointAuthorization", + "EnergyQuantity", + "EnergyUnit", + "Exercise", + "ExportExerciseTcxRequest", + "ExportExerciseTcxResponse", + "Floors", + "FloorsRollupValue", + "Food", + "FoodAccessLevel", + "FoodMeasurementUnit", + "GetDataPointRequest", + "GetIdentityRequest", + "GetIrnProfileRequest", + "GetPairedDeviceRequest", + "GetProfileRequest", + "GetSettingsRequest", + "HealthProfileServiceClient", + "HeartRate", + "HeartRateRollupValue", + "HeartRateVariability", + "HeartRateVariabilityPersonalRangeRollupValue", + "HeartRateZoneType", + "Height", + "HydrationLog", + "HydrationLogRollupValue", + "Identity", + "IrnProfile", + "IrregularRhythmNotification", + "ListDataPointsRequest", + "ListDataPointsResponse", + "ListPairedDevicesRequest", + "ListPairedDevicesResponse", + "ListSubscribersRequest", + "ListSubscribersResponse", + "ListSubscriptionsRequest", + "ListSubscriptionsResponse", + "MealType", + "MedicalDeviceInfo", + "MetricsSummary", + "Nutrient", + "NutrientQuantity", + "NutritionLog", + "NutritionLogRollupValue", + "ObservationSampleTime", + "ObservationTimeInterval", + "OxygenSaturation", + "PairedDevice", + "Profile", + "ReconcileDataPointsRequest", + "ReconcileDataPointsResponse", + "ReconciledDataPoint", + "RespiratoryRateSleepSummary", + "RestingHeartRatePersonalRangeRollupValue", + "RollUpDataPointsRequest", + "RollUpDataPointsResponse", + "RollupDataPoint", + "RunVO2Max", + "RunVO2MaxRollupValue", + "SedentaryPeriod", + "SedentaryPeriodRollupValue", + "SessionTimeInterval", + "Settings", + "Sleep", + "Steps", + "StepsRollupValue", + "Subscriber", + "SubscriberConfig", + "Subscription", + "SwimLengthsData", + "SwimLengthsDataRollupValue", + "TimeInHeartRateZone", + "TimeInHeartRateZoneRollupValue", + "TotalCaloriesRollupValue", + "UpdateDataPointOperationMetadata", + "UpdateDataPointRequest", + "UpdateProfileRequest", + "UpdateSettingsRequest", + "UpdateSubscriberMetadata", + "UpdateSubscriberRequest", + "UpdateSubscriptionRequest", + "User", + "VO2Max", + "VolumeQuantity", + "VolumeUnit", + "WebhookNotificationCloudLog", + "Weight", + "WeightQuantity", + "WeightRollupValue", + "WeightUnit", +) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/gapic_metadata.json b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/gapic_metadata.json new file mode 100644 index 000000000000..52877256a0f5 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/gapic_metadata.json @@ -0,0 +1,441 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.devicesandservices.health_v4", + "protoPackage": "google.devicesandservices.health.v4", + "schema": "1.0", + "services": { + "DataPointsService": { + "clients": { + "grpc": { + "libraryClient": "DataPointsServiceClient", + "rpcs": { + "BatchDeleteDataPoints": { + "methods": [ + "batch_delete_data_points" + ] + }, + "CreateDataPoint": { + "methods": [ + "create_data_point" + ] + }, + "DailyRollUpDataPoints": { + "methods": [ + "daily_roll_up_data_points" + ] + }, + "ExportExerciseTcx": { + "methods": [ + "export_exercise_tcx" + ] + }, + "GetDataPoint": { + "methods": [ + "get_data_point" + ] + }, + "ListDataPoints": { + "methods": [ + "list_data_points" + ] + }, + "ReconcileDataPoints": { + "methods": [ + "reconcile_data_points" + ] + }, + "RollUpDataPoints": { + "methods": [ + "roll_up_data_points" + ] + }, + "UpdateDataPoint": { + "methods": [ + "update_data_point" + ] + } + } + }, + "grpc-async": { + "libraryClient": "DataPointsServiceAsyncClient", + "rpcs": { + "BatchDeleteDataPoints": { + "methods": [ + "batch_delete_data_points" + ] + }, + "CreateDataPoint": { + "methods": [ + "create_data_point" + ] + }, + "DailyRollUpDataPoints": { + "methods": [ + "daily_roll_up_data_points" + ] + }, + "ExportExerciseTcx": { + "methods": [ + "export_exercise_tcx" + ] + }, + "GetDataPoint": { + "methods": [ + "get_data_point" + ] + }, + "ListDataPoints": { + "methods": [ + "list_data_points" + ] + }, + "ReconcileDataPoints": { + "methods": [ + "reconcile_data_points" + ] + }, + "RollUpDataPoints": { + "methods": [ + "roll_up_data_points" + ] + }, + "UpdateDataPoint": { + "methods": [ + "update_data_point" + ] + } + } + }, + "rest": { + "libraryClient": "DataPointsServiceClient", + "rpcs": { + "BatchDeleteDataPoints": { + "methods": [ + "batch_delete_data_points" + ] + }, + "CreateDataPoint": { + "methods": [ + "create_data_point" + ] + }, + "DailyRollUpDataPoints": { + "methods": [ + "daily_roll_up_data_points" + ] + }, + "ExportExerciseTcx": { + "methods": [ + "export_exercise_tcx" + ] + }, + "GetDataPoint": { + "methods": [ + "get_data_point" + ] + }, + "ListDataPoints": { + "methods": [ + "list_data_points" + ] + }, + "ReconcileDataPoints": { + "methods": [ + "reconcile_data_points" + ] + }, + "RollUpDataPoints": { + "methods": [ + "roll_up_data_points" + ] + }, + "UpdateDataPoint": { + "methods": [ + "update_data_point" + ] + } + } + } + } + }, + "DataSubscriptionService": { + "clients": { + "grpc": { + "libraryClient": "DataSubscriptionServiceClient", + "rpcs": { + "CreateSubscriber": { + "methods": [ + "create_subscriber" + ] + }, + "CreateSubscription": { + "methods": [ + "create_subscription" + ] + }, + "DeleteSubscriber": { + "methods": [ + "delete_subscriber" + ] + }, + "DeleteSubscription": { + "methods": [ + "delete_subscription" + ] + }, + "ListSubscribers": { + "methods": [ + "list_subscribers" + ] + }, + "ListSubscriptions": { + "methods": [ + "list_subscriptions" + ] + }, + "UpdateSubscriber": { + "methods": [ + "update_subscriber" + ] + }, + "UpdateSubscription": { + "methods": [ + "update_subscription" + ] + } + } + }, + "grpc-async": { + "libraryClient": "DataSubscriptionServiceAsyncClient", + "rpcs": { + "CreateSubscriber": { + "methods": [ + "create_subscriber" + ] + }, + "CreateSubscription": { + "methods": [ + "create_subscription" + ] + }, + "DeleteSubscriber": { + "methods": [ + "delete_subscriber" + ] + }, + "DeleteSubscription": { + "methods": [ + "delete_subscription" + ] + }, + "ListSubscribers": { + "methods": [ + "list_subscribers" + ] + }, + "ListSubscriptions": { + "methods": [ + "list_subscriptions" + ] + }, + "UpdateSubscriber": { + "methods": [ + "update_subscriber" + ] + }, + "UpdateSubscription": { + "methods": [ + "update_subscription" + ] + } + } + }, + "rest": { + "libraryClient": "DataSubscriptionServiceClient", + "rpcs": { + "CreateSubscriber": { + "methods": [ + "create_subscriber" + ] + }, + "CreateSubscription": { + "methods": [ + "create_subscription" + ] + }, + "DeleteSubscriber": { + "methods": [ + "delete_subscriber" + ] + }, + "DeleteSubscription": { + "methods": [ + "delete_subscription" + ] + }, + "ListSubscribers": { + "methods": [ + "list_subscribers" + ] + }, + "ListSubscriptions": { + "methods": [ + "list_subscriptions" + ] + }, + "UpdateSubscriber": { + "methods": [ + "update_subscriber" + ] + }, + "UpdateSubscription": { + "methods": [ + "update_subscription" + ] + } + } + } + } + }, + "HealthProfileService": { + "clients": { + "grpc": { + "libraryClient": "HealthProfileServiceClient", + "rpcs": { + "GetIdentity": { + "methods": [ + "get_identity" + ] + }, + "GetIrnProfile": { + "methods": [ + "get_irn_profile" + ] + }, + "GetPairedDevice": { + "methods": [ + "get_paired_device" + ] + }, + "GetProfile": { + "methods": [ + "get_profile" + ] + }, + "GetSettings": { + "methods": [ + "get_settings" + ] + }, + "ListPairedDevices": { + "methods": [ + "list_paired_devices" + ] + }, + "UpdateProfile": { + "methods": [ + "update_profile" + ] + }, + "UpdateSettings": { + "methods": [ + "update_settings" + ] + } + } + }, + "grpc-async": { + "libraryClient": "HealthProfileServiceAsyncClient", + "rpcs": { + "GetIdentity": { + "methods": [ + "get_identity" + ] + }, + "GetIrnProfile": { + "methods": [ + "get_irn_profile" + ] + }, + "GetPairedDevice": { + "methods": [ + "get_paired_device" + ] + }, + "GetProfile": { + "methods": [ + "get_profile" + ] + }, + "GetSettings": { + "methods": [ + "get_settings" + ] + }, + "ListPairedDevices": { + "methods": [ + "list_paired_devices" + ] + }, + "UpdateProfile": { + "methods": [ + "update_profile" + ] + }, + "UpdateSettings": { + "methods": [ + "update_settings" + ] + } + } + }, + "rest": { + "libraryClient": "HealthProfileServiceClient", + "rpcs": { + "GetIdentity": { + "methods": [ + "get_identity" + ] + }, + "GetIrnProfile": { + "methods": [ + "get_irn_profile" + ] + }, + "GetPairedDevice": { + "methods": [ + "get_paired_device" + ] + }, + "GetProfile": { + "methods": [ + "get_profile" + ] + }, + "GetSettings": { + "methods": [ + "get_settings" + ] + }, + "ListPairedDevices": { + "methods": [ + "list_paired_devices" + ] + }, + "UpdateProfile": { + "methods": [ + "update_profile" + ] + }, + "UpdateSettings": { + "methods": [ + "update_settings" + ] + } + } + } + } + } + } +} diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/gapic_version.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/gapic_version.py new file mode 100644 index 000000000000..e89a0031d71b --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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. +# +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/py.typed b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/py.typed new file mode 100644 index 000000000000..f45ddfa9a8d0 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-devicesandservices-health package uses inline types. diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/__init__.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/__init__.py new file mode 100644 index 000000000000..32b36c5c4fe0 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/__init__.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/__init__.py new file mode 100644 index 000000000000..edc3c1f37ee0 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .async_client import DataPointsServiceAsyncClient +from .client import DataPointsServiceClient + +__all__ = ( + "DataPointsServiceClient", + "DataPointsServiceAsyncClient", +) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/async_client.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/async_client.py new file mode 100644 index 000000000000..95ea8d7fe29f --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/async_client.py @@ -0,0 +1,1373 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 logging as std_logging +import re +from collections import OrderedDict +from typing import ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, +) + +import google.protobuf +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.api_core.client_options import ClientOptions +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.devicesandservices.health_v4 import gapic_version as package_version + +try: + OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +import google.api_core.operation as operation # type: ignore +import google.api_core.operation_async as operation_async # type: ignore + +from google.devicesandservices.health_v4.services.data_points_service import pagers +from google.devicesandservices.health_v4.types import ( + data_model, + data_points, + data_source, +) + +from .client import DataPointsServiceClient +from .transports.base import DEFAULT_CLIENT_INFO, DataPointsServiceTransport +from .transports.grpc_asyncio import DataPointsServiceGrpcAsyncIOTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class DataPointsServiceAsyncClient: + """Data Points Service exposing the user's health and fitness + measured and derived data. + """ + + _client: DataPointsServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = DataPointsServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = DataPointsServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = DataPointsServiceClient._DEFAULT_ENDPOINT_TEMPLATE + _DEFAULT_UNIVERSE = DataPointsServiceClient._DEFAULT_UNIVERSE + + data_point_path = staticmethod(DataPointsServiceClient.data_point_path) + parse_data_point_path = staticmethod(DataPointsServiceClient.parse_data_point_path) + data_type_path = staticmethod(DataPointsServiceClient.data_type_path) + parse_data_type_path = staticmethod(DataPointsServiceClient.parse_data_type_path) + common_billing_account_path = staticmethod( + DataPointsServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + DataPointsServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(DataPointsServiceClient.common_folder_path) + parse_common_folder_path = staticmethod( + DataPointsServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + DataPointsServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + DataPointsServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod(DataPointsServiceClient.common_project_path) + parse_common_project_path = staticmethod( + DataPointsServiceClient.parse_common_project_path + ) + common_location_path = staticmethod(DataPointsServiceClient.common_location_path) + parse_common_location_path = staticmethod( + DataPointsServiceClient.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: + DataPointsServiceAsyncClient: The constructed client. + """ + sa_info_func = ( + DataPointsServiceClient.from_service_account_info.__func__ # type: ignore + ) + return sa_info_func(DataPointsServiceAsyncClient, info, *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: + DataPointsServiceAsyncClient: The constructed client. + """ + sa_file_func = ( + DataPointsServiceClient.from_service_account_file.__func__ # type: ignore + ) + return sa_file_func(DataPointsServiceAsyncClient, filename, *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 variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return DataPointsServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> DataPointsServiceTransport: + """Returns the transport used by the client instance. + + Returns: + DataPointsServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self) -> str: + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = DataPointsServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + DataPointsServiceTransport, + Callable[..., DataPointsServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the data points service async 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 (Optional[Union[str,DataPointsServiceTransport,Callable[..., DataPointsServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the DataPointsServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "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). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS 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. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + 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. + """ + self._client = DataPointsServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.devicesandservices.health_v4.DataPointsServiceAsyncClient`.", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataPointsService", + "universeDomain": getattr( + self._client._transport._credentials, "universe_domain", "" + ), + "credentialsType": f"{type(self._client._transport._credentials).__module__}.{type(self._client._transport._credentials).__qualname__}", + "credentialsInfo": getattr( + self.transport._credentials, "get_cred_info", lambda: None + )(), + } + if hasattr(self._client._transport, "_credentials") + else { + "serviceName": "google.devicesandservices.health.v4.DataPointsService", + "credentialsType": None, + }, + ) + + async def get_data_point( + self, + request: Optional[Union[data_points.GetDataPointRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> data_points.DataPoint: + r"""Get a single identifyable data point. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + async def sample_get_data_point(): + # Create a client + client = health_v4.DataPointsServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.GetDataPointRequest( + name="name_value", + ) + + # Make the request + response = await client.get_data_point(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.devicesandservices.health_v4.types.GetDataPointRequest, dict]]): + The request object. Request for getting a single data + point + name (:class:`str`): + Required. The name of the data point to retrieve. + + Format: + ``users/{user}/dataTypes/{data_type}/dataPoints/{data_point}`` + + See + [DataPoint.name][google.devicesandservices.health.v4.DataPoint.name] + for examples and possible values. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.types.DataPoint: + A computed or recorded metric. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_points.GetDataPointRequest): + request = data_points.GetDataPointRequest(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._client._transport._wrapped_methods[ + self._client._transport.get_data_point + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_data_points( + self, + request: Optional[Union[data_points.ListDataPointsRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListDataPointsAsyncPager: + r"""Query user health and fitness data points. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + async def sample_list_data_points(): + # Create a client + client = health_v4.DataPointsServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.ListDataPointsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_data_points(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.devicesandservices.health_v4.types.ListDataPointsRequest, dict]]): + The request object. Request for listing raw data points + parent (:class:`str`): + Required. Parent data type of the Data Point collection. + + Format: ``users/me/dataTypes/{data_type}``, e.g.: + + - ``users/me/dataTypes/steps`` + - ``users/me/dataTypes/weight`` + + For a list of the supported data types see the + [DataPoint + data][google.devicesandservices.health.v4.DataPoint] + union field. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.services.data_points_service.pagers.ListDataPointsAsyncPager: + Response containing raw data points + matching the query + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_points.ListDataPointsRequest): + request = data_points.ListDataPointsRequest(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._client._transport._wrapped_methods[ + self._client._transport.list_data_points + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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.ListDataPointsAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def create_data_point( + self, + request: Optional[Union[data_points.CreateDataPointRequest, dict]] = None, + *, + parent: Optional[str] = None, + data_point: Optional[data_points.DataPoint] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""Creates a single identifiable data point. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + async def sample_create_data_point(): + # Create a client + client = health_v4.DataPointsServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.CreateDataPointRequest( + parent="parent_value", + ) + + # Make the request + operation = await client.create_data_point(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.devicesandservices.health_v4.types.CreateDataPointRequest, dict]]): + The request object. Request to create an identifiable + data point. + parent (:class:`str`): + Required. The parent resource name where the data point + will be created. Format: + ``users/{user}/dataTypes/{data_type}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + data_point (:class:`google.devicesandservices.health_v4.types.DataPoint`): + Required. The data point to create. + This corresponds to the ``data_point`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.devicesandservices.health_v4.types.DataPoint` + A computed or recorded metric. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, data_point] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_points.CreateDataPointRequest): + request = data_points.CreateDataPointRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if data_point is not None: + request.data_point = data_point + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.create_data_point + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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, + data_points.DataPoint, + metadata_type=data_points.CreateDataPointOperationMetadata, + ) + + # Done; return the response. + return response + + async def update_data_point( + self, + request: Optional[Union[data_points.UpdateDataPointRequest, dict]] = None, + *, + data_point: Optional[data_points.DataPoint] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""Updates a single identifiable data point. If a data point with + the specified ``name`` is not found, the request will fail. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + async def sample_update_data_point(): + # Create a client + client = health_v4.DataPointsServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.UpdateDataPointRequest( + ) + + # Make the request + operation = await client.update_data_point(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.devicesandservices.health_v4.types.UpdateDataPointRequest, dict]]): + The request object. Request to update an identifiable + data point. + data_point (:class:`google.devicesandservices.health_v4.types.DataPoint`): + Required. The data point to update + + The data point's ``name`` field is used to identify the + data point to update. + + Format: + ``users/{user}/dataTypes/{data_type}/dataPoints/{data_point}`` + + This corresponds to the ``data_point`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.devicesandservices.health_v4.types.DataPoint` + A computed or recorded metric. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [data_point] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_points.UpdateDataPointRequest): + request = data_points.UpdateDataPointRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if data_point is not None: + request.data_point = data_point + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.update_data_point + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("data_point.name", request.data_point.name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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, + data_points.DataPoint, + metadata_type=data_points.UpdateDataPointOperationMetadata, + ) + + # Done; return the response. + return response + + async def batch_delete_data_points( + self, + request: Optional[Union[data_points.BatchDeleteDataPointsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""Delete a batch of identifyable data points. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + async def sample_batch_delete_data_points(): + # Create a client + client = health_v4.DataPointsServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.BatchDeleteDataPointsRequest( + names=['names_value1', 'names_value2'], + ) + + # Make the request + operation = await client.batch_delete_data_points(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.devicesandservices.health_v4.types.BatchDeleteDataPointsRequest, dict]]): + The request object. Request to delete a batch of + identifiable data points. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.devicesandservices.health_v4.types.BatchDeleteDataPointsResponse` + Response containing the list of possibly soft-deleted + DataPoints. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_points.BatchDeleteDataPointsRequest): + request = data_points.BatchDeleteDataPointsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.batch_delete_data_points + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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, + data_points.BatchDeleteDataPointsResponse, + metadata_type=data_points.BatchDeleteDataPointsOperationMetadata, + ) + + # Done; return the response. + return response + + async def reconcile_data_points( + self, + request: Optional[Union[data_points.ReconcileDataPointsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ReconcileDataPointsAsyncPager: + r"""Reconcile data points from multiple data sources into + a single data stream. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + async def sample_reconcile_data_points(): + # Create a client + client = health_v4.DataPointsServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.ReconcileDataPointsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.reconcile_data_points(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.devicesandservices.health_v4.types.ReconcileDataPointsRequest, dict]]): + The request object. Request to reconcile data points from + multiple data sources. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.services.data_points_service.pagers.ReconcileDataPointsAsyncPager: + Response containing the list of + reconciled DataPoints. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_points.ReconcileDataPointsRequest): + request = data_points.ReconcileDataPointsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.reconcile_data_points + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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.ReconcileDataPointsAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def roll_up_data_points( + self, + request: Optional[Union[data_points.RollUpDataPointsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.RollUpDataPointsAsyncPager: + r"""Roll up data points over physical time intervals for + supported data types. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + async def sample_roll_up_data_points(): + # Create a client + client = health_v4.DataPointsServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.RollUpDataPointsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.roll_up_data_points(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.devicesandservices.health_v4.types.RollUpDataPointsRequest, dict]]): + The request object. Request to roll up data points by + physical time intervals. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.services.data_points_service.pagers.RollUpDataPointsAsyncPager: + Response containing the list of + rolled up data points. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_points.RollUpDataPointsRequest): + request = data_points.RollUpDataPointsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.roll_up_data_points + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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.RollUpDataPointsAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def daily_roll_up_data_points( + self, + request: Optional[Union[data_points.DailyRollUpDataPointsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> data_points.DailyRollUpDataPointsResponse: + r"""Roll up data points over civil time intervals for + supported data types. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + async def sample_daily_roll_up_data_points(): + # Create a client + client = health_v4.DataPointsServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.DailyRollUpDataPointsRequest( + parent="parent_value", + ) + + # Make the request + response = await client.daily_roll_up_data_points(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.devicesandservices.health_v4.types.DailyRollUpDataPointsRequest, dict]]): + The request object. Request to roll up data points by + civil time intervals. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.types.DailyRollUpDataPointsResponse: + Response containing the list of + rolled up data points. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_points.DailyRollUpDataPointsRequest): + request = data_points.DailyRollUpDataPointsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.daily_roll_up_data_points + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def export_exercise_tcx( + self, + request: Optional[Union[data_points.ExportExerciseTcxRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> data_points.ExportExerciseTcxResponse: + r"""Exports exercise data in TCX format. + + **IMPORTANT:** HTTP clients must append ``?alt=media`` to the + request URL to download the raw TCX file. + + Example: + ``https://health.googleapis.com/v4/users/me/dataTypes/exercise/dataPoints/EXERCISE_ID:exportExerciseTcx?alt=media`` + + Without ``alt=media``, the server returns a JSON response + (``ExportExerciseTcxResponse``) which is intended primarily for + gRPC clients. + + **Note:** While the Authorization section below states that any + one of the listed scopes is accepted, this specific method + requires the user to provide both one of the + ``activity_and_fitness`` scopes (``normal`` or ``readonly``) AND + one of the ``location`` scopes (``normal`` or ``readonly``) in + their access token to succeed. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + async def sample_export_exercise_tcx(): + # Create a client + client = health_v4.DataPointsServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.ExportExerciseTcxRequest( + name="name_value", + ) + + # Make the request + response = await client.export_exercise_tcx(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.devicesandservices.health_v4.types.ExportExerciseTcxRequest, dict]]): + The request object. Represents a request to export + exercise data in TCX format. + name (:class:`str`): + Required. The resource name of the exercise data point + to export. + + Format: + ``users/{user}/dataTypes/exercise/dataPoints/{data_point}`` + Example: + ``users/me/dataTypes/exercise/dataPoints/2026443605080188808`` + + The ``{user}`` is the alias ``"me"`` currently. Future + versions may support user IDs. The ``{data_point}`` ID + maps to the exercise ID, which is a long integer. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.types.ExportExerciseTcxResponse: + Represents a Response for exporting + exercise data in TCX format. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_points.ExportExerciseTcxRequest): + request = data_points.ExportExerciseTcxRequest(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._client._transport._wrapped_methods[ + self._client._transport.export_exercise_tcx + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "DataPointsServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("DataPointsServiceAsyncClient",) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/client.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/client.py new file mode 100644 index 000000000000..4ee05ba8a573 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/client.py @@ -0,0 +1,1808 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 json +import logging as std_logging +import os +import re +import warnings +from collections import OrderedDict +from http import HTTPStatus +from typing import ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) + +import google.protobuf +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.devicesandservices.health_v4 import gapic_version as package_version + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + +import google.api_core.operation as operation # type: ignore +import google.api_core.operation_async as operation_async # type: ignore + +from google.devicesandservices.health_v4.services.data_points_service import pagers +from google.devicesandservices.health_v4.types import ( + data_model, + data_points, + data_source, +) + +from .transports.base import DEFAULT_CLIENT_INFO, DataPointsServiceTransport +from .transports.grpc import DataPointsServiceGrpcTransport +from .transports.grpc_asyncio import DataPointsServiceGrpcAsyncIOTransport +from .transports.rest import DataPointsServiceRestTransport + + +class DataPointsServiceClientMeta(type): + """Metaclass for the DataPointsService 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[DataPointsServiceTransport]] + _transport_registry["grpc"] = DataPointsServiceGrpcTransport + _transport_registry["grpc_asyncio"] = DataPointsServiceGrpcAsyncIOTransport + _transport_registry["rest"] = DataPointsServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[DataPointsServiceTransport]: + """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 DataPointsServiceClient(metaclass=DataPointsServiceClientMeta): + """Data Points Service exposing the user's health and fitness + measured and derived data. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint) -> Optional[str]: + """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: + Optional[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) + if m is None: + # Could not parse api_endpoint; return as-is. + return 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") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "health.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "health.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @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: + DataPointsServiceClient: 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: + DataPointsServiceClient: 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) -> DataPointsServiceTransport: + """Returns the transport used by the client instance. + + Returns: + DataPointsServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def data_point_path( + user: str, + data_type: str, + data_point: str, + ) -> str: + """Returns a fully-qualified data_point string.""" + return "users/{user}/dataTypes/{data_type}/dataPoints/{data_point}".format( + user=user, + data_type=data_type, + data_point=data_point, + ) + + @staticmethod + def parse_data_point_path(path: str) -> Dict[str, str]: + """Parses a data_point path into its component segments.""" + m = re.match( + r"^users/(?P.+?)/dataTypes/(?P.+?)/dataPoints/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def data_type_path( + user: str, + data_type: str, + ) -> str: + """Returns a fully-qualified data_type string.""" + return "users/{user}/dataTypes/{data_type}".format( + user=user, + data_type=data_type, + ) + + @staticmethod + def parse_data_type_path(path: str) -> Dict[str, str]: + """Parses a data_type path into its component segments.""" + m = re.match(r"^users/(?P.+?)/dataTypes/(?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 + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = DataPointsServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + 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: + 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 + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = DataPointsServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ) -> str: + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = DataPointsServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = DataPointsServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = DataPointsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], universe_domain_env: Optional[str] + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = DataPointsServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self) -> str: + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + DataPointsServiceTransport, + Callable[..., DataPointsServiceTransport], + ] + ] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the data points 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 (Optional[Union[str,DataPointsServiceTransport,Callable[..., DataPointsServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the DataPointsServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "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). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS 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. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + 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. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict(self._client_options) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr(self._client_options, "universe_domain", None) + + self._use_client_cert, self._use_mtls_endpoint, self._universe_domain_env = ( + DataPointsServiceClient._read_environment_variables() + ) + self._client_cert_source = DataPointsServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = DataPointsServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint: str = "" # updated below, depending on `transport` + + # Initialize the universe domain validation. + self._is_universe_domain_valid = False + + if CLIENT_LOGGING_SUPPORTED: # pragma: NO COVER + # Setup logging. + client_logging.initialize_logging() + + api_key_value = getattr(self._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. + transport_provided = isinstance(transport, DataPointsServiceTransport) + if transport_provided: + # transport is a DataPointsServiceTransport instance. + if credentials or self._client_options.credentials_file or api_key_value: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes directly." + ) + self._transport = cast(DataPointsServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or DataPointsServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + 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_init: Union[ + Type[DataPointsServiceTransport], + Callable[..., DataPointsServiceTransport], + ] = ( + DataPointsServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., DataPointsServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + api_audience=self._client_options.api_audience, + ) + + if "async" not in str(self._transport): + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.devicesandservices.health_v4.DataPointsServiceClient`.", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataPointsService", + "universeDomain": getattr( + self._transport._credentials, "universe_domain", "" + ), + "credentialsType": f"{type(self._transport._credentials).__module__}.{type(self._transport._credentials).__qualname__}", + "credentialsInfo": getattr( + self.transport._credentials, "get_cred_info", lambda: None + )(), + } + if hasattr(self._transport, "_credentials") + else { + "serviceName": "google.devicesandservices.health.v4.DataPointsService", + "credentialsType": None, + }, + ) + + def get_data_point( + self, + request: Optional[Union[data_points.GetDataPointRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> data_points.DataPoint: + r"""Get a single identifyable data point. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + def sample_get_data_point(): + # Create a client + client = health_v4.DataPointsServiceClient() + + # Initialize request argument(s) + request = health_v4.GetDataPointRequest( + name="name_value", + ) + + # Make the request + response = client.get_data_point(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.devicesandservices.health_v4.types.GetDataPointRequest, dict]): + The request object. Request for getting a single data + point + name (str): + Required. The name of the data point to retrieve. + + Format: + ``users/{user}/dataTypes/{data_type}/dataPoints/{data_point}`` + + See + [DataPoint.name][google.devicesandservices.health.v4.DataPoint.name] + for examples and possible values. + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.types.DataPoint: + A computed or recorded metric. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_points.GetDataPointRequest): + request = data_points.GetDataPointRequest(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_data_point] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_data_points( + self, + request: Optional[Union[data_points.ListDataPointsRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListDataPointsPager: + r"""Query user health and fitness data points. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + def sample_list_data_points(): + # Create a client + client = health_v4.DataPointsServiceClient() + + # Initialize request argument(s) + request = health_v4.ListDataPointsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_data_points(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.devicesandservices.health_v4.types.ListDataPointsRequest, dict]): + The request object. Request for listing raw data points + parent (str): + Required. Parent data type of the Data Point collection. + + Format: ``users/me/dataTypes/{data_type}``, e.g.: + + - ``users/me/dataTypes/steps`` + - ``users/me/dataTypes/weight`` + + For a list of the supported data types see the + [DataPoint + data][google.devicesandservices.health.v4.DataPoint] + union field. + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.services.data_points_service.pagers.ListDataPointsPager: + Response containing raw data points + matching the query + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_points.ListDataPointsRequest): + request = data_points.ListDataPointsRequest(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_data_points] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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.ListDataPointsPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def create_data_point( + self, + request: Optional[Union[data_points.CreateDataPointRequest, dict]] = None, + *, + parent: Optional[str] = None, + data_point: Optional[data_points.DataPoint] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Creates a single identifiable data point. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + def sample_create_data_point(): + # Create a client + client = health_v4.DataPointsServiceClient() + + # Initialize request argument(s) + request = health_v4.CreateDataPointRequest( + parent="parent_value", + ) + + # Make the request + operation = client.create_data_point(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.devicesandservices.health_v4.types.CreateDataPointRequest, dict]): + The request object. Request to create an identifiable + data point. + parent (str): + Required. The parent resource name where the data point + will be created. Format: + ``users/{user}/dataTypes/{data_type}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + data_point (google.devicesandservices.health_v4.types.DataPoint): + Required. The data point to create. + This corresponds to the ``data_point`` 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.devicesandservices.health_v4.types.DataPoint` + A computed or recorded metric. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, data_point] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_points.CreateDataPointRequest): + request = data_points.CreateDataPointRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if data_point is not None: + request.data_point = data_point + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_data_point] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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, + data_points.DataPoint, + metadata_type=data_points.CreateDataPointOperationMetadata, + ) + + # Done; return the response. + return response + + def update_data_point( + self, + request: Optional[Union[data_points.UpdateDataPointRequest, dict]] = None, + *, + data_point: Optional[data_points.DataPoint] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Updates a single identifiable data point. If a data point with + the specified ``name`` is not found, the request will fail. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + def sample_update_data_point(): + # Create a client + client = health_v4.DataPointsServiceClient() + + # Initialize request argument(s) + request = health_v4.UpdateDataPointRequest( + ) + + # Make the request + operation = client.update_data_point(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.devicesandservices.health_v4.types.UpdateDataPointRequest, dict]): + The request object. Request to update an identifiable + data point. + data_point (google.devicesandservices.health_v4.types.DataPoint): + Required. The data point to update + + The data point's ``name`` field is used to identify the + data point to update. + + Format: + ``users/{user}/dataTypes/{data_type}/dataPoints/{data_point}`` + + This corresponds to the ``data_point`` 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.devicesandservices.health_v4.types.DataPoint` + A computed or recorded metric. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [data_point] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_points.UpdateDataPointRequest): + request = data_points.UpdateDataPointRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if data_point is not None: + request.data_point = data_point + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_data_point] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("data_point.name", request.data_point.name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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, + data_points.DataPoint, + metadata_type=data_points.UpdateDataPointOperationMetadata, + ) + + # Done; return the response. + return response + + def batch_delete_data_points( + self, + request: Optional[Union[data_points.BatchDeleteDataPointsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Delete a batch of identifyable data points. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + def sample_batch_delete_data_points(): + # Create a client + client = health_v4.DataPointsServiceClient() + + # Initialize request argument(s) + request = health_v4.BatchDeleteDataPointsRequest( + names=['names_value1', 'names_value2'], + ) + + # Make the request + operation = client.batch_delete_data_points(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.devicesandservices.health_v4.types.BatchDeleteDataPointsRequest, dict]): + The request object. Request to delete a batch of + identifiable data points. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.devicesandservices.health_v4.types.BatchDeleteDataPointsResponse` + Response containing the list of possibly soft-deleted + DataPoints. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_points.BatchDeleteDataPointsRequest): + request = data_points.BatchDeleteDataPointsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.batch_delete_data_points] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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, + data_points.BatchDeleteDataPointsResponse, + metadata_type=data_points.BatchDeleteDataPointsOperationMetadata, + ) + + # Done; return the response. + return response + + def reconcile_data_points( + self, + request: Optional[Union[data_points.ReconcileDataPointsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ReconcileDataPointsPager: + r"""Reconcile data points from multiple data sources into + a single data stream. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + def sample_reconcile_data_points(): + # Create a client + client = health_v4.DataPointsServiceClient() + + # Initialize request argument(s) + request = health_v4.ReconcileDataPointsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.reconcile_data_points(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.devicesandservices.health_v4.types.ReconcileDataPointsRequest, dict]): + The request object. Request to reconcile data points from + multiple data sources. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.services.data_points_service.pagers.ReconcileDataPointsPager: + Response containing the list of + reconciled DataPoints. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_points.ReconcileDataPointsRequest): + request = data_points.ReconcileDataPointsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.reconcile_data_points] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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.ReconcileDataPointsPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def roll_up_data_points( + self, + request: Optional[Union[data_points.RollUpDataPointsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.RollUpDataPointsPager: + r"""Roll up data points over physical time intervals for + supported data types. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + def sample_roll_up_data_points(): + # Create a client + client = health_v4.DataPointsServiceClient() + + # Initialize request argument(s) + request = health_v4.RollUpDataPointsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.roll_up_data_points(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.devicesandservices.health_v4.types.RollUpDataPointsRequest, dict]): + The request object. Request to roll up data points by + physical time intervals. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.services.data_points_service.pagers.RollUpDataPointsPager: + Response containing the list of + rolled up data points. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_points.RollUpDataPointsRequest): + request = data_points.RollUpDataPointsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.roll_up_data_points] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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.RollUpDataPointsPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def daily_roll_up_data_points( + self, + request: Optional[Union[data_points.DailyRollUpDataPointsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> data_points.DailyRollUpDataPointsResponse: + r"""Roll up data points over civil time intervals for + supported data types. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + def sample_daily_roll_up_data_points(): + # Create a client + client = health_v4.DataPointsServiceClient() + + # Initialize request argument(s) + request = health_v4.DailyRollUpDataPointsRequest( + parent="parent_value", + ) + + # Make the request + response = client.daily_roll_up_data_points(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.devicesandservices.health_v4.types.DailyRollUpDataPointsRequest, dict]): + The request object. Request to roll up data points by + civil time intervals. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.types.DailyRollUpDataPointsResponse: + Response containing the list of + rolled up data points. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_points.DailyRollUpDataPointsRequest): + request = data_points.DailyRollUpDataPointsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.daily_roll_up_data_points + ] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def export_exercise_tcx( + self, + request: Optional[Union[data_points.ExportExerciseTcxRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> data_points.ExportExerciseTcxResponse: + r"""Exports exercise data in TCX format. + + **IMPORTANT:** HTTP clients must append ``?alt=media`` to the + request URL to download the raw TCX file. + + Example: + ``https://health.googleapis.com/v4/users/me/dataTypes/exercise/dataPoints/EXERCISE_ID:exportExerciseTcx?alt=media`` + + Without ``alt=media``, the server returns a JSON response + (``ExportExerciseTcxResponse``) which is intended primarily for + gRPC clients. + + **Note:** While the Authorization section below states that any + one of the listed scopes is accepted, this specific method + requires the user to provide both one of the + ``activity_and_fitness`` scopes (``normal`` or ``readonly``) AND + one of the ``location`` scopes (``normal`` or ``readonly``) in + their access token to succeed. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + def sample_export_exercise_tcx(): + # Create a client + client = health_v4.DataPointsServiceClient() + + # Initialize request argument(s) + request = health_v4.ExportExerciseTcxRequest( + name="name_value", + ) + + # Make the request + response = client.export_exercise_tcx(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.devicesandservices.health_v4.types.ExportExerciseTcxRequest, dict]): + The request object. Represents a request to export + exercise data in TCX format. + name (str): + Required. The resource name of the exercise data point + to export. + + Format: + ``users/{user}/dataTypes/exercise/dataPoints/{data_point}`` + Example: + ``users/me/dataTypes/exercise/dataPoints/2026443605080188808`` + + The ``{user}`` is the alias ``"me"`` currently. Future + versions may support user IDs. The ``{data_point}`` ID + maps to the exercise ID, which is a long integer. + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.types.ExportExerciseTcxResponse: + Represents a Response for exporting + exercise data in TCX format. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_points.ExportExerciseTcxRequest): + request = data_points.ExportExerciseTcxRequest(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.export_exercise_tcx] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "DataPointsServiceClient": + 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() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("DataPointsServiceClient",) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/pagers.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/pagers.py new file mode 100644 index 000000000000..4a8ffae9f0e5 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/pagers.py @@ -0,0 +1,509 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, + Union, +) + +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import retry_async as retries_async + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] + OptionalAsyncRetry = Union[ + retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore + +from google.devicesandservices.health_v4.types import data_points + + +class ListDataPointsPager: + """A pager for iterating through ``list_data_points`` requests. + + This class thinly wraps an initial + :class:`google.devicesandservices.health_v4.types.ListDataPointsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``data_points`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListDataPoints`` requests and continue to iterate + through the ``data_points`` field on the + corresponding responses. + + All the usual :class:`google.devicesandservices.health_v4.types.ListDataPointsResponse` + 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[..., data_points.ListDataPointsResponse], + request: data_points.ListDataPointsRequest, + response: data_points.ListDataPointsResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.devicesandservices.health_v4.types.ListDataPointsRequest): + The initial request object. + response (google.devicesandservices.health_v4.types.ListDataPointsResponse): + The initial response object. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = data_points.ListDataPointsRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[data_points.ListDataPointsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __iter__(self) -> Iterator[data_points.DataPoint]: + for page in self.pages: + yield from page.data_points + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListDataPointsAsyncPager: + """A pager for iterating through ``list_data_points`` requests. + + This class thinly wraps an initial + :class:`google.devicesandservices.health_v4.types.ListDataPointsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``data_points`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListDataPoints`` requests and continue to iterate + through the ``data_points`` field on the + corresponding responses. + + All the usual :class:`google.devicesandservices.health_v4.types.ListDataPointsResponse` + 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[data_points.ListDataPointsResponse]], + request: data_points.ListDataPointsRequest, + response: data_points.ListDataPointsResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.devicesandservices.health_v4.types.ListDataPointsRequest): + The initial request object. + response (google.devicesandservices.health_v4.types.ListDataPointsResponse): + The initial response object. + retry (google.api_core.retry.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = data_points.ListDataPointsRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[data_points.ListDataPointsResponse]: + 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, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __aiter__(self) -> AsyncIterator[data_points.DataPoint]: + async def async_generator(): + async for page in self.pages: + for response in page.data_points: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ReconcileDataPointsPager: + """A pager for iterating through ``reconcile_data_points`` requests. + + This class thinly wraps an initial + :class:`google.devicesandservices.health_v4.types.ReconcileDataPointsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``data_points`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ReconcileDataPoints`` requests and continue to iterate + through the ``data_points`` field on the + corresponding responses. + + All the usual :class:`google.devicesandservices.health_v4.types.ReconcileDataPointsResponse` + 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[..., data_points.ReconcileDataPointsResponse], + request: data_points.ReconcileDataPointsRequest, + response: data_points.ReconcileDataPointsResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.devicesandservices.health_v4.types.ReconcileDataPointsRequest): + The initial request object. + response (google.devicesandservices.health_v4.types.ReconcileDataPointsResponse): + The initial response object. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = data_points.ReconcileDataPointsRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[data_points.ReconcileDataPointsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __iter__(self) -> Iterator[data_points.ReconciledDataPoint]: + for page in self.pages: + yield from page.data_points + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ReconcileDataPointsAsyncPager: + """A pager for iterating through ``reconcile_data_points`` requests. + + This class thinly wraps an initial + :class:`google.devicesandservices.health_v4.types.ReconcileDataPointsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``data_points`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ReconcileDataPoints`` requests and continue to iterate + through the ``data_points`` field on the + corresponding responses. + + All the usual :class:`google.devicesandservices.health_v4.types.ReconcileDataPointsResponse` + 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[data_points.ReconcileDataPointsResponse]], + request: data_points.ReconcileDataPointsRequest, + response: data_points.ReconcileDataPointsResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.devicesandservices.health_v4.types.ReconcileDataPointsRequest): + The initial request object. + response (google.devicesandservices.health_v4.types.ReconcileDataPointsResponse): + The initial response object. + retry (google.api_core.retry.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = data_points.ReconcileDataPointsRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[data_points.ReconcileDataPointsResponse]: + 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, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __aiter__(self) -> AsyncIterator[data_points.ReconciledDataPoint]: + async def async_generator(): + async for page in self.pages: + for response in page.data_points: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class RollUpDataPointsPager: + """A pager for iterating through ``roll_up_data_points`` requests. + + This class thinly wraps an initial + :class:`google.devicesandservices.health_v4.types.RollUpDataPointsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``rollup_data_points`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``RollUpDataPoints`` requests and continue to iterate + through the ``rollup_data_points`` field on the + corresponding responses. + + All the usual :class:`google.devicesandservices.health_v4.types.RollUpDataPointsResponse` + 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[..., data_points.RollUpDataPointsResponse], + request: data_points.RollUpDataPointsRequest, + response: data_points.RollUpDataPointsResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.devicesandservices.health_v4.types.RollUpDataPointsRequest): + The initial request object. + response (google.devicesandservices.health_v4.types.RollUpDataPointsResponse): + The initial response object. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = data_points.RollUpDataPointsRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[data_points.RollUpDataPointsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __iter__(self) -> Iterator[data_points.RollupDataPoint]: + for page in self.pages: + yield from page.rollup_data_points + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class RollUpDataPointsAsyncPager: + """A pager for iterating through ``roll_up_data_points`` requests. + + This class thinly wraps an initial + :class:`google.devicesandservices.health_v4.types.RollUpDataPointsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``rollup_data_points`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``RollUpDataPoints`` requests and continue to iterate + through the ``rollup_data_points`` field on the + corresponding responses. + + All the usual :class:`google.devicesandservices.health_v4.types.RollUpDataPointsResponse` + 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[data_points.RollUpDataPointsResponse]], + request: data_points.RollUpDataPointsRequest, + response: data_points.RollUpDataPointsResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.devicesandservices.health_v4.types.RollUpDataPointsRequest): + The initial request object. + response (google.devicesandservices.health_v4.types.RollUpDataPointsResponse): + The initial response object. + retry (google.api_core.retry.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = data_points.RollUpDataPointsRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[data_points.RollUpDataPointsResponse]: + 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, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __aiter__(self) -> AsyncIterator[data_points.RollupDataPoint]: + async def async_generator(): + async for page in self.pages: + for response in page.rollup_data_points: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/transports/README.rst b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/transports/README.rst new file mode 100644 index 000000000000..c55b237eaad3 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/transports/README.rst @@ -0,0 +1,10 @@ + +transport inheritance structure +_______________________________ + +``DataPointsServiceTransport`` is the ABC for all transports. + +- public child ``DataPointsServiceGrpcTransport`` for sync gRPC transport (defined in ``grpc.py``). +- public child ``DataPointsServiceGrpcAsyncIOTransport`` for async gRPC transport (defined in ``grpc_asyncio.py``). +- private child ``_BaseDataPointsServiceRestTransport`` for base REST transport with inner classes ``_BaseMETHOD`` (defined in ``rest_base.py``). +- public child ``DataPointsServiceRestTransport`` for sync REST transport with inner classes ``METHOD`` derived from the parent's corresponding ``_BaseMETHOD`` classes (defined in ``rest.py``). diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/transports/__init__.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/transports/__init__.py new file mode 100644 index 000000000000..603e59d4cc1d --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/transports/__init__.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 DataPointsServiceTransport +from .grpc import DataPointsServiceGrpcTransport +from .grpc_asyncio import DataPointsServiceGrpcAsyncIOTransport +from .rest import DataPointsServiceRestInterceptor, DataPointsServiceRestTransport + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[DataPointsServiceTransport]] +_transport_registry["grpc"] = DataPointsServiceGrpcTransport +_transport_registry["grpc_asyncio"] = DataPointsServiceGrpcAsyncIOTransport +_transport_registry["rest"] = DataPointsServiceRestTransport + +__all__ = ( + "DataPointsServiceTransport", + "DataPointsServiceGrpcTransport", + "DataPointsServiceGrpcAsyncIOTransport", + "DataPointsServiceRestTransport", + "DataPointsServiceRestInterceptor", +) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/transports/base.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/transports/base.py new file mode 100644 index 000000000000..b4ea418280f4 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/transports/base.py @@ -0,0 +1,376 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union + +import google.api_core +import google.auth # type: ignore +import google.protobuf +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, operations_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.devicesandservices.health_v4 import gapic_version as package_version +from google.devicesandservices.health_v4.types import data_points + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class DataPointsServiceTransport(abc.ABC): + """Abstract transport class for DataPointsService.""" + + AUTH_SCOPES = ( + "https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly", + "https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.readonly", + "https://www.googleapis.com/auth/googlehealth.location.readonly", + "https://www.googleapis.com/auth/googlehealth.sleep.readonly", + ) + + DEFAULT_HOST: str = "health.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'health.googleapis.com'). + 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]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + 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. + api_audience (Optional[str]): The intended audience for the API calls + to the service that will be set when using certain 3rd party + authentication flows. Audience is typically a resource identifier. + If not set, the host value will be used as a default. + """ + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # 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=scopes, + quota_project_id=quota_project_id, + default_scopes=self.AUTH_SCOPES, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + scopes=scopes, + quota_project_id=quota_project_id, + default_scopes=self.AUTH_SCOPES, + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr(service_account.Credentials, "with_always_use_jwt_access") + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + self._wrapped_methods: Dict[Callable, Callable] = {} + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.get_data_point: gapic_v1.method.wrap_method( + self.get_data_point, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.list_data_points: gapic_v1.method.wrap_method( + self.list_data_points, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.create_data_point: gapic_v1.method.wrap_method( + self.create_data_point, + default_timeout=60.0, + client_info=client_info, + ), + self.update_data_point: gapic_v1.method.wrap_method( + self.update_data_point, + default_timeout=60.0, + client_info=client_info, + ), + self.batch_delete_data_points: gapic_v1.method.wrap_method( + self.batch_delete_data_points, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.reconcile_data_points: gapic_v1.method.wrap_method( + self.reconcile_data_points, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.roll_up_data_points: gapic_v1.method.wrap_method( + self.roll_up_data_points, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.daily_roll_up_data_points: gapic_v1.method.wrap_method( + self.daily_roll_up_data_points, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.export_exercise_tcx: gapic_v1.method.wrap_method( + self.export_exercise_tcx, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + 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 get_data_point( + self, + ) -> Callable[ + [data_points.GetDataPointRequest], + Union[data_points.DataPoint, Awaitable[data_points.DataPoint]], + ]: + raise NotImplementedError() + + @property + def list_data_points( + self, + ) -> Callable[ + [data_points.ListDataPointsRequest], + Union[ + data_points.ListDataPointsResponse, + Awaitable[data_points.ListDataPointsResponse], + ], + ]: + raise NotImplementedError() + + @property + def create_data_point( + self, + ) -> Callable[ + [data_points.CreateDataPointRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def update_data_point( + self, + ) -> Callable[ + [data_points.UpdateDataPointRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def batch_delete_data_points( + self, + ) -> Callable[ + [data_points.BatchDeleteDataPointsRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def reconcile_data_points( + self, + ) -> Callable[ + [data_points.ReconcileDataPointsRequest], + Union[ + data_points.ReconcileDataPointsResponse, + Awaitable[data_points.ReconcileDataPointsResponse], + ], + ]: + raise NotImplementedError() + + @property + def roll_up_data_points( + self, + ) -> Callable[ + [data_points.RollUpDataPointsRequest], + Union[ + data_points.RollUpDataPointsResponse, + Awaitable[data_points.RollUpDataPointsResponse], + ], + ]: + raise NotImplementedError() + + @property + def daily_roll_up_data_points( + self, + ) -> Callable[ + [data_points.DailyRollUpDataPointsRequest], + Union[ + data_points.DailyRollUpDataPointsResponse, + Awaitable[data_points.DailyRollUpDataPointsResponse], + ], + ]: + raise NotImplementedError() + + @property + def export_exercise_tcx( + self, + ) -> Callable[ + [data_points.ExportExerciseTcxRequest], + Union[ + data_points.ExportExerciseTcxResponse, + Awaitable[data_points.ExportExerciseTcxResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("DataPointsServiceTransport",) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/transports/grpc.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/transports/grpc.py new file mode 100644 index 000000000000..81a3de106268 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/transports/grpc.py @@ -0,0 +1,622 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 json +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +import google.auth # type: ignore +import google.protobuf.message +import grpc # type: ignore +import proto # type: ignore +from google.api_core import gapic_v1, grpc_helpers, operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson + +from google.devicesandservices.health_v4.types import data_points + +from .base import DEFAULT_CLIENT_INFO, DataPointsServiceTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor(grpc.UnaryUnaryClientInterceptor): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = f"{type(request).__name__}: {pickle.dumps(request)!r}" + + request_metadata = { + key: value.decode("utf-8") if isinstance(value, bytes) else value + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataPointsService", + "rpcName": str(client_call_details.method), + "request": grpc_request, + "metadata": grpc_request["metadata"], + }, + ) + response = continuation(client_call_details, request) + if logging_enabled: # pragma: NO COVER + response_metadata = response.trailing_metadata() + # Convert gRPC metadata `` to list of tuples + metadata = ( + dict([(k, str(v)) for k, v in response_metadata]) + if response_metadata + else None + ) + result = response.result() + if isinstance(result, proto.Message): + response_payload = type(result).to_json(result) + elif isinstance(result, google.protobuf.message.Message): + response_payload = MessageToJson(result) + else: + response_payload = f"{type(result).__name__}: {pickle.dumps(result)!r}" + grpc_response = { + "payload": response_payload, + "metadata": metadata, + "status": "OK", + } + _LOGGER.debug( + f"Received response for {client_call_details.method}.", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataPointsService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class DataPointsServiceGrpcTransport(DataPointsServiceTransport): + """gRPC backend transport for DataPointsService. + + Data Points Service exposing the user's health and fitness + measured and derived data. + + 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 = "health.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'health.googleapis.com'). + 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 a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + 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 a ``channel`` instance 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 a ``channel`` instance 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. + api_audience (Optional[str]): The intended audience for the API calls + to the service that will be set when using certain 3rd party + authentication flows. Audience is typically a resource identifier. + If not set, the host value will be used as a default. + + 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 isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + self._interceptor = _LoggingClientInterceptor() + self._logged_channel = grpc.intercept_channel( + self._grpc_channel, self._interceptor + ) + + # Wrap messages. This must be done after self._logged_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "health.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsClient( + self._logged_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def get_data_point( + self, + ) -> Callable[[data_points.GetDataPointRequest], data_points.DataPoint]: + r"""Return a callable for the get data point method over gRPC. + + Get a single identifyable data point. + + Returns: + Callable[[~.GetDataPointRequest], + ~.DataPoint]: + 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_data_point" not in self._stubs: + self._stubs["get_data_point"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataPointsService/GetDataPoint", + request_serializer=data_points.GetDataPointRequest.serialize, + response_deserializer=data_points.DataPoint.deserialize, + ) + return self._stubs["get_data_point"] + + @property + def list_data_points( + self, + ) -> Callable[ + [data_points.ListDataPointsRequest], data_points.ListDataPointsResponse + ]: + r"""Return a callable for the list data points method over gRPC. + + Query user health and fitness data points. + + Returns: + Callable[[~.ListDataPointsRequest], + ~.ListDataPointsResponse]: + 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_data_points" not in self._stubs: + self._stubs["list_data_points"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataPointsService/ListDataPoints", + request_serializer=data_points.ListDataPointsRequest.serialize, + response_deserializer=data_points.ListDataPointsResponse.deserialize, + ) + return self._stubs["list_data_points"] + + @property + def create_data_point( + self, + ) -> Callable[[data_points.CreateDataPointRequest], operations_pb2.Operation]: + r"""Return a callable for the create data point method over gRPC. + + Creates a single identifiable data point. + + Returns: + Callable[[~.CreateDataPointRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_data_point" not in self._stubs: + self._stubs["create_data_point"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataPointsService/CreateDataPoint", + request_serializer=data_points.CreateDataPointRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["create_data_point"] + + @property + def update_data_point( + self, + ) -> Callable[[data_points.UpdateDataPointRequest], operations_pb2.Operation]: + r"""Return a callable for the update data point method over gRPC. + + Updates a single identifiable data point. If a data point with + the specified ``name`` is not found, the request will fail. + + Returns: + Callable[[~.UpdateDataPointRequest], + ~.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 "update_data_point" not in self._stubs: + self._stubs["update_data_point"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataPointsService/UpdateDataPoint", + request_serializer=data_points.UpdateDataPointRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["update_data_point"] + + @property + def batch_delete_data_points( + self, + ) -> Callable[[data_points.BatchDeleteDataPointsRequest], operations_pb2.Operation]: + r"""Return a callable for the batch delete data points method over gRPC. + + Delete a batch of identifyable data points. + + Returns: + Callable[[~.BatchDeleteDataPointsRequest], + ~.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 "batch_delete_data_points" not in self._stubs: + self._stubs["batch_delete_data_points"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataPointsService/BatchDeleteDataPoints", + request_serializer=data_points.BatchDeleteDataPointsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["batch_delete_data_points"] + + @property + def reconcile_data_points( + self, + ) -> Callable[ + [data_points.ReconcileDataPointsRequest], + data_points.ReconcileDataPointsResponse, + ]: + r"""Return a callable for the reconcile data points method over gRPC. + + Reconcile data points from multiple data sources into + a single data stream. + + Returns: + Callable[[~.ReconcileDataPointsRequest], + ~.ReconcileDataPointsResponse]: + 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 "reconcile_data_points" not in self._stubs: + self._stubs["reconcile_data_points"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataPointsService/ReconcileDataPoints", + request_serializer=data_points.ReconcileDataPointsRequest.serialize, + response_deserializer=data_points.ReconcileDataPointsResponse.deserialize, + ) + return self._stubs["reconcile_data_points"] + + @property + def roll_up_data_points( + self, + ) -> Callable[ + [data_points.RollUpDataPointsRequest], data_points.RollUpDataPointsResponse + ]: + r"""Return a callable for the roll up data points method over gRPC. + + Roll up data points over physical time intervals for + supported data types. + + Returns: + Callable[[~.RollUpDataPointsRequest], + ~.RollUpDataPointsResponse]: + 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 "roll_up_data_points" not in self._stubs: + self._stubs["roll_up_data_points"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataPointsService/RollUpDataPoints", + request_serializer=data_points.RollUpDataPointsRequest.serialize, + response_deserializer=data_points.RollUpDataPointsResponse.deserialize, + ) + return self._stubs["roll_up_data_points"] + + @property + def daily_roll_up_data_points( + self, + ) -> Callable[ + [data_points.DailyRollUpDataPointsRequest], + data_points.DailyRollUpDataPointsResponse, + ]: + r"""Return a callable for the daily roll up data points method over gRPC. + + Roll up data points over civil time intervals for + supported data types. + + Returns: + Callable[[~.DailyRollUpDataPointsRequest], + ~.DailyRollUpDataPointsResponse]: + 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 "daily_roll_up_data_points" not in self._stubs: + self._stubs["daily_roll_up_data_points"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataPointsService/DailyRollUpDataPoints", + request_serializer=data_points.DailyRollUpDataPointsRequest.serialize, + response_deserializer=data_points.DailyRollUpDataPointsResponse.deserialize, + ) + return self._stubs["daily_roll_up_data_points"] + + @property + def export_exercise_tcx( + self, + ) -> Callable[ + [data_points.ExportExerciseTcxRequest], data_points.ExportExerciseTcxResponse + ]: + r"""Return a callable for the export exercise tcx method over gRPC. + + Exports exercise data in TCX format. + + **IMPORTANT:** HTTP clients must append ``?alt=media`` to the + request URL to download the raw TCX file. + + Example: + ``https://health.googleapis.com/v4/users/me/dataTypes/exercise/dataPoints/EXERCISE_ID:exportExerciseTcx?alt=media`` + + Without ``alt=media``, the server returns a JSON response + (``ExportExerciseTcxResponse``) which is intended primarily for + gRPC clients. + + **Note:** While the Authorization section below states that any + one of the listed scopes is accepted, this specific method + requires the user to provide both one of the + ``activity_and_fitness`` scopes (``normal`` or ``readonly``) AND + one of the ``location`` scopes (``normal`` or ``readonly``) in + their access token to succeed. + + Returns: + Callable[[~.ExportExerciseTcxRequest], + ~.ExportExerciseTcxResponse]: + 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 "export_exercise_tcx" not in self._stubs: + self._stubs["export_exercise_tcx"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataPointsService/ExportExerciseTcx", + request_serializer=data_points.ExportExerciseTcxRequest.serialize, + response_deserializer=data_points.ExportExerciseTcxResponse.deserialize, + ) + return self._stubs["export_exercise_tcx"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("DataPointsServiceGrpcTransport",) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/transports/grpc_asyncio.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/transports/grpc_asyncio.py new file mode 100644 index 000000000000..eb603576d74f --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/transports/grpc_asyncio.py @@ -0,0 +1,757 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 inspect +import json +import logging as std_logging +import pickle +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +import google.protobuf.message +import grpc # type: ignore +import proto # type: ignore +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, grpc_helpers_async, operations_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +from grpc.experimental import aio # type: ignore + +from google.devicesandservices.health_v4.types import data_points + +from .base import DEFAULT_CLIENT_INFO, DataPointsServiceTransport +from .grpc import DataPointsServiceGrpcTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientAIOInterceptor( + grpc.aio.UnaryUnaryClientInterceptor +): # pragma: NO COVER + async def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = f"{type(request).__name__}: {pickle.dumps(request)!r}" + + request_metadata = { + key: value.decode("utf-8") if isinstance(value, bytes) else value + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataPointsService", + "rpcName": str(client_call_details.method), + "request": grpc_request, + "metadata": grpc_request["metadata"], + }, + ) + response = await continuation(client_call_details, request) + if logging_enabled: # pragma: NO COVER + response_metadata = await response.trailing_metadata() + # Convert gRPC metadata `` to list of tuples + metadata = ( + dict([(k, str(v)) for k, v in response_metadata]) + if response_metadata + else None + ) + result = await response + if isinstance(result, proto.Message): + response_payload = type(result).to_json(result) + elif isinstance(result, google.protobuf.message.Message): + response_payload = MessageToJson(result) + else: + response_payload = f"{type(result).__name__}: {pickle.dumps(result)!r}" + grpc_response = { + "payload": response_payload, + "metadata": metadata, + "status": "OK", + } + _LOGGER.debug( + f"Received response to rpc {client_call_details.method}.", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataPointsService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class DataPointsServiceGrpcAsyncIOTransport(DataPointsServiceTransport): + """gRPC AsyncIO backend transport for DataPointsService. + + Data Points Service exposing the user's health and fitness + measured and derived data. + + 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 = "health.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + 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 = "health.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[Union[aio.Channel, Callable[..., aio.Channel]]] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'health.googleapis.com'). + 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 a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + 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[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + 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 a ``channel`` instance 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 a ``channel`` instance 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. + api_audience (Optional[str]): The intended audience for the API calls + to the service that will be set when using certain 3rd party + authentication flows. Audience is typically a resource identifier. + If not set, the host value will be used as a default. + + 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 isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + self._interceptor = _LoggingClientAIOInterceptor() + self._grpc_channel._unary_unary_interceptors.append(self._interceptor) + self._logged_channel = self._grpc_channel + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) + # Wrap messages. This must be done after self._logged_channel exists + self._prep_wrapped_messages(client_info) + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsAsyncClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsAsyncClient( + self._logged_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def get_data_point( + self, + ) -> Callable[[data_points.GetDataPointRequest], Awaitable[data_points.DataPoint]]: + r"""Return a callable for the get data point method over gRPC. + + Get a single identifyable data point. + + Returns: + Callable[[~.GetDataPointRequest], + Awaitable[~.DataPoint]]: + 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_data_point" not in self._stubs: + self._stubs["get_data_point"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataPointsService/GetDataPoint", + request_serializer=data_points.GetDataPointRequest.serialize, + response_deserializer=data_points.DataPoint.deserialize, + ) + return self._stubs["get_data_point"] + + @property + def list_data_points( + self, + ) -> Callable[ + [data_points.ListDataPointsRequest], + Awaitable[data_points.ListDataPointsResponse], + ]: + r"""Return a callable for the list data points method over gRPC. + + Query user health and fitness data points. + + Returns: + Callable[[~.ListDataPointsRequest], + Awaitable[~.ListDataPointsResponse]]: + 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_data_points" not in self._stubs: + self._stubs["list_data_points"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataPointsService/ListDataPoints", + request_serializer=data_points.ListDataPointsRequest.serialize, + response_deserializer=data_points.ListDataPointsResponse.deserialize, + ) + return self._stubs["list_data_points"] + + @property + def create_data_point( + self, + ) -> Callable[ + [data_points.CreateDataPointRequest], Awaitable[operations_pb2.Operation] + ]: + r"""Return a callable for the create data point method over gRPC. + + Creates a single identifiable data point. + + Returns: + Callable[[~.CreateDataPointRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_data_point" not in self._stubs: + self._stubs["create_data_point"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataPointsService/CreateDataPoint", + request_serializer=data_points.CreateDataPointRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["create_data_point"] + + @property + def update_data_point( + self, + ) -> Callable[ + [data_points.UpdateDataPointRequest], Awaitable[operations_pb2.Operation] + ]: + r"""Return a callable for the update data point method over gRPC. + + Updates a single identifiable data point. If a data point with + the specified ``name`` is not found, the request will fail. + + Returns: + Callable[[~.UpdateDataPointRequest], + 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 "update_data_point" not in self._stubs: + self._stubs["update_data_point"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataPointsService/UpdateDataPoint", + request_serializer=data_points.UpdateDataPointRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["update_data_point"] + + @property + def batch_delete_data_points( + self, + ) -> Callable[ + [data_points.BatchDeleteDataPointsRequest], Awaitable[operations_pb2.Operation] + ]: + r"""Return a callable for the batch delete data points method over gRPC. + + Delete a batch of identifyable data points. + + Returns: + Callable[[~.BatchDeleteDataPointsRequest], + 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 "batch_delete_data_points" not in self._stubs: + self._stubs["batch_delete_data_points"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataPointsService/BatchDeleteDataPoints", + request_serializer=data_points.BatchDeleteDataPointsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["batch_delete_data_points"] + + @property + def reconcile_data_points( + self, + ) -> Callable[ + [data_points.ReconcileDataPointsRequest], + Awaitable[data_points.ReconcileDataPointsResponse], + ]: + r"""Return a callable for the reconcile data points method over gRPC. + + Reconcile data points from multiple data sources into + a single data stream. + + Returns: + Callable[[~.ReconcileDataPointsRequest], + Awaitable[~.ReconcileDataPointsResponse]]: + 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 "reconcile_data_points" not in self._stubs: + self._stubs["reconcile_data_points"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataPointsService/ReconcileDataPoints", + request_serializer=data_points.ReconcileDataPointsRequest.serialize, + response_deserializer=data_points.ReconcileDataPointsResponse.deserialize, + ) + return self._stubs["reconcile_data_points"] + + @property + def roll_up_data_points( + self, + ) -> Callable[ + [data_points.RollUpDataPointsRequest], + Awaitable[data_points.RollUpDataPointsResponse], + ]: + r"""Return a callable for the roll up data points method over gRPC. + + Roll up data points over physical time intervals for + supported data types. + + Returns: + Callable[[~.RollUpDataPointsRequest], + Awaitable[~.RollUpDataPointsResponse]]: + 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 "roll_up_data_points" not in self._stubs: + self._stubs["roll_up_data_points"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataPointsService/RollUpDataPoints", + request_serializer=data_points.RollUpDataPointsRequest.serialize, + response_deserializer=data_points.RollUpDataPointsResponse.deserialize, + ) + return self._stubs["roll_up_data_points"] + + @property + def daily_roll_up_data_points( + self, + ) -> Callable[ + [data_points.DailyRollUpDataPointsRequest], + Awaitable[data_points.DailyRollUpDataPointsResponse], + ]: + r"""Return a callable for the daily roll up data points method over gRPC. + + Roll up data points over civil time intervals for + supported data types. + + Returns: + Callable[[~.DailyRollUpDataPointsRequest], + Awaitable[~.DailyRollUpDataPointsResponse]]: + 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 "daily_roll_up_data_points" not in self._stubs: + self._stubs["daily_roll_up_data_points"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataPointsService/DailyRollUpDataPoints", + request_serializer=data_points.DailyRollUpDataPointsRequest.serialize, + response_deserializer=data_points.DailyRollUpDataPointsResponse.deserialize, + ) + return self._stubs["daily_roll_up_data_points"] + + @property + def export_exercise_tcx( + self, + ) -> Callable[ + [data_points.ExportExerciseTcxRequest], + Awaitable[data_points.ExportExerciseTcxResponse], + ]: + r"""Return a callable for the export exercise tcx method over gRPC. + + Exports exercise data in TCX format. + + **IMPORTANT:** HTTP clients must append ``?alt=media`` to the + request URL to download the raw TCX file. + + Example: + ``https://health.googleapis.com/v4/users/me/dataTypes/exercise/dataPoints/EXERCISE_ID:exportExerciseTcx?alt=media`` + + Without ``alt=media``, the server returns a JSON response + (``ExportExerciseTcxResponse``) which is intended primarily for + gRPC clients. + + **Note:** While the Authorization section below states that any + one of the listed scopes is accepted, this specific method + requires the user to provide both one of the + ``activity_and_fitness`` scopes (``normal`` or ``readonly``) AND + one of the ``location`` scopes (``normal`` or ``readonly``) in + their access token to succeed. + + Returns: + Callable[[~.ExportExerciseTcxRequest], + Awaitable[~.ExportExerciseTcxResponse]]: + 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 "export_exercise_tcx" not in self._stubs: + self._stubs["export_exercise_tcx"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataPointsService/ExportExerciseTcx", + request_serializer=data_points.ExportExerciseTcxRequest.serialize, + response_deserializer=data_points.ExportExerciseTcxResponse.deserialize, + ) + return self._stubs["export_exercise_tcx"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.get_data_point: self._wrap_method( + self.get_data_point, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.list_data_points: self._wrap_method( + self.list_data_points, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.create_data_point: self._wrap_method( + self.create_data_point, + default_timeout=60.0, + client_info=client_info, + ), + self.update_data_point: self._wrap_method( + self.update_data_point, + default_timeout=60.0, + client_info=client_info, + ), + self.batch_delete_data_points: self._wrap_method( + self.batch_delete_data_points, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.reconcile_data_points: self._wrap_method( + self.reconcile_data_points, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.roll_up_data_points: self._wrap_method( + self.roll_up_data_points, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.daily_roll_up_data_points: self._wrap_method( + self.daily_roll_up_data_points, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.export_exercise_tcx: self._wrap_method( + self.export_exercise_tcx, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("DataPointsServiceGrpcAsyncIOTransport",) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/transports/rest.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/transports/rest.py new file mode 100644 index 000000000000..76e3e4e15eaa --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/transports/rest.py @@ -0,0 +1,2183 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +import warnings +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +import google.protobuf +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, operations_v1, rest_helpers, rest_streaming +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.devicesandservices.health_v4.types import data_points + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseDataPointsServiceRestTransport + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class DataPointsServiceRestInterceptor: + """Interceptor for DataPointsService. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the DataPointsServiceRestTransport. + + .. code-block:: python + class MyCustomDataPointsServiceInterceptor(DataPointsServiceRestInterceptor): + def pre_batch_delete_data_points(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_delete_data_points(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_create_data_point(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_data_point(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_daily_roll_up_data_points(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_daily_roll_up_data_points(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_export_exercise_tcx(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_export_exercise_tcx(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_data_point(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_data_point(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_data_points(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_data_points(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_reconcile_data_points(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_reconcile_data_points(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_roll_up_data_points(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_roll_up_data_points(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_data_point(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_data_point(self, response): + logging.log(f"Received response: {response}") + return response + + transport = DataPointsServiceRestTransport(interceptor=MyCustomDataPointsServiceInterceptor()) + client = DataPointsServiceClient(transport=transport) + + + """ + + def pre_batch_delete_data_points( + self, + request: data_points.BatchDeleteDataPointsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + data_points.BatchDeleteDataPointsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for batch_delete_data_points + + Override in a subclass to manipulate the request or metadata + before they are sent to the DataPointsService server. + """ + return request, metadata + + def post_batch_delete_data_points( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for batch_delete_data_points + + DEPRECATED. Please use the `post_batch_delete_data_points_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the DataPointsService server but before + it is returned to user code. This `post_batch_delete_data_points` interceptor runs + before the `post_batch_delete_data_points_with_metadata` interceptor. + """ + return response + + def post_batch_delete_data_points_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for batch_delete_data_points + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataPointsService server but before it is returned to user code. + + We recommend only using this `post_batch_delete_data_points_with_metadata` + interceptor in new development instead of the `post_batch_delete_data_points` interceptor. + When both interceptors are used, this `post_batch_delete_data_points_with_metadata` interceptor runs after the + `post_batch_delete_data_points` interceptor. The (possibly modified) response returned by + `post_batch_delete_data_points` will be passed to + `post_batch_delete_data_points_with_metadata`. + """ + return response, metadata + + def pre_create_data_point( + self, + request: data_points.CreateDataPointRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + data_points.CreateDataPointRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for create_data_point + + Override in a subclass to manipulate the request or metadata + before they are sent to the DataPointsService server. + """ + return request, metadata + + def post_create_data_point( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for create_data_point + + DEPRECATED. Please use the `post_create_data_point_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the DataPointsService server but before + it is returned to user code. This `post_create_data_point` interceptor runs + before the `post_create_data_point_with_metadata` interceptor. + """ + return response + + def post_create_data_point_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_data_point + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataPointsService server but before it is returned to user code. + + We recommend only using this `post_create_data_point_with_metadata` + interceptor in new development instead of the `post_create_data_point` interceptor. + When both interceptors are used, this `post_create_data_point_with_metadata` interceptor runs after the + `post_create_data_point` interceptor. The (possibly modified) response returned by + `post_create_data_point` will be passed to + `post_create_data_point_with_metadata`. + """ + return response, metadata + + def pre_daily_roll_up_data_points( + self, + request: data_points.DailyRollUpDataPointsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + data_points.DailyRollUpDataPointsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for daily_roll_up_data_points + + Override in a subclass to manipulate the request or metadata + before they are sent to the DataPointsService server. + """ + return request, metadata + + def post_daily_roll_up_data_points( + self, response: data_points.DailyRollUpDataPointsResponse + ) -> data_points.DailyRollUpDataPointsResponse: + """Post-rpc interceptor for daily_roll_up_data_points + + DEPRECATED. Please use the `post_daily_roll_up_data_points_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the DataPointsService server but before + it is returned to user code. This `post_daily_roll_up_data_points` interceptor runs + before the `post_daily_roll_up_data_points_with_metadata` interceptor. + """ + return response + + def post_daily_roll_up_data_points_with_metadata( + self, + response: data_points.DailyRollUpDataPointsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + data_points.DailyRollUpDataPointsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for daily_roll_up_data_points + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataPointsService server but before it is returned to user code. + + We recommend only using this `post_daily_roll_up_data_points_with_metadata` + interceptor in new development instead of the `post_daily_roll_up_data_points` interceptor. + When both interceptors are used, this `post_daily_roll_up_data_points_with_metadata` interceptor runs after the + `post_daily_roll_up_data_points` interceptor. The (possibly modified) response returned by + `post_daily_roll_up_data_points` will be passed to + `post_daily_roll_up_data_points_with_metadata`. + """ + return response, metadata + + def pre_export_exercise_tcx( + self, + request: data_points.ExportExerciseTcxRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + data_points.ExportExerciseTcxRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for export_exercise_tcx + + Override in a subclass to manipulate the request or metadata + before they are sent to the DataPointsService server. + """ + return request, metadata + + def post_export_exercise_tcx( + self, response: data_points.ExportExerciseTcxResponse + ) -> data_points.ExportExerciseTcxResponse: + """Post-rpc interceptor for export_exercise_tcx + + DEPRECATED. Please use the `post_export_exercise_tcx_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the DataPointsService server but before + it is returned to user code. This `post_export_exercise_tcx` interceptor runs + before the `post_export_exercise_tcx_with_metadata` interceptor. + """ + return response + + def post_export_exercise_tcx_with_metadata( + self, + response: data_points.ExportExerciseTcxResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + data_points.ExportExerciseTcxResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for export_exercise_tcx + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataPointsService server but before it is returned to user code. + + We recommend only using this `post_export_exercise_tcx_with_metadata` + interceptor in new development instead of the `post_export_exercise_tcx` interceptor. + When both interceptors are used, this `post_export_exercise_tcx_with_metadata` interceptor runs after the + `post_export_exercise_tcx` interceptor. The (possibly modified) response returned by + `post_export_exercise_tcx` will be passed to + `post_export_exercise_tcx_with_metadata`. + """ + return response, metadata + + def pre_get_data_point( + self, + request: data_points.GetDataPointRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + data_points.GetDataPointRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_data_point + + Override in a subclass to manipulate the request or metadata + before they are sent to the DataPointsService server. + """ + return request, metadata + + def post_get_data_point( + self, response: data_points.DataPoint + ) -> data_points.DataPoint: + """Post-rpc interceptor for get_data_point + + DEPRECATED. Please use the `post_get_data_point_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the DataPointsService server but before + it is returned to user code. This `post_get_data_point` interceptor runs + before the `post_get_data_point_with_metadata` interceptor. + """ + return response + + def post_get_data_point_with_metadata( + self, + response: data_points.DataPoint, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[data_points.DataPoint, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_data_point + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataPointsService server but before it is returned to user code. + + We recommend only using this `post_get_data_point_with_metadata` + interceptor in new development instead of the `post_get_data_point` interceptor. + When both interceptors are used, this `post_get_data_point_with_metadata` interceptor runs after the + `post_get_data_point` interceptor. The (possibly modified) response returned by + `post_get_data_point` will be passed to + `post_get_data_point_with_metadata`. + """ + return response, metadata + + def pre_list_data_points( + self, + request: data_points.ListDataPointsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + data_points.ListDataPointsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for list_data_points + + Override in a subclass to manipulate the request or metadata + before they are sent to the DataPointsService server. + """ + return request, metadata + + def post_list_data_points( + self, response: data_points.ListDataPointsResponse + ) -> data_points.ListDataPointsResponse: + """Post-rpc interceptor for list_data_points + + DEPRECATED. Please use the `post_list_data_points_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the DataPointsService server but before + it is returned to user code. This `post_list_data_points` interceptor runs + before the `post_list_data_points_with_metadata` interceptor. + """ + return response + + def post_list_data_points_with_metadata( + self, + response: data_points.ListDataPointsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + data_points.ListDataPointsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_data_points + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataPointsService server but before it is returned to user code. + + We recommend only using this `post_list_data_points_with_metadata` + interceptor in new development instead of the `post_list_data_points` interceptor. + When both interceptors are used, this `post_list_data_points_with_metadata` interceptor runs after the + `post_list_data_points` interceptor. The (possibly modified) response returned by + `post_list_data_points` will be passed to + `post_list_data_points_with_metadata`. + """ + return response, metadata + + def pre_reconcile_data_points( + self, + request: data_points.ReconcileDataPointsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + data_points.ReconcileDataPointsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for reconcile_data_points + + Override in a subclass to manipulate the request or metadata + before they are sent to the DataPointsService server. + """ + return request, metadata + + def post_reconcile_data_points( + self, response: data_points.ReconcileDataPointsResponse + ) -> data_points.ReconcileDataPointsResponse: + """Post-rpc interceptor for reconcile_data_points + + DEPRECATED. Please use the `post_reconcile_data_points_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the DataPointsService server but before + it is returned to user code. This `post_reconcile_data_points` interceptor runs + before the `post_reconcile_data_points_with_metadata` interceptor. + """ + return response + + def post_reconcile_data_points_with_metadata( + self, + response: data_points.ReconcileDataPointsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + data_points.ReconcileDataPointsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for reconcile_data_points + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataPointsService server but before it is returned to user code. + + We recommend only using this `post_reconcile_data_points_with_metadata` + interceptor in new development instead of the `post_reconcile_data_points` interceptor. + When both interceptors are used, this `post_reconcile_data_points_with_metadata` interceptor runs after the + `post_reconcile_data_points` interceptor. The (possibly modified) response returned by + `post_reconcile_data_points` will be passed to + `post_reconcile_data_points_with_metadata`. + """ + return response, metadata + + def pre_roll_up_data_points( + self, + request: data_points.RollUpDataPointsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + data_points.RollUpDataPointsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for roll_up_data_points + + Override in a subclass to manipulate the request or metadata + before they are sent to the DataPointsService server. + """ + return request, metadata + + def post_roll_up_data_points( + self, response: data_points.RollUpDataPointsResponse + ) -> data_points.RollUpDataPointsResponse: + """Post-rpc interceptor for roll_up_data_points + + DEPRECATED. Please use the `post_roll_up_data_points_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the DataPointsService server but before + it is returned to user code. This `post_roll_up_data_points` interceptor runs + before the `post_roll_up_data_points_with_metadata` interceptor. + """ + return response + + def post_roll_up_data_points_with_metadata( + self, + response: data_points.RollUpDataPointsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + data_points.RollUpDataPointsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for roll_up_data_points + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataPointsService server but before it is returned to user code. + + We recommend only using this `post_roll_up_data_points_with_metadata` + interceptor in new development instead of the `post_roll_up_data_points` interceptor. + When both interceptors are used, this `post_roll_up_data_points_with_metadata` interceptor runs after the + `post_roll_up_data_points` interceptor. The (possibly modified) response returned by + `post_roll_up_data_points` will be passed to + `post_roll_up_data_points_with_metadata`. + """ + return response, metadata + + def pre_update_data_point( + self, + request: data_points.UpdateDataPointRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + data_points.UpdateDataPointRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for update_data_point + + Override in a subclass to manipulate the request or metadata + before they are sent to the DataPointsService server. + """ + return request, metadata + + def post_update_data_point( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for update_data_point + + DEPRECATED. Please use the `post_update_data_point_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the DataPointsService server but before + it is returned to user code. This `post_update_data_point` interceptor runs + before the `post_update_data_point_with_metadata` interceptor. + """ + return response + + def post_update_data_point_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_data_point + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataPointsService server but before it is returned to user code. + + We recommend only using this `post_update_data_point_with_metadata` + interceptor in new development instead of the `post_update_data_point` interceptor. + When both interceptors are used, this `post_update_data_point_with_metadata` interceptor runs after the + `post_update_data_point` interceptor. The (possibly modified) response returned by + `post_update_data_point` will be passed to + `post_update_data_point_with_metadata`. + """ + return response, metadata + + +@dataclasses.dataclass +class DataPointsServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: DataPointsServiceRestInterceptor + + +class DataPointsServiceRestTransport(_BaseDataPointsServiceRestTransport): + """REST backend synchronous transport for DataPointsService. + + Data Points Service exposing the user's health and fitness + measured and derived data. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "health.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[DataPointsServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'health.googleapis.com'). + 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]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. This argument will be + removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + interceptor (Optional[DataPointsServiceRestInterceptor]): Interceptor used + to manipulate requests, request metadata, and responses. + api_audience (Optional[str]): The intended audience for the API calls + to the service that will be set when using certain 3rd party + authentication flows. Audience is typically a resource identifier. + If not set, the host value will be used as a default. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + self._operations_client: Optional[operations_v1.AbstractOperationsClient] = None + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or DataPointsServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + @property + def operations_client(self) -> operations_v1.AbstractOperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Only create a new client if we do not already have one. + if self._operations_client is None: + http_options: Dict[str, List[Dict[str, str]]] = {} + + rest_transport = operations_v1.OperationsRestTransport( + host=self._host, + # use the credentials which are saved + credentials=self._credentials, + scopes=self._scopes, + http_options=http_options, + path_prefix="v4", + ) + + self._operations_client = operations_v1.AbstractOperationsClient( + transport=rest_transport + ) + + # Return the client from cache. + return self._operations_client + + class _BatchDeleteDataPoints( + _BaseDataPointsServiceRestTransport._BaseBatchDeleteDataPoints, + DataPointsServiceRestStub, + ): + def __hash__(self): + return hash("DataPointsServiceRestTransport.BatchDeleteDataPoints") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: data_points.BatchDeleteDataPointsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the batch delete data points method over HTTP. + + Args: + request (~.data_points.BatchDeleteDataPointsRequest): + The request object. Request to delete a batch of + identifiable data points. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseDataPointsServiceRestTransport._BaseBatchDeleteDataPoints._get_http_options() + + request, metadata = self._interceptor.pre_batch_delete_data_points( + request, metadata + ) + transcoded_request = _BaseDataPointsServiceRestTransport._BaseBatchDeleteDataPoints._get_transcoded_request( + http_options, request + ) + + body = _BaseDataPointsServiceRestTransport._BaseBatchDeleteDataPoints._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseDataPointsServiceRestTransport._BaseBatchDeleteDataPoints._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.devicesandservices.health_v4.DataPointsServiceClient.BatchDeleteDataPoints", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataPointsService", + "rpcName": "BatchDeleteDataPoints", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + DataPointsServiceRestTransport._BatchDeleteDataPoints._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_batch_delete_data_points(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_delete_data_points_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.devicesandservices.health_v4.DataPointsServiceClient.batch_delete_data_points", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataPointsService", + "rpcName": "BatchDeleteDataPoints", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _CreateDataPoint( + _BaseDataPointsServiceRestTransport._BaseCreateDataPoint, + DataPointsServiceRestStub, + ): + def __hash__(self): + return hash("DataPointsServiceRestTransport.CreateDataPoint") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: data_points.CreateDataPointRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the create data point method over HTTP. + + Args: + request (~.data_points.CreateDataPointRequest): + The request object. Request to create an identifiable + data point. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseDataPointsServiceRestTransport._BaseCreateDataPoint._get_http_options() + + request, metadata = self._interceptor.pre_create_data_point( + request, metadata + ) + transcoded_request = _BaseDataPointsServiceRestTransport._BaseCreateDataPoint._get_transcoded_request( + http_options, request + ) + + body = _BaseDataPointsServiceRestTransport._BaseCreateDataPoint._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseDataPointsServiceRestTransport._BaseCreateDataPoint._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.devicesandservices.health_v4.DataPointsServiceClient.CreateDataPoint", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataPointsService", + "rpcName": "CreateDataPoint", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = DataPointsServiceRestTransport._CreateDataPoint._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_create_data_point(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_data_point_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.devicesandservices.health_v4.DataPointsServiceClient.create_data_point", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataPointsService", + "rpcName": "CreateDataPoint", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _DailyRollUpDataPoints( + _BaseDataPointsServiceRestTransport._BaseDailyRollUpDataPoints, + DataPointsServiceRestStub, + ): + def __hash__(self): + return hash("DataPointsServiceRestTransport.DailyRollUpDataPoints") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: data_points.DailyRollUpDataPointsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> data_points.DailyRollUpDataPointsResponse: + r"""Call the daily roll up data points method over HTTP. + + Args: + request (~.data_points.DailyRollUpDataPointsRequest): + The request object. Request to roll up data points by + civil time intervals. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.data_points.DailyRollUpDataPointsResponse: + Response containing the list of + rolled up data points. + + """ + + http_options = _BaseDataPointsServiceRestTransport._BaseDailyRollUpDataPoints._get_http_options() + + request, metadata = self._interceptor.pre_daily_roll_up_data_points( + request, metadata + ) + transcoded_request = _BaseDataPointsServiceRestTransport._BaseDailyRollUpDataPoints._get_transcoded_request( + http_options, request + ) + + body = _BaseDataPointsServiceRestTransport._BaseDailyRollUpDataPoints._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseDataPointsServiceRestTransport._BaseDailyRollUpDataPoints._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.devicesandservices.health_v4.DataPointsServiceClient.DailyRollUpDataPoints", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataPointsService", + "rpcName": "DailyRollUpDataPoints", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + DataPointsServiceRestTransport._DailyRollUpDataPoints._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = data_points.DailyRollUpDataPointsResponse() + pb_resp = data_points.DailyRollUpDataPointsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_daily_roll_up_data_points(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_daily_roll_up_data_points_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + data_points.DailyRollUpDataPointsResponse.to_json(response) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.devicesandservices.health_v4.DataPointsServiceClient.daily_roll_up_data_points", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataPointsService", + "rpcName": "DailyRollUpDataPoints", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _ExportExerciseTcx( + _BaseDataPointsServiceRestTransport._BaseExportExerciseTcx, + DataPointsServiceRestStub, + ): + def __hash__(self): + return hash("DataPointsServiceRestTransport.ExportExerciseTcx") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: data_points.ExportExerciseTcxRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> data_points.ExportExerciseTcxResponse: + r"""Call the export exercise tcx method over HTTP. + + Args: + request (~.data_points.ExportExerciseTcxRequest): + The request object. Represents a request to export + exercise data in TCX format. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.data_points.ExportExerciseTcxResponse: + Represents a Response for exporting + exercise data in TCX format. + + """ + + http_options = _BaseDataPointsServiceRestTransport._BaseExportExerciseTcx._get_http_options() + + request, metadata = self._interceptor.pre_export_exercise_tcx( + request, metadata + ) + transcoded_request = _BaseDataPointsServiceRestTransport._BaseExportExerciseTcx._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseDataPointsServiceRestTransport._BaseExportExerciseTcx._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.devicesandservices.health_v4.DataPointsServiceClient.ExportExerciseTcx", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataPointsService", + "rpcName": "ExportExerciseTcx", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = DataPointsServiceRestTransport._ExportExerciseTcx._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = data_points.ExportExerciseTcxResponse() + pb_resp = data_points.ExportExerciseTcxResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_export_exercise_tcx(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_export_exercise_tcx_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = data_points.ExportExerciseTcxResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.devicesandservices.health_v4.DataPointsServiceClient.export_exercise_tcx", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataPointsService", + "rpcName": "ExportExerciseTcx", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _GetDataPoint( + _BaseDataPointsServiceRestTransport._BaseGetDataPoint, DataPointsServiceRestStub + ): + def __hash__(self): + return hash("DataPointsServiceRestTransport.GetDataPoint") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: data_points.GetDataPointRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> data_points.DataPoint: + r"""Call the get data point method over HTTP. + + Args: + request (~.data_points.GetDataPointRequest): + The request object. Request for getting a single data + point + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.data_points.DataPoint: + A computed or recorded metric. + """ + + http_options = _BaseDataPointsServiceRestTransport._BaseGetDataPoint._get_http_options() + + request, metadata = self._interceptor.pre_get_data_point(request, metadata) + transcoded_request = _BaseDataPointsServiceRestTransport._BaseGetDataPoint._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseDataPointsServiceRestTransport._BaseGetDataPoint._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.devicesandservices.health_v4.DataPointsServiceClient.GetDataPoint", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataPointsService", + "rpcName": "GetDataPoint", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = DataPointsServiceRestTransport._GetDataPoint._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = data_points.DataPoint() + pb_resp = data_points.DataPoint.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_data_point(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_data_point_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = data_points.DataPoint.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.devicesandservices.health_v4.DataPointsServiceClient.get_data_point", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataPointsService", + "rpcName": "GetDataPoint", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _ListDataPoints( + _BaseDataPointsServiceRestTransport._BaseListDataPoints, + DataPointsServiceRestStub, + ): + def __hash__(self): + return hash("DataPointsServiceRestTransport.ListDataPoints") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: data_points.ListDataPointsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> data_points.ListDataPointsResponse: + r"""Call the list data points method over HTTP. + + Args: + request (~.data_points.ListDataPointsRequest): + The request object. Request for listing raw data points + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.data_points.ListDataPointsResponse: + Response containing raw data points + matching the query + + """ + + http_options = _BaseDataPointsServiceRestTransport._BaseListDataPoints._get_http_options() + + request, metadata = self._interceptor.pre_list_data_points( + request, metadata + ) + transcoded_request = _BaseDataPointsServiceRestTransport._BaseListDataPoints._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseDataPointsServiceRestTransport._BaseListDataPoints._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.devicesandservices.health_v4.DataPointsServiceClient.ListDataPoints", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataPointsService", + "rpcName": "ListDataPoints", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = DataPointsServiceRestTransport._ListDataPoints._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = data_points.ListDataPointsResponse() + pb_resp = data_points.ListDataPointsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_list_data_points(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_data_points_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = data_points.ListDataPointsResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.devicesandservices.health_v4.DataPointsServiceClient.list_data_points", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataPointsService", + "rpcName": "ListDataPoints", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _ReconcileDataPoints( + _BaseDataPointsServiceRestTransport._BaseReconcileDataPoints, + DataPointsServiceRestStub, + ): + def __hash__(self): + return hash("DataPointsServiceRestTransport.ReconcileDataPoints") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: data_points.ReconcileDataPointsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> data_points.ReconcileDataPointsResponse: + r"""Call the reconcile data points method over HTTP. + + Args: + request (~.data_points.ReconcileDataPointsRequest): + The request object. Request to reconcile data points from + multiple data sources. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.data_points.ReconcileDataPointsResponse: + Response containing the list of + reconciled DataPoints. + + """ + + http_options = _BaseDataPointsServiceRestTransport._BaseReconcileDataPoints._get_http_options() + + request, metadata = self._interceptor.pre_reconcile_data_points( + request, metadata + ) + transcoded_request = _BaseDataPointsServiceRestTransport._BaseReconcileDataPoints._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseDataPointsServiceRestTransport._BaseReconcileDataPoints._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.devicesandservices.health_v4.DataPointsServiceClient.ReconcileDataPoints", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataPointsService", + "rpcName": "ReconcileDataPoints", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + DataPointsServiceRestTransport._ReconcileDataPoints._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = data_points.ReconcileDataPointsResponse() + pb_resp = data_points.ReconcileDataPointsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_reconcile_data_points(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_reconcile_data_points_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = data_points.ReconcileDataPointsResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.devicesandservices.health_v4.DataPointsServiceClient.reconcile_data_points", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataPointsService", + "rpcName": "ReconcileDataPoints", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _RollUpDataPoints( + _BaseDataPointsServiceRestTransport._BaseRollUpDataPoints, + DataPointsServiceRestStub, + ): + def __hash__(self): + return hash("DataPointsServiceRestTransport.RollUpDataPoints") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: data_points.RollUpDataPointsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> data_points.RollUpDataPointsResponse: + r"""Call the roll up data points method over HTTP. + + Args: + request (~.data_points.RollUpDataPointsRequest): + The request object. Request to roll up data points by + physical time intervals. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.data_points.RollUpDataPointsResponse: + Response containing the list of + rolled up data points. + + """ + + http_options = _BaseDataPointsServiceRestTransport._BaseRollUpDataPoints._get_http_options() + + request, metadata = self._interceptor.pre_roll_up_data_points( + request, metadata + ) + transcoded_request = _BaseDataPointsServiceRestTransport._BaseRollUpDataPoints._get_transcoded_request( + http_options, request + ) + + body = _BaseDataPointsServiceRestTransport._BaseRollUpDataPoints._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseDataPointsServiceRestTransport._BaseRollUpDataPoints._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.devicesandservices.health_v4.DataPointsServiceClient.RollUpDataPoints", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataPointsService", + "rpcName": "RollUpDataPoints", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = DataPointsServiceRestTransport._RollUpDataPoints._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = data_points.RollUpDataPointsResponse() + pb_resp = data_points.RollUpDataPointsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_roll_up_data_points(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_roll_up_data_points_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = data_points.RollUpDataPointsResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.devicesandservices.health_v4.DataPointsServiceClient.roll_up_data_points", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataPointsService", + "rpcName": "RollUpDataPoints", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _UpdateDataPoint( + _BaseDataPointsServiceRestTransport._BaseUpdateDataPoint, + DataPointsServiceRestStub, + ): + def __hash__(self): + return hash("DataPointsServiceRestTransport.UpdateDataPoint") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: data_points.UpdateDataPointRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the update data point method over HTTP. + + Args: + request (~.data_points.UpdateDataPointRequest): + The request object. Request to update an identifiable + data point. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseDataPointsServiceRestTransport._BaseUpdateDataPoint._get_http_options() + + request, metadata = self._interceptor.pre_update_data_point( + request, metadata + ) + transcoded_request = _BaseDataPointsServiceRestTransport._BaseUpdateDataPoint._get_transcoded_request( + http_options, request + ) + + body = _BaseDataPointsServiceRestTransport._BaseUpdateDataPoint._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseDataPointsServiceRestTransport._BaseUpdateDataPoint._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.devicesandservices.health_v4.DataPointsServiceClient.UpdateDataPoint", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataPointsService", + "rpcName": "UpdateDataPoint", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = DataPointsServiceRestTransport._UpdateDataPoint._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_update_data_point(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_data_point_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.devicesandservices.health_v4.DataPointsServiceClient.update_data_point", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataPointsService", + "rpcName": "UpdateDataPoint", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def batch_delete_data_points( + self, + ) -> Callable[[data_points.BatchDeleteDataPointsRequest], operations_pb2.Operation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchDeleteDataPoints(self._session, self._host, self._interceptor) # type: ignore + + @property + def create_data_point( + self, + ) -> Callable[[data_points.CreateDataPointRequest], operations_pb2.Operation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateDataPoint(self._session, self._host, self._interceptor) # type: ignore + + @property + def daily_roll_up_data_points( + self, + ) -> Callable[ + [data_points.DailyRollUpDataPointsRequest], + data_points.DailyRollUpDataPointsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DailyRollUpDataPoints(self._session, self._host, self._interceptor) # type: ignore + + @property + def export_exercise_tcx( + self, + ) -> Callable[ + [data_points.ExportExerciseTcxRequest], data_points.ExportExerciseTcxResponse + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ExportExerciseTcx(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_data_point( + self, + ) -> Callable[[data_points.GetDataPointRequest], data_points.DataPoint]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetDataPoint(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_data_points( + self, + ) -> Callable[ + [data_points.ListDataPointsRequest], data_points.ListDataPointsResponse + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListDataPoints(self._session, self._host, self._interceptor) # type: ignore + + @property + def reconcile_data_points( + self, + ) -> Callable[ + [data_points.ReconcileDataPointsRequest], + data_points.ReconcileDataPointsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ReconcileDataPoints(self._session, self._host, self._interceptor) # type: ignore + + @property + def roll_up_data_points( + self, + ) -> Callable[ + [data_points.RollUpDataPointsRequest], data_points.RollUpDataPointsResponse + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._RollUpDataPoints(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_data_point( + self, + ) -> Callable[[data_points.UpdateDataPointRequest], operations_pb2.Operation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateDataPoint(self._session, self._host, self._interceptor) # type: ignore + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("DataPointsServiceRestTransport",) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/transports/rest_base.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/transports/rest_base.py new file mode 100644 index 000000000000..c2be94c3aac5 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_points_service/transports/rest_base.py @@ -0,0 +1,565 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format + +from google.devicesandservices.health_v4.types import data_points + +from .base import DEFAULT_CLIENT_INFO, DataPointsServiceTransport + + +class _BaseDataPointsServiceRestTransport(DataPointsServiceTransport): + """Base REST backend transport for DataPointsService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "health.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'health.googleapis.com'). + credentials (Optional[Any]): 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. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseBatchDeleteDataPoints: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v4/{parent=users/*/dataTypes/*}/dataPoints:batchDelete", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = data_points.BatchDeleteDataPointsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDataPointsServiceRestTransport._BaseBatchDeleteDataPoints._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseCreateDataPoint: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v4/{parent=users/*/dataTypes/*}/dataPoints", + "body": "data_point", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = data_points.CreateDataPointRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDataPointsServiceRestTransport._BaseCreateDataPoint._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseDailyRollUpDataPoints: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v4/{parent=users/*/dataTypes/*}/dataPoints:dailyRollUp", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = data_points.DailyRollUpDataPointsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDataPointsServiceRestTransport._BaseDailyRollUpDataPoints._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseExportExerciseTcx: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v4/{name=users/*/dataTypes/*/dataPoints/*}:exportExerciseTcx", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = data_points.ExportExerciseTcxRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDataPointsServiceRestTransport._BaseExportExerciseTcx._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetDataPoint: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v4/{name=users/*/dataTypes/*/dataPoints/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = data_points.GetDataPointRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDataPointsServiceRestTransport._BaseGetDataPoint._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListDataPoints: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v4/{parent=users/*/dataTypes/*}/dataPoints", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = data_points.ListDataPointsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDataPointsServiceRestTransport._BaseListDataPoints._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseReconcileDataPoints: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v4/{parent=users/*/dataTypes/*}/dataPoints:reconcile", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = data_points.ReconcileDataPointsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDataPointsServiceRestTransport._BaseReconcileDataPoints._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseRollUpDataPoints: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v4/{parent=users/*/dataTypes/*}/dataPoints:rollUp", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = data_points.RollUpDataPointsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDataPointsServiceRestTransport._BaseRollUpDataPoints._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateDataPoint: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v4/{data_point.name=users/*/dataTypes/*/dataPoints/*}", + "body": "data_point", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = data_points.UpdateDataPointRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDataPointsServiceRestTransport._BaseUpdateDataPoint._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseDataPointsServiceRestTransport",) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/__init__.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/__init__.py new file mode 100644 index 000000000000..e9043f219be6 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .async_client import DataSubscriptionServiceAsyncClient +from .client import DataSubscriptionServiceClient + +__all__ = ( + "DataSubscriptionServiceClient", + "DataSubscriptionServiceAsyncClient", +) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/async_client.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/async_client.py new file mode 100644 index 000000000000..82156c94cfca --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/async_client.py @@ -0,0 +1,1496 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 logging as std_logging +import re +from collections import OrderedDict +from typing import ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, +) + +import google.protobuf +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.api_core.client_options import ClientOptions +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.devicesandservices.health_v4 import gapic_version as package_version + +try: + OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +import google.api_core.operation as operation # type: ignore +import google.api_core.operation_async as operation_async # type: ignore +import google.protobuf.empty_pb2 as empty_pb2 # type: ignore +import google.protobuf.field_mask_pb2 as field_mask_pb2 # type: ignore + +from google.devicesandservices.health_v4.services.data_subscription_service import ( + pagers, +) +from google.devicesandservices.health_v4.types import data_subscription_service + +from .client import DataSubscriptionServiceClient +from .transports.base import DEFAULT_CLIENT_INFO, DataSubscriptionServiceTransport +from .transports.grpc_asyncio import DataSubscriptionServiceGrpcAsyncIOTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class DataSubscriptionServiceAsyncClient: + """Data Subscription Service that allows clients (e.g., Fitbit + 3P applications, internal Fitbit Services) to manage their + subscriber endpoints. This service provides CRUD APIs for + subscribers, + and also offers functionalities for subscriber verification and + statistics. + """ + + _client: DataSubscriptionServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = DataSubscriptionServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = DataSubscriptionServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + DataSubscriptionServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = DataSubscriptionServiceClient._DEFAULT_UNIVERSE + + data_type_path = staticmethod(DataSubscriptionServiceClient.data_type_path) + parse_data_type_path = staticmethod( + DataSubscriptionServiceClient.parse_data_type_path + ) + subscriber_path = staticmethod(DataSubscriptionServiceClient.subscriber_path) + parse_subscriber_path = staticmethod( + DataSubscriptionServiceClient.parse_subscriber_path + ) + subscription_path = staticmethod(DataSubscriptionServiceClient.subscription_path) + parse_subscription_path = staticmethod( + DataSubscriptionServiceClient.parse_subscription_path + ) + user_path = staticmethod(DataSubscriptionServiceClient.user_path) + parse_user_path = staticmethod(DataSubscriptionServiceClient.parse_user_path) + common_billing_account_path = staticmethod( + DataSubscriptionServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + DataSubscriptionServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(DataSubscriptionServiceClient.common_folder_path) + parse_common_folder_path = staticmethod( + DataSubscriptionServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + DataSubscriptionServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + DataSubscriptionServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + DataSubscriptionServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + DataSubscriptionServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + DataSubscriptionServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + DataSubscriptionServiceClient.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: + DataSubscriptionServiceAsyncClient: The constructed client. + """ + sa_info_func = ( + DataSubscriptionServiceClient.from_service_account_info.__func__ # type: ignore + ) + return sa_info_func(DataSubscriptionServiceAsyncClient, info, *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: + DataSubscriptionServiceAsyncClient: The constructed client. + """ + sa_file_func = ( + DataSubscriptionServiceClient.from_service_account_file.__func__ # type: ignore + ) + return sa_file_func( + DataSubscriptionServiceAsyncClient, filename, *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 variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return DataSubscriptionServiceClient.get_mtls_endpoint_and_cert_source( + client_options + ) # type: ignore + + @property + def transport(self) -> DataSubscriptionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + DataSubscriptionServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self) -> str: + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = DataSubscriptionServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + DataSubscriptionServiceTransport, + Callable[..., DataSubscriptionServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the data subscription service async 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 (Optional[Union[str,DataSubscriptionServiceTransport,Callable[..., DataSubscriptionServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the DataSubscriptionServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "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). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS 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. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + 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. + """ + self._client = DataSubscriptionServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.devicesandservices.health_v4.DataSubscriptionServiceAsyncClient`.", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataSubscriptionService", + "universeDomain": getattr( + self._client._transport._credentials, "universe_domain", "" + ), + "credentialsType": f"{type(self._client._transport._credentials).__module__}.{type(self._client._transport._credentials).__qualname__}", + "credentialsInfo": getattr( + self.transport._credentials, "get_cred_info", lambda: None + )(), + } + if hasattr(self._client._transport, "_credentials") + else { + "serviceName": "google.devicesandservices.health.v4.DataSubscriptionService", + "credentialsType": None, + }, + ) + + async def create_subscriber( + self, + request: Optional[ + Union[data_subscription_service.CreateSubscriberRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + subscriber: Optional[data_subscription_service.CreateSubscriberPayload] = None, + subscriber_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""Registers a new subscriber endpoint to receive notifications. A + subscriber represents an application or service that wishes to + receive data change notifications for users who have granted + consent. + + **Endpoint Verification:** For a subscriber to be successfully + created, the provided ``endpoint_uri`` must be a valid HTTPS + endpoint and must pass an automated verification check. The + backend will send two HTTP POST requests to the + ``endpoint_uri``: + + 1. **Verification with Authorization:** + + - **Headers:** Includes ``Content-Type: application/json`` + and ``Authorization`` (with the exact value from + ``CreateSubscriberPayload.endpoint_authorization.secret``). + - **Body:** ``{"type": "verification"}`` + - **Expected Response:** HTTP ``201 Created``. + + 2. **Verification without Authorization:** + + - **Headers:** Includes ``Content-Type: application/json``. + The ``Authorization`` header is OMITTED. + - **Body:** ``{"type": "verification"}`` + - **Expected Response:** HTTP ``401 Unauthorized`` or + ``403 Forbidden``. + + Both tests must pass for the subscriber creation to succeed. If + verification fails, the operation will not be completed and an + error will be returned. This process ensures the endpoint is + reachable and correctly validates the ``Authorization`` header. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + async def sample_create_subscriber(): + # Create a client + client = health_v4.DataSubscriptionServiceAsyncClient() + + # Initialize request argument(s) + subscriber = health_v4.CreateSubscriberPayload() + subscriber.endpoint_uri = "endpoint_uri_value" + subscriber.endpoint_authorization.secret = "secret_value" + + request = health_v4.CreateSubscriberRequest( + parent="parent_value", + subscriber=subscriber, + ) + + # Make the request + operation = await client.create_subscriber(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.devicesandservices.health_v4.types.CreateSubscriberRequest, dict]]): + The request object. -- Messages -- + Request message for CreateSubscriber. + parent (:class:`str`): + Required. The parent resource where + this subscriber will be created. Format: + projects/{project} Example: + projects/my-project-123 + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + subscriber (:class:`google.devicesandservices.health_v4.types.CreateSubscriberPayload`): + Required. The subscriber to create. + This corresponds to the ``subscriber`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + subscriber_id (:class:`str`): + Optional. The ID to use for the subscriber, which will + become the final component of the subscriber's resource + name. + + This value should be 4-36 characters, and valid + characters are /`a-z <[a-z0-9-]{2,34}[a-z0-9]>`__/. + + This corresponds to the ``subscriber_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.devicesandservices.health_v4.types.Subscriber` + -- Resource Messages -- A subscriber receives + notifications from Google Health API. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, subscriber, subscriber_id] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_subscription_service.CreateSubscriberRequest): + request = data_subscription_service.CreateSubscriberRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if subscriber is not None: + request.subscriber = subscriber + if subscriber_id is not None: + request.subscriber_id = subscriber_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.create_subscriber + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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, + data_subscription_service.Subscriber, + metadata_type=data_subscription_service.CreateSubscriberMetadata, + ) + + # Done; return the response. + return response + + async def list_subscribers( + self, + request: Optional[ + Union[data_subscription_service.ListSubscribersRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListSubscribersAsyncPager: + r"""Lists all subscribers registered within the owned + Google Cloud Project. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + async def sample_list_subscribers(): + # Create a client + client = health_v4.DataSubscriptionServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.ListSubscribersRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_subscribers(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.devicesandservices.health_v4.types.ListSubscribersRequest, dict]]): + The request object. Request message for ListSubscribers. + parent (:class:`str`): + Required. The parent, which owns this + collection of subscribers. Format: + projects/{project} + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.services.data_subscription_service.pagers.ListSubscribersAsyncPager: + Response message for ListSubscribers. + + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_subscription_service.ListSubscribersRequest): + request = data_subscription_service.ListSubscribersRequest(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._client._transport._wrapped_methods[ + self._client._transport.list_subscribers + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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.ListSubscribersAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_subscriber( + self, + request: Optional[ + Union[data_subscription_service.UpdateSubscriberRequest, dict] + ] = None, + *, + subscriber: Optional[data_subscription_service.Subscriber] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""Updates the configuration of an existing subscriber, such as the + endpoint URI or the data types it's interested in. + + **Endpoint Verification:** If the ``endpoint_uri`` or + ``endpoint_authorization`` field is included in the + ``update_mask``, the backend will re-verify the endpoint. The + verification process is the same as described in + ``CreateSubscriber``: + + 1. **Verification with Authorization:** POST to the new or + existing ``endpoint_uri`` with the new or existing + ``Authorization`` secret. Expects HTTP ``201 Created``. + 2. **Verification without Authorization:** POST to the + ``endpoint_uri`` without the ``Authorization`` header. + Expects HTTP ``401 Unauthorized`` or ``403 Forbidden``. + + Both tests must pass using the potentially updated values for + the subscriber update to succeed. If verification fails, the + update will not be applied, and an error will be returned. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + async def sample_update_subscriber(): + # Create a client + client = health_v4.DataSubscriptionServiceAsyncClient() + + # Initialize request argument(s) + subscriber = health_v4.Subscriber() + subscriber.endpoint_uri = "endpoint_uri_value" + subscriber.endpoint_authorization.secret = "secret_value" + + request = health_v4.UpdateSubscriberRequest( + subscriber=subscriber, + ) + + # Make the request + operation = await client.update_subscriber(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.devicesandservices.health_v4.types.UpdateSubscriberRequest, dict]]): + The request object. Request message for UpdateSubscriber. + subscriber (:class:`google.devicesandservices.health_v4.types.Subscriber`): + Required. The subscriber resource to update. Its 'name' + field is mapped to the URI, and the value of the 'name' + field should be of the form: + "projects/{project}/subscribers/{subscriber_id}". The + remaining fields of the Subscriber object represent the + new values for the corresponding fields in the existing + subscriber resource. + + This corresponds to the ``subscriber`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Optional. A field mask that specifies which fields of + the Subscriber message are to be updated. This allows + for partial updates. Supported fields: + + - endpoint_uri + - subscriber_configs + - endpoint_authorization + + 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_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.devicesandservices.health_v4.types.Subscriber` + -- Resource Messages -- A subscriber receives + notifications from Google Health API. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [subscriber, update_mask] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_subscription_service.UpdateSubscriberRequest): + request = data_subscription_service.UpdateSubscriberRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if subscriber is not None: + request.subscriber = subscriber + 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._client._transport._wrapped_methods[ + self._client._transport.update_subscriber + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("subscriber.name", request.subscriber.name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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, + data_subscription_service.Subscriber, + metadata_type=data_subscription_service.UpdateSubscriberMetadata, + ) + + # Done; return the response. + return response + + async def delete_subscriber( + self, + request: Optional[ + Union[data_subscription_service.DeleteSubscriberRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""Deletes a subscriber registration. This will stop all + notifications to the subscriber's endpoint. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + async def sample_delete_subscriber(): + # Create a client + client = health_v4.DataSubscriptionServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.DeleteSubscriberRequest( + name="name_value", + ) + + # Make the request + operation = await client.delete_subscriber(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.devicesandservices.health_v4.types.DeleteSubscriberRequest, dict]]): + The request object. Request message for DeleteSubscriber. + name (:class:`str`): + Required. The name of the subscriber to delete. Format: + projects/{project}/subscribers/{subscriber} Example: + projects/my-project/subscribers/my-subscriber-123 The + {subscriber} ID is user-settable (4-36 characters, + matching /`a-z <[a-z0-9-]{2,34}[a-z0-9]>`__/) or + system-generated if not provided during creation. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_subscription_service.DeleteSubscriberRequest): + request = data_subscription_service.DeleteSubscriberRequest(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._client._transport._wrapped_methods[ + self._client._transport.delete_subscriber + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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, + empty_pb2.Empty, + metadata_type=data_subscription_service.DeleteSubscriberMetadata, + ) + + # Done; return the response. + return response + + async def create_subscription( + self, + request: Optional[ + Union[data_subscription_service.CreateSubscriptionRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + subscription: Optional[ + data_subscription_service.CreateSubscriptionPayload + ] = None, + subscription_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> data_subscription_service.Subscription: + r"""Creates a subscription for a specific user to a specific + subscriber. This method requires the subscriber to have a + ``SubscriptionCreatePolicy`` set to ``MANUAL`` for the given + data types. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + async def sample_create_subscription(): + # Create a client + client = health_v4.DataSubscriptionServiceAsyncClient() + + # Initialize request argument(s) + subscription = health_v4.CreateSubscriptionPayload() + subscription.user = "user_value" + + request = health_v4.CreateSubscriptionRequest( + parent="parent_value", + subscription=subscription, + ) + + # Make the request + response = await client.create_subscription(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.devicesandservices.health_v4.types.CreateSubscriptionRequest, dict]]): + The request object. Request message for + CreateSubscription. + parent (:class:`str`): + Required. The parent subscriber. Format: + projects/{project}/subscribers/{subscriber} The + {subscriber} ID is user-settable (4-36 characters, + matching /`a-z <[a-z0-9-]{2,34}[a-z0-9]>`__/) if + provided during creation, or system-generated otherwise. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + subscription (:class:`google.devicesandservices.health_v4.types.CreateSubscriptionPayload`): + Required. The subscription to create. + This corresponds to the ``subscription`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + subscription_id (:class:`str`): + Optional. The {subscription_id} is user-settable (4-36 + chars, matching /`a-z <[a-z0-9-]{2,34}[a-z0-9]>`__/) or + system-generated otherwise. If provided, the ID must be + unique within the parent subscriber. + + This corresponds to the ``subscription_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.types.Subscription: + A subscription to a data collection + for a specific user, to be delivered to + a subscriber. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, subscription, subscription_id] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_subscription_service.CreateSubscriptionRequest): + request = data_subscription_service.CreateSubscriptionRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if subscription is not None: + request.subscription = subscription + if subscription_id is not None: + request.subscription_id = subscription_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.create_subscription + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_subscriptions( + self, + request: Optional[ + Union[data_subscription_service.ListSubscriptionsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListSubscriptionsAsyncPager: + r"""Lists all active subscriptions for a given + subscriber. This can be filtered, for example, by user + or data type. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + async def sample_list_subscriptions(): + # Create a client + client = health_v4.DataSubscriptionServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.ListSubscriptionsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_subscriptions(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.devicesandservices.health_v4.types.ListSubscriptionsRequest, dict]]): + The request object. Request message for + ListSubscriptions. + parent (:class:`str`): + Required. The parent subscriber. Format: + projects/{project}/subscribers/{subscriber} The + {subscriber} ID is user-settable (4-36 characters, + matching /`a-z <[a-z0-9-]{2,34}[a-z0-9]>`__/) if + provided during creation, or system-generated otherwise. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.services.data_subscription_service.pagers.ListSubscriptionsAsyncPager: + Response message for + ListSubscriptions. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_subscription_service.ListSubscriptionsRequest): + request = data_subscription_service.ListSubscriptionsRequest(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._client._transport._wrapped_methods[ + self._client._transport.list_subscriptions + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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.ListSubscriptionsAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_subscription( + self, + request: Optional[ + Union[data_subscription_service.UpdateSubscriptionRequest, dict] + ] = None, + *, + subscription: Optional[data_subscription_service.Subscription] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> data_subscription_service.Subscription: + r"""Updates the data types for an existing user + subscription. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + async def sample_update_subscription(): + # Create a client + client = health_v4.DataSubscriptionServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.UpdateSubscriptionRequest( + ) + + # Make the request + response = await client.update_subscription(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.devicesandservices.health_v4.types.UpdateSubscriptionRequest, dict]]): + The request object. Request message for + UpdateSubscription. + subscription (:class:`google.devicesandservices.health_v4.types.Subscription`): + Required. The subscription to update. The subscription's + ``name`` field is used to identify the subscription to + update. Format: + projects/{project}/subscribers/{subscriber}/subscriptions/{subscription} + + This corresponds to the ``subscription`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Optional. The list of fields to + update. + + 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_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.types.Subscription: + A subscription to a data collection + for a specific user, to be delivered to + a subscriber. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [subscription, update_mask] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_subscription_service.UpdateSubscriptionRequest): + request = data_subscription_service.UpdateSubscriptionRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if subscription is not None: + request.subscription = subscription + 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._client._transport._wrapped_methods[ + self._client._transport.update_subscription + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("subscription.name", request.subscription.name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_subscription( + self, + request: Optional[ + Union[data_subscription_service.DeleteSubscriptionRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Deletes a specific user subscription, stopping + notifications for this user to this subscriber. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + async def sample_delete_subscription(): + # Create a client + client = health_v4.DataSubscriptionServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.DeleteSubscriptionRequest( + name="name_value", + ) + + # Make the request + await client.delete_subscription(request=request) + + Args: + request (Optional[Union[google.devicesandservices.health_v4.types.DeleteSubscriptionRequest, dict]]): + The request object. Request message for + DeleteSubscription. + name (:class:`str`): + Required. The resource name of the subscription to + delete. Format: + ``projects/{project}/subscribers/{subscriber}/subscriptions/{subscription}`` + Example: + ``projects/my-project/subscribers/my-subscriber-123/subscriptions/my-subscription-456`` + The {subscriber} ID is user-settable (4-36 characters, + matching /`a-z <[a-z0-9-]{2,34}[a-z0-9]>`__/) if + provided during creation, or system-generated otherwise. + The {subscription} ID is user-settable (4-36 characters, + matching /`a-z <[a-z0-9-]{2,34}[a-z0-9]>`__/) or + system-generated if not provided during creation. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_subscription_service.DeleteSubscriptionRequest): + request = data_subscription_service.DeleteSubscriptionRequest(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._client._transport._wrapped_methods[ + self._client._transport.delete_subscription + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def __aenter__(self) -> "DataSubscriptionServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("DataSubscriptionServiceAsyncClient",) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/client.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/client.py new file mode 100644 index 000000000000..ec786b943480 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/client.py @@ -0,0 +1,1946 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 json +import logging as std_logging +import os +import re +import warnings +from collections import OrderedDict +from http import HTTPStatus +from typing import ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) + +import google.protobuf +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.devicesandservices.health_v4 import gapic_version as package_version + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + +import google.api_core.operation as operation # type: ignore +import google.api_core.operation_async as operation_async # type: ignore +import google.protobuf.empty_pb2 as empty_pb2 # type: ignore +import google.protobuf.field_mask_pb2 as field_mask_pb2 # type: ignore + +from google.devicesandservices.health_v4.services.data_subscription_service import ( + pagers, +) +from google.devicesandservices.health_v4.types import data_subscription_service + +from .transports.base import DEFAULT_CLIENT_INFO, DataSubscriptionServiceTransport +from .transports.grpc import DataSubscriptionServiceGrpcTransport +from .transports.grpc_asyncio import DataSubscriptionServiceGrpcAsyncIOTransport +from .transports.rest import DataSubscriptionServiceRestTransport + + +class DataSubscriptionServiceClientMeta(type): + """Metaclass for the DataSubscriptionService 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[DataSubscriptionServiceTransport]] + _transport_registry["grpc"] = DataSubscriptionServiceGrpcTransport + _transport_registry["grpc_asyncio"] = DataSubscriptionServiceGrpcAsyncIOTransport + _transport_registry["rest"] = DataSubscriptionServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[DataSubscriptionServiceTransport]: + """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 DataSubscriptionServiceClient(metaclass=DataSubscriptionServiceClientMeta): + """Data Subscription Service that allows clients (e.g., Fitbit + 3P applications, internal Fitbit Services) to manage their + subscriber endpoints. This service provides CRUD APIs for + subscribers, + and also offers functionalities for subscriber verification and + statistics. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint) -> Optional[str]: + """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: + Optional[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) + if m is None: + # Could not parse api_endpoint; return as-is. + return 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") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "health.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "health.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @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: + DataSubscriptionServiceClient: 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: + DataSubscriptionServiceClient: 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) -> DataSubscriptionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + DataSubscriptionServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def data_type_path( + user: str, + data_type: str, + ) -> str: + """Returns a fully-qualified data_type string.""" + return "users/{user}/dataTypes/{data_type}".format( + user=user, + data_type=data_type, + ) + + @staticmethod + def parse_data_type_path(path: str) -> Dict[str, str]: + """Parses a data_type path into its component segments.""" + m = re.match(r"^users/(?P.+?)/dataTypes/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def subscriber_path( + project: str, + subscriber: str, + ) -> str: + """Returns a fully-qualified subscriber string.""" + return "projects/{project}/subscribers/{subscriber}".format( + project=project, + subscriber=subscriber, + ) + + @staticmethod + def parse_subscriber_path(path: str) -> Dict[str, str]: + """Parses a subscriber path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/subscribers/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def subscription_path( + project: str, + subscriber: str, + subscription: str, + ) -> str: + """Returns a fully-qualified subscription string.""" + return "projects/{project}/subscribers/{subscriber}/subscriptions/{subscription}".format( + project=project, + subscriber=subscriber, + subscription=subscription, + ) + + @staticmethod + def parse_subscription_path(path: str) -> Dict[str, str]: + """Parses a subscription path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/subscribers/(?P.+?)/subscriptions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def user_path( + user: str, + ) -> str: + """Returns a fully-qualified user string.""" + return "users/{user}".format( + user=user, + ) + + @staticmethod + def parse_user_path(path: str) -> Dict[str, str]: + """Parses a user path into its component segments.""" + m = re.match(r"^users/(?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 + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = DataSubscriptionServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + 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: + 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 + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = DataSubscriptionServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ) -> str: + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = DataSubscriptionServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = DataSubscriptionServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + DataSubscriptionServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], universe_domain_env: Optional[str] + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = DataSubscriptionServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self) -> str: + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + DataSubscriptionServiceTransport, + Callable[..., DataSubscriptionServiceTransport], + ] + ] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the data subscription 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 (Optional[Union[str,DataSubscriptionServiceTransport,Callable[..., DataSubscriptionServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the DataSubscriptionServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "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). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS 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. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + 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. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict(self._client_options) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr(self._client_options, "universe_domain", None) + + self._use_client_cert, self._use_mtls_endpoint, self._universe_domain_env = ( + DataSubscriptionServiceClient._read_environment_variables() + ) + self._client_cert_source = ( + DataSubscriptionServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = DataSubscriptionServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint: str = "" # updated below, depending on `transport` + + # Initialize the universe domain validation. + self._is_universe_domain_valid = False + + if CLIENT_LOGGING_SUPPORTED: # pragma: NO COVER + # Setup logging. + client_logging.initialize_logging() + + api_key_value = getattr(self._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. + transport_provided = isinstance(transport, DataSubscriptionServiceTransport) + if transport_provided: + # transport is a DataSubscriptionServiceTransport instance. + if credentials or self._client_options.credentials_file or api_key_value: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes directly." + ) + self._transport = cast(DataSubscriptionServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or DataSubscriptionServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + 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_init: Union[ + Type[DataSubscriptionServiceTransport], + Callable[..., DataSubscriptionServiceTransport], + ] = ( + DataSubscriptionServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., DataSubscriptionServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + api_audience=self._client_options.api_audience, + ) + + if "async" not in str(self._transport): + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.devicesandservices.health_v4.DataSubscriptionServiceClient`.", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataSubscriptionService", + "universeDomain": getattr( + self._transport._credentials, "universe_domain", "" + ), + "credentialsType": f"{type(self._transport._credentials).__module__}.{type(self._transport._credentials).__qualname__}", + "credentialsInfo": getattr( + self.transport._credentials, "get_cred_info", lambda: None + )(), + } + if hasattr(self._transport, "_credentials") + else { + "serviceName": "google.devicesandservices.health.v4.DataSubscriptionService", + "credentialsType": None, + }, + ) + + def create_subscriber( + self, + request: Optional[ + Union[data_subscription_service.CreateSubscriberRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + subscriber: Optional[data_subscription_service.CreateSubscriberPayload] = None, + subscriber_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Registers a new subscriber endpoint to receive notifications. A + subscriber represents an application or service that wishes to + receive data change notifications for users who have granted + consent. + + **Endpoint Verification:** For a subscriber to be successfully + created, the provided ``endpoint_uri`` must be a valid HTTPS + endpoint and must pass an automated verification check. The + backend will send two HTTP POST requests to the + ``endpoint_uri``: + + 1. **Verification with Authorization:** + + - **Headers:** Includes ``Content-Type: application/json`` + and ``Authorization`` (with the exact value from + ``CreateSubscriberPayload.endpoint_authorization.secret``). + - **Body:** ``{"type": "verification"}`` + - **Expected Response:** HTTP ``201 Created``. + + 2. **Verification without Authorization:** + + - **Headers:** Includes ``Content-Type: application/json``. + The ``Authorization`` header is OMITTED. + - **Body:** ``{"type": "verification"}`` + - **Expected Response:** HTTP ``401 Unauthorized`` or + ``403 Forbidden``. + + Both tests must pass for the subscriber creation to succeed. If + verification fails, the operation will not be completed and an + error will be returned. This process ensures the endpoint is + reachable and correctly validates the ``Authorization`` header. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + def sample_create_subscriber(): + # Create a client + client = health_v4.DataSubscriptionServiceClient() + + # Initialize request argument(s) + subscriber = health_v4.CreateSubscriberPayload() + subscriber.endpoint_uri = "endpoint_uri_value" + subscriber.endpoint_authorization.secret = "secret_value" + + request = health_v4.CreateSubscriberRequest( + parent="parent_value", + subscriber=subscriber, + ) + + # Make the request + operation = client.create_subscriber(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.devicesandservices.health_v4.types.CreateSubscriberRequest, dict]): + The request object. -- Messages -- + Request message for CreateSubscriber. + parent (str): + Required. The parent resource where + this subscriber will be created. Format: + projects/{project} Example: + projects/my-project-123 + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + subscriber (google.devicesandservices.health_v4.types.CreateSubscriberPayload): + Required. The subscriber to create. + This corresponds to the ``subscriber`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + subscriber_id (str): + Optional. The ID to use for the subscriber, which will + become the final component of the subscriber's resource + name. + + This value should be 4-36 characters, and valid + characters are /`a-z <[a-z0-9-]{2,34}[a-z0-9]>`__/. + + This corresponds to the ``subscriber_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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.devicesandservices.health_v4.types.Subscriber` + -- Resource Messages -- A subscriber receives + notifications from Google Health API. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, subscriber, subscriber_id] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_subscription_service.CreateSubscriberRequest): + request = data_subscription_service.CreateSubscriberRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if subscriber is not None: + request.subscriber = subscriber + if subscriber_id is not None: + request.subscriber_id = subscriber_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_subscriber] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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, + data_subscription_service.Subscriber, + metadata_type=data_subscription_service.CreateSubscriberMetadata, + ) + + # Done; return the response. + return response + + def list_subscribers( + self, + request: Optional[ + Union[data_subscription_service.ListSubscribersRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListSubscribersPager: + r"""Lists all subscribers registered within the owned + Google Cloud Project. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + def sample_list_subscribers(): + # Create a client + client = health_v4.DataSubscriptionServiceClient() + + # Initialize request argument(s) + request = health_v4.ListSubscribersRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_subscribers(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.devicesandservices.health_v4.types.ListSubscribersRequest, dict]): + The request object. Request message for ListSubscribers. + parent (str): + Required. The parent, which owns this + collection of subscribers. Format: + projects/{project} + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.services.data_subscription_service.pagers.ListSubscribersPager: + Response message for ListSubscribers. + + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_subscription_service.ListSubscribersRequest): + request = data_subscription_service.ListSubscribersRequest(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_subscribers] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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.ListSubscribersPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_subscriber( + self, + request: Optional[ + Union[data_subscription_service.UpdateSubscriberRequest, dict] + ] = None, + *, + subscriber: Optional[data_subscription_service.Subscriber] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Updates the configuration of an existing subscriber, such as the + endpoint URI or the data types it's interested in. + + **Endpoint Verification:** If the ``endpoint_uri`` or + ``endpoint_authorization`` field is included in the + ``update_mask``, the backend will re-verify the endpoint. The + verification process is the same as described in + ``CreateSubscriber``: + + 1. **Verification with Authorization:** POST to the new or + existing ``endpoint_uri`` with the new or existing + ``Authorization`` secret. Expects HTTP ``201 Created``. + 2. **Verification without Authorization:** POST to the + ``endpoint_uri`` without the ``Authorization`` header. + Expects HTTP ``401 Unauthorized`` or ``403 Forbidden``. + + Both tests must pass using the potentially updated values for + the subscriber update to succeed. If verification fails, the + update will not be applied, and an error will be returned. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + def sample_update_subscriber(): + # Create a client + client = health_v4.DataSubscriptionServiceClient() + + # Initialize request argument(s) + subscriber = health_v4.Subscriber() + subscriber.endpoint_uri = "endpoint_uri_value" + subscriber.endpoint_authorization.secret = "secret_value" + + request = health_v4.UpdateSubscriberRequest( + subscriber=subscriber, + ) + + # Make the request + operation = client.update_subscriber(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.devicesandservices.health_v4.types.UpdateSubscriberRequest, dict]): + The request object. Request message for UpdateSubscriber. + subscriber (google.devicesandservices.health_v4.types.Subscriber): + Required. The subscriber resource to update. Its 'name' + field is mapped to the URI, and the value of the 'name' + field should be of the form: + "projects/{project}/subscribers/{subscriber_id}". The + remaining fields of the Subscriber object represent the + new values for the corresponding fields in the existing + subscriber resource. + + This corresponds to the ``subscriber`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Optional. A field mask that specifies which fields of + the Subscriber message are to be updated. This allows + for partial updates. Supported fields: + + - endpoint_uri + - subscriber_configs + - endpoint_authorization + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.devicesandservices.health_v4.types.Subscriber` + -- Resource Messages -- A subscriber receives + notifications from Google Health API. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [subscriber, update_mask] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_subscription_service.UpdateSubscriberRequest): + request = data_subscription_service.UpdateSubscriberRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if subscriber is not None: + request.subscriber = subscriber + 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_subscriber] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("subscriber.name", request.subscriber.name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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, + data_subscription_service.Subscriber, + metadata_type=data_subscription_service.UpdateSubscriberMetadata, + ) + + # Done; return the response. + return response + + def delete_subscriber( + self, + request: Optional[ + Union[data_subscription_service.DeleteSubscriberRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Deletes a subscriber registration. This will stop all + notifications to the subscriber's endpoint. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + def sample_delete_subscriber(): + # Create a client + client = health_v4.DataSubscriptionServiceClient() + + # Initialize request argument(s) + request = health_v4.DeleteSubscriberRequest( + name="name_value", + ) + + # Make the request + operation = client.delete_subscriber(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.devicesandservices.health_v4.types.DeleteSubscriberRequest, dict]): + The request object. Request message for DeleteSubscriber. + name (str): + Required. The name of the subscriber to delete. Format: + projects/{project}/subscribers/{subscriber} Example: + projects/my-project/subscribers/my-subscriber-123 The + {subscriber} ID is user-settable (4-36 characters, + matching /`a-z <[a-z0-9-]{2,34}[a-z0-9]>`__/) or + system-generated if not provided during creation. + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_subscription_service.DeleteSubscriberRequest): + request = data_subscription_service.DeleteSubscriberRequest(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_subscriber] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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, + empty_pb2.Empty, + metadata_type=data_subscription_service.DeleteSubscriberMetadata, + ) + + # Done; return the response. + return response + + def create_subscription( + self, + request: Optional[ + Union[data_subscription_service.CreateSubscriptionRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + subscription: Optional[ + data_subscription_service.CreateSubscriptionPayload + ] = None, + subscription_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> data_subscription_service.Subscription: + r"""Creates a subscription for a specific user to a specific + subscriber. This method requires the subscriber to have a + ``SubscriptionCreatePolicy`` set to ``MANUAL`` for the given + data types. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + def sample_create_subscription(): + # Create a client + client = health_v4.DataSubscriptionServiceClient() + + # Initialize request argument(s) + subscription = health_v4.CreateSubscriptionPayload() + subscription.user = "user_value" + + request = health_v4.CreateSubscriptionRequest( + parent="parent_value", + subscription=subscription, + ) + + # Make the request + response = client.create_subscription(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.devicesandservices.health_v4.types.CreateSubscriptionRequest, dict]): + The request object. Request message for + CreateSubscription. + parent (str): + Required. The parent subscriber. Format: + projects/{project}/subscribers/{subscriber} The + {subscriber} ID is user-settable (4-36 characters, + matching /`a-z <[a-z0-9-]{2,34}[a-z0-9]>`__/) if + provided during creation, or system-generated otherwise. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + subscription (google.devicesandservices.health_v4.types.CreateSubscriptionPayload): + Required. The subscription to create. + This corresponds to the ``subscription`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + subscription_id (str): + Optional. The {subscription_id} is user-settable (4-36 + chars, matching /`a-z <[a-z0-9-]{2,34}[a-z0-9]>`__/) or + system-generated otherwise. If provided, the ID must be + unique within the parent subscriber. + + This corresponds to the ``subscription_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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.types.Subscription: + A subscription to a data collection + for a specific user, to be delivered to + a subscriber. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, subscription, subscription_id] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_subscription_service.CreateSubscriptionRequest): + request = data_subscription_service.CreateSubscriptionRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if subscription is not None: + request.subscription = subscription + if subscription_id is not None: + request.subscription_id = subscription_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_subscription] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_subscriptions( + self, + request: Optional[ + Union[data_subscription_service.ListSubscriptionsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListSubscriptionsPager: + r"""Lists all active subscriptions for a given + subscriber. This can be filtered, for example, by user + or data type. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + def sample_list_subscriptions(): + # Create a client + client = health_v4.DataSubscriptionServiceClient() + + # Initialize request argument(s) + request = health_v4.ListSubscriptionsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_subscriptions(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.devicesandservices.health_v4.types.ListSubscriptionsRequest, dict]): + The request object. Request message for + ListSubscriptions. + parent (str): + Required. The parent subscriber. Format: + projects/{project}/subscribers/{subscriber} The + {subscriber} ID is user-settable (4-36 characters, + matching /`a-z <[a-z0-9-]{2,34}[a-z0-9]>`__/) if + provided during creation, or system-generated otherwise. + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.services.data_subscription_service.pagers.ListSubscriptionsPager: + Response message for + ListSubscriptions. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_subscription_service.ListSubscriptionsRequest): + request = data_subscription_service.ListSubscriptionsRequest(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_subscriptions] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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.ListSubscriptionsPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_subscription( + self, + request: Optional[ + Union[data_subscription_service.UpdateSubscriptionRequest, dict] + ] = None, + *, + subscription: Optional[data_subscription_service.Subscription] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> data_subscription_service.Subscription: + r"""Updates the data types for an existing user + subscription. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + def sample_update_subscription(): + # Create a client + client = health_v4.DataSubscriptionServiceClient() + + # Initialize request argument(s) + request = health_v4.UpdateSubscriptionRequest( + ) + + # Make the request + response = client.update_subscription(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.devicesandservices.health_v4.types.UpdateSubscriptionRequest, dict]): + The request object. Request message for + UpdateSubscription. + subscription (google.devicesandservices.health_v4.types.Subscription): + Required. The subscription to update. The subscription's + ``name`` field is used to identify the subscription to + update. Format: + projects/{project}/subscribers/{subscriber}/subscriptions/{subscription} + + This corresponds to the ``subscription`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Optional. The list of fields to + update. + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.types.Subscription: + A subscription to a data collection + for a specific user, to be delivered to + a subscriber. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [subscription, update_mask] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_subscription_service.UpdateSubscriptionRequest): + request = data_subscription_service.UpdateSubscriptionRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if subscription is not None: + request.subscription = subscription + 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_subscription] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("subscription.name", request.subscription.name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def delete_subscription( + self, + request: Optional[ + Union[data_subscription_service.DeleteSubscriptionRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Deletes a specific user subscription, stopping + notifications for this user to this subscriber. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + def sample_delete_subscription(): + # Create a client + client = health_v4.DataSubscriptionServiceClient() + + # Initialize request argument(s) + request = health_v4.DeleteSubscriptionRequest( + name="name_value", + ) + + # Make the request + client.delete_subscription(request=request) + + Args: + request (Union[google.devicesandservices.health_v4.types.DeleteSubscriptionRequest, dict]): + The request object. Request message for + DeleteSubscription. + name (str): + Required. The resource name of the subscription to + delete. Format: + ``projects/{project}/subscribers/{subscriber}/subscriptions/{subscription}`` + Example: + ``projects/my-project/subscribers/my-subscriber-123/subscriptions/my-subscription-456`` + The {subscriber} ID is user-settable (4-36 characters, + matching /`a-z <[a-z0-9-]{2,34}[a-z0-9]>`__/) if + provided during creation, or system-generated otherwise. + The {subscription} ID is user-settable (4-36 characters, + matching /`a-z <[a-z0-9-]{2,34}[a-z0-9]>`__/) or + system-generated if not provided during creation. + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_subscription_service.DeleteSubscriptionRequest): + request = data_subscription_service.DeleteSubscriptionRequest(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_subscription] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def __enter__(self) -> "DataSubscriptionServiceClient": + 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() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("DataSubscriptionServiceClient",) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/pagers.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/pagers.py new file mode 100644 index 000000000000..382b1b9077ed --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/pagers.py @@ -0,0 +1,361 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, + Union, +) + +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import retry_async as retries_async + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] + OptionalAsyncRetry = Union[ + retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore + +from google.devicesandservices.health_v4.types import data_subscription_service + + +class ListSubscribersPager: + """A pager for iterating through ``list_subscribers`` requests. + + This class thinly wraps an initial + :class:`google.devicesandservices.health_v4.types.ListSubscribersResponse` object, and + provides an ``__iter__`` method to iterate through its + ``subscribers`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListSubscribers`` requests and continue to iterate + through the ``subscribers`` field on the + corresponding responses. + + All the usual :class:`google.devicesandservices.health_v4.types.ListSubscribersResponse` + 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[..., data_subscription_service.ListSubscribersResponse], + request: data_subscription_service.ListSubscribersRequest, + response: data_subscription_service.ListSubscribersResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.devicesandservices.health_v4.types.ListSubscribersRequest): + The initial request object. + response (google.devicesandservices.health_v4.types.ListSubscribersResponse): + The initial response object. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = data_subscription_service.ListSubscribersRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[data_subscription_service.ListSubscribersResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __iter__(self) -> Iterator[data_subscription_service.Subscriber]: + for page in self.pages: + yield from page.subscribers + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListSubscribersAsyncPager: + """A pager for iterating through ``list_subscribers`` requests. + + This class thinly wraps an initial + :class:`google.devicesandservices.health_v4.types.ListSubscribersResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``subscribers`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListSubscribers`` requests and continue to iterate + through the ``subscribers`` field on the + corresponding responses. + + All the usual :class:`google.devicesandservices.health_v4.types.ListSubscribersResponse` + 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[data_subscription_service.ListSubscribersResponse] + ], + request: data_subscription_service.ListSubscribersRequest, + response: data_subscription_service.ListSubscribersResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.devicesandservices.health_v4.types.ListSubscribersRequest): + The initial request object. + response (google.devicesandservices.health_v4.types.ListSubscribersResponse): + The initial response object. + retry (google.api_core.retry.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = data_subscription_service.ListSubscribersRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[data_subscription_service.ListSubscribersResponse]: + 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, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __aiter__(self) -> AsyncIterator[data_subscription_service.Subscriber]: + async def async_generator(): + async for page in self.pages: + for response in page.subscribers: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListSubscriptionsPager: + """A pager for iterating through ``list_subscriptions`` requests. + + This class thinly wraps an initial + :class:`google.devicesandservices.health_v4.types.ListSubscriptionsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``subscriptions`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListSubscriptions`` requests and continue to iterate + through the ``subscriptions`` field on the + corresponding responses. + + All the usual :class:`google.devicesandservices.health_v4.types.ListSubscriptionsResponse` + 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[..., data_subscription_service.ListSubscriptionsResponse], + request: data_subscription_service.ListSubscriptionsRequest, + response: data_subscription_service.ListSubscriptionsResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.devicesandservices.health_v4.types.ListSubscriptionsRequest): + The initial request object. + response (google.devicesandservices.health_v4.types.ListSubscriptionsResponse): + The initial response object. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = data_subscription_service.ListSubscriptionsRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[data_subscription_service.ListSubscriptionsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __iter__(self) -> Iterator[data_subscription_service.Subscription]: + for page in self.pages: + yield from page.subscriptions + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListSubscriptionsAsyncPager: + """A pager for iterating through ``list_subscriptions`` requests. + + This class thinly wraps an initial + :class:`google.devicesandservices.health_v4.types.ListSubscriptionsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``subscriptions`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListSubscriptions`` requests and continue to iterate + through the ``subscriptions`` field on the + corresponding responses. + + All the usual :class:`google.devicesandservices.health_v4.types.ListSubscriptionsResponse` + 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[data_subscription_service.ListSubscriptionsResponse] + ], + request: data_subscription_service.ListSubscriptionsRequest, + response: data_subscription_service.ListSubscriptionsResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.devicesandservices.health_v4.types.ListSubscriptionsRequest): + The initial request object. + response (google.devicesandservices.health_v4.types.ListSubscriptionsResponse): + The initial response object. + retry (google.api_core.retry.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = data_subscription_service.ListSubscriptionsRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[data_subscription_service.ListSubscriptionsResponse]: + 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, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __aiter__(self) -> AsyncIterator[data_subscription_service.Subscription]: + async def async_generator(): + async for page in self.pages: + for response in page.subscriptions: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/transports/README.rst b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/transports/README.rst new file mode 100644 index 000000000000..8fd3d553a5e5 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/transports/README.rst @@ -0,0 +1,10 @@ + +transport inheritance structure +_______________________________ + +``DataSubscriptionServiceTransport`` is the ABC for all transports. + +- public child ``DataSubscriptionServiceGrpcTransport`` for sync gRPC transport (defined in ``grpc.py``). +- public child ``DataSubscriptionServiceGrpcAsyncIOTransport`` for async gRPC transport (defined in ``grpc_asyncio.py``). +- private child ``_BaseDataSubscriptionServiceRestTransport`` for base REST transport with inner classes ``_BaseMETHOD`` (defined in ``rest_base.py``). +- public child ``DataSubscriptionServiceRestTransport`` for sync REST transport with inner classes ``METHOD`` derived from the parent's corresponding ``_BaseMETHOD`` classes (defined in ``rest.py``). diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/transports/__init__.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/transports/__init__.py new file mode 100644 index 000000000000..62efac75cca2 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/transports/__init__.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 DataSubscriptionServiceTransport +from .grpc import DataSubscriptionServiceGrpcTransport +from .grpc_asyncio import DataSubscriptionServiceGrpcAsyncIOTransport +from .rest import ( + DataSubscriptionServiceRestInterceptor, + DataSubscriptionServiceRestTransport, +) + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[DataSubscriptionServiceTransport]] +_transport_registry["grpc"] = DataSubscriptionServiceGrpcTransport +_transport_registry["grpc_asyncio"] = DataSubscriptionServiceGrpcAsyncIOTransport +_transport_registry["rest"] = DataSubscriptionServiceRestTransport + +__all__ = ( + "DataSubscriptionServiceTransport", + "DataSubscriptionServiceGrpcTransport", + "DataSubscriptionServiceGrpcAsyncIOTransport", + "DataSubscriptionServiceRestTransport", + "DataSubscriptionServiceRestInterceptor", +) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/transports/base.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/transports/base.py new file mode 100644 index 000000000000..d310b415790c --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/transports/base.py @@ -0,0 +1,328 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union + +import google.api_core +import google.auth # type: ignore +import google.protobuf +import google.protobuf.empty_pb2 as empty_pb2 # type: ignore +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, operations_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.devicesandservices.health_v4 import gapic_version as package_version +from google.devicesandservices.health_v4.types import data_subscription_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class DataSubscriptionServiceTransport(abc.ABC): + """Abstract transport class for DataSubscriptionService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) + + DEFAULT_HOST: str = "health.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'health.googleapis.com'). + 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]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + 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. + api_audience (Optional[str]): The intended audience for the API calls + to the service that will be set when using certain 3rd party + authentication flows. Audience is typically a resource identifier. + If not set, the host value will be used as a default. + """ + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # 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=scopes, + quota_project_id=quota_project_id, + default_scopes=self.AUTH_SCOPES, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + scopes=scopes, + quota_project_id=quota_project_id, + default_scopes=self.AUTH_SCOPES, + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr(service_account.Credentials, "with_always_use_jwt_access") + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + self._wrapped_methods: Dict[Callable, Callable] = {} + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.create_subscriber: gapic_v1.method.wrap_method( + self.create_subscriber, + default_timeout=60.0, + client_info=client_info, + ), + self.list_subscribers: gapic_v1.method.wrap_method( + self.list_subscribers, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.update_subscriber: gapic_v1.method.wrap_method( + self.update_subscriber, + default_timeout=60.0, + client_info=client_info, + ), + self.delete_subscriber: gapic_v1.method.wrap_method( + self.delete_subscriber, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.create_subscription: gapic_v1.method.wrap_method( + self.create_subscription, + default_timeout=60.0, + client_info=client_info, + ), + self.list_subscriptions: gapic_v1.method.wrap_method( + self.list_subscriptions, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.update_subscription: gapic_v1.method.wrap_method( + self.update_subscription, + default_timeout=60.0, + client_info=client_info, + ), + self.delete_subscription: gapic_v1.method.wrap_method( + self.delete_subscription, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + 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_subscriber( + self, + ) -> Callable[ + [data_subscription_service.CreateSubscriberRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def list_subscribers( + self, + ) -> Callable[ + [data_subscription_service.ListSubscribersRequest], + Union[ + data_subscription_service.ListSubscribersResponse, + Awaitable[data_subscription_service.ListSubscribersResponse], + ], + ]: + raise NotImplementedError() + + @property + def update_subscriber( + self, + ) -> Callable[ + [data_subscription_service.UpdateSubscriberRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def delete_subscriber( + self, + ) -> Callable[ + [data_subscription_service.DeleteSubscriberRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def create_subscription( + self, + ) -> Callable[ + [data_subscription_service.CreateSubscriptionRequest], + Union[ + data_subscription_service.Subscription, + Awaitable[data_subscription_service.Subscription], + ], + ]: + raise NotImplementedError() + + @property + def list_subscriptions( + self, + ) -> Callable[ + [data_subscription_service.ListSubscriptionsRequest], + Union[ + data_subscription_service.ListSubscriptionsResponse, + Awaitable[data_subscription_service.ListSubscriptionsResponse], + ], + ]: + raise NotImplementedError() + + @property + def update_subscription( + self, + ) -> Callable[ + [data_subscription_service.UpdateSubscriptionRequest], + Union[ + data_subscription_service.Subscription, + Awaitable[data_subscription_service.Subscription], + ], + ]: + raise NotImplementedError() + + @property + def delete_subscription( + self, + ) -> Callable[ + [data_subscription_service.DeleteSubscriptionRequest], + Union[empty_pb2.Empty, Awaitable[empty_pb2.Empty]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("DataSubscriptionServiceTransport",) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/transports/grpc.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/transports/grpc.py new file mode 100644 index 000000000000..22e2f998e177 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/transports/grpc.py @@ -0,0 +1,645 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 json +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +import google.auth # type: ignore +import google.protobuf.empty_pb2 as empty_pb2 # type: ignore +import google.protobuf.message +import grpc # type: ignore +import proto # type: ignore +from google.api_core import gapic_v1, grpc_helpers, operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson + +from google.devicesandservices.health_v4.types import data_subscription_service + +from .base import DEFAULT_CLIENT_INFO, DataSubscriptionServiceTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor(grpc.UnaryUnaryClientInterceptor): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = f"{type(request).__name__}: {pickle.dumps(request)!r}" + + request_metadata = { + key: value.decode("utf-8") if isinstance(value, bytes) else value + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataSubscriptionService", + "rpcName": str(client_call_details.method), + "request": grpc_request, + "metadata": grpc_request["metadata"], + }, + ) + response = continuation(client_call_details, request) + if logging_enabled: # pragma: NO COVER + response_metadata = response.trailing_metadata() + # Convert gRPC metadata `` to list of tuples + metadata = ( + dict([(k, str(v)) for k, v in response_metadata]) + if response_metadata + else None + ) + result = response.result() + if isinstance(result, proto.Message): + response_payload = type(result).to_json(result) + elif isinstance(result, google.protobuf.message.Message): + response_payload = MessageToJson(result) + else: + response_payload = f"{type(result).__name__}: {pickle.dumps(result)!r}" + grpc_response = { + "payload": response_payload, + "metadata": metadata, + "status": "OK", + } + _LOGGER.debug( + f"Received response for {client_call_details.method}.", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataSubscriptionService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class DataSubscriptionServiceGrpcTransport(DataSubscriptionServiceTransport): + """gRPC backend transport for DataSubscriptionService. + + Data Subscription Service that allows clients (e.g., Fitbit + 3P applications, internal Fitbit Services) to manage their + subscriber endpoints. This service provides CRUD APIs for + subscribers, + and also offers functionalities for subscriber verification and + statistics. + + 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 = "health.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'health.googleapis.com'). + 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 a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + 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 a ``channel`` instance 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 a ``channel`` instance 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. + api_audience (Optional[str]): The intended audience for the API calls + to the service that will be set when using certain 3rd party + authentication flows. Audience is typically a resource identifier. + If not set, the host value will be used as a default. + + 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 isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + self._interceptor = _LoggingClientInterceptor() + self._logged_channel = grpc.intercept_channel( + self._grpc_channel, self._interceptor + ) + + # Wrap messages. This must be done after self._logged_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "health.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsClient( + self._logged_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def create_subscriber( + self, + ) -> Callable[ + [data_subscription_service.CreateSubscriberRequest], operations_pb2.Operation + ]: + r"""Return a callable for the create subscriber method over gRPC. + + Registers a new subscriber endpoint to receive notifications. A + subscriber represents an application or service that wishes to + receive data change notifications for users who have granted + consent. + + **Endpoint Verification:** For a subscriber to be successfully + created, the provided ``endpoint_uri`` must be a valid HTTPS + endpoint and must pass an automated verification check. The + backend will send two HTTP POST requests to the + ``endpoint_uri``: + + 1. **Verification with Authorization:** + + - **Headers:** Includes ``Content-Type: application/json`` + and ``Authorization`` (with the exact value from + ``CreateSubscriberPayload.endpoint_authorization.secret``). + - **Body:** ``{"type": "verification"}`` + - **Expected Response:** HTTP ``201 Created``. + + 2. **Verification without Authorization:** + + - **Headers:** Includes ``Content-Type: application/json``. + The ``Authorization`` header is OMITTED. + - **Body:** ``{"type": "verification"}`` + - **Expected Response:** HTTP ``401 Unauthorized`` or + ``403 Forbidden``. + + Both tests must pass for the subscriber creation to succeed. If + verification fails, the operation will not be completed and an + error will be returned. This process ensures the endpoint is + reachable and correctly validates the ``Authorization`` header. + + Returns: + Callable[[~.CreateSubscriberRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_subscriber" not in self._stubs: + self._stubs["create_subscriber"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataSubscriptionService/CreateSubscriber", + request_serializer=data_subscription_service.CreateSubscriberRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["create_subscriber"] + + @property + def list_subscribers( + self, + ) -> Callable[ + [data_subscription_service.ListSubscribersRequest], + data_subscription_service.ListSubscribersResponse, + ]: + r"""Return a callable for the list subscribers method over gRPC. + + Lists all subscribers registered within the owned + Google Cloud Project. + + Returns: + Callable[[~.ListSubscribersRequest], + ~.ListSubscribersResponse]: + 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_subscribers" not in self._stubs: + self._stubs["list_subscribers"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataSubscriptionService/ListSubscribers", + request_serializer=data_subscription_service.ListSubscribersRequest.serialize, + response_deserializer=data_subscription_service.ListSubscribersResponse.deserialize, + ) + return self._stubs["list_subscribers"] + + @property + def update_subscriber( + self, + ) -> Callable[ + [data_subscription_service.UpdateSubscriberRequest], operations_pb2.Operation + ]: + r"""Return a callable for the update subscriber method over gRPC. + + Updates the configuration of an existing subscriber, such as the + endpoint URI or the data types it's interested in. + + **Endpoint Verification:** If the ``endpoint_uri`` or + ``endpoint_authorization`` field is included in the + ``update_mask``, the backend will re-verify the endpoint. The + verification process is the same as described in + ``CreateSubscriber``: + + 1. **Verification with Authorization:** POST to the new or + existing ``endpoint_uri`` with the new or existing + ``Authorization`` secret. Expects HTTP ``201 Created``. + 2. **Verification without Authorization:** POST to the + ``endpoint_uri`` without the ``Authorization`` header. + Expects HTTP ``401 Unauthorized`` or ``403 Forbidden``. + + Both tests must pass using the potentially updated values for + the subscriber update to succeed. If verification fails, the + update will not be applied, and an error will be returned. + + Returns: + Callable[[~.UpdateSubscriberRequest], + ~.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 "update_subscriber" not in self._stubs: + self._stubs["update_subscriber"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataSubscriptionService/UpdateSubscriber", + request_serializer=data_subscription_service.UpdateSubscriberRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["update_subscriber"] + + @property + def delete_subscriber( + self, + ) -> Callable[ + [data_subscription_service.DeleteSubscriberRequest], operations_pb2.Operation + ]: + r"""Return a callable for the delete subscriber method over gRPC. + + Deletes a subscriber registration. This will stop all + notifications to the subscriber's endpoint. + + Returns: + Callable[[~.DeleteSubscriberRequest], + ~.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 "delete_subscriber" not in self._stubs: + self._stubs["delete_subscriber"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataSubscriptionService/DeleteSubscriber", + request_serializer=data_subscription_service.DeleteSubscriberRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["delete_subscriber"] + + @property + def create_subscription( + self, + ) -> Callable[ + [data_subscription_service.CreateSubscriptionRequest], + data_subscription_service.Subscription, + ]: + r"""Return a callable for the create subscription method over gRPC. + + Creates a subscription for a specific user to a specific + subscriber. This method requires the subscriber to have a + ``SubscriptionCreatePolicy`` set to ``MANUAL`` for the given + data types. + + Returns: + Callable[[~.CreateSubscriptionRequest], + ~.Subscription]: + 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_subscription" not in self._stubs: + self._stubs["create_subscription"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataSubscriptionService/CreateSubscription", + request_serializer=data_subscription_service.CreateSubscriptionRequest.serialize, + response_deserializer=data_subscription_service.Subscription.deserialize, + ) + return self._stubs["create_subscription"] + + @property + def list_subscriptions( + self, + ) -> Callable[ + [data_subscription_service.ListSubscriptionsRequest], + data_subscription_service.ListSubscriptionsResponse, + ]: + r"""Return a callable for the list subscriptions method over gRPC. + + Lists all active subscriptions for a given + subscriber. This can be filtered, for example, by user + or data type. + + Returns: + Callable[[~.ListSubscriptionsRequest], + ~.ListSubscriptionsResponse]: + 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_subscriptions" not in self._stubs: + self._stubs["list_subscriptions"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataSubscriptionService/ListSubscriptions", + request_serializer=data_subscription_service.ListSubscriptionsRequest.serialize, + response_deserializer=data_subscription_service.ListSubscriptionsResponse.deserialize, + ) + return self._stubs["list_subscriptions"] + + @property + def update_subscription( + self, + ) -> Callable[ + [data_subscription_service.UpdateSubscriptionRequest], + data_subscription_service.Subscription, + ]: + r"""Return a callable for the update subscription method over gRPC. + + Updates the data types for an existing user + subscription. + + Returns: + Callable[[~.UpdateSubscriptionRequest], + ~.Subscription]: + 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_subscription" not in self._stubs: + self._stubs["update_subscription"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataSubscriptionService/UpdateSubscription", + request_serializer=data_subscription_service.UpdateSubscriptionRequest.serialize, + response_deserializer=data_subscription_service.Subscription.deserialize, + ) + return self._stubs["update_subscription"] + + @property + def delete_subscription( + self, + ) -> Callable[ + [data_subscription_service.DeleteSubscriptionRequest], empty_pb2.Empty + ]: + r"""Return a callable for the delete subscription method over gRPC. + + Deletes a specific user subscription, stopping + notifications for this user to this subscriber. + + Returns: + Callable[[~.DeleteSubscriptionRequest], + ~.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_subscription" not in self._stubs: + self._stubs["delete_subscription"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataSubscriptionService/DeleteSubscription", + request_serializer=data_subscription_service.DeleteSubscriptionRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs["delete_subscription"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("DataSubscriptionServiceGrpcTransport",) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/transports/grpc_asyncio.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/transports/grpc_asyncio.py new file mode 100644 index 000000000000..95b0e729f59b --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/transports/grpc_asyncio.py @@ -0,0 +1,743 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 inspect +import json +import logging as std_logging +import pickle +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +import google.protobuf.empty_pb2 as empty_pb2 # type: ignore +import google.protobuf.message +import grpc # type: ignore +import proto # type: ignore +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, grpc_helpers_async, operations_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +from grpc.experimental import aio # type: ignore + +from google.devicesandservices.health_v4.types import data_subscription_service + +from .base import DEFAULT_CLIENT_INFO, DataSubscriptionServiceTransport +from .grpc import DataSubscriptionServiceGrpcTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientAIOInterceptor( + grpc.aio.UnaryUnaryClientInterceptor +): # pragma: NO COVER + async def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = f"{type(request).__name__}: {pickle.dumps(request)!r}" + + request_metadata = { + key: value.decode("utf-8") if isinstance(value, bytes) else value + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataSubscriptionService", + "rpcName": str(client_call_details.method), + "request": grpc_request, + "metadata": grpc_request["metadata"], + }, + ) + response = await continuation(client_call_details, request) + if logging_enabled: # pragma: NO COVER + response_metadata = await response.trailing_metadata() + # Convert gRPC metadata `` to list of tuples + metadata = ( + dict([(k, str(v)) for k, v in response_metadata]) + if response_metadata + else None + ) + result = await response + if isinstance(result, proto.Message): + response_payload = type(result).to_json(result) + elif isinstance(result, google.protobuf.message.Message): + response_payload = MessageToJson(result) + else: + response_payload = f"{type(result).__name__}: {pickle.dumps(result)!r}" + grpc_response = { + "payload": response_payload, + "metadata": metadata, + "status": "OK", + } + _LOGGER.debug( + f"Received response to rpc {client_call_details.method}.", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataSubscriptionService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class DataSubscriptionServiceGrpcAsyncIOTransport(DataSubscriptionServiceTransport): + """gRPC AsyncIO backend transport for DataSubscriptionService. + + Data Subscription Service that allows clients (e.g., Fitbit + 3P applications, internal Fitbit Services) to manage their + subscriber endpoints. This service provides CRUD APIs for + subscribers, + and also offers functionalities for subscriber verification and + statistics. + + 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 = "health.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + 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 = "health.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[Union[aio.Channel, Callable[..., aio.Channel]]] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'health.googleapis.com'). + 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 a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + 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[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + 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 a ``channel`` instance 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 a ``channel`` instance 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. + api_audience (Optional[str]): The intended audience for the API calls + to the service that will be set when using certain 3rd party + authentication flows. Audience is typically a resource identifier. + If not set, the host value will be used as a default. + + 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 isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + self._interceptor = _LoggingClientAIOInterceptor() + self._grpc_channel._unary_unary_interceptors.append(self._interceptor) + self._logged_channel = self._grpc_channel + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) + # Wrap messages. This must be done after self._logged_channel exists + self._prep_wrapped_messages(client_info) + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsAsyncClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsAsyncClient( + self._logged_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def create_subscriber( + self, + ) -> Callable[ + [data_subscription_service.CreateSubscriberRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the create subscriber method over gRPC. + + Registers a new subscriber endpoint to receive notifications. A + subscriber represents an application or service that wishes to + receive data change notifications for users who have granted + consent. + + **Endpoint Verification:** For a subscriber to be successfully + created, the provided ``endpoint_uri`` must be a valid HTTPS + endpoint and must pass an automated verification check. The + backend will send two HTTP POST requests to the + ``endpoint_uri``: + + 1. **Verification with Authorization:** + + - **Headers:** Includes ``Content-Type: application/json`` + and ``Authorization`` (with the exact value from + ``CreateSubscriberPayload.endpoint_authorization.secret``). + - **Body:** ``{"type": "verification"}`` + - **Expected Response:** HTTP ``201 Created``. + + 2. **Verification without Authorization:** + + - **Headers:** Includes ``Content-Type: application/json``. + The ``Authorization`` header is OMITTED. + - **Body:** ``{"type": "verification"}`` + - **Expected Response:** HTTP ``401 Unauthorized`` or + ``403 Forbidden``. + + Both tests must pass for the subscriber creation to succeed. If + verification fails, the operation will not be completed and an + error will be returned. This process ensures the endpoint is + reachable and correctly validates the ``Authorization`` header. + + Returns: + Callable[[~.CreateSubscriberRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_subscriber" not in self._stubs: + self._stubs["create_subscriber"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataSubscriptionService/CreateSubscriber", + request_serializer=data_subscription_service.CreateSubscriberRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["create_subscriber"] + + @property + def list_subscribers( + self, + ) -> Callable[ + [data_subscription_service.ListSubscribersRequest], + Awaitable[data_subscription_service.ListSubscribersResponse], + ]: + r"""Return a callable for the list subscribers method over gRPC. + + Lists all subscribers registered within the owned + Google Cloud Project. + + Returns: + Callable[[~.ListSubscribersRequest], + Awaitable[~.ListSubscribersResponse]]: + 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_subscribers" not in self._stubs: + self._stubs["list_subscribers"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataSubscriptionService/ListSubscribers", + request_serializer=data_subscription_service.ListSubscribersRequest.serialize, + response_deserializer=data_subscription_service.ListSubscribersResponse.deserialize, + ) + return self._stubs["list_subscribers"] + + @property + def update_subscriber( + self, + ) -> Callable[ + [data_subscription_service.UpdateSubscriberRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the update subscriber method over gRPC. + + Updates the configuration of an existing subscriber, such as the + endpoint URI or the data types it's interested in. + + **Endpoint Verification:** If the ``endpoint_uri`` or + ``endpoint_authorization`` field is included in the + ``update_mask``, the backend will re-verify the endpoint. The + verification process is the same as described in + ``CreateSubscriber``: + + 1. **Verification with Authorization:** POST to the new or + existing ``endpoint_uri`` with the new or existing + ``Authorization`` secret. Expects HTTP ``201 Created``. + 2. **Verification without Authorization:** POST to the + ``endpoint_uri`` without the ``Authorization`` header. + Expects HTTP ``401 Unauthorized`` or ``403 Forbidden``. + + Both tests must pass using the potentially updated values for + the subscriber update to succeed. If verification fails, the + update will not be applied, and an error will be returned. + + Returns: + Callable[[~.UpdateSubscriberRequest], + 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 "update_subscriber" not in self._stubs: + self._stubs["update_subscriber"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataSubscriptionService/UpdateSubscriber", + request_serializer=data_subscription_service.UpdateSubscriberRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["update_subscriber"] + + @property + def delete_subscriber( + self, + ) -> Callable[ + [data_subscription_service.DeleteSubscriberRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the delete subscriber method over gRPC. + + Deletes a subscriber registration. This will stop all + notifications to the subscriber's endpoint. + + Returns: + Callable[[~.DeleteSubscriberRequest], + 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 "delete_subscriber" not in self._stubs: + self._stubs["delete_subscriber"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataSubscriptionService/DeleteSubscriber", + request_serializer=data_subscription_service.DeleteSubscriberRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["delete_subscriber"] + + @property + def create_subscription( + self, + ) -> Callable[ + [data_subscription_service.CreateSubscriptionRequest], + Awaitable[data_subscription_service.Subscription], + ]: + r"""Return a callable for the create subscription method over gRPC. + + Creates a subscription for a specific user to a specific + subscriber. This method requires the subscriber to have a + ``SubscriptionCreatePolicy`` set to ``MANUAL`` for the given + data types. + + Returns: + Callable[[~.CreateSubscriptionRequest], + Awaitable[~.Subscription]]: + 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_subscription" not in self._stubs: + self._stubs["create_subscription"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataSubscriptionService/CreateSubscription", + request_serializer=data_subscription_service.CreateSubscriptionRequest.serialize, + response_deserializer=data_subscription_service.Subscription.deserialize, + ) + return self._stubs["create_subscription"] + + @property + def list_subscriptions( + self, + ) -> Callable[ + [data_subscription_service.ListSubscriptionsRequest], + Awaitable[data_subscription_service.ListSubscriptionsResponse], + ]: + r"""Return a callable for the list subscriptions method over gRPC. + + Lists all active subscriptions for a given + subscriber. This can be filtered, for example, by user + or data type. + + Returns: + Callable[[~.ListSubscriptionsRequest], + Awaitable[~.ListSubscriptionsResponse]]: + 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_subscriptions" not in self._stubs: + self._stubs["list_subscriptions"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataSubscriptionService/ListSubscriptions", + request_serializer=data_subscription_service.ListSubscriptionsRequest.serialize, + response_deserializer=data_subscription_service.ListSubscriptionsResponse.deserialize, + ) + return self._stubs["list_subscriptions"] + + @property + def update_subscription( + self, + ) -> Callable[ + [data_subscription_service.UpdateSubscriptionRequest], + Awaitable[data_subscription_service.Subscription], + ]: + r"""Return a callable for the update subscription method over gRPC. + + Updates the data types for an existing user + subscription. + + Returns: + Callable[[~.UpdateSubscriptionRequest], + Awaitable[~.Subscription]]: + 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_subscription" not in self._stubs: + self._stubs["update_subscription"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataSubscriptionService/UpdateSubscription", + request_serializer=data_subscription_service.UpdateSubscriptionRequest.serialize, + response_deserializer=data_subscription_service.Subscription.deserialize, + ) + return self._stubs["update_subscription"] + + @property + def delete_subscription( + self, + ) -> Callable[ + [data_subscription_service.DeleteSubscriptionRequest], + Awaitable[empty_pb2.Empty], + ]: + r"""Return a callable for the delete subscription method over gRPC. + + Deletes a specific user subscription, stopping + notifications for this user to this subscriber. + + Returns: + Callable[[~.DeleteSubscriptionRequest], + 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_subscription" not in self._stubs: + self._stubs["delete_subscription"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.DataSubscriptionService/DeleteSubscription", + request_serializer=data_subscription_service.DeleteSubscriptionRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs["delete_subscription"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.create_subscriber: self._wrap_method( + self.create_subscriber, + default_timeout=60.0, + client_info=client_info, + ), + self.list_subscribers: self._wrap_method( + self.list_subscribers, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.update_subscriber: self._wrap_method( + self.update_subscriber, + default_timeout=60.0, + client_info=client_info, + ), + self.delete_subscriber: self._wrap_method( + self.delete_subscriber, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.create_subscription: self._wrap_method( + self.create_subscription, + default_timeout=60.0, + client_info=client_info, + ), + self.list_subscriptions: self._wrap_method( + self.list_subscriptions, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.update_subscription: self._wrap_method( + self.update_subscription, + default_timeout=60.0, + client_info=client_info, + ), + self.delete_subscription: self._wrap_method( + self.delete_subscription, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("DataSubscriptionServiceGrpcAsyncIOTransport",) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/transports/rest.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/transports/rest.py new file mode 100644 index 000000000000..a878b96f2400 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/transports/rest.py @@ -0,0 +1,1920 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +import warnings +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +import google.protobuf +import google.protobuf.empty_pb2 as empty_pb2 # type: ignore +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, operations_v1, rest_helpers, rest_streaming +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.devicesandservices.health_v4.types import data_subscription_service + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseDataSubscriptionServiceRestTransport + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class DataSubscriptionServiceRestInterceptor: + """Interceptor for DataSubscriptionService. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the DataSubscriptionServiceRestTransport. + + .. code-block:: python + class MyCustomDataSubscriptionServiceInterceptor(DataSubscriptionServiceRestInterceptor): + def pre_create_subscriber(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_subscriber(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_create_subscription(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_subscription(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_delete_subscriber(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_delete_subscriber(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_delete_subscription(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_list_subscribers(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_subscribers(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_subscriptions(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_subscriptions(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_subscriber(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_subscriber(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_subscription(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_subscription(self, response): + logging.log(f"Received response: {response}") + return response + + transport = DataSubscriptionServiceRestTransport(interceptor=MyCustomDataSubscriptionServiceInterceptor()) + client = DataSubscriptionServiceClient(transport=transport) + + + """ + + def pre_create_subscriber( + self, + request: data_subscription_service.CreateSubscriberRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + data_subscription_service.CreateSubscriberRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for create_subscriber + + Override in a subclass to manipulate the request or metadata + before they are sent to the DataSubscriptionService server. + """ + return request, metadata + + def post_create_subscriber( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for create_subscriber + + DEPRECATED. Please use the `post_create_subscriber_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the DataSubscriptionService server but before + it is returned to user code. This `post_create_subscriber` interceptor runs + before the `post_create_subscriber_with_metadata` interceptor. + """ + return response + + def post_create_subscriber_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_subscriber + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataSubscriptionService server but before it is returned to user code. + + We recommend only using this `post_create_subscriber_with_metadata` + interceptor in new development instead of the `post_create_subscriber` interceptor. + When both interceptors are used, this `post_create_subscriber_with_metadata` interceptor runs after the + `post_create_subscriber` interceptor. The (possibly modified) response returned by + `post_create_subscriber` will be passed to + `post_create_subscriber_with_metadata`. + """ + return response, metadata + + def pre_create_subscription( + self, + request: data_subscription_service.CreateSubscriptionRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + data_subscription_service.CreateSubscriptionRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for create_subscription + + Override in a subclass to manipulate the request or metadata + before they are sent to the DataSubscriptionService server. + """ + return request, metadata + + def post_create_subscription( + self, response: data_subscription_service.Subscription + ) -> data_subscription_service.Subscription: + """Post-rpc interceptor for create_subscription + + DEPRECATED. Please use the `post_create_subscription_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the DataSubscriptionService server but before + it is returned to user code. This `post_create_subscription` interceptor runs + before the `post_create_subscription_with_metadata` interceptor. + """ + return response + + def post_create_subscription_with_metadata( + self, + response: data_subscription_service.Subscription, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + data_subscription_service.Subscription, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for create_subscription + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataSubscriptionService server but before it is returned to user code. + + We recommend only using this `post_create_subscription_with_metadata` + interceptor in new development instead of the `post_create_subscription` interceptor. + When both interceptors are used, this `post_create_subscription_with_metadata` interceptor runs after the + `post_create_subscription` interceptor. The (possibly modified) response returned by + `post_create_subscription` will be passed to + `post_create_subscription_with_metadata`. + """ + return response, metadata + + def pre_delete_subscriber( + self, + request: data_subscription_service.DeleteSubscriberRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + data_subscription_service.DeleteSubscriberRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for delete_subscriber + + Override in a subclass to manipulate the request or metadata + before they are sent to the DataSubscriptionService server. + """ + return request, metadata + + def post_delete_subscriber( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for delete_subscriber + + DEPRECATED. Please use the `post_delete_subscriber_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the DataSubscriptionService server but before + it is returned to user code. This `post_delete_subscriber` interceptor runs + before the `post_delete_subscriber_with_metadata` interceptor. + """ + return response + + def post_delete_subscriber_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_subscriber + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataSubscriptionService server but before it is returned to user code. + + We recommend only using this `post_delete_subscriber_with_metadata` + interceptor in new development instead of the `post_delete_subscriber` interceptor. + When both interceptors are used, this `post_delete_subscriber_with_metadata` interceptor runs after the + `post_delete_subscriber` interceptor. The (possibly modified) response returned by + `post_delete_subscriber` will be passed to + `post_delete_subscriber_with_metadata`. + """ + return response, metadata + + def pre_delete_subscription( + self, + request: data_subscription_service.DeleteSubscriptionRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + data_subscription_service.DeleteSubscriptionRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for delete_subscription + + Override in a subclass to manipulate the request or metadata + before they are sent to the DataSubscriptionService server. + """ + return request, metadata + + def pre_list_subscribers( + self, + request: data_subscription_service.ListSubscribersRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + data_subscription_service.ListSubscribersRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for list_subscribers + + Override in a subclass to manipulate the request or metadata + before they are sent to the DataSubscriptionService server. + """ + return request, metadata + + def post_list_subscribers( + self, response: data_subscription_service.ListSubscribersResponse + ) -> data_subscription_service.ListSubscribersResponse: + """Post-rpc interceptor for list_subscribers + + DEPRECATED. Please use the `post_list_subscribers_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the DataSubscriptionService server but before + it is returned to user code. This `post_list_subscribers` interceptor runs + before the `post_list_subscribers_with_metadata` interceptor. + """ + return response + + def post_list_subscribers_with_metadata( + self, + response: data_subscription_service.ListSubscribersResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + data_subscription_service.ListSubscribersResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_subscribers + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataSubscriptionService server but before it is returned to user code. + + We recommend only using this `post_list_subscribers_with_metadata` + interceptor in new development instead of the `post_list_subscribers` interceptor. + When both interceptors are used, this `post_list_subscribers_with_metadata` interceptor runs after the + `post_list_subscribers` interceptor. The (possibly modified) response returned by + `post_list_subscribers` will be passed to + `post_list_subscribers_with_metadata`. + """ + return response, metadata + + def pre_list_subscriptions( + self, + request: data_subscription_service.ListSubscriptionsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + data_subscription_service.ListSubscriptionsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for list_subscriptions + + Override in a subclass to manipulate the request or metadata + before they are sent to the DataSubscriptionService server. + """ + return request, metadata + + def post_list_subscriptions( + self, response: data_subscription_service.ListSubscriptionsResponse + ) -> data_subscription_service.ListSubscriptionsResponse: + """Post-rpc interceptor for list_subscriptions + + DEPRECATED. Please use the `post_list_subscriptions_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the DataSubscriptionService server but before + it is returned to user code. This `post_list_subscriptions` interceptor runs + before the `post_list_subscriptions_with_metadata` interceptor. + """ + return response + + def post_list_subscriptions_with_metadata( + self, + response: data_subscription_service.ListSubscriptionsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + data_subscription_service.ListSubscriptionsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_subscriptions + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataSubscriptionService server but before it is returned to user code. + + We recommend only using this `post_list_subscriptions_with_metadata` + interceptor in new development instead of the `post_list_subscriptions` interceptor. + When both interceptors are used, this `post_list_subscriptions_with_metadata` interceptor runs after the + `post_list_subscriptions` interceptor. The (possibly modified) response returned by + `post_list_subscriptions` will be passed to + `post_list_subscriptions_with_metadata`. + """ + return response, metadata + + def pre_update_subscriber( + self, + request: data_subscription_service.UpdateSubscriberRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + data_subscription_service.UpdateSubscriberRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for update_subscriber + + Override in a subclass to manipulate the request or metadata + before they are sent to the DataSubscriptionService server. + """ + return request, metadata + + def post_update_subscriber( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for update_subscriber + + DEPRECATED. Please use the `post_update_subscriber_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the DataSubscriptionService server but before + it is returned to user code. This `post_update_subscriber` interceptor runs + before the `post_update_subscriber_with_metadata` interceptor. + """ + return response + + def post_update_subscriber_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_subscriber + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataSubscriptionService server but before it is returned to user code. + + We recommend only using this `post_update_subscriber_with_metadata` + interceptor in new development instead of the `post_update_subscriber` interceptor. + When both interceptors are used, this `post_update_subscriber_with_metadata` interceptor runs after the + `post_update_subscriber` interceptor. The (possibly modified) response returned by + `post_update_subscriber` will be passed to + `post_update_subscriber_with_metadata`. + """ + return response, metadata + + def pre_update_subscription( + self, + request: data_subscription_service.UpdateSubscriptionRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + data_subscription_service.UpdateSubscriptionRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for update_subscription + + Override in a subclass to manipulate the request or metadata + before they are sent to the DataSubscriptionService server. + """ + return request, metadata + + def post_update_subscription( + self, response: data_subscription_service.Subscription + ) -> data_subscription_service.Subscription: + """Post-rpc interceptor for update_subscription + + DEPRECATED. Please use the `post_update_subscription_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the DataSubscriptionService server but before + it is returned to user code. This `post_update_subscription` interceptor runs + before the `post_update_subscription_with_metadata` interceptor. + """ + return response + + def post_update_subscription_with_metadata( + self, + response: data_subscription_service.Subscription, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + data_subscription_service.Subscription, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for update_subscription + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataSubscriptionService server but before it is returned to user code. + + We recommend only using this `post_update_subscription_with_metadata` + interceptor in new development instead of the `post_update_subscription` interceptor. + When both interceptors are used, this `post_update_subscription_with_metadata` interceptor runs after the + `post_update_subscription` interceptor. The (possibly modified) response returned by + `post_update_subscription` will be passed to + `post_update_subscription_with_metadata`. + """ + return response, metadata + + +@dataclasses.dataclass +class DataSubscriptionServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: DataSubscriptionServiceRestInterceptor + + +class DataSubscriptionServiceRestTransport(_BaseDataSubscriptionServiceRestTransport): + """REST backend synchronous transport for DataSubscriptionService. + + Data Subscription Service that allows clients (e.g., Fitbit + 3P applications, internal Fitbit Services) to manage their + subscriber endpoints. This service provides CRUD APIs for + subscribers, + and also offers functionalities for subscriber verification and + statistics. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "health.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[DataSubscriptionServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'health.googleapis.com'). + 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]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. This argument will be + removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + interceptor (Optional[DataSubscriptionServiceRestInterceptor]): Interceptor used + to manipulate requests, request metadata, and responses. + api_audience (Optional[str]): The intended audience for the API calls + to the service that will be set when using certain 3rd party + authentication flows. Audience is typically a resource identifier. + If not set, the host value will be used as a default. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + self._operations_client: Optional[operations_v1.AbstractOperationsClient] = None + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or DataSubscriptionServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + @property + def operations_client(self) -> operations_v1.AbstractOperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Only create a new client if we do not already have one. + if self._operations_client is None: + http_options: Dict[str, List[Dict[str, str]]] = {} + + rest_transport = operations_v1.OperationsRestTransport( + host=self._host, + # use the credentials which are saved + credentials=self._credentials, + scopes=self._scopes, + http_options=http_options, + path_prefix="v4", + ) + + self._operations_client = operations_v1.AbstractOperationsClient( + transport=rest_transport + ) + + # Return the client from cache. + return self._operations_client + + class _CreateSubscriber( + _BaseDataSubscriptionServiceRestTransport._BaseCreateSubscriber, + DataSubscriptionServiceRestStub, + ): + def __hash__(self): + return hash("DataSubscriptionServiceRestTransport.CreateSubscriber") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: data_subscription_service.CreateSubscriberRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the create subscriber method over HTTP. + + Args: + request (~.data_subscription_service.CreateSubscriberRequest): + The request object. -- Messages -- + Request message for CreateSubscriber. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseDataSubscriptionServiceRestTransport._BaseCreateSubscriber._get_http_options() + + request, metadata = self._interceptor.pre_create_subscriber( + request, metadata + ) + transcoded_request = _BaseDataSubscriptionServiceRestTransport._BaseCreateSubscriber._get_transcoded_request( + http_options, request + ) + + body = _BaseDataSubscriptionServiceRestTransport._BaseCreateSubscriber._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseDataSubscriptionServiceRestTransport._BaseCreateSubscriber._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.devicesandservices.health_v4.DataSubscriptionServiceClient.CreateSubscriber", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataSubscriptionService", + "rpcName": "CreateSubscriber", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + DataSubscriptionServiceRestTransport._CreateSubscriber._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_create_subscriber(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_subscriber_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.devicesandservices.health_v4.DataSubscriptionServiceClient.create_subscriber", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataSubscriptionService", + "rpcName": "CreateSubscriber", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _CreateSubscription( + _BaseDataSubscriptionServiceRestTransport._BaseCreateSubscription, + DataSubscriptionServiceRestStub, + ): + def __hash__(self): + return hash("DataSubscriptionServiceRestTransport.CreateSubscription") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: data_subscription_service.CreateSubscriptionRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> data_subscription_service.Subscription: + r"""Call the create subscription method over HTTP. + + Args: + request (~.data_subscription_service.CreateSubscriptionRequest): + The request object. Request message for + CreateSubscription. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.data_subscription_service.Subscription: + A subscription to a data collection + for a specific user, to be delivered to + a subscriber. + + """ + + http_options = _BaseDataSubscriptionServiceRestTransport._BaseCreateSubscription._get_http_options() + + request, metadata = self._interceptor.pre_create_subscription( + request, metadata + ) + transcoded_request = _BaseDataSubscriptionServiceRestTransport._BaseCreateSubscription._get_transcoded_request( + http_options, request + ) + + body = _BaseDataSubscriptionServiceRestTransport._BaseCreateSubscription._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseDataSubscriptionServiceRestTransport._BaseCreateSubscription._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.devicesandservices.health_v4.DataSubscriptionServiceClient.CreateSubscription", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataSubscriptionService", + "rpcName": "CreateSubscription", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + DataSubscriptionServiceRestTransport._CreateSubscription._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = data_subscription_service.Subscription() + pb_resp = data_subscription_service.Subscription.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_create_subscription(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_subscription_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = data_subscription_service.Subscription.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.devicesandservices.health_v4.DataSubscriptionServiceClient.create_subscription", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataSubscriptionService", + "rpcName": "CreateSubscription", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _DeleteSubscriber( + _BaseDataSubscriptionServiceRestTransport._BaseDeleteSubscriber, + DataSubscriptionServiceRestStub, + ): + def __hash__(self): + return hash("DataSubscriptionServiceRestTransport.DeleteSubscriber") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: data_subscription_service.DeleteSubscriberRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the delete subscriber method over HTTP. + + Args: + request (~.data_subscription_service.DeleteSubscriberRequest): + The request object. Request message for DeleteSubscriber. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseDataSubscriptionServiceRestTransport._BaseDeleteSubscriber._get_http_options() + + request, metadata = self._interceptor.pre_delete_subscriber( + request, metadata + ) + transcoded_request = _BaseDataSubscriptionServiceRestTransport._BaseDeleteSubscriber._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseDataSubscriptionServiceRestTransport._BaseDeleteSubscriber._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.devicesandservices.health_v4.DataSubscriptionServiceClient.DeleteSubscriber", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataSubscriptionService", + "rpcName": "DeleteSubscriber", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + DataSubscriptionServiceRestTransport._DeleteSubscriber._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_delete_subscriber(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_subscriber_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.devicesandservices.health_v4.DataSubscriptionServiceClient.delete_subscriber", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataSubscriptionService", + "rpcName": "DeleteSubscriber", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _DeleteSubscription( + _BaseDataSubscriptionServiceRestTransport._BaseDeleteSubscription, + DataSubscriptionServiceRestStub, + ): + def __hash__(self): + return hash("DataSubscriptionServiceRestTransport.DeleteSubscription") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: data_subscription_service.DeleteSubscriptionRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + r"""Call the delete subscription method over HTTP. + + Args: + request (~.data_subscription_service.DeleteSubscriptionRequest): + The request object. Request message for + DeleteSubscription. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + + http_options = _BaseDataSubscriptionServiceRestTransport._BaseDeleteSubscription._get_http_options() + + request, metadata = self._interceptor.pre_delete_subscription( + request, metadata + ) + transcoded_request = _BaseDataSubscriptionServiceRestTransport._BaseDeleteSubscription._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseDataSubscriptionServiceRestTransport._BaseDeleteSubscription._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.devicesandservices.health_v4.DataSubscriptionServiceClient.DeleteSubscription", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataSubscriptionService", + "rpcName": "DeleteSubscription", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + DataSubscriptionServiceRestTransport._DeleteSubscription._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + class _ListSubscribers( + _BaseDataSubscriptionServiceRestTransport._BaseListSubscribers, + DataSubscriptionServiceRestStub, + ): + def __hash__(self): + return hash("DataSubscriptionServiceRestTransport.ListSubscribers") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: data_subscription_service.ListSubscribersRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> data_subscription_service.ListSubscribersResponse: + r"""Call the list subscribers method over HTTP. + + Args: + request (~.data_subscription_service.ListSubscribersRequest): + The request object. Request message for ListSubscribers. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.data_subscription_service.ListSubscribersResponse: + Response message for ListSubscribers. + """ + + http_options = _BaseDataSubscriptionServiceRestTransport._BaseListSubscribers._get_http_options() + + request, metadata = self._interceptor.pre_list_subscribers( + request, metadata + ) + transcoded_request = _BaseDataSubscriptionServiceRestTransport._BaseListSubscribers._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseDataSubscriptionServiceRestTransport._BaseListSubscribers._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.devicesandservices.health_v4.DataSubscriptionServiceClient.ListSubscribers", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataSubscriptionService", + "rpcName": "ListSubscribers", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + DataSubscriptionServiceRestTransport._ListSubscribers._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = data_subscription_service.ListSubscribersResponse() + pb_resp = data_subscription_service.ListSubscribersResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_list_subscribers(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_subscribers_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + data_subscription_service.ListSubscribersResponse.to_json( + response + ) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.devicesandservices.health_v4.DataSubscriptionServiceClient.list_subscribers", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataSubscriptionService", + "rpcName": "ListSubscribers", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _ListSubscriptions( + _BaseDataSubscriptionServiceRestTransport._BaseListSubscriptions, + DataSubscriptionServiceRestStub, + ): + def __hash__(self): + return hash("DataSubscriptionServiceRestTransport.ListSubscriptions") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: data_subscription_service.ListSubscriptionsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> data_subscription_service.ListSubscriptionsResponse: + r"""Call the list subscriptions method over HTTP. + + Args: + request (~.data_subscription_service.ListSubscriptionsRequest): + The request object. Request message for + ListSubscriptions. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.data_subscription_service.ListSubscriptionsResponse: + Response message for + ListSubscriptions. + + """ + + http_options = _BaseDataSubscriptionServiceRestTransport._BaseListSubscriptions._get_http_options() + + request, metadata = self._interceptor.pre_list_subscriptions( + request, metadata + ) + transcoded_request = _BaseDataSubscriptionServiceRestTransport._BaseListSubscriptions._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseDataSubscriptionServiceRestTransport._BaseListSubscriptions._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.devicesandservices.health_v4.DataSubscriptionServiceClient.ListSubscriptions", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataSubscriptionService", + "rpcName": "ListSubscriptions", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + DataSubscriptionServiceRestTransport._ListSubscriptions._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = data_subscription_service.ListSubscriptionsResponse() + pb_resp = data_subscription_service.ListSubscriptionsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_list_subscriptions(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_subscriptions_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + data_subscription_service.ListSubscriptionsResponse.to_json( + response + ) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.devicesandservices.health_v4.DataSubscriptionServiceClient.list_subscriptions", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataSubscriptionService", + "rpcName": "ListSubscriptions", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _UpdateSubscriber( + _BaseDataSubscriptionServiceRestTransport._BaseUpdateSubscriber, + DataSubscriptionServiceRestStub, + ): + def __hash__(self): + return hash("DataSubscriptionServiceRestTransport.UpdateSubscriber") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: data_subscription_service.UpdateSubscriberRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the update subscriber method over HTTP. + + Args: + request (~.data_subscription_service.UpdateSubscriberRequest): + The request object. Request message for UpdateSubscriber. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseDataSubscriptionServiceRestTransport._BaseUpdateSubscriber._get_http_options() + + request, metadata = self._interceptor.pre_update_subscriber( + request, metadata + ) + transcoded_request = _BaseDataSubscriptionServiceRestTransport._BaseUpdateSubscriber._get_transcoded_request( + http_options, request + ) + + body = _BaseDataSubscriptionServiceRestTransport._BaseUpdateSubscriber._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseDataSubscriptionServiceRestTransport._BaseUpdateSubscriber._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.devicesandservices.health_v4.DataSubscriptionServiceClient.UpdateSubscriber", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataSubscriptionService", + "rpcName": "UpdateSubscriber", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + DataSubscriptionServiceRestTransport._UpdateSubscriber._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_update_subscriber(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_subscriber_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.devicesandservices.health_v4.DataSubscriptionServiceClient.update_subscriber", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataSubscriptionService", + "rpcName": "UpdateSubscriber", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _UpdateSubscription( + _BaseDataSubscriptionServiceRestTransport._BaseUpdateSubscription, + DataSubscriptionServiceRestStub, + ): + def __hash__(self): + return hash("DataSubscriptionServiceRestTransport.UpdateSubscription") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: data_subscription_service.UpdateSubscriptionRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> data_subscription_service.Subscription: + r"""Call the update subscription method over HTTP. + + Args: + request (~.data_subscription_service.UpdateSubscriptionRequest): + The request object. Request message for + UpdateSubscription. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.data_subscription_service.Subscription: + A subscription to a data collection + for a specific user, to be delivered to + a subscriber. + + """ + + http_options = _BaseDataSubscriptionServiceRestTransport._BaseUpdateSubscription._get_http_options() + + request, metadata = self._interceptor.pre_update_subscription( + request, metadata + ) + transcoded_request = _BaseDataSubscriptionServiceRestTransport._BaseUpdateSubscription._get_transcoded_request( + http_options, request + ) + + body = _BaseDataSubscriptionServiceRestTransport._BaseUpdateSubscription._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseDataSubscriptionServiceRestTransport._BaseUpdateSubscription._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.devicesandservices.health_v4.DataSubscriptionServiceClient.UpdateSubscription", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataSubscriptionService", + "rpcName": "UpdateSubscription", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + DataSubscriptionServiceRestTransport._UpdateSubscription._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = data_subscription_service.Subscription() + pb_resp = data_subscription_service.Subscription.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_update_subscription(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_subscription_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = data_subscription_service.Subscription.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.devicesandservices.health_v4.DataSubscriptionServiceClient.update_subscription", + extra={ + "serviceName": "google.devicesandservices.health.v4.DataSubscriptionService", + "rpcName": "UpdateSubscription", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def create_subscriber( + self, + ) -> Callable[ + [data_subscription_service.CreateSubscriberRequest], operations_pb2.Operation + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateSubscriber(self._session, self._host, self._interceptor) # type: ignore + + @property + def create_subscription( + self, + ) -> Callable[ + [data_subscription_service.CreateSubscriptionRequest], + data_subscription_service.Subscription, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateSubscription(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_subscriber( + self, + ) -> Callable[ + [data_subscription_service.DeleteSubscriberRequest], operations_pb2.Operation + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteSubscriber(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_subscription( + self, + ) -> Callable[ + [data_subscription_service.DeleteSubscriptionRequest], empty_pb2.Empty + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteSubscription(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_subscribers( + self, + ) -> Callable[ + [data_subscription_service.ListSubscribersRequest], + data_subscription_service.ListSubscribersResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListSubscribers(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_subscriptions( + self, + ) -> Callable[ + [data_subscription_service.ListSubscriptionsRequest], + data_subscription_service.ListSubscriptionsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListSubscriptions(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_subscriber( + self, + ) -> Callable[ + [data_subscription_service.UpdateSubscriberRequest], operations_pb2.Operation + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateSubscriber(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_subscription( + self, + ) -> Callable[ + [data_subscription_service.UpdateSubscriptionRequest], + data_subscription_service.Subscription, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateSubscription(self._session, self._host, self._interceptor) # type: ignore + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("DataSubscriptionServiceRestTransport",) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/transports/rest_base.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/transports/rest_base.py new file mode 100644 index 000000000000..7bcda2cb92e2 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/data_subscription_service/transports/rest_base.py @@ -0,0 +1,509 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +import google.protobuf.empty_pb2 as empty_pb2 # type: ignore +from google.api_core import gapic_v1, path_template +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format + +from google.devicesandservices.health_v4.types import data_subscription_service + +from .base import DEFAULT_CLIENT_INFO, DataSubscriptionServiceTransport + + +class _BaseDataSubscriptionServiceRestTransport(DataSubscriptionServiceTransport): + """Base REST backend transport for DataSubscriptionService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "health.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'health.googleapis.com'). + credentials (Optional[Any]): 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. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseCreateSubscriber: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v4/{parent=projects/*}/subscribers", + "body": "subscriber", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = data_subscription_service.CreateSubscriberRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDataSubscriptionServiceRestTransport._BaseCreateSubscriber._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseCreateSubscription: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v4/{parent=projects/*/subscribers/*}/subscriptions", + "body": "subscription", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = data_subscription_service.CreateSubscriptionRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDataSubscriptionServiceRestTransport._BaseCreateSubscription._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseDeleteSubscriber: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/v4/{name=projects/*/subscribers/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = data_subscription_service.DeleteSubscriberRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDataSubscriptionServiceRestTransport._BaseDeleteSubscriber._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseDeleteSubscription: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/v4/{name=projects/*/subscribers/*/subscriptions/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = data_subscription_service.DeleteSubscriptionRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDataSubscriptionServiceRestTransport._BaseDeleteSubscription._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListSubscribers: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v4/{parent=projects/*}/subscribers", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = data_subscription_service.ListSubscribersRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDataSubscriptionServiceRestTransport._BaseListSubscribers._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListSubscriptions: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v4/{parent=projects/*/subscribers/*}/subscriptions", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = data_subscription_service.ListSubscriptionsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDataSubscriptionServiceRestTransport._BaseListSubscriptions._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateSubscriber: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v4/{subscriber.name=projects/*/subscribers/*}", + "body": "subscriber", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = data_subscription_service.UpdateSubscriberRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDataSubscriptionServiceRestTransport._BaseUpdateSubscriber._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateSubscription: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v4/{subscription.name=projects/*/subscribers/*/subscriptions/*}", + "body": "subscription", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = data_subscription_service.UpdateSubscriptionRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDataSubscriptionServiceRestTransport._BaseUpdateSubscription._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseDataSubscriptionServiceRestTransport",) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/__init__.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/__init__.py new file mode 100644 index 000000000000..782c42252ee1 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .async_client import HealthProfileServiceAsyncClient +from .client import HealthProfileServiceClient + +__all__ = ( + "HealthProfileServiceClient", + "HealthProfileServiceAsyncClient", +) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/async_client.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/async_client.py new file mode 100644 index 000000000000..19b42f6ceb01 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/async_client.py @@ -0,0 +1,1270 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 logging as std_logging +import re +from collections import OrderedDict +from typing import ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, +) + +import google.protobuf +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.api_core.client_options import ClientOptions +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.devicesandservices.health_v4 import gapic_version as package_version + +try: + OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +import google.protobuf.duration_pb2 as duration_pb2 # type: ignore +import google.protobuf.field_mask_pb2 as field_mask_pb2 # type: ignore +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore +import google.type.date_pb2 as date_pb2 # type: ignore + +from google.devicesandservices.health_v4.services.health_profile_service import pagers +from google.devicesandservices.health_v4.types import health_profile + +from .client import HealthProfileServiceClient +from .transports.base import DEFAULT_CLIENT_INFO, HealthProfileServiceTransport +from .transports.grpc_asyncio import HealthProfileServiceGrpcAsyncIOTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class HealthProfileServiceAsyncClient: + """Health Profile Service""" + + _client: HealthProfileServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = HealthProfileServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = HealthProfileServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = HealthProfileServiceClient._DEFAULT_ENDPOINT_TEMPLATE + _DEFAULT_UNIVERSE = HealthProfileServiceClient._DEFAULT_UNIVERSE + + identity_path = staticmethod(HealthProfileServiceClient.identity_path) + parse_identity_path = staticmethod(HealthProfileServiceClient.parse_identity_path) + irn_profile_path = staticmethod(HealthProfileServiceClient.irn_profile_path) + parse_irn_profile_path = staticmethod( + HealthProfileServiceClient.parse_irn_profile_path + ) + paired_device_path = staticmethod(HealthProfileServiceClient.paired_device_path) + parse_paired_device_path = staticmethod( + HealthProfileServiceClient.parse_paired_device_path + ) + profile_path = staticmethod(HealthProfileServiceClient.profile_path) + parse_profile_path = staticmethod(HealthProfileServiceClient.parse_profile_path) + settings_path = staticmethod(HealthProfileServiceClient.settings_path) + parse_settings_path = staticmethod(HealthProfileServiceClient.parse_settings_path) + common_billing_account_path = staticmethod( + HealthProfileServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + HealthProfileServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(HealthProfileServiceClient.common_folder_path) + parse_common_folder_path = staticmethod( + HealthProfileServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + HealthProfileServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + HealthProfileServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod(HealthProfileServiceClient.common_project_path) + parse_common_project_path = staticmethod( + HealthProfileServiceClient.parse_common_project_path + ) + common_location_path = staticmethod(HealthProfileServiceClient.common_location_path) + parse_common_location_path = staticmethod( + HealthProfileServiceClient.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: + HealthProfileServiceAsyncClient: The constructed client. + """ + sa_info_func = ( + HealthProfileServiceClient.from_service_account_info.__func__ # type: ignore + ) + return sa_info_func(HealthProfileServiceAsyncClient, info, *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: + HealthProfileServiceAsyncClient: The constructed client. + """ + sa_file_func = ( + HealthProfileServiceClient.from_service_account_file.__func__ # type: ignore + ) + return sa_file_func(HealthProfileServiceAsyncClient, filename, *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 variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return HealthProfileServiceClient.get_mtls_endpoint_and_cert_source( + client_options + ) # type: ignore + + @property + def transport(self) -> HealthProfileServiceTransport: + """Returns the transport used by the client instance. + + Returns: + HealthProfileServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self) -> str: + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = HealthProfileServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + HealthProfileServiceTransport, + Callable[..., HealthProfileServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the health profile service async 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 (Optional[Union[str,HealthProfileServiceTransport,Callable[..., HealthProfileServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the HealthProfileServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "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). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS 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. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + 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. + """ + self._client = HealthProfileServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.devicesandservices.health_v4.HealthProfileServiceAsyncClient`.", + extra={ + "serviceName": "google.devicesandservices.health.v4.HealthProfileService", + "universeDomain": getattr( + self._client._transport._credentials, "universe_domain", "" + ), + "credentialsType": f"{type(self._client._transport._credentials).__module__}.{type(self._client._transport._credentials).__qualname__}", + "credentialsInfo": getattr( + self.transport._credentials, "get_cred_info", lambda: None + )(), + } + if hasattr(self._client._transport, "_credentials") + else { + "serviceName": "google.devicesandservices.health.v4.HealthProfileService", + "credentialsType": None, + }, + ) + + async def get_profile( + self, + request: Optional[Union[health_profile.GetProfileRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> health_profile.Profile: + r"""Returns user Profile details. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + async def sample_get_profile(): + # Create a client + client = health_v4.HealthProfileServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.GetProfileRequest( + name="name_value", + ) + + # Make the request + response = await client.get_profile(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.devicesandservices.health_v4.types.GetProfileRequest, dict]]): + The request object. Request message for getting Profile + details. + name (:class:`str`): + Required. The name of the Profile. Format: + ``users/me/profile``. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.types.Profile: + Profile details. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, health_profile.GetProfileRequest): + request = health_profile.GetProfileRequest(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._client._transport._wrapped_methods[ + self._client._transport.get_profile + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_profile( + self, + request: Optional[Union[health_profile.UpdateProfileRequest, dict]] = None, + *, + profile: Optional[health_profile.Profile] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> health_profile.Profile: + r"""Updates the user's profile details. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + async def sample_update_profile(): + # Create a client + client = health_v4.HealthProfileServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.UpdateProfileRequest( + ) + + # Make the request + response = await client.update_profile(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.devicesandservices.health_v4.types.UpdateProfileRequest, dict]]): + The request object. Request message for updating Profile + details. + profile (:class:`google.devicesandservices.health_v4.types.Profile`): + Required. Profile details. + This corresponds to the ``profile`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Optional. The list of fields to be + updated. + + 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_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.types.Profile: + Profile details. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [profile, update_mask] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, health_profile.UpdateProfileRequest): + request = health_profile.UpdateProfileRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if profile is not None: + request.profile = profile + 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._client._transport._wrapped_methods[ + self._client._transport.update_profile + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("profile.name", request.profile.name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_settings( + self, + request: Optional[Union[health_profile.GetSettingsRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> health_profile.Settings: + r"""Returns user settings details. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + async def sample_get_settings(): + # Create a client + client = health_v4.HealthProfileServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.GetSettingsRequest( + name="name_value", + ) + + # Make the request + response = await client.get_settings(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.devicesandservices.health_v4.types.GetSettingsRequest, dict]]): + The request object. Request message for getting Settings + details. + name (:class:`str`): + Required. The name of the Settings. Format: + ``users/me/settings``. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.types.Settings: + Settings details. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, health_profile.GetSettingsRequest): + request = health_profile.GetSettingsRequest(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._client._transport._wrapped_methods[ + self._client._transport.get_settings + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_settings( + self, + request: Optional[Union[health_profile.UpdateSettingsRequest, dict]] = None, + *, + settings: Optional[health_profile.Settings] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> health_profile.Settings: + r"""Updates the user's settings details. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + async def sample_update_settings(): + # Create a client + client = health_v4.HealthProfileServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.UpdateSettingsRequest( + ) + + # Make the request + response = await client.update_settings(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.devicesandservices.health_v4.types.UpdateSettingsRequest, dict]]): + The request object. Request message for updating Settings + details. + settings (:class:`google.devicesandservices.health_v4.types.Settings`): + Required. Settings details + This corresponds to the ``settings`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Optional. The list of fields to be + updated. + + 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_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.types.Settings: + Settings details. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [settings, update_mask] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, health_profile.UpdateSettingsRequest): + request = health_profile.UpdateSettingsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if settings is not None: + request.settings = settings + 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._client._transport._wrapped_methods[ + self._client._transport.update_settings + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("settings.name", request.settings.name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_identity( + self, + request: Optional[Union[health_profile.GetIdentityRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> health_profile.Identity: + r"""Gets the user's identity. + + It includes the legacy Fitbit user ID and the Google + user ID and it can be used by migrating clients to map + identifiers between the two systems. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + async def sample_get_identity(): + # Create a client + client = health_v4.HealthProfileServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.GetIdentityRequest( + name="name_value", + ) + + # Make the request + response = await client.get_identity(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.devicesandservices.health_v4.types.GetIdentityRequest, dict]]): + The request object. Request message for getting Identity + details. + name (:class:`str`): + Required. The resource name of the Identity. Format: + ``users/me/identity`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.types.Identity: + Represents details about the Google + user's identity. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, health_profile.GetIdentityRequest): + request = health_profile.GetIdentityRequest(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._client._transport._wrapped_methods[ + self._client._transport.get_identity + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_irn_profile( + self, + request: Optional[Union[health_profile.GetIrnProfileRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> health_profile.IrnProfile: + r"""Returns user's IRN Profile details. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + async def sample_get_irn_profile(): + # Create a client + client = health_v4.HealthProfileServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.GetIrnProfileRequest( + name="name_value", + ) + + # Make the request + response = await client.get_irn_profile(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.devicesandservices.health_v4.types.GetIrnProfileRequest, dict]]): + The request object. Request message for getting IRN + Profile details. + name (:class:`str`): + Required. The resource name of the IRN Profile. Format: + ``users/{user}/irnProfile`` Example: + ``users/1234567890/irnProfile`` or + ``users/me/irnProfile`` The {user} ID is a + system-generated Google Health API user ID, a string of + 1-63 characters consisting of lowercase and uppercase + letters, numbers, and hyphens. The literal ``me`` can + also be used to refer to the authenticated user. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.types.IrnProfile: + Irregular Rhythm Notifications (IRN) + Profile details. + The Irregular Rhythm Notifications (IRN) + feature checks for signs of atrial + fibrillation (AFib). The IrnProfile + details include information about the + user's onboarding status, enrollment + status, and the last update time of + analyzable data for this feature. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, health_profile.GetIrnProfileRequest): + request = health_profile.GetIrnProfileRequest(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._client._transport._wrapped_methods[ + self._client._transport.get_irn_profile + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_paired_device( + self, + request: Optional[Union[health_profile.GetPairedDeviceRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> health_profile.PairedDevice: + r"""Returns user's Device. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + async def sample_get_paired_device(): + # Create a client + client = health_v4.HealthProfileServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.GetPairedDeviceRequest( + name="name_value", + ) + + # Make the request + response = await client.get_paired_device(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.devicesandservices.health_v4.types.GetPairedDeviceRequest, dict]]): + The request object. Request message for getting a Device. + name (:class:`str`): + Required. The name of the device to + retrieve. Format: + users/{user}/devices/{device} + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.types.PairedDevice: + User's Paired 1P Device + + The PairedDevice details include + information about the device type, + battery status, battery level, last sync + time, device version, mac address, and + features. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, health_profile.GetPairedDeviceRequest): + request = health_profile.GetPairedDeviceRequest(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._client._transport._wrapped_methods[ + self._client._transport.get_paired_device + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_paired_devices( + self, + request: Optional[Union[health_profile.ListPairedDevicesRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListPairedDevicesAsyncPager: + r"""Returns the user's list of paired 1P trackers and + smartwatches. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + async def sample_list_paired_devices(): + # Create a client + client = health_v4.HealthProfileServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.ListPairedDevicesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_paired_devices(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.devicesandservices.health_v4.types.ListPairedDevicesRequest, dict]]): + The request object. Request message for listing Devices. + parent (:class:`str`): + Required. The parent, which owns this + collection of devices. Format: + users/{user} + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.services.health_profile_service.pagers.ListPairedDevicesAsyncPager: + Response message for + ListPairedDevices. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, health_profile.ListPairedDevicesRequest): + request = health_profile.ListPairedDevicesRequest(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._client._transport._wrapped_methods[ + self._client._transport.list_paired_devices + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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.ListPairedDevicesAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "HealthProfileServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("HealthProfileServiceAsyncClient",) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/client.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/client.py new file mode 100644 index 000000000000..a0779f62f91b --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/client.py @@ -0,0 +1,1730 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 json +import logging as std_logging +import os +import re +import warnings +from collections import OrderedDict +from http import HTTPStatus +from typing import ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) + +import google.protobuf +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.devicesandservices.health_v4 import gapic_version as package_version + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + +import google.protobuf.duration_pb2 as duration_pb2 # type: ignore +import google.protobuf.field_mask_pb2 as field_mask_pb2 # type: ignore +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore +import google.type.date_pb2 as date_pb2 # type: ignore + +from google.devicesandservices.health_v4.services.health_profile_service import pagers +from google.devicesandservices.health_v4.types import health_profile + +from .transports.base import DEFAULT_CLIENT_INFO, HealthProfileServiceTransport +from .transports.grpc import HealthProfileServiceGrpcTransport +from .transports.grpc_asyncio import HealthProfileServiceGrpcAsyncIOTransport +from .transports.rest import HealthProfileServiceRestTransport + + +class HealthProfileServiceClientMeta(type): + """Metaclass for the HealthProfileService 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[HealthProfileServiceTransport]] + _transport_registry["grpc"] = HealthProfileServiceGrpcTransport + _transport_registry["grpc_asyncio"] = HealthProfileServiceGrpcAsyncIOTransport + _transport_registry["rest"] = HealthProfileServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[HealthProfileServiceTransport]: + """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 HealthProfileServiceClient(metaclass=HealthProfileServiceClientMeta): + """Health Profile Service""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint) -> Optional[str]: + """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: + Optional[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) + if m is None: + # Could not parse api_endpoint; return as-is. + return 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") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "health.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "health.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @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: + HealthProfileServiceClient: 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: + HealthProfileServiceClient: 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) -> HealthProfileServiceTransport: + """Returns the transport used by the client instance. + + Returns: + HealthProfileServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def identity_path( + user: str, + ) -> str: + """Returns a fully-qualified identity string.""" + return "users/{user}/identity".format( + user=user, + ) + + @staticmethod + def parse_identity_path(path: str) -> Dict[str, str]: + """Parses a identity path into its component segments.""" + m = re.match(r"^users/(?P.+?)/identity$", path) + return m.groupdict() if m else {} + + @staticmethod + def irn_profile_path( + user: str, + ) -> str: + """Returns a fully-qualified irn_profile string.""" + return "users/{user}/irnProfile".format( + user=user, + ) + + @staticmethod + def parse_irn_profile_path(path: str) -> Dict[str, str]: + """Parses a irn_profile path into its component segments.""" + m = re.match(r"^users/(?P.+?)/irnProfile$", path) + return m.groupdict() if m else {} + + @staticmethod + def paired_device_path( + user: str, + paired_device: str, + ) -> str: + """Returns a fully-qualified paired_device string.""" + return "users/{user}/pairedDevices/{paired_device}".format( + user=user, + paired_device=paired_device, + ) + + @staticmethod + def parse_paired_device_path(path: str) -> Dict[str, str]: + """Parses a paired_device path into its component segments.""" + m = re.match( + r"^users/(?P.+?)/pairedDevices/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def profile_path( + user: str, + ) -> str: + """Returns a fully-qualified profile string.""" + return "users/{user}/profile".format( + user=user, + ) + + @staticmethod + def parse_profile_path(path: str) -> Dict[str, str]: + """Parses a profile path into its component segments.""" + m = re.match(r"^users/(?P.+?)/profile$", path) + return m.groupdict() if m else {} + + @staticmethod + def settings_path( + user: str, + ) -> str: + """Returns a fully-qualified settings string.""" + return "users/{user}/settings".format( + user=user, + ) + + @staticmethod + def parse_settings_path(path: str) -> Dict[str, str]: + """Parses a settings path into its component segments.""" + m = re.match(r"^users/(?P.+?)/settings$", 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 + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = HealthProfileServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + 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: + 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 + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = HealthProfileServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ) -> str: + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = HealthProfileServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = HealthProfileServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = HealthProfileServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], universe_domain_env: Optional[str] + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = HealthProfileServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self) -> str: + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + HealthProfileServiceTransport, + Callable[..., HealthProfileServiceTransport], + ] + ] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the health profile 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 (Optional[Union[str,HealthProfileServiceTransport,Callable[..., HealthProfileServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the HealthProfileServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "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). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS 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. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + 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. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict(self._client_options) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr(self._client_options, "universe_domain", None) + + self._use_client_cert, self._use_mtls_endpoint, self._universe_domain_env = ( + HealthProfileServiceClient._read_environment_variables() + ) + self._client_cert_source = HealthProfileServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = HealthProfileServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint: str = "" # updated below, depending on `transport` + + # Initialize the universe domain validation. + self._is_universe_domain_valid = False + + if CLIENT_LOGGING_SUPPORTED: # pragma: NO COVER + # Setup logging. + client_logging.initialize_logging() + + api_key_value = getattr(self._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. + transport_provided = isinstance(transport, HealthProfileServiceTransport) + if transport_provided: + # transport is a HealthProfileServiceTransport instance. + if credentials or self._client_options.credentials_file or api_key_value: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes directly." + ) + self._transport = cast(HealthProfileServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or HealthProfileServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + 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_init: Union[ + Type[HealthProfileServiceTransport], + Callable[..., HealthProfileServiceTransport], + ] = ( + HealthProfileServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., HealthProfileServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + api_audience=self._client_options.api_audience, + ) + + if "async" not in str(self._transport): + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.devicesandservices.health_v4.HealthProfileServiceClient`.", + extra={ + "serviceName": "google.devicesandservices.health.v4.HealthProfileService", + "universeDomain": getattr( + self._transport._credentials, "universe_domain", "" + ), + "credentialsType": f"{type(self._transport._credentials).__module__}.{type(self._transport._credentials).__qualname__}", + "credentialsInfo": getattr( + self.transport._credentials, "get_cred_info", lambda: None + )(), + } + if hasattr(self._transport, "_credentials") + else { + "serviceName": "google.devicesandservices.health.v4.HealthProfileService", + "credentialsType": None, + }, + ) + + def get_profile( + self, + request: Optional[Union[health_profile.GetProfileRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> health_profile.Profile: + r"""Returns user Profile details. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + def sample_get_profile(): + # Create a client + client = health_v4.HealthProfileServiceClient() + + # Initialize request argument(s) + request = health_v4.GetProfileRequest( + name="name_value", + ) + + # Make the request + response = client.get_profile(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.devicesandservices.health_v4.types.GetProfileRequest, dict]): + The request object. Request message for getting Profile + details. + name (str): + Required. The name of the Profile. Format: + ``users/me/profile``. + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.types.Profile: + Profile details. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, health_profile.GetProfileRequest): + request = health_profile.GetProfileRequest(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_profile] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_profile( + self, + request: Optional[Union[health_profile.UpdateProfileRequest, dict]] = None, + *, + profile: Optional[health_profile.Profile] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> health_profile.Profile: + r"""Updates the user's profile details. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + def sample_update_profile(): + # Create a client + client = health_v4.HealthProfileServiceClient() + + # Initialize request argument(s) + request = health_v4.UpdateProfileRequest( + ) + + # Make the request + response = client.update_profile(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.devicesandservices.health_v4.types.UpdateProfileRequest, dict]): + The request object. Request message for updating Profile + details. + profile (google.devicesandservices.health_v4.types.Profile): + Required. Profile details. + This corresponds to the ``profile`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Optional. The list of fields to be + updated. + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.types.Profile: + Profile details. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [profile, update_mask] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, health_profile.UpdateProfileRequest): + request = health_profile.UpdateProfileRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if profile is not None: + request.profile = profile + 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_profile] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("profile.name", request.profile.name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_settings( + self, + request: Optional[Union[health_profile.GetSettingsRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> health_profile.Settings: + r"""Returns user settings details. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + def sample_get_settings(): + # Create a client + client = health_v4.HealthProfileServiceClient() + + # Initialize request argument(s) + request = health_v4.GetSettingsRequest( + name="name_value", + ) + + # Make the request + response = client.get_settings(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.devicesandservices.health_v4.types.GetSettingsRequest, dict]): + The request object. Request message for getting Settings + details. + name (str): + Required. The name of the Settings. Format: + ``users/me/settings``. + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.types.Settings: + Settings details. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, health_profile.GetSettingsRequest): + request = health_profile.GetSettingsRequest(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_settings] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_settings( + self, + request: Optional[Union[health_profile.UpdateSettingsRequest, dict]] = None, + *, + settings: Optional[health_profile.Settings] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> health_profile.Settings: + r"""Updates the user's settings details. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + def sample_update_settings(): + # Create a client + client = health_v4.HealthProfileServiceClient() + + # Initialize request argument(s) + request = health_v4.UpdateSettingsRequest( + ) + + # Make the request + response = client.update_settings(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.devicesandservices.health_v4.types.UpdateSettingsRequest, dict]): + The request object. Request message for updating Settings + details. + settings (google.devicesandservices.health_v4.types.Settings): + Required. Settings details + This corresponds to the ``settings`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Optional. The list of fields to be + updated. + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.types.Settings: + Settings details. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [settings, update_mask] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, health_profile.UpdateSettingsRequest): + request = health_profile.UpdateSettingsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if settings is not None: + request.settings = settings + 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_settings] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("settings.name", request.settings.name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_identity( + self, + request: Optional[Union[health_profile.GetIdentityRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> health_profile.Identity: + r"""Gets the user's identity. + + It includes the legacy Fitbit user ID and the Google + user ID and it can be used by migrating clients to map + identifiers between the two systems. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + def sample_get_identity(): + # Create a client + client = health_v4.HealthProfileServiceClient() + + # Initialize request argument(s) + request = health_v4.GetIdentityRequest( + name="name_value", + ) + + # Make the request + response = client.get_identity(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.devicesandservices.health_v4.types.GetIdentityRequest, dict]): + The request object. Request message for getting Identity + details. + name (str): + Required. The resource name of the Identity. Format: + ``users/me/identity`` + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.types.Identity: + Represents details about the Google + user's identity. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, health_profile.GetIdentityRequest): + request = health_profile.GetIdentityRequest(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_identity] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_irn_profile( + self, + request: Optional[Union[health_profile.GetIrnProfileRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> health_profile.IrnProfile: + r"""Returns user's IRN Profile details. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + def sample_get_irn_profile(): + # Create a client + client = health_v4.HealthProfileServiceClient() + + # Initialize request argument(s) + request = health_v4.GetIrnProfileRequest( + name="name_value", + ) + + # Make the request + response = client.get_irn_profile(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.devicesandservices.health_v4.types.GetIrnProfileRequest, dict]): + The request object. Request message for getting IRN + Profile details. + name (str): + Required. The resource name of the IRN Profile. Format: + ``users/{user}/irnProfile`` Example: + ``users/1234567890/irnProfile`` or + ``users/me/irnProfile`` The {user} ID is a + system-generated Google Health API user ID, a string of + 1-63 characters consisting of lowercase and uppercase + letters, numbers, and hyphens. The literal ``me`` can + also be used to refer to the authenticated user. + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.types.IrnProfile: + Irregular Rhythm Notifications (IRN) + Profile details. + The Irregular Rhythm Notifications (IRN) + feature checks for signs of atrial + fibrillation (AFib). The IrnProfile + details include information about the + user's onboarding status, enrollment + status, and the last update time of + analyzable data for this feature. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, health_profile.GetIrnProfileRequest): + request = health_profile.GetIrnProfileRequest(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_irn_profile] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_paired_device( + self, + request: Optional[Union[health_profile.GetPairedDeviceRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> health_profile.PairedDevice: + r"""Returns user's Device. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + def sample_get_paired_device(): + # Create a client + client = health_v4.HealthProfileServiceClient() + + # Initialize request argument(s) + request = health_v4.GetPairedDeviceRequest( + name="name_value", + ) + + # Make the request + response = client.get_paired_device(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.devicesandservices.health_v4.types.GetPairedDeviceRequest, dict]): + The request object. Request message for getting a Device. + name (str): + Required. The name of the device to + retrieve. Format: + users/{user}/devices/{device} + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.types.PairedDevice: + User's Paired 1P Device + + The PairedDevice details include + information about the device type, + battery status, battery level, last sync + time, device version, mac address, and + features. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, health_profile.GetPairedDeviceRequest): + request = health_profile.GetPairedDeviceRequest(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_paired_device] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_paired_devices( + self, + request: Optional[Union[health_profile.ListPairedDevicesRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListPairedDevicesPager: + r"""Returns the user's list of paired 1P trackers and + smartwatches. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.devicesandservices import health_v4 + + def sample_list_paired_devices(): + # Create a client + client = health_v4.HealthProfileServiceClient() + + # Initialize request argument(s) + request = health_v4.ListPairedDevicesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_paired_devices(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.devicesandservices.health_v4.types.ListPairedDevicesRequest, dict]): + The request object. Request message for listing Devices. + parent (str): + Required. The parent, which owns this + collection of devices. Format: + users/{user} + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.devicesandservices.health_v4.services.health_profile_service.pagers.ListPairedDevicesPager: + Response message for + ListPairedDevices. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, health_profile.ListPairedDevicesRequest): + request = health_profile.ListPairedDevicesRequest(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_paired_devices] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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.ListPairedDevicesPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "HealthProfileServiceClient": + 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() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("HealthProfileServiceClient",) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/pagers.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/pagers.py new file mode 100644 index 000000000000..aa687484b401 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/pagers.py @@ -0,0 +1,197 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, + Union, +) + +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import retry_async as retries_async + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] + OptionalAsyncRetry = Union[ + retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore + +from google.devicesandservices.health_v4.types import health_profile + + +class ListPairedDevicesPager: + """A pager for iterating through ``list_paired_devices`` requests. + + This class thinly wraps an initial + :class:`google.devicesandservices.health_v4.types.ListPairedDevicesResponse` object, and + provides an ``__iter__`` method to iterate through its + ``paired_devices`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListPairedDevices`` requests and continue to iterate + through the ``paired_devices`` field on the + corresponding responses. + + All the usual :class:`google.devicesandservices.health_v4.types.ListPairedDevicesResponse` + 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[..., health_profile.ListPairedDevicesResponse], + request: health_profile.ListPairedDevicesRequest, + response: health_profile.ListPairedDevicesResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.devicesandservices.health_v4.types.ListPairedDevicesRequest): + The initial request object. + response (google.devicesandservices.health_v4.types.ListPairedDevicesResponse): + The initial response object. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = health_profile.ListPairedDevicesRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[health_profile.ListPairedDevicesResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __iter__(self) -> Iterator[health_profile.PairedDevice]: + for page in self.pages: + yield from page.paired_devices + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListPairedDevicesAsyncPager: + """A pager for iterating through ``list_paired_devices`` requests. + + This class thinly wraps an initial + :class:`google.devicesandservices.health_v4.types.ListPairedDevicesResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``paired_devices`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListPairedDevices`` requests and continue to iterate + through the ``paired_devices`` field on the + corresponding responses. + + All the usual :class:`google.devicesandservices.health_v4.types.ListPairedDevicesResponse` + 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[health_profile.ListPairedDevicesResponse]], + request: health_profile.ListPairedDevicesRequest, + response: health_profile.ListPairedDevicesResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.devicesandservices.health_v4.types.ListPairedDevicesRequest): + The initial request object. + response (google.devicesandservices.health_v4.types.ListPairedDevicesResponse): + The initial response object. + retry (google.api_core.retry.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = health_profile.ListPairedDevicesRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[health_profile.ListPairedDevicesResponse]: + 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, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __aiter__(self) -> AsyncIterator[health_profile.PairedDevice]: + async def async_generator(): + async for page in self.pages: + for response in page.paired_devices: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/transports/README.rst b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/transports/README.rst new file mode 100644 index 000000000000..c56ff6ca3315 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/transports/README.rst @@ -0,0 +1,10 @@ + +transport inheritance structure +_______________________________ + +``HealthProfileServiceTransport`` is the ABC for all transports. + +- public child ``HealthProfileServiceGrpcTransport`` for sync gRPC transport (defined in ``grpc.py``). +- public child ``HealthProfileServiceGrpcAsyncIOTransport`` for async gRPC transport (defined in ``grpc_asyncio.py``). +- private child ``_BaseHealthProfileServiceRestTransport`` for base REST transport with inner classes ``_BaseMETHOD`` (defined in ``rest_base.py``). +- public child ``HealthProfileServiceRestTransport`` for sync REST transport with inner classes ``METHOD`` derived from the parent's corresponding ``_BaseMETHOD`` classes (defined in ``rest.py``). diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/transports/__init__.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/transports/__init__.py new file mode 100644 index 000000000000..9258aee90a44 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/transports/__init__.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 HealthProfileServiceTransport +from .grpc import HealthProfileServiceGrpcTransport +from .grpc_asyncio import HealthProfileServiceGrpcAsyncIOTransport +from .rest import HealthProfileServiceRestInterceptor, HealthProfileServiceRestTransport + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[HealthProfileServiceTransport]] +_transport_registry["grpc"] = HealthProfileServiceGrpcTransport +_transport_registry["grpc_asyncio"] = HealthProfileServiceGrpcAsyncIOTransport +_transport_registry["rest"] = HealthProfileServiceRestTransport + +__all__ = ( + "HealthProfileServiceTransport", + "HealthProfileServiceGrpcTransport", + "HealthProfileServiceGrpcAsyncIOTransport", + "HealthProfileServiceRestTransport", + "HealthProfileServiceRestInterceptor", +) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/transports/base.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/transports/base.py new file mode 100644 index 000000000000..61fbc9dff29a --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/transports/base.py @@ -0,0 +1,338 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union + +import google.api_core +import google.auth # type: ignore +import google.protobuf +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.devicesandservices.health_v4 import gapic_version as package_version +from google.devicesandservices.health_v4.types import health_profile + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class HealthProfileServiceTransport(abc.ABC): + """Abstract transport class for HealthProfileService.""" + + AUTH_SCOPES = ( + "https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly", + "https://www.googleapis.com/auth/googlehealth.ecg.readonly", + "https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.readonly", + "https://www.googleapis.com/auth/googlehealth.irn.readonly", + "https://www.googleapis.com/auth/googlehealth.profile.readonly", + "https://www.googleapis.com/auth/googlehealth.settings.readonly", + "https://www.googleapis.com/auth/googlehealth.sleep.readonly", + ) + + DEFAULT_HOST: str = "health.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'health.googleapis.com'). + 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]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + 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. + api_audience (Optional[str]): The intended audience for the API calls + to the service that will be set when using certain 3rd party + authentication flows. Audience is typically a resource identifier. + If not set, the host value will be used as a default. + """ + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # 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=scopes, + quota_project_id=quota_project_id, + default_scopes=self.AUTH_SCOPES, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + scopes=scopes, + quota_project_id=quota_project_id, + default_scopes=self.AUTH_SCOPES, + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr(service_account.Credentials, "with_always_use_jwt_access") + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + self._wrapped_methods: Dict[Callable, Callable] = {} + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.get_profile: gapic_v1.method.wrap_method( + self.get_profile, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.update_profile: gapic_v1.method.wrap_method( + self.update_profile, + default_timeout=60.0, + client_info=client_info, + ), + self.get_settings: gapic_v1.method.wrap_method( + self.get_settings, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.update_settings: gapic_v1.method.wrap_method( + self.update_settings, + default_timeout=60.0, + client_info=client_info, + ), + self.get_identity: gapic_v1.method.wrap_method( + self.get_identity, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.get_irn_profile: gapic_v1.method.wrap_method( + self.get_irn_profile, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.get_paired_device: gapic_v1.method.wrap_method( + self.get_paired_device, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.list_paired_devices: gapic_v1.method.wrap_method( + self.list_paired_devices, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + 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 get_profile( + self, + ) -> Callable[ + [health_profile.GetProfileRequest], + Union[health_profile.Profile, Awaitable[health_profile.Profile]], + ]: + raise NotImplementedError() + + @property + def update_profile( + self, + ) -> Callable[ + [health_profile.UpdateProfileRequest], + Union[health_profile.Profile, Awaitable[health_profile.Profile]], + ]: + raise NotImplementedError() + + @property + def get_settings( + self, + ) -> Callable[ + [health_profile.GetSettingsRequest], + Union[health_profile.Settings, Awaitable[health_profile.Settings]], + ]: + raise NotImplementedError() + + @property + def update_settings( + self, + ) -> Callable[ + [health_profile.UpdateSettingsRequest], + Union[health_profile.Settings, Awaitable[health_profile.Settings]], + ]: + raise NotImplementedError() + + @property + def get_identity( + self, + ) -> Callable[ + [health_profile.GetIdentityRequest], + Union[health_profile.Identity, Awaitable[health_profile.Identity]], + ]: + raise NotImplementedError() + + @property + def get_irn_profile( + self, + ) -> Callable[ + [health_profile.GetIrnProfileRequest], + Union[health_profile.IrnProfile, Awaitable[health_profile.IrnProfile]], + ]: + raise NotImplementedError() + + @property + def get_paired_device( + self, + ) -> Callable[ + [health_profile.GetPairedDeviceRequest], + Union[health_profile.PairedDevice, Awaitable[health_profile.PairedDevice]], + ]: + raise NotImplementedError() + + @property + def list_paired_devices( + self, + ) -> Callable[ + [health_profile.ListPairedDevicesRequest], + Union[ + health_profile.ListPairedDevicesResponse, + Awaitable[health_profile.ListPairedDevicesResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("HealthProfileServiceTransport",) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/transports/grpc.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/transports/grpc.py new file mode 100644 index 000000000000..c8798c614e85 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/transports/grpc.py @@ -0,0 +1,552 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 json +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +import google.auth # type: ignore +import google.protobuf.message +import grpc # type: ignore +import proto # type: ignore +from google.api_core import gapic_v1, grpc_helpers +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson + +from google.devicesandservices.health_v4.types import health_profile + +from .base import DEFAULT_CLIENT_INFO, HealthProfileServiceTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor(grpc.UnaryUnaryClientInterceptor): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = f"{type(request).__name__}: {pickle.dumps(request)!r}" + + request_metadata = { + key: value.decode("utf-8") if isinstance(value, bytes) else value + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.devicesandservices.health.v4.HealthProfileService", + "rpcName": str(client_call_details.method), + "request": grpc_request, + "metadata": grpc_request["metadata"], + }, + ) + response = continuation(client_call_details, request) + if logging_enabled: # pragma: NO COVER + response_metadata = response.trailing_metadata() + # Convert gRPC metadata `` to list of tuples + metadata = ( + dict([(k, str(v)) for k, v in response_metadata]) + if response_metadata + else None + ) + result = response.result() + if isinstance(result, proto.Message): + response_payload = type(result).to_json(result) + elif isinstance(result, google.protobuf.message.Message): + response_payload = MessageToJson(result) + else: + response_payload = f"{type(result).__name__}: {pickle.dumps(result)!r}" + grpc_response = { + "payload": response_payload, + "metadata": metadata, + "status": "OK", + } + _LOGGER.debug( + f"Received response for {client_call_details.method}.", + extra={ + "serviceName": "google.devicesandservices.health.v4.HealthProfileService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class HealthProfileServiceGrpcTransport(HealthProfileServiceTransport): + """gRPC backend transport for HealthProfileService. + + Health Profile Service + + 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 = "health.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'health.googleapis.com'). + 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 a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + 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 a ``channel`` instance 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 a ``channel`` instance 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. + api_audience (Optional[str]): The intended audience for the API calls + to the service that will be set when using certain 3rd party + authentication flows. Audience is typically a resource identifier. + If not set, the host value will be used as a default. + + 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 isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + self._interceptor = _LoggingClientInterceptor() + self._logged_channel = grpc.intercept_channel( + self._grpc_channel, self._interceptor + ) + + # Wrap messages. This must be done after self._logged_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "health.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + 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 get_profile( + self, + ) -> Callable[[health_profile.GetProfileRequest], health_profile.Profile]: + r"""Return a callable for the get profile method over gRPC. + + Returns user Profile details. + + Returns: + Callable[[~.GetProfileRequest], + ~.Profile]: + 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_profile" not in self._stubs: + self._stubs["get_profile"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.HealthProfileService/GetProfile", + request_serializer=health_profile.GetProfileRequest.serialize, + response_deserializer=health_profile.Profile.deserialize, + ) + return self._stubs["get_profile"] + + @property + def update_profile( + self, + ) -> Callable[[health_profile.UpdateProfileRequest], health_profile.Profile]: + r"""Return a callable for the update profile method over gRPC. + + Updates the user's profile details. + + Returns: + Callable[[~.UpdateProfileRequest], + ~.Profile]: + 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_profile" not in self._stubs: + self._stubs["update_profile"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.HealthProfileService/UpdateProfile", + request_serializer=health_profile.UpdateProfileRequest.serialize, + response_deserializer=health_profile.Profile.deserialize, + ) + return self._stubs["update_profile"] + + @property + def get_settings( + self, + ) -> Callable[[health_profile.GetSettingsRequest], health_profile.Settings]: + r"""Return a callable for the get settings method over gRPC. + + Returns user settings details. + + Returns: + Callable[[~.GetSettingsRequest], + ~.Settings]: + 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_settings" not in self._stubs: + self._stubs["get_settings"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.HealthProfileService/GetSettings", + request_serializer=health_profile.GetSettingsRequest.serialize, + response_deserializer=health_profile.Settings.deserialize, + ) + return self._stubs["get_settings"] + + @property + def update_settings( + self, + ) -> Callable[[health_profile.UpdateSettingsRequest], health_profile.Settings]: + r"""Return a callable for the update settings method over gRPC. + + Updates the user's settings details. + + Returns: + Callable[[~.UpdateSettingsRequest], + ~.Settings]: + 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_settings" not in self._stubs: + self._stubs["update_settings"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.HealthProfileService/UpdateSettings", + request_serializer=health_profile.UpdateSettingsRequest.serialize, + response_deserializer=health_profile.Settings.deserialize, + ) + return self._stubs["update_settings"] + + @property + def get_identity( + self, + ) -> Callable[[health_profile.GetIdentityRequest], health_profile.Identity]: + r"""Return a callable for the get identity method over gRPC. + + Gets the user's identity. + + It includes the legacy Fitbit user ID and the Google + user ID and it can be used by migrating clients to map + identifiers between the two systems. + + Returns: + Callable[[~.GetIdentityRequest], + ~.Identity]: + 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_identity" not in self._stubs: + self._stubs["get_identity"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.HealthProfileService/GetIdentity", + request_serializer=health_profile.GetIdentityRequest.serialize, + response_deserializer=health_profile.Identity.deserialize, + ) + return self._stubs["get_identity"] + + @property + def get_irn_profile( + self, + ) -> Callable[[health_profile.GetIrnProfileRequest], health_profile.IrnProfile]: + r"""Return a callable for the get irn profile method over gRPC. + + Returns user's IRN Profile details. + + Returns: + Callable[[~.GetIrnProfileRequest], + ~.IrnProfile]: + 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_irn_profile" not in self._stubs: + self._stubs["get_irn_profile"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.HealthProfileService/GetIrnProfile", + request_serializer=health_profile.GetIrnProfileRequest.serialize, + response_deserializer=health_profile.IrnProfile.deserialize, + ) + return self._stubs["get_irn_profile"] + + @property + def get_paired_device( + self, + ) -> Callable[[health_profile.GetPairedDeviceRequest], health_profile.PairedDevice]: + r"""Return a callable for the get paired device method over gRPC. + + Returns user's Device. + + Returns: + Callable[[~.GetPairedDeviceRequest], + ~.PairedDevice]: + 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_paired_device" not in self._stubs: + self._stubs["get_paired_device"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.HealthProfileService/GetPairedDevice", + request_serializer=health_profile.GetPairedDeviceRequest.serialize, + response_deserializer=health_profile.PairedDevice.deserialize, + ) + return self._stubs["get_paired_device"] + + @property + def list_paired_devices( + self, + ) -> Callable[ + [health_profile.ListPairedDevicesRequest], + health_profile.ListPairedDevicesResponse, + ]: + r"""Return a callable for the list paired devices method over gRPC. + + Returns the user's list of paired 1P trackers and + smartwatches. + + Returns: + Callable[[~.ListPairedDevicesRequest], + ~.ListPairedDevicesResponse]: + 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_paired_devices" not in self._stubs: + self._stubs["list_paired_devices"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.HealthProfileService/ListPairedDevices", + request_serializer=health_profile.ListPairedDevicesRequest.serialize, + response_deserializer=health_profile.ListPairedDevicesResponse.deserialize, + ) + return self._stubs["list_paired_devices"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("HealthProfileServiceGrpcTransport",) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/transports/grpc_asyncio.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/transports/grpc_asyncio.py new file mode 100644 index 000000000000..6d17f9d6eeaf --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/transports/grpc_asyncio.py @@ -0,0 +1,678 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 inspect +import json +import logging as std_logging +import pickle +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +import google.protobuf.message +import grpc # type: ignore +import proto # type: ignore +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, grpc_helpers_async +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +from grpc.experimental import aio # type: ignore + +from google.devicesandservices.health_v4.types import health_profile + +from .base import DEFAULT_CLIENT_INFO, HealthProfileServiceTransport +from .grpc import HealthProfileServiceGrpcTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientAIOInterceptor( + grpc.aio.UnaryUnaryClientInterceptor +): # pragma: NO COVER + async def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = f"{type(request).__name__}: {pickle.dumps(request)!r}" + + request_metadata = { + key: value.decode("utf-8") if isinstance(value, bytes) else value + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.devicesandservices.health.v4.HealthProfileService", + "rpcName": str(client_call_details.method), + "request": grpc_request, + "metadata": grpc_request["metadata"], + }, + ) + response = await continuation(client_call_details, request) + if logging_enabled: # pragma: NO COVER + response_metadata = await response.trailing_metadata() + # Convert gRPC metadata `` to list of tuples + metadata = ( + dict([(k, str(v)) for k, v in response_metadata]) + if response_metadata + else None + ) + result = await response + if isinstance(result, proto.Message): + response_payload = type(result).to_json(result) + elif isinstance(result, google.protobuf.message.Message): + response_payload = MessageToJson(result) + else: + response_payload = f"{type(result).__name__}: {pickle.dumps(result)!r}" + grpc_response = { + "payload": response_payload, + "metadata": metadata, + "status": "OK", + } + _LOGGER.debug( + f"Received response to rpc {client_call_details.method}.", + extra={ + "serviceName": "google.devicesandservices.health.v4.HealthProfileService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class HealthProfileServiceGrpcAsyncIOTransport(HealthProfileServiceTransport): + """gRPC AsyncIO backend transport for HealthProfileService. + + Health Profile Service + + 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 = "health.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + 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 = "health.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[Union[aio.Channel, Callable[..., aio.Channel]]] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'health.googleapis.com'). + 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 a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + 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[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + 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 a ``channel`` instance 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 a ``channel`` instance 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. + api_audience (Optional[str]): The intended audience for the API calls + to the service that will be set when using certain 3rd party + authentication flows. Audience is typically a resource identifier. + If not set, the host value will be used as a default. + + 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 isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + self._interceptor = _LoggingClientAIOInterceptor() + self._grpc_channel._unary_unary_interceptors.append(self._interceptor) + self._logged_channel = self._grpc_channel + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) + # Wrap messages. This must be done after self._logged_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 get_profile( + self, + ) -> Callable[ + [health_profile.GetProfileRequest], Awaitable[health_profile.Profile] + ]: + r"""Return a callable for the get profile method over gRPC. + + Returns user Profile details. + + Returns: + Callable[[~.GetProfileRequest], + Awaitable[~.Profile]]: + 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_profile" not in self._stubs: + self._stubs["get_profile"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.HealthProfileService/GetProfile", + request_serializer=health_profile.GetProfileRequest.serialize, + response_deserializer=health_profile.Profile.deserialize, + ) + return self._stubs["get_profile"] + + @property + def update_profile( + self, + ) -> Callable[ + [health_profile.UpdateProfileRequest], Awaitable[health_profile.Profile] + ]: + r"""Return a callable for the update profile method over gRPC. + + Updates the user's profile details. + + Returns: + Callable[[~.UpdateProfileRequest], + Awaitable[~.Profile]]: + 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_profile" not in self._stubs: + self._stubs["update_profile"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.HealthProfileService/UpdateProfile", + request_serializer=health_profile.UpdateProfileRequest.serialize, + response_deserializer=health_profile.Profile.deserialize, + ) + return self._stubs["update_profile"] + + @property + def get_settings( + self, + ) -> Callable[ + [health_profile.GetSettingsRequest], Awaitable[health_profile.Settings] + ]: + r"""Return a callable for the get settings method over gRPC. + + Returns user settings details. + + Returns: + Callable[[~.GetSettingsRequest], + Awaitable[~.Settings]]: + 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_settings" not in self._stubs: + self._stubs["get_settings"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.HealthProfileService/GetSettings", + request_serializer=health_profile.GetSettingsRequest.serialize, + response_deserializer=health_profile.Settings.deserialize, + ) + return self._stubs["get_settings"] + + @property + def update_settings( + self, + ) -> Callable[ + [health_profile.UpdateSettingsRequest], Awaitable[health_profile.Settings] + ]: + r"""Return a callable for the update settings method over gRPC. + + Updates the user's settings details. + + Returns: + Callable[[~.UpdateSettingsRequest], + Awaitable[~.Settings]]: + 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_settings" not in self._stubs: + self._stubs["update_settings"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.HealthProfileService/UpdateSettings", + request_serializer=health_profile.UpdateSettingsRequest.serialize, + response_deserializer=health_profile.Settings.deserialize, + ) + return self._stubs["update_settings"] + + @property + def get_identity( + self, + ) -> Callable[ + [health_profile.GetIdentityRequest], Awaitable[health_profile.Identity] + ]: + r"""Return a callable for the get identity method over gRPC. + + Gets the user's identity. + + It includes the legacy Fitbit user ID and the Google + user ID and it can be used by migrating clients to map + identifiers between the two systems. + + Returns: + Callable[[~.GetIdentityRequest], + Awaitable[~.Identity]]: + 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_identity" not in self._stubs: + self._stubs["get_identity"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.HealthProfileService/GetIdentity", + request_serializer=health_profile.GetIdentityRequest.serialize, + response_deserializer=health_profile.Identity.deserialize, + ) + return self._stubs["get_identity"] + + @property + def get_irn_profile( + self, + ) -> Callable[ + [health_profile.GetIrnProfileRequest], Awaitable[health_profile.IrnProfile] + ]: + r"""Return a callable for the get irn profile method over gRPC. + + Returns user's IRN Profile details. + + Returns: + Callable[[~.GetIrnProfileRequest], + Awaitable[~.IrnProfile]]: + 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_irn_profile" not in self._stubs: + self._stubs["get_irn_profile"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.HealthProfileService/GetIrnProfile", + request_serializer=health_profile.GetIrnProfileRequest.serialize, + response_deserializer=health_profile.IrnProfile.deserialize, + ) + return self._stubs["get_irn_profile"] + + @property + def get_paired_device( + self, + ) -> Callable[ + [health_profile.GetPairedDeviceRequest], Awaitable[health_profile.PairedDevice] + ]: + r"""Return a callable for the get paired device method over gRPC. + + Returns user's Device. + + Returns: + Callable[[~.GetPairedDeviceRequest], + Awaitable[~.PairedDevice]]: + 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_paired_device" not in self._stubs: + self._stubs["get_paired_device"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.HealthProfileService/GetPairedDevice", + request_serializer=health_profile.GetPairedDeviceRequest.serialize, + response_deserializer=health_profile.PairedDevice.deserialize, + ) + return self._stubs["get_paired_device"] + + @property + def list_paired_devices( + self, + ) -> Callable[ + [health_profile.ListPairedDevicesRequest], + Awaitable[health_profile.ListPairedDevicesResponse], + ]: + r"""Return a callable for the list paired devices method over gRPC. + + Returns the user's list of paired 1P trackers and + smartwatches. + + Returns: + Callable[[~.ListPairedDevicesRequest], + Awaitable[~.ListPairedDevicesResponse]]: + 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_paired_devices" not in self._stubs: + self._stubs["list_paired_devices"] = self._logged_channel.unary_unary( + "/google.devicesandservices.health.v4.HealthProfileService/ListPairedDevices", + request_serializer=health_profile.ListPairedDevicesRequest.serialize, + response_deserializer=health_profile.ListPairedDevicesResponse.deserialize, + ) + return self._stubs["list_paired_devices"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.get_profile: self._wrap_method( + self.get_profile, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.update_profile: self._wrap_method( + self.update_profile, + default_timeout=60.0, + client_info=client_info, + ), + self.get_settings: self._wrap_method( + self.get_settings, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.update_settings: self._wrap_method( + self.update_settings, + default_timeout=60.0, + client_info=client_info, + ), + self.get_identity: self._wrap_method( + self.get_identity, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.get_irn_profile: self._wrap_method( + self.get_irn_profile, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.get_paired_device: self._wrap_method( + self.get_paired_device, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.list_paired_devices: self._wrap_method( + self.list_paired_devices, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("HealthProfileServiceGrpcAsyncIOTransport",) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/transports/rest.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/transports/rest.py new file mode 100644 index 000000000000..1a6ddf36c977 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/transports/rest.py @@ -0,0 +1,1891 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +import warnings +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +import google.protobuf +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.devicesandservices.health_v4.types import health_profile + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseHealthProfileServiceRestTransport + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class HealthProfileServiceRestInterceptor: + """Interceptor for HealthProfileService. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the HealthProfileServiceRestTransport. + + .. code-block:: python + class MyCustomHealthProfileServiceInterceptor(HealthProfileServiceRestInterceptor): + def pre_get_identity(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_identity(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_irn_profile(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_irn_profile(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_paired_device(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_paired_device(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_profile(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_profile(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_settings(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_settings(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_paired_devices(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_paired_devices(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_profile(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_profile(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_settings(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_settings(self, response): + logging.log(f"Received response: {response}") + return response + + transport = HealthProfileServiceRestTransport(interceptor=MyCustomHealthProfileServiceInterceptor()) + client = HealthProfileServiceClient(transport=transport) + + + """ + + def pre_get_identity( + self, + request: health_profile.GetIdentityRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + health_profile.GetIdentityRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_identity + + Override in a subclass to manipulate the request or metadata + before they are sent to the HealthProfileService server. + """ + return request, metadata + + def post_get_identity( + self, response: health_profile.Identity + ) -> health_profile.Identity: + """Post-rpc interceptor for get_identity + + DEPRECATED. Please use the `post_get_identity_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the HealthProfileService server but before + it is returned to user code. This `post_get_identity` interceptor runs + before the `post_get_identity_with_metadata` interceptor. + """ + return response + + def post_get_identity_with_metadata( + self, + response: health_profile.Identity, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[health_profile.Identity, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_identity + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the HealthProfileService server but before it is returned to user code. + + We recommend only using this `post_get_identity_with_metadata` + interceptor in new development instead of the `post_get_identity` interceptor. + When both interceptors are used, this `post_get_identity_with_metadata` interceptor runs after the + `post_get_identity` interceptor. The (possibly modified) response returned by + `post_get_identity` will be passed to + `post_get_identity_with_metadata`. + """ + return response, metadata + + def pre_get_irn_profile( + self, + request: health_profile.GetIrnProfileRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + health_profile.GetIrnProfileRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_irn_profile + + Override in a subclass to manipulate the request or metadata + before they are sent to the HealthProfileService server. + """ + return request, metadata + + def post_get_irn_profile( + self, response: health_profile.IrnProfile + ) -> health_profile.IrnProfile: + """Post-rpc interceptor for get_irn_profile + + DEPRECATED. Please use the `post_get_irn_profile_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the HealthProfileService server but before + it is returned to user code. This `post_get_irn_profile` interceptor runs + before the `post_get_irn_profile_with_metadata` interceptor. + """ + return response + + def post_get_irn_profile_with_metadata( + self, + response: health_profile.IrnProfile, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[health_profile.IrnProfile, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_irn_profile + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the HealthProfileService server but before it is returned to user code. + + We recommend only using this `post_get_irn_profile_with_metadata` + interceptor in new development instead of the `post_get_irn_profile` interceptor. + When both interceptors are used, this `post_get_irn_profile_with_metadata` interceptor runs after the + `post_get_irn_profile` interceptor. The (possibly modified) response returned by + `post_get_irn_profile` will be passed to + `post_get_irn_profile_with_metadata`. + """ + return response, metadata + + def pre_get_paired_device( + self, + request: health_profile.GetPairedDeviceRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + health_profile.GetPairedDeviceRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_paired_device + + Override in a subclass to manipulate the request or metadata + before they are sent to the HealthProfileService server. + """ + return request, metadata + + def post_get_paired_device( + self, response: health_profile.PairedDevice + ) -> health_profile.PairedDevice: + """Post-rpc interceptor for get_paired_device + + DEPRECATED. Please use the `post_get_paired_device_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the HealthProfileService server but before + it is returned to user code. This `post_get_paired_device` interceptor runs + before the `post_get_paired_device_with_metadata` interceptor. + """ + return response + + def post_get_paired_device_with_metadata( + self, + response: health_profile.PairedDevice, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[health_profile.PairedDevice, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_paired_device + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the HealthProfileService server but before it is returned to user code. + + We recommend only using this `post_get_paired_device_with_metadata` + interceptor in new development instead of the `post_get_paired_device` interceptor. + When both interceptors are used, this `post_get_paired_device_with_metadata` interceptor runs after the + `post_get_paired_device` interceptor. The (possibly modified) response returned by + `post_get_paired_device` will be passed to + `post_get_paired_device_with_metadata`. + """ + return response, metadata + + def pre_get_profile( + self, + request: health_profile.GetProfileRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + health_profile.GetProfileRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_profile + + Override in a subclass to manipulate the request or metadata + before they are sent to the HealthProfileService server. + """ + return request, metadata + + def post_get_profile( + self, response: health_profile.Profile + ) -> health_profile.Profile: + """Post-rpc interceptor for get_profile + + DEPRECATED. Please use the `post_get_profile_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the HealthProfileService server but before + it is returned to user code. This `post_get_profile` interceptor runs + before the `post_get_profile_with_metadata` interceptor. + """ + return response + + def post_get_profile_with_metadata( + self, + response: health_profile.Profile, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[health_profile.Profile, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_profile + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the HealthProfileService server but before it is returned to user code. + + We recommend only using this `post_get_profile_with_metadata` + interceptor in new development instead of the `post_get_profile` interceptor. + When both interceptors are used, this `post_get_profile_with_metadata` interceptor runs after the + `post_get_profile` interceptor. The (possibly modified) response returned by + `post_get_profile` will be passed to + `post_get_profile_with_metadata`. + """ + return response, metadata + + def pre_get_settings( + self, + request: health_profile.GetSettingsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + health_profile.GetSettingsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_settings + + Override in a subclass to manipulate the request or metadata + before they are sent to the HealthProfileService server. + """ + return request, metadata + + def post_get_settings( + self, response: health_profile.Settings + ) -> health_profile.Settings: + """Post-rpc interceptor for get_settings + + DEPRECATED. Please use the `post_get_settings_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the HealthProfileService server but before + it is returned to user code. This `post_get_settings` interceptor runs + before the `post_get_settings_with_metadata` interceptor. + """ + return response + + def post_get_settings_with_metadata( + self, + response: health_profile.Settings, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[health_profile.Settings, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_settings + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the HealthProfileService server but before it is returned to user code. + + We recommend only using this `post_get_settings_with_metadata` + interceptor in new development instead of the `post_get_settings` interceptor. + When both interceptors are used, this `post_get_settings_with_metadata` interceptor runs after the + `post_get_settings` interceptor. The (possibly modified) response returned by + `post_get_settings` will be passed to + `post_get_settings_with_metadata`. + """ + return response, metadata + + def pre_list_paired_devices( + self, + request: health_profile.ListPairedDevicesRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + health_profile.ListPairedDevicesRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for list_paired_devices + + Override in a subclass to manipulate the request or metadata + before they are sent to the HealthProfileService server. + """ + return request, metadata + + def post_list_paired_devices( + self, response: health_profile.ListPairedDevicesResponse + ) -> health_profile.ListPairedDevicesResponse: + """Post-rpc interceptor for list_paired_devices + + DEPRECATED. Please use the `post_list_paired_devices_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the HealthProfileService server but before + it is returned to user code. This `post_list_paired_devices` interceptor runs + before the `post_list_paired_devices_with_metadata` interceptor. + """ + return response + + def post_list_paired_devices_with_metadata( + self, + response: health_profile.ListPairedDevicesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + health_profile.ListPairedDevicesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_paired_devices + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the HealthProfileService server but before it is returned to user code. + + We recommend only using this `post_list_paired_devices_with_metadata` + interceptor in new development instead of the `post_list_paired_devices` interceptor. + When both interceptors are used, this `post_list_paired_devices_with_metadata` interceptor runs after the + `post_list_paired_devices` interceptor. The (possibly modified) response returned by + `post_list_paired_devices` will be passed to + `post_list_paired_devices_with_metadata`. + """ + return response, metadata + + def pre_update_profile( + self, + request: health_profile.UpdateProfileRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + health_profile.UpdateProfileRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for update_profile + + Override in a subclass to manipulate the request or metadata + before they are sent to the HealthProfileService server. + """ + return request, metadata + + def post_update_profile( + self, response: health_profile.Profile + ) -> health_profile.Profile: + """Post-rpc interceptor for update_profile + + DEPRECATED. Please use the `post_update_profile_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the HealthProfileService server but before + it is returned to user code. This `post_update_profile` interceptor runs + before the `post_update_profile_with_metadata` interceptor. + """ + return response + + def post_update_profile_with_metadata( + self, + response: health_profile.Profile, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[health_profile.Profile, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_profile + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the HealthProfileService server but before it is returned to user code. + + We recommend only using this `post_update_profile_with_metadata` + interceptor in new development instead of the `post_update_profile` interceptor. + When both interceptors are used, this `post_update_profile_with_metadata` interceptor runs after the + `post_update_profile` interceptor. The (possibly modified) response returned by + `post_update_profile` will be passed to + `post_update_profile_with_metadata`. + """ + return response, metadata + + def pre_update_settings( + self, + request: health_profile.UpdateSettingsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + health_profile.UpdateSettingsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for update_settings + + Override in a subclass to manipulate the request or metadata + before they are sent to the HealthProfileService server. + """ + return request, metadata + + def post_update_settings( + self, response: health_profile.Settings + ) -> health_profile.Settings: + """Post-rpc interceptor for update_settings + + DEPRECATED. Please use the `post_update_settings_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the HealthProfileService server but before + it is returned to user code. This `post_update_settings` interceptor runs + before the `post_update_settings_with_metadata` interceptor. + """ + return response + + def post_update_settings_with_metadata( + self, + response: health_profile.Settings, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[health_profile.Settings, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_settings + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the HealthProfileService server but before it is returned to user code. + + We recommend only using this `post_update_settings_with_metadata` + interceptor in new development instead of the `post_update_settings` interceptor. + When both interceptors are used, this `post_update_settings_with_metadata` interceptor runs after the + `post_update_settings` interceptor. The (possibly modified) response returned by + `post_update_settings` will be passed to + `post_update_settings_with_metadata`. + """ + return response, metadata + + +@dataclasses.dataclass +class HealthProfileServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: HealthProfileServiceRestInterceptor + + +class HealthProfileServiceRestTransport(_BaseHealthProfileServiceRestTransport): + """REST backend synchronous transport for HealthProfileService. + + Health Profile Service + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "health.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[HealthProfileServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'health.googleapis.com'). + 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]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. This argument will be + removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + interceptor (Optional[HealthProfileServiceRestInterceptor]): Interceptor used + to manipulate requests, request metadata, and responses. + api_audience (Optional[str]): The intended audience for the API calls + to the service that will be set when using certain 3rd party + authentication flows. Audience is typically a resource identifier. + If not set, the host value will be used as a default. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or HealthProfileServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _GetIdentity( + _BaseHealthProfileServiceRestTransport._BaseGetIdentity, + HealthProfileServiceRestStub, + ): + def __hash__(self): + return hash("HealthProfileServiceRestTransport.GetIdentity") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: health_profile.GetIdentityRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> health_profile.Identity: + r"""Call the get identity method over HTTP. + + Args: + request (~.health_profile.GetIdentityRequest): + The request object. Request message for getting Identity + details. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.health_profile.Identity: + Represents details about the Google + user's identity. + + """ + + http_options = _BaseHealthProfileServiceRestTransport._BaseGetIdentity._get_http_options() + + request, metadata = self._interceptor.pre_get_identity(request, metadata) + transcoded_request = _BaseHealthProfileServiceRestTransport._BaseGetIdentity._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseHealthProfileServiceRestTransport._BaseGetIdentity._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.devicesandservices.health_v4.HealthProfileServiceClient.GetIdentity", + extra={ + "serviceName": "google.devicesandservices.health.v4.HealthProfileService", + "rpcName": "GetIdentity", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = HealthProfileServiceRestTransport._GetIdentity._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = health_profile.Identity() + pb_resp = health_profile.Identity.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_identity(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_identity_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = health_profile.Identity.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.devicesandservices.health_v4.HealthProfileServiceClient.get_identity", + extra={ + "serviceName": "google.devicesandservices.health.v4.HealthProfileService", + "rpcName": "GetIdentity", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _GetIrnProfile( + _BaseHealthProfileServiceRestTransport._BaseGetIrnProfile, + HealthProfileServiceRestStub, + ): + def __hash__(self): + return hash("HealthProfileServiceRestTransport.GetIrnProfile") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: health_profile.GetIrnProfileRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> health_profile.IrnProfile: + r"""Call the get irn profile method over HTTP. + + Args: + request (~.health_profile.GetIrnProfileRequest): + The request object. Request message for getting IRN + Profile details. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.health_profile.IrnProfile: + Irregular Rhythm Notifications (IRN) + Profile details. + The Irregular Rhythm Notifications (IRN) + feature checks for signs of atrial + fibrillation (AFib). The IrnProfile + details include information about the + user's onboarding status, enrollment + status, and the last update time of + analyzable data for this feature. + + """ + + http_options = _BaseHealthProfileServiceRestTransport._BaseGetIrnProfile._get_http_options() + + request, metadata = self._interceptor.pre_get_irn_profile(request, metadata) + transcoded_request = _BaseHealthProfileServiceRestTransport._BaseGetIrnProfile._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseHealthProfileServiceRestTransport._BaseGetIrnProfile._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.devicesandservices.health_v4.HealthProfileServiceClient.GetIrnProfile", + extra={ + "serviceName": "google.devicesandservices.health.v4.HealthProfileService", + "rpcName": "GetIrnProfile", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = HealthProfileServiceRestTransport._GetIrnProfile._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = health_profile.IrnProfile() + pb_resp = health_profile.IrnProfile.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_irn_profile(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_irn_profile_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = health_profile.IrnProfile.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.devicesandservices.health_v4.HealthProfileServiceClient.get_irn_profile", + extra={ + "serviceName": "google.devicesandservices.health.v4.HealthProfileService", + "rpcName": "GetIrnProfile", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _GetPairedDevice( + _BaseHealthProfileServiceRestTransport._BaseGetPairedDevice, + HealthProfileServiceRestStub, + ): + def __hash__(self): + return hash("HealthProfileServiceRestTransport.GetPairedDevice") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: health_profile.GetPairedDeviceRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> health_profile.PairedDevice: + r"""Call the get paired device method over HTTP. + + Args: + request (~.health_profile.GetPairedDeviceRequest): + The request object. Request message for getting a Device. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.health_profile.PairedDevice: + User's Paired 1P Device + + The PairedDevice details include + information about the device type, + battery status, battery level, last sync + time, device version, mac address, and + features. + + """ + + http_options = _BaseHealthProfileServiceRestTransport._BaseGetPairedDevice._get_http_options() + + request, metadata = self._interceptor.pre_get_paired_device( + request, metadata + ) + transcoded_request = _BaseHealthProfileServiceRestTransport._BaseGetPairedDevice._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseHealthProfileServiceRestTransport._BaseGetPairedDevice._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.devicesandservices.health_v4.HealthProfileServiceClient.GetPairedDevice", + extra={ + "serviceName": "google.devicesandservices.health.v4.HealthProfileService", + "rpcName": "GetPairedDevice", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = HealthProfileServiceRestTransport._GetPairedDevice._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = health_profile.PairedDevice() + pb_resp = health_profile.PairedDevice.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_paired_device(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_paired_device_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = health_profile.PairedDevice.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.devicesandservices.health_v4.HealthProfileServiceClient.get_paired_device", + extra={ + "serviceName": "google.devicesandservices.health.v4.HealthProfileService", + "rpcName": "GetPairedDevice", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _GetProfile( + _BaseHealthProfileServiceRestTransport._BaseGetProfile, + HealthProfileServiceRestStub, + ): + def __hash__(self): + return hash("HealthProfileServiceRestTransport.GetProfile") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: health_profile.GetProfileRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> health_profile.Profile: + r"""Call the get profile method over HTTP. + + Args: + request (~.health_profile.GetProfileRequest): + The request object. Request message for getting Profile + details. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.health_profile.Profile: + Profile details. + """ + + http_options = _BaseHealthProfileServiceRestTransport._BaseGetProfile._get_http_options() + + request, metadata = self._interceptor.pre_get_profile(request, metadata) + transcoded_request = _BaseHealthProfileServiceRestTransport._BaseGetProfile._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseHealthProfileServiceRestTransport._BaseGetProfile._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.devicesandservices.health_v4.HealthProfileServiceClient.GetProfile", + extra={ + "serviceName": "google.devicesandservices.health.v4.HealthProfileService", + "rpcName": "GetProfile", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = HealthProfileServiceRestTransport._GetProfile._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = health_profile.Profile() + pb_resp = health_profile.Profile.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_profile(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_profile_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = health_profile.Profile.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.devicesandservices.health_v4.HealthProfileServiceClient.get_profile", + extra={ + "serviceName": "google.devicesandservices.health.v4.HealthProfileService", + "rpcName": "GetProfile", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _GetSettings( + _BaseHealthProfileServiceRestTransport._BaseGetSettings, + HealthProfileServiceRestStub, + ): + def __hash__(self): + return hash("HealthProfileServiceRestTransport.GetSettings") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: health_profile.GetSettingsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> health_profile.Settings: + r"""Call the get settings method over HTTP. + + Args: + request (~.health_profile.GetSettingsRequest): + The request object. Request message for getting Settings + details. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.health_profile.Settings: + Settings details. + """ + + http_options = _BaseHealthProfileServiceRestTransport._BaseGetSettings._get_http_options() + + request, metadata = self._interceptor.pre_get_settings(request, metadata) + transcoded_request = _BaseHealthProfileServiceRestTransport._BaseGetSettings._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseHealthProfileServiceRestTransport._BaseGetSettings._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.devicesandservices.health_v4.HealthProfileServiceClient.GetSettings", + extra={ + "serviceName": "google.devicesandservices.health.v4.HealthProfileService", + "rpcName": "GetSettings", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = HealthProfileServiceRestTransport._GetSettings._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = health_profile.Settings() + pb_resp = health_profile.Settings.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_settings(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_settings_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = health_profile.Settings.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.devicesandservices.health_v4.HealthProfileServiceClient.get_settings", + extra={ + "serviceName": "google.devicesandservices.health.v4.HealthProfileService", + "rpcName": "GetSettings", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _ListPairedDevices( + _BaseHealthProfileServiceRestTransport._BaseListPairedDevices, + HealthProfileServiceRestStub, + ): + def __hash__(self): + return hash("HealthProfileServiceRestTransport.ListPairedDevices") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: health_profile.ListPairedDevicesRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> health_profile.ListPairedDevicesResponse: + r"""Call the list paired devices method over HTTP. + + Args: + request (~.health_profile.ListPairedDevicesRequest): + The request object. Request message for listing Devices. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.health_profile.ListPairedDevicesResponse: + Response message for + ListPairedDevices. + + """ + + http_options = _BaseHealthProfileServiceRestTransport._BaseListPairedDevices._get_http_options() + + request, metadata = self._interceptor.pre_list_paired_devices( + request, metadata + ) + transcoded_request = _BaseHealthProfileServiceRestTransport._BaseListPairedDevices._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseHealthProfileServiceRestTransport._BaseListPairedDevices._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.devicesandservices.health_v4.HealthProfileServiceClient.ListPairedDevices", + extra={ + "serviceName": "google.devicesandservices.health.v4.HealthProfileService", + "rpcName": "ListPairedDevices", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + HealthProfileServiceRestTransport._ListPairedDevices._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = health_profile.ListPairedDevicesResponse() + pb_resp = health_profile.ListPairedDevicesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_list_paired_devices(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_paired_devices_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = health_profile.ListPairedDevicesResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.devicesandservices.health_v4.HealthProfileServiceClient.list_paired_devices", + extra={ + "serviceName": "google.devicesandservices.health.v4.HealthProfileService", + "rpcName": "ListPairedDevices", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _UpdateProfile( + _BaseHealthProfileServiceRestTransport._BaseUpdateProfile, + HealthProfileServiceRestStub, + ): + def __hash__(self): + return hash("HealthProfileServiceRestTransport.UpdateProfile") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: health_profile.UpdateProfileRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> health_profile.Profile: + r"""Call the update profile method over HTTP. + + Args: + request (~.health_profile.UpdateProfileRequest): + The request object. Request message for updating Profile + details. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.health_profile.Profile: + Profile details. + """ + + http_options = _BaseHealthProfileServiceRestTransport._BaseUpdateProfile._get_http_options() + + request, metadata = self._interceptor.pre_update_profile(request, metadata) + transcoded_request = _BaseHealthProfileServiceRestTransport._BaseUpdateProfile._get_transcoded_request( + http_options, request + ) + + body = _BaseHealthProfileServiceRestTransport._BaseUpdateProfile._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseHealthProfileServiceRestTransport._BaseUpdateProfile._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.devicesandservices.health_v4.HealthProfileServiceClient.UpdateProfile", + extra={ + "serviceName": "google.devicesandservices.health.v4.HealthProfileService", + "rpcName": "UpdateProfile", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = HealthProfileServiceRestTransport._UpdateProfile._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = health_profile.Profile() + pb_resp = health_profile.Profile.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_update_profile(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_profile_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = health_profile.Profile.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.devicesandservices.health_v4.HealthProfileServiceClient.update_profile", + extra={ + "serviceName": "google.devicesandservices.health.v4.HealthProfileService", + "rpcName": "UpdateProfile", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _UpdateSettings( + _BaseHealthProfileServiceRestTransport._BaseUpdateSettings, + HealthProfileServiceRestStub, + ): + def __hash__(self): + return hash("HealthProfileServiceRestTransport.UpdateSettings") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: health_profile.UpdateSettingsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> health_profile.Settings: + r"""Call the update settings method over HTTP. + + Args: + request (~.health_profile.UpdateSettingsRequest): + The request object. Request message for updating Settings + details. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.health_profile.Settings: + Settings details. + """ + + http_options = _BaseHealthProfileServiceRestTransport._BaseUpdateSettings._get_http_options() + + request, metadata = self._interceptor.pre_update_settings(request, metadata) + transcoded_request = _BaseHealthProfileServiceRestTransport._BaseUpdateSettings._get_transcoded_request( + http_options, request + ) + + body = _BaseHealthProfileServiceRestTransport._BaseUpdateSettings._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseHealthProfileServiceRestTransport._BaseUpdateSettings._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.devicesandservices.health_v4.HealthProfileServiceClient.UpdateSettings", + extra={ + "serviceName": "google.devicesandservices.health.v4.HealthProfileService", + "rpcName": "UpdateSettings", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = HealthProfileServiceRestTransport._UpdateSettings._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = health_profile.Settings() + pb_resp = health_profile.Settings.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_update_settings(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_settings_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = health_profile.Settings.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.devicesandservices.health_v4.HealthProfileServiceClient.update_settings", + extra={ + "serviceName": "google.devicesandservices.health.v4.HealthProfileService", + "rpcName": "UpdateSettings", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def get_identity( + self, + ) -> Callable[[health_profile.GetIdentityRequest], health_profile.Identity]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetIdentity(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_irn_profile( + self, + ) -> Callable[[health_profile.GetIrnProfileRequest], health_profile.IrnProfile]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetIrnProfile(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_paired_device( + self, + ) -> Callable[[health_profile.GetPairedDeviceRequest], health_profile.PairedDevice]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetPairedDevice(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_profile( + self, + ) -> Callable[[health_profile.GetProfileRequest], health_profile.Profile]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetProfile(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_settings( + self, + ) -> Callable[[health_profile.GetSettingsRequest], health_profile.Settings]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetSettings(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_paired_devices( + self, + ) -> Callable[ + [health_profile.ListPairedDevicesRequest], + health_profile.ListPairedDevicesResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListPairedDevices(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_profile( + self, + ) -> Callable[[health_profile.UpdateProfileRequest], health_profile.Profile]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateProfile(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_settings( + self, + ) -> Callable[[health_profile.UpdateSettingsRequest], health_profile.Settings]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateSettings(self._session, self._host, self._interceptor) # type: ignore + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("HealthProfileServiceRestTransport",) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/transports/rest_base.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/transports/rest_base.py new file mode 100644 index 000000000000..66d0290fe822 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/services/health_profile_service/transports/rest_base.py @@ -0,0 +1,487 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import json_format + +from google.devicesandservices.health_v4.types import health_profile + +from .base import DEFAULT_CLIENT_INFO, HealthProfileServiceTransport + + +class _BaseHealthProfileServiceRestTransport(HealthProfileServiceTransport): + """Base REST backend transport for HealthProfileService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "health.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'health.googleapis.com'). + credentials (Optional[Any]): 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. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetIdentity: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v4/{name=users/*/identity}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = health_profile.GetIdentityRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseHealthProfileServiceRestTransport._BaseGetIdentity._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetIrnProfile: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v4/{name=users/*/irnProfile}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = health_profile.GetIrnProfileRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseHealthProfileServiceRestTransport._BaseGetIrnProfile._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetPairedDevice: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v4/{name=users/*/pairedDevices/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = health_profile.GetPairedDeviceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseHealthProfileServiceRestTransport._BaseGetPairedDevice._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetProfile: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v4/{name=users/*/profile}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = health_profile.GetProfileRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseHealthProfileServiceRestTransport._BaseGetProfile._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetSettings: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v4/{name=users/*/settings}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = health_profile.GetSettingsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseHealthProfileServiceRestTransport._BaseGetSettings._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListPairedDevices: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v4/{parent=users/*}/pairedDevices", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = health_profile.ListPairedDevicesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseHealthProfileServiceRestTransport._BaseListPairedDevices._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateProfile: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v4/{profile.name=users/*/profile}", + "body": "profile", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = health_profile.UpdateProfileRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseHealthProfileServiceRestTransport._BaseUpdateProfile._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateSettings: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v4/{settings.name=users/*/settings}", + "body": "settings", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = health_profile.UpdateSettingsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseHealthProfileServiceRestTransport._BaseUpdateSettings._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseHealthProfileServiceRestTransport",) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/__init__.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/__init__.py new file mode 100644 index 000000000000..4f026d232692 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/__init__.py @@ -0,0 +1,310 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 .data_coordinates import ( + CivilDateTime, + CivilTimeInterval, + ObservationSampleTime, + ObservationTimeInterval, + SessionTimeInterval, +) +from .data_model import ( + ActiveEnergyBurned, + ActiveEnergyBurnedRollupValue, + ActiveMinutes, + ActiveMinutesRollupValue, + ActiveZoneMinutes, + ActiveZoneMinutesRollupValue, + ActivityLevel, + ActivityLevelRollupValue, + Altitude, + AltitudeRollupValue, + BasalEnergyBurned, + BloodGlucose, + BloodGlucoseRollupValue, + BodyFat, + BodyFatRollupValue, + CaloriesInHeartRateZoneRollupValue, + CoreBodyTemperature, + CoreBodyTemperatureRollupValue, + DailyHeartRateVariability, + DailyHeartRateZones, + DailyOxygenSaturation, + DailyRespiratoryRate, + DailyRestingHeartRate, + DailySleepTemperatureDerivations, + DailyVO2Max, + Distance, + DistanceRollupValue, + Electrocardiogram, + EnergyQuantity, + EnergyUnit, + Exercise, + Floors, + FloorsRollupValue, + Food, + FoodAccessLevel, + FoodMeasurementUnit, + HeartRate, + HeartRateRollupValue, + HeartRateVariability, + HeartRateVariabilityPersonalRangeRollupValue, + HeartRateZoneType, + Height, + HydrationLog, + HydrationLogRollupValue, + IrregularRhythmNotification, + MealType, + MetricsSummary, + Nutrient, + NutrientQuantity, + NutritionLog, + NutritionLogRollupValue, + OxygenSaturation, + RespiratoryRateSleepSummary, + RestingHeartRatePersonalRangeRollupValue, + RunVO2Max, + RunVO2MaxRollupValue, + SedentaryPeriod, + SedentaryPeriodRollupValue, + Sleep, + Steps, + StepsRollupValue, + SwimLengthsData, + SwimLengthsDataRollupValue, + TimeInHeartRateZone, + TimeInHeartRateZoneRollupValue, + TotalCaloriesRollupValue, + VO2Max, + VolumeQuantity, + VolumeUnit, + Weight, + WeightQuantity, + WeightRollupValue, + WeightUnit, +) +from .data_points import ( + BatchDeleteDataPointsOperationMetadata, + BatchDeleteDataPointsRequest, + BatchDeleteDataPointsResponse, + CreateDataPointOperationMetadata, + CreateDataPointRequest, + DailyRollupDataPoint, + DailyRollUpDataPointsRequest, + DailyRollUpDataPointsResponse, + DataPoint, + DataType, + ExportExerciseTcxRequest, + ExportExerciseTcxResponse, + GetDataPointRequest, + ListDataPointsRequest, + ListDataPointsResponse, + ReconcileDataPointsRequest, + ReconcileDataPointsResponse, + ReconciledDataPoint, + RollupDataPoint, + RollUpDataPointsRequest, + RollUpDataPointsResponse, + UpdateDataPointOperationMetadata, + UpdateDataPointRequest, +) +from .data_source import ( + DataSource, +) +from .data_subscription_service import ( + CreateSubscriberMetadata, + CreateSubscriberPayload, + CreateSubscriberRequest, + CreateSubscriptionPayload, + CreateSubscriptionRequest, + DeleteSubscriberMetadata, + DeleteSubscriberRequest, + DeleteSubscriptionRequest, + EndpointAuthorization, + ListSubscribersRequest, + ListSubscribersResponse, + ListSubscriptionsRequest, + ListSubscriptionsResponse, + Subscriber, + SubscriberConfig, + Subscription, + UpdateSubscriberMetadata, + UpdateSubscriberRequest, + UpdateSubscriptionRequest, +) +from .health_profile import ( + GetIdentityRequest, + GetIrnProfileRequest, + GetPairedDeviceRequest, + GetProfileRequest, + GetSettingsRequest, + Identity, + IrnProfile, + ListPairedDevicesRequest, + ListPairedDevicesResponse, + PairedDevice, + Profile, + Settings, + UpdateProfileRequest, + UpdateSettingsRequest, + User, +) +from .medical_device_info import ( + MedicalDeviceInfo, +) +from .webhook_notification_cloud_log import ( + WebhookNotificationCloudLog, +) + +__all__ = ( + "CivilDateTime", + "CivilTimeInterval", + "ObservationSampleTime", + "ObservationTimeInterval", + "SessionTimeInterval", + "ActiveEnergyBurned", + "ActiveEnergyBurnedRollupValue", + "ActiveMinutes", + "ActiveMinutesRollupValue", + "ActiveZoneMinutes", + "ActiveZoneMinutesRollupValue", + "ActivityLevel", + "ActivityLevelRollupValue", + "Altitude", + "AltitudeRollupValue", + "BasalEnergyBurned", + "BloodGlucose", + "BloodGlucoseRollupValue", + "BodyFat", + "BodyFatRollupValue", + "CaloriesInHeartRateZoneRollupValue", + "CoreBodyTemperature", + "CoreBodyTemperatureRollupValue", + "DailyHeartRateVariability", + "DailyHeartRateZones", + "DailyOxygenSaturation", + "DailyRespiratoryRate", + "DailyRestingHeartRate", + "DailySleepTemperatureDerivations", + "DailyVO2Max", + "Distance", + "DistanceRollupValue", + "Electrocardiogram", + "EnergyQuantity", + "Exercise", + "Floors", + "FloorsRollupValue", + "Food", + "FoodMeasurementUnit", + "HeartRate", + "HeartRateRollupValue", + "HeartRateVariability", + "HeartRateVariabilityPersonalRangeRollupValue", + "Height", + "HydrationLog", + "HydrationLogRollupValue", + "IrregularRhythmNotification", + "MetricsSummary", + "NutrientQuantity", + "NutritionLog", + "NutritionLogRollupValue", + "OxygenSaturation", + "RespiratoryRateSleepSummary", + "RestingHeartRatePersonalRangeRollupValue", + "RunVO2Max", + "RunVO2MaxRollupValue", + "SedentaryPeriod", + "SedentaryPeriodRollupValue", + "Sleep", + "Steps", + "StepsRollupValue", + "SwimLengthsData", + "SwimLengthsDataRollupValue", + "TimeInHeartRateZone", + "TimeInHeartRateZoneRollupValue", + "TotalCaloriesRollupValue", + "VO2Max", + "VolumeQuantity", + "Weight", + "WeightQuantity", + "WeightRollupValue", + "EnergyUnit", + "FoodAccessLevel", + "HeartRateZoneType", + "MealType", + "Nutrient", + "VolumeUnit", + "WeightUnit", + "BatchDeleteDataPointsOperationMetadata", + "BatchDeleteDataPointsRequest", + "BatchDeleteDataPointsResponse", + "CreateDataPointOperationMetadata", + "CreateDataPointRequest", + "DailyRollupDataPoint", + "DailyRollUpDataPointsRequest", + "DailyRollUpDataPointsResponse", + "DataPoint", + "DataType", + "ExportExerciseTcxRequest", + "ExportExerciseTcxResponse", + "GetDataPointRequest", + "ListDataPointsRequest", + "ListDataPointsResponse", + "ReconcileDataPointsRequest", + "ReconcileDataPointsResponse", + "ReconciledDataPoint", + "RollupDataPoint", + "RollUpDataPointsRequest", + "RollUpDataPointsResponse", + "UpdateDataPointOperationMetadata", + "UpdateDataPointRequest", + "DataSource", + "CreateSubscriberMetadata", + "CreateSubscriberPayload", + "CreateSubscriberRequest", + "CreateSubscriptionPayload", + "CreateSubscriptionRequest", + "DeleteSubscriberMetadata", + "DeleteSubscriberRequest", + "DeleteSubscriptionRequest", + "EndpointAuthorization", + "ListSubscribersRequest", + "ListSubscribersResponse", + "ListSubscriptionsRequest", + "ListSubscriptionsResponse", + "Subscriber", + "SubscriberConfig", + "Subscription", + "UpdateSubscriberMetadata", + "UpdateSubscriberRequest", + "UpdateSubscriptionRequest", + "GetIdentityRequest", + "GetIrnProfileRequest", + "GetPairedDeviceRequest", + "GetProfileRequest", + "GetSettingsRequest", + "Identity", + "IrnProfile", + "ListPairedDevicesRequest", + "ListPairedDevicesResponse", + "PairedDevice", + "Profile", + "Settings", + "UpdateProfileRequest", + "UpdateSettingsRequest", + "User", + "MedicalDeviceInfo", + "WebhookNotificationCloudLog", +) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/data_coordinates.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/data_coordinates.py new file mode 100644 index 000000000000..e780af7d1fd0 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/data_coordinates.py @@ -0,0 +1,240 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import google.protobuf.duration_pb2 as duration_pb2 # type: ignore +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore +import google.type.date_pb2 as date_pb2 # type: ignore +import google.type.timeofday_pb2 as timeofday_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.devicesandservices.health.v4", + manifest={ + "CivilDateTime", + "CivilTimeInterval", + "ObservationTimeInterval", + "SessionTimeInterval", + "ObservationSampleTime", + }, +) + + +class CivilDateTime(proto.Message): + r"""Civil time representation similar to + [google.type.DateTime][google.type.DateTime], but ensures that + neither the timezone nor the UTC offset can be set to avoid + confusion between civil and physical time queries. + + Attributes: + date (google.type.date_pb2.Date): + Required. Calendar date. + time (google.type.timeofday_pb2.TimeOfDay): + Optional. Time of day. Defaults to the start + of the day, at midnight if omitted. + """ + + date: date_pb2.Date = proto.Field( + proto.MESSAGE, + number=1, + message=date_pb2.Date, + ) + time: timeofday_pb2.TimeOfDay = proto.Field( + proto.MESSAGE, + number=2, + message=timeofday_pb2.TimeOfDay, + ) + + +class CivilTimeInterval(proto.Message): + r"""Counterpart of [google.type.Interval][google.type.Interval], but + using + [CivilDateTime][google.devicesandservices.health.v4.CivilDateTime]. + + Attributes: + start (google.devicesandservices.health_v4.types.CivilDateTime): + Required. The inclusive start of the range. + end (google.devicesandservices.health_v4.types.CivilDateTime): + Required. The exclusive end of the range. + """ + + start: "CivilDateTime" = proto.Field( + proto.MESSAGE, + number=1, + message="CivilDateTime", + ) + end: "CivilDateTime" = proto.Field( + proto.MESSAGE, + number=2, + message="CivilDateTime", + ) + + +class ObservationTimeInterval(proto.Message): + r"""Represents a time interval of an observed data point. + + Attributes: + start_time (google.protobuf.timestamp_pb2.Timestamp): + Required. Observed interval start time. + start_utc_offset (google.protobuf.duration_pb2.Duration): + Required. The offset of the user's local time + at the start of the observation relative to the + Coordinated Universal Time (UTC). + end_time (google.protobuf.timestamp_pb2.Timestamp): + Required. Observed interval end time. + end_utc_offset (google.protobuf.duration_pb2.Duration): + Required. The offset of the user's local time + at the end of the observation relative to the + Coordinated Universal Time (UTC). + civil_start_time (google.devicesandservices.health_v4.types.CivilDateTime): + Output only. Observed interval start time in + civil time in the timezone the subject is in at + the start of the observed interval + civil_end_time (google.devicesandservices.health_v4.types.CivilDateTime): + Output only. Observed interval end time in + civil time in the timezone the subject is in at + the end of the observed interval + """ + + start_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + start_utc_offset: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=2, + message=duration_pb2.Duration, + ) + end_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + end_utc_offset: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=4, + message=duration_pb2.Duration, + ) + civil_start_time: "CivilDateTime" = proto.Field( + proto.MESSAGE, + number=5, + message="CivilDateTime", + ) + civil_end_time: "CivilDateTime" = proto.Field( + proto.MESSAGE, + number=6, + message="CivilDateTime", + ) + + +class SessionTimeInterval(proto.Message): + r"""Represents a time interval of session data point, which + bundles multiple observed metrics together. + + Attributes: + start_time (google.protobuf.timestamp_pb2.Timestamp): + Required. The start time of the observed + session. + start_utc_offset (google.protobuf.duration_pb2.Duration): + Required. The offset of the user's local time + at the start of the session relative to the + Coordinated Universal Time (UTC). + end_time (google.protobuf.timestamp_pb2.Timestamp): + Required. The end time of the observed + session. + end_utc_offset (google.protobuf.duration_pb2.Duration): + Required. The offset of the user's local time + at the end of the session relative to the + Coordinated Universal Time (UTC). + civil_start_time (google.devicesandservices.health_v4.types.CivilDateTime): + Output only. Session start time in civil time + in the timezone the subject is in at the start + of the session. + civil_end_time (google.devicesandservices.health_v4.types.CivilDateTime): + Output only. Session end time in civil time + in the timezone the subject is in at the end of + the session. + """ + + start_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + start_utc_offset: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=2, + message=duration_pb2.Duration, + ) + end_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + end_utc_offset: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=4, + message=duration_pb2.Duration, + ) + civil_start_time: "CivilDateTime" = proto.Field( + proto.MESSAGE, + number=5, + message="CivilDateTime", + ) + civil_end_time: "CivilDateTime" = proto.Field( + proto.MESSAGE, + number=6, + message="CivilDateTime", + ) + + +class ObservationSampleTime(proto.Message): + r"""Represents a sample time of an observed data point. + + Attributes: + physical_time (google.protobuf.timestamp_pb2.Timestamp): + Required. The time of the observation. + utc_offset (google.protobuf.duration_pb2.Duration): + Required. The offset of the user's local time + during the observation relative to the + Coordinated Universal Time (UTC). + civil_time (google.devicesandservices.health_v4.types.CivilDateTime): + Output only. The civil time in the timezone + the subject is in at the time of the + observation. + """ + + physical_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + utc_offset: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=2, + message=duration_pb2.Duration, + ) + civil_time: "CivilDateTime" = proto.Field( + proto.MESSAGE, + number=3, + message="CivilDateTime", + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/data_model.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/data_model.py new file mode 100644 index 000000000000..574e4f97312e --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/data_model.py @@ -0,0 +1,4564 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import google.protobuf.duration_pb2 as duration_pb2 # type: ignore +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore +import google.type.date_pb2 as date_pb2 # type: ignore +import proto # type: ignore + +from google.devicesandservices.health_v4.types import data_coordinates +from google.devicesandservices.health_v4.types import ( + medical_device_info as gdh_medical_device_info, +) + +__protobuf__ = proto.module( + package="google.devicesandservices.health.v4", + manifest={ + "HeartRateZoneType", + "FoodAccessLevel", + "MealType", + "EnergyUnit", + "Nutrient", + "WeightUnit", + "VolumeUnit", + "ActiveZoneMinutes", + "ActiveZoneMinutesRollupValue", + "ActiveMinutes", + "ActiveMinutesRollupValue", + "ActivityLevel", + "ActivityLevelRollupValue", + "Altitude", + "BasalEnergyBurned", + "BodyFat", + "BodyFatRollupValue", + "CoreBodyTemperature", + "CoreBodyTemperatureRollupValue", + "CaloriesInHeartRateZoneRollupValue", + "DailyHeartRateZones", + "DailyHeartRateVariability", + "DailyRespiratoryRate", + "DailyOxygenSaturation", + "DailyRestingHeartRate", + "DailySleepTemperatureDerivations", + "DailyVO2Max", + "Distance", + "DistanceRollupValue", + "Electrocardiogram", + "Exercise", + "Floors", + "FloorsRollupValue", + "AltitudeRollupValue", + "HeartRate", + "HeartRateRollupValue", + "RunVO2MaxRollupValue", + "RunVO2Max", + "HeartRateVariabilityPersonalRangeRollupValue", + "Height", + "HeartRateVariability", + "VolumeQuantity", + "HydrationLog", + "HydrationLogRollupValue", + "IrregularRhythmNotification", + "MetricsSummary", + "WeightQuantity", + "EnergyQuantity", + "NutrientQuantity", + "NutritionLog", + "Food", + "NutritionLogRollupValue", + "OxygenSaturation", + "RestingHeartRatePersonalRangeRollupValue", + "FoodMeasurementUnit", + "RespiratoryRateSleepSummary", + "Sleep", + "Steps", + "StepsRollupValue", + "SwimLengthsData", + "SwimLengthsDataRollupValue", + "TimeInHeartRateZone", + "TimeInHeartRateZoneRollupValue", + "TotalCaloriesRollupValue", + "VO2Max", + "Weight", + "WeightRollupValue", + "BloodGlucose", + "BloodGlucoseRollupValue", + "SedentaryPeriod", + "SedentaryPeriodRollupValue", + "ActiveEnergyBurned", + "ActiveEnergyBurnedRollupValue", + }, +) + + +class HeartRateZoneType(proto.Enum): + r"""The heart rate zone type. + + Values: + HEART_RATE_ZONE_TYPE_UNSPECIFIED (0): + Unspecified heart rate zone. + LIGHT (1): + The light heart rate zone. + MODERATE (2): + The moderate heart rate zone. + VIGOROUS (3): + The vigorous heart rate zone. + PEAK (4): + The peak heart rate zone. + """ + + HEART_RATE_ZONE_TYPE_UNSPECIFIED = 0 + LIGHT = 1 + MODERATE = 2 + VIGOROUS = 3 + PEAK = 4 + + +class FoodAccessLevel(proto.Enum): + r"""Enum representing the access level of a food item. + + Values: + FOOD_ACCESS_LEVEL_UNSPECIFIED (0): + Unspecified food access level. + FOOD_ACCESS_LEVEL_PUBLIC (1): + Public food access level. + FOOD_ACCESS_LEVEL_PRIVATE (2): + Private food access level. + """ + + FOOD_ACCESS_LEVEL_UNSPECIFIED = 0 + FOOD_ACCESS_LEVEL_PUBLIC = 1 + FOOD_ACCESS_LEVEL_PRIVATE = 2 + + +class MealType(proto.Enum): + r"""Enum representing the meal type. + + Values: + MEAL_TYPE_UNSPECIFIED (0): + Unspecified meal type. + BEFORE_BREAKFAST (1): + Value representing a meal before breakfast. + BREAKFAST (2): + Value representing a breakfast. + BEFORE_LUNCH (3): + Value representing a morning snack. + LUNCH (4): + Value representing a lunch. + BEFORE_DINNER (5): + Value representing an afternoon snack. + DINNER (6): + Value representing dinner. + AFTER_DINNER (7): + Value representing an evening snack. + SNACK (8): + Value representing any meal outside of the + usual three meals per day. + ANYTIME (9): + Value representing any time (legacy NA). + """ + + MEAL_TYPE_UNSPECIFIED = 0 + BEFORE_BREAKFAST = 1 + BREAKFAST = 2 + BEFORE_LUNCH = 3 + LUNCH = 4 + BEFORE_DINNER = 5 + DINNER = 6 + AFTER_DINNER = 7 + SNACK = 8 + ANYTIME = 9 + + +class EnergyUnit(proto.Enum): + r"""Enum representing the unit of energy. + + Values: + ENERGY_UNIT_UNSPECIFIED (0): + Unspecified energy unit. + JOULE (1): + Value representing joule. + KILOJOULE (2): + Value representing kilojoule. + KILOCALORIE (3): + Value representing kilocalorie. + SMALL_CALORIE (4): + Value representing small calorie. + CALORIE (5): + Value representing calorie. + """ + + ENERGY_UNIT_UNSPECIFIED = 0 + JOULE = 1 + KILOJOULE = 2 + KILOCALORIE = 3 + SMALL_CALORIE = 4 + CALORIE = 5 + + +class Nutrient(proto.Enum): + r"""Holds information about a user logged food. + + Values: + NUTRIENT_UNSPECIFIED (0): + Unspecified nutrient. + BIOTIN (1): + Value representing biotin nutrient. + CAFFEINE (2): + Value representing caffeine nutrient. + CALCIUM (3): + Value representing calcium nutrient. + CHLORIDE (4): + Value representing chloride nutrient. + CARBOHYDRATES (5): + Value representing carbohydrates nutrient. + CHOLESTEROL (6): + Value representing cholesterol nutrient. + CHROMIUM (7): + Value representing chromium nutrient. + COPPER (8): + Value representing copper nutrient. + DIETARY_FIBER (9): + Value representing dietary fiber nutrient. + FOLIC_ACID (10): + Value representing folic acid nutrient. + IODINE (11): + Value representing iodine nutrient. + IRON (12): + Value representing iron nutrient. + MAGNESIUM (13): + Value representing magnesium nutrient. + MANGANESE (14): + Value representing manganese nutrient. + MOLYBDENUM (15): + Value representing molybdenum nutrient. + MONOUNSATURATED_FAT (16): + Value representing monounsaturated fat + nutrient. + NIACIN (17): + Value representing niacin nutrient. + PANTOTHENIC_ACID (18): + Value representing pantothenic acid nutrient. + PHOSPHORUS (19): + Value representing phosphorus nutrient. + POLYUNSATURATED_FAT (20): + Value representing polyunsaturated fat + nutrient. + POTASSIUM (21): + Value representing potassium nutrient. + PROTEIN (22): + Value representing protein nutrient. + RIBOFLAVIN (23): + Value representing riboflavin nutrient. + SATURATED_FAT (24): + Value representing saturated fat nutrient. + SELENIUM (25): + Value representing selenium nutrient. + SODIUM (26): + Value representing sodium nutrient. + SUGAR (27): + Value representing sugar nutrient. + THIAMIN (28): + Value representing thiamin nutrient. + TRANS_FAT (29): + Value representing trans fat nutrient. + UNSATURATED_FAT (30): + Value representing unsaturated fat nutrient. + VITAMIN_A (31): + Value representing vitamin A nutrient. + VITAMIN_B12 (32): + Value representing vitamin B12 nutrient. + VITAMIN_B6 (33): + Value representing vitamin B6 nutrient. + VITAMIN_C (34): + Value representing vitamin C nutrient. + VITAMIN_D (35): + Value representing vitamin D nutrient. + VITAMIN_E (36): + Value representing vitamin E nutrient. + VITAMIN_K (37): + Value representing vitamin K nutrient. + ZINC (38): + Value representing zinc nutrient. + FOLATE (39): + Value representing folate nutrient. + """ + + NUTRIENT_UNSPECIFIED = 0 + BIOTIN = 1 + CAFFEINE = 2 + CALCIUM = 3 + CHLORIDE = 4 + CARBOHYDRATES = 5 + CHOLESTEROL = 6 + CHROMIUM = 7 + COPPER = 8 + DIETARY_FIBER = 9 + FOLIC_ACID = 10 + IODINE = 11 + IRON = 12 + MAGNESIUM = 13 + MANGANESE = 14 + MOLYBDENUM = 15 + MONOUNSATURATED_FAT = 16 + NIACIN = 17 + PANTOTHENIC_ACID = 18 + PHOSPHORUS = 19 + POLYUNSATURATED_FAT = 20 + POTASSIUM = 21 + PROTEIN = 22 + RIBOFLAVIN = 23 + SATURATED_FAT = 24 + SELENIUM = 25 + SODIUM = 26 + SUGAR = 27 + THIAMIN = 28 + TRANS_FAT = 29 + UNSATURATED_FAT = 30 + VITAMIN_A = 31 + VITAMIN_B12 = 32 + VITAMIN_B6 = 33 + VITAMIN_C = 34 + VITAMIN_D = 35 + VITAMIN_E = 36 + VITAMIN_K = 37 + ZINC = 38 + FOLATE = 39 + + +class WeightUnit(proto.Enum): + r"""Enum representing the unit of weight. + + Values: + WEIGHT_UNIT_UNSPECIFIED (0): + Unspecified weight unit. + GRAM (1): + Value representing gram. + KILOGRAM (2): + Value representing kilogram. + OUNCE (3): + Value representing ounce. + POUND (4): + Value representing pound. + STONE (5): + Value representing stone. + MILLIGRAM (6): + Value representing milligram. + MICROGRAM (7): + Value representing microgram. + NANOGRAM (8): + Value representing nanogram. + """ + + WEIGHT_UNIT_UNSPECIFIED = 0 + GRAM = 1 + KILOGRAM = 2 + OUNCE = 3 + POUND = 4 + STONE = 5 + MILLIGRAM = 6 + MICROGRAM = 7 + NANOGRAM = 8 + + +class VolumeUnit(proto.Enum): + r"""Enum representing the unit of volume. + + Values: + VOLUME_UNIT_UNSPECIFIED (0): + Unspecified volume unit. + CUP_IMPERIAL (1): + Cup (imperial) + CUP_US (2): + Cup (US) + FLUID_OUNCE_IMPERIAL (3): + Fluid ounce (imperial) + FLUID_OUNCE_US (4): + Fluid ounce (US) + LITER (5): + Liter + MILLILITER (6): + Milliliter + PINT_IMPERIAL (7): + Pint (imperial) + PINT_US (8): + Pint (US) + """ + + VOLUME_UNIT_UNSPECIFIED = 0 + CUP_IMPERIAL = 1 + CUP_US = 2 + FLUID_OUNCE_IMPERIAL = 3 + FLUID_OUNCE_US = 4 + LITER = 5 + MILLILITER = 6 + PINT_IMPERIAL = 7 + PINT_US = 8 + + +class ActiveZoneMinutes(proto.Message): + r"""Record of active zone minutes in a given time interval. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + interval (google.devicesandservices.health_v4.types.ObservationTimeInterval): + Required. Observed interval. + heart_rate_zone (google.devicesandservices.health_v4.types.ActiveZoneMinutes.HeartRateZone): + Required. Heart rate zone in which the active + zone minutes have been earned, in the given time + interval. + active_zone_minutes (int): + Required. Number of Active Zone Minutes earned in the given + time interval. Note: active_zone_minutes equals to 1 for low + intensity (fat burn) zones or 2 for high intensity zones + (cardio, peak). + + This field is a member of `oneof`_ ``_active_zone_minutes``. + """ + + class HeartRateZone(proto.Enum): + r"""Represents different heart rate zones. + + Values: + HEART_RATE_ZONE_UNSPECIFIED (0): + Unspecified heart rate zone. + FAT_BURN (1): + The fat burn heart rate zone. + CARDIO (2): + The cardio heart rate zone. + PEAK (3): + The peak heart rate zone. + """ + + HEART_RATE_ZONE_UNSPECIFIED = 0 + FAT_BURN = 1 + CARDIO = 2 + PEAK = 3 + + interval: data_coordinates.ObservationTimeInterval = proto.Field( + proto.MESSAGE, + number=1, + message=data_coordinates.ObservationTimeInterval, + ) + heart_rate_zone: HeartRateZone = proto.Field( + proto.ENUM, + number=2, + enum=HeartRateZone, + ) + active_zone_minutes: int = proto.Field( + proto.INT64, + number=3, + optional=True, + ) + + +class ActiveZoneMinutesRollupValue(proto.Message): + r"""Represents the result of the rollup of the active zone + minutes data type. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + sum_in_cardio_heart_zone (int): + Active zone minutes in ``HeartRateZone.CARDIO``. + + This field is a member of `oneof`_ ``_sum_in_cardio_heart_zone``. + sum_in_peak_heart_zone (int): + Active zone minutes in ``HeartRateZone.PEAK``. + + This field is a member of `oneof`_ ``_sum_in_peak_heart_zone``. + sum_in_fat_burn_heart_zone (int): + Active zone minutes in ``HeartRateZone.FAT_BURN``. + + This field is a member of `oneof`_ ``_sum_in_fat_burn_heart_zone``. + """ + + sum_in_cardio_heart_zone: int = proto.Field( + proto.INT64, + number=1, + optional=True, + ) + sum_in_peak_heart_zone: int = proto.Field( + proto.INT64, + number=2, + optional=True, + ) + sum_in_fat_burn_heart_zone: int = proto.Field( + proto.INT64, + number=3, + optional=True, + ) + + +class ActiveMinutes(proto.Message): + r"""Record of active minutes in a given time interval. + + Attributes: + interval (google.devicesandservices.health_v4.types.ObservationTimeInterval): + Required. Observed interval. + active_minutes_by_activity_level (MutableSequence[google.devicesandservices.health_v4.types.ActiveMinutes.ActiveMinutesByActivityLevel]): + Required. Active minutes by activity level. + At most one record per activity level is + allowed. + """ + + class ActivityLevel(proto.Enum): + r"""Activity level. + + Values: + ACTIVITY_LEVEL_UNSPECIFIED (0): + Activity level is unspecified. + LIGHT (1): + Light activity level. + MODERATE (2): + Moderate activity level. + VIGOROUS (3): + Vigorous activity level. + """ + + ACTIVITY_LEVEL_UNSPECIFIED = 0 + LIGHT = 1 + MODERATE = 2 + VIGOROUS = 3 + + class ActiveMinutesByActivityLevel(proto.Message): + r"""Active minutes at a given activity level. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + activity_level (google.devicesandservices.health_v4.types.ActiveMinutes.ActivityLevel): + Required. The level of activity. + active_minutes (int): + Required. Number of whole minutes spent in + activity. + + This field is a member of `oneof`_ ``_active_minutes``. + """ + + activity_level: "ActiveMinutes.ActivityLevel" = proto.Field( + proto.ENUM, + number=1, + enum="ActiveMinutes.ActivityLevel", + ) + active_minutes: int = proto.Field( + proto.INT64, + number=2, + optional=True, + ) + + interval: data_coordinates.ObservationTimeInterval = proto.Field( + proto.MESSAGE, + number=1, + message=data_coordinates.ObservationTimeInterval, + ) + active_minutes_by_activity_level: MutableSequence[ActiveMinutesByActivityLevel] = ( + proto.RepeatedField( + proto.MESSAGE, + number=2, + message=ActiveMinutesByActivityLevel, + ) + ) + + +class ActiveMinutesRollupValue(proto.Message): + r"""Represents the result of the rollup of the active minutes + data type. + + Attributes: + active_minutes_rollup_by_activity_level (MutableSequence[google.devicesandservices.health_v4.types.ActiveMinutesRollupValue.ActiveMinutesRollupByActivityLevel]): + Active minutes by activity level. At most one + record per activity level is allowed. + """ + + class ActiveMinutesRollupByActivityLevel(proto.Message): + r"""Active minutes by activity level. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + activity_level (google.devicesandservices.health_v4.types.ActiveMinutes.ActivityLevel): + The level of activity. + active_minutes_sum (int): + Number of whole minutes spent in activity. + + This field is a member of `oneof`_ ``_active_minutes_sum``. + """ + + activity_level: "ActiveMinutes.ActivityLevel" = proto.Field( + proto.ENUM, + number=1, + enum="ActiveMinutes.ActivityLevel", + ) + active_minutes_sum: int = proto.Field( + proto.INT64, + number=2, + optional=True, + ) + + active_minutes_rollup_by_activity_level: MutableSequence[ + ActiveMinutesRollupByActivityLevel + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=ActiveMinutesRollupByActivityLevel, + ) + + +class ActivityLevel(proto.Message): + r"""Internal type to capture activity level during a certain time + interval. + + Attributes: + interval (google.devicesandservices.health_v4.types.ObservationTimeInterval): + Required. Observed interval. + activity_level_type (google.devicesandservices.health_v4.types.ActivityLevel.ActivityLevelType): + Required. Activity level type in the given + time interval. + """ + + class ActivityLevelType(proto.Enum): + r"""Represents different activity level types. + + Values: + ACTIVITY_LEVEL_TYPE_UNSPECIFIED (0): + Unspecified activity level type. + SEDENTARY (1): + Sedentary activity level. + LIGHTLY_ACTIVE (2): + Lightly active activity level. + MODERATELY_ACTIVE (3): + Moderately active activity level. + VERY_ACTIVE (4): + Very active activity level. + """ + + ACTIVITY_LEVEL_TYPE_UNSPECIFIED = 0 + SEDENTARY = 1 + LIGHTLY_ACTIVE = 2 + MODERATELY_ACTIVE = 3 + VERY_ACTIVE = 4 + + interval: data_coordinates.ObservationTimeInterval = proto.Field( + proto.MESSAGE, + number=1, + message=data_coordinates.ObservationTimeInterval, + ) + activity_level_type: ActivityLevelType = proto.Field( + proto.ENUM, + number=2, + enum=ActivityLevelType, + ) + + +class ActivityLevelRollupValue(proto.Message): + r"""Represents the result of the rollup of the activity level + data type. + + Attributes: + activity_level_rollups_by_activity_level_type (MutableSequence[google.devicesandservices.health_v4.types.ActivityLevelRollupValue.ActivityLevelRollupByActivityLevelType]): + List of total durations in each activity + level type. + """ + + class ActivityLevelRollupByActivityLevelType(proto.Message): + r"""Represents the total duration in a specific activity level + type. + + Attributes: + activity_level_type (google.devicesandservices.health_v4.types.ActivityLevel.ActivityLevelType): + Activity level type. + total_duration (google.protobuf.duration_pb2.Duration): + Total duration in the activity level type. + """ + + activity_level_type: "ActivityLevel.ActivityLevelType" = proto.Field( + proto.ENUM, + number=1, + enum="ActivityLevel.ActivityLevelType", + ) + total_duration: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=2, + message=duration_pb2.Duration, + ) + + activity_level_rollups_by_activity_level_type: MutableSequence[ + ActivityLevelRollupByActivityLevelType + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=ActivityLevelRollupByActivityLevelType, + ) + + +class Altitude(proto.Message): + r"""Captures the altitude gain (i.e. deltas), and not level above + sea, for a user in millimeters. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + interval (google.devicesandservices.health_v4.types.ObservationTimeInterval): + Required. Observed interval. + gain_millimeters (int): + Required. Altitude gain in millimeters over + the observed interval. + + This field is a member of `oneof`_ ``_gain_millimeters``. + """ + + interval: data_coordinates.ObservationTimeInterval = proto.Field( + proto.MESSAGE, + number=2, + message=data_coordinates.ObservationTimeInterval, + ) + gain_millimeters: int = proto.Field( + proto.INT64, + number=3, + optional=True, + ) + + +class BasalEnergyBurned(proto.Message): + r"""Number of calories burned due to basal metabolic rate (BMR) + over a period of time. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + interval (google.devicesandservices.health_v4.types.ObservationTimeInterval): + Required. Observed interval. + kcal (float): + Required. Number of calories burned due to + basal metabolic rate in kilocalories over the + observed interval. + + This field is a member of `oneof`_ ``_kcal``. + """ + + interval: data_coordinates.ObservationTimeInterval = proto.Field( + proto.MESSAGE, + number=1, + message=data_coordinates.ObservationTimeInterval, + ) + kcal: float = proto.Field( + proto.DOUBLE, + number=2, + optional=True, + ) + + +class BodyFat(proto.Message): + r"""Body fat measurement. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + sample_time (google.devicesandservices.health_v4.types.ObservationSampleTime): + Required. The time at which body fat was + measured. + percentage (float): + Required. Body fat percentage, in range [0, 100]. + + This field is a member of `oneof`_ ``_percentage``. + """ + + sample_time: data_coordinates.ObservationSampleTime = proto.Field( + proto.MESSAGE, + number=2, + message=data_coordinates.ObservationSampleTime, + ) + percentage: float = proto.Field( + proto.DOUBLE, + number=3, + optional=True, + ) + + +class BodyFatRollupValue(proto.Message): + r"""Represents the result of the rollup of the body fat data + type. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + body_fat_percentage_avg (float): + Average body fat percentage. + + This field is a member of `oneof`_ ``_body_fat_percentage_avg``. + """ + + body_fat_percentage_avg: float = proto.Field( + proto.DOUBLE, + number=1, + optional=True, + ) + + +class CoreBodyTemperature(proto.Message): + r"""Core body temperature measurement, distinct from peripheral + body temperature, reflects the temperature of the body's + internal organs. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + sample_time (google.devicesandservices.health_v4.types.ObservationSampleTime): + Required. The time at which core body + temperature was measured. + temperature_celsius (float): + Required. The core body temperature in + Celsius. + + This field is a member of `oneof`_ ``_temperature_celsius``. + measurement_location (google.devicesandservices.health_v4.types.CoreBodyTemperature.MeasurementLocation): + Optional. The location of the core body + temperature measurement. + id (str): + Optional. The unique identifier of the core + body temperature measurement. + """ + + class MeasurementLocation(proto.Enum): + r"""Measurement location for core body temperature. + + Values: + MEASUREMENT_LOCATION_UNSPECIFIED (0): + Measurement location is unspecified. + OTHER (1): + Other measurement location. + ARMPIT (2): + Armpit measurement location. + BODY (3): + Body measurement location. + EAR (4): + Ear measurement location. + FINGER (5): + Finger measurement location. + GASTRO_INTESTINAL (6): + Gastro-intestinal measurement location. + MOUTH (7): + Mouth measurement location. + RECTUM (8): + Rectum measurement location. + TOE (9): + Toe measurement location. + EAR_DRUM (10): + Ear drum measurement location. + TEMPORAL_ARTERY (11): + Temporal artery measurement location. + FOREHEAD (12): + Forehead measurement location. + URINARY_BLADDER (13): + Urinary bladder measurement location. + NASAL (14): + Nasal measurement location. + NASOPHARYNGEAL (15): + Nasopharyngeal measurement location. + WRIST (16): + Wrist measurement location. + VAGINA (17): + Vagina measurement location. + """ + + MEASUREMENT_LOCATION_UNSPECIFIED = 0 + OTHER = 1 + ARMPIT = 2 + BODY = 3 + EAR = 4 + FINGER = 5 + GASTRO_INTESTINAL = 6 + MOUTH = 7 + RECTUM = 8 + TOE = 9 + EAR_DRUM = 10 + TEMPORAL_ARTERY = 11 + FOREHEAD = 12 + URINARY_BLADDER = 13 + NASAL = 14 + NASOPHARYNGEAL = 15 + WRIST = 16 + VAGINA = 17 + + sample_time: data_coordinates.ObservationSampleTime = proto.Field( + proto.MESSAGE, + number=2, + message=data_coordinates.ObservationSampleTime, + ) + temperature_celsius: float = proto.Field( + proto.DOUBLE, + number=3, + optional=True, + ) + measurement_location: MeasurementLocation = proto.Field( + proto.ENUM, + number=4, + enum=MeasurementLocation, + ) + id: str = proto.Field( + proto.STRING, + number=5, + ) + + +class CoreBodyTemperatureRollupValue(proto.Message): + r"""Represents the result of the rollup of the core body + temperature data type. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + temperature_celsius_avg (float): + Average core body temperature in Celsius. + + This field is a member of `oneof`_ ``_temperature_celsius_avg``. + temperature_celsius_max (float): + Maximum core body temperature in Celsius. + + This field is a member of `oneof`_ ``_temperature_celsius_max``. + temperature_celsius_min (float): + Minimum core body temperature in Celsius. + + This field is a member of `oneof`_ ``_temperature_celsius_min``. + """ + + temperature_celsius_avg: float = proto.Field( + proto.DOUBLE, + number=1, + optional=True, + ) + temperature_celsius_max: float = proto.Field( + proto.DOUBLE, + number=2, + optional=True, + ) + temperature_celsius_min: float = proto.Field( + proto.DOUBLE, + number=3, + optional=True, + ) + + +class CaloriesInHeartRateZoneRollupValue(proto.Message): + r"""Represents the result of the rollup of the calories in heart + rate zone data type. + + Attributes: + calories_in_heart_rate_zones (MutableSequence[google.devicesandservices.health_v4.types.CaloriesInHeartRateZoneRollupValue.CaloriesInHeartRateZoneValue]): + List of calories burned in each heart rate + zone. + """ + + class CaloriesInHeartRateZoneValue(proto.Message): + r"""Represents the amount of kilocalories burned in a specific + heart rate zone. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + heart_rate_zone (google.devicesandservices.health_v4.types.HeartRateZoneType): + The heart rate zone. + kcal (float): + The amount of kilocalories burned in the + specified heart rate zone. + + This field is a member of `oneof`_ ``_kcal``. + """ + + heart_rate_zone: "HeartRateZoneType" = proto.Field( + proto.ENUM, + number=1, + enum="HeartRateZoneType", + ) + kcal: float = proto.Field( + proto.DOUBLE, + number=2, + optional=True, + ) + + calories_in_heart_rate_zones: MutableSequence[CaloriesInHeartRateZoneValue] = ( + proto.RepeatedField( + proto.MESSAGE, + number=1, + message=CaloriesInHeartRateZoneValue, + ) + ) + + +class DailyHeartRateZones(proto.Message): + r"""User's heart rate zone thresholds based on the Karvonen + algorithm for a specific day. + + Attributes: + date (google.type.date_pb2.Date): + Required. Date (in user's timezone) of the + heart rate zones record. + heart_rate_zones (MutableSequence[google.devicesandservices.health_v4.types.DailyHeartRateZones.HeartRateZone]): + Required. The heart rate zones. + """ + + class HeartRateZone(proto.Message): + r"""The heart rate zone. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + heart_rate_zone_type (google.devicesandservices.health_v4.types.HeartRateZoneType): + Required. The heart rate zone type. + min_beats_per_minute (int): + Required. Minimum heart rate for this zone in + beats per minute. + + This field is a member of `oneof`_ ``_min_beats_per_minute``. + max_beats_per_minute (int): + Required. Maximum heart rate for this zone in + beats per minute. + + This field is a member of `oneof`_ ``_max_beats_per_minute``. + """ + + heart_rate_zone_type: "HeartRateZoneType" = proto.Field( + proto.ENUM, + number=1, + enum="HeartRateZoneType", + ) + min_beats_per_minute: int = proto.Field( + proto.INT64, + number=2, + optional=True, + ) + max_beats_per_minute: int = proto.Field( + proto.INT64, + number=3, + optional=True, + ) + + date: date_pb2.Date = proto.Field( + proto.MESSAGE, + number=1, + message=date_pb2.Date, + ) + heart_rate_zones: MutableSequence[HeartRateZone] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=HeartRateZone, + ) + + +class DailyHeartRateVariability(proto.Message): + r"""Represents the daily heart rate variability data type. + + At least one of the following fields must be set: + + - ``average_heart_rate_variability_milliseconds`` + - ``non_rem_heart_rate_beats_per_minute`` + - ``entropy`` + - ``deep_sleep_root_mean_square_of_successive_differences_milliseconds`` + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + date (google.type.date_pb2.Date): + Required. Date (in the user's timezone) of + heart rate variability measurement. + average_heart_rate_variability_milliseconds (float): + Optional. A user's average heart rate + variability calculated using the root mean + square of successive differences (RMSSD) in + times between heartbeats. + + This field is a member of `oneof`_ ``_average_heart_rate_variability_milliseconds``. + non_rem_heart_rate_beats_per_minute (int): + Optional. Non-REM heart rate + + This field is a member of `oneof`_ ``_non_rem_heart_rate_beats_per_minute``. + entropy (float): + Optional. The Shanon entropy of heartbeat + intervals. Entropy quantifies randomness or + disorder in a system. High entropy indicates + high HRV. Entropy is measured from the histogram + of time interval between successive heart beats + values measured during sleep. + + This field is a member of `oneof`_ ``_entropy``. + deep_sleep_root_mean_square_of_successive_differences_milliseconds (float): + Optional. The root mean square of successive + differences (RMSSD) value during deep sleep. + + This field is a member of `oneof`_ ``_deep_sleep_root_mean_square_of_successive_differences_milliseconds``. + """ + + date: date_pb2.Date = proto.Field( + proto.MESSAGE, + number=2, + message=date_pb2.Date, + ) + average_heart_rate_variability_milliseconds: float = proto.Field( + proto.DOUBLE, + number=4, + optional=True, + ) + non_rem_heart_rate_beats_per_minute: int = proto.Field( + proto.INT64, + number=5, + optional=True, + ) + entropy: float = proto.Field( + proto.DOUBLE, + number=6, + optional=True, + ) + deep_sleep_root_mean_square_of_successive_differences_milliseconds: float = ( + proto.Field( + proto.DOUBLE, + number=7, + optional=True, + ) + ) + + +class DailyRespiratoryRate(proto.Message): + r"""A daily average respiratory rate (breaths per minute) for a + day of the year. One data point per day calculated for the main + sleep. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + date (google.type.date_pb2.Date): + Required. The date on which the respiratory + rate was measured. + breaths_per_minute (float): + Required. The average number of breaths taken + per minute. + + This field is a member of `oneof`_ ``_breaths_per_minute``. + """ + + date: date_pb2.Date = proto.Field( + proto.MESSAGE, + number=1, + message=date_pb2.Date, + ) + breaths_per_minute: float = proto.Field( + proto.DOUBLE, + number=2, + optional=True, + ) + + +class DailyOxygenSaturation(proto.Message): + r"""A daily oxygen saturation (SpO2) record. + Represents the user's daily oxygen saturation summary, typically + calculated during sleep. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + date (google.type.date_pb2.Date): + Required. Date (in user's timezone) of the + daily oxygen saturation record. + average_percentage (float): + Required. The average value of the oxygen + saturation samples during the sleep. + + This field is a member of `oneof`_ ``_average_percentage``. + lower_bound_percentage (float): + Required. The lower bound of the confidence + interval of oxygen saturation samples during + sleep. + + This field is a member of `oneof`_ ``_lower_bound_percentage``. + upper_bound_percentage (float): + Required. The upper bound of the confidence + interval of oxygen saturation samples during + sleep. + + This field is a member of `oneof`_ ``_upper_bound_percentage``. + standard_deviation_percentage (float): + Optional. Standard deviation of the daily + oxygen saturation averages from the past 7-30 + days. + + This field is a member of `oneof`_ ``_standard_deviation_percentage``. + """ + + date: date_pb2.Date = proto.Field( + proto.MESSAGE, + number=1, + message=date_pb2.Date, + ) + average_percentage: float = proto.Field( + proto.DOUBLE, + number=2, + optional=True, + ) + lower_bound_percentage: float = proto.Field( + proto.DOUBLE, + number=3, + optional=True, + ) + upper_bound_percentage: float = proto.Field( + proto.DOUBLE, + number=4, + optional=True, + ) + standard_deviation_percentage: float = proto.Field( + proto.DOUBLE, + number=5, + optional=True, + ) + + +class DailyRestingHeartRate(proto.Message): + r"""Measures the daily resting heart rate for a user, calculated + using the all day heart rate measurements. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + date (google.type.date_pb2.Date): + Required. Date (in the user's timezone) of + the resting heart rate measurement. + beats_per_minute (int): + Required. The resting heart rate value in + beats per minute. + + This field is a member of `oneof`_ ``_beats_per_minute``. + daily_resting_heart_rate_metadata (google.devicesandservices.health_v4.types.DailyRestingHeartRate.DailyRestingHeartRateMetadata): + Optional. Metadata for the daily resting + heart rate. + """ + + class DailyRestingHeartRateMetadata(proto.Message): + r"""Metadata for the daily resting heart rate. + + Attributes: + calculation_method (google.devicesandservices.health_v4.types.DailyRestingHeartRate.DailyRestingHeartRateMetadata.CalculationMethod): + Required. The method used to calculate the + resting heart rate. + """ + + class CalculationMethod(proto.Enum): + r"""The method used to calculate the resting heart rate. + + Values: + CALCULATION_METHOD_UNSPECIFIED (0): + The calculation method is unspecified. + WITH_SLEEP (1): + The resting heart rate is calculated using + the sleep data. + ONLY_WITH_AWAKE_DATA (2): + The resting heart rate is calculated using + only awake data. + """ + + CALCULATION_METHOD_UNSPECIFIED = 0 + WITH_SLEEP = 1 + ONLY_WITH_AWAKE_DATA = 2 + + calculation_method: "DailyRestingHeartRate.DailyRestingHeartRateMetadata.CalculationMethod" = proto.Field( + proto.ENUM, + number=1, + enum="DailyRestingHeartRate.DailyRestingHeartRateMetadata.CalculationMethod", + ) + + date: date_pb2.Date = proto.Field( + proto.MESSAGE, + number=2, + message=date_pb2.Date, + ) + beats_per_minute: int = proto.Field( + proto.INT64, + number=4, + optional=True, + ) + daily_resting_heart_rate_metadata: DailyRestingHeartRateMetadata = proto.Field( + proto.MESSAGE, + number=5, + message=DailyRestingHeartRateMetadata, + ) + + +class DailySleepTemperatureDerivations(proto.Message): + r"""Provides derived sleep temperature values, calculated from + skin or internal device temperature readings during sleep. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + date (google.type.date_pb2.Date): + Required. Date for which the sleep + temperature derivations are calculated. + nightly_temperature_celsius (float): + Required. The user's nightly skin + temperature. It is the mean of skin temperature + samples taken from the user’s sleep. + + This field is a member of `oneof`_ ``_nightly_temperature_celsius``. + baseline_temperature_celsius (float): + Optional. The user's baseline skin + temperature. It is the median of the user's + nightly skin temperature over the past 30 days. + + This field is a member of `oneof`_ ``_baseline_temperature_celsius``. + relative_nightly_stddev_30d_celsius (float): + Optional. The standard deviation of the + user’s relative nightly skin temperature + (temperature - baseline) over the past 30 days. + + This field is a member of `oneof`_ ``_relative_nightly_stddev_30d_celsius``. + """ + + date: date_pb2.Date = proto.Field( + proto.MESSAGE, + number=1, + message=date_pb2.Date, + ) + nightly_temperature_celsius: float = proto.Field( + proto.DOUBLE, + number=2, + optional=True, + ) + baseline_temperature_celsius: float = proto.Field( + proto.DOUBLE, + number=3, + optional=True, + ) + relative_nightly_stddev_30d_celsius: float = proto.Field( + proto.DOUBLE, + number=4, + optional=True, + ) + + +class DailyVO2Max(proto.Message): + r"""Contains a daily summary of the user's VO2 max (cardio + fitness score), which is the maximum rate of oxygen the body can + use during exercise. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + date (google.type.date_pb2.Date): + Required. The date for which the Daily VO2 + max was measured. + vo2_max (float): + Required. Daily VO2 max value measured as in + ml consumed oxygen / kg of body weight / min. + + This field is a member of `oneof`_ ``_vo2_max``. + estimated (bool): + Optional. An estimated field is added to + indicate when the confidence has decreased + sufficiently to consider the value an + estimation. + cardio_fitness_level (google.devicesandservices.health_v4.types.DailyVO2Max.CardioFitnessLevel): + Optional. Represents the user's cardio + fitness level based on their VO2 max. + vo2_max_covariance (float): + Optional. The covariance of the VO2 max + value. + + This field is a member of `oneof`_ ``_vo2_max_covariance``. + """ + + class CardioFitnessLevel(proto.Enum): + r"""The cardio fitness level categories. + + Values: + CARDIO_FITNESS_LEVEL_UNSPECIFIED (0): + Unspecified cardio fitness level. + POOR (1): + Poor cardio fitness level. + FAIR (2): + Fair cardio fitness level. + AVERAGE (3): + Average cardio fitness level. + GOOD (4): + Good cardio fitness level. + VERY_GOOD (5): + Very good cardio fitness level. + EXCELLENT (6): + Excellent cardio fitness level. + """ + + CARDIO_FITNESS_LEVEL_UNSPECIFIED = 0 + POOR = 1 + FAIR = 2 + AVERAGE = 3 + GOOD = 4 + VERY_GOOD = 5 + EXCELLENT = 6 + + date: date_pb2.Date = proto.Field( + proto.MESSAGE, + number=1, + message=date_pb2.Date, + ) + vo2_max: float = proto.Field( + proto.DOUBLE, + number=2, + optional=True, + ) + estimated: bool = proto.Field( + proto.BOOL, + number=3, + ) + cardio_fitness_level: CardioFitnessLevel = proto.Field( + proto.ENUM, + number=4, + enum=CardioFitnessLevel, + ) + vo2_max_covariance: float = proto.Field( + proto.DOUBLE, + number=5, + optional=True, + ) + + +class Distance(proto.Message): + r"""Distance traveled over an interval of time. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + interval (google.devicesandservices.health_v4.types.ObservationTimeInterval): + Required. Observed interval. + millimeters (int): + Required. Distance in millimeters over the + observed interval. + + This field is a member of `oneof`_ ``_millimeters``. + """ + + interval: data_coordinates.ObservationTimeInterval = proto.Field( + proto.MESSAGE, + number=2, + message=data_coordinates.ObservationTimeInterval, + ) + millimeters: int = proto.Field( + proto.INT64, + number=3, + optional=True, + ) + + +class DistanceRollupValue(proto.Message): + r"""Result of the rollup of the user's distance. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + millimeters_sum (int): + Sum of the distance in millimeters. + + This field is a member of `oneof`_ ``_millimeters_sum``. + """ + + millimeters_sum: int = proto.Field( + proto.INT64, + number=1, + optional=True, + ) + + +class Electrocardiogram(proto.Message): + r"""Represents an Electrocardiogram (ECG) measurement session. + This data type is based on SaMD feature and any changes to it + may require additional review. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + interval (google.devicesandservices.health_v4.types.SessionTimeInterval): + Required. Observed interval. + + NOTE: Historical ECG data lacks timezone offsets, so + ``start_utc_offset`` and ``end_utc_offset`` will be missing + or default to zero. As a result, the civil time fields + within this interval will default to UTC. It is recommended + to use physical time fields instead for accurate time + referencing. + + NOTE: The ``start_time`` and ``end_time`` of the interval + are equal, representing the reading time. + beats_per_minute_avg (int): + Optional. Average heart rate recorded during + ECG reading in beats per minute. + + This field is a member of `oneof`_ ``_beats_per_minute_avg``. + result_classification (google.devicesandservices.health_v4.types.Electrocardiogram.ResultClassification): + Optional. The result classification of the + ECG reading. + waveform_samples (MutableSequence[int]): + Optional. An array of voltage values + representing lead I ECG values. Each sample + represents voltage difference in ECG graph. The + first value in array corresponds to the start of + the reading. + sampling_frequency_hertz (int): + Optional. The sampling frequency of waveform + samples in hertz. + + This field is a member of `oneof`_ ``_sampling_frequency_hertz``. + millivolts_scaling_factor (int): + Optional. The factor by which to divide waveform samples to + get voltage in millivolts: millivolts = waveform_sample / + millivolts_scaling_factor. + + This field is a member of `oneof`_ ``_millivolts_scaling_factor``. + lead_number (int): + Optional. The number of leads used for ECG + reading. + + This field is a member of `oneof`_ ``_lead_number``. + medical_device_info (google.devicesandservices.health_v4.types.MedicalDeviceInfo): + Output only. The meta information for the compatible device + used to conduct the measurement. + + ECG measurements typically populate ``firmware_version``, + ``feature_version``, and ``device_model``. + """ + + class ResultClassification(proto.Enum): + r"""The classification of the ECG reading rhythm. + + Values: + RESULT_CLASSIFICATION_UNSPECIFIED (0): + Unspecified result classification. + NORMAL_SINUS_RHYTHM (1): + Heart rhythm appears normal. Corresponds to + result "Normal Sinus Rhythm". + ATRIAL_FIBRILLATION (2): + Signs of Atrial Fibrillation detected. + Corresponds to result "Atrial Fibrillation". + INCONCLUSIVE (3): + The reading is inconclusive as it could not + be classified. Corresponds to result + "Inconclusive". + INCONCLUSIVE_HIGH_HEART_RATE (4): + The reading is inconclusive as it could not + be classified because heart rate is high + (>120bpm). Corresponds to result "Inconclusive: + High heart rate". + INCONCLUSIVE_LOW_HEART_RATE (5): + The reading is inconclusive as it could not + be classified because heart rate is low + (<50bpm). Corresponds to result "Inconclusive: + Low heart rate". + UNREADABLE (6): + The reading is unreadable. + NOT_ANALYZED (7): + The reading was not analyzed. + """ + + RESULT_CLASSIFICATION_UNSPECIFIED = 0 + NORMAL_SINUS_RHYTHM = 1 + ATRIAL_FIBRILLATION = 2 + INCONCLUSIVE = 3 + INCONCLUSIVE_HIGH_HEART_RATE = 4 + INCONCLUSIVE_LOW_HEART_RATE = 5 + UNREADABLE = 6 + NOT_ANALYZED = 7 + + interval: data_coordinates.SessionTimeInterval = proto.Field( + proto.MESSAGE, + number=1, + message=data_coordinates.SessionTimeInterval, + ) + beats_per_minute_avg: int = proto.Field( + proto.INT64, + number=2, + optional=True, + ) + result_classification: ResultClassification = proto.Field( + proto.ENUM, + number=3, + enum=ResultClassification, + ) + waveform_samples: MutableSequence[int] = proto.RepeatedField( + proto.SINT32, + number=4, + ) + sampling_frequency_hertz: int = proto.Field( + proto.INT32, + number=5, + optional=True, + ) + millivolts_scaling_factor: int = proto.Field( + proto.INT32, + number=6, + optional=True, + ) + lead_number: int = proto.Field( + proto.INT32, + number=7, + optional=True, + ) + medical_device_info: gdh_medical_device_info.MedicalDeviceInfo = proto.Field( + proto.MESSAGE, + number=8, + message=gdh_medical_device_info.MedicalDeviceInfo, + ) + + +class Exercise(proto.Message): + r"""An exercise that stores information about a physical + activity. + + Attributes: + interval (google.devicesandservices.health_v4.types.SessionTimeInterval): + Required. Observed exercise interval + exercise_type (google.devicesandservices.health_v4.types.Exercise.ExerciseType): + Required. The type of activity performed + during an exercise. + splits (MutableSequence[google.devicesandservices.health_v4.types.Exercise.SplitSummary]): + Optional. The default split is 1 km or 1 + mile. + - if the movement distance is less than the + default, then there are no splits + - if the movement distance is greater than or + equal to the default, + then we have splits + exercise_events (MutableSequence[google.devicesandservices.health_v4.types.Exercise.ExerciseEvent]): + Optional. Exercise events that happen during + an exercise, such as pause & restarts. + split_summaries (MutableSequence[google.devicesandservices.health_v4.types.Exercise.SplitSummary]): + Optional. Laps or splits recorded within an + exercise. Laps could be split based on distance + or other criteria (duration, etc.) Laps should + not be overlapping with each other. + metrics_summary (google.devicesandservices.health_v4.types.MetricsSummary): + Required. Summary metrics for this exercise + ( ) + exercise_metadata (google.devicesandservices.health_v4.types.Exercise.ExerciseMetadata): + Optional. Additional exercise metadata. + display_name (str): + Required. Exercise display name. + active_duration (google.protobuf.duration_pb2.Duration): + Optional. Duration excluding pauses. + notes (str): + Optional. Standard free-form notes captured + at manual logging. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. This is the timestamp of the + last update to the exercise. + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Represents the timestamp of the + creation of the exercise. + """ + + class ExerciseType(proto.Enum): + r"""The type of activity performed during an exercise. + + Values: + EXERCISE_TYPE_UNSPECIFIED (0): + Exercise type is unspecified. + RUNNING (1): + Running type. + WALKING (2): + Walking type. + BIKING (3): + Biking type. + SWIMMING (4): + Swimming type. + HIKING (5): + Hiking type. + YOGA (6): + Yoga type. + PILATES (7): + Pilates type. + WORKOUT (8): + Workout type. + HIIT (9): + HIIT type. + WEIGHTLIFTING (10): + Weightlifting type. + STRENGTH_TRAINING (11): + Strength training type. + OTHER (12): + Other type. + """ + + EXERCISE_TYPE_UNSPECIFIED = 0 + RUNNING = 1 + WALKING = 2 + BIKING = 3 + SWIMMING = 4 + HIKING = 5 + YOGA = 6 + PILATES = 7 + WORKOUT = 8 + HIIT = 9 + WEIGHTLIFTING = 10 + STRENGTH_TRAINING = 11 + OTHER = 12 + + class SplitSummary(proto.Message): + r"""Represents splits or laps recorded within an exercise. Lap + events partition a workout into segments based on criteria like + distance, time, or calories. + + Attributes: + start_time (google.protobuf.timestamp_pb2.Timestamp): + Required. Lap start time + start_utc_offset (google.protobuf.duration_pb2.Duration): + Required. Lap start time offset from UTC + end_time (google.protobuf.timestamp_pb2.Timestamp): + Required. Lap end time + end_utc_offset (google.protobuf.duration_pb2.Duration): + Required. Lap end time offset from UTC + active_duration (google.protobuf.duration_pb2.Duration): + Output only. Lap time excluding the pauses. + metrics_summary (google.devicesandservices.health_v4.types.MetricsSummary): + Required. Summary metrics for this split. + split_type (google.devicesandservices.health_v4.types.Exercise.SplitSummary.SplitType): + Required. Method used to split the exercise + laps. Users may manually mark the lap as + complete even if the tracking is automatic. + """ + + class SplitType(proto.Enum): + r"""The type of the split, such as manual, duration, distance, + calories. + + Values: + SPLIT_TYPE_UNSPECIFIED (0): + Split type is unspecified. + MANUAL (1): + Manual split. + DURATION (2): + Split by duration. + DISTANCE (3): + Split by distance. + CALORIES (4): + Split by calories. + """ + + SPLIT_TYPE_UNSPECIFIED = 0 + MANUAL = 1 + DURATION = 2 + DISTANCE = 3 + CALORIES = 4 + + start_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + start_utc_offset: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=2, + message=duration_pb2.Duration, + ) + end_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + end_utc_offset: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=4, + message=duration_pb2.Duration, + ) + active_duration: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=5, + message=duration_pb2.Duration, + ) + metrics_summary: "MetricsSummary" = proto.Field( + proto.MESSAGE, + number=6, + message="MetricsSummary", + ) + split_type: "Exercise.SplitSummary.SplitType" = proto.Field( + proto.ENUM, + number=7, + enum="Exercise.SplitSummary.SplitType", + ) + + class ExerciseEvent(proto.Message): + r"""Represents instantaneous events that happen during an + exercise, such as start, stop, pause, split. + + Attributes: + event_time (google.protobuf.timestamp_pb2.Timestamp): + Required. Exercise event time + event_utc_offset (google.protobuf.duration_pb2.Duration): + Required. Exercise event time offset from UTC + exercise_event_type (google.devicesandservices.health_v4.types.Exercise.ExerciseEvent.ExerciseEventType): + Required. The type of the event, such as + start, stop, pause, resume. + """ + + class ExerciseEventType(proto.Enum): + r"""The type of the event, such as start, stop, pause, resume. + + Values: + EXERCISE_EVENT_TYPE_UNSPECIFIED (0): + Exercise event type is unspecified. + START (1): + Exercise start event. + STOP (2): + Exercise stop event. + PAUSE (3): + Exercise pause event. + RESUME (4): + Exercise resume event. + AUTO_PAUSE (5): + Exercise auto-pause event. + AUTO_RESUME (6): + Exercise auto-resume event. + """ + + EXERCISE_EVENT_TYPE_UNSPECIFIED = 0 + START = 1 + STOP = 2 + PAUSE = 3 + RESUME = 4 + AUTO_PAUSE = 5 + AUTO_RESUME = 6 + + event_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + event_utc_offset: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=2, + message=duration_pb2.Duration, + ) + exercise_event_type: "Exercise.ExerciseEvent.ExerciseEventType" = proto.Field( + proto.ENUM, + number=3, + enum="Exercise.ExerciseEvent.ExerciseEventType", + ) + + class ExerciseMetadata(proto.Message): + r"""Additional exercise metadata. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + pool_length_millimeters (int): + Optional. Pool length in millimeters. Only + present in the swimming exercises. + + This field is a member of `oneof`_ ``_pool_length_millimeters``. + has_gps (bool): + Optional. Whether the exercise had GPS + tracking. + """ + + pool_length_millimeters: int = proto.Field( + proto.INT64, + number=1, + optional=True, + ) + has_gps: bool = proto.Field( + proto.BOOL, + number=2, + ) + + interval: data_coordinates.SessionTimeInterval = proto.Field( + proto.MESSAGE, + number=2, + message=data_coordinates.SessionTimeInterval, + ) + exercise_type: ExerciseType = proto.Field( + proto.ENUM, + number=6, + enum=ExerciseType, + ) + splits: MutableSequence[SplitSummary] = proto.RepeatedField( + proto.MESSAGE, + number=8, + message=SplitSummary, + ) + exercise_events: MutableSequence[ExerciseEvent] = proto.RepeatedField( + proto.MESSAGE, + number=15, + message=ExerciseEvent, + ) + split_summaries: MutableSequence[SplitSummary] = proto.RepeatedField( + proto.MESSAGE, + number=9, + message=SplitSummary, + ) + metrics_summary: "MetricsSummary" = proto.Field( + proto.MESSAGE, + number=10, + message="MetricsSummary", + ) + exercise_metadata: ExerciseMetadata = proto.Field( + proto.MESSAGE, + number=11, + message=ExerciseMetadata, + ) + display_name: str = proto.Field( + proto.STRING, + number=12, + ) + active_duration: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=13, + message=duration_pb2.Duration, + ) + notes: str = proto.Field( + proto.STRING, + number=14, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=16, + message=timestamp_pb2.Timestamp, + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=17, + message=timestamp_pb2.Timestamp, + ) + + +class Floors(proto.Message): + r"""Gained elevation measured in floors over the time interval + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + interval (google.devicesandservices.health_v4.types.ObservationTimeInterval): + Required. Observed interval + count (int): + Required. Number of floors in the recorded + interval + + This field is a member of `oneof`_ ``_count``. + """ + + interval: data_coordinates.ObservationTimeInterval = proto.Field( + proto.MESSAGE, + number=2, + message=data_coordinates.ObservationTimeInterval, + ) + count: int = proto.Field( + proto.INT64, + number=4, + optional=True, + ) + + +class FloorsRollupValue(proto.Message): + r"""Represents the result of the rollup of the user's floors. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + count_sum (int): + Sum of the floors count. + + This field is a member of `oneof`_ ``_count_sum``. + """ + + count_sum: int = proto.Field( + proto.INT64, + number=1, + optional=True, + ) + + +class AltitudeRollupValue(proto.Message): + r"""Represents the result of the rollup of the user's altitude. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + gain_millimeters_sum (int): + Sum of the altitude gain in millimeters. + + This field is a member of `oneof`_ ``_gain_millimeters_sum``. + """ + + gain_millimeters_sum: int = proto.Field( + proto.INT64, + number=1, + optional=True, + ) + + +class HeartRate(proto.Message): + r"""A heart rate measurement. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + sample_time (google.devicesandservices.health_v4.types.ObservationSampleTime): + Required. Observation time + beats_per_minute (int): + Required. The heart rate value in beats per + minute. + + This field is a member of `oneof`_ ``_beats_per_minute``. + metadata (google.devicesandservices.health_v4.types.HeartRate.HeartRateMetadata): + Optional. Metadata about the heart rate + sample. + """ + + class HeartRateMetadata(proto.Message): + r"""Heart rate metadata. + + Attributes: + motion_context (google.devicesandservices.health_v4.types.HeartRate.HeartRateMetadata.MotionContext): + Optional. Indicates the user’s level of + activity when the heart rate sample was measured + sensor_location (google.devicesandservices.health_v4.types.HeartRate.HeartRateMetadata.SensorLocation): + Optional. Indicates the location of the + sensor that measured the heart rate. + """ + + class MotionContext(proto.Enum): + r"""The user’s level of activity when the heart rate sample was + measured. + + Values: + MOTION_CONTEXT_UNSPECIFIED (0): + The default value when no data is available. + ACTIVE (1): + The user is active. + SEDENTARY (2): + The user is inactive. + """ + + MOTION_CONTEXT_UNSPECIFIED = 0 + ACTIVE = 1 + SEDENTARY = 2 + + class SensorLocation(proto.Enum): + r"""The location of the sensor that measured the heart rate. + + Values: + SENSOR_LOCATION_UNSPECIFIED (0): + The default value when no data is available. + CHEST (1): + Chest sensor. + WRIST (2): + Wrist sensor. + FINGER (3): + Finger sensor. + HAND (4): + Hand sensor. + EAR_LOBE (5): + Ear lobe sensor. + FOOT (6): + Foot sensor. + """ + + SENSOR_LOCATION_UNSPECIFIED = 0 + CHEST = 1 + WRIST = 2 + FINGER = 3 + HAND = 4 + EAR_LOBE = 5 + FOOT = 6 + + motion_context: "HeartRate.HeartRateMetadata.MotionContext" = proto.Field( + proto.ENUM, + number=1, + enum="HeartRate.HeartRateMetadata.MotionContext", + ) + sensor_location: "HeartRate.HeartRateMetadata.SensorLocation" = proto.Field( + proto.ENUM, + number=2, + enum="HeartRate.HeartRateMetadata.SensorLocation", + ) + + sample_time: data_coordinates.ObservationSampleTime = proto.Field( + proto.MESSAGE, + number=2, + message=data_coordinates.ObservationSampleTime, + ) + beats_per_minute: int = proto.Field( + proto.INT64, + number=4, + optional=True, + ) + metadata: HeartRateMetadata = proto.Field( + proto.MESSAGE, + number=6, + message=HeartRateMetadata, + ) + + +class HeartRateRollupValue(proto.Message): + r"""Represents the result of the rollup of the heart rate data + type. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + beats_per_minute_avg (float): + The average heart rate value in the interval. + + This field is a member of `oneof`_ ``_beats_per_minute_avg``. + beats_per_minute_max (float): + The maximum heart rate value in the interval. + + This field is a member of `oneof`_ ``_beats_per_minute_max``. + beats_per_minute_min (float): + The minimum heart rate value in the interval. + + This field is a member of `oneof`_ ``_beats_per_minute_min``. + """ + + beats_per_minute_avg: float = proto.Field( + proto.DOUBLE, + number=1, + optional=True, + ) + beats_per_minute_max: float = proto.Field( + proto.DOUBLE, + number=2, + optional=True, + ) + beats_per_minute_min: float = proto.Field( + proto.DOUBLE, + number=3, + optional=True, + ) + + +class RunVO2MaxRollupValue(proto.Message): + r"""Represents the result of the rollup of the user's daily heart + rate variability personal range. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + rate_min (float): + Minimum value of run VO2 max in the + interval.. + + This field is a member of `oneof`_ ``_rate_min``. + rate_max (float): + Maximum value of run VO2 max in the interval. + + This field is a member of `oneof`_ ``_rate_max``. + rate_avg (float): + Average value of run VO2 max in the interval. + + This field is a member of `oneof`_ ``_rate_avg``. + """ + + rate_min: float = proto.Field( + proto.DOUBLE, + number=1, + optional=True, + ) + rate_max: float = proto.Field( + proto.DOUBLE, + number=2, + optional=True, + ) + rate_avg: float = proto.Field( + proto.DOUBLE, + number=3, + optional=True, + ) + + +class RunVO2Max(proto.Message): + r"""VO2 max value calculated based on the user's running + activity. Value stored in ml/kg/min. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + sample_time (google.devicesandservices.health_v4.types.ObservationSampleTime): + Required. The time at which the metric was + measured. + run_vo2_max (float): + Required. Run VO2 max value in ml/kg/min. + + This field is a member of `oneof`_ ``_run_vo2_max``. + """ + + sample_time: data_coordinates.ObservationSampleTime = proto.Field( + proto.MESSAGE, + number=1, + message=data_coordinates.ObservationSampleTime, + ) + run_vo2_max: float = proto.Field( + proto.DOUBLE, + number=2, + optional=True, + ) + + +class HeartRateVariabilityPersonalRangeRollupValue(proto.Message): + r"""Represents the result of the rollup of the user's daily heart + rate variability personal range. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + average_heart_rate_variability_milliseconds_min (float): + The lower bound of the user's average heart + rate variability personal range. + + This field is a member of `oneof`_ ``_average_heart_rate_variability_milliseconds_min``. + average_heart_rate_variability_milliseconds_max (float): + The upper bound of the user's average heart + rate variability personal range. + + This field is a member of `oneof`_ ``_average_heart_rate_variability_milliseconds_max``. + """ + + average_heart_rate_variability_milliseconds_min: float = proto.Field( + proto.DOUBLE, + number=1, + optional=True, + ) + average_heart_rate_variability_milliseconds_max: float = proto.Field( + proto.DOUBLE, + number=2, + optional=True, + ) + + +class Height(proto.Message): + r"""Body height measurement. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + sample_time (google.devicesandservices.health_v4.types.ObservationSampleTime): + Required. The time at which the height was + recorded. + height_millimeters (int): + Required. Height of the user in millimeters. + + This field is a member of `oneof`_ ``_height_millimeters``. + """ + + sample_time: data_coordinates.ObservationSampleTime = proto.Field( + proto.MESSAGE, + number=1, + message=data_coordinates.ObservationSampleTime, + ) + height_millimeters: int = proto.Field( + proto.INT64, + number=2, + optional=True, + ) + + +class HeartRateVariability(proto.Message): + r"""Captures user's heart rate variability (HRV) as measured by + the root mean square of successive differences (RMSSD) between + normal heartbeats or by standard deviation of the inter-beat + intervals (SDNN). + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + sample_time (google.devicesandservices.health_v4.types.ObservationSampleTime): + Required. The time of the heart rate + variability measurement. + root_mean_square_of_successive_differences_milliseconds (float): + Optional. The root mean square of successive + differences between normal heartbeats. This is a + measure of heart rate variability used by Google + Health. + + This field is a member of `oneof`_ ``_root_mean_square_of_successive_differences_milliseconds``. + standard_deviation_milliseconds (float): + Optional. The standard deviation of the heart + rate variability measurement. + + This field is a member of `oneof`_ ``_standard_deviation_milliseconds``. + """ + + sample_time: data_coordinates.ObservationSampleTime = proto.Field( + proto.MESSAGE, + number=1, + message=data_coordinates.ObservationSampleTime, + ) + root_mean_square_of_successive_differences_milliseconds: float = proto.Field( + proto.DOUBLE, + number=2, + optional=True, + ) + standard_deviation_milliseconds: float = proto.Field( + proto.DOUBLE, + number=3, + optional=True, + ) + + +class VolumeQuantity(proto.Message): + r"""Represents the volume quantity. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + milliliters (float): + Required. Value representing the volume in + milliliters. + + This field is a member of `oneof`_ ``_milliliters``. + user_provided_unit (google.devicesandservices.health_v4.types.VolumeUnit): + Optional. Value representing the user + provided unit, used only for user-facing input + and display purposes. In the API format, all + volume quantities are converted to milliliters. + """ + + milliliters: float = proto.Field( + proto.DOUBLE, + number=1, + optional=True, + ) + user_provided_unit: "VolumeUnit" = proto.Field( + proto.ENUM, + number=2, + enum="VolumeUnit", + ) + + +class HydrationLog(proto.Message): + r"""Holds information about a user logged hydration. + + Attributes: + interval (google.devicesandservices.health_v4.types.SessionTimeInterval): + Required. Observed interval. + amount_consumed (google.devicesandservices.health_v4.types.VolumeQuantity): + Required. Amount of liquid (ex. water) + consumed. + """ + + interval: data_coordinates.SessionTimeInterval = proto.Field( + proto.MESSAGE, + number=1, + message=data_coordinates.SessionTimeInterval, + ) + amount_consumed: "VolumeQuantity" = proto.Field( + proto.MESSAGE, + number=2, + message="VolumeQuantity", + ) + + +class HydrationLogRollupValue(proto.Message): + r"""Represents the result of the rollup of the hydration log data + type. + + Attributes: + amount_consumed (google.devicesandservices.health_v4.types.HydrationLogRollupValue.VolumeQuantityRollup): + Rollup for amount consumed. + """ + + class VolumeQuantityRollup(proto.Message): + r"""Rollup for volume quantity. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + milliliters_sum (float): + Required. The sum of volume in milliliters. + + This field is a member of `oneof`_ ``_milliliters_sum``. + user_provided_unit_last (google.devicesandservices.health_v4.types.VolumeUnit): + Optional. The user provided unit on the last + element. + """ + + milliliters_sum: float = proto.Field( + proto.DOUBLE, + number=1, + optional=True, + ) + user_provided_unit_last: "VolumeUnit" = proto.Field( + proto.ENUM, + number=2, + enum="VolumeUnit", + ) + + amount_consumed: VolumeQuantityRollup = proto.Field( + proto.MESSAGE, + number=1, + message=VolumeQuantityRollup, + ) + + +class IrregularRhythmNotification(proto.Message): + r"""Represents an Irregular Rhythm Notification alert, indicating + a potential sign of atrial fibrillation (AFib). + This data type is based on SaMD feature and any changes to it + may require additional review. + + Attributes: + interval (google.devicesandservices.health_v4.types.SessionTimeInterval): + Required. Observed interval. + alert_windows (MutableSequence[google.devicesandservices.health_v4.types.IrregularRhythmNotification.AlertWindow]): + Optional. The overlapping analysis windows + that were used to evaluate rhythm for potential + AFib, containing specific information about the + user's heart rhythm. + medical_device_info (google.devicesandservices.health_v4.types.MedicalDeviceInfo): + Output only. The meta information for the compatible device + used to conduct the measurement. + + Irregular Rhythm Notification measurements typically + populate ``algorithm_version``, ``service_version``, and + ``device_model``. + """ + + class HeartBeat(proto.Message): + r"""A single heart beat measurement. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + physical_time (google.protobuf.timestamp_pb2.Timestamp): + Required. The time of the heart beat + measurement. + utc_offset (google.protobuf.duration_pb2.Duration): + Required. The UTC offset of the user's + timezone when the heart beat measurement + occurred. + civil_time (google.devicesandservices.health_v4.types.CivilDateTime): + Output only. The civil time in the timezone + the subject is in at the time of the + observation. + beats_per_minute (int): + Required. The beats-per-minute value + extrapolated from the time before the following + heart beat. This is calculated as 60000 / rr, + where rr is the gap between heart beats in + milliseconds (IBI - Interbeat Interval). + + This field is a member of `oneof`_ ``_beats_per_minute``. + """ + + physical_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + utc_offset: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=2, + message=duration_pb2.Duration, + ) + civil_time: data_coordinates.CivilDateTime = proto.Field( + proto.MESSAGE, + number=3, + message=data_coordinates.CivilDateTime, + ) + beats_per_minute: int = proto.Field( + proto.INT32, + number=4, + optional=True, + ) + + class AlertWindow(proto.Message): + r"""An analysis window evaluated for AFib. + + Note: The current version of the algorithm will only produce + alerts if all windows are positive. So anything returned from + the API will always have the positive bit set to true. + Internally, windows can be negative, however. We never save + "inconclusive" windows (they aren't produced by the algorithm). + + Attributes: + start_time (google.protobuf.timestamp_pb2.Timestamp): + Required. Observed interval. + The start time of the analysis window. + start_utc_offset (google.protobuf.duration_pb2.Duration): + Required. The UTC offset of the user's + timezone when the analysis window started. + end_time (google.protobuf.timestamp_pb2.Timestamp): + Required. The end time of the analysis + window. + end_utc_offset (google.protobuf.duration_pb2.Duration): + Required. The UTC offset of the user's + timezone when the analysis window ended. + civil_start_time (google.devicesandservices.health_v4.types.CivilDateTime): + Output only. Observed interval start time in + civil time in the timezone the subject is in at + the start of the observed interval + civil_end_time (google.devicesandservices.health_v4.types.CivilDateTime): + Output only. Observed interval end time in + civil time in the timezone the subject is in at + the end of the observed interval + positive (bool): + Optional. Flag indicating whether the window was positive + for AFib or not. A ``true`` value indicates that AFib was + detected in this window. A ``false`` value means AFib was + not detected, but does not guarantee the absence of AFib. + heart_beats (MutableSequence[google.devicesandservices.health_v4.types.IrregularRhythmNotification.HeartBeat]): + Optional. All heart beats in the interval + contained in this analysis window. + """ + + start_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + start_utc_offset: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=2, + message=duration_pb2.Duration, + ) + end_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + end_utc_offset: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=4, + message=duration_pb2.Duration, + ) + civil_start_time: data_coordinates.CivilDateTime = proto.Field( + proto.MESSAGE, + number=5, + message=data_coordinates.CivilDateTime, + ) + civil_end_time: data_coordinates.CivilDateTime = proto.Field( + proto.MESSAGE, + number=6, + message=data_coordinates.CivilDateTime, + ) + positive: bool = proto.Field( + proto.BOOL, + number=7, + ) + heart_beats: MutableSequence["IrregularRhythmNotification.HeartBeat"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=8, + message="IrregularRhythmNotification.HeartBeat", + ) + ) + + interval: data_coordinates.SessionTimeInterval = proto.Field( + proto.MESSAGE, + number=1, + message=data_coordinates.SessionTimeInterval, + ) + alert_windows: MutableSequence[AlertWindow] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message=AlertWindow, + ) + medical_device_info: gdh_medical_device_info.MedicalDeviceInfo = proto.Field( + proto.MESSAGE, + number=6, + message=gdh_medical_device_info.MedicalDeviceInfo, + ) + + +class MetricsSummary(proto.Message): + r"""Summary metrics for an exercise. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + calories_kcal (float): + Optional. Total calories burned by the user + during the exercise. + + This field is a member of `oneof`_ ``_calories_kcal``. + distance_millimeters (float): + Optional. Total distance covered by the user + during the exercise. + + This field is a member of `oneof`_ ``_distance_millimeters``. + steps (int): + Optional. Total steps taken during the + exercise. + + This field is a member of `oneof`_ ``_steps``. + average_speed_millimeters_per_second (float): + Optional. Average speed in millimeters per + second. + + This field is a member of `oneof`_ ``_average_speed_millimeters_per_second``. + average_pace_seconds_per_meter (float): + Optional. Average pace in seconds per meter. + + This field is a member of `oneof`_ ``_average_pace_seconds_per_meter``. + average_heart_rate_beats_per_minute (int): + Optional. Average heart rate during the + exercise. + + This field is a member of `oneof`_ ``_average_heart_rate_beats_per_minute``. + elevation_gain_millimeters (float): + Optional. Total elevation gain during the + exercise. + + This field is a member of `oneof`_ ``_elevation_gain_millimeters``. + active_zone_minutes (int): + Optional. Total active zone minutes for the + exercise. + + This field is a member of `oneof`_ ``_active_zone_minutes``. + run_vo2_max (float): + Optional. Run VO2 max value for the exercise. + Only present in the running exercises at the top + level as in the summary of the whole exercise. + + This field is a member of `oneof`_ ``_run_vo2_max``. + total_swim_lengths (float): + Optional. Number of full pool lengths + completed during the exercise. Only present in + the swimming exercises at the top level as in + the summary of the whole exercise. + + This field is a member of `oneof`_ ``_total_swim_lengths``. + heart_rate_zone_durations (google.devicesandservices.health_v4.types.MetricsSummary.TimeInHeartRateZones): + Optional. Time spent in each heart rate zone. + mobility_metrics (google.devicesandservices.health_v4.types.MetricsSummary.MobilityMetrics): + Optional. Mobility workouts specific metrics. + Only present in the advanced running exercises. + """ + + class TimeInHeartRateZones(proto.Message): + r"""Time spent in each heart rate zone. + + Attributes: + light_time (google.protobuf.duration_pb2.Duration): + Optional. Time spent in light heart rate + zone. + moderate_time (google.protobuf.duration_pb2.Duration): + Optional. Time spent in moderate heart rate + zone. + vigorous_time (google.protobuf.duration_pb2.Duration): + Optional. Time spent in vigorous heart rate + zone. + peak_time (google.protobuf.duration_pb2.Duration): + Optional. Time spent in peak heart rate zone. + """ + + light_time: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=1, + message=duration_pb2.Duration, + ) + moderate_time: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=2, + message=duration_pb2.Duration, + ) + vigorous_time: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=3, + message=duration_pb2.Duration, + ) + peak_time: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=4, + message=duration_pb2.Duration, + ) + + class MobilityMetrics(proto.Message): + r"""Mobility workouts specific metrics + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + avg_cadence_steps_per_minute (float): + Optional. Cadence is a measure of the + frequency of your foot strikes. Steps / min in + real time during workout. + + This field is a member of `oneof`_ ``_avg_cadence_steps_per_minute``. + avg_stride_length_millimeters (int): + Optional. Stride length is a measure of the + distance covered by a single stride + + This field is a member of `oneof`_ ``_avg_stride_length_millimeters``. + avg_vertical_oscillation_millimeters (int): + Optional. Distance off the ground your center + of mass moves with each stride while running + + This field is a member of `oneof`_ ``_avg_vertical_oscillation_millimeters``. + avg_vertical_ratio (float): + Optional. Vertical oscillation/stride length between [5.0, + 11.0]. + + This field is a member of `oneof`_ ``_avg_vertical_ratio``. + avg_ground_contact_time_duration (google.protobuf.duration_pb2.Duration): + Optional. The ground contact time for a + particular stride is the amount of time for + which the foot was in contact with the ground on + that stride + """ + + avg_cadence_steps_per_minute: float = proto.Field( + proto.DOUBLE, + number=1, + optional=True, + ) + avg_stride_length_millimeters: int = proto.Field( + proto.INT64, + number=2, + optional=True, + ) + avg_vertical_oscillation_millimeters: int = proto.Field( + proto.INT64, + number=3, + optional=True, + ) + avg_vertical_ratio: float = proto.Field( + proto.DOUBLE, + number=4, + optional=True, + ) + avg_ground_contact_time_duration: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=5, + message=duration_pb2.Duration, + ) + + calories_kcal: float = proto.Field( + proto.DOUBLE, + number=1, + optional=True, + ) + distance_millimeters: float = proto.Field( + proto.DOUBLE, + number=2, + optional=True, + ) + steps: int = proto.Field( + proto.INT64, + number=3, + optional=True, + ) + average_speed_millimeters_per_second: float = proto.Field( + proto.DOUBLE, + number=4, + optional=True, + ) + average_pace_seconds_per_meter: float = proto.Field( + proto.DOUBLE, + number=5, + optional=True, + ) + average_heart_rate_beats_per_minute: int = proto.Field( + proto.INT64, + number=6, + optional=True, + ) + elevation_gain_millimeters: float = proto.Field( + proto.DOUBLE, + number=7, + optional=True, + ) + active_zone_minutes: int = proto.Field( + proto.INT64, + number=9, + optional=True, + ) + run_vo2_max: float = proto.Field( + proto.DOUBLE, + number=10, + optional=True, + ) + total_swim_lengths: float = proto.Field( + proto.DOUBLE, + number=11, + optional=True, + ) + heart_rate_zone_durations: TimeInHeartRateZones = proto.Field( + proto.MESSAGE, + number=12, + message=TimeInHeartRateZones, + ) + mobility_metrics: MobilityMetrics = proto.Field( + proto.MESSAGE, + number=13, + message=MobilityMetrics, + ) + + +class WeightQuantity(proto.Message): + r"""Represents the weight quantity. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + grams (float): + Required. Value representing the weight in + grams. + + This field is a member of `oneof`_ ``_grams``. + user_provided_unit (google.devicesandservices.health_v4.types.WeightUnit): + Optional. Value representing the user + provided unit. + """ + + grams: float = proto.Field( + proto.DOUBLE, + number=1, + optional=True, + ) + user_provided_unit: "WeightUnit" = proto.Field( + proto.ENUM, + number=2, + enum="WeightUnit", + ) + + +class EnergyQuantity(proto.Message): + r"""Represents the energy quantity. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + kcal (float): + Required. Value representing the energy in + kilocalories. + + This field is a member of `oneof`_ ``_kcal``. + user_provided_unit (google.devicesandservices.health_v4.types.EnergyUnit): + Optional. Value representing the user + provided unit. + """ + + kcal: float = proto.Field( + proto.DOUBLE, + number=1, + optional=True, + ) + user_provided_unit: "EnergyUnit" = proto.Field( + proto.ENUM, + number=2, + enum="EnergyUnit", + ) + + +class NutrientQuantity(proto.Message): + r"""Represents the quantity of a nutrient. + + Attributes: + quantity (google.devicesandservices.health_v4.types.WeightQuantity): + Required. Value representing the quantity of + the nutrient. + nutrient (google.devicesandservices.health_v4.types.Nutrient): + Required. Value representing the nutrient. + """ + + quantity: "WeightQuantity" = proto.Field( + proto.MESSAGE, + number=1, + message="WeightQuantity", + ) + nutrient: "Nutrient" = proto.Field( + proto.ENUM, + number=2, + enum="Nutrient", + ) + + +class NutritionLog(proto.Message): + r"""Holds information about a user logged food. + + There are two ways of creating a nutrition log based on the food + type: + + 1. Identified food: Using the food field, which is a reference to a + Food resource. In this case fields ``nutrients``, ``energy``, + ``energy_from_fat``, ``total_carbohydrate``, ``total_fat``, + ``food_display_name`` will be populated based on the referenced + food. + 2. Anonymous food: Using the ``food_display_name`` field and setting + the ``nutrients``, ``energy``, ``energy_from_fat``, + ``total_carbohydrate``, ``total_fat`` fields manually. + + The identified food is preferred over the anonymous food. Nutrition + logs created from anonymous food are not be editable. + + Attributes: + interval (google.devicesandservices.health_v4.types.SessionTimeInterval): + Required. Observed interval. + nutrients (MutableSequence[google.devicesandservices.health_v4.types.NutrientQuantity]): + Optional. Value representing the nutrients of + the nutrition log. + energy (google.devicesandservices.health_v4.types.EnergyQuantity): + Optional. Value representing the energy of + the nutrition log. For nutrition logs created + from an identified food, this field will be + populated based on the referenced food. For + anonymous food, this field will be populated + manually. + energy_from_fat (google.devicesandservices.health_v4.types.EnergyQuantity): + Optional. Value representing the energy from + fat of the nutrition log. For nutrition logs + created from an identified food, this field will + be populated based on the referenced food. For + anonymous food, this field will be populated + manually. + total_carbohydrate (google.devicesandservices.health_v4.types.WeightQuantity): + Optional. Value representing the total + carbohydrate of the nutrition log. For nutrition + logs created from an identified food, this field + will be populated based on the referenced food. + For anonymous food, this field will be populated + manually. + total_fat (google.devicesandservices.health_v4.types.WeightQuantity): + Optional. Value representing the total fat of + the nutrition log. For nutrition logs created + from an identified food, this field will be + populated based on the referenced food. For + anonymous food, this field will be populated + manually. + meal_type (google.devicesandservices.health_v4.types.MealType): + Optional. Value representing the meal type of + the nutrition log. + serving (google.devicesandservices.health_v4.types.NutritionLog.Serving): + Optional. Value representing the nutrition + log serving. + food (str): + Required. Represents the food ID. + food_display_name (str): + Value representing the display name of the + food. For nutrition logs created from an + identified food, this field will be populated + based on the referenced food. For anonymous + food, this field will be populated manually. + """ + + class Serving(proto.Message): + r"""Represents different properties and information about the + serving of a specific food. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + amount (float): + Optional. Amount of food consumed, fractional + values are supported. + + This field is a member of `oneof`_ ``_amount``. + food_measurement_unit (str): + Required. Food measurement unit + food_measurement_unit_display_name (str): + Output only. Legacy measurement unit for + serving size in singular form (e.g. "piece", + "gram"). + """ + + amount: float = proto.Field( + proto.DOUBLE, + number=1, + optional=True, + ) + food_measurement_unit: str = proto.Field( + proto.STRING, + number=2, + ) + food_measurement_unit_display_name: str = proto.Field( + proto.STRING, + number=3, + ) + + interval: data_coordinates.SessionTimeInterval = proto.Field( + proto.MESSAGE, + number=2, + message=data_coordinates.SessionTimeInterval, + ) + nutrients: MutableSequence["NutrientQuantity"] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message="NutrientQuantity", + ) + energy: "EnergyQuantity" = proto.Field( + proto.MESSAGE, + number=4, + message="EnergyQuantity", + ) + energy_from_fat: "EnergyQuantity" = proto.Field( + proto.MESSAGE, + number=5, + message="EnergyQuantity", + ) + total_carbohydrate: "WeightQuantity" = proto.Field( + proto.MESSAGE, + number=7, + message="WeightQuantity", + ) + total_fat: "WeightQuantity" = proto.Field( + proto.MESSAGE, + number=8, + message="WeightQuantity", + ) + meal_type: "MealType" = proto.Field( + proto.ENUM, + number=13, + enum="MealType", + ) + serving: Serving = proto.Field( + proto.MESSAGE, + number=14, + message=Serving, + ) + food: str = proto.Field( + proto.STRING, + number=15, + ) + food_display_name: str = proto.Field( + proto.STRING, + number=16, + ) + + +class Food(proto.Message): + r"""Represents a food item. + + Attributes: + display_name (str): + Required. The display name of the food. + brand (str): + Optional. The brand of the food. + access_level (google.devicesandservices.health_v4.types.FoodAccessLevel): + Required. The access level of the food. + description (str): + Optional. The description of the food. + language_code (str): + Optional. The language code where the food is available in + format xx-XX. Supported values are defined in + [Settings.food_language_code][google.devicesandservices.health.v4.Settings.food_language_code]. + meal_type (google.devicesandservices.health_v4.types.MealType): + Optional. The meal type associated with this + food. + nutrients (MutableSequence[google.devicesandservices.health_v4.types.NutrientQuantity]): + Optional. Value representing the nutrients of + the food for the default serving. + energy_from_fat (google.devicesandservices.health_v4.types.EnergyQuantity): + Optional. Value representing the energy from + fat of the food for the default serving. + total_carbohydrate (google.devicesandservices.health_v4.types.WeightQuantity): + Optional. Value representing the total + carbohydrate of the food for the default + serving. + total_fat (google.devicesandservices.health_v4.types.WeightQuantity): + Optional. Value representing the total fat of + the food for the default serving. + energy_min (google.devicesandservices.health_v4.types.EnergyQuantity): + Optional. Value representing the minimum + energy of the food for the default serving. + energy_avg (google.devicesandservices.health_v4.types.EnergyQuantity): + Optional. Value representing the average + energy of the food for the default serving. + energy_max (google.devicesandservices.health_v4.types.EnergyQuantity): + Optional. Value representing the maximum + energy of the food for the default serving. + default_serving (google.devicesandservices.health_v4.types.Food.FoodServing): + Required. Value representing the default + serving of the food. + servings (MutableSequence[google.devicesandservices.health_v4.types.Food.FoodServing]): + Optional. The serving of the food. + """ + + class FoodServing(proto.Message): + r"""Represents different properties and information about the + serving of a specific food. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + amount (float): + Optional. Amount of food consumed, fractional + values are supported. + + This field is a member of `oneof`_ ``_amount``. + food_measurement_unit (str): + Required. Food measurement unit + food_measurement_unit_display_name (str): + Output only. Legacy measurement unit for + serving size in singular form (e.g. "piece", + "gram"). + food_measurement_unit_display_name_plural (str): + Output only. Legacy measurement unit for + serving size in plural form (e.g. "pieces", + "grams"). + multiplier (float): + Optional. Value representing the multiplier + used to compute the energy when using this + serving instead of the default serving. + """ + + amount: float = proto.Field( + proto.DOUBLE, + number=1, + optional=True, + ) + food_measurement_unit: str = proto.Field( + proto.STRING, + number=2, + ) + food_measurement_unit_display_name: str = proto.Field( + proto.STRING, + number=3, + ) + food_measurement_unit_display_name_plural: str = proto.Field( + proto.STRING, + number=4, + ) + multiplier: float = proto.Field( + proto.DOUBLE, + number=5, + ) + + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + brand: str = proto.Field( + proto.STRING, + number=3, + ) + access_level: "FoodAccessLevel" = proto.Field( + proto.ENUM, + number=4, + enum="FoodAccessLevel", + ) + description: str = proto.Field( + proto.STRING, + number=5, + ) + language_code: str = proto.Field( + proto.STRING, + number=6, + ) + meal_type: "MealType" = proto.Field( + proto.ENUM, + number=10, + enum="MealType", + ) + nutrients: MutableSequence["NutrientQuantity"] = proto.RepeatedField( + proto.MESSAGE, + number=12, + message="NutrientQuantity", + ) + energy_from_fat: "EnergyQuantity" = proto.Field( + proto.MESSAGE, + number=13, + message="EnergyQuantity", + ) + total_carbohydrate: "WeightQuantity" = proto.Field( + proto.MESSAGE, + number=14, + message="WeightQuantity", + ) + total_fat: "WeightQuantity" = proto.Field( + proto.MESSAGE, + number=15, + message="WeightQuantity", + ) + energy_min: "EnergyQuantity" = proto.Field( + proto.MESSAGE, + number=16, + message="EnergyQuantity", + ) + energy_avg: "EnergyQuantity" = proto.Field( + proto.MESSAGE, + number=17, + message="EnergyQuantity", + ) + energy_max: "EnergyQuantity" = proto.Field( + proto.MESSAGE, + number=18, + message="EnergyQuantity", + ) + default_serving: FoodServing = proto.Field( + proto.MESSAGE, + number=19, + message=FoodServing, + ) + servings: MutableSequence[FoodServing] = proto.RepeatedField( + proto.MESSAGE, + number=20, + message=FoodServing, + ) + + +class NutritionLogRollupValue(proto.Message): + r"""Represents the result of the rollup of the nutrition log data + type. + + Attributes: + nutrients (MutableSequence[google.devicesandservices.health_v4.types.NutritionLogRollupValue.NutrientQuantityRollup]): + List of the nutrient roll-ups by the nutrient + type. + energy (google.devicesandservices.health_v4.types.NutritionLogRollupValue.EnergyQuantityRollup): + Energy rollup. + energy_from_fat (google.devicesandservices.health_v4.types.NutritionLogRollupValue.EnergyQuantityRollup): + Value + Energy from fat rollup. + total_carbohydrate (google.devicesandservices.health_v4.types.NutritionLogRollupValue.WeightQuantityRollup): + Total carbohydrate rollup. + total_fat (google.devicesandservices.health_v4.types.NutritionLogRollupValue.WeightQuantityRollup): + Total fat rollup. + """ + + class WeightQuantityRollup(proto.Message): + r"""Rollup for the weight. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + grams_sum (float): + Required. The sum of the weight in grams. + + This field is a member of `oneof`_ ``_grams_sum``. + user_provided_unit_last (google.devicesandservices.health_v4.types.WeightUnit): + Optional. The user provided unit on the last + element. + """ + + grams_sum: float = proto.Field( + proto.DOUBLE, + number=1, + optional=True, + ) + user_provided_unit_last: "WeightUnit" = proto.Field( + proto.ENUM, + number=2, + enum="WeightUnit", + ) + + class EnergyQuantityRollup(proto.Message): + r"""Rollup for the energy quantity. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + kcal_sum (float): + Required. The sum of the energy in + kilocalories. + + This field is a member of `oneof`_ ``_kcal_sum``. + user_provided_unit_last (google.devicesandservices.health_v4.types.EnergyUnit): + Optional. The user provided unit on the last + element. + """ + + kcal_sum: float = proto.Field( + proto.DOUBLE, + number=1, + optional=True, + ) + user_provided_unit_last: "EnergyUnit" = proto.Field( + proto.ENUM, + number=2, + enum="EnergyUnit", + ) + + class NutrientQuantityRollup(proto.Message): + r"""Nutrient quantity rollup. + + Attributes: + quantity (google.devicesandservices.health_v4.types.NutritionLogRollupValue.WeightQuantityRollup): + Required. Aggregated nutrient weight. + nutrient (google.devicesandservices.health_v4.types.Nutrient): + Required. Aggregated nutrient. + """ + + quantity: "NutritionLogRollupValue.WeightQuantityRollup" = proto.Field( + proto.MESSAGE, + number=1, + message="NutritionLogRollupValue.WeightQuantityRollup", + ) + nutrient: "Nutrient" = proto.Field( + proto.ENUM, + number=2, + enum="Nutrient", + ) + + nutrients: MutableSequence[NutrientQuantityRollup] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=NutrientQuantityRollup, + ) + energy: EnergyQuantityRollup = proto.Field( + proto.MESSAGE, + number=2, + message=EnergyQuantityRollup, + ) + energy_from_fat: EnergyQuantityRollup = proto.Field( + proto.MESSAGE, + number=3, + message=EnergyQuantityRollup, + ) + total_carbohydrate: WeightQuantityRollup = proto.Field( + proto.MESSAGE, + number=4, + message=WeightQuantityRollup, + ) + total_fat: WeightQuantityRollup = proto.Field( + proto.MESSAGE, + number=5, + message=WeightQuantityRollup, + ) + + +class OxygenSaturation(proto.Message): + r"""Captures the user's instantaneous oxygen saturation + percentage (SpO2). + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + sample_time (google.devicesandservices.health_v4.types.ObservationSampleTime): + Required. The time at which oxygen saturation + was measured. + percentage (float): + Required. The oxygen saturation percentage. + Valid values are from 0 to 100. + + This field is a member of `oneof`_ ``_percentage``. + """ + + sample_time: data_coordinates.ObservationSampleTime = proto.Field( + proto.MESSAGE, + number=1, + message=data_coordinates.ObservationSampleTime, + ) + percentage: float = proto.Field( + proto.DOUBLE, + number=2, + optional=True, + ) + + +class RestingHeartRatePersonalRangeRollupValue(proto.Message): + r"""Represents the rollup value for the daily resting heart rate + data type. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + beats_per_minute_min (float): + The lower bound of the user's daily resting + heart rate personal range. + + This field is a member of `oneof`_ ``_beats_per_minute_min``. + beats_per_minute_max (float): + The upper bound of the user's daily resting + heart rate personal range. + + This field is a member of `oneof`_ ``_beats_per_minute_max``. + """ + + beats_per_minute_min: float = proto.Field( + proto.DOUBLE, + number=1, + optional=True, + ) + beats_per_minute_max: float = proto.Field( + proto.DOUBLE, + number=2, + optional=True, + ) + + +class FoodMeasurementUnit(proto.Message): + r"""Represents a food measurement unit. + + Attributes: + display_name (str): + Required. The display name of the food + measurement unit (e.g., "gram", "piece"). + plural_display_name (str): + Optional. The plural display name of the food + measurement unit (e.g., "grams", "pieces"). + """ + + display_name: str = proto.Field( + proto.STRING, + number=1, + ) + plural_display_name: str = proto.Field( + proto.STRING, + number=2, + ) + + +class RespiratoryRateSleepSummary(proto.Message): + r"""Records respiratory rate details during sleep. + Can have multiple per day if the user sleeps multiple times. + + Attributes: + sample_time (google.devicesandservices.health_v4.types.ObservationSampleTime): + Required. The time at which respiratory rate + was measured. + deep_sleep_stats (google.devicesandservices.health_v4.types.RespiratoryRateSleepSummary.RespiratoryRateSleepSummaryStatistics): + Optional. Respiratory rate statistics for + deep sleep. + light_sleep_stats (google.devicesandservices.health_v4.types.RespiratoryRateSleepSummary.RespiratoryRateSleepSummaryStatistics): + Optional. Respiratory rate statistics for + light sleep. + rem_sleep_stats (google.devicesandservices.health_v4.types.RespiratoryRateSleepSummary.RespiratoryRateSleepSummaryStatistics): + Optional. Respiratory rate statistics for REM + sleep. + full_sleep_stats (google.devicesandservices.health_v4.types.RespiratoryRateSleepSummary.RespiratoryRateSleepSummaryStatistics): + Required. Full respiratory rate statistics. + """ + + class RespiratoryRateSleepSummaryStatistics(proto.Message): + r"""Respiratory rate statistics for a given sleep stage. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + breaths_per_minute (float): + Required. Average breaths per minute. + + This field is a member of `oneof`_ ``_breaths_per_minute``. + standard_deviation (float): + Optional. Standard deviation of the + respiratory rate during sleep. + + This field is a member of `oneof`_ ``_standard_deviation``. + signal_to_noise (float): + Optional. How trustworthy the data is for the + computation. + + This field is a member of `oneof`_ ``_signal_to_noise``. + """ + + breaths_per_minute: float = proto.Field( + proto.DOUBLE, + number=1, + optional=True, + ) + standard_deviation: float = proto.Field( + proto.DOUBLE, + number=2, + optional=True, + ) + signal_to_noise: float = proto.Field( + proto.DOUBLE, + number=3, + optional=True, + ) + + sample_time: data_coordinates.ObservationSampleTime = proto.Field( + proto.MESSAGE, + number=1, + message=data_coordinates.ObservationSampleTime, + ) + deep_sleep_stats: RespiratoryRateSleepSummaryStatistics = proto.Field( + proto.MESSAGE, + number=2, + message=RespiratoryRateSleepSummaryStatistics, + ) + light_sleep_stats: RespiratoryRateSleepSummaryStatistics = proto.Field( + proto.MESSAGE, + number=3, + message=RespiratoryRateSleepSummaryStatistics, + ) + rem_sleep_stats: RespiratoryRateSleepSummaryStatistics = proto.Field( + proto.MESSAGE, + number=4, + message=RespiratoryRateSleepSummaryStatistics, + ) + full_sleep_stats: RespiratoryRateSleepSummaryStatistics = proto.Field( + proto.MESSAGE, + number=5, + message=RespiratoryRateSleepSummaryStatistics, + ) + + +class Sleep(proto.Message): + r"""A sleep session possibly including stages. + + Attributes: + interval (google.devicesandservices.health_v4.types.SessionTimeInterval): + Required. Observed sleep interval. + type_ (google.devicesandservices.health_v4.types.Sleep.SleepType): + Optional. SleepType: classic or stages. + stages (MutableSequence[google.devicesandservices.health_v4.types.Sleep.SleepStage]): + Optional. List of non-overlapping contiguous + sleep stage segments that cover the sleep + period. + out_of_bed_segments (MutableSequence[google.devicesandservices.health_v4.types.Sleep.OutOfBedSegment]): + Optional. + “Out of bed” segments that can overlap with + sleep stages. + metadata (google.devicesandservices.health_v4.types.Sleep.SleepMetadata): + Optional. Sleep metadata: processing, main, + manually edited, stages status. + summary (google.devicesandservices.health_v4.types.Sleep.SleepSummary): + Output only. Sleep summary: metrics and + stages summary. + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Creation time of this sleep + observation. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Last update time of this sleep + observation. + """ + + class SleepType(proto.Enum): + r"""Sleep type: classic or stages. + + Values: + SLEEP_TYPE_UNSPECIFIED (0): + Sleep type is unspecified. + CLASSIC (1): + Classic sleep is a sleep with 3 stages types: + AWAKE, RESTLESS and ASLEEP. + STAGES (2): + On top of "classic" sleep stages an + additional processing pass can calculate stages + more precisely, overwriting the prior stages + with AWAKE, LIGHT, REM and DEEP. + """ + + SLEEP_TYPE_UNSPECIFIED = 0 + CLASSIC = 1 + STAGES = 2 + + class SleepStageType(proto.Enum): + r"""Sleep stage type: AWAKE, DEEP, REM, LIGHT etc. + + Values: + SLEEP_STAGE_TYPE_UNSPECIFIED (0): + The default unset value. + AWAKE (1): + Sleep stage AWAKE. + LIGHT (2): + Sleep stage LIGHT. + DEEP (3): + Sleep stage DEEP. + REM (4): + Sleep stage REM. + ASLEEP (5): + Sleep stage ASLEEP. + RESTLESS (6): + Sleep stage RESTLESS. + """ + + SLEEP_STAGE_TYPE_UNSPECIFIED = 0 + AWAKE = 1 + LIGHT = 2 + DEEP = 3 + REM = 4 + ASLEEP = 5 + RESTLESS = 6 + + class SleepStage(proto.Message): + r"""Sleep stage segment. + + Attributes: + start_time (google.protobuf.timestamp_pb2.Timestamp): + Required. Sleep stage start time. + start_utc_offset (google.protobuf.duration_pb2.Duration): + Required. The offset of the user's local time + at the start of the sleep stage relative to the + Coordinated Universal Time (UTC). + end_time (google.protobuf.timestamp_pb2.Timestamp): + Required. Sleep stage end time. + end_utc_offset (google.protobuf.duration_pb2.Duration): + Required. The offset of the user's local time + at the end of the sleep stage relative to the + Coordinated Universal Time (UTC). + type_ (google.devicesandservices.health_v4.types.Sleep.SleepStageType): + Required. Sleep stage type: AWAKE, DEEP, REM, + LIGHT etc. + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Creation time of this sleep + stages segment. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Last update time of this sleep + stages segment. + """ + + start_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + start_utc_offset: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=4, + message=duration_pb2.Duration, + ) + end_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + end_utc_offset: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=6, + message=duration_pb2.Duration, + ) + type_: "Sleep.SleepStageType" = proto.Field( + proto.ENUM, + number=7, + enum="Sleep.SleepStageType", + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=8, + message=timestamp_pb2.Timestamp, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=9, + message=timestamp_pb2.Timestamp, + ) + + class OutOfBedSegment(proto.Message): + r"""A time interval to represent an out-of-bed segment. + + Attributes: + start_time (google.protobuf.timestamp_pb2.Timestamp): + Required. Segment tart time. + start_utc_offset (google.protobuf.duration_pb2.Duration): + Required. The offset of the user's local time + at the start of the segment relative to the + Coordinated Universal Time (UTC). + end_time (google.protobuf.timestamp_pb2.Timestamp): + Required. Segment end time. + end_utc_offset (google.protobuf.duration_pb2.Duration): + Required. The offset of the user's local time + at the end of the segment relative to the + Coordinated Universal Time (UTC). + """ + + start_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + start_utc_offset: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=2, + message=duration_pb2.Duration, + ) + end_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + end_utc_offset: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=4, + message=duration_pb2.Duration, + ) + + class SleepMetadata(proto.Message): + r"""Additional information about how the sleep was processed. + + Attributes: + stages_status (google.devicesandservices.health_v4.types.Sleep.SleepMetadata.StagesState): + Output only. Sleep stages algorithm + processing status. + processed (bool): + Output only. Sleep and sleep stages + algorithms finished processing. + nap (bool): + Output only. Naps are sleeps without stages + and relatively short durations. + manually_edited (bool): + Output only. Some sleeps autodetected by + algorithms can be manually edited by users. + external_id (str): + Optional. Sleep identifier relevant in the + context of the data source. + """ + + class StagesState(proto.Enum): + r"""Sleep stages algorithm processing status. + + Values: + STAGES_STATE_UNSPECIFIED (0): + Output only. Sleep stages status is + unspecified. + REJECTED_COVERAGE (1): + Output only. Sleep stages cannot be computed + due to low RR coverage. + REJECTED_MAX_GAP (2): + Output only. Sleep stages cannot be computed + due to the large middle gap (2h). + REJECTED_START_GAP (3): + Output only. Sleep stages cannot be computed + due to the large start gap (1h). + REJECTED_END_GAP (4): + Output only. Sleep stages cannot be computed + due to the large end gap (1h). + REJECTED_NAP (5): + Output only. Sleep stages cannot be computed + because the sleep log is a nap (has < 3h + duration). + REJECTED_SERVER (6): + Output only. Sleep stages cannot be computed + because input data is not available (PPGV2, wake + magnitude, etc). + TIMEOUT (7): + Output only. Sleep stages cannot be computed + due to server timeout. + SUCCEEDED (8): + Output only. Sleep stages successfully + computed. + PROCESSING_INTERNAL_ERROR (9): + Output only. Sleep stages cannot be computed + due to server internal error. + """ + + STAGES_STATE_UNSPECIFIED = 0 + REJECTED_COVERAGE = 1 + REJECTED_MAX_GAP = 2 + REJECTED_START_GAP = 3 + REJECTED_END_GAP = 4 + REJECTED_NAP = 5 + REJECTED_SERVER = 6 + TIMEOUT = 7 + SUCCEEDED = 8 + PROCESSING_INTERNAL_ERROR = 9 + + stages_status: "Sleep.SleepMetadata.StagesState" = proto.Field( + proto.ENUM, + number=1, + enum="Sleep.SleepMetadata.StagesState", + ) + processed: bool = proto.Field( + proto.BOOL, + number=2, + ) + nap: bool = proto.Field( + proto.BOOL, + number=5, + ) + manually_edited: bool = proto.Field( + proto.BOOL, + number=6, + ) + external_id: str = proto.Field( + proto.STRING, + number=7, + ) + + class SleepSummary(proto.Message): + r"""Sleep summary: metrics and stages summary. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + minutes_in_sleep_period (int): + Output only. Delta between wake time and + bedtime. It is the sum of all stages. + + This field is a member of `oneof`_ ``_minutes_in_sleep_period``. + minutes_after_wake_up (int): + Output only. Minutes after wake up calculated + by restlessness algorithm. + + This field is a member of `oneof`_ ``_minutes_after_wake_up``. + minutes_to_fall_asleep (int): + Output only. Minutes to fall asleep + calculated by restlessness algorithm. + + This field is a member of `oneof`_ ``_minutes_to_fall_asleep``. + minutes_asleep (int): + Output only. Total number of minutes asleep. + For classic sleep it is the sum of ASLEEP stages + (excluding AWAKE and RESTLESS). For "stages" + sleep it is the sum of LIGHT, REM and DEEP + stages (excluding AWAKE). + + This field is a member of `oneof`_ ``_minutes_asleep``. + minutes_awake (int): + Output only. Total number of minutes awake. + It is a sum of all AWAKE stages. + + This field is a member of `oneof`_ ``_minutes_awake``. + stages_summary (MutableSequence[google.devicesandservices.health_v4.types.Sleep.SleepSummary.StageSummary]): + Output only. List of summaries (total + duration and segment count) per each sleep stage + type. + """ + + class StageSummary(proto.Message): + r"""Total duration and segment count for a stage. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + type_ (google.devicesandservices.health_v4.types.Sleep.SleepStageType): + Output only. Sleep stage type: AWAKE, DEEP, + REM, LIGHT etc. + minutes (int): + Output only. Total duration in minutes of a + sleep stage. + + This field is a member of `oneof`_ ``_minutes``. + count (int): + Output only. Number of sleep stages segments. + + This field is a member of `oneof`_ ``_count``. + """ + + type_: "Sleep.SleepStageType" = proto.Field( + proto.ENUM, + number=1, + enum="Sleep.SleepStageType", + ) + minutes: int = proto.Field( + proto.INT64, + number=2, + optional=True, + ) + count: int = proto.Field( + proto.INT64, + number=3, + optional=True, + ) + + minutes_in_sleep_period: int = proto.Field( + proto.INT64, + number=1, + optional=True, + ) + minutes_after_wake_up: int = proto.Field( + proto.INT64, + number=2, + optional=True, + ) + minutes_to_fall_asleep: int = proto.Field( + proto.INT64, + number=3, + optional=True, + ) + minutes_asleep: int = proto.Field( + proto.INT64, + number=4, + optional=True, + ) + minutes_awake: int = proto.Field( + proto.INT64, + number=5, + optional=True, + ) + stages_summary: MutableSequence["Sleep.SleepSummary.StageSummary"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=6, + message="Sleep.SleepSummary.StageSummary", + ) + ) + + interval: data_coordinates.SessionTimeInterval = proto.Field( + proto.MESSAGE, + number=3, + message=data_coordinates.SessionTimeInterval, + ) + type_: SleepType = proto.Field( + proto.ENUM, + number=4, + enum=SleepType, + ) + stages: MutableSequence[SleepStage] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message=SleepStage, + ) + out_of_bed_segments: MutableSequence[OutOfBedSegment] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message=OutOfBedSegment, + ) + metadata: SleepMetadata = proto.Field( + proto.MESSAGE, + number=8, + message=SleepMetadata, + ) + summary: SleepSummary = proto.Field( + proto.MESSAGE, + number=9, + message=SleepSummary, + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=10, + message=timestamp_pb2.Timestamp, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=11, + message=timestamp_pb2.Timestamp, + ) + + +class Steps(proto.Message): + r"""Step count over the time interval. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + interval (google.devicesandservices.health_v4.types.ObservationTimeInterval): + Required. Observed interval. + count (int): + Required. Number of steps in the recorded + interval. + + This field is a member of `oneof`_ ``_count``. + """ + + interval: data_coordinates.ObservationTimeInterval = proto.Field( + proto.MESSAGE, + number=2, + message=data_coordinates.ObservationTimeInterval, + ) + count: int = proto.Field( + proto.INT64, + number=4, + optional=True, + ) + + +class StepsRollupValue(proto.Message): + r"""Represents the result of the rollup of the steps data type. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + count_sum (int): + Total number of steps in the interval. + + This field is a member of `oneof`_ ``_count_sum``. + """ + + count_sum: int = proto.Field( + proto.INT64, + number=1, + optional=True, + ) + + +class SwimLengthsData(proto.Message): + r"""Swim lengths data over the time interval. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + interval (google.devicesandservices.health_v4.types.ObservationTimeInterval): + Required. Observed interval. + swim_stroke_type (google.devicesandservices.health_v4.types.SwimLengthsData.SwimStrokeType): + Required. Swim stroke type. + stroke_count (int): + Required. Number of strokes in the lap. + + This field is a member of `oneof`_ ``_stroke_count``. + """ + + class SwimStrokeType(proto.Enum): + r"""Swim stroke type. + + Values: + SWIM_STROKE_TYPE_UNSPECIFIED (0): + Swim stroke type is unspecified. + FREESTYLE (1): + Freestyle swim stroke type. + BACKSTROKE (2): + Backstroke swim stroke type. + BREASTSTROKE (3): + Breaststroke swim stroke type. + BUTTERFLY (4): + Butterfly swim stroke type. + """ + + SWIM_STROKE_TYPE_UNSPECIFIED = 0 + FREESTYLE = 1 + BACKSTROKE = 2 + BREASTSTROKE = 3 + BUTTERFLY = 4 + + interval: data_coordinates.ObservationTimeInterval = proto.Field( + proto.MESSAGE, + number=1, + message=data_coordinates.ObservationTimeInterval, + ) + swim_stroke_type: SwimStrokeType = proto.Field( + proto.ENUM, + number=2, + enum=SwimStrokeType, + ) + stroke_count: int = proto.Field( + proto.INT64, + number=3, + optional=True, + ) + + +class SwimLengthsDataRollupValue(proto.Message): + r"""Represents the result of the rollup of the swim lengths data + type. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + stroke_count_sum (int): + Total number of swim strokes in the interval. + + This field is a member of `oneof`_ ``_stroke_count_sum``. + """ + + stroke_count_sum: int = proto.Field( + proto.INT64, + number=1, + optional=True, + ) + + +class TimeInHeartRateZone(proto.Message): + r"""Time in heart rate zone record. It's an interval spent in + specific heart rate zone. + + Attributes: + interval (google.devicesandservices.health_v4.types.ObservationTimeInterval): + Required. Observed interval. + heart_rate_zone_type (google.devicesandservices.health_v4.types.HeartRateZoneType): + Required. Heart rate zone type. + """ + + interval: data_coordinates.ObservationTimeInterval = proto.Field( + proto.MESSAGE, + number=1, + message=data_coordinates.ObservationTimeInterval, + ) + heart_rate_zone_type: "HeartRateZoneType" = proto.Field( + proto.ENUM, + number=2, + enum="HeartRateZoneType", + ) + + +class TimeInHeartRateZoneRollupValue(proto.Message): + r"""Represents the result of the rollup of the time in heart rate + zone data type. + + Attributes: + time_in_heart_rate_zones (MutableSequence[google.devicesandservices.health_v4.types.TimeInHeartRateZoneRollupValue.TimeInHeartRateZoneValue]): + List of time spent in each heart rate zone. + """ + + class TimeInHeartRateZoneValue(proto.Message): + r"""Represents the total time spent in a specific heart rate + zone. + + Attributes: + heart_rate_zone (google.devicesandservices.health_v4.types.HeartRateZoneType): + The heart rate zone. + duration (google.protobuf.duration_pb2.Duration): + The total time spent in the specified heart + rate zone. + """ + + heart_rate_zone: "HeartRateZoneType" = proto.Field( + proto.ENUM, + number=1, + enum="HeartRateZoneType", + ) + duration: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=2, + message=duration_pb2.Duration, + ) + + time_in_heart_rate_zones: MutableSequence[TimeInHeartRateZoneValue] = ( + proto.RepeatedField( + proto.MESSAGE, + number=1, + message=TimeInHeartRateZoneValue, + ) + ) + + +class TotalCaloriesRollupValue(proto.Message): + r"""Represents the result of the rollup of the user's total + calories. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + kcal_sum (float): + Sum of the total calories in kilocalories. + + This field is a member of `oneof`_ ``_kcal_sum``. + """ + + kcal_sum: float = proto.Field( + proto.DOUBLE, + number=1, + optional=True, + ) + + +class VO2Max(proto.Message): + r"""VO2 max measurement. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + sample_time (google.devicesandservices.health_v4.types.ObservationSampleTime): + Required. The time at which VO2 max was + measured. + vo2_max (float): + Required. VO2 max value measured as in ml + consumed oxygen / kg of body weight / min. + + This field is a member of `oneof`_ ``_vo2_max``. + measurement_method (google.devicesandservices.health_v4.types.VO2Max.MeasurementMethod): + Optional. The method used to measure the VO2 + max value. + """ + + class MeasurementMethod(proto.Enum): + r"""Measurement method used to measure the VO2 max value. + + Values: + MEASUREMENT_METHOD_UNSPECIFIED (0): + Unspecified measurement method. + FITBIT_RUN (1): + Fitbit specific, measures VO2 max rate during + a run. + GOOGLE_DEMOGRAPHIC (2): + Google specific, measures VO2 max rate for a + user based on their demographic data. + COOPER_TEST (3): + Run as far as possible for 12 minutes. + Distance correlated with age and gender + translates to a VO2 max value. + HEART_RATE_RATIO (4): + Maximum heart rate divided by the resting + heart rate, with a multiplier applied. Does not + require any exercise. + METABOLIC_CART (5): + Measured by a medical device called metabolic + cart. + MULTISTAGE_FITNESS_TEST (6): + Continuous 20m back-and-forth runs with + increasing difficulty, until exhaustion. + ROCKPORT_FITNESS_TEST (7): + Measured using walking exercise. + MAX_EXERCISE (8): + Healthkit specific, measures VO2 max rate by monitoring + exercise to the user’s physical limit. Similar to + COOPER_TEST or MULTISTAGE_FITNESS_TEST. + PREDICTION_SUB_MAX_EXERCISE (9): + Healthkit specific, estimates VO2 max rate based on + low-intensity exercise. Similar to ROCKPORT_FITNESS_TEST. + PREDICTION_NON_EXERCISE (10): + Healthkit specific, estimates VO2 max rate without any + exercise. Similar to HEART_RATE_RATIO. + OTHER (11): + Use when the method is not covered in this + enum. + """ + + MEASUREMENT_METHOD_UNSPECIFIED = 0 + FITBIT_RUN = 1 + GOOGLE_DEMOGRAPHIC = 2 + COOPER_TEST = 3 + HEART_RATE_RATIO = 4 + METABOLIC_CART = 5 + MULTISTAGE_FITNESS_TEST = 6 + ROCKPORT_FITNESS_TEST = 7 + MAX_EXERCISE = 8 + PREDICTION_SUB_MAX_EXERCISE = 9 + PREDICTION_NON_EXERCISE = 10 + OTHER = 11 + + sample_time: data_coordinates.ObservationSampleTime = proto.Field( + proto.MESSAGE, + number=1, + message=data_coordinates.ObservationSampleTime, + ) + vo2_max: float = proto.Field( + proto.DOUBLE, + number=2, + optional=True, + ) + measurement_method: MeasurementMethod = proto.Field( + proto.ENUM, + number=4, + enum=MeasurementMethod, + ) + + +class Weight(proto.Message): + r"""Body weight measurement. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + sample_time (google.devicesandservices.health_v4.types.ObservationSampleTime): + Required. The time at which the weight was + measured + weight_grams (float): + Required. Weight of a user in grams. + + This field is a member of `oneof`_ ``_weight_grams``. + notes (str): + Optional. Standard free-form notes captured + at manual logging. + """ + + sample_time: data_coordinates.ObservationSampleTime = proto.Field( + proto.MESSAGE, + number=2, + message=data_coordinates.ObservationSampleTime, + ) + weight_grams: float = proto.Field( + proto.DOUBLE, + number=3, + optional=True, + ) + notes: str = proto.Field( + proto.STRING, + number=4, + ) + + +class WeightRollupValue(proto.Message): + r"""Represents the result of the rollup of the weight data type. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + weight_grams_avg (float): + Average weight in grams. + + This field is a member of `oneof`_ ``_weight_grams_avg``. + """ + + weight_grams_avg: float = proto.Field( + proto.DOUBLE, + number=1, + optional=True, + ) + + +class BloodGlucose(proto.Message): + r"""Represents a blood glucose level measurement. LINT: LEGACY_NAMES + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + sample_time (google.devicesandservices.health_v4.types.ObservationSampleTime): + Required. The time at which blood glucose was + measured. + blood_glucose_milligrams_per_deciliter (float): + Required. Blood glucose level concentration + in mg/dL. + + This field is a member of `oneof`_ ``_blood_glucose_milligrams_per_deciliter``. + measurement_source (google.devicesandservices.health_v4.types.BloodGlucose.MeasurementSource): + Optional. Source of the measurement. + meal_type (google.devicesandservices.health_v4.types.BloodGlucose.MealType): + Optional. Meal type of the measurement. + measurement_timing (google.devicesandservices.health_v4.types.BloodGlucose.MeasurementTiming): + Optional. Timing of the measurement. + specimen (google.devicesandservices.health_v4.types.BloodGlucose.Specimen): + Optional. Type of body fluid used to measure + the blood glucose. + notes (str): + Optional. Standard free-form notes captured + at manual logging. + """ + + class MeasurementSource(proto.Enum): + r"""The clinical method or tool used to measure the blood glucose + level. + + Values: + MEASUREMENT_SOURCE_UNSPECIFIED (0): + Unspecified measurement source. + SELF_MONITORING_BLOOD_GLUCOSE (1): + Self-monitoring of blood glucose (Blood + glucose meter) + CONTINUOUS_GLUCOSE_MONITORING (2): + Continuous glucose monitoring device + LAB_TEST (3): + Laboratory test + """ + + MEASUREMENT_SOURCE_UNSPECIFIED = 0 + SELF_MONITORING_BLOOD_GLUCOSE = 1 + CONTINUOUS_GLUCOSE_MONITORING = 2 + LAB_TEST = 3 + + class MealType(proto.Enum): + r"""Meal type associated with the measurement. + + Values: + MEAL_TYPE_UNSPECIFIED (0): + Unspecified meal type. + BREAKFAST (1): + Breakfast. + LUNCH (2): + Lunch. + DINNER (3): + Dinner. + SNACK (4): + Snack. + """ + + MEAL_TYPE_UNSPECIFIED = 0 + BREAKFAST = 1 + LUNCH = 2 + DINNER = 3 + SNACK = 4 + + class MeasurementTiming(proto.Enum): + r"""Timing of the measurement. + + Values: + MEASUREMENT_TIMING_UNSPECIFIED (0): + Unspecified measurement timing. + AFTER_MEAL (1): + Measurement taken after meal. + BEFORE_MEAL (2): + Measurement taken before meal. + FASTING (3): + Measurement taken while fasting. + GENERAL (4): + General measurement (not associated with a + meal or time of day). + BEFORE_BED (5): + Measurement taken before bed. + OVER_NIGHT (6): + Measurement taken over night. + """ + + MEASUREMENT_TIMING_UNSPECIFIED = 0 + AFTER_MEAL = 1 + BEFORE_MEAL = 2 + FASTING = 3 + GENERAL = 4 + BEFORE_BED = 5 + OVER_NIGHT = 6 + + class Specimen(proto.Enum): + r"""Type of body fluid used to measure the blood glucose. + + Values: + SPECIMEN_UNSPECIFIED (0): + Unspecified specimen. + CAPILLARY_BLOOD (1): + Capillary blood. + INTERSTITIAL_FLUID (2): + Interstitial fluid. + PLASMA (3): + Plasma. + SERUM (4): + Serum. + TEARS (5): + Tears. + WHOLE_BLOOD (6): + Whole blood. + """ + + SPECIMEN_UNSPECIFIED = 0 + CAPILLARY_BLOOD = 1 + INTERSTITIAL_FLUID = 2 + PLASMA = 3 + SERUM = 4 + TEARS = 5 + WHOLE_BLOOD = 6 + + sample_time: data_coordinates.ObservationSampleTime = proto.Field( + proto.MESSAGE, + number=1, + message=data_coordinates.ObservationSampleTime, + ) + blood_glucose_milligrams_per_deciliter: float = proto.Field( + proto.DOUBLE, + number=2, + optional=True, + ) + measurement_source: MeasurementSource = proto.Field( + proto.ENUM, + number=3, + enum=MeasurementSource, + ) + meal_type: MealType = proto.Field( + proto.ENUM, + number=4, + enum=MealType, + ) + measurement_timing: MeasurementTiming = proto.Field( + proto.ENUM, + number=5, + enum=MeasurementTiming, + ) + specimen: Specimen = proto.Field( + proto.ENUM, + number=6, + enum=Specimen, + ) + notes: str = proto.Field( + proto.STRING, + number=8, + ) + + +class BloodGlucoseRollupValue(proto.Message): + r"""Represents the result of the rollup of the blood glucose data type. + LINT: LEGACY_NAMES + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + blood_glucose_milligrams_per_deciliter_avg (float): + Average blood glucose level in mg/dL. + + This field is a member of `oneof`_ ``_blood_glucose_milligrams_per_deciliter_avg``. + """ + + blood_glucose_milligrams_per_deciliter_avg: float = proto.Field( + proto.DOUBLE, + number=1, + optional=True, + ) + + +class SedentaryPeriod(proto.Message): + r"""SedentaryPeriod + + SedentaryPeriod data represents the periods of time that the + user was sedentary (i.e. not moving while wearing the device). + + Attributes: + interval (google.devicesandservices.health_v4.types.ObservationTimeInterval): + Required. Observed interval. + """ + + interval: data_coordinates.ObservationTimeInterval = proto.Field( + proto.MESSAGE, + number=1, + message=data_coordinates.ObservationTimeInterval, + ) + + +class SedentaryPeriodRollupValue(proto.Message): + r"""Represents the result of the rollup of the user's sedentary + periods. + + Attributes: + duration_sum (google.protobuf.duration_pb2.Duration): + The total time user spent sedentary during + the interval. + """ + + duration_sum: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=1, + message=duration_pb2.Duration, + ) + + +class ActiveEnergyBurned(proto.Message): + r"""Energy burned as part of an activity, excluding the basal + energy burn. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + interval (google.devicesandservices.health_v4.types.ObservationTimeInterval): + Required. Observed interval + kcal (float): + Required. Energy burned during an activity, + measured in kilocalories. + + This field is a member of `oneof`_ ``_kcal``. + """ + + interval: data_coordinates.ObservationTimeInterval = proto.Field( + proto.MESSAGE, + number=1, + message=data_coordinates.ObservationTimeInterval, + ) + kcal: float = proto.Field( + proto.DOUBLE, + number=2, + optional=True, + ) + + +class ActiveEnergyBurnedRollupValue(proto.Message): + r"""Represents the result of the rollup of active energy burned. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + kcal_sum (float): + Output only. Sum of the active energy burned + in kilocalories. + + This field is a member of `oneof`_ ``_kcal_sum``. + """ + + kcal_sum: float = proto.Field( + proto.DOUBLE, + number=1, + optional=True, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/data_points.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/data_points.py new file mode 100644 index 000000000000..b8df31f71a9e --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/data_points.py @@ -0,0 +1,2278 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import google.protobuf.duration_pb2 as duration_pb2 # type: ignore +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore +import google.rpc.status_pb2 as status_pb2 # type: ignore +import google.type.interval_pb2 as interval_pb2 # type: ignore +import proto # type: ignore + +from google.devicesandservices.health_v4.types import data_coordinates, data_model +from google.devicesandservices.health_v4.types import data_source as gdh_data_source + +__protobuf__ = proto.module( + package="google.devicesandservices.health.v4", + manifest={ + "DataPoint", + "ReconciledDataPoint", + "RollupDataPoint", + "DailyRollupDataPoint", + "GetDataPointRequest", + "ListDataPointsRequest", + "ListDataPointsResponse", + "CreateDataPointRequest", + "CreateDataPointOperationMetadata", + "UpdateDataPointRequest", + "UpdateDataPointOperationMetadata", + "BatchDeleteDataPointsRequest", + "BatchDeleteDataPointsResponse", + "BatchDeleteDataPointsOperationMetadata", + "ReconcileDataPointsRequest", + "ReconcileDataPointsResponse", + "RollUpDataPointsRequest", + "RollUpDataPointsResponse", + "DailyRollUpDataPointsRequest", + "DailyRollUpDataPointsResponse", + "DataType", + "ExportExerciseTcxRequest", + "ExportExerciseTcxResponse", + }, +) + + +class DataPoint(proto.Message): + r"""A computed or recorded metric. + + 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: + steps (google.devicesandservices.health_v4.types.Steps): + Optional. Data for points in the ``steps`` interval data + type collection. + + This field is a member of `oneof`_ ``data``. + floors (google.devicesandservices.health_v4.types.Floors): + Optional. Data for points in the ``floors`` interval data + type collection. + + This field is a member of `oneof`_ ``data``. + heart_rate (google.devicesandservices.health_v4.types.HeartRate): + Optional. Data for points in the ``heart-rate`` sample data + type collection. + + This field is a member of `oneof`_ ``data``. + sleep (google.devicesandservices.health_v4.types.Sleep): + Optional. Data for points in the ``sleep`` session data type + collection. + + This field is a member of `oneof`_ ``data``. + daily_resting_heart_rate (google.devicesandservices.health_v4.types.DailyRestingHeartRate): + Optional. Data for points in the + ``daily-resting-heart-rate`` daily data type collection. + + This field is a member of `oneof`_ ``data``. + daily_heart_rate_variability (google.devicesandservices.health_v4.types.DailyHeartRateVariability): + Optional. Data for points in the + ``daily-heart-rate-variability`` daily data type collection. + + This field is a member of `oneof`_ ``data``. + exercise (google.devicesandservices.health_v4.types.Exercise): + Optional. Data for points in the ``exercise`` session data + type collection. + + This field is a member of `oneof`_ ``data``. + weight (google.devicesandservices.health_v4.types.Weight): + Optional. Data for points in the ``weight`` sample data type + collection. + + This field is a member of `oneof`_ ``data``. + altitude (google.devicesandservices.health_v4.types.Altitude): + Optional. Data for points in the ``altitude`` interval data + type collection. + + This field is a member of `oneof`_ ``data``. + distance (google.devicesandservices.health_v4.types.Distance): + Optional. Data for points in the ``distance`` interval data + type collection. + + This field is a member of `oneof`_ ``data``. + body_fat (google.devicesandservices.health_v4.types.BodyFat): + Optional. Data for points in the ``body-fat`` sample data + type collection. + + This field is a member of `oneof`_ ``data``. + active_zone_minutes (google.devicesandservices.health_v4.types.ActiveZoneMinutes): + Optional. Data for points in the ``active-zone-minutes`` + interval data type collection, measured in minutes. + + This field is a member of `oneof`_ ``data``. + heart_rate_variability (google.devicesandservices.health_v4.types.HeartRateVariability): + Optional. Data for points in the ``heart-rate-variability`` + sample data type collection. + + This field is a member of `oneof`_ ``data``. + daily_sleep_temperature_derivations (google.devicesandservices.health_v4.types.DailySleepTemperatureDerivations): + Optional. Data for points in the + ``daily-sleep-temperature-derivations`` daily data type + collection. + + This field is a member of `oneof`_ ``data``. + sedentary_period (google.devicesandservices.health_v4.types.SedentaryPeriod): + Optional. Data for points in the ``sedentary-period`` + interval data type collection. + + This field is a member of `oneof`_ ``data``. + run_vo2_max (google.devicesandservices.health_v4.types.RunVO2Max): + Optional. Data for points in the ``run-vo2-max`` sample data + type collection. + + This field is a member of `oneof`_ ``data``. + oxygen_saturation (google.devicesandservices.health_v4.types.OxygenSaturation): + Optional. Data for points in the ``oxygen-saturation`` + sample data type collection. + + This field is a member of `oneof`_ ``data``. + daily_oxygen_saturation (google.devicesandservices.health_v4.types.DailyOxygenSaturation): + Optional. Data for points in the ``daily-oxygen-saturation`` + daily data type collection. + + This field is a member of `oneof`_ ``data``. + activity_level (google.devicesandservices.health_v4.types.ActivityLevel): + Optional. Data for points in the ``activity-level`` daily + data type collection. + + This field is a member of `oneof`_ ``data``. + vo2_max (google.devicesandservices.health_v4.types.VO2Max): + Optional. Data for points in the ``vo2-max`` sample data + type collection. + + This field is a member of `oneof`_ ``data``. + daily_vo2_max (google.devicesandservices.health_v4.types.DailyVO2Max): + Optional. Data for points in the ``daily-vo2-max`` daily + data type collection. + + This field is a member of `oneof`_ ``data``. + nutrition_log (google.devicesandservices.health_v4.types.NutritionLog): + Optional. Data for points in the ``nutrition-log`` session + data type collection. + + This field is a member of `oneof`_ ``data``. + irregular_rhythm_notification (google.devicesandservices.health_v4.types.IrregularRhythmNotification): + Optional. Data for points in the + ``irregular-rhythm-notification`` session data type + collection. + + This field is a member of `oneof`_ ``data``. + electrocardiogram (google.devicesandservices.health_v4.types.Electrocardiogram): + Optional. Data for points in the ``electrocardiogram`` + session data type collection. + + This field is a member of `oneof`_ ``data``. + daily_heart_rate_zones (google.devicesandservices.health_v4.types.DailyHeartRateZones): + Optional. Data for points in the ``daily-heart-rate-zones`` + daily data type collection. + + This field is a member of `oneof`_ ``data``. + hydration_log (google.devicesandservices.health_v4.types.HydrationLog): + Optional. Data for points in the ``hydration-log`` session + data type collection. + + This field is a member of `oneof`_ ``data``. + food (google.devicesandservices.health_v4.types.Food): + Optional. The food details. + + This field is a member of `oneof`_ ``data``. + time_in_heart_rate_zone (google.devicesandservices.health_v4.types.TimeInHeartRateZone): + Optional. Data for points in the ``time-in-heart-rate-zone`` + interval data type collection. + + This field is a member of `oneof`_ ``data``. + active_minutes (google.devicesandservices.health_v4.types.ActiveMinutes): + Optional. Data for points in the ``active-minutes`` interval + data type collection. + + This field is a member of `oneof`_ ``data``. + respiratory_rate_sleep_summary (google.devicesandservices.health_v4.types.RespiratoryRateSleepSummary): + Optional. Data for points in the + ``respiratory-rate-sleep-summary`` sample data type + collection. + + This field is a member of `oneof`_ ``data``. + daily_respiratory_rate (google.devicesandservices.health_v4.types.DailyRespiratoryRate): + Optional. Data for points in the ``daily-respiratory-rate`` + daily data type collection. + + This field is a member of `oneof`_ ``data``. + swim_lengths_data (google.devicesandservices.health_v4.types.SwimLengthsData): + Optional. Data for points in the ``swim-lengths-data`` + interval data type collection. + + This field is a member of `oneof`_ ``data``. + height (google.devicesandservices.health_v4.types.Height): + Optional. Data for points in the ``height`` sample data type + collection. + + This field is a member of `oneof`_ ``data``. + basal_energy_burned (google.devicesandservices.health_v4.types.BasalEnergyBurned): + Optional. Data for points in the ``basal-energy-burned`` + interval data type collection. + + This field is a member of `oneof`_ ``data``. + core_body_temperature (google.devicesandservices.health_v4.types.CoreBodyTemperature): + Optional. Data for points in the ``core-body-temperature`` + sample data type collection. + + This field is a member of `oneof`_ ``data``. + active_energy_burned (google.devicesandservices.health_v4.types.ActiveEnergyBurned): + Optional. Data for points in the ``active-energy-burned`` + interval data type collection. + + This field is a member of `oneof`_ ``data``. + food_measurement_unit (google.devicesandservices.health_v4.types.FoodMeasurementUnit): + Optional. The food measurement unit details. + + This field is a member of `oneof`_ ``data``. + blood_glucose (google.devicesandservices.health_v4.types.BloodGlucose): + Optional. Data for points in the ``blood-glucose`` sample + data type collection. + + This field is a member of `oneof`_ ``data``. + name (str): + Identifier. Data point name, only supported for the subset + of identifiable data types. For the majority of the data + types, individual data points do not need to be identified + and this field would be empty. + + Format: + ``users/{user}/dataTypes/{data_type}/dataPoints/{data_point}`` + + Example: + ``users/abcd1234/dataTypes/sleep/dataPoints/a1b2c3d4-e5f6-7890-1234-567890abcdef`` + + The ``{user}`` ID is a system-generated identifier, as + described in + [Identity.health_user_id][google.devicesandservices.health.v4.Identity.health_user_id]. + + The ``{data_type}`` ID corresponds to the kebab-case version + of the field names in the [DataPoint + data][google.devicesandservices.health.v4.DataPoint] union + field, e.g. ``total-calories`` for the ``total_calories`` + field. + + The ``{data_point}`` ID can be client-provided or + system-generated. If client-provided, it must be a string of + 4-63 characters, containing only lowercase letters, numbers, + and hyphens. + data_source (google.devicesandservices.health_v4.types.DataSource): + Optional. Data source information for the + metric + """ + + steps: data_model.Steps = proto.Field( + proto.MESSAGE, + number=4, + oneof="data", + message=data_model.Steps, + ) + floors: data_model.Floors = proto.Field( + proto.MESSAGE, + number=5, + oneof="data", + message=data_model.Floors, + ) + heart_rate: data_model.HeartRate = proto.Field( + proto.MESSAGE, + number=6, + oneof="data", + message=data_model.HeartRate, + ) + sleep: data_model.Sleep = proto.Field( + proto.MESSAGE, + number=8, + oneof="data", + message=data_model.Sleep, + ) + daily_resting_heart_rate: data_model.DailyRestingHeartRate = proto.Field( + proto.MESSAGE, + number=9, + oneof="data", + message=data_model.DailyRestingHeartRate, + ) + daily_heart_rate_variability: data_model.DailyHeartRateVariability = proto.Field( + proto.MESSAGE, + number=10, + oneof="data", + message=data_model.DailyHeartRateVariability, + ) + exercise: data_model.Exercise = proto.Field( + proto.MESSAGE, + number=11, + oneof="data", + message=data_model.Exercise, + ) + weight: data_model.Weight = proto.Field( + proto.MESSAGE, + number=12, + oneof="data", + message=data_model.Weight, + ) + altitude: data_model.Altitude = proto.Field( + proto.MESSAGE, + number=13, + oneof="data", + message=data_model.Altitude, + ) + distance: data_model.Distance = proto.Field( + proto.MESSAGE, + number=14, + oneof="data", + message=data_model.Distance, + ) + body_fat: data_model.BodyFat = proto.Field( + proto.MESSAGE, + number=15, + oneof="data", + message=data_model.BodyFat, + ) + active_zone_minutes: data_model.ActiveZoneMinutes = proto.Field( + proto.MESSAGE, + number=17, + oneof="data", + message=data_model.ActiveZoneMinutes, + ) + heart_rate_variability: data_model.HeartRateVariability = proto.Field( + proto.MESSAGE, + number=19, + oneof="data", + message=data_model.HeartRateVariability, + ) + daily_sleep_temperature_derivations: data_model.DailySleepTemperatureDerivations = ( + proto.Field( + proto.MESSAGE, + number=20, + oneof="data", + message=data_model.DailySleepTemperatureDerivations, + ) + ) + sedentary_period: data_model.SedentaryPeriod = proto.Field( + proto.MESSAGE, + number=21, + oneof="data", + message=data_model.SedentaryPeriod, + ) + run_vo2_max: data_model.RunVO2Max = proto.Field( + proto.MESSAGE, + number=22, + oneof="data", + message=data_model.RunVO2Max, + ) + oxygen_saturation: data_model.OxygenSaturation = proto.Field( + proto.MESSAGE, + number=24, + oneof="data", + message=data_model.OxygenSaturation, + ) + daily_oxygen_saturation: data_model.DailyOxygenSaturation = proto.Field( + proto.MESSAGE, + number=25, + oneof="data", + message=data_model.DailyOxygenSaturation, + ) + activity_level: data_model.ActivityLevel = proto.Field( + proto.MESSAGE, + number=26, + oneof="data", + message=data_model.ActivityLevel, + ) + vo2_max: data_model.VO2Max = proto.Field( + proto.MESSAGE, + number=27, + oneof="data", + message=data_model.VO2Max, + ) + daily_vo2_max: data_model.DailyVO2Max = proto.Field( + proto.MESSAGE, + number=28, + oneof="data", + message=data_model.DailyVO2Max, + ) + nutrition_log: data_model.NutritionLog = proto.Field( + proto.MESSAGE, + number=29, + oneof="data", + message=data_model.NutritionLog, + ) + irregular_rhythm_notification: data_model.IrregularRhythmNotification = proto.Field( + proto.MESSAGE, + number=30, + oneof="data", + message=data_model.IrregularRhythmNotification, + ) + electrocardiogram: data_model.Electrocardiogram = proto.Field( + proto.MESSAGE, + number=31, + oneof="data", + message=data_model.Electrocardiogram, + ) + daily_heart_rate_zones: data_model.DailyHeartRateZones = proto.Field( + proto.MESSAGE, + number=32, + oneof="data", + message=data_model.DailyHeartRateZones, + ) + hydration_log: data_model.HydrationLog = proto.Field( + proto.MESSAGE, + number=33, + oneof="data", + message=data_model.HydrationLog, + ) + food: data_model.Food = proto.Field( + proto.MESSAGE, + number=34, + oneof="data", + message=data_model.Food, + ) + time_in_heart_rate_zone: data_model.TimeInHeartRateZone = proto.Field( + proto.MESSAGE, + number=35, + oneof="data", + message=data_model.TimeInHeartRateZone, + ) + active_minutes: data_model.ActiveMinutes = proto.Field( + proto.MESSAGE, + number=36, + oneof="data", + message=data_model.ActiveMinutes, + ) + respiratory_rate_sleep_summary: data_model.RespiratoryRateSleepSummary = ( + proto.Field( + proto.MESSAGE, + number=37, + oneof="data", + message=data_model.RespiratoryRateSleepSummary, + ) + ) + daily_respiratory_rate: data_model.DailyRespiratoryRate = proto.Field( + proto.MESSAGE, + number=38, + oneof="data", + message=data_model.DailyRespiratoryRate, + ) + swim_lengths_data: data_model.SwimLengthsData = proto.Field( + proto.MESSAGE, + number=39, + oneof="data", + message=data_model.SwimLengthsData, + ) + height: data_model.Height = proto.Field( + proto.MESSAGE, + number=40, + oneof="data", + message=data_model.Height, + ) + basal_energy_burned: data_model.BasalEnergyBurned = proto.Field( + proto.MESSAGE, + number=41, + oneof="data", + message=data_model.BasalEnergyBurned, + ) + core_body_temperature: data_model.CoreBodyTemperature = proto.Field( + proto.MESSAGE, + number=42, + oneof="data", + message=data_model.CoreBodyTemperature, + ) + active_energy_burned: data_model.ActiveEnergyBurned = proto.Field( + proto.MESSAGE, + number=44, + oneof="data", + message=data_model.ActiveEnergyBurned, + ) + food_measurement_unit: data_model.FoodMeasurementUnit = proto.Field( + proto.MESSAGE, + number=45, + oneof="data", + message=data_model.FoodMeasurementUnit, + ) + blood_glucose: data_model.BloodGlucose = proto.Field( + proto.MESSAGE, + number=46, + oneof="data", + message=data_model.BloodGlucose, + ) + name: str = proto.Field( + proto.STRING, + number=1, + ) + data_source: gdh_data_source.DataSource = proto.Field( + proto.MESSAGE, + number=3, + message=gdh_data_source.DataSource, + ) + + +class ReconciledDataPoint(proto.Message): + r"""A reconciled computed or recorded metric. + + 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: + steps (google.devicesandservices.health_v4.types.Steps): + Data for points in the ``steps`` interval data type + collection. + + This field is a member of `oneof`_ ``data``. + floors (google.devicesandservices.health_v4.types.Floors): + Data for points in the ``floors`` interval data type + collection. + + This field is a member of `oneof`_ ``data``. + heart_rate (google.devicesandservices.health_v4.types.HeartRate): + Data for points in the ``heart-rate`` sample data type + collection. + + This field is a member of `oneof`_ ``data``. + sleep (google.devicesandservices.health_v4.types.Sleep): + Data for points in the ``sleep`` session data type + collection. + + This field is a member of `oneof`_ ``data``. + daily_resting_heart_rate (google.devicesandservices.health_v4.types.DailyRestingHeartRate): + Data for points in the ``daily-resting-heart-rate`` daily + data type collection. + + This field is a member of `oneof`_ ``data``. + daily_heart_rate_variability (google.devicesandservices.health_v4.types.DailyHeartRateVariability): + Data for points in the ``daily-heart-rate-variability`` + daily data type collection. + + This field is a member of `oneof`_ ``data``. + exercise (google.devicesandservices.health_v4.types.Exercise): + Data for points in the ``exercise`` session data type + collection. + + This field is a member of `oneof`_ ``data``. + weight (google.devicesandservices.health_v4.types.Weight): + Data for points in the ``weight`` sample data type + collection. + + This field is a member of `oneof`_ ``data``. + altitude (google.devicesandservices.health_v4.types.Altitude): + Data for points in the ``altitude`` interval data type + collection. + + This field is a member of `oneof`_ ``data``. + distance (google.devicesandservices.health_v4.types.Distance): + Data for points in the ``distance`` interval data type + collection. + + This field is a member of `oneof`_ ``data``. + body_fat (google.devicesandservices.health_v4.types.BodyFat): + Data for points in the ``body-fat`` sample data type + collection. + + This field is a member of `oneof`_ ``data``. + active_zone_minutes (google.devicesandservices.health_v4.types.ActiveZoneMinutes): + Data for points in the ``active-zone-minutes`` interval data + type collection, measured in minutes. + + This field is a member of `oneof`_ ``data``. + heart_rate_variability (google.devicesandservices.health_v4.types.HeartRateVariability): + Data for points in the ``heart-rate-variability`` sample + data type collection. + + This field is a member of `oneof`_ ``data``. + daily_sleep_temperature_derivations (google.devicesandservices.health_v4.types.DailySleepTemperatureDerivations): + Data for points in the + ``daily-sleep-temperature-derivations`` daily data type + collection. + + This field is a member of `oneof`_ ``data``. + sedentary_period (google.devicesandservices.health_v4.types.SedentaryPeriod): + Data for points in the ``sedentary-period`` interval data + type collection. + + This field is a member of `oneof`_ ``data``. + run_vo2_max (google.devicesandservices.health_v4.types.RunVO2Max): + Data for points in the ``run-vo2-max`` sample data type + collection. + + This field is a member of `oneof`_ ``data``. + oxygen_saturation (google.devicesandservices.health_v4.types.OxygenSaturation): + Data for points in the ``oxygen-saturation`` sample data + type collection. + + This field is a member of `oneof`_ ``data``. + daily_oxygen_saturation (google.devicesandservices.health_v4.types.DailyOxygenSaturation): + Data for points in the ``daily-oxygen-saturation`` daily + data type collection. + + This field is a member of `oneof`_ ``data``. + activity_level (google.devicesandservices.health_v4.types.ActivityLevel): + Data for points in the ``activity-level`` daily data type + collection. + + This field is a member of `oneof`_ ``data``. + vo2_max (google.devicesandservices.health_v4.types.VO2Max): + Data for points in the ``vo2-max`` sample data type + collection. + + This field is a member of `oneof`_ ``data``. + daily_vo2_max (google.devicesandservices.health_v4.types.DailyVO2Max): + Data for points in the ``daily-vo2-max`` daily data type + collection. + + This field is a member of `oneof`_ ``data``. + nutrition_log (google.devicesandservices.health_v4.types.NutritionLog): + Data for points in the ``nutrition-log`` session data type + collection. + + This field is a member of `oneof`_ ``data``. + daily_heart_rate_zones (google.devicesandservices.health_v4.types.DailyHeartRateZones): + Data for points in the ``daily-heart-rate-zones`` daily data + type collection. + + This field is a member of `oneof`_ ``data``. + hydration_log (google.devicesandservices.health_v4.types.HydrationLog): + Data for points in the ``hydration-log`` session data type + collection. + + This field is a member of `oneof`_ ``data``. + time_in_heart_rate_zone (google.devicesandservices.health_v4.types.TimeInHeartRateZone): + Data for points in the ``time-in-heart-rate-zone`` interval + data type collection. + + This field is a member of `oneof`_ ``data``. + active_minutes (google.devicesandservices.health_v4.types.ActiveMinutes): + Data for points in the ``active-minutes`` interval data type + collection. + + This field is a member of `oneof`_ ``data``. + respiratory_rate_sleep_summary (google.devicesandservices.health_v4.types.RespiratoryRateSleepSummary): + Data for points in the ``respiratory-rate-sleep-summary`` + sample data type collection. + + This field is a member of `oneof`_ ``data``. + daily_respiratory_rate (google.devicesandservices.health_v4.types.DailyRespiratoryRate): + Data for points in the ``daily-respiratory-rate`` daily data + type collection. + + This field is a member of `oneof`_ ``data``. + swim_lengths_data (google.devicesandservices.health_v4.types.SwimLengthsData): + Data for points in the ``swim-lengths-data`` interval data + type collection. + + This field is a member of `oneof`_ ``data``. + height (google.devicesandservices.health_v4.types.Height): + Data for points in the ``height`` sample data type + collection. + + This field is a member of `oneof`_ ``data``. + basal_energy_burned (google.devicesandservices.health_v4.types.BasalEnergyBurned): + Data for points in the ``basal-energy-burned`` interval data + type collection. + + This field is a member of `oneof`_ ``data``. + core_body_temperature (google.devicesandservices.health_v4.types.CoreBodyTemperature): + Data for points in the ``core-body-temperature`` sample data + type collection. + + This field is a member of `oneof`_ ``data``. + active_energy_burned (google.devicesandservices.health_v4.types.ActiveEnergyBurned): + Data for points in the ``active-energy-burned`` interval + data type collection. + + This field is a member of `oneof`_ ``data``. + blood_glucose (google.devicesandservices.health_v4.types.BloodGlucose): + Data for points in the ``blood-glucose`` sample data type + collection. + + This field is a member of `oneof`_ ``data``. + data_point_name (str): + Identifier. Data point name, only supported for the subset + of identifiable data types. For the majority of the data + types, individual data points do not need to be identified + and this field would be empty. + + Format: + ``users/{user}/dataTypes/{data_type}/dataPoints/{data_point}`` + + Example: + ``users/abcd1234/dataTypes/sleep/dataPoints/a1b2c3d4-e5f6-7890-1234-567890abcdef`` + + The ``{user}`` ID is a system-generated identifier, as + described in + [Identity.health_user_id][google.devicesandservices.health.v4.Identity.health_user_id]. + + The ``{data_type}`` ID corresponds to the kebab-case version + of the field names in the [DataPoint + data][google.devicesandservices.health.v4.DataPoint] union + field, e.g. ``total-calories`` for the ``total_calories`` + field. + + The ``{data_point}`` ID can be client-provided or + system-generated. If client-provided, it must be a string of + 4-63 characters, containing only lowercase letters, numbers, + and hyphens. + """ + + steps: data_model.Steps = proto.Field( + proto.MESSAGE, + number=4, + oneof="data", + message=data_model.Steps, + ) + floors: data_model.Floors = proto.Field( + proto.MESSAGE, + number=5, + oneof="data", + message=data_model.Floors, + ) + heart_rate: data_model.HeartRate = proto.Field( + proto.MESSAGE, + number=6, + oneof="data", + message=data_model.HeartRate, + ) + sleep: data_model.Sleep = proto.Field( + proto.MESSAGE, + number=8, + oneof="data", + message=data_model.Sleep, + ) + daily_resting_heart_rate: data_model.DailyRestingHeartRate = proto.Field( + proto.MESSAGE, + number=9, + oneof="data", + message=data_model.DailyRestingHeartRate, + ) + daily_heart_rate_variability: data_model.DailyHeartRateVariability = proto.Field( + proto.MESSAGE, + number=10, + oneof="data", + message=data_model.DailyHeartRateVariability, + ) + exercise: data_model.Exercise = proto.Field( + proto.MESSAGE, + number=11, + oneof="data", + message=data_model.Exercise, + ) + weight: data_model.Weight = proto.Field( + proto.MESSAGE, + number=12, + oneof="data", + message=data_model.Weight, + ) + altitude: data_model.Altitude = proto.Field( + proto.MESSAGE, + number=13, + oneof="data", + message=data_model.Altitude, + ) + distance: data_model.Distance = proto.Field( + proto.MESSAGE, + number=14, + oneof="data", + message=data_model.Distance, + ) + body_fat: data_model.BodyFat = proto.Field( + proto.MESSAGE, + number=15, + oneof="data", + message=data_model.BodyFat, + ) + active_zone_minutes: data_model.ActiveZoneMinutes = proto.Field( + proto.MESSAGE, + number=17, + oneof="data", + message=data_model.ActiveZoneMinutes, + ) + heart_rate_variability: data_model.HeartRateVariability = proto.Field( + proto.MESSAGE, + number=19, + oneof="data", + message=data_model.HeartRateVariability, + ) + daily_sleep_temperature_derivations: data_model.DailySleepTemperatureDerivations = ( + proto.Field( + proto.MESSAGE, + number=20, + oneof="data", + message=data_model.DailySleepTemperatureDerivations, + ) + ) + sedentary_period: data_model.SedentaryPeriod = proto.Field( + proto.MESSAGE, + number=21, + oneof="data", + message=data_model.SedentaryPeriod, + ) + run_vo2_max: data_model.RunVO2Max = proto.Field( + proto.MESSAGE, + number=22, + oneof="data", + message=data_model.RunVO2Max, + ) + oxygen_saturation: data_model.OxygenSaturation = proto.Field( + proto.MESSAGE, + number=24, + oneof="data", + message=data_model.OxygenSaturation, + ) + daily_oxygen_saturation: data_model.DailyOxygenSaturation = proto.Field( + proto.MESSAGE, + number=25, + oneof="data", + message=data_model.DailyOxygenSaturation, + ) + activity_level: data_model.ActivityLevel = proto.Field( + proto.MESSAGE, + number=26, + oneof="data", + message=data_model.ActivityLevel, + ) + vo2_max: data_model.VO2Max = proto.Field( + proto.MESSAGE, + number=27, + oneof="data", + message=data_model.VO2Max, + ) + daily_vo2_max: data_model.DailyVO2Max = proto.Field( + proto.MESSAGE, + number=28, + oneof="data", + message=data_model.DailyVO2Max, + ) + nutrition_log: data_model.NutritionLog = proto.Field( + proto.MESSAGE, + number=29, + oneof="data", + message=data_model.NutritionLog, + ) + daily_heart_rate_zones: data_model.DailyHeartRateZones = proto.Field( + proto.MESSAGE, + number=32, + oneof="data", + message=data_model.DailyHeartRateZones, + ) + hydration_log: data_model.HydrationLog = proto.Field( + proto.MESSAGE, + number=33, + oneof="data", + message=data_model.HydrationLog, + ) + time_in_heart_rate_zone: data_model.TimeInHeartRateZone = proto.Field( + proto.MESSAGE, + number=35, + oneof="data", + message=data_model.TimeInHeartRateZone, + ) + active_minutes: data_model.ActiveMinutes = proto.Field( + proto.MESSAGE, + number=36, + oneof="data", + message=data_model.ActiveMinutes, + ) + respiratory_rate_sleep_summary: data_model.RespiratoryRateSleepSummary = ( + proto.Field( + proto.MESSAGE, + number=37, + oneof="data", + message=data_model.RespiratoryRateSleepSummary, + ) + ) + daily_respiratory_rate: data_model.DailyRespiratoryRate = proto.Field( + proto.MESSAGE, + number=38, + oneof="data", + message=data_model.DailyRespiratoryRate, + ) + swim_lengths_data: data_model.SwimLengthsData = proto.Field( + proto.MESSAGE, + number=39, + oneof="data", + message=data_model.SwimLengthsData, + ) + height: data_model.Height = proto.Field( + proto.MESSAGE, + number=40, + oneof="data", + message=data_model.Height, + ) + basal_energy_burned: data_model.BasalEnergyBurned = proto.Field( + proto.MESSAGE, + number=41, + oneof="data", + message=data_model.BasalEnergyBurned, + ) + core_body_temperature: data_model.CoreBodyTemperature = proto.Field( + proto.MESSAGE, + number=42, + oneof="data", + message=data_model.CoreBodyTemperature, + ) + active_energy_burned: data_model.ActiveEnergyBurned = proto.Field( + proto.MESSAGE, + number=44, + oneof="data", + message=data_model.ActiveEnergyBurned, + ) + blood_glucose: data_model.BloodGlucose = proto.Field( + proto.MESSAGE, + number=46, + oneof="data", + message=data_model.BloodGlucose, + ) + data_point_name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class RollupDataPoint(proto.Message): + r"""Value of a rollup for a single physical time interval + (aggregation window) of reconciled data points from all data + sources, excluding those data points that are identified as + recorded by wearables in intervals when they were not actually + worn. + + 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: + steps (google.devicesandservices.health_v4.types.StepsRollupValue): + Returned by default when rolling up data points from the + ``steps`` data type, or when requested explicitly using the + ``steps`` rollup type identifier. + + This field is a member of `oneof`_ ``value``. + floors (google.devicesandservices.health_v4.types.FloorsRollupValue): + Returned by default when rolling up data points from the + ``floors`` data type, or when requested explicitly using the + ``floors`` rollup type identifier. + + This field is a member of `oneof`_ ``value``. + heart_rate (google.devicesandservices.health_v4.types.HeartRateRollupValue): + Returned by default when rolling up data points from the + ``heart-rate`` data type, or when requested explicitly using + the ``heart-rate`` rollup type identifier. + + This field is a member of `oneof`_ ``value``. + weight (google.devicesandservices.health_v4.types.WeightRollupValue): + Returned by default when rolling up data points from the + ``weight`` data type, or when requested explicitly using the + ``weight`` rollup type identifier. + + This field is a member of `oneof`_ ``value``. + altitude (google.devicesandservices.health_v4.types.AltitudeRollupValue): + Returned by default when rolling up data points from the + ``altitude`` data type, or when requested explicitly using + the ``altitude`` rollup type identifier. + + This field is a member of `oneof`_ ``value``. + distance (google.devicesandservices.health_v4.types.DistanceRollupValue): + Returned by default when rolling up data points from the + ``distance`` data type, or when requested explicitly using + the ``distance`` rollup type identifier. + + This field is a member of `oneof`_ ``value``. + body_fat (google.devicesandservices.health_v4.types.BodyFatRollupValue): + Returned by default when rolling up data points from the + ``body-fat`` data type, or when requested explicitly using + the ``body-fat`` rollup type identifier. + + This field is a member of `oneof`_ ``value``. + total_calories (google.devicesandservices.health_v4.types.TotalCaloriesRollupValue): + Returned by default when rolling up data points from the + ``total-calories`` data type, or when requested explicitly + using the ``total-calories`` rollup type identifier. + + This field is a member of `oneof`_ ``value``. + active_zone_minutes (google.devicesandservices.health_v4.types.ActiveZoneMinutesRollupValue): + Returned by default when rolling up data points from the + ``active-zone-minutes`` data type, or when requested + explicitly using the ``active-zone-minutes`` rollup type + identifier. + + This field is a member of `oneof`_ ``value``. + sedentary_period (google.devicesandservices.health_v4.types.SedentaryPeriodRollupValue): + Returned by default when rolling up data points from the + ``sedentary-period`` data type, or when requested explicitly + using the ``sedentary-period`` rollup type identifier. + + This field is a member of `oneof`_ ``value``. + run_vo2_max (google.devicesandservices.health_v4.types.RunVO2MaxRollupValue): + Returned by default when rolling up data points from the + ``run-vo2-max`` data type, or when requested explicitly + using the ``run-vo2-max`` rollup type identifier. + + This field is a member of `oneof`_ ``value``. + calories_in_heart_rate_zone (google.devicesandservices.health_v4.types.CaloriesInHeartRateZoneRollupValue): + Returned by default when rolling up data points from the + ``calories-in-heart-rate-zone`` data type, or when requested + explicitly using the ``calories-in-heart-rate-zone`` rollup + type identifier. + + This field is a member of `oneof`_ ``value``. + activity_level (google.devicesandservices.health_v4.types.ActivityLevelRollupValue): + Returned by default when rolling up data points from the + ``activity-level`` data type, or when requested explicitly + using the ``activity-level`` rollup type identifier. + + This field is a member of `oneof`_ ``value``. + nutrition_log (google.devicesandservices.health_v4.types.NutritionLogRollupValue): + Returned by default when rolling up data points from the + ``nutrition-log`` data type, or when requested explicitly + using the ``nutrition-log`` rollup type identifier. + + This field is a member of `oneof`_ ``value``. + hydration_log (google.devicesandservices.health_v4.types.HydrationLogRollupValue): + Returned by default when rolling up data points from the + ``hydration-log`` data type, or when requested explicitly + using the ``hydration-log`` rollup type identifier. + + This field is a member of `oneof`_ ``value``. + time_in_heart_rate_zone (google.devicesandservices.health_v4.types.TimeInHeartRateZoneRollupValue): + Returned by default when rolling up data points from the + ``time-in-heart-rate-zone`` data type, or when requested + explicitly using the ``time-in-heart-rate-zone`` rollup type + identifier. + + This field is a member of `oneof`_ ``value``. + active_minutes (google.devicesandservices.health_v4.types.ActiveMinutesRollupValue): + Returned by default when rolling up data points from the + ``active-minutes`` data type, or when requested explicitly + using the ``active-minutes`` rollup type identifier. + + This field is a member of `oneof`_ ``value``. + swim_lengths_data (google.devicesandservices.health_v4.types.SwimLengthsDataRollupValue): + Returned by default when rolling up data points from the + ``swim-lengths-data`` data type, or when requested + explicitly using the ``swim-lengths-data`` rollup type + identifier. + + This field is a member of `oneof`_ ``value``. + core_body_temperature (google.devicesandservices.health_v4.types.CoreBodyTemperatureRollupValue): + Returned by default when rolling up data points from the + ``core-body-temperature`` data type, or when requested + explicitly using the ``core-body-temperature`` rollup type + identifier. + + This field is a member of `oneof`_ ``value``. + active_energy_burned (google.devicesandservices.health_v4.types.ActiveEnergyBurnedRollupValue): + Returned by default when rolling up data points from the + ``active-energy-burned`` data type. + + This field is a member of `oneof`_ ``value``. + blood_glucose (google.devicesandservices.health_v4.types.BloodGlucoseRollupValue): + Returned by default when rolling up data points from the + ``blood-glucose`` data type. + + This field is a member of `oneof`_ ``value``. + start_time (google.protobuf.timestamp_pb2.Timestamp): + Start time of the window this value + aggregates over + end_time (google.protobuf.timestamp_pb2.Timestamp): + End time of the window this value aggregates + over + """ + + steps: data_model.StepsRollupValue = proto.Field( + proto.MESSAGE, + number=5, + oneof="value", + message=data_model.StepsRollupValue, + ) + floors: data_model.FloorsRollupValue = proto.Field( + proto.MESSAGE, + number=6, + oneof="value", + message=data_model.FloorsRollupValue, + ) + heart_rate: data_model.HeartRateRollupValue = proto.Field( + proto.MESSAGE, + number=7, + oneof="value", + message=data_model.HeartRateRollupValue, + ) + weight: data_model.WeightRollupValue = proto.Field( + proto.MESSAGE, + number=8, + oneof="value", + message=data_model.WeightRollupValue, + ) + altitude: data_model.AltitudeRollupValue = proto.Field( + proto.MESSAGE, + number=9, + oneof="value", + message=data_model.AltitudeRollupValue, + ) + distance: data_model.DistanceRollupValue = proto.Field( + proto.MESSAGE, + number=10, + oneof="value", + message=data_model.DistanceRollupValue, + ) + body_fat: data_model.BodyFatRollupValue = proto.Field( + proto.MESSAGE, + number=11, + oneof="value", + message=data_model.BodyFatRollupValue, + ) + total_calories: data_model.TotalCaloriesRollupValue = proto.Field( + proto.MESSAGE, + number=12, + oneof="value", + message=data_model.TotalCaloriesRollupValue, + ) + active_zone_minutes: data_model.ActiveZoneMinutesRollupValue = proto.Field( + proto.MESSAGE, + number=13, + oneof="value", + message=data_model.ActiveZoneMinutesRollupValue, + ) + sedentary_period: data_model.SedentaryPeriodRollupValue = proto.Field( + proto.MESSAGE, + number=15, + oneof="value", + message=data_model.SedentaryPeriodRollupValue, + ) + run_vo2_max: data_model.RunVO2MaxRollupValue = proto.Field( + proto.MESSAGE, + number=16, + oneof="value", + message=data_model.RunVO2MaxRollupValue, + ) + calories_in_heart_rate_zone: data_model.CaloriesInHeartRateZoneRollupValue = ( + proto.Field( + proto.MESSAGE, + number=17, + oneof="value", + message=data_model.CaloriesInHeartRateZoneRollupValue, + ) + ) + activity_level: data_model.ActivityLevelRollupValue = proto.Field( + proto.MESSAGE, + number=18, + oneof="value", + message=data_model.ActivityLevelRollupValue, + ) + nutrition_log: data_model.NutritionLogRollupValue = proto.Field( + proto.MESSAGE, + number=19, + oneof="value", + message=data_model.NutritionLogRollupValue, + ) + hydration_log: data_model.HydrationLogRollupValue = proto.Field( + proto.MESSAGE, + number=20, + oneof="value", + message=data_model.HydrationLogRollupValue, + ) + time_in_heart_rate_zone: data_model.TimeInHeartRateZoneRollupValue = proto.Field( + proto.MESSAGE, + number=21, + oneof="value", + message=data_model.TimeInHeartRateZoneRollupValue, + ) + active_minutes: data_model.ActiveMinutesRollupValue = proto.Field( + proto.MESSAGE, + number=22, + oneof="value", + message=data_model.ActiveMinutesRollupValue, + ) + swim_lengths_data: data_model.SwimLengthsDataRollupValue = proto.Field( + proto.MESSAGE, + number=23, + oneof="value", + message=data_model.SwimLengthsDataRollupValue, + ) + core_body_temperature: data_model.CoreBodyTemperatureRollupValue = proto.Field( + proto.MESSAGE, + number=24, + oneof="value", + message=data_model.CoreBodyTemperatureRollupValue, + ) + active_energy_burned: data_model.ActiveEnergyBurnedRollupValue = proto.Field( + proto.MESSAGE, + number=25, + oneof="value", + message=data_model.ActiveEnergyBurnedRollupValue, + ) + blood_glucose: data_model.BloodGlucoseRollupValue = proto.Field( + proto.MESSAGE, + number=26, + oneof="value", + message=data_model.BloodGlucoseRollupValue, + ) + start_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + end_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + + +class DailyRollupDataPoint(proto.Message): + r"""Value of a daily rollup for a single civil time interval + (aggregation window) of reconciled data points from all data + sources, excluding those data points that are identified as + recorded by wearables in intervals when they were not actually + worn. + + 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: + steps (google.devicesandservices.health_v4.types.StepsRollupValue): + Returned by default when rolling up data points from the + ``steps`` data type, or when requested explicitly using the + ``steps`` rollup type identifier. + + This field is a member of `oneof`_ ``value``. + floors (google.devicesandservices.health_v4.types.FloorsRollupValue): + Returned by default when rolling up data points from the + ``floors`` data type, or when requested explicitly using the + ``floors`` rollup type identifier. + + This field is a member of `oneof`_ ``value``. + heart_rate (google.devicesandservices.health_v4.types.HeartRateRollupValue): + Returned by default when rolling up data points from the + ``heart-rate`` data type, or when requested explicitly using + the ``heart-rate`` rollup type identifier. + + This field is a member of `oneof`_ ``value``. + resting_heart_rate_personal_range (google.devicesandservices.health_v4.types.RestingHeartRatePersonalRangeRollupValue): + Returned by default when rolling up data points from the + ``daily-resting-heart-rate`` data type, or when requested + explicitly using the ``resting-heart-rate-personal-range`` + rollup type identifier. + + This field is a member of `oneof`_ ``value``. + heart_rate_variability_personal_range (google.devicesandservices.health_v4.types.HeartRateVariabilityPersonalRangeRollupValue): + Returned by default when rolling up data points from the + ``daily-heart-rate-variability`` data type, or when + requested explicitly using the + ``heart-rate-variability-personal-range`` rollup type + identifier. + + This field is a member of `oneof`_ ``value``. + weight (google.devicesandservices.health_v4.types.WeightRollupValue): + Returned by default when rolling up data points from the + ``weight`` data type, or when requested explicitly using the + ``weight`` rollup type identifier. + + This field is a member of `oneof`_ ``value``. + altitude (google.devicesandservices.health_v4.types.AltitudeRollupValue): + Returned by default when rolling up data points from the + ``altitude`` data type, or when requested explicitly using + the ``altitude`` rollup type identifier. + + This field is a member of `oneof`_ ``value``. + distance (google.devicesandservices.health_v4.types.DistanceRollupValue): + Returned by default when rolling up data points from the + ``distance`` data type, or when requested explicitly using + the ``distance`` rollup type identifier. + + This field is a member of `oneof`_ ``value``. + body_fat (google.devicesandservices.health_v4.types.BodyFatRollupValue): + Returned by default when rolling up data points from the + ``body-fat`` data type, or when requested explicitly using + the ``body-fat`` rollup type identifier. + + This field is a member of `oneof`_ ``value``. + total_calories (google.devicesandservices.health_v4.types.TotalCaloriesRollupValue): + Returned by default when rolling up data points from the + ``total-calories`` data type, or when requested explicitly + using the ``total-calories`` rollup type identifier. + + This field is a member of `oneof`_ ``value``. + active_zone_minutes (google.devicesandservices.health_v4.types.ActiveZoneMinutesRollupValue): + Returned by default when rolling up data points from the + ``active-zone-minutes`` data type, or when requested + explicitly using the ``active-zone-minutes`` rollup type + identifier. + + This field is a member of `oneof`_ ``value``. + sedentary_period (google.devicesandservices.health_v4.types.SedentaryPeriodRollupValue): + Returned by default when rolling up data points from the + ``sedentary-period`` data type, or when requested explicitly + using the ``sedentary-period`` rollup type identifier. + + This field is a member of `oneof`_ ``value``. + run_vo2_max (google.devicesandservices.health_v4.types.RunVO2MaxRollupValue): + Returned by default when rolling up data points from the + ``run-vo2-max`` data type, or when requested explicitly + using the ``run-vo2-max`` rollup type identifier. + + This field is a member of `oneof`_ ``value``. + calories_in_heart_rate_zone (google.devicesandservices.health_v4.types.CaloriesInHeartRateZoneRollupValue): + Returned by default when rolling up data points from the + ``calories-in-heart-rate-zone`` data type, or when requested + explicitly using the ``calories-in-heart-rate-zone`` rollup + type identifier. + + This field is a member of `oneof`_ ``value``. + activity_level (google.devicesandservices.health_v4.types.ActivityLevelRollupValue): + Returned by default when rolling up data points from the + ``activity-level`` data type, or when requested explicitly + using the ``activity-level`` rollup type identifier. + + This field is a member of `oneof`_ ``value``. + nutrition_log (google.devicesandservices.health_v4.types.NutritionLogRollupValue): + Returned by default when rolling up data points from the + ``nutrition-log`` data type, or when requested explicitly + using the ``nutrition-log`` rollup type identifier. + + This field is a member of `oneof`_ ``value``. + hydration_log (google.devicesandservices.health_v4.types.HydrationLogRollupValue): + Returned by default when rolling up data points from the + ``hydration-log`` data type, or when requested explicitly + using the ``hydration-log`` rollup type identifier. + + This field is a member of `oneof`_ ``value``. + time_in_heart_rate_zone (google.devicesandservices.health_v4.types.TimeInHeartRateZoneRollupValue): + Returned by default when rolling up data points from the + ``time-in-heart-rate-zone`` data type, or when requested + explicitly using the ``time-in-heart-rate-zone`` rollup type + identifier. + + This field is a member of `oneof`_ ``value``. + active_minutes (google.devicesandservices.health_v4.types.ActiveMinutesRollupValue): + Returned by default when rolling up data points from the + ``active-minutes`` data type, or when requested explicitly + using the ``active-minutes`` rollup type identifier. + + This field is a member of `oneof`_ ``value``. + swim_lengths_data (google.devicesandservices.health_v4.types.SwimLengthsDataRollupValue): + Returned by default when rolling up data points from the + ``swim-lengths-data`` data type, or when requested + explicitly using the ``swim-lengths-data`` rollup type + identifier. + + This field is a member of `oneof`_ ``value``. + core_body_temperature (google.devicesandservices.health_v4.types.CoreBodyTemperatureRollupValue): + Returned by default when rolling up data points from the + ``core-body-temperature`` data type, or when requested + explicitly using the ``core-body-temperature`` rollup type + identifier. + + This field is a member of `oneof`_ ``value``. + active_energy_burned (google.devicesandservices.health_v4.types.ActiveEnergyBurnedRollupValue): + Returned by default when rolling up data points from the + ``active-energy-burned`` data type. + + This field is a member of `oneof`_ ``value``. + blood_glucose (google.devicesandservices.health_v4.types.BloodGlucoseRollupValue): + Returned by default when rolling up data points from the + ``blood-glucose`` data type. + + This field is a member of `oneof`_ ``value``. + civil_start_time (google.devicesandservices.health_v4.types.CivilDateTime): + Start time of the window this value + aggregates over + civil_end_time (google.devicesandservices.health_v4.types.CivilDateTime): + End time of the window this value aggregates + over + """ + + steps: data_model.StepsRollupValue = proto.Field( + proto.MESSAGE, + number=5, + oneof="value", + message=data_model.StepsRollupValue, + ) + floors: data_model.FloorsRollupValue = proto.Field( + proto.MESSAGE, + number=6, + oneof="value", + message=data_model.FloorsRollupValue, + ) + heart_rate: data_model.HeartRateRollupValue = proto.Field( + proto.MESSAGE, + number=7, + oneof="value", + message=data_model.HeartRateRollupValue, + ) + resting_heart_rate_personal_range: data_model.RestingHeartRatePersonalRangeRollupValue = proto.Field( + proto.MESSAGE, + number=8, + oneof="value", + message=data_model.RestingHeartRatePersonalRangeRollupValue, + ) + heart_rate_variability_personal_range: data_model.HeartRateVariabilityPersonalRangeRollupValue = proto.Field( + proto.MESSAGE, + number=9, + oneof="value", + message=data_model.HeartRateVariabilityPersonalRangeRollupValue, + ) + weight: data_model.WeightRollupValue = proto.Field( + proto.MESSAGE, + number=10, + oneof="value", + message=data_model.WeightRollupValue, + ) + altitude: data_model.AltitudeRollupValue = proto.Field( + proto.MESSAGE, + number=11, + oneof="value", + message=data_model.AltitudeRollupValue, + ) + distance: data_model.DistanceRollupValue = proto.Field( + proto.MESSAGE, + number=12, + oneof="value", + message=data_model.DistanceRollupValue, + ) + body_fat: data_model.BodyFatRollupValue = proto.Field( + proto.MESSAGE, + number=13, + oneof="value", + message=data_model.BodyFatRollupValue, + ) + total_calories: data_model.TotalCaloriesRollupValue = proto.Field( + proto.MESSAGE, + number=14, + oneof="value", + message=data_model.TotalCaloriesRollupValue, + ) + active_zone_minutes: data_model.ActiveZoneMinutesRollupValue = proto.Field( + proto.MESSAGE, + number=15, + oneof="value", + message=data_model.ActiveZoneMinutesRollupValue, + ) + sedentary_period: data_model.SedentaryPeriodRollupValue = proto.Field( + proto.MESSAGE, + number=17, + oneof="value", + message=data_model.SedentaryPeriodRollupValue, + ) + run_vo2_max: data_model.RunVO2MaxRollupValue = proto.Field( + proto.MESSAGE, + number=18, + oneof="value", + message=data_model.RunVO2MaxRollupValue, + ) + calories_in_heart_rate_zone: data_model.CaloriesInHeartRateZoneRollupValue = ( + proto.Field( + proto.MESSAGE, + number=19, + oneof="value", + message=data_model.CaloriesInHeartRateZoneRollupValue, + ) + ) + activity_level: data_model.ActivityLevelRollupValue = proto.Field( + proto.MESSAGE, + number=20, + oneof="value", + message=data_model.ActivityLevelRollupValue, + ) + nutrition_log: data_model.NutritionLogRollupValue = proto.Field( + proto.MESSAGE, + number=21, + oneof="value", + message=data_model.NutritionLogRollupValue, + ) + hydration_log: data_model.HydrationLogRollupValue = proto.Field( + proto.MESSAGE, + number=22, + oneof="value", + message=data_model.HydrationLogRollupValue, + ) + time_in_heart_rate_zone: data_model.TimeInHeartRateZoneRollupValue = proto.Field( + proto.MESSAGE, + number=23, + oneof="value", + message=data_model.TimeInHeartRateZoneRollupValue, + ) + active_minutes: data_model.ActiveMinutesRollupValue = proto.Field( + proto.MESSAGE, + number=24, + oneof="value", + message=data_model.ActiveMinutesRollupValue, + ) + swim_lengths_data: data_model.SwimLengthsDataRollupValue = proto.Field( + proto.MESSAGE, + number=25, + oneof="value", + message=data_model.SwimLengthsDataRollupValue, + ) + core_body_temperature: data_model.CoreBodyTemperatureRollupValue = proto.Field( + proto.MESSAGE, + number=26, + oneof="value", + message=data_model.CoreBodyTemperatureRollupValue, + ) + active_energy_burned: data_model.ActiveEnergyBurnedRollupValue = proto.Field( + proto.MESSAGE, + number=27, + oneof="value", + message=data_model.ActiveEnergyBurnedRollupValue, + ) + blood_glucose: data_model.BloodGlucoseRollupValue = proto.Field( + proto.MESSAGE, + number=28, + oneof="value", + message=data_model.BloodGlucoseRollupValue, + ) + civil_start_time: data_coordinates.CivilDateTime = proto.Field( + proto.MESSAGE, + number=1, + message=data_coordinates.CivilDateTime, + ) + civil_end_time: data_coordinates.CivilDateTime = proto.Field( + proto.MESSAGE, + number=2, + message=data_coordinates.CivilDateTime, + ) + + +class GetDataPointRequest(proto.Message): + r"""Request for getting a single data point + + Attributes: + name (str): + Required. The name of the data point to retrieve. + + Format: + ``users/{user}/dataTypes/{data_type}/dataPoints/{data_point}`` + + See + [DataPoint.name][google.devicesandservices.health.v4.DataPoint.name] + for examples and possible values. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListDataPointsRequest(proto.Message): + r"""Request for listing raw data points + + Attributes: + parent (str): + Required. Parent data type of the Data Point collection. + + Format: ``users/me/dataTypes/{data_type}``, e.g.: + + - ``users/me/dataTypes/steps`` + - ``users/me/dataTypes/weight`` + + For a list of the supported data types see the [DataPoint + data][google.devicesandservices.health.v4.DataPoint] union + field. + page_size (int): + Optional. The maximum number of data points to return. If + unspecified, at most 1440 data points will be returned. The + maximum page size is 10000; values above that will be + truncated accordingly. For ``exercise`` and ``sleep`` the + default page size is 25. The maximum page size for + ``exercise`` and ``sleep`` is 25. + page_token (str): + Optional. The ``next_page_token`` from a previous request, + if any. + filter (str): + Optional. Filter expression following + https://google.aip.dev/160. + + A time range (either physical or civil) can be specified. + + The supported filter fields are: + + - Interval start time: + + - Pattern: ``{interval_data_type}.interval.start_time`` + - Supported comparison operators: ``>=``, ``<`` + - Timestamp literal expected in RFC-3339 format + - Supported logical operators: ``AND`` + - Example: + + - ``steps.interval.start_time >= "2023-11-24T00:00:00Z" AND steps.interval.start_time < "2023-11-25T00:00:00Z"`` + - ``distance.interval.start_time >= "2024-08-14T12:34:56Z"`` + + - Interval civil start time: + + - Pattern: + ``{interval_data_type}.interval.civil_start_time`` + - Supported comparison operators: ``>=``, ``<`` + - Date with optional time literal expected in ISO 8601 + ``YYYY-MM-DD[THH:mm:ss]`` format + - Supported logical operators: ``AND`` + - Example: + + - ``steps.interval.civil_start_time >= "2023-11-24" AND steps.interval.civil_start_time < "2023-11-25"`` + - ``distance.interval.civil_start_time >= "2024-08-14T12:34:56"`` + + - Sample observation physical time: + + - Pattern: + ``{sample_data_type}.sample_time.physical_time`` + - Supported comparison operators: ``>=``, ``<`` + - Timestamp literal expected in RFC-3339 format + - Supported logical operators: ``AND`` + - Example: + + - ``weight.sample_time.physical_time >= "2023-11-24T00:00:00Z" AND weight.sample_time.physical_time < "2023-11-25T00:00:00Z"`` + - ``weight.sample_time.physical_time >= "2024-08-14T12:34:56Z"`` + + - Sample observation civil time: + + - Pattern: ``{sample_data_type}.sample_time.civil_time`` + - Supported comparison operators: ``>=``, ``<`` + - Date with optional time literal expected in ISO 8601 + ``YYYY-MM-DD[THH:mm:ss]`` format + - Supported logical operators: ``AND`` + - Example: + + - ``weight.sample_time.civil_time >= "2023-11-24" AND weight.sample_time.civil_time < "2023-11-25"`` + - ``weight.sample_time.civil_time >= "2024-08-14T12:34:56"`` + + - Daily summary date: + + - Pattern: ``{daily_summary_data_type}.date`` + - Supported comparison operators: ``>=``, ``<`` + - Date literal expected in ISO 8601 ``YYYY-MM-DD`` format + - Supported logical operators: ``AND`` + - Example: + + - ``daily_heart_rate_variability.date < "2024-08-15"`` + + - Session civil start time (**Excluding Sleep and ECG**): + + - Pattern: + ``{session_data_type}.interval.civil_start_time`` + - Supported comparison operators: ``>=``, ``<`` + - Date with optional time literal expected in ISO 8601 + ``YYYY-MM-DD[THH:mm:ss]`` format + - Supported logical operators: ``AND`` + - Example: + + - ``exercise.interval.civil_start_time >= "2023-11-24" AND exercise.interval.civil_start_time < "2023-11-25"`` + - ``exercise.interval.civil_start_time >= "2024-08-14T12:34:56"`` + + - Session start time (**ECG specific**): + + - Pattern: ``electrocardiogram.interval.start_time`` + - Supported comparison operators: ``>=`` + - Timestamp literal expected in RFC-3339 format + - Example: + + - ``electrocardiogram.interval.start_time >= "2024-08-14T12:34:56Z"`` + + - Note: Only filtering by start time is supported for ECG. + Filtering by end time (e.g., + ``electrocardiogram.interval.end_time``) is not + supported. + + - Session end time (**Sleep specific**): + + - Pattern: ``sleep.interval.end_time`` + - Supported comparison operators: ``>=``, ``<`` + - Timestamp literal expected in RFC-3339 format + - Supported logical operators: ``AND``, ``OR`` + - Example: + + - ``sleep.interval.end_time >= "2023-11-24T00:00:00Z" AND sleep.interval.end_time < "2023-11-25T00:00:00Z"`` + + - Session civil end time (**Sleep specific**): + + - Pattern: ``sleep.interval.civil_end_time`` + - Supported comparison operators: ``>=``, ``<`` + - Date with optional time literal expected in ISO 8601 + ``YYYY-MM-DD[THH:mm:ss]`` format + - Supported logical operators: ``AND``, ``OR`` + - Example: + + - ``sleep.interval.civil_end_time >= "2023-11-24" AND sleep.interval.civil_end_time < "2023-11-25"`` + + Data points in the response will be ordered by the interval + start time in descending order. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + + +class ListDataPointsResponse(proto.Message): + r"""Response containing raw data points matching the query + + Attributes: + data_points (MutableSequence[google.devicesandservices.health_v4.types.DataPoint]): + Data points matching the query + next_page_token (str): + Next page token, empty if the response is + complete + """ + + @property + def raw_page(self): + return self + + data_points: MutableSequence["DataPoint"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="DataPoint", + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class CreateDataPointRequest(proto.Message): + r"""Request to create an identifiable data point. + + Attributes: + parent (str): + Required. The parent resource name where the data point will + be created. Format: ``users/{user}/dataTypes/{data_type}`` + data_point (google.devicesandservices.health_v4.types.DataPoint): + Required. The data point to create. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + data_point: "DataPoint" = proto.Field( + proto.MESSAGE, + number=2, + message="DataPoint", + ) + + +class CreateDataPointOperationMetadata(proto.Message): + r"""Metadata for a create data point operation.""" + + +class UpdateDataPointRequest(proto.Message): + r"""Request to update an identifiable data point. + + Attributes: + data_point (google.devicesandservices.health_v4.types.DataPoint): + Required. The data point to update + + The data point's ``name`` field is used to identify the data + point to update. + + Format: + ``users/{user}/dataTypes/{data_type}/dataPoints/{data_point}`` + """ + + data_point: "DataPoint" = proto.Field( + proto.MESSAGE, + number=1, + message="DataPoint", + ) + + +class UpdateDataPointOperationMetadata(proto.Message): + r"""Metadata for an update data point operation.""" + + +class BatchDeleteDataPointsRequest(proto.Message): + r"""Request to delete a batch of identifiable data points. + + Attributes: + parent (str): + Optional. Parent (data type) for the Data Point collection + Format: ``users/me/dataTypes/{data_type}``, e.g.: + + - ``users/me/dataTypes/steps`` + - ``users/me/dataTypes/-`` + + For a list of the supported data types see the [DataPoint + data][google.devicesandservices.health.v4.DataPoint] union + field. + + Deleting data points across multiple data type collections + is supported following https://aip.dev/159. + + If this is set, the parent of all of the data points + specified in ``names`` must match this field. + names (MutableSequence[str]): + Required. The names of the DataPoints to + delete. A maximum of 10000 data points can be + deleted in a single request. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + names: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + +class BatchDeleteDataPointsResponse(proto.Message): + r"""Response containing the list of possibly soft-deleted + DataPoints. + + Attributes: + data_points (MutableSequence[google.devicesandservices.health_v4.types.DataPoint]): + The list of soft-deleted DataPoints, if the + data type supports only soft deletion. + """ + + data_points: MutableSequence["DataPoint"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="DataPoint", + ) + + +class BatchDeleteDataPointsOperationMetadata(proto.Message): + r"""Metadata for a batch delete data points operation. + + Attributes: + failed_requests (MutableMapping[int, google.rpc.status_pb2.Status]): + The key in this map is the index of the request in the + ``requests`` field in the batch request. + """ + + failed_requests: MutableMapping[int, status_pb2.Status] = proto.MapField( + proto.INT32, + proto.MESSAGE, + number=1, + message=status_pb2.Status, + ) + + +class ReconcileDataPointsRequest(proto.Message): + r"""Request to reconcile data points from multiple data sources. + + Attributes: + parent (str): + Required. Parent data type of the Data Point collection. + + Format: ``users/me/dataTypes/{data_type}``, e.g.: + + - ``users/me/dataTypes/steps`` + - ``users/me/dataTypes/heart-rate`` + + For a list of the supported data types see the [DataPoint + data][google.devicesandservices.health.v4.DataPoint] union + field. + page_size (int): + Optional. The maximum number of data points to return. If + unspecified, at most 1440 data points will be returned. The + maximum page size is 10000; values above that will be + truncated accordingly. For ``exercise`` and ``sleep`` the + default page size is 25. The maximum page size for + ``exercise`` and ``sleep`` is 25. + page_token (str): + Optional. The ``next_page_token`` from a previous request, + if any. + filter (str): + Optional. Filter expression based on https://aip.dev/160. + + A time range, either physical or civil, can be specified. + See the + [ListDataPointsRequest.filter][google.devicesandservices.health.v4.ListDataPointsRequest.filter] + for the supported fields and syntax. + data_source_family (str): + Optional. The data source family name to reconcile. + + If empty, data points from all data sources will be + reconciled. + + Format: ``users/me/dataSourceFamilies/{data_source_family}`` + + The supported values are: + + - ``users/me/dataSourceFamilies/all-sources`` - default + value + - ``users/me/dataSourceFamilies/google-wearables`` - tracker + devices + - ``users/me/dataSourceFamilies/google-sources`` - Google + first party sources + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + data_source_family: str = proto.Field( + proto.STRING, + number=5, + ) + + +class ReconcileDataPointsResponse(proto.Message): + r"""Response containing the list of reconciled DataPoints. + + Attributes: + data_points (MutableSequence[google.devicesandservices.health_v4.types.ReconciledDataPoint]): + Data points matching the query + next_page_token (str): + Next page token, empty if the response is + complete + """ + + @property + def raw_page(self): + return self + + data_points: MutableSequence["ReconciledDataPoint"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="ReconciledDataPoint", + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class RollUpDataPointsRequest(proto.Message): + r"""Request to roll up data points by physical time intervals. + + Attributes: + parent (str): + Required. Parent data type of the Data Point collection. + + Format: ``users/{user}/dataTypes/{data_type}``, e.g.: + + - ``users/me/dataTypes/steps`` + - ``users/me/dataTypes/distance`` + + For a list of the supported data types see the + [RollupDataPoint + value][google.devicesandservices.health.v4.RollupDataPoint] + union field. + range_ (google.type.interval_pb2.Interval): + Required. Closed-open range of data points that will be + rolled up. The maximum range for + ``calories-in-heart-rate-zone``, ``heart-rate``, + ``active-minutes`` and ``total-calories`` is 14 days. The + maximum range for all other data types is 90 days. + window_size (google.protobuf.duration_pb2.Duration): + Required. The size of the time window to + group data points into before applying the + aggregation functions. + page_size (int): + Optional. The maximum number of data points + to return. If unspecified, at most 1440 data + points will be returned. The maximum page size + is 10000; values above that will be truncated + accordingly. + page_token (str): + Optional. The next_page_token from a previous request, if + any. All other request fields need to be the same as in the + initial request when the page token is specified. + data_source_family (str): + Optional. The data source family name to roll up. + + If empty, data points from all available data sources will + be rolled up. + + Format: ``users/me/dataSourceFamilies/{data_source_family}`` + + The supported values are: + + - ``users/me/dataSourceFamilies/all-sources`` - default + value + - ``users/me/dataSourceFamilies/google-wearables`` - tracker + devices + - ``users/me/dataSourceFamilies/google-sources`` - Google + first party sources + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + range_: interval_pb2.Interval = proto.Field( + proto.MESSAGE, + number=2, + message=interval_pb2.Interval, + ) + window_size: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=3, + message=duration_pb2.Duration, + ) + page_size: int = proto.Field( + proto.INT32, + number=4, + ) + page_token: str = proto.Field( + proto.STRING, + number=5, + ) + data_source_family: str = proto.Field( + proto.STRING, + number=7, + ) + + +class RollUpDataPointsResponse(proto.Message): + r"""Response containing the list of rolled up data points. + + Attributes: + rollup_data_points (MutableSequence[google.devicesandservices.health_v4.types.RollupDataPoint]): + Values for each aggregation time window. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + """ + + @property + def raw_page(self): + return self + + rollup_data_points: MutableSequence["RollupDataPoint"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="RollupDataPoint", + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class DailyRollUpDataPointsRequest(proto.Message): + r"""Request to roll up data points by civil time intervals. + + Attributes: + parent (str): + Required. Parent data type of the Data Point collection. + + Format: ``users/{user}/dataTypes/{data_type}``, e.g.: + + - ``users/me/dataTypes/steps`` + - ``users/me/dataTypes/distance`` + + For a list of the supported data types see the + [DailyRollupDataPoint + value][google.devicesandservices.health.v4.DailyRollupDataPoint] + union field. + range_ (google.devicesandservices.health_v4.types.CivilTimeInterval): + Required. Closed-open range of data points that will be + rolled up. The start time must be aligned with the + aggregation window. The maximum range for + ``calories-in-heart-rate-zone``, ``heart-rate``, + ``active-minutes`` and ``total-calories`` is 14 days. The + maximum range for all other data types is 90 days. + window_size_days (int): + Optional. Aggregation window size, in number + of days. Defaults to 1 if not specified. + page_size (int): + Optional. The maximum number of data points + to return. If unspecified, at most 1440 data + points will be returned. The maximum page size + is 10000; values above that will be truncated + accordingly. + page_token (str): + Optional. The ``next_page_token`` from a previous request, + if any. All other request fields need to be the same as in + the initial request when the page token is specified. + data_source_family (str): + Optional. The data source family name to roll up. If empty, + data points from all available data sources will be rolled + up. + + Format: ``users/me/dataSourceFamilies/{data_source_family}`` + + The supported values are: + + - ``users/me/dataSourceFamilies/all-sources`` - default + value + - ``users/me/dataSourceFamilies/google-wearables`` - tracker + devices + - ``users/me/dataSourceFamilies/google-sources`` - Google + first party sources + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + range_: data_coordinates.CivilTimeInterval = proto.Field( + proto.MESSAGE, + number=2, + message=data_coordinates.CivilTimeInterval, + ) + window_size_days: int = proto.Field( + proto.INT32, + number=3, + ) + page_size: int = proto.Field( + proto.INT32, + number=4, + ) + page_token: str = proto.Field( + proto.STRING, + number=5, + ) + data_source_family: str = proto.Field( + proto.STRING, + number=7, + ) + + +class DailyRollUpDataPointsResponse(proto.Message): + r"""Response containing the list of rolled up data points. + + Attributes: + rollup_data_points (MutableSequence[google.devicesandservices.health_v4.types.DailyRollupDataPoint]): + Values for each aggregation time window. + """ + + rollup_data_points: MutableSequence["DailyRollupDataPoint"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="DailyRollupDataPoint", + ) + + +class DataType(proto.Message): + r"""Represents a type of health data a user can have data points + recorded for. It matches the parent resource of collection + containing data points of the given type. + + Clients currently do not need to interact with this resource + directly. + + Attributes: + name (str): + Identifier. The resource name of the data type. + + Format: ``users/{user}/dataTypes/{data_type}`` + + See + [DataPoint.name][google.devicesandservices.health.v4.DataPoint.name] + for examples and possible values. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ExportExerciseTcxRequest(proto.Message): + r"""Represents a request to export exercise data in TCX format. + + Attributes: + name (str): + Required. The resource name of the exercise data point to + export. + + Format: + ``users/{user}/dataTypes/exercise/dataPoints/{data_point}`` + Example: + ``users/me/dataTypes/exercise/dataPoints/2026443605080188808`` + + The ``{user}`` is the alias ``"me"`` currently. Future + versions may support user IDs. The ``{data_point}`` ID maps + to the exercise ID, which is a long integer. + partial_data (bool): + Optional. Indicates whether to include the TCX data points + when the GPS data is not available. If not specified, + defaults to ``false`` and partial data will not be included. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + partial_data: bool = proto.Field( + proto.BOOL, + number=2, + ) + + +class ExportExerciseTcxResponse(proto.Message): + r"""Represents a Response for exporting exercise data in TCX + format. + + Attributes: + tcx_data (str): + Contains the exported TCX data. + + This field is intended for gRPC clients, as media download + integration is not supported for gRPC. HTTP clients should + instead use the ``alt=media`` query parameter to download + the raw binary TCX file. + """ + + tcx_data: str = proto.Field( + proto.STRING, + number=2, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/data_source.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/data_source.py new file mode 100644 index 000000000000..e3022a0e2263 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/data_source.py @@ -0,0 +1,256 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.devicesandservices.health.v4", + manifest={ + "DataSource", + }, +) + + +class DataSource(proto.Message): + r"""Data Source definition to track the origin of data. + + Each health data point, regardless of the complexity or data + model (whether a simple step count or a detailed sleep session) + must retain information about its source of origin (e.g. the + device or app that collected it). + + Attributes: + recording_method (google.devicesandservices.health_v4.types.DataSource.RecordingMethod): + Optional. Captures how the data was recorded. + device (google.devicesandservices.health_v4.types.DataSource.Device): + Optional. Captures metadata for raw data + points originating from devices. We expect this + data source to be used for data points written + on device sync. + application (google.devicesandservices.health_v4.types.DataSource.Application): + Output only. Captures metadata for the + application that provided this data. + platform (google.devicesandservices.health_v4.types.DataSource.Platform): + Output only. Captures the platform that + uploaded the data. + """ + + class RecordingMethod(proto.Enum): + r"""The method by which the data was recorded. + + Values: + RECORDING_METHOD_UNSPECIFIED (0): + The recording method is unspecified. + MANUAL (1): + The data was manually entered by the user. + PASSIVELY_MEASURED (2): + The data was passively measured by a device. + DERIVED (3): + The data was derived from other data, e.g., + by an algorithm in the backend. + ACTIVELY_MEASURED (4): + The data was actively measured by a device. + UNKNOWN (5): + The recording method is unknown. This is set + when the data is uploaded from a third party app + that does not provide this information. + """ + + RECORDING_METHOD_UNSPECIFIED = 0 + MANUAL = 1 + PASSIVELY_MEASURED = 2 + DERIVED = 3 + ACTIVELY_MEASURED = 4 + UNKNOWN = 5 + + class Platform(proto.Enum): + r"""The platform that uploaded the data. + Additional values may be added in the future. Clients should be + prepared to handle unknown values gracefully. + + Values: + PLATFORM_UNSPECIFIED (0): + The platform is unspecified. + FITBIT (1): + The data was uploaded from Fitbit. + HEALTH_CONNECT (2): + The data was uploaded from Health Connect. + HEALTH_KIT (3): + The data was uploaded from Health Kit. + FIT (4): + The data was uploaded from Google Fit. + FITBIT_WEB_API (5): + The data was uploaded from Fitbit legacy Web + API. + NEST (6): + The data was uploaded from Nest devices. + GOOGLE_WEB_API (7): + The data was uploaded from Google Health API. + GOOGLE_PARTNER_INTEGRATION (8): + The data was uploaded from Google Partner + Integrations. + """ + + PLATFORM_UNSPECIFIED = 0 + FITBIT = 1 + HEALTH_CONNECT = 2 + HEALTH_KIT = 3 + FIT = 4 + FITBIT_WEB_API = 5 + NEST = 6 + GOOGLE_WEB_API = 7 + GOOGLE_PARTNER_INTEGRATION = 8 + + class Device(proto.Message): + r"""Captures metadata about the device that recorded the + measurement. + + Attributes: + form_factor (google.devicesandservices.health_v4.types.DataSource.Device.FormFactor): + Optional. Captures the form factor of the + device. + manufacturer (str): + Optional. An optional manufacturer of the + device. + display_name (str): + Optional. An optional name for the device. + """ + + class FormFactor(proto.Enum): + r"""Form factor of the device, e.g. phone, watch, band, etc. + + Values: + FORM_FACTOR_UNSPECIFIED (0): + The form factor is unspecified. + FITNESS_BAND (1): + The device is a fitness band. + WATCH (2): + The device is a watch. + PHONE (3): + The device is a phone. + RING (4): + The device is a ring. + CHEST_STRAP (5): + The device is a chest strap. + SCALE (6): + The device is a scale. + TABLET (7): + The device is a tablet. + HEAD_MOUNTED (8): + The device is a head mounted device. + SMART_DISPLAY (9): + The device is a smart display. + """ + + FORM_FACTOR_UNSPECIFIED = 0 + FITNESS_BAND = 1 + WATCH = 2 + PHONE = 3 + RING = 4 + CHEST_STRAP = 5 + SCALE = 6 + TABLET = 7 + HEAD_MOUNTED = 8 + SMART_DISPLAY = 9 + + form_factor: "DataSource.Device.FormFactor" = proto.Field( + proto.ENUM, + number=1, + enum="DataSource.Device.FormFactor", + ) + manufacturer: str = proto.Field( + proto.STRING, + number=2, + ) + display_name: str = proto.Field( + proto.STRING, + number=3, + ) + + class Application(proto.Message): + r"""Optional metadata for the application that provided this + data. + + Attributes: + package_name (str): + Output only. A unique identifier for the mobile application + that was the source of the data. + + This is typically the application's package name on Android + (e.g., ``com.google.fitbit``) or the bundle ID on iOS. This + field is informational and helps trace data origin. This + field is system-populated when the data is uploaded from the + Fitbit mobile application, Health Connect or Health Kit. + web_client_id (str): + Output only. The client ID of the application that recorded + the data. + + This ID is a legacy Fitbit API client ID, which is different + from a Google OAuth client ID. Example format: ``ABC123``. + This field is system-populated and used for tracing data + from legacy Fitbit API integrations. This field is + system-populated when the data is uploaded from a legacy + Fitbit API integration. + google_web_client_id (str): + Output only. The Google OAuth 2.0 client ID + of the web application or service that recorded + the data. + + This is the client ID used during the Google + OAuth flow to obtain user credentials. This + field is system-populated when the data is + uploaded from Google Web API. + """ + + package_name: str = proto.Field( + proto.STRING, + number=1, + ) + web_client_id: str = proto.Field( + proto.STRING, + number=2, + ) + google_web_client_id: str = proto.Field( + proto.STRING, + number=3, + ) + + recording_method: RecordingMethod = proto.Field( + proto.ENUM, + number=1, + enum=RecordingMethod, + ) + device: Device = proto.Field( + proto.MESSAGE, + number=2, + message=Device, + ) + application: Application = proto.Field( + proto.MESSAGE, + number=3, + message=Application, + ) + platform: Platform = proto.Field( + proto.ENUM, + number=4, + enum=Platform, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/data_subscription_service.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/data_subscription_service.py new file mode 100644 index 000000000000..9d82c528389a --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/data_subscription_service.py @@ -0,0 +1,692 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import google.protobuf.field_mask_pb2 as field_mask_pb2 # type: ignore +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.devicesandservices.health.v4", + manifest={ + "CreateSubscriberRequest", + "ListSubscribersRequest", + "ListSubscribersResponse", + "UpdateSubscriberRequest", + "DeleteSubscriberRequest", + "CreateSubscriptionRequest", + "ListSubscriptionsRequest", + "ListSubscriptionsResponse", + "UpdateSubscriptionRequest", + "DeleteSubscriptionRequest", + "Subscriber", + "Subscription", + "SubscriberConfig", + "EndpointAuthorization", + "CreateSubscriberPayload", + "CreateSubscriptionPayload", + "CreateSubscriberMetadata", + "UpdateSubscriberMetadata", + "DeleteSubscriberMetadata", + }, +) + + +class CreateSubscriberRequest(proto.Message): + r"""-- Messages -- + Request message for CreateSubscriber. + + Attributes: + parent (str): + Required. The parent resource where this + subscriber will be created. Format: + projects/{project} Example: + projects/my-project-123 + subscriber (google.devicesandservices.health_v4.types.CreateSubscriberPayload): + Required. The subscriber to create. + subscriber_id (str): + Optional. The ID to use for the subscriber, which will + become the final component of the subscriber's resource + name. + + This value should be 4-36 characters, and valid characters + are /`a-z <[a-z0-9-]{2,34}[a-z0-9]>`__/. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + subscriber: "CreateSubscriberPayload" = proto.Field( + proto.MESSAGE, + number=2, + message="CreateSubscriberPayload", + ) + subscriber_id: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListSubscribersRequest(proto.Message): + r"""Request message for ListSubscribers. + + Attributes: + parent (str): + Required. The parent, which owns this + collection of subscribers. Format: + projects/{project} + page_size (int): + Optional. The maximum number of subscribers + to return. The service may return fewer than + this value. If unspecified, at most 50 + subscribers will be returned. The maximum value + is 1000; values above 1000 will be coerced to + 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListSubscribers`` call. Provide this to retrieve the + subsequent page. When paginating, all other parameters + provided to ``ListSubscribers`` must match the call that + provided the page token. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListSubscribersResponse(proto.Message): + r"""Response message for ListSubscribers. + + Attributes: + subscribers (MutableSequence[google.devicesandservices.health_v4.types.Subscriber]): + Subscribers from the specified project. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + total_size (int): + The total number of subscribers matching the + request. + """ + + @property + def raw_page(self): + return self + + subscribers: MutableSequence["Subscriber"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="Subscriber", + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + total_size: int = proto.Field( + proto.INT32, + number=3, + ) + + +class UpdateSubscriberRequest(proto.Message): + r"""Request message for UpdateSubscriber. + + Attributes: + subscriber (google.devicesandservices.health_v4.types.Subscriber): + Required. The subscriber resource to update. Its 'name' + field is mapped to the URI, and the value of the 'name' + field should be of the form: + "projects/{project}/subscribers/{subscriber_id}". The + remaining fields of the Subscriber object represent the new + values for the corresponding fields in the existing + subscriber resource. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Optional. A field mask that specifies which fields of the + Subscriber message are to be updated. This allows for + partial updates. Supported fields: + + - endpoint_uri + - subscriber_configs + - endpoint_authorization + """ + + subscriber: "Subscriber" = proto.Field( + proto.MESSAGE, + number=1, + message="Subscriber", + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class DeleteSubscriberRequest(proto.Message): + r"""Request message for DeleteSubscriber. + + Attributes: + name (str): + Required. The name of the subscriber to delete. Format: + projects/{project}/subscribers/{subscriber} Example: + projects/my-project/subscribers/my-subscriber-123 The + {subscriber} ID is user-settable (4-36 characters, matching + /`a-z <[a-z0-9-]{2,34}[a-z0-9]>`__/) or system-generated if + not provided during creation. + force (bool): + Optional. If set to true, any child resources + (e.g., subscriptions) will also be deleted. If + false (default) and child resources exist, the + request will fail. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + force: bool = proto.Field( + proto.BOOL, + number=2, + ) + + +class CreateSubscriptionRequest(proto.Message): + r"""Request message for CreateSubscription. + + Attributes: + parent (str): + Required. The parent subscriber. Format: + projects/{project}/subscribers/{subscriber} The {subscriber} + ID is user-settable (4-36 characters, matching + /`a-z <[a-z0-9-]{2,34}[a-z0-9]>`__/) if provided during + creation, or system-generated otherwise. + subscription_id (str): + Optional. The {subscription_id} is user-settable (4-36 + chars, matching /`a-z <[a-z0-9-]{2,34}[a-z0-9]>`__/) or + system-generated otherwise. If provided, the ID must be + unique within the parent subscriber. + subscription (google.devicesandservices.health_v4.types.CreateSubscriptionPayload): + Required. The subscription to create. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + subscription_id: str = proto.Field( + proto.STRING, + number=2, + ) + subscription: "CreateSubscriptionPayload" = proto.Field( + proto.MESSAGE, + number=3, + message="CreateSubscriptionPayload", + ) + + +class ListSubscriptionsRequest(proto.Message): + r"""Request message for ListSubscriptions. + + Attributes: + parent (str): + Required. The parent subscriber. Format: + projects/{project}/subscribers/{subscriber} The {subscriber} + ID is user-settable (4-36 characters, matching + /`a-z <[a-z0-9-]{2,34}[a-z0-9]>`__/) if provided during + creation, or system-generated otherwise. + filter (str): + Optional. A filter to apply to the list of subscriptions. + The filter syntax is described in + https://google.aip.dev/160. The filter can be applied to the + following fields: + + - ``user`` + - ``data_type`` + + The ``user`` identifier (e.g., ``user1`` in ``users/user1``) + refers to the public ``healthUserId`` + + Example: user = "users/user1" Example: user = "users/user1" + OR user = "users/user2" Example: user = "users/user1" AND + (data_type = "sleep" OR data_type = "weight") + page_size (int): + Optional. The maximum number of subscriptions + to return. The service may return fewer than + this value. If unspecified, at most 50 + subscriptions will be returned. The maximum + value is 1000; values above 1000 will be coerced + to 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListSubscriptions`` call. Provide this to retrieve the + subsequent page. When paginating, all other parameters + provided to ``ListSubscriptions`` must match the call that + provided the page token. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + filter: str = proto.Field( + proto.STRING, + number=2, + ) + page_size: int = proto.Field( + proto.INT32, + number=3, + ) + page_token: str = proto.Field( + proto.STRING, + number=4, + ) + + +class ListSubscriptionsResponse(proto.Message): + r"""Response message for ListSubscriptions. + + Attributes: + subscriptions (MutableSequence[google.devicesandservices.health_v4.types.Subscription]): + The subscriptions from the specified + subscriber. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + """ + + @property + def raw_page(self): + return self + + subscriptions: MutableSequence["Subscription"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="Subscription", + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class UpdateSubscriptionRequest(proto.Message): + r"""Request message for UpdateSubscription. + + Attributes: + subscription (google.devicesandservices.health_v4.types.Subscription): + Required. The subscription to update. The subscription's + ``name`` field is used to identify the subscription to + update. Format: + projects/{project}/subscribers/{subscriber}/subscriptions/{subscription} + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Optional. The list of fields to update. + """ + + subscription: "Subscription" = proto.Field( + proto.MESSAGE, + number=1, + message="Subscription", + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class DeleteSubscriptionRequest(proto.Message): + r"""Request message for DeleteSubscription. + + Attributes: + name (str): + Required. The resource name of the subscription to delete. + Format: + ``projects/{project}/subscribers/{subscriber}/subscriptions/{subscription}`` + Example: + ``projects/my-project/subscribers/my-subscriber-123/subscriptions/my-subscription-456`` + The {subscriber} ID is user-settable (4-36 characters, + matching /`a-z <[a-z0-9-]{2,34}[a-z0-9]>`__/) if provided + during creation, or system-generated otherwise. The + {subscription} ID is user-settable (4-36 characters, + matching /`a-z <[a-z0-9-]{2,34}[a-z0-9]>`__/) or + system-generated if not provided during creation. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class Subscriber(proto.Message): + r"""-- Resource Messages -- + A subscriber receives notifications from Google Health API. + + Attributes: + name (str): + Identifier. The resource name of the Subscriber. Format: + projects/{project}/subscribers/{subscriber} The {project} ID + is a Google Cloud Project ID or Project Number. The + {subscriber} ID is user-settable (4-36 characters, matching + /`a-z <[a-z0-9-]{2,34}[a-z0-9]>`__/) if provided during + creation, or system-generated otherwise (e.g., a UUID). + Example (User-settable subscriber ID): + projects/my-project/subscribers/my-sub-123 Example + (System-generated subscriber ID): + projects/my-project/subscribers/a1b2c3d4-e5f6-7890-1234-567890abcdef + endpoint_uri (str): + Required. The full HTTPS URI where update + notifications will be sent. The URI must be a + valid URL and use HTTPS as the scheme. This + endpoint will be verified during + CreateSubscriber and UpdateSubscriber calls. See + RPC documentation for verification details. + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time at which the subscriber + was created. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time at which the subscriber + was last updated. + subscriber_configs (MutableSequence[google.devicesandservices.health_v4.types.SubscriberConfig]): + Optional. Configuration for the subscriber. + endpoint_authorization (google.devicesandservices.health_v4.types.EndpointAuthorization): + Required. Authorization mechanism for a + subscriber endpoint. This is required to ensure + the endpoint can be verified. + state (google.devicesandservices.health_v4.types.Subscriber.State): + Output only. The state of the subscriber. + """ + + class State(proto.Enum): + r"""The state of the subscriber. + + Values: + STATE_UNSPECIFIED (0): + Represents an unspecified subscriber state. + UNVERIFIED (1): + Represents an unverified subscriber. This is the initial + state of the subscriber when it is created. The backend will + verify the subscriber's endpoint_uri. + ACTIVE (2): + Represents an active subscriber. The endpoint + has been verified. + INACTIVE (3): + Represents an inactive subscriber. + """ + + STATE_UNSPECIFIED = 0 + UNVERIFIED = 1 + ACTIVE = 2 + INACTIVE = 3 + + name: str = proto.Field( + proto.STRING, + number=1, + ) + endpoint_uri: str = proto.Field( + proto.STRING, + number=2, + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=4, + message=timestamp_pb2.Timestamp, + ) + subscriber_configs: MutableSequence["SubscriberConfig"] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message="SubscriberConfig", + ) + endpoint_authorization: "EndpointAuthorization" = proto.Field( + proto.MESSAGE, + number=7, + message="EndpointAuthorization", + ) + state: State = proto.Field( + proto.ENUM, + number=6, + enum=State, + ) + + +class Subscription(proto.Message): + r"""A subscription to a data collection for a specific user, to + be delivered to a subscriber. + + Attributes: + name (str): + Identifier. The resource name of the Subscription. Format: + ``projects/{project}/subscribers/{subscriber}/subscriptions/{subscription}`` + Example: + ``projects/my-project/subscribers/my-subscriber-123/subscriptions/my-subscription-456`` + The {project} ID is mandatory (6-30 characters, matching + /[a-z][a-z0-9-]{6,30}/) The {subscriber} ID is user-settable + (4-36 characters, matching + /`a-z <[a-z0-9-]{2,34}[a-z0-9]>`__/) if provided during + creation, or system-generated otherwise. The {subscription} + ID is user-settable (4-36 chars, matching + /`a-z <[a-z0-9-]{2,34}[a-z0-9]>`__/) or system-generated + otherwise. + data_types (MutableSequence[str]): + Optional. Data types subscribed to. + A subscriber will only receive notifications for + data types that are declared here. + A subscription can only subscribe to the data + types of the subscriber. Supported data types + are: "altitude", "distance", "floors", "sleep", + "steps", "weight". + user (str): + Immutable. The resource name of the user for whom this + subscription is active. Format: ``users/{user}`` where + ``{user}`` is the public ``healthUserId`` as returned by the + ``GetIdentity`` action in the profile PAPI (see + ``google.devicesandservices.health.v4main.HealthProfileService.GetIdentity``). + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + data_types: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + user: str = proto.Field( + proto.STRING, + number=3, + ) + + +class SubscriberConfig(proto.Message): + r"""Configuration for a subscriber. + A notification is sent to a subscription ONLY if the subscriber + has a config for the data type. + + Attributes: + data_types (MutableSequence[str]): + Required. See `Google Health API data + types `__ + for the list of supported data types. Values should be in + kebab-case. + subscription_create_policy (google.devicesandservices.health_v4.types.SubscriberConfig.SubscriptionCreatePolicy): + Required. Policy for subscription creation. + """ + + class SubscriptionCreatePolicy(proto.Enum): + r"""Policy for subscription creation. + + Values: + SUBSCRIPTION_CREATE_POLICY_UNSPECIFIED (0): + Represents an unspecified policy. + AUTOMATIC (1): + When using ``AUTOMATIC``, individual subscriptions are not + created or stored. Instead, eligibility for notifications is + computed dynamically. When a data update occurs for a given + data type, notifications are sent to all subscribers with an + ``AUTOMATIC`` policy for that data type, provided the user + has granted the necessary consents. + + This means you do not need to call ``CreateSubscription`` + for each user; notifications are managed automatically based + on user consents. As ``Subscription`` resources are not + stored, they cannot be retrieved or managed through + ``GetSubscription``, ``ListSubscriptions``, + ``UpdateSubscription``, or ``DeleteSubscription``. + MANUAL (2): + Requires subscriptions to be created manually + for new users. The developer needs to call + CreateSubscription for new users. + """ + + SUBSCRIPTION_CREATE_POLICY_UNSPECIFIED = 0 + AUTOMATIC = 1 + MANUAL = 2 + + data_types: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + subscription_create_policy: SubscriptionCreatePolicy = proto.Field( + proto.ENUM, + number=2, + enum=SubscriptionCreatePolicy, + ) + + +class EndpointAuthorization(proto.Message): + r"""Authorization mechanism for a subscriber endpoint. For all requests + sent by the Webhooks service, the JSON payload is cryptographically + signed. The signature is delivered in the ``X-HEALTHAPI-SIGNATURE`` + HTTP header. This is an ECDSA (NIST P256) signature of the JSON + payload. Clients must verify this signature using Google Health + API's public key to confirm the payload was sent by the Health API. + + Attributes: + secret (str): + Required. Input only. Provides a client-provided secret that + will be sent with each notification to the subscriber + endpoint using the "Authorization" header. The value must + include the authorization scheme, e.g., "Bearer " or "Basic + ", as it will be used as the full Authorization header + value. This secret is used by the API to test the endpoint + during ``CreateSubscriber`` and ``UpdateSubscriber`` calls, + and will be sent in the ``Authorization`` header for all + subsequent webhook notifications to this endpoint. + secret_set (bool): + Output only. Whether the secret is set. + """ + + secret: str = proto.Field( + proto.STRING, + number=1, + ) + secret_set: bool = proto.Field( + proto.BOOL, + number=2, + ) + + +class CreateSubscriberPayload(proto.Message): + r"""Payload for creating a subscriber. + + Attributes: + endpoint_uri (str): + Required. The full HTTPS URI where update notifications will + be sent. The URI must be a valid URL and use HTTPS as the + scheme. This endpoint will be verified during the + ``CreateSubscriber`` call. See CreateSubscriber RPC + documentation for verification details. + subscriber_configs (MutableSequence[google.devicesandservices.health_v4.types.SubscriberConfig]): + Optional. Configuration for the subscriber. + endpoint_authorization (google.devicesandservices.health_v4.types.EndpointAuthorization): + Required. Authorization mechanism for the subscriber + endpoint. The ``secret`` within this message is crucial for + endpoint verification and for securing webhook + notifications. + """ + + endpoint_uri: str = proto.Field( + proto.STRING, + number=1, + ) + subscriber_configs: MutableSequence["SubscriberConfig"] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="SubscriberConfig", + ) + endpoint_authorization: "EndpointAuthorization" = proto.Field( + proto.MESSAGE, + number=3, + message="EndpointAuthorization", + ) + + +class CreateSubscriptionPayload(proto.Message): + r"""Payload for creating a subscription. + + Attributes: + data_types (MutableSequence[str]): + Optional. Data types subscribed to. + user (str): + Required. Immutable. The resource name of the user for whom + this subscription is active. Format: ``users/{user}`` where + ``{user}`` is the public ``healthUserId`` as returned by the + ``GetIdentity`` action in the profile PAPI (see + ``google.devicesandservices.health.v4main.HealthProfileService.GetIdentity``). + """ + + data_types: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + user: str = proto.Field( + proto.STRING, + number=2, + ) + + +class CreateSubscriberMetadata(proto.Message): + r"""Represents metadata for creating a subscriber.""" + + +class UpdateSubscriberMetadata(proto.Message): + r"""Represents metadata for updating a subscriber.""" + + +class DeleteSubscriberMetadata(proto.Message): + r"""Represents metadata for deleting a subscriber.""" + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/health_profile.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/health_profile.py new file mode 100644 index 000000000000..dc5bdafd2369 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/health_profile.py @@ -0,0 +1,977 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import google.protobuf.duration_pb2 as duration_pb2 # type: ignore +import google.protobuf.field_mask_pb2 as field_mask_pb2 # type: ignore +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore +import google.type.date_pb2 as date_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.devicesandservices.health.v4", + manifest={ + "User", + "Profile", + "PairedDevice", + "IrnProfile", + "Settings", + "Identity", + "GetProfileRequest", + "GetIrnProfileRequest", + "UpdateProfileRequest", + "GetSettingsRequest", + "UpdateSettingsRequest", + "GetIdentityRequest", + "GetPairedDeviceRequest", + "ListPairedDevicesRequest", + "ListPairedDevicesResponse", + }, +) + + +class User(proto.Message): + r"""Represents a user in the Google Health API. + It matches the parent resource of collections owned by the user. + + Clients currently do not need to interact with this resource + directly. + + Attributes: + name (str): + Identifier. The resource name of the user. + + The ``{user}`` ID is a system-generated identifier, as + described in + [Identity.health_user_id][google.devicesandservices.health.v4.Identity.health_user_id]. + + Format: ``users/{user}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class Profile(proto.Message): + r"""Profile details. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + name (str): + Identifier. The resource name of this Profile resource. + + Format: ``users/{user}/profile`` Example: + ``users/1234567890/profile`` or ``users/me/profile`` The + {user} ID is a system-generated Google Health API user ID, a + string of 1-63 characters consisting of lowercase and + uppercase letters, numbers, and hyphens. The literal ``me`` + can also be used to refer to the authenticated user. + age (int): + Optional. The age in years based on the + user's birth date. + Updates to this field are currently not + supported. + membership_start_date (google.type.date_pb2.Date): + Output only. The date the user created their + account. + Updates to this field are currently not + supported. + user_configured_walking_stride_length_mm (int): + Optional. The user's user configured walking stride length, + in millimeters. + + The user must consent to one of the following access scopes + to access this field: + + - + + ``https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly`` + + - ``https://www.googleapis.com/auth/googlehealth.activity_and_fitness`` + + This field is a member of `oneof`_ ``_user_configured_walking_stride_length_mm``. + user_configured_running_stride_length_mm (int): + Optional. The user's user configured running stride length, + in millimeters. + + The user must consent to one of the following access scopes + to access this field: + + - + + ``https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly`` + + - ``https://www.googleapis.com/auth/googlehealth.activity_and_fitness`` + + This field is a member of `oneof`_ ``_user_configured_running_stride_length_mm``. + auto_walking_stride_length_mm (int): + Output only. The automatically calculated walking stride + length, in millimeters. + + The user must consent to one of the following access scopes + to access this field: + + - + + ``https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly`` + + - ``https://www.googleapis.com/auth/googlehealth.activity_and_fitness`` + + This field is a member of `oneof`_ ``_auto_walking_stride_length_mm``. + auto_running_stride_length_mm (int): + Output only. The automatically calculated running stride + length, in millimeters. + + The user must consent to one of the following access scopes + to access this field: + + - + + ``https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly`` + + - ``https://www.googleapis.com/auth/googlehealth.activity_and_fitness`` + + This field is a member of `oneof`_ ``_auto_running_stride_length_mm``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + age: int = proto.Field( + proto.INT32, + number=6, + ) + membership_start_date: date_pb2.Date = proto.Field( + proto.MESSAGE, + number=9, + message=date_pb2.Date, + ) + user_configured_walking_stride_length_mm: int = proto.Field( + proto.INT32, + number=13, + optional=True, + ) + user_configured_running_stride_length_mm: int = proto.Field( + proto.INT32, + number=14, + optional=True, + ) + auto_walking_stride_length_mm: int = proto.Field( + proto.INT32, + number=15, + optional=True, + ) + auto_running_stride_length_mm: int = proto.Field( + proto.INT32, + number=16, + optional=True, + ) + + +class PairedDevice(proto.Message): + r"""User's Paired 1P Device + + The PairedDevice details include information about the device + type, battery status, battery level, last sync time, device + version, mac address, and features. + + Attributes: + name (str): + Identifier. The resource name of this Device resource. + + Format: ``users/{user}/pairedDevices/{paired_device}`` + Example: ``users/1234567890/pairedDevices/123`` or + ``users/me/pairedDevices/123`` + device_type (google.devicesandservices.health_v4.types.PairedDevice.DeviceType): + Output only. The device type. Supported: TRACKER \| SCALE + battery_status (str): + Output only. The battery status of the device. Supported: + High \| Medium \| Low \| Empty + battery_level (int): + Output only. The battery level of the device. + last_sync_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time of last sync with the + Fitbit mobile application. + device_version (str): + Output only. The product name of the device + mac_address (str): + Output only. Mac ID number of the device. + features (MutableSequence[str]): + Output only. Lists of unique features supported by the + device. + + Comprehensive list of supported features: + + **Fitness Tracking** + + - ``ACTIVE_MINUTES``: Legacy active minutes. + - ``AUTOSTRIDE``: Automatic stride length calculation. + - ``BIKE_ONBOARDING``: Cycling UI support. + - ``CALORIES``: Daily burned calories. + - ``DISTANCE``: Daily distance tracking. + - ``ELEVATION``: Floors climbed. + - ``INACTIVITY_ALERTS``: Reminders to move. + - ``SEDENTARY_TIME``: Tracks inactive time. + - ``STEPS``: Daily steps. + - ``SWIM``: Swim tracking (laps/strokes). + - ``AUTORUN``: Automatic run detection. + - ``ACTIVE_ZONE_MINUTES``: Active Zone Minutes (AZM). + + **Heart Rate & Health** + + - ``HEART_RATE``: Continuous heart rate (PPG). + - ``BAT_SIGNAL``: High/Low Heart Rate Alerts. + + **Advanced Sensors** + + - ``SPO2``: Blood oxygen saturation. + - ``NIGHTTIME_OXYGEN_SATURATION``: Sleep SpO2. + - ``ESTIMATED_OXYGEN_VARIATION``: Estimated Oxygen + Variation. + - ``EDA``: Electrodermal Activity (stress). + - ``SKIN_TEMPERATURE``: Skin temperature variation. + - ``INTERNAL_DEVICE_TEMPERATURE``: Internal device + temperature. + + **Sleep & Wellness** + + - ``SLEEP``: Basic sleep tracking. + - ``SMART_SLEEP``: Advanced sleep tracking (stages/score). + - ``BEDTIME_REMINDER``: Bedtime reminders. + - ``SOUNDSCAPE``: Snore and noise detection. + + **Advanced Workouts** + + - ``WB``: Custom Workout Builder. + - ``AUTOCUES``: Auto Cues / Auto Lap. + - ``DWR_RUN``: Daily Run Recommendations. + - ``ADVANCED_RUNNING``: Advanced Running Dynamics (e.g., + GCT, VO). + + **GPS & Location** + + - ``GPS``: Built-in GPS. + - ``CONNECTED_GPS``: Connected GPS (uses phone). + - ``LOCATION_HINT``: Location helper. + + **Payments & NFC** + + - ``PAYMENTS``: NFC payments (Fitbit Pay/Google Wallet). + - ``FELICA``: FeliCa support (Japan payments/transit). + + **Activity Detection** + + - ``GROK``: SmartTrack automatic activity detection. + - ``RETRO_AR``: Retroactive Activity Recognition prompts. + + **Smart Features & UI** + + - ``ALARMS``: Silent alarms. + - ``BLE_MUSIC_CONTROL``: BLE music control. + - ``MUSIC``: Direct music storage/control. + - ``YOUTUBE_MUSIC_SUPPORTED``: YouTube Music support. + - ``GALLERY``: App Gallery. + - ``TUTORIAL_SUPPORTED``: On-screen tutorials. + - ``SMILEY_EMOTE``: Legacy Zip face. + - ``MOBILE_TO_DEVICE_DEEPLINK``: Mobile to device settings + deep link. + - ``HIDE_GALLERY``: Option to hide Gallery. + - ``HIDE_GOAL_SELECTION``: Option to hide goal selection. + - ``DIGITAL_WARRANTY_SUPPORTED``: Digital warranty display. + - ``DIRECT_DEVICE_SETTINGS_SUPPORTED``: Direct device + settings management. + + **Gym HR Broadcasting** + + - ``ASPEN_SUPPORTED``: Broadcast HR to gym equipment. + - ``ASPEN_REMOTE_UI_SUPPORTED``: Remote UI for HR sharing. + + **Privacy & Security** + + - ``FINITE_IMPROBABILITY``: BLE Resolvable Private Address + (RPA) privacy. + - ``DOMAIN_KEY_SYNC``: Domain key synchronization. + + **BLE Protocol** + + - ``BONDING``: Secure BLE bonding. + - ``ADVERTISES_SERIAL``: Advertises serial number. + - ``STATUS_CHARACTERISTIC``: BLE Status Characteristic. + - ``TRACKER_CHANNEL_CHARACTERISTIC``: BLE Tracker Channel + Characteristic. + - ``PING_CHARACTERISTIC``: BLE Ping Characteristic. + + **Cellular & Wi-Fi** + + - ``MOBILE_DATA``: LTE cellular support. + - ``SINGLE_AP_WIFI``: Single AP Wi-Fi. + - ``MULTI_AP_WIFI``: Multi AP Wi-Fi. + - ``WIFI_FWUP``: Firmware updates over Wi-Fi. + + **Data Sync & Transfer** + + - ``APP_SYNC``: Background app sync. + - ``LIVE_DATA``: Real-time data streaming. + - ``EVENT_BASED_SYNC_SUPPORTED``: Event-based sync. + - ``TIME_SERVICE``: Time synchronization service. + - ``REMOTE_FILE_PROVIDER``: Remote file transfer. + - ``DIRECT_COMMS_ALARMS``: Direct communication for alarms. + - ``DIRECT_COMMS_EXERCISE``: Direct communication for + exercise. + - ``DIRECT_COMMS_BATTERY_ALERTS``: Direct communication for + battery alerts. + + **Google Integrations** + + - ``PARROT_TREE_SUPPORTED``: Find My Device support. + """ + + class DeviceType(proto.Enum): + r"""The type of device. + + Values: + DEVICE_TYPE_UNSPECIFIED (0): + Device type is not specified. + TRACKER (1): + Device type is tracker. + SCALE (2): + Device type is scale. + """ + + DEVICE_TYPE_UNSPECIFIED = 0 + TRACKER = 1 + SCALE = 2 + + name: str = proto.Field( + proto.STRING, + number=1, + ) + device_type: DeviceType = proto.Field( + proto.ENUM, + number=3, + enum=DeviceType, + ) + battery_status: str = proto.Field( + proto.STRING, + number=4, + ) + battery_level: int = proto.Field( + proto.INT32, + number=5, + ) + last_sync_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=6, + message=timestamp_pb2.Timestamp, + ) + device_version: str = proto.Field( + proto.STRING, + number=7, + ) + mac_address: str = proto.Field( + proto.STRING, + number=8, + ) + features: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=9, + ) + + +class IrnProfile(proto.Message): + r"""Irregular Rhythm Notifications (IRN) Profile details. + + The Irregular Rhythm Notifications (IRN) feature checks for + signs of atrial fibrillation (AFib). The IrnProfile details + include information about the user's onboarding status, + enrollment status, and the last update time of analyzable data + for this feature. + + Attributes: + name (str): + Identifier. The resource name of this IrnProfile resource. + + Format: ``users/{user}/irnProfile`` Example: + ``users/1234567890/irnProfile`` or ``users/me/irnProfile`` + The {user} ID is a system-generated Google Health API user + ID, a string of 1-63 characters consisting of lowercase and + uppercase letters, numbers, and hyphens. The literal ``me`` + can also be used to refer to the authenticated user. + onboarding_status (bool): + Required. Whether or not the user has + onboarded onto the IRN feature. + enrollment_status (bool): + Required. Whether or not the user is + currently enrolled in having their data + processed for IRN alerts. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The timestamp of the last piece + of analyzable data synced by the user. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + onboarding_status: bool = proto.Field( + proto.BOOL, + number=2, + ) + enrollment_status: bool = proto.Field( + proto.BOOL, + number=3, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=4, + message=timestamp_pb2.Timestamp, + ) + + +class Settings(proto.Message): + r"""Settings details. + + Attributes: + name (str): + Identifier. The resource name of this Settings resource. + + Format: ``users/{user}/settings`` Example: + ``users/1234567890/settings`` or ``users/me/settings`` The + {user} ID is a system-generated Google Health API user ID, a + string of 1-63 characters consisting of lowercase and + uppercase letters, numbers, and hyphens. The literal ``me`` + can also be used to refer to the authenticated user. + auto_stride_enabled (bool): + Optional. True if the user's stride length is + determined automatically. + Updates to this field are currently not + supported. + distance_unit (google.devicesandservices.health_v4.types.Settings.DistanceUnit): + Optional. The measurement unit defined in the + user's account settings. + Updates to this field are currently not + supported. + glucose_unit (google.devicesandservices.health_v4.types.Settings.GlucoseUnit): + Optional. The measurement unit defined in the + user's account settings. + height_unit (google.devicesandservices.health_v4.types.Settings.HeightUnit): + Optional. The measurement unit defined in the + user's account settings. + language_locale (str): + Optional. The locale defined in the user's + account settings. + Updates to this field are currently not + supported. + utc_offset (google.protobuf.duration_pb2.Duration): + Optional. The user's timezone offset relative + to UTC. + Updates to this field are currently not + supported. + stride_length_walking_type (google.devicesandservices.health_v4.types.Settings.StrideLengthType): + Optional. The stride length type defined in + the user's account settings for walking. + + Updates to this field are currently not + supported. + stride_length_running_type (google.devicesandservices.health_v4.types.Settings.StrideLengthType): + Optional. The stride length type defined in + the user's account settings for running. + + Updates to this field are currently not + supported. + swim_unit (google.devicesandservices.health_v4.types.Settings.SwimUnit): + Optional. The measurement unit defined in the + user's account settings. + temperature_unit (google.devicesandservices.health_v4.types.Settings.TemperatureUnit): + Optional. The measurement unit defined in the + user's account settings. + time_zone (str): + Optional. The timezone defined in the user's account + settings. This follows the IANA `Time Zone + Database `__. + + Updates to this field are currently not supported. + weight_unit (google.devicesandservices.health_v4.types.Settings.WeightUnit): + Optional. The measurement unit defined in the + user's account settings. + water_unit (google.devicesandservices.health_v4.types.Settings.WaterUnit): + Optional. The measurement unit defined in the + user's account settings. + food_language_code (str): + Output only. The food language code derived from the user's + food database. Possible values: ``'en-US'``, ``'en-GB'``, + ``'de-DE'``, ``'es-ES'``, ``'fr-FR'``, ``'zh-CN'``, + ``'zh-TW'``, ``'ja-JP'``, ``'en-AU'``, ``'en-CA'``, + ``'it-IT'``, ``'ko-KR'``, ``'es-MX'``, ``'en-IN'``, + ``'en-SG'``, ``'en-PH'``, ``'en-IE'``, ``'fr-CA'``. + + Updates to this field are currently not supported. + """ + + class DistanceUnit(proto.Enum): + r"""The measurement unit defined in the user's account settings. + + Values: + DISTANCE_UNIT_UNSPECIFIED (0): + Distance unit is not specified. + DISTANCE_UNIT_MILES (1): + Distance unit is miles. + DISTANCE_UNIT_KILOMETERS (2): + Distance unit is kilometers. + """ + + DISTANCE_UNIT_UNSPECIFIED = 0 + DISTANCE_UNIT_MILES = 1 + DISTANCE_UNIT_KILOMETERS = 2 + + class GlucoseUnit(proto.Enum): + r"""The measurement unit defined in the user's account settings. + + Values: + GLUCOSE_UNIT_UNSPECIFIED (0): + Glucose unit is not specified. + GLUCOSE_UNIT_MG_DL (1): + Glucose unit is mg/dL. + GLUCOSE_UNIT_MMOL_L (2): + Glucose unit is mmol/l. + """ + + GLUCOSE_UNIT_UNSPECIFIED = 0 + GLUCOSE_UNIT_MG_DL = 1 + GLUCOSE_UNIT_MMOL_L = 2 + + class HeightUnit(proto.Enum): + r"""The measurement unit defined in the user's account settings. + + Values: + HEIGHT_UNIT_UNSPECIFIED (0): + Height unit is not specified. + HEIGHT_UNIT_INCHES (1): + Height unit is inches. + HEIGHT_UNIT_CENTIMETERS (2): + Height unit is cm. + """ + + HEIGHT_UNIT_UNSPECIFIED = 0 + HEIGHT_UNIT_INCHES = 1 + HEIGHT_UNIT_CENTIMETERS = 2 + + class StrideLengthType(proto.Enum): + r"""The stride length type defined in the user's account + settings. Specifies if the user's stride length is determined + automatically (default) or manually as defined in the user's + account settings. + + Values: + STRIDE_LENGTH_TYPE_UNSPECIFIED (0): + Stride length type is not specified. + STRIDE_LENGTH_TYPE_DEFAULT (1): + Stride length type is computed based on the + user's gender and height. + STRIDE_LENGTH_TYPE_MANUAL (2): + Stride length type is manually set by the + user. + STRIDE_LENGTH_TYPE_AUTO (3): + Stride length type is determined + automatically. + """ + + STRIDE_LENGTH_TYPE_UNSPECIFIED = 0 + STRIDE_LENGTH_TYPE_DEFAULT = 1 + STRIDE_LENGTH_TYPE_MANUAL = 2 + STRIDE_LENGTH_TYPE_AUTO = 3 + + class SwimUnit(proto.Enum): + r"""The swim unit defined in the user's account settings. + + Values: + SWIM_UNIT_UNSPECIFIED (0): + Swim unit is not specified. + SWIM_UNIT_METERS (1): + Swim unit is meters. + SWIM_UNIT_YARDS (2): + Swim unit is yards. + """ + + SWIM_UNIT_UNSPECIFIED = 0 + SWIM_UNIT_METERS = 1 + SWIM_UNIT_YARDS = 2 + + class TemperatureUnit(proto.Enum): + r"""The measurement unit defined in the user's account settings. + + Values: + TEMPERATURE_UNIT_UNSPECIFIED (0): + Temperature unit is not specified. + TEMPERATURE_UNIT_CELSIUS (1): + Temperature unit is Celsius. + TEMPERATURE_UNIT_FAHRENHEIT (2): + Temperature unit is Fahrenheit. + """ + + TEMPERATURE_UNIT_UNSPECIFIED = 0 + TEMPERATURE_UNIT_CELSIUS = 1 + TEMPERATURE_UNIT_FAHRENHEIT = 2 + + class WeightUnit(proto.Enum): + r"""The measurement unit defined in the user's account settings. + + Values: + WEIGHT_UNIT_UNSPECIFIED (0): + Weight unit is not specified. + WEIGHT_UNIT_POUNDS (1): + Weight unit is pounds. + WEIGHT_UNIT_STONE (2): + Weight unit is stones. + WEIGHT_UNIT_KILOGRAMS (3): + Weight unit is kilograms. + """ + + WEIGHT_UNIT_UNSPECIFIED = 0 + WEIGHT_UNIT_POUNDS = 1 + WEIGHT_UNIT_STONE = 2 + WEIGHT_UNIT_KILOGRAMS = 3 + + class WaterUnit(proto.Enum): + r"""The water measurement unit defined in the user's account + settings. + + Values: + WATER_UNIT_UNSPECIFIED (0): + Water unit is not specified. + WATER_UNIT_ML (1): + Water unit is milliliters. + WATER_UNIT_FL_OZ (2): + Water unit is fluid ounces. + WATER_UNIT_CUP (3): + Water unit is cups. + """ + + WATER_UNIT_UNSPECIFIED = 0 + WATER_UNIT_ML = 1 + WATER_UNIT_FL_OZ = 2 + WATER_UNIT_CUP = 3 + + name: str = proto.Field( + proto.STRING, + number=1, + ) + auto_stride_enabled: bool = proto.Field( + proto.BOOL, + number=2, + ) + distance_unit: DistanceUnit = proto.Field( + proto.ENUM, + number=5, + enum=DistanceUnit, + ) + glucose_unit: GlucoseUnit = proto.Field( + proto.ENUM, + number=7, + enum=GlucoseUnit, + ) + height_unit: HeightUnit = proto.Field( + proto.ENUM, + number=8, + enum=HeightUnit, + ) + language_locale: str = proto.Field( + proto.STRING, + number=9, + ) + utc_offset: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=10, + message=duration_pb2.Duration, + ) + stride_length_walking_type: StrideLengthType = proto.Field( + proto.ENUM, + number=13, + enum=StrideLengthType, + ) + stride_length_running_type: StrideLengthType = proto.Field( + proto.ENUM, + number=14, + enum=StrideLengthType, + ) + swim_unit: SwimUnit = proto.Field( + proto.ENUM, + number=15, + enum=SwimUnit, + ) + temperature_unit: TemperatureUnit = proto.Field( + proto.ENUM, + number=16, + enum=TemperatureUnit, + ) + time_zone: str = proto.Field( + proto.STRING, + number=17, + ) + weight_unit: WeightUnit = proto.Field( + proto.ENUM, + number=18, + enum=WeightUnit, + ) + water_unit: WaterUnit = proto.Field( + proto.ENUM, + number=19, + enum=WaterUnit, + ) + food_language_code: str = proto.Field( + proto.STRING, + number=20, + ) + + +class Identity(proto.Message): + r"""Represents details about the Google user's identity. + + Attributes: + name (str): + Identifier. The resource name of this Identity resource. + Format: ``users/me/identity`` + legacy_user_id (str): + Output only. The legacy Fitbit User identifier. This is the + Fitbit ID used in the legacy Fitbit APIs (v1-v3). It can be + referenced by clients migrating from the legacy Fitbit APIs + to map their existing identifiers to the new Google user ID. + + It **must not** be used for any other purpose. It is not of + any use for new clients using only the Google Health APIs. + + Valid values are strings of 1-63 characters, and valid + characters are lowercase and uppercase letters, numbers, and + hyphens. + health_user_id (str): + Output only. The Google User Identifier in the Google Health + APIs. It matches the ``{user}`` resource ID segment in the + resource name paths, e.g. ``users/{user}/dataTypes/steps``. + + Valid values are strings of 1-63 characters, and valid + characters are lowercase and uppercase letters, numbers, and + hyphens. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + legacy_user_id: str = proto.Field( + proto.STRING, + number=2, + ) + health_user_id: str = proto.Field( + proto.STRING, + number=3, + ) + + +class GetProfileRequest(proto.Message): + r"""Request message for getting Profile details. + + Attributes: + name (str): + Required. The name of the Profile. Format: + ``users/me/profile``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class GetIrnProfileRequest(proto.Message): + r"""Request message for getting IRN Profile details. + + Attributes: + name (str): + Required. The resource name of the IRN Profile. Format: + ``users/{user}/irnProfile`` Example: + ``users/1234567890/irnProfile`` or ``users/me/irnProfile`` + The {user} ID is a system-generated Google Health API user + ID, a string of 1-63 characters consisting of lowercase and + uppercase letters, numbers, and hyphens. The literal ``me`` + can also be used to refer to the authenticated user. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class UpdateProfileRequest(proto.Message): + r"""Request message for updating Profile details. + + Attributes: + profile (google.devicesandservices.health_v4.types.Profile): + Required. Profile details. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Optional. The list of fields to be updated. + """ + + profile: "Profile" = proto.Field( + proto.MESSAGE, + number=1, + message="Profile", + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class GetSettingsRequest(proto.Message): + r"""Request message for getting Settings details. + + Attributes: + name (str): + Required. The name of the Settings. Format: + ``users/me/settings``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class UpdateSettingsRequest(proto.Message): + r"""Request message for updating Settings details. + + Attributes: + settings (google.devicesandservices.health_v4.types.Settings): + Required. Settings details + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Optional. The list of fields to be updated. + """ + + settings: "Settings" = proto.Field( + proto.MESSAGE, + number=1, + message="Settings", + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class GetIdentityRequest(proto.Message): + r"""Request message for getting Identity details. + + Attributes: + name (str): + Required. The resource name of the Identity. Format: + ``users/me/identity`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class GetPairedDeviceRequest(proto.Message): + r"""Request message for getting a Device. + + Attributes: + name (str): + Required. The name of the device to retrieve. + Format: users/{user}/devices/{device} + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListPairedDevicesRequest(proto.Message): + r"""Request message for listing Devices. + + Attributes: + parent (str): + Required. The parent, which owns this + collection of devices. Format: users/{user} + page_size (int): + Optional. The maximum number of devices to + return. The service may return fewer than this + value. If unspecified, at most 5 devices will be + returned. The maximum value is 100. values above + 100 will be coerced to 100. + page_token (str): + Optional. A page token, received from a previous + ``ListPairedDevices`` call. Provide this to retrieve the + subsequent page. + + When paginating, all other parameters provided to + ``ListPairedDevices`` must match the call that provided the + page token. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListPairedDevicesResponse(proto.Message): + r"""Response message for ListPairedDevices. + + Attributes: + paired_devices (MutableSequence[google.devicesandservices.health_v4.types.PairedDevice]): + The paired devices of the user. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + """ + + @property + def raw_page(self): + return self + + paired_devices: MutableSequence["PairedDevice"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="PairedDevice", + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/medical_device_info.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/medical_device_info.py new file mode 100644 index 000000000000..cd49a6cde431 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/medical_device_info.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.devicesandservices.health.v4", + manifest={ + "MedicalDeviceInfo", + }, +) + + +class MedicalDeviceInfo(proto.Message): + r"""Software as Medical Device (SaMD) metadata. + Used to construct the Unique Device Identifier (UDI). + + Attributes: + algorithm_version (str): + Output only. The algorithm version used by + the feature. + service_version (str): + Output only. The service version used by the + feature. + firmware_version (str): + Output only. The firmware version running on + the compatible device used to collect the data. + feature_version (str): + Output only. The version of the feature/app + running on the device. + device_model (str): + Output only. The model name or device type of + the compatible device used to collect the data. + """ + + algorithm_version: str = proto.Field( + proto.STRING, + number=1, + ) + service_version: str = proto.Field( + proto.STRING, + number=2, + ) + firmware_version: str = proto.Field( + proto.STRING, + number=3, + ) + feature_version: str = proto.Field( + proto.STRING, + number=4, + ) + device_model: str = proto.Field( + proto.STRING, + number=5, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/webhook_notification_cloud_log.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/webhook_notification_cloud_log.py new file mode 100644 index 000000000000..71dc2d66d482 --- /dev/null +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/types/webhook_notification_cloud_log.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import google.rpc.http_pb2 as http_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.devicesandservices.health.v4", + manifest={ + "WebhookNotificationCloudLog", + }, +) + + +class WebhookNotificationCloudLog(proto.Message): + r"""Log message for a webhook notification sent by the Google + Health API to a subscriber's endpoint. Includes the HTTP + response received from the endpoint. + + Attributes: + http_response (google.rpc.http_pb2.HttpResponse): + Required. Represents the HTTP response. + This message includes the status code, reason + phrase, headers, and body. + """ + + http_response: http_pb2.HttpResponse = proto.Field( + proto.MESSAGE, + number=1, + message=http_pb2.HttpResponse, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-devicesandservices-health/mypy.ini b/packages/google-devicesandservices-health/mypy.ini new file mode 100644 index 000000000000..e0e0da2e9e40 --- /dev/null +++ b/packages/google-devicesandservices-health/mypy.ini @@ -0,0 +1,15 @@ +[mypy] +python_version = 3.14 +namespace_packages = True +ignore_missing_imports = False + +# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): +# Dependencies that historically lacks py.typed markers +[mypy-google.iam.*] +ignore_missing_imports = True + +# Helps mypy navigate the 'google' namespace more reliably in 3.10+ +explicit_package_bases = True + +# Performance: reuse results from previous runs to speed up 'nox' +incremental = True diff --git a/packages/google-devicesandservices-health/noxfile.py b/packages/google-devicesandservices-health/noxfile.py new file mode 100644 index 000000000000..167314ff8a7a --- /dev/null +++ b/packages/google-devicesandservices-health/noxfile.py @@ -0,0 +1,639 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 re +import shutil +import warnings +from typing import Dict, List + +import nox + +RUFF_VERSION = "ruff==0.14.14" + +LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] + +# Add samples to the list of directories to format if the directory exists. +if os.path.isdir("samples"): + LINT_PATHS.append("samples") + +ALL_PYTHON = [ + "3.10", + "3.11", + "3.12", + "3.13", + "3.14", +] + +DEFAULT_PYTHON_VERSION = "3.14" + +# TODO(https://github.com/googleapis/gapic-generator-python/issues/2450): +# Switch this to Python 3.15 alpha1 +# https://peps.python.org/pep-0790/ +PREVIEW_PYTHON_VERSION = "3.14" + +CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() + +if (CURRENT_DIRECTORY / "testing").exists(): + LOWER_BOUND_CONSTRAINTS_FILE = ( + CURRENT_DIRECTORY / "testing" / f"constraints-{ALL_PYTHON[0]}.txt" + ) +else: + LOWER_BOUND_CONSTRAINTS_FILE = CURRENT_DIRECTORY / "constraints.txt" +PACKAGE_NAME = "google-devicesandservices-health" + +UNIT_TEST_STANDARD_DEPENDENCIES = [ + "mock", + "asyncmock", + "pytest", + "pytest-cov", + "pytest-asyncio", +] +UNIT_TEST_EXTERNAL_DEPENDENCIES: List[str] = [] +UNIT_TEST_LOCAL_DEPENDENCIES: List[str] = [] +UNIT_TEST_DEPENDENCIES: List[str] = [] +UNIT_TEST_EXTRAS: List[str] = [] +UNIT_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} + +SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ALL_PYTHON +SYSTEM_TEST_STANDARD_DEPENDENCIES = [ + "mock", + "pytest", + "google-cloud-testutils", +] +SYSTEM_TEST_EXTERNAL_DEPENDENCIES: List[str] = [] +SYSTEM_TEST_LOCAL_DEPENDENCIES: List[str] = [] +SYSTEM_TEST_DEPENDENCIES: List[str] = [] +SYSTEM_TEST_EXTRAS: List[str] = [] +SYSTEM_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} + +nox.options.sessions = [ + "unit", + "system", + "cover", + "lint", + "lint_setup_py", + "blacken", + "docs", +] + +# Error if a python version is missing +nox.options.error_on_missing_interpreters = True + + +@nox.session(python=ALL_PYTHON) +def mypy(session): + """Run the type checker.""" + # TODO(https://github.com/googleapis/gapic-generator-python/issues/2579): + # use the latest version of mypy + session.install( + "mypy<1.16.0", + "types-requests", + "types-protobuf", + ) + session.install(".") + session.run( + "mypy", + "-p", + "google", + "--check-untyped-defs", + *session.posargs, + ) + + +@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=DEFAULT_PYTHON_VERSION) +def lint(session): + """Run linters. + + Returns a failure if the linters find linting errors or sufficiently + serious code quality issues. + """ + session.install("flake8", RUFF_VERSION) + + # 2. Check formatting + session.run( + "ruff", + "format", + "--check", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", + *LINT_PATHS, + ) + + session.run("flake8", "google", "tests") + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def blacken(session): + """(Deprecated) Legacy session. Please use 'nox -s format'.""" + session.log( + "WARNING: The 'blacken' session is deprecated and will be removed in a future release. Please use 'nox -s format' in the future." + ) + + # Just run the ruff formatter (keeping legacy behavior of only formatting, not sorting imports) + session.install(RUFF_VERSION) + session.run( + "ruff", + "format", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", + *LINT_PATHS, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def format(session): + """ + Run ruff to sort imports and format code. + """ + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports + # check --select I: Enables strict import sorting + # --fix: Applies the changes automatically + session.run( + "ruff", + "check", + "--select", + "I", + "--fix", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", # Standard Black line length + *LINT_PATHS, + ) + + # 3. Run Ruff to format code + session.run( + "ruff", + "format", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", # Standard Black line length + *LINT_PATHS, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def lint_setup_py(session): + """Verify that setup.py is valid (including RST check).""" + session.install("setuptools", "docutils", "pygments") + session.run("python", "setup.py", "check", "--restructuredtext", "--strict") + + +def install_unittest_dependencies(session, *constraints): + standard_deps = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_DEPENDENCIES + session.install(*standard_deps, *constraints) + + if UNIT_TEST_EXTERNAL_DEPENDENCIES: + warnings.warn( + "'unit_test_external_dependencies' is deprecated. Instead, please " + "use 'unit_test_dependencies' or 'unit_test_local_dependencies'.", + DeprecationWarning, + ) + session.install(*UNIT_TEST_EXTERNAL_DEPENDENCIES, *constraints) + + if UNIT_TEST_LOCAL_DEPENDENCIES: + session.install(*UNIT_TEST_LOCAL_DEPENDENCIES, *constraints) + + if UNIT_TEST_EXTRAS_BY_PYTHON: + extras = UNIT_TEST_EXTRAS_BY_PYTHON.get(session.python, []) + elif UNIT_TEST_EXTRAS: + extras = UNIT_TEST_EXTRAS + else: + extras = [] + + if extras: + session.install("-e", f".[{','.join(extras)}]", *constraints) + else: + session.install("-e", ".", *constraints) + + +@nox.session(python=ALL_PYTHON) +@nox.parametrize( + "protobuf_implementation", + ["python", "upb"], +) +def unit(session, protobuf_implementation): + # Install all test dependencies, then install this package in-place. + + constraints_path = str( + CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" + ) + install_unittest_dependencies(session, "-c", constraints_path) + + # Run py.test against the unit tests. + session.run( + "py.test", + "--quiet", + f"--junitxml=unit_{session.python}_sponge_log.xml", + "--cov=google", + "--cov=tests/unit", + "--cov-append", + "--cov-config=.coveragerc", + "--cov-report=", + "--cov-fail-under=0", + os.path.join("tests", "unit"), + *session.posargs, + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) + + +def install_systemtest_dependencies(session, *constraints): + if session.python >= "3.12": + session.install("--pre", "grpcio>=1.75.1") + else: + session.install("--pre", "grpcio<=1.62.2") + + session.install(*SYSTEM_TEST_STANDARD_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_EXTERNAL_DEPENDENCIES: + session.install(*SYSTEM_TEST_EXTERNAL_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_LOCAL_DEPENDENCIES: + session.install("-e", *SYSTEM_TEST_LOCAL_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_DEPENDENCIES: + session.install("-e", *SYSTEM_TEST_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_EXTRAS_BY_PYTHON: + extras = SYSTEM_TEST_EXTRAS_BY_PYTHON.get(session.python, []) + elif SYSTEM_TEST_EXTRAS: + extras = SYSTEM_TEST_EXTRAS + else: + extras = [] + + if extras: + session.install("-e", f".[{','.join(extras)}]", *constraints) + else: + session.install("-e", ".", *constraints) + + +@nox.session(python=SYSTEM_TEST_PYTHON_VERSIONS) +def system(session): + """Run the system test suite.""" + constraints_path = str( + CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" + ) + system_test_path = os.path.join("tests", "system.py") + system_test_folder_path = os.path.join("tests", "system") + + # Check the value of `RUN_SYSTEM_TESTS` env var. It defaults to true. + if os.environ.get("RUN_SYSTEM_TESTS", "true") == "false": + session.skip("RUN_SYSTEM_TESTS is set to false, skipping") + # Install pyopenssl for mTLS testing. + if os.environ.get("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true": + session.install("pyopenssl") + + system_test_exists = os.path.exists(system_test_path) + system_test_folder_exists = os.path.exists(system_test_folder_path) + # Sanity check: only run tests if found. + if not system_test_exists and not system_test_folder_exists: + session.skip("System tests were not found") + + install_systemtest_dependencies(session, "-c", constraints_path) + + # Run py.test against the system tests. + if system_test_exists: + session.run( + "py.test", + "--quiet", + f"--junitxml=system_{session.python}_sponge_log.xml", + system_test_path, + *session.posargs, + ) + if system_test_folder_exists: + session.run( + "py.test", + "--quiet", + f"--junitxml=system_{session.python}_sponge_log.xml", + system_test_folder_path, + *session.posargs, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +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.10") +def docs(session): + """Build the docs for this library.""" + + session.install("-e", ".") + session.install( + # We need to pin to specific versions of the `sphinxcontrib-*` packages + # which still support sphinx 4.x. + # See https://github.com/googleapis/sphinx-docfx-yaml/issues/344 + # and https://github.com/googleapis/sphinx-docfx-yaml/issues/345. + "sphinxcontrib-applehelp==1.0.4", + "sphinxcontrib-devhelp==1.0.2", + "sphinxcontrib-htmlhelp==2.0.1", + "sphinxcontrib-qthelp==1.0.3", + "sphinxcontrib-serializinghtml==1.1.5", + "sphinx==4.5.0", + "alabaster", + "recommonmark", + ) + + shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) + session.run( + "sphinx-build", + "-T", # show full traceback on exception + "-N", # no colors + "-b", + "html", # builder + "-d", + os.path.join("docs", "_build", "doctrees", ""), # cache directory + # paths to build: + os.path.join("docs", ""), + os.path.join("docs", "_build", "html", ""), + ) + + +@nox.session(python="3.10") +def docfx(session): + """Build the docfx yaml files for this library.""" + + session.install("-e", ".") + session.install( + # We need to pin to specific versions of the `sphinxcontrib-*` packages + # which still support sphinx 4.x. + # See https://github.com/googleapis/sphinx-docfx-yaml/issues/344 + # and https://github.com/googleapis/sphinx-docfx-yaml/issues/345. + "sphinxcontrib-applehelp==1.0.4", + "sphinxcontrib-devhelp==1.0.2", + "sphinxcontrib-htmlhelp==2.0.1", + "sphinxcontrib-qthelp==1.0.3", + "sphinxcontrib-serializinghtml==1.1.5", + "gcp-sphinx-docfx-yaml", + "alabaster", + "recommonmark", + ) + + shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) + session.run( + "sphinx-build", + "-T", # show full traceback on exception + "-N", # no colors + "-D", + ( + "extensions=sphinx.ext.autodoc," + "sphinx.ext.autosummary," + "docfx_yaml.extension," + "sphinx.ext.intersphinx," + "sphinx.ext.coverage," + "sphinx.ext.napoleon," + "sphinx.ext.todo," + "sphinx.ext.viewcode," + "recommonmark" + ), + "-b", + "html", + "-d", + os.path.join("docs", "_build", "doctrees", ""), + os.path.join("docs", ""), + os.path.join("docs", "_build", "html", ""), + ) + + +@nox.session(python=PREVIEW_PYTHON_VERSION) +@nox.parametrize( + "protobuf_implementation", + ["python", "upb"], +) +def prerelease_deps(session, protobuf_implementation): + """ + Run all tests with pre-release versions of dependencies installed + rather than the standard non pre-release versions. + Pre-release versions can be installed using + `pip install --pre `. + """ + + # Install all dependencies + session.install("-e", ".") + + # Install dependencies for the unit test environment + unit_deps_all = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_EXTERNAL_DEPENDENCIES + session.install(*unit_deps_all) + + # Because we test minimum dependency versions on the minimum Python + # version, the first version we test with in the unit tests sessions has a + # constraints file containing all dependencies and extras. + with open( + CURRENT_DIRECTORY / "testing" / f"constraints-{ALL_PYTHON[0]}.txt", + encoding="utf-8", + ) as constraints_file: + constraints_text = constraints_file.read() + + # Ignore leading whitespace and comment lines. + constraints_deps = [ + match.group(1) + for match in re.finditer( + r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE + ) + ] + + # Install dependencies specified in `testing/constraints-X.txt`. + session.install(*constraints_deps) + + # Note: If a dependency is added to the `prerel_deps` list, + # the `core_dependencies_from_source` list in the `core_deps_from_source` + # nox session should also be updated. + prerel_deps = [ + "googleapis-common-protos", + "google-api-core", + "google-auth", + "grpc-google-iam-v1", + "grpcio>=1.75.1" if session.python >= "3.12" else "grpcio<=1.62.2", + "grpcio-status", + "protobuf", + "proto-plus", + ] + + deps_dir = CURRENT_DIRECTORY.parent + while deps_dir.name != "packages" and deps_dir.parent != deps_dir: + deps_dir = deps_dir.parent + + # Extract the base package name, safely ignoring version bounds and spaces + # (e.g., "grpcio>=1.75.1" becomes "grpcio") + parsed_deps = { + dep: re.match(r"^([a-zA-Z0-9_-]+)", dep).group(1) for dep in prerel_deps + } + + # Dynamically sort local packages vs PyPI dependencies + local_paths = [] + pypi_deps = [] + + for dep, pkg_name in parsed_deps.items(): + if (deps_dir / pkg_name).exists(): + local_paths.append(str(deps_dir / pkg_name)) + else: + pypi_deps.append(dep) + + # Batch pip installations to avoid sequential overhead + if local_paths: + session.install(*local_paths, "--no-deps", "--ignore-installed") + if pypi_deps: + session.install(*pypi_deps, "--pre", "--no-deps", "--ignore-installed") + + # TODO(https://github.com/grpc/grpc/issues/38965): Add `grpcio-status`` + # to the dictionary below once this bug is fixed. + # TODO(https://github.com/googleapis/google-cloud-python/issues/13643): Add + # `googleapis-common-protos` and `grpc-google-iam-v1` to the dictionary below + # once this bug is fixed. + package_namespaces = { + "google-api-core": "google.api_core", + "google-auth": "google.auth", + "grpcio": "grpc", + "protobuf": "google.protobuf", + "proto-plus": "proto", + } + + # Reuse the parsed names for logging and version verification + for dep, pkg_name in parsed_deps.items(): + print(f"Installed {dep}") + version_namespace = package_namespaces.get(pkg_name) + + if version_namespace: + session.run( + "python", + "-c", + f"import {version_namespace}; print({version_namespace}.__version__)", + ) + + session.run( + "py.test", + "tests/unit", + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +@nox.parametrize( + "protobuf_implementation", + ["python", "upb"], +) +def core_deps_from_source(session, protobuf_implementation): + """Run all tests with core dependencies installed from source + rather than pulling the dependencies from PyPI. + """ + + # Install all dependencies + session.install("-e", ".") + + # Install dependencies for the unit test environment + unit_deps_all = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_EXTERNAL_DEPENDENCIES + session.install(*unit_deps_all) + + # Because we test minimum dependency versions on the minimum Python + # version, the first version we test with in the unit tests sessions has a + # constraints file containing all dependencies and extras. + with open( + CURRENT_DIRECTORY / "testing" / f"constraints-{ALL_PYTHON[0]}.txt", + encoding="utf-8", + ) as constraints_file: + constraints_text = constraints_file.read() + + # Ignore leading whitespace and comment lines. + constraints_deps = [ + match.group(1) + for match in re.finditer( + r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE + ) + ] + + # Install dependencies specified in `testing/constraints-X.txt`. + session.install(*constraints_deps) + + # TODO(https://github.com/googleapis/gapic-generator-python/issues/2358): `grpcio` and + # `grpcio-status` should be added to the list below so that they are installed from source, + # rather than PyPI. + # TODO(https://github.com/googleapis/gapic-generator-python/issues/2357): `protobuf` should be + # added to the list below so that it is installed from source, rather than PyPI + # Note: If a dependency is added to the `core_dependencies_from_source` list, + # the `prerel_deps` list in the `prerelease_deps` nox session should also be updated. + core_dependencies_from_source = [ + "googleapis-common-protos", + "google-api-core", + "google-auth", + "grpc-google-iam-v1", + "proto-plus", + ] + + deps_dir = CURRENT_DIRECTORY.parent + while deps_dir.name != "packages" and deps_dir.parent != deps_dir: + deps_dir = deps_dir.parent + + # Batch the pip installation to avoid sequential overhead + dep_paths = [str(deps_dir / dep) for dep in core_dependencies_from_source] + + session.install(*dep_paths, "--no-deps", "--ignore-installed") + print( + f"Installed {', '.join(core_dependencies_from_source)} locally from {deps_dir}" + ) + + session.run( + "py.test", + "tests/unit", + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_batch_delete_data_points_async.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_batch_delete_data_points_async.py new file mode 100644 index 000000000000..0607041ad028 --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_batch_delete_data_points_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchDeleteDataPoints +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataPointsService_BatchDeleteDataPoints_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +async def sample_batch_delete_data_points(): + # Create a client + client = health_v4.DataPointsServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.BatchDeleteDataPointsRequest( + names=["names_value1", "names_value2"], + ) + + # Make the request + operation = await client.batch_delete_data_points(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + +# [END health_v4_generated_DataPointsService_BatchDeleteDataPoints_async] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_batch_delete_data_points_sync.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_batch_delete_data_points_sync.py new file mode 100644 index 000000000000..65825db79b88 --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_batch_delete_data_points_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchDeleteDataPoints +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataPointsService_BatchDeleteDataPoints_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +def sample_batch_delete_data_points(): + # Create a client + client = health_v4.DataPointsServiceClient() + + # Initialize request argument(s) + request = health_v4.BatchDeleteDataPointsRequest( + names=["names_value1", "names_value2"], + ) + + # Make the request + operation = client.batch_delete_data_points(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + +# [END health_v4_generated_DataPointsService_BatchDeleteDataPoints_sync] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_create_data_point_async.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_create_data_point_async.py new file mode 100644 index 000000000000..88cefd3a6cec --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_create_data_point_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateDataPoint +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataPointsService_CreateDataPoint_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +async def sample_create_data_point(): + # Create a client + client = health_v4.DataPointsServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.CreateDataPointRequest( + parent="parent_value", + ) + + # Make the request + operation = await client.create_data_point(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + +# [END health_v4_generated_DataPointsService_CreateDataPoint_async] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_create_data_point_sync.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_create_data_point_sync.py new file mode 100644 index 000000000000..8693bc635abf --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_create_data_point_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateDataPoint +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataPointsService_CreateDataPoint_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +def sample_create_data_point(): + # Create a client + client = health_v4.DataPointsServiceClient() + + # Initialize request argument(s) + request = health_v4.CreateDataPointRequest( + parent="parent_value", + ) + + # Make the request + operation = client.create_data_point(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + +# [END health_v4_generated_DataPointsService_CreateDataPoint_sync] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_daily_roll_up_data_points_async.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_daily_roll_up_data_points_async.py new file mode 100644 index 000000000000..ef8fb0dd7208 --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_daily_roll_up_data_points_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DailyRollUpDataPoints +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataPointsService_DailyRollUpDataPoints_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +async def sample_daily_roll_up_data_points(): + # Create a client + client = health_v4.DataPointsServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.DailyRollUpDataPointsRequest( + parent="parent_value", + ) + + # Make the request + response = await client.daily_roll_up_data_points(request=request) + + # Handle the response + print(response) + + +# [END health_v4_generated_DataPointsService_DailyRollUpDataPoints_async] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_daily_roll_up_data_points_sync.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_daily_roll_up_data_points_sync.py new file mode 100644 index 000000000000..1173ee9e2aa4 --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_daily_roll_up_data_points_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DailyRollUpDataPoints +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataPointsService_DailyRollUpDataPoints_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +def sample_daily_roll_up_data_points(): + # Create a client + client = health_v4.DataPointsServiceClient() + + # Initialize request argument(s) + request = health_v4.DailyRollUpDataPointsRequest( + parent="parent_value", + ) + + # Make the request + response = client.daily_roll_up_data_points(request=request) + + # Handle the response + print(response) + + +# [END health_v4_generated_DataPointsService_DailyRollUpDataPoints_sync] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_export_exercise_tcx_async.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_export_exercise_tcx_async.py new file mode 100644 index 000000000000..f78e69d672e2 --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_export_exercise_tcx_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ExportExerciseTcx +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataPointsService_ExportExerciseTcx_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +async def sample_export_exercise_tcx(): + # Create a client + client = health_v4.DataPointsServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.ExportExerciseTcxRequest( + name="name_value", + ) + + # Make the request + response = await client.export_exercise_tcx(request=request) + + # Handle the response + print(response) + + +# [END health_v4_generated_DataPointsService_ExportExerciseTcx_async] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_export_exercise_tcx_sync.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_export_exercise_tcx_sync.py new file mode 100644 index 000000000000..09d0a5ad66e4 --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_export_exercise_tcx_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ExportExerciseTcx +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataPointsService_ExportExerciseTcx_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +def sample_export_exercise_tcx(): + # Create a client + client = health_v4.DataPointsServiceClient() + + # Initialize request argument(s) + request = health_v4.ExportExerciseTcxRequest( + name="name_value", + ) + + # Make the request + response = client.export_exercise_tcx(request=request) + + # Handle the response + print(response) + + +# [END health_v4_generated_DataPointsService_ExportExerciseTcx_sync] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_get_data_point_async.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_get_data_point_async.py new file mode 100644 index 000000000000..f1802e102ad4 --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_get_data_point_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetDataPoint +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataPointsService_GetDataPoint_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +async def sample_get_data_point(): + # Create a client + client = health_v4.DataPointsServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.GetDataPointRequest( + name="name_value", + ) + + # Make the request + response = await client.get_data_point(request=request) + + # Handle the response + print(response) + + +# [END health_v4_generated_DataPointsService_GetDataPoint_async] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_get_data_point_sync.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_get_data_point_sync.py new file mode 100644 index 000000000000..804f1ffdbbbc --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_get_data_point_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetDataPoint +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataPointsService_GetDataPoint_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +def sample_get_data_point(): + # Create a client + client = health_v4.DataPointsServiceClient() + + # Initialize request argument(s) + request = health_v4.GetDataPointRequest( + name="name_value", + ) + + # Make the request + response = client.get_data_point(request=request) + + # Handle the response + print(response) + + +# [END health_v4_generated_DataPointsService_GetDataPoint_sync] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_list_data_points_async.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_list_data_points_async.py new file mode 100644 index 000000000000..44f8f74c381c --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_list_data_points_async.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListDataPoints +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataPointsService_ListDataPoints_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +async def sample_list_data_points(): + # Create a client + client = health_v4.DataPointsServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.ListDataPointsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_data_points(request=request) + + # Handle the response + async for response in page_result: + print(response) + + +# [END health_v4_generated_DataPointsService_ListDataPoints_async] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_list_data_points_sync.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_list_data_points_sync.py new file mode 100644 index 000000000000..48653c729c72 --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_list_data_points_sync.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListDataPoints +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataPointsService_ListDataPoints_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +def sample_list_data_points(): + # Create a client + client = health_v4.DataPointsServiceClient() + + # Initialize request argument(s) + request = health_v4.ListDataPointsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_data_points(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END health_v4_generated_DataPointsService_ListDataPoints_sync] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_reconcile_data_points_async.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_reconcile_data_points_async.py new file mode 100644 index 000000000000..9e6a6425a8b7 --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_reconcile_data_points_async.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ReconcileDataPoints +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataPointsService_ReconcileDataPoints_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +async def sample_reconcile_data_points(): + # Create a client + client = health_v4.DataPointsServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.ReconcileDataPointsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.reconcile_data_points(request=request) + + # Handle the response + async for response in page_result: + print(response) + + +# [END health_v4_generated_DataPointsService_ReconcileDataPoints_async] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_reconcile_data_points_sync.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_reconcile_data_points_sync.py new file mode 100644 index 000000000000..99de7fcb8c2c --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_reconcile_data_points_sync.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ReconcileDataPoints +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataPointsService_ReconcileDataPoints_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +def sample_reconcile_data_points(): + # Create a client + client = health_v4.DataPointsServiceClient() + + # Initialize request argument(s) + request = health_v4.ReconcileDataPointsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.reconcile_data_points(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END health_v4_generated_DataPointsService_ReconcileDataPoints_sync] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_roll_up_data_points_async.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_roll_up_data_points_async.py new file mode 100644 index 000000000000..426d0462c5d4 --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_roll_up_data_points_async.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for RollUpDataPoints +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataPointsService_RollUpDataPoints_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +async def sample_roll_up_data_points(): + # Create a client + client = health_v4.DataPointsServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.RollUpDataPointsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.roll_up_data_points(request=request) + + # Handle the response + async for response in page_result: + print(response) + + +# [END health_v4_generated_DataPointsService_RollUpDataPoints_async] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_roll_up_data_points_sync.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_roll_up_data_points_sync.py new file mode 100644 index 000000000000..236c7b96fc6b --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_roll_up_data_points_sync.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for RollUpDataPoints +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataPointsService_RollUpDataPoints_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +def sample_roll_up_data_points(): + # Create a client + client = health_v4.DataPointsServiceClient() + + # Initialize request argument(s) + request = health_v4.RollUpDataPointsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.roll_up_data_points(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END health_v4_generated_DataPointsService_RollUpDataPoints_sync] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_update_data_point_async.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_update_data_point_async.py new file mode 100644 index 000000000000..23822eb59f82 --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_update_data_point_async.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateDataPoint +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataPointsService_UpdateDataPoint_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +async def sample_update_data_point(): + # Create a client + client = health_v4.DataPointsServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.UpdateDataPointRequest() + + # Make the request + operation = await client.update_data_point(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + +# [END health_v4_generated_DataPointsService_UpdateDataPoint_async] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_update_data_point_sync.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_update_data_point_sync.py new file mode 100644 index 000000000000..fec248b33d81 --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_points_service_update_data_point_sync.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateDataPoint +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataPointsService_UpdateDataPoint_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +def sample_update_data_point(): + # Create a client + client = health_v4.DataPointsServiceClient() + + # Initialize request argument(s) + request = health_v4.UpdateDataPointRequest() + + # Make the request + operation = client.update_data_point(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + +# [END health_v4_generated_DataPointsService_UpdateDataPoint_sync] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_create_subscriber_async.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_create_subscriber_async.py new file mode 100644 index 000000000000..ff1827bac229 --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_create_subscriber_async.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateSubscriber +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataSubscriptionService_CreateSubscriber_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +async def sample_create_subscriber(): + # Create a client + client = health_v4.DataSubscriptionServiceAsyncClient() + + # Initialize request argument(s) + subscriber = health_v4.CreateSubscriberPayload() + subscriber.endpoint_uri = "endpoint_uri_value" + subscriber.endpoint_authorization.secret = "secret_value" + + request = health_v4.CreateSubscriberRequest( + parent="parent_value", + subscriber=subscriber, + ) + + # Make the request + operation = await client.create_subscriber(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + +# [END health_v4_generated_DataSubscriptionService_CreateSubscriber_async] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_create_subscriber_sync.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_create_subscriber_sync.py new file mode 100644 index 000000000000..08e8fe79b03e --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_create_subscriber_sync.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateSubscriber +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataSubscriptionService_CreateSubscriber_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +def sample_create_subscriber(): + # Create a client + client = health_v4.DataSubscriptionServiceClient() + + # Initialize request argument(s) + subscriber = health_v4.CreateSubscriberPayload() + subscriber.endpoint_uri = "endpoint_uri_value" + subscriber.endpoint_authorization.secret = "secret_value" + + request = health_v4.CreateSubscriberRequest( + parent="parent_value", + subscriber=subscriber, + ) + + # Make the request + operation = client.create_subscriber(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + +# [END health_v4_generated_DataSubscriptionService_CreateSubscriber_sync] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_create_subscription_async.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_create_subscription_async.py new file mode 100644 index 000000000000..f345d46c31c1 --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_create_subscription_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateSubscription +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataSubscriptionService_CreateSubscription_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +async def sample_create_subscription(): + # Create a client + client = health_v4.DataSubscriptionServiceAsyncClient() + + # Initialize request argument(s) + subscription = health_v4.CreateSubscriptionPayload() + subscription.user = "user_value" + + request = health_v4.CreateSubscriptionRequest( + parent="parent_value", + subscription=subscription, + ) + + # Make the request + response = await client.create_subscription(request=request) + + # Handle the response + print(response) + + +# [END health_v4_generated_DataSubscriptionService_CreateSubscription_async] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_create_subscription_sync.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_create_subscription_sync.py new file mode 100644 index 000000000000..a17b052fb0ec --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_create_subscription_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateSubscription +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataSubscriptionService_CreateSubscription_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +def sample_create_subscription(): + # Create a client + client = health_v4.DataSubscriptionServiceClient() + + # Initialize request argument(s) + subscription = health_v4.CreateSubscriptionPayload() + subscription.user = "user_value" + + request = health_v4.CreateSubscriptionRequest( + parent="parent_value", + subscription=subscription, + ) + + # Make the request + response = client.create_subscription(request=request) + + # Handle the response + print(response) + + +# [END health_v4_generated_DataSubscriptionService_CreateSubscription_sync] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_delete_subscriber_async.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_delete_subscriber_async.py new file mode 100644 index 000000000000..1379b800eb42 --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_delete_subscriber_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteSubscriber +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataSubscriptionService_DeleteSubscriber_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +async def sample_delete_subscriber(): + # Create a client + client = health_v4.DataSubscriptionServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.DeleteSubscriberRequest( + name="name_value", + ) + + # Make the request + operation = await client.delete_subscriber(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + +# [END health_v4_generated_DataSubscriptionService_DeleteSubscriber_async] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_delete_subscriber_sync.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_delete_subscriber_sync.py new file mode 100644 index 000000000000..94bd92523972 --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_delete_subscriber_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteSubscriber +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataSubscriptionService_DeleteSubscriber_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +def sample_delete_subscriber(): + # Create a client + client = health_v4.DataSubscriptionServiceClient() + + # Initialize request argument(s) + request = health_v4.DeleteSubscriberRequest( + name="name_value", + ) + + # Make the request + operation = client.delete_subscriber(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + +# [END health_v4_generated_DataSubscriptionService_DeleteSubscriber_sync] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_delete_subscription_async.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_delete_subscription_async.py new file mode 100644 index 000000000000..ad867659f8df --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_delete_subscription_async.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteSubscription +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataSubscriptionService_DeleteSubscription_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +async def sample_delete_subscription(): + # Create a client + client = health_v4.DataSubscriptionServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.DeleteSubscriptionRequest( + name="name_value", + ) + + # Make the request + await client.delete_subscription(request=request) + + +# [END health_v4_generated_DataSubscriptionService_DeleteSubscription_async] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_delete_subscription_sync.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_delete_subscription_sync.py new file mode 100644 index 000000000000..01cdbaddb855 --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_delete_subscription_sync.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteSubscription +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataSubscriptionService_DeleteSubscription_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +def sample_delete_subscription(): + # Create a client + client = health_v4.DataSubscriptionServiceClient() + + # Initialize request argument(s) + request = health_v4.DeleteSubscriptionRequest( + name="name_value", + ) + + # Make the request + client.delete_subscription(request=request) + + +# [END health_v4_generated_DataSubscriptionService_DeleteSubscription_sync] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_list_subscribers_async.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_list_subscribers_async.py new file mode 100644 index 000000000000..867e7400ab3f --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_list_subscribers_async.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListSubscribers +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataSubscriptionService_ListSubscribers_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +async def sample_list_subscribers(): + # Create a client + client = health_v4.DataSubscriptionServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.ListSubscribersRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_subscribers(request=request) + + # Handle the response + async for response in page_result: + print(response) + + +# [END health_v4_generated_DataSubscriptionService_ListSubscribers_async] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_list_subscribers_sync.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_list_subscribers_sync.py new file mode 100644 index 000000000000..1377c6dd1a95 --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_list_subscribers_sync.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListSubscribers +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataSubscriptionService_ListSubscribers_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +def sample_list_subscribers(): + # Create a client + client = health_v4.DataSubscriptionServiceClient() + + # Initialize request argument(s) + request = health_v4.ListSubscribersRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_subscribers(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END health_v4_generated_DataSubscriptionService_ListSubscribers_sync] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_list_subscriptions_async.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_list_subscriptions_async.py new file mode 100644 index 000000000000..efa0d49013db --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_list_subscriptions_async.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListSubscriptions +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataSubscriptionService_ListSubscriptions_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +async def sample_list_subscriptions(): + # Create a client + client = health_v4.DataSubscriptionServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.ListSubscriptionsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_subscriptions(request=request) + + # Handle the response + async for response in page_result: + print(response) + + +# [END health_v4_generated_DataSubscriptionService_ListSubscriptions_async] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_list_subscriptions_sync.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_list_subscriptions_sync.py new file mode 100644 index 000000000000..45bad7fb359b --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_list_subscriptions_sync.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListSubscriptions +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataSubscriptionService_ListSubscriptions_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +def sample_list_subscriptions(): + # Create a client + client = health_v4.DataSubscriptionServiceClient() + + # Initialize request argument(s) + request = health_v4.ListSubscriptionsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_subscriptions(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END health_v4_generated_DataSubscriptionService_ListSubscriptions_sync] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_update_subscriber_async.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_update_subscriber_async.py new file mode 100644 index 000000000000..6ff2bba6f724 --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_update_subscriber_async.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateSubscriber +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataSubscriptionService_UpdateSubscriber_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +async def sample_update_subscriber(): + # Create a client + client = health_v4.DataSubscriptionServiceAsyncClient() + + # Initialize request argument(s) + subscriber = health_v4.Subscriber() + subscriber.endpoint_uri = "endpoint_uri_value" + subscriber.endpoint_authorization.secret = "secret_value" + + request = health_v4.UpdateSubscriberRequest( + subscriber=subscriber, + ) + + # Make the request + operation = await client.update_subscriber(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + +# [END health_v4_generated_DataSubscriptionService_UpdateSubscriber_async] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_update_subscriber_sync.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_update_subscriber_sync.py new file mode 100644 index 000000000000..f4efbf5e345c --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_update_subscriber_sync.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateSubscriber +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataSubscriptionService_UpdateSubscriber_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +def sample_update_subscriber(): + # Create a client + client = health_v4.DataSubscriptionServiceClient() + + # Initialize request argument(s) + subscriber = health_v4.Subscriber() + subscriber.endpoint_uri = "endpoint_uri_value" + subscriber.endpoint_authorization.secret = "secret_value" + + request = health_v4.UpdateSubscriberRequest( + subscriber=subscriber, + ) + + # Make the request + operation = client.update_subscriber(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + +# [END health_v4_generated_DataSubscriptionService_UpdateSubscriber_sync] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_update_subscription_async.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_update_subscription_async.py new file mode 100644 index 000000000000..34c413b02bf9 --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_update_subscription_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateSubscription +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataSubscriptionService_UpdateSubscription_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +async def sample_update_subscription(): + # Create a client + client = health_v4.DataSubscriptionServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.UpdateSubscriptionRequest() + + # Make the request + response = await client.update_subscription(request=request) + + # Handle the response + print(response) + + +# [END health_v4_generated_DataSubscriptionService_UpdateSubscription_async] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_update_subscription_sync.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_update_subscription_sync.py new file mode 100644 index 000000000000..43c09e6ab0ca --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_data_subscription_service_update_subscription_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateSubscription +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_DataSubscriptionService_UpdateSubscription_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +def sample_update_subscription(): + # Create a client + client = health_v4.DataSubscriptionServiceClient() + + # Initialize request argument(s) + request = health_v4.UpdateSubscriptionRequest() + + # Make the request + response = client.update_subscription(request=request) + + # Handle the response + print(response) + + +# [END health_v4_generated_DataSubscriptionService_UpdateSubscription_sync] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_identity_async.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_identity_async.py new file mode 100644 index 000000000000..672e8bb8ec31 --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_identity_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetIdentity +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_HealthProfileService_GetIdentity_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +async def sample_get_identity(): + # Create a client + client = health_v4.HealthProfileServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.GetIdentityRequest( + name="name_value", + ) + + # Make the request + response = await client.get_identity(request=request) + + # Handle the response + print(response) + + +# [END health_v4_generated_HealthProfileService_GetIdentity_async] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_identity_sync.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_identity_sync.py new file mode 100644 index 000000000000..028c96a851a4 --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_identity_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetIdentity +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_HealthProfileService_GetIdentity_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +def sample_get_identity(): + # Create a client + client = health_v4.HealthProfileServiceClient() + + # Initialize request argument(s) + request = health_v4.GetIdentityRequest( + name="name_value", + ) + + # Make the request + response = client.get_identity(request=request) + + # Handle the response + print(response) + + +# [END health_v4_generated_HealthProfileService_GetIdentity_sync] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_irn_profile_async.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_irn_profile_async.py new file mode 100644 index 000000000000..9a487d73f39e --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_irn_profile_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetIrnProfile +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_HealthProfileService_GetIrnProfile_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +async def sample_get_irn_profile(): + # Create a client + client = health_v4.HealthProfileServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.GetIrnProfileRequest( + name="name_value", + ) + + # Make the request + response = await client.get_irn_profile(request=request) + + # Handle the response + print(response) + + +# [END health_v4_generated_HealthProfileService_GetIrnProfile_async] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_irn_profile_sync.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_irn_profile_sync.py new file mode 100644 index 000000000000..e22982d08125 --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_irn_profile_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetIrnProfile +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_HealthProfileService_GetIrnProfile_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +def sample_get_irn_profile(): + # Create a client + client = health_v4.HealthProfileServiceClient() + + # Initialize request argument(s) + request = health_v4.GetIrnProfileRequest( + name="name_value", + ) + + # Make the request + response = client.get_irn_profile(request=request) + + # Handle the response + print(response) + + +# [END health_v4_generated_HealthProfileService_GetIrnProfile_sync] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_paired_device_async.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_paired_device_async.py new file mode 100644 index 000000000000..7307d8c9f55b --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_paired_device_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetPairedDevice +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_HealthProfileService_GetPairedDevice_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +async def sample_get_paired_device(): + # Create a client + client = health_v4.HealthProfileServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.GetPairedDeviceRequest( + name="name_value", + ) + + # Make the request + response = await client.get_paired_device(request=request) + + # Handle the response + print(response) + + +# [END health_v4_generated_HealthProfileService_GetPairedDevice_async] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_paired_device_sync.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_paired_device_sync.py new file mode 100644 index 000000000000..6d6fd41b4088 --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_paired_device_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetPairedDevice +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_HealthProfileService_GetPairedDevice_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +def sample_get_paired_device(): + # Create a client + client = health_v4.HealthProfileServiceClient() + + # Initialize request argument(s) + request = health_v4.GetPairedDeviceRequest( + name="name_value", + ) + + # Make the request + response = client.get_paired_device(request=request) + + # Handle the response + print(response) + + +# [END health_v4_generated_HealthProfileService_GetPairedDevice_sync] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_profile_async.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_profile_async.py new file mode 100644 index 000000000000..16504e094185 --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_profile_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetProfile +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_HealthProfileService_GetProfile_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +async def sample_get_profile(): + # Create a client + client = health_v4.HealthProfileServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.GetProfileRequest( + name="name_value", + ) + + # Make the request + response = await client.get_profile(request=request) + + # Handle the response + print(response) + + +# [END health_v4_generated_HealthProfileService_GetProfile_async] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_profile_sync.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_profile_sync.py new file mode 100644 index 000000000000..be18ab89d909 --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_profile_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetProfile +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_HealthProfileService_GetProfile_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +def sample_get_profile(): + # Create a client + client = health_v4.HealthProfileServiceClient() + + # Initialize request argument(s) + request = health_v4.GetProfileRequest( + name="name_value", + ) + + # Make the request + response = client.get_profile(request=request) + + # Handle the response + print(response) + + +# [END health_v4_generated_HealthProfileService_GetProfile_sync] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_settings_async.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_settings_async.py new file mode 100644 index 000000000000..65396df4f01e --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_settings_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetSettings +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_HealthProfileService_GetSettings_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +async def sample_get_settings(): + # Create a client + client = health_v4.HealthProfileServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.GetSettingsRequest( + name="name_value", + ) + + # Make the request + response = await client.get_settings(request=request) + + # Handle the response + print(response) + + +# [END health_v4_generated_HealthProfileService_GetSettings_async] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_settings_sync.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_settings_sync.py new file mode 100644 index 000000000000..49b12da442de --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_get_settings_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetSettings +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_HealthProfileService_GetSettings_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +def sample_get_settings(): + # Create a client + client = health_v4.HealthProfileServiceClient() + + # Initialize request argument(s) + request = health_v4.GetSettingsRequest( + name="name_value", + ) + + # Make the request + response = client.get_settings(request=request) + + # Handle the response + print(response) + + +# [END health_v4_generated_HealthProfileService_GetSettings_sync] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_list_paired_devices_async.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_list_paired_devices_async.py new file mode 100644 index 000000000000..cc517bc9807d --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_list_paired_devices_async.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListPairedDevices +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_HealthProfileService_ListPairedDevices_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +async def sample_list_paired_devices(): + # Create a client + client = health_v4.HealthProfileServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.ListPairedDevicesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_paired_devices(request=request) + + # Handle the response + async for response in page_result: + print(response) + + +# [END health_v4_generated_HealthProfileService_ListPairedDevices_async] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_list_paired_devices_sync.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_list_paired_devices_sync.py new file mode 100644 index 000000000000..7687b5a835f9 --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_list_paired_devices_sync.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListPairedDevices +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_HealthProfileService_ListPairedDevices_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +def sample_list_paired_devices(): + # Create a client + client = health_v4.HealthProfileServiceClient() + + # Initialize request argument(s) + request = health_v4.ListPairedDevicesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_paired_devices(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END health_v4_generated_HealthProfileService_ListPairedDevices_sync] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_update_profile_async.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_update_profile_async.py new file mode 100644 index 000000000000..d0722c1643c1 --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_update_profile_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateProfile +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_HealthProfileService_UpdateProfile_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +async def sample_update_profile(): + # Create a client + client = health_v4.HealthProfileServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.UpdateProfileRequest() + + # Make the request + response = await client.update_profile(request=request) + + # Handle the response + print(response) + + +# [END health_v4_generated_HealthProfileService_UpdateProfile_async] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_update_profile_sync.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_update_profile_sync.py new file mode 100644 index 000000000000..65dea0bc55ce --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_update_profile_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateProfile +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_HealthProfileService_UpdateProfile_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +def sample_update_profile(): + # Create a client + client = health_v4.HealthProfileServiceClient() + + # Initialize request argument(s) + request = health_v4.UpdateProfileRequest() + + # Make the request + response = client.update_profile(request=request) + + # Handle the response + print(response) + + +# [END health_v4_generated_HealthProfileService_UpdateProfile_sync] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_update_settings_async.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_update_settings_async.py new file mode 100644 index 000000000000..5b6aa3bbb1c9 --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_update_settings_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateSettings +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_HealthProfileService_UpdateSettings_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +async def sample_update_settings(): + # Create a client + client = health_v4.HealthProfileServiceAsyncClient() + + # Initialize request argument(s) + request = health_v4.UpdateSettingsRequest() + + # Make the request + response = await client.update_settings(request=request) + + # Handle the response + print(response) + + +# [END health_v4_generated_HealthProfileService_UpdateSettings_async] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_update_settings_sync.py b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_update_settings_sync.py new file mode 100644 index 000000000000..8469eb7828cc --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/health_v4_generated_health_profile_service_update_settings_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateSettings +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-devicesandservices-health + + +# [START health_v4_generated_HealthProfileService_UpdateSettings_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.devicesandservices import health_v4 + + +def sample_update_settings(): + # Create a client + client = health_v4.HealthProfileServiceClient() + + # Initialize request argument(s) + request = health_v4.UpdateSettingsRequest() + + # Make the request + response = client.update_settings(request=request) + + # Handle the response + print(response) + + +# [END health_v4_generated_HealthProfileService_UpdateSettings_sync] diff --git a/packages/google-devicesandservices-health/samples/generated_samples/snippet_metadata_google.devicesandservices.health.v4.json b/packages/google-devicesandservices-health/samples/generated_samples/snippet_metadata_google.devicesandservices.health.v4.json new file mode 100644 index 000000000000..3bfd37bf444a --- /dev/null +++ b/packages/google-devicesandservices-health/samples/generated_samples/snippet_metadata_google.devicesandservices.health.v4.json @@ -0,0 +1,4074 @@ +{ + "clientLibrary": { + "apis": [ + { + "id": "google.devicesandservices.health.v4", + "version": "v4" + } + ], + "language": "PYTHON", + "name": "google-devicesandservices-health", + "version": "0.0.0" + }, + "snippets": [ + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.devicesandservices.health_v4.DataPointsServiceAsyncClient", + "shortName": "DataPointsServiceAsyncClient" + }, + "fullName": "google.devicesandservices.health_v4.DataPointsServiceAsyncClient.batch_delete_data_points", + "method": { + "fullName": "google.devicesandservices.health.v4.DataPointsService.BatchDeleteDataPoints", + "service": { + "fullName": "google.devicesandservices.health.v4.DataPointsService", + "shortName": "DataPointsService" + }, + "shortName": "BatchDeleteDataPoints" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.BatchDeleteDataPointsRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "batch_delete_data_points" + }, + "description": "Sample for BatchDeleteDataPoints", + "file": "health_v4_generated_data_points_service_batch_delete_data_points_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataPointsService_BatchDeleteDataPoints_async", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_points_service_batch_delete_data_points_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.devicesandservices.health_v4.DataPointsServiceClient", + "shortName": "DataPointsServiceClient" + }, + "fullName": "google.devicesandservices.health_v4.DataPointsServiceClient.batch_delete_data_points", + "method": { + "fullName": "google.devicesandservices.health.v4.DataPointsService.BatchDeleteDataPoints", + "service": { + "fullName": "google.devicesandservices.health.v4.DataPointsService", + "shortName": "DataPointsService" + }, + "shortName": "BatchDeleteDataPoints" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.BatchDeleteDataPointsRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "batch_delete_data_points" + }, + "description": "Sample for BatchDeleteDataPoints", + "file": "health_v4_generated_data_points_service_batch_delete_data_points_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataPointsService_BatchDeleteDataPoints_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_points_service_batch_delete_data_points_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.devicesandservices.health_v4.DataPointsServiceAsyncClient", + "shortName": "DataPointsServiceAsyncClient" + }, + "fullName": "google.devicesandservices.health_v4.DataPointsServiceAsyncClient.create_data_point", + "method": { + "fullName": "google.devicesandservices.health.v4.DataPointsService.CreateDataPoint", + "service": { + "fullName": "google.devicesandservices.health.v4.DataPointsService", + "shortName": "DataPointsService" + }, + "shortName": "CreateDataPoint" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.CreateDataPointRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "data_point", + "type": "google.devicesandservices.health_v4.types.DataPoint" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "create_data_point" + }, + "description": "Sample for CreateDataPoint", + "file": "health_v4_generated_data_points_service_create_data_point_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataPointsService_CreateDataPoint_async", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_points_service_create_data_point_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.devicesandservices.health_v4.DataPointsServiceClient", + "shortName": "DataPointsServiceClient" + }, + "fullName": "google.devicesandservices.health_v4.DataPointsServiceClient.create_data_point", + "method": { + "fullName": "google.devicesandservices.health.v4.DataPointsService.CreateDataPoint", + "service": { + "fullName": "google.devicesandservices.health.v4.DataPointsService", + "shortName": "DataPointsService" + }, + "shortName": "CreateDataPoint" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.CreateDataPointRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "data_point", + "type": "google.devicesandservices.health_v4.types.DataPoint" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "create_data_point" + }, + "description": "Sample for CreateDataPoint", + "file": "health_v4_generated_data_points_service_create_data_point_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataPointsService_CreateDataPoint_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_points_service_create_data_point_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.devicesandservices.health_v4.DataPointsServiceAsyncClient", + "shortName": "DataPointsServiceAsyncClient" + }, + "fullName": "google.devicesandservices.health_v4.DataPointsServiceAsyncClient.daily_roll_up_data_points", + "method": { + "fullName": "google.devicesandservices.health.v4.DataPointsService.DailyRollUpDataPoints", + "service": { + "fullName": "google.devicesandservices.health.v4.DataPointsService", + "shortName": "DataPointsService" + }, + "shortName": "DailyRollUpDataPoints" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.DailyRollUpDataPointsRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.types.DailyRollUpDataPointsResponse", + "shortName": "daily_roll_up_data_points" + }, + "description": "Sample for DailyRollUpDataPoints", + "file": "health_v4_generated_data_points_service_daily_roll_up_data_points_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataPointsService_DailyRollUpDataPoints_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_points_service_daily_roll_up_data_points_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.devicesandservices.health_v4.DataPointsServiceClient", + "shortName": "DataPointsServiceClient" + }, + "fullName": "google.devicesandservices.health_v4.DataPointsServiceClient.daily_roll_up_data_points", + "method": { + "fullName": "google.devicesandservices.health.v4.DataPointsService.DailyRollUpDataPoints", + "service": { + "fullName": "google.devicesandservices.health.v4.DataPointsService", + "shortName": "DataPointsService" + }, + "shortName": "DailyRollUpDataPoints" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.DailyRollUpDataPointsRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.types.DailyRollUpDataPointsResponse", + "shortName": "daily_roll_up_data_points" + }, + "description": "Sample for DailyRollUpDataPoints", + "file": "health_v4_generated_data_points_service_daily_roll_up_data_points_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataPointsService_DailyRollUpDataPoints_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_points_service_daily_roll_up_data_points_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.devicesandservices.health_v4.DataPointsServiceAsyncClient", + "shortName": "DataPointsServiceAsyncClient" + }, + "fullName": "google.devicesandservices.health_v4.DataPointsServiceAsyncClient.export_exercise_tcx", + "method": { + "fullName": "google.devicesandservices.health.v4.DataPointsService.ExportExerciseTcx", + "service": { + "fullName": "google.devicesandservices.health.v4.DataPointsService", + "shortName": "DataPointsService" + }, + "shortName": "ExportExerciseTcx" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.ExportExerciseTcxRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.types.ExportExerciseTcxResponse", + "shortName": "export_exercise_tcx" + }, + "description": "Sample for ExportExerciseTcx", + "file": "health_v4_generated_data_points_service_export_exercise_tcx_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataPointsService_ExportExerciseTcx_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_points_service_export_exercise_tcx_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.devicesandservices.health_v4.DataPointsServiceClient", + "shortName": "DataPointsServiceClient" + }, + "fullName": "google.devicesandservices.health_v4.DataPointsServiceClient.export_exercise_tcx", + "method": { + "fullName": "google.devicesandservices.health.v4.DataPointsService.ExportExerciseTcx", + "service": { + "fullName": "google.devicesandservices.health.v4.DataPointsService", + "shortName": "DataPointsService" + }, + "shortName": "ExportExerciseTcx" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.ExportExerciseTcxRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.types.ExportExerciseTcxResponse", + "shortName": "export_exercise_tcx" + }, + "description": "Sample for ExportExerciseTcx", + "file": "health_v4_generated_data_points_service_export_exercise_tcx_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataPointsService_ExportExerciseTcx_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_points_service_export_exercise_tcx_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.devicesandservices.health_v4.DataPointsServiceAsyncClient", + "shortName": "DataPointsServiceAsyncClient" + }, + "fullName": "google.devicesandservices.health_v4.DataPointsServiceAsyncClient.get_data_point", + "method": { + "fullName": "google.devicesandservices.health.v4.DataPointsService.GetDataPoint", + "service": { + "fullName": "google.devicesandservices.health.v4.DataPointsService", + "shortName": "DataPointsService" + }, + "shortName": "GetDataPoint" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.GetDataPointRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.types.DataPoint", + "shortName": "get_data_point" + }, + "description": "Sample for GetDataPoint", + "file": "health_v4_generated_data_points_service_get_data_point_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataPointsService_GetDataPoint_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_points_service_get_data_point_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.devicesandservices.health_v4.DataPointsServiceClient", + "shortName": "DataPointsServiceClient" + }, + "fullName": "google.devicesandservices.health_v4.DataPointsServiceClient.get_data_point", + "method": { + "fullName": "google.devicesandservices.health.v4.DataPointsService.GetDataPoint", + "service": { + "fullName": "google.devicesandservices.health.v4.DataPointsService", + "shortName": "DataPointsService" + }, + "shortName": "GetDataPoint" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.GetDataPointRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.types.DataPoint", + "shortName": "get_data_point" + }, + "description": "Sample for GetDataPoint", + "file": "health_v4_generated_data_points_service_get_data_point_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataPointsService_GetDataPoint_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_points_service_get_data_point_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.devicesandservices.health_v4.DataPointsServiceAsyncClient", + "shortName": "DataPointsServiceAsyncClient" + }, + "fullName": "google.devicesandservices.health_v4.DataPointsServiceAsyncClient.list_data_points", + "method": { + "fullName": "google.devicesandservices.health.v4.DataPointsService.ListDataPoints", + "service": { + "fullName": "google.devicesandservices.health.v4.DataPointsService", + "shortName": "DataPointsService" + }, + "shortName": "ListDataPoints" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.ListDataPointsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.services.data_points_service.pagers.ListDataPointsAsyncPager", + "shortName": "list_data_points" + }, + "description": "Sample for ListDataPoints", + "file": "health_v4_generated_data_points_service_list_data_points_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataPointsService_ListDataPoints_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_points_service_list_data_points_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.devicesandservices.health_v4.DataPointsServiceClient", + "shortName": "DataPointsServiceClient" + }, + "fullName": "google.devicesandservices.health_v4.DataPointsServiceClient.list_data_points", + "method": { + "fullName": "google.devicesandservices.health.v4.DataPointsService.ListDataPoints", + "service": { + "fullName": "google.devicesandservices.health.v4.DataPointsService", + "shortName": "DataPointsService" + }, + "shortName": "ListDataPoints" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.ListDataPointsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.services.data_points_service.pagers.ListDataPointsPager", + "shortName": "list_data_points" + }, + "description": "Sample for ListDataPoints", + "file": "health_v4_generated_data_points_service_list_data_points_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataPointsService_ListDataPoints_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_points_service_list_data_points_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.devicesandservices.health_v4.DataPointsServiceAsyncClient", + "shortName": "DataPointsServiceAsyncClient" + }, + "fullName": "google.devicesandservices.health_v4.DataPointsServiceAsyncClient.reconcile_data_points", + "method": { + "fullName": "google.devicesandservices.health.v4.DataPointsService.ReconcileDataPoints", + "service": { + "fullName": "google.devicesandservices.health.v4.DataPointsService", + "shortName": "DataPointsService" + }, + "shortName": "ReconcileDataPoints" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.ReconcileDataPointsRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.services.data_points_service.pagers.ReconcileDataPointsAsyncPager", + "shortName": "reconcile_data_points" + }, + "description": "Sample for ReconcileDataPoints", + "file": "health_v4_generated_data_points_service_reconcile_data_points_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataPointsService_ReconcileDataPoints_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_points_service_reconcile_data_points_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.devicesandservices.health_v4.DataPointsServiceClient", + "shortName": "DataPointsServiceClient" + }, + "fullName": "google.devicesandservices.health_v4.DataPointsServiceClient.reconcile_data_points", + "method": { + "fullName": "google.devicesandservices.health.v4.DataPointsService.ReconcileDataPoints", + "service": { + "fullName": "google.devicesandservices.health.v4.DataPointsService", + "shortName": "DataPointsService" + }, + "shortName": "ReconcileDataPoints" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.ReconcileDataPointsRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.services.data_points_service.pagers.ReconcileDataPointsPager", + "shortName": "reconcile_data_points" + }, + "description": "Sample for ReconcileDataPoints", + "file": "health_v4_generated_data_points_service_reconcile_data_points_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataPointsService_ReconcileDataPoints_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_points_service_reconcile_data_points_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.devicesandservices.health_v4.DataPointsServiceAsyncClient", + "shortName": "DataPointsServiceAsyncClient" + }, + "fullName": "google.devicesandservices.health_v4.DataPointsServiceAsyncClient.roll_up_data_points", + "method": { + "fullName": "google.devicesandservices.health.v4.DataPointsService.RollUpDataPoints", + "service": { + "fullName": "google.devicesandservices.health.v4.DataPointsService", + "shortName": "DataPointsService" + }, + "shortName": "RollUpDataPoints" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.RollUpDataPointsRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.services.data_points_service.pagers.RollUpDataPointsAsyncPager", + "shortName": "roll_up_data_points" + }, + "description": "Sample for RollUpDataPoints", + "file": "health_v4_generated_data_points_service_roll_up_data_points_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataPointsService_RollUpDataPoints_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_points_service_roll_up_data_points_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.devicesandservices.health_v4.DataPointsServiceClient", + "shortName": "DataPointsServiceClient" + }, + "fullName": "google.devicesandservices.health_v4.DataPointsServiceClient.roll_up_data_points", + "method": { + "fullName": "google.devicesandservices.health.v4.DataPointsService.RollUpDataPoints", + "service": { + "fullName": "google.devicesandservices.health.v4.DataPointsService", + "shortName": "DataPointsService" + }, + "shortName": "RollUpDataPoints" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.RollUpDataPointsRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.services.data_points_service.pagers.RollUpDataPointsPager", + "shortName": "roll_up_data_points" + }, + "description": "Sample for RollUpDataPoints", + "file": "health_v4_generated_data_points_service_roll_up_data_points_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataPointsService_RollUpDataPoints_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_points_service_roll_up_data_points_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.devicesandservices.health_v4.DataPointsServiceAsyncClient", + "shortName": "DataPointsServiceAsyncClient" + }, + "fullName": "google.devicesandservices.health_v4.DataPointsServiceAsyncClient.update_data_point", + "method": { + "fullName": "google.devicesandservices.health.v4.DataPointsService.UpdateDataPoint", + "service": { + "fullName": "google.devicesandservices.health.v4.DataPointsService", + "shortName": "DataPointsService" + }, + "shortName": "UpdateDataPoint" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.UpdateDataPointRequest" + }, + { + "name": "data_point", + "type": "google.devicesandservices.health_v4.types.DataPoint" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "update_data_point" + }, + "description": "Sample for UpdateDataPoint", + "file": "health_v4_generated_data_points_service_update_data_point_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataPointsService_UpdateDataPoint_async", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_points_service_update_data_point_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.devicesandservices.health_v4.DataPointsServiceClient", + "shortName": "DataPointsServiceClient" + }, + "fullName": "google.devicesandservices.health_v4.DataPointsServiceClient.update_data_point", + "method": { + "fullName": "google.devicesandservices.health.v4.DataPointsService.UpdateDataPoint", + "service": { + "fullName": "google.devicesandservices.health.v4.DataPointsService", + "shortName": "DataPointsService" + }, + "shortName": "UpdateDataPoint" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.UpdateDataPointRequest" + }, + { + "name": "data_point", + "type": "google.devicesandservices.health_v4.types.DataPoint" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "update_data_point" + }, + "description": "Sample for UpdateDataPoint", + "file": "health_v4_generated_data_points_service_update_data_point_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataPointsService_UpdateDataPoint_sync", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_points_service_update_data_point_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceAsyncClient", + "shortName": "DataSubscriptionServiceAsyncClient" + }, + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceAsyncClient.create_subscriber", + "method": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService.CreateSubscriber", + "service": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService", + "shortName": "DataSubscriptionService" + }, + "shortName": "CreateSubscriber" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.CreateSubscriberRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "subscriber", + "type": "google.devicesandservices.health_v4.types.CreateSubscriberPayload" + }, + { + "name": "subscriber_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "create_subscriber" + }, + "description": "Sample for CreateSubscriber", + "file": "health_v4_generated_data_subscription_service_create_subscriber_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataSubscriptionService_CreateSubscriber_async", + "segments": [ + { + "end": 60, + "start": 27, + "type": "FULL" + }, + { + "end": 60, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 57, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 61, + "start": 58, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_subscription_service_create_subscriber_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceClient", + "shortName": "DataSubscriptionServiceClient" + }, + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceClient.create_subscriber", + "method": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService.CreateSubscriber", + "service": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService", + "shortName": "DataSubscriptionService" + }, + "shortName": "CreateSubscriber" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.CreateSubscriberRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "subscriber", + "type": "google.devicesandservices.health_v4.types.CreateSubscriberPayload" + }, + { + "name": "subscriber_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "create_subscriber" + }, + "description": "Sample for CreateSubscriber", + "file": "health_v4_generated_data_subscription_service_create_subscriber_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataSubscriptionService_CreateSubscriber_sync", + "segments": [ + { + "end": 60, + "start": 27, + "type": "FULL" + }, + { + "end": 60, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 57, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 61, + "start": 58, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_subscription_service_create_subscriber_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceAsyncClient", + "shortName": "DataSubscriptionServiceAsyncClient" + }, + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceAsyncClient.create_subscription", + "method": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService.CreateSubscription", + "service": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService", + "shortName": "DataSubscriptionService" + }, + "shortName": "CreateSubscription" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.CreateSubscriptionRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "subscription", + "type": "google.devicesandservices.health_v4.types.CreateSubscriptionPayload" + }, + { + "name": "subscription_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.types.Subscription", + "shortName": "create_subscription" + }, + "description": "Sample for CreateSubscription", + "file": "health_v4_generated_data_subscription_service_create_subscription_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataSubscriptionService_CreateSubscription_async", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 49, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 50, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_subscription_service_create_subscription_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceClient", + "shortName": "DataSubscriptionServiceClient" + }, + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceClient.create_subscription", + "method": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService.CreateSubscription", + "service": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService", + "shortName": "DataSubscriptionService" + }, + "shortName": "CreateSubscription" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.CreateSubscriptionRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "subscription", + "type": "google.devicesandservices.health_v4.types.CreateSubscriptionPayload" + }, + { + "name": "subscription_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.types.Subscription", + "shortName": "create_subscription" + }, + "description": "Sample for CreateSubscription", + "file": "health_v4_generated_data_subscription_service_create_subscription_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataSubscriptionService_CreateSubscription_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 49, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 50, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_subscription_service_create_subscription_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceAsyncClient", + "shortName": "DataSubscriptionServiceAsyncClient" + }, + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceAsyncClient.delete_subscriber", + "method": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService.DeleteSubscriber", + "service": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService", + "shortName": "DataSubscriptionService" + }, + "shortName": "DeleteSubscriber" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.DeleteSubscriberRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "delete_subscriber" + }, + "description": "Sample for DeleteSubscriber", + "file": "health_v4_generated_data_subscription_service_delete_subscriber_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataSubscriptionService_DeleteSubscriber_async", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_subscription_service_delete_subscriber_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceClient", + "shortName": "DataSubscriptionServiceClient" + }, + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceClient.delete_subscriber", + "method": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService.DeleteSubscriber", + "service": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService", + "shortName": "DataSubscriptionService" + }, + "shortName": "DeleteSubscriber" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.DeleteSubscriberRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "delete_subscriber" + }, + "description": "Sample for DeleteSubscriber", + "file": "health_v4_generated_data_subscription_service_delete_subscriber_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataSubscriptionService_DeleteSubscriber_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_subscription_service_delete_subscriber_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceAsyncClient", + "shortName": "DataSubscriptionServiceAsyncClient" + }, + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceAsyncClient.delete_subscription", + "method": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService.DeleteSubscription", + "service": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService", + "shortName": "DataSubscriptionService" + }, + "shortName": "DeleteSubscription" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.DeleteSubscriptionRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "shortName": "delete_subscription" + }, + "description": "Sample for DeleteSubscription", + "file": "health_v4_generated_data_subscription_service_delete_subscription_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataSubscriptionService_DeleteSubscription_async", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_subscription_service_delete_subscription_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceClient", + "shortName": "DataSubscriptionServiceClient" + }, + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceClient.delete_subscription", + "method": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService.DeleteSubscription", + "service": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService", + "shortName": "DataSubscriptionService" + }, + "shortName": "DeleteSubscription" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.DeleteSubscriptionRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "shortName": "delete_subscription" + }, + "description": "Sample for DeleteSubscription", + "file": "health_v4_generated_data_subscription_service_delete_subscription_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataSubscriptionService_DeleteSubscription_sync", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_subscription_service_delete_subscription_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceAsyncClient", + "shortName": "DataSubscriptionServiceAsyncClient" + }, + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceAsyncClient.list_subscribers", + "method": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService.ListSubscribers", + "service": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService", + "shortName": "DataSubscriptionService" + }, + "shortName": "ListSubscribers" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.ListSubscribersRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.services.data_subscription_service.pagers.ListSubscribersAsyncPager", + "shortName": "list_subscribers" + }, + "description": "Sample for ListSubscribers", + "file": "health_v4_generated_data_subscription_service_list_subscribers_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataSubscriptionService_ListSubscribers_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_subscription_service_list_subscribers_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceClient", + "shortName": "DataSubscriptionServiceClient" + }, + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceClient.list_subscribers", + "method": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService.ListSubscribers", + "service": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService", + "shortName": "DataSubscriptionService" + }, + "shortName": "ListSubscribers" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.ListSubscribersRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.services.data_subscription_service.pagers.ListSubscribersPager", + "shortName": "list_subscribers" + }, + "description": "Sample for ListSubscribers", + "file": "health_v4_generated_data_subscription_service_list_subscribers_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataSubscriptionService_ListSubscribers_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_subscription_service_list_subscribers_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceAsyncClient", + "shortName": "DataSubscriptionServiceAsyncClient" + }, + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceAsyncClient.list_subscriptions", + "method": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService.ListSubscriptions", + "service": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService", + "shortName": "DataSubscriptionService" + }, + "shortName": "ListSubscriptions" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.ListSubscriptionsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.services.data_subscription_service.pagers.ListSubscriptionsAsyncPager", + "shortName": "list_subscriptions" + }, + "description": "Sample for ListSubscriptions", + "file": "health_v4_generated_data_subscription_service_list_subscriptions_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataSubscriptionService_ListSubscriptions_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_subscription_service_list_subscriptions_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceClient", + "shortName": "DataSubscriptionServiceClient" + }, + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceClient.list_subscriptions", + "method": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService.ListSubscriptions", + "service": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService", + "shortName": "DataSubscriptionService" + }, + "shortName": "ListSubscriptions" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.ListSubscriptionsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.services.data_subscription_service.pagers.ListSubscriptionsPager", + "shortName": "list_subscriptions" + }, + "description": "Sample for ListSubscriptions", + "file": "health_v4_generated_data_subscription_service_list_subscriptions_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataSubscriptionService_ListSubscriptions_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_subscription_service_list_subscriptions_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceAsyncClient", + "shortName": "DataSubscriptionServiceAsyncClient" + }, + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceAsyncClient.update_subscriber", + "method": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService.UpdateSubscriber", + "service": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService", + "shortName": "DataSubscriptionService" + }, + "shortName": "UpdateSubscriber" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.UpdateSubscriberRequest" + }, + { + "name": "subscriber", + "type": "google.devicesandservices.health_v4.types.Subscriber" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "update_subscriber" + }, + "description": "Sample for UpdateSubscriber", + "file": "health_v4_generated_data_subscription_service_update_subscriber_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataSubscriptionService_UpdateSubscriber_async", + "segments": [ + { + "end": 59, + "start": 27, + "type": "FULL" + }, + { + "end": 59, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 49, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 56, + "start": 50, + "type": "REQUEST_EXECUTION" + }, + { + "end": 60, + "start": 57, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_subscription_service_update_subscriber_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceClient", + "shortName": "DataSubscriptionServiceClient" + }, + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceClient.update_subscriber", + "method": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService.UpdateSubscriber", + "service": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService", + "shortName": "DataSubscriptionService" + }, + "shortName": "UpdateSubscriber" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.UpdateSubscriberRequest" + }, + { + "name": "subscriber", + "type": "google.devicesandservices.health_v4.types.Subscriber" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "update_subscriber" + }, + "description": "Sample for UpdateSubscriber", + "file": "health_v4_generated_data_subscription_service_update_subscriber_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataSubscriptionService_UpdateSubscriber_sync", + "segments": [ + { + "end": 59, + "start": 27, + "type": "FULL" + }, + { + "end": 59, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 49, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 56, + "start": 50, + "type": "REQUEST_EXECUTION" + }, + { + "end": 60, + "start": 57, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_subscription_service_update_subscriber_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceAsyncClient", + "shortName": "DataSubscriptionServiceAsyncClient" + }, + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceAsyncClient.update_subscription", + "method": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService.UpdateSubscription", + "service": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService", + "shortName": "DataSubscriptionService" + }, + "shortName": "UpdateSubscription" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.UpdateSubscriptionRequest" + }, + { + "name": "subscription", + "type": "google.devicesandservices.health_v4.types.Subscription" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.types.Subscription", + "shortName": "update_subscription" + }, + "description": "Sample for UpdateSubscription", + "file": "health_v4_generated_data_subscription_service_update_subscription_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataSubscriptionService_UpdateSubscription_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_subscription_service_update_subscription_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceClient", + "shortName": "DataSubscriptionServiceClient" + }, + "fullName": "google.devicesandservices.health_v4.DataSubscriptionServiceClient.update_subscription", + "method": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService.UpdateSubscription", + "service": { + "fullName": "google.devicesandservices.health.v4.DataSubscriptionService", + "shortName": "DataSubscriptionService" + }, + "shortName": "UpdateSubscription" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.UpdateSubscriptionRequest" + }, + { + "name": "subscription", + "type": "google.devicesandservices.health_v4.types.Subscription" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.types.Subscription", + "shortName": "update_subscription" + }, + "description": "Sample for UpdateSubscription", + "file": "health_v4_generated_data_subscription_service_update_subscription_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_DataSubscriptionService_UpdateSubscription_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_data_subscription_service_update_subscription_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceAsyncClient", + "shortName": "HealthProfileServiceAsyncClient" + }, + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceAsyncClient.get_identity", + "method": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService.GetIdentity", + "service": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService", + "shortName": "HealthProfileService" + }, + "shortName": "GetIdentity" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.GetIdentityRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.types.Identity", + "shortName": "get_identity" + }, + "description": "Sample for GetIdentity", + "file": "health_v4_generated_health_profile_service_get_identity_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_HealthProfileService_GetIdentity_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_health_profile_service_get_identity_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceClient", + "shortName": "HealthProfileServiceClient" + }, + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceClient.get_identity", + "method": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService.GetIdentity", + "service": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService", + "shortName": "HealthProfileService" + }, + "shortName": "GetIdentity" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.GetIdentityRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.types.Identity", + "shortName": "get_identity" + }, + "description": "Sample for GetIdentity", + "file": "health_v4_generated_health_profile_service_get_identity_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_HealthProfileService_GetIdentity_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_health_profile_service_get_identity_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceAsyncClient", + "shortName": "HealthProfileServiceAsyncClient" + }, + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceAsyncClient.get_irn_profile", + "method": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService.GetIrnProfile", + "service": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService", + "shortName": "HealthProfileService" + }, + "shortName": "GetIrnProfile" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.GetIrnProfileRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.types.IrnProfile", + "shortName": "get_irn_profile" + }, + "description": "Sample for GetIrnProfile", + "file": "health_v4_generated_health_profile_service_get_irn_profile_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_HealthProfileService_GetIrnProfile_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_health_profile_service_get_irn_profile_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceClient", + "shortName": "HealthProfileServiceClient" + }, + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceClient.get_irn_profile", + "method": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService.GetIrnProfile", + "service": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService", + "shortName": "HealthProfileService" + }, + "shortName": "GetIrnProfile" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.GetIrnProfileRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.types.IrnProfile", + "shortName": "get_irn_profile" + }, + "description": "Sample for GetIrnProfile", + "file": "health_v4_generated_health_profile_service_get_irn_profile_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_HealthProfileService_GetIrnProfile_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_health_profile_service_get_irn_profile_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceAsyncClient", + "shortName": "HealthProfileServiceAsyncClient" + }, + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceAsyncClient.get_paired_device", + "method": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService.GetPairedDevice", + "service": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService", + "shortName": "HealthProfileService" + }, + "shortName": "GetPairedDevice" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.GetPairedDeviceRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.types.PairedDevice", + "shortName": "get_paired_device" + }, + "description": "Sample for GetPairedDevice", + "file": "health_v4_generated_health_profile_service_get_paired_device_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_HealthProfileService_GetPairedDevice_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_health_profile_service_get_paired_device_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceClient", + "shortName": "HealthProfileServiceClient" + }, + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceClient.get_paired_device", + "method": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService.GetPairedDevice", + "service": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService", + "shortName": "HealthProfileService" + }, + "shortName": "GetPairedDevice" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.GetPairedDeviceRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.types.PairedDevice", + "shortName": "get_paired_device" + }, + "description": "Sample for GetPairedDevice", + "file": "health_v4_generated_health_profile_service_get_paired_device_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_HealthProfileService_GetPairedDevice_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_health_profile_service_get_paired_device_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceAsyncClient", + "shortName": "HealthProfileServiceAsyncClient" + }, + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceAsyncClient.get_profile", + "method": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService.GetProfile", + "service": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService", + "shortName": "HealthProfileService" + }, + "shortName": "GetProfile" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.GetProfileRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.types.Profile", + "shortName": "get_profile" + }, + "description": "Sample for GetProfile", + "file": "health_v4_generated_health_profile_service_get_profile_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_HealthProfileService_GetProfile_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_health_profile_service_get_profile_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceClient", + "shortName": "HealthProfileServiceClient" + }, + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceClient.get_profile", + "method": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService.GetProfile", + "service": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService", + "shortName": "HealthProfileService" + }, + "shortName": "GetProfile" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.GetProfileRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.types.Profile", + "shortName": "get_profile" + }, + "description": "Sample for GetProfile", + "file": "health_v4_generated_health_profile_service_get_profile_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_HealthProfileService_GetProfile_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_health_profile_service_get_profile_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceAsyncClient", + "shortName": "HealthProfileServiceAsyncClient" + }, + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceAsyncClient.get_settings", + "method": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService.GetSettings", + "service": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService", + "shortName": "HealthProfileService" + }, + "shortName": "GetSettings" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.GetSettingsRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.types.Settings", + "shortName": "get_settings" + }, + "description": "Sample for GetSettings", + "file": "health_v4_generated_health_profile_service_get_settings_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_HealthProfileService_GetSettings_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_health_profile_service_get_settings_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceClient", + "shortName": "HealthProfileServiceClient" + }, + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceClient.get_settings", + "method": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService.GetSettings", + "service": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService", + "shortName": "HealthProfileService" + }, + "shortName": "GetSettings" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.GetSettingsRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.types.Settings", + "shortName": "get_settings" + }, + "description": "Sample for GetSettings", + "file": "health_v4_generated_health_profile_service_get_settings_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_HealthProfileService_GetSettings_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_health_profile_service_get_settings_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceAsyncClient", + "shortName": "HealthProfileServiceAsyncClient" + }, + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceAsyncClient.list_paired_devices", + "method": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService.ListPairedDevices", + "service": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService", + "shortName": "HealthProfileService" + }, + "shortName": "ListPairedDevices" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.ListPairedDevicesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.services.health_profile_service.pagers.ListPairedDevicesAsyncPager", + "shortName": "list_paired_devices" + }, + "description": "Sample for ListPairedDevices", + "file": "health_v4_generated_health_profile_service_list_paired_devices_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_HealthProfileService_ListPairedDevices_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_health_profile_service_list_paired_devices_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceClient", + "shortName": "HealthProfileServiceClient" + }, + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceClient.list_paired_devices", + "method": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService.ListPairedDevices", + "service": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService", + "shortName": "HealthProfileService" + }, + "shortName": "ListPairedDevices" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.ListPairedDevicesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.services.health_profile_service.pagers.ListPairedDevicesPager", + "shortName": "list_paired_devices" + }, + "description": "Sample for ListPairedDevices", + "file": "health_v4_generated_health_profile_service_list_paired_devices_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_HealthProfileService_ListPairedDevices_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_health_profile_service_list_paired_devices_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceAsyncClient", + "shortName": "HealthProfileServiceAsyncClient" + }, + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceAsyncClient.update_profile", + "method": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService.UpdateProfile", + "service": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService", + "shortName": "HealthProfileService" + }, + "shortName": "UpdateProfile" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.UpdateProfileRequest" + }, + { + "name": "profile", + "type": "google.devicesandservices.health_v4.types.Profile" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.types.Profile", + "shortName": "update_profile" + }, + "description": "Sample for UpdateProfile", + "file": "health_v4_generated_health_profile_service_update_profile_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_HealthProfileService_UpdateProfile_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_health_profile_service_update_profile_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceClient", + "shortName": "HealthProfileServiceClient" + }, + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceClient.update_profile", + "method": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService.UpdateProfile", + "service": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService", + "shortName": "HealthProfileService" + }, + "shortName": "UpdateProfile" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.UpdateProfileRequest" + }, + { + "name": "profile", + "type": "google.devicesandservices.health_v4.types.Profile" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.types.Profile", + "shortName": "update_profile" + }, + "description": "Sample for UpdateProfile", + "file": "health_v4_generated_health_profile_service_update_profile_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_HealthProfileService_UpdateProfile_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_health_profile_service_update_profile_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceAsyncClient", + "shortName": "HealthProfileServiceAsyncClient" + }, + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceAsyncClient.update_settings", + "method": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService.UpdateSettings", + "service": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService", + "shortName": "HealthProfileService" + }, + "shortName": "UpdateSettings" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.UpdateSettingsRequest" + }, + { + "name": "settings", + "type": "google.devicesandservices.health_v4.types.Settings" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.types.Settings", + "shortName": "update_settings" + }, + "description": "Sample for UpdateSettings", + "file": "health_v4_generated_health_profile_service_update_settings_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_HealthProfileService_UpdateSettings_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_health_profile_service_update_settings_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceClient", + "shortName": "HealthProfileServiceClient" + }, + "fullName": "google.devicesandservices.health_v4.HealthProfileServiceClient.update_settings", + "method": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService.UpdateSettings", + "service": { + "fullName": "google.devicesandservices.health.v4.HealthProfileService", + "shortName": "HealthProfileService" + }, + "shortName": "UpdateSettings" + }, + "parameters": [ + { + "name": "request", + "type": "google.devicesandservices.health_v4.types.UpdateSettingsRequest" + }, + { + "name": "settings", + "type": "google.devicesandservices.health_v4.types.Settings" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.devicesandservices.health_v4.types.Settings", + "shortName": "update_settings" + }, + "description": "Sample for UpdateSettings", + "file": "health_v4_generated_health_profile_service_update_settings_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "health_v4_generated_HealthProfileService_UpdateSettings_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "health_v4_generated_health_profile_service_update_settings_sync.py" + } + ] +} diff --git a/packages/google-devicesandservices-health/setup.py b/packages/google-devicesandservices-health/setup.py new file mode 100644 index 000000000000..b87889d68543 --- /dev/null +++ b/packages/google-devicesandservices-health/setup.py @@ -0,0 +1,99 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 re + +import setuptools # type: ignore + +package_root = os.path.abspath(os.path.dirname(__file__)) + +name = "google-devicesandservices-health" + + +description = "Google Devicesandservices Health API client library" + +version = None + +with open( + os.path.join(package_root, "google/devicesandservices/health/gapic_version.py") +) as fp: + version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + assert len(version_candidates) == 1 + version = version_candidates[0] + +if version[0] == "0": + release_status = "Development Status :: 4 - Beta" +else: + release_status = "Development Status :: 5 - Production/Stable" + +dependencies = [ + "google-api-core[grpc] >= 2.17.1, <3.0.0", + # Exclude incompatible versions of `google-auth` + # See https://github.com/googleapis/google-cloud-python/issues/12364 + "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", + "grpcio >= 1.59.0, < 2.0.0", + "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", + "proto-plus >= 1.22.3, <2.0.0", + "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", + "protobuf >= 4.25.8, < 8.0.0", +] +extras = {} +url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-devicesandservices-health" + +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() + +packages = [ + package + for package in setuptools.find_namespace_packages() + if package.startswith("google") +] + +setuptools.setup( + name=name, + version=version, + description=description, + long_description=readme, + author="Google LLC", + author_email="googleapis-packages@google.com", + license="Apache-2.0", + url=url, + classifiers=[ + release_status, + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", + "Operating System :: OS Independent", + "Topic :: Internet", + ], + platforms="Posix; MacOS X; Windows", + packages=packages, + python_requires=">=3.10", + install_requires=dependencies, + extras_require=extras, + include_package_data=True, + zip_safe=False, +) diff --git a/packages/google-devicesandservices-health/testing/constraints-3.10.txt b/packages/google-devicesandservices-health/testing/constraints-3.10.txt new file mode 100644 index 000000000000..7be9c36933fc --- /dev/null +++ b/packages/google-devicesandservices-health/testing/constraints-3.10.txt @@ -0,0 +1,11 @@ +# This constraints file is used to check that lower bounds +# are correct in setup.py +# List all library dependencies and extras in this file, +# pinning their versions to their lower bounds. +# For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", +# then this file should have google-cloud-foo==1.14.0 +google-api-core==2.17.1 +google-auth==2.14.1 +grpcio==1.59.0 +proto-plus==1.22.3 +protobuf==4.25.8 diff --git a/packages/google-devicesandservices-health/testing/constraints-3.11.txt b/packages/google-devicesandservices-health/testing/constraints-3.11.txt new file mode 100644 index 000000000000..7599dea499ed --- /dev/null +++ b/packages/google-devicesandservices-health/testing/constraints-3.11.txt @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +google-auth +grpcio +proto-plus +protobuf +# cryptography is a direct dependency of google-auth +cryptography diff --git a/packages/google-devicesandservices-health/testing/constraints-3.12.txt b/packages/google-devicesandservices-health/testing/constraints-3.12.txt new file mode 100644 index 000000000000..7599dea499ed --- /dev/null +++ b/packages/google-devicesandservices-health/testing/constraints-3.12.txt @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +google-auth +grpcio +proto-plus +protobuf +# cryptography is a direct dependency of google-auth +cryptography diff --git a/packages/google-devicesandservices-health/testing/constraints-3.13.txt b/packages/google-devicesandservices-health/testing/constraints-3.13.txt new file mode 100644 index 000000000000..1e93c60e50aa --- /dev/null +++ b/packages/google-devicesandservices-health/testing/constraints-3.13.txt @@ -0,0 +1,12 @@ +# We use the constraints file for the latest Python version +# (currently this file) to check that the latest +# major versions of dependencies are supported in setup.py. +# List all library dependencies and extras in this file. +# Require the latest major version be installed for each dependency. +# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", +# Then this file should have google-cloud-foo>=1 +google-api-core>=2 +google-auth>=2 +grpcio>=1 +proto-plus>=1 +protobuf>=6 diff --git a/packages/google-devicesandservices-health/testing/constraints-3.14.txt b/packages/google-devicesandservices-health/testing/constraints-3.14.txt new file mode 100644 index 000000000000..1e93c60e50aa --- /dev/null +++ b/packages/google-devicesandservices-health/testing/constraints-3.14.txt @@ -0,0 +1,12 @@ +# We use the constraints file for the latest Python version +# (currently this file) to check that the latest +# major versions of dependencies are supported in setup.py. +# List all library dependencies and extras in this file. +# Require the latest major version be installed for each dependency. +# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", +# Then this file should have google-cloud-foo>=1 +google-api-core>=2 +google-auth>=2 +grpcio>=1 +proto-plus>=1 +protobuf>=6 diff --git a/packages/google-devicesandservices-health/tests/__init__.py b/packages/google-devicesandservices-health/tests/__init__.py new file mode 100644 index 000000000000..32b36c5c4fe0 --- /dev/null +++ b/packages/google-devicesandservices-health/tests/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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/packages/google-devicesandservices-health/tests/unit/__init__.py b/packages/google-devicesandservices-health/tests/unit/__init__.py new file mode 100644 index 000000000000..32b36c5c4fe0 --- /dev/null +++ b/packages/google-devicesandservices-health/tests/unit/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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/packages/google-devicesandservices-health/tests/unit/gapic/__init__.py b/packages/google-devicesandservices-health/tests/unit/gapic/__init__.py new file mode 100644 index 000000000000..32b36c5c4fe0 --- /dev/null +++ b/packages/google-devicesandservices-health/tests/unit/gapic/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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/packages/google-devicesandservices-health/tests/unit/gapic/health_v4/__init__.py b/packages/google-devicesandservices-health/tests/unit/gapic/health_v4/__init__.py new file mode 100644 index 000000000000..32b36c5c4fe0 --- /dev/null +++ b/packages/google-devicesandservices-health/tests/unit/gapic/health_v4/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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/packages/google-devicesandservices-health/tests/unit/gapic/health_v4/test_data_points_service.py b/packages/google-devicesandservices-health/tests/unit/gapic/health_v4/test_data_points_service.py new file mode 100644 index 000000000000..09f6cc35bcde --- /dev/null +++ b/packages/google-devicesandservices-health/tests/unit/gapic/health_v4/test_data_points_service.py @@ -0,0 +1,10005 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 asyncio +import json +import math +import os +from collections.abc import AsyncIterable, Iterable, Mapping, Sequence +from unittest import mock +from unittest.mock import AsyncMock + +import grpc +import pytest +from google.api_core import api_core_version +from google.protobuf import json_format +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +import google.api_core.operation_async as operation_async # type: ignore +import google.auth +import google.protobuf.duration_pb2 as duration_pb2 # type: ignore +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore +import google.type.date_pb2 as date_pb2 # type: ignore +import google.type.interval_pb2 as interval_pb2 # type: ignore +import google.type.timeofday_pb2 as timeofday_pb2 # type: ignore +from google.api_core import ( + client_options, + future, + gapic_v1, + grpc_helpers, + grpc_helpers_async, + operation, + operations_v1, + path_template, +) +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account + +from google.devicesandservices.health_v4.services.data_points_service import ( + DataPointsServiceAsyncClient, + DataPointsServiceClient, + pagers, + transports, +) +from google.devicesandservices.health_v4.types import ( + data_coordinates, + data_model, + data_points, + data_source, + medical_device_info, +) + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + +# 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 + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +@pytest.fixture(autouse=True) +def set_event_loop(): + try: + asyncio.get_running_loop() + yield + except RuntimeError: + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + try: + yield + finally: + loop.close() + asyncio.set_event_loop(None) + + +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" + custom_endpoint = ".custom" + + assert DataPointsServiceClient._get_default_mtls_endpoint(None) is None + assert ( + DataPointsServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + DataPointsServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + DataPointsServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + DataPointsServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + DataPointsServiceClient._get_default_mtls_endpoint(non_googleapi) + == non_googleapi + ) + assert ( + DataPointsServiceClient._get_default_mtls_endpoint(custom_endpoint) + == custom_endpoint + ) + + +def test__read_environment_variables(): + assert DataPointsServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert DataPointsServiceClient._read_environment_variables() == ( + True, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert DataPointsServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with pytest.raises(ValueError) as excinfo: + DataPointsServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + else: + assert DataPointsServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert DataPointsServiceClient._read_environment_variables() == ( + False, + "never", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert DataPointsServiceClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert DataPointsServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + DataPointsServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert DataPointsServiceClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test_use_client_cert_effective(): + # Test case 1: Test when `should_use_client_cert` returns True. + # We mock the `should_use_client_cert` function to simulate a scenario where + # the google-auth library supports automatic mTLS and determines that a + # client certificate should be used. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch( + "google.auth.transport.mtls.should_use_client_cert", return_value=True + ): + assert DataPointsServiceClient._use_client_cert_effective() is True + + # Test case 2: Test when `should_use_client_cert` returns False. + # We mock the `should_use_client_cert` function to simulate a scenario where + # the google-auth library supports automatic mTLS and determines that a + # client certificate should NOT be used. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch( + "google.auth.transport.mtls.should_use_client_cert", return_value=False + ): + assert DataPointsServiceClient._use_client_cert_effective() is False + + # Test case 3: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "true". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert DataPointsServiceClient._use_client_cert_effective() is True + + # Test case 4: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "false". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"} + ): + assert DataPointsServiceClient._use_client_cert_effective() is False + + # Test case 5: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "True". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "True"}): + assert DataPointsServiceClient._use_client_cert_effective() is True + + # Test case 6: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "False". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "False"} + ): + assert DataPointsServiceClient._use_client_cert_effective() is False + + # Test case 7: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "TRUE". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "TRUE"}): + assert DataPointsServiceClient._use_client_cert_effective() is True + + # Test case 8: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "FALSE". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "FALSE"} + ): + assert DataPointsServiceClient._use_client_cert_effective() is False + + # Test case 9: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not set. + # In this case, the method should return False, which is the default value. + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, clear=True): + assert DataPointsServiceClient._use_client_cert_effective() is False + + # Test case 10: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value. + # The method should raise a ValueError as the environment variable must be either + # "true" or "false". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"} + ): + with pytest.raises(ValueError): + DataPointsServiceClient._use_client_cert_effective() + + # Test case 11: Test when `should_use_client_cert` is available and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value. + # The method should return False as the environment variable is set to an invalid value. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"} + ): + assert DataPointsServiceClient._use_client_cert_effective() is False + + # Test case 12: Test when `should_use_client_cert` is available and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is unset. Also, + # the GOOGLE_API_CONFIG environment variable is unset. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": ""}): + with mock.patch.dict(os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": ""}): + assert DataPointsServiceClient._use_client_cert_effective() is False + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert DataPointsServiceClient._get_client_cert_source(None, False) is None + assert ( + DataPointsServiceClient._get_client_cert_source( + mock_provided_cert_source, False + ) + is None + ) + assert ( + DataPointsServiceClient._get_client_cert_source(mock_provided_cert_source, True) + == mock_provided_cert_source + ) + + 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_default_cert_source, + ): + assert ( + DataPointsServiceClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + DataPointsServiceClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + DataPointsServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DataPointsServiceClient), +) +@mock.patch.object( + DataPointsServiceAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DataPointsServiceAsyncClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = DataPointsServiceClient._DEFAULT_UNIVERSE + default_endpoint = DataPointsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = DataPointsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + DataPointsServiceClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + DataPointsServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == DataPointsServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + DataPointsServiceClient._get_api_endpoint(None, None, default_universe, "auto") + == default_endpoint + ) + assert ( + DataPointsServiceClient._get_api_endpoint( + None, None, default_universe, "always" + ) + == DataPointsServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + DataPointsServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == DataPointsServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + DataPointsServiceClient._get_api_endpoint(None, None, mock_universe, "never") + == mock_endpoint + ) + assert ( + DataPointsServiceClient._get_api_endpoint(None, None, default_universe, "never") + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + DataPointsServiceClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + DataPointsServiceClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + DataPointsServiceClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert ( + DataPointsServiceClient._get_universe_domain(None, None) + == DataPointsServiceClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + DataPointsServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DataPointsServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DataPointsServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (DataPointsServiceClient, "grpc"), + (DataPointsServiceAsyncClient, "grpc_asyncio"), + (DataPointsServiceClient, "rest"), + ], +) +def test_data_points_service_client_from_service_account_info( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "health.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://health.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.DataPointsServiceGrpcTransport, "grpc"), + (transports.DataPointsServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.DataPointsServiceRestTransport, "rest"), + ], +) +def test_data_points_service_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (DataPointsServiceClient, "grpc"), + (DataPointsServiceAsyncClient, "grpc_asyncio"), + (DataPointsServiceClient, "rest"), + ], +) +def test_data_points_service_client_from_service_account_file( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "health.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://health.googleapis.com" + ) + + +def test_data_points_service_client_get_transport_class(): + transport = DataPointsServiceClient.get_transport_class() + available_transports = [ + transports.DataPointsServiceGrpcTransport, + transports.DataPointsServiceRestTransport, + ] + assert transport in available_transports + + transport = DataPointsServiceClient.get_transport_class("grpc") + assert transport == transports.DataPointsServiceGrpcTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (DataPointsServiceClient, transports.DataPointsServiceGrpcTransport, "grpc"), + ( + DataPointsServiceAsyncClient, + transports.DataPointsServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + (DataPointsServiceClient, transports.DataPointsServiceRestTransport, "rest"), + ], +) +@mock.patch.object( + DataPointsServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DataPointsServiceClient), +) +@mock.patch.object( + DataPointsServiceAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DataPointsServiceAsyncClient), +) +def test_data_points_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(DataPointsServiceClient, "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(DataPointsServiceClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # 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_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + DataPointsServiceClient, + transports.DataPointsServiceGrpcTransport, + "grpc", + "true", + ), + ( + DataPointsServiceAsyncClient, + transports.DataPointsServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + ( + DataPointsServiceClient, + transports.DataPointsServiceGrpcTransport, + "grpc", + "false", + ), + ( + DataPointsServiceAsyncClient, + transports.DataPointsServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + ( + DataPointsServiceClient, + transports.DataPointsServiceRestTransport, + "rest", + "true", + ), + ( + DataPointsServiceClient, + transports.DataPointsServiceRestTransport, + "rest", + "false", + ), + ], +) +@mock.patch.object( + DataPointsServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DataPointsServiceClient), +) +@mock.patch.object( + DataPointsServiceAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DataPointsServiceAsyncClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_data_points_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_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class", [DataPointsServiceClient, DataPointsServiceAsyncClient] +) +@mock.patch.object( + DataPointsServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(DataPointsServiceClient), +) +@mock.patch.object( + DataPointsServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(DataPointsServiceAsyncClient), +) +def test_data_points_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_CLIENT_CERTIFICATE is "Unsupported". + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + 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 cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset. + test_cases = [ + ( + # With workloads present in config, mTLS is enabled. + { + "version": 1, + "cert_configs": { + "workload": { + "cert_path": "path/to/cert/file", + "key_path": "path/to/key/file", + } + }, + }, + mock_client_cert_source, + ), + ( + # With workloads not present in config, mTLS is disabled. + { + "version": 1, + "cert_configs": {}, + }, + None, + ), + ] + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + for config_data, expected_cert_source in test_cases: + env = os.environ.copy() + env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", None) + with mock.patch.dict(os.environ, env, clear=True): + config_filename = "mock_certificate_config.json" + config_file_content = json.dumps(config_data) + m = mock.mock_open(read_data=config_file_content) + with mock.patch("builtins.open", m): + with mock.patch.dict( + os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename} + ): + 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 expected_cert_source + + # Test cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset(empty). + test_cases = [ + ( + # With workloads present in config, mTLS is enabled. + { + "version": 1, + "cert_configs": { + "workload": { + "cert_path": "path/to/cert/file", + "key_path": "path/to/key/file", + } + }, + }, + mock_client_cert_source, + ), + ( + # With workloads not present in config, mTLS is disabled. + { + "version": 1, + "cert_configs": {}, + }, + None, + ), + ] + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + for config_data, expected_cert_source in test_cases: + env = os.environ.copy() + env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", "") + with mock.patch.dict(os.environ, env, clear=True): + config_filename = "mock_certificate_config.json" + config_file_content = json.dumps(config_data) + m = mock.mock_open(read_data=config_file_content) + with mock.patch("builtins.open", m): + with mock.patch.dict( + os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename} + ): + 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 expected_cert_source + + # 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 + + # 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) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + +@pytest.mark.parametrize( + "client_class", [DataPointsServiceClient, DataPointsServiceAsyncClient] +) +@mock.patch.object( + DataPointsServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DataPointsServiceClient), +) +@mock.patch.object( + DataPointsServiceAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DataPointsServiceAsyncClient), +) +def test_data_points_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = DataPointsServiceClient._DEFAULT_UNIVERSE + default_endpoint = DataPointsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = DataPointsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (DataPointsServiceClient, transports.DataPointsServiceGrpcTransport, "grpc"), + ( + DataPointsServiceAsyncClient, + transports.DataPointsServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + (DataPointsServiceClient, transports.DataPointsServiceRestTransport, "rest"), + ], +) +def test_data_points_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_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + DataPointsServiceClient, + transports.DataPointsServiceGrpcTransport, + "grpc", + grpc_helpers, + ), + ( + DataPointsServiceAsyncClient, + transports.DataPointsServiceGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + ( + DataPointsServiceClient, + transports.DataPointsServiceRestTransport, + "rest", + None, + ), + ], +) +def test_data_points_service_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_data_points_service_client_client_options_from_dict(): + with mock.patch( + "google.devicesandservices.health_v4.services.data_points_service.transports.DataPointsServiceGrpcTransport.__init__" + ) as grpc_transport: + grpc_transport.return_value = None + client = DataPointsServiceClient( + client_options={"api_endpoint": "squid.clam.whelk"} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + DataPointsServiceClient, + transports.DataPointsServiceGrpcTransport, + "grpc", + grpc_helpers, + ), + ( + DataPointsServiceAsyncClient, + transports.DataPointsServiceGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + ], +) +def test_data_points_service_client_create_channel_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # test that the credentials from file are saved and used as the credentials. + with ( + mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, + mock.patch.object(google.auth, "default", autospec=True) as adc, + mock.patch.object(grpc_helpers, "create_channel") as create_channel, + ): + creds = ga_credentials.AnonymousCredentials() + file_creds = ga_credentials.AnonymousCredentials() + load_creds.return_value = (file_creds, None) + adc.return_value = (creds, None) + client = client_class(client_options=options, transport=transport_name) + create_channel.assert_called_with( + "health.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + "https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly", + "https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.readonly", + "https://www.googleapis.com/auth/googlehealth.location.readonly", + "https://www.googleapis.com/auth/googlehealth.sleep.readonly", + ), + scopes=None, + default_host="health.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "request_type", + [ + data_points.GetDataPointRequest(), + {}, + ], +) +def test_get_data_point(request_type, transport: str = "grpc"): + client = DataPointsServiceClient( + 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_data_point), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = data_points.DataPoint( + name="name_value", + ) + response = client.get_data_point(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = data_points.GetDataPointRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, data_points.DataPoint) + assert response.name == "name_value" + + +def test_get_data_point_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = data_points.GetDataPointRequest( + name="name_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_data_point), "__call__") as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.get_data_point(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.GetDataPointRequest( + name="name_value", + ) + assert args[0] == request_msg + + +def test_get_data_point_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_data_point in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_data_point] = mock_rpc + request = {} + client.get_data_point(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_data_point(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_get_data_point_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.get_data_point + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.get_data_point + ] = mock_rpc + + request = {} + await client.get_data_point(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.get_data_point(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + data_points.GetDataPointRequest(), + {}, + ], +) +async def test_get_data_point_async(request_type, transport: str = "grpc_asyncio"): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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_data_point), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_points.DataPoint( + name="name_value", + ) + ) + response = await client.get_data_point(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = data_points.GetDataPointRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, data_points.DataPoint) + assert response.name == "name_value" + + +def test_get_data_point_field_headers(): + client = DataPointsServiceClient( + 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 = data_points.GetDataPointRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_data_point), "__call__") as call: + call.return_value = data_points.DataPoint() + client.get_data_point(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_data_point_field_headers_async(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = data_points.GetDataPointRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_data_point), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_points.DataPoint() + ) + await client.get_data_point(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_data_point_flattened(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_data_point), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = data_points.DataPoint() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_data_point( + 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_data_point_flattened_error(): + client = DataPointsServiceClient( + 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_data_point( + data_points.GetDataPointRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_data_point_flattened_async(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_data_point), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = data_points.DataPoint() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_points.DataPoint() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_data_point( + 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_data_point_flattened_error_async(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_data_point( + data_points.GetDataPointRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + data_points.ListDataPointsRequest(), + {}, + ], +) +def test_list_data_points(request_type, transport: str = "grpc"): + client = DataPointsServiceClient( + 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_data_points), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = data_points.ListDataPointsResponse( + next_page_token="next_page_token_value", + ) + response = client.list_data_points(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = data_points.ListDataPointsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListDataPointsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_data_points_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = data_points.ListDataPointsRequest( + parent="parent_value", + page_token="page_token_value", + filter="filter_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_data_points), "__call__") as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.list_data_points(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.ListDataPointsRequest( + parent="parent_value", + page_token="page_token_value", + filter="filter_value", + ) + assert args[0] == request_msg + + +def test_list_data_points_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.list_data_points in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.list_data_points] = ( + mock_rpc + ) + request = {} + client.list_data_points(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_data_points(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_list_data_points_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.list_data_points + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.list_data_points + ] = mock_rpc + + request = {} + await client.list_data_points(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.list_data_points(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + data_points.ListDataPointsRequest(), + {}, + ], +) +async def test_list_data_points_async(request_type, transport: str = "grpc_asyncio"): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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_data_points), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_points.ListDataPointsResponse( + next_page_token="next_page_token_value", + ) + ) + response = await client.list_data_points(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = data_points.ListDataPointsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListDataPointsAsyncPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_data_points_field_headers(): + client = DataPointsServiceClient( + 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 = data_points.ListDataPointsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_data_points), "__call__") as call: + call.return_value = data_points.ListDataPointsResponse() + client.list_data_points(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_data_points_field_headers_async(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = data_points.ListDataPointsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_data_points), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_points.ListDataPointsResponse() + ) + await client.list_data_points(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_data_points_flattened(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_data_points), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = data_points.ListDataPointsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_data_points( + 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_data_points_flattened_error(): + client = DataPointsServiceClient( + 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_data_points( + data_points.ListDataPointsRequest(), + parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_list_data_points_flattened_async(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_data_points), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = data_points.ListDataPointsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_points.ListDataPointsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_data_points( + 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_data_points_flattened_error_async(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_data_points( + data_points.ListDataPointsRequest(), + parent="parent_value", + ) + + +def test_list_data_points_pager(transport_name: str = "grpc"): + client = DataPointsServiceClient( + 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_data_points), "__call__") as call: + # Set the response to a series of pages. + call.side_effect = ( + data_points.ListDataPointsResponse( + data_points=[ + data_points.DataPoint(), + data_points.DataPoint(), + data_points.DataPoint(), + ], + next_page_token="abc", + ), + data_points.ListDataPointsResponse( + data_points=[], + next_page_token="def", + ), + data_points.ListDataPointsResponse( + data_points=[ + data_points.DataPoint(), + ], + next_page_token="ghi", + ), + data_points.ListDataPointsResponse( + data_points=[ + data_points.DataPoint(), + data_points.DataPoint(), + ], + ), + RuntimeError, + ) + + expected_metadata = () + retry = retries.Retry() + timeout = 5 + expected_metadata = tuple(expected_metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_data_points(request={}, retry=retry, timeout=timeout) + + assert pager._metadata == expected_metadata + assert pager._retry == retry + assert pager._timeout == timeout + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, data_points.DataPoint) for i in results) + + +def test_list_data_points_pages(transport_name: str = "grpc"): + client = DataPointsServiceClient( + 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_data_points), "__call__") as call: + # Set the response to a series of pages. + call.side_effect = ( + data_points.ListDataPointsResponse( + data_points=[ + data_points.DataPoint(), + data_points.DataPoint(), + data_points.DataPoint(), + ], + next_page_token="abc", + ), + data_points.ListDataPointsResponse( + data_points=[], + next_page_token="def", + ), + data_points.ListDataPointsResponse( + data_points=[ + data_points.DataPoint(), + ], + next_page_token="ghi", + ), + data_points.ListDataPointsResponse( + data_points=[ + data_points.DataPoint(), + data_points.DataPoint(), + ], + ), + RuntimeError, + ) + pages = list(client.list_data_points(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_data_points_async_pager(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_data_points), "__call__", new_callable=mock.AsyncMock + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + data_points.ListDataPointsResponse( + data_points=[ + data_points.DataPoint(), + data_points.DataPoint(), + data_points.DataPoint(), + ], + next_page_token="abc", + ), + data_points.ListDataPointsResponse( + data_points=[], + next_page_token="def", + ), + data_points.ListDataPointsResponse( + data_points=[ + data_points.DataPoint(), + ], + next_page_token="ghi", + ), + data_points.ListDataPointsResponse( + data_points=[ + data_points.DataPoint(), + data_points.DataPoint(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_data_points( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, data_points.DataPoint) for i in responses) + + +@pytest.mark.asyncio +async def test_list_data_points_async_pages(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_data_points), "__call__", new_callable=mock.AsyncMock + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + data_points.ListDataPointsResponse( + data_points=[ + data_points.DataPoint(), + data_points.DataPoint(), + data_points.DataPoint(), + ], + next_page_token="abc", + ), + data_points.ListDataPointsResponse( + data_points=[], + next_page_token="def", + ), + data_points.ListDataPointsResponse( + data_points=[ + data_points.DataPoint(), + ], + next_page_token="ghi", + ), + data_points.ListDataPointsResponse( + data_points=[ + data_points.DataPoint(), + data_points.DataPoint(), + ], + ), + RuntimeError, + ) + pages = [] + async for page_ in (await client.list_data_points(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", + [ + data_points.CreateDataPointRequest(), + {}, + ], +) +def test_create_data_point(request_type, transport: str = "grpc"): + client = DataPointsServiceClient( + 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_data_point), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.create_data_point(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = data_points.CreateDataPointRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_create_data_point_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = data_points.CreateDataPointRequest( + parent="parent_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_data_point), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.create_data_point(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.CreateDataPointRequest( + parent="parent_value", + ) + assert args[0] == request_msg + + +def test_create_data_point_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.create_data_point in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.create_data_point] = ( + mock_rpc + ) + request = {} + client.create_data_point(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.create_data_point(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_create_data_point_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.create_data_point + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.create_data_point + ] = mock_rpc + + request = {} + await client.create_data_point(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + await client.create_data_point(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + data_points.CreateDataPointRequest(), + {}, + ], +) +async def test_create_data_point_async(request_type, transport: str = "grpc_asyncio"): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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_data_point), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + response = await client.create_data_point(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = data_points.CreateDataPointRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_create_data_point_field_headers(): + client = DataPointsServiceClient( + 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 = data_points.CreateDataPointRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_data_point), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_data_point(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_data_point_field_headers_async(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = data_points.CreateDataPointRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_data_point), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.create_data_point(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_data_point_flattened(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_data_point), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_data_point( + parent="parent_value", + data_point=data_points.DataPoint( + steps=data_model.Steps( + interval=data_coordinates.ObservationTimeInterval( + start_time=timestamp_pb2.Timestamp(seconds=751) + ) + ) + ), + ) + + # 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].data_point + mock_val = data_points.DataPoint( + steps=data_model.Steps( + interval=data_coordinates.ObservationTimeInterval( + start_time=timestamp_pb2.Timestamp(seconds=751) + ) + ) + ) + assert arg == mock_val + + +def test_create_data_point_flattened_error(): + client = DataPointsServiceClient( + 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_data_point( + data_points.CreateDataPointRequest(), + parent="parent_value", + data_point=data_points.DataPoint( + steps=data_model.Steps( + interval=data_coordinates.ObservationTimeInterval( + start_time=timestamp_pb2.Timestamp(seconds=751) + ) + ) + ), + ) + + +@pytest.mark.asyncio +async def test_create_data_point_flattened_async(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_data_point), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_data_point( + parent="parent_value", + data_point=data_points.DataPoint( + steps=data_model.Steps( + interval=data_coordinates.ObservationTimeInterval( + start_time=timestamp_pb2.Timestamp(seconds=751) + ) + ) + ), + ) + + # 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].data_point + mock_val = data_points.DataPoint( + steps=data_model.Steps( + interval=data_coordinates.ObservationTimeInterval( + start_time=timestamp_pb2.Timestamp(seconds=751) + ) + ) + ) + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_create_data_point_flattened_error_async(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_data_point( + data_points.CreateDataPointRequest(), + parent="parent_value", + data_point=data_points.DataPoint( + steps=data_model.Steps( + interval=data_coordinates.ObservationTimeInterval( + start_time=timestamp_pb2.Timestamp(seconds=751) + ) + ) + ), + ) + + +@pytest.mark.parametrize( + "request_type", + [ + data_points.UpdateDataPointRequest(), + {}, + ], +) +def test_update_data_point(request_type, transport: str = "grpc"): + client = DataPointsServiceClient( + 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_data_point), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.update_data_point(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = data_points.UpdateDataPointRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_update_data_point_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = data_points.UpdateDataPointRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_data_point), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.update_data_point(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.UpdateDataPointRequest() + assert args[0] == request_msg + + +def test_update_data_point_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.update_data_point in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.update_data_point] = ( + mock_rpc + ) + request = {} + client.update_data_point(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.update_data_point(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_update_data_point_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.update_data_point + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.update_data_point + ] = mock_rpc + + request = {} + await client.update_data_point(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + await client.update_data_point(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + data_points.UpdateDataPointRequest(), + {}, + ], +) +async def test_update_data_point_async(request_type, transport: str = "grpc_asyncio"): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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_data_point), "__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.update_data_point(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = data_points.UpdateDataPointRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_update_data_point_field_headers(): + client = DataPointsServiceClient( + 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 = data_points.UpdateDataPointRequest() + + request.data_point.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_data_point), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.update_data_point(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", + "data_point.name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_update_data_point_field_headers_async(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = data_points.UpdateDataPointRequest() + + request.data_point.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_data_point), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.update_data_point(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", + "data_point.name=name_value", + ) in kw["metadata"] + + +def test_update_data_point_flattened(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_data_point), "__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.update_data_point( + data_point=data_points.DataPoint( + steps=data_model.Steps( + interval=data_coordinates.ObservationTimeInterval( + start_time=timestamp_pb2.Timestamp(seconds=751) + ) + ) + ), + ) + + # 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].data_point + mock_val = data_points.DataPoint( + steps=data_model.Steps( + interval=data_coordinates.ObservationTimeInterval( + start_time=timestamp_pb2.Timestamp(seconds=751) + ) + ) + ) + assert arg == mock_val + + +def test_update_data_point_flattened_error(): + client = DataPointsServiceClient( + 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_data_point( + data_points.UpdateDataPointRequest(), + data_point=data_points.DataPoint( + steps=data_model.Steps( + interval=data_coordinates.ObservationTimeInterval( + start_time=timestamp_pb2.Timestamp(seconds=751) + ) + ) + ), + ) + + +@pytest.mark.asyncio +async def test_update_data_point_flattened_async(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_data_point), "__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.update_data_point( + data_point=data_points.DataPoint( + steps=data_model.Steps( + interval=data_coordinates.ObservationTimeInterval( + start_time=timestamp_pb2.Timestamp(seconds=751) + ) + ) + ), + ) + + # 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].data_point + mock_val = data_points.DataPoint( + steps=data_model.Steps( + interval=data_coordinates.ObservationTimeInterval( + start_time=timestamp_pb2.Timestamp(seconds=751) + ) + ) + ) + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_update_data_point_flattened_error_async(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_data_point( + data_points.UpdateDataPointRequest(), + data_point=data_points.DataPoint( + steps=data_model.Steps( + interval=data_coordinates.ObservationTimeInterval( + start_time=timestamp_pb2.Timestamp(seconds=751) + ) + ) + ), + ) + + +@pytest.mark.parametrize( + "request_type", + [ + data_points.BatchDeleteDataPointsRequest(), + {}, + ], +) +def test_batch_delete_data_points(request_type, transport: str = "grpc"): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_delete_data_points), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.batch_delete_data_points(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = data_points.BatchDeleteDataPointsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_batch_delete_data_points_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = data_points.BatchDeleteDataPointsRequest( + parent="parent_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_delete_data_points), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.batch_delete_data_points(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.BatchDeleteDataPointsRequest( + parent="parent_value", + ) + assert args[0] == request_msg + + +def test_batch_delete_data_points_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.batch_delete_data_points + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.batch_delete_data_points + ] = mock_rpc + request = {} + client.batch_delete_data_points(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.batch_delete_data_points(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_batch_delete_data_points_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.batch_delete_data_points + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.batch_delete_data_points + ] = mock_rpc + + request = {} + await client.batch_delete_data_points(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + await client.batch_delete_data_points(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + data_points.BatchDeleteDataPointsRequest(), + {}, + ], +) +async def test_batch_delete_data_points_async( + request_type, transport: str = "grpc_asyncio" +): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_delete_data_points), "__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.batch_delete_data_points(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = data_points.BatchDeleteDataPointsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_batch_delete_data_points_field_headers(): + client = DataPointsServiceClient( + 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 = data_points.BatchDeleteDataPointsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_delete_data_points), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.batch_delete_data_points(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_batch_delete_data_points_field_headers_async(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = data_points.BatchDeleteDataPointsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_delete_data_points), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.batch_delete_data_points(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", + [ + data_points.ReconcileDataPointsRequest(), + {}, + ], +) +def test_reconcile_data_points(request_type, transport: str = "grpc"): + client = DataPointsServiceClient( + 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.reconcile_data_points), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = data_points.ReconcileDataPointsResponse( + next_page_token="next_page_token_value", + ) + response = client.reconcile_data_points(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = data_points.ReconcileDataPointsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ReconcileDataPointsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_reconcile_data_points_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = data_points.ReconcileDataPointsRequest( + parent="parent_value", + page_token="page_token_value", + filter="filter_value", + data_source_family="data_source_family_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.reconcile_data_points), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.reconcile_data_points(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.ReconcileDataPointsRequest( + parent="parent_value", + page_token="page_token_value", + filter="filter_value", + data_source_family="data_source_family_value", + ) + assert args[0] == request_msg + + +def test_reconcile_data_points_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.reconcile_data_points + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.reconcile_data_points] = ( + mock_rpc + ) + request = {} + client.reconcile_data_points(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.reconcile_data_points(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_reconcile_data_points_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.reconcile_data_points + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.reconcile_data_points + ] = mock_rpc + + request = {} + await client.reconcile_data_points(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.reconcile_data_points(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + data_points.ReconcileDataPointsRequest(), + {}, + ], +) +async def test_reconcile_data_points_async( + request_type, transport: str = "grpc_asyncio" +): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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.reconcile_data_points), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_points.ReconcileDataPointsResponse( + next_page_token="next_page_token_value", + ) + ) + response = await client.reconcile_data_points(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = data_points.ReconcileDataPointsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ReconcileDataPointsAsyncPager) + assert response.next_page_token == "next_page_token_value" + + +def test_reconcile_data_points_field_headers(): + client = DataPointsServiceClient( + 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 = data_points.ReconcileDataPointsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.reconcile_data_points), "__call__" + ) as call: + call.return_value = data_points.ReconcileDataPointsResponse() + client.reconcile_data_points(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_reconcile_data_points_field_headers_async(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = data_points.ReconcileDataPointsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.reconcile_data_points), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_points.ReconcileDataPointsResponse() + ) + await client.reconcile_data_points(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_reconcile_data_points_pager(transport_name: str = "grpc"): + client = DataPointsServiceClient( + 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.reconcile_data_points), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + data_points.ReconcileDataPointsResponse( + data_points=[ + data_points.ReconciledDataPoint(), + data_points.ReconciledDataPoint(), + data_points.ReconciledDataPoint(), + ], + next_page_token="abc", + ), + data_points.ReconcileDataPointsResponse( + data_points=[], + next_page_token="def", + ), + data_points.ReconcileDataPointsResponse( + data_points=[ + data_points.ReconciledDataPoint(), + ], + next_page_token="ghi", + ), + data_points.ReconcileDataPointsResponse( + data_points=[ + data_points.ReconciledDataPoint(), + data_points.ReconciledDataPoint(), + ], + ), + RuntimeError, + ) + + expected_metadata = () + retry = retries.Retry() + timeout = 5 + expected_metadata = tuple(expected_metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.reconcile_data_points(request={}, retry=retry, timeout=timeout) + + assert pager._metadata == expected_metadata + assert pager._retry == retry + assert pager._timeout == timeout + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, data_points.ReconciledDataPoint) for i in results) + + +def test_reconcile_data_points_pages(transport_name: str = "grpc"): + client = DataPointsServiceClient( + 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.reconcile_data_points), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + data_points.ReconcileDataPointsResponse( + data_points=[ + data_points.ReconciledDataPoint(), + data_points.ReconciledDataPoint(), + data_points.ReconciledDataPoint(), + ], + next_page_token="abc", + ), + data_points.ReconcileDataPointsResponse( + data_points=[], + next_page_token="def", + ), + data_points.ReconcileDataPointsResponse( + data_points=[ + data_points.ReconciledDataPoint(), + ], + next_page_token="ghi", + ), + data_points.ReconcileDataPointsResponse( + data_points=[ + data_points.ReconciledDataPoint(), + data_points.ReconciledDataPoint(), + ], + ), + RuntimeError, + ) + pages = list(client.reconcile_data_points(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_reconcile_data_points_async_pager(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.reconcile_data_points), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + data_points.ReconcileDataPointsResponse( + data_points=[ + data_points.ReconciledDataPoint(), + data_points.ReconciledDataPoint(), + data_points.ReconciledDataPoint(), + ], + next_page_token="abc", + ), + data_points.ReconcileDataPointsResponse( + data_points=[], + next_page_token="def", + ), + data_points.ReconcileDataPointsResponse( + data_points=[ + data_points.ReconciledDataPoint(), + ], + next_page_token="ghi", + ), + data_points.ReconcileDataPointsResponse( + data_points=[ + data_points.ReconciledDataPoint(), + data_points.ReconciledDataPoint(), + ], + ), + RuntimeError, + ) + async_pager = await client.reconcile_data_points( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, data_points.ReconciledDataPoint) for i in responses) + + +@pytest.mark.asyncio +async def test_reconcile_data_points_async_pages(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.reconcile_data_points), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + data_points.ReconcileDataPointsResponse( + data_points=[ + data_points.ReconciledDataPoint(), + data_points.ReconciledDataPoint(), + data_points.ReconciledDataPoint(), + ], + next_page_token="abc", + ), + data_points.ReconcileDataPointsResponse( + data_points=[], + next_page_token="def", + ), + data_points.ReconcileDataPointsResponse( + data_points=[ + data_points.ReconciledDataPoint(), + ], + next_page_token="ghi", + ), + data_points.ReconcileDataPointsResponse( + data_points=[ + data_points.ReconciledDataPoint(), + data_points.ReconciledDataPoint(), + ], + ), + RuntimeError, + ) + pages = [] + async for page_ in (await client.reconcile_data_points(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", + [ + data_points.RollUpDataPointsRequest(), + {}, + ], +) +def test_roll_up_data_points(request_type, transport: str = "grpc"): + client = DataPointsServiceClient( + 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.roll_up_data_points), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = data_points.RollUpDataPointsResponse( + next_page_token="next_page_token_value", + ) + response = client.roll_up_data_points(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = data_points.RollUpDataPointsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.RollUpDataPointsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_roll_up_data_points_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = data_points.RollUpDataPointsRequest( + parent="parent_value", + page_token="page_token_value", + data_source_family="data_source_family_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.roll_up_data_points), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.roll_up_data_points(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.RollUpDataPointsRequest( + parent="parent_value", + page_token="page_token_value", + data_source_family="data_source_family_value", + ) + assert args[0] == request_msg + + +def test_roll_up_data_points_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.roll_up_data_points in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.roll_up_data_points] = ( + mock_rpc + ) + request = {} + client.roll_up_data_points(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.roll_up_data_points(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_roll_up_data_points_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.roll_up_data_points + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.roll_up_data_points + ] = mock_rpc + + request = {} + await client.roll_up_data_points(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.roll_up_data_points(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + data_points.RollUpDataPointsRequest(), + {}, + ], +) +async def test_roll_up_data_points_async(request_type, transport: str = "grpc_asyncio"): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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.roll_up_data_points), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_points.RollUpDataPointsResponse( + next_page_token="next_page_token_value", + ) + ) + response = await client.roll_up_data_points(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = data_points.RollUpDataPointsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.RollUpDataPointsAsyncPager) + assert response.next_page_token == "next_page_token_value" + + +def test_roll_up_data_points_field_headers(): + client = DataPointsServiceClient( + 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 = data_points.RollUpDataPointsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.roll_up_data_points), "__call__" + ) as call: + call.return_value = data_points.RollUpDataPointsResponse() + client.roll_up_data_points(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_roll_up_data_points_field_headers_async(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = data_points.RollUpDataPointsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.roll_up_data_points), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_points.RollUpDataPointsResponse() + ) + await client.roll_up_data_points(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_roll_up_data_points_pager(transport_name: str = "grpc"): + client = DataPointsServiceClient( + 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.roll_up_data_points), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + data_points.RollUpDataPointsResponse( + rollup_data_points=[ + data_points.RollupDataPoint(), + data_points.RollupDataPoint(), + data_points.RollupDataPoint(), + ], + next_page_token="abc", + ), + data_points.RollUpDataPointsResponse( + rollup_data_points=[], + next_page_token="def", + ), + data_points.RollUpDataPointsResponse( + rollup_data_points=[ + data_points.RollupDataPoint(), + ], + next_page_token="ghi", + ), + data_points.RollUpDataPointsResponse( + rollup_data_points=[ + data_points.RollupDataPoint(), + data_points.RollupDataPoint(), + ], + ), + RuntimeError, + ) + + expected_metadata = () + retry = retries.Retry() + timeout = 5 + expected_metadata = tuple(expected_metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.roll_up_data_points(request={}, retry=retry, timeout=timeout) + + assert pager._metadata == expected_metadata + assert pager._retry == retry + assert pager._timeout == timeout + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, data_points.RollupDataPoint) for i in results) + + +def test_roll_up_data_points_pages(transport_name: str = "grpc"): + client = DataPointsServiceClient( + 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.roll_up_data_points), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + data_points.RollUpDataPointsResponse( + rollup_data_points=[ + data_points.RollupDataPoint(), + data_points.RollupDataPoint(), + data_points.RollupDataPoint(), + ], + next_page_token="abc", + ), + data_points.RollUpDataPointsResponse( + rollup_data_points=[], + next_page_token="def", + ), + data_points.RollUpDataPointsResponse( + rollup_data_points=[ + data_points.RollupDataPoint(), + ], + next_page_token="ghi", + ), + data_points.RollUpDataPointsResponse( + rollup_data_points=[ + data_points.RollupDataPoint(), + data_points.RollupDataPoint(), + ], + ), + RuntimeError, + ) + pages = list(client.roll_up_data_points(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_roll_up_data_points_async_pager(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.roll_up_data_points), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + data_points.RollUpDataPointsResponse( + rollup_data_points=[ + data_points.RollupDataPoint(), + data_points.RollupDataPoint(), + data_points.RollupDataPoint(), + ], + next_page_token="abc", + ), + data_points.RollUpDataPointsResponse( + rollup_data_points=[], + next_page_token="def", + ), + data_points.RollUpDataPointsResponse( + rollup_data_points=[ + data_points.RollupDataPoint(), + ], + next_page_token="ghi", + ), + data_points.RollUpDataPointsResponse( + rollup_data_points=[ + data_points.RollupDataPoint(), + data_points.RollupDataPoint(), + ], + ), + RuntimeError, + ) + async_pager = await client.roll_up_data_points( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, data_points.RollupDataPoint) for i in responses) + + +@pytest.mark.asyncio +async def test_roll_up_data_points_async_pages(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.roll_up_data_points), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + data_points.RollUpDataPointsResponse( + rollup_data_points=[ + data_points.RollupDataPoint(), + data_points.RollupDataPoint(), + data_points.RollupDataPoint(), + ], + next_page_token="abc", + ), + data_points.RollUpDataPointsResponse( + rollup_data_points=[], + next_page_token="def", + ), + data_points.RollUpDataPointsResponse( + rollup_data_points=[ + data_points.RollupDataPoint(), + ], + next_page_token="ghi", + ), + data_points.RollUpDataPointsResponse( + rollup_data_points=[ + data_points.RollupDataPoint(), + data_points.RollupDataPoint(), + ], + ), + RuntimeError, + ) + pages = [] + async for page_ in (await client.roll_up_data_points(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", + [ + data_points.DailyRollUpDataPointsRequest(), + {}, + ], +) +def test_daily_roll_up_data_points(request_type, transport: str = "grpc"): + client = DataPointsServiceClient( + 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.daily_roll_up_data_points), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = data_points.DailyRollUpDataPointsResponse() + response = client.daily_roll_up_data_points(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = data_points.DailyRollUpDataPointsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, data_points.DailyRollUpDataPointsResponse) + + +def test_daily_roll_up_data_points_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = data_points.DailyRollUpDataPointsRequest( + parent="parent_value", + page_token="page_token_value", + data_source_family="data_source_family_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.daily_roll_up_data_points), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.daily_roll_up_data_points(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.DailyRollUpDataPointsRequest( + parent="parent_value", + page_token="page_token_value", + data_source_family="data_source_family_value", + ) + assert args[0] == request_msg + + +def test_daily_roll_up_data_points_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.daily_roll_up_data_points + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.daily_roll_up_data_points + ] = mock_rpc + request = {} + client.daily_roll_up_data_points(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.daily_roll_up_data_points(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_daily_roll_up_data_points_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.daily_roll_up_data_points + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.daily_roll_up_data_points + ] = mock_rpc + + request = {} + await client.daily_roll_up_data_points(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.daily_roll_up_data_points(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + data_points.DailyRollUpDataPointsRequest(), + {}, + ], +) +async def test_daily_roll_up_data_points_async( + request_type, transport: str = "grpc_asyncio" +): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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.daily_roll_up_data_points), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_points.DailyRollUpDataPointsResponse() + ) + response = await client.daily_roll_up_data_points(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = data_points.DailyRollUpDataPointsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, data_points.DailyRollUpDataPointsResponse) + + +def test_daily_roll_up_data_points_field_headers(): + client = DataPointsServiceClient( + 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 = data_points.DailyRollUpDataPointsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.daily_roll_up_data_points), "__call__" + ) as call: + call.return_value = data_points.DailyRollUpDataPointsResponse() + client.daily_roll_up_data_points(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_daily_roll_up_data_points_field_headers_async(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = data_points.DailyRollUpDataPointsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.daily_roll_up_data_points), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_points.DailyRollUpDataPointsResponse() + ) + await client.daily_roll_up_data_points(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", + [ + data_points.ExportExerciseTcxRequest(), + {}, + ], +) +def test_export_exercise_tcx(request_type, transport: str = "grpc"): + client = DataPointsServiceClient( + 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.export_exercise_tcx), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = data_points.ExportExerciseTcxResponse( + tcx_data="tcx_data_value", + ) + response = client.export_exercise_tcx(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = data_points.ExportExerciseTcxRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, data_points.ExportExerciseTcxResponse) + assert response.tcx_data == "tcx_data_value" + + +def test_export_exercise_tcx_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = data_points.ExportExerciseTcxRequest( + name="name_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.export_exercise_tcx), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.export_exercise_tcx(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.ExportExerciseTcxRequest( + name="name_value", + ) + assert args[0] == request_msg + + +def test_export_exercise_tcx_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.export_exercise_tcx in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.export_exercise_tcx] = ( + mock_rpc + ) + request = {} + client.export_exercise_tcx(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.export_exercise_tcx(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_export_exercise_tcx_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.export_exercise_tcx + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.export_exercise_tcx + ] = mock_rpc + + request = {} + await client.export_exercise_tcx(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.export_exercise_tcx(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + data_points.ExportExerciseTcxRequest(), + {}, + ], +) +async def test_export_exercise_tcx_async(request_type, transport: str = "grpc_asyncio"): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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.export_exercise_tcx), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_points.ExportExerciseTcxResponse( + tcx_data="tcx_data_value", + ) + ) + response = await client.export_exercise_tcx(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = data_points.ExportExerciseTcxRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, data_points.ExportExerciseTcxResponse) + assert response.tcx_data == "tcx_data_value" + + +def test_export_exercise_tcx_field_headers(): + client = DataPointsServiceClient( + 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 = data_points.ExportExerciseTcxRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.export_exercise_tcx), "__call__" + ) as call: + call.return_value = data_points.ExportExerciseTcxResponse() + client.export_exercise_tcx(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_export_exercise_tcx_field_headers_async(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = data_points.ExportExerciseTcxRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.export_exercise_tcx), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_points.ExportExerciseTcxResponse() + ) + await client.export_exercise_tcx(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_export_exercise_tcx_flattened(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.export_exercise_tcx), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = data_points.ExportExerciseTcxResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.export_exercise_tcx( + 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_export_exercise_tcx_flattened_error(): + client = DataPointsServiceClient( + 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.export_exercise_tcx( + data_points.ExportExerciseTcxRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_export_exercise_tcx_flattened_async(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.export_exercise_tcx), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = data_points.ExportExerciseTcxResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_points.ExportExerciseTcxResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.export_exercise_tcx( + 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_export_exercise_tcx_flattened_error_async(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.export_exercise_tcx( + data_points.ExportExerciseTcxRequest(), + name="name_value", + ) + + +def test_get_data_point_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_data_point in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_data_point] = mock_rpc + + request = {} + client.get_data_point(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_data_point(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_data_point_rest_required_fields( + request_type=data_points.GetDataPointRequest, +): + transport_class = transports.DataPointsServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_data_point._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_data_point._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = data_points.DataPoint() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = data_points.DataPoint.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_data_point(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_get_data_point_rest_unset_required_fields(): + transport = transports.DataPointsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_data_point._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_data_point_rest_flattened(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = data_points.DataPoint() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "users/sample1/dataTypes/sample2/dataPoints/sample3"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = data_points.DataPoint.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_data_point(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v4/{name=users/*/dataTypes/*/dataPoints/*}" % client.transport._host, + args[1], + ) + + +def test_get_data_point_rest_flattened_error(transport: str = "rest"): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_data_point( + data_points.GetDataPointRequest(), + name="name_value", + ) + + +def test_list_data_points_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.list_data_points in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.list_data_points] = ( + mock_rpc + ) + + request = {} + client.list_data_points(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_data_points(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_data_points_rest_required_fields( + request_type=data_points.ListDataPointsRequest, +): + transport_class = transports.DataPointsServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_data_points._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_data_points._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = data_points.ListDataPointsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = data_points.ListDataPointsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_data_points(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_list_data_points_rest_unset_required_fields(): + transport = transports.DataPointsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_data_points._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +def test_list_data_points_rest_flattened(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = data_points.ListDataPointsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "users/sample1/dataTypes/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = data_points.ListDataPointsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_data_points(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v4/{parent=users/*/dataTypes/*}/dataPoints" % client.transport._host, + args[1], + ) + + +def test_list_data_points_rest_flattened_error(transport: str = "rest"): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_data_points( + data_points.ListDataPointsRequest(), + parent="parent_value", + ) + + +def test_list_data_points_rest_pager(transport: str = "rest"): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + data_points.ListDataPointsResponse( + data_points=[ + data_points.DataPoint(), + data_points.DataPoint(), + data_points.DataPoint(), + ], + next_page_token="abc", + ), + data_points.ListDataPointsResponse( + data_points=[], + next_page_token="def", + ), + data_points.ListDataPointsResponse( + data_points=[ + data_points.DataPoint(), + ], + next_page_token="ghi", + ), + data_points.ListDataPointsResponse( + data_points=[ + data_points.DataPoint(), + data_points.DataPoint(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + data_points.ListDataPointsResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "users/sample1/dataTypes/sample2"} + + pager = client.list_data_points(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, data_points.DataPoint) for i in results) + + pages = list(client.list_data_points(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_create_data_point_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.create_data_point in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.create_data_point] = ( + mock_rpc + ) + + request = {} + client.create_data_point(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.create_data_point(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_create_data_point_rest_required_fields( + request_type=data_points.CreateDataPointRequest, +): + transport_class = transports.DataPointsServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_data_point._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_data_point._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.create_data_point(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_create_data_point_rest_unset_required_fields(): + transport = transports.DataPointsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.create_data_point._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "dataPoint", + ) + ) + ) + + +def test_create_data_point_rest_flattened(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "users/sample1/dataTypes/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + data_point=data_points.DataPoint( + steps=data_model.Steps( + interval=data_coordinates.ObservationTimeInterval( + start_time=timestamp_pb2.Timestamp(seconds=751) + ) + ) + ), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.create_data_point(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v4/{parent=users/*/dataTypes/*}/dataPoints" % client.transport._host, + args[1], + ) + + +def test_create_data_point_rest_flattened_error(transport: str = "rest"): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_data_point( + data_points.CreateDataPointRequest(), + parent="parent_value", + data_point=data_points.DataPoint( + steps=data_model.Steps( + interval=data_coordinates.ObservationTimeInterval( + start_time=timestamp_pb2.Timestamp(seconds=751) + ) + ) + ), + ) + + +def test_update_data_point_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.update_data_point in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.update_data_point] = ( + mock_rpc + ) + + request = {} + client.update_data_point(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.update_data_point(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_update_data_point_rest_required_fields( + request_type=data_points.UpdateDataPointRequest, +): + transport_class = transports.DataPointsServiceRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_data_point._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_data_point._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.update_data_point(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_update_data_point_rest_unset_required_fields(): + transport = transports.DataPointsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_data_point._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("dataPoint",))) + + +def test_update_data_point_rest_flattened(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = { + "data_point": {"name": "users/sample1/dataTypes/sample2/dataPoints/sample3"} + } + + # get truthy value for each flattened field + mock_args = dict( + data_point=data_points.DataPoint( + steps=data_model.Steps( + interval=data_coordinates.ObservationTimeInterval( + start_time=timestamp_pb2.Timestamp(seconds=751) + ) + ) + ), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.update_data_point(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v4/{data_point.name=users/*/dataTypes/*/dataPoints/*}" + % client.transport._host, + args[1], + ) + + +def test_update_data_point_rest_flattened_error(transport: str = "rest"): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_data_point( + data_points.UpdateDataPointRequest(), + data_point=data_points.DataPoint( + steps=data_model.Steps( + interval=data_coordinates.ObservationTimeInterval( + start_time=timestamp_pb2.Timestamp(seconds=751) + ) + ) + ), + ) + + +def test_batch_delete_data_points_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.batch_delete_data_points + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.batch_delete_data_points + ] = mock_rpc + + request = {} + client.batch_delete_data_points(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.batch_delete_data_points(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_batch_delete_data_points_rest_required_fields( + request_type=data_points.BatchDeleteDataPointsRequest, +): + transport_class = transports.DataPointsServiceRestTransport + + request_init = {} + request_init["names"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_delete_data_points._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["names"] = "names_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_delete_data_points._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "names" in jsonified_request + assert jsonified_request["names"] == "names_value" + + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.batch_delete_data_points(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_batch_delete_data_points_rest_unset_required_fields(): + transport = transports.DataPointsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.batch_delete_data_points._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("names",))) + + +def test_reconcile_data_points_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.reconcile_data_points + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.reconcile_data_points] = ( + mock_rpc + ) + + request = {} + client.reconcile_data_points(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.reconcile_data_points(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_reconcile_data_points_rest_required_fields( + request_type=data_points.ReconcileDataPointsRequest, +): + transport_class = transports.DataPointsServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).reconcile_data_points._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).reconcile_data_points._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "data_source_family", + "filter", + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = data_points.ReconcileDataPointsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = data_points.ReconcileDataPointsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.reconcile_data_points(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_reconcile_data_points_rest_unset_required_fields(): + transport = transports.DataPointsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.reconcile_data_points._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "dataSourceFamily", + "filter", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +def test_reconcile_data_points_rest_pager(transport: str = "rest"): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + data_points.ReconcileDataPointsResponse( + data_points=[ + data_points.ReconciledDataPoint(), + data_points.ReconciledDataPoint(), + data_points.ReconciledDataPoint(), + ], + next_page_token="abc", + ), + data_points.ReconcileDataPointsResponse( + data_points=[], + next_page_token="def", + ), + data_points.ReconcileDataPointsResponse( + data_points=[ + data_points.ReconciledDataPoint(), + ], + next_page_token="ghi", + ), + data_points.ReconcileDataPointsResponse( + data_points=[ + data_points.ReconciledDataPoint(), + data_points.ReconciledDataPoint(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + data_points.ReconcileDataPointsResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "users/sample1/dataTypes/sample2"} + + pager = client.reconcile_data_points(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, data_points.ReconciledDataPoint) for i in results) + + pages = list(client.reconcile_data_points(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_roll_up_data_points_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.roll_up_data_points in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.roll_up_data_points] = ( + mock_rpc + ) + + request = {} + client.roll_up_data_points(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.roll_up_data_points(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_roll_up_data_points_rest_required_fields( + request_type=data_points.RollUpDataPointsRequest, +): + transport_class = transports.DataPointsServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).roll_up_data_points._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).roll_up_data_points._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = data_points.RollUpDataPointsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = data_points.RollUpDataPointsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.roll_up_data_points(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_roll_up_data_points_rest_unset_required_fields(): + transport = transports.DataPointsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.roll_up_data_points._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "range", + "windowSize", + ) + ) + ) + + +def test_roll_up_data_points_rest_pager(transport: str = "rest"): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + data_points.RollUpDataPointsResponse( + rollup_data_points=[ + data_points.RollupDataPoint(), + data_points.RollupDataPoint(), + data_points.RollupDataPoint(), + ], + next_page_token="abc", + ), + data_points.RollUpDataPointsResponse( + rollup_data_points=[], + next_page_token="def", + ), + data_points.RollUpDataPointsResponse( + rollup_data_points=[ + data_points.RollupDataPoint(), + ], + next_page_token="ghi", + ), + data_points.RollUpDataPointsResponse( + rollup_data_points=[ + data_points.RollupDataPoint(), + data_points.RollupDataPoint(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + data_points.RollUpDataPointsResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "users/sample1/dataTypes/sample2"} + + pager = client.roll_up_data_points(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, data_points.RollupDataPoint) for i in results) + + pages = list(client.roll_up_data_points(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_daily_roll_up_data_points_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.daily_roll_up_data_points + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.daily_roll_up_data_points + ] = mock_rpc + + request = {} + client.daily_roll_up_data_points(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.daily_roll_up_data_points(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_daily_roll_up_data_points_rest_required_fields( + request_type=data_points.DailyRollUpDataPointsRequest, +): + transport_class = transports.DataPointsServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).daily_roll_up_data_points._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).daily_roll_up_data_points._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = data_points.DailyRollUpDataPointsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = data_points.DailyRollUpDataPointsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.daily_roll_up_data_points(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_daily_roll_up_data_points_rest_unset_required_fields(): + transport = transports.DataPointsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.daily_roll_up_data_points._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "range", + ) + ) + ) + + +def test_export_exercise_tcx_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.export_exercise_tcx in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.export_exercise_tcx] = ( + mock_rpc + ) + + request = {} + client.export_exercise_tcx(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.export_exercise_tcx(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_export_exercise_tcx_rest_required_fields( + request_type=data_points.ExportExerciseTcxRequest, +): + transport_class = transports.DataPointsServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).export_exercise_tcx._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).export_exercise_tcx._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("partial_data",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = data_points.ExportExerciseTcxResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = data_points.ExportExerciseTcxResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.export_exercise_tcx(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_export_exercise_tcx_rest_unset_required_fields(): + transport = transports.DataPointsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.export_exercise_tcx._get_unset_required_fields({}) + assert set(unset_fields) == (set(("partialData",)) & set(("name",))) + + +def test_export_exercise_tcx_rest_flattened(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = data_points.ExportExerciseTcxResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "users/sample1/dataTypes/sample2/dataPoints/sample3"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = data_points.ExportExerciseTcxResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.export_exercise_tcx(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v4/{name=users/*/dataTypes/*/dataPoints/*}:exportExerciseTcx" + % client.transport._host, + args[1], + ) + + +def test_export_exercise_tcx_rest_flattened_error(transport: str = "rest"): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.export_exercise_tcx( + data_points.ExportExerciseTcxRequest(), + name="name_value", + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.DataPointsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.DataPointsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = DataPointsServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.DataPointsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = DataPointsServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = DataPointsServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.DataPointsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = DataPointsServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.DataPointsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = DataPointsServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.DataPointsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.DataPointsServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.DataPointsServiceGrpcTransport, + transports.DataPointsServiceGrpcAsyncIOTransport, + transports.DataPointsServiceRestTransport, + ], +) +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_kind_grpc(): + transport = DataPointsServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_data_point_empty_call_grpc(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_data_point), "__call__") as call: + call.return_value = data_points.DataPoint() + client.get_data_point(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.GetDataPointRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_data_points_empty_call_grpc(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_data_points), "__call__") as call: + call.return_value = data_points.ListDataPointsResponse() + client.list_data_points(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.ListDataPointsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_data_point_empty_call_grpc(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_data_point), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_data_point(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.CreateDataPointRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_data_point_empty_call_grpc(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_data_point), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.update_data_point(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.UpdateDataPointRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_delete_data_points_empty_call_grpc(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_delete_data_points), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.batch_delete_data_points(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.BatchDeleteDataPointsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_reconcile_data_points_empty_call_grpc(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.reconcile_data_points), "__call__" + ) as call: + call.return_value = data_points.ReconcileDataPointsResponse() + client.reconcile_data_points(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.ReconcileDataPointsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_roll_up_data_points_empty_call_grpc(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.roll_up_data_points), "__call__" + ) as call: + call.return_value = data_points.RollUpDataPointsResponse() + client.roll_up_data_points(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.RollUpDataPointsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_daily_roll_up_data_points_empty_call_grpc(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.daily_roll_up_data_points), "__call__" + ) as call: + call.return_value = data_points.DailyRollUpDataPointsResponse() + client.daily_roll_up_data_points(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.DailyRollUpDataPointsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_export_exercise_tcx_empty_call_grpc(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.export_exercise_tcx), "__call__" + ) as call: + call.return_value = data_points.ExportExerciseTcxResponse() + client.export_exercise_tcx(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.ExportExerciseTcxRequest() + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = DataPointsServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_data_point_empty_call_grpc_asyncio(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_data_point), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_points.DataPoint( + name="name_value", + ) + ) + await client.get_data_point(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.GetDataPointRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_data_points_empty_call_grpc_asyncio(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_data_points), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_points.ListDataPointsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_data_points(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.ListDataPointsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_data_point_empty_call_grpc_asyncio(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_data_point), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.create_data_point(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.CreateDataPointRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_data_point_empty_call_grpc_asyncio(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_data_point), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.update_data_point(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.UpdateDataPointRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_batch_delete_data_points_empty_call_grpc_asyncio(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_delete_data_points), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.batch_delete_data_points(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.BatchDeleteDataPointsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_reconcile_data_points_empty_call_grpc_asyncio(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.reconcile_data_points), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_points.ReconcileDataPointsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.reconcile_data_points(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.ReconcileDataPointsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_roll_up_data_points_empty_call_grpc_asyncio(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.roll_up_data_points), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_points.RollUpDataPointsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.roll_up_data_points(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.RollUpDataPointsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_daily_roll_up_data_points_empty_call_grpc_asyncio(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.daily_roll_up_data_points), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_points.DailyRollUpDataPointsResponse() + ) + await client.daily_roll_up_data_points(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.DailyRollUpDataPointsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_export_exercise_tcx_empty_call_grpc_asyncio(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.export_exercise_tcx), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_points.ExportExerciseTcxResponse( + tcx_data="tcx_data_value", + ) + ) + await client.export_exercise_tcx(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.ExportExerciseTcxRequest() + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = DataPointsServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_data_point_rest_bad_request(request_type=data_points.GetDataPointRequest): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "users/sample1/dataTypes/sample2/dataPoints/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_data_point(request) + + +@pytest.mark.parametrize( + "request_type", + [ + data_points.GetDataPointRequest, + dict, + ], +) +def test_get_data_point_rest_call_success(request_type): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "users/sample1/dataTypes/sample2/dataPoints/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = data_points.DataPoint( + name="name_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = data_points.DataPoint.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_data_point(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, data_points.DataPoint) + assert response.name == "name_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_data_point_rest_interceptors(null_interceptor): + transport = transports.DataPointsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DataPointsServiceRestInterceptor(), + ) + client = DataPointsServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.DataPointsServiceRestInterceptor, "post_get_data_point" + ) as post, + mock.patch.object( + transports.DataPointsServiceRestInterceptor, + "post_get_data_point_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.DataPointsServiceRestInterceptor, "pre_get_data_point" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = data_points.GetDataPointRequest.pb( + data_points.GetDataPointRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = data_points.DataPoint.to_json(data_points.DataPoint()) + req.return_value.content = return_value + + request = data_points.GetDataPointRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = data_points.DataPoint() + post_with_metadata.return_value = data_points.DataPoint(), metadata + + client.get_data_point( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_data_points_rest_bad_request( + request_type=data_points.ListDataPointsRequest, +): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "users/sample1/dataTypes/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_data_points(request) + + +@pytest.mark.parametrize( + "request_type", + [ + data_points.ListDataPointsRequest, + dict, + ], +) +def test_list_data_points_rest_call_success(request_type): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "users/sample1/dataTypes/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = data_points.ListDataPointsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = data_points.ListDataPointsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_data_points(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListDataPointsPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_data_points_rest_interceptors(null_interceptor): + transport = transports.DataPointsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DataPointsServiceRestInterceptor(), + ) + client = DataPointsServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.DataPointsServiceRestInterceptor, "post_list_data_points" + ) as post, + mock.patch.object( + transports.DataPointsServiceRestInterceptor, + "post_list_data_points_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.DataPointsServiceRestInterceptor, "pre_list_data_points" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = data_points.ListDataPointsRequest.pb( + data_points.ListDataPointsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = data_points.ListDataPointsResponse.to_json( + data_points.ListDataPointsResponse() + ) + req.return_value.content = return_value + + request = data_points.ListDataPointsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = data_points.ListDataPointsResponse() + post_with_metadata.return_value = data_points.ListDataPointsResponse(), metadata + + client.list_data_points( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_create_data_point_rest_bad_request( + request_type=data_points.CreateDataPointRequest, +): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "users/sample1/dataTypes/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.create_data_point(request) + + +@pytest.mark.parametrize( + "request_type", + [ + data_points.CreateDataPointRequest, + dict, + ], +) +def test_create_data_point_rest_call_success(request_type): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "users/sample1/dataTypes/sample2"} + request_init["data_point"] = { + "steps": { + "interval": { + "start_time": {"seconds": 751, "nanos": 543}, + "start_utc_offset": {"seconds": 751, "nanos": 543}, + "end_time": {}, + "end_utc_offset": {}, + "civil_start_time": { + "date": {"year": 433, "month": 550, "day": 318}, + "time": { + "hours": 561, + "minutes": 773, + "seconds": 751, + "nanos": 543, + }, + }, + "civil_end_time": {}, + }, + "count": 553, + }, + "floors": {"interval": {}, "count": 553}, + "heart_rate": { + "sample_time": {"physical_time": {}, "utc_offset": {}, "civil_time": {}}, + "beats_per_minute": 1702, + "metadata": {"motion_context": 1, "sensor_location": 1}, + }, + "sleep": { + "interval": { + "start_time": {}, + "start_utc_offset": {}, + "end_time": {}, + "end_utc_offset": {}, + "civil_start_time": {}, + "civil_end_time": {}, + }, + "type_": 1, + "stages": [ + { + "start_time": {}, + "start_utc_offset": {}, + "end_time": {}, + "end_utc_offset": {}, + "type_": 1, + "create_time": {}, + "update_time": {}, + } + ], + "out_of_bed_segments": [ + { + "start_time": {}, + "start_utc_offset": {}, + "end_time": {}, + "end_utc_offset": {}, + } + ], + "metadata": { + "stages_status": 1, + "processed": True, + "nap": True, + "manually_edited": True, + "external_id": "external_id_value", + }, + "summary": { + "minutes_in_sleep_period": 2453, + "minutes_after_wake_up": 2241, + "minutes_to_fall_asleep": 2334, + "minutes_asleep": 1502, + "minutes_awake": 1389, + "stages_summary": [{"type_": 1, "minutes": 773, "count": 553}], + }, + "create_time": {}, + "update_time": {}, + }, + "daily_resting_heart_rate": { + "date": {}, + "beats_per_minute": 1702, + "daily_resting_heart_rate_metadata": {"calculation_method": 1}, + }, + "daily_heart_rate_variability": { + "date": {}, + "average_heart_rate_variability_milliseconds": 0.4541, + "non_rem_heart_rate_beats_per_minute": 3697, + "entropy": 0.785, + "deep_sleep_root_mean_square_of_successive_differences_milliseconds": 0.6971, + }, + "exercise": { + "interval": {}, + "exercise_type": 1, + "splits": [ + { + "start_time": {}, + "start_utc_offset": {}, + "end_time": {}, + "end_utc_offset": {}, + "active_duration": {}, + "metrics_summary": { + "calories_kcal": 0.1356, + "distance_millimeters": 0.2129, + "steps": 559, + "average_speed_millimeters_per_second": 0.3794, + "average_pace_seconds_per_meter": 0.3139, + "average_heart_rate_beats_per_minute": 3678, + "elevation_gain_millimeters": 0.2763, + "active_zone_minutes": 2043, + "run_vo2_max": 0.1136, + "total_swim_lengths": 0.1943, + "heart_rate_zone_durations": { + "light_time": {}, + "moderate_time": {}, + "vigorous_time": {}, + "peak_time": {}, + }, + "mobility_metrics": { + "avg_cadence_steps_per_minute": 0.2949, + "avg_stride_length_millimeters": 3087, + "avg_vertical_oscillation_millimeters": 3837, + "avg_vertical_ratio": 0.19090000000000001, + "avg_ground_contact_time_duration": {}, + }, + }, + "split_type": 1, + } + ], + "exercise_events": [ + {"event_time": {}, "event_utc_offset": {}, "exercise_event_type": 1} + ], + "split_summaries": {}, + "metrics_summary": {}, + "exercise_metadata": {"pool_length_millimeters": 2465, "has_gps": True}, + "display_name": "display_name_value", + "active_duration": {}, + "notes": "notes_value", + "update_time": {}, + "create_time": {}, + }, + "weight": { + "sample_time": {}, + "weight_grams": 0.12810000000000002, + "notes": "notes_value", + }, + "altitude": {"interval": {}, "gain_millimeters": 1701}, + "distance": {"interval": {}, "millimeters": 1191}, + "body_fat": {"sample_time": {}, "percentage": 0.10540000000000001}, + "active_zone_minutes": { + "interval": {}, + "heart_rate_zone": 1, + "active_zone_minutes": 2043, + }, + "heart_rate_variability": { + "sample_time": {}, + "root_mean_square_of_successive_differences_milliseconds": 0.5830000000000001, + "standard_deviation_milliseconds": 0.32880000000000004, + }, + "daily_sleep_temperature_derivations": { + "date": {}, + "nightly_temperature_celsius": 0.29150000000000004, + "baseline_temperature_celsius": 0.2983, + "relative_nightly_stddev_30d_celsius": 0.36160000000000003, + }, + "sedentary_period": {"interval": {}}, + "run_vo2_max": {"sample_time": {}, "run_vo2_max": 0.1136}, + "oxygen_saturation": {"sample_time": {}, "percentage": 0.10540000000000001}, + "daily_oxygen_saturation": { + "date": {}, + "average_percentage": 0.188, + "lower_bound_percentage": 0.2333, + "upper_bound_percentage": 0.2336, + "standard_deviation_percentage": 0.30560000000000004, + }, + "activity_level": {"interval": {}, "activity_level_type": 1}, + "vo2_max": { + "sample_time": {}, + "vo2_max": 0.7000000000000001, + "measurement_method": 1, + }, + "daily_vo2_max": { + "date": {}, + "vo2_max": 0.7000000000000001, + "estimated": True, + "cardio_fitness_level": 1, + "vo2_max_covariance": 0.18460000000000001, + }, + "nutrition_log": { + "interval": {}, + "nutrients": [ + {"quantity": {"grams": 0.538, "user_provided_unit": 1}, "nutrient": 1} + ], + "energy": {"kcal": 0.41100000000000003, "user_provided_unit": 1}, + "energy_from_fat": {}, + "total_carbohydrate": {}, + "total_fat": {}, + "meal_type": 1, + "serving": { + "amount": 0.66, + "food_measurement_unit": "food_measurement_unit_value", + "food_measurement_unit_display_name": "food_measurement_unit_display_name_value", + }, + "food": "food_value", + "food_display_name": "food_display_name_value", + }, + "irregular_rhythm_notification": { + "interval": {}, + "alert_windows": [ + { + "start_time": {}, + "start_utc_offset": {}, + "end_time": {}, + "end_utc_offset": {}, + "civil_start_time": {}, + "civil_end_time": {}, + "positive": True, + "heart_beats": [ + { + "physical_time": {}, + "utc_offset": {}, + "civil_time": {}, + "beats_per_minute": 1702, + } + ], + } + ], + "medical_device_info": { + "algorithm_version": "algorithm_version_value", + "service_version": "service_version_value", + "firmware_version": "firmware_version_value", + "feature_version": "feature_version_value", + "device_model": "device_model_value", + }, + }, + "electrocardiogram": { + "interval": {}, + "beats_per_minute_avg": 2115, + "result_classification": 1, + "waveform_samples": [1724, 1725], + "sampling_frequency_hertz": 2584, + "millivolts_scaling_factor": 2669, + "lead_number": 1150, + "medical_device_info": {}, + }, + "daily_heart_rate_zones": { + "date": {}, + "heart_rate_zones": [ + { + "heart_rate_zone_type": 1, + "min_beats_per_minute": 2121, + "max_beats_per_minute": 2123, + } + ], + }, + "hydration_log": { + "interval": {}, + "amount_consumed": {"milliliters": 0.1194, "user_provided_unit": 1}, + }, + "food": { + "display_name": "display_name_value", + "brand": "brand_value", + "access_level": 1, + "description": "description_value", + "language_code": "language_code_value", + "meal_type": 1, + "nutrients": {}, + "energy_from_fat": {}, + "total_carbohydrate": {}, + "total_fat": {}, + "energy_min": {}, + "energy_avg": {}, + "energy_max": {}, + "default_serving": { + "amount": 0.66, + "food_measurement_unit": "food_measurement_unit_value", + "food_measurement_unit_display_name": "food_measurement_unit_display_name_value", + "food_measurement_unit_display_name_plural": "food_measurement_unit_display_name_plural_value", + "multiplier": 0.1095, + }, + "servings": {}, + }, + "time_in_heart_rate_zone": {"interval": {}, "heart_rate_zone_type": 1}, + "active_minutes": { + "interval": {}, + "active_minutes_by_activity_level": [ + {"activity_level": 1, "active_minutes": 1504} + ], + }, + "respiratory_rate_sleep_summary": { + "sample_time": {}, + "deep_sleep_stats": { + "breaths_per_minute": 0.192, + "standard_deviation": 0.1907, + "signal_to_noise": 0.1597, + }, + "light_sleep_stats": {}, + "rem_sleep_stats": {}, + "full_sleep_stats": {}, + }, + "daily_respiratory_rate": {"date": {}, "breaths_per_minute": 0.192}, + "swim_lengths_data": { + "interval": {}, + "swim_stroke_type": 1, + "stroke_count": 1312, + }, + "height": {"sample_time": {}, "height_millimeters": 1919}, + "basal_energy_burned": {"interval": {}, "kcal": 0.41100000000000003}, + "core_body_temperature": { + "sample_time": {}, + "temperature_celsius": 0.2053, + "measurement_location": 1, + "id": "id_value", + }, + "active_energy_burned": {"interval": {}, "kcal": 0.41100000000000003}, + "food_measurement_unit": { + "display_name": "display_name_value", + "plural_display_name": "plural_display_name_value", + }, + "blood_glucose": { + "sample_time": {}, + "blood_glucose_milligrams_per_deciliter": 0.4011, + "measurement_source": 1, + "meal_type": 1, + "measurement_timing": 1, + "specimen": 1, + "notes": "notes_value", + }, + "name": "name_value", + "data_source": { + "recording_method": 1, + "device": { + "form_factor": 1, + "manufacturer": "manufacturer_value", + "display_name": "display_name_value", + }, + "application": { + "package_name": "package_name_value", + "web_client_id": "web_client_id_value", + "google_web_client_id": "google_web_client_id_value", + }, + "platform": 1, + }, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = data_points.CreateDataPointRequest.meta.fields["data_point"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["data_point"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["data_point"][field])): + del request_init["data_point"][field][i][subfield] + else: + del request_init["data_point"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.create_data_point(request) + + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_data_point_rest_interceptors(null_interceptor): + transport = transports.DataPointsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DataPointsServiceRestInterceptor(), + ) + client = DataPointsServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), + mock.patch.object( + transports.DataPointsServiceRestInterceptor, "post_create_data_point" + ) as post, + mock.patch.object( + transports.DataPointsServiceRestInterceptor, + "post_create_data_point_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.DataPointsServiceRestInterceptor, "pre_create_data_point" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = data_points.CreateDataPointRequest.pb( + data_points.CreateDataPointRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value + + request = data_points.CreateDataPointRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata + + client.create_data_point( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_update_data_point_rest_bad_request( + request_type=data_points.UpdateDataPointRequest, +): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "data_point": {"name": "users/sample1/dataTypes/sample2/dataPoints/sample3"} + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.update_data_point(request) + + +@pytest.mark.parametrize( + "request_type", + [ + data_points.UpdateDataPointRequest, + dict, + ], +) +def test_update_data_point_rest_call_success(request_type): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "data_point": {"name": "users/sample1/dataTypes/sample2/dataPoints/sample3"} + } + request_init["data_point"] = { + "steps": { + "interval": { + "start_time": {"seconds": 751, "nanos": 543}, + "start_utc_offset": {"seconds": 751, "nanos": 543}, + "end_time": {}, + "end_utc_offset": {}, + "civil_start_time": { + "date": {"year": 433, "month": 550, "day": 318}, + "time": { + "hours": 561, + "minutes": 773, + "seconds": 751, + "nanos": 543, + }, + }, + "civil_end_time": {}, + }, + "count": 553, + }, + "floors": {"interval": {}, "count": 553}, + "heart_rate": { + "sample_time": {"physical_time": {}, "utc_offset": {}, "civil_time": {}}, + "beats_per_minute": 1702, + "metadata": {"motion_context": 1, "sensor_location": 1}, + }, + "sleep": { + "interval": { + "start_time": {}, + "start_utc_offset": {}, + "end_time": {}, + "end_utc_offset": {}, + "civil_start_time": {}, + "civil_end_time": {}, + }, + "type_": 1, + "stages": [ + { + "start_time": {}, + "start_utc_offset": {}, + "end_time": {}, + "end_utc_offset": {}, + "type_": 1, + "create_time": {}, + "update_time": {}, + } + ], + "out_of_bed_segments": [ + { + "start_time": {}, + "start_utc_offset": {}, + "end_time": {}, + "end_utc_offset": {}, + } + ], + "metadata": { + "stages_status": 1, + "processed": True, + "nap": True, + "manually_edited": True, + "external_id": "external_id_value", + }, + "summary": { + "minutes_in_sleep_period": 2453, + "minutes_after_wake_up": 2241, + "minutes_to_fall_asleep": 2334, + "minutes_asleep": 1502, + "minutes_awake": 1389, + "stages_summary": [{"type_": 1, "minutes": 773, "count": 553}], + }, + "create_time": {}, + "update_time": {}, + }, + "daily_resting_heart_rate": { + "date": {}, + "beats_per_minute": 1702, + "daily_resting_heart_rate_metadata": {"calculation_method": 1}, + }, + "daily_heart_rate_variability": { + "date": {}, + "average_heart_rate_variability_milliseconds": 0.4541, + "non_rem_heart_rate_beats_per_minute": 3697, + "entropy": 0.785, + "deep_sleep_root_mean_square_of_successive_differences_milliseconds": 0.6971, + }, + "exercise": { + "interval": {}, + "exercise_type": 1, + "splits": [ + { + "start_time": {}, + "start_utc_offset": {}, + "end_time": {}, + "end_utc_offset": {}, + "active_duration": {}, + "metrics_summary": { + "calories_kcal": 0.1356, + "distance_millimeters": 0.2129, + "steps": 559, + "average_speed_millimeters_per_second": 0.3794, + "average_pace_seconds_per_meter": 0.3139, + "average_heart_rate_beats_per_minute": 3678, + "elevation_gain_millimeters": 0.2763, + "active_zone_minutes": 2043, + "run_vo2_max": 0.1136, + "total_swim_lengths": 0.1943, + "heart_rate_zone_durations": { + "light_time": {}, + "moderate_time": {}, + "vigorous_time": {}, + "peak_time": {}, + }, + "mobility_metrics": { + "avg_cadence_steps_per_minute": 0.2949, + "avg_stride_length_millimeters": 3087, + "avg_vertical_oscillation_millimeters": 3837, + "avg_vertical_ratio": 0.19090000000000001, + "avg_ground_contact_time_duration": {}, + }, + }, + "split_type": 1, + } + ], + "exercise_events": [ + {"event_time": {}, "event_utc_offset": {}, "exercise_event_type": 1} + ], + "split_summaries": {}, + "metrics_summary": {}, + "exercise_metadata": {"pool_length_millimeters": 2465, "has_gps": True}, + "display_name": "display_name_value", + "active_duration": {}, + "notes": "notes_value", + "update_time": {}, + "create_time": {}, + }, + "weight": { + "sample_time": {}, + "weight_grams": 0.12810000000000002, + "notes": "notes_value", + }, + "altitude": {"interval": {}, "gain_millimeters": 1701}, + "distance": {"interval": {}, "millimeters": 1191}, + "body_fat": {"sample_time": {}, "percentage": 0.10540000000000001}, + "active_zone_minutes": { + "interval": {}, + "heart_rate_zone": 1, + "active_zone_minutes": 2043, + }, + "heart_rate_variability": { + "sample_time": {}, + "root_mean_square_of_successive_differences_milliseconds": 0.5830000000000001, + "standard_deviation_milliseconds": 0.32880000000000004, + }, + "daily_sleep_temperature_derivations": { + "date": {}, + "nightly_temperature_celsius": 0.29150000000000004, + "baseline_temperature_celsius": 0.2983, + "relative_nightly_stddev_30d_celsius": 0.36160000000000003, + }, + "sedentary_period": {"interval": {}}, + "run_vo2_max": {"sample_time": {}, "run_vo2_max": 0.1136}, + "oxygen_saturation": {"sample_time": {}, "percentage": 0.10540000000000001}, + "daily_oxygen_saturation": { + "date": {}, + "average_percentage": 0.188, + "lower_bound_percentage": 0.2333, + "upper_bound_percentage": 0.2336, + "standard_deviation_percentage": 0.30560000000000004, + }, + "activity_level": {"interval": {}, "activity_level_type": 1}, + "vo2_max": { + "sample_time": {}, + "vo2_max": 0.7000000000000001, + "measurement_method": 1, + }, + "daily_vo2_max": { + "date": {}, + "vo2_max": 0.7000000000000001, + "estimated": True, + "cardio_fitness_level": 1, + "vo2_max_covariance": 0.18460000000000001, + }, + "nutrition_log": { + "interval": {}, + "nutrients": [ + {"quantity": {"grams": 0.538, "user_provided_unit": 1}, "nutrient": 1} + ], + "energy": {"kcal": 0.41100000000000003, "user_provided_unit": 1}, + "energy_from_fat": {}, + "total_carbohydrate": {}, + "total_fat": {}, + "meal_type": 1, + "serving": { + "amount": 0.66, + "food_measurement_unit": "food_measurement_unit_value", + "food_measurement_unit_display_name": "food_measurement_unit_display_name_value", + }, + "food": "food_value", + "food_display_name": "food_display_name_value", + }, + "irregular_rhythm_notification": { + "interval": {}, + "alert_windows": [ + { + "start_time": {}, + "start_utc_offset": {}, + "end_time": {}, + "end_utc_offset": {}, + "civil_start_time": {}, + "civil_end_time": {}, + "positive": True, + "heart_beats": [ + { + "physical_time": {}, + "utc_offset": {}, + "civil_time": {}, + "beats_per_minute": 1702, + } + ], + } + ], + "medical_device_info": { + "algorithm_version": "algorithm_version_value", + "service_version": "service_version_value", + "firmware_version": "firmware_version_value", + "feature_version": "feature_version_value", + "device_model": "device_model_value", + }, + }, + "electrocardiogram": { + "interval": {}, + "beats_per_minute_avg": 2115, + "result_classification": 1, + "waveform_samples": [1724, 1725], + "sampling_frequency_hertz": 2584, + "millivolts_scaling_factor": 2669, + "lead_number": 1150, + "medical_device_info": {}, + }, + "daily_heart_rate_zones": { + "date": {}, + "heart_rate_zones": [ + { + "heart_rate_zone_type": 1, + "min_beats_per_minute": 2121, + "max_beats_per_minute": 2123, + } + ], + }, + "hydration_log": { + "interval": {}, + "amount_consumed": {"milliliters": 0.1194, "user_provided_unit": 1}, + }, + "food": { + "display_name": "display_name_value", + "brand": "brand_value", + "access_level": 1, + "description": "description_value", + "language_code": "language_code_value", + "meal_type": 1, + "nutrients": {}, + "energy_from_fat": {}, + "total_carbohydrate": {}, + "total_fat": {}, + "energy_min": {}, + "energy_avg": {}, + "energy_max": {}, + "default_serving": { + "amount": 0.66, + "food_measurement_unit": "food_measurement_unit_value", + "food_measurement_unit_display_name": "food_measurement_unit_display_name_value", + "food_measurement_unit_display_name_plural": "food_measurement_unit_display_name_plural_value", + "multiplier": 0.1095, + }, + "servings": {}, + }, + "time_in_heart_rate_zone": {"interval": {}, "heart_rate_zone_type": 1}, + "active_minutes": { + "interval": {}, + "active_minutes_by_activity_level": [ + {"activity_level": 1, "active_minutes": 1504} + ], + }, + "respiratory_rate_sleep_summary": { + "sample_time": {}, + "deep_sleep_stats": { + "breaths_per_minute": 0.192, + "standard_deviation": 0.1907, + "signal_to_noise": 0.1597, + }, + "light_sleep_stats": {}, + "rem_sleep_stats": {}, + "full_sleep_stats": {}, + }, + "daily_respiratory_rate": {"date": {}, "breaths_per_minute": 0.192}, + "swim_lengths_data": { + "interval": {}, + "swim_stroke_type": 1, + "stroke_count": 1312, + }, + "height": {"sample_time": {}, "height_millimeters": 1919}, + "basal_energy_burned": {"interval": {}, "kcal": 0.41100000000000003}, + "core_body_temperature": { + "sample_time": {}, + "temperature_celsius": 0.2053, + "measurement_location": 1, + "id": "id_value", + }, + "active_energy_burned": {"interval": {}, "kcal": 0.41100000000000003}, + "food_measurement_unit": { + "display_name": "display_name_value", + "plural_display_name": "plural_display_name_value", + }, + "blood_glucose": { + "sample_time": {}, + "blood_glucose_milligrams_per_deciliter": 0.4011, + "measurement_source": 1, + "meal_type": 1, + "measurement_timing": 1, + "specimen": 1, + "notes": "notes_value", + }, + "name": "users/sample1/dataTypes/sample2/dataPoints/sample3", + "data_source": { + "recording_method": 1, + "device": { + "form_factor": 1, + "manufacturer": "manufacturer_value", + "display_name": "display_name_value", + }, + "application": { + "package_name": "package_name_value", + "web_client_id": "web_client_id_value", + "google_web_client_id": "google_web_client_id_value", + }, + "platform": 1, + }, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = data_points.UpdateDataPointRequest.meta.fields["data_point"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["data_point"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["data_point"][field])): + del request_init["data_point"][field][i][subfield] + else: + del request_init["data_point"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.update_data_point(request) + + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_data_point_rest_interceptors(null_interceptor): + transport = transports.DataPointsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DataPointsServiceRestInterceptor(), + ) + client = DataPointsServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), + mock.patch.object( + transports.DataPointsServiceRestInterceptor, "post_update_data_point" + ) as post, + mock.patch.object( + transports.DataPointsServiceRestInterceptor, + "post_update_data_point_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.DataPointsServiceRestInterceptor, "pre_update_data_point" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = data_points.UpdateDataPointRequest.pb( + data_points.UpdateDataPointRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value + + request = data_points.UpdateDataPointRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata + + client.update_data_point( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_batch_delete_data_points_rest_bad_request( + request_type=data_points.BatchDeleteDataPointsRequest, +): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "users/sample1/dataTypes/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.batch_delete_data_points(request) + + +@pytest.mark.parametrize( + "request_type", + [ + data_points.BatchDeleteDataPointsRequest, + dict, + ], +) +def test_batch_delete_data_points_rest_call_success(request_type): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "users/sample1/dataTypes/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.batch_delete_data_points(request) + + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_delete_data_points_rest_interceptors(null_interceptor): + transport = transports.DataPointsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DataPointsServiceRestInterceptor(), + ) + client = DataPointsServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), + mock.patch.object( + transports.DataPointsServiceRestInterceptor, "post_batch_delete_data_points" + ) as post, + mock.patch.object( + transports.DataPointsServiceRestInterceptor, + "post_batch_delete_data_points_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.DataPointsServiceRestInterceptor, "pre_batch_delete_data_points" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = data_points.BatchDeleteDataPointsRequest.pb( + data_points.BatchDeleteDataPointsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value + + request = data_points.BatchDeleteDataPointsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata + + client.batch_delete_data_points( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_reconcile_data_points_rest_bad_request( + request_type=data_points.ReconcileDataPointsRequest, +): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "users/sample1/dataTypes/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.reconcile_data_points(request) + + +@pytest.mark.parametrize( + "request_type", + [ + data_points.ReconcileDataPointsRequest, + dict, + ], +) +def test_reconcile_data_points_rest_call_success(request_type): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "users/sample1/dataTypes/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = data_points.ReconcileDataPointsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = data_points.ReconcileDataPointsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.reconcile_data_points(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ReconcileDataPointsPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_reconcile_data_points_rest_interceptors(null_interceptor): + transport = transports.DataPointsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DataPointsServiceRestInterceptor(), + ) + client = DataPointsServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.DataPointsServiceRestInterceptor, "post_reconcile_data_points" + ) as post, + mock.patch.object( + transports.DataPointsServiceRestInterceptor, + "post_reconcile_data_points_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.DataPointsServiceRestInterceptor, "pre_reconcile_data_points" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = data_points.ReconcileDataPointsRequest.pb( + data_points.ReconcileDataPointsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = data_points.ReconcileDataPointsResponse.to_json( + data_points.ReconcileDataPointsResponse() + ) + req.return_value.content = return_value + + request = data_points.ReconcileDataPointsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = data_points.ReconcileDataPointsResponse() + post_with_metadata.return_value = ( + data_points.ReconcileDataPointsResponse(), + metadata, + ) + + client.reconcile_data_points( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_roll_up_data_points_rest_bad_request( + request_type=data_points.RollUpDataPointsRequest, +): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "users/sample1/dataTypes/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.roll_up_data_points(request) + + +@pytest.mark.parametrize( + "request_type", + [ + data_points.RollUpDataPointsRequest, + dict, + ], +) +def test_roll_up_data_points_rest_call_success(request_type): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "users/sample1/dataTypes/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = data_points.RollUpDataPointsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = data_points.RollUpDataPointsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.roll_up_data_points(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.RollUpDataPointsPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_roll_up_data_points_rest_interceptors(null_interceptor): + transport = transports.DataPointsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DataPointsServiceRestInterceptor(), + ) + client = DataPointsServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.DataPointsServiceRestInterceptor, "post_roll_up_data_points" + ) as post, + mock.patch.object( + transports.DataPointsServiceRestInterceptor, + "post_roll_up_data_points_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.DataPointsServiceRestInterceptor, "pre_roll_up_data_points" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = data_points.RollUpDataPointsRequest.pb( + data_points.RollUpDataPointsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = data_points.RollUpDataPointsResponse.to_json( + data_points.RollUpDataPointsResponse() + ) + req.return_value.content = return_value + + request = data_points.RollUpDataPointsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = data_points.RollUpDataPointsResponse() + post_with_metadata.return_value = ( + data_points.RollUpDataPointsResponse(), + metadata, + ) + + client.roll_up_data_points( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_daily_roll_up_data_points_rest_bad_request( + request_type=data_points.DailyRollUpDataPointsRequest, +): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "users/sample1/dataTypes/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.daily_roll_up_data_points(request) + + +@pytest.mark.parametrize( + "request_type", + [ + data_points.DailyRollUpDataPointsRequest, + dict, + ], +) +def test_daily_roll_up_data_points_rest_call_success(request_type): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "users/sample1/dataTypes/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = data_points.DailyRollUpDataPointsResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = data_points.DailyRollUpDataPointsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.daily_roll_up_data_points(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, data_points.DailyRollUpDataPointsResponse) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_daily_roll_up_data_points_rest_interceptors(null_interceptor): + transport = transports.DataPointsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DataPointsServiceRestInterceptor(), + ) + client = DataPointsServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.DataPointsServiceRestInterceptor, + "post_daily_roll_up_data_points", + ) as post, + mock.patch.object( + transports.DataPointsServiceRestInterceptor, + "post_daily_roll_up_data_points_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.DataPointsServiceRestInterceptor, "pre_daily_roll_up_data_points" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = data_points.DailyRollUpDataPointsRequest.pb( + data_points.DailyRollUpDataPointsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = data_points.DailyRollUpDataPointsResponse.to_json( + data_points.DailyRollUpDataPointsResponse() + ) + req.return_value.content = return_value + + request = data_points.DailyRollUpDataPointsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = data_points.DailyRollUpDataPointsResponse() + post_with_metadata.return_value = ( + data_points.DailyRollUpDataPointsResponse(), + metadata, + ) + + client.daily_roll_up_data_points( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_export_exercise_tcx_rest_bad_request( + request_type=data_points.ExportExerciseTcxRequest, +): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "users/sample1/dataTypes/sample2/dataPoints/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.export_exercise_tcx(request) + + +@pytest.mark.parametrize( + "request_type", + [ + data_points.ExportExerciseTcxRequest, + dict, + ], +) +def test_export_exercise_tcx_rest_call_success(request_type): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "users/sample1/dataTypes/sample2/dataPoints/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = data_points.ExportExerciseTcxResponse( + tcx_data="tcx_data_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = data_points.ExportExerciseTcxResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.export_exercise_tcx(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, data_points.ExportExerciseTcxResponse) + assert response.tcx_data == "tcx_data_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_export_exercise_tcx_rest_interceptors(null_interceptor): + transport = transports.DataPointsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DataPointsServiceRestInterceptor(), + ) + client = DataPointsServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.DataPointsServiceRestInterceptor, "post_export_exercise_tcx" + ) as post, + mock.patch.object( + transports.DataPointsServiceRestInterceptor, + "post_export_exercise_tcx_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.DataPointsServiceRestInterceptor, "pre_export_exercise_tcx" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = data_points.ExportExerciseTcxRequest.pb( + data_points.ExportExerciseTcxRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = data_points.ExportExerciseTcxResponse.to_json( + data_points.ExportExerciseTcxResponse() + ) + req.return_value.content = return_value + + request = data_points.ExportExerciseTcxRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = data_points.ExportExerciseTcxResponse() + post_with_metadata.return_value = ( + data_points.ExportExerciseTcxResponse(), + metadata, + ) + + client.export_exercise_tcx( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_initialize_client_w_rest(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_data_point_empty_call_rest(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_data_point), "__call__") as call: + client.get_data_point(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.GetDataPointRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_data_points_empty_call_rest(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_data_points), "__call__") as call: + client.list_data_points(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.ListDataPointsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_data_point_empty_call_rest(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_data_point), "__call__" + ) as call: + client.create_data_point(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.CreateDataPointRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_data_point_empty_call_rest(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_data_point), "__call__" + ) as call: + client.update_data_point(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.UpdateDataPointRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_delete_data_points_empty_call_rest(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_delete_data_points), "__call__" + ) as call: + client.batch_delete_data_points(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.BatchDeleteDataPointsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_reconcile_data_points_empty_call_rest(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.reconcile_data_points), "__call__" + ) as call: + client.reconcile_data_points(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.ReconcileDataPointsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_roll_up_data_points_empty_call_rest(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.roll_up_data_points), "__call__" + ) as call: + client.roll_up_data_points(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.RollUpDataPointsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_daily_roll_up_data_points_empty_call_rest(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.daily_roll_up_data_points), "__call__" + ) as call: + client.daily_roll_up_data_points(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.DailyRollUpDataPointsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_export_exercise_tcx_empty_call_rest(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.export_exercise_tcx), "__call__" + ) as call: + client.export_exercise_tcx(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_points.ExportExerciseTcxRequest() + assert args[0] == request_msg + + +def test_data_points_service_rest_lro_client(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + transport = client.transport + + # Ensure that we have an api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.AbstractOperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.DataPointsServiceGrpcTransport, + ) + + +def test_data_points_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.DataPointsServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_data_points_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.devicesandservices.health_v4.services.data_points_service.transports.DataPointsServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.DataPointsServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "get_data_point", + "list_data_points", + "create_data_point", + "update_data_point", + "batch_delete_data_points", + "reconcile_data_points", + "roll_up_data_points", + "daily_roll_up_data_points", + "export_exercise_tcx", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Additionally, the LRO client (a property) should + # also raise NotImplementedError + with pytest.raises(NotImplementedError): + transport.operations_client + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_data_points_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.devicesandservices.health_v4.services.data_points_service.transports.DataPointsServiceTransport._prep_wrapped_messages" + ) as Transport, + ): + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.DataPointsServiceTransport( + 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/googlehealth.activity_and_fitness.readonly", + "https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.readonly", + "https://www.googleapis.com/auth/googlehealth.location.readonly", + "https://www.googleapis.com/auth/googlehealth.sleep.readonly", + ), + quota_project_id="octopus", + ) + + +def test_data_points_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.devicesandservices.health_v4.services.data_points_service.transports.DataPointsServiceTransport._prep_wrapped_messages" + ) as Transport, + ): + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.DataPointsServiceTransport() + adc.assert_called_once() + + +def test_data_points_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) + DataPointsServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + "https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly", + "https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.readonly", + "https://www.googleapis.com/auth/googlehealth.location.readonly", + "https://www.googleapis.com/auth/googlehealth.sleep.readonly", + ), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.DataPointsServiceGrpcTransport, + transports.DataPointsServiceGrpcAsyncIOTransport, + ], +) +def test_data_points_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/googlehealth.activity_and_fitness.readonly", + "https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.readonly", + "https://www.googleapis.com/auth/googlehealth.location.readonly", + "https://www.googleapis.com/auth/googlehealth.sleep.readonly", + ), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.DataPointsServiceGrpcTransport, + transports.DataPointsServiceGrpcAsyncIOTransport, + transports.DataPointsServiceRestTransport, + ], +) +def test_data_points_service_transport_auth_gdch_credentials(transport_class): + host = "https://language.com" + api_audience_tests = [None, "https://language2.com"] + api_audience_expect = [host, "https://language2.com"] + for t, e in zip(api_audience_tests, api_audience_expect): + with mock.patch.object(google.auth, "default", autospec=True) as adc: + gdch_mock = mock.MagicMock() + type(gdch_mock).with_gdch_audience = mock.PropertyMock( + return_value=gdch_mock + ) + adc.return_value = (gdch_mock, None) + transport_class(host=host, api_audience=t) + gdch_mock.with_gdch_audience.assert_called_once_with(e) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.DataPointsServiceGrpcTransport, grpc_helpers), + (transports.DataPointsServiceGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +def test_data_points_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( + "health.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + "https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly", + "https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.readonly", + "https://www.googleapis.com/auth/googlehealth.location.readonly", + "https://www.googleapis.com/auth/googlehealth.sleep.readonly", + ), + scopes=["1", "2"], + default_host="health.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.DataPointsServiceGrpcTransport, + transports.DataPointsServiceGrpcAsyncIOTransport, + ], +) +def test_data_points_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_data_points_service_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.DataPointsServiceRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_data_points_service_host_no_port(transport_name): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="health.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "health.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://health.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_data_points_service_host_with_port(transport_name): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="health.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "health.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://health.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_data_points_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = DataPointsServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = DataPointsServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.get_data_point._session + session2 = client2.transport.get_data_point._session + assert session1 != session2 + session1 = client1.transport.list_data_points._session + session2 = client2.transport.list_data_points._session + assert session1 != session2 + session1 = client1.transport.create_data_point._session + session2 = client2.transport.create_data_point._session + assert session1 != session2 + session1 = client1.transport.update_data_point._session + session2 = client2.transport.update_data_point._session + assert session1 != session2 + session1 = client1.transport.batch_delete_data_points._session + session2 = client2.transport.batch_delete_data_points._session + assert session1 != session2 + session1 = client1.transport.reconcile_data_points._session + session2 = client2.transport.reconcile_data_points._session + assert session1 != session2 + session1 = client1.transport.roll_up_data_points._session + session2 = client2.transport.roll_up_data_points._session + assert session1 != session2 + session1 = client1.transport.daily_roll_up_data_points._session + session2 = client2.transport.daily_roll_up_data_points._session + assert session1 != session2 + session1 = client1.transport.export_exercise_tcx._session + session2 = client2.transport.export_exercise_tcx._session + assert session1 != session2 + + +def test_data_points_service_grpc_transport_channel(): + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.DataPointsServiceGrpcTransport( + 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_data_points_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.DataPointsServiceGrpcAsyncIOTransport( + 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.filterwarnings("ignore::FutureWarning") +@pytest.mark.parametrize( + "transport_class", + [ + transports.DataPointsServiceGrpcTransport, + transports.DataPointsServiceGrpcAsyncIOTransport, + ], +) +def test_data_points_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.DataPointsServiceGrpcTransport, + transports.DataPointsServiceGrpcAsyncIOTransport, + ], +) +def test_data_points_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_data_points_service_grpc_lro_client(): + client = DataPointsServiceClient( + 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_data_points_service_grpc_lro_async_client(): + client = DataPointsServiceAsyncClient( + 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_data_point_path(): + user = "squid" + data_type = "clam" + data_point = "whelk" + expected = "users/{user}/dataTypes/{data_type}/dataPoints/{data_point}".format( + user=user, + data_type=data_type, + data_point=data_point, + ) + actual = DataPointsServiceClient.data_point_path(user, data_type, data_point) + assert expected == actual + + +def test_parse_data_point_path(): + expected = { + "user": "octopus", + "data_type": "oyster", + "data_point": "nudibranch", + } + path = DataPointsServiceClient.data_point_path(**expected) + + # Check that the path construction is reversible. + actual = DataPointsServiceClient.parse_data_point_path(path) + assert expected == actual + + +def test_data_type_path(): + user = "cuttlefish" + data_type = "mussel" + expected = "users/{user}/dataTypes/{data_type}".format( + user=user, + data_type=data_type, + ) + actual = DataPointsServiceClient.data_type_path(user, data_type) + assert expected == actual + + +def test_parse_data_type_path(): + expected = { + "user": "winkle", + "data_type": "nautilus", + } + path = DataPointsServiceClient.data_type_path(**expected) + + # Check that the path construction is reversible. + actual = DataPointsServiceClient.parse_data_type_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "scallop" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = DataPointsServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "abalone", + } + path = DataPointsServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = DataPointsServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "squid" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = DataPointsServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "clam", + } + path = DataPointsServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = DataPointsServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "whelk" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = DataPointsServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "octopus", + } + path = DataPointsServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = DataPointsServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "oyster" + expected = "projects/{project}".format( + project=project, + ) + actual = DataPointsServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nudibranch", + } + path = DataPointsServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = DataPointsServiceClient.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 = DataPointsServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "winkle", + "location": "nautilus", + } + path = DataPointsServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = DataPointsServiceClient.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.DataPointsServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.DataPointsServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = DataPointsServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_grpc(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +@pytest.mark.asyncio +async def test_transport_close_grpc_asyncio(): + client = DataPointsServiceAsyncClient( + credentials=async_anonymous_credentials(), 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_rest(): + client = DataPointsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + "grpc", + ] + for transport in transports: + client = DataPointsServiceClient( + 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", + [ + (DataPointsServiceClient, transports.DataPointsServiceGrpcTransport), + ( + DataPointsServiceAsyncClient, + transports.DataPointsServiceGrpcAsyncIOTransport, + ), + ], +) +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_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/packages/google-devicesandservices-health/tests/unit/gapic/health_v4/test_data_subscription_service.py b/packages/google-devicesandservices-health/tests/unit/gapic/health_v4/test_data_subscription_service.py new file mode 100644 index 000000000000..d20c45db4cd8 --- /dev/null +++ b/packages/google-devicesandservices-health/tests/unit/gapic/health_v4/test_data_subscription_service.py @@ -0,0 +1,9154 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 asyncio +import json +import math +import os +from collections.abc import AsyncIterable, Iterable, Mapping, Sequence +from unittest import mock +from unittest.mock import AsyncMock + +import grpc +import pytest +from google.api_core import api_core_version +from google.protobuf import json_format +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +import google.api_core.operation_async as operation_async # type: ignore +import google.auth +import google.protobuf.empty_pb2 as empty_pb2 # type: ignore +import google.protobuf.field_mask_pb2 as field_mask_pb2 # type: ignore +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore +from google.api_core import ( + client_options, + future, + gapic_v1, + grpc_helpers, + grpc_helpers_async, + operation, + operations_v1, + path_template, +) +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account + +from google.devicesandservices.health_v4.services.data_subscription_service import ( + DataSubscriptionServiceAsyncClient, + DataSubscriptionServiceClient, + pagers, + transports, +) +from google.devicesandservices.health_v4.types import data_subscription_service + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + +# 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 + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +@pytest.fixture(autouse=True) +def set_event_loop(): + try: + asyncio.get_running_loop() + yield + except RuntimeError: + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + try: + yield + finally: + loop.close() + asyncio.set_event_loop(None) + + +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" + custom_endpoint = ".custom" + + assert DataSubscriptionServiceClient._get_default_mtls_endpoint(None) is None + assert ( + DataSubscriptionServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + DataSubscriptionServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + DataSubscriptionServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + DataSubscriptionServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + DataSubscriptionServiceClient._get_default_mtls_endpoint(non_googleapi) + == non_googleapi + ) + assert ( + DataSubscriptionServiceClient._get_default_mtls_endpoint(custom_endpoint) + == custom_endpoint + ) + + +def test__read_environment_variables(): + assert DataSubscriptionServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert DataSubscriptionServiceClient._read_environment_variables() == ( + True, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert DataSubscriptionServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with pytest.raises(ValueError) as excinfo: + DataSubscriptionServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + else: + assert DataSubscriptionServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert DataSubscriptionServiceClient._read_environment_variables() == ( + False, + "never", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert DataSubscriptionServiceClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert DataSubscriptionServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + DataSubscriptionServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert DataSubscriptionServiceClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test_use_client_cert_effective(): + # Test case 1: Test when `should_use_client_cert` returns True. + # We mock the `should_use_client_cert` function to simulate a scenario where + # the google-auth library supports automatic mTLS and determines that a + # client certificate should be used. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch( + "google.auth.transport.mtls.should_use_client_cert", return_value=True + ): + assert DataSubscriptionServiceClient._use_client_cert_effective() is True + + # Test case 2: Test when `should_use_client_cert` returns False. + # We mock the `should_use_client_cert` function to simulate a scenario where + # the google-auth library supports automatic mTLS and determines that a + # client certificate should NOT be used. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch( + "google.auth.transport.mtls.should_use_client_cert", return_value=False + ): + assert DataSubscriptionServiceClient._use_client_cert_effective() is False + + # Test case 3: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "true". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert DataSubscriptionServiceClient._use_client_cert_effective() is True + + # Test case 4: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "false". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"} + ): + assert DataSubscriptionServiceClient._use_client_cert_effective() is False + + # Test case 5: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "True". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "True"}): + assert DataSubscriptionServiceClient._use_client_cert_effective() is True + + # Test case 6: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "False". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "False"} + ): + assert DataSubscriptionServiceClient._use_client_cert_effective() is False + + # Test case 7: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "TRUE". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "TRUE"}): + assert DataSubscriptionServiceClient._use_client_cert_effective() is True + + # Test case 8: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "FALSE". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "FALSE"} + ): + assert DataSubscriptionServiceClient._use_client_cert_effective() is False + + # Test case 9: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not set. + # In this case, the method should return False, which is the default value. + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, clear=True): + assert DataSubscriptionServiceClient._use_client_cert_effective() is False + + # Test case 10: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value. + # The method should raise a ValueError as the environment variable must be either + # "true" or "false". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"} + ): + with pytest.raises(ValueError): + DataSubscriptionServiceClient._use_client_cert_effective() + + # Test case 11: Test when `should_use_client_cert` is available and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value. + # The method should return False as the environment variable is set to an invalid value. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"} + ): + assert DataSubscriptionServiceClient._use_client_cert_effective() is False + + # Test case 12: Test when `should_use_client_cert` is available and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is unset. Also, + # the GOOGLE_API_CONFIG environment variable is unset. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": ""}): + with mock.patch.dict(os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": ""}): + assert ( + DataSubscriptionServiceClient._use_client_cert_effective() is False + ) + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert DataSubscriptionServiceClient._get_client_cert_source(None, False) is None + assert ( + DataSubscriptionServiceClient._get_client_cert_source( + mock_provided_cert_source, False + ) + is None + ) + assert ( + DataSubscriptionServiceClient._get_client_cert_source( + mock_provided_cert_source, True + ) + == mock_provided_cert_source + ) + + 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_default_cert_source, + ): + assert ( + DataSubscriptionServiceClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + DataSubscriptionServiceClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + DataSubscriptionServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DataSubscriptionServiceClient), +) +@mock.patch.object( + DataSubscriptionServiceAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DataSubscriptionServiceAsyncClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = DataSubscriptionServiceClient._DEFAULT_UNIVERSE + default_endpoint = DataSubscriptionServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = DataSubscriptionServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + DataSubscriptionServiceClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + DataSubscriptionServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == DataSubscriptionServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + DataSubscriptionServiceClient._get_api_endpoint( + None, None, default_universe, "auto" + ) + == default_endpoint + ) + assert ( + DataSubscriptionServiceClient._get_api_endpoint( + None, None, default_universe, "always" + ) + == DataSubscriptionServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + DataSubscriptionServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == DataSubscriptionServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + DataSubscriptionServiceClient._get_api_endpoint( + None, None, mock_universe, "never" + ) + == mock_endpoint + ) + assert ( + DataSubscriptionServiceClient._get_api_endpoint( + None, None, default_universe, "never" + ) + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + DataSubscriptionServiceClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + DataSubscriptionServiceClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + DataSubscriptionServiceClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert ( + DataSubscriptionServiceClient._get_universe_domain(None, None) + == DataSubscriptionServiceClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + DataSubscriptionServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DataSubscriptionServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DataSubscriptionServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (DataSubscriptionServiceClient, "grpc"), + (DataSubscriptionServiceAsyncClient, "grpc_asyncio"), + (DataSubscriptionServiceClient, "rest"), + ], +) +def test_data_subscription_service_client_from_service_account_info( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "health.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://health.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.DataSubscriptionServiceGrpcTransport, "grpc"), + (transports.DataSubscriptionServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.DataSubscriptionServiceRestTransport, "rest"), + ], +) +def test_data_subscription_service_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (DataSubscriptionServiceClient, "grpc"), + (DataSubscriptionServiceAsyncClient, "grpc_asyncio"), + (DataSubscriptionServiceClient, "rest"), + ], +) +def test_data_subscription_service_client_from_service_account_file( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "health.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://health.googleapis.com" + ) + + +def test_data_subscription_service_client_get_transport_class(): + transport = DataSubscriptionServiceClient.get_transport_class() + available_transports = [ + transports.DataSubscriptionServiceGrpcTransport, + transports.DataSubscriptionServiceRestTransport, + ] + assert transport in available_transports + + transport = DataSubscriptionServiceClient.get_transport_class("grpc") + assert transport == transports.DataSubscriptionServiceGrpcTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + DataSubscriptionServiceClient, + transports.DataSubscriptionServiceGrpcTransport, + "grpc", + ), + ( + DataSubscriptionServiceAsyncClient, + transports.DataSubscriptionServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ( + DataSubscriptionServiceClient, + transports.DataSubscriptionServiceRestTransport, + "rest", + ), + ], +) +@mock.patch.object( + DataSubscriptionServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DataSubscriptionServiceClient), +) +@mock.patch.object( + DataSubscriptionServiceAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DataSubscriptionServiceAsyncClient), +) +def test_data_subscription_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(DataSubscriptionServiceClient, "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(DataSubscriptionServiceClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # 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_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + DataSubscriptionServiceClient, + transports.DataSubscriptionServiceGrpcTransport, + "grpc", + "true", + ), + ( + DataSubscriptionServiceAsyncClient, + transports.DataSubscriptionServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + ( + DataSubscriptionServiceClient, + transports.DataSubscriptionServiceGrpcTransport, + "grpc", + "false", + ), + ( + DataSubscriptionServiceAsyncClient, + transports.DataSubscriptionServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + ( + DataSubscriptionServiceClient, + transports.DataSubscriptionServiceRestTransport, + "rest", + "true", + ), + ( + DataSubscriptionServiceClient, + transports.DataSubscriptionServiceRestTransport, + "rest", + "false", + ), + ], +) +@mock.patch.object( + DataSubscriptionServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DataSubscriptionServiceClient), +) +@mock.patch.object( + DataSubscriptionServiceAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DataSubscriptionServiceAsyncClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_data_subscription_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_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class", [DataSubscriptionServiceClient, DataSubscriptionServiceAsyncClient] +) +@mock.patch.object( + DataSubscriptionServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(DataSubscriptionServiceClient), +) +@mock.patch.object( + DataSubscriptionServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(DataSubscriptionServiceAsyncClient), +) +def test_data_subscription_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_CLIENT_CERTIFICATE is "Unsupported". + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + 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 cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset. + test_cases = [ + ( + # With workloads present in config, mTLS is enabled. + { + "version": 1, + "cert_configs": { + "workload": { + "cert_path": "path/to/cert/file", + "key_path": "path/to/key/file", + } + }, + }, + mock_client_cert_source, + ), + ( + # With workloads not present in config, mTLS is disabled. + { + "version": 1, + "cert_configs": {}, + }, + None, + ), + ] + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + for config_data, expected_cert_source in test_cases: + env = os.environ.copy() + env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", None) + with mock.patch.dict(os.environ, env, clear=True): + config_filename = "mock_certificate_config.json" + config_file_content = json.dumps(config_data) + m = mock.mock_open(read_data=config_file_content) + with mock.patch("builtins.open", m): + with mock.patch.dict( + os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename} + ): + 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 expected_cert_source + + # Test cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset(empty). + test_cases = [ + ( + # With workloads present in config, mTLS is enabled. + { + "version": 1, + "cert_configs": { + "workload": { + "cert_path": "path/to/cert/file", + "key_path": "path/to/key/file", + } + }, + }, + mock_client_cert_source, + ), + ( + # With workloads not present in config, mTLS is disabled. + { + "version": 1, + "cert_configs": {}, + }, + None, + ), + ] + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + for config_data, expected_cert_source in test_cases: + env = os.environ.copy() + env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", "") + with mock.patch.dict(os.environ, env, clear=True): + config_filename = "mock_certificate_config.json" + config_file_content = json.dumps(config_data) + m = mock.mock_open(read_data=config_file_content) + with mock.patch("builtins.open", m): + with mock.patch.dict( + os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename} + ): + 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 expected_cert_source + + # 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 + + # 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) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + +@pytest.mark.parametrize( + "client_class", [DataSubscriptionServiceClient, DataSubscriptionServiceAsyncClient] +) +@mock.patch.object( + DataSubscriptionServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DataSubscriptionServiceClient), +) +@mock.patch.object( + DataSubscriptionServiceAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DataSubscriptionServiceAsyncClient), +) +def test_data_subscription_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = DataSubscriptionServiceClient._DEFAULT_UNIVERSE + default_endpoint = DataSubscriptionServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = DataSubscriptionServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + DataSubscriptionServiceClient, + transports.DataSubscriptionServiceGrpcTransport, + "grpc", + ), + ( + DataSubscriptionServiceAsyncClient, + transports.DataSubscriptionServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ( + DataSubscriptionServiceClient, + transports.DataSubscriptionServiceRestTransport, + "rest", + ), + ], +) +def test_data_subscription_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_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + DataSubscriptionServiceClient, + transports.DataSubscriptionServiceGrpcTransport, + "grpc", + grpc_helpers, + ), + ( + DataSubscriptionServiceAsyncClient, + transports.DataSubscriptionServiceGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + ( + DataSubscriptionServiceClient, + transports.DataSubscriptionServiceRestTransport, + "rest", + None, + ), + ], +) +def test_data_subscription_service_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_data_subscription_service_client_client_options_from_dict(): + with mock.patch( + "google.devicesandservices.health_v4.services.data_subscription_service.transports.DataSubscriptionServiceGrpcTransport.__init__" + ) as grpc_transport: + grpc_transport.return_value = None + client = DataSubscriptionServiceClient( + client_options={"api_endpoint": "squid.clam.whelk"} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + DataSubscriptionServiceClient, + transports.DataSubscriptionServiceGrpcTransport, + "grpc", + grpc_helpers, + ), + ( + DataSubscriptionServiceAsyncClient, + transports.DataSubscriptionServiceGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + ], +) +def test_data_subscription_service_client_create_channel_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # test that the credentials from file are saved and used as the credentials. + with ( + mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, + mock.patch.object(google.auth, "default", autospec=True) as adc, + mock.patch.object(grpc_helpers, "create_channel") as create_channel, + ): + creds = ga_credentials.AnonymousCredentials() + file_creds = ga_credentials.AnonymousCredentials() + load_creds.return_value = (file_creds, None) + adc.return_value = (creds, None) + client = client_class(client_options=options, transport=transport_name) + create_channel.assert_called_with( + "health.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + scopes=None, + default_host="health.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "request_type", + [ + data_subscription_service.CreateSubscriberRequest(), + {}, + ], +) +def test_create_subscriber(request_type, transport: str = "grpc"): + client = DataSubscriptionServiceClient( + 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_subscriber), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.create_subscriber(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = data_subscription_service.CreateSubscriberRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_create_subscriber_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = data_subscription_service.CreateSubscriberRequest( + parent="parent_value", + subscriber_id="subscriber_id_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_subscriber), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.create_subscriber(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.CreateSubscriberRequest( + parent="parent_value", + subscriber_id="subscriber_id_value", + ) + assert args[0] == request_msg + + +def test_create_subscriber_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.create_subscriber in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.create_subscriber] = ( + mock_rpc + ) + request = {} + client.create_subscriber(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.create_subscriber(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_create_subscriber_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.create_subscriber + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.create_subscriber + ] = mock_rpc + + request = {} + await client.create_subscriber(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + await client.create_subscriber(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + data_subscription_service.CreateSubscriberRequest(), + {}, + ], +) +async def test_create_subscriber_async(request_type, transport: str = "grpc_asyncio"): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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_subscriber), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + response = await client.create_subscriber(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = data_subscription_service.CreateSubscriberRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_create_subscriber_field_headers(): + client = DataSubscriptionServiceClient( + 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 = data_subscription_service.CreateSubscriberRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_subscriber), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_subscriber(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_subscriber_field_headers_async(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = data_subscription_service.CreateSubscriberRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_subscriber), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.create_subscriber(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_subscriber_flattened(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_subscriber), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_subscriber( + parent="parent_value", + subscriber=data_subscription_service.CreateSubscriberPayload( + endpoint_uri="endpoint_uri_value" + ), + subscriber_id="subscriber_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].subscriber + mock_val = data_subscription_service.CreateSubscriberPayload( + endpoint_uri="endpoint_uri_value" + ) + assert arg == mock_val + arg = args[0].subscriber_id + mock_val = "subscriber_id_value" + assert arg == mock_val + + +def test_create_subscriber_flattened_error(): + client = DataSubscriptionServiceClient( + 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_subscriber( + data_subscription_service.CreateSubscriberRequest(), + parent="parent_value", + subscriber=data_subscription_service.CreateSubscriberPayload( + endpoint_uri="endpoint_uri_value" + ), + subscriber_id="subscriber_id_value", + ) + + +@pytest.mark.asyncio +async def test_create_subscriber_flattened_async(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_subscriber), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_subscriber( + parent="parent_value", + subscriber=data_subscription_service.CreateSubscriberPayload( + endpoint_uri="endpoint_uri_value" + ), + subscriber_id="subscriber_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].subscriber + mock_val = data_subscription_service.CreateSubscriberPayload( + endpoint_uri="endpoint_uri_value" + ) + assert arg == mock_val + arg = args[0].subscriber_id + mock_val = "subscriber_id_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_create_subscriber_flattened_error_async(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_subscriber( + data_subscription_service.CreateSubscriberRequest(), + parent="parent_value", + subscriber=data_subscription_service.CreateSubscriberPayload( + endpoint_uri="endpoint_uri_value" + ), + subscriber_id="subscriber_id_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + data_subscription_service.ListSubscribersRequest(), + {}, + ], +) +def test_list_subscribers(request_type, transport: str = "grpc"): + client = DataSubscriptionServiceClient( + 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_subscribers), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = data_subscription_service.ListSubscribersResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + response = client.list_subscribers(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = data_subscription_service.ListSubscribersRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListSubscribersPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +def test_list_subscribers_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = data_subscription_service.ListSubscribersRequest( + parent="parent_value", + page_token="page_token_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_subscribers), "__call__") as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.list_subscribers(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.ListSubscribersRequest( + parent="parent_value", + page_token="page_token_value", + ) + assert args[0] == request_msg + + +def test_list_subscribers_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.list_subscribers in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.list_subscribers] = ( + mock_rpc + ) + request = {} + client.list_subscribers(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_subscribers(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_list_subscribers_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.list_subscribers + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.list_subscribers + ] = mock_rpc + + request = {} + await client.list_subscribers(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.list_subscribers(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + data_subscription_service.ListSubscribersRequest(), + {}, + ], +) +async def test_list_subscribers_async(request_type, transport: str = "grpc_asyncio"): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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_subscribers), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_subscription_service.ListSubscribersResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + ) + response = await client.list_subscribers(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = data_subscription_service.ListSubscribersRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListSubscribersAsyncPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +def test_list_subscribers_field_headers(): + client = DataSubscriptionServiceClient( + 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 = data_subscription_service.ListSubscribersRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_subscribers), "__call__") as call: + call.return_value = data_subscription_service.ListSubscribersResponse() + client.list_subscribers(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_subscribers_field_headers_async(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = data_subscription_service.ListSubscribersRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_subscribers), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_subscription_service.ListSubscribersResponse() + ) + await client.list_subscribers(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_subscribers_flattened(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_subscribers), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = data_subscription_service.ListSubscribersResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_subscribers( + 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_subscribers_flattened_error(): + client = DataSubscriptionServiceClient( + 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_subscribers( + data_subscription_service.ListSubscribersRequest(), + parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_list_subscribers_flattened_async(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_subscribers), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = data_subscription_service.ListSubscribersResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_subscription_service.ListSubscribersResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_subscribers( + 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_subscribers_flattened_error_async(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_subscribers( + data_subscription_service.ListSubscribersRequest(), + parent="parent_value", + ) + + +def test_list_subscribers_pager(transport_name: str = "grpc"): + client = DataSubscriptionServiceClient( + 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_subscribers), "__call__") as call: + # Set the response to a series of pages. + call.side_effect = ( + data_subscription_service.ListSubscribersResponse( + subscribers=[ + data_subscription_service.Subscriber(), + data_subscription_service.Subscriber(), + data_subscription_service.Subscriber(), + ], + next_page_token="abc", + ), + data_subscription_service.ListSubscribersResponse( + subscribers=[], + next_page_token="def", + ), + data_subscription_service.ListSubscribersResponse( + subscribers=[ + data_subscription_service.Subscriber(), + ], + next_page_token="ghi", + ), + data_subscription_service.ListSubscribersResponse( + subscribers=[ + data_subscription_service.Subscriber(), + data_subscription_service.Subscriber(), + ], + ), + RuntimeError, + ) + + expected_metadata = () + retry = retries.Retry() + timeout = 5 + expected_metadata = tuple(expected_metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_subscribers(request={}, retry=retry, timeout=timeout) + + assert pager._metadata == expected_metadata + assert pager._retry == retry + assert pager._timeout == timeout + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, data_subscription_service.Subscriber) for i in results) + + +def test_list_subscribers_pages(transport_name: str = "grpc"): + client = DataSubscriptionServiceClient( + 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_subscribers), "__call__") as call: + # Set the response to a series of pages. + call.side_effect = ( + data_subscription_service.ListSubscribersResponse( + subscribers=[ + data_subscription_service.Subscriber(), + data_subscription_service.Subscriber(), + data_subscription_service.Subscriber(), + ], + next_page_token="abc", + ), + data_subscription_service.ListSubscribersResponse( + subscribers=[], + next_page_token="def", + ), + data_subscription_service.ListSubscribersResponse( + subscribers=[ + data_subscription_service.Subscriber(), + ], + next_page_token="ghi", + ), + data_subscription_service.ListSubscribersResponse( + subscribers=[ + data_subscription_service.Subscriber(), + data_subscription_service.Subscriber(), + ], + ), + RuntimeError, + ) + pages = list(client.list_subscribers(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_subscribers_async_pager(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_subscribers), "__call__", new_callable=mock.AsyncMock + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + data_subscription_service.ListSubscribersResponse( + subscribers=[ + data_subscription_service.Subscriber(), + data_subscription_service.Subscriber(), + data_subscription_service.Subscriber(), + ], + next_page_token="abc", + ), + data_subscription_service.ListSubscribersResponse( + subscribers=[], + next_page_token="def", + ), + data_subscription_service.ListSubscribersResponse( + subscribers=[ + data_subscription_service.Subscriber(), + ], + next_page_token="ghi", + ), + data_subscription_service.ListSubscribersResponse( + subscribers=[ + data_subscription_service.Subscriber(), + data_subscription_service.Subscriber(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_subscribers( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all( + isinstance(i, data_subscription_service.Subscriber) for i in responses + ) + + +@pytest.mark.asyncio +async def test_list_subscribers_async_pages(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_subscribers), "__call__", new_callable=mock.AsyncMock + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + data_subscription_service.ListSubscribersResponse( + subscribers=[ + data_subscription_service.Subscriber(), + data_subscription_service.Subscriber(), + data_subscription_service.Subscriber(), + ], + next_page_token="abc", + ), + data_subscription_service.ListSubscribersResponse( + subscribers=[], + next_page_token="def", + ), + data_subscription_service.ListSubscribersResponse( + subscribers=[ + data_subscription_service.Subscriber(), + ], + next_page_token="ghi", + ), + data_subscription_service.ListSubscribersResponse( + subscribers=[ + data_subscription_service.Subscriber(), + data_subscription_service.Subscriber(), + ], + ), + RuntimeError, + ) + pages = [] + async for page_ in (await client.list_subscribers(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", + [ + data_subscription_service.UpdateSubscriberRequest(), + {}, + ], +) +def test_update_subscriber(request_type, transport: str = "grpc"): + client = DataSubscriptionServiceClient( + 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_subscriber), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.update_subscriber(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = data_subscription_service.UpdateSubscriberRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_update_subscriber_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = data_subscription_service.UpdateSubscriberRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_subscriber), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.update_subscriber(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.UpdateSubscriberRequest() + assert args[0] == request_msg + + +def test_update_subscriber_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.update_subscriber in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.update_subscriber] = ( + mock_rpc + ) + request = {} + client.update_subscriber(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.update_subscriber(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_update_subscriber_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.update_subscriber + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.update_subscriber + ] = mock_rpc + + request = {} + await client.update_subscriber(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + await client.update_subscriber(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + data_subscription_service.UpdateSubscriberRequest(), + {}, + ], +) +async def test_update_subscriber_async(request_type, transport: str = "grpc_asyncio"): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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_subscriber), "__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.update_subscriber(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = data_subscription_service.UpdateSubscriberRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_update_subscriber_field_headers(): + client = DataSubscriptionServiceClient( + 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 = data_subscription_service.UpdateSubscriberRequest() + + request.subscriber.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_subscriber), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.update_subscriber(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", + "subscriber.name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_update_subscriber_field_headers_async(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = data_subscription_service.UpdateSubscriberRequest() + + request.subscriber.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_subscriber), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.update_subscriber(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", + "subscriber.name=name_value", + ) in kw["metadata"] + + +def test_update_subscriber_flattened(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_subscriber), "__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.update_subscriber( + subscriber=data_subscription_service.Subscriber(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].subscriber + mock_val = data_subscription_service.Subscriber(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_subscriber_flattened_error(): + client = DataSubscriptionServiceClient( + 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_subscriber( + data_subscription_service.UpdateSubscriberRequest(), + subscriber=data_subscription_service.Subscriber(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.asyncio +async def test_update_subscriber_flattened_async(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_subscriber), "__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.update_subscriber( + subscriber=data_subscription_service.Subscriber(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].subscriber + mock_val = data_subscription_service.Subscriber(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_subscriber_flattened_error_async(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_subscriber( + data_subscription_service.UpdateSubscriberRequest(), + subscriber=data_subscription_service.Subscriber(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.parametrize( + "request_type", + [ + data_subscription_service.DeleteSubscriberRequest(), + {}, + ], +) +def test_delete_subscriber(request_type, transport: str = "grpc"): + client = DataSubscriptionServiceClient( + 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_subscriber), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.delete_subscriber(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = data_subscription_service.DeleteSubscriberRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_delete_subscriber_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = data_subscription_service.DeleteSubscriberRequest( + name="name_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_subscriber), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.delete_subscriber(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.DeleteSubscriberRequest( + name="name_value", + ) + assert args[0] == request_msg + + +def test_delete_subscriber_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.delete_subscriber in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.delete_subscriber] = ( + mock_rpc + ) + request = {} + client.delete_subscriber(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_subscriber(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_delete_subscriber_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.delete_subscriber + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.delete_subscriber + ] = mock_rpc + + request = {} + await client.delete_subscriber(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + await client.delete_subscriber(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + data_subscription_service.DeleteSubscriberRequest(), + {}, + ], +) +async def test_delete_subscriber_async(request_type, transport: str = "grpc_asyncio"): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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_subscriber), "__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.delete_subscriber(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = data_subscription_service.DeleteSubscriberRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_delete_subscriber_field_headers(): + client = DataSubscriptionServiceClient( + 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 = data_subscription_service.DeleteSubscriberRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_subscriber), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_subscriber(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_subscriber_field_headers_async(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = data_subscription_service.DeleteSubscriberRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_subscriber), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.delete_subscriber(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_subscriber_flattened(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_subscriber), "__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.delete_subscriber( + 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_subscriber_flattened_error(): + client = DataSubscriptionServiceClient( + 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_subscriber( + data_subscription_service.DeleteSubscriberRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_delete_subscriber_flattened_async(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_subscriber), "__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.delete_subscriber( + 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_subscriber_flattened_error_async(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_subscriber( + data_subscription_service.DeleteSubscriberRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + data_subscription_service.CreateSubscriptionRequest(), + {}, + ], +) +def test_create_subscription(request_type, transport: str = "grpc"): + client = DataSubscriptionServiceClient( + 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_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = data_subscription_service.Subscription( + name="name_value", + data_types=["data_types_value"], + user="user_value", + ) + response = client.create_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = data_subscription_service.CreateSubscriptionRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, data_subscription_service.Subscription) + assert response.name == "name_value" + assert response.data_types == ["data_types_value"] + assert response.user == "user_value" + + +def test_create_subscription_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = data_subscription_service.CreateSubscriptionRequest( + parent="parent_value", + subscription_id="subscription_id_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_subscription), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.create_subscription(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.CreateSubscriptionRequest( + parent="parent_value", + subscription_id="subscription_id_value", + ) + assert args[0] == request_msg + + +def test_create_subscription_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.create_subscription in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.create_subscription] = ( + mock_rpc + ) + request = {} + client.create_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.create_subscription(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_create_subscription_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.create_subscription + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.create_subscription + ] = mock_rpc + + request = {} + await client.create_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.create_subscription(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + data_subscription_service.CreateSubscriptionRequest(), + {}, + ], +) +async def test_create_subscription_async(request_type, transport: str = "grpc_asyncio"): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_subscription_service.Subscription( + name="name_value", + data_types=["data_types_value"], + user="user_value", + ) + ) + response = await client.create_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = data_subscription_service.CreateSubscriptionRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, data_subscription_service.Subscription) + assert response.name == "name_value" + assert response.data_types == ["data_types_value"] + assert response.user == "user_value" + + +def test_create_subscription_field_headers(): + client = DataSubscriptionServiceClient( + 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 = data_subscription_service.CreateSubscriptionRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_subscription), "__call__" + ) as call: + call.return_value = data_subscription_service.Subscription() + client.create_subscription(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_subscription_field_headers_async(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = data_subscription_service.CreateSubscriptionRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_subscription), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_subscription_service.Subscription() + ) + await client.create_subscription(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_subscription_flattened(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = data_subscription_service.Subscription() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_subscription( + parent="parent_value", + subscription=data_subscription_service.CreateSubscriptionPayload( + data_types=["data_types_value"] + ), + subscription_id="subscription_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].subscription + mock_val = data_subscription_service.CreateSubscriptionPayload( + data_types=["data_types_value"] + ) + assert arg == mock_val + arg = args[0].subscription_id + mock_val = "subscription_id_value" + assert arg == mock_val + + +def test_create_subscription_flattened_error(): + client = DataSubscriptionServiceClient( + 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_subscription( + data_subscription_service.CreateSubscriptionRequest(), + parent="parent_value", + subscription=data_subscription_service.CreateSubscriptionPayload( + data_types=["data_types_value"] + ), + subscription_id="subscription_id_value", + ) + + +@pytest.mark.asyncio +async def test_create_subscription_flattened_async(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = data_subscription_service.Subscription() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_subscription_service.Subscription() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_subscription( + parent="parent_value", + subscription=data_subscription_service.CreateSubscriptionPayload( + data_types=["data_types_value"] + ), + subscription_id="subscription_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].subscription + mock_val = data_subscription_service.CreateSubscriptionPayload( + data_types=["data_types_value"] + ) + assert arg == mock_val + arg = args[0].subscription_id + mock_val = "subscription_id_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_create_subscription_flattened_error_async(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_subscription( + data_subscription_service.CreateSubscriptionRequest(), + parent="parent_value", + subscription=data_subscription_service.CreateSubscriptionPayload( + data_types=["data_types_value"] + ), + subscription_id="subscription_id_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + data_subscription_service.ListSubscriptionsRequest(), + {}, + ], +) +def test_list_subscriptions(request_type, transport: str = "grpc"): + client = DataSubscriptionServiceClient( + 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_subscriptions), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = data_subscription_service.ListSubscriptionsResponse( + next_page_token="next_page_token_value", + ) + response = client.list_subscriptions(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = data_subscription_service.ListSubscriptionsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListSubscriptionsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_subscriptions_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = data_subscription_service.ListSubscriptionsRequest( + parent="parent_value", + filter="filter_value", + page_token="page_token_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_subscriptions), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.list_subscriptions(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.ListSubscriptionsRequest( + parent="parent_value", + filter="filter_value", + page_token="page_token_value", + ) + assert args[0] == request_msg + + +def test_list_subscriptions_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_subscriptions in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.list_subscriptions] = ( + mock_rpc + ) + request = {} + client.list_subscriptions(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_subscriptions(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_list_subscriptions_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.list_subscriptions + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.list_subscriptions + ] = mock_rpc + + request = {} + await client.list_subscriptions(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.list_subscriptions(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + data_subscription_service.ListSubscriptionsRequest(), + {}, + ], +) +async def test_list_subscriptions_async(request_type, transport: str = "grpc_asyncio"): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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_subscriptions), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_subscription_service.ListSubscriptionsResponse( + next_page_token="next_page_token_value", + ) + ) + response = await client.list_subscriptions(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = data_subscription_service.ListSubscriptionsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListSubscriptionsAsyncPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_subscriptions_field_headers(): + client = DataSubscriptionServiceClient( + 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 = data_subscription_service.ListSubscriptionsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_subscriptions), "__call__" + ) as call: + call.return_value = data_subscription_service.ListSubscriptionsResponse() + client.list_subscriptions(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_subscriptions_field_headers_async(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = data_subscription_service.ListSubscriptionsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_subscriptions), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_subscription_service.ListSubscriptionsResponse() + ) + await client.list_subscriptions(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_subscriptions_flattened(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_subscriptions), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = data_subscription_service.ListSubscriptionsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_subscriptions( + 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_subscriptions_flattened_error(): + client = DataSubscriptionServiceClient( + 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_subscriptions( + data_subscription_service.ListSubscriptionsRequest(), + parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_list_subscriptions_flattened_async(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_subscriptions), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = data_subscription_service.ListSubscriptionsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_subscription_service.ListSubscriptionsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_subscriptions( + 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_subscriptions_flattened_error_async(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_subscriptions( + data_subscription_service.ListSubscriptionsRequest(), + parent="parent_value", + ) + + +def test_list_subscriptions_pager(transport_name: str = "grpc"): + client = DataSubscriptionServiceClient( + 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_subscriptions), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + data_subscription_service.ListSubscriptionsResponse( + subscriptions=[ + data_subscription_service.Subscription(), + data_subscription_service.Subscription(), + data_subscription_service.Subscription(), + ], + next_page_token="abc", + ), + data_subscription_service.ListSubscriptionsResponse( + subscriptions=[], + next_page_token="def", + ), + data_subscription_service.ListSubscriptionsResponse( + subscriptions=[ + data_subscription_service.Subscription(), + ], + next_page_token="ghi", + ), + data_subscription_service.ListSubscriptionsResponse( + subscriptions=[ + data_subscription_service.Subscription(), + data_subscription_service.Subscription(), + ], + ), + RuntimeError, + ) + + expected_metadata = () + retry = retries.Retry() + timeout = 5 + expected_metadata = tuple(expected_metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_subscriptions(request={}, retry=retry, timeout=timeout) + + assert pager._metadata == expected_metadata + assert pager._retry == retry + assert pager._timeout == timeout + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, data_subscription_service.Subscription) for i in results + ) + + +def test_list_subscriptions_pages(transport_name: str = "grpc"): + client = DataSubscriptionServiceClient( + 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_subscriptions), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + data_subscription_service.ListSubscriptionsResponse( + subscriptions=[ + data_subscription_service.Subscription(), + data_subscription_service.Subscription(), + data_subscription_service.Subscription(), + ], + next_page_token="abc", + ), + data_subscription_service.ListSubscriptionsResponse( + subscriptions=[], + next_page_token="def", + ), + data_subscription_service.ListSubscriptionsResponse( + subscriptions=[ + data_subscription_service.Subscription(), + ], + next_page_token="ghi", + ), + data_subscription_service.ListSubscriptionsResponse( + subscriptions=[ + data_subscription_service.Subscription(), + data_subscription_service.Subscription(), + ], + ), + RuntimeError, + ) + pages = list(client.list_subscriptions(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_subscriptions_async_pager(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_subscriptions), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + data_subscription_service.ListSubscriptionsResponse( + subscriptions=[ + data_subscription_service.Subscription(), + data_subscription_service.Subscription(), + data_subscription_service.Subscription(), + ], + next_page_token="abc", + ), + data_subscription_service.ListSubscriptionsResponse( + subscriptions=[], + next_page_token="def", + ), + data_subscription_service.ListSubscriptionsResponse( + subscriptions=[ + data_subscription_service.Subscription(), + ], + next_page_token="ghi", + ), + data_subscription_service.ListSubscriptionsResponse( + subscriptions=[ + data_subscription_service.Subscription(), + data_subscription_service.Subscription(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_subscriptions( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all( + isinstance(i, data_subscription_service.Subscription) for i in responses + ) + + +@pytest.mark.asyncio +async def test_list_subscriptions_async_pages(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_subscriptions), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + data_subscription_service.ListSubscriptionsResponse( + subscriptions=[ + data_subscription_service.Subscription(), + data_subscription_service.Subscription(), + data_subscription_service.Subscription(), + ], + next_page_token="abc", + ), + data_subscription_service.ListSubscriptionsResponse( + subscriptions=[], + next_page_token="def", + ), + data_subscription_service.ListSubscriptionsResponse( + subscriptions=[ + data_subscription_service.Subscription(), + ], + next_page_token="ghi", + ), + data_subscription_service.ListSubscriptionsResponse( + subscriptions=[ + data_subscription_service.Subscription(), + data_subscription_service.Subscription(), + ], + ), + RuntimeError, + ) + pages = [] + async for page_ in (await client.list_subscriptions(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", + [ + data_subscription_service.UpdateSubscriptionRequest(), + {}, + ], +) +def test_update_subscription(request_type, transport: str = "grpc"): + client = DataSubscriptionServiceClient( + 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_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = data_subscription_service.Subscription( + name="name_value", + data_types=["data_types_value"], + user="user_value", + ) + response = client.update_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = data_subscription_service.UpdateSubscriptionRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, data_subscription_service.Subscription) + assert response.name == "name_value" + assert response.data_types == ["data_types_value"] + assert response.user == "user_value" + + +def test_update_subscription_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = data_subscription_service.UpdateSubscriptionRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_subscription), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.update_subscription(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.UpdateSubscriptionRequest() + assert args[0] == request_msg + + +def test_update_subscription_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.update_subscription in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.update_subscription] = ( + mock_rpc + ) + request = {} + client.update_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.update_subscription(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_update_subscription_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.update_subscription + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.update_subscription + ] = mock_rpc + + request = {} + await client.update_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.update_subscription(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + data_subscription_service.UpdateSubscriptionRequest(), + {}, + ], +) +async def test_update_subscription_async(request_type, transport: str = "grpc_asyncio"): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_subscription_service.Subscription( + name="name_value", + data_types=["data_types_value"], + user="user_value", + ) + ) + response = await client.update_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = data_subscription_service.UpdateSubscriptionRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, data_subscription_service.Subscription) + assert response.name == "name_value" + assert response.data_types == ["data_types_value"] + assert response.user == "user_value" + + +def test_update_subscription_field_headers(): + client = DataSubscriptionServiceClient( + 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 = data_subscription_service.UpdateSubscriptionRequest() + + request.subscription.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_subscription), "__call__" + ) as call: + call.return_value = data_subscription_service.Subscription() + client.update_subscription(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", + "subscription.name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_update_subscription_field_headers_async(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = data_subscription_service.UpdateSubscriptionRequest() + + request.subscription.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_subscription), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_subscription_service.Subscription() + ) + await client.update_subscription(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", + "subscription.name=name_value", + ) in kw["metadata"] + + +def test_update_subscription_flattened(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = data_subscription_service.Subscription() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_subscription( + subscription=data_subscription_service.Subscription(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].subscription + mock_val = data_subscription_service.Subscription(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_subscription_flattened_error(): + client = DataSubscriptionServiceClient( + 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_subscription( + data_subscription_service.UpdateSubscriptionRequest(), + subscription=data_subscription_service.Subscription(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.asyncio +async def test_update_subscription_flattened_async(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = data_subscription_service.Subscription() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_subscription_service.Subscription() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_subscription( + subscription=data_subscription_service.Subscription(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].subscription + mock_val = data_subscription_service.Subscription(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_subscription_flattened_error_async(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_subscription( + data_subscription_service.UpdateSubscriptionRequest(), + subscription=data_subscription_service.Subscription(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.parametrize( + "request_type", + [ + data_subscription_service.DeleteSubscriptionRequest(), + {}, + ], +) +def test_delete_subscription(request_type, transport: str = "grpc"): + client = DataSubscriptionServiceClient( + 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_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = data_subscription_service.DeleteSubscriptionRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_subscription_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = data_subscription_service.DeleteSubscriptionRequest( + name="name_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_subscription), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.delete_subscription(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.DeleteSubscriptionRequest( + name="name_value", + ) + assert args[0] == request_msg + + +def test_delete_subscription_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.delete_subscription in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.delete_subscription] = ( + mock_rpc + ) + request = {} + client.delete_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.delete_subscription(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_delete_subscription_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.delete_subscription + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.delete_subscription + ] = mock_rpc + + request = {} + await client.delete_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.delete_subscription(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + data_subscription_service.DeleteSubscriptionRequest(), + {}, + ], +) +async def test_delete_subscription_async(request_type, transport: str = "grpc_asyncio"): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = data_subscription_service.DeleteSubscriptionRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_subscription_field_headers(): + client = DataSubscriptionServiceClient( + 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 = data_subscription_service.DeleteSubscriptionRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_subscription), "__call__" + ) as call: + call.return_value = None + client.delete_subscription(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_subscription_field_headers_async(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = data_subscription_service.DeleteSubscriptionRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_subscription), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_subscription(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_subscription_flattened(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_subscription), "__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_subscription( + 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_subscription_flattened_error(): + client = DataSubscriptionServiceClient( + 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_subscription( + data_subscription_service.DeleteSubscriptionRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_delete_subscription_flattened_async(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_subscription), "__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_subscription( + 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_subscription_flattened_error_async(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_subscription( + data_subscription_service.DeleteSubscriptionRequest(), + name="name_value", + ) + + +def test_create_subscriber_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.create_subscriber in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.create_subscriber] = ( + mock_rpc + ) + + request = {} + client.create_subscriber(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.create_subscriber(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_create_subscriber_rest_required_fields( + request_type=data_subscription_service.CreateSubscriberRequest, +): + transport_class = transports.DataSubscriptionServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_subscriber._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_subscriber._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("subscriber_id",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.create_subscriber(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_create_subscriber_rest_unset_required_fields(): + transport = transports.DataSubscriptionServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.create_subscriber._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("subscriberId",)) + & set( + ( + "parent", + "subscriber", + ) + ) + ) + + +def test_create_subscriber_rest_flattened(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + subscriber=data_subscription_service.CreateSubscriberPayload( + endpoint_uri="endpoint_uri_value" + ), + subscriber_id="subscriber_id_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.create_subscriber(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v4/{parent=projects/*}/subscribers" % client.transport._host, args[1] + ) + + +def test_create_subscriber_rest_flattened_error(transport: str = "rest"): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_subscriber( + data_subscription_service.CreateSubscriberRequest(), + parent="parent_value", + subscriber=data_subscription_service.CreateSubscriberPayload( + endpoint_uri="endpoint_uri_value" + ), + subscriber_id="subscriber_id_value", + ) + + +def test_list_subscribers_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.list_subscribers in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.list_subscribers] = ( + mock_rpc + ) + + request = {} + client.list_subscribers(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_subscribers(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_subscribers_rest_required_fields( + request_type=data_subscription_service.ListSubscribersRequest, +): + transport_class = transports.DataSubscriptionServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_subscribers._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_subscribers._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = data_subscription_service.ListSubscribersResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = data_subscription_service.ListSubscribersResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_subscribers(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_list_subscribers_rest_unset_required_fields(): + transport = transports.DataSubscriptionServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_subscribers._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +def test_list_subscribers_rest_flattened(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = data_subscription_service.ListSubscribersResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = data_subscription_service.ListSubscribersResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_subscribers(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v4/{parent=projects/*}/subscribers" % client.transport._host, args[1] + ) + + +def test_list_subscribers_rest_flattened_error(transport: str = "rest"): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_subscribers( + data_subscription_service.ListSubscribersRequest(), + parent="parent_value", + ) + + +def test_list_subscribers_rest_pager(transport: str = "rest"): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + data_subscription_service.ListSubscribersResponse( + subscribers=[ + data_subscription_service.Subscriber(), + data_subscription_service.Subscriber(), + data_subscription_service.Subscriber(), + ], + next_page_token="abc", + ), + data_subscription_service.ListSubscribersResponse( + subscribers=[], + next_page_token="def", + ), + data_subscription_service.ListSubscribersResponse( + subscribers=[ + data_subscription_service.Subscriber(), + ], + next_page_token="ghi", + ), + data_subscription_service.ListSubscribersResponse( + subscribers=[ + data_subscription_service.Subscriber(), + data_subscription_service.Subscriber(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + data_subscription_service.ListSubscribersResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1"} + + pager = client.list_subscribers(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, data_subscription_service.Subscriber) for i in results) + + pages = list(client.list_subscribers(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_update_subscriber_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.update_subscriber in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.update_subscriber] = ( + mock_rpc + ) + + request = {} + client.update_subscriber(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.update_subscriber(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_update_subscriber_rest_required_fields( + request_type=data_subscription_service.UpdateSubscriberRequest, +): + transport_class = transports.DataSubscriptionServiceRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_subscriber._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_subscriber._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.update_subscriber(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_update_subscriber_rest_unset_required_fields(): + transport = transports.DataSubscriptionServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_subscriber._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("subscriber",))) + + +def test_update_subscriber_rest_flattened(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = { + "subscriber": {"name": "projects/sample1/subscribers/sample2"} + } + + # get truthy value for each flattened field + mock_args = dict( + subscriber=data_subscription_service.Subscriber(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.update_subscriber(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v4/{subscriber.name=projects/*/subscribers/*}" % client.transport._host, + args[1], + ) + + +def test_update_subscriber_rest_flattened_error(transport: str = "rest"): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_subscriber( + data_subscription_service.UpdateSubscriberRequest(), + subscriber=data_subscription_service.Subscriber(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_delete_subscriber_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.delete_subscriber in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.delete_subscriber] = ( + mock_rpc + ) + + request = {} + client.delete_subscriber(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_subscriber(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_delete_subscriber_rest_required_fields( + request_type=data_subscription_service.DeleteSubscriberRequest, +): + transport_class = transports.DataSubscriptionServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_subscriber._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_subscriber._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("force",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "delete", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.delete_subscriber(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_delete_subscriber_rest_unset_required_fields(): + transport = transports.DataSubscriptionServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.delete_subscriber._get_unset_required_fields({}) + assert set(unset_fields) == (set(("force",)) & set(("name",))) + + +def test_delete_subscriber_rest_flattened(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "projects/sample1/subscribers/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.delete_subscriber(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v4/{name=projects/*/subscribers/*}" % client.transport._host, args[1] + ) + + +def test_delete_subscriber_rest_flattened_error(transport: str = "rest"): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_subscriber( + data_subscription_service.DeleteSubscriberRequest(), + name="name_value", + ) + + +def test_create_subscription_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.create_subscription in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.create_subscription] = ( + mock_rpc + ) + + request = {} + client.create_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.create_subscription(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_create_subscription_rest_required_fields( + request_type=data_subscription_service.CreateSubscriptionRequest, +): + transport_class = transports.DataSubscriptionServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_subscription._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_subscription._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("subscription_id",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = data_subscription_service.Subscription() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = data_subscription_service.Subscription.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.create_subscription(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_create_subscription_rest_unset_required_fields(): + transport = transports.DataSubscriptionServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.create_subscription._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("subscriptionId",)) + & set( + ( + "parent", + "subscription", + ) + ) + ) + + +def test_create_subscription_rest_flattened(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = data_subscription_service.Subscription() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/subscribers/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + subscription=data_subscription_service.CreateSubscriptionPayload( + data_types=["data_types_value"] + ), + subscription_id="subscription_id_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = data_subscription_service.Subscription.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.create_subscription(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v4/{parent=projects/*/subscribers/*}/subscriptions" + % client.transport._host, + args[1], + ) + + +def test_create_subscription_rest_flattened_error(transport: str = "rest"): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_subscription( + data_subscription_service.CreateSubscriptionRequest(), + parent="parent_value", + subscription=data_subscription_service.CreateSubscriptionPayload( + data_types=["data_types_value"] + ), + subscription_id="subscription_id_value", + ) + + +def test_list_subscriptions_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_subscriptions in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.list_subscriptions] = ( + mock_rpc + ) + + request = {} + client.list_subscriptions(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_subscriptions(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_subscriptions_rest_required_fields( + request_type=data_subscription_service.ListSubscriptionsRequest, +): + transport_class = transports.DataSubscriptionServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_subscriptions._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_subscriptions._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = data_subscription_service.ListSubscriptionsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = data_subscription_service.ListSubscriptionsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_subscriptions(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_list_subscriptions_rest_unset_required_fields(): + transport = transports.DataSubscriptionServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_subscriptions._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +def test_list_subscriptions_rest_flattened(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = data_subscription_service.ListSubscriptionsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/subscribers/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = data_subscription_service.ListSubscriptionsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_subscriptions(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v4/{parent=projects/*/subscribers/*}/subscriptions" + % client.transport._host, + args[1], + ) + + +def test_list_subscriptions_rest_flattened_error(transport: str = "rest"): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_subscriptions( + data_subscription_service.ListSubscriptionsRequest(), + parent="parent_value", + ) + + +def test_list_subscriptions_rest_pager(transport: str = "rest"): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + data_subscription_service.ListSubscriptionsResponse( + subscriptions=[ + data_subscription_service.Subscription(), + data_subscription_service.Subscription(), + data_subscription_service.Subscription(), + ], + next_page_token="abc", + ), + data_subscription_service.ListSubscriptionsResponse( + subscriptions=[], + next_page_token="def", + ), + data_subscription_service.ListSubscriptionsResponse( + subscriptions=[ + data_subscription_service.Subscription(), + ], + next_page_token="ghi", + ), + data_subscription_service.ListSubscriptionsResponse( + subscriptions=[ + data_subscription_service.Subscription(), + data_subscription_service.Subscription(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + data_subscription_service.ListSubscriptionsResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/subscribers/sample2"} + + pager = client.list_subscriptions(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, data_subscription_service.Subscription) for i in results + ) + + pages = list(client.list_subscriptions(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_update_subscription_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.update_subscription in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.update_subscription] = ( + mock_rpc + ) + + request = {} + client.update_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.update_subscription(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_update_subscription_rest_required_fields( + request_type=data_subscription_service.UpdateSubscriptionRequest, +): + transport_class = transports.DataSubscriptionServiceRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_subscription._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_subscription._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = data_subscription_service.Subscription() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = data_subscription_service.Subscription.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.update_subscription(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_update_subscription_rest_unset_required_fields(): + transport = transports.DataSubscriptionServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_subscription._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("subscription",))) + + +def test_update_subscription_rest_flattened(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = data_subscription_service.Subscription() + + # get arguments that satisfy an http rule for this method + sample_request = { + "subscription": { + "name": "projects/sample1/subscribers/sample2/subscriptions/sample3" + } + } + + # get truthy value for each flattened field + mock_args = dict( + subscription=data_subscription_service.Subscription(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = data_subscription_service.Subscription.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.update_subscription(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v4/{subscription.name=projects/*/subscribers/*/subscriptions/*}" + % client.transport._host, + args[1], + ) + + +def test_update_subscription_rest_flattened_error(transport: str = "rest"): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_subscription( + data_subscription_service.UpdateSubscriptionRequest(), + subscription=data_subscription_service.Subscription(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_delete_subscription_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.delete_subscription in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.delete_subscription] = ( + mock_rpc + ) + + request = {} + client.delete_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.delete_subscription(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_delete_subscription_rest_required_fields( + request_type=data_subscription_service.DeleteSubscriptionRequest, +): + transport_class = transports.DataSubscriptionServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_subscription._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_subscription._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = None + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "delete", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.delete_subscription(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_delete_subscription_rest_unset_required_fields(): + transport = transports.DataSubscriptionServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.delete_subscription._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_delete_subscription_rest_flattened(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/subscribers/sample2/subscriptions/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.delete_subscription(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v4/{name=projects/*/subscribers/*/subscriptions/*}" + % client.transport._host, + args[1], + ) + + +def test_delete_subscription_rest_flattened_error(transport: str = "rest"): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_subscription( + data_subscription_service.DeleteSubscriptionRequest(), + name="name_value", + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.DataSubscriptionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.DataSubscriptionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = DataSubscriptionServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.DataSubscriptionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = DataSubscriptionServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = DataSubscriptionServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.DataSubscriptionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = DataSubscriptionServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.DataSubscriptionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = DataSubscriptionServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.DataSubscriptionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.DataSubscriptionServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.DataSubscriptionServiceGrpcTransport, + transports.DataSubscriptionServiceGrpcAsyncIOTransport, + transports.DataSubscriptionServiceRestTransport, + ], +) +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_kind_grpc(): + transport = DataSubscriptionServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_subscriber_empty_call_grpc(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_subscriber), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_subscriber(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.CreateSubscriberRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_subscribers_empty_call_grpc(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_subscribers), "__call__") as call: + call.return_value = data_subscription_service.ListSubscribersResponse() + client.list_subscribers(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.ListSubscribersRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_subscriber_empty_call_grpc(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_subscriber), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.update_subscriber(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.UpdateSubscriberRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_subscriber_empty_call_grpc(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_subscriber), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_subscriber(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.DeleteSubscriberRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_subscription_empty_call_grpc(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_subscription), "__call__" + ) as call: + call.return_value = data_subscription_service.Subscription() + client.create_subscription(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.CreateSubscriptionRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_subscriptions_empty_call_grpc(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_subscriptions), "__call__" + ) as call: + call.return_value = data_subscription_service.ListSubscriptionsResponse() + client.list_subscriptions(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.ListSubscriptionsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_subscription_empty_call_grpc(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_subscription), "__call__" + ) as call: + call.return_value = data_subscription_service.Subscription() + client.update_subscription(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.UpdateSubscriptionRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_subscription_empty_call_grpc(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_subscription), "__call__" + ) as call: + call.return_value = None + client.delete_subscription(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.DeleteSubscriptionRequest() + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = DataSubscriptionServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_subscriber_empty_call_grpc_asyncio(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_subscriber), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.create_subscriber(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.CreateSubscriberRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_subscribers_empty_call_grpc_asyncio(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_subscribers), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_subscription_service.ListSubscribersResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + ) + await client.list_subscribers(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.ListSubscribersRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_subscriber_empty_call_grpc_asyncio(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_subscriber), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.update_subscriber(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.UpdateSubscriberRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_subscriber_empty_call_grpc_asyncio(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_subscriber), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.delete_subscriber(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.DeleteSubscriberRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_subscription_empty_call_grpc_asyncio(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_subscription_service.Subscription( + name="name_value", + data_types=["data_types_value"], + user="user_value", + ) + ) + await client.create_subscription(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.CreateSubscriptionRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_subscriptions_empty_call_grpc_asyncio(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_subscriptions), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_subscription_service.ListSubscriptionsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_subscriptions(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.ListSubscriptionsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_subscription_empty_call_grpc_asyncio(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + data_subscription_service.Subscription( + name="name_value", + data_types=["data_types_value"], + user="user_value", + ) + ) + await client.update_subscription(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.UpdateSubscriptionRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_subscription_empty_call_grpc_asyncio(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_subscription(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.DeleteSubscriptionRequest() + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = DataSubscriptionServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_create_subscriber_rest_bad_request( + request_type=data_subscription_service.CreateSubscriberRequest, +): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.create_subscriber(request) + + +@pytest.mark.parametrize( + "request_type", + [ + data_subscription_service.CreateSubscriberRequest, + dict, + ], +) +def test_create_subscriber_rest_call_success(request_type): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1"} + request_init["subscriber"] = { + "endpoint_uri": "endpoint_uri_value", + "subscriber_configs": [ + { + "data_types": ["data_types_value1", "data_types_value2"], + "subscription_create_policy": 1, + } + ], + "endpoint_authorization": {"secret": "secret_value", "secret_set": True}, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = data_subscription_service.CreateSubscriberRequest.meta.fields[ + "subscriber" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["subscriber"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["subscriber"][field])): + del request_init["subscriber"][field][i][subfield] + else: + del request_init["subscriber"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.create_subscriber(request) + + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_subscriber_rest_interceptors(null_interceptor): + transport = transports.DataSubscriptionServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DataSubscriptionServiceRestInterceptor(), + ) + client = DataSubscriptionServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), + mock.patch.object( + transports.DataSubscriptionServiceRestInterceptor, "post_create_subscriber" + ) as post, + mock.patch.object( + transports.DataSubscriptionServiceRestInterceptor, + "post_create_subscriber_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.DataSubscriptionServiceRestInterceptor, "pre_create_subscriber" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = data_subscription_service.CreateSubscriberRequest.pb( + data_subscription_service.CreateSubscriberRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value + + request = data_subscription_service.CreateSubscriberRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata + + client.create_subscriber( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_subscribers_rest_bad_request( + request_type=data_subscription_service.ListSubscribersRequest, +): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_subscribers(request) + + +@pytest.mark.parametrize( + "request_type", + [ + data_subscription_service.ListSubscribersRequest, + dict, + ], +) +def test_list_subscribers_rest_call_success(request_type): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = data_subscription_service.ListSubscribersResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = data_subscription_service.ListSubscribersResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_subscribers(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListSubscribersPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_subscribers_rest_interceptors(null_interceptor): + transport = transports.DataSubscriptionServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DataSubscriptionServiceRestInterceptor(), + ) + client = DataSubscriptionServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.DataSubscriptionServiceRestInterceptor, "post_list_subscribers" + ) as post, + mock.patch.object( + transports.DataSubscriptionServiceRestInterceptor, + "post_list_subscribers_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.DataSubscriptionServiceRestInterceptor, "pre_list_subscribers" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = data_subscription_service.ListSubscribersRequest.pb( + data_subscription_service.ListSubscribersRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = data_subscription_service.ListSubscribersResponse.to_json( + data_subscription_service.ListSubscribersResponse() + ) + req.return_value.content = return_value + + request = data_subscription_service.ListSubscribersRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = data_subscription_service.ListSubscribersResponse() + post_with_metadata.return_value = ( + data_subscription_service.ListSubscribersResponse(), + metadata, + ) + + client.list_subscribers( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_update_subscriber_rest_bad_request( + request_type=data_subscription_service.UpdateSubscriberRequest, +): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"subscriber": {"name": "projects/sample1/subscribers/sample2"}} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.update_subscriber(request) + + +@pytest.mark.parametrize( + "request_type", + [ + data_subscription_service.UpdateSubscriberRequest, + dict, + ], +) +def test_update_subscriber_rest_call_success(request_type): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"subscriber": {"name": "projects/sample1/subscribers/sample2"}} + request_init["subscriber"] = { + "name": "projects/sample1/subscribers/sample2", + "endpoint_uri": "endpoint_uri_value", + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "subscriber_configs": [ + { + "data_types": ["data_types_value1", "data_types_value2"], + "subscription_create_policy": 1, + } + ], + "endpoint_authorization": {"secret": "secret_value", "secret_set": True}, + "state": 1, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = data_subscription_service.UpdateSubscriberRequest.meta.fields[ + "subscriber" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["subscriber"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["subscriber"][field])): + del request_init["subscriber"][field][i][subfield] + else: + del request_init["subscriber"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.update_subscriber(request) + + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_subscriber_rest_interceptors(null_interceptor): + transport = transports.DataSubscriptionServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DataSubscriptionServiceRestInterceptor(), + ) + client = DataSubscriptionServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), + mock.patch.object( + transports.DataSubscriptionServiceRestInterceptor, "post_update_subscriber" + ) as post, + mock.patch.object( + transports.DataSubscriptionServiceRestInterceptor, + "post_update_subscriber_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.DataSubscriptionServiceRestInterceptor, "pre_update_subscriber" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = data_subscription_service.UpdateSubscriberRequest.pb( + data_subscription_service.UpdateSubscriberRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value + + request = data_subscription_service.UpdateSubscriberRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata + + client.update_subscriber( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_delete_subscriber_rest_bad_request( + request_type=data_subscription_service.DeleteSubscriberRequest, +): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/subscribers/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.delete_subscriber(request) + + +@pytest.mark.parametrize( + "request_type", + [ + data_subscription_service.DeleteSubscriberRequest, + dict, + ], +) +def test_delete_subscriber_rest_call_success(request_type): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/subscribers/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.delete_subscriber(request) + + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_subscriber_rest_interceptors(null_interceptor): + transport = transports.DataSubscriptionServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DataSubscriptionServiceRestInterceptor(), + ) + client = DataSubscriptionServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), + mock.patch.object( + transports.DataSubscriptionServiceRestInterceptor, "post_delete_subscriber" + ) as post, + mock.patch.object( + transports.DataSubscriptionServiceRestInterceptor, + "post_delete_subscriber_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.DataSubscriptionServiceRestInterceptor, "pre_delete_subscriber" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = data_subscription_service.DeleteSubscriberRequest.pb( + data_subscription_service.DeleteSubscriberRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value + + request = data_subscription_service.DeleteSubscriberRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata + + client.delete_subscriber( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_create_subscription_rest_bad_request( + request_type=data_subscription_service.CreateSubscriptionRequest, +): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/subscribers/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.create_subscription(request) + + +@pytest.mark.parametrize( + "request_type", + [ + data_subscription_service.CreateSubscriptionRequest, + dict, + ], +) +def test_create_subscription_rest_call_success(request_type): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/subscribers/sample2"} + request_init["subscription"] = { + "data_types": ["data_types_value1", "data_types_value2"], + "user": "user_value", + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = data_subscription_service.CreateSubscriptionRequest.meta.fields[ + "subscription" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["subscription"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["subscription"][field])): + del request_init["subscription"][field][i][subfield] + else: + del request_init["subscription"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = data_subscription_service.Subscription( + name="name_value", + data_types=["data_types_value"], + user="user_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = data_subscription_service.Subscription.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.create_subscription(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, data_subscription_service.Subscription) + assert response.name == "name_value" + assert response.data_types == ["data_types_value"] + assert response.user == "user_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_subscription_rest_interceptors(null_interceptor): + transport = transports.DataSubscriptionServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DataSubscriptionServiceRestInterceptor(), + ) + client = DataSubscriptionServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.DataSubscriptionServiceRestInterceptor, + "post_create_subscription", + ) as post, + mock.patch.object( + transports.DataSubscriptionServiceRestInterceptor, + "post_create_subscription_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.DataSubscriptionServiceRestInterceptor, "pre_create_subscription" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = data_subscription_service.CreateSubscriptionRequest.pb( + data_subscription_service.CreateSubscriptionRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = data_subscription_service.Subscription.to_json( + data_subscription_service.Subscription() + ) + req.return_value.content = return_value + + request = data_subscription_service.CreateSubscriptionRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = data_subscription_service.Subscription() + post_with_metadata.return_value = ( + data_subscription_service.Subscription(), + metadata, + ) + + client.create_subscription( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_subscriptions_rest_bad_request( + request_type=data_subscription_service.ListSubscriptionsRequest, +): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/subscribers/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_subscriptions(request) + + +@pytest.mark.parametrize( + "request_type", + [ + data_subscription_service.ListSubscriptionsRequest, + dict, + ], +) +def test_list_subscriptions_rest_call_success(request_type): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/subscribers/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = data_subscription_service.ListSubscriptionsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = data_subscription_service.ListSubscriptionsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_subscriptions(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListSubscriptionsPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_subscriptions_rest_interceptors(null_interceptor): + transport = transports.DataSubscriptionServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DataSubscriptionServiceRestInterceptor(), + ) + client = DataSubscriptionServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.DataSubscriptionServiceRestInterceptor, "post_list_subscriptions" + ) as post, + mock.patch.object( + transports.DataSubscriptionServiceRestInterceptor, + "post_list_subscriptions_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.DataSubscriptionServiceRestInterceptor, "pre_list_subscriptions" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = data_subscription_service.ListSubscriptionsRequest.pb( + data_subscription_service.ListSubscriptionsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = data_subscription_service.ListSubscriptionsResponse.to_json( + data_subscription_service.ListSubscriptionsResponse() + ) + req.return_value.content = return_value + + request = data_subscription_service.ListSubscriptionsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = data_subscription_service.ListSubscriptionsResponse() + post_with_metadata.return_value = ( + data_subscription_service.ListSubscriptionsResponse(), + metadata, + ) + + client.list_subscriptions( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_update_subscription_rest_bad_request( + request_type=data_subscription_service.UpdateSubscriptionRequest, +): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "subscription": { + "name": "projects/sample1/subscribers/sample2/subscriptions/sample3" + } + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.update_subscription(request) + + +@pytest.mark.parametrize( + "request_type", + [ + data_subscription_service.UpdateSubscriptionRequest, + dict, + ], +) +def test_update_subscription_rest_call_success(request_type): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "subscription": { + "name": "projects/sample1/subscribers/sample2/subscriptions/sample3" + } + } + request_init["subscription"] = { + "name": "projects/sample1/subscribers/sample2/subscriptions/sample3", + "data_types": ["data_types_value1", "data_types_value2"], + "user": "user_value", + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = data_subscription_service.UpdateSubscriptionRequest.meta.fields[ + "subscription" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["subscription"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["subscription"][field])): + del request_init["subscription"][field][i][subfield] + else: + del request_init["subscription"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = data_subscription_service.Subscription( + name="name_value", + data_types=["data_types_value"], + user="user_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = data_subscription_service.Subscription.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.update_subscription(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, data_subscription_service.Subscription) + assert response.name == "name_value" + assert response.data_types == ["data_types_value"] + assert response.user == "user_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_subscription_rest_interceptors(null_interceptor): + transport = transports.DataSubscriptionServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DataSubscriptionServiceRestInterceptor(), + ) + client = DataSubscriptionServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.DataSubscriptionServiceRestInterceptor, + "post_update_subscription", + ) as post, + mock.patch.object( + transports.DataSubscriptionServiceRestInterceptor, + "post_update_subscription_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.DataSubscriptionServiceRestInterceptor, "pre_update_subscription" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = data_subscription_service.UpdateSubscriptionRequest.pb( + data_subscription_service.UpdateSubscriptionRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = data_subscription_service.Subscription.to_json( + data_subscription_service.Subscription() + ) + req.return_value.content = return_value + + request = data_subscription_service.UpdateSubscriptionRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = data_subscription_service.Subscription() + post_with_metadata.return_value = ( + data_subscription_service.Subscription(), + metadata, + ) + + client.update_subscription( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_delete_subscription_rest_bad_request( + request_type=data_subscription_service.DeleteSubscriptionRequest, +): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/subscribers/sample2/subscriptions/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.delete_subscription(request) + + +@pytest.mark.parametrize( + "request_type", + [ + data_subscription_service.DeleteSubscriptionRequest, + dict, + ], +) +def test_delete_subscription_rest_call_success(request_type): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/subscribers/sample2/subscriptions/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = "" + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.delete_subscription(request) + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_subscription_rest_interceptors(null_interceptor): + transport = transports.DataSubscriptionServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DataSubscriptionServiceRestInterceptor(), + ) + client = DataSubscriptionServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.DataSubscriptionServiceRestInterceptor, "pre_delete_subscription" + ) as pre, + ): + pre.assert_not_called() + pb_message = data_subscription_service.DeleteSubscriptionRequest.pb( + data_subscription_service.DeleteSubscriptionRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + request = data_subscription_service.DeleteSubscriptionRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_subscription( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + + +def test_initialize_client_w_rest(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_subscriber_empty_call_rest(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_subscriber), "__call__" + ) as call: + client.create_subscriber(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.CreateSubscriberRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_subscribers_empty_call_rest(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_subscribers), "__call__") as call: + client.list_subscribers(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.ListSubscribersRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_subscriber_empty_call_rest(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_subscriber), "__call__" + ) as call: + client.update_subscriber(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.UpdateSubscriberRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_subscriber_empty_call_rest(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_subscriber), "__call__" + ) as call: + client.delete_subscriber(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.DeleteSubscriberRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_subscription_empty_call_rest(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_subscription), "__call__" + ) as call: + client.create_subscription(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.CreateSubscriptionRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_subscriptions_empty_call_rest(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_subscriptions), "__call__" + ) as call: + client.list_subscriptions(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.ListSubscriptionsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_subscription_empty_call_rest(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_subscription), "__call__" + ) as call: + client.update_subscription(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.UpdateSubscriptionRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_subscription_empty_call_rest(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_subscription), "__call__" + ) as call: + client.delete_subscription(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = data_subscription_service.DeleteSubscriptionRequest() + assert args[0] == request_msg + + +def test_data_subscription_service_rest_lro_client(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + transport = client.transport + + # Ensure that we have an api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.AbstractOperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.DataSubscriptionServiceGrpcTransport, + ) + + +def test_data_subscription_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.DataSubscriptionServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_data_subscription_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.devicesandservices.health_v4.services.data_subscription_service.transports.DataSubscriptionServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.DataSubscriptionServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "create_subscriber", + "list_subscribers", + "update_subscriber", + "delete_subscriber", + "create_subscription", + "list_subscriptions", + "update_subscription", + "delete_subscription", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Additionally, the LRO client (a property) should + # also raise NotImplementedError + with pytest.raises(NotImplementedError): + transport.operations_client + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_data_subscription_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.devicesandservices.health_v4.services.data_subscription_service.transports.DataSubscriptionServiceTransport._prep_wrapped_messages" + ) as Transport, + ): + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.DataSubscriptionServiceTransport( + 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_data_subscription_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.devicesandservices.health_v4.services.data_subscription_service.transports.DataSubscriptionServiceTransport._prep_wrapped_messages" + ) as Transport, + ): + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.DataSubscriptionServiceTransport() + adc.assert_called_once() + + +def test_data_subscription_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) + DataSubscriptionServiceClient() + 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.DataSubscriptionServiceGrpcTransport, + transports.DataSubscriptionServiceGrpcAsyncIOTransport, + ], +) +def test_data_subscription_service_transport_auth_adc(transport_class): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.DataSubscriptionServiceGrpcTransport, + transports.DataSubscriptionServiceGrpcAsyncIOTransport, + transports.DataSubscriptionServiceRestTransport, + ], +) +def test_data_subscription_service_transport_auth_gdch_credentials(transport_class): + host = "https://language.com" + api_audience_tests = [None, "https://language2.com"] + api_audience_expect = [host, "https://language2.com"] + for t, e in zip(api_audience_tests, api_audience_expect): + with mock.patch.object(google.auth, "default", autospec=True) as adc: + gdch_mock = mock.MagicMock() + type(gdch_mock).with_gdch_audience = mock.PropertyMock( + return_value=gdch_mock + ) + adc.return_value = (gdch_mock, None) + transport_class(host=host, api_audience=t) + gdch_mock.with_gdch_audience.assert_called_once_with(e) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.DataSubscriptionServiceGrpcTransport, grpc_helpers), + (transports.DataSubscriptionServiceGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +def test_data_subscription_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( + "health.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="health.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.DataSubscriptionServiceGrpcTransport, + transports.DataSubscriptionServiceGrpcAsyncIOTransport, + ], +) +def test_data_subscription_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_data_subscription_service_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.DataSubscriptionServiceRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_data_subscription_service_host_no_port(transport_name): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="health.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "health.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://health.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_data_subscription_service_host_with_port(transport_name): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="health.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "health.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://health.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_data_subscription_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = DataSubscriptionServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = DataSubscriptionServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.create_subscriber._session + session2 = client2.transport.create_subscriber._session + assert session1 != session2 + session1 = client1.transport.list_subscribers._session + session2 = client2.transport.list_subscribers._session + assert session1 != session2 + session1 = client1.transport.update_subscriber._session + session2 = client2.transport.update_subscriber._session + assert session1 != session2 + session1 = client1.transport.delete_subscriber._session + session2 = client2.transport.delete_subscriber._session + assert session1 != session2 + session1 = client1.transport.create_subscription._session + session2 = client2.transport.create_subscription._session + assert session1 != session2 + session1 = client1.transport.list_subscriptions._session + session2 = client2.transport.list_subscriptions._session + assert session1 != session2 + session1 = client1.transport.update_subscription._session + session2 = client2.transport.update_subscription._session + assert session1 != session2 + session1 = client1.transport.delete_subscription._session + session2 = client2.transport.delete_subscription._session + assert session1 != session2 + + +def test_data_subscription_service_grpc_transport_channel(): + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.DataSubscriptionServiceGrpcTransport( + 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_data_subscription_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.DataSubscriptionServiceGrpcAsyncIOTransport( + 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.filterwarnings("ignore::FutureWarning") +@pytest.mark.parametrize( + "transport_class", + [ + transports.DataSubscriptionServiceGrpcTransport, + transports.DataSubscriptionServiceGrpcAsyncIOTransport, + ], +) +def test_data_subscription_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.DataSubscriptionServiceGrpcTransport, + transports.DataSubscriptionServiceGrpcAsyncIOTransport, + ], +) +def test_data_subscription_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_data_subscription_service_grpc_lro_client(): + client = DataSubscriptionServiceClient( + 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_data_subscription_service_grpc_lro_async_client(): + client = DataSubscriptionServiceAsyncClient( + 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_data_type_path(): + user = "squid" + data_type = "clam" + expected = "users/{user}/dataTypes/{data_type}".format( + user=user, + data_type=data_type, + ) + actual = DataSubscriptionServiceClient.data_type_path(user, data_type) + assert expected == actual + + +def test_parse_data_type_path(): + expected = { + "user": "whelk", + "data_type": "octopus", + } + path = DataSubscriptionServiceClient.data_type_path(**expected) + + # Check that the path construction is reversible. + actual = DataSubscriptionServiceClient.parse_data_type_path(path) + assert expected == actual + + +def test_subscriber_path(): + project = "oyster" + subscriber = "nudibranch" + expected = "projects/{project}/subscribers/{subscriber}".format( + project=project, + subscriber=subscriber, + ) + actual = DataSubscriptionServiceClient.subscriber_path(project, subscriber) + assert expected == actual + + +def test_parse_subscriber_path(): + expected = { + "project": "cuttlefish", + "subscriber": "mussel", + } + path = DataSubscriptionServiceClient.subscriber_path(**expected) + + # Check that the path construction is reversible. + actual = DataSubscriptionServiceClient.parse_subscriber_path(path) + assert expected == actual + + +def test_subscription_path(): + project = "winkle" + subscriber = "nautilus" + subscription = "scallop" + expected = "projects/{project}/subscribers/{subscriber}/subscriptions/{subscription}".format( + project=project, + subscriber=subscriber, + subscription=subscription, + ) + actual = DataSubscriptionServiceClient.subscription_path( + project, subscriber, subscription + ) + assert expected == actual + + +def test_parse_subscription_path(): + expected = { + "project": "abalone", + "subscriber": "squid", + "subscription": "clam", + } + path = DataSubscriptionServiceClient.subscription_path(**expected) + + # Check that the path construction is reversible. + actual = DataSubscriptionServiceClient.parse_subscription_path(path) + assert expected == actual + + +def test_user_path(): + user = "whelk" + expected = "users/{user}".format( + user=user, + ) + actual = DataSubscriptionServiceClient.user_path(user) + assert expected == actual + + +def test_parse_user_path(): + expected = { + "user": "octopus", + } + path = DataSubscriptionServiceClient.user_path(**expected) + + # Check that the path construction is reversible. + actual = DataSubscriptionServiceClient.parse_user_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "oyster" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = DataSubscriptionServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "nudibranch", + } + path = DataSubscriptionServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = DataSubscriptionServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "cuttlefish" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = DataSubscriptionServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "mussel", + } + path = DataSubscriptionServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = DataSubscriptionServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "winkle" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = DataSubscriptionServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nautilus", + } + path = DataSubscriptionServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = DataSubscriptionServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "scallop" + expected = "projects/{project}".format( + project=project, + ) + actual = DataSubscriptionServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "abalone", + } + path = DataSubscriptionServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = DataSubscriptionServiceClient.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 = DataSubscriptionServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "whelk", + "location": "octopus", + } + path = DataSubscriptionServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = DataSubscriptionServiceClient.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.DataSubscriptionServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.DataSubscriptionServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = DataSubscriptionServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_grpc(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +@pytest.mark.asyncio +async def test_transport_close_grpc_asyncio(): + client = DataSubscriptionServiceAsyncClient( + credentials=async_anonymous_credentials(), 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_rest(): + client = DataSubscriptionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + "grpc", + ] + for transport in transports: + client = DataSubscriptionServiceClient( + 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", + [ + ( + DataSubscriptionServiceClient, + transports.DataSubscriptionServiceGrpcTransport, + ), + ( + DataSubscriptionServiceAsyncClient, + transports.DataSubscriptionServiceGrpcAsyncIOTransport, + ), + ], +) +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_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/packages/google-devicesandservices-health/tests/unit/gapic/health_v4/test_health_profile_service.py b/packages/google-devicesandservices-health/tests/unit/gapic/health_v4/test_health_profile_service.py new file mode 100644 index 000000000000..253b34ea9a1d --- /dev/null +++ b/packages/google-devicesandservices-health/tests/unit/gapic/health_v4/test_health_profile_service.py @@ -0,0 +1,8818 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 asyncio +import json +import math +import os +from collections.abc import AsyncIterable, Iterable, Mapping, Sequence +from unittest import mock +from unittest.mock import AsyncMock + +import grpc +import pytest +from google.api_core import api_core_version +from google.protobuf import json_format +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +import google.auth +import google.protobuf.duration_pb2 as duration_pb2 # type: ignore +import google.protobuf.field_mask_pb2 as field_mask_pb2 # type: ignore +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore +import google.type.date_pb2 as date_pb2 # type: ignore +from google.api_core import ( + client_options, + gapic_v1, + grpc_helpers, + grpc_helpers_async, + path_template, +) +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.oauth2 import service_account + +from google.devicesandservices.health_v4.services.health_profile_service import ( + HealthProfileServiceAsyncClient, + HealthProfileServiceClient, + pagers, + transports, +) +from google.devicesandservices.health_v4.types import health_profile + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + +# 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 + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +@pytest.fixture(autouse=True) +def set_event_loop(): + try: + asyncio.get_running_loop() + yield + except RuntimeError: + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + try: + yield + finally: + loop.close() + asyncio.set_event_loop(None) + + +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" + custom_endpoint = ".custom" + + assert HealthProfileServiceClient._get_default_mtls_endpoint(None) is None + assert ( + HealthProfileServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + HealthProfileServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + HealthProfileServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + HealthProfileServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + HealthProfileServiceClient._get_default_mtls_endpoint(non_googleapi) + == non_googleapi + ) + assert ( + HealthProfileServiceClient._get_default_mtls_endpoint(custom_endpoint) + == custom_endpoint + ) + + +def test__read_environment_variables(): + assert HealthProfileServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert HealthProfileServiceClient._read_environment_variables() == ( + True, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert HealthProfileServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with pytest.raises(ValueError) as excinfo: + HealthProfileServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + else: + assert HealthProfileServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert HealthProfileServiceClient._read_environment_variables() == ( + False, + "never", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert HealthProfileServiceClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert HealthProfileServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + HealthProfileServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert HealthProfileServiceClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test_use_client_cert_effective(): + # Test case 1: Test when `should_use_client_cert` returns True. + # We mock the `should_use_client_cert` function to simulate a scenario where + # the google-auth library supports automatic mTLS and determines that a + # client certificate should be used. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch( + "google.auth.transport.mtls.should_use_client_cert", return_value=True + ): + assert HealthProfileServiceClient._use_client_cert_effective() is True + + # Test case 2: Test when `should_use_client_cert` returns False. + # We mock the `should_use_client_cert` function to simulate a scenario where + # the google-auth library supports automatic mTLS and determines that a + # client certificate should NOT be used. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch( + "google.auth.transport.mtls.should_use_client_cert", return_value=False + ): + assert HealthProfileServiceClient._use_client_cert_effective() is False + + # Test case 3: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "true". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert HealthProfileServiceClient._use_client_cert_effective() is True + + # Test case 4: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "false". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"} + ): + assert HealthProfileServiceClient._use_client_cert_effective() is False + + # Test case 5: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "True". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "True"}): + assert HealthProfileServiceClient._use_client_cert_effective() is True + + # Test case 6: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "False". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "False"} + ): + assert HealthProfileServiceClient._use_client_cert_effective() is False + + # Test case 7: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "TRUE". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "TRUE"}): + assert HealthProfileServiceClient._use_client_cert_effective() is True + + # Test case 8: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "FALSE". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "FALSE"} + ): + assert HealthProfileServiceClient._use_client_cert_effective() is False + + # Test case 9: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not set. + # In this case, the method should return False, which is the default value. + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, clear=True): + assert HealthProfileServiceClient._use_client_cert_effective() is False + + # Test case 10: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value. + # The method should raise a ValueError as the environment variable must be either + # "true" or "false". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"} + ): + with pytest.raises(ValueError): + HealthProfileServiceClient._use_client_cert_effective() + + # Test case 11: Test when `should_use_client_cert` is available and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value. + # The method should return False as the environment variable is set to an invalid value. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"} + ): + assert HealthProfileServiceClient._use_client_cert_effective() is False + + # Test case 12: Test when `should_use_client_cert` is available and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is unset. Also, + # the GOOGLE_API_CONFIG environment variable is unset. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": ""}): + with mock.patch.dict(os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": ""}): + assert HealthProfileServiceClient._use_client_cert_effective() is False + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert HealthProfileServiceClient._get_client_cert_source(None, False) is None + assert ( + HealthProfileServiceClient._get_client_cert_source( + mock_provided_cert_source, False + ) + is None + ) + assert ( + HealthProfileServiceClient._get_client_cert_source( + mock_provided_cert_source, True + ) + == mock_provided_cert_source + ) + + 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_default_cert_source, + ): + assert ( + HealthProfileServiceClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + HealthProfileServiceClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + HealthProfileServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(HealthProfileServiceClient), +) +@mock.patch.object( + HealthProfileServiceAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(HealthProfileServiceAsyncClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = HealthProfileServiceClient._DEFAULT_UNIVERSE + default_endpoint = HealthProfileServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = HealthProfileServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + HealthProfileServiceClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + HealthProfileServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == HealthProfileServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + HealthProfileServiceClient._get_api_endpoint( + None, None, default_universe, "auto" + ) + == default_endpoint + ) + assert ( + HealthProfileServiceClient._get_api_endpoint( + None, None, default_universe, "always" + ) + == HealthProfileServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + HealthProfileServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == HealthProfileServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + HealthProfileServiceClient._get_api_endpoint(None, None, mock_universe, "never") + == mock_endpoint + ) + assert ( + HealthProfileServiceClient._get_api_endpoint( + None, None, default_universe, "never" + ) + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + HealthProfileServiceClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + HealthProfileServiceClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + HealthProfileServiceClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert ( + HealthProfileServiceClient._get_universe_domain(None, None) + == HealthProfileServiceClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + HealthProfileServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = HealthProfileServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = HealthProfileServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (HealthProfileServiceClient, "grpc"), + (HealthProfileServiceAsyncClient, "grpc_asyncio"), + (HealthProfileServiceClient, "rest"), + ], +) +def test_health_profile_service_client_from_service_account_info( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "health.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://health.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.HealthProfileServiceGrpcTransport, "grpc"), + (transports.HealthProfileServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.HealthProfileServiceRestTransport, "rest"), + ], +) +def test_health_profile_service_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (HealthProfileServiceClient, "grpc"), + (HealthProfileServiceAsyncClient, "grpc_asyncio"), + (HealthProfileServiceClient, "rest"), + ], +) +def test_health_profile_service_client_from_service_account_file( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "health.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://health.googleapis.com" + ) + + +def test_health_profile_service_client_get_transport_class(): + transport = HealthProfileServiceClient.get_transport_class() + available_transports = [ + transports.HealthProfileServiceGrpcTransport, + transports.HealthProfileServiceRestTransport, + ] + assert transport in available_transports + + transport = HealthProfileServiceClient.get_transport_class("grpc") + assert transport == transports.HealthProfileServiceGrpcTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + HealthProfileServiceClient, + transports.HealthProfileServiceGrpcTransport, + "grpc", + ), + ( + HealthProfileServiceAsyncClient, + transports.HealthProfileServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ( + HealthProfileServiceClient, + transports.HealthProfileServiceRestTransport, + "rest", + ), + ], +) +@mock.patch.object( + HealthProfileServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(HealthProfileServiceClient), +) +@mock.patch.object( + HealthProfileServiceAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(HealthProfileServiceAsyncClient), +) +def test_health_profile_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(HealthProfileServiceClient, "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(HealthProfileServiceClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # 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_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + HealthProfileServiceClient, + transports.HealthProfileServiceGrpcTransport, + "grpc", + "true", + ), + ( + HealthProfileServiceAsyncClient, + transports.HealthProfileServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + ( + HealthProfileServiceClient, + transports.HealthProfileServiceGrpcTransport, + "grpc", + "false", + ), + ( + HealthProfileServiceAsyncClient, + transports.HealthProfileServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + ( + HealthProfileServiceClient, + transports.HealthProfileServiceRestTransport, + "rest", + "true", + ), + ( + HealthProfileServiceClient, + transports.HealthProfileServiceRestTransport, + "rest", + "false", + ), + ], +) +@mock.patch.object( + HealthProfileServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(HealthProfileServiceClient), +) +@mock.patch.object( + HealthProfileServiceAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(HealthProfileServiceAsyncClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_health_profile_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_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class", [HealthProfileServiceClient, HealthProfileServiceAsyncClient] +) +@mock.patch.object( + HealthProfileServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(HealthProfileServiceClient), +) +@mock.patch.object( + HealthProfileServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(HealthProfileServiceAsyncClient), +) +def test_health_profile_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_CLIENT_CERTIFICATE is "Unsupported". + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + 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 cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset. + test_cases = [ + ( + # With workloads present in config, mTLS is enabled. + { + "version": 1, + "cert_configs": { + "workload": { + "cert_path": "path/to/cert/file", + "key_path": "path/to/key/file", + } + }, + }, + mock_client_cert_source, + ), + ( + # With workloads not present in config, mTLS is disabled. + { + "version": 1, + "cert_configs": {}, + }, + None, + ), + ] + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + for config_data, expected_cert_source in test_cases: + env = os.environ.copy() + env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", None) + with mock.patch.dict(os.environ, env, clear=True): + config_filename = "mock_certificate_config.json" + config_file_content = json.dumps(config_data) + m = mock.mock_open(read_data=config_file_content) + with mock.patch("builtins.open", m): + with mock.patch.dict( + os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename} + ): + 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 expected_cert_source + + # Test cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset(empty). + test_cases = [ + ( + # With workloads present in config, mTLS is enabled. + { + "version": 1, + "cert_configs": { + "workload": { + "cert_path": "path/to/cert/file", + "key_path": "path/to/key/file", + } + }, + }, + mock_client_cert_source, + ), + ( + # With workloads not present in config, mTLS is disabled. + { + "version": 1, + "cert_configs": {}, + }, + None, + ), + ] + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + for config_data, expected_cert_source in test_cases: + env = os.environ.copy() + env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", "") + with mock.patch.dict(os.environ, env, clear=True): + config_filename = "mock_certificate_config.json" + config_file_content = json.dumps(config_data) + m = mock.mock_open(read_data=config_file_content) + with mock.patch("builtins.open", m): + with mock.patch.dict( + os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename} + ): + 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 expected_cert_source + + # 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 + + # 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) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + +@pytest.mark.parametrize( + "client_class", [HealthProfileServiceClient, HealthProfileServiceAsyncClient] +) +@mock.patch.object( + HealthProfileServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(HealthProfileServiceClient), +) +@mock.patch.object( + HealthProfileServiceAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(HealthProfileServiceAsyncClient), +) +def test_health_profile_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = HealthProfileServiceClient._DEFAULT_UNIVERSE + default_endpoint = HealthProfileServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = HealthProfileServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + HealthProfileServiceClient, + transports.HealthProfileServiceGrpcTransport, + "grpc", + ), + ( + HealthProfileServiceAsyncClient, + transports.HealthProfileServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ( + HealthProfileServiceClient, + transports.HealthProfileServiceRestTransport, + "rest", + ), + ], +) +def test_health_profile_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_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + HealthProfileServiceClient, + transports.HealthProfileServiceGrpcTransport, + "grpc", + grpc_helpers, + ), + ( + HealthProfileServiceAsyncClient, + transports.HealthProfileServiceGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + ( + HealthProfileServiceClient, + transports.HealthProfileServiceRestTransport, + "rest", + None, + ), + ], +) +def test_health_profile_service_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_health_profile_service_client_client_options_from_dict(): + with mock.patch( + "google.devicesandservices.health_v4.services.health_profile_service.transports.HealthProfileServiceGrpcTransport.__init__" + ) as grpc_transport: + grpc_transport.return_value = None + client = HealthProfileServiceClient( + client_options={"api_endpoint": "squid.clam.whelk"} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + HealthProfileServiceClient, + transports.HealthProfileServiceGrpcTransport, + "grpc", + grpc_helpers, + ), + ( + HealthProfileServiceAsyncClient, + transports.HealthProfileServiceGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + ], +) +def test_health_profile_service_client_create_channel_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # test that the credentials from file are saved and used as the credentials. + with ( + mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, + mock.patch.object(google.auth, "default", autospec=True) as adc, + mock.patch.object(grpc_helpers, "create_channel") as create_channel, + ): + creds = ga_credentials.AnonymousCredentials() + file_creds = ga_credentials.AnonymousCredentials() + load_creds.return_value = (file_creds, None) + adc.return_value = (creds, None) + client = client_class(client_options=options, transport=transport_name) + create_channel.assert_called_with( + "health.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + "https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly", + "https://www.googleapis.com/auth/googlehealth.ecg.readonly", + "https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.readonly", + "https://www.googleapis.com/auth/googlehealth.irn.readonly", + "https://www.googleapis.com/auth/googlehealth.profile.readonly", + "https://www.googleapis.com/auth/googlehealth.settings.readonly", + "https://www.googleapis.com/auth/googlehealth.sleep.readonly", + ), + scopes=None, + default_host="health.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "request_type", + [ + health_profile.GetProfileRequest(), + {}, + ], +) +def test_get_profile(request_type, transport: str = "grpc"): + client = HealthProfileServiceClient( + 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_profile), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = health_profile.Profile( + name="name_value", + age=301, + user_configured_walking_stride_length_mm=4244, + user_configured_running_stride_length_mm=4264, + auto_walking_stride_length_mm=3081, + auto_running_stride_length_mm=3101, + ) + response = client.get_profile(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = health_profile.GetProfileRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, health_profile.Profile) + assert response.name == "name_value" + assert response.age == 301 + assert response.user_configured_walking_stride_length_mm == 4244 + assert response.user_configured_running_stride_length_mm == 4264 + assert response.auto_walking_stride_length_mm == 3081 + assert response.auto_running_stride_length_mm == 3101 + + +def test_get_profile_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = health_profile.GetProfileRequest( + name="name_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_profile), "__call__") as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.get_profile(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.GetProfileRequest( + name="name_value", + ) + assert args[0] == request_msg + + +def test_get_profile_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_profile in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_profile] = mock_rpc + request = {} + client.get_profile(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_profile(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_get_profile_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.get_profile + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.get_profile + ] = mock_rpc + + request = {} + await client.get_profile(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.get_profile(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + health_profile.GetProfileRequest(), + {}, + ], +) +async def test_get_profile_async(request_type, transport: str = "grpc_asyncio"): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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_profile), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.Profile( + name="name_value", + age=301, + user_configured_walking_stride_length_mm=4244, + user_configured_running_stride_length_mm=4264, + auto_walking_stride_length_mm=3081, + auto_running_stride_length_mm=3101, + ) + ) + response = await client.get_profile(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = health_profile.GetProfileRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, health_profile.Profile) + assert response.name == "name_value" + assert response.age == 301 + assert response.user_configured_walking_stride_length_mm == 4244 + assert response.user_configured_running_stride_length_mm == 4264 + assert response.auto_walking_stride_length_mm == 3081 + assert response.auto_running_stride_length_mm == 3101 + + +def test_get_profile_field_headers(): + client = HealthProfileServiceClient( + 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 = health_profile.GetProfileRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_profile), "__call__") as call: + call.return_value = health_profile.Profile() + client.get_profile(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_profile_field_headers_async(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = health_profile.GetProfileRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_profile), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.Profile() + ) + await client.get_profile(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_profile_flattened(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_profile), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = health_profile.Profile() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_profile( + 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_profile_flattened_error(): + client = HealthProfileServiceClient( + 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_profile( + health_profile.GetProfileRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_profile_flattened_async(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_profile), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = health_profile.Profile() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.Profile() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_profile( + 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_profile_flattened_error_async(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_profile( + health_profile.GetProfileRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + health_profile.UpdateProfileRequest(), + {}, + ], +) +def test_update_profile(request_type, transport: str = "grpc"): + client = HealthProfileServiceClient( + 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_profile), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = health_profile.Profile( + name="name_value", + age=301, + user_configured_walking_stride_length_mm=4244, + user_configured_running_stride_length_mm=4264, + auto_walking_stride_length_mm=3081, + auto_running_stride_length_mm=3101, + ) + response = client.update_profile(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = health_profile.UpdateProfileRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, health_profile.Profile) + assert response.name == "name_value" + assert response.age == 301 + assert response.user_configured_walking_stride_length_mm == 4244 + assert response.user_configured_running_stride_length_mm == 4264 + assert response.auto_walking_stride_length_mm == 3081 + assert response.auto_running_stride_length_mm == 3101 + + +def test_update_profile_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = health_profile.UpdateProfileRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_profile), "__call__") as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.update_profile(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.UpdateProfileRequest() + assert args[0] == request_msg + + +def test_update_profile_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.update_profile in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.update_profile] = mock_rpc + request = {} + client.update_profile(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.update_profile(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_update_profile_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.update_profile + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.update_profile + ] = mock_rpc + + request = {} + await client.update_profile(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.update_profile(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + health_profile.UpdateProfileRequest(), + {}, + ], +) +async def test_update_profile_async(request_type, transport: str = "grpc_asyncio"): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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_profile), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.Profile( + name="name_value", + age=301, + user_configured_walking_stride_length_mm=4244, + user_configured_running_stride_length_mm=4264, + auto_walking_stride_length_mm=3081, + auto_running_stride_length_mm=3101, + ) + ) + response = await client.update_profile(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = health_profile.UpdateProfileRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, health_profile.Profile) + assert response.name == "name_value" + assert response.age == 301 + assert response.user_configured_walking_stride_length_mm == 4244 + assert response.user_configured_running_stride_length_mm == 4264 + assert response.auto_walking_stride_length_mm == 3081 + assert response.auto_running_stride_length_mm == 3101 + + +def test_update_profile_field_headers(): + client = HealthProfileServiceClient( + 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 = health_profile.UpdateProfileRequest() + + request.profile.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_profile), "__call__") as call: + call.return_value = health_profile.Profile() + client.update_profile(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", + "profile.name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_update_profile_field_headers_async(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = health_profile.UpdateProfileRequest() + + request.profile.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_profile), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.Profile() + ) + await client.update_profile(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", + "profile.name=name_value", + ) in kw["metadata"] + + +def test_update_profile_flattened(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_profile), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = health_profile.Profile() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_profile( + profile=health_profile.Profile(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].profile + mock_val = health_profile.Profile(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_profile_flattened_error(): + client = HealthProfileServiceClient( + 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_profile( + health_profile.UpdateProfileRequest(), + profile=health_profile.Profile(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.asyncio +async def test_update_profile_flattened_async(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_profile), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = health_profile.Profile() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.Profile() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_profile( + profile=health_profile.Profile(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].profile + mock_val = health_profile.Profile(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_profile_flattened_error_async(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_profile( + health_profile.UpdateProfileRequest(), + profile=health_profile.Profile(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.parametrize( + "request_type", + [ + health_profile.GetSettingsRequest(), + {}, + ], +) +def test_get_settings(request_type, transport: str = "grpc"): + client = HealthProfileServiceClient( + 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_settings), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = health_profile.Settings( + name="name_value", + auto_stride_enabled=True, + distance_unit=health_profile.Settings.DistanceUnit.DISTANCE_UNIT_MILES, + glucose_unit=health_profile.Settings.GlucoseUnit.GLUCOSE_UNIT_MG_DL, + height_unit=health_profile.Settings.HeightUnit.HEIGHT_UNIT_INCHES, + language_locale="language_locale_value", + stride_length_walking_type=health_profile.Settings.StrideLengthType.STRIDE_LENGTH_TYPE_DEFAULT, + stride_length_running_type=health_profile.Settings.StrideLengthType.STRIDE_LENGTH_TYPE_DEFAULT, + swim_unit=health_profile.Settings.SwimUnit.SWIM_UNIT_METERS, + temperature_unit=health_profile.Settings.TemperatureUnit.TEMPERATURE_UNIT_CELSIUS, + time_zone="time_zone_value", + weight_unit=health_profile.Settings.WeightUnit.WEIGHT_UNIT_POUNDS, + water_unit=health_profile.Settings.WaterUnit.WATER_UNIT_ML, + food_language_code="food_language_code_value", + ) + response = client.get_settings(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = health_profile.GetSettingsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, health_profile.Settings) + assert response.name == "name_value" + assert response.auto_stride_enabled is True + assert ( + response.distance_unit + == health_profile.Settings.DistanceUnit.DISTANCE_UNIT_MILES + ) + assert ( + response.glucose_unit == health_profile.Settings.GlucoseUnit.GLUCOSE_UNIT_MG_DL + ) + assert response.height_unit == health_profile.Settings.HeightUnit.HEIGHT_UNIT_INCHES + assert response.language_locale == "language_locale_value" + assert ( + response.stride_length_walking_type + == health_profile.Settings.StrideLengthType.STRIDE_LENGTH_TYPE_DEFAULT + ) + assert ( + response.stride_length_running_type + == health_profile.Settings.StrideLengthType.STRIDE_LENGTH_TYPE_DEFAULT + ) + assert response.swim_unit == health_profile.Settings.SwimUnit.SWIM_UNIT_METERS + assert ( + response.temperature_unit + == health_profile.Settings.TemperatureUnit.TEMPERATURE_UNIT_CELSIUS + ) + assert response.time_zone == "time_zone_value" + assert response.weight_unit == health_profile.Settings.WeightUnit.WEIGHT_UNIT_POUNDS + assert response.water_unit == health_profile.Settings.WaterUnit.WATER_UNIT_ML + assert response.food_language_code == "food_language_code_value" + + +def test_get_settings_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = health_profile.GetSettingsRequest( + name="name_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_settings), "__call__") as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.get_settings(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.GetSettingsRequest( + name="name_value", + ) + assert args[0] == request_msg + + +def test_get_settings_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_settings in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_settings] = mock_rpc + request = {} + client.get_settings(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_settings(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_get_settings_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.get_settings + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.get_settings + ] = mock_rpc + + request = {} + await client.get_settings(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.get_settings(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + health_profile.GetSettingsRequest(), + {}, + ], +) +async def test_get_settings_async(request_type, transport: str = "grpc_asyncio"): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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_settings), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.Settings( + name="name_value", + auto_stride_enabled=True, + distance_unit=health_profile.Settings.DistanceUnit.DISTANCE_UNIT_MILES, + glucose_unit=health_profile.Settings.GlucoseUnit.GLUCOSE_UNIT_MG_DL, + height_unit=health_profile.Settings.HeightUnit.HEIGHT_UNIT_INCHES, + language_locale="language_locale_value", + stride_length_walking_type=health_profile.Settings.StrideLengthType.STRIDE_LENGTH_TYPE_DEFAULT, + stride_length_running_type=health_profile.Settings.StrideLengthType.STRIDE_LENGTH_TYPE_DEFAULT, + swim_unit=health_profile.Settings.SwimUnit.SWIM_UNIT_METERS, + temperature_unit=health_profile.Settings.TemperatureUnit.TEMPERATURE_UNIT_CELSIUS, + time_zone="time_zone_value", + weight_unit=health_profile.Settings.WeightUnit.WEIGHT_UNIT_POUNDS, + water_unit=health_profile.Settings.WaterUnit.WATER_UNIT_ML, + food_language_code="food_language_code_value", + ) + ) + response = await client.get_settings(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = health_profile.GetSettingsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, health_profile.Settings) + assert response.name == "name_value" + assert response.auto_stride_enabled is True + assert ( + response.distance_unit + == health_profile.Settings.DistanceUnit.DISTANCE_UNIT_MILES + ) + assert ( + response.glucose_unit == health_profile.Settings.GlucoseUnit.GLUCOSE_UNIT_MG_DL + ) + assert response.height_unit == health_profile.Settings.HeightUnit.HEIGHT_UNIT_INCHES + assert response.language_locale == "language_locale_value" + assert ( + response.stride_length_walking_type + == health_profile.Settings.StrideLengthType.STRIDE_LENGTH_TYPE_DEFAULT + ) + assert ( + response.stride_length_running_type + == health_profile.Settings.StrideLengthType.STRIDE_LENGTH_TYPE_DEFAULT + ) + assert response.swim_unit == health_profile.Settings.SwimUnit.SWIM_UNIT_METERS + assert ( + response.temperature_unit + == health_profile.Settings.TemperatureUnit.TEMPERATURE_UNIT_CELSIUS + ) + assert response.time_zone == "time_zone_value" + assert response.weight_unit == health_profile.Settings.WeightUnit.WEIGHT_UNIT_POUNDS + assert response.water_unit == health_profile.Settings.WaterUnit.WATER_UNIT_ML + assert response.food_language_code == "food_language_code_value" + + +def test_get_settings_field_headers(): + client = HealthProfileServiceClient( + 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 = health_profile.GetSettingsRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_settings), "__call__") as call: + call.return_value = health_profile.Settings() + client.get_settings(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_settings_field_headers_async(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = health_profile.GetSettingsRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_settings), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.Settings() + ) + await client.get_settings(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_settings_flattened(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_settings), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = health_profile.Settings() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_settings( + 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_settings_flattened_error(): + client = HealthProfileServiceClient( + 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_settings( + health_profile.GetSettingsRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_settings_flattened_async(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_settings), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = health_profile.Settings() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.Settings() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_settings( + 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_settings_flattened_error_async(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_settings( + health_profile.GetSettingsRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + health_profile.UpdateSettingsRequest(), + {}, + ], +) +def test_update_settings(request_type, transport: str = "grpc"): + client = HealthProfileServiceClient( + 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_settings), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = health_profile.Settings( + name="name_value", + auto_stride_enabled=True, + distance_unit=health_profile.Settings.DistanceUnit.DISTANCE_UNIT_MILES, + glucose_unit=health_profile.Settings.GlucoseUnit.GLUCOSE_UNIT_MG_DL, + height_unit=health_profile.Settings.HeightUnit.HEIGHT_UNIT_INCHES, + language_locale="language_locale_value", + stride_length_walking_type=health_profile.Settings.StrideLengthType.STRIDE_LENGTH_TYPE_DEFAULT, + stride_length_running_type=health_profile.Settings.StrideLengthType.STRIDE_LENGTH_TYPE_DEFAULT, + swim_unit=health_profile.Settings.SwimUnit.SWIM_UNIT_METERS, + temperature_unit=health_profile.Settings.TemperatureUnit.TEMPERATURE_UNIT_CELSIUS, + time_zone="time_zone_value", + weight_unit=health_profile.Settings.WeightUnit.WEIGHT_UNIT_POUNDS, + water_unit=health_profile.Settings.WaterUnit.WATER_UNIT_ML, + food_language_code="food_language_code_value", + ) + response = client.update_settings(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = health_profile.UpdateSettingsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, health_profile.Settings) + assert response.name == "name_value" + assert response.auto_stride_enabled is True + assert ( + response.distance_unit + == health_profile.Settings.DistanceUnit.DISTANCE_UNIT_MILES + ) + assert ( + response.glucose_unit == health_profile.Settings.GlucoseUnit.GLUCOSE_UNIT_MG_DL + ) + assert response.height_unit == health_profile.Settings.HeightUnit.HEIGHT_UNIT_INCHES + assert response.language_locale == "language_locale_value" + assert ( + response.stride_length_walking_type + == health_profile.Settings.StrideLengthType.STRIDE_LENGTH_TYPE_DEFAULT + ) + assert ( + response.stride_length_running_type + == health_profile.Settings.StrideLengthType.STRIDE_LENGTH_TYPE_DEFAULT + ) + assert response.swim_unit == health_profile.Settings.SwimUnit.SWIM_UNIT_METERS + assert ( + response.temperature_unit + == health_profile.Settings.TemperatureUnit.TEMPERATURE_UNIT_CELSIUS + ) + assert response.time_zone == "time_zone_value" + assert response.weight_unit == health_profile.Settings.WeightUnit.WEIGHT_UNIT_POUNDS + assert response.water_unit == health_profile.Settings.WaterUnit.WATER_UNIT_ML + assert response.food_language_code == "food_language_code_value" + + +def test_update_settings_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = health_profile.UpdateSettingsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_settings), "__call__") as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.update_settings(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.UpdateSettingsRequest() + assert args[0] == request_msg + + +def test_update_settings_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.update_settings in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.update_settings] = mock_rpc + request = {} + client.update_settings(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.update_settings(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_update_settings_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.update_settings + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.update_settings + ] = mock_rpc + + request = {} + await client.update_settings(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.update_settings(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + health_profile.UpdateSettingsRequest(), + {}, + ], +) +async def test_update_settings_async(request_type, transport: str = "grpc_asyncio"): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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_settings), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.Settings( + name="name_value", + auto_stride_enabled=True, + distance_unit=health_profile.Settings.DistanceUnit.DISTANCE_UNIT_MILES, + glucose_unit=health_profile.Settings.GlucoseUnit.GLUCOSE_UNIT_MG_DL, + height_unit=health_profile.Settings.HeightUnit.HEIGHT_UNIT_INCHES, + language_locale="language_locale_value", + stride_length_walking_type=health_profile.Settings.StrideLengthType.STRIDE_LENGTH_TYPE_DEFAULT, + stride_length_running_type=health_profile.Settings.StrideLengthType.STRIDE_LENGTH_TYPE_DEFAULT, + swim_unit=health_profile.Settings.SwimUnit.SWIM_UNIT_METERS, + temperature_unit=health_profile.Settings.TemperatureUnit.TEMPERATURE_UNIT_CELSIUS, + time_zone="time_zone_value", + weight_unit=health_profile.Settings.WeightUnit.WEIGHT_UNIT_POUNDS, + water_unit=health_profile.Settings.WaterUnit.WATER_UNIT_ML, + food_language_code="food_language_code_value", + ) + ) + response = await client.update_settings(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = health_profile.UpdateSettingsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, health_profile.Settings) + assert response.name == "name_value" + assert response.auto_stride_enabled is True + assert ( + response.distance_unit + == health_profile.Settings.DistanceUnit.DISTANCE_UNIT_MILES + ) + assert ( + response.glucose_unit == health_profile.Settings.GlucoseUnit.GLUCOSE_UNIT_MG_DL + ) + assert response.height_unit == health_profile.Settings.HeightUnit.HEIGHT_UNIT_INCHES + assert response.language_locale == "language_locale_value" + assert ( + response.stride_length_walking_type + == health_profile.Settings.StrideLengthType.STRIDE_LENGTH_TYPE_DEFAULT + ) + assert ( + response.stride_length_running_type + == health_profile.Settings.StrideLengthType.STRIDE_LENGTH_TYPE_DEFAULT + ) + assert response.swim_unit == health_profile.Settings.SwimUnit.SWIM_UNIT_METERS + assert ( + response.temperature_unit + == health_profile.Settings.TemperatureUnit.TEMPERATURE_UNIT_CELSIUS + ) + assert response.time_zone == "time_zone_value" + assert response.weight_unit == health_profile.Settings.WeightUnit.WEIGHT_UNIT_POUNDS + assert response.water_unit == health_profile.Settings.WaterUnit.WATER_UNIT_ML + assert response.food_language_code == "food_language_code_value" + + +def test_update_settings_field_headers(): + client = HealthProfileServiceClient( + 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 = health_profile.UpdateSettingsRequest() + + request.settings.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_settings), "__call__") as call: + call.return_value = health_profile.Settings() + client.update_settings(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", + "settings.name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_update_settings_field_headers_async(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = health_profile.UpdateSettingsRequest() + + request.settings.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_settings), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.Settings() + ) + await client.update_settings(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", + "settings.name=name_value", + ) in kw["metadata"] + + +def test_update_settings_flattened(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_settings), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = health_profile.Settings() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_settings( + settings=health_profile.Settings(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].settings + mock_val = health_profile.Settings(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_settings_flattened_error(): + client = HealthProfileServiceClient( + 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_settings( + health_profile.UpdateSettingsRequest(), + settings=health_profile.Settings(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.asyncio +async def test_update_settings_flattened_async(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_settings), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = health_profile.Settings() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.Settings() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_settings( + settings=health_profile.Settings(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].settings + mock_val = health_profile.Settings(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_settings_flattened_error_async(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_settings( + health_profile.UpdateSettingsRequest(), + settings=health_profile.Settings(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.parametrize( + "request_type", + [ + health_profile.GetIdentityRequest(), + {}, + ], +) +def test_get_identity(request_type, transport: str = "grpc"): + client = HealthProfileServiceClient( + 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_identity), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = health_profile.Identity( + name="name_value", + legacy_user_id="legacy_user_id_value", + health_user_id="health_user_id_value", + ) + response = client.get_identity(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = health_profile.GetIdentityRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, health_profile.Identity) + assert response.name == "name_value" + assert response.legacy_user_id == "legacy_user_id_value" + assert response.health_user_id == "health_user_id_value" + + +def test_get_identity_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = health_profile.GetIdentityRequest( + name="name_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_identity), "__call__") as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.get_identity(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.GetIdentityRequest( + name="name_value", + ) + assert args[0] == request_msg + + +def test_get_identity_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_identity in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_identity] = mock_rpc + request = {} + client.get_identity(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_identity(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_get_identity_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.get_identity + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.get_identity + ] = mock_rpc + + request = {} + await client.get_identity(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.get_identity(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + health_profile.GetIdentityRequest(), + {}, + ], +) +async def test_get_identity_async(request_type, transport: str = "grpc_asyncio"): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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_identity), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.Identity( + name="name_value", + legacy_user_id="legacy_user_id_value", + health_user_id="health_user_id_value", + ) + ) + response = await client.get_identity(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = health_profile.GetIdentityRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, health_profile.Identity) + assert response.name == "name_value" + assert response.legacy_user_id == "legacy_user_id_value" + assert response.health_user_id == "health_user_id_value" + + +def test_get_identity_field_headers(): + client = HealthProfileServiceClient( + 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 = health_profile.GetIdentityRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_identity), "__call__") as call: + call.return_value = health_profile.Identity() + client.get_identity(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_identity_field_headers_async(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = health_profile.GetIdentityRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_identity), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.Identity() + ) + await client.get_identity(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_identity_flattened(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_identity), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = health_profile.Identity() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_identity( + 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_identity_flattened_error(): + client = HealthProfileServiceClient( + 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_identity( + health_profile.GetIdentityRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_identity_flattened_async(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_identity), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = health_profile.Identity() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.Identity() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_identity( + 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_identity_flattened_error_async(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_identity( + health_profile.GetIdentityRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + health_profile.GetIrnProfileRequest(), + {}, + ], +) +def test_get_irn_profile(request_type, transport: str = "grpc"): + client = HealthProfileServiceClient( + 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_irn_profile), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = health_profile.IrnProfile( + name="name_value", + onboarding_status=True, + enrollment_status=True, + ) + response = client.get_irn_profile(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = health_profile.GetIrnProfileRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, health_profile.IrnProfile) + assert response.name == "name_value" + assert response.onboarding_status is True + assert response.enrollment_status is True + + +def test_get_irn_profile_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = health_profile.GetIrnProfileRequest( + name="name_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_irn_profile), "__call__") as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.get_irn_profile(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.GetIrnProfileRequest( + name="name_value", + ) + assert args[0] == request_msg + + +def test_get_irn_profile_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_irn_profile in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_irn_profile] = mock_rpc + request = {} + client.get_irn_profile(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_irn_profile(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_get_irn_profile_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.get_irn_profile + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.get_irn_profile + ] = mock_rpc + + request = {} + await client.get_irn_profile(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.get_irn_profile(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + health_profile.GetIrnProfileRequest(), + {}, + ], +) +async def test_get_irn_profile_async(request_type, transport: str = "grpc_asyncio"): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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_irn_profile), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.IrnProfile( + name="name_value", + onboarding_status=True, + enrollment_status=True, + ) + ) + response = await client.get_irn_profile(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = health_profile.GetIrnProfileRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, health_profile.IrnProfile) + assert response.name == "name_value" + assert response.onboarding_status is True + assert response.enrollment_status is True + + +def test_get_irn_profile_field_headers(): + client = HealthProfileServiceClient( + 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 = health_profile.GetIrnProfileRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_irn_profile), "__call__") as call: + call.return_value = health_profile.IrnProfile() + client.get_irn_profile(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_irn_profile_field_headers_async(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = health_profile.GetIrnProfileRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_irn_profile), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.IrnProfile() + ) + await client.get_irn_profile(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_irn_profile_flattened(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_irn_profile), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = health_profile.IrnProfile() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_irn_profile( + 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_irn_profile_flattened_error(): + client = HealthProfileServiceClient( + 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_irn_profile( + health_profile.GetIrnProfileRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_irn_profile_flattened_async(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_irn_profile), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = health_profile.IrnProfile() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.IrnProfile() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_irn_profile( + 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_irn_profile_flattened_error_async(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_irn_profile( + health_profile.GetIrnProfileRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + health_profile.GetPairedDeviceRequest(), + {}, + ], +) +def test_get_paired_device(request_type, transport: str = "grpc"): + client = HealthProfileServiceClient( + 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_paired_device), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = health_profile.PairedDevice( + name="name_value", + device_type=health_profile.PairedDevice.DeviceType.TRACKER, + battery_status="battery_status_value", + battery_level=1394, + device_version="device_version_value", + mac_address="mac_address_value", + features=["features_value"], + ) + response = client.get_paired_device(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = health_profile.GetPairedDeviceRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, health_profile.PairedDevice) + assert response.name == "name_value" + assert response.device_type == health_profile.PairedDevice.DeviceType.TRACKER + assert response.battery_status == "battery_status_value" + assert response.battery_level == 1394 + assert response.device_version == "device_version_value" + assert response.mac_address == "mac_address_value" + assert response.features == ["features_value"] + + +def test_get_paired_device_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = health_profile.GetPairedDeviceRequest( + name="name_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_paired_device), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.get_paired_device(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.GetPairedDeviceRequest( + name="name_value", + ) + assert args[0] == request_msg + + +def test_get_paired_device_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_paired_device in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_paired_device] = ( + mock_rpc + ) + request = {} + client.get_paired_device(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_paired_device(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_get_paired_device_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.get_paired_device + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.get_paired_device + ] = mock_rpc + + request = {} + await client.get_paired_device(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.get_paired_device(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + health_profile.GetPairedDeviceRequest(), + {}, + ], +) +async def test_get_paired_device_async(request_type, transport: str = "grpc_asyncio"): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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_paired_device), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.PairedDevice( + name="name_value", + device_type=health_profile.PairedDevice.DeviceType.TRACKER, + battery_status="battery_status_value", + battery_level=1394, + device_version="device_version_value", + mac_address="mac_address_value", + features=["features_value"], + ) + ) + response = await client.get_paired_device(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = health_profile.GetPairedDeviceRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, health_profile.PairedDevice) + assert response.name == "name_value" + assert response.device_type == health_profile.PairedDevice.DeviceType.TRACKER + assert response.battery_status == "battery_status_value" + assert response.battery_level == 1394 + assert response.device_version == "device_version_value" + assert response.mac_address == "mac_address_value" + assert response.features == ["features_value"] + + +def test_get_paired_device_field_headers(): + client = HealthProfileServiceClient( + 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 = health_profile.GetPairedDeviceRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_paired_device), "__call__" + ) as call: + call.return_value = health_profile.PairedDevice() + client.get_paired_device(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_paired_device_field_headers_async(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = health_profile.GetPairedDeviceRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_paired_device), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.PairedDevice() + ) + await client.get_paired_device(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_paired_device_flattened(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_paired_device), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = health_profile.PairedDevice() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_paired_device( + 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_paired_device_flattened_error(): + client = HealthProfileServiceClient( + 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_paired_device( + health_profile.GetPairedDeviceRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_paired_device_flattened_async(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_paired_device), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = health_profile.PairedDevice() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.PairedDevice() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_paired_device( + 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_paired_device_flattened_error_async(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_paired_device( + health_profile.GetPairedDeviceRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + health_profile.ListPairedDevicesRequest(), + {}, + ], +) +def test_list_paired_devices(request_type, transport: str = "grpc"): + client = HealthProfileServiceClient( + 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_paired_devices), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = health_profile.ListPairedDevicesResponse( + next_page_token="next_page_token_value", + ) + response = client.list_paired_devices(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = health_profile.ListPairedDevicesRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListPairedDevicesPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_paired_devices_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = health_profile.ListPairedDevicesRequest( + parent="parent_value", + page_token="page_token_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_paired_devices), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.list_paired_devices(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.ListPairedDevicesRequest( + parent="parent_value", + page_token="page_token_value", + ) + assert args[0] == request_msg + + +def test_list_paired_devices_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_paired_devices in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.list_paired_devices] = ( + mock_rpc + ) + request = {} + client.list_paired_devices(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_paired_devices(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_list_paired_devices_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.list_paired_devices + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.list_paired_devices + ] = mock_rpc + + request = {} + await client.list_paired_devices(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.list_paired_devices(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + health_profile.ListPairedDevicesRequest(), + {}, + ], +) +async def test_list_paired_devices_async(request_type, transport: str = "grpc_asyncio"): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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_paired_devices), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.ListPairedDevicesResponse( + next_page_token="next_page_token_value", + ) + ) + response = await client.list_paired_devices(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = health_profile.ListPairedDevicesRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListPairedDevicesAsyncPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_paired_devices_field_headers(): + client = HealthProfileServiceClient( + 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 = health_profile.ListPairedDevicesRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_paired_devices), "__call__" + ) as call: + call.return_value = health_profile.ListPairedDevicesResponse() + client.list_paired_devices(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_paired_devices_field_headers_async(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = health_profile.ListPairedDevicesRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_paired_devices), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.ListPairedDevicesResponse() + ) + await client.list_paired_devices(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_paired_devices_flattened(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_paired_devices), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = health_profile.ListPairedDevicesResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_paired_devices( + 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_paired_devices_flattened_error(): + client = HealthProfileServiceClient( + 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_paired_devices( + health_profile.ListPairedDevicesRequest(), + parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_list_paired_devices_flattened_async(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_paired_devices), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = health_profile.ListPairedDevicesResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.ListPairedDevicesResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_paired_devices( + 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_paired_devices_flattened_error_async(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_paired_devices( + health_profile.ListPairedDevicesRequest(), + parent="parent_value", + ) + + +def test_list_paired_devices_pager(transport_name: str = "grpc"): + client = HealthProfileServiceClient( + 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_paired_devices), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + health_profile.ListPairedDevicesResponse( + paired_devices=[ + health_profile.PairedDevice(), + health_profile.PairedDevice(), + health_profile.PairedDevice(), + ], + next_page_token="abc", + ), + health_profile.ListPairedDevicesResponse( + paired_devices=[], + next_page_token="def", + ), + health_profile.ListPairedDevicesResponse( + paired_devices=[ + health_profile.PairedDevice(), + ], + next_page_token="ghi", + ), + health_profile.ListPairedDevicesResponse( + paired_devices=[ + health_profile.PairedDevice(), + health_profile.PairedDevice(), + ], + ), + RuntimeError, + ) + + expected_metadata = () + retry = retries.Retry() + timeout = 5 + expected_metadata = tuple(expected_metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_paired_devices(request={}, retry=retry, timeout=timeout) + + assert pager._metadata == expected_metadata + assert pager._retry == retry + assert pager._timeout == timeout + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, health_profile.PairedDevice) for i in results) + + +def test_list_paired_devices_pages(transport_name: str = "grpc"): + client = HealthProfileServiceClient( + 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_paired_devices), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + health_profile.ListPairedDevicesResponse( + paired_devices=[ + health_profile.PairedDevice(), + health_profile.PairedDevice(), + health_profile.PairedDevice(), + ], + next_page_token="abc", + ), + health_profile.ListPairedDevicesResponse( + paired_devices=[], + next_page_token="def", + ), + health_profile.ListPairedDevicesResponse( + paired_devices=[ + health_profile.PairedDevice(), + ], + next_page_token="ghi", + ), + health_profile.ListPairedDevicesResponse( + paired_devices=[ + health_profile.PairedDevice(), + health_profile.PairedDevice(), + ], + ), + RuntimeError, + ) + pages = list(client.list_paired_devices(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_paired_devices_async_pager(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_paired_devices), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + health_profile.ListPairedDevicesResponse( + paired_devices=[ + health_profile.PairedDevice(), + health_profile.PairedDevice(), + health_profile.PairedDevice(), + ], + next_page_token="abc", + ), + health_profile.ListPairedDevicesResponse( + paired_devices=[], + next_page_token="def", + ), + health_profile.ListPairedDevicesResponse( + paired_devices=[ + health_profile.PairedDevice(), + ], + next_page_token="ghi", + ), + health_profile.ListPairedDevicesResponse( + paired_devices=[ + health_profile.PairedDevice(), + health_profile.PairedDevice(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_paired_devices( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, health_profile.PairedDevice) for i in responses) + + +@pytest.mark.asyncio +async def test_list_paired_devices_async_pages(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_paired_devices), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + health_profile.ListPairedDevicesResponse( + paired_devices=[ + health_profile.PairedDevice(), + health_profile.PairedDevice(), + health_profile.PairedDevice(), + ], + next_page_token="abc", + ), + health_profile.ListPairedDevicesResponse( + paired_devices=[], + next_page_token="def", + ), + health_profile.ListPairedDevicesResponse( + paired_devices=[ + health_profile.PairedDevice(), + ], + next_page_token="ghi", + ), + health_profile.ListPairedDevicesResponse( + paired_devices=[ + health_profile.PairedDevice(), + health_profile.PairedDevice(), + ], + ), + RuntimeError, + ) + pages = [] + async for page_ in (await client.list_paired_devices(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_get_profile_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_profile in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_profile] = mock_rpc + + request = {} + client.get_profile(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_profile(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_profile_rest_required_fields( + request_type=health_profile.GetProfileRequest, +): + transport_class = transports.HealthProfileServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_profile._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_profile._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = health_profile.Profile() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = health_profile.Profile.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_profile(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_get_profile_rest_unset_required_fields(): + transport = transports.HealthProfileServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_profile._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_profile_rest_flattened(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = health_profile.Profile() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "users/sample1/profile"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = health_profile.Profile.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_profile(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v4/{name=users/*/profile}" % client.transport._host, args[1] + ) + + +def test_get_profile_rest_flattened_error(transport: str = "rest"): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_profile( + health_profile.GetProfileRequest(), + name="name_value", + ) + + +def test_update_profile_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.update_profile in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.update_profile] = mock_rpc + + request = {} + client.update_profile(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.update_profile(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_update_profile_rest_required_fields( + request_type=health_profile.UpdateProfileRequest, +): + transport_class = transports.HealthProfileServiceRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_profile._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_profile._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = health_profile.Profile() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = health_profile.Profile.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.update_profile(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_update_profile_rest_unset_required_fields(): + transport = transports.HealthProfileServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_profile._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("profile",))) + + +def test_update_profile_rest_flattened(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = health_profile.Profile() + + # get arguments that satisfy an http rule for this method + sample_request = {"profile": {"name": "users/sample1/profile"}} + + # get truthy value for each flattened field + mock_args = dict( + profile=health_profile.Profile(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = health_profile.Profile.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.update_profile(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v4/{profile.name=users/*/profile}" % client.transport._host, args[1] + ) + + +def test_update_profile_rest_flattened_error(transport: str = "rest"): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_profile( + health_profile.UpdateProfileRequest(), + profile=health_profile.Profile(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_get_settings_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_settings in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_settings] = mock_rpc + + request = {} + client.get_settings(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_settings(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_settings_rest_required_fields( + request_type=health_profile.GetSettingsRequest, +): + transport_class = transports.HealthProfileServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_settings._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_settings._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = health_profile.Settings() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = health_profile.Settings.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_settings(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_get_settings_rest_unset_required_fields(): + transport = transports.HealthProfileServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_settings._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_settings_rest_flattened(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = health_profile.Settings() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "users/sample1/settings"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = health_profile.Settings.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_settings(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v4/{name=users/*/settings}" % client.transport._host, args[1] + ) + + +def test_get_settings_rest_flattened_error(transport: str = "rest"): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_settings( + health_profile.GetSettingsRequest(), + name="name_value", + ) + + +def test_update_settings_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.update_settings in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.update_settings] = mock_rpc + + request = {} + client.update_settings(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.update_settings(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_update_settings_rest_required_fields( + request_type=health_profile.UpdateSettingsRequest, +): + transport_class = transports.HealthProfileServiceRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_settings._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_settings._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = health_profile.Settings() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = health_profile.Settings.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.update_settings(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_update_settings_rest_unset_required_fields(): + transport = transports.HealthProfileServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_settings._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("settings",))) + + +def test_update_settings_rest_flattened(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = health_profile.Settings() + + # get arguments that satisfy an http rule for this method + sample_request = {"settings": {"name": "users/sample1/settings"}} + + # get truthy value for each flattened field + mock_args = dict( + settings=health_profile.Settings(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = health_profile.Settings.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.update_settings(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v4/{settings.name=users/*/settings}" % client.transport._host, args[1] + ) + + +def test_update_settings_rest_flattened_error(transport: str = "rest"): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_settings( + health_profile.UpdateSettingsRequest(), + settings=health_profile.Settings(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_get_identity_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_identity in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_identity] = mock_rpc + + request = {} + client.get_identity(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_identity(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_identity_rest_required_fields( + request_type=health_profile.GetIdentityRequest, +): + transport_class = transports.HealthProfileServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_identity._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_identity._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = health_profile.Identity() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = health_profile.Identity.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_identity(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_get_identity_rest_unset_required_fields(): + transport = transports.HealthProfileServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_identity._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_identity_rest_flattened(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = health_profile.Identity() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "users/sample1/identity"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = health_profile.Identity.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_identity(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v4/{name=users/*/identity}" % client.transport._host, args[1] + ) + + +def test_get_identity_rest_flattened_error(transport: str = "rest"): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_identity( + health_profile.GetIdentityRequest(), + name="name_value", + ) + + +def test_get_irn_profile_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_irn_profile in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_irn_profile] = mock_rpc + + request = {} + client.get_irn_profile(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_irn_profile(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_irn_profile_rest_required_fields( + request_type=health_profile.GetIrnProfileRequest, +): + transport_class = transports.HealthProfileServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_irn_profile._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_irn_profile._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = health_profile.IrnProfile() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = health_profile.IrnProfile.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_irn_profile(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_get_irn_profile_rest_unset_required_fields(): + transport = transports.HealthProfileServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_irn_profile._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_irn_profile_rest_flattened(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = health_profile.IrnProfile() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "users/sample1/irnProfile"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = health_profile.IrnProfile.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_irn_profile(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v4/{name=users/*/irnProfile}" % client.transport._host, args[1] + ) + + +def test_get_irn_profile_rest_flattened_error(transport: str = "rest"): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_irn_profile( + health_profile.GetIrnProfileRequest(), + name="name_value", + ) + + +def test_get_paired_device_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_paired_device in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_paired_device] = ( + mock_rpc + ) + + request = {} + client.get_paired_device(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_paired_device(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_paired_device_rest_required_fields( + request_type=health_profile.GetPairedDeviceRequest, +): + transport_class = transports.HealthProfileServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_paired_device._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_paired_device._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = health_profile.PairedDevice() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = health_profile.PairedDevice.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_paired_device(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_get_paired_device_rest_unset_required_fields(): + transport = transports.HealthProfileServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_paired_device._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_paired_device_rest_flattened(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = health_profile.PairedDevice() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "users/sample1/pairedDevices/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = health_profile.PairedDevice.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_paired_device(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v4/{name=users/*/pairedDevices/*}" % client.transport._host, args[1] + ) + + +def test_get_paired_device_rest_flattened_error(transport: str = "rest"): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_paired_device( + health_profile.GetPairedDeviceRequest(), + name="name_value", + ) + + +def test_list_paired_devices_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_paired_devices in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.list_paired_devices] = ( + mock_rpc + ) + + request = {} + client.list_paired_devices(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_paired_devices(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_paired_devices_rest_required_fields( + request_type=health_profile.ListPairedDevicesRequest, +): + transport_class = transports.HealthProfileServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_paired_devices._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_paired_devices._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = health_profile.ListPairedDevicesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = health_profile.ListPairedDevicesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_paired_devices(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_list_paired_devices_rest_unset_required_fields(): + transport = transports.HealthProfileServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_paired_devices._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +def test_list_paired_devices_rest_flattened(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = health_profile.ListPairedDevicesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "users/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = health_profile.ListPairedDevicesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_paired_devices(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v4/{parent=users/*}/pairedDevices" % client.transport._host, args[1] + ) + + +def test_list_paired_devices_rest_flattened_error(transport: str = "rest"): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_paired_devices( + health_profile.ListPairedDevicesRequest(), + parent="parent_value", + ) + + +def test_list_paired_devices_rest_pager(transport: str = "rest"): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + health_profile.ListPairedDevicesResponse( + paired_devices=[ + health_profile.PairedDevice(), + health_profile.PairedDevice(), + health_profile.PairedDevice(), + ], + next_page_token="abc", + ), + health_profile.ListPairedDevicesResponse( + paired_devices=[], + next_page_token="def", + ), + health_profile.ListPairedDevicesResponse( + paired_devices=[ + health_profile.PairedDevice(), + ], + next_page_token="ghi", + ), + health_profile.ListPairedDevicesResponse( + paired_devices=[ + health_profile.PairedDevice(), + health_profile.PairedDevice(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + health_profile.ListPairedDevicesResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "users/sample1"} + + pager = client.list_paired_devices(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, health_profile.PairedDevice) for i in results) + + pages = list(client.list_paired_devices(request=sample_request).pages) + 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.HealthProfileServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.HealthProfileServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = HealthProfileServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.HealthProfileServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = HealthProfileServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = HealthProfileServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.HealthProfileServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = HealthProfileServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.HealthProfileServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = HealthProfileServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.HealthProfileServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.HealthProfileServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.HealthProfileServiceGrpcTransport, + transports.HealthProfileServiceGrpcAsyncIOTransport, + transports.HealthProfileServiceRestTransport, + ], +) +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_kind_grpc(): + transport = HealthProfileServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_profile_empty_call_grpc(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_profile), "__call__") as call: + call.return_value = health_profile.Profile() + client.get_profile(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.GetProfileRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_profile_empty_call_grpc(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_profile), "__call__") as call: + call.return_value = health_profile.Profile() + client.update_profile(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.UpdateProfileRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_settings_empty_call_grpc(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_settings), "__call__") as call: + call.return_value = health_profile.Settings() + client.get_settings(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.GetSettingsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_settings_empty_call_grpc(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_settings), "__call__") as call: + call.return_value = health_profile.Settings() + client.update_settings(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.UpdateSettingsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_identity_empty_call_grpc(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_identity), "__call__") as call: + call.return_value = health_profile.Identity() + client.get_identity(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.GetIdentityRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_irn_profile_empty_call_grpc(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_irn_profile), "__call__") as call: + call.return_value = health_profile.IrnProfile() + client.get_irn_profile(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.GetIrnProfileRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_paired_device_empty_call_grpc(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_paired_device), "__call__" + ) as call: + call.return_value = health_profile.PairedDevice() + client.get_paired_device(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.GetPairedDeviceRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_paired_devices_empty_call_grpc(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_paired_devices), "__call__" + ) as call: + call.return_value = health_profile.ListPairedDevicesResponse() + client.list_paired_devices(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.ListPairedDevicesRequest() + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = HealthProfileServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_profile_empty_call_grpc_asyncio(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_profile), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.Profile( + name="name_value", + age=301, + user_configured_walking_stride_length_mm=4244, + user_configured_running_stride_length_mm=4264, + auto_walking_stride_length_mm=3081, + auto_running_stride_length_mm=3101, + ) + ) + await client.get_profile(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.GetProfileRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_profile_empty_call_grpc_asyncio(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_profile), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.Profile( + name="name_value", + age=301, + user_configured_walking_stride_length_mm=4244, + user_configured_running_stride_length_mm=4264, + auto_walking_stride_length_mm=3081, + auto_running_stride_length_mm=3101, + ) + ) + await client.update_profile(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.UpdateProfileRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_settings_empty_call_grpc_asyncio(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_settings), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.Settings( + name="name_value", + auto_stride_enabled=True, + distance_unit=health_profile.Settings.DistanceUnit.DISTANCE_UNIT_MILES, + glucose_unit=health_profile.Settings.GlucoseUnit.GLUCOSE_UNIT_MG_DL, + height_unit=health_profile.Settings.HeightUnit.HEIGHT_UNIT_INCHES, + language_locale="language_locale_value", + stride_length_walking_type=health_profile.Settings.StrideLengthType.STRIDE_LENGTH_TYPE_DEFAULT, + stride_length_running_type=health_profile.Settings.StrideLengthType.STRIDE_LENGTH_TYPE_DEFAULT, + swim_unit=health_profile.Settings.SwimUnit.SWIM_UNIT_METERS, + temperature_unit=health_profile.Settings.TemperatureUnit.TEMPERATURE_UNIT_CELSIUS, + time_zone="time_zone_value", + weight_unit=health_profile.Settings.WeightUnit.WEIGHT_UNIT_POUNDS, + water_unit=health_profile.Settings.WaterUnit.WATER_UNIT_ML, + food_language_code="food_language_code_value", + ) + ) + await client.get_settings(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.GetSettingsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_settings_empty_call_grpc_asyncio(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_settings), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.Settings( + name="name_value", + auto_stride_enabled=True, + distance_unit=health_profile.Settings.DistanceUnit.DISTANCE_UNIT_MILES, + glucose_unit=health_profile.Settings.GlucoseUnit.GLUCOSE_UNIT_MG_DL, + height_unit=health_profile.Settings.HeightUnit.HEIGHT_UNIT_INCHES, + language_locale="language_locale_value", + stride_length_walking_type=health_profile.Settings.StrideLengthType.STRIDE_LENGTH_TYPE_DEFAULT, + stride_length_running_type=health_profile.Settings.StrideLengthType.STRIDE_LENGTH_TYPE_DEFAULT, + swim_unit=health_profile.Settings.SwimUnit.SWIM_UNIT_METERS, + temperature_unit=health_profile.Settings.TemperatureUnit.TEMPERATURE_UNIT_CELSIUS, + time_zone="time_zone_value", + weight_unit=health_profile.Settings.WeightUnit.WEIGHT_UNIT_POUNDS, + water_unit=health_profile.Settings.WaterUnit.WATER_UNIT_ML, + food_language_code="food_language_code_value", + ) + ) + await client.update_settings(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.UpdateSettingsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_identity_empty_call_grpc_asyncio(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_identity), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.Identity( + name="name_value", + legacy_user_id="legacy_user_id_value", + health_user_id="health_user_id_value", + ) + ) + await client.get_identity(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.GetIdentityRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_irn_profile_empty_call_grpc_asyncio(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_irn_profile), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.IrnProfile( + name="name_value", + onboarding_status=True, + enrollment_status=True, + ) + ) + await client.get_irn_profile(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.GetIrnProfileRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_paired_device_empty_call_grpc_asyncio(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_paired_device), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.PairedDevice( + name="name_value", + device_type=health_profile.PairedDevice.DeviceType.TRACKER, + battery_status="battery_status_value", + battery_level=1394, + device_version="device_version_value", + mac_address="mac_address_value", + features=["features_value"], + ) + ) + await client.get_paired_device(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.GetPairedDeviceRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_paired_devices_empty_call_grpc_asyncio(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_paired_devices), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + health_profile.ListPairedDevicesResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_paired_devices(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.ListPairedDevicesRequest() + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = HealthProfileServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_profile_rest_bad_request(request_type=health_profile.GetProfileRequest): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "users/sample1/profile"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_profile(request) + + +@pytest.mark.parametrize( + "request_type", + [ + health_profile.GetProfileRequest, + dict, + ], +) +def test_get_profile_rest_call_success(request_type): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "users/sample1/profile"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = health_profile.Profile( + name="name_value", + age=301, + user_configured_walking_stride_length_mm=4244, + user_configured_running_stride_length_mm=4264, + auto_walking_stride_length_mm=3081, + auto_running_stride_length_mm=3101, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = health_profile.Profile.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_profile(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, health_profile.Profile) + assert response.name == "name_value" + assert response.age == 301 + assert response.user_configured_walking_stride_length_mm == 4244 + assert response.user_configured_running_stride_length_mm == 4264 + assert response.auto_walking_stride_length_mm == 3081 + assert response.auto_running_stride_length_mm == 3101 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_profile_rest_interceptors(null_interceptor): + transport = transports.HealthProfileServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.HealthProfileServiceRestInterceptor(), + ) + client = HealthProfileServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.HealthProfileServiceRestInterceptor, "post_get_profile" + ) as post, + mock.patch.object( + transports.HealthProfileServiceRestInterceptor, + "post_get_profile_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.HealthProfileServiceRestInterceptor, "pre_get_profile" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = health_profile.GetProfileRequest.pb( + health_profile.GetProfileRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = health_profile.Profile.to_json(health_profile.Profile()) + req.return_value.content = return_value + + request = health_profile.GetProfileRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = health_profile.Profile() + post_with_metadata.return_value = health_profile.Profile(), metadata + + client.get_profile( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_update_profile_rest_bad_request( + request_type=health_profile.UpdateProfileRequest, +): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"profile": {"name": "users/sample1/profile"}} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.update_profile(request) + + +@pytest.mark.parametrize( + "request_type", + [ + health_profile.UpdateProfileRequest, + dict, + ], +) +def test_update_profile_rest_call_success(request_type): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"profile": {"name": "users/sample1/profile"}} + request_init["profile"] = { + "name": "users/sample1/profile", + "age": 301, + "membership_start_date": {"year": 433, "month": 550, "day": 318}, + "user_configured_walking_stride_length_mm": 4244, + "user_configured_running_stride_length_mm": 4264, + "auto_walking_stride_length_mm": 3081, + "auto_running_stride_length_mm": 3101, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = health_profile.UpdateProfileRequest.meta.fields["profile"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["profile"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["profile"][field])): + del request_init["profile"][field][i][subfield] + else: + del request_init["profile"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = health_profile.Profile( + name="name_value", + age=301, + user_configured_walking_stride_length_mm=4244, + user_configured_running_stride_length_mm=4264, + auto_walking_stride_length_mm=3081, + auto_running_stride_length_mm=3101, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = health_profile.Profile.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.update_profile(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, health_profile.Profile) + assert response.name == "name_value" + assert response.age == 301 + assert response.user_configured_walking_stride_length_mm == 4244 + assert response.user_configured_running_stride_length_mm == 4264 + assert response.auto_walking_stride_length_mm == 3081 + assert response.auto_running_stride_length_mm == 3101 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_profile_rest_interceptors(null_interceptor): + transport = transports.HealthProfileServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.HealthProfileServiceRestInterceptor(), + ) + client = HealthProfileServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.HealthProfileServiceRestInterceptor, "post_update_profile" + ) as post, + mock.patch.object( + transports.HealthProfileServiceRestInterceptor, + "post_update_profile_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.HealthProfileServiceRestInterceptor, "pre_update_profile" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = health_profile.UpdateProfileRequest.pb( + health_profile.UpdateProfileRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = health_profile.Profile.to_json(health_profile.Profile()) + req.return_value.content = return_value + + request = health_profile.UpdateProfileRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = health_profile.Profile() + post_with_metadata.return_value = health_profile.Profile(), metadata + + client.update_profile( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_settings_rest_bad_request(request_type=health_profile.GetSettingsRequest): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "users/sample1/settings"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_settings(request) + + +@pytest.mark.parametrize( + "request_type", + [ + health_profile.GetSettingsRequest, + dict, + ], +) +def test_get_settings_rest_call_success(request_type): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "users/sample1/settings"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = health_profile.Settings( + name="name_value", + auto_stride_enabled=True, + distance_unit=health_profile.Settings.DistanceUnit.DISTANCE_UNIT_MILES, + glucose_unit=health_profile.Settings.GlucoseUnit.GLUCOSE_UNIT_MG_DL, + height_unit=health_profile.Settings.HeightUnit.HEIGHT_UNIT_INCHES, + language_locale="language_locale_value", + stride_length_walking_type=health_profile.Settings.StrideLengthType.STRIDE_LENGTH_TYPE_DEFAULT, + stride_length_running_type=health_profile.Settings.StrideLengthType.STRIDE_LENGTH_TYPE_DEFAULT, + swim_unit=health_profile.Settings.SwimUnit.SWIM_UNIT_METERS, + temperature_unit=health_profile.Settings.TemperatureUnit.TEMPERATURE_UNIT_CELSIUS, + time_zone="time_zone_value", + weight_unit=health_profile.Settings.WeightUnit.WEIGHT_UNIT_POUNDS, + water_unit=health_profile.Settings.WaterUnit.WATER_UNIT_ML, + food_language_code="food_language_code_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = health_profile.Settings.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_settings(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, health_profile.Settings) + assert response.name == "name_value" + assert response.auto_stride_enabled is True + assert ( + response.distance_unit + == health_profile.Settings.DistanceUnit.DISTANCE_UNIT_MILES + ) + assert ( + response.glucose_unit == health_profile.Settings.GlucoseUnit.GLUCOSE_UNIT_MG_DL + ) + assert response.height_unit == health_profile.Settings.HeightUnit.HEIGHT_UNIT_INCHES + assert response.language_locale == "language_locale_value" + assert ( + response.stride_length_walking_type + == health_profile.Settings.StrideLengthType.STRIDE_LENGTH_TYPE_DEFAULT + ) + assert ( + response.stride_length_running_type + == health_profile.Settings.StrideLengthType.STRIDE_LENGTH_TYPE_DEFAULT + ) + assert response.swim_unit == health_profile.Settings.SwimUnit.SWIM_UNIT_METERS + assert ( + response.temperature_unit + == health_profile.Settings.TemperatureUnit.TEMPERATURE_UNIT_CELSIUS + ) + assert response.time_zone == "time_zone_value" + assert response.weight_unit == health_profile.Settings.WeightUnit.WEIGHT_UNIT_POUNDS + assert response.water_unit == health_profile.Settings.WaterUnit.WATER_UNIT_ML + assert response.food_language_code == "food_language_code_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_settings_rest_interceptors(null_interceptor): + transport = transports.HealthProfileServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.HealthProfileServiceRestInterceptor(), + ) + client = HealthProfileServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.HealthProfileServiceRestInterceptor, "post_get_settings" + ) as post, + mock.patch.object( + transports.HealthProfileServiceRestInterceptor, + "post_get_settings_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.HealthProfileServiceRestInterceptor, "pre_get_settings" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = health_profile.GetSettingsRequest.pb( + health_profile.GetSettingsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = health_profile.Settings.to_json(health_profile.Settings()) + req.return_value.content = return_value + + request = health_profile.GetSettingsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = health_profile.Settings() + post_with_metadata.return_value = health_profile.Settings(), metadata + + client.get_settings( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_update_settings_rest_bad_request( + request_type=health_profile.UpdateSettingsRequest, +): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"settings": {"name": "users/sample1/settings"}} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.update_settings(request) + + +@pytest.mark.parametrize( + "request_type", + [ + health_profile.UpdateSettingsRequest, + dict, + ], +) +def test_update_settings_rest_call_success(request_type): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"settings": {"name": "users/sample1/settings"}} + request_init["settings"] = { + "name": "users/sample1/settings", + "auto_stride_enabled": True, + "distance_unit": 1, + "glucose_unit": 1, + "height_unit": 1, + "language_locale": "language_locale_value", + "utc_offset": {"seconds": 751, "nanos": 543}, + "stride_length_walking_type": 1, + "stride_length_running_type": 1, + "swim_unit": 1, + "temperature_unit": 1, + "time_zone": "time_zone_value", + "weight_unit": 1, + "water_unit": 1, + "food_language_code": "food_language_code_value", + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = health_profile.UpdateSettingsRequest.meta.fields["settings"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["settings"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["settings"][field])): + del request_init["settings"][field][i][subfield] + else: + del request_init["settings"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = health_profile.Settings( + name="name_value", + auto_stride_enabled=True, + distance_unit=health_profile.Settings.DistanceUnit.DISTANCE_UNIT_MILES, + glucose_unit=health_profile.Settings.GlucoseUnit.GLUCOSE_UNIT_MG_DL, + height_unit=health_profile.Settings.HeightUnit.HEIGHT_UNIT_INCHES, + language_locale="language_locale_value", + stride_length_walking_type=health_profile.Settings.StrideLengthType.STRIDE_LENGTH_TYPE_DEFAULT, + stride_length_running_type=health_profile.Settings.StrideLengthType.STRIDE_LENGTH_TYPE_DEFAULT, + swim_unit=health_profile.Settings.SwimUnit.SWIM_UNIT_METERS, + temperature_unit=health_profile.Settings.TemperatureUnit.TEMPERATURE_UNIT_CELSIUS, + time_zone="time_zone_value", + weight_unit=health_profile.Settings.WeightUnit.WEIGHT_UNIT_POUNDS, + water_unit=health_profile.Settings.WaterUnit.WATER_UNIT_ML, + food_language_code="food_language_code_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = health_profile.Settings.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.update_settings(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, health_profile.Settings) + assert response.name == "name_value" + assert response.auto_stride_enabled is True + assert ( + response.distance_unit + == health_profile.Settings.DistanceUnit.DISTANCE_UNIT_MILES + ) + assert ( + response.glucose_unit == health_profile.Settings.GlucoseUnit.GLUCOSE_UNIT_MG_DL + ) + assert response.height_unit == health_profile.Settings.HeightUnit.HEIGHT_UNIT_INCHES + assert response.language_locale == "language_locale_value" + assert ( + response.stride_length_walking_type + == health_profile.Settings.StrideLengthType.STRIDE_LENGTH_TYPE_DEFAULT + ) + assert ( + response.stride_length_running_type + == health_profile.Settings.StrideLengthType.STRIDE_LENGTH_TYPE_DEFAULT + ) + assert response.swim_unit == health_profile.Settings.SwimUnit.SWIM_UNIT_METERS + assert ( + response.temperature_unit + == health_profile.Settings.TemperatureUnit.TEMPERATURE_UNIT_CELSIUS + ) + assert response.time_zone == "time_zone_value" + assert response.weight_unit == health_profile.Settings.WeightUnit.WEIGHT_UNIT_POUNDS + assert response.water_unit == health_profile.Settings.WaterUnit.WATER_UNIT_ML + assert response.food_language_code == "food_language_code_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_settings_rest_interceptors(null_interceptor): + transport = transports.HealthProfileServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.HealthProfileServiceRestInterceptor(), + ) + client = HealthProfileServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.HealthProfileServiceRestInterceptor, "post_update_settings" + ) as post, + mock.patch.object( + transports.HealthProfileServiceRestInterceptor, + "post_update_settings_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.HealthProfileServiceRestInterceptor, "pre_update_settings" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = health_profile.UpdateSettingsRequest.pb( + health_profile.UpdateSettingsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = health_profile.Settings.to_json(health_profile.Settings()) + req.return_value.content = return_value + + request = health_profile.UpdateSettingsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = health_profile.Settings() + post_with_metadata.return_value = health_profile.Settings(), metadata + + client.update_settings( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_identity_rest_bad_request(request_type=health_profile.GetIdentityRequest): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "users/sample1/identity"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_identity(request) + + +@pytest.mark.parametrize( + "request_type", + [ + health_profile.GetIdentityRequest, + dict, + ], +) +def test_get_identity_rest_call_success(request_type): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "users/sample1/identity"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = health_profile.Identity( + name="name_value", + legacy_user_id="legacy_user_id_value", + health_user_id="health_user_id_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = health_profile.Identity.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_identity(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, health_profile.Identity) + assert response.name == "name_value" + assert response.legacy_user_id == "legacy_user_id_value" + assert response.health_user_id == "health_user_id_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_identity_rest_interceptors(null_interceptor): + transport = transports.HealthProfileServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.HealthProfileServiceRestInterceptor(), + ) + client = HealthProfileServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.HealthProfileServiceRestInterceptor, "post_get_identity" + ) as post, + mock.patch.object( + transports.HealthProfileServiceRestInterceptor, + "post_get_identity_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.HealthProfileServiceRestInterceptor, "pre_get_identity" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = health_profile.GetIdentityRequest.pb( + health_profile.GetIdentityRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = health_profile.Identity.to_json(health_profile.Identity()) + req.return_value.content = return_value + + request = health_profile.GetIdentityRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = health_profile.Identity() + post_with_metadata.return_value = health_profile.Identity(), metadata + + client.get_identity( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_irn_profile_rest_bad_request( + request_type=health_profile.GetIrnProfileRequest, +): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "users/sample1/irnProfile"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_irn_profile(request) + + +@pytest.mark.parametrize( + "request_type", + [ + health_profile.GetIrnProfileRequest, + dict, + ], +) +def test_get_irn_profile_rest_call_success(request_type): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "users/sample1/irnProfile"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = health_profile.IrnProfile( + name="name_value", + onboarding_status=True, + enrollment_status=True, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = health_profile.IrnProfile.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_irn_profile(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, health_profile.IrnProfile) + assert response.name == "name_value" + assert response.onboarding_status is True + assert response.enrollment_status is True + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_irn_profile_rest_interceptors(null_interceptor): + transport = transports.HealthProfileServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.HealthProfileServiceRestInterceptor(), + ) + client = HealthProfileServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.HealthProfileServiceRestInterceptor, "post_get_irn_profile" + ) as post, + mock.patch.object( + transports.HealthProfileServiceRestInterceptor, + "post_get_irn_profile_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.HealthProfileServiceRestInterceptor, "pre_get_irn_profile" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = health_profile.GetIrnProfileRequest.pb( + health_profile.GetIrnProfileRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = health_profile.IrnProfile.to_json(health_profile.IrnProfile()) + req.return_value.content = return_value + + request = health_profile.GetIrnProfileRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = health_profile.IrnProfile() + post_with_metadata.return_value = health_profile.IrnProfile(), metadata + + client.get_irn_profile( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_paired_device_rest_bad_request( + request_type=health_profile.GetPairedDeviceRequest, +): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "users/sample1/pairedDevices/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_paired_device(request) + + +@pytest.mark.parametrize( + "request_type", + [ + health_profile.GetPairedDeviceRequest, + dict, + ], +) +def test_get_paired_device_rest_call_success(request_type): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "users/sample1/pairedDevices/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = health_profile.PairedDevice( + name="name_value", + device_type=health_profile.PairedDevice.DeviceType.TRACKER, + battery_status="battery_status_value", + battery_level=1394, + device_version="device_version_value", + mac_address="mac_address_value", + features=["features_value"], + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = health_profile.PairedDevice.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_paired_device(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, health_profile.PairedDevice) + assert response.name == "name_value" + assert response.device_type == health_profile.PairedDevice.DeviceType.TRACKER + assert response.battery_status == "battery_status_value" + assert response.battery_level == 1394 + assert response.device_version == "device_version_value" + assert response.mac_address == "mac_address_value" + assert response.features == ["features_value"] + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_paired_device_rest_interceptors(null_interceptor): + transport = transports.HealthProfileServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.HealthProfileServiceRestInterceptor(), + ) + client = HealthProfileServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.HealthProfileServiceRestInterceptor, "post_get_paired_device" + ) as post, + mock.patch.object( + transports.HealthProfileServiceRestInterceptor, + "post_get_paired_device_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.HealthProfileServiceRestInterceptor, "pre_get_paired_device" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = health_profile.GetPairedDeviceRequest.pb( + health_profile.GetPairedDeviceRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = health_profile.PairedDevice.to_json( + health_profile.PairedDevice() + ) + req.return_value.content = return_value + + request = health_profile.GetPairedDeviceRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = health_profile.PairedDevice() + post_with_metadata.return_value = health_profile.PairedDevice(), metadata + + client.get_paired_device( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_paired_devices_rest_bad_request( + request_type=health_profile.ListPairedDevicesRequest, +): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "users/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_paired_devices(request) + + +@pytest.mark.parametrize( + "request_type", + [ + health_profile.ListPairedDevicesRequest, + dict, + ], +) +def test_list_paired_devices_rest_call_success(request_type): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "users/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = health_profile.ListPairedDevicesResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = health_profile.ListPairedDevicesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_paired_devices(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListPairedDevicesPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_paired_devices_rest_interceptors(null_interceptor): + transport = transports.HealthProfileServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.HealthProfileServiceRestInterceptor(), + ) + client = HealthProfileServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.HealthProfileServiceRestInterceptor, "post_list_paired_devices" + ) as post, + mock.patch.object( + transports.HealthProfileServiceRestInterceptor, + "post_list_paired_devices_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.HealthProfileServiceRestInterceptor, "pre_list_paired_devices" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = health_profile.ListPairedDevicesRequest.pb( + health_profile.ListPairedDevicesRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = health_profile.ListPairedDevicesResponse.to_json( + health_profile.ListPairedDevicesResponse() + ) + req.return_value.content = return_value + + request = health_profile.ListPairedDevicesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = health_profile.ListPairedDevicesResponse() + post_with_metadata.return_value = ( + health_profile.ListPairedDevicesResponse(), + metadata, + ) + + client.list_paired_devices( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_initialize_client_w_rest(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_profile_empty_call_rest(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_profile), "__call__") as call: + client.get_profile(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.GetProfileRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_profile_empty_call_rest(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_profile), "__call__") as call: + client.update_profile(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.UpdateProfileRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_settings_empty_call_rest(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_settings), "__call__") as call: + client.get_settings(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.GetSettingsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_settings_empty_call_rest(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_settings), "__call__") as call: + client.update_settings(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.UpdateSettingsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_identity_empty_call_rest(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_identity), "__call__") as call: + client.get_identity(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.GetIdentityRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_irn_profile_empty_call_rest(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_irn_profile), "__call__") as call: + client.get_irn_profile(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.GetIrnProfileRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_paired_device_empty_call_rest(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_paired_device), "__call__" + ) as call: + client.get_paired_device(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.GetPairedDeviceRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_paired_devices_empty_call_rest(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_paired_devices), "__call__" + ) as call: + client.list_paired_devices(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = health_profile.ListPairedDevicesRequest() + assert args[0] == request_msg + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.HealthProfileServiceGrpcTransport, + ) + + +def test_health_profile_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.HealthProfileServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_health_profile_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.devicesandservices.health_v4.services.health_profile_service.transports.HealthProfileServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.HealthProfileServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "get_profile", + "update_profile", + "get_settings", + "update_settings", + "get_identity", + "get_irn_profile", + "get_paired_device", + "list_paired_devices", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_health_profile_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.devicesandservices.health_v4.services.health_profile_service.transports.HealthProfileServiceTransport._prep_wrapped_messages" + ) as Transport, + ): + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.HealthProfileServiceTransport( + 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/googlehealth.activity_and_fitness.readonly", + "https://www.googleapis.com/auth/googlehealth.ecg.readonly", + "https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.readonly", + "https://www.googleapis.com/auth/googlehealth.irn.readonly", + "https://www.googleapis.com/auth/googlehealth.profile.readonly", + "https://www.googleapis.com/auth/googlehealth.settings.readonly", + "https://www.googleapis.com/auth/googlehealth.sleep.readonly", + ), + quota_project_id="octopus", + ) + + +def test_health_profile_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.devicesandservices.health_v4.services.health_profile_service.transports.HealthProfileServiceTransport._prep_wrapped_messages" + ) as Transport, + ): + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.HealthProfileServiceTransport() + adc.assert_called_once() + + +def test_health_profile_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) + HealthProfileServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + "https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly", + "https://www.googleapis.com/auth/googlehealth.ecg.readonly", + "https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.readonly", + "https://www.googleapis.com/auth/googlehealth.irn.readonly", + "https://www.googleapis.com/auth/googlehealth.profile.readonly", + "https://www.googleapis.com/auth/googlehealth.settings.readonly", + "https://www.googleapis.com/auth/googlehealth.sleep.readonly", + ), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.HealthProfileServiceGrpcTransport, + transports.HealthProfileServiceGrpcAsyncIOTransport, + ], +) +def test_health_profile_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/googlehealth.activity_and_fitness.readonly", + "https://www.googleapis.com/auth/googlehealth.ecg.readonly", + "https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.readonly", + "https://www.googleapis.com/auth/googlehealth.irn.readonly", + "https://www.googleapis.com/auth/googlehealth.profile.readonly", + "https://www.googleapis.com/auth/googlehealth.settings.readonly", + "https://www.googleapis.com/auth/googlehealth.sleep.readonly", + ), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.HealthProfileServiceGrpcTransport, + transports.HealthProfileServiceGrpcAsyncIOTransport, + transports.HealthProfileServiceRestTransport, + ], +) +def test_health_profile_service_transport_auth_gdch_credentials(transport_class): + host = "https://language.com" + api_audience_tests = [None, "https://language2.com"] + api_audience_expect = [host, "https://language2.com"] + for t, e in zip(api_audience_tests, api_audience_expect): + with mock.patch.object(google.auth, "default", autospec=True) as adc: + gdch_mock = mock.MagicMock() + type(gdch_mock).with_gdch_audience = mock.PropertyMock( + return_value=gdch_mock + ) + adc.return_value = (gdch_mock, None) + transport_class(host=host, api_audience=t) + gdch_mock.with_gdch_audience.assert_called_once_with(e) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.HealthProfileServiceGrpcTransport, grpc_helpers), + (transports.HealthProfileServiceGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +def test_health_profile_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( + "health.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + "https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly", + "https://www.googleapis.com/auth/googlehealth.ecg.readonly", + "https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.readonly", + "https://www.googleapis.com/auth/googlehealth.irn.readonly", + "https://www.googleapis.com/auth/googlehealth.profile.readonly", + "https://www.googleapis.com/auth/googlehealth.settings.readonly", + "https://www.googleapis.com/auth/googlehealth.sleep.readonly", + ), + scopes=["1", "2"], + default_host="health.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.HealthProfileServiceGrpcTransport, + transports.HealthProfileServiceGrpcAsyncIOTransport, + ], +) +def test_health_profile_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_health_profile_service_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.HealthProfileServiceRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_health_profile_service_host_no_port(transport_name): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="health.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "health.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://health.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_health_profile_service_host_with_port(transport_name): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="health.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "health.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://health.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_health_profile_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = HealthProfileServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = HealthProfileServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.get_profile._session + session2 = client2.transport.get_profile._session + assert session1 != session2 + session1 = client1.transport.update_profile._session + session2 = client2.transport.update_profile._session + assert session1 != session2 + session1 = client1.transport.get_settings._session + session2 = client2.transport.get_settings._session + assert session1 != session2 + session1 = client1.transport.update_settings._session + session2 = client2.transport.update_settings._session + assert session1 != session2 + session1 = client1.transport.get_identity._session + session2 = client2.transport.get_identity._session + assert session1 != session2 + session1 = client1.transport.get_irn_profile._session + session2 = client2.transport.get_irn_profile._session + assert session1 != session2 + session1 = client1.transport.get_paired_device._session + session2 = client2.transport.get_paired_device._session + assert session1 != session2 + session1 = client1.transport.list_paired_devices._session + session2 = client2.transport.list_paired_devices._session + assert session1 != session2 + + +def test_health_profile_service_grpc_transport_channel(): + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.HealthProfileServiceGrpcTransport( + 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_health_profile_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.HealthProfileServiceGrpcAsyncIOTransport( + 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.filterwarnings("ignore::FutureWarning") +@pytest.mark.parametrize( + "transport_class", + [ + transports.HealthProfileServiceGrpcTransport, + transports.HealthProfileServiceGrpcAsyncIOTransport, + ], +) +def test_health_profile_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.HealthProfileServiceGrpcTransport, + transports.HealthProfileServiceGrpcAsyncIOTransport, + ], +) +def test_health_profile_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_identity_path(): + user = "squid" + expected = "users/{user}/identity".format( + user=user, + ) + actual = HealthProfileServiceClient.identity_path(user) + assert expected == actual + + +def test_parse_identity_path(): + expected = { + "user": "clam", + } + path = HealthProfileServiceClient.identity_path(**expected) + + # Check that the path construction is reversible. + actual = HealthProfileServiceClient.parse_identity_path(path) + assert expected == actual + + +def test_irn_profile_path(): + user = "whelk" + expected = "users/{user}/irnProfile".format( + user=user, + ) + actual = HealthProfileServiceClient.irn_profile_path(user) + assert expected == actual + + +def test_parse_irn_profile_path(): + expected = { + "user": "octopus", + } + path = HealthProfileServiceClient.irn_profile_path(**expected) + + # Check that the path construction is reversible. + actual = HealthProfileServiceClient.parse_irn_profile_path(path) + assert expected == actual + + +def test_paired_device_path(): + user = "oyster" + paired_device = "nudibranch" + expected = "users/{user}/pairedDevices/{paired_device}".format( + user=user, + paired_device=paired_device, + ) + actual = HealthProfileServiceClient.paired_device_path(user, paired_device) + assert expected == actual + + +def test_parse_paired_device_path(): + expected = { + "user": "cuttlefish", + "paired_device": "mussel", + } + path = HealthProfileServiceClient.paired_device_path(**expected) + + # Check that the path construction is reversible. + actual = HealthProfileServiceClient.parse_paired_device_path(path) + assert expected == actual + + +def test_profile_path(): + user = "winkle" + expected = "users/{user}/profile".format( + user=user, + ) + actual = HealthProfileServiceClient.profile_path(user) + assert expected == actual + + +def test_parse_profile_path(): + expected = { + "user": "nautilus", + } + path = HealthProfileServiceClient.profile_path(**expected) + + # Check that the path construction is reversible. + actual = HealthProfileServiceClient.parse_profile_path(path) + assert expected == actual + + +def test_settings_path(): + user = "scallop" + expected = "users/{user}/settings".format( + user=user, + ) + actual = HealthProfileServiceClient.settings_path(user) + assert expected == actual + + +def test_parse_settings_path(): + expected = { + "user": "abalone", + } + path = HealthProfileServiceClient.settings_path(**expected) + + # Check that the path construction is reversible. + actual = HealthProfileServiceClient.parse_settings_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "squid" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = HealthProfileServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "clam", + } + path = HealthProfileServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = HealthProfileServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "whelk" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = HealthProfileServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "octopus", + } + path = HealthProfileServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = HealthProfileServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "oyster" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = HealthProfileServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nudibranch", + } + path = HealthProfileServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = HealthProfileServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "cuttlefish" + expected = "projects/{project}".format( + project=project, + ) + actual = HealthProfileServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "mussel", + } + path = HealthProfileServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = HealthProfileServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "winkle" + location = "nautilus" + expected = "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + actual = HealthProfileServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "scallop", + "location": "abalone", + } + path = HealthProfileServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = HealthProfileServiceClient.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.HealthProfileServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.HealthProfileServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = HealthProfileServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_grpc(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +@pytest.mark.asyncio +async def test_transport_close_grpc_asyncio(): + client = HealthProfileServiceAsyncClient( + credentials=async_anonymous_credentials(), 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_rest(): + client = HealthProfileServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + "grpc", + ] + for transport in transports: + client = HealthProfileServiceClient( + 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", + [ + (HealthProfileServiceClient, transports.HealthProfileServiceGrpcTransport), + ( + HealthProfileServiceAsyncClient, + transports.HealthProfileServiceGrpcAsyncIOTransport, + ), + ], +) +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_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) From 1f6205ee5a370249ece2c2cc7131a47830ef00ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Swe=C3=B1a=20=28Swast=29?= Date: Wed, 3 Jun 2026 16:22:07 -0500 Subject: [PATCH 021/174] fix(bigframes): include pyopenssl as a dependency (#17362) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also, support pandas 3.0 in various system tests. Internal issue b/519591816 🦕 --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- .../bigframes/bigquery/_operations/ai.py | 27 ++++--- .../bigframes/bigquery/_operations/struct.py | 2 +- packages/bigframes/bigframes/core/blocks.py | 6 ++ .../bigframes/core/compile/polars/compiler.py | 53 ++++++++++++- .../bigframes/bigframes/core/indexes/base.py | 1 + packages/bigframes/bigframes/operations/ai.py | 10 +-- packages/bigframes/bigframes/series.py | 6 +- packages/bigframes/bigframes/testing/utils.py | 8 ++ packages/bigframes/setup.py | 3 +- .../small/functions/test_remote_function.py | 23 +++++- .../tests/system/small/test_magics.py | 4 +- .../test_compile_fromrange/out.sql | 4 +- .../test_bigframes_sql_scalar/out.sql | 2 +- .../test_sql_scalar/out.sql | 2 +- .../compile/sqlglot/test_compile_fromrange.py | 2 +- .../sqlglot/test_dataframe_accessor.py | 8 +- .../core/test_dataframe_accessor.py | 74 +++++++++---------- packages/bigframes/tests/unit/test_col.py | 4 +- .../bigframes_vendored/pandas/core/frame.py | 14 ++-- .../bigframes_vendored/pandas/core/generic.py | 6 +- .../pandas/core/indexes/accessor.py | 4 +- .../bigframes_vendored/pandas/core/series.py | 7 +- .../sklearn/decomposition/_mf.py | 2 +- 23 files changed, 183 insertions(+), 89 deletions(-) diff --git a/packages/bigframes/bigframes/bigquery/_operations/ai.py b/packages/bigframes/bigframes/bigquery/_operations/ai.py index 907d2e462295..78b5d81b6744 100644 --- a/packages/bigframes/bigframes/bigquery/_operations/ai.py +++ b/packages/bigframes/bigframes/bigquery/_operations/ai.py @@ -61,7 +61,7 @@ def generate( >>> import bigframes.pandas as bpd >>> import bigframes.bigquery as bbq >>> country = bpd.Series(["Japan", "Canada"]) - >>> bbq.ai.generate(("What's the capital city of ", country, " one word only")) + >>> bbq.ai.generate(("What's the capital city of ", country, " one word only")) # doctest: +ELLIPSIS 0 {'result': 'Tokyo', 'full_response': '{"cand... 1 {'result': 'Ottawa', 'full_response': '{"can... dtype: struct>, status: string>[pyarrow] @@ -231,8 +231,8 @@ def generate_int( >>> import bigframes.pandas as bpd >>> import bigframes.bigquery as bbq - >>> animal = bpd.Series(["Kangaroo", "Rabbit", "Spider"]) - >>> bbq.ai.generate_int(("How many legs does a ", animal, " have?")) + >>> animal = bpd.Series(["Ostrich", "Rabbit", "Spider"]) + >>> bbq.ai.generate_int(("How many legs does a ", animal, " have?")) # doctest: +ELLIPSIS 0 {'result': 2, 'full_response': '{"candidates":... 1 {'result': 4, 'full_response': '{"candidates":... 2 {'result': 8, 'full_response': '{"candidates":... @@ -305,8 +305,8 @@ def generate_double( >>> import bigframes.pandas as bpd >>> import bigframes.bigquery as bbq - >>> animal = bpd.Series(["Kangaroo", "Rabbit", "Spider"]) - >>> bbq.ai.generate_double(("How many legs does a ", animal, " have?")) + >>> animal = bpd.Series(["Ostrich", "Rabbit", "Spider"]) + >>> bbq.ai.generate_double(("How many legs does a ", animal, " have?")) # doctest: +ELLIPSIS 0 {'result': 2.0, 'full_response': '{"candidates... 1 {'result': 4.0, 'full_response': '{"candidates... 2 {'result': 8.0, 'full_response': '{"candidates... @@ -383,7 +383,7 @@ def generate_embedding( >>> import bigframes.pandas as bpd >>> import bigframes.bigquery as bbq >>> df = bpd.DataFrame({"content": ["apple", "bear", "pear"]}) - >>> bbq.ai.generate_embedding( + >>> bbq.ai.generate_embedding( # doctest: +SKIP ... "project.dataset.model_name", ... df ... ) @@ -486,7 +486,7 @@ def generate_text( >>> import bigframes.pandas as bpd >>> import bigframes.bigquery as bbq >>> df = bpd.DataFrame({"prompt": ["write a poem about apples"]}) - >>> bbq.ai.generate_text( + >>> bbq.ai.generate_text( # doctest: +SKIP ... "project.dataset.model_name", ... df ... ) @@ -601,7 +601,7 @@ def generate_table( >>> # the necessary columns for the model's prompt. For example, a >>> # DataFrame with a 'prompt' column for text classification. >>> df = bpd.DataFrame({'prompt': ["some text to classify"]}) - >>> result = bbq.ai.generate_table( + >>> result = bbq.ai.generate_table( # doctest: +SKIP ... "project.dataset.model_name", ... data=df, ... output_schema="category STRING" @@ -708,12 +708,14 @@ def embed( >>> import bigframes.pandas as bpd >>> import bigframes.bigquery as bbq - >>> bbq.ai.embed("dog", endpoint="text-embedding-005") + >>> bbq.ai.embed("dog", endpoint="text-embedding-005") # doctest: +ELLIPSIS 0 {'result': array([ 1.78243860e-03, -1.10658340... + dtype: struct, status: string>[pyarrow] >>> s = bpd.Series(['dog']) - >>> bbq.ai.embed(s, endpoint='text-embedding-005') + >>> bbq.ai.embed(s, endpoint='text-embedding-005') # doctest: +ELLIPSIS 0 {'result': array([ 1.78243860e-03, -1.10658340... + dtype: struct, status: string>[pyarrow] Args: content (str | Series): @@ -1004,6 +1006,7 @@ def similarity( >>> bbq.ai.similarity(df['word'], 'glad', endpoint='text-embedding-005') 0 0.916601 1 0.660579 + Name: word, dtype: Float64 Args: content1 (str | Series): @@ -1082,8 +1085,8 @@ def forecast( >>> df = pd.DataFrame({"value": [1, 2, 3], "time": pd.to_datetime(["2020-01-01", "2020-01-02", "2020-01-03"])}) >>> bpd.options.display.progress_bar = None >>> forecasted_pandas_df = df.bigquery.ai.forecast(data_col="value", timestamp_col="time", horizon=2) - >>> type(forecasted_pandas_df) - + >>> type(forecasted_pandas_df) # doctest: +ELLIPSIS + Forecast using a BigFrames DataFrame: diff --git a/packages/bigframes/bigframes/bigquery/_operations/struct.py b/packages/bigframes/bigframes/bigquery/_operations/struct.py index ba33457a768c..2ee760fb8e54 100644 --- a/packages/bigframes/bigframes/bigquery/_operations/struct.py +++ b/packages/bigframes/bigframes/bigquery/_operations/struct.py @@ -57,5 +57,5 @@ def struct(value: dataframe.DataFrame) -> series.Series: block, result_id = block.apply_nary_op( block.value_columns, ops.StructOp(column_names=tuple(block.column_labels)) ) - block = block.select_column(result_id) + block = block.select_column(result_id).with_column_labels([None]) return series.Series(block) diff --git a/packages/bigframes/bigframes/core/blocks.py b/packages/bigframes/bigframes/core/blocks.py index 6fb78363fdea..8522a4d97be7 100644 --- a/packages/bigframes/bigframes/core/blocks.py +++ b/packages/bigframes/bigframes/core/blocks.py @@ -1991,6 +1991,10 @@ def _generate_resample_label( ) level = level or 0 col_id = self.index.resolve_level(level)[0] + if isinstance(level, int): + resample_label = self.index.names[level] + else: + resample_label = level # Reset index to make the resampling level a column, then drop all other index columns. # This simplifies processing by focusing solely on the column required for resampling. block = self.reset_index(drop=False) @@ -2009,6 +2013,7 @@ def _generate_resample_label( raise KeyError(f"The grouper name {on} is not found") col_id = matches[0] + resample_label = on block = self if level is None: dtype = self._column_type(col_id) @@ -2101,6 +2106,7 @@ def _generate_resample_label( block.value_columns[0], block.value_columns[1], op=ops.IntegerLabelToDatetimeOp(freq=freq, label=label, origin=origin), + result_label=resample_label, ) # After multiple merges, the columns: diff --git a/packages/bigframes/bigframes/core/compile/polars/compiler.py b/packages/bigframes/bigframes/core/compile/polars/compiler.py index dac78f5c7b89..6f24929eeb4e 100644 --- a/packages/bigframes/bigframes/core/compile/polars/compiler.py +++ b/packages/bigframes/bigframes/core/compile/polars/compiler.py @@ -178,8 +178,59 @@ def _( self, expression: ex.OpExpression, ) -> pl.Expr: - # TODO: Complete the implementation + import datetime + + import pyarrow as pa + op = expression.op + + # Polars panics on nulls from pandas objects in timezone-aware + # datetimes for certain ops. Convert to timezone-naive temporarily + # to avoid this issue. + # TODO(tswast): Remove workaround when + # https://github.com/pola-rs/polars/issues/27862 has been fixed. + is_problematic_op = type(op) in ( + date_ops.YearOp, + date_ops.QuarterOp, + date_ops.MonthOp, + date_ops.DayOp, + date_ops.IsoWeekOp, + ) + + if is_problematic_op and len(expression.inputs) == 1: + input_expr = expression.inputs[0] + if ( + input_expr.is_resolved + and isinstance(input_expr.output_type, pd.ArrowDtype) + and isinstance( + input_expr.output_type.pyarrow_dtype, pa.TimestampType + ) + and input_expr.output_type.pyarrow_dtype.tz is not None + ): + tz_str = input_expr.output_type.pyarrow_dtype.tz + if tz_str == "UTC": + dummy_tz = datetime.timezone.utc + else: + try: + from zoneinfo import ZoneInfo + + dummy_tz = ZoneInfo(tz_str) # type: ignore + except Exception: + dummy_tz = datetime.timezone.utc + + dummy_val = datetime.datetime(1970, 1, 1, tzinfo=dummy_tz) + + compiled_input = self.compile_expression(input_expr) + filled_input = compiled_input.fill_null(dummy_val) + compiled_op_with_fill = self.compile_op(op, filled_input) + + return ( + pl.when(compiled_input.is_null()) + .then(None) + .otherwise(compiled_op_with_fill) + ) + + # TODO: Complete the implementation args = tuple(map(self.compile_expression, expression.inputs)) return self.compile_op(op, *args) diff --git a/packages/bigframes/bigframes/core/indexes/base.py b/packages/bigframes/bigframes/core/indexes/base.py index 8c418471f6cc..32279d36c9ab 100644 --- a/packages/bigframes/bigframes/core/indexes/base.py +++ b/packages/bigframes/bigframes/core/indexes/base.py @@ -325,6 +325,7 @@ def get_loc(self, key) -> typing.Union[int, slice, "bigframes.series.Series"]: # Return boolean mask for non-monotonic duplicates mask_block = block_with_offsets.select_columns([match_col_id]) mask_block = mask_block.reset_index(drop=True) + mask_block = mask_block.with_column_labels([None]) result_series = bigframes.series.Series(mask_block) return result_series.astype("boolean") diff --git a/packages/bigframes/bigframes/operations/ai.py b/packages/bigframes/bigframes/operations/ai.py index c1c5164e9065..bba0bf5a8362 100644 --- a/packages/bigframes/bigframes/operations/ai.py +++ b/packages/bigframes/bigframes/operations/ai.py @@ -122,12 +122,10 @@ def map( >>> model = llm.GeminiTextGenerator(model_name="gemini-2.5-pro") >>> df = bpd.DataFrame({"ingredient_1": ["Burger Bun", "Soy Bean"], "ingredient_2": ["Beef Patty", "Bittern"]}) - >>> df.ai.map("What is the food made from {ingredient_1} and {ingredient_2}? One word only.", model=model, output_schema={"food": "string"}) - ingredient_1 ingredient_2 food - 0 Burger Bun Beef Patty Burger - - 1 Soy Bean Bittern Tofu - + >>> df.ai.map("What is the food made from {ingredient_1} and {ingredient_2}? One word only.", model=model, output_schema={"food": "string"}) # doctest: +ELLIPSIS + ingredient_1 ingredient_2... + 0 Burger Bun Beef Patty... + 1 Soy Bean Bittern...Tofu [2 rows x 3 columns] diff --git a/packages/bigframes/bigframes/series.py b/packages/bigframes/bigframes/series.py index d4e704591b01..60acad0c301f 100644 --- a/packages/bigframes/bigframes/series.py +++ b/packages/bigframes/bigframes/series.py @@ -2472,7 +2472,9 @@ def map( self_df = self.to_frame(name="series") result_df = self_df.join(map_df, on="series") - return result_df[self.name] + result = cast(Series, result_df[self.name]) + result.name = self.name + return result @validations.requires_ordering() def sample( @@ -2698,7 +2700,7 @@ def _apply_nary_op( others, ignore_self=ignore_self, cast_scalars=False ) block, result_id = block.project_expr(op.as_expr(*values)) - return Series(block.select_column(result_id)) + return Series(block.select_column(result_id).with_column_labels([None])) def _apply_binary_aggregation( self, other: Series, stat: agg_ops.BinaryAggregateOp diff --git a/packages/bigframes/bigframes/testing/utils.py b/packages/bigframes/bigframes/testing/utils.py index b3b8ba1ab921..79e99968f583 100644 --- a/packages/bigframes/bigframes/testing/utils.py +++ b/packages/bigframes/bigframes/testing/utils.py @@ -93,6 +93,14 @@ def assert_series_equivalent(pd_series: pd.Series, bf_series: bpd.Series, **kwar def _normalize_all_nulls(col: pd.Series) -> pd.Series: if pd_types.is_float_dtype(col.dtype): col = col.astype("float64").astype("Float64") + elif col.dtype == "object": + if any(isinstance(x, decimal.Decimal) for x in col): + pass + else: + try: + col = col.astype("Float64") + except (TypeError, ValueError, SystemError): + pass return col diff --git a/packages/bigframes/setup.py b/packages/bigframes/setup.py index 819f8489e36e..138c52879526 100644 --- a/packages/bigframes/setup.py +++ b/packages/bigframes/setup.py @@ -38,7 +38,7 @@ "fsspec >=2023.3.0", "gcsfs >=2023.3.0, !=2025.5.0, !=2026.2.0, !=2026.3.0", "geopandas >=0.12.2", - "google-auth >=2.15.0,<3.0", + "google-auth[pyopenssl] >=2.15.0,<3.0", "google-cloud-bigquery[bqstorage,pandas] >=3.36.0", # 2.30 needed for arrow support. "google-cloud-bigquery-storage >= 2.30.0, < 3.0.0", @@ -75,6 +75,7 @@ "pytest-snapshot", "google-cloud-bigtable >=2.24.0", "google-cloud-pubsub >=2.21.4", + "tzdata", ], # used for local engine "polars": ["polars >= 1.21.0"], diff --git a/packages/bigframes/tests/system/small/functions/test_remote_function.py b/packages/bigframes/tests/system/small/functions/test_remote_function.py index a970fab64db3..869b26ca38c5 100644 --- a/packages/bigframes/tests/system/small/functions/test_remote_function.py +++ b/packages/bigframes/tests/system/small/functions/test_remote_function.py @@ -468,7 +468,12 @@ def add_one(x): pd_int64_df = scalars_pandas_df[int64_cols] pd_int64_df_filtered = pd_int64_df.dropna() - pd_result = pd_int64_df_filtered.applymap(add_one) + + # TODO(swast): Remove when pandas 2.1.x+ is the minimum supported. + if hasattr(pd_int64_df_filtered, "map"): + pd_result = pd_int64_df_filtered.map(add_one) + else: + pd_result = pd_int64_df_filtered.applymap(add_one) # TODO(shobs): Figure why pandas .applymap() changes the dtype, i.e. # pd_int64_df_filtered.dtype is Int64Dtype() # pd_int64_df_filtered.applymap(lambda x: x).dtype is int64. @@ -503,7 +508,13 @@ def add_one(x): pd_int64_df = scalars_pandas_df[int64_cols] pd_int64_df_filtered = pd_int64_df[pd_int64_df["int64_col"].notnull()] - pd_result = pd_int64_df_filtered.applymap(add_one) + + # TODO(swast): Remove when pandas 2.1.x+ is the minimum supported. + if hasattr(pd_int64_df_filtered, "map"): + pd_result = pd_int64_df_filtered.map(add_one) + else: + pd_result = pd_int64_df_filtered.applymap(add_one) + # TODO(shobs): Figure why pandas .applymap() changes the dtype, i.e. # pd_int64_df_filtered.dtype is Int64Dtype() # pd_int64_df_filtered.applymap(lambda x: x).dtype is int64. @@ -536,7 +547,13 @@ def add_one(x): bf_result = bf_int64_df.applymap(remote_add_one, na_action="ignore").to_pandas() pd_int64_df = scalars_pandas_df[int64_cols] - pd_result = pd_int64_df.applymap(add_one, na_action="ignore") + + # TODO(swast): Remove when pandas 2.1.x+ is the minimum supported. + if hasattr(pd_int64_df, "map"): + pd_result = pd_int64_df.map(add_one, na_action="ignore") + else: + pd_result = pd_int64_df.applymap(add_one, na_action="ignore") + # TODO(shobs): Figure why pandas .applymap() changes the dtype, i.e. # pd_int64_df_filtered.dtype is Int64Dtype() # pd_int64_df_filtered.applymap(lambda x: x).dtype is int64. diff --git a/packages/bigframes/tests/system/small/test_magics.py b/packages/bigframes/tests/system/small/test_magics.py index 91ada5b9e34a..eac0f233f98e 100644 --- a/packages/bigframes/tests/system/small/test_magics.py +++ b/packages/bigframes/tests/system/small/test_magics.py @@ -44,7 +44,7 @@ def test_magic_select_lit_to_var(ip): assert "dst_var" in ip.user_ns result_df = ip.user_ns["dst_var"] assert result_df.shape == (1, 1) - assert result_df.loc[0, 0] == 3 + assert result_df.to_pandas().iloc[0, 0] == 3 def test_magic_select_lit_dry_run(ip): @@ -97,4 +97,4 @@ def test_magic_select_interpolate(ip): assert "dst_var" in ip.user_ns result_df = ip.user_ns["dst_var"] assert result_df.shape == (1, 1) - assert result_df.loc[0, 0] == 9 + assert result_df.loc[0, "total"] == 9 diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/snapshots/test_compile_fromrange/test_compile_fromrange/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/snapshots/test_compile_fromrange/test_compile_fromrange/out.sql index 0b0e07056ab4..4f4e2496498f 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/snapshots/test_compile_fromrange/test_compile_fromrange/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/snapshots/test_compile_fromrange/test_compile_fromrange/out.sql @@ -60,7 +60,7 @@ WITH `bfcte_0` AS ( SELECT CAST(TIMESTAMP_MICROS( CAST(CAST(`bfcol_17` AS BIGNUMERIC) * 7000000 + CAST(UNIX_MICROS(CAST(CAST(`bfcol_8` AS DATE) AS TIMESTAMP)) AS BIGNUMERIC) AS INT64) - ) AS DATETIME) AS `bigframes_unnamed_index`, + ) AS DATETIME) AS `timestamp_col`, `bfcol_11` AS `int64_col`, `bfcol_12` AS `int64_too` FROM ( @@ -72,4 +72,4 @@ FROM ( LEFT JOIN `bfcte_5` ON `bfcol_17` = `bfcol_13` ORDER BY - `bfcol_17` ASC NULLS LAST \ No newline at end of file + `bfcol_17` ASC NULLS LAST diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/snapshots/test_dataframe_accessor/test_bigframes_sql_scalar/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/snapshots/test_dataframe_accessor/test_bigframes_sql_scalar/out.sql index 14853067c700..80b3137b0b55 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/snapshots/test_dataframe_accessor/test_bigframes_sql_scalar/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/snapshots/test_dataframe_accessor/test_bigframes_sql_scalar/out.sql @@ -1,4 +1,4 @@ SELECT `rowindex`, ROUND(`int64_col` + `int64_too`) AS `0` -FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` AS `bft_0` \ No newline at end of file +FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` AS `bft_0` diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/snapshots/test_dataframe_accessor/test_sql_scalar/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/snapshots/test_dataframe_accessor/test_sql_scalar/out.sql index 14853067c700..80b3137b0b55 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/snapshots/test_dataframe_accessor/test_sql_scalar/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/snapshots/test_dataframe_accessor/test_sql_scalar/out.sql @@ -1,4 +1,4 @@ SELECT `rowindex`, ROUND(`int64_col` + `int64_too`) AS `0` -FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` AS `bft_0` \ No newline at end of file +FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` AS `bft_0` diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/test_compile_fromrange.py b/packages/bigframes/tests/unit/core/compile/sqlglot/test_compile_fromrange.py index ba2e2075517b..8c25ca0310cd 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/test_compile_fromrange.py +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/test_compile_fromrange.py @@ -32,4 +32,4 @@ def test_compile_fromrange(compiler_session, snapshot): sql, _, _ = df.resample(rule="7s")._block.to_sql_query( include_index=True, enable_cache=False ) - snapshot.assert_match(sql, "out.sql") + snapshot.assert_match(sql.strip() + "\n", "out.sql") diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/test_dataframe_accessor.py b/packages/bigframes/tests/unit/core/compile/sqlglot/test_dataframe_accessor.py index 26e4d1788059..e430f5664975 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/test_dataframe_accessor.py +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/test_dataframe_accessor.py @@ -22,6 +22,10 @@ pytest.importorskip("pytest_snapshot") +# Only test on the latest pandas since column naming behavior is slightly +# different across versions, e.g. unnamed vs 0 for unnamed Series. +pytest.importorskip("pandas", minversion="3.0.0") + def test_sql_scalar(scalar_types_df: bpd.DataFrame, snapshot, monkeypatch): session = mock.create_autospec(bigframes.session.Session) @@ -42,7 +46,7 @@ def to_pandas(series, *, ordered): ) session.read_pandas.assert_called_once() - snapshot.assert_match(result, "out.sql") + snapshot.assert_match(result.strip() + "\n", "out.sql") def test_bigframes_sql_scalar(scalar_types_df: bpd.DataFrame, snapshot): @@ -57,4 +61,4 @@ def test_bigframes_sql_scalar(scalar_types_df: bpd.DataFrame, snapshot): session.read_pandas.assert_not_called() # Bigframes implementation returns a bigframes.series.Series sql, _, _ = result.to_frame()._to_sql_query(include_index=True) - snapshot.assert_match(sql, "out.sql") + snapshot.assert_match(sql.strip() + "\n", "out.sql") diff --git a/packages/bigframes/tests/unit/extensions/core/test_dataframe_accessor.py b/packages/bigframes/tests/unit/extensions/core/test_dataframe_accessor.py index 914a448700f4..7ab4f5176980 100644 --- a/packages/bigframes/tests/unit/extensions/core/test_dataframe_accessor.py +++ b/packages/bigframes/tests/unit/extensions/core/test_dataframe_accessor.py @@ -96,16 +96,16 @@ def mock_generate(prompt, **kwargs): output_schema={"res": "STRING"}, ) - assert result == ( - df["text_input"], - { - "connection_id": "conn", - "endpoint": "endpoint", - "request_type": "dedicated", - "model_params": {"temp": 0.5}, - "output_schema": {"res": "STRING"}, - }, - ) + assert isinstance(result, tuple) + assert len(result) == 2 + pd.testing.assert_series_equal(result[0], df["text_input"]) + assert result[1] == { + "connection_id": "conn", + "endpoint": "endpoint", + "request_type": "dedicated", + "model_params": {"temp": 0.5}, + "output_schema": {"res": "STRING"}, + } def test_bigframes_ai_generate(scalar_types_df: bpd.DataFrame, monkeypatch): @@ -147,15 +147,15 @@ def mock_generate_bool(prompt, **kwargs): model_params={"temp": 0.5}, ) - assert result == ( - df["text_input"], - { - "connection_id": "conn", - "endpoint": "endpoint", - "request_type": "dedicated", - "model_params": {"temp": 0.5}, - }, - ) + assert isinstance(result, tuple) + assert len(result) == 2 + pd.testing.assert_series_equal(result[0], df["text_input"]) + assert result[1] == { + "connection_id": "conn", + "endpoint": "endpoint", + "request_type": "dedicated", + "model_params": {"temp": 0.5}, + } def test_bigframes_ai_generate_bool(scalar_types_df: bpd.DataFrame, monkeypatch): @@ -196,15 +196,15 @@ def mock_generate_int(prompt, **kwargs): model_params={"temp": 0.5}, ) - assert result == ( - df["text_input"], - { - "connection_id": "conn", - "endpoint": "endpoint", - "request_type": "dedicated", - "model_params": {"temp": 0.5}, - }, - ) + assert isinstance(result, tuple) + assert len(result) == 2 + pd.testing.assert_series_equal(result[0], df["text_input"]) + assert result[1] == { + "connection_id": "conn", + "endpoint": "endpoint", + "request_type": "dedicated", + "model_params": {"temp": 0.5}, + } def test_bigframes_ai_generate_int(scalar_types_df: bpd.DataFrame, monkeypatch): @@ -245,15 +245,15 @@ def mock_generate_double(prompt, **kwargs): model_params={"temp": 0.5}, ) - assert result == ( - df["text_input"], - { - "connection_id": "conn", - "endpoint": "endpoint", - "request_type": "dedicated", - "model_params": {"temp": 0.5}, - }, - ) + assert isinstance(result, tuple) + assert len(result) == 2 + pd.testing.assert_series_equal(result[0], df["text_input"]) + assert result[1] == { + "connection_id": "conn", + "endpoint": "endpoint", + "request_type": "dedicated", + "model_params": {"temp": 0.5}, + } def test_bigframes_ai_generate_double(scalar_types_df: bpd.DataFrame, monkeypatch): diff --git a/packages/bigframes/tests/unit/test_col.py b/packages/bigframes/tests/unit/test_col.py index 9f5bbca5d9bc..c8caf9136c0a 100644 --- a/packages/bigframes/tests/unit/test_col.py +++ b/packages/bigframes/tests/unit/test_col.py @@ -88,10 +88,10 @@ def scalars_dfs( def test_pd_col_unary_operators(scalars_dfs, op): scalars_df, scalars_pandas_df = scalars_dfs bf_kwargs = { - "result": op(bpd.col("float64_col")), + "result": op(bpd.col("bool_col")), } pd_kwargs = { - "result": op(pd.col("float64_col")), # type: ignore + "result": op(pd.col("bool_col")), # type: ignore } df = scalars_df.assign(**bf_kwargs) diff --git a/packages/bigframes/third_party/bigframes_vendored/pandas/core/frame.py b/packages/bigframes/third_party/bigframes_vendored/pandas/core/frame.py index 678fb5f65177..f016cab47ae3 100644 --- a/packages/bigframes/third_party/bigframes_vendored/pandas/core/frame.py +++ b/packages/bigframes/third_party/bigframes_vendored/pandas/core/frame.py @@ -66,7 +66,7 @@ def axes(self) -> list: >>> df = bpd.DataFrame({'col1': [1, 2], 'col2': [3, 4]}) >>> df.axes[1:] - [Index(['col1', 'col2'], dtype='object')] + [Index(['col1', 'col2'], dtype='str')] """ raise NotImplementedError(constants.ABSTRACT_METHOD_ERROR_MESSAGE) @@ -1963,7 +1963,7 @@ def keys(self): ... 'B': [4, 5, 6], ... }) >>> df.keys() - Index(['A', 'B'], dtype='object') + Index(['A', 'B'], dtype='str') Returns: pandas.Index: Info axis. @@ -4819,7 +4819,8 @@ def resample( >>> df = bpd.DataFrame(data).set_index("timestamp_col") >>> df.resample(rule="7s").min() - int64_col int64_too + int64_col int64_too + timestamp_col 2021-01-01 12:59:55 0 10 2021-01-01 13:00:02 2 12 2021-01-01 13:00:09 9 19 @@ -4832,7 +4833,8 @@ def resample( >>> df = bpd.DataFrame(data) >>> df.resample(rule="7s", on = "timestamp_col", origin="start").min() - int64_col int64_too + int64_col int64_too + timestamp_col 2021-01-01 13:00:00 0 10 2021-01-01 13:00:07 7 17 2021-01-01 13:00:14 14 24 @@ -6633,7 +6635,7 @@ def columns(self): [3 rows x 3 columns] >>> df.columns - Index(['Name', 'Age', 'Location'], dtype='object') + Index(['Name', 'Age', 'Location'], dtype='str') You can also set new labels for columns. @@ -6646,7 +6648,7 @@ def columns(self): [3 rows x 3 columns] >>> df.columns - Index(['NewName', 'NewAge', 'NewLocation'], dtype='object') + Index(['NewName', 'NewAge', 'NewLocation'], dtype='str') """ raise NotImplementedError(constants.ABSTRACT_METHOD_ERROR_MESSAGE) diff --git a/packages/bigframes/third_party/bigframes_vendored/pandas/core/generic.py b/packages/bigframes/third_party/bigframes_vendored/pandas/core/generic.py index a5a3e6098376..0e4ac335c8a0 100644 --- a/packages/bigframes/third_party/bigframes_vendored/pandas/core/generic.py +++ b/packages/bigframes/third_party/bigframes_vendored/pandas/core/generic.py @@ -629,9 +629,9 @@ def dtypes(self): >>> df = bpd.DataFrame({'float': [1.0], 'int': [1], 'string': ['foo']}) >>> df.dtypes - float Float64 - int Int64 - string string[pyarrow] + float Float64 + int Int64 + string string dtype: object Returns: diff --git a/packages/bigframes/third_party/bigframes_vendored/pandas/core/indexes/accessor.py b/packages/bigframes/third_party/bigframes_vendored/pandas/core/indexes/accessor.py index a3404c222d49..da5f9e3b88a5 100644 --- a/packages/bigframes/third_party/bigframes_vendored/pandas/core/indexes/accessor.py +++ b/packages/bigframes/third_party/bigframes_vendored/pandas/core/indexes/accessor.py @@ -281,7 +281,7 @@ def month(self): **Examples:** >>> s = bpd.Series( - ... pd.date_range("2000-01-01", periods=3, freq="M") + ... pd.date_range("2000-01-01", periods=3, freq="ME") ... ) >>> s 0 2000-01-31 00:00:00 @@ -404,7 +404,7 @@ def year(self): **Examples:** >>> s = bpd.Series( - ... pd.date_range("2000-01-01", periods=3, freq="Y") + ... pd.date_range("2000-01-01", periods=3, freq="YE") ... ) >>> s 0 2000-12-31 00:00:00 diff --git a/packages/bigframes/third_party/bigframes_vendored/pandas/core/series.py b/packages/bigframes/third_party/bigframes_vendored/pandas/core/series.py index b9cacf3855a2..c116ed640122 100644 --- a/packages/bigframes/third_party/bigframes_vendored/pandas/core/series.py +++ b/packages/bigframes/third_party/bigframes_vendored/pandas/core/series.py @@ -2582,7 +2582,8 @@ def resample( ... } >>> s = bpd.DataFrame(data).set_index("timestamp_col") >>> s.resample(rule="7s", origin="epoch").min() - int64_col + int64_col + timestamp_col 2021-01-01 12:59:56 0 2021-01-01 13:00:03 3 2021-01-01 13:00:10 10 @@ -5674,8 +5675,8 @@ def iloc(self): With a scalar integer. - >>> type(df.iloc[0]) - + >>> type(df.iloc[0]) # doctest: +ELLIPSIS + >>> df.iloc[0] a 1 diff --git a/packages/bigframes/third_party/bigframes_vendored/sklearn/decomposition/_mf.py b/packages/bigframes/third_party/bigframes_vendored/sklearn/decomposition/_mf.py index 6d5a40714505..0ce79995d0c3 100644 --- a/packages/bigframes/third_party/bigframes_vendored/sklearn/decomposition/_mf.py +++ b/packages/bigframes/third_party/bigframes_vendored/sklearn/decomposition/_mf.py @@ -29,7 +29,7 @@ class MatrixFactorization(BaseEstimator, metaclass=ABCMeta): ... "value": [1, 1, 2, 1, 3, 1.2, 4, 1, 5, 0.8, 6, 1, 2, 3], ... }) >>> model = MatrixFactorization(feedback_type='explicit', num_factors=6, user_col='row', item_col='column', rating_col='value', l2_reg=2.06) - >>> W = model.fit(X) + >>> W = model.fit(X) # doctest: +SKIP Args: feedback_type ('explicit' | 'implicit'): From d01a4ba30040cfcb6498d0e9ef3ed3a54d56239d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Swe=C3=B1a=20=28Swast=29?= Date: Wed, 3 Jun 2026 17:01:19 -0500 Subject: [PATCH 022/174] feat: create `Series.bigquery.function_name` accessors for array and AEAD functions (#17279) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🦕 --- packages/bigframes/bigframes/__init__.py | 1 + .../extensions/bigframes/__init__.py | 9 +- .../extensions/bigframes/series_accessor.py | 60 ++ .../extensions/core/series_accessor.py | 712 ++++++++++++++++++ .../bigframes/extensions/pandas/__init__.py | 8 +- .../extensions/pandas/series_accessor.py | 69 ++ .../googlesql/global_namespace/array.py | 44 +- packages/bigframes/bigframes/series.py | 32 +- packages/bigframes/docs/reference/index.rst | 4 +- .../scripts/data/sql-functions/aead.yaml | 3 + .../global_namespace/aead_encryption.yaml | 3 + .../sql-functions/global_namespace/array.yaml | 57 +- .../scripts/generate_bigframes_bigquery.py | 183 ++++- .../templates/bigframes_series_accessor.py.j2 | 41 + .../templates/core_series_accessor.py.j2 | 92 +++ .../templates/pandas_series_accessor.py.j2 | 50 ++ .../scripts/templates/signature_def.py.j2 | 2 + .../unit/extensions/bigframes/__init__.py | 13 + .../bigframes/test_series_accessor.py | 78 ++ .../extensions/pandas/test_series_accessor.py | 136 ++++ 20 files changed, 1577 insertions(+), 20 deletions(-) create mode 100644 packages/bigframes/bigframes/extensions/bigframes/series_accessor.py create mode 100644 packages/bigframes/bigframes/extensions/core/series_accessor.py create mode 100644 packages/bigframes/bigframes/extensions/pandas/series_accessor.py create mode 100644 packages/bigframes/scripts/templates/bigframes_series_accessor.py.j2 create mode 100644 packages/bigframes/scripts/templates/core_series_accessor.py.j2 create mode 100644 packages/bigframes/scripts/templates/pandas_series_accessor.py.j2 create mode 100644 packages/bigframes/tests/unit/extensions/bigframes/__init__.py create mode 100644 packages/bigframes/tests/unit/extensions/bigframes/test_series_accessor.py create mode 100644 packages/bigframes/tests/unit/extensions/pandas/test_series_accessor.py diff --git a/packages/bigframes/bigframes/__init__.py b/packages/bigframes/bigframes/__init__.py index 7061300b5cc5..533726343a59 100644 --- a/packages/bigframes/bigframes/__init__.py +++ b/packages/bigframes/bigframes/__init__.py @@ -42,6 +42,7 @@ # Register pandas extensions import bigframes.extensions.pandas.dataframe_accessor # noqa: F401, E402 +import bigframes.extensions.pandas.series_accessor # noqa: F401, E402 from bigframes._config.bigquery_options import BigQueryOptions # noqa: E402 from bigframes.core.global_session import ( # noqa: E402 close_session, diff --git a/packages/bigframes/bigframes/extensions/bigframes/__init__.py b/packages/bigframes/bigframes/extensions/bigframes/__init__.py index 859b51d71ca8..439a8189dedf 100644 --- a/packages/bigframes/bigframes/extensions/bigframes/__init__.py +++ b/packages/bigframes/bigframes/extensions/bigframes/__init__.py @@ -16,5 +16,12 @@ BigframesAIAccessor, BigframesBigQueryDataFrameAccessor, ) +from bigframes.extensions.bigframes.series_accessor import ( + BigframesBigQuerySeriesAccessor, +) -__all__ = ["BigframesAIAccessor", "BigframesBigQueryDataFrameAccessor"] +__all__ = [ + "BigframesAIAccessor", + "BigframesBigQueryDataFrameAccessor", + "BigframesBigQuerySeriesAccessor", +] diff --git a/packages/bigframes/bigframes/extensions/bigframes/series_accessor.py b/packages/bigframes/bigframes/extensions/bigframes/series_accessor.py new file mode 100644 index 000000000000..b67d007b88e7 --- /dev/null +++ b/packages/bigframes/bigframes/extensions/bigframes/series_accessor.py @@ -0,0 +1,60 @@ +# Copyright 2026 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. +# +# DO NOT MODIFY THIS FILE DIRECTLY. +# This file was generated by the script: scripts/generate_bigframes_bigquery.py +# + +from __future__ import annotations + +from typing import Optional, TypeVar, cast + +import bigframes.extensions.core.series_accessor as core_accessor +import bigframes.series +import bigframes.session +from bigframes.core.logging import log_adapter + +S = TypeVar("S", bound="bigframes.series.Series") + + +@log_adapter.class_logger +class BigframesBigQuerySeriesAccessor(core_accessor.BigQuerySeriesAccessor[S]): + def __init__(self, bf_obj: S): + super().__init__(bf_obj) + + def _bf_from_series( + self, session: Optional[bigframes.session.Session] = None + ) -> bigframes.series.Series: + return self._obj + + def _to_series(self, bf_series: bigframes.series.Series) -> S: + return cast(S, bf_series) + + @property + def aead(self) -> BigframesAeadSeriesAccessor[S]: + return BigframesAeadSeriesAccessor(self._obj) + + +@log_adapter.class_logger +class BigframesAeadSeriesAccessor(core_accessor.AeadSeriesAccessor[S]): + def __init__(self, bf_obj: S): + super().__init__(bf_obj) + + def _bf_from_series( + self, session: Optional[bigframes.session.Session] = None + ) -> bigframes.series.Series: + return self._obj + + def _to_series(self, bf_series: bigframes.series.Series) -> S: + return cast(S, bf_series) diff --git a/packages/bigframes/bigframes/extensions/core/series_accessor.py b/packages/bigframes/bigframes/extensions/core/series_accessor.py new file mode 100644 index 000000000000..4c0f261b83cd --- /dev/null +++ b/packages/bigframes/bigframes/extensions/core/series_accessor.py @@ -0,0 +1,712 @@ +# Copyright 2026 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. +# +# DO NOT MODIFY THIS FILE DIRECTLY. +# This file was generated by the script: scripts/generate_bigframes_bigquery.py +# + +from __future__ import annotations + +import abc +from typing import ( + Any, + Generic, + Literal, + Optional, + TypeVar, + Union, + cast, +) + +import bigframes.core.col +import bigframes.core.sentinels as sentinels +import bigframes.series as series +import bigframes.session + +S = TypeVar("S") + + +class AbstractBigQuerySeriesAccessor(abc.ABC, Generic[S]): + def __init__(self, obj: S): + self._obj = obj + + @abc.abstractmethod + def _bf_from_series( + self, session: Optional[bigframes.session.Session] = None + ) -> series.Series: + """Convert the accessor's object to a BigFrames Series.""" + + @abc.abstractmethod + def _to_series(self, bf_series: series.Series) -> S: + """Convert a BigFrames Series to the accessor's object type.""" + + +class BigQuerySeriesAccessor(AbstractBigQuerySeriesAccessor[S]): + """Series accessor for BigQuery functions.""" + + @property + @abc.abstractmethod + def aead(self) -> AeadSeriesAccessor[S]: + """Accessor for BigQuery aead functions.""" + + def deterministic_decrypt_bytes( + self, + ciphertext: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes], + ], + additional_data: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes], + ], + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Uses the matching key from `keyset` to decrypt `ciphertext` and verifies the integrity of the data using `additional_data`. Returns an error if decryption fails.""" + from bigframes.operations.googlesql.global_namespace.aead_encryption import ( + deterministic_decrypt_bytes as deterministic_decrypt_bytes_impl, + ) + + # Resolve session from other arguments if not passed + if session is None: + import bigframes.core.googlesql as googlesql + + session = googlesql._find_session( + ciphertext, + additional_data, + ) + + bf_series = self._bf_from_series(session) + result = deterministic_decrypt_bytes_impl( + bf_series, + ciphertext, + additional_data, + ) + return self._to_series(cast(series.Series, result)) + + def deterministic_decrypt_string( + self, + ciphertext: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes], + ], + additional_data: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ], + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Like `DETERMINISTIC_DECRYPT_BYTES`, but where plaintext is of type STRING.""" + from bigframes.operations.googlesql.global_namespace.aead_encryption import ( + deterministic_decrypt_string as deterministic_decrypt_string_impl, + ) + + # Resolve session from other arguments if not passed + if session is None: + import bigframes.core.googlesql as googlesql + + session = googlesql._find_session( + ciphertext, + additional_data, + ) + + bf_series = self._bf_from_series(session) + result = deterministic_decrypt_string_impl( + bf_series, + ciphertext, + additional_data, + ) + return self._to_series(cast(series.Series, result)) + + def deterministic_encrypt( + self, + plaintext: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes, str], + ], + additional_data: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes, str], + ], + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Encrypts `plaintext` using the primary cryptographic key in `keyset` using deterministic AEAD. The algorithm of the primary key must be `DETERMINISTIC_AEAD_AES_SIV_CMAC_256`. Binds the ciphertext to the context defined by `additional_data`. Returns `NULL` if any input is `NULL`.""" + from bigframes.operations.googlesql.global_namespace.aead_encryption import ( + deterministic_encrypt as deterministic_encrypt_impl, + ) + + # Resolve session from other arguments if not passed + if session is None: + import bigframes.core.googlesql as googlesql + + session = googlesql._find_session( + plaintext, + additional_data, + ) + + bf_series = self._bf_from_series(session) + result = deterministic_encrypt_impl( + bf_series, + plaintext, + additional_data, + ) + return self._to_series(cast(series.Series, result)) + + def array_concat( + self, + array_expression_2: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Any, Literal[sentinels.Sentinel.ARGUMENT_DEFAULT]], + ], + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Concatenates one or more arrays with the same element type into a single array.""" + from bigframes.operations.googlesql.global_namespace.array import ( + array_concat as array_concat_impl, + ) + + # Resolve session from other arguments if not passed + if session is None: + import bigframes.core.googlesql as googlesql + + session = googlesql._find_session( + array_expression_2, + ) + + bf_series = self._bf_from_series(session) + result = array_concat_impl( + bf_series, + array_expression_2, + ) + return self._to_series(cast(series.Series, result)) + + def array_first( + self, + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Takes an array and returns the first element in the array.""" + from bigframes.operations.googlesql.global_namespace.array import ( + array_first as array_first_impl, + ) + + bf_series = self._bf_from_series(session) + result = array_first_impl( + bf_series, + ) + return self._to_series(cast(series.Series, result)) + + def array_first_n( + self, + n: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], int], + ], + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Returns a prefix of `input_array` consisting of the first `n` elements.""" + from bigframes.operations.googlesql.global_namespace.array import ( + array_first_n as array_first_n_impl, + ) + + # Resolve session from other arguments if not passed + if session is None: + import bigframes.core.googlesql as googlesql + + session = googlesql._find_session( + n, + ) + + bf_series = self._bf_from_series(session) + result = array_first_n_impl( + bf_series, + n, + ) + return self._to_series(cast(series.Series, result)) + + def array_includes( + self, + search_value: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Any, Literal[sentinels.Sentinel.ARGUMENT_DEFAULT]], + ], + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Takes an array and returns `TRUE` if there is an element in the array that is equal to the search_value.""" + from bigframes.operations.googlesql.global_namespace.array import ( + array_includes as array_includes_impl, + ) + + # Resolve session from other arguments if not passed + if session is None: + import bigframes.core.googlesql as googlesql + + session = googlesql._find_session( + search_value, + ) + + bf_series = self._bf_from_series(session) + result = array_includes_impl( + bf_series, + search_value, + ) + return self._to_series(cast(series.Series, result)) + + def array_includes_all( + self, + search_values: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Any, Literal[sentinels.Sentinel.ARGUMENT_DEFAULT]], + ], + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Takes an array to search and an array of search values. Returns `TRUE` if all search values are in the array to search, otherwise returns `FALSE`.""" + from bigframes.operations.googlesql.global_namespace.array import ( + array_includes_all as array_includes_all_impl, + ) + + # Resolve session from other arguments if not passed + if session is None: + import bigframes.core.googlesql as googlesql + + session = googlesql._find_session( + search_values, + ) + + bf_series = self._bf_from_series(session) + result = array_includes_all_impl( + bf_series, + search_values, + ) + return self._to_series(cast(series.Series, result)) + + def array_includes_any( + self, + search_values: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Any, Literal[sentinels.Sentinel.ARGUMENT_DEFAULT]], + ], + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Takes an array to search and an array of search values. Returns `TRUE` if any search values are in the array to search, otherwise returns `FALSE`.""" + from bigframes.operations.googlesql.global_namespace.array import ( + array_includes_any as array_includes_any_impl, + ) + + # Resolve session from other arguments if not passed + if session is None: + import bigframes.core.googlesql as googlesql + + session = googlesql._find_session( + search_values, + ) + + bf_series = self._bf_from_series(session) + result = array_includes_any_impl( + bf_series, + search_values, + ) + return self._to_series(cast(series.Series, result)) + + def array_is_distinct( + self, + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Returns `TRUE` if the array contains no repeated elements, using the same equality comparison logic as `SELECT DISTINCT`.""" + from bigframes.operations.googlesql.global_namespace.array import ( + array_is_distinct as array_is_distinct_impl, + ) + + bf_series = self._bf_from_series(session) + result = array_is_distinct_impl( + bf_series, + ) + return self._to_series(cast(series.Series, result)) + + def array_last( + self, + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Takes an array and returns the last element in the array.""" + from bigframes.operations.googlesql.global_namespace.array import ( + array_last as array_last_impl, + ) + + bf_series = self._bf_from_series(session) + result = array_last_impl( + bf_series, + ) + return self._to_series(cast(series.Series, result)) + + def array_length( + self, + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Compute the length of each array element in the Series. + + **Examples:** + + >>> import bigframes.pandas as bpd + >>> import bigframes.bigquery as bbq + + >>> s = bpd.Series([[1, 2, 8, 3], [], [3, 4]]) + >>> bbq.array_length(s) + 0 4 + 1 0 + 2 2 + dtype: Int64 + + You can call this function using the Series `bigquery` accessor. + + >>> s.bigquery.array_length() + 0 4 + 1 0 + 2 2 + dtype: Int64 + + You can also use this accessor on a pandas Series after importing bigframes. + + >>> import bigframes + >>> import pandas as pd + >>> ps = pd.Series([[1, 2, 8, 3], [], [3, 4]]) + >>> ps.bigquery.array_length() + 0 4 + 1 0 + 2 2 + dtype: Int64 + + You can also apply this function directly to Series using `apply`. + + >>> s.apply(bbq.array_length, by_row=False) + 0 4 + 1 0 + 2 2 + dtype: Int64 + + Args: + series (bigframes.series.Series): A Series with array columns. + + Returns: + bigframes.series.Series: A Series of integer values indicating + the length of each element in the Series. + """ + from bigframes.operations.googlesql.global_namespace.array import ( + array_length as array_length_impl, + ) + + bf_series = self._bf_from_series(session) + result = array_length_impl( + bf_series, + ) + return self._to_series(cast(series.Series, result)) + + def array_reverse( + self, + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Returns the input `ARRAY` with elements in reverse order.""" + from bigframes.operations.googlesql.global_namespace.array import ( + array_reverse as array_reverse_impl, + ) + + bf_series = self._bf_from_series(session) + result = array_reverse_impl( + bf_series, + ) + return self._to_series(cast(series.Series, result)) + + def array_slice( + self, + start_offset: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], int], + ], + end_offset: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], int], + ], + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Returns an array containing zero or more consecutive elements from the input array.""" + from bigframes.operations.googlesql.global_namespace.array import ( + array_slice as array_slice_impl, + ) + + # Resolve session from other arguments if not passed + if session is None: + import bigframes.core.googlesql as googlesql + + session = googlesql._find_session( + start_offset, + end_offset, + ) + + bf_series = self._bf_from_series(session) + result = array_slice_impl( + bf_series, + start_offset, + end_offset, + ) + return self._to_series(cast(series.Series, result)) + + def array_to_string( + self, + delimiter: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes, str], + ], + null_text: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes, str], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Converts array elements within a Series into delimited strings. + + **Examples:** + + >>> import bigframes.pandas as bpd + >>> import bigframes.bigquery as bbq + + >>> s = bpd.Series([["H", "i", "!"], ["Hello", "World"], np.nan, [], ["Hi"]]) + >>> bbq.array_to_string(s, delimiter=", ") + 0 H, i, ! + 1 Hello, World + 2 + 3 + 4 Hi + dtype: string + + You can call this function using the Series `bigquery` accessor. + + >>> s.bigquery.array_to_string(delimiter=", ") + 0 H, i, ! + 1 Hello, World + 2 + 3 + 4 Hi + dtype: string + + You can also use this accessor on a pandas Series after importing bigframes. + + >>> import bigframes + >>> import pandas as pd + >>> ps = pd.Series([["H", "i", "!"], ["Hello", "World"], None, [], ["Hi"]]) + >>> ps.bigquery.array_to_string(delimiter=", ") + 0 H, i, ! + 1 Hello, World + 2 + 3 + 4 Hi + dtype: string + + Args: + series (bigframes.series.Series): A Series containing arrays. + delimiter (str): The string used to separate array elements. + null_text (str, optional): The string to replace any NULL values in the array with. + + Returns: + bigframes.series.Series: A Series containing delimited strings. + """ + from bigframes.operations.googlesql.global_namespace.array import ( + array_to_string as array_to_string_impl, + ) + + # Resolve session from other arguments if not passed + if session is None: + import bigframes.core.googlesql as googlesql + + session = googlesql._find_session( + delimiter, + null_text, + ) + + bf_series = self._bf_from_series(session) + result = array_to_string_impl( + bf_series, + delimiter, + null_text, + ) + return self._to_series(cast(series.Series, result)) + + def flatten( + self, + depth: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], int], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Takes an array of nested data and flattens a specific part of it into a single, flat array with the [array elements field access operator][array-el-field-operator]. Returns `NULL` if the input value is `NULL`.""" + from bigframes.operations.googlesql.global_namespace.array import ( + flatten as flatten_impl, + ) + + # Resolve session from other arguments if not passed + if session is None: + import bigframes.core.googlesql as googlesql + + session = googlesql._find_session( + depth, + ) + + bf_series = self._bf_from_series(session) + result = flatten_impl( + bf_series, + depth, + ) + return self._to_series(cast(series.Series, result)) + + +class AeadSeriesAccessor(AbstractBigQuerySeriesAccessor[S]): + """Series accessor for BigQuery aead functions.""" + + def decrypt_bytes( + self, + ciphertext: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes], + ], + additional_data: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes], + ], + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Uses the matching key from keyset to decrypt ciphertext and verifies the integrity of the data using additional_data. Returns an error if decryption or verification fails.""" + from bigframes.operations.googlesql.aead import ( + decrypt_bytes as decrypt_bytes_impl, + ) + + # Resolve session from other arguments if not passed + if session is None: + import bigframes.core.googlesql as googlesql + + session = googlesql._find_session( + ciphertext, + additional_data, + ) + + bf_series = self._bf_from_series(session) + result = decrypt_bytes_impl( + bf_series, + ciphertext, + additional_data, + ) + return self._to_series(cast(series.Series, result)) + + def decrypt_string( + self, + ciphertext: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes], + ], + additional_data: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ], + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Like AEAD.DECRYPT_BYTES, but where additional_data is of type STRING.""" + from bigframes.operations.googlesql.aead import ( + decrypt_string as decrypt_string_impl, + ) + + # Resolve session from other arguments if not passed + if session is None: + import bigframes.core.googlesql as googlesql + + session = googlesql._find_session( + ciphertext, + additional_data, + ) + + bf_series = self._bf_from_series(session) + result = decrypt_string_impl( + bf_series, + ciphertext, + additional_data, + ) + return self._to_series(cast(series.Series, result)) + + def encrypt( + self, + plaintext: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes, str], + ], + additional_data: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes, str], + ], + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Encrypts plaintext using the primary cryptographic key in keyset. The algorithm of the primary key must be AEAD_AES_GCM_256. Binds the ciphertext to the context defined by additional_data. Returns NULL if any input is NULL.""" + from bigframes.operations.googlesql.aead import encrypt as encrypt_impl + + # Resolve session from other arguments if not passed + if session is None: + import bigframes.core.googlesql as googlesql + + session = googlesql._find_session( + plaintext, + additional_data, + ) + + bf_series = self._bf_from_series(session) + result = encrypt_impl( + bf_series, + plaintext, + additional_data, + ) + return self._to_series(cast(series.Series, result)) diff --git a/packages/bigframes/bigframes/extensions/pandas/__init__.py b/packages/bigframes/bigframes/extensions/pandas/__init__.py index d47acd3b05e0..6af1f769b5ba 100644 --- a/packages/bigframes/bigframes/extensions/pandas/__init__.py +++ b/packages/bigframes/bigframes/extensions/pandas/__init__.py @@ -21,5 +21,11 @@ from bigframes.extensions.pandas.dataframe_accessor import ( PandasBigQueryDataFrameAccessor, ) +from bigframes.extensions.pandas.series_accessor import ( + PandasBigQuerySeriesAccessor, +) -__all__ = ["PandasBigQueryDataFrameAccessor"] +__all__ = [ + "PandasBigQueryDataFrameAccessor", + "PandasBigQuerySeriesAccessor", +] diff --git a/packages/bigframes/bigframes/extensions/pandas/series_accessor.py b/packages/bigframes/bigframes/extensions/pandas/series_accessor.py new file mode 100644 index 000000000000..837664c6e1f5 --- /dev/null +++ b/packages/bigframes/bigframes/extensions/pandas/series_accessor.py @@ -0,0 +1,69 @@ +# Copyright 2026 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. +# +# DO NOT MODIFY THIS FILE DIRECTLY. +# This file was generated by the script: scripts/generate_bigframes_bigquery.py +# + +from __future__ import annotations + +from typing import Optional, TypeVar, cast + +import pandas +import pandas.api.extensions + +import bigframes.core.global_session as bf_session +import bigframes.extensions.core.series_accessor as core_accessor +import bigframes.series +import bigframes.session +from bigframes.core.logging import log_adapter + +S = TypeVar("S", bound="pandas.Series") + + +@pandas.api.extensions.register_series_accessor("bigquery") +@log_adapter.class_logger +class PandasBigQuerySeriesAccessor(core_accessor.BigQuerySeriesAccessor[S]): + def __init__(self, pandas_obj: S): + super().__init__(pandas_obj) + + def _bf_from_series( + self, session: Optional[bigframes.session.Session] = None + ) -> bigframes.series.Series: + if session is None: + session = bf_session.get_global_session() + return cast(bigframes.series.Series, session.read_pandas(self._obj)) + + def _to_series(self, bf_series: bigframes.series.Series) -> S: + return cast(S, bf_series.to_pandas(ordered=True)) + + @property + def aead(self) -> PandasAeadSeriesAccessor[S]: + return PandasAeadSeriesAccessor(self._obj) + + +@log_adapter.class_logger +class PandasAeadSeriesAccessor(core_accessor.AeadSeriesAccessor[S]): + def __init__(self, pandas_obj: S): + super().__init__(pandas_obj) + + def _bf_from_series( + self, session: Optional[bigframes.session.Session] = None + ) -> bigframes.series.Series: + if session is None: + session = bf_session.get_global_session() + return cast(bigframes.series.Series, session.read_pandas(self._obj)) + + def _to_series(self, bf_series: bigframes.series.Series) -> S: + return cast(S, bf_series.to_pandas(ordered=True)) diff --git a/packages/bigframes/bigframes/operations/googlesql/global_namespace/array.py b/packages/bigframes/bigframes/operations/googlesql/global_namespace/array.py index c8d24aa98df5..94adbad1839d 100644 --- a/packages/bigframes/bigframes/operations/googlesql/global_namespace/array.py +++ b/packages/bigframes/bigframes/operations/googlesql/global_namespace/array.py @@ -688,7 +688,26 @@ def array_length( 2 2 dtype: Int64 - You can also apply this function directly to Series. + You can call this function using the Series `bigquery` accessor. + + >>> s.bigquery.array_length() + 0 4 + 1 0 + 2 2 + dtype: Int64 + + You can also use this accessor on a pandas Series after importing bigframes. + + >>> import bigframes + >>> import pandas as pd + >>> ps = pd.Series([[1, 2, 8, 3], [], [3, 4]]) + >>> ps.bigquery.array_length() + 0 4 + 1 0 + 2 2 + dtype: Int64 + + You can also apply this function directly to Series using `apply`. >>> s.apply(bbq.array_length, by_row=False) 0 4 @@ -782,6 +801,29 @@ def array_to_string( 4 Hi dtype: string + You can call this function using the Series `bigquery` accessor. + + >>> s.bigquery.array_to_string(delimiter=", ") + 0 H, i, ! + 1 Hello, World + 2 + 3 + 4 Hi + dtype: string + + You can also use this accessor on a pandas Series after importing bigframes. + + >>> import bigframes + >>> import pandas as pd + >>> ps = pd.Series([["H", "i", "!"], ["Hello", "World"], None, [], ["Hi"]]) + >>> ps.bigquery.array_to_string(delimiter=", ") + 0 H, i, ! + 1 Hello, World + 2 + 3 + 4 Hi + dtype: string + Args: series (bigframes.series.Series): A Series containing arrays. delimiter (str): The string used to separate array elements. diff --git a/packages/bigframes/bigframes/series.py b/packages/bigframes/bigframes/series.py index 60acad0c301f..ebf32ac7850d 100644 --- a/packages/bigframes/bigframes/series.py +++ b/packages/bigframes/bigframes/series.py @@ -41,7 +41,7 @@ import bigframes_vendored.constants as constants import bigframes_vendored.pandas.core.series as vendored_pandas_series -import google.cloud.bigquery as bigquery +import google.cloud.bigquery.job import numpy import pandas import pyarrow as pa @@ -80,6 +80,7 @@ from bigframes.core.window import rolling if typing.TYPE_CHECKING: + import bigframes.extensions.bigframes.series_accessor as series_bigquery_accessor import bigframes.geopandas.geoseries import bigframes.operations.datetimes as datetimes import bigframes.operations.strings as strings @@ -118,7 +119,7 @@ def __init__( *, session: Optional[bigframes.session.Session] = None, ): - self._query_job: Optional[bigquery.QueryJob] = None + self._query_job: Optional[google.cloud.bigquery.job.QueryJob] = None import bigframes.pandas # Ignore object dtype if provided, as it provides no additional @@ -301,7 +302,26 @@ def keys(self) -> indexes.Index: return self.index @property - def query_job(self) -> Optional[bigquery.QueryJob]: + def bigquery( + self, + ) -> series_bigquery_accessor.BigframesBigQuerySeriesAccessor: + """ + Accessor for BigQuery functionality. + + Returns: + bigframes.extensions.core.series_accessor.BigQuerySeriesAccessor: + Accessor that exposes BigQuery functionality on a Series, + with method names closer to SQL. + """ + # Import the accessor here to avoid circular imports. + import bigframes.extensions.bigframes.series_accessor + + return bigframes.extensions.bigframes.series_accessor.BigframesBigQuerySeriesAccessor( + self + ) + + @property + def query_job(self) -> Optional[google.cloud.bigquery.job.QueryJob]: """BigQuery job metadata for the most recent query. Returns: @@ -355,7 +375,9 @@ def sql(self) -> str: def transpose(self) -> Series: return self - def _set_internal_query_job(self, query_job: Optional[bigquery.QueryJob]): + def _set_internal_query_job( + self, query_job: Optional[google.cloud.bigquery.job.QueryJob] + ): self._query_job = query_job def __len__(self): @@ -817,7 +839,7 @@ def to_pandas_batches( ) return map(lambda df: cast(pandas.Series, df.squeeze(1)), batches) - def _compute_dry_run(self) -> bigquery.QueryJob: + def _compute_dry_run(self) -> google.cloud.bigquery.job.QueryJob: _, query_job = self._block._compute_dry_run((self._value_column,)) return query_job diff --git a/packages/bigframes/docs/reference/index.rst b/packages/bigframes/docs/reference/index.rst index 60934582e969..99228010b249 100644 --- a/packages/bigframes/docs/reference/index.rst +++ b/packages/bigframes/docs/reference/index.rst @@ -23,13 +23,15 @@ packages. Pandas Extensions ~~~~~~~~~~~~~~~~~ -BigQuery DataFrames provides extensions to pandas DataFrame objects. +BigQuery DataFrames provides extensions to pandas DataFrame and Series objects. .. autosummary:: :toctree: api bigframes.extensions.core.dataframe_accessor.BigQueryDataFrameAccessor bigframes.extensions.core.dataframe_accessor.AIAccessor + bigframes.extensions.core.series_accessor.BigQuerySeriesAccessor + bigframes.extensions.core.series_accessor.AeadSeriesAccessor ML APIs ~~~~~~~ diff --git a/packages/bigframes/scripts/data/sql-functions/aead.yaml b/packages/bigframes/scripts/data/sql-functions/aead.yaml index 6c289a96e886..198248782d7d 100644 --- a/packages/bigframes/scripts/data/sql-functions/aead.yaml +++ b/packages/bigframes/scripts/data/sql-functions/aead.yaml @@ -2,6 +2,7 @@ urn: extension:google:bq_scalar_functions scalar_functions: - name: "aead.decrypt_bytes" description: "Uses the matching key from keyset to decrypt ciphertext and verifies the integrity of the data using additional_data. Returns an error if decryption or verification fails." + series_accessor_arg: keyset impls: # Signature: aead.decrypt_bytes:vbin_vbin_vbin - args: @@ -35,6 +36,7 @@ scalar_functions: return: binary - name: "aead.decrypt_string" description: "Like AEAD.DECRYPT_BYTES, but where additional_data is of type STRING." + series_accessor_arg: keyset impls: # Signature: aead.decrypt_string:vbin_vbin_str - args: @@ -68,6 +70,7 @@ scalar_functions: return: string - name: "aead.encrypt" description: "Encrypts plaintext using the primary cryptographic key in keyset. The algorithm of the primary key must be AEAD_AES_GCM_256. Binds the ciphertext to the context defined by additional_data. Returns NULL if any input is NULL." + series_accessor_arg: keyset impls: # Signature: aead.encrypt:vbin_str_str - args: diff --git a/packages/bigframes/scripts/data/sql-functions/global_namespace/aead_encryption.yaml b/packages/bigframes/scripts/data/sql-functions/global_namespace/aead_encryption.yaml index ffd26e5e0e7b..1e62de0f2a65 100644 --- a/packages/bigframes/scripts/data/sql-functions/global_namespace/aead_encryption.yaml +++ b/packages/bigframes/scripts/data/sql-functions/global_namespace/aead_encryption.yaml @@ -2,6 +2,7 @@ urn: extension:google:bq_scalar_functions scalar_functions: - name: "deterministic_decrypt_bytes" description: "Uses the matching key from `keyset` to decrypt `ciphertext` and verifies the integrity of the data using `additional_data`. Returns an error if decryption fails." + series_accessor_arg: keyset impls: # Signature: deterministic_decrypt_bytes:vbin_vbin_vbin - args: @@ -35,6 +36,7 @@ scalar_functions: return: binary - name: "deterministic_decrypt_string" description: "Like `DETERMINISTIC_DECRYPT_BYTES`, but where plaintext is of type STRING." + series_accessor_arg: keyset impls: # Signature: deterministic_decrypt_string:vbin_vbin_str - args: @@ -68,6 +70,7 @@ scalar_functions: return: string - name: "deterministic_encrypt" description: "Encrypts `plaintext` using the primary cryptographic key in `keyset` using deterministic AEAD. The algorithm of the primary key must be `DETERMINISTIC_AEAD_AES_SIV_CMAC_256`. Binds the ciphertext to the context defined by `additional_data`. Returns `NULL` if any input is `NULL`." + series_accessor_arg: keyset impls: # Signature: deterministic_encrypt:vbin_str_str - args: diff --git a/packages/bigframes/scripts/data/sql-functions/global_namespace/array.yaml b/packages/bigframes/scripts/data/sql-functions/global_namespace/array.yaml index a7d01a9143ce..aa9230c251be 100644 --- a/packages/bigframes/scripts/data/sql-functions/global_namespace/array.yaml +++ b/packages/bigframes/scripts/data/sql-functions/global_namespace/array.yaml @@ -2,6 +2,7 @@ urn: extension:google:bq_scalar_functions scalar_functions: - name: "array_concat" description: "Concatenates one or more arrays with the same element type into a single array." + series_accessor_arg: array_expression_1 impls: # Signature: array_concat:list_list - args: @@ -16,6 +17,7 @@ scalar_functions: return: list - name: "array_first" description: "Takes an array and returns the first element in the array." + series_accessor_arg: array_expression impls: # Signature: array_first:list - args: @@ -26,6 +28,7 @@ scalar_functions: return: any1 - name: "array_first_n" description: "Returns a prefix of `input_array` consisting of the first `n` elements." + series_accessor_arg: input_array impls: # Signature: array_first_n:list_i64 - args: @@ -40,6 +43,7 @@ scalar_functions: return: list - name: "array_includes" description: "Takes an array and returns `TRUE` if there is an element in the array that is equal to the search_value." + series_accessor_arg: array_to_search impls: # Signature: array_includes:list_any - args: @@ -54,6 +58,7 @@ scalar_functions: return: boolean - name: "array_includes_all" description: "Takes an array to search and an array of search values. Returns `TRUE` if all search values are in the array to search, otherwise returns `FALSE`." + series_accessor_arg: array_to_search impls: # Signature: array_includes_all:list_list - args: @@ -68,6 +73,7 @@ scalar_functions: return: boolean - name: "array_includes_any" description: "Takes an array to search and an array of search values. Returns `TRUE` if any search values are in the array to search, otherwise returns `FALSE`." + series_accessor_arg: array_to_search impls: # Signature: array_includes_any:list_list - args: @@ -82,6 +88,7 @@ scalar_functions: return: boolean - name: "array_is_distinct" description: "Returns `TRUE` if the array contains no repeated elements, using the same equality comparison logic as `SELECT DISTINCT`." + series_accessor_arg: array_expression impls: # Signature: array_is_distinct:list - args: @@ -92,6 +99,7 @@ scalar_functions: return: boolean - name: "array_last" description: "Takes an array and returns the last element in the array." + series_accessor_arg: array_expression impls: # Signature: array_last:list - args: @@ -116,7 +124,26 @@ scalar_functions: 2 2 dtype: Int64 - You can also apply this function directly to Series. + You can call this function using the Series `bigquery` accessor. + + >>> s.bigquery.array_length() + 0 4 + 1 0 + 2 2 + dtype: Int64 + + You can also use this accessor on a pandas Series after importing bigframes. + + >>> import bigframes + >>> import pandas as pd + >>> ps = pd.Series([[1, 2, 8, 3], [], [3, 4]]) + >>> ps.bigquery.array_length() + 0 4 + 1 0 + 2 2 + dtype: Int64 + + You can also apply this function directly to Series using `apply`. >>> s.apply(bbq.array_length, by_row=False) 0 4 @@ -130,6 +157,7 @@ scalar_functions: Returns: bigframes.series.Series: A Series of integer values indicating the length of each element in the Series. + series_accessor_arg: series impls: # Signature: array_length:list - args: @@ -140,6 +168,7 @@ scalar_functions: return: i64 - name: "array_reverse" description: "Returns the input `ARRAY` with elements in reverse order." + series_accessor_arg: value impls: # Signature: array_reverse:list - args: @@ -150,6 +179,7 @@ scalar_functions: return: list - name: "array_slice" description: "Returns an array containing zero or more consecutive elements from the input array." + series_accessor_arg: array_to_slice impls: # Signature: array_slice:list_i64_i64 - args: @@ -184,6 +214,29 @@ scalar_functions: 4 Hi dtype: string + You can call this function using the Series `bigquery` accessor. + + >>> s.bigquery.array_to_string(delimiter=", ") + 0 H, i, ! + 1 Hello, World + 2 + 3 + 4 Hi + dtype: string + + You can also use this accessor on a pandas Series after importing bigframes. + + >>> import bigframes + >>> import pandas as pd + >>> ps = pd.Series([["H", "i", "!"], ["Hello", "World"], None, [], ["Hi"]]) + >>> ps.bigquery.array_to_string(delimiter=", ") + 0 H, i, ! + 1 Hello, World + 2 + 3 + 4 Hi + dtype: string + Args: series (bigframes.series.Series): A Series containing arrays. delimiter (str): The string used to separate array elements. @@ -191,6 +244,7 @@ scalar_functions: Returns: bigframes.series.Series: A Series containing delimited strings. + series_accessor_arg: series impls: # Signature: array_to_string:list_str_str - args: @@ -224,6 +278,7 @@ scalar_functions: return: binary - name: "flatten" description: "Takes an array of nested data and flattens a specific part of it into a single, flat array with the [array elements field access operator][array-el-field-operator]. Returns `NULL` if the input value is `NULL`." + series_accessor_arg: array_to_flatten impls: # Signature: flatten:list_i64 - args: diff --git a/packages/bigframes/scripts/generate_bigframes_bigquery.py b/packages/bigframes/scripts/generate_bigframes_bigquery.py index afdda2a5f98b..124604354205 100755 --- a/packages/bigframes/scripts/generate_bigframes_bigquery.py +++ b/packages/bigframes/scripts/generate_bigframes_bigquery.py @@ -29,14 +29,20 @@ import jinja2 import yaml +SCRIPTS_DIRECTORY = pathlib.Path(__file__).parent.absolute() +PACKAGE_ROOT = SCRIPTS_DIRECTORY.parent +CODE_ROOT = PACKAGE_ROOT / "bigframes" +SCRIPT_PATH_RELATIVE = pathlib.Path(__file__).relative_to(PACKAGE_ROOT) + # Directory containing the YAML files -DATA_DIR = pathlib.Path("scripts/data/sql-functions") +DATA_DIR = SCRIPTS_DIRECTORY / "data" / "sql-functions" # Directory where the generated Python files will be placed -OUTPUT_DIR = pathlib.Path("bigframes/operations/googlesql") +OUTPUT_DIR = CODE_ROOT / "operations" / "googlesql" # Directory where the generated test files will be placed -TEST_OUTPUT_DIR = pathlib.Path("tests/unit/bigquery/generated") +TEST_OUTPUT_DIR = PACKAGE_ROOT / "tests" / "unit" / "bigquery" / "generated" # Directory containing the Jinja2 templates -TEMPLATE_DIR = pathlib.Path("scripts/templates") +TEMPLATE_DIR = SCRIPTS_DIRECTORY / "templates" + RUFF_COMMON_ARGS = [ "--target-version=py310", @@ -46,7 +52,7 @@ "ruff", "check", "--select", - "I", + "I,F", "--fix", ] + RUFF_COMMON_ARGS RUFF_FORMAT_ARGS = [ @@ -131,6 +137,11 @@ def load_templates(): "test_operation": env.get_template("test_operation.py.j2"), "license": env.get_template("license.py.j2"), "signature_def": env.get_template("signature_def.py.j2"), + "core_series_accessor": env.get_template("core_series_accessor.py.j2"), + "bigframes_series_accessor": env.get_template( + "bigframes_series_accessor.py.j2" + ), + "pandas_series_accessor": env.get_template("pandas_series_accessor.py.j2"), } @@ -212,6 +223,15 @@ def _validate_types(impls): def _generate_signature_def(python_name, impls, sql_name, template): + for impl in impls: + uses_any1 = False + if "any1" in str(impl["return"]): + uses_any1 = True + for arg in impl["args"]: + if "any1" in str(arg["value"]): + uses_any1 = True + impl["uses_any1"] = uses_any1 + return_types = {impl["return"] for impl in impls} # Optimization: if all impls return the same concrete type, @@ -326,6 +346,9 @@ def parse_scalar_functions(data, module_name, signature_def_template, is_global= # Test args test_args = _get_test_args(args_by_name, arg_order) + # Read series_accessor_arg + series_accessor_arg = func_data.get("series_accessor_arg") + functions_list.append( { "name": python_name, @@ -333,6 +356,7 @@ def parse_scalar_functions(data, module_name, signature_def_template, is_global= "description": func_data["description"], "args": func_args, "test_args": test_args, + "series_accessor_arg": series_accessor_arg, } ) @@ -386,6 +410,7 @@ def process_yaml_file(yaml_file, templates): output_file = OUTPUT_DIR.joinpath(module_path).with_suffix(".py") is_global = "global_namespace" in module_path.parts + namespace = get_namespace(yaml_file) ops_list, functions_list = parse_scalar_functions( data, module_name, @@ -396,9 +421,10 @@ def process_yaml_file(yaml_file, templates): # Render and write output_file.parent.mkdir(parents=True, exist_ok=True) ensure_init_py(output_file.parent, OUTPUT_DIR.parent, templates["license"]) + yaml_file_relative = yaml_file.relative_to(PACKAGE_ROOT) content = templates["operation"].render( - yaml_path=str(yaml_file), - script_path="scripts/generate_bigframes_bigquery.py", + yaml_path=yaml_file_relative, + script_path=SCRIPT_PATH_RELATIVE, ops=ops_list, functions=functions_list, ) @@ -419,8 +445,8 @@ def process_yaml_file(yaml_file, templates): test_output_file.parent, TEST_OUTPUT_DIR.parent, templates["license"] ) test_content = templates["test_operation"].render( - yaml_path=str(yaml_file), - script_path="scripts/generate_bigframes_bigquery.py", + yaml_path=yaml_file_relative, + script_path=SCRIPT_PATH_RELATIVE, import_path=import_path, short_name=module_path.name, is_global=is_global, @@ -432,12 +458,149 @@ def process_yaml_file(yaml_file, templates): run_ruff(test_output_file) print(f" Generated {test_output_file}") + # Collect functions for Series accessor + accessor_functions = [] + for func in functions_list: + if func.get("series_accessor_arg"): + import_module = ( + f"bigframes.operations.googlesql.{'.'.join(module_path.parts)}" + ) + accessor_functions.append( + { + "name": func["name"], + "import_module": import_module, + "namespace": namespace, + "description": func["description"], + "args": func["args"], + "series_accessor_arg": func["series_accessor_arg"], + } + ) + + return accessor_functions + + +def get_namespace(yaml_file: pathlib.Path) -> tuple[str, ...] | None: + rel_path = yaml_file.relative_to(DATA_DIR) + parts = rel_path.with_suffix("").parts + if "global_namespace" in parts: + return None + return parts + + +def get_class_name(ns_tuple: tuple[str, ...], prefix: str = "") -> str: + if not ns_tuple: + return f"{prefix}BigQuerySeriesAccessor" + camel_parts = [part.capitalize() for part in ns_tuple] + return f"{prefix}{''.join(camel_parts)}SeriesAccessor" + + +def generate_series_accessors(functions: list[dict], templates: dict): + print("Generating Series accessors...") + # Find all active namespaces + active_namespaces = set() + for func in functions: + ns = func["namespace"] or () + for i in range(len(ns) + 1): + active_namespaces.add(ns[:i]) + + # Sort namespaces by depth so parents come first + sorted_namespaces = sorted(list(active_namespaces), key=len) + + # Build namespace definitions + ns_defs = [] + ns_by_tuple = {} + for ns in sorted_namespaces: + class_name = get_class_name(ns) + bf_class_name = get_class_name(ns, prefix="Bigframes") + pd_class_name = get_class_name(ns, prefix="Pandas") + + ns_def = { + "ns_tuple": ns, + "class_name": class_name, + "bigframes_class_name": bf_class_name, + "pandas_class_name": pd_class_name, + "is_root": len(ns) == 0, + "description": ( + f"Series accessor for BigQuery {'.'.join(ns)} functions." + if ns + else "Series accessor for BigQuery functions." + ), + "children": [], + "functions": [], + } + ns_defs.append(ns_def) + ns_by_tuple[ns] = ns_def + + # Populate functions + for func in functions: + ns = func["namespace"] or () + ns_by_tuple[ns]["functions"].append(func) + + # Populate children properties + for ns in sorted_namespaces: + if len(ns) > 0: + parent_ns = ns[:-1] + parent_def = ns_by_tuple[parent_ns] + child_def = ns_by_tuple[ns] + parent_def["children"].append( + { + "prop_name": ns[-1], + "class_name": child_def["class_name"], + "bigframes_class_name": child_def["bigframes_class_name"], + "pandas_class_name": child_def["pandas_class_name"], + } + ) + + # Render and write core + core_output_file = CODE_ROOT / "extensions" / "core" / "series_accessor.py" + core_output_file.parent.mkdir(parents=True, exist_ok=True) + ensure_init_py(core_output_file.parent, CODE_ROOT, templates["license"]) + core_content = templates["core_series_accessor"].render( + script_path=SCRIPT_PATH_RELATIVE, + namespaces=ns_defs, + ) + with open(core_output_file, "w") as f: + f.write(core_content) + run_ruff(core_output_file) + print(f" Generated {core_output_file}") + + # Render and write bigframes + bf_output_file = CODE_ROOT / "extensions" / "bigframes" / "series_accessor.py" + bf_output_file.parent.mkdir(parents=True, exist_ok=True) + ensure_init_py(bf_output_file.parent, CODE_ROOT, templates["license"]) + bf_content = templates["bigframes_series_accessor"].render( + script_path=SCRIPT_PATH_RELATIVE, + namespaces=ns_defs, + ) + with open(bf_output_file, "w") as f: + f.write(bf_content) + run_ruff(bf_output_file) + print(f" Generated {bf_output_file}") + + # Render and write pandas + pd_output_file = CODE_ROOT / "extensions" / "pandas" / "series_accessor.py" + pd_output_file.parent.mkdir(parents=True, exist_ok=True) + ensure_init_py(pd_output_file.parent, CODE_ROOT, templates["license"]) + pd_content = templates["pandas_series_accessor"].render( + script_path=SCRIPT_PATH_RELATIVE, + namespaces=ns_defs, + ) + with open(pd_output_file, "w") as f: + f.write(pd_content) + run_ruff(pd_output_file) + print(f" Generated {pd_output_file}") + def main(): templates = load_templates() + all_accessor_functions = [] for yaml_file in sorted(DATA_DIR.glob("**/*.yaml")): - process_yaml_file(yaml_file, templates) + accessor_funcs = process_yaml_file(yaml_file, templates) + all_accessor_functions.extend(accessor_funcs) + + if all_accessor_functions: + generate_series_accessors(all_accessor_functions, templates) if __name__ == "__main__": diff --git a/packages/bigframes/scripts/templates/bigframes_series_accessor.py.j2 b/packages/bigframes/scripts/templates/bigframes_series_accessor.py.j2 new file mode 100644 index 000000000000..f5ed3d045485 --- /dev/null +++ b/packages/bigframes/scripts/templates/bigframes_series_accessor.py.j2 @@ -0,0 +1,41 @@ +{% include 'license.py.j2' %} + +# +# DO NOT MODIFY THIS FILE DIRECTLY. +# This file was generated by the script: {{ script_path }} +# + +from __future__ import annotations + +from typing import cast, Optional, TypeVar + +from bigframes.core.logging import log_adapter +import bigframes.extensions.core.series_accessor as core_accessor +import bigframes.series +import bigframes.session + +S = TypeVar("S", bound="bigframes.series.Series") + + +{% for ns in namespaces %} +@log_adapter.class_logger +class {{ ns.bigframes_class_name }}(core_accessor.{{ ns.class_name }}[S]): + def __init__(self, bf_obj: S): + super().__init__(bf_obj) + + def _bf_from_series( + self, session: Optional[bigframes.session.Session] = None + ) -> bigframes.series.Series: + return self._obj + + def _to_series(self, bf_series: bigframes.series.Series) -> S: + return cast(S, bf_series) + + {% for child in ns.children %} + @property + def {{ child.prop_name }}(self) -> {{ child.bigframes_class_name }}[S]: + return {{ child.bigframes_class_name }}(self._obj) + + {% endfor %} + +{% endfor %} diff --git a/packages/bigframes/scripts/templates/core_series_accessor.py.j2 b/packages/bigframes/scripts/templates/core_series_accessor.py.j2 new file mode 100644 index 000000000000..5881fe6963b9 --- /dev/null +++ b/packages/bigframes/scripts/templates/core_series_accessor.py.j2 @@ -0,0 +1,92 @@ +{% include 'license.py.j2' %} + +# +# DO NOT MODIFY THIS FILE DIRECTLY. +# This file was generated by the script: {{ script_path }} +# + +from __future__ import annotations + +import abc +from typing import ( + Any, + cast, + Generic, + Literal, + Optional, + TypeVar, + Union, +) + +from bigframes import dtypes +import bigframes.core.col +import bigframes.core.sentinels as sentinels +import bigframes.series as series +import bigframes.session + +S = TypeVar("S") + +class AbstractBigQuerySeriesAccessor(abc.ABC, Generic[S]): + def __init__(self, obj: S): + self._obj = obj + + @abc.abstractmethod + def _bf_from_series( + self, session: Optional[bigframes.session.Session] = None + ) -> series.Series: + """Convert the accessor's object to a BigFrames Series.""" + + @abc.abstractmethod + def _to_series(self, bf_series: series.Series) -> S: + """Convert a BigFrames Series to the accessor's object type.""" + + +{% for ns in namespaces %} +class {{ ns.class_name }}(AbstractBigQuerySeriesAccessor[S]): + """{{ ns.description }}""" + + {% for child in ns.children %} + @property + @abc.abstractmethod + def {{ child.prop_name }}(self) -> {{ child.class_name }}[S]: + """Accessor for BigQuery {{ child.prop_name }} functions.""" + + {% endfor %} + {% for func in ns.functions %} + def {{ func.name }}( + self, + {% for arg in func.args if arg.name != func.series_accessor_arg %} + {{ arg.name }}: Union[series.Series, bigframes.core.col.Expression, {{ arg.type_hint }}]{% if arg.default %} = {{ arg.default }}{% endif %}, + {% endfor %} + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """{{ func.description | indent(8) }}""" + from {{ func.import_module }} import {{ func.name }} as {{ func.name }}_impl + {% if func.args | length > 1 %} + + # Resolve session from other arguments if not passed + if session is None: + import bigframes.core.googlesql as googlesql + session = googlesql._find_session( + {% for arg in func.args if arg.name != func.series_accessor_arg %} + {{ arg.name }}, + {% endfor %} + ) + {% endif %} + + bf_series = self._bf_from_series(session) + result = {{ func.name }}_impl( + {% for arg in func.args %} + {% if arg.name == func.series_accessor_arg %} + bf_series, + {% else %} + {{ arg.name }}, + {% endif %} + {% endfor %} + ) + return self._to_series(cast(series.Series, result)) + + {% endfor %} + +{% endfor %} diff --git a/packages/bigframes/scripts/templates/pandas_series_accessor.py.j2 b/packages/bigframes/scripts/templates/pandas_series_accessor.py.j2 new file mode 100644 index 000000000000..76f3d4797531 --- /dev/null +++ b/packages/bigframes/scripts/templates/pandas_series_accessor.py.j2 @@ -0,0 +1,50 @@ +{% include 'license.py.j2' %} + +# +# DO NOT MODIFY THIS FILE DIRECTLY. +# This file was generated by the script: {{ script_path }} +# + +from __future__ import annotations + +from typing import cast, Optional, TypeVar + +import pandas +import pandas.api.extensions + +import bigframes.core.global_session as bf_session +from bigframes.core.logging import log_adapter +import bigframes.extensions.core.series_accessor as core_accessor +import bigframes.series +import bigframes.session + +S = TypeVar("S", bound="pandas.Series") + + +{% for ns in namespaces %} +{% if ns.is_root %} +@pandas.api.extensions.register_series_accessor("bigquery") +{% endif %} +@log_adapter.class_logger +class {{ ns.pandas_class_name }}(core_accessor.{{ ns.class_name }}[S]): + def __init__(self, pandas_obj: S): + super().__init__(pandas_obj) + + def _bf_from_series( + self, session: Optional[bigframes.session.Session] = None + ) -> bigframes.series.Series: + if session is None: + session = bf_session.get_global_session() + return cast(bigframes.series.Series, session.read_pandas(self._obj)) + + def _to_series(self, bf_series: bigframes.series.Series) -> S: + return cast(S, bf_series.to_pandas(ordered=True)) + + {% for child in ns.children %} + @property + def {{ child.prop_name }}(self) -> {{ child.pandas_class_name }}[S]: + return {{ child.pandas_class_name }}(self._obj) + + {% endfor %} + +{% endfor %} diff --git a/packages/bigframes/scripts/templates/signature_def.py.j2 b/packages/bigframes/scripts/templates/signature_def.py.j2 index ad1871f7df6d..341b889df4b8 100644 --- a/packages/bigframes/scripts/templates/signature_def.py.j2 +++ b/packages/bigframes/scripts/templates/signature_def.py.j2 @@ -3,7 +3,9 @@ def {{ func_name }}(*args): args = args + (None,) * ({{ max_args }} - len(args)) {% for impl in impls %} # Try matching impl {{ loop.index0 }} + {% if impl.uses_any1 %} any1_val = None + {% endif %} match_ok = True {% for arg in impl.args %} {% set idx = loop.index0 %} diff --git a/packages/bigframes/tests/unit/extensions/bigframes/__init__.py b/packages/bigframes/tests/unit/extensions/bigframes/__init__.py new file mode 100644 index 000000000000..58d482ea3866 --- /dev/null +++ b/packages/bigframes/tests/unit/extensions/bigframes/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2026 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/packages/bigframes/tests/unit/extensions/bigframes/test_series_accessor.py b/packages/bigframes/tests/unit/extensions/bigframes/test_series_accessor.py new file mode 100644 index 000000000000..4c74b60a1a03 --- /dev/null +++ b/packages/bigframes/tests/unit/extensions/bigframes/test_series_accessor.py @@ -0,0 +1,78 @@ +# Copyright 2026 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 cast +from unittest.mock import MagicMock, patch + +import pytest + +import bigframes.series as series +from bigframes.testing import mocks + + +def test_bigframes_series_has_accessor(monkeypatch: pytest.MonkeyPatch): + # Arrange + from bigframes.extensions.bigframes.series_accessor import ( + BigframesBigQuerySeriesAccessor, + ) + + bf_df = mocks.create_dataframe(monkeypatch, data={"col": [1, 2]}) + bf_series = cast(series.Series, bf_df["col"]) + + # Act + has_bq = hasattr(bf_series, "bigquery") + bq_obj = bf_series.bigquery + + # Assert + assert has_bq + assert isinstance(bq_obj, BigframesBigQuerySeriesAccessor) + + +@patch("bigframes.operations.googlesql.global_namespace.array.array_length") +def test_bigframes_series_accessor_global_routing( + mock_array_length, monkeypatch: pytest.MonkeyPatch +): + # Arrange + bf_df = mocks.create_dataframe(monkeypatch, data={"col": [[1, 2], [3, 4, 5]]}) + bf_series = cast(series.Series, bf_df["col"]) + mock_result_series = MagicMock() + mock_array_length.return_value = mock_result_series + + # Act + result = bf_series.bigquery.array_length() + + # Assert + mock_array_length.assert_called_once_with(bf_series) + assert result is mock_result_series + + +@patch("bigframes.operations.googlesql.aead.encrypt") +def test_bigframes_series_accessor_namespaced_routing( + mock_encrypt, monkeypatch: pytest.MonkeyPatch +): + # Arrange + bf_df = mocks.create_dataframe(monkeypatch, data={"keyset": [b"key1", b"key2"]}) + keyset_series = cast(series.Series, bf_df["keyset"]) + mock_result_series = MagicMock() + mock_encrypt.return_value = mock_result_series + + plaintext = "my secret" + additional_data = "context" + + # Act + result = keyset_series.bigquery.aead.encrypt(plaintext, additional_data) + + # Assert + mock_encrypt.assert_called_once_with(keyset_series, plaintext, additional_data) + assert result is mock_result_series diff --git a/packages/bigframes/tests/unit/extensions/pandas/test_series_accessor.py b/packages/bigframes/tests/unit/extensions/pandas/test_series_accessor.py new file mode 100644 index 000000000000..bfb68323f6da --- /dev/null +++ b/packages/bigframes/tests/unit/extensions/pandas/test_series_accessor.py @@ -0,0 +1,136 @@ +# Copyright 2026 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 unittest.mock import MagicMock, patch + +import pandas as pd + +import bigframes # noqa: F401 registers pandas extensions +import bigframes.series as series + + +def test_pandas_series_registers_accessor(): + # Arrange + from bigframes.extensions.pandas.series_accessor import ( + PandasBigQuerySeriesAccessor, + ) + + s = pd.Series([1, 2]) + + # Act + has_bq = hasattr(s, "bigquery") + bq_obj = s.bigquery + + # Assert + assert has_bq + assert isinstance(bq_obj, PandasBigQuerySeriesAccessor) + + +@patch("bigframes.operations.googlesql.global_namespace.array.array_length") +def test_pandas_series_accessor_global_routing(mock_array_length): + # Arrange + mock_bf_series = MagicMock() + mock_bf_series.to_pandas.return_value = pd.Series([2, 3]) + mock_array_length.return_value = mock_bf_series + mock_session = MagicMock() + mock_bf_self = MagicMock() + mock_session.read_pandas.return_value = mock_bf_self + + s = pd.Series([[1, 2], [3, 4, 5]]) + + # Act + result = s.bigquery.array_length(session=mock_session) + + # Assert + mock_session.read_pandas.assert_called_once_with(s) + mock_array_length.assert_called_once_with(mock_bf_self) + mock_bf_series.to_pandas.assert_called_once_with(ordered=True) + pd.testing.assert_series_equal(result, pd.Series([2, 3])) + + +@patch("bigframes.operations.googlesql.aead.encrypt") +def test_pandas_series_accessor_namespaced_routing(mock_encrypt): + # Arrange + mock_bf_series = MagicMock() + mock_bf_series.to_pandas.return_value = pd.Series([b"encrypted1", b"encrypted2"]) + mock_encrypt.return_value = mock_bf_series + mock_session = MagicMock() + mock_bf_self = MagicMock() + mock_session.read_pandas.return_value = mock_bf_self + + keyset_series = pd.Series([b"key1", b"key2"]) + plaintext = "my secret" + additional_data = "context" + + # Act + result = keyset_series.bigquery.aead.encrypt( # type: ignore + plaintext, additional_data, session=mock_session + ) + + # Assert + mock_session.read_pandas.assert_called_once_with(keyset_series) + mock_encrypt.assert_called_once_with(mock_bf_self, plaintext, additional_data) + mock_bf_series.to_pandas.assert_called_once_with(ordered=True) + pd.testing.assert_series_equal(result, pd.Series([b"encrypted1", b"encrypted2"])) + + +@patch("bigframes.operations.googlesql.global_namespace.array.array_concat") +def test_pandas_series_accessor_global_routing_uses_series_session(mock_array_concat): + # Arrange + mock_bf_series = MagicMock() + mock_bf_series.to_pandas.return_value = pd.Series([[1, 2, 3, 4]]) + mock_array_concat.return_value = mock_bf_series + mock_session = MagicMock() + mock_bf_other = MagicMock(spec=series.Series) + mock_bf_other._session = mock_session + mock_bf_self = MagicMock() + mock_session.read_pandas.return_value = mock_bf_self + s = pd.Series([[1, 2]]) + + # Act + result = s.bigquery.array_concat(mock_bf_other) + + # Assert + assert result is not None + mock_session.read_pandas.assert_called_once_with(s) + mock_array_concat.assert_called_once_with(mock_bf_self, mock_bf_other) + + +@patch("bigframes.operations.googlesql.aead.encrypt") +def test_pandas_series_accessor_namespaced_routing_uses_series_session( + mock_encrypt, +): + # Arrange + mock_bf_series = MagicMock() + mock_bf_series.to_pandas.return_value = pd.Series([b"encrypted1", b"encrypted2"]) + mock_encrypt.return_value = mock_bf_series + mock_session = MagicMock() + mock_bf_plaintext = MagicMock(spec=series.Series) + mock_bf_plaintext._session = mock_session + mock_bf_self = MagicMock() + mock_session.read_pandas.return_value = mock_bf_self + keyset_series = pd.Series([b"key1", b"key2"]) + additional_data = "context" + + # Act + result = keyset_series.bigquery.aead.encrypt( # type: ignore + mock_bf_plaintext, additional_data + ) + + # Assert + assert result is not None + mock_session.read_pandas.assert_called_once_with(keyset_series) + mock_encrypt.assert_called_once_with( + mock_bf_self, mock_bf_plaintext, additional_data + ) From 72c7a2728bf66d684a12fdaac59c089115a53246 Mon Sep 17 00:00:00 2001 From: Chandra Shekhar Sirimala Date: Thu, 4 Jun 2026 15:12:05 +0530 Subject: [PATCH 023/174] feat(storage): Enable full object checksum PR 1/3 : parse finalize_time and server crc32c in async object stream (#17261) ### 1. Overview of the Solution This solution implements end-to-end full-object checksum validation in `AsyncMultiRangeDownloader` for the asynchronous Google Cloud Storage Python client library. As asynchronous multiplexed downloads of non-contiguous ranges are performed concurrently over a single bidirectional gRPC connection, this feature automatically and incrementally calculates a rolling checksum as bytes arrive and validates it against the server's authoritative object checksum once the download completes. The technical approach consists of three coordinated layers: * **`_AsyncReadObjectStream` (Stream Ingestion)**: Safely extracts the authoritative server checksum (`full_obj_server_crc32c`) and finalization status (`is_finalized`) from the object metadata received in the first data payload response of the stream. * **`_ReadResumptionStrategy` & `_DownloadState` (Verification Logic)**: Computes an isolated, persistent rolling checksum in the individual `_DownloadState` object to ensure calculations do not bleed across concurrent multiplexed ranges. Crucially, the rolling hash updates only *after* buffer writes succeed to prevent state corruption during retry re-connects, raising a `DataCorruption` exception on completion if a mismatch occurs. * **`AsyncMultiRangeDownloader` (Orchestration & Cleanup)**: Detects candidate full-object ranges (e.g., `(0, 0)` or `(0, persisted_size)`), propagates checksum settings to the resumption strategy, and guarantees robust cleanup (closing the stream immediately and unregistering IDs) if data corruption or write errors occur. ### 2. What This PR Specifically Does This PR implements **Step 1: Stream Metadata Ingestion** of the solution: * Modifies `_AsyncReadObjectStream` to safely parse GCS object metadata from the first data payload of the response. * Populates `is_finalized`, `full_obj_server_crc32c`, and `object_metadata` attributes in `_AsyncReadObjectStream.open()`. * Adds an autouse pytest event loop fixture in `tests/unit/conftest.py` to resolve compatibility issues with `pytest-asyncio` under Python 3.11+. * Adds unit tests in `test_async_read_object_stream.py` to verify that finalization status and server-authoritative checksums are correctly extracted or skipped for unfinalized objects. --- .../asyncio/async_read_object_stream.py | 15 +++++++ .../asyncio/test_async_read_object_stream.py | 39 ++++++++++++++++++- .../tests/unit/conftest.py | 32 +++++++++++++++ 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 packages/google-cloud-storage/tests/unit/conftest.py diff --git a/packages/google-cloud-storage/google/cloud/storage/asyncio/async_read_object_stream.py b/packages/google-cloud-storage/google/cloud/storage/asyncio/async_read_object_stream.py index cd7ae067c631..8fd98d623571 100644 --- a/packages/google-cloud-storage/google/cloud/storage/asyncio/async_read_object_stream.py +++ b/packages/google-cloud-storage/google/cloud/storage/asyncio/async_read_object_stream.py @@ -79,6 +79,9 @@ def __init__( self.socket_like_rpc: Optional[AsyncBidiRpc] = None self._is_stream_open: bool = False self.persisted_size: Optional[int] = None + self.is_finalized: bool = False + self.full_obj_server_crc32c: Optional[int] = None + self.object_metadata: Optional[_storage_v2.Object] = None async def open(self, metadata: Optional[List[Tuple[str, str]]] = None) -> None: """Opens the bidi-gRPC connection to read from the object. @@ -132,6 +135,18 @@ async def open(self, metadata: Optional[List[Tuple[str, str]]] = None) -> None: self.generation_number = response.metadata.generation # update persisted size self.persisted_size = response.metadata.size + self.object_metadata = response.metadata + if ( + hasattr(response.metadata, "finalize_time") + and response.metadata.finalize_time + and response.metadata.finalize_time.second > 0 + ): + self.is_finalized = True + if ( + hasattr(response.metadata, "checksums") + and response.metadata.checksums + ): + self.full_obj_server_crc32c = response.metadata.checksums.crc32c if response and response.read_handle: self.read_handle = response.read_handle diff --git a/packages/google-cloud-storage/tests/unit/asyncio/test_async_read_object_stream.py b/packages/google-cloud-storage/tests/unit/asyncio/test_async_read_object_stream.py index f5783be6bf94..a8f64422765e 100644 --- a/packages/google-cloud-storage/tests/unit/asyncio/test_async_read_object_stream.py +++ b/packages/google-cloud-storage/tests/unit/asyncio/test_async_read_object_stream.py @@ -38,9 +38,11 @@ async def instantiate_read_obj_stream(mock_client, mock_cls_async_bidi_rpc, open socket_like_rpc.open = AsyncMock() recv_response = mock.MagicMock(spec=_storage_v2.BidiReadObjectResponse) - recv_response.metadata = mock.MagicMock(spec=_storage_v2.Object) + recv_response.metadata = mock.MagicMock() recv_response.metadata.generation = _TEST_GENERATION_NUMBER recv_response.metadata.size = _TEST_OBJECT_SIZE + recv_response.metadata.finalize_time.second = 30 + recv_response.metadata.checksums.crc32c = 98765 recv_response.read_handle = _TEST_READ_HANDLE socket_like_rpc.recv = AsyncMock(return_value=recv_response) @@ -130,6 +132,8 @@ async def test_open(mock_client, mock_cls_async_bidi_rpc): assert read_obj_stream.generation_number == _TEST_GENERATION_NUMBER assert read_obj_stream.read_handle == _TEST_READ_HANDLE assert read_obj_stream.persisted_size == _TEST_OBJECT_SIZE + assert read_obj_stream.is_finalized is True + assert read_obj_stream.full_obj_server_crc32c == 98765 assert read_obj_stream.is_stream_open @@ -381,3 +385,36 @@ async def test_recv_updates_read_handle_on_refresh( await stream.recv() assert stream.read_handle == refreshed_handle + + +@mock.patch("google.cloud.storage.asyncio.async_read_object_stream.AsyncBidiRpc") +@mock.patch( + "google.cloud.storage.asyncio.async_grpc_client.AsyncGrpcClient.grpc_client" +) +@pytest.mark.asyncio +async def test_open_unfinalized_object_skips_checksum( + mock_client, mock_cls_async_bidi_rpc +): + socket_like_rpc = AsyncMock() + mock_cls_async_bidi_rpc.return_value = socket_like_rpc + socket_like_rpc.open = AsyncMock() + + recv_response = mock.MagicMock(spec=_storage_v2.BidiReadObjectResponse) + recv_response.metadata = mock.MagicMock() + recv_response.metadata.generation = _TEST_GENERATION_NUMBER + recv_response.metadata.size = _TEST_OBJECT_SIZE + recv_response.metadata.finalize_time.second = 0 # NOT finalized! + recv_response.metadata.checksums.crc32c = 98765 + recv_response.read_handle = _TEST_READ_HANDLE + socket_like_rpc.recv = AsyncMock(return_value=recv_response) + + read_obj_stream = _AsyncReadObjectStream( + client=mock_client, + bucket_name=_TEST_BUCKET_NAME, + object_name=_TEST_OBJECT_NAME, + ) + + await read_obj_stream.open() + + assert read_obj_stream.is_finalized is False + assert read_obj_stream.full_obj_server_crc32c is None diff --git a/packages/google-cloud-storage/tests/unit/conftest.py b/packages/google-cloud-storage/tests/unit/conftest.py new file mode 100644 index 000000000000..2eeabdc990e6 --- /dev/null +++ b/packages/google-cloud-storage/tests/unit/conftest.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 asyncio +import pytest + + +@pytest.fixture(autouse=True) +def set_event_loop(): + try: + asyncio.get_running_loop() + yield + except RuntimeError: + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + try: + yield + finally: + loop.close() + asyncio.set_event_loop(None) From e4a207d9cb3aea6bedaf2e7c5d3994715dcbc58c Mon Sep 17 00:00:00 2001 From: Chandra Shekhar Sirimala Date: Thu, 4 Jun 2026 15:37:20 +0530 Subject: [PATCH 024/174] chore(storage): support DISABLE_GCS_PYTHON_CLIENT_OTEL_BUCKET_METADATA environment variable flag (#17248) This PR introduces the `DISABLE_GCS_PYTHON_CLIENT_OTEL_BUCKET_METADATA` environment flag to dynamically disable injecting Cloud Storage bucket metadata destination attributes (`gcp.resource.destination.id` and `gcp.resource.destination.location`) inside OTel spans. --- .../google/cloud/storage/_helpers.py | 2 + .../google/cloud/storage/_http.py | 2 + .../cloud/storage/_opentelemetry_tracing.py | 6 +++ .../tests/system/test_aco_observability.py | 37 +++++++++++++++++++ .../tests/unit/test__opentelemetry_tracing.py | 31 ++++++++++++++++ 5 files changed, 78 insertions(+) diff --git a/packages/google-cloud-storage/google/cloud/storage/_helpers.py b/packages/google-cloud-storage/google/cloud/storage/_helpers.py index ffa9fe177ea3..04039971ef41 100644 --- a/packages/google-cloud-storage/google/cloud/storage/_helpers.py +++ b/packages/google-cloud-storage/google/cloud/storage/_helpers.py @@ -34,6 +34,7 @@ from google.cloud.storage._opentelemetry_tracing import ( create_trace_span as _base_create_trace_span, + _is_bucket_metadata_disabled, ) from google.cloud.storage.constants import _DEFAULT_TIMEOUT from google.cloud.storage.retry import ( @@ -156,6 +157,7 @@ def create_trace_span_helper(client, bucket_name, name, attributes=None, **kwarg and client and hasattr(client, "_bucket_metadata_cache") and client._bucket_metadata_cache + and not _is_bucket_metadata_disabled() ): try: if name in ( diff --git a/packages/google-cloud-storage/google/cloud/storage/_http.py b/packages/google-cloud-storage/google/cloud/storage/_http.py index ca7c90e2061a..bfe2bf3843af 100644 --- a/packages/google-cloud-storage/google/cloud/storage/_http.py +++ b/packages/google-cloud-storage/google/cloud/storage/_http.py @@ -27,6 +27,7 @@ HAS_OPENTELEMETRY, create_trace_span, enable_otel_traces, + _is_bucket_metadata_disabled, ) logger = logging.getLogger(__name__) @@ -88,6 +89,7 @@ def api_request(self, *args, **kwargs): and enable_otel_traces and hasattr(client, "_bucket_metadata_cache") and client._bucket_metadata_cache + and not _is_bucket_metadata_disabled() ): path = kwargs.get("path") or "" match = re.search(r"/b/([^/?#]+)", path) diff --git a/packages/google-cloud-storage/google/cloud/storage/_opentelemetry_tracing.py b/packages/google-cloud-storage/google/cloud/storage/_opentelemetry_tracing.py index 173fa090fcb5..1d9e4b88270b 100644 --- a/packages/google-cloud-storage/google/cloud/storage/_opentelemetry_tracing.py +++ b/packages/google-cloud-storage/google/cloud/storage/_opentelemetry_tracing.py @@ -27,6 +27,7 @@ ENABLE_OTEL_TRACES_ENV_VAR = "ENABLE_GCS_PYTHON_CLIENT_OTEL_TRACES" _DEFAULT_ENABLE_OTEL_TRACES_VALUE = False +DISABLE_BUCKET_MD_ENV_VAR = "DISABLE_GCS_PYTHON_CLIENT_OTEL_BUCKET_METADATA" def _parse_bool_env(name: str, default: bool = False) -> bool: @@ -36,11 +37,16 @@ def _parse_bool_env(name: str, default: bool = False) -> bool: return str(val).strip().lower() in {"1", "true", "yes", "on"} +def _is_bucket_metadata_disabled() -> bool: + return _parse_bool_env(DISABLE_BUCKET_MD_ENV_VAR, False) + + enable_otel_traces = _parse_bool_env( ENABLE_OTEL_TRACES_ENV_VAR, _DEFAULT_ENABLE_OTEL_TRACES_VALUE ) logger = logging.getLogger(__name__) + try: from opentelemetry import trace diff --git a/packages/google-cloud-storage/tests/system/test_aco_observability.py b/packages/google-cloud-storage/tests/system/test_aco_observability.py index b1de4ae87025..280a7d05badb 100644 --- a/packages/google-cloud-storage/tests/system/test_aco_observability.py +++ b/packages/google-cloud-storage/tests/system/test_aco_observability.py @@ -549,3 +549,40 @@ def monitored_update(*args, **kwargs): assert attrs["gcp.resource.destination.location"] == "global" finally: storage_client._bucket_metadata_cache.update_cache = original_update + + +@pytest.mark.parametrize("env_value", ["true", "1", "yes", "on"]) +def test_disable_bucket_md_env_flag( + storage_client, exporter, buckets_to_delete, monkeypatch, env_value +): + """Verifies that setting DISABLE_GCS_PYTHON_CLIENT_OTEL_BUCKET_METADATA to a truthy value disables GCS + destination annotations, even on cache hits.""" + # Clear cache and OTel exporter logs + storage_client._bucket_metadata_cache.clear() + exporter.clear() + + bucket_name = _helpers.unique_name("aco-disable") + bucket = storage_client.bucket(bucket_name) + storage_client.create_bucket(bucket) + buckets_to_delete.append(bucket) + + blob_name = "test_blob.txt" + blob = bucket.blob(blob_name) + blob.upload_from_string("hello") + + # Warm cache directly via GCS creation warming (client.create_bucket already primes the cache) + assert storage_client._bucket_metadata_cache.get(bucket_name) is not None + + # Enable the DISABLE_GCS_PYTHON_CLIENT_OTEL_BUCKET_METADATA environment variable using monkeypatch + monkeypatch.setenv("DISABLE_GCS_PYTHON_CLIENT_OTEL_BUCKET_METADATA", env_value) + + # Download (normally would be a cache hit with GCS annotations) + blob.download_as_bytes() + + # Verify that ACO attributes are NOT present in the OTel span! + spans = exporter.get_finished_spans() + dl_spans = [s for s in spans if s.name == "Storage.Blob.downloadAsBytes"] + assert len(dl_spans) == 1 + attrs = dl_spans[0].attributes + assert "gcp.resource.destination.id" not in attrs + assert "gcp.resource.destination.location" not in attrs diff --git a/packages/google-cloud-storage/tests/unit/test__opentelemetry_tracing.py b/packages/google-cloud-storage/tests/unit/test__opentelemetry_tracing.py index 9a17281906e7..70722bb0b0f8 100644 --- a/packages/google-cloud-storage/tests/unit/test__opentelemetry_tracing.py +++ b/packages/google-cloud-storage/tests/unit/test__opentelemetry_tracing.py @@ -321,3 +321,34 @@ def test__parse_bool_env(monkeypatch, env_value, default, expected): result = _opentelemetry_tracing._parse_bool_env(env_var_name, default) assert result is expected + + +@pytest.mark.parametrize( + "env_value, expected", + [ + # Test default (not set) + (None, False), + # Test truthy values + ("true", True), + ("1", True), + ("yes", True), + ("on", True), + ("TRUE", True), + (" Yes ", True), + # Test falsy values + ("false", False), + ("0", False), + ("no", False), + ("off", False), + ("any_other_string", False), + ("", False), + ], +) +def test__is_bucket_metadata_disabled(monkeypatch, env_value, expected): + env_var_name = "DISABLE_GCS_PYTHON_CLIENT_OTEL_BUCKET_METADATA" + if env_value is not None: + monkeypatch.setenv(env_var_name, str(env_value)) + else: + monkeypatch.delenv(env_var_name, raising=False) + + assert _opentelemetry_tracing._is_bucket_metadata_disabled() is expected From 2361ba6eeb766722b9460f3eb1dc1286c6fb19f3 Mon Sep 17 00:00:00 2001 From: Chandra Shekhar Sirimala Date: Thu, 4 Jun 2026 16:52:34 +0530 Subject: [PATCH 025/174] feat(storage): full object checksum: implement rolling checksum and verification in reads resumption strategy (#17262) ### 1. Overview of the Solution This solution implements end-to-end full-object checksum validation in `AsyncMultiRangeDownloader` for the asynchronous Google Cloud Storage Python client library. As asynchronous multiplexed downloads of non-contiguous ranges are performed concurrently over a single bidirectional gRPC connection, this feature automatically and incrementally calculates a rolling checksum as bytes arrive and validates it against the server's authoritative object checksum once the download completes. The technical approach consists of three coordinated layers: * **`_AsyncReadObjectStream` (Stream Ingestion)**: Safely extracts the authoritative server checksum (`full_obj_server_crc32c`) and finalization status (`is_finalized`) from the object metadata received in the first data payload response of the stream. * **`_ReadResumptionStrategy` & `_DownloadState` (Verification Logic)**: Computes an isolated, persistent rolling checksum in the individual `_DownloadState` object to ensure calculations do not bleed across concurrent multiplexed ranges. Crucially, the rolling hash updates only *after* buffer writes succeed to prevent state corruption during retry re-connects, raising a `DataCorruption` exception on completion if a mismatch occurs. * **`AsyncMultiRangeDownloader` (Orchestration & Cleanup)**: Detects candidate full-object ranges (e.g., `(0, 0)` or `(0, persisted_size)`), propagates checksum settings to the resumption strategy, and guarantees robust cleanup (closing the stream immediately and unregistering IDs) if data corruption or write errors occur. ### 2. What This PR Specifically Does This PR implements **Step 2: Full-Object Rolling Checksum & Resumption Verification Logic** of the solution: * Upgrades `_DownloadState` to track `is_full_object_read` and initialize an isolated `google_crc32c.Checksum()` rolling instance. * Updates `_ReadResumptionStrategy.update_state_from_response()` to run buffer writes *before* updating the rolling checksum, ensuring transactional safety during connection failures and retry reconnects. * Optimizes performance by bypassing rolling checksum calculations entirely if `enable_checksum` is `False`. * Performs the final validation match at `range_end` against the server's authoritative checksum, raising a `DataCorruption` exception if a mismatch is found. * Adds comprehensive unit tests in `test_reads_resumption_strategy.py` to verify successful validation, failure exceptions, and bypassed checks when validation is disabled. --- .../retry/reads_resumption_strategy.py | 42 ++++++- .../retry/test_reads_resumption_strategy.py | 116 +++++++++++++++++- 2 files changed, 153 insertions(+), 5 deletions(-) diff --git a/packages/google-cloud-storage/google/cloud/storage/asyncio/retry/reads_resumption_strategy.py b/packages/google-cloud-storage/google/cloud/storage/asyncio/retry/reads_resumption_strategy.py index 845770c3a215..6cf17af19089 100644 --- a/packages/google-cloud-storage/google/cloud/storage/asyncio/retry/reads_resumption_strategy.py +++ b/packages/google-cloud-storage/google/cloud/storage/asyncio/retry/reads_resumption_strategy.py @@ -36,7 +36,12 @@ class _DownloadState: """A helper class to track the state of a single range download.""" def __init__( - self, initial_offset: int, initial_length: int, user_buffer: IO[bytes] + self, + initial_offset: int, + initial_length: int, + user_buffer: IO[bytes], + is_full_object_read: bool = False, + enable_checksum: bool = True, ): self.initial_offset = initial_offset self.initial_length = initial_length @@ -44,6 +49,12 @@ def __init__( self.bytes_written = 0 self.next_expected_offset = initial_offset self.is_complete = False + self.is_full_object_read = is_full_object_read + self.rolling_checksum = ( + google_crc32c.Checksum() + if (is_full_object_read and enable_checksum) + else None + ) class _ReadResumptionStrategy(_BaseResumptionStrategy): @@ -90,6 +101,7 @@ def update_state_from_response( ) download_states = state["download_states"] + checksum_enabled = state.get("enable_checksum", True) for object_data_range in proto.object_data_ranges: # Ignore empty ranges or ranges for IDs not in our state @@ -125,7 +137,7 @@ def update_state_from_response( checksummed_data = object_data_range.checksummed_data data = checksummed_data.content - if checksummed_data.HasField("crc32c"): + if checksum_enabled and checksummed_data.HasField("crc32c"): server_checksum = checksummed_data.crc32c client_checksum = google_crc32c.value(data) if server_checksum != client_checksum: @@ -138,10 +150,14 @@ def update_state_from_response( # Update State & Write Data chunk_size = len(data) read_state.user_buffer.write(data) + + # Commit updates only after the write succeeds + if checksum_enabled and read_state.rolling_checksum is not None: + read_state.rolling_checksum.update(data) read_state.bytes_written += chunk_size read_state.next_expected_offset += chunk_size - # Final Byte Count Verification + # Final Byte Count & Full Object Checksum Verification if object_data_range.range_end: read_state.is_complete = True if ( @@ -154,6 +170,26 @@ def update_state_from_response( f"Expected {read_state.initial_length}, got {read_state.bytes_written}", ) + # Perform full-object checksum verification once the stream finishes. + if ( + read_state.is_full_object_read + and checksum_enabled + and read_state.rolling_checksum is not None + ): + full_obj_server_crc32c = state.get("full_obj_server_crc32c") + if full_obj_server_crc32c is not None: + # Use standard big-endian byte conversion to retrieve the rolling checksum value. + client_checksum = int.from_bytes( + read_state.rolling_checksum.digest(), + byteorder="big", + ) + if client_checksum != full_obj_server_crc32c: + raise DataCorruption( + response, + f"Full object checksum mismatch for read_id {read_id}. " + f"Server authoritative crc32c: {full_obj_server_crc32c}, client calculated rolling: {client_checksum}.", + ) + async def recover_state_on_failure(self, error: Exception, state: Any) -> None: """Handles BidiReadObjectRedirectedError for reads.""" routing_token, read_handle = _handle_redirect(error) diff --git a/packages/google-cloud-storage/tests/unit/asyncio/retry/test_reads_resumption_strategy.py b/packages/google-cloud-storage/tests/unit/asyncio/retry/test_reads_resumption_strategy.py index dc27cb701974..841ea655626e 100644 --- a/packages/google-cloud-storage/tests/unit/asyncio/retry/test_reads_resumption_strategy.py +++ b/packages/google-cloud-storage/tests/unit/asyncio/retry/test_reads_resumption_strategy.py @@ -45,6 +45,48 @@ def test_initialization(self): self.assertEqual(state.bytes_written, 0) self.assertEqual(state.next_expected_offset, initial_offset) self.assertFalse(state.is_complete) + self.assertFalse(state.is_full_object_read) + self.assertIsNone(state.rolling_checksum) + + def test_initialization_with_full_object_read(self): + """Test that _DownloadState initializes correctly when is_full_object_read is True.""" + initial_offset = 10 + initial_length = 100 + user_buffer = io.BytesIO() + state_full = _DownloadState( + initial_offset, initial_length, user_buffer, is_full_object_read=True + ) + + self.assertEqual(state_full.initial_offset, initial_offset) + self.assertEqual(state_full.initial_length, initial_length) + self.assertEqual(state_full.user_buffer, user_buffer) + self.assertEqual(state_full.bytes_written, 0) + self.assertEqual(state_full.next_expected_offset, initial_offset) + self.assertFalse(state_full.is_complete) + self.assertTrue(state_full.is_full_object_read) + self.assertIsNotNone(state_full.rolling_checksum) + + def test_initialization_with_full_object_read_and_checksum_disabled(self): + """Test that _DownloadState does not initialize rolling_checksum when enable_checksum is False.""" + initial_offset = 10 + initial_length = 100 + user_buffer = io.BytesIO() + state_full = _DownloadState( + initial_offset, + initial_length, + user_buffer, + is_full_object_read=True, + enable_checksum=False, + ) + + self.assertEqual(state_full.initial_offset, initial_offset) + self.assertEqual(state_full.initial_length, initial_length) + self.assertEqual(state_full.user_buffer, user_buffer) + self.assertEqual(state_full.bytes_written, 0) + self.assertEqual(state_full.next_expected_offset, initial_offset) + self.assertFalse(state_full.is_complete) + self.assertTrue(state_full.is_full_object_read) + self.assertIsNone(state_full.rolling_checksum) class TestReadResumptionStrategy(unittest.TestCase): @@ -53,12 +95,24 @@ def setUp(self): self.state = {"download_states": {}, "read_handle": None, "routing_token": None} - def _add_download(self, read_id, offset=0, length=100, buffer=None): + def _add_download( + self, + read_id, + offset=0, + length=100, + buffer=None, + is_full_object_read=False, + enable_checksum=True, + ): """Helper to inject a download state into the correct nested location.""" if buffer is None: buffer = io.BytesIO() state = _DownloadState( - initial_offset=offset, initial_length=length, user_buffer=buffer + initial_offset=offset, + initial_length=length, + user_buffer=buffer, + is_full_object_read=is_full_object_read, + enable_checksum=enable_checksum, ) self.state["download_states"][read_id] = state return state @@ -358,3 +412,61 @@ async def run(): # Token should remain unchanged self.assertEqual(self.state["routing_token"], "existing-token") + + def test_update_state_full_object_checksum_success(self): + """Test that full object checksum verification succeeds on range_end.""" + read_state = self._add_download( + _READ_ID, offset=0, length=9, is_full_object_read=True + ) + self.state["enable_checksum"] = True + self.state["full_obj_server_crc32c"] = google_crc32c.value(b"testdata1") + + resp1 = self._create_response(b"test", _READ_ID, offset=0) + self.strategy.update_state_from_response(resp1, self.state) + + resp2 = self._create_response(b"data1", _READ_ID, offset=4, range_end=True) + self.strategy.update_state_from_response(resp2, self.state) + + self.assertTrue(read_state.is_complete) + self.assertEqual(read_state.bytes_written, 9) + + def test_update_state_full_object_checksum_failure(self): + """Test that full object checksum verification raises DataCorruption on mismatch at range_end.""" + self._add_download(_READ_ID, offset=0, length=9, is_full_object_read=True) + self.state["enable_checksum"] = True + self.state["full_obj_server_crc32c"] = 111111 # Wrong server checksum! + + resp1 = self._create_response(b"test", _READ_ID, offset=0) + self.strategy.update_state_from_response(resp1, self.state) + + resp2 = self._create_response(b"data1", _READ_ID, offset=4, range_end=True) + with self.assertRaisesRegex(DataCorruption, "Full object checksum mismatch"): + self.strategy.update_state_from_response(resp2, self.state) + + def test_update_state_checksum_mismatch_ignored_when_disabled(self): + """Test that a CRC32C mismatch is ignored when enable_checksum is False.""" + self._add_download(_READ_ID) + self.state["enable_checksum"] = False + response = self._create_response(b"data", _READ_ID, offset=0, crc=999999) + + # Should NOT raise DataCorruption! + self.strategy.update_state_from_response(response, self.state) + + def test_update_state_full_object_checksum_mismatch_ignored_when_disabled(self): + """Test that a full-object CRC32C mismatch is ignored when enable_checksum is False.""" + self._add_download( + _READ_ID, + offset=0, + length=9, + is_full_object_read=True, + enable_checksum=False, + ) + self.state["enable_checksum"] = False + self.state["full_obj_server_crc32c"] = 111111 # Wrong server checksum! + + resp1 = self._create_response(b"test", _READ_ID, offset=0) + self.strategy.update_state_from_response(resp1, self.state) + + resp2 = self._create_response(b"data1", _READ_ID, offset=4, range_end=True) + # Should NOT raise DataCorruption! + self.strategy.update_state_from_response(resp2, self.state) From b6a85e49ae3873a853812e46ddf759607a01cf25 Mon Sep 17 00:00:00 2001 From: Chandra Shekhar Sirimala Date: Thu, 4 Jun 2026 19:03:28 +0530 Subject: [PATCH 026/174] feat(storage): full object checksum: integrate full-object checksum in AsyncMultiRangeDownloader (#17263) ### 1. Overview of the Solution This solution implements end-to-end full-object checksum validation in `AsyncMultiRangeDownloader` for the asynchronous Google Cloud Storage Python client library. As asynchronous multiplexed downloads of non-contiguous ranges are performed concurrently over a single bidirectional gRPC connection, this feature automatically and incrementally calculates a rolling checksum as bytes arrive and validates it against the server's authoritative object checksum once the download completes. The technical approach consists of three coordinated layers: * **`_AsyncReadObjectStream` (Stream Ingestion)**: Safely extracts the authoritative server checksum (`full_obj_server_crc32c`) and finalization status (`is_finalized`) from the object metadata received in the first data payload response of the stream. * **`_ReadResumptionStrategy` & `_DownloadState` (Verification Logic)**: Computes an isolated, persistent rolling checksum in the individual `_DownloadState` object to ensure calculations do not bleed across concurrent multiplexed ranges. Crucially, the rolling hash updates only *after* buffer writes succeed to prevent state corruption during retry re-connects, raising a `DataCorruption` exception on completion if a mismatch occurs. * **`AsyncMultiRangeDownloader` (Orchestration & Cleanup)**: Detects candidate full-object ranges (e.g., `(0, 0)` or `(0, persisted_size)`), propagates checksum settings to the resumption strategy, and guarantees robust cleanup (closing the stream immediately and unregistering IDs) if data corruption or write errors occur. ### 2. What This PR Specifically Does This PR implements **Step 3: Downloader Orchestration & End-to-End Integration/System Tests** of the solution: * Relocates `raise_if_no_fast_crc32c()` validation to the execution phase (`download_ranges()`) instead of construction time. * Propagates stream details (`is_finalized`, `full_obj_server_crc32c`) to the resumption state dictionary. * Detects implicit full-object downloads (`(0, 0)`) or explicit full-object downloads (`(0, persisted_size)`) post-`open()`, and flags them for validation. * Implements the robust cleanup guarantee in `download_ranges()`: wraps execution in a robust `try...finally` block to close the stream immediately and unregister multiplexer range IDs upon a `DataCorruption` exception. * Adds integration tests in `test_async_multi_range_downloader.py` and extensive end-to-end system tests in `test_zonal.py` checking finalized, unfinalized (appendable), explicit, implicit, and bypassed range downloads against live GCS buckets. --- .../google/cloud/storage/_helpers.py | 4 +- .../google/cloud/storage/_http.py | 2 +- .../asyncio/async_multi_range_downloader.py | 43 +++++- .../tests/system/test_zonal.py | 86 ++++++++++++ .../test_async_multi_range_downloader.py | 132 +++++++++++++++++- .../tests/unit/conftest.py | 1 + 6 files changed, 257 insertions(+), 11 deletions(-) diff --git a/packages/google-cloud-storage/google/cloud/storage/_helpers.py b/packages/google-cloud-storage/google/cloud/storage/_helpers.py index 04039971ef41..c5d2de61796b 100644 --- a/packages/google-cloud-storage/google/cloud/storage/_helpers.py +++ b/packages/google-cloud-storage/google/cloud/storage/_helpers.py @@ -33,9 +33,11 @@ from google.cloud.exceptions import NotFound from google.cloud.storage._opentelemetry_tracing import ( - create_trace_span as _base_create_trace_span, _is_bucket_metadata_disabled, ) +from google.cloud.storage._opentelemetry_tracing import ( + create_trace_span as _base_create_trace_span, +) from google.cloud.storage.constants import _DEFAULT_TIMEOUT from google.cloud.storage.retry import ( DEFAULT_RETRY, diff --git a/packages/google-cloud-storage/google/cloud/storage/_http.py b/packages/google-cloud-storage/google/cloud/storage/_http.py index bfe2bf3843af..72734f511b41 100644 --- a/packages/google-cloud-storage/google/cloud/storage/_http.py +++ b/packages/google-cloud-storage/google/cloud/storage/_http.py @@ -25,9 +25,9 @@ from google.cloud.storage import __version__, _helpers from google.cloud.storage._opentelemetry_tracing import ( HAS_OPENTELEMETRY, + _is_bucket_metadata_disabled, create_trace_span, enable_otel_traces, - _is_bucket_metadata_disabled, ) logger = logging.getLogger(__name__) diff --git a/packages/google-cloud-storage/google/cloud/storage/asyncio/async_multi_range_downloader.py b/packages/google-cloud-storage/google/cloud/storage/asyncio/async_multi_range_downloader.py index ac0844519e2d..6d3f5e2fab4b 100644 --- a/packages/google-cloud-storage/google/cloud/storage/asyncio/async_multi_range_downloader.py +++ b/packages/google-cloud-storage/google/cloud/storage/asyncio/async_multi_range_downloader.py @@ -44,6 +44,7 @@ _DownloadState, _ReadResumptionStrategy, ) +from google.cloud.storage.exceptions import DataCorruption from ._utils import raise_if_no_fast_crc32c @@ -219,8 +220,6 @@ def __init__( ) generation = kwargs.pop("generation_number") - raise_if_no_fast_crc32c() - self.client = client self.bucket_name = bucket_name self.object_name = object_name @@ -232,6 +231,8 @@ def __init__( self._multiplexer: Optional[_StreamMultiplexer] = None self.persisted_size: Optional[int] = None # updated after opening the stream self._open_retries: int = 0 + self.is_finalized: bool = False + self.full_obj_server_crc32c: Optional[int] = None async def __aenter__(self): """Opens the underlying bidi-gRPC connection to read from the object.""" @@ -327,6 +328,8 @@ async def _do_open(): self.read_handle = self.read_obj_str.read_handle if self.read_obj_str.persisted_size is not None: self.persisted_size = self.read_obj_str.persisted_size + self.is_finalized = self.read_obj_str.is_finalized + self.full_obj_server_crc32c = self.read_obj_str.full_obj_server_crc32c self._is_stream_open = True @@ -363,6 +366,8 @@ async def factory(): self.generation = stream.generation_number if stream.read_handle: self.read_handle = stream.read_handle + self.is_finalized = stream.is_finalized + self.full_obj_server_crc32c = stream.full_obj_server_crc32c self.read_obj_str = stream self._is_stream_open = True @@ -377,6 +382,7 @@ async def download_ranges( lock: asyncio.Lock = None, retry_policy: Optional[AsyncRetry] = None, metadata: Optional[List[Tuple[str, str]]] = None, + enable_checksum: bool = True, ) -> None: """Downloads multiple byte ranges from the object into the buffers provided by user with automatic retries. @@ -412,6 +418,9 @@ async def download_ranges( "Invalid input - length of read_ranges cannot be more than 1000" ) + if enable_checksum: + raise_if_no_fast_crc32c() + if not self._is_stream_open: raise ValueError("Underlying bidi-gRPC stream is not open") @@ -422,16 +431,30 @@ async def download_ranges( download_states = {} for read_range in read_ranges: read_id = generate_random_56_bit_integer() + # Unpack tuple into self-documenting variable names to improve readability. + offset, length, user_buffer = read_range + + # Heuristic to detect full object reads: + # - Implicit full object read: start offset is 0 and length is 0 (read all). + # - Explicit full object read: start offset is 0 and length matches the exact persisted size. + is_full_object_read = (offset == 0 and length == 0) or ( + self.persisted_size is not None + and offset == 0 + and length == self.persisted_size + ) download_states[read_id] = _DownloadState( - initial_offset=read_range[0], - initial_length=read_range[1], - user_buffer=read_range[2], + initial_offset=offset, + initial_length=length, + user_buffer=user_buffer, + is_full_object_read=is_full_object_read, ) initial_state = { "download_states": download_states, "read_handle": self.read_handle, "routing_token": None, + "enable_checksum": enable_checksum, + "full_obj_server_crc32c": self.full_obj_server_crc32c, } read_ids = set(download_states.keys()) @@ -519,12 +542,18 @@ async def generator(): strategy, send_and_recv_via_multiplexer ) - await retry_manager.execute(initial_state, retry_policy) + try: + await retry_manager.execute(initial_state, retry_policy) + except DataCorruption: + if self.is_stream_open: + await self.close() + raise if initial_state.get("read_handle"): self.read_handle = initial_state["read_handle"] finally: - self._multiplexer.unregister(read_ids) + if self._multiplexer is not None: + self._multiplexer.unregister(read_ids) async def close(self): """ diff --git a/packages/google-cloud-storage/tests/system/test_zonal.py b/packages/google-cloud-storage/tests/system/test_zonal.py index 20e172a1adee..2d79ec8a817c 100644 --- a/packages/google-cloud-storage/tests/system/test_zonal.py +++ b/packages/google-cloud-storage/tests/system/test_zonal.py @@ -27,6 +27,7 @@ ObjectCustomContextPayload, ) + pytestmark = pytest.mark.skipif( os.getenv("RUN_ZONAL_SYSTEM_TESTS") != "True", reason="Zonal system tests need to be explicitly enabled. This helps scheduling tests in Kokoro and Cloud Build.", @@ -961,3 +962,88 @@ async def _run(): blobs_to_delete.append(storage_client.bucket(_ZONAL_BUCKET).blob(object_name)) event_loop.run_until_complete(_run()) + + +@pytest.mark.parametrize( + "read_start, read_length, enable_checksum", + [ + (0, 0, True), + (0, 1024 * 1024, True), + (0, 0, False), + ], +) +def test_mrd_checksum_validation( + storage_client, + blobs_to_delete, + event_loop, + grpc_client_direct, + read_start, + read_length, + enable_checksum, +): + """ + Tests full downloads with specified offset, length, and enable_checksum toggle on finalized objects. + """ + object_size = 1024 * 1024 # 1MB + object_name = f"test_mrd_chksum-{uuid.uuid4()}" + + async def _run(): + object_data = os.urandom(object_size) + + writer = AsyncAppendableObjectWriter( + grpc_client_direct, _ZONAL_BUCKET, object_name + ) + await writer.open() + await writer.append(object_data) + await writer.close(finalize_on_close=True) + + async with AsyncMultiRangeDownloader( + grpc_client_direct, _ZONAL_BUCKET, object_name + ) as mrd: + buffer = BytesIO() + await mrd.download_ranges( + [(read_start, read_length, buffer)], enable_checksum=enable_checksum + ) + assert buffer.getvalue() == object_data + + # cleanup + del writer + gc.collect() + blobs_to_delete.append(storage_client.bucket(_ZONAL_BUCKET).blob(object_name)) + + event_loop.run_until_complete(_run()) + + +def test_mrd_checksum_unfinalized_appendable_skipped( + storage_client, blobs_to_delete, event_loop, grpc_client_direct +): + """ + Verifies that live, unfinalized appendable objects skip the full-object checksum check + naturally without raising any exceptions. + """ + object_name = f"test_mrd_chksum_unfin-{uuid.uuid4()}" + + async def _run(): + writer = AsyncAppendableObjectWriter( + grpc_client_direct, _ZONAL_BUCKET, object_name + ) + await writer.open() + await writer.append(_BYTES_TO_UPLOAD) + await writer.flush() # Flushed but not finalized! + + # Download the unfinalized appendable object with enable_checksum=True + async with AsyncMultiRangeDownloader( + grpc_client_direct, _ZONAL_BUCKET, object_name + ) as mrd: + buffer = BytesIO() + # Since it's unfinalized, it should skip the checksum check without raising + await mrd.download_ranges([(0, 0, buffer)], enable_checksum=True) + assert buffer.getvalue() == _BYTES_TO_UPLOAD + + # cleanup + await writer.close() + del writer + gc.collect() + blobs_to_delete.append(storage_client.bucket(_ZONAL_BUCKET).blob(object_name)) + + event_loop.run_until_complete(_run()) diff --git a/packages/google-cloud-storage/tests/unit/asyncio/test_async_multi_range_downloader.py b/packages/google-cloud-storage/tests/unit/asyncio/test_async_multi_range_downloader.py index 24a632b68131..6ead8d8964e9 100644 --- a/packages/google-cloud-storage/tests/unit/asyncio/test_async_multi_range_downloader.py +++ b/packages/google-cloud-storage/tests/unit/asyncio/test_async_multi_range_downloader.py @@ -308,12 +308,16 @@ async def test_downloading_without_opening_should_throw_error(self): assert not mrd.is_stream_open @mock.patch("google.cloud.storage.asyncio._utils.google_crc32c") - def test_init_raises_if_crc32c_c_extension_is_missing(self, mock_google_crc32c): + @pytest.mark.asyncio + async def test_download_ranges_raises_if_crc32c_c_extension_is_missing( + self, mock_google_crc32c + ): mock_google_crc32c.implementation = "python" mock_client = mock.MagicMock() + mrd = AsyncMultiRangeDownloader(mock_client, "bucket", "object") with pytest.raises(exceptions.FailedPrecondition) as exc_info: - AsyncMultiRangeDownloader(mock_client, "bucket", "object") + await mrd.download_ranges([(0, 10, BytesIO())]) assert "The google-crc32c package is not installed with C support" in str( exc_info.value @@ -579,3 +583,127 @@ async def staged_recv(): # Assert mock_logger.info.assert_any_call("Resuming download (attempt 2) for 1 ranges.") + + @mock.patch( + "google.cloud.storage.asyncio.async_multi_range_downloader._AsyncReadObjectStream" + ) + @pytest.mark.asyncio + async def test_open_populates_checksum_properties( + self, mock_cls_async_read_object_stream + ): + # Arrange + mock_client = mock.MagicMock() + mock_client.grpc_client = mock.AsyncMock() + mock_stream = mock_cls_async_read_object_stream.return_value + mock_stream.open = AsyncMock() + mock_stream.generation_number = 123 + mock_stream.persisted_size = 100 + mock_stream.read_handle = b"h" + mock_stream.is_finalized = True + mock_stream.full_obj_server_crc32c = 999 + + mrd = AsyncMultiRangeDownloader(mock_client, "bucket", "object") + assert mrd.is_finalized is False + assert mrd.full_obj_server_crc32c is None + + # Act + await mrd.open() + + # Assert + assert mrd.is_finalized is True + assert mrd.full_obj_server_crc32c == 999 + + @mock.patch( + "google.cloud.storage.asyncio.async_multi_range_downloader._ReadResumptionStrategy" + ) + @mock.patch( + "google.cloud.storage.asyncio.async_multi_range_downloader._BidiStreamRetryManager" + ) + @mock.patch( + "google.cloud.storage.asyncio.async_multi_range_downloader._AsyncReadObjectStream" + ) + @pytest.mark.asyncio + async def test_download_ranges_configures_full_object_read_state( + self, + mock_cls_async_read_object_stream, + mock_retry_manager_cls, + mock_strategy_cls, + ): + # Arrange + mock_client = mock.MagicMock() + mock_client.grpc_client = mock.AsyncMock() + mock_stream = mock_cls_async_read_object_stream.return_value + mock_stream.open = AsyncMock() + mock_stream.persisted_size = 100 + mock_stream.is_finalized = True + mock_stream.full_obj_server_crc32c = 999 + + mrd = await AsyncMultiRangeDownloader.create_mrd(mock_client, "b", "o") + + mock_retry_manager = mock_retry_manager_cls.return_value + mock_retry_manager.execute = AsyncMock() + + # Act + # Implicit full read (0, 0) and explicit full read (0, persisted_size=100) + ranges = [(0, 0, BytesIO()), (0, 100, BytesIO()), (10, 20, BytesIO())] + await mrd.download_ranges(ranges, enable_checksum=True) + + # Assert + mock_retry_manager.execute.assert_called_once() + initial_state = mock_retry_manager.execute.call_args[0][0] + + download_states = initial_state["download_states"] + assert len(download_states) == 3 + + states_list = list(download_states.values()) + # First state: (0, 0) -> is_full_object_read is True + assert states_list[0].is_full_object_read is True + assert states_list[0].rolling_checksum is not None + + # Second state: (0, 100) -> is_full_object_read is True + assert states_list[1].is_full_object_read is True + assert states_list[1].rolling_checksum is not None + + # Third state: (10, 20) -> is_full_object_read is False + assert states_list[2].is_full_object_read is False + assert states_list[2].rolling_checksum is None + + # State values for enable_checksum and crc32c + assert initial_state["enable_checksum"] is True + assert initial_state["full_obj_server_crc32c"] == 999 + + @mock.patch( + "google.cloud.storage.asyncio.async_multi_range_downloader._ReadResumptionStrategy" + ) + @mock.patch( + "google.cloud.storage.asyncio.async_multi_range_downloader._BidiStreamRetryManager" + ) + @mock.patch( + "google.cloud.storage.asyncio.async_multi_range_downloader._AsyncReadObjectStream" + ) + @pytest.mark.asyncio + async def test_download_ranges_closes_on_datacorruption( + self, + mock_cls_async_read_object_stream, + mock_retry_manager_cls, + mock_strategy_cls, + ): + # Arrange + mock_client = mock.MagicMock() + mock_client.grpc_client = mock.AsyncMock() + mock_stream = mock_cls_async_read_object_stream.return_value + mock_stream.open = AsyncMock() + + mrd = await AsyncMultiRangeDownloader.create_mrd(mock_client, "b", "o") + mrd.close = AsyncMock() + + mock_retry_manager = mock_retry_manager_cls.return_value + mock_retry_manager.execute = AsyncMock( + side_effect=DataCorruption(None, "corrupted") + ) + + # Act & Assert + with pytest.raises(DataCorruption): + await mrd.download_ranges([(0, 0, BytesIO())]) + + mrd.close.assert_called_once() diff --git a/packages/google-cloud-storage/tests/unit/conftest.py b/packages/google-cloud-storage/tests/unit/conftest.py index 2eeabdc990e6..ef3d3a1afc21 100644 --- a/packages/google-cloud-storage/tests/unit/conftest.py +++ b/packages/google-cloud-storage/tests/unit/conftest.py @@ -14,6 +14,7 @@ # limitations under the License. import asyncio + import pytest From 65f059e22ea1d710e06230cf5f6ee9eb5fe45e8e Mon Sep 17 00:00:00 2001 From: Tomo Suzuki Date: Thu, 4 Jun 2026 11:21:18 -0400 Subject: [PATCH 027/174] feat(google-backstory): new library google-backstory (#17374) I manually edit librarian.yaml and librarian.state file and ran `$ docker run -u $(id -u):$(id -g) -v .:/repo -v ~/.cache:/.cache -w /repo docker.io/library/librarian-python:${V} generate -v google-backstory`. I referenced the google-cloud-common declaration in librarian.yaml. At first, I hit `2026/06/04 14:33:45 librarian: generate library "google-backstory" (python): error creating metadata for google-backstory: default version must be specified for every library with generated APIs` error but this was resolved by declaring `default_version: apiVersion`. ### Unit Test Failure and Fix The CI check failed because `google-backstory` is a type-only library and had no unit tests, causing `pytest` to exit with code 5 (no tests collected). To fix this, I added: - `test_packaging.py` to verify namespace package compatibility. - `test_backstory.py` to verify that backstory types can be imported. This follows the pattern of `google-cloud-common` which also has a dummy test to avoid empty test suite failures. I also updated `librarian.yaml` (`keep`) and `.librarian/state.yaml` (`preserve_regex`) to preserve these tests during regeneration. --- .librarian/state.yaml | 18 + librarian.yaml | 14 + packages/google-backstory/.coveragerc | 13 + packages/google-backstory/.flake8 | 34 + packages/google-backstory/.repo-metadata.json | 16 + packages/google-backstory/CHANGELOG.md | 5 + packages/google-backstory/LICENSE | 202 + packages/google-backstory/MANIFEST.in | 20 + packages/google-backstory/README.rst | 198 + packages/google-backstory/docs/CHANGELOG.md | 1 + packages/google-backstory/docs/README.rst | 198 + .../google-backstory/docs/_static/custom.css | 20 + .../docs/_templates/layout.html | 50 + .../docs/backstory/services_.rst | 4 + .../docs/backstory/types_.rst | 6 + packages/google-backstory/docs/conf.py | 417 + packages/google-backstory/docs/index.rst | 10 + .../google-backstory/docs/multiprocessing.rst | 7 + .../google/backstory/__init__.py | 339 + .../google/backstory/gapic_metadata.json | 7 + .../google/backstory/gapic_version.py | 16 + .../google/backstory/py.typed | 2 + .../google/backstory/services/__init__.py | 15 + .../google/backstory/types/__init__.py | 260 + .../google/backstory/types/collection.py | 665 + .../google/backstory/types/data_access.py | 99 + .../google/backstory/types/entity.py | 976 ++ .../google/backstory/types/entity_risk.py | 197 + .../google/backstory/types/id.py | 100 + .../google/backstory/types/udm.py | 11335 ++++++++++++++++ packages/google-backstory/mypy.ini | 15 + packages/google-backstory/noxfile.py | 639 + packages/google-backstory/setup.py | 97 + .../testing/constraints-3.10.txt | 11 + .../testing/constraints-3.11.txt | 10 + .../testing/constraints-3.12.txt | 10 + .../testing/constraints-3.13.txt | 12 + .../testing/constraints-3.14.txt | 12 + packages/google-backstory/tests/__init__.py | 15 + .../google-backstory/tests/unit/__init__.py | 15 + .../tests/unit/gapic/__init__.py | 15 + .../tests/unit/gapic/backstory/__init__.py | 15 + .../tests/unit/test_backstory.py | 19 + .../tests/unit/test_packaging.py | 28 + 44 files changed, 16157 insertions(+) create mode 100644 packages/google-backstory/.coveragerc create mode 100644 packages/google-backstory/.flake8 create mode 100644 packages/google-backstory/.repo-metadata.json create mode 100644 packages/google-backstory/CHANGELOG.md create mode 100644 packages/google-backstory/LICENSE create mode 100644 packages/google-backstory/MANIFEST.in create mode 100644 packages/google-backstory/README.rst create mode 120000 packages/google-backstory/docs/CHANGELOG.md create mode 100644 packages/google-backstory/docs/README.rst create mode 100644 packages/google-backstory/docs/_static/custom.css create mode 100644 packages/google-backstory/docs/_templates/layout.html create mode 100644 packages/google-backstory/docs/backstory/services_.rst create mode 100644 packages/google-backstory/docs/backstory/types_.rst create mode 100644 packages/google-backstory/docs/conf.py create mode 100644 packages/google-backstory/docs/index.rst create mode 100644 packages/google-backstory/docs/multiprocessing.rst create mode 100644 packages/google-backstory/google/backstory/__init__.py create mode 100644 packages/google-backstory/google/backstory/gapic_metadata.json create mode 100644 packages/google-backstory/google/backstory/gapic_version.py create mode 100644 packages/google-backstory/google/backstory/py.typed create mode 100644 packages/google-backstory/google/backstory/services/__init__.py create mode 100644 packages/google-backstory/google/backstory/types/__init__.py create mode 100644 packages/google-backstory/google/backstory/types/collection.py create mode 100644 packages/google-backstory/google/backstory/types/data_access.py create mode 100644 packages/google-backstory/google/backstory/types/entity.py create mode 100644 packages/google-backstory/google/backstory/types/entity_risk.py create mode 100644 packages/google-backstory/google/backstory/types/id.py create mode 100644 packages/google-backstory/google/backstory/types/udm.py create mode 100644 packages/google-backstory/mypy.ini create mode 100644 packages/google-backstory/noxfile.py create mode 100644 packages/google-backstory/setup.py create mode 100644 packages/google-backstory/testing/constraints-3.10.txt create mode 100644 packages/google-backstory/testing/constraints-3.11.txt create mode 100644 packages/google-backstory/testing/constraints-3.12.txt create mode 100644 packages/google-backstory/testing/constraints-3.13.txt create mode 100644 packages/google-backstory/testing/constraints-3.14.txt create mode 100644 packages/google-backstory/tests/__init__.py create mode 100644 packages/google-backstory/tests/unit/__init__.py create mode 100644 packages/google-backstory/tests/unit/gapic/__init__.py create mode 100644 packages/google-backstory/tests/unit/gapic/backstory/__init__.py create mode 100644 packages/google-backstory/tests/unit/test_backstory.py create mode 100644 packages/google-backstory/tests/unit/test_packaging.py diff --git a/.librarian/state.yaml b/.librarian/state.yaml index 3f9c5d638041..cd38250abfb4 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -431,6 +431,24 @@ libraries: - packages/google-auth-oauthlib/README.rst - packages/google-auth-oauthlib/docs/ tag_format: '{id}-v{version}' + - id: google-backstory + version: 0.0.0 + last_generated_commit: "" + apis: + - path: backstory + source_roots: + - packages/google-backstory + preserve_regex: + - tests/unit/test_backstory.py + - tests/unit/test_packaging.py + remove_regex: [] + release_exclude_paths: + - packages/google-backstory/.repo-metadata.json + - packages/google-backstory/noxfile.py + - packages/google-backstory/tests/ + - packages/google-backstory/README.rst + - packages/google-backstory/docs/ + tag_format: '{id}-v{version}' - id: google-cloud-access-approval version: 1.20.0 last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd diff --git a/librarian.yaml b/librarian.yaml index ceb33c5f2b6e..c1a78b3f5094 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -238,6 +238,20 @@ libraries: version: 1.4.0 python: library_type: AUTH + - name: google-backstory + version: 0.0.0 + apis: + - path: backstory + keep: + - tests/unit/test_backstory.py + - tests/unit/test_packaging.py + python: + library_type: CORE + opt_args_by_api: + backstory: + - python-gapic-namespace=google + - python-gapic-name=backstory + default_version: apiVersion - name: google-cloud-access-approval version: 1.20.0 apis: diff --git a/packages/google-backstory/.coveragerc b/packages/google-backstory/.coveragerc new file mode 100644 index 000000000000..533a3b989412 --- /dev/null +++ b/packages/google-backstory/.coveragerc @@ -0,0 +1,13 @@ +[run] +branch = True + +[report] +show_missing = True +omit = + google/backstory/__init__.py + google/backstory/gapic_version.py +exclude_lines = + # Re-enable the standard pragma + pragma: NO COVER + # Ignore debug-only repr + def __repr__ diff --git a/packages/google-backstory/.flake8 b/packages/google-backstory/.flake8 new file mode 100644 index 000000000000..f9069a84687b --- /dev/null +++ b/packages/google-backstory/.flake8 @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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. +# +[flake8] +# TODO(https://github.com/googleapis/gapic-generator-python/issues/2333): +# Resolve flake8 lint issues +ignore = E203, E231, E266, E501, W503 +exclude = + # TODO(https://github.com/googleapis/gapic-generator-python/issues/2333): + # Ensure that generated code passes flake8 lint + **/gapic/** + **/services/** + **/types/** + # Exclude Protobuf gencode + *_pb2.py + + # Standard linting exemptions. + **/.nox/** + __pycache__, + .git, + *.pyc, + conf.py diff --git a/packages/google-backstory/.repo-metadata.json b/packages/google-backstory/.repo-metadata.json new file mode 100644 index 000000000000..b05902a82089 --- /dev/null +++ b/packages/google-backstory/.repo-metadata.json @@ -0,0 +1,16 @@ +{ + "api_description": "Common Universal Data Model (UDM) and Entity protos used by Chronicle.", + "api_id": "backstory.googleapis.com", + "api_shortname": "backstory", + "client_documentation": "https://googleapis.dev/python/google-backstory/latest", + "default_version": "apiVersion", + "distribution_name": "google-backstory", + "issue_tracker": "https://issuetracker.google.com/issues/new?component=1387895", + "language": "python", + "library_type": "CORE", + "name": "google-backstory", + "name_pretty": "Malachite Common Protos", + "product_documentation": "https://cloud.google.com/chronicle/", + "release_level": "preview", + "repo": "googleapis/google-cloud-python" +} \ No newline at end of file diff --git a/packages/google-backstory/CHANGELOG.md b/packages/google-backstory/CHANGELOG.md new file mode 100644 index 000000000000..44f8b4f93b7b --- /dev/null +++ b/packages/google-backstory/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +[PyPI History][1] + +[1]: https://pypi.org/project/google-backstory/#history diff --git a/packages/google-backstory/LICENSE b/packages/google-backstory/LICENSE new file mode 100644 index 000000000000..d64569567334 --- /dev/null +++ b/packages/google-backstory/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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/packages/google-backstory/MANIFEST.in b/packages/google-backstory/MANIFEST.in new file mode 100644 index 000000000000..f932577add9d --- /dev/null +++ b/packages/google-backstory/MANIFEST.in @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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. +# +include README.rst LICENSE +recursive-include google *.py *.pyi *.json *.proto py.typed +recursive-include tests * +global-exclude *.py[co] +global-exclude __pycache__ diff --git a/packages/google-backstory/README.rst b/packages/google-backstory/README.rst new file mode 100644 index 000000000000..7cc595d29b3d --- /dev/null +++ b/packages/google-backstory/README.rst @@ -0,0 +1,198 @@ +Python Client for Malachite Common Protos +========================================= + +|preview| |pypi| |versions| + +`Malachite Common Protos`_: Common Universal Data Model (UDM) and Entity protos used by Chronicle. + +- `Client Library Documentation`_ +- `Product Documentation`_ + +.. |preview| image:: https://img.shields.io/badge/support-preview-orange.svg + :target: https://github.com/googleapis/google-cloud-python/blob/main/README.rst#stability-levels +.. |pypi| image:: https://img.shields.io/pypi/v/google-backstory.svg + :target: https://pypi.org/project/google-backstory/ +.. |versions| image:: https://img.shields.io/pypi/pyversions/google-backstory.svg + :target: https://pypi.org/project/google-backstory/ +.. _Malachite Common Protos: https://cloud.google.com/chronicle/ +.. _Client Library Documentation: https://googleapis.dev/python/google-backstory/latest +.. _Product Documentation: https://cloud.google.com/chronicle/ + +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 Malachite Common Protos.`_ +4. `Set up 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 +.. _Enable the Malachite Common Protos.: https://cloud.google.com/chronicle/ +.. _Set up Authentication.: https://googleapis.dev/python/google-api-core/latest/auth.html + +Installation +~~~~~~~~~~~~ + +Install this library in a virtual environment using `venv`_. `venv`_ is a tool that +creates isolated Python environments. These isolated environments can have separate +versions of Python packages, which allows you to isolate one project's dependencies +from the dependencies of other projects. + +With `venv`_, it's possible to install this library without needing system +install permissions, and without clashing with the installed system +dependencies. + +.. _`venv`: https://docs.python.org/3/library/venv.html + + +Code samples and snippets +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Code samples and snippets live in the `samples/`_ folder. + +.. _samples/: https://github.com/googleapis/google-cloud-python/tree/main/packages/google-backstory/samples + + +Supported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^ +Our client libraries are compatible with all current `active`_ and `maintenance`_ versions of +Python. + +Python >= 3.10, including 3.14 + +.. _active: https://devguide.python.org/devcycle/#in-development-main-branch +.. _maintenance: https://devguide.python.org/devcycle/#maintenance-branches + +Unsupported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Python <= 3.9 + + +If you are using an `end-of-life`_ +version of Python, we recommend that you update as soon as possible to an actively supported version. + +.. _end-of-life: https://devguide.python.org/devcycle/#end-of-life-branches + +Mac/Linux +^^^^^^^^^ + +.. code-block:: console + + python3 -m venv + source /bin/activate + pip install google-backstory + + +Windows +^^^^^^^ + +.. code-block:: console + + py -m venv + .\\Scripts\activate + pip install google-backstory + +Next Steps +~~~~~~~~~~ + +- Read the `Client Library Documentation`_ for Malachite Common Protos + to see other available methods on the client. +- Read the `Malachite Common Protos Product documentation`_ to learn + more about the product and see How-to Guides. +- View this `README`_ to see the full list of Cloud + APIs that we cover. + +.. _Malachite Common Protos Product documentation: https://cloud.google.com/chronicle/ +.. _README: https://github.com/googleapis/google-cloud-python/blob/main/README.rst + +Logging +------- + +This library uses the standard Python :code:`logging` functionality to log some RPC events that could be of interest for debugging and monitoring purposes. +Note the following: + +#. Logs may contain sensitive information. Take care to **restrict access to the logs** if they are saved, whether it be on local storage or on Google Cloud Logging. +#. Google may refine the occurrence, level, and content of various log messages in this library without flagging such changes as breaking. **Do not depend on immutability of the logging events**. +#. By default, the logging events from this library are not handled. You must **explicitly configure log handling** using one of the mechanisms below. + +Simple, environment-based configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To enable logging for this library without any changes in your code, set the :code:`GOOGLE_SDK_PYTHON_LOGGING_SCOPE` environment variable to a valid Google +logging scope. This configures handling of logging events (at level :code:`logging.DEBUG` or higher) from this library in a default manner, emitting the logged +messages in a structured format. It does not currently allow customizing the logging levels captured nor the handlers, formatters, etc. used for any logging +event. + +A logging scope is a period-separated namespace that begins with :code:`google`, identifying the Python module or package to log. + +- Valid logging scopes: :code:`google`, :code:`google.cloud.asset.v1`, :code:`google.api`, :code:`google.auth`, etc. +- Invalid logging scopes: :code:`foo`, :code:`123`, etc. + +**NOTE**: If the logging scope is invalid, the library does not set up any logging handlers. + +Environment-Based Examples +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Enabling the default handler for all Google-based loggers + +.. code-block:: console + + export GOOGLE_SDK_PYTHON_LOGGING_SCOPE=google + +- Enabling the default handler for a specific Google module (for a client library called :code:`library_v1`): + +.. code-block:: console + + export GOOGLE_SDK_PYTHON_LOGGING_SCOPE=google.cloud.library_v1 + + +Advanced, code-based configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can also configure a valid logging scope using Python's standard `logging` mechanism. + +Code-Based Examples +^^^^^^^^^^^^^^^^^^^ + +- Configuring a handler for all Google-based loggers + +.. code-block:: python + + import logging + + from google.cloud import library_v1 + + base_logger = logging.getLogger("google") + base_logger.addHandler(logging.StreamHandler()) + base_logger.setLevel(logging.DEBUG) + +- Configuring a handler for a specific Google module (for a client library called :code:`library_v1`): + +.. code-block:: python + + import logging + + from google.cloud import library_v1 + + base_logger = logging.getLogger("google.cloud.library_v1") + base_logger.addHandler(logging.StreamHandler()) + base_logger.setLevel(logging.DEBUG) + +Logging details +~~~~~~~~~~~~~~~ + +#. Regardless of which of the mechanisms above you use to configure logging for this library, by default logging events are not propagated up to the root + logger from the `google`-level logger. If you need the events to be propagated to the root logger, you must explicitly set + :code:`logging.getLogger("google").propagate = True` in your code. +#. You can mix the different logging configurations above for different Google modules. For example, you may want use a code-based logging configuration for + one library, but decide you need to also set up environment-based logging configuration for another library. + + #. If you attempt to use both code-based and environment-based configuration for the same module, the environment-based configuration will be ineffectual + if the code -based configuration gets applied first. + +#. The Google-specific logging configurations (default handlers for environment-based configuration; not propagating logging events to the root logger) get + executed the first time *any* client library is instantiated in your application, and only if the affected loggers have not been previously configured. + (This is the reason for 2.i. above.) diff --git a/packages/google-backstory/docs/CHANGELOG.md b/packages/google-backstory/docs/CHANGELOG.md new file mode 120000 index 000000000000..04c99a55caae --- /dev/null +++ b/packages/google-backstory/docs/CHANGELOG.md @@ -0,0 +1 @@ +../CHANGELOG.md \ No newline at end of file diff --git a/packages/google-backstory/docs/README.rst b/packages/google-backstory/docs/README.rst new file mode 100644 index 000000000000..7cc595d29b3d --- /dev/null +++ b/packages/google-backstory/docs/README.rst @@ -0,0 +1,198 @@ +Python Client for Malachite Common Protos +========================================= + +|preview| |pypi| |versions| + +`Malachite Common Protos`_: Common Universal Data Model (UDM) and Entity protos used by Chronicle. + +- `Client Library Documentation`_ +- `Product Documentation`_ + +.. |preview| image:: https://img.shields.io/badge/support-preview-orange.svg + :target: https://github.com/googleapis/google-cloud-python/blob/main/README.rst#stability-levels +.. |pypi| image:: https://img.shields.io/pypi/v/google-backstory.svg + :target: https://pypi.org/project/google-backstory/ +.. |versions| image:: https://img.shields.io/pypi/pyversions/google-backstory.svg + :target: https://pypi.org/project/google-backstory/ +.. _Malachite Common Protos: https://cloud.google.com/chronicle/ +.. _Client Library Documentation: https://googleapis.dev/python/google-backstory/latest +.. _Product Documentation: https://cloud.google.com/chronicle/ + +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 Malachite Common Protos.`_ +4. `Set up 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 +.. _Enable the Malachite Common Protos.: https://cloud.google.com/chronicle/ +.. _Set up Authentication.: https://googleapis.dev/python/google-api-core/latest/auth.html + +Installation +~~~~~~~~~~~~ + +Install this library in a virtual environment using `venv`_. `venv`_ is a tool that +creates isolated Python environments. These isolated environments can have separate +versions of Python packages, which allows you to isolate one project's dependencies +from the dependencies of other projects. + +With `venv`_, it's possible to install this library without needing system +install permissions, and without clashing with the installed system +dependencies. + +.. _`venv`: https://docs.python.org/3/library/venv.html + + +Code samples and snippets +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Code samples and snippets live in the `samples/`_ folder. + +.. _samples/: https://github.com/googleapis/google-cloud-python/tree/main/packages/google-backstory/samples + + +Supported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^ +Our client libraries are compatible with all current `active`_ and `maintenance`_ versions of +Python. + +Python >= 3.10, including 3.14 + +.. _active: https://devguide.python.org/devcycle/#in-development-main-branch +.. _maintenance: https://devguide.python.org/devcycle/#maintenance-branches + +Unsupported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Python <= 3.9 + + +If you are using an `end-of-life`_ +version of Python, we recommend that you update as soon as possible to an actively supported version. + +.. _end-of-life: https://devguide.python.org/devcycle/#end-of-life-branches + +Mac/Linux +^^^^^^^^^ + +.. code-block:: console + + python3 -m venv + source /bin/activate + pip install google-backstory + + +Windows +^^^^^^^ + +.. code-block:: console + + py -m venv + .\\Scripts\activate + pip install google-backstory + +Next Steps +~~~~~~~~~~ + +- Read the `Client Library Documentation`_ for Malachite Common Protos + to see other available methods on the client. +- Read the `Malachite Common Protos Product documentation`_ to learn + more about the product and see How-to Guides. +- View this `README`_ to see the full list of Cloud + APIs that we cover. + +.. _Malachite Common Protos Product documentation: https://cloud.google.com/chronicle/ +.. _README: https://github.com/googleapis/google-cloud-python/blob/main/README.rst + +Logging +------- + +This library uses the standard Python :code:`logging` functionality to log some RPC events that could be of interest for debugging and monitoring purposes. +Note the following: + +#. Logs may contain sensitive information. Take care to **restrict access to the logs** if they are saved, whether it be on local storage or on Google Cloud Logging. +#. Google may refine the occurrence, level, and content of various log messages in this library without flagging such changes as breaking. **Do not depend on immutability of the logging events**. +#. By default, the logging events from this library are not handled. You must **explicitly configure log handling** using one of the mechanisms below. + +Simple, environment-based configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To enable logging for this library without any changes in your code, set the :code:`GOOGLE_SDK_PYTHON_LOGGING_SCOPE` environment variable to a valid Google +logging scope. This configures handling of logging events (at level :code:`logging.DEBUG` or higher) from this library in a default manner, emitting the logged +messages in a structured format. It does not currently allow customizing the logging levels captured nor the handlers, formatters, etc. used for any logging +event. + +A logging scope is a period-separated namespace that begins with :code:`google`, identifying the Python module or package to log. + +- Valid logging scopes: :code:`google`, :code:`google.cloud.asset.v1`, :code:`google.api`, :code:`google.auth`, etc. +- Invalid logging scopes: :code:`foo`, :code:`123`, etc. + +**NOTE**: If the logging scope is invalid, the library does not set up any logging handlers. + +Environment-Based Examples +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Enabling the default handler for all Google-based loggers + +.. code-block:: console + + export GOOGLE_SDK_PYTHON_LOGGING_SCOPE=google + +- Enabling the default handler for a specific Google module (for a client library called :code:`library_v1`): + +.. code-block:: console + + export GOOGLE_SDK_PYTHON_LOGGING_SCOPE=google.cloud.library_v1 + + +Advanced, code-based configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can also configure a valid logging scope using Python's standard `logging` mechanism. + +Code-Based Examples +^^^^^^^^^^^^^^^^^^^ + +- Configuring a handler for all Google-based loggers + +.. code-block:: python + + import logging + + from google.cloud import library_v1 + + base_logger = logging.getLogger("google") + base_logger.addHandler(logging.StreamHandler()) + base_logger.setLevel(logging.DEBUG) + +- Configuring a handler for a specific Google module (for a client library called :code:`library_v1`): + +.. code-block:: python + + import logging + + from google.cloud import library_v1 + + base_logger = logging.getLogger("google.cloud.library_v1") + base_logger.addHandler(logging.StreamHandler()) + base_logger.setLevel(logging.DEBUG) + +Logging details +~~~~~~~~~~~~~~~ + +#. Regardless of which of the mechanisms above you use to configure logging for this library, by default logging events are not propagated up to the root + logger from the `google`-level logger. If you need the events to be propagated to the root logger, you must explicitly set + :code:`logging.getLogger("google").propagate = True` in your code. +#. You can mix the different logging configurations above for different Google modules. For example, you may want use a code-based logging configuration for + one library, but decide you need to also set up environment-based logging configuration for another library. + + #. If you attempt to use both code-based and environment-based configuration for the same module, the environment-based configuration will be ineffectual + if the code -based configuration gets applied first. + +#. The Google-specific logging configurations (default handlers for environment-based configuration; not propagating logging events to the root logger) get + executed the first time *any* client library is instantiated in your application, and only if the affected loggers have not been previously configured. + (This is the reason for 2.i. above.) diff --git a/packages/google-backstory/docs/_static/custom.css b/packages/google-backstory/docs/_static/custom.css new file mode 100644 index 000000000000..b0a295464b23 --- /dev/null +++ b/packages/google-backstory/docs/_static/custom.css @@ -0,0 +1,20 @@ +div#python2-eol { + border-color: red; + border-width: medium; +} + +/* Ensure minimum width for 'Parameters' / 'Returns' column */ +dl.field-list > dt { + min-width: 100px +} + +/* Insert space between methods for readability */ +dl.method { + padding-top: 10px; + padding-bottom: 10px +} + +/* Insert empty space between classes */ +dl.class { + padding-bottom: 50px +} diff --git a/packages/google-backstory/docs/_templates/layout.html b/packages/google-backstory/docs/_templates/layout.html new file mode 100644 index 000000000000..95e9c77fcfe1 --- /dev/null +++ b/packages/google-backstory/docs/_templates/layout.html @@ -0,0 +1,50 @@ + +{% extends "!layout.html" %} +{%- block content %} +{%- if theme_fixed_sidebar|lower == 'true' %} +
+ {{ sidebar() }} + {%- block document %} +
+ {%- if render_sidebar %} +
+ {%- endif %} + + {%- block relbar_top %} + {%- if theme_show_relbar_top|tobool %} + + {%- endif %} + {% endblock %} + +
+
+ As of January 1, 2020 this library no longer supports Python 2 on the latest released version. + Library versions released prior to that date will continue to be available. For more information please + visit Python 2 support on Google Cloud. +
+ {% block body %} {% endblock %} +
+ + {%- block relbar_bottom %} + {%- if theme_show_relbar_bottom|tobool %} + + {%- endif %} + {% endblock %} + + {%- if render_sidebar %} +
+ {%- endif %} +
+ {%- endblock %} +
+
+{%- else %} +{{ super() }} +{%- endif %} +{%- endblock %} diff --git a/packages/google-backstory/docs/backstory/services_.rst b/packages/google-backstory/docs/backstory/services_.rst new file mode 100644 index 000000000000..cece5b116ec5 --- /dev/null +++ b/packages/google-backstory/docs/backstory/services_.rst @@ -0,0 +1,4 @@ +Services for Google Backstory API +================================== +.. toctree:: + :maxdepth: 2 diff --git a/packages/google-backstory/docs/backstory/types_.rst b/packages/google-backstory/docs/backstory/types_.rst new file mode 100644 index 000000000000..e61c709387a2 --- /dev/null +++ b/packages/google-backstory/docs/backstory/types_.rst @@ -0,0 +1,6 @@ +Types for Google Backstory API +=============================== + +.. automodule:: google.backstory.types + :members: + :show-inheritance: diff --git a/packages/google-backstory/docs/conf.py b/packages/google-backstory/docs/conf.py new file mode 100644 index 000000000000..b05f4ceb2b6f --- /dev/null +++ b/packages/google-backstory/docs/conf.py @@ -0,0 +1,417 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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-backstory 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 logging +import os +import shlex +import sys +from typing import Any + +# 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("..")) + +# For plugins that can not read conf.py. +# See also: https://github.com/docascode/sphinx-docfx-yaml/issues/85 +sys.path.insert(0, os.path.abspath(".")) + +__version__ = "" + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +needs_sphinx = "4.5.0" + +# 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.doctest", + "sphinx.ext.napoleon", + "sphinx.ext.todo", + "sphinx.ext.viewcode", + "recommonmark", +] + +# autodoc/autosummary flags +autoclass_content = "both" +autodoc_default_options = {"members": True} +autosummary_generate = True + + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# source_suffix = ['.rst', '.md'] +source_suffix = [".rst", ".md"] + +# The encoding of source files. +# source_encoding = 'utf-8-sig' + +# The root toctree document. +root_doc = "index" + +# General information about the project. +project = "google-backstory" +copyright = "2026, Google, LLC" +author = "Google APIs" + +# 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", + "**/.nox/**/*", + "samples/AUTHORING_GUIDE.md", + "samples/CONTRIBUTING.md", + "samples/snippets/README.rst", +] + +# 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 Client Libraries for google-backstory", + "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-backstory-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 = [ + ( + root_doc, + "google-backstory.tex", + "google-backstory 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 = [ + ( + root_doc, + "google-backstory", + "google-backstory 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 = [ + ( + root_doc, + "google-backstory", + "google-backstory Documentation", + author, + "google-backstory", + "google-backstory Library", + "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": ("https://python.readthedocs.org/en/latest/", None), + "google-auth": ("https://googleapis.dev/python/google-auth/latest/", None), + "google.api_core": ( + "https://googleapis.dev/python/google-api-core/latest/", + None, + ), + "grpc": ("https://grpc.github.io/grpc/python/", None), + "proto-plus": ("https://proto-plus-python.readthedocs.io/en/latest/", None), + "protobuf": ("https://googleapis.dev/python/protobuf/latest/", None), +} + + +# 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 + + +# Setup for sphinx behaviors such as warning filters. +class UnexpectedUnindentFilter(logging.Filter): + """Filter out warnings about unexpected unindentation following bullet lists.""" + + def filter(self, record: logging.LogRecord) -> bool: + """Filter the log record. + + Args: + record (logging.LogRecord): The log record. + + Returns: + bool: False to suppress the warning, True to allow it. + """ + msg = record.getMessage() + if "Bullet list ends without a blank line" in msg: + return False + return True + + +def setup(app: Any) -> None: + """Setup the Sphinx application. + + Args: + app (Any): The Sphinx application. + """ + # Sphinx's logger is hierarchical. Adding a filter to the + # root 'sphinx' logger will catch warnings from all sub-loggers. + logger = logging.getLogger("sphinx") + logger.addFilter(UnexpectedUnindentFilter()) diff --git a/packages/google-backstory/docs/index.rst b/packages/google-backstory/docs/index.rst new file mode 100644 index 000000000000..126e2a8e18c3 --- /dev/null +++ b/packages/google-backstory/docs/index.rst @@ -0,0 +1,10 @@ +.. include:: multiprocessing.rst + + +API Reference +------------- +.. toctree:: + :maxdepth: 2 + + backstory/services_ + backstory/types_ diff --git a/packages/google-backstory/docs/multiprocessing.rst b/packages/google-backstory/docs/multiprocessing.rst new file mode 100644 index 000000000000..536d17b2ea65 --- /dev/null +++ b/packages/google-backstory/docs/multiprocessing.rst @@ -0,0 +1,7 @@ +.. note:: + + Because this client uses :mod:`grpc` library, it is safe to + share instances across threads. In multiprocessing scenarios, the best + practice is to create client instances *after* the invocation of + :func:`os.fork` by :class:`multiprocessing.pool.Pool` or + :class:`multiprocessing.Process`. diff --git a/packages/google-backstory/google/backstory/__init__.py b/packages/google-backstory/google/backstory/__init__.py new file mode 100644 index 000000000000..bdb09ee6600d --- /dev/null +++ b/packages/google-backstory/google/backstory/__init__.py @@ -0,0 +1,339 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 sys + +import google.api_core as api_core + +from google.backstory import gapic_version as package_version + +__version__ = package_version.__version__ + +from importlib import metadata + +from .types.collection import ( + Collection, + DataTableRowInfo, + Element, + EntityGraphEnrichment, + LatencyMetrics, + Reference, + ResponsePlatformInfo, + SoarAlertMetadata, +) +from .types.data_access import DataAccessIngestionLabel, DataAccessLabels +from .types.entity import AtiPrioritization, Entity, EntityMetadata, Metric, Relation +from .types.entity_risk import EntityRisk, RiskDelta +from .types.id import Id +from .types.udm import ( + UDM, + X509, + AnalyticsMetadata, + AppCompatMetadata, + Artifact, + ArtifactClient, + Asset, + AttackDetails, + Attribute, + Authentication, + BoolSequence, + Browser, + BytesSequence, + Certificate, + Cloud, + Dhcp, + Dns, + DNSRecord, + Domain, + DoubleSequence, + Email, + ExifInfo, + Extensions, + Favicon, + File, + FileMetadata, + FileMetadataCodesign, + FileMetadataImports, + FileMetadataPE, + FileMetadataPeResourceInfo, + FileMetadataSection, + FileMetadataSignatureInfo, + FindingVariable, + Ftp, + Group, + GroupedFields, + Hardware, + Http, + Int64Sequence, + Investigation, + Label, + LinuxUtmp, + Location, + Metadata, + Network, + Noun, + NtfsFileMetadata, + OutlookMetadata, + PDFInfo, + PeFileMetadata, + Permission, + PlatformSoftware, + PopularityRank, + PrefetchFileMetadata, + Prevalence, + Priority, + Process, + ProxyInfo, + Reason, + Registry, + Reputation, + Resource, + ResourceUsage, + Role, + ScheduledAnacronTask, + ScheduledCronTask, + ScheduledTask, + SecurityResult, + Service, + SignatureInfo, + SignerInfo, + Smtp, + Software, + Srum, + SSLCertificate, + Status, + StringSequence, + StringToInt64MapEntry, + SystemEventDetails, + Tags, + ThreatVerdict, + TimeOff, + Tls, + Tracker, + Tunnels, + Uint64Sequence, + Url, + User, + UserAssist, + UsnJournal, + Verdict, + Volume, + Vulnerabilities, + Vulnerability, + WindowsEventLog, + WindowsScheduledTask, + WmiPersistenceItem, +) + +if hasattr(api_core, "check_python_version") and hasattr( + api_core, "check_dependency_versions" +): # pragma: NO COVER + api_core.check_python_version("google.backstory") # type: ignore + api_core.check_dependency_versions("google.backstory") # type: ignore +else: # pragma: NO COVER + # An older version of api_core is installed which does not define the + # functions above. We do equivalent checks manually. + try: + import warnings + + _py_version_str = sys.version.split()[0] + _package_label = "google.backstory" + if sys.version_info < (3, 10): + warnings.warn( + "You are using a non-supported Python version " + + f"({_py_version_str}). Google will not post any further " + + f"updates to {_package_label} supporting this Python version. " + + "Please upgrade to the latest Python version, or at " + + f"least to Python 3.10, and then update {_package_label}.", + FutureWarning, + ) + + def parse_version_to_tuple(version_string: str): + """Safely converts a semantic version string to a comparable tuple of integers. + Example: "4.25.8" -> (4, 25, 8) + Ignores non-numeric parts and handles common version formats. + Args: + version_string: Version string in the format "x.y.z" or "x.y.z" + Returns: + Tuple of integers for the parsed version string. + """ + parts = [] + for part in version_string.split("."): + try: + parts.append(int(part)) + except ValueError: + # If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here. + # This is a simplification compared to 'packaging.parse_version', but sufficient + # for comparing strictly numeric semantic versions. + break + return tuple(parts) + + def _get_version(dependency_name): + try: + version_string: str = metadata.version(dependency_name) + parsed_version = parse_version_to_tuple(version_string) + return (parsed_version, version_string) + except Exception: + # Catch exceptions from metadata.version() (e.g., PackageNotFoundError) + # or errors during parse_version_to_tuple + return (None, "--") + + _dependency_package = "google.protobuf" + _next_supported_version = "4.25.8" + _next_supported_version_tuple = (4, 25, 8) + _recommendation = " (we recommend 6.x)" + (_version_used, _version_used_string) = _get_version(_dependency_package) + if _version_used and _version_used < _next_supported_version_tuple: + warnings.warn( + f"Package {_package_label} depends on " + + f"{_dependency_package}, currently installed at version " + + f"{_version_used_string}. Future updates to " + + f"{_package_label} will require {_dependency_package} at " + + f"version {_next_supported_version} or higher{_recommendation}." + + " Please ensure " + + "that either (a) your Python environment doesn't pin the " + + f"version of {_dependency_package}, so that updates to " + + f"{_package_label} can require the higher version, or " + + "(b) you manually update your Python environment to use at " + + f"least version {_next_supported_version} of " + + f"{_dependency_package}.", + FutureWarning, + ) + except Exception: + warnings.warn( + "Could not determine the version of Python " + + "currently being used. To continue receiving " + + "updates for {_package_label}, ensure you are " + + "using a supported version of Python; see " + + "https://devguide.python.org/versions/" + ) + +__all__ = ( + "AnalyticsMetadata", + "AppCompatMetadata", + "Artifact", + "ArtifactClient", + "Asset", + "AtiPrioritization", + "AttackDetails", + "Attribute", + "Authentication", + "BoolSequence", + "Browser", + "BytesSequence", + "Certificate", + "Cloud", + "Collection", + "DNSRecord", + "DataAccessIngestionLabel", + "DataAccessLabels", + "DataTableRowInfo", + "Dhcp", + "Dns", + "Domain", + "DoubleSequence", + "Element", + "Email", + "Entity", + "EntityGraphEnrichment", + "EntityMetadata", + "EntityRisk", + "ExifInfo", + "Extensions", + "Favicon", + "File", + "FileMetadata", + "FileMetadataCodesign", + "FileMetadataImports", + "FileMetadataPE", + "FileMetadataPeResourceInfo", + "FileMetadataSection", + "FileMetadataSignatureInfo", + "FindingVariable", + "Ftp", + "Group", + "GroupedFields", + "Hardware", + "Http", + "Id", + "Int64Sequence", + "Investigation", + "Label", + "LatencyMetrics", + "LinuxUtmp", + "Location", + "Metadata", + "Metric", + "Network", + "Noun", + "NtfsFileMetadata", + "OutlookMetadata", + "PDFInfo", + "PeFileMetadata", + "Permission", + "PlatformSoftware", + "PopularityRank", + "PrefetchFileMetadata", + "Prevalence", + "Priority", + "Process", + "ProxyInfo", + "Reason", + "Reference", + "Registry", + "Relation", + "Reputation", + "Resource", + "ResourceUsage", + "ResponsePlatformInfo", + "RiskDelta", + "Role", + "SSLCertificate", + "ScheduledAnacronTask", + "ScheduledCronTask", + "ScheduledTask", + "SecurityResult", + "Service", + "SignatureInfo", + "SignerInfo", + "Smtp", + "SoarAlertMetadata", + "Software", + "Srum", + "Status", + "StringSequence", + "StringToInt64MapEntry", + "SystemEventDetails", + "Tags", + "ThreatVerdict", + "TimeOff", + "Tls", + "Tracker", + "Tunnels", + "UDM", + "Uint64Sequence", + "Url", + "User", + "UserAssist", + "UsnJournal", + "Verdict", + "Volume", + "Vulnerabilities", + "Vulnerability", + "WindowsEventLog", + "WindowsScheduledTask", + "WmiPersistenceItem", + "X509", +) diff --git a/packages/google-backstory/google/backstory/gapic_metadata.json b/packages/google-backstory/google/backstory/gapic_metadata.json new file mode 100644 index 000000000000..c94ccca35663 --- /dev/null +++ b/packages/google-backstory/google/backstory/gapic_metadata.json @@ -0,0 +1,7 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.backstory", + "protoPackage": "google.backstory", + "schema": "1.0" +} diff --git a/packages/google-backstory/google/backstory/gapic_version.py b/packages/google-backstory/google/backstory/gapic_version.py new file mode 100644 index 000000000000..e89a0031d71b --- /dev/null +++ b/packages/google-backstory/google/backstory/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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. +# +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-backstory/google/backstory/py.typed b/packages/google-backstory/google/backstory/py.typed new file mode 100644 index 000000000000..0d1d48dcfeaa --- /dev/null +++ b/packages/google-backstory/google/backstory/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-backstory package uses inline types. diff --git a/packages/google-backstory/google/backstory/services/__init__.py b/packages/google-backstory/google/backstory/services/__init__.py new file mode 100644 index 000000000000..32b36c5c4fe0 --- /dev/null +++ b/packages/google-backstory/google/backstory/services/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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/packages/google-backstory/google/backstory/types/__init__.py b/packages/google-backstory/google/backstory/types/__init__.py new file mode 100644 index 000000000000..658d39b622b2 --- /dev/null +++ b/packages/google-backstory/google/backstory/types/__init__.py @@ -0,0 +1,260 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 .collection import ( + Collection, + DataTableRowInfo, + Element, + EntityGraphEnrichment, + LatencyMetrics, + Reference, + ResponsePlatformInfo, + SoarAlertMetadata, +) +from .data_access import ( + DataAccessIngestionLabel, + DataAccessLabels, +) +from .entity import ( + AtiPrioritization, + Entity, + EntityMetadata, + Metric, + Relation, +) +from .entity_risk import ( + EntityRisk, + RiskDelta, +) +from .id import ( + Id, +) +from .udm import ( + UDM, + X509, + AnalyticsMetadata, + AppCompatMetadata, + Artifact, + ArtifactClient, + Asset, + AttackDetails, + Attribute, + Authentication, + BoolSequence, + Browser, + BytesSequence, + Certificate, + Cloud, + Dhcp, + Dns, + DNSRecord, + Domain, + DoubleSequence, + Email, + ExifInfo, + Extensions, + Favicon, + File, + FileMetadata, + FileMetadataCodesign, + FileMetadataImports, + FileMetadataPE, + FileMetadataPeResourceInfo, + FileMetadataSection, + FileMetadataSignatureInfo, + FindingVariable, + Ftp, + Group, + GroupedFields, + Hardware, + Http, + Int64Sequence, + Investigation, + Label, + LinuxUtmp, + Location, + Metadata, + Network, + Noun, + NtfsFileMetadata, + OutlookMetadata, + PDFInfo, + PeFileMetadata, + Permission, + PlatformSoftware, + PopularityRank, + PrefetchFileMetadata, + Prevalence, + Priority, + Process, + ProxyInfo, + Reason, + Registry, + Reputation, + Resource, + ResourceUsage, + Role, + ScheduledAnacronTask, + ScheduledCronTask, + ScheduledTask, + SecurityResult, + Service, + SignatureInfo, + SignerInfo, + Smtp, + Software, + Srum, + SSLCertificate, + Status, + StringSequence, + StringToInt64MapEntry, + SystemEventDetails, + Tags, + ThreatVerdict, + TimeOff, + Tls, + Tracker, + Tunnels, + Uint64Sequence, + Url, + User, + UserAssist, + UsnJournal, + Verdict, + Volume, + Vulnerabilities, + Vulnerability, + WindowsEventLog, + WindowsScheduledTask, + WmiPersistenceItem, +) + +__all__ = ( + "Collection", + "DataTableRowInfo", + "Element", + "EntityGraphEnrichment", + "LatencyMetrics", + "Reference", + "ResponsePlatformInfo", + "SoarAlertMetadata", + "DataAccessIngestionLabel", + "DataAccessLabels", + "AtiPrioritization", + "Entity", + "EntityMetadata", + "Metric", + "Relation", + "EntityRisk", + "RiskDelta", + "Id", + "AnalyticsMetadata", + "AppCompatMetadata", + "Artifact", + "ArtifactClient", + "Asset", + "AttackDetails", + "Attribute", + "Authentication", + "BoolSequence", + "Browser", + "BytesSequence", + "Certificate", + "Cloud", + "Dhcp", + "Dns", + "DNSRecord", + "Domain", + "DoubleSequence", + "Email", + "ExifInfo", + "Extensions", + "Favicon", + "File", + "FileMetadata", + "FileMetadataCodesign", + "FileMetadataImports", + "FileMetadataPE", + "FileMetadataPeResourceInfo", + "FileMetadataSection", + "FileMetadataSignatureInfo", + "FindingVariable", + "Ftp", + "Group", + "GroupedFields", + "Hardware", + "Http", + "Int64Sequence", + "Investigation", + "Label", + "LinuxUtmp", + "Location", + "Metadata", + "Network", + "Noun", + "NtfsFileMetadata", + "OutlookMetadata", + "PDFInfo", + "PeFileMetadata", + "Permission", + "PlatformSoftware", + "PopularityRank", + "PrefetchFileMetadata", + "Prevalence", + "Process", + "ProxyInfo", + "Registry", + "Resource", + "ResourceUsage", + "Role", + "ScheduledAnacronTask", + "ScheduledCronTask", + "ScheduledTask", + "SecurityResult", + "Service", + "SignatureInfo", + "SignerInfo", + "Smtp", + "Software", + "Srum", + "SSLCertificate", + "StringSequence", + "StringToInt64MapEntry", + "SystemEventDetails", + "Tags", + "TimeOff", + "Tls", + "Tracker", + "Tunnels", + "UDM", + "Uint64Sequence", + "Url", + "User", + "UserAssist", + "UsnJournal", + "Volume", + "Vulnerabilities", + "Vulnerability", + "WindowsEventLog", + "WindowsScheduledTask", + "WmiPersistenceItem", + "X509", + "Priority", + "Reason", + "Reputation", + "Status", + "ThreatVerdict", + "Verdict", +) diff --git a/packages/google-backstory/google/backstory/types/collection.py b/packages/google-backstory/google/backstory/types/collection.py new file mode 100644 index 000000000000..c4b512f8154f --- /dev/null +++ b/packages/google-backstory/google/backstory/types/collection.py @@ -0,0 +1,665 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import google.protobuf.duration_pb2 as duration_pb2 # type: ignore +import google.protobuf.struct_pb2 as struct_pb2 # type: ignore +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore +import google.type.interval_pb2 as interval_pb2 # type: ignore +import proto # type: ignore + +from google.backstory.types import entity as gb_entity +from google.backstory.types import id as gb_id +from google.backstory.types import udm + +__protobuf__ = proto.module( + package="google.backstory", + manifest={ + "Collection", + "EntityGraphEnrichment", + "DataTableRowInfo", + "LatencyMetrics", + "Reference", + "Element", + "ResponsePlatformInfo", + "SoarAlertMetadata", + }, +) + + +class Collection(proto.Message): + r"""Collection represents a container of objects (such as events, + entity context metadata, detection finding metadata) and state + (such as investigation details). + + An example use case for Collection is to model a detection and + investigation from detection finding metadata to investigative + state collected in the course of the investigation. For more + complex investigation and response workflows a Collection could + represent an incident consisting of multiple child findings or + incidents. This can be expanded on to model remediation elements + of a full detection and response workflow. + + Attributes: + id (str): + Unique ID for the collection. + The ID is specific to the type of collection. + For example, with rule detections this is the + detection ID. + type_ (google.backstory.types.Collection.CollectionType): + What the collection represents. + id_namespace (google.backstory.types.Id.Namespace): + The ID namespace used for the Collection. + created_time (google.protobuf.timestamp_pb2.Timestamp): + Time the collection was created. + last_updated_time (google.protobuf.timestamp_pb2.Timestamp): + Time the collection was last updated. + time_window (google.type.interval_pb2.Interval): + Time interval that the collection represents. + collection_elements (MutableSequence[google.backstory.types.Element]): + Constituent elements of the collection. Each + element shares an association that groups it + together and is a component of the overall + collection. For example, a detection collection + may have several constituent elements that each + share a correlation association that together + represent a particular pattern or behavior. + detection (MutableSequence[google.backstory.types.SecurityResult]): + Detection metadata for findings that + represent detections, can include rule details, + machine learning model metadata, and indicators + implicated in the detection (using the .about + field). + detection_time (google.protobuf.timestamp_pb2.Timestamp): + Timestamp within the time_window related to the time of the + collection_elements. For Rule Detections, this timestamp is + the end of the the time_window for multi-event rules or the + time of the event for single event rules. For late-arriving + events that trigger new alerts, the detection_time will be + the event time of the event. + investigation (google.backstory.types.Investigation): + Consolidated investigation details + (categorization, status, etc) typically for + collections that begin as detection findings and + then evolve with analyst action and feedback + into investigations around the detection output. + tags (MutableSequence[str]): + Tags set by UC/DSML/RE for the Finding during + creation. + response_platform_info (google.backstory.types.ResponsePlatformInfo): + Alert related info of this same alert in + customer's SOAR platform. + case_name (str): + The resource name of the Case that this collection belongs + to. Example: projects/{project + id}/locations/{region}/chronicle/cases/{internal_case_id} + soar_alert (bool): + A boolean field indicating that the alert is + present in SOAR. + soar_alert_metadata (google.backstory.types.SoarAlertMetadata): + Metadata fields of alerts coming from other + SIEM systems via SOAR. + data_access_scope (str): + The resource name of the DataAccessScope of + this collection. + detection_timing_details (MutableSequence[google.backstory.types.Collection.DetectionTimingDetails]): + Detection timing details for the collection. + These details are used to determine prossible + causes of latency for the detection. This field + is only set for detections that are generated by + rules. + latency_metrics (google.backstory.types.LatencyMetrics): + The latency metrics for the specific + detection. These metrics are calculated from ALL + of the events that contribute to the detection, + not just the sampled ones. + rule_run_frequency (google.backstory.types.Collection.RunFrequency): + The run frequency of the rule when it + generated the detection. + simulated_event_count (int): + The total number of simulated events that + contributed to this detection. Simulated events + are realistic threat sequences (Raw Logs or UDM) + programmatically delivered into the production + ingestion pipeline to verify the entire + detection lifecycle—from identification to + action. + simulated_event_names (MutableSequence[str]): + The set of all values from event ingestion_labels where + SIMULATED is set as the key, for all simulated events that + participated in this detection. + """ + + class CollectionType(proto.Enum): + r"""The type of the collection which will indicate which other + fields are relevant. For example, detection finding collections + will populate the detection field. Findings that evolve into + investigations will populate the investigation field. + + Values: + COLLECTION_TYPE_UNSPECIFIED (0): + An unspecified collection type. + TELEMETRY_ALERT (1): + An alert reported in customer telemetry. + GCTI_FINDING (2): + A finding from the Uppercase team. + UPPERCASE_ALERT (2): + No description available. + RULE_DETECTION (3): + A detection found by applying a rule. + MACHINE_INTELLIGENCE_ALERT (4): + An alert generated by Chronicle machine + learning models. + SOAR_ALERT (5): + An alert coming from other SIEMs via + Chronicle SOAR. + """ + + _pb_options = {"allow_alias": True} + COLLECTION_TYPE_UNSPECIFIED = 0 + TELEMETRY_ALERT = 1 + GCTI_FINDING = 2 + UPPERCASE_ALERT = 2 + RULE_DETECTION = 3 + MACHINE_INTELLIGENCE_ALERT = 4 + SOAR_ALERT = 5 + + class DetectionTimingDetails(proto.Enum): + r"""Detection timing details for the collection. + + Values: + DETECTION_TIMING_DETAILS_UNSPECIFIED (0): + Detection timing details are unspecified. + DETECTION_TIMING_DETAILS_REPROCESSING (1): + Detection is generated by a reprocessing run. + DETECTION_TIMING_DETAILS_RETROHUNT (2): + Detection is generated by a retrohunt run. + """ + + DETECTION_TIMING_DETAILS_UNSPECIFIED = 0 + DETECTION_TIMING_DETAILS_REPROCESSING = 1 + DETECTION_TIMING_DETAILS_RETROHUNT = 2 + + class RunFrequency(proto.Enum): + r"""Run frequencies used by rule executions. + + Values: + RUN_FREQUENCY_UNSPECIFIED (0): + Unspecified run frequency. + RUN_FREQUENCY_REALTIME (1): + Real-time run frequency. + RUN_FREQUENCY_HOURLY (2): + Executes once an hour. + RUN_FREQUENCY_DAILY (3): + Executes once a day. + """ + + RUN_FREQUENCY_UNSPECIFIED = 0 + RUN_FREQUENCY_REALTIME = 1 + RUN_FREQUENCY_HOURLY = 2 + RUN_FREQUENCY_DAILY = 3 + + id: str = proto.Field( + proto.STRING, + number=7, + ) + type_: CollectionType = proto.Field( + proto.ENUM, + number=1, + enum=CollectionType, + ) + id_namespace: gb_id.Id.Namespace = proto.Field( + proto.ENUM, + number=12, + enum=gb_id.Id.Namespace, + ) + created_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + last_updated_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=6, + message=timestamp_pb2.Timestamp, + ) + time_window: interval_pb2.Interval = proto.Field( + proto.MESSAGE, + number=8, + message=interval_pb2.Interval, + ) + collection_elements: MutableSequence["Element"] = proto.RepeatedField( + proto.MESSAGE, + number=9, + message="Element", + ) + detection: MutableSequence[udm.SecurityResult] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=udm.SecurityResult, + ) + detection_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=10, + message=timestamp_pb2.Timestamp, + ) + investigation: udm.Investigation = proto.Field( + proto.MESSAGE, + number=4, + message=udm.Investigation, + ) + tags: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=11, + ) + response_platform_info: "ResponsePlatformInfo" = proto.Field( + proto.MESSAGE, + number=13, + message="ResponsePlatformInfo", + ) + case_name: str = proto.Field( + proto.STRING, + number=14, + ) + soar_alert: bool = proto.Field( + proto.BOOL, + number=17, + ) + soar_alert_metadata: "SoarAlertMetadata" = proto.Field( + proto.MESSAGE, + number=18, + message="SoarAlertMetadata", + ) + data_access_scope: str = proto.Field( + proto.STRING, + number=19, + ) + detection_timing_details: MutableSequence[DetectionTimingDetails] = ( + proto.RepeatedField( + proto.ENUM, + number=20, + enum=DetectionTimingDetails, + ) + ) + latency_metrics: "LatencyMetrics" = proto.Field( + proto.MESSAGE, + number=21, + message="LatencyMetrics", + ) + rule_run_frequency: RunFrequency = proto.Field( + proto.ENUM, + number=22, + enum=RunFrequency, + ) + simulated_event_count: int = proto.Field( + proto.INT64, + number=23, + ) + simulated_event_names: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=24, + ) + + +class EntityGraphEnrichment(proto.Message): + r"""EntityGraphEnrichment contains the data table name and the + enrichment applied to the entity. + + Attributes: + data_table (str): + The name of the data table. + enrichment_type (google.backstory.types.EntityGraphEnrichment.EnrichmentType): + The type of enrichment. + overridden_entity (google.backstory.types.Entity): + The entity which has only the overridden + fields populated. Only populated if the + enrichment type is OVERRIDE. + """ + + class EnrichmentType(proto.Enum): + r"""Type of enrichment. + + Values: + ENRICHMENT_TYPE_UNSPECIFIED (0): + Enrichment type is unspecified. + APPEND (1): + The data table was appended to the entity + graph. + OVERRIDE (2): + The entity graph was overridden by the data + table. + """ + + ENRICHMENT_TYPE_UNSPECIFIED = 0 + APPEND = 1 + OVERRIDE = 2 + + data_table: str = proto.Field( + proto.STRING, + number=1, + ) + enrichment_type: EnrichmentType = proto.Field( + proto.ENUM, + number=3, + enum=EnrichmentType, + ) + overridden_entity: gb_entity.Entity = proto.Field( + proto.MESSAGE, + number=2, + message=gb_entity.Entity, + ) + + +class DataTableRowInfo(proto.Message): + r"""DataTableRowInfo captures information about a data table row + including the name of the data table. + + Attributes: + data_table (str): + The name of data table. + row (google.protobuf.struct_pb2.Struct): + Stores the key value pair for a data table + row where the key is the name of the column for + the given value. + row_id (str): + The row id of the data table row. + """ + + data_table: str = proto.Field( + proto.STRING, + number=1, + ) + row: struct_pb2.Struct = proto.Field( + proto.MESSAGE, + number=2, + message=struct_pb2.Struct, + ) + row_id: str = proto.Field( + proto.STRING, + number=3, + ) + + +class LatencyMetrics(proto.Message): + r"""LatencyMetrics contains relevant timestamps for measuring + latency per event variable. These metrics are calculated from + ALL of the events that contribute to the detection, not just the + sampled ones. + + Attributes: + oldest_ingestion_time (google.protobuf.timestamp_pb2.Timestamp): + The oldest ingestion timestamp from the + events used to create the detection. + newest_ingestion_time (google.protobuf.timestamp_pb2.Timestamp): + The newest (most recent) ingestion timestamp + from the events used to create the detection. + oldest_event_time (google.protobuf.timestamp_pb2.Timestamp): + The oldest event timestamp from the events + used to create the detection. + newest_event_time (google.protobuf.timestamp_pb2.Timestamp): + The newest (most recent) event timestamp from + the events used to create the detection. + ingestion_latency (google.protobuf.duration_pb2.Duration): + The difference between newest ingestion + timestamp and newest event timestamp. + """ + + oldest_ingestion_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + newest_ingestion_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + oldest_event_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + newest_event_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=4, + message=timestamp_pb2.Timestamp, + ) + ingestion_latency: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=5, + message=duration_pb2.Duration, + ) + + +class Reference(proto.Message): + r"""Reference to model primatives including event and entity. As + support is added for fast retrieval of objects by identifiers, + this will be expanded to include ID references rather than full + object copies. + + Attributes: + event (google.backstory.types.UDM): + Only one of event or entity will be populated + for a single reference. + Start one-of + Event being referenced. + entity (google.backstory.types.Entity): + Entity being referenced. In cases where the + entity graph is overridden by data table, this + will represent the original entity. End one-of + joined_data_table_rows (MutableSequence[google.backstory.types.DataTableRowInfo]): + The data table rows joined with the event. + graph_enrichment (google.backstory.types.EntityGraphEnrichment): + The entity graph enrichment details. Only set + when the reference is an Entity which has been + overridden by a data table or appended from a + data table. + id (google.backstory.types.Id): + Id being referenced. This field will also be + populated for both event and entity with the + event id. For detections, only this field will + be populated. + log_batch_token (str): + The log batch token of the event being + referenced. This field is used to fetch the raw + log associated with the event in some legacy + systems. This field is only populated for + events/entities. + """ + + event: udm.UDM = proto.Field( + proto.MESSAGE, + number=1, + message=udm.UDM, + ) + entity: gb_entity.Entity = proto.Field( + proto.MESSAGE, + number=2, + message=gb_entity.Entity, + ) + joined_data_table_rows: MutableSequence["DataTableRowInfo"] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message="DataTableRowInfo", + ) + graph_enrichment: "EntityGraphEnrichment" = proto.Field( + proto.MESSAGE, + number=5, + message="EntityGraphEnrichment", + ) + id: gb_id.Id = proto.Field( + proto.MESSAGE, + number=3, + message=gb_id.Id, + ) + log_batch_token: str = proto.Field( + proto.STRING, + number=6, + ) + + +class Element(proto.Message): + r""" + + Attributes: + association (google.backstory.types.SecurityResult): + Metadata that provides the relevant + association for the references in the element. + For a detection, this can be the correlated + aspect of the references that contributed to the + overall detection. For example, may include + sub-rule condition, machine learning model + metadata, and/or indicators implicated in this + component of the detection (using the .about + field). + references (MutableSequence[google.backstory.types.Reference]): + References to model primatives including + events and entities that share a common + association. Even though a reference can have + both UDM and entity, a collection of references + (of a single element) will only have one type of + message in it (either UDM / Entity). + label (str): + A name that labels the entire references + group. + references_sampled (bool): + Copied from the detection + event_sample.too_many_event_samples field. If true, the + number of references will be capped at the sample limit (set + at rule service). This is applicable to both UDM references + and Entity references. + latency_metrics (google.backstory.types.LatencyMetrics): + Latency metrics for the specific element. + These are calculated from all the contributing + events or entities for a single event variable, + not just the sampled ones included in + references. This is currently only populated for + UDM events. + """ + + association: udm.SecurityResult = proto.Field( + proto.MESSAGE, + number=1, + message=udm.SecurityResult, + ) + references: MutableSequence["Reference"] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="Reference", + ) + label: str = proto.Field( + proto.STRING, + number=3, + ) + references_sampled: bool = proto.Field( + proto.BOOL, + number=4, + ) + latency_metrics: "LatencyMetrics" = proto.Field( + proto.MESSAGE, + number=5, + message="LatencyMetrics", + ) + + +class ResponsePlatformInfo(proto.Message): + r"""Related info of an Alert in customer's SOAR platform. + + Attributes: + alert_id (str): + Id of the alert in SOAR product. + response_platform_type (google.backstory.types.ResponsePlatformInfo.ResponsePlatformType): + Type of SOAR product. + """ + + class ResponsePlatformType(proto.Enum): + r"""Available response platforms. + + Values: + RESPONSE_PLATFORM_TYPE_UNSPECIFIED (0): + Response platform not specified. + RESPONSE_PLATFORM_TYPE_SIEMPLIFY (1): + Siemplify + """ + + RESPONSE_PLATFORM_TYPE_UNSPECIFIED = 0 + RESPONSE_PLATFORM_TYPE_SIEMPLIFY = 1 + + alert_id: str = proto.Field( + proto.STRING, + number=2, + ) + response_platform_type: ResponsePlatformType = proto.Field( + proto.ENUM, + number=3, + enum=ResponsePlatformType, + ) + + +class SoarAlertMetadata(proto.Message): + r"""Metadata fields of alerts coming from other SIEM systems. + + Attributes: + alert_id (str): + Alert ID in the source SIEM system. + source_rule (str): + Name of the rule triggering the alert in the + source SIEM. + vendor (str): + Name of the vendor. + source_system (str): + Name of the Source SIEM system. + product (str): + Name of the product the alert is coming from. + source_system_ticket_id (str): + Ticket id for the alert in the source system. + source_system_uri (str): + Url to the source SIEM system. + """ + + alert_id: str = proto.Field( + proto.STRING, + number=1, + ) + source_rule: str = proto.Field( + proto.STRING, + number=2, + ) + vendor: str = proto.Field( + proto.STRING, + number=3, + ) + source_system: str = proto.Field( + proto.STRING, + number=4, + ) + product: str = proto.Field( + proto.STRING, + number=5, + ) + source_system_ticket_id: str = proto.Field( + proto.STRING, + number=6, + ) + source_system_uri: str = proto.Field( + proto.STRING, + number=7, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-backstory/google/backstory/types/data_access.py b/packages/google-backstory/google/backstory/types/data_access.py new file mode 100644 index 000000000000..bf944d8810fe --- /dev/null +++ b/packages/google-backstory/google/backstory/types/data_access.py @@ -0,0 +1,99 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.backstory", + manifest={ + "DataAccessIngestionLabel", + "DataAccessLabels", + }, +) + + +class DataAccessIngestionLabel(proto.Message): + r"""Label used in data access for ingestion. + + Attributes: + key (str): + The key. + value (str): + The value. + """ + + key: str = proto.Field( + proto.STRING, + number=1, + ) + value: str = proto.Field( + proto.STRING, + number=2, + ) + + +class DataAccessLabels(proto.Message): + r"""Label used in data access. + + Attributes: + log_types (MutableSequence[str]): + All the LogType labels. + ingestion_labels (MutableSequence[str]): + All the ingestion labels. + namespaces (MutableSequence[str]): + All the namespaces. + custom_labels (MutableSequence[str]): + All the complex labels (UDM search syntax + based). + ingestion_kv_labels (MutableSequence[google.backstory.types.DataAccessIngestionLabel]): + All the ingestion labels (key/value pairs). + allow_scoped_access (bool): + Are the labels ready for scoped access + """ + + log_types: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + ingestion_labels: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + namespaces: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + custom_labels: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=4, + ) + ingestion_kv_labels: MutableSequence["DataAccessIngestionLabel"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=5, + message="DataAccessIngestionLabel", + ) + ) + allow_scoped_access: bool = proto.Field( + proto.BOOL, + number=6, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-backstory/google/backstory/types/entity.py b/packages/google-backstory/google/backstory/types/entity.py new file mode 100644 index 000000000000..b11d1bf977a5 --- /dev/null +++ b/packages/google-backstory/google/backstory/types/entity.py @@ -0,0 +1,976 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import google.protobuf.struct_pb2 as struct_pb2 # type: ignore +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore +import google.type.interval_pb2 as interval_pb2 # type: ignore +import proto # type: ignore + +from google.backstory.types import entity_risk, udm + +__protobuf__ = proto.module( + package="google.backstory", + manifest={ + "EntityMetadata", + "AtiPrioritization", + "Entity", + "Relation", + "Metric", + }, +) + + +class EntityMetadata(proto.Message): + r"""Information about the Entity and the product where the entity + was created. + + Attributes: + product_entity_id (str): + A vendor-specific identifier that uniquely + identifies the entity (e.g. a GUID, LDAP, OID, + or similar). + collected_timestamp (google.protobuf.timestamp_pb2.Timestamp): + GMT timestamp when the entity information was + collected by the vendor's local collection + infrastructure. + creation_timestamp (google.protobuf.timestamp_pb2.Timestamp): + GMT timestamp when the entity described by the + product_entity_id was created on the system where data was + collected. + interval (google.type.interval_pb2.Interval): + Valid existence time range for the version of + the entity represented by this entity data. + vendor_name (str): + Vendor name of the product that produced the + entity information. + product_name (str): + Product name that produced the entity + information. + feed (str): + Vendor feed name for a threat indicator feed. + product_version (str): + Version of the product that produced the + entity information. + entity_type (google.backstory.types.EntityMetadata.EntityType): + Entity type. + If an entity has multiple possible types, this + specifies the most specific type. + description (str): + Human-readable description of the entity. + threat (MutableSequence[google.backstory.types.SecurityResult]): + Metadata provided by a threat intelligence + feed that identified the entity as malicious. + source_type (google.backstory.types.EntityMetadata.SourceType): + The source of the entity. + source_labels (MutableSequence[google.backstory.types.Label]): + Entity source metadata labels. + event_metadata (google.backstory.types.Metadata): + Metadata field from the event. + structured_fields (google.protobuf.struct_pb2.Struct): + Structured fields extracted from the log. + extracted (google.protobuf.struct_pb2.Struct): + Flattened fields extracted from the log. + ati_prioritization (google.backstory.types.AtiPrioritization): + Prioritization factors used by ATI curated + rules. + """ + + class EntityType(proto.Enum): + r"""Describes the type of entity. + An unknown event type. + + Values: + UNKNOWN_ENTITYTYPE (0): + @hide_from_doc + ASSET (1): + An asset, such as workstation, laptop, phone, + virtual machine, etc. + USER (10000): + User. + GROUP (10001): + Group. + RESOURCE (2): + Resource. + IP_ADDRESS (3): + An external IP address. + CIDR_BLOCK (9): + A CIDR block. + FILE (4): + A file. + DOMAIN_NAME (5): + A domain. + URL (6): + A url. + MUTEX (7): + A mutex. + METRIC (8): + A metric. + """ + + UNKNOWN_ENTITYTYPE = 0 + ASSET = 1 + USER = 10000 + GROUP = 10001 + RESOURCE = 2 + IP_ADDRESS = 3 + CIDR_BLOCK = 9 + FILE = 4 + DOMAIN_NAME = 5 + URL = 6 + MUTEX = 7 + METRIC = 8 + + class SourceType(proto.Enum): + r"""Describes the source of an entity. + + Values: + SOURCE_TYPE_UNSPECIFIED (0): + Default source type + ENTITY_CONTEXT (1): + Entities ingested from customers (e.g. AD_CONTEXT, + DLP_CONTEXT) + DERIVED_CONTEXT (2): + Entities derived from customer data such as + prevalence, artifact first/last seen, or + asset/user first seen stats. + GLOBAL_CONTEXT (3): + Global contextual entities such as WHOIS or + Safe Browsing. + """ + + SOURCE_TYPE_UNSPECIFIED = 0 + ENTITY_CONTEXT = 1 + DERIVED_CONTEXT = 2 + GLOBAL_CONTEXT = 3 + + product_entity_id: str = proto.Field( + proto.STRING, + number=1, + ) + collected_timestamp: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + creation_timestamp: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=8, + message=timestamp_pb2.Timestamp, + ) + interval: interval_pb2.Interval = proto.Field( + proto.MESSAGE, + number=9, + message=interval_pb2.Interval, + ) + vendor_name: str = proto.Field( + proto.STRING, + number=3, + ) + product_name: str = proto.Field( + proto.STRING, + number=4, + ) + feed: str = proto.Field( + proto.STRING, + number=14, + ) + product_version: str = proto.Field( + proto.STRING, + number=5, + ) + entity_type: EntityType = proto.Field( + proto.ENUM, + number=6, + enum=EntityType, + ) + description: str = proto.Field( + proto.STRING, + number=7, + ) + threat: MutableSequence[udm.SecurityResult] = proto.RepeatedField( + proto.MESSAGE, + number=10, + message=udm.SecurityResult, + ) + source_type: SourceType = proto.Field( + proto.ENUM, + number=11, + enum=SourceType, + ) + source_labels: MutableSequence[udm.Label] = proto.RepeatedField( + proto.MESSAGE, + number=12, + message=udm.Label, + ) + event_metadata: udm.Metadata = proto.Field( + proto.MESSAGE, + number=13, + message=udm.Metadata, + ) + structured_fields: struct_pb2.Struct = proto.Field( + proto.MESSAGE, + number=15, + message=struct_pb2.Struct, + ) + extracted: struct_pb2.Struct = proto.Field( + proto.MESSAGE, + number=16, + message=struct_pb2.Struct, + ) + ati_prioritization: "AtiPrioritization" = proto.Field( + proto.MESSAGE, + number=17, + message="AtiPrioritization", + ) + + +class AtiPrioritization(proto.Message): + r"""AtiPrioritization contains various fields used to calculate a + priority score for an entity identified as a threat. + + Attributes: + gti_verdict (int): + The confidence score from "GTI verdict" + source. + gti_severity (int): + The confidence score from "GTI severity" + source. + gti_threat_score (int): + The confidence score from "GTI threat score" + source. + mandiant_analyst_confidence (int): + The confidence score from "Mandiant Analyst + Intel" source. + gti_update_time (google.protobuf.timestamp_pb2.Timestamp): + Timestamp of the latest update for GTI + verdict, severity, or threat score. + active_ir (bool): + Whether one or more Mandiant incident + response customers had this indicator in their + environment. + active_ir_first_tagged_time (google.protobuf.timestamp_pb2.Timestamp): + The timestamp of the first time an active IR + was applied to this entity. + global_customer_count (int): + Global customer count over the last 30 days + global_hit_count (int): + Global hit count over the last 30 days + exclusive (bool): + Whether the indicator is being used by a + maximum of one threat actor. + osint (bool): + Whether the indicator details are available + in open source. + scanner (bool): + Whether the indicator is a scanner. + reviewed (bool): + Whether the indicator verdict has passed + review. + attributed_malware (MutableSequence[google.backstory.types.SecurityResult.Association]): + Malware families associated with this + indicator. + attributed_threat_actors (MutableSequence[google.backstory.types.SecurityResult.Association]): + Threat actors associated with this indicator. + """ + + gti_verdict: int = proto.Field( + proto.INT32, + number=1, + ) + gti_severity: int = proto.Field( + proto.INT32, + number=2, + ) + gti_threat_score: int = proto.Field( + proto.INT32, + number=3, + ) + mandiant_analyst_confidence: int = proto.Field( + proto.INT32, + number=4, + ) + gti_update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + active_ir: bool = proto.Field( + proto.BOOL, + number=6, + ) + active_ir_first_tagged_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=7, + message=timestamp_pb2.Timestamp, + ) + global_customer_count: int = proto.Field( + proto.INT64, + number=8, + ) + global_hit_count: int = proto.Field( + proto.INT64, + number=9, + ) + exclusive: bool = proto.Field( + proto.BOOL, + number=10, + ) + osint: bool = proto.Field( + proto.BOOL, + number=11, + ) + scanner: bool = proto.Field( + proto.BOOL, + number=12, + ) + reviewed: bool = proto.Field( + proto.BOOL, + number=13, + ) + attributed_malware: MutableSequence[udm.SecurityResult.Association] = ( + proto.RepeatedField( + proto.MESSAGE, + number=14, + message=udm.SecurityResult.Association, + ) + ) + attributed_threat_actors: MutableSequence[udm.SecurityResult.Association] = ( + proto.RepeatedField( + proto.MESSAGE, + number=15, + message=udm.SecurityResult.Association, + ) + ) + + +class Entity(proto.Message): + r"""An Entity provides additional context about an item in a UDM event. + For example, a PROCESS_LAUNCH event describes that user + 'abc@example.corp' launched process 'shady.exe'. The event does not + include information that user 'abc@example.com' is a recently + terminated employee who administers a server storing finance data. + Information stored in one or more Entities can add this additional + context. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + metadata (google.backstory.types.EntityMetadata): + Entity metadata such as timestamp, product, + etc. + entity (google.backstory.types.Noun): + Noun in the UDM event that this entity + represents. + relations (MutableSequence[google.backstory.types.Relation]): + One or more relationships between the entity + (a) and other entities, including the + relationship type and related entity. + additional (google.protobuf.struct_pb2.Struct): + Important entity data that cannot be + adequately represented within the formal + sections of the Entity. + risk_score (google.backstory.types.EntityRisk): + Stores information related to the entity's + risk score. + + This field is a member of `oneof`_ ``_risk_score``. + metric (google.backstory.types.Metric): + Stores statistical metrics about the entity. Used if + metadata.entity_type is METRIC. + """ + + metadata: "EntityMetadata" = proto.Field( + proto.MESSAGE, + number=1, + message="EntityMetadata", + ) + entity: udm.Noun = proto.Field( + proto.MESSAGE, + number=2, + message=udm.Noun, + ) + relations: MutableSequence["Relation"] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message="Relation", + ) + additional: struct_pb2.Struct = proto.Field( + proto.MESSAGE, + number=3, + message=struct_pb2.Struct, + ) + risk_score: entity_risk.EntityRisk = proto.Field( + proto.MESSAGE, + number=5, + optional=True, + message=entity_risk.EntityRisk, + ) + metric: "Metric" = proto.Field( + proto.MESSAGE, + number=6, + message="Metric", + ) + + +class Relation(proto.Message): + r"""Defines the relationship between the entity (a) and another + entity (b). + + Attributes: + entity (google.backstory.types.Noun): + Entity (b) that the primary entity (a) is + related to. + entity_type (google.backstory.types.EntityMetadata.EntityType): + Type of the related entity (b) in this + relationship. + relationship (google.backstory.types.Relation.Relationship): + Type of relationship. + direction (google.backstory.types.Relation.Directionality): + Directionality of relationship between + primary entity (a) and the related entity (b). + uid (bytes): + UID of the relationship. + entity_label (google.backstory.types.Relation.EntityLabel): + Label to identify the Noun of the relation. + """ + + class Relationship(proto.Enum): + r"""Type of relationship between the primary entity (a) and + related entity (b). + + Values: + RELATIONSHIP_UNSPECIFIED (0): + Default value + OWNS (1): + Related entity is owned by the primary entity + (e.g. user owns device asset). + ADMINISTERS (2): + Related entity is administered by the primary + entity (e.g. user administers a group). + MEMBER (3): + Primary entity is a member of the related + entity (e.g. user is a member of a group). + EXECUTES (4): + Primary entity may have executed the related + entity. + DOWNLOADED_FROM (5): + Primary entity may have been downloaded from + the related entity. + CONTACTS (6): + Primary entity contacts the related entity. + """ + + RELATIONSHIP_UNSPECIFIED = 0 + OWNS = 1 + ADMINISTERS = 2 + MEMBER = 3 + EXECUTES = 4 + DOWNLOADED_FROM = 5 + CONTACTS = 6 + + class Directionality(proto.Enum): + r"""Describes the relationship model as directed or undirected. + + Values: + DIRECTIONALITY_UNSPECIFIED (0): + Default value. + BIDIRECTIONAL (1): + Modeled in both directions. Primary entity + (a) to related entity (b) and related entity (b) + to primary entity (a). + UNIDIRECTIONAL (2): + Modeled in a single direction. Primary entity + (a) to related entity (b). + """ + + DIRECTIONALITY_UNSPECIFIED = 0 + BIDIRECTIONAL = 1 + UNIDIRECTIONAL = 2 + + class EntityLabel(proto.Enum): + r"""Entity label of the relation. + + Values: + ENTITY_LABEL_UNSPECIFIED (0): + Default value. + PRINCIPAL (1): + The Noun represents a principal type object. + TARGET (2): + The Noun represents a target type object. + OBSERVER (3): + The Noun represents an observer type object. + SRC (4): + The Noun represents src type object. + NETWORK (5): + The Noun represents a network type object. + SECURITY_RESULT (6): + The Noun represents a SecurityResult object. + INTERMEDIARY (7): + The Noun represents an intermediary type + object. + """ + + ENTITY_LABEL_UNSPECIFIED = 0 + PRINCIPAL = 1 + TARGET = 2 + OBSERVER = 3 + SRC = 4 + NETWORK = 5 + SECURITY_RESULT = 6 + INTERMEDIARY = 7 + + entity: udm.Noun = proto.Field( + proto.MESSAGE, + number=1, + message=udm.Noun, + ) + entity_type: "EntityMetadata.EntityType" = proto.Field( + proto.ENUM, + number=2, + enum="EntityMetadata.EntityType", + ) + relationship: Relationship = proto.Field( + proto.ENUM, + number=3, + enum=Relationship, + ) + direction: Directionality = proto.Field( + proto.ENUM, + number=4, + enum=Directionality, + ) + uid: bytes = proto.Field( + proto.BYTES, + number=5, + ) + entity_label: EntityLabel = proto.Field( + proto.ENUM, + number=6, + enum=EntityLabel, + ) + + +class Metric(proto.Message): + r"""Stores precomputed aggregated analytic data for an entity. + + Attributes: + first_seen (google.protobuf.timestamp_pb2.Timestamp): + Timestamp of the first time the entity was + seen in the environment. + last_seen (google.protobuf.timestamp_pb2.Timestamp): + Time stamp of the last time last time the + entity was seen in the environment. + sum_measure (google.backstory.types.Metric.Measure): + Sum of all precomputed measures for the given + metric. + total_events (int): + Total number of events used to calculate the + given precomputed metric. + metric_name (google.backstory.types.Metric.MetricName): + Name of the analytic. + dimensions (MutableSequence[google.backstory.types.Metric.Dimension]): + All group by clauses used to calculate the + metric. + export_window (int): + Export window for which the metric was + exported. + display_name (str): + Display name of the custom metric. + Google-authored metrics do not have a display + name. + outcome_variables (MutableSequence[google.backstory.types.FindingVariable]): + List of outcome variables used in the custom + metric. + match_variables (MutableSequence[google.backstory.types.FindingVariable]): + List of match variables used in the custom + metric. + time_range (google.type.interval_pb2.Interval): + Time range for which the custom metric was + calculated. + """ + + class AggregateFunction(proto.Enum): + r"""Mathematic function used to calculate the value. + + Values: + AGGREGATE_FUNCTION_UNSPECIFIED (0): + Default value. + MIN (1): + Minimum. + MAX (2): + Maximum. + COUNT (3): + Count. + SUM (4): + Sum. + AVG (5): + Average. + STDDEV (6): + Standard Deviation. + """ + + AGGREGATE_FUNCTION_UNSPECIFIED = 0 + MIN = 1 + MAX = 2 + COUNT = 3 + SUM = 4 + AVG = 5 + STDDEV = 6 + + class MetricName(proto.Enum): + r"""The name of the precomputed analytic. + + Values: + METRIC_NAME_UNSPECIFIED (0): + Default + NETWORK_BYTES_INBOUND (1): + Total received network bytes. + NETWORK_BYTES_OUTBOUND (2): + Total network sent bytes. + NETWORK_BYTES_TOTAL (3): + Total network sent bytes and received bytes. + AUTH_ATTEMPTS_SUCCESS (4): + Successful authentication attempts. + AUTH_ATTEMPTS_FAIL (5): + Failed authentication attempts. + AUTH_ATTEMPTS_TOTAL (6): + Total authentication attempts. + DNS_BYTES_OUTBOUND (7): + Total number of sent bytes for DNS events. + NETWORK_FLOWS_INBOUND (8): + Total number of events having non-null + received bytes. + NETWORK_FLOWS_OUTBOUND (9): + Total number of events having non-null sent + bytes. + NETWORK_FLOWS_TOTAL (10): + Total events having non-null sent or received + bytes. + DNS_QUERIES_SUCCESS (11): + DNS query success count - Number of events with + response_code = 0. + DNS_QUERIES_FAIL (12): + Number of events with response_code != 0. + DNS_QUERIES_TOTAL (13): + Total number of DNS queries made. + FILE_EXECUTIONS_SUCCESS (14): + Number of successfule file executions. + FILE_EXECUTIONS_FAIL (15): + Number of failed file executions. + FILE_EXECUTIONS_TOTAL (16): + Total number file executions. + HTTP_QUERIES_SUCCESS (17): + Number of successful HTTP queries. + HTTP_QUERIES_FAIL (18): + Number of failed HTTP queries. + HTTP_QUERIES_TOTAL (19): + Total number of HTTP queries. + WORKSPACE_EMAILS_SENT_TOTAL (20): + Total number of emails sent in Google + Workspace. + WORKSPACE_TOTAL_DOWNLOAD_ACTIONS (21): + Total number of download actions in Google + Workspace. + WORKSPACE_TOTAL_CHANGE_ACTIONS (22): + Total number of change actions in Google + Workspace. + WORKSPACE_AUTH_ATTEMPTS_TOTAL (23): + Total number of authentication attempts in + Google Workspace. + WORKSPACE_NETWORK_BYTES_OUTBOUND (24): + Number of outbound network bytes (total sent) + in Google Workspace. + WORKSPACE_NETWORK_BYTES_TOTAL (25): + Total number of network bytes (both sent and + received) in Google Workspace. + ALERT_EVENT_NAME_COUNT (26): + Track number of alerts fired by + EDR/SENTINEL/MICROSOFT_GRAPH. + RESOURCE_CREATION_TOTAL (27): + Analytic tracking successful resource + creations. + RESOURCE_CREATION_SUCCESS (28): + Analytic tracking successful resource + creations. + RESOURCE_READ_SUCCESS (29): + Analytic tracking successful resource reads. + RESOURCE_READ_FAIL (30): + Analytic tracking failed resource reads. + RESOURCE_DELETION_SUCCESS (31): + Analytic tracking successful resource + deletions. + RESOURCE_CREATION_FAIL (32): + Analytic tracking failed resource creations. + RESOURCE_DELETION_FAIL (33): + Analytic tracking failed resource deletions. + RESOURCE_DELETION_TOTAL (34): + Analytic tracking total resource deletions. + RESOURCE_READ_TOTAL (35): + Analytic tracking total resource reads. + RESOURCE_WRITTEN_FAIL (36): + Analytic tracking failed resource writes. + RESOURCE_WRITTEN_SUCCESS (37): + Analytic tracking successful resource writes. + RESOURCE_WRITTEN_TOTAL (38): + Analytic tracking total resource writes. + UDM_DATA_PRESENCE_SUMMARY (39): + UDM data summary tracking unique values of + dimensions. + """ + + METRIC_NAME_UNSPECIFIED = 0 + NETWORK_BYTES_INBOUND = 1 + NETWORK_BYTES_OUTBOUND = 2 + NETWORK_BYTES_TOTAL = 3 + AUTH_ATTEMPTS_SUCCESS = 4 + AUTH_ATTEMPTS_FAIL = 5 + AUTH_ATTEMPTS_TOTAL = 6 + DNS_BYTES_OUTBOUND = 7 + NETWORK_FLOWS_INBOUND = 8 + NETWORK_FLOWS_OUTBOUND = 9 + NETWORK_FLOWS_TOTAL = 10 + DNS_QUERIES_SUCCESS = 11 + DNS_QUERIES_FAIL = 12 + DNS_QUERIES_TOTAL = 13 + FILE_EXECUTIONS_SUCCESS = 14 + FILE_EXECUTIONS_FAIL = 15 + FILE_EXECUTIONS_TOTAL = 16 + HTTP_QUERIES_SUCCESS = 17 + HTTP_QUERIES_FAIL = 18 + HTTP_QUERIES_TOTAL = 19 + WORKSPACE_EMAILS_SENT_TOTAL = 20 + WORKSPACE_TOTAL_DOWNLOAD_ACTIONS = 21 + WORKSPACE_TOTAL_CHANGE_ACTIONS = 22 + WORKSPACE_AUTH_ATTEMPTS_TOTAL = 23 + WORKSPACE_NETWORK_BYTES_OUTBOUND = 24 + WORKSPACE_NETWORK_BYTES_TOTAL = 25 + ALERT_EVENT_NAME_COUNT = 26 + RESOURCE_CREATION_TOTAL = 27 + RESOURCE_CREATION_SUCCESS = 28 + RESOURCE_READ_SUCCESS = 29 + RESOURCE_READ_FAIL = 30 + RESOURCE_DELETION_SUCCESS = 31 + RESOURCE_CREATION_FAIL = 32 + RESOURCE_DELETION_FAIL = 33 + RESOURCE_DELETION_TOTAL = 34 + RESOURCE_READ_TOTAL = 35 + RESOURCE_WRITTEN_FAIL = 36 + RESOURCE_WRITTEN_SUCCESS = 37 + RESOURCE_WRITTEN_TOTAL = 38 + UDM_DATA_PRESENCE_SUMMARY = 39 + + class Dimension(proto.Enum): + r"""Describes field used as the dimension when grouping data to + calculate the aggregate metric. + + Values: + DIMENSION_UNSPECIFIED (0): + Default + PRINCIPAL_DEVICE (1): + Principal Device + TARGET_USER (2): + Target User + TARGET_DEVICE (3): + Target Device + PRINCIPAL_USER (4): + Principal User + TARGET_IP (5): + Target IP + PRINCIPAL_FILE_HASH (6): + Principal File Hash + PRINCIPAL_COUNTRY (7): + Principal Country + SECURITY_CATEGORY (8): + Security Category + NETWORK_ASN (9): + Network ASN + CLIENT_CERTIFICATE_HASH (10): + Client Certificate Hash + DNS_QUERY_TYPE (11): + DNS Query Type + DNS_DOMAIN (12): + DNS Domain + HTTP_USER_AGENT (13): + HTTP User Agent + EVENT_TYPE (14): + Event Type + PRODUCT_NAME (15): + Product Name + PRODUCT_EVENT_TYPE (16): + Product Event Type + PARENT_FOLDER_PATH (17): + Parent Folder Path + TARGET_RESOURCE_NAME (18): + Target resource Name + PRINCIPAL_APPLICATION (19): + Principal Application. + TARGET_APPLICATION (20): + Target Application. + EMAIL_TO_ADDRESS (21): + Email To Address. + EMAIL_FROM_ADDRESS (22): + Email From Address. + MAIL_ID (23): + Mail Id. + PRINCIPAL_IP (24): + Principal IP. + SECURITY_ACTION (25): + Security Action. + SECURITY_RULE_ID (28): + Security Rule Id. + TARGET_NETWORK_ORGANIZATION_NAME (29): + Target Network Organization name. + PRINCIPAL_NETWORK_ORGANIZATION_NAME (30): + Principal Network Organization name. + PRINCIPAL_PROCESS_FILE_PATH (31): + Principal Process File Path. + PRINCIPAL_PROCESS_FILE_HASH (32): + Principal Process File SHA256 Hash. + SECURITY_RESULT_RULE_NAME (33): + Security Result rule name. + TARGET_RESOURCE_LABEL_KEY (34): + Target Resource label key. + VENDOR_NAME (35): + Vendor name. + TARGET_RESOURCE_TYPE (36): + Target Resource type. + TARGET_LOCATION_NAME (37): + Target Location name. + LOG_TYPE (38): + Log type. + TARGET_HOSTNAME (39): + Target Hostname. + """ + + DIMENSION_UNSPECIFIED = 0 + PRINCIPAL_DEVICE = 1 + TARGET_USER = 2 + TARGET_DEVICE = 3 + PRINCIPAL_USER = 4 + TARGET_IP = 5 + PRINCIPAL_FILE_HASH = 6 + PRINCIPAL_COUNTRY = 7 + SECURITY_CATEGORY = 8 + NETWORK_ASN = 9 + CLIENT_CERTIFICATE_HASH = 10 + DNS_QUERY_TYPE = 11 + DNS_DOMAIN = 12 + HTTP_USER_AGENT = 13 + EVENT_TYPE = 14 + PRODUCT_NAME = 15 + PRODUCT_EVENT_TYPE = 16 + PARENT_FOLDER_PATH = 17 + TARGET_RESOURCE_NAME = 18 + PRINCIPAL_APPLICATION = 19 + TARGET_APPLICATION = 20 + EMAIL_TO_ADDRESS = 21 + EMAIL_FROM_ADDRESS = 22 + MAIL_ID = 23 + PRINCIPAL_IP = 24 + SECURITY_ACTION = 25 + SECURITY_RULE_ID = 28 + TARGET_NETWORK_ORGANIZATION_NAME = 29 + PRINCIPAL_NETWORK_ORGANIZATION_NAME = 30 + PRINCIPAL_PROCESS_FILE_PATH = 31 + PRINCIPAL_PROCESS_FILE_HASH = 32 + SECURITY_RESULT_RULE_NAME = 33 + TARGET_RESOURCE_LABEL_KEY = 34 + VENDOR_NAME = 35 + TARGET_RESOURCE_TYPE = 36 + TARGET_LOCATION_NAME = 37 + LOG_TYPE = 38 + TARGET_HOSTNAME = 39 + + class Measure(proto.Message): + r"""Describes the precomputed measure. + + Attributes: + value (float): + Value of the aggregated measure. + aggregate_function (google.backstory.types.Metric.AggregateFunction): + Function used to calculate the aggregated + measure. + """ + + value: float = proto.Field( + proto.DOUBLE, + number=1, + ) + aggregate_function: "Metric.AggregateFunction" = proto.Field( + proto.ENUM, + number=2, + enum="Metric.AggregateFunction", + ) + + first_seen: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + last_seen: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + sum_measure: Measure = proto.Field( + proto.MESSAGE, + number=3, + message=Measure, + ) + total_events: int = proto.Field( + proto.INT64, + number=4, + ) + metric_name: MetricName = proto.Field( + proto.ENUM, + number=5, + enum=MetricName, + ) + dimensions: MutableSequence[Dimension] = proto.RepeatedField( + proto.ENUM, + number=6, + enum=Dimension, + ) + export_window: int = proto.Field( + proto.INT64, + number=7, + ) + display_name: str = proto.Field( + proto.STRING, + number=8, + ) + outcome_variables: MutableSequence[udm.FindingVariable] = proto.RepeatedField( + proto.MESSAGE, + number=9, + message=udm.FindingVariable, + ) + match_variables: MutableSequence[udm.FindingVariable] = proto.RepeatedField( + proto.MESSAGE, + number=10, + message=udm.FindingVariable, + ) + time_range: interval_pb2.Interval = proto.Field( + proto.MESSAGE, + number=11, + message=interval_pb2.Interval, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-backstory/google/backstory/types/entity_risk.py b/packages/google-backstory/google/backstory/types/entity_risk.py new file mode 100644 index 000000000000..e1970b0f78da --- /dev/null +++ b/packages/google-backstory/google/backstory/types/entity_risk.py @@ -0,0 +1,197 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import google.protobuf.duration_pb2 as duration_pb2 # type: ignore +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore +import google.type.interval_pb2 as interval_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.backstory", + manifest={ + "EntityRisk", + "RiskDelta", + }, +) + + +class EntityRisk(proto.Message): + r"""Stores information related to the risk score of an entity. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + risk_version (str): + Version of the risk score calculation + algorithm. + risk_window (google.type.interval_pb2.Interval): + Time window used when computing the risk + score for an entity, for example 24 hours or 7 + days. + DEPRECATED_risk_score (int): + Deprecated risk score. + risk_delta (google.backstory.types.RiskDelta): + Represents the change in risk score for an + entity between the end of the previous time + window and the end of the current time window. + + This field is a member of `oneof`_ ``_risk_delta``. + detections_count (int): + Number of detections that make up the risk + score within the time window. + first_detection_time (google.protobuf.timestamp_pb2.Timestamp): + Timestamp of the first detection within the + specified time window. This field is empty when + there are no detections. + last_detection_time (google.protobuf.timestamp_pb2.Timestamp): + Timestamp of the last detection within the + specified time window. This field is empty when + there are no detections. + risk_score (float): + Raw risk score for the entity. + normalized_risk_score (int): + Normalized risk score for the entity. This + value is between 0-1000. + risk_window_size (google.protobuf.duration_pb2.Duration): + Risk window duration for the entity. + raw_risk_delta (google.backstory.types.RiskDelta): + Represents the change in raw risk score for + an entity between the end of the previous time + window and the end of the current time window. + + This field is a member of `oneof`_ ``_raw_risk_delta``. + last_reset_time (google.protobuf.timestamp_pb2.Timestamp): + Timestamp for UEBA risk score reset based + deduplication. Used specifically for risk based + meta rules. + detail_uri (str): + Link to the Google Security Operations UI + with information about the entity risk score. If + the SecOps instance has multiple frontend paths + configured, this will be a relative path that + can be used to construct the full URL. + risk_window_has_new_detections (bool): + Whether there are new detections for the risk + window. + """ + + risk_version: str = proto.Field( + proto.STRING, + number=1, + ) + risk_window: interval_pb2.Interval = proto.Field( + proto.MESSAGE, + number=2, + message=interval_pb2.Interval, + ) + DEPRECATED_risk_score: int = proto.Field( + proto.INT32, + number=3, + ) + risk_delta: "RiskDelta" = proto.Field( + proto.MESSAGE, + number=4, + optional=True, + message="RiskDelta", + ) + detections_count: int = proto.Field( + proto.INT32, + number=5, + ) + first_detection_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=6, + message=timestamp_pb2.Timestamp, + ) + last_detection_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=7, + message=timestamp_pb2.Timestamp, + ) + risk_score: float = proto.Field( + proto.FLOAT, + number=8, + ) + normalized_risk_score: int = proto.Field( + proto.INT32, + number=9, + ) + risk_window_size: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=10, + message=duration_pb2.Duration, + ) + raw_risk_delta: "RiskDelta" = proto.Field( + proto.MESSAGE, + number=11, + optional=True, + message="RiskDelta", + ) + last_reset_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=12, + message=timestamp_pb2.Timestamp, + ) + detail_uri: str = proto.Field( + proto.STRING, + number=13, + ) + risk_window_has_new_detections: bool = proto.Field( + proto.BOOL, + number=14, + ) + + +class RiskDelta(proto.Message): + r"""Describes the difference in risk score between two points in + time. + + Attributes: + previous_range_end_time (google.protobuf.timestamp_pb2.Timestamp): + End time of the previous time window. + risk_score_delta (int): + Difference in the normalized risk score from + the previous recorded value. + previous_risk_score (int): + Risk score from previous risk window + risk_score_numeric_delta (int): + Numeric change between current and previous + risk score + """ + + previous_range_end_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + risk_score_delta: int = proto.Field( + proto.INT32, + number=2, + ) + previous_risk_score: int = proto.Field( + proto.INT32, + number=3, + ) + risk_score_numeric_delta: int = proto.Field( + proto.INT32, + number=4, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-backstory/google/backstory/types/id.py b/packages/google-backstory/google/backstory/types/id.py new file mode 100644 index 000000000000..961a8e5ed794 --- /dev/null +++ b/packages/google-backstory/google/backstory/types/id.py @@ -0,0 +1,100 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.backstory", + manifest={ + "Id", + }, +) + + +class Id(proto.Message): + r"""Identifier to identify a UDM object like a UDM event, Entity, + Collection. The full identifier for persistence is created by + setting the 32 most significant bits as the Id.Namespace enum + This is a convenience wrapper to define the id space enum values + and provide an easy interface for RPCs, most persistence use + cases should use a denormalized form. + + Attributes: + namespace (google.backstory.types.Id.Namespace): + Namespace the id belongs to. + id (bytes): + Full raw ID. + string_id (str): + Some ids are stored as strings that are not able to be + translated to bytes, so store these separately. Ex. + detection id of the form de_aaaaaaaa-aaaa... + """ + + class Namespace(proto.Enum): + r"""Extracted Namespace Component + + Values: + NORMALIZED_TELEMETRY (0): + Ingested and Normalized telemetry events + RAW_TELEMETRY (1): + Ingested Raw telemetry + RULE_DETECTIONS (2): + Chronicle Rules engine + UPPERCASE (3): + Uppercase + MACHINE_INTELLIGENCE (4): + DSML - Machine Intelligence + SECURITY_COMMAND_CENTER (5): + A normalized telemetry event from Google + Security Command Center. + UNSPECIFIED (6): + Unspecified Namespace + SOAR_ALERT (7): + An alert coming from other SIEMs via + Chronicle SOAR. + VIRUS_TOTAL (8): + VirusTotal. + """ + + NORMALIZED_TELEMETRY = 0 + RAW_TELEMETRY = 1 + RULE_DETECTIONS = 2 + UPPERCASE = 3 + MACHINE_INTELLIGENCE = 4 + SECURITY_COMMAND_CENTER = 5 + UNSPECIFIED = 6 + SOAR_ALERT = 7 + VIRUS_TOTAL = 8 + + namespace: Namespace = proto.Field( + proto.ENUM, + number=1, + enum=Namespace, + ) + id: bytes = proto.Field( + proto.BYTES, + number=2, + ) + string_id: str = proto.Field( + proto.STRING, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-backstory/google/backstory/types/udm.py b/packages/google-backstory/google/backstory/types/udm.py new file mode 100644 index 000000000000..b9f7adf64b80 --- /dev/null +++ b/packages/google-backstory/google/backstory/types/udm.py @@ -0,0 +1,11335 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import google.protobuf.duration_pb2 as duration_pb2 # type: ignore +import google.protobuf.struct_pb2 as struct_pb2 # type: ignore +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore +import google.type.interval_pb2 as interval_pb2 # type: ignore +import google.type.latlng_pb2 as latlng_pb2 # type: ignore +import proto # type: ignore + +from google.backstory.types import data_access +from google.backstory.types import entity_risk as gb_entity_risk +from google.backstory.types import id as gb_id + +__protobuf__ = proto.module( + package="google.backstory", + manifest={ + "Verdict", + "Reputation", + "Status", + "Priority", + "Reason", + "ThreatVerdict", + "UDM", + "Metadata", + "Attribute", + "Network", + "ProxyInfo", + "Extensions", + "Authentication", + "LinuxUtmp", + "WindowsEventLog", + "ResourceUsage", + "SystemEventDetails", + "OutlookMetadata", + "Srum", + "UserAssist", + "Vulnerabilities", + "Vulnerability", + "Ftp", + "Smtp", + "Email", + "Process", + "AnalyticsMetadata", + "FindingVariable", + "SecurityResult", + "PeFileMetadata", + "FileMetadata", + "File", + "NtfsFileMetadata", + "PrefetchFileMetadata", + "UsnJournal", + "AppCompatMetadata", + "FileMetadataPE", + "FileMetadataPeResourceInfo", + "SignatureInfo", + "FileMetadataSignatureInfo", + "SignerInfo", + "FileMetadataCodesign", + "X509", + "PDFInfo", + "StringToInt64MapEntry", + "FileMetadataSection", + "FileMetadataImports", + "ExifInfo", + "Prevalence", + "Dns", + "Dhcp", + "Certificate", + "Tls", + "Http", + "Browser", + "Hardware", + "PlatformSoftware", + "Software", + "Asset", + "User", + "TimeOff", + "Permission", + "Role", + "Group", + "Registry", + "WmiPersistenceItem", + "Location", + "ScheduledTask", + "WindowsScheduledTask", + "ScheduledCronTask", + "ScheduledAnacronTask", + "Volume", + "Service", + "Resource", + "Label", + "Cloud", + "Artifact", + "Tunnels", + "ArtifactClient", + "Favicon", + "DNSRecord", + "SSLCertificate", + "PopularityRank", + "Tracker", + "Url", + "Domain", + "Noun", + "Investigation", + "Tags", + "AttackDetails", + "BoolSequence", + "BytesSequence", + "DoubleSequence", + "Int64Sequence", + "Uint64Sequence", + "StringSequence", + "GroupedFields", + }, +) + + +class Verdict(proto.Enum): + r"""Categorization options for the validity of a finding (for + example, whether it reflects an actual security incident). + + Values: + VERDICT_UNSPECIFIED (0): + An unspecified verdict. + TRUE_POSITIVE (1): + A categorization of the finding as a "true + positive". + FALSE_POSITIVE (2): + A categorization of the finding as a "false + positive". + """ + + VERDICT_UNSPECIFIED = 0 + TRUE_POSITIVE = 1 + FALSE_POSITIVE = 2 + + +class Reputation(proto.Enum): + r"""Categorization options for the usefulness of a finding. + + Values: + REPUTATION_UNSPECIFIED (0): + An unspecified reputation. + USEFUL (1): + A categorization of the finding as useful. + NOT_USEFUL (2): + A categorization of the finding as not + useful. + """ + + REPUTATION_UNSPECIFIED = 0 + USEFUL = 1 + NOT_USEFUL = 2 + + +class Status(proto.Enum): + r"""Describes status of a finding. + + Values: + STATUS_UNSPECIFIED (0): + Unspecified finding status. + NEW (1): + New finding. + REVIEWED (2): + When a finding has feedback. + CLOSED (3): + When an analyst closes an finding. + OPEN (4): + Open. Used to indicate that a Case / Alert is + open. + """ + + STATUS_UNSPECIFIED = 0 + NEW = 1 + REVIEWED = 2 + CLOSED = 3 + OPEN = 4 + + +class Priority(proto.Enum): + r"""Priority that is assigned to a Case or Alert. + + Values: + PRIORITY_UNSPECIFIED (0): + Default priority level. + PRIORITY_INFO (100): + Informational priority. + PRIORITY_LOW (200): + Low priority. + PRIORITY_MEDIUM (300): + Medium priority. + PRIORITY_HIGH (400): + High priority. + PRIORITY_CRITICAL (500): + Critical priority. + """ + + PRIORITY_UNSPECIFIED = 0 + PRIORITY_INFO = 100 + PRIORITY_LOW = 200 + PRIORITY_MEDIUM = 300 + PRIORITY_HIGH = 400 + PRIORITY_CRITICAL = 500 + + +class Reason(proto.Enum): + r"""Reason for closing an Alert or Case in the SOAR product. + + Values: + REASON_UNSPECIFIED (0): + Default reason. + REASON_NOT_MALICIOUS (1): + Case or Alert not malicious. + REASON_MALICIOUS (2): + Case or Alert is malicious. + REASON_MAINTENANCE (3): + Case or Alert is under maintenance. + """ + + REASON_UNSPECIFIED = 0 + REASON_NOT_MALICIOUS = 1 + REASON_MALICIOUS = 2 + REASON_MAINTENANCE = 3 + + +class ThreatVerdict(proto.Enum): + r"""GCTI threat verdict levels. + + Values: + THREAT_VERDICT_UNSPECIFIED (0): + Unspecified threat verdict level. + UNDETECTED (1): + Undetected threat verdict level. + SUSPICIOUS (2): + Suspicious threat verdict level. + MALICIOUS (3): + Malicious threat verdict level. + """ + + THREAT_VERDICT_UNSPECIFIED = 0 + UNDETECTED = 1 + SUSPICIOUS = 2 + MALICIOUS = 3 + + +class UDM(proto.Message): + r"""A Unified Data Model event. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + metadata (google.backstory.types.Metadata): + Event metadata such as timestamp, source + product, etc. + additional (google.protobuf.struct_pb2.Struct): + Any important vendor-specific event data that + cannot be adequately represented within the + formal sections of the UDM model. + principal (google.backstory.types.Noun): + Represents the acting entity that originates + the activity described in the event. The + principal must include at least one machine + detail (hostname, MACs, IPs, port, + product-specific identifiers like an EDR asset + ID) or user detail (for example, username), and + optionally include process details. It must NOT + include any of the following fields: + + email, files, registry keys or values. + src (google.backstory.types.Noun): + Represents a source entity being acted upon + by the participant along with the device or + process context for the source object (the + machine where the source object resides). For + example, if user U copies file A on machine X to + file B on machine Y, both file A and machine X + would be specified in the src portion of the UDM + event. + target (google.backstory.types.Noun): + Represents a target entity being referenced + by the event or an object on the target entity. + For example, in a firewall connection from + device A to device B, A is described as the + principal and B is described as the target. For + a process injection by process C into target + process D, process C is described as the + principal and process D is described as the + target. + intermediary (MutableSequence[google.backstory.types.Noun]): + Represents details on one or more + intermediate entities processing activity + described in the event. This includes device + details about a proxy server or SMTP relay + server. If an active event (that has a principal + and possibly target) passes through any + intermediaries, they're added here. + Intermediaries can impact the overall action, + for example blocking or modifying an ongoing + request. A rule of thumb here is that + 'principal', 'target', and description of the + initial action should be the same regardless of + the intermediary or its action. A successful + network connection from A->B should look the + same in principal/target/intermediary as one + blocked by firewall C: principal: A, target: B + (intermediary: C). + observer (google.backstory.types.Noun): + Represents an observer entity (for example, a + packet sniffer or network-based vulnerability + scanner), which is not a direct intermediary, + but which observes and reports on the event in + question. + about (MutableSequence[google.backstory.types.Noun]): + Represents entities referenced by the event that are not + otherwise described in principal, src, target, intermediary + or observer. For example, it could be used to track email + file attachments, domains/URLs/IPs embedded within an email + body, and DLLs that are loaded during a PROCESS_LAUNCH + event. + security_result (MutableSequence[google.backstory.types.SecurityResult]): + A list of security results. + network (google.backstory.types.Network): + All network details go here, including + sub-messages with details on each protocol (for + example, DHCP, DNS, or HTTP). + extensions (google.backstory.types.Extensions): + All other first-class, event-specific + metadata goes in this message. Do not place + protocol metadata in Extensions; put it in + Network. + extracted (google.protobuf.struct_pb2.Struct): + Flattened fields extracted from the log. + grouped (google.backstory.types.GroupedFields): + Related UDM fields that are grouped together. + + This field is a member of `oneof`_ ``_grouped``. + """ + + metadata: "Metadata" = proto.Field( + proto.MESSAGE, + number=1, + message="Metadata", + ) + additional: struct_pb2.Struct = proto.Field( + proto.MESSAGE, + number=2, + message=struct_pb2.Struct, + ) + principal: "Noun" = proto.Field( + proto.MESSAGE, + number=3, + message="Noun", + ) + src: "Noun" = proto.Field( + proto.MESSAGE, + number=4, + message="Noun", + ) + target: "Noun" = proto.Field( + proto.MESSAGE, + number=5, + message="Noun", + ) + intermediary: MutableSequence["Noun"] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message="Noun", + ) + observer: "Noun" = proto.Field( + proto.MESSAGE, + number=7, + message="Noun", + ) + about: MutableSequence["Noun"] = proto.RepeatedField( + proto.MESSAGE, + number=8, + message="Noun", + ) + security_result: MutableSequence["SecurityResult"] = proto.RepeatedField( + proto.MESSAGE, + number=9, + message="SecurityResult", + ) + network: "Network" = proto.Field( + proto.MESSAGE, + number=10, + message="Network", + ) + extensions: "Extensions" = proto.Field( + proto.MESSAGE, + number=11, + message="Extensions", + ) + extracted: struct_pb2.Struct = proto.Field( + proto.MESSAGE, + number=12, + message=struct_pb2.Struct, + ) + grouped: "GroupedFields" = proto.Field( + proto.MESSAGE, + number=13, + optional=True, + message="GroupedFields", + ) + + +class Metadata(proto.Message): + r"""General information associated with a UDM event. + + Attributes: + id (bytes): + ID of the UDM event. Can be used for raw and + normalized event retrieval. + product_log_id (str): + A vendor-specific event identifier to + uniquely identify the event (e.g. a GUID). + event_timestamp (google.protobuf.timestamp_pb2.Timestamp): + The GMT timestamp when the event was + generated. + event_timestamp_attributes (MutableSequence[google.backstory.types.Metadata.EventTimestampAttribute]): + Attributes associated with event_timestamp. This field is + used to distinguish between different types of timestamps + that can be used to represent the event_timestamp. + collected_timestamp (google.protobuf.timestamp_pb2.Timestamp): + The GMT timestamp when the event was + collected by the vendor's local collection + infrastructure. + ingested_timestamp (google.protobuf.timestamp_pb2.Timestamp): + The GMT timestamp when the event was ingested + (received) by Chronicle. + event_type (google.backstory.types.Metadata.EventType): + The event type. + If an event has multiple possible types, this + specifies the most specific type. + vendor_name (str): + The name of the product vendor. + product_name (str): + The name of the product. + product_version (str): + The version of the product. + product_event_type (str): + A short, descriptive, human-readable, product-specific event + name or type (e.g. "Scanned X", "User account created", + "process_start"). + product_deployment_id (str): + The deployment identifier assigned by the + vendor for a product deployment. + description (str): + A human-readable unparsable description of + the event. + url_back_to_product (str): + A URL that takes the user to the source + product console for this event. + ingestion_labels (MutableSequence[google.backstory.types.Label]): + User-configured ingestion metadata labels. + tags (google.backstory.types.Tags): + Tags added by Chronicle after an event is + parsed. It is an error to populate this field + from within a parser. + enrichment_state (google.backstory.types.Metadata.EnrichmentState): + The enrichment state. + log_type (str): + The string value of log type. + base_labels (google.backstory.types.DataAccessLabels): + Data access labels on the base event. + enrichment_labels (google.backstory.types.DataAccessLabels): + Data access labels from all the contextual + events used to enrich the base event. + structured_fields (google.protobuf.struct_pb2.Struct): + Flattened fields extracted from the log. + parser_version (str): + The version of the parser that generated this + UDM event. + """ + + class EventTimestampAttribute(proto.Enum): + r"""Enum representing the type of timestamp that the event_timestamp + field represents. + + Values: + EVENT_TIMESTAMP_ATTRIBUTE_UNSPECIFIED (0): + Default event timestamp attribute. + FILE_LAST_ACCESS_TIME (1): + Deprecated. Use LAST_ACCESSED instead. + FILE_LAST_MODIFIED_TIME (2): + Deprecated. Use LAST_MODIFIED instead. + FILE_METADATA_LAST_CHANGE_TIME (3): + Deprecated. Use METADATA_LAST_CHANGED instead. + FILE_CREATION_TIME (4): + Deprecated. Use CREATED instead. + COLLECTED_TIME (5): + Deprecated. Use COLLECTED instead. + COLLECTED (6): + The time when the event was collected by the + vendor's local collection infrastructure. + ACCESSED (7): + The time when the file was accessed. + CHANGED (8): + The time when the file was changed. + CREATED (9): + The time when the file was first created. + FILE_NAME_ACCESSED (10): + The time when the file name was accessed. + FILE_NAME_CHANGED (11): + The time when the file name was changed. + FILE_NAME_CREATED (12): + The time when the file name was created. + FILE_NAME_LAST_ACCESSED (13): + The time when the file name was last + accessed. + FILE_NAME_LAST_MODIFIED (14): + The time when the file name was last + modified. + FILE_NAME_METADATA_LAST_CHANGED (15): + The time when the file name metadata was last + changed. + FILE_NAME_MODIFIED (16): + The time when the file name was modified. + LAST_ACCESSED (17): + The time when the file was last accessed. + LAST_MODIFIED (18): + The time when the file was last modified. + METADATA_LAST_CHANGED (19): + The time when the file metadata was last + changed. + MODIFIED (20): + The time when the file was modified. + ADDED (21): + Added Timestamp. + BACKED_UP (22): + Backed Up Timestamp. + LAST_CONNECTED (23): + Last Connected timestamp. + DELETED (24): + Deleted Timestamp. + ENDED (25): + Ended Timestamp. + EXITED (26): + Exited Timestamp. + EXPIRED (27): + Expired Timestamp. + FIRST_ACCESSED (28): + First Accessed Timestamp. + APPEARED (29): + Appeared Timestamp. + INSTALLED (30): + Installed Timestamp. + LAST_ACTIVE (31): + Last Active Timestamp. + LAST_LOGGED_IN (32): + Last Login Timestamp. + LAST_LOGIN_ATTEMPT (33): + Last Login Attempt Timestamp. + LAST_PASSWORD_SET (34): + Last Password Set Timestamp. + LAST_PRINTED (35): + Last Printed Timestamp. + LAST_RESUMED (36): + Last Resumed Timestamp. + LAST_EXECUTED (37): + Last Executed Timestamp. + LAST_SEEN (38): + Last Seen Timestamp. + LAST_SHUTDOWN (39): + Last Shutdown Timestamp. + LAST_UPDATED (40): + Last Updated Timestamp. + LAST_USED (41): + Last Used Timestamp. + LAST_VISITED (42): + Last Visited Timestamp. + LINKED (43): + Linked Timestamp. + METADATA_MODIFIED (44): + Metadata Modified Timestamp. + CONTENT_MODIFIED (45): + Modified Timestamp. + PURCHASED (46): + Purchased Timestamp. + RECORDED (47): + Recorded Timestamp. + REQUEST_RECEIVED (48): + Request Received Timestamp. + RESPONSE_SENT (49): + Response Sent Timestamp. + SCHEDULED_TO_END (50): + Scheduled to End Timestamp. + SCHEDULED_TO_START (51): + Scheduled to Start Timestamp. + SENT (52): + Sent Timestamp. + STARTED (53): + Started Timestamp. + UPDATED (54): + Updated Timestamp. + VALIDATED (55): + Validated Timestamp. + MOST_RECENT_RUN (56): + Most Recent Run Timestamp. + NEXT_RUN (57): + Next Run Timestamp. + VISITED (58): + Visited Timestamp. + TARGET_CREATED (59): + Target Created Timestamp. + VOLUME_CREATED (60): + Volume Created Timestamp. + POST_CHECKED (61): + Post Checked Timestamp. + SYNCHRONIZED (62): + Synchronized Timestamp. + ITEM_CREATED (63): + Item Created Timestamp. + ITEM_MODIFIED (64): + Item Modified Timestamp. + DOCUMENT_LAST_SAVED (65): + Document Last Saved Timestamp. + LAST_REGISTERED (66): + Last Registered Timestamp. + LAUNCHED (67): + Launched Timestamp. + FIRST_VISITED (68): + First Visited Timestamp. + FIRST_SEEN (69): + First Seen Timestamp. + DOWNLOADED (70): + Downloaded Timestamp. + """ + + EVENT_TIMESTAMP_ATTRIBUTE_UNSPECIFIED = 0 + FILE_LAST_ACCESS_TIME = 1 + FILE_LAST_MODIFIED_TIME = 2 + FILE_METADATA_LAST_CHANGE_TIME = 3 + FILE_CREATION_TIME = 4 + COLLECTED_TIME = 5 + COLLECTED = 6 + ACCESSED = 7 + CHANGED = 8 + CREATED = 9 + FILE_NAME_ACCESSED = 10 + FILE_NAME_CHANGED = 11 + FILE_NAME_CREATED = 12 + FILE_NAME_LAST_ACCESSED = 13 + FILE_NAME_LAST_MODIFIED = 14 + FILE_NAME_METADATA_LAST_CHANGED = 15 + FILE_NAME_MODIFIED = 16 + LAST_ACCESSED = 17 + LAST_MODIFIED = 18 + METADATA_LAST_CHANGED = 19 + MODIFIED = 20 + ADDED = 21 + BACKED_UP = 22 + LAST_CONNECTED = 23 + DELETED = 24 + ENDED = 25 + EXITED = 26 + EXPIRED = 27 + FIRST_ACCESSED = 28 + APPEARED = 29 + INSTALLED = 30 + LAST_ACTIVE = 31 + LAST_LOGGED_IN = 32 + LAST_LOGIN_ATTEMPT = 33 + LAST_PASSWORD_SET = 34 + LAST_PRINTED = 35 + LAST_RESUMED = 36 + LAST_EXECUTED = 37 + LAST_SEEN = 38 + LAST_SHUTDOWN = 39 + LAST_UPDATED = 40 + LAST_USED = 41 + LAST_VISITED = 42 + LINKED = 43 + METADATA_MODIFIED = 44 + CONTENT_MODIFIED = 45 + PURCHASED = 46 + RECORDED = 47 + REQUEST_RECEIVED = 48 + RESPONSE_SENT = 49 + SCHEDULED_TO_END = 50 + SCHEDULED_TO_START = 51 + SENT = 52 + STARTED = 53 + UPDATED = 54 + VALIDATED = 55 + MOST_RECENT_RUN = 56 + NEXT_RUN = 57 + VISITED = 58 + TARGET_CREATED = 59 + VOLUME_CREATED = 60 + POST_CHECKED = 61 + SYNCHRONIZED = 62 + ITEM_CREATED = 63 + ITEM_MODIFIED = 64 + DOCUMENT_LAST_SAVED = 65 + LAST_REGISTERED = 66 + LAUNCHED = 67 + FIRST_VISITED = 68 + FIRST_SEEN = 69 + DOWNLOADED = 70 + + class EventType(proto.Enum): + r"""An event type. Choose event type not based on the product that + generated the event but the one that logged the event itself. So, + for example, an antivirus (AV) scanning email on a client would + generate an SMTP_PROXY event, not an AV event. A DLP device scanning + a web upload would generate an HTTP_PROXY event and not a DLP or + process activity event. Note: In the case of a HTTP_PROXY event, you + might also include process details if this occurred on an endpoint. + That would be optional, but there are a certain set of required + fields and banned fields due to its status as an HTTP_PROXY event. + + Values: + EVENTTYPE_UNSPECIFIED (0): + Default event type + PROCESS_UNCATEGORIZED (10000): + Activity related to a process which does not + match any other event types. + PROCESS_LAUNCH (10001): + Process launch. + PROCESS_INJECTION (10002): + Process injecting into another process. + PROCESS_PRIVILEGE_ESCALATION (10003): + Process privilege escalation. + PROCESS_TERMINATION (10004): + Process termination. + PROCESS_OPEN (10005): + Process being opened. + PROCESS_MODULE_LOAD (10006): + Process loading a module. + REGISTRY_UNCATEGORIZED (11000): + Registry event which does not match any of + the other event types. + REGISTRY_CREATION (11001): + Registry creation. + REGISTRY_MODIFICATION (11002): + Registry modification. + REGISTRY_DELETION (11003): + Registry deletion. + SETTING_UNCATEGORIZED (12000): + Settings-related event which does not match + any of the other event types. + SETTING_CREATION (12001): + Setting creation. + SETTING_MODIFICATION (12002): + Setting modification. + SETTING_DELETION (12003): + Setting deletion. + MUTEX_UNCATEGORIZED (13000): + Any mutex event other than creation. + MUTEX_CREATION (13001): + Mutex creation. + FILE_UNCATEGORIZED (14000): + File event which does not match any of the + other event types. + FILE_CREATION (14001): + File created. + FILE_DELETION (14002): + File deleted. + FILE_MODIFICATION (14003): + File modified. + FILE_READ (14004): + File read. + FILE_COPY (14005): + File copied. + Used for file copies, for example, to a thumb + drive. + FILE_OPEN (14006): + File opened. + FILE_MOVE (14007): + File moved or renamed. + FILE_SYNC (14008): + File synced (for example, Google Drive, + Dropbox, backup). + USER_UNCATEGORIZED (15000): + User activity which does not match any of the + other event types. + USER_LOGIN (15001): + User login. + USER_LOGOUT (15002): + User logout. + USER_CREATION (15003): + User creation. + USER_CHANGE_PASSWORD (15004): + User password change event. + USER_CHANGE_PERMISSIONS (15005): + Change in user permissions. + USER_STATS (15006): + Deprecated. Used to update user info for an + LDAP dump. + USER_BADGE_IN (15007): + User physically badging into a location. + USER_DELETION (15008): + User deletion. + USER_RESOURCE_CREATION (15009): + User creating a virtual resource. This is equivalent to + RESOURCE_CREATION. + USER_RESOURCE_UPDATE_CONTENT (15010): + User updating content of a virtual resource. This is + equivalent to RESOURCE_WRITTEN. + USER_RESOURCE_UPDATE_PERMISSIONS (15011): + User updating permissions of a virtual resource. This is + equivalent to RESOURCE_PERMISSIONS_CHANGE. + USER_COMMUNICATION (15012): + User initiating communication through a + medium (for example, video). + USER_RESOURCE_ACCESS (15013): + User accessing a virtual resource. This is equivalent to + RESOURCE_READ. + USER_RESOURCE_DELETION (15014): + User deleting a virtual resource. This is equivalent to + RESOURCE_DELETION. + GROUP_UNCATEGORIZED (23000): + A group activity that does not fall into one + of the other event types. + GROUP_CREATION (23001): + A group creation. + GROUP_DELETION (23002): + A group deletion. + GROUP_MODIFICATION (23003): + A group modification. + EMAIL_UNCATEGORIZED (19000): + Email messages + EMAIL_TRANSACTION (19001): + An email transaction. + EMAIL_URL_CLICK (19002): + Deprecated: use NETWORK_HTTP instead. An email URL click + event. + NETWORK_UNCATEGORIZED (16000): + A network event that does not fit into one of + the other event types. + NETWORK_FLOW (16001): + Aggregated flow stats like netflow. + NETWORK_CONNECTION (16002): + Network connection details like from a FW. + NETWORK_FTP (16003): + FTP telemetry. + NETWORK_DHCP (16004): + DHCP payload. + NETWORK_DNS (16005): + DNS payload. + NETWORK_HTTP (16006): + HTTP telemetry. + NETWORK_SMTP (16007): + SMTP telemetry. + STATUS_UNCATEGORIZED (17000): + A status message that does not fit into one + of the other event types. + STATUS_HEARTBEAT (17001): + Heartbeat indicating product is alive. + STATUS_STARTUP (17002): + An agent startup. + STATUS_SHUTDOWN (17003): + An agent shutdown. + STATUS_UPDATE (17004): + A software or fingerprint update. + SCAN_UNCATEGORIZED (18000): + Scan item that does not fit into one of the + other event types. + SCAN_FILE (18001): + A file scan. + SCAN_PROCESS_BEHAVIORS (18002): + Scan process behaviors. Please use SCAN_PROCESS instead. + SCAN_PROCESS (18003): + Scan process. + SCAN_HOST (18004): + Scan results from scanning an entire host + device for threats/sensitive documents. + SCAN_VULN_HOST (18005): + Vulnerability scan logs about host + vulnerabilities (e.g., out of date software) and + network vulnerabilities (e.g., unprotected + service detected via a network scan). + SCAN_VULN_NETWORK (18006): + Vulnerability scan logs about network + vulnerabilities. + SCAN_NETWORK (18007): + Scan network for suspicious activity + SCHEDULED_TASK_UNCATEGORIZED (20000): + Scheduled task event that does not fall into + one of the other event types. + SCHEDULED_TASK_CREATION (20001): + Scheduled task creation. + SCHEDULED_TASK_DELETION (20002): + Scheduled task deletion. + SCHEDULED_TASK_ENABLE (20003): + Scheduled task being enabled. + SCHEDULED_TASK_DISABLE (20004): + Scheduled task being disabled. + SCHEDULED_TASK_MODIFICATION (20005): + Scheduled task being modified. + SYSTEM_AUDIT_LOG_UNCATEGORIZED (21000): + A system audit log event that is not a wipe. + SYSTEM_AUDIT_LOG_WIPE (21001): + A system audit log wipe. + SERVICE_UNSPECIFIED (22000): + Service event that does not fit into one of + the other event types. + SERVICE_CREATION (22001): + A service creation. + SERVICE_DELETION (22002): + A service deletion. + SERVICE_START (22003): + A service start. + SERVICE_STOP (22004): + A service stop. + SERVICE_MODIFICATION (22005): + A service modification. + GENERIC_EVENT (100000): + Operating system events that are not + described by any of the other event types. Might + include uncategorized Microsoft Windows event + logs. + RESOURCE_CREATION (1): + The resource was created/provisioned. This is equivalent to + USER_RESOURCE_CREATION. + RESOURCE_DELETION (2): + The resource was deleted/deprovisioned. This is equivalent + to USER_RESOURCE_DELETION. + RESOURCE_PERMISSIONS_CHANGE (3): + The resource had it's permissions or ACLs updated. This is + equivalent to USER_RESOURCE_UPDATE_PERMISSIONS. + RESOURCE_READ (4): + The resource was read. This is equivalent to + USER_RESOURCE_ACCESS. + RESOURCE_WRITTEN (5): + The resource was written to. This is equivalent to + USER_RESOURCE_UPDATE_CONTENT. + DEVICE_FIRMWARE_UPDATE (25000): + Firmware update. + DEVICE_CONFIG_UPDATE (25001): + Configuration update. + DEVICE_PROGRAM_UPLOAD (25002): + A program or application uploaded to a + device. + DEVICE_PROGRAM_DOWNLOAD (25003): + A program or application downloaded to a + device. + ANALYST_UPDATE_VERDICT (24000): + Analyst update about the Verdict (such as + true positive, false positive, or disregard) of + a finding. + ANALYST_UPDATE_REPUTATION (24001): + Analyst update about the Reputation (such as + useful or not useful) of a finding. + ANALYST_UPDATE_SEVERITY_SCORE (24002): + Analyst update about the Severity score + (0-100) of a finding. + ANALYST_UPDATE_STATUS (24007): + Analyst update about the finding status. + ANALYST_ADD_COMMENT (24008): + Analyst addition of a comment for a finding. + ANALYST_UPDATE_PRIORITY (24009): + Analyst update about the priority (such as + low, medium, or high) for a finding. + ANALYST_UPDATE_ROOT_CAUSE (24010): + Analyst update about the root cause for a + finding. + ANALYST_UPDATE_REASON (24011): + Analyst update about the reason (such as + malicious or not malicious) for a finding. + ANALYST_UPDATE_RISK_SCORE (24012): + Analyst update about the risk score (0-100) + of a finding. + ENTITY_RISK_CHANGE (26000): + An update to an entity risk score. This event + type is restricted to events published by Google + Securit Operations Risk Analytics. + TRIAGE_AGENT_UPDATE_INVESTIGATION (27000): + Triage Agent has investigated the finding. + """ + + EVENTTYPE_UNSPECIFIED = 0 + PROCESS_UNCATEGORIZED = 10000 + PROCESS_LAUNCH = 10001 + PROCESS_INJECTION = 10002 + PROCESS_PRIVILEGE_ESCALATION = 10003 + PROCESS_TERMINATION = 10004 + PROCESS_OPEN = 10005 + PROCESS_MODULE_LOAD = 10006 + REGISTRY_UNCATEGORIZED = 11000 + REGISTRY_CREATION = 11001 + REGISTRY_MODIFICATION = 11002 + REGISTRY_DELETION = 11003 + SETTING_UNCATEGORIZED = 12000 + SETTING_CREATION = 12001 + SETTING_MODIFICATION = 12002 + SETTING_DELETION = 12003 + MUTEX_UNCATEGORIZED = 13000 + MUTEX_CREATION = 13001 + FILE_UNCATEGORIZED = 14000 + FILE_CREATION = 14001 + FILE_DELETION = 14002 + FILE_MODIFICATION = 14003 + FILE_READ = 14004 + FILE_COPY = 14005 + FILE_OPEN = 14006 + FILE_MOVE = 14007 + FILE_SYNC = 14008 + USER_UNCATEGORIZED = 15000 + USER_LOGIN = 15001 + USER_LOGOUT = 15002 + USER_CREATION = 15003 + USER_CHANGE_PASSWORD = 15004 + USER_CHANGE_PERMISSIONS = 15005 + USER_STATS = 15006 + USER_BADGE_IN = 15007 + USER_DELETION = 15008 + USER_RESOURCE_CREATION = 15009 + USER_RESOURCE_UPDATE_CONTENT = 15010 + USER_RESOURCE_UPDATE_PERMISSIONS = 15011 + USER_COMMUNICATION = 15012 + USER_RESOURCE_ACCESS = 15013 + USER_RESOURCE_DELETION = 15014 + GROUP_UNCATEGORIZED = 23000 + GROUP_CREATION = 23001 + GROUP_DELETION = 23002 + GROUP_MODIFICATION = 23003 + EMAIL_UNCATEGORIZED = 19000 + EMAIL_TRANSACTION = 19001 + EMAIL_URL_CLICK = 19002 + NETWORK_UNCATEGORIZED = 16000 + NETWORK_FLOW = 16001 + NETWORK_CONNECTION = 16002 + NETWORK_FTP = 16003 + NETWORK_DHCP = 16004 + NETWORK_DNS = 16005 + NETWORK_HTTP = 16006 + NETWORK_SMTP = 16007 + STATUS_UNCATEGORIZED = 17000 + STATUS_HEARTBEAT = 17001 + STATUS_STARTUP = 17002 + STATUS_SHUTDOWN = 17003 + STATUS_UPDATE = 17004 + SCAN_UNCATEGORIZED = 18000 + SCAN_FILE = 18001 + SCAN_PROCESS_BEHAVIORS = 18002 + SCAN_PROCESS = 18003 + SCAN_HOST = 18004 + SCAN_VULN_HOST = 18005 + SCAN_VULN_NETWORK = 18006 + SCAN_NETWORK = 18007 + SCHEDULED_TASK_UNCATEGORIZED = 20000 + SCHEDULED_TASK_CREATION = 20001 + SCHEDULED_TASK_DELETION = 20002 + SCHEDULED_TASK_ENABLE = 20003 + SCHEDULED_TASK_DISABLE = 20004 + SCHEDULED_TASK_MODIFICATION = 20005 + SYSTEM_AUDIT_LOG_UNCATEGORIZED = 21000 + SYSTEM_AUDIT_LOG_WIPE = 21001 + SERVICE_UNSPECIFIED = 22000 + SERVICE_CREATION = 22001 + SERVICE_DELETION = 22002 + SERVICE_START = 22003 + SERVICE_STOP = 22004 + SERVICE_MODIFICATION = 22005 + GENERIC_EVENT = 100000 + RESOURCE_CREATION = 1 + RESOURCE_DELETION = 2 + RESOURCE_PERMISSIONS_CHANGE = 3 + RESOURCE_READ = 4 + RESOURCE_WRITTEN = 5 + DEVICE_FIRMWARE_UPDATE = 25000 + DEVICE_CONFIG_UPDATE = 25001 + DEVICE_PROGRAM_UPLOAD = 25002 + DEVICE_PROGRAM_DOWNLOAD = 25003 + ANALYST_UPDATE_VERDICT = 24000 + ANALYST_UPDATE_REPUTATION = 24001 + ANALYST_UPDATE_SEVERITY_SCORE = 24002 + ANALYST_UPDATE_STATUS = 24007 + ANALYST_ADD_COMMENT = 24008 + ANALYST_UPDATE_PRIORITY = 24009 + ANALYST_UPDATE_ROOT_CAUSE = 24010 + ANALYST_UPDATE_REASON = 24011 + ANALYST_UPDATE_RISK_SCORE = 24012 + ENTITY_RISK_CHANGE = 26000 + TRIAGE_AGENT_UPDATE_INVESTIGATION = 27000 + + class EnrichmentState(proto.Enum): + r"""An enrichment state. + + Values: + ENRICHMENT_STATE_UNSPECIFIED (0): + Unspecified. + ENRICHED (1): + The event has been enriched by Chronicle. + UNENRICHED (2): + The event has not been enriched by Chronicle. + """ + + ENRICHMENT_STATE_UNSPECIFIED = 0 + ENRICHED = 1 + UNENRICHED = 2 + + id: bytes = proto.Field( + proto.BYTES, + number=15, + ) + product_log_id: str = proto.Field( + proto.STRING, + number=1, + ) + event_timestamp: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + event_timestamp_attributes: MutableSequence[EventTimestampAttribute] = ( + proto.RepeatedField( + proto.ENUM, + number=21, + enum=EventTimestampAttribute, + ) + ) + collected_timestamp: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + ingested_timestamp: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=11, + message=timestamp_pb2.Timestamp, + ) + event_type: EventType = proto.Field( + proto.ENUM, + number=4, + enum=EventType, + ) + vendor_name: str = proto.Field( + proto.STRING, + number=5, + ) + product_name: str = proto.Field( + proto.STRING, + number=6, + ) + product_version: str = proto.Field( + proto.STRING, + number=7, + ) + product_event_type: str = proto.Field( + proto.STRING, + number=8, + ) + product_deployment_id: str = proto.Field( + proto.STRING, + number=14, + ) + description: str = proto.Field( + proto.STRING, + number=9, + ) + url_back_to_product: str = proto.Field( + proto.STRING, + number=10, + ) + ingestion_labels: MutableSequence["Label"] = proto.RepeatedField( + proto.MESSAGE, + number=12, + message="Label", + ) + tags: "Tags" = proto.Field( + proto.MESSAGE, + number=13, + message="Tags", + ) + enrichment_state: EnrichmentState = proto.Field( + proto.ENUM, + number=16, + enum=EnrichmentState, + ) + log_type: str = proto.Field( + proto.STRING, + number=17, + ) + base_labels: data_access.DataAccessLabels = proto.Field( + proto.MESSAGE, + number=18, + message=data_access.DataAccessLabels, + ) + enrichment_labels: data_access.DataAccessLabels = proto.Field( + proto.MESSAGE, + number=19, + message=data_access.DataAccessLabels, + ) + structured_fields: struct_pb2.Struct = proto.Field( + proto.MESSAGE, + number=20, + message=struct_pb2.Struct, + ) + parser_version: str = proto.Field( + proto.STRING, + number=22, + ) + + +class Attribute(proto.Message): + r"""Attribute is a container for generic entity attributes + including common attributes across core entities (such as, user + or asset). For example, Cloud is a generic entity attribute + since it can apply to an asset (for example, a VM) or a user + (for example, an identity service account). + + Attributes: + cloud (google.backstory.types.Cloud): + Cloud metadata attributes such as project ID, + account ID, or organizational hierarchy. + labels (MutableSequence[google.backstory.types.Label]): + Set of labels for the entity. Should only be + used for product labels (for example, Google + Cloud resource labels or Azure AD sensitivity + labels. Should not be used for arbitrary + key-value mappings. + permissions (MutableSequence[google.backstory.types.Permission]): + System permissions for IAM entity + (human principal, service account, group). + roles (MutableSequence[google.backstory.types.Role]): + System IAM roles to be assumed by resources + to use the role's permissions for access + control. + creation_time (google.protobuf.timestamp_pb2.Timestamp): + Time the resource or entity was created or + provisioned. + last_update_time (google.protobuf.timestamp_pb2.Timestamp): + Time the resource or entity was last updated. + """ + + cloud: "Cloud" = proto.Field( + proto.MESSAGE, + number=1, + message="Cloud", + ) + labels: MutableSequence["Label"] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="Label", + ) + permissions: MutableSequence["Permission"] = proto.RepeatedField( + proto.MESSAGE, + number=705, + message="Permission", + ) + roles: MutableSequence["Role"] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message="Role", + ) + creation_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=4, + message=timestamp_pb2.Timestamp, + ) + last_update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + + +class Network(proto.Message): + r"""A network event. + + Attributes: + sent_bytes (int): + The number of bytes sent. + received_bytes (int): + The number of bytes received. + total_bytes (int): + The number of total bytes. + sent_packets (int): + The number of packets sent. + received_packets (int): + The number of packets received. + session_duration (google.protobuf.duration_pb2.Duration): + The duration of the session as the number of seconds and + nanoseconds. For seconds, network.session_duration.seconds, + the type is a 64-bit integer. For nanoseconds, + network.session_duration.nanos, the type is a 32-bit + integer. + session_id (str): + The ID of the network session. + parent_session_id (str): + The ID of the parent network session. + application_protocol_version (str): + The version of the application protocol. e.g. + "1.1, 2.0". + community_id (str): + Community ID network flow value. + direction (google.backstory.types.Network.Direction): + The direction of network traffic. + ip_protocol (google.backstory.types.Network.IpProtocol): + The IP protocol. + ipv6 (bool): + True if IPv6 is used. + application_protocol (google.backstory.types.Network.ApplicationProtocol): + The application protocol. + ftp (google.backstory.types.Ftp): + FTP info. + email (google.backstory.types.Email): + Email info for the sender/recipient. + dns (google.backstory.types.Dns): + DNS info. + dhcp (google.backstory.types.Dhcp): + DHCP info. + http (google.backstory.types.Http): + HTTP info. + tls (google.backstory.types.Tls): + TLS info. + smtp (google.backstory.types.Smtp): + SMTP info. + Store fields specific to SMTP not covered by + Email. + asn (str): + Autonomous system number. + dns_domain (str): + DNS domain name. + carrier_name (str): + Carrier identification. + organization_name (str): + Organization name (e.g Google). + ip_subnet_range (str): + Associated human-readable IP subnet range + (e.g. 10.1.2.0/24). + is_proxy (bool): + Whether the IP address is a known proxy. + proxy_info (google.backstory.types.ProxyInfo): + Proxy information. Only set if is_proxy is true. + connection_state (google.backstory.types.Network.ConnectionState): + The state of the network connection. + """ + + class Direction(proto.Enum): + r"""A network traffic direction. + + Values: + UNKNOWN_DIRECTION (0): + The default direction. + INBOUND (1): + An inbound request. + OUTBOUND (2): + An outbound request. + BROADCAST (3): + A broadcast. + """ + + UNKNOWN_DIRECTION = 0 + INBOUND = 1 + OUTBOUND = 2 + BROADCAST = 3 + + class IpProtocol(proto.Enum): + r"""An IP protocol. + + Values: + UNKNOWN_IP_PROTOCOL (0): + The default protocol. + ICMP (1): + ICMP. + IGMP (2): + IGMP + TCP (6): + TCP. + UDP (17): + UDP. + IP6IN4 (41): + IPv6 Encapsulation + GRE (47): + Generic Routing Encapsulation + ESP (50): + Encapsulating Security Payload + ICMP6 (58): + ICMPv6 + EIGRP (88): + Enhanced Interior Gateway Routing + ETHERIP (97): + Ethernet-within-IP Encapsulation + PIM (103): + Protocol Independent Multicast + VRRP (112): + Virtual Router Redundancy Protocol + SCTP (132): + Stream Control Transmission Protocol + """ + + UNKNOWN_IP_PROTOCOL = 0 + ICMP = 1 + IGMP = 2 + TCP = 6 + UDP = 17 + IP6IN4 = 41 + GRE = 47 + ESP = 50 + ICMP6 = 58 + EIGRP = 88 + ETHERIP = 97 + PIM = 103 + VRRP = 112 + SCTP = 132 + + class ApplicationProtocol(proto.Enum): + r"""A network application protocol. + + Values: + UNKNOWN_APPLICATION_PROTOCOL (0): + The default application protocol. + AFP (1): + Apple Filing Protocol. + APPC (2): + Advanced Program-to-Program Communication. + AMQP (3): + Advanced Message Queuing Protocol. + ATOM (4): + Publishing Protocol. + BEEP (5): + Block Extensible Exchange Protocol. + BITCOIN (6): + Crypto currency protocol. + BIT_TORRENT (7): + Peer-to-peer file sharing. + CFDP (8): + Coherent File Distribution Protocol. + CIP (67): + Common Industrial Protocol. + COAP (9): + Constrained Application Protocol. + COTP (68): + Connection Oriented Transport Protocol. + DCERPC (66): + DCE/RPC. + DDS (10): + Data Distribution Service. + DEVICE_NET (11): + Automation industry protocol. + DHCP (4000): + DHCP. + DICOM (69): + Digital Imaging and Communications in + Medicine Protocol. + DNP3 (70): + Distributed Network Protocol 3 (DNP3) + DNS (3000): + DNS. + E_DONKEY (12): + Classic file sharing protocol. + ENRP (13): + Endpoint Handlespace Redundancy Protocol. + FAST_TRACK (14): + Filesharing peer-to-peer protocol. + FINGER (15): + User Information Protocol. + FREENET (16): + Censorship resistant peer-to-peer network. + FTAM (17): + File Transfer Access and Management. + GOOSE (71): + GOOSE Protocol. + GOPHER (18): + Gopher protocol. + GRPC (77): + gRPC Remote Procedure Call. + HL7 (19): + Health Level Seven. + H323 (20): + Packet-based multimedia communications + system. + HTTP (2000): + HTTP. + HTTPS (2001): + HTTPS. + IEC104 (72): + IEC 60870-5-104 (IEC 104) Protocol. + IRCP (21): + Internet Relay Chat Protocol. + KADEMLIA (22): + Peer-to-peer hashtables. + KRB5 (65): + Kerberos 5. + LDAP (23): + Lightweight Directory Access Protocol. + LPD (24): + Line Printer Daemon Protocol. + MIME (25): + Multipurpose Internet Mail Extensions and + Secure MIME. + MMS (73): + Multimedia Messaging Service. + MODBUS (26): + Serial communications protocol. + MQTT (27): + Message Queuing Telemetry Transport. + NETCONF (28): + Network Configuration. + NFS (29): + Network File System. + NIS (30): + Network Information Service. + NNTP (31): + Network News Transfer Protocol. + NTCIP (32): + National Transportation Communications for + Intelligent Transportation System. + NTP (33): + Network Time Protocol. + OSCAR (34): + AOL Instant Messenger Protocol. + PNRP (35): + Peer Name Resolution Protocol. + PTP (74): + Precision Time Protocol. + QUIC (1000): + QUIC. + RDP (36): + Remote Desktop Protocol. + RELP (37): + Reliable Event Logging Protocol. + RIP (38): + Routing Information Protocol. + RLOGIN (39): + Remote Login in UNIX Systems. + RPC (40): + Remote Procedure Call. + RTMP (41): + Real Time Messaging Protocol. + RTP (42): + Real-time Transport Protocol. + RTPS (43): + Real Time Publish Subscribe. + RTSP (44): + Real Time Streaming Protocol. + SAP (45): + Session Announcement Protocol. + SDP (46): + Session Description Protocol. + SIP (47): + Session Initiation Protocol. + SLP (48): + Service Location Protocol. + SMB (49): + Server Message Block. + SMTP (50): + Simple Mail Transfer Protocol. + SNMP (75): + Simple Network Management Protocol. + SNTP (51): + Simple Network Time Protocol. + SSH (52): + Secure Shell. + SSMS (53): + Secure SMS Messaging Protocol. + STYX (54): + Styx/9P - Plan 9 from Bell Labs distributed + file system protocol. + SV (76): + Sampled Values Protocol. + TCAP (55): + Transaction Capabilities Application Part. + TDS (56): + Tabular Data Stream. + TOR (57): + Anonymity network. + TSP (58): + Time Stamp Protocol. + VTP (59): + Virtual Terminal Protocol. + WHOIS (60): + Remote Directory Access Protocol. + WEB_DAV (61): + Web Distributed Authoring and Versioning. + X400 (62): + Message Handling Service Protocol. + X500 (63): + Directory Access Protocol (DAP). + XMPP (64): + Extensible Messaging and Presence Protocol. + FTP (78): + File Transfer Protocol. + """ + + UNKNOWN_APPLICATION_PROTOCOL = 0 + AFP = 1 + APPC = 2 + AMQP = 3 + ATOM = 4 + BEEP = 5 + BITCOIN = 6 + BIT_TORRENT = 7 + CFDP = 8 + CIP = 67 + COAP = 9 + COTP = 68 + DCERPC = 66 + DDS = 10 + DEVICE_NET = 11 + DHCP = 4000 + DICOM = 69 + DNP3 = 70 + DNS = 3000 + E_DONKEY = 12 + ENRP = 13 + FAST_TRACK = 14 + FINGER = 15 + FREENET = 16 + FTAM = 17 + GOOSE = 71 + GOPHER = 18 + GRPC = 77 + HL7 = 19 + H323 = 20 + HTTP = 2000 + HTTPS = 2001 + IEC104 = 72 + IRCP = 21 + KADEMLIA = 22 + KRB5 = 65 + LDAP = 23 + LPD = 24 + MIME = 25 + MMS = 73 + MODBUS = 26 + MQTT = 27 + NETCONF = 28 + NFS = 29 + NIS = 30 + NNTP = 31 + NTCIP = 32 + NTP = 33 + OSCAR = 34 + PNRP = 35 + PTP = 74 + QUIC = 1000 + RDP = 36 + RELP = 37 + RIP = 38 + RLOGIN = 39 + RPC = 40 + RTMP = 41 + RTP = 42 + RTPS = 43 + RTSP = 44 + SAP = 45 + SDP = 46 + SIP = 47 + SLP = 48 + SMB = 49 + SMTP = 50 + SNMP = 75 + SNTP = 51 + SSH = 52 + SSMS = 53 + STYX = 54 + SV = 76 + TCAP = 55 + TDS = 56 + TOR = 57 + TSP = 58 + VTP = 59 + WHOIS = 60 + WEB_DAV = 61 + X400 = 62 + X500 = 63 + XMPP = 64 + FTP = 78 + + class ConnectionState(proto.Enum): + r"""The state of a network connection. + + Values: + CONNECTION_STATE_UNSPECIFIED (0): + The default connection state. + LISTENING (1): + The port is listening for incoming + connections. + ESTABLISHED (2): + A connection has been established. + TIME_WAIT (3): + The connection is waiting for a timeout. + CLOSE_WAIT (4): + The connection is waiting for a connection + termination request from the local application. + CLOSED (5): + The connection is closed. + SYN_SENT (6): + A connection request has been sent. + SYN_RECEIVED (7): + A connection request has been received. + FIN_WAIT1 (8): + The connection is waiting for a connection + termination request from the remote host. + FIN_WAIT2 (9): + The connection is waiting for a connection + termination request from the local application. + LAST_ACK (10): + The connection is waiting for an + acknowledgment of the final connection + termination request. + """ + + CONNECTION_STATE_UNSPECIFIED = 0 + LISTENING = 1 + ESTABLISHED = 2 + TIME_WAIT = 3 + CLOSE_WAIT = 4 + CLOSED = 5 + SYN_SENT = 6 + SYN_RECEIVED = 7 + FIN_WAIT1 = 8 + FIN_WAIT2 = 9 + LAST_ACK = 10 + + sent_bytes: int = proto.Field( + proto.UINT64, + number=1, + ) + received_bytes: int = proto.Field( + proto.UINT64, + number=2, + ) + total_bytes: int = proto.Field( + proto.INT64, + number=27, + ) + sent_packets: int = proto.Field( + proto.INT64, + number=22, + ) + received_packets: int = proto.Field( + proto.INT64, + number=23, + ) + session_duration: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=13, + message=duration_pb2.Duration, + ) + session_id: str = proto.Field( + proto.STRING, + number=14, + ) + parent_session_id: str = proto.Field( + proto.STRING, + number=20, + ) + application_protocol_version: str = proto.Field( + proto.STRING, + number=21, + ) + community_id: str = proto.Field( + proto.STRING, + number=15, + ) + direction: Direction = proto.Field( + proto.ENUM, + number=12, + enum=Direction, + ) + ip_protocol: IpProtocol = proto.Field( + proto.ENUM, + number=3, + enum=IpProtocol, + ) + ipv6: bool = proto.Field( + proto.BOOL, + number=29, + ) + application_protocol: ApplicationProtocol = proto.Field( + proto.ENUM, + number=4, + enum=ApplicationProtocol, + ) + ftp: "Ftp" = proto.Field( + proto.MESSAGE, + number=5, + message="Ftp", + ) + email: "Email" = proto.Field( + proto.MESSAGE, + number=6, + message="Email", + ) + dns: "Dns" = proto.Field( + proto.MESSAGE, + number=7, + message="Dns", + ) + dhcp: "Dhcp" = proto.Field( + proto.MESSAGE, + number=8, + message="Dhcp", + ) + http: "Http" = proto.Field( + proto.MESSAGE, + number=9, + message="Http", + ) + tls: "Tls" = proto.Field( + proto.MESSAGE, + number=10, + message="Tls", + ) + smtp: "Smtp" = proto.Field( + proto.MESSAGE, + number=11, + message="Smtp", + ) + asn: str = proto.Field( + proto.STRING, + number=16, + ) + dns_domain: str = proto.Field( + proto.STRING, + number=17, + ) + carrier_name: str = proto.Field( + proto.STRING, + number=18, + ) + organization_name: str = proto.Field( + proto.STRING, + number=19, + ) + ip_subnet_range: str = proto.Field( + proto.STRING, + number=24, + ) + is_proxy: bool = proto.Field( + proto.BOOL, + number=25, + ) + proxy_info: "ProxyInfo" = proto.Field( + proto.MESSAGE, + number=26, + message="ProxyInfo", + ) + connection_state: ConnectionState = proto.Field( + proto.ENUM, + number=28, + enum=ConnectionState, + ) + + +class ProxyInfo(proto.Message): + r"""Proxy information. + + Attributes: + anonymous (bool): + Whether the IP address is anonymous. + anonymous_vpn (bool): + Whether the IP address is an anonymous VPN. + public_proxy (bool): + Whether the IP address is a public proxy. + tor_exit_node (bool): + Whether the IP address is a tor exit node. + smart_dns_proxy (bool): + Whether the IP address is a smart DNS proxy. + hosting_provider (bool): + Whether the IP address is a hosting provider. + vpn_datacenter (bool): + Whether the IP address is a VPN datacenter. + residential_proxy (bool): + Whether the IP address is a residential + proxy. + vpn_service_name (str): + The name of the VPN service. + proxy_over_vpn (bool): + Whether the IP address is a proxy over VPN. + relay_proxy (bool): + Whether the IP address is a relay proxy. + """ + + anonymous: bool = proto.Field( + proto.BOOL, + number=1, + ) + anonymous_vpn: bool = proto.Field( + proto.BOOL, + number=2, + ) + public_proxy: bool = proto.Field( + proto.BOOL, + number=3, + ) + tor_exit_node: bool = proto.Field( + proto.BOOL, + number=4, + ) + smart_dns_proxy: bool = proto.Field( + proto.BOOL, + number=5, + ) + hosting_provider: bool = proto.Field( + proto.BOOL, + number=6, + ) + vpn_datacenter: bool = proto.Field( + proto.BOOL, + number=7, + ) + residential_proxy: bool = proto.Field( + proto.BOOL, + number=8, + ) + vpn_service_name: str = proto.Field( + proto.STRING, + number=9, + ) + proxy_over_vpn: bool = proto.Field( + proto.BOOL, + number=10, + ) + relay_proxy: bool = proto.Field( + proto.BOOL, + number=11, + ) + + +class Extensions(proto.Message): + r"""Extensions to a UDM event. + + Attributes: + auth (google.backstory.types.Authentication): + An authentication extension. + vulns (google.backstory.types.Vulnerabilities): + A vulnerability extension. + entity_risk (google.backstory.types.EntityRisk): + An entity risk change extension. + linux_utmp (google.backstory.types.LinuxUtmp): + A Linux Utmp extension. This captures details + specific to Linux Utmp events, which record + login and logout sessions on a Linux system. + windows_event_log (google.backstory.types.WindowsEventLog): + A Windows Event Log extension. This captures + details specific to Windows Event Log events, + providing structured information from various + Windows logs. + resource_usage (google.backstory.types.ResourceUsage): + A resource usage extension. This captures + details about what entity (e.g., process, user) + is using a specific resource. + system_event_details (google.backstory.types.SystemEventDetails): + A system event details extension. This + captures additional details for system-level + events, such as message type, sender image ID, + and subsystem. + outlook_metadata (google.backstory.types.OutlookMetadata): + A Microsoft Outlook specific metadata + extension. This includes metadata related to + Outlook items, such as comments, templates, and + security flags. + srum (google.backstory.types.Srum): + A SRUM extension. This captures details + specific to Windows System Resource Usage + Monitor (SRUM) events, providing insights into + application resource consumption. + user_assist (google.backstory.types.UserAssist): + A UserAssist extension. This captures details + specific to Windows User Assist events, which + track application usage and execution. + """ + + auth: "Authentication" = proto.Field( + proto.MESSAGE, + number=1, + message="Authentication", + ) + vulns: "Vulnerabilities" = proto.Field( + proto.MESSAGE, + number=2, + message="Vulnerabilities", + ) + entity_risk: gb_entity_risk.EntityRisk = proto.Field( + proto.MESSAGE, + number=3, + message=gb_entity_risk.EntityRisk, + ) + linux_utmp: "LinuxUtmp" = proto.Field( + proto.MESSAGE, + number=4, + message="LinuxUtmp", + ) + windows_event_log: "WindowsEventLog" = proto.Field( + proto.MESSAGE, + number=5, + message="WindowsEventLog", + ) + resource_usage: "ResourceUsage" = proto.Field( + proto.MESSAGE, + number=6, + message="ResourceUsage", + ) + system_event_details: "SystemEventDetails" = proto.Field( + proto.MESSAGE, + number=7, + message="SystemEventDetails", + ) + outlook_metadata: "OutlookMetadata" = proto.Field( + proto.MESSAGE, + number=8, + message="OutlookMetadata", + ) + srum: "Srum" = proto.Field( + proto.MESSAGE, + number=9, + message="Srum", + ) + user_assist: "UserAssist" = proto.Field( + proto.MESSAGE, + number=10, + message="UserAssist", + ) + + +class Authentication(proto.Message): + r"""The Authentication extension captures details specific to + authentication events. General guidelines for authentication events: + + - Details about the source of the authentication event (for example, + client IP or hostname), should be captured in principal. The + principal may be empty if we have no details about the source of + the login. + - Details about the target of the authentication event (for example, + details about the machine that is being logged into or logged out + of) should be captured in target. + - Some authentication events may involve a third-party. For example, + a user logs into a cloud service (for example, Chronicle) via + their company's SSO (the event is logged by their SSO solution). + In this case, the principal captures information about the user's + device, the target captures details about the cloud service they + logged into, and the intermediary captures details about the SSO + solution. + + Attributes: + type_ (google.backstory.types.Authentication.AuthType): + The type of authentication. + mechanism (MutableSequence[google.backstory.types.Authentication.Mechanism]): + The authentication mechanism. + auth_details (str): + The vendor defined details of the + authentication. + outcome (google.backstory.types.Authentication.Outcome): + The outcome of the authentication event. + """ + + class AuthType(proto.Enum): + r"""Type of system the authentication event is associated with. + + Values: + AUTHTYPE_UNSPECIFIED (0): + The default type. + MACHINE (1): + A machine authentication. + SSO (2): + An SSO authentication. + VPN (3): + A VPN authentication. + PHYSICAL (4): + A Physical authentication (e.g. "Badge + reader"). + TACACS (5): + A TACACS family protocol for networked + systems authentication (e.g. TACACS, TACACS+). + """ + + AUTHTYPE_UNSPECIFIED = 0 + MACHINE = 1 + SSO = 2 + VPN = 3 + PHYSICAL = 4 + TACACS = 5 + + class Mechanism(proto.Enum): + r"""Mechanism(s) used to authenticate. + + Values: + MECHANISM_UNSPECIFIED (0): + The default mechanism. + USERNAME_PASSWORD (1): + Username + password authentication. + OTP (2): + OTP authentication. + HARDWARE_KEY (3): + Hardware key authentication. + LOCAL (4): + Local authentication. + REMOTE (5): + Remote authentication. + REMOTE_INTERACTIVE (6): + RDP, Terminal Services, or VNC. + MECHANISM_OTHER (7): + Some other mechanism that is not defined + here. + BADGE_READER (8): + Badge reader authentication + NETWORK (9): + Network authentication. + BATCH (10): + Batch authentication. + SERVICE (11): + Service authentication + UNLOCK (12): + Direct human-interactive unlock + authentication. + NETWORK_CLEAR_TEXT (13): + Network clear text authentication. + NEW_CREDENTIALS (14): + Authentication with new credentials. + INTERACTIVE (15): + Interactive authentication. + CACHED_INTERACTIVE (16): + Interactive authentication using cached + credentials. + CACHED_REMOTE_INTERACTIVE (17): + Cached Remote Interactive authentication + using cached credentials. + CACHED_UNLOCK (18): + Cached Remote Interactive authentication + using cached credentials. + BIOMETRIC (19): + Biometric device such as a fingerprint + reader. + WEARABLE (20): + Wearable such as an Apple Watch. + """ + + MECHANISM_UNSPECIFIED = 0 + USERNAME_PASSWORD = 1 + OTP = 2 + HARDWARE_KEY = 3 + LOCAL = 4 + REMOTE = 5 + REMOTE_INTERACTIVE = 6 + MECHANISM_OTHER = 7 + BADGE_READER = 8 + NETWORK = 9 + BATCH = 10 + SERVICE = 11 + UNLOCK = 12 + NETWORK_CLEAR_TEXT = 13 + NEW_CREDENTIALS = 14 + INTERACTIVE = 15 + CACHED_INTERACTIVE = 16 + CACHED_REMOTE_INTERACTIVE = 17 + CACHED_UNLOCK = 18 + BIOMETRIC = 19 + WEARABLE = 20 + + class AuthenticationStatus(proto.Enum): + r"""Authentication status, can be used to describe the status of + authentication for a user or particular credential. + + Values: + UNKNOWN_AUTHENTICATION_STATUS (0): + The default authentication status. + ACTIVE (1): + The authentication method is in active state. + SUSPENDED (2): + The authentication method is in + suspended/disabled state. + NO_ACTIVE_CREDENTIALS (3): + The authentication method has no active + credentials. + DELETED (4): + The authentication method has been deleted. + """ + + UNKNOWN_AUTHENTICATION_STATUS = 0 + ACTIVE = 1 + SUSPENDED = 2 + NO_ACTIVE_CREDENTIALS = 3 + DELETED = 4 + + class Outcome(proto.Enum): + r"""The outcome of the authentication event. + + Values: + OUTCOME_UNSPECIFIED (0): + The default outcome. + SUCCESS (1): + The authentication was successful. + FAILURE (2): + The authentication failed. + """ + + OUTCOME_UNSPECIFIED = 0 + SUCCESS = 1 + FAILURE = 2 + + type_: AuthType = proto.Field( + proto.ENUM, + number=1, + enum=AuthType, + ) + mechanism: MutableSequence[Mechanism] = proto.RepeatedField( + proto.ENUM, + number=2, + enum=Mechanism, + ) + auth_details: str = proto.Field( + proto.STRING, + number=3, + ) + outcome: Outcome = proto.Field( + proto.ENUM, + number=4, + enum=Outcome, + ) + + +class LinuxUtmp(proto.Message): + r"""The LinuxUtmp extension captures details specific to Linux + Utmp events. + + Attributes: + record_type (google.backstory.types.LinuxUtmp.RecordType): + The activity record type. + """ + + class RecordType(proto.Enum): + r"""The type of activity record from the Utmp file. + + Values: + RECORD_TYPE_UNSPECIFIED (0): + The default record type. + RUN_LVL (1): + Run-level change. + BOOT_TIME (2): + System boot time. + NEW_TIME (3): + New time after system clock change. + OLD_TIME (4): + Old time before system clock change. + INIT_PROCESS (5): + Process spawned by init. + LOGIN_PROCESS (6): + Login process. + USER_PROCESS (7): + Normal user process (logged-in session). + DEAD_PROCESS (8): + Terminated process (session ended). + ACCOUNTING (9): + Accounting message. + """ + + RECORD_TYPE_UNSPECIFIED = 0 + RUN_LVL = 1 + BOOT_TIME = 2 + NEW_TIME = 3 + OLD_TIME = 4 + INIT_PROCESS = 5 + LOGIN_PROCESS = 6 + USER_PROCESS = 7 + DEAD_PROCESS = 8 + ACCOUNTING = 9 + + record_type: RecordType = proto.Field( + proto.ENUM, + number=1, + enum=RecordType, + ) + + +class WindowsEventLog(proto.Message): + r"""The WindowsEventLog extension captures details specific to + Windows Event Log events. + + Attributes: + channel (google.backstory.types.WindowsEventLog.Channel): + The channel of the event. + event_id (str): + A unique identifier for a specific type of + event. + activity_id (str): + A GUID (Globally Unique Identifier) used to + link a sequence of related events together. + """ + + class Channel(proto.Enum): + r"""The channel specifies the source or category of the event. + + Values: + CHANNEL_UNSPECIFIED (0): + Default channel. + SECURITY (1): + The security channel. + SYSTEM (2): + The system channel. + APPLICATION (3): + The application channel. + SETUP (4): + The setup channel. + FORWARDED_EVENTS (5): + The forwarded events channel. + OTHER (6): + The other channel. + """ + + CHANNEL_UNSPECIFIED = 0 + SECURITY = 1 + SYSTEM = 2 + APPLICATION = 3 + SETUP = 4 + FORWARDED_EVENTS = 5 + OTHER = 6 + + channel: Channel = proto.Field( + proto.ENUM, + number=1, + enum=Channel, + ) + event_id: str = proto.Field( + proto.STRING, + number=2, + ) + activity_id: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ResourceUsage(proto.Message): + r"""The ResourceUsage extension captures details about what is + using a resource. + + Attributes: + used_entity (str): + The name of the entity (e.g., process, user) + that is using the resource. + used_entity_id (str): + A numerical identifier for the entity using + the resource (e.g., PID, UID). + """ + + used_entity: str = proto.Field( + proto.STRING, + number=1, + ) + used_entity_id: str = proto.Field( + proto.STRING, + number=2, + ) + + +class SystemEventDetails(proto.Message): + r"""Captures additional details for system-level events. + + Attributes: + message_type (str): + The specific type or category of the message. + sender_image_id (str): + An identifier for the image associated with + the sender of the message. + subsystem (str): + The subsystem or component that generated the + event. + """ + + message_type: str = proto.Field( + proto.STRING, + number=1, + ) + sender_image_id: str = proto.Field( + proto.STRING, + number=2, + ) + subsystem: str = proto.Field( + proto.STRING, + number=3, + ) + + +class OutlookMetadata(proto.Message): + r"""Microsoft Outlook specific metadata. + + Attributes: + comment (str): + A user-defined comment or note associated + with the Outlook item. + template (str): + The name of the template file used to create + the Outlook item. + title (str): + The title of the Outlook item. + security_flags_count (int): + Count of Security-related flags for the + message, such as encryption or signing status. + """ + + comment: str = proto.Field( + proto.STRING, + number=1, + ) + template: str = proto.Field( + proto.STRING, + number=2, + ) + title: str = proto.Field( + proto.STRING, + number=3, + ) + security_flags_count: int = proto.Field( + proto.INT32, + number=4, + ) + + +class Srum(proto.Message): + r"""The Srum extension captures details specific to Windows + System Resource Usage Monitor (SRUM) events. + + Attributes: + id (str): + A unique identifier for the SRUM record or + the application/user being monitored. + background_bytes_read (int): + The number of bytes read by the application + while running in the background. + background_bytes_written (int): + The number of bytes written by the + application while running in the background. + background_context_switches (int): + The number of context switches performed by + the application's threads while in the + background. + background_cycle_count (int): + The amount of CPU cycle time consumed by the + application in the background, measured in clock + cycles. + background_flushes_count (int): + The number of flush operations performed by + the application in the background. + background_read_operations (int): + The number of read operations performed by + the application in the background. + background_write_operations (int): + The number of write operations performed by + the application in the background. + interface_luid (str): + The Locally Unique Identifier (LUID) for the + network interface used for data transfer. + """ + + id: str = proto.Field( + proto.STRING, + number=1, + ) + background_bytes_read: int = proto.Field( + proto.INT64, + number=2, + ) + background_bytes_written: int = proto.Field( + proto.INT64, + number=3, + ) + background_context_switches: int = proto.Field( + proto.INT64, + number=4, + ) + background_cycle_count: int = proto.Field( + proto.INT64, + number=5, + ) + background_flushes_count: int = proto.Field( + proto.INT64, + number=6, + ) + background_read_operations: int = proto.Field( + proto.INT64, + number=7, + ) + background_write_operations: int = proto.Field( + proto.INT64, + number=8, + ) + interface_luid: str = proto.Field( + proto.STRING, + number=9, + ) + + +class UserAssist(proto.Message): + r"""The UserAssist extension captures details specific to Windows + User Assist events. + + Attributes: + application_focus_count (int): + The number of times the application + associated with the entry gained focus. + application_focus_duration (google.protobuf.duration_pb2.Duration): + The total duration the application associated + with the entry was in focus. + executions_count (int): + The number of times the application + associated with the entry has been executed. + entry_index (int): + The index or identifier of the user assist + entry, unique per user. + """ + + application_focus_count: int = proto.Field( + proto.INT64, + number=1, + ) + application_focus_duration: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=2, + message=duration_pb2.Duration, + ) + executions_count: int = proto.Field( + proto.INT64, + number=3, + ) + entry_index: int = proto.Field( + proto.INT64, + number=4, + ) + + +class Vulnerabilities(proto.Message): + r"""The Vulnerabilities extension captures details on + observed/detected vulnerabilities. + + Attributes: + vulnerabilities (MutableSequence[google.backstory.types.Vulnerability]): + A list of vulnerabilities. + """ + + vulnerabilities: MutableSequence["Vulnerability"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="Vulnerability", + ) + + +class Vulnerability(proto.Message): + r"""A vulnerability. + + Attributes: + about (google.backstory.types.Noun): + If the vulnerability is about a specific noun + (e.g. executable), then add it here. + name (str): + Name of the vulnerability (e.g. "Unsupported + OS Version detected"). + description (str): + Description of the vulnerability. + vendor (str): + Vendor of scan that discovered vulnerability. + scan_start_time (google.protobuf.timestamp_pb2.Timestamp): + If the vulnerability was discovered during an + asset scan, then this field should be populated + with the time the scan started. This field can + be left unset if the start time is not available + or not applicable. + scan_end_time (google.protobuf.timestamp_pb2.Timestamp): + If the vulnerability was discovered during an + asset scan, then this field should be populated + with the time the scan ended. This field can be + left unset if the end time is not available or + not applicable. + first_found (google.protobuf.timestamp_pb2.Timestamp): + Products that maintain a history of vuln scans should + populate first_found with the time that a scan first + detected the vulnerability on this asset. + last_found (google.protobuf.timestamp_pb2.Timestamp): + Products that maintain a history of vuln scans should + populate last_found with the time that a scan last detected + the vulnerability on this asset. + severity (google.backstory.types.Vulnerability.Severity): + The severity of the vulnerability. + severity_details (str): + Vendor-specific severity + cvss_base_score (float): + CVSS Base Score in the range of 0.0 to 10.0. + Useful for sorting. + cvss_vector (str): + Vector of CVSS properties (e.g. + "AV:L/AC:H/Au:N/C:N/I:P/A:C") Can be linked to via: + https://nvd.nist.gov/vuln-metrics/cvss/v2-calculator + cvss_version (str): + Version of CVSS Vector/Score. + cve_id (str): + Common Vulnerabilities and Exposures Id. + https://en.wikipedia.org/wiki/Common_Vulnerabilities_and_Exposures + https://cve.mitre.org/about/faqs.html#what_is_cve_id + cve_description (str): + Common Vulnerabilities and Exposures Description. + https://cve.mitre.org/about/faqs.html#what_is_cve_record + vendor_vulnerability_id (str): + Vendor specific vulnerability id (e.g. + Microsoft security bulletin id). + vendor_knowledge_base_article_id (str): + Vendor specific knowledge base article (e.g. "KBXXXXXX" from + Microsoft). + https://en.wikipedia.org/wiki/Microsoft_Knowledge_Base + https://access.redhat.com/knowledgebase + """ + + class Severity(proto.Enum): + r"""Severity of the vulnerability. + + Values: + UNKNOWN_SEVERITY (0): + The default severity level. + LOW (1): + Low severity. + MEDIUM (2): + Medium severity. + HIGH (3): + High severity. + CRITICAL (4): + Critical severity. + """ + + UNKNOWN_SEVERITY = 0 + LOW = 1 + MEDIUM = 2 + HIGH = 3 + CRITICAL = 4 + + about: "Noun" = proto.Field( + proto.MESSAGE, + number=1, + message="Noun", + ) + name: str = proto.Field( + proto.STRING, + number=2, + ) + description: str = proto.Field( + proto.STRING, + number=3, + ) + vendor: str = proto.Field( + proto.STRING, + number=13, + ) + scan_start_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=4, + message=timestamp_pb2.Timestamp, + ) + scan_end_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + first_found: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=6, + message=timestamp_pb2.Timestamp, + ) + last_found: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=7, + message=timestamp_pb2.Timestamp, + ) + severity: Severity = proto.Field( + proto.ENUM, + number=8, + enum=Severity, + ) + severity_details: str = proto.Field( + proto.STRING, + number=9, + ) + cvss_base_score: float = proto.Field( + proto.FLOAT, + number=10, + ) + cvss_vector: str = proto.Field( + proto.STRING, + number=11, + ) + cvss_version: str = proto.Field( + proto.STRING, + number=12, + ) + cve_id: str = proto.Field( + proto.STRING, + number=14, + ) + cve_description: str = proto.Field( + proto.STRING, + number=15, + ) + vendor_vulnerability_id: str = proto.Field( + proto.STRING, + number=16, + ) + vendor_knowledge_base_article_id: str = proto.Field( + proto.STRING, + number=17, + ) + + +class Ftp(proto.Message): + r"""FTP info. + + Attributes: + command (str): + The FTP command. + """ + + command: str = proto.Field( + proto.STRING, + number=1, + ) + + +class Smtp(proto.Message): + r"""SMTP info. See RFC 2821. + + Attributes: + helo (str): + The client's 'HELO'/'EHLO' string. + mail_from (str): + The client's 'MAIL FROM' string. + rcpt_to (MutableSequence[str]): + The client's 'RCPT TO' string(s). + server_response (MutableSequence[str]): + The server's response(s) to the client. + message_path (str): + The message's path (extracted from the + headers). + is_webmail (bool): + If the message was sent via a webmail client. + is_tls (bool): + If the connection switched to TLS. + """ + + helo: str = proto.Field( + proto.STRING, + number=1, + ) + mail_from: str = proto.Field( + proto.STRING, + number=2, + ) + rcpt_to: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + server_response: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=4, + ) + message_path: str = proto.Field( + proto.STRING, + number=5, + ) + is_webmail: bool = proto.Field( + proto.BOOL, + number=6, + ) + is_tls: bool = proto.Field( + proto.BOOL, + number=7, + ) + + +class Email(proto.Message): + r"""Email info. + + Attributes: + from_ (str): + The 'from' address. + reply_to (str): + The 'reply to' address. + to (MutableSequence[str]): + A list of 'to' addresses. + cc (MutableSequence[str]): + A list of 'cc' addresses. + bcc (MutableSequence[str]): + A list of 'bcc' addresses. + mail_id (str): + The mail (or message) ID. + subject (MutableSequence[str]): + The subject line(s) of the email. + bounce_address (str): + The envelope from address. + https://en.wikipedia.org/wiki/Bounce_address + """ + + from_: str = proto.Field( + proto.STRING, + number=1, + ) + reply_to: str = proto.Field( + proto.STRING, + number=2, + ) + to: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + cc: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=4, + ) + bcc: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=5, + ) + mail_id: str = proto.Field( + proto.STRING, + number=6, + ) + subject: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=7, + ) + bounce_address: str = proto.Field( + proto.STRING, + number=8, + ) + + +class Process(proto.Message): + r"""Information about a process. + + Attributes: + pid (str): + The process ID. + This field can be used as an entity indicator + for process entities. + parent_pid (str): + The ID of the parent process. Deprecated: use + parent_process.pid instead. + parent_process (google.backstory.types.Process): + Information about the parent process. + file (google.backstory.types.File): + Information about the file in use by the + process. + command_line (str): + The command line command that created the + process. This field can be used as an entity + indicator for process entities. + command_line_history (MutableSequence[str]): + The command line history of the process. + product_specific_process_id (str): + A product specific process id. + access_mask (int): + A bit mask representing the level of access. + integrity_level_rid (int): + The Microsoft Windows integrity level + relative ID (RID) of the process. + euid (str): + The effective user ID of the process. + ruid (str): + The real user ID of the process. + egid (str): + The effective group ID of the process. + rgid (str): + The real group ID of the process. + pgid (str): + The identifier that points to the process + group ID leader. + session_leader_pid (str): + The process ID of the session leader process. + tty (str): + The teletype terminal which the command was + executed within. + token_elevation_type (google.backstory.types.Process.TokenElevationType): + The elevation type of the process on + Microsoft Windows. This determines if any + privileges are removed when UAC is enabled. + product_specific_parent_process_id (str): + A product specific id for the parent process. Please use + parent_process.product_specific_process_id instead. + ipv6 (bool): + This is used to determine if the process is + an IPv6 process. + kernel_duration (google.protobuf.duration_pb2.Duration): + The kernel time spent in the process. + user_duration (google.protobuf.duration_pb2.Duration): + The user time spent in the process. + real_duration (google.protobuf.duration_pb2.Duration): + The real time spent in the process. This is + the sum of the kernel and user time. + state (google.backstory.types.Process.State): + The state of the process. + """ + + class TokenElevationType(proto.Enum): + r"""The elevation type of the process's token. See + https://learn.microsoft.com/en-us/windows/win32/api/winnt/ne-winnt-token_elevation_type + + Values: + UNKNOWN (0): + An undetermined token type. + TYPE_1 (1): + A full token with no privileges removed or + groups disabled. + TYPE_2 (2): + An elevated token with no privileges removed + or groups disabled. Used when running as + administrator. + TYPE_3 (3): + A limited token with administrative + privileges removed and administrative groups + disabled. + """ + + UNKNOWN = 0 + TYPE_1 = 1 + TYPE_2 = 2 + TYPE_3 = 3 + + class State(proto.Enum): + r"""The state of the process. + See + https://psutil.readthedocs.io/en/stable/#process-status-constants. + + Values: + STATE_UNSPECIFIED (0): + Undetermined state. + RUNNING (1): + Process is running or runnable. + SLEEPING (2): + Process is waiting for an event. + DISK_SLEEP (3): + Process is in uninterruptible sleep, + typically I/O. + STOPPED (4): + Process is stopped. + TRACING_STOP (5): + Process is stopped by debugger. + ZOMBIE (6): + Process is terminated but not reaped by + parent. + DEAD (7): + Process is terminated. + WAKE_KILL (8): + Process is woken to be killed. + WAKING (9): + Process is waking from sleep. + PARKED (10): + Linux specific: process is parked. + IDLE (11): + Linux, macOS, and FreeBSD specific: process + is idle. + LOCKED (12): + FreeBSD specific: process is locked. + WAITING (13): + FreeBSD specific: process is waiting. + SUSPENDED (14): + NetBSD specific: process is suspended. + """ + + STATE_UNSPECIFIED = 0 + RUNNING = 1 + SLEEPING = 2 + DISK_SLEEP = 3 + STOPPED = 4 + TRACING_STOP = 5 + ZOMBIE = 6 + DEAD = 7 + WAKE_KILL = 8 + WAKING = 9 + PARKED = 10 + IDLE = 11 + LOCKED = 12 + WAITING = 13 + SUSPENDED = 14 + + pid: str = proto.Field( + proto.STRING, + number=1, + ) + parent_pid: str = proto.Field( + proto.STRING, + number=2, + ) + parent_process: "Process" = proto.Field( + proto.MESSAGE, + number=7, + message="Process", + ) + file: "File" = proto.Field( + proto.MESSAGE, + number=3, + message="File", + ) + command_line: str = proto.Field( + proto.STRING, + number=4, + ) + command_line_history: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=9, + ) + product_specific_process_id: str = proto.Field( + proto.STRING, + number=5, + ) + access_mask: int = proto.Field( + proto.UINT64, + number=8, + ) + integrity_level_rid: int = proto.Field( + proto.UINT64, + number=11, + ) + euid: str = proto.Field( + proto.STRING, + number=12, + ) + ruid: str = proto.Field( + proto.STRING, + number=13, + ) + egid: str = proto.Field( + proto.STRING, + number=14, + ) + rgid: str = proto.Field( + proto.STRING, + number=15, + ) + pgid: str = proto.Field( + proto.STRING, + number=16, + ) + session_leader_pid: str = proto.Field( + proto.STRING, + number=17, + ) + tty: str = proto.Field( + proto.STRING, + number=18, + ) + token_elevation_type: TokenElevationType = proto.Field( + proto.ENUM, + number=10, + enum=TokenElevationType, + ) + product_specific_parent_process_id: str = proto.Field( + proto.STRING, + number=6, + ) + ipv6: bool = proto.Field( + proto.BOOL, + number=19, + ) + kernel_duration: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=20, + message=duration_pb2.Duration, + ) + user_duration: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=21, + message=duration_pb2.Duration, + ) + real_duration: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=22, + message=duration_pb2.Duration, + ) + state: State = proto.Field( + proto.ENUM, + number=23, + enum=State, + ) + + +class AnalyticsMetadata(proto.Message): + r"""Stores information about an analytics metric used in a rule. + + Attributes: + analytic (str): + Name of the analytic. + """ + + analytic: str = proto.Field( + proto.STRING, + number=1, + ) + + +class FindingVariable(proto.Message): + r"""A structure that holds the value and associated metadata for + values extracted while producing a Finding. + + 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: + type_ (google.backstory.types.FindingVariable.Type): + The type of the variable. + value (str): + The value in string form. + source_path (str): + The UDM field path for the field which this value was + derived from. Example: ``principal.user.username`` + bool_val (bool): + The value in boolean format. + + This field is a member of `oneof`_ ``typed_value``. + bytes_val (bytes): + The value in bytes format. + + This field is a member of `oneof`_ ``typed_value``. + double_val (float): + The value in double format. + + This field is a member of `oneof`_ ``typed_value``. + int64_val (int): + The value in int64 format. + + This field is a member of `oneof`_ ``typed_value``. + uint64_val (int): + The value in uint64 format. + + This field is a member of `oneof`_ ``typed_value``. + string_val (str): + The value in string format. + Enum values are returned as strings. + + This field is a member of `oneof`_ ``typed_value``. + timestamp_time (google.protobuf.timestamp_pb2.Timestamp): + The value in timestamp format. + + This field is a member of `oneof`_ ``typed_value``. + null_val (bool): + Whether the value is null. + + This field is a member of `oneof`_ ``typed_value``. + bool_seq (google.backstory.types.BoolSequence): + The value in boolsequence format. + + This field is a member of `oneof`_ ``typed_value``. + bytes_seq (google.backstory.types.BytesSequence): + The value in bytessequence format. + + This field is a member of `oneof`_ ``typed_value``. + double_seq (google.backstory.types.DoubleSequence): + The value in doublesequence format. + + This field is a member of `oneof`_ ``typed_value``. + int64_seq (google.backstory.types.Int64Sequence): + The value in int64sequence format. + + This field is a member of `oneof`_ ``typed_value``. + uint64_seq (google.backstory.types.Uint64Sequence): + The value in uint64sequence format. + + This field is a member of `oneof`_ ``typed_value``. + string_seq (google.backstory.types.StringSequence): + The value in stringsequence format. + + This field is a member of `oneof`_ ``typed_value``. + """ + + class Type(proto.Enum): + r"""Type options for Finding variables. + + Values: + TYPE_UNSPECIFIED (0): + An unspecified variable type. + MATCH (1): + A variable coming from the match conditions. + OUTCOME (2): + A variable representing significant data that + was found in the detection logic. + """ + + TYPE_UNSPECIFIED = 0 + MATCH = 1 + OUTCOME = 2 + + type_: Type = proto.Field( + proto.ENUM, + number=1, + enum=Type, + ) + value: str = proto.Field( + proto.STRING, + number=2, + ) + source_path: str = proto.Field( + proto.STRING, + number=3, + ) + bool_val: bool = proto.Field( + proto.BOOL, + number=4, + oneof="typed_value", + ) + bytes_val: bytes = proto.Field( + proto.BYTES, + number=5, + oneof="typed_value", + ) + double_val: float = proto.Field( + proto.DOUBLE, + number=6, + oneof="typed_value", + ) + int64_val: int = proto.Field( + proto.INT64, + number=7, + oneof="typed_value", + ) + uint64_val: int = proto.Field( + proto.UINT64, + number=8, + oneof="typed_value", + ) + string_val: str = proto.Field( + proto.STRING, + number=9, + oneof="typed_value", + ) + timestamp_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=17, + oneof="typed_value", + message=timestamp_pb2.Timestamp, + ) + null_val: bool = proto.Field( + proto.BOOL, + number=10, + oneof="typed_value", + ) + bool_seq: "BoolSequence" = proto.Field( + proto.MESSAGE, + number=11, + oneof="typed_value", + message="BoolSequence", + ) + bytes_seq: "BytesSequence" = proto.Field( + proto.MESSAGE, + number=12, + oneof="typed_value", + message="BytesSequence", + ) + double_seq: "DoubleSequence" = proto.Field( + proto.MESSAGE, + number=13, + oneof="typed_value", + message="DoubleSequence", + ) + int64_seq: "Int64Sequence" = proto.Field( + proto.MESSAGE, + number=14, + oneof="typed_value", + message="Int64Sequence", + ) + uint64_seq: "Uint64Sequence" = proto.Field( + proto.MESSAGE, + number=15, + oneof="typed_value", + message="Uint64Sequence", + ) + string_seq: "StringSequence" = proto.Field( + proto.MESSAGE, + number=16, + oneof="typed_value", + message="StringSequence", + ) + + +class SecurityResult(proto.Message): + r"""Security related metadata for the event. A security result might be + something like "virus detected and quarantined," "malicious + connection blocked," or "sensitive data included in document + foo.doc." Each security result, of which there may be more than one, + may either pertain to the whole event, or to a specific object or + device referenced in the event (e.g. a malicious file that was + detected, or a sensitive document sent as an email attachment). For + security results that apply to a particular object referenced in the + event, the security_results message MUST contain details about the + implicated object (such as process, user, IP, domain, URL, IP, or + email address) in the about field. For security results that apply + to the entire event (e.g. SPAM found in this email), the about field + must remain empty. + + Attributes: + about (google.backstory.types.Noun): + If the security result is about a specific + entity (Noun), add it here. This field is not + populated when the SecurityResult appears in a + detection. + category (MutableSequence[google.backstory.types.SecurityResult.SecurityCategory]): + The security category. + This field is not populated when the + SecurityResult appears in a detection. + category_details (MutableSequence[str]): + For vendor-specific categories. For web + categorization, put type in here such as + "gambling" or "porn". This field is not + populated when the SecurityResult appears in a + detection. + threat_name (str): + A vendor-assigned classification common + across multiple customers (for example, + "W32/File-A", "Slammer"). This field is not + populated when the SecurityResult appears in a + detection. + rule_set (str): + The curated detection's rule set identifier. + (for example, "windows-threats") + This is primarily set in rule-generated + detections and alerts. + rule_set_display_name (str): + The curated detections rule set display name. + This is primarily set in rule-generated + detections and alerts. + ruleset_category_display_name (str): + The curated detection rule set category display name. (for + example, if rule_set_display_name is "CDIR SCC Enhanced + Exfiltration", the rule_set_category is "Cloud Threats"). + This is primarily set in rule-generated detections and + alerts. + rule_id (str): + A vendor-specific ID for a rule, varying by + observer type (e.g. "08123", + "5d2b44d0-5ef6-40f5-a704-47d61d3babbe"). + rule_name (str): + Name of the security rule + (e.g. "BlockInboundToOracle"). + display_name (str): + The display name of the security result. This is populated + from 'name_override' Outcome Variable, if present. + Otherwise, this field is not set. + rule_version (str): + Version of the security rule. + (e.g. "v1.1", "00001", "1604709794", + "2020-11-16T23:04:19+00:00"). Note that rule + versions are source-dependant and lexical + ordering should not be assumed. + rule_type (str): + The type of security rule. + rule_author (str): + Author of the security rule. + This field is not populated when the + SecurityResult appears in a detection. + rule_labels (MutableSequence[google.backstory.types.Label]): + A list of rule labels that can't be captured + by the other fields in security result + (e.g. "reference : AnotherRule", "contributor : + John"). This is primarily set in rule-generated + detections and alerts. + alert_state (google.backstory.types.SecurityResult.AlertState): + The alerting types of this security result. + This is primarily set for rule-generated + detections and alerts. + detection_fields (MutableSequence[google.backstory.types.Label]): + An ordered list of values, that represent + fields in detections for a security finding. + This list represents mapping of names of + requested entities to their values (the security + result matched variables). + + For Collection SecurityResults, prefer variables + instead. + outcomes (MutableSequence[google.backstory.types.Label]): + A list of outcomes that represent the results + of this security finding. This list represents a + mapping of names of the requested outcomes, to a + stringified version of their values. + + This is only populated when the SecurityResult + appears in a detection. This is deprecated. Use + variables instead. + variables (MutableMapping[str, google.backstory.types.FindingVariable]): + A list of outcomes and match variables that + represent the results of this security finding. + This list represents a mapping of names of the + requested outcomes or match variables, to their + values. + + This is only populated when the SecurityResult + appears in a detection. + summary (str): + A short human-readable summary (e.g. "failed + login occurred") + description (str): + A human-readable description (e.g. "user + password was wrong"). This can be more detailed + than the summary. + action (MutableSequence[google.backstory.types.SecurityResult.Action]): + Actions taken for this event. + This field is not populated when the + SecurityResult appears in a detection. + action_details (str): + The detail of the action taken as provided by + the vendor. This field is not populated when the + SecurityResult appears in a detection. + severity (google.backstory.types.SecurityResult.ProductSeverity): + The severity of the result. + confidence (google.backstory.types.SecurityResult.ProductConfidence): + The confidence level of the result as + estimated by the product. This field is not + populated when the SecurityResult appears in a + detection. + priority (google.backstory.types.SecurityResult.ProductPriority): + The priority of the result. + This field is not populated when the + SecurityResult appears in a detection. + risk_score (float): + The risk score of the security result. + confidence_score (float): + The confidence score of the security result. + This field is not populated when the + SecurityResult appears in a detection. + analytics_metadata (MutableSequence[google.backstory.types.AnalyticsMetadata]): + Stores metadata about each risk analytic + metric the rule uses. This field is not + populated when the SecurityResult appears in a + detection. + severity_details (str): + Vendor-specific severity. + This field is not populated when the + SecurityResult appears in a detection. + confidence_details (str): + Additional detail with regards to the + confidence of a security event as estimated by + the product vendor. This field is not populated + when the SecurityResult appears in a detection. + priority_details (str): + Vendor-specific information about the + security result priority. This field is not + populated when the SecurityResult appears in a + detection. + url_back_to_product (str): + URL that takes the user to the source product + console for this event. This field is not + populated when the SecurityResult appears in a + detection. + threat_id (str): + Vendor-specific ID for a threat. + This field is not populated when the + SecurityResult appears in a detection. + threat_feed_name (str): + Vendor feed name for a threat indicator feed. + This field is not populated when the + SecurityResult appears in a detection. + threat_id_namespace (google.backstory.types.Id.Namespace): + The attribute threat_id_namespace qualifies threat_id with + an id namespace to get an unique id. The attribute threat_id + by itself is not unique across Chronicle as it is a vendor + specific id. This field is not populated when the + SecurityResult appears in a detection. + threat_status (google.backstory.types.SecurityResult.ThreatStatus): + Current status of the threat + This field is not populated when the + SecurityResult appears in a detection. + attack_details (google.backstory.types.AttackDetails): + MITRE ATT&CK details. + This field is not populated when the + SecurityResult appears in a detection. + first_discovered_time (google.protobuf.timestamp_pb2.Timestamp): + First time the IoC threat was discovered in + the provider. This field is not populated when + the SecurityResult appears in a detection. + associations (MutableSequence[google.backstory.types.SecurityResult.Association]): + Associations related to the threat. + campaigns (MutableSequence[str]): + Campaigns using this IOC threat. This is deprecated. Use + threat_collections instead. + reports (MutableSequence[str]): + Reports that reference this IOC threat. These are the report + IDs. This is deprecated. Use threat_collections instead. + verdict (google.backstory.types.SecurityResult.Verdict): + Verdict about the IoC from the provider. + This field is now deprecated. Use VerdictInfo + instead. + last_updated_time (google.protobuf.timestamp_pb2.Timestamp): + Last time the IoC threat was updated in the + provider. This field is not populated when the + SecurityResult appears in a detection. + verdict_info (MutableSequence[google.backstory.types.SecurityResult.VerdictInfo]): + Verdict information about the IoC from the + provider. This field is not populated when the + SecurityResult appears in a detection. + threat_verdict (google.backstory.types.ThreatVerdict): + GCTI threat verdict on the security result + entity. This field is not populated when the + SecurityResult appears in a detection. + last_discovered_time (google.protobuf.timestamp_pb2.Timestamp): + Last time the IoC was seen in the provider + data. This field is not populated when the + SecurityResult appears in a detection. + detection_depth (int): + The depth of the detection chain. + Applies only to composite detections. + threat_collections (MutableSequence[google.backstory.types.SecurityResult.ThreatCollectionItem]): + GTI collections associated with the security + result. + """ + + class VerdictResponse(proto.Enum): + r"""Represents different verdict types. Used to represent + Mandiant threat intelligence. + + Values: + VERDICT_RESPONSE_UNSPECIFIED (0): + The default verdict response type. + MALICIOUS (1): + VerdictResponse resulted a threat as + malicious. + BENIGN (2): + VerdictResponse resulted a threat as benign. + """ + + VERDICT_RESPONSE_UNSPECIFIED = 0 + MALICIOUS = 1 + BENIGN = 2 + + class IoCStatsType(proto.Enum): + r"""Type of IoCStat based on source. + + Values: + UNSPECIFIED_IOC_STATS_TYPE (0): + IoCStat source is unidentified. + MANDIANT_SOURCES (1): + IoCStat is from a Mandiant Source. + THIRD_PARTY_SOURCES (2): + IoCStat is from a third-party source. + THREAT_INTELLIGENCE_IOC_STATS (3): + IoCStat is from a threat intelligence feed. + """ + + UNSPECIFIED_IOC_STATS_TYPE = 0 + MANDIANT_SOURCES = 1 + THIRD_PARTY_SOURCES = 2 + THREAT_INTELLIGENCE_IOC_STATS = 3 + + class VerdictType(proto.Enum): + r"""Category of the verdict. + + Values: + VERDICT_TYPE_UNSPECIFIED (0): + Verdict category not specified. + PROVIDER_ML_VERDICT (1): + MLVerdict result provided from threat + providers, like Mandiant. These fields are used + to model Mandiant sources. + ANALYST_VERDICT (2): + Verdict provided by the human analyst. These + fields are used to model Mandiant sources. + """ + + VERDICT_TYPE_UNSPECIFIED = 0 + PROVIDER_ML_VERDICT = 1 + ANALYST_VERDICT = 2 + + class SecurityCategory(proto.Enum): + r"""SecurityCategory is used to standardize security categories + across products so one event is not categorized as "malware" and + another as a "virus". + + Values: + UNKNOWN_CATEGORY (0): + The default category. + SOFTWARE_MALICIOUS (10000): + Malware, spyware, rootkit. + SOFTWARE_SUSPICIOUS (10100): + Below the conviction threshold; probably bad. + SOFTWARE_PUA (10200): + Potentially Unwanted App (such as adware). + NETWORK_MALICIOUS (20000): + Includes C&C or network exploit. + NETWORK_SUSPICIOUS (20100): + Suspicious activity, such as potential + reverse tunnel. + NETWORK_CATEGORIZED_CONTENT (20200): + Non-security related: URL has category like + gambling or porn. + NETWORK_DENIAL_OF_SERVICE (20300): + DoS, DDoS. + NETWORK_RECON (20400): + Port scan detected by an IDS, probing of web + app. + NETWORK_COMMAND_AND_CONTROL (20500): + If we know this is a C&C channel. + ACL_VIOLATION (30000): + Unauthorized access attempted, including + attempted access to files, web services, + processes, web objects, etc. + AUTH_VIOLATION (40000): + Authentication failed (e.g. bad password or + bad 2-factor authentication). + EXPLOIT (50000): + Exploit: For all manner of exploits including + attempted overflows, bad protocol encodings, + ROP, SQL injection, etc. For both network and + host- based exploits. + DATA_EXFILTRATION (60000): + DLP: Sensitive data transmission, copy to + thumb drive. + DATA_AT_REST (60100): + DLP: Sensitive data found at rest in a scan. + DATA_DESTRUCTION (60200): + Attempt to destroy/delete data. + TOR_EXIT_NODE (60300): + TOR Exit Nodes. + MAIL_SPAM (70000): + Spam email, message, etc. + MAIL_PHISHING (70100): + Phishing email, chat messages, etc. + MAIL_SPOOFING (70200): + Spoofed source email address, etc. + POLICY_VIOLATION (80000): + Security-related policy violation (e.g. + firewall/proxy/HIPS rule violated, NAC block + action). + SOCIAL_ENGINEERING (90001): + Threats which manipulate to break normal + security procedures. + PHISHING (90002): + Phishing pages, pops, https phishing etc. + """ + + UNKNOWN_CATEGORY = 0 + SOFTWARE_MALICIOUS = 10000 + SOFTWARE_SUSPICIOUS = 10100 + SOFTWARE_PUA = 10200 + NETWORK_MALICIOUS = 20000 + NETWORK_SUSPICIOUS = 20100 + NETWORK_CATEGORIZED_CONTENT = 20200 + NETWORK_DENIAL_OF_SERVICE = 20300 + NETWORK_RECON = 20400 + NETWORK_COMMAND_AND_CONTROL = 20500 + ACL_VIOLATION = 30000 + AUTH_VIOLATION = 40000 + EXPLOIT = 50000 + DATA_EXFILTRATION = 60000 + DATA_AT_REST = 60100 + DATA_DESTRUCTION = 60200 + TOR_EXIT_NODE = 60300 + MAIL_SPAM = 70000 + MAIL_PHISHING = 70100 + MAIL_SPOOFING = 70200 + POLICY_VIOLATION = 80000 + SOCIAL_ENGINEERING = 90001 + PHISHING = 90002 + + class AlertState(proto.Enum): + r"""The type of alerting set up for a security result. + + Values: + UNSPECIFIED (0): + The security result type is not known. + NOT_ALERTING (1): + The security result is not an alert. + ALERTING (2): + The security result is an alert. + """ + + UNSPECIFIED = 0 + NOT_ALERTING = 1 + ALERTING = 2 + + class Action(proto.Enum): + r"""Enum representing different possible actions taken by the product + that created the event. Google SecOps classifies: + + - ALLOW and ALLOW_WITH_MODIFICATION actions as "successful". + - BLOCK, QUARANTINE, FAIL, and CHALLENGE actions as "failed". This + includes all corresponding metrics (for example, + AUTH_ATTEMPTS_FAIL, FILE_EXECUTIONS_FAIL, RESOURCE_READ_FAIL, and + so on). + - UNKNOWN_ACTION actions as neither "successful" nor "failed", + because, for example, logs might not provide information whether a + login event occurred but some kind of "unknown" error was issued + nonetheless. + + Values: + UNKNOWN_ACTION (0): + The default action. + ALLOW (1): + Allowed. + BLOCK (2): + Blocked. + ALLOW_WITH_MODIFICATION (3): + Strip, modify something + (e.g. File or email was disinfected or rewritten + and still forwarded). + QUARANTINE (4): + Put somewhere for later analysis (does NOT + imply block). + FAIL (5): + Failed (e.g. the event was allowed but + failed). + CHALLENGE (6): + Challenged (e.g. the user was challenged by a + Captcha, 2FA). + """ + + UNKNOWN_ACTION = 0 + ALLOW = 1 + BLOCK = 2 + ALLOW_WITH_MODIFICATION = 3 + QUARANTINE = 4 + FAIL = 5 + CHALLENGE = 6 + + class ProductSeverity(proto.Enum): + r"""Defined by the product + + Values: + UNKNOWN_SEVERITY (0): + The default severity level. + INFORMATIONAL (100): + Info severity. + ERROR (150): + An error. + NONE (101): + No malicious result. + LOW (200): + Low-severity malicious result. + MEDIUM (300): + Medium-severity malicious result. + HIGH (400): + High-severity malicious result. + CRITICAL (500): + Critical-severity malicious result. + """ + + UNKNOWN_SEVERITY = 0 + INFORMATIONAL = 100 + ERROR = 150 + NONE = 101 + LOW = 200 + MEDIUM = 300 + HIGH = 400 + CRITICAL = 500 + + class ProductConfidence(proto.Enum): + r"""A level of confidence in the result. + + Values: + UNKNOWN_CONFIDENCE (0): + The default confidence level. + LOW_CONFIDENCE (200): + Low confidence. + MEDIUM_CONFIDENCE (300): + Medium confidence. + HIGH_CONFIDENCE (400): + High confidence. + """ + + UNKNOWN_CONFIDENCE = 0 + LOW_CONFIDENCE = 200 + MEDIUM_CONFIDENCE = 300 + HIGH_CONFIDENCE = 400 + + class ProductPriority(proto.Enum): + r"""A product priority level. + + Values: + UNKNOWN_PRIORITY (0): + Default priority level. + LOW_PRIORITY (200): + Low priority. + MEDIUM_PRIORITY (300): + Medium priority. + HIGH_PRIORITY (400): + High priority. + """ + + UNKNOWN_PRIORITY = 0 + LOW_PRIORITY = 200 + MEDIUM_PRIORITY = 300 + HIGH_PRIORITY = 400 + + class ThreatStatus(proto.Enum): + r"""Vendor-specific information about the status of a threat + (ITW). + + Values: + THREAT_STATUS_UNSPECIFIED (0): + Default threat status + ACTIVE (1): + Active threat. + CLEARED (2): + Cleared threat. + FALSE_POSITIVE (3): + False positive. + """ + + THREAT_STATUS_UNSPECIFIED = 0 + ACTIVE = 1 + CLEARED = 2 + FALSE_POSITIVE = 3 + + class ThreatCollectionType(proto.Enum): + r"""Different Types of threat collections currently supported. + + Values: + THREAT_COLLECTION_TYPE_UNSPECIFIED (0): + Threat collection type is unspecified. + CAMPAIGN (1): + Threat collection type is campaign. + REPORT (2): + Threat collection type is report. + """ + + THREAT_COLLECTION_TYPE_UNSPECIFIED = 0 + CAMPAIGN = 1 + REPORT = 2 + + class Association(proto.Message): + r"""Associations represents different metadata about malware and + threat actors involved with an IoC. + + Attributes: + id (str): + Unique association id generated by mandiant. + country_code (MutableSequence[str]): + Country from which the threat actor/ malware + is originated. + type_ (google.backstory.types.SecurityResult.Association.AssociationType): + Signifies the type of association. + name (str): + Name of the threat actor/malware. + description (str): + Human readable description about the + association. + role (str): + Role of the malware. Not applicable for + threat actor. + source_country (str): + Name of the country the threat originated + from. + alias (MutableSequence[google.backstory.types.SecurityResult.Association.AssociationAlias]): + Different aliases of the threat actor given + by different sources. + first_reference_time (google.protobuf.timestamp_pb2.Timestamp): + First time the threat actor was referenced or + seen. + last_reference_time (google.protobuf.timestamp_pb2.Timestamp): + Last time the threat actor was referenced or + seen. + industries_affected (MutableSequence[str]): + List of industries the threat actor affects. + associated_actors (MutableSequence[google.backstory.types.SecurityResult.Association]): + List of associated threat actors for a + malware. Not applicable for threat actors. + region_code (google.backstory.types.Location): + Name of the country, the threat is + originating from. + sponsor_region (google.backstory.types.Location): + Sponsor region of the threat actor. + targeted_regions (MutableSequence[google.backstory.types.Location]): + Targeted regions. + tags (MutableSequence[str]): + Tags. + """ + + class AssociationType(proto.Enum): + r"""Represents different possible Association types. Can be + threat or malware. Used to represent Mandiant threat + intelligence. + + Values: + ASSOCIATION_TYPE_UNSPECIFIED (0): + The default Association Type. + THREAT_ACTOR (1): + Association type Threat actor. + MALWARE (2): + Association type Malware. + SOFTWARE_TOOLKIT (3): + Association type Software toolkit. + """ + + ASSOCIATION_TYPE_UNSPECIFIED = 0 + THREAT_ACTOR = 1 + MALWARE = 2 + SOFTWARE_TOOLKIT = 3 + + class AssociationAlias(proto.Message): + r"""Association Alias used to represent Mandiant Threat + Intelligence. + + Attributes: + name (str): + Name of the alias. + company (str): + Name of the provider who gave the + association's name. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + company: str = proto.Field( + proto.STRING, + number=2, + ) + + id: str = proto.Field( + proto.STRING, + number=1, + ) + country_code: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + type_: "SecurityResult.Association.AssociationType" = proto.Field( + proto.ENUM, + number=3, + enum="SecurityResult.Association.AssociationType", + ) + name: str = proto.Field( + proto.STRING, + number=4, + ) + description: str = proto.Field( + proto.STRING, + number=5, + ) + role: str = proto.Field( + proto.STRING, + number=6, + ) + source_country: str = proto.Field( + proto.STRING, + number=7, + ) + alias: MutableSequence["SecurityResult.Association.AssociationAlias"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=8, + message="SecurityResult.Association.AssociationAlias", + ) + ) + first_reference_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=9, + message=timestamp_pb2.Timestamp, + ) + last_reference_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=10, + message=timestamp_pb2.Timestamp, + ) + industries_affected: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=11, + ) + associated_actors: MutableSequence["SecurityResult.Association"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=12, + message="SecurityResult.Association", + ) + ) + region_code: "Location" = proto.Field( + proto.MESSAGE, + number=13, + message="Location", + ) + sponsor_region: "Location" = proto.Field( + proto.MESSAGE, + number=14, + message="Location", + ) + targeted_regions: MutableSequence["Location"] = proto.RepeatedField( + proto.MESSAGE, + number=15, + message="Location", + ) + tags: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=16, + ) + + class Source(proto.Message): + r"""Deprecated. + Information about the threat intelligence source. These fields + are used to model Mandiant sources. + + Attributes: + name (str): + Name of the IoC source. + benign_count (int): + Count of responses where this IoC was marked + benign. + malicious_count (int): + Count of responses where this IoC was marked + malicious. + quality (google.backstory.types.SecurityResult.ProductConfidence): + Quality of the IoC mapping extracted from the + source. + response_count (int): + Total response count from this source. + source_count (int): + Number of sources from which intelligence was + extracted. + threat_intelligence_sources (MutableSequence[google.backstory.types.SecurityResult.Source]): + Different threat intelligence sources from + which IoC info was extracted. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + benign_count: int = proto.Field( + proto.INT32, + number=2, + ) + malicious_count: int = proto.Field( + proto.INT32, + number=3, + ) + quality: "SecurityResult.ProductConfidence" = proto.Field( + proto.ENUM, + number=4, + enum="SecurityResult.ProductConfidence", + ) + response_count: int = proto.Field( + proto.INT32, + number=5, + ) + source_count: int = proto.Field( + proto.INT32, + number=6, + ) + threat_intelligence_sources: MutableSequence["SecurityResult.Source"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=7, + message="SecurityResult.Source", + ) + ) + + class ProviderMLVerdict(proto.Message): + r"""Deprecated. + MLVerdict result provided from threat providers, like Mandiant. + These fields are used to model Mandiant sources. + + Attributes: + source_provider (str): + Source provider giving the ML verdict. + benign_count (int): + Count of responses where this IoC was marked + benign. + malicious_count (int): + Count of responses where this IoC was marked + malicious. + confidence_score (int): + Confidence score of the verdict. + mandiant_sources (MutableSequence[google.backstory.types.SecurityResult.Source]): + List of mandiant sources from which the + verdict was generated. + third_party_sources (MutableSequence[google.backstory.types.SecurityResult.Source]): + List of third-party sources from which the + verdict was generated. + """ + + source_provider: str = proto.Field( + proto.STRING, + number=1, + ) + benign_count: int = proto.Field( + proto.INT32, + number=2, + ) + malicious_count: int = proto.Field( + proto.INT32, + number=3, + ) + confidence_score: int = proto.Field( + proto.INT32, + number=4, + ) + mandiant_sources: MutableSequence["SecurityResult.Source"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=5, + message="SecurityResult.Source", + ) + ) + third_party_sources: MutableSequence["SecurityResult.Source"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=6, + message="SecurityResult.Source", + ) + ) + + class AnalystVerdict(proto.Message): + r"""Verdict provided by the human analyst. These fields are used + to model Mandiant sources. + + Attributes: + confidence_score (int): + Confidence score of the verdict. + verdict_time (google.protobuf.timestamp_pb2.Timestamp): + Timestamp at which the verdict was generated. + verdict_response (google.backstory.types.SecurityResult.VerdictResponse): + Details of the verdict. + """ + + confidence_score: int = proto.Field( + proto.INT32, + number=1, + ) + verdict_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + verdict_response: "SecurityResult.VerdictResponse" = proto.Field( + proto.ENUM, + number=3, + enum="SecurityResult.VerdictResponse", + ) + + class IoCStats(proto.Message): + r"""Information about the threat intelligence source. These + fields are used to model Mandiant sources. + + Attributes: + ioc_stats_type (google.backstory.types.SecurityResult.IoCStatsType): + Describes the source of the IoCStat. + first_level_source (str): + Name of first level IoC source, for example + Mandiant or a third-party. + second_level_source (str): + Name of the second-level IoC source, for + example Crowdsourced Threat Analysis or + Knowledge Graph. + benign_count (int): + Count of responses where the IoC was + identified as benign. + quality (google.backstory.types.SecurityResult.ProductConfidence): + Level of confidence in the IoC mapping + extracted from the source. + malicious_count (int): + Count of responses where the IoC was + identified as malicious. + response_count (int): + Total number of response from the source. + source_count (int): + Number of sources from which information was + extracted. + """ + + ioc_stats_type: "SecurityResult.IoCStatsType" = proto.Field( + proto.ENUM, + number=1, + enum="SecurityResult.IoCStatsType", + ) + first_level_source: str = proto.Field( + proto.STRING, + number=2, + ) + second_level_source: str = proto.Field( + proto.STRING, + number=3, + ) + benign_count: int = proto.Field( + proto.INT32, + number=4, + ) + quality: "SecurityResult.ProductConfidence" = proto.Field( + proto.ENUM, + number=5, + enum="SecurityResult.ProductConfidence", + ) + malicious_count: int = proto.Field( + proto.INT32, + number=6, + ) + response_count: int = proto.Field( + proto.INT32, + number=7, + ) + source_count: int = proto.Field( + proto.INT32, + number=8, + ) + + class VerdictInfo(proto.Message): + r"""Describes the threat verdict provided by human analysts and + machine learning models. These fields are used to model Mandiant + sources. + + Attributes: + source_count (int): + Number of sources from which intelligence was + extracted. + response_count (int): + Total response count across all sources. + neighbour_influence (str): + Describes the near neighbor influence of the + verdict. + verdict_type (google.backstory.types.SecurityResult.VerdictType): + Type of verdict. + source_provider (str): + Source provider giving the machine learning + verdict. + benign_count (int): + Count of responses where this IoC was marked + as benign. + malicious_count (int): + Count of responses where this IoC was marked + as malicious. + confidence_score (int): + Confidence score of the verdict. + ioc_stats (MutableSequence[google.backstory.types.SecurityResult.IoCStats]): + List of IoCStats from which the verdict was + generated. + verdict_time (google.protobuf.timestamp_pb2.Timestamp): + Timestamp when the verdict was generated. + verdict_response (google.backstory.types.SecurityResult.VerdictResponse): + Details about the verdict. + global_customer_count (int): + Global customer count over the last 30 days + global_hits_count (int): + Global hit count over the last 30 days. + pwn (bool): + Whether one or more Mandiant incident + response customers had this indicator in their + environment. + category_details (str): + Tags related to the verdict. + pwn_first_tagged_time (google.protobuf.timestamp_pb2.Timestamp): + The timestamp of the first time a pwn was + associated to this entity. + """ + + source_count: int = proto.Field( + proto.INT32, + number=1, + ) + response_count: int = proto.Field( + proto.INT32, + number=2, + ) + neighbour_influence: str = proto.Field( + proto.STRING, + number=3, + ) + verdict_type: "SecurityResult.VerdictType" = proto.Field( + proto.ENUM, + number=4, + enum="SecurityResult.VerdictType", + ) + source_provider: str = proto.Field( + proto.STRING, + number=5, + ) + benign_count: int = proto.Field( + proto.INT32, + number=6, + ) + malicious_count: int = proto.Field( + proto.INT32, + number=7, + ) + confidence_score: int = proto.Field( + proto.INT32, + number=8, + ) + ioc_stats: MutableSequence["SecurityResult.IoCStats"] = proto.RepeatedField( + proto.MESSAGE, + number=9, + message="SecurityResult.IoCStats", + ) + verdict_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=11, + message=timestamp_pb2.Timestamp, + ) + verdict_response: "SecurityResult.VerdictResponse" = proto.Field( + proto.ENUM, + number=12, + enum="SecurityResult.VerdictResponse", + ) + global_customer_count: int = proto.Field( + proto.INT32, + number=13, + ) + global_hits_count: int = proto.Field( + proto.INT32, + number=14, + ) + pwn: bool = proto.Field( + proto.BOOL, + number=15, + ) + category_details: str = proto.Field( + proto.STRING, + number=16, + ) + pwn_first_tagged_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=17, + message=timestamp_pb2.Timestamp, + ) + + class Verdict(proto.Message): + r"""Deprecated. + Encapsulates the threat verdict provided by human analysts and + ML models. These fields are used to model Mandiant sources. + + Attributes: + source_count (int): + Number of sources from which intelligence was + extracted. + response_count (int): + Total response count across all sources. + neighbour_influence (str): + Describes the neighbour influence of the + verdict. + verdict (google.backstory.types.SecurityResult.ProviderMLVerdict): + ML Verdict provided by sources like Mandiant. + analyst_verdict (google.backstory.types.SecurityResult.AnalystVerdict): + Human analyst verdict provided by sources + like Mandiant. + """ + + source_count: int = proto.Field( + proto.INT32, + number=1, + ) + response_count: int = proto.Field( + proto.INT32, + number=2, + ) + neighbour_influence: str = proto.Field( + proto.STRING, + number=3, + ) + verdict: "SecurityResult.ProviderMLVerdict" = proto.Field( + proto.MESSAGE, + number=4, + message="SecurityResult.ProviderMLVerdict", + ) + analyst_verdict: "SecurityResult.AnalystVerdict" = proto.Field( + proto.MESSAGE, + number=5, + message="SecurityResult.AnalystVerdict", + ) + + class ThreatCollectionItem(proto.Message): + r"""Threat Collection that is either a threat campaign or a + threat report. + + Attributes: + id (str): + The ID of the threat collection. + type_ (google.backstory.types.SecurityResult.ThreatCollectionType): + The type of threat collection (e.g., + "campaign"). + alt_names (MutableSequence[str]): + The name of the threat collection. + """ + + id: str = proto.Field( + proto.STRING, + number=1, + ) + type_: "SecurityResult.ThreatCollectionType" = proto.Field( + proto.ENUM, + number=2, + enum="SecurityResult.ThreatCollectionType", + ) + alt_names: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + + about: "Noun" = proto.Field( + proto.MESSAGE, + number=1, + message="Noun", + ) + category: MutableSequence[SecurityCategory] = proto.RepeatedField( + proto.ENUM, + number=2, + enum=SecurityCategory, + ) + category_details: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + threat_name: str = proto.Field( + proto.STRING, + number=4, + ) + rule_set: str = proto.Field( + proto.STRING, + number=29, + ) + rule_set_display_name: str = proto.Field( + proto.STRING, + number=30, + ) + ruleset_category_display_name: str = proto.Field( + proto.STRING, + number=41, + ) + rule_id: str = proto.Field( + proto.STRING, + number=16, + ) + rule_name: str = proto.Field( + proto.STRING, + number=5, + ) + display_name: str = proto.Field( + proto.STRING, + number=49, + ) + rule_version: str = proto.Field( + proto.STRING, + number=20, + ) + rule_type: str = proto.Field( + proto.STRING, + number=22, + ) + rule_author: str = proto.Field( + proto.STRING, + number=25, + ) + rule_labels: MutableSequence["Label"] = proto.RepeatedField( + proto.MESSAGE, + number=26, + message="Label", + ) + alert_state: AlertState = proto.Field( + proto.ENUM, + number=21, + enum=AlertState, + ) + detection_fields: MutableSequence["Label"] = proto.RepeatedField( + proto.MESSAGE, + number=23, + message="Label", + ) + outcomes: MutableSequence["Label"] = proto.RepeatedField( + proto.MESSAGE, + number=28, + message="Label", + ) + variables: MutableMapping[str, "FindingVariable"] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=44, + message="FindingVariable", + ) + summary: str = proto.Field( + proto.STRING, + number=6, + ) + description: str = proto.Field( + proto.STRING, + number=7, + ) + action: MutableSequence[Action] = proto.RepeatedField( + proto.ENUM, + number=8, + enum=Action, + ) + action_details: str = proto.Field( + proto.STRING, + number=19, + ) + severity: ProductSeverity = proto.Field( + proto.ENUM, + number=9, + enum=ProductSeverity, + ) + confidence: ProductConfidence = proto.Field( + proto.ENUM, + number=10, + enum=ProductConfidence, + ) + priority: ProductPriority = proto.Field( + proto.ENUM, + number=11, + enum=ProductPriority, + ) + risk_score: float = proto.Field( + proto.FLOAT, + number=31, + ) + confidence_score: float = proto.Field( + proto.FLOAT, + number=42, + ) + analytics_metadata: MutableSequence["AnalyticsMetadata"] = proto.RepeatedField( + proto.MESSAGE, + number=43, + message="AnalyticsMetadata", + ) + severity_details: str = proto.Field( + proto.STRING, + number=12, + ) + confidence_details: str = proto.Field( + proto.STRING, + number=13, + ) + priority_details: str = proto.Field( + proto.STRING, + number=14, + ) + url_back_to_product: str = proto.Field( + proto.STRING, + number=15, + ) + threat_id: str = proto.Field( + proto.STRING, + number=17, + ) + threat_feed_name: str = proto.Field( + proto.STRING, + number=27, + ) + threat_id_namespace: gb_id.Id.Namespace = proto.Field( + proto.ENUM, + number=24, + enum=gb_id.Id.Namespace, + ) + threat_status: ThreatStatus = proto.Field( + proto.ENUM, + number=18, + enum=ThreatStatus, + ) + attack_details: "AttackDetails" = proto.Field( + proto.MESSAGE, + number=32, + message="AttackDetails", + ) + first_discovered_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=33, + message=timestamp_pb2.Timestamp, + ) + associations: MutableSequence[Association] = proto.RepeatedField( + proto.MESSAGE, + number=34, + message=Association, + ) + campaigns: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=35, + ) + reports: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=46, + ) + verdict: Verdict = proto.Field( + proto.MESSAGE, + number=36, + message=Verdict, + ) + last_updated_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=37, + message=timestamp_pb2.Timestamp, + ) + verdict_info: MutableSequence[VerdictInfo] = proto.RepeatedField( + proto.MESSAGE, + number=38, + message=VerdictInfo, + ) + threat_verdict: "ThreatVerdict" = proto.Field( + proto.ENUM, + number=39, + enum="ThreatVerdict", + ) + last_discovered_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=40, + message=timestamp_pb2.Timestamp, + ) + detection_depth: int = proto.Field( + proto.INT64, + number=47, + ) + threat_collections: MutableSequence[ThreatCollectionItem] = proto.RepeatedField( + proto.MESSAGE, + number=48, + message=ThreatCollectionItem, + ) + + +class PeFileMetadata(proto.Message): + r"""Metadata about a Microsoft Windows Portable Executable. + + Attributes: + import_hash (str): + Hash of PE imports. + """ + + import_hash: str = proto.Field( + proto.STRING, + number=1, + ) + + +class FileMetadata(proto.Message): + r"""Metadata about a file. + Place metadata about different file types here, for example data + from the Microsoft Windows VersionInfo block or digital signer + details. Use a different sub-message per file type. + + Attributes: + pe (google.backstory.types.PeFileMetadata): + Metadata for Microsoft Windows PE files. + Deprecate PeFileMetadata in favor of single File + proto. + """ + + pe: "PeFileMetadata" = proto.Field( + proto.MESSAGE, + number=1, + message="PeFileMetadata", + ) + + +class File(proto.Message): + r"""Information about a file. + + Attributes: + sha256 (str): + The SHA256 hash of the file, as a hex-encoded + string. This field can be used as an entity + indicator for file entities. + md5 (str): + The MD5 hash of the file, as a hex-encoded + string. This field can be used as an entity + indicator for file entities. + sha1 (str): + The SHA1 hash of the file, as a hex-encoded + string. This field can be used as an entity + indicator for file entities. + size (int): + The size of the file in bytes. + full_path (str): + The full path identifying the location of the + file on the system. This field can be used as an + entity indicator for file entities. + mime_type (str): + The MIME (Multipurpose Internet Mail + Extensions) type of the file, for example "PE", + "PDF", or "powershell script". + file_metadata (google.backstory.types.FileMetadata): + Metadata associated with the file. + Deprecate FileMetadata in favor of using fields + in File. + security_result (google.backstory.types.SecurityResult): + Google Cloud Threat Intelligence (GCTI) + security result for the file including threat + context and detection metadata. + pe_file (google.backstory.types.FileMetadataPE): + Metadata about the Portable Executable (PE) + file. + ssdeep (str): + Ssdeep of the file + vhash (str): + Vhash of the file. + ahash (str): + Deprecated. Use authentihash instead. + authentihash (str): + Authentihash of the file. + symhash (str): + SymHash of the file. Used for Mach-O (e.g. + MacOS) binaries, to identify similar files based + on their symbol table. + prefetch_file_metadata (google.backstory.types.PrefetchFileMetadata): + Metadata about the prefetch file. + file_type (google.backstory.types.File.FileType): + FileType field. + capabilities_tags (MutableSequence[str]): + Capabilities tags. + names (MutableSequence[str]): + Names fields. + tags (MutableSequence[str]): + Tags for the file. + last_modification_time (google.protobuf.timestamp_pb2.Timestamp): + Timestamp when the file was last updated. + create_time (google.protobuf.timestamp_pb2.Timestamp): + Timestamp when the file was created. + last_access_time (google.protobuf.timestamp_pb2.Timestamp): + Timestamp when the file was accessed. + prevalence (google.backstory.types.Prevalence): + Prevalence of the file hash in the customer's + environment. + first_seen_time (google.protobuf.timestamp_pb2.Timestamp): + Timestamp the file was first seen in the + customer's environment. + last_seen_time (google.protobuf.timestamp_pb2.Timestamp): + Timestamp the file was last seen in the + customer's environment. + stat_mode (int): + The mode of the file. A bit string indicating + the permissions and privileges of the file. + stat_inode (int): + The file identifier. Unique identifier of + object within a file system. + stat_dev (int): + The file system identifier to which the + object belongs. + stat_nlink (int): + Number of links to file. + stat_flags (int): + User defined flags for file. + last_analysis_time (google.protobuf.timestamp_pb2.Timestamp): + Timestamp the file was last analysed. + embedded_urls (MutableSequence[str]): + Embedded urls found in the file. + embedded_domains (MutableSequence[str]): + Embedded domains found in the file. + embedded_ips (MutableSequence[str]): + Embedded IP addresses found in the file. + exif_info (google.backstory.types.ExifInfo): + Exif metadata from different file formats + extracted by exiftool. + signature_info (google.backstory.types.SignatureInfo): + File signature information extracted from + different tools. + pdf_info (google.backstory.types.PDFInfo): + Information about the PDF file structure. + first_submission_time (google.protobuf.timestamp_pb2.Timestamp): + First submission time of the file. + last_submission_time (google.protobuf.timestamp_pb2.Timestamp): + Last submission time of the file. + main_icon (google.backstory.types.Favicon): + Icon's relevant hashes. + ntfs (google.backstory.types.NtfsFileMetadata): + NTFS metadata. + app_compat_cache (google.backstory.types.AppCompatMetadata): + Windows AppCompatCache (Application + Compatibility) metadata. + """ + + class FileType(proto.Enum): + r"""The file type, for example Microsoft Windows executable. + + Values: + FILE_TYPE_UNSPECIFIED (0): + File type is UNSPECIFIED. + FILE_TYPE_PE_EXE (1): + File type is PE_EXE. + FILE_TYPE_PE_DLL (2): + Although DLLs are actually portable executables, this value + enables the file type to be identified separately. File type + is PE_DLL. + FILE_TYPE_MSI (3): + File type is MSI. + FILE_TYPE_NE_EXE (10): + File type is NE_EXE. + FILE_TYPE_NE_DLL (11): + File type is NE_DLL. + FILE_TYPE_DOS_EXE (20): + File type is DOS_EXE. + FILE_TYPE_DOS_COM (21): + File type is DOS_COM. + FILE_TYPE_COFF (30): + File type is COFF. + FILE_TYPE_ELF (31): + File type is ELF. + FILE_TYPE_LINUX_KERNEL (32): + File type is LINUX_KERNEL. + FILE_TYPE_RPM (33): + File type is RPM. + FILE_TYPE_LINUX (34): + File type is LINUX. + FILE_TYPE_MACH_O (35): + File type is MACH_O. + FILE_TYPE_JAVA_BYTECODE (36): + File type is JAVA_BYTECODE. + FILE_TYPE_DMG (37): + File type is DMG. + FILE_TYPE_DEB (38): + File type is DEB. + FILE_TYPE_PKG (39): + File type is PKG. + FILE_TYPE_PYC (40): + File type is PYC. + FILE_TYPE_LNK (50): + File type is LNK. + FILE_TYPE_DESKTOP_ENTRY (51): + File type is DESKTOP_ENTRY. + FILE_TYPE_JPEG (100): + File type is JPEG. + FILE_TYPE_TIFF (101): + File type is TIFF. + FILE_TYPE_GIF (102): + File type is GIF. + FILE_TYPE_PNG (103): + File type is PNG. + FILE_TYPE_BMP (104): + File type is BMP. + FILE_TYPE_GIMP (105): + File type is GIMP. + FILE_TYPE_IN_DESIGN (106): + File type is Adobe InDesign. + FILE_TYPE_PSD (107): + File type is PSD. + Adobe Photoshop. + FILE_TYPE_TARGA (108): + File type is TARGA. + FILE_TYPE_XWD (109): + File type is XWD. + FILE_TYPE_DIB (110): + File type is DIB. + FILE_TYPE_JNG (111): + File type is JNG. + FILE_TYPE_ICO (112): + File type is ICO. + FILE_TYPE_FPX (113): + File type is FPX. + FILE_TYPE_EPS (114): + File type is EPS. + FILE_TYPE_SVG (115): + File type is SVG. + FILE_TYPE_EMF (116): + File type is EMF. + FILE_TYPE_WEBP (117): + File type is WEBP. + FILE_TYPE_DWG (118): + File type is DWG. + FILE_TYPE_DXF (119): + File type is DXF. + FILE_TYPE_THREEDS (120): + File type is 3DS. + FILE_TYPE_OGG (150): + File type is OGG. + FILE_TYPE_FLC (151): + File type is FLC. + FILE_TYPE_FLI (152): + File type is FLI. + FILE_TYPE_MP3 (153): + File type is MP3. + FILE_TYPE_FLAC (154): + File type is FLAC. + FILE_TYPE_WAV (155): + File type is WAV. + FILE_TYPE_MIDI (156): + File type is MIDI. + FILE_TYPE_AVI (157): + File type is AVI. + FILE_TYPE_MPEG (158): + File type is MPEG. + FILE_TYPE_QUICKTIME (159): + File type is QUICKTIME. + FILE_TYPE_ASF (160): + File type is ASF. + FILE_TYPE_DIVX (161): + File type is DIVX. + FILE_TYPE_FLV (162): + File type is FLV. + FILE_TYPE_WMA (163): + File type is WMA. + FILE_TYPE_WMV (164): + File type is WMV. + FILE_TYPE_RM (165): + File type is RM. + RealMedia type. + FILE_TYPE_MOV (166): + File type is MOV. + FILE_TYPE_MP4 (167): + File type is MP4. + FILE_TYPE_T3GP (168): + File type is T3GP. + FILE_TYPE_WEBM (169): + File type is WEBM. + FILE_TYPE_MKV (170): + File type is MKV. + FILE_TYPE_PDF (200): + File type is PDF. + FILE_TYPE_PS (201): + File type is PS. + FILE_TYPE_DOC (202): + File type is DOC. + FILE_TYPE_DOCX (203): + File type is DOCX. + FILE_TYPE_PPT (204): + File type is PPT. + FILE_TYPE_PPTX (205): + File type is PPTX. + FILE_TYPE_XLS (206): + File type is XLS. + FILE_TYPE_XLSX (207): + File type is XLSX. + FILE_TYPE_RTF (208): + File type is RTF. + FILE_TYPE_PPSX (209): + File type is PPSX. + FILE_TYPE_ODP (250): + File type is ODP. + FILE_TYPE_ODS (251): + File type is ODS. + FILE_TYPE_ODT (252): + File type is ODT. + FILE_TYPE_HWP (253): + File type is HWP. + FILE_TYPE_GUL (254): + File type is GUL. + FILE_TYPE_ODF (255): + File type is ODF. + FILE_TYPE_ODG (256): + File type is ODG. + FILE_TYPE_ONE_NOTE (257): + File type is ONE_NOTE. + FILE_TYPE_OOXML (258): + File type is OOXML. + FILE_TYPE_SLK (259): + File type is SLK. + FILE_TYPE_EBOOK (260): + File type is EBOOK. + FILE_TYPE_LATEX (261): + File type is LATEX. + FILE_TYPE_TTF (262): + File type is TTF. + FILE_TYPE_EOT (263): + File type is EOT. + FILE_TYPE_WOFF (264): + File type is WOFF. + FILE_TYPE_CHM (265): + File type is CHM. + FILE_TYPE_ZIP (300): + File type is ZIP. + FILE_TYPE_GZIP (301): + File type is GZIP. + FILE_TYPE_BZIP (302): + File type is BZIP. + FILE_TYPE_RZIP (303): + File type is RZIP. + FILE_TYPE_DZIP (304): + File type is DZIP. + FILE_TYPE_SEVENZIP (305): + File type is SEVENZIP. + FILE_TYPE_CAB (306): + File type is CAB. + FILE_TYPE_JAR (307): + File type is JAR. + FILE_TYPE_RAR (308): + File type is RAR. + FILE_TYPE_MSCOMPRESS (309): + File type is MSCOMPRESS. + FILE_TYPE_ACE (310): + File type is ACE. + FILE_TYPE_ARC (311): + File type is ARC. + FILE_TYPE_ARJ (312): + File type is ARJ. + FILE_TYPE_ASD (313): + File type is ASD. + FILE_TYPE_BLACKHOLE (314): + File type is BLACKHOLE. + FILE_TYPE_KGB (315): + File type is KGB. + FILE_TYPE_ZLIB (316): + File type is ZLIB. + FILE_TYPE_TAR (317): + File type is TAR. + FILE_TYPE_ZST (318): + File type is ZST. + FILE_TYPE_LZFSE (319): + File type is LZFSE. + FILE_TYPE_PYTHON_WHL (320): + File type is PYTHON_WHL. + FILE_TYPE_PYTHON_PKG (321): + File type is PYTHON_PKG. + FILE_TYPE_MSIX (322): + File type is MSIX, new Windows app package + format. + FILE_TYPE_TEXT (400): + File type is TEXT. + FILE_TYPE_SCRIPT (401): + File type is SCRIPT. + FILE_TYPE_PHP (402): + File type is PHP. + FILE_TYPE_PYTHON (403): + File type is PYTHON. + FILE_TYPE_PERL (404): + File type is PERL. + FILE_TYPE_RUBY (405): + File type is RUBY. + FILE_TYPE_C (406): + File type is C. + FILE_TYPE_CPP (407): + File type is CPP. + FILE_TYPE_JAVA (408): + File type is JAVA. + FILE_TYPE_SHELLSCRIPT (409): + File type is SHELLSCRIPT. + FILE_TYPE_PASCAL (410): + File type is PASCAL. + FILE_TYPE_AWK (411): + File type is AWK. + FILE_TYPE_DYALOG (412): + File type is DYALOG. + FILE_TYPE_FORTRAN (413): + File type is FORTRAN. + FILE_TYPE_JAVASCRIPT (414): + File type is JAVASCRIPT. + FILE_TYPE_POWERSHELL (415): + File type is POWERSHELL. + FILE_TYPE_VBA (416): + File type is VBA. + FILE_TYPE_M4 (417): + File type is M4. + FILE_TYPE_OBJETIVEC (418): + File type is OBJETIVEC. + FILE_TYPE_JMOD (419): + File type is JMOD. + FILE_TYPE_MAKEFILE (420): + File type is MAKEFILE. + FILE_TYPE_INI (421): + File type is INI. + FILE_TYPE_CLJ (422): + File type is CLJ. + FILE_TYPE_PDB (425): + File type is PDB. + FILE_TYPE_SQL (426): + File type is SQL. + FILE_TYPE_NEKO (427): + File type is NEKO. + FILE_TYPE_WER (428): + File type is WER. + FILE_TYPE_GOLANG (429): + File type is GOLANG. + FILE_TYPE_M3U (430): + File type is M3U. + FILE_TYPE_BAT (431): + File type is BAT, Windows .bat/.cmd (old + files are tagged as SHELLSCRIPT). + FILE_TYPE_MSC (432): + File type is MSC, Microsoft Management + Console (MMC). + FILE_TYPE_RDP (433): + File type is RDP, Microsoft Remote Desktop + Protocol (RDP) file. + FILE_TYPE_SYMBIAN (500): + File type is SYMBIAN. + FILE_TYPE_PALMOS (501): + File type is PALMOS. + FILE_TYPE_WINCE (502): + File type is WINCE. + FILE_TYPE_ANDROID (503): + File type is ANDROID. + FILE_TYPE_IPHONE (504): + File type is IPHONE. + FILE_TYPE_HTML (600): + File type is HTML. + FILE_TYPE_XML (601): + File type is XML. + FILE_TYPE_SWF (602): + File type is SWF. + FILE_TYPE_FLA (603): + File type is FLA. + FILE_TYPE_COOKIE (604): + File type is COOKIE. + FILE_TYPE_TORRENT (605): + File type is TORRENT. + FILE_TYPE_EMAIL_TYPE (606): + File type is EMAIL_TYPE. + FILE_TYPE_OUTLOOK (607): + File type is OUTLOOK. + FILE_TYPE_SGML (608): + File type is SGML. + FILE_TYPE_JSON (609): + File type is JSON. + FILE_TYPE_CSV (610): + File type is CSV. + FILE_TYPE_HTA (611): + File type is HTA (HTML Application). + FILE_TYPE_INTERNET_SHORTCUT (612): + File type is MSHTML .url. + FILE_TYPE_CAP (700): + File type is CAP. + FILE_TYPE_ISOIMAGE (800): + File type is ISOIMAGE. + FILE_TYPE_SQUASHFS (801): + File type is SQUASHFS. + FILE_TYPE_VHD (802): + File type is VHD. + FILE_TYPE_APPLE (1000): + File type is APPLE. + FILE_TYPE_MACINTOSH (1001): + File type is MACINTOSH. + FILE_TYPE_APPLESINGLE (1002): + File type is APPLESINGLE. + FILE_TYPE_APPLEDOUBLE (1003): + File type is APPLEDOUBLE. + FILE_TYPE_MACINTOSH_HFS (1004): + File type is MACINTOSH_HFS. + FILE_TYPE_APPLE_PLIST (1005): + File type is APPLE_PLIST. + FILE_TYPE_MACINTOSH_LIB (1006): + File type is MACINTOSH_LIB. + FILE_TYPE_APPLESCRIPT (1007): + File type is APPLESCRIPT. + FILE_TYPE_APPLESCRIPT_COMPILED (1008): + File type is APPLESCRIPT_COMPILED . + FILE_TYPE_CRX (1100): + File type is CRX. + FILE_TYPE_XPI (1101): + File type is XPI. + FILE_TYPE_ROM (1200): + File type is ROM. + FILE_TYPE_IPS (1201): + File type is IPS. + FILE_TYPE_PEM (1300): + File type is PEM. + FILE_TYPE_PGP (1301): + File type is PGP. + FILE_TYPE_CRT (1302): + File type is CRT. + """ + + FILE_TYPE_UNSPECIFIED = 0 + FILE_TYPE_PE_EXE = 1 + FILE_TYPE_PE_DLL = 2 + FILE_TYPE_MSI = 3 + FILE_TYPE_NE_EXE = 10 + FILE_TYPE_NE_DLL = 11 + FILE_TYPE_DOS_EXE = 20 + FILE_TYPE_DOS_COM = 21 + FILE_TYPE_COFF = 30 + FILE_TYPE_ELF = 31 + FILE_TYPE_LINUX_KERNEL = 32 + FILE_TYPE_RPM = 33 + FILE_TYPE_LINUX = 34 + FILE_TYPE_MACH_O = 35 + FILE_TYPE_JAVA_BYTECODE = 36 + FILE_TYPE_DMG = 37 + FILE_TYPE_DEB = 38 + FILE_TYPE_PKG = 39 + FILE_TYPE_PYC = 40 + FILE_TYPE_LNK = 50 + FILE_TYPE_DESKTOP_ENTRY = 51 + FILE_TYPE_JPEG = 100 + FILE_TYPE_TIFF = 101 + FILE_TYPE_GIF = 102 + FILE_TYPE_PNG = 103 + FILE_TYPE_BMP = 104 + FILE_TYPE_GIMP = 105 + FILE_TYPE_IN_DESIGN = 106 + FILE_TYPE_PSD = 107 + FILE_TYPE_TARGA = 108 + FILE_TYPE_XWD = 109 + FILE_TYPE_DIB = 110 + FILE_TYPE_JNG = 111 + FILE_TYPE_ICO = 112 + FILE_TYPE_FPX = 113 + FILE_TYPE_EPS = 114 + FILE_TYPE_SVG = 115 + FILE_TYPE_EMF = 116 + FILE_TYPE_WEBP = 117 + FILE_TYPE_DWG = 118 + FILE_TYPE_DXF = 119 + FILE_TYPE_THREEDS = 120 + FILE_TYPE_OGG = 150 + FILE_TYPE_FLC = 151 + FILE_TYPE_FLI = 152 + FILE_TYPE_MP3 = 153 + FILE_TYPE_FLAC = 154 + FILE_TYPE_WAV = 155 + FILE_TYPE_MIDI = 156 + FILE_TYPE_AVI = 157 + FILE_TYPE_MPEG = 158 + FILE_TYPE_QUICKTIME = 159 + FILE_TYPE_ASF = 160 + FILE_TYPE_DIVX = 161 + FILE_TYPE_FLV = 162 + FILE_TYPE_WMA = 163 + FILE_TYPE_WMV = 164 + FILE_TYPE_RM = 165 + FILE_TYPE_MOV = 166 + FILE_TYPE_MP4 = 167 + FILE_TYPE_T3GP = 168 + FILE_TYPE_WEBM = 169 + FILE_TYPE_MKV = 170 + FILE_TYPE_PDF = 200 + FILE_TYPE_PS = 201 + FILE_TYPE_DOC = 202 + FILE_TYPE_DOCX = 203 + FILE_TYPE_PPT = 204 + FILE_TYPE_PPTX = 205 + FILE_TYPE_XLS = 206 + FILE_TYPE_XLSX = 207 + FILE_TYPE_RTF = 208 + FILE_TYPE_PPSX = 209 + FILE_TYPE_ODP = 250 + FILE_TYPE_ODS = 251 + FILE_TYPE_ODT = 252 + FILE_TYPE_HWP = 253 + FILE_TYPE_GUL = 254 + FILE_TYPE_ODF = 255 + FILE_TYPE_ODG = 256 + FILE_TYPE_ONE_NOTE = 257 + FILE_TYPE_OOXML = 258 + FILE_TYPE_SLK = 259 + FILE_TYPE_EBOOK = 260 + FILE_TYPE_LATEX = 261 + FILE_TYPE_TTF = 262 + FILE_TYPE_EOT = 263 + FILE_TYPE_WOFF = 264 + FILE_TYPE_CHM = 265 + FILE_TYPE_ZIP = 300 + FILE_TYPE_GZIP = 301 + FILE_TYPE_BZIP = 302 + FILE_TYPE_RZIP = 303 + FILE_TYPE_DZIP = 304 + FILE_TYPE_SEVENZIP = 305 + FILE_TYPE_CAB = 306 + FILE_TYPE_JAR = 307 + FILE_TYPE_RAR = 308 + FILE_TYPE_MSCOMPRESS = 309 + FILE_TYPE_ACE = 310 + FILE_TYPE_ARC = 311 + FILE_TYPE_ARJ = 312 + FILE_TYPE_ASD = 313 + FILE_TYPE_BLACKHOLE = 314 + FILE_TYPE_KGB = 315 + FILE_TYPE_ZLIB = 316 + FILE_TYPE_TAR = 317 + FILE_TYPE_ZST = 318 + FILE_TYPE_LZFSE = 319 + FILE_TYPE_PYTHON_WHL = 320 + FILE_TYPE_PYTHON_PKG = 321 + FILE_TYPE_MSIX = 322 + FILE_TYPE_TEXT = 400 + FILE_TYPE_SCRIPT = 401 + FILE_TYPE_PHP = 402 + FILE_TYPE_PYTHON = 403 + FILE_TYPE_PERL = 404 + FILE_TYPE_RUBY = 405 + FILE_TYPE_C = 406 + FILE_TYPE_CPP = 407 + FILE_TYPE_JAVA = 408 + FILE_TYPE_SHELLSCRIPT = 409 + FILE_TYPE_PASCAL = 410 + FILE_TYPE_AWK = 411 + FILE_TYPE_DYALOG = 412 + FILE_TYPE_FORTRAN = 413 + FILE_TYPE_JAVASCRIPT = 414 + FILE_TYPE_POWERSHELL = 415 + FILE_TYPE_VBA = 416 + FILE_TYPE_M4 = 417 + FILE_TYPE_OBJETIVEC = 418 + FILE_TYPE_JMOD = 419 + FILE_TYPE_MAKEFILE = 420 + FILE_TYPE_INI = 421 + FILE_TYPE_CLJ = 422 + FILE_TYPE_PDB = 425 + FILE_TYPE_SQL = 426 + FILE_TYPE_NEKO = 427 + FILE_TYPE_WER = 428 + FILE_TYPE_GOLANG = 429 + FILE_TYPE_M3U = 430 + FILE_TYPE_BAT = 431 + FILE_TYPE_MSC = 432 + FILE_TYPE_RDP = 433 + FILE_TYPE_SYMBIAN = 500 + FILE_TYPE_PALMOS = 501 + FILE_TYPE_WINCE = 502 + FILE_TYPE_ANDROID = 503 + FILE_TYPE_IPHONE = 504 + FILE_TYPE_HTML = 600 + FILE_TYPE_XML = 601 + FILE_TYPE_SWF = 602 + FILE_TYPE_FLA = 603 + FILE_TYPE_COOKIE = 604 + FILE_TYPE_TORRENT = 605 + FILE_TYPE_EMAIL_TYPE = 606 + FILE_TYPE_OUTLOOK = 607 + FILE_TYPE_SGML = 608 + FILE_TYPE_JSON = 609 + FILE_TYPE_CSV = 610 + FILE_TYPE_HTA = 611 + FILE_TYPE_INTERNET_SHORTCUT = 612 + FILE_TYPE_CAP = 700 + FILE_TYPE_ISOIMAGE = 800 + FILE_TYPE_SQUASHFS = 801 + FILE_TYPE_VHD = 802 + FILE_TYPE_APPLE = 1000 + FILE_TYPE_MACINTOSH = 1001 + FILE_TYPE_APPLESINGLE = 1002 + FILE_TYPE_APPLEDOUBLE = 1003 + FILE_TYPE_MACINTOSH_HFS = 1004 + FILE_TYPE_APPLE_PLIST = 1005 + FILE_TYPE_MACINTOSH_LIB = 1006 + FILE_TYPE_APPLESCRIPT = 1007 + FILE_TYPE_APPLESCRIPT_COMPILED = 1008 + FILE_TYPE_CRX = 1100 + FILE_TYPE_XPI = 1101 + FILE_TYPE_ROM = 1200 + FILE_TYPE_IPS = 1201 + FILE_TYPE_PEM = 1300 + FILE_TYPE_PGP = 1301 + FILE_TYPE_CRT = 1302 + + sha256: str = proto.Field( + proto.STRING, + number=1, + ) + md5: str = proto.Field( + proto.STRING, + number=2, + ) + sha1: str = proto.Field( + proto.STRING, + number=3, + ) + size: int = proto.Field( + proto.UINT64, + number=4, + ) + full_path: str = proto.Field( + proto.STRING, + number=5, + ) + mime_type: str = proto.Field( + proto.STRING, + number=6, + ) + file_metadata: "FileMetadata" = proto.Field( + proto.MESSAGE, + number=7, + message="FileMetadata", + ) + security_result: "SecurityResult" = proto.Field( + proto.MESSAGE, + number=36, + message="SecurityResult", + ) + pe_file: "FileMetadataPE" = proto.Field( + proto.MESSAGE, + number=8, + message="FileMetadataPE", + ) + ssdeep: str = proto.Field( + proto.STRING, + number=9, + ) + vhash: str = proto.Field( + proto.STRING, + number=10, + ) + ahash: str = proto.Field( + proto.STRING, + number=11, + ) + authentihash: str = proto.Field( + proto.STRING, + number=20, + ) + symhash: str = proto.Field( + proto.STRING, + number=41, + ) + prefetch_file_metadata: "PrefetchFileMetadata" = proto.Field( + proto.MESSAGE, + number=43, + message="PrefetchFileMetadata", + ) + file_type: FileType = proto.Field( + proto.ENUM, + number=12, + enum=FileType, + ) + capabilities_tags: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=13, + ) + names: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=14, + ) + tags: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=27, + ) + last_modification_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=15, + message=timestamp_pb2.Timestamp, + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=39, + message=timestamp_pb2.Timestamp, + ) + last_access_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=40, + message=timestamp_pb2.Timestamp, + ) + prevalence: "Prevalence" = proto.Field( + proto.MESSAGE, + number=16, + message="Prevalence", + ) + first_seen_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=17, + message=timestamp_pb2.Timestamp, + ) + last_seen_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=18, + message=timestamp_pb2.Timestamp, + ) + stat_mode: int = proto.Field( + proto.UINT64, + number=21, + ) + stat_inode: int = proto.Field( + proto.UINT64, + number=22, + ) + stat_dev: int = proto.Field( + proto.UINT64, + number=23, + ) + stat_nlink: int = proto.Field( + proto.UINT64, + number=24, + ) + stat_flags: int = proto.Field( + proto.UINT32, + number=25, + ) + last_analysis_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=26, + message=timestamp_pb2.Timestamp, + ) + embedded_urls: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=28, + ) + embedded_domains: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=29, + ) + embedded_ips: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=30, + ) + exif_info: "ExifInfo" = proto.Field( + proto.MESSAGE, + number=31, + message="ExifInfo", + ) + signature_info: "SignatureInfo" = proto.Field( + proto.MESSAGE, + number=32, + message="SignatureInfo", + ) + pdf_info: "PDFInfo" = proto.Field( + proto.MESSAGE, + number=33, + message="PDFInfo", + ) + first_submission_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=34, + message=timestamp_pb2.Timestamp, + ) + last_submission_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=35, + message=timestamp_pb2.Timestamp, + ) + main_icon: "Favicon" = proto.Field( + proto.MESSAGE, + number=37, + message="Favicon", + ) + ntfs: "NtfsFileMetadata" = proto.Field( + proto.MESSAGE, + number=38, + message="NtfsFileMetadata", + ) + app_compat_cache: "AppCompatMetadata" = proto.Field( + proto.MESSAGE, + number=42, + message="AppCompatMetadata", + ) + + +class NtfsFileMetadata(proto.Message): + r"""NTFS-specific file metadata. + + Attributes: + change_time (google.protobuf.timestamp_pb2.Timestamp): + NTFS MFT entry changed timestamp. + filename_create_time (google.protobuf.timestamp_pb2.Timestamp): + NTFS $FILE_NAME attribute created timestamp. + filename_modify_time (google.protobuf.timestamp_pb2.Timestamp): + NTFS $FILE_NAME attribute modified timestamp. + filename_access_time (google.protobuf.timestamp_pb2.Timestamp): + NTFS $FILE_NAME attribute accessed timestamp. + filename_change_time (google.protobuf.timestamp_pb2.Timestamp): + NTFS $FILE_NAME attribute changed timestamp. + usn_journal (MutableSequence[google.backstory.types.UsnJournal]): + NTFS USN journal. + """ + + change_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + filename_create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + filename_modify_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + filename_access_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=4, + message=timestamp_pb2.Timestamp, + ) + filename_change_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + usn_journal: MutableSequence["UsnJournal"] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message="UsnJournal", + ) + + +class PrefetchFileMetadata(proto.Message): + r"""Windows Prefetch file metadata. + + Attributes: + run_count (int): + The number of times the application has been + run. + prefetch_hash (str): + A hash of the executable path used to + identify the prefetch file. + """ + + run_count: int = proto.Field( + proto.INT64, + number=1, + ) + prefetch_hash: str = proto.Field( + proto.STRING, + number=2, + ) + + +class UsnJournal(proto.Message): + r"""Information from the NTFS USN Journal. + + Attributes: + attributes_flag (str): + File attributes flags from the USN record + (e.g., "0x20"). + attributes (google.backstory.types.UsnJournal.Attribute): + Deprecated: Use file_attributes instead. File attributes + from the USN record. + file_attributes (MutableSequence[google.backstory.types.UsnJournal.Attribute]): + File attributes from the USN record. + allocated (bool): + Indicates whether the file is allocated in + the Master File Table (MFT). + reason (google.backstory.types.UsnJournal.Reason): + Deprecated: Use reasons instead. Human-readable string + describing the reason for the USN journal entry. (e.g., + "USN_REASON_FILE_CREATE"). + reasons (MutableSequence[google.backstory.types.UsnJournal.Reason]): + Human-readable string describing the reasons for the USN + journal entry (e.g., "USN_REASON_FILE_CREATE"). + """ + + class Attribute(proto.Enum): + r"""File attributes from the USN record (e.g., "READ_ONLY, HIDDEN"). See + https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants + for more information about the attributes. + + Values: + ATTRIBUTE_UNSPECIFIED (0): + Unspecified attribute. + READ_ONLY (1): + A file that is read-only. + HIDDEN (2): + The file or directory is hidden. + SYSTEM (3): + A file or directory that the operating system + uses. + ARCHIVE (4): + Archive file or directory. + COMPRESSED (5): + A file or directory that is compressed. + ENCRYPTED (6): + A file or directory that is encrypted. + DIRECTORY (7): + The handle that identifies the directory. + DEVICE (8): + Reserved for system use. + NORMAL (9): + A file that does not have other attributes + set. + TEMPORARY (10): + A file that is being used for temporary + storage. + SPARSE_FILE (11): + A file that is a sparse file. + REPARSE_POINT (12): + A file or directory that has an associated + reparse point. + OFFLINE (13): + The data of a file is not available + immediately. + NOT_CONTENT_INDEXED (14): + The file or directory is not to be indexed. + NON_CONTENT_INDEXED (14): + Deprecated: Use NOT_CONTENT_INDEXED instead. + INTEGRITY_STREAM (15): + The directory or user data stream is + configured with integrity. + VIRTUAL (16): + Reserved for system use. + NO_SCRUB_DATA (17): + The user data stream not to be read by the + background data integrity scanner. + EA (18): + A file or directory with extended attributes. + PINNED (19): + The file or directory should be kept fully + present locally. + UNPINNED (20): + The file or directory should not be kept + fully present locally. + RECALL_ON_OPEN (21): + The file or directory has no physical + representation on the local system. + RECALL_ON_DATA_ACCESS (22): + The file or directory is not fully present + locally. + """ + + _pb_options = {"allow_alias": True} + ATTRIBUTE_UNSPECIFIED = 0 + READ_ONLY = 1 + HIDDEN = 2 + SYSTEM = 3 + ARCHIVE = 4 + COMPRESSED = 5 + ENCRYPTED = 6 + DIRECTORY = 7 + DEVICE = 8 + NORMAL = 9 + TEMPORARY = 10 + SPARSE_FILE = 11 + REPARSE_POINT = 12 + OFFLINE = 13 + NOT_CONTENT_INDEXED = 14 + NON_CONTENT_INDEXED = 14 + INTEGRITY_STREAM = 15 + VIRTUAL = 16 + NO_SCRUB_DATA = 17 + EA = 18 + PINNED = 19 + UNPINNED = 20 + RECALL_ON_OPEN = 21 + RECALL_ON_DATA_ACCESS = 22 + + class Reason(proto.Enum): + r"""The reason for the USN journal entry. + + Values: + REASON_UNSPECIFIED (0): + Unspecified reason. + DATA_OVERWRITE (1): + Data overwrite reason. + DATA_EXTEND (2): + Data extend reason. + DATA_TRUNCATION (3): + Data truncation reason. + NAMED_DATA_OVERWRITE (4): + Named data overwrite reason. + NAMED_DATA_EXTEND (5): + Named data extend reason. + NAMED_DATA_TRUNCATION (6): + Named data truncation reason. + FILE_CREATE (7): + File create reason. + FILE_DELETE (8): + File delete reason. + EA_CHANGE (9): + EA change reason. + SECURITY_CHANGE (10): + Security change reason. + RENAME_OLD_NAME (11): + Rename old name reason. + RENAME_NEW_NAME (12): + Rename new name reason. + INDEXABLE_CHANGE (13): + Indexable change reason. + BASIC_INFO_CHANGE (14): + Basic info change reason. + HARD_LINK_CHANGE (15): + Hard link change reason. + COMPRESSION_CHANGE (16): + Compression change reason. + ENCRYPTION_CHANGE (17): + Encryption change reason. + OBJECT_ID_CHANGE (18): + Object ID change reason. + REPARSE_POINT_CHANGE (19): + Reparse point change reason. + STREAM_CHANGE (20): + Stream change reason. + TRANSACTED_CHANGE (21): + Transacted change reason. + CLOSE (22): + Close reason. + """ + + REASON_UNSPECIFIED = 0 + DATA_OVERWRITE = 1 + DATA_EXTEND = 2 + DATA_TRUNCATION = 3 + NAMED_DATA_OVERWRITE = 4 + NAMED_DATA_EXTEND = 5 + NAMED_DATA_TRUNCATION = 6 + FILE_CREATE = 7 + FILE_DELETE = 8 + EA_CHANGE = 9 + SECURITY_CHANGE = 10 + RENAME_OLD_NAME = 11 + RENAME_NEW_NAME = 12 + INDEXABLE_CHANGE = 13 + BASIC_INFO_CHANGE = 14 + HARD_LINK_CHANGE = 15 + COMPRESSION_CHANGE = 16 + ENCRYPTION_CHANGE = 17 + OBJECT_ID_CHANGE = 18 + REPARSE_POINT_CHANGE = 19 + STREAM_CHANGE = 20 + TRANSACTED_CHANGE = 21 + CLOSE = 22 + + attributes_flag: str = proto.Field( + proto.STRING, + number=1, + ) + attributes: Attribute = proto.Field( + proto.ENUM, + number=2, + enum=Attribute, + ) + file_attributes: MutableSequence[Attribute] = proto.RepeatedField( + proto.ENUM, + number=5, + enum=Attribute, + ) + allocated: bool = proto.Field( + proto.BOOL, + number=3, + ) + reason: Reason = proto.Field( + proto.ENUM, + number=4, + enum=Reason, + ) + reasons: MutableSequence[Reason] = proto.RepeatedField( + proto.ENUM, + number=6, + enum=Reason, + ) + + +class AppCompatMetadata(proto.Message): + r"""Windows AppCompatCache (Application Compatibility) metadata. + + Attributes: + sequence (int): + Indicates the chronological order in which + the entry was added to the cache. + executed (bool): + Indicates whether the file associated with + the entry was executed. + control_set (str): + Indicates which registry Control Set the + AppCompatCache data belongs to (e.g., + "ControlSet001"). + """ + + sequence: int = proto.Field( + proto.INT32, + number=1, + ) + executed: bool = proto.Field( + proto.BOOL, + number=2, + ) + control_set: str = proto.Field( + proto.STRING, + number=3, + ) + + +class FileMetadataPE(proto.Message): + r"""Metadata about the Portable Executable (PE) file. + + Attributes: + imphash (str): + Imphash of the file. + entry_point (int): + info.pe-entry-point. + entry_point_exiftool (int): + info.exiftool.EntryPoint. + compilation_time (google.protobuf.timestamp_pb2.Timestamp): + info.pe-timestamp. + compilation_exiftool_time (google.protobuf.timestamp_pb2.Timestamp): + info.exiftool.TimeStamp. + section (MutableSequence[google.backstory.types.FileMetadataSection]): + FilemetadataSection fields. + imports (MutableSequence[google.backstory.types.FileMetadataImports]): + FilemetadataImports fields. + resource (MutableSequence[google.backstory.types.FileMetadataPeResourceInfo]): + FilemetadataPeResourceInfo fields. + resources_type_count (MutableSequence[google.backstory.types.StringToInt64MapEntry]): + Deprecated: use resources_type_count_str. + resources_language_count (MutableSequence[google.backstory.types.StringToInt64MapEntry]): + Deprecated: use resources_language_count_str. + resources_type_count_str (MutableSequence[google.backstory.types.Label]): + Number of resources by resource type. Example: RT_ICON: 10, + RT_DIALOG: 5 + resources_language_count_str (MutableSequence[google.backstory.types.Label]): + Number of resources by language. + Example: NEUTRAL: 20, ENGLISH US: 10 + signature_info (google.backstory.types.FileMetadataSignatureInfo): + FilemetadataSignatureInfo field. deprecated, user + File.signature_info instead. + """ + + imphash: str = proto.Field( + proto.STRING, + number=1, + ) + entry_point: int = proto.Field( + proto.INT64, + number=2, + ) + entry_point_exiftool: int = proto.Field( + proto.INT64, + number=9, + ) + compilation_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=10, + message=timestamp_pb2.Timestamp, + ) + compilation_exiftool_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=11, + message=timestamp_pb2.Timestamp, + ) + section: MutableSequence["FileMetadataSection"] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message="FileMetadataSection", + ) + imports: MutableSequence["FileMetadataImports"] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message="FileMetadataImports", + ) + resource: MutableSequence["FileMetadataPeResourceInfo"] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message="FileMetadataPeResourceInfo", + ) + resources_type_count: MutableSequence["StringToInt64MapEntry"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=6, + message="StringToInt64MapEntry", + ) + ) + resources_language_count: MutableSequence["StringToInt64MapEntry"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=7, + message="StringToInt64MapEntry", + ) + ) + resources_type_count_str: MutableSequence["Label"] = proto.RepeatedField( + proto.MESSAGE, + number=12, + message="Label", + ) + resources_language_count_str: MutableSequence["Label"] = proto.RepeatedField( + proto.MESSAGE, + number=13, + message="Label", + ) + signature_info: "FileMetadataSignatureInfo" = proto.Field( + proto.MESSAGE, + number=8, + message="FileMetadataSignatureInfo", + ) + + +class FileMetadataPeResourceInfo(proto.Message): + r"""File metadata for PE resource. + + Attributes: + sha256_hex (str): + SHA256_hex field.. + filetype_magic (str): + Type of resource content, as identified by + the magic Python module. + language_code (str): + Human-readable version of the language and + sublanguage identifiers, as defined in the + Microsoft Windows PE specification. + entropy (float): + Entropy of the resource. + file_type (str): + File type. + Note that this value may not match any of the + well-known type identifiers defined in the + ResourceType enum. + """ + + sha256_hex: str = proto.Field( + proto.STRING, + number=1, + ) + filetype_magic: str = proto.Field( + proto.STRING, + number=2, + ) + language_code: str = proto.Field( + proto.STRING, + number=4, + ) + entropy: float = proto.Field( + proto.DOUBLE, + number=5, + ) + file_type: str = proto.Field( + proto.STRING, + number=6, + ) + + +class SignatureInfo(proto.Message): + r"""File signature information extracted from different tools. + + Attributes: + sigcheck (google.backstory.types.FileMetadataSignatureInfo): + Signature information extracted from the + sigcheck tool. + codesign (google.backstory.types.FileMetadataCodesign): + Signature information extracted from the + codesign utility. + """ + + sigcheck: "FileMetadataSignatureInfo" = proto.Field( + proto.MESSAGE, + number=1, + message="FileMetadataSignatureInfo", + ) + codesign: "FileMetadataCodesign" = proto.Field( + proto.MESSAGE, + number=2, + message="FileMetadataCodesign", + ) + + +class FileMetadataSignatureInfo(proto.Message): + r"""Signature information. + + Attributes: + verification_message (str): + Status of the certificate. + Valid values are "Signed", "Unsigned" or a + description of the certificate anomaly, if + found. + verified (bool): + True if verification_message == "Signed". + signer (MutableSequence[str]): + Deprecated: use signers field. + signers (MutableSequence[google.backstory.types.SignerInfo]): + File metadata signer information. + The order of the signers matters. Each element + is a higher level authority, being the last the + root authority. + x509 (MutableSequence[google.backstory.types.X509]): + List of certificates. + """ + + verification_message: str = proto.Field( + proto.STRING, + number=1, + ) + verified: bool = proto.Field( + proto.BOOL, + number=2, + ) + signer: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + signers: MutableSequence["SignerInfo"] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message="SignerInfo", + ) + x509: MutableSequence["X509"] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message="X509", + ) + + +class SignerInfo(proto.Message): + r"""File metadata related to the signer information. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + name (str): + Common name of the signers/certificate. + The order of the signers matters. Each element + is a higher level authority, the last being the + root authority. + + This field is a member of `oneof`_ ``_name``. + status (str): + It can say "Valid" or state the problem with + the certificate if any (e.g. "This certificate + or one of the certificates in the certificate + chain is not time valid."). + + This field is a member of `oneof`_ ``_status``. + valid_usage (str): + Indicates which situations the certificate is + valid for (e.g. "Code Signing"). + + This field is a member of `oneof`_ ``_valid_usage``. + cert_issuer (str): + Company that issued the certificate. + + This field is a member of `oneof`_ ``_cert_issuer``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + optional=True, + ) + status: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + valid_usage: str = proto.Field( + proto.STRING, + number=3, + optional=True, + ) + cert_issuer: str = proto.Field( + proto.STRING, + number=4, + optional=True, + ) + + +class FileMetadataCodesign(proto.Message): + r"""File metadata from the codesign utility. + + Attributes: + id (str): + Code sign identifier. + format_ (str): + Code sign format. + compilation_time (google.protobuf.timestamp_pb2.Timestamp): + Code sign timestamp + team_id (str): + The assigned team identifier of the developer + who signed the application. + """ + + id: str = proto.Field( + proto.STRING, + number=1, + ) + format_: str = proto.Field( + proto.STRING, + number=2, + ) + compilation_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + team_id: str = proto.Field( + proto.STRING, + number=4, + ) + + +class X509(proto.Message): + r"""File certificate. + + Attributes: + name (str): + Certificate name. + algorithm (str): + Certificate algorithm. + thumbprint (str): + Certificate thumbprint. + cert_issuer (str): + Issuer of the certificate. + serial_number (str): + Certificate serial number. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + algorithm: str = proto.Field( + proto.STRING, + number=2, + ) + thumbprint: str = proto.Field( + proto.STRING, + number=3, + ) + cert_issuer: str = proto.Field( + proto.STRING, + number=4, + ) + serial_number: str = proto.Field( + proto.STRING, + number=5, + ) + + +class PDFInfo(proto.Message): + r"""Information about the PDF file structure. See + https://developers.virustotal.com/reference/pdf_info + + Attributes: + js (int): + Number of /JS tags found in the PDF file. + Should be the same as javascript field in normal + scenarios. + javascript (int): + Number of /JavaScript tags found in the PDF + file. Should be the same as the js field in + normal scenarios. + launch_action_count (int): + Number of /Launch tags found in the PDF file. + object_stream_count (int): + Number of object streams. + endobj_count (int): + Number of object definitions (endobj + keyword). + header (str): + PDF version. + acroform (int): + Number of /AcroForm tags found in the PDF. + autoaction (int): + Number of /AA tags found in the PDF. + embedded_file (int): + Number of /EmbeddedFile tags found in the + PDF. + encrypted (int): + Whether the document is encrypted or not. + This is defined by the /Encrypt tag. + flash (int): + Number of /RichMedia tags found in the PDF. + jbig2_compression (int): + Number of /JBIG2Decode tags found in the PDF. + obj_count (int): + Number of objects definitions (obj keyword). + endstream_count (int): + Number of defined stream objects (stream + keyword). + page_count (int): + Number of pages in the PDF. + stream_count (int): + Number of defined stream objects (stream + keyword). + openaction (int): + Number of /OpenAction tags found in the PDF. + startxref (int): + Number of startxref keywords in the PDF. + suspicious_colors (int): + Number of colors expressed with more than 3 + bytes (CVE-2009-3459). + trailer (int): + Number of trailer keywords in the PDF. + xfa (int): + Number of \XFA tags found in the PDF. + xref (int): + Number of xref keywords in the PDF. + """ + + js: int = proto.Field( + proto.INT64, + number=1, + ) + javascript: int = proto.Field( + proto.INT64, + number=2, + ) + launch_action_count: int = proto.Field( + proto.INT64, + number=3, + ) + object_stream_count: int = proto.Field( + proto.INT64, + number=4, + ) + endobj_count: int = proto.Field( + proto.INT64, + number=5, + ) + header: str = proto.Field( + proto.STRING, + number=6, + ) + acroform: int = proto.Field( + proto.INT64, + number=7, + ) + autoaction: int = proto.Field( + proto.INT64, + number=8, + ) + embedded_file: int = proto.Field( + proto.INT64, + number=9, + ) + encrypted: int = proto.Field( + proto.INT64, + number=10, + ) + flash: int = proto.Field( + proto.INT64, + number=11, + ) + jbig2_compression: int = proto.Field( + proto.INT64, + number=12, + ) + obj_count: int = proto.Field( + proto.INT64, + number=13, + ) + endstream_count: int = proto.Field( + proto.INT64, + number=14, + ) + page_count: int = proto.Field( + proto.INT64, + number=15, + ) + stream_count: int = proto.Field( + proto.INT64, + number=16, + ) + openaction: int = proto.Field( + proto.INT64, + number=17, + ) + startxref: int = proto.Field( + proto.INT64, + number=18, + ) + suspicious_colors: int = proto.Field( + proto.INT64, + number=19, + ) + trailer: int = proto.Field( + proto.INT64, + number=20, + ) + xfa: int = proto.Field( + proto.INT64, + number=21, + ) + xref: int = proto.Field( + proto.INT64, + number=22, + ) + + +class StringToInt64MapEntry(proto.Message): + r""" + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + key (str): + Key field. + + This field is a member of `oneof`_ ``_key``. + value (int): + Value field. + + This field is a member of `oneof`_ ``_value``. + """ + + key: str = proto.Field( + proto.STRING, + number=1, + optional=True, + ) + value: int = proto.Field( + proto.INT64, + number=2, + optional=True, + ) + + +class FileMetadataSection(proto.Message): + r"""File metadata section. + + Attributes: + name (str): + Name of the section. + entropy (float): + Entropy of the section. + raw_size_bytes (int): + Raw file size in bytes. + virtual_size_bytes (int): + Virtual file size in bytes. + md5_hex (str): + MD5 hex of the file. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + entropy: float = proto.Field( + proto.DOUBLE, + number=2, + ) + raw_size_bytes: int = proto.Field( + proto.INT64, + number=3, + ) + virtual_size_bytes: int = proto.Field( + proto.INT64, + number=4, + ) + md5_hex: str = proto.Field( + proto.STRING, + number=5, + ) + + +class FileMetadataImports(proto.Message): + r"""File metadata imports. + + Attributes: + library (str): + Library field. + functions (MutableSequence[str]): + Function field. + """ + + library: str = proto.Field( + proto.STRING, + number=1, + ) + functions: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + +class ExifInfo(proto.Message): + r"""Exif information. + + Attributes: + original_file (str): + original file name. + product (str): + product name. + company (str): + company name. + file_description (str): + description of a file. + entry_point (int): + entry point. + compilation_time (google.protobuf.timestamp_pb2.Timestamp): + Compilation time. + """ + + original_file: str = proto.Field( + proto.STRING, + number=1, + ) + product: str = proto.Field( + proto.STRING, + number=2, + ) + company: str = proto.Field( + proto.STRING, + number=3, + ) + file_description: str = proto.Field( + proto.STRING, + number=4, + ) + entry_point: int = proto.Field( + proto.INT64, + number=5, + ) + compilation_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=6, + message=timestamp_pb2.Timestamp, + ) + + +class Prevalence(proto.Message): + r"""The prevalence of a resource within the customer's + environment. This measures how common it is for assets to access + the resource. + + Attributes: + rolling_max (int): + The maximum number of assets per day accessing the resource + over the trailing day_count days. + day_count (int): + The number of days over which rolling_max is calculated. + rolling_max_sub_domains (int): + The maximum number of assets per day accessing the domain + along with sub-domains over the trailing day_count days. + This field is only valid for domains. + day_max (int): + The max prevalence score in a day interval + window. + day_max_sub_domains (int): + The max prevalence score in a day interval + window across sub-domains. This field is only + valid for domains. + """ + + rolling_max: int = proto.Field( + proto.INT32, + number=1, + ) + day_count: int = proto.Field( + proto.INT32, + number=2, + ) + rolling_max_sub_domains: int = proto.Field( + proto.INT32, + number=3, + ) + day_max: int = proto.Field( + proto.INT32, + number=4, + ) + day_max_sub_domains: int = proto.Field( + proto.INT32, + number=5, + ) + + +class Dns(proto.Message): + r"""DNS information. + + Attributes: + id (int): + DNS query id. + response (bool): + Set to true if the event is a DNS response. + See QR field from RFC1035. + opcode (int): + The DNS OpCode used to specify the type of + DNS query (for example, QUERY, IQUERY, or + STATUS). + authoritative (bool): + Other DNS header flags. See RFC1035, section + 4.1.1. + truncated (bool): + Whether the DNS response was truncated. + recursion_desired (bool): + Whether a recursive DNS lookup is desired. + recursion_available (bool): + Whether a recursive DNS lookup is available. + response_code (int): + Response code. See RCODE from RFC1035. + questions (MutableSequence[google.backstory.types.Dns.Question]): + A list of domain protocol message questions. + answers (MutableSequence[google.backstory.types.Dns.ResourceRecord]): + A list of answers to the domain name query. + authority (MutableSequence[google.backstory.types.Dns.ResourceRecord]): + A list of domain name servers which verified + the answers to the domain name queries. + additional (MutableSequence[google.backstory.types.Dns.ResourceRecord]): + A list of additional domain name servers that + can be used to verify the answer to the domain. + """ + + class Question(proto.Message): + r"""DNS Questions. See RFC1035, section 4.1.2. + + Attributes: + name (str): + The domain name. + type_ (int): + The code specifying the type of the query. + class_ (int): + The code specifying the class of the query. + prevalence (google.backstory.types.Prevalence): + The prevalence of the domain within the + customer's environment. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + type_: int = proto.Field( + proto.UINT32, + number=2, + ) + class_: int = proto.Field( + proto.UINT32, + number=3, + ) + prevalence: "Prevalence" = proto.Field( + proto.MESSAGE, + number=4, + message="Prevalence", + ) + + class ResourceRecord(proto.Message): + r"""DNS Resource Records. See RFC1035, section 4.1.3. + + Attributes: + name (str): + The name of the owner of the resource record. + type_ (int): + The code specifying the type of the resource + record. + class_ (int): + The code specifying the class of the resource + record. + ttl (int): + The time interval for which the resource + record can be cached before the source of the + information should again be queried. + data (str): + The payload or response to the DNS question + for all responses encoded in UTF-8 format + binary_data (bytes): + The raw bytes of any non-UTF8 strings that + might be included as part of a DNS response. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + type_: int = proto.Field( + proto.UINT32, + number=2, + ) + class_: int = proto.Field( + proto.UINT32, + number=3, + ) + ttl: int = proto.Field( + proto.UINT32, + number=4, + ) + data: str = proto.Field( + proto.STRING, + number=5, + ) + binary_data: bytes = proto.Field( + proto.BYTES, + number=6, + ) + + id: int = proto.Field( + proto.UINT32, + number=6, + ) + response: bool = proto.Field( + proto.BOOL, + number=7, + ) + opcode: int = proto.Field( + proto.UINT32, + number=8, + ) + authoritative: bool = proto.Field( + proto.BOOL, + number=9, + ) + truncated: bool = proto.Field( + proto.BOOL, + number=10, + ) + recursion_desired: bool = proto.Field( + proto.BOOL, + number=11, + ) + recursion_available: bool = proto.Field( + proto.BOOL, + number=12, + ) + response_code: int = proto.Field( + proto.UINT32, + number=13, + ) + questions: MutableSequence[Question] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=Question, + ) + answers: MutableSequence[ResourceRecord] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=ResourceRecord, + ) + authority: MutableSequence[ResourceRecord] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=ResourceRecord, + ) + additional: MutableSequence[ResourceRecord] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message=ResourceRecord, + ) + + +class Dhcp(proto.Message): + r"""DHCP information. + + Attributes: + opcode (google.backstory.types.Dhcp.OpCode): + The BOOTP op code. + htype (int): + Hardware address type. + hlen (int): + Hardware address length. + hops (int): + Hardware ops. + transaction_id (int): + Transaction ID. + seconds (int): + Seconds elapsed since client began address + acquisition/renewal process. + flags (int): + Flags. + ciaddr (str): + Client IP address (ciaddr). + yiaddr (str): + Your IP address (yiaddr). + siaddr (str): + IP address of the next bootstrap server. + giaddr (str): + Relay agent IP address (giaddr). + chaddr (str): + Client hardware address (chaddr). + sname (str): + Server name that the client wishes to boot + from. + file (str): + Boot image filename. + options (MutableSequence[google.backstory.types.Dhcp.Option]): + List of DHCP options. + type_ (google.backstory.types.Dhcp.MessageType): + DHCP message type. + lease_time_seconds (int): + Lease time in seconds. See RFC2132, section + 9.2. + client_hostname (str): + Client hostname. See RFC2132, section 3.14. + client_identifier (bytes): + Client identifier. See RFC2132, section 9.14. Note: Make + sure to update the client_identifier_string field as well if + you update this field. + requested_address (str): + Requested IP address. See RFC2132, section + 9.1. + client_identifier_string (str): + Client identifier as string. See RFC2132, section 9.14. This + field holds the string value of the client_identifier. + """ + + class OpCode(proto.Enum): + r"""BOOTP op code. See RFC951, section 3. + + Values: + UNKNOWN_OPCODE (0): + Default opcode. + BOOTREQUEST (1): + Request. + BOOTREPLY (2): + Reply. + """ + + UNKNOWN_OPCODE = 0 + BOOTREQUEST = 1 + BOOTREPLY = 2 + + class MessageType(proto.Enum): + r"""DHCP message type. See RFC2131, section 3.1. + + Values: + UNKNOWN_MESSAGE_TYPE (0): + Default message type. + DISCOVER (1): + DHCPDISCOVER. + OFFER (2): + DHCPOFFER. + REQUEST (3): + DHCPREQUEST. + DECLINE (4): + DHCPDECLINE. + ACK (5): + DHCPACK. + NAK (6): + DHCPNAK. + RELEASE (7): + DHCPRELEASE. + INFORM (8): + DHCPINFORM. + WIN_DELETED (100): + Microsoft Windows DHCP "lease deleted". + WIN_EXPIRED (101): + Microsoft Windows DHCP "lease expired". + """ + + UNKNOWN_MESSAGE_TYPE = 0 + DISCOVER = 1 + OFFER = 2 + REQUEST = 3 + DECLINE = 4 + ACK = 5 + NAK = 6 + RELEASE = 7 + INFORM = 8 + WIN_DELETED = 100 + WIN_EXPIRED = 101 + + class Option(proto.Message): + r"""DHCP options. + + Attributes: + code (int): + Code. See RFC1533. + data (bytes): + Data. + """ + + code: int = proto.Field( + proto.UINT32, + number=1, + ) + data: bytes = proto.Field( + proto.BYTES, + number=2, + ) + + opcode: OpCode = proto.Field( + proto.ENUM, + number=1, + enum=OpCode, + ) + htype: int = proto.Field( + proto.UINT32, + number=2, + ) + hlen: int = proto.Field( + proto.UINT32, + number=3, + ) + hops: int = proto.Field( + proto.UINT32, + number=4, + ) + transaction_id: int = proto.Field( + proto.UINT32, + number=5, + ) + seconds: int = proto.Field( + proto.UINT32, + number=6, + ) + flags: int = proto.Field( + proto.UINT32, + number=7, + ) + ciaddr: str = proto.Field( + proto.STRING, + number=8, + ) + yiaddr: str = proto.Field( + proto.STRING, + number=9, + ) + siaddr: str = proto.Field( + proto.STRING, + number=10, + ) + giaddr: str = proto.Field( + proto.STRING, + number=11, + ) + chaddr: str = proto.Field( + proto.STRING, + number=12, + ) + sname: str = proto.Field( + proto.STRING, + number=13, + ) + file: str = proto.Field( + proto.STRING, + number=14, + ) + options: MutableSequence[Option] = proto.RepeatedField( + proto.MESSAGE, + number=15, + message=Option, + ) + type_: MessageType = proto.Field( + proto.ENUM, + number=16, + enum=MessageType, + ) + lease_time_seconds: int = proto.Field( + proto.UINT32, + number=17, + ) + client_hostname: str = proto.Field( + proto.STRING, + number=18, + ) + client_identifier: bytes = proto.Field( + proto.BYTES, + number=19, + ) + requested_address: str = proto.Field( + proto.STRING, + number=20, + ) + client_identifier_string: str = proto.Field( + proto.STRING, + number=21, + ) + + +class Certificate(proto.Message): + r"""Certificate information + + Attributes: + version (str): + Certificate version. + serial (str): + Certificate serial number. + subject (str): + Subject of the certificate. + issuer (str): + Issuer of the certificate. + md5 (str): + The MD5 hash of the certificate, as a + hex-encoded string. + sha1 (str): + The SHA1 hash of the certificate, as a + hex-encoded string. + sha256 (str): + The SHA256 hash of the certificate, as a + hex-encoded string. + not_before (google.protobuf.timestamp_pb2.Timestamp): + Indicates when the certificate is first + valid. + not_after (google.protobuf.timestamp_pb2.Timestamp): + Indicates when the certificate is no longer + valid. + """ + + version: str = proto.Field( + proto.STRING, + number=1, + ) + serial: str = proto.Field( + proto.STRING, + number=2, + ) + subject: str = proto.Field( + proto.STRING, + number=3, + ) + issuer: str = proto.Field( + proto.STRING, + number=4, + ) + md5: str = proto.Field( + proto.STRING, + number=5, + ) + sha1: str = proto.Field( + proto.STRING, + number=6, + ) + sha256: str = proto.Field( + proto.STRING, + number=7, + ) + not_before: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=8, + message=timestamp_pb2.Timestamp, + ) + not_after: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=9, + message=timestamp_pb2.Timestamp, + ) + + +class Tls(proto.Message): + r"""Transport Layer Security (TLS) information. + + Attributes: + client (google.backstory.types.Tls.Client): + Certificate information for the client + certificate. + server (google.backstory.types.Tls.Server): + Certificate information for the server + certificate. + cipher (str): + Cipher used during the connection. + curve (str): + Elliptical curve used for a given cipher. + version (str): + TLS version. + version_protocol (str): + Protocol. + established (bool): + Indicates whether the TLS negotiation was + successful. + next_protocol (str): + Protocol to be used for tunnel. + resumed (bool): + Indicates whether the TLS connection was + resumed from a previous TLS negotiation. + """ + + class Client(proto.Message): + r"""Transport Layer Security (TLS) information associated with + the client (for example, Certificate or JA3 hash). + + Attributes: + certificate (google.backstory.types.Certificate): + Client certificate. + ja3 (str): + JA3 hash from the TLS ClientHello, as a + hex-encoded string. + server_name (str): + Host name of the server, that the client is + connecting to. + supported_ciphers (MutableSequence[str]): + Ciphers supported by the client during client + hello. + ja4 (str): + JA4 hash from the TLS ClientHello, as a + hex-encoded string. + """ + + certificate: "Certificate" = proto.Field( + proto.MESSAGE, + number=1, + message="Certificate", + ) + ja3: str = proto.Field( + proto.STRING, + number=2, + ) + server_name: str = proto.Field( + proto.STRING, + number=3, + ) + supported_ciphers: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=4, + ) + ja4: str = proto.Field( + proto.STRING, + number=5, + ) + + class Server(proto.Message): + r"""Transport Layer Security (TLS) information associated with + the server (for example, Certificate or JA3 hash). + + Attributes: + certificate (google.backstory.types.Certificate): + Server certificate. + ja3s (str): + JA3 hash from the TLS ServerHello, as a + hex-encoded string. + ja4s (str): + JA4 hash from the TLS ServerHello, as a + hex-encoded string. + """ + + certificate: "Certificate" = proto.Field( + proto.MESSAGE, + number=1, + message="Certificate", + ) + ja3s: str = proto.Field( + proto.STRING, + number=2, + ) + ja4s: str = proto.Field( + proto.STRING, + number=3, + ) + + client: Client = proto.Field( + proto.MESSAGE, + number=1, + message=Client, + ) + server: Server = proto.Field( + proto.MESSAGE, + number=2, + message=Server, + ) + cipher: str = proto.Field( + proto.STRING, + number=3, + ) + curve: str = proto.Field( + proto.STRING, + number=4, + ) + version: str = proto.Field( + proto.STRING, + number=5, + ) + version_protocol: str = proto.Field( + proto.STRING, + number=6, + ) + established: bool = proto.Field( + proto.BOOL, + number=7, + ) + next_protocol: str = proto.Field( + proto.STRING, + number=8, + ) + resumed: bool = proto.Field( + proto.BOOL, + number=9, + ) + + +class Http(proto.Message): + r"""Specify the full URL of the HTTP request within "target". + Also specify any uploaded or downloaded file information within + "source" or "target". + + Attributes: + method (str): + The HTTP request method + (e.g. "GET", "POST", "PATCH", "DELETE"). + referral_url (str): + The URL for the HTTP referer. + user_agent (str): + The User-Agent request header which includes + the application type, operating system, software + vendor or software version of the requesting + software user agent. + response_code (int): + The response status code, for example + 200, 302, 404, or 500. + """ + + method: str = proto.Field( + proto.STRING, + number=1, + ) + referral_url: str = proto.Field( + proto.STRING, + number=2, + ) + user_agent: str = proto.Field( + proto.STRING, + number=3, + ) + response_code: int = proto.Field( + proto.INT32, + number=4, + ) + + +class Browser(proto.Message): + r"""Information about an entry in the web browser's local history + database. + + Attributes: + browser_type (google.backstory.types.Browser.BrowserType): + The browser that recorded the history entry + (e.g. "Chrome", "Firefox", "Safari", etc.). + browser_version (str): + The browser version. + first_visit_time (google.protobuf.timestamp_pb2.Timestamp): + The timestamp indicating the initial visit to + the URL. + last_visit_time (google.protobuf.timestamp_pb2.Timestamp): + The timestamp indicating the most recent + visit to the URL. + profile (str): + The browser profile associated with the + history entry. + typed (bool): + A boolean value indicating if the URL was + typed by the user. + visit_type (google.backstory.types.Browser.UrlVisitType): + Describes the type of navigation or visit + (e.g., direct, redirect, etc.). + hidden (bool): + A boolean value indicating if the history + entry is hidden. + request_origin_uri (str): + Indicates the URI from which the current + visit originated. + visit_count (int): + The total number of times the Url has been + visited. + visit_count_criteria (str): + Describes the criteria used to calculate the visit_count. + indexed_content (str): + Represents the textual content of a web page. + This field should be kept short. Large strings + may affect latency and payload sizes. + first_bookmarked_time (google.protobuf.timestamp_pb2.Timestamp): + The timestamp indicating the first time the + URL was bookmarked. + cookies (MutableSequence[google.backstory.types.Browser.Cookie]): + Information about the cookies. + typed_count (int): + The number of times the URL was visited with + this specific visit type and visit source. + visit_source (google.backstory.types.Browser.VisitSource): + The source of the visit. + """ + + class BrowserType(proto.Enum): + r"""The name of the browser. + + Values: + BROWSER_TYPE_UNSPECIFIED (0): + Default value. + CHROME (1): + Chrome. + FIREFOX (2): + Firefox. + SAFARI (3): + Safari. + INTERNET_EXPLORER (4): + Internet Explorer. + EDGE (5): + Edge. + OPERA (6): + Opera. + """ + + BROWSER_TYPE_UNSPECIFIED = 0 + CHROME = 1 + FIREFOX = 2 + SAFARI = 3 + INTERNET_EXPLORER = 4 + EDGE = 5 + OPERA = 6 + + class UrlVisitType(proto.Enum): + r"""The type of visit to a URL. + + Values: + URL_VISIT_TYPE_UNSPECIFIED (0): + Default value. + LINK (1): + The user clicked a link. + TYPED (2): + The user typed a URL. + AUTO_BOOKMARK (3): + The user bookmarked the URL. + AUTO_SUBFRAME (4): + Loaded in a nested subframe by the parent + frame. + MANUAL_SUBFRAME (5): + Loaded in a nested subframe by the user. + GENERATED (6): + The user clicked on auto generated link in + browser address bar. + AUTO_TOPLEVEL (7): + The page was loaded through command line or + is the starting page. + FORM_SUBMIT (8): + The user submitted a form. + RELOAD (9): + The user reloaded the page. + KEYWORD (10): + The Url was generated by a keyword search + configured by user. + KEYWORD_GENERATED (11): + Corresponds to a visit generated by a keyword + search. + REDIRECT (12): + The user was redirected to the URL. + """ + + URL_VISIT_TYPE_UNSPECIFIED = 0 + LINK = 1 + TYPED = 2 + AUTO_BOOKMARK = 3 + AUTO_SUBFRAME = 4 + MANUAL_SUBFRAME = 5 + GENERATED = 6 + AUTO_TOPLEVEL = 7 + FORM_SUBMIT = 8 + RELOAD = 9 + KEYWORD = 10 + KEYWORD_GENERATED = 11 + REDIRECT = 12 + + class VisitSource(proto.Enum): + r"""The source of the visit. + + Values: + VISIT_SOURCE_UNSPECIFIED (0): + Default value. + SYNCED (1): + The visit was synced from another device. + BROWSER (2): + The visit was from a browser. + EXTENSION (3): + The visit was from an extension. + IMPORTED (4): + The visit was imported from another browser + application. + """ + + VISIT_SOURCE_UNSPECIFIED = 0 + SYNCED = 1 + BROWSER = 2 + EXTENSION = 3 + IMPORTED = 4 + + class Cookie(proto.Message): + r"""Browser cookie. + + Attributes: + name (str): + The unique name identifying the cookie. + value (str): + The data stored within the cookie. + domain (str): + The domain for which the cookie is valid. + path (str): + The URL path for which the cookie is valid. + expiration_time (google.protobuf.timestamp_pb2.Timestamp): + The date and time when the cookie will + expire. + http_only (bool): + Indicates if the cookie is inaccessible via + client-side scripts (e.g., JavaScript). + secure (bool): + Indicates if the cookie should only be sent + over secure HTTPS connections. + max_age (int): + The maximum age of the cookie in seconds. + same_site (google.backstory.types.Browser.Cookie.CookieSameSite): + Affects cross-site request behavior. + session (bool): + Indicates if the cookie is persistent. + partitioned (bool): + Shows if the cookies is stored using + partitioned storage. + """ + + class CookieSameSite(proto.Enum): + r"""The SameSite attribute of a cookie. + + Values: + COOKIE_SAME_SITE_UNSPECIFIED (0): + Default value. + STRICT (1): + Corresponds to SameSite=Strict. + LAX (2): + Corresponds to SameSite=Lax. + NONE (3): + Corresponds to SameSite=None. + """ + + COOKIE_SAME_SITE_UNSPECIFIED = 0 + STRICT = 1 + LAX = 2 + NONE = 3 + + name: str = proto.Field( + proto.STRING, + number=1, + ) + value: str = proto.Field( + proto.STRING, + number=2, + ) + domain: str = proto.Field( + proto.STRING, + number=3, + ) + path: str = proto.Field( + proto.STRING, + number=4, + ) + expiration_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + http_only: bool = proto.Field( + proto.BOOL, + number=6, + ) + secure: bool = proto.Field( + proto.BOOL, + number=7, + ) + max_age: int = proto.Field( + proto.INT64, + number=8, + ) + same_site: "Browser.Cookie.CookieSameSite" = proto.Field( + proto.ENUM, + number=9, + enum="Browser.Cookie.CookieSameSite", + ) + session: bool = proto.Field( + proto.BOOL, + number=10, + ) + partitioned: bool = proto.Field( + proto.BOOL, + number=11, + ) + + browser_type: BrowserType = proto.Field( + proto.ENUM, + number=1, + enum=BrowserType, + ) + browser_version: str = proto.Field( + proto.STRING, + number=2, + ) + first_visit_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + last_visit_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=4, + message=timestamp_pb2.Timestamp, + ) + profile: str = proto.Field( + proto.STRING, + number=5, + ) + typed: bool = proto.Field( + proto.BOOL, + number=6, + ) + visit_type: UrlVisitType = proto.Field( + proto.ENUM, + number=7, + enum=UrlVisitType, + ) + hidden: bool = proto.Field( + proto.BOOL, + number=8, + ) + request_origin_uri: str = proto.Field( + proto.STRING, + number=9, + ) + visit_count: int = proto.Field( + proto.INT64, + number=10, + ) + visit_count_criteria: str = proto.Field( + proto.STRING, + number=11, + ) + indexed_content: str = proto.Field( + proto.STRING, + number=12, + ) + first_bookmarked_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=13, + message=timestamp_pb2.Timestamp, + ) + cookies: MutableSequence[Cookie] = proto.RepeatedField( + proto.MESSAGE, + number=14, + message=Cookie, + ) + typed_count: int = proto.Field( + proto.INT64, + number=15, + ) + visit_source: VisitSource = proto.Field( + proto.ENUM, + number=16, + enum=VisitSource, + ) + + +class Hardware(proto.Message): + r"""Hardware specification details for a resource, including both + physical and virtual hardware. + + Attributes: + serial_number (str): + Hardware serial number. + manufacturer (str): + Hardware manufacturer. + model (str): + Hardware model. + cpu_platform (str): + Platform of the hardware CPU (e.g. "Intel + Broadwell"). + cpu_model (str): + Model description of the hardware CPU + (e.g. "2.8 GHz Quad-Core Intel Core i5"). + cpu_clock_speed (int): + Clock speed of the hardware CPU in MHz. + cpu_max_clock_speed (int): + Maximum possible clock speed of the hardware + CPU in MHz. + cpu_number_cores (int): + Number of CPU cores. + ram (int): + Amount of the hardware ramdom access memory + (RAM) in Mb. + """ + + serial_number: str = proto.Field( + proto.STRING, + number=1, + ) + manufacturer: str = proto.Field( + proto.STRING, + number=2, + ) + model: str = proto.Field( + proto.STRING, + number=3, + ) + cpu_platform: str = proto.Field( + proto.STRING, + number=4, + ) + cpu_model: str = proto.Field( + proto.STRING, + number=5, + ) + cpu_clock_speed: int = proto.Field( + proto.UINT64, + number=6, + ) + cpu_max_clock_speed: int = proto.Field( + proto.UINT64, + number=7, + ) + cpu_number_cores: int = proto.Field( + proto.UINT64, + number=8, + ) + ram: int = proto.Field( + proto.UINT64, + number=9, + ) + + +class PlatformSoftware(proto.Message): + r"""Platform software information about an operating system. + + Attributes: + platform (google.backstory.types.Noun.Platform): + The platform operating system. + platform_version (str): + The platform software version ( + e.g. "Microsoft Windows 1803"). + platform_patch_level (str): + The platform software patch level ( + e.g. "Build 17134.48", "SP1"). + """ + + platform: "Noun.Platform" = proto.Field( + proto.ENUM, + number=1, + enum="Noun.Platform", + ) + platform_version: str = proto.Field( + proto.STRING, + number=2, + ) + platform_patch_level: str = proto.Field( + proto.STRING, + number=3, + ) + + +class Software(proto.Message): + r"""Information about a software package or application. + + Attributes: + name (str): + The name of the software. + version (str): + The version of the software. + permissions (MutableSequence[google.backstory.types.Permission]): + System permissions granted to the software. For example, + "android.permission.WRITE_EXTERNAL_STORAGE". + description (str): + The description of the software. + vendor_name (str): + The name of the software vendor. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + version: str = proto.Field( + proto.STRING, + number=2, + ) + permissions: MutableSequence["Permission"] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message="Permission", + ) + description: str = proto.Field( + proto.STRING, + number=4, + ) + vendor_name: str = proto.Field( + proto.STRING, + number=5, + ) + + +class Asset(proto.Message): + r"""Information about a compute asset such as a workstation, + laptop, phone, virtual desktop, or VM. + + Attributes: + product_object_id (str): + A vendor-specific identifier to uniquely + identify the entity (a GUID or similar). + This field can be used as an entity indicator + for asset entities. + hostname (str): + Asset hostname or domain name field. + This field can be used as an entity indicator + for asset entities. + asset_id (str): + The asset ID. Value must contain the ':' + character. For example, cs:abcdd23434. + This field can be used as an entity indicator + for asset entities. + ip (MutableSequence[str]): + A list of IP addresses associated with an + asset. This field can be used as an entity + indicator for asset entities. + mac (MutableSequence[str]): + List of MAC addresses associated with an + asset. This field can be used as an entity + indicator for asset entities. + nat_ip (MutableSequence[str]): + List of NAT IP addresses associated with an + asset. + first_seen_time (google.protobuf.timestamp_pb2.Timestamp): + The first observed time for an asset. + The value is calculated on the basis of the + first time the identifier was observed. + hardware (MutableSequence[google.backstory.types.Hardware]): + The asset hardware specifications. + platform_software (google.backstory.types.PlatformSoftware): + The asset operating system platform software. + software (MutableSequence[google.backstory.types.Software]): + The asset software details. + location (google.backstory.types.Location): + Location of the asset. + category (str): + The category of the asset (e.g. "End User + Asset", "Workstation", "Server"). + type_ (google.backstory.types.Asset.AssetType): + The type of the asset (e.g. workstation or + laptop or server). + network_domain (str): + The network domain of the asset (e.g. + "corp.acme.com") + creation_time (google.protobuf.timestamp_pb2.Timestamp): + Time the asset was created or provisioned. Deprecate: + creation_time should be populated in Attribute as generic + metadata. + first_discover_time (google.protobuf.timestamp_pb2.Timestamp): + Time the asset was first discovered (by asset + management/discoverability software). + last_discover_time (google.protobuf.timestamp_pb2.Timestamp): + Time the asset was last discovered (by asset + management/discoverability software). + system_last_update_time (google.protobuf.timestamp_pb2.Timestamp): + Time the asset system or OS was last updated. For all other + operations that are not system updates (such as resizing a + VM), use Attribute.last_update_time. + last_boot_time (google.protobuf.timestamp_pb2.Timestamp): + Time the asset was last boot started. + labels (MutableSequence[google.backstory.types.Label]): + Metadata labels for the asset. + Deprecated: labels should be populated in + Attribute as generic metadata. + deployment_status (google.backstory.types.Asset.DeploymentStatus): + The deployment status of the asset for device + lifecycle purposes. + vulnerabilities (MutableSequence[google.backstory.types.Vulnerability]): + Vulnerabilities discovered on asset. + attribute (google.backstory.types.Attribute): + Generic entity metadata attributes of the + asset. + wmi_persistence_item (google.backstory.types.WmiPersistenceItem): + Information about a WMI persistence item. + """ + + class AssetType(proto.Enum): + r"""The role type of the asset. + + Values: + ROLE_UNSPECIFIED (0): + Unspecified asset role. + WORKSTATION (1): + A workstation or desktop. + LAPTOP (2): + A laptop computer. + IOT (3): + An IOT asset. + NETWORK_ATTACHED_STORAGE (4): + A network attached storage device. + PRINTER (5): + A printer. + SCANNER (6): + A scanner. + SERVER (7): + A server. + TAPE_LIBRARY (8): + A tape library device. + MOBILE (9): + A mobile device such as a mobile phone or + PDA. + """ + + ROLE_UNSPECIFIED = 0 + WORKSTATION = 1 + LAPTOP = 2 + IOT = 3 + NETWORK_ATTACHED_STORAGE = 4 + PRINTER = 5 + SCANNER = 6 + SERVER = 7 + TAPE_LIBRARY = 8 + MOBILE = 9 + + class DeploymentStatus(proto.Enum): + r"""Deployment status states. + + Values: + DEPLOYMENT_STATUS_UNSPECIFIED (0): + Unspecified deployment status. + ACTIVE (1): + Asset is active, functional and deployed. + PENDING_DECOMISSION (2): + Asset is pending decommission and no longer + deployed. + DECOMISSIONED (3): + Asset is decommissioned. + """ + + DEPLOYMENT_STATUS_UNSPECIFIED = 0 + ACTIVE = 1 + PENDING_DECOMISSION = 2 + DECOMISSIONED = 3 + + product_object_id: str = proto.Field( + proto.STRING, + number=1, + ) + hostname: str = proto.Field( + proto.STRING, + number=2, + ) + asset_id: str = proto.Field( + proto.STRING, + number=3, + ) + ip: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=4, + ) + mac: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=5, + ) + nat_ip: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=22, + ) + first_seen_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=23, + message=timestamp_pb2.Timestamp, + ) + hardware: MutableSequence["Hardware"] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message="Hardware", + ) + platform_software: "PlatformSoftware" = proto.Field( + proto.MESSAGE, + number=7, + message="PlatformSoftware", + ) + software: MutableSequence["Software"] = proto.RepeatedField( + proto.MESSAGE, + number=17, + message="Software", + ) + location: "Location" = proto.Field( + proto.MESSAGE, + number=8, + message="Location", + ) + category: str = proto.Field( + proto.STRING, + number=9, + ) + type_: AssetType = proto.Field( + proto.ENUM, + number=18, + enum=AssetType, + ) + network_domain: str = proto.Field( + proto.STRING, + number=10, + ) + creation_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=11, + message=timestamp_pb2.Timestamp, + ) + first_discover_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=12, + message=timestamp_pb2.Timestamp, + ) + last_discover_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=13, + message=timestamp_pb2.Timestamp, + ) + system_last_update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=14, + message=timestamp_pb2.Timestamp, + ) + last_boot_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=15, + message=timestamp_pb2.Timestamp, + ) + labels: MutableSequence["Label"] = proto.RepeatedField( + proto.MESSAGE, + number=16, + message="Label", + ) + deployment_status: DeploymentStatus = proto.Field( + proto.ENUM, + number=19, + enum=DeploymentStatus, + ) + vulnerabilities: MutableSequence["Vulnerability"] = proto.RepeatedField( + proto.MESSAGE, + number=21, + message="Vulnerability", + ) + attribute: "Attribute" = proto.Field( + proto.MESSAGE, + number=20, + message="Attribute", + ) + wmi_persistence_item: "WmiPersistenceItem" = proto.Field( + proto.MESSAGE, + number=24, + message="WmiPersistenceItem", + ) + + +class User(proto.Message): + r"""Information about a user. + + Attributes: + product_object_id (str): + A vendor-specific identifier to uniquely + identify the entity (e.g. a GUID, LDAP, OID, or + similar). This field can be used as an entity + indicator for user entities. + userid (str): + The ID of the user. + This field can be used as an entity indicator + for user entities. + user_display_name (str): + The display name of the user + (e.g. "John Locke"). + first_name (str): + First name of the user (e.g. "John"). + middle_name (str): + Middle name of the user. + last_name (str): + Last name of the user (e.g. "Locke"). + phone_numbers (MutableSequence[str]): + Phone numbers for the user. + personal_address (google.backstory.types.Location): + Personal address of the user. + attribute (google.backstory.types.Attribute): + Generic entity metadata attributes of the + user. + first_seen_time (google.protobuf.timestamp_pb2.Timestamp): + The first observed time for a user. + The value is calculated on the basis of the + first time the identifier was observed. + account_type (google.backstory.types.User.AccountType): + Type of user account (for example, service, domain, or + cloud). This is somewhat aligned to: + https://attack.mitre.org/techniques/T1078/ + groupid (str): + The ID of the group that the user belongs to. Deprecated in + favor of the repeated group_identifiers field. + group_identifiers (MutableSequence[str]): + Product object identifiers of the group(s) + the user belongs to A vendor-specific identifier + to uniquely identify the group(s) the user + belongs to (a GUID, LDAP OID, or similar). + windows_sid (str): + The Microsoft Windows SID of the user. + This field can be used as an entity indicator + for user entities. + email_addresses (MutableSequence[str]): + Email addresses of the user. + This field can be used as an entity indicator + for user entities. + employee_id (str): + Human capital management identifier. + This field can be used as an entity indicator + for user entities. + title (str): + User job title. + company_name (str): + User job company name. + department (MutableSequence[str]): + User job department + office_address (google.backstory.types.Location): + User job office location. + managers (MutableSequence[google.backstory.types.User]): + User job manager(s). + hire_date (google.protobuf.timestamp_pb2.Timestamp): + User job employment hire date. + termination_date (google.protobuf.timestamp_pb2.Timestamp): + User job employment termination date. + time_off (MutableSequence[google.backstory.types.TimeOff]): + User time off leaves from active work. + last_login_time (google.protobuf.timestamp_pb2.Timestamp): + User last login timestamp. + last_password_change_time (google.protobuf.timestamp_pb2.Timestamp): + User last password change timestamp. + password_expiration_time (google.protobuf.timestamp_pb2.Timestamp): + User password expiration timestamp. + account_expiration_time (google.protobuf.timestamp_pb2.Timestamp): + User account expiration timestamp. + account_lockout_time (google.protobuf.timestamp_pb2.Timestamp): + User account lockout timestamp. + last_bad_password_attempt_time (google.protobuf.timestamp_pb2.Timestamp): + User last bad password attempt timestamp. + user_authentication_status (google.backstory.types.Authentication.AuthenticationStatus): + System authentication status for user. + role_name (str): + System role name for user. + Deprecated: use attribute.roles. + role_description (str): + System role description for user. + Deprecated: use attribute.roles. + user_role (google.backstory.types.User.Role): + System role for user. + Deprecated: use attribute.roles. + """ + + class AccountType(proto.Enum): + r"""User Account Type. + + Values: + ACCOUNT_TYPE_UNSPECIFIED (0): + Default user account type. + DOMAIN_ACCOUNT_TYPE (1): + A human account part of some domain in + directory services. + LOCAL_ACCOUNT_TYPE (2): + A local machine account. + CLOUD_ACCOUNT_TYPE (3): + A SaaS service account type (such as Slack or + GitHub). + SERVICE_ACCOUNT_TYPE (4): + A non-human account for data access. + DEFAULT_ACCOUNT_TYPE (5): + A system built in default account. + """ + + ACCOUNT_TYPE_UNSPECIFIED = 0 + DOMAIN_ACCOUNT_TYPE = 1 + LOCAL_ACCOUNT_TYPE = 2 + CLOUD_ACCOUNT_TYPE = 3 + SERVICE_ACCOUNT_TYPE = 4 + DEFAULT_ACCOUNT_TYPE = 5 + + class Role(proto.Enum): + r"""User system roles. + + Values: + UNKNOWN_ROLE (0): + Default user role. + ADMINISTRATOR (1): + Product administrator with elevated + privileges. + SERVICE_ACCOUNT (2): + System service account for automated privilege access. + Deprecated: not a role, instead set User.account_type. + """ + + UNKNOWN_ROLE = 0 + ADMINISTRATOR = 1 + SERVICE_ACCOUNT = 2 + + product_object_id: str = proto.Field( + proto.STRING, + number=7, + ) + userid: str = proto.Field( + proto.STRING, + number=1, + ) + user_display_name: str = proto.Field( + proto.STRING, + number=3, + ) + first_name: str = proto.Field( + proto.STRING, + number=100, + ) + middle_name: str = proto.Field( + proto.STRING, + number=101, + ) + last_name: str = proto.Field( + proto.STRING, + number=102, + ) + phone_numbers: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=103, + ) + personal_address: "Location" = proto.Field( + proto.MESSAGE, + number=104, + message="Location", + ) + attribute: "Attribute" = proto.Field( + proto.MESSAGE, + number=8, + message="Attribute", + ) + first_seen_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=10, + message=timestamp_pb2.Timestamp, + ) + account_type: AccountType = proto.Field( + proto.ENUM, + number=9, + enum=AccountType, + ) + groupid: str = proto.Field( + proto.STRING, + number=2, + ) + group_identifiers: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=200, + ) + windows_sid: str = proto.Field( + proto.STRING, + number=4, + ) + email_addresses: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=5, + ) + employee_id: str = proto.Field( + proto.STRING, + number=6, + ) + title: str = proto.Field( + proto.STRING, + number=601, + ) + company_name: str = proto.Field( + proto.STRING, + number=602, + ) + department: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=603, + ) + office_address: "Location" = proto.Field( + proto.MESSAGE, + number=604, + message="Location", + ) + managers: MutableSequence["User"] = proto.RepeatedField( + proto.MESSAGE, + number=605, + message="User", + ) + hire_date: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=606, + message=timestamp_pb2.Timestamp, + ) + termination_date: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=607, + message=timestamp_pb2.Timestamp, + ) + time_off: MutableSequence["TimeOff"] = proto.RepeatedField( + proto.MESSAGE, + number=608, + message="TimeOff", + ) + last_login_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=609, + message=timestamp_pb2.Timestamp, + ) + last_password_change_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=610, + message=timestamp_pb2.Timestamp, + ) + password_expiration_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=611, + message=timestamp_pb2.Timestamp, + ) + account_expiration_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=612, + message=timestamp_pb2.Timestamp, + ) + account_lockout_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=613, + message=timestamp_pb2.Timestamp, + ) + last_bad_password_attempt_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=614, + message=timestamp_pb2.Timestamp, + ) + user_authentication_status: "Authentication.AuthenticationStatus" = proto.Field( + proto.ENUM, + number=701, + enum="Authentication.AuthenticationStatus", + ) + role_name: str = proto.Field( + proto.STRING, + number=702, + ) + role_description: str = proto.Field( + proto.STRING, + number=703, + ) + user_role: Role = proto.Field( + proto.ENUM, + number=704, + enum=Role, + ) + + +class TimeOff(proto.Message): + r"""System record for leave/time-off from a Human Capital + Management (HCM) system. + + Attributes: + interval (google.type.interval_pb2.Interval): + Interval duration of the leave. + description (str): + Description of the leave if available (e.g. + 'Vacation'). + """ + + interval: interval_pb2.Interval = proto.Field( + proto.MESSAGE, + number=1, + message=interval_pb2.Interval, + ) + description: str = proto.Field( + proto.STRING, + number=2, + ) + + +class Permission(proto.Message): + r"""System permission for resource access and modification. + + Attributes: + name (str): + Name of the permission (e.g. + chronicle.analyst.updateRule). + description (str): + Description of the permission (e.g. 'Ability + to update detect rules'). + type_ (google.backstory.types.Permission.PermissionType): + Type of the permission. + """ + + class PermissionType(proto.Enum): + r"""High level categorizations of permission type. + + Values: + UNKNOWN_PERMISSION_TYPE (0): + Default permission type. + ADMIN_WRITE (1): + Administrator write permission. + ADMIN_READ (2): + Administrator read permission. + DATA_WRITE (3): + Data resource access write permission. + DATA_READ (4): + Data resource access read permission. + """ + + UNKNOWN_PERMISSION_TYPE = 0 + ADMIN_WRITE = 1 + ADMIN_READ = 2 + DATA_WRITE = 3 + DATA_READ = 4 + + name: str = proto.Field( + proto.STRING, + number=1, + ) + description: str = proto.Field( + proto.STRING, + number=2, + ) + type_: PermissionType = proto.Field( + proto.ENUM, + number=3, + enum=PermissionType, + ) + + +class Role(proto.Message): + r"""System role for resource access and modification. + + Attributes: + name (str): + System role name for user. + description (str): + System role description for user. + type_ (google.backstory.types.Role.Type): + System role type for well known roles. + """ + + class Type(proto.Enum): + r"""Well-known system roles. + + Values: + TYPE_UNSPECIFIED (0): + Default user role. + ADMINISTRATOR (1): + Product administrator with elevated + privileges. + SERVICE_ACCOUNT (2): + System service account for automated + privilege access. + """ + + TYPE_UNSPECIFIED = 0 + ADMINISTRATOR = 1 + SERVICE_ACCOUNT = 2 + + name: str = proto.Field( + proto.STRING, + number=1, + ) + description: str = proto.Field( + proto.STRING, + number=2, + ) + type_: Type = proto.Field( + proto.ENUM, + number=3, + enum=Type, + ) + + +class Group(proto.Message): + r"""Information about an organizational group. + + Attributes: + product_object_id (str): + Product globally unique user object + identifier, such as an LDAP Object Identifier. + creation_time (google.protobuf.timestamp_pb2.Timestamp): + Group creation time. Deprecated: creation_time should be + populated in Attribute as generic metadata. + group_display_name (str): + Group display name. e.g. "Finance". + attribute (google.backstory.types.Attribute): + Generic entity metadata attributes of the + group. + email_addresses (MutableSequence[str]): + Email addresses of the group. + windows_sid (str): + Microsoft Windows SID of the group. + """ + + product_object_id: str = proto.Field( + proto.STRING, + number=1, + ) + creation_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=100, + message=timestamp_pb2.Timestamp, + ) + group_display_name: str = proto.Field( + proto.STRING, + number=101, + ) + attribute: "Attribute" = proto.Field( + proto.MESSAGE, + number=4, + message="Attribute", + ) + email_addresses: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + windows_sid: str = proto.Field( + proto.STRING, + number=3, + ) + + +class Registry(proto.Message): + r"""Information about a registry key or value. + + Attributes: + registry_key (str): + Registry key associated with an application or system + component (e.g., HKEY\_, HKCU\\Environment...). + registry_value_name (str): + Name of the registry value associated with an + application or system component (e.g. TEMP). + registry_value_data (str): + Data associated with a registry value + (e.g. %USERPROFILE%\Local Settings\Temp). + registry_value_type (google.backstory.types.Registry.Type): + Type of the registry value. + registry_value_binary_data (bytes): + Binary data associated with a registry value. + This field is only populated if the registry + value type is BINARY. This field is not + populated for other registry value types. + """ + + class Type(proto.Enum): + r"""Type of the registry value. These values are based on the + Windows Registry value types: + + https://learn.microsoft.com/en-us/windows/win32/sysinfo/registry-value-types + + Values: + TYPE_UNSPECIFIED (0): + Default registry value type used when the + type is unknown. + NONE (1): + The registry value is not set and only the + key exists. + SZ (2): + A null-terminated string. + EXPAND_SZ (3): + A null-terminated string that contains + unexpanded references to environment variables + BINARY (4): + Binary data in any form. + DWORD (5): + A 32-bit number. + DWORD_LITTLE_ENDIAN (6): + A 32-bit number in little-endian format. + DWORD_BIG_ENDIAN (7): + A 32-bit number in big-endian format. + LINK (8): + A null-terminated Unicode string that + contains the target path of a symbolic link. + MULTI_SZ (9): + A sequence of null-terminated strings, + terminated by an empty string + RESOURCE_LIST (10): + A device driver resource list. + QWORD (11): + A 64-bit number. + QWORD_LITTLE_ENDIAN (12): + A 64-bit number in little-endian format. + """ + + TYPE_UNSPECIFIED = 0 + NONE = 1 + SZ = 2 + EXPAND_SZ = 3 + BINARY = 4 + DWORD = 5 + DWORD_LITTLE_ENDIAN = 6 + DWORD_BIG_ENDIAN = 7 + LINK = 8 + MULTI_SZ = 9 + RESOURCE_LIST = 10 + QWORD = 11 + QWORD_LITTLE_ENDIAN = 12 + + registry_key: str = proto.Field( + proto.STRING, + number=1, + ) + registry_value_name: str = proto.Field( + proto.STRING, + number=2, + ) + registry_value_data: str = proto.Field( + proto.STRING, + number=3, + ) + registry_value_type: Type = proto.Field( + proto.ENUM, + number=4, + enum=Type, + ) + registry_value_binary_data: bytes = proto.Field( + proto.BYTES, + number=5, + ) + + +class WmiPersistenceItem(proto.Message): + r"""Information about a WMI persistence item. + + Attributes: + caption (str): + A brief title or caption for the WMI object. + name (str): + The name of the WMI object. + setting_id (str): + The identifier for the setting. + derivation (str): + The base class from which the WMI class is derived (e.g., + CIM_Setting). + property_count (int): + The number of properties in the WMI object. + rel_path (str): + The relative path to the WMI object (e.g., + Win32_StartupCommand.Command='''). + dynasty (str): + The top-level class in the WMI inheritance hierarchy (e.g., + CMI_Setting). + wmi_super_class (str): + The immediate parent class in the WMI + inheritance hierarchy. + wmi_class (str): + The name of the WMI class. + genus (int): + An integer representing the type or version + of the WMI object. + """ + + caption: str = proto.Field( + proto.STRING, + number=1, + ) + name: str = proto.Field( + proto.STRING, + number=2, + ) + setting_id: str = proto.Field( + proto.STRING, + number=3, + ) + derivation: str = proto.Field( + proto.STRING, + number=4, + ) + property_count: int = proto.Field( + proto.INT64, + number=5, + ) + rel_path: str = proto.Field( + proto.STRING, + number=6, + ) + dynasty: str = proto.Field( + proto.STRING, + number=7, + ) + wmi_super_class: str = proto.Field( + proto.STRING, + number=8, + ) + wmi_class: str = proto.Field( + proto.STRING, + number=9, + ) + genus: int = proto.Field( + proto.INT64, + number=10, + ) + + +class Location(proto.Message): + r"""Information about a location. + + Attributes: + city (str): + The city. + state (str): + The state. + country_or_region (str): + The country or region. + name (str): + Custom location name (e.g. building or site + name like "London Office"). For cloud + environments, this is the region (e.g. + "us-west2"). + desk_name (str): + Desk name or individual location, typically + for an employee in an office. + (e.g. "IN-BLR-BCPC-11-1121D"). + floor_name (str): + Floor name, number or a combination of the + two for a building. (e.g. "1-A"). + region_latitude (float): + Deprecated: use region_coordinates. + region_longitude (float): + Deprecated: use region_coordinates. + region_coordinates (google.type.latlng_pb2.LatLng): + Coordinates for the associated region. See + https://cloud.google.com/vision/docs/reference/rest/v1/LatLng + for a description of the fields. + """ + + city: str = proto.Field( + proto.STRING, + number=1, + ) + state: str = proto.Field( + proto.STRING, + number=2, + ) + country_or_region: str = proto.Field( + proto.STRING, + number=3, + ) + name: str = proto.Field( + proto.STRING, + number=4, + ) + desk_name: str = proto.Field( + proto.STRING, + number=5, + ) + floor_name: str = proto.Field( + proto.STRING, + number=6, + ) + region_latitude: float = proto.Field( + proto.FLOAT, + number=7, + ) + region_longitude: float = proto.Field( + proto.FLOAT, + number=8, + ) + region_coordinates: latlng_pb2.LatLng = proto.Field( + proto.MESSAGE, + number=9, + message=latlng_pb2.LatLng, + ) + + +class ScheduledTask(proto.Message): + r"""Deprecated: use WindowsScheduledTask for Windows scheduled + tasks or ScheduledCronTask for cron jobs. + Information about a scheduled task. + + Attributes: + minute (int): + The minute of the hour (0-59). + hour (int): + The hour of the day (0-23). + month_day (int): + The day of the month (1-31). + month (int): + The month of the year (1-12). + week_day (int): + The day of the week (0-6, Sunday=0). + comment (str): + A comment or description for the task. + author (str): + The account name that authored or last + modified the scheduled task. + """ + + minute: int = proto.Field( + proto.INT32, + number=1, + ) + hour: int = proto.Field( + proto.INT32, + number=2, + ) + month_day: int = proto.Field( + proto.INT32, + number=3, + ) + month: int = proto.Field( + proto.INT32, + number=4, + ) + week_day: int = proto.Field( + proto.INT32, + number=5, + ) + comment: str = proto.Field( + proto.STRING, + number=6, + ) + author: str = proto.Field( + proto.STRING, + number=7, + ) + + +class WindowsScheduledTask(proto.Message): + r"""Information about a Windows scheduled task. + + Attributes: + author (str): + The account name that authored or last + modified the scheduled task. + virtual_path (str): + The task's path in the Task Scheduler + library. + exit_code (int): + The result which was returned the last time + the registered task was run. + state (google.backstory.types.WindowsScheduledTask.TaskState): + The operation state of the task. + logon_type (google.backstory.types.WindowsScheduledTask.TaskLogonType): + The logon type of the task. + task_actions (MutableSequence[google.backstory.types.WindowsScheduledTask.TaskAction]): + The actions of the scheduled task. + task_triggers (MutableSequence[google.backstory.types.WindowsScheduledTask.TaskTrigger]): + The triggers of the scheduled task. + """ + + class TaskState(proto.Enum): + r"""Enum representing the operation state of the task. + + Values: + TASK_STATE_UNSPECIFIED (0): + The state of the task is unknown or not + specified. + DISABLED (1): + The task is registered but is disabled and no + instances of the task are queued or running. The + task cannot be run until it is enabled. + QUEUED (2): + Instances of the task are queued. + ACTIVE (3): + The task is ready to be executed, but no + instances are queued or running. + RUNNING (4): + One or more instances of the task are + running. + """ + + TASK_STATE_UNSPECIFIED = 0 + DISABLED = 1 + QUEUED = 2 + ACTIVE = 3 + RUNNING = 4 + + class TaskLogonType(proto.Enum): + r"""Enum representing the logon type of the task. + + Values: + TASK_LOGON_TYPE_UNSPECIFIED (0): + The logon method is not specified. Used for + non-NT credentials. + PASSWORD (1): + Use a password for logging on the user. The + password must be supplied at registration time. + S4U (2): + Use an existing interactive token to run a + task. The user must log on using a service for + user (S4U) logon. When an S4U logon is used, no + password is stored by the system and there is no + access to either the network or encrypted files. + INTERACTIVE_TOKEN (3): + User must already be logged on. The task will + be run only in an existing interactive session. + GROUP (4): + Logon with group credentials. + SERVICE_ACCOUNT (5): + Indicates that a Local System, Local Service, + or Network Service account is being used as a + security context to run the task. + INTERACTIVE_TOKEN_OR_PASSWORD (6): + First use the interactive token. If the user is not logged + on (no interactive token is available), the password is + used. The password must be specified when a task is + registered. This flag is not recommended for new tasks + because it is less reliable than TASK_LOGON_PASSWORD. + """ + + TASK_LOGON_TYPE_UNSPECIFIED = 0 + PASSWORD = 1 + S4U = 2 + INTERACTIVE_TOKEN = 3 + GROUP = 4 + SERVICE_ACCOUNT = 5 + INTERACTIVE_TOKEN_OR_PASSWORD = 6 + + class TaskAction(proto.Message): + r"""The task action. + + Attributes: + action_type (google.backstory.types.WindowsScheduledTask.TaskAction.ActionType): + The action type of the task. + exec_arguments (MutableSequence[str]): + The arguments of the task. This field is only + populated if the task action type is EXEC. + exec_working_directory (str): + The executable working directory of the task. + This field is only populated if the task action + type is EXEC. + com_class_id (str): + The COM class IF the action is COM handler. This field is + only populated if the task action type is COM_HANDLER. + com_data (str): + The data of the task. This field is only populated if the + task action type is COM_HANDLER. + """ + + class ActionType(proto.Enum): + r"""Enum representing the action type of the task. + + Values: + ACTION_TYPE_UNSPECIFIED (0): + The action type is not specified. + EXEC (1): + This action performs a command-line + operation. For example, the action can run a + script, launch an executable, or, if the name of + a document is provided, find its associated + application and launch the application with the + document. + COM_HANDLER (2): + This action fires a handler. This action can only be used if + the task Compatibility property is set to + TASK_COMPATIBILITY_V2. + SEND_EMAIL (3): + This action sends an email message. This action can only be + used if the task Compatibility property is set to + TASK_COMPATIBILITY_V2. + SHOW_MESSAGE (4): + This action shows a message box. This action can only be + used if the task Compatibility property is set to + TASK_COMPATIBILITY_V2. + """ + + ACTION_TYPE_UNSPECIFIED = 0 + EXEC = 1 + COM_HANDLER = 2 + SEND_EMAIL = 3 + SHOW_MESSAGE = 4 + + action_type: "WindowsScheduledTask.TaskAction.ActionType" = proto.Field( + proto.ENUM, + number=1, + enum="WindowsScheduledTask.TaskAction.ActionType", + ) + exec_arguments: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + exec_working_directory: str = proto.Field( + proto.STRING, + number=3, + ) + com_class_id: str = proto.Field( + proto.STRING, + number=4, + ) + com_data: str = proto.Field( + proto.STRING, + number=5, + ) + + class TaskTrigger(proto.Message): + r"""The trigger of the scheduled task. + + Attributes: + enabled (bool): + Indicates whether the task trigger is + enabled. + duration (google.protobuf.duration_pb2.Duration): + The duration of the task trigger repetition. + interval (str): + The interval between each repetition of the task. The format + for this string is ``PDTHMS`` + (for example, "PT5M" is 5 minutes, "PT1H" is 1 hour, and + "PT20M" is 20 minutes). The maximum time allowed is 31 days, + and the minimum time allowed is 1 minute. + trigger_type (google.backstory.types.WindowsScheduledTask.TaskTrigger.TriggerType): + The trigger frequency of the task. + """ + + class TriggerType(proto.Enum): + r"""Enum representing the trigger type of the task. For more details, + see + https://learn.microsoft.com/en-us/windows/win32/api/taskschd/ne-taskschd-task_trigger_type2. + + Values: + TRIGGER_TYPE_UNSPECIFIED (0): + The trigger frequency is not specified. + EVENT (1): + Triggers the task when a specific event + occurs. + TIME (2): + Triggers the task at a specific time of day. + DAILY (3): + Triggers the task on a daily schedule. For + example, the task starts at a specific time + every day, every other day, or every third day. + WEEKLY (4): + Triggers the task on a weekly schedule. For + example, the task starts at 8:00 AM on a + specific day every week or other week. + MONTHLY (5): + Triggers the task on a monthly schedule. For + example, the task starts on specific days of + specific months. + MONTHLYDOW (6): + Triggers the task on a monthly day-of-week + schedule. For example, the task starts on a + specific days of the week, weeks of the month, + and months of the year. + IDLE (7): + Triggers the task when the computer goes into + an idle state. + REGISTRATION (8): + Triggers the task when the task is + registered. + BOOT (9): + Triggers the task when the computer boots. + LOGON (10): + Triggers the task when a specific user logs + on. + SESSION_STATE_CHANGE (11): + Triggers the task when a specific user + session state changes. + CUSTOM_TRIGGER01 (12): + Custom trigger 01. + """ + + TRIGGER_TYPE_UNSPECIFIED = 0 + EVENT = 1 + TIME = 2 + DAILY = 3 + WEEKLY = 4 + MONTHLY = 5 + MONTHLYDOW = 6 + IDLE = 7 + REGISTRATION = 8 + BOOT = 9 + LOGON = 10 + SESSION_STATE_CHANGE = 11 + CUSTOM_TRIGGER01 = 12 + + enabled: bool = proto.Field( + proto.BOOL, + number=1, + ) + duration: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=2, + message=duration_pb2.Duration, + ) + interval: str = proto.Field( + proto.STRING, + number=3, + ) + trigger_type: "WindowsScheduledTask.TaskTrigger.TriggerType" = proto.Field( + proto.ENUM, + number=4, + enum="WindowsScheduledTask.TaskTrigger.TriggerType", + ) + + author: str = proto.Field( + proto.STRING, + number=1, + ) + virtual_path: str = proto.Field( + proto.STRING, + number=2, + ) + exit_code: int = proto.Field( + proto.INT32, + number=3, + ) + state: TaskState = proto.Field( + proto.ENUM, + number=4, + enum=TaskState, + ) + logon_type: TaskLogonType = proto.Field( + proto.ENUM, + number=5, + enum=TaskLogonType, + ) + task_actions: MutableSequence[TaskAction] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message=TaskAction, + ) + task_triggers: MutableSequence[TaskTrigger] = proto.RepeatedField( + proto.MESSAGE, + number=7, + message=TaskTrigger, + ) + + +class ScheduledCronTask(proto.Message): + r"""Information about a scheduled cron task. + + Attributes: + minute (str): + Crontab minute field. Value is an integer between 0 and 59 + and can also be a range or list of values (e.g., "0-59", + "0-59/5", "0,15,30,45") and it // can also be an asterisk + (\*) to indicate first-last minutes. More on crontab format + can be found here: + https://www.linux.org/docs/man5/crontab.html + hour (str): + Crontab hour field. Value is an integer between 0 and 23, a + range or list of values (e.g., "0-6", "*/2", "1,2"), or an + asterisk (*) to indicate first-last hours. + month_day (str): + Crontab day of month field. Value is an integer between 1 + and 31, a range or list of values (e.g., "1-7", "1-31/7", + "1,15"), or an asterisk (\*) to indicate first-last days of + month. + month (str): + Crontab month field. Value is an integer between 1 and 12 or + a 3-letter name (e.g., "Jan"), a range or list of values + (e.g., "1-3", "*/2", "1,6"), or an asterisk (*) to indicate + first-last months. + week_day (str): + Crontab day of week field. Value is an integer between 0 and + 7 (0 or 7 is Sunday) or a 3-letter name (e.g., "Fri"), a + range or list of values (e.g., "1-5", "0,6"), or an asterisk + (\*) to indicate first-last days of week. + comment (str): + A comment or description for the task. + author (str): + The author or creator of the task. + event (str): + Crontab special string or event (e.g., + "@reboot", "@daily"). + path (str): + The PATH environment variable defined in the + crontab file. + """ + + minute: str = proto.Field( + proto.STRING, + number=1, + ) + hour: str = proto.Field( + proto.STRING, + number=2, + ) + month_day: str = proto.Field( + proto.STRING, + number=3, + ) + month: str = proto.Field( + proto.STRING, + number=4, + ) + week_day: str = proto.Field( + proto.STRING, + number=5, + ) + comment: str = proto.Field( + proto.STRING, + number=6, + ) + author: str = proto.Field( + proto.STRING, + number=7, + ) + event: str = proto.Field( + proto.STRING, + number=8, + ) + path: str = proto.Field( + proto.STRING, + number=9, + ) + + +class ScheduledAnacronTask(proto.Message): + r"""Information about a scheduled anacron task. + + Attributes: + period (str): + Anacrontab period field. Value is an integer + in days, or a string like "@daily", "@weekly", + or "@monthly". + delay_minutes (int): + The delay in minutes before the job is run. + job_id (str): + The unique identifier of the job. + path (str): + The PATH environment variable defined in the + anacrontab file. + source_line (str): + The original source line from the anacrontab + file. + """ + + period: str = proto.Field( + proto.STRING, + number=1, + ) + delay_minutes: int = proto.Field( + proto.INT64, + number=2, + ) + job_id: str = proto.Field( + proto.STRING, + number=3, + ) + path: str = proto.Field( + proto.STRING, + number=4, + ) + source_line: str = proto.Field( + proto.STRING, + number=5, + ) + + +class Volume(proto.Message): + r"""Information about a storage volume. + + Attributes: + file_system (str): + The name of the file system on the volume + (e.g., "NTFS", "FAT32"). + mount_point (str): + The path where the volume is mounted (e.g., + "C:", "/mnt/data"). + device_path (str): + The system path to the device (e.g., + "\\.\HarddiskVolume1", "/dev/sda1"). + is_mounted (bool): + Indicates whether the volume is currently + mounted. + is_read_only (bool): + Indicates whether the volume is mounted as + read-only. + name (str): + The user-assigned label or name for the + volume. + """ + + file_system: str = proto.Field( + proto.STRING, + number=1, + ) + mount_point: str = proto.Field( + proto.STRING, + number=2, + ) + device_path: str = proto.Field( + proto.STRING, + number=3, + ) + is_mounted: bool = proto.Field( + proto.BOOL, + number=4, + ) + is_read_only: bool = proto.Field( + proto.BOOL, + number=5, + ) + name: str = proto.Field( + proto.STRING, + number=6, + ) + + +class Service(proto.Message): + r"""Information about a Windows service. + + Attributes: + display_name (str): + The user-friendly display name of the + service. + service_type (google.backstory.types.Service.ServiceType): + Deprecated: use service_types instead. The type of service. + service_types (MutableSequence[google.backstory.types.Service.ServiceType]): + The list of service types. + startup_type (google.backstory.types.Service.StartupType): + The startup type of the service. + state (google.backstory.types.Service.State): + The status of the service. + """ + + class ServiceType(proto.Enum): + r"""The type of service. + + Values: + SERVICE_TYPE_UNSPECIFIED (0): + Default service type. + KERNEL_DRIVER (1): + A kernel driver. + FILE_SYSTEM_DRIVER (2): + A file system driver. + WIN32_OWN_PROCESS (3): + A process that is owned by the service. This + is a Windows-specific service type. + WIN32_SHARE_PROCESS (4): + A process that is shared by the service. This + is a Windows-specific service type. + ADAPTER (5): + An adapter. This is a Windows-specific + service type. + RECOGNIZER_DRIVER (6): + A recognizer driver. This is a + Windows-specific service type. + INTERACTIVE_PROCESS (7): + An interactive process. This is a + Windows-specific service type. + """ + + SERVICE_TYPE_UNSPECIFIED = 0 + KERNEL_DRIVER = 1 + FILE_SYSTEM_DRIVER = 2 + WIN32_OWN_PROCESS = 3 + WIN32_SHARE_PROCESS = 4 + ADAPTER = 5 + RECOGNIZER_DRIVER = 6 + INTERACTIVE_PROCESS = 7 + + class StartupType(proto.Enum): + r"""How the service is started. + + Values: + STARTUP_TYPE_UNSPECIFIED (0): + Default startup type. + AUTOMATIC (1): + The service is started automatically. + MANUAL (2): + The service is started manually by a user. + DISABLED (3): + The service is disabled and will not start + automatically. + """ + + STARTUP_TYPE_UNSPECIFIED = 0 + AUTOMATIC = 1 + MANUAL = 2 + DISABLED = 3 + + class State(proto.Enum): + r"""The current status of the service. + + Values: + STATE_UNSPECIFIED (0): + Default service status. + RUNNING (1): + The service is running. + STOPPED (2): + The service is stopped. This is a + Windows-specific service status. + PAUSED (3): + The service is paused. This is a + Windows-specific service status. + COMPLETED (4): + The service is completed. + START_PENDING (5): + The service is starting. + STOP_PENDING (6): + The service is stopping. + PAUSE_PENDING (7): + The service is pausing. + CONTINUE_PENDING (8): + The service is continuing. + """ + + STATE_UNSPECIFIED = 0 + RUNNING = 1 + STOPPED = 2 + PAUSED = 3 + COMPLETED = 4 + START_PENDING = 5 + STOP_PENDING = 6 + PAUSE_PENDING = 7 + CONTINUE_PENDING = 8 + + display_name: str = proto.Field( + proto.STRING, + number=1, + ) + service_type: ServiceType = proto.Field( + proto.ENUM, + number=3, + enum=ServiceType, + ) + service_types: MutableSequence[ServiceType] = proto.RepeatedField( + proto.ENUM, + number=6, + enum=ServiceType, + ) + startup_type: StartupType = proto.Field( + proto.ENUM, + number=4, + enum=StartupType, + ) + state: State = proto.Field( + proto.ENUM, + number=5, + enum=State, + ) + + +class Resource(proto.Message): + r"""Information about a resource such as a task, Cloud Storage + bucket, database, disk, logical policy, or something similar. + + Attributes: + type_ (str): + Deprecated: use resource_type instead. + resource_type (google.backstory.types.Resource.ResourceType): + Resource type. + resource_subtype (str): + Resource sub-type (e.g. "BigQuery", + "Bigtable"). + id (str): + Deprecated: Use resource.name or resource.product_object_id. + name (str): + The full name of the resource. For example, + Google Cloud: + //cloudresourcemanager.googleapis.com/projects/wombat-123, + and AWS: arn:aws:iam::123456789012:user/johndoe. + parent (str): + The parent of the resource. For a database table, the parent + is the database. For a storage object, the bucket name. + Deprecated: use resource_ancestors.name. + product_object_id (str): + A vendor-specific identifier to uniquely + identify the entity (a GUID, OID, or similar) + This field can be used as an entity indicator + for a Resource entity. + attribute (google.backstory.types.Attribute): + Generic entity metadata attributes of the + resource. + scheduled_task (google.backstory.types.ScheduledTask): + DEPRECATED: use windows_scheduled_task for Windows scheduled + tasks or scheduled_cron_task for cron jobs. Information + about a scheduled task associated with the resource. + scheduled_cron_task (google.backstory.types.ScheduledCronTask): + Information about a scheduled cron task + associated with the resource. + scheduled_anacron_task (google.backstory.types.ScheduledAnacronTask): + Information about a scheduled anacron task + associated with the resource. + windows_scheduled_task (google.backstory.types.WindowsScheduledTask): + Information about a Windows scheduled task + associated with the resource. + volume (google.backstory.types.Volume): + Information about a storage volume associated + with the resource. + service (google.backstory.types.Service): + Information about a Windows service + associated with the resource. + """ + + class ResourceType(proto.Enum): + r"""The type of resource. + + Values: + UNSPECIFIED (0): + Default type. + MUTEX (1): + Mutex. + TASK (2): + Task. + PIPE (3): + Named pipe. + DEVICE (4): + Device. + FIREWALL_RULE (5): + Firewall rule. + MAILBOX_FOLDER (6): + Mailbox folder. + VPC_NETWORK (7): + VPC Network. + VIRTUAL_MACHINE (8): + Virtual machine. + STORAGE_BUCKET (9): + Storage bucket. + STORAGE_OBJECT (10): + Storage object. + DATABASE (11): + Database. + TABLE (12): + Data table. + CLOUD_PROJECT (13): + Cloud project. + CLOUD_ORGANIZATION (14): + Cloud organization. + SERVICE_ACCOUNT (15): + Service account. + ACCESS_POLICY (16): + Access policy. + CLUSTER (17): + Cluster. + SETTING (18): + Settings. + DATASET (19): + Dataset. + BACKEND_SERVICE (20): + Endpoint that receive traffic from a load + balancer or proxy. + POD (21): + Pod, which is a collection of containers. + Often used in Kubernetes. + CONTAINER (22): + Container. + FUNCTION (23): + Cloud function. + RUNTIME (24): + Runtime. + IP_ADDRESS (25): + IP address. + DISK (26): + Disk. + VOLUME (27): + Volume. + IMAGE (28): + Machine image. + SNAPSHOT (29): + Snapshot. + REPOSITORY (30): + Repository. + CREDENTIAL (31): + Credential, e.g. access keys, ssh keys, + tokens, certificates. + LOAD_BALANCER (32): + Load balancer. + GATEWAY (33): + Gateway. + SUBNET (34): + Subnet. + USER (35): + User. + SERVICE (36): + Service. + """ + + UNSPECIFIED = 0 + MUTEX = 1 + TASK = 2 + PIPE = 3 + DEVICE = 4 + FIREWALL_RULE = 5 + MAILBOX_FOLDER = 6 + VPC_NETWORK = 7 + VIRTUAL_MACHINE = 8 + STORAGE_BUCKET = 9 + STORAGE_OBJECT = 10 + DATABASE = 11 + TABLE = 12 + CLOUD_PROJECT = 13 + CLOUD_ORGANIZATION = 14 + SERVICE_ACCOUNT = 15 + ACCESS_POLICY = 16 + CLUSTER = 17 + SETTING = 18 + DATASET = 19 + BACKEND_SERVICE = 20 + POD = 21 + CONTAINER = 22 + FUNCTION = 23 + RUNTIME = 24 + IP_ADDRESS = 25 + DISK = 26 + VOLUME = 27 + IMAGE = 28 + SNAPSHOT = 29 + REPOSITORY = 30 + CREDENTIAL = 31 + LOAD_BALANCER = 32 + GATEWAY = 33 + SUBNET = 34 + USER = 35 + SERVICE = 36 + + type_: str = proto.Field( + proto.STRING, + number=1, + ) + resource_type: ResourceType = proto.Field( + proto.ENUM, + number=5, + enum=ResourceType, + ) + resource_subtype: str = proto.Field( + proto.STRING, + number=6, + ) + id: str = proto.Field( + proto.STRING, + number=2, + ) + name: str = proto.Field( + proto.STRING, + number=3, + ) + parent: str = proto.Field( + proto.STRING, + number=4, + ) + product_object_id: str = proto.Field( + proto.STRING, + number=8, + ) + attribute: "Attribute" = proto.Field( + proto.MESSAGE, + number=7, + message="Attribute", + ) + scheduled_task: "ScheduledTask" = proto.Field( + proto.MESSAGE, + number=9, + message="ScheduledTask", + ) + scheduled_cron_task: "ScheduledCronTask" = proto.Field( + proto.MESSAGE, + number=12, + message="ScheduledCronTask", + ) + scheduled_anacron_task: "ScheduledAnacronTask" = proto.Field( + proto.MESSAGE, + number=13, + message="ScheduledAnacronTask", + ) + windows_scheduled_task: "WindowsScheduledTask" = proto.Field( + proto.MESSAGE, + number=14, + message="WindowsScheduledTask", + ) + volume: "Volume" = proto.Field( + proto.MESSAGE, + number=10, + message="Volume", + ) + service: "Service" = proto.Field( + proto.MESSAGE, + number=11, + message="Service", + ) + + +class Label(proto.Message): + r"""Key value labels. + + Attributes: + key (str): + The key. + value (str): + The value. + source (str): + Where the label is derived from. + rbac_enabled (bool): + Indicates whether this label can be used for + Data RBAC + """ + + key: str = proto.Field( + proto.STRING, + number=1, + ) + value: str = proto.Field( + proto.STRING, + number=2, + ) + source: str = proto.Field( + proto.STRING, + number=3, + ) + rbac_enabled: bool = proto.Field( + proto.BOOL, + number=4, + ) + + +class Cloud(proto.Message): + r"""Metadata related to the cloud environment. + + Attributes: + environment (google.backstory.types.Cloud.CloudEnvironment): + The Cloud environment. + vpc (google.backstory.types.Resource): + The cloud environment VPC. + Deprecated. + project (google.backstory.types.Resource): + The cloud environment project information. Deprecated: Use + Resource.resource_ancestors + availability_zone (str): + The cloud environment availability zone + (different from region which is location.name). + """ + + class CloudEnvironment(proto.Enum): + r"""The service provider environment. + + Values: + UNSPECIFIED_CLOUD_ENVIRONMENT (0): + Default. + GOOGLE_CLOUD_PLATFORM (1): + Google Cloud Platform. + AMAZON_WEB_SERVICES (2): + Amazon Web Services. + MICROSOFT_AZURE (3): + Microsoft Azure. + """ + + UNSPECIFIED_CLOUD_ENVIRONMENT = 0 + GOOGLE_CLOUD_PLATFORM = 1 + AMAZON_WEB_SERVICES = 2 + MICROSOFT_AZURE = 3 + + environment: CloudEnvironment = proto.Field( + proto.ENUM, + number=1, + enum=CloudEnvironment, + ) + vpc: "Resource" = proto.Field( + proto.MESSAGE, + number=2, + message="Resource", + ) + project: "Resource" = proto.Field( + proto.MESSAGE, + number=3, + message="Resource", + ) + availability_zone: str = proto.Field( + proto.STRING, + number=4, + ) + + +class Artifact(proto.Message): + r"""Information about an artifact. The artifact can only be an + IP. + + Attributes: + ip (str): + IP address of the artifact. + This field can be used as an entity indicator + for an external destination IP entity. + prevalence (google.backstory.types.Prevalence): + The prevalence of the artifact within the + customer's environment. + first_seen_time (google.protobuf.timestamp_pb2.Timestamp): + First seen timestamp of the IP in the + customer's environment. + last_seen_time (google.protobuf.timestamp_pb2.Timestamp): + Last seen timestamp of the IP address in the + customer's environment. + location (google.backstory.types.Location): + Location of the Artifact's IP address. + network (google.backstory.types.Network): + Network information related to the Artifact's + IP address. + as_owner (str): + Owner of the Autonomous System to which the + IP address belongs. + asn (int): + Autonomous System Number to which the IP + address belongs. + jarm (str): + The JARM hash for the IP address. + (https://engineering.salesforce.com/easily-identify-malicious-servers-on-the-internet-with-jarm-e095edac525a). + last_https_certificate (google.backstory.types.SSLCertificate): + SSL certificate information about the IP + address. + last_https_certificate_date (google.protobuf.timestamp_pb2.Timestamp): + Most recent date for the certificate in + VirusTotal. + regional_internet_registry (str): + RIR (one of the current RIRs: AFRINIC, ARIN, + APNIC, LACNIC or RIPE NCC). + tags (MutableSequence[str]): + Identification attributes + whois (str): + WHOIS information as returned from the + pertinent WHOIS server. + whois_date (google.protobuf.timestamp_pb2.Timestamp): + Date of the last update of the WHOIS record + in VirusTotal. + tunnels (MutableSequence[google.backstory.types.Tunnels]): + VPN tunnels. + anonymous (bool): + Whether the VPN tunnels are configured for + anonymous browsing or not. + artifact_client (google.backstory.types.ArtifactClient): + Entity or software accessing or utilizing + network resources. + risks (MutableSequence[str]): + This field lists potential risks associated + with the network activity. + """ + + ip: str = proto.Field( + proto.STRING, + number=1, + ) + prevalence: "Prevalence" = proto.Field( + proto.MESSAGE, + number=2, + message="Prevalence", + ) + first_seen_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + last_seen_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=4, + message=timestamp_pb2.Timestamp, + ) + location: "Location" = proto.Field( + proto.MESSAGE, + number=5, + message="Location", + ) + network: "Network" = proto.Field( + proto.MESSAGE, + number=6, + message="Network", + ) + as_owner: str = proto.Field( + proto.STRING, + number=7, + ) + asn: int = proto.Field( + proto.INT64, + number=8, + ) + jarm: str = proto.Field( + proto.STRING, + number=9, + ) + last_https_certificate: "SSLCertificate" = proto.Field( + proto.MESSAGE, + number=10, + message="SSLCertificate", + ) + last_https_certificate_date: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=11, + message=timestamp_pb2.Timestamp, + ) + regional_internet_registry: str = proto.Field( + proto.STRING, + number=12, + ) + tags: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=13, + ) + whois: str = proto.Field( + proto.STRING, + number=14, + ) + whois_date: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=15, + message=timestamp_pb2.Timestamp, + ) + tunnels: MutableSequence["Tunnels"] = proto.RepeatedField( + proto.MESSAGE, + number=16, + message="Tunnels", + ) + anonymous: bool = proto.Field( + proto.BOOL, + number=17, + ) + artifact_client: "ArtifactClient" = proto.Field( + proto.MESSAGE, + number=18, + message="ArtifactClient", + ) + risks: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=19, + ) + + +class Tunnels(proto.Message): + r"""VPN tunnels. + + Attributes: + provider (str): + The provider of the VPN tunnels being used. + type_ (str): + The type of the VPN tunnels. + """ + + provider: str = proto.Field( + proto.STRING, + number=1, + ) + type_: str = proto.Field( + proto.STRING, + number=2, + ) + + +class ArtifactClient(proto.Message): + r"""Entity or software accessing or utilizing network resources. + + Attributes: + behaviors (MutableSequence[str]): + The behaviors of the client accessing the + network. + proxies (MutableSequence[str]): + The type of proxies used by the client. + """ + + behaviors: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + proxies: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + +class Favicon(proto.Message): + r"""Difference hash and MD5 hash of the domain's favicon. + + Attributes: + raw_md5 (str): + Favicon's MD5 hash. + dhash (str): + Difference hash. + """ + + raw_md5: str = proto.Field( + proto.STRING, + number=1, + ) + dhash: str = proto.Field( + proto.STRING, + number=2, + ) + + +class DNSRecord(proto.Message): + r"""DNS record. + + Attributes: + type_ (str): + Type. + value (str): + Value. + ttl (google.protobuf.duration_pb2.Duration): + Time to live. + priority (int): + Priority. + retry (int): + Retry. + refresh (google.protobuf.duration_pb2.Duration): + Refresh. + minimum (google.protobuf.duration_pb2.Duration): + Minimum. + expire (google.protobuf.duration_pb2.Duration): + Expire. + serial (int): + Serial. + rname (str): + Rname. + """ + + type_: str = proto.Field( + proto.STRING, + number=1, + ) + value: str = proto.Field( + proto.STRING, + number=2, + ) + ttl: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=3, + message=duration_pb2.Duration, + ) + priority: int = proto.Field( + proto.INT64, + number=4, + ) + retry: int = proto.Field( + proto.INT64, + number=5, + ) + refresh: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=6, + message=duration_pb2.Duration, + ) + minimum: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=7, + message=duration_pb2.Duration, + ) + expire: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=8, + message=duration_pb2.Duration, + ) + serial: int = proto.Field( + proto.INT64, + number=9, + ) + rname: str = proto.Field( + proto.STRING, + number=10, + ) + + +class SSLCertificate(proto.Message): + r"""SSL certificate. + + Attributes: + cert_signature (google.backstory.types.SSLCertificate.CertSignature): + Certificate's signature and algorithm. + extension (google.backstory.types.SSLCertificate.Extension): + (DEPRECATED) certificate's extension. + cert_extensions (google.protobuf.struct_pb2.Struct): + Certificate's extensions. + first_seen_time (google.protobuf.timestamp_pb2.Timestamp): + Date the certificate was first retrieved by + VirusTotal. + issuer (google.backstory.types.SSLCertificate.Subject): + Certificate's issuer data. + ec (google.backstory.types.SSLCertificate.EC): + EC public key information. + serial_number (str): + Certificate's serial number hexdump. + signature_algorithm (str): + Algorithm used for the signature (for + example, "sha1RSA"). + size (int): + Certificate content length. + subject (google.backstory.types.SSLCertificate.Subject): + Certificate's subject data. + thumbprint (str): + Certificate's content SHA1 hash. + thumbprint_sha256 (str): + Certificate's content SHA256 hash. + validity (google.backstory.types.SSLCertificate.Validity): + Certificate's validity period. + version (str): + Certificate version (typically "V1", "V2" or + "V3"). + public_key (google.backstory.types.SSLCertificate.PublicKey): + Public key information. + """ + + class CertSignature(proto.Message): + r"""Certificate's signature and algorithm. + + Attributes: + signature (str): + Signature. + signature_algorithm (str): + Algorithm. + """ + + signature: str = proto.Field( + proto.STRING, + number=1, + ) + signature_algorithm: str = proto.Field( + proto.STRING, + number=2, + ) + + class AuthorityKeyId(proto.Message): + r"""Identifies the public key to be used to verify the signature + on this certificate or CRL. + + Attributes: + keyid (str): + Key hexdump. + serial_number (str): + Serial number hexdump. + """ + + keyid: str = proto.Field( + proto.STRING, + number=1, + ) + serial_number: str = proto.Field( + proto.STRING, + number=2, + ) + + class Extension(proto.Message): + r"""Certificate's extensions. + + Attributes: + ca (bool): + Whether the subject acts as a certificate + authority (CA) or not. + subject_key_id (str): + Identifies the public key being certified. + authority_key_id (google.backstory.types.SSLCertificate.AuthorityKeyId): + Identifies the public key to be used to + verify the signature on this certificate or CRL. + key_usage (str): + The purpose for which the certified public + key is used. + ca_info_access (str): + Authority information access locations are + URLs that are added to a certificate in its + authority information access extension. + crl_distribution_points (str): + CRL distribution points to which a + certificate user should refer to ascertain if + the certificate has been revoked. + extended_key_usage (str): + One or more purposes for which the certified + public key may be used, in addition to or in + place of the basic purposes indicated in the key + usage extension field. + subject_alternative_name (str): + Contains one or more alternative names, using + any of a variety of name forms, for the entity + that is bound by the CA to the certified public + key. + certificate_policies (str): + Different certificate policies will relate to + different applications which may use the + certified key. + netscape_cert_comment (str): + Used to include free-form text comments + inside certificates. + cert_template_name_dc (str): + BMP data value "DomainController". See MS + Q291010. + netscape_certificate (bool): + Identify whether the certificate subject is + an SSL client, an SSL server, or a CA. + pe_logotype (bool): + Whether the certificate includes a logotype. + old_authority_key_id (bool): + Whether the certificate has an old authority + key identifier extension. + """ + + ca: bool = proto.Field( + proto.BOOL, + number=1, + ) + subject_key_id: str = proto.Field( + proto.STRING, + number=2, + ) + authority_key_id: "SSLCertificate.AuthorityKeyId" = proto.Field( + proto.MESSAGE, + number=3, + message="SSLCertificate.AuthorityKeyId", + ) + key_usage: str = proto.Field( + proto.STRING, + number=6, + ) + ca_info_access: str = proto.Field( + proto.STRING, + number=7, + ) + crl_distribution_points: str = proto.Field( + proto.STRING, + number=8, + ) + extended_key_usage: str = proto.Field( + proto.STRING, + number=9, + ) + subject_alternative_name: str = proto.Field( + proto.STRING, + number=10, + ) + certificate_policies: str = proto.Field( + proto.STRING, + number=11, + ) + netscape_cert_comment: str = proto.Field( + proto.STRING, + number=12, + ) + cert_template_name_dc: str = proto.Field( + proto.STRING, + number=13, + ) + netscape_certificate: bool = proto.Field( + proto.BOOL, + number=14, + ) + pe_logotype: bool = proto.Field( + proto.BOOL, + number=15, + ) + old_authority_key_id: bool = proto.Field( + proto.BOOL, + number=16, + ) + + class Subject(proto.Message): + r"""Subject data. + + Attributes: + country_name (str): + C: Country name. + common_name (str): + CN: CommonName. + locality (str): + L: Locality. + organization (str): + O: Organization. + organizational_unit (str): + OU: OrganizationalUnit. + state_or_province_name (str): + ST: StateOrProvinceName. + """ + + country_name: str = proto.Field( + proto.STRING, + number=1, + ) + common_name: str = proto.Field( + proto.STRING, + number=2, + ) + locality: str = proto.Field( + proto.STRING, + number=3, + ) + organization: str = proto.Field( + proto.STRING, + number=4, + ) + organizational_unit: str = proto.Field( + proto.STRING, + number=5, + ) + state_or_province_name: str = proto.Field( + proto.STRING, + number=6, + ) + + class RSA(proto.Message): + r"""RSA public key information. + + Attributes: + key_size (int): + Key size. + modulus (str): + Key modulus hexdump. + exponent (str): + Key exponent hexdump. + """ + + key_size: int = proto.Field( + proto.INT64, + number=1, + ) + modulus: str = proto.Field( + proto.STRING, + number=2, + ) + exponent: str = proto.Field( + proto.STRING, + number=3, + ) + + class EC(proto.Message): + r"""EC public key information. + + Attributes: + oid (str): + Curve name. + pub (str): + Public key hexdump. + """ + + oid: str = proto.Field( + proto.STRING, + number=1, + ) + pub: str = proto.Field( + proto.STRING, + number=2, + ) + + class PublicKey(proto.Message): + r"""Subject public key info. + + Attributes: + algorithm (str): + Any of "RSA", "DSA" or "EC". Indicates the + algorithm used to generate the certificate. + rsa (google.backstory.types.SSLCertificate.RSA): + RSA public key information. + """ + + algorithm: str = proto.Field( + proto.STRING, + number=1, + ) + rsa: "SSLCertificate.RSA" = proto.Field( + proto.MESSAGE, + number=2, + message="SSLCertificate.RSA", + ) + + class Validity(proto.Message): + r"""Defines certificate's validity period. + + Attributes: + expiry_time (google.protobuf.timestamp_pb2.Timestamp): + Expiry date. + issue_time (google.protobuf.timestamp_pb2.Timestamp): + Issue date. + """ + + expiry_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + issue_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + + cert_signature: CertSignature = proto.Field( + proto.MESSAGE, + number=1, + message=CertSignature, + ) + extension: Extension = proto.Field( + proto.MESSAGE, + number=2, + message=Extension, + ) + cert_extensions: struct_pb2.Struct = proto.Field( + proto.MESSAGE, + number=14, + message=struct_pb2.Struct, + ) + first_seen_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + issuer: Subject = proto.Field( + proto.MESSAGE, + number=4, + message=Subject, + ) + ec: EC = proto.Field( + proto.MESSAGE, + number=5, + message=EC, + ) + serial_number: str = proto.Field( + proto.STRING, + number=6, + ) + signature_algorithm: str = proto.Field( + proto.STRING, + number=7, + ) + size: int = proto.Field( + proto.INT64, + number=8, + ) + subject: Subject = proto.Field( + proto.MESSAGE, + number=9, + message=Subject, + ) + thumbprint: str = proto.Field( + proto.STRING, + number=10, + ) + thumbprint_sha256: str = proto.Field( + proto.STRING, + number=11, + ) + validity: Validity = proto.Field( + proto.MESSAGE, + number=12, + message=Validity, + ) + version: str = proto.Field( + proto.STRING, + number=13, + ) + public_key: PublicKey = proto.Field( + proto.MESSAGE, + number=15, + message=PublicKey, + ) + + +class PopularityRank(proto.Message): + r"""Domain's position in popularity ranks for sources such as + Alexa, Quantcast, or Statvoo. + + Attributes: + giver (str): + Name of the rank serial number hexdump. + rank (int): + Rank position. + ingestion_time (google.protobuf.timestamp_pb2.Timestamp): + Timestamp when the rank was ingested. + """ + + giver: str = proto.Field( + proto.STRING, + number=1, + ) + rank: int = proto.Field( + proto.INT64, + number=2, + ) + ingestion_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + + +class Tracker(proto.Message): + r"""URL Tracker. + + Attributes: + tracker (str): + Tracker name. + id (str): + Tracker ID, if available. + timestamp (google.protobuf.timestamp_pb2.Timestamp): + Tracker ingestion date. + url (str): + Tracker script URL. + """ + + tracker: str = proto.Field( + proto.STRING, + number=1, + ) + id: str = proto.Field( + proto.STRING, + number=2, + ) + timestamp: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + url: str = proto.Field( + proto.STRING, + number=4, + ) + + +class Url(proto.Message): + r"""Url. + + Attributes: + url (str): + URL. + categories (MutableSequence[str]): + Categorisation done by VirusTotal partners. + favicon (google.backstory.types.Favicon): + Difference hash and MD5 hash of the URL's. + html_meta (google.protobuf.struct_pb2.Struct): + Meta tags (only for URLs downloading HTML). + last_final_url (str): + If the original URL redirects, where does it + end. + last_http_response_code (int): + HTTP response code of the last response. + last_http_response_content_length (int): + Length in bytes of the content received. + last_http_response_content_sha256 (str): + URL response body's SHA256 hash. + last_http_response_cookies (google.protobuf.struct_pb2.Struct): + Website's cookies. + last_http_response_headers (google.protobuf.struct_pb2.Struct): + Headers and values of the last HTTP response. + tags (MutableSequence[str]): + Tags. + title (str): + Webpage title. + trackers (MutableSequence[google.backstory.types.Tracker]): + Trackers found in the URL in a historical + manner. + """ + + url: str = proto.Field( + proto.STRING, + number=1, + ) + categories: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + favicon: "Favicon" = proto.Field( + proto.MESSAGE, + number=3, + message="Favicon", + ) + html_meta: struct_pb2.Struct = proto.Field( + proto.MESSAGE, + number=4, + message=struct_pb2.Struct, + ) + last_final_url: str = proto.Field( + proto.STRING, + number=5, + ) + last_http_response_code: int = proto.Field( + proto.INT32, + number=6, + ) + last_http_response_content_length: int = proto.Field( + proto.INT64, + number=7, + ) + last_http_response_content_sha256: str = proto.Field( + proto.STRING, + number=8, + ) + last_http_response_cookies: struct_pb2.Struct = proto.Field( + proto.MESSAGE, + number=9, + message=struct_pb2.Struct, + ) + last_http_response_headers: struct_pb2.Struct = proto.Field( + proto.MESSAGE, + number=10, + message=struct_pb2.Struct, + ) + tags: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=11, + ) + title: str = proto.Field( + proto.STRING, + number=12, + ) + trackers: MutableSequence["Tracker"] = proto.RepeatedField( + proto.MESSAGE, + number=13, + message="Tracker", + ) + + +class Domain(proto.Message): + r"""Information about a domain. + + Attributes: + name (str): + The domain name. + This field can be used as an entity indicator + for Domain entities. + prevalence (google.backstory.types.Prevalence): + The prevalence of the domain within the + customer's environment. + first_seen_time (google.protobuf.timestamp_pb2.Timestamp): + First seen timestamp of the domain in the + customer's environment. + last_seen_time (google.protobuf.timestamp_pb2.Timestamp): + Last seen timestamp of the domain in the + customer's environment. + registrar (str): + Registrar name . FOr example, "Wild West + Domains, Inc. (R120-LROR)", "GoDaddy.com, LLC", + or "PDR LTD. D/B/A PUBLICDOMAINREGISTRY.COM". + contact_email (str): + Contact email address. + whois_server (str): + Whois server name. + name_server (MutableSequence[str]): + Repeated list of name servers. + creation_time (google.protobuf.timestamp_pb2.Timestamp): + Domain creation time. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Last updated time. + expiration_time (google.protobuf.timestamp_pb2.Timestamp): + Expiration time. + audit_update_time (google.protobuf.timestamp_pb2.Timestamp): + Audit updated time. + status (str): + Domain status. See + https://www.icann.org/resources/pages/epp-status-codes-2014-06-16-en + for meanings of possible values + registrant (google.backstory.types.User): + Parsed contact information for the registrant + of the domain. + admin (google.backstory.types.User): + Parsed contact information for the + administrative contact for the domain. + tech (google.backstory.types.User): + Parsed contact information for the technical + contact for the domain + billing (google.backstory.types.User): + Parsed contact information for the billing + contact of the domain. + zone (google.backstory.types.User): + Parsed contact information for the zone. + whois_record_raw_text (bytes): + WHOIS raw text. + registry_data_raw_text (bytes): + Registry Data raw text. + iana_registrar_id (int): + IANA Registrar ID. See + https://www.iana.org/assignments/registrar-ids/registrar-ids.xhtml + private_registration (bool): + Indicates whether the domain appears to be + using a private registration service to mask the + owner's contact information. + categories (MutableSequence[str]): + Categories assign to the domain as retrieved + from VirusTotal. + favicon (google.backstory.types.Favicon): + Includes difference hash and MD5 hash of the + domain's favicon. + jarm (str): + Domain's JARM hash. + last_dns_records (MutableSequence[google.backstory.types.DNSRecord]): + Domain's DNS records from the last scan. + last_dns_records_time (google.protobuf.timestamp_pb2.Timestamp): + Date when the DNS records list was retrieved + by VirusTotal. + last_https_certificate (google.backstory.types.SSLCertificate): + SSL certificate object retrieved last time + the domain was analyzed. + last_https_certificate_time (google.protobuf.timestamp_pb2.Timestamp): + When the certificate was retrieved by + VirusTotal. + popularity_ranks (MutableSequence[google.backstory.types.PopularityRank]): + Domain's position in popularity ranks such as + Alexa, Quantcast, Statvoo, etc + tags (MutableSequence[str]): + List of representative attributes. + whois_time (google.protobuf.timestamp_pb2.Timestamp): + Date of the last update of the WHOIS record. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + prevalence: "Prevalence" = proto.Field( + proto.MESSAGE, + number=2, + message="Prevalence", + ) + first_seen_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + last_seen_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=4, + message=timestamp_pb2.Timestamp, + ) + registrar: str = proto.Field( + proto.STRING, + number=5, + ) + contact_email: str = proto.Field( + proto.STRING, + number=6, + ) + whois_server: str = proto.Field( + proto.STRING, + number=7, + ) + name_server: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=8, + ) + creation_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=9, + message=timestamp_pb2.Timestamp, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=10, + message=timestamp_pb2.Timestamp, + ) + expiration_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=11, + message=timestamp_pb2.Timestamp, + ) + audit_update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=12, + message=timestamp_pb2.Timestamp, + ) + status: str = proto.Field( + proto.STRING, + number=13, + ) + registrant: "User" = proto.Field( + proto.MESSAGE, + number=14, + message="User", + ) + admin: "User" = proto.Field( + proto.MESSAGE, + number=15, + message="User", + ) + tech: "User" = proto.Field( + proto.MESSAGE, + number=16, + message="User", + ) + billing: "User" = proto.Field( + proto.MESSAGE, + number=17, + message="User", + ) + zone: "User" = proto.Field( + proto.MESSAGE, + number=18, + message="User", + ) + whois_record_raw_text: bytes = proto.Field( + proto.BYTES, + number=19, + ) + registry_data_raw_text: bytes = proto.Field( + proto.BYTES, + number=20, + ) + iana_registrar_id: int = proto.Field( + proto.INT32, + number=21, + ) + private_registration: bool = proto.Field( + proto.BOOL, + number=22, + ) + categories: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=23, + ) + favicon: "Favicon" = proto.Field( + proto.MESSAGE, + number=24, + message="Favicon", + ) + jarm: str = proto.Field( + proto.STRING, + number=25, + ) + last_dns_records: MutableSequence["DNSRecord"] = proto.RepeatedField( + proto.MESSAGE, + number=26, + message="DNSRecord", + ) + last_dns_records_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=27, + message=timestamp_pb2.Timestamp, + ) + last_https_certificate: "SSLCertificate" = proto.Field( + proto.MESSAGE, + number=28, + message="SSLCertificate", + ) + last_https_certificate_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=29, + message=timestamp_pb2.Timestamp, + ) + popularity_ranks: MutableSequence["PopularityRank"] = proto.RepeatedField( + proto.MESSAGE, + number=30, + message="PopularityRank", + ) + tags: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=31, + ) + whois_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=32, + message=timestamp_pb2.Timestamp, + ) + + +class Noun(proto.Message): + r"""The Noun type is used to represent the different entities in + an event: principal, src, target, observer, intermediary, and + about. It stores attributes known about the entity. For example, + if the entity is a device with multiple IP or MAC addresses, it + stores the IP and MAC addresses that are relevant to the event. + + Attributes: + hostname (str): + Client hostname or domain name field. + Hostname also doubles as the domain for remote + entities. This field can be used as an entity + indicator for asset entities. + domain (google.backstory.types.Domain): + Information about the domain. + artifact (google.backstory.types.Artifact): + Information about an artifact. + url_metadata (google.backstory.types.Url): + Information about the URL. + browser (google.backstory.types.Browser): + Information about an entry in the web + browser's local history database. + asset_id (str): + The asset ID. + This field can be used as an entity indicator + for asset entities. + user (google.backstory.types.User): + Information about the user. + user_management_chain (MutableSequence[google.backstory.types.User]): + Information about the user's management chain (reporting + hierarchy). Note: user_management_chain is only populated + when data is exported to BigQuery since recursive fields + (e.g. user.managers) are not supported by BigQuery. + group (google.backstory.types.Group): + Information about the group. + process (google.backstory.types.Process): + Information about the process. + process_ancestors (MutableSequence[google.backstory.types.Process]): + Information about the process's ancestors ordered from + immediate ancestor (parent process) to root. Note: + process_ancestors is only populated when data is exported to + BigQuery since recursive fields (e.g. + process.parent_process) are not supported by BigQuery. + asset (google.backstory.types.Asset): + Information about the asset. + ip (MutableSequence[str]): + A list of IP addresses associated with a + network connection. This field can be used as an + entity indicator for asset entities. + nat_ip (MutableSequence[str]): + A list of NAT translated IP addresses + associated with a network connection. + port (int): + Source or destination network port number + when a specific network connection is described + within an event. + nat_port (int): + NAT external network port number when a + specific network connection is described within + an event. + mac (MutableSequence[str]): + List of MAC addresses associated with a + device. This field can be used as an entity + indicator for asset entities. + administrative_domain (str): + Domain which the device belongs to (for + example, the Microsoft Windows domain). + namespace (str): + Namespace which the device belongs to, such + as "AD forest". Uses for this field include + Microsoft Windows AD forest, the name of + subsidiary, or the name of acquisition. + This field can be used along with an asset + indicator to identify an asset. + url (str): + The URL. + file (google.backstory.types.File): + Information about the file. + email (str): + Email address. Only filled in for security_result.about + registry (google.backstory.types.Registry): + Registry information. + application (str): + The name of an application or service. + Some SSO solutions only capture the name of a + target application such as "Atlassian" or + "Chronicle". + platform (google.backstory.types.Noun.Platform): + Platform. + platform_version (str): + Platform version. For example, + "Microsoft Windows 1803". + platform_patch_level (str): + Platform patch level. + For example, "Build 17134.48". + cloud (google.backstory.types.Cloud): + Cloud metadata. + Deprecated: cloud should be populated in entity + Attribute as generic metadata (e.g. + asset.attribute.cloud). + location (google.backstory.types.Location): + Physical location. For cloud environments, + set the region in location.name. + ip_location (MutableSequence[google.backstory.types.Location]): + Deprecated: use ip_geo_artifact.location instead. + ip_geo_artifact (MutableSequence[google.backstory.types.Artifact]): + Enriched geographic information corresponding + to an IP address. Specifically, location and + network data. + resource (google.backstory.types.Resource): + Information about the resource (e.g. + scheduled task, calendar entry). This field + should not be used for files, registry, or + processes because these objects are already part + of Noun. + resource_ancestors (MutableSequence[google.backstory.types.Resource]): + Information about the resource's ancestors + ordered from immediate ancestor (starting with + parent resource). + labels (MutableSequence[google.backstory.types.Label]): + Labels are key-value pairs. + For example: key = "env", value = "prod". + Deprecated: labels should be populated in entity + Attribute as generic metadata (e.g. + user.attribute.labels). + object_reference (google.backstory.types.Id): + Finding to which the Analyst updated the + feedback. + investigation (google.backstory.types.Investigation): + Analyst feedback/investigation for alerts. + network (google.backstory.types.Network): + Network details, including sub-messages with + details on each protocol (for example, DHCP, + DNS, or HTTP). + security_result (MutableSequence[google.backstory.types.SecurityResult]): + A list of security results. + """ + + class Platform(proto.Enum): + r"""Operating system platform. + + Values: + UNKNOWN_PLATFORM (0): + Default value. + WINDOWS (1): + Microsoft Windows. + MAC (2): + macOS. + LINUX (3): + Linux. + GCP (4): + Deprecated: see cloud.environment. + AWS (5): + Deprecated: see cloud.environment. + AZURE (6): + Deprecated: see cloud.environment. + IOS (7): + IOS + ANDROID (8): + Android + CHROME_OS (9): + Chrome OS + """ + + UNKNOWN_PLATFORM = 0 + WINDOWS = 1 + MAC = 2 + LINUX = 3 + GCP = 4 + AWS = 5 + AZURE = 6 + IOS = 7 + ANDROID = 8 + CHROME_OS = 9 + + hostname: str = proto.Field( + proto.STRING, + number=1, + ) + domain: "Domain" = proto.Field( + proto.MESSAGE, + number=30, + message="Domain", + ) + artifact: "Artifact" = proto.Field( + proto.MESSAGE, + number=32, + message="Artifact", + ) + url_metadata: "Url" = proto.Field( + proto.MESSAGE, + number=37, + message="Url", + ) + browser: "Browser" = proto.Field( + proto.MESSAGE, + number=38, + message="Browser", + ) + asset_id: str = proto.Field( + proto.STRING, + number=2, + ) + user: "User" = proto.Field( + proto.MESSAGE, + number=3, + message="User", + ) + user_management_chain: MutableSequence["User"] = proto.RepeatedField( + proto.MESSAGE, + number=29, + message="User", + ) + group: "Group" = proto.Field( + proto.MESSAGE, + number=20, + message="Group", + ) + process: "Process" = proto.Field( + proto.MESSAGE, + number=4, + message="Process", + ) + process_ancestors: MutableSequence["Process"] = proto.RepeatedField( + proto.MESSAGE, + number=28, + message="Process", + ) + asset: "Asset" = proto.Field( + proto.MESSAGE, + number=27, + message="Asset", + ) + ip: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=6, + ) + nat_ip: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=21, + ) + port: int = proto.Field( + proto.INT32, + number=7, + ) + nat_port: int = proto.Field( + proto.INT32, + number=22, + ) + mac: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=8, + ) + administrative_domain: str = proto.Field( + proto.STRING, + number=9, + ) + namespace: str = proto.Field( + proto.STRING, + number=19, + ) + url: str = proto.Field( + proto.STRING, + number=10, + ) + file: "File" = proto.Field( + proto.MESSAGE, + number=11, + message="File", + ) + email: str = proto.Field( + proto.STRING, + number=12, + ) + registry: "Registry" = proto.Field( + proto.MESSAGE, + number=13, + message="Registry", + ) + application: str = proto.Field( + proto.STRING, + number=14, + ) + platform: Platform = proto.Field( + proto.ENUM, + number=5, + enum=Platform, + ) + platform_version: str = proto.Field( + proto.STRING, + number=15, + ) + platform_patch_level: str = proto.Field( + proto.STRING, + number=16, + ) + cloud: "Cloud" = proto.Field( + proto.MESSAGE, + number=24, + message="Cloud", + ) + location: "Location" = proto.Field( + proto.MESSAGE, + number=17, + message="Location", + ) + ip_location: MutableSequence["Location"] = proto.RepeatedField( + proto.MESSAGE, + number=34, + message="Location", + ) + ip_geo_artifact: MutableSequence["Artifact"] = proto.RepeatedField( + proto.MESSAGE, + number=35, + message="Artifact", + ) + resource: "Resource" = proto.Field( + proto.MESSAGE, + number=18, + message="Resource", + ) + resource_ancestors: MutableSequence["Resource"] = proto.RepeatedField( + proto.MESSAGE, + number=31, + message="Resource", + ) + labels: MutableSequence["Label"] = proto.RepeatedField( + proto.MESSAGE, + number=23, + message="Label", + ) + object_reference: gb_id.Id = proto.Field( + proto.MESSAGE, + number=25, + message=gb_id.Id, + ) + investigation: "Investigation" = proto.Field( + proto.MESSAGE, + number=26, + message="Investigation", + ) + network: "Network" = proto.Field( + proto.MESSAGE, + number=33, + message="Network", + ) + security_result: MutableSequence["SecurityResult"] = proto.RepeatedField( + proto.MESSAGE, + number=36, + message="SecurityResult", + ) + + +class Investigation(proto.Message): + r"""Represents the aggregated state of an investigation such as + categorization, severity, and status. Can be expanded to include + analyst assignment details and more. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + verdict (google.backstory.types.Verdict): + Describes reason a finding investigation was + resolved. + + This field is a member of `oneof`_ ``_verdict``. + reputation (google.backstory.types.Reputation): + Describes whether a finding was useful or + not-useful. + + This field is a member of `oneof`_ ``_reputation``. + severity_score (int): + Severity score for a finding set by an + analyst. + + This field is a member of `oneof`_ ``_severity_score``. + status (google.backstory.types.Status): + Describes the workflow status of a finding. + + This field is a member of `oneof`_ ``_status``. + comments (MutableSequence[str]): + Comment added by the Analyst. + priority (google.backstory.types.Priority): + Priority of the Alert or Finding set by + analyst. + + This field is a member of `oneof`_ ``_priority``. + root_cause (str): + Root cause of the Alert or Finding set by + analyst. + + This field is a member of `oneof`_ ``_root_cause``. + reason (google.backstory.types.Reason): + Reason for closing the Case or Alert. + + This field is a member of `oneof`_ ``_reason``. + risk_score (int): + Risk score for a finding set by an analyst. + + This field is a member of `oneof`_ ``_risk_score``. + id (str): + Identifier for the investigation + + This field is a member of `oneof`_ ``_id``. + """ + + verdict: "Verdict" = proto.Field( + proto.ENUM, + number=2, + optional=True, + enum="Verdict", + ) + reputation: "Reputation" = proto.Field( + proto.ENUM, + number=3, + optional=True, + enum="Reputation", + ) + severity_score: int = proto.Field( + proto.UINT32, + number=4, + optional=True, + ) + status: "Status" = proto.Field( + proto.ENUM, + number=5, + optional=True, + enum="Status", + ) + comments: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=6, + ) + priority: "Priority" = proto.Field( + proto.ENUM, + number=7, + optional=True, + enum="Priority", + ) + root_cause: str = proto.Field( + proto.STRING, + number=8, + optional=True, + ) + reason: "Reason" = proto.Field( + proto.ENUM, + number=9, + optional=True, + enum="Reason", + ) + risk_score: int = proto.Field( + proto.UINT32, + number=10, + optional=True, + ) + id: str = proto.Field( + proto.STRING, + number=11, + optional=True, + ) + + +class Tags(proto.Message): + r"""Tags are event metadata which is set by examining event contents + post-parsing. For example, a UDM event may be assigned a tenant_id + based on certain customer-defined parameters. + + Attributes: + tenant_id (MutableSequence[bytes]): + A list of subtenant ids that this event + belongs to. + data_tap_config_name (MutableSequence[str]): + A list of sink name values defined in DataTap + configurations. + """ + + tenant_id: MutableSequence[bytes] = proto.RepeatedField( + proto.BYTES, + number=1, + ) + data_tap_config_name: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + +class AttackDetails(proto.Message): + r"""MITRE ATT&CK details. + + Attributes: + version (str): + ATT&CK version (e.g. 12.1). + tactics (MutableSequence[google.backstory.types.AttackDetails.Tactic]): + Tactics employed. + techniques (MutableSequence[google.backstory.types.AttackDetails.Technique]): + Techniques employed. + """ + + class Tactic(proto.Message): + r"""Tactic information related to an attack or threat. + + Attributes: + id (str): + Tactic ID (e.g. "TA0043"). + name (str): + Tactic Name (e.g. "Reconnaissance") + """ + + id: str = proto.Field( + proto.STRING, + number=1, + ) + name: str = proto.Field( + proto.STRING, + number=2, + ) + + class Technique(proto.Message): + r"""Technique information related to an attack or threat. + + Attributes: + id (str): + Technique ID (e.g. "T1595"). + name (str): + Technique Name (e.g. "Active Scanning"). + subtechnique_id (str): + Subtechnique ID (e.g. "T1595.001"). + subtechnique_name (str): + Subtechnique Name (e.g. "Scanning IP + Blocks"). + """ + + id: str = proto.Field( + proto.STRING, + number=1, + ) + name: str = proto.Field( + proto.STRING, + number=2, + ) + subtechnique_id: str = proto.Field( + proto.STRING, + number=3, + ) + subtechnique_name: str = proto.Field( + proto.STRING, + number=4, + ) + + version: str = proto.Field( + proto.STRING, + number=1, + ) + tactics: MutableSequence[Tactic] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=Tactic, + ) + techniques: MutableSequence[Technique] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=Technique, + ) + + +class BoolSequence(proto.Message): + r"""BoolSequence represents a sequence of bools. + + Attributes: + bool_vals (MutableSequence[bool]): + bool sequence. + """ + + bool_vals: MutableSequence[bool] = proto.RepeatedField( + proto.BOOL, + number=1, + ) + + +class BytesSequence(proto.Message): + r"""BytesSequence represents a sequence of bytes. + + Attributes: + bytes_vals (MutableSequence[bytes]): + bytes sequence. + """ + + bytes_vals: MutableSequence[bytes] = proto.RepeatedField( + proto.BYTES, + number=1, + ) + + +class DoubleSequence(proto.Message): + r"""DoubleSequence represents a sequence of doubles. + + Attributes: + double_vals (MutableSequence[float]): + double sequence. + """ + + double_vals: MutableSequence[float] = proto.RepeatedField( + proto.DOUBLE, + number=1, + ) + + +class Int64Sequence(proto.Message): + r"""Int64Sequence represents a sequence of int64s. + + Attributes: + int64_vals (MutableSequence[int]): + int64 sequence. + """ + + int64_vals: MutableSequence[int] = proto.RepeatedField( + proto.INT64, + number=1, + ) + + +class Uint64Sequence(proto.Message): + r"""Uint64Sequence represents a sequence of uint64s. + + Attributes: + uint64_vals (MutableSequence[int]): + uint64 sequence. + """ + + uint64_vals: MutableSequence[int] = proto.RepeatedField( + proto.UINT64, + number=1, + ) + + +class StringSequence(proto.Message): + r"""StringSequence represents a sequence of string. + + Attributes: + string_vals (MutableSequence[str]): + string sequence. + """ + + string_vals: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + + +class GroupedFields(proto.Message): + r"""Grouped fields are aliases for groups of related UDM fields. + All fields grouped together are of type string. + + Attributes: + ip (MutableSequence[str]): + IP addresses. + domain (MutableSequence[str]): + Domains. + hostname (MutableSequence[str]): + Hostnames. + user (MutableSequence[str]): + Users. + email (MutableSequence[str]): + Emails. + file_path (MutableSequence[str]): + File paths. + hash_ (MutableSequence[str]): + File Hashes. + process_id (MutableSequence[str]): + Process Identifiers. + """ + + ip: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + domain: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + hostname: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + user: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=4, + ) + email: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=5, + ) + file_path: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=6, + ) + hash_: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=7, + ) + process_id: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=8, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-backstory/mypy.ini b/packages/google-backstory/mypy.ini new file mode 100644 index 000000000000..e0e0da2e9e40 --- /dev/null +++ b/packages/google-backstory/mypy.ini @@ -0,0 +1,15 @@ +[mypy] +python_version = 3.14 +namespace_packages = True +ignore_missing_imports = False + +# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): +# Dependencies that historically lacks py.typed markers +[mypy-google.iam.*] +ignore_missing_imports = True + +# Helps mypy navigate the 'google' namespace more reliably in 3.10+ +explicit_package_bases = True + +# Performance: reuse results from previous runs to speed up 'nox' +incremental = True diff --git a/packages/google-backstory/noxfile.py b/packages/google-backstory/noxfile.py new file mode 100644 index 000000000000..44eaafe8e0f6 --- /dev/null +++ b/packages/google-backstory/noxfile.py @@ -0,0 +1,639 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 re +import shutil +import warnings +from typing import Dict, List + +import nox + +RUFF_VERSION = "ruff==0.14.14" + +LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] + +# Add samples to the list of directories to format if the directory exists. +if os.path.isdir("samples"): + LINT_PATHS.append("samples") + +ALL_PYTHON = [ + "3.10", + "3.11", + "3.12", + "3.13", + "3.14", +] + +DEFAULT_PYTHON_VERSION = "3.14" + +# TODO(https://github.com/googleapis/gapic-generator-python/issues/2450): +# Switch this to Python 3.15 alpha1 +# https://peps.python.org/pep-0790/ +PREVIEW_PYTHON_VERSION = "3.14" + +CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() + +if (CURRENT_DIRECTORY / "testing").exists(): + LOWER_BOUND_CONSTRAINTS_FILE = ( + CURRENT_DIRECTORY / "testing" / f"constraints-{ALL_PYTHON[0]}.txt" + ) +else: + LOWER_BOUND_CONSTRAINTS_FILE = CURRENT_DIRECTORY / "constraints.txt" +PACKAGE_NAME = "google-backstory" + +UNIT_TEST_STANDARD_DEPENDENCIES = [ + "mock", + "asyncmock", + "pytest", + "pytest-cov", + "pytest-asyncio", +] +UNIT_TEST_EXTERNAL_DEPENDENCIES: List[str] = [] +UNIT_TEST_LOCAL_DEPENDENCIES: List[str] = [] +UNIT_TEST_DEPENDENCIES: List[str] = [] +UNIT_TEST_EXTRAS: List[str] = [] +UNIT_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} + +SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ALL_PYTHON +SYSTEM_TEST_STANDARD_DEPENDENCIES = [ + "mock", + "pytest", + "google-cloud-testutils", +] +SYSTEM_TEST_EXTERNAL_DEPENDENCIES: List[str] = [] +SYSTEM_TEST_LOCAL_DEPENDENCIES: List[str] = [] +SYSTEM_TEST_DEPENDENCIES: List[str] = [] +SYSTEM_TEST_EXTRAS: List[str] = [] +SYSTEM_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} + +nox.options.sessions = [ + "unit", + "system", + "cover", + "lint", + "lint_setup_py", + "blacken", + "docs", +] + +# Error if a python version is missing +nox.options.error_on_missing_interpreters = True + + +@nox.session(python=ALL_PYTHON) +def mypy(session): + """Run the type checker.""" + # TODO(https://github.com/googleapis/gapic-generator-python/issues/2579): + # use the latest version of mypy + session.install( + "mypy<1.16.0", + "types-requests", + "types-protobuf", + ) + session.install(".") + session.run( + "mypy", + "-p", + "google", + "--check-untyped-defs", + *session.posargs, + ) + + +@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=DEFAULT_PYTHON_VERSION) +def lint(session): + """Run linters. + + Returns a failure if the linters find linting errors or sufficiently + serious code quality issues. + """ + session.install("flake8", RUFF_VERSION) + + # 2. Check formatting + session.run( + "ruff", + "format", + "--check", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", + *LINT_PATHS, + ) + + session.run("flake8", "google", "tests") + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def blacken(session): + """(Deprecated) Legacy session. Please use 'nox -s format'.""" + session.log( + "WARNING: The 'blacken' session is deprecated and will be removed in a future release. Please use 'nox -s format' in the future." + ) + + # Just run the ruff formatter (keeping legacy behavior of only formatting, not sorting imports) + session.install(RUFF_VERSION) + session.run( + "ruff", + "format", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", + *LINT_PATHS, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def format(session): + """ + Run ruff to sort imports and format code. + """ + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports + # check --select I: Enables strict import sorting + # --fix: Applies the changes automatically + session.run( + "ruff", + "check", + "--select", + "I", + "--fix", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", # Standard Black line length + *LINT_PATHS, + ) + + # 3. Run Ruff to format code + session.run( + "ruff", + "format", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", # Standard Black line length + *LINT_PATHS, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def lint_setup_py(session): + """Verify that setup.py is valid (including RST check).""" + session.install("setuptools", "docutils", "pygments") + session.run("python", "setup.py", "check", "--restructuredtext", "--strict") + + +def install_unittest_dependencies(session, *constraints): + standard_deps = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_DEPENDENCIES + session.install(*standard_deps, *constraints) + + if UNIT_TEST_EXTERNAL_DEPENDENCIES: + warnings.warn( + "'unit_test_external_dependencies' is deprecated. Instead, please " + "use 'unit_test_dependencies' or 'unit_test_local_dependencies'.", + DeprecationWarning, + ) + session.install(*UNIT_TEST_EXTERNAL_DEPENDENCIES, *constraints) + + if UNIT_TEST_LOCAL_DEPENDENCIES: + session.install(*UNIT_TEST_LOCAL_DEPENDENCIES, *constraints) + + if UNIT_TEST_EXTRAS_BY_PYTHON: + extras = UNIT_TEST_EXTRAS_BY_PYTHON.get(session.python, []) + elif UNIT_TEST_EXTRAS: + extras = UNIT_TEST_EXTRAS + else: + extras = [] + + if extras: + session.install("-e", f".[{','.join(extras)}]", *constraints) + else: + session.install("-e", ".", *constraints) + + +@nox.session(python=ALL_PYTHON) +@nox.parametrize( + "protobuf_implementation", + ["python", "upb"], +) +def unit(session, protobuf_implementation): + # Install all test dependencies, then install this package in-place. + + constraints_path = str( + CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" + ) + install_unittest_dependencies(session, "-c", constraints_path) + + # Run py.test against the unit tests. + session.run( + "py.test", + "--quiet", + f"--junitxml=unit_{session.python}_sponge_log.xml", + "--cov=google", + "--cov=tests/unit", + "--cov-append", + "--cov-config=.coveragerc", + "--cov-report=", + "--cov-fail-under=0", + os.path.join("tests", "unit"), + *session.posargs, + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) + + +def install_systemtest_dependencies(session, *constraints): + if session.python >= "3.12": + session.install("--pre", "grpcio>=1.75.1") + else: + session.install("--pre", "grpcio<=1.62.2") + + session.install(*SYSTEM_TEST_STANDARD_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_EXTERNAL_DEPENDENCIES: + session.install(*SYSTEM_TEST_EXTERNAL_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_LOCAL_DEPENDENCIES: + session.install("-e", *SYSTEM_TEST_LOCAL_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_DEPENDENCIES: + session.install("-e", *SYSTEM_TEST_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_EXTRAS_BY_PYTHON: + extras = SYSTEM_TEST_EXTRAS_BY_PYTHON.get(session.python, []) + elif SYSTEM_TEST_EXTRAS: + extras = SYSTEM_TEST_EXTRAS + else: + extras = [] + + if extras: + session.install("-e", f".[{','.join(extras)}]", *constraints) + else: + session.install("-e", ".", *constraints) + + +@nox.session(python=SYSTEM_TEST_PYTHON_VERSIONS) +def system(session): + """Run the system test suite.""" + constraints_path = str( + CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" + ) + system_test_path = os.path.join("tests", "system.py") + system_test_folder_path = os.path.join("tests", "system") + + # Check the value of `RUN_SYSTEM_TESTS` env var. It defaults to true. + if os.environ.get("RUN_SYSTEM_TESTS", "true") == "false": + session.skip("RUN_SYSTEM_TESTS is set to false, skipping") + # Install pyopenssl for mTLS testing. + if os.environ.get("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true": + session.install("pyopenssl") + + system_test_exists = os.path.exists(system_test_path) + system_test_folder_exists = os.path.exists(system_test_folder_path) + # Sanity check: only run tests if found. + if not system_test_exists and not system_test_folder_exists: + session.skip("System tests were not found") + + install_systemtest_dependencies(session, "-c", constraints_path) + + # Run py.test against the system tests. + if system_test_exists: + session.run( + "py.test", + "--quiet", + f"--junitxml=system_{session.python}_sponge_log.xml", + system_test_path, + *session.posargs, + ) + if system_test_folder_exists: + session.run( + "py.test", + "--quiet", + f"--junitxml=system_{session.python}_sponge_log.xml", + system_test_folder_path, + *session.posargs, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +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.10") +def docs(session): + """Build the docs for this library.""" + + session.install("-e", ".") + session.install( + # We need to pin to specific versions of the `sphinxcontrib-*` packages + # which still support sphinx 4.x. + # See https://github.com/googleapis/sphinx-docfx-yaml/issues/344 + # and https://github.com/googleapis/sphinx-docfx-yaml/issues/345. + "sphinxcontrib-applehelp==1.0.4", + "sphinxcontrib-devhelp==1.0.2", + "sphinxcontrib-htmlhelp==2.0.1", + "sphinxcontrib-qthelp==1.0.3", + "sphinxcontrib-serializinghtml==1.1.5", + "sphinx==4.5.0", + "alabaster", + "recommonmark", + ) + + shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) + session.run( + "sphinx-build", + "-T", # show full traceback on exception + "-N", # no colors + "-b", + "html", # builder + "-d", + os.path.join("docs", "_build", "doctrees", ""), # cache directory + # paths to build: + os.path.join("docs", ""), + os.path.join("docs", "_build", "html", ""), + ) + + +@nox.session(python="3.10") +def docfx(session): + """Build the docfx yaml files for this library.""" + + session.install("-e", ".") + session.install( + # We need to pin to specific versions of the `sphinxcontrib-*` packages + # which still support sphinx 4.x. + # See https://github.com/googleapis/sphinx-docfx-yaml/issues/344 + # and https://github.com/googleapis/sphinx-docfx-yaml/issues/345. + "sphinxcontrib-applehelp==1.0.4", + "sphinxcontrib-devhelp==1.0.2", + "sphinxcontrib-htmlhelp==2.0.1", + "sphinxcontrib-qthelp==1.0.3", + "sphinxcontrib-serializinghtml==1.1.5", + "gcp-sphinx-docfx-yaml", + "alabaster", + "recommonmark", + ) + + shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) + session.run( + "sphinx-build", + "-T", # show full traceback on exception + "-N", # no colors + "-D", + ( + "extensions=sphinx.ext.autodoc," + "sphinx.ext.autosummary," + "docfx_yaml.extension," + "sphinx.ext.intersphinx," + "sphinx.ext.coverage," + "sphinx.ext.napoleon," + "sphinx.ext.todo," + "sphinx.ext.viewcode," + "recommonmark" + ), + "-b", + "html", + "-d", + os.path.join("docs", "_build", "doctrees", ""), + os.path.join("docs", ""), + os.path.join("docs", "_build", "html", ""), + ) + + +@nox.session(python=PREVIEW_PYTHON_VERSION) +@nox.parametrize( + "protobuf_implementation", + ["python", "upb"], +) +def prerelease_deps(session, protobuf_implementation): + """ + Run all tests with pre-release versions of dependencies installed + rather than the standard non pre-release versions. + Pre-release versions can be installed using + `pip install --pre `. + """ + + # Install all dependencies + session.install("-e", ".") + + # Install dependencies for the unit test environment + unit_deps_all = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_EXTERNAL_DEPENDENCIES + session.install(*unit_deps_all) + + # Because we test minimum dependency versions on the minimum Python + # version, the first version we test with in the unit tests sessions has a + # constraints file containing all dependencies and extras. + with open( + CURRENT_DIRECTORY / "testing" / f"constraints-{ALL_PYTHON[0]}.txt", + encoding="utf-8", + ) as constraints_file: + constraints_text = constraints_file.read() + + # Ignore leading whitespace and comment lines. + constraints_deps = [ + match.group(1) + for match in re.finditer( + r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE + ) + ] + + # Install dependencies specified in `testing/constraints-X.txt`. + session.install(*constraints_deps) + + # Note: If a dependency is added to the `prerel_deps` list, + # the `core_dependencies_from_source` list in the `core_deps_from_source` + # nox session should also be updated. + prerel_deps = [ + "googleapis-common-protos", + "google-api-core", + "google-auth", + "grpc-google-iam-v1", + "grpcio>=1.75.1" if session.python >= "3.12" else "grpcio<=1.62.2", + "grpcio-status", + "protobuf", + "proto-plus", + ] + + deps_dir = CURRENT_DIRECTORY.parent + while deps_dir.name != "packages" and deps_dir.parent != deps_dir: + deps_dir = deps_dir.parent + + # Extract the base package name, safely ignoring version bounds and spaces + # (e.g., "grpcio>=1.75.1" becomes "grpcio") + parsed_deps = { + dep: re.match(r"^([a-zA-Z0-9_-]+)", dep).group(1) for dep in prerel_deps + } + + # Dynamically sort local packages vs PyPI dependencies + local_paths = [] + pypi_deps = [] + + for dep, pkg_name in parsed_deps.items(): + if (deps_dir / pkg_name).exists(): + local_paths.append(str(deps_dir / pkg_name)) + else: + pypi_deps.append(dep) + + # Batch pip installations to avoid sequential overhead + if local_paths: + session.install(*local_paths, "--no-deps", "--ignore-installed") + if pypi_deps: + session.install(*pypi_deps, "--pre", "--no-deps", "--ignore-installed") + + # TODO(https://github.com/grpc/grpc/issues/38965): Add `grpcio-status`` + # to the dictionary below once this bug is fixed. + # TODO(https://github.com/googleapis/google-cloud-python/issues/13643): Add + # `googleapis-common-protos` and `grpc-google-iam-v1` to the dictionary below + # once this bug is fixed. + package_namespaces = { + "google-api-core": "google.api_core", + "google-auth": "google.auth", + "grpcio": "grpc", + "protobuf": "google.protobuf", + "proto-plus": "proto", + } + + # Reuse the parsed names for logging and version verification + for dep, pkg_name in parsed_deps.items(): + print(f"Installed {dep}") + version_namespace = package_namespaces.get(pkg_name) + + if version_namespace: + session.run( + "python", + "-c", + f"import {version_namespace}; print({version_namespace}.__version__)", + ) + + session.run( + "py.test", + "tests/unit", + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +@nox.parametrize( + "protobuf_implementation", + ["python", "upb"], +) +def core_deps_from_source(session, protobuf_implementation): + """Run all tests with core dependencies installed from source + rather than pulling the dependencies from PyPI. + """ + + # Install all dependencies + session.install("-e", ".") + + # Install dependencies for the unit test environment + unit_deps_all = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_EXTERNAL_DEPENDENCIES + session.install(*unit_deps_all) + + # Because we test minimum dependency versions on the minimum Python + # version, the first version we test with in the unit tests sessions has a + # constraints file containing all dependencies and extras. + with open( + CURRENT_DIRECTORY / "testing" / f"constraints-{ALL_PYTHON[0]}.txt", + encoding="utf-8", + ) as constraints_file: + constraints_text = constraints_file.read() + + # Ignore leading whitespace and comment lines. + constraints_deps = [ + match.group(1) + for match in re.finditer( + r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE + ) + ] + + # Install dependencies specified in `testing/constraints-X.txt`. + session.install(*constraints_deps) + + # TODO(https://github.com/googleapis/gapic-generator-python/issues/2358): `grpcio` and + # `grpcio-status` should be added to the list below so that they are installed from source, + # rather than PyPI. + # TODO(https://github.com/googleapis/gapic-generator-python/issues/2357): `protobuf` should be + # added to the list below so that it is installed from source, rather than PyPI + # Note: If a dependency is added to the `core_dependencies_from_source` list, + # the `prerel_deps` list in the `prerelease_deps` nox session should also be updated. + core_dependencies_from_source = [ + "googleapis-common-protos", + "google-api-core", + "google-auth", + "grpc-google-iam-v1", + "proto-plus", + ] + + deps_dir = CURRENT_DIRECTORY.parent + while deps_dir.name != "packages" and deps_dir.parent != deps_dir: + deps_dir = deps_dir.parent + + # Batch the pip installation to avoid sequential overhead + dep_paths = [str(deps_dir / dep) for dep in core_dependencies_from_source] + + session.install(*dep_paths, "--no-deps", "--ignore-installed") + print( + f"Installed {', '.join(core_dependencies_from_source)} locally from {deps_dir}" + ) + + session.run( + "py.test", + "tests/unit", + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) diff --git a/packages/google-backstory/setup.py b/packages/google-backstory/setup.py new file mode 100644 index 000000000000..0bc1a58702fc --- /dev/null +++ b/packages/google-backstory/setup.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 re + +import setuptools # type: ignore + +package_root = os.path.abspath(os.path.dirname(__file__)) + +name = "google-backstory" + + +description = "Google Backstory API client library" + +version = None + +with open(os.path.join(package_root, "google/backstory/gapic_version.py")) as fp: + version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + assert len(version_candidates) == 1 + version = version_candidates[0] + +if version[0] == "0": + release_status = "Development Status :: 4 - Beta" +else: + release_status = "Development Status :: 5 - Production/Stable" + +dependencies = [ + "google-api-core[grpc] >= 2.17.1, <3.0.0", + # Exclude incompatible versions of `google-auth` + # See https://github.com/googleapis/google-cloud-python/issues/12364 + "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", + "grpcio >= 1.59.0, < 2.0.0", + "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", + "proto-plus >= 1.22.3, <2.0.0", + "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", + "protobuf >= 4.25.8, < 8.0.0", +] +extras = {} +url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-backstory" + +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() + +packages = [ + package + for package in setuptools.find_namespace_packages() + if package.startswith("google") +] + +setuptools.setup( + name=name, + version=version, + description=description, + long_description=readme, + author="Google LLC", + author_email="googleapis-packages@google.com", + license="Apache-2.0", + url=url, + classifiers=[ + release_status, + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", + "Operating System :: OS Independent", + "Topic :: Internet", + ], + platforms="Posix; MacOS X; Windows", + packages=packages, + python_requires=">=3.10", + install_requires=dependencies, + extras_require=extras, + include_package_data=True, + zip_safe=False, +) diff --git a/packages/google-backstory/testing/constraints-3.10.txt b/packages/google-backstory/testing/constraints-3.10.txt new file mode 100644 index 000000000000..7be9c36933fc --- /dev/null +++ b/packages/google-backstory/testing/constraints-3.10.txt @@ -0,0 +1,11 @@ +# This constraints file is used to check that lower bounds +# are correct in setup.py +# List all library dependencies and extras in this file, +# pinning their versions to their lower bounds. +# For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", +# then this file should have google-cloud-foo==1.14.0 +google-api-core==2.17.1 +google-auth==2.14.1 +grpcio==1.59.0 +proto-plus==1.22.3 +protobuf==4.25.8 diff --git a/packages/google-backstory/testing/constraints-3.11.txt b/packages/google-backstory/testing/constraints-3.11.txt new file mode 100644 index 000000000000..7599dea499ed --- /dev/null +++ b/packages/google-backstory/testing/constraints-3.11.txt @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +google-auth +grpcio +proto-plus +protobuf +# cryptography is a direct dependency of google-auth +cryptography diff --git a/packages/google-backstory/testing/constraints-3.12.txt b/packages/google-backstory/testing/constraints-3.12.txt new file mode 100644 index 000000000000..7599dea499ed --- /dev/null +++ b/packages/google-backstory/testing/constraints-3.12.txt @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +google-auth +grpcio +proto-plus +protobuf +# cryptography is a direct dependency of google-auth +cryptography diff --git a/packages/google-backstory/testing/constraints-3.13.txt b/packages/google-backstory/testing/constraints-3.13.txt new file mode 100644 index 000000000000..1e93c60e50aa --- /dev/null +++ b/packages/google-backstory/testing/constraints-3.13.txt @@ -0,0 +1,12 @@ +# We use the constraints file for the latest Python version +# (currently this file) to check that the latest +# major versions of dependencies are supported in setup.py. +# List all library dependencies and extras in this file. +# Require the latest major version be installed for each dependency. +# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", +# Then this file should have google-cloud-foo>=1 +google-api-core>=2 +google-auth>=2 +grpcio>=1 +proto-plus>=1 +protobuf>=6 diff --git a/packages/google-backstory/testing/constraints-3.14.txt b/packages/google-backstory/testing/constraints-3.14.txt new file mode 100644 index 000000000000..1e93c60e50aa --- /dev/null +++ b/packages/google-backstory/testing/constraints-3.14.txt @@ -0,0 +1,12 @@ +# We use the constraints file for the latest Python version +# (currently this file) to check that the latest +# major versions of dependencies are supported in setup.py. +# List all library dependencies and extras in this file. +# Require the latest major version be installed for each dependency. +# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", +# Then this file should have google-cloud-foo>=1 +google-api-core>=2 +google-auth>=2 +grpcio>=1 +proto-plus>=1 +protobuf>=6 diff --git a/packages/google-backstory/tests/__init__.py b/packages/google-backstory/tests/__init__.py new file mode 100644 index 000000000000..32b36c5c4fe0 --- /dev/null +++ b/packages/google-backstory/tests/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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/packages/google-backstory/tests/unit/__init__.py b/packages/google-backstory/tests/unit/__init__.py new file mode 100644 index 000000000000..32b36c5c4fe0 --- /dev/null +++ b/packages/google-backstory/tests/unit/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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/packages/google-backstory/tests/unit/gapic/__init__.py b/packages/google-backstory/tests/unit/gapic/__init__.py new file mode 100644 index 000000000000..32b36c5c4fe0 --- /dev/null +++ b/packages/google-backstory/tests/unit/gapic/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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/packages/google-backstory/tests/unit/gapic/backstory/__init__.py b/packages/google-backstory/tests/unit/gapic/backstory/__init__.py new file mode 100644 index 000000000000..32b36c5c4fe0 --- /dev/null +++ b/packages/google-backstory/tests/unit/gapic/backstory/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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/packages/google-backstory/tests/unit/test_backstory.py b/packages/google-backstory/tests/unit/test_backstory.py new file mode 100644 index 000000000000..49d0f73e1af4 --- /dev/null +++ b/packages/google-backstory/tests/unit/test_backstory.py @@ -0,0 +1,19 @@ +# Copyright 2026 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.backstory import types + + +def test_types(): + assert types.Collection is not None diff --git a/packages/google-backstory/tests/unit/test_packaging.py b/packages/google-backstory/tests/unit/test_packaging.py new file mode 100644 index 000000000000..79d24cdfb2df --- /dev/null +++ b/packages/google-backstory/tests/unit/test_packaging.py @@ -0,0 +1,28 @@ +# Copyright 2026 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 subprocess +import sys + + +def test_namespace_package_compat(tmp_path): + # The ``google`` namespace package should not be masked + # by the presence of ``google-backstory``. + google = tmp_path / "google" + google.mkdir() + google.joinpath("othermod.py").write_text("") + env = dict(os.environ, PYTHONPATH=str(tmp_path)) + cmd = [sys.executable, "-m", "google.othermod"] + subprocess.check_call(cmd, env=env) From 25b857e1bc196da5b56cf599ec346967c6559922 Mon Sep 17 00:00:00 2001 From: Noah Dietz Date: Thu, 4 Jun 2026 15:16:43 -0700 Subject: [PATCH 028/174] feat(gapic-generator): setup.py matches prerelease versions (#17370) --- packages/gapic-generator/gapic/templates/setup.py.j2 | 5 ++++- .../gapic-generator/tests/integration/goldens/asset/setup.py | 5 ++++- .../tests/integration/goldens/credentials/setup.py | 5 ++++- .../tests/integration/goldens/eventarc/setup.py | 5 ++++- .../tests/integration/goldens/logging/setup.py | 5 ++++- .../tests/integration/goldens/logging_internal/setup.py | 5 ++++- .../gapic-generator/tests/integration/goldens/redis/setup.py | 5 ++++- .../tests/integration/goldens/redis_selective/setup.py | 5 ++++- .../integration/goldens/storagebatchoperations/setup.py | 5 ++++- 9 files changed, 36 insertions(+), 9 deletions(-) diff --git a/packages/gapic-generator/gapic/templates/setup.py.j2 b/packages/gapic-generator/gapic/templates/setup.py.j2 index 9834a2884c95..fb902178055f 100644 --- a/packages/gapic-generator/gapic/templates/setup.py.j2 +++ b/packages/gapic-generator/gapic/templates/setup.py.j2 @@ -23,7 +23,10 @@ description = "{{ warehouse_description }} API client library" version = None with open(os.path.join(package_root, '{{ package_path }}/gapic_version.py')) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert (len(version_candidates) == 1) version = version_candidates[0] diff --git a/packages/gapic-generator/tests/integration/goldens/asset/setup.py b/packages/gapic-generator/tests/integration/goldens/asset/setup.py index 197a610bff72..d5e4623ee04b 100755 --- a/packages/gapic-generator/tests/integration/goldens/asset/setup.py +++ b/packages/gapic-generator/tests/integration/goldens/asset/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, 'google/cloud/asset/gapic_version.py')) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert (len(version_candidates) == 1) version = version_candidates[0] diff --git a/packages/gapic-generator/tests/integration/goldens/credentials/setup.py b/packages/gapic-generator/tests/integration/goldens/credentials/setup.py index 4d4533c20e18..57e35ca4e0c0 100755 --- a/packages/gapic-generator/tests/integration/goldens/credentials/setup.py +++ b/packages/gapic-generator/tests/integration/goldens/credentials/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, 'google/iam/credentials/gapic_version.py')) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert (len(version_candidates) == 1) version = version_candidates[0] diff --git a/packages/gapic-generator/tests/integration/goldens/eventarc/setup.py b/packages/gapic-generator/tests/integration/goldens/eventarc/setup.py index 0a0aae863942..a7179a051924 100755 --- a/packages/gapic-generator/tests/integration/goldens/eventarc/setup.py +++ b/packages/gapic-generator/tests/integration/goldens/eventarc/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, 'google/cloud/eventarc_v1/gapic_version.py')) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert (len(version_candidates) == 1) version = version_candidates[0] diff --git a/packages/gapic-generator/tests/integration/goldens/logging/setup.py b/packages/gapic-generator/tests/integration/goldens/logging/setup.py index 38c15878df5e..0c230d719cdd 100755 --- a/packages/gapic-generator/tests/integration/goldens/logging/setup.py +++ b/packages/gapic-generator/tests/integration/goldens/logging/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, 'google/cloud/logging/gapic_version.py')) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert (len(version_candidates) == 1) version = version_candidates[0] diff --git a/packages/gapic-generator/tests/integration/goldens/logging_internal/setup.py b/packages/gapic-generator/tests/integration/goldens/logging_internal/setup.py index 38c15878df5e..0c230d719cdd 100755 --- a/packages/gapic-generator/tests/integration/goldens/logging_internal/setup.py +++ b/packages/gapic-generator/tests/integration/goldens/logging_internal/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, 'google/cloud/logging/gapic_version.py')) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert (len(version_candidates) == 1) version = version_candidates[0] diff --git a/packages/gapic-generator/tests/integration/goldens/redis/setup.py b/packages/gapic-generator/tests/integration/goldens/redis/setup.py index 18e5226c7306..02095ef25809 100755 --- a/packages/gapic-generator/tests/integration/goldens/redis/setup.py +++ b/packages/gapic-generator/tests/integration/goldens/redis/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, 'google/cloud/redis/gapic_version.py')) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert (len(version_candidates) == 1) version = version_candidates[0] diff --git a/packages/gapic-generator/tests/integration/goldens/redis_selective/setup.py b/packages/gapic-generator/tests/integration/goldens/redis_selective/setup.py index 18e5226c7306..02095ef25809 100755 --- a/packages/gapic-generator/tests/integration/goldens/redis_selective/setup.py +++ b/packages/gapic-generator/tests/integration/goldens/redis_selective/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, 'google/cloud/redis/gapic_version.py')) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert (len(version_candidates) == 1) version = version_candidates[0] diff --git a/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/setup.py b/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/setup.py index 56c8e3127f42..1250019e9117 100755 --- a/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/setup.py +++ b/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, 'google/cloud/storagebatchoperations/gapic_version.py')) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert (len(version_candidates) == 1) version = version_candidates[0] From 761c8052198f8db98f7d747d6db9a1b9ec875668 Mon Sep 17 00:00:00 2001 From: Chalmer Lowe Date: Thu, 4 Jun 2026 18:34:56 -0400 Subject: [PATCH 029/174] test(spanner): add pytest-xdist parallel execution with state isolation (#17344) This PR adds `pytest-xdist` to parallelize unit tests and the `core_deps_from_source` nox sessions for the `google-cloud-spanner` package. **By running tests in parallel using `-n auto`, the execution time of the Spanner unit tests are reduced from ~8 minutes to 4 minutes.** State isolation and test reliability are achieved by: * **Simplifying Subtests**: We pass simple strings/names to `subTest()` instead of complex objects. This keeps subtests lightweight and prevents serialization errors. * **Cleaning Up Global Singletons**: We reset telemetry singleton states on test teardown (using pytest's idiomatic `monkeypatch` fixture). This ensures metric counters don't leak from one test into another. * **Fixing Concurrent Mock Conflicts**: We return fresh mocked iterators for concurrent calls (using `side_effect` instead of `return_value`). This prevents one thread from exhausting a mock's results before another thread can read them. * **Robust Assertion Checks**: We added a helper method (`_assert_concurrent_transaction_invariants`) that verifies the *behavior* of concurrent threads (ensuring exactly one thread starts the transaction while others wait/reuse it), rather than checking fragile call logs or counting sequential request IDs. This allowed us to safely run four concurrent tests. > [!note] > The long pole in the tent is still the `system` tests, which require about 30 minutes. It is not as simple as just adding xdist because there are other factors that limit velocity including the fact that system tests actually interact with live systems. --- packages/google-cloud-spanner/noxfile.py | 7 +- packages/google-cloud-spanner/setup.py | 12 +- .../tests/system/_async/test_database_api.py | 5 +- .../tests/system/conftest.py | 5 + .../tests/unit/_async/test_client.py | 4 +- .../tests/unit/_async/test_client_extra.py | 32 ++- .../tests/unit/_async/test_session.py | 23 +- .../tests/unit/conftest.py | 18 ++ .../spanner_dbapi/test_partition_helper.py | 2 +- .../tests/unit/test__helpers.py | 4 +- .../tests/unit/test_client.py | 4 +- .../tests/unit/test_metrics.py | 7 +- .../tests/unit/test_session.py | 23 +- .../tests/unit/test_spanner.py | 234 ++++-------------- 14 files changed, 163 insertions(+), 217 deletions(-) diff --git a/packages/google-cloud-spanner/noxfile.py b/packages/google-cloud-spanner/noxfile.py index 54ead8405fb9..fa74716b8142 100644 --- a/packages/google-cloud-spanner/noxfile.py +++ b/packages/google-cloud-spanner/noxfile.py @@ -43,6 +43,7 @@ "pytest", "pytest-cov", "pytest-asyncio", + "pytest-xdist", ] MOCK_SERVER_ADDITIONAL_DEPENDENCIES = [ "google-cloud-testutils", @@ -240,6 +241,8 @@ def unit(session, protobuf_implementation): # Run py.test against the unit tests. args = [ "py.test", + "-n", + "auto", "-s", f"--junitxml=unit_{session.python}_sponge_log.xml", "--cov=google", @@ -754,7 +757,6 @@ def prerelease_deps(session, protobuf_implementation, database_dialect): def mypy(session): """Run the type checker.""" session.skip("Mypy is not yet supported") - # TODO(https://github.com/googleapis/gapic-generator-python/issues/2579): # use the latest version of mypy session.install( @@ -832,12 +834,15 @@ def core_deps_from_source(session, protobuf_implementation): dep_paths = [str(deps_dir / dep) for dep in core_dependencies_from_source] session.install(*dep_paths, "--no-deps", "--ignore-installed") + session.install("pytest-xdist") print( f"Installed {', '.join(core_dependencies_from_source)} locally from {deps_dir}" ) session.run( "py.test", + "-n", + "auto", "tests/unit", env={ "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, diff --git a/packages/google-cloud-spanner/setup.py b/packages/google-cloud-spanner/setup.py index 34eace7a4506..e7dce1a06904 100644 --- a/packages/google-cloud-spanner/setup.py +++ b/packages/google-cloud-spanner/setup.py @@ -60,7 +60,17 @@ "google-cloud-monitoring >= 2.16.0", "mmh3 >= 4.1.0", ] -extras = {"libcst": "libcst >= 0.2.5"} +extras = { + "libcst": "libcst >= 0.2.5", + "test": [ + "pytest", + "mock", + "asyncmock", + "pytest-cov", + "pytest-asyncio", + "pytest-xdist", + ], +} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-spanner" diff --git a/packages/google-cloud-spanner/tests/system/_async/test_database_api.py b/packages/google-cloud-spanner/tests/system/_async/test_database_api.py index 5c7cd78efe65..fa0ffaeab623 100644 --- a/packages/google-cloud-spanner/tests/system/_async/test_database_api.py +++ b/packages/google-cloud-spanner/tests/system/_async/test_database_api.py @@ -179,7 +179,10 @@ async def _unit_of_work(transaction): transaction.insert_or_update(sd.TABLE, sd.COLUMNS, sd.ROW_DATA) await shared_database.run_in_transaction(_unit_of_work) - assert attempts == 2 + # Expect at least 2 attempts due to our simulated manual abort on first try. + # We use >= 2 rather than == 2 because the live Spanner server can also + # trigger transient abort retries depending on real-world GCP resource contention. + assert attempts >= 2 @pytest.mark.asyncio diff --git a/packages/google-cloud-spanner/tests/system/conftest.py b/packages/google-cloud-spanner/tests/system/conftest.py index 10839d50bee3..740cfc0e02b5 100644 --- a/packages/google-cloud-spanner/tests/system/conftest.py +++ b/packages/google-cloud-spanner/tests/system/conftest.py @@ -13,6 +13,7 @@ # limitations under the License. import datetime +import os import time import pytest @@ -25,6 +26,10 @@ from . import _helpers +# Disable builtin metrics for system tests by default to avoid 401 errors +# from the background thread exporting to Cloud Monitoring without permissions. +os.environ["SPANNER_DISABLE_BUILTIN_METRICS"] = "true" + @pytest.fixture(scope="function") def if_create_instance(): diff --git a/packages/google-cloud-spanner/tests/unit/_async/test_client.py b/packages/google-cloud-spanner/tests/unit/_async/test_client.py index d420f157196f..60bc98addc8e 100644 --- a/packages/google-cloud-spanner/tests/unit/_async/test_client.py +++ b/packages/google-cloud-spanner/tests/unit/_async/test_client.py @@ -799,7 +799,9 @@ async def test_constructor_logs_options_disabled_by_default(self): info_logger.assert_not_called() # Also test when the environment variable is not set at all - with mock.patch.dict(os.environ, {}, clear=True): + with mock.patch.dict( + os.environ, {"SPANNER_DISABLE_BUILTIN_METRICS": "true"}, clear=True + ): with mock.patch.object(logger, "info") as info_logger: client = self._make_one(project=self.PROJECT, credentials=creds) self.assertIsNotNone(client) diff --git a/packages/google-cloud-spanner/tests/unit/_async/test_client_extra.py b/packages/google-cloud-spanner/tests/unit/_async/test_client_extra.py index 8370bd825120..6dbba5bacc25 100644 --- a/packages/google-cloud-spanner/tests/unit/_async/test_client_extra.py +++ b/packages/google-cloud-spanner/tests/unit/_async/test_client_extra.py @@ -131,7 +131,21 @@ async def test_sync_branches_admin_apis(self): self.assertIsNotNone(ia_api) self.assertIsNotNone(da_api) - def test_initialize_metrics_double_check(self): + # Safety shield mocks: We intercept the OpenTelemetry metric classes at the client module namespace level + # to prevent instantiating real exporter objects. This prevents spawning live background worker threads + # that periodically wake up and trigger 401 credential errors inside unauthenticated unit test runs. + @mock.patch("google.cloud.spanner_v1._async.client.CloudMonitoringMetricsExporter") + @mock.patch("google.cloud.spanner_v1._async.client.PeriodicExportingMetricReader") + @mock.patch("google.cloud.spanner_v1._async.client.MeterProvider") + # Global state reset: Temporarily override the module's process-wide global boolean _metrics_monitor_initialized + # to False so that the client enters the initialization logic instead of returning early. + @mock.patch( + "google.cloud.spanner_v1._async.client._metrics_monitor_initialized", + False, + ) + def test_initialize_metrics_double_check( + self, mock_provider, mock_reader, mock_exporter + ): # coverage for line 143->exit from google.cloud.spanner_v1._async import client as MUT @@ -147,15 +161,17 @@ def __enter__(self): def __exit__(self, *args): return original_lock.__exit__(*args) + # Concurrency race condition simulator: Replace the process synchronization lock with our custom SettingLock. + # When this lock enters, it toggles _metrics_monitor_initialized to True to simulate another thread + # completing metrics setup while this thread was waiting for the lock. with mock.patch( - "google.cloud.spanner_v1._async.client._metrics_monitor_initialized", False + "google.cloud.spanner_v1._async.client._metrics_monitor_lock", + SettingLock(), ): - with mock.patch( - "google.cloud.spanner_v1._async.client._metrics_monitor_lock", - SettingLock(), - ): - MUT._initialize_metrics("project", self.credentials) - self.assertTrue(MUT._metrics_monitor_initialized) + # Trigger the initialization function and verify Spanner's double-checked lock safely + # checks the flag again and aborts cleanly to prevent dual-registration. + MUT._initialize_metrics("project", self.credentials) + self.assertTrue(MUT._metrics_monitor_initialized) def test_default_transaction_options_validation(self): # coverage for line 344 diff --git a/packages/google-cloud-spanner/tests/unit/_async/test_session.py b/packages/google-cloud-spanner/tests/unit/_async/test_session.py index 9902c89c4c40..98758b6b904b 100644 --- a/packages/google-cloud-spanner/tests/unit/_async/test_session.py +++ b/packages/google-cloud-spanner/tests/unit/_async/test_session.py @@ -1,4 +1,5 @@ import datetime +import threading from datetime import timezone import google.api_core.gapic_v1.method @@ -1800,11 +1801,16 @@ async def unit_of_work(txn, *args, **kw): called_with.append((txn, args, kw)) txn.insert(TABLE_NAME, COLUMNS, VALUES) + main_thread = threading.current_thread() + _results = [1, 1.5] + # retry once w/ timeout_secs=1 - def _time(_results=[1, 1.5]): - if len(_results) > 1: - return _results.pop(0) - return _results[0] + def _time(): + if threading.current_thread() is main_thread: + if len(_results) > 1: + return _results.pop(0) + return _results[0] + return 1.0 with mock.patch("time.time", _time): with mock.patch( @@ -1877,9 +1883,14 @@ async def unit_of_work(txn, *args, **kw): called_with.append((txn, args, kw)) txn.insert(TABLE_NAME, COLUMNS, VALUES) + main_thread = threading.current_thread() + _results = [1] * 100 + # retry several times to check backoff - def _time(_results=[1] * 100): - return _results.pop(0) + def _time(): + if threading.current_thread() is main_thread: + return _results.pop(0) + return 1.0 with ( mock.patch("time.time", _time), diff --git a/packages/google-cloud-spanner/tests/unit/conftest.py b/packages/google-cloud-spanner/tests/unit/conftest.py index 885ee5dda12b..422fedafe9b8 100644 --- a/packages/google-cloud-spanner/tests/unit/conftest.py +++ b/packages/google-cloud-spanner/tests/unit/conftest.py @@ -14,5 +14,23 @@ import os +import pytest + +from google.cloud.spanner_v1.metrics.spanner_metrics_tracer_factory import ( + SpannerMetricsTracerFactory, +) + # Disable builtin metrics to avoid background thread noise and 401 errors in unit tests os.environ["SPANNER_DISABLE_BUILTIN_METRICS"] = "true" + + +@pytest.fixture(autouse=True) +def reset_metrics_singletons(monkeypatch): + # Reset singletons and env var before test to avoid state pollution + monkeypatch.setenv("SPANNER_DISABLE_BUILTIN_METRICS", "true") + SpannerMetricsTracerFactory._metrics_tracer_factory = None + SpannerMetricsTracerFactory._current_metrics_tracer_ctx.set(None) + yield + # Reset singletons after test to ensure no leakage + SpannerMetricsTracerFactory._metrics_tracer_factory = None + SpannerMetricsTracerFactory._current_metrics_tracer_ctx.set(None) diff --git a/packages/google-cloud-spanner/tests/unit/spanner_dbapi/test_partition_helper.py b/packages/google-cloud-spanner/tests/unit/spanner_dbapi/test_partition_helper.py index def5530a64e1..88d8592bf11a 100644 --- a/packages/google-cloud-spanner/tests/unit/spanner_dbapi/test_partition_helper.py +++ b/packages/google-cloud-spanner/tests/unit/spanner_dbapi/test_partition_helper.py @@ -192,7 +192,7 @@ def collect_protobufs(val): registered_classes = set(partition_helper._PROTO_CLASS_MAP.values()) for cls in discovered_protobuf_classes: - with self.subTest(cls=cls): + with self.subTest(cls_name=cls.__name__): self.assertIn( cls, registered_classes, diff --git a/packages/google-cloud-spanner/tests/unit/test__helpers.py b/packages/google-cloud-spanner/tests/unit/test__helpers.py index b81e745d418f..01c320bf21a5 100644 --- a/packages/google-cloud-spanner/tests/unit/test__helpers.py +++ b/packages/google-cloud-spanner/tests/unit/test__helpers.py @@ -329,7 +329,7 @@ def test_w_numeric_precision_and_scale_valid(self): decimal.Decimal("1E-9"), ] for value in cases: - with self.subTest(value=value): + with self.subTest(value=str(value)): value_pb = self._callFUT(value) self.assertIsInstance(value_pb, Value) self.assertEqual(value_pb.string_value, str(value)) @@ -371,7 +371,7 @@ def test_w_numeric_precision_and_scale_invalid(self): ] for value, err_msg in cases: - with self.subTest(value=value, err_msg=err_msg): + with self.subTest(value=str(value), err_msg=err_msg): self.assertRaisesRegex( ValueError, err_msg, diff --git a/packages/google-cloud-spanner/tests/unit/test_client.py b/packages/google-cloud-spanner/tests/unit/test_client.py index ff1bb0f5d00c..69bb317f58e0 100644 --- a/packages/google-cloud-spanner/tests/unit/test_client.py +++ b/packages/google-cloud-spanner/tests/unit/test_client.py @@ -856,7 +856,9 @@ def test_constructor_logs_options_disabled_by_default(self): info_logger.assert_not_called() # Also test when the environment variable is not set at all - with mock.patch.dict(os.environ, {}, clear=True): + with mock.patch.dict( + os.environ, {"SPANNER_DISABLE_BUILTIN_METRICS": "true"}, clear=True + ): with mock.patch.object(logger, "info") as info_logger: client = self._make_one(project=self.PROJECT, credentials=creds) self.assertIsNotNone(client) diff --git a/packages/google-cloud-spanner/tests/unit/test_metrics.py b/packages/google-cloud-spanner/tests/unit/test_metrics.py index 0a4f618a2feb..94586dece870 100644 --- a/packages/google-cloud-spanner/tests/unit/test_metrics.py +++ b/packages/google-cloud-spanner/tests/unit/test_metrics.py @@ -67,10 +67,8 @@ def patched_client(monkeypatch): with ( patch("google.cloud.spanner_v1.metrics.metrics_exporter.MetricServiceClient"), - patch( - "google.cloud.spanner_v1.metrics.metrics_exporter.CloudMonitoringMetricsExporter" - ), - patch("opentelemetry.sdk.metrics.export.PeriodicExportingMetricReader"), + patch("google.cloud.spanner_v1.client.CloudMonitoringMetricsExporter"), + patch("google.cloud.spanner_v1.client.PeriodicExportingMetricReader"), ): client = Client( project="test", @@ -81,6 +79,7 @@ def patched_client(monkeypatch): # Resetting metrics.set_meter_provider(metrics.NoOpMeterProvider()) SpannerMetricsTracerFactory._metrics_tracer_factory = None + client_module._metrics_monitor_initialized = False # Reset context var ctx = SpannerMetricsTracerFactory._current_metrics_tracer_ctx ctx.set(None) diff --git a/packages/google-cloud-spanner/tests/unit/test_session.py b/packages/google-cloud-spanner/tests/unit/test_session.py index c155b5d84b76..17704cb59b2f 100644 --- a/packages/google-cloud-spanner/tests/unit/test_session.py +++ b/packages/google-cloud-spanner/tests/unit/test_session.py @@ -14,6 +14,7 @@ import datetime +import threading from datetime import timezone import google.api_core.gapic_v1.method @@ -1714,9 +1715,16 @@ def unit_of_work(txn, *args, **kw): called_with.append((txn, args, kw)) txn.insert(TABLE_NAME, COLUMNS, VALUES) + main_thread = threading.current_thread() + _results = [1, 1.5] + # retry once w/ timeout_secs=1 - def _time(_results=[1, 1.5]): - return _results.pop(0) + def _time(): + if threading.current_thread() is main_thread: + if len(_results) > 1: + return _results.pop(0) + return _results[0] + return 1.0 with mock.patch("time.time", _time): with mock.patch("time.sleep") as sleep_mock: @@ -1783,9 +1791,16 @@ def unit_of_work(txn, *args, **kw): called_with.append((txn, args, kw)) txn.insert(TABLE_NAME, COLUMNS, VALUES) + main_thread = threading.current_thread() + _results = [1, 2, 4, 8] + # retry several times to check backoff - def _time(_results=[1, 2, 4, 8]): - return _results.pop(0) + def _time(): + if threading.current_thread() is main_thread: + if len(_results) > 1: + return _results.pop(0) + return _results[0] + return 1.0 with ( mock.patch("time.time", _time), diff --git a/packages/google-cloud-spanner/tests/unit/test_spanner.py b/packages/google-cloud-spanner/tests/unit/test_spanner.py index e11b28475059..8317b605bd28 100644 --- a/packages/google-cloud-spanner/tests/unit/test_spanner.py +++ b/packages/google-cloud-spanner/tests/unit/test_spanner.py @@ -15,7 +15,6 @@ import threading import mock -import pytest from google.api_core import gapic_v1 from google.protobuf.struct_pb2 import Struct @@ -135,6 +134,33 @@ def _make_spanner_api(self): return mock.create_autospec(SpannerClient, instance=True) + def _assert_concurrent_transaction_invariants( + self, call_args_list, expected_count=2 + ): + self.assertEqual(len(call_args_list), expected_count) + + begin_calls = [] + reused_calls = [] + + for call in call_args_list: + request = call.kwargs["request"] + pb_transaction = request.transaction._pb + if pb_transaction.HasField("begin"): + begin_calls.append(call) + elif pb_transaction.id: + reused_calls.append(call) + + self.assertEqual( + len(begin_calls), + 1, + "Exactly one concurrent thread must initiate the transaction.", + ) + self.assertEqual( + len(reused_calls), + expected_count - 1, + f"Remaining {expected_count - 1} thread(s) must reuse the transaction ID.", + ) + def _execute_update_helper( self, transaction, @@ -227,6 +253,7 @@ def _execute_sql_helper( sql_count=0, query_options=None, directed_read_options=None, + concurrent=False, ): VALUES = [["bharney", "rhubbyl", 31], ["phred", "phlyntstone", 32]] VALUE_PBS = [[_make_value_pb(item) for item in row] for row in VALUES] @@ -253,8 +280,9 @@ def _execute_sql_helper( api.execute_streaming_sql.side_effect = lambda *a, **kw: _MockIterator( *result_sets ) - transaction._execute_sql_request_count = sql_count - transaction._read_request_count = count + if not concurrent: + transaction._execute_sql_request_count = sql_count + transaction._read_request_count = count result_set = transaction.execute_sql( SQL_QUERY_WITH_PARAM, @@ -269,12 +297,14 @@ def _execute_sql_helper( directed_read_options=directed_read_options, ) - self.assertEqual(transaction._read_request_count, count + 1) + if not concurrent: + self.assertEqual(transaction._read_request_count, count + 1) self.assertEqual(list(result_set), VALUES) self.assertEqual(result_set.metadata, metadata_pb) self.assertEqual(result_set.stats, stats_pb) - self.assertEqual(transaction._execute_sql_request_count, sql_count + 1) + if not concurrent: + self.assertEqual(transaction._execute_sql_request_count, sql_count + 1) def _execute_sql_expected_request( self, @@ -359,7 +389,7 @@ def _read_helper( for i in range(len(result_sets)): result_sets[i].values.extend(VALUE_PBS[i]) - api.streaming_read.return_value = _MockIterator(*result_sets) + api.streaming_read.side_effect = lambda *a, **kw: _MockIterator(*result_sets) if not concurrent: transaction._read_request_count = count @@ -986,49 +1016,9 @@ def test_transaction_for_concurrent_statement_should_begin_one_transaction_with_ self._batch_update_helper(transaction=transaction, database=database, api=api) - api.execute_sql.assert_any_call( - request=self._execute_update_expected_request(database), - retry=RETRY, - timeout=TIMEOUT, - metadata=[ - ("google-cloud-resource-prefix", database.name), - ("x-goog-spanner-route-to-leader", "true"), - ( - "x-goog-spanner-request-id", - f"1.{REQ_RAND_PROCESS_ID}.{database._nth_client_id}.{database._channel_id}.1.1", - ), - ], - ) - - api.execute_sql.assert_any_call( - request=self._execute_update_expected_request(database, begin=False), - retry=RETRY, - timeout=TIMEOUT, - metadata=[ - ("google-cloud-resource-prefix", database.name), - ("x-goog-spanner-route-to-leader", "true"), - ( - "x-goog-spanner-request-id", - f"1.{REQ_RAND_PROCESS_ID}.{database._nth_client_id}.{database._channel_id}.2.1", - ), - ], + self._assert_concurrent_transaction_invariants( + api.execute_sql.call_args_list, 2 ) - - api.execute_batch_dml.assert_any_call( - request=self._batch_update_expected_request(begin=False), - metadata=[ - ("google-cloud-resource-prefix", database.name), - ("x-goog-spanner-route-to-leader", "true"), - ( - "x-goog-spanner-request-id", - f"1.{REQ_RAND_PROCESS_ID}.{database._nth_client_id}.{database._channel_id}.3.1", - ), - ], - retry=RETRY, - timeout=TIMEOUT, - ) - - self.assertEqual(api.execute_sql.call_count, 2) self.assertEqual(api.execute_batch_dml.call_count, 1) def test_transaction_for_concurrent_statement_should_begin_one_transaction_with_batch_update( @@ -1060,47 +1050,10 @@ def test_transaction_for_concurrent_statement_should_begin_one_transaction_with_ self._execute_update_helper(transaction=transaction, api=api) self.assertEqual(api.execute_sql.call_count, 1) - api.execute_sql.assert_any_call( - request=self._execute_update_expected_request(database, begin=False), - retry=RETRY, - timeout=TIMEOUT, - metadata=[ - ("google-cloud-resource-prefix", database.name), - ("x-goog-spanner-route-to-leader", "true"), - ( - "x-goog-spanner-request-id", - f"1.{REQ_RAND_PROCESS_ID}.{database._nth_client_id}.{database._channel_id}.3.1", - ), - ], - ) - - self.assertEqual(api.execute_batch_dml.call_count, 2) - - call_args_list = api.execute_batch_dml.call_args_list - - request_ids = [] - for call in call_args_list: - metadata = call.kwargs["metadata"] - self.assertEqual(len(metadata), 3) - self.assertEqual( - metadata[0], ("google-cloud-resource-prefix", database.name) - ) - self.assertEqual(metadata[1], ("x-goog-spanner-route-to-leader", "true")) - self.assertEqual(metadata[2][0], "x-goog-spanner-request-id") - request_ids.append(metadata[2][1]) - self.assertEqual(call.kwargs["retry"], RETRY) - self.assertEqual(call.kwargs["timeout"], TIMEOUT) - - expected_id_suffixes = ["1.1", "2.1"] - actual_id_suffixes = sorted( - [".".join(rid.split(".")[-2:]) for rid in request_ids] + self._assert_concurrent_transaction_invariants( + api.execute_batch_dml.call_args_list, 2 ) - self.assertEqual(actual_id_suffixes, expected_id_suffixes) - @pytest.mark.skip( - reason="Concurrent statement execution at transaction start is not deterministic. " - "Will be fixed in a separate change." - ) def test_transaction_for_concurrent_statement_should_begin_one_transaction_with_read( self, ): @@ -1130,55 +1083,11 @@ def test_transaction_for_concurrent_statement_should_begin_one_transaction_with_ self._execute_update_helper(transaction=transaction, api=api) - api.execute_sql.assert_any_call( - request=self._execute_update_expected_request(database, begin=False), - retry=RETRY, - timeout=TIMEOUT, - metadata=[ - ("google-cloud-resource-prefix", database.name), - ("x-goog-spanner-route-to-leader", "true"), - ( - "x-goog-spanner-request-id", - f"1.{REQ_RAND_PROCESS_ID}.{database._nth_client_id}.1.3.1", - ), - ], - ) - self.assertEqual(api.execute_sql.call_count, 1) - self.assertEqual(api.streaming_read.call_count, 2) - - call_args_list = api.streaming_read.call_args_list - - expected_requests = [ - self._read_helper_expected_request(), - self._read_helper_expected_request(begin=False), - ] - actual_requests = [call.kwargs["request"] for call in call_args_list] - self.assertCountEqual(actual_requests, expected_requests) - - request_ids = [] - for call in call_args_list: - metadata = call.kwargs["metadata"] - self.assertEqual(len(metadata), 3) - self.assertEqual( - metadata[0], ("google-cloud-resource-prefix", database.name) - ) - self.assertEqual(metadata[1], ("x-goog-spanner-route-to-leader", "true")) - self.assertEqual(metadata[2][0], "x-goog-spanner-request-id") - request_ids.append(metadata[2][1]) - self.assertEqual(call.kwargs["retry"], RETRY) - self.assertEqual(call.kwargs["timeout"], TIMEOUT) - - expected_id_suffixes = ["1.1", "2.1"] - actual_id_suffixes = sorted( - [".".join(rid.split(".")[-2:]) for rid in request_ids] + self._assert_concurrent_transaction_invariants( + api.streaming_read.call_args_list, 2 ) - self.assertEqual(actual_id_suffixes, expected_id_suffixes) - @pytest.mark.skip( - reason="Concurrent statement execution at transaction start is not deterministic. " - "Will be fixed in a separate change." - ) def test_transaction_for_concurrent_statement_should_begin_one_transaction_with_query( self, ): @@ -1190,13 +1099,13 @@ def test_transaction_for_concurrent_statement_should_begin_one_transaction_with_ threads.append( threading.Thread( target=self._execute_sql_helper, - kwargs={"transaction": transaction, "api": api}, + kwargs={"transaction": transaction, "api": api, "concurrent": True}, ) ) threads.append( threading.Thread( target=self._execute_sql_helper, - kwargs={"transaction": transaction, "api": api}, + kwargs={"transaction": transaction, "api": api, "concurrent": True}, ) ) for thread in threads: @@ -1207,59 +1116,10 @@ def test_transaction_for_concurrent_statement_should_begin_one_transaction_with_ self._execute_update_helper(transaction=transaction, api=api) - begin_read_write_count = sum( - [1 for call in api.mock_calls if "read_write" in call.kwargs.__str__()] - ) - - self.assertEqual(begin_read_write_count, 1) - api.execute_sql.assert_any_call( - request=self._execute_update_expected_request(database, begin=False), - retry=RETRY, - timeout=TIMEOUT, - metadata=[ - ("google-cloud-resource-prefix", database.name), - ("x-goog-spanner-route-to-leader", "true"), - ( - "x-goog-spanner-request-id", - f"1.{REQ_RAND_PROCESS_ID}.{database._nth_client_id}.1.3.1", - ), - ], - ) - - self.assertEqual( - api.execute_streaming_sql.call_args_list, - [ - mock.call( - request=self._execute_sql_expected_request(database), - metadata=[ - ("google-cloud-resource-prefix", database.name), - ("x-goog-spanner-route-to-leader", "true"), - ( - "x-goog-spanner-request-id", - f"1.{REQ_RAND_PROCESS_ID}.{database._nth_client_id}.{database._channel_id}.1.1", - ), - ], - retry=RETRY, - timeout=TIMEOUT, - ), - mock.call( - request=self._execute_sql_expected_request(database, begin=False), - metadata=[ - ("google-cloud-resource-prefix", database.name), - ("x-goog-spanner-route-to-leader", "true"), - ( - "x-goog-spanner-request-id", - f"1.{REQ_RAND_PROCESS_ID}.{database._nth_client_id}.{database._channel_id}.2.1", - ), - ], - retry=RETRY, - timeout=TIMEOUT, - ), - ], - ) - self.assertEqual(api.execute_sql.call_count, 1) - self.assertEqual(api.execute_streaming_sql.call_count, 2) + self._assert_concurrent_transaction_invariants( + api.execute_streaming_sql.call_args_list, 2 + ) def test_transaction_should_execute_sql_with_route_to_leader_disabled(self): database = _Database() From b23bfa4ceb819bca8201a7fe8b64a9bed56733f0 Mon Sep 17 00:00:00 2001 From: Shuowei Li Date: Fri, 5 Jun 2026 01:25:53 +0000 Subject: [PATCH 030/174] fix: nameless column to_frame bug for pandas 3.0 (#17371) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #<519726816> 🦕 --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- packages/bigframes/bigframes/series.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/bigframes/bigframes/series.py b/packages/bigframes/bigframes/series.py index ebf32ac7850d..181bc4f63b2f 100644 --- a/packages/bigframes/bigframes/series.py +++ b/packages/bigframes/bigframes/series.py @@ -2280,11 +2280,14 @@ def mask(self, cond, other=None) -> Series: return self.where(~cond, other) def to_frame(self, name: blocks.Label = None) -> bigframes.dataframe.DataFrame: - provided_name = name if name else self.name + provided_name = name if name is not None else self.name # To be consistent with Pandas, it assigns 0 as the column name if missing. 0 is the first element of RangeIndex. - block = self._block.with_column_labels( - [provided_name] if provided_name else [0] - ) + column_names: List[blocks.Label] + if provided_name is None or pandas.isna([cast(Any, provided_name)])[0]: + column_names = [0] + else: + column_names = [provided_name] + block = self._block.with_column_labels(column_names) return bigframes.dataframe.DataFrame(block) def to_csv( From 3f70b2ff6f6bc5d4c3bee33784da3e353866ec8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Fri, 5 Jun 2026 10:52:56 +0200 Subject: [PATCH 031/174] perf(spanner): optimize query result decoding (#17375) Work in progress. Optimizes the decoding and reading of (large) result sets for Spanner. image --- .../cloud/spanner_v1/_async/streamed.py | 43 ++++-- .../google/cloud/spanner_v1/_helpers.py | 135 +++++++++++------ .../google/cloud/spanner_v1/data_types.py | 8 +- .../google/cloud/spanner_v1/streamed.py | 43 ++++-- .../tests/unit/test__helpers.py | 137 +++++++++++++++++- 5 files changed, 292 insertions(+), 74 deletions(-) diff --git a/packages/google-cloud-spanner/google/cloud/spanner_v1/_async/streamed.py b/packages/google-cloud-spanner/google/cloud/spanner_v1/_async/streamed.py index 3104274ced2c..d16955d88abb 100644 --- a/packages/google-cloud-spanner/google/cloud/spanner_v1/_async/streamed.py +++ b/packages/google-cloud-spanner/google/cloud/spanner_v1/_async/streamed.py @@ -129,16 +129,39 @@ def _merge_values(self, values): decoders = self._decoders width = len(self.fields) index = len(self._current_row) - for value in values: - if self._lazy_decode: - self._current_row.append(value) - else: - self._current_row.append(_parse_nullable(value, decoders[index])) - index += 1 - if index == width: - self._rows.append(self._current_row) - self._current_row = [] - index = 0 + current_row = self._current_row + rows = self._rows + + current_row_append = current_row.append + rows_append = rows.append + + if self._lazy_decode: + for value in values: + current_row_append(value) + index += 1 + if index == width: + rows_append(current_row) + current_row = [] + current_row_append = current_row.append + index = 0 + else: + for value in values: + # Note: We manually check value.HasField("null_value") here instead of + # wrapping every decoder in _parse_nullable to avoid the overhead of + # an extra Python function call layer for every cell value decoded in this loop. + # If the nullable check logic is updated in _parse_nullable, update this check. + if value.HasField("null_value"): + current_row_append(None) + else: + current_row_append(decoders[index](value)) + index += 1 + if index == width: + rows_append(current_row) + current_row = [] + current_row_append = current_row.append + index = 0 + + self._current_row = current_row @CrossSync.convert async def _consume_next(self): diff --git a/packages/google-cloud-spanner/google/cloud/spanner_v1/_helpers.py b/packages/google-cloud-spanner/google/cloud/spanner_v1/_helpers.py index dfcf6721af82..a9b1c448860c 100644 --- a/packages/google-cloud-spanner/google/cloud/spanner_v1/_helpers.py +++ b/packages/google-cloud-spanner/google/cloud/spanner_v1/_helpers.py @@ -19,6 +19,7 @@ import decimal import logging import math +import operator import threading import time import uuid @@ -26,7 +27,6 @@ from google.api_core import datetime_helpers from google.api_core.exceptions import Aborted -from google.cloud._helpers import _date_from_iso8601_date from google.protobuf.internal.enum_type_wrapper import EnumTypeWrapper from google.protobuf.message import DecodeError, Message from google.protobuf.struct_pb2 import ListValue, Value @@ -465,6 +465,12 @@ def _parse_value_pb(value_pb, field_type, field_name, column_info=None): return _parse_nullable(value_pb, decoder) +_date_fromisoformat = datetime.date.fromisoformat +_Decimal = decimal.Decimal +_json_from_str = JsonObject.from_str +_uuid_UUID = uuid.UUID + + def _get_type_decoder(field_type, field_name, column_info=None): """Returns a function that converts a Value protobuf to cell data. @@ -489,28 +495,30 @@ def _get_type_decoder(field_type, field_name, column_info=None): """ type_code = field_type.code + # Note: STRING and BOOL use operator.attrgetter because direct attribute extraction + # is faster in Python. Other types require type transformation, so they use lambdas. if type_code == TypeCode.STRING: - return _parse_string + return operator.attrgetter("string_value") elif type_code == TypeCode.BYTES: - return _parse_bytes + return lambda value_pb: value_pb.string_value.encode("utf8") elif type_code == TypeCode.BOOL: - return _parse_bool + return operator.attrgetter("bool_value") elif type_code == TypeCode.INT64: - return _parse_int64 + return lambda value_pb: int(value_pb.string_value) elif type_code == TypeCode.FLOAT64: return _parse_float elif type_code == TypeCode.FLOAT32: return _parse_float elif type_code == TypeCode.DATE: - return _parse_date + return lambda value_pb: _date_fromisoformat(value_pb.string_value) elif type_code == TypeCode.TIMESTAMP: return _parse_timestamp elif type_code == TypeCode.NUMERIC: - return _parse_numeric + return lambda value_pb: _Decimal(value_pb.string_value) elif type_code == TypeCode.JSON: - return _parse_json + return lambda value_pb: _json_from_str(value_pb.string_value) elif type_code == TypeCode.UUID: - return _parse_uuid + return lambda value_pb: _uuid_UUID(value_pb.string_value) elif type_code == TypeCode.PROTO: return lambda value_pb: _parse_proto(value_pb, column_info, field_name) elif type_code == TypeCode.ENUM: @@ -553,48 +561,81 @@ def _parse_list_value_pbs(rows, row_type): return result -def _parse_string(value_pb) -> str: - return value_pb.string_value - - -def _parse_bytes(value_pb): - return value_pb.string_value.encode("utf8") - - -def _parse_bool(value_pb) -> bool: - return value_pb.bool_value - - -def _parse_int64(value_pb) -> int: - return int(value_pb.string_value) - - def _parse_float(value_pb) -> float: - if value_pb.HasField("string_value"): - return float(value_pb.string_value) - else: - return value_pb.number_value - - -def _parse_date(value_pb): - return _date_from_iso8601_date(value_pb.string_value) + # Note: Storing val = value_pb.string_value and doing a truthiness check is faster + # than calling value_pb.HasField("string_value") because it avoids the C-extension + # method lookup/call overhead and accesses the attribute only once. + val = value_pb.string_value + return float(val) if val else value_pb.number_value + + +_POWERS_OF_10 = ( + 1, + 10, + 100, + 1000, + 10000, + 100000, + 1000000, + 10000000, + 100000000, + 1000000000, +) def _parse_timestamp(value_pb): - DatetimeWithNanoseconds = datetime_helpers.DatetimeWithNanoseconds - return DatetimeWithNanoseconds.from_rfc3339(value_pb.string_value) - - -def _parse_numeric(value_pb): - return decimal.Decimal(value_pb.string_value) - - -def _parse_json(value_pb): - return JsonObject.from_str(value_pb.string_value) - - -def _parse_uuid(value_pb): - return uuid.UUID(value_pb.string_value) + val = value_pb.string_value + try: + if len(val) < 20 or val[10] != "T": + raise ValueError() + no_fraction = val[:19] + bare = datetime.datetime.fromisoformat(no_fraction) + if val[19] == ".": + if val.endswith("Z"): + offset = "Z" + fraction = val[20:-1] + elif val[-6] in ("+", "-"): + offset = val[-6:] + fraction = val[20:-6] + else: + raise ValueError() + if not fraction or len(fraction) > 9 or not fraction.isdigit(): + raise ValueError() + scale = 9 - len(fraction) + nanos = int(fraction) * _POWERS_OF_10[scale] + else: + nanos = 0 + if val.endswith("Z"): + offset = "Z" + elif val[-6] in ("+", "-"): + offset = val[-6:] + else: + raise ValueError() + + if offset != "Z": + sign = offset[0] + hours = int(offset[1:3]) + minutes = int(offset[4:6]) + if offset[3] != ":": + raise ValueError() + delta = datetime.timedelta(hours=hours, minutes=minutes) + if sign == "-": + delta = -delta + tzinfo = datetime.timezone(delta) + bare = bare.replace(tzinfo=tzinfo).astimezone(datetime.timezone.utc) + + return datetime_helpers.DatetimeWithNanoseconds( + bare.year, + bare.month, + bare.day, + bare.hour, + bare.minute, + bare.second, + nanosecond=nanos, + tzinfo=datetime.timezone.utc, + ) + except (IndexError, ValueError) as e: + raise ValueError("Timestamp: {} does not match pattern".format(val)) from e def _parse_proto(value_pb, column_info, field_name): diff --git a/packages/google-cloud-spanner/google/cloud/spanner_v1/data_types.py b/packages/google-cloud-spanner/google/cloud/spanner_v1/data_types.py index 3c3a7f6bfe32..59a2268e98a7 100644 --- a/packages/google-cloud-spanner/google/cloud/spanner_v1/data_types.py +++ b/packages/google-cloud-spanner/google/cloud/spanner_v1/data_types.py @@ -99,6 +99,11 @@ def serialize(self): return json.dumps(self, sort_keys=True, separators=(",", ":")) +_INTERVAL_PATTERN = re.compile( + r"^P(-?\d+Y)?(-?\d+M)?(-?\d+D)?(T(-?\d+H)?(-?\d+M)?(-?((\d+([.,]\d{1,9})?)|([.,]\d{1,9}))S)?)?$" +) + + @dataclass class Interval: """Represents a Spanner INTERVAL type. @@ -187,8 +192,7 @@ def __str__(self) -> str: @classmethod def from_str(cls, s: str) -> "Interval": """Parse an ISO8601 duration format string into an Interval.""" - pattern = r"^P(-?\d+Y)?(-?\d+M)?(-?\d+D)?(T(-?\d+H)?(-?\d+M)?(-?((\d+([.,]\d{1,9})?)|([.,]\d{1,9}))S)?)?$" - match = re.match(pattern, s) + match = _INTERVAL_PATTERN.match(s) if not match or len(s) == 1: raise ValueError(f"Invalid interval format: {s}") diff --git a/packages/google-cloud-spanner/google/cloud/spanner_v1/streamed.py b/packages/google-cloud-spanner/google/cloud/spanner_v1/streamed.py index 59d8d8b746d5..8facd015151d 100644 --- a/packages/google-cloud-spanner/google/cloud/spanner_v1/streamed.py +++ b/packages/google-cloud-spanner/google/cloud/spanner_v1/streamed.py @@ -35,8 +35,7 @@ class StreamedResultSet(object): instances. :type source: :class:`~google.cloud.spanner_v1.snapshot.Snapshot` - :param source: Deprecated. Snapshot from which the result set was fetched. - """ + :param source: Deprecated. Snapshot from which the result set was fetched.""" def __init__( self, @@ -117,16 +116,36 @@ def _merge_values(self, values): decoders = self._decoders width = len(self.fields) index = len(self._current_row) - for value in values: - if self._lazy_decode: - self._current_row.append(value) - else: - self._current_row.append(_parse_nullable(value, decoders[index])) - index += 1 - if index == width: - self._rows.append(self._current_row) - self._current_row = [] - index = 0 + current_row = self._current_row + rows = self._rows + current_row_append = current_row.append + rows_append = rows.append + if self._lazy_decode: + for value in values: + current_row_append(value) + index += 1 + if index == width: + rows_append(current_row) + current_row = [] + current_row_append = current_row.append + index = 0 + else: + for value in values: + # Note: We manually check value.HasField("null_value") here instead of + # wrapping every decoder in _parse_nullable to avoid the overhead of + # an extra Python function call layer for every cell value decoded in this loop. + # If the nullable check logic is updated in _parse_nullable, update this check. + if value.HasField("null_value"): + current_row_append(None) + else: + current_row_append(decoders[index](value)) + index += 1 + if index == width: + rows_append(current_row) + current_row = [] + current_row_append = current_row.append + index = 0 + self._current_row = current_row def _consume_next(self): """Consume the next partial result set from the stream. diff --git a/packages/google-cloud-spanner/tests/unit/test__helpers.py b/packages/google-cloud-spanner/tests/unit/test__helpers.py index 01c320bf21a5..53f38b7aa76e 100644 --- a/packages/google-cloud-spanner/tests/unit/test__helpers.py +++ b/packages/google-cloud-spanner/tests/unit/test__helpers.py @@ -626,15 +626,16 @@ def test_w_timestamp_wo_nanos(self): from google.cloud.spanner_v1 import Type, TypeCode value = datetime_helpers.DatetimeWithNanoseconds( - 2016, 12, 20, 21, 13, 47, microsecond=123456, tzinfo=timezone.utc + 2016, 12, 20, 21, 13, 47, nanosecond=123456000, tzinfo=timezone.utc ) field_type = Type(code=TypeCode.TIMESTAMP) field_name = "nanos_column" - value_pb = Value(string_value=datetime_helpers.to_rfc3339(value)) + value_pb = Value(string_value="2016-12-20T21:13:47.123456Z") parsed = self._callFUT(value_pb, field_type, field_name) self.assertIsInstance(parsed, datetime_helpers.DatetimeWithNanoseconds) self.assertEqual(parsed, value) + self.assertEqual(parsed.nanosecond, value.nanosecond) def test_w_timestamp_w_nanos(self): from google.api_core import datetime_helpers @@ -647,11 +648,141 @@ def test_w_timestamp_w_nanos(self): ) field_type = Type(code=TypeCode.TIMESTAMP) field_name = "timestamp_column" - value_pb = Value(string_value=datetime_helpers.to_rfc3339(value)) + value_pb = Value(string_value="2016-12-20T21:13:47.123456789Z") parsed = self._callFUT(value_pb, field_type, field_name) self.assertIsInstance(parsed, datetime_helpers.DatetimeWithNanoseconds) self.assertEqual(parsed, value) + self.assertEqual(parsed.nanosecond, value.nanosecond) + + def test_w_timestamp_w_offset(self): + from google.api_core import datetime_helpers + from google.protobuf.struct_pb2 import Value + + from google.cloud.spanner_v1 import Type, TypeCode + + value_pb = Value(string_value="2016-12-20T12:13:47.123456789+01:00") + field_type = Type(code=TypeCode.TIMESTAMP) + field_name = "timestamp_column" + + expected = datetime_helpers.DatetimeWithNanoseconds( + 2016, 12, 20, 11, 13, 47, nanosecond=123456789, tzinfo=timezone.utc + ) + + parsed = self._callFUT(value_pb, field_type, field_name) + self.assertIsInstance(parsed, datetime_helpers.DatetimeWithNanoseconds) + self.assertEqual(parsed, expected) + self.assertEqual(parsed.nanosecond, expected.nanosecond) + + value_pb_neg = Value(string_value="2016-12-20T12:13:47.123456789-05:00") + expected_neg = datetime_helpers.DatetimeWithNanoseconds( + 2016, 12, 20, 17, 13, 47, nanosecond=123456789, tzinfo=timezone.utc + ) + parsed_neg = self._callFUT(value_pb_neg, field_type, field_name) + self.assertEqual(parsed_neg, expected_neg) + self.assertEqual(parsed_neg.nanosecond, expected_neg.nanosecond) + + def test_w_timestamp_various_formats(self): + from google.api_core import datetime_helpers + from google.protobuf.struct_pb2 import Value + + from google.cloud.spanner_v1 import Type, TypeCode + + field_type = Type(code=TypeCode.TIMESTAMP) + field_name = "timestamp_column" + + # 1. No seconds fraction, UTC (Z) + value_pb = Value(string_value="2016-12-20T21:13:47Z") + expected = datetime_helpers.DatetimeWithNanoseconds( + 2016, 12, 20, 21, 13, 47, nanosecond=0, tzinfo=timezone.utc + ) + parsed = self._callFUT(value_pb, field_type, field_name) + self.assertEqual(parsed, expected) + self.assertEqual(parsed.nanosecond, expected.nanosecond) + + # 2. Single digit fraction (nanoseconds), UTC (Z) + value_pb = Value(string_value="2016-12-20T21:13:47.1Z") + expected = datetime_helpers.DatetimeWithNanoseconds( + 2016, 12, 20, 21, 13, 47, nanosecond=100000000, tzinfo=timezone.utc + ) + parsed = self._callFUT(value_pb, field_type, field_name) + self.assertEqual(parsed, expected) + self.assertEqual(parsed.nanosecond, expected.nanosecond) + + # 3. Milliseconds (3 digits fraction), UTC (Z) + value_pb = Value(string_value="2016-12-20T21:13:47.123Z") + expected = datetime_helpers.DatetimeWithNanoseconds( + 2016, 12, 20, 21, 13, 47, nanosecond=123000000, tzinfo=timezone.utc + ) + parsed = self._callFUT(value_pb, field_type, field_name) + self.assertEqual(parsed, expected) + self.assertEqual(parsed.nanosecond, expected.nanosecond) + + # 4. Microseconds (6 digits fraction), UTC (Z) + value_pb = Value(string_value="2016-12-20T21:13:47.123456Z") + expected = datetime_helpers.DatetimeWithNanoseconds( + 2016, 12, 20, 21, 13, 47, nanosecond=123456000, tzinfo=timezone.utc + ) + parsed = self._callFUT(value_pb, field_type, field_name) + self.assertEqual(parsed, expected) + self.assertEqual(parsed.nanosecond, expected.nanosecond) + + # 5. Offset without seconds fraction + value_pb = Value(string_value="2016-12-20T21:13:47+02:00") + expected = datetime_helpers.DatetimeWithNanoseconds( + 2016, 12, 20, 19, 13, 47, nanosecond=0, tzinfo=timezone.utc + ) + parsed = self._callFUT(value_pb, field_type, field_name) + self.assertEqual(parsed, expected) + self.assertEqual(parsed.nanosecond, expected.nanosecond) + + def test_datetime_with_nanoseconds_equality_ignores_nanoseconds(self): + from google.api_core import datetime_helpers + from google.protobuf.struct_pb2 import Value + + from google.cloud.spanner_v1 import Type, TypeCode + + field_type = Type(code=TypeCode.TIMESTAMP) + field_name = "timestamp_column" + + # Actual parsed timestamp has nanoseconds = 123456789 + value_pb = Value(string_value="2016-12-20T21:13:47.123456789Z") + parsed = self._callFUT(value_pb, field_type, field_name) + + # Expected object with DIFFERENT nanoseconds but SAME microseconds (123456) + expected_different_nanos = datetime_helpers.DatetimeWithNanoseconds( + 2016, 12, 20, 21, 13, 47, nanosecond=123456000, tzinfo=timezone.utc + ) + + # Assert that standard assertEqual would FALSE POSITIVE (return True / pass) + self.assertEqual(parsed, expected_different_nanos) + + # Assert that their actual nanosecond property values are DIFFERENT + self.assertNotEqual(parsed.nanosecond, expected_different_nanos.nanosecond) + + def test_w_timestamp_invalid_formats(self): + from google.protobuf.struct_pb2 import Value + + from google.cloud.spanner_v1 import Type, TypeCode + + field_type = Type(code=TypeCode.TIMESTAMP) + field_name = "timestamp_column" + + invalid_strings = [ + "2016-12-20T21:13:47", # Missing timezone offset + "2016-12-20 21:13:47Z", # Space instead of 'T' separator + "2016-12-20T21:13:47+0100", # Missing colon in offset + "2016-12-20T21:13:47.1234567890Z", # Too many sub-seconds digits (10 digits) + "2016-12-20T21:13:4Z", # Single digit second + "2016-12-20T21:1:47Z", # Single digit minute + "2016-12-20T2:13:47Z", # Single digit hour + "2016-12-20T21:13:47+1:00", # Single digit hour in offset + ] + + for invalid_string in invalid_strings: + value_pb = Value(string_value=invalid_string) + with self.assertRaises((ValueError, IndexError)): + self._callFUT(value_pb, field_type, field_name) def test_w_array_empty(self): from google.protobuf.struct_pb2 import ListValue, Value From e0961270013ceea2c191ec2c6d445c5c5f928ddf Mon Sep 17 00:00:00 2001 From: nbayati <99771966+nbayati@users.noreply.github.com> Date: Fri, 5 Jun 2026 08:15:54 -0700 Subject: [PATCH 032/174] fix: fail-fast on missing ECP config file to avoid 30s hang (#17377) This PR resolves two issues in the `google-auth` package: First, it adds a fast-fail check for ECP configuration. When the `GOOGLE_API_CERTIFICATE_CONFIG` environment variable is set but the configuration file is missing (common on corporate workstations or clean sandbox test runners), the SDK was falling through to the well-known SPIFFE path and waiting on a 30-second retry loop. We now check if the config path is set but missing, and if we are not in a workload environment (the well-known credentials directory is absent), we immediately return `None` to fallback to unbound tokens. (Fixes b/512912028) Second, it fixes an incorrect mock in `test_mtls.py`. `test_default_client_encrypted_cert_source` was mocking `open` in the test namespace instead of the target module namespace. This caused the test to write actual `cert_path` and `key_path` files to the local disk during test runs. This is fixed by patching `google.auth.transport.mtls.open`. Unit tests have been added to verify the fast-fail behavior, and existing retry tests have been updated to mock the workload directory. All tests now pass without writing files to disk. --- .../google/auth/_agent_identity_utils.py | 8 +++++ .../tests/test_agent_identity_utils.py | 35 +++++++++++++++++-- .../google-auth/tests/transport/test_mtls.py | 4 ++- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/packages/google-auth/google/auth/_agent_identity_utils.py b/packages/google-auth/google/auth/_agent_identity_utils.py index 8a1eddbe1cd3..b57c7bc82b52 100644 --- a/packages/google-auth/google/auth/_agent_identity_utils.py +++ b/packages/google-auth/google/auth/_agent_identity_utils.py @@ -89,6 +89,14 @@ def get_agent_identity_certificate_path(): if not cert_config_path and not has_well_known_dir: return None + # If ECP config path is specified but does not exist, and we are on a workstation, fail-fast immediately. + if ( + cert_config_path + and not has_well_known_dir + and not os.path.exists(cert_config_path) + ): + return None + has_logged_config_warning = False has_logged_cert_warning = False diff --git a/packages/google-auth/tests/test_agent_identity_utils.py b/packages/google-auth/tests/test_agent_identity_utils.py index f74bdad9e475..50a47367b9d7 100644 --- a/packages/google-auth/tests/test_agent_identity_utils.py +++ b/packages/google-auth/tests/test_agent_identity_utils.py @@ -165,14 +165,23 @@ def test_get_agent_identity_certificate_path_success(self, tmpdir, monkeypatch): assert result == str(cert_path) @mock.patch("time.sleep") + @mock.patch("google.auth._agent_identity_utils.os.path.exists") def test_get_agent_identity_certificate_path_retry( - self, mock_sleep, tmpdir, monkeypatch + self, mock_exists, mock_sleep, tmpdir, monkeypatch ): config_path = tmpdir.join("config.json") monkeypatch.setenv( environment_vars.GOOGLE_API_CERTIFICATE_CONFIG, str(config_path) ) + # Simulate workload env (well_known_dir exists) to avoid fail-fast + def exists_side_effect(path): + if path == "/var/run/secrets/workload-spiffe-credentials": + return True + return False + + mock_exists.side_effect = exists_side_effect + # File doesn't exist initially with pytest.raises(exceptions.RefreshError): _agent_identity_utils.get_agent_identity_certificate_path() @@ -180,14 +189,23 @@ def test_get_agent_identity_certificate_path_retry( assert mock_sleep.call_count == len(_agent_identity_utils._POLLING_INTERVALS) @mock.patch("time.sleep") + @mock.patch("google.auth._agent_identity_utils.os.path.exists") def test_get_agent_identity_certificate_path_failure( - self, mock_sleep, tmpdir, monkeypatch + self, mock_exists, mock_sleep, tmpdir, monkeypatch ): config_path = tmpdir.join("non_existent_config.json") monkeypatch.setenv( environment_vars.GOOGLE_API_CERTIFICATE_CONFIG, str(config_path) ) + # Simulate workload env (well_known_dir exists) to avoid fail-fast + def exists_side_effect(path): + if path == "/var/run/secrets/workload-spiffe-credentials": + return True + return False + + mock_exists.side_effect = exists_side_effect + with pytest.raises(exceptions.RefreshError) as excinfo: _agent_identity_utils.get_agent_identity_certificate_path() @@ -198,6 +216,19 @@ def test_get_agent_identity_certificate_path_failure( ) assert mock_sleep.call_count == len(_agent_identity_utils._POLLING_INTERVALS) + def test_get_agent_identity_certificate_path_workstation_fail_fast( + self, tmpdir, monkeypatch + ): + config_path = tmpdir.join("non_existent_config.json") + monkeypatch.setenv( + environment_vars.GOOGLE_API_CERTIFICATE_CONFIG, str(config_path) + ) + + # On a workstation, well_known_dir does not exist, and config file is missing. + # It should fail-fast and return None immediately. + result = _agent_identity_utils.get_agent_identity_certificate_path() + assert result is None + @mock.patch("time.sleep") @mock.patch("os.path.exists") def test_get_agent_identity_certificate_path_cert_not_found( diff --git a/packages/google-auth/tests/transport/test_mtls.py b/packages/google-auth/tests/transport/test_mtls.py index fc0e69bd377c..405cb496cad2 100644 --- a/packages/google-auth/tests/transport/test_mtls.py +++ b/packages/google-auth/tests/transport/test_mtls.py @@ -154,8 +154,10 @@ def test_default_client_encrypted_cert_source( # Test good callback. get_client_ssl_credentials.return_value = (True, b"cert", b"key", b"passphrase") callback = mtls.default_client_encrypted_cert_source("cert_path", "key_path") - with mock.patch("{}.open".format(__name__), return_value=mock.MagicMock()): + with mock.patch("google.auth.transport.mtls.open", mock.mock_open()) as mock_file: assert callback() == ("cert_path", "key_path", b"passphrase") + mock_file.assert_any_call("cert_path", "wb") + mock_file.assert_any_call("key_path", "wb") # Test bad callback which throws exception. get_client_ssl_credentials.side_effect = exceptions.ClientCertError() From 4005e660a38fd770f8754af1cd07d6d8aa9ed60e Mon Sep 17 00:00:00 2001 From: Daniel Sanche Date: Fri, 5 Jun 2026 08:54:34 -0700 Subject: [PATCH 033/174] feat: added client side metric instrumentation to read_rows and mutate_rows (#16758) Migration of https://github.com/googleapis/python-bigtable/pull/1256 to the monorepo Builds off of https://github.com/googleapis/google-cloud-python/pull/16712/ to add instrumentation to read_rows and mutate_rows, along with the mutation batcher --- .../bigtable/data/_async/_mutate_rows.py | 82 +- .../cloud/bigtable/data/_async/_read_rows.py | 244 ++-- .../cloud/bigtable/data/_async/client.py | 36 +- .../bigtable/data/_async/mutations_batcher.py | 33 +- .../data/_sync_autogen/_mutate_rows.py | 74 +- .../bigtable/data/_sync_autogen/_read_rows.py | 215 +-- .../bigtable/data/_sync_autogen/client.py | 33 +- .../data/_sync_autogen/mutations_batcher.py | 31 +- .../tests/system/data/test_metrics_async.py | 1219 +++++++++++++++++ .../tests/system/data/test_metrics_autogen.py | 1020 ++++++++++++++ .../unit/data/_async/test__mutate_rows.py | 22 +- .../tests/unit/data/_async/test__read_rows.py | 16 +- .../tests/unit/data/_async/test_client.py | 105 +- .../data/_async/test_mutations_batcher.py | 29 +- .../data/_async/test_read_rows_acceptance.py | 37 +- .../data/_sync_autogen/test__mutate_rows.py | 25 +- .../data/_sync_autogen/test__read_rows.py | 16 +- .../unit/data/_sync_autogen/test_client.py | 70 +- .../_sync_autogen/test_mutations_batcher.py | 27 +- .../test_read_rows_acceptance.py | 39 +- 20 files changed, 2931 insertions(+), 442 deletions(-) diff --git a/packages/google-cloud-bigtable/google/cloud/bigtable/data/_async/_mutate_rows.py b/packages/google-cloud-bigtable/google/cloud/bigtable/data/_async/_mutate_rows.py index 6efb9e5f25be..974e450d232b 100644 --- a/packages/google-cloud-bigtable/google/cloud/bigtable/data/_async/_mutate_rows.py +++ b/packages/google-cloud-bigtable/google/cloud/bigtable/data/_async/_mutate_rows.py @@ -22,10 +22,8 @@ import google.cloud.bigtable.data.exceptions as bt_exceptions import google.cloud.bigtable_v2.types.bigtable as types_pb from google.cloud.bigtable.data._cross_sync import CrossSync -from google.cloud.bigtable.data._helpers import ( - _attempt_timeout_generator, - _retry_exception_factory, -) +from google.cloud.bigtable.data._helpers import _attempt_timeout_generator +from google.cloud.bigtable.data._metrics import tracked_retry # mutate_rows requests are limited to this number of mutations from google.cloud.bigtable.data.mutations import ( @@ -34,6 +32,7 @@ ) if TYPE_CHECKING: + from google.cloud.bigtable.data._metrics import ActiveOperationMetric from google.cloud.bigtable.data.mutations import RowMutationEntry if CrossSync.is_async: @@ -72,6 +71,8 @@ class _MutateRowsOperationAsync: operation_timeout: the timeout to use for the entire operation, in seconds. attempt_timeout: the timeout to use for each mutate_rows attempt, in seconds. If not specified, the request will run until operation_timeout is reached. + metric: the metric object representing the active operation + retryable_exceptions: a list of exceptions that should be retried """ @CrossSync.convert @@ -82,6 +83,7 @@ def __init__( mutation_entries: list["RowMutationEntry"], operation_timeout: float, attempt_timeout: float | None, + metric: ActiveOperationMetric, retryable_exceptions: Sequence[type[Exception]] = (), ): # check that mutations are within limits @@ -101,13 +103,12 @@ def __init__( # Entry level errors bt_exceptions._MutateRowsIncomplete, ) - sleep_generator = retries.exponential_sleep_generator(0.01, 2, 60) - self._operation = lambda: CrossSync.retry_target( - self._run_attempt, - self.is_retryable, - sleep_generator, - operation_timeout, - exception_factory=_retry_exception_factory, + self._operation = lambda: tracked_retry( + retry_fn=CrossSync.retry_target, + operation=metric, + target=self._run_attempt, + predicate=self.is_retryable, + timeout=operation_timeout, ) # initialize state self.timeout_generator = _attempt_timeout_generator( @@ -116,6 +117,8 @@ def __init__( self.mutations = [_EntryWithProto(m, m._to_pb()) for m in mutation_entries] self.remaining_indices = list(range(len(self.mutations))) self.errors: dict[int, list[Exception]] = {} + # set up metrics + self._operation_metric = metric @CrossSync.convert async def start(self): @@ -125,34 +128,35 @@ async def start(self): Raises: MutationsExceptionGroup: if any mutations failed """ - try: - # trigger mutate_rows - await self._operation() - except Exception as exc: - # exceptions raised by retryable are added to the list of exceptions for all unfinalized mutations - incomplete_indices = self.remaining_indices.copy() - for idx in incomplete_indices: - self._handle_entry_error(idx, exc) - finally: - # raise exception detailing incomplete mutations - all_errors: list[Exception] = [] - for idx, exc_list in self.errors.items(): - if len(exc_list) == 0: - raise core_exceptions.ClientError( - f"Mutation {idx} failed with no associated errors" + with self._operation_metric: + try: + # trigger mutate_rows + await self._operation() + except Exception as exc: + # exceptions raised by retryable are added to the list of exceptions for all unfinalized mutations + incomplete_indices = self.remaining_indices.copy() + for idx in incomplete_indices: + self._handle_entry_error(idx, exc) + finally: + # raise exception detailing incomplete mutations + all_errors: list[Exception] = [] + for idx, exc_list in self.errors.items(): + if len(exc_list) == 0: + raise core_exceptions.ClientError( + f"Mutation {idx} failed with no associated errors" + ) + elif len(exc_list) == 1: + cause_exc = exc_list[0] + else: + cause_exc = bt_exceptions.RetryExceptionGroup(exc_list) + entry = self.mutations[idx].entry + all_errors.append( + bt_exceptions.FailedMutationEntryError(idx, entry, cause_exc) + ) + if all_errors: + raise bt_exceptions.MutationsExceptionGroup( + all_errors, len(self.mutations) ) - elif len(exc_list) == 1: - cause_exc = exc_list[0] - else: - cause_exc = bt_exceptions.RetryExceptionGroup(exc_list) - entry = self.mutations[idx].entry - all_errors.append( - bt_exceptions.FailedMutationEntryError(idx, entry, cause_exc) - ) - if all_errors: - raise bt_exceptions.MutationsExceptionGroup( - all_errors, len(self.mutations) - ) @CrossSync.convert async def _run_attempt(self): @@ -164,6 +168,8 @@ async def _run_attempt(self): retry after the attempt is complete GoogleAPICallError: if the gapic rpc fails """ + # register attempt start + self._operation_metric.start_attempt() request_entries = [self.mutations[idx].proto for idx in self.remaining_indices] # track mutations in this request that have not been finalized yet active_request_indices = { diff --git a/packages/google-cloud-bigtable/google/cloud/bigtable/data/_async/_read_rows.py b/packages/google-cloud-bigtable/google/cloud/bigtable/data/_async/_read_rows.py index f8e203bc10b3..ab7eb3ceccb3 100644 --- a/packages/google-cloud-bigtable/google/cloud/bigtable/data/_async/_read_rows.py +++ b/packages/google-cloud-bigtable/google/cloud/bigtable/data/_async/_read_rows.py @@ -15,16 +15,17 @@ from __future__ import annotations +import time from typing import TYPE_CHECKING, Sequence from google.api_core import retry as retries -from google.api_core.retry import exponential_sleep_generator +from grpc import StatusCode from google.cloud.bigtable.data._cross_sync import CrossSync from google.cloud.bigtable.data._helpers import ( _attempt_timeout_generator, - _retry_exception_factory, ) +from google.cloud.bigtable.data._metrics import tracked_retry from google.cloud.bigtable.data.exceptions import ( InvalidChunk, _ResetRow, @@ -38,6 +39,8 @@ from google.cloud.bigtable_v2.types import RowSet as RowSetPB if TYPE_CHECKING: + from google.cloud.bigtable.data._metrics import ActiveOperationMetric + if CrossSync.is_async: from google.cloud.bigtable.data._async.client import ( _DataApiTargetAsync as TargetType, @@ -68,6 +71,7 @@ class _ReadRowsOperationAsync: target: The table or view to send the request to operation_timeout: The total time to allow for the operation, in seconds attempt_timeout: The time to allow for each individual attempt, in seconds + metric: the metric object representing the active operation retryable_exceptions: A list of exceptions that should trigger a retry """ @@ -79,6 +83,7 @@ class _ReadRowsOperationAsync: "_predicate", "_last_yielded_row_key", "_remaining_count", + "_operation_metric", ) def __init__( @@ -87,6 +92,7 @@ def __init__( target: TargetType, operation_timeout: float, attempt_timeout: float, + metric: ActiveOperationMetric, retryable_exceptions: Sequence[type[Exception]] = (), ): self.attempt_timeout_gen = _attempt_timeout_generator( @@ -105,6 +111,7 @@ def __init__( self._predicate = retries.if_exception_type(*retryable_exceptions) self._last_yielded_row_key: bytes | None = None self._remaining_count: int | None = self.request.rows_limit or None + self._operation_metric = metric def start_operation(self) -> CrossSync.Iterable[Row]: """ @@ -113,12 +120,12 @@ def start_operation(self) -> CrossSync.Iterable[Row]: Yields: Row: The next row in the stream """ - return CrossSync.retry_target_stream( - self._read_rows_attempt, - self._predicate, - exponential_sleep_generator(0.01, 60, multiplier=2), - self.operation_timeout, - exception_factory=_retry_exception_factory, + return tracked_retry( + retry_fn=CrossSync.retry_target_stream, + operation=self._operation_metric, + target=self._read_rows_attempt, + predicate=self._predicate, + timeout=self.operation_timeout, ) def _read_rows_attempt(self) -> CrossSync.Iterable[Row]: @@ -131,6 +138,7 @@ def _read_rows_attempt(self) -> CrossSync.Iterable[Row]: Yields: Row: The next row in the stream """ + self._operation_metric.start_attempt() # revise request keys and ranges between attempts if self._last_yielded_row_key is not None: # if this is a retry, try to trim down the request to avoid ones we've already processed @@ -208,12 +216,11 @@ async def chunk_stream( raise InvalidChunk("emit count exceeds row limit") current_key = None - @staticmethod @CrossSync.convert( replace_symbols={"__aiter__": "__iter__", "__anext__": "__next__"}, ) async def merge_rows( - chunks: CrossSync.Iterable[ReadRowsResponsePB.CellChunk] | None, + self, chunks: CrossSync.Iterable[ReadRowsResponsePB.CellChunk] | None ) -> CrossSync.Iterable[Row]: """ Merge chunks into rows @@ -223,108 +230,125 @@ async def merge_rows( Yields: Row: the next row in the stream """ - if chunks is None: - return - it = chunks.__aiter__() - # For each row - while True: - try: - c = await it.__anext__() - except CrossSync.StopIteration: - # stream complete + try: + if chunks is None: + self._operation_metric.end_with_success() return - row_key = c.row_key - - if not row_key: - raise InvalidChunk("first row chunk is missing key") - - cells = [] - - # shared per cell storage - family: str | None = None - qualifier: bytes | None = None - - try: - # for each cell - while True: - if c.reset_row: - raise _ResetRow(c) - k = c.row_key - f = c.family_name.value - q = c.qualifier.value if c.HasField("qualifier") else None - if k and k != row_key: - raise InvalidChunk("unexpected new row key") - if f: - family = f - if q is not None: - qualifier = q - else: - raise InvalidChunk("new family without qualifier") - elif family is None: - raise InvalidChunk("missing family") - elif q is not None: - if family is None: - raise InvalidChunk("new qualifier without family") - qualifier = q - elif qualifier is None: - raise InvalidChunk("missing qualifier") - - ts = c.timestamp_micros - labels = c.labels if c.labels else [] - value = c.value - - # merge split cells - if c.value_size > 0: - buffer = [value] - while c.value_size > 0: - # throws when premature end - c = await it.__anext__() - - t = c.timestamp_micros - cl = c.labels - k = c.row_key - if ( - c.HasField("family_name") - and c.family_name.value != family - ): - raise InvalidChunk("family changed mid cell") - if ( - c.HasField("qualifier") - and c.qualifier.value != qualifier - ): - raise InvalidChunk("qualifier changed mid cell") - if t and t != ts: - raise InvalidChunk("timestamp changed mid cell") - if cl and cl != labels: - raise InvalidChunk("labels changed mid cell") - if k and k != row_key: - raise InvalidChunk("row key changed mid cell") - - if c.reset_row: - raise _ResetRow(c) - buffer.append(c.value) - value = b"".join(buffer) - cells.append( - Cell(value, row_key, family, qualifier, ts, list(labels)) - ) - if c.commit_row: - yield Row(row_key, cells) - break + it = chunks.__aiter__() + # For each row + while True: + try: c = await it.__anext__() - except _ResetRow as e: - c = e.chunk - if ( - c.row_key - or c.HasField("family_name") - or c.HasField("qualifier") - or c.timestamp_micros - or c.labels - or c.value - ): - raise InvalidChunk("reset row with data") - continue - except CrossSync.StopIteration: - raise InvalidChunk("premature end of stream") + except CrossSync.StopIteration: + # stream complete + self._operation_metric.end_with_success() + return + row_key = c.row_key + + if not row_key: + raise InvalidChunk("first row chunk is missing key") + + cells = [] + + # shared per cell storage + family: str | None = None + qualifier: bytes | None = None + + try: + # for each cell + while True: + if c.reset_row: + raise _ResetRow(c) + k = c.row_key + f = c.family_name.value + q = c.qualifier.value if c.HasField("qualifier") else None + if k and k != row_key: + raise InvalidChunk("unexpected new row key") + if f: + family = f + if q is not None: + qualifier = q + else: + raise InvalidChunk("new family without qualifier") + elif family is None: + raise InvalidChunk("missing family") + elif q is not None: + if family is None: + raise InvalidChunk("new qualifier without family") + qualifier = q + elif qualifier is None: + raise InvalidChunk("missing qualifier") + + ts = c.timestamp_micros + labels = c.labels if c.labels else [] + value = c.value + + # merge split cells + if c.value_size > 0: + buffer = [value] + while c.value_size > 0: + # throws when premature end + c = await it.__anext__() + + t = c.timestamp_micros + cl = c.labels + k = c.row_key + if ( + c.HasField("family_name") + and c.family_name.value != family + ): + raise InvalidChunk("family changed mid cell") + if ( + c.HasField("qualifier") + and c.qualifier.value != qualifier + ): + raise InvalidChunk("qualifier changed mid cell") + if t and t != ts: + raise InvalidChunk("timestamp changed mid cell") + if cl and cl != labels: + raise InvalidChunk("labels changed mid cell") + if k and k != row_key: + raise InvalidChunk("row key changed mid cell") + + if c.reset_row: + raise _ResetRow(c) + buffer.append(c.value) + value = b"".join(buffer) + cells.append( + Cell(value, row_key, family, qualifier, ts, list(labels)) + ) + if c.commit_row: + block_time = time.monotonic_ns() + yield Row(row_key, cells) + # most metric operations use setters, but this one updates + # the value directly to avoid extra overhead + if self._operation_metric.active_attempt is not None: + self._operation_metric.active_attempt.application_blocking_time_ns += ( # type: ignore + time.monotonic_ns() - block_time + ) + break + c = await it.__anext__() + except _ResetRow as e: + c = e.chunk + if ( + c.row_key + or c.HasField("family_name") + or c.HasField("qualifier") + or c.timestamp_micros + or c.labels + or c.value + ): + raise InvalidChunk("reset row with data") + continue + except CrossSync.StopIteration: + raise InvalidChunk("premature end of stream") + except GeneratorExit as close_exception: + # handle aclose() + self._operation_metric.end_with_status(StatusCode.CANCELLED) + raise close_exception + except Exception as generic_exception: + # handle exceptions in retry wrapper + raise generic_exception @staticmethod def _revise_request_rowset( diff --git a/packages/google-cloud-bigtable/google/cloud/bigtable/data/_async/client.py b/packages/google-cloud-bigtable/google/cloud/bigtable/data/_async/client.py index 5d0a23e54364..1a404d0b55b8 100644 --- a/packages/google-cloud-bigtable/google/cloud/bigtable/data/_async/client.py +++ b/packages/google-cloud-bigtable/google/cloud/bigtable/data/_async/client.py @@ -1132,6 +1132,9 @@ async def read_rows_stream( self, operation_timeout=operation_timeout, attempt_timeout=attempt_timeout, + metric=self._metrics.create_operation( + OperationType.READ_ROWS, is_streaming=True + ), retryable_exceptions=retryable_excs, ) return row_merger.start_operation() @@ -1224,15 +1227,28 @@ async def read_row( if row_key is None: raise ValueError("row_key must be string or bytes") query = ReadRowsQuery(row_keys=row_key, row_filter=row_filter, limit=1) - results = await self.read_rows( + + operation_timeout, attempt_timeout = _get_timeouts( + operation_timeout, attempt_timeout, self + ) + retryable_excs = _get_retryable_errors(retryable_errors, self) + + row_merger = CrossSync._ReadRowsOperation( query, + self, operation_timeout=operation_timeout, attempt_timeout=attempt_timeout, - retryable_errors=retryable_errors, + metric=self._metrics.create_operation( + OperationType.READ_ROWS, is_streaming=False + ), + retryable_exceptions=retryable_excs, ) - if len(results) == 0: + results_generator = row_merger.start_operation() + try: + results = [a async for a in results_generator] + return results[0] + except IndexError: return None - return results[0] @CrossSync.convert async def read_rows_sharded( @@ -1374,20 +1390,17 @@ async def row_exists( from any retries that failed google.api_core.exceptions.GoogleAPIError: raised if the request encounters an unrecoverable error """ - if row_key is None: - raise ValueError("row_key must be string or bytes") - strip_filter = StripValueTransformerFilter(flag=True) limit_filter = CellsRowLimitFilter(1) chain_filter = RowFilterChain(filters=[limit_filter, strip_filter]) - query = ReadRowsQuery(row_keys=row_key, limit=1, row_filter=chain_filter) - results = await self.read_rows( - query, + result = await self.read_row( + row_key=row_key, + row_filter=chain_filter, operation_timeout=operation_timeout, attempt_timeout=attempt_timeout, retryable_errors=retryable_errors, ) - return len(results) > 0 + return result is not None @CrossSync.convert async def sample_row_keys( @@ -1647,6 +1660,7 @@ async def bulk_mutate_rows( mutation_entries, operation_timeout, attempt_timeout, + metric=self._metrics.create_operation(OperationType.BULK_MUTATE_ROWS), retryable_exceptions=retryable_excs, ) await operation.start() diff --git a/packages/google-cloud-bigtable/google/cloud/bigtable/data/_async/mutations_batcher.py b/packages/google-cloud-bigtable/google/cloud/bigtable/data/_async/mutations_batcher.py index 405983393ee7..13e45721245a 100644 --- a/packages/google-cloud-bigtable/google/cloud/bigtable/data/_async/mutations_batcher.py +++ b/packages/google-cloud-bigtable/google/cloud/bigtable/data/_async/mutations_batcher.py @@ -16,6 +16,7 @@ import atexit import concurrent.futures +import time import warnings from collections import deque from typing import TYPE_CHECKING, Sequence, cast @@ -26,6 +27,7 @@ _get_retryable_errors, _get_timeouts, ) +from google.cloud.bigtable.data._metrics import ActiveOperationMetric, OperationType from google.cloud.bigtable.data.exceptions import ( FailedMutationEntryError, MutationsExceptionGroup, @@ -36,6 +38,7 @@ ) if TYPE_CHECKING: + from google.cloud.bigtable.data._metrics import BigtableClientSideMetricsController from google.cloud.bigtable.data.mutations import RowMutationEntry if CrossSync.is_async: @@ -181,6 +184,24 @@ async def add_to_flow(self, mutations: RowMutationEntry | list[RowMutationEntry] ) yield mutations[start_idx:end_idx] + @CrossSync.convert(replace_symbols={"__anext__": "__next__"}) + async def add_to_flow_with_metrics( + self, + mutations: RowMutationEntry | list[RowMutationEntry], + metrics_controller: BigtableClientSideMetricsController, + ): + inner_generator = self.add_to_flow(mutations) + while True: + # start a new metric + metric = metrics_controller.create_operation(OperationType.BULK_MUTATE_ROWS) + flow_start_time = time.monotonic_ns() + try: + value = await inner_generator.__anext__() + except CrossSync.StopIteration: + return + metric.flow_throttling_time_ns = time.monotonic_ns() - flow_start_time + yield value, metric + @CrossSync.convert_class(sync_name="MutationsBatcher") class MutationsBatcherAsync: @@ -357,9 +378,14 @@ async def _flush_internal(self, new_entries: list[RowMutationEntry]): """ # flush new entries in_process_requests: list[CrossSync.Future[list[FailedMutationEntryError]]] = [] - async for batch in self._flow_control.add_to_flow(new_entries): + async for batch, metric in self._flow_control.add_to_flow_with_metrics( + new_entries, self._target._metrics + ): batch_task = CrossSync.create_task( - self._execute_mutate_rows, batch, sync_executor=self._sync_rpc_executor + self._execute_mutate_rows, + batch, + metric, + sync_executor=self._sync_rpc_executor, ) in_process_requests.append(batch_task) # wait for all inflight requests to complete @@ -370,7 +396,7 @@ async def _flush_internal(self, new_entries: list[RowMutationEntry]): @CrossSync.convert async def _execute_mutate_rows( - self, batch: list[RowMutationEntry] + self, batch: list[RowMutationEntry], metric: ActiveOperationMetric ) -> list[FailedMutationEntryError]: """ Helper to execute mutation operation on a batch @@ -391,6 +417,7 @@ async def _execute_mutate_rows( batch, operation_timeout=self._operation_timeout, attempt_timeout=self._attempt_timeout, + metric=metric, retryable_exceptions=self._retryable_errors, ) await operation.start() diff --git a/packages/google-cloud-bigtable/google/cloud/bigtable/data/_sync_autogen/_mutate_rows.py b/packages/google-cloud-bigtable/google/cloud/bigtable/data/_sync_autogen/_mutate_rows.py index c1c508a526f2..40e19dd85847 100644 --- a/packages/google-cloud-bigtable/google/cloud/bigtable/data/_sync_autogen/_mutate_rows.py +++ b/packages/google-cloud-bigtable/google/cloud/bigtable/data/_sync_autogen/_mutate_rows.py @@ -25,16 +25,15 @@ import google.cloud.bigtable.data.exceptions as bt_exceptions import google.cloud.bigtable_v2.types.bigtable as types_pb from google.cloud.bigtable.data._cross_sync import CrossSync -from google.cloud.bigtable.data._helpers import ( - _attempt_timeout_generator, - _retry_exception_factory, -) +from google.cloud.bigtable.data._helpers import _attempt_timeout_generator +from google.cloud.bigtable.data._metrics import tracked_retry from google.cloud.bigtable.data.mutations import ( _MUTATE_ROWS_REQUEST_MUTATION_LIMIT, _EntryWithProto, ) if TYPE_CHECKING: + from google.cloud.bigtable.data._metrics import ActiveOperationMetric from google.cloud.bigtable.data._sync_autogen.client import ( _DataApiTarget as TargetType, ) @@ -61,6 +60,8 @@ class _MutateRowsOperation: operation_timeout: the timeout to use for the entire operation, in seconds. attempt_timeout: the timeout to use for each mutate_rows attempt, in seconds. If not specified, the request will run until operation_timeout is reached. + metric: the metric object representing the active operation + retryable_exceptions: a list of exceptions that should be retried """ def __init__( @@ -70,6 +71,7 @@ def __init__( mutation_entries: list["RowMutationEntry"], operation_timeout: float, attempt_timeout: float | None, + metric: ActiveOperationMetric, retryable_exceptions: Sequence[type[Exception]] = (), ): total_mutations = sum((len(entry.mutations) for entry in mutation_entries)) @@ -82,13 +84,12 @@ def __init__( self.is_retryable = retries.if_exception_type( *retryable_exceptions, bt_exceptions._MutateRowsIncomplete ) - sleep_generator = retries.exponential_sleep_generator(0.01, 2, 60) - self._operation = lambda: CrossSync._Sync_Impl.retry_target( - self._run_attempt, - self.is_retryable, - sleep_generator, - operation_timeout, - exception_factory=_retry_exception_factory, + self._operation = lambda: tracked_retry( + retry_fn=CrossSync._Sync_Impl.retry_target, + operation=metric, + target=self._run_attempt, + predicate=self.is_retryable, + timeout=operation_timeout, ) self.timeout_generator = _attempt_timeout_generator( attempt_timeout, operation_timeout @@ -96,37 +97,39 @@ def __init__( self.mutations = [_EntryWithProto(m, m._to_pb()) for m in mutation_entries] self.remaining_indices = list(range(len(self.mutations))) self.errors: dict[int, list[Exception]] = {} + self._operation_metric = metric def start(self): """Start the operation, and run until completion Raises: MutationsExceptionGroup: if any mutations failed""" - try: - self._operation() - except Exception as exc: - incomplete_indices = self.remaining_indices.copy() - for idx in incomplete_indices: - self._handle_entry_error(idx, exc) - finally: - all_errors: list[Exception] = [] - for idx, exc_list in self.errors.items(): - if len(exc_list) == 0: - raise core_exceptions.ClientError( - f"Mutation {idx} failed with no associated errors" + with self._operation_metric: + try: + self._operation() + except Exception as exc: + incomplete_indices = self.remaining_indices.copy() + for idx in incomplete_indices: + self._handle_entry_error(idx, exc) + finally: + all_errors: list[Exception] = [] + for idx, exc_list in self.errors.items(): + if len(exc_list) == 0: + raise core_exceptions.ClientError( + f"Mutation {idx} failed with no associated errors" + ) + elif len(exc_list) == 1: + cause_exc = exc_list[0] + else: + cause_exc = bt_exceptions.RetryExceptionGroup(exc_list) + entry = self.mutations[idx].entry + all_errors.append( + bt_exceptions.FailedMutationEntryError(idx, entry, cause_exc) + ) + if all_errors: + raise bt_exceptions.MutationsExceptionGroup( + all_errors, len(self.mutations) ) - elif len(exc_list) == 1: - cause_exc = exc_list[0] - else: - cause_exc = bt_exceptions.RetryExceptionGroup(exc_list) - entry = self.mutations[idx].entry - all_errors.append( - bt_exceptions.FailedMutationEntryError(idx, entry, cause_exc) - ) - if all_errors: - raise bt_exceptions.MutationsExceptionGroup( - all_errors, len(self.mutations) - ) def _run_attempt(self): """Run a single attempt of the mutate_rows rpc. @@ -135,6 +138,7 @@ def _run_attempt(self): _MutateRowsIncomplete: if there are failed mutations eligible for retry after the attempt is complete GoogleAPICallError: if the gapic rpc fails""" + self._operation_metric.start_attempt() request_entries = [self.mutations[idx].proto for idx in self.remaining_indices] active_request_indices = { req_idx: orig_idx for req_idx, orig_idx in enumerate(self.remaining_indices) diff --git a/packages/google-cloud-bigtable/google/cloud/bigtable/data/_sync_autogen/_read_rows.py b/packages/google-cloud-bigtable/google/cloud/bigtable/data/_sync_autogen/_read_rows.py index a74374988161..b9c2a4bf8cb6 100644 --- a/packages/google-cloud-bigtable/google/cloud/bigtable/data/_sync_autogen/_read_rows.py +++ b/packages/google-cloud-bigtable/google/cloud/bigtable/data/_sync_autogen/_read_rows.py @@ -18,16 +18,15 @@ from __future__ import annotations +import time from typing import TYPE_CHECKING, Sequence from google.api_core import retry as retries -from google.api_core.retry import exponential_sleep_generator +from grpc import StatusCode from google.cloud.bigtable.data._cross_sync import CrossSync -from google.cloud.bigtable.data._helpers import ( - _attempt_timeout_generator, - _retry_exception_factory, -) +from google.cloud.bigtable.data._helpers import _attempt_timeout_generator +from google.cloud.bigtable.data._metrics import tracked_retry from google.cloud.bigtable.data.exceptions import ( InvalidChunk, _ResetRow, @@ -41,6 +40,7 @@ from google.cloud.bigtable_v2.types import RowSet as RowSetPB if TYPE_CHECKING: + from google.cloud.bigtable.data._metrics import ActiveOperationMetric from google.cloud.bigtable.data._sync_autogen.client import ( _DataApiTarget as TargetType, ) @@ -63,6 +63,7 @@ class _ReadRowsOperation: target: The table or view to send the request to operation_timeout: The total time to allow for the operation, in seconds attempt_timeout: The time to allow for each individual attempt, in seconds + metric: the metric object representing the active operation retryable_exceptions: A list of exceptions that should trigger a retry """ @@ -74,6 +75,7 @@ class _ReadRowsOperation: "_predicate", "_last_yielded_row_key", "_remaining_count", + "_operation_metric", ) def __init__( @@ -82,6 +84,7 @@ def __init__( target: TargetType, operation_timeout: float, attempt_timeout: float, + metric: ActiveOperationMetric, retryable_exceptions: Sequence[type[Exception]] = (), ): self.attempt_timeout_gen = _attempt_timeout_generator( @@ -98,18 +101,19 @@ def __init__( self._predicate = retries.if_exception_type(*retryable_exceptions) self._last_yielded_row_key: bytes | None = None self._remaining_count: int | None = self.request.rows_limit or None + self._operation_metric = metric def start_operation(self) -> CrossSync._Sync_Impl.Iterable[Row]: """Start the read_rows operation, retrying on retryable errors. Yields: Row: The next row in the stream""" - return CrossSync._Sync_Impl.retry_target_stream( - self._read_rows_attempt, - self._predicate, - exponential_sleep_generator(0.01, 60, multiplier=2), - self.operation_timeout, - exception_factory=_retry_exception_factory, + return tracked_retry( + retry_fn=CrossSync._Sync_Impl.retry_target_stream, + operation=self._operation_metric, + target=self._read_rows_attempt, + predicate=self._predicate, + timeout=self.operation_timeout, ) def _read_rows_attempt(self) -> CrossSync._Sync_Impl.Iterable[Row]: @@ -120,6 +124,7 @@ def _read_rows_attempt(self) -> CrossSync._Sync_Impl.Iterable[Row]: Yields: Row: The next row in the stream""" + self._operation_metric.start_attempt() if self._last_yielded_row_key is not None: try: self.request.rows = self._revise_request_rowset( @@ -181,9 +186,8 @@ def chunk_stream( raise InvalidChunk("emit count exceeds row limit") current_key = None - @staticmethod def merge_rows( - chunks: CrossSync._Sync_Impl.Iterable[ReadRowsResponsePB.CellChunk] | None, + self, chunks: CrossSync._Sync_Impl.Iterable[ReadRowsResponsePB.CellChunk] | None ) -> CrossSync._Sync_Impl.Iterable[Row]: """Merge chunks into rows @@ -191,94 +195,107 @@ def merge_rows( chunks: the chunk stream to merge Yields: Row: the next row in the stream""" - if chunks is None: - return - it = chunks.__iter__() - while True: - try: - c = it.__next__() - except CrossSync._Sync_Impl.StopIteration: + try: + if chunks is None: + self._operation_metric.end_with_success() return - row_key = c.row_key - if not row_key: - raise InvalidChunk("first row chunk is missing key") - cells = [] - family: str | None = None - qualifier: bytes | None = None - try: - while True: - if c.reset_row: - raise _ResetRow(c) - k = c.row_key - f = c.family_name.value - q = c.qualifier.value if c.HasField("qualifier") else None - if k and k != row_key: - raise InvalidChunk("unexpected new row key") - if f: - family = f - if q is not None: - qualifier = q - else: - raise InvalidChunk("new family without qualifier") - elif family is None: - raise InvalidChunk("missing family") - elif q is not None: - if family is None: - raise InvalidChunk("new qualifier without family") - qualifier = q - elif qualifier is None: - raise InvalidChunk("missing qualifier") - ts = c.timestamp_micros - labels = c.labels if c.labels else [] - value = c.value - if c.value_size > 0: - buffer = [value] - while c.value_size > 0: - c = it.__next__() - t = c.timestamp_micros - cl = c.labels - k = c.row_key - if ( - c.HasField("family_name") - and c.family_name.value != family - ): - raise InvalidChunk("family changed mid cell") - if ( - c.HasField("qualifier") - and c.qualifier.value != qualifier - ): - raise InvalidChunk("qualifier changed mid cell") - if t and t != ts: - raise InvalidChunk("timestamp changed mid cell") - if cl and cl != labels: - raise InvalidChunk("labels changed mid cell") - if k and k != row_key: - raise InvalidChunk("row key changed mid cell") - if c.reset_row: - raise _ResetRow(c) - buffer.append(c.value) - value = b"".join(buffer) - cells.append( - Cell(value, row_key, family, qualifier, ts, list(labels)) - ) - if c.commit_row: - yield Row(row_key, cells) - break + it = chunks.__iter__() + while True: + try: c = it.__next__() - except _ResetRow as e: - c = e.chunk - if ( - c.row_key - or c.HasField("family_name") - or c.HasField("qualifier") - or c.timestamp_micros - or c.labels - or c.value - ): - raise InvalidChunk("reset row with data") - continue - except CrossSync._Sync_Impl.StopIteration: - raise InvalidChunk("premature end of stream") + except CrossSync._Sync_Impl.StopIteration: + self._operation_metric.end_with_success() + return + row_key = c.row_key + if not row_key: + raise InvalidChunk("first row chunk is missing key") + cells = [] + family: str | None = None + qualifier: bytes | None = None + try: + while True: + if c.reset_row: + raise _ResetRow(c) + k = c.row_key + f = c.family_name.value + q = c.qualifier.value if c.HasField("qualifier") else None + if k and k != row_key: + raise InvalidChunk("unexpected new row key") + if f: + family = f + if q is not None: + qualifier = q + else: + raise InvalidChunk("new family without qualifier") + elif family is None: + raise InvalidChunk("missing family") + elif q is not None: + if family is None: + raise InvalidChunk("new qualifier without family") + qualifier = q + elif qualifier is None: + raise InvalidChunk("missing qualifier") + ts = c.timestamp_micros + labels = c.labels if c.labels else [] + value = c.value + if c.value_size > 0: + buffer = [value] + while c.value_size > 0: + c = it.__next__() + t = c.timestamp_micros + cl = c.labels + k = c.row_key + if ( + c.HasField("family_name") + and c.family_name.value != family + ): + raise InvalidChunk("family changed mid cell") + if ( + c.HasField("qualifier") + and c.qualifier.value != qualifier + ): + raise InvalidChunk("qualifier changed mid cell") + if t and t != ts: + raise InvalidChunk("timestamp changed mid cell") + if cl and cl != labels: + raise InvalidChunk("labels changed mid cell") + if k and k != row_key: + raise InvalidChunk("row key changed mid cell") + if c.reset_row: + raise _ResetRow(c) + buffer.append(c.value) + value = b"".join(buffer) + cells.append( + Cell(value, row_key, family, qualifier, ts, list(labels)) + ) + if c.commit_row: + block_time = time.monotonic_ns() + yield Row(row_key, cells) + if self._operation_metric.active_attempt is not None: + self._operation_metric.active_attempt.application_blocking_time_ns += ( + time.monotonic_ns() - block_time + ) + break + c = it.__next__() + except _ResetRow as e: + c = e.chunk + if ( + c.row_key + or c.HasField("family_name") + or c.HasField("qualifier") + or c.timestamp_micros + or c.labels + or c.value + ): + raise InvalidChunk("reset row with data") + continue + except CrossSync._Sync_Impl.StopIteration: + raise InvalidChunk("premature end of stream") + except GeneratorExit as close_exception: + self._operation_metric.end_with_status(StatusCode.CANCELLED) + raise close_exception + except Exception as generic_exception: + raise generic_exception @staticmethod def _revise_request_rowset(row_set: RowSetPB, last_seen_row_key: bytes) -> RowSetPB: diff --git a/packages/google-cloud-bigtable/google/cloud/bigtable/data/_sync_autogen/client.py b/packages/google-cloud-bigtable/google/cloud/bigtable/data/_sync_autogen/client.py index 6d808fe9719f..854a596254b1 100644 --- a/packages/google-cloud-bigtable/google/cloud/bigtable/data/_sync_autogen/client.py +++ b/packages/google-cloud-bigtable/google/cloud/bigtable/data/_sync_autogen/client.py @@ -907,6 +907,9 @@ def read_rows_stream( self, operation_timeout=operation_timeout, attempt_timeout=attempt_timeout, + metric=self._metrics.create_operation( + OperationType.READ_ROWS, is_streaming=True + ), retryable_exceptions=retryable_excs, ) return row_merger.start_operation() @@ -993,15 +996,26 @@ def read_row( if row_key is None: raise ValueError("row_key must be string or bytes") query = ReadRowsQuery(row_keys=row_key, row_filter=row_filter, limit=1) - results = self.read_rows( + operation_timeout, attempt_timeout = _get_timeouts( + operation_timeout, attempt_timeout, self + ) + retryable_excs = _get_retryable_errors(retryable_errors, self) + row_merger = CrossSync._Sync_Impl._ReadRowsOperation( query, + self, operation_timeout=operation_timeout, attempt_timeout=attempt_timeout, - retryable_errors=retryable_errors, + metric=self._metrics.create_operation( + OperationType.READ_ROWS, is_streaming=False + ), + retryable_exceptions=retryable_excs, ) - if len(results) == 0: + results_generator = row_merger.start_operation() + try: + results = [a for a in results_generator] + return results[0] + except IndexError: return None - return results[0] def read_rows_sharded( self, @@ -1125,19 +1139,17 @@ def row_exists( will be chained with a RetryExceptionGroup containing GoogleAPIError exceptions from any retries that failed google.api_core.exceptions.GoogleAPIError: raised if the request encounters an unrecoverable error""" - if row_key is None: - raise ValueError("row_key must be string or bytes") strip_filter = StripValueTransformerFilter(flag=True) limit_filter = CellsRowLimitFilter(1) chain_filter = RowFilterChain(filters=[limit_filter, strip_filter]) - query = ReadRowsQuery(row_keys=row_key, limit=1, row_filter=chain_filter) - results = self.read_rows( - query, + result = self.read_row( + row_key=row_key, + row_filter=chain_filter, operation_timeout=operation_timeout, attempt_timeout=attempt_timeout, retryable_errors=retryable_errors, ) - return len(results) > 0 + return result is not None def sample_row_keys( self, @@ -1375,6 +1387,7 @@ def bulk_mutate_rows( mutation_entries, operation_timeout, attempt_timeout, + metric=self._metrics.create_operation(OperationType.BULK_MUTATE_ROWS), retryable_exceptions=retryable_excs, ) operation.start() diff --git a/packages/google-cloud-bigtable/google/cloud/bigtable/data/_sync_autogen/mutations_batcher.py b/packages/google-cloud-bigtable/google/cloud/bigtable/data/_sync_autogen/mutations_batcher.py index 5be449a49d4a..107c2cbf591b 100644 --- a/packages/google-cloud-bigtable/google/cloud/bigtable/data/_sync_autogen/mutations_batcher.py +++ b/packages/google-cloud-bigtable/google/cloud/bigtable/data/_sync_autogen/mutations_batcher.py @@ -19,6 +19,7 @@ import atexit import concurrent.futures +import time import warnings from collections import deque from typing import TYPE_CHECKING, Sequence, cast @@ -29,6 +30,7 @@ _get_retryable_errors, _get_timeouts, ) +from google.cloud.bigtable.data._metrics import ActiveOperationMetric, OperationType from google.cloud.bigtable.data.exceptions import ( FailedMutationEntryError, MutationsExceptionGroup, @@ -39,6 +41,7 @@ ) if TYPE_CHECKING: + from google.cloud.bigtable.data._metrics import BigtableClientSideMetricsController from google.cloud.bigtable.data._sync_autogen.client import ( _DataApiTarget as TargetType, ) @@ -154,6 +157,22 @@ def add_to_flow(self, mutations: RowMutationEntry | list[RowMutationEntry]): ) yield mutations[start_idx:end_idx] + def add_to_flow_with_metrics( + self, + mutations: RowMutationEntry | list[RowMutationEntry], + metrics_controller: BigtableClientSideMetricsController, + ): + inner_generator = self.add_to_flow(mutations) + while True: + metric = metrics_controller.create_operation(OperationType.BULK_MUTATE_ROWS) + flow_start_time = time.monotonic_ns() + try: + value = inner_generator.__next__() + except CrossSync._Sync_Impl.StopIteration: + return + metric.flow_throttling_time_ns = time.monotonic_ns() - flow_start_time + yield (value, metric) + class MutationsBatcher: """ @@ -309,9 +328,14 @@ def _flush_internal(self, new_entries: list[RowMutationEntry]): in_process_requests: list[ CrossSync._Sync_Impl.Future[list[FailedMutationEntryError]] ] = [] - for batch in self._flow_control.add_to_flow(new_entries): + for batch, metric in self._flow_control.add_to_flow_with_metrics( + new_entries, self._target._metrics + ): batch_task = CrossSync._Sync_Impl.create_task( - self._execute_mutate_rows, batch, sync_executor=self._sync_rpc_executor + self._execute_mutate_rows, + batch, + metric, + sync_executor=self._sync_rpc_executor, ) in_process_requests.append(batch_task) found_exceptions = self._wait_for_batch_results(*in_process_requests) @@ -319,7 +343,7 @@ def _flush_internal(self, new_entries: list[RowMutationEntry]): self._add_exceptions(found_exceptions) def _execute_mutate_rows( - self, batch: list[RowMutationEntry] + self, batch: list[RowMutationEntry], metric: ActiveOperationMetric ) -> list[FailedMutationEntryError]: """Helper to execute mutation operation on a batch @@ -338,6 +362,7 @@ def _execute_mutate_rows( batch, operation_timeout=self._operation_timeout, attempt_timeout=self._attempt_timeout, + metric=metric, retryable_exceptions=self._retryable_errors, ) operation.start() diff --git a/packages/google-cloud-bigtable/tests/system/data/test_metrics_async.py b/packages/google-cloud-bigtable/tests/system/data/test_metrics_async.py index 48678160e867..b4e5b0f3819e 100644 --- a/packages/google-cloud-bigtable/tests/system/data/test_metrics_async.py +++ b/packages/google-cloud-bigtable/tests/system/data/test_metrics_async.py @@ -26,6 +26,7 @@ CompletedOperationMetric, ) from google.cloud.bigtable.data._metrics.handlers._base import MetricsHandler +from google.cloud.bigtable.data.read_rows_query import ReadRowsQuery from google.cloud.bigtable_v2.types import ResponseParams from . import TEST_FAMILY, SystemTestRunner @@ -135,6 +136,10 @@ def __getattr__(self, name): @CrossSync.convert_class(sync_name="TestMetrics") +@pytest.mark.skipif( + bool(os.environ.get(BIGTABLE_EMULATOR)), + reason="Emulator does not support metrics", +) class TestMetricsAsync(SystemTestRunner): def _make_client(self): project = os.getenv("GOOGLE_CLOUD_PROJECT") or None @@ -225,6 +230,1220 @@ async def authorized_view( table._metrics.add_handler(handler) yield table + @CrossSync.pytest + async def test_read_rows(self, table, temp_rows, handler, cluster_config): + await temp_rows.add_row(b"row_key_1") + await temp_rows.add_row(b"row_key_2") + handler.clear() + row_list = await table.read_rows(ReadRowsQuery()) + assert len(row_list) == 2 + # validate counts + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + # validate operation + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.value[0] == 0 + assert operation.is_streaming is True + assert operation.op_type.value == "ReadRows" + assert len(operation.completed_attempts) == 1 + assert operation.completed_attempts[0] == handler.completed_attempts[0] + assert operation.cluster_id == next(iter(cluster_config.keys())) + assert ( + operation.zone + == cluster_config[operation.cluster_id].location.split("/")[-1] + ) + assert operation.duration_ns > 0 and operation.duration_ns < 1e9 + assert ( + operation.first_response_latency_ns is not None + and operation.first_response_latency_ns < operation.duration_ns + ) + assert operation.flow_throttling_time_ns == 0 + # validate attempt + attempt = handler.completed_attempts[0] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.duration_ns > 0 and attempt.duration_ns < operation.duration_ns + assert attempt.end_status.value[0] == 0 + assert attempt.backoff_before_attempt_ns == 0 + assert ( + attempt.gfe_latency_ns > 0 and attempt.gfe_latency_ns < attempt.duration_ns + ) + assert ( + attempt.application_blocking_time_ns > 0 + and attempt.application_blocking_time_ns < operation.duration_ns + ) + + @CrossSync.pytest + async def test_read_rows_failure_with_retries( + self, table, temp_rows, handler, error_injector + ): + """ + Test failure in grpc layer by injecting errors into an interceptor + with retryable errors, then a terminal one + """ + await temp_rows.add_row(b"row_key_1") + handler.clear() + expected_zone = "my_zone" + expected_cluster = "my_cluster" + num_retryable = 2 + for i in range(num_retryable): + error_injector.push( + self._make_exception(StatusCode.ABORTED, cluster_id=expected_cluster) + ) + error_injector.push( + self._make_exception(StatusCode.PERMISSION_DENIED, zone_id=expected_zone) + ) + with pytest.raises(PermissionDenied): + await table.read_rows(ReadRowsQuery(), retryable_errors=[Aborted]) + # validate counts + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == num_retryable + 1 + # validate operation + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.name == "PERMISSION_DENIED" + assert operation.op_type.value == "ReadRows" + assert operation.is_streaming is True + assert len(operation.completed_attempts) == num_retryable + 1 + assert operation.cluster_id == expected_cluster + assert operation.zone == expected_zone + # validate attempts + for i in range(num_retryable): + attempt = handler.completed_attempts[i] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.end_status.name == "ABORTED" + assert attempt.gfe_latency_ns is None + final_attempt = handler.completed_attempts[num_retryable] + assert isinstance(final_attempt, CompletedAttemptMetric) + assert final_attempt.end_status.name == "PERMISSION_DENIED" + assert final_attempt.gfe_latency_ns is None + + @CrossSync.pytest + async def test_read_rows_failure_timeout(self, table, temp_rows, handler): + """ + Test failure in gapic layer by passing very low timeout + + No grpc headers expected + """ + await temp_rows.add_row(b"row_key_1") + handler.clear() + with pytest.raises(GoogleAPICallError): + await table.read_rows(ReadRowsQuery(), operation_timeout=0.001) + # validate counts + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + # validate operation + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.name == "DEADLINE_EXCEEDED" + assert operation.op_type.value == "ReadRows" + assert operation.is_streaming is True + assert len(operation.completed_attempts) == 1 + assert operation.cluster_id == "" + assert operation.zone == "global" + # validate attempt + attempt = handler.completed_attempts[0] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.end_status.name == "DEADLINE_EXCEEDED" + assert attempt.gfe_latency_ns is None + + @CrossSync.pytest + async def test_read_rows_failure_unauthorized( + self, handler, authorized_view, cluster_config + ): + """ + Test failure in backend by accessing an unauthorized family + """ + from google.cloud.bigtable.data.row_filters import FamilyNameRegexFilter + + with pytest.raises(GoogleAPICallError) as e: + await authorized_view.read_rows( + ReadRowsQuery(row_filter=FamilyNameRegexFilter("unauthorized")) + ) + assert e.value.grpc_status_code.name == "PERMISSION_DENIED" + # validate counts + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + # validate operation + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.name == "PERMISSION_DENIED" + assert operation.op_type.value == "ReadRows" + assert operation.is_streaming is True + assert len(operation.completed_attempts) == 1 + assert operation.cluster_id == next(iter(cluster_config.keys())) + assert ( + operation.zone + == cluster_config[operation.cluster_id].location.split("/")[-1] + ) + # validate attempt + attempt = handler.completed_attempts[0] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.end_status.name == "PERMISSION_DENIED" + assert ( + attempt.gfe_latency_ns >= 0 + and attempt.gfe_latency_ns < operation.duration_ns + ) + + @CrossSync.pytest + async def test_read_rows_stream(self, table, temp_rows, handler, cluster_config): + await temp_rows.add_row(b"row_key_1") + await temp_rows.add_row(b"row_key_2") + handler.clear() + # full table scan + generator = await table.read_rows_stream(ReadRowsQuery()) + row_list = [r async for r in generator] + assert len(row_list) == 2 + # validate counts + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + # validate operation + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.value[0] == 0 + assert operation.is_streaming is True + assert operation.op_type.value == "ReadRows" + assert len(operation.completed_attempts) == 1 + assert operation.completed_attempts[0] == handler.completed_attempts[0] + assert operation.cluster_id == next(iter(cluster_config.keys())) + assert ( + operation.zone + == cluster_config[operation.cluster_id].location.split("/")[-1] + ) + assert operation.duration_ns > 0 and operation.duration_ns < 1e9 + assert ( + operation.first_response_latency_ns is not None + and operation.first_response_latency_ns < operation.duration_ns + ) + assert operation.flow_throttling_time_ns == 0 + # validate attempt + attempt = handler.completed_attempts[0] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.duration_ns > 0 and attempt.duration_ns < operation.duration_ns + assert attempt.end_status.value[0] == 0 + assert attempt.backoff_before_attempt_ns == 0 + assert ( + attempt.gfe_latency_ns > 0 and attempt.gfe_latency_ns < attempt.duration_ns + ) + assert ( + attempt.application_blocking_time_ns > 0 + and attempt.application_blocking_time_ns < operation.duration_ns + ) + + @CrossSync.pytest + @CrossSync.convert(replace_symbols={"__anext__": "__next__", "aclose": "close"}) + async def test_read_rows_stream_failure_closed( + self, table, temp_rows, handler, error_injector + ): + """ + Test how metrics collection handles closed generator + """ + await temp_rows.add_row(b"row_key_1") + await temp_rows.add_row(b"row_key_2") + handler.clear() + generator = await table.read_rows_stream(ReadRowsQuery()) + await generator.__anext__() + await generator.aclose() + with pytest.raises(CrossSync.StopIteration): + await generator.__anext__() + # validate counts + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + # validate operation + operation = handler.completed_operations[0] + assert operation.final_status.name == "CANCELLED" + assert operation.op_type.value == "ReadRows" + assert operation.is_streaming is True + assert len(operation.completed_attempts) == 1 + assert operation.cluster_id == "" + assert operation.zone == "global" + # validate attempt + attempt = handler.completed_attempts[0] + assert attempt.end_status.name == "CANCELLED" + assert attempt.gfe_latency_ns is None + + @CrossSync.pytest + async def test_read_rows_stream_failure_with_retries( + self, table, temp_rows, handler, error_injector + ): + """ + Test failure in grpc layer by injecting errors into an interceptor + with retryable errors, then a terminal one + """ + await temp_rows.add_row(b"row_key_1") + handler.clear() + expected_zone = "my_zone" + expected_cluster = "my_cluster" + num_retryable = 2 + for i in range(num_retryable): + error_injector.push( + self._make_exception(StatusCode.ABORTED, cluster_id=expected_cluster) + ) + error_injector.push( + self._make_exception(StatusCode.PERMISSION_DENIED, zone_id=expected_zone) + ) + generator = await table.read_rows_stream( + ReadRowsQuery(), retryable_errors=[Aborted] + ) + with pytest.raises(PermissionDenied): + [_ async for _ in generator] + # validate counts + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == num_retryable + 1 + # validate operation + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.name == "PERMISSION_DENIED" + assert operation.op_type.value == "ReadRows" + assert operation.is_streaming is True + assert len(operation.completed_attempts) == num_retryable + 1 + assert operation.cluster_id == expected_cluster + assert operation.zone == expected_zone + # validate attempts + for i in range(num_retryable): + attempt = handler.completed_attempts[i] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.end_status.name == "ABORTED" + assert attempt.gfe_latency_ns is None + final_attempt = handler.completed_attempts[num_retryable] + assert isinstance(final_attempt, CompletedAttemptMetric) + assert final_attempt.end_status.name == "PERMISSION_DENIED" + assert final_attempt.gfe_latency_ns is None + + @CrossSync.pytest + async def test_read_rows_stream_failure_timeout(self, table, temp_rows, handler): + """ + Test failure in gapic layer by passing very low timeout + + No grpc headers expected + """ + await temp_rows.add_row(b"row_key_1") + handler.clear() + generator = await table.read_rows_stream( + ReadRowsQuery(), operation_timeout=0.001 + ) + with pytest.raises(GoogleAPICallError): + [_ async for _ in generator] + # validate counts + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + # validate operation + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.name == "DEADLINE_EXCEEDED" + assert operation.op_type.value == "ReadRows" + assert operation.is_streaming is True + assert len(operation.completed_attempts) == 1 + assert operation.cluster_id == "" + assert operation.zone == "global" + # validate attempt + attempt = handler.completed_attempts[0] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.end_status.name == "DEADLINE_EXCEEDED" + assert attempt.gfe_latency_ns is None + + @CrossSync.pytest + async def test_read_rows_stream_failure_unauthorized( + self, handler, authorized_view, cluster_config + ): + """ + Test failure in backend by accessing an unauthorized family + """ + from google.cloud.bigtable.data.row_filters import FamilyNameRegexFilter + + with pytest.raises(GoogleAPICallError) as e: + generator = await authorized_view.read_rows_stream( + ReadRowsQuery(row_filter=FamilyNameRegexFilter("unauthorized")) + ) + [_ async for _ in generator] + assert e.value.grpc_status_code.name == "PERMISSION_DENIED" + # validate counts + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + # validate operation + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.name == "PERMISSION_DENIED" + assert operation.op_type.value == "ReadRows" + assert operation.is_streaming is True + assert len(operation.completed_attempts) == 1 + assert operation.cluster_id == next(iter(cluster_config.keys())) + assert ( + operation.zone + == cluster_config[operation.cluster_id].location.split("/")[-1] + ) + # validate attempt + attempt = handler.completed_attempts[0] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.end_status.name == "PERMISSION_DENIED" + assert ( + attempt.gfe_latency_ns >= 0 + and attempt.gfe_latency_ns < operation.duration_ns + ) + + @CrossSync.pytest + async def test_read_rows_stream_failure_unauthorized_with_retries( + self, handler, authorized_view, cluster_config + ): + """ + retry unauthorized request multiple times before timing out + """ + from google.cloud.bigtable.data.row_filters import FamilyNameRegexFilter + + with pytest.raises(GoogleAPICallError) as e: + generator = await authorized_view.read_rows_stream( + ReadRowsQuery(row_filter=FamilyNameRegexFilter("unauthorized")), + retryable_errors=[PermissionDenied], + operation_timeout=0.5, + ) + [_ async for _ in generator] + assert e.value.grpc_status_code.name == "DEADLINE_EXCEEDED" + # validate counts + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) > 1 + # validate operation + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.name == "DEADLINE_EXCEEDED" + assert operation.op_type.value == "ReadRows" + assert operation.is_streaming is True + assert len(operation.completed_attempts) > 1 + assert operation.cluster_id == next(iter(cluster_config.keys())) + assert ( + operation.zone + == cluster_config[operation.cluster_id].location.split("/")[-1] + ) + # validate attempts + for attempt in handler.completed_attempts: + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.end_status.name in ["PERMISSION_DENIED", "DEADLINE_EXCEEDED"] + + @CrossSync.pytest + async def test_read_rows_stream_failure_mid_stream( + self, table, temp_rows, handler, error_injector + ): + """ + Test failure in grpc stream + """ + await temp_rows.add_row(b"row_key_1") + handler.clear() + error_injector.fail_mid_stream = True + error_injector.push(self._make_exception(StatusCode.ABORTED)) + error_injector.push(self._make_exception(StatusCode.PERMISSION_DENIED)) + generator = await table.read_rows_stream( + ReadRowsQuery(), retryable_errors=[Aborted] + ) + with pytest.raises(PermissionDenied): + [_ async for _ in generator] + # validate counts + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 2 + # validate operation + operation = handler.completed_operations[0] + assert operation.final_status.name == "PERMISSION_DENIED" + assert operation.op_type.value == "ReadRows" + assert operation.is_streaming is True + assert len(operation.completed_attempts) == 2 + # validate retried attempt + attempt = handler.completed_attempts[0] + assert attempt.end_status.name == "ABORTED" + # validate final attempt + final_attempt = handler.completed_attempts[-1] + assert final_attempt.end_status.name == "PERMISSION_DENIED" + + @CrossSync.pytest + async def test_read_row(self, table, temp_rows, handler, cluster_config): + await temp_rows.add_row(b"row_key_1") + handler.clear() + await table.read_row(b"row_key_1") + # validate counts + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + # validate operation + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.value[0] == 0 + assert operation.is_streaming is False + assert operation.op_type.value == "ReadRows" + assert len(operation.completed_attempts) == 1 + assert operation.completed_attempts[0] == handler.completed_attempts[0] + assert operation.cluster_id == next(iter(cluster_config.keys())) + assert ( + operation.zone + == cluster_config[operation.cluster_id].location.split("/")[-1] + ) + assert operation.duration_ns > 0 and operation.duration_ns < 1e9 + assert ( + operation.first_response_latency_ns > 0 + and operation.first_response_latency_ns < operation.duration_ns + ) + assert operation.flow_throttling_time_ns == 0 + # validate attempt + attempt = handler.completed_attempts[0] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.duration_ns > 0 and attempt.duration_ns < operation.duration_ns + assert attempt.end_status.value[0] == 0 + assert attempt.backoff_before_attempt_ns == 0 + assert ( + attempt.gfe_latency_ns > 0 and attempt.gfe_latency_ns < attempt.duration_ns + ) + assert ( + attempt.application_blocking_time_ns > 0 + and attempt.application_blocking_time_ns < operation.duration_ns + ) + + @CrossSync.pytest + async def test_read_row_failure_with_retries( + self, table, temp_rows, handler, error_injector + ): + """ + Test failure in grpc layer by injecting errors into an interceptor + with retryable errors, then a terminal one + """ + await temp_rows.add_row(b"row_key_1") + handler.clear() + expected_zone = "my_zone" + expected_cluster = "my_cluster" + num_retryable = 2 + for i in range(num_retryable): + error_injector.push( + self._make_exception(StatusCode.ABORTED, cluster_id=expected_cluster) + ) + error_injector.push( + self._make_exception(StatusCode.PERMISSION_DENIED, zone_id=expected_zone) + ) + with pytest.raises(PermissionDenied): + await table.read_row(b"row_key_1", retryable_errors=[Aborted]) + # validate counts + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == num_retryable + 1 + # validate operation + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.name == "PERMISSION_DENIED" + assert operation.op_type.value == "ReadRows" + assert operation.is_streaming is False + assert len(operation.completed_attempts) == num_retryable + 1 + assert operation.cluster_id == expected_cluster + assert operation.zone == expected_zone + # validate attempts + for i in range(num_retryable): + attempt = handler.completed_attempts[i] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.end_status.name == "ABORTED" + assert attempt.gfe_latency_ns is None + final_attempt = handler.completed_attempts[num_retryable] + assert isinstance(final_attempt, CompletedAttemptMetric) + assert final_attempt.end_status.name == "PERMISSION_DENIED" + assert final_attempt.gfe_latency_ns is None + + @CrossSync.pytest + async def test_read_row_failure_timeout(self, table, temp_rows, handler): + """ + Test failure in gapic layer by passing very low timeout + + No grpc headers expected + """ + await temp_rows.add_row(b"row_key_1") + handler.clear() + with pytest.raises(GoogleAPICallError): + await table.read_row(b"row_key_1", operation_timeout=0.001) + # validate counts + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + # validate operation + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.name == "DEADLINE_EXCEEDED" + assert operation.op_type.value == "ReadRows" + assert operation.is_streaming is False + assert len(operation.completed_attempts) == 1 + assert operation.cluster_id == "" + assert operation.zone == "global" + # validate attempt + attempt = handler.completed_attempts[0] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.end_status.name == "DEADLINE_EXCEEDED" + assert attempt.gfe_latency_ns is None + + @CrossSync.pytest + async def test_read_row_failure_unauthorized( + self, handler, authorized_view, cluster_config + ): + """ + Test failure in backend by accessing an unauthorized family + """ + from google.cloud.bigtable.data.row_filters import FamilyNameRegexFilter + + with pytest.raises(GoogleAPICallError) as e: + await authorized_view.read_row( + b"any_row", row_filter=FamilyNameRegexFilter("unauthorized") + ) + assert e.value.grpc_status_code.name == "PERMISSION_DENIED" + # validate counts + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + # validate operation + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.name == "PERMISSION_DENIED" + assert operation.op_type.value == "ReadRows" + assert operation.is_streaming is False + assert len(operation.completed_attempts) == 1 + assert operation.cluster_id == next(iter(cluster_config.keys())) + assert ( + operation.zone + == cluster_config[operation.cluster_id].location.split("/")[-1] + ) + # validate attempt + attempt = handler.completed_attempts[0] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.end_status.name == "PERMISSION_DENIED" + assert ( + attempt.gfe_latency_ns >= 0 + and attempt.gfe_latency_ns < operation.duration_ns + ) + + @CrossSync.pytest + async def test_read_rows_sharded(self, table, temp_rows, handler, cluster_config): + from google.cloud.bigtable.data.read_rows_query import ReadRowsQuery + + await temp_rows.add_row(b"a") + await temp_rows.add_row(b"b") + await temp_rows.add_row(b"c") + await temp_rows.add_row(b"d") + query1 = ReadRowsQuery(row_keys=[b"a", b"c"]) + query2 = ReadRowsQuery(row_keys=[b"b", b"d"]) + handler.clear() + row_list = await table.read_rows_sharded([query1, query2]) + assert len(row_list) == 4 + # validate counts + assert len(handler.completed_operations) == 2 + assert len(handler.completed_attempts) == 2 + # validate operations + for operation in handler.completed_operations: + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.value[0] == 0 + assert operation.is_streaming is True + assert operation.op_type.value == "ReadRows" + assert len(operation.completed_attempts) == 1 + attempt = operation.completed_attempts[0] + assert attempt in handler.completed_attempts + assert operation.cluster_id == next(iter(cluster_config.keys())) + assert ( + operation.zone + == cluster_config[operation.cluster_id].location.split("/")[-1] + ) + assert operation.duration_ns > 0 and operation.duration_ns < 1e9 + assert ( + operation.first_response_latency_ns is not None + and operation.first_response_latency_ns < operation.duration_ns + ) + assert operation.flow_throttling_time_ns == 0 + # validate attempt + assert isinstance(attempt, CompletedAttemptMetric) + assert ( + attempt.duration_ns > 0 and attempt.duration_ns < operation.duration_ns + ) + assert attempt.end_status.value[0] == 0 + assert attempt.backoff_before_attempt_ns == 0 + assert ( + attempt.gfe_latency_ns > 0 + and attempt.gfe_latency_ns < attempt.duration_ns + ) + assert ( + attempt.application_blocking_time_ns > 0 + and attempt.application_blocking_time_ns < operation.duration_ns + ) + + @CrossSync.pytest + async def test_read_rows_sharded_failure_with_retries( + self, table, temp_rows, handler, error_injector + ): + """ + Test failure in grpc layer by injecting errors into an interceptor + with retryable errors + """ + from google.cloud.bigtable.data.read_rows_query import ReadRowsQuery + + await temp_rows.add_row(b"a") + await temp_rows.add_row(b"b") + query1 = ReadRowsQuery(row_keys=[b"a"]) + query2 = ReadRowsQuery(row_keys=[b"b"]) + handler.clear() + + error_injector.push(self._make_exception(StatusCode.ABORTED)) + await table.read_rows_sharded([query1, query2], retryable_errors=[Aborted]) + + assert len(handler.completed_operations) == 2 + assert len(handler.completed_attempts) == 3 + # validate operations + for op in handler.completed_operations: + assert op.final_status.name == "OK" + assert op.op_type.value == "ReadRows" + assert op.is_streaming is True + # validate attempts + assert ( + len([a for a in handler.completed_attempts if a.end_status.name == "OK"]) + == 2 + ) + assert ( + len( + [ + a + for a in handler.completed_attempts + if a.end_status.name == "ABORTED" + ] + ) + == 1 + ) + + @CrossSync.pytest + async def test_read_rows_sharded_failure_timeout(self, table, temp_rows, handler): + """ + Test failure in gapic layer by passing very low timeout + + No grpc headers expected + """ + from google.api_core.exceptions import DeadlineExceeded + + from google.cloud.bigtable.data.exceptions import ShardedReadRowsExceptionGroup + from google.cloud.bigtable.data.read_rows_query import ReadRowsQuery + + await temp_rows.add_row(b"a") + await temp_rows.add_row(b"b") + query1 = ReadRowsQuery(row_keys=[b"a"]) + query2 = ReadRowsQuery(row_keys=[b"b"]) + handler.clear() + with pytest.raises(ShardedReadRowsExceptionGroup) as e: + await table.read_rows_sharded([query1, query2], operation_timeout=0.005) + assert len(e.value.exceptions) == 2 + for sub_exc in e.value.exceptions: + assert isinstance(sub_exc.__cause__, DeadlineExceeded) + # both shards should fail + assert len(handler.completed_operations) == 2 + assert len(handler.completed_attempts) == 2 + # validate operations + for operation in handler.completed_operations: + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.name == "DEADLINE_EXCEEDED" + assert operation.op_type.value == "ReadRows" + assert operation.is_streaming is True + assert len(operation.completed_attempts) == 1 + assert operation.cluster_id == "" + assert operation.zone == "global" + # validate attempt + attempt = operation.completed_attempts[0] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.end_status.name == "DEADLINE_EXCEEDED" + assert attempt.gfe_latency_ns is None + + @CrossSync.pytest + async def test_read_rows_sharded_failure_unauthorized( + self, handler, authorized_view, cluster_config + ): + """ + Test failure in backend by accessing an unauthorized family + """ + from google.cloud.bigtable.data.exceptions import ShardedReadRowsExceptionGroup + from google.cloud.bigtable.data.read_rows_query import ReadRowsQuery + from google.cloud.bigtable.data.row_filters import FamilyNameRegexFilter + + query1 = ReadRowsQuery(row_filter=FamilyNameRegexFilter("unauthorized")) + query2 = ReadRowsQuery(row_filter=FamilyNameRegexFilter(TEST_FAMILY)) + handler.clear() + with pytest.raises(ShardedReadRowsExceptionGroup) as e: + await authorized_view.read_rows_sharded([query1, query2]) + assert len(e.value.exceptions) == 1 + assert isinstance(e.value.exceptions[0].__cause__, GoogleAPICallError) + assert ( + e.value.exceptions[0].__cause__.grpc_status_code.name == "PERMISSION_DENIED" + ) + # one shard will fail, the other will succeed + assert len(handler.completed_operations) == 2 + assert len(handler.completed_attempts) == 2 + # sort operations by status + failed_op = next( + op for op in handler.completed_operations if op.final_status.name != "OK" + ) + success_op = next( + op for op in handler.completed_operations if op.final_status.name == "OK" + ) + # validate failed operation + assert failed_op.final_status.name == "PERMISSION_DENIED" + assert failed_op.op_type.value == "ReadRows" + assert failed_op.is_streaming is True + assert len(failed_op.completed_attempts) == 1 + assert failed_op.cluster_id == next(iter(cluster_config.keys())) + assert ( + failed_op.zone + == cluster_config[failed_op.cluster_id].location.split("/")[-1] + ) + # validate failed attempt + failed_attempt = failed_op.completed_attempts[0] + assert failed_attempt.end_status.name == "PERMISSION_DENIED" + assert ( + failed_attempt.gfe_latency_ns >= 0 + and failed_attempt.gfe_latency_ns < failed_op.duration_ns + ) + # validate successful operation + assert success_op.final_status.name == "OK" + assert success_op.op_type.value == "ReadRows" + assert success_op.is_streaming is True + assert len(success_op.completed_attempts) == 1 + # validate successful attempt + success_attempt = success_op.completed_attempts[0] + assert success_attempt.end_status.name == "OK" + + @CrossSync.pytest + async def test_read_rows_sharded_failure_mid_stream( + self, table, temp_rows, handler, error_injector + ): + """ + Test failure in grpc stream + """ + from google.cloud.bigtable.data.exceptions import ShardedReadRowsExceptionGroup + from google.cloud.bigtable.data.read_rows_query import ReadRowsQuery + + await temp_rows.add_row(b"a") + await temp_rows.add_row(b"b") + query1 = ReadRowsQuery(row_keys=[b"a"]) + query2 = ReadRowsQuery(row_keys=[b"b"]) + handler.clear() + error_injector.fail_mid_stream = True + error_injector.push(self._make_exception(StatusCode.ABORTED)) + error_injector.push(self._make_exception(StatusCode.PERMISSION_DENIED)) + with pytest.raises(ShardedReadRowsExceptionGroup) as e: + await table.read_rows_sharded([query1, query2], retryable_errors=[Aborted]) + assert len(e.value.exceptions) == 1 + assert isinstance(e.value.exceptions[0].__cause__, PermissionDenied) + # one shard will fail, the other will succeed + # the failing shard will have one retry + assert len(handler.completed_operations) == 2 + assert len(handler.completed_attempts) == 3 + # sort operations by status + failed_op = next( + op for op in handler.completed_operations if op.final_status.name != "OK" + ) + success_op = next( + op for op in handler.completed_operations if op.final_status.name == "OK" + ) + # validate failed operation + assert failed_op.final_status.name == "PERMISSION_DENIED" + assert failed_op.op_type.value == "ReadRows" + assert failed_op.is_streaming is True + assert len(failed_op.completed_attempts) == 1 + # validate successful operation + assert success_op.final_status.name == "OK" + assert len(success_op.completed_attempts) == 2 + # validate failed attempt + attempt = failed_op.completed_attempts[0] + assert attempt.end_status.name == "PERMISSION_DENIED" + # validate retried attempt + retried_attempt = success_op.completed_attempts[0] + assert retried_attempt.end_status.name == "ABORTED" + # validate successful attempt + success_attempt = success_op.completed_attempts[-1] + assert success_attempt.end_status.name == "OK" + + @CrossSync.pytest + async def test_bulk_mutate_rows(self, table, temp_rows, handler, cluster_config): + from google.cloud.bigtable.data.mutations import RowMutationEntry + + new_value = uuid.uuid4().hex.encode() + row_key, mutation = await temp_rows.create_row_and_mutation( + table, new_value=new_value + ) + bulk_mutation = RowMutationEntry(row_key, [mutation]) + + handler.clear() + await table.bulk_mutate_rows([bulk_mutation]) + # validate counts + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + # validate operation + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.value[0] == 0 + assert operation.is_streaming is False + assert operation.op_type.value == "MutateRows" + assert len(operation.completed_attempts) == 1 + assert operation.completed_attempts[0] == handler.completed_attempts[0] + assert operation.cluster_id == next(iter(cluster_config.keys())) + assert ( + operation.zone + == cluster_config[operation.cluster_id].location.split("/")[-1] + ) + assert operation.duration_ns > 0 and operation.duration_ns < 1e9 + assert ( + operation.first_response_latency_ns is None + ) # populated for read_rows only + assert operation.flow_throttling_time_ns == 0 + # validate attempt + attempt = handler.completed_attempts[0] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.duration_ns > 0 and attempt.duration_ns < operation.duration_ns + assert attempt.end_status.value[0] == 0 + assert attempt.backoff_before_attempt_ns == 0 + assert ( + attempt.gfe_latency_ns > 0 and attempt.gfe_latency_ns < attempt.duration_ns + ) + assert attempt.application_blocking_time_ns == 0 + + @CrossSync.pytest + async def test_bulk_mutate_rows_failure_with_retries( + self, table, temp_rows, handler, error_injector + ): + """ + Test failure in grpc layer by injecting errors into an interceptor + with retryable errors, then a terminal one + """ + from google.cloud.bigtable.data.exceptions import MutationsExceptionGroup + from google.cloud.bigtable.data.mutations import RowMutationEntry, SetCell + + row_key = b"row_key_1" + mutation = SetCell(TEST_FAMILY, b"q", b"v") + entry = RowMutationEntry(row_key, [mutation]) + assert entry.is_idempotent() + + handler.clear() + expected_zone = "my_zone" + expected_cluster = "my_cluster" + num_retryable = 2 + for i in range(num_retryable): + error_injector.push( + self._make_exception(StatusCode.ABORTED, cluster_id=expected_cluster) + ) + error_injector.push( + self._make_exception(StatusCode.PERMISSION_DENIED, zone_id=expected_zone) + ) + with pytest.raises(MutationsExceptionGroup): + await table.bulk_mutate_rows([entry], retryable_errors=[Aborted]) + # validate counts + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == num_retryable + 1 + # validate operation + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.name == "PERMISSION_DENIED" + assert operation.op_type.value == "MutateRows" + assert operation.is_streaming is False + assert len(operation.completed_attempts) == num_retryable + 1 + assert operation.cluster_id == expected_cluster + assert operation.zone == expected_zone + # validate attempts + for i in range(num_retryable): + attempt = handler.completed_attempts[i] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.end_status.name == "ABORTED" + assert attempt.gfe_latency_ns is None + final_attempt = handler.completed_attempts[num_retryable] + assert isinstance(final_attempt, CompletedAttemptMetric) + assert final_attempt.end_status.name == "PERMISSION_DENIED" + assert final_attempt.gfe_latency_ns is None + + @CrossSync.pytest + async def test_bulk_mutate_rows_failure_timeout(self, table, temp_rows, handler): + """ + Test failure in gapic layer by passing very low timeout + + No grpc headers expected + """ + from google.cloud.bigtable.data.exceptions import MutationsExceptionGroup + from google.cloud.bigtable.data.mutations import RowMutationEntry, SetCell + + row_key = b"row_key_1" + mutation = SetCell(TEST_FAMILY, b"q", b"v") + entry = RowMutationEntry(row_key, [mutation]) + + handler.clear() + with pytest.raises(MutationsExceptionGroup): + await table.bulk_mutate_rows([entry], operation_timeout=0.001) + # validate counts + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + # validate operation + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.name == "DEADLINE_EXCEEDED" + assert operation.op_type.value == "MutateRows" + assert operation.is_streaming is False + assert len(operation.completed_attempts) == 1 + assert operation.cluster_id == "" + assert operation.zone == "global" + # validate attempt + attempt = handler.completed_attempts[0] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.end_status.name == "DEADLINE_EXCEEDED" + assert attempt.gfe_latency_ns is None + + @CrossSync.pytest + async def test_bulk_mutate_rows_failure_unauthorized( + self, handler, authorized_view, cluster_config + ): + """ + Test failure in backend by accessing an unauthorized family + """ + from google.cloud.bigtable.data.exceptions import MutationsExceptionGroup + from google.cloud.bigtable.data.mutations import RowMutationEntry, SetCell + + row_key = b"row_key_1" + mutation = SetCell("unauthorized", b"q", b"v") + entry = RowMutationEntry(row_key, [mutation]) + + handler.clear() + with pytest.raises(MutationsExceptionGroup): + await authorized_view.bulk_mutate_rows([entry]) + # validate counts + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + # validate operation + operation = handler.completed_operations[0] + assert operation.final_status.name == "PERMISSION_DENIED" + assert operation.op_type.value == "MutateRows" + assert operation.is_streaming is False + assert len(operation.completed_attempts) == 1 + assert operation.cluster_id == next(iter(cluster_config.keys())) + assert ( + operation.zone + == cluster_config[operation.cluster_id].location.split("/")[-1] + ) + # validate attempt + attempt = handler.completed_attempts[0] + assert attempt.end_status.name == "PERMISSION_DENIED" + assert ( + attempt.gfe_latency_ns >= 0 + and attempt.gfe_latency_ns < operation.duration_ns + ) + + @CrossSync.pytest + async def test_bulk_mutate_rows_failure_unauthorized_with_retries( + self, handler, authorized_view, cluster_config + ): + """ + retry unauthorized request multiple times before timing out + + For bulk_mutate, the rpc returns success, with failures returned in the response. + For this reason, We expect the attempts to be marked as successful, even though + the underlying mutation is retried + """ + from google.cloud.bigtable.data.exceptions import MutationsExceptionGroup + from google.cloud.bigtable.data.mutations import RowMutationEntry, SetCell + + row_key = b"row_key_1" + mutation = SetCell("unauthorized", b"q", b"v") + entry = RowMutationEntry(row_key, [mutation]) + + handler.clear() + with pytest.raises(MutationsExceptionGroup) as e: + await authorized_view.bulk_mutate_rows( + [entry], retryable_errors=[PermissionDenied], operation_timeout=0.5 + ) + assert len(e.value.exceptions) == 1 + # validate counts + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) > 1 + # validate operation + operation = handler.completed_operations[0] + assert operation.final_status.name == "DEADLINE_EXCEEDED" + assert operation.op_type.value == "MutateRows" + assert operation.is_streaming is False + assert len(operation.completed_attempts) > 1 + assert operation.cluster_id == next(iter(cluster_config.keys())) + assert ( + operation.zone + == cluster_config[operation.cluster_id].location.split("/")[-1] + ) + # validate attempts + for attempt in handler.completed_attempts: + assert attempt.end_status.name in ["OK", "DEADLINE_EXCEEDED"] + + @CrossSync.pytest + async def test_mutate_rows_batcher(self, table, temp_rows, handler, cluster_config): + from google.cloud.bigtable.data.mutations import RowMutationEntry + + new_value, new_value2 = [uuid.uuid4().hex.encode() for _ in range(2)] + row_key, mutation = await temp_rows.create_row_and_mutation( + table, new_value=new_value + ) + row_key2, mutation2 = await temp_rows.create_row_and_mutation( + table, new_value=new_value2 + ) + bulk_mutation = RowMutationEntry(row_key, [mutation]) + bulk_mutation2 = RowMutationEntry(row_key2, [mutation2]) + + handler.clear() + async with table.mutations_batcher() as batcher: + await batcher.append(bulk_mutation) + await batcher.append(bulk_mutation2) + # validate counts + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + # bacher expects to cancel staged operation on close + # validate operation + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.value[0] == 0 + assert operation.is_streaming is False + assert operation.op_type.value == "MutateRows" + assert len(operation.completed_attempts) == 1 + assert operation.completed_attempts[0] == handler.completed_attempts[0] + assert operation.cluster_id == next(iter(cluster_config.keys())) + assert ( + operation.zone + == cluster_config[operation.cluster_id].location.split("/")[-1] + ) + assert operation.duration_ns > 0 and operation.duration_ns < 1e9 + assert ( + operation.first_response_latency_ns is None + ) # populated for read_rows only + assert ( + operation.flow_throttling_time_ns > 0 + and operation.flow_throttling_time_ns < operation.duration_ns + ) + # validate attempt + attempt = handler.completed_attempts[0] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.duration_ns > 0 and attempt.duration_ns < operation.duration_ns + assert attempt.end_status.value[0] == 0 + assert attempt.backoff_before_attempt_ns == 0 + assert ( + attempt.gfe_latency_ns > 0 and attempt.gfe_latency_ns < attempt.duration_ns + ) + assert attempt.application_blocking_time_ns == 0 + + @CrossSync.pytest + async def test_mutate_rows_batcher_failure_with_retries( + self, table, handler, error_injector + ): + """ + Test failure in grpc layer by injecting errors into an interceptor + with retryable errors, then a terminal one + """ + from google.cloud.bigtable.data.exceptions import MutationsExceptionGroup + from google.cloud.bigtable.data.mutations import RowMutationEntry, SetCell + + row_key = b"row_key_1" + mutation = SetCell(TEST_FAMILY, b"q", b"v") + entry = RowMutationEntry(row_key, [mutation]) + assert entry.is_idempotent() + + handler.clear() + expected_zone = "my_zone" + expected_cluster = "my_cluster" + num_retryable = 2 + for i in range(num_retryable): + error_injector.push( + self._make_exception(StatusCode.ABORTED, cluster_id=expected_cluster) + ) + error_injector.push( + self._make_exception(StatusCode.PERMISSION_DENIED, zone_id=expected_zone) + ) + with pytest.raises(MutationsExceptionGroup): + async with table.mutations_batcher( + batch_retryable_errors=[Aborted] + ) as batcher: + await batcher.append(entry) + # validate counts + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == num_retryable + 1 + # validate operation + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.name == "PERMISSION_DENIED" + assert operation.op_type.value == "MutateRows" + assert operation.is_streaming is False + assert len(operation.completed_attempts) == num_retryable + 1 + assert operation.cluster_id == expected_cluster + assert operation.zone == expected_zone + # validate attempts + for i in range(num_retryable): + attempt = handler.completed_attempts[i] + assert attempt.end_status.name == "ABORTED" + assert attempt.gfe_latency_ns is None + final_attempt = handler.completed_attempts[num_retryable] + assert final_attempt.end_status.name == "PERMISSION_DENIED" + assert final_attempt.gfe_latency_ns is None + + @CrossSync.pytest + async def test_mutate_rows_batcher_failure_timeout(self, table, temp_rows, handler): + """ + Test failure in gapic layer by passing very low timeout + + No grpc headers expected + """ + from google.cloud.bigtable.data.exceptions import MutationsExceptionGroup + from google.cloud.bigtable.data.mutations import RowMutationEntry, SetCell + + row_key = b"row_key_1" + mutation = SetCell(TEST_FAMILY, b"q", b"v") + entry = RowMutationEntry(row_key, [mutation]) + + with pytest.raises(MutationsExceptionGroup): + async with table.mutations_batcher( + batch_operation_timeout=0.001 + ) as batcher: + await batcher.append(entry) + # validate counts + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + # validate operation + operation = handler.completed_operations[0] + assert operation.final_status.name == "DEADLINE_EXCEEDED" + assert operation.op_type.value == "MutateRows" + assert operation.is_streaming is False + assert len(operation.completed_attempts) == 1 + assert operation.cluster_id == "" + assert operation.zone == "global" + # validate attempt + attempt = handler.completed_attempts[0] + assert attempt.end_status.name == "DEADLINE_EXCEEDED" + assert attempt.gfe_latency_ns is None + + @CrossSync.pytest + async def test_mutate_rows_batcher_failure_unauthorized( + self, handler, authorized_view, cluster_config + ): + """ + Test failure in backend by accessing an unauthorized family + """ + from google.cloud.bigtable.data.exceptions import MutationsExceptionGroup + from google.cloud.bigtable.data.mutations import RowMutationEntry, SetCell + + row_key = b"row_key_1" + mutation = SetCell("unauthorized", b"q", b"v") + entry = RowMutationEntry(row_key, [mutation]) + + with pytest.raises(MutationsExceptionGroup) as e: + async with authorized_view.mutations_batcher() as batcher: + await batcher.append(entry) + assert len(e.value.exceptions) == 1 + assert isinstance(e.value.exceptions[0].__cause__, GoogleAPICallError) + assert ( + e.value.exceptions[0].__cause__.grpc_status_code.name == "PERMISSION_DENIED" + ) + # validate counts + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + # validate operation + operation = handler.completed_operations[0] + assert operation.final_status.name == "PERMISSION_DENIED" + assert operation.op_type.value == "MutateRows" + assert operation.is_streaming is False + assert len(operation.completed_attempts) == 1 + assert operation.cluster_id == next(iter(cluster_config.keys())) + assert ( + operation.zone + == cluster_config[operation.cluster_id].location.split("/")[-1] + ) + # validate attempt + attempt = handler.completed_attempts[0] + assert attempt.end_status.name == "PERMISSION_DENIED" + assert ( + attempt.gfe_latency_ns >= 0 + and attempt.gfe_latency_ns < operation.duration_ns + ) + @pytest.mark.skipif( bool(os.environ.get(BIGTABLE_EMULATOR)), reason="emulator doesn't suport cluster_config", diff --git a/packages/google-cloud-bigtable/tests/system/data/test_metrics_autogen.py b/packages/google-cloud-bigtable/tests/system/data/test_metrics_autogen.py index bee213626f7e..f37a07aa58bc 100644 --- a/packages/google-cloud-bigtable/tests/system/data/test_metrics_autogen.py +++ b/packages/google-cloud-bigtable/tests/system/data/test_metrics_autogen.py @@ -34,6 +34,7 @@ CompletedOperationMetric, ) from google.cloud.bigtable.data._metrics.handlers._base import MetricsHandler +from google.cloud.bigtable.data.read_rows_query import ReadRowsQuery from google.cloud.bigtable_v2.types import ResponseParams from . import TEST_FAMILY, SystemTestRunner @@ -115,6 +116,9 @@ def __getattr__(self, name): return response +@pytest.mark.skipif( + bool(os.environ.get(BIGTABLE_EMULATOR)), reason="Emulator does not support metrics" +) class TestMetrics(SystemTestRunner): def _make_client(self): project = os.getenv("GOOGLE_CLOUD_PROJECT") or None @@ -187,6 +191,1022 @@ def authorized_view( table._metrics.add_handler(handler) yield table + def test_read_rows(self, table, temp_rows, handler, cluster_config): + temp_rows.add_row(b"row_key_1") + temp_rows.add_row(b"row_key_2") + handler.clear() + row_list = table.read_rows(ReadRowsQuery()) + assert len(row_list) == 2 + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.value[0] == 0 + assert operation.is_streaming is True + assert operation.op_type.value == "ReadRows" + assert len(operation.completed_attempts) == 1 + assert operation.completed_attempts[0] == handler.completed_attempts[0] + assert operation.cluster_id == next(iter(cluster_config.keys())) + assert ( + operation.zone + == cluster_config[operation.cluster_id].location.split("/")[-1] + ) + assert operation.duration_ns > 0 and operation.duration_ns < 1000000000.0 + assert ( + operation.first_response_latency_ns is not None + and operation.first_response_latency_ns < operation.duration_ns + ) + assert operation.flow_throttling_time_ns == 0 + attempt = handler.completed_attempts[0] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.duration_ns > 0 and attempt.duration_ns < operation.duration_ns + assert attempt.end_status.value[0] == 0 + assert attempt.backoff_before_attempt_ns == 0 + assert ( + attempt.gfe_latency_ns > 0 and attempt.gfe_latency_ns < attempt.duration_ns + ) + assert ( + attempt.application_blocking_time_ns > 0 + and attempt.application_blocking_time_ns < operation.duration_ns + ) + + def test_read_rows_failure_with_retries( + self, table, temp_rows, handler, error_injector + ): + """Test failure in grpc layer by injecting errors into an interceptor + with retryable errors, then a terminal one""" + temp_rows.add_row(b"row_key_1") + handler.clear() + expected_zone = "my_zone" + expected_cluster = "my_cluster" + num_retryable = 2 + for i in range(num_retryable): + error_injector.push( + self._make_exception(StatusCode.ABORTED, cluster_id=expected_cluster) + ) + error_injector.push( + self._make_exception(StatusCode.PERMISSION_DENIED, zone_id=expected_zone) + ) + with pytest.raises(PermissionDenied): + table.read_rows(ReadRowsQuery(), retryable_errors=[Aborted]) + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == num_retryable + 1 + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.name == "PERMISSION_DENIED" + assert operation.op_type.value == "ReadRows" + assert operation.is_streaming is True + assert len(operation.completed_attempts) == num_retryable + 1 + assert operation.cluster_id == expected_cluster + assert operation.zone == expected_zone + for i in range(num_retryable): + attempt = handler.completed_attempts[i] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.end_status.name == "ABORTED" + assert attempt.gfe_latency_ns is None + final_attempt = handler.completed_attempts[num_retryable] + assert isinstance(final_attempt, CompletedAttemptMetric) + assert final_attempt.end_status.name == "PERMISSION_DENIED" + assert final_attempt.gfe_latency_ns is None + + def test_read_rows_failure_timeout(self, table, temp_rows, handler): + """Test failure in gapic layer by passing very low timeout + + No grpc headers expected""" + temp_rows.add_row(b"row_key_1") + handler.clear() + with pytest.raises(GoogleAPICallError): + table.read_rows(ReadRowsQuery(), operation_timeout=0.001) + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.name == "DEADLINE_EXCEEDED" + assert operation.op_type.value == "ReadRows" + assert operation.is_streaming is True + assert len(operation.completed_attempts) == 1 + assert operation.cluster_id == "" + assert operation.zone == "global" + attempt = handler.completed_attempts[0] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.end_status.name == "DEADLINE_EXCEEDED" + assert attempt.gfe_latency_ns is None + + def test_read_rows_failure_unauthorized( + self, handler, authorized_view, cluster_config + ): + """Test failure in backend by accessing an unauthorized family""" + from google.cloud.bigtable.data.row_filters import FamilyNameRegexFilter + + with pytest.raises(GoogleAPICallError) as e: + authorized_view.read_rows( + ReadRowsQuery(row_filter=FamilyNameRegexFilter("unauthorized")) + ) + assert e.value.grpc_status_code.name == "PERMISSION_DENIED" + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.name == "PERMISSION_DENIED" + assert operation.op_type.value == "ReadRows" + assert operation.is_streaming is True + assert len(operation.completed_attempts) == 1 + assert operation.cluster_id == next(iter(cluster_config.keys())) + assert ( + operation.zone + == cluster_config[operation.cluster_id].location.split("/")[-1] + ) + attempt = handler.completed_attempts[0] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.end_status.name == "PERMISSION_DENIED" + assert ( + attempt.gfe_latency_ns >= 0 + and attempt.gfe_latency_ns < operation.duration_ns + ) + + def test_read_rows_stream(self, table, temp_rows, handler, cluster_config): + temp_rows.add_row(b"row_key_1") + temp_rows.add_row(b"row_key_2") + handler.clear() + generator = table.read_rows_stream(ReadRowsQuery()) + row_list = [r for r in generator] + assert len(row_list) == 2 + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.value[0] == 0 + assert operation.is_streaming is True + assert operation.op_type.value == "ReadRows" + assert len(operation.completed_attempts) == 1 + assert operation.completed_attempts[0] == handler.completed_attempts[0] + assert operation.cluster_id == next(iter(cluster_config.keys())) + assert ( + operation.zone + == cluster_config[operation.cluster_id].location.split("/")[-1] + ) + assert operation.duration_ns > 0 and operation.duration_ns < 1000000000.0 + assert ( + operation.first_response_latency_ns is not None + and operation.first_response_latency_ns < operation.duration_ns + ) + assert operation.flow_throttling_time_ns == 0 + attempt = handler.completed_attempts[0] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.duration_ns > 0 and attempt.duration_ns < operation.duration_ns + assert attempt.end_status.value[0] == 0 + assert attempt.backoff_before_attempt_ns == 0 + assert ( + attempt.gfe_latency_ns > 0 and attempt.gfe_latency_ns < attempt.duration_ns + ) + assert ( + attempt.application_blocking_time_ns > 0 + and attempt.application_blocking_time_ns < operation.duration_ns + ) + + def test_read_rows_stream_failure_closed( + self, table, temp_rows, handler, error_injector + ): + """Test how metrics collection handles closed generator""" + temp_rows.add_row(b"row_key_1") + temp_rows.add_row(b"row_key_2") + handler.clear() + generator = table.read_rows_stream(ReadRowsQuery()) + generator.__next__() + generator.close() + with pytest.raises(CrossSync._Sync_Impl.StopIteration): + generator.__next__() + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + operation = handler.completed_operations[0] + assert operation.final_status.name == "CANCELLED" + assert operation.op_type.value == "ReadRows" + assert operation.is_streaming is True + assert len(operation.completed_attempts) == 1 + assert operation.cluster_id == "" + assert operation.zone == "global" + attempt = handler.completed_attempts[0] + assert attempt.end_status.name == "CANCELLED" + assert attempt.gfe_latency_ns is None + + def test_read_rows_stream_failure_with_retries( + self, table, temp_rows, handler, error_injector + ): + """Test failure in grpc layer by injecting errors into an interceptor + with retryable errors, then a terminal one""" + temp_rows.add_row(b"row_key_1") + handler.clear() + expected_zone = "my_zone" + expected_cluster = "my_cluster" + num_retryable = 2 + for i in range(num_retryable): + error_injector.push( + self._make_exception(StatusCode.ABORTED, cluster_id=expected_cluster) + ) + error_injector.push( + self._make_exception(StatusCode.PERMISSION_DENIED, zone_id=expected_zone) + ) + generator = table.read_rows_stream(ReadRowsQuery(), retryable_errors=[Aborted]) + with pytest.raises(PermissionDenied): + [_ for _ in generator] + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == num_retryable + 1 + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.name == "PERMISSION_DENIED" + assert operation.op_type.value == "ReadRows" + assert operation.is_streaming is True + assert len(operation.completed_attempts) == num_retryable + 1 + assert operation.cluster_id == expected_cluster + assert operation.zone == expected_zone + for i in range(num_retryable): + attempt = handler.completed_attempts[i] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.end_status.name == "ABORTED" + assert attempt.gfe_latency_ns is None + final_attempt = handler.completed_attempts[num_retryable] + assert isinstance(final_attempt, CompletedAttemptMetric) + assert final_attempt.end_status.name == "PERMISSION_DENIED" + assert final_attempt.gfe_latency_ns is None + + def test_read_rows_stream_failure_timeout(self, table, temp_rows, handler): + """Test failure in gapic layer by passing very low timeout + + No grpc headers expected""" + temp_rows.add_row(b"row_key_1") + handler.clear() + generator = table.read_rows_stream(ReadRowsQuery(), operation_timeout=0.001) + with pytest.raises(GoogleAPICallError): + [_ for _ in generator] + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.name == "DEADLINE_EXCEEDED" + assert operation.op_type.value == "ReadRows" + assert operation.is_streaming is True + assert len(operation.completed_attempts) == 1 + assert operation.cluster_id == "" + assert operation.zone == "global" + attempt = handler.completed_attempts[0] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.end_status.name == "DEADLINE_EXCEEDED" + assert attempt.gfe_latency_ns is None + + def test_read_rows_stream_failure_unauthorized( + self, handler, authorized_view, cluster_config + ): + """Test failure in backend by accessing an unauthorized family""" + from google.cloud.bigtable.data.row_filters import FamilyNameRegexFilter + + with pytest.raises(GoogleAPICallError) as e: + generator = authorized_view.read_rows_stream( + ReadRowsQuery(row_filter=FamilyNameRegexFilter("unauthorized")) + ) + [_ for _ in generator] + assert e.value.grpc_status_code.name == "PERMISSION_DENIED" + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.name == "PERMISSION_DENIED" + assert operation.op_type.value == "ReadRows" + assert operation.is_streaming is True + assert len(operation.completed_attempts) == 1 + assert operation.cluster_id == next(iter(cluster_config.keys())) + assert ( + operation.zone + == cluster_config[operation.cluster_id].location.split("/")[-1] + ) + attempt = handler.completed_attempts[0] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.end_status.name == "PERMISSION_DENIED" + assert ( + attempt.gfe_latency_ns >= 0 + and attempt.gfe_latency_ns < operation.duration_ns + ) + + def test_read_rows_stream_failure_unauthorized_with_retries( + self, handler, authorized_view, cluster_config + ): + """retry unauthorized request multiple times before timing out""" + from google.cloud.bigtable.data.row_filters import FamilyNameRegexFilter + + with pytest.raises(GoogleAPICallError) as e: + generator = authorized_view.read_rows_stream( + ReadRowsQuery(row_filter=FamilyNameRegexFilter("unauthorized")), + retryable_errors=[PermissionDenied], + operation_timeout=0.5, + ) + [_ for _ in generator] + assert e.value.grpc_status_code.name == "DEADLINE_EXCEEDED" + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) > 1 + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.name == "DEADLINE_EXCEEDED" + assert operation.op_type.value == "ReadRows" + assert operation.is_streaming is True + assert len(operation.completed_attempts) > 1 + assert operation.cluster_id == next(iter(cluster_config.keys())) + assert ( + operation.zone + == cluster_config[operation.cluster_id].location.split("/")[-1] + ) + for attempt in handler.completed_attempts: + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.end_status.name in ["PERMISSION_DENIED", "DEADLINE_EXCEEDED"] + + def test_read_rows_stream_failure_mid_stream( + self, table, temp_rows, handler, error_injector + ): + """Test failure in grpc stream""" + temp_rows.add_row(b"row_key_1") + handler.clear() + error_injector.fail_mid_stream = True + error_injector.push(self._make_exception(StatusCode.ABORTED)) + error_injector.push(self._make_exception(StatusCode.PERMISSION_DENIED)) + generator = table.read_rows_stream(ReadRowsQuery(), retryable_errors=[Aborted]) + with pytest.raises(PermissionDenied): + [_ for _ in generator] + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 2 + operation = handler.completed_operations[0] + assert operation.final_status.name == "PERMISSION_DENIED" + assert operation.op_type.value == "ReadRows" + assert operation.is_streaming is True + assert len(operation.completed_attempts) == 2 + attempt = handler.completed_attempts[0] + assert attempt.end_status.name == "ABORTED" + final_attempt = handler.completed_attempts[-1] + assert final_attempt.end_status.name == "PERMISSION_DENIED" + + def test_read_row(self, table, temp_rows, handler, cluster_config): + temp_rows.add_row(b"row_key_1") + handler.clear() + table.read_row(b"row_key_1") + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.value[0] == 0 + assert operation.is_streaming is False + assert operation.op_type.value == "ReadRows" + assert len(operation.completed_attempts) == 1 + assert operation.completed_attempts[0] == handler.completed_attempts[0] + assert operation.cluster_id == next(iter(cluster_config.keys())) + assert ( + operation.zone + == cluster_config[operation.cluster_id].location.split("/")[-1] + ) + assert operation.duration_ns > 0 and operation.duration_ns < 1000000000.0 + assert ( + operation.first_response_latency_ns > 0 + and operation.first_response_latency_ns < operation.duration_ns + ) + assert operation.flow_throttling_time_ns == 0 + attempt = handler.completed_attempts[0] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.duration_ns > 0 and attempt.duration_ns < operation.duration_ns + assert attempt.end_status.value[0] == 0 + assert attempt.backoff_before_attempt_ns == 0 + assert ( + attempt.gfe_latency_ns > 0 and attempt.gfe_latency_ns < attempt.duration_ns + ) + assert ( + attempt.application_blocking_time_ns > 0 + and attempt.application_blocking_time_ns < operation.duration_ns + ) + + def test_read_row_failure_with_retries( + self, table, temp_rows, handler, error_injector + ): + """Test failure in grpc layer by injecting errors into an interceptor + with retryable errors, then a terminal one""" + temp_rows.add_row(b"row_key_1") + handler.clear() + expected_zone = "my_zone" + expected_cluster = "my_cluster" + num_retryable = 2 + for i in range(num_retryable): + error_injector.push( + self._make_exception(StatusCode.ABORTED, cluster_id=expected_cluster) + ) + error_injector.push( + self._make_exception(StatusCode.PERMISSION_DENIED, zone_id=expected_zone) + ) + with pytest.raises(PermissionDenied): + table.read_row(b"row_key_1", retryable_errors=[Aborted]) + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == num_retryable + 1 + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.name == "PERMISSION_DENIED" + assert operation.op_type.value == "ReadRows" + assert operation.is_streaming is False + assert len(operation.completed_attempts) == num_retryable + 1 + assert operation.cluster_id == expected_cluster + assert operation.zone == expected_zone + for i in range(num_retryable): + attempt = handler.completed_attempts[i] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.end_status.name == "ABORTED" + assert attempt.gfe_latency_ns is None + final_attempt = handler.completed_attempts[num_retryable] + assert isinstance(final_attempt, CompletedAttemptMetric) + assert final_attempt.end_status.name == "PERMISSION_DENIED" + assert final_attempt.gfe_latency_ns is None + + def test_read_row_failure_timeout(self, table, temp_rows, handler): + """Test failure in gapic layer by passing very low timeout + + No grpc headers expected""" + temp_rows.add_row(b"row_key_1") + handler.clear() + with pytest.raises(GoogleAPICallError): + table.read_row(b"row_key_1", operation_timeout=0.001) + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.name == "DEADLINE_EXCEEDED" + assert operation.op_type.value == "ReadRows" + assert operation.is_streaming is False + assert len(operation.completed_attempts) == 1 + assert operation.cluster_id == "" + assert operation.zone == "global" + attempt = handler.completed_attempts[0] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.end_status.name == "DEADLINE_EXCEEDED" + assert attempt.gfe_latency_ns is None + + def test_read_row_failure_unauthorized( + self, handler, authorized_view, cluster_config + ): + """Test failure in backend by accessing an unauthorized family""" + from google.cloud.bigtable.data.row_filters import FamilyNameRegexFilter + + with pytest.raises(GoogleAPICallError) as e: + authorized_view.read_row( + b"any_row", row_filter=FamilyNameRegexFilter("unauthorized") + ) + assert e.value.grpc_status_code.name == "PERMISSION_DENIED" + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.name == "PERMISSION_DENIED" + assert operation.op_type.value == "ReadRows" + assert operation.is_streaming is False + assert len(operation.completed_attempts) == 1 + assert operation.cluster_id == next(iter(cluster_config.keys())) + assert ( + operation.zone + == cluster_config[operation.cluster_id].location.split("/")[-1] + ) + attempt = handler.completed_attempts[0] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.end_status.name == "PERMISSION_DENIED" + assert ( + attempt.gfe_latency_ns >= 0 + and attempt.gfe_latency_ns < operation.duration_ns + ) + + def test_read_rows_sharded(self, table, temp_rows, handler, cluster_config): + from google.cloud.bigtable.data.read_rows_query import ReadRowsQuery + + temp_rows.add_row(b"a") + temp_rows.add_row(b"b") + temp_rows.add_row(b"c") + temp_rows.add_row(b"d") + query1 = ReadRowsQuery(row_keys=[b"a", b"c"]) + query2 = ReadRowsQuery(row_keys=[b"b", b"d"]) + handler.clear() + row_list = table.read_rows_sharded([query1, query2]) + assert len(row_list) == 4 + assert len(handler.completed_operations) == 2 + assert len(handler.completed_attempts) == 2 + for operation in handler.completed_operations: + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.value[0] == 0 + assert operation.is_streaming is True + assert operation.op_type.value == "ReadRows" + assert len(operation.completed_attempts) == 1 + attempt = operation.completed_attempts[0] + assert attempt in handler.completed_attempts + assert operation.cluster_id == next(iter(cluster_config.keys())) + assert ( + operation.zone + == cluster_config[operation.cluster_id].location.split("/")[-1] + ) + assert operation.duration_ns > 0 and operation.duration_ns < 1000000000.0 + assert ( + operation.first_response_latency_ns is not None + and operation.first_response_latency_ns < operation.duration_ns + ) + assert operation.flow_throttling_time_ns == 0 + assert isinstance(attempt, CompletedAttemptMetric) + assert ( + attempt.duration_ns > 0 and attempt.duration_ns < operation.duration_ns + ) + assert attempt.end_status.value[0] == 0 + assert attempt.backoff_before_attempt_ns == 0 + assert ( + attempt.gfe_latency_ns > 0 + and attempt.gfe_latency_ns < attempt.duration_ns + ) + assert ( + attempt.application_blocking_time_ns > 0 + and attempt.application_blocking_time_ns < operation.duration_ns + ) + + def test_read_rows_sharded_failure_with_retries( + self, table, temp_rows, handler, error_injector + ): + """Test failure in grpc layer by injecting errors into an interceptor + with retryable errors""" + from google.cloud.bigtable.data.read_rows_query import ReadRowsQuery + + temp_rows.add_row(b"a") + temp_rows.add_row(b"b") + query1 = ReadRowsQuery(row_keys=[b"a"]) + query2 = ReadRowsQuery(row_keys=[b"b"]) + handler.clear() + error_injector.push(self._make_exception(StatusCode.ABORTED)) + table.read_rows_sharded([query1, query2], retryable_errors=[Aborted]) + assert len(handler.completed_operations) == 2 + assert len(handler.completed_attempts) == 3 + for op in handler.completed_operations: + assert op.final_status.name == "OK" + assert op.op_type.value == "ReadRows" + assert op.is_streaming is True + assert ( + len([a for a in handler.completed_attempts if a.end_status.name == "OK"]) + == 2 + ) + assert ( + len( + [ + a + for a in handler.completed_attempts + if a.end_status.name == "ABORTED" + ] + ) + == 1 + ) + + def test_read_rows_sharded_failure_timeout(self, table, temp_rows, handler): + """Test failure in gapic layer by passing very low timeout + + No grpc headers expected""" + from google.api_core.exceptions import DeadlineExceeded + + from google.cloud.bigtable.data.exceptions import ShardedReadRowsExceptionGroup + from google.cloud.bigtable.data.read_rows_query import ReadRowsQuery + + temp_rows.add_row(b"a") + temp_rows.add_row(b"b") + query1 = ReadRowsQuery(row_keys=[b"a"]) + query2 = ReadRowsQuery(row_keys=[b"b"]) + handler.clear() + with pytest.raises(ShardedReadRowsExceptionGroup) as e: + table.read_rows_sharded([query1, query2], operation_timeout=0.005) + assert len(e.value.exceptions) == 2 + for sub_exc in e.value.exceptions: + assert isinstance(sub_exc.__cause__, DeadlineExceeded) + assert len(handler.completed_operations) == 2 + assert len(handler.completed_attempts) == 2 + for operation in handler.completed_operations: + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.name == "DEADLINE_EXCEEDED" + assert operation.op_type.value == "ReadRows" + assert operation.is_streaming is True + assert len(operation.completed_attempts) == 1 + assert operation.cluster_id == "" + assert operation.zone == "global" + attempt = operation.completed_attempts[0] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.end_status.name == "DEADLINE_EXCEEDED" + assert attempt.gfe_latency_ns is None + + def test_read_rows_sharded_failure_unauthorized( + self, handler, authorized_view, cluster_config + ): + """Test failure in backend by accessing an unauthorized family""" + from google.cloud.bigtable.data.exceptions import ShardedReadRowsExceptionGroup + from google.cloud.bigtable.data.read_rows_query import ReadRowsQuery + from google.cloud.bigtable.data.row_filters import FamilyNameRegexFilter + + query1 = ReadRowsQuery(row_filter=FamilyNameRegexFilter("unauthorized")) + query2 = ReadRowsQuery(row_filter=FamilyNameRegexFilter(TEST_FAMILY)) + handler.clear() + with pytest.raises(ShardedReadRowsExceptionGroup) as e: + authorized_view.read_rows_sharded([query1, query2]) + assert len(e.value.exceptions) == 1 + assert isinstance(e.value.exceptions[0].__cause__, GoogleAPICallError) + assert ( + e.value.exceptions[0].__cause__.grpc_status_code.name == "PERMISSION_DENIED" + ) + assert len(handler.completed_operations) == 2 + assert len(handler.completed_attempts) == 2 + failed_op = next( + (op for op in handler.completed_operations if op.final_status.name != "OK") + ) + success_op = next( + (op for op in handler.completed_operations if op.final_status.name == "OK") + ) + assert failed_op.final_status.name == "PERMISSION_DENIED" + assert failed_op.op_type.value == "ReadRows" + assert failed_op.is_streaming is True + assert len(failed_op.completed_attempts) == 1 + assert failed_op.cluster_id == next(iter(cluster_config.keys())) + assert ( + failed_op.zone + == cluster_config[failed_op.cluster_id].location.split("/")[-1] + ) + failed_attempt = failed_op.completed_attempts[0] + assert failed_attempt.end_status.name == "PERMISSION_DENIED" + assert ( + failed_attempt.gfe_latency_ns >= 0 + and failed_attempt.gfe_latency_ns < failed_op.duration_ns + ) + assert success_op.final_status.name == "OK" + assert success_op.op_type.value == "ReadRows" + assert success_op.is_streaming is True + assert len(success_op.completed_attempts) == 1 + success_attempt = success_op.completed_attempts[0] + assert success_attempt.end_status.name == "OK" + + def test_read_rows_sharded_failure_mid_stream( + self, table, temp_rows, handler, error_injector + ): + """Test failure in grpc stream""" + from google.cloud.bigtable.data.exceptions import ShardedReadRowsExceptionGroup + from google.cloud.bigtable.data.read_rows_query import ReadRowsQuery + + temp_rows.add_row(b"a") + temp_rows.add_row(b"b") + query1 = ReadRowsQuery(row_keys=[b"a"]) + query2 = ReadRowsQuery(row_keys=[b"b"]) + handler.clear() + error_injector.fail_mid_stream = True + error_injector.push(self._make_exception(StatusCode.ABORTED)) + error_injector.push(self._make_exception(StatusCode.PERMISSION_DENIED)) + with pytest.raises(ShardedReadRowsExceptionGroup) as e: + table.read_rows_sharded([query1, query2], retryable_errors=[Aborted]) + assert len(e.value.exceptions) == 1 + assert isinstance(e.value.exceptions[0].__cause__, PermissionDenied) + assert len(handler.completed_operations) == 2 + assert len(handler.completed_attempts) == 3 + failed_op = next( + (op for op in handler.completed_operations if op.final_status.name != "OK") + ) + success_op = next( + (op for op in handler.completed_operations if op.final_status.name == "OK") + ) + assert failed_op.final_status.name == "PERMISSION_DENIED" + assert failed_op.op_type.value == "ReadRows" + assert failed_op.is_streaming is True + assert len(failed_op.completed_attempts) == 1 + assert success_op.final_status.name == "OK" + assert len(success_op.completed_attempts) == 2 + attempt = failed_op.completed_attempts[0] + assert attempt.end_status.name == "PERMISSION_DENIED" + retried_attempt = success_op.completed_attempts[0] + assert retried_attempt.end_status.name == "ABORTED" + success_attempt = success_op.completed_attempts[-1] + assert success_attempt.end_status.name == "OK" + + def test_bulk_mutate_rows(self, table, temp_rows, handler, cluster_config): + from google.cloud.bigtable.data.mutations import RowMutationEntry + + new_value = uuid.uuid4().hex.encode() + row_key, mutation = temp_rows.create_row_and_mutation( + table, new_value=new_value + ) + bulk_mutation = RowMutationEntry(row_key, [mutation]) + handler.clear() + table.bulk_mutate_rows([bulk_mutation]) + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.value[0] == 0 + assert operation.is_streaming is False + assert operation.op_type.value == "MutateRows" + assert len(operation.completed_attempts) == 1 + assert operation.completed_attempts[0] == handler.completed_attempts[0] + assert operation.cluster_id == next(iter(cluster_config.keys())) + assert ( + operation.zone + == cluster_config[operation.cluster_id].location.split("/")[-1] + ) + assert operation.duration_ns > 0 and operation.duration_ns < 1000000000.0 + assert operation.first_response_latency_ns is None + assert operation.flow_throttling_time_ns == 0 + attempt = handler.completed_attempts[0] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.duration_ns > 0 and attempt.duration_ns < operation.duration_ns + assert attempt.end_status.value[0] == 0 + assert attempt.backoff_before_attempt_ns == 0 + assert ( + attempt.gfe_latency_ns > 0 and attempt.gfe_latency_ns < attempt.duration_ns + ) + assert attempt.application_blocking_time_ns == 0 + + def test_bulk_mutate_rows_failure_with_retries( + self, table, temp_rows, handler, error_injector + ): + """Test failure in grpc layer by injecting errors into an interceptor + with retryable errors, then a terminal one""" + from google.cloud.bigtable.data.exceptions import MutationsExceptionGroup + from google.cloud.bigtable.data.mutations import RowMutationEntry, SetCell + + row_key = b"row_key_1" + mutation = SetCell(TEST_FAMILY, b"q", b"v") + entry = RowMutationEntry(row_key, [mutation]) + assert entry.is_idempotent() + handler.clear() + expected_zone = "my_zone" + expected_cluster = "my_cluster" + num_retryable = 2 + for i in range(num_retryable): + error_injector.push( + self._make_exception(StatusCode.ABORTED, cluster_id=expected_cluster) + ) + error_injector.push( + self._make_exception(StatusCode.PERMISSION_DENIED, zone_id=expected_zone) + ) + with pytest.raises(MutationsExceptionGroup): + table.bulk_mutate_rows([entry], retryable_errors=[Aborted]) + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == num_retryable + 1 + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.name == "PERMISSION_DENIED" + assert operation.op_type.value == "MutateRows" + assert operation.is_streaming is False + assert len(operation.completed_attempts) == num_retryable + 1 + assert operation.cluster_id == expected_cluster + assert operation.zone == expected_zone + for i in range(num_retryable): + attempt = handler.completed_attempts[i] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.end_status.name == "ABORTED" + assert attempt.gfe_latency_ns is None + final_attempt = handler.completed_attempts[num_retryable] + assert isinstance(final_attempt, CompletedAttemptMetric) + assert final_attempt.end_status.name == "PERMISSION_DENIED" + assert final_attempt.gfe_latency_ns is None + + def test_bulk_mutate_rows_failure_timeout(self, table, temp_rows, handler): + """Test failure in gapic layer by passing very low timeout + + No grpc headers expected""" + from google.cloud.bigtable.data.exceptions import MutationsExceptionGroup + from google.cloud.bigtable.data.mutations import RowMutationEntry, SetCell + + row_key = b"row_key_1" + mutation = SetCell(TEST_FAMILY, b"q", b"v") + entry = RowMutationEntry(row_key, [mutation]) + handler.clear() + with pytest.raises(MutationsExceptionGroup): + table.bulk_mutate_rows([entry], operation_timeout=0.001) + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.name == "DEADLINE_EXCEEDED" + assert operation.op_type.value == "MutateRows" + assert operation.is_streaming is False + assert len(operation.completed_attempts) == 1 + assert operation.cluster_id == "" + assert operation.zone == "global" + attempt = handler.completed_attempts[0] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.end_status.name == "DEADLINE_EXCEEDED" + assert attempt.gfe_latency_ns is None + + def test_bulk_mutate_rows_failure_unauthorized( + self, handler, authorized_view, cluster_config + ): + """Test failure in backend by accessing an unauthorized family""" + from google.cloud.bigtable.data.exceptions import MutationsExceptionGroup + from google.cloud.bigtable.data.mutations import RowMutationEntry, SetCell + + row_key = b"row_key_1" + mutation = SetCell("unauthorized", b"q", b"v") + entry = RowMutationEntry(row_key, [mutation]) + handler.clear() + with pytest.raises(MutationsExceptionGroup): + authorized_view.bulk_mutate_rows([entry]) + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + operation = handler.completed_operations[0] + assert operation.final_status.name == "PERMISSION_DENIED" + assert operation.op_type.value == "MutateRows" + assert operation.is_streaming is False + assert len(operation.completed_attempts) == 1 + assert operation.cluster_id == next(iter(cluster_config.keys())) + assert ( + operation.zone + == cluster_config[operation.cluster_id].location.split("/")[-1] + ) + attempt = handler.completed_attempts[0] + assert attempt.end_status.name == "PERMISSION_DENIED" + assert ( + attempt.gfe_latency_ns >= 0 + and attempt.gfe_latency_ns < operation.duration_ns + ) + + def test_bulk_mutate_rows_failure_unauthorized_with_retries( + self, handler, authorized_view, cluster_config + ): + """retry unauthorized request multiple times before timing out + + For bulk_mutate, the rpc returns success, with failures returned in the response. + For this reason, We expect the attempts to be marked as successful, even though + the underlying mutation is retried""" + from google.cloud.bigtable.data.exceptions import MutationsExceptionGroup + from google.cloud.bigtable.data.mutations import RowMutationEntry, SetCell + + row_key = b"row_key_1" + mutation = SetCell("unauthorized", b"q", b"v") + entry = RowMutationEntry(row_key, [mutation]) + handler.clear() + with pytest.raises(MutationsExceptionGroup) as e: + authorized_view.bulk_mutate_rows( + [entry], retryable_errors=[PermissionDenied], operation_timeout=0.5 + ) + assert len(e.value.exceptions) == 1 + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) > 1 + operation = handler.completed_operations[0] + assert operation.final_status.name == "DEADLINE_EXCEEDED" + assert operation.op_type.value == "MutateRows" + assert operation.is_streaming is False + assert len(operation.completed_attempts) > 1 + assert operation.cluster_id == next(iter(cluster_config.keys())) + assert ( + operation.zone + == cluster_config[operation.cluster_id].location.split("/")[-1] + ) + for attempt in handler.completed_attempts: + assert attempt.end_status.name in ["OK", "DEADLINE_EXCEEDED"] + + def test_mutate_rows_batcher(self, table, temp_rows, handler, cluster_config): + from google.cloud.bigtable.data.mutations import RowMutationEntry + + new_value, new_value2 = [uuid.uuid4().hex.encode() for _ in range(2)] + row_key, mutation = temp_rows.create_row_and_mutation( + table, new_value=new_value + ) + row_key2, mutation2 = temp_rows.create_row_and_mutation( + table, new_value=new_value2 + ) + bulk_mutation = RowMutationEntry(row_key, [mutation]) + bulk_mutation2 = RowMutationEntry(row_key2, [mutation2]) + handler.clear() + with table.mutations_batcher() as batcher: + batcher.append(bulk_mutation) + batcher.append(bulk_mutation2) + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.value[0] == 0 + assert operation.is_streaming is False + assert operation.op_type.value == "MutateRows" + assert len(operation.completed_attempts) == 1 + assert operation.completed_attempts[0] == handler.completed_attempts[0] + assert operation.cluster_id == next(iter(cluster_config.keys())) + assert ( + operation.zone + == cluster_config[operation.cluster_id].location.split("/")[-1] + ) + assert operation.duration_ns > 0 and operation.duration_ns < 1000000000.0 + assert operation.first_response_latency_ns is None + assert ( + operation.flow_throttling_time_ns > 0 + and operation.flow_throttling_time_ns < operation.duration_ns + ) + attempt = handler.completed_attempts[0] + assert isinstance(attempt, CompletedAttemptMetric) + assert attempt.duration_ns > 0 and attempt.duration_ns < operation.duration_ns + assert attempt.end_status.value[0] == 0 + assert attempt.backoff_before_attempt_ns == 0 + assert ( + attempt.gfe_latency_ns > 0 and attempt.gfe_latency_ns < attempt.duration_ns + ) + assert attempt.application_blocking_time_ns == 0 + + def test_mutate_rows_batcher_failure_with_retries( + self, table, handler, error_injector + ): + """Test failure in grpc layer by injecting errors into an interceptor + with retryable errors, then a terminal one""" + from google.cloud.bigtable.data.exceptions import MutationsExceptionGroup + from google.cloud.bigtable.data.mutations import RowMutationEntry, SetCell + + row_key = b"row_key_1" + mutation = SetCell(TEST_FAMILY, b"q", b"v") + entry = RowMutationEntry(row_key, [mutation]) + assert entry.is_idempotent() + handler.clear() + expected_zone = "my_zone" + expected_cluster = "my_cluster" + num_retryable = 2 + for i in range(num_retryable): + error_injector.push( + self._make_exception(StatusCode.ABORTED, cluster_id=expected_cluster) + ) + error_injector.push( + self._make_exception(StatusCode.PERMISSION_DENIED, zone_id=expected_zone) + ) + with pytest.raises(MutationsExceptionGroup): + with table.mutations_batcher(batch_retryable_errors=[Aborted]) as batcher: + batcher.append(entry) + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == num_retryable + 1 + operation = handler.completed_operations[0] + assert isinstance(operation, CompletedOperationMetric) + assert operation.final_status.name == "PERMISSION_DENIED" + assert operation.op_type.value == "MutateRows" + assert operation.is_streaming is False + assert len(operation.completed_attempts) == num_retryable + 1 + assert operation.cluster_id == expected_cluster + assert operation.zone == expected_zone + for i in range(num_retryable): + attempt = handler.completed_attempts[i] + assert attempt.end_status.name == "ABORTED" + assert attempt.gfe_latency_ns is None + final_attempt = handler.completed_attempts[num_retryable] + assert final_attempt.end_status.name == "PERMISSION_DENIED" + assert final_attempt.gfe_latency_ns is None + + def test_mutate_rows_batcher_failure_timeout(self, table, temp_rows, handler): + """Test failure in gapic layer by passing very low timeout + + No grpc headers expected""" + from google.cloud.bigtable.data.exceptions import MutationsExceptionGroup + from google.cloud.bigtable.data.mutations import RowMutationEntry, SetCell + + row_key = b"row_key_1" + mutation = SetCell(TEST_FAMILY, b"q", b"v") + entry = RowMutationEntry(row_key, [mutation]) + with pytest.raises(MutationsExceptionGroup): + with table.mutations_batcher(batch_operation_timeout=0.001) as batcher: + batcher.append(entry) + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + operation = handler.completed_operations[0] + assert operation.final_status.name == "DEADLINE_EXCEEDED" + assert operation.op_type.value == "MutateRows" + assert operation.is_streaming is False + assert len(operation.completed_attempts) == 1 + assert operation.cluster_id == "" + assert operation.zone == "global" + attempt = handler.completed_attempts[0] + assert attempt.end_status.name == "DEADLINE_EXCEEDED" + assert attempt.gfe_latency_ns is None + + def test_mutate_rows_batcher_failure_unauthorized( + self, handler, authorized_view, cluster_config + ): + """Test failure in backend by accessing an unauthorized family""" + from google.cloud.bigtable.data.exceptions import MutationsExceptionGroup + from google.cloud.bigtable.data.mutations import RowMutationEntry, SetCell + + row_key = b"row_key_1" + mutation = SetCell("unauthorized", b"q", b"v") + entry = RowMutationEntry(row_key, [mutation]) + with pytest.raises(MutationsExceptionGroup) as e: + with authorized_view.mutations_batcher() as batcher: + batcher.append(entry) + assert len(e.value.exceptions) == 1 + assert isinstance(e.value.exceptions[0].__cause__, GoogleAPICallError) + assert ( + e.value.exceptions[0].__cause__.grpc_status_code.name == "PERMISSION_DENIED" + ) + assert len(handler.completed_operations) == 1 + assert len(handler.completed_attempts) == 1 + operation = handler.completed_operations[0] + assert operation.final_status.name == "PERMISSION_DENIED" + assert operation.op_type.value == "MutateRows" + assert operation.is_streaming is False + assert len(operation.completed_attempts) == 1 + assert operation.cluster_id == next(iter(cluster_config.keys())) + assert ( + operation.zone + == cluster_config[operation.cluster_id].location.split("/")[-1] + ) + attempt = handler.completed_attempts[0] + assert attempt.end_status.name == "PERMISSION_DENIED" + assert ( + attempt.gfe_latency_ns >= 0 + and attempt.gfe_latency_ns < operation.duration_ns + ) + @pytest.mark.skipif( bool(os.environ.get(BIGTABLE_EMULATOR)), reason="emulator doesn't suport cluster_config", diff --git a/packages/google-cloud-bigtable/tests/unit/data/_async/test__mutate_rows.py b/packages/google-cloud-bigtable/tests/unit/data/_async/test__mutate_rows.py index 9b64d74326b8..8ff6e42532b4 100644 --- a/packages/google-cloud-bigtable/tests/unit/data/_async/test__mutate_rows.py +++ b/packages/google-cloud-bigtable/tests/unit/data/_async/test__mutate_rows.py @@ -19,6 +19,7 @@ from google.rpc import status_pb2 from google.cloud.bigtable.data._cross_sync import CrossSync +from google.cloud.bigtable.data._metrics import ActiveOperationMetric from google.cloud.bigtable.data.mutations import DeleteAllFromRow, RowMutationEntry from google.cloud.bigtable_v2.types import MutateRowsResponse @@ -41,6 +42,9 @@ def _make_one(self, *args, **kwargs): kwargs["attempt_timeout"] = kwargs.pop("attempt_timeout", 0.1) kwargs["retryable_exceptions"] = kwargs.pop("retryable_exceptions", ()) kwargs["mutation_entries"] = kwargs.pop("mutation_entries", []) + kwargs["metric"] = kwargs.pop( + "metric", ActiveOperationMetric("MUTATE_ROWS") + ) return self._target_class()(*args, **kwargs) def _make_mutation(self, count=1, size=1): @@ -83,6 +87,7 @@ def test_ctor(self): entries = [self._make_mutation(), self._make_mutation()] operation_timeout = 0.05 attempt_timeout = 0.01 + metric = mock.Mock() retryable_exceptions = () instance = self._make_one( client, @@ -90,6 +95,7 @@ def test_ctor(self): entries, operation_timeout, attempt_timeout, + metric, retryable_exceptions, ) # running gapic_fn should trigger a client call with baked-in args @@ -109,6 +115,7 @@ def test_ctor(self): assert instance.is_retryable(RuntimeError("")) is False assert instance.remaining_indices == list(range(len(entries))) assert instance.errors == {} + assert instance._operation_metric == metric def test_ctor_too_many_entries(self): """ @@ -132,6 +139,7 @@ def test_ctor_too_many_entries(self): entries, operation_timeout, attempt_timeout, + mock.Mock(), ) assert "mutate_rows requests can contain at most 100000 mutations" in str( e.value @@ -145,6 +153,7 @@ async def test_mutate_rows_operation(self): """ client = mock.Mock() table = mock.Mock() + metric = ActiveOperationMetric("MUTATE_ROWS") entries = [self._make_mutation(), self._make_mutation()] operation_timeout = 0.05 cls = self._target_class() @@ -152,7 +161,7 @@ async def test_mutate_rows_operation(self): f"{cls.__module__}.{cls.__name__}._run_attempt", CrossSync.Mock() ) as attempt_mock: instance = self._make_one( - client, table, entries, operation_timeout, operation_timeout + client, table, entries, operation_timeout, operation_timeout, metric ) await instance.start() assert attempt_mock.call_count == 1 @@ -166,6 +175,7 @@ async def test_mutate_rows_attempt_exception(self, exc_type): client = CrossSync.Mock() table = mock.Mock() table._request_path = {"table_name": "table"} + metric = ActiveOperationMetric("MUTATE_ROWS") table.app_profile_id = None entries = [self._make_mutation(), self._make_mutation()] operation_timeout = 0.05 @@ -174,7 +184,7 @@ async def test_mutate_rows_attempt_exception(self, exc_type): found_exc = None try: instance = self._make_one( - client, table, entries, operation_timeout, operation_timeout + client, table, entries, operation_timeout, operation_timeout, metric ) await instance._run_attempt() except Exception as e: @@ -198,6 +208,7 @@ async def test_mutate_rows_exception(self, exc_type): client = mock.Mock() table = mock.Mock() + metric = ActiveOperationMetric("MUTATE_ROWS") entries = [self._make_mutation(), self._make_mutation()] operation_timeout = 0.05 expected_cause = exc_type("abort") @@ -210,7 +221,7 @@ async def test_mutate_rows_exception(self, exc_type): found_exc = None try: instance = self._make_one( - client, table, entries, operation_timeout, operation_timeout + client, table, entries, operation_timeout, operation_timeout, metric ) await instance.start() except MutationsExceptionGroup as e: @@ -234,6 +245,7 @@ async def test_mutate_rows_exception_retryable_eventually_pass(self, exc_type): client = mock.Mock() table = mock.Mock() + metric = ActiveOperationMetric("MUTATE_ROWS") entries = [self._make_mutation()] operation_timeout = 1 expected_cause = exc_type("retry") @@ -250,6 +262,7 @@ async def test_mutate_rows_exception_retryable_eventually_pass(self, exc_type): entries, operation_timeout, operation_timeout, + metric, retryable_exceptions=(exc_type,), ) await instance.start() @@ -269,6 +282,7 @@ async def test_mutate_rows_incomplete_ignored(self): client = mock.Mock() table = mock.Mock() + metric = ActiveOperationMetric("MUTATE_ROWS") entries = [self._make_mutation()] operation_timeout = 0.05 with mock.patch.object( @@ -280,7 +294,7 @@ async def test_mutate_rows_incomplete_ignored(self): found_exc = None try: instance = self._make_one( - client, table, entries, operation_timeout, operation_timeout + client, table, entries, operation_timeout, operation_timeout, metric ) await instance.start() except MutationsExceptionGroup as e: diff --git a/packages/google-cloud-bigtable/tests/unit/data/_async/test__read_rows.py b/packages/google-cloud-bigtable/tests/unit/data/_async/test__read_rows.py index c806f8c814c8..24b92d2de5ad 100644 --- a/packages/google-cloud-bigtable/tests/unit/data/_async/test__read_rows.py +++ b/packages/google-cloud-bigtable/tests/unit/data/_async/test__read_rows.py @@ -17,6 +17,7 @@ import pytest from google.cloud.bigtable.data._cross_sync import CrossSync +from google.cloud.bigtable.data._metrics import ActiveOperationMetric __CROSS_SYNC_OUTPUT__ = "tests.unit.data._sync_autogen.test__read_rows" @@ -54,6 +55,7 @@ def test_ctor(self): expected_operation_timeout = 42 expected_request_timeout = 44 time_gen_mock = mock.Mock() + expected_metric = mock.Mock() subpath = "_async" if CrossSync.is_async else "_sync_autogen" with mock.patch( f"google.cloud.bigtable.data.{subpath}._read_rows._attempt_timeout_generator", @@ -64,6 +66,7 @@ def test_ctor(self): table, operation_timeout=expected_operation_timeout, attempt_timeout=expected_request_timeout, + metric=expected_metric, ) assert time_gen_mock.call_count == 1 time_gen_mock.assert_called_once_with( @@ -76,6 +79,7 @@ def test_ctor(self): assert instance.request.table_name == "test_table" assert instance.request.app_profile_id == table.app_profile_id assert instance.request.rows_limit == row_limit + assert instance._operation_metric == expected_metric @pytest.mark.parametrize( "in_keys,last_key,expected", @@ -264,7 +268,9 @@ async def mock_stream(): table = mock.Mock() table._request_path = {"table_name": "table_name"} table.app_profile_id = "app_profile_id" - instance = self._make_one(query, table, 10, 10) + instance = self._make_one( + query, table, 10, 10, ActiveOperationMetric("READ_ROWS") + ) assert instance._remaining_count == start_limit # read emit_num rows async for val in instance.chunk_stream(awaitable_stream()): @@ -303,7 +309,9 @@ async def mock_stream(): table = mock.Mock() table._request_path = {"table_name": "table_name"} table.app_profile_id = "app_profile_id" - instance = self._make_one(query, table, 10, 10) + instance = self._make_one( + query, table, 10, 10, ActiveOperationMetric("READ_ROWS") + ) assert instance._remaining_count == start_limit with pytest.raises(InvalidChunk) as e: # read emit_num rows @@ -329,7 +337,9 @@ async def mock_stream(): with mock.patch.object( self._get_target_class(), "_read_rows_attempt" ) as mock_attempt: - instance = self._make_one(mock.Mock(), mock.Mock(), 1, 1) + instance = self._make_one( + mock.Mock(), mock.Mock(), 1, 1, ActiveOperationMetric("READ_ROWS") + ) wrapped_gen = mock_stream() mock_attempt.return_value = wrapped_gen gen = instance.start_operation() diff --git a/packages/google-cloud-bigtable/tests/unit/data/_async/test_client.py b/packages/google-cloud-bigtable/tests/unit/data/_async/test_client.py index 391c38006df5..b0d67ecc2496 100644 --- a/packages/google-cloud-bigtable/tests/unit/data/_async/test_client.py +++ b/packages/google-cloud-bigtable/tests/unit/data/_async/test_client.py @@ -2010,9 +2010,21 @@ async def test_read_row(self): async with self._make_client() as client: table = client.get_table("instance", "table") row_key = b"test_1" - with mock.patch.object(table, "read_rows") as read_rows: + with mock.patch.object( + CrossSync, "_ReadRowsOperation" + ) as mock_op_constructor: + mock_op = mock.Mock() expected_result = object() - read_rows.side_effect = lambda *args, **kwargs: [expected_result] + + if CrossSync.is_async: + + async def mock_generator(): + yield expected_result + + mock_op.start_operation.return_value = mock_generator() + else: + mock_op.start_operation.return_value = [expected_result] + mock_op_constructor.return_value = mock_op expected_op_timeout = 8 expected_req_timeout = 4 row = await table.read_row( @@ -2021,16 +2033,17 @@ async def test_read_row(self): attempt_timeout=expected_req_timeout, ) assert row == expected_result - assert read_rows.call_count == 1 - args, kwargs = read_rows.call_args_list[0] + assert mock_op_constructor.call_count == 1 + args, kwargs = mock_op_constructor.call_args_list[0] assert kwargs["operation_timeout"] == expected_op_timeout assert kwargs["attempt_timeout"] == expected_req_timeout - assert len(args) == 1 + assert len(args) == 2 assert isinstance(args[0], ReadRowsQuery) query = args[0] assert query.row_keys == [row_key] assert query.row_ranges == [] assert query.limit == 1 + assert args[1] is table @CrossSync.pytest async def test_read_row_w_filter(self): @@ -2038,14 +2051,24 @@ async def test_read_row_w_filter(self): async with self._make_client() as client: table = client.get_table("instance", "table") row_key = b"test_1" - with mock.patch.object(table, "read_rows") as read_rows: + with mock.patch.object( + CrossSync, "_ReadRowsOperation" + ) as mock_op_constructor: + mock_op = mock.Mock() expected_result = object() - read_rows.side_effect = lambda *args, **kwargs: [expected_result] + + if CrossSync.is_async: + + async def mock_generator(): + yield expected_result + + mock_op.start_operation.return_value = mock_generator() + else: + mock_op.start_operation.return_value = [expected_result] + mock_op_constructor.return_value = mock_op expected_op_timeout = 8 expected_req_timeout = 4 - mock_filter = mock.Mock() - expected_filter = {"filter": "mock filter"} - mock_filter._to_dict.return_value = expected_filter + expected_filter = mock.Mock() row = await table.read_row( row_key, operation_timeout=expected_op_timeout, @@ -2053,11 +2076,11 @@ async def test_read_row_w_filter(self): row_filter=expected_filter, ) assert row == expected_result - assert read_rows.call_count == 1 - args, kwargs = read_rows.call_args_list[0] + assert mock_op_constructor.call_count == 1 + args, kwargs = mock_op_constructor.call_args_list[0] assert kwargs["operation_timeout"] == expected_op_timeout assert kwargs["attempt_timeout"] == expected_req_timeout - assert len(args) == 1 + assert len(args) == 2 assert isinstance(args[0], ReadRowsQuery) query = args[0] assert query.row_keys == [row_key] @@ -2071,9 +2094,21 @@ async def test_read_row_no_response(self): async with self._make_client() as client: table = client.get_table("instance", "table") row_key = b"test_1" - with mock.patch.object(table, "read_rows") as read_rows: - # return no rows - read_rows.side_effect = lambda *args, **kwargs: [] + with mock.patch.object( + CrossSync, "_ReadRowsOperation" + ) as mock_op_constructor: + mock_op = mock.Mock() + + if CrossSync.is_async: + + async def mock_generator(): + if False: + yield + + mock_op.start_operation.return_value = mock_generator() + else: + mock_op.start_operation.return_value = [] + mock_op_constructor.return_value = mock_op expected_op_timeout = 8 expected_req_timeout = 4 result = await table.read_row( @@ -2082,8 +2117,8 @@ async def test_read_row_no_response(self): attempt_timeout=expected_req_timeout, ) assert result is None - assert read_rows.call_count == 1 - args, kwargs = read_rows.call_args_list[0] + assert mock_op_constructor.call_count == 1 + args, kwargs = mock_op_constructor.call_args_list[0] assert kwargs["operation_timeout"] == expected_op_timeout assert kwargs["attempt_timeout"] == expected_req_timeout assert isinstance(args[0], ReadRowsQuery) @@ -2106,22 +2141,36 @@ async def test_row_exists(self, return_value, expected_result): async with self._make_client() as client: table = client.get_table("instance", "table") row_key = b"test_1" - with mock.patch.object(table, "read_rows") as read_rows: - # return no rows - read_rows.side_effect = lambda *args, **kwargs: return_value - expected_op_timeout = 1 - expected_req_timeout = 2 + with mock.patch.object( + CrossSync, "_ReadRowsOperation" + ) as mock_op_constructor: + mock_op = mock.Mock() + if CrossSync.is_async: + + async def mock_generator(): + for item in return_value: + yield item + + mock_op.start_operation.return_value = mock_generator() + else: + mock_op.start_operation.return_value = return_value + mock_op_constructor.return_value = mock_op + expected_op_timeout = 2 + expected_req_timeout = 1 result = await table.row_exists( row_key, operation_timeout=expected_op_timeout, attempt_timeout=expected_req_timeout, ) assert expected_result == result - assert read_rows.call_count == 1 - args, kwargs = read_rows.call_args_list[0] + assert mock_op_constructor.call_count == 1 + args, kwargs = mock_op_constructor.call_args_list[0] assert kwargs["operation_timeout"] == expected_op_timeout assert kwargs["attempt_timeout"] == expected_req_timeout - assert isinstance(args[0], ReadRowsQuery) + query = args[0] + assert isinstance(query, ReadRowsQuery) + assert query.row_keys == [row_key] + assert query.limit == 1 expected_filter = { "chain": { "filters": [ @@ -2130,10 +2179,6 @@ async def test_row_exists(self, return_value, expected_result): ] } } - query = args[0] - assert query.row_keys == [row_key] - assert query.row_ranges == [] - assert query.limit == 1 assert query.filter._to_dict() == expected_filter diff --git a/packages/google-cloud-bigtable/tests/unit/data/_async/test_mutations_batcher.py b/packages/google-cloud-bigtable/tests/unit/data/_async/test_mutations_batcher.py index 75de7c281332..ff5a6b1123dd 100644 --- a/packages/google-cloud-bigtable/tests/unit/data/_async/test_mutations_batcher.py +++ b/packages/google-cloud-bigtable/tests/unit/data/_async/test_mutations_batcher.py @@ -307,6 +307,10 @@ def _get_target_class(self): def _make_one(self, table=None, **kwargs): from google.api_core.exceptions import DeadlineExceeded, ServiceUnavailable + from google.cloud.bigtable.data._metrics import ( + BigtableClientSideMetricsController, + ) + if table is None: table = mock.Mock() table._request_path = {"table_name": "table"} @@ -317,6 +321,7 @@ def _make_one(self, table=None, **kwargs): DeadlineExceeded, ServiceUnavailable, ) + table._metrics = BigtableClientSideMetricsController([]) return self._get_target_class()(table, **kwargs) @@ -935,14 +940,16 @@ async def test__execute_mutate_rows(self): table.default_mutate_rows_retryable_errors = () async with self._make_one(table) as instance: batch = [self._make_mutation()] - result = await instance._execute_mutate_rows(batch) + expected_metric = mock.Mock() + result = await instance._execute_mutate_rows(batch, expected_metric) assert start_operation.call_count == 1 args, kwargs = mutate_rows.call_args assert args[0] == table.client._gapic_client assert args[1] == table assert args[2] == batch - kwargs["operation_timeout"] == 17 - kwargs["attempt_timeout"] == 13 + assert kwargs["operation_timeout"] == 17 + assert kwargs["attempt_timeout"] == 13 + assert kwargs["metric"] == expected_metric assert result == [] @CrossSync.pytest @@ -963,7 +970,7 @@ async def test__execute_mutate_rows_returns_errors(self): table.default_mutate_rows_retryable_errors = () async with self._make_one(table) as instance: batch = [self._make_mutation()] - result = await instance._execute_mutate_rows(batch) + result = await instance._execute_mutate_rows(batch, mock.Mock()) assert len(result) == 2 assert result[0] == err1 assert result[1] == err2 @@ -1093,7 +1100,9 @@ async def test_timeout_args_passed(self): assert instance._operation_timeout == expected_operation_timeout assert instance._attempt_timeout == expected_attempt_timeout # make simulated gapic call - await instance._execute_mutate_rows([self._make_mutation()]) + await instance._execute_mutate_rows( + [self._make_mutation()], mock.Mock() + ) assert mutate_rows.call_count == 1 kwargs = mutate_rows.call_args[1] assert kwargs["operation_timeout"] == expected_operation_timeout @@ -1192,6 +1201,8 @@ async def test_customizable_retryable_errors( Test that retryable functions support user-configurable arguments, and that the configured retryables are passed down to the gapic layer. """ + from google.cloud.bigtable.data._metrics import ActiveOperationMetric + with mock.patch.object( google.api_core.retry, "if_exception_type" ) as predicate_builder_mock: @@ -1207,14 +1218,16 @@ async def test_customizable_retryable_errors( predicate_builder_mock.return_value = expected_predicate retry_fn_mock.side_effect = RuntimeError("stop early") mutation = self._make_mutation(count=1, size=1) - await instance._execute_mutate_rows([mutation]) + await instance._execute_mutate_rows( + [mutation], ActiveOperationMetric("MUTATE_ROWS") + ) # passed in errors should be used to build the predicate predicate_builder_mock.assert_called_once_with( *expected_retryables, _MutateRowsIncomplete ) - retry_call_args = retry_fn_mock.call_args_list[0].args + retry_call_kwargs = retry_fn_mock.call_args_list[0].kwargs # output of if_exception_type should be sent in to retry constructor - assert retry_call_args[1] is expected_predicate + assert retry_call_kwargs["predicate"] is expected_predicate @CrossSync.pytest async def test_large_batch_write(self): diff --git a/packages/google-cloud-bigtable/tests/unit/data/_async/test_read_rows_acceptance.py b/packages/google-cloud-bigtable/tests/unit/data/_async/test_read_rows_acceptance.py index d69b776bfe42..53689c9c33f7 100644 --- a/packages/google-cloud-bigtable/tests/unit/data/_async/test_read_rows_acceptance.py +++ b/packages/google-cloud-bigtable/tests/unit/data/_async/test_read_rows_acceptance.py @@ -21,6 +21,7 @@ import pytest from google.cloud.bigtable.data._cross_sync import CrossSync +from google.cloud.bigtable.data._metrics import ActiveOperationMetric from google.cloud.bigtable.data.exceptions import InvalidChunk from google.cloud.bigtable.data.row import Row from google.cloud.bigtable_v2 import ReadRowsResponse @@ -36,8 +37,11 @@ class TestReadRowsAcceptanceAsync: @staticmethod @CrossSync.convert - def _get_operation_class(): - return CrossSync._ReadRowsOperation + def _make_operation(): + metric = ActiveOperationMetric("READ_ROWS") + op = CrossSync._ReadRowsOperation(mock.Mock(), mock.Mock(), 5, 5, metric) + op._remaining_count = None + return op @staticmethod @CrossSync.convert @@ -80,13 +84,8 @@ async def _process_chunks(self, *chunks): async def _row_stream(): yield ReadRowsResponse(chunks=chunks) - instance = mock.Mock() - instance._remaining_count = None - instance._last_yielded_row_key = None - chunker = self._get_operation_class().chunk_stream( - instance, self._coro_wrapper(_row_stream()) - ) - merger = self._get_operation_class().merge_rows(chunker) + chunker = self._make_operation().chunk_stream(self._coro_wrapper(_row_stream())) + merger = self._make_operation().merge_rows(chunker) results = [] async for row in merger: results.append(row) @@ -103,13 +102,10 @@ async def _scenerio_stream(): try: results = [] - instance = mock.Mock() - instance._last_yielded_row_key = None - instance._remaining_count = None - chunker = self._get_operation_class().chunk_stream( - instance, self._coro_wrapper(_scenerio_stream()) + chunker = self._make_operation().chunk_stream( + self._coro_wrapper(_scenerio_stream()) ) - merger = self._get_operation_class().merge_rows(chunker) + merger = self._make_operation().merge_rows(chunker) async for row in merger: for cell in row: cell_result = ReadRowsTest.Result( @@ -196,13 +192,10 @@ async def test_out_of_order_rows(self): async def _row_stream(): yield ReadRowsResponse(last_scanned_row_key=b"a") - instance = mock.Mock() - instance._remaining_count = None - instance._last_yielded_row_key = b"b" - chunker = self._get_operation_class().chunk_stream( - instance, self._coro_wrapper(_row_stream()) - ) - merger = self._get_operation_class().merge_rows(chunker) + op = self._make_operation() + op._last_yielded_row_key = b"b" + chunker = op.chunk_stream(self._coro_wrapper(_row_stream())) + merger = self._make_operation().merge_rows(chunker) with pytest.raises(InvalidChunk): async for _ in merger: pass diff --git a/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test__mutate_rows.py b/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test__mutate_rows.py index c1b993f7d337..2fe86a41fef0 100644 --- a/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test__mutate_rows.py +++ b/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test__mutate_rows.py @@ -22,6 +22,7 @@ from google.rpc import status_pb2 from google.cloud.bigtable.data._cross_sync import CrossSync +from google.cloud.bigtable.data._metrics import ActiveOperationMetric from google.cloud.bigtable.data.mutations import DeleteAllFromRow, RowMutationEntry from google.cloud.bigtable_v2.types import MutateRowsResponse @@ -41,6 +42,9 @@ def _make_one(self, *args, **kwargs): kwargs["attempt_timeout"] = kwargs.pop("attempt_timeout", 0.1) kwargs["retryable_exceptions"] = kwargs.pop("retryable_exceptions", ()) kwargs["mutation_entries"] = kwargs.pop("mutation_entries", []) + kwargs["metric"] = kwargs.pop( + "metric", ActiveOperationMetric("MUTATE_ROWS") + ) return self._target_class()(*args, **kwargs) def _make_mutation(self, count=1, size=1): @@ -80,6 +84,7 @@ def test_ctor(self): entries = [self._make_mutation(), self._make_mutation()] operation_timeout = 0.05 attempt_timeout = 0.01 + metric = mock.Mock() retryable_exceptions = () instance = self._make_one( client, @@ -87,6 +92,7 @@ def test_ctor(self): entries, operation_timeout, attempt_timeout, + metric, retryable_exceptions, ) assert client.mutate_rows.call_count == 0 @@ -102,6 +108,7 @@ def test_ctor(self): assert instance.is_retryable(RuntimeError("")) is False assert instance.remaining_indices == list(range(len(entries))) assert instance.errors == {} + assert instance._operation_metric == metric def test_ctor_too_many_entries(self): """should raise an error if an operation is created with more than 100,000 entries""" @@ -116,7 +123,9 @@ def test_ctor_too_many_entries(self): operation_timeout = 0.05 attempt_timeout = 0.01 with pytest.raises(ValueError) as e: - self._make_one(client, table, entries, operation_timeout, attempt_timeout) + self._make_one( + client, table, entries, operation_timeout, attempt_timeout, mock.Mock() + ) assert "mutate_rows requests can contain at most 100000 mutations" in str( e.value ) @@ -126,6 +135,7 @@ def test_mutate_rows_operation(self): """Test successful case of mutate_rows_operation""" client = mock.Mock() table = mock.Mock() + metric = ActiveOperationMetric("MUTATE_ROWS") entries = [self._make_mutation(), self._make_mutation()] operation_timeout = 0.05 cls = self._target_class() @@ -133,7 +143,7 @@ def test_mutate_rows_operation(self): f"{cls.__module__}.{cls.__name__}._run_attempt", CrossSync._Sync_Impl.Mock() ) as attempt_mock: instance = self._make_one( - client, table, entries, operation_timeout, operation_timeout + client, table, entries, operation_timeout, operation_timeout, metric ) instance.start() assert attempt_mock.call_count == 1 @@ -144,6 +154,7 @@ def test_mutate_rows_attempt_exception(self, exc_type): client = CrossSync._Sync_Impl.Mock() table = mock.Mock() table._request_path = {"table_name": "table"} + metric = ActiveOperationMetric("MUTATE_ROWS") table.app_profile_id = None entries = [self._make_mutation(), self._make_mutation()] operation_timeout = 0.05 @@ -152,7 +163,7 @@ def test_mutate_rows_attempt_exception(self, exc_type): found_exc = None try: instance = self._make_one( - client, table, entries, operation_timeout, operation_timeout + client, table, entries, operation_timeout, operation_timeout, metric ) instance._run_attempt() except Exception as e: @@ -173,6 +184,7 @@ def test_mutate_rows_exception(self, exc_type): client = mock.Mock() table = mock.Mock() + metric = ActiveOperationMetric("MUTATE_ROWS") entries = [self._make_mutation(), self._make_mutation()] operation_timeout = 0.05 expected_cause = exc_type("abort") @@ -183,7 +195,7 @@ def test_mutate_rows_exception(self, exc_type): found_exc = None try: instance = self._make_one( - client, table, entries, operation_timeout, operation_timeout + client, table, entries, operation_timeout, operation_timeout, metric ) instance.start() except MutationsExceptionGroup as e: @@ -200,6 +212,7 @@ def test_mutate_rows_exception_retryable_eventually_pass(self, exc_type): """If an exception fails but eventually passes, it should not raise an exception""" client = mock.Mock() table = mock.Mock() + metric = ActiveOperationMetric("MUTATE_ROWS") entries = [self._make_mutation()] operation_timeout = 1 expected_cause = exc_type("retry") @@ -214,6 +227,7 @@ def test_mutate_rows_exception_retryable_eventually_pass(self, exc_type): entries, operation_timeout, operation_timeout, + metric, retryable_exceptions=(exc_type,), ) instance.start() @@ -230,6 +244,7 @@ def test_mutate_rows_incomplete_ignored(self): client = mock.Mock() table = mock.Mock() + metric = ActiveOperationMetric("MUTATE_ROWS") entries = [self._make_mutation()] operation_timeout = 0.05 with mock.patch.object( @@ -239,7 +254,7 @@ def test_mutate_rows_incomplete_ignored(self): found_exc = None try: instance = self._make_one( - client, table, entries, operation_timeout, operation_timeout + client, table, entries, operation_timeout, operation_timeout, metric ) instance.start() except MutationsExceptionGroup as e: diff --git a/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test__read_rows.py b/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test__read_rows.py index 7e1e0e47d5ce..b6cac9cafbc0 100644 --- a/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test__read_rows.py +++ b/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test__read_rows.py @@ -20,6 +20,7 @@ import pytest from google.cloud.bigtable.data._cross_sync import CrossSync +from google.cloud.bigtable.data._metrics import ActiveOperationMetric class TestReadRowsOperation: @@ -51,6 +52,7 @@ def test_ctor(self): expected_operation_timeout = 42 expected_request_timeout = 44 time_gen_mock = mock.Mock() + expected_metric = mock.Mock() subpath = "_async" if CrossSync._Sync_Impl.is_async else "_sync_autogen" with mock.patch( f"google.cloud.bigtable.data.{subpath}._read_rows._attempt_timeout_generator", @@ -61,6 +63,7 @@ def test_ctor(self): table, operation_timeout=expected_operation_timeout, attempt_timeout=expected_request_timeout, + metric=expected_metric, ) assert time_gen_mock.call_count == 1 time_gen_mock.assert_called_once_with( @@ -73,6 +76,7 @@ def test_ctor(self): assert instance.request.table_name == "test_table" assert instance.request.app_profile_id == table.app_profile_id assert instance.request.rows_limit == row_limit + assert instance._operation_metric == expected_metric @pytest.mark.parametrize( "in_keys,last_key,expected", @@ -251,7 +255,9 @@ def mock_stream(): table = mock.Mock() table._request_path = {"table_name": "table_name"} table.app_profile_id = "app_profile_id" - instance = self._make_one(query, table, 10, 10) + instance = self._make_one( + query, table, 10, 10, ActiveOperationMetric("READ_ROWS") + ) assert instance._remaining_count == start_limit for val in instance.chunk_stream(awaitable_stream()): pass @@ -286,7 +292,9 @@ def mock_stream(): table = mock.Mock() table._request_path = {"table_name": "table_name"} table.app_profile_id = "app_profile_id" - instance = self._make_one(query, table, 10, 10) + instance = self._make_one( + query, table, 10, 10, ActiveOperationMetric("READ_ROWS") + ) assert instance._remaining_count == start_limit with pytest.raises(InvalidChunk) as e: for val in instance.chunk_stream(awaitable_stream()): @@ -304,7 +312,9 @@ def mock_stream(): with mock.patch.object( self._get_target_class(), "_read_rows_attempt" ) as mock_attempt: - instance = self._make_one(mock.Mock(), mock.Mock(), 1, 1) + instance = self._make_one( + mock.Mock(), mock.Mock(), 1, 1, ActiveOperationMetric("READ_ROWS") + ) wrapped_gen = mock_stream() mock_attempt.return_value = wrapped_gen gen = instance.start_operation() diff --git a/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_client.py b/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_client.py index f8edea5e1a32..e5041161b0fc 100644 --- a/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_client.py +++ b/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_client.py @@ -1674,9 +1674,13 @@ def test_read_row(self): with self._make_client() as client: table = client.get_table("instance", "table") row_key = b"test_1" - with mock.patch.object(table, "read_rows") as read_rows: + with mock.patch.object( + CrossSync._Sync_Impl, "_ReadRowsOperation" + ) as mock_op_constructor: + mock_op = mock.Mock() expected_result = object() - read_rows.side_effect = lambda *args, **kwargs: [expected_result] + mock_op.start_operation.return_value = [expected_result] + mock_op_constructor.return_value = mock_op expected_op_timeout = 8 expected_req_timeout = 4 row = table.read_row( @@ -1685,30 +1689,33 @@ def test_read_row(self): attempt_timeout=expected_req_timeout, ) assert row == expected_result - assert read_rows.call_count == 1 - args, kwargs = read_rows.call_args_list[0] + assert mock_op_constructor.call_count == 1 + args, kwargs = mock_op_constructor.call_args_list[0] assert kwargs["operation_timeout"] == expected_op_timeout assert kwargs["attempt_timeout"] == expected_req_timeout - assert len(args) == 1 + assert len(args) == 2 assert isinstance(args[0], ReadRowsQuery) query = args[0] assert query.row_keys == [row_key] assert query.row_ranges == [] assert query.limit == 1 + assert args[1] is table def test_read_row_w_filter(self): """Test reading a single row with an added filter""" with self._make_client() as client: table = client.get_table("instance", "table") row_key = b"test_1" - with mock.patch.object(table, "read_rows") as read_rows: + with mock.patch.object( + CrossSync._Sync_Impl, "_ReadRowsOperation" + ) as mock_op_constructor: + mock_op = mock.Mock() expected_result = object() - read_rows.side_effect = lambda *args, **kwargs: [expected_result] + mock_op.start_operation.return_value = [expected_result] + mock_op_constructor.return_value = mock_op expected_op_timeout = 8 expected_req_timeout = 4 - mock_filter = mock.Mock() - expected_filter = {"filter": "mock filter"} - mock_filter._to_dict.return_value = expected_filter + expected_filter = mock.Mock() row = table.read_row( row_key, operation_timeout=expected_op_timeout, @@ -1716,11 +1723,11 @@ def test_read_row_w_filter(self): row_filter=expected_filter, ) assert row == expected_result - assert read_rows.call_count == 1 - args, kwargs = read_rows.call_args_list[0] + assert mock_op_constructor.call_count == 1 + args, kwargs = mock_op_constructor.call_args_list[0] assert kwargs["operation_timeout"] == expected_op_timeout assert kwargs["attempt_timeout"] == expected_req_timeout - assert len(args) == 1 + assert len(args) == 2 assert isinstance(args[0], ReadRowsQuery) query = args[0] assert query.row_keys == [row_key] @@ -1733,8 +1740,12 @@ def test_read_row_no_response(self): with self._make_client() as client: table = client.get_table("instance", "table") row_key = b"test_1" - with mock.patch.object(table, "read_rows") as read_rows: - read_rows.side_effect = lambda *args, **kwargs: [] + with mock.patch.object( + CrossSync._Sync_Impl, "_ReadRowsOperation" + ) as mock_op_constructor: + mock_op = mock.Mock() + mock_op.start_operation.return_value = [] + mock_op_constructor.return_value = mock_op expected_op_timeout = 8 expected_req_timeout = 4 result = table.read_row( @@ -1743,8 +1754,8 @@ def test_read_row_no_response(self): attempt_timeout=expected_req_timeout, ) assert result is None - assert read_rows.call_count == 1 - args, kwargs = read_rows.call_args_list[0] + assert mock_op_constructor.call_count == 1 + args, kwargs = mock_op_constructor.call_args_list[0] assert kwargs["operation_timeout"] == expected_op_timeout assert kwargs["attempt_timeout"] == expected_req_timeout assert isinstance(args[0], ReadRowsQuery) @@ -1762,21 +1773,28 @@ def test_row_exists(self, return_value, expected_result): with self._make_client() as client: table = client.get_table("instance", "table") row_key = b"test_1" - with mock.patch.object(table, "read_rows") as read_rows: - read_rows.side_effect = lambda *args, **kwargs: return_value - expected_op_timeout = 1 - expected_req_timeout = 2 + with mock.patch.object( + CrossSync._Sync_Impl, "_ReadRowsOperation" + ) as mock_op_constructor: + mock_op = mock.Mock() + mock_op.start_operation.return_value = return_value + mock_op_constructor.return_value = mock_op + expected_op_timeout = 2 + expected_req_timeout = 1 result = table.row_exists( row_key, operation_timeout=expected_op_timeout, attempt_timeout=expected_req_timeout, ) assert expected_result == result - assert read_rows.call_count == 1 - args, kwargs = read_rows.call_args_list[0] + assert mock_op_constructor.call_count == 1 + args, kwargs = mock_op_constructor.call_args_list[0] assert kwargs["operation_timeout"] == expected_op_timeout assert kwargs["attempt_timeout"] == expected_req_timeout - assert isinstance(args[0], ReadRowsQuery) + query = args[0] + assert isinstance(query, ReadRowsQuery) + assert query.row_keys == [row_key] + assert query.limit == 1 expected_filter = { "chain": { "filters": [ @@ -1785,10 +1803,6 @@ def test_row_exists(self, return_value, expected_result): ] } } - query = args[0] - assert query.row_keys == [row_key] - assert query.row_ranges == [] - assert query.limit == 1 assert query.filter._to_dict() == expected_filter diff --git a/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_mutations_batcher.py b/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_mutations_batcher.py index f6568448ff8c..bf54a44ad35b 100644 --- a/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_mutations_batcher.py +++ b/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_mutations_batcher.py @@ -258,6 +258,10 @@ def _get_target_class(self): def _make_one(self, table=None, **kwargs): from google.api_core.exceptions import DeadlineExceeded, ServiceUnavailable + from google.cloud.bigtable.data._metrics import ( + BigtableClientSideMetricsController, + ) + if table is None: table = mock.Mock() table._request_path = {"table_name": "table"} @@ -268,6 +272,7 @@ def _make_one(self, table=None, **kwargs): DeadlineExceeded, ServiceUnavailable, ) + table._metrics = BigtableClientSideMetricsController([]) return self._get_target_class()(table, **kwargs) @staticmethod @@ -816,14 +821,16 @@ def test__execute_mutate_rows(self): table.default_mutate_rows_retryable_errors = () with self._make_one(table) as instance: batch = [self._make_mutation()] - result = instance._execute_mutate_rows(batch) + expected_metric = mock.Mock() + result = instance._execute_mutate_rows(batch, expected_metric) assert start_operation.call_count == 1 args, kwargs = mutate_rows.call_args assert args[0] == table.client._gapic_client assert args[1] == table assert args[2] == batch - kwargs["operation_timeout"] == 17 - kwargs["attempt_timeout"] == 13 + assert kwargs["operation_timeout"] == 17 + assert kwargs["attempt_timeout"] == 13 + assert kwargs["metric"] == expected_metric assert result == [] def test__execute_mutate_rows_returns_errors(self): @@ -845,7 +852,7 @@ def test__execute_mutate_rows_returns_errors(self): table.default_mutate_rows_retryable_errors = () with self._make_one(table) as instance: batch = [self._make_mutation()] - result = instance._execute_mutate_rows(batch) + result = instance._execute_mutate_rows(batch, mock.Mock()) assert len(result) == 2 assert result[0] == err1 assert result[1] == err2 @@ -953,7 +960,7 @@ def test_timeout_args_passed(self): ) as instance: assert instance._operation_timeout == expected_operation_timeout assert instance._attempt_timeout == expected_attempt_timeout - instance._execute_mutate_rows([self._make_mutation()]) + instance._execute_mutate_rows([self._make_mutation()], mock.Mock()) assert mutate_rows.call_count == 1 kwargs = mutate_rows.call_args[1] assert kwargs["operation_timeout"] == expected_operation_timeout @@ -1039,6 +1046,8 @@ def test__add_exceptions(self, limit, in_e, start_e, end_e): def test_customizable_retryable_errors(self, input_retryables, expected_retryables): """Test that retryable functions support user-configurable arguments, and that the configured retryables are passed down to the gapic layer.""" + from google.cloud.bigtable.data._metrics import ActiveOperationMetric + with mock.patch.object( google.api_core.retry, "if_exception_type" ) as predicate_builder_mock: @@ -1056,12 +1065,14 @@ def test_customizable_retryable_errors(self, input_retryables, expected_retryabl predicate_builder_mock.return_value = expected_predicate retry_fn_mock.side_effect = RuntimeError("stop early") mutation = self._make_mutation(count=1, size=1) - instance._execute_mutate_rows([mutation]) + instance._execute_mutate_rows( + [mutation], ActiveOperationMetric("MUTATE_ROWS") + ) predicate_builder_mock.assert_called_once_with( *expected_retryables, _MutateRowsIncomplete ) - retry_call_args = retry_fn_mock.call_args_list[0].args - assert retry_call_args[1] is expected_predicate + retry_call_kwargs = retry_fn_mock.call_args_list[0].kwargs + assert retry_call_kwargs["predicate"] is expected_predicate def test_large_batch_write(self): """Test that a large batch of mutations can be written""" diff --git a/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_read_rows_acceptance.py b/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_read_rows_acceptance.py index 29332e712d35..77c55ce0183b 100644 --- a/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_read_rows_acceptance.py +++ b/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_read_rows_acceptance.py @@ -24,6 +24,7 @@ import pytest from google.cloud.bigtable.data._cross_sync import CrossSync +from google.cloud.bigtable.data._metrics import ActiveOperationMetric from google.cloud.bigtable.data.exceptions import InvalidChunk from google.cloud.bigtable.data.row import Row from google.cloud.bigtable_v2 import ReadRowsResponse @@ -33,8 +34,13 @@ class TestReadRowsAcceptance: @staticmethod - def _get_operation_class(): - return CrossSync._Sync_Impl._ReadRowsOperation + def _make_operation(): + metric = ActiveOperationMetric("READ_ROWS") + op = CrossSync._Sync_Impl._ReadRowsOperation( + mock.Mock(), mock.Mock(), 5, 5, metric + ) + op._remaining_count = None + return op @staticmethod def _get_client_class(): @@ -72,13 +78,8 @@ def _process_chunks(self, *chunks): def _row_stream(): yield ReadRowsResponse(chunks=chunks) - instance = mock.Mock() - instance._remaining_count = None - instance._last_yielded_row_key = None - chunker = self._get_operation_class().chunk_stream( - instance, self._coro_wrapper(_row_stream()) - ) - merger = self._get_operation_class().merge_rows(chunker) + chunker = self._make_operation().chunk_stream(self._coro_wrapper(_row_stream())) + merger = self._make_operation().merge_rows(chunker) results = [] for row in merger: results.append(row) @@ -94,13 +95,10 @@ def _scenerio_stream(): try: results = [] - instance = mock.Mock() - instance._last_yielded_row_key = None - instance._remaining_count = None - chunker = self._get_operation_class().chunk_stream( - instance, self._coro_wrapper(_scenerio_stream()) + chunker = self._make_operation().chunk_stream( + self._coro_wrapper(_scenerio_stream()) ) - merger = self._get_operation_class().merge_rows(chunker) + merger = self._make_operation().merge_rows(chunker) for row in merger: for cell in row: cell_result = ReadRowsTest.Result( @@ -183,13 +181,10 @@ def test_out_of_order_rows(self): def _row_stream(): yield ReadRowsResponse(last_scanned_row_key=b"a") - instance = mock.Mock() - instance._remaining_count = None - instance._last_yielded_row_key = b"b" - chunker = self._get_operation_class().chunk_stream( - instance, self._coro_wrapper(_row_stream()) - ) - merger = self._get_operation_class().merge_rows(chunker) + op = self._make_operation() + op._last_yielded_row_key = b"b" + chunker = op.chunk_stream(self._coro_wrapper(_row_stream())) + merger = self._make_operation().merge_rows(chunker) with pytest.raises(InvalidChunk): for _ in merger: pass From 35af6168c19dd6f114dd67a8bfdcd0ff8fe3bdf9 Mon Sep 17 00:00:00 2001 From: nbayati <99771966+nbayati@users.noreply.github.com> Date: Fri, 5 Jun 2026 09:09:45 -0700 Subject: [PATCH 034/174] feat(auth): implement regional access boundary support for standalone JWT and async service accounts (#17025) This PR implements the following changes: - Add RAB support to async service account and jwt credential types, by providing async manager and fetching methods. - Update unit tests to accept both mtls and standard lookup endpoint urls. - Refactor before_request to use a _after_refresh hook so we don't have to override the method. - Add RAb support for self signed jwt flow through jwt.py - some small enhancements for test coverage and backward compatibility --- .../google/auth/_credentials_async.py | 92 ++++++++ packages/google-auth/google/auth/_helpers.py | 2 + .../google-auth/google/auth/_jwt_async.py | 18 +- .../auth/_regional_access_boundary_utils.py | 198 +++++++++++++++- .../google/auth/compute_engine/_metadata.py | 20 ++ .../google/auth/compute_engine/credentials.py | 34 ++- .../google-auth/google/auth/credentials.py | 105 ++++++--- .../google/auth/external_account.py | 20 +- .../auth/external_account_authorized_user.py | 6 +- packages/google-auth/google/auth/iam.py | 10 +- .../google/auth/impersonated_credentials.py | 5 +- packages/google-auth/google/auth/jwt.py | 34 ++- packages/google-auth/google/oauth2/_client.py | 2 +- .../google/oauth2/_client_async.py | 164 ++++++++++++++ .../google/oauth2/_service_account_async.py | 28 +-- .../google/oauth2/service_account.py | 5 +- .../tests/compute_engine/test__metadata.py | 25 +++ .../tests/compute_engine/test_credentials.py | 109 ++++++++- .../google-auth/tests/oauth2/test__client.py | 29 ++- .../tests/oauth2/test_service_account.py | 64 +++++- .../test__regional_access_boundary_utils.py | 211 +++++++++++++++++- .../google-auth/tests/test_credentials.py | 29 +++ .../tests/test_external_account.py | 189 +++++++++++----- .../test_external_account_authorized_user.py | 19 +- .../tests/test_impersonated_credentials.py | 24 +- packages/google-auth/tests/test_jwt.py | 51 +++++ .../tests_async/oauth2/test__client_async.py | 179 ++++++++++++++- .../oauth2/test_service_account_async.py | 137 ++++++++++++ .../test__regional_access_boundary_utils.py | 84 +++++++ .../google-auth/tests_async/test_jwt_async.py | 50 ++++- 30 files changed, 1769 insertions(+), 174 deletions(-) create mode 100644 packages/google-auth/tests_async/test__regional_access_boundary_utils.py diff --git a/packages/google-auth/google/auth/_credentials_async.py b/packages/google-auth/google/auth/_credentials_async.py index 760758d851b0..937f6e8fb6df 100644 --- a/packages/google-auth/google/auth/_credentials_async.py +++ b/packages/google-auth/google/auth/_credentials_async.py @@ -18,6 +18,7 @@ import abc import inspect +from google.auth import _regional_access_boundary_utils from google.auth import credentials @@ -64,8 +65,28 @@ async def before_request(self, request, method, url, headers): await self.refresh(request) else: self.refresh(request) + + if inspect.iscoroutinefunction(self._after_refresh): + await self._after_refresh(request, method, url, headers) + else: + self._after_refresh(request, method, url, headers) + self.apply(headers) + def _after_refresh(self, request, method, url, headers): + """Hook for subclasses to perform actions after refresh but before + applying credentials to headers. + + Args: + request (google.auth.transport.Request): The object used to make + HTTP requests. + method (str): The request's HTTP method or the RPC method being + invoked. + url (str): The request's URI or the RPC service's URI. + headers (Mapping[str, str]): The request's headers. + """ + pass + class CredentialsWithQuotaProject(credentials.CredentialsWithQuotaProject): """Abstract base for credentials supporting ``with_quota_project`` factory""" @@ -169,3 +190,74 @@ def with_scopes_if_required(credentials, scopes): class Signing(credentials.Signing, metaclass=abc.ABCMeta): """Interface for credentials that can cryptographically sign messages.""" + + +class CredentialsWithRegionalAccessBoundary( + Credentials, credentials.CredentialsWithRegionalAccessBoundary +): + """Async base for credentials supporting regional access boundary configuration.""" + + def __init__(self): + super().__init__() + self._rab_manager.refresh_manager = ( + _regional_access_boundary_utils._AsyncRegionalAccessBoundaryRefreshManager() + ) + + def __setstate__(self, state): + super().__setstate__(state) + self._rab_manager.refresh_manager = ( + _regional_access_boundary_utils._AsyncRegionalAccessBoundaryRefreshManager() + ) + + async def _after_refresh(self, request, method, url, headers): + """Triggers the Regional Access Boundary lookup asynchronously if necessary.""" + await self._maybe_start_regional_access_boundary_refresh_async(request, url) + + async def _maybe_start_regional_access_boundary_refresh_async(self, request, url): + """Starts a background refresh or performs a blocking refresh asynchronously. + + Args: + request (google.auth.aio.transport.Request): The object used to make + HTTP requests. + url (str): The URL of the request. + """ + # Do not perform a lookup if the request is for a regional endpoint. + if self._is_regional_endpoint(url): + return + + # A refresh is only needed if the feature is enabled. + if not self._is_regional_access_boundary_lookup_required(): + return + + # Trigger background or blocking refresh if needed. + await self._rab_manager.maybe_start_refresh_async(self, request) + + async def _lookup_regional_access_boundary(self, request, fail_fast=False): + """Calls the Regional Access Boundary lookup API asynchronously. + + Args: + request (google.auth.aio.transport.Request): The object used to make + HTTP requests. + fail_fast (bool): Whether the lookup should fail fast (short timeout, no retries). + + Returns: + Optional[Dict[str, str]]: The Regional Access Boundary information + returned by the lookup API, or None if the lookup failed. + """ + url_builder = self._build_regional_access_boundary_lookup_url + if inspect.iscoroutinefunction(url_builder): + url = await url_builder(request=request) + else: + url = url_builder(request=request) + + if not url: + return None + + headers = {} + self._apply(headers) + + from google.oauth2 import _client_async + + return await _client_async._lookup_regional_access_boundary( + request, url, headers=headers, fail_fast=fail_fast + ) diff --git a/packages/google-auth/google/auth/_helpers.py b/packages/google-auth/google/auth/_helpers.py index 08146221503e..86c48c1e525c 100644 --- a/packages/google-auth/google/auth/_helpers.py +++ b/packages/google-auth/google/auth/_helpers.py @@ -28,6 +28,8 @@ from google.auth import exceptions +DEFAULT_UNIVERSE_DOMAIN = "googleapis.com" + # _BASE_LOGGER_NAME is the base logger for all google-based loggers. _BASE_LOGGER_NAME = "google" diff --git a/packages/google-auth/google/auth/_jwt_async.py b/packages/google-auth/google/auth/_jwt_async.py index 3a1abc5b85c9..ce3bfe4eba57 100644 --- a/packages/google-auth/google/auth/_jwt_async.py +++ b/packages/google-auth/google/auth/_jwt_async.py @@ -44,6 +44,8 @@ """ from google.auth import _credentials_async +from google.auth import _helpers +from google.auth import _regional_access_boundary_utils from google.auth import jwt @@ -91,7 +93,9 @@ def decode(token, certs=None, verify=True, audience=None): class Credentials( - jwt.Credentials, _credentials_async.Signing, _credentials_async.Credentials + jwt.Credentials, + _credentials_async.Signing, + _credentials_async.CredentialsWithRegionalAccessBoundary, ): """Credentials that use a JWT as the bearer token. @@ -142,6 +146,14 @@ class Credentials( new_credentials = credentials.with_claims(audience=new_audience) """ + def __setstate__(self, state): + """Restores the credential state and ensures the async refresh manager is attached.""" + super().__setstate__(state) + + self._rab_manager.refresh_manager = ( + _regional_access_boundary_utils._AsyncRegionalAccessBoundaryRefreshManager() + ) + class OnDemandCredentials( jwt.OnDemandCredentials, _credentials_async.Signing, _credentials_async.Credentials @@ -162,3 +174,7 @@ class OnDemandCredentials( .. _grpc: http://www.grpc.io/ """ + + @_helpers.copy_docstring(jwt.OnDemandCredentials) + async def before_request(self, request, method, url, headers): + super(OnDemandCredentials, self).before_request(request, method, url, headers) diff --git a/packages/google-auth/google/auth/_regional_access_boundary_utils.py b/packages/google-auth/google/auth/_regional_access_boundary_utils.py index 5f451bf0e8f4..c97bf8f484df 100644 --- a/packages/google-auth/google/auth/_regional_access_boundary_utils.py +++ b/packages/google-auth/google/auth/_regional_access_boundary_utils.py @@ -14,9 +14,11 @@ """Utilities for Regional Access Boundary management.""" +import asyncio import copy import datetime import functools +import inspect import logging import os import threading @@ -170,12 +172,11 @@ def apply_headers(self, headers): else: headers.pop(_REGIONAL_ACCESS_BOUNDARY_HEADER, None) - def maybe_start_refresh(self, credentials, request): - """Starts a background thread to refresh the Regional Access Boundary if needed. + def _should_refresh(self): + """Checks if the Regional Access Boundary data needs a refresh and is not in cooldown. - Args: - credentials (google.auth.credentials.Credentials): The credentials to refresh. - request (google.auth.transport.Request): The object used to make HTTP requests. + Returns: + bool: True if a refresh is required, False otherwise. """ rab_data = self._data @@ -186,10 +187,22 @@ def maybe_start_refresh(self, credentials, request): and _helpers.utcnow() < (rab_data.expiry - REGIONAL_ACCESS_BOUNDARY_REFRESH_THRESHOLD) ): - return + return False # Don't start a new refresh if the cooldown is still in effect. if rab_data.cooldown_expiry and _helpers.utcnow() < rab_data.cooldown_expiry: + return False + + return True + + def maybe_start_refresh(self, credentials, request): + """Starts a background thread to refresh the Regional Access Boundary if needed. + + Args: + credentials (google.auth.credentials.Credentials): The credentials to refresh. + request (google.auth.transport.Request): The object used to make HTTP requests. + """ + if not self._should_refresh(): return # If all checks pass, start the background refresh. @@ -198,6 +211,22 @@ def maybe_start_refresh(self, credentials, request): else: self.refresh_manager.start_refresh(credentials, request, self) + async def maybe_start_refresh_async(self, credentials, request): + """Starts a background refresh or performs a blocking refresh asynchronously. + + Args: + credentials (google.auth.credentials.Credentials): The credentials to refresh. + request (google.auth.aio.transport.Request): The object used to make HTTP requests. + """ + if not self._should_refresh(): + return + + # If all checks pass, start the refresh. + if self._use_blocking_regional_access_boundary_lookup: + await self.start_blocking_refresh_async(credentials, request) + else: + self.refresh_manager.start_refresh(credentials, request, self) + def start_blocking_refresh(self, credentials, request): """Initiates a blocking lookup of the Regional Access Boundary. @@ -209,6 +238,15 @@ def start_blocking_refresh(self, credentials, request): credentials (google.auth.credentials.Credentials): The credentials to refresh. request (google.auth.transport.Request): The object used to make HTTP requests. """ + # Async credentials do not support blocking lookups. + if inspect.iscoroutinefunction(credentials._lookup_regional_access_boundary): + if _helpers.is_logging_enabled(_LOGGER): + _LOGGER.warning( + "Blocking Regional Access Boundary lookup is not supported for async credentials." + ) + self.process_regional_access_boundary_info(None) + return + try: # The fail_fast parameter is set to True to ensure we don't block the calling # thread for too long. This will do two things: 1) set a timeout to 3s @@ -227,6 +265,37 @@ def start_blocking_refresh(self, credentials, request): self.process_regional_access_boundary_info(regional_access_boundary_info) + async def start_blocking_refresh_async(self, credentials, request): + """Initiates a blocking lookup of the Regional Access Boundary asynchronously. + + If the lookup raises an exception, it is caught and logged as a warning, + and the lookup is treated as a failure (entering cooldown). Exceptions + are not propagated to the caller. + + Args: + credentials (google.auth.credentials.Credentials): The credentials to refresh. + request (google.auth.aio.transport.Request): The object used to make HTTP requests. + """ + try: + # The fail_fast parameter is set to True to ensure we don't block the calling + # thread for too long. This will do two things: 1) set a timeout to 3s + # instead of the default 120s and 2) ensure we do not retry at all + regional_access_boundary_info = ( + await credentials._lookup_regional_access_boundary( + request, fail_fast=True + ) + ) + except Exception as e: + if _helpers.is_logging_enabled(_LOGGER): + _LOGGER.warning( + "Regional Access Boundary lookup raised an exception: %s", + e, + exc_info=True, + ) + regional_access_boundary_info = None + + self.process_regional_access_boundary_info(regional_access_boundary_info) + def process_regional_access_boundary_info(self, regional_access_boundary_info): """Processes the regional access boundary info and updates the state. @@ -384,3 +453,120 @@ def start_refresh(self, credentials, request, rab_manager): credentials, copied_request, rab_manager ) self._worker.start() + + +class _AsyncRegionalAccessBoundaryRefreshManager(object): + """Manages a task for background refreshing of the Regional Access Boundary in async flows.""" + + def __init__(self): + self._lock = threading.Lock() + self._worker_task = None + + def __getstate__(self): + """Pickle helper that excludes the un-picklable _lock and _worker_task attributes from serialization.""" + state = self.__dict__.copy() + state["_lock"] = None + state["_worker_task"] = None + return state + + def __setstate__(self, state): + """Pickle helper that restores state and re-initializes the _lock and _worker_task attributes.""" + self.__dict__.update(state) + self._lock = threading.Lock() + self._worker_task = None + + def start_refresh(self, credentials, request, rab_manager): + """ + Starts a background task to refresh the Regional Access Boundary if one is not already running. + + Args: + credentials (CredentialsWithRegionalAccessBoundary): The credentials + to refresh. + request (google.auth.aio.transport.Request): The object used to make + HTTP requests. + rab_manager (_RegionalAccessBoundaryManager): The manager container to update. + """ + with self._lock: + if self._worker_task and not self._worker_task.done(): + # A refresh is already in progress. + return + + async def _worker(): + try: + # credentials._lookup_regional_access_boundary should be async in the async creds class + regional_access_boundary_info = ( + await credentials._lookup_regional_access_boundary(request) + ) + except Exception as e: + if _helpers.is_logging_enabled(_LOGGER): + _LOGGER.warning( + "Asynchronous Regional Access Boundary lookup raised an exception: %s", + e, + exc_info=True, + ) + regional_access_boundary_info = None + + rab_manager.process_regional_access_boundary_info( + regional_access_boundary_info + ) + + coro = _worker() + try: + self._worker_task = asyncio.create_task(coro) + except Exception: + coro.close() + raise + + +def _get_domain() -> str: + """Dynamically determines the domain for IAM credentials based on active mTLS configuration. + + Returns: + str: The dynamic domain string. + """ + from google.auth.transport import _mtls_helper + + if ( + hasattr(_mtls_helper, "check_use_client_cert") + and _mtls_helper.check_use_client_cert() + ): + return f"iamcredentials.mtls.{_helpers.DEFAULT_UNIVERSE_DOMAIN}" + else: + return f"iamcredentials.{_helpers.DEFAULT_UNIVERSE_DOMAIN}" + + +def get_service_account_rab_endpoint(service_account_email: str) -> str: + """Builds the Regional Access Boundary lookup URL for service accounts. + + Args: + service_account_email: The service account email. + + Returns: + str: The complete lookup URL. + """ + return f"https://{_get_domain()}/v1/projects/-/serviceAccounts/{service_account_email}/allowedLocations" + + +def get_workforce_pool_rab_endpoint(pool_id: str) -> str: + """Builds the Regional Access Boundary lookup URL for workforce pools. + + Args: + pool_id: The workforce pool ID. + + Returns: + str: The complete lookup URL. + """ + return f"https://{_get_domain()}/v1/locations/global/workforcePools/{pool_id}/allowedLocations" + + +def get_workload_identity_pool_rab_endpoint(project_number: str, pool_id: str) -> str: + """Builds the Regional Access Boundary lookup URL for workload identity pools. + + Args: + project_number: The Google Cloud project number. + pool_id: The workload identity pool ID. + + Returns: + str: The complete lookup URL. + """ + return f"https://{_get_domain()}/v1/projects/{project_number}/locations/global/workloadIdentityPools/{pool_id}/allowedLocations" diff --git a/packages/google-auth/google/auth/compute_engine/_metadata.py b/packages/google-auth/google/auth/compute_engine/_metadata.py index aae724ab18ee..f8e1769334d2 100644 --- a/packages/google-auth/google/auth/compute_engine/_metadata.py +++ b/packages/google-auth/google/auth/compute_engine/_metadata.py @@ -22,6 +22,7 @@ import json import logging import os +import re from urllib.parse import urljoin import requests @@ -37,6 +38,8 @@ _LOGGER = logging.getLogger(__name__) +_SERVICE_ACCOUNT_EMAIL_PATTERN = re.compile(r"^[^@]+@[^@]+\.[^@]+$") + _GCE_DEFAULT_MDS_IP = "169.254.169.254" _GCE_DEFAULT_HOST = "metadata.google.internal" _GCE_DEFAULT_MDS_HOSTS = [_GCE_DEFAULT_HOST, _GCE_DEFAULT_MDS_IP] @@ -502,3 +505,20 @@ def get_service_account_token(request, service_account="default", scopes=None): seconds=token_json["expires_in"] ) return token_json["access_token"], token_expiry + + +def _is_service_account_email(email): + """Checks if the provided string is a service account email. + + This is a check that ensures the candidate string is non-empty + and matches a standard email format. + + Args: + email (str): The candidate string to check. + + Returns: + bool: True if the string is non-empty and matches email format, False otherwise. + """ + if not email: + return False + return bool(_SERVICE_ACCOUNT_EMAIL_PATTERN.match(email)) diff --git a/packages/google-auth/google/auth/compute_engine/credentials.py b/packages/google-auth/google/auth/compute_engine/credentials.py index b91e06cf5407..ffe62e0ba9af 100644 --- a/packages/google-auth/google/auth/compute_engine/credentials.py +++ b/packages/google-auth/google/auth/compute_engine/credentials.py @@ -25,6 +25,7 @@ from google.auth import _helpers +from google.auth import _regional_access_boundary_utils from google.auth import credentials from google.auth import exceptions from google.auth import iam @@ -99,6 +100,7 @@ def __init__( self._universe_domain_cached = True self._trust_boundary = trust_boundary + self._rab_disabled = False def _retrieve_info(self, request): """Retrieve information about the service account. @@ -151,6 +153,26 @@ def _perform_refresh_token(self, request): new_exc = exceptions.RefreshError(caught_exc) raise new_exc from caught_exc + def _is_regional_access_boundary_lookup_required(self): + """Checks if a Regional Access Boundary lookup is required. + + Returns: + bool: True if a Regional Access Boundary lookup is required, False otherwise. + """ + if not super()._is_regional_access_boundary_lookup_required(): + return False + + if getattr(self, "_rab_disabled", False): + return False + + # If the field is 'default', the actual value hasn't been fetched from the metadata + # server yet. Allow it to proceed so the actual value can be retrieved and checked + # during the URL construction. + if self.service_account_email == "default": + return True + + return _metadata._is_service_account_email(self.service_account_email) + def _build_regional_access_boundary_lookup_url( self, request: "Optional[google.auth.transport.Request]" = None # noqa: F821 ): @@ -196,8 +218,16 @@ def _build_regional_access_boundary_lookup_url( ) return None - return iam._SERVICE_ACCOUNT_REGIONAL_ACCESS_BOUNDARY_LOOKUP_ENDPOINT.format( - service_account_email=self.service_account_email + if not _metadata._is_service_account_email(self.service_account_email): + _LOGGER.info( + "Service account email '%s' is not a valid email. Skipping Regional Access Boundary lookup.", + self.service_account_email, + ) + self._rab_disabled = True + return None + + return _regional_access_boundary_utils.get_service_account_rab_endpoint( + self.service_account_email ) @property diff --git a/packages/google-auth/google/auth/credentials.py b/packages/google-auth/google/auth/credentials.py index 2242cd2869c0..f0ce4f41e0ac 100644 --- a/packages/google-auth/google/auth/credentials.py +++ b/packages/google-auth/google/auth/credentials.py @@ -34,7 +34,7 @@ if TYPE_CHECKING: # pragma: NO COVER import google.auth.transport -DEFAULT_UNIVERSE_DOMAIN = "googleapis.com" +DEFAULT_UNIVERSE_DOMAIN = _helpers.DEFAULT_UNIVERSE_DOMAIN # These constants are deprecated and no longer used. # They are kept solely for backward compatibility with older implementations. @@ -239,9 +239,25 @@ def before_request(self, request, method, url, headers): else: self._blocking_refresh(request) + self._after_refresh(request, method, url, headers) + metrics.add_metric_header(headers, self._metric_header_for_usage()) self.apply(headers) + def _after_refresh(self, request, method, url, headers): + """Hook for subclasses to perform actions after refresh but before + applying credentials to headers. + + Args: + request (google.auth.transport.Request): The object used to make + HTTP requests. + method (str): The request's HTTP method or the RPC method being + invoked. + url (str): The request's URI or the RPC service's URI. + headers (Mapping): The request's headers. + """ + pass + def with_non_blocking_refresh(self): self._use_non_blocking_refresh = True @@ -309,6 +325,22 @@ def __init__(self): _regional_access_boundary_utils._RegionalAccessBoundaryManager() ) + def __setstate__(self, state): + """Pickle helper that restores state, safely reconstructing RAB fields if missing.""" + self.__dict__.update(state) + if "_rab_manager" not in self.__dict__: + from google.auth import _regional_access_boundary_utils + + self._rab_manager = ( + _regional_access_boundary_utils._RegionalAccessBoundaryManager() + ) + if "_use_non_blocking_refresh" not in self.__dict__: + self._use_non_blocking_refresh = False + if "_refresh_worker" not in self.__dict__: + from google.auth._refresh_worker import RefreshThreadManager + + self._refresh_worker = RefreshThreadManager() + @property def regional_access_boundary(self): """Optional[str]: The encoded Regional Access Boundary locations.""" @@ -364,12 +396,11 @@ def with_trust_boundary(self, trust_boundary): ) def _copy_regional_access_boundary_manager(self, target): - """Copies the regional access boundary manager to another instance.""" - # Create a new manager for the clone to isolate background refresh locks and threads, - # but share the immutable data reference to avoid unnecessary initial lookups. - new_manager = _regional_access_boundary_utils._RegionalAccessBoundaryManager() - new_manager._data = self._rab_manager._data - target._rab_manager = new_manager + """Copies the regional access boundary manager state to another instance.""" + target._rab_manager._data = self._rab_manager._data + target._rab_manager._use_blocking_regional_access_boundary_lookup = ( + self._rab_manager._use_blocking_regional_access_boundary_lookup + ) def _set_regional_access_boundary(self, initial_boundary): """Applies the regional_access_boundary provided via the initial_boundary on these @@ -403,18 +434,14 @@ def _set_blocking_regional_access_boundary_lookup(self): self._rab_manager.enable_blocking_lookup() return self - def _maybe_start_regional_access_boundary_refresh(self, request, url): - """ - Starts a background thread to refresh the Regional Access Boundary if needed. - - This method checks if a refresh is necessary and if one is not already - in progress or in a cooldown period. If so, it starts a background - thread to perform the lookup. + def _is_regional_endpoint(self, url): + """Checks if the request URL is for a regional endpoint. Args: - request (google.auth.transport.Request): The object used to make - HTTP requests. url (str): The URL of the request. + + Returns: + bool: True if the URL is a regional endpoint, False otherwise. """ try: # Do not perform a lookup if the request is for a regional endpoint. @@ -423,16 +450,35 @@ def _maybe_start_regional_access_boundary_refresh(self, request, url): hostname.endswith(".rep.googleapis.com") or hostname.endswith(".rep.sandbox.googleapis.com") ): - return - except (ValueError, TypeError): + return True + except (ValueError, TypeError, AttributeError): # If the URL is malformed, proceed with the default lookup behavior. pass + return False + + def _maybe_start_regional_access_boundary_refresh(self, request, url): + """ + Starts a background thread to refresh the Regional Access Boundary if needed. + + This method checks if a refresh is necessary and if one is not already + in progress or in a cooldown period. If so, it starts a background + thread to perform the lookup. + + Args: + request (google.auth.transport.Request): The object used to make + HTTP requests. + url (str): The URL of the request. + """ + # Do not perform a lookup if the request is for a regional endpoint. + if self._is_regional_endpoint(url): + return + # A refresh is only needed if the feature is enabled. if not self._is_regional_access_boundary_lookup_required(): return - # Start the background refresh if needed. + # Trigger background or blocking refresh if needed self._rab_manager.maybe_start_refresh(self, request) def _is_regional_access_boundary_lookup_required(self): @@ -444,11 +490,11 @@ def _is_regional_access_boundary_lookup_required(self): Returns: bool: True if a Regional Access Boundary lookup is required, False otherwise. """ - # 1. Check if the feature is enabled. + # Check if the feature is enabled. if not _regional_access_boundary_utils.is_regional_access_boundary_enabled(): return False - # 2. Skip for non-default universe domains. + # Skip for non-default universe domains. if self.universe_domain != DEFAULT_UNIVERSE_DOMAIN: return False @@ -459,20 +505,10 @@ def apply(self, headers, token=None): super().apply(headers, token) self._rab_manager.apply_headers(headers) - def before_request(self, request, method, url, headers): - """Refreshes the access token and triggers the Regional Access Boundary - lookup if necessary. - """ - if self._use_non_blocking_refresh: - self._non_blocking_refresh(request) - else: - self._blocking_refresh(request) - + def _after_refresh(self, request, method, url, headers): + """Triggers the Regional Access Boundary lookup if necessary.""" self._maybe_start_regional_access_boundary_refresh(request, url) - metrics.add_metric_header(headers, self._metric_header_for_usage()) - self.apply(headers) - def refresh(self, request): """Refreshes the access token. @@ -500,12 +536,11 @@ def _lookup_regional_access_boundary( url = self._build_regional_access_boundary_lookup_url(request=request) if not url: - _LOGGER.error("Failed to build Regional Access Boundary lookup URL.") + _LOGGER.warning("Failed to build Regional Access Boundary lookup URL.") return None headers: Dict[str, str] = {} self._apply(headers) - self._rab_manager.apply_headers(headers) return _client._lookup_regional_access_boundary( request, url, headers=headers, fail_fast=fail_fast ) diff --git a/packages/google-auth/google/auth/external_account.py b/packages/google-auth/google/auth/external_account.py index b490f368ea45..eee6d1194031 100644 --- a/packages/google-auth/google/auth/external_account.py +++ b/packages/google-auth/google/auth/external_account.py @@ -40,9 +40,9 @@ from google.auth import _helpers +from google.auth import _regional_access_boundary_utils from google.auth import credentials from google.auth import exceptions -from google.auth import iam from google.auth import impersonated_credentials from google.auth import metrics from google.oauth2 import sts @@ -526,9 +526,10 @@ def _build_regional_access_boundary_lookup_url( ) if workload_match: project_number, pool_id = workload_match.groups() - url = iam._WORKLOAD_IDENTITY_POOL_REGIONAL_ACCESS_BOUNDARY_LOOKUP_ENDPOINT.format( - project_number=project_number, - pool_id=pool_id, + url = ( + _regional_access_boundary_utils.get_workload_identity_pool_rab_endpoint( + project_number, pool_id + ) ) else: # If that fails, try to parse as a workforce pool. @@ -538,10 +539,8 @@ def _build_regional_access_boundary_lookup_url( ) if workforce_match: pool_id = workforce_match.groups()[0] - url = ( - iam._WORKFORCE_POOL_REGIONAL_ACCESS_BOUNDARY_LOOKUP_ENDPOINT.format( - pool_id=pool_id - ) + url = _regional_access_boundary_utils.get_workforce_pool_rab_endpoint( + pool_id ) if url: @@ -620,7 +619,7 @@ def _initialize_impersonated_credentials(self): scopes = self._scopes if self._scopes is not None else self._default_scopes # Initialize and return impersonated credentials. - return impersonated_credentials.Credentials( + impersonated_creds = impersonated_credentials.Credentials( source_credentials=source_credentials, target_principal=target_principal, target_scopes=scopes, @@ -631,6 +630,9 @@ def _initialize_impersonated_credentials(self): ), trust_boundary=self._trust_boundary, ) + if self._rab_manager._use_blocking_regional_access_boundary_lookup: + impersonated_creds._set_blocking_regional_access_boundary_lookup() + return impersonated_creds def _create_default_metrics_options(self): metrics_options = {} diff --git a/packages/google-auth/google/auth/external_account_authorized_user.py b/packages/google-auth/google/auth/external_account_authorized_user.py index d292589b6010..35144f15d69e 100644 --- a/packages/google-auth/google/auth/external_account_authorized_user.py +++ b/packages/google-auth/google/auth/external_account_authorized_user.py @@ -42,9 +42,9 @@ from google.auth import _helpers +from google.auth import _regional_access_boundary_utils from google.auth import credentials from google.auth import exceptions -from google.auth import iam from google.oauth2 import sts from google.oauth2 import utils @@ -337,9 +337,7 @@ def _build_regional_access_boundary_lookup_url( pool_id = match.groups()[0] - return iam._WORKFORCE_POOL_REGIONAL_ACCESS_BOUNDARY_LOOKUP_ENDPOINT.format( - pool_id=pool_id - ) + return _regional_access_boundary_utils.get_workforce_pool_rab_endpoint(pool_id) def revoke(self, request): """Revokes the refresh token. diff --git a/packages/google-auth/google/auth/iam.py b/packages/google-auth/google/auth/iam.py index 00b6e06a2c4f..2ecb1b0014b8 100644 --- a/packages/google-auth/google/auth/iam.py +++ b/packages/google-auth/google/auth/iam.py @@ -49,23 +49,17 @@ else: _IAM_DOMAIN = f"iamcredentials.{credentials.DEFAULT_UNIVERSE_DOMAIN}" -# 3. Create the common base URL template +# Create the common base URL template # We use double brackets {{}} so .format() can be called later for the email. _IAM_BASE_URL = f"https://{_IAM_DOMAIN}/v1/projects/-/serviceAccounts/{{}}" -# 4. Define the endpoints as templates +# Define the endpoints as static templates _IAM_ENDPOINT = _IAM_BASE_URL + ":generateAccessToken" _IAM_SIGN_ENDPOINT = _IAM_BASE_URL + ":signBlob" _IAM_SIGNJWT_ENDPOINT = _IAM_BASE_URL + ":signJwt" _IAM_IDTOKEN_ENDPOINT = _IAM_BASE_URL + ":generateIdToken" -# Regional Access Boundary (RAB) Lookup Endpoints -_SERVICE_ACCOUNT_REGIONAL_ACCESS_BOUNDARY_LOOKUP_ENDPOINT = f"https://{_IAM_DOMAIN}/v1/projects/-/serviceAccounts/{{service_account_email}}/allowedLocations" -_WORKFORCE_POOL_REGIONAL_ACCESS_BOUNDARY_LOOKUP_ENDPOINT = f"https://{_IAM_DOMAIN}/v1/locations/global/workforcePools/{{pool_id}}/allowedLocations" -_WORKLOAD_IDENTITY_POOL_REGIONAL_ACCESS_BOUNDARY_LOOKUP_ENDPOINT = f"https://{_IAM_DOMAIN}/v1/projects/{{project_number}}/locations/global/workloadIdentityPools/{{pool_id}}/allowedLocations" - - class Signer(crypt.Signer): """Signs messages using the IAM `signBlob API`_. diff --git a/packages/google-auth/google/auth/impersonated_credentials.py b/packages/google-auth/google/auth/impersonated_credentials.py index 45db79daa42e..2f14d809319e 100644 --- a/packages/google-auth/google/auth/impersonated_credentials.py +++ b/packages/google-auth/google/auth/impersonated_credentials.py @@ -36,6 +36,7 @@ from google.auth import _exponential_backoff from google.auth import _helpers +from google.auth import _regional_access_boundary_utils from google.auth import credentials from google.auth import exceptions from google.auth import iam @@ -368,8 +369,8 @@ def _build_regional_access_boundary_lookup_url( "Service account email is required to build the Regional Access Boundary lookup URL for impersonated credentials." ) return None - return iam._SERVICE_ACCOUNT_REGIONAL_ACCESS_BOUNDARY_LOOKUP_ENDPOINT.format( - service_account_email=self.service_account_email + return _regional_access_boundary_utils.get_service_account_rab_endpoint( + self.service_account_email ) def sign_bytes(self, message): diff --git a/packages/google-auth/google/auth/jwt.py b/packages/google-auth/google/auth/jwt.py index b6fe60736fa1..1241aee70121 100644 --- a/packages/google-auth/google/auth/jwt.py +++ b/packages/google-auth/google/auth/jwt.py @@ -52,6 +52,7 @@ from google.auth import _cache from google.auth import _helpers +from google.auth import _regional_access_boundary_utils from google.auth import _service_account_info from google.auth import crypt from google.auth import exceptions @@ -317,7 +318,9 @@ def decode(token, certs=None, verify=True, audience=None, clock_skew_in_seconds= class Credentials( - google.auth.credentials.Signing, google.auth.credentials.CredentialsWithQuotaProject + google.auth.credentials.Signing, + google.auth.credentials.CredentialsWithQuotaProject, + google.auth.credentials.CredentialsWithRegionalAccessBoundary, ): """Credentials that use a JWT as the bearer token. @@ -490,7 +493,15 @@ def from_signing_credentials(cls, credentials, audience, **kwargs): """ kwargs.setdefault("issuer", credentials.signer_email) kwargs.setdefault("subject", credentials.signer_email) - return cls(credentials.signer, audience=audience, **kwargs) + jwt_creds = cls(credentials.signer, audience=audience, **kwargs) + + if isinstance( + credentials, + google.auth.credentials.CredentialsWithRegionalAccessBoundary, + ): + credentials._copy_regional_access_boundary_manager(jwt_creds) + + return jwt_creds def with_claims( self, issuer=None, subject=None, audience=None, additional_claims=None @@ -514,7 +525,7 @@ def with_claims( new_additional_claims = copy.deepcopy(self._additional_claims) new_additional_claims.update(additional_claims or {}) - return self.__class__( + cred = self.__class__( self._signer, issuer=issuer if issuer is not None else self._issuer, subject=subject if subject is not None else self._subject, @@ -522,10 +533,12 @@ def with_claims( additional_claims=new_additional_claims, quota_project_id=self._quota_project_id, ) + self._copy_regional_access_boundary_manager(cred) + return cred @_helpers.copy_docstring(google.auth.credentials.CredentialsWithQuotaProject) def with_quota_project(self, quota_project_id): - return self.__class__( + cred = self.__class__( self._signer, issuer=self._issuer, subject=self._subject, @@ -533,6 +546,8 @@ def with_quota_project(self, quota_project_id): additional_claims=self._additional_claims, quota_project_id=quota_project_id, ) + self._copy_regional_access_boundary_manager(cred) + return cred def _make_jwt(self): """Make a signed JWT. @@ -559,7 +574,7 @@ def _make_jwt(self): return jwt, expiry - def refresh(self, request): + def _perform_refresh_token(self, request): """Refreshes the access token. Args: @@ -569,6 +584,15 @@ def refresh(self, request): # (pylint doesn't correctly recognize overridden methods.) self.token, self.expiry = self._make_jwt() + def _build_regional_access_boundary_lookup_url(self, request=None): + """Builds the lookup URL using the service account's email address.""" + if not self.signer_email: + return None + + return _regional_access_boundary_utils.get_service_account_rab_endpoint( + self.signer_email + ) + @_helpers.copy_docstring(google.auth.credentials.Signing) def sign_bytes(self, message): return self._signer.sign(message) diff --git a/packages/google-auth/google/oauth2/_client.py b/packages/google-auth/google/oauth2/_client.py index 1c7ba46b72e1..88083d022986 100644 --- a/packages/google-auth/google/oauth2/_client.py +++ b/packages/google-auth/google/oauth2/_client.py @@ -549,7 +549,7 @@ def _lookup_regional_access_boundary(request, url, headers=None, fail_fast=False # Error was already logged by _lookup_regional_access_boundary_request return None - if "encodedLocations" not in response_data: + if not isinstance(response_data, dict) or "encodedLocations" not in response_data: _LOGGER.error( "Regional Access Boundary response malformed: missing 'encodedLocations' key in %s", response_data, diff --git a/packages/google-auth/google/oauth2/_client_async.py b/packages/google-auth/google/oauth2/_client_async.py index a6201fbdcb94..ce94284ea7c9 100644 --- a/packages/google-auth/google/oauth2/_client_async.py +++ b/packages/google-auth/google/oauth2/_client_async.py @@ -23,6 +23,7 @@ .. _Section 3.1 of rfc6749: https://tools.ietf.org/html/rfc6749#section-3.2 """ +import asyncio import http.client as http_client import json import urllib @@ -288,3 +289,166 @@ async def refresh_grant( request, token_uri, body, can_retry=can_retry ) return client._handle_refresh_grant_response(response_data, refresh_token) + + +async def _lookup_regional_access_boundary(request, url, headers=None, fail_fast=False): + """Implements the global lookup of a credential Regional Access Boundary. + For the lookup, we send a request to the global lookup endpoint and then + parse the response. Service account credentials, workload identity + pools and workforce pools implementation may have Regional Access Boundaries configured. + Args: + request (google.auth.aio.transport.Request): A callable used to make + HTTP requests. The returned response must support `await response.read()` + (standard async transport) or `await response.content()` (legacy/custom transport). + url (str): The Regional Access Boundary lookup url. + headers (Optional[Mapping[str, str]]): The headers for the request. + fail_fast (bool): Whether the lookup should fail fast (uses a short timeout and no retries). + Returns: + Optional[Mapping[str,list|str]]: A dictionary containing + "locations" as a list of allowed locations as strings and + "encodedLocations" as a hex string. + e.g: + { + "locations": [ + "us-central1", "us-east1", "europe-west1", "asia-east1" + ], + "encodedLocations": "0xA30" + } + """ + response_data = await _lookup_regional_access_boundary_request( + request, url, headers=headers, fail_fast=fail_fast + ) + if response_data is None: + # Error was already logged by _lookup_regional_access_boundary_request + return None + + if not isinstance(response_data, dict) or "encodedLocations" not in response_data: + client._LOGGER.error( + "Regional Access Boundary response malformed: missing 'encodedLocations' key in %s", + response_data, + ) + return None + return response_data + + +async def _lookup_regional_access_boundary_request( + request, url, can_retry=True, headers=None, fail_fast=False +): + """Makes a request to the Regional Access Boundary lookup endpoint. + + Args: + request (google.auth.aio.transport.Request): A callable used to make + HTTP requests. The returned response must support `await response.read()` + (standard async transport) or `await response.content()` (legacy/custom transport). + url (str): The Regional Access Boundary lookup url. + can_retry (bool): Enable or disable request retry behavior. Defaults to true. + headers (Optional[Mapping[str, str]]): The headers for the request. + fail_fast (bool): Whether the lookup should fail fast (uses a short timeout and no retries). + + Returns: + Optional[Mapping[str, str]]: The JSON-decoded response data on success, or None on failure. + """ + ( + response_status_ok, + response_data, + retryable_error, + ) = await _lookup_regional_access_boundary_request_no_throw( + request, url, can_retry=can_retry, headers=headers, fail_fast=fail_fast + ) + if not response_status_ok: + client._LOGGER.warning( + "Regional Access Boundary HTTP request failed after retries: response_data=%s, retryable_error=%s", + response_data, + retryable_error, + ) + return None + return response_data + + +async def _lookup_regional_access_boundary_request_no_throw( + request, url, can_retry=True, headers=None, fail_fast=False +): + """Makes a request to the Regional Access Boundary lookup endpoint. This + function doesn't throw on response errors. + + Args: + request (google.auth.aio.transport.Request): A callable used to make + HTTP requests. The returned response must support `await response.read()` + (standard async transport) or `await response.content()` (legacy/custom transport). + url (str): The Regional Access Boundary lookup url. + can_retry (bool): Enable or disable request retry behavior. Defaults to true. + headers (Optional[Mapping[str, str]]): The headers for the request. + fail_fast (bool): Whether the lookup should fail fast (uses a short timeout and no retries). + + Returns: + Tuple(bool, Mapping[str, str], Optional[bool]): A boolean indicating + if the request is successful, a mapping for the JSON-decoded response + data and in the case of an error a boolean indicating if the error + is retryable. + """ + + response_data = {} + retryable_error = False + + timeout = ( + client._BLOCKING_REGIONAL_ACCESS_BOUNDARY_LOOKUP_TIMEOUT if fail_fast else None + ) + total_attempts = 1 if fail_fast else 6 + retries = _exponential_backoff.AsyncExponentialBackoff( + total_attempts=total_attempts + ) + + async for _ in retries: + try: + if timeout: + response = await asyncio.wait_for( + request(method="GET", url=url, headers=headers, timeout=timeout), + timeout=timeout, + ) + else: + response = await request(method="GET", url=url, headers=headers) + + # Supports both modern google.auth.aio (exposing read()) and legacy transports (exposing content()) + if hasattr(response, "read"): + response_bytes = await response.read() + else: + response_bytes = await response.content() + except (asyncio.TimeoutError, exceptions.TransportError): + retryable_error = True + if not can_retry: + return False, {}, retryable_error + continue + except Exception: + # Catch raw transport/socket exceptions raised during body streaming. + return False, {}, False + + try: + response_body = ( + response_bytes.decode("utf-8") + if hasattr(response_bytes, "decode") + else response_bytes + ) + response_data = json.loads(response_body) + except (UnicodeDecodeError, ValueError): + # Keep types safe and allow status-code checks below to determine retryability + response_data = {} + + status_code = ( + response.status_code + if hasattr(response, "status_code") + else response.status + ) + + if status_code == http_client.OK: + return True, response_data, None + + retryable_error = client._can_retry( + status_code=status_code, response_data=response_data + ) + if status_code == http_client.BAD_GATEWAY: + retryable_error = True + + if not can_retry or not retryable_error: + return False, response_data, retryable_error + + return False, response_data, retryable_error diff --git a/packages/google-auth/google/oauth2/_service_account_async.py b/packages/google-auth/google/oauth2/_service_account_async.py index fa6cfb7b7d7a..69b80a2531d2 100644 --- a/packages/google-auth/google/oauth2/_service_account_async.py +++ b/packages/google-auth/google/oauth2/_service_account_async.py @@ -24,12 +24,15 @@ from google.auth import _credentials_async as credentials_async from google.auth import _helpers +from google.auth import _regional_access_boundary_utils from google.oauth2 import _client_async from google.oauth2 import service_account class Credentials( - service_account.Credentials, credentials_async.Scoped, credentials_async.Credentials + service_account.Credentials, + credentials_async.Scoped, + credentials_async.CredentialsWithRegionalAccessBoundary, ): """Service account credentials @@ -66,6 +69,14 @@ class Credentials( credentials = credentials.with_quota_project('myproject-123') """ + def __setstate__(self, state): + """Restores the credential state and ensures the async refresh manager is attached.""" + super().__setstate__(state) + + self._rab_manager.refresh_manager = ( + _regional_access_boundary_utils._AsyncRegionalAccessBoundaryRefreshManager() + ) + @_helpers.copy_docstring(credentials_async.Credentials) async def refresh(self, request): assertion = self._make_authorization_grant_assertion() @@ -75,13 +86,6 @@ async def refresh(self, request): self.token = access_token self.expiry = expiry - @_helpers.copy_docstring(credentials_async.Credentials) - async def before_request(self, request, method, url, headers): - # Explicit override to bypass synchronous CredentialsWithRegionalAccessBoundary. - await credentials_async.Credentials.before_request( - self, request, method, url, headers - ) - class IDTokenCredentials( service_account.IDTokenCredentials, @@ -137,11 +141,3 @@ async def refresh(self, request): ) self.token = access_token self.expiry = expiry - - @_helpers.copy_docstring(credentials_async.Credentials) - async def before_request(self, request, method, url, headers): - # Explicit override to bypass synchronous CredentialsWithRegionalAccessBoundary - # and disable Regional Access Boundary refresh for async credentials. - await credentials_async.Credentials.before_request( - self, request, method, url, headers - ) diff --git a/packages/google-auth/google/oauth2/service_account.py b/packages/google-auth/google/oauth2/service_account.py index 5c19b8fe01ae..7f719ade2cdb 100644 --- a/packages/google-auth/google/oauth2/service_account.py +++ b/packages/google-auth/google/oauth2/service_account.py @@ -77,6 +77,7 @@ from google.auth import _helpers +from google.auth import _regional_access_boundary_utils from google.auth import _service_account_info from google.auth import credentials from google.auth import exceptions @@ -520,8 +521,8 @@ def _build_regional_access_boundary_lookup_url( "Service account email is required to build the Regional Access Boundary lookup URL for service account credentials." ) return None - return iam._SERVICE_ACCOUNT_REGIONAL_ACCESS_BOUNDARY_LOOKUP_ENDPOINT.format( - service_account_email=self._service_account_email, + return _regional_access_boundary_utils.get_service_account_rab_endpoint( + self._service_account_email ) @_helpers.copy_docstring(credentials.Signing) diff --git a/packages/google-auth/tests/compute_engine/test__metadata.py b/packages/google-auth/tests/compute_engine/test__metadata.py index e2cbf425a1ec..b27e7f7f4fb5 100644 --- a/packages/google-auth/tests/compute_engine/test__metadata.py +++ b/packages/google-auth/tests/compute_engine/test__metadata.py @@ -985,3 +985,28 @@ def test__prepare_request_for_mds_mtls_http_request(mock_mds_mtls_adapter): _metadata._prepare_request_for_mds(request, use_mtls=True) assert mock_mds_mtls_adapter.call_count == 0 + + +def test__is_service_account_email(): + # Valid email formats + assert ( + _metadata._is_service_account_email("my-sa@my-project.iam.gserviceaccount.com") + is True + ) + assert _metadata._is_service_account_email("test@example.com") is True + + # Empty inputs and standard string placeholders + assert _metadata._is_service_account_email("default") is False + assert _metadata._is_service_account_email("") is False + assert _metadata._is_service_account_email(None) is False + + # Workload identity principal URI formats + assert ( + _metadata._is_service_account_email( + "principal://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/my-project.svc.id.goog/subject/ns/my-namespace/sa/my-kubernetes-sa" + ) + is False + ) + + # Workforce or workload pool identifier paths + assert _metadata._is_service_account_email("my-gcp-project.svc.id.goog") is False diff --git a/packages/google-auth/tests/compute_engine/test_credentials.py b/packages/google-auth/tests/compute_engine/test_credentials.py index 5a60ffd44145..7fb2b8b504fc 100644 --- a/packages/google-auth/tests/compute_engine/test_credentials.py +++ b/packages/google-auth/tests/compute_engine/test_credentials.py @@ -306,8 +306,9 @@ def test_build_regional_access_boundary_lookup_url_default_email( url = creds._build_regional_access_boundary_lookup_url(request=mock_request) mock_get_service_account_info.assert_called_once_with(mock_request, "default") - expected_url = "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/resolved-email@example.com/allowedLocations" - assert url == expected_url + expected_url_standard = "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/resolved-email@example.com/allowedLocations" + expected_url_mtls = "https://iamcredentials.mtls.googleapis.com/v1/projects/-/serviceAccounts/resolved-email@example.com/allowedLocations" + assert url in (expected_url_standard, expected_url_mtls) @mock.patch("google.auth.compute_engine._metadata.get", autospec=True) def test_build_regional_access_boundary_lookup_url_http_client_request( @@ -323,7 +324,33 @@ def test_build_regional_access_boundary_lookup_url_http_client_request( url = creds._build_regional_access_boundary_lookup_url(request=req) - expected_url = "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/resolved-email@example.com/allowedLocations" + expected_url_standard = "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/resolved-email@example.com/allowedLocations" + expected_url_mtls = "https://iamcredentials.mtls.googleapis.com/v1/projects/-/serviceAccounts/resolved-email@example.com/allowedLocations" + assert url in (expected_url_standard, expected_url_mtls) + + @mock.patch( + "google.auth.compute_engine._metadata.get_service_account_info", autospec=True + ) + @mock.patch( + "google.auth.compute_engine._metadata.get_universe_domain", autospec=True + ) + def test_build_regional_access_boundary_lookup_url_explicit_email_standard( + self, mock_get_universe_domain, mock_get_service_account_info, monkeypatch + ): + from google.auth.transport import _mtls_helper + + # Mock check_use_client_cert to return False + monkeypatch.setattr(_mtls_helper, "check_use_client_cert", lambda: False) + + # Test with an explicit service account email, no resolution needed + creds = self.credentials + creds._service_account_email = FAKE_SERVICE_ACCOUNT_EMAIL + mock_get_universe_domain.return_value = "googleapis.com" + + url = creds._build_regional_access_boundary_lookup_url() + + mock_get_service_account_info.assert_not_called() + expected_url = "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/foo@bar.com/allowedLocations" assert url == expected_url @mock.patch( @@ -332,9 +359,14 @@ def test_build_regional_access_boundary_lookup_url_http_client_request( @mock.patch( "google.auth.compute_engine._metadata.get_universe_domain", autospec=True ) - def test_build_regional_access_boundary_lookup_url_explicit_email( - self, mock_get_universe_domain, mock_get_service_account_info + def test_build_regional_access_boundary_lookup_url_explicit_email_mtls( + self, mock_get_universe_domain, mock_get_service_account_info, monkeypatch ): + from google.auth.transport import _mtls_helper + + # Mock check_use_client_cert to return True + monkeypatch.setattr(_mtls_helper, "check_use_client_cert", lambda: True) + # Test with an explicit service account email, no resolution needed creds = self.credentials creds._service_account_email = FAKE_SERVICE_ACCOUNT_EMAIL @@ -343,9 +375,8 @@ def test_build_regional_access_boundary_lookup_url_explicit_email( url = creds._build_regional_access_boundary_lookup_url() mock_get_service_account_info.assert_not_called() - assert url == ( - "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/foo@bar.com/allowedLocations" - ) + expected_url = "https://iamcredentials.mtls.googleapis.com/v1/projects/-/serviceAccounts/foo@bar.com/allowedLocations" + assert url == expected_url @mock.patch( "google.auth.compute_engine._metadata.get_universe_domain", autospec=True @@ -379,6 +410,68 @@ def test_build_regional_access_boundary_lookup_url_no_email( url = creds._build_regional_access_boundary_lookup_url() assert url is None + @mock.patch( + "google.auth._regional_access_boundary_utils.is_regional_access_boundary_enabled", + return_value=True, + ) + def test_is_regional_access_boundary_lookup_required(self, mock_enabled): + creds = self.credentials + creds._universe_domain_cached = True + + # Valid email formats should pass. + creds._service_account_email = "my-sa@my-project.iam.gserviceaccount.com" + assert creds._is_regional_access_boundary_lookup_required() is True + + # GCE default email placeholder should pass to allow dynamic resolution. + creds._service_account_email = "default" + assert creds._is_regional_access_boundary_lookup_required() is True + + # Lookup for non-email based identities should be skipped. + creds._service_account_email = "my-gcp-project.svc.id.goog" + assert creds._is_regional_access_boundary_lookup_required() is False + + creds._service_account_email = "principal://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/my-project.svc.id.goog/subject/ns/my-namespace/sa/my-kubernetes-sa" + assert creds._is_regional_access_boundary_lookup_required() is False + + def test_build_regional_access_boundary_lookup_url_with_invalid_email(self): + creds = self.credentials + creds._universe_domain_cached = True + + # Set a non-email identity. + creds._service_account_email = "my-gcp-project.svc.id.goog" + url = creds._build_regional_access_boundary_lookup_url() + assert url is None + + @mock.patch( + "google.auth._regional_access_boundary_utils.is_regional_access_boundary_enabled", + return_value=True, + ) + @mock.patch( + "google.auth.compute_engine._metadata.get_service_account_info", autospec=True + ) + def test_regional_access_boundary_disabled_state_transitions( + self, mock_get_service_account_info, mock_enabled + ): + mock_get_service_account_info.return_value = { + "email": "spiffe://trust-domain/ns/ns/sa/sa", + "scopes": ["one", "two"], + } + creds = self.credentials + creds._universe_domain_cached = True + creds._service_account_email = "default" + + # Initially, GCE 'default' placeholder passes the pre-check + assert not creds._rab_disabled + assert creds._is_regional_access_boundary_lookup_required() is True + + # Resolving a non-email identity should disable RAB lookup + url = creds._build_regional_access_boundary_lookup_url() + assert url is None + assert creds._rab_disabled is True + + # Subsequent check calls should return False early + assert creds._is_regional_access_boundary_lookup_required() is False + @mock.patch("google.auth.compute_engine._metadata.get") @mock.patch("google.auth._agent_identity_utils.get_agent_identity_certificate_path") @mock.patch("google.auth._agent_identity_utils.parse_certificate") diff --git a/packages/google-auth/tests/oauth2/test__client.py b/packages/google-auth/tests/oauth2/test__client.py index 173ddbd27948..b20a8042d5f5 100644 --- a/packages/google-auth/tests/oauth2/test__client.py +++ b/packages/google-auth/tests/oauth2/test__client.py @@ -185,7 +185,8 @@ def test__token_endpoint_request_error(): _client._token_endpoint_request(request, "http://example.com", {}) -def test__token_endpoint_request_internal_failure_error(): +@mock.patch("time.sleep", return_value=None) +def test__token_endpoint_request_internal_failure_error(mock_sleep): request = make_request( {"error_description": "internal_failure"}, status=http_client.BAD_REQUEST ) @@ -207,9 +208,11 @@ def test__token_endpoint_request_internal_failure_error(): ) # request with 2 retries assert request.call_count == 3 + assert mock_sleep.call_count == 4 -def test__token_endpoint_request_internal_failure_and_retry_failure_error(): +@mock.patch("time.sleep", return_value=None) +def test__token_endpoint_request_internal_failure_and_retry_failure_error(mock_sleep): retryable_error = mock.create_autospec(transport.Response, instance=True) retryable_error.status = http_client.BAD_REQUEST retryable_error.data = json.dumps({"error_description": "internal_failure"}).encode( @@ -233,9 +236,11 @@ def test__token_endpoint_request_internal_failure_and_retry_failure_error(): # request should be called three times. Two retryable errors and one # unretryable error to break the retry loop. assert request.call_count == 3 + assert mock_sleep.call_count == 2 -def test__token_endpoint_request_internal_failure_and_retry_succeeds(): +@mock.patch("time.sleep", return_value=None) +def test__token_endpoint_request_internal_failure_and_retry_succeeds(mock_sleep): retryable_error = mock.create_autospec(transport.Response, instance=True) retryable_error.status = http_client.BAD_REQUEST retryable_error.data = json.dumps({"error_description": "internal_failure"}).encode( @@ -255,6 +260,7 @@ def test__token_endpoint_request_internal_failure_and_retry_succeeds(): ) assert request.call_count == 2 + assert mock_sleep.call_count == 1 def test__token_endpoint_request_string_error(): @@ -611,7 +617,8 @@ def test_refresh_grant_retry_with_retry( @pytest.mark.parametrize("can_retry", [True, False]) -def test__token_endpoint_request_no_throw_with_retry(can_retry): +@mock.patch("time.sleep", return_value=None) +def test__token_endpoint_request_no_throw_with_retry(mock_sleep, can_retry): response_data = {"error": "help", "error_description": "I'm alive"} body = "dummy body" @@ -628,8 +635,10 @@ def test__token_endpoint_request_no_throw_with_retry(can_retry): if can_retry: assert mock_request.call_count == 3 + assert mock_sleep.call_count == 2 else: assert mock_request.call_count == 1 + mock_sleep.assert_not_called() def test_lookup_regional_access_boundary(): @@ -706,7 +715,10 @@ def test_lookup_regional_access_boundary_non_retryable_error(status_code): ) -def test_lookup_regional_access_boundary_internal_failure_and_retry_failure_error(): +@mock.patch("time.sleep", return_value=None) +def test_lookup_regional_access_boundary_internal_failure_and_retry_failure_error( + mock_sleep, +): retryable_error = mock.create_autospec(transport.Response, instance=True) retryable_error.status = http_client.BAD_REQUEST retryable_error.data = json.dumps({"error_description": "internal_failure"}).encode( @@ -731,11 +743,15 @@ def test_lookup_regional_access_boundary_internal_failure_and_retry_failure_erro # request should be called three times. Two retryable errors and one # unretryable error to break the retry loop. assert request.call_count == 3 + assert mock_sleep.call_count == 2 for call in request.call_args_list: assert call[1]["headers"] == headers -def test_lookup_regional_access_boundary_internal_failure_and_retry_succeeds(): +@mock.patch("time.sleep", return_value=None) +def test_lookup_regional_access_boundary_internal_failure_and_retry_succeeds( + mock_sleep, +): retryable_error = mock.create_autospec(transport.Response, instance=True) retryable_error.status = http_client.BAD_REQUEST retryable_error.data = json.dumps({"error_description": "internal_failure"}).encode( @@ -760,6 +776,7 @@ def test_lookup_regional_access_boundary_internal_failure_and_retry_succeeds(): ) assert request.call_count == 2 + assert mock_sleep.call_count == 1 for call in request.call_args_list: assert call[1]["headers"] == headers diff --git a/packages/google-auth/tests/oauth2/test_service_account.py b/packages/google-auth/tests/oauth2/test_service_account.py index f0d8f0759e50..958eace2dd22 100644 --- a/packages/google-auth/tests/oauth2/test_service_account.py +++ b/packages/google-auth/tests/oauth2/test_service_account.py @@ -228,15 +228,65 @@ def test_with_quota_project(self): new_credentials.apply(hdrs, token="tok") assert "x-goog-user-project" in hdrs - def test_build_regional_access_boundary_lookup_url(self): + def test_copy_regional_access_boundary_manager_state_and_config_with_scopes(self): credentials = self.make_credentials() - expected_url = ( - "https://iamcredentials.googleapis.com/v1/projects/-/" - "serviceAccounts/{}/allowedLocations".format( - credentials.service_account_email - ) + credentials._rab_manager._data = mock.sentinel.rab_data + credentials._rab_manager._use_blocking_regional_access_boundary_lookup = True + + new_credentials = credentials.with_scopes(["scope-foo"]) + + # Verify references to boundary data are shared + assert new_credentials._rab_manager._data == mock.sentinel.rab_data + # Verify blocking config flag is preserved + assert ( + new_credentials._rab_manager._use_blocking_regional_access_boundary_lookup + is True + ) + # Verify target manager object is not replaced + assert new_credentials._rab_manager is not credentials._rab_manager + + def test_copy_regional_access_boundary_manager_state_and_config_with_quota_project( + self, + ): + credentials = self.make_credentials() + credentials._rab_manager._data = mock.sentinel.rab_data + credentials._rab_manager._use_blocking_regional_access_boundary_lookup = True + + new_credentials = credentials.with_quota_project("new-project-foo") + + # Verify references to boundary data are shared + assert new_credentials._rab_manager._data == mock.sentinel.rab_data + # Verify blocking config flag is preserved + assert ( + new_credentials._rab_manager._use_blocking_regional_access_boundary_lookup + is True + ) + # Verify target manager object is not replaced + assert new_credentials._rab_manager is not credentials._rab_manager + + def test_build_regional_access_boundary_lookup_url_standard(self, monkeypatch): + from google.auth.transport import _mtls_helper + + monkeypatch.setattr(_mtls_helper, "check_use_client_cert", lambda: False) + + credentials = self.make_credentials() + url = credentials._build_regional_access_boundary_lookup_url() + expected_url = "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/{}/allowedLocations".format( + credentials.service_account_email + ) + assert url == expected_url + + def test_build_regional_access_boundary_lookup_url_mtls(self, monkeypatch): + from google.auth.transport import _mtls_helper + + monkeypatch.setattr(_mtls_helper, "check_use_client_cert", lambda: True) + + credentials = self.make_credentials() + url = credentials._build_regional_access_boundary_lookup_url() + expected_url = "https://iamcredentials.mtls.googleapis.com/v1/projects/-/serviceAccounts/{}/allowedLocations".format( + credentials.service_account_email ) - assert credentials._build_regional_access_boundary_lookup_url() == expected_url + assert url == expected_url def test_with_token_uri(self): credentials = self.make_credentials() diff --git a/packages/google-auth/tests/test__regional_access_boundary_utils.py b/packages/google-auth/tests/test__regional_access_boundary_utils.py index ab6ec75fd9b8..c612b60b8ed2 100644 --- a/packages/google-auth/tests/test__regional_access_boundary_utils.py +++ b/packages/google-auth/tests/test__regional_access_boundary_utils.py @@ -1,4 +1,4 @@ -# Copyright 2026 Google Inc. +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ import pytest # type: ignore +from google.auth import _credentials_async from google.auth import _helpers from google.auth import _regional_access_boundary_utils from google.auth import credentials @@ -301,6 +302,24 @@ def test_serialization(self): assert unpickled.refresh_manager._lock is not None assert unpickled.refresh_manager._worker is None + def test_unpickle_old_credentials_without_rab(self): + creds = CredentialsImpl() + old_state = creds.__dict__.copy() + if "_rab_manager" in old_state: + del old_state["_rab_manager"] + if "_use_non_blocking_refresh" in old_state: + del old_state["_use_non_blocking_refresh"] + if "_refresh_worker" in old_state: + del old_state["_refresh_worker"] + + new_instance = CredentialsImpl.__new__(CredentialsImpl) + new_instance.__setstate__(old_state) + + assert hasattr(new_instance, "_rab_manager") + assert new_instance._rab_manager is not None + assert new_instance._use_non_blocking_refresh is False + assert new_instance._refresh_worker is not None + @mock.patch( "google.auth._regional_access_boundary_utils._RegionalAccessBoundaryRefreshManager.start_refresh" ) @@ -379,6 +398,21 @@ def test_start_blocking_refresh_failure(self): assert creds._rab_manager._data.encoded_locations is None assert creds._rab_manager._data.cooldown_expiry is not None + def test_start_blocking_refresh_with_async_credentials(self): + creds = CredentialsImpl() + request = mock.Mock() + + with mock.patch.object( + creds, + "_lookup_regional_access_boundary", + new_callable=mock.AsyncMock, + ) as mock_lookup: + creds._rab_manager.start_blocking_refresh(creds, request) + + mock_lookup.assert_not_called() + assert creds._rab_manager._data.encoded_locations is None + assert creds._rab_manager._data.cooldown_expiry is not None + @mock.patch("copy.deepcopy") def test_start_refresh_deepcopy_failure(self, mock_deepcopy): mock_deepcopy.side_effect = Exception("deepcopy error") @@ -552,3 +586,178 @@ def test_regional_access_boundary_refresh_manager_start_refresh_safety_lock(self mock_thread_class.assert_not_called() assert manager._worker == mock_worker + + +class AsyncCredentialsImpl(_credentials_async.CredentialsWithRegionalAccessBoundary): + def __init__(self, universe_domain=None): + super().__init__() + if universe_domain: + self._universe_domain = universe_domain + + async def _perform_refresh_token(self, request): + self.token = "refreshed-token" + self.expiry = ( + _helpers.utcnow() + + _helpers.REFRESH_THRESHOLD + + datetime.timedelta(seconds=5) + ) + + def with_quota_project(self, quota_project_id): + raise NotImplementedError() + + def _build_regional_access_boundary_lookup_url(self, request=None): + # Using self.token here to make the URL dynamic for testing purposes + return "http://mock.url/lookup_for_{}".format(self.token) + + def _make_copy(self): + new_credentials = self.__class__() + self._copy_regional_access_boundary_manager(new_credentials) + return new_credentials + + +class TestAsyncCredentialsWithRegionalAccessBoundary(object): + @pytest.mark.asyncio + async def test_maybe_start_refresh_async_blocking(self): + creds = AsyncCredentialsImpl() + creds._rab_manager._use_blocking_regional_access_boundary_lookup = True + request = mock.Mock() + + with mock.patch.dict( + os.environ, + {environment_vars.GOOGLE_AUTH_TRUST_BOUNDARY_ENABLED: "true"}, + ): + with mock.patch.object( + creds._rab_manager, + "start_blocking_refresh_async", + new_callable=mock.AsyncMock, + ) as mock_start_blocking: + await creds._maybe_start_regional_access_boundary_refresh_async( + request, "http://example.com" + ) + mock_start_blocking.assert_called_once_with(creds, request) + + @pytest.mark.asyncio + async def test_start_blocking_refresh_async_success(self): + creds = AsyncCredentialsImpl() + request = mock.Mock() + + with mock.patch.object( + creds, + "_lookup_regional_access_boundary", + new_callable=mock.AsyncMock, + return_value={"encodedLocations": "0xABC"}, + ) as mock_lookup: + await creds._rab_manager.start_blocking_refresh_async(creds, request) + + mock_lookup.assert_called_once_with(request, fail_fast=True) + assert creds._rab_manager._data.encoded_locations == "0xABC" + + @pytest.mark.asyncio + async def test_start_blocking_refresh_async_failure(self): + creds = AsyncCredentialsImpl() + request = mock.Mock() + + with mock.patch.object( + creds, + "_lookup_regional_access_boundary", + new_callable=mock.AsyncMock, + side_effect=Exception("error"), + ) as mock_lookup: + await creds._rab_manager.start_blocking_refresh_async(creds, request) + + mock_lookup.assert_called_once_with(request, fail_fast=True) + assert creds._rab_manager._data.encoded_locations is None + assert creds._rab_manager._data.cooldown_expiry is not None + + @pytest.mark.asyncio + async def test_async_refresh_manager_session_closed_ignored(self): + credentials = mock.AsyncMock() + # Simulate a closed session RuntimeError when invoking the boundary lookup + credentials._lookup_regional_access_boundary.side_effect = RuntimeError( + "Session is closed" + ) + + request = mock.Mock() + rab_manager = mock.Mock() + + manager = ( + _regional_access_boundary_utils._AsyncRegionalAccessBoundaryRefreshManager() + ) + + # Trigger refresh, which starts a background task that should swallow the error + manager.start_refresh(credentials, request, rab_manager) + + # Wait for the background worker task to terminate + await manager._worker_task + + # Verify that the lookup was still triggered but failed open cleanly + credentials._lookup_regional_access_boundary.assert_called_once_with(request) + rab_manager.process_regional_access_boundary_info.assert_called_once_with(None) + + +def test_get_service_account_rab_endpoint(monkeypatch): + from google.auth.transport import _mtls_helper + + # Test Standard TLS + monkeypatch.setattr(_mtls_helper, "check_use_client_cert", lambda: False) + url = _regional_access_boundary_utils.get_service_account_rab_endpoint( + "test@example.com" + ) + assert ( + url + == "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/test@example.com/allowedLocations" + ) + + # Test mTLS + monkeypatch.setattr(_mtls_helper, "check_use_client_cert", lambda: True) + url = _regional_access_boundary_utils.get_service_account_rab_endpoint( + "test@example.com" + ) + assert ( + url + == "https://iamcredentials.mtls.googleapis.com/v1/projects/-/serviceAccounts/test@example.com/allowedLocations" + ) + + +def test_get_workforce_pool_rab_endpoint(monkeypatch): + from google.auth.transport import _mtls_helper + + # Test Standard TLS + monkeypatch.setattr(_mtls_helper, "check_use_client_cert", lambda: False) + url = _regional_access_boundary_utils.get_workforce_pool_rab_endpoint("POOL_ID") + assert ( + url + == "https://iamcredentials.googleapis.com/v1/locations/global/workforcePools/POOL_ID/allowedLocations" + ) + + # Test mTLS + monkeypatch.setattr(_mtls_helper, "check_use_client_cert", lambda: True) + url = _regional_access_boundary_utils.get_workforce_pool_rab_endpoint("POOL_ID") + assert ( + url + == "https://iamcredentials.mtls.googleapis.com/v1/locations/global/workforcePools/POOL_ID/allowedLocations" + ) + + +def test_get_workload_identity_pool_rab_endpoint(monkeypatch): + from google.auth.transport import _mtls_helper + + # Test Standard TLS + monkeypatch.setattr(_mtls_helper, "check_use_client_cert", lambda: False) + url = _regional_access_boundary_utils.get_workload_identity_pool_rab_endpoint( + "PROJECT_NUM", "POOL_ID" + ) + assert ( + url + == "https://iamcredentials.googleapis.com/v1/projects/PROJECT_NUM/locations/global/workloadIdentityPools/POOL_ID/allowedLocations" + ) + + # Test mTLS + monkeypatch.setattr(_mtls_helper, "check_use_client_cert", lambda: True) + url = _regional_access_boundary_utils.get_workload_identity_pool_rab_endpoint( + "PROJECT_NUM", "POOL_ID" + ) + assert ( + url + == "https://iamcredentials.mtls.googleapis.com/v1/projects/PROJECT_NUM/locations/global/workloadIdentityPools/POOL_ID/allowedLocations" + ) diff --git a/packages/google-auth/tests/test_credentials.py b/packages/google-auth/tests/test_credentials.py index e1528a3ce365..5c7e39d59e84 100644 --- a/packages/google-auth/tests/test_credentials.py +++ b/packages/google-auth/tests/test_credentials.py @@ -154,6 +154,21 @@ def test_before_request_with_regional_access_boundary(): assert headers["x-allowed-locations"] == DUMMY_BOUNDARY +def test_copy_regional_access_boundary_manager_state_and_config(): + creds = CredentialsImpl() + creds._rab_manager._data = mock.sentinel.rab_data + creds._rab_manager._use_blocking_regional_access_boundary_lookup = True + + new_creds = creds._make_copy() + + # Verify references to immutable boundary data are shared + assert new_creds._rab_manager._data == mock.sentinel.rab_data + # Verify blocking config flag is preserved + assert new_creds._rab_manager._use_blocking_regional_access_boundary_lookup is True + # Verify target manager object is isolated (kept from constructor, not replaced) + assert new_creds._rab_manager is not creds._rab_manager + + def test_before_request_metrics(): credentials = CredentialsImplWithMetrics() request = "token" @@ -424,3 +439,17 @@ def test_before_request_triggers_rab_refresh(): lookup.assert_called_once() args, kwargs = lookup.call_args assert args[1] == "http://mock.url/lookup_for_refreshed-token" + + +def test_maybe_start_regional_access_boundary_refresh_invalid_url(): + credentials_instance = CredentialsImpl() + request = mock.Mock() + + # Verifies that passing invalid/non-string URLs synchronously fails safe without crashing. + credentials_instance._maybe_start_regional_access_boundary_refresh( + request, url=None + ) + credentials_instance._maybe_start_regional_access_boundary_refresh(request, url=123) + credentials_instance._maybe_start_regional_access_boundary_refresh( + request, url=object() + ) diff --git a/packages/google-auth/tests/test_external_account.py b/packages/google-auth/tests/test_external_account.py index dc296f7a52ae..870b07d47b6e 100644 --- a/packages/google-auth/tests/test_external_account.py +++ b/packages/google-auth/tests/test_external_account.py @@ -403,29 +403,22 @@ def test_with_scopes_full_options_propagated(self): service_account_impersonation_options={"token_lifetime_seconds": 2800}, ) - with mock.patch.object( - external_account.Credentials, "__init__", return_value=None - ) as mock_init: - credentials.with_scopes(["email"], ["default2"]) - - # Confirm with_scopes initialized the credential with the expected - # parameters and scopes. - mock_init.assert_called_once_with( - audience=self.AUDIENCE, - subject_token_type=self.SUBJECT_TOKEN_TYPE, - token_url=self.TOKEN_URL, - token_info_url=self.TOKEN_INFO_URL, - credential_source=self.CREDENTIAL_SOURCE, - service_account_impersonation_url=self.SERVICE_ACCOUNT_IMPERSONATION_URL, - service_account_impersonation_options={"token_lifetime_seconds": 2800}, - client_id=CLIENT_ID, - client_secret=CLIENT_SECRET, - quota_project_id=self.QUOTA_PROJECT_ID, - scopes=["email"], - default_scopes=["default2"], - universe_domain=DEFAULT_UNIVERSE_DOMAIN, - trust_boundary=None, + cloned = credentials.with_scopes(["email"], ["default2"]) + + assert cloned.scopes == ["email"] + assert cloned.default_scopes == ["default2"] + assert cloned.quota_project_id == self.QUOTA_PROJECT_ID + assert cloned._client_id == CLIENT_ID + assert cloned._client_secret == CLIENT_SECRET + assert cloned._token_info_url == self.TOKEN_INFO_URL + assert ( + cloned._service_account_impersonation_url + == self.SERVICE_ACCOUNT_IMPERSONATION_URL ) + assert cloned._service_account_impersonation_options == { + "token_lifetime_seconds": 2800 + } + assert cloned.universe_domain == DEFAULT_UNIVERSE_DOMAIN def test_with_token_uri(self): credentials = self.make_credentials() @@ -492,33 +485,21 @@ def test_with_quota_project_full_options_propagated(self): service_account_impersonation_options={"token_lifetime_seconds": 2800}, ) - with mock.patch.object( - external_account.Credentials, "__init__", return_value=None - ) as mock_init: - new_cred = credentials.with_quota_project("project-foo") - - # Confirm with_quota_project initialized the credential with the - # expected parameters. - mock_init.assert_called_once_with( - audience=self.AUDIENCE, - subject_token_type=self.SUBJECT_TOKEN_TYPE, - token_url=self.TOKEN_URL, - token_info_url=self.TOKEN_INFO_URL, - credential_source=self.CREDENTIAL_SOURCE, - service_account_impersonation_url=self.SERVICE_ACCOUNT_IMPERSONATION_URL, - service_account_impersonation_options={"token_lifetime_seconds": 2800}, - client_id=CLIENT_ID, - client_secret=CLIENT_SECRET, - quota_project_id=self.QUOTA_PROJECT_ID, - scopes=self.SCOPES, - default_scopes=["default1"], - universe_domain=DEFAULT_UNIVERSE_DOMAIN, - trust_boundary=None, - ) + new_cred = credentials.with_quota_project("project-foo") - # Confirm with_quota_project sets the correct quota project after - # initialization. - assert new_cred.quota_project_id == "project-foo" + assert new_cred.quota_project_id == "project-foo" + assert new_cred.scopes == self.SCOPES + assert new_cred.default_scopes == ["default1"] + assert new_cred._client_id == CLIENT_ID + assert new_cred._client_secret == CLIENT_SECRET + assert new_cred._token_info_url == self.TOKEN_INFO_URL + assert ( + new_cred._service_account_impersonation_url + == self.SERVICE_ACCOUNT_IMPERSONATION_URL + ) + assert new_cred._service_account_impersonation_options == { + "token_lifetime_seconds": 2800 + } def test_info(self): credentials = self.make_credentials(universe_domain="dummy_universe.com") @@ -544,6 +525,23 @@ def test_with_universe_domain(self): new_credentials = credentials.with_universe_domain("dummy_universe.com") assert new_credentials.universe_domain == "dummy_universe.com" + def test_copy_regional_access_boundary_manager_state_and_config(self): + credentials = self.make_credentials() + credentials._rab_manager._data = mock.sentinel.rab_data + credentials._rab_manager._use_blocking_regional_access_boundary_lookup = True + + new_credentials = credentials.with_universe_domain("dummy_universe.com") + + # Verify references to boundary data are shared + assert new_credentials._rab_manager._data == mock.sentinel.rab_data + # Verify blocking config flag is preserved + assert ( + new_credentials._rab_manager._use_blocking_regional_access_boundary_lookup + is True + ) + # Verify target manager object is not replaced + assert new_credentials._rab_manager is not credentials._rab_manager + def test_info_workforce_pool(self): credentials = self.make_workforce_pool_credentials( workforce_pool_user_project=self.WORKFORCE_POOL_USER_PROJECT @@ -979,6 +977,57 @@ def test_refresh_impersonation_without_client_auth_success( assert not credentials.expired assert credentials.token == impersonation_response["accessToken"] + @mock.patch( + "google.auth.metrics.token_request_access_token_impersonate", + return_value=IMPERSONATE_ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE, + ) + @mock.patch( + "google.auth.metrics.python_and_auth_lib_version", + return_value=LANG_LIBRARY_METRICS_HEADER_VALUE, + ) + def test_refresh_impersonation_propagates_rab_config( + self, mock_metrics_header_value, mock_auth_lib_value + ): + expire_time = ( + _helpers.utcnow().replace(microsecond=0) + datetime.timedelta(seconds=2800) + ).isoformat("T") + "Z" + token_response = self.SUCCESS_RESPONSE.copy() + impersonation_response = { + "accessToken": "SA_ACCESS_TOKEN", + "expireTime": expire_time, + } + request = self.make_mock_request( + status=http_client.OK, + data=token_response, + impersonation_status=http_client.OK, + impersonation_data=impersonation_response, + ) + credentials = self.make_credentials( + service_account_impersonation_url=self.SERVICE_ACCOUNT_IMPERSONATION_URL, + scopes=self.SCOPES, + ) + credentials._set_blocking_regional_access_boundary_lookup() + assert ( + credentials._rab_manager._use_blocking_regional_access_boundary_lookup + is True + ) + + credentials.refresh(request) + + assert credentials._impersonated_credentials is not None + assert ( + credentials._impersonated_credentials._rab_manager._use_blocking_regional_access_boundary_lookup + is True + ) + assert ( + credentials._rab_manager._use_blocking_regional_access_boundary_lookup + is True + ) + assert ( + credentials._rab_manager + is credentials._impersonated_credentials._rab_manager + ) + @mock.patch( "google.auth.metrics.token_request_access_token_impersonate", return_value=IMPERSONATE_ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE, @@ -1727,15 +1776,51 @@ def test_before_request_expired(self, utcnow): "authorization": "Bearer {}".format(self.SUCCESS_RESPONSE["access_token"]) } - def test_build_regional_access_boundary_lookup_url_workload(self): + def test_build_regional_access_boundary_lookup_url_workload_standard( + self, monkeypatch + ): + from google.auth.transport import _mtls_helper + + monkeypatch.setattr(_mtls_helper, "check_use_client_cert", lambda: False) + credentials = self.make_credentials() + url = credentials._build_regional_access_boundary_lookup_url() expected_url = "https://iamcredentials.googleapis.com/v1/projects/123456/locations/global/workloadIdentityPools/POOL_ID/allowedLocations" - assert credentials._build_regional_access_boundary_lookup_url() == expected_url + assert url == expected_url + + def test_build_regional_access_boundary_lookup_url_workload_mtls(self, monkeypatch): + from google.auth.transport import _mtls_helper + + monkeypatch.setattr(_mtls_helper, "check_use_client_cert", lambda: True) + + credentials = self.make_credentials() + url = credentials._build_regional_access_boundary_lookup_url() + expected_url = "https://iamcredentials.mtls.googleapis.com/v1/projects/123456/locations/global/workloadIdentityPools/POOL_ID/allowedLocations" + assert url == expected_url + + def test_build_regional_access_boundary_lookup_url_workforce_standard( + self, monkeypatch + ): + from google.auth.transport import _mtls_helper + + monkeypatch.setattr(_mtls_helper, "check_use_client_cert", lambda: False) - def test_build_regional_access_boundary_lookup_url_workforce(self): credentials = self.make_workforce_pool_credentials() + url = credentials._build_regional_access_boundary_lookup_url() expected_url = "https://iamcredentials.googleapis.com/v1/locations/global/workforcePools/POOL_ID/allowedLocations" - assert credentials._build_regional_access_boundary_lookup_url() == expected_url + assert url == expected_url + + def test_build_regional_access_boundary_lookup_url_workforce_mtls( + self, monkeypatch + ): + from google.auth.transport import _mtls_helper + + monkeypatch.setattr(_mtls_helper, "check_use_client_cert", lambda: True) + + credentials = self.make_workforce_pool_credentials() + url = credentials._build_regional_access_boundary_lookup_url() + expected_url = "https://iamcredentials.mtls.googleapis.com/v1/locations/global/workforcePools/POOL_ID/allowedLocations" + assert url == expected_url @pytest.mark.parametrize( "audience", diff --git a/packages/google-auth/tests/test_external_account_authorized_user.py b/packages/google-auth/tests/test_external_account_authorized_user.py index 648966d924bf..69a085e65df5 100644 --- a/packages/google-auth/tests/test_external_account_authorized_user.py +++ b/packages/google-auth/tests/test_external_account_authorized_user.py @@ -601,10 +601,25 @@ def test_from_file_full_options(self, tmpdir): assert creds._revoke_url == REVOKE_URL assert creds._quota_project_id == QUOTA_PROJECT_ID - def test_build_regional_access_boundary_lookup_url(self): + def test_build_regional_access_boundary_lookup_url_standard(self, monkeypatch): + from google.auth.transport import _mtls_helper + + monkeypatch.setattr(_mtls_helper, "check_use_client_cert", lambda: False) + credentials = self.make_credentials() + url = credentials._build_regional_access_boundary_lookup_url() expected_url = "https://iamcredentials.googleapis.com/v1/locations/global/workforcePools/POOL_ID/allowedLocations" - assert credentials._build_regional_access_boundary_lookup_url() == expected_url + assert url == expected_url + + def test_build_regional_access_boundary_lookup_url_mtls(self, monkeypatch): + from google.auth.transport import _mtls_helper + + monkeypatch.setattr(_mtls_helper, "check_use_client_cert", lambda: True) + + credentials = self.make_credentials() + url = credentials._build_regional_access_boundary_lookup_url() + expected_url = "https://iamcredentials.mtls.googleapis.com/v1/locations/global/workforcePools/POOL_ID/allowedLocations" + assert url == expected_url @pytest.mark.parametrize( "audience", diff --git a/packages/google-auth/tests/test_impersonated_credentials.py b/packages/google-auth/tests/test_impersonated_credentials.py index 500209f663d7..c286e3010f38 100644 --- a/packages/google-auth/tests/test_impersonated_credentials.py +++ b/packages/google-auth/tests/test_impersonated_credentials.py @@ -717,13 +717,31 @@ def test_build_regional_access_boundary_lookup_url_no_email(self): assert credentials._build_regional_access_boundary_lookup_url() is None - def test_build_regional_access_boundary_lookup_url_success(self): + def test_build_regional_access_boundary_lookup_url_success_standard( + self, monkeypatch + ): + from google.auth.transport import _mtls_helper + + monkeypatch.setattr(_mtls_helper, "check_use_client_cert", lambda: False) + credentials = self.make_credentials() - # Ensure service_account_email is properly set by default mock + url = credentials._build_regional_access_boundary_lookup_url() expected_url = "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/{}/allowedLocations".format( credentials.service_account_email ) - assert credentials._build_regional_access_boundary_lookup_url() == expected_url + assert url == expected_url + + def test_build_regional_access_boundary_lookup_url_success_mtls(self, monkeypatch): + from google.auth.transport import _mtls_helper + + monkeypatch.setattr(_mtls_helper, "check_use_client_cert", lambda: True) + + credentials = self.make_credentials() + url = credentials._build_regional_access_boundary_lookup_url() + expected_url = "https://iamcredentials.mtls.googleapis.com/v1/projects/-/serviceAccounts/{}/allowedLocations".format( + credentials.service_account_email + ) + assert url == expected_url def test_with_scopes_provide_default_scopes(self): credentials = self.make_credentials() diff --git a/packages/google-auth/tests/test_jwt.py b/packages/google-auth/tests/test_jwt.py index 4c5988469494..27b951b8b7bc 100644 --- a/packages/google-auth/tests/test_jwt.py +++ b/packages/google-auth/tests/test_jwt.py @@ -553,6 +553,57 @@ def test_before_request_refreshes(self): self.credentials.before_request(None, "GET", "http://example.com?a=1#3", {}) assert self.credentials.valid + def test_build_regional_access_boundary_lookup_url_standard(self, monkeypatch): + from google.auth.transport import _mtls_helper + + # Mock check_use_client_cert to return False to simulate standard TLS + monkeypatch.setattr(_mtls_helper, "check_use_client_cert", lambda: False) + + url = self.credentials._build_regional_access_boundary_lookup_url() + expected_url = "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/{}/allowedLocations".format( + self.SERVICE_ACCOUNT_EMAIL + ) + assert url == expected_url + + def test_build_regional_access_boundary_lookup_url_mtls(self, monkeypatch): + from google.auth.transport import _mtls_helper + + # Mock check_use_client_cert to return True to simulate mTLS + monkeypatch.setattr(_mtls_helper, "check_use_client_cert", lambda: True) + + url = self.credentials._build_regional_access_boundary_lookup_url() + expected_url = "https://iamcredentials.mtls.googleapis.com/v1/projects/-/serviceAccounts/{}/allowedLocations".format( + self.SERVICE_ACCOUNT_EMAIL + ) + assert url == expected_url + + def test_cloning_retains_rab_manager_data(self): + self.credentials._rab_manager._data = mock.sentinel.rab_data + + cloned_claims = self.credentials.with_claims(audience="new-audience") + cloned_quota = self.credentials.with_quota_project("new-quota") + + # Verify references to immutable boundary data are shared + assert cloned_claims._rab_manager._data == mock.sentinel.rab_data + assert cloned_quota._rab_manager._data == mock.sentinel.rab_data + + # Verify manager objects and lock properties are isolated to prevent race conditions + assert cloned_claims._rab_manager is not self.credentials._rab_manager + assert cloned_quota._rab_manager is not self.credentials._rab_manager + + def test_from_signing_credentials_copies_rab_state(self): + from google.oauth2 import service_account + + sa_creds = service_account.Credentials.from_service_account_info( + SERVICE_ACCOUNT_INFO + ) + sa_creds._rab_manager._data = mock.sentinel.rab_data + + jwt_creds = jwt.Credentials.from_signing_credentials(sa_creds, audience="aud") + + assert jwt_creds._rab_manager._data == mock.sentinel.rab_data + assert jwt_creds._rab_manager is not sa_creds._rab_manager + class TestOnDemandCredentials(object): SERVICE_ACCOUNT_EMAIL = "service-account@example.com" diff --git a/packages/google-auth/tests_async/oauth2/test__client_async.py b/packages/google-auth/tests_async/oauth2/test__client_async.py index 5ad9596cf85c..a3abd9067186 100644 --- a/packages/google-auth/tests_async/oauth2/test__client_async.py +++ b/packages/google-auth/tests_async/oauth2/test__client_async.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import asyncio import datetime import http.client as http_client import json @@ -23,6 +24,7 @@ from google.auth import _helpers from google.auth import _jwt_async as jwt from google.auth import exceptions +from google.auth.aio import transport as aio_transport from google.oauth2 import _client as sync_client from google.oauth2 import _client_async as _client from tests.oauth2 import test__client as test_client @@ -40,6 +42,17 @@ def make_request(response_data, status=http_client.OK, text=False): return request +def make_aio_request(response_data, status_code=http_client.OK, text=False): + """Creates a mock request/response conforming to the google.auth.aio.transport interface (exposing .status_code and .read()).""" + response = mock.AsyncMock(spec=aio_transport.Response) + response.status_code = status_code + data = response_data if text else json.dumps(response_data).encode("utf-8") + response.read = mock.AsyncMock(return_value=data) + request = mock.AsyncMock(spec=aio_transport.Request) + request.return_value = response + return request + + @pytest.mark.asyncio async def test__token_endpoint_request(): request = make_request({"test": "response"}) @@ -473,7 +486,8 @@ async def test_refresh_grant_retry_with_retry( @pytest.mark.asyncio @pytest.mark.parametrize("can_retry", [True, False]) -async def test__token_endpoint_request_no_throw_with_retry(can_retry): +@mock.patch("time.sleep", return_value=None) +async def test__token_endpoint_request_no_throw_with_retry(mock_sleep, can_retry): mock_request = make_request( {"error": "help", "error_description": "I'm alive"}, http_client.INTERNAL_SERVER_ERROR, @@ -490,5 +504,168 @@ async def test__token_endpoint_request_no_throw_with_retry(can_retry): if can_retry: assert mock_request.call_count == 3 + assert mock_sleep.call_count == 2 else: assert mock_request.call_count == 1 + mock_sleep.assert_not_called() + + +@pytest.mark.asyncio +async def test__lookup_regional_access_boundary_success(): + request = make_aio_request( + {"encodedLocations": "0xA30", "locations": ["us-central1"]} + ) + result = await _client._lookup_regional_access_boundary( + request, "http://example.com" + ) + assert result == {"encodedLocations": "0xA30", "locations": ["us-central1"]} + + +@pytest.mark.asyncio +async def test__lookup_regional_access_boundary_legacy_transport(): + # Create a legacy mock response that has .status and .content() + response = mock.AsyncMock(spec=["transport.Response"]) + response.status = http_client.OK + + data = json.dumps( + {"encodedLocations": "0xA30", "locations": ["us-central1"]} + ).encode("utf-8") + response.content = mock.AsyncMock(return_value=data) + + request = mock.AsyncMock(spec=["transport.Request"]) + request.return_value = response + + result = await _client._lookup_regional_access_boundary( + request, "http://example.com" + ) + assert result == {"encodedLocations": "0xA30", "locations": ["us-central1"]} + + +@pytest.mark.asyncio +async def test__lookup_regional_access_boundary_malformed(): + request = make_aio_request({"locations": ["us-central1"]}) + result = await _client._lookup_regional_access_boundary( + request, "http://example.com" + ) + assert result is None + + +@pytest.mark.asyncio +async def test__lookup_regional_access_boundary_invalid_json(): + request = make_aio_request("Service Unavailable", text=True) + result = await _client._lookup_regional_access_boundary( + request, "http://example.com" + ) + assert result is None + + +@pytest.mark.asyncio +async def test__lookup_regional_access_boundary_non_dict_response(): + request = make_aio_request(123) + result = await _client._lookup_regional_access_boundary( + request, "http://example.com" + ) + assert result is None + + +@pytest.mark.asyncio +@mock.patch("asyncio.wait_for", side_effect=asyncio.TimeoutError) +async def test__lookup_regional_access_boundary_request_no_throw_timeout(mock_wait_for): + request = mock.AsyncMock(spec=["transport.Request"]) + + ( + success, + data, + retryable, + ) = await _client._lookup_regional_access_boundary_request_no_throw( + request, "http://example.com", fail_fast=True + ) + + assert success is False + assert data == {} + assert retryable is True + + +@pytest.mark.asyncio +@mock.patch("asyncio.sleep", new_callable=mock.AsyncMock) +async def test__lookup_regional_access_boundary_request_no_throw_bad_gateway_retry( + mock_sleep, +): + bad_gateway_response = mock.AsyncMock(spec=["transport.Response"]) + bad_gateway_response.status = http_client.BAD_GATEWAY + bad_gateway_response.content = mock.AsyncMock(return_value=b"{}") + + ok_response = mock.AsyncMock(spec=["transport.Response"]) + ok_response.status = http_client.OK + ok_response.content = mock.AsyncMock(return_value=b'{"encodedLocations": "0xA30"}') + + request = mock.AsyncMock(spec=["transport.Request"]) + request.side_effect = [bad_gateway_response, ok_response] + + ( + success, + data, + retryable, + ) = await _client._lookup_regional_access_boundary_request_no_throw( + request, "http://example.com" + ) + + assert success is True + assert data == {"encodedLocations": "0xA30"} + assert request.call_count == 2 + + +@pytest.mark.asyncio +@mock.patch("asyncio.sleep", new_callable=mock.AsyncMock) +async def test__lookup_regional_access_boundary_request_no_throw_transport_error( + mock_sleep, +): + request = mock.AsyncMock(spec=["transport.Request"]) + request.side_effect = exceptions.TransportError("Socket connection failed") + + ( + success, + data, + retryable, + ) = await _client._lookup_regional_access_boundary_request_no_throw( + request, "http://example.com" + ) + + assert success is False + assert data == {} + assert retryable is True + assert request.call_count == 6 + assert mock_sleep.call_count == 5 + + +@pytest.mark.asyncio +@mock.patch("asyncio.sleep", new_callable=mock.AsyncMock) +async def test__lookup_regional_access_boundary_request_no_throw_non_json_bad_gateway_retry( + mock_sleep, +): + bad_gateway_response = mock.AsyncMock(spec=["status", "content"]) + bad_gateway_response.status = http_client.BAD_GATEWAY + bad_gateway_response.content = mock.AsyncMock( + return_value=b"Bad Gateway" + ) + + ok_response = mock.AsyncMock(spec=["status", "content"]) + ok_response.status = http_client.OK + ok_response.content = mock.AsyncMock(return_value=b'{"encodedLocations": "0xA30"}') + + request = mock.AsyncMock(spec=["__call__"]) + request.side_effect = [bad_gateway_response, ok_response] + + ( + success, + data, + retryable, + ) = await _client._lookup_regional_access_boundary_request_no_throw( + request, "http://example.com" + ) + + assert success is True + assert data == {"encodedLocations": "0xA30"} + assert retryable is None + assert request.call_count == 2 + mock_sleep.assert_called_once() diff --git a/packages/google-auth/tests_async/oauth2/test_service_account_async.py b/packages/google-auth/tests_async/oauth2/test_service_account_async.py index 5a9a89fcaac2..e0c2e0d60a60 100644 --- a/packages/google-auth/tests_async/oauth2/test_service_account_async.py +++ b/packages/google-auth/tests_async/oauth2/test_service_account_async.py @@ -229,6 +229,143 @@ async def test_before_request_refreshes(self, jwt_grant): # Credentials should now be valid. assert credentials.valid + @pytest.mark.asyncio + async def test_before_request_triggers_rab_refresh(self): + credentials = self.make_credentials() + credentials.token = "tok" + + request = mock.AsyncMock(spec=["transport.Request"]) + headers1 = {} + + with mock.patch.object( + credentials, + "_lookup_regional_access_boundary", + new_callable=mock.AsyncMock, + ) as mock_lookup, mock.patch.object( + credentials, + "_is_regional_access_boundary_lookup_required", + return_value=True, + ): + mock_lookup.return_value = { + "locations": ["us-central1", "europe-west1"], + "encodedLocations": "0xA30", + } + + # The first request triggers a background refresh and returns immediately. + await credentials.before_request( + request, "GET", "https://storage.googleapis.com/bucket", headers1 + ) + assert "x-allowed-locations" not in headers1 + + # Wait for the background task to finish and update the cache. + await credentials._rab_manager.refresh_manager._worker_task + mock_lookup.assert_called_once_with(request) + + # The second request retrieves the locations from the cache. + headers2 = {} + await credentials.before_request( + request, "GET", "https://storage.googleapis.com/bucket", headers2 + ) + assert headers2["x-allowed-locations"] == "0xA30" + + @pytest.mark.asyncio + async def test_before_request_rab_refresh_failure_ignored(self): + credentials = self.make_credentials() + credentials.token = "tok" + + request = mock.AsyncMock(spec=["transport.Request"]) + headers = {} + + with mock.patch.object( + credentials, + "_lookup_regional_access_boundary", + new_callable=mock.AsyncMock, + side_effect=Exception("Transport failed"), + ) as mock_lookup, mock.patch.object( + credentials, + "_is_regional_access_boundary_lookup_required", + return_value=True, + ): + # Any transport/lookup failure must be caught gracefully during refresh. + await credentials.before_request( + request, "GET", "https://storage.googleapis.com/bucket", headers + ) + + # Wait for the background task to finish. + await credentials._rab_manager.refresh_manager._worker_task + + mock_lookup.assert_called_once_with(request) + assert "x-allowed-locations" not in headers + + @pytest.mark.asyncio + async def test_before_request_triggers_blocking_rab_refresh(self): + credentials = self.make_credentials() + credentials.token = "tok" + credentials._set_blocking_regional_access_boundary_lookup() + + request = mock.AsyncMock(spec=["transport.Request"]) + headers = {} + + with mock.patch.object( + credentials, + "_lookup_regional_access_boundary", + new_callable=mock.AsyncMock, + ) as mock_lookup, mock.patch.object( + credentials, + "_is_regional_access_boundary_lookup_required", + return_value=True, + ): + mock_lookup.return_value = { + "locations": ["us-central1", "europe-west1"], + "encodedLocations": "0xA30", + } + + # When blocking lookup is enabled, the first request awaits the lookup sequentially. + await credentials.before_request( + request, "GET", "https://storage.googleapis.com/bucket", headers + ) + + mock_lookup.assert_called_once_with(request, fail_fast=True) + assert headers["x-allowed-locations"] == "0xA30" + + @pytest.mark.asyncio + async def test_maybe_start_regional_access_boundary_refresh_async_invalid_url(self): + credentials = self.make_credentials() + request = mock.create_autospec(transport.Request) + + # Verifies that passing invalid/non-string URLs asynchronously fails safe without crashing. + await credentials._maybe_start_regional_access_boundary_refresh_async( + request, url=None + ) + await credentials._maybe_start_regional_access_boundary_refresh_async( + request, url=123 + ) + await credentials._maybe_start_regional_access_boundary_refresh_async( + request, url=object() + ) + + def test_unpickle_old_credentials_without_rab(self): + from google.auth import _regional_access_boundary_utils + + credentials = self.make_credentials() + old_state = credentials.__dict__.copy() + if "_rab_manager" in old_state: + del old_state["_rab_manager"] + if "_use_non_blocking_refresh" in old_state: + del old_state["_use_non_blocking_refresh"] + if "_refresh_worker" in old_state: + del old_state["_refresh_worker"] + + new_instance = type(credentials).__new__(type(credentials)) + new_instance.__setstate__(old_state) + + # Verify the manager was correctly restored with the async refresh manager! + assert hasattr(new_instance, "_rab_manager") + assert isinstance( + new_instance._rab_manager.refresh_manager, + _regional_access_boundary_utils._AsyncRegionalAccessBoundaryRefreshManager, + ) + class TestIDTokenCredentials(object): SERVICE_ACCOUNT_EMAIL = "service-account@example.com" diff --git a/packages/google-auth/tests_async/test__regional_access_boundary_utils.py b/packages/google-auth/tests_async/test__regional_access_boundary_utils.py new file mode 100644 index 000000000000..268ee37261c8 --- /dev/null +++ b/packages/google-auth/tests_async/test__regional_access_boundary_utils.py @@ -0,0 +1,84 @@ +# Copyright 2026 Google Inc. +# +# 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 asyncio +from unittest import mock + +import pytest # type: ignore + +from google.auth import _regional_access_boundary_utils + + +@pytest.mark.asyncio +async def test_async_refresh_manager_start_refresh(): + credentials = mock.AsyncMock() + credentials._lookup_regional_access_boundary.return_value = { + "encodedLocations": "0xA30" + } + + request = mock.Mock() + rab_manager = mock.Mock() + + manager = ( + _regional_access_boundary_utils._AsyncRegionalAccessBoundaryRefreshManager() + ) + + manager.start_refresh(credentials, request, rab_manager) + + # Wait for the background task to finish + await manager._worker_task + + credentials._lookup_regional_access_boundary.assert_called_once_with(request) + rab_manager.process_regional_access_boundary_info.assert_called_once_with( + {"encodedLocations": "0xA30"} + ) + + +@pytest.mark.asyncio +async def test_async_refresh_manager_duplicate_refresh_prevented(): + credentials = mock.AsyncMock() + + # Use events to control the concurrency timing + lookup_started = asyncio.Event() + lookup_finish = asyncio.Event() + + async def controlled_lookup(*args, **kwargs): + lookup_started.set() # Signal that the background lookup has started. + await lookup_finish.wait() # Block until the test allows the lookup to complete. + return {"encodedLocations": "0xA30"} + + credentials._lookup_regional_access_boundary.side_effect = controlled_lookup + + request = mock.Mock() + rab_manager = mock.Mock() + + manager = ( + _regional_access_boundary_utils._AsyncRegionalAccessBoundaryRefreshManager() + ) + + # Start the initial refresh task in the background. + manager.start_refresh(credentials, request, rab_manager) + + # Wait until the background task has begun executing the lookup. + await lookup_started.wait() + + # Attempt a second refresh while the initial task is still in progress. + manager.start_refresh(credentials, request, rab_manager) + + # Unblock the initial task and wait for it to complete. + lookup_finish.set() + await manager._worker_task + + # Verify that the second refresh request was ignored and only one lookup occurred. + assert credentials._lookup_regional_access_boundary.call_count == 1 diff --git a/packages/google-auth/tests_async/test_jwt_async.py b/packages/google-auth/tests_async/test_jwt_async.py index 9d9eca4e2852..9e6054fa93ef 100644 --- a/packages/google-auth/tests_async/test_jwt_async.py +++ b/packages/google-auth/tests_async/test_jwt_async.py @@ -143,6 +143,47 @@ def test_with_quota_project(self): assert new_credentials._additional_claims == self.credentials._additional_claims assert new_credentials._quota_project_id == quota_project_id + def test_build_regional_access_boundary_lookup_url_standard(self, monkeypatch): + from google.auth.transport import _mtls_helper + + # Mock check_use_client_cert to return False to simulate standard TLS + monkeypatch.setattr(_mtls_helper, "check_use_client_cert", lambda: False) + + url = self.credentials._build_regional_access_boundary_lookup_url() + expected_url = "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/{}/allowedLocations".format( + self.SERVICE_ACCOUNT_EMAIL + ) + assert url == expected_url + + def test_build_regional_access_boundary_lookup_url_mtls(self, monkeypatch): + from google.auth.transport import _mtls_helper + + # Mock check_use_client_cert to return True to simulate mTLS + monkeypatch.setattr(_mtls_helper, "check_use_client_cert", lambda: True) + + url = self.credentials._build_regional_access_boundary_lookup_url() + expected_url = "https://iamcredentials.mtls.googleapis.com/v1/projects/-/serviceAccounts/{}/allowedLocations".format( + self.SERVICE_ACCOUNT_EMAIL + ) + assert url == expected_url + + def test_unpickle_old_credentials_without_rab(self): + from google.auth import _regional_access_boundary_utils + + credentials = self.credentials + old_state = credentials.__dict__.copy() + if "_rab_manager" in old_state: + del old_state["_rab_manager"] + + new_instance = type(credentials).__new__(type(credentials)) + new_instance.__setstate__(old_state) + + assert hasattr(new_instance, "_rab_manager") + assert isinstance( + new_instance._rab_manager.refresh_manager, + _regional_access_boundary_utils._AsyncRegionalAccessBoundaryRefreshManager, + ) + def test_sign_bytes(self): to_sign = b"123" signature = self.credentials.sign_bytes(to_sign) @@ -326,10 +367,11 @@ def test_refresh(self): with pytest.raises(exceptions.RefreshError): self.credentials.refresh(None) - def test_before_request(self): + @pytest.mark.asyncio + async def test_before_request(self): headers = {} - self.credentials.before_request( + await self.credentials.before_request( None, "GET", "http://example.com?a=1#3", headers ) @@ -339,7 +381,9 @@ def test_before_request(self): assert payload["aud"] == "http://example.com" # Making another request should re-use the same token. - self.credentials.before_request(None, "GET", "http://example.com?b=2", headers) + await self.credentials.before_request( + None, "GET", "http://example.com?b=2", headers + ) _, new_token = headers["authorization"].split(" ") From 2695aad5c2949e20e77ae9dd432c6fc8ef787952 Mon Sep 17 00:00:00 2001 From: Anwesha Das Date: Fri, 5 Jun 2026 13:24:35 -0400 Subject: [PATCH 035/174] feat(bigtable): add view_parameters support to execute_query (#17382) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly: - [ ] Make sure to open an issue as a [bug/issue](https://github.com/googleapis/google-cloud-python/issues) before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea - [ ] Ensure the tests and linter pass - [ ] Code coverage does not decrease (if any source code was changed) - [ ] Appropriate docs were updated (if necessary) Fixes # 🦕 --- .../cloud/bigtable/data/_async/client.py | 6 +++ .../bigtable/data/_sync_autogen/client.py | 6 +++ .../execute_query/_parameters_formatting.py | 21 ++++++++++ .../tests/unit/data/_async/test_client.py | 38 +++++++++++++++++++ .../unit/data/_sync_autogen/test_client.py | 36 ++++++++++++++++++ 5 files changed, 107 insertions(+) diff --git a/packages/google-cloud-bigtable/google/cloud/bigtable/data/_async/client.py b/packages/google-cloud-bigtable/google/cloud/bigtable/data/_async/client.py index 1a404d0b55b8..24da33318677 100644 --- a/packages/google-cloud-bigtable/google/cloud/bigtable/data/_async/client.py +++ b/packages/google-cloud-bigtable/google/cloud/bigtable/data/_async/client.py @@ -74,6 +74,7 @@ ) from google.cloud.bigtable.data.execute_query._parameters_formatting import ( _format_execute_query_params, + _format_execute_query_view_params, _to_param_types, ) from google.cloud.bigtable.data.execute_query.metadata import ( @@ -717,6 +718,7 @@ async def execute_query( *, parameters: dict[str, ExecuteQueryValueType] | None = None, parameter_types: dict[str, SqlType.Type] | None = None, + view_parameters: dict[str, str] | None = None, app_profile_id: str | None = None, operation_timeout: float = 600, attempt_timeout: float | None = 20, @@ -758,6 +760,8 @@ async def execute_query( Required to contain entries only for parameters whose type cannot be detected automatically (i.e. the value can be None, an empty list or an empty dict). + view_parameters: Dictionary with values for all view parameters. Currently only + string values are supported. app_profile_id: The app profile to associate with requests. https://cloud.google.com/bigtable/docs/app-profiles operation_timeout: the time budget for the entire executeQuery operation, in seconds. @@ -883,12 +887,14 @@ async def execute_query( retryable_excs = [_get_error_type(e) for e in retryable_errors] pb_params = _format_execute_query_params(parameters, parameter_types) + pb_view_params = _format_execute_query_view_params(view_parameters) request_body = { "instance_name": instance_name, "app_profile_id": app_profile_id, "prepared_query": prepare_result.prepared_query, "params": pb_params, + "view_parameters": pb_view_params, } operation_timeout, attempt_timeout = _align_timeouts( operation_timeout, attempt_timeout diff --git a/packages/google-cloud-bigtable/google/cloud/bigtable/data/_sync_autogen/client.py b/packages/google-cloud-bigtable/google/cloud/bigtable/data/_sync_autogen/client.py index 854a596254b1..636ea854137d 100644 --- a/packages/google-cloud-bigtable/google/cloud/bigtable/data/_sync_autogen/client.py +++ b/packages/google-cloud-bigtable/google/cloud/bigtable/data/_sync_autogen/client.py @@ -75,6 +75,7 @@ ) from google.cloud.bigtable.data.execute_query._parameters_formatting import ( _format_execute_query_params, + _format_execute_query_view_params, _to_param_types, ) from google.cloud.bigtable.data.execute_query.metadata import ( @@ -532,6 +533,7 @@ def execute_query( *, parameters: dict[str, ExecuteQueryValueType] | None = None, parameter_types: dict[str, SqlType.Type] | None = None, + view_parameters: dict[str, str] | None = None, app_profile_id: str | None = None, operation_timeout: float = 600, attempt_timeout: float | None = 20, @@ -572,6 +574,8 @@ def execute_query( Required to contain entries only for parameters whose type cannot be detected automatically (i.e. the value can be None, an empty list or an empty dict). + view_parameters: Dictionary with values for all view parameters. Currently only + string values are supported. app_profile_id: The app profile to associate with requests. https://cloud.google.com/bigtable/docs/app-profiles operation_timeout: the time budget for the entire executeQuery operation, in seconds. @@ -692,11 +696,13 @@ def execute_query( prepare_metadata = _pb_metadata_to_metadata_types(prepare_result.metadata) retryable_excs = [_get_error_type(e) for e in retryable_errors] pb_params = _format_execute_query_params(parameters, parameter_types) + pb_view_params = _format_execute_query_view_params(view_parameters) request_body = { "instance_name": instance_name, "app_profile_id": app_profile_id, "prepared_query": prepare_result.prepared_query, "params": pb_params, + "view_parameters": pb_view_params, } operation_timeout, attempt_timeout = _align_timeouts( operation_timeout, attempt_timeout diff --git a/packages/google-cloud-bigtable/google/cloud/bigtable/data/execute_query/_parameters_formatting.py b/packages/google-cloud-bigtable/google/cloud/bigtable/data/execute_query/_parameters_formatting.py index ed7e946e8455..816e9fbe1180 100644 --- a/packages/google-cloud-bigtable/google/cloud/bigtable/data/execute_query/_parameters_formatting.py +++ b/packages/google-cloud-bigtable/google/cloud/bigtable/data/execute_query/_parameters_formatting.py @@ -23,6 +23,27 @@ from google.cloud.bigtable_v2.types.data import Value +def _format_execute_query_view_params( + view_parameters: Optional[Dict[str, str]], +) -> Dict[str, Value]: + """ + Takes a dictionary of view_param_name -> view_param_value (string) and formats + them into a dictionary of string-typed Value objects. + """ + if not view_parameters: + return {} + + result_values = {} + for key, value in view_parameters.items(): + if not isinstance(value, str): + raise TypeError( + f"View parameter {key} must be a string, got {type(value).__name__}" + ) + result_values[key] = Value(string_value=value) + + return result_values + + def _format_execute_query_params( params: Optional[Dict[str, ExecuteQueryValueType]], parameter_types: Optional[Dict[str, SqlType.Type]], diff --git a/packages/google-cloud-bigtable/tests/unit/data/_async/test_client.py b/packages/google-cloud-bigtable/tests/unit/data/_async/test_client.py index b0d67ecc2496..76b7d5c3f3f4 100644 --- a/packages/google-cloud-bigtable/tests/unit/data/_async/test_client.py +++ b/packages/google-cloud-bigtable/tests/unit/data/_async/test_client.py @@ -3507,6 +3507,44 @@ async def test_execute_query_with_params( assert execute_query_mock.call_count == 1 assert prepare_mock.call_count == 1 + @CrossSync.pytest + async def test_execute_query_with_view_parameters( + self, client, execute_query_mock, prepare_mock + ): + values = [ + *chunked_responses(2, str_val("test2"), int_val(9), token=b"r2"), + ] + execute_query_mock.return_value = self._make_gapic_stream(values) + query_str = f"SELECT a, b FROM {self.TABLE_NAME} WHERE user_id = VIEW_PARAMETERS('user_id')" + result = await client.execute_query( + query_str, + self.INSTANCE_NAME, + view_parameters={"user_id": "alice"}, + ) + results = [r async for r in result] + assert len(results) == 1 + assert results[0]["a"] == "test2" + assert results[0]["b"] == 9 + assert execute_query_mock.call_count == 1 + assert prepare_mock.call_count == 1 + assert prepare_mock.call_args[1]["request"]["query"] == query_str + + request = execute_query_mock.call_args[0][0] + assert "user_id" in request.view_parameters + assert request.view_parameters["user_id"].string_value == "alice" + + @CrossSync.pytest + async def test_execute_query_with_view_parameters_invalid_type( + self, client, execute_query_mock, prepare_mock + ): + with pytest.raises(TypeError) as e: + await client.execute_query( + f"SELECT a, b FROM {self.TABLE_NAME}", + self.INSTANCE_NAME, + view_parameters={"user_id": 123}, + ) + assert "View parameter user_id must be a string, got int" in str(e.value) + @CrossSync.pytest async def test_execute_query_error_before_metadata( self, client, execute_query_mock, prepare_mock diff --git a/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_client.py b/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_client.py index e5041161b0fc..9a7939ce7c1c 100644 --- a/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_client.py +++ b/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_client.py @@ -2973,6 +2973,42 @@ def test_execute_query_with_params(self, client, execute_query_mock, prepare_moc assert execute_query_mock.call_count == 1 assert prepare_mock.call_count == 1 + def test_execute_query_with_view_parameters( + self, client, execute_query_mock, prepare_mock + ): + values = [ + *chunked_responses(2, str_val("test2"), int_val(9), token=b"r2"), + ] + execute_query_mock.return_value = self._make_gapic_stream(values) + query_str = f"SELECT a, b FROM {self.TABLE_NAME} WHERE user_id = VIEW_PARAMETERS('user_id')" + result = client.execute_query( + query_str, + self.INSTANCE_NAME, + view_parameters={"user_id": "alice"}, + ) + results = [r for r in result] + assert len(results) == 1 + assert results[0]["a"] == "test2" + assert results[0]["b"] == 9 + assert execute_query_mock.call_count == 1 + assert prepare_mock.call_count == 1 + assert prepare_mock.call_args[1]["request"]["query"] == query_str + + request = execute_query_mock.call_args[0][0] + assert "user_id" in request.view_parameters + assert request.view_parameters["user_id"].string_value == "alice" + + def test_execute_query_with_view_parameters_invalid_type( + self, client, execute_query_mock, prepare_mock + ): + with pytest.raises(TypeError) as e: + client.execute_query( + f"SELECT a, b FROM {self.TABLE_NAME}", + self.INSTANCE_NAME, + view_parameters={"user_id": 123}, + ) + assert "View parameter user_id must be a string, got int" in str(e.value) + def test_execute_query_error_before_metadata( self, client, execute_query_mock, prepare_mock ): From 33ba3afe520e2f64ac7464f1b4ee31c0624a65ac Mon Sep 17 00:00:00 2001 From: Tomo Suzuki Date: Fri, 5 Jun 2026 15:44:21 -0400 Subject: [PATCH 036/174] chore: update googleapis and regenerate (#17383) Update googleapis to the latest commit and regenerate all client libraries. This includes https://github.com/googleapis/googleapis/commit/ff15be54722218705740b9fc6223d264c4cdb6dd "feat: initial release of the Agent Identity Credentials API (v1)". We can run `librarian add` after this commit. --- librarian.yaml | 4 +- .../services/bigtable/async_client.py | 12 +- .../bigtable_v2/services/bigtable/client.py | 12 +- .../services/bigtable/transports/grpc.py | 12 +- .../bigtable/transports/grpc_asyncio.py | 12 +- .../cloud/bigtable_v2/types/bigtable.py | 41 +- .../google/cloud/dlp/__init__.py | 6 + .../google/cloud/dlp_v2/__init__.py | 6 + .../google/cloud/dlp_v2/types/__init__.py | 6 + .../google/cloud/dlp_v2/types/dlp.py | 76 +- .../geminidataanalytics_v1beta/__init__.py | 24 + .../data_agent_service/async_client.py | 2 + .../services/data_agent_service/client.py | 24 + .../data_chat_service/async_client.py | 5 +- .../services/data_chat_service/client.py | 27 +- .../data_chat_service/transports/grpc.py | 3 +- .../transports/grpc_asyncio.py | 3 +- .../types/__init__.py | 24 + .../types/context.py | 407 +++++- .../types/conversation.py | 35 +- .../types/data_agent.py | 13 + .../types/data_chat_service.py | 212 ++- .../types/datasource.py | 183 ++- .../test_data_agent_service.py | 246 +++- .../test_data_chat_service.py | 95 +- .../tests/system/test_zonal.py | 1 - .../services/workstations/async_client.py | 24 +- .../services/workstations/client.py | 24 +- .../services/workstations/transports/grpc.py | 3 +- .../workstations/transports/grpc_asyncio.py | 3 +- .../workstations_v1/types/workstations.py | 879 +++++++++++- .../cloud/workstations_v1beta/__init__.py | 4 + .../workstations_v1beta/gapic_metadata.json | 15 + .../services/workstations/async_client.py | 155 +- .../services/workstations/client.py | 152 +- .../services/workstations/transports/base.py | 14 + .../services/workstations/transports/grpc.py | 32 +- .../workstations/transports/grpc_asyncio.py | 39 +- .../services/workstations/transports/rest.py | 217 +++ .../workstations/transports/rest_base.py | 57 + .../workstations_v1beta/types/__init__.py | 4 + .../workstations_v1beta/types/workstations.py | 1078 +++++++++++++- ...data_google.cloud.workstations.v1beta.json | 161 +++ ...ted_workstations_push_credentials_async.py | 57 + ...ated_workstations_push_credentials_sync.py | 57 + .../workstations_v1/test_workstations.py | 188 +++ .../workstations_v1beta/test_workstations.py | 1262 +++++++++++++++-- 47 files changed, 5476 insertions(+), 440 deletions(-) create mode 100644 packages/google-cloud-workstations/samples/generated_samples/workstations_v1beta_generated_workstations_push_credentials_async.py create mode 100644 packages/google-cloud-workstations/samples/generated_samples/workstations_v1beta_generated_workstations_push_credentials_sync.py diff --git a/librarian.yaml b/librarian.yaml index c1a78b3f5094..2ff93a45f04d 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -16,8 +16,8 @@ version: v0.16.0 repo: googleapis/google-cloud-python sources: googleapis: - commit: c73334a47800ba03cc65e46ade96c07f01db3446 - sha256: 07be59c8bc1dfc420e352db0528641baa23943e7dd1659acac41ca55969fb259 + commit: ff15be54722218705740b9fc6223d264c4cdb6dd + sha256: 13dc3b1a01767be8d486980d3ddcb7fe6f6b89c3da8d41c358d5c2536c86de3c default: output: packages tag_format: '{name}-v{version}' diff --git a/packages/google-cloud-bigtable/google/cloud/bigtable_v2/services/bigtable/async_client.py b/packages/google-cloud-bigtable/google/cloud/bigtable_v2/services/bigtable/async_client.py index b794a173d89a..c91d8c72771a 100644 --- a/packages/google-cloud-bigtable/google/cloud/bigtable_v2/services/bigtable/async_client.py +++ b/packages/google-cloud-bigtable/google/cloud/bigtable_v2/services/bigtable/async_client.py @@ -438,11 +438,13 @@ def sample_row_keys( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> Awaitable[AsyncIterable[bigtable.SampleRowKeysResponse]]: - r"""Returns a sample of row keys in the table. The - returned row keys will delimit contiguous sections of - the table of approximately equal size, which can be used - to break up the data for distributed tasks like - mapreduces. + r"""Returns a sample of row keys in the table. The returned row keys + will delimit contiguous sections of the table of approximately + equal size, which can be used to break up the data for + distributed tasks like mapreduces. + + If a ``row_range`` is provided in the request, the returned + samples will be restricted to the specified range. Args: request (Optional[Union[google.cloud.bigtable_v2.types.SampleRowKeysRequest, dict]]): diff --git a/packages/google-cloud-bigtable/google/cloud/bigtable_v2/services/bigtable/client.py b/packages/google-cloud-bigtable/google/cloud/bigtable_v2/services/bigtable/client.py index 2e98f59ff944..92dbae5d1c5d 100644 --- a/packages/google-cloud-bigtable/google/cloud/bigtable_v2/services/bigtable/client.py +++ b/packages/google-cloud-bigtable/google/cloud/bigtable_v2/services/bigtable/client.py @@ -928,11 +928,13 @@ def sample_row_keys( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> Iterable[bigtable.SampleRowKeysResponse]: - r"""Returns a sample of row keys in the table. The - returned row keys will delimit contiguous sections of - the table of approximately equal size, which can be used - to break up the data for distributed tasks like - mapreduces. + r"""Returns a sample of row keys in the table. The returned row keys + will delimit contiguous sections of the table of approximately + equal size, which can be used to break up the data for + distributed tasks like mapreduces. + + If a ``row_range`` is provided in the request, the returned + samples will be restricted to the specified range. Args: request (Union[google.cloud.bigtable_v2.types.SampleRowKeysRequest, dict]): diff --git a/packages/google-cloud-bigtable/google/cloud/bigtable_v2/services/bigtable/transports/grpc.py b/packages/google-cloud-bigtable/google/cloud/bigtable_v2/services/bigtable/transports/grpc.py index 9d0bae86fd72..b4efced84827 100644 --- a/packages/google-cloud-bigtable/google/cloud/bigtable_v2/services/bigtable/transports/grpc.py +++ b/packages/google-cloud-bigtable/google/cloud/bigtable_v2/services/bigtable/transports/grpc.py @@ -363,11 +363,13 @@ def sample_row_keys( ) -> Callable[[bigtable.SampleRowKeysRequest], bigtable.SampleRowKeysResponse]: r"""Return a callable for the sample row keys method over gRPC. - Returns a sample of row keys in the table. The - returned row keys will delimit contiguous sections of - the table of approximately equal size, which can be used - to break up the data for distributed tasks like - mapreduces. + Returns a sample of row keys in the table. The returned row keys + will delimit contiguous sections of the table of approximately + equal size, which can be used to break up the data for + distributed tasks like mapreduces. + + If a ``row_range`` is provided in the request, the returned + samples will be restricted to the specified range. Returns: Callable[[~.SampleRowKeysRequest], diff --git a/packages/google-cloud-bigtable/google/cloud/bigtable_v2/services/bigtable/transports/grpc_asyncio.py b/packages/google-cloud-bigtable/google/cloud/bigtable_v2/services/bigtable/transports/grpc_asyncio.py index dfa4b4c24a91..83bd59e725cc 100644 --- a/packages/google-cloud-bigtable/google/cloud/bigtable_v2/services/bigtable/transports/grpc_asyncio.py +++ b/packages/google-cloud-bigtable/google/cloud/bigtable_v2/services/bigtable/transports/grpc_asyncio.py @@ -373,11 +373,13 @@ def sample_row_keys( ]: r"""Return a callable for the sample row keys method over gRPC. - Returns a sample of row keys in the table. The - returned row keys will delimit contiguous sections of - the table of approximately equal size, which can be used - to break up the data for distributed tasks like - mapreduces. + Returns a sample of row keys in the table. The returned row keys + will delimit contiguous sections of the table of approximately + equal size, which can be used to break up the data for + distributed tasks like mapreduces. + + If a ``row_range`` is provided in the request, the returned + samples will be restricted to the specified range. Returns: Callable[[~.SampleRowKeysRequest], diff --git a/packages/google-cloud-bigtable/google/cloud/bigtable_v2/types/bigtable.py b/packages/google-cloud-bigtable/google/cloud/bigtable_v2/types/bigtable.py index bf63f4d1e12e..24e3ae5ea280 100644 --- a/packages/google-cloud-bigtable/google/cloud/bigtable_v2/types/bigtable.py +++ b/packages/google-cloud-bigtable/google/cloud/bigtable_v2/types/bigtable.py @@ -358,6 +358,11 @@ class SampleRowKeysRequest(proto.Message): This value specifies routing for replication. If not specified, the "default" application profile will be used. + row_range (google.cloud.bigtable_v2.types.RowRange): + Optional. The row range to sample. If not + specified, samples from all rows. + The output will always return the end key in the + range as the last sample returned. """ table_name: str = proto.Field( @@ -376,6 +381,11 @@ class SampleRowKeysRequest(proto.Message): proto.STRING, number=2, ) + row_range: data.RowRange = proto.Field( + proto.MESSAGE, + number=6, + message=data.RowRange, + ) class SampleRowKeysResponse(proto.Message): @@ -383,23 +393,24 @@ class SampleRowKeysResponse(proto.Message): Attributes: row_key (bytes): - Sorted streamed sequence of sample row keys - in the table. The table might have contents - before the first row key in the list and after - the last one, but a key containing the empty - string indicates "end of table" and will be the - last response given, if present. - Note that row keys in this list may not have - ever been written to or read from, and users - should therefore not make any assumptions about - the row key structure that are specific to their - use case. + Sorted streamed sequence of sample row keys in the table, + restricted to the row_range if specified in the request. The + table might have contents before the first row key in the + list and after the last one, but a key containing the empty + string indicates "end of table" and will be the last + response given, if present and within the row-range + specified in the request. Note that row keys in this list + may not have ever been written to or read from, and users + should therefore not make any assumptions about the row key + structure that are specific to their use case. offset_bytes (int): Approximate total storage space used by all rows in the - table which precede ``row_key``. Buffering the contents of - all rows between two subsequent samples would require space - roughly equal to the difference in their ``offset_bytes`` - fields. + table which precede ``row_key`` (and if a row-range is + specified in the request, which follow what would have been + the previous sample before the row-range start). Buffering + the contents of all rows between two subsequent samples + would require space roughly equal to the difference in their + ``offset_bytes`` fields. """ row_key: bytes = proto.Field( diff --git a/packages/google-cloud-dlp/google/cloud/dlp/__init__.py b/packages/google-cloud-dlp/google/cloud/dlp/__init__.py index f4e3d6a1ec2e..17c72787aa6d 100644 --- a/packages/google-cloud-dlp/google/cloud/dlp/__init__.py +++ b/packages/google-cloud-dlp/google/cloud/dlp/__init__.py @@ -35,6 +35,8 @@ AnalyzeDataSourceRiskDetails, AwsAccount, AwsAccountRegex, + BatchContentItem, + BatchContentLocation, BigQueryDiscoveryTarget, BigQueryRegex, BigQueryRegexes, @@ -280,6 +282,7 @@ StoredInfoTypeState, StoredInfoTypeStats, StoredInfoTypeVersion, + StringValueBatch, Table, TableDataProfile, TableLocation, @@ -363,6 +366,8 @@ "AnalyzeDataSourceRiskDetails", "AwsAccount", "AwsAccountRegex", + "BatchContentItem", + "BatchContentLocation", "BigQueryDiscoveryTarget", "BigQueryRegex", "BigQueryRegexes", @@ -591,6 +596,7 @@ "StoredInfoTypeConfig", "StoredInfoTypeStats", "StoredInfoTypeVersion", + "StringValueBatch", "Table", "TableDataProfile", "TableLocation", diff --git a/packages/google-cloud-dlp/google/cloud/dlp_v2/__init__.py b/packages/google-cloud-dlp/google/cloud/dlp_v2/__init__.py index 4bc8431e09e9..350174be60ef 100644 --- a/packages/google-cloud-dlp/google/cloud/dlp_v2/__init__.py +++ b/packages/google-cloud-dlp/google/cloud/dlp_v2/__init__.py @@ -39,6 +39,8 @@ AnalyzeDataSourceRiskDetails, AwsAccount, AwsAccountRegex, + BatchContentItem, + BatchContentLocation, BigQueryDiscoveryTarget, BigQueryRegex, BigQueryRegexes, @@ -284,6 +286,7 @@ StoredInfoTypeState, StoredInfoTypeStats, StoredInfoTypeVersion, + StringValueBatch, Table, TableDataProfile, TableLocation, @@ -449,6 +452,8 @@ def _get_version(dependency_name): "AnalyzeDataSourceRiskDetails", "AwsAccount", "AwsAccountRegex", + "BatchContentItem", + "BatchContentLocation", "BigQueryDiscoveryTarget", "BigQueryField", "BigQueryKey", @@ -719,6 +724,7 @@ def _get_version(dependency_name): "StoredInfoTypeStats", "StoredInfoTypeVersion", "StoredType", + "StringValueBatch", "Table", "TableDataProfile", "TableLocation", diff --git a/packages/google-cloud-dlp/google/cloud/dlp_v2/types/__init__.py b/packages/google-cloud-dlp/google/cloud/dlp_v2/types/__init__.py index 0b416e4fa3a0..bc666e4f520f 100644 --- a/packages/google-cloud-dlp/google/cloud/dlp_v2/types/__init__.py +++ b/packages/google-cloud-dlp/google/cloud/dlp_v2/types/__init__.py @@ -28,6 +28,8 @@ AnalyzeDataSourceRiskDetails, AwsAccount, AwsAccountRegex, + BatchContentItem, + BatchContentLocation, BigQueryDiscoveryTarget, BigQueryRegex, BigQueryRegexes, @@ -273,6 +275,7 @@ StoredInfoTypeState, StoredInfoTypeStats, StoredInfoTypeVersion, + StringValueBatch, Table, TableDataProfile, TableLocation, @@ -354,6 +357,8 @@ "AnalyzeDataSourceRiskDetails", "AwsAccount", "AwsAccountRegex", + "BatchContentItem", + "BatchContentLocation", "BigQueryDiscoveryTarget", "BigQueryRegex", "BigQueryRegexes", @@ -582,6 +587,7 @@ "StoredInfoTypeConfig", "StoredInfoTypeStats", "StoredInfoTypeVersion", + "StringValueBatch", "Table", "TableDataProfile", "TableLocation", diff --git a/packages/google-cloud-dlp/google/cloud/dlp_v2/types/dlp.py b/packages/google-cloud-dlp/google/cloud/dlp_v2/types/dlp.py index 567cd1d2d95d..922359158fdc 100644 --- a/packages/google-cloud-dlp/google/cloud/dlp_v2/types/dlp.py +++ b/packages/google-cloud-dlp/google/cloud/dlp_v2/types/dlp.py @@ -68,6 +68,8 @@ "ContentMetadata", "Conversation", "ConversationMessage", + "BatchContentItem", + "StringValueBatch", "Table", "KeyValueMetadataProperty", "InspectResult", @@ -75,6 +77,7 @@ "Location", "ContentLocation", "ConversationLocation", + "BatchContentLocation", "MetadataLocation", "StorageMetadataLabel", "KeyValueMetadataLabel", @@ -1644,6 +1647,10 @@ class ContentItem(proto.Message): messages are contiguous and ordered in chronological order. + This field is a member of `oneof`_ ``data_item``. + batch_content_item (google.cloud.dlp_v2.types.BatchContentItem): + Represents a batch of items to inspect. + This field is a member of `oneof`_ ``data_item``. content_metadata (google.cloud.dlp_v2.types.ContentMetadata): User provided metadata for the content. @@ -1672,6 +1679,12 @@ class ContentItem(proto.Message): oneof="data_item", message="Conversation", ) + batch_content_item: "BatchContentItem" = proto.Field( + proto.MESSAGE, + number=8, + oneof="data_item", + message="BatchContentItem", + ) content_metadata: "ContentMetadata" = proto.Field( proto.MESSAGE, number=6, @@ -1725,7 +1738,7 @@ class ConversationMessage(proto.Message): message_type (google.cloud.dlp_v2.types.ConversationMessage.MessageType): The type of message. participant_id (str): - Optional. The identifier of the participant, for example, + Optional. The identifier of the participant, for example 'test-user' or 'gemini'. The participant ID can contain lowercase letters, numbers, and hyphens; that is, it must match the regular expression: @@ -1767,6 +1780,42 @@ class MessageType(proto.Enum): ) +class BatchContentItem(proto.Message): + r"""Represents a batch of content to inspect or redact. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + string_value_batch (google.cloud.dlp_v2.types.StringValueBatch): + Optional. Represents a batch of string values + to inspect or redact. + + This field is a member of `oneof`_ ``batch``. + """ + + string_value_batch: "StringValueBatch" = proto.Field( + proto.MESSAGE, + number=1, + oneof="batch", + message="StringValueBatch", + ) + + +class StringValueBatch(proto.Message): + r"""Represents a batch of string values to inspect or redact. + + Attributes: + values (MutableSequence[str]): + Optional. Represents string data to inspect + or redact. + """ + + values: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + + class Table(proto.Message): r"""Structured content to inspect. Up to 50,000 ``Value``\ s per request allowed. See @@ -2069,6 +2118,10 @@ class ContentLocation(proto.Message): conversation_location (google.cloud.dlp_v2.types.ConversationLocation): Location within a conversation. + This field is a member of `oneof`_ ``location``. + batch_content_location (google.cloud.dlp_v2.types.BatchContentLocation): + Location within a batch of content. + This field is a member of `oneof`_ ``location``. container_timestamp (google.protobuf.timestamp_pb2.Timestamp): Finding container modification timestamp, if applicable. For @@ -2115,6 +2168,12 @@ class ContentLocation(proto.Message): oneof="location", message="ConversationLocation", ) + batch_content_location: "BatchContentLocation" = proto.Field( + proto.MESSAGE, + number=11, + oneof="location", + message="BatchContentLocation", + ) container_timestamp: timestamp_pb2.Timestamp = proto.Field( proto.MESSAGE, number=6, @@ -2168,6 +2227,21 @@ class AllMessages(proto.Message): ) +class BatchContentLocation(proto.Message): + r"""Location within a batch of content. + + Attributes: + item_index (int): + Matches an index of a batch item in the batch + provided in the request. + """ + + item_index: int = proto.Field( + proto.INT32, + number=1, + ) + + class MetadataLocation(proto.Message): r"""Metadata Location diff --git a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/__init__.py b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/__init__.py index 07edbdbb3cd0..db78fe9542c2 100644 --- a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/__init__.py +++ b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/__init__.py @@ -34,7 +34,12 @@ from .types.agent_context import AgentContextReference from .types.context import ( AnalysisOptions, + BigQueryRoutine, + BigQueryRoutineReference, ChartOptions, + Citation, + CitationAnchor, + CitationSource, Context, ConversationOptions, DatasourceOptions, @@ -42,6 +47,10 @@ GlossaryTerm, LookerGoldenQuery, LookerQuery, + MatchedQuery, + QueryParameter, + QueryParameterValues, + UserFunctions, ) from .types.conversation import ( Conversation, @@ -89,6 +98,7 @@ GenerationOptions, ListMessagesRequest, ListMessagesResponse, + LookerSettings, Message, ParameterizedSecureViewParameters, QueryDataContext, @@ -105,10 +115,12 @@ from .types.datasource import ( AlloyDbDatabaseReference, AlloyDbReference, + BigQueryPropertyGraphReference, BigQueryTableReference, BigQueryTableReferences, CloudSqlDatabaseReference, CloudSqlReference, + DatabaseTableReference, DataFilter, DataFilterType, Datasource, @@ -218,6 +230,9 @@ def _get_version(dependency_name): "AnalysisOptions", "AnalysisQuery", "BigQueryJob", + "BigQueryPropertyGraphReference", + "BigQueryRoutine", + "BigQueryRoutineReference", "BigQueryTableReference", "BigQueryTableReferences", "Blob", @@ -226,6 +241,9 @@ def _get_version(dependency_name): "ChartQuery", "ChartResult", "ChatRequest", + "Citation", + "CitationAnchor", + "CitationSource", "ClarificationMessage", "ClarificationQuestion", "ClientManagedResourceContext", @@ -248,6 +266,7 @@ def _get_version(dependency_name): "DataMessage", "DataQuery", "DataResult", + "DatabaseTableReference", "Datasource", "DatasourceOptions", "DatasourceReferences", @@ -274,6 +293,8 @@ def _get_version(dependency_name): "LookerExploreReferences", "LookerGoldenQuery", "LookerQuery", + "LookerSettings", + "MatchedQuery", "Message", "OAuthCredentials", "OperationMetadata", @@ -282,6 +303,8 @@ def _get_version(dependency_name): "QueryDataContext", "QueryDataRequest", "QueryDataResponse", + "QueryParameter", + "QueryParameterValues", "Schema", "SchemaMessage", "SchemaQuery", @@ -294,5 +317,6 @@ def _get_version(dependency_name): "SystemMessage", "TextMessage", "UpdateDataAgentRequest", + "UserFunctions", "UserMessage", ) diff --git a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/services/data_agent_service/async_client.py b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/services/data_agent_service/async_client.py index 4ef2b8d9e90b..75202c204bc9 100644 --- a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/services/data_agent_service/async_client.py +++ b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/services/data_agent_service/async_client.py @@ -88,6 +88,8 @@ class DataAgentServiceAsyncClient: _DEFAULT_ENDPOINT_TEMPLATE = DataAgentServiceClient._DEFAULT_ENDPOINT_TEMPLATE _DEFAULT_UNIVERSE = DataAgentServiceClient._DEFAULT_UNIVERSE + crypto_key_path = staticmethod(DataAgentServiceClient.crypto_key_path) + parse_crypto_key_path = staticmethod(DataAgentServiceClient.parse_crypto_key_path) data_agent_path = staticmethod(DataAgentServiceClient.data_agent_path) parse_data_agent_path = staticmethod(DataAgentServiceClient.parse_data_agent_path) common_billing_account_path = staticmethod( diff --git a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/services/data_agent_service/client.py b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/services/data_agent_service/client.py index 5bbd4d73008b..2e3cffac16f0 100644 --- a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/services/data_agent_service/client.py +++ b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/services/data_agent_service/client.py @@ -241,6 +241,30 @@ def transport(self) -> DataAgentServiceTransport: """ return self._transport + @staticmethod + def crypto_key_path( + project: str, + location: str, + key_ring: str, + crypto_key: str, + ) -> str: + """Returns a fully-qualified crypto_key string.""" + return "projects/{project}/locations/{location}/keyRings/{key_ring}/cryptoKeys/{crypto_key}".format( + project=project, + location=location, + key_ring=key_ring, + crypto_key=crypto_key, + ) + + @staticmethod + def parse_crypto_key_path(path: str) -> Dict[str, str]: + """Parses a crypto_key path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/keyRings/(?P.+?)/cryptoKeys/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def data_agent_path( project: str, diff --git a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/services/data_chat_service/async_client.py b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/services/data_chat_service/async_client.py index ff0a0a5a4fac..81b99ecb0717 100644 --- a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/services/data_chat_service/async_client.py +++ b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/services/data_chat_service/async_client.py @@ -92,6 +92,8 @@ class DataChatServiceAsyncClient: parse_conversation_path = staticmethod( DataChatServiceClient.parse_conversation_path ) + crypto_key_path = staticmethod(DataChatServiceClient.crypto_key_path) + parse_crypto_key_path = staticmethod(DataChatServiceClient.parse_crypto_key_path) data_agent_path = staticmethod(DataChatServiceClient.data_agent_path) parse_data_agent_path = staticmethod(DataChatServiceClient.parse_data_agent_path) common_billing_account_path = staticmethod( @@ -323,8 +325,7 @@ def chat( metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> Awaitable[AsyncIterable[data_chat_service.Message]]: r"""Answers a data question by generating a stream of - [Message][google.cloud.geminidataanalytics.v1alpha.Message] - objects. + [Message][google.cloud.geminidataanalytics.v1.Message] objects. .. code-block:: python diff --git a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/services/data_chat_service/client.py b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/services/data_chat_service/client.py index a6a36cd555c8..a17532f97afc 100644 --- a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/services/data_chat_service/client.py +++ b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/services/data_chat_service/client.py @@ -262,6 +262,30 @@ def parse_conversation_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def crypto_key_path( + project: str, + location: str, + key_ring: str, + crypto_key: str, + ) -> str: + """Returns a fully-qualified crypto_key string.""" + return "projects/{project}/locations/{location}/keyRings/{key_ring}/cryptoKeys/{crypto_key}".format( + project=project, + location=location, + key_ring=key_ring, + crypto_key=crypto_key, + ) + + @staticmethod + def parse_crypto_key_path(path: str) -> Dict[str, str]: + """Parses a crypto_key path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/keyRings/(?P.+?)/cryptoKeys/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def data_agent_path( project: str, @@ -774,8 +798,7 @@ def chat( metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> Iterable[data_chat_service.Message]: r"""Answers a data question by generating a stream of - [Message][google.cloud.geminidataanalytics.v1alpha.Message] - objects. + [Message][google.cloud.geminidataanalytics.v1.Message] objects. .. code-block:: python diff --git a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/services/data_chat_service/transports/grpc.py b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/services/data_chat_service/transports/grpc.py index 769cf5e1311b..3508fedf3e2a 100644 --- a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/services/data_chat_service/transports/grpc.py +++ b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/services/data_chat_service/transports/grpc.py @@ -343,8 +343,7 @@ def chat( r"""Return a callable for the chat method over gRPC. Answers a data question by generating a stream of - [Message][google.cloud.geminidataanalytics.v1alpha.Message] - objects. + [Message][google.cloud.geminidataanalytics.v1.Message] objects. Returns: Callable[[~.ChatRequest], diff --git a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/services/data_chat_service/transports/grpc_asyncio.py b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/services/data_chat_service/transports/grpc_asyncio.py index f7447ede900c..7df68e8da03c 100644 --- a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/services/data_chat_service/transports/grpc_asyncio.py +++ b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/services/data_chat_service/transports/grpc_asyncio.py @@ -353,8 +353,7 @@ def chat( r"""Return a callable for the chat method over gRPC. Answers a data question by generating a stream of - [Message][google.cloud.geminidataanalytics.v1alpha.Message] - objects. + [Message][google.cloud.geminidataanalytics.v1.Message] objects. Returns: Callable[[~.ChatRequest], diff --git a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/types/__init__.py b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/types/__init__.py index 85838315154f..7eefd0f64522 100644 --- a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/types/__init__.py +++ b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/types/__init__.py @@ -18,7 +18,12 @@ ) from .context import ( AnalysisOptions, + BigQueryRoutine, + BigQueryRoutineReference, ChartOptions, + Citation, + CitationAnchor, + CitationSource, Context, ConversationOptions, DatasourceOptions, @@ -26,6 +31,10 @@ GlossaryTerm, LookerGoldenQuery, LookerQuery, + MatchedQuery, + QueryParameter, + QueryParameterValues, + UserFunctions, ) from .conversation import ( Conversation, @@ -80,6 +89,7 @@ GenerationOptions, ListMessagesRequest, ListMessagesResponse, + LookerSettings, Message, ParameterizedSecureViewParameters, QueryDataContext, @@ -96,10 +106,12 @@ from .datasource import ( AlloyDbDatabaseReference, AlloyDbReference, + BigQueryPropertyGraphReference, BigQueryTableReference, BigQueryTableReferences, CloudSqlDatabaseReference, CloudSqlReference, + DatabaseTableReference, DataFilter, DataFilterType, Datasource, @@ -118,7 +130,12 @@ __all__ = ( "AgentContextReference", "AnalysisOptions", + "BigQueryRoutine", + "BigQueryRoutineReference", "ChartOptions", + "Citation", + "CitationAnchor", + "CitationSource", "Context", "ConversationOptions", "DatasourceOptions", @@ -126,6 +143,10 @@ "GlossaryTerm", "LookerGoldenQuery", "LookerQuery", + "MatchedQuery", + "QueryParameter", + "QueryParameterValues", + "UserFunctions", "Conversation", "CreateConversationRequest", "DeleteConversationRequest", @@ -168,6 +189,7 @@ "GenerationOptions", "ListMessagesRequest", "ListMessagesResponse", + "LookerSettings", "Message", "ParameterizedSecureViewParameters", "QueryDataContext", @@ -182,10 +204,12 @@ "UserMessage", "AlloyDbDatabaseReference", "AlloyDbReference", + "BigQueryPropertyGraphReference", "BigQueryTableReference", "BigQueryTableReferences", "CloudSqlDatabaseReference", "CloudSqlReference", + "DatabaseTableReference", "DataFilter", "Datasource", "DatasourceReferences", diff --git a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/types/context.py b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/types/context.py index 034610559c00..383117bb720e 100644 --- a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/types/context.py +++ b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/types/context.py @@ -26,7 +26,13 @@ package="google.cloud.geminidataanalytics.v1beta", manifest={ "Context", + "UserFunctions", + "BigQueryRoutine", + "BigQueryRoutineReference", "ExampleQuery", + "QueryParameter", + "MatchedQuery", + "QueryParameterValues", "LookerGoldenQuery", "LookerQuery", "GlossaryTerm", @@ -34,6 +40,9 @@ "DatasourceOptions", "ChartOptions", "AnalysisOptions", + "Citation", + "CitationSource", + "CitationAnchor", }, ) @@ -62,18 +71,25 @@ class Context(proto.Message): providing examples of relevant and commonly used SQL queries and their corresponding natural language queries optionally present. Currently - only used for BigQuery data sources. + only used for BigQuery data sources and + databases (alloydb, cloudsql, spanner) data + sources. looker_golden_queries (MutableSequence[google.cloud.geminidataanalytics_v1beta.types.LookerGoldenQuery]): Optional. A list of golden queries, providing examples of relevant and commonly used Looker queries and their corresponding natural language - queries optionally present. + queries optionally present. Only supported for + Looker data sources. glossary_terms (MutableSequence[google.cloud.geminidataanalytics_v1beta.types.GlossaryTerm]): Optional. Term definitions (currently, only - user authored) + user authored) Not supported for databases + (alloydb, cloudsql, spanner) data sources. schema_relationships (MutableSequence[google.cloud.geminidataanalytics_v1beta.types.Context.SchemaRelationship]): Optional. Relationships between table schema, including referencing and referenced columns. + user_functions (google.cloud.geminidataanalytics_v1beta.types.UserFunctions): + Optional. A collection of user functions to + be included in context. """ class SchemaRelationship(proto.Message): @@ -95,12 +111,12 @@ class SchemaRelationship(proto.Message): must correspond to a field at the same index in the ``left_schema_paths`` list. sources (MutableSequence[google.cloud.geminidataanalytics_v1beta.types.Context.SchemaRelationship.Source]): - Sources which generated the schema relation - edge. + Optional. Sources which generated the schema + relation edge. confidence_score (float): - A confidence score for the suggested - relationship. Manually added edges have the - highest confidence score. + Optional. A confidence score for the + suggested relationship. Manually added edges + have the highest confidence score. """ class Source(proto.Enum): @@ -203,6 +219,75 @@ class SchemaPaths(proto.Message): number=9, message=SchemaRelationship, ) + user_functions: "UserFunctions" = proto.Field( + proto.MESSAGE, + number=10, + message="UserFunctions", + ) + + +class UserFunctions(proto.Message): + r"""A collection of user functions to be included in context. + + Attributes: + bq_routines (MutableSequence[google.cloud.geminidataanalytics_v1beta.types.BigQueryRoutine]): + A list of BigQuery routines to include in the + context. + """ + + bq_routines: MutableSequence["BigQueryRoutine"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="BigQueryRoutine", + ) + + +class BigQueryRoutine(proto.Message): + r"""A reference to a BigQuery routine. + + Attributes: + routine_reference (google.cloud.geminidataanalytics_v1beta.types.BigQueryRoutineReference): + The reference to the BigQuery routine. + description (str): + User override or addition to description, to + tell the agent when to use the UDF. + """ + + routine_reference: "BigQueryRoutineReference" = proto.Field( + proto.MESSAGE, + number=1, + message="BigQueryRoutineReference", + ) + description: str = proto.Field( + proto.STRING, + number=2, + ) + + +class BigQueryRoutineReference(proto.Message): + r"""A reference to a BigQuery routine. + + Attributes: + project_id (str): + The project ID of the routine. + dataset_id (str): + The dataset ID of the routine. + routine_id (str): + The routine ID of the routine. + """ + + project_id: str = proto.Field( + proto.STRING, + number=1, + ) + dataset_id: str = proto.Field( + proto.STRING, + number=2, + ) + routine_id: str = proto.Field( + proto.STRING, + number=3, + ) class ExampleQuery(proto.Message): @@ -225,6 +310,10 @@ class ExampleQuery(proto.Message): Optional. A natural language question that a user might ask. For example: "How many orders were placed last month?". + parameters (MutableSequence[google.cloud.geminidataanalytics_v1beta.types.QueryParameter]): + Optional. The list of query parameters. Example: The + parameterized SQL query "SELECT \* FROM my_table WHERE id = + @id" can be matched with any value of id. """ sql_query: str = proto.Field( @@ -236,6 +325,96 @@ class ExampleQuery(proto.Message): proto.STRING, number=1, ) + parameters: MutableSequence["QueryParameter"] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message="QueryParameter", + ) + + +class QueryParameter(proto.Message): + r"""A query parameter message represents a parameter that can be + used to parameterize a SQL query. + + Attributes: + name (str): + Required. The name of the parameter reference + in the SQL query. + description (str): + Optional. The description of the parameter + that can be used by LLM to extract the parameter + value from the user question. + data_type (str): + Required. The data type of the parameter, e.g. "STRING", + "INT64", "DATE", etc. For valid values, see the `BigQuery + documentation `__. + This will be used to populate + google.cloud.bigquery.v2.QueryParameterType.type. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + description: str = proto.Field( + proto.STRING, + number=2, + ) + data_type: str = proto.Field( + proto.STRING, + number=3, + ) + + +class MatchedQuery(proto.Message): + r"""A matched query message represents the agent having matched + one of the example queries supplied in context as being + applicable to the current question. It will also contain + additional info during the matching process. + + Attributes: + example_query (google.cloud.geminidataanalytics_v1beta.types.ExampleQuery): + The query that was matched based on an + example query. + query_parameter_values (MutableSequence[google.cloud.geminidataanalytics_v1beta.types.QueryParameterValues]): + The extracted values for the query + parameters. + """ + + example_query: "ExampleQuery" = proto.Field( + proto.MESSAGE, + number=1, + message="ExampleQuery", + ) + query_parameter_values: MutableSequence["QueryParameterValues"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=2, + message="QueryParameterValues", + ) + ) + + +class QueryParameterValues(proto.Message): + r"""A query parameter values message represents the values for + the query parameters that were extracted from the user question + by LLM, based on the example query. + + Attributes: + name (str): + Required. The name of the parameter. + value (str): + Required. The value of the parameter. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + value: str = proto.Field( + proto.STRING, + number=2, + ) class LookerGoldenQuery(proto.Message): @@ -290,17 +469,36 @@ class LookerQuery(proto.Message): Optional. Limit in the query. This field is a member of `oneof`_ ``_limit``. + query_id (str): + Optional. The primary identifier for the query resource in + Looker, used for API operations. Maps to ``id`` (or + ``slug``) in the Looker API ``Query`` resource. + + This field is a member of `oneof`_ ``_query_id``. + client_id (str): + Optional. The short alphanumeric identifier for the query, + used for share links and Explore URLs (e.g., in the ``qid`` + parameter). Maps to ``client_id`` in the Looker API + ``Query`` resource. + + This field is a member of `oneof`_ ``_client_id``. """ class Filter(proto.Message): r"""A Looker query filter. + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + Attributes: field (str): Required. The field to filter on. value (str): - Required. The value for the field to filter - on. + Optional. The value for the field to filter + on. Optional so we can preserve the default + value as an empty string, important to get a + valid and working Looker Explore url. + + This field is a member of `oneof`_ ``_value``. """ field: str = proto.Field( @@ -310,6 +508,7 @@ class Filter(proto.Message): value: str = proto.Field( proto.STRING, number=2, + optional=True, ) model: str = proto.Field( @@ -338,6 +537,16 @@ class Filter(proto.Message): number=6, optional=True, ) + query_id: str = proto.Field( + proto.STRING, + number=10, + optional=True, + ) + client_id: str = proto.Field( + proto.STRING, + number=11, + optional=True, + ) class GlossaryTerm(proto.Message): @@ -377,6 +586,8 @@ class GlossaryTerm(proto.Message): class ConversationOptions(proto.Message): r"""Options for the conversation. + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + Attributes: chart (google.cloud.geminidataanalytics_v1beta.types.ChartOptions): Optional. Options for chart generation. @@ -384,8 +595,30 @@ class ConversationOptions(proto.Message): Optional. Options for analysis. datasource (google.cloud.geminidataanalytics_v1beta.types.DatasourceOptions): Optional. Options for datasources. + model (google.cloud.geminidataanalytics_v1beta.types.ConversationOptions.Model): + Optional. The model to use for the agent + loop. + + This field is a member of `oneof`_ ``_model``. """ + class Model(proto.Enum): + r"""Allowed models for the agent/conversation. + + Values: + MODEL_UNSPECIFIED (0): + No model specified. The model may be set on + the chat request, or the default model will be + used. + LATEST_GA_MODEL (1): + Use the most up-to-date non-preview model. + This may constrain certain request level + settings. + """ + + MODEL_UNSPECIFIED = 0 + LATEST_GA_MODEL = 1 + chart: "ChartOptions" = proto.Field( proto.MESSAGE, number=1, @@ -401,6 +634,12 @@ class ConversationOptions(proto.Message): number=3, message="DatasourceOptions", ) + model: Model = proto.Field( + proto.ENUM, + number=6, + optional=True, + enum=Model, + ) class DatasourceOptions(proto.Message): @@ -509,4 +748,152 @@ class Python(proto.Message): ) +class Citation(proto.Message): + r"""Source attributions for content. + + Attributes: + sources (MutableSequence[google.cloud.geminidataanalytics_v1beta.types.CitationSource]): + Output only. List of the sources being cited. + anchors (MutableSequence[google.cloud.geminidataanalytics_v1beta.types.CitationAnchor]): + Output only. List of the anchors of the + citations. + """ + + sources: MutableSequence["CitationSource"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="CitationSource", + ) + anchors: MutableSequence["CitationAnchor"] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="CitationAnchor", + ) + + +class CitationSource(proto.Message): + r"""The source of the citation. + + 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: + uri (str): + Output only. The uri used as the source, such + as a web grounding URL. + + This field is a member of `oneof`_ ``source_type``. + example_query (google.cloud.geminidataanalytics_v1beta.types.ExampleQuery): + Output only. The example query used as the + source. + + This field is a member of `oneof`_ ``source_type``. + glossary_term (google.cloud.geminidataanalytics_v1beta.types.GlossaryTerm): + Output only. The glossary term used as the + source. + + This field is a member of `oneof`_ ``source_type``. + id (str): + Output only. Unique identifier of the source. This ID is + service-generated and is unique within the scope of a single + ``Citation`` message. + title (str): + Output only. The title of the source. + """ + + uri: str = proto.Field( + proto.STRING, + number=3, + oneof="source_type", + ) + example_query: "ExampleQuery" = proto.Field( + proto.MESSAGE, + number=4, + oneof="source_type", + message="ExampleQuery", + ) + glossary_term: "GlossaryTerm" = proto.Field( + proto.MESSAGE, + number=5, + oneof="source_type", + message="GlossaryTerm", + ) + id: str = proto.Field( + proto.STRING, + number=1, + ) + title: str = proto.Field( + proto.STRING, + number=2, + ) + + +class CitationAnchor(proto.Message): + r"""The anchor of the citation. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + text_message_anchor (google.cloud.geminidataanalytics_v1beta.types.CitationAnchor.TextMessageCitationAnchor): + Output only. Only set if the citation is for + a TextMessage. + + This field is a member of `oneof`_ ``anchor_type``. + """ + + class TextMessageCitationAnchor(proto.Message): + r"""Citation anchor within a TextMessage. + + Attributes: + part_index (int): + Output only. The 0-based index of the part + within the TextMessage.parts field. + start_offset_bytes (int): + Output only. The offset, measured in UTF-8 + bytes, within the part string where the citation + begins (inclusive). Example: For the text + "Hello, world" where "world" is cited, the start + offset bytes (inclusive) is 7 and the end offset + bytes (exclusive) is 12. + end_offset_bytes (int): + Output only. The offset, measured in UTF-8 + bytes, within the part string where the citation + ends (exclusive). Example: For the text "Hello, + world" where "world" is cited, the start offset + bytes (inclusive) is 7 and the end offset bytes + (exclusive) is 12. + source_ids (MutableSequence[str]): + Output only. The ids of the sources that are + cited. + """ + + part_index: int = proto.Field( + proto.INT32, + number=1, + ) + start_offset_bytes: int = proto.Field( + proto.INT32, + number=2, + ) + end_offset_bytes: int = proto.Field( + proto.INT32, + number=3, + ) + source_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=4, + ) + + text_message_anchor: TextMessageCitationAnchor = proto.Field( + proto.MESSAGE, + number=1, + oneof="anchor_type", + message=TextMessageCitationAnchor, + ) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/types/conversation.py b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/types/conversation.py index 48091924c735..787f9a93d6a3 100644 --- a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/types/conversation.py +++ b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/types/conversation.py @@ -36,6 +36,8 @@ class Conversation(proto.Message): r"""Message for a conversation. + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + Attributes: name (str): Optional. Identifier. The unique resource name of a @@ -67,6 +69,20 @@ class Conversation(proto.Message): that can be set by the client to tag a conversation (e.g. to filter conversations for specific surfaces/products). + kms_key (str): + Optional. Customer managed encryption key (CMEK) to use for + encrypting the Conversation resources. Encryption will + happen at Titan layer, we will pass the KMS key to Titan. + + Format: + projects/{project_id}/locations/{location}/keyRings/{key_ring_name}/cryptoKeys/{key_name}. + + This field is a member of `oneof`_ ``_kms_key``. + memory_paused (bool): + Optional. Whether memory is paused for this + conversation. + + This field is a member of `oneof`_ ``_memory_paused``. """ name: str = proto.Field( @@ -92,6 +108,16 @@ class Conversation(proto.Message): proto.STRING, number=9, ) + kms_key: str = proto.Field( + proto.STRING, + number=10, + optional=True, + ) + memory_paused: bool = proto.Field( + proto.BOOL, + number=11, + optional=True, + ) class CreateConversationRequest(proto.Message): @@ -160,11 +186,10 @@ class ListConversationsRequest(proto.Message): Required. Parent value for ListConversationsRequest. Format: ``projects/{project}/locations/{location}`` page_size (int): - Optional. Requested page size. Server may - return fewer items than requested. The max page - size is 100. All larger page sizes will be - coerced to 100. If unspecified, server will pick - 50 as an approperiate default. + Optional. Requested page size. Server may return fewer items + than requested. The max page size is ``100``. All larger + page sizes will be coerced to ``100``. If unspecified, + server will pick ``50`` as an appropriate default. page_token (str): Optional. A token identifying a page of results the server should return. diff --git a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/types/data_agent.py b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/types/data_agent.py index 83db62ac5617..e250674853cf 100644 --- a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/types/data_agent.py +++ b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/types/data_agent.py @@ -84,6 +84,14 @@ class DataAgent(proto.Message): Output only. Timestamp in UTC of when this data agent is considered expired. This is *always* provided on output, regardless of what was sent on input. + kms_key (str): + Optional. Customer managed encryption key (CMEK) to use for + encrypting the DataAgent resources. Cloud KMS CryptoKeys + must reside in the same location as the DataAgent. The + expected format is + ``projects/*/locations/*/keyRings/*/cryptoKeys/*``. + + This field is a member of `oneof`_ ``_kms_key``. """ data_analytics_agent: gcg_data_analytics_agent.DataAnalyticsAgent = proto.Field( @@ -129,6 +137,11 @@ class DataAgent(proto.Message): number=13, message=timestamp_pb2.Timestamp, ) + kms_key: str = proto.Field( + proto.STRING, + number=14, + optional=True, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/types/data_chat_service.py b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/types/data_chat_service.py index 3a0a35d3a702..237691bdbd42 100644 --- a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/types/data_chat_service.py +++ b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/types/data_chat_service.py @@ -42,6 +42,7 @@ "ConversationReference", "ClientManagedResourceContext", "Message", + "LookerSettings", "UserMessage", "SystemMessage", "TextMessage", @@ -179,17 +180,34 @@ class ParameterizedSecureViewParameters(proto.Message): generation and query execution. Attributes: - parameters (MutableMapping[str, str]): - Optional. Named parameters for Parameterized Secure Views - (PSV). The map keys are parameter names (e.g., - ``"user_id"``), and values are the corresponding parameter - values (e.g., ``"123"``). + parameters (MutableSequence[google.cloud.geminidataanalytics_v1beta.types.ParameterizedSecureViewParameters.Parameter]): + Optional. Named parameters for Parameterized + Secure Views (PSV). """ - parameters: MutableMapping[str, str] = proto.MapField( - proto.STRING, - proto.STRING, + class Parameter(proto.Message): + r"""Represents a single parameter for Parameterized Secure Views. + + Attributes: + key (str): + Required. The parameter key (e.g., ``"user_id"``). + value (str): + Required. The parameter value (e.g., ``"123"``). + """ + + key: str = proto.Field( + proto.STRING, + number=1, + ) + value: str = proto.Field( + proto.STRING, + number=2, + ) + + parameters: MutableSequence[Parameter] = proto.RepeatedField( + proto.MESSAGE, number=1, + message=Parameter, ) @@ -356,11 +374,10 @@ class ListMessagesRequest(proto.Message): Required. The conversation to list messages under. Format: ``projects/{project}/locations/{location}/conversations/{conversation_id}`` page_size (int): - Optional. Requested page size. Server may - return fewer items than requested. The max page - size is 100. All larger page sizes will be - coerced to 100. If unspecified, server will pick - 50 as an approperiate default. + Optional. Requested page size. Server may return fewer items + than requested. The max page size is ``100``. All larger + page sizes will be coerced to ``100``. If unspecified, + server will pick ``50`` as an appropriate default. page_token (str): Optional. A token identifying a page of results the server should return. @@ -479,17 +496,35 @@ class ChatRequest(proto.Message): conversations and agents resources. This field is a member of `oneof`_ ``context_provider``. + looker_settings (google.cloud.geminidataanalytics_v1beta.types.LookerSettings): + Optional. Looker specific settings. + + This field is a member of `oneof`_ ``datasource_settings``. project (str): - Optional. The Google Cloud project to be used - for quota and billing. + Optional. Deprecated: Use ``parent`` field instead. The + Google Cloud project to be used for quota and billing. parent (str): Required. The parent value for chat request. Pattern: ``projects/{project}/locations/{location}`` messages (MutableSequence[google.cloud.geminidataanalytics_v1beta.types.Message]): Required. Content of current conversation. + credentials (google.cloud.geminidataanalytics_v1beta.types.Credentials): + Optional. The credentials to use when calling the data + source(s) specified in the context. + + This field can be used to provide credentials for various + data sources. For example, when connecting to Looker, it + currently supports both OAuth token and API key-based + credentials, as described in `Authentication with an + SDK `__. thinking_mode (google.cloud.geminidataanalytics_v1beta.types.ChatRequest.ThinkingMode): Optional. The thinking mode to use for the agent loop. Defaults to THINKING_MODE_UNSPECIFIED if not specified. + model (google.cloud.geminidataanalytics_v1beta.types.ChatRequest.Model): + Optional. The model to use for the agent loop + when processing the request. This setting only + has an effect when context.options.model is not + set. """ class ThinkingMode(proto.Enum): @@ -509,6 +544,22 @@ class ThinkingMode(proto.Enum): FAST = 1 THINKING = 2 + class Model(proto.Enum): + r"""Model selection for the agent. + + Values: + MODEL_UNSPECIFIED (0): + No model specified. The default model will be + used. + LATEST_GA_MODEL (1): + Use the most up-to-date non-preview model. + This may constrain certain request level + settings. + """ + + MODEL_UNSPECIFIED = 0 + LATEST_GA_MODEL = 1 + inline_context: gcg_context.Context = proto.Field( proto.MESSAGE, number=101, @@ -533,6 +584,12 @@ class ThinkingMode(proto.Enum): oneof="context_provider", message="ClientManagedResourceContext", ) + looker_settings: "LookerSettings" = proto.Field( + proto.MESSAGE, + number=13, + oneof="datasource_settings", + message="LookerSettings", + ) project: str = proto.Field( proto.STRING, number=1, @@ -546,11 +603,21 @@ class ThinkingMode(proto.Enum): number=2, message="Message", ) + credentials: gcg_credentials.Credentials = proto.Field( + proto.MESSAGE, + number=7, + message=gcg_credentials.Credentials, + ) thinking_mode: ThinkingMode = proto.Field( proto.ENUM, number=9, enum=ThinkingMode, ) + model: Model = proto.Field( + proto.ENUM, + number=11, + enum=Model, + ) class DataAgentContext(proto.Message): @@ -561,8 +628,8 @@ class DataAgentContext(proto.Message): Required. The name of the data agent resource. credentials (google.cloud.geminidataanalytics_v1beta.types.Credentials): - Optional. The credentials to use when calling the Looker - data source. + Optional. Deprecated: Use credentials in ChatRequest. The + credentials to use when calling the Looker data source. Currently supports both OAuth token and API key-based credentials, as described in `Authentication with an @@ -719,6 +786,28 @@ class Message(proto.Message): ) +class LookerSettings(proto.Message): + r"""Message to hold Looker specific custom settings. + + Attributes: + enable_dev_mode (bool): + Optional. Whether to operate in Looker's + Development Mode. If true, the API session will + be switched to the "dev" workspace, allowing + interaction with LookML changes in the user's + development branch. If false or unset, the + session remains in the default state (Production + Mode). + See + https://cloud.google.com/looker/docs/dev-mode-prod-mode. + """ + + enable_dev_mode: bool = proto.Field( + proto.BOOL, + number=1, + ) + + class UserMessage(proto.Message): r"""A message from the user that is interacting with the system. @@ -741,7 +830,7 @@ class UserMessage(proto.Message): class SystemMessage(proto.Message): r"""A message from the system in response to the user. This message can also be a message from the user as historical - context for multiturn conversations with the system. + context for multi-turn conversations with the system. This message has `oneof`_ fields (mutually exclusive fields). For each oneof, at most one member field can be set at the same time. @@ -782,8 +871,9 @@ class SystemMessage(proto.Message): This field is a member of `oneof`_ ``kind``. clarification (google.cloud.geminidataanalytics_v1beta.types.ClarificationMessage): - Optional. A message containing clarification - questions. + Optional. Deprecated: Use TextMessage with + TextType.FINAL_RESPONSE instead. A message containing + clarification questions. This field is a member of `oneof`_ ``kind``. group_id (int): @@ -793,6 +883,9 @@ class SystemMessage(proto.Message): together in the UI. This field is a member of `oneof`_ ``_group_id``. + citation (google.cloud.geminidataanalytics_v1beta.types.Citation): + Output only. Citation information for the + system message. """ text: "TextMessage" = proto.Field( @@ -848,6 +941,11 @@ class SystemMessage(proto.Message): number=12, optional=True, ) + citation: gcg_context.Citation = proto.Field( + proto.MESSAGE, + number=15, + message=gcg_context.Citation, + ) class TextMessage(proto.Message): @@ -880,12 +978,17 @@ class TextType(proto.Enum): from the agent's internal thought process (``THOUGHT``) and the final answer to the user (``FINAL_RESPONSE``). These messages provide insight into the agent's actions. + FOLLOWUP_QUESTIONS (4): + The text is a list of follow-up questions + suggested. Each item in parts is a follow-up + question. """ TEXT_TYPE_UNSPECIFIED = 0 FINAL_RESPONSE = 1 THOUGHT = 2 PROGRESS = 3 + FOLLOWUP_QUESTIONS = 4 parts: MutableSequence[str] = proto.RepeatedField( proto.STRING, @@ -993,15 +1096,20 @@ class DataMessage(proto.Message): This field is a member of `oneof`_ ``kind``. generated_looker_query (google.cloud.geminidataanalytics_v1beta.types.LookerQuery): - Looker Query generated by the system to - retrieve data. Deprecated: generated looker - query is now under DataQuery.looker. + Deprecated: generated looker query is now + under DataQuery.looker. Looker Query generated + by the system to retrieve data. This field is a member of `oneof`_ ``kind``. big_query_job (google.cloud.geminidataanalytics_v1beta.types.BigQueryJob): A BigQuery job executed by the system to retrieve data. + This field is a member of `oneof`_ ``kind``. + matched_query (google.cloud.geminidataanalytics_v1beta.types.MatchedQuery): + A pre-existing query that was matched to + retrieve data. + This field is a member of `oneof`_ ``kind``. """ @@ -1034,6 +1142,12 @@ class DataMessage(proto.Message): oneof="kind", message="BigQueryJob", ) + matched_query: gcg_context.MatchedQuery = proto.Field( + proto.MESSAGE, + number=6, + oneof="kind", + message=gcg_context.MatchedQuery, + ) class DataQuery(proto.Message): @@ -1463,57 +1577,71 @@ class ErrorMessage(proto.Message): class ClarificationQuestion(proto.Message): - r"""Represents a single question to the user to help clarify - their query. + r"""Deprecated: Use TextMessage with TextType.FINAL_RESPONSE instead. + Represents a single question to the user to help clarify their + query. Attributes: question (str): - Required. The natural language question to - ask the user. + Required. Deprecated: The parent message is + deprecated. The natural language question to ask + the user. selection_mode (google.cloud.geminidataanalytics_v1beta.types.ClarificationQuestion.SelectionMode): - Required. The selection mode for this + Required. Deprecated: The parent message is + deprecated. The selection mode for this question. options (MutableSequence[str]): - Required. A list of distinct options for the + Required. Deprecated: The parent message is + deprecated. A list of distinct options for the user to choose from. The number of options is limited to a maximum of 5. clarification_question_type (google.cloud.geminidataanalytics_v1beta.types.ClarificationQuestion.ClarificationQuestionType): - Optional. The type of clarification question. + Optional. Deprecated: The parent message is + deprecated. The type of clarification question. """ class SelectionMode(proto.Enum): - r"""The selection mode for the clarification question. + r"""Deprecated: The parent message is deprecated. + The selection mode for the clarification question. Values: SELECTION_MODE_UNSPECIFIED (0): + Deprecated: The parent message is deprecated. Unspecified selection mode. SINGLE_SELECT (1): + Deprecated: The parent message is deprecated. The user can select only one option. MULTI_SELECT (2): + Deprecated: The parent message is deprecated. The user can select multiple options. """ + _pb_options = {"deprecated": True} SELECTION_MODE_UNSPECIFIED = 0 SINGLE_SELECT = 1 MULTI_SELECT = 2 class ClarificationQuestionType(proto.Enum): - r"""The type of clarification question. + r"""Deprecated: The parent message is deprecated. + The type of clarification question. This enum may be extended with new values in the future. Values: CLARIFICATION_QUESTION_TYPE_UNSPECIFIED (0): + Deprecated: The parent message is deprecated. Unspecified clarification question type. FILTER_VALUES (1): - The clarification question is for filter - values. + Deprecated: The parent message is deprecated. + The clarification question is for filter values. FIELDS (2): - The clarification question is for data - fields. This is a generic term encompassing SQL - columns, Looker fields (dimensions/measures), or - nested data structure properties. + Deprecated: The parent message is deprecated. + The clarification question is for data fields. + This is a generic term encompassing SQL columns, + Looker fields (dimensions/measures), or nested + data structure properties. """ + _pb_options = {"deprecated": True} CLARIFICATION_QUESTION_TYPE_UNSPECIFIED = 0 FILTER_VALUES = 1 FIELDS = 2 @@ -1539,13 +1667,15 @@ class ClarificationQuestionType(proto.Enum): class ClarificationMessage(proto.Message): - r"""A message of questions to help clarify the user's query. This - is returned when the system cannot confidently answer the user's + r"""Deprecated: Use TextMessage with TextType.FINAL_RESPONSE instead. A + message of questions to help clarify the user's query. This is + returned when the system cannot confidently answer the user's question. Attributes: questions (MutableSequence[google.cloud.geminidataanalytics_v1beta.types.ClarificationQuestion]): - Required. A batch of clarification questions + Required. Deprecated: The parent message is + deprecated. A batch of clarification questions to ask the user. """ diff --git a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/types/datasource.py b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/types/datasource.py index 7f743db56df9..e92e494f6ebb 100644 --- a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/types/datasource.py +++ b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/types/datasource.py @@ -33,6 +33,7 @@ "StudioDatasourceReferences", "StudioDatasourceReference", "AlloyDbReference", + "DatabaseTableReference", "AlloyDbDatabaseReference", "SpannerReference", "SpannerDatabaseReference", @@ -40,6 +41,7 @@ "CloudSqlDatabaseReference", "LookerExploreReferences", "LookerExploreReference", + "BigQueryPropertyGraphReference", "PrivateLookerInstanceInfo", "Datasource", "Schema", @@ -146,12 +148,19 @@ class DatasourceReferences(proto.Message): class BigQueryTableReferences(proto.Message): r"""Message representing references to BigQuery tables and property - graphs. At least one of ``table_references`` or - ``property_graph_references`` must be populated. + graphs. At least one of ``table_references``, + ``property_graph_references``, or ``search_scope`` must be + populated. Attributes: table_references (MutableSequence[google.cloud.geminidataanalytics_v1beta.types.BigQueryTableReference]): Optional. References to BigQuery tables. + property_graph_references (MutableSequence[google.cloud.geminidataanalytics_v1beta.types.BigQueryPropertyGraphReference]): + Optional. Preview feature. References to + BigQuery property graphs. Note: Data sources + must exclusively use either tables or property + graphs, not both. When using property graphs, a + maximum of one graph reference is supported. """ table_references: MutableSequence["BigQueryTableReference"] = proto.RepeatedField( @@ -159,6 +168,13 @@ class BigQueryTableReferences(proto.Message): number=1, message="BigQueryTableReference", ) + property_graph_references: MutableSequence["BigQueryPropertyGraphReference"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=2, + message="BigQueryPropertyGraphReference", + ) + ) class BigQueryTableReference(proto.Message): @@ -201,7 +217,8 @@ class StudioDatasourceReferences(proto.Message): Attributes: studio_references (MutableSequence[google.cloud.geminidataanalytics_v1beta.types.StudioDatasourceReference]): - The references to the studio datasources. + Optional. The references to the studio + datasources. """ studio_references: MutableSequence["StudioDatasourceReference"] = ( @@ -253,6 +270,58 @@ class AlloyDbReference(proto.Message): ) +class DatabaseTableReference(proto.Message): + r"""Message representing a table including its schema. + + Attributes: + table_id (str): + Required. The name of the table as defined in the database. + + Note: The precise rules for table naming, including valid + characters, length limits, and case sensitivity, are + determined by the specific database system. + + Requirements: + + - Exact Match: The provided name must be identical to the + name stored in the database. + - Case Sensitivity: Respect the case sensitivity rules of + the specific database system and how the table was + created. For example, "Orders" and "orders" may be + distinct table names. + - Special Characters/Keywords: If the table name includes + spaces, special characters, or is a database reserved + keyword, provide the literal name as it is stored. Do not + add any database-specific identifier quoting characters + (e.g., ", \`, []). + + Examples: + + - Simple name: "orders", "UserActivity" + - Case sensitive: "MyTable" + - Name with spaces: "Order Details" + - Name with other special characters: "user/data", + "order-items" + - Name that is a keyword: "Group", "Order" + + Permissions: The caller's credentials must have the + necessary database permissions to access the table's schema + and data. + schema (google.cloud.geminidataanalytics_v1beta.types.Schema): + Optional. The schema of the table. + """ + + table_id: str = proto.Field( + proto.STRING, + number=1, + ) + schema: "Schema" = proto.Field( + proto.MESSAGE, + number=2, + message="Schema", + ) + + class AlloyDbDatabaseReference(proto.Message): r"""Message representing a reference to a single AlloyDB database. @@ -272,6 +341,11 @@ class AlloyDbDatabaseReference(proto.Message): table_ids (MutableSequence[str]): Optional. The table ids. Denotes all tables if unset. + database_table_references (MutableSequence[google.cloud.geminidataanalytics_v1beta.types.DatabaseTableReference]): + Optional. References to tables within the + database. Each reference specifies a table and + can optionally include the table's schema to + provide context for the query. """ project_id: str = proto.Field( @@ -298,6 +372,13 @@ class AlloyDbDatabaseReference(proto.Message): proto.STRING, number=6, ) + database_table_references: MutableSequence["DatabaseTableReference"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=7, + message="DatabaseTableReference", + ) + ) class SpannerReference(proto.Message): @@ -335,8 +416,6 @@ class SpannerDatabaseReference(proto.Message): project_id (str): Required. The project the instance belongs to. - region (str): - Required. The region of the instance. instance_id (str): Required. The instance id. database_id (str): @@ -344,6 +423,22 @@ class SpannerDatabaseReference(proto.Message): table_ids (MutableSequence[str]): Optional. The table ids. Denotes all tables if unset. + database_table_references (MutableSequence[google.cloud.geminidataanalytics_v1beta.types.DatabaseTableReference]): + Optional. References to tables within the + database. Each reference specifies a table and + can optionally include the table's schema to + provide context for the query. + priority (str): + Optional. Priority for the queries to + Spanner. Should be a value supported by Cloud + Spanner e.g.: LOW, MEDIUM, HIGH. Unsupported + values will be ignored. See + https://docs.cloud.google.com/spanner/docs/reference/rest/v1/RequestOptions#Priority + for complete list. + request_tag (str): + Tag to be attached to all queries to Spanner. + Allows to identify and monitor queries sent to + Spanner by the GDA service. """ class Engine(proto.Enum): @@ -371,10 +466,6 @@ class Engine(proto.Enum): proto.STRING, number=1, ) - region: str = proto.Field( - proto.STRING, - number=2, - ) instance_id: str = proto.Field( proto.STRING, number=3, @@ -387,6 +478,21 @@ class Engine(proto.Enum): proto.STRING, number=5, ) + database_table_references: MutableSequence["DatabaseTableReference"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=7, + message="DatabaseTableReference", + ) + ) + priority: str = proto.Field( + proto.STRING, + number=8, + ) + request_tag: str = proto.Field( + proto.STRING, + number=9, + ) class CloudSqlReference(proto.Message): @@ -434,6 +540,11 @@ class CloudSqlDatabaseReference(proto.Message): table_ids (MutableSequence[str]): Optional. The table ids. Denotes all tables if unset. + database_table_references (MutableSequence[google.cloud.geminidataanalytics_v1beta.types.DatabaseTableReference]): + Optional. References to tables within the + database. Each reference specifies a table and + can optionally include the table's schema to + provide context for the query. """ class Engine(proto.Enum): @@ -477,6 +588,13 @@ class Engine(proto.Enum): proto.STRING, number=7, ) + database_table_references: MutableSequence["DatabaseTableReference"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=8, + message="DatabaseTableReference", + ) + ) class LookerExploreReferences(proto.Message): @@ -486,8 +604,8 @@ class LookerExploreReferences(proto.Message): explore_references (MutableSequence[google.cloud.geminidataanalytics_v1beta.types.LookerExploreReference]): Required. References to Looker explores. credentials (google.cloud.geminidataanalytics_v1beta.types.Credentials): - Optional. The credentials to use when calling the Looker - API. + Optional. Deprecated: Use credentials in ChatRequest. The + credentials to use when calling the Looker API. Currently supports both OAuth token and API key-based credentials, as described in `Authentication with an @@ -564,6 +682,35 @@ class LookerExploreReference(proto.Message): ) +class BigQueryPropertyGraphReference(proto.Message): + r"""Message representing a reference to a single BigQuery + property graph. + + Attributes: + project_id (str): + Required. The project that the property graph + belongs to. + dataset_id (str): + Required. The dataset that the property graph + belongs to. + property_graph_id (str): + Required. The property graph id. + """ + + project_id: str = proto.Field( + proto.STRING, + number=1, + ) + dataset_id: str = proto.Field( + proto.STRING, + number=2, + ) + property_graph_id: str = proto.Field( + proto.STRING, + number=3, + ) + + class PrivateLookerInstanceInfo(proto.Message): r"""Message representing a private Looker instance info required if the Looker instance is behind a private network. @@ -620,6 +767,10 @@ class Datasource(proto.Message): cloud_sql_reference (google.cloud.geminidataanalytics_v1beta.types.CloudSqlReference): A reference to a CloudSQL database. + This field is a member of `oneof`_ ``reference``. + bigquery_property_graph_reference (google.cloud.geminidataanalytics_v1beta.types.BigQueryPropertyGraphReference): + A reference to a BigQuery property graph. + This field is a member of `oneof`_ ``reference``. schema (google.cloud.geminidataanalytics_v1beta.types.Schema): Optional. The schema of the datasource. @@ -668,6 +819,12 @@ class Datasource(proto.Message): oneof="reference", message="CloudSqlReference", ) + bigquery_property_graph_reference: "BigQueryPropertyGraphReference" = proto.Field( + proto.MESSAGE, + number=16, + oneof="reference", + message="BigQueryPropertyGraphReference", + ) schema: "Schema" = proto.Field( proto.MESSAGE, number=7, @@ -770,9 +927,7 @@ class Field(proto.Message): schema structures. category (str): Optional. Field category, not required, - currently only useful for Looker. We are using a - string to avoid depending on an external package - and keep this package self-contained. + currently only useful for Looker. value_format (str): Optional. Looker only. Value format of the field. Ref: diff --git a/packages/google-cloud-geminidataanalytics/tests/unit/gapic/geminidataanalytics_v1beta/test_data_agent_service.py b/packages/google-cloud-geminidataanalytics/tests/unit/gapic/geminidataanalytics_v1beta/test_data_agent_service.py index c7b48b76e446..112b3ba57d7a 100644 --- a/packages/google-cloud-geminidataanalytics/tests/unit/gapic/geminidataanalytics_v1beta/test_data_agent_service.py +++ b/packages/google-cloud-geminidataanalytics/tests/unit/gapic/geminidataanalytics_v1beta/test_data_agent_service.py @@ -2481,6 +2481,7 @@ def test_get_data_agent(request_type, transport: str = "grpc"): name="name_value", display_name="display_name_value", description="description_value", + kms_key="kms_key_value", ) response = client.get_data_agent(request) @@ -2495,6 +2496,7 @@ def test_get_data_agent(request_type, transport: str = "grpc"): assert response.name == "name_value" assert response.display_name == "display_name_value" assert response.description == "description_value" + assert response.kms_key == "kms_key_value" def test_get_data_agent_non_empty_request_with_auto_populated_field(): @@ -2629,6 +2631,7 @@ async def test_get_data_agent_async(request_type, transport: str = "grpc_asyncio name="name_value", display_name="display_name_value", description="description_value", + kms_key="kms_key_value", ) ) response = await client.get_data_agent(request) @@ -2644,6 +2647,7 @@ async def test_get_data_agent_async(request_type, transport: str = "grpc_asyncio assert response.name == "name_value" assert response.display_name == "display_name_value" assert response.description == "description_value" + assert response.kms_key == "kms_key_value" def test_get_data_agent_field_headers(): @@ -3217,6 +3221,7 @@ def test_create_data_agent_sync(request_type, transport: str = "grpc"): name="name_value", display_name="display_name_value", description="description_value", + kms_key="kms_key_value", ) response = client.create_data_agent_sync(request) @@ -3231,6 +3236,7 @@ def test_create_data_agent_sync(request_type, transport: str = "grpc"): assert response.name == "name_value" assert response.display_name == "display_name_value" assert response.description == "description_value" + assert response.kms_key == "kms_key_value" def test_create_data_agent_sync_non_empty_request_with_auto_populated_field(): @@ -3378,6 +3384,7 @@ async def test_create_data_agent_sync_async( name="name_value", display_name="display_name_value", description="description_value", + kms_key="kms_key_value", ) ) response = await client.create_data_agent_sync(request) @@ -3393,6 +3400,7 @@ async def test_create_data_agent_sync_async( assert response.name == "name_value" assert response.display_name == "display_name_value" assert response.description == "description_value" + assert response.kms_key == "kms_key_value" def test_create_data_agent_sync_field_headers(): @@ -4014,6 +4022,7 @@ def test_update_data_agent_sync(request_type, transport: str = "grpc"): name="name_value", display_name="display_name_value", description="description_value", + kms_key="kms_key_value", ) response = client.update_data_agent_sync(request) @@ -4028,6 +4037,7 @@ def test_update_data_agent_sync(request_type, transport: str = "grpc"): assert response.name == "name_value" assert response.display_name == "display_name_value" assert response.description == "description_value" + assert response.kms_key == "kms_key_value" def test_update_data_agent_sync_non_empty_request_with_auto_populated_field(): @@ -4169,6 +4179,7 @@ async def test_update_data_agent_sync_async( name="name_value", display_name="display_name_value", description="description_value", + kms_key="kms_key_value", ) ) response = await client.update_data_agent_sync(request) @@ -4184,6 +4195,7 @@ async def test_update_data_agent_sync_async( assert response.name == "name_value" assert response.display_name == "display_name_value" assert response.description == "description_value" + assert response.kms_key == "kms_key_value" def test_update_data_agent_sync_field_headers(): @@ -8471,6 +8483,7 @@ async def test_get_data_agent_empty_call_grpc_asyncio(): name="name_value", display_name="display_name_value", description="description_value", + kms_key="kms_key_value", ) ) await client.get_data_agent(request=None) @@ -8527,6 +8540,7 @@ async def test_create_data_agent_sync_empty_call_grpc_asyncio(): name="name_value", display_name="display_name_value", description="description_value", + kms_key="kms_key_value", ) ) await client.create_data_agent_sync(request=None) @@ -8583,6 +8597,7 @@ async def test_update_data_agent_sync_empty_call_grpc_asyncio(): name="name_value", display_name="display_name_value", description="description_value", + kms_key="kms_key_value", ) ) await client.update_data_agent_sync(request=None) @@ -9034,6 +9049,7 @@ def test_get_data_agent_rest_call_success(request_type): name="name_value", display_name="display_name_value", description="description_value", + kms_key="kms_key_value", ) # Wrap the value into a proper Response obj @@ -9053,6 +9069,7 @@ def test_get_data_agent_rest_call_success(request_type): assert response.name == "name_value" assert response.display_name == "display_name_value" assert response.description == "description_value" + assert response.kms_key == "kms_key_value" @pytest.mark.parametrize("null_interceptor", [True, False]) @@ -9202,7 +9219,14 @@ def test_create_data_agent_rest_call_success(request_type): ], }, } - ] + ], + "property_graph_references": [ + { + "project_id": "project_id_value", + "dataset_id": "dataset_id_value", + "property_graph_id": "property_graph_id_value", + } + ], }, "studio": { "studio_references": [{"datasource_id": "datasource_id_value"}] @@ -9238,6 +9262,9 @@ def test_create_data_agent_rest_call_success(request_type): "instance_id": "instance_id_value", "database_id": "database_id_value", "table_ids": ["table_ids_value1", "table_ids_value2"], + "database_table_references": [ + {"table_id": "table_id_value", "schema": {}} + ], }, "agent_context_reference": { "context_set_id": "context_set_id_value" @@ -9247,10 +9274,12 @@ def test_create_data_agent_rest_call_success(request_type): "database_reference": { "engine": 1, "project_id": "project_id_value", - "region": "region_value", "instance_id": "instance_id_value", "database_id": "database_id_value", "table_ids": ["table_ids_value1", "table_ids_value2"], + "database_table_references": {}, + "priority": "priority_value", + "request_tag": "request_tag_value", }, "agent_context_reference": {}, }, @@ -9262,6 +9291,7 @@ def test_create_data_agent_rest_call_success(request_type): "instance_id": "instance_id_value", "database_id": "database_id_value", "table_ids": ["table_ids_value1", "table_ids_value2"], + "database_table_references": {}, }, "agent_context_reference": {}, }, @@ -9270,11 +9300,19 @@ def test_create_data_agent_rest_call_success(request_type): "chart": {"image": {"no_image": {}, "svg": {}}}, "analysis": {"python": {"enabled": True}}, "datasource": {"big_query_max_billed_bytes": {"value": 541}}, + "model": 1, }, "example_queries": [ { "sql_query": "sql_query_value", "natural_language_question": "natural_language_question_value", + "parameters": [ + { + "name": "name_value", + "description": "description_value", + "data_type": "data_type_value", + } + ], } ], "looker_golden_queries": [ @@ -9292,6 +9330,8 @@ def test_create_data_agent_rest_call_success(request_type): ], "sorts": ["sorts_value1", "sorts_value2"], "limit": "limit_value", + "query_id": "query_id_value", + "client_id": "client_id_value", }, } ], @@ -9313,6 +9353,18 @@ def test_create_data_agent_rest_call_success(request_type): "confidence_score": 0.1673, } ], + "user_functions": { + "bq_routines": [ + { + "routine_reference": { + "project_id": "project_id_value", + "dataset_id": "dataset_id_value", + "routine_id": "routine_id_value", + }, + "description": "description_value", + } + ] + }, }, "published_context": {}, "last_published_context": {}, @@ -9325,6 +9377,7 @@ def test_create_data_agent_rest_call_success(request_type): "update_time": {}, "delete_time": {}, "purge_time": {}, + "kms_key": "kms_key_value", } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -9561,7 +9614,14 @@ def test_create_data_agent_sync_rest_call_success(request_type): ], }, } - ] + ], + "property_graph_references": [ + { + "project_id": "project_id_value", + "dataset_id": "dataset_id_value", + "property_graph_id": "property_graph_id_value", + } + ], }, "studio": { "studio_references": [{"datasource_id": "datasource_id_value"}] @@ -9597,6 +9657,9 @@ def test_create_data_agent_sync_rest_call_success(request_type): "instance_id": "instance_id_value", "database_id": "database_id_value", "table_ids": ["table_ids_value1", "table_ids_value2"], + "database_table_references": [ + {"table_id": "table_id_value", "schema": {}} + ], }, "agent_context_reference": { "context_set_id": "context_set_id_value" @@ -9606,10 +9669,12 @@ def test_create_data_agent_sync_rest_call_success(request_type): "database_reference": { "engine": 1, "project_id": "project_id_value", - "region": "region_value", "instance_id": "instance_id_value", "database_id": "database_id_value", "table_ids": ["table_ids_value1", "table_ids_value2"], + "database_table_references": {}, + "priority": "priority_value", + "request_tag": "request_tag_value", }, "agent_context_reference": {}, }, @@ -9621,6 +9686,7 @@ def test_create_data_agent_sync_rest_call_success(request_type): "instance_id": "instance_id_value", "database_id": "database_id_value", "table_ids": ["table_ids_value1", "table_ids_value2"], + "database_table_references": {}, }, "agent_context_reference": {}, }, @@ -9629,11 +9695,19 @@ def test_create_data_agent_sync_rest_call_success(request_type): "chart": {"image": {"no_image": {}, "svg": {}}}, "analysis": {"python": {"enabled": True}}, "datasource": {"big_query_max_billed_bytes": {"value": 541}}, + "model": 1, }, "example_queries": [ { "sql_query": "sql_query_value", "natural_language_question": "natural_language_question_value", + "parameters": [ + { + "name": "name_value", + "description": "description_value", + "data_type": "data_type_value", + } + ], } ], "looker_golden_queries": [ @@ -9651,6 +9725,8 @@ def test_create_data_agent_sync_rest_call_success(request_type): ], "sorts": ["sorts_value1", "sorts_value2"], "limit": "limit_value", + "query_id": "query_id_value", + "client_id": "client_id_value", }, } ], @@ -9672,6 +9748,18 @@ def test_create_data_agent_sync_rest_call_success(request_type): "confidence_score": 0.1673, } ], + "user_functions": { + "bq_routines": [ + { + "routine_reference": { + "project_id": "project_id_value", + "dataset_id": "dataset_id_value", + "routine_id": "routine_id_value", + }, + "description": "description_value", + } + ] + }, }, "published_context": {}, "last_published_context": {}, @@ -9684,6 +9772,7 @@ def test_create_data_agent_sync_rest_call_success(request_type): "update_time": {}, "delete_time": {}, "purge_time": {}, + "kms_key": "kms_key_value", } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -9761,6 +9850,7 @@ def get_message_fields(field): name="name_value", display_name="display_name_value", description="description_value", + kms_key="kms_key_value", ) # Wrap the value into a proper Response obj @@ -9780,6 +9870,7 @@ def get_message_fields(field): assert response.name == "name_value" assert response.display_name == "display_name_value" assert response.description == "description_value" + assert response.kms_key == "kms_key_value" @pytest.mark.parametrize("null_interceptor", [True, False]) @@ -9933,7 +10024,14 @@ def test_update_data_agent_rest_call_success(request_type): ], }, } - ] + ], + "property_graph_references": [ + { + "project_id": "project_id_value", + "dataset_id": "dataset_id_value", + "property_graph_id": "property_graph_id_value", + } + ], }, "studio": { "studio_references": [{"datasource_id": "datasource_id_value"}] @@ -9969,6 +10067,9 @@ def test_update_data_agent_rest_call_success(request_type): "instance_id": "instance_id_value", "database_id": "database_id_value", "table_ids": ["table_ids_value1", "table_ids_value2"], + "database_table_references": [ + {"table_id": "table_id_value", "schema": {}} + ], }, "agent_context_reference": { "context_set_id": "context_set_id_value" @@ -9978,10 +10079,12 @@ def test_update_data_agent_rest_call_success(request_type): "database_reference": { "engine": 1, "project_id": "project_id_value", - "region": "region_value", "instance_id": "instance_id_value", "database_id": "database_id_value", "table_ids": ["table_ids_value1", "table_ids_value2"], + "database_table_references": {}, + "priority": "priority_value", + "request_tag": "request_tag_value", }, "agent_context_reference": {}, }, @@ -9993,6 +10096,7 @@ def test_update_data_agent_rest_call_success(request_type): "instance_id": "instance_id_value", "database_id": "database_id_value", "table_ids": ["table_ids_value1", "table_ids_value2"], + "database_table_references": {}, }, "agent_context_reference": {}, }, @@ -10001,11 +10105,19 @@ def test_update_data_agent_rest_call_success(request_type): "chart": {"image": {"no_image": {}, "svg": {}}}, "analysis": {"python": {"enabled": True}}, "datasource": {"big_query_max_billed_bytes": {"value": 541}}, + "model": 1, }, "example_queries": [ { "sql_query": "sql_query_value", "natural_language_question": "natural_language_question_value", + "parameters": [ + { + "name": "name_value", + "description": "description_value", + "data_type": "data_type_value", + } + ], } ], "looker_golden_queries": [ @@ -10023,6 +10135,8 @@ def test_update_data_agent_rest_call_success(request_type): ], "sorts": ["sorts_value1", "sorts_value2"], "limit": "limit_value", + "query_id": "query_id_value", + "client_id": "client_id_value", }, } ], @@ -10044,6 +10158,18 @@ def test_update_data_agent_rest_call_success(request_type): "confidence_score": 0.1673, } ], + "user_functions": { + "bq_routines": [ + { + "routine_reference": { + "project_id": "project_id_value", + "dataset_id": "dataset_id_value", + "routine_id": "routine_id_value", + }, + "description": "description_value", + } + ] + }, }, "published_context": {}, "last_published_context": {}, @@ -10056,6 +10182,7 @@ def test_update_data_agent_rest_call_success(request_type): "update_time": {}, "delete_time": {}, "purge_time": {}, + "kms_key": "kms_key_value", } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -10296,7 +10423,14 @@ def test_update_data_agent_sync_rest_call_success(request_type): ], }, } - ] + ], + "property_graph_references": [ + { + "project_id": "project_id_value", + "dataset_id": "dataset_id_value", + "property_graph_id": "property_graph_id_value", + } + ], }, "studio": { "studio_references": [{"datasource_id": "datasource_id_value"}] @@ -10332,6 +10466,9 @@ def test_update_data_agent_sync_rest_call_success(request_type): "instance_id": "instance_id_value", "database_id": "database_id_value", "table_ids": ["table_ids_value1", "table_ids_value2"], + "database_table_references": [ + {"table_id": "table_id_value", "schema": {}} + ], }, "agent_context_reference": { "context_set_id": "context_set_id_value" @@ -10341,10 +10478,12 @@ def test_update_data_agent_sync_rest_call_success(request_type): "database_reference": { "engine": 1, "project_id": "project_id_value", - "region": "region_value", "instance_id": "instance_id_value", "database_id": "database_id_value", "table_ids": ["table_ids_value1", "table_ids_value2"], + "database_table_references": {}, + "priority": "priority_value", + "request_tag": "request_tag_value", }, "agent_context_reference": {}, }, @@ -10356,6 +10495,7 @@ def test_update_data_agent_sync_rest_call_success(request_type): "instance_id": "instance_id_value", "database_id": "database_id_value", "table_ids": ["table_ids_value1", "table_ids_value2"], + "database_table_references": {}, }, "agent_context_reference": {}, }, @@ -10364,11 +10504,19 @@ def test_update_data_agent_sync_rest_call_success(request_type): "chart": {"image": {"no_image": {}, "svg": {}}}, "analysis": {"python": {"enabled": True}}, "datasource": {"big_query_max_billed_bytes": {"value": 541}}, + "model": 1, }, "example_queries": [ { "sql_query": "sql_query_value", "natural_language_question": "natural_language_question_value", + "parameters": [ + { + "name": "name_value", + "description": "description_value", + "data_type": "data_type_value", + } + ], } ], "looker_golden_queries": [ @@ -10386,6 +10534,8 @@ def test_update_data_agent_sync_rest_call_success(request_type): ], "sorts": ["sorts_value1", "sorts_value2"], "limit": "limit_value", + "query_id": "query_id_value", + "client_id": "client_id_value", }, } ], @@ -10407,6 +10557,18 @@ def test_update_data_agent_sync_rest_call_success(request_type): "confidence_score": 0.1673, } ], + "user_functions": { + "bq_routines": [ + { + "routine_reference": { + "project_id": "project_id_value", + "dataset_id": "dataset_id_value", + "routine_id": "routine_id_value", + }, + "description": "description_value", + } + ] + }, }, "published_context": {}, "last_published_context": {}, @@ -10419,6 +10581,7 @@ def test_update_data_agent_sync_rest_call_success(request_type): "update_time": {}, "delete_time": {}, "purge_time": {}, + "kms_key": "kms_key_value", } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -10496,6 +10659,7 @@ def get_message_fields(field): name="name_value", display_name="display_name_value", description="description_value", + kms_key="kms_key_value", ) # Wrap the value into a proper Response obj @@ -10515,6 +10679,7 @@ def get_message_fields(field): assert response.name == "name_value" assert response.display_name == "display_name_value" assert response.description == "description_value" + assert response.kms_key == "kms_key_value" @pytest.mark.parametrize("null_interceptor", [True, False]) @@ -12211,10 +12376,41 @@ def test_data_agent_service_grpc_lro_async_client(): assert transport.operations_client is transport.operations_client -def test_data_agent_path(): +def test_crypto_key_path(): project = "squid" location = "clam" - data_agent = "whelk" + key_ring = "whelk" + crypto_key = "octopus" + expected = "projects/{project}/locations/{location}/keyRings/{key_ring}/cryptoKeys/{crypto_key}".format( + project=project, + location=location, + key_ring=key_ring, + crypto_key=crypto_key, + ) + actual = DataAgentServiceClient.crypto_key_path( + project, location, key_ring, crypto_key + ) + assert expected == actual + + +def test_parse_crypto_key_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + "key_ring": "cuttlefish", + "crypto_key": "mussel", + } + path = DataAgentServiceClient.crypto_key_path(**expected) + + # Check that the path construction is reversible. + actual = DataAgentServiceClient.parse_crypto_key_path(path) + assert expected == actual + + +def test_data_agent_path(): + project = "winkle" + location = "nautilus" + data_agent = "scallop" expected = "projects/{project}/locations/{location}/dataAgents/{data_agent}".format( project=project, location=location, @@ -12226,9 +12422,9 @@ def test_data_agent_path(): def test_parse_data_agent_path(): expected = { - "project": "octopus", - "location": "oyster", - "data_agent": "nudibranch", + "project": "abalone", + "location": "squid", + "data_agent": "clam", } path = DataAgentServiceClient.data_agent_path(**expected) @@ -12238,7 +12434,7 @@ def test_parse_data_agent_path(): def test_common_billing_account_path(): - billing_account = "cuttlefish" + billing_account = "whelk" expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -12248,7 +12444,7 @@ def test_common_billing_account_path(): def test_parse_common_billing_account_path(): expected = { - "billing_account": "mussel", + "billing_account": "octopus", } path = DataAgentServiceClient.common_billing_account_path(**expected) @@ -12258,7 +12454,7 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): - folder = "winkle" + folder = "oyster" expected = "folders/{folder}".format( folder=folder, ) @@ -12268,7 +12464,7 @@ def test_common_folder_path(): def test_parse_common_folder_path(): expected = { - "folder": "nautilus", + "folder": "nudibranch", } path = DataAgentServiceClient.common_folder_path(**expected) @@ -12278,7 +12474,7 @@ def test_parse_common_folder_path(): def test_common_organization_path(): - organization = "scallop" + organization = "cuttlefish" expected = "organizations/{organization}".format( organization=organization, ) @@ -12288,7 +12484,7 @@ def test_common_organization_path(): def test_parse_common_organization_path(): expected = { - "organization": "abalone", + "organization": "mussel", } path = DataAgentServiceClient.common_organization_path(**expected) @@ -12298,7 +12494,7 @@ def test_parse_common_organization_path(): def test_common_project_path(): - project = "squid" + project = "winkle" expected = "projects/{project}".format( project=project, ) @@ -12308,7 +12504,7 @@ def test_common_project_path(): def test_parse_common_project_path(): expected = { - "project": "clam", + "project": "nautilus", } path = DataAgentServiceClient.common_project_path(**expected) @@ -12318,8 +12514,8 @@ def test_parse_common_project_path(): def test_common_location_path(): - project = "whelk" - location = "octopus" + project = "scallop" + location = "abalone" expected = "projects/{project}/locations/{location}".format( project=project, location=location, @@ -12330,8 +12526,8 @@ def test_common_location_path(): def test_parse_common_location_path(): expected = { - "project": "oyster", - "location": "nudibranch", + "project": "squid", + "location": "clam", } path = DataAgentServiceClient.common_location_path(**expected) diff --git a/packages/google-cloud-geminidataanalytics/tests/unit/gapic/geminidataanalytics_v1beta/test_data_chat_service.py b/packages/google-cloud-geminidataanalytics/tests/unit/gapic/geminidataanalytics_v1beta/test_data_chat_service.py index 6348deebdc71..8c92be8a4f29 100644 --- a/packages/google-cloud-geminidataanalytics/tests/unit/gapic/geminidataanalytics_v1beta/test_data_chat_service.py +++ b/packages/google-cloud-geminidataanalytics/tests/unit/gapic/geminidataanalytics_v1beta/test_data_chat_service.py @@ -1626,6 +1626,8 @@ def test_create_conversation(request_type, transport: str = "grpc"): call.return_value = gcg_conversation.Conversation( name="name_value", agents=["agents_value"], + kms_key="kms_key_value", + memory_paused=True, ) response = client.create_conversation(request) @@ -1639,6 +1641,8 @@ def test_create_conversation(request_type, transport: str = "grpc"): assert isinstance(response, gcg_conversation.Conversation) assert response.name == "name_value" assert response.agents == ["agents_value"] + assert response.kms_key == "kms_key_value" + assert response.memory_paused is True def test_create_conversation_non_empty_request_with_auto_populated_field(): @@ -1782,6 +1786,8 @@ async def test_create_conversation_async(request_type, transport: str = "grpc_as gcg_conversation.Conversation( name="name_value", agents=["agents_value"], + kms_key="kms_key_value", + memory_paused=True, ) ) response = await client.create_conversation(request) @@ -1796,6 +1802,8 @@ async def test_create_conversation_async(request_type, transport: str = "grpc_as assert isinstance(response, gcg_conversation.Conversation) assert response.name == "name_value" assert response.agents == ["agents_value"] + assert response.kms_key == "kms_key_value" + assert response.memory_paused is True def test_create_conversation_field_headers(): @@ -2322,6 +2330,8 @@ def test_get_conversation(request_type, transport: str = "grpc"): call.return_value = conversation.Conversation( name="name_value", agents=["agents_value"], + kms_key="kms_key_value", + memory_paused=True, ) response = client.get_conversation(request) @@ -2335,6 +2345,8 @@ def test_get_conversation(request_type, transport: str = "grpc"): assert isinstance(response, conversation.Conversation) assert response.name == "name_value" assert response.agents == ["agents_value"] + assert response.kms_key == "kms_key_value" + assert response.memory_paused is True def test_get_conversation_non_empty_request_with_auto_populated_field(): @@ -2470,6 +2482,8 @@ async def test_get_conversation_async(request_type, transport: str = "grpc_async conversation.Conversation( name="name_value", agents=["agents_value"], + kms_key="kms_key_value", + memory_paused=True, ) ) response = await client.get_conversation(request) @@ -2484,6 +2498,8 @@ async def test_get_conversation_async(request_type, transport: str = "grpc_async assert isinstance(response, conversation.Conversation) assert response.name == "name_value" assert response.agents == ["agents_value"] + assert response.kms_key == "kms_key_value" + assert response.memory_paused is True def test_get_conversation_field_headers(): @@ -5610,6 +5626,8 @@ async def test_create_conversation_empty_call_grpc_asyncio(): gcg_conversation.Conversation( name="name_value", agents=["agents_value"], + kms_key="kms_key_value", + memory_paused=True, ) ) await client.create_conversation(request=None) @@ -5661,6 +5679,8 @@ async def test_get_conversation_empty_call_grpc_asyncio(): conversation.Conversation( name="name_value", agents=["agents_value"], + kms_key="kms_key_value", + memory_paused=True, ) ) await client.get_conversation(request=None) @@ -5936,6 +5956,8 @@ def test_create_conversation_rest_call_success(request_type): "create_time": {"seconds": 751, "nanos": 543}, "last_used_time": {}, "labels": {}, + "kms_key": "kms_key_value", + "memory_paused": True, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -6012,6 +6034,8 @@ def get_message_fields(field): return_value = gcg_conversation.Conversation( name="name_value", agents=["agents_value"], + kms_key="kms_key_value", + memory_paused=True, ) # Wrap the value into a proper Response obj @@ -6030,6 +6054,8 @@ def get_message_fields(field): assert isinstance(response, gcg_conversation.Conversation) assert response.name == "name_value" assert response.agents == ["agents_value"] + assert response.kms_key == "kms_key_value" + assert response.memory_paused is True @pytest.mark.parametrize("null_interceptor", [True, False]) @@ -6257,6 +6283,8 @@ def test_get_conversation_rest_call_success(request_type): return_value = conversation.Conversation( name="name_value", agents=["agents_value"], + kms_key="kms_key_value", + memory_paused=True, ) # Wrap the value into a proper Response obj @@ -6275,6 +6303,8 @@ def test_get_conversation_rest_call_success(request_type): assert isinstance(response, conversation.Conversation) assert response.name == "name_value" assert response.agents == ["agents_value"] + assert response.kms_key == "kms_key_value" + assert response.memory_paused is True @pytest.mark.parametrize("null_interceptor", [True, False]) @@ -7766,10 +7796,41 @@ def test_parse_conversation_path(): assert expected == actual -def test_data_agent_path(): +def test_crypto_key_path(): project = "cuttlefish" location = "mussel" - data_agent = "winkle" + key_ring = "winkle" + crypto_key = "nautilus" + expected = "projects/{project}/locations/{location}/keyRings/{key_ring}/cryptoKeys/{crypto_key}".format( + project=project, + location=location, + key_ring=key_ring, + crypto_key=crypto_key, + ) + actual = DataChatServiceClient.crypto_key_path( + project, location, key_ring, crypto_key + ) + assert expected == actual + + +def test_parse_crypto_key_path(): + expected = { + "project": "scallop", + "location": "abalone", + "key_ring": "squid", + "crypto_key": "clam", + } + path = DataChatServiceClient.crypto_key_path(**expected) + + # Check that the path construction is reversible. + actual = DataChatServiceClient.parse_crypto_key_path(path) + assert expected == actual + + +def test_data_agent_path(): + project = "whelk" + location = "octopus" + data_agent = "oyster" expected = "projects/{project}/locations/{location}/dataAgents/{data_agent}".format( project=project, location=location, @@ -7781,9 +7842,9 @@ def test_data_agent_path(): def test_parse_data_agent_path(): expected = { - "project": "nautilus", - "location": "scallop", - "data_agent": "abalone", + "project": "nudibranch", + "location": "cuttlefish", + "data_agent": "mussel", } path = DataChatServiceClient.data_agent_path(**expected) @@ -7793,7 +7854,7 @@ def test_parse_data_agent_path(): def test_common_billing_account_path(): - billing_account = "squid" + billing_account = "winkle" expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -7803,7 +7864,7 @@ def test_common_billing_account_path(): def test_parse_common_billing_account_path(): expected = { - "billing_account": "clam", + "billing_account": "nautilus", } path = DataChatServiceClient.common_billing_account_path(**expected) @@ -7813,7 +7874,7 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): - folder = "whelk" + folder = "scallop" expected = "folders/{folder}".format( folder=folder, ) @@ -7823,7 +7884,7 @@ def test_common_folder_path(): def test_parse_common_folder_path(): expected = { - "folder": "octopus", + "folder": "abalone", } path = DataChatServiceClient.common_folder_path(**expected) @@ -7833,7 +7894,7 @@ def test_parse_common_folder_path(): def test_common_organization_path(): - organization = "oyster" + organization = "squid" expected = "organizations/{organization}".format( organization=organization, ) @@ -7843,7 +7904,7 @@ def test_common_organization_path(): def test_parse_common_organization_path(): expected = { - "organization": "nudibranch", + "organization": "clam", } path = DataChatServiceClient.common_organization_path(**expected) @@ -7853,7 +7914,7 @@ def test_parse_common_organization_path(): def test_common_project_path(): - project = "cuttlefish" + project = "whelk" expected = "projects/{project}".format( project=project, ) @@ -7863,7 +7924,7 @@ def test_common_project_path(): def test_parse_common_project_path(): expected = { - "project": "mussel", + "project": "octopus", } path = DataChatServiceClient.common_project_path(**expected) @@ -7873,8 +7934,8 @@ def test_parse_common_project_path(): def test_common_location_path(): - project = "winkle" - location = "nautilus" + project = "oyster" + location = "nudibranch" expected = "projects/{project}/locations/{location}".format( project=project, location=location, @@ -7885,8 +7946,8 @@ def test_common_location_path(): def test_parse_common_location_path(): expected = { - "project": "scallop", - "location": "abalone", + "project": "cuttlefish", + "location": "mussel", } path = DataChatServiceClient.common_location_path(**expected) diff --git a/packages/google-cloud-storage/tests/system/test_zonal.py b/packages/google-cloud-storage/tests/system/test_zonal.py index 2d79ec8a817c..bcdaeaffb182 100644 --- a/packages/google-cloud-storage/tests/system/test_zonal.py +++ b/packages/google-cloud-storage/tests/system/test_zonal.py @@ -27,7 +27,6 @@ ObjectCustomContextPayload, ) - pytestmark = pytest.mark.skipif( os.getenv("RUN_ZONAL_SYSTEM_TESTS") != "True", reason="Zonal system tests need to be explicitly enabled. This helps scheduling tests in Kokoro and Cloud Build.", diff --git a/packages/google-cloud-workstations/google/cloud/workstations_v1/services/workstations/async_client.py b/packages/google-cloud-workstations/google/cloud/workstations_v1/services/workstations/async_client.py index 490316be1e22..8fd43959ea38 100644 --- a/packages/google-cloud-workstations/google/cloud/workstations_v1/services/workstations/async_client.py +++ b/packages/google-cloud-workstations/google/cloud/workstations_v1/services/workstations/async_client.py @@ -1413,7 +1413,9 @@ async def sample_create_workstation_config(): on the ``request`` instance; if ``request`` is provided, this should not be set. workstation_config (:class:`google.cloud.workstations_v1.types.WorkstationConfig`): - Required. Config to create. + Required. Workstation configuration + to create. + This corresponds to the ``workstation_config`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1562,7 +1564,9 @@ async def sample_update_workstation_config(): The request object. Request message for UpdateWorkstationConfig. workstation_config (:class:`google.cloud.workstations_v1.types.WorkstationConfig`): - Required. Config to update. + Required. Workstation configuration + to update. + This corresponds to the ``workstation_config`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -2221,7 +2225,14 @@ async def sample_create_workstation(): on the ``request`` instance; if ``request`` is provided, this should not be set. workstation (:class:`google.cloud.workstations_v1.types.Workstation`): - Required. Workstation to create. + Required. Workstation to create. If source_workstation + is specified, the user must have + ``workstations.workstations.use`` permission on the + source workstation, and the Cloud Workstations Service + Agent for the project where you are creating the new + workstation must have compute.disks.createSnapshot and + compute.snapshots.useReadOnly on the source project. + This corresponds to the ``workstation`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -2363,8 +2374,8 @@ async def sample_update_workstation(): should not be set. update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): Required. Mask specifying which - fields in the workstation configuration - should be updated. + fields in the workstation should be + updated. This corresponds to the ``update_mask`` field on the ``request`` instance; if ``request`` is provided, this @@ -2839,7 +2850,8 @@ async def generate_access_token( ) -> workstations.GenerateAccessTokenResponse: r"""Returns a short-lived credential that can be used to send authenticated and authorized traffic to a - workstation. + workstation. Once generated this token cannot be revoked + and is good for the lifetime of the token. .. code-block:: python diff --git a/packages/google-cloud-workstations/google/cloud/workstations_v1/services/workstations/client.py b/packages/google-cloud-workstations/google/cloud/workstations_v1/services/workstations/client.py index e2453f65fce0..201a77a9c903 100644 --- a/packages/google-cloud-workstations/google/cloud/workstations_v1/services/workstations/client.py +++ b/packages/google-cloud-workstations/google/cloud/workstations_v1/services/workstations/client.py @@ -1876,7 +1876,9 @@ def sample_create_workstation_config(): on the ``request`` instance; if ``request`` is provided, this should not be set. workstation_config (google.cloud.workstations_v1.types.WorkstationConfig): - Required. Config to create. + Required. Workstation configuration + to create. + This corresponds to the ``workstation_config`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -2024,7 +2026,9 @@ def sample_update_workstation_config(): The request object. Request message for UpdateWorkstationConfig. workstation_config (google.cloud.workstations_v1.types.WorkstationConfig): - Required. Config to update. + Required. Workstation configuration + to update. + This corresponds to the ``workstation_config`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -2672,7 +2676,14 @@ def sample_create_workstation(): on the ``request`` instance; if ``request`` is provided, this should not be set. workstation (google.cloud.workstations_v1.types.Workstation): - Required. Workstation to create. + Required. Workstation to create. If source_workstation + is specified, the user must have + ``workstations.workstations.use`` permission on the + source workstation, and the Cloud Workstations Service + Agent for the project where you are creating the new + workstation must have compute.disks.createSnapshot and + compute.snapshots.useReadOnly on the source project. + This corresponds to the ``workstation`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -2811,8 +2822,8 @@ def sample_update_workstation(): should not be set. update_mask (google.protobuf.field_mask_pb2.FieldMask): Required. Mask specifying which - fields in the workstation configuration - should be updated. + fields in the workstation should be + updated. This corresponds to the ``update_mask`` field on the ``request`` instance; if ``request`` is provided, this @@ -3275,7 +3286,8 @@ def generate_access_token( ) -> workstations.GenerateAccessTokenResponse: r"""Returns a short-lived credential that can be used to send authenticated and authorized traffic to a - workstation. + workstation. Once generated this token cannot be revoked + and is good for the lifetime of the token. .. code-block:: python diff --git a/packages/google-cloud-workstations/google/cloud/workstations_v1/services/workstations/transports/grpc.py b/packages/google-cloud-workstations/google/cloud/workstations_v1/services/workstations/transports/grpc.py index f7c763db3a7c..09c3420c1c68 100644 --- a/packages/google-cloud-workstations/google/cloud/workstations_v1/services/workstations/transports/grpc.py +++ b/packages/google-cloud-workstations/google/cloud/workstations_v1/services/workstations/transports/grpc.py @@ -900,7 +900,8 @@ def generate_access_token( Returns a short-lived credential that can be used to send authenticated and authorized traffic to a - workstation. + workstation. Once generated this token cannot be revoked + and is good for the lifetime of the token. Returns: Callable[[~.GenerateAccessTokenRequest], diff --git a/packages/google-cloud-workstations/google/cloud/workstations_v1/services/workstations/transports/grpc_asyncio.py b/packages/google-cloud-workstations/google/cloud/workstations_v1/services/workstations/transports/grpc_asyncio.py index 1630391a3946..12f1d4f78f69 100644 --- a/packages/google-cloud-workstations/google/cloud/workstations_v1/services/workstations/transports/grpc_asyncio.py +++ b/packages/google-cloud-workstations/google/cloud/workstations_v1/services/workstations/transports/grpc_asyncio.py @@ -929,7 +929,8 @@ def generate_access_token( Returns a short-lived credential that can be used to send authenticated and authorized traffic to a - workstation. + workstation. Once generated this token cannot be revoked + and is good for the lifetime of the token. Returns: Callable[[~.GenerateAccessTokenRequest], diff --git a/packages/google-cloud-workstations/google/cloud/workstations_v1/types/workstations.py b/packages/google-cloud-workstations/google/cloud/workstations_v1/types/workstations.py index b5180a3edfda..eee957989694 100644 --- a/packages/google-cloud-workstations/google/cloud/workstations_v1/types/workstations.py +++ b/packages/google-cloud-workstations/google/cloud/workstations_v1/types/workstations.py @@ -68,7 +68,8 @@ class WorkstationCluster(proto.Message): Attributes: name (str): - Full name of this workstation cluster. + Identifier. Full name of this workstation + cluster. display_name (str): Optional. Human-readable name for this workstation cluster. @@ -120,14 +121,50 @@ class WorkstationCluster(proto.Message): private_cluster_config (google.cloud.workstations_v1.types.WorkstationCluster.PrivateClusterConfig): Optional. Configuration for private workstation cluster. + domain_config (google.cloud.workstations_v1.types.WorkstationCluster.DomainConfig): + Optional. Configuration options for a custom + domain. degraded (bool): Output only. Whether this workstation cluster is in degraded mode, in which case it may require user action to restore - full functionality. Details can be found in - [conditions][google.cloud.workstations.v1.WorkstationCluster.conditions]. + full functionality. The + [conditions][google.cloud.workstations.v1.WorkstationCluster.conditions] + field contains detailed information about the status of the + cluster. conditions (MutableSequence[google.rpc.status_pb2.Status]): Output only. Status conditions describing the workstation cluster's current state. + tags (MutableMapping[str, str]): + Optional. Input only. Immutable. Tag + keys/values directly bound to this resource. For + example: + + "123/environment": "production", + "123/costCenter": "marketing". + gateway_config (google.cloud.workstations_v1.types.WorkstationCluster.GatewayConfig): + Optional. Configuration options for Cluster + HTTP Gateway. + workstation_authorization_url (str): + Optional. Specifies the redirect URL for unauthorized + requests received by workstation VMs in this cluster. + + Redirects to this endpoint will send a base64 encoded + ``state`` query param containing the target workstation name + and original request hostname. The endpoint is responsible + for retrieving a token using ``GenerateAccessToken`` and + redirecting back to the original hostname with the token. + workstation_launch_url (str): + Optional. Specifies the launch URL for workstations in this + cluster. Requests sent to unstarted workstations will be + redirected to this URL. + + Requests redirected to the launch endpoint will be sent with + a ``workstation`` and ``project`` query parameter containing + the full workstation resource name and project ID, + respectively. The launch endpoint is responsible for + starting the workstation, polling it until it reaches + ``STATE_RUNNING``, and then issuing a redirect to the + workstation's host URL. """ class PrivateClusterConfig(proto.Message): @@ -147,7 +184,7 @@ class PrivateClusterConfig(proto.Message): mapping that address to the service attachment. service_attachment_uri (str): Output only. Service attachment URI for the workstation - cluster. The service attachemnt is created when private + cluster. The service attachment is created when private endpoint is enabled. To access workstations in the workstation cluster, configure access to the managed service using `Private Service @@ -177,6 +214,34 @@ class PrivateClusterConfig(proto.Message): number=4, ) + class DomainConfig(proto.Message): + r"""Configuration options for a custom domain. + + Attributes: + domain (str): + Immutable. Domain used by Workstations for + HTTP ingress. + """ + + domain: str = proto.Field( + proto.STRING, + number=1, + ) + + class GatewayConfig(proto.Message): + r"""Configuration options for Cluster HTTP Gateway. + + Attributes: + http2_enabled (bool): + Optional. Whether HTTP/2 is enabled for this + workstation cluster. Defaults to false. + """ + + http2_enabled: bool = proto.Field( + proto.BOOL, + number=1, + ) + name: str = proto.Field( proto.STRING, number=1, @@ -239,6 +304,11 @@ class PrivateClusterConfig(proto.Message): number=12, message=PrivateClusterConfig, ) + domain_config: DomainConfig = proto.Field( + proto.MESSAGE, + number=17, + message=DomainConfig, + ) degraded: bool = proto.Field( proto.BOOL, number=13, @@ -248,6 +318,24 @@ class PrivateClusterConfig(proto.Message): number=14, message=status_pb2.Status, ) + tags: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=20, + ) + gateway_config: GatewayConfig = proto.Field( + proto.MESSAGE, + number=21, + message=GatewayConfig, + ) + workstation_authorization_url: str = proto.Field( + proto.STRING, + number=22, + ) + workstation_launch_url: str = proto.Field( + proto.STRING, + number=23, + ) class WorkstationConfig(proto.Message): @@ -264,7 +352,8 @@ class WorkstationConfig(proto.Message): Attributes: name (str): - Full name of this workstation configuration. + Identifier. Full name of this workstation + configuration. display_name (str): Optional. Human-readable name for this workstation configuration. @@ -332,11 +421,31 @@ class WorkstationConfig(proto.Message): Workstations VMs created with this configuration have no maximum running time. This is strongly discouraged because you incur costs and will not pick up security updates. + max_usable_workstations (int): + Optional. Maximum number of workstations under this + configuration a user can have + ``workstations.workstation.use`` permission on. + + Only enforced on CreateWorkstation API calls on the user + issuing the API request. Can be overridden by: + + - granting a user + workstations.workstationConfigs.exemptMaxUsableWorkstationLimit + permission, or + - having a user with that permission create a workstation + and granting another user ``workstations.workstation.use`` + permission on that workstation. + + If not specified, defaults to ``0``, which indicates + unlimited. host (google.cloud.workstations_v1.types.WorkstationConfig.Host): Optional. Runtime host for the workstation. persistent_directories (MutableSequence[google.cloud.workstations_v1.types.WorkstationConfig.PersistentDirectory]): Optional. Directories to persist across workstation sessions. + ephemeral_directories (MutableSequence[google.cloud.workstations_v1.types.WorkstationConfig.EphemeralDirectory]): + Optional. Ephemeral directories which won't + persist across workstation sessions. container (google.cloud.workstations_v1.types.WorkstationConfig.Container): Optional. Container that runs upon startup for each workstation using this workstation @@ -383,14 +492,56 @@ class WorkstationConfig(proto.Message): Immutable after the workstation configuration is created. degraded (bool): - Output only. Whether this resource is degraded, in which - case it may require user action to restore full - functionality. See also the + Output only. Whether this workstation configuration is in + degraded mode, in which case it may require user action to + restore full functionality. The [conditions][google.cloud.workstations.v1.WorkstationConfig.conditions] - field. + field contains detailed information about the status of the + configuration. conditions (MutableSequence[google.rpc.status_pb2.Status]): Output only. Status conditions describing the - current resource state. + workstation configuration's current state. + enable_audit_agent (bool): + Optional. Whether to enable Linux ``auditd`` logging on the + workstation. When enabled, a + [service_account][google.cloud.workstations.v1.WorkstationConfig.Host.GceInstance.service_account] + must also be specified that has ``roles/logging.logWriter`` + and ``roles/monitoring.metricWriter`` on the project. + Operating system audit logging is distinct from `Cloud Audit + Logs `__ + and `Container output + logging `__. + Operating system audit logs are available in the `Cloud + Logging `__ console + by querying: + + :: + + resource.type="gce_instance" + log_name:"/logs/linux-auditd". + disable_tcp_connections (bool): + Optional. Disables support for plain TCP + connections in the workstation. By default the + service supports TCP connections through a + websocket relay. Setting this option to true + disables that relay, which prevents the usage of + services that require plain TCP connections, + such as SSH. When enabled, all communication + must occur over HTTPS or WSS. + allowed_ports (MutableSequence[google.cloud.workstations_v1.types.WorkstationConfig.PortRange]): + Optional. A list of + [PortRange][google.cloud.workstations.v1.WorkstationConfig.PortRange]s + specifying single ports or ranges of ports that are + externally accessible in the workstation. Allowed ports must + be one of 22, 80, or within range 1024-65535. If not + specified defaults to ports 22, 80, and ports 1024-65535. + grant_workstation_admin_role_on_create (bool): + Optional. Grant creator of a workstation + ``roles/workstations.policyAdmin`` role along with + ``roles/workstations.user`` role on the workstation created + by them. This allows workstation users to share access to + either their entire workstation, or individual ports. + Defaults to false. """ class Host(proto.Message): @@ -420,10 +571,13 @@ class GceInstance(proto.Message): Optional. The email address of the service account for Cloud Workstations VMs created with this configuration. When specified, be sure that the service account has - ``logginglogEntries.create`` permission on the project so it - can write logs out to Cloud Logging. If using a custom - container image, the service account must have permissions - to pull the specified image. + ``logging.logEntries.create`` and + ``monitoring.timeSeries.create`` permissions on the project + so it can write logs out to Cloud Logging. If using a custom + container image, the service account must have `Artifact + Registry + Reader `__ + permission to pull the specified image. If you as the administrator want to be able to ``ssh`` into the underlying VM, you need to set this value to a service @@ -438,8 +592,7 @@ class GceInstance(proto.Message): service_account_scopes (MutableSequence[str]): Optional. Scopes to grant to the [service_account][google.cloud.workstations.v1.WorkstationConfig.Host.GceInstance.service_account]. - Various scopes are automatically added based on feature - usage. When specified, users of workstations under this + When specified, users of workstations under this configuration must have ``iam.serviceAccounts.actAs`` on the service account. tags (MutableSequence[str]): @@ -469,9 +622,11 @@ class GceInstance(proto.Message): addresses). enable_nested_virtualization (bool): Optional. Whether to enable nested virtualization on Cloud - Workstations VMs created under this workstation + Workstations VMs created using this workstation configuration. + Defaults to false. + Nested virtualization lets you run virtual machine (VM) instances inside your workstation. Before enabling nested virtualization, consider the following important @@ -494,15 +649,6 @@ class GceInstance(proto.Message): enabled on workstation configurations that specify a [machine_type][google.cloud.workstations.v1.WorkstationConfig.Host.GceInstance.machine_type] in the N1 or N2 machine series. - - **GPUs**: nested virtualization may not be enabled on - workstation configurations with accelerators. - - **Operating System**: Because `Container-Optimized - OS `__ - does not support nested virtualization, when nested - virtualization is enabled, the underlying Compute Engine - VM instances boot from an `Ubuntu - LTS `__ - image. shielded_instance_config (google.cloud.workstations_v1.types.WorkstationConfig.Host.GceInstance.GceShieldedInstanceConfig): Optional. A set of Compute Engine Shielded instance options. @@ -513,6 +659,41 @@ class GceInstance(proto.Message): Optional. The size of the boot disk for the VM in gigabytes (GB). The minimum boot disk size is ``30`` GB. Defaults to ``50`` GB. + accelerators (MutableSequence[google.cloud.workstations_v1.types.WorkstationConfig.Host.GceInstance.Accelerator]): + Optional. A list of the type and count of + accelerator cards attached to the instance. + boost_configs (MutableSequence[google.cloud.workstations_v1.types.WorkstationConfig.Host.GceInstance.BoostConfig]): + Optional. A list of the boost configurations + that workstations created using this workstation + configuration are allowed to use. If specified, + users will have the option to choose from the + list of boost configs when starting a + workstation. + disable_ssh (bool): + Optional. Whether to disable SSH access to + the VM. + vm_tags (MutableMapping[str, str]): + Optional. Resource manager tags to be bound to this + instance. Tag keys and values have the same definition as + `resource manager + tags `__. + Keys must be in the format ``tagKeys/{tag_key_id}``, and + values are in the format ``tagValues/456``. + startup_script_uri (str): + Optional. Link to the startup script stored in Cloud + Storage. This script will be run on the host workstation VM + when the VM is created. The URI must be of the form + gs://{bucket-name}/{object-name}. If specifying a startup + script, the service account must have `Permission to access + the bucket and script file in Cloud + Storage `__. + Otherwise, the script must be publicly accessible. Note that + the service regularly updates the OS version of the host VM, + and it is the responsibility of the user to ensure the + script stays compatible with the OS version. + instance_metadata (MutableMapping[str, str]): + Optional. Custom metadata to apply to Compute + Engine instances. """ class GceShieldedInstanceConfig(proto.Message): @@ -557,6 +738,118 @@ class GceConfidentialInstanceConfig(proto.Message): number=1, ) + class Accelerator(proto.Message): + r"""An accelerator card attached to the instance. + + Attributes: + type_ (str): + Optional. Type of accelerator resource to attach to the + instance, for example, ``"nvidia-tesla-p100"``. + count (int): + Optional. Number of accelerator cards exposed + to the instance. + """ + + type_: str = proto.Field( + proto.STRING, + number=1, + ) + count: int = proto.Field( + proto.INT32, + number=2, + ) + + class BoostConfig(proto.Message): + r"""A boost configuration is a set of resources that a + workstation can use to increase its performance. If you specify + a boost configuration, upon startup, workstation users can + choose to use a VM provisioned under the boost config by passing + the boost config ID in the start request. If the workstation + user does not provide a boost config ID in the start request, + the system will choose a VM from the pool provisioned under the + default config. + + Attributes: + id (str): + Required. The ID to be used for the boost + configuration. + machine_type (str): + Optional. The type of machine that boosted VM instances will + use—for example, ``e2-standard-4``. For more information + about machine types that Cloud Workstations supports, see + the list of `available machine + types `__. + Defaults to ``e2-standard-4``. + accelerators (MutableSequence[google.cloud.workstations_v1.types.WorkstationConfig.Host.GceInstance.Accelerator]): + Optional. A list of the type and count of accelerator cards + attached to the boost instance. Defaults to ``none``. + boot_disk_size_gb (int): + Optional. The size of the boot disk for the VM in gigabytes + (GB). The minimum boot disk size is ``30`` GB. Defaults to + ``50`` GB. + enable_nested_virtualization (bool): + Optional. Whether to enable nested virtualization on boosted + Cloud Workstations VMs running using this boost + configuration. + + Defaults to false. + + Nested virtualization lets you run virtual machine (VM) + instances inside your workstation. Before enabling nested + virtualization, consider the following important + considerations. Cloud Workstations instances are subject to + the `same restrictions as Compute Engine + instances `__: + + - **Organization policy**: projects, folders, or + organizations may be restricted from creating nested VMs + if the **Disable VM nested virtualization** constraint is + enforced in the organization policy. For more information, + see the Compute Engine section, `Checking whether nested + virtualization is + allowed `__. + - **Performance**: nested VMs might experience a 10% or + greater decrease in performance for workloads that are + CPU-bound and possibly greater than a 10% decrease for + workloads that are input/output bound. + - **Machine Type**: nested virtualization can only be + enabled on boost configurations that specify a + [machine_type][google.cloud.workstations.v1.WorkstationConfig.Host.GceInstance.BoostConfig.machine_type] + in the N1 or N2 machine series. + pool_size (int): + Optional. The number of boost VMs that the system should + keep idle so that workstations can be boosted quickly. + Defaults to ``0``. + """ + + id: str = proto.Field( + proto.STRING, + number=1, + ) + machine_type: str = proto.Field( + proto.STRING, + number=2, + ) + accelerators: MutableSequence[ + "WorkstationConfig.Host.GceInstance.Accelerator" + ] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message="WorkstationConfig.Host.GceInstance.Accelerator", + ) + boot_disk_size_gb: int = proto.Field( + proto.INT32, + number=4, + ) + enable_nested_virtualization: bool = proto.Field( + proto.BOOL, + number=7, + ) + pool_size: int = proto.Field( + proto.INT32, + number=5, + ) + machine_type: str = proto.Field( proto.STRING, number=1, @@ -603,6 +896,38 @@ class GceConfidentialInstanceConfig(proto.Message): proto.INT32, number=9, ) + accelerators: MutableSequence[ + "WorkstationConfig.Host.GceInstance.Accelerator" + ] = proto.RepeatedField( + proto.MESSAGE, + number=11, + message="WorkstationConfig.Host.GceInstance.Accelerator", + ) + boost_configs: MutableSequence[ + "WorkstationConfig.Host.GceInstance.BoostConfig" + ] = proto.RepeatedField( + proto.MESSAGE, + number=25, + message="WorkstationConfig.Host.GceInstance.BoostConfig", + ) + disable_ssh: bool = proto.Field( + proto.BOOL, + number=13, + ) + vm_tags: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=14, + ) + startup_script_uri: str = proto.Field( + proto.STRING, + number=26, + ) + instance_metadata: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=27, + ) gce_instance: "WorkstationConfig.Host.GceInstance" = proto.Field( proto.MESSAGE, @@ -612,7 +937,14 @@ class GceConfidentialInstanceConfig(proto.Message): ) class PersistentDirectory(proto.Message): - r"""A directory to persist across workstation sessions. + r"""A directory to persist across workstation sessions. Updates + to this field will not update existing workstations and will + only take effect on new workstations. + + 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 @@ -621,6 +953,11 @@ class PersistentDirectory(proto.Message): A PersistentDirectory backed by a Compute Engine persistent disk. + This field is a member of `oneof`_ ``directory_type``. + gce_hd (google.cloud.workstations_v1.types.WorkstationConfig.PersistentDirectory.GceHyperdiskBalancedHighAvailability): + A PersistentDirectory backed by a Compute + Engine hyperdisk high availability disk. + This field is a member of `oneof`_ ``directory_type``. mount_path (str): Optional. Location of this directory in the @@ -628,8 +965,8 @@ class PersistentDirectory(proto.Message): """ class GceRegionalPersistentDisk(proto.Message): - r"""A PersistentDirectory backed by a Compute Engine regional persistent - disk. The + r"""A Persistent Directory backed by a Compute Engine regional + persistent disk. The [persistent_directories][google.cloud.workstations.v1.WorkstationConfig.persistent_directories] field is repeated, but it may contain only one entry. It creates a `persistent @@ -652,6 +989,10 @@ class GceRegionalPersistentDisk(proto.Message): the [disk_type][google.cloud.workstations.v1.WorkstationConfig.PersistentDirectory.GceRegionalPersistentDisk.disk_type] must be ``"pd-balanced"`` or ``"pd-ssd"``. + max_size_gb (int): + Optional. Maximum size in GB to which this + persistent directory can be resized. Defaults to + unlimited if not set. fs_type (str): Optional. Type of file system that the disk should be formatted with. The workstation image must support this file @@ -668,11 +1009,22 @@ class GceRegionalPersistentDisk(proto.Message): [size_gb][google.cloud.workstations.v1.WorkstationConfig.PersistentDirectory.GceRegionalPersistentDisk.size_gb] and [fs_type][google.cloud.workstations.v1.WorkstationConfig.PersistentDirectory.GceRegionalPersistentDisk.fs_type] - must be empty. + must be empty. Must be formatted as ext4 file system with no + partitions. reclaim_policy (google.cloud.workstations_v1.types.WorkstationConfig.PersistentDirectory.GceRegionalPersistentDisk.ReclaimPolicy): Optional. Whether the persistent disk should be deleted when the workstation is deleted. Valid values are ``DELETE`` and ``RETAIN``. Defaults to ``DELETE``. + archive_timeout (google.protobuf.duration_pb2.Duration): + Optional. Number of seconds to wait after initially creating + or subsequently shutting down the workstation before + converting its disk into a snapshot. This generally saves + costs at the expense of greater startup time on next + workstation start, as the service will need to create a disk + from the archival snapshot. + + A value of ``"0s"`` indicates that the disk will never be + archived. """ class ReclaimPolicy(proto.Enum): @@ -699,6 +1051,10 @@ class ReclaimPolicy(proto.Enum): proto.INT32, number=1, ) + max_size_gb: int = proto.Field( + proto.INT32, + number=7, + ) fs_type: str = proto.Field( proto.STRING, number=2, @@ -716,6 +1072,98 @@ class ReclaimPolicy(proto.Enum): number=4, enum="WorkstationConfig.PersistentDirectory.GceRegionalPersistentDisk.ReclaimPolicy", ) + archive_timeout: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=6, + message=duration_pb2.Duration, + ) + + class GceHyperdiskBalancedHighAvailability(proto.Message): + r"""A Persistent Directory backed by a Compute Engine `Hyperdisk + Balanced High Availability + Disk `__. + This is a high-availability block storage solution that offers a + balance between performance and cost for most general-purpose + workloads. + + Attributes: + size_gb (int): + Optional. The GB capacity of a persistent home directory for + each workstation created with this configuration. Must be + empty if + [source_snapshot][google.cloud.workstations.v1.WorkstationConfig.PersistentDirectory.GceHyperdiskBalancedHighAvailability.source_snapshot] + is set. + + Valid values are ``10``, ``50``, ``100``, ``200``, ``500``, + or ``1000``. Defaults to ``200``. + max_size_gb (int): + Optional. Maximum size in GB to which this + persistent directory can be resized. Defaults to + unlimited if not set. + source_snapshot (str): + Optional. Name of the snapshot to use as the source for the + disk. If set, + [size_gb][google.cloud.workstations.v1.WorkstationConfig.PersistentDirectory.GceHyperdiskBalancedHighAvailability.size_gb] + must be empty. Must be formatted as ext4 file system with no + partitions. + reclaim_policy (google.cloud.workstations_v1.types.WorkstationConfig.PersistentDirectory.GceHyperdiskBalancedHighAvailability.ReclaimPolicy): + Optional. Whether the persistent disk should be deleted when + the workstation is deleted. Valid values are ``DELETE`` and + ``RETAIN``. Defaults to ``DELETE``. + archive_timeout (google.protobuf.duration_pb2.Duration): + Optional. Number of seconds to wait after initially creating + or subsequently shutting down the workstation before + converting its disk into a snapshot. This generally saves + costs at the expense of greater startup time on next + workstation start, as the service will need to create a disk + from the archival snapshot. + + A value of ``"0s"`` indicates that the disk will never be + archived. + """ + + class ReclaimPolicy(proto.Enum): + r"""Value representing what should happen to the disk after the + workstation is deleted. + + Values: + RECLAIM_POLICY_UNSPECIFIED (0): + Do not use. + DELETE (1): + Delete the persistent disk when deleting the + workstation. + RETAIN (2): + Keep the persistent disk when deleting the + workstation. An administrator must manually + delete the disk. + """ + + RECLAIM_POLICY_UNSPECIFIED = 0 + DELETE = 1 + RETAIN = 2 + + size_gb: int = proto.Field( + proto.INT32, + number=1, + ) + max_size_gb: int = proto.Field( + proto.INT32, + number=5, + ) + source_snapshot: str = proto.Field( + proto.STRING, + number=2, + ) + reclaim_policy: "WorkstationConfig.PersistentDirectory.GceHyperdiskBalancedHighAvailability.ReclaimPolicy" = proto.Field( + proto.ENUM, + number=3, + enum="WorkstationConfig.PersistentDirectory.GceHyperdiskBalancedHighAvailability.ReclaimPolicy", + ) + archive_timeout: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=4, + message=duration_pb2.Duration, + ) gce_pd: "WorkstationConfig.PersistentDirectory.GceRegionalPersistentDisk" = proto.Field( proto.MESSAGE, @@ -723,6 +1171,107 @@ class ReclaimPolicy(proto.Enum): oneof="directory_type", message="WorkstationConfig.PersistentDirectory.GceRegionalPersistentDisk", ) + gce_hd: "WorkstationConfig.PersistentDirectory.GceHyperdiskBalancedHighAvailability" = proto.Field( + proto.MESSAGE, + number=3, + oneof="directory_type", + message="WorkstationConfig.PersistentDirectory.GceHyperdiskBalancedHighAvailability", + ) + mount_path: str = proto.Field( + proto.STRING, + number=1, + ) + + class EphemeralDirectory(proto.Message): + r"""An ephemeral directory which won't persist across workstation + sessions. It is freshly created on every workstation start + operation. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + gce_pd (google.cloud.workstations_v1.types.WorkstationConfig.EphemeralDirectory.GcePersistentDisk): + An EphemeralDirectory backed by a Compute + Engine persistent disk. + + This field is a member of `oneof`_ ``directory_type``. + mount_path (str): + Required. Location of this directory in the + running workstation. + """ + + class GcePersistentDisk(proto.Message): + r"""An EphemeralDirectory is backed by a Compute Engine + persistent disk. + + Attributes: + disk_type (str): + Optional. Type of the disk to use. Defaults to + ``"pd-standard"``. + source_snapshot (str): + Optional. Name of the snapshot to use as the source for the + disk. Must be empty if + [source_image][google.cloud.workstations.v1.WorkstationConfig.EphemeralDirectory.GcePersistentDisk.source_image] + is set. Must be empty if + [read_only][google.cloud.workstations.v1.WorkstationConfig.EphemeralDirectory.GcePersistentDisk.read_only] + is false. Updating + [source_snapshot][google.cloud.workstations.v1.WorkstationConfig.EphemeralDirectory.GcePersistentDisk.source_snapshot] + will update content in the ephemeral directory after the + workstation is restarted. + + Only file systems supported by Container-Optimized OS (COS) + are explicitly supported. For a list of supported file + systems, see `the filesystems available in + Container-Optimized + OS `__. + + This field is mutable. + source_image (str): + Optional. Name of the disk image to use as the source for + the disk. Must be empty if + [source_snapshot][google.cloud.workstations.v1.WorkstationConfig.EphemeralDirectory.GcePersistentDisk.source_snapshot] + is set. Updating + [source_image][google.cloud.workstations.v1.WorkstationConfig.EphemeralDirectory.GcePersistentDisk.source_image] + will update content in the ephemeral directory after the + workstation is restarted. + + Only file systems supported by Container-Optimized OS (COS) + are explicitly supported. For a list of supported file + systems, please refer to the `COS + documentation `__. + + This field is mutable. + read_only (bool): + Optional. Whether the disk is read only. If true, the disk + may be shared by multiple VMs and + [source_snapshot][google.cloud.workstations.v1.WorkstationConfig.EphemeralDirectory.GcePersistentDisk.source_snapshot] + must be set. + """ + + disk_type: str = proto.Field( + proto.STRING, + number=1, + ) + source_snapshot: str = proto.Field( + proto.STRING, + number=2, + ) + source_image: str = proto.Field( + proto.STRING, + number=3, + ) + read_only: bool = proto.Field( + proto.BOOL, + number=4, + ) + + gce_pd: "WorkstationConfig.EphemeralDirectory.GcePersistentDisk" = proto.Field( + proto.MESSAGE, + number=3, + oneof="directory_type", + message="WorkstationConfig.EphemeralDirectory.GcePersistentDisk", + ) mount_path: str = proto.Field( proto.STRING, number=1, @@ -742,9 +1291,12 @@ class Container(proto.Message): images `__. If using a private image, the ``host.gceInstance.serviceAccount`` field must be specified - in the workstation configuration and must have permission to - pull the specified image. Otherwise, the image must be - publicly accessible. + in the workstation configuration. If using a custom + container image, the service account must have `Artifact + Registry + Reader `__ + permission to pull the specified image. Otherwise, the image + must be publicly accessible. command (MutableSequence[str]): Optional. If set, overrides the default ENTRYPOINT specified by the image. @@ -842,6 +1394,37 @@ class ReadinessCheck(proto.Message): number=2, ) + class PortRange(proto.Message): + r"""A PortRange defines a range of ports. Both + [first][google.cloud.workstations.v1.WorkstationConfig.PortRange.first] + and + [last][google.cloud.workstations.v1.WorkstationConfig.PortRange.last] + are inclusive. To specify a single port, both + [first][google.cloud.workstations.v1.WorkstationConfig.PortRange.first] + and + [last][google.cloud.workstations.v1.WorkstationConfig.PortRange.last] + should be the same. + + Attributes: + first (int): + Required. Starting port number for the + current range of ports. Valid ports are 22, 80, + and ports within the range 1024-65535. + last (int): + Required. Ending port number for the current + range of ports. Valid ports are 22, 80, and + ports within the range 1024-65535. + """ + + first: int = proto.Field( + proto.INT32, + number=1, + ) + last: int = proto.Field( + proto.INT32, + number=2, + ) + name: str = proto.Field( proto.STRING, number=1, @@ -897,6 +1480,10 @@ class ReadinessCheck(proto.Message): number=11, message=duration_pb2.Duration, ) + max_usable_workstations: int = proto.Field( + proto.INT32, + number=28, + ) host: Host = proto.Field( proto.MESSAGE, number=12, @@ -907,6 +1494,11 @@ class ReadinessCheck(proto.Message): number=13, message=PersistentDirectory, ) + ephemeral_directories: MutableSequence[EphemeralDirectory] = proto.RepeatedField( + proto.MESSAGE, + number=22, + message=EphemeralDirectory, + ) container: Container = proto.Field( proto.MESSAGE, number=14, @@ -935,6 +1527,23 @@ class ReadinessCheck(proto.Message): number=16, message=status_pb2.Status, ) + enable_audit_agent: bool = proto.Field( + proto.BOOL, + number=20, + ) + disable_tcp_connections: bool = proto.Field( + proto.BOOL, + number=24, + ) + allowed_ports: MutableSequence[PortRange] = proto.RepeatedField( + proto.MESSAGE, + number=25, + message=PortRange, + ) + grant_workstation_admin_role_on_create: bool = proto.Field( + proto.BOOL, + number=29, + ) class Workstation(proto.Message): @@ -943,7 +1552,7 @@ class Workstation(proto.Message): Attributes: name (str): - Full name of this workstation. + Identifier. Full name of this workstation. display_name (str): Optional. Human-readable name for this workstation. @@ -979,6 +1588,9 @@ class Workstation(proto.Message): May be sent on update and delete requests to make sure that the client has an up-to-date value before proceeding. + persistent_directories (MutableSequence[google.cloud.workstations_v1.types.Workstation.WorkstationPersistentDirectory]): + Optional. Directories to persist across + workstation sessions. state (google.cloud.workstations_v1.types.Workstation.State): Output only. Current state of the workstation. @@ -989,6 +1601,21 @@ class Workstation(proto.Message): send traffic to a different port, clients may prefix the host with the destination port in the format ``{port}-{host}``. + env (MutableMapping[str, str]): + Optional. Environment variables passed to the + workstation container's entrypoint. + kms_key (str): + Output only. The name of the Google Cloud KMS encryption key + used to encrypt this workstation. The KMS key can only be + configured in the WorkstationConfig. The expected format is + ``projects/*/locations/*/keyRings/*/cryptoKeys/*``. + source_workstation (str): + Optional. The source workstation from which + this workstation's persistent directories were + cloned on creation. + runtime_host (google.cloud.workstations_v1.types.Workstation.RuntimeHost): + Optional. Output only. Runtime host for the workstation when + in STATE_RUNNING. """ class State(proto.Enum): @@ -1017,6 +1644,78 @@ class State(proto.Enum): STATE_STOPPING = 3 STATE_STOPPED = 4 + class WorkstationPersistentDirectory(proto.Message): + r"""A directory to persist across workstation sessions. Updates + to this field will only take effect on this workstation after it + is restarted. + + Attributes: + mount_path (str): + Optional. The mount path of the persistent + directory. + size_gb (int): + Optional. Size of the persistent directory in + GB. If specified in an update request, this is + the desired size of the directory. + """ + + mount_path: str = proto.Field( + proto.STRING, + number=2, + ) + size_gb: int = proto.Field( + proto.INT32, + number=3, + ) + + class RuntimeHost(proto.Message): + r"""Runtime host for the workstation. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + gce_instance_host (google.cloud.workstations_v1.types.Workstation.RuntimeHost.GceInstanceHost): + Specifies a Compute Engine instance as the + host. + + This field is a member of `oneof`_ ``host_type``. + """ + + class GceInstanceHost(proto.Message): + r"""The Compute Engine instance host. + + Attributes: + name (str): + Optional. Output only. The name of the + Compute Engine instance. + id (str): + Optional. Output only. The ID of the Compute + Engine instance. + zone (str): + Optional. Output only. The zone of the + Compute Engine instance. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + id: str = proto.Field( + proto.STRING, + number=2, + ) + zone: str = proto.Field( + proto.STRING, + number=3, + ) + + gce_instance_host: "Workstation.RuntimeHost.GceInstanceHost" = proto.Field( + proto.MESSAGE, + number=1, + oneof="host_type", + message="Workstation.RuntimeHost.GceInstanceHost", + ) + name: str = proto.Field( proto.STRING, number=1, @@ -1067,6 +1766,13 @@ class State(proto.Enum): proto.STRING, number=9, ) + persistent_directories: MutableSequence[WorkstationPersistentDirectory] = ( + proto.RepeatedField( + proto.MESSAGE, + number=25, + message=WorkstationPersistentDirectory, + ) + ) state: State = proto.Field( proto.ENUM, number=10, @@ -1076,6 +1782,24 @@ class State(proto.Enum): proto.STRING, number=11, ) + env: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=12, + ) + kms_key: str = proto.Field( + proto.STRING, + number=15, + ) + source_workstation: str = proto.Field( + proto.STRING, + number=17, + ) + runtime_host: RuntimeHost = proto.Field( + proto.MESSAGE, + number=21, + message=RuntimeHost, + ) class GetWorkstationClusterRequest(proto.Message): @@ -1103,6 +1827,10 @@ class ListWorkstationClustersRequest(proto.Message): page_token (str): Optional. next_page_token value returned from a previous List request, if any. + filter (str): + Optional. Filter the WorkstationClusters to + be listed. Possible filters are described in + https://google.aip.dev/160. """ parent: str = proto.Field( @@ -1117,6 +1845,10 @@ class ListWorkstationClustersRequest(proto.Message): proto.STRING, number=3, ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) class ListWorkstationClustersResponse(proto.Message): @@ -1165,7 +1897,7 @@ class CreateWorkstationClusterRequest(proto.Message): Required. Workstation cluster to create. validate_only (bool): Optional. If set, validate the request and - preview the review, but do not actually apply + preview the result, but do not actually apply it. """ @@ -1199,7 +1931,7 @@ class UpdateWorkstationClusterRequest(proto.Message): the workstation cluster should be updated. validate_only (bool): Optional. If set, validate the request and - preview the review, but do not actually apply + preview the result, but do not actually apply it. allow_missing (bool): Optional. If set, and the workstation cluster is not found, @@ -1236,7 +1968,7 @@ class DeleteWorkstationClusterRequest(proto.Message): delete. validate_only (bool): Optional. If set, validate the request and - preview the review, but do not apply it. + preview the result, but do not apply it. etag (str): Optional. If set, the request will be rejected if the latest version of the @@ -1293,6 +2025,10 @@ class ListWorkstationConfigsRequest(proto.Message): page_token (str): Optional. next_page_token value returned from a previous List request, if any. + filter (str): + Optional. Filter the WorkstationConfigs to be + listed. Possible filters are described in + https://google.aip.dev/160. """ parent: str = proto.Field( @@ -1307,6 +2043,10 @@ class ListWorkstationConfigsRequest(proto.Message): proto.STRING, number=3, ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) class ListWorkstationConfigsResponse(proto.Message): @@ -1412,10 +2152,11 @@ class CreateWorkstationConfigRequest(proto.Message): Required. ID to use for the workstation configuration. workstation_config (google.cloud.workstations_v1.types.WorkstationConfig): - Required. Config to create. + Required. Workstation configuration to + create. validate_only (bool): Optional. If set, validate the request and - preview the review, but do not actually apply + preview the result, but do not actually apply it. """ @@ -1443,13 +2184,14 @@ class UpdateWorkstationConfigRequest(proto.Message): Attributes: workstation_config (google.cloud.workstations_v1.types.WorkstationConfig): - Required. Config to update. + Required. Workstation configuration to + update. update_mask (google.protobuf.field_mask_pb2.FieldMask): Required. Mask specifying which fields in the workstation configuration should be updated. validate_only (bool): Optional. If set, validate the request and - preview the review, but do not actually apply + preview the result, but do not actually apply it. allow_missing (bool): Optional. If set and the workstation configuration is not @@ -1486,7 +2228,7 @@ class DeleteWorkstationConfigRequest(proto.Message): configuration to delete. validate_only (bool): Optional. If set, validate the request and - preview the review, but do not actually apply + preview the result, but do not actually apply it. etag (str): Optional. If set, the request is rejected if @@ -1543,6 +2285,10 @@ class ListWorkstationsRequest(proto.Message): page_token (str): Optional. next_page_token value returned from a previous List request, if any. + filter (str): + Optional. Filter the Workstations to be + listed. Possible filters are described in + https://google.aip.dev/160. """ parent: str = proto.Field( @@ -1557,6 +2303,10 @@ class ListWorkstationsRequest(proto.Message): proto.STRING, number=3, ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) class ListWorkstationsResponse(proto.Message): @@ -1661,10 +2411,16 @@ class CreateWorkstationRequest(proto.Message): workstation_id (str): Required. ID to use for the workstation. workstation (google.cloud.workstations_v1.types.Workstation): - Required. Workstation to create. + Required. Workstation to create. If source_workstation is + specified, the user must have + ``workstations.workstations.use`` permission on the source + workstation, and the Cloud Workstations Service Agent for + the project where you are creating the new workstation must + have compute.disks.createSnapshot and + compute.snapshots.useReadOnly on the source project. validate_only (bool): Optional. If set, validate the request and - preview the review, but do not actually apply + preview the result, but do not actually apply it. """ @@ -1695,15 +2451,15 @@ class UpdateWorkstationRequest(proto.Message): Required. Workstation to update. update_mask (google.protobuf.field_mask_pb2.FieldMask): Required. Mask specifying which fields in the - workstation configuration should be updated. + workstation should be updated. validate_only (bool): Optional. If set, validate the request and - preview the review, but do not actually apply + preview the result, but do not actually apply it. allow_missing (bool): - Optional. If set and the workstation configuration is not - found, a new workstation configuration is created. In this - situation, update_mask is ignored. + Optional. If set and the workstation is not found, a new + workstation is created. In this situation, update_mask is + ignored. """ workstation: "Workstation" = proto.Field( @@ -1734,7 +2490,7 @@ class DeleteWorkstationRequest(proto.Message): Required. Name of the workstation to delete. validate_only (bool): Optional. If set, validate the request and - preview the review, but do not actually apply + preview the result, but do not actually apply it. etag (str): Optional. If set, the request will be @@ -1765,13 +2521,17 @@ class StartWorkstationRequest(proto.Message): Required. Name of the workstation to start. validate_only (bool): Optional. If set, validate the request and - preview the review, but do not actually apply + preview the result, but do not actually apply it. etag (str): Optional. If set, the request will be rejected if the latest version of the workstation on the server does not have this ETag. + boost_config (str): + Optional. If set, the workstation starts + using the boost configuration with the specified + ID. """ name: str = proto.Field( @@ -1786,6 +2546,10 @@ class StartWorkstationRequest(proto.Message): proto.STRING, number=3, ) + boost_config: str = proto.Field( + proto.STRING, + number=4, + ) class StopWorkstationRequest(proto.Message): @@ -1796,7 +2560,7 @@ class StopWorkstationRequest(proto.Message): Required. Name of the workstation to stop. validate_only (bool): Optional. If set, validate the request and - preview the review, but do not actually apply + preview the result, but do not actually apply it. etag (str): Optional. If set, the request will be @@ -1848,6 +2612,13 @@ class GenerateAccessTokenRequest(proto.Message): workstation (str): Required. Name of the workstation for which the access token should be generated. + port (int): + Optional. Port for which the access token should be + generated. If specified, the generated access token grants + access only to the specified port of the workstation. If + specified, values must be within the range [1 - 65535]. If + not specified, the generated access token grants access to + all ports of the workstation. """ expire_time: timestamp_pb2.Timestamp = proto.Field( @@ -1866,6 +2637,10 @@ class GenerateAccessTokenRequest(proto.Message): proto.STRING, number=1, ) + port: int = proto.Field( + proto.INT32, + number=4, + ) class GenerateAccessTokenResponse(proto.Message): diff --git a/packages/google-cloud-workstations/google/cloud/workstations_v1beta/__init__.py b/packages/google-cloud-workstations/google/cloud/workstations_v1beta/__init__.py index 1afa425e3c15..1a0ed5c51123 100644 --- a/packages/google-cloud-workstations/google/cloud/workstations_v1beta/__init__.py +++ b/packages/google-cloud-workstations/google/cloud/workstations_v1beta/__init__.py @@ -47,6 +47,8 @@ ListWorkstationsRequest, ListWorkstationsResponse, OperationMetadata, + PushCredentialsMetadata, + PushCredentialsRequest, StartWorkstationRequest, StopWorkstationRequest, UpdateWorkstationClusterRequest, @@ -164,6 +166,8 @@ def _get_version(dependency_name): "ListWorkstationsRequest", "ListWorkstationsResponse", "OperationMetadata", + "PushCredentialsMetadata", + "PushCredentialsRequest", "StartWorkstationRequest", "StopWorkstationRequest", "UpdateWorkstationClusterRequest", diff --git a/packages/google-cloud-workstations/google/cloud/workstations_v1beta/gapic_metadata.json b/packages/google-cloud-workstations/google/cloud/workstations_v1beta/gapic_metadata.json index cf8a80968ec1..b5e2753ac53e 100644 --- a/packages/google-cloud-workstations/google/cloud/workstations_v1beta/gapic_metadata.json +++ b/packages/google-cloud-workstations/google/cloud/workstations_v1beta/gapic_metadata.json @@ -85,6 +85,11 @@ "list_workstations" ] }, + "PushCredentials": { + "methods": [ + "push_credentials" + ] + }, "StartWorkstation": { "methods": [ "start_workstation" @@ -190,6 +195,11 @@ "list_workstations" ] }, + "PushCredentials": { + "methods": [ + "push_credentials" + ] + }, "StartWorkstation": { "methods": [ "start_workstation" @@ -295,6 +305,11 @@ "list_workstations" ] }, + "PushCredentials": { + "methods": [ + "push_credentials" + ] + }, "StartWorkstation": { "methods": [ "start_workstation" diff --git a/packages/google-cloud-workstations/google/cloud/workstations_v1beta/services/workstations/async_client.py b/packages/google-cloud-workstations/google/cloud/workstations_v1beta/services/workstations/async_client.py index 66e4284718ab..d9eae3bc2993 100644 --- a/packages/google-cloud-workstations/google/cloud/workstations_v1beta/services/workstations/async_client.py +++ b/packages/google-cloud-workstations/google/cloud/workstations_v1beta/services/workstations/async_client.py @@ -1413,7 +1413,9 @@ async def sample_create_workstation_config(): on the ``request`` instance; if ``request`` is provided, this should not be set. workstation_config (:class:`google.cloud.workstations_v1beta.types.WorkstationConfig`): - Required. Config to create. + Required. Workstation configuration + to create. + This corresponds to the ``workstation_config`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1562,7 +1564,9 @@ async def sample_update_workstation_config(): The request object. Request message for UpdateWorkstationConfig. workstation_config (:class:`google.cloud.workstations_v1beta.types.WorkstationConfig`): - Required. Config to update. + Required. Workstation configuration + to update. + This corresponds to the ``workstation_config`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -2221,7 +2225,14 @@ async def sample_create_workstation(): on the ``request`` instance; if ``request`` is provided, this should not be set. workstation (:class:`google.cloud.workstations_v1beta.types.Workstation`): - Required. Workstation to create. + Required. Workstation to create. If source_workstation + is specified, the user must have + ``workstations.workstations.use`` permission on the + source workstation, and the Cloud Workstations Service + Agent for the project where you are creating the new + workstation must have compute.disks.createSnapshot and + compute.snapshots.useReadOnly on the source project. + This corresponds to the ``workstation`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -2363,8 +2374,8 @@ async def sample_update_workstation(): should not be set. update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): Required. Mask specifying which - fields in the workstation configuration - should be updated. + fields in the workstation should be + updated. This corresponds to the ``update_mask`` field on the ``request`` instance; if ``request`` is provided, this @@ -2839,7 +2850,8 @@ async def generate_access_token( ) -> workstations.GenerateAccessTokenResponse: r"""Returns a short-lived credential that can be used to send authenticated and authorized traffic to a - workstation. + workstation. Once generated this token cannot be revoked + and is good for the lifetime of the token. .. code-block:: python @@ -2944,6 +2956,137 @@ async def sample_generate_access_token(): # Done; return the response. return response + async def push_credentials( + self, + request: Optional[Union[workstations.PushCredentialsRequest, dict]] = None, + *, + workstation: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""Pushes credentials to a running workstation on behalf of a user. + Once complete, supported credential types + (application_default_credentials) are made available to + processes running in the user container. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import workstations_v1beta + + async def sample_push_credentials(): + # Create a client + client = workstations_v1beta.WorkstationsAsyncClient() + + # Initialize request argument(s) + request = workstations_v1beta.PushCredentialsRequest( + workstation="workstation_value", + ) + + # Make the request + operation = await client.push_credentials(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.workstations_v1beta.types.PushCredentialsRequest, dict]]): + The request object. Request message for PushCredentials. + workstation (:class:`str`): + Required. Name of the workstation for + which the credentials should be pushed. + + This corresponds to the ``workstation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + 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.workstations_v1beta.types.Workstation` + A single instance of a developer workstation with its + own persistent storage. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [workstation] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, workstations.PushCredentialsRequest): + request = workstations.PushCredentialsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if workstation is not None: + request.workstation = workstation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.push_credentials + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("workstation", request.workstation),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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, + workstations.Workstation, + metadata_type=workstations.PushCredentialsMetadata, + ) + + # Done; return the response. + return response + async def list_operations( self, request: Optional[Union[operations_pb2.ListOperationsRequest, dict]] = None, diff --git a/packages/google-cloud-workstations/google/cloud/workstations_v1beta/services/workstations/client.py b/packages/google-cloud-workstations/google/cloud/workstations_v1beta/services/workstations/client.py index d363529917b4..1fdbed3608f8 100644 --- a/packages/google-cloud-workstations/google/cloud/workstations_v1beta/services/workstations/client.py +++ b/packages/google-cloud-workstations/google/cloud/workstations_v1beta/services/workstations/client.py @@ -1876,7 +1876,9 @@ def sample_create_workstation_config(): on the ``request`` instance; if ``request`` is provided, this should not be set. workstation_config (google.cloud.workstations_v1beta.types.WorkstationConfig): - Required. Config to create. + Required. Workstation configuration + to create. + This corresponds to the ``workstation_config`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -2024,7 +2026,9 @@ def sample_update_workstation_config(): The request object. Request message for UpdateWorkstationConfig. workstation_config (google.cloud.workstations_v1beta.types.WorkstationConfig): - Required. Config to update. + Required. Workstation configuration + to update. + This corresponds to the ``workstation_config`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -2672,7 +2676,14 @@ def sample_create_workstation(): on the ``request`` instance; if ``request`` is provided, this should not be set. workstation (google.cloud.workstations_v1beta.types.Workstation): - Required. Workstation to create. + Required. Workstation to create. If source_workstation + is specified, the user must have + ``workstations.workstations.use`` permission on the + source workstation, and the Cloud Workstations Service + Agent for the project where you are creating the new + workstation must have compute.disks.createSnapshot and + compute.snapshots.useReadOnly on the source project. + This corresponds to the ``workstation`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -2811,8 +2822,8 @@ def sample_update_workstation(): should not be set. update_mask (google.protobuf.field_mask_pb2.FieldMask): Required. Mask specifying which - fields in the workstation configuration - should be updated. + fields in the workstation should be + updated. This corresponds to the ``update_mask`` field on the ``request`` instance; if ``request`` is provided, this @@ -3275,7 +3286,8 @@ def generate_access_token( ) -> workstations.GenerateAccessTokenResponse: r"""Returns a short-lived credential that can be used to send authenticated and authorized traffic to a - workstation. + workstation. Once generated this token cannot be revoked + and is good for the lifetime of the token. .. code-block:: python @@ -3377,6 +3389,134 @@ def sample_generate_access_token(): # Done; return the response. return response + def push_credentials( + self, + request: Optional[Union[workstations.PushCredentialsRequest, dict]] = None, + *, + workstation: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Pushes credentials to a running workstation on behalf of a user. + Once complete, supported credential types + (application_default_credentials) are made available to + processes running in the user container. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import workstations_v1beta + + def sample_push_credentials(): + # Create a client + client = workstations_v1beta.WorkstationsClient() + + # Initialize request argument(s) + request = workstations_v1beta.PushCredentialsRequest( + workstation="workstation_value", + ) + + # Make the request + operation = client.push_credentials(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.workstations_v1beta.types.PushCredentialsRequest, dict]): + The request object. Request message for PushCredentials. + workstation (str): + Required. Name of the workstation for + which the credentials should be pushed. + + This corresponds to the ``workstation`` 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.workstations_v1beta.types.Workstation` + A single instance of a developer workstation with its + own persistent storage. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [workstation] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, workstations.PushCredentialsRequest): + request = workstations.PushCredentialsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if workstation is not None: + request.workstation = workstation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.push_credentials] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("workstation", request.workstation),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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, + workstations.Workstation, + metadata_type=workstations.PushCredentialsMetadata, + ) + + # Done; return the response. + return response + def __enter__(self) -> "WorkstationsClient": return self diff --git a/packages/google-cloud-workstations/google/cloud/workstations_v1beta/services/workstations/transports/base.py b/packages/google-cloud-workstations/google/cloud/workstations_v1beta/services/workstations/transports/base.py index 07fc1cb5cccb..65bf9beb00c7 100644 --- a/packages/google-cloud-workstations/google/cloud/workstations_v1beta/services/workstations/transports/base.py +++ b/packages/google-cloud-workstations/google/cloud/workstations_v1beta/services/workstations/transports/base.py @@ -329,6 +329,11 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), + self.push_credentials: gapic_v1.method.wrap_method( + self.push_credentials, + default_timeout=None, + client_info=client_info, + ), self.get_iam_policy: gapic_v1.method.wrap_method( self.get_iam_policy, default_timeout=None, @@ -582,6 +587,15 @@ def generate_access_token( ]: raise NotImplementedError() + @property + def push_credentials( + self, + ) -> Callable[ + [workstations.PushCredentialsRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + @property def list_operations( self, diff --git a/packages/google-cloud-workstations/google/cloud/workstations_v1beta/services/workstations/transports/grpc.py b/packages/google-cloud-workstations/google/cloud/workstations_v1beta/services/workstations/transports/grpc.py index 6f9ae8d92ae6..43ef131b8549 100644 --- a/packages/google-cloud-workstations/google/cloud/workstations_v1beta/services/workstations/transports/grpc.py +++ b/packages/google-cloud-workstations/google/cloud/workstations_v1beta/services/workstations/transports/grpc.py @@ -900,7 +900,8 @@ def generate_access_token( Returns a short-lived credential that can be used to send authenticated and authorized traffic to a - workstation. + workstation. Once generated this token cannot be revoked + and is good for the lifetime of the token. Returns: Callable[[~.GenerateAccessTokenRequest], @@ -920,6 +921,35 @@ def generate_access_token( ) return self._stubs["generate_access_token"] + @property + def push_credentials( + self, + ) -> Callable[[workstations.PushCredentialsRequest], operations_pb2.Operation]: + r"""Return a callable for the push credentials method over gRPC. + + Pushes credentials to a running workstation on behalf of a user. + Once complete, supported credential types + (application_default_credentials) are made available to + processes running in the user container. + + Returns: + Callable[[~.PushCredentialsRequest], + ~.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 "push_credentials" not in self._stubs: + self._stubs["push_credentials"] = self._logged_channel.unary_unary( + "/google.cloud.workstations.v1beta.Workstations/PushCredentials", + request_serializer=workstations.PushCredentialsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["push_credentials"] + def close(self): self._logged_channel.close() diff --git a/packages/google-cloud-workstations/google/cloud/workstations_v1beta/services/workstations/transports/grpc_asyncio.py b/packages/google-cloud-workstations/google/cloud/workstations_v1beta/services/workstations/transports/grpc_asyncio.py index 7eedf7168ed1..9547c1a026d3 100644 --- a/packages/google-cloud-workstations/google/cloud/workstations_v1beta/services/workstations/transports/grpc_asyncio.py +++ b/packages/google-cloud-workstations/google/cloud/workstations_v1beta/services/workstations/transports/grpc_asyncio.py @@ -929,7 +929,8 @@ def generate_access_token( Returns a short-lived credential that can be used to send authenticated and authorized traffic to a - workstation. + workstation. Once generated this token cannot be revoked + and is good for the lifetime of the token. Returns: Callable[[~.GenerateAccessTokenRequest], @@ -949,6 +950,37 @@ def generate_access_token( ) return self._stubs["generate_access_token"] + @property + def push_credentials( + self, + ) -> Callable[ + [workstations.PushCredentialsRequest], Awaitable[operations_pb2.Operation] + ]: + r"""Return a callable for the push credentials method over gRPC. + + Pushes credentials to a running workstation on behalf of a user. + Once complete, supported credential types + (application_default_credentials) are made available to + processes running in the user container. + + Returns: + Callable[[~.PushCredentialsRequest], + 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 "push_credentials" not in self._stubs: + self._stubs["push_credentials"] = self._logged_channel.unary_unary( + "/google.cloud.workstations.v1beta.Workstations/PushCredentials", + request_serializer=workstations.PushCredentialsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["push_credentials"] + def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { @@ -1133,6 +1165,11 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), + self.push_credentials: self._wrap_method( + self.push_credentials, + default_timeout=None, + client_info=client_info, + ), self.get_iam_policy: self._wrap_method( self.get_iam_policy, default_timeout=None, diff --git a/packages/google-cloud-workstations/google/cloud/workstations_v1beta/services/workstations/transports/rest.py b/packages/google-cloud-workstations/google/cloud/workstations_v1beta/services/workstations/transports/rest.py index 4483c48249a7..956c7fe4e514 100644 --- a/packages/google-cloud-workstations/google/cloud/workstations_v1beta/services/workstations/transports/rest.py +++ b/packages/google-cloud-workstations/google/cloud/workstations_v1beta/services/workstations/transports/rest.py @@ -198,6 +198,14 @@ def post_list_workstations(self, response): logging.log(f"Received response: {response}") return response + def pre_push_credentials(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_push_credentials(self, response): + logging.log(f"Received response: {response}") + return response + def pre_start_workstation(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -993,6 +1001,54 @@ def post_list_workstations_with_metadata( """ return response, metadata + def pre_push_credentials( + self, + request: workstations.PushCredentialsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + workstations.PushCredentialsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for push_credentials + + Override in a subclass to manipulate the request or metadata + before they are sent to the Workstations server. + """ + return request, metadata + + def post_push_credentials( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for push_credentials + + DEPRECATED. Please use the `post_push_credentials_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the Workstations server but before + it is returned to user code. This `post_push_credentials` interceptor runs + before the `post_push_credentials_with_metadata` interceptor. + """ + return response + + def post_push_credentials_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for push_credentials + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Workstations server but before it is returned to user code. + + We recommend only using this `post_push_credentials_with_metadata` + interceptor in new development instead of the `post_push_credentials` interceptor. + When both interceptors are used, this `post_push_credentials_with_metadata` interceptor runs after the + `post_push_credentials` interceptor. The (possibly modified) response returned by + `post_push_credentials` will be passed to + `post_push_credentials_with_metadata`. + """ + return response, metadata + def pre_start_workstation( self, request: workstations.StartWorkstationRequest, @@ -3820,6 +3876,159 @@ def __call__( ) return resp + class _PushCredentials( + _BaseWorkstationsRestTransport._BasePushCredentials, WorkstationsRestStub + ): + def __hash__(self): + return hash("WorkstationsRestTransport.PushCredentials") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: workstations.PushCredentialsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the push credentials method over HTTP. + + Args: + request (~.workstations.PushCredentialsRequest): + The request object. Request message for PushCredentials. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = ( + _BaseWorkstationsRestTransport._BasePushCredentials._get_http_options() + ) + + request, metadata = self._interceptor.pre_push_credentials( + request, metadata + ) + transcoded_request = _BaseWorkstationsRestTransport._BasePushCredentials._get_transcoded_request( + http_options, request + ) + + body = _BaseWorkstationsRestTransport._BasePushCredentials._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseWorkstationsRestTransport._BasePushCredentials._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.workstations_v1beta.WorkstationsClient.PushCredentials", + extra={ + "serviceName": "google.cloud.workstations.v1beta.Workstations", + "rpcName": "PushCredentials", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = WorkstationsRestTransport._PushCredentials._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_push_credentials(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_push_credentials_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.workstations_v1beta.WorkstationsClient.push_credentials", + extra={ + "serviceName": "google.cloud.workstations.v1beta.Workstations", + "rpcName": "PushCredentials", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + class _StartWorkstation( _BaseWorkstationsRestTransport._BaseStartWorkstation, WorkstationsRestStub ): @@ -4752,6 +4961,14 @@ def list_workstations( # In C++ this would require a dynamic_cast return self._ListWorkstations(self._session, self._host, self._interceptor) # type: ignore + @property + def push_credentials( + self, + ) -> Callable[[workstations.PushCredentialsRequest], operations_pb2.Operation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._PushCredentials(self._session, self._host, self._interceptor) # type: ignore + @property def start_workstation( self, diff --git a/packages/google-cloud-workstations/google/cloud/workstations_v1beta/services/workstations/transports/rest_base.py b/packages/google-cloud-workstations/google/cloud/workstations_v1beta/services/workstations/transports/rest_base.py index 1e7a1ee489de..a08657a0771d 100644 --- a/packages/google-cloud-workstations/google/cloud/workstations_v1beta/services/workstations/transports/rest_base.py +++ b/packages/google-cloud-workstations/google/cloud/workstations_v1beta/services/workstations/transports/rest_base.py @@ -844,6 +844,63 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params + class _BasePushCredentials: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1beta/{workstation=projects/*/locations/*/workstationClusters/*/workstationConfigs/*/workstations/*}:pushCredentials", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = workstations.PushCredentialsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseWorkstationsRestTransport._BasePushCredentials._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + class _BaseStartWorkstation: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") diff --git a/packages/google-cloud-workstations/google/cloud/workstations_v1beta/types/__init__.py b/packages/google-cloud-workstations/google/cloud/workstations_v1beta/types/__init__.py index bcd583094bb2..b8a909b3eec0 100644 --- a/packages/google-cloud-workstations/google/cloud/workstations_v1beta/types/__init__.py +++ b/packages/google-cloud-workstations/google/cloud/workstations_v1beta/types/__init__.py @@ -36,6 +36,8 @@ ListWorkstationsRequest, ListWorkstationsResponse, OperationMetadata, + PushCredentialsMetadata, + PushCredentialsRequest, StartWorkstationRequest, StopWorkstationRequest, UpdateWorkstationClusterRequest, @@ -69,6 +71,8 @@ "ListWorkstationsRequest", "ListWorkstationsResponse", "OperationMetadata", + "PushCredentialsMetadata", + "PushCredentialsRequest", "StartWorkstationRequest", "StopWorkstationRequest", "UpdateWorkstationClusterRequest", diff --git a/packages/google-cloud-workstations/google/cloud/workstations_v1beta/types/workstations.py b/packages/google-cloud-workstations/google/cloud/workstations_v1beta/types/workstations.py index 5873eb7bffce..c901224d4c35 100644 --- a/packages/google-cloud-workstations/google/cloud/workstations_v1beta/types/workstations.py +++ b/packages/google-cloud-workstations/google/cloud/workstations_v1beta/types/workstations.py @@ -55,6 +55,8 @@ "StopWorkstationRequest", "GenerateAccessTokenRequest", "GenerateAccessTokenResponse", + "PushCredentialsRequest", + "PushCredentialsMetadata", "OperationMetadata", }, ) @@ -68,7 +70,8 @@ class WorkstationCluster(proto.Message): Attributes: name (str): - Full name of this workstation cluster. + Identifier. Full name of this workstation + cluster. display_name (str): Optional. Human-readable name for this workstation cluster. @@ -120,14 +123,54 @@ class WorkstationCluster(proto.Message): private_cluster_config (google.cloud.workstations_v1beta.types.WorkstationCluster.PrivateClusterConfig): Optional. Configuration for private workstation cluster. + domain_config (google.cloud.workstations_v1beta.types.WorkstationCluster.DomainConfig): + Optional. Configuration options for a custom + domain. degraded (bool): Output only. Whether this workstation cluster is in degraded mode, in which case it may require user action to restore - full functionality. Details can be found in - [conditions][google.cloud.workstations.v1beta.WorkstationCluster.conditions]. + full functionality. The + [conditions][google.cloud.workstations.v1beta.WorkstationCluster.conditions] + field contains detailed information about the status of the + cluster. conditions (MutableSequence[google.rpc.status_pb2.Status]): Output only. Status conditions describing the workstation cluster's current state. + satisfies_pzs (bool): + Output only. Reserved for future use. + satisfies_pzi (bool): + Output only. Reserved for future use. + tags (MutableMapping[str, str]): + Optional. Input only. Immutable. Tag + keys/values directly bound to this resource. For + example: + + "123/environment": "production", + "123/costCenter": "marketing". + gateway_config (google.cloud.workstations_v1beta.types.WorkstationCluster.GatewayConfig): + Optional. Configuration options for Cluster + HTTP Gateway. + workstation_authorization_url (str): + Optional. Specifies the redirect URL for unauthorized + requests received by workstation VMs in this cluster. + + Redirects to this endpoint will send a base64 encoded + ``state`` query param containing the target workstation name + and original request hostname. The endpoint is responsible + for retrieving a token using ``GenerateAccessToken`` and + redirecting back to the original hostname with the token. + workstation_launch_url (str): + Optional. Specifies the launch URL for workstations in this + cluster. Requests sent to unstarted workstations will be + redirected to this URL. + + Requests redirected to the launch endpoint will be sent with + a ``workstation`` and ``project`` query parameter containing + the full workstation resource name and project ID, + respectively. The launch endpoint is responsible for + starting the workstation, polling it until it reaches + ``STATE_RUNNING``, and then issuing a redirect to the + workstation's host URL. """ class PrivateClusterConfig(proto.Message): @@ -147,7 +190,7 @@ class PrivateClusterConfig(proto.Message): mapping that address to the service attachment. service_attachment_uri (str): Output only. Service attachment URI for the workstation - cluster. The service attachemnt is created when private + cluster. The service attachment is created when private endpoint is enabled. To access workstations in the workstation cluster, configure access to the managed service using `Private Service @@ -177,6 +220,34 @@ class PrivateClusterConfig(proto.Message): number=4, ) + class DomainConfig(proto.Message): + r"""Configuration options for a custom domain. + + Attributes: + domain (str): + Immutable. Domain used by Workstations for + HTTP ingress. + """ + + domain: str = proto.Field( + proto.STRING, + number=1, + ) + + class GatewayConfig(proto.Message): + r"""Configuration options for Cluster HTTP Gateway. + + Attributes: + http2_enabled (bool): + Optional. Whether HTTP/2 is enabled for this + workstation cluster. Defaults to false. + """ + + http2_enabled: bool = proto.Field( + proto.BOOL, + number=1, + ) + name: str = proto.Field( proto.STRING, number=1, @@ -239,6 +310,11 @@ class PrivateClusterConfig(proto.Message): number=12, message=PrivateClusterConfig, ) + domain_config: DomainConfig = proto.Field( + proto.MESSAGE, + number=17, + message=DomainConfig, + ) degraded: bool = proto.Field( proto.BOOL, number=13, @@ -248,6 +324,32 @@ class PrivateClusterConfig(proto.Message): number=14, message=status_pb2.Status, ) + satisfies_pzs: bool = proto.Field( + proto.BOOL, + number=18, + ) + satisfies_pzi: bool = proto.Field( + proto.BOOL, + number=19, + ) + tags: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=20, + ) + gateway_config: GatewayConfig = proto.Field( + proto.MESSAGE, + number=21, + message=GatewayConfig, + ) + workstation_authorization_url: str = proto.Field( + proto.STRING, + number=22, + ) + workstation_launch_url: str = proto.Field( + proto.STRING, + number=23, + ) class WorkstationConfig(proto.Message): @@ -264,7 +366,8 @@ class WorkstationConfig(proto.Message): Attributes: name (str): - Full name of this workstation configuration. + Identifier. Full name of this workstation + configuration. display_name (str): Optional. Human-readable name for this workstation configuration. @@ -332,6 +435,23 @@ class WorkstationConfig(proto.Message): Workstations VMs created with this configuration have no maximum running time. This is strongly discouraged because you incur costs and will not pick up security updates. + max_usable_workstations (int): + Optional. Maximum number of workstations under this + configuration a user can have + ``workstations.workstation.use`` permission on. + + Only enforced on CreateWorkstation API calls on the user + issuing the API request. Can be overridden by: + + - granting a user + workstations.workstationConfigs.exemptMaxUsableWorkstationLimit + permission, or + - having a user with that permission create a workstation + and granting another user ``workstations.workstation.use`` + permission on that workstation. + + If not specified, defaults to ``0``, which indicates + unlimited. host (google.cloud.workstations_v1beta.types.WorkstationConfig.Host): Optional. Runtime host for the workstation. persistent_directories (MutableSequence[google.cloud.workstations_v1beta.types.WorkstationConfig.PersistentDirectory]): @@ -386,21 +506,73 @@ class WorkstationConfig(proto.Message): Immutable after the workstation configuration is created. degraded (bool): - Output only. Whether this resource is degraded, in which - case it may require user action to restore full - functionality. See also the + Output only. Whether this workstation configuration is in + degraded mode, in which case it may require user action to + restore full functionality. The [conditions][google.cloud.workstations.v1beta.WorkstationConfig.conditions] - field. + field contains detailed information about the status of the + configuration. conditions (MutableSequence[google.rpc.status_pb2.Status]): Output only. Status conditions describing the - current resource state. + workstation configuration's current state. enable_audit_agent (bool): Optional. Whether to enable Linux ``auditd`` logging on the - workstation. When enabled, a service account must also be - specified that has ``logging.buckets.write`` permission on - the project. Operating system audit logging is distinct from - `Cloud Audit - Logs `__. + workstation. When enabled, a + [service_account][google.cloud.workstations.v1beta.WorkstationConfig.Host.GceInstance.service_account] + must also be specified that has ``roles/logging.logWriter`` + and ``roles/monitoring.metricWriter`` on the project. + Operating system audit logging is distinct from `Cloud Audit + Logs `__ + and `Container output + logging `__. + Operating system audit logs are available in the `Cloud + Logging `__ console + by querying: + + :: + + resource.type="gce_instance" + log_name:"/logs/linux-auditd". + http_options (google.cloud.workstations_v1beta.types.WorkstationConfig.HttpOptions): + Optional. HTTP options that customize the + behavior of the workstation service's HTTP + proxy. + disable_tcp_connections (bool): + Optional. Disables support for plain TCP + connections in the workstation. By default the + service supports TCP connections through a + websocket relay. Setting this option to true + disables that relay, which prevents the usage of + services that require plain TCP connections, + such as SSH. When enabled, all communication + must occur over HTTPS or WSS. + allowed_ports (MutableSequence[google.cloud.workstations_v1beta.types.WorkstationConfig.PortRange]): + Optional. A list of + [PortRange][google.cloud.workstations.v1beta.WorkstationConfig.PortRange]s + specifying single ports or ranges of ports that are + externally accessible in the workstation. Allowed ports must + be one of 22, 80, or within range 1024-65535. If not + specified defaults to ports 22, 80, and ports 1024-65535. + satisfies_pzs (bool): + Output only. Reserved for future use. + satisfies_pzi (bool): + Output only. Reserved for future use. + grant_workstation_admin_role_on_create (bool): + Optional. Grant creator of a workstation + ``roles/workstations.policyAdmin`` role along with + ``roles/workstations.user`` role on the workstation created + by them. This allows workstation users to share access to + either their entire workstation, or individual ports. + Defaults to false. + enable_pushing_credentials (bool): + Optional. Enables pushing user provided credentials to + Workstations by calling workstations.pushCredentials. If + application_default_credentials are supplied to + pushCredentials, the provided token is returned when tools + and applications running in the user container make a + request for Default Application Credentials. Please note + that any credentials supplied are made available to all + users with access to the workstation. """ class Host(proto.Message): @@ -430,10 +602,13 @@ class GceInstance(proto.Message): Optional. The email address of the service account for Cloud Workstations VMs created with this configuration. When specified, be sure that the service account has - ``logginglogEntries.create`` permission on the project so it - can write logs out to Cloud Logging. If using a custom - container image, the service account must have permissions - to pull the specified image. + ``logging.logEntries.create`` and + ``monitoring.timeSeries.create`` permissions on the project + so it can write logs out to Cloud Logging. If using a custom + container image, the service account must have `Artifact + Registry + Reader `__ + permission to pull the specified image. If you as the administrator want to be able to ``ssh`` into the underlying VM, you need to set this value to a service @@ -448,8 +623,7 @@ class GceInstance(proto.Message): service_account_scopes (MutableSequence[str]): Optional. Scopes to grant to the [service_account][google.cloud.workstations.v1beta.WorkstationConfig.Host.GceInstance.service_account]. - Various scopes are automatically added based on feature - usage. When specified, users of workstations under this + When specified, users of workstations under this configuration must have ``iam.serviceAccounts.actAs`` on the service account. tags (MutableSequence[str]): @@ -479,9 +653,11 @@ class GceInstance(proto.Message): addresses). enable_nested_virtualization (bool): Optional. Whether to enable nested virtualization on Cloud - Workstations VMs created under this workstation + Workstations VMs created using this workstation configuration. + Defaults to false. + Nested virtualization lets you run virtual machine (VM) instances inside your workstation. Before enabling nested virtualization, consider the following important @@ -504,15 +680,6 @@ class GceInstance(proto.Message): enabled on workstation configurations that specify a [machine_type][google.cloud.workstations.v1beta.WorkstationConfig.Host.GceInstance.machine_type] in the N1 or N2 machine series. - - **GPUs**: nested virtualization may not be enabled on - workstation configurations with accelerators. - - **Operating System**: Because `Container-Optimized - OS `__ - does not support nested virtualization, when nested - virtualization is enabled, the underlying Compute Engine - VM instances boot from an `Ubuntu - LTS `__ - image. shielded_instance_config (google.cloud.workstations_v1beta.types.WorkstationConfig.Host.GceInstance.GceShieldedInstanceConfig): Optional. A set of Compute Engine Shielded instance options. @@ -526,6 +693,58 @@ class GceInstance(proto.Message): accelerators (MutableSequence[google.cloud.workstations_v1beta.types.WorkstationConfig.Host.GceInstance.Accelerator]): Optional. A list of the type and count of accelerator cards attached to the instance. + boost_configs (MutableSequence[google.cloud.workstations_v1beta.types.WorkstationConfig.Host.GceInstance.BoostConfig]): + Optional. A list of the boost configurations + that workstations created using this workstation + configuration are allowed to use. If specified, + users will have the option to choose from the + list of boost configs when starting a + workstation. + disable_ssh (bool): + Optional. Whether to disable SSH access to + the VM. + vm_tags (MutableMapping[str, str]): + Optional. Resource manager tags to be bound to this + instance. Tag keys and values have the same definition as + `resource manager + tags `__. + Keys must be in the format ``tagKeys/{tag_key_id}``, and + values are in the format ``tagValues/456``. + reservation_affinity (google.cloud.workstations_v1beta.types.WorkstationConfig.Host.GceInstance.ReservationAffinity): + Optional. + `ReservationAffinity `__ + specifies a reservation that can be consumed to create VM + instances. If SPECIFIC_RESERVATION is specified, Cloud + Workstations will only create VMs in the zone where the + reservation is located. This would affect availability since + the service will no longer be resilient to zonal outages. If + ANY_RESERVATION is specified, creating reservations in both + zones that the config creates VMs in will ensure higher + availability. **Important Considerations for Reservation + Affinity:** + + - This feature is intended for advanced users and requires + familiarity with Google Compute Engine reservations. + - Using reservations incurs charges, regardless of + utilization. + - The resources in the pool will consume the specified + reservation. Take this into account when setting the pool + size. + startup_script_uri (str): + Optional. Link to the startup script stored in Cloud + Storage. This script will be run on the host workstation VM + when the VM is created. The URI must be of the form + gs://{bucket-name}/{object-name}. If specifying a startup + script, the service account must have `Permission to access + the bucket and script file in Cloud + Storage `__. + Otherwise, the script must be publicly accessible. Note that + the service regularly updates the OS version of the host VM, + and it is the responsibility of the user to ensure the + script stays compatible with the OS version. + instance_metadata (MutableMapping[str, str]): + Optional. Custom metadata to apply to Compute + Engine instances. """ class GceShieldedInstanceConfig(proto.Message): @@ -591,6 +810,178 @@ class Accelerator(proto.Message): number=2, ) + class BoostConfig(proto.Message): + r"""A boost configuration is a set of resources that a + workstation can use to increase its performance. If you specify + a boost configuration, upon startup, workstation users can + choose to use a VM provisioned under the boost config by passing + the boost config ID in the start request. If the workstation + user does not provide a boost config ID in the start request, + the system will choose a VM from the pool provisioned under the + default config. + + Attributes: + id (str): + Required. The ID to be used for the boost + configuration. + machine_type (str): + Optional. The type of machine that boosted VM instances will + use—for example, ``e2-standard-4``. For more information + about machine types that Cloud Workstations supports, see + the list of `available machine + types `__. + Defaults to ``e2-standard-4``. + accelerators (MutableSequence[google.cloud.workstations_v1beta.types.WorkstationConfig.Host.GceInstance.Accelerator]): + Optional. A list of the type and count of accelerator cards + attached to the boost instance. Defaults to ``none``. + boot_disk_size_gb (int): + Optional. The size of the boot disk for the VM in gigabytes + (GB). The minimum boot disk size is ``30`` GB. Defaults to + ``50`` GB. + enable_nested_virtualization (bool): + Optional. Whether to enable nested virtualization on boosted + Cloud Workstations VMs running using this boost + configuration. + + Defaults to false. + + Nested virtualization lets you run virtual machine (VM) + instances inside your workstation. Before enabling nested + virtualization, consider the following important + considerations. Cloud Workstations instances are subject to + the `same restrictions as Compute Engine + instances `__: + + - **Organization policy**: projects, folders, or + organizations may be restricted from creating nested VMs + if the **Disable VM nested virtualization** constraint is + enforced in the organization policy. For more information, + see the Compute Engine section, `Checking whether nested + virtualization is + allowed `__. + - **Performance**: nested VMs might experience a 10% or + greater decrease in performance for workloads that are + CPU-bound and possibly greater than a 10% decrease for + workloads that are input/output bound. + - **Machine Type**: nested virtualization can only be + enabled on boost configurations that specify a + [machine_type][google.cloud.workstations.v1beta.WorkstationConfig.Host.GceInstance.BoostConfig.machine_type] + in the N1 or N2 machine series. + pool_size (int): + Optional. The number of boost VMs that the system should + keep idle so that workstations can be boosted quickly. + Defaults to ``0``. + reservation_affinity (google.cloud.workstations_v1beta.types.WorkstationConfig.Host.GceInstance.ReservationAffinity): + Optional. + `ReservationAffinity `__ + specifies a reservation that can be consumed to create boost + VM instances. If SPECIFIC_RESERVATION is specified, Cloud + Workstations will only create VMs in the zone where the + reservation is located. This would affect availability since + the service will no longer be resilient to zonal outages. If + ANY_RESERVATION is specified, creating reservations in both + zones that the config creates VMs in will ensure higher + availability. **Important Considerations for Reservation + Affinity:** + + - This feature is intended for advanced users and requires + familiarity with Google Compute Engine reservations. + - Using reservations incurs charges, regardless of + utilization. + - The resources in the pool will consume the specified + reservation. Take this into account when setting the pool + size. + """ + + id: str = proto.Field( + proto.STRING, + number=1, + ) + machine_type: str = proto.Field( + proto.STRING, + number=2, + ) + accelerators: MutableSequence[ + "WorkstationConfig.Host.GceInstance.Accelerator" + ] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message="WorkstationConfig.Host.GceInstance.Accelerator", + ) + boot_disk_size_gb: int = proto.Field( + proto.INT32, + number=4, + ) + enable_nested_virtualization: bool = proto.Field( + proto.BOOL, + number=7, + ) + pool_size: int = proto.Field( + proto.INT32, + number=5, + ) + reservation_affinity: "WorkstationConfig.Host.GceInstance.ReservationAffinity" = proto.Field( + proto.MESSAGE, + number=6, + message="WorkstationConfig.Host.GceInstance.ReservationAffinity", + ) + + class ReservationAffinity(proto.Message): + r"""ReservationAffinity is the configuration of the desired + reservation from which instances can consume resources. + + Attributes: + consume_reservation_type (google.cloud.workstations_v1beta.types.WorkstationConfig.Host.GceInstance.ReservationAffinity.Type): + Optional. Corresponds to the type of + reservation consumption. + key (str): + Optional. Corresponds to the label key of + reservation resource. + values (MutableSequence[str]): + Optional. Corresponds to the label values of + reservation resources. Valid values are either + the name of a reservation in the same project or + "projects/{project}/reservations/{reservation}" + to target a shared reservation in the same zone + but in a different project. + """ + + class Type(proto.Enum): + r"""Indicates whether to consume capacity from a reservation or + not. + + Values: + TYPE_UNSPECIFIED (0): + Default value. This should not be used. + NO_RESERVATION (1): + Do not consume from any reserved capacity. + ANY_RESERVATION (2): + Consume any reservation available. + SPECIFIC_RESERVATION (3): + Must consume from a specific reservation. + Must specify key value fields for specifying the + reservations. + """ + + TYPE_UNSPECIFIED = 0 + NO_RESERVATION = 1 + ANY_RESERVATION = 2 + SPECIFIC_RESERVATION = 3 + + consume_reservation_type: "WorkstationConfig.Host.GceInstance.ReservationAffinity.Type" = proto.Field( + proto.ENUM, + number=1, + enum="WorkstationConfig.Host.GceInstance.ReservationAffinity.Type", + ) + key: str = proto.Field( + proto.STRING, + number=2, + ) + values: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + machine_type: str = proto.Field( proto.STRING, number=1, @@ -644,6 +1035,36 @@ class Accelerator(proto.Message): number=11, message="WorkstationConfig.Host.GceInstance.Accelerator", ) + boost_configs: MutableSequence[ + "WorkstationConfig.Host.GceInstance.BoostConfig" + ] = proto.RepeatedField( + proto.MESSAGE, + number=25, + message="WorkstationConfig.Host.GceInstance.BoostConfig", + ) + disable_ssh: bool = proto.Field( + proto.BOOL, + number=13, + ) + vm_tags: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=14, + ) + reservation_affinity: "WorkstationConfig.Host.GceInstance.ReservationAffinity" = proto.Field( + proto.MESSAGE, + number=15, + message="WorkstationConfig.Host.GceInstance.ReservationAffinity", + ) + startup_script_uri: str = proto.Field( + proto.STRING, + number=26, + ) + instance_metadata: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=27, + ) gce_instance: "WorkstationConfig.Host.GceInstance" = proto.Field( proto.MESSAGE, @@ -653,7 +1074,14 @@ class Accelerator(proto.Message): ) class PersistentDirectory(proto.Message): - r"""A directory to persist across workstation sessions. + r"""A directory to persist across workstation sessions. Updates + to this field will not update existing workstations and will + only take effect on new workstations. + + 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 @@ -662,6 +1090,11 @@ class PersistentDirectory(proto.Message): A PersistentDirectory backed by a Compute Engine persistent disk. + This field is a member of `oneof`_ ``directory_type``. + gce_hd (google.cloud.workstations_v1beta.types.WorkstationConfig.PersistentDirectory.GceHyperdiskBalancedHighAvailability): + A PersistentDirectory backed by a Compute + Engine hyperdisk high availability disk. + This field is a member of `oneof`_ ``directory_type``. mount_path (str): Optional. Location of this directory in the @@ -669,8 +1102,8 @@ class PersistentDirectory(proto.Message): """ class GceRegionalPersistentDisk(proto.Message): - r"""A PersistentDirectory backed by a Compute Engine regional persistent - disk. The + r"""A Persistent Directory backed by a Compute Engine regional + persistent disk. The [persistent_directories][google.cloud.workstations.v1beta.WorkstationConfig.persistent_directories] field is repeated, but it may contain only one entry. It creates a `persistent @@ -693,6 +1126,10 @@ class GceRegionalPersistentDisk(proto.Message): the [disk_type][google.cloud.workstations.v1beta.WorkstationConfig.PersistentDirectory.GceRegionalPersistentDisk.disk_type] must be ``"pd-balanced"`` or ``"pd-ssd"``. + max_size_gb (int): + Optional. Maximum size in GB to which this + persistent directory can be resized. Defaults to + unlimited if not set. fs_type (str): Optional. Type of file system that the disk should be formatted with. The workstation image must support this file @@ -709,11 +1146,22 @@ class GceRegionalPersistentDisk(proto.Message): [size_gb][google.cloud.workstations.v1beta.WorkstationConfig.PersistentDirectory.GceRegionalPersistentDisk.size_gb] and [fs_type][google.cloud.workstations.v1beta.WorkstationConfig.PersistentDirectory.GceRegionalPersistentDisk.fs_type] - must be empty. + must be empty. Must be formatted as ext4 file system with no + partitions. reclaim_policy (google.cloud.workstations_v1beta.types.WorkstationConfig.PersistentDirectory.GceRegionalPersistentDisk.ReclaimPolicy): Optional. Whether the persistent disk should be deleted when the workstation is deleted. Valid values are ``DELETE`` and ``RETAIN``. Defaults to ``DELETE``. + archive_timeout (google.protobuf.duration_pb2.Duration): + Optional. Number of seconds to wait after initially creating + or subsequently shutting down the workstation before + converting its disk into a snapshot. This generally saves + costs at the expense of greater startup time on next + workstation start, as the service will need to create a disk + from the archival snapshot. + + A value of ``"0s"`` indicates that the disk will never be + archived. """ class ReclaimPolicy(proto.Enum): @@ -740,6 +1188,10 @@ class ReclaimPolicy(proto.Enum): proto.INT32, number=1, ) + max_size_gb: int = proto.Field( + proto.INT32, + number=7, + ) fs_type: str = proto.Field( proto.STRING, number=2, @@ -757,6 +1209,98 @@ class ReclaimPolicy(proto.Enum): number=4, enum="WorkstationConfig.PersistentDirectory.GceRegionalPersistentDisk.ReclaimPolicy", ) + archive_timeout: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=6, + message=duration_pb2.Duration, + ) + + class GceHyperdiskBalancedHighAvailability(proto.Message): + r"""A Persistent Directory backed by a Compute Engine `Hyperdisk + Balanced High Availability + Disk `__. + This is a high-availability block storage solution that offers a + balance between performance and cost for most general-purpose + workloads. + + Attributes: + size_gb (int): + Optional. The GB capacity of a persistent home directory for + each workstation created with this configuration. Must be + empty if + [source_snapshot][google.cloud.workstations.v1beta.WorkstationConfig.PersistentDirectory.GceHyperdiskBalancedHighAvailability.source_snapshot] + is set. + + Valid values are ``10``, ``50``, ``100``, ``200``, ``500``, + or ``1000``. Defaults to ``200``. + max_size_gb (int): + Optional. Maximum size in GB to which this + persistent directory can be resized. Defaults to + unlimited if not set. + source_snapshot (str): + Optional. Name of the snapshot to use as the source for the + disk. If set, + [size_gb][google.cloud.workstations.v1beta.WorkstationConfig.PersistentDirectory.GceHyperdiskBalancedHighAvailability.size_gb] + must be empty. Must be formatted as ext4 file system with no + partitions. + reclaim_policy (google.cloud.workstations_v1beta.types.WorkstationConfig.PersistentDirectory.GceHyperdiskBalancedHighAvailability.ReclaimPolicy): + Optional. Whether the persistent disk should be deleted when + the workstation is deleted. Valid values are ``DELETE`` and + ``RETAIN``. Defaults to ``DELETE``. + archive_timeout (google.protobuf.duration_pb2.Duration): + Optional. Number of seconds to wait after initially creating + or subsequently shutting down the workstation before + converting its disk into a snapshot. This generally saves + costs at the expense of greater startup time on next + workstation start, as the service will need to create a disk + from the archival snapshot. + + A value of ``"0s"`` indicates that the disk will never be + archived. + """ + + class ReclaimPolicy(proto.Enum): + r"""Value representing what should happen to the disk after the + workstation is deleted. + + Values: + RECLAIM_POLICY_UNSPECIFIED (0): + Do not use. + DELETE (1): + Delete the persistent disk when deleting the + workstation. + RETAIN (2): + Keep the persistent disk when deleting the + workstation. An administrator must manually + delete the disk. + """ + + RECLAIM_POLICY_UNSPECIFIED = 0 + DELETE = 1 + RETAIN = 2 + + size_gb: int = proto.Field( + proto.INT32, + number=1, + ) + max_size_gb: int = proto.Field( + proto.INT32, + number=5, + ) + source_snapshot: str = proto.Field( + proto.STRING, + number=2, + ) + reclaim_policy: "WorkstationConfig.PersistentDirectory.GceHyperdiskBalancedHighAvailability.ReclaimPolicy" = proto.Field( + proto.ENUM, + number=3, + enum="WorkstationConfig.PersistentDirectory.GceHyperdiskBalancedHighAvailability.ReclaimPolicy", + ) + archive_timeout: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=4, + message=duration_pb2.Duration, + ) gce_pd: "WorkstationConfig.PersistentDirectory.GceRegionalPersistentDisk" = proto.Field( proto.MESSAGE, @@ -764,6 +1308,12 @@ class ReclaimPolicy(proto.Enum): oneof="directory_type", message="WorkstationConfig.PersistentDirectory.GceRegionalPersistentDisk", ) + gce_hd: "WorkstationConfig.PersistentDirectory.GceHyperdiskBalancedHighAvailability" = proto.Field( + proto.MESSAGE, + number=3, + oneof="directory_type", + message="WorkstationConfig.PersistentDirectory.GceHyperdiskBalancedHighAvailability", + ) mount_path: str = proto.Field( proto.STRING, number=1, @@ -800,10 +1350,20 @@ class GcePersistentDisk(proto.Message): Optional. Name of the snapshot to use as the source for the disk. Must be empty if [source_image][google.cloud.workstations.v1beta.WorkstationConfig.EphemeralDirectory.GcePersistentDisk.source_image] - is set. Updating + is set. Must be empty if + [read_only][google.cloud.workstations.v1beta.WorkstationConfig.EphemeralDirectory.GcePersistentDisk.read_only] + is false. Updating [source_snapshot][google.cloud.workstations.v1beta.WorkstationConfig.EphemeralDirectory.GcePersistentDisk.source_snapshot] will update content in the ephemeral directory after the - workstation is restarted. This field is mutable. + workstation is restarted. + + Only file systems supported by Container-Optimized OS (COS) + are explicitly supported. For a list of supported file + systems, see `the filesystems available in + Container-Optimized + OS `__. + + This field is mutable. source_image (str): Optional. Name of the disk image to use as the source for the disk. Must be empty if @@ -811,7 +1371,14 @@ class GcePersistentDisk(proto.Message): is set. Updating [source_image][google.cloud.workstations.v1beta.WorkstationConfig.EphemeralDirectory.GcePersistentDisk.source_image] will update content in the ephemeral directory after the - workstation is restarted. This field is mutable. + workstation is restarted. + + Only file systems supported by Container-Optimized OS (COS) + are explicitly supported. For a list of supported file + systems, please refer to the `COS + documentation `__. + + This field is mutable. read_only (bool): Optional. Whether the disk is read only. If true, the disk may be shared by multiple VMs and @@ -861,9 +1428,12 @@ class Container(proto.Message): images `__. If using a private image, the ``host.gceInstance.serviceAccount`` field must be specified - in the workstation configuration and must have permission to - pull the specified image. Otherwise, the image must be - publicly accessible. + in the workstation configuration. If using a custom + container image, the service account must have `Artifact + Registry + Reader `__ + permission to pull the specified image. Otherwise, the image + must be publicly accessible. command (MutableSequence[str]): Optional. If set, overrides the default ENTRYPOINT specified by the image. @@ -961,6 +1531,73 @@ class ReadinessCheck(proto.Message): number=2, ) + class HttpOptions(proto.Message): + r"""HTTP options for the running workstations. + + Attributes: + allowed_unauthenticated_cors_preflight_requests (bool): + Optional. By default, the workstations + service makes sure that all requests to the + workstation are authenticated. CORS preflight + requests do not include cookies or custom + headers, and so are considered unauthenticated + and blocked by the workstations service. + Enabling this option allows these + unauthenticated CORS preflight requests through + to the workstation, where it becomes the + responsibility of the destination server in the + workstation to validate the request. + disable_localhost_replacement (bool): + Optional. By default, the workstations + service replaces references to localhost, + 127.0.0.1, and 0.0.0.0 with the workstation's + hostname in http responses from the workstation + so that applications under development run + properly on the workstation. This may intefere + with some applications, and so this option + allows that behavior to be disabled. + """ + + allowed_unauthenticated_cors_preflight_requests: bool = proto.Field( + proto.BOOL, + number=1, + ) + disable_localhost_replacement: bool = proto.Field( + proto.BOOL, + number=2, + ) + + class PortRange(proto.Message): + r"""A PortRange defines a range of ports. Both + [first][google.cloud.workstations.v1beta.WorkstationConfig.PortRange.first] + and + [last][google.cloud.workstations.v1beta.WorkstationConfig.PortRange.last] + are inclusive. To specify a single port, both + [first][google.cloud.workstations.v1beta.WorkstationConfig.PortRange.first] + and + [last][google.cloud.workstations.v1beta.WorkstationConfig.PortRange.last] + should be the same. + + Attributes: + first (int): + Required. Starting port number for the + current range of ports. Valid ports are 22, 80, + and ports within the range 1024-65535. + last (int): + Required. Ending port number for the current + range of ports. Valid ports are 22, 80, and + ports within the range 1024-65535. + """ + + first: int = proto.Field( + proto.INT32, + number=1, + ) + last: int = proto.Field( + proto.INT32, + number=2, + ) + name: str = proto.Field( proto.STRING, number=1, @@ -1016,6 +1653,10 @@ class ReadinessCheck(proto.Message): number=11, message=duration_pb2.Duration, ) + max_usable_workstations: int = proto.Field( + proto.INT32, + number=28, + ) host: Host = proto.Field( proto.MESSAGE, number=12, @@ -1063,6 +1704,36 @@ class ReadinessCheck(proto.Message): proto.BOOL, number=20, ) + http_options: HttpOptions = proto.Field( + proto.MESSAGE, + number=21, + message=HttpOptions, + ) + disable_tcp_connections: bool = proto.Field( + proto.BOOL, + number=24, + ) + allowed_ports: MutableSequence[PortRange] = proto.RepeatedField( + proto.MESSAGE, + number=25, + message=PortRange, + ) + satisfies_pzs: bool = proto.Field( + proto.BOOL, + number=26, + ) + satisfies_pzi: bool = proto.Field( + proto.BOOL, + number=27, + ) + grant_workstation_admin_role_on_create: bool = proto.Field( + proto.BOOL, + number=29, + ) + enable_pushing_credentials: bool = proto.Field( + proto.BOOL, + number=30, + ) class Workstation(proto.Message): @@ -1071,7 +1742,7 @@ class Workstation(proto.Message): Attributes: name (str): - Full name of this workstation. + Identifier. Full name of this workstation. display_name (str): Optional. Human-readable name for this workstation. @@ -1107,6 +1778,9 @@ class Workstation(proto.Message): May be sent on update and delete requests to make sure that the client has an up-to-date value before proceeding. + persistent_directories (MutableSequence[google.cloud.workstations_v1beta.types.Workstation.WorkstationPersistentDirectory]): + Optional. Directories to persist across + workstation sessions. state (google.cloud.workstations_v1beta.types.Workstation.State): Output only. Current state of the workstation. @@ -1120,6 +1794,36 @@ class Workstation(proto.Message): env (MutableMapping[str, str]): Optional. Environment variables passed to the workstation container's entrypoint. + kms_key (str): + Output only. The name of the Google Cloud KMS encryption key + used to encrypt this workstation. The KMS key can only be + configured in the WorkstationConfig. The expected format is + ``projects/*/locations/*/keyRings/*/cryptoKeys/*``. + boost_configs (MutableSequence[google.cloud.workstations_v1beta.types.Workstation.WorkstationBoostConfig]): + Output only. List of available boost + configuration IDs that this workstation can be + boosted up to. + source_workstation (str): + Optional. The source workstation from which + this workstation's persistent directories were + cloned on creation. + satisfies_pzs (bool): + Output only. Reserved for future use. + satisfies_pzi (bool): + Output only. Reserved for future use. + runtime_host (google.cloud.workstations_v1beta.types.Workstation.RuntimeHost): + Optional. Output only. Runtime host for the workstation when + in STATE_RUNNING. + degraded (bool): + Output only. Whether this workstation is in degraded mode, + in which case it may require user action to restore full + functionality. The + [conditions][google.cloud.workstations.v1beta.Workstation.conditions] + field contains detailed information about the status of the + workstation. + conditions (MutableSequence[google.rpc.status_pb2.Status]): + Output only. Status conditions describing the + workstation's current state. """ class State(proto.Enum): @@ -1148,6 +1852,99 @@ class State(proto.Enum): STATE_STOPPING = 3 STATE_STOPPED = 4 + class WorkstationPersistentDirectory(proto.Message): + r"""A directory to persist across workstation sessions. Updates + to this field will only take effect on this workstation after it + is restarted. + + Attributes: + mount_path (str): + Optional. The mount path of the persistent + directory. + size_gb (int): + Optional. Size of the persistent directory in + GB. If specified in an update request, this is + the desired size of the directory. + """ + + mount_path: str = proto.Field( + proto.STRING, + number=2, + ) + size_gb: int = proto.Field( + proto.INT32, + number=3, + ) + + class WorkstationBoostConfig(proto.Message): + r"""Boost configuration for this workstation. This object is + populated from the parent workstation configuration. + + Attributes: + id (str): + Output only. Boost configuration ID. + running (bool): + Output only. Whether or not the current + workstation is actively boosted with this id. + """ + + id: str = proto.Field( + proto.STRING, + number=1, + ) + running: bool = proto.Field( + proto.BOOL, + number=2, + ) + + class RuntimeHost(proto.Message): + r"""Runtime host for the workstation. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + gce_instance_host (google.cloud.workstations_v1beta.types.Workstation.RuntimeHost.GceInstanceHost): + Specifies a Compute Engine instance as the + host. + + This field is a member of `oneof`_ ``host_type``. + """ + + class GceInstanceHost(proto.Message): + r"""The Compute Engine instance host. + + Attributes: + name (str): + Optional. Output only. The name of the + Compute Engine instance. + id (str): + Optional. Output only. The ID of the Compute + Engine instance. + zone (str): + Optional. Output only. The zone of the + Compute Engine instance. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + id: str = proto.Field( + proto.STRING, + number=2, + ) + zone: str = proto.Field( + proto.STRING, + number=3, + ) + + gce_instance_host: "Workstation.RuntimeHost.GceInstanceHost" = proto.Field( + proto.MESSAGE, + number=1, + oneof="host_type", + message="Workstation.RuntimeHost.GceInstanceHost", + ) + name: str = proto.Field( proto.STRING, number=1, @@ -1198,6 +1995,13 @@ class State(proto.Enum): proto.STRING, number=9, ) + persistent_directories: MutableSequence[WorkstationPersistentDirectory] = ( + proto.RepeatedField( + proto.MESSAGE, + number=25, + message=WorkstationPersistentDirectory, + ) + ) state: State = proto.Field( proto.ENUM, number=10, @@ -1212,6 +2016,41 @@ class State(proto.Enum): proto.STRING, number=12, ) + kms_key: str = proto.Field( + proto.STRING, + number=15, + ) + boost_configs: MutableSequence[WorkstationBoostConfig] = proto.RepeatedField( + proto.MESSAGE, + number=16, + message=WorkstationBoostConfig, + ) + source_workstation: str = proto.Field( + proto.STRING, + number=17, + ) + satisfies_pzs: bool = proto.Field( + proto.BOOL, + number=18, + ) + satisfies_pzi: bool = proto.Field( + proto.BOOL, + number=19, + ) + runtime_host: RuntimeHost = proto.Field( + proto.MESSAGE, + number=21, + message=RuntimeHost, + ) + degraded: bool = proto.Field( + proto.BOOL, + number=23, + ) + conditions: MutableSequence[status_pb2.Status] = proto.RepeatedField( + proto.MESSAGE, + number=24, + message=status_pb2.Status, + ) class GetWorkstationClusterRequest(proto.Message): @@ -1239,6 +2078,10 @@ class ListWorkstationClustersRequest(proto.Message): page_token (str): Optional. next_page_token value returned from a previous List request, if any. + filter (str): + Optional. Filter the WorkstationClusters to + be listed. Possible filters are described in + https://google.aip.dev/160. """ parent: str = proto.Field( @@ -1253,6 +2096,10 @@ class ListWorkstationClustersRequest(proto.Message): proto.STRING, number=3, ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) class ListWorkstationClustersResponse(proto.Message): @@ -1301,7 +2148,7 @@ class CreateWorkstationClusterRequest(proto.Message): Required. Workstation cluster to create. validate_only (bool): Optional. If set, validate the request and - preview the review, but do not actually apply + preview the result, but do not actually apply it. """ @@ -1335,7 +2182,7 @@ class UpdateWorkstationClusterRequest(proto.Message): the workstation cluster should be updated. validate_only (bool): Optional. If set, validate the request and - preview the review, but do not actually apply + preview the result, but do not actually apply it. allow_missing (bool): Optional. If set, and the workstation cluster is not found, @@ -1372,7 +2219,7 @@ class DeleteWorkstationClusterRequest(proto.Message): delete. validate_only (bool): Optional. If set, validate the request and - preview the review, but do not apply it. + preview the result, but do not apply it. etag (str): Optional. If set, the request will be rejected if the latest version of the @@ -1429,6 +2276,10 @@ class ListWorkstationConfigsRequest(proto.Message): page_token (str): Optional. next_page_token value returned from a previous List request, if any. + filter (str): + Optional. Filter the WorkstationConfigs to be + listed. Possible filters are described in + https://google.aip.dev/160. """ parent: str = proto.Field( @@ -1443,6 +2294,10 @@ class ListWorkstationConfigsRequest(proto.Message): proto.STRING, number=3, ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) class ListWorkstationConfigsResponse(proto.Message): @@ -1548,10 +2403,11 @@ class CreateWorkstationConfigRequest(proto.Message): Required. ID to use for the workstation configuration. workstation_config (google.cloud.workstations_v1beta.types.WorkstationConfig): - Required. Config to create. + Required. Workstation configuration to + create. validate_only (bool): Optional. If set, validate the request and - preview the review, but do not actually apply + preview the result, but do not actually apply it. """ @@ -1579,13 +2435,14 @@ class UpdateWorkstationConfigRequest(proto.Message): Attributes: workstation_config (google.cloud.workstations_v1beta.types.WorkstationConfig): - Required. Config to update. + Required. Workstation configuration to + update. update_mask (google.protobuf.field_mask_pb2.FieldMask): Required. Mask specifying which fields in the workstation configuration should be updated. validate_only (bool): Optional. If set, validate the request and - preview the review, but do not actually apply + preview the result, but do not actually apply it. allow_missing (bool): Optional. If set and the workstation configuration is not @@ -1622,7 +2479,7 @@ class DeleteWorkstationConfigRequest(proto.Message): configuration to delete. validate_only (bool): Optional. If set, validate the request and - preview the review, but do not actually apply + preview the result, but do not actually apply it. etag (str): Optional. If set, the request is rejected if @@ -1679,6 +2536,10 @@ class ListWorkstationsRequest(proto.Message): page_token (str): Optional. next_page_token value returned from a previous List request, if any. + filter (str): + Optional. Filter the Workstations to be + listed. Possible filters are described in + https://google.aip.dev/160. """ parent: str = proto.Field( @@ -1693,6 +2554,10 @@ class ListWorkstationsRequest(proto.Message): proto.STRING, number=3, ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) class ListWorkstationsResponse(proto.Message): @@ -1797,10 +2662,16 @@ class CreateWorkstationRequest(proto.Message): workstation_id (str): Required. ID to use for the workstation. workstation (google.cloud.workstations_v1beta.types.Workstation): - Required. Workstation to create. + Required. Workstation to create. If source_workstation is + specified, the user must have + ``workstations.workstations.use`` permission on the source + workstation, and the Cloud Workstations Service Agent for + the project where you are creating the new workstation must + have compute.disks.createSnapshot and + compute.snapshots.useReadOnly on the source project. validate_only (bool): Optional. If set, validate the request and - preview the review, but do not actually apply + preview the result, but do not actually apply it. """ @@ -1831,15 +2702,15 @@ class UpdateWorkstationRequest(proto.Message): Required. Workstation to update. update_mask (google.protobuf.field_mask_pb2.FieldMask): Required. Mask specifying which fields in the - workstation configuration should be updated. + workstation should be updated. validate_only (bool): Optional. If set, validate the request and - preview the review, but do not actually apply + preview the result, but do not actually apply it. allow_missing (bool): - Optional. If set and the workstation configuration is not - found, a new workstation configuration is created. In this - situation, update_mask is ignored. + Optional. If set and the workstation is not found, a new + workstation is created. In this situation, update_mask is + ignored. """ workstation: "Workstation" = proto.Field( @@ -1870,7 +2741,7 @@ class DeleteWorkstationRequest(proto.Message): Required. Name of the workstation to delete. validate_only (bool): Optional. If set, validate the request and - preview the review, but do not actually apply + preview the result, but do not actually apply it. etag (str): Optional. If set, the request will be @@ -1901,13 +2772,17 @@ class StartWorkstationRequest(proto.Message): Required. Name of the workstation to start. validate_only (bool): Optional. If set, validate the request and - preview the review, but do not actually apply + preview the result, but do not actually apply it. etag (str): Optional. If set, the request will be rejected if the latest version of the workstation on the server does not have this ETag. + boost_config (str): + Optional. If set, the workstation starts + using the boost configuration with the specified + ID. """ name: str = proto.Field( @@ -1922,6 +2797,10 @@ class StartWorkstationRequest(proto.Message): proto.STRING, number=3, ) + boost_config: str = proto.Field( + proto.STRING, + number=4, + ) class StopWorkstationRequest(proto.Message): @@ -1932,7 +2811,7 @@ class StopWorkstationRequest(proto.Message): Required. Name of the workstation to stop. validate_only (bool): Optional. If set, validate the request and - preview the review, but do not actually apply + preview the result, but do not actually apply it. etag (str): Optional. If set, the request will be @@ -1984,6 +2863,13 @@ class GenerateAccessTokenRequest(proto.Message): workstation (str): Required. Name of the workstation for which the access token should be generated. + port (int): + Optional. Port for which the access token should be + generated. If specified, the generated access token grants + access only to the specified port of the workstation. If + specified, values must be within the range [1 - 65535]. If + not specified, the generated access token grants access to + all ports of the workstation. """ expire_time: timestamp_pb2.Timestamp = proto.Field( @@ -2002,6 +2888,10 @@ class GenerateAccessTokenRequest(proto.Message): proto.STRING, number=1, ) + port: int = proto.Field( + proto.INT32, + number=4, + ) class GenerateAccessTokenResponse(proto.Message): @@ -2029,6 +2919,74 @@ class GenerateAccessTokenResponse(proto.Message): ) +class PushCredentialsRequest(proto.Message): + r"""Request message for PushCredentials. + + Attributes: + workstation (str): + Required. Name of the workstation for which + the credentials should be pushed. + application_default_credentials (google.cloud.workstations_v1beta.types.PushCredentialsRequest.OAuthToken): + Optional. Credentials used by Cloud Client + Libraries, Google API Client Libraries, and + other tooling within the user conainer: + + https://cloud.google.com/docs/authentication/application-default-credentials + """ + + class OAuthToken(proto.Message): + r"""OAuth token. + + Attributes: + email (str): + Optional. The email address encapsulated in + the OAuth token. + scopes (str): + Optional. The scopes encapsulated in the + OAuth token. See + https://developers.google.com/identity/protocols/oauth2/scopes + for more information. + access_token (str): + Required. The OAuth token. + expire_time (google.protobuf.timestamp_pb2.Timestamp): + Optional. The time the OAuth access token will expire. This + should be the time the access token was generated plus the + expires_in offset returned from the Access Token Response. + """ + + email: str = proto.Field( + proto.STRING, + number=1, + ) + scopes: str = proto.Field( + proto.STRING, + number=2, + ) + access_token: str = proto.Field( + proto.STRING, + number=3, + ) + expire_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=4, + message=timestamp_pb2.Timestamp, + ) + + workstation: str = proto.Field( + proto.STRING, + number=1, + ) + application_default_credentials: OAuthToken = proto.Field( + proto.MESSAGE, + number=2, + message=OAuthToken, + ) + + +class PushCredentialsMetadata(proto.Message): + r"""Metadata message for PushCredentials.""" + + class OperationMetadata(proto.Message): r"""Metadata for long-running operations. diff --git a/packages/google-cloud-workstations/samples/generated_samples/snippet_metadata_google.cloud.workstations.v1beta.json b/packages/google-cloud-workstations/samples/generated_samples/snippet_metadata_google.cloud.workstations.v1beta.json index a9d21967918d..39c427311dce 100644 --- a/packages/google-cloud-workstations/samples/generated_samples/snippet_metadata_google.cloud.workstations.v1beta.json +++ b/packages/google-cloud-workstations/samples/generated_samples/snippet_metadata_google.cloud.workstations.v1beta.json @@ -2474,6 +2474,167 @@ ], "title": "workstations_v1beta_generated_workstations_list_workstations_sync.py" }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.workstations_v1beta.WorkstationsAsyncClient", + "shortName": "WorkstationsAsyncClient" + }, + "fullName": "google.cloud.workstations_v1beta.WorkstationsAsyncClient.push_credentials", + "method": { + "fullName": "google.cloud.workstations.v1beta.Workstations.PushCredentials", + "service": { + "fullName": "google.cloud.workstations.v1beta.Workstations", + "shortName": "Workstations" + }, + "shortName": "PushCredentials" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.workstations_v1beta.types.PushCredentialsRequest" + }, + { + "name": "workstation", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "push_credentials" + }, + "description": "Sample for PushCredentials", + "file": "workstations_v1beta_generated_workstations_push_credentials_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "workstations_v1beta_generated_Workstations_PushCredentials_async", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "workstations_v1beta_generated_workstations_push_credentials_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.workstations_v1beta.WorkstationsClient", + "shortName": "WorkstationsClient" + }, + "fullName": "google.cloud.workstations_v1beta.WorkstationsClient.push_credentials", + "method": { + "fullName": "google.cloud.workstations.v1beta.Workstations.PushCredentials", + "service": { + "fullName": "google.cloud.workstations.v1beta.Workstations", + "shortName": "Workstations" + }, + "shortName": "PushCredentials" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.workstations_v1beta.types.PushCredentialsRequest" + }, + { + "name": "workstation", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "push_credentials" + }, + "description": "Sample for PushCredentials", + "file": "workstations_v1beta_generated_workstations_push_credentials_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "workstations_v1beta_generated_Workstations_PushCredentials_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "workstations_v1beta_generated_workstations_push_credentials_sync.py" + }, { "canonical": true, "clientMethod": { diff --git a/packages/google-cloud-workstations/samples/generated_samples/workstations_v1beta_generated_workstations_push_credentials_async.py b/packages/google-cloud-workstations/samples/generated_samples/workstations_v1beta_generated_workstations_push_credentials_async.py new file mode 100644 index 000000000000..d70b287c4356 --- /dev/null +++ b/packages/google-cloud-workstations/samples/generated_samples/workstations_v1beta_generated_workstations_push_credentials_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for PushCredentials +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-workstations + + +# [START workstations_v1beta_generated_Workstations_PushCredentials_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import workstations_v1beta + + +async def sample_push_credentials(): + # Create a client + client = workstations_v1beta.WorkstationsAsyncClient() + + # Initialize request argument(s) + request = workstations_v1beta.PushCredentialsRequest( + workstation="workstation_value", + ) + + # Make the request + operation = await client.push_credentials(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + +# [END workstations_v1beta_generated_Workstations_PushCredentials_async] diff --git a/packages/google-cloud-workstations/samples/generated_samples/workstations_v1beta_generated_workstations_push_credentials_sync.py b/packages/google-cloud-workstations/samples/generated_samples/workstations_v1beta_generated_workstations_push_credentials_sync.py new file mode 100644 index 000000000000..5d41bb377748 --- /dev/null +++ b/packages/google-cloud-workstations/samples/generated_samples/workstations_v1beta_generated_workstations_push_credentials_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for PushCredentials +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-workstations + + +# [START workstations_v1beta_generated_Workstations_PushCredentials_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import workstations_v1beta + + +def sample_push_credentials(): + # Create a client + client = workstations_v1beta.WorkstationsClient() + + # Initialize request argument(s) + request = workstations_v1beta.PushCredentialsRequest( + workstation="workstation_value", + ) + + # Make the request + operation = client.push_credentials(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + +# [END workstations_v1beta_generated_Workstations_PushCredentials_sync] diff --git a/packages/google-cloud-workstations/tests/unit/gapic/workstations_v1/test_workstations.py b/packages/google-cloud-workstations/tests/unit/gapic/workstations_v1/test_workstations.py index c32c2b5c40b6..d055e9cdf871 100644 --- a/packages/google-cloud-workstations/tests/unit/gapic/workstations_v1/test_workstations.py +++ b/packages/google-cloud-workstations/tests/unit/gapic/workstations_v1/test_workstations.py @@ -1348,6 +1348,8 @@ def test_get_workstation_cluster(request_type, transport: str = "grpc"): subnetwork="subnetwork_value", control_plane_ip="control_plane_ip_value", degraded=True, + workstation_authorization_url="workstation_authorization_url_value", + workstation_launch_url="workstation_launch_url_value", ) response = client.get_workstation_cluster(request) @@ -1368,6 +1370,10 @@ def test_get_workstation_cluster(request_type, transport: str = "grpc"): assert response.subnetwork == "subnetwork_value" assert response.control_plane_ip == "control_plane_ip_value" assert response.degraded is True + assert ( + response.workstation_authorization_url == "workstation_authorization_url_value" + ) + assert response.workstation_launch_url == "workstation_launch_url_value" def test_get_workstation_cluster_non_empty_request_with_auto_populated_field(): @@ -1519,6 +1525,8 @@ async def test_get_workstation_cluster_async( subnetwork="subnetwork_value", control_plane_ip="control_plane_ip_value", degraded=True, + workstation_authorization_url="workstation_authorization_url_value", + workstation_launch_url="workstation_launch_url_value", ) ) response = await client.get_workstation_cluster(request) @@ -1540,6 +1548,10 @@ async def test_get_workstation_cluster_async( assert response.subnetwork == "subnetwork_value" assert response.control_plane_ip == "control_plane_ip_value" assert response.degraded is True + assert ( + response.workstation_authorization_url == "workstation_authorization_url_value" + ) + assert response.workstation_launch_url == "workstation_launch_url_value" def test_get_workstation_cluster_field_headers(): @@ -1747,6 +1759,7 @@ def test_list_workstation_clusters_non_empty_request_with_auto_populated_field() request = workstations.ListWorkstationClustersRequest( parent="parent_value", page_token="page_token_value", + filter="filter_value", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1762,6 +1775,7 @@ def test_list_workstation_clusters_non_empty_request_with_auto_populated_field() request_msg = workstations.ListWorkstationClustersRequest( parent="parent_value", page_token="page_token_value", + filter="filter_value", ) assert args[0] == request_msg @@ -3349,8 +3363,12 @@ def test_get_workstation_config(request_type, transport: str = "grpc"): uid="uid_value", reconciling=True, etag="etag_value", + max_usable_workstations=2488, replica_zones=["replica_zones_value"], degraded=True, + enable_audit_agent=True, + disable_tcp_connections=True, + grant_workstation_admin_role_on_create=True, ) response = client.get_workstation_config(request) @@ -3367,8 +3385,12 @@ def test_get_workstation_config(request_type, transport: str = "grpc"): assert response.uid == "uid_value" assert response.reconciling is True assert response.etag == "etag_value" + assert response.max_usable_workstations == 2488 assert response.replica_zones == ["replica_zones_value"] assert response.degraded is True + assert response.enable_audit_agent is True + assert response.disable_tcp_connections is True + assert response.grant_workstation_admin_role_on_create is True def test_get_workstation_config_non_empty_request_with_auto_populated_field(): @@ -3516,8 +3538,12 @@ async def test_get_workstation_config_async( uid="uid_value", reconciling=True, etag="etag_value", + max_usable_workstations=2488, replica_zones=["replica_zones_value"], degraded=True, + enable_audit_agent=True, + disable_tcp_connections=True, + grant_workstation_admin_role_on_create=True, ) ) response = await client.get_workstation_config(request) @@ -3535,8 +3561,12 @@ async def test_get_workstation_config_async( assert response.uid == "uid_value" assert response.reconciling is True assert response.etag == "etag_value" + assert response.max_usable_workstations == 2488 assert response.replica_zones == ["replica_zones_value"] assert response.degraded is True + assert response.enable_audit_agent is True + assert response.disable_tcp_connections is True + assert response.grant_workstation_admin_role_on_create is True def test_get_workstation_config_field_headers(): @@ -3744,6 +3774,7 @@ def test_list_workstation_configs_non_empty_request_with_auto_populated_field(): request = workstations.ListWorkstationConfigsRequest( parent="parent_value", page_token="page_token_value", + filter="filter_value", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3759,6 +3790,7 @@ def test_list_workstation_configs_non_empty_request_with_auto_populated_field(): request_msg = workstations.ListWorkstationConfigsRequest( parent="parent_value", page_token="page_token_value", + filter="filter_value", ) assert args[0] == request_msg @@ -5899,6 +5931,8 @@ def test_get_workstation(request_type, transport: str = "grpc"): etag="etag_value", state=workstations.Workstation.State.STATE_STARTING, host="host_value", + kms_key="kms_key_value", + source_workstation="source_workstation_value", ) response = client.get_workstation(request) @@ -5917,6 +5951,8 @@ def test_get_workstation(request_type, transport: str = "grpc"): assert response.etag == "etag_value" assert response.state == workstations.Workstation.State.STATE_STARTING assert response.host == "host_value" + assert response.kms_key == "kms_key_value" + assert response.source_workstation == "source_workstation_value" def test_get_workstation_non_empty_request_with_auto_populated_field(): @@ -6055,6 +6091,8 @@ async def test_get_workstation_async(request_type, transport: str = "grpc_asynci etag="etag_value", state=workstations.Workstation.State.STATE_STARTING, host="host_value", + kms_key="kms_key_value", + source_workstation="source_workstation_value", ) ) response = await client.get_workstation(request) @@ -6074,6 +6112,8 @@ async def test_get_workstation_async(request_type, transport: str = "grpc_asynci assert response.etag == "etag_value" assert response.state == workstations.Workstation.State.STATE_STARTING assert response.host == "host_value" + assert response.kms_key == "kms_key_value" + assert response.source_workstation == "source_workstation_value" def test_get_workstation_field_headers(): @@ -6273,6 +6313,7 @@ def test_list_workstations_non_empty_request_with_auto_populated_field(): request = workstations.ListWorkstationsRequest( parent="parent_value", page_token="page_token_value", + filter="filter_value", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -6288,6 +6329,7 @@ def test_list_workstations_non_empty_request_with_auto_populated_field(): request_msg = workstations.ListWorkstationsRequest( parent="parent_value", page_token="page_token_value", + filter="filter_value", ) assert args[0] == request_msg @@ -8431,6 +8473,7 @@ def test_start_workstation_non_empty_request_with_auto_populated_field(): request = workstations.StartWorkstationRequest( name="name_value", etag="etag_value", + boost_config="boost_config_value", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -8446,6 +8489,7 @@ def test_start_workstation_non_empty_request_with_auto_populated_field(): request_msg = workstations.StartWorkstationRequest( name="name_value", etag="etag_value", + boost_config="boost_config_value", ) assert args[0] == request_msg @@ -9661,6 +9705,7 @@ def test_list_workstation_clusters_rest_required_fields( # Check that path parameters and body parameters are not mixing in. assert not set(unset_fields) - set( ( + "filter", "page_size", "page_token", ) @@ -9722,6 +9767,7 @@ def test_list_workstation_clusters_rest_unset_required_fields(): assert set(unset_fields) == ( set( ( + "filter", "pageSize", "pageToken", ) @@ -10738,6 +10784,7 @@ def test_list_workstation_configs_rest_required_fields( # Check that path parameters and body parameters are not mixing in. assert not set(unset_fields) - set( ( + "filter", "page_size", "page_token", ) @@ -10799,6 +10846,7 @@ def test_list_workstation_configs_rest_unset_required_fields(): assert set(unset_fields) == ( set( ( + "filter", "pageSize", "pageToken", ) @@ -12087,6 +12135,7 @@ def test_list_workstations_rest_required_fields( # Check that path parameters and body parameters are not mixing in. assert not set(unset_fields) - set( ( + "filter", "page_size", "page_token", ) @@ -12148,6 +12197,7 @@ def test_list_workstations_rest_unset_required_fields(): assert set(unset_fields) == ( set( ( + "filter", "pageSize", "pageToken", ) @@ -14302,6 +14352,8 @@ async def test_get_workstation_cluster_empty_call_grpc_asyncio(): subnetwork="subnetwork_value", control_plane_ip="control_plane_ip_value", degraded=True, + workstation_authorization_url="workstation_authorization_url_value", + workstation_launch_url="workstation_launch_url_value", ) ) await client.get_workstation_cluster(request=None) @@ -14441,8 +14493,12 @@ async def test_get_workstation_config_empty_call_grpc_asyncio(): uid="uid_value", reconciling=True, etag="etag_value", + max_usable_workstations=2488, replica_zones=["replica_zones_value"], degraded=True, + enable_audit_agent=True, + disable_tcp_connections=True, + grant_workstation_admin_role_on_create=True, ) ) await client.get_workstation_config(request=None) @@ -14611,6 +14667,8 @@ async def test_get_workstation_empty_call_grpc_asyncio(): etag="etag_value", state=workstations.Workstation.State.STATE_STARTING, host="host_value", + kms_key="kms_key_value", + source_workstation="source_workstation_value", ) ) await client.get_workstation(request=None) @@ -14902,6 +14960,8 @@ def test_get_workstation_cluster_rest_call_success(request_type): subnetwork="subnetwork_value", control_plane_ip="control_plane_ip_value", degraded=True, + workstation_authorization_url="workstation_authorization_url_value", + workstation_launch_url="workstation_launch_url_value", ) # Wrap the value into a proper Response obj @@ -14927,6 +14987,10 @@ def test_get_workstation_cluster_rest_call_success(request_type): assert response.subnetwork == "subnetwork_value" assert response.control_plane_ip == "control_plane_ip_value" assert response.degraded is True + assert ( + response.workstation_authorization_url == "workstation_authorization_url_value" + ) + assert response.workstation_launch_url == "workstation_launch_url_value" @pytest.mark.parametrize("null_interceptor", [True, False]) @@ -15194,6 +15258,7 @@ def test_create_workstation_cluster_rest_call_success(request_type): "service_attachment_uri": "service_attachment_uri_value", "allowed_projects": ["allowed_projects_value1", "allowed_projects_value2"], }, + "domain_config": {"domain": "domain_value"}, "degraded": True, "conditions": [ { @@ -15207,6 +15272,10 @@ def test_create_workstation_cluster_rest_call_success(request_type): ], } ], + "tags": {}, + "gateway_config": {"http2_enabled": True}, + "workstation_authorization_url": "workstation_authorization_url_value", + "workstation_launch_url": "workstation_launch_url_value", } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -15431,6 +15500,7 @@ def test_update_workstation_cluster_rest_call_success(request_type): "service_attachment_uri": "service_attachment_uri_value", "allowed_projects": ["allowed_projects_value1", "allowed_projects_value2"], }, + "domain_config": {"domain": "domain_value"}, "degraded": True, "conditions": [ { @@ -15444,6 +15514,10 @@ def test_update_workstation_cluster_rest_call_success(request_type): ], } ], + "tags": {}, + "gateway_config": {"http2_enabled": True}, + "workstation_authorization_url": "workstation_authorization_url_value", + "workstation_launch_url": "workstation_launch_url_value", } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -15785,8 +15859,12 @@ def test_get_workstation_config_rest_call_success(request_type): uid="uid_value", reconciling=True, etag="etag_value", + max_usable_workstations=2488, replica_zones=["replica_zones_value"], degraded=True, + enable_audit_agent=True, + disable_tcp_connections=True, + grant_workstation_admin_role_on_create=True, ) # Wrap the value into a proper Response obj @@ -15808,8 +15886,12 @@ def test_get_workstation_config_rest_call_success(request_type): assert response.uid == "uid_value" assert response.reconciling is True assert response.etag == "etag_value" + assert response.max_usable_workstations == 2488 assert response.replica_zones == ["replica_zones_value"] assert response.degraded is True + assert response.enable_audit_agent is True + assert response.disable_tcp_connections is True + assert response.grant_workstation_admin_role_on_create is True @pytest.mark.parametrize("null_interceptor", [True, False]) @@ -16224,6 +16306,7 @@ def test_create_workstation_config_rest_call_success(request_type): "etag": "etag_value", "idle_timeout": {"seconds": 751, "nanos": 543}, "running_timeout": {}, + "max_usable_workstations": 2488, "host": { "gce_instance": { "machine_type": "machine_type_value", @@ -16244,16 +16327,51 @@ def test_create_workstation_config_rest_call_success(request_type): }, "confidential_instance_config": {"enable_confidential_compute": True}, "boot_disk_size_gb": 1792, + "accelerators": [{"type_": "type__value", "count": 553}], + "boost_configs": [ + { + "id": "id_value", + "machine_type": "machine_type_value", + "accelerators": {}, + "boot_disk_size_gb": 1792, + "enable_nested_virtualization": True, + "pool_size": 980, + } + ], + "disable_ssh": True, + "vm_tags": {}, + "startup_script_uri": "startup_script_uri_value", + "instance_metadata": {}, } }, "persistent_directories": [ { "gce_pd": { "size_gb": 739, + "max_size_gb": 1160, "fs_type": "fs_type_value", "disk_type": "disk_type_value", "source_snapshot": "source_snapshot_value", "reclaim_policy": 1, + "archive_timeout": {}, + }, + "gce_hd": { + "size_gb": 739, + "max_size_gb": 1160, + "source_snapshot": "source_snapshot_value", + "reclaim_policy": 1, + "archive_timeout": {}, + }, + "mount_path": "mount_path_value", + } + ], + "ephemeral_directories": [ + { + "gce_pd": { + "disk_type": "disk_type_value", + "source_snapshot": "source_snapshot_value", + "source_image": "source_image_value", + "read_only": True, }, "mount_path": "mount_path_value", } @@ -16285,6 +16403,10 @@ def test_create_workstation_config_rest_call_success(request_type): ], } ], + "enable_audit_agent": True, + "disable_tcp_connections": True, + "allowed_ports": [{"first": 552, "last": 436}], + "grant_workstation_admin_role_on_create": True, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -16502,6 +16624,7 @@ def test_update_workstation_config_rest_call_success(request_type): "etag": "etag_value", "idle_timeout": {"seconds": 751, "nanos": 543}, "running_timeout": {}, + "max_usable_workstations": 2488, "host": { "gce_instance": { "machine_type": "machine_type_value", @@ -16522,16 +16645,51 @@ def test_update_workstation_config_rest_call_success(request_type): }, "confidential_instance_config": {"enable_confidential_compute": True}, "boot_disk_size_gb": 1792, + "accelerators": [{"type_": "type__value", "count": 553}], + "boost_configs": [ + { + "id": "id_value", + "machine_type": "machine_type_value", + "accelerators": {}, + "boot_disk_size_gb": 1792, + "enable_nested_virtualization": True, + "pool_size": 980, + } + ], + "disable_ssh": True, + "vm_tags": {}, + "startup_script_uri": "startup_script_uri_value", + "instance_metadata": {}, } }, "persistent_directories": [ { "gce_pd": { "size_gb": 739, + "max_size_gb": 1160, "fs_type": "fs_type_value", "disk_type": "disk_type_value", "source_snapshot": "source_snapshot_value", "reclaim_policy": 1, + "archive_timeout": {}, + }, + "gce_hd": { + "size_gb": 739, + "max_size_gb": 1160, + "source_snapshot": "source_snapshot_value", + "reclaim_policy": 1, + "archive_timeout": {}, + }, + "mount_path": "mount_path_value", + } + ], + "ephemeral_directories": [ + { + "gce_pd": { + "disk_type": "disk_type_value", + "source_snapshot": "source_snapshot_value", + "source_image": "source_image_value", + "read_only": True, }, "mount_path": "mount_path_value", } @@ -16563,6 +16721,10 @@ def test_update_workstation_config_rest_call_success(request_type): ], } ], + "enable_audit_agent": True, + "disable_tcp_connections": True, + "allowed_ports": [{"first": 552, "last": 436}], + "grant_workstation_admin_role_on_create": True, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -16906,6 +17068,8 @@ def test_get_workstation_rest_call_success(request_type): etag="etag_value", state=workstations.Workstation.State.STATE_STARTING, host="host_value", + kms_key="kms_key_value", + source_workstation="source_workstation_value", ) # Wrap the value into a proper Response obj @@ -16929,6 +17093,8 @@ def test_get_workstation_rest_call_success(request_type): assert response.etag == "etag_value" assert response.state == workstations.Workstation.State.STATE_STARTING assert response.host == "host_value" + assert response.kms_key == "kms_key_value" + assert response.source_workstation == "source_workstation_value" @pytest.mark.parametrize("null_interceptor", [True, False]) @@ -17335,8 +17501,19 @@ def test_create_workstation_rest_call_success(request_type): "start_time": {}, "delete_time": {}, "etag": "etag_value", + "persistent_directories": [{"mount_path": "mount_path_value", "size_gb": 739}], "state": 1, "host": "host_value", + "env": {}, + "kms_key": "kms_key_value", + "source_workstation": "source_workstation_value", + "runtime_host": { + "gce_instance_host": { + "name": "name_value", + "id": "id_value", + "zone": "zone_value", + } + }, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -17551,8 +17728,19 @@ def test_update_workstation_rest_call_success(request_type): "start_time": {}, "delete_time": {}, "etag": "etag_value", + "persistent_directories": [{"mount_path": "mount_path_value", "size_gb": 739}], "state": 1, "host": "host_value", + "env": {}, + "kms_key": "kms_key_value", + "source_workstation": "source_workstation_value", + "runtime_host": { + "gce_instance_host": { + "name": "name_value", + "id": "id_value", + "zone": "zone_value", + } + }, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency diff --git a/packages/google-cloud-workstations/tests/unit/gapic/workstations_v1beta/test_workstations.py b/packages/google-cloud-workstations/tests/unit/gapic/workstations_v1beta/test_workstations.py index a40a95643153..0e0dadd3fb7f 100644 --- a/packages/google-cloud-workstations/tests/unit/gapic/workstations_v1beta/test_workstations.py +++ b/packages/google-cloud-workstations/tests/unit/gapic/workstations_v1beta/test_workstations.py @@ -1348,6 +1348,10 @@ def test_get_workstation_cluster(request_type, transport: str = "grpc"): subnetwork="subnetwork_value", control_plane_ip="control_plane_ip_value", degraded=True, + satisfies_pzs=True, + satisfies_pzi=True, + workstation_authorization_url="workstation_authorization_url_value", + workstation_launch_url="workstation_launch_url_value", ) response = client.get_workstation_cluster(request) @@ -1368,6 +1372,12 @@ def test_get_workstation_cluster(request_type, transport: str = "grpc"): assert response.subnetwork == "subnetwork_value" assert response.control_plane_ip == "control_plane_ip_value" assert response.degraded is True + assert response.satisfies_pzs is True + assert response.satisfies_pzi is True + assert ( + response.workstation_authorization_url == "workstation_authorization_url_value" + ) + assert response.workstation_launch_url == "workstation_launch_url_value" def test_get_workstation_cluster_non_empty_request_with_auto_populated_field(): @@ -1519,6 +1529,10 @@ async def test_get_workstation_cluster_async( subnetwork="subnetwork_value", control_plane_ip="control_plane_ip_value", degraded=True, + satisfies_pzs=True, + satisfies_pzi=True, + workstation_authorization_url="workstation_authorization_url_value", + workstation_launch_url="workstation_launch_url_value", ) ) response = await client.get_workstation_cluster(request) @@ -1540,6 +1554,12 @@ async def test_get_workstation_cluster_async( assert response.subnetwork == "subnetwork_value" assert response.control_plane_ip == "control_plane_ip_value" assert response.degraded is True + assert response.satisfies_pzs is True + assert response.satisfies_pzi is True + assert ( + response.workstation_authorization_url == "workstation_authorization_url_value" + ) + assert response.workstation_launch_url == "workstation_launch_url_value" def test_get_workstation_cluster_field_headers(): @@ -1747,6 +1767,7 @@ def test_list_workstation_clusters_non_empty_request_with_auto_populated_field() request = workstations.ListWorkstationClustersRequest( parent="parent_value", page_token="page_token_value", + filter="filter_value", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1762,6 +1783,7 @@ def test_list_workstation_clusters_non_empty_request_with_auto_populated_field() request_msg = workstations.ListWorkstationClustersRequest( parent="parent_value", page_token="page_token_value", + filter="filter_value", ) assert args[0] == request_msg @@ -3349,9 +3371,15 @@ def test_get_workstation_config(request_type, transport: str = "grpc"): uid="uid_value", reconciling=True, etag="etag_value", + max_usable_workstations=2488, replica_zones=["replica_zones_value"], degraded=True, enable_audit_agent=True, + disable_tcp_connections=True, + satisfies_pzs=True, + satisfies_pzi=True, + grant_workstation_admin_role_on_create=True, + enable_pushing_credentials=True, ) response = client.get_workstation_config(request) @@ -3368,9 +3396,15 @@ def test_get_workstation_config(request_type, transport: str = "grpc"): assert response.uid == "uid_value" assert response.reconciling is True assert response.etag == "etag_value" + assert response.max_usable_workstations == 2488 assert response.replica_zones == ["replica_zones_value"] assert response.degraded is True assert response.enable_audit_agent is True + assert response.disable_tcp_connections is True + assert response.satisfies_pzs is True + assert response.satisfies_pzi is True + assert response.grant_workstation_admin_role_on_create is True + assert response.enable_pushing_credentials is True def test_get_workstation_config_non_empty_request_with_auto_populated_field(): @@ -3518,9 +3552,15 @@ async def test_get_workstation_config_async( uid="uid_value", reconciling=True, etag="etag_value", + max_usable_workstations=2488, replica_zones=["replica_zones_value"], degraded=True, enable_audit_agent=True, + disable_tcp_connections=True, + satisfies_pzs=True, + satisfies_pzi=True, + grant_workstation_admin_role_on_create=True, + enable_pushing_credentials=True, ) ) response = await client.get_workstation_config(request) @@ -3538,9 +3578,15 @@ async def test_get_workstation_config_async( assert response.uid == "uid_value" assert response.reconciling is True assert response.etag == "etag_value" + assert response.max_usable_workstations == 2488 assert response.replica_zones == ["replica_zones_value"] assert response.degraded is True assert response.enable_audit_agent is True + assert response.disable_tcp_connections is True + assert response.satisfies_pzs is True + assert response.satisfies_pzi is True + assert response.grant_workstation_admin_role_on_create is True + assert response.enable_pushing_credentials is True def test_get_workstation_config_field_headers(): @@ -3748,6 +3794,7 @@ def test_list_workstation_configs_non_empty_request_with_auto_populated_field(): request = workstations.ListWorkstationConfigsRequest( parent="parent_value", page_token="page_token_value", + filter="filter_value", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3763,6 +3810,7 @@ def test_list_workstation_configs_non_empty_request_with_auto_populated_field(): request_msg = workstations.ListWorkstationConfigsRequest( parent="parent_value", page_token="page_token_value", + filter="filter_value", ) assert args[0] == request_msg @@ -5903,6 +5951,11 @@ def test_get_workstation(request_type, transport: str = "grpc"): etag="etag_value", state=workstations.Workstation.State.STATE_STARTING, host="host_value", + kms_key="kms_key_value", + source_workstation="source_workstation_value", + satisfies_pzs=True, + satisfies_pzi=True, + degraded=True, ) response = client.get_workstation(request) @@ -5921,6 +5974,11 @@ def test_get_workstation(request_type, transport: str = "grpc"): assert response.etag == "etag_value" assert response.state == workstations.Workstation.State.STATE_STARTING assert response.host == "host_value" + assert response.kms_key == "kms_key_value" + assert response.source_workstation == "source_workstation_value" + assert response.satisfies_pzs is True + assert response.satisfies_pzi is True + assert response.degraded is True def test_get_workstation_non_empty_request_with_auto_populated_field(): @@ -6059,6 +6117,11 @@ async def test_get_workstation_async(request_type, transport: str = "grpc_asynci etag="etag_value", state=workstations.Workstation.State.STATE_STARTING, host="host_value", + kms_key="kms_key_value", + source_workstation="source_workstation_value", + satisfies_pzs=True, + satisfies_pzi=True, + degraded=True, ) ) response = await client.get_workstation(request) @@ -6078,6 +6141,11 @@ async def test_get_workstation_async(request_type, transport: str = "grpc_asynci assert response.etag == "etag_value" assert response.state == workstations.Workstation.State.STATE_STARTING assert response.host == "host_value" + assert response.kms_key == "kms_key_value" + assert response.source_workstation == "source_workstation_value" + assert response.satisfies_pzs is True + assert response.satisfies_pzi is True + assert response.degraded is True def test_get_workstation_field_headers(): @@ -6277,6 +6345,7 @@ def test_list_workstations_non_empty_request_with_auto_populated_field(): request = workstations.ListWorkstationsRequest( parent="parent_value", page_token="page_token_value", + filter="filter_value", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -6292,6 +6361,7 @@ def test_list_workstations_non_empty_request_with_auto_populated_field(): request_msg = workstations.ListWorkstationsRequest( parent="parent_value", page_token="page_token_value", + filter="filter_value", ) assert args[0] == request_msg @@ -8435,6 +8505,7 @@ def test_start_workstation_non_empty_request_with_auto_populated_field(): request = workstations.StartWorkstationRequest( name="name_value", etag="etag_value", + boost_config="boost_config_value", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -8450,6 +8521,7 @@ def test_start_workstation_non_empty_request_with_auto_populated_field(): request_msg = workstations.StartWorkstationRequest( name="name_value", etag="etag_value", + boost_config="boost_config_value", ) assert args[0] == request_msg @@ -9409,13 +9481,75 @@ async def test_generate_access_token_flattened_error_async(): ) -def test_get_workstation_cluster_rest_use_cached_wrapped_rpc(): +@pytest.mark.parametrize( + "request_type", + [ + workstations.PushCredentialsRequest(), + {}, + ], +) +def test_push_credentials(request_type, transport: str = "grpc"): + client = WorkstationsClient( + 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.push_credentials), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.push_credentials(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = workstations.PushCredentialsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_push_credentials_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = WorkstationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = workstations.PushCredentialsRequest( + workstation="workstation_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.push_credentials), "__call__") as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.push_credentials(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = workstations.PushCredentialsRequest( + workstation="workstation_value", + ) + assert args[0] == request_msg + + +def test_push_credentials_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = WorkstationsClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) # Should wrap all calls on client creation @@ -9423,160 +9557,428 @@ def test_get_workstation_cluster_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert ( - client._transport.get_workstation_cluster - in client._transport._wrapped_methods - ) + assert client._transport.push_credentials in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[ - client._transport.get_workstation_cluster - ] = mock_rpc - + client._transport._wrapped_methods[client._transport.push_credentials] = ( + mock_rpc + ) request = {} - client.get_workstation_cluster(request) + client.push_credentials(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.get_workstation_cluster(request) + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.push_credentials(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_get_workstation_cluster_rest_required_fields( - request_type=workstations.GetWorkstationClusterRequest, +@pytest.mark.asyncio +async def test_push_credentials_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", ): - transport_class = transports.WorkstationsRestTransport - - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_workstation_cluster._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = WorkstationsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - # verify required fields with default values are now present + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - jsonified_request["name"] = "name_value" + # Ensure method has been cached + assert ( + client._client._transport.push_credentials + in client._client._transport._wrapped_methods + ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_workstation_cluster._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.push_credentials + ] = mock_rpc - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + request = {} + await client.push_credentials(request) - client = WorkstationsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - # Designate an appropriate value for the returned response. - return_value = workstations.WorkstationCluster() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() - response_value = Response() - response_value.status_code = 200 + await client.push_credentials(request) - # Convert return value to protobuf type - return_value = workstations.WorkstationCluster.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_workstation_cluster(request) +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + workstations.PushCredentialsRequest(), + {}, + ], +) +async def test_push_credentials_async(request_type, transport: str = "grpc_asyncio"): + client = WorkstationsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + # 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.push_credentials), "__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.push_credentials(request) -def test_get_workstation_cluster_rest_unset_required_fields(): - transport = transports.WorkstationsRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = workstations.PushCredentialsRequest() + assert args[0] == request - unset_fields = transport.get_workstation_cluster._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) -def test_get_workstation_cluster_rest_flattened(): +def test_push_credentials_field_headers(): client = WorkstationsClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = workstations.WorkstationCluster() + # 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 = workstations.PushCredentialsRequest() - # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/workstationClusters/sample3" - } + request.workstation = "workstation_value" - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.push_credentials), "__call__") as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.push_credentials(request) - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = workstations.WorkstationCluster.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request - client.get_workstation_cluster(**mock_args) + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "workstation=workstation_value", + ) in kw["metadata"] - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1beta/{name=projects/*/locations/*/workstationClusters/*}" - % client.transport._host, - args[1], - ) + +@pytest.mark.asyncio +async def test_push_credentials_field_headers_async(): + client = WorkstationsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = workstations.PushCredentialsRequest() + + request.workstation = "workstation_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.push_credentials), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.push_credentials(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", + "workstation=workstation_value", + ) in kw["metadata"] + + +def test_push_credentials_flattened(): + client = WorkstationsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.push_credentials), "__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.push_credentials( + workstation="workstation_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].workstation + mock_val = "workstation_value" + assert arg == mock_val + + +def test_push_credentials_flattened_error(): + client = WorkstationsClient( + 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.push_credentials( + workstations.PushCredentialsRequest(), + workstation="workstation_value", + ) + + +@pytest.mark.asyncio +async def test_push_credentials_flattened_async(): + client = WorkstationsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.push_credentials), "__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.push_credentials( + workstation="workstation_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].workstation + mock_val = "workstation_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_push_credentials_flattened_error_async(): + client = WorkstationsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.push_credentials( + workstations.PushCredentialsRequest(), + workstation="workstation_value", + ) + + +def test_get_workstation_cluster_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = WorkstationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.get_workstation_cluster + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.get_workstation_cluster + ] = mock_rpc + + request = {} + client.get_workstation_cluster(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_workstation_cluster(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_workstation_cluster_rest_required_fields( + request_type=workstations.GetWorkstationClusterRequest, +): + transport_class = transports.WorkstationsRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_workstation_cluster._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_workstation_cluster._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = WorkstationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = workstations.WorkstationCluster() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = workstations.WorkstationCluster.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_workstation_cluster(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_get_workstation_cluster_rest_unset_required_fields(): + transport = transports.WorkstationsRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_workstation_cluster._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_workstation_cluster_rest_flattened(): + client = WorkstationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = workstations.WorkstationCluster() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/workstationClusters/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = workstations.WorkstationCluster.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_workstation_cluster(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1beta/{name=projects/*/locations/*/workstationClusters/*}" + % client.transport._host, + args[1], + ) def test_get_workstation_cluster_rest_flattened_error(transport: str = "rest"): @@ -9665,6 +10067,7 @@ def test_list_workstation_clusters_rest_required_fields( # Check that path parameters and body parameters are not mixing in. assert not set(unset_fields) - set( ( + "filter", "page_size", "page_token", ) @@ -9726,6 +10129,7 @@ def test_list_workstation_clusters_rest_unset_required_fields(): assert set(unset_fields) == ( set( ( + "filter", "pageSize", "pageToken", ) @@ -10742,6 +11146,7 @@ def test_list_workstation_configs_rest_required_fields( # Check that path parameters and body parameters are not mixing in. assert not set(unset_fields) - set( ( + "filter", "page_size", "page_token", ) @@ -10803,6 +11208,7 @@ def test_list_workstation_configs_rest_unset_required_fields(): assert set(unset_fields) == ( set( ( + "filter", "pageSize", "pageToken", ) @@ -12091,6 +12497,7 @@ def test_list_workstations_rest_required_fields( # Check that path parameters and body parameters are not mixing in. assert not set(unset_fields) - set( ( + "filter", "page_size", "page_token", ) @@ -12152,6 +12559,7 @@ def test_list_workstations_rest_unset_required_fields(): assert set(unset_fields) == ( set( ( + "filter", "pageSize", "pageToken", ) @@ -13539,7 +13947,193 @@ def test_stop_workstation_rest_flattened_error(transport: str = "rest"): ) -def test_generate_access_token_rest_use_cached_wrapped_rpc(): +def test_generate_access_token_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = WorkstationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.generate_access_token + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.generate_access_token] = ( + mock_rpc + ) + + request = {} + client.generate_access_token(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.generate_access_token(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_generate_access_token_rest_required_fields( + request_type=workstations.GenerateAccessTokenRequest, +): + transport_class = transports.WorkstationsRestTransport + + request_init = {} + request_init["workstation"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).generate_access_token._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["workstation"] = "workstation_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).generate_access_token._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "workstation" in jsonified_request + assert jsonified_request["workstation"] == "workstation_value" + + client = WorkstationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = workstations.GenerateAccessTokenResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = workstations.GenerateAccessTokenResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.generate_access_token(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_generate_access_token_rest_unset_required_fields(): + transport = transports.WorkstationsRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.generate_access_token._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("workstation",))) + + +def test_generate_access_token_rest_flattened(): + client = WorkstationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = workstations.GenerateAccessTokenResponse() + + # get arguments that satisfy an http rule for this method + sample_request = { + "workstation": "projects/sample1/locations/sample2/workstationClusters/sample3/workstationConfigs/sample4/workstations/sample5" + } + + # get truthy value for each flattened field + mock_args = dict( + workstation="workstation_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = workstations.GenerateAccessTokenResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.generate_access_token(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1beta/{workstation=projects/*/locations/*/workstationClusters/*/workstationConfigs/*/workstations/*}:generateAccessToken" + % client.transport._host, + args[1], + ) + + +def test_generate_access_token_rest_flattened_error(transport: str = "rest"): + client = WorkstationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.generate_access_token( + workstations.GenerateAccessTokenRequest(), + workstation="workstation_value", + ) + + +def test_push_credentials_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -13553,35 +14147,36 @@ def test_generate_access_token_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert ( - client._transport.generate_access_token - in client._transport._wrapped_methods - ) + assert client._transport.push_credentials in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.generate_access_token] = ( + client._transport._wrapped_methods[client._transport.push_credentials] = ( mock_rpc ) request = {} - client.generate_access_token(request) + client.push_credentials(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.generate_access_token(request) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.push_credentials(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_generate_access_token_rest_required_fields( - request_type=workstations.GenerateAccessTokenRequest, +def test_push_credentials_rest_required_fields( + request_type=workstations.PushCredentialsRequest, ): transport_class = transports.WorkstationsRestTransport @@ -13597,7 +14192,7 @@ def test_generate_access_token_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).generate_access_token._get_unset_required_fields(jsonified_request) + ).push_credentials._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -13606,7 +14201,7 @@ def test_generate_access_token_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).generate_access_token._get_unset_required_fields(jsonified_request) + ).push_credentials._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -13620,7 +14215,7 @@ def test_generate_access_token_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = workstations.GenerateAccessTokenResponse() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -13640,32 +14235,29 @@ def test_generate_access_token_rest_required_fields( response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = workstations.GenerateAccessTokenResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.generate_access_token(request) + response = client.push_credentials(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_generate_access_token_rest_unset_required_fields(): +def test_push_credentials_rest_unset_required_fields(): transport = transports.WorkstationsRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.generate_access_token._get_unset_required_fields({}) + unset_fields = transport.push_credentials._get_unset_required_fields({}) assert set(unset_fields) == (set(()) & set(("workstation",))) -def test_generate_access_token_rest_flattened(): +def test_push_credentials_rest_flattened(): client = WorkstationsClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -13674,7 +14266,7 @@ def test_generate_access_token_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = workstations.GenerateAccessTokenResponse() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method sample_request = { @@ -13690,27 +14282,25 @@ def test_generate_access_token_rest_flattened(): # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = workstations.GenerateAccessTokenResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.generate_access_token(**mock_args) + client.push_credentials(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1beta/{workstation=projects/*/locations/*/workstationClusters/*/workstationConfigs/*/workstations/*}:generateAccessToken" + "%s/v1beta/{workstation=projects/*/locations/*/workstationClusters/*/workstationConfigs/*/workstations/*}:pushCredentials" % client.transport._host, args[1], ) -def test_generate_access_token_rest_flattened_error(transport: str = "rest"): +def test_push_credentials_rest_flattened_error(transport: str = "rest"): client = WorkstationsClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -13719,8 +14309,8 @@ def test_generate_access_token_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.generate_access_token( - workstations.GenerateAccessTokenRequest(), + client.push_credentials( + workstations.PushCredentialsRequest(), workstation="workstation_value", ) @@ -14267,6 +14857,26 @@ def test_generate_access_token_empty_call_grpc(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_push_credentials_empty_call_grpc(): + client = WorkstationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.push_credentials), "__call__") as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.push_credentials(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = workstations.PushCredentialsRequest() + assert args[0] == request_msg + + def test_transport_kind_grpc_asyncio(): transport = WorkstationsAsyncClient.get_transport_class("grpc_asyncio")( credentials=async_anonymous_credentials() @@ -14306,6 +14916,10 @@ async def test_get_workstation_cluster_empty_call_grpc_asyncio(): subnetwork="subnetwork_value", control_plane_ip="control_plane_ip_value", degraded=True, + satisfies_pzs=True, + satisfies_pzi=True, + workstation_authorization_url="workstation_authorization_url_value", + workstation_launch_url="workstation_launch_url_value", ) ) await client.get_workstation_cluster(request=None) @@ -14445,9 +15059,15 @@ async def test_get_workstation_config_empty_call_grpc_asyncio(): uid="uid_value", reconciling=True, etag="etag_value", + max_usable_workstations=2488, replica_zones=["replica_zones_value"], degraded=True, enable_audit_agent=True, + disable_tcp_connections=True, + satisfies_pzs=True, + satisfies_pzi=True, + grant_workstation_admin_role_on_create=True, + enable_pushing_credentials=True, ) ) await client.get_workstation_config(request=None) @@ -14616,6 +15236,11 @@ async def test_get_workstation_empty_call_grpc_asyncio(): etag="etag_value", state=workstations.Workstation.State.STATE_STARTING, host="host_value", + kms_key="kms_key_value", + source_workstation="source_workstation_value", + satisfies_pzs=True, + satisfies_pzi=True, + degraded=True, ) ) await client.get_workstation(request=None) @@ -14841,6 +15466,30 @@ async def test_generate_access_token_empty_call_grpc_asyncio(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_push_credentials_empty_call_grpc_asyncio(): + client = WorkstationsAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.push_credentials), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.push_credentials(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = workstations.PushCredentialsRequest() + assert args[0] == request_msg + + def test_transport_kind_rest(): transport = WorkstationsClient.get_transport_class("rest")( credentials=ga_credentials.AnonymousCredentials() @@ -14907,6 +15556,10 @@ def test_get_workstation_cluster_rest_call_success(request_type): subnetwork="subnetwork_value", control_plane_ip="control_plane_ip_value", degraded=True, + satisfies_pzs=True, + satisfies_pzi=True, + workstation_authorization_url="workstation_authorization_url_value", + workstation_launch_url="workstation_launch_url_value", ) # Wrap the value into a proper Response obj @@ -14932,6 +15585,12 @@ def test_get_workstation_cluster_rest_call_success(request_type): assert response.subnetwork == "subnetwork_value" assert response.control_plane_ip == "control_plane_ip_value" assert response.degraded is True + assert response.satisfies_pzs is True + assert response.satisfies_pzi is True + assert ( + response.workstation_authorization_url == "workstation_authorization_url_value" + ) + assert response.workstation_launch_url == "workstation_launch_url_value" @pytest.mark.parametrize("null_interceptor", [True, False]) @@ -15199,6 +15858,7 @@ def test_create_workstation_cluster_rest_call_success(request_type): "service_attachment_uri": "service_attachment_uri_value", "allowed_projects": ["allowed_projects_value1", "allowed_projects_value2"], }, + "domain_config": {"domain": "domain_value"}, "degraded": True, "conditions": [ { @@ -15212,6 +15872,12 @@ def test_create_workstation_cluster_rest_call_success(request_type): ], } ], + "satisfies_pzs": True, + "satisfies_pzi": True, + "tags": {}, + "gateway_config": {"http2_enabled": True}, + "workstation_authorization_url": "workstation_authorization_url_value", + "workstation_launch_url": "workstation_launch_url_value", } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -15436,6 +16102,7 @@ def test_update_workstation_cluster_rest_call_success(request_type): "service_attachment_uri": "service_attachment_uri_value", "allowed_projects": ["allowed_projects_value1", "allowed_projects_value2"], }, + "domain_config": {"domain": "domain_value"}, "degraded": True, "conditions": [ { @@ -15449,6 +16116,12 @@ def test_update_workstation_cluster_rest_call_success(request_type): ], } ], + "satisfies_pzs": True, + "satisfies_pzi": True, + "tags": {}, + "gateway_config": {"http2_enabled": True}, + "workstation_authorization_url": "workstation_authorization_url_value", + "workstation_launch_url": "workstation_launch_url_value", } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -15790,9 +16463,15 @@ def test_get_workstation_config_rest_call_success(request_type): uid="uid_value", reconciling=True, etag="etag_value", + max_usable_workstations=2488, replica_zones=["replica_zones_value"], degraded=True, enable_audit_agent=True, + disable_tcp_connections=True, + satisfies_pzs=True, + satisfies_pzi=True, + grant_workstation_admin_role_on_create=True, + enable_pushing_credentials=True, ) # Wrap the value into a proper Response obj @@ -15814,9 +16493,15 @@ def test_get_workstation_config_rest_call_success(request_type): assert response.uid == "uid_value" assert response.reconciling is True assert response.etag == "etag_value" + assert response.max_usable_workstations == 2488 assert response.replica_zones == ["replica_zones_value"] assert response.degraded is True assert response.enable_audit_agent is True + assert response.disable_tcp_connections is True + assert response.satisfies_pzs is True + assert response.satisfies_pzi is True + assert response.grant_workstation_admin_role_on_create is True + assert response.enable_pushing_credentials is True @pytest.mark.parametrize("null_interceptor", [True, False]) @@ -16231,6 +16916,7 @@ def test_create_workstation_config_rest_call_success(request_type): "etag": "etag_value", "idle_timeout": {"seconds": 751, "nanos": 543}, "running_timeout": {}, + "max_usable_workstations": 2488, "host": { "gce_instance": { "machine_type": "machine_type_value", @@ -16252,16 +16938,45 @@ def test_create_workstation_config_rest_call_success(request_type): "confidential_instance_config": {"enable_confidential_compute": True}, "boot_disk_size_gb": 1792, "accelerators": [{"type_": "type__value", "count": 553}], + "boost_configs": [ + { + "id": "id_value", + "machine_type": "machine_type_value", + "accelerators": {}, + "boot_disk_size_gb": 1792, + "enable_nested_virtualization": True, + "pool_size": 980, + "reservation_affinity": { + "consume_reservation_type": 1, + "key": "key_value", + "values": ["values_value1", "values_value2"], + }, + } + ], + "disable_ssh": True, + "vm_tags": {}, + "reservation_affinity": {}, + "startup_script_uri": "startup_script_uri_value", + "instance_metadata": {}, } }, "persistent_directories": [ { "gce_pd": { "size_gb": 739, + "max_size_gb": 1160, "fs_type": "fs_type_value", "disk_type": "disk_type_value", "source_snapshot": "source_snapshot_value", "reclaim_policy": 1, + "archive_timeout": {}, + }, + "gce_hd": { + "size_gb": 739, + "max_size_gb": 1160, + "source_snapshot": "source_snapshot_value", + "reclaim_policy": 1, + "archive_timeout": {}, }, "mount_path": "mount_path_value", } @@ -16305,6 +17020,16 @@ def test_create_workstation_config_rest_call_success(request_type): } ], "enable_audit_agent": True, + "http_options": { + "allowed_unauthenticated_cors_preflight_requests": True, + "disable_localhost_replacement": True, + }, + "disable_tcp_connections": True, + "allowed_ports": [{"first": 552, "last": 436}], + "satisfies_pzs": True, + "satisfies_pzi": True, + "grant_workstation_admin_role_on_create": True, + "enable_pushing_credentials": True, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -16522,6 +17247,7 @@ def test_update_workstation_config_rest_call_success(request_type): "etag": "etag_value", "idle_timeout": {"seconds": 751, "nanos": 543}, "running_timeout": {}, + "max_usable_workstations": 2488, "host": { "gce_instance": { "machine_type": "machine_type_value", @@ -16543,16 +17269,45 @@ def test_update_workstation_config_rest_call_success(request_type): "confidential_instance_config": {"enable_confidential_compute": True}, "boot_disk_size_gb": 1792, "accelerators": [{"type_": "type__value", "count": 553}], + "boost_configs": [ + { + "id": "id_value", + "machine_type": "machine_type_value", + "accelerators": {}, + "boot_disk_size_gb": 1792, + "enable_nested_virtualization": True, + "pool_size": 980, + "reservation_affinity": { + "consume_reservation_type": 1, + "key": "key_value", + "values": ["values_value1", "values_value2"], + }, + } + ], + "disable_ssh": True, + "vm_tags": {}, + "reservation_affinity": {}, + "startup_script_uri": "startup_script_uri_value", + "instance_metadata": {}, } }, "persistent_directories": [ { "gce_pd": { "size_gb": 739, + "max_size_gb": 1160, "fs_type": "fs_type_value", "disk_type": "disk_type_value", "source_snapshot": "source_snapshot_value", "reclaim_policy": 1, + "archive_timeout": {}, + }, + "gce_hd": { + "size_gb": 739, + "max_size_gb": 1160, + "source_snapshot": "source_snapshot_value", + "reclaim_policy": 1, + "archive_timeout": {}, }, "mount_path": "mount_path_value", } @@ -16596,6 +17351,16 @@ def test_update_workstation_config_rest_call_success(request_type): } ], "enable_audit_agent": True, + "http_options": { + "allowed_unauthenticated_cors_preflight_requests": True, + "disable_localhost_replacement": True, + }, + "disable_tcp_connections": True, + "allowed_ports": [{"first": 552, "last": 436}], + "satisfies_pzs": True, + "satisfies_pzi": True, + "grant_workstation_admin_role_on_create": True, + "enable_pushing_credentials": True, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -16939,6 +17704,11 @@ def test_get_workstation_rest_call_success(request_type): etag="etag_value", state=workstations.Workstation.State.STATE_STARTING, host="host_value", + kms_key="kms_key_value", + source_workstation="source_workstation_value", + satisfies_pzs=True, + satisfies_pzi=True, + degraded=True, ) # Wrap the value into a proper Response obj @@ -16962,6 +17732,11 @@ def test_get_workstation_rest_call_success(request_type): assert response.etag == "etag_value" assert response.state == workstations.Workstation.State.STATE_STARTING assert response.host == "host_value" + assert response.kms_key == "kms_key_value" + assert response.source_workstation == "source_workstation_value" + assert response.satisfies_pzs is True + assert response.satisfies_pzi is True + assert response.degraded is True @pytest.mark.parametrize("null_interceptor", [True, False]) @@ -17368,9 +18143,35 @@ def test_create_workstation_rest_call_success(request_type): "start_time": {}, "delete_time": {}, "etag": "etag_value", + "persistent_directories": [{"mount_path": "mount_path_value", "size_gb": 739}], "state": 1, "host": "host_value", "env": {}, + "kms_key": "kms_key_value", + "boost_configs": [{"id": "id_value", "running": True}], + "source_workstation": "source_workstation_value", + "satisfies_pzs": True, + "satisfies_pzi": True, + "runtime_host": { + "gce_instance_host": { + "name": "name_value", + "id": "id_value", + "zone": "zone_value", + } + }, + "degraded": True, + "conditions": [ + { + "code": 411, + "message": "message_value", + "details": [ + { + "type_url": "type.googleapis.com/google.protobuf.Duration", + "value": b"\x08\x0c\x10\xdb\x07", + } + ], + } + ], } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -17585,9 +18386,35 @@ def test_update_workstation_rest_call_success(request_type): "start_time": {}, "delete_time": {}, "etag": "etag_value", + "persistent_directories": [{"mount_path": "mount_path_value", "size_gb": 739}], "state": 1, "host": "host_value", "env": {}, + "kms_key": "kms_key_value", + "boost_configs": [{"id": "id_value", "running": True}], + "source_workstation": "source_workstation_value", + "satisfies_pzs": True, + "satisfies_pzi": True, + "runtime_host": { + "gce_instance_host": { + "name": "name_value", + "id": "id_value", + "zone": "zone_value", + } + }, + "degraded": True, + "conditions": [ + { + "code": 411, + "message": "message_value", + "details": [ + { + "type_url": "type.googleapis.com/google.protobuf.Duration", + "value": b"\x08\x0c\x10\xdb\x07", + } + ], + } + ], } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -18272,6 +19099,136 @@ def test_generate_access_token_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() +def test_push_credentials_rest_bad_request( + request_type=workstations.PushCredentialsRequest, +): + client = WorkstationsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "workstation": "projects/sample1/locations/sample2/workstationClusters/sample3/workstationConfigs/sample4/workstations/sample5" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.push_credentials(request) + + +@pytest.mark.parametrize( + "request_type", + [ + workstations.PushCredentialsRequest, + dict, + ], +) +def test_push_credentials_rest_call_success(request_type): + client = WorkstationsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "workstation": "projects/sample1/locations/sample2/workstationClusters/sample3/workstationConfigs/sample4/workstations/sample5" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.push_credentials(request) + + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_push_credentials_rest_interceptors(null_interceptor): + transport = transports.WorkstationsRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.WorkstationsRestInterceptor(), + ) + client = WorkstationsClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), + mock.patch.object( + transports.WorkstationsRestInterceptor, "post_push_credentials" + ) as post, + mock.patch.object( + transports.WorkstationsRestInterceptor, + "post_push_credentials_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.WorkstationsRestInterceptor, "pre_push_credentials" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = workstations.PushCredentialsRequest.pb( + workstations.PushCredentialsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value + + request = workstations.PushCredentialsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata + + client.push_credentials( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + def test_get_iam_policy_rest_bad_request( request_type=iam_policy_pb2.GetIamPolicyRequest, ): @@ -19151,6 +20108,25 @@ def test_generate_access_token_empty_call_rest(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_push_credentials_empty_call_rest(): + client = WorkstationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.push_credentials), "__call__") as call: + client.push_credentials(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = workstations.PushCredentialsRequest() + assert args[0] == request_msg + + def test_workstations_rest_lro_client(): client = WorkstationsClient( credentials=ga_credentials.AnonymousCredentials(), @@ -19221,6 +20197,7 @@ def test_workstations_base_transport(): "start_workstation", "stop_workstation", "generate_access_token", + "push_credentials", "set_iam_policy", "get_iam_policy", "test_iam_permissions", @@ -19555,6 +20532,9 @@ def test_workstations_client_transport_session_collision(transport_name): session1 = client1.transport.generate_access_token._session session2 = client2.transport.generate_access_token._session assert session1 != session2 + session1 = client1.transport.push_credentials._session + session2 = client2.transport.push_credentials._session + assert session1 != session2 def test_workstations_grpc_transport_channel(): From af1c6c89a6a8b4ecf62312e8694725a520f9d8b6 Mon Sep 17 00:00:00 2001 From: Noah Dietz Date: Fri, 5 Jun 2026 13:47:03 -0700 Subject: [PATCH 037/174] chore(librarian): use librarian pseudo-version (#17384) --- librarian.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librarian.yaml b/librarian.yaml index 2ff93a45f04d..929a95abd3da 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. language: python -version: v0.16.0 +version: v0.16.1-0.20260605194008-9ebe31201f8d repo: googleapis/google-cloud-python sources: googleapis: From 7611ac79e9ee762571c6a3c44060935923d336b9 Mon Sep 17 00:00:00 2001 From: Tomo Suzuki Date: Mon, 8 Jun 2026 11:27:10 -0400 Subject: [PATCH 038/174] feat(google/developers/knowledge/v1): add google-developers-knowledge (#17393) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit b/503382870 Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly: - [ ] Make sure to open an issue as a [bug/issue](https://github.com/googleapis/google-cloud-python/issues) before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea - [ ] Ensure the tests and linter pass - [ ] Code coverage does not decrease (if any source code was changed) - [ ] Appropriate docs were updated (if necessary) Fixes # 🦕 --- .librarian/state.yaml | 16 + librarian.yaml | 14 +- .../google-developers-knowledge/.coveragerc | 13 + packages/google-developers-knowledge/.flake8 | 34 + .../.repo-metadata.json | 16 + .../google-developers-knowledge/CHANGELOG.md | 5 + packages/google-developers-knowledge/LICENSE | 202 + .../google-developers-knowledge/MANIFEST.in | 20 + .../google-developers-knowledge/README.rst | 198 + .../docs/CHANGELOG.md | 1 + .../docs/README.rst | 198 + .../docs/_static/custom.css | 20 + .../docs/_templates/layout.html | 50 + .../google-developers-knowledge/docs/conf.py | 417 ++ .../developer_knowledge.rst | 10 + .../developers_knowledge_v1/services_.rst | 6 + .../docs/developers_knowledge_v1/types_.rst | 6 + .../docs/index.rst | 23 + .../docs/multiprocessing.rst | 7 + .../google/developers_knowledge/__init__.py | 49 + .../developers_knowledge/gapic_version.py | 16 + .../google/developers_knowledge/py.typed | 2 + .../developers_knowledge_v1/__init__.py | 135 + .../gapic_metadata.json | 73 + .../developers_knowledge_v1/gapic_version.py | 16 + .../google/developers_knowledge_v1/py.typed | 2 + .../services/__init__.py | 15 + .../services/developer_knowledge/__init__.py | 22 + .../developer_knowledge/async_client.py | 642 +++ .../services/developer_knowledge/client.py | 1067 +++++ .../services/developer_knowledge/pagers.py | 201 + .../developer_knowledge/transports/README.rst | 10 + .../transports/__init__.py | 36 + .../developer_knowledge/transports/base.py | 227 + .../developer_knowledge/transports/grpc.py | 449 ++ .../transports/grpc_asyncio.py | 502 ++ .../developer_knowledge/transports/rest.py | 855 ++++ .../transports/rest_base.py | 236 + .../developers_knowledge_v1/types/__init__.py | 36 + .../types/developerknowledge.py | 413 ++ packages/google-developers-knowledge/mypy.ini | 15 + .../google-developers-knowledge/noxfile.py | 639 +++ ...per_knowledge_batch_get_documents_async.py | 53 + ...oper_knowledge_batch_get_documents_sync.py | 53 + ..._developer_knowledge_get_document_async.py | 53 + ...d_developer_knowledge_get_document_sync.py | 53 + ..._knowledge_search_document_chunks_async.py | 54 + ...r_knowledge_search_document_chunks_sync.py | 54 + ...tadata_google.developers.knowledge.v1.json | 482 ++ packages/google-developers-knowledge/setup.py | 99 + .../testing/constraints-3.10.txt | 11 + .../testing/constraints-3.11.txt | 10 + .../testing/constraints-3.12.txt | 10 + .../testing/constraints-3.13.txt | 12 + .../testing/constraints-3.14.txt | 12 + .../tests/__init__.py | 15 + .../tests/unit/__init__.py | 15 + .../tests/unit/gapic/__init__.py | 15 + .../gapic/developers_knowledge_v1/__init__.py | 15 + .../test_developer_knowledge.py | 4268 +++++++++++++++++ 60 files changed, 12197 insertions(+), 1 deletion(-) create mode 100644 packages/google-developers-knowledge/.coveragerc create mode 100644 packages/google-developers-knowledge/.flake8 create mode 100644 packages/google-developers-knowledge/.repo-metadata.json create mode 100644 packages/google-developers-knowledge/CHANGELOG.md create mode 100644 packages/google-developers-knowledge/LICENSE create mode 100644 packages/google-developers-knowledge/MANIFEST.in create mode 100644 packages/google-developers-knowledge/README.rst create mode 120000 packages/google-developers-knowledge/docs/CHANGELOG.md create mode 100644 packages/google-developers-knowledge/docs/README.rst create mode 100644 packages/google-developers-knowledge/docs/_static/custom.css create mode 100644 packages/google-developers-knowledge/docs/_templates/layout.html create mode 100644 packages/google-developers-knowledge/docs/conf.py create mode 100644 packages/google-developers-knowledge/docs/developers_knowledge_v1/developer_knowledge.rst create mode 100644 packages/google-developers-knowledge/docs/developers_knowledge_v1/services_.rst create mode 100644 packages/google-developers-knowledge/docs/developers_knowledge_v1/types_.rst create mode 100644 packages/google-developers-knowledge/docs/index.rst create mode 100644 packages/google-developers-knowledge/docs/multiprocessing.rst create mode 100644 packages/google-developers-knowledge/google/developers_knowledge/__init__.py create mode 100644 packages/google-developers-knowledge/google/developers_knowledge/gapic_version.py create mode 100644 packages/google-developers-knowledge/google/developers_knowledge/py.typed create mode 100644 packages/google-developers-knowledge/google/developers_knowledge_v1/__init__.py create mode 100644 packages/google-developers-knowledge/google/developers_knowledge_v1/gapic_metadata.json create mode 100644 packages/google-developers-knowledge/google/developers_knowledge_v1/gapic_version.py create mode 100644 packages/google-developers-knowledge/google/developers_knowledge_v1/py.typed create mode 100644 packages/google-developers-knowledge/google/developers_knowledge_v1/services/__init__.py create mode 100644 packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/__init__.py create mode 100644 packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/async_client.py create mode 100644 packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/client.py create mode 100644 packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/pagers.py create mode 100644 packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/README.rst create mode 100644 packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/__init__.py create mode 100644 packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/base.py create mode 100644 packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/grpc.py create mode 100644 packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/grpc_asyncio.py create mode 100644 packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/rest.py create mode 100644 packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/rest_base.py create mode 100644 packages/google-developers-knowledge/google/developers_knowledge_v1/types/__init__.py create mode 100644 packages/google-developers-knowledge/google/developers_knowledge_v1/types/developerknowledge.py create mode 100644 packages/google-developers-knowledge/mypy.ini create mode 100644 packages/google-developers-knowledge/noxfile.py create mode 100644 packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_batch_get_documents_async.py create mode 100644 packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_batch_get_documents_sync.py create mode 100644 packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_get_document_async.py create mode 100644 packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_get_document_sync.py create mode 100644 packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_search_document_chunks_async.py create mode 100644 packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_search_document_chunks_sync.py create mode 100644 packages/google-developers-knowledge/samples/generated_samples/snippet_metadata_google.developers.knowledge.v1.json create mode 100644 packages/google-developers-knowledge/setup.py create mode 100644 packages/google-developers-knowledge/testing/constraints-3.10.txt create mode 100644 packages/google-developers-knowledge/testing/constraints-3.11.txt create mode 100644 packages/google-developers-knowledge/testing/constraints-3.12.txt create mode 100644 packages/google-developers-knowledge/testing/constraints-3.13.txt create mode 100644 packages/google-developers-knowledge/testing/constraints-3.14.txt create mode 100644 packages/google-developers-knowledge/tests/__init__.py create mode 100644 packages/google-developers-knowledge/tests/unit/__init__.py create mode 100644 packages/google-developers-knowledge/tests/unit/gapic/__init__.py create mode 100644 packages/google-developers-knowledge/tests/unit/gapic/developers_knowledge_v1/__init__.py create mode 100644 packages/google-developers-knowledge/tests/unit/gapic/developers_knowledge_v1/test_developer_knowledge.py diff --git a/.librarian/state.yaml b/.librarian/state.yaml index cd38250abfb4..2dc84d100e05 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -5404,6 +5404,22 @@ libraries: - packages/google-crc32c/README.rst - packages/google-crc32c/docs/ tag_format: '{id}-v{version}' + - id: google-developers-knowledge + version: 0.0.0 + last_generated_commit: "" + apis: + - path: google/developers/knowledge/v1 + source_roots: + - packages/google-developers-knowledge + preserve_regex: [] + remove_regex: [] + release_exclude_paths: + - packages/google-developers-knowledge/.repo-metadata.json + - packages/google-developers-knowledge/noxfile.py + - packages/google-developers-knowledge/tests/ + - packages/google-developers-knowledge/README.rst + - packages/google-developers-knowledge/docs/ + tag_format: '{id}-v{version}' - id: google-devicesandservices-health version: 0.0.0 last_generated_commit: "" diff --git a/librarian.yaml b/librarian.yaml index 929a95abd3da..20c52d69e5a1 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. language: python -version: v0.16.1-0.20260605194008-9ebe31201f8d +version: v0.16.0 repo: googleapis/google-cloud-python sources: googleapis: @@ -29,6 +29,7 @@ default: - google.maps - google.shopping - google.devicesandservices + - google.developers common_gapic_paths: - samples/generated_samples - tests/unit/gapic @@ -2218,6 +2219,17 @@ libraries: skip_release: true python: library_type: OTHER + - name: google-developers-knowledge + version: 0.0.0 + apis: + - path: google/developers/knowledge/v1 + copyright_year: "2026" + python: + opt_args_by_api: + google/developers/knowledge/v1: + - python-gapic-namespace=google + - python-gapic-name=developers_knowledge + default_version: v1 - name: google-devicesandservices-health version: 0.0.0 apis: diff --git a/packages/google-developers-knowledge/.coveragerc b/packages/google-developers-knowledge/.coveragerc new file mode 100644 index 000000000000..2eb560db0b14 --- /dev/null +++ b/packages/google-developers-knowledge/.coveragerc @@ -0,0 +1,13 @@ +[run] +branch = True + +[report] +show_missing = True +omit = + google/developers_knowledge/__init__.py + google/developers_knowledge/gapic_version.py +exclude_lines = + # Re-enable the standard pragma + pragma: NO COVER + # Ignore debug-only repr + def __repr__ diff --git a/packages/google-developers-knowledge/.flake8 b/packages/google-developers-knowledge/.flake8 new file mode 100644 index 000000000000..f9069a84687b --- /dev/null +++ b/packages/google-developers-knowledge/.flake8 @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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. +# +[flake8] +# TODO(https://github.com/googleapis/gapic-generator-python/issues/2333): +# Resolve flake8 lint issues +ignore = E203, E231, E266, E501, W503 +exclude = + # TODO(https://github.com/googleapis/gapic-generator-python/issues/2333): + # Ensure that generated code passes flake8 lint + **/gapic/** + **/services/** + **/types/** + # Exclude Protobuf gencode + *_pb2.py + + # Standard linting exemptions. + **/.nox/** + __pycache__, + .git, + *.pyc, + conf.py diff --git a/packages/google-developers-knowledge/.repo-metadata.json b/packages/google-developers-knowledge/.repo-metadata.json new file mode 100644 index 000000000000..4195a25dae2a --- /dev/null +++ b/packages/google-developers-knowledge/.repo-metadata.json @@ -0,0 +1,16 @@ +{ + "api_description": "The Developer Knowledge API provides access to Google's developer knowledge.", + "api_id": "developerknowledge.googleapis.com", + "api_shortname": "developerknowledge", + "client_documentation": "https://googleapis.dev/python/google-developers-knowledge/latest", + "default_version": "v1", + "distribution_name": "google-developers-knowledge", + "issue_tracker": "https://issuetracker.google.com/issues/new?component=190865\u0026template=1161103", + "language": "python", + "library_type": "GAPIC_AUTO", + "name": "google-developers-knowledge", + "name_pretty": "Developer Knowledge", + "product_documentation": "https://developers.google.com/knowledge", + "release_level": "preview", + "repo": "googleapis/google-cloud-python" +} \ No newline at end of file diff --git a/packages/google-developers-knowledge/CHANGELOG.md b/packages/google-developers-knowledge/CHANGELOG.md new file mode 100644 index 000000000000..6abef3a7fecc --- /dev/null +++ b/packages/google-developers-knowledge/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +[PyPI History][1] + +[1]: https://pypi.org/project/google-developers-knowledge/#history diff --git a/packages/google-developers-knowledge/LICENSE b/packages/google-developers-knowledge/LICENSE new file mode 100644 index 000000000000..d64569567334 --- /dev/null +++ b/packages/google-developers-knowledge/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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/packages/google-developers-knowledge/MANIFEST.in b/packages/google-developers-knowledge/MANIFEST.in new file mode 100644 index 000000000000..f932577add9d --- /dev/null +++ b/packages/google-developers-knowledge/MANIFEST.in @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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. +# +include README.rst LICENSE +recursive-include google *.py *.pyi *.json *.proto py.typed +recursive-include tests * +global-exclude *.py[co] +global-exclude __pycache__ diff --git a/packages/google-developers-knowledge/README.rst b/packages/google-developers-knowledge/README.rst new file mode 100644 index 000000000000..c11f928f2ee9 --- /dev/null +++ b/packages/google-developers-knowledge/README.rst @@ -0,0 +1,198 @@ +Python Client for Developer Knowledge +===================================== + +|preview| |pypi| |versions| + +`Developer Knowledge`_: The Developer Knowledge API provides access to Google's developer knowledge. + +- `Client Library Documentation`_ +- `Product Documentation`_ + +.. |preview| image:: https://img.shields.io/badge/support-preview-orange.svg + :target: https://github.com/googleapis/google-cloud-python/blob/main/README.rst#stability-levels +.. |pypi| image:: https://img.shields.io/pypi/v/google-developers-knowledge.svg + :target: https://pypi.org/project/google-developers-knowledge/ +.. |versions| image:: https://img.shields.io/pypi/pyversions/google-developers-knowledge.svg + :target: https://pypi.org/project/google-developers-knowledge/ +.. _Developer Knowledge: https://developers.google.com/knowledge +.. _Client Library Documentation: https://googleapis.dev/python/google-developers-knowledge/latest +.. _Product Documentation: https://developers.google.com/knowledge + +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 Developer Knowledge.`_ +4. `Set up 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 +.. _Enable the Developer Knowledge.: https://developers.google.com/knowledge +.. _Set up Authentication.: https://googleapis.dev/python/google-api-core/latest/auth.html + +Installation +~~~~~~~~~~~~ + +Install this library in a virtual environment using `venv`_. `venv`_ is a tool that +creates isolated Python environments. These isolated environments can have separate +versions of Python packages, which allows you to isolate one project's dependencies +from the dependencies of other projects. + +With `venv`_, it's possible to install this library without needing system +install permissions, and without clashing with the installed system +dependencies. + +.. _`venv`: https://docs.python.org/3/library/venv.html + + +Code samples and snippets +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Code samples and snippets live in the `samples/`_ folder. + +.. _samples/: https://github.com/googleapis/google-cloud-python/tree/main/packages/google-developers-knowledge/samples + + +Supported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^ +Our client libraries are compatible with all current `active`_ and `maintenance`_ versions of +Python. + +Python >= 3.10, including 3.14 + +.. _active: https://devguide.python.org/devcycle/#in-development-main-branch +.. _maintenance: https://devguide.python.org/devcycle/#maintenance-branches + +Unsupported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Python <= 3.9 + + +If you are using an `end-of-life`_ +version of Python, we recommend that you update as soon as possible to an actively supported version. + +.. _end-of-life: https://devguide.python.org/devcycle/#end-of-life-branches + +Mac/Linux +^^^^^^^^^ + +.. code-block:: console + + python3 -m venv + source /bin/activate + pip install google-developers-knowledge + + +Windows +^^^^^^^ + +.. code-block:: console + + py -m venv + .\\Scripts\activate + pip install google-developers-knowledge + +Next Steps +~~~~~~~~~~ + +- Read the `Client Library Documentation`_ for Developer Knowledge + to see other available methods on the client. +- Read the `Developer Knowledge Product documentation`_ to learn + more about the product and see How-to Guides. +- View this `README`_ to see the full list of Cloud + APIs that we cover. + +.. _Developer Knowledge Product documentation: https://developers.google.com/knowledge +.. _README: https://github.com/googleapis/google-cloud-python/blob/main/README.rst + +Logging +------- + +This library uses the standard Python :code:`logging` functionality to log some RPC events that could be of interest for debugging and monitoring purposes. +Note the following: + +#. Logs may contain sensitive information. Take care to **restrict access to the logs** if they are saved, whether it be on local storage or on Google Cloud Logging. +#. Google may refine the occurrence, level, and content of various log messages in this library without flagging such changes as breaking. **Do not depend on immutability of the logging events**. +#. By default, the logging events from this library are not handled. You must **explicitly configure log handling** using one of the mechanisms below. + +Simple, environment-based configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To enable logging for this library without any changes in your code, set the :code:`GOOGLE_SDK_PYTHON_LOGGING_SCOPE` environment variable to a valid Google +logging scope. This configures handling of logging events (at level :code:`logging.DEBUG` or higher) from this library in a default manner, emitting the logged +messages in a structured format. It does not currently allow customizing the logging levels captured nor the handlers, formatters, etc. used for any logging +event. + +A logging scope is a period-separated namespace that begins with :code:`google`, identifying the Python module or package to log. + +- Valid logging scopes: :code:`google`, :code:`google.cloud.asset.v1`, :code:`google.api`, :code:`google.auth`, etc. +- Invalid logging scopes: :code:`foo`, :code:`123`, etc. + +**NOTE**: If the logging scope is invalid, the library does not set up any logging handlers. + +Environment-Based Examples +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Enabling the default handler for all Google-based loggers + +.. code-block:: console + + export GOOGLE_SDK_PYTHON_LOGGING_SCOPE=google + +- Enabling the default handler for a specific Google module (for a client library called :code:`library_v1`): + +.. code-block:: console + + export GOOGLE_SDK_PYTHON_LOGGING_SCOPE=google.cloud.library_v1 + + +Advanced, code-based configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can also configure a valid logging scope using Python's standard `logging` mechanism. + +Code-Based Examples +^^^^^^^^^^^^^^^^^^^ + +- Configuring a handler for all Google-based loggers + +.. code-block:: python + + import logging + + from google.cloud import library_v1 + + base_logger = logging.getLogger("google") + base_logger.addHandler(logging.StreamHandler()) + base_logger.setLevel(logging.DEBUG) + +- Configuring a handler for a specific Google module (for a client library called :code:`library_v1`): + +.. code-block:: python + + import logging + + from google.cloud import library_v1 + + base_logger = logging.getLogger("google.cloud.library_v1") + base_logger.addHandler(logging.StreamHandler()) + base_logger.setLevel(logging.DEBUG) + +Logging details +~~~~~~~~~~~~~~~ + +#. Regardless of which of the mechanisms above you use to configure logging for this library, by default logging events are not propagated up to the root + logger from the `google`-level logger. If you need the events to be propagated to the root logger, you must explicitly set + :code:`logging.getLogger("google").propagate = True` in your code. +#. You can mix the different logging configurations above for different Google modules. For example, you may want use a code-based logging configuration for + one library, but decide you need to also set up environment-based logging configuration for another library. + + #. If you attempt to use both code-based and environment-based configuration for the same module, the environment-based configuration will be ineffectual + if the code -based configuration gets applied first. + +#. The Google-specific logging configurations (default handlers for environment-based configuration; not propagating logging events to the root logger) get + executed the first time *any* client library is instantiated in your application, and only if the affected loggers have not been previously configured. + (This is the reason for 2.i. above.) diff --git a/packages/google-developers-knowledge/docs/CHANGELOG.md b/packages/google-developers-knowledge/docs/CHANGELOG.md new file mode 120000 index 000000000000..04c99a55caae --- /dev/null +++ b/packages/google-developers-knowledge/docs/CHANGELOG.md @@ -0,0 +1 @@ +../CHANGELOG.md \ No newline at end of file diff --git a/packages/google-developers-knowledge/docs/README.rst b/packages/google-developers-knowledge/docs/README.rst new file mode 100644 index 000000000000..c11f928f2ee9 --- /dev/null +++ b/packages/google-developers-knowledge/docs/README.rst @@ -0,0 +1,198 @@ +Python Client for Developer Knowledge +===================================== + +|preview| |pypi| |versions| + +`Developer Knowledge`_: The Developer Knowledge API provides access to Google's developer knowledge. + +- `Client Library Documentation`_ +- `Product Documentation`_ + +.. |preview| image:: https://img.shields.io/badge/support-preview-orange.svg + :target: https://github.com/googleapis/google-cloud-python/blob/main/README.rst#stability-levels +.. |pypi| image:: https://img.shields.io/pypi/v/google-developers-knowledge.svg + :target: https://pypi.org/project/google-developers-knowledge/ +.. |versions| image:: https://img.shields.io/pypi/pyversions/google-developers-knowledge.svg + :target: https://pypi.org/project/google-developers-knowledge/ +.. _Developer Knowledge: https://developers.google.com/knowledge +.. _Client Library Documentation: https://googleapis.dev/python/google-developers-knowledge/latest +.. _Product Documentation: https://developers.google.com/knowledge + +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 Developer Knowledge.`_ +4. `Set up 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 +.. _Enable the Developer Knowledge.: https://developers.google.com/knowledge +.. _Set up Authentication.: https://googleapis.dev/python/google-api-core/latest/auth.html + +Installation +~~~~~~~~~~~~ + +Install this library in a virtual environment using `venv`_. `venv`_ is a tool that +creates isolated Python environments. These isolated environments can have separate +versions of Python packages, which allows you to isolate one project's dependencies +from the dependencies of other projects. + +With `venv`_, it's possible to install this library without needing system +install permissions, and without clashing with the installed system +dependencies. + +.. _`venv`: https://docs.python.org/3/library/venv.html + + +Code samples and snippets +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Code samples and snippets live in the `samples/`_ folder. + +.. _samples/: https://github.com/googleapis/google-cloud-python/tree/main/packages/google-developers-knowledge/samples + + +Supported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^ +Our client libraries are compatible with all current `active`_ and `maintenance`_ versions of +Python. + +Python >= 3.10, including 3.14 + +.. _active: https://devguide.python.org/devcycle/#in-development-main-branch +.. _maintenance: https://devguide.python.org/devcycle/#maintenance-branches + +Unsupported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Python <= 3.9 + + +If you are using an `end-of-life`_ +version of Python, we recommend that you update as soon as possible to an actively supported version. + +.. _end-of-life: https://devguide.python.org/devcycle/#end-of-life-branches + +Mac/Linux +^^^^^^^^^ + +.. code-block:: console + + python3 -m venv + source /bin/activate + pip install google-developers-knowledge + + +Windows +^^^^^^^ + +.. code-block:: console + + py -m venv + .\\Scripts\activate + pip install google-developers-knowledge + +Next Steps +~~~~~~~~~~ + +- Read the `Client Library Documentation`_ for Developer Knowledge + to see other available methods on the client. +- Read the `Developer Knowledge Product documentation`_ to learn + more about the product and see How-to Guides. +- View this `README`_ to see the full list of Cloud + APIs that we cover. + +.. _Developer Knowledge Product documentation: https://developers.google.com/knowledge +.. _README: https://github.com/googleapis/google-cloud-python/blob/main/README.rst + +Logging +------- + +This library uses the standard Python :code:`logging` functionality to log some RPC events that could be of interest for debugging and monitoring purposes. +Note the following: + +#. Logs may contain sensitive information. Take care to **restrict access to the logs** if they are saved, whether it be on local storage or on Google Cloud Logging. +#. Google may refine the occurrence, level, and content of various log messages in this library without flagging such changes as breaking. **Do not depend on immutability of the logging events**. +#. By default, the logging events from this library are not handled. You must **explicitly configure log handling** using one of the mechanisms below. + +Simple, environment-based configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To enable logging for this library without any changes in your code, set the :code:`GOOGLE_SDK_PYTHON_LOGGING_SCOPE` environment variable to a valid Google +logging scope. This configures handling of logging events (at level :code:`logging.DEBUG` or higher) from this library in a default manner, emitting the logged +messages in a structured format. It does not currently allow customizing the logging levels captured nor the handlers, formatters, etc. used for any logging +event. + +A logging scope is a period-separated namespace that begins with :code:`google`, identifying the Python module or package to log. + +- Valid logging scopes: :code:`google`, :code:`google.cloud.asset.v1`, :code:`google.api`, :code:`google.auth`, etc. +- Invalid logging scopes: :code:`foo`, :code:`123`, etc. + +**NOTE**: If the logging scope is invalid, the library does not set up any logging handlers. + +Environment-Based Examples +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Enabling the default handler for all Google-based loggers + +.. code-block:: console + + export GOOGLE_SDK_PYTHON_LOGGING_SCOPE=google + +- Enabling the default handler for a specific Google module (for a client library called :code:`library_v1`): + +.. code-block:: console + + export GOOGLE_SDK_PYTHON_LOGGING_SCOPE=google.cloud.library_v1 + + +Advanced, code-based configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can also configure a valid logging scope using Python's standard `logging` mechanism. + +Code-Based Examples +^^^^^^^^^^^^^^^^^^^ + +- Configuring a handler for all Google-based loggers + +.. code-block:: python + + import logging + + from google.cloud import library_v1 + + base_logger = logging.getLogger("google") + base_logger.addHandler(logging.StreamHandler()) + base_logger.setLevel(logging.DEBUG) + +- Configuring a handler for a specific Google module (for a client library called :code:`library_v1`): + +.. code-block:: python + + import logging + + from google.cloud import library_v1 + + base_logger = logging.getLogger("google.cloud.library_v1") + base_logger.addHandler(logging.StreamHandler()) + base_logger.setLevel(logging.DEBUG) + +Logging details +~~~~~~~~~~~~~~~ + +#. Regardless of which of the mechanisms above you use to configure logging for this library, by default logging events are not propagated up to the root + logger from the `google`-level logger. If you need the events to be propagated to the root logger, you must explicitly set + :code:`logging.getLogger("google").propagate = True` in your code. +#. You can mix the different logging configurations above for different Google modules. For example, you may want use a code-based logging configuration for + one library, but decide you need to also set up environment-based logging configuration for another library. + + #. If you attempt to use both code-based and environment-based configuration for the same module, the environment-based configuration will be ineffectual + if the code -based configuration gets applied first. + +#. The Google-specific logging configurations (default handlers for environment-based configuration; not propagating logging events to the root logger) get + executed the first time *any* client library is instantiated in your application, and only if the affected loggers have not been previously configured. + (This is the reason for 2.i. above.) diff --git a/packages/google-developers-knowledge/docs/_static/custom.css b/packages/google-developers-knowledge/docs/_static/custom.css new file mode 100644 index 000000000000..b0a295464b23 --- /dev/null +++ b/packages/google-developers-knowledge/docs/_static/custom.css @@ -0,0 +1,20 @@ +div#python2-eol { + border-color: red; + border-width: medium; +} + +/* Ensure minimum width for 'Parameters' / 'Returns' column */ +dl.field-list > dt { + min-width: 100px +} + +/* Insert space between methods for readability */ +dl.method { + padding-top: 10px; + padding-bottom: 10px +} + +/* Insert empty space between classes */ +dl.class { + padding-bottom: 50px +} diff --git a/packages/google-developers-knowledge/docs/_templates/layout.html b/packages/google-developers-knowledge/docs/_templates/layout.html new file mode 100644 index 000000000000..95e9c77fcfe1 --- /dev/null +++ b/packages/google-developers-knowledge/docs/_templates/layout.html @@ -0,0 +1,50 @@ + +{% extends "!layout.html" %} +{%- block content %} +{%- if theme_fixed_sidebar|lower == 'true' %} +
+ {{ sidebar() }} + {%- block document %} +
+ {%- if render_sidebar %} +
+ {%- endif %} + + {%- block relbar_top %} + {%- if theme_show_relbar_top|tobool %} + + {%- endif %} + {% endblock %} + +
+
+ As of January 1, 2020 this library no longer supports Python 2 on the latest released version. + Library versions released prior to that date will continue to be available. For more information please + visit Python 2 support on Google Cloud. +
+ {% block body %} {% endblock %} +
+ + {%- block relbar_bottom %} + {%- if theme_show_relbar_bottom|tobool %} + + {%- endif %} + {% endblock %} + + {%- if render_sidebar %} +
+ {%- endif %} +
+ {%- endblock %} +
+
+{%- else %} +{{ super() }} +{%- endif %} +{%- endblock %} diff --git a/packages/google-developers-knowledge/docs/conf.py b/packages/google-developers-knowledge/docs/conf.py new file mode 100644 index 000000000000..465dfefb7d33 --- /dev/null +++ b/packages/google-developers-knowledge/docs/conf.py @@ -0,0 +1,417 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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-developers-knowledge 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 logging +import os +import shlex +import sys +from typing import Any + +# 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("..")) + +# For plugins that can not read conf.py. +# See also: https://github.com/docascode/sphinx-docfx-yaml/issues/85 +sys.path.insert(0, os.path.abspath(".")) + +__version__ = "" + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +needs_sphinx = "4.5.0" + +# 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.doctest", + "sphinx.ext.napoleon", + "sphinx.ext.todo", + "sphinx.ext.viewcode", + "recommonmark", +] + +# autodoc/autosummary flags +autoclass_content = "both" +autodoc_default_options = {"members": True} +autosummary_generate = True + + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# source_suffix = ['.rst', '.md'] +source_suffix = [".rst", ".md"] + +# The encoding of source files. +# source_encoding = 'utf-8-sig' + +# The root toctree document. +root_doc = "index" + +# General information about the project. +project = "google-developers-knowledge" +copyright = "2026, Google, LLC" +author = "Google APIs" + +# 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", + "**/.nox/**/*", + "samples/AUTHORING_GUIDE.md", + "samples/CONTRIBUTING.md", + "samples/snippets/README.rst", +] + +# 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 Client Libraries for google-developers-knowledge", + "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-developers-knowledge-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 = [ + ( + root_doc, + "google-developers-knowledge.tex", + "google-developers-knowledge 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 = [ + ( + root_doc, + "google-developers-knowledge", + "google-developers-knowledge 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 = [ + ( + root_doc, + "google-developers-knowledge", + "google-developers-knowledge Documentation", + author, + "google-developers-knowledge", + "google-developers-knowledge Library", + "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": ("https://python.readthedocs.org/en/latest/", None), + "google-auth": ("https://googleapis.dev/python/google-auth/latest/", None), + "google.api_core": ( + "https://googleapis.dev/python/google-api-core/latest/", + None, + ), + "grpc": ("https://grpc.github.io/grpc/python/", None), + "proto-plus": ("https://proto-plus-python.readthedocs.io/en/latest/", None), + "protobuf": ("https://googleapis.dev/python/protobuf/latest/", None), +} + + +# 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 + + +# Setup for sphinx behaviors such as warning filters. +class UnexpectedUnindentFilter(logging.Filter): + """Filter out warnings about unexpected unindentation following bullet lists.""" + + def filter(self, record: logging.LogRecord) -> bool: + """Filter the log record. + + Args: + record (logging.LogRecord): The log record. + + Returns: + bool: False to suppress the warning, True to allow it. + """ + msg = record.getMessage() + if "Bullet list ends without a blank line" in msg: + return False + return True + + +def setup(app: Any) -> None: + """Setup the Sphinx application. + + Args: + app (Any): The Sphinx application. + """ + # Sphinx's logger is hierarchical. Adding a filter to the + # root 'sphinx' logger will catch warnings from all sub-loggers. + logger = logging.getLogger("sphinx") + logger.addFilter(UnexpectedUnindentFilter()) diff --git a/packages/google-developers-knowledge/docs/developers_knowledge_v1/developer_knowledge.rst b/packages/google-developers-knowledge/docs/developers_knowledge_v1/developer_knowledge.rst new file mode 100644 index 000000000000..fbfc3c907022 --- /dev/null +++ b/packages/google-developers-knowledge/docs/developers_knowledge_v1/developer_knowledge.rst @@ -0,0 +1,10 @@ +DeveloperKnowledge +------------------------------------ + +.. automodule:: google.developers_knowledge_v1.services.developer_knowledge + :members: + :inherited-members: + +.. automodule:: google.developers_knowledge_v1.services.developer_knowledge.pagers + :members: + :inherited-members: diff --git a/packages/google-developers-knowledge/docs/developers_knowledge_v1/services_.rst b/packages/google-developers-knowledge/docs/developers_knowledge_v1/services_.rst new file mode 100644 index 000000000000..7073d3f33ded --- /dev/null +++ b/packages/google-developers-knowledge/docs/developers_knowledge_v1/services_.rst @@ -0,0 +1,6 @@ +Services for Google Developers Knowledge v1 API +=============================================== +.. toctree:: + :maxdepth: 2 + + developer_knowledge diff --git a/packages/google-developers-knowledge/docs/developers_knowledge_v1/types_.rst b/packages/google-developers-knowledge/docs/developers_knowledge_v1/types_.rst new file mode 100644 index 000000000000..66703edbc136 --- /dev/null +++ b/packages/google-developers-knowledge/docs/developers_knowledge_v1/types_.rst @@ -0,0 +1,6 @@ +Types for Google Developers Knowledge v1 API +============================================ + +.. automodule:: google.developers_knowledge_v1.types + :members: + :show-inheritance: diff --git a/packages/google-developers-knowledge/docs/index.rst b/packages/google-developers-knowledge/docs/index.rst new file mode 100644 index 000000000000..83367bc76281 --- /dev/null +++ b/packages/google-developers-knowledge/docs/index.rst @@ -0,0 +1,23 @@ +.. include:: README.rst + +.. include:: multiprocessing.rst + + +API Reference +------------- +.. toctree:: + :maxdepth: 2 + + developers_knowledge_v1/services_ + developers_knowledge_v1/types_ + + +Changelog +--------- + +For a list of all ``google-developers-knowledge`` releases: + +.. toctree:: + :maxdepth: 2 + + CHANGELOG diff --git a/packages/google-developers-knowledge/docs/multiprocessing.rst b/packages/google-developers-knowledge/docs/multiprocessing.rst new file mode 100644 index 000000000000..536d17b2ea65 --- /dev/null +++ b/packages/google-developers-knowledge/docs/multiprocessing.rst @@ -0,0 +1,7 @@ +.. note:: + + Because this client uses :mod:`grpc` library, it is safe to + share instances across threads. In multiprocessing scenarios, the best + practice is to create client instances *after* the invocation of + :func:`os.fork` by :class:`multiprocessing.pool.Pool` or + :class:`multiprocessing.Process`. diff --git a/packages/google-developers-knowledge/google/developers_knowledge/__init__.py b/packages/google-developers-knowledge/google/developers_knowledge/__init__.py new file mode 100644 index 000000000000..e5e9b8075191 --- /dev/null +++ b/packages/google-developers-knowledge/google/developers_knowledge/__init__.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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.developers_knowledge import gapic_version as package_version + +__version__ = package_version.__version__ + + +from google.developers_knowledge_v1.services.developer_knowledge.async_client import ( + DeveloperKnowledgeAsyncClient, +) +from google.developers_knowledge_v1.services.developer_knowledge.client import ( + DeveloperKnowledgeClient, +) +from google.developers_knowledge_v1.types.developerknowledge import ( + BatchGetDocumentsRequest, + BatchGetDocumentsResponse, + Document, + DocumentChunk, + DocumentView, + GetDocumentRequest, + SearchDocumentChunksRequest, + SearchDocumentChunksResponse, +) + +__all__ = ( + "DeveloperKnowledgeClient", + "DeveloperKnowledgeAsyncClient", + "BatchGetDocumentsRequest", + "BatchGetDocumentsResponse", + "Document", + "DocumentChunk", + "GetDocumentRequest", + "SearchDocumentChunksRequest", + "SearchDocumentChunksResponse", + "DocumentView", +) diff --git a/packages/google-developers-knowledge/google/developers_knowledge/gapic_version.py b/packages/google-developers-knowledge/google/developers_knowledge/gapic_version.py new file mode 100644 index 000000000000..e89a0031d71b --- /dev/null +++ b/packages/google-developers-knowledge/google/developers_knowledge/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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. +# +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-developers-knowledge/google/developers_knowledge/py.typed b/packages/google-developers-knowledge/google/developers_knowledge/py.typed new file mode 100644 index 000000000000..184e0e4d53ea --- /dev/null +++ b/packages/google-developers-knowledge/google/developers_knowledge/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-developers-knowledge package uses inline types. diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/__init__.py b/packages/google-developers-knowledge/google/developers_knowledge_v1/__init__.py new file mode 100644 index 000000000000..e9e476db76c8 --- /dev/null +++ b/packages/google-developers-knowledge/google/developers_knowledge_v1/__init__.py @@ -0,0 +1,135 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 sys + +import google.api_core as api_core + +from google.developers_knowledge_v1 import gapic_version as package_version + +__version__ = package_version.__version__ + +from importlib import metadata + +from .services.developer_knowledge import ( + DeveloperKnowledgeAsyncClient, + DeveloperKnowledgeClient, +) +from .types.developerknowledge import ( + BatchGetDocumentsRequest, + BatchGetDocumentsResponse, + Document, + DocumentChunk, + DocumentView, + GetDocumentRequest, + SearchDocumentChunksRequest, + SearchDocumentChunksResponse, +) + +if hasattr(api_core, "check_python_version") and hasattr( + api_core, "check_dependency_versions" +): # pragma: NO COVER + api_core.check_python_version("google.developers_knowledge_v1") # type: ignore + api_core.check_dependency_versions("google.developers_knowledge_v1") # type: ignore +else: # pragma: NO COVER + # An older version of api_core is installed which does not define the + # functions above. We do equivalent checks manually. + try: + import warnings + + _py_version_str = sys.version.split()[0] + _package_label = "google.developers_knowledge_v1" + if sys.version_info < (3, 10): + warnings.warn( + "You are using a non-supported Python version " + + f"({_py_version_str}). Google will not post any further " + + f"updates to {_package_label} supporting this Python version. " + + "Please upgrade to the latest Python version, or at " + + f"least to Python 3.10, and then update {_package_label}.", + FutureWarning, + ) + + def parse_version_to_tuple(version_string: str): + """Safely converts a semantic version string to a comparable tuple of integers. + Example: "4.25.8" -> (4, 25, 8) + Ignores non-numeric parts and handles common version formats. + Args: + version_string: Version string in the format "x.y.z" or "x.y.z" + Returns: + Tuple of integers for the parsed version string. + """ + parts = [] + for part in version_string.split("."): + try: + parts.append(int(part)) + except ValueError: + # If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here. + # This is a simplification compared to 'packaging.parse_version', but sufficient + # for comparing strictly numeric semantic versions. + break + return tuple(parts) + + def _get_version(dependency_name): + try: + version_string: str = metadata.version(dependency_name) + parsed_version = parse_version_to_tuple(version_string) + return (parsed_version, version_string) + except Exception: + # Catch exceptions from metadata.version() (e.g., PackageNotFoundError) + # or errors during parse_version_to_tuple + return (None, "--") + + _dependency_package = "google.protobuf" + _next_supported_version = "4.25.8" + _next_supported_version_tuple = (4, 25, 8) + _recommendation = " (we recommend 6.x)" + (_version_used, _version_used_string) = _get_version(_dependency_package) + if _version_used and _version_used < _next_supported_version_tuple: + warnings.warn( + f"Package {_package_label} depends on " + + f"{_dependency_package}, currently installed at version " + + f"{_version_used_string}. Future updates to " + + f"{_package_label} will require {_dependency_package} at " + + f"version {_next_supported_version} or higher{_recommendation}." + + " Please ensure " + + "that either (a) your Python environment doesn't pin the " + + f"version of {_dependency_package}, so that updates to " + + f"{_package_label} can require the higher version, or " + + "(b) you manually update your Python environment to use at " + + f"least version {_next_supported_version} of " + + f"{_dependency_package}.", + FutureWarning, + ) + except Exception: + warnings.warn( + "Could not determine the version of Python " + + "currently being used. To continue receiving " + + "updates for {_package_label}, ensure you are " + + "using a supported version of Python; see " + + "https://devguide.python.org/versions/" + ) + +__all__ = ( + "DeveloperKnowledgeAsyncClient", + "BatchGetDocumentsRequest", + "BatchGetDocumentsResponse", + "DeveloperKnowledgeClient", + "Document", + "DocumentChunk", + "DocumentView", + "GetDocumentRequest", + "SearchDocumentChunksRequest", + "SearchDocumentChunksResponse", +) diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/gapic_metadata.json b/packages/google-developers-knowledge/google/developers_knowledge_v1/gapic_metadata.json new file mode 100644 index 000000000000..0d8e9e182579 --- /dev/null +++ b/packages/google-developers-knowledge/google/developers_knowledge_v1/gapic_metadata.json @@ -0,0 +1,73 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.developers_knowledge_v1", + "protoPackage": "google.developers.knowledge.v1", + "schema": "1.0", + "services": { + "DeveloperKnowledge": { + "clients": { + "grpc": { + "libraryClient": "DeveloperKnowledgeClient", + "rpcs": { + "BatchGetDocuments": { + "methods": [ + "batch_get_documents" + ] + }, + "GetDocument": { + "methods": [ + "get_document" + ] + }, + "SearchDocumentChunks": { + "methods": [ + "search_document_chunks" + ] + } + } + }, + "grpc-async": { + "libraryClient": "DeveloperKnowledgeAsyncClient", + "rpcs": { + "BatchGetDocuments": { + "methods": [ + "batch_get_documents" + ] + }, + "GetDocument": { + "methods": [ + "get_document" + ] + }, + "SearchDocumentChunks": { + "methods": [ + "search_document_chunks" + ] + } + } + }, + "rest": { + "libraryClient": "DeveloperKnowledgeClient", + "rpcs": { + "BatchGetDocuments": { + "methods": [ + "batch_get_documents" + ] + }, + "GetDocument": { + "methods": [ + "get_document" + ] + }, + "SearchDocumentChunks": { + "methods": [ + "search_document_chunks" + ] + } + } + } + } + } + } +} diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/gapic_version.py b/packages/google-developers-knowledge/google/developers_knowledge_v1/gapic_version.py new file mode 100644 index 000000000000..e89a0031d71b --- /dev/null +++ b/packages/google-developers-knowledge/google/developers_knowledge_v1/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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. +# +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/py.typed b/packages/google-developers-knowledge/google/developers_knowledge_v1/py.typed new file mode 100644 index 000000000000..184e0e4d53ea --- /dev/null +++ b/packages/google-developers-knowledge/google/developers_knowledge_v1/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-developers-knowledge package uses inline types. diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/__init__.py b/packages/google-developers-knowledge/google/developers_knowledge_v1/services/__init__.py new file mode 100644 index 000000000000..32b36c5c4fe0 --- /dev/null +++ b/packages/google-developers-knowledge/google/developers_knowledge_v1/services/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/__init__.py b/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/__init__.py new file mode 100644 index 000000000000..e276f0d9c4bf --- /dev/null +++ b/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .async_client import DeveloperKnowledgeAsyncClient +from .client import DeveloperKnowledgeClient + +__all__ = ( + "DeveloperKnowledgeClient", + "DeveloperKnowledgeAsyncClient", +) diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/async_client.py b/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/async_client.py new file mode 100644 index 000000000000..b7c29b9ab0c1 --- /dev/null +++ b/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/async_client.py @@ -0,0 +1,642 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 logging as std_logging +import re +from collections import OrderedDict +from typing import ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, +) + +import google.protobuf +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.api_core.client_options import ClientOptions +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.developers_knowledge_v1 import gapic_version as package_version + +try: + OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore + +from google.developers_knowledge_v1.services.developer_knowledge import pagers +from google.developers_knowledge_v1.types import developerknowledge + +from .client import DeveloperKnowledgeClient +from .transports.base import DEFAULT_CLIENT_INFO, DeveloperKnowledgeTransport +from .transports.grpc_asyncio import DeveloperKnowledgeGrpcAsyncIOTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class DeveloperKnowledgeAsyncClient: + """The Developer Knowledge API provides programmatic access to Google's + public developer documentation, enabling you to integrate this + knowledge base into your own applications and workflows. + + The API is designed to be the canonical source for machine-readable + access to Google's developer documentation. + + A typical use case is to first use + [DeveloperKnowledge.SearchDocumentChunks][google.developers.knowledge.v1.DeveloperKnowledge.SearchDocumentChunks] + to find relevant page URIs based on a query, and then use + [DeveloperKnowledge.GetDocument][google.developers.knowledge.v1.DeveloperKnowledge.GetDocument] + or + [DeveloperKnowledge.BatchGetDocuments][google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments] + to fetch the full content of the top results. + + All document content is provided in Markdown format. + """ + + _client: DeveloperKnowledgeClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = DeveloperKnowledgeClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = DeveloperKnowledgeClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = DeveloperKnowledgeClient._DEFAULT_ENDPOINT_TEMPLATE + _DEFAULT_UNIVERSE = DeveloperKnowledgeClient._DEFAULT_UNIVERSE + + document_path = staticmethod(DeveloperKnowledgeClient.document_path) + parse_document_path = staticmethod(DeveloperKnowledgeClient.parse_document_path) + common_billing_account_path = staticmethod( + DeveloperKnowledgeClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + DeveloperKnowledgeClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(DeveloperKnowledgeClient.common_folder_path) + parse_common_folder_path = staticmethod( + DeveloperKnowledgeClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + DeveloperKnowledgeClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + DeveloperKnowledgeClient.parse_common_organization_path + ) + common_project_path = staticmethod(DeveloperKnowledgeClient.common_project_path) + parse_common_project_path = staticmethod( + DeveloperKnowledgeClient.parse_common_project_path + ) + common_location_path = staticmethod(DeveloperKnowledgeClient.common_location_path) + parse_common_location_path = staticmethod( + DeveloperKnowledgeClient.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: + DeveloperKnowledgeAsyncClient: The constructed client. + """ + sa_info_func = ( + DeveloperKnowledgeClient.from_service_account_info.__func__ # type: ignore + ) + return sa_info_func(DeveloperKnowledgeAsyncClient, info, *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: + DeveloperKnowledgeAsyncClient: The constructed client. + """ + sa_file_func = ( + DeveloperKnowledgeClient.from_service_account_file.__func__ # type: ignore + ) + return sa_file_func(DeveloperKnowledgeAsyncClient, filename, *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 variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return DeveloperKnowledgeClient.get_mtls_endpoint_and_cert_source( + client_options + ) # type: ignore + + @property + def transport(self) -> DeveloperKnowledgeTransport: + """Returns the transport used by the client instance. + + Returns: + DeveloperKnowledgeTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self) -> str: + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = DeveloperKnowledgeClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + DeveloperKnowledgeTransport, + Callable[..., DeveloperKnowledgeTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the developer knowledge async 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 (Optional[Union[str,DeveloperKnowledgeTransport,Callable[..., DeveloperKnowledgeTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the DeveloperKnowledgeTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "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). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS 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. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + 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. + """ + self._client = DeveloperKnowledgeClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.developers.knowledge_v1.DeveloperKnowledgeAsyncClient`.", + extra={ + "serviceName": "google.developers.knowledge.v1.DeveloperKnowledge", + "universeDomain": getattr( + self._client._transport._credentials, "universe_domain", "" + ), + "credentialsType": f"{type(self._client._transport._credentials).__module__}.{type(self._client._transport._credentials).__qualname__}", + "credentialsInfo": getattr( + self.transport._credentials, "get_cred_info", lambda: None + )(), + } + if hasattr(self._client._transport, "_credentials") + else { + "serviceName": "google.developers.knowledge.v1.DeveloperKnowledge", + "credentialsType": None, + }, + ) + + async def search_document_chunks( + self, + request: Optional[ + Union[developerknowledge.SearchDocumentChunksRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.SearchDocumentChunksAsyncPager: + r"""Searches for developer knowledge across Google's developer + documentation. Returns + [DocumentChunk][google.developers.knowledge.v1.DocumentChunk]s + based on the user's query. There may be many chunks from the + same [Document][google.developers.knowledge.v1.Document]. To + retrieve full documents, use + [DeveloperKnowledge.GetDocument][google.developers.knowledge.v1.DeveloperKnowledge.GetDocument] + or + [DeveloperKnowledge.BatchGetDocuments][google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments] + with the + [DocumentChunk.parent][google.developers.knowledge.v1.DocumentChunk.parent] + returned in the + [SearchDocumentChunksResponse.results][google.developers.knowledge.v1.SearchDocumentChunksResponse.results]. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google import developers_knowledge_v1 + + async def sample_search_document_chunks(): + # Create a client + client = developers_knowledge_v1.DeveloperKnowledgeAsyncClient() + + # Initialize request argument(s) + request = developers_knowledge_v1.SearchDocumentChunksRequest( + query="query_value", + ) + + # Make the request + page_result = client.search_document_chunks(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.developers_knowledge_v1.types.SearchDocumentChunksRequest, dict]]): + The request object. Request message for + [DeveloperKnowledge.SearchDocumentChunks][google.developers.knowledge.v1.DeveloperKnowledge.SearchDocumentChunks]. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.developers_knowledge_v1.services.developer_knowledge.pagers.SearchDocumentChunksAsyncPager: + Response message for + [DeveloperKnowledge.SearchDocumentChunks][google.developers.knowledge.v1.DeveloperKnowledge.SearchDocumentChunks]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, developerknowledge.SearchDocumentChunksRequest): + request = developerknowledge.SearchDocumentChunksRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.search_document_chunks + ] + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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.SearchDocumentChunksAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_document( + self, + request: Optional[Union[developerknowledge.GetDocumentRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> developerknowledge.Document: + r"""Retrieves a single document with its full Markdown + content. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google import developers_knowledge_v1 + + async def sample_get_document(): + # Create a client + client = developers_knowledge_v1.DeveloperKnowledgeAsyncClient() + + # Initialize request argument(s) + request = developers_knowledge_v1.GetDocumentRequest( + name="name_value", + ) + + # Make the request + response = await client.get_document(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.developers_knowledge_v1.types.GetDocumentRequest, dict]]): + The request object. Request message for + [DeveloperKnowledge.GetDocument][google.developers.knowledge.v1.DeveloperKnowledge.GetDocument]. + name (:class:`str`): + Required. Specifies the name of the document to + retrieve. Format: ``documents/{uri_without_scheme}`` + Example: + ``documents/docs.cloud.google.com/storage/docs/creating-buckets`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.developers_knowledge_v1.types.Document: + A Document represents a piece of + content from the Developer Knowledge + corpus. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, developerknowledge.GetDocumentRequest): + request = developerknowledge.GetDocumentRequest(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._client._transport._wrapped_methods[ + self._client._transport.get_document + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def batch_get_documents( + self, + request: Optional[ + Union[developerknowledge.BatchGetDocumentsRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> developerknowledge.BatchGetDocumentsResponse: + r"""Retrieves multiple documents, each with its full + Markdown content. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google import developers_knowledge_v1 + + async def sample_batch_get_documents(): + # Create a client + client = developers_knowledge_v1.DeveloperKnowledgeAsyncClient() + + # Initialize request argument(s) + request = developers_knowledge_v1.BatchGetDocumentsRequest( + names=['names_value1', 'names_value2'], + ) + + # Make the request + response = await client.batch_get_documents(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.developers_knowledge_v1.types.BatchGetDocumentsRequest, dict]]): + The request object. Request message for + [DeveloperKnowledge.BatchGetDocuments][google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments]. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.developers_knowledge_v1.types.BatchGetDocumentsResponse: + Response message for + [DeveloperKnowledge.BatchGetDocuments][google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, developerknowledge.BatchGetDocumentsRequest): + request = developerknowledge.BatchGetDocumentsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.batch_get_documents + ] + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "DeveloperKnowledgeAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("DeveloperKnowledgeAsyncClient",) diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/client.py b/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/client.py new file mode 100644 index 000000000000..8adfa8990176 --- /dev/null +++ b/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/client.py @@ -0,0 +1,1067 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 json +import logging as std_logging +import os +import re +import warnings +from collections import OrderedDict +from http import HTTPStatus +from typing import ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) + +import google.protobuf +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.developers_knowledge_v1 import gapic_version as package_version + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore + +from google.developers_knowledge_v1.services.developer_knowledge import pagers +from google.developers_knowledge_v1.types import developerknowledge + +from .transports.base import DEFAULT_CLIENT_INFO, DeveloperKnowledgeTransport +from .transports.grpc import DeveloperKnowledgeGrpcTransport +from .transports.grpc_asyncio import DeveloperKnowledgeGrpcAsyncIOTransport +from .transports.rest import DeveloperKnowledgeRestTransport + + +class DeveloperKnowledgeClientMeta(type): + """Metaclass for the DeveloperKnowledge 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[DeveloperKnowledgeTransport]] + _transport_registry["grpc"] = DeveloperKnowledgeGrpcTransport + _transport_registry["grpc_asyncio"] = DeveloperKnowledgeGrpcAsyncIOTransport + _transport_registry["rest"] = DeveloperKnowledgeRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[DeveloperKnowledgeTransport]: + """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 DeveloperKnowledgeClient(metaclass=DeveloperKnowledgeClientMeta): + """The Developer Knowledge API provides programmatic access to Google's + public developer documentation, enabling you to integrate this + knowledge base into your own applications and workflows. + + The API is designed to be the canonical source for machine-readable + access to Google's developer documentation. + + A typical use case is to first use + [DeveloperKnowledge.SearchDocumentChunks][google.developers.knowledge.v1.DeveloperKnowledge.SearchDocumentChunks] + to find relevant page URIs based on a query, and then use + [DeveloperKnowledge.GetDocument][google.developers.knowledge.v1.DeveloperKnowledge.GetDocument] + or + [DeveloperKnowledge.BatchGetDocuments][google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments] + to fetch the full content of the top results. + + All document content is provided in Markdown format. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint) -> Optional[str]: + """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: + Optional[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) + if m is None: + # Could not parse api_endpoint; return as-is. + return 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") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "developerknowledge.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "developerknowledge.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @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: + DeveloperKnowledgeClient: 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: + DeveloperKnowledgeClient: 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) -> DeveloperKnowledgeTransport: + """Returns the transport used by the client instance. + + Returns: + DeveloperKnowledgeTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def document_path( + document: str, + ) -> str: + """Returns a fully-qualified document string.""" + return "documents/{document}".format( + document=document, + ) + + @staticmethod + def parse_document_path(path: str) -> Dict[str, str]: + """Parses a document path into its component segments.""" + m = re.match(r"^documents/(?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 + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = DeveloperKnowledgeClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + 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: + 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 + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = DeveloperKnowledgeClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ) -> str: + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = DeveloperKnowledgeClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = DeveloperKnowledgeClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = DeveloperKnowledgeClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], universe_domain_env: Optional[str] + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = DeveloperKnowledgeClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self) -> str: + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + DeveloperKnowledgeTransport, + Callable[..., DeveloperKnowledgeTransport], + ] + ] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the developer knowledge 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 (Optional[Union[str,DeveloperKnowledgeTransport,Callable[..., DeveloperKnowledgeTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the DeveloperKnowledgeTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "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). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS 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. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + 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. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict(self._client_options) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr(self._client_options, "universe_domain", None) + + self._use_client_cert, self._use_mtls_endpoint, self._universe_domain_env = ( + DeveloperKnowledgeClient._read_environment_variables() + ) + self._client_cert_source = DeveloperKnowledgeClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = DeveloperKnowledgeClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint: str = "" # updated below, depending on `transport` + + # Initialize the universe domain validation. + self._is_universe_domain_valid = False + + if CLIENT_LOGGING_SUPPORTED: # pragma: NO COVER + # Setup logging. + client_logging.initialize_logging() + + api_key_value = getattr(self._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. + transport_provided = isinstance(transport, DeveloperKnowledgeTransport) + if transport_provided: + # transport is a DeveloperKnowledgeTransport instance. + if credentials or self._client_options.credentials_file or api_key_value: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes directly." + ) + self._transport = cast(DeveloperKnowledgeTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or DeveloperKnowledgeClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + 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_init: Union[ + Type[DeveloperKnowledgeTransport], + Callable[..., DeveloperKnowledgeTransport], + ] = ( + DeveloperKnowledgeClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., DeveloperKnowledgeTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + api_audience=self._client_options.api_audience, + ) + + if "async" not in str(self._transport): + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.developers.knowledge_v1.DeveloperKnowledgeClient`.", + extra={ + "serviceName": "google.developers.knowledge.v1.DeveloperKnowledge", + "universeDomain": getattr( + self._transport._credentials, "universe_domain", "" + ), + "credentialsType": f"{type(self._transport._credentials).__module__}.{type(self._transport._credentials).__qualname__}", + "credentialsInfo": getattr( + self.transport._credentials, "get_cred_info", lambda: None + )(), + } + if hasattr(self._transport, "_credentials") + else { + "serviceName": "google.developers.knowledge.v1.DeveloperKnowledge", + "credentialsType": None, + }, + ) + + def search_document_chunks( + self, + request: Optional[ + Union[developerknowledge.SearchDocumentChunksRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.SearchDocumentChunksPager: + r"""Searches for developer knowledge across Google's developer + documentation. Returns + [DocumentChunk][google.developers.knowledge.v1.DocumentChunk]s + based on the user's query. There may be many chunks from the + same [Document][google.developers.knowledge.v1.Document]. To + retrieve full documents, use + [DeveloperKnowledge.GetDocument][google.developers.knowledge.v1.DeveloperKnowledge.GetDocument] + or + [DeveloperKnowledge.BatchGetDocuments][google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments] + with the + [DocumentChunk.parent][google.developers.knowledge.v1.DocumentChunk.parent] + returned in the + [SearchDocumentChunksResponse.results][google.developers.knowledge.v1.SearchDocumentChunksResponse.results]. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google import developers_knowledge_v1 + + def sample_search_document_chunks(): + # Create a client + client = developers_knowledge_v1.DeveloperKnowledgeClient() + + # Initialize request argument(s) + request = developers_knowledge_v1.SearchDocumentChunksRequest( + query="query_value", + ) + + # Make the request + page_result = client.search_document_chunks(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.developers_knowledge_v1.types.SearchDocumentChunksRequest, dict]): + The request object. Request message for + [DeveloperKnowledge.SearchDocumentChunks][google.developers.knowledge.v1.DeveloperKnowledge.SearchDocumentChunks]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.developers_knowledge_v1.services.developer_knowledge.pagers.SearchDocumentChunksPager: + Response message for + [DeveloperKnowledge.SearchDocumentChunks][google.developers.knowledge.v1.DeveloperKnowledge.SearchDocumentChunks]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, developerknowledge.SearchDocumentChunksRequest): + request = developerknowledge.SearchDocumentChunksRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.search_document_chunks] + + # Validate the universe domain. + self._validate_universe_domain() + + # 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.SearchDocumentChunksPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_document( + self, + request: Optional[Union[developerknowledge.GetDocumentRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> developerknowledge.Document: + r"""Retrieves a single document with its full Markdown + content. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google import developers_knowledge_v1 + + def sample_get_document(): + # Create a client + client = developers_knowledge_v1.DeveloperKnowledgeClient() + + # Initialize request argument(s) + request = developers_knowledge_v1.GetDocumentRequest( + name="name_value", + ) + + # Make the request + response = client.get_document(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.developers_knowledge_v1.types.GetDocumentRequest, dict]): + The request object. Request message for + [DeveloperKnowledge.GetDocument][google.developers.knowledge.v1.DeveloperKnowledge.GetDocument]. + name (str): + Required. Specifies the name of the document to + retrieve. Format: ``documents/{uri_without_scheme}`` + Example: + ``documents/docs.cloud.google.com/storage/docs/creating-buckets`` + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.developers_knowledge_v1.types.Document: + A Document represents a piece of + content from the Developer Knowledge + corpus. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, developerknowledge.GetDocumentRequest): + request = developerknowledge.GetDocumentRequest(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_document] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def batch_get_documents( + self, + request: Optional[ + Union[developerknowledge.BatchGetDocumentsRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> developerknowledge.BatchGetDocumentsResponse: + r"""Retrieves multiple documents, each with its full + Markdown content. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google import developers_knowledge_v1 + + def sample_batch_get_documents(): + # Create a client + client = developers_knowledge_v1.DeveloperKnowledgeClient() + + # Initialize request argument(s) + request = developers_knowledge_v1.BatchGetDocumentsRequest( + names=['names_value1', 'names_value2'], + ) + + # Make the request + response = client.batch_get_documents(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.developers_knowledge_v1.types.BatchGetDocumentsRequest, dict]): + The request object. Request message for + [DeveloperKnowledge.BatchGetDocuments][google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.developers_knowledge_v1.types.BatchGetDocumentsResponse: + Response message for + [DeveloperKnowledge.BatchGetDocuments][google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, developerknowledge.BatchGetDocumentsRequest): + request = developerknowledge.BatchGetDocumentsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.batch_get_documents] + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "DeveloperKnowledgeClient": + 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() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("DeveloperKnowledgeClient",) diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/pagers.py b/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/pagers.py new file mode 100644 index 000000000000..a99ffe3675f9 --- /dev/null +++ b/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/pagers.py @@ -0,0 +1,201 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, + Union, +) + +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import retry_async as retries_async + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] + OptionalAsyncRetry = Union[ + retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore + +from google.developers_knowledge_v1.types import developerknowledge + + +class SearchDocumentChunksPager: + """A pager for iterating through ``search_document_chunks`` requests. + + This class thinly wraps an initial + :class:`google.developers_knowledge_v1.types.SearchDocumentChunksResponse` object, and + provides an ``__iter__`` method to iterate through its + ``results`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``SearchDocumentChunks`` requests and continue to iterate + through the ``results`` field on the + corresponding responses. + + All the usual :class:`google.developers_knowledge_v1.types.SearchDocumentChunksResponse` + 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[..., developerknowledge.SearchDocumentChunksResponse], + request: developerknowledge.SearchDocumentChunksRequest, + response: developerknowledge.SearchDocumentChunksResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.developers_knowledge_v1.types.SearchDocumentChunksRequest): + The initial request object. + response (google.developers_knowledge_v1.types.SearchDocumentChunksResponse): + The initial response object. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = developerknowledge.SearchDocumentChunksRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[developerknowledge.SearchDocumentChunksResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __iter__(self) -> Iterator[developerknowledge.DocumentChunk]: + for page in self.pages: + yield from page.results + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class SearchDocumentChunksAsyncPager: + """A pager for iterating through ``search_document_chunks`` requests. + + This class thinly wraps an initial + :class:`google.developers_knowledge_v1.types.SearchDocumentChunksResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``results`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``SearchDocumentChunks`` requests and continue to iterate + through the ``results`` field on the + corresponding responses. + + All the usual :class:`google.developers_knowledge_v1.types.SearchDocumentChunksResponse` + 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[developerknowledge.SearchDocumentChunksResponse] + ], + request: developerknowledge.SearchDocumentChunksRequest, + response: developerknowledge.SearchDocumentChunksResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.developers_knowledge_v1.types.SearchDocumentChunksRequest): + The initial request object. + response (google.developers_knowledge_v1.types.SearchDocumentChunksResponse): + The initial response object. + retry (google.api_core.retry.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = developerknowledge.SearchDocumentChunksRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[developerknowledge.SearchDocumentChunksResponse]: + 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, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __aiter__(self) -> AsyncIterator[developerknowledge.DocumentChunk]: + 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/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/README.rst b/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/README.rst new file mode 100644 index 000000000000..dc29c2939f13 --- /dev/null +++ b/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/README.rst @@ -0,0 +1,10 @@ + +transport inheritance structure +_______________________________ + +``DeveloperKnowledgeTransport`` is the ABC for all transports. + +- public child ``DeveloperKnowledgeGrpcTransport`` for sync gRPC transport (defined in ``grpc.py``). +- public child ``DeveloperKnowledgeGrpcAsyncIOTransport`` for async gRPC transport (defined in ``grpc_asyncio.py``). +- private child ``_BaseDeveloperKnowledgeRestTransport`` for base REST transport with inner classes ``_BaseMETHOD`` (defined in ``rest_base.py``). +- public child ``DeveloperKnowledgeRestTransport`` for sync REST transport with inner classes ``METHOD`` derived from the parent's corresponding ``_BaseMETHOD`` classes (defined in ``rest.py``). diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/__init__.py b/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/__init__.py new file mode 100644 index 000000000000..f34f8d761ccd --- /dev/null +++ b/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/__init__.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 DeveloperKnowledgeTransport +from .grpc import DeveloperKnowledgeGrpcTransport +from .grpc_asyncio import DeveloperKnowledgeGrpcAsyncIOTransport +from .rest import DeveloperKnowledgeRestInterceptor, DeveloperKnowledgeRestTransport + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[DeveloperKnowledgeTransport]] +_transport_registry["grpc"] = DeveloperKnowledgeGrpcTransport +_transport_registry["grpc_asyncio"] = DeveloperKnowledgeGrpcAsyncIOTransport +_transport_registry["rest"] = DeveloperKnowledgeRestTransport + +__all__ = ( + "DeveloperKnowledgeTransport", + "DeveloperKnowledgeGrpcTransport", + "DeveloperKnowledgeGrpcAsyncIOTransport", + "DeveloperKnowledgeRestTransport", + "DeveloperKnowledgeRestInterceptor", +) diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/base.py b/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/base.py new file mode 100644 index 000000000000..f02e32c7be8c --- /dev/null +++ b/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/base.py @@ -0,0 +1,227 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union + +import google.api_core +import google.auth # type: ignore +import google.protobuf +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.developers_knowledge_v1 import gapic_version as package_version +from google.developers_knowledge_v1.types import developerknowledge + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class DeveloperKnowledgeTransport(abc.ABC): + """Abstract transport class for DeveloperKnowledge.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) + + DEFAULT_HOST: str = "developerknowledge.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'developerknowledge.googleapis.com'). + 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]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + 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. + api_audience (Optional[str]): The intended audience for the API calls + to the service that will be set when using certain 3rd party + authentication flows. Audience is typically a resource identifier. + If not set, the host value will be used as a default. + """ + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # 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=scopes, + quota_project_id=quota_project_id, + default_scopes=self.AUTH_SCOPES, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + scopes=scopes, + quota_project_id=quota_project_id, + default_scopes=self.AUTH_SCOPES, + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr(service_account.Credentials, "with_always_use_jwt_access") + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + self._wrapped_methods: Dict[Callable, Callable] = {} + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.search_document_chunks: gapic_v1.method.wrap_method( + self.search_document_chunks, + default_timeout=None, + client_info=client_info, + ), + self.get_document: gapic_v1.method.wrap_method( + self.get_document, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.batch_get_documents: gapic_v1.method.wrap_method( + self.batch_get_documents, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + 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_document_chunks( + self, + ) -> Callable[ + [developerknowledge.SearchDocumentChunksRequest], + Union[ + developerknowledge.SearchDocumentChunksResponse, + Awaitable[developerknowledge.SearchDocumentChunksResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_document( + self, + ) -> Callable[ + [developerknowledge.GetDocumentRequest], + Union[developerknowledge.Document, Awaitable[developerknowledge.Document]], + ]: + raise NotImplementedError() + + @property + def batch_get_documents( + self, + ) -> Callable[ + [developerknowledge.BatchGetDocumentsRequest], + Union[ + developerknowledge.BatchGetDocumentsResponse, + Awaitable[developerknowledge.BatchGetDocumentsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("DeveloperKnowledgeTransport",) diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/grpc.py b/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/grpc.py new file mode 100644 index 000000000000..51d25b504688 --- /dev/null +++ b/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/grpc.py @@ -0,0 +1,449 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 json +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +import google.auth # type: ignore +import google.protobuf.message +import grpc # type: ignore +import proto # type: ignore +from google.api_core import gapic_v1, grpc_helpers +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson + +from google.developers_knowledge_v1.types import developerknowledge + +from .base import DEFAULT_CLIENT_INFO, DeveloperKnowledgeTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor(grpc.UnaryUnaryClientInterceptor): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = f"{type(request).__name__}: {pickle.dumps(request)!r}" + + request_metadata = { + key: value.decode("utf-8") if isinstance(value, bytes) else value + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.developers.knowledge.v1.DeveloperKnowledge", + "rpcName": str(client_call_details.method), + "request": grpc_request, + "metadata": grpc_request["metadata"], + }, + ) + response = continuation(client_call_details, request) + if logging_enabled: # pragma: NO COVER + response_metadata = response.trailing_metadata() + # Convert gRPC metadata `` to list of tuples + metadata = ( + dict([(k, str(v)) for k, v in response_metadata]) + if response_metadata + else None + ) + result = response.result() + if isinstance(result, proto.Message): + response_payload = type(result).to_json(result) + elif isinstance(result, google.protobuf.message.Message): + response_payload = MessageToJson(result) + else: + response_payload = f"{type(result).__name__}: {pickle.dumps(result)!r}" + grpc_response = { + "payload": response_payload, + "metadata": metadata, + "status": "OK", + } + _LOGGER.debug( + f"Received response for {client_call_details.method}.", + extra={ + "serviceName": "google.developers.knowledge.v1.DeveloperKnowledge", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class DeveloperKnowledgeGrpcTransport(DeveloperKnowledgeTransport): + """gRPC backend transport for DeveloperKnowledge. + + The Developer Knowledge API provides programmatic access to Google's + public developer documentation, enabling you to integrate this + knowledge base into your own applications and workflows. + + The API is designed to be the canonical source for machine-readable + access to Google's developer documentation. + + A typical use case is to first use + [DeveloperKnowledge.SearchDocumentChunks][google.developers.knowledge.v1.DeveloperKnowledge.SearchDocumentChunks] + to find relevant page URIs based on a query, and then use + [DeveloperKnowledge.GetDocument][google.developers.knowledge.v1.DeveloperKnowledge.GetDocument] + or + [DeveloperKnowledge.BatchGetDocuments][google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments] + to fetch the full content of the top results. + + All document content is provided in Markdown format. + + 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 = "developerknowledge.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'developerknowledge.googleapis.com'). + 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 a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + 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 a ``channel`` instance 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 a ``channel`` instance 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. + api_audience (Optional[str]): The intended audience for the API calls + to the service that will be set when using certain 3rd party + authentication flows. Audience is typically a resource identifier. + If not set, the host value will be used as a default. + + 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 isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + self._interceptor = _LoggingClientInterceptor() + self._logged_channel = grpc.intercept_channel( + self._grpc_channel, self._interceptor + ) + + # Wrap messages. This must be done after self._logged_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "developerknowledge.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + 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_document_chunks( + self, + ) -> Callable[ + [developerknowledge.SearchDocumentChunksRequest], + developerknowledge.SearchDocumentChunksResponse, + ]: + r"""Return a callable for the search document chunks method over gRPC. + + Searches for developer knowledge across Google's developer + documentation. Returns + [DocumentChunk][google.developers.knowledge.v1.DocumentChunk]s + based on the user's query. There may be many chunks from the + same [Document][google.developers.knowledge.v1.Document]. To + retrieve full documents, use + [DeveloperKnowledge.GetDocument][google.developers.knowledge.v1.DeveloperKnowledge.GetDocument] + or + [DeveloperKnowledge.BatchGetDocuments][google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments] + with the + [DocumentChunk.parent][google.developers.knowledge.v1.DocumentChunk.parent] + returned in the + [SearchDocumentChunksResponse.results][google.developers.knowledge.v1.SearchDocumentChunksResponse.results]. + + Returns: + Callable[[~.SearchDocumentChunksRequest], + ~.SearchDocumentChunksResponse]: + 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_document_chunks" not in self._stubs: + self._stubs["search_document_chunks"] = self._logged_channel.unary_unary( + "/google.developers.knowledge.v1.DeveloperKnowledge/SearchDocumentChunks", + request_serializer=developerknowledge.SearchDocumentChunksRequest.serialize, + response_deserializer=developerknowledge.SearchDocumentChunksResponse.deserialize, + ) + return self._stubs["search_document_chunks"] + + @property + def get_document( + self, + ) -> Callable[[developerknowledge.GetDocumentRequest], developerknowledge.Document]: + r"""Return a callable for the get document method over gRPC. + + Retrieves a single document with its full Markdown + content. + + Returns: + Callable[[~.GetDocumentRequest], + ~.Document]: + 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_document" not in self._stubs: + self._stubs["get_document"] = self._logged_channel.unary_unary( + "/google.developers.knowledge.v1.DeveloperKnowledge/GetDocument", + request_serializer=developerknowledge.GetDocumentRequest.serialize, + response_deserializer=developerknowledge.Document.deserialize, + ) + return self._stubs["get_document"] + + @property + def batch_get_documents( + self, + ) -> Callable[ + [developerknowledge.BatchGetDocumentsRequest], + developerknowledge.BatchGetDocumentsResponse, + ]: + r"""Return a callable for the batch get documents method over gRPC. + + Retrieves multiple documents, each with its full + Markdown content. + + Returns: + Callable[[~.BatchGetDocumentsRequest], + ~.BatchGetDocumentsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "batch_get_documents" not in self._stubs: + self._stubs["batch_get_documents"] = self._logged_channel.unary_unary( + "/google.developers.knowledge.v1.DeveloperKnowledge/BatchGetDocuments", + request_serializer=developerknowledge.BatchGetDocumentsRequest.serialize, + response_deserializer=developerknowledge.BatchGetDocumentsResponse.deserialize, + ) + return self._stubs["batch_get_documents"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("DeveloperKnowledgeGrpcTransport",) diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/grpc_asyncio.py b/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/grpc_asyncio.py new file mode 100644 index 000000000000..f446f2be32ca --- /dev/null +++ b/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/grpc_asyncio.py @@ -0,0 +1,502 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 inspect +import json +import logging as std_logging +import pickle +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +import google.protobuf.message +import grpc # type: ignore +import proto # type: ignore +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, grpc_helpers_async +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +from grpc.experimental import aio # type: ignore + +from google.developers_knowledge_v1.types import developerknowledge + +from .base import DEFAULT_CLIENT_INFO, DeveloperKnowledgeTransport +from .grpc import DeveloperKnowledgeGrpcTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientAIOInterceptor( + grpc.aio.UnaryUnaryClientInterceptor +): # pragma: NO COVER + async def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = f"{type(request).__name__}: {pickle.dumps(request)!r}" + + request_metadata = { + key: value.decode("utf-8") if isinstance(value, bytes) else value + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.developers.knowledge.v1.DeveloperKnowledge", + "rpcName": str(client_call_details.method), + "request": grpc_request, + "metadata": grpc_request["metadata"], + }, + ) + response = await continuation(client_call_details, request) + if logging_enabled: # pragma: NO COVER + response_metadata = await response.trailing_metadata() + # Convert gRPC metadata `` to list of tuples + metadata = ( + dict([(k, str(v)) for k, v in response_metadata]) + if response_metadata + else None + ) + result = await response + if isinstance(result, proto.Message): + response_payload = type(result).to_json(result) + elif isinstance(result, google.protobuf.message.Message): + response_payload = MessageToJson(result) + else: + response_payload = f"{type(result).__name__}: {pickle.dumps(result)!r}" + grpc_response = { + "payload": response_payload, + "metadata": metadata, + "status": "OK", + } + _LOGGER.debug( + f"Received response to rpc {client_call_details.method}.", + extra={ + "serviceName": "google.developers.knowledge.v1.DeveloperKnowledge", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class DeveloperKnowledgeGrpcAsyncIOTransport(DeveloperKnowledgeTransport): + """gRPC AsyncIO backend transport for DeveloperKnowledge. + + The Developer Knowledge API provides programmatic access to Google's + public developer documentation, enabling you to integrate this + knowledge base into your own applications and workflows. + + The API is designed to be the canonical source for machine-readable + access to Google's developer documentation. + + A typical use case is to first use + [DeveloperKnowledge.SearchDocumentChunks][google.developers.knowledge.v1.DeveloperKnowledge.SearchDocumentChunks] + to find relevant page URIs based on a query, and then use + [DeveloperKnowledge.GetDocument][google.developers.knowledge.v1.DeveloperKnowledge.GetDocument] + or + [DeveloperKnowledge.BatchGetDocuments][google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments] + to fetch the full content of the top results. + + All document content is provided in Markdown format. + + 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 = "developerknowledge.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + 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 = "developerknowledge.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[Union[aio.Channel, Callable[..., aio.Channel]]] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'developerknowledge.googleapis.com'). + 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 a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + 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[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + 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 a ``channel`` instance 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 a ``channel`` instance 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. + api_audience (Optional[str]): The intended audience for the API calls + to the service that will be set when using certain 3rd party + authentication flows. Audience is typically a resource identifier. + If not set, the host value will be used as a default. + + 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 isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + self._interceptor = _LoggingClientAIOInterceptor() + self._grpc_channel._unary_unary_interceptors.append(self._interceptor) + self._logged_channel = self._grpc_channel + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) + # Wrap messages. This must be done after self._logged_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_document_chunks( + self, + ) -> Callable[ + [developerknowledge.SearchDocumentChunksRequest], + Awaitable[developerknowledge.SearchDocumentChunksResponse], + ]: + r"""Return a callable for the search document chunks method over gRPC. + + Searches for developer knowledge across Google's developer + documentation. Returns + [DocumentChunk][google.developers.knowledge.v1.DocumentChunk]s + based on the user's query. There may be many chunks from the + same [Document][google.developers.knowledge.v1.Document]. To + retrieve full documents, use + [DeveloperKnowledge.GetDocument][google.developers.knowledge.v1.DeveloperKnowledge.GetDocument] + or + [DeveloperKnowledge.BatchGetDocuments][google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments] + with the + [DocumentChunk.parent][google.developers.knowledge.v1.DocumentChunk.parent] + returned in the + [SearchDocumentChunksResponse.results][google.developers.knowledge.v1.SearchDocumentChunksResponse.results]. + + Returns: + Callable[[~.SearchDocumentChunksRequest], + Awaitable[~.SearchDocumentChunksResponse]]: + 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_document_chunks" not in self._stubs: + self._stubs["search_document_chunks"] = self._logged_channel.unary_unary( + "/google.developers.knowledge.v1.DeveloperKnowledge/SearchDocumentChunks", + request_serializer=developerknowledge.SearchDocumentChunksRequest.serialize, + response_deserializer=developerknowledge.SearchDocumentChunksResponse.deserialize, + ) + return self._stubs["search_document_chunks"] + + @property + def get_document( + self, + ) -> Callable[ + [developerknowledge.GetDocumentRequest], Awaitable[developerknowledge.Document] + ]: + r"""Return a callable for the get document method over gRPC. + + Retrieves a single document with its full Markdown + content. + + Returns: + Callable[[~.GetDocumentRequest], + Awaitable[~.Document]]: + 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_document" not in self._stubs: + self._stubs["get_document"] = self._logged_channel.unary_unary( + "/google.developers.knowledge.v1.DeveloperKnowledge/GetDocument", + request_serializer=developerknowledge.GetDocumentRequest.serialize, + response_deserializer=developerknowledge.Document.deserialize, + ) + return self._stubs["get_document"] + + @property + def batch_get_documents( + self, + ) -> Callable[ + [developerknowledge.BatchGetDocumentsRequest], + Awaitable[developerknowledge.BatchGetDocumentsResponse], + ]: + r"""Return a callable for the batch get documents method over gRPC. + + Retrieves multiple documents, each with its full + Markdown content. + + Returns: + Callable[[~.BatchGetDocumentsRequest], + Awaitable[~.BatchGetDocumentsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "batch_get_documents" not in self._stubs: + self._stubs["batch_get_documents"] = self._logged_channel.unary_unary( + "/google.developers.knowledge.v1.DeveloperKnowledge/BatchGetDocuments", + request_serializer=developerknowledge.BatchGetDocumentsRequest.serialize, + response_deserializer=developerknowledge.BatchGetDocumentsResponse.deserialize, + ) + return self._stubs["batch_get_documents"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.search_document_chunks: self._wrap_method( + self.search_document_chunks, + default_timeout=None, + client_info=client_info, + ), + self.get_document: self._wrap_method( + self.get_document, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.batch_get_documents: self._wrap_method( + self.batch_get_documents, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("DeveloperKnowledgeGrpcAsyncIOTransport",) diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/rest.py b/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/rest.py new file mode 100644 index 000000000000..bdd1bf490fcf --- /dev/null +++ b/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/rest.py @@ -0,0 +1,855 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +import warnings +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +import google.protobuf +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.developers_knowledge_v1.types import developerknowledge + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseDeveloperKnowledgeRestTransport + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class DeveloperKnowledgeRestInterceptor: + """Interceptor for DeveloperKnowledge. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the DeveloperKnowledgeRestTransport. + + .. code-block:: python + class MyCustomDeveloperKnowledgeInterceptor(DeveloperKnowledgeRestInterceptor): + def pre_batch_get_documents(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_get_documents(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_document(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_document(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_search_document_chunks(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_search_document_chunks(self, response): + logging.log(f"Received response: {response}") + return response + + transport = DeveloperKnowledgeRestTransport(interceptor=MyCustomDeveloperKnowledgeInterceptor()) + client = DeveloperKnowledgeClient(transport=transport) + + + """ + + def pre_batch_get_documents( + self, + request: developerknowledge.BatchGetDocumentsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + developerknowledge.BatchGetDocumentsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for batch_get_documents + + Override in a subclass to manipulate the request or metadata + before they are sent to the DeveloperKnowledge server. + """ + return request, metadata + + def post_batch_get_documents( + self, response: developerknowledge.BatchGetDocumentsResponse + ) -> developerknowledge.BatchGetDocumentsResponse: + """Post-rpc interceptor for batch_get_documents + + DEPRECATED. Please use the `post_batch_get_documents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the DeveloperKnowledge server but before + it is returned to user code. This `post_batch_get_documents` interceptor runs + before the `post_batch_get_documents_with_metadata` interceptor. + """ + return response + + def post_batch_get_documents_with_metadata( + self, + response: developerknowledge.BatchGetDocumentsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + developerknowledge.BatchGetDocumentsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for batch_get_documents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DeveloperKnowledge server but before it is returned to user code. + + We recommend only using this `post_batch_get_documents_with_metadata` + interceptor in new development instead of the `post_batch_get_documents` interceptor. + When both interceptors are used, this `post_batch_get_documents_with_metadata` interceptor runs after the + `post_batch_get_documents` interceptor. The (possibly modified) response returned by + `post_batch_get_documents` will be passed to + `post_batch_get_documents_with_metadata`. + """ + return response, metadata + + def pre_get_document( + self, + request: developerknowledge.GetDocumentRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + developerknowledge.GetDocumentRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_document + + Override in a subclass to manipulate the request or metadata + before they are sent to the DeveloperKnowledge server. + """ + return request, metadata + + def post_get_document( + self, response: developerknowledge.Document + ) -> developerknowledge.Document: + """Post-rpc interceptor for get_document + + DEPRECATED. Please use the `post_get_document_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the DeveloperKnowledge server but before + it is returned to user code. This `post_get_document` interceptor runs + before the `post_get_document_with_metadata` interceptor. + """ + return response + + def post_get_document_with_metadata( + self, + response: developerknowledge.Document, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[developerknowledge.Document, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_document + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DeveloperKnowledge server but before it is returned to user code. + + We recommend only using this `post_get_document_with_metadata` + interceptor in new development instead of the `post_get_document` interceptor. + When both interceptors are used, this `post_get_document_with_metadata` interceptor runs after the + `post_get_document` interceptor. The (possibly modified) response returned by + `post_get_document` will be passed to + `post_get_document_with_metadata`. + """ + return response, metadata + + def pre_search_document_chunks( + self, + request: developerknowledge.SearchDocumentChunksRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + developerknowledge.SearchDocumentChunksRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for search_document_chunks + + Override in a subclass to manipulate the request or metadata + before they are sent to the DeveloperKnowledge server. + """ + return request, metadata + + def post_search_document_chunks( + self, response: developerknowledge.SearchDocumentChunksResponse + ) -> developerknowledge.SearchDocumentChunksResponse: + """Post-rpc interceptor for search_document_chunks + + DEPRECATED. Please use the `post_search_document_chunks_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the DeveloperKnowledge server but before + it is returned to user code. This `post_search_document_chunks` interceptor runs + before the `post_search_document_chunks_with_metadata` interceptor. + """ + return response + + def post_search_document_chunks_with_metadata( + self, + response: developerknowledge.SearchDocumentChunksResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + developerknowledge.SearchDocumentChunksResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for search_document_chunks + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DeveloperKnowledge server but before it is returned to user code. + + We recommend only using this `post_search_document_chunks_with_metadata` + interceptor in new development instead of the `post_search_document_chunks` interceptor. + When both interceptors are used, this `post_search_document_chunks_with_metadata` interceptor runs after the + `post_search_document_chunks` interceptor. The (possibly modified) response returned by + `post_search_document_chunks` will be passed to + `post_search_document_chunks_with_metadata`. + """ + return response, metadata + + +@dataclasses.dataclass +class DeveloperKnowledgeRestStub: + _session: AuthorizedSession + _host: str + _interceptor: DeveloperKnowledgeRestInterceptor + + +class DeveloperKnowledgeRestTransport(_BaseDeveloperKnowledgeRestTransport): + """REST backend synchronous transport for DeveloperKnowledge. + + The Developer Knowledge API provides programmatic access to Google's + public developer documentation, enabling you to integrate this + knowledge base into your own applications and workflows. + + The API is designed to be the canonical source for machine-readable + access to Google's developer documentation. + + A typical use case is to first use + [DeveloperKnowledge.SearchDocumentChunks][google.developers.knowledge.v1.DeveloperKnowledge.SearchDocumentChunks] + to find relevant page URIs based on a query, and then use + [DeveloperKnowledge.GetDocument][google.developers.knowledge.v1.DeveloperKnowledge.GetDocument] + or + [DeveloperKnowledge.BatchGetDocuments][google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments] + to fetch the full content of the top results. + + All document content is provided in Markdown format. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "developerknowledge.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[DeveloperKnowledgeRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'developerknowledge.googleapis.com'). + 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]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. This argument will be + removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + interceptor (Optional[DeveloperKnowledgeRestInterceptor]): Interceptor used + to manipulate requests, request metadata, and responses. + api_audience (Optional[str]): The intended audience for the API calls + to the service that will be set when using certain 3rd party + authentication flows. Audience is typically a resource identifier. + If not set, the host value will be used as a default. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or DeveloperKnowledgeRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _BatchGetDocuments( + _BaseDeveloperKnowledgeRestTransport._BaseBatchGetDocuments, + DeveloperKnowledgeRestStub, + ): + def __hash__(self): + return hash("DeveloperKnowledgeRestTransport.BatchGetDocuments") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: developerknowledge.BatchGetDocumentsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> developerknowledge.BatchGetDocumentsResponse: + r"""Call the batch get documents method over HTTP. + + Args: + request (~.developerknowledge.BatchGetDocumentsRequest): + The request object. Request message for + [DeveloperKnowledge.BatchGetDocuments][google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.developerknowledge.BatchGetDocumentsResponse: + Response message for + [DeveloperKnowledge.BatchGetDocuments][google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments]. + + """ + + http_options = _BaseDeveloperKnowledgeRestTransport._BaseBatchGetDocuments._get_http_options() + + request, metadata = self._interceptor.pre_batch_get_documents( + request, metadata + ) + transcoded_request = _BaseDeveloperKnowledgeRestTransport._BaseBatchGetDocuments._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseDeveloperKnowledgeRestTransport._BaseBatchGetDocuments._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.developers.knowledge_v1.DeveloperKnowledgeClient.BatchGetDocuments", + extra={ + "serviceName": "google.developers.knowledge.v1.DeveloperKnowledge", + "rpcName": "BatchGetDocuments", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = DeveloperKnowledgeRestTransport._BatchGetDocuments._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = developerknowledge.BatchGetDocumentsResponse() + pb_resp = developerknowledge.BatchGetDocumentsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_batch_get_documents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_get_documents_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + developerknowledge.BatchGetDocumentsResponse.to_json(response) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.developers.knowledge_v1.DeveloperKnowledgeClient.batch_get_documents", + extra={ + "serviceName": "google.developers.knowledge.v1.DeveloperKnowledge", + "rpcName": "BatchGetDocuments", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _GetDocument( + _BaseDeveloperKnowledgeRestTransport._BaseGetDocument, + DeveloperKnowledgeRestStub, + ): + def __hash__(self): + return hash("DeveloperKnowledgeRestTransport.GetDocument") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: developerknowledge.GetDocumentRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> developerknowledge.Document: + r"""Call the get document method over HTTP. + + Args: + request (~.developerknowledge.GetDocumentRequest): + The request object. Request message for + [DeveloperKnowledge.GetDocument][google.developers.knowledge.v1.DeveloperKnowledge.GetDocument]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.developerknowledge.Document: + A Document represents a piece of + content from the Developer Knowledge + corpus. + + """ + + http_options = _BaseDeveloperKnowledgeRestTransport._BaseGetDocument._get_http_options() + + request, metadata = self._interceptor.pre_get_document(request, metadata) + transcoded_request = _BaseDeveloperKnowledgeRestTransport._BaseGetDocument._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseDeveloperKnowledgeRestTransport._BaseGetDocument._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.developers.knowledge_v1.DeveloperKnowledgeClient.GetDocument", + extra={ + "serviceName": "google.developers.knowledge.v1.DeveloperKnowledge", + "rpcName": "GetDocument", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = DeveloperKnowledgeRestTransport._GetDocument._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = developerknowledge.Document() + pb_resp = developerknowledge.Document.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_document(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_document_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = developerknowledge.Document.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.developers.knowledge_v1.DeveloperKnowledgeClient.get_document", + extra={ + "serviceName": "google.developers.knowledge.v1.DeveloperKnowledge", + "rpcName": "GetDocument", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _SearchDocumentChunks( + _BaseDeveloperKnowledgeRestTransport._BaseSearchDocumentChunks, + DeveloperKnowledgeRestStub, + ): + def __hash__(self): + return hash("DeveloperKnowledgeRestTransport.SearchDocumentChunks") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: developerknowledge.SearchDocumentChunksRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> developerknowledge.SearchDocumentChunksResponse: + r"""Call the search document chunks method over HTTP. + + Args: + request (~.developerknowledge.SearchDocumentChunksRequest): + The request object. Request message for + [DeveloperKnowledge.SearchDocumentChunks][google.developers.knowledge.v1.DeveloperKnowledge.SearchDocumentChunks]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.developerknowledge.SearchDocumentChunksResponse: + Response message for + [DeveloperKnowledge.SearchDocumentChunks][google.developers.knowledge.v1.DeveloperKnowledge.SearchDocumentChunks]. + + """ + + http_options = _BaseDeveloperKnowledgeRestTransport._BaseSearchDocumentChunks._get_http_options() + + request, metadata = self._interceptor.pre_search_document_chunks( + request, metadata + ) + transcoded_request = _BaseDeveloperKnowledgeRestTransport._BaseSearchDocumentChunks._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseDeveloperKnowledgeRestTransport._BaseSearchDocumentChunks._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.developers.knowledge_v1.DeveloperKnowledgeClient.SearchDocumentChunks", + extra={ + "serviceName": "google.developers.knowledge.v1.DeveloperKnowledge", + "rpcName": "SearchDocumentChunks", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + DeveloperKnowledgeRestTransport._SearchDocumentChunks._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = developerknowledge.SearchDocumentChunksResponse() + pb_resp = developerknowledge.SearchDocumentChunksResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_search_document_chunks(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_search_document_chunks_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + developerknowledge.SearchDocumentChunksResponse.to_json( + response + ) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.developers.knowledge_v1.DeveloperKnowledgeClient.search_document_chunks", + extra={ + "serviceName": "google.developers.knowledge.v1.DeveloperKnowledge", + "rpcName": "SearchDocumentChunks", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def batch_get_documents( + self, + ) -> Callable[ + [developerknowledge.BatchGetDocumentsRequest], + developerknowledge.BatchGetDocumentsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchGetDocuments(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_document( + self, + ) -> Callable[[developerknowledge.GetDocumentRequest], developerknowledge.Document]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetDocument(self._session, self._host, self._interceptor) # type: ignore + + @property + def search_document_chunks( + self, + ) -> Callable[ + [developerknowledge.SearchDocumentChunksRequest], + developerknowledge.SearchDocumentChunksResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._SearchDocumentChunks(self._session, self._host, self._interceptor) # type: ignore + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("DeveloperKnowledgeRestTransport",) diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/rest_base.py b/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/rest_base.py new file mode 100644 index 000000000000..b0e62a922cfa --- /dev/null +++ b/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/rest_base.py @@ -0,0 +1,236 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import json_format + +from google.developers_knowledge_v1.types import developerknowledge + +from .base import DEFAULT_CLIENT_INFO, DeveloperKnowledgeTransport + + +class _BaseDeveloperKnowledgeRestTransport(DeveloperKnowledgeTransport): + """Base REST backend transport for DeveloperKnowledge. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "developerknowledge.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'developerknowledge.googleapis.com'). + credentials (Optional[Any]): 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. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseBatchGetDocuments: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "names": "", + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/documents:batchGet", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = developerknowledge.BatchGetDocumentsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDeveloperKnowledgeRestTransport._BaseBatchGetDocuments._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetDocument: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=documents/**}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = developerknowledge.GetDocumentRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDeveloperKnowledgeRestTransport._BaseGetDocument._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseSearchDocumentChunks: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "query": "", + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/documents:searchDocumentChunks", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = developerknowledge.SearchDocumentChunksRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDeveloperKnowledgeRestTransport._BaseSearchDocumentChunks._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseDeveloperKnowledgeRestTransport",) diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/types/__init__.py b/packages/google-developers-knowledge/google/developers_knowledge_v1/types/__init__.py new file mode 100644 index 000000000000..ec2947d921b3 --- /dev/null +++ b/packages/google-developers-knowledge/google/developers_knowledge_v1/types/__init__.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 .developerknowledge import ( + BatchGetDocumentsRequest, + BatchGetDocumentsResponse, + Document, + DocumentChunk, + DocumentView, + GetDocumentRequest, + SearchDocumentChunksRequest, + SearchDocumentChunksResponse, +) + +__all__ = ( + "BatchGetDocumentsRequest", + "BatchGetDocumentsResponse", + "Document", + "DocumentChunk", + "GetDocumentRequest", + "SearchDocumentChunksRequest", + "SearchDocumentChunksResponse", + "DocumentView", +) diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/types/developerknowledge.py b/packages/google-developers-knowledge/google/developers_knowledge_v1/types/developerknowledge.py new file mode 100644 index 000000000000..c39eb80c82cb --- /dev/null +++ b/packages/google-developers-knowledge/google/developers_knowledge_v1/types/developerknowledge.py @@ -0,0 +1,413 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.developers.knowledge.v1", + manifest={ + "DocumentView", + "Document", + "SearchDocumentChunksRequest", + "SearchDocumentChunksResponse", + "GetDocumentRequest", + "BatchGetDocumentsRequest", + "BatchGetDocumentsResponse", + "DocumentChunk", + }, +) + + +class DocumentView(proto.Enum): + r"""Specifies which fields of the + [Document][google.developers.knowledge.v1.Document] are included. + + Values: + DOCUMENT_VIEW_UNSPECIFIED (0): + The default / unset value. See each API method for its + default value if + [DocumentView][google.developers.knowledge.v1.DocumentView] + is not specified. + DOCUMENT_VIEW_BASIC (1): + Includes only the basic metadata fields: + + - ``name`` + - ``uri`` + - ``data_source`` + - ``title`` + - ``description`` + - ``update_time`` + - ``view`` + + This is the default of view for + [DeveloperKnowledge.SearchDocumentChunks][google.developers.knowledge.v1.DeveloperKnowledge.SearchDocumentChunks]. + DOCUMENT_VIEW_FULL (2): + Includes all + [Document][google.developers.knowledge.v1.Document] fields. + DOCUMENT_VIEW_CONTENT (3): + Includes the ``DOCUMENT_VIEW_BASIC`` fields and the + ``content`` field. + + This is the default of view for + [DeveloperKnowledge.GetDocument][google.developers.knowledge.v1.DeveloperKnowledge.GetDocument] + and + [DeveloperKnowledge.BatchGetDocuments][google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments]. + """ + + DOCUMENT_VIEW_UNSPECIFIED = 0 + DOCUMENT_VIEW_BASIC = 1 + DOCUMENT_VIEW_FULL = 2 + DOCUMENT_VIEW_CONTENT = 3 + + +class Document(proto.Message): + r"""A Document represents a piece of content from the Developer + Knowledge corpus. + + Attributes: + name (str): + Identifier. Contains the resource name of the document. + Format: ``documents/{uri_without_scheme}`` Example: + ``documents/docs.cloud.google.com/storage/docs/creating-buckets`` + uri (str): + Output only. Provides the URI of the content, such as + ``docs.cloud.google.com/storage/docs/creating-buckets``. + content (str): + Output only. Contains the full content of the + document in Markdown format. + description (str): + Output only. Provides a description of the + document. + data_source (str): + Output only. Specifies the data source of the document. + Example data source: ``firebase.google.com`` + title (str): + Output only. Provides the title of the + document. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Represents the timestamp when + the content or metadata of the document was last + updated. + view (google.developers_knowledge_v1.types.DocumentView): + Output only. Specifies the + [DocumentView][google.developers.knowledge.v1.DocumentView] + of the document. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + uri: str = proto.Field( + proto.STRING, + number=2, + ) + content: str = proto.Field( + proto.STRING, + number=3, + ) + description: str = proto.Field( + proto.STRING, + number=4, + ) + data_source: str = proto.Field( + proto.STRING, + number=5, + ) + title: str = proto.Field( + proto.STRING, + number=6, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=7, + message=timestamp_pb2.Timestamp, + ) + view: "DocumentView" = proto.Field( + proto.ENUM, + number=8, + enum="DocumentView", + ) + + +class SearchDocumentChunksRequest(proto.Message): + r"""Request message for + [DeveloperKnowledge.SearchDocumentChunks][google.developers.knowledge.v1.DeveloperKnowledge.SearchDocumentChunks]. + + Attributes: + query (str): + Required. Provides the raw query string + provided by the user, such as "How to create a + Cloud Storage bucket?". + page_size (int): + Optional. Specifies the maximum number of results to return. + The service may return fewer than this value. + + If unspecified, at most 5 results will be returned. + + The maximum value is 20; values above 20 will result in an + INVALID_ARGUMENT error. + page_token (str): + Optional. Contains a page token, received from a previous + ``SearchDocumentChunks`` call. Provide this to retrieve the + subsequent page. + filter (str): + Optional. Applies a strict filter to the search results. The + expression supports a subset of the syntax described at + https://google.aip.dev/160. + + While ``SearchDocumentChunks`` returns + [DocumentChunk][google.developers.knowledge.v1.DocumentChunk]s, + the filter is applied to ``DocumentChunk.document`` fields. + + Supported fields for filtering: + + - ``data_source`` (STRING): The source of the document, e.g. + ``docs.cloud.google.com``. See + https://developers.google.com/knowledge/reference/corpus-reference + for the complete list of data sources in the corpus. + - ``update_time`` (TIMESTAMP): The timestamp of when the + document was last meaningfully updated. A meaningful + update is one that changes document's markdown content or + metadata. + - ``uri`` (STRING): The document URI, e.g. + ``https://docs.cloud.google.com/bigquery/docs/tables``. + + STRING fields support ``=`` (equals) and ``!=`` (not equals) + operators for **exact match** on the whole string. Partial + match, prefix match, and regexp match are not supported. + + TIMESTAMP fields support ``=``, ``<``, ``<=``, ``>``, and + ``>=`` operators. Timestamps must be in RFC-3339 format, + e.g., ``"2025-01-01T00:00:00Z"``. + + You can combine expressions using ``AND``, ``OR``, and + ``NOT`` (or ``-``) logical operators. ``OR`` has higher + precedence than ``AND``. Use parentheses for explicit + precedence grouping. + + Examples: + + - ``data_source = "docs.cloud.google.com" OR data_source = "firebase.google.com"`` + - ``data_source != "firebase.google.com"`` + - ``update_time < "2024-01-01T00:00:00Z"`` + - ``update_time >= "2025-01-22T00:00:00Z" AND (data_source = "developer.chrome.com" OR data_source = "web.dev")`` + - ``uri = "https://docs.cloud.google.com/release-notes"`` + + The ``filter`` string must not exceed 500 characters; values + longer than 500 characters will result in an + ``INVALID_ARGUMENT`` error. + """ + + query: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + + +class SearchDocumentChunksResponse(proto.Message): + r"""Response message for + [DeveloperKnowledge.SearchDocumentChunks][google.developers.knowledge.v1.DeveloperKnowledge.SearchDocumentChunks]. + + Attributes: + results (MutableSequence[google.developers_knowledge_v1.types.DocumentChunk]): + Contains the search results for the given query. Each + [DocumentChunk][google.developers.knowledge.v1.DocumentChunk] + in this list contains a snippet of content relevant to the + search query. Use the + [DocumentChunk.parent][google.developers.knowledge.v1.DocumentChunk.parent] + field of each result with + [DeveloperKnowledge.GetDocument][google.developers.knowledge.v1.DeveloperKnowledge.GetDocument] + or + [DeveloperKnowledge.BatchGetDocuments][google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments] + to retrieve the full document content. + next_page_token (str): + Optional. Provides a token that can be sent as + ``page_token`` to retrieve the next page. If this field is + omitted, there are no subsequent pages. + """ + + @property + def raw_page(self): + return self + + results: MutableSequence["DocumentChunk"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="DocumentChunk", + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class GetDocumentRequest(proto.Message): + r"""Request message for + [DeveloperKnowledge.GetDocument][google.developers.knowledge.v1.DeveloperKnowledge.GetDocument]. + + Attributes: + name (str): + Required. Specifies the name of the document to retrieve. + Format: ``documents/{uri_without_scheme}`` Example: + ``documents/docs.cloud.google.com/storage/docs/creating-buckets`` + view (google.developers_knowledge_v1.types.DocumentView): + Optional. Specifies the + [DocumentView][google.developers.knowledge.v1.DocumentView] + of the document. If unspecified, + [DeveloperKnowledge.GetDocument][google.developers.knowledge.v1.DeveloperKnowledge.GetDocument] + defaults to ``DOCUMENT_VIEW_CONTENT``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + view: "DocumentView" = proto.Field( + proto.ENUM, + number=2, + enum="DocumentView", + ) + + +class BatchGetDocumentsRequest(proto.Message): + r"""Request message for + [DeveloperKnowledge.BatchGetDocuments][google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments]. + + Attributes: + names (MutableSequence[str]): + Required. Specifies the names of the documents to retrieve. + A maximum of 20 documents can be retrieved in a batch. The + documents are returned in the same order as the ``names`` in + the request. + + Format: ``documents/{uri_without_scheme}`` Example: + ``documents/docs.cloud.google.com/storage/docs/creating-buckets`` + view (google.developers_knowledge_v1.types.DocumentView): + Optional. Specifies the + [DocumentView][google.developers.knowledge.v1.DocumentView] + of the document. If unspecified, + [DeveloperKnowledge.BatchGetDocuments][google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments] + defaults to ``DOCUMENT_VIEW_CONTENT``. + """ + + names: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + view: "DocumentView" = proto.Field( + proto.ENUM, + number=2, + enum="DocumentView", + ) + + +class BatchGetDocumentsResponse(proto.Message): + r"""Response message for + [DeveloperKnowledge.BatchGetDocuments][google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments]. + + Attributes: + documents (MutableSequence[google.developers_knowledge_v1.types.Document]): + Contains the documents requested. + """ + + documents: MutableSequence["Document"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="Document", + ) + + +class DocumentChunk(proto.Message): + r"""A DocumentChunk represents a piece of content from a + [Document][google.developers.knowledge.v1.Document] in the + DeveloperKnowledge corpus. To fetch the entire document content, + pass the ``parent`` to + [DeveloperKnowledge.GetDocument][google.developers.knowledge.v1.DeveloperKnowledge.GetDocument] + or + [DeveloperKnowledge.BatchGetDocuments][google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments]. + + Attributes: + parent (str): + Output only. Contains the resource name of the document this + chunk is from. Format: ``documents/{uri_without_scheme}`` + Example: + ``documents/docs.cloud.google.com/storage/docs/creating-buckets`` + id (str): + Output only. Specifies the ID of this chunk + within the document. The chunk ID is unique + within a document, but not globally unique + across documents. The chunk ID is not stable and + may change over time. + content (str): + Output only. Contains the content of the + document chunk. + document (google.developers_knowledge_v1.types.Document): + Output only. Represents metadata about the + [Document][google.developers.knowledge.v1.Document] this + chunk is from. The + [DocumentView][google.developers.knowledge.v1.DocumentView] + of this [Document][google.developers.knowledge.v1.Document] + message will be set to ``DOCUMENT_VIEW_BASIC``. It is + included here for convenience so that clients do not need to + call + [DeveloperKnowledge.GetDocument][google.developers.knowledge.v1.DeveloperKnowledge.GetDocument] + or + [DeveloperKnowledge.BatchGetDocuments][google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments] + if they only need the metadata fields. Otherwise, clients + should use + [DeveloperKnowledge.GetDocument][google.developers.knowledge.v1.DeveloperKnowledge.GetDocument] + or + [DeveloperKnowledge.BatchGetDocuments][google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments] + to fetch the full document content. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + id: str = proto.Field( + proto.STRING, + number=2, + ) + content: str = proto.Field( + proto.STRING, + number=3, + ) + document: "Document" = proto.Field( + proto.MESSAGE, + number=4, + message="Document", + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-developers-knowledge/mypy.ini b/packages/google-developers-knowledge/mypy.ini new file mode 100644 index 000000000000..e0e0da2e9e40 --- /dev/null +++ b/packages/google-developers-knowledge/mypy.ini @@ -0,0 +1,15 @@ +[mypy] +python_version = 3.14 +namespace_packages = True +ignore_missing_imports = False + +# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): +# Dependencies that historically lacks py.typed markers +[mypy-google.iam.*] +ignore_missing_imports = True + +# Helps mypy navigate the 'google' namespace more reliably in 3.10+ +explicit_package_bases = True + +# Performance: reuse results from previous runs to speed up 'nox' +incremental = True diff --git a/packages/google-developers-knowledge/noxfile.py b/packages/google-developers-knowledge/noxfile.py new file mode 100644 index 000000000000..e61a256304dd --- /dev/null +++ b/packages/google-developers-knowledge/noxfile.py @@ -0,0 +1,639 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 re +import shutil +import warnings +from typing import Dict, List + +import nox + +RUFF_VERSION = "ruff==0.14.14" + +LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] + +# Add samples to the list of directories to format if the directory exists. +if os.path.isdir("samples"): + LINT_PATHS.append("samples") + +ALL_PYTHON = [ + "3.10", + "3.11", + "3.12", + "3.13", + "3.14", +] + +DEFAULT_PYTHON_VERSION = "3.14" + +# TODO(https://github.com/googleapis/gapic-generator-python/issues/2450): +# Switch this to Python 3.15 alpha1 +# https://peps.python.org/pep-0790/ +PREVIEW_PYTHON_VERSION = "3.14" + +CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() + +if (CURRENT_DIRECTORY / "testing").exists(): + LOWER_BOUND_CONSTRAINTS_FILE = ( + CURRENT_DIRECTORY / "testing" / f"constraints-{ALL_PYTHON[0]}.txt" + ) +else: + LOWER_BOUND_CONSTRAINTS_FILE = CURRENT_DIRECTORY / "constraints.txt" +PACKAGE_NAME = "google-developers-knowledge" + +UNIT_TEST_STANDARD_DEPENDENCIES = [ + "mock", + "asyncmock", + "pytest", + "pytest-cov", + "pytest-asyncio", +] +UNIT_TEST_EXTERNAL_DEPENDENCIES: List[str] = [] +UNIT_TEST_LOCAL_DEPENDENCIES: List[str] = [] +UNIT_TEST_DEPENDENCIES: List[str] = [] +UNIT_TEST_EXTRAS: List[str] = [] +UNIT_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} + +SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ALL_PYTHON +SYSTEM_TEST_STANDARD_DEPENDENCIES = [ + "mock", + "pytest", + "google-cloud-testutils", +] +SYSTEM_TEST_EXTERNAL_DEPENDENCIES: List[str] = [] +SYSTEM_TEST_LOCAL_DEPENDENCIES: List[str] = [] +SYSTEM_TEST_DEPENDENCIES: List[str] = [] +SYSTEM_TEST_EXTRAS: List[str] = [] +SYSTEM_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} + +nox.options.sessions = [ + "unit", + "system", + "cover", + "lint", + "lint_setup_py", + "blacken", + "docs", +] + +# Error if a python version is missing +nox.options.error_on_missing_interpreters = True + + +@nox.session(python=ALL_PYTHON) +def mypy(session): + """Run the type checker.""" + # TODO(https://github.com/googleapis/gapic-generator-python/issues/2579): + # use the latest version of mypy + session.install( + "mypy<1.16.0", + "types-requests", + "types-protobuf", + ) + session.install(".") + session.run( + "mypy", + "-p", + "google", + "--check-untyped-defs", + *session.posargs, + ) + + +@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=DEFAULT_PYTHON_VERSION) +def lint(session): + """Run linters. + + Returns a failure if the linters find linting errors or sufficiently + serious code quality issues. + """ + session.install("flake8", RUFF_VERSION) + + # 2. Check formatting + session.run( + "ruff", + "format", + "--check", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", + *LINT_PATHS, + ) + + session.run("flake8", "google", "tests") + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def blacken(session): + """(Deprecated) Legacy session. Please use 'nox -s format'.""" + session.log( + "WARNING: The 'blacken' session is deprecated and will be removed in a future release. Please use 'nox -s format' in the future." + ) + + # Just run the ruff formatter (keeping legacy behavior of only formatting, not sorting imports) + session.install(RUFF_VERSION) + session.run( + "ruff", + "format", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", + *LINT_PATHS, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def format(session): + """ + Run ruff to sort imports and format code. + """ + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports + # check --select I: Enables strict import sorting + # --fix: Applies the changes automatically + session.run( + "ruff", + "check", + "--select", + "I", + "--fix", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", # Standard Black line length + *LINT_PATHS, + ) + + # 3. Run Ruff to format code + session.run( + "ruff", + "format", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", # Standard Black line length + *LINT_PATHS, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def lint_setup_py(session): + """Verify that setup.py is valid (including RST check).""" + session.install("setuptools", "docutils", "pygments") + session.run("python", "setup.py", "check", "--restructuredtext", "--strict") + + +def install_unittest_dependencies(session, *constraints): + standard_deps = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_DEPENDENCIES + session.install(*standard_deps, *constraints) + + if UNIT_TEST_EXTERNAL_DEPENDENCIES: + warnings.warn( + "'unit_test_external_dependencies' is deprecated. Instead, please " + "use 'unit_test_dependencies' or 'unit_test_local_dependencies'.", + DeprecationWarning, + ) + session.install(*UNIT_TEST_EXTERNAL_DEPENDENCIES, *constraints) + + if UNIT_TEST_LOCAL_DEPENDENCIES: + session.install(*UNIT_TEST_LOCAL_DEPENDENCIES, *constraints) + + if UNIT_TEST_EXTRAS_BY_PYTHON: + extras = UNIT_TEST_EXTRAS_BY_PYTHON.get(session.python, []) + elif UNIT_TEST_EXTRAS: + extras = UNIT_TEST_EXTRAS + else: + extras = [] + + if extras: + session.install("-e", f".[{','.join(extras)}]", *constraints) + else: + session.install("-e", ".", *constraints) + + +@nox.session(python=ALL_PYTHON) +@nox.parametrize( + "protobuf_implementation", + ["python", "upb"], +) +def unit(session, protobuf_implementation): + # Install all test dependencies, then install this package in-place. + + constraints_path = str( + CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" + ) + install_unittest_dependencies(session, "-c", constraints_path) + + # Run py.test against the unit tests. + session.run( + "py.test", + "--quiet", + f"--junitxml=unit_{session.python}_sponge_log.xml", + "--cov=google", + "--cov=tests/unit", + "--cov-append", + "--cov-config=.coveragerc", + "--cov-report=", + "--cov-fail-under=0", + os.path.join("tests", "unit"), + *session.posargs, + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) + + +def install_systemtest_dependencies(session, *constraints): + if session.python >= "3.12": + session.install("--pre", "grpcio>=1.75.1") + else: + session.install("--pre", "grpcio<=1.62.2") + + session.install(*SYSTEM_TEST_STANDARD_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_EXTERNAL_DEPENDENCIES: + session.install(*SYSTEM_TEST_EXTERNAL_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_LOCAL_DEPENDENCIES: + session.install("-e", *SYSTEM_TEST_LOCAL_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_DEPENDENCIES: + session.install("-e", *SYSTEM_TEST_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_EXTRAS_BY_PYTHON: + extras = SYSTEM_TEST_EXTRAS_BY_PYTHON.get(session.python, []) + elif SYSTEM_TEST_EXTRAS: + extras = SYSTEM_TEST_EXTRAS + else: + extras = [] + + if extras: + session.install("-e", f".[{','.join(extras)}]", *constraints) + else: + session.install("-e", ".", *constraints) + + +@nox.session(python=SYSTEM_TEST_PYTHON_VERSIONS) +def system(session): + """Run the system test suite.""" + constraints_path = str( + CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" + ) + system_test_path = os.path.join("tests", "system.py") + system_test_folder_path = os.path.join("tests", "system") + + # Check the value of `RUN_SYSTEM_TESTS` env var. It defaults to true. + if os.environ.get("RUN_SYSTEM_TESTS", "true") == "false": + session.skip("RUN_SYSTEM_TESTS is set to false, skipping") + # Install pyopenssl for mTLS testing. + if os.environ.get("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true": + session.install("pyopenssl") + + system_test_exists = os.path.exists(system_test_path) + system_test_folder_exists = os.path.exists(system_test_folder_path) + # Sanity check: only run tests if found. + if not system_test_exists and not system_test_folder_exists: + session.skip("System tests were not found") + + install_systemtest_dependencies(session, "-c", constraints_path) + + # Run py.test against the system tests. + if system_test_exists: + session.run( + "py.test", + "--quiet", + f"--junitxml=system_{session.python}_sponge_log.xml", + system_test_path, + *session.posargs, + ) + if system_test_folder_exists: + session.run( + "py.test", + "--quiet", + f"--junitxml=system_{session.python}_sponge_log.xml", + system_test_folder_path, + *session.posargs, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +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.10") +def docs(session): + """Build the docs for this library.""" + + session.install("-e", ".") + session.install( + # We need to pin to specific versions of the `sphinxcontrib-*` packages + # which still support sphinx 4.x. + # See https://github.com/googleapis/sphinx-docfx-yaml/issues/344 + # and https://github.com/googleapis/sphinx-docfx-yaml/issues/345. + "sphinxcontrib-applehelp==1.0.4", + "sphinxcontrib-devhelp==1.0.2", + "sphinxcontrib-htmlhelp==2.0.1", + "sphinxcontrib-qthelp==1.0.3", + "sphinxcontrib-serializinghtml==1.1.5", + "sphinx==4.5.0", + "alabaster", + "recommonmark", + ) + + shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) + session.run( + "sphinx-build", + "-T", # show full traceback on exception + "-N", # no colors + "-b", + "html", # builder + "-d", + os.path.join("docs", "_build", "doctrees", ""), # cache directory + # paths to build: + os.path.join("docs", ""), + os.path.join("docs", "_build", "html", ""), + ) + + +@nox.session(python="3.10") +def docfx(session): + """Build the docfx yaml files for this library.""" + + session.install("-e", ".") + session.install( + # We need to pin to specific versions of the `sphinxcontrib-*` packages + # which still support sphinx 4.x. + # See https://github.com/googleapis/sphinx-docfx-yaml/issues/344 + # and https://github.com/googleapis/sphinx-docfx-yaml/issues/345. + "sphinxcontrib-applehelp==1.0.4", + "sphinxcontrib-devhelp==1.0.2", + "sphinxcontrib-htmlhelp==2.0.1", + "sphinxcontrib-qthelp==1.0.3", + "sphinxcontrib-serializinghtml==1.1.5", + "gcp-sphinx-docfx-yaml", + "alabaster", + "recommonmark", + ) + + shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) + session.run( + "sphinx-build", + "-T", # show full traceback on exception + "-N", # no colors + "-D", + ( + "extensions=sphinx.ext.autodoc," + "sphinx.ext.autosummary," + "docfx_yaml.extension," + "sphinx.ext.intersphinx," + "sphinx.ext.coverage," + "sphinx.ext.napoleon," + "sphinx.ext.todo," + "sphinx.ext.viewcode," + "recommonmark" + ), + "-b", + "html", + "-d", + os.path.join("docs", "_build", "doctrees", ""), + os.path.join("docs", ""), + os.path.join("docs", "_build", "html", ""), + ) + + +@nox.session(python=PREVIEW_PYTHON_VERSION) +@nox.parametrize( + "protobuf_implementation", + ["python", "upb"], +) +def prerelease_deps(session, protobuf_implementation): + """ + Run all tests with pre-release versions of dependencies installed + rather than the standard non pre-release versions. + Pre-release versions can be installed using + `pip install --pre `. + """ + + # Install all dependencies + session.install("-e", ".") + + # Install dependencies for the unit test environment + unit_deps_all = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_EXTERNAL_DEPENDENCIES + session.install(*unit_deps_all) + + # Because we test minimum dependency versions on the minimum Python + # version, the first version we test with in the unit tests sessions has a + # constraints file containing all dependencies and extras. + with open( + CURRENT_DIRECTORY / "testing" / f"constraints-{ALL_PYTHON[0]}.txt", + encoding="utf-8", + ) as constraints_file: + constraints_text = constraints_file.read() + + # Ignore leading whitespace and comment lines. + constraints_deps = [ + match.group(1) + for match in re.finditer( + r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE + ) + ] + + # Install dependencies specified in `testing/constraints-X.txt`. + session.install(*constraints_deps) + + # Note: If a dependency is added to the `prerel_deps` list, + # the `core_dependencies_from_source` list in the `core_deps_from_source` + # nox session should also be updated. + prerel_deps = [ + "googleapis-common-protos", + "google-api-core", + "google-auth", + "grpc-google-iam-v1", + "grpcio>=1.75.1" if session.python >= "3.12" else "grpcio<=1.62.2", + "grpcio-status", + "protobuf", + "proto-plus", + ] + + deps_dir = CURRENT_DIRECTORY.parent + while deps_dir.name != "packages" and deps_dir.parent != deps_dir: + deps_dir = deps_dir.parent + + # Extract the base package name, safely ignoring version bounds and spaces + # (e.g., "grpcio>=1.75.1" becomes "grpcio") + parsed_deps = { + dep: re.match(r"^([a-zA-Z0-9_-]+)", dep).group(1) for dep in prerel_deps + } + + # Dynamically sort local packages vs PyPI dependencies + local_paths = [] + pypi_deps = [] + + for dep, pkg_name in parsed_deps.items(): + if (deps_dir / pkg_name).exists(): + local_paths.append(str(deps_dir / pkg_name)) + else: + pypi_deps.append(dep) + + # Batch pip installations to avoid sequential overhead + if local_paths: + session.install(*local_paths, "--no-deps", "--ignore-installed") + if pypi_deps: + session.install(*pypi_deps, "--pre", "--no-deps", "--ignore-installed") + + # TODO(https://github.com/grpc/grpc/issues/38965): Add `grpcio-status`` + # to the dictionary below once this bug is fixed. + # TODO(https://github.com/googleapis/google-cloud-python/issues/13643): Add + # `googleapis-common-protos` and `grpc-google-iam-v1` to the dictionary below + # once this bug is fixed. + package_namespaces = { + "google-api-core": "google.api_core", + "google-auth": "google.auth", + "grpcio": "grpc", + "protobuf": "google.protobuf", + "proto-plus": "proto", + } + + # Reuse the parsed names for logging and version verification + for dep, pkg_name in parsed_deps.items(): + print(f"Installed {dep}") + version_namespace = package_namespaces.get(pkg_name) + + if version_namespace: + session.run( + "python", + "-c", + f"import {version_namespace}; print({version_namespace}.__version__)", + ) + + session.run( + "py.test", + "tests/unit", + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +@nox.parametrize( + "protobuf_implementation", + ["python", "upb"], +) +def core_deps_from_source(session, protobuf_implementation): + """Run all tests with core dependencies installed from source + rather than pulling the dependencies from PyPI. + """ + + # Install all dependencies + session.install("-e", ".") + + # Install dependencies for the unit test environment + unit_deps_all = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_EXTERNAL_DEPENDENCIES + session.install(*unit_deps_all) + + # Because we test minimum dependency versions on the minimum Python + # version, the first version we test with in the unit tests sessions has a + # constraints file containing all dependencies and extras. + with open( + CURRENT_DIRECTORY / "testing" / f"constraints-{ALL_PYTHON[0]}.txt", + encoding="utf-8", + ) as constraints_file: + constraints_text = constraints_file.read() + + # Ignore leading whitespace and comment lines. + constraints_deps = [ + match.group(1) + for match in re.finditer( + r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE + ) + ] + + # Install dependencies specified in `testing/constraints-X.txt`. + session.install(*constraints_deps) + + # TODO(https://github.com/googleapis/gapic-generator-python/issues/2358): `grpcio` and + # `grpcio-status` should be added to the list below so that they are installed from source, + # rather than PyPI. + # TODO(https://github.com/googleapis/gapic-generator-python/issues/2357): `protobuf` should be + # added to the list below so that it is installed from source, rather than PyPI + # Note: If a dependency is added to the `core_dependencies_from_source` list, + # the `prerel_deps` list in the `prerelease_deps` nox session should also be updated. + core_dependencies_from_source = [ + "googleapis-common-protos", + "google-api-core", + "google-auth", + "grpc-google-iam-v1", + "proto-plus", + ] + + deps_dir = CURRENT_DIRECTORY.parent + while deps_dir.name != "packages" and deps_dir.parent != deps_dir: + deps_dir = deps_dir.parent + + # Batch the pip installation to avoid sequential overhead + dep_paths = [str(deps_dir / dep) for dep in core_dependencies_from_source] + + session.install(*dep_paths, "--no-deps", "--ignore-installed") + print( + f"Installed {', '.join(core_dependencies_from_source)} locally from {deps_dir}" + ) + + session.run( + "py.test", + "tests/unit", + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) diff --git a/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_batch_get_documents_async.py b/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_batch_get_documents_async.py new file mode 100644 index 000000000000..8d801d2c521f --- /dev/null +++ b/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_batch_get_documents_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchGetDocuments +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-developers-knowledge + + +# [START developerknowledge_v1_generated_DeveloperKnowledge_BatchGetDocuments_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google import developers_knowledge_v1 + + +async def sample_batch_get_documents(): + # Create a client + client = developers_knowledge_v1.DeveloperKnowledgeAsyncClient() + + # Initialize request argument(s) + request = developers_knowledge_v1.BatchGetDocumentsRequest( + names=["names_value1", "names_value2"], + ) + + # Make the request + response = await client.batch_get_documents(request=request) + + # Handle the response + print(response) + + +# [END developerknowledge_v1_generated_DeveloperKnowledge_BatchGetDocuments_async] diff --git a/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_batch_get_documents_sync.py b/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_batch_get_documents_sync.py new file mode 100644 index 000000000000..75c3d903bd65 --- /dev/null +++ b/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_batch_get_documents_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchGetDocuments +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-developers-knowledge + + +# [START developerknowledge_v1_generated_DeveloperKnowledge_BatchGetDocuments_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google import developers_knowledge_v1 + + +def sample_batch_get_documents(): + # Create a client + client = developers_knowledge_v1.DeveloperKnowledgeClient() + + # Initialize request argument(s) + request = developers_knowledge_v1.BatchGetDocumentsRequest( + names=["names_value1", "names_value2"], + ) + + # Make the request + response = client.batch_get_documents(request=request) + + # Handle the response + print(response) + + +# [END developerknowledge_v1_generated_DeveloperKnowledge_BatchGetDocuments_sync] diff --git a/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_get_document_async.py b/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_get_document_async.py new file mode 100644 index 000000000000..70d14f7df658 --- /dev/null +++ b/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_get_document_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetDocument +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-developers-knowledge + + +# [START developerknowledge_v1_generated_DeveloperKnowledge_GetDocument_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google import developers_knowledge_v1 + + +async def sample_get_document(): + # Create a client + client = developers_knowledge_v1.DeveloperKnowledgeAsyncClient() + + # Initialize request argument(s) + request = developers_knowledge_v1.GetDocumentRequest( + name="name_value", + ) + + # Make the request + response = await client.get_document(request=request) + + # Handle the response + print(response) + + +# [END developerknowledge_v1_generated_DeveloperKnowledge_GetDocument_async] diff --git a/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_get_document_sync.py b/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_get_document_sync.py new file mode 100644 index 000000000000..ab34304febdc --- /dev/null +++ b/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_get_document_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetDocument +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-developers-knowledge + + +# [START developerknowledge_v1_generated_DeveloperKnowledge_GetDocument_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google import developers_knowledge_v1 + + +def sample_get_document(): + # Create a client + client = developers_knowledge_v1.DeveloperKnowledgeClient() + + # Initialize request argument(s) + request = developers_knowledge_v1.GetDocumentRequest( + name="name_value", + ) + + # Make the request + response = client.get_document(request=request) + + # Handle the response + print(response) + + +# [END developerknowledge_v1_generated_DeveloperKnowledge_GetDocument_sync] diff --git a/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_search_document_chunks_async.py b/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_search_document_chunks_async.py new file mode 100644 index 000000000000..a164870b859a --- /dev/null +++ b/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_search_document_chunks_async.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for SearchDocumentChunks +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-developers-knowledge + + +# [START developerknowledge_v1_generated_DeveloperKnowledge_SearchDocumentChunks_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google import developers_knowledge_v1 + + +async def sample_search_document_chunks(): + # Create a client + client = developers_knowledge_v1.DeveloperKnowledgeAsyncClient() + + # Initialize request argument(s) + request = developers_knowledge_v1.SearchDocumentChunksRequest( + query="query_value", + ) + + # Make the request + page_result = client.search_document_chunks(request=request) + + # Handle the response + async for response in page_result: + print(response) + + +# [END developerknowledge_v1_generated_DeveloperKnowledge_SearchDocumentChunks_async] diff --git a/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_search_document_chunks_sync.py b/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_search_document_chunks_sync.py new file mode 100644 index 000000000000..c2c30cbad088 --- /dev/null +++ b/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_search_document_chunks_sync.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for SearchDocumentChunks +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-developers-knowledge + + +# [START developerknowledge_v1_generated_DeveloperKnowledge_SearchDocumentChunks_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google import developers_knowledge_v1 + + +def sample_search_document_chunks(): + # Create a client + client = developers_knowledge_v1.DeveloperKnowledgeClient() + + # Initialize request argument(s) + request = developers_knowledge_v1.SearchDocumentChunksRequest( + query="query_value", + ) + + # Make the request + page_result = client.search_document_chunks(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END developerknowledge_v1_generated_DeveloperKnowledge_SearchDocumentChunks_sync] diff --git a/packages/google-developers-knowledge/samples/generated_samples/snippet_metadata_google.developers.knowledge.v1.json b/packages/google-developers-knowledge/samples/generated_samples/snippet_metadata_google.developers.knowledge.v1.json new file mode 100644 index 000000000000..71c0bd01267e --- /dev/null +++ b/packages/google-developers-knowledge/samples/generated_samples/snippet_metadata_google.developers.knowledge.v1.json @@ -0,0 +1,482 @@ +{ + "clientLibrary": { + "apis": [ + { + "id": "google.developers.knowledge.v1", + "version": "v1" + } + ], + "language": "PYTHON", + "name": "google-developers-knowledge", + "version": "0.0.0" + }, + "snippets": [ + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.developers_knowledge_v1.DeveloperKnowledgeAsyncClient", + "shortName": "DeveloperKnowledgeAsyncClient" + }, + "fullName": "google.developers_knowledge_v1.DeveloperKnowledgeAsyncClient.batch_get_documents", + "method": { + "fullName": "google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments", + "service": { + "fullName": "google.developers.knowledge.v1.DeveloperKnowledge", + "shortName": "DeveloperKnowledge" + }, + "shortName": "BatchGetDocuments" + }, + "parameters": [ + { + "name": "request", + "type": "google.developers_knowledge_v1.types.BatchGetDocumentsRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.developers_knowledge_v1.types.BatchGetDocumentsResponse", + "shortName": "batch_get_documents" + }, + "description": "Sample for BatchGetDocuments", + "file": "developerknowledge_v1_generated_developer_knowledge_batch_get_documents_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "developerknowledge_v1_generated_DeveloperKnowledge_BatchGetDocuments_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "developerknowledge_v1_generated_developer_knowledge_batch_get_documents_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.developers_knowledge_v1.DeveloperKnowledgeClient", + "shortName": "DeveloperKnowledgeClient" + }, + "fullName": "google.developers_knowledge_v1.DeveloperKnowledgeClient.batch_get_documents", + "method": { + "fullName": "google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments", + "service": { + "fullName": "google.developers.knowledge.v1.DeveloperKnowledge", + "shortName": "DeveloperKnowledge" + }, + "shortName": "BatchGetDocuments" + }, + "parameters": [ + { + "name": "request", + "type": "google.developers_knowledge_v1.types.BatchGetDocumentsRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.developers_knowledge_v1.types.BatchGetDocumentsResponse", + "shortName": "batch_get_documents" + }, + "description": "Sample for BatchGetDocuments", + "file": "developerknowledge_v1_generated_developer_knowledge_batch_get_documents_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "developerknowledge_v1_generated_DeveloperKnowledge_BatchGetDocuments_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "developerknowledge_v1_generated_developer_knowledge_batch_get_documents_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.developers_knowledge_v1.DeveloperKnowledgeAsyncClient", + "shortName": "DeveloperKnowledgeAsyncClient" + }, + "fullName": "google.developers_knowledge_v1.DeveloperKnowledgeAsyncClient.get_document", + "method": { + "fullName": "google.developers.knowledge.v1.DeveloperKnowledge.GetDocument", + "service": { + "fullName": "google.developers.knowledge.v1.DeveloperKnowledge", + "shortName": "DeveloperKnowledge" + }, + "shortName": "GetDocument" + }, + "parameters": [ + { + "name": "request", + "type": "google.developers_knowledge_v1.types.GetDocumentRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.developers_knowledge_v1.types.Document", + "shortName": "get_document" + }, + "description": "Sample for GetDocument", + "file": "developerknowledge_v1_generated_developer_knowledge_get_document_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "developerknowledge_v1_generated_DeveloperKnowledge_GetDocument_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "developerknowledge_v1_generated_developer_knowledge_get_document_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.developers_knowledge_v1.DeveloperKnowledgeClient", + "shortName": "DeveloperKnowledgeClient" + }, + "fullName": "google.developers_knowledge_v1.DeveloperKnowledgeClient.get_document", + "method": { + "fullName": "google.developers.knowledge.v1.DeveloperKnowledge.GetDocument", + "service": { + "fullName": "google.developers.knowledge.v1.DeveloperKnowledge", + "shortName": "DeveloperKnowledge" + }, + "shortName": "GetDocument" + }, + "parameters": [ + { + "name": "request", + "type": "google.developers_knowledge_v1.types.GetDocumentRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.developers_knowledge_v1.types.Document", + "shortName": "get_document" + }, + "description": "Sample for GetDocument", + "file": "developerknowledge_v1_generated_developer_knowledge_get_document_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "developerknowledge_v1_generated_DeveloperKnowledge_GetDocument_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "developerknowledge_v1_generated_developer_knowledge_get_document_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.developers_knowledge_v1.DeveloperKnowledgeAsyncClient", + "shortName": "DeveloperKnowledgeAsyncClient" + }, + "fullName": "google.developers_knowledge_v1.DeveloperKnowledgeAsyncClient.search_document_chunks", + "method": { + "fullName": "google.developers.knowledge.v1.DeveloperKnowledge.SearchDocumentChunks", + "service": { + "fullName": "google.developers.knowledge.v1.DeveloperKnowledge", + "shortName": "DeveloperKnowledge" + }, + "shortName": "SearchDocumentChunks" + }, + "parameters": [ + { + "name": "request", + "type": "google.developers_knowledge_v1.types.SearchDocumentChunksRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.developers_knowledge_v1.services.developer_knowledge.pagers.SearchDocumentChunksAsyncPager", + "shortName": "search_document_chunks" + }, + "description": "Sample for SearchDocumentChunks", + "file": "developerknowledge_v1_generated_developer_knowledge_search_document_chunks_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "developerknowledge_v1_generated_DeveloperKnowledge_SearchDocumentChunks_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "developerknowledge_v1_generated_developer_knowledge_search_document_chunks_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.developers_knowledge_v1.DeveloperKnowledgeClient", + "shortName": "DeveloperKnowledgeClient" + }, + "fullName": "google.developers_knowledge_v1.DeveloperKnowledgeClient.search_document_chunks", + "method": { + "fullName": "google.developers.knowledge.v1.DeveloperKnowledge.SearchDocumentChunks", + "service": { + "fullName": "google.developers.knowledge.v1.DeveloperKnowledge", + "shortName": "DeveloperKnowledge" + }, + "shortName": "SearchDocumentChunks" + }, + "parameters": [ + { + "name": "request", + "type": "google.developers_knowledge_v1.types.SearchDocumentChunksRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.developers_knowledge_v1.services.developer_knowledge.pagers.SearchDocumentChunksPager", + "shortName": "search_document_chunks" + }, + "description": "Sample for SearchDocumentChunks", + "file": "developerknowledge_v1_generated_developer_knowledge_search_document_chunks_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "developerknowledge_v1_generated_DeveloperKnowledge_SearchDocumentChunks_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "developerknowledge_v1_generated_developer_knowledge_search_document_chunks_sync.py" + } + ] +} diff --git a/packages/google-developers-knowledge/setup.py b/packages/google-developers-knowledge/setup.py new file mode 100644 index 000000000000..5784d51f6ece --- /dev/null +++ b/packages/google-developers-knowledge/setup.py @@ -0,0 +1,99 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 re + +import setuptools # type: ignore + +package_root = os.path.abspath(os.path.dirname(__file__)) + +name = "google-developers-knowledge" + + +description = "Google Developers Knowledge API client library" + +version = None + +with open( + os.path.join(package_root, "google/developers_knowledge/gapic_version.py") +) as fp: + version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + assert len(version_candidates) == 1 + version = version_candidates[0] + +if version[0] == "0": + release_status = "Development Status :: 4 - Beta" +else: + release_status = "Development Status :: 5 - Production/Stable" + +dependencies = [ + "google-api-core[grpc] >= 2.17.1, <3.0.0", + # Exclude incompatible versions of `google-auth` + # See https://github.com/googleapis/google-cloud-python/issues/12364 + "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", + "grpcio >= 1.59.0, < 2.0.0", + "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", + "proto-plus >= 1.22.3, <2.0.0", + "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", + "protobuf >= 4.25.8, < 8.0.0", +] +extras = {} +url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-developers-knowledge" + +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() + +packages = [ + package + for package in setuptools.find_namespace_packages() + if package.startswith("google") +] + +setuptools.setup( + name=name, + version=version, + description=description, + long_description=readme, + author="Google LLC", + author_email="googleapis-packages@google.com", + license="Apache-2.0", + url=url, + classifiers=[ + release_status, + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", + "Operating System :: OS Independent", + "Topic :: Internet", + ], + platforms="Posix; MacOS X; Windows", + packages=packages, + python_requires=">=3.10", + install_requires=dependencies, + extras_require=extras, + include_package_data=True, + zip_safe=False, +) diff --git a/packages/google-developers-knowledge/testing/constraints-3.10.txt b/packages/google-developers-knowledge/testing/constraints-3.10.txt new file mode 100644 index 000000000000..7be9c36933fc --- /dev/null +++ b/packages/google-developers-knowledge/testing/constraints-3.10.txt @@ -0,0 +1,11 @@ +# This constraints file is used to check that lower bounds +# are correct in setup.py +# List all library dependencies and extras in this file, +# pinning their versions to their lower bounds. +# For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", +# then this file should have google-cloud-foo==1.14.0 +google-api-core==2.17.1 +google-auth==2.14.1 +grpcio==1.59.0 +proto-plus==1.22.3 +protobuf==4.25.8 diff --git a/packages/google-developers-knowledge/testing/constraints-3.11.txt b/packages/google-developers-knowledge/testing/constraints-3.11.txt new file mode 100644 index 000000000000..7599dea499ed --- /dev/null +++ b/packages/google-developers-knowledge/testing/constraints-3.11.txt @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +google-auth +grpcio +proto-plus +protobuf +# cryptography is a direct dependency of google-auth +cryptography diff --git a/packages/google-developers-knowledge/testing/constraints-3.12.txt b/packages/google-developers-knowledge/testing/constraints-3.12.txt new file mode 100644 index 000000000000..7599dea499ed --- /dev/null +++ b/packages/google-developers-knowledge/testing/constraints-3.12.txt @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +google-auth +grpcio +proto-plus +protobuf +# cryptography is a direct dependency of google-auth +cryptography diff --git a/packages/google-developers-knowledge/testing/constraints-3.13.txt b/packages/google-developers-knowledge/testing/constraints-3.13.txt new file mode 100644 index 000000000000..1e93c60e50aa --- /dev/null +++ b/packages/google-developers-knowledge/testing/constraints-3.13.txt @@ -0,0 +1,12 @@ +# We use the constraints file for the latest Python version +# (currently this file) to check that the latest +# major versions of dependencies are supported in setup.py. +# List all library dependencies and extras in this file. +# Require the latest major version be installed for each dependency. +# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", +# Then this file should have google-cloud-foo>=1 +google-api-core>=2 +google-auth>=2 +grpcio>=1 +proto-plus>=1 +protobuf>=6 diff --git a/packages/google-developers-knowledge/testing/constraints-3.14.txt b/packages/google-developers-knowledge/testing/constraints-3.14.txt new file mode 100644 index 000000000000..1e93c60e50aa --- /dev/null +++ b/packages/google-developers-knowledge/testing/constraints-3.14.txt @@ -0,0 +1,12 @@ +# We use the constraints file for the latest Python version +# (currently this file) to check that the latest +# major versions of dependencies are supported in setup.py. +# List all library dependencies and extras in this file. +# Require the latest major version be installed for each dependency. +# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", +# Then this file should have google-cloud-foo>=1 +google-api-core>=2 +google-auth>=2 +grpcio>=1 +proto-plus>=1 +protobuf>=6 diff --git a/packages/google-developers-knowledge/tests/__init__.py b/packages/google-developers-knowledge/tests/__init__.py new file mode 100644 index 000000000000..32b36c5c4fe0 --- /dev/null +++ b/packages/google-developers-knowledge/tests/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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/packages/google-developers-knowledge/tests/unit/__init__.py b/packages/google-developers-knowledge/tests/unit/__init__.py new file mode 100644 index 000000000000..32b36c5c4fe0 --- /dev/null +++ b/packages/google-developers-knowledge/tests/unit/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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/packages/google-developers-knowledge/tests/unit/gapic/__init__.py b/packages/google-developers-knowledge/tests/unit/gapic/__init__.py new file mode 100644 index 000000000000..32b36c5c4fe0 --- /dev/null +++ b/packages/google-developers-knowledge/tests/unit/gapic/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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/packages/google-developers-knowledge/tests/unit/gapic/developers_knowledge_v1/__init__.py b/packages/google-developers-knowledge/tests/unit/gapic/developers_knowledge_v1/__init__.py new file mode 100644 index 000000000000..32b36c5c4fe0 --- /dev/null +++ b/packages/google-developers-knowledge/tests/unit/gapic/developers_knowledge_v1/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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/packages/google-developers-knowledge/tests/unit/gapic/developers_knowledge_v1/test_developer_knowledge.py b/packages/google-developers-knowledge/tests/unit/gapic/developers_knowledge_v1/test_developer_knowledge.py new file mode 100644 index 000000000000..b92aec170daa --- /dev/null +++ b/packages/google-developers-knowledge/tests/unit/gapic/developers_knowledge_v1/test_developer_knowledge.py @@ -0,0 +1,4268 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 asyncio +import json +import math +import os +from collections.abc import AsyncIterable, Iterable, Mapping, Sequence +from unittest import mock +from unittest.mock import AsyncMock + +import grpc +import pytest +from google.api_core import api_core_version +from google.protobuf import json_format +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +import google.auth +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore +from google.api_core import ( + client_options, + gapic_v1, + grpc_helpers, + grpc_helpers_async, + path_template, +) +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.oauth2 import service_account + +from google.developers_knowledge_v1.services.developer_knowledge import ( + DeveloperKnowledgeAsyncClient, + DeveloperKnowledgeClient, + pagers, + transports, +) +from google.developers_knowledge_v1.types import developerknowledge + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + +# 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 + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +@pytest.fixture(autouse=True) +def set_event_loop(): + try: + asyncio.get_running_loop() + yield + except RuntimeError: + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + try: + yield + finally: + loop.close() + asyncio.set_event_loop(None) + + +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" + custom_endpoint = ".custom" + + assert DeveloperKnowledgeClient._get_default_mtls_endpoint(None) is None + assert ( + DeveloperKnowledgeClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + DeveloperKnowledgeClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + DeveloperKnowledgeClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + DeveloperKnowledgeClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + DeveloperKnowledgeClient._get_default_mtls_endpoint(non_googleapi) + == non_googleapi + ) + assert ( + DeveloperKnowledgeClient._get_default_mtls_endpoint(custom_endpoint) + == custom_endpoint + ) + + +def test__read_environment_variables(): + assert DeveloperKnowledgeClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert DeveloperKnowledgeClient._read_environment_variables() == ( + True, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert DeveloperKnowledgeClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with pytest.raises(ValueError) as excinfo: + DeveloperKnowledgeClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + else: + assert DeveloperKnowledgeClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert DeveloperKnowledgeClient._read_environment_variables() == ( + False, + "never", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert DeveloperKnowledgeClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert DeveloperKnowledgeClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + DeveloperKnowledgeClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert DeveloperKnowledgeClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test_use_client_cert_effective(): + # Test case 1: Test when `should_use_client_cert` returns True. + # We mock the `should_use_client_cert` function to simulate a scenario where + # the google-auth library supports automatic mTLS and determines that a + # client certificate should be used. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch( + "google.auth.transport.mtls.should_use_client_cert", return_value=True + ): + assert DeveloperKnowledgeClient._use_client_cert_effective() is True + + # Test case 2: Test when `should_use_client_cert` returns False. + # We mock the `should_use_client_cert` function to simulate a scenario where + # the google-auth library supports automatic mTLS and determines that a + # client certificate should NOT be used. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch( + "google.auth.transport.mtls.should_use_client_cert", return_value=False + ): + assert DeveloperKnowledgeClient._use_client_cert_effective() is False + + # Test case 3: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "true". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert DeveloperKnowledgeClient._use_client_cert_effective() is True + + # Test case 4: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "false". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"} + ): + assert DeveloperKnowledgeClient._use_client_cert_effective() is False + + # Test case 5: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "True". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "True"}): + assert DeveloperKnowledgeClient._use_client_cert_effective() is True + + # Test case 6: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "False". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "False"} + ): + assert DeveloperKnowledgeClient._use_client_cert_effective() is False + + # Test case 7: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "TRUE". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "TRUE"}): + assert DeveloperKnowledgeClient._use_client_cert_effective() is True + + # Test case 8: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "FALSE". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "FALSE"} + ): + assert DeveloperKnowledgeClient._use_client_cert_effective() is False + + # Test case 9: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not set. + # In this case, the method should return False, which is the default value. + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, clear=True): + assert DeveloperKnowledgeClient._use_client_cert_effective() is False + + # Test case 10: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value. + # The method should raise a ValueError as the environment variable must be either + # "true" or "false". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"} + ): + with pytest.raises(ValueError): + DeveloperKnowledgeClient._use_client_cert_effective() + + # Test case 11: Test when `should_use_client_cert` is available and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value. + # The method should return False as the environment variable is set to an invalid value. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"} + ): + assert DeveloperKnowledgeClient._use_client_cert_effective() is False + + # Test case 12: Test when `should_use_client_cert` is available and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is unset. Also, + # the GOOGLE_API_CONFIG environment variable is unset. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": ""}): + with mock.patch.dict(os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": ""}): + assert DeveloperKnowledgeClient._use_client_cert_effective() is False + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert DeveloperKnowledgeClient._get_client_cert_source(None, False) is None + assert ( + DeveloperKnowledgeClient._get_client_cert_source( + mock_provided_cert_source, False + ) + is None + ) + assert ( + DeveloperKnowledgeClient._get_client_cert_source( + mock_provided_cert_source, True + ) + == mock_provided_cert_source + ) + + 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_default_cert_source, + ): + assert ( + DeveloperKnowledgeClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + DeveloperKnowledgeClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + DeveloperKnowledgeClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DeveloperKnowledgeClient), +) +@mock.patch.object( + DeveloperKnowledgeAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DeveloperKnowledgeAsyncClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = DeveloperKnowledgeClient._DEFAULT_UNIVERSE + default_endpoint = DeveloperKnowledgeClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = DeveloperKnowledgeClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + DeveloperKnowledgeClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + DeveloperKnowledgeClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == DeveloperKnowledgeClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + DeveloperKnowledgeClient._get_api_endpoint(None, None, default_universe, "auto") + == default_endpoint + ) + assert ( + DeveloperKnowledgeClient._get_api_endpoint( + None, None, default_universe, "always" + ) + == DeveloperKnowledgeClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + DeveloperKnowledgeClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == DeveloperKnowledgeClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + DeveloperKnowledgeClient._get_api_endpoint(None, None, mock_universe, "never") + == mock_endpoint + ) + assert ( + DeveloperKnowledgeClient._get_api_endpoint( + None, None, default_universe, "never" + ) + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + DeveloperKnowledgeClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + DeveloperKnowledgeClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + DeveloperKnowledgeClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert ( + DeveloperKnowledgeClient._get_universe_domain(None, None) + == DeveloperKnowledgeClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + DeveloperKnowledgeClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DeveloperKnowledgeClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DeveloperKnowledgeClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (DeveloperKnowledgeClient, "grpc"), + (DeveloperKnowledgeAsyncClient, "grpc_asyncio"), + (DeveloperKnowledgeClient, "rest"), + ], +) +def test_developer_knowledge_client_from_service_account_info( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "developerknowledge.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://developerknowledge.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.DeveloperKnowledgeGrpcTransport, "grpc"), + (transports.DeveloperKnowledgeGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.DeveloperKnowledgeRestTransport, "rest"), + ], +) +def test_developer_knowledge_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (DeveloperKnowledgeClient, "grpc"), + (DeveloperKnowledgeAsyncClient, "grpc_asyncio"), + (DeveloperKnowledgeClient, "rest"), + ], +) +def test_developer_knowledge_client_from_service_account_file( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "developerknowledge.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://developerknowledge.googleapis.com" + ) + + +def test_developer_knowledge_client_get_transport_class(): + transport = DeveloperKnowledgeClient.get_transport_class() + available_transports = [ + transports.DeveloperKnowledgeGrpcTransport, + transports.DeveloperKnowledgeRestTransport, + ] + assert transport in available_transports + + transport = DeveloperKnowledgeClient.get_transport_class("grpc") + assert transport == transports.DeveloperKnowledgeGrpcTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (DeveloperKnowledgeClient, transports.DeveloperKnowledgeGrpcTransport, "grpc"), + ( + DeveloperKnowledgeAsyncClient, + transports.DeveloperKnowledgeGrpcAsyncIOTransport, + "grpc_asyncio", + ), + (DeveloperKnowledgeClient, transports.DeveloperKnowledgeRestTransport, "rest"), + ], +) +@mock.patch.object( + DeveloperKnowledgeClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DeveloperKnowledgeClient), +) +@mock.patch.object( + DeveloperKnowledgeAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DeveloperKnowledgeAsyncClient), +) +def test_developer_knowledge_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(DeveloperKnowledgeClient, "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(DeveloperKnowledgeClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # 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_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + DeveloperKnowledgeClient, + transports.DeveloperKnowledgeGrpcTransport, + "grpc", + "true", + ), + ( + DeveloperKnowledgeAsyncClient, + transports.DeveloperKnowledgeGrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + ( + DeveloperKnowledgeClient, + transports.DeveloperKnowledgeGrpcTransport, + "grpc", + "false", + ), + ( + DeveloperKnowledgeAsyncClient, + transports.DeveloperKnowledgeGrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + ( + DeveloperKnowledgeClient, + transports.DeveloperKnowledgeRestTransport, + "rest", + "true", + ), + ( + DeveloperKnowledgeClient, + transports.DeveloperKnowledgeRestTransport, + "rest", + "false", + ), + ], +) +@mock.patch.object( + DeveloperKnowledgeClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DeveloperKnowledgeClient), +) +@mock.patch.object( + DeveloperKnowledgeAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DeveloperKnowledgeAsyncClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_developer_knowledge_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_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class", [DeveloperKnowledgeClient, DeveloperKnowledgeAsyncClient] +) +@mock.patch.object( + DeveloperKnowledgeClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(DeveloperKnowledgeClient), +) +@mock.patch.object( + DeveloperKnowledgeAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(DeveloperKnowledgeAsyncClient), +) +def test_developer_knowledge_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_CLIENT_CERTIFICATE is "Unsupported". + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + 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 cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset. + test_cases = [ + ( + # With workloads present in config, mTLS is enabled. + { + "version": 1, + "cert_configs": { + "workload": { + "cert_path": "path/to/cert/file", + "key_path": "path/to/key/file", + } + }, + }, + mock_client_cert_source, + ), + ( + # With workloads not present in config, mTLS is disabled. + { + "version": 1, + "cert_configs": {}, + }, + None, + ), + ] + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + for config_data, expected_cert_source in test_cases: + env = os.environ.copy() + env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", None) + with mock.patch.dict(os.environ, env, clear=True): + config_filename = "mock_certificate_config.json" + config_file_content = json.dumps(config_data) + m = mock.mock_open(read_data=config_file_content) + with mock.patch("builtins.open", m): + with mock.patch.dict( + os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename} + ): + 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 expected_cert_source + + # Test cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset(empty). + test_cases = [ + ( + # With workloads present in config, mTLS is enabled. + { + "version": 1, + "cert_configs": { + "workload": { + "cert_path": "path/to/cert/file", + "key_path": "path/to/key/file", + } + }, + }, + mock_client_cert_source, + ), + ( + # With workloads not present in config, mTLS is disabled. + { + "version": 1, + "cert_configs": {}, + }, + None, + ), + ] + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + for config_data, expected_cert_source in test_cases: + env = os.environ.copy() + env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", "") + with mock.patch.dict(os.environ, env, clear=True): + config_filename = "mock_certificate_config.json" + config_file_content = json.dumps(config_data) + m = mock.mock_open(read_data=config_file_content) + with mock.patch("builtins.open", m): + with mock.patch.dict( + os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename} + ): + 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 expected_cert_source + + # 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 + + # 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) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + +@pytest.mark.parametrize( + "client_class", [DeveloperKnowledgeClient, DeveloperKnowledgeAsyncClient] +) +@mock.patch.object( + DeveloperKnowledgeClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DeveloperKnowledgeClient), +) +@mock.patch.object( + DeveloperKnowledgeAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DeveloperKnowledgeAsyncClient), +) +def test_developer_knowledge_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = DeveloperKnowledgeClient._DEFAULT_UNIVERSE + default_endpoint = DeveloperKnowledgeClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = DeveloperKnowledgeClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (DeveloperKnowledgeClient, transports.DeveloperKnowledgeGrpcTransport, "grpc"), + ( + DeveloperKnowledgeAsyncClient, + transports.DeveloperKnowledgeGrpcAsyncIOTransport, + "grpc_asyncio", + ), + (DeveloperKnowledgeClient, transports.DeveloperKnowledgeRestTransport, "rest"), + ], +) +def test_developer_knowledge_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_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + DeveloperKnowledgeClient, + transports.DeveloperKnowledgeGrpcTransport, + "grpc", + grpc_helpers, + ), + ( + DeveloperKnowledgeAsyncClient, + transports.DeveloperKnowledgeGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + ( + DeveloperKnowledgeClient, + transports.DeveloperKnowledgeRestTransport, + "rest", + None, + ), + ], +) +def test_developer_knowledge_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_developer_knowledge_client_client_options_from_dict(): + with mock.patch( + "google.developers_knowledge_v1.services.developer_knowledge.transports.DeveloperKnowledgeGrpcTransport.__init__" + ) as grpc_transport: + grpc_transport.return_value = None + client = DeveloperKnowledgeClient( + client_options={"api_endpoint": "squid.clam.whelk"} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + DeveloperKnowledgeClient, + transports.DeveloperKnowledgeGrpcTransport, + "grpc", + grpc_helpers, + ), + ( + DeveloperKnowledgeAsyncClient, + transports.DeveloperKnowledgeGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + ], +) +def test_developer_knowledge_client_create_channel_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # test that the credentials from file are saved and used as the credentials. + with ( + mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, + mock.patch.object(google.auth, "default", autospec=True) as adc, + mock.patch.object(grpc_helpers, "create_channel") as create_channel, + ): + creds = ga_credentials.AnonymousCredentials() + file_creds = ga_credentials.AnonymousCredentials() + load_creds.return_value = (file_creds, None) + adc.return_value = (creds, None) + client = client_class(client_options=options, transport=transport_name) + create_channel.assert_called_with( + "developerknowledge.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + scopes=None, + default_host="developerknowledge.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "request_type", + [ + developerknowledge.SearchDocumentChunksRequest(), + {}, + ], +) +def test_search_document_chunks(request_type, transport: str = "grpc"): + client = DeveloperKnowledgeClient( + 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_document_chunks), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = developerknowledge.SearchDocumentChunksResponse( + next_page_token="next_page_token_value", + ) + response = client.search_document_chunks(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = developerknowledge.SearchDocumentChunksRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.SearchDocumentChunksPager) + assert response.next_page_token == "next_page_token_value" + + +def test_search_document_chunks_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = developerknowledge.SearchDocumentChunksRequest( + query="query_value", + page_token="page_token_value", + filter="filter_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search_document_chunks), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.search_document_chunks(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = developerknowledge.SearchDocumentChunksRequest( + query="query_value", + page_token="page_token_value", + filter="filter_value", + ) + assert args[0] == request_msg + + +def test_search_document_chunks_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.search_document_chunks + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.search_document_chunks] = ( + mock_rpc + ) + request = {} + client.search_document_chunks(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.search_document_chunks(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_search_document_chunks_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = DeveloperKnowledgeAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.search_document_chunks + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.search_document_chunks + ] = mock_rpc + + request = {} + await client.search_document_chunks(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.search_document_chunks(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + developerknowledge.SearchDocumentChunksRequest(), + {}, + ], +) +async def test_search_document_chunks_async( + request_type, transport: str = "grpc_asyncio" +): + client = DeveloperKnowledgeAsyncClient( + credentials=async_anonymous_credentials(), + 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_document_chunks), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + developerknowledge.SearchDocumentChunksResponse( + next_page_token="next_page_token_value", + ) + ) + response = await client.search_document_chunks(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = developerknowledge.SearchDocumentChunksRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.SearchDocumentChunksAsyncPager) + assert response.next_page_token == "next_page_token_value" + + +def test_search_document_chunks_pager(transport_name: str = "grpc"): + client = DeveloperKnowledgeClient( + 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_document_chunks), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + developerknowledge.SearchDocumentChunksResponse( + results=[ + developerknowledge.DocumentChunk(), + developerknowledge.DocumentChunk(), + developerknowledge.DocumentChunk(), + ], + next_page_token="abc", + ), + developerknowledge.SearchDocumentChunksResponse( + results=[], + next_page_token="def", + ), + developerknowledge.SearchDocumentChunksResponse( + results=[ + developerknowledge.DocumentChunk(), + ], + next_page_token="ghi", + ), + developerknowledge.SearchDocumentChunksResponse( + results=[ + developerknowledge.DocumentChunk(), + developerknowledge.DocumentChunk(), + ], + ), + RuntimeError, + ) + + expected_metadata = () + retry = retries.Retry() + timeout = 5 + pager = client.search_document_chunks(request={}, retry=retry, timeout=timeout) + + assert pager._metadata == expected_metadata + assert pager._retry == retry + assert pager._timeout == timeout + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, developerknowledge.DocumentChunk) for i in results) + + +def test_search_document_chunks_pages(transport_name: str = "grpc"): + client = DeveloperKnowledgeClient( + 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_document_chunks), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + developerknowledge.SearchDocumentChunksResponse( + results=[ + developerknowledge.DocumentChunk(), + developerknowledge.DocumentChunk(), + developerknowledge.DocumentChunk(), + ], + next_page_token="abc", + ), + developerknowledge.SearchDocumentChunksResponse( + results=[], + next_page_token="def", + ), + developerknowledge.SearchDocumentChunksResponse( + results=[ + developerknowledge.DocumentChunk(), + ], + next_page_token="ghi", + ), + developerknowledge.SearchDocumentChunksResponse( + results=[ + developerknowledge.DocumentChunk(), + developerknowledge.DocumentChunk(), + ], + ), + RuntimeError, + ) + pages = list(client.search_document_chunks(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_document_chunks_async_pager(): + client = DeveloperKnowledgeAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search_document_chunks), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + developerknowledge.SearchDocumentChunksResponse( + results=[ + developerknowledge.DocumentChunk(), + developerknowledge.DocumentChunk(), + developerknowledge.DocumentChunk(), + ], + next_page_token="abc", + ), + developerknowledge.SearchDocumentChunksResponse( + results=[], + next_page_token="def", + ), + developerknowledge.SearchDocumentChunksResponse( + results=[ + developerknowledge.DocumentChunk(), + ], + next_page_token="ghi", + ), + developerknowledge.SearchDocumentChunksResponse( + results=[ + developerknowledge.DocumentChunk(), + developerknowledge.DocumentChunk(), + ], + ), + RuntimeError, + ) + async_pager = await client.search_document_chunks( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, developerknowledge.DocumentChunk) for i in responses) + + +@pytest.mark.asyncio +async def test_search_document_chunks_async_pages(): + client = DeveloperKnowledgeAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search_document_chunks), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + developerknowledge.SearchDocumentChunksResponse( + results=[ + developerknowledge.DocumentChunk(), + developerknowledge.DocumentChunk(), + developerknowledge.DocumentChunk(), + ], + next_page_token="abc", + ), + developerknowledge.SearchDocumentChunksResponse( + results=[], + next_page_token="def", + ), + developerknowledge.SearchDocumentChunksResponse( + results=[ + developerknowledge.DocumentChunk(), + ], + next_page_token="ghi", + ), + developerknowledge.SearchDocumentChunksResponse( + results=[ + developerknowledge.DocumentChunk(), + developerknowledge.DocumentChunk(), + ], + ), + RuntimeError, + ) + pages = [] + async for page_ in (await client.search_document_chunks(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", + [ + developerknowledge.GetDocumentRequest(), + {}, + ], +) +def test_get_document(request_type, transport: str = "grpc"): + client = DeveloperKnowledgeClient( + 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_document), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = developerknowledge.Document( + name="name_value", + uri="uri_value", + content="content_value", + description="description_value", + data_source="data_source_value", + title="title_value", + view=developerknowledge.DocumentView.DOCUMENT_VIEW_BASIC, + ) + response = client.get_document(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = developerknowledge.GetDocumentRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, developerknowledge.Document) + assert response.name == "name_value" + assert response.uri == "uri_value" + assert response.content == "content_value" + assert response.description == "description_value" + assert response.data_source == "data_source_value" + assert response.title == "title_value" + assert response.view == developerknowledge.DocumentView.DOCUMENT_VIEW_BASIC + + +def test_get_document_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = developerknowledge.GetDocumentRequest( + name="name_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_document), "__call__") as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.get_document(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = developerknowledge.GetDocumentRequest( + name="name_value", + ) + assert args[0] == request_msg + + +def test_get_document_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_document in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_document] = mock_rpc + request = {} + client.get_document(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_document(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_get_document_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = DeveloperKnowledgeAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.get_document + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.get_document + ] = mock_rpc + + request = {} + await client.get_document(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.get_document(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + developerknowledge.GetDocumentRequest(), + {}, + ], +) +async def test_get_document_async(request_type, transport: str = "grpc_asyncio"): + client = DeveloperKnowledgeAsyncClient( + credentials=async_anonymous_credentials(), + 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_document), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + developerknowledge.Document( + name="name_value", + uri="uri_value", + content="content_value", + description="description_value", + data_source="data_source_value", + title="title_value", + view=developerknowledge.DocumentView.DOCUMENT_VIEW_BASIC, + ) + ) + response = await client.get_document(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = developerknowledge.GetDocumentRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, developerknowledge.Document) + assert response.name == "name_value" + assert response.uri == "uri_value" + assert response.content == "content_value" + assert response.description == "description_value" + assert response.data_source == "data_source_value" + assert response.title == "title_value" + assert response.view == developerknowledge.DocumentView.DOCUMENT_VIEW_BASIC + + +def test_get_document_field_headers(): + client = DeveloperKnowledgeClient( + 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 = developerknowledge.GetDocumentRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_document), "__call__") as call: + call.return_value = developerknowledge.Document() + client.get_document(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_document_field_headers_async(): + client = DeveloperKnowledgeAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = developerknowledge.GetDocumentRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_document), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + developerknowledge.Document() + ) + await client.get_document(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_document_flattened(): + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_document), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = developerknowledge.Document() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_document( + 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_document_flattened_error(): + client = DeveloperKnowledgeClient( + 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_document( + developerknowledge.GetDocumentRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_document_flattened_async(): + client = DeveloperKnowledgeAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_document), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = developerknowledge.Document() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + developerknowledge.Document() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_document( + 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_document_flattened_error_async(): + client = DeveloperKnowledgeAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_document( + developerknowledge.GetDocumentRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + developerknowledge.BatchGetDocumentsRequest(), + {}, + ], +) +def test_batch_get_documents(request_type, transport: str = "grpc"): + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_get_documents), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = developerknowledge.BatchGetDocumentsResponse() + response = client.batch_get_documents(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = developerknowledge.BatchGetDocumentsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, developerknowledge.BatchGetDocumentsResponse) + + +def test_batch_get_documents_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = developerknowledge.BatchGetDocumentsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_get_documents), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.batch_get_documents(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = developerknowledge.BatchGetDocumentsRequest() + assert args[0] == request_msg + + +def test_batch_get_documents_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.batch_get_documents in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.batch_get_documents] = ( + mock_rpc + ) + request = {} + client.batch_get_documents(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.batch_get_documents(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_batch_get_documents_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = DeveloperKnowledgeAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.batch_get_documents + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.batch_get_documents + ] = mock_rpc + + request = {} + await client.batch_get_documents(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.batch_get_documents(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + developerknowledge.BatchGetDocumentsRequest(), + {}, + ], +) +async def test_batch_get_documents_async(request_type, transport: str = "grpc_asyncio"): + client = DeveloperKnowledgeAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_get_documents), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + developerknowledge.BatchGetDocumentsResponse() + ) + response = await client.batch_get_documents(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = developerknowledge.BatchGetDocumentsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, developerknowledge.BatchGetDocumentsResponse) + + +def test_search_document_chunks_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.search_document_chunks + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.search_document_chunks] = ( + mock_rpc + ) + + request = {} + client.search_document_chunks(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.search_document_chunks(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_search_document_chunks_rest_required_fields( + request_type=developerknowledge.SearchDocumentChunksRequest, +): + transport_class = transports.DeveloperKnowledgeRestTransport + + request_init = {} + request_init["query"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + assert "query" not in jsonified_request + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).search_document_chunks._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "query" in jsonified_request + assert jsonified_request["query"] == request_init["query"] + + jsonified_request["query"] = "query_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).search_document_chunks._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "page_size", + "page_token", + "query", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "query" in jsonified_request + assert jsonified_request["query"] == "query_value" + + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = developerknowledge.SearchDocumentChunksResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = developerknowledge.SearchDocumentChunksResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.search_document_chunks(request) + + expected_params = [ + ( + "query", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_search_document_chunks_rest_unset_required_fields(): + transport = transports.DeveloperKnowledgeRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.search_document_chunks._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "pageSize", + "pageToken", + "query", + ) + ) + & set(("query",)) + ) + + +def test_search_document_chunks_rest_pager(transport: str = "rest"): + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + developerknowledge.SearchDocumentChunksResponse( + results=[ + developerknowledge.DocumentChunk(), + developerknowledge.DocumentChunk(), + developerknowledge.DocumentChunk(), + ], + next_page_token="abc", + ), + developerknowledge.SearchDocumentChunksResponse( + results=[], + next_page_token="def", + ), + developerknowledge.SearchDocumentChunksResponse( + results=[ + developerknowledge.DocumentChunk(), + ], + next_page_token="ghi", + ), + developerknowledge.SearchDocumentChunksResponse( + results=[ + developerknowledge.DocumentChunk(), + developerknowledge.DocumentChunk(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + developerknowledge.SearchDocumentChunksResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {} + + pager = client.search_document_chunks(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, developerknowledge.DocumentChunk) for i in results) + + pages = list(client.search_document_chunks(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_get_document_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_document in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_document] = mock_rpc + + request = {} + client.get_document(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_document(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_document_rest_required_fields( + request_type=developerknowledge.GetDocumentRequest, +): + transport_class = transports.DeveloperKnowledgeRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_document._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_document._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("view",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = developerknowledge.Document() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = developerknowledge.Document.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_document(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_get_document_rest_unset_required_fields(): + transport = transports.DeveloperKnowledgeRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_document._get_unset_required_fields({}) + assert set(unset_fields) == (set(("view",)) & set(("name",))) + + +def test_get_document_rest_flattened(): + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = developerknowledge.Document() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "documents/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = developerknowledge.Document.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_document(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=documents/**}" % client.transport._host, args[1] + ) + + +def test_get_document_rest_flattened_error(transport: str = "rest"): + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_document( + developerknowledge.GetDocumentRequest(), + name="name_value", + ) + + +def test_batch_get_documents_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.batch_get_documents in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.batch_get_documents] = ( + mock_rpc + ) + + request = {} + client.batch_get_documents(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.batch_get_documents(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_batch_get_documents_rest_required_fields( + request_type=developerknowledge.BatchGetDocumentsRequest, +): + transport_class = transports.DeveloperKnowledgeRestTransport + + request_init = {} + request_init["names"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + assert "names" not in jsonified_request + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_get_documents._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "names" in jsonified_request + assert jsonified_request["names"] == request_init["names"] + + jsonified_request["names"] = "names_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_get_documents._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "names", + "view", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "names" in jsonified_request + assert jsonified_request["names"] == "names_value" + + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = developerknowledge.BatchGetDocumentsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = developerknowledge.BatchGetDocumentsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.batch_get_documents(request) + + expected_params = [ + ( + "names", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_batch_get_documents_rest_unset_required_fields(): + transport = transports.DeveloperKnowledgeRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.batch_get_documents._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "names", + "view", + ) + ) + & set(("names",)) + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.DeveloperKnowledgeGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.DeveloperKnowledgeGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = DeveloperKnowledgeClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.DeveloperKnowledgeGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = DeveloperKnowledgeClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = DeveloperKnowledgeClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.DeveloperKnowledgeGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = DeveloperKnowledgeClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.DeveloperKnowledgeGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = DeveloperKnowledgeClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.DeveloperKnowledgeGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.DeveloperKnowledgeGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.DeveloperKnowledgeGrpcTransport, + transports.DeveloperKnowledgeGrpcAsyncIOTransport, + transports.DeveloperKnowledgeRestTransport, + ], +) +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_kind_grpc(): + transport = DeveloperKnowledgeClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_search_document_chunks_empty_call_grpc(): + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.search_document_chunks), "__call__" + ) as call: + call.return_value = developerknowledge.SearchDocumentChunksResponse() + client.search_document_chunks(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = developerknowledge.SearchDocumentChunksRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_document_empty_call_grpc(): + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_document), "__call__") as call: + call.return_value = developerknowledge.Document() + client.get_document(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = developerknowledge.GetDocumentRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_get_documents_empty_call_grpc(): + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_get_documents), "__call__" + ) as call: + call.return_value = developerknowledge.BatchGetDocumentsResponse() + client.batch_get_documents(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = developerknowledge.BatchGetDocumentsRequest() + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = DeveloperKnowledgeAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = DeveloperKnowledgeAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_search_document_chunks_empty_call_grpc_asyncio(): + client = DeveloperKnowledgeAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.search_document_chunks), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + developerknowledge.SearchDocumentChunksResponse( + next_page_token="next_page_token_value", + ) + ) + await client.search_document_chunks(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = developerknowledge.SearchDocumentChunksRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_document_empty_call_grpc_asyncio(): + client = DeveloperKnowledgeAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_document), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + developerknowledge.Document( + name="name_value", + uri="uri_value", + content="content_value", + description="description_value", + data_source="data_source_value", + title="title_value", + view=developerknowledge.DocumentView.DOCUMENT_VIEW_BASIC, + ) + ) + await client.get_document(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = developerknowledge.GetDocumentRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_batch_get_documents_empty_call_grpc_asyncio(): + client = DeveloperKnowledgeAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_get_documents), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + developerknowledge.BatchGetDocumentsResponse() + ) + await client.batch_get_documents(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = developerknowledge.BatchGetDocumentsRequest() + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = DeveloperKnowledgeClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_search_document_chunks_rest_bad_request( + request_type=developerknowledge.SearchDocumentChunksRequest, +): + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.search_document_chunks(request) + + +@pytest.mark.parametrize( + "request_type", + [ + developerknowledge.SearchDocumentChunksRequest, + dict, + ], +) +def test_search_document_chunks_rest_call_success(request_type): + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = developerknowledge.SearchDocumentChunksResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = developerknowledge.SearchDocumentChunksResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.search_document_chunks(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.SearchDocumentChunksPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_search_document_chunks_rest_interceptors(null_interceptor): + transport = transports.DeveloperKnowledgeRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DeveloperKnowledgeRestInterceptor(), + ) + client = DeveloperKnowledgeClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.DeveloperKnowledgeRestInterceptor, "post_search_document_chunks" + ) as post, + mock.patch.object( + transports.DeveloperKnowledgeRestInterceptor, + "post_search_document_chunks_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.DeveloperKnowledgeRestInterceptor, "pre_search_document_chunks" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = developerknowledge.SearchDocumentChunksRequest.pb( + developerknowledge.SearchDocumentChunksRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = developerknowledge.SearchDocumentChunksResponse.to_json( + developerknowledge.SearchDocumentChunksResponse() + ) + req.return_value.content = return_value + + request = developerknowledge.SearchDocumentChunksRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = developerknowledge.SearchDocumentChunksResponse() + post_with_metadata.return_value = ( + developerknowledge.SearchDocumentChunksResponse(), + metadata, + ) + + client.search_document_chunks( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_document_rest_bad_request( + request_type=developerknowledge.GetDocumentRequest, +): + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "documents/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_document(request) + + +@pytest.mark.parametrize( + "request_type", + [ + developerknowledge.GetDocumentRequest, + dict, + ], +) +def test_get_document_rest_call_success(request_type): + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "documents/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = developerknowledge.Document( + name="name_value", + uri="uri_value", + content="content_value", + description="description_value", + data_source="data_source_value", + title="title_value", + view=developerknowledge.DocumentView.DOCUMENT_VIEW_BASIC, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = developerknowledge.Document.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_document(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, developerknowledge.Document) + assert response.name == "name_value" + assert response.uri == "uri_value" + assert response.content == "content_value" + assert response.description == "description_value" + assert response.data_source == "data_source_value" + assert response.title == "title_value" + assert response.view == developerknowledge.DocumentView.DOCUMENT_VIEW_BASIC + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_document_rest_interceptors(null_interceptor): + transport = transports.DeveloperKnowledgeRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DeveloperKnowledgeRestInterceptor(), + ) + client = DeveloperKnowledgeClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.DeveloperKnowledgeRestInterceptor, "post_get_document" + ) as post, + mock.patch.object( + transports.DeveloperKnowledgeRestInterceptor, + "post_get_document_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.DeveloperKnowledgeRestInterceptor, "pre_get_document" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = developerknowledge.GetDocumentRequest.pb( + developerknowledge.GetDocumentRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = developerknowledge.Document.to_json( + developerknowledge.Document() + ) + req.return_value.content = return_value + + request = developerknowledge.GetDocumentRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = developerknowledge.Document() + post_with_metadata.return_value = developerknowledge.Document(), metadata + + client.get_document( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_batch_get_documents_rest_bad_request( + request_type=developerknowledge.BatchGetDocumentsRequest, +): + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.batch_get_documents(request) + + +@pytest.mark.parametrize( + "request_type", + [ + developerknowledge.BatchGetDocumentsRequest, + dict, + ], +) +def test_batch_get_documents_rest_call_success(request_type): + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = developerknowledge.BatchGetDocumentsResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = developerknowledge.BatchGetDocumentsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.batch_get_documents(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, developerknowledge.BatchGetDocumentsResponse) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_get_documents_rest_interceptors(null_interceptor): + transport = transports.DeveloperKnowledgeRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DeveloperKnowledgeRestInterceptor(), + ) + client = DeveloperKnowledgeClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.DeveloperKnowledgeRestInterceptor, "post_batch_get_documents" + ) as post, + mock.patch.object( + transports.DeveloperKnowledgeRestInterceptor, + "post_batch_get_documents_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.DeveloperKnowledgeRestInterceptor, "pre_batch_get_documents" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = developerknowledge.BatchGetDocumentsRequest.pb( + developerknowledge.BatchGetDocumentsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = developerknowledge.BatchGetDocumentsResponse.to_json( + developerknowledge.BatchGetDocumentsResponse() + ) + req.return_value.content = return_value + + request = developerknowledge.BatchGetDocumentsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = developerknowledge.BatchGetDocumentsResponse() + post_with_metadata.return_value = ( + developerknowledge.BatchGetDocumentsResponse(), + metadata, + ) + + client.batch_get_documents( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_initialize_client_w_rest(): + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_search_document_chunks_empty_call_rest(): + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.search_document_chunks), "__call__" + ) as call: + client.search_document_chunks(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = developerknowledge.SearchDocumentChunksRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_document_empty_call_rest(): + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_document), "__call__") as call: + client.get_document(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = developerknowledge.GetDocumentRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_get_documents_empty_call_rest(): + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_get_documents), "__call__" + ) as call: + client.batch_get_documents(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = developerknowledge.BatchGetDocumentsRequest() + assert args[0] == request_msg + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.DeveloperKnowledgeGrpcTransport, + ) + + +def test_developer_knowledge_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.DeveloperKnowledgeTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_developer_knowledge_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.developers_knowledge_v1.services.developer_knowledge.transports.DeveloperKnowledgeTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.DeveloperKnowledgeTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "search_document_chunks", + "get_document", + "batch_get_documents", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_developer_knowledge_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.developers_knowledge_v1.services.developer_knowledge.transports.DeveloperKnowledgeTransport._prep_wrapped_messages" + ) as Transport, + ): + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.DeveloperKnowledgeTransport( + 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_developer_knowledge_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.developers_knowledge_v1.services.developer_knowledge.transports.DeveloperKnowledgeTransport._prep_wrapped_messages" + ) as Transport, + ): + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.DeveloperKnowledgeTransport() + adc.assert_called_once() + + +def test_developer_knowledge_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) + DeveloperKnowledgeClient() + 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.DeveloperKnowledgeGrpcTransport, + transports.DeveloperKnowledgeGrpcAsyncIOTransport, + ], +) +def test_developer_knowledge_transport_auth_adc(transport_class): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.DeveloperKnowledgeGrpcTransport, + transports.DeveloperKnowledgeGrpcAsyncIOTransport, + transports.DeveloperKnowledgeRestTransport, + ], +) +def test_developer_knowledge_transport_auth_gdch_credentials(transport_class): + host = "https://language.com" + api_audience_tests = [None, "https://language2.com"] + api_audience_expect = [host, "https://language2.com"] + for t, e in zip(api_audience_tests, api_audience_expect): + with mock.patch.object(google.auth, "default", autospec=True) as adc: + gdch_mock = mock.MagicMock() + type(gdch_mock).with_gdch_audience = mock.PropertyMock( + return_value=gdch_mock + ) + adc.return_value = (gdch_mock, None) + transport_class(host=host, api_audience=t) + gdch_mock.with_gdch_audience.assert_called_once_with(e) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.DeveloperKnowledgeGrpcTransport, grpc_helpers), + (transports.DeveloperKnowledgeGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +def test_developer_knowledge_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( + "developerknowledge.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="developerknowledge.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.DeveloperKnowledgeGrpcTransport, + transports.DeveloperKnowledgeGrpcAsyncIOTransport, + ], +) +def test_developer_knowledge_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_developer_knowledge_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.DeveloperKnowledgeRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_developer_knowledge_host_no_port(transport_name): + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="developerknowledge.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "developerknowledge.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://developerknowledge.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_developer_knowledge_host_with_port(transport_name): + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="developerknowledge.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "developerknowledge.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://developerknowledge.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_developer_knowledge_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = DeveloperKnowledgeClient( + credentials=creds1, + transport=transport_name, + ) + client2 = DeveloperKnowledgeClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.search_document_chunks._session + session2 = client2.transport.search_document_chunks._session + assert session1 != session2 + session1 = client1.transport.get_document._session + session2 = client2.transport.get_document._session + assert session1 != session2 + session1 = client1.transport.batch_get_documents._session + session2 = client2.transport.batch_get_documents._session + assert session1 != session2 + + +def test_developer_knowledge_grpc_transport_channel(): + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.DeveloperKnowledgeGrpcTransport( + 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_developer_knowledge_grpc_asyncio_transport_channel(): + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.DeveloperKnowledgeGrpcAsyncIOTransport( + 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.filterwarnings("ignore::FutureWarning") +@pytest.mark.parametrize( + "transport_class", + [ + transports.DeveloperKnowledgeGrpcTransport, + transports.DeveloperKnowledgeGrpcAsyncIOTransport, + ], +) +def test_developer_knowledge_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.DeveloperKnowledgeGrpcTransport, + transports.DeveloperKnowledgeGrpcAsyncIOTransport, + ], +) +def test_developer_knowledge_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_document_path(): + document = "squid" + expected = "documents/{document}".format( + document=document, + ) + actual = DeveloperKnowledgeClient.document_path(document) + assert expected == actual + + +def test_parse_document_path(): + expected = { + "document": "clam", + } + path = DeveloperKnowledgeClient.document_path(**expected) + + # Check that the path construction is reversible. + actual = DeveloperKnowledgeClient.parse_document_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "whelk" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = DeveloperKnowledgeClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "octopus", + } + path = DeveloperKnowledgeClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = DeveloperKnowledgeClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "oyster" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = DeveloperKnowledgeClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nudibranch", + } + path = DeveloperKnowledgeClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = DeveloperKnowledgeClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "cuttlefish" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = DeveloperKnowledgeClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "mussel", + } + path = DeveloperKnowledgeClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = DeveloperKnowledgeClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "winkle" + expected = "projects/{project}".format( + project=project, + ) + actual = DeveloperKnowledgeClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nautilus", + } + path = DeveloperKnowledgeClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = DeveloperKnowledgeClient.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 = DeveloperKnowledgeClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "squid", + "location": "clam", + } + path = DeveloperKnowledgeClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = DeveloperKnowledgeClient.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.DeveloperKnowledgeTransport, "_prep_wrapped_messages" + ) as prep: + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.DeveloperKnowledgeTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = DeveloperKnowledgeClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_grpc(): + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +@pytest.mark.asyncio +async def test_transport_close_grpc_asyncio(): + client = DeveloperKnowledgeAsyncClient( + credentials=async_anonymous_credentials(), 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_rest(): + client = DeveloperKnowledgeClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + "grpc", + ] + for transport in transports: + client = DeveloperKnowledgeClient( + 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", + [ + (DeveloperKnowledgeClient, transports.DeveloperKnowledgeGrpcTransport), + ( + DeveloperKnowledgeAsyncClient, + transports.DeveloperKnowledgeGrpcAsyncIOTransport, + ), + ], +) +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_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) From 94c09fdb034fa8fb0ca10778aaacdde9aa047d2a Mon Sep 17 00:00:00 2001 From: Daniel Sanche Date: Mon, 8 Jun 2026 09:28:11 -0700 Subject: [PATCH 039/174] chore(bigtable): prevent test leaks (#17350) The bigtable system tests were leaving left-over instances, which could cause future tests to fail until they were manually cleaned up This PR improves the test logic to make sure resources are properly cleaned up Also added a fixture to remove test instances created more than a day ago --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- .../system/admin_overlay/test_system_async.py | 42 +++++++++----- .../admin_overlay/test_system_autogen.py | 39 ++++++++----- .../tests/system/data/__init__.py | 21 +++++-- .../tests/system/utils.py | 58 +++++++++++++++++++ 4 files changed, 128 insertions(+), 32 deletions(-) create mode 100644 packages/google-cloud-bigtable/tests/system/utils.py diff --git a/packages/google-cloud-bigtable/tests/system/admin_overlay/test_system_async.py b/packages/google-cloud-bigtable/tests/system/admin_overlay/test_system_async.py index 343ebcabb616..bca591d0a11e 100644 --- a/packages/google-cloud-bigtable/tests/system/admin_overlay/test_system_async.py +++ b/packages/google-cloud-bigtable/tests/system/admin_overlay/test_system_async.py @@ -17,7 +17,6 @@ from typing import Tuple import pytest -from google.api_core import exceptions from google.cloud.environment_vars import BIGTABLE_EMULATOR from google.cloud import bigtable_admin_v2 as admin_v2 @@ -89,33 +88,49 @@ async def instance_admin_client(admin_overlay_project_id): @CrossSync.convert -@CrossSync.pytest_fixture(scope="session") +@CrossSync.pytest_fixture(scope="session", autouse=True) +async def cleanup_old_instances(admin_overlay_project_id): + """ + Automatically deletes any test instances older than 1 day. + + This fixture runs once per test session and helps prevent resource leakage + by cleaning up instances that failed to be deleted during previous test runs. + """ + from tests.system.utils import clear_stale_instances + + from .conftest import INSTANCE_PREFIX + + clear_stale_instances(admin_overlay_project_id, INSTANCE_PREFIX, older_than_days=1) + + +@CrossSync.convert +@CrossSync.pytest_fixture(scope="function") async def instances_to_delete(instance_admin_client): instances = [] try: yield instances finally: - for instance in instances: + for instance in reversed(instances): try: await instance_admin_client.delete_instance(name=instance.name) - except exceptions.NotFound: - pass + except Exception as e: + print(f"Failed to delete instance {instance.name}: {e}") @CrossSync.convert -@CrossSync.pytest_fixture(scope="session") +@CrossSync.pytest_fixture(scope="function") async def backups_to_delete(table_admin_client): backups = [] try: yield backups finally: - for backup in backups: + for backup in reversed(backups): try: await table_admin_client.delete_backup(name=backup.name) - except exceptions.NotFound: - pass + except Exception as e: + print(f"Failed to delete backup {backup.name}: {e}") @CrossSync.convert @@ -169,7 +184,8 @@ async def create_instance( # add to cleanup list before waiting for result, in case of timeout instance_name = instance_admin_client.instance_path(project_id, instance_id) - instances_to_delete.append(admin_v2.Instance(name=instance_name)) + instance_placeholder = admin_v2.Instance(name=instance_name) + instances_to_delete.append(instance_placeholder) instance = await operation.result() @@ -260,9 +276,9 @@ async def create_backup( ) # add to cleanup list before waiting for result, in case of timeout - backups_to_delete.append( - admin_v2.Backup(name=f"{cluster_name}/backups/{backup_id}") - ) + backup_name = f"{cluster_name}/backups/{backup_id}" + backup_placeholder = admin_v2.Backup(name=backup_name) + backups_to_delete.append(backup_placeholder) backup = await operation.result() diff --git a/packages/google-cloud-bigtable/tests/system/admin_overlay/test_system_autogen.py b/packages/google-cloud-bigtable/tests/system/admin_overlay/test_system_autogen.py index 20c5b2c277eb..16628121e687 100644 --- a/packages/google-cloud-bigtable/tests/system/admin_overlay/test_system_autogen.py +++ b/packages/google-cloud-bigtable/tests/system/admin_overlay/test_system_autogen.py @@ -20,7 +20,6 @@ from typing import Tuple import pytest -from google.api_core import exceptions from google.api_core import operation as api_core_operation from google.cloud.environment_vars import BIGTABLE_EMULATOR @@ -73,30 +72,43 @@ def instance_admin_client(admin_overlay_project_id): yield client -@pytest.fixture(scope="session") +@pytest.fixture(scope="session", autouse=True) +def cleanup_old_instances(admin_overlay_project_id): + """Automatically deletes any test instances older than 1 day. + + This fixture runs once per test session and helps prevent resource leakage + by cleaning up instances that failed to be deleted during previous test runs.""" + from tests.system.utils import clear_stale_instances + + from .conftest import INSTANCE_PREFIX + + clear_stale_instances(admin_overlay_project_id, INSTANCE_PREFIX, older_than_days=1) + + +@pytest.fixture(scope="function") def instances_to_delete(instance_admin_client): instances = [] try: yield instances finally: - for instance in instances: + for instance in reversed(instances): try: instance_admin_client.delete_instance(name=instance.name) - except exceptions.NotFound: - pass + except Exception as e: + print(f"Failed to delete instance {instance.name}: {e}") -@pytest.fixture(scope="session") +@pytest.fixture(scope="function") def backups_to_delete(table_admin_client): backups = [] try: yield backups finally: - for backup in backups: + for backup in reversed(backups): try: table_admin_client.delete_backup(name=backup.name) - except exceptions.NotFound: - pass + except Exception as e: + print(f"Failed to delete backup {backup.name}: {e}") def create_instance( @@ -135,7 +147,8 @@ def create_instance( ) operation = instance_admin_client.create_instance(create_instance_request) instance_name = instance_admin_client.instance_path(project_id, instance_id) - instances_to_delete.append(admin_v2.Instance(name=instance_name)) + instance_placeholder = admin_v2.Instance(name=instance_name) + instances_to_delete.append(instance_placeholder) instance = operation.result() instances_to_delete[-1] = instance create_table_request = admin_v2.CreateTableRequest( @@ -198,9 +211,9 @@ def create_backup( ), ) ) - backups_to_delete.append( - admin_v2.Backup(name=f"{cluster_name}/backups/{backup_id}") - ) + backup_name = f"{cluster_name}/backups/{backup_id}" + backup_placeholder = admin_v2.Backup(name=backup_name) + backups_to_delete.append(backup_placeholder) backup = operation.result() backups_to_delete[-1] = backup return backup diff --git a/packages/google-cloud-bigtable/tests/system/data/__init__.py b/packages/google-cloud-bigtable/tests/system/data/__init__.py index 939955635979..2dce4850d547 100644 --- a/packages/google-cloud-bigtable/tests/system/data/__init__.py +++ b/packages/google-cloud-bigtable/tests/system/data/__init__.py @@ -34,6 +34,15 @@ class SystemTestRunner: used by standard system tests, and metrics tests """ + @pytest.fixture(scope="session", autouse=True) + def cleanup_old_instances(self, project_id): + """ + Automatically deletes any test instances older than 1 day. + """ + from tests.system.utils import clear_stale_instances + + clear_stale_instances(project_id, "python-bigtable-tests", older_than_days=1) + @pytest.fixture(scope="session") def init_table_id(self): """ @@ -128,8 +137,8 @@ def instance_id(self, admin_client, project_id, cluster_config): admin_client.instance_admin_client.delete_instance( name=f"projects/{project_id}/instances/{instance_id}" ) - except exceptions.NotFound: - pass + except Exception as e: + print(f"Failed to delete instance {instance_id}: {e}") @pytest.fixture(scope="session") def column_split_config(self): @@ -195,8 +204,8 @@ def table_id( admin_client.table_admin_client.delete_table( name=f"{parent_path}/tables/{init_table_id}" ) - except exceptions.NotFound: - print(f"Table {init_table_id} not found, skipping deletion") + except Exception as e: + print(f"Failed to delete table {init_table_id}: {e}") @pytest.fixture(scope="session") def authorized_view_id( @@ -256,8 +265,8 @@ def authorized_view_id( admin_client.table_admin_client.delete_authorized_view( name=new_path ) - except exceptions.NotFound: - print(f"View {new_view_id} not found, skipping deletion") + except Exception as e: + print(f"Failed to delete view {new_view_id}: {e}") @pytest.fixture(scope="session") def project_id(self, client): diff --git a/packages/google-cloud-bigtable/tests/system/utils.py b/packages/google-cloud-bigtable/tests/system/utils.py new file mode 100644 index 000000000000..5ea1fedd1189 --- /dev/null +++ b/packages/google-cloud-bigtable/tests/system/utils.py @@ -0,0 +1,58 @@ +# Copyright 2026 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 datetime import datetime, timedelta, timezone + +from google.api_core.exceptions import NotFound + +from google.cloud import bigtable_admin_v2 as admin_v2 + + +def clear_stale_instances(project_id: str, prefix: str, older_than_days: int = 1): + """ + Synchronously deletes any instances in the given project that are older + than older_than_days and whose name or display name matches the given prefix. + """ + client = admin_v2.BigtableInstanceAdminClient( + client_options={"quota_project_id": project_id} + ) + parent = client.common_project_path(project_id) + next_page_token = "" + + while True: + try: + response = client.list_instances( + request={"parent": parent, "page_token": next_page_token} + ) + except Exception: + # Cannot list instances, skip cleanup + break + + for instance in response.instances: + # Check if instance matches the prefix + display_name_matches = instance.display_name.startswith(prefix) + name_matches = instance.name.split("/")[-1].startswith(prefix) + + if display_name_matches or name_matches: + if instance.create_time: + now = datetime.now(timezone.utc) + if now - instance.create_time > timedelta(days=older_than_days): + try: + client.delete_instance(name=instance.name) + except NotFound: + pass + + next_page_token = response.next_page_token + if not next_page_token: + break From aa61c78eee65028b19c8ec790ca7260474ddad42 Mon Sep 17 00:00:00 2001 From: Tomo Suzuki Date: Mon, 8 Jun 2026 14:44:18 -0400 Subject: [PATCH 040/174] chore: update librarian to v0.16.1-0.20260608172125-d123ec9cac76 (#17398) --- librarian.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librarian.yaml b/librarian.yaml index 20c52d69e5a1..d356794988b4 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. language: python -version: v0.16.0 +version: v0.16.1-0.20260608172125-d123ec9cac76 repo: googleapis/google-cloud-python sources: googleapis: From 6e0f0ecebde0dd92d8789f470a27c49d9971cf87 Mon Sep 17 00:00:00 2001 From: Tomo Suzuki Date: Mon, 8 Jun 2026 14:59:17 -0400 Subject: [PATCH 041/174] feat(google/cloud/agentidentitycredentials/v1): add google-cloud-agentidentitycredentials (#17399) Towards b/520427993 --- .librarian/state.yaml | 16 + librarian.yaml | 7 + .../.coveragerc | 13 + .../.flake8 | 34 + .../.repo-metadata.json | 16 + .../CHANGELOG.md | 5 + .../LICENSE | 202 + .../MANIFEST.in | 20 + .../README.rst | 198 + .../docs/CHANGELOG.md | 1 + .../docs/README.rst | 198 + .../docs/_static/custom.css | 20 + .../docs/_templates/layout.html | 50 + .../auth_provider_credentials_service.rst | 6 + .../agentidentitycredentials_v1/services_.rst | 6 + .../agentidentitycredentials_v1/types_.rst | 6 + .../docs/conf.py | 417 ++ .../docs/index.rst | 28 + .../docs/multiprocessing.rst | 7 + .../docs/summary_overview.md | 22 + .../agentidentitycredentials/__init__.py | 41 + .../agentidentitycredentials/gapic_version.py | 16 + .../cloud/agentidentitycredentials/py.typed | 2 + .../agentidentitycredentials_v1/__init__.py | 127 + .../gapic_metadata.json | 58 + .../gapic_version.py | 16 + .../agentidentitycredentials_v1/py.typed | 2 + .../services/__init__.py | 15 + .../__init__.py | 22 + .../async_client.py | 574 +++ .../client.py | 1010 +++++ .../transports/README.rst | 10 + .../transports/__init__.py | 39 + .../transports/base.py | 197 + .../transports/grpc.py | 406 ++ .../transports/grpc_asyncio.py | 434 ++ .../transports/rest.py | 652 +++ .../transports/rest_base.py | 213 + .../types/__init__.py | 28 + .../auth_provider_credentials_service.py | 283 ++ .../mypy.ini | 15 + .../noxfile.py | 639 +++ ...ials_service_finalize_credentials_async.py | 56 + ...tials_service_finalize_credentials_sync.py | 56 + ...ials_service_retrieve_credentials_async.py | 54 + ...tials_service_retrieve_credentials_sync.py | 54 + ...gle.cloud.agentidentitycredentials.v1.json | 337 ++ .../setup.py | 99 + .../testing/constraints-3.10.txt | 11 + .../testing/constraints-3.11.txt | 10 + .../testing/constraints-3.12.txt | 10 + .../testing/constraints-3.13.txt | 12 + .../testing/constraints-3.14.txt | 12 + .../tests/__init__.py | 15 + .../tests/unit/__init__.py | 15 + .../tests/unit/gapic/__init__.py | 15 + .../agentidentitycredentials_v1/__init__.py | 15 + .../test_auth_provider_credentials_service.py | 3710 +++++++++++++++++ 58 files changed, 10552 insertions(+) create mode 100644 packages/google-cloud-agentidentitycredentials/.coveragerc create mode 100644 packages/google-cloud-agentidentitycredentials/.flake8 create mode 100644 packages/google-cloud-agentidentitycredentials/.repo-metadata.json create mode 100644 packages/google-cloud-agentidentitycredentials/CHANGELOG.md create mode 100644 packages/google-cloud-agentidentitycredentials/LICENSE create mode 100644 packages/google-cloud-agentidentitycredentials/MANIFEST.in create mode 100644 packages/google-cloud-agentidentitycredentials/README.rst create mode 120000 packages/google-cloud-agentidentitycredentials/docs/CHANGELOG.md create mode 100644 packages/google-cloud-agentidentitycredentials/docs/README.rst create mode 100644 packages/google-cloud-agentidentitycredentials/docs/_static/custom.css create mode 100644 packages/google-cloud-agentidentitycredentials/docs/_templates/layout.html create mode 100644 packages/google-cloud-agentidentitycredentials/docs/agentidentitycredentials_v1/auth_provider_credentials_service.rst create mode 100644 packages/google-cloud-agentidentitycredentials/docs/agentidentitycredentials_v1/services_.rst create mode 100644 packages/google-cloud-agentidentitycredentials/docs/agentidentitycredentials_v1/types_.rst create mode 100644 packages/google-cloud-agentidentitycredentials/docs/conf.py create mode 100644 packages/google-cloud-agentidentitycredentials/docs/index.rst create mode 100644 packages/google-cloud-agentidentitycredentials/docs/multiprocessing.rst create mode 100644 packages/google-cloud-agentidentitycredentials/docs/summary_overview.md create mode 100644 packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials/__init__.py create mode 100644 packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials/gapic_version.py create mode 100644 packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials/py.typed create mode 100644 packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/__init__.py create mode 100644 packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/gapic_metadata.json create mode 100644 packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/gapic_version.py create mode 100644 packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/py.typed create mode 100644 packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/__init__.py create mode 100644 packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/__init__.py create mode 100644 packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/async_client.py create mode 100644 packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/client.py create mode 100644 packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/transports/README.rst create mode 100644 packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/transports/__init__.py create mode 100644 packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/transports/base.py create mode 100644 packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/transports/grpc.py create mode 100644 packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/transports/grpc_asyncio.py create mode 100644 packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/transports/rest.py create mode 100644 packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/transports/rest_base.py create mode 100644 packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/types/__init__.py create mode 100644 packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/types/auth_provider_credentials_service.py create mode 100644 packages/google-cloud-agentidentitycredentials/mypy.ini create mode 100644 packages/google-cloud-agentidentitycredentials/noxfile.py create mode 100644 packages/google-cloud-agentidentitycredentials/samples/generated_samples/agentidentitycredentials_v1_generated_auth_provider_credentials_service_finalize_credentials_async.py create mode 100644 packages/google-cloud-agentidentitycredentials/samples/generated_samples/agentidentitycredentials_v1_generated_auth_provider_credentials_service_finalize_credentials_sync.py create mode 100644 packages/google-cloud-agentidentitycredentials/samples/generated_samples/agentidentitycredentials_v1_generated_auth_provider_credentials_service_retrieve_credentials_async.py create mode 100644 packages/google-cloud-agentidentitycredentials/samples/generated_samples/agentidentitycredentials_v1_generated_auth_provider_credentials_service_retrieve_credentials_sync.py create mode 100644 packages/google-cloud-agentidentitycredentials/samples/generated_samples/snippet_metadata_google.cloud.agentidentitycredentials.v1.json create mode 100644 packages/google-cloud-agentidentitycredentials/setup.py create mode 100644 packages/google-cloud-agentidentitycredentials/testing/constraints-3.10.txt create mode 100644 packages/google-cloud-agentidentitycredentials/testing/constraints-3.11.txt create mode 100644 packages/google-cloud-agentidentitycredentials/testing/constraints-3.12.txt create mode 100644 packages/google-cloud-agentidentitycredentials/testing/constraints-3.13.txt create mode 100644 packages/google-cloud-agentidentitycredentials/testing/constraints-3.14.txt create mode 100644 packages/google-cloud-agentidentitycredentials/tests/__init__.py create mode 100644 packages/google-cloud-agentidentitycredentials/tests/unit/__init__.py create mode 100644 packages/google-cloud-agentidentitycredentials/tests/unit/gapic/__init__.py create mode 100644 packages/google-cloud-agentidentitycredentials/tests/unit/gapic/agentidentitycredentials_v1/__init__.py create mode 100644 packages/google-cloud-agentidentitycredentials/tests/unit/gapic/agentidentitycredentials_v1/test_auth_provider_credentials_service.py diff --git a/.librarian/state.yaml b/.librarian/state.yaml index 2dc84d100e05..0cb1a6b1982d 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -514,6 +514,22 @@ libraries: - packages/google-cloud-advisorynotifications/README.rst - packages/google-cloud-advisorynotifications/docs/ tag_format: '{id}-v{version}' + - id: google-cloud-agentidentitycredentials + version: 0.0.0 + last_generated_commit: "" + apis: + - path: google/cloud/agentidentitycredentials/v1 + source_roots: + - packages/google-cloud-agentidentitycredentials + preserve_regex: [] + remove_regex: [] + release_exclude_paths: + - packages/google-cloud-agentidentitycredentials/.repo-metadata.json + - packages/google-cloud-agentidentitycredentials/noxfile.py + - packages/google-cloud-agentidentitycredentials/tests/ + - packages/google-cloud-agentidentitycredentials/README.rst + - packages/google-cloud-agentidentitycredentials/docs/ + tag_format: '{id}-v{version}' - id: google-cloud-alloydb version: 0.10.0 last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c diff --git a/librarian.yaml b/librarian.yaml index d356794988b4..cf7c3f01daaa 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -279,6 +279,13 @@ libraries: python: metadata_name_override: advisorynotifications default_version: v1 + - name: google-cloud-agentidentitycredentials + version: 0.0.0 + apis: + - path: google/cloud/agentidentitycredentials/v1 + copyright_year: "2026" + python: + default_version: v1 - name: google-cloud-alloydb version: 0.10.0 apis: diff --git a/packages/google-cloud-agentidentitycredentials/.coveragerc b/packages/google-cloud-agentidentitycredentials/.coveragerc new file mode 100644 index 000000000000..4b44b44e714f --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/.coveragerc @@ -0,0 +1,13 @@ +[run] +branch = True + +[report] +show_missing = True +omit = + google/cloud/agentidentitycredentials/__init__.py + google/cloud/agentidentitycredentials/gapic_version.py +exclude_lines = + # Re-enable the standard pragma + pragma: NO COVER + # Ignore debug-only repr + def __repr__ diff --git a/packages/google-cloud-agentidentitycredentials/.flake8 b/packages/google-cloud-agentidentitycredentials/.flake8 new file mode 100644 index 000000000000..f9069a84687b --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/.flake8 @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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. +# +[flake8] +# TODO(https://github.com/googleapis/gapic-generator-python/issues/2333): +# Resolve flake8 lint issues +ignore = E203, E231, E266, E501, W503 +exclude = + # TODO(https://github.com/googleapis/gapic-generator-python/issues/2333): + # Ensure that generated code passes flake8 lint + **/gapic/** + **/services/** + **/types/** + # Exclude Protobuf gencode + *_pb2.py + + # Standard linting exemptions. + **/.nox/** + __pycache__, + .git, + *.pyc, + conf.py diff --git a/packages/google-cloud-agentidentitycredentials/.repo-metadata.json b/packages/google-cloud-agentidentitycredentials/.repo-metadata.json new file mode 100644 index 000000000000..6d7d9a213a26 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/.repo-metadata.json @@ -0,0 +1,16 @@ +{ + "api_description": "agentidentitycredentials.googleapis.com API.", + "api_id": "agentidentitycredentials.googleapis.com", + "api_shortname": "agentidentitycredentials", + "client_documentation": "https://cloud.google.com/python/docs/reference/google-cloud-agentidentitycredentials/latest", + "default_version": "v1", + "distribution_name": "google-cloud-agentidentitycredentials", + "issue_tracker": "https://issuetracker.google.com/issues/new?component=190865\u0026template=1161103", + "language": "python", + "library_type": "GAPIC_AUTO", + "name": "google-cloud-agentidentitycredentials", + "name_pretty": "agentidentitycredentials.googleapis.com", + "product_documentation": "https://cloud.google.com/agentidentitycredentials/", + "release_level": "preview", + "repo": "googleapis/google-cloud-python" +} \ No newline at end of file diff --git a/packages/google-cloud-agentidentitycredentials/CHANGELOG.md b/packages/google-cloud-agentidentitycredentials/CHANGELOG.md new file mode 100644 index 000000000000..b008a19d3788 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +[PyPI History][1] + +[1]: https://pypi.org/project/google-cloud-agentidentitycredentials/#history diff --git a/packages/google-cloud-agentidentitycredentials/LICENSE b/packages/google-cloud-agentidentitycredentials/LICENSE new file mode 100644 index 000000000000..d64569567334 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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/packages/google-cloud-agentidentitycredentials/MANIFEST.in b/packages/google-cloud-agentidentitycredentials/MANIFEST.in new file mode 100644 index 000000000000..f932577add9d --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/MANIFEST.in @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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. +# +include README.rst LICENSE +recursive-include google *.py *.pyi *.json *.proto py.typed +recursive-include tests * +global-exclude *.py[co] +global-exclude __pycache__ diff --git a/packages/google-cloud-agentidentitycredentials/README.rst b/packages/google-cloud-agentidentitycredentials/README.rst new file mode 100644 index 000000000000..9a52a52beb08 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/README.rst @@ -0,0 +1,198 @@ +Python Client for agentidentitycredentials.googleapis.com +========================================================= + +|preview| |pypi| |versions| + +`agentidentitycredentials.googleapis.com`_: agentidentitycredentials.googleapis.com API. + +- `Client Library Documentation`_ +- `Product Documentation`_ + +.. |preview| image:: https://img.shields.io/badge/support-preview-orange.svg + :target: https://github.com/googleapis/google-cloud-python/blob/main/README.rst#stability-levels +.. |pypi| image:: https://img.shields.io/pypi/v/google-cloud-agentidentitycredentials.svg + :target: https://pypi.org/project/google-cloud-agentidentitycredentials/ +.. |versions| image:: https://img.shields.io/pypi/pyversions/google-cloud-agentidentitycredentials.svg + :target: https://pypi.org/project/google-cloud-agentidentitycredentials/ +.. _agentidentitycredentials.googleapis.com: https://cloud.google.com/agentidentitycredentials/ +.. _Client Library Documentation: https://cloud.google.com/python/docs/reference/google-cloud-agentidentitycredentials/latest/summary_overview +.. _Product Documentation: https://cloud.google.com/agentidentitycredentials/ + +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 agentidentitycredentials.googleapis.com.`_ +4. `Set up 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 +.. _Enable the agentidentitycredentials.googleapis.com.: https://cloud.google.com/agentidentitycredentials/ +.. _Set up Authentication.: https://googleapis.dev/python/google-api-core/latest/auth.html + +Installation +~~~~~~~~~~~~ + +Install this library in a virtual environment using `venv`_. `venv`_ is a tool that +creates isolated Python environments. These isolated environments can have separate +versions of Python packages, which allows you to isolate one project's dependencies +from the dependencies of other projects. + +With `venv`_, it's possible to install this library without needing system +install permissions, and without clashing with the installed system +dependencies. + +.. _`venv`: https://docs.python.org/3/library/venv.html + + +Code samples and snippets +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Code samples and snippets live in the `samples/`_ folder. + +.. _samples/: https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-agentidentitycredentials/samples + + +Supported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^ +Our client libraries are compatible with all current `active`_ and `maintenance`_ versions of +Python. + +Python >= 3.10, including 3.14 + +.. _active: https://devguide.python.org/devcycle/#in-development-main-branch +.. _maintenance: https://devguide.python.org/devcycle/#maintenance-branches + +Unsupported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Python <= 3.9 + + +If you are using an `end-of-life`_ +version of Python, we recommend that you update as soon as possible to an actively supported version. + +.. _end-of-life: https://devguide.python.org/devcycle/#end-of-life-branches + +Mac/Linux +^^^^^^^^^ + +.. code-block:: console + + python3 -m venv + source /bin/activate + pip install google-cloud-agentidentitycredentials + + +Windows +^^^^^^^ + +.. code-block:: console + + py -m venv + .\\Scripts\activate + pip install google-cloud-agentidentitycredentials + +Next Steps +~~~~~~~~~~ + +- Read the `Client Library Documentation`_ for agentidentitycredentials.googleapis.com + to see other available methods on the client. +- Read the `agentidentitycredentials.googleapis.com Product documentation`_ to learn + more about the product and see How-to Guides. +- View this `README`_ to see the full list of Cloud + APIs that we cover. + +.. _agentidentitycredentials.googleapis.com Product documentation: https://cloud.google.com/agentidentitycredentials/ +.. _README: https://github.com/googleapis/google-cloud-python/blob/main/README.rst + +Logging +------- + +This library uses the standard Python :code:`logging` functionality to log some RPC events that could be of interest for debugging and monitoring purposes. +Note the following: + +#. Logs may contain sensitive information. Take care to **restrict access to the logs** if they are saved, whether it be on local storage or on Google Cloud Logging. +#. Google may refine the occurrence, level, and content of various log messages in this library without flagging such changes as breaking. **Do not depend on immutability of the logging events**. +#. By default, the logging events from this library are not handled. You must **explicitly configure log handling** using one of the mechanisms below. + +Simple, environment-based configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To enable logging for this library without any changes in your code, set the :code:`GOOGLE_SDK_PYTHON_LOGGING_SCOPE` environment variable to a valid Google +logging scope. This configures handling of logging events (at level :code:`logging.DEBUG` or higher) from this library in a default manner, emitting the logged +messages in a structured format. It does not currently allow customizing the logging levels captured nor the handlers, formatters, etc. used for any logging +event. + +A logging scope is a period-separated namespace that begins with :code:`google`, identifying the Python module or package to log. + +- Valid logging scopes: :code:`google`, :code:`google.cloud.asset.v1`, :code:`google.api`, :code:`google.auth`, etc. +- Invalid logging scopes: :code:`foo`, :code:`123`, etc. + +**NOTE**: If the logging scope is invalid, the library does not set up any logging handlers. + +Environment-Based Examples +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Enabling the default handler for all Google-based loggers + +.. code-block:: console + + export GOOGLE_SDK_PYTHON_LOGGING_SCOPE=google + +- Enabling the default handler for a specific Google module (for a client library called :code:`library_v1`): + +.. code-block:: console + + export GOOGLE_SDK_PYTHON_LOGGING_SCOPE=google.cloud.library_v1 + + +Advanced, code-based configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can also configure a valid logging scope using Python's standard `logging` mechanism. + +Code-Based Examples +^^^^^^^^^^^^^^^^^^^ + +- Configuring a handler for all Google-based loggers + +.. code-block:: python + + import logging + + from google.cloud import library_v1 + + base_logger = logging.getLogger("google") + base_logger.addHandler(logging.StreamHandler()) + base_logger.setLevel(logging.DEBUG) + +- Configuring a handler for a specific Google module (for a client library called :code:`library_v1`): + +.. code-block:: python + + import logging + + from google.cloud import library_v1 + + base_logger = logging.getLogger("google.cloud.library_v1") + base_logger.addHandler(logging.StreamHandler()) + base_logger.setLevel(logging.DEBUG) + +Logging details +~~~~~~~~~~~~~~~ + +#. Regardless of which of the mechanisms above you use to configure logging for this library, by default logging events are not propagated up to the root + logger from the `google`-level logger. If you need the events to be propagated to the root logger, you must explicitly set + :code:`logging.getLogger("google").propagate = True` in your code. +#. You can mix the different logging configurations above for different Google modules. For example, you may want use a code-based logging configuration for + one library, but decide you need to also set up environment-based logging configuration for another library. + + #. If you attempt to use both code-based and environment-based configuration for the same module, the environment-based configuration will be ineffectual + if the code -based configuration gets applied first. + +#. The Google-specific logging configurations (default handlers for environment-based configuration; not propagating logging events to the root logger) get + executed the first time *any* client library is instantiated in your application, and only if the affected loggers have not been previously configured. + (This is the reason for 2.i. above.) diff --git a/packages/google-cloud-agentidentitycredentials/docs/CHANGELOG.md b/packages/google-cloud-agentidentitycredentials/docs/CHANGELOG.md new file mode 120000 index 000000000000..04c99a55caae --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/docs/CHANGELOG.md @@ -0,0 +1 @@ +../CHANGELOG.md \ No newline at end of file diff --git a/packages/google-cloud-agentidentitycredentials/docs/README.rst b/packages/google-cloud-agentidentitycredentials/docs/README.rst new file mode 100644 index 000000000000..9a52a52beb08 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/docs/README.rst @@ -0,0 +1,198 @@ +Python Client for agentidentitycredentials.googleapis.com +========================================================= + +|preview| |pypi| |versions| + +`agentidentitycredentials.googleapis.com`_: agentidentitycredentials.googleapis.com API. + +- `Client Library Documentation`_ +- `Product Documentation`_ + +.. |preview| image:: https://img.shields.io/badge/support-preview-orange.svg + :target: https://github.com/googleapis/google-cloud-python/blob/main/README.rst#stability-levels +.. |pypi| image:: https://img.shields.io/pypi/v/google-cloud-agentidentitycredentials.svg + :target: https://pypi.org/project/google-cloud-agentidentitycredentials/ +.. |versions| image:: https://img.shields.io/pypi/pyversions/google-cloud-agentidentitycredentials.svg + :target: https://pypi.org/project/google-cloud-agentidentitycredentials/ +.. _agentidentitycredentials.googleapis.com: https://cloud.google.com/agentidentitycredentials/ +.. _Client Library Documentation: https://cloud.google.com/python/docs/reference/google-cloud-agentidentitycredentials/latest/summary_overview +.. _Product Documentation: https://cloud.google.com/agentidentitycredentials/ + +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 agentidentitycredentials.googleapis.com.`_ +4. `Set up 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 +.. _Enable the agentidentitycredentials.googleapis.com.: https://cloud.google.com/agentidentitycredentials/ +.. _Set up Authentication.: https://googleapis.dev/python/google-api-core/latest/auth.html + +Installation +~~~~~~~~~~~~ + +Install this library in a virtual environment using `venv`_. `venv`_ is a tool that +creates isolated Python environments. These isolated environments can have separate +versions of Python packages, which allows you to isolate one project's dependencies +from the dependencies of other projects. + +With `venv`_, it's possible to install this library without needing system +install permissions, and without clashing with the installed system +dependencies. + +.. _`venv`: https://docs.python.org/3/library/venv.html + + +Code samples and snippets +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Code samples and snippets live in the `samples/`_ folder. + +.. _samples/: https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-agentidentitycredentials/samples + + +Supported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^ +Our client libraries are compatible with all current `active`_ and `maintenance`_ versions of +Python. + +Python >= 3.10, including 3.14 + +.. _active: https://devguide.python.org/devcycle/#in-development-main-branch +.. _maintenance: https://devguide.python.org/devcycle/#maintenance-branches + +Unsupported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Python <= 3.9 + + +If you are using an `end-of-life`_ +version of Python, we recommend that you update as soon as possible to an actively supported version. + +.. _end-of-life: https://devguide.python.org/devcycle/#end-of-life-branches + +Mac/Linux +^^^^^^^^^ + +.. code-block:: console + + python3 -m venv + source /bin/activate + pip install google-cloud-agentidentitycredentials + + +Windows +^^^^^^^ + +.. code-block:: console + + py -m venv + .\\Scripts\activate + pip install google-cloud-agentidentitycredentials + +Next Steps +~~~~~~~~~~ + +- Read the `Client Library Documentation`_ for agentidentitycredentials.googleapis.com + to see other available methods on the client. +- Read the `agentidentitycredentials.googleapis.com Product documentation`_ to learn + more about the product and see How-to Guides. +- View this `README`_ to see the full list of Cloud + APIs that we cover. + +.. _agentidentitycredentials.googleapis.com Product documentation: https://cloud.google.com/agentidentitycredentials/ +.. _README: https://github.com/googleapis/google-cloud-python/blob/main/README.rst + +Logging +------- + +This library uses the standard Python :code:`logging` functionality to log some RPC events that could be of interest for debugging and monitoring purposes. +Note the following: + +#. Logs may contain sensitive information. Take care to **restrict access to the logs** if they are saved, whether it be on local storage or on Google Cloud Logging. +#. Google may refine the occurrence, level, and content of various log messages in this library without flagging such changes as breaking. **Do not depend on immutability of the logging events**. +#. By default, the logging events from this library are not handled. You must **explicitly configure log handling** using one of the mechanisms below. + +Simple, environment-based configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To enable logging for this library without any changes in your code, set the :code:`GOOGLE_SDK_PYTHON_LOGGING_SCOPE` environment variable to a valid Google +logging scope. This configures handling of logging events (at level :code:`logging.DEBUG` or higher) from this library in a default manner, emitting the logged +messages in a structured format. It does not currently allow customizing the logging levels captured nor the handlers, formatters, etc. used for any logging +event. + +A logging scope is a period-separated namespace that begins with :code:`google`, identifying the Python module or package to log. + +- Valid logging scopes: :code:`google`, :code:`google.cloud.asset.v1`, :code:`google.api`, :code:`google.auth`, etc. +- Invalid logging scopes: :code:`foo`, :code:`123`, etc. + +**NOTE**: If the logging scope is invalid, the library does not set up any logging handlers. + +Environment-Based Examples +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Enabling the default handler for all Google-based loggers + +.. code-block:: console + + export GOOGLE_SDK_PYTHON_LOGGING_SCOPE=google + +- Enabling the default handler for a specific Google module (for a client library called :code:`library_v1`): + +.. code-block:: console + + export GOOGLE_SDK_PYTHON_LOGGING_SCOPE=google.cloud.library_v1 + + +Advanced, code-based configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can also configure a valid logging scope using Python's standard `logging` mechanism. + +Code-Based Examples +^^^^^^^^^^^^^^^^^^^ + +- Configuring a handler for all Google-based loggers + +.. code-block:: python + + import logging + + from google.cloud import library_v1 + + base_logger = logging.getLogger("google") + base_logger.addHandler(logging.StreamHandler()) + base_logger.setLevel(logging.DEBUG) + +- Configuring a handler for a specific Google module (for a client library called :code:`library_v1`): + +.. code-block:: python + + import logging + + from google.cloud import library_v1 + + base_logger = logging.getLogger("google.cloud.library_v1") + base_logger.addHandler(logging.StreamHandler()) + base_logger.setLevel(logging.DEBUG) + +Logging details +~~~~~~~~~~~~~~~ + +#. Regardless of which of the mechanisms above you use to configure logging for this library, by default logging events are not propagated up to the root + logger from the `google`-level logger. If you need the events to be propagated to the root logger, you must explicitly set + :code:`logging.getLogger("google").propagate = True` in your code. +#. You can mix the different logging configurations above for different Google modules. For example, you may want use a code-based logging configuration for + one library, but decide you need to also set up environment-based logging configuration for another library. + + #. If you attempt to use both code-based and environment-based configuration for the same module, the environment-based configuration will be ineffectual + if the code -based configuration gets applied first. + +#. The Google-specific logging configurations (default handlers for environment-based configuration; not propagating logging events to the root logger) get + executed the first time *any* client library is instantiated in your application, and only if the affected loggers have not been previously configured. + (This is the reason for 2.i. above.) diff --git a/packages/google-cloud-agentidentitycredentials/docs/_static/custom.css b/packages/google-cloud-agentidentitycredentials/docs/_static/custom.css new file mode 100644 index 000000000000..b0a295464b23 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/docs/_static/custom.css @@ -0,0 +1,20 @@ +div#python2-eol { + border-color: red; + border-width: medium; +} + +/* Ensure minimum width for 'Parameters' / 'Returns' column */ +dl.field-list > dt { + min-width: 100px +} + +/* Insert space between methods for readability */ +dl.method { + padding-top: 10px; + padding-bottom: 10px +} + +/* Insert empty space between classes */ +dl.class { + padding-bottom: 50px +} diff --git a/packages/google-cloud-agentidentitycredentials/docs/_templates/layout.html b/packages/google-cloud-agentidentitycredentials/docs/_templates/layout.html new file mode 100644 index 000000000000..95e9c77fcfe1 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/docs/_templates/layout.html @@ -0,0 +1,50 @@ + +{% extends "!layout.html" %} +{%- block content %} +{%- if theme_fixed_sidebar|lower == 'true' %} +
+ {{ sidebar() }} + {%- block document %} +
+ {%- if render_sidebar %} +
+ {%- endif %} + + {%- block relbar_top %} + {%- if theme_show_relbar_top|tobool %} + + {%- endif %} + {% endblock %} + +
+
+ As of January 1, 2020 this library no longer supports Python 2 on the latest released version. + Library versions released prior to that date will continue to be available. For more information please + visit Python 2 support on Google Cloud. +
+ {% block body %} {% endblock %} +
+ + {%- block relbar_bottom %} + {%- if theme_show_relbar_bottom|tobool %} + + {%- endif %} + {% endblock %} + + {%- if render_sidebar %} +
+ {%- endif %} +
+ {%- endblock %} +
+
+{%- else %} +{{ super() }} +{%- endif %} +{%- endblock %} diff --git a/packages/google-cloud-agentidentitycredentials/docs/agentidentitycredentials_v1/auth_provider_credentials_service.rst b/packages/google-cloud-agentidentitycredentials/docs/agentidentitycredentials_v1/auth_provider_credentials_service.rst new file mode 100644 index 000000000000..15d0ab0d0149 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/docs/agentidentitycredentials_v1/auth_provider_credentials_service.rst @@ -0,0 +1,6 @@ +AuthProviderCredentialsService +------------------------------------------------ + +.. automodule:: google.cloud.agentidentitycredentials_v1.services.auth_provider_credentials_service + :members: + :inherited-members: diff --git a/packages/google-cloud-agentidentitycredentials/docs/agentidentitycredentials_v1/services_.rst b/packages/google-cloud-agentidentitycredentials/docs/agentidentitycredentials_v1/services_.rst new file mode 100644 index 000000000000..f457ba2f9285 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/docs/agentidentitycredentials_v1/services_.rst @@ -0,0 +1,6 @@ +Services for Google Cloud Agentidentitycredentials v1 API +========================================================= +.. toctree:: + :maxdepth: 2 + + auth_provider_credentials_service diff --git a/packages/google-cloud-agentidentitycredentials/docs/agentidentitycredentials_v1/types_.rst b/packages/google-cloud-agentidentitycredentials/docs/agentidentitycredentials_v1/types_.rst new file mode 100644 index 000000000000..a6b534e508dc --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/docs/agentidentitycredentials_v1/types_.rst @@ -0,0 +1,6 @@ +Types for Google Cloud Agentidentitycredentials v1 API +====================================================== + +.. automodule:: google.cloud.agentidentitycredentials_v1.types + :members: + :show-inheritance: diff --git a/packages/google-cloud-agentidentitycredentials/docs/conf.py b/packages/google-cloud-agentidentitycredentials/docs/conf.py new file mode 100644 index 000000000000..6e69db83f8a5 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/docs/conf.py @@ -0,0 +1,417 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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-agentidentitycredentials 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 logging +import os +import shlex +import sys +from typing import Any + +# 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("..")) + +# For plugins that can not read conf.py. +# See also: https://github.com/docascode/sphinx-docfx-yaml/issues/85 +sys.path.insert(0, os.path.abspath(".")) + +__version__ = "" + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +needs_sphinx = "4.5.0" + +# 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.doctest", + "sphinx.ext.napoleon", + "sphinx.ext.todo", + "sphinx.ext.viewcode", + "recommonmark", +] + +# autodoc/autosummary flags +autoclass_content = "both" +autodoc_default_options = {"members": True} +autosummary_generate = True + + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# source_suffix = ['.rst', '.md'] +source_suffix = [".rst", ".md"] + +# The encoding of source files. +# source_encoding = 'utf-8-sig' + +# The root toctree document. +root_doc = "index" + +# General information about the project. +project = "google-cloud-agentidentitycredentials" +copyright = "2026, Google, LLC" +author = "Google APIs" + +# 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", + "**/.nox/**/*", + "samples/AUTHORING_GUIDE.md", + "samples/CONTRIBUTING.md", + "samples/snippets/README.rst", +] + +# 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 google-cloud-agentidentitycredentials", + "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-agentidentitycredentials-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 = [ + ( + root_doc, + "google-cloud-agentidentitycredentials.tex", + "google-cloud-agentidentitycredentials 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 = [ + ( + root_doc, + "google-cloud-agentidentitycredentials", + "google-cloud-agentidentitycredentials 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 = [ + ( + root_doc, + "google-cloud-agentidentitycredentials", + "google-cloud-agentidentitycredentials Documentation", + author, + "google-cloud-agentidentitycredentials", + "google-cloud-agentidentitycredentials Library", + "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": ("https://python.readthedocs.org/en/latest/", None), + "google-auth": ("https://googleapis.dev/python/google-auth/latest/", None), + "google.api_core": ( + "https://googleapis.dev/python/google-api-core/latest/", + None, + ), + "grpc": ("https://grpc.github.io/grpc/python/", None), + "proto-plus": ("https://proto-plus-python.readthedocs.io/en/latest/", None), + "protobuf": ("https://googleapis.dev/python/protobuf/latest/", None), +} + + +# 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 + + +# Setup for sphinx behaviors such as warning filters. +class UnexpectedUnindentFilter(logging.Filter): + """Filter out warnings about unexpected unindentation following bullet lists.""" + + def filter(self, record: logging.LogRecord) -> bool: + """Filter the log record. + + Args: + record (logging.LogRecord): The log record. + + Returns: + bool: False to suppress the warning, True to allow it. + """ + msg = record.getMessage() + if "Bullet list ends without a blank line" in msg: + return False + return True + + +def setup(app: Any) -> None: + """Setup the Sphinx application. + + Args: + app (Any): The Sphinx application. + """ + # Sphinx's logger is hierarchical. Adding a filter to the + # root 'sphinx' logger will catch warnings from all sub-loggers. + logger = logging.getLogger("sphinx") + logger.addFilter(UnexpectedUnindentFilter()) diff --git a/packages/google-cloud-agentidentitycredentials/docs/index.rst b/packages/google-cloud-agentidentitycredentials/docs/index.rst new file mode 100644 index 000000000000..39357d159687 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/docs/index.rst @@ -0,0 +1,28 @@ +.. include:: README.rst + +.. include:: multiprocessing.rst + + +API Reference +------------- +.. toctree:: + :maxdepth: 2 + + agentidentitycredentials_v1/services_ + agentidentitycredentials_v1/types_ + + +Changelog +--------- + +For a list of all ``google-cloud-agentidentitycredentials`` releases: + +.. toctree:: + :maxdepth: 2 + + CHANGELOG + +.. toctree:: + :hidden: + + summary_overview.md diff --git a/packages/google-cloud-agentidentitycredentials/docs/multiprocessing.rst b/packages/google-cloud-agentidentitycredentials/docs/multiprocessing.rst new file mode 100644 index 000000000000..536d17b2ea65 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/docs/multiprocessing.rst @@ -0,0 +1,7 @@ +.. note:: + + Because this client uses :mod:`grpc` library, it is safe to + share instances across threads. In multiprocessing scenarios, the best + practice is to create client instances *after* the invocation of + :func:`os.fork` by :class:`multiprocessing.pool.Pool` or + :class:`multiprocessing.Process`. diff --git a/packages/google-cloud-agentidentitycredentials/docs/summary_overview.md b/packages/google-cloud-agentidentitycredentials/docs/summary_overview.md new file mode 100644 index 000000000000..c7299562adfc --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/docs/summary_overview.md @@ -0,0 +1,22 @@ +[ +This is a templated file. Adding content to this file may result in it being +reverted. Instead, if you want to place additional content, create an +"overview_content.md" file in `docs/` directory. The Sphinx tool will +pick up on the content and merge the content. +]: # + +# agentidentitycredentials.googleapis.com API + +Overview of the APIs available for agentidentitycredentials.googleapis.com API. + +## All entries + +Classes, methods and properties & attributes for +agentidentitycredentials.googleapis.com API. + +[classes](https://cloud.google.com/python/docs/reference/google-cloud-agentidentitycredentials/latest/summary_class.html) + +[methods](https://cloud.google.com/python/docs/reference/google-cloud-agentidentitycredentials/latest/summary_method.html) + +[properties and +attributes](https://cloud.google.com/python/docs/reference/google-cloud-agentidentitycredentials/latest/summary_property.html) diff --git a/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials/__init__.py b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials/__init__.py new file mode 100644 index 000000000000..88da41495d79 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials/__init__.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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.agentidentitycredentials import gapic_version as package_version + +__version__ = package_version.__version__ + + +from google.cloud.agentidentitycredentials_v1.services.auth_provider_credentials_service.async_client import ( + AuthProviderCredentialsServiceAsyncClient, +) +from google.cloud.agentidentitycredentials_v1.services.auth_provider_credentials_service.client import ( + AuthProviderCredentialsServiceClient, +) +from google.cloud.agentidentitycredentials_v1.types.auth_provider_credentials_service import ( + FinalizeCredentialsRequest, + FinalizeCredentialsResponse, + RetrieveCredentialsRequest, + RetrieveCredentialsResponse, +) + +__all__ = ( + "AuthProviderCredentialsServiceClient", + "AuthProviderCredentialsServiceAsyncClient", + "FinalizeCredentialsRequest", + "FinalizeCredentialsResponse", + "RetrieveCredentialsRequest", + "RetrieveCredentialsResponse", +) diff --git a/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials/gapic_version.py b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials/gapic_version.py new file mode 100644 index 000000000000..e89a0031d71b --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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. +# +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials/py.typed b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials/py.typed new file mode 100644 index 000000000000..fe5e68011f94 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-cloud-agentidentitycredentials package uses inline types. diff --git a/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/__init__.py b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/__init__.py new file mode 100644 index 000000000000..aa5fecf0e405 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/__init__.py @@ -0,0 +1,127 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 sys + +import google.api_core as api_core + +from google.cloud.agentidentitycredentials_v1 import gapic_version as package_version + +__version__ = package_version.__version__ + +from importlib import metadata + +from .services.auth_provider_credentials_service import ( + AuthProviderCredentialsServiceAsyncClient, + AuthProviderCredentialsServiceClient, +) +from .types.auth_provider_credentials_service import ( + FinalizeCredentialsRequest, + FinalizeCredentialsResponse, + RetrieveCredentialsRequest, + RetrieveCredentialsResponse, +) + +if hasattr(api_core, "check_python_version") and hasattr( + api_core, "check_dependency_versions" +): # pragma: NO COVER + api_core.check_python_version("google.cloud.agentidentitycredentials_v1") # type: ignore + api_core.check_dependency_versions("google.cloud.agentidentitycredentials_v1") # type: ignore +else: # pragma: NO COVER + # An older version of api_core is installed which does not define the + # functions above. We do equivalent checks manually. + try: + import warnings + + _py_version_str = sys.version.split()[0] + _package_label = "google.cloud.agentidentitycredentials_v1" + if sys.version_info < (3, 10): + warnings.warn( + "You are using a non-supported Python version " + + f"({_py_version_str}). Google will not post any further " + + f"updates to {_package_label} supporting this Python version. " + + "Please upgrade to the latest Python version, or at " + + f"least to Python 3.10, and then update {_package_label}.", + FutureWarning, + ) + + def parse_version_to_tuple(version_string: str): + """Safely converts a semantic version string to a comparable tuple of integers. + Example: "4.25.8" -> (4, 25, 8) + Ignores non-numeric parts and handles common version formats. + Args: + version_string: Version string in the format "x.y.z" or "x.y.z" + Returns: + Tuple of integers for the parsed version string. + """ + parts = [] + for part in version_string.split("."): + try: + parts.append(int(part)) + except ValueError: + # If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here. + # This is a simplification compared to 'packaging.parse_version', but sufficient + # for comparing strictly numeric semantic versions. + break + return tuple(parts) + + def _get_version(dependency_name): + try: + version_string: str = metadata.version(dependency_name) + parsed_version = parse_version_to_tuple(version_string) + return (parsed_version, version_string) + except Exception: + # Catch exceptions from metadata.version() (e.g., PackageNotFoundError) + # or errors during parse_version_to_tuple + return (None, "--") + + _dependency_package = "google.protobuf" + _next_supported_version = "4.25.8" + _next_supported_version_tuple = (4, 25, 8) + _recommendation = " (we recommend 6.x)" + (_version_used, _version_used_string) = _get_version(_dependency_package) + if _version_used and _version_used < _next_supported_version_tuple: + warnings.warn( + f"Package {_package_label} depends on " + + f"{_dependency_package}, currently installed at version " + + f"{_version_used_string}. Future updates to " + + f"{_package_label} will require {_dependency_package} at " + + f"version {_next_supported_version} or higher{_recommendation}." + + " Please ensure " + + "that either (a) your Python environment doesn't pin the " + + f"version of {_dependency_package}, so that updates to " + + f"{_package_label} can require the higher version, or " + + "(b) you manually update your Python environment to use at " + + f"least version {_next_supported_version} of " + + f"{_dependency_package}.", + FutureWarning, + ) + except Exception: + warnings.warn( + "Could not determine the version of Python " + + "currently being used. To continue receiving " + + "updates for {_package_label}, ensure you are " + + "using a supported version of Python; see " + + "https://devguide.python.org/versions/" + ) + +__all__ = ( + "AuthProviderCredentialsServiceAsyncClient", + "AuthProviderCredentialsServiceClient", + "FinalizeCredentialsRequest", + "FinalizeCredentialsResponse", + "RetrieveCredentialsRequest", + "RetrieveCredentialsResponse", +) diff --git a/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/gapic_metadata.json b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/gapic_metadata.json new file mode 100644 index 000000000000..269f7c89204f --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/gapic_metadata.json @@ -0,0 +1,58 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.cloud.agentidentitycredentials_v1", + "protoPackage": "google.cloud.agentidentitycredentials.v1", + "schema": "1.0", + "services": { + "AuthProviderCredentialsService": { + "clients": { + "grpc": { + "libraryClient": "AuthProviderCredentialsServiceClient", + "rpcs": { + "FinalizeCredentials": { + "methods": [ + "finalize_credentials" + ] + }, + "RetrieveCredentials": { + "methods": [ + "retrieve_credentials" + ] + } + } + }, + "grpc-async": { + "libraryClient": "AuthProviderCredentialsServiceAsyncClient", + "rpcs": { + "FinalizeCredentials": { + "methods": [ + "finalize_credentials" + ] + }, + "RetrieveCredentials": { + "methods": [ + "retrieve_credentials" + ] + } + } + }, + "rest": { + "libraryClient": "AuthProviderCredentialsServiceClient", + "rpcs": { + "FinalizeCredentials": { + "methods": [ + "finalize_credentials" + ] + }, + "RetrieveCredentials": { + "methods": [ + "retrieve_credentials" + ] + } + } + } + } + } + } +} diff --git a/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/gapic_version.py b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/gapic_version.py new file mode 100644 index 000000000000..e89a0031d71b --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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. +# +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/py.typed b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/py.typed new file mode 100644 index 000000000000..fe5e68011f94 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-cloud-agentidentitycredentials package uses inline types. diff --git a/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/__init__.py b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/__init__.py new file mode 100644 index 000000000000..32b36c5c4fe0 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/__init__.py b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/__init__.py new file mode 100644 index 000000000000..815d5397c0ca --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .async_client import AuthProviderCredentialsServiceAsyncClient +from .client import AuthProviderCredentialsServiceClient + +__all__ = ( + "AuthProviderCredentialsServiceClient", + "AuthProviderCredentialsServiceAsyncClient", +) diff --git a/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/async_client.py b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/async_client.py new file mode 100644 index 000000000000..15c8a8642162 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/async_client.py @@ -0,0 +1,574 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 logging as std_logging +import re +from collections import OrderedDict +from typing import ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, +) + +import google.protobuf +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.api_core.client_options import ClientOptions +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.agentidentitycredentials_v1 import gapic_version as package_version + +try: + OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.cloud.agentidentitycredentials_v1.types import ( + auth_provider_credentials_service, +) + +from .client import AuthProviderCredentialsServiceClient +from .transports.base import ( + DEFAULT_CLIENT_INFO, + AuthProviderCredentialsServiceTransport, +) +from .transports.grpc_asyncio import AuthProviderCredentialsServiceGrpcAsyncIOTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class AuthProviderCredentialsServiceAsyncClient: + """Service for managing AuthProvider Credentials.""" + + _client: AuthProviderCredentialsServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = AuthProviderCredentialsServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = AuthProviderCredentialsServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + AuthProviderCredentialsServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = AuthProviderCredentialsServiceClient._DEFAULT_UNIVERSE + + auth_provider_path = staticmethod( + AuthProviderCredentialsServiceClient.auth_provider_path + ) + parse_auth_provider_path = staticmethod( + AuthProviderCredentialsServiceClient.parse_auth_provider_path + ) + common_billing_account_path = staticmethod( + AuthProviderCredentialsServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AuthProviderCredentialsServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + AuthProviderCredentialsServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + AuthProviderCredentialsServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + AuthProviderCredentialsServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + AuthProviderCredentialsServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + AuthProviderCredentialsServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + AuthProviderCredentialsServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + AuthProviderCredentialsServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + AuthProviderCredentialsServiceClient.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: + AuthProviderCredentialsServiceAsyncClient: The constructed client. + """ + sa_info_func = ( + AuthProviderCredentialsServiceClient.from_service_account_info.__func__ # type: ignore + ) + return sa_info_func( + AuthProviderCredentialsServiceAsyncClient, info, *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: + AuthProviderCredentialsServiceAsyncClient: The constructed client. + """ + sa_file_func = ( + AuthProviderCredentialsServiceClient.from_service_account_file.__func__ # type: ignore + ) + return sa_file_func( + AuthProviderCredentialsServiceAsyncClient, filename, *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 variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AuthProviderCredentialsServiceClient.get_mtls_endpoint_and_cert_source( + client_options + ) # type: ignore + + @property + def transport(self) -> AuthProviderCredentialsServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AuthProviderCredentialsServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self) -> str: + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = AuthProviderCredentialsServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AuthProviderCredentialsServiceTransport, + Callable[..., AuthProviderCredentialsServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the auth provider credentials service async 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 (Optional[Union[str,AuthProviderCredentialsServiceTransport,Callable[..., AuthProviderCredentialsServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AuthProviderCredentialsServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "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). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS 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. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + 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. + """ + self._client = AuthProviderCredentialsServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.cloud.agentidentitycredentials_v1.AuthProviderCredentialsServiceAsyncClient`.", + extra={ + "serviceName": "google.cloud.agentidentitycredentials.v1.AuthProviderCredentialsService", + "universeDomain": getattr( + self._client._transport._credentials, "universe_domain", "" + ), + "credentialsType": f"{type(self._client._transport._credentials).__module__}.{type(self._client._transport._credentials).__qualname__}", + "credentialsInfo": getattr( + self.transport._credentials, "get_cred_info", lambda: None + )(), + } + if hasattr(self._client._transport, "_credentials") + else { + "serviceName": "google.cloud.agentidentitycredentials.v1.AuthProviderCredentialsService", + "credentialsType": None, + }, + ) + + async def retrieve_credentials( + self, + request: Optional[ + Union[auth_provider_credentials_service.RetrieveCredentialsRequest, dict] + ] = None, + *, + auth_provider: Optional[str] = None, + user_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> auth_provider_credentials_service.RetrieveCredentialsResponse: + r"""Retrieves authorization credentials for an authprovider, or + indicates what action needs to be taken to obtain credentials. + If the ``token`` field in the response is populated, credential + retrieval was successful. If one of the fields in the ``status`` + oneof is populated, further action is required to obtain + credentials, such as redirecting the user for consent. View + comments on ``RetrieveCredentialsResponse`` for more + information. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import agentidentitycredentials_v1 + + async def sample_retrieve_credentials(): + # Create a client + client = agentidentitycredentials_v1.AuthProviderCredentialsServiceAsyncClient() + + # Initialize request argument(s) + request = agentidentitycredentials_v1.RetrieveCredentialsRequest( + auth_provider="auth_provider_value", + user_id="user_id_value", + ) + + # Make the request + response = await client.retrieve_credentials(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.agentidentitycredentials_v1.types.RetrieveCredentialsRequest, dict]]): + The request object. Request message for + RetrieveCredentials. + auth_provider (:class:`str`): + Required. The parent resource name of the AuthProvider. + Format: + ``projects/{project}/locations/{location}/authProviders/{auth_provider}`` + + This corresponds to the ``auth_provider`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + user_id (:class:`str`): + Required. The identity of the end + user. + + This corresponds to the ``user_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.agentidentitycredentials_v1.types.RetrieveCredentialsResponse: + Response message for + RetrieveCredentials. Contains the access + tokens and related artifacts. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [auth_provider, user_id] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, auth_provider_credentials_service.RetrieveCredentialsRequest + ): + request = auth_provider_credentials_service.RetrieveCredentialsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if auth_provider is not None: + request.auth_provider = auth_provider + if user_id is not None: + request.user_id = user_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.retrieve_credentials + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("auth_provider", request.auth_provider),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def finalize_credentials( + self, + request: Optional[ + Union[auth_provider_credentials_service.FinalizeCredentialsRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> auth_provider_credentials_service.FinalizeCredentialsResponse: + r"""Finalizes the credentials after a successful consent + flow. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import agentidentitycredentials_v1 + + async def sample_finalize_credentials(): + # Create a client + client = agentidentitycredentials_v1.AuthProviderCredentialsServiceAsyncClient() + + # Initialize request argument(s) + request = agentidentitycredentials_v1.FinalizeCredentialsRequest( + auth_provider="auth_provider_value", + user_id="user_id_value", + user_id_validation_state=b'user_id_validation_state_blob', + consent_nonce="consent_nonce_value", + ) + + # Make the request + response = await client.finalize_credentials(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.agentidentitycredentials_v1.types.FinalizeCredentialsRequest, dict]]): + The request object. Request message for + FinalizeCredentials. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.agentidentitycredentials_v1.types.FinalizeCredentialsResponse: + Response message for + FinalizeCredentials. Intentionally empty + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, auth_provider_credentials_service.FinalizeCredentialsRequest + ): + request = auth_provider_credentials_service.FinalizeCredentialsRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.finalize_credentials + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("auth_provider", request.auth_provider),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "AuthProviderCredentialsServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AuthProviderCredentialsServiceAsyncClient",) diff --git a/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/client.py b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/client.py new file mode 100644 index 000000000000..68b58218d3f4 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/client.py @@ -0,0 +1,1010 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 json +import logging as std_logging +import os +import re +import warnings +from collections import OrderedDict +from http import HTTPStatus +from typing import ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) + +import google.protobuf +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.agentidentitycredentials_v1 import gapic_version as package_version + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + +from google.cloud.agentidentitycredentials_v1.types import ( + auth_provider_credentials_service, +) + +from .transports.base import ( + DEFAULT_CLIENT_INFO, + AuthProviderCredentialsServiceTransport, +) +from .transports.grpc import AuthProviderCredentialsServiceGrpcTransport +from .transports.grpc_asyncio import AuthProviderCredentialsServiceGrpcAsyncIOTransport +from .transports.rest import AuthProviderCredentialsServiceRestTransport + + +class AuthProviderCredentialsServiceClientMeta(type): + """Metaclass for the AuthProviderCredentialsService 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[AuthProviderCredentialsServiceTransport]] + _transport_registry["grpc"] = AuthProviderCredentialsServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + AuthProviderCredentialsServiceGrpcAsyncIOTransport + ) + _transport_registry["rest"] = AuthProviderCredentialsServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AuthProviderCredentialsServiceTransport]: + """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 AuthProviderCredentialsServiceClient( + metaclass=AuthProviderCredentialsServiceClientMeta +): + """Service for managing AuthProvider Credentials.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint) -> Optional[str]: + """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: + Optional[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) + if m is None: + # Could not parse api_endpoint; return as-is. + return 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") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "agentidentitycredentials.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "agentidentitycredentials.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @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: + AuthProviderCredentialsServiceClient: 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: + AuthProviderCredentialsServiceClient: 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) -> AuthProviderCredentialsServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AuthProviderCredentialsServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def auth_provider_path( + project: str, + location: str, + auth_provider: str, + ) -> str: + """Returns a fully-qualified auth_provider string.""" + return "projects/{project}/locations/{location}/authProviders/{auth_provider}".format( + project=project, + location=location, + auth_provider=auth_provider, + ) + + @staticmethod + def parse_auth_provider_path(path: str) -> Dict[str, str]: + """Parses a auth_provider path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/authProviders/(?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 + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + AuthProviderCredentialsServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + 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: + 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 + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + AuthProviderCredentialsServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ) -> str: + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = AuthProviderCredentialsServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = AuthProviderCredentialsServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + AuthProviderCredentialsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], universe_domain_env: Optional[str] + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = AuthProviderCredentialsServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self) -> str: + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AuthProviderCredentialsServiceTransport, + Callable[..., AuthProviderCredentialsServiceTransport], + ] + ] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the auth provider credentials 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 (Optional[Union[str,AuthProviderCredentialsServiceTransport,Callable[..., AuthProviderCredentialsServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AuthProviderCredentialsServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "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). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS 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. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + 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. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict(self._client_options) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr(self._client_options, "universe_domain", None) + + self._use_client_cert, self._use_mtls_endpoint, self._universe_domain_env = ( + AuthProviderCredentialsServiceClient._read_environment_variables() + ) + self._client_cert_source = ( + AuthProviderCredentialsServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + AuthProviderCredentialsServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint: str = "" # updated below, depending on `transport` + + # Initialize the universe domain validation. + self._is_universe_domain_valid = False + + if CLIENT_LOGGING_SUPPORTED: # pragma: NO COVER + # Setup logging. + client_logging.initialize_logging() + + api_key_value = getattr(self._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. + transport_provided = isinstance( + transport, AuthProviderCredentialsServiceTransport + ) + if transport_provided: + # transport is a AuthProviderCredentialsServiceTransport instance. + if credentials or self._client_options.credentials_file or api_key_value: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes directly." + ) + self._transport = cast(AuthProviderCredentialsServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AuthProviderCredentialsServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + 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_init: Union[ + Type[AuthProviderCredentialsServiceTransport], + Callable[..., AuthProviderCredentialsServiceTransport], + ] = ( + AuthProviderCredentialsServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., AuthProviderCredentialsServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + api_audience=self._client_options.api_audience, + ) + + if "async" not in str(self._transport): + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.cloud.agentidentitycredentials_v1.AuthProviderCredentialsServiceClient`.", + extra={ + "serviceName": "google.cloud.agentidentitycredentials.v1.AuthProviderCredentialsService", + "universeDomain": getattr( + self._transport._credentials, "universe_domain", "" + ), + "credentialsType": f"{type(self._transport._credentials).__module__}.{type(self._transport._credentials).__qualname__}", + "credentialsInfo": getattr( + self.transport._credentials, "get_cred_info", lambda: None + )(), + } + if hasattr(self._transport, "_credentials") + else { + "serviceName": "google.cloud.agentidentitycredentials.v1.AuthProviderCredentialsService", + "credentialsType": None, + }, + ) + + def retrieve_credentials( + self, + request: Optional[ + Union[auth_provider_credentials_service.RetrieveCredentialsRequest, dict] + ] = None, + *, + auth_provider: Optional[str] = None, + user_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> auth_provider_credentials_service.RetrieveCredentialsResponse: + r"""Retrieves authorization credentials for an authprovider, or + indicates what action needs to be taken to obtain credentials. + If the ``token`` field in the response is populated, credential + retrieval was successful. If one of the fields in the ``status`` + oneof is populated, further action is required to obtain + credentials, such as redirecting the user for consent. View + comments on ``RetrieveCredentialsResponse`` for more + information. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import agentidentitycredentials_v1 + + def sample_retrieve_credentials(): + # Create a client + client = agentidentitycredentials_v1.AuthProviderCredentialsServiceClient() + + # Initialize request argument(s) + request = agentidentitycredentials_v1.RetrieveCredentialsRequest( + auth_provider="auth_provider_value", + user_id="user_id_value", + ) + + # Make the request + response = client.retrieve_credentials(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.agentidentitycredentials_v1.types.RetrieveCredentialsRequest, dict]): + The request object. Request message for + RetrieveCredentials. + auth_provider (str): + Required. The parent resource name of the AuthProvider. + Format: + ``projects/{project}/locations/{location}/authProviders/{auth_provider}`` + + This corresponds to the ``auth_provider`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + user_id (str): + Required. The identity of the end + user. + + This corresponds to the ``user_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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.agentidentitycredentials_v1.types.RetrieveCredentialsResponse: + Response message for + RetrieveCredentials. Contains the access + tokens and related artifacts. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [auth_provider, user_id] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, auth_provider_credentials_service.RetrieveCredentialsRequest + ): + request = auth_provider_credentials_service.RetrieveCredentialsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if auth_provider is not None: + request.auth_provider = auth_provider + if user_id is not None: + request.user_id = user_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.retrieve_credentials] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("auth_provider", request.auth_provider),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def finalize_credentials( + self, + request: Optional[ + Union[auth_provider_credentials_service.FinalizeCredentialsRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> auth_provider_credentials_service.FinalizeCredentialsResponse: + r"""Finalizes the credentials after a successful consent + flow. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import agentidentitycredentials_v1 + + def sample_finalize_credentials(): + # Create a client + client = agentidentitycredentials_v1.AuthProviderCredentialsServiceClient() + + # Initialize request argument(s) + request = agentidentitycredentials_v1.FinalizeCredentialsRequest( + auth_provider="auth_provider_value", + user_id="user_id_value", + user_id_validation_state=b'user_id_validation_state_blob', + consent_nonce="consent_nonce_value", + ) + + # Make the request + response = client.finalize_credentials(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.agentidentitycredentials_v1.types.FinalizeCredentialsRequest, dict]): + The request object. Request message for + FinalizeCredentials. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.agentidentitycredentials_v1.types.FinalizeCredentialsResponse: + Response message for + FinalizeCredentials. Intentionally empty + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, auth_provider_credentials_service.FinalizeCredentialsRequest + ): + request = auth_provider_credentials_service.FinalizeCredentialsRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.finalize_credentials] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("auth_provider", request.auth_provider),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AuthProviderCredentialsServiceClient": + 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() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AuthProviderCredentialsServiceClient",) diff --git a/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/transports/README.rst b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/transports/README.rst new file mode 100644 index 000000000000..b6c556ba9dec --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/transports/README.rst @@ -0,0 +1,10 @@ + +transport inheritance structure +_______________________________ + +``AuthProviderCredentialsServiceTransport`` is the ABC for all transports. + +- public child ``AuthProviderCredentialsServiceGrpcTransport`` for sync gRPC transport (defined in ``grpc.py``). +- public child ``AuthProviderCredentialsServiceGrpcAsyncIOTransport`` for async gRPC transport (defined in ``grpc_asyncio.py``). +- private child ``_BaseAuthProviderCredentialsServiceRestTransport`` for base REST transport with inner classes ``_BaseMETHOD`` (defined in ``rest_base.py``). +- public child ``AuthProviderCredentialsServiceRestTransport`` for sync REST transport with inner classes ``METHOD`` derived from the parent's corresponding ``_BaseMETHOD`` classes (defined in ``rest.py``). diff --git a/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/transports/__init__.py b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/transports/__init__.py new file mode 100644 index 000000000000..278fcc1b1855 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/transports/__init__.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 AuthProviderCredentialsServiceTransport +from .grpc import AuthProviderCredentialsServiceGrpcTransport +from .grpc_asyncio import AuthProviderCredentialsServiceGrpcAsyncIOTransport +from .rest import ( + AuthProviderCredentialsServiceRestInterceptor, + AuthProviderCredentialsServiceRestTransport, +) + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[AuthProviderCredentialsServiceTransport]] +_transport_registry["grpc"] = AuthProviderCredentialsServiceGrpcTransport +_transport_registry["grpc_asyncio"] = AuthProviderCredentialsServiceGrpcAsyncIOTransport +_transport_registry["rest"] = AuthProviderCredentialsServiceRestTransport + +__all__ = ( + "AuthProviderCredentialsServiceTransport", + "AuthProviderCredentialsServiceGrpcTransport", + "AuthProviderCredentialsServiceGrpcAsyncIOTransport", + "AuthProviderCredentialsServiceRestTransport", + "AuthProviderCredentialsServiceRestInterceptor", +) diff --git a/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/transports/base.py b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/transports/base.py new file mode 100644 index 000000000000..2e31afc06123 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/transports/base.py @@ -0,0 +1,197 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union + +import google.api_core +import google.auth # type: ignore +import google.protobuf +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.agentidentitycredentials_v1 import gapic_version as package_version +from google.cloud.agentidentitycredentials_v1.types import ( + auth_provider_credentials_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AuthProviderCredentialsServiceTransport(abc.ABC): + """Abstract transport class for AuthProviderCredentialsService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) + + DEFAULT_HOST: str = "agentidentitycredentials.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'agentidentitycredentials.googleapis.com'). + 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]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + 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. + api_audience (Optional[str]): The intended audience for the API calls + to the service that will be set when using certain 3rd party + authentication flows. Audience is typically a resource identifier. + If not set, the host value will be used as a default. + """ + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # 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=scopes, + quota_project_id=quota_project_id, + default_scopes=self.AUTH_SCOPES, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + scopes=scopes, + quota_project_id=quota_project_id, + default_scopes=self.AUTH_SCOPES, + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr(service_account.Credentials, "with_always_use_jwt_access") + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + self._wrapped_methods: Dict[Callable, Callable] = {} + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.retrieve_credentials: gapic_v1.method.wrap_method( + self.retrieve_credentials, + default_timeout=None, + client_info=client_info, + ), + self.finalize_credentials: gapic_v1.method.wrap_method( + self.finalize_credentials, + 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 retrieve_credentials( + self, + ) -> Callable[ + [auth_provider_credentials_service.RetrieveCredentialsRequest], + Union[ + auth_provider_credentials_service.RetrieveCredentialsResponse, + Awaitable[auth_provider_credentials_service.RetrieveCredentialsResponse], + ], + ]: + raise NotImplementedError() + + @property + def finalize_credentials( + self, + ) -> Callable[ + [auth_provider_credentials_service.FinalizeCredentialsRequest], + Union[ + auth_provider_credentials_service.FinalizeCredentialsResponse, + Awaitable[auth_provider_credentials_service.FinalizeCredentialsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AuthProviderCredentialsServiceTransport",) diff --git a/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/transports/grpc.py b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/transports/grpc.py new file mode 100644 index 000000000000..c0f7598e15d7 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/transports/grpc.py @@ -0,0 +1,406 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 json +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +import google.auth # type: ignore +import google.protobuf.message +import grpc # type: ignore +import proto # type: ignore +from google.api_core import gapic_v1, grpc_helpers +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson + +from google.cloud.agentidentitycredentials_v1.types import ( + auth_provider_credentials_service, +) + +from .base import DEFAULT_CLIENT_INFO, AuthProviderCredentialsServiceTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor(grpc.UnaryUnaryClientInterceptor): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = f"{type(request).__name__}: {pickle.dumps(request)!r}" + + request_metadata = { + key: value.decode("utf-8") if isinstance(value, bytes) else value + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.cloud.agentidentitycredentials.v1.AuthProviderCredentialsService", + "rpcName": str(client_call_details.method), + "request": grpc_request, + "metadata": grpc_request["metadata"], + }, + ) + response = continuation(client_call_details, request) + if logging_enabled: # pragma: NO COVER + response_metadata = response.trailing_metadata() + # Convert gRPC metadata `` to list of tuples + metadata = ( + dict([(k, str(v)) for k, v in response_metadata]) + if response_metadata + else None + ) + result = response.result() + if isinstance(result, proto.Message): + response_payload = type(result).to_json(result) + elif isinstance(result, google.protobuf.message.Message): + response_payload = MessageToJson(result) + else: + response_payload = f"{type(result).__name__}: {pickle.dumps(result)!r}" + grpc_response = { + "payload": response_payload, + "metadata": metadata, + "status": "OK", + } + _LOGGER.debug( + f"Received response for {client_call_details.method}.", + extra={ + "serviceName": "google.cloud.agentidentitycredentials.v1.AuthProviderCredentialsService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AuthProviderCredentialsServiceGrpcTransport( + AuthProviderCredentialsServiceTransport +): + """gRPC backend transport for AuthProviderCredentialsService. + + Service for managing AuthProvider Credentials. + + 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 = "agentidentitycredentials.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'agentidentitycredentials.googleapis.com'). + 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 a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + 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 a ``channel`` instance 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 a ``channel`` instance 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. + api_audience (Optional[str]): The intended audience for the API calls + to the service that will be set when using certain 3rd party + authentication flows. Audience is typically a resource identifier. + If not set, the host value will be used as a default. + + 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 isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + self._interceptor = _LoggingClientInterceptor() + self._logged_channel = grpc.intercept_channel( + self._grpc_channel, self._interceptor + ) + + # Wrap messages. This must be done after self._logged_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "agentidentitycredentials.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + 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 retrieve_credentials( + self, + ) -> Callable[ + [auth_provider_credentials_service.RetrieveCredentialsRequest], + auth_provider_credentials_service.RetrieveCredentialsResponse, + ]: + r"""Return a callable for the retrieve credentials method over gRPC. + + Retrieves authorization credentials for an authprovider, or + indicates what action needs to be taken to obtain credentials. + If the ``token`` field in the response is populated, credential + retrieval was successful. If one of the fields in the ``status`` + oneof is populated, further action is required to obtain + credentials, such as redirecting the user for consent. View + comments on ``RetrieveCredentialsResponse`` for more + information. + + Returns: + Callable[[~.RetrieveCredentialsRequest], + ~.RetrieveCredentialsResponse]: + 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 "retrieve_credentials" not in self._stubs: + self._stubs["retrieve_credentials"] = self._logged_channel.unary_unary( + "/google.cloud.agentidentitycredentials.v1.AuthProviderCredentialsService/RetrieveCredentials", + request_serializer=auth_provider_credentials_service.RetrieveCredentialsRequest.serialize, + response_deserializer=auth_provider_credentials_service.RetrieveCredentialsResponse.deserialize, + ) + return self._stubs["retrieve_credentials"] + + @property + def finalize_credentials( + self, + ) -> Callable[ + [auth_provider_credentials_service.FinalizeCredentialsRequest], + auth_provider_credentials_service.FinalizeCredentialsResponse, + ]: + r"""Return a callable for the finalize credentials method over gRPC. + + Finalizes the credentials after a successful consent + flow. + + Returns: + Callable[[~.FinalizeCredentialsRequest], + ~.FinalizeCredentialsResponse]: + 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 "finalize_credentials" not in self._stubs: + self._stubs["finalize_credentials"] = self._logged_channel.unary_unary( + "/google.cloud.agentidentitycredentials.v1.AuthProviderCredentialsService/FinalizeCredentials", + request_serializer=auth_provider_credentials_service.FinalizeCredentialsRequest.serialize, + response_deserializer=auth_provider_credentials_service.FinalizeCredentialsResponse.deserialize, + ) + return self._stubs["finalize_credentials"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("AuthProviderCredentialsServiceGrpcTransport",) diff --git a/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/transports/grpc_asyncio.py b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/transports/grpc_asyncio.py new file mode 100644 index 000000000000..4ec0467f2726 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/transports/grpc_asyncio.py @@ -0,0 +1,434 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 inspect +import json +import logging as std_logging +import pickle +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +import google.protobuf.message +import grpc # type: ignore +import proto # type: ignore +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, grpc_helpers_async +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +from grpc.experimental import aio # type: ignore + +from google.cloud.agentidentitycredentials_v1.types import ( + auth_provider_credentials_service, +) + +from .base import DEFAULT_CLIENT_INFO, AuthProviderCredentialsServiceTransport +from .grpc import AuthProviderCredentialsServiceGrpcTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientAIOInterceptor( + grpc.aio.UnaryUnaryClientInterceptor +): # pragma: NO COVER + async def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = f"{type(request).__name__}: {pickle.dumps(request)!r}" + + request_metadata = { + key: value.decode("utf-8") if isinstance(value, bytes) else value + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.cloud.agentidentitycredentials.v1.AuthProviderCredentialsService", + "rpcName": str(client_call_details.method), + "request": grpc_request, + "metadata": grpc_request["metadata"], + }, + ) + response = await continuation(client_call_details, request) + if logging_enabled: # pragma: NO COVER + response_metadata = await response.trailing_metadata() + # Convert gRPC metadata `` to list of tuples + metadata = ( + dict([(k, str(v)) for k, v in response_metadata]) + if response_metadata + else None + ) + result = await response + if isinstance(result, proto.Message): + response_payload = type(result).to_json(result) + elif isinstance(result, google.protobuf.message.Message): + response_payload = MessageToJson(result) + else: + response_payload = f"{type(result).__name__}: {pickle.dumps(result)!r}" + grpc_response = { + "payload": response_payload, + "metadata": metadata, + "status": "OK", + } + _LOGGER.debug( + f"Received response to rpc {client_call_details.method}.", + extra={ + "serviceName": "google.cloud.agentidentitycredentials.v1.AuthProviderCredentialsService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AuthProviderCredentialsServiceGrpcAsyncIOTransport( + AuthProviderCredentialsServiceTransport +): + """gRPC AsyncIO backend transport for AuthProviderCredentialsService. + + Service for managing AuthProvider Credentials. + + 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 = "agentidentitycredentials.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + 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 = "agentidentitycredentials.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[Union[aio.Channel, Callable[..., aio.Channel]]] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'agentidentitycredentials.googleapis.com'). + 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 a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + 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[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + 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 a ``channel`` instance 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 a ``channel`` instance 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. + api_audience (Optional[str]): The intended audience for the API calls + to the service that will be set when using certain 3rd party + authentication flows. Audience is typically a resource identifier. + If not set, the host value will be used as a default. + + 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 isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + self._interceptor = _LoggingClientAIOInterceptor() + self._grpc_channel._unary_unary_interceptors.append(self._interceptor) + self._logged_channel = self._grpc_channel + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) + # Wrap messages. This must be done after self._logged_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 retrieve_credentials( + self, + ) -> Callable[ + [auth_provider_credentials_service.RetrieveCredentialsRequest], + Awaitable[auth_provider_credentials_service.RetrieveCredentialsResponse], + ]: + r"""Return a callable for the retrieve credentials method over gRPC. + + Retrieves authorization credentials for an authprovider, or + indicates what action needs to be taken to obtain credentials. + If the ``token`` field in the response is populated, credential + retrieval was successful. If one of the fields in the ``status`` + oneof is populated, further action is required to obtain + credentials, such as redirecting the user for consent. View + comments on ``RetrieveCredentialsResponse`` for more + information. + + Returns: + Callable[[~.RetrieveCredentialsRequest], + Awaitable[~.RetrieveCredentialsResponse]]: + 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 "retrieve_credentials" not in self._stubs: + self._stubs["retrieve_credentials"] = self._logged_channel.unary_unary( + "/google.cloud.agentidentitycredentials.v1.AuthProviderCredentialsService/RetrieveCredentials", + request_serializer=auth_provider_credentials_service.RetrieveCredentialsRequest.serialize, + response_deserializer=auth_provider_credentials_service.RetrieveCredentialsResponse.deserialize, + ) + return self._stubs["retrieve_credentials"] + + @property + def finalize_credentials( + self, + ) -> Callable[ + [auth_provider_credentials_service.FinalizeCredentialsRequest], + Awaitable[auth_provider_credentials_service.FinalizeCredentialsResponse], + ]: + r"""Return a callable for the finalize credentials method over gRPC. + + Finalizes the credentials after a successful consent + flow. + + Returns: + Callable[[~.FinalizeCredentialsRequest], + Awaitable[~.FinalizeCredentialsResponse]]: + 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 "finalize_credentials" not in self._stubs: + self._stubs["finalize_credentials"] = self._logged_channel.unary_unary( + "/google.cloud.agentidentitycredentials.v1.AuthProviderCredentialsService/FinalizeCredentials", + request_serializer=auth_provider_credentials_service.FinalizeCredentialsRequest.serialize, + response_deserializer=auth_provider_credentials_service.FinalizeCredentialsResponse.deserialize, + ) + return self._stubs["finalize_credentials"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.retrieve_credentials: self._wrap_method( + self.retrieve_credentials, + default_timeout=None, + client_info=client_info, + ), + self.finalize_credentials: self._wrap_method( + self.finalize_credentials, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("AuthProviderCredentialsServiceGrpcAsyncIOTransport",) diff --git a/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/transports/rest.py b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/transports/rest.py new file mode 100644 index 000000000000..7e64c91a6441 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/transports/rest.py @@ -0,0 +1,652 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +import warnings +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +import google.protobuf +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.cloud.agentidentitycredentials_v1.types import ( + auth_provider_credentials_service, +) + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseAuthProviderCredentialsServiceRestTransport + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AuthProviderCredentialsServiceRestInterceptor: + """Interceptor for AuthProviderCredentialsService. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the AuthProviderCredentialsServiceRestTransport. + + .. code-block:: python + class MyCustomAuthProviderCredentialsServiceInterceptor(AuthProviderCredentialsServiceRestInterceptor): + def pre_finalize_credentials(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_finalize_credentials(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_retrieve_credentials(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_retrieve_credentials(self, response): + logging.log(f"Received response: {response}") + return response + + transport = AuthProviderCredentialsServiceRestTransport(interceptor=MyCustomAuthProviderCredentialsServiceInterceptor()) + client = AuthProviderCredentialsServiceClient(transport=transport) + + + """ + + def pre_finalize_credentials( + self, + request: auth_provider_credentials_service.FinalizeCredentialsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + auth_provider_credentials_service.FinalizeCredentialsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for finalize_credentials + + Override in a subclass to manipulate the request or metadata + before they are sent to the AuthProviderCredentialsService server. + """ + return request, metadata + + def post_finalize_credentials( + self, response: auth_provider_credentials_service.FinalizeCredentialsResponse + ) -> auth_provider_credentials_service.FinalizeCredentialsResponse: + """Post-rpc interceptor for finalize_credentials + + DEPRECATED. Please use the `post_finalize_credentials_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the AuthProviderCredentialsService server but before + it is returned to user code. This `post_finalize_credentials` interceptor runs + before the `post_finalize_credentials_with_metadata` interceptor. + """ + return response + + def post_finalize_credentials_with_metadata( + self, + response: auth_provider_credentials_service.FinalizeCredentialsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + auth_provider_credentials_service.FinalizeCredentialsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for finalize_credentials + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the AuthProviderCredentialsService server but before it is returned to user code. + + We recommend only using this `post_finalize_credentials_with_metadata` + interceptor in new development instead of the `post_finalize_credentials` interceptor. + When both interceptors are used, this `post_finalize_credentials_with_metadata` interceptor runs after the + `post_finalize_credentials` interceptor. The (possibly modified) response returned by + `post_finalize_credentials` will be passed to + `post_finalize_credentials_with_metadata`. + """ + return response, metadata + + def pre_retrieve_credentials( + self, + request: auth_provider_credentials_service.RetrieveCredentialsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + auth_provider_credentials_service.RetrieveCredentialsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for retrieve_credentials + + Override in a subclass to manipulate the request or metadata + before they are sent to the AuthProviderCredentialsService server. + """ + return request, metadata + + def post_retrieve_credentials( + self, response: auth_provider_credentials_service.RetrieveCredentialsResponse + ) -> auth_provider_credentials_service.RetrieveCredentialsResponse: + """Post-rpc interceptor for retrieve_credentials + + DEPRECATED. Please use the `post_retrieve_credentials_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the AuthProviderCredentialsService server but before + it is returned to user code. This `post_retrieve_credentials` interceptor runs + before the `post_retrieve_credentials_with_metadata` interceptor. + """ + return response + + def post_retrieve_credentials_with_metadata( + self, + response: auth_provider_credentials_service.RetrieveCredentialsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + auth_provider_credentials_service.RetrieveCredentialsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for retrieve_credentials + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the AuthProviderCredentialsService server but before it is returned to user code. + + We recommend only using this `post_retrieve_credentials_with_metadata` + interceptor in new development instead of the `post_retrieve_credentials` interceptor. + When both interceptors are used, this `post_retrieve_credentials_with_metadata` interceptor runs after the + `post_retrieve_credentials` interceptor. The (possibly modified) response returned by + `post_retrieve_credentials` will be passed to + `post_retrieve_credentials_with_metadata`. + """ + return response, metadata + + +@dataclasses.dataclass +class AuthProviderCredentialsServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: AuthProviderCredentialsServiceRestInterceptor + + +class AuthProviderCredentialsServiceRestTransport( + _BaseAuthProviderCredentialsServiceRestTransport +): + """REST backend synchronous transport for AuthProviderCredentialsService. + + Service for managing AuthProvider Credentials. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "agentidentitycredentials.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[AuthProviderCredentialsServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'agentidentitycredentials.googleapis.com'). + 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]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. This argument will be + removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + interceptor (Optional[AuthProviderCredentialsServiceRestInterceptor]): Interceptor used + to manipulate requests, request metadata, and responses. + api_audience (Optional[str]): The intended audience for the API calls + to the service that will be set when using certain 3rd party + authentication flows. Audience is typically a resource identifier. + If not set, the host value will be used as a default. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = ( + interceptor or AuthProviderCredentialsServiceRestInterceptor() + ) + self._prep_wrapped_messages(client_info) + + class _FinalizeCredentials( + _BaseAuthProviderCredentialsServiceRestTransport._BaseFinalizeCredentials, + AuthProviderCredentialsServiceRestStub, + ): + def __hash__(self): + return hash( + "AuthProviderCredentialsServiceRestTransport.FinalizeCredentials" + ) + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: auth_provider_credentials_service.FinalizeCredentialsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> auth_provider_credentials_service.FinalizeCredentialsResponse: + r"""Call the finalize credentials method over HTTP. + + Args: + request (~.auth_provider_credentials_service.FinalizeCredentialsRequest): + The request object. Request message for + FinalizeCredentials. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.auth_provider_credentials_service.FinalizeCredentialsResponse: + Response message for + FinalizeCredentials. Intentionally empty + + """ + + http_options = _BaseAuthProviderCredentialsServiceRestTransport._BaseFinalizeCredentials._get_http_options() + + request, metadata = self._interceptor.pre_finalize_credentials( + request, metadata + ) + transcoded_request = _BaseAuthProviderCredentialsServiceRestTransport._BaseFinalizeCredentials._get_transcoded_request( + http_options, request + ) + + body = _BaseAuthProviderCredentialsServiceRestTransport._BaseFinalizeCredentials._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseAuthProviderCredentialsServiceRestTransport._BaseFinalizeCredentials._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.agentidentitycredentials_v1.AuthProviderCredentialsServiceClient.FinalizeCredentials", + extra={ + "serviceName": "google.cloud.agentidentitycredentials.v1.AuthProviderCredentialsService", + "rpcName": "FinalizeCredentials", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = AuthProviderCredentialsServiceRestTransport._FinalizeCredentials._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = auth_provider_credentials_service.FinalizeCredentialsResponse() + pb_resp = auth_provider_credentials_service.FinalizeCredentialsResponse.pb( + resp + ) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_finalize_credentials(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_finalize_credentials_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = auth_provider_credentials_service.FinalizeCredentialsResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.agentidentitycredentials_v1.AuthProviderCredentialsServiceClient.finalize_credentials", + extra={ + "serviceName": "google.cloud.agentidentitycredentials.v1.AuthProviderCredentialsService", + "rpcName": "FinalizeCredentials", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _RetrieveCredentials( + _BaseAuthProviderCredentialsServiceRestTransport._BaseRetrieveCredentials, + AuthProviderCredentialsServiceRestStub, + ): + def __hash__(self): + return hash( + "AuthProviderCredentialsServiceRestTransport.RetrieveCredentials" + ) + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: auth_provider_credentials_service.RetrieveCredentialsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> auth_provider_credentials_service.RetrieveCredentialsResponse: + r"""Call the retrieve credentials method over HTTP. + + Args: + request (~.auth_provider_credentials_service.RetrieveCredentialsRequest): + The request object. Request message for + RetrieveCredentials. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.auth_provider_credentials_service.RetrieveCredentialsResponse: + Response message for + RetrieveCredentials. Contains the access + tokens and related artifacts. + + """ + + http_options = _BaseAuthProviderCredentialsServiceRestTransport._BaseRetrieveCredentials._get_http_options() + + request, metadata = self._interceptor.pre_retrieve_credentials( + request, metadata + ) + transcoded_request = _BaseAuthProviderCredentialsServiceRestTransport._BaseRetrieveCredentials._get_transcoded_request( + http_options, request + ) + + body = _BaseAuthProviderCredentialsServiceRestTransport._BaseRetrieveCredentials._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseAuthProviderCredentialsServiceRestTransport._BaseRetrieveCredentials._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.agentidentitycredentials_v1.AuthProviderCredentialsServiceClient.RetrieveCredentials", + extra={ + "serviceName": "google.cloud.agentidentitycredentials.v1.AuthProviderCredentialsService", + "rpcName": "RetrieveCredentials", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = AuthProviderCredentialsServiceRestTransport._RetrieveCredentials._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = auth_provider_credentials_service.RetrieveCredentialsResponse() + pb_resp = auth_provider_credentials_service.RetrieveCredentialsResponse.pb( + resp + ) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_retrieve_credentials(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_retrieve_credentials_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = auth_provider_credentials_service.RetrieveCredentialsResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.agentidentitycredentials_v1.AuthProviderCredentialsServiceClient.retrieve_credentials", + extra={ + "serviceName": "google.cloud.agentidentitycredentials.v1.AuthProviderCredentialsService", + "rpcName": "RetrieveCredentials", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def finalize_credentials( + self, + ) -> Callable[ + [auth_provider_credentials_service.FinalizeCredentialsRequest], + auth_provider_credentials_service.FinalizeCredentialsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._FinalizeCredentials(self._session, self._host, self._interceptor) # type: ignore + + @property + def retrieve_credentials( + self, + ) -> Callable[ + [auth_provider_credentials_service.RetrieveCredentialsRequest], + auth_provider_credentials_service.RetrieveCredentialsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._RetrieveCredentials(self._session, self._host, self._interceptor) # type: ignore + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("AuthProviderCredentialsServiceRestTransport",) diff --git a/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/transports/rest_base.py b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/transports/rest_base.py new file mode 100644 index 000000000000..f46db0c9b13e --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/services/auth_provider_credentials_service/transports/rest_base.py @@ -0,0 +1,213 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import json_format + +from google.cloud.agentidentitycredentials_v1.types import ( + auth_provider_credentials_service, +) + +from .base import DEFAULT_CLIENT_INFO, AuthProviderCredentialsServiceTransport + + +class _BaseAuthProviderCredentialsServiceRestTransport( + AuthProviderCredentialsServiceTransport +): + """Base REST backend transport for AuthProviderCredentialsService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "agentidentitycredentials.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'agentidentitycredentials.googleapis.com'). + credentials (Optional[Any]): 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. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseFinalizeCredentials: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{auth_provider=projects/*/locations/*/authProviders/*}/credentials:finalize", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = ( + auth_provider_credentials_service.FinalizeCredentialsRequest.pb(request) + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAuthProviderCredentialsServiceRestTransport._BaseFinalizeCredentials._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseRetrieveCredentials: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{auth_provider=projects/*/locations/*/authProviders/*}/credentials:retrieve", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = ( + auth_provider_credentials_service.RetrieveCredentialsRequest.pb(request) + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAuthProviderCredentialsServiceRestTransport._BaseRetrieveCredentials._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseAuthProviderCredentialsServiceRestTransport",) diff --git a/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/types/__init__.py b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/types/__init__.py new file mode 100644 index 000000000000..8b5a1f63b3f5 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/types/__init__.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 .auth_provider_credentials_service import ( + FinalizeCredentialsRequest, + FinalizeCredentialsResponse, + RetrieveCredentialsRequest, + RetrieveCredentialsResponse, +) + +__all__ = ( + "FinalizeCredentialsRequest", + "FinalizeCredentialsResponse", + "RetrieveCredentialsRequest", + "RetrieveCredentialsResponse", +) diff --git a/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/types/auth_provider_credentials_service.py b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/types/auth_provider_credentials_service.py new file mode 100644 index 000000000000..9d78ace05276 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/types/auth_provider_credentials_service.py @@ -0,0 +1,283 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.agentidentitycredentials.v1", + manifest={ + "RetrieveCredentialsRequest", + "RetrieveCredentialsResponse", + "FinalizeCredentialsRequest", + "FinalizeCredentialsResponse", + }, +) + + +class RetrieveCredentialsRequest(proto.Message): + r"""Request message for RetrieveCredentials. + + Attributes: + auth_provider (str): + Required. The parent resource name of the AuthProvider. + Format: + ``projects/{project}/locations/{location}/authProviders/{auth_provider}`` + user_id (str): + Required. The identity of the end user. + scopes (MutableSequence[str]): + Optional. The OAuth scopes required for this + access. + continue_uri (str): + Optional. The URI to redirect the user to + after consent is completed. This field is + required for authproviders using the 3-legged + OAuth flow. For other authprovider types, this + field is unused but not rejected. + force_refresh_token (str): + Optional. Input only. Set this field only if + the previous token was expired or invalid. This + value must be the full, previously returned + token string. Will trigger a refresh of the + access token with a stored refresh token, if + possible, or a new consent flow. + """ + + auth_provider: str = proto.Field( + proto.STRING, + number=1, + ) + user_id: str = proto.Field( + proto.STRING, + number=2, + ) + scopes: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + continue_uri: str = proto.Field( + proto.STRING, + number=4, + ) + force_refresh_token: str = proto.Field( + proto.STRING, + number=7, + ) + + +class RetrieveCredentialsResponse(proto.Message): + r"""Response message for RetrieveCredentials. + Contains the access tokens and related artifacts. + + 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: + success (google.cloud.agentidentitycredentials_v1.types.RetrieveCredentialsResponse.Success): + Message indicating credentials were + successfully retrieved. + + This field is a member of `oneof`_ ``result``. + pending (google.cloud.agentidentitycredentials_v1.types.RetrieveCredentialsResponse.Pending): + Message indicating credential retrieval is + pending. + + This field is a member of `oneof`_ ``result``. + uri_consent_required (google.cloud.agentidentitycredentials_v1.types.RetrieveCredentialsResponse.UriConsentRequired): + Message indicating uri based consent is + required. + + This field is a member of `oneof`_ ``result``. + consent_rejected (google.cloud.agentidentitycredentials_v1.types.RetrieveCredentialsResponse.ConsentRejected): + Message indicating consent was rejected. + + This field is a member of `oneof`_ ``result``. + """ + + class Success(proto.Message): + r"""Message indicating successful retrieval of credentials. + + Attributes: + token (str): + The retrieved access token or credential for the end user. + + On MCPTool call, for an invalid token OAuth spec says this + should return 401 or 403, but MCPServers may implement this + differently. If you get any flavor of ``PERMISSION_DENIED``, + retry your original request to RetrieveCredentials with + [force_refresh_token][google.cloud.agentidentitycredentials.v1.RetrieveCredentialsRequest.force_refresh_token] + set to the expired/invalid token string, which will fetch a + new token or initiate a new consent flow. + header (str): + The HTTP header name where the token should + be placed. + expire_time (google.protobuf.timestamp_pb2.Timestamp): + The expiration time of the token. + + This does not guarantee that the token will be + valid until this time, since the token could be + revoked earlier. There could also be clock skew + between the auth provider and the client so it + may expire slightly earlier. If not set, the + token might be permanent or it may be that the + service does not (or cannot) know when it will + expire. + scopes (MutableSequence[str]): + The scopes actually associated with the + retrieved token. + End users may have rejected some requested + scopes, or the third-party authorization servers + can return a different set of scopes than what + was asked for. Callers should verify that all + required scopes for their intended use are + included in this list. + """ + + token: str = proto.Field( + proto.STRING, + number=1, + ) + header: str = proto.Field( + proto.STRING, + number=2, + ) + expire_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + scopes: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=4, + ) + + class UriConsentRequired(proto.Message): + r"""Indicates that the user must visit the provided URI to + consent to delegate permission to the agent to act on their + behalf. The caller can either poll the provided operation, or + await the user ID validation callback + + Attributes: + authorization_uri (str): + Output only. The URL where the user should be + redirected to grant consent. This will always be + present. + consent_nonce (str): + Output only. A one-time, randomly generated + value that validates the entire consent flow is + handled by a single user, avoiding CSRF attacks. + It must be submitted with the + FinalizeCredentials request to complete the + OAuth exchange. This will always be present. + Implemented per + https://www.rfc-editor.org/rfc/rfc6819#section-5.3.5 + """ + + authorization_uri: str = proto.Field( + proto.STRING, + number=1, + ) + consent_nonce: str = proto.Field( + proto.STRING, + number=2, + ) + + class Pending(proto.Message): + r"""Indicates that the credential retrieval is pending. The + caller should retry the RetrieveCredentials request after some + time. + + """ + + class ConsentRejected(proto.Message): + r"""Indicates the user has rejected the permission delegation or + cancelled the request. + + """ + + success: Success = proto.Field( + proto.MESSAGE, + number=1, + oneof="result", + message=Success, + ) + pending: Pending = proto.Field( + proto.MESSAGE, + number=2, + oneof="result", + message=Pending, + ) + uri_consent_required: UriConsentRequired = proto.Field( + proto.MESSAGE, + number=3, + oneof="result", + message=UriConsentRequired, + ) + consent_rejected: ConsentRejected = proto.Field( + proto.MESSAGE, + number=4, + oneof="result", + message=ConsentRejected, + ) + + +class FinalizeCredentialsRequest(proto.Message): + r"""Request message for FinalizeCredentials. + + Attributes: + auth_provider (str): + Required. The resource name of the AuthProvider. Format: + ``projects/{project}/locations/{location}/authProviders/{auth_provider}`` + user_id (str): + Required. The identity of the end user. + user_id_validation_state (bytes): + Required. The encrypted state passed back + from the consent flow. + consent_nonce (str): + Required. The same consent_nonce value that was provided + during redirect in the UriConsentRequired metadata. + """ + + auth_provider: str = proto.Field( + proto.STRING, + number=1, + ) + user_id: str = proto.Field( + proto.STRING, + number=2, + ) + user_id_validation_state: bytes = proto.Field( + proto.BYTES, + number=3, + ) + consent_nonce: str = proto.Field( + proto.STRING, + number=4, + ) + + +class FinalizeCredentialsResponse(proto.Message): + r"""Response message for FinalizeCredentials. Intentionally empty""" + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-agentidentitycredentials/mypy.ini b/packages/google-cloud-agentidentitycredentials/mypy.ini new file mode 100644 index 000000000000..e0e0da2e9e40 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/mypy.ini @@ -0,0 +1,15 @@ +[mypy] +python_version = 3.14 +namespace_packages = True +ignore_missing_imports = False + +# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): +# Dependencies that historically lacks py.typed markers +[mypy-google.iam.*] +ignore_missing_imports = True + +# Helps mypy navigate the 'google' namespace more reliably in 3.10+ +explicit_package_bases = True + +# Performance: reuse results from previous runs to speed up 'nox' +incremental = True diff --git a/packages/google-cloud-agentidentitycredentials/noxfile.py b/packages/google-cloud-agentidentitycredentials/noxfile.py new file mode 100644 index 000000000000..e7d8e25739ad --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/noxfile.py @@ -0,0 +1,639 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 re +import shutil +import warnings +from typing import Dict, List + +import nox + +RUFF_VERSION = "ruff==0.14.14" + +LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] + +# Add samples to the list of directories to format if the directory exists. +if os.path.isdir("samples"): + LINT_PATHS.append("samples") + +ALL_PYTHON = [ + "3.10", + "3.11", + "3.12", + "3.13", + "3.14", +] + +DEFAULT_PYTHON_VERSION = "3.14" + +# TODO(https://github.com/googleapis/gapic-generator-python/issues/2450): +# Switch this to Python 3.15 alpha1 +# https://peps.python.org/pep-0790/ +PREVIEW_PYTHON_VERSION = "3.14" + +CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() + +if (CURRENT_DIRECTORY / "testing").exists(): + LOWER_BOUND_CONSTRAINTS_FILE = ( + CURRENT_DIRECTORY / "testing" / f"constraints-{ALL_PYTHON[0]}.txt" + ) +else: + LOWER_BOUND_CONSTRAINTS_FILE = CURRENT_DIRECTORY / "constraints.txt" +PACKAGE_NAME = "google-cloud-agentidentitycredentials" + +UNIT_TEST_STANDARD_DEPENDENCIES = [ + "mock", + "asyncmock", + "pytest", + "pytest-cov", + "pytest-asyncio", +] +UNIT_TEST_EXTERNAL_DEPENDENCIES: List[str] = [] +UNIT_TEST_LOCAL_DEPENDENCIES: List[str] = [] +UNIT_TEST_DEPENDENCIES: List[str] = [] +UNIT_TEST_EXTRAS: List[str] = [] +UNIT_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} + +SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ALL_PYTHON +SYSTEM_TEST_STANDARD_DEPENDENCIES = [ + "mock", + "pytest", + "google-cloud-testutils", +] +SYSTEM_TEST_EXTERNAL_DEPENDENCIES: List[str] = [] +SYSTEM_TEST_LOCAL_DEPENDENCIES: List[str] = [] +SYSTEM_TEST_DEPENDENCIES: List[str] = [] +SYSTEM_TEST_EXTRAS: List[str] = [] +SYSTEM_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} + +nox.options.sessions = [ + "unit", + "system", + "cover", + "lint", + "lint_setup_py", + "blacken", + "docs", +] + +# Error if a python version is missing +nox.options.error_on_missing_interpreters = True + + +@nox.session(python=ALL_PYTHON) +def mypy(session): + """Run the type checker.""" + # TODO(https://github.com/googleapis/gapic-generator-python/issues/2579): + # use the latest version of mypy + session.install( + "mypy<1.16.0", + "types-requests", + "types-protobuf", + ) + session.install(".") + session.run( + "mypy", + "-p", + "google", + "--check-untyped-defs", + *session.posargs, + ) + + +@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=DEFAULT_PYTHON_VERSION) +def lint(session): + """Run linters. + + Returns a failure if the linters find linting errors or sufficiently + serious code quality issues. + """ + session.install("flake8", RUFF_VERSION) + + # 2. Check formatting + session.run( + "ruff", + "format", + "--check", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", + *LINT_PATHS, + ) + + session.run("flake8", "google", "tests") + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def blacken(session): + """(Deprecated) Legacy session. Please use 'nox -s format'.""" + session.log( + "WARNING: The 'blacken' session is deprecated and will be removed in a future release. Please use 'nox -s format' in the future." + ) + + # Just run the ruff formatter (keeping legacy behavior of only formatting, not sorting imports) + session.install(RUFF_VERSION) + session.run( + "ruff", + "format", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", + *LINT_PATHS, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def format(session): + """ + Run ruff to sort imports and format code. + """ + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports + # check --select I: Enables strict import sorting + # --fix: Applies the changes automatically + session.run( + "ruff", + "check", + "--select", + "I", + "--fix", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", # Standard Black line length + *LINT_PATHS, + ) + + # 3. Run Ruff to format code + session.run( + "ruff", + "format", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", # Standard Black line length + *LINT_PATHS, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def lint_setup_py(session): + """Verify that setup.py is valid (including RST check).""" + session.install("setuptools", "docutils", "pygments") + session.run("python", "setup.py", "check", "--restructuredtext", "--strict") + + +def install_unittest_dependencies(session, *constraints): + standard_deps = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_DEPENDENCIES + session.install(*standard_deps, *constraints) + + if UNIT_TEST_EXTERNAL_DEPENDENCIES: + warnings.warn( + "'unit_test_external_dependencies' is deprecated. Instead, please " + "use 'unit_test_dependencies' or 'unit_test_local_dependencies'.", + DeprecationWarning, + ) + session.install(*UNIT_TEST_EXTERNAL_DEPENDENCIES, *constraints) + + if UNIT_TEST_LOCAL_DEPENDENCIES: + session.install(*UNIT_TEST_LOCAL_DEPENDENCIES, *constraints) + + if UNIT_TEST_EXTRAS_BY_PYTHON: + extras = UNIT_TEST_EXTRAS_BY_PYTHON.get(session.python, []) + elif UNIT_TEST_EXTRAS: + extras = UNIT_TEST_EXTRAS + else: + extras = [] + + if extras: + session.install("-e", f".[{','.join(extras)}]", *constraints) + else: + session.install("-e", ".", *constraints) + + +@nox.session(python=ALL_PYTHON) +@nox.parametrize( + "protobuf_implementation", + ["python", "upb"], +) +def unit(session, protobuf_implementation): + # Install all test dependencies, then install this package in-place. + + constraints_path = str( + CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" + ) + install_unittest_dependencies(session, "-c", constraints_path) + + # Run py.test against the unit tests. + session.run( + "py.test", + "--quiet", + f"--junitxml=unit_{session.python}_sponge_log.xml", + "--cov=google", + "--cov=tests/unit", + "--cov-append", + "--cov-config=.coveragerc", + "--cov-report=", + "--cov-fail-under=0", + os.path.join("tests", "unit"), + *session.posargs, + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) + + +def install_systemtest_dependencies(session, *constraints): + if session.python >= "3.12": + session.install("--pre", "grpcio>=1.75.1") + else: + session.install("--pre", "grpcio<=1.62.2") + + session.install(*SYSTEM_TEST_STANDARD_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_EXTERNAL_DEPENDENCIES: + session.install(*SYSTEM_TEST_EXTERNAL_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_LOCAL_DEPENDENCIES: + session.install("-e", *SYSTEM_TEST_LOCAL_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_DEPENDENCIES: + session.install("-e", *SYSTEM_TEST_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_EXTRAS_BY_PYTHON: + extras = SYSTEM_TEST_EXTRAS_BY_PYTHON.get(session.python, []) + elif SYSTEM_TEST_EXTRAS: + extras = SYSTEM_TEST_EXTRAS + else: + extras = [] + + if extras: + session.install("-e", f".[{','.join(extras)}]", *constraints) + else: + session.install("-e", ".", *constraints) + + +@nox.session(python=SYSTEM_TEST_PYTHON_VERSIONS) +def system(session): + """Run the system test suite.""" + constraints_path = str( + CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" + ) + system_test_path = os.path.join("tests", "system.py") + system_test_folder_path = os.path.join("tests", "system") + + # Check the value of `RUN_SYSTEM_TESTS` env var. It defaults to true. + if os.environ.get("RUN_SYSTEM_TESTS", "true") == "false": + session.skip("RUN_SYSTEM_TESTS is set to false, skipping") + # Install pyopenssl for mTLS testing. + if os.environ.get("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true": + session.install("pyopenssl") + + system_test_exists = os.path.exists(system_test_path) + system_test_folder_exists = os.path.exists(system_test_folder_path) + # Sanity check: only run tests if found. + if not system_test_exists and not system_test_folder_exists: + session.skip("System tests were not found") + + install_systemtest_dependencies(session, "-c", constraints_path) + + # Run py.test against the system tests. + if system_test_exists: + session.run( + "py.test", + "--quiet", + f"--junitxml=system_{session.python}_sponge_log.xml", + system_test_path, + *session.posargs, + ) + if system_test_folder_exists: + session.run( + "py.test", + "--quiet", + f"--junitxml=system_{session.python}_sponge_log.xml", + system_test_folder_path, + *session.posargs, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +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.10") +def docs(session): + """Build the docs for this library.""" + + session.install("-e", ".") + session.install( + # We need to pin to specific versions of the `sphinxcontrib-*` packages + # which still support sphinx 4.x. + # See https://github.com/googleapis/sphinx-docfx-yaml/issues/344 + # and https://github.com/googleapis/sphinx-docfx-yaml/issues/345. + "sphinxcontrib-applehelp==1.0.4", + "sphinxcontrib-devhelp==1.0.2", + "sphinxcontrib-htmlhelp==2.0.1", + "sphinxcontrib-qthelp==1.0.3", + "sphinxcontrib-serializinghtml==1.1.5", + "sphinx==4.5.0", + "alabaster", + "recommonmark", + ) + + shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) + session.run( + "sphinx-build", + "-T", # show full traceback on exception + "-N", # no colors + "-b", + "html", # builder + "-d", + os.path.join("docs", "_build", "doctrees", ""), # cache directory + # paths to build: + os.path.join("docs", ""), + os.path.join("docs", "_build", "html", ""), + ) + + +@nox.session(python="3.10") +def docfx(session): + """Build the docfx yaml files for this library.""" + + session.install("-e", ".") + session.install( + # We need to pin to specific versions of the `sphinxcontrib-*` packages + # which still support sphinx 4.x. + # See https://github.com/googleapis/sphinx-docfx-yaml/issues/344 + # and https://github.com/googleapis/sphinx-docfx-yaml/issues/345. + "sphinxcontrib-applehelp==1.0.4", + "sphinxcontrib-devhelp==1.0.2", + "sphinxcontrib-htmlhelp==2.0.1", + "sphinxcontrib-qthelp==1.0.3", + "sphinxcontrib-serializinghtml==1.1.5", + "gcp-sphinx-docfx-yaml", + "alabaster", + "recommonmark", + ) + + shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) + session.run( + "sphinx-build", + "-T", # show full traceback on exception + "-N", # no colors + "-D", + ( + "extensions=sphinx.ext.autodoc," + "sphinx.ext.autosummary," + "docfx_yaml.extension," + "sphinx.ext.intersphinx," + "sphinx.ext.coverage," + "sphinx.ext.napoleon," + "sphinx.ext.todo," + "sphinx.ext.viewcode," + "recommonmark" + ), + "-b", + "html", + "-d", + os.path.join("docs", "_build", "doctrees", ""), + os.path.join("docs", ""), + os.path.join("docs", "_build", "html", ""), + ) + + +@nox.session(python=PREVIEW_PYTHON_VERSION) +@nox.parametrize( + "protobuf_implementation", + ["python", "upb"], +) +def prerelease_deps(session, protobuf_implementation): + """ + Run all tests with pre-release versions of dependencies installed + rather than the standard non pre-release versions. + Pre-release versions can be installed using + `pip install --pre `. + """ + + # Install all dependencies + session.install("-e", ".") + + # Install dependencies for the unit test environment + unit_deps_all = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_EXTERNAL_DEPENDENCIES + session.install(*unit_deps_all) + + # Because we test minimum dependency versions on the minimum Python + # version, the first version we test with in the unit tests sessions has a + # constraints file containing all dependencies and extras. + with open( + CURRENT_DIRECTORY / "testing" / f"constraints-{ALL_PYTHON[0]}.txt", + encoding="utf-8", + ) as constraints_file: + constraints_text = constraints_file.read() + + # Ignore leading whitespace and comment lines. + constraints_deps = [ + match.group(1) + for match in re.finditer( + r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE + ) + ] + + # Install dependencies specified in `testing/constraints-X.txt`. + session.install(*constraints_deps) + + # Note: If a dependency is added to the `prerel_deps` list, + # the `core_dependencies_from_source` list in the `core_deps_from_source` + # nox session should also be updated. + prerel_deps = [ + "googleapis-common-protos", + "google-api-core", + "google-auth", + "grpc-google-iam-v1", + "grpcio>=1.75.1" if session.python >= "3.12" else "grpcio<=1.62.2", + "grpcio-status", + "protobuf", + "proto-plus", + ] + + deps_dir = CURRENT_DIRECTORY.parent + while deps_dir.name != "packages" and deps_dir.parent != deps_dir: + deps_dir = deps_dir.parent + + # Extract the base package name, safely ignoring version bounds and spaces + # (e.g., "grpcio>=1.75.1" becomes "grpcio") + parsed_deps = { + dep: re.match(r"^([a-zA-Z0-9_-]+)", dep).group(1) for dep in prerel_deps + } + + # Dynamically sort local packages vs PyPI dependencies + local_paths = [] + pypi_deps = [] + + for dep, pkg_name in parsed_deps.items(): + if (deps_dir / pkg_name).exists(): + local_paths.append(str(deps_dir / pkg_name)) + else: + pypi_deps.append(dep) + + # Batch pip installations to avoid sequential overhead + if local_paths: + session.install(*local_paths, "--no-deps", "--ignore-installed") + if pypi_deps: + session.install(*pypi_deps, "--pre", "--no-deps", "--ignore-installed") + + # TODO(https://github.com/grpc/grpc/issues/38965): Add `grpcio-status`` + # to the dictionary below once this bug is fixed. + # TODO(https://github.com/googleapis/google-cloud-python/issues/13643): Add + # `googleapis-common-protos` and `grpc-google-iam-v1` to the dictionary below + # once this bug is fixed. + package_namespaces = { + "google-api-core": "google.api_core", + "google-auth": "google.auth", + "grpcio": "grpc", + "protobuf": "google.protobuf", + "proto-plus": "proto", + } + + # Reuse the parsed names for logging and version verification + for dep, pkg_name in parsed_deps.items(): + print(f"Installed {dep}") + version_namespace = package_namespaces.get(pkg_name) + + if version_namespace: + session.run( + "python", + "-c", + f"import {version_namespace}; print({version_namespace}.__version__)", + ) + + session.run( + "py.test", + "tests/unit", + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +@nox.parametrize( + "protobuf_implementation", + ["python", "upb"], +) +def core_deps_from_source(session, protobuf_implementation): + """Run all tests with core dependencies installed from source + rather than pulling the dependencies from PyPI. + """ + + # Install all dependencies + session.install("-e", ".") + + # Install dependencies for the unit test environment + unit_deps_all = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_EXTERNAL_DEPENDENCIES + session.install(*unit_deps_all) + + # Because we test minimum dependency versions on the minimum Python + # version, the first version we test with in the unit tests sessions has a + # constraints file containing all dependencies and extras. + with open( + CURRENT_DIRECTORY / "testing" / f"constraints-{ALL_PYTHON[0]}.txt", + encoding="utf-8", + ) as constraints_file: + constraints_text = constraints_file.read() + + # Ignore leading whitespace and comment lines. + constraints_deps = [ + match.group(1) + for match in re.finditer( + r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE + ) + ] + + # Install dependencies specified in `testing/constraints-X.txt`. + session.install(*constraints_deps) + + # TODO(https://github.com/googleapis/gapic-generator-python/issues/2358): `grpcio` and + # `grpcio-status` should be added to the list below so that they are installed from source, + # rather than PyPI. + # TODO(https://github.com/googleapis/gapic-generator-python/issues/2357): `protobuf` should be + # added to the list below so that it is installed from source, rather than PyPI + # Note: If a dependency is added to the `core_dependencies_from_source` list, + # the `prerel_deps` list in the `prerelease_deps` nox session should also be updated. + core_dependencies_from_source = [ + "googleapis-common-protos", + "google-api-core", + "google-auth", + "grpc-google-iam-v1", + "proto-plus", + ] + + deps_dir = CURRENT_DIRECTORY.parent + while deps_dir.name != "packages" and deps_dir.parent != deps_dir: + deps_dir = deps_dir.parent + + # Batch the pip installation to avoid sequential overhead + dep_paths = [str(deps_dir / dep) for dep in core_dependencies_from_source] + + session.install(*dep_paths, "--no-deps", "--ignore-installed") + print( + f"Installed {', '.join(core_dependencies_from_source)} locally from {deps_dir}" + ) + + session.run( + "py.test", + "tests/unit", + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) diff --git a/packages/google-cloud-agentidentitycredentials/samples/generated_samples/agentidentitycredentials_v1_generated_auth_provider_credentials_service_finalize_credentials_async.py b/packages/google-cloud-agentidentitycredentials/samples/generated_samples/agentidentitycredentials_v1_generated_auth_provider_credentials_service_finalize_credentials_async.py new file mode 100644 index 000000000000..5f0b178927ef --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/samples/generated_samples/agentidentitycredentials_v1_generated_auth_provider_credentials_service_finalize_credentials_async.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for FinalizeCredentials +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-agentidentitycredentials + + +# [START agentidentitycredentials_v1_generated_AuthProviderCredentialsService_FinalizeCredentials_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import agentidentitycredentials_v1 + + +async def sample_finalize_credentials(): + # Create a client + client = agentidentitycredentials_v1.AuthProviderCredentialsServiceAsyncClient() + + # Initialize request argument(s) + request = agentidentitycredentials_v1.FinalizeCredentialsRequest( + auth_provider="auth_provider_value", + user_id="user_id_value", + user_id_validation_state=b"user_id_validation_state_blob", + consent_nonce="consent_nonce_value", + ) + + # Make the request + response = await client.finalize_credentials(request=request) + + # Handle the response + print(response) + + +# [END agentidentitycredentials_v1_generated_AuthProviderCredentialsService_FinalizeCredentials_async] diff --git a/packages/google-cloud-agentidentitycredentials/samples/generated_samples/agentidentitycredentials_v1_generated_auth_provider_credentials_service_finalize_credentials_sync.py b/packages/google-cloud-agentidentitycredentials/samples/generated_samples/agentidentitycredentials_v1_generated_auth_provider_credentials_service_finalize_credentials_sync.py new file mode 100644 index 000000000000..0078e1731033 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/samples/generated_samples/agentidentitycredentials_v1_generated_auth_provider_credentials_service_finalize_credentials_sync.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for FinalizeCredentials +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-agentidentitycredentials + + +# [START agentidentitycredentials_v1_generated_AuthProviderCredentialsService_FinalizeCredentials_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import agentidentitycredentials_v1 + + +def sample_finalize_credentials(): + # Create a client + client = agentidentitycredentials_v1.AuthProviderCredentialsServiceClient() + + # Initialize request argument(s) + request = agentidentitycredentials_v1.FinalizeCredentialsRequest( + auth_provider="auth_provider_value", + user_id="user_id_value", + user_id_validation_state=b"user_id_validation_state_blob", + consent_nonce="consent_nonce_value", + ) + + # Make the request + response = client.finalize_credentials(request=request) + + # Handle the response + print(response) + + +# [END agentidentitycredentials_v1_generated_AuthProviderCredentialsService_FinalizeCredentials_sync] diff --git a/packages/google-cloud-agentidentitycredentials/samples/generated_samples/agentidentitycredentials_v1_generated_auth_provider_credentials_service_retrieve_credentials_async.py b/packages/google-cloud-agentidentitycredentials/samples/generated_samples/agentidentitycredentials_v1_generated_auth_provider_credentials_service_retrieve_credentials_async.py new file mode 100644 index 000000000000..90a00d0b3819 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/samples/generated_samples/agentidentitycredentials_v1_generated_auth_provider_credentials_service_retrieve_credentials_async.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for RetrieveCredentials +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-agentidentitycredentials + + +# [START agentidentitycredentials_v1_generated_AuthProviderCredentialsService_RetrieveCredentials_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import agentidentitycredentials_v1 + + +async def sample_retrieve_credentials(): + # Create a client + client = agentidentitycredentials_v1.AuthProviderCredentialsServiceAsyncClient() + + # Initialize request argument(s) + request = agentidentitycredentials_v1.RetrieveCredentialsRequest( + auth_provider="auth_provider_value", + user_id="user_id_value", + ) + + # Make the request + response = await client.retrieve_credentials(request=request) + + # Handle the response + print(response) + + +# [END agentidentitycredentials_v1_generated_AuthProviderCredentialsService_RetrieveCredentials_async] diff --git a/packages/google-cloud-agentidentitycredentials/samples/generated_samples/agentidentitycredentials_v1_generated_auth_provider_credentials_service_retrieve_credentials_sync.py b/packages/google-cloud-agentidentitycredentials/samples/generated_samples/agentidentitycredentials_v1_generated_auth_provider_credentials_service_retrieve_credentials_sync.py new file mode 100644 index 000000000000..79485a23cca4 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/samples/generated_samples/agentidentitycredentials_v1_generated_auth_provider_credentials_service_retrieve_credentials_sync.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for RetrieveCredentials +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-agentidentitycredentials + + +# [START agentidentitycredentials_v1_generated_AuthProviderCredentialsService_RetrieveCredentials_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import agentidentitycredentials_v1 + + +def sample_retrieve_credentials(): + # Create a client + client = agentidentitycredentials_v1.AuthProviderCredentialsServiceClient() + + # Initialize request argument(s) + request = agentidentitycredentials_v1.RetrieveCredentialsRequest( + auth_provider="auth_provider_value", + user_id="user_id_value", + ) + + # Make the request + response = client.retrieve_credentials(request=request) + + # Handle the response + print(response) + + +# [END agentidentitycredentials_v1_generated_AuthProviderCredentialsService_RetrieveCredentials_sync] diff --git a/packages/google-cloud-agentidentitycredentials/samples/generated_samples/snippet_metadata_google.cloud.agentidentitycredentials.v1.json b/packages/google-cloud-agentidentitycredentials/samples/generated_samples/snippet_metadata_google.cloud.agentidentitycredentials.v1.json new file mode 100644 index 000000000000..11df3850aef6 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/samples/generated_samples/snippet_metadata_google.cloud.agentidentitycredentials.v1.json @@ -0,0 +1,337 @@ +{ + "clientLibrary": { + "apis": [ + { + "id": "google.cloud.agentidentitycredentials.v1", + "version": "v1" + } + ], + "language": "PYTHON", + "name": "google-cloud-agentidentitycredentials", + "version": "0.0.0" + }, + "snippets": [ + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.agentidentitycredentials_v1.AuthProviderCredentialsServiceAsyncClient", + "shortName": "AuthProviderCredentialsServiceAsyncClient" + }, + "fullName": "google.cloud.agentidentitycredentials_v1.AuthProviderCredentialsServiceAsyncClient.finalize_credentials", + "method": { + "fullName": "google.cloud.agentidentitycredentials.v1.AuthProviderCredentialsService.FinalizeCredentials", + "service": { + "fullName": "google.cloud.agentidentitycredentials.v1.AuthProviderCredentialsService", + "shortName": "AuthProviderCredentialsService" + }, + "shortName": "FinalizeCredentials" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.agentidentitycredentials_v1.types.FinalizeCredentialsRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.agentidentitycredentials_v1.types.FinalizeCredentialsResponse", + "shortName": "finalize_credentials" + }, + "description": "Sample for FinalizeCredentials", + "file": "agentidentitycredentials_v1_generated_auth_provider_credentials_service_finalize_credentials_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "agentidentitycredentials_v1_generated_AuthProviderCredentialsService_FinalizeCredentials_async", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "agentidentitycredentials_v1_generated_auth_provider_credentials_service_finalize_credentials_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.agentidentitycredentials_v1.AuthProviderCredentialsServiceClient", + "shortName": "AuthProviderCredentialsServiceClient" + }, + "fullName": "google.cloud.agentidentitycredentials_v1.AuthProviderCredentialsServiceClient.finalize_credentials", + "method": { + "fullName": "google.cloud.agentidentitycredentials.v1.AuthProviderCredentialsService.FinalizeCredentials", + "service": { + "fullName": "google.cloud.agentidentitycredentials.v1.AuthProviderCredentialsService", + "shortName": "AuthProviderCredentialsService" + }, + "shortName": "FinalizeCredentials" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.agentidentitycredentials_v1.types.FinalizeCredentialsRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.agentidentitycredentials_v1.types.FinalizeCredentialsResponse", + "shortName": "finalize_credentials" + }, + "description": "Sample for FinalizeCredentials", + "file": "agentidentitycredentials_v1_generated_auth_provider_credentials_service_finalize_credentials_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "agentidentitycredentials_v1_generated_AuthProviderCredentialsService_FinalizeCredentials_sync", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "agentidentitycredentials_v1_generated_auth_provider_credentials_service_finalize_credentials_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.agentidentitycredentials_v1.AuthProviderCredentialsServiceAsyncClient", + "shortName": "AuthProviderCredentialsServiceAsyncClient" + }, + "fullName": "google.cloud.agentidentitycredentials_v1.AuthProviderCredentialsServiceAsyncClient.retrieve_credentials", + "method": { + "fullName": "google.cloud.agentidentitycredentials.v1.AuthProviderCredentialsService.RetrieveCredentials", + "service": { + "fullName": "google.cloud.agentidentitycredentials.v1.AuthProviderCredentialsService", + "shortName": "AuthProviderCredentialsService" + }, + "shortName": "RetrieveCredentials" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.agentidentitycredentials_v1.types.RetrieveCredentialsRequest" + }, + { + "name": "auth_provider", + "type": "str" + }, + { + "name": "user_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.agentidentitycredentials_v1.types.RetrieveCredentialsResponse", + "shortName": "retrieve_credentials" + }, + "description": "Sample for RetrieveCredentials", + "file": "agentidentitycredentials_v1_generated_auth_provider_credentials_service_retrieve_credentials_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "agentidentitycredentials_v1_generated_AuthProviderCredentialsService_RetrieveCredentials_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "agentidentitycredentials_v1_generated_auth_provider_credentials_service_retrieve_credentials_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.agentidentitycredentials_v1.AuthProviderCredentialsServiceClient", + "shortName": "AuthProviderCredentialsServiceClient" + }, + "fullName": "google.cloud.agentidentitycredentials_v1.AuthProviderCredentialsServiceClient.retrieve_credentials", + "method": { + "fullName": "google.cloud.agentidentitycredentials.v1.AuthProviderCredentialsService.RetrieveCredentials", + "service": { + "fullName": "google.cloud.agentidentitycredentials.v1.AuthProviderCredentialsService", + "shortName": "AuthProviderCredentialsService" + }, + "shortName": "RetrieveCredentials" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.agentidentitycredentials_v1.types.RetrieveCredentialsRequest" + }, + { + "name": "auth_provider", + "type": "str" + }, + { + "name": "user_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.agentidentitycredentials_v1.types.RetrieveCredentialsResponse", + "shortName": "retrieve_credentials" + }, + "description": "Sample for RetrieveCredentials", + "file": "agentidentitycredentials_v1_generated_auth_provider_credentials_service_retrieve_credentials_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "agentidentitycredentials_v1_generated_AuthProviderCredentialsService_RetrieveCredentials_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "agentidentitycredentials_v1_generated_auth_provider_credentials_service_retrieve_credentials_sync.py" + } + ] +} diff --git a/packages/google-cloud-agentidentitycredentials/setup.py b/packages/google-cloud-agentidentitycredentials/setup.py new file mode 100644 index 000000000000..d664811f1e93 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/setup.py @@ -0,0 +1,99 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 re + +import setuptools # type: ignore + +package_root = os.path.abspath(os.path.dirname(__file__)) + +name = "google-cloud-agentidentitycredentials" + + +description = "Google Cloud Agentidentitycredentials API client library" + +version = None + +with open( + os.path.join(package_root, "google/cloud/agentidentitycredentials/gapic_version.py") +) as fp: + version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + assert len(version_candidates) == 1 + version = version_candidates[0] + +if version[0] == "0": + release_status = "Development Status :: 4 - Beta" +else: + release_status = "Development Status :: 5 - Production/Stable" + +dependencies = [ + "google-api-core[grpc] >= 2.17.1, <3.0.0", + # Exclude incompatible versions of `google-auth` + # See https://github.com/googleapis/google-cloud-python/issues/12364 + "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", + "grpcio >= 1.59.0, < 2.0.0", + "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", + "proto-plus >= 1.22.3, <2.0.0", + "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", + "protobuf >= 4.25.8, < 8.0.0", +] +extras = {} +url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-agentidentitycredentials" + +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() + +packages = [ + package + for package in setuptools.find_namespace_packages() + if package.startswith("google") +] + +setuptools.setup( + name=name, + version=version, + description=description, + long_description=readme, + author="Google LLC", + author_email="googleapis-packages@google.com", + license="Apache-2.0", + url=url, + classifiers=[ + release_status, + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", + "Operating System :: OS Independent", + "Topic :: Internet", + ], + platforms="Posix; MacOS X; Windows", + packages=packages, + python_requires=">=3.10", + install_requires=dependencies, + extras_require=extras, + include_package_data=True, + zip_safe=False, +) diff --git a/packages/google-cloud-agentidentitycredentials/testing/constraints-3.10.txt b/packages/google-cloud-agentidentitycredentials/testing/constraints-3.10.txt new file mode 100644 index 000000000000..7be9c36933fc --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/testing/constraints-3.10.txt @@ -0,0 +1,11 @@ +# This constraints file is used to check that lower bounds +# are correct in setup.py +# List all library dependencies and extras in this file, +# pinning their versions to their lower bounds. +# For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", +# then this file should have google-cloud-foo==1.14.0 +google-api-core==2.17.1 +google-auth==2.14.1 +grpcio==1.59.0 +proto-plus==1.22.3 +protobuf==4.25.8 diff --git a/packages/google-cloud-agentidentitycredentials/testing/constraints-3.11.txt b/packages/google-cloud-agentidentitycredentials/testing/constraints-3.11.txt new file mode 100644 index 000000000000..7599dea499ed --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/testing/constraints-3.11.txt @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +google-auth +grpcio +proto-plus +protobuf +# cryptography is a direct dependency of google-auth +cryptography diff --git a/packages/google-cloud-agentidentitycredentials/testing/constraints-3.12.txt b/packages/google-cloud-agentidentitycredentials/testing/constraints-3.12.txt new file mode 100644 index 000000000000..7599dea499ed --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/testing/constraints-3.12.txt @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +google-auth +grpcio +proto-plus +protobuf +# cryptography is a direct dependency of google-auth +cryptography diff --git a/packages/google-cloud-agentidentitycredentials/testing/constraints-3.13.txt b/packages/google-cloud-agentidentitycredentials/testing/constraints-3.13.txt new file mode 100644 index 000000000000..1e93c60e50aa --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/testing/constraints-3.13.txt @@ -0,0 +1,12 @@ +# We use the constraints file for the latest Python version +# (currently this file) to check that the latest +# major versions of dependencies are supported in setup.py. +# List all library dependencies and extras in this file. +# Require the latest major version be installed for each dependency. +# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", +# Then this file should have google-cloud-foo>=1 +google-api-core>=2 +google-auth>=2 +grpcio>=1 +proto-plus>=1 +protobuf>=6 diff --git a/packages/google-cloud-agentidentitycredentials/testing/constraints-3.14.txt b/packages/google-cloud-agentidentitycredentials/testing/constraints-3.14.txt new file mode 100644 index 000000000000..1e93c60e50aa --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/testing/constraints-3.14.txt @@ -0,0 +1,12 @@ +# We use the constraints file for the latest Python version +# (currently this file) to check that the latest +# major versions of dependencies are supported in setup.py. +# List all library dependencies and extras in this file. +# Require the latest major version be installed for each dependency. +# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", +# Then this file should have google-cloud-foo>=1 +google-api-core>=2 +google-auth>=2 +grpcio>=1 +proto-plus>=1 +protobuf>=6 diff --git a/packages/google-cloud-agentidentitycredentials/tests/__init__.py b/packages/google-cloud-agentidentitycredentials/tests/__init__.py new file mode 100644 index 000000000000..32b36c5c4fe0 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/tests/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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/packages/google-cloud-agentidentitycredentials/tests/unit/__init__.py b/packages/google-cloud-agentidentitycredentials/tests/unit/__init__.py new file mode 100644 index 000000000000..32b36c5c4fe0 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/tests/unit/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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/packages/google-cloud-agentidentitycredentials/tests/unit/gapic/__init__.py b/packages/google-cloud-agentidentitycredentials/tests/unit/gapic/__init__.py new file mode 100644 index 000000000000..32b36c5c4fe0 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/tests/unit/gapic/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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/packages/google-cloud-agentidentitycredentials/tests/unit/gapic/agentidentitycredentials_v1/__init__.py b/packages/google-cloud-agentidentitycredentials/tests/unit/gapic/agentidentitycredentials_v1/__init__.py new file mode 100644 index 000000000000..32b36c5c4fe0 --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/tests/unit/gapic/agentidentitycredentials_v1/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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/packages/google-cloud-agentidentitycredentials/tests/unit/gapic/agentidentitycredentials_v1/test_auth_provider_credentials_service.py b/packages/google-cloud-agentidentitycredentials/tests/unit/gapic/agentidentitycredentials_v1/test_auth_provider_credentials_service.py new file mode 100644 index 000000000000..21ca36a862ce --- /dev/null +++ b/packages/google-cloud-agentidentitycredentials/tests/unit/gapic/agentidentitycredentials_v1/test_auth_provider_credentials_service.py @@ -0,0 +1,3710 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 asyncio +import json +import math +import os +from collections.abc import AsyncIterable, Iterable, Mapping, Sequence +from unittest import mock +from unittest.mock import AsyncMock + +import grpc +import pytest +from google.api_core import api_core_version +from google.protobuf import json_format +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +import google.auth +from google.api_core import ( + client_options, + gapic_v1, + grpc_helpers, + grpc_helpers_async, + path_template, +) +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.oauth2 import service_account + +from google.cloud.agentidentitycredentials_v1.services.auth_provider_credentials_service import ( + AuthProviderCredentialsServiceAsyncClient, + AuthProviderCredentialsServiceClient, + transports, +) +from google.cloud.agentidentitycredentials_v1.types import ( + auth_provider_credentials_service, +) + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + +# 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 + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +@pytest.fixture(autouse=True) +def set_event_loop(): + try: + asyncio.get_running_loop() + yield + except RuntimeError: + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + try: + yield + finally: + loop.close() + asyncio.set_event_loop(None) + + +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" + custom_endpoint = ".custom" + + assert AuthProviderCredentialsServiceClient._get_default_mtls_endpoint(None) is None + assert ( + AuthProviderCredentialsServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + AuthProviderCredentialsServiceClient._get_default_mtls_endpoint( + api_mtls_endpoint + ) + == api_mtls_endpoint + ) + assert ( + AuthProviderCredentialsServiceClient._get_default_mtls_endpoint( + sandbox_endpoint + ) + == sandbox_mtls_endpoint + ) + assert ( + AuthProviderCredentialsServiceClient._get_default_mtls_endpoint( + sandbox_mtls_endpoint + ) + == sandbox_mtls_endpoint + ) + assert ( + AuthProviderCredentialsServiceClient._get_default_mtls_endpoint(non_googleapi) + == non_googleapi + ) + assert ( + AuthProviderCredentialsServiceClient._get_default_mtls_endpoint(custom_endpoint) + == custom_endpoint + ) + + +def test__read_environment_variables(): + assert AuthProviderCredentialsServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert AuthProviderCredentialsServiceClient._read_environment_variables() == ( + True, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert AuthProviderCredentialsServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with pytest.raises(ValueError) as excinfo: + AuthProviderCredentialsServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + else: + assert ( + AuthProviderCredentialsServiceClient._read_environment_variables() + == ( + False, + "auto", + None, + ) + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert AuthProviderCredentialsServiceClient._read_environment_variables() == ( + False, + "never", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert AuthProviderCredentialsServiceClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert AuthProviderCredentialsServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + AuthProviderCredentialsServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert AuthProviderCredentialsServiceClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test_use_client_cert_effective(): + # Test case 1: Test when `should_use_client_cert` returns True. + # We mock the `should_use_client_cert` function to simulate a scenario where + # the google-auth library supports automatic mTLS and determines that a + # client certificate should be used. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch( + "google.auth.transport.mtls.should_use_client_cert", return_value=True + ): + assert ( + AuthProviderCredentialsServiceClient._use_client_cert_effective() + is True + ) + + # Test case 2: Test when `should_use_client_cert` returns False. + # We mock the `should_use_client_cert` function to simulate a scenario where + # the google-auth library supports automatic mTLS and determines that a + # client certificate should NOT be used. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch( + "google.auth.transport.mtls.should_use_client_cert", return_value=False + ): + assert ( + AuthProviderCredentialsServiceClient._use_client_cert_effective() + is False + ) + + # Test case 3: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "true". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert ( + AuthProviderCredentialsServiceClient._use_client_cert_effective() + is True + ) + + # Test case 4: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "false". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"} + ): + assert ( + AuthProviderCredentialsServiceClient._use_client_cert_effective() + is False + ) + + # Test case 5: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "True". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "True"}): + assert ( + AuthProviderCredentialsServiceClient._use_client_cert_effective() + is True + ) + + # Test case 6: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "False". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "False"} + ): + assert ( + AuthProviderCredentialsServiceClient._use_client_cert_effective() + is False + ) + + # Test case 7: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "TRUE". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "TRUE"}): + assert ( + AuthProviderCredentialsServiceClient._use_client_cert_effective() + is True + ) + + # Test case 8: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "FALSE". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "FALSE"} + ): + assert ( + AuthProviderCredentialsServiceClient._use_client_cert_effective() + is False + ) + + # Test case 9: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not set. + # In this case, the method should return False, which is the default value. + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, clear=True): + assert ( + AuthProviderCredentialsServiceClient._use_client_cert_effective() + is False + ) + + # Test case 10: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value. + # The method should raise a ValueError as the environment variable must be either + # "true" or "false". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"} + ): + with pytest.raises(ValueError): + AuthProviderCredentialsServiceClient._use_client_cert_effective() + + # Test case 11: Test when `should_use_client_cert` is available and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value. + # The method should return False as the environment variable is set to an invalid value. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"} + ): + assert ( + AuthProviderCredentialsServiceClient._use_client_cert_effective() + is False + ) + + # Test case 12: Test when `should_use_client_cert` is available and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is unset. Also, + # the GOOGLE_API_CONFIG environment variable is unset. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": ""}): + with mock.patch.dict(os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": ""}): + assert ( + AuthProviderCredentialsServiceClient._use_client_cert_effective() + is False + ) + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert ( + AuthProviderCredentialsServiceClient._get_client_cert_source(None, False) + is None + ) + assert ( + AuthProviderCredentialsServiceClient._get_client_cert_source( + mock_provided_cert_source, False + ) + is None + ) + assert ( + AuthProviderCredentialsServiceClient._get_client_cert_source( + mock_provided_cert_source, True + ) + == mock_provided_cert_source + ) + + 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_default_cert_source, + ): + assert ( + AuthProviderCredentialsServiceClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + AuthProviderCredentialsServiceClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + AuthProviderCredentialsServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(AuthProviderCredentialsServiceClient), +) +@mock.patch.object( + AuthProviderCredentialsServiceAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(AuthProviderCredentialsServiceAsyncClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = AuthProviderCredentialsServiceClient._DEFAULT_UNIVERSE + default_endpoint = ( + AuthProviderCredentialsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + ) + mock_universe = "bar.com" + mock_endpoint = ( + AuthProviderCredentialsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + ) + + assert ( + AuthProviderCredentialsServiceClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + AuthProviderCredentialsServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == AuthProviderCredentialsServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + AuthProviderCredentialsServiceClient._get_api_endpoint( + None, None, default_universe, "auto" + ) + == default_endpoint + ) + assert ( + AuthProviderCredentialsServiceClient._get_api_endpoint( + None, None, default_universe, "always" + ) + == AuthProviderCredentialsServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + AuthProviderCredentialsServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == AuthProviderCredentialsServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + AuthProviderCredentialsServiceClient._get_api_endpoint( + None, None, mock_universe, "never" + ) + == mock_endpoint + ) + assert ( + AuthProviderCredentialsServiceClient._get_api_endpoint( + None, None, default_universe, "never" + ) + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + AuthProviderCredentialsServiceClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + AuthProviderCredentialsServiceClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + AuthProviderCredentialsServiceClient._get_universe_domain( + None, universe_domain_env + ) + == universe_domain_env + ) + assert ( + AuthProviderCredentialsServiceClient._get_universe_domain(None, None) + == AuthProviderCredentialsServiceClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + AuthProviderCredentialsServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = AuthProviderCredentialsServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = AuthProviderCredentialsServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (AuthProviderCredentialsServiceClient, "grpc"), + (AuthProviderCredentialsServiceAsyncClient, "grpc_asyncio"), + (AuthProviderCredentialsServiceClient, "rest"), + ], +) +def test_auth_provider_credentials_service_client_from_service_account_info( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "agentidentitycredentials.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://agentidentitycredentials.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.AuthProviderCredentialsServiceGrpcTransport, "grpc"), + (transports.AuthProviderCredentialsServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.AuthProviderCredentialsServiceRestTransport, "rest"), + ], +) +def test_auth_provider_credentials_service_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (AuthProviderCredentialsServiceClient, "grpc"), + (AuthProviderCredentialsServiceAsyncClient, "grpc_asyncio"), + (AuthProviderCredentialsServiceClient, "rest"), + ], +) +def test_auth_provider_credentials_service_client_from_service_account_file( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "agentidentitycredentials.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://agentidentitycredentials.googleapis.com" + ) + + +def test_auth_provider_credentials_service_client_get_transport_class(): + transport = AuthProviderCredentialsServiceClient.get_transport_class() + available_transports = [ + transports.AuthProviderCredentialsServiceGrpcTransport, + transports.AuthProviderCredentialsServiceRestTransport, + ] + assert transport in available_transports + + transport = AuthProviderCredentialsServiceClient.get_transport_class("grpc") + assert transport == transports.AuthProviderCredentialsServiceGrpcTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + AuthProviderCredentialsServiceClient, + transports.AuthProviderCredentialsServiceGrpcTransport, + "grpc", + ), + ( + AuthProviderCredentialsServiceAsyncClient, + transports.AuthProviderCredentialsServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ( + AuthProviderCredentialsServiceClient, + transports.AuthProviderCredentialsServiceRestTransport, + "rest", + ), + ], +) +@mock.patch.object( + AuthProviderCredentialsServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(AuthProviderCredentialsServiceClient), +) +@mock.patch.object( + AuthProviderCredentialsServiceAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(AuthProviderCredentialsServiceAsyncClient), +) +def test_auth_provider_credentials_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( + AuthProviderCredentialsServiceClient, "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( + AuthProviderCredentialsServiceClient, "get_transport_class" + ) as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # 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_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + AuthProviderCredentialsServiceClient, + transports.AuthProviderCredentialsServiceGrpcTransport, + "grpc", + "true", + ), + ( + AuthProviderCredentialsServiceAsyncClient, + transports.AuthProviderCredentialsServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + ( + AuthProviderCredentialsServiceClient, + transports.AuthProviderCredentialsServiceGrpcTransport, + "grpc", + "false", + ), + ( + AuthProviderCredentialsServiceAsyncClient, + transports.AuthProviderCredentialsServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + ( + AuthProviderCredentialsServiceClient, + transports.AuthProviderCredentialsServiceRestTransport, + "rest", + "true", + ), + ( + AuthProviderCredentialsServiceClient, + transports.AuthProviderCredentialsServiceRestTransport, + "rest", + "false", + ), + ], +) +@mock.patch.object( + AuthProviderCredentialsServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(AuthProviderCredentialsServiceClient), +) +@mock.patch.object( + AuthProviderCredentialsServiceAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(AuthProviderCredentialsServiceAsyncClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_auth_provider_credentials_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_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class", + [AuthProviderCredentialsServiceClient, AuthProviderCredentialsServiceAsyncClient], +) +@mock.patch.object( + AuthProviderCredentialsServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(AuthProviderCredentialsServiceClient), +) +@mock.patch.object( + AuthProviderCredentialsServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(AuthProviderCredentialsServiceAsyncClient), +) +def test_auth_provider_credentials_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_CLIENT_CERTIFICATE is "Unsupported". + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + 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 cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset. + test_cases = [ + ( + # With workloads present in config, mTLS is enabled. + { + "version": 1, + "cert_configs": { + "workload": { + "cert_path": "path/to/cert/file", + "key_path": "path/to/key/file", + } + }, + }, + mock_client_cert_source, + ), + ( + # With workloads not present in config, mTLS is disabled. + { + "version": 1, + "cert_configs": {}, + }, + None, + ), + ] + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + for config_data, expected_cert_source in test_cases: + env = os.environ.copy() + env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", None) + with mock.patch.dict(os.environ, env, clear=True): + config_filename = "mock_certificate_config.json" + config_file_content = json.dumps(config_data) + m = mock.mock_open(read_data=config_file_content) + with mock.patch("builtins.open", m): + with mock.patch.dict( + os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename} + ): + 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 expected_cert_source + + # Test cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset(empty). + test_cases = [ + ( + # With workloads present in config, mTLS is enabled. + { + "version": 1, + "cert_configs": { + "workload": { + "cert_path": "path/to/cert/file", + "key_path": "path/to/key/file", + } + }, + }, + mock_client_cert_source, + ), + ( + # With workloads not present in config, mTLS is disabled. + { + "version": 1, + "cert_configs": {}, + }, + None, + ), + ] + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + for config_data, expected_cert_source in test_cases: + env = os.environ.copy() + env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", "") + with mock.patch.dict(os.environ, env, clear=True): + config_filename = "mock_certificate_config.json" + config_file_content = json.dumps(config_data) + m = mock.mock_open(read_data=config_file_content) + with mock.patch("builtins.open", m): + with mock.patch.dict( + os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename} + ): + 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 expected_cert_source + + # 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 + + # 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) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + +@pytest.mark.parametrize( + "client_class", + [AuthProviderCredentialsServiceClient, AuthProviderCredentialsServiceAsyncClient], +) +@mock.patch.object( + AuthProviderCredentialsServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(AuthProviderCredentialsServiceClient), +) +@mock.patch.object( + AuthProviderCredentialsServiceAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(AuthProviderCredentialsServiceAsyncClient), +) +def test_auth_provider_credentials_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = AuthProviderCredentialsServiceClient._DEFAULT_UNIVERSE + default_endpoint = ( + AuthProviderCredentialsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + ) + mock_universe = "bar.com" + mock_endpoint = ( + AuthProviderCredentialsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + AuthProviderCredentialsServiceClient, + transports.AuthProviderCredentialsServiceGrpcTransport, + "grpc", + ), + ( + AuthProviderCredentialsServiceAsyncClient, + transports.AuthProviderCredentialsServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ( + AuthProviderCredentialsServiceClient, + transports.AuthProviderCredentialsServiceRestTransport, + "rest", + ), + ], +) +def test_auth_provider_credentials_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_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + AuthProviderCredentialsServiceClient, + transports.AuthProviderCredentialsServiceGrpcTransport, + "grpc", + grpc_helpers, + ), + ( + AuthProviderCredentialsServiceAsyncClient, + transports.AuthProviderCredentialsServiceGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + ( + AuthProviderCredentialsServiceClient, + transports.AuthProviderCredentialsServiceRestTransport, + "rest", + None, + ), + ], +) +def test_auth_provider_credentials_service_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_auth_provider_credentials_service_client_client_options_from_dict(): + with mock.patch( + "google.cloud.agentidentitycredentials_v1.services.auth_provider_credentials_service.transports.AuthProviderCredentialsServiceGrpcTransport.__init__" + ) as grpc_transport: + grpc_transport.return_value = None + client = AuthProviderCredentialsServiceClient( + client_options={"api_endpoint": "squid.clam.whelk"} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + AuthProviderCredentialsServiceClient, + transports.AuthProviderCredentialsServiceGrpcTransport, + "grpc", + grpc_helpers, + ), + ( + AuthProviderCredentialsServiceAsyncClient, + transports.AuthProviderCredentialsServiceGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + ], +) +def test_auth_provider_credentials_service_client_create_channel_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # test that the credentials from file are saved and used as the credentials. + with ( + mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, + mock.patch.object(google.auth, "default", autospec=True) as adc, + mock.patch.object(grpc_helpers, "create_channel") as create_channel, + ): + creds = ga_credentials.AnonymousCredentials() + file_creds = ga_credentials.AnonymousCredentials() + load_creds.return_value = (file_creds, None) + adc.return_value = (creds, None) + client = client_class(client_options=options, transport=transport_name) + create_channel.assert_called_with( + "agentidentitycredentials.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + scopes=None, + default_host="agentidentitycredentials.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "request_type", + [ + auth_provider_credentials_service.RetrieveCredentialsRequest(), + {}, + ], +) +def test_retrieve_credentials(request_type, transport: str = "grpc"): + client = AuthProviderCredentialsServiceClient( + 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.retrieve_credentials), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + auth_provider_credentials_service.RetrieveCredentialsResponse() + ) + response = client.retrieve_credentials(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = auth_provider_credentials_service.RetrieveCredentialsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance( + response, auth_provider_credentials_service.RetrieveCredentialsResponse + ) + + +def test_retrieve_credentials_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = AuthProviderCredentialsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = auth_provider_credentials_service.RetrieveCredentialsRequest( + auth_provider="auth_provider_value", + user_id="user_id_value", + continue_uri="continue_uri_value", + force_refresh_token="force_refresh_token_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.retrieve_credentials), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.retrieve_credentials(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = auth_provider_credentials_service.RetrieveCredentialsRequest( + auth_provider="auth_provider_value", + user_id="user_id_value", + continue_uri="continue_uri_value", + force_refresh_token="force_refresh_token_value", + ) + assert args[0] == request_msg + + +def test_retrieve_credentials_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = AuthProviderCredentialsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.retrieve_credentials in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.retrieve_credentials] = ( + mock_rpc + ) + request = {} + client.retrieve_credentials(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.retrieve_credentials(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_retrieve_credentials_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = AuthProviderCredentialsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.retrieve_credentials + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.retrieve_credentials + ] = mock_rpc + + request = {} + await client.retrieve_credentials(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.retrieve_credentials(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + auth_provider_credentials_service.RetrieveCredentialsRequest(), + {}, + ], +) +async def test_retrieve_credentials_async( + request_type, transport: str = "grpc_asyncio" +): + client = AuthProviderCredentialsServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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.retrieve_credentials), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + auth_provider_credentials_service.RetrieveCredentialsResponse() + ) + response = await client.retrieve_credentials(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = auth_provider_credentials_service.RetrieveCredentialsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance( + response, auth_provider_credentials_service.RetrieveCredentialsResponse + ) + + +def test_retrieve_credentials_field_headers(): + client = AuthProviderCredentialsServiceClient( + 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 = auth_provider_credentials_service.RetrieveCredentialsRequest() + + request.auth_provider = "auth_provider_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.retrieve_credentials), "__call__" + ) as call: + call.return_value = ( + auth_provider_credentials_service.RetrieveCredentialsResponse() + ) + client.retrieve_credentials(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", + "auth_provider=auth_provider_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_retrieve_credentials_field_headers_async(): + client = AuthProviderCredentialsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = auth_provider_credentials_service.RetrieveCredentialsRequest() + + request.auth_provider = "auth_provider_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.retrieve_credentials), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + auth_provider_credentials_service.RetrieveCredentialsResponse() + ) + await client.retrieve_credentials(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", + "auth_provider=auth_provider_value", + ) in kw["metadata"] + + +def test_retrieve_credentials_flattened(): + client = AuthProviderCredentialsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.retrieve_credentials), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + auth_provider_credentials_service.RetrieveCredentialsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.retrieve_credentials( + auth_provider="auth_provider_value", + user_id="user_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].auth_provider + mock_val = "auth_provider_value" + assert arg == mock_val + arg = args[0].user_id + mock_val = "user_id_value" + assert arg == mock_val + + +def test_retrieve_credentials_flattened_error(): + client = AuthProviderCredentialsServiceClient( + 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.retrieve_credentials( + auth_provider_credentials_service.RetrieveCredentialsRequest(), + auth_provider="auth_provider_value", + user_id="user_id_value", + ) + + +@pytest.mark.asyncio +async def test_retrieve_credentials_flattened_async(): + client = AuthProviderCredentialsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.retrieve_credentials), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + auth_provider_credentials_service.RetrieveCredentialsResponse() + ) + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + auth_provider_credentials_service.RetrieveCredentialsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.retrieve_credentials( + auth_provider="auth_provider_value", + user_id="user_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].auth_provider + mock_val = "auth_provider_value" + assert arg == mock_val + arg = args[0].user_id + mock_val = "user_id_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_retrieve_credentials_flattened_error_async(): + client = AuthProviderCredentialsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.retrieve_credentials( + auth_provider_credentials_service.RetrieveCredentialsRequest(), + auth_provider="auth_provider_value", + user_id="user_id_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + auth_provider_credentials_service.FinalizeCredentialsRequest(), + {}, + ], +) +def test_finalize_credentials(request_type, transport: str = "grpc"): + client = AuthProviderCredentialsServiceClient( + 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.finalize_credentials), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + auth_provider_credentials_service.FinalizeCredentialsResponse() + ) + response = client.finalize_credentials(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = auth_provider_credentials_service.FinalizeCredentialsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance( + response, auth_provider_credentials_service.FinalizeCredentialsResponse + ) + + +def test_finalize_credentials_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = AuthProviderCredentialsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = auth_provider_credentials_service.FinalizeCredentialsRequest( + auth_provider="auth_provider_value", + user_id="user_id_value", + consent_nonce="consent_nonce_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.finalize_credentials), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.finalize_credentials(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = auth_provider_credentials_service.FinalizeCredentialsRequest( + auth_provider="auth_provider_value", + user_id="user_id_value", + consent_nonce="consent_nonce_value", + ) + assert args[0] == request_msg + + +def test_finalize_credentials_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = AuthProviderCredentialsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.finalize_credentials in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.finalize_credentials] = ( + mock_rpc + ) + request = {} + client.finalize_credentials(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.finalize_credentials(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_finalize_credentials_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = AuthProviderCredentialsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.finalize_credentials + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.finalize_credentials + ] = mock_rpc + + request = {} + await client.finalize_credentials(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.finalize_credentials(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + auth_provider_credentials_service.FinalizeCredentialsRequest(), + {}, + ], +) +async def test_finalize_credentials_async( + request_type, transport: str = "grpc_asyncio" +): + client = AuthProviderCredentialsServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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.finalize_credentials), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + auth_provider_credentials_service.FinalizeCredentialsResponse() + ) + response = await client.finalize_credentials(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = auth_provider_credentials_service.FinalizeCredentialsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance( + response, auth_provider_credentials_service.FinalizeCredentialsResponse + ) + + +def test_finalize_credentials_field_headers(): + client = AuthProviderCredentialsServiceClient( + 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 = auth_provider_credentials_service.FinalizeCredentialsRequest() + + request.auth_provider = "auth_provider_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.finalize_credentials), "__call__" + ) as call: + call.return_value = ( + auth_provider_credentials_service.FinalizeCredentialsResponse() + ) + client.finalize_credentials(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", + "auth_provider=auth_provider_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_finalize_credentials_field_headers_async(): + client = AuthProviderCredentialsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = auth_provider_credentials_service.FinalizeCredentialsRequest() + + request.auth_provider = "auth_provider_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.finalize_credentials), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + auth_provider_credentials_service.FinalizeCredentialsResponse() + ) + await client.finalize_credentials(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", + "auth_provider=auth_provider_value", + ) in kw["metadata"] + + +def test_retrieve_credentials_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = AuthProviderCredentialsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.retrieve_credentials in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.retrieve_credentials] = ( + mock_rpc + ) + + request = {} + client.retrieve_credentials(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.retrieve_credentials(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_retrieve_credentials_rest_required_fields( + request_type=auth_provider_credentials_service.RetrieveCredentialsRequest, +): + transport_class = transports.AuthProviderCredentialsServiceRestTransport + + request_init = {} + request_init["auth_provider"] = "" + request_init["user_id"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).retrieve_credentials._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["authProvider"] = "auth_provider_value" + jsonified_request["userId"] = "user_id_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).retrieve_credentials._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "authProvider" in jsonified_request + assert jsonified_request["authProvider"] == "auth_provider_value" + assert "userId" in jsonified_request + assert jsonified_request["userId"] == "user_id_value" + + client = AuthProviderCredentialsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = auth_provider_credentials_service.RetrieveCredentialsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = ( + auth_provider_credentials_service.RetrieveCredentialsResponse.pb( + return_value + ) + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.retrieve_credentials(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_retrieve_credentials_rest_unset_required_fields(): + transport = transports.AuthProviderCredentialsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.retrieve_credentials._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "authProvider", + "userId", + ) + ) + ) + + +def test_retrieve_credentials_rest_flattened(): + client = AuthProviderCredentialsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = auth_provider_credentials_service.RetrieveCredentialsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = { + "auth_provider": "projects/sample1/locations/sample2/authProviders/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + auth_provider="auth_provider_value", + user_id="user_id_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = auth_provider_credentials_service.RetrieveCredentialsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.retrieve_credentials(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{auth_provider=projects/*/locations/*/authProviders/*}/credentials:retrieve" + % client.transport._host, + args[1], + ) + + +def test_retrieve_credentials_rest_flattened_error(transport: str = "rest"): + client = AuthProviderCredentialsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.retrieve_credentials( + auth_provider_credentials_service.RetrieveCredentialsRequest(), + auth_provider="auth_provider_value", + user_id="user_id_value", + ) + + +def test_finalize_credentials_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = AuthProviderCredentialsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.finalize_credentials in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.finalize_credentials] = ( + mock_rpc + ) + + request = {} + client.finalize_credentials(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.finalize_credentials(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_finalize_credentials_rest_required_fields( + request_type=auth_provider_credentials_service.FinalizeCredentialsRequest, +): + transport_class = transports.AuthProviderCredentialsServiceRestTransport + + request_init = {} + request_init["auth_provider"] = "" + request_init["user_id"] = "" + request_init["user_id_validation_state"] = b"" + request_init["consent_nonce"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).finalize_credentials._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["authProvider"] = "auth_provider_value" + jsonified_request["userId"] = "user_id_value" + jsonified_request["userIdValidationState"] = b"user_id_validation_state_blob" + jsonified_request["consentNonce"] = "consent_nonce_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).finalize_credentials._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "authProvider" in jsonified_request + assert jsonified_request["authProvider"] == "auth_provider_value" + assert "userId" in jsonified_request + assert jsonified_request["userId"] == "user_id_value" + assert "userIdValidationState" in jsonified_request + assert ( + jsonified_request["userIdValidationState"] == b"user_id_validation_state_blob" + ) + assert "consentNonce" in jsonified_request + assert jsonified_request["consentNonce"] == "consent_nonce_value" + + client = AuthProviderCredentialsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = auth_provider_credentials_service.FinalizeCredentialsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = ( + auth_provider_credentials_service.FinalizeCredentialsResponse.pb( + return_value + ) + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.finalize_credentials(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_finalize_credentials_rest_unset_required_fields(): + transport = transports.AuthProviderCredentialsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.finalize_credentials._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "authProvider", + "userId", + "userIdValidationState", + "consentNonce", + ) + ) + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.AuthProviderCredentialsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AuthProviderCredentialsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.AuthProviderCredentialsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AuthProviderCredentialsServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.AuthProviderCredentialsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = AuthProviderCredentialsServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = AuthProviderCredentialsServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.AuthProviderCredentialsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AuthProviderCredentialsServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.AuthProviderCredentialsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = AuthProviderCredentialsServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.AuthProviderCredentialsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.AuthProviderCredentialsServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.AuthProviderCredentialsServiceGrpcTransport, + transports.AuthProviderCredentialsServiceGrpcAsyncIOTransport, + transports.AuthProviderCredentialsServiceRestTransport, + ], +) +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_kind_grpc(): + transport = AuthProviderCredentialsServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = AuthProviderCredentialsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_retrieve_credentials_empty_call_grpc(): + client = AuthProviderCredentialsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.retrieve_credentials), "__call__" + ) as call: + call.return_value = ( + auth_provider_credentials_service.RetrieveCredentialsResponse() + ) + client.retrieve_credentials(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = auth_provider_credentials_service.RetrieveCredentialsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_finalize_credentials_empty_call_grpc(): + client = AuthProviderCredentialsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.finalize_credentials), "__call__" + ) as call: + call.return_value = ( + auth_provider_credentials_service.FinalizeCredentialsResponse() + ) + client.finalize_credentials(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = auth_provider_credentials_service.FinalizeCredentialsRequest() + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = AuthProviderCredentialsServiceAsyncClient.get_transport_class( + "grpc_asyncio" + )(credentials=async_anonymous_credentials()) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = AuthProviderCredentialsServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_retrieve_credentials_empty_call_grpc_asyncio(): + client = AuthProviderCredentialsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.retrieve_credentials), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + auth_provider_credentials_service.RetrieveCredentialsResponse() + ) + await client.retrieve_credentials(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = auth_provider_credentials_service.RetrieveCredentialsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_finalize_credentials_empty_call_grpc_asyncio(): + client = AuthProviderCredentialsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.finalize_credentials), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + auth_provider_credentials_service.FinalizeCredentialsResponse() + ) + await client.finalize_credentials(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = auth_provider_credentials_service.FinalizeCredentialsRequest() + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = AuthProviderCredentialsServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_retrieve_credentials_rest_bad_request( + request_type=auth_provider_credentials_service.RetrieveCredentialsRequest, +): + client = AuthProviderCredentialsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "auth_provider": "projects/sample1/locations/sample2/authProviders/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.retrieve_credentials(request) + + +@pytest.mark.parametrize( + "request_type", + [ + auth_provider_credentials_service.RetrieveCredentialsRequest, + dict, + ], +) +def test_retrieve_credentials_rest_call_success(request_type): + client = AuthProviderCredentialsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "auth_provider": "projects/sample1/locations/sample2/authProviders/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = auth_provider_credentials_service.RetrieveCredentialsResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = auth_provider_credentials_service.RetrieveCredentialsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.retrieve_credentials(request) + + # Establish that the response is the type that we expect. + assert isinstance( + response, auth_provider_credentials_service.RetrieveCredentialsResponse + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_retrieve_credentials_rest_interceptors(null_interceptor): + transport = transports.AuthProviderCredentialsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.AuthProviderCredentialsServiceRestInterceptor(), + ) + client = AuthProviderCredentialsServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.AuthProviderCredentialsServiceRestInterceptor, + "post_retrieve_credentials", + ) as post, + mock.patch.object( + transports.AuthProviderCredentialsServiceRestInterceptor, + "post_retrieve_credentials_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.AuthProviderCredentialsServiceRestInterceptor, + "pre_retrieve_credentials", + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = auth_provider_credentials_service.RetrieveCredentialsRequest.pb( + auth_provider_credentials_service.RetrieveCredentialsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = ( + auth_provider_credentials_service.RetrieveCredentialsResponse.to_json( + auth_provider_credentials_service.RetrieveCredentialsResponse() + ) + ) + req.return_value.content = return_value + + request = auth_provider_credentials_service.RetrieveCredentialsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = ( + auth_provider_credentials_service.RetrieveCredentialsResponse() + ) + post_with_metadata.return_value = ( + auth_provider_credentials_service.RetrieveCredentialsResponse(), + metadata, + ) + + client.retrieve_credentials( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_finalize_credentials_rest_bad_request( + request_type=auth_provider_credentials_service.FinalizeCredentialsRequest, +): + client = AuthProviderCredentialsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "auth_provider": "projects/sample1/locations/sample2/authProviders/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.finalize_credentials(request) + + +@pytest.mark.parametrize( + "request_type", + [ + auth_provider_credentials_service.FinalizeCredentialsRequest, + dict, + ], +) +def test_finalize_credentials_rest_call_success(request_type): + client = AuthProviderCredentialsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "auth_provider": "projects/sample1/locations/sample2/authProviders/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = auth_provider_credentials_service.FinalizeCredentialsResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = auth_provider_credentials_service.FinalizeCredentialsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.finalize_credentials(request) + + # Establish that the response is the type that we expect. + assert isinstance( + response, auth_provider_credentials_service.FinalizeCredentialsResponse + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_finalize_credentials_rest_interceptors(null_interceptor): + transport = transports.AuthProviderCredentialsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.AuthProviderCredentialsServiceRestInterceptor(), + ) + client = AuthProviderCredentialsServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.AuthProviderCredentialsServiceRestInterceptor, + "post_finalize_credentials", + ) as post, + mock.patch.object( + transports.AuthProviderCredentialsServiceRestInterceptor, + "post_finalize_credentials_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.AuthProviderCredentialsServiceRestInterceptor, + "pre_finalize_credentials", + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = auth_provider_credentials_service.FinalizeCredentialsRequest.pb( + auth_provider_credentials_service.FinalizeCredentialsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = ( + auth_provider_credentials_service.FinalizeCredentialsResponse.to_json( + auth_provider_credentials_service.FinalizeCredentialsResponse() + ) + ) + req.return_value.content = return_value + + request = auth_provider_credentials_service.FinalizeCredentialsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = ( + auth_provider_credentials_service.FinalizeCredentialsResponse() + ) + post_with_metadata.return_value = ( + auth_provider_credentials_service.FinalizeCredentialsResponse(), + metadata, + ) + + client.finalize_credentials( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_initialize_client_w_rest(): + client = AuthProviderCredentialsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_retrieve_credentials_empty_call_rest(): + client = AuthProviderCredentialsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.retrieve_credentials), "__call__" + ) as call: + client.retrieve_credentials(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = auth_provider_credentials_service.RetrieveCredentialsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_finalize_credentials_empty_call_rest(): + client = AuthProviderCredentialsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.finalize_credentials), "__call__" + ) as call: + client.finalize_credentials(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = auth_provider_credentials_service.FinalizeCredentialsRequest() + assert args[0] == request_msg + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = AuthProviderCredentialsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.AuthProviderCredentialsServiceGrpcTransport, + ) + + +def test_auth_provider_credentials_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.AuthProviderCredentialsServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_auth_provider_credentials_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.cloud.agentidentitycredentials_v1.services.auth_provider_credentials_service.transports.AuthProviderCredentialsServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.AuthProviderCredentialsServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "retrieve_credentials", + "finalize_credentials", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_auth_provider_credentials_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.agentidentitycredentials_v1.services.auth_provider_credentials_service.transports.AuthProviderCredentialsServiceTransport._prep_wrapped_messages" + ) as Transport, + ): + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.AuthProviderCredentialsServiceTransport( + 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_auth_provider_credentials_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.agentidentitycredentials_v1.services.auth_provider_credentials_service.transports.AuthProviderCredentialsServiceTransport._prep_wrapped_messages" + ) as Transport, + ): + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.AuthProviderCredentialsServiceTransport() + adc.assert_called_once() + + +def test_auth_provider_credentials_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) + AuthProviderCredentialsServiceClient() + 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.AuthProviderCredentialsServiceGrpcTransport, + transports.AuthProviderCredentialsServiceGrpcAsyncIOTransport, + ], +) +def test_auth_provider_credentials_service_transport_auth_adc(transport_class): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.AuthProviderCredentialsServiceGrpcTransport, + transports.AuthProviderCredentialsServiceGrpcAsyncIOTransport, + transports.AuthProviderCredentialsServiceRestTransport, + ], +) +def test_auth_provider_credentials_service_transport_auth_gdch_credentials( + transport_class, +): + host = "https://language.com" + api_audience_tests = [None, "https://language2.com"] + api_audience_expect = [host, "https://language2.com"] + for t, e in zip(api_audience_tests, api_audience_expect): + with mock.patch.object(google.auth, "default", autospec=True) as adc: + gdch_mock = mock.MagicMock() + type(gdch_mock).with_gdch_audience = mock.PropertyMock( + return_value=gdch_mock + ) + adc.return_value = (gdch_mock, None) + transport_class(host=host, api_audience=t) + gdch_mock.with_gdch_audience.assert_called_once_with(e) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.AuthProviderCredentialsServiceGrpcTransport, grpc_helpers), + ( + transports.AuthProviderCredentialsServiceGrpcAsyncIOTransport, + grpc_helpers_async, + ), + ], +) +def test_auth_provider_credentials_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( + "agentidentitycredentials.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="agentidentitycredentials.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.AuthProviderCredentialsServiceGrpcTransport, + transports.AuthProviderCredentialsServiceGrpcAsyncIOTransport, + ], +) +def test_auth_provider_credentials_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_auth_provider_credentials_service_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.AuthProviderCredentialsServiceRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_auth_provider_credentials_service_host_no_port(transport_name): + client = AuthProviderCredentialsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="agentidentitycredentials.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "agentidentitycredentials.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://agentidentitycredentials.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_auth_provider_credentials_service_host_with_port(transport_name): + client = AuthProviderCredentialsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="agentidentitycredentials.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "agentidentitycredentials.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://agentidentitycredentials.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_auth_provider_credentials_service_client_transport_session_collision( + transport_name, +): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = AuthProviderCredentialsServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = AuthProviderCredentialsServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.retrieve_credentials._session + session2 = client2.transport.retrieve_credentials._session + assert session1 != session2 + session1 = client1.transport.finalize_credentials._session + session2 = client2.transport.finalize_credentials._session + assert session1 != session2 + + +def test_auth_provider_credentials_service_grpc_transport_channel(): + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.AuthProviderCredentialsServiceGrpcTransport( + 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_auth_provider_credentials_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.AuthProviderCredentialsServiceGrpcAsyncIOTransport( + 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.filterwarnings("ignore::FutureWarning") +@pytest.mark.parametrize( + "transport_class", + [ + transports.AuthProviderCredentialsServiceGrpcTransport, + transports.AuthProviderCredentialsServiceGrpcAsyncIOTransport, + ], +) +def test_auth_provider_credentials_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.AuthProviderCredentialsServiceGrpcTransport, + transports.AuthProviderCredentialsServiceGrpcAsyncIOTransport, + ], +) +def test_auth_provider_credentials_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_auth_provider_path(): + project = "squid" + location = "clam" + auth_provider = "whelk" + expected = ( + "projects/{project}/locations/{location}/authProviders/{auth_provider}".format( + project=project, + location=location, + auth_provider=auth_provider, + ) + ) + actual = AuthProviderCredentialsServiceClient.auth_provider_path( + project, location, auth_provider + ) + assert expected == actual + + +def test_parse_auth_provider_path(): + expected = { + "project": "octopus", + "location": "oyster", + "auth_provider": "nudibranch", + } + path = AuthProviderCredentialsServiceClient.auth_provider_path(**expected) + + # Check that the path construction is reversible. + actual = AuthProviderCredentialsServiceClient.parse_auth_provider_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "cuttlefish" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = AuthProviderCredentialsServiceClient.common_billing_account_path( + billing_account + ) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "mussel", + } + path = AuthProviderCredentialsServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = AuthProviderCredentialsServiceClient.parse_common_billing_account_path( + path + ) + assert expected == actual + + +def test_common_folder_path(): + folder = "winkle" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = AuthProviderCredentialsServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nautilus", + } + path = AuthProviderCredentialsServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = AuthProviderCredentialsServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "scallop" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = AuthProviderCredentialsServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "abalone", + } + path = AuthProviderCredentialsServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = AuthProviderCredentialsServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "squid" + expected = "projects/{project}".format( + project=project, + ) + actual = AuthProviderCredentialsServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "clam", + } + path = AuthProviderCredentialsServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = AuthProviderCredentialsServiceClient.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 = AuthProviderCredentialsServiceClient.common_location_path( + project, location + ) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + } + path = AuthProviderCredentialsServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = AuthProviderCredentialsServiceClient.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.AuthProviderCredentialsServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = AuthProviderCredentialsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.AuthProviderCredentialsServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = AuthProviderCredentialsServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_grpc(): + client = AuthProviderCredentialsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +@pytest.mark.asyncio +async def test_transport_close_grpc_asyncio(): + client = AuthProviderCredentialsServiceAsyncClient( + credentials=async_anonymous_credentials(), 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_rest(): + client = AuthProviderCredentialsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + "grpc", + ] + for transport in transports: + client = AuthProviderCredentialsServiceClient( + 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", + [ + ( + AuthProviderCredentialsServiceClient, + transports.AuthProviderCredentialsServiceGrpcTransport, + ), + ( + AuthProviderCredentialsServiceAsyncClient, + transports.AuthProviderCredentialsServiceGrpcAsyncIOTransport, + ), + ], +) +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_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) From 860cd4003a5a336367cc2a163c97a57e3f0369a8 Mon Sep 17 00:00:00 2001 From: Tomo Suzuki Date: Mon, 8 Jun 2026 15:31:53 -0400 Subject: [PATCH 042/174] chore: librarian release pull request: 20260608T174331Z (#17395) PR created by the Librarian CLI to initialize a release. Merging this PR will auto trigger a release. Librarian Version: v0.16.0 Language Image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:234b9d1f2ddb057ed7ac6a38db0bf8163d839c65c6cf88ade52530cddebce59e
google-devicesandservices-health: v0.1.0 ## [v0.1.0](https://github.com/googleapis/google-cloud-python/compare/google-devicesandservices-health-v0.0.0...google-devicesandservices-health-v0.1.0) (2026-06-08) ### Features * add google-devicesandservices-health (#17365) ([f9ff3b1b](https://github.com/googleapis/google-cloud-python/commit/f9ff3b1b))
--- .librarian/state.yaml | 2 +- librarian.yaml | 2 +- packages/google-devicesandservices-health/CHANGELOG.md | 7 +++++++ .../google/devicesandservices/health/gapic_version.py | 2 +- .../google/devicesandservices/health_v4/gapic_version.py | 2 +- ...ippet_metadata_google.devicesandservices.health.v4.json | 2 +- 6 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index 0cb1a6b1982d..b3f68c3f5214 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -5437,7 +5437,7 @@ libraries: - packages/google-developers-knowledge/docs/ tag_format: '{id}-v{version}' - id: google-devicesandservices-health - version: 0.0.0 + version: 0.1.0 last_generated_commit: "" apis: - path: google/devicesandservices/health/v4 diff --git a/librarian.yaml b/librarian.yaml index cf7c3f01daaa..7b237e6a6c6c 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -2238,7 +2238,7 @@ libraries: - python-gapic-name=developers_knowledge default_version: v1 - name: google-devicesandservices-health - version: 0.0.0 + version: 0.1.0 apis: - path: google/devicesandservices/health/v4 copyright_year: "2026" diff --git a/packages/google-devicesandservices-health/CHANGELOG.md b/packages/google-devicesandservices-health/CHANGELOG.md index 34808bf0463d..b786688698bd 100644 --- a/packages/google-devicesandservices-health/CHANGELOG.md +++ b/packages/google-devicesandservices-health/CHANGELOG.md @@ -3,3 +3,10 @@ [PyPI History][1] [1]: https://pypi.org/project/google-devicesandservices-health/#history + +## [0.1.0](https://github.com/googleapis/google-cloud-python/compare/google-devicesandservices-health-v0.0.0...google-devicesandservices-health-v0.1.0) (2026-06-08) + + +### Features + +* add google-devicesandservices-health (#17365) ([f9ff3b1baf56980210a7770e54e50711754f1d2d](https://github.com/googleapis/google-cloud-python/commit/f9ff3b1baf56980210a7770e54e50711754f1d2d)) diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health/gapic_version.py b/packages/google-devicesandservices-health/google/devicesandservices/health/gapic_version.py index e89a0031d71b..075b8773ece3 100644 --- a/packages/google-devicesandservices-health/google/devicesandservices/health/gapic_version.py +++ b/packages/google-devicesandservices-health/google/devicesandservices/health/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.0.0" # {x-release-please-version} +__version__ = "0.1.0" # {x-release-please-version} diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/gapic_version.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/gapic_version.py index e89a0031d71b..075b8773ece3 100644 --- a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/gapic_version.py +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.0.0" # {x-release-please-version} +__version__ = "0.1.0" # {x-release-please-version} diff --git a/packages/google-devicesandservices-health/samples/generated_samples/snippet_metadata_google.devicesandservices.health.v4.json b/packages/google-devicesandservices-health/samples/generated_samples/snippet_metadata_google.devicesandservices.health.v4.json index 3bfd37bf444a..169609d26bd9 100644 --- a/packages/google-devicesandservices-health/samples/generated_samples/snippet_metadata_google.devicesandservices.health.v4.json +++ b/packages/google-devicesandservices-health/samples/generated_samples/snippet_metadata_google.devicesandservices.health.v4.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-devicesandservices-health", - "version": "0.0.0" + "version": "0.1.0" }, "snippets": [ { From a1a538a04041e0d2e92018d65fa2aa53aef4f166 Mon Sep 17 00:00:00 2001 From: Tomo Suzuki Date: Mon, 8 Jun 2026 16:36:39 -0400 Subject: [PATCH 043/174] chore: librarian release pull request: 20260608T175401Z (#17396) PR created by the Librarian CLI to initialize a release. Merging this PR will auto trigger a release. Librarian Version: v0.16.0 Language Image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:234b9d1f2ddb057ed7ac6a38db0bf8163d839c65c6cf88ade52530cddebce59e
google-backstory: v0.1.0 ## [v0.1.0](https://github.com/googleapis/google-cloud-python/compare/google-backstory-v0.0.0...google-backstory-v0.1.0) (2026-06-08) ### Features * new library google-backstory (#17374) ([65f059e2](https://github.com/googleapis/google-cloud-python/commit/65f059e2))
--- .librarian/state.yaml | 2 +- librarian.yaml | 2 +- packages/google-backstory/CHANGELOG.md | 7 +++++++ .../google-backstory/google/backstory/gapic_version.py | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index b3f68c3f5214..edc35267330c 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -432,7 +432,7 @@ libraries: - packages/google-auth-oauthlib/docs/ tag_format: '{id}-v{version}' - id: google-backstory - version: 0.0.0 + version: 0.1.0 last_generated_commit: "" apis: - path: backstory diff --git a/librarian.yaml b/librarian.yaml index 7b237e6a6c6c..6885f7e34c36 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -240,7 +240,7 @@ libraries: python: library_type: AUTH - name: google-backstory - version: 0.0.0 + version: 0.1.0 apis: - path: backstory keep: diff --git a/packages/google-backstory/CHANGELOG.md b/packages/google-backstory/CHANGELOG.md index 44f8b4f93b7b..a8344ed93f66 100644 --- a/packages/google-backstory/CHANGELOG.md +++ b/packages/google-backstory/CHANGELOG.md @@ -3,3 +3,10 @@ [PyPI History][1] [1]: https://pypi.org/project/google-backstory/#history + +## [0.1.0](https://github.com/googleapis/google-cloud-python/compare/google-backstory-v0.0.0...google-backstory-v0.1.0) (2026-06-08) + + +### Features + +* new library google-backstory (#17374) ([65f059e22ea1d710e06230cf5f6ee9eb5fe45e8e](https://github.com/googleapis/google-cloud-python/commit/65f059e22ea1d710e06230cf5f6ee9eb5fe45e8e)) diff --git a/packages/google-backstory/google/backstory/gapic_version.py b/packages/google-backstory/google/backstory/gapic_version.py index e89a0031d71b..075b8773ece3 100644 --- a/packages/google-backstory/google/backstory/gapic_version.py +++ b/packages/google-backstory/google/backstory/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.0.0" # {x-release-please-version} +__version__ = "0.1.0" # {x-release-please-version} From 50053e51b9cee24a949c3fe3e7bda4f418d6bf47 Mon Sep 17 00:00:00 2001 From: Dan Lee <71398022+dandhlee@users.noreply.github.com> Date: Mon, 8 Jun 2026 13:50:38 -0700 Subject: [PATCH 044/174] chore: update owners for sphinx plugin (#17332) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ownership for the Python plugin is being transitioned to the Platform team. Unsure if there's a specific GitHub team for it - if there is, please let me know! Towards b/450646740 🦕 This PR will not be submitted until a training session has been done with the team. --- .github/CODEOWNERS | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index d469316c73a6..5fec4f6ddc9b 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -16,7 +16,6 @@ # - @googleapis/bigtable-team # - @googleapis/cloud-sdk-auth-team # - @googleapis/cloud-sdk-python-team -# - @googleapis/dkp-team # - @googleapis/firestore-team # - @googleapis/gcs-team # - @googleapis/pubsub-team @@ -33,7 +32,6 @@ /packages/bigquery-magics/ @googleapis/bigquery-team @googleapis/bigquery-dataframe-team /packages/db-dtypes/ @googleapis/bigquery-team @googleapis/bigquery-dataframe-team /packages/django-google-spanner/ @googleapis/spanner-team -/packages/gcp-sphinx-docfx-yaml/ @googleapis/dkp-team /packages/google-auth/ @googleapis/cloud-sdk-auth-team @googleapis/aion-team /packages/google-cloud-bigquery*/ @googleapis/bigquery-team @googleapis/bigquery-dataframe-team /packages/google-cloud-bigtable/ @googleapis/bigtable-team From 82101134fbaf376bc007f6a52c4ec5e75b1cb5a7 Mon Sep 17 00:00:00 2001 From: Shuowei Li Date: Mon, 8 Jun 2026 21:23:46 +0000 Subject: [PATCH 045/174] test: skip ai/ml doctests (#17401) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #<521482448> 🦕 --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- packages/bigframes/noxfile.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/bigframes/noxfile.py b/packages/bigframes/noxfile.py index c8d08c6787d0..7ba8f04d4075 100644 --- a/packages/bigframes/noxfile.py +++ b/packages/bigframes/noxfile.py @@ -428,6 +428,16 @@ def doctest(session: nox.sessions.Session): "bigframes/display/anywidget.py", "--ignore", "bigframes/bigquery/_operations/ai.py", + "--ignore", + "bigframes/bigquery/ai.py", + "--ignore", + "bigframes/ml", + "--ignore", + "bigframes/operations/ai.py", + "--ignore", + "bigframes/operations/semantics.py", + "--ignore", + "third_party/bigframes_vendored/sklearn", ), test_folder="bigframes", check_cov=True, From 7141356eab4fe745752707646c1c42dc09c199a4 Mon Sep 17 00:00:00 2001 From: Shuowei Li Date: Tue, 9 Jun 2026 02:43:05 +0000 Subject: [PATCH 046/174] chore: librarian release pull request: 20260608T235726Z (#17403) PR created by the Librarian CLI to initialize a release. Merging this PR will auto trigger a release. Librarian Version: v0.16.0 Language Image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:234b9d1f2ddb057ed7ac6a38db0bf8163d839c65c6cf88ade52530cddebce59e
bigframes: v2.42.0 ## [v2.42.0](https://github.com/googleapis/google-cloud-python/compare/bigframes-v2.41.0...bigframes-v2.42.0) (2026-06-08) ### Features * Add ai_generate functions to the dataframe bq accessor (#17302) ([6b62cb6f](https://github.com/googleapis/google-cloud-python/commit/6b62cb6f)) * support automatic per-cell execution history filtering and isolated callbacks (#17144) ([7d440111](https://github.com/googleapis/google-cloud-python/commit/7d440111)) * create `Series.bigquery.function_name` accessors for array and AEAD functions (#17279) ([d01a4ba3](https://github.com/googleapis/google-cloud-python/commit/d01a4ba3)) ### Bug Fixes * include pyopenssl as a dependency (#17362) ([1f6205ee](https://github.com/googleapis/google-cloud-python/commit/1f6205ee)) * Fix IsInOp literal bug with sqlglot (#17356) ([a3d93afe](https://github.com/googleapis/google-cloud-python/commit/a3d93afe)) * nameless column to_frame bug for pandas 3.0 (#17371) ([b23bfa4c](https://github.com/googleapis/google-cloud-python/commit/b23bfa4c))
--- .librarian/state.yaml | 2 +- librarian.yaml | 2 +- packages/bigframes/CHANGELOG.md | 16 ++++++++++++++++ packages/bigframes/bigframes/version.py | 4 ++-- .../third_party/bigframes_vendored/version.py | 4 ++-- 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index edc35267330c..e7edb1d6fa21 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -14,7 +14,7 @@ image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:234b9d1f2ddb057ed7ac6a38db0bf8163d839c65c6cf88ade52530cddebce59e libraries: - id: bigframes - version: 2.41.0 + version: 2.42.0 last_generated_commit: "" apis: [] source_roots: diff --git a/librarian.yaml b/librarian.yaml index 6885f7e34c36..80f260642d86 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -58,7 +58,7 @@ default: library_type: GAPIC_AUTO libraries: - name: bigframes - version: 2.41.0 + version: 2.42.0 skip_release: true python: library_type: INTEGRATION diff --git a/packages/bigframes/CHANGELOG.md b/packages/bigframes/CHANGELOG.md index f3f727b8f50f..1708074a9ae0 100644 --- a/packages/bigframes/CHANGELOG.md +++ b/packages/bigframes/CHANGELOG.md @@ -4,6 +4,22 @@ [1]: https://pypi.org/project/bigframes/#history +## [2.42.0](https://github.com/googleapis/google-cloud-python/compare/bigframes-v2.41.0...bigframes-v2.42.0) (2026-06-08) + + +### Features + +* create `Series.bigquery.function_name` accessors for array and AEAD functions (#17279) ([d01a4ba30040cfcb6498d0e9ef3ed3a54d56239d](https://github.com/googleapis/google-cloud-python/commit/d01a4ba30040cfcb6498d0e9ef3ed3a54d56239d)) +* support automatic per-cell execution history filtering and isolated callbacks (#17144) ([7d440111d836b94f0ce22f6b08c7ce0e7bf4a38a](https://github.com/googleapis/google-cloud-python/commit/7d440111d836b94f0ce22f6b08c7ce0e7bf4a38a)) +* Add ai_generate functions to the dataframe bq accessor (#17302) ([6b62cb6fb3de94326b8944ae08a400c12529cad2](https://github.com/googleapis/google-cloud-python/commit/6b62cb6fb3de94326b8944ae08a400c12529cad2)) + + +### Bug Fixes + +* nameless column to_frame bug for pandas 3.0 (#17371) ([b23bfa4ceb819bca8201a7fe8b64a9bed56733f0](https://github.com/googleapis/google-cloud-python/commit/b23bfa4ceb819bca8201a7fe8b64a9bed56733f0)) +* include pyopenssl as a dependency (#17362) ([1f6205ee5a370249ece2c2cc7131a47830ef00ea](https://github.com/googleapis/google-cloud-python/commit/1f6205ee5a370249ece2c2cc7131a47830ef00ea)) +* Fix IsInOp literal bug with sqlglot (#17356) ([a3d93afe74dd2b5ec8a2ae92f91c95962764debe](https://github.com/googleapis/google-cloud-python/commit/a3d93afe74dd2b5ec8a2ae92f91c95962764debe)) + ## [2.41.0](https://github.com/googleapis/google-cloud-python/compare/bigframes-v2.40.0...bigframes-v2.41.0) (2026-05-28) diff --git a/packages/bigframes/bigframes/version.py b/packages/bigframes/bigframes/version.py index df8e49f86ebe..8982d009e1b8 100644 --- a/packages/bigframes/bigframes/version.py +++ b/packages/bigframes/bigframes/version.py @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "2.41.0" +__version__ = "2.42.0" # {x-release-please-start-date} -__release_date__ = "2026-05-28" +__release_date__ = "2026-06-08" # {x-release-please-end} diff --git a/packages/bigframes/third_party/bigframes_vendored/version.py b/packages/bigframes/third_party/bigframes_vendored/version.py index df8e49f86ebe..8982d009e1b8 100644 --- a/packages/bigframes/third_party/bigframes_vendored/version.py +++ b/packages/bigframes/third_party/bigframes_vendored/version.py @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "2.41.0" +__version__ = "2.42.0" # {x-release-please-start-date} -__release_date__ = "2026-05-28" +__release_date__ = "2026-06-08" # {x-release-please-end} From 1a0de4a7701b7fdf4c2593b1960f1194ebc49793 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Swe=C3=B1a=20=28Swast=29?= Date: Tue, 9 Jun 2026 09:32:28 -0500 Subject: [PATCH 047/174] docs(bigframes): add a notebook explaining bqsql magics cell chaining (#17216) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly: - [ ] Make sure to open an issue as a [bug/issue](https://github.com/googleapis/google-cloud-python/issues) before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea - [ ] Ensure the tests and linter pass - [ ] Code coverage does not decrease (if any source code was changed) - [ ] Appropriate docs were updated (if necessary) Fixes # 🦕 --- packages/bigframes/docs/user_guide/index.rst | 1 + .../dataframes/magics_with_local_data.ipynb | 2488 +++++++++++++++++ 2 files changed, 2489 insertions(+) create mode 100644 packages/bigframes/notebooks/dataframes/magics_with_local_data.ipynb diff --git a/packages/bigframes/docs/user_guide/index.rst b/packages/bigframes/docs/user_guide/index.rst index a9695cf8c7a7..0c0935ac40aa 100644 --- a/packages/bigframes/docs/user_guide/index.rst +++ b/packages/bigframes/docs/user_guide/index.rst @@ -28,6 +28,7 @@ User Guide Dataframe <../notebooks/dataframes/dataframe.ipynb> Index Col Null <../notebooks/dataframes/index_col_null.ipynb> Integrations <../notebooks/dataframes/integrations.ipynb> + Magics for Python and SQL Interoperability <../notebooks/dataframes/magics_with_local_data.ipynb> Pypi <../notebooks/dataframes/pypi.ipynb> .. toctree:: diff --git a/packages/bigframes/notebooks/dataframes/magics_with_local_data.ipynb b/packages/bigframes/notebooks/dataframes/magics_with_local_data.ipynb new file mode 100644 index 000000000000..675ac83988b8 --- /dev/null +++ b/packages/bigframes/notebooks/dataframes/magics_with_local_data.ipynb @@ -0,0 +1,2488 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "c5f9e86e", + "metadata": {}, + "outputs": [], + "source": [ + "# Copyright 2026 Google LLC\n", + "#\n", + "# Licensed under the Apache License, Version 2.0 (the \"License\");\n", + "# you may not use this file except in compliance with the License.\n", + "# You may obtain a copy of the License at\n", + "#\n", + "# https://www.apache.org/licenses/LICENSE-2.0\n", + "#\n", + "# Unless required by applicable law or agreed to in writing, software\n", + "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", + "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", + "# See the License for the specific language governing permissions and\n", + "# limitations under the License." + ] + }, + { + "cell_type": "markdown", + "id": "71383fa0", + "metadata": {}, + "source": [ + "# Unlock SQL and Python interoperability for BigQuery with %%bqsql magic\n", + "\n", + "In this tutorial, you will learn how to seamlessly chain data processing across\n", + "SQL and Python code cells using `%%bqsql` IPython magic and BigQuery DataFrames\n", + "(BigFrames). This interoperability is now available to all Jupyter users,\n", + "whether you're in Colab, JupyterLab, or VS Code. \n", + "\n", + "While we begin by loading a local Excel dataset into a local Pandas DataFrame,\n", + "the main focus is on how you can transition between Pandas' Python-centric API\n", + "and BigQuery's SQL-centric engine. This hybrid workflow combines the best of\n", + "both worlds: the expressive power of SQL for complex transformations and the\n", + "versatile Python ecosystem for visualization and further analysis.\n", + "\n", + "Thanks to open-source packages like Jupyter, Pandas, BigFrames, and the\n", + "[BigQuery sandbox](https://docs.cloud.google.com/bigquery/docs/sandbox), you can\n", + "follow all steps in this guide for free\\* and without a credit card.\n", + "\n", + "_\\*See the [BigQuery sandbox](https://docs.cloud.google.com/bigquery/docs/sandbox) documentation for limitations._\n", + "\n", + "## The %%bqsql Magic\n", + "\n", + "Last year, Google introduced [SQL cells in Colab Enterprise\n", + "notebooks](https://docs.cloud.google.com/colab/docs/sql-cells). Now, with the\n", + "[%%bqsql cell\n", + "magics](https://dataframes.bigquery.dev/notebooks/getting_started/magics.html)\n", + "in BigQuery DataFrames, this same powerful interoperability is available to all\n", + "Jupyter users, whether you're in Colab, JupyterLab, or VS Code. These magics\n", + "allow you to write SQL queries that run directly on local pandas DataFrames,\n", + "BigFrames DataFrames, or BigQuery tables.\n", + "\n", + "\n", + "## Getting Started\n", + "\n", + "To get started,\n", + "\n", + "1. Enable the [BigQuery\n", + " sandbox](https://docs.cloud.google.com/bigquery/docs/sandbox). Make note of your\n", + " Google Cloud project ID.\n", + "\n", + "2. Set up a local Python development environment (see: [Setting up a Python\n", + " development environment](https://docs.cloud.google.com/python/docs/setup)) for\n", + " Google Cloud.\n", + "\n", + "3. Create and activate a venv to isolate Python dependencies.\n", + " On Linux or macOS, use these commands (update to your preferred Python\n", + " version):\n", + "\n", + " ```\n", + " python3.12 -m venv ~/venv\n", + " . ~/venv/bin/activate\n", + " ```\n", + "\n", + "4. Install the Jupyter, bigframes, and python-calamine packages:\n", + "\n", + " ```\n", + " pip install --upgrade jupyterlab bigframes python-calamine\n", + " ```\n", + "\n", + "5. Start Jupyter Lab.\n", + "\n", + " ```\n", + " jupyter lab\n", + " ```\n", + "\n", + "6. Open a web browser to the URL listed in the output. It will be something like\n", + " `http://localhost:8888/lab?token=somesupersecretvaluehere`.\n", + "\n", + "7. Create a new notebook using the Jupyter Lab UI.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d00aeb28", + "metadata": {}, + "outputs": [], + "source": [ + "%pip install python-calamine pandas bigframes" + ] + }, + { + "cell_type": "markdown", + "id": "5ba39d0d", + "metadata": {}, + "source": [ + "## Accessing the Dataset\n", + "\n", + "In this tutorial, you'll analyze the [USDA wheat\n", + "data](https://www.ers.usda.gov/data-products/wheat-data). Use the standard\n", + "`requests` package to download the data to a temporary file, mimicking a typical\n", + "local data analysis workflow.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "fb1dfdc2", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\n", + "import tempfile\n", + "\n", + "import requests\n", + "\n", + "url = \"https://www.ers.usda.gov/media/5706/wheat-data-all-years.xlsx?v=52690\"\n", + "\n", + "tmp = tempfile.NamedTemporaryFile(delete=True)\n", + "\n", + "with requests.get(url, stream=True) as r:\n", + " r.raise_for_status()\n", + " for chunk in r.iter_content(chunk_size=8192):\n", + " tmp.write(chunk)\n", + "\n", + "tmp.flush()\n", + "tmp.seek(0)" + ] + }, + { + "cell_type": "markdown", + "id": "50f896bb", + "metadata": {}, + "source": [ + "Use the `pyarrow` `dtype_backend` when preparing local Pandas data for SQL\n", + "processing. This ensures more consistent handling of NULL values and seamless\n", + "schema mapping when you hand off the data to the BigQuery SQL engine. For this\n", + "example, read the 'Table05' sheet, which contains annual wheat supply and\n", + "disappearance data:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "8a8a137b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Marketing year 1/Time periodBeginning stocksProductionImports 2/Total supply 3/Food useSeed useFeed and residual useTotal domestic use 3/Exports 2/Total disappearance 3/Ending stocks
01950/51MY Jun-May496.01019.011.01526.0580.0--109.0689.0345.01034.0492.0
11951/52MY Jun-May492.0988.030.01510.0585.0--110.0695.0485.01180.0330.0
21952/53MY Jun-May330.01306.024.01660.0578.0--78.0656.0332.0988.0672.0
31953/54MY Jun-May672.01173.06.01851.0556.0--87.0643.0214.0857.0994.0
41954/55MY Jun-May994.0984.03.01981.0552.0--53.0605.0267.0872.01109.0
..........................................
2811/ June–May. Latest data may be preliminary or...<NA><NA><NA><NA><NA><NA><NA><NA><NA><NA><NA><NA>
2822/ Includes flour and selected other products ...<NA><NA><NA><NA><NA><NA><NA><NA><NA><NA><NA><NA>
2833/ Totals may not add due to rounding.<NA><NA><NA><NA><NA><NA><NA><NA><NA><NA><NA><NA>
284Source: USDA, Economic Research Service, based...<NA><NA><NA><NA><NA><NA><NA><NA><NA><NA><NA><NA>
285Updated: May 12, 2026<NA><NA><NA><NA><NA><NA><NA><NA><NA><NA><NA><NA>
\n", + "

286 rows × 13 columns

\n", + "
" + ], + "text/plain": [ + " Marketing year 1/ Time period \\\n", + "0 1950/51 MY Jun-May \n", + "1 1951/52 MY Jun-May \n", + "2 1952/53 MY Jun-May \n", + "3 1953/54 MY Jun-May \n", + "4 1954/55 MY Jun-May \n", + ".. ... ... \n", + "281 1/ June–May. Latest data may be preliminary or... \n", + "282 2/ Includes flour and selected other products ... \n", + "283 3/ Totals may not add due to rounding. \n", + "284 Source: USDA, Economic Research Service, based... \n", + "285 Updated: May 12, 2026 \n", + "\n", + " Beginning stocks Production Imports 2/ Total supply 3/ Food use \\\n", + "0 496.0 1019.0 11.0 1526.0 580.0 \n", + "1 492.0 988.0 30.0 1510.0 585.0 \n", + "2 330.0 1306.0 24.0 1660.0 578.0 \n", + "3 672.0 1173.0 6.0 1851.0 556.0 \n", + "4 994.0 984.0 3.0 1981.0 552.0 \n", + ".. ... ... ... ... ... \n", + "281 \n", + "282 \n", + "283 \n", + "284 \n", + "285 \n", + "\n", + " Seed use Feed and residual use Total domestic use 3/ Exports 2/ \\\n", + "0 -- 109.0 689.0 345.0 \n", + "1 -- 110.0 695.0 485.0 \n", + "2 -- 78.0 656.0 332.0 \n", + "3 -- 87.0 643.0 214.0 \n", + "4 -- 53.0 605.0 267.0 \n", + ".. ... ... ... ... \n", + "281 \n", + "282 \n", + "283 \n", + "284 \n", + "285 \n", + "\n", + " Total disappearance 3/ Ending stocks \n", + "0 1034.0 492.0 \n", + "1 1180.0 330.0 \n", + "2 988.0 672.0 \n", + "3 857.0 994.0 \n", + "4 872.0 1109.0 \n", + ".. ... ... \n", + "281 \n", + "282 \n", + "283 \n", + "284 \n", + "285 \n", + "\n", + "[286 rows x 13 columns]" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\n", + "import pandas as pd\n", + "\n", + "df = pd.read_excel(\n", + " tmp,\n", + " sheet_name=\"Table05\",\n", + " dtype_backend=\"pyarrow\",\n", + " engine=\"calamine\",\n", + " header=1, # Skip the first row.\n", + ")\n", + "tmp.close()\n", + "df" + ] + }, + { + "cell_type": "markdown", + "id": "1a7ec573", + "metadata": {}, + "source": [ + "## Preparing the data\n", + "\n", + "Before querying the local DataFrame with SQL, ensure that the column names are\n", + "SQL-friendly. BigQuery supports [flexible column\n", + "names](https://docs.cloud.google.com/bigquery/docs/schemas#flexible-column-names),\n", + "allowing most unicode characters, but special characters like \"/\" and \"\\\" must\n", + "be removed or replaced.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "d5674020", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Marketing year 1Time periodBeginning stocksProductionImports 2Total supply 3Food useSeed useFeed and residual useTotal domestic use 3Exports 2Total disappearance 3Ending stocks
01950/51MY Jun-May496.01019.011.01526.0580.0--109.0689.0345.01034.0492.0
11951/52MY Jun-May492.0988.030.01510.0585.0--110.0695.0485.01180.0330.0
21952/53MY Jun-May330.01306.024.01660.0578.0--78.0656.0332.0988.0672.0
31953/54MY Jun-May672.01173.06.01851.0556.0--87.0643.0214.0857.0994.0
41954/55MY Jun-May994.0984.03.01981.0552.0--53.0605.0267.0872.01109.0
..........................................
2811/ June–May. Latest data may be preliminary or...<NA><NA><NA><NA><NA><NA><NA><NA><NA><NA><NA><NA>
2822/ Includes flour and selected other products ...<NA><NA><NA><NA><NA><NA><NA><NA><NA><NA><NA><NA>
2833/ Totals may not add due to rounding.<NA><NA><NA><NA><NA><NA><NA><NA><NA><NA><NA><NA>
284Source: USDA, Economic Research Service, based...<NA><NA><NA><NA><NA><NA><NA><NA><NA><NA><NA><NA>
285Updated: May 12, 2026<NA><NA><NA><NA><NA><NA><NA><NA><NA><NA><NA><NA>
\n", + "

286 rows × 13 columns

\n", + "
" + ], + "text/plain": [ + " Marketing year 1 Time period \\\n", + "0 1950/51 MY Jun-May \n", + "1 1951/52 MY Jun-May \n", + "2 1952/53 MY Jun-May \n", + "3 1953/54 MY Jun-May \n", + "4 1954/55 MY Jun-May \n", + ".. ... ... \n", + "281 1/ June–May. Latest data may be preliminary or... \n", + "282 2/ Includes flour and selected other products ... \n", + "283 3/ Totals may not add due to rounding. \n", + "284 Source: USDA, Economic Research Service, based... \n", + "285 Updated: May 12, 2026 \n", + "\n", + " Beginning stocks Production Imports 2 Total supply 3 Food use \\\n", + "0 496.0 1019.0 11.0 1526.0 580.0 \n", + "1 492.0 988.0 30.0 1510.0 585.0 \n", + "2 330.0 1306.0 24.0 1660.0 578.0 \n", + "3 672.0 1173.0 6.0 1851.0 556.0 \n", + "4 994.0 984.0 3.0 1981.0 552.0 \n", + ".. ... ... ... ... ... \n", + "281 \n", + "282 \n", + "283 \n", + "284 \n", + "285 \n", + "\n", + " Seed use Feed and residual use Total domestic use 3 Exports 2 \\\n", + "0 -- 109.0 689.0 345.0 \n", + "1 -- 110.0 695.0 485.0 \n", + "2 -- 78.0 656.0 332.0 \n", + "3 -- 87.0 643.0 214.0 \n", + "4 -- 53.0 605.0 267.0 \n", + ".. ... ... ... ... \n", + "281 \n", + "282 \n", + "283 \n", + "284 \n", + "285 \n", + "\n", + " Total disappearance 3 Ending stocks \n", + "0 1034.0 492.0 \n", + "1 1180.0 330.0 \n", + "2 988.0 672.0 \n", + "3 857.0 994.0 \n", + "4 872.0 1109.0 \n", + ".. ... ... \n", + "281 \n", + "282 \n", + "283 \n", + "284 \n", + "285 \n", + "\n", + "[286 rows x 13 columns]" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.columns = [name.replace(\"/\", \"\") for name in df.columns]\n", + "df" + ] + }, + { + "cell_type": "markdown", + "id": "b50c5798", + "metadata": {}, + "source": [ + "## Filtering with Pandas\n", + "\n", + "Perform a basic filter using standard Python/Pandas syntax to remove rows with missing data. This represents the initial Python-only stage of a processing chain.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "1dbad481", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Marketing year 1Time periodBeginning stocksProductionImports 2Total supply 3Food useSeed useFeed and residual useTotal domestic use 3Exports 2Total disappearance 3Ending stocks
01950/51MY Jun-May496.01019.011.01526.0580.0--109.0689.0345.01034.0492.0
11951/52MY Jun-May492.0988.030.01510.0585.0--110.0695.0485.01180.0330.0
21952/53MY Jun-May330.01306.024.01660.0578.0--78.0656.0332.0988.0672.0
31953/54MY Jun-May672.01173.06.01851.0556.0--87.0643.0214.0857.0994.0
41954/55MY Jun-May994.0984.03.01981.0552.0--53.0605.0267.0872.01109.0
..........................................
2752025/26MY Jun-May854.7341984.537125.02964.271960.059.7100.01119.7910.02029.7934.571
2762025/26Q1 Jun-Aug854.7341984.53730.5932869.864241.0912.653239.522483.266252.58735.8462134.018
2772025/26Q2 Sep-Nov2134.0180.030.0782164.096245.5839.658-54.047231.191255.802486.9931677.103
2782025/26Q3 Dec-Feb1677.1030.032.3631709.466230.9751.75-24.747207.978201.291409.2691300.197
2792026/27MY Jun-May934.5711561.322140.02635.893960.05980.01099.0775.01874.0761.893
\n", + "

280 rows × 13 columns

\n", + "
" + ], + "text/plain": [ + " Marketing year 1 Time period Beginning stocks Production Imports 2 \\\n", + "0 1950/51 MY Jun-May 496.0 1019.0 11.0 \n", + "1 1951/52 MY Jun-May 492.0 988.0 30.0 \n", + "2 1952/53 MY Jun-May 330.0 1306.0 24.0 \n", + "3 1953/54 MY Jun-May 672.0 1173.0 6.0 \n", + "4 1954/55 MY Jun-May 994.0 984.0 3.0 \n", + ".. ... ... ... ... ... \n", + "275 2025/26 MY Jun-May 854.734 1984.537 125.0 \n", + "276 2025/26 Q1 Jun-Aug 854.734 1984.537 30.593 \n", + "277 2025/26 Q2 Sep-Nov 2134.018 0.0 30.078 \n", + "278 2025/26 Q3 Dec-Feb 1677.103 0.0 32.363 \n", + "279 2026/27 MY Jun-May 934.571 1561.322 140.0 \n", + "\n", + " Total supply 3 Food use Seed use Feed and residual use \\\n", + "0 1526.0 580.0 -- 109.0 \n", + "1 1510.0 585.0 -- 110.0 \n", + "2 1660.0 578.0 -- 78.0 \n", + "3 1851.0 556.0 -- 87.0 \n", + "4 1981.0 552.0 -- 53.0 \n", + ".. ... ... ... ... \n", + "275 2964.271 960.0 59.7 100.0 \n", + "276 2869.864 241.091 2.653 239.522 \n", + "277 2164.096 245.58 39.658 -54.047 \n", + "278 1709.466 230.975 1.75 -24.747 \n", + "279 2635.893 960.0 59 80.0 \n", + "\n", + " Total domestic use 3 Exports 2 Total disappearance 3 Ending stocks \n", + "0 689.0 345.0 1034.0 492.0 \n", + "1 695.0 485.0 1180.0 330.0 \n", + "2 656.0 332.0 988.0 672.0 \n", + "3 643.0 214.0 857.0 994.0 \n", + "4 605.0 267.0 872.0 1109.0 \n", + ".. ... ... ... ... \n", + "275 1119.7 910.0 2029.7 934.571 \n", + "276 483.266 252.58 735.846 2134.018 \n", + "277 231.191 255.802 486.993 1677.103 \n", + "278 207.978 201.291 409.269 1300.197 \n", + "279 1099.0 775.0 1874.0 761.893 \n", + "\n", + "[280 rows x 13 columns]" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "full_rows = df[~df['Beginning stocks'].isna()]\n", + "full_rows" + ] + }, + { + "cell_type": "markdown", + "id": "e914ce69", + "metadata": {}, + "source": [ + "## Interoperate with SQL using the BigQuery SQL magics (%%bqsql)\n", + "\n", + "The BigQuery DataFrames library provides the `%%bqsql` magic, which acts as the bridge between your Python and SQL environments. It allows the BigQuery query engine to directly reference and query your local Pandas DataFrames (by implicitly uploading them as temporary tables) as well as actual BigQuery tables and external tables in GCS (Parquet, Iceberg, CSV).\n", + "\n", + "To enable this integration in your notebook, load the `bigframes` extension. This is already completed in BigQuery Studio, Colab Enterprise, and Colab notebooks. For other environments, such as VS Code and Jupyter Lab, run the following cell:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "3d837a5e", + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext bigframes\n" + ] + }, + { + "cell_type": "markdown", + "id": "315a53b5", + "metadata": {}, + "source": [ + "To ensure the correct Google Cloud project is billed for query usage, including free tier usage, configure the project ID used by the magics. Even in the free sandbox tier, a project ID is required to allocate query resources. If you don't set it explicitly, BigFrames will try to discover it from your environment (e.g., your Application Default Credentials).\n" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "ffe5757c", + "metadata": {}, + "outputs": [], + "source": [ + "import bigframes.pandas as bpd\n", + "\n", + "PROJECT_ID = \"\" # @param {type:\"string\"}\n", + "bpd.options.bigquery.project = PROJECT_ID\n" + ] + }, + { + "cell_type": "markdown", + "id": "fe174ed2", + "metadata": {}, + "source": [ + "### Querying Local Pandas DataFrames with SQL\n", + "\n", + "With the project configured, you can now run SQL queries directly against your local Pandas DataFrame (`full_rows`) as if it were a table in BigQuery. Simply reference the variable name inside braces `{full_rows}` in your SQL query.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "fbbf52d6", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " Query processed 0 Bytes. [Job bigframes-dev:US.c3c67902-6a45-492a-9491-a91daddaada1 details]\n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Load job c22ec1ce-09da-4ea1-b0a0-f28eee65aa20 is DONE. Open Job" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n", + " Query processed 30.0 kB in a moment of slot time.\n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Marketing year 1Time periodBeginning stocksProductionImports 2Total supply 3Food useSeed useFeed and residual useTotal domestic use 3Exports 2Total disappearance 3Ending stocks
01980/81Q2 Sep-Nov2714.00.00.62714.6162.1764.865242.965379.335622.32092.3
11987/88Q2 Sep-Nov2976.4620.04.5252980.987193.04858-79.082171.966308.453480.4192500.568
22014/15Q2 Sep-Nov1907.220.034.5511941.771248.18748.802-92.585204.404207.737412.1411529.63
31976/77Q2 Sep-Nov2385.20.00.52385.7153.064-2.795214.205277.295491.51894.2
41994/95Q2 Sep-Nov2069.4940.021.4232090.917229.29760.954-28.64261.611338.202599.8131491.104
52002/03Q2 Sep-Nov1748.9870.023.0871772.074237.75454.599-74.678217.675234.53452.2051319.869
62007/08Q2 Sep-Nov1716.9270.021.4861738.413245.02659.915-119.882185.059421.416606.4751131.938
72025/26Q2 Sep-Nov2134.0180.030.0782164.096245.5839.658-54.047231.191255.802486.9931677.103
81995/96Q2 Sep-Nov1881.0990.016.2521897.351232.15164.356-98.182198.325360.759559.0841338.267
92001/02Q2 Sep-Nov2155.8140.029.042184.854245.08851.601-23.073273.616287.783561.3991623.455
\n", + "

10 rows × 13 columns

\n", + "
[280 rows x 13 columns in total]" + ], + "text/plain": [ + " Marketing year 1 Time period Beginning stocks Production Imports 2 \\\n", + "0 1980/81 Q2 Sep-Nov 2714.0 0.0 0.6 \n", + "1 1987/88 Q2 Sep-Nov 2976.462 0.0 4.525 \n", + "2 2014/15 Q2 Sep-Nov 1907.22 0.0 34.551 \n", + "3 1976/77 Q2 Sep-Nov 2385.2 0.0 0.5 \n", + "4 1994/95 Q2 Sep-Nov 2069.494 0.0 21.423 \n", + "5 2002/03 Q2 Sep-Nov 1748.987 0.0 23.087 \n", + "6 2007/08 Q2 Sep-Nov 1716.927 0.0 21.486 \n", + "7 2025/26 Q2 Sep-Nov 2134.018 0.0 30.078 \n", + "8 1995/96 Q2 Sep-Nov 1881.099 0.0 16.252 \n", + "9 2001/02 Q2 Sep-Nov 2155.814 0.0 29.04 \n", + "\n", + " Total supply 3 Food use Seed use Feed and residual use \\\n", + "0 2714.6 162.1 76 4.865 \n", + "1 2980.987 193.048 58 -79.082 \n", + "2 1941.771 248.187 48.802 -92.585 \n", + "3 2385.7 153.0 64 -2.795 \n", + "4 2090.917 229.297 60.954 -28.64 \n", + "5 1772.074 237.754 54.599 -74.678 \n", + "6 1738.413 245.026 59.915 -119.882 \n", + "7 2164.096 245.58 39.658 -54.047 \n", + "8 1897.351 232.151 64.356 -98.182 \n", + "9 2184.854 245.088 51.601 -23.073 \n", + "\n", + " Total domestic use 3 Exports 2 Total disappearance 3 Ending stocks \n", + "0 242.965 379.335 622.3 2092.3 \n", + "1 171.966 308.453 480.419 2500.568 \n", + "2 204.404 207.737 412.141 1529.63 \n", + "3 214.205 277.295 491.5 1894.2 \n", + "4 261.611 338.202 599.813 1491.104 \n", + "5 217.675 234.53 452.205 1319.869 \n", + "6 185.059 421.416 606.475 1131.938 \n", + "7 231.191 255.802 486.993 1677.103 \n", + "8 198.325 360.759 559.084 1338.267 \n", + "9 273.616 287.783 561.399 1623.455 \n", + "...\n", + "\n", + "[280 rows x 13 columns]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%%bqsql\n", + "SELECT * FROM {full_rows}\n" + ] + }, + { + "cell_type": "markdown", + "id": "2fcd5284", + "metadata": {}, + "source": [ + "You should see the results from full_rows.\n", + "\n", + "\n", + "## Chaining SQL and Python: Saving SQL Results\n", + "\n", + "The true power of the `%%bqsql` magic lies in chaining. By providing a destination variable name as an argument to `%%bqsql` (e.g., `%%bqsql destination_var`), the query result is saved as a BigQuery DataFrame (a.k.a. BigFrames DataFrame) to that variable. \n", + "\n", + "This DataFrame lives on the BigQuery engine but behaves like a Pandas DataFrame in Python. You can immediately use it in subsequent Python cells, or reference it again in another SQL cell. This allows you to build a multi-step, hybrid processing pipeline.\n", + "\n", + "Filter the data to only yearly entries using SQL, and save the result into a new BigFrames DataFrame named `yearly`:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "75fe0e10", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " Query processed 0 Bytes in a moment of slot time. [Job bigframes-dev:US.71850fc1-147f-44f7-b4c0-b94592f55639 details]\n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Load job aaa74c26-b3ff-422f-a670-93222188fe9f is DONE. Open Job" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n", + " Query processed 30.0 kB in a moment of slot time.\n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Marketing year 1Time periodBeginning stocksProductionImports 2Total supply 3Food useSeed useFeed and residual useTotal domestic use 3Exports 2Total disappearance 3Ending stocks
01955/56MY Jun-May1109.0937.010.02056.0553.0--51.0604.0322.0926.01130.0
11957/58MY Jun-May1004.0956.010.01970.0547.0--43.0590.0418.01008.0962.0
21954/55MY Jun-May994.0984.03.01981.0552.0--53.0605.0267.0872.01109.0
31951/52MY Jun-May492.0988.030.01510.0585.0--110.0695.0485.01180.0330.0
41956/57MY Jun-May1130.01005.08.02143.0541.0--57.0598.0541.01139.01004.0
51950/51MY Jun-May496.01019.011.01526.0580.0--109.0689.0345.01034.0492.0
61962/63MY Jun-May1420.61092.05.32517.9502.761.434.7598.8649.41248.21269.7
71959/60MY Jun-May1368.01118.07.02493.0558.0--49.0607.0502.01109.01384.0
81963/64MY Jun-May1269.71146.84.02420.5487.964.928.6581.4845.61427.0993.5
91953/54MY Jun-May672.01173.06.01851.0556.0--87.0643.0214.0857.0994.0
\n", + "

10 rows × 13 columns

\n", + "
[77 rows x 13 columns in total]" + ], + "text/plain": [ + " Marketing year 1 Time period Beginning stocks Production Imports 2 \\\n", + "0 1955/56 MY Jun-May 1109.0 937.0 10.0 \n", + "1 1957/58 MY Jun-May 1004.0 956.0 10.0 \n", + "2 1954/55 MY Jun-May 994.0 984.0 3.0 \n", + "3 1951/52 MY Jun-May 492.0 988.0 30.0 \n", + "4 1956/57 MY Jun-May 1130.0 1005.0 8.0 \n", + "5 1950/51 MY Jun-May 496.0 1019.0 11.0 \n", + "6 1962/63 MY Jun-May 1420.6 1092.0 5.3 \n", + "7 1959/60 MY Jun-May 1368.0 1118.0 7.0 \n", + "8 1963/64 MY Jun-May 1269.7 1146.8 4.0 \n", + "9 1953/54 MY Jun-May 672.0 1173.0 6.0 \n", + "\n", + " Total supply 3 Food use Seed use Feed and residual use \\\n", + "0 2056.0 553.0 -- 51.0 \n", + "1 1970.0 547.0 -- 43.0 \n", + "2 1981.0 552.0 -- 53.0 \n", + "3 1510.0 585.0 -- 110.0 \n", + "4 2143.0 541.0 -- 57.0 \n", + "5 1526.0 580.0 -- 109.0 \n", + "6 2517.9 502.7 61.4 34.7 \n", + "7 2493.0 558.0 -- 49.0 \n", + "8 2420.5 487.9 64.9 28.6 \n", + "9 1851.0 556.0 -- 87.0 \n", + "\n", + " Total domestic use 3 Exports 2 Total disappearance 3 Ending stocks \n", + "0 604.0 322.0 926.0 1130.0 \n", + "1 590.0 418.0 1008.0 962.0 \n", + "2 605.0 267.0 872.0 1109.0 \n", + "3 695.0 485.0 1180.0 330.0 \n", + "4 598.0 541.0 1139.0 1004.0 \n", + "5 689.0 345.0 1034.0 492.0 \n", + "6 598.8 649.4 1248.2 1269.7 \n", + "7 607.0 502.0 1109.0 1384.0 \n", + "8 581.4 845.6 1427.0 993.5 \n", + "9 643.0 214.0 857.0 994.0 \n", + "...\n", + "\n", + "[77 rows x 13 columns]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%%bqsql yearly\n", + "SELECT *\n", + "FROM {full_rows}\n", + "WHERE STARTS_WITH(`Time period`, 'MY')\n" + ] + }, + { + "cell_type": "markdown", + "id": "19a70e9e", + "metadata": {}, + "source": [ + "### Chaining Step 2: Complex SQL Transformation on the BigFrames DataFrame\n", + "\n", + "Now, you can chain another SQL operation. Reference the `yearly` BigFrames DataFrame that you just created, extract the year using SQL regular expressions, cast it to a timestamp, and save the results into a new BigFrames DataFrame named `timeseries`.\n", + "\n", + "Notice how you are building a chain: Local Pandas -> [SQL filter] -> BigFrames `yearly` -> [SQL transform] -> BigFrames `timeseries`.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "8fbb5224", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " Query processed 0 Bytes in a moment of slot time. [Job bigframes-dev:US.fdcdabc9-e1a3-47e6-ab27-9e19d9aaa106 details]\n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Load job ec6be16a-722d-4151-b7a6-5e410557577d is DONE. Open Job" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n", + " Query processed 8.3 kB in a moment of slot time.\n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Time periodBeginning stocksProductionImports 2Total supply 3Food useSeed useFeed and residual useTotal domestic use 3Exports 2Total disappearance 3Ending stocksyear
0MY Jun-May1004.0956.010.01970.0547.0--43.0590.0418.01008.0962.01957-01-01 00:00:00+00:00
1MY Jun-May672.01173.06.01851.0556.0--87.0643.0214.0857.0994.01953-01-01 00:00:00+00:00
2MY Jun-May496.01019.011.01526.0580.0--109.0689.0345.01034.0492.01950-01-01 00:00:00+00:00
3MY Jun-May330.01306.024.01660.0578.0--78.0656.0332.0988.0672.01952-01-01 00:00:00+00:00
4MY Jun-May962.01457.08.02427.0561.0--48.0609.0450.01059.01368.01958-01-01 00:00:00+00:00
5MY Jun-May994.0984.03.01981.0552.0--53.0605.0267.0872.01109.01954-01-01 00:00:00+00:00
6MY Jun-May492.0988.030.01510.0585.0--110.0695.0485.01180.0330.01951-01-01 00:00:00+00:00
7MY Jun-May1130.01005.08.02143.0541.0--57.0598.0541.01139.01004.01956-01-01 00:00:00+00:00
8MY Jun-May1109.0937.010.02056.0553.0--51.0604.0322.0926.01130.01955-01-01 00:00:00+00:00
9MY Jun-May1368.01118.07.02493.0558.0--49.0607.0502.01109.01384.01959-01-01 00:00:00+00:00
\n", + "

10 rows × 13 columns

\n", + "
[77 rows x 13 columns in total]" + ], + "text/plain": [ + " Time period Beginning stocks Production Imports 2 Total supply 3 \\\n", + "0 MY Jun-May 1004.0 956.0 10.0 1970.0 \n", + "1 MY Jun-May 672.0 1173.0 6.0 1851.0 \n", + "2 MY Jun-May 496.0 1019.0 11.0 1526.0 \n", + "3 MY Jun-May 330.0 1306.0 24.0 1660.0 \n", + "4 MY Jun-May 962.0 1457.0 8.0 2427.0 \n", + "5 MY Jun-May 994.0 984.0 3.0 1981.0 \n", + "6 MY Jun-May 492.0 988.0 30.0 1510.0 \n", + "7 MY Jun-May 1130.0 1005.0 8.0 2143.0 \n", + "8 MY Jun-May 1109.0 937.0 10.0 2056.0 \n", + "9 MY Jun-May 1368.0 1118.0 7.0 2493.0 \n", + "\n", + " Food use Seed use Feed and residual use Total domestic use 3 Exports 2 \\\n", + "0 547.0 -- 43.0 590.0 418.0 \n", + "1 556.0 -- 87.0 643.0 214.0 \n", + "2 580.0 -- 109.0 689.0 345.0 \n", + "3 578.0 -- 78.0 656.0 332.0 \n", + "4 561.0 -- 48.0 609.0 450.0 \n", + "5 552.0 -- 53.0 605.0 267.0 \n", + "6 585.0 -- 110.0 695.0 485.0 \n", + "7 541.0 -- 57.0 598.0 541.0 \n", + "8 553.0 -- 51.0 604.0 322.0 \n", + "9 558.0 -- 49.0 607.0 502.0 \n", + "\n", + " Total disappearance 3 Ending stocks year \n", + "0 1008.0 962.0 1957-01-01 00:00:00+00:00 \n", + "1 857.0 994.0 1953-01-01 00:00:00+00:00 \n", + "2 1034.0 492.0 1950-01-01 00:00:00+00:00 \n", + "3 988.0 672.0 1952-01-01 00:00:00+00:00 \n", + "4 1059.0 1368.0 1958-01-01 00:00:00+00:00 \n", + "5 872.0 1109.0 1954-01-01 00:00:00+00:00 \n", + "6 1180.0 330.0 1951-01-01 00:00:00+00:00 \n", + "7 1139.0 1004.0 1956-01-01 00:00:00+00:00 \n", + "8 926.0 1130.0 1955-01-01 00:00:00+00:00 \n", + "9 1109.0 1384.0 1959-01-01 00:00:00+00:00 \n", + "...\n", + "\n", + "[77 rows x 13 columns]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%%bqsql timeseries\n", + "SELECT\n", + " * EXCEPT (`Marketing year 1`),\n", + " TIMESTAMP(CONCAT(\n", + " REGEXP_EXTRACT(`Marketing year 1`, r'([0-9]+)\\/'),\n", + " '-01-01')) AS `year`\n", + "FROM {yearly}\n" + ] + }, + { + "cell_type": "markdown", + "id": "76ba8a7d", + "metadata": {}, + "source": [ + "## Chaining Back to Python: Visualizing BigFrames Data\n", + "\n", + "Now that you've completed some SQL transformations, you can chain back to Python for visualization. Because BigFrames DataFrames implement the Pandas API, you can call standard visualization methods (like `.plot.line()`) directly on the `timeseries` DataFrame without downloading the full dataset first. The computations happen in BigQuery, and only the summarized chart data is sent back to the notebook.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "d3ff4eec", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " Query processed 8.8 kB in a moment of slot time.\n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Load job c6b4d65a-4555-4efc-9f8b-7156f4c62835 is DONE. Open Job" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjAAAAGwCAYAAAC3qV8qAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjksIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvJkbTWQAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzsnXd4FGXXh+/Zmk3Z9JCEBAiE3psSUKlSBARBxPJRFPRFUcQCigVFVCxgVywooIgKFlREigioFEGQIqGGQAIklPS2fb4/Zneym56QkATmvq65ksw8M/PMbnbnzDm/c44giqKIgoKCgoKCgkI9QlXbE1BQUFBQUFBQqCyKAaOgoKCgoKBQ71AMGAUFBQUFBYV6h2LAKCgoKCgoKNQ7FANGQUFBQUFBod6hGDAKCgoKCgoK9Q7FgFFQUFBQUFCod2hqewI1hcPh4OzZs/j5+SEIQm1PR0FBQUFBQaECiKJITk4OkZGRqFSl+1muWAPm7NmzREdH1/Y0FBQUFBQUFKpAcnIyUVFRpW6/Yg0YPz8/QHoBjEZjLc9GQUFBQUFBoSJkZ2cTHR0t38dL44o1YFxhI6PRqBgwCgoKCgoK9Yzy5B+KiFdBQUFBQUGh3qEYMAoKCgoKCgr1DsWAUVBQUFBQUKh3XLEamIpit9uxWq21PQ0FhTqHVqtFrVbX9jQUFBQUSuSqNWBEUSQ1NZXMzMzanoqCQp0lICCA8PBwpZaSgoJCneOqNWBcxktYWBje3t7KF7SCghuiKJKfn8/58+cBiIiIqOUZKSgoKHhyVRowdrtdNl6Cg4NrezoKCnUSg8EAwPnz5wkLC1PCSQoKCnWKq1LE69K8eHt71/JMFBTqNq7PiKITU1BQqGtclQaMCyVspKBQNspnREFBoa5yVRswCgoKCgoKCvUTxYBRUFBQUFBQqHcoBoxCifTp04fp06dX6zGXLFlCQEBAtR6zrlATr5eCgoKCQulckgHzyiuvIAiCxxe3yWRi6tSpBAcH4+vry+jRozl37pzHfklJSQwdOhRvb2/CwsKYMWMGNpvNY8zmzZvp0qULer2e2NhYlixZcilTvSKYOHEigiDIS3BwMIMHD2b//v3Vfq7vv/+euXPnVusxx44dy9GjR6v1mJXlSjai6jOixYLDYqntaSgoKNQjqmzA7Nq1i48++ogOHTp4rH/kkUf4+eefWblyJVu2bOHs2bOMGjVK3m632xk6dCgWi4Vt27axdOlSlixZwuzZs+UxiYmJDB06lL59+7J3716mT5/O5MmTWbduXVWne8UwePBgUlJSSElJYePGjWg0GoYNG1bt5wkKCiq3lXllMRgMhIWFVesxFeo/jrw8EobcxInBQ7AkJdX2dBQUFOoLYhXIyckRmzdvLm7YsEHs3bu3+PDDD4uiKIqZmZmiVqsVV65cKY89dOiQCIjbt28XRVEU16xZI6pUKjE1NVUes3DhQtFoNIpms1kURVGcOXOm2LZtW49zjh07Vhw0aFCpczKZTGJWVpa8JCcni4CYlZVVbGxBQYEYHx8vFhQUiKIoig6HQ8wzW2tlcTgcFX7dJ0yYII4YMcJj3Z9//ikC4vnz5+V1SUlJ4pgxY0R/f38xMDBQvPnmm8XExER5u9VqFR966CHR399fDAoKEmfOnCmOHz/e49ju76soimLjxo3Fl156Sbz77rtFX19fMTo6Wvzoo4/k7YmJiSIgfvfdd2KfPn1Eg8EgdujQQdy2bZs8ZvHixaK/v7/893PPPSd27NhR/Pzzz8XGjRuLRqNRHDt2rJidnS2Pyc7OFu+8807R29tbDA8PF994441icyvK3r17xT59+oi+vr6in5+f2KVLF3HXrl3ipk2bRMBjee6550RRFMX09HRx3LhxYkBAgGgwGMTBgweLR48e9TjuX3/9Jfbu3Vs0GAxiQECAOHDgQDE9Pb3E12v16tWi0WgUly1bJoqiKG7atEns3r276O3tLfr7+4s9e/YUT548Weo11BWKflYqgi07W0x+eLp4cvwE0ZaTU+74i4sXi/EtW4nxLVuJR/v0Fc3JyZcyZQUFhXpOVlZWqfdvd6pUyG7q1KkMHTqUAQMG8OKLL8rrd+/ejdVqZcCAAfK6Vq1a0ahRI7Zv306PHj3Yvn077du3p0GDBvKYQYMGcf/993Pw4EE6d+7M9u3bPY7hGlOWxmDevHnMmTOnKpdDgdVOm9m1492Jf2EQ3rqq1RPMzc1l2bJlxMbGygX5rFYrgwYNIi4ujj///BONRsOLL74oh5p0Oh2vvvoqX375JYsXL6Z169a8/fbbrFq1ir59+5Z5vgULFjB37lyeeuopvv32W+6//3569+5Ny5Yt5TFPP/008+fPp3nz5jz99NPccccdHD9+HI2m5GtMSEhg1apVrF69moyMDG677TZeeeUVXnrpJQAeffRRtm7dyk8//USDBg2YPXs2e/bsoVOnTqXO86677qJz584sXLgQtVrN3r170Wq19OzZk7feeovZs2dz5MgRAHx9fQEpPHfs2DF++uknjEYjTzzxBDfddBPx8fFotVr27t1L//79ueeee3j77bfRaDRs2rQJu91e7PzLly9nypQpLF++nGHDhmGz2Rg5ciT33nsvX331FRaLhZ07d16RKcrW8+dJvu9/mA8fBiB96VJCp04tdbxosZC+eAkAKh8fbCkpJE2YSOPPl6Jt2PByTFlBQaGeUuk759dff82ePXvYtWtXsW2pqanodLpiGoMGDRqQmpoqj3E3XlzbXdvKGpOdnU1BQYFcIdSdWbNm8eijj8p/Z2dnEx0dXdnLq/OsXr1avunm5eURERHB6tWrUamkaOA333yDw+Fg0aJF8g1y8eLFBAQEsHnzZgYOHMi7777LrFmzuOWWWwB47733WLNmTbnnvummm3jggQcAeOKJJ3jzzTfZtGmThwHz+OOPM3ToUADmzJlD27ZtOX78OK1atSrxmA6HgyVLlsjhqnHjxrFx40ZeeuklcnJyWLp0KcuXL6d///7ytURGRpY5z6SkJGbMmCGfs3nz5vI2f39/BEEgPDxcXucyXLZu3UrPnj0B+PLLL4mOjmbVqlWMGTOG1157jW7duvHBBx/I+7Vt27bYud9//32efvppfv75Z3r37g1I/4tZWVkMGzaMZs2aAdC6desyr6E+Yjl5kqRJk7GeOYNgMCAWFJC+eAlBd92FuhTdUdbPq7GdO4cmNJTGX31F8qRJWE6d4tTEu2n8xedo3d4nBQUFBXcqZcAkJyfz8MMPs2HDBry8vGpqTlVCr9ej1+urtK9Bqyb+hUHVPKOKn7sy9O3bl4ULFwKQkZHBBx98wJAhQ9i5cyeNGzdm3759HD9+vJh+xWQykZCQQFZWFufOneOaa66Rt6nVarp27YrD4Sjz3O56J5cR4OqVU9IYV/+c8+fPl2rANGnSxGOuERER8jFPnDiB1Wr1mKu/v7+HwVQSjz76KJMnT+aLL75gwIABjBkzRjYcSuLQoUNoNBquvfZaeV1wcDAtW7bk0KFDAOzdu5cxY8aUed5vv/2W8+fPs3XrVrp37y6vDwoKYuLEiQwaNIgbb7yRAQMGcNttt11R/YUKDvxH8v/+hz09HW2jRjT65GNOPzwd8+HDpH36GWGPPVpsH9HhIG3RIgCCJk5EF9WQRkuXcGrceKzJyZyaMIHGn3+BtoGim1JQUChOpUS8u3fv5vz583Tp0gWNRoNGo2HLli288847aDQaGjRogMViKdbh+dy5c/ITb3h4eLGsJNff5Y0xGo0lel8uFUEQ8NZpamWpbBjBx8eH2NhYYmNj6d69O4sWLSIvL49PPvkEkMJKXbt2Ze/evR7L0aNHufPOOy/pddJqtcVet6JGj/sY17WVZRhV5JiV5fnnn+fgwYMMHTqU33//nTZt2vDDDz9c0jEr8n/XuXNnQkND+eyzzxBF0WPb4sWL2b59Oz179uSbb76hRYsW7Nix45LmVFfI3bqVUxMmYE9Px6tNG5os/xJd48aETpsGQPqyZdguXiy2X87GjVgSE1EZjQSMvQ0AbXg4jZcuQduwIdZTSSRNmIC1iJGsoKCgAJU0YPr378+BAwc8bozdunXjrrvukn/XarVs3LhR3ufIkSMkJSURFxcHQFxcHAcOHPB4ct+wYQNGo5E2bdrIY9yP4RrjOoZCIYIgoFKpKCgoAKBLly4cO3aMsLAw2dBxLf7+/vj7+9OgQQOPEKDdbmfPnj21dQml0rRpU7Rarcdcs7KyKpSK3aJFCx555BHWr1/PqFGjWLx4MQA6na6YbqV169bYbDb+/vtveV1aWhpHjhyR/yc7dOhQ7H+yKM2aNWPTpk38+OOPPPTQQ8W2d+7cmVmzZrFt2zbatWvH8uXLy72OuoQ9Nw9zYiL5u3aRvWYN6Z9/zrl580iecj9ifj7ecT1o9PlSNCEhAPj27YNXhw6IBQVc/Phjj2OJokjaJ5L3JfDOO1A7w6IA2shIGi1diiYyAsvJk5x5pLj3RkFBQaFSISQ/Pz/atWvnsc7Hx4fg4GB5/aRJk3j00UcJCgrCaDTy0EMPERcXR48ePQAYOHAgbdq0Ydy4cbz22mukpqbyzDPPMHXqVDkENGXKFN577z1mzpzJPffcw++//86KFSv45ZdfquOa6zVms1nWCmVkZPDee++Rm5vL8OHDAUnA+vrrrzNixAheeOEFoqKiOHXqFN9//z0zZ84kKiqKhx56iHnz5hEbG0urVq149913ycjIqHOiUj8/PyZMmMCMGTMICgoiLCyM5557DpVKVepcCwoKmDFjBrfeeisxMTGcPn2aXbt2MXr0aEAKWeXm5rJx40Y6duyIt7c3zZs3Z8SIEdx777189NFH+Pn58eSTT9KwYUNGjBgBSBqr9u3b88ADDzBlyhR0Oh2bNm1izJgxhDhv2CAZTps2baJPnz5oNBreeustEhMT+fjjj7n55puJjIzkyJEjHDt2jPHjx9f8i1hNXFj4IbkffVTqdr8hg4l89VVUOp28ThAEwqY/TNI9k8j86muC774brTNslv/3Tkz79yPo9QSNG1fseLqohkR/+CGJN4+gYM8eRLsdQemGraCg4EbV0l/K4M0330SlUjF69GjMZjODBg3yED6q1WpWr17N/fffT1xcHD4+PkyYMIEXXnhBHhMTE8Mvv/zCI488wttvv01UVBSLFi1i0KDa0anUJdauXStrJ/z8/GjVqhUrV66kT58+gNQ9+I8//uCJJ55g1KhR5OTk0LBhQ/r374/RaAQkAW5qairjx49HrVZz3333MWjQINR18AbxxhtvMGXKFIYNG4bRaGTmzJkkJyeXqsFSq9WkpaUxfvx4zp07R0hICKNGjZIz1Hr27MmUKVMYO3YsaWlpPPfcczz//PMsXryYhx9+mGHDhmGxWLjhhhtYs2aNHOJq0aIF69ev56mnnuKaa67BYDBw7bXXcscddxSbQ8uWLfn999/p06cParWamTNncvjwYZYuXUpaWhoRERFMnTqV//3vfzX3wlUjos1G9urVqACVtzfq0BA0oaHSEhKKV6tW+N8yEkFV3KHrHReH9zXXkL9zJxcXfkjEC9L7kOb0yASMHo3GmUFXFH1MjHMCIvbMzFLHKSgoXJ0IYtFg/RVCdnY2/v7+ZGVlyTduFyaTicTERGJiYuqcGLk2cDgctG7dmttuu63aq+9WN3l5eTRs2JAFCxYwadKk2p7OFY/JZOL4v/8iPPU0fs2a0WjRJ5U+Rv6ePZy68y7QaGi25hfs2TmcvPVWUKtptm4tuqioUvc9em0P7FlZNP35J/Ru2WQKCgpXLmXdv92pdg+MQt3n1KlTrF+/nt69e2M2m3nvvfdITEy8ZJFvTfDvv/9y+PBhrrnmGrKysmRPnSu0o1CziDYbjoIC1EDw5KoZjN5duuBzw/Xk/fEnF99/H4dZahlgvOmmMo0XAHVQEPasLGzpGVQtx1BBQeFKRTFgrkJUKhVLlizh8ccfRxRF2rVrx2+//VZna5PMnz+fI0eOoNPp6Nq1K3/++aeH7kSh5rBlZYEooo+NxdstzbyyhE57mLw//iTrp5/ldcGTJ5e7nzooCBITsaenVfncCgoKVyaKAXMVEh0dzdatW2t7GhWic+fO7N69u7ancVUiOhw4nCUR/EePuiSRt6FdW/xuvJGcDRsA8O3dG6+WLcrdTxMUBIAtPb3K51ZQULgyuaRu1AoKClcu9owMRLsd1Gp8r7vuko8XOu0hcBpBwffdW6F91E4Dxp6eccnnV1BQuLJQPDAKCgrFEEURW5oUtlH7+CCU0suqMuibN6fhGwuw5+bi3bVrhfbRBLs8MEoISUFBwRPFgFFQUCiGIzsb0WJBUKsRvL2r7bjGIUMqNV4dqHhgFBQUSkYJISkoKHggiqJc+l/l719ifZfLhTooEAB7muKBUVBQ8EQxYBQUFDxw5OfjKCgAQUBTShfpy4WreJ0tQ/HAKCgoeKIYMAolMnHiREaOHFnj52nSpAlvvfVWjZ9HoeLYnd4XdUBgtWhfLoXCEJKShaSgoOCJYsDUMyZOnIggCAiCgE6nIzY2lhdeeAGbzVbbUyuTJUuWEFDC0/yuXbu47777Lv+EFErEYTJhz8kBQBNS+6X7Na4QUmamlBGloKCg4EQxYOohgwcPJiUlhWPHjvHYY4/x/PPP8/rrrxcbZ7FYamF2lSM0NBTvahSJKlwatjTJ06E2GlHpa7/2rTpQMmBc/ZAUFBQUXCgGTD1Er9cTHh5O48aNuf/++xkwYAA//fSTHPZ56aWXiIyMpGXLlgAcOHCAfv36YTAYCA4O5r777iM3N1c+nt1u59FHHyUgIIDg4GBmzpxJ0RZZJYV6OnXqxPPPPy//nZmZyf/+9z8aNGiAl5cX7dq1Y/Xq1WzevJm7776brKws2Xvk2q/ocZOSkhgxYgS+vr4YjUZuu+02zp07J29//vnn6dSpE1988QVNmjTB39+f22+/nRyn10Dh0hAL8gFQ17L2xYWg0aD29weUMJKCgoInigEDIIpgyaudpRp6aRoMBtnbsnHjRo4cOcKGDRtYvXo1eXl5DBo0iMDAQHbt2sXKlSv57bffePDBB+X9FyxYwJIlS/jss8/466+/SE9P54cffqjUHBwOB0OGDGHr1q0sW7aM+Ph4XnnlFdRqNT179uStt97CaDSSkpJCSkoKjz/+eInHGDFiBOnp6WzZsoUNGzZw4sQJxo4d6zEuISGBVatWsXr1alavXs2WLVt45ZVXqvDKKbgjiiIO5/+RUAe8Ly7ULiFvmmLAKCgoFKLUgQGw5sPLkbVz7qfOgs6nSruKosjGjRtZt24dDz30EBcuXMDHx4dFixah0+kA+OSTTzCZTHz++ef4+Ejnee+99xg+fDivvvoqDRo04K233mLWrFmMGjUKgA8//JB169ZVai6//fYbO3fu5NChQ7RoIZWIb9q0qbzd398fQRAIDw8v9RgbN27kwIEDJCYmEh0dDcDnn39O27Zt2bVrF927dwckQ2fJkiX4+fkBMG7cODZu3MhLL71UqTkreCLabOBwAAKCVlvb05FRBwXCCbBnKAaMgoJCIYoHph6yevVqfH198fLyYsiQIYwdO1YOybRv3142XgAOHTpEx44dZeMFoFevXjgcDo4cOUJWVhYpKSlc69aoT6PR0K1bt0rNae/evURFRcnGS1U4dOgQ0dHRsvEC0KZNGwICAjh06JC8rkmTJrLxAhAREcH58+erfF4FCdHlfdFpa7X2S1E0gUo/JAUFheIoHhgArbfkCamtc1eSvn37snDhQnQ6HZGRkWjcUl3dDZXqRKVSFdPFWK1W+XeDwVAj5y0JbRHvgCAIOByOy3b+KxXRbAZAcDOA6wJqZzsBuxJCUlBQcKPuPGbVJoIghXFqY6lCh18fHx9iY2Np1KiRh/FSEq1bt2bfvn3k5eXJ67Zu3YpKpaJly5b4+/sTERHB33//LW+32WzFOkCHhoaSkpIi/52dnU1iYqL8d4cOHTh9+jRHjx4tcR46nQ57OWmwrVu3Jjk5meTkZHldfHw8mZmZtGnTpsx9FS4dlwdGpas7+hdw60ithJAUFBTcUAyYK5y77roLLy8vJkyYwH///cemTZt46KGHGDduHA0aNADg4Ycf5pVXXmHVqlUcPnyYBx54gMwiKav9+vXjiy++4M8//+TAgQNMmDABtVotb+/duzc33HADo0ePZsOGDSQmJvLrr7+ydu1aQAr75ObmsnHjRi5evEh+fn6xuQ4YMID27dtz1113sWfPHnbu3Mn48ePp3bt3pUNaCpVHDiHp65gHJlDxwCgoKBRHMWCucLy9vVm3bh3p6el0796dW2+9lf79+/Pee+/JYx577DHGjRvHhAkTiIuLw8/Pj1tuucXjOLNmzaJ3794MGzaMoUOHMnLkSJo1a+Yx5rvvvqN79+7ccccdtGnThpkzZ8pel549ezJlyhTGjh1LaGgor732WrG5CoLAjz/+SGBgIDfccAMDBgygadOmfPPNNzXwyigUpa6GkFwdqZU0agUFBXcEsaiw4QohOzsbf39/srKyMBqNHttMJhOJiYnExMTg5eVVSzNUUKg7iKKIKT4eRBF98+ZyEbu68FnJ27GDpIl3o2vWjGa/rK6VOSgoKFw+yrp/u6N4YBQUFBCtVqkmkSDUOQ9MYQhJ6UitoKBQiGLAKCgoFOpftFqEKgjLaxI5hJSVpfRDUlBQkFEMGAUFhcIMpDpUgdeF3NZA6YekoKDghmLAKCgoIJpdRezqVvgInP2QnEaMTQkjKSgoOFEMGAUFBURL3cxAcqEOcmUiZdTyTBQUFOoKigGjoKBQ2MSxjhWxc6EOCgSUfkgKCgqFKAaMgsJVjiiKdbaInQtNkNKRWkFBwRPFgFFQuMrxSKGuQ12o3ZE9MEoxOwUFBSeKAaOgcJVT2IVaV+dSqF0o/ZAUFBSKohgwCgpXOa4WAqo6KuAFUDtDSEo/JAUFBReKAVOPmDhxIiNHjqztaZTKyZMnEQSBvXv3XtIxJk2aRExMDAaDgWbNmvHcc89hcXoJFKofdw9MXUWjhJAUFBSKUCkDZuHChXTo0AGj0YjRaCQuLo5ff/1V3t6nTx8EQfBYpkyZ4nGMpKQkhg4dire3N2FhYcyYMQObzeYxZvPmzXTp0gW9Xk9sbCxLliyp+hUqXBaqy8A4fPgwDoeDjz76iIMHD/Lmm2/y4Ycf8tRTT1XL8RWKUyjgrZsZSFDogbEpBoyCgoKTShkwUVFRvPLKK+zevZt//vmHfv36MWLECA4ePCiPuffee0lJSZEX967DdrudoUOHYrFY2LZtG0uXLmXJkiXMnj1bHpOYmMjQoUPp27cve/fuZfr06UyePJl169ZVw+VeWfTp04eHHnqI6dOnExgYSIMGDfjkk0/Iy8vj7rvvxs/Pj9jYWA8jc/PmzQiCwC+//EKHDh3w8vKiR48e/Pfffx7H/u6772jbti16vZ4mTZqwYMECj+1NmjRh7ty5jB8/HqPRyH333UdMTAwAnTt3RhAE+vTpI5/zmmuuwcfHh4CAAHr16sWpU6dKvKbBgwezePFiBg4cSNOmTbn55pt5/PHH+f7776vxlVNwx1FHu1C7o4h4FRQUiiFeIoGBgeKiRYtEURTF3r17iw8//HCpY9esWSOqVCoxNTVVXrdw4ULRaDSKZrNZFEVRnDlzpti2bVuP/caOHSsOGjSozHmYTCYxKytLXpKTk0VAzMrKKja2oKBAjI+PFwsKCkRRFEWHwyHmWfJqZXE4HBV6nUVRFCdMmCCOGDFC/rt3796in5+fOHfuXPHo0aPi3LlzRbVaLQ4ZMkT8+OOPxaNHj4r333+/GBwcLObl5YmiKIqbNm0SAbF169bi+vXrxf3794vDhg0TmzRpIlosFlEURfGff/4RVSqV+MILL4hHjhwRFy9eLBoMBnHx4sXyuRs3biwajUZx/vz54vHjx8Xjx4+LO3fuFAHxt99+E1NSUsS0tDTRarWK/v7+4uOPPy4eP35cjI+PF5csWSKeOnWqwtf99NNPi127dq3weIWK43A4xPz//hPzDxwQ7c7PoDtFPyu1hfXCBTG+ZSsxvlVr0WG11upcFBQUapasrKxS79/uaKpq+NjtdlauXEleXh5xcXHy+i+//JJly5YRHh7O8OHDefbZZ/H29gZg+/bttG/fngYNGsjjBw0axP3338/Bgwfp3Lkz27dvZ8CAAR7nGjRoENOnTy9zPvPmzWPOnDlVupYCWwHXLr+2SvteKn/f+TfeWu8q79+xY0eeeeYZAGbNmsUrr7xCSEgI9957LwCzZ89m4cKF7N+/nx49esj7Pffcc9x4440ALF26lKioKH744Qduu+023njjDfr378+zzz4LQIsWLYiPj+f1119n4sSJ8jH69evHY489Jv+tVqsBCA4OJjw8HID09HSysrIYNmwYzZo1A6B169YVvr7jx4/z7rvvMn/+/Mq+NAoVQLRY6nwKNTj7IQmC3A9JExJS21NSUFCoZSot4j1w4AC+vr7o9XqmTJnCDz/8QJs2bQC48847WbZsGZs2bWLWrFl88cUX/N///Z+8b2pqqofxAsh/p6amljkmOzubgoKCUuc1a9YssrKy5CU5Obmyl1Yv6dChg/y7Wq0mODiY9u3by+tcr+X58+c99nM3OoOCgmjZsiWHDh0C4NChQ/Tq1ctjfK9evTh27Bh2t27A3bp1K3d+QUFBTJw4kUGDBjF8+HDefvttUlJSKnRtZ86cYfDgwYwZM0Y2yBSqF7mJYx1OoQZnPyR/f0DRwSgoKEhU2gPTsmVL9u7dS1ZWFt9++y0TJkxgy5YttGnThvvuu08e1759eyIiIujfvz8JCQny03dNodfr0VdRhGjQGPj7zr+reUYVP/eloC3y1CwIgsc6103J4XBc0nlKwsfHp0LjFi9ezLRp01i7di3ffPMNzzzzDBs2bPDwCBXl7Nmz9O3bl549e/Lxxx9X15QVilAfBLwu1EFB2DMzlX5ICgoKQBUMGJ1OR2xsLABdu3Zl165dvP3223z00UfFxl57rRSWOX78OM2aNSM8PJydO3d6jDl37hyAHHIIDw+X17mPMRqNGAyXdrMvDUEQLimMUx/ZsWMHjRo1AiAjI4OjR4/KoZ3WrVuzdetWj/Fbt26lRYsWcpioJHROEai7l8ZF586d6dy5M7NmzSIuLo7ly5eXasCcOXOGvn370rVrVxYvXoxKpWT71xR1uQt1UTRBQVhOnMCernSkVlBQqIY6MA6HA7Mzi6EornogERERgBS2OHDggEc4Y8OGDRiNRjkMFRcXx8aNGz2Os2HDBo+Qh8Kl88ILL7Bx40b+++8/Jk6cSEhIiFxj5rHHHmPjxo3MnTuXo0ePsnTpUt577z0ef/zxMo8ZFhaGwWBg7dq1nDt3jqysLBITE5k1axbbt2/n1KlTrF+/nmPHjpWqgzlz5gx9+vShUaNGzJ8/nwsXLpCamiqHGBWqF0cd70LtjqsjtU3xwCgoKFBJD8ysWbMYMmQIjRo1Iicnh+XLl7N582bWrVtHQkICy5cv56abbiI4OJj9+/fzyCOPcMMNN8g6jYEDB9KmTRvGjRvHa6+9RmpqKs888wxTp06Vwz9TpkzhvffeY+bMmdxzzz38/vvvrFixgl9++aX6r/4q5pVXXuHhhx/m2LFjdOrUiZ9//ln2oHTp0oUVK1Ywe/Zs5s6dS0REBC+88IKHgLckNBoN77zzDi+88AKzZ8/m+uuv55tvvuHw4cMsXbqUtLQ0IiIimDp1Kv/73/9KPMaGDRs4fvw4x48fJyoqymObKIrVcu0KhYh1vAu1O+pgyYBRUqkVFBSAyqVR33PPPWLjxo1FnU4nhoaGiv379xfXr18viqIoJiUliTfccIMYFBQk6vV6MTY2VpwxY0axNKiTJ0+KQ4YMEQ0GgxgSEiI+9thjorVIWuSmTZvETp06iTqdTmzatKlH+m5FKSsNq66khtYGrjTqjIyM2p6KQi3jsNvF/APOFGpnCn1R6tJn5fzb74jxLVuJZ597rranoqCgUIPUSBr1p59+Wuq26OhotmzZUu4xGjduzJo1a8oc06dPH/7999/KTE1BQaGSiFYrIIJKhaCpckWFy4YrhKSIeBXqKumff45gMBA4ZkxtT+WqoO5/aykoKNQI9SWF2oUm2KWBUUS8CnUPa2oq516eB4KA8cYbpdpFCjWKkt5xldGnTx9EUSRA+XBd9Yj1oIWAO+rAq9MD48jPx1qkjpNC3cNy4oT0iyhSsH9/7U7mKkExYBQUrlLqQxdqd67WfkinH5rG8Rt6c/qhhzAdPVrb01EoBfPJk/LvBXv31d5EriIUA0ZB4SrFUY+K2AFogqWO1PbMTMQiHeyvVBz5+eRt3w5AzobfSBwxkjOPz8BSSjNUhdrD4mHA7K21eVxNKAaMgsJVSr0LIbn6ISEZMVcDpsNHwOFAHRSE3+DBIIpkr15Nwk1DSXn2WawVbMuhUPN4GDD79yPWQPVzBU8UA0ZB4SpEdDicWUiSiLc+IKjVV10/JNN//wFg6NCBqLfeJOb77/Dt3RvsdjJXfkvC0GHk7dhRy7NUALAknpR/d+TmFmpiFGoMxYBRULgKkfUvKhXUgxRqF2pXGOlqMWAOHgTAq1076WebNkR/9CGNly/H0KkTYn4+yf+bQu4ff9TmNK96HBYL1jNnANDFxABKGOlyoBgwCgpXIe4C3vqQQu1CE1h5Ia8oiuTt2IEto/5lLxUclDwwXm3beKz37tKZRp8vxbdfP0SzmeSpD5K9YUNtTFEBsCYng8OByscHvwH9ASjYpwh5axrFgFEoE0EQWLVqVW1Po0xOnjyJIAhy7y2F8qlPXajdcXlgKtMPKX/HDpIm3k3KM8/W1LRqBEd+PpYTiQB4tW1bbLtKpyPq7bckbYzVypnpj5CltFypFVz6F12TJhg6dQKUTKTLgWLA1BMEQShzef7550vdV7nBl8/3339Pt27dCAgIwMfHh06dOvHFF1/U9rRqDEc96kLtTmEqdcWL2ZkOHQbq3xOx6fBhcDjQhIWhDQsrcYyg1dJw/uv4j7gZ7HbOzphJ5vc/XOaZKngYMM7ef+bjx7Hn5NTirK586k/w+yonxS3b4JtvvmH27NkcOXJEXufr61sb07piCAoK4umnn6ZVq1bodDpWr17N3XffTVhYGIMGDart6VU7jrw8AFReXrU8k8qhCXRV4614CMl6+jQA9osXsaWno3G2JKjruAS8JXlf3BE0GiLmzUPQe5G5YgUpTz2FaLEQePvYyzFNBcCcKHnKdE2aoAkNRduwIdYzZzAdOIBPz561PLsrF8UDU08IDw+XF39/fwRBkP8OCwvjjTfeICoqCr1eT6dOnVi7dq28b4xTVNa5c2cEQaBPnz4A7Nq1ixtvvJGQkBD8/f3p3bs3e/bsqdS8vv32W9q3b4/BYCA4OJgBAwaQ57w59unTh+nTp3uMHzlypEdX6yZNmjB37lzuuOMOfHx8aNiwIe+//77HPoIgsHDhQoYMGYLBYKBp06Z8++23Jc5HFEViY2OZP3++x/q9e/ciCALHjx8vcb8+ffpwyy230Lp1a5o1a8bDDz9Mhw4d+Ouvvyr1etQHHGYzosUMgoCqnhm+ckfqtIobMJbTyfLv5mMlv/91kUIBb9kGDEhi7PA5zxM4bhwAqS++WC81P/UVdw8MUBhGqmdev/qGYsAg3fQc+fm1soiieMnzf/vtt1mwYAHz589n//79DBo0iJtvvpljx44BsHPnTgB+++03UlJS+P777wHIyclhwoQJ/PXXX+zYsYPmzZtz0003kVNBt2dKSgp33HEH99xzD4cOHWLz5s2MGjWq0tf0+uuv07FjR/7991+efPJJHn74YTYUESQ+++yzjB49mn379nHXXXdx++23c+jQoWLHEgSBe+65h8WLF3usX7x4MTfccAOxsbHlzkcURTZu3MiRI0e44YYbKnUt9QF7djYAKh8fBLW6lmdTOVzeE1tGZTwwZ+Tfzc7PRH2g4D+nAVOOB8aFIAg0eGqWdBO12TAp5ewvG5aTUmFB2YDp2BGAfCVsX6MoISRALCjgSJeutXLulnt2I3h7X9Ix5s+fzxNPPMHtt98OwKuvvsqmTZt46623eP/99wkNDQUgODiY8PBweb9+/fp5HOfjjz8mICCALVu2MGzYsHLPm5KSgs1mY9SoUTRu3BiA9u3bV3r+vXr14sknnwSgRYsWbN26lTfffJMbb7xRHjNmzBgmT54MwNy5c9mwYQPvvvsuH3zwQbHjTZw4kdmzZ7Nz506uueYarFYry5cvL+aVKUpWVhYNGzbEbDajVqv54IMPPOZwpeBwGjBqo7GWZ1J5KtsPSXQ45BAS1B8DxpGXJ9cRMVTQgAHJiDF07Ijl5EkK9h+QasZcweTv2UPGV1/TYNaTtRYatOfkYL94EQBdTBMADJ07AWDauw9RFOtVpl99QvHA1HOys7M5e/YsvXr18ljfq1evEj0U7pw7d457772X5s2b4+/vj9FoJDc3l6SkpAqdu2PHjvTv35/27dszZswYPvnkEzKq4LaOi4sr9nfRuVdkjIvIyEiGDh3KZ599BsDPP/+M2WxmTDkt7v38/Ni7dy+7du3ipZde4tFHH2Xz5s2VvJq6jcNqxVFQAIDaz6+WZ1N5NHIIqWIiXtuFi3LGFdQfA8Z0+DCIIpoGDdA4H0AqilcH6SGi4MCV74E5//p8sn/+mYxly2ptDi7vizo0BLUzJOvVsiWCToc9Kwur0vahxlA8MIBgMNByz+5aO3dtMWHCBNLS0nj77bdp3Lgxer2euLg4LG5f+GWhVqvZsGED27ZtY/369bz77rs8/fTT/P3338TExKBSqYqFk6zO6q81zeTJkxk3bhxvvvkmixcvZuzYsXiX4+lSqVRyiKlTp04cOnSIefPmyZqhKwGX90Xl7Y2g1dbybCqP2vmUbc/KQrTZEMopwmd16V/UarDbMR87Vi+eiCsq4C0JVxaMaf+BenGtVcWelSVrTPK2bSd02rRamYflpCTg1TduIq8TdDq82ral4N9/yd+7Vw4tKVQvigcGye2q8vauleVSv1yMRiORkZFs3brVY/3WrVtp00YqfqVzpsra7fZiY6ZNm8ZNN91E27Zt0ev1XHS6QiuKIAj06tWLOXPm8O+//6LT6fjhBymNMzQ01CN7ym6385/zi9mdHUVKoe/YsYPWrVtXeow7N910Ez4+PixcuJC1a9dyzz33VOq6ABwOB2Znv6ArBVdaZ330vkDl+yG5wkeGTp1Ao8GRk4Pt3Lmam2A1UVAJAW9R9C1bImi12DMzPcJnVxp527aBs99QwYEDtZay7Goh4AofuVCEvDWP4oG5ApgxYwbPPfcczZo1o1OnTixevJi9e/fy5ZdfAhAWFobBYGDt2rVERUXh5eWFv78/zZs354svvqBbt25kZ2czY8YMDJXwCP39999s3LiRgQMHEhYWxt9//82FCxdkw6Jfv348+uij/PLLLzRr1ow33niDzBJuOlu3buW1115j5MiRbNiwgZUrV/JLkYJcK1eupFu3blx33XV8+eWX7Ny5k08//bTUuanVaiZOnMisWbNo3rx5sRBUUebNm0e3bt1o1qwZZrOZNWvW8MUXX7Bw4cIKvx51HdFmK0yfrof6F3D2QwoIwJ6RgS0tHU1ISJnjLcnSDVwX0wR7ZiaWhATMx46hddOC1UVMTgFvZfQvLlQ6HfrWrTHt30/B/v3ooqOre3p1gtw/3TIE7Xbyd+3Cr4iu73JQNAPJhUvIqxgwNYfigbkCmDZtGo8++iiPPfYY7du3Z+3atfz00080b94cAI1GwzvvvMNHH31EZGQkI0aMAODTTz8lIyODLl26MG7cOKZNm0ZYKQWzSsJoNPLHH39w00030aJFC5555hkWLFjAkCFDALjnnnuYMGEC48ePp3fv3jRt2pS+ffsWO85jjz3GP//8Q+fOnXnxxRd54403itVemTNnDl9//TUdOnTg888/56uvvpI9TKUxadIkLBYLd999d7nXkpeXxwMPPEDbtm3p1asX3333HcuWLZOFw1cC9txcEEVUej2qelaB1x05jFSBTCSXB0IXFY3e+Xmo66nU9tw8LImlV+CtCAanmP5KzUQSRZG8P/8EQNe0KSCFkWqDUg2YTpIBYz5yFEd+/mWe1dWB4oGph0ycONGjlopKpeK5557jueeeK3WfyZMnF7sZd+7cmV27dnmsu/XWWz3+LislunXr1h71Zoqi1Wr54IMPSswUcsdoNLJixYoyx0RGRrJ+/foStzVp0qTEeZ45cwatVsv48ePLPDbAiy++yIsvvljuuNpGdDiwZ2aiNhrL1X8URda/1FPviwtNUBCWhIQK9UNy1YDRRkUh2m3krK37Ql7zoXhJwBseXq6HqTQMHdqT8SUU7D9QzbOrG5iPHsV24QKCwUDI/fdzdsYM8rZffgNGFMVCA8ZZb8uFNjwcTXg4ttRUCv77D59rrrns87vSUTwwClccZrOZ06dP8/zzzzNmzBgaNGhQ21OqNuzp6VjPnsXqpi2qCKLDIXlgqJ/p0+64PDC2ChSzc9WA0UVHuXlg6rYBcyn6Fxde7Z1C3vh4xMsknL+cuLwvPtdcg+8N14MgYElIwHqZ9U22Cxck74pKhS4qqth2JYxUsygGjMIVx1dffUXjxo3JzMzktddeq+3pVCsuV7Q9OxuxiCi7zP1yc8HhQNBqEepZ+4CiyP2QygkhOSwWWbCrjXIzYI4fR3SKP+sipoPxQNX0Ly50TRqj8vNDNJvrvMFWFVz6F5/rr0ft749Xu3bA5Q8juQS82qioEvuKyQaM0tixRlAMGIVa5eTJk8XaDRRFFEVGjhxZ4WNOnDgRu93O7t27adiw4aVNsI7hquGCKFYq68JVfVftZ6z3abWaIGdH6nI8MNYzZ0AUEby9UQcFoWvUCEGnQzSZ6nR2zqWkULsQVCoM7aWb+pUWRrLn5pHvbHnie/11APg4Rfp527dd1rkU6l8al7jdPROpOqquK3iiGDAKCvUE0Wr1CAfYs7Iqtp8o4nAaOypj/UyfdqewI3U5BoxLwNuwodS1Xa1GF9sMqLthJHturnxTvBQDBgrDSFdaQbv8v3eA1Yq2USN0zgrgPj1dBsz2Mg2F1Bde4NgNvaVCgdVAaQJeF15tWoNWi/3iRaxnzsrrRZuNjBUrONavH4c7duJojziO9+tPwrBhJI65jVMT7yb711+rZY5XMooBo6BQT3B5X1z9ixy5uYg2W/n75eUj2u0IajUqH58anePlQBPs9MCUE0JyGTBaN22CVx3XwZjinQLeiAj5OquKoYMrE+nK8sDkOvUvvtdfL68zdO6M4OWF/cJFLKU0bDUnJJCx/Cts589z5uHpsibsUijPgFF5eeHVqhUABXv3IooiuX/8QeItt5A6+zlsZ1MQzWapZs/Zs1iOJ2A6cID8HTtIee55JXupHJQsJAWFeoLLgFH5+SGaTDhMJuzZ2eX2gHHkZMv71ffwEbj1Q7pYdjsBVw0YbXShAaNzVlo2H62jBoxL/3IJAl4XXs5UavPx49hz81D71n/jVUqfdulfrpPXq/R6vLt2JW/rVvK2b5f1Tu6kfbJI/t1y6hSps2cTuWDBJX0mXAaMvkgGkjuGTp0wHThA9i+/kPX9d7JOR+3vT8jUB/Dt2xdHQQFiQQGOggIc+fmce3ke1tOnyfp5NYFjb6vy/K50FA+MgkI9QTZgDAZU/v5A+WEkURQL9S/1PPvIhc5pkFhOn8ZhMpU6rrAGTKEB4y7krYuYDlauA3VZaMPC0ISHgyhiij94ycerC1gST2I9cwZBqy2WliyHkUoQ8lrPniVr9WoAGjw1CzQastf8SsZXX1V5LqLViiVZStMvq1WAS8ibu2kTedu2I2i1BN1zD83WryNo/Hh00dF4tWiBoWNHfHr0wK9fPwLvuguAjC+/VLQzZaAYMAoK9QBRFBHdDBi104Bx5OXhKCNNVjSZJN2MoELlbDRX39FERKAOCQGbDVMZDUsLa8AUVqKVQ0iJiXUyvbg6BLzuyAXtDlwZYaS8v6TwkXf3bqiK9DZzCXnzd+4s9t6mfbYYbDa8e/QgaPx4wh57DIDz816h4EDx9iYVwXrmDNhsCF5eaMoo1eDdrSuCs3Ck8aabaPrrGhrMnCF/hksiYNQtCAYD5qNHKfjnnyrN72pAMWAUFOoBotUqpU0LAoKXFyqdDpVB+gJ3ZGWXup+rX5DazxdBdWV83AVBqNCN2VUDRhtVmImmiYyUbnxWK5Y61iW4OgW8LuTO1FeIDkZOn77u+mLb9K1aoQ4IwJGfT4Hb/4UtPZ3Mb78FIOS+ewEImjgB3/79Ea1WzjzyiOylrAxml/6lceMyP1va8HCafPM1MT/9SMM3FpRYL6Yoan9//IcPByB92ZeVntvVwpXxjaZQY2zevBlBEErsYaRw+ZC9L3q9/GWpLieM5MgvkFON1QEBNT/Jy4hLoFqwr+QMG3tWllx52P2GIQjCJRW0q0ztncri0r9oIiPK1TVVFMMVlInkMJnI37kTKEyfdkdQqfCO6wFA3tbCdOr0L75ANJnwatcOb6eXRhAEIl9+CW1UFNbTpzn71FOVDtWUJ+B1x6tVK7xatKjU8QPvuhOAnN9+w5qaWql9rxYqZcAsXLiQDh06YDQaMRqNxMXF8atbqpfJZGLq1KkEBwfj6+vL6NGjOVekMmJSUhJDhw7F29ubsLAwZsyYga1IJsXmzZvp0qULer2e2NhYlixZUvUrvIKYOHGilA5aZDleR+P5CtWHnIFkKHSbq/yNzm35OCwWj/Giw4HlzGlARO3vf8XoX1x4dXDdmEv2LFic+hd1cHCxUIO+ReUMGOu586R//gUn77iTwx06kvrSy4hFXu/qwKV/MbRtV23H9GrXFgQB29kUbBcuVNtxa4P8Xf8gms1owsNlMXZRCuvBSDoYe24uGV8uByD4vns9BLtqf38avvkmglZL7m8bSV+6tFLzqYwBUxW8WrbEu1s3sNvJ+OabGjlHfadSBkxUVBSvvPIKu3fv5p9//qFfv36MGDGCg84P3iOPPMLPP//MypUr2bJlC2fPnmXUqFHy/na7naFDh2KxWNi2bRtLly5lyZIlzJ49Wx6TmJjI0KFD6du3L3v37mX69OlMnjyZdevWVdMl128GDx5MSkqKxxJThgJe4cqgUMBbWEVXpdXKadFFvTC28+cRzWYEjQZtRMTlm+hlwuCsvGpNSsKWkVFsu9xCoAR3fUU8MLa0NNKXL+fUuPEc79OHcy+/TMG//0o3ky++4NS48ZVu51Ae1SngdaH29UXvrH1TVa1HXSH3zz8AyftSWuaQT89egFQ4zp6bS+Y33+DIzkYXE4PfgAHFxhvatyNs1pMAnJ+/QDZ8K4KrCq8upkklrqJyBP7f/wGQuWJlsYcUhUoaMMOHD+emm26iefPmtGjRgpdeeglfX1927NhBVlYWn376KW+88Qb9+vWja9euLF68mG3btrFjxw4A1q9fT3x8PMuWLaNTp04MGTKEuXPn8v7772NxvjkffvghMTExLFiwgNatW/Pggw9y66238uabb1b/1ddD9Ho94eHhHovaWRdky5YtXHPNNej1eiIiInjyySc9vFtms1nuOO3l5cV1111XrJnjmjVraNGiBQaDgb59+3LS+ZRRGidPnkQQBPbu3Suvy8zMRBAENm/eDEBGRgZ33XUXoaGhGAwGmjdvzuLFi+XxycnJ3HbbbQQEBBAUFMSIESPKPe/VhIeAt4g3QRbzuhkwjvx8bBcvAqCNjKx008f6gNrfX37ydQlf3bG6NXEsimzAlJJKnbNpE8f79OXcC3PJ37ULRBFDp040eGoWka+/jspopGDfPhJHjSZ369ZquR5RFCUDCeSy+NXFlVLQLs+tfUBp6KIaom3UCOx28v7aSprTex88eXKpOpXAO+7A0LUr2Gzkbtpc4fnIKdQ15IEB8OvfD02DBtjT0sgpo3Hu1UqVNTB2u52vv/6avLw84uLi2L17N1arlQFuVm6rVq1o1KgR253uvO3bt9O+fXuP5nqDBg0iOztb9uJs377d4xiuMdvL6TRqNpvJzs72WCqKKIpYzfZaWaorRe7MmTPcdNNNdO/enX379rFw4UI+/fRTjw7LM2fO5LvvvmPp0qXs2bOH2NhYBg0aRLqzomlycjKjRo1i+PDh7N27l8mTJ/Pkk09e8tyeffZZ4uPj+fXXXzl06BALFy4kxNll12q1MmjQIPz8/Pjzzz/ZunUrvr6+DB48WDZqr3ZEs1nq3SOo5GwGF2qjEQQBh8mEwzlODp8EBFxxoSN3DB2dN+YSdDCu18C9BowLvTP8YElKKpaG7SgoIHXOC4hWK/pWrQibMYPY3zfS5OuvCBo/Hv/hw4j57lu82rTBnpFB8uR7ufD++5fcW8l6+jTWs2dBo8G7S+dLOlZR5IJ2peiF6gOW06exJCaCWi2HiUrDtf3cvHnYL1xEEx6O//BhpY4XBAG/fn0ByPvrrwrNx5GXJ/fZqqkQEoCg1RJ4+1gA0r9UxLxFqfSj2YEDB4iLi8NkMuHr68sPP/xAmzZt2Lt3LzqdjoAiYsEGDRqQ6hQgpaamFusM7Pq7vDHZ2dkUFBRgMBhKnNe8efOYM2dOZS8HAJvFwccPb6nSvpfKfW/3RqtXV3j86tWr8XVLhx0yZAgrV67kgw8+IDo6mvfeew9BEGjVqhVnz57liSeeYPbs2RQUFLBw4UKWLFnCkCFDAPjkk0/YsGEDn376KTNmzGDhwoU0a9aMBQsWANCyZUsOHDjAq6++eknXmJSUROfOnenWrRsATdw+8N988w0Oh4NFixbJbuHFixcTEBDA5s2bGThw4CWd+0rAPXxU1HUuaDSofH1x5ORgz8wChx3RYpFCR+HhtTHdy4ZX+w5k/fhTiZ4Fa3LxGjAu1CEhqAMCsGdmYk5I8GiamPbpZ9hSU9FERtDk669QldD4UhcdTeOvlnPuxZfIXLmSi+++R8G/e2n41puoq5iq7tJsGDp2LOZlu1RcBe0K/vsP0eGod9looiiS9f33ABg6d0LtV3Y7DJ+4ODK/+UY2MILvubvERose+/TqBa/PJ2/nThwWC6pyxluSkgDnQ0INC+QDbruNix8sxLRvPwUHDsgZeApV8MC0bNmSvXv38vfff3P//fczYcIE4uPja2JulWLWrFlkZWXJS7KzwNCVhksb5FreeecdAA4dOkRcXJzHDa5Xr17k5uZy+vRpEhISsFqt9OrVS96u1Wq55pprOOSspXHo0CGuvfZaj/PFlfO0UxHuv/9+vv76azp16sTMmTPZtq0wQ2Dfvn0cP34cPz8/fH198fX1JSgoCJPJREJCwiWf+0rAvf5LScjZSOlp2NKk6rTahg2vyNCRO+6l8ot6MgvbCEQX2889E8m97Lw1JYW0RVK11gYzZ5ZovLhQ6fVEzH2BiHnzELy8yPvrL9I+/bTK15K/428AfHr0qPIxSsOrRQsEnQ5HdnadSx0vj/zduzl5++1c/GAhQIk6lqJ4X3sNOL8H1QEBBNx6a7n76Fu2RB0SglhQQMGef8sdX9MCXnc0wcH4DRkMQEYtpVTX1WJ6lf6G0+l0xDpdsF27dmXXrl28/fbbjB07FovFQmZmpocX5ty5c4Q7nwTDw8PZ6UyDc9/u2ub6WTRz6dy5cxiNxlK9LyBpQ/RF3OsVRaNTcd/bvau076Wi0VXOhvTx8ZFf/7qAyvk05/4Pbi1SRGrIkCGcOnWKNWvWsGHDBvr378/UqVOZP38+ubm5dO3alS9LcI+GhobW7OTrCYUZSKUYMH5+WAVBTvFVBwaW+5R6JaBv1QpBq8WekYH19Gl00ZKxIjocUpExStbAgKSDyd+1y0PIe37+AkSTCUO3rvgNGlShOQTcMhJBJXD2iSfJWb+BsIcfrvR1iKJI3t8uA+backZXHkGrxatNGwr27sV04ECZZe/rCubERC688QY5G34DQPD2JnjSPQQ5Ra1loQkMxKtdO0wHDhA4flyFPFqCIODbqydZP/5E3tat5b4P5sRE4PIYMABBd91F9k8/k71mDWFPzKy2NPuKkLZoERc+WEjjpUvqnPfnkn2JDocDs9lM165d0Wq1bNy4Ud525MgRkpKS5Kf4uLg4Dhw4wPnz5+UxGzZswGg00qZNG3mM+zFcY6rDE1AagiCg1atrZamu3jStW7dme5FOrFu3bsXPz4+oqCiaNWuGTqdjq5vo0Gq1smvXLvm1b926dTED0yXALg2XkZHilpHhLuh1HzdhwgSWLVvGW2+9xccffwxAly5dOHbsGGFhYcTGxnos/mVUqrxaEB0OWadRmgdGUKtlg0XQaq/40JELlU6HvnVrAAr2F4aRbOfPS5VYNRq04SVXSHWlUpucBkz+nj1k//ILCALhTz1Vqc+lb79+oNViSUjAfCKx0tdhPnYMe1oagpcXXs6y89VNfSlo5zCZSH3xJU4Mv1kyXlQqAm67jdh1awmdOrXCXsWIOc8TOv1hgidNqvC5fZze6dyt5etgLqcHBqSyAV7t2iFarWSuWHlZzglgPX+eC+++h5ifT/aautcdu1IGzKxZs/jjjz84efIkBw4cYNasWWzevJm77roLf39/Jk2axKOPPsqmTZvYvXs3d999N3FxcfRwukUHDhxImzZtGDduHPv27WPdunU888wzTJ06VfaeTJkyhRMnTjBz5kwOHz7MBx98wIoVK3jkkUeq/+qvIB544AGSk5N56KGHOHz4MD/++CPPPfccjz76KCqVCh8fH+6//35mzJjB2rVriY+P59577yU/P59Jzg/5lClTOHbsGDNmzODIkSMsX7683Bo8BoOBHj168Morr3Do0CG2bNnCM8884zFm9uzZ/Pjjjxw/fpyDBw+yevVqWjtvPHfddRchISGMGDGCP//8k8TERDZv3sy0adM4XYmUxisV0WwGUURQqcuM42vCwlD7+aGLjpa7VV8NyBV53W7MVmf4WBsRUeoNzz2VWnQ4OPfSywAE3HorXk6DvqKo/fzwcYZec377rXIXQGH4yLtr13K1F1WlvhS0S/tkERnLloHNhk/vG2j64yoiXpiDppLeWK82bQiZMgVVJbzyPj17AmCOPySHYkvDclIKxekukzdLEAQC77gdgJwiD/g1SdqiRdJ3EFJqel2jUgbM+fPnGT9+PC1btqR///7s2rWLdevWceONNwLw5ptvMmzYMEaPHs0NN9xAeHg43zvFVwBqtZrVq1ejVquJi4vj//7v/xg/fjwvvPCCPCYmJoZffvmFDRs20LFjRxYsWMCiRYsYVEGX7tVKw4YNWbNmDTt37qRjx45MmTKFSZMmeRgTr7zyCqNHj2bcuHF06dKF48ePs27dOgIDAwFo1KgR3333HatWraJjx458+OGHvPzyy+We+7PPPsNms9G1a1emT5/ukfkEUthx1qxZdOjQgRtuuAG1Ws3XX38NgLe3N3/88QeNGjVi1KhRtG7dmkmTJmEymTBewRk0FaUwfFRcwOuOyssLXePG1S4ArevIFXndCtpZXDVgSshAcuHKRLKdTSFj2TJMBw+i8vUldHrlQ0BQqM2oigHjCh9510D4yIXrdTLHH6qTPaBc5Dk9vmEzZ9Loo49K7CpdU2hCQmSPXkkNIV2IDoeUEcXl88AAUlE7wHzkyGV5D63nzpH5dWEBPdPBg3Xuf0cQ66o65xLJzs7G39+frKysYjdCk8lEYmIiMTExeJUh1FNQqG0sZ85gz8hAExJSK6Ghuv5ZMScmcmLITQh6PS3/2YWg1XLhnXe5+MEHBIwZQ8TcF0rd91jvPlKmilYLVithM2cSfM/dVZqH7cIFjt3QG0SR2C2b0ZbR3M8d0WbjaFxPHDk5NFm5osY0BqLDwZEuXRFNJpr+uqZO6mBEq5Uj3bojms00XfML+qZNL/sczi9YQNoni/AfMYLIV18pcUzuli0k/28KKl9fmm/9q1JenktBFEWOXnMtjpwcYlb9gFerVjV6vtQX5pKxfDmGbl0xHz2GIzubJt9965G1V1OUdf92p37l0ykoXGWUl4F0taNr3BiV0YhoNsuCXOsZVw2Y4hlI7ri8MFit6Bo3Juj/7qryPDShoRg6dQIq54UxHTqEIycHlZ9fpUNXlUFQqdA1bgwU6jfKQhRFMr76iry/d5Y7trowHTmKaDajMhovq2fDHVkHs21rqZk3ruJ4AWPGXDbjBaQwkpfTQ+Sq2lxTWFNSyFwpaW1CH5rmFqqtWyFIxYBRUKijSAJeKf5cWgbS1Y6gUsltBVwCVYtcA6ZhqfsBHuGJsFlPllsrpDyqEkbK2y6FTLyvuabGtUsuvYarBH5ZmP77j9Q5L5A8ZQrWIlmhNUXBfkljYejQodZq1Ri6dEEwGLBfuIj56NFi202HD5O/fQeo1Zdk8FYVV5sJV+PPmuLiRx8hWq14X3stPtdeU1g0cm/d0sEoBoyCQh3FUWACRASNBkGrre3p1Fm8XF+uzqdDuQZMOR4Y7+6SpsC3d298e196GQW/GyUDJn/nLuwV7N6e79R8+Fxbc/oXF66ePRXxwJgOHwYkD+CFN9+quUm5n9MpEjXUUCZWRVDpdHhf0x2AvL+Kt4lIXyI1fDQOGoi2YdkGck3g8tKZarD2muX0GTK/k7SroQ89KJ23g+dnrK6gGDAKCnUUsSAfkMJH1ZVufyXiyrAxHdiPw2TC5izTUFoNGBe+/frR+KvlNHzn7Wp5fXWNGqFv0QLsdnKcfcDKwmGxkL9nDwA+cdVfwK4orp49LgFqWVgSTsi/Z61aRcF/NRuygMKne0On2jNgAHx7XQdAXpF0auv582T98gsAQRMnXu5pAW4emMOHEd363FUnaR99CFYrPj3jZOGwy6i0JCYWaxxbmygGjIJCHUXywCjho/KQM2yOJ8g6GJWPT7kl3gVBwLtz52rVMVQmjFSwdy+iyYQ6OBjdZShOKYeQKuCBMZ+QqmCrnLWYzr0yr0arsdoyMuQqwbVdLM3nOkkHk//PbjkLECBj+XKwWjF07ozB6ZG43OiaSJmGoslUIUO0sliSk8n8/gcAQh58SF6vCQyUmmRSt7qaKwaMgkIdxeHmgVEoHU1ICNrISBBFsp0de7VRUbXitXKFkfL+2upx8ysJuX3Atddelrm6hLG2Cxew5+aWOdZyXDJgwp95BsHLi4J/dpOzbn2Nzc0lDtU1aVLjvYXKQxcTgyYiAtFiIf+ffwCpnEHmV1Lph9ryvoCk+ZKLN9aAkPfiwg/Bbsfn+uuLNRV1GW0F+/ZW+3mrimLAKCjUQUS71JQRFAOmIrhi9Nm/StVCS+pCfTnQt2qFtmFDRJOJ3HI6G8v1Xy5D+AikzuXq4GCgsBBbSTjy86XO2EjeiOB77gHg/Pz5OJxFzaqbgjqgf3EhCAK+Ti+MSweT9eOP2LOy0EZF4Tegf21OD6+2NaODsZw8SdaPPwKF2hd3XO9NXdLBKAaMgkIdRC5gp9Ve8U0ZqwNX2MF2VmppoWtYOwaMIAhyGCm3jDCSIy9PvmnXRAPH0tBVQAfjaoegDgxEExhI8ORJaMLCsJ4+TcYXX9TIvAr2STfF2ta/uHClU+dt24rocJC+9HMAgsaPq/VK17KQt5ozkdK/WAZ2O769e5cYInNlIpn27a8zzR0VA0ZBoQ7iyHOGj66yyrpVxaWDcVGegLcmcYWRcjZtLrVyaf6ePWCzoY2MvKxzrUgmksWpf9E3awZI/4OhzlYuFxd+WG6Z/coiOhzyU31d8MCA06hUqTAfO07mipVYEhNR+friP2p0bU9NLiRnOnQI0eGotuPm79oFgP/oUSVul5unZmbK7TpqG8WAUSiT559/nk7OAl2XmyZNmvDWW29d1nNW5HonTpzIyJEjq/W8S5Ys8eji7sjNASQx6mWnjjxdVQavtm3BrXZIbYWQAAydO6MOCsKRnS3fFIriKpnvHdfjsmp1KpKJZHZmIOmcBgyA/4ib8WrbFkdeHhfeebda52RJTMSRk4Pg5SVlcdUB1AEBeLWX6gude0WqyBtw222ofWvh81gEXUwMgpcXYn5+hQTZFcGekyML4L07dy5xjEqnQ9/Gqb+pI32RFAOmHjFx4kQEQSi2HD9+vLandsXw+OOPF+uGfrkRbTY5hKRydpm+bGSnQMpeuHBE+t2SXy8MGpW3t0dhOl0temAEtRrffn2B0rOR8p0F7C5n+AgqlolkTpC+T/TNCkv5CyoVDWY9CUDmypWYjhQv8lZVXOnTXu3a1qlwqSudWjSZaq1wXUkIGo3cRqC6wkgF+/aDKKKNji6zcaasg9lXN3QwigFTzxg8eDApKSkeS0wd7GtSG1icotdLwdfXl2Cn0LG2cOTlAaDS61Fd7gJ2pgzppzUfclMh8yRkn4X1z0L8T3XamHEPI9VGkTF3CtOpNxZz89szMzEdOgSA9zU1X8DOHVkDc/JkqToGSwkeGJCaCfoNHAgOB2cefRTTkSPVMqe6JOB1x5VODc7CdZGRtTgbTwp1MNWTiVTw778AGDp3KnOcoUPdEvIqBgxS3w+ryVQrS2XFUHq9nvDwcI9F7RSV/fjjj3Tp0gUvLy+aNm3KnDlzsLkVO8rMzGTy5MmEhoZiNBrp168f+4q4Al955RUaNGiAn5+f3BW6LOx2O5MmTSImJgaDwUDLli15++23Pca4Qi7z588nIiKC4OBgpk6ditVNH3D+/HmGDx+OwWAgJiaGL7/8stzXwnXcl156icjISFq2bAlAcnIyt912GwEBAQQFBTFixAhOuj1xbt68mWuuuQYfHx8CAgLo1asXp5w1KIqGkOx2O48++igBAQEEBwczc+bMYu9ZSaGuTp068fzzz8t/v/HGG7Rv3x4fHx+io6N54IEHyC0lldWe4wwf+RZ6XzZv3owgCGS6VXjdu3cvgiDI13bq1CmGDx9OYGAgPj4+tG3bljVr1sjj//vvP4YMGYKvry8NGjRg3LhxXLx4sfDEDgfYnFkmxobgFQCoQbTD0V9hxTg4WXZmTW3iykRSh4bUeuaWT1wcKm9vbOfPkzJ7Nhlff03+rl3Y0tPJ27kTRBFds2ZoG4Rd1nnpoqNBpcKRn4/t/IVi20WLBUtSElCogXEnbOYM1MHBWBISOHnrGNIWLUK02y9pTnXVgDF06IA6KAio3dTpkpAL2lVTJpLLgCktfOTCJeQ1HzqEoxoeGC+VuuOvq0VsZjPvTLi1Vs49bem3aKuhy++ff/7J+PHjeeedd7j++utJSEjgvvvuA+C5554DYMyYMRgMBn799Vf8/f356KOP6N+/P0ePHiUoKIgVK1bw/PPP8/7773Pdddfx+ZIlvPvuu8RER2M+eRJBrUHQqCU3r1aL2tcXhygSFRXFypUrCQ4OZtu2bdx3331ERERw2223yfPbtGkTERERbNq0iePHjzN27Fg6derEvffeC0jGyNmzZ9m0aRNarZZp06Zx3llRtSw2btyI0Whkw4YNAFitVgYNGkRcXBx//vknGo2GF198kcGDB7N//35UKhUjR47k3nvv5auvvsJisbBz585SdQgLFixgyZIlfPbZZ7Ru3ZoFCxbwww8/0K9fv0q9PyqVinfeeYeYmBhOnDjBAw88wMyZM/nggw88xomiiMNp2Kj8fCt1jqlTp2KxWPjjjz/w8fEhPj4eX1/pGJmZmfTr14/Jkyfz5ptvUlBQwBNPPMFtt93G77//Lh3A5jRWBTX4hIJvGBjyIUuEBh0gNxmSdkDM9ZWa1+XCt3dvNJERGG+8sbangkqvx3dAf7J/+pmsb78j69vvCjc6vWqXo31AUQSdDm1UFNakJCyJicUMKMupU2C3o/LxQVNCR21dVBRNf1xFyrOzyd20ifPzF5CzaTORr8yTjKNK4sjLk7UXho6dqnRNNYWg0dDos0+xZ2TUWuG60nBPpRYdjkvqHSXa7YVGZDkGjDYqCnVgIPaMDMzx8XID09pCMWDqGatXr5ZvSgBDhgxh5cqVzJkzhyeffJIJEyYA0LRpU+bOncvMmTN57rnn+Ouvv9i5cyfnz59H76w8On/+fFatWsW3337Lfffdx1tvvcWkSZOYNGkSAM8/+igb1qzBZDbLN1V3HEYjukaNmDNnjrwuJiaG7du3s2LFCg8DJjAwkPfeew+1Wk2rVq0YOnQoGzdu5N577+Xo0aP8+uuv7Ny5k+7dpT4kn376Ka2dBZvKwsfHh0WLFqFzNuJbtmwZDoeDRYsWyUbJ4sWLCQgIYPPmzXTr1o2srCyGDRtGM+cTZlnneeutt5g1axajRknK/A8//JB169aVO6+iTJ8+Xf69SZMmvPjii0yZMqW4AWM2SyXCVapKZyAlJSUxevRo2jtTips2LdQwvPfee3Tu3JmXX35ZXvfZZ58RHR3N0aNHadGiBdichde0BnAZdIIKNHqI7Q8Jv8DZPZWa0+VEGxZGc5cx5o7DAYd+gqju4H/5Qkvhzz6Lz7U9MCckYE44jiXhhNSnyel59O1fOSO4utDFNJEMmJMn8enhaUS5C3hLM+o1ISFEffA+Wd9/z7mXXqZg924SR4wkbNaTBNx6a6VEyQX/HQSHA01ExGX3RlUEl9akrqFv1gxBp8ORm4s1OVnuNF4VzMeP48jLK6YjKwlBEDB07Eju5s0U7N+vGDB1AY1ez7Sl39bauStD3759Wbhwofy3jzNLZd++fWzdupWXXnpJ3ma32zGZTOTn57Nv3z5yc3OL6TsKCgpISJDSJg8dOsSUKVPkbY7cXK7t0IE/9uyRNAU2G6LNjmizYs/Kwp6Tg2i388GHH/LZZ5+RlJREQUEBFoulWCZP27Zt5VAXQEREBAcOHJDPq9Fo6Nq1q7y9VatWHlk5pdG+fXvZeHG9DsePH8eviPjVZDKRkJDAwIEDmThxIoMGDeLGG29kwIAB3HbbbURERBQ7dlZWFikpKVzr9qSs0Wjo1q1bpUN/v/32G/PmzePw4cNkZ2djs9nk98bbzVBxOMNHah+fSj9VTZs2jfvvv5/169czYMAARo8eTQfnk+O+ffvYtGmTh/HrIiEhQTJgrE4PjKYEj2CY9MTH2X8rNac6wYnfYeUEaDEY7vzmsp1W7edHQJGUVEdBAZbERES7vdZK5uubxJC35Y8SM5FcLQT0bsZvSQiCQMDo0Xhfey0pT84i/59/SH12NtakZMIee7TCc6mr4aO6jqDVom/ZEtOBA5ji4y/JgJH1L506VqjGjaFjB8mAqQNCXsWAQfowVkcY53Lg4+NDbAl9U3Jzc5kzZ47sKXDHy8uL3NxcIiIi2FxCk7mSDAXRbseRL9UiETQaNIGBhdtEEUdBAaLFwldLl/L444+zYMEC4uLi8PPz4/XXX+dvZ5VRF9oiYlRBEHBUQw0DnyJpxrm5uXTt2rVEDU2oU12/ePFipk2bxtq1a/nmm2945pln2LBhAz2qmBGiUqmKGTTu+p6TJ08ybNgw7r//fl566SWCgoL466+/mDRpEhaLxcOAcZV4VxUxNFROY8b9PNYiNUYmT57MoEGD+OWXX1i/fj3z5s1jwYIFPPTQQ+Tm5jJ8+HBeffXVYvOXjTd3D0xRQltK3picFCk7yVjc4KuzXHRm6aUl1O48kKoquwSYtUVZtWBcLQT0scX1LyUeKyqKRp8vJe3jj7nw1ttkfP01oQ89iOD2UFEWsgFTx0I09QGvNm0kA+bgQYxDhlT5OIUGTNnhI/m8dagztSLivULo0qULR44cITY2ttiiUqno0qULqampaDSaYttDQkIAKZTiMjwceXkgiuz877/CcIITQRBQG40A/PXnn/Ts2ZMHHniAzp07ExsbK3t0KkqrVq2w2Wzs3r1bXnfkyBEPwWplXodjx44RFhZW7Dr9nY3pADp37sysWbPYtm0b7dq1Y/ny5cWO5e/vT0REhIcxVnSeIBlGKSkp8t/Z2dkkuj3d7t69G4fDwYIFC+jRowctWrTgrLNUe1FcRmNRA8ZlfLmfZ+/evcX2j46OZsqUKXz//fc89thjfPLJJ/LrcvDgQZo0aVLsdZGNwLI8MDpvCHW60+ubFybH+Zrllq+puhrQNZGyFs0nS/LAOENITStmwICUYh18332oQ0Jw5OSQt7Pk2jdFEUWx0ICpIxV46xPV1VIg/9+9QPn6Fxcuz6E1ORlbevolnftSUQyYK4TZs2fz+eefM2fOHA4ePMihQ4f4+uuveeaZZwAYMGAAcXFxjBw5kvXr13Py5Em2bdvG008/zT/OhmUPP/wwn332GYsXL+bwvn3Mff99DpVSY0blNGCaRUTwzz//sG7dOo4ePcqzzz7LrlKKd5VGy5YtGTx4MP/73//4+++/2b17N5MnT8ZQhUySu+66i5CQEEaMGMGff/5JYmIimzdvZtq0aZw+fZrExERmzZrF9u3bOXXqFOvXr+fYsWOl6mAefvhhXnnlFVatWsXhw4d54IEHihlW/fr144svvuDPP//kwIEDTJgwwSNcFhsbi9Vq5d133+XEiRN88cUXfPjhhyVfgCgi6HTFnmBjY2OJjo7m+eef59ixY/zyyy8sWLDAY8z06dNZt24diYmJ7Nmzh02bNsnXNXXqVNLT07njjjvYtWsXCQkJrFu3jrvvvhu73Q4OGzicHp2SPDAAkV2kn5dRB5OSuoq0tD8v7SA5qdJPcxZYy26weDXg8sBYT5+R+22B5HW1OA0Y9xowFUFQqfBzCttznIL68rCeOYv94kXQaGrdK1Uf8WojZSIVHIyvcml/28WLWJOSQBDkDKPyUBuNcop9bRe0UwyYK4RBgwaxevVq1q9fT/fu3enRowdvvvkmjZ2xUUEQWLNmDTfccAN33303LVq04Pbbb+fUqVM0cGYbjB07lmeffZaZM2fSY/Bgks+e5X9OQW9RVAYDgkbDpFtv5Zbhwxk7dizXXnstaWlpPPDAA5We/+LFi4mMjKR3796MGjWK++67j7Cwyov6vL29+eOPP2jUqBGjRo2idevWcjq40WjE29ubw4cPM3r0aFq0aMF9993H1KlT+d///lfi8R577DHGjRvHhAkT5BDZLbfc4jFm1qxZ9O7dm2HDhjF06FBGjhwpC4QBOnbsyBtvvMGrr75Ku3bt+PLLL5k3b17xkzm/hNS+vsWEkFqtlq+++orDhw/ToUMHXn31VV588UWPMXa7nalTp9K6dWsGDx5MixYtZJFwZGQkW7duxW63M3DgQNq3b8/06dMJCAiQwlMu74taB6pS4uCRnaSfl8kDk59/ivj4x9h/4H7s9ktoIphT6LVSvDCgCQtD8PYGux3L6dPyeusZyaBxZSpVFj9n9lfO78Vr35SEab+zgF2rVqjqSQi/LqFv0Ry0WhxZWVjPlOzRLY8CpxdXHxsre9UrgqGOhJEEsa50ZapmsrOz8ff3JysrC2ORN8ZkMpGYmEhMTAxeygenGA6zWUptFAS8WrUqVdhlOXsWe3o66sBAdLVcOKy+I4oi5qPHEK0WdI0aVerLpFrIuwBZp0FvhOBC48vjs5J2ED7pB4YgmHmiWGixurlwcSP790ulALp0+ZrAgO5VO9B718BFZ9G1Sb9BdBWPcwVxYtQozPGHiPrg/ULPyaZNnL7/AfQtW9L0x1WVPqZosXC013U4cnJovHw53l3KDkmcmzeP9KWfE3jXXYQ/+0xVLuOqx/U+Nnz7bYyDBlZ6/3Ovv076p58RcNttRLwwp/wdnGR8/TWpz8/Bp2dPGn32aaXPWx5l3b/dUTwwCsWQ65B4e5epSnfdZB05OXWmO2l9RbRYEK0WEITa6X9kLUPA66JBO1BpoSAdMpNqfEoF+Sfl3zMz/i59YHl4eGBSq36cKwi9UwfjnolkSfBs4lhZBJ0O3969gdJbKLjjaiGg6F+qjlyRt4o6mIJK6l9cyC0F9u+v1oaSlUUxYBSK4SglE6YoLgNHtNlk8alC1aio0VhjlCXgdaHRQwMp7n45dDD5BSfl3zMzK6erkjHngjm78O/cc5c2qSsE95YCLgprwFRO/+JOYQuF38p8qHFYLPJNV0mhrjqGS6jI67BYMP33HwDe5bQQKIq+eXMEgwFHbm6ZjUFrGsWAUfBAdDiwO3vxqMsxYASVSm426MjOLnOsQtm4DJjyXvMaQRQLq/BqDWV70yKdT2qXQQeT7+aBycreg8NhLX1waRQ1WBQNDFDY1NHsdvORa8BU0QMD4Hv9dQg6HdakJMxHS2/4aD50CNFqRR0YiLYKFXwVJNx7IlXWC26Oj0e0WKT3oJJ1ZASNRs6Cqs16MIoBo+CBIz8fHA4EjQahAvogVxjJnp2thJGqiLvRWJ7Xq0awW6R+RwiY7dnk5sZjt5eSrdPQmYl0puY9MO4hJLs9n5yc/yp/EPfwESgeGCeFHhipB5goioU1YC7BgFH5+OBzndTFOWdD6WGk3D+kzDJDhw6Vqtyr4Im+ZUtQq7Gnp2M7V7n/bff06aq8BwGjbyV0+sMeTVQvN4oBo+CBe/ioIv/UKl9fEFSIVqvUdl6h0lTWaKx2XN4XjR6rLRNRdGCxpJU81uWBSdknlegv9ZgWsFQ9rGi3mzCZpcwKf3/JaMrM3Fn5A+UU0bwoHhigMJXafvEi9pwcbOfPS7Wf1OpLquoKnmGkkrCmpJD22WcAGIcNvaRzXe2ovLxkg7Oynakr2oG6NAJuGUnIlCnoSyiserlQDBgFDyqqf3EhqFSonU0H7UoYqUpU1misdpwCXofWC4dDqgtis2UhiiUYKKGtQWOQdCXppRQsdDhg8RB4u0OVDYaCAskzoNH4ERYqVRnNqJIB4/TA6JytJYoaNFcpal9f1KFSAUvLyZOYnfWedNHRFa6iWxq+ffuAWo358GGPNG0X5159DbGgAEOXLhiHDbukcym4daY+WHEdjCiK5P8reVHL60Bdl1EMGAUZh9WKw+lFqYwWw1XUTtHBVA25/1GR/k2XDaeA164pFA+LogObLaf4WLUGIpwFr0oJI1mPr+GEJp7jYXmI/yyp0pRcAl6DoQkBgdcAkJn5D6Jor9yBsp0GjGvOigdGxj0TyeIS8FawhUBZaAID8e7WDSgeRsrbto2ctWtBpSJ89rNK+Kga8GonGTA5mzZVOIxvPXMW+wVnEcF27WpyejWKYsAoyMieAC+pSF1FUfv6giDgMJtxmC+h4NhViMNqlV+zWkmfBrkHkl1VtJ9TVsnjSxHy2u0FnDz1EduSHiWxsTenor3Ji/8M7LZKT8mlf/H2boKfb2vUal/s9lxycg9V7kAuD0yEM9Ml95xcMPBqxyXktZw86dbE8dINGHAraudWlVe0WEidKxVfDLzzzjrb6bm+YRwyBMHbG/OhQ+Ru2lyhfVzhI682bep1EUHFgFGQkQ0Yv8oJSQWNRr75KmGkyuFwiXcNlTMaqw3RATbJgLIjZfnodFLHcps9u2SPR5GWAg6HldNnlrNtez8SEl7Dpircx2S9CEfWVHpargwkb0MTBEFNQID0RJ+ZUckwkitk5DJgHFYoyKj0fGoVe83M2SXkNScmVrqJY3n4DegPSDdK28WLAKR//jmWxETUwcGETnuoWs6jAJqgIILuuhOAi++9VyEvjMuAqWz6dF1DMWAUAGeH6RL0L4IgsGrVqnL3V7uFkfr06cP06dNrYpo1zuWeu+j0vtSKeBecxouIKKixO6S5aLVBqFR6EEWs1hLCSLKQdz/pF/9gx98DOXLkWSyW83jhR5vDOQTnSwXxTF5q2LWo0tPKd2pgDN5NAAgMcIWRKmvAOD0wAY3BK0D6vT5lImUmw8KesKB1tRcPLOxKfapKTRzLQhsejlf79iCK5Gz8HWtqKhc+WAhA2GOPXf5K01c4QXffjeDtjSk+vkJemPy9LgFv/dW/QCUNmHnz5tG9e3f8/PwICwtj5MiRHDlyxGNMnz59EATBY5kyZYrHmKSkJIYOHYq3tzdhYWHMmDEDm83Tzbx582a6dOmCXq8nNjaWJUuWVO0KrxCKvqZFl+eff77UfU+ePIkgCCV2L3YhFhQg2u1SbZcqNFGU68EUFNQLF/3mzZsRBKFYY8bvv/+euXPnlru/6HBgOX0G6/kLlzQPlwGj0uurfIybb76ZRo0a4eXlRUREBOPGjSu123UxXAJenQ5EB4KgQqXSo9UGAGC35xbfJzgWdH6YVSb2/3c/BQVJ6HQhtIh9lrj9NiLOm/EKlDQnZr0aErfAhdJrgpREfr5Un8TbWwpzBARcC0BG5q6SxcUlIYqFHhi/cGmB+mPAXDwGnw2Gi0elMN/hX6r18LIH5vhx7M6uwvqmMdV2fPdspPOvvYaYn4+hc2f8R46otnMoSFTGC+PIy8N8WLpvGzp1uhzTqzEqZcBs2bKFqVOnsmPHDjZs2IDVamXgwIHkOd3gLu69915SUlLk5bXXXpO32e12hg4disViYdu2bSxdupQlS5Ywe/ZseUxiYiJDhw6lb9++7N27l+nTpzN58mTWrVt3iZdbf3F/Pd966y2MRqPHuscff/ySjm93z4RRVd4xp9JqUXl7AyDaKq95qCsEBQXhV46YVhRFrGfPYs/MwHb+HA5rFQqsOXHpX4RLMGD69u3LihUrOHLkCN999x0JCQnceuutFdvZ5hLwSuErtdobQRDQav2l9fb84mEklQoiO5HQxAe7w4TRrwNxPX4n2hSJKjMZvALwiugJgCnU2RTwn4r3S7HZ8rBYJLGtt6EJAH5+bVGrvbHZMsnLO1axA5kyZX0PfuHg62wOWh+EvGf3wmeDIPu01GAT4Hj55fkrgy4qCjQacP7/aiMj5c9wdeB3o2TA5G3dSvaaXwuFu2V9v7iMznrwEFTXqKgXpuDAAXA40ERGoA0Pv3wTrAEqdadau3YtEydOpG3btnTs2JElS5aQlJTE7t27PcZ5e3sTHh4uL+7NmNavX098fDzLli2jU6dODBkyhLlz5/L+++9jcbZ2//DDD4mJiWHBggW0bt2aBx98kFtvvZU333yzGi65OKIo4rDYa2WpqGrc/fX09/dHEAT577CwMN544w2ioqLQ6/V06tSJtWvXyvvGOMV6nZ0Fi/r06QPArl27uPHGGwkJCSGkWTMGTpzI3oRSUmNLIS8vj/Hjx+Pr60uTuDjeXrpUqgnjViMkIyOD8ePHExgYiLe3N0OGDOHYscKb0JIlSwgICGD16tW0bNkSb29vbr31VvLz81m6dClNmjQhMDCQadOmYbcX3kzNZjOPP/44DRs2xMfHh2uvvZbNmzfL20+dOsXw4cMJDAzEx8eHtm3bsmbNGk6ePEnfvn0BCAwMRBAEJk6cCBQPIZnNZp544gmio6Nlb+Anb7+N3c1z4559VVLILSAgQPYgWiwWHnzwQSIiIvDy8qJF7968vmiRbMBkZmYyefJkQkNDMRqN9OvXj33ltKx/5JFH6NGjB40bN6Znz548+eST7NixA2tFDCurp4BXrZZuYCqVXv69pKJ22ZGNSGkgzblFi9loND7wj1Tbg0534uXdCABTgKSnYe9yqax/BXClUGu1gbIhpVJp8TdK2psKp1O7vC9eAVKPJ1+p63qd98Cc/AuWDIP8NIjoBON+KFxvLaXAYBUQtFrJiHGiu4QCdiWhb9pUOqbzuyDw9tvxat267J3+XQYLWsK/X1TrXK4GKuKFEW02Mr75BgDvTvU7fARwSarBrCwpSyEoKMhj/ZdffsmyZcsIDw9n+PDhPPvss3g7Lfvt27fTvn17GjRoII8fNGgQ999/PwcPHqRz585s376dAU73o/uYsrQJZrMZs1sGTHYlxKSi1cHZ2dsqPL46iXyhJ4Lu0nrfvP322yxYsICPPvqIzp0789lnn3HzzTdz8OBBmjdvzs6dO7nmmmv47bffaNu2LTpnnYecnBwmTJjAO2++ienECd5eupSb77iDY8eOleuFcDFjxgy2bNnCjz/+SGhICLMeeYS98fF0bNcOURRl4+DYsWP89NNPGI1GnnjiCW666Sbi4+PRarUA5Ofn88477/D111+Tk5PDqFGjuOWWWwgICGDNmjWcOHGC0aNH06tXL8aOHQvAgw8+SHx8PF9//TWRkZH88MMPDB48mAMHDtC8eXOmTp2KxWLhjz/+wMfHh/j4eHx9fYmOjua7775j9OjRHDlyBKPRiKGUsNn48ePZvn0777zzDh07duR4fDznDh8GpCJSDpMJe04OmuDgCr1e77zzDj/99BMrVqwgKiyME3//zelz5xCcr8OYMWMwGAz8+uuv+Pv789FHH9G/f3+OHj1a7HNWEunp6Xz55Zf07NlTfm3LxOWBQfKauYwWAK3Wn4KCvGIGjCiKHDUcAatAeLY3/v6dpU7Wx5we0q5346WVPn9moQCCmkL6CTiwArrdU+6U3FOo3QkI6E56xl9kZu4kOmpc+dfm0r8YI6Wf9cGAOfIrrJwovS+Nr4M7vgK9HxijJG/Mya3QfEC5h6koupgYuR+SvmnVeyCVht+AAaQlJKAOCiL04Wnl75CwUfp58AfoMr7a53OlE3T33aR/uVz2wvj16ytvc5jNnH38cSm1XaXCf9SoWpxp9VBlA8bhcDB9+nR69epFO7c88jvvvJPGjRsTGRnJ/v37eeKJJzhy5Ajff/89AKmpqR7GCyD/nZqaWuaY7OxsCgoKSrzZzJs3jzlzKt4O/Epi/vz5PPHEE9x+++0AvPrqq2zatIm33nqL999/n9DQUACCg4MJd3MZ9uvXD9Fmw3IqCUfTpix8+WUadO/Oli1bGFaBAlO5ubl8+umnLFu2jP79payDpcuW0ahZM0SrFfvFNBIzM/jpp5/YunUrPXtKYYUvv/yS6OhoVq1axZgxYwCwWq0sXLiQZs6nwFtvvZUvvviCc+fO4evrS5s2bejbty+bNm1i7NixJCUlsXjxYpKSkoiMlG5Qjz/+OGvXrmXx4sW8/PLLJCUlMXr0aNq3l0pdN3X7gnYZA2FhYQQEBJR4fUePHmXFihVs2LCBAQMG4LBYiDSbEZs0QR0QgCY0FPOxYzhy8xBttgplESUlJdG8eXOuu+46HNnZhHfpImUgCQJ//fUXO3fu5Pz58+idHpn58+ezatUqvv32W+67775Sj/vEE0/w3nvvkZ+fT48ePVi9enW5c8FhA7sFhwAOUTJgVKrCz5ZG4w+cRRQtFBScwctLem/OnV9NlvUkKrtIs8OpkhB4z+dSRlOT6yG0BfqCMwCYzKmI3R5EWP807PoUut4N5dT+KEyh9qwIGxB4LSRKQl6XcVwm7voXKAwh5ZRtwBQUnOZU0ifo9WH4+bXFz68del1IqeMdDgt2uwmt9hKFqQdXwbf3SG0dWt4Et35W2B08tj/sWSqFkarTgHHqYKB6asAUJWjCeKynTxMw5lbU/v7l73DR6ZlN3iml36trITOvHuPywqR9soiL772Hb19Jk2rPzeP0gw+Sv2MHglZL5BsL8L2uV21P95Kp8n/H1KlT+e+///jrr7881rt/ybZv356IiAj69+9PQkKCfHOqCWbNmsWjjz4q/52dnU10BZuECVoVkS/0rKmplXvuSyE7O5uzZ8/Sq5fnP2OvXr3KDT2knj7NU48+xh9/7+BCejp2USQ/P5+kpIplOyQkJGCxWLj22mvldSGRkbRo3hwA6/lzHIyPR6PReIwJDg6mZcuWHDpUWNPD29vb4/+jQYMGNGnSBF+3jKgGDRpw/rykXzhw4AB2u50WLVp4zMlsNhPs9IZMmzaN+++/n/Xr1zNgwABGjx5Nhw4dKnRtAHv37kWtVtO7d29EhwNrUhKi3Y7Ky4A2MlISPLt7YQIDyz3mxIkTufHGG2nZsiUDb7iBQddcw6CbbgJg37595ObmyvN3UVBQQEI5ob0ZM2YwadIkTp06xZw5cxg/fjyrV68u+yYvF7DTAiIqlR6VqvArQaXSyh6ZtLRNBAY2w24v4PjxVwFokiLiZbJIbQV2L5V26joRAL0+DFAhilYsbQeh//1FOPcfJO2AxnFlXkthCrWnoNTf2AGVSofFcpH8/ER8fMrxGLg8MH4R0k/f8kW8eXkJ/PvvOMwWzzE6nWTM+PjEYrPlYDafcy6pWK2SALZly7lENbyz7DmVhsMBa2dJxkuH22HE+54379gBhQZMNeLKRIJL64FUGpqgIBoumF+xwQ4HpDn/zy25cP5gYfq7QoUp6oUxdO5E8n3/w3TgACpvb6I+eB+fHj1qe5rVQpUMmAcffJDVq1fzxx9/EOUWQy0J143r+PHjNGvWjPDwcHbu9Ixhn3M2oXJ5B8LDw+V17mPKcvXr9Xr5qbWyCIJwyWGc+obDYmH8HXeQlpHB/Keeoln37hiMRuLi4mQtUlUR1GqpHLkoyjUgyqNouEMSkhZf53DG03Nzc1Gr1ezevRu12vO9cxk9kydPZtCgQfzyyy+sX7+eefPmsWDBAh56qGI1KFz/a6IoYj1zFofJhKDWoG0ULQsRVUYjDpNJ0sE49TRFY8/uWpQuXbqQmJjIr7/+yvpVqxj3+OP0+/lnvv/5Z3Jzc4mIiPDQ8bgozUvkIiQkhJCQEFq0aEHr1q2Jjo5mx44dxMWVYSy4Cthp1YDNI3zkQq2WQokXLv5Os2aTOJW0CLM5BS99JI2EYGATbJ4HuangHQKth0uvi0qLXh+G2ZyKSchH3/5WSdewa1H5BkyBKwOpicd6lUqP0diZzMy/ycz8uwIGTCkemFJEvDk58fy7dwJWazreeTb8rAZywhuSbzqFxXKetLTzpKVtKvV0R4++gNGvHUZjxY1kmaRtkHMWvPzh5neKex6a9gZBDWnHIOMkBDap/DlKwN0DUxMhpEqRfbpQdA2SsasYMJXG3Qtz4a23EO12LAkJqAMCiP7kYwzta6/5YnVTqcd/URR58MEH+eGHH/j9999lcWhZuFJ3IyKkp6C4uDgOHDggP0kDbNiwAaPRSBtna/C4uDg2btzocZwNGzaU/WV8lWI0GomMjGTr1q0e67du3Sq/ni7Ni0sA6zCZsJw4wfY9e5g6fjw3T5xIe2fK+sUKGhwAzZo1Q6vV8vfff8vrMjIyOHr0KCofHwStlpaNGmGz2TzGpKWlceTIEXl+VaFz587Y7XbOnz9PbGysx+IeJouOjmbKlCl8//33PPbYY3zyySclviYl0b59exwOB5t+/hl7ViYgoI2ORuXWK0buxp2bi2i3ExoaSkpKYQfkY8eOkZ/v2dTQaDQyduxYPpg7l89ff50fVq8mPT2dLl26kJqaikajKXZNISGlhzCK4jLyzOVVRXZ5YJzfAiUZMFqtLyBgMiVz8eJGTp36EIDY2CdQN5SKy5Hwu/Sz8/+BpvAhwksvfebNphToPllaGf9juVlALg+MoYgBA+71YHaVfW0A2c5UctkDU7oGJitrD3v+vQurNR0/u5Gu+7Jotz+FuH8y6NN5Hd26rqRFi+eJippATMzDtGr5Eh07LOKa7qu5/rqdhIYOQhStHPjvwdIrGJfFgW+ln62He7yGMl7+EO30Yh7fWHx7FfFq3RqV0Yi+dWvU5RjJNc7FIqn2SdtrZx5XAK6MJPPRo1gSEtCEh9N4+ZdXlPEClfTATJ06leXLl/Pjjz/i5+cna1b8/f0xGAwkJCSwfPlybrrpJoKDg9m/fz+PPPIIN9xwg+y6HzhwIG3atGHcuHG89tprpKam8swzzzB16lTZgzJlyhTee+89Zs6cyT333MPvv//OihUr+OWX6q2DcKUwY8YMnnvuOZo1a0anTp1YvHgxe/fu5csvvwQknYfBYGDt2rVEBgWhunABo7c3sU2a8NWGDcQNH052djYzZswo1cNVEr6+vkyaNIkZM2YQHBxMWFgYTz/9NCqVCkGlQhsVRazVxrC+fbl30iQ++uQT/Pz8ePLJJ2nYsCEjRlS9HkSLFi246667GD9+PAsWLKBz585cuHCBjRs30qFDB4YOHcr06dMZMmQILVq0ICMjg02bNtHamQXRuHFjBEFg9erV3HTTTRgMBo9wFUCTJk0Yf9ddTH7wQeY/+SRdrrueM//s4vz589x2222AlP4s6HSIFgv2nBz69evHe++9R1xcHHa7nSeeeMLDk/TGG28QERFBp06dsJ5I5Pv16wkPDycgIIABAwYQFxfHyJEjee2112jRogVnz57ll19+4ZZbbqGbs7+MO3///Te7du3iuuuuIzAwkISEBJ599lmaNWtWvsFvK0AEHEhGXEkGjCCoUamkInv/HXwYh8OEv383wsKGQkaR8FTXCR5/6r0iIPtfTKaz0GgwRHWH07ukcFPvGSVPyZYjh2S8i4h4QRLyAmRk/l2+DsbpgbH5BHD00JNoRS3BAVoCstJR2SygkQzR9PRt7D/wP+z2fPz9u9Fpfzoa2wlQaSA9AfUXt+I/YTX+UV1KPVXrVq+Qm3OIAlMS8Ydm0qH9hxXv82OzQPwq6fd2xdPfXXVvhNj+kqfm+EboPqlixy4HtZ8fsRvW114hRXcuSg0l8QmFvAuSB0YUy9VMXSoFBWdIPr0Eh8NMi+azPcKo9RVNUBBB//d/pH38MbqYGBp9ugitUyt4JVEpD8zChQvJysqiT58+REREyMs3zrQsnU7Hb7/9xsCBA2nVqhWPPfYYo0eP5ueff5aPoVarWb16NWq1mri4OP7v//6P8ePH88ILL8hjYmJi+OWXX9iwYQMdO3ZkwYIFLFq0iEGDBlXTZV9ZTJs2jUcffZTHHnuM9u3bs3btWn766SeaO7UoGo2Gd955h48++oio2FjGTJ2KymDg0yVLyMzMpEuXLowbN45p06YRFhZWqXO//vrrXH/99QwfPpwBAwZw3XXX0bVrVwDUPj5owkL5aO5cOrVowbBhw4iLi0MURdasWVOxLJkyWLx4MePHj+exxx6jZcuWjBw5kl27dtGokZTCa7fbmTp1Kq1bt2bw4MG0aNGCDz74AICGDRsyZ84cnnzySRo0aMCDDz5Y7Piiw8HbTzzJLTfeyCMvv0y7nnHce++9HnWPBEHwqEK8YMECoqOjuf7667nzzjt5/PHH5Qw8AD8/P1577TW6d+/O9bePJclpoKhUKgRBYM2aNdxwww3cfffdtGjRgttvv51Tp04VE7W78Pb25vvvv6d///60bNmSSZMm0aFDB7Zs2VJ2SFUUwWrCoQIRUS5gVxJqtWTUOhwmQKBF82ekm3Ok2w29WT8p28gNLy/pC9Nkdnqkut8r/dy9GBwle75cBex0uhA0muItLfz9uyAIWik0ZUou/fpANmDO2P8jJWUlSanL+beDP3/EBbF//32cPbuC1NQf2bd/EnZ7PkGB19G502I0F09K+9/6GQQ0kjKolgyVMq1KQas10q79uwiCjosXfyMpueJ1bzixSWoV4BMGMTd4bBJFkf0HprDlj46c8E+TvGWJWySjp5pQ+/tfUiHFaiPNKeBtdyuotJKGKfNUjZ0uL+848fEz2L6jH8nJn3HmzJdkZO6osfNdbkKnP0z0xx/RZMU3V6TxAiCIFS1EUs/Izs7G39+frKwsjzo0ACaTicTERGJiYvCqC08elwl7Tg6WU6cQtFr0sbEI6prX/YiiiCXxJI78PNR+fugaNy5/pzqC9dw5bBcuIKjV6Js3LzXLyJFfIDXDU6nwatWqQoUAXe+FSq9H7zQ0Lys2C5w/iEWrwqRXodH4ylVv3TGZTJw4cYKLaY9htR4lImIMbVq/UjjgzXaQlQxjl8n6FxfJyUs4emwuoaGD6dD+fSlb6fVYMGfDlL8gvLg7OzX1Jw7GP4K/fze6df2mxKn/s3sMWVl7aN36VSIjSinY53DAi6HgsLFr8HVk5x/G39iZgrR/sZRgN4eG3Ei7dm+jspjhFaf4/8kkMGVLxkvmKakdwcTVklFTCqfPLOfIkWcRBDVdOi+XeziVyXf3Sinm106BIa96bLpwYT37D9wv/623QGxCDg2GfIvQ9IaiR6rfLB0OiX/AyIVSTaHTu+CWj6Dj7dV6muzs/Zw89SEXLqwHCusf2e35NI99mkaNyk/1V6hZyrp/u6P0QrqKkMvWGwyXxXgBpxi3oWT923NypFYD9QBHQYEsQNZGRpaZIi0YvKQ6Lg6H3E+qPGq/B5IrA0n6P1CpSw8dCoJAk8ZTCAkZQGyzIqGf0Z/CsLegVfG0e5cHxuzywGj0hX2UzuwuNh4Ka8CUZEy5CHDpYMpq7JifBg4bBV5qsvMPAyrad/iQ605F0X1PJjF+QzEaOwECEeGjaNfuXckDle7MgvEJlXQnAdFw9xoIjJGMmCVDIaN0r0DDyDto0GA4omjnv4MPY7Gklz5HAEt+YYuAIuEjh8PK8QSpinloyI14eTXErIODrf3YnTiD7Oz9xQ5nt5sxmVOx2+thV3hXCCm4OTRyZslUsw4mIWE+u/65hQsX1gEioSE30q3b9zSKlkJyFa7yrFAnqP/BPoUKUx1l66uCSq9H7R+APSsT2/kL6BqX/gRbFxAdDqxnzoAoojYaUZXTeM4VRrKlpWHPzq5Qozr5vdDVkuveVYFXLQAialXZJeTDwgbRqFEJmqVG10pLCeidIl6Tya0vU1Q3KQRy+h855dqdArcu1KURGHANp059SHrGVkTRjiCUYIw7U6jPRQYBIoGBPaRaLr7hGM/uxajqQtOu7+BwWFCpCkXZchpvkFtKsX8UTPxF8hCkJ8DnI+CetYXZTW4IgkCrli+Sk/Mf+fmJxMc/RseOnyIIpTwrHl0L1jzJuxPl6a05e3YF+fmJaLVBtGnzOoKgJWnXI5zKWUeW+iK7/rkFf/8uOOxmrNYMLNYMHA7pfdXrw4nr8Zsc/qvzmHOkLCyAkFhoFAfb3pV0MNV1CstFTiVJIv7wBiNp3Ph/+PpKZRhMBVJ4MFcxYOoVigfmKkI0S3Hzy23AAGjCpGJ69pzsOu+FsV286EyZVqONiKiQGFMl62ByPNoolIZocnrDvGrJgLEV4AAcSHMtScB7qbg8MBbLBRzOTtc0lPRRnNlT4j6FHpgmpR43IKAHWm0gZnMqFy/+XvIgpwFzPkR6RmsQJtXaKZpK7WG8gKR3AQguUhPFv6EzfNQYMhLhi1sgv2TvikbjS/t276NS6UlL/4OEhNdLvRb++0762W60h1jVZsvlROLbAMTETEOj8UOt9iKm/VzidmUQkSp50LKy9pCTexCT+axsvACYzamkZ9ROdfEqkeYm4DUEFmZcXThc6usMUtHBpOTFFfI4pZz9FlG0YTR2pm3bBbLxAuDjI4Vx8/KOVbi9i0LtoxgwVxGixXnTrIWnfpcXBsB2iR2caxJHQQG2C9L8NBERcon/8lB5eyNoNIgOO44izU2LIoqi/F7UhjGJKII5x+l9kW7iNZF5odUGycJgs9mZuuwyYC4cKrE3Ulkp1C7Uaj2REVIF59Onl5U8KCeFfC8VOV5WBEFNaOhAab2rmJ2rRkxRXDfSogYMSC0Jxv8oHeN8PHx5q+Q5KAFf35a0avUyAKeSPiY5eUnxQQWZcGy99Ht7z/DRqaRPsFrTMBia0DDSTQPiE4I+pBNtjuZyjd8DtGmzgI4dFtGt2/fE9fidG67/l4YN/w+AixerL926xnEPHwH4hECI08Aowwtz7Pg8jh17kROJZffJE0UHZ85+BUDDhsU1Nd7eTRAEDXZ7bmHIU6HOoxgwVwmi3S53iRb0unJG1wx1xQtjz87GmpKCLSMDR0GB7DEpGjqqUOlzJ4IgyF4Yezl9uESbDdFZf0bQ1cJ7Yc0Hhw27Wvr414T3BaTXpDCM5KqKGy719REdkLLXc1rWDGw2qYaKt6FssXfDhncCAukZf8mZSx7kpHI+VDKeAgPi0Omc1Y1lD0wp1XhLCiG5ExQD41dJXoIzu+HrO+V6OkWJCB9Js6ZSl/ijx17k3LkiZSAO/Qx2C4S2hgZt5dVm8zmSkqQspthmM1GpihjRzW8EwO/kf0SEjyQkpC/+xo54ezdGqzUSGiK19bh4cVOVvQl2u5l9/97DieMLqrR/pXHVgAmJLVzXyFkGoAwdTHb2XgDOnPkSqzWj1HHp6X9iMp1GozHSIGxose0qlU7WXeXmHS22XaFuohgwVwmyaFSjuWwC3qLUBS+MaLNhSU7GlpaG9cwZzAkJmA4dwpyQgCUpqdKhI3fU7mGkMm4c8nuh01UoY6nacXoNHFrJ61JTBgyAl1cJOpiGzvTrIkJel/dFrw8vV7thMEQTEiw1qivRC5OTwjmnAdOggdsNSy5mV0oxPZeItyQPjIuw1vB/34HOV8qa+fZusJfc+btx4ylENRwHiByMf5z0DLeb8X/O4nVFvC8nEt/G4SjA39i50HPkTqyzF1LC7yWmowcEXIta7Y3Fcp6cnP9Kv44yyEhZy8WMLSQmfUBG+mUoKOdKoQ4pDOsUGjAle2AslouYzZInzW7PJ6kkL5eT02eWAxARPqrU/y33MJJC/UAxYK4SakvAW5Ta9sLY0tNBFBG0OqlasEoFooijoEDOIKpM6Mgdlbc3glqNaLfhKFJ91x05G6y23gtTFiJgF2pO/+JCrsbr7pZ3iVVP/+Mx1uVJKUvA605UlBQqSUn9Drvd8/XOyz9Jrq8GARWhoTcWbiirI3V+ulSPBYrVtClGw65wx9eg8YIja2DVA1LqdhEEQaBFi2cJDR2MKFrYv38KObmHpYaSiX9Ig9qNlsfn5h7l7NmVAMQ2n1WyER3ZBbwCwJRZopZIrdYTFHQdQOkaoXLIPfen/PuRQ0/hcJRsoFUbRUNIUJiJdPZfWXTuTk5OPACCIBnip08vxWYrHtIzmVLkFhANG95R6hR8fCTjKS9X8cDUFxQD5iqh1m+aTmrTCyM6HNjTJUGgpkEY+pgY9K1bo2/eHF10NJqQELTh4ZUKHbkjqFSo/KTeQY6s0sNIYm0ak3YbWPOLFLCruVRuvauYnYcHpmQhr0vAW5b+xZ2goOsxGBpjs+WQmvqjx7bzgpTqHKRvhVbr1mTTXcRb1EvmCh/5RYLOp/wJxFwPt30uVew9sAJ2fFDiMEFQ07bNGwQEXIPdnsvevXdT8N9SKYzWsJsUlnIiCX4dhIYOIsC/a8nnVWugmeR9Kq25Y0iwM4yUVjUDJqeg0AuRZ07i9JlStEZVxGrN4OixFzl7dgU2S1ah9ijEzYAJbCLpjRzWEg01lwETGjoQb2+pyWby6c+LjTubshJRtBMQcC0+PrHFtrvwdXpgLikTyZQFlrI1cArVh2LAXCWIltrLQCpKbXlh7FlZiDYbglYrh3sEQXAaVf5ow8PRhIRUOnTkjtwbKTur1DBSrXrDzJJhZddK2huVynBJ11seLg+Myd0DE9EJBJXUvM9NTCt3oa6gASMIKqIa3gXA6TPLPF7vcz7Sk3hYUD/PnVweGFuB/FrIVCR8VJQWgwqLz/25oFRRr1qtp0P7D/HxaY7Fcp5/sz/lcKwPCS0bcOrUx5w5+w1JSZ9xMe13BEFdvN5OUVxhpFIMmOCQPoBATs5/hQLqSpBrOQNA6AXpf/XEibcwm6vvgePUqY9JTl7MocOz+HNrD/6L1XAx2IDDv2HhIEEosx5MTu5BAIx+7Yhp8gAAycmLsdkKDQiHw8bZs1JBRA8xdAnIHpi843L7hkphzoEP4uCTfiV64xSqH8WAuUqo9bojbtSGF0YURexpaQCog4JqTHui8vWVwkg2W6lF7WrVGyYbMDWvfwG3dgLuHhi9ryRcBQ8dTIErhbqCISSAiIhbUam8yM09TFaWdKzc7EPkGUBwiIRGeFYHRucNemednqI6GFnAW8muzF0mQnAsFKTD3x+WOkyr9adTx8XotaEUaG2ciTRw0vY3xxNe5fDhpzh2/CUAIiPvKLOQHwDNJA8LZ3ZD0t/FNut1IRiNUifnixdL76BdEnZ7AfmiFEprkZCHMduK3Z7L8YRXytmz4qSnS81ntdogHKKFc2F69rX1YeuO3hw99lKhILcMHYxL3+Pn146wsKEYDI2xWjPkbCOAtLRNmM2paLVBhIWV3YrGYGiEIOhwOAowmc5U/qJObIbsM1Lqd17dzbS8klAMmHrExIkTEQSh2DJ48OAy9xMdDjcPTM1lvUycOJGRI0dWaKy7F8aeU/jU+sknn3D99dcTGBhIYGAgAwYMYOfOMiquVhBHXh4OkwlUKjSBgeXvUEUElUru6mvPKJ4VIdpsbtlgl9mAcaVPC2BF+n/QaMovuncp6L1K0MBAMSGvKIrk50thn3Jv3m5otf6EN7gZQA4fnD8j1VYJyrShNZZgjJSWiSR7YEoPM5SIWgN9Zkm/b3tXSo8uBS+vCLqLQ2lxPJeYrBCiosYTHj6SkOB++Pt3JTi4N01jHi7/nMYIaDEYEOGLkdLNswgukXNlw0i5eUdBAK3FgV4TSIuEPBAhNXUVmZn/lH+AcrBY0snJlcI/116zhu5e44g6U4DWocFiuUhy8mecPLlQGuzywCTv9BAsW63ZFBQkAeDn1waVSkOTxlLLhaSkRdjtUmbYGad4NzLi1lJ7fblQqTT4+DQtfA0qy7ENhb9nJlV+f4VKoxgw9YzBgweTkpLisXz11Vdl7iNardLNS6Wqkji1POx2O45KukxVer18o7ecOiVlAFksbN68mTvuuINNmzaxfft2oqOjGThwIGfOVOGJyH2OLu9LQECZbQGqA9mAycmRjRUXDlcxQa328meDOdOnLXrpvBqNHxpNDXtgnCEkmy3HU2Dp0sE4hbwWy0Xs9lxAhcEQXalzREWNA+DChXWYzec5lybVVmmQ4w0ledpKE/KWVQOmPNqOkrxKpizY/n7p47JOo9/+KdFnTTRtPJWWLZ6jbZsFdOz4Cd26rqBTx8/Q6YIqds5bF0tNNK358OVtcORXj80hznTq9PSt8g29IuTmHALAL8+GcO39+OfYiHQWzjty9DkcDltZu5eL1DBRxMenBXp9KMaMHFom5HEdY2nWbKY0Z1cRvgbtpGwvcxacP1Q4R6cB5OXVUNY4hYePwEsficVygbMpKygoSCYtXRIjR5YTPnIhZyLlVlIHI4pFDJiaa0KpUIhiwOBsOGix1MpS2ToNer2e8PBwjyXQ6VHYvHkzOp2OP/8szCB47bXXCI+K4tzFi6h0Ovr27cuDDz7Igw8+iL+/PyEhITz77LMe88jIyGD8+PEEBgbi7e3NkCFDOHas8AO9ZMkSAgIC+Omnn2jTpg16vZ577rmHpUuX8uOPP8qeoc2bN2OxWHjwwQeJiIjAy8uLxo0bM2/ePAC0ERFogqQva3t2NuZjx1jyxhvc/7//0alTJ1q1asWiRYtwOBxs3Fj1olwOs1n28miCg6t8nIqiMhhQeXmBKGLPzPTYJpqlG0Gt6F9M2ZL3RSNpXvT6ynUerwoaja/s5ZFrwUBhJtLZf8HhkAW8Xl6R5T4pF8XPrw3+/l0QRRtHj80l33JGCh85IkreweWByXEzYEQR0pxVeEurAVMWKhX0dXphdiwsuXqs3Qrf3iNlOkV0gg5jK38ed3TeUiZUq2FgN8M3/1dY2Rfw9W2FXh+Bw2EiI6O4hqQ0cnMPS/vn2qBxT4juQbPEPDToyc09zJmzyy9p2hnpknESFNhTWuGsAaMKbklExGjnHA5JYSS1BqK6S+PcdDA5OZL+xc+vsH6OSqWjceMpAJw69RGnT38BiAQFXoe3t7Ou0IWjcODbUjUqVU6lPh9f2AoBFA/MZULphQRYrVZefvnlWjn3U089ha6aipn16dOH6dOnM27cOPbt28eJEyd49tln+XrRIhqEhMg3zaVLlzJp0iR27tzJP//8w3333UejRo249957ASkUdOzYMX766SeMRiNPPPEEN910E/Hx8WidHpz8/HxeffVVFi1aRHBwMBERERQUFJCdnc3ixYsBCAoK4p133uGnn35ixYoVNGrUiOTkZJKTkwGkeiuRkaiDgrCmpODIy8N24QL2jAw04eFoAgLIz8/HarUSFFTBp9ISsKdJNxOVn99l052oAwNxpKRgz8hEHRwsC2VrW/9i1kvPLBqNscb1Ly68vCLJzc3GZD5bWL49tDVoDJImJ+0YBdaTQOX0L+5ENRxHVtYezp9fA0BwugWNT2TJg13VeN09MHkXwJIDCB5ZQZWi1XCpw3bqAdj6Ntw4x3P77y9C8t+SBmfMEqm55aWi0UvHWnU/HFgJ302WUo47/z975x0eR3l18d/M9tVq1btVLBe5dxvbYKrBNiUQOoFQA6ElIRCSjxQCAUKHUB0IwXQI1RAgYJoNGNwtd8uyrGart1XZvjPfH+9Wdclygz3Ps8+uprwzO9rdOe+95557CZIkkZx8Ivv2vUpDwxckJ5/QryHb2kWkw9LhE9GqKT9DX7mKEVUaijJhz55HSEs9Fb0+eVCn3NQs9C+JiUeLBQ2hCiSDPpmYmFF0dBTT3LxG6FZy5sCer4QOZpb4jQpUIMVaxkWMnZFxLqVlT+Jy1VBR+TwQMD304+0roHarIJH+scJhCQp5B0hgAo7KAUQJzEFBNAJzhOHDDz/EYrFEPMLJ1913301CQgLXXHMNl1xyCZdddhmnnSgqMQIEJjs7m0cffZSCggIuvvhifvWrX/Hoo8KKO0BcnnvuOebNm8fkyZN59dVX2bdvH0uXLg0ex+Px8PTTTzN37lwKCgqwWq2YTKaICJFer6eiooJRo0ZxzDHHkJubyzHHHMNFF0V6MchGI/q8PPQ5OUg6ParXi2fvXnw2G3/4wx/IzMxk/vz5g7peqs+Ht0VoUQ5G9CUATVwcSBKKy4nqDIXvD1kFks+Dz+fAqxVfeYMh7aAdOuDG6wqPwGi0kDlFvN63fsAl1J2RmroAnS70/02rd0NsHxGYcBFvQMAbnz14YiHLcMKfxOs1z0aOv2sZrPyHeH3mk4MnSd1Bo4OfPgPTLhOl2e/fAGtE08LkZPHdb2jsnyuvqiq0+wlMbLsXYtNg/E9BayJrdwWxhjy83jaKdv1tUC6/DsdeHI4KJElDfPzMyCaOfu1RQrzQvTS3+CMuwUqkkJA3UIEUGzsh8lJoDOTmBIiJil6fGrwG2PYK8gLwxV3dmhkGIzD23ahqV5PAHlHsrwbLEMLpKIE5OIhGYACdTscf//jHQ3bsgeCEE05g8eLFEcvCoxN6vZ5XX32VSZMmkZuby6OPPopaK2aagVn/7NmzI0pn58yZw8MPP4zP52PHjh1otVqOOirUYTgpKYmCggJ27NgRcZxJkyb1eb6XX345J598MgUFBSxcuJDTTz+dU07p6i4a6OgsWyx4qqrwtbRw37338sYbb7B8+XKMxsF5lfiam0FRkA0G5Jh+eHsMESStFo3Vis9mw9fcjGwS7p+HzAPG1YZLL/7nWl0cGs2B837pjG4rkUDoYCq+FwQmR5C8/pZQd4YsG8jKvICy8qeRVZnkJjdM7NotGuheAxPQvwwmfRSO0QvF+9q3Hr59FBbeC7Z98N4vxfpZ18C4brp67y9kDZzxmNCLrHoK/vcHGPsTEuLnIMsmXK4a2tu3R6RcuoPTuRefrwNJUTF7DWI8SYJxZyJtfoOClizWmSqoq/uIPebhjMj/7YBOs9mvbbFaJ6PVxkLdRrHCnAxm8TuWkDCbvfteprnZT1iGzQBJI8ruWyrxxSbR0SEIZ3fvJyvrQsrKF+PxNJGZeX6oFUNJWDWWywaf3Q4/jawaM5mykWUDiuLC4ajon6DcaYOK71GBrePi0MRaGNtYzoEzJ4gigGgEBnHz1Ov1h+QxUA+OmJgYRo4cGfHonF757jvxI9HU1ERTU1OEdf1QwWTqn3/ItGnTKC0t5a677sLhcHD++edz7rnn9ri9JMtoEhL4xwsv8ODTT/Ppp5/2iyh1B1VV8QbEu2FpnIMFjV+b5LPZRCWYzycE1Rz8FJLP1RyKvugPvPYlHN16wUCEkHcwJdSdMSz7MqzWyeS2paD1qaL5Ynforp3AYDxguoMkhaIwa/8tZuJvXylKrDMmwyl379/4fR17wT1C+Kr6oOwbvyuvSNXU98OVNzx9JMekhTpkTxV+O3Gbv2LMyL8AUFb2JPv29V5A0BkBcW5CUP/S1cAuPn4WINI4bneDMBUMRDYKX/WLjBX0+pRudVwajZlx4x4kI/1scrKvDK0o8b//UacAEmx6HcojO3ZLkoYY88jg8fuFPctB9dE6LI86z3aq043Y3fu6GiVGMeSIEpgfGEpKSvjtb3/Lv/71L4466iguu/RSfP6bZmDWv3p1pG/EqlWrGDVqFBqNhrFjx+L1eiO2aWxspKioiHHjIvPNnaHX6/H5uoZdrVYrF1xwAf/617/4z3/+wzvvvENTUzciRz8eevJJ7nvmGd5fvJjpEyf2+713htLaiurxIGk0wcqggwk5JgZJp0P1+fC1toZK2TXaA14JFQFVxYWw2tdpLAc1+gK9RGD8Ql61duuATey6g0GfzMwZ75Jf5b9xxPYUgQmkkMI6UjcOsoS6O4w4Ueg2fC749ylQuWpodS+9QZJg+LHidZkQ8wdSKI39IDCBCiRLhzdE9AByj4H4HHC1ktViJC/vRgB2Ft3e73YFqqrSFBTw+vUvwR5IIQKj1ydisYwBoLnZ/zs0xt/Pavm9tH5xE9B99CWA5KTjGTfuQXQ6v6u24hM6GoB5t8C0S8Xrj27p0scqxjJAR16//qUpJy+4qCGOnvttRTFkiBKYIwwul4uampqIR0NDAyDKmS+55BIWLFjAFVdcwZIlS9i8eTOPvfiiKNv1l5RWVFRw8803U1RUxOuvv84TTzzBb34jvCdGjRrFmWeeydVXX823337Lpk2buOSSS8jKyuLMM3sPfefl5bF582aKiopoaGjA4/HwyCOP8Prrr7Nz50527drFW2+9RXp6OvE9EIr777+f22+/nWceeICcrCyqSkqoqamhvQdTuN7gPQjGdb1BkqRQSXVLS5j+5eB2oPa6mvD6K7b1xh6iEgcQhu76IQHEZUNMCu0mFUVxIssGjMZh+3/AtkDn6x40MAFi09EgWisANO1HBVJnhEdhAufyk8cHbpA3WOTNE8+lfgLj94NpbduMy9X7TTUYgQnoXwKQZZjsF8MWvkr+8JvIyDgXUNiy9dfYWjf1eVodHbvweBqRZRNxcVPEwkAX6vAeSITrYPxppKNvgvl3gtZIu1P8r2Jtzm6bWXaL6k1CuGuwisjf/DvAlCiqh1Y/E7HpgHoiqWpQ/9IcEyJCDYn6qA7mICBKYI4wfPLJJ2RkZEQ8jjlGNG675557KC8v55lnxBcyIyODxY88wp1PPMGWkpLgGJdeeikOh4NZs2Zxww038Jvf/IZrrrkmuH7JkiVMnz6d008/nTlz5qCqKh9//HGfep2rr76agoICZsyYQUpKCitXriQ2NpYHHniAGTNmMHPmTMrKyvj444+ReyAUixcvxu12c9H115N/wglkT5hARkYGDz300ICuk+JwiIaKkoRmPyqY9heBNJLS3o7SJkiYZDi4ERCXW7iC6lQtGs3Br34KRWBqIi3aJQmyposfe0RaIahXGCw8zlBDxp4iMOYk0coAFewNoqS2cYhSSAEMnwf5x4vXM38hhLAHC7lzxftrKoHWKgyGVGJjRSSzsXF5r7sGSqhjO3yhaq0ApvjF93tWINn2MqbgbpISj0VRHGza9ItgFK0nBNx3E+JnIst+Eh9MIY2O2DYhwU9gAjoYjRaOuQmu+462RBFVid20DJ5fAHU7ez0uEEofDT9WiJ7NiYLEACy/F1pD0UHLQEqpa7ZAew0+gxmbuzS42BanxdPUj/OKYr8QJTBHEF544QVUVe3y2LlTfFFuv/12qqqqSAqrtjlrwQJaNmxgytSpwWU6nY7Fixdjs9loamrinnvuidCHJCQk8NJLL9HS0oLdbueTTz5h1KjQDOnyyy+npZO/CUBKSgrLli2jra0NVVU5/vjjufrqq9m4cSPt7e3YbDY+//xzpoadS2eUlZUJ23+7HfuWLTi2bUPx+bjjjjsGdK2C0RerFfkAmPf1F7JeHxQP+2wtYtlB1L94ve34EDNDg/bgVWGFQ1Q8SaiqG7enU+owawYNSeJmluI3XtsvBCIeWqPo2NwdZA3ECCdo2mvFPl6HaMoYn7P/5xDAuUtEs8eF9w/dmP2BKR7S/bqxQBTGf23rG3r2U/J4WnE69wKBFFInfUlCnj+6o0Lha8iyjgkTniQ2djweTxOFm64QmpUeENS/JPr1L4rSfRNHAjoYCbt9T0QvJyVhGO1GQYJj3QbYuxaemddtO4UIBAS8gSaYAFN/Ljxm3O3w6Z+Ci0OVSKV9m/btFuZ1tlFTUFQ3BkM6Mb4YVEmiqeW73veNYr8RJTBHOBSXK5ia6A4HQsB7MCAZjaKnkKKgOPrvIgrCrt9nswFCvHuooenUukAy9kJgVFV0s22tEuH1QDRhEFBVNVi6rPcoyMYD10KhN8iyLigcdnXSwbjSR9IaK/RAwXLX/UGgOWRsekiA2h3CS6kDAt74XDE7HyqYE0XFkeYQFHsO96eRyr4GIMV/bZuaVkY0OwxHIPpi9OrQedXuI1hTLxHPK+6HlY+hlU1MnvRvjMZhOBwVbNn6624bISqKh5YW0RIkqH9p3esnjjpx7cOg08URGys0d0EdDEKXoqoetNo4jFetEoTK5xaNNHuCq03474DQJwUgy3DawyJate3dYDsGozELjcaMqrpxOPpw1PW77zali9+ZhIQ5JGlEqrDBub33faPYb0QJzBEMX0cHrt27cZeUdLGsD+CQdj7eD0iSFIxcKB0D0794m5tBVZGNpmD58qGExmpFkkNtA7r8LxRFlGK2VAifioZdIjLg7oDmCvAOjMAF4PXa8ClOJFVFrxiG9uY8QAR6IkW48QKNRhtIErFtHgy+ITi/oP6lD61PQKDaVrN/LQQOV+QFhLzfAmCxjMNkykVRHNTV/6/bXQL+Lxan/7YQLuINYMK5MPF8UeX02e3w+oUYfBqmTF6CLJtoaVnNvqo3uuzW2roJn68DnS4k0KXBn6JJzO+W5AV1MGEuwuEOvFL8MDj9H2JF8TJoLuv+WpStBMUjIkiddUgZk0WKD+Cj34HXhSTJwUqkXnsiOZpFjyagWSsii4kJc0m2CHF6o1w9MC+ZKAaMKIE5QqG43XgqK0FVURWli2U9BJo4RlYgLV++nH/84x8H8UwHD9liAUBp737G2B1UVcXnr3DSJCUe9NLp7iDJMnJ8XPB1RAWS1ylIS9MesDeC4hWeF8Z40JkBBZrLB1ySqaoKLpeIRujdKnKgA/MhQlAH44qMwDTYhMYhudEN+zbs/4HCIzC9IdyNN9iF+gdEYHJmi89Rcxm0VCJJEpkZwr6guurtbncJthBo80d0uyMwGi2c/awgDhoDFH8K/5xHTFMDI0f8DoDdu+/rUnEWKp+ejST5bzsNXSuQwpGQIDpRB4W8hBMYf0Vk8kjIPwFQYd3z3Y4T1L+M6CHCd8KfICZVVET5Izn9ailQ8hWoPjypo2i1C6KTkDiXuOSj0XoUPBofrf0QN0cxeEQJzBEIVVHwVFSKqItfDOttau7ijCnKdtWuN80jBMEIjMOO2s9mkRGl03FxB/L0BgRtYiJIErLFEkmqnK1iNitrhZlX4ghInyCcWhOGi5uQx9618WAfcLsbURQPkirSR+gPnolfdzB248br87lobBIRguQmN+zr1Om4vV40KGwsod/oqwIpgIgUkr8C6YcUgTFaQ07H/nLq9PSfAjIttrXY7aVddgl0iI5t9jfd7I7AgEjNzbgCfvG5+Ly27oUlixhW0UqcdRo+Xwc7d/4psr9a5/5HECqh7qF0PT5+BpKkweGoCBKiUAuBsBLqQEuADS8LEXdn9EVgTPGwyK9T+uZhqNkaLKXulcDs9lcfjRwPqJjN+RgN6cgJw0lqFhPH/paYRzE4RAnMEQZVVfHs24fidCBpNBjy85FkGdXtQumIjFQEfUcMhsMiEjFQSHq96J6tqigd9n7t4/X3PTpUpdM9QTYaMRYUoBvWqUzY7X9fMSnCxt5o9VfIAFo9xPm3b6sJbdsHFMWL2y3KZQ0un3AE1R3aVFoohRSamTe3fI+iODBIFmLbfVD6NWx+E/77G3hyJjw0El6/EF44rf/lskEC01cEJsyNd6grkA4XdCqnNhozSEoSy6qq34nYVFG8dPjTJZZ2j/gMxvTR6yhjElyzXHTiVrxIn/2FsS3DkGU9jU1fU1PzLgBebwe2VuG4G+x/BGERmNF0B602NtgqoLl5FYriDbU5CG8hMGoBWIcJs8Bt70YO0lIhiJKkCV2P7jD+p6IppuKF928gxihSTT0SGEUJ6l+aE0JVdABYs0hq8hOYus+63b2/cLlqqav7lOLd97F+/YWs+HoaZWVP79eYPyQcPr/wUfQLvoYGIVCVJHQ5OchGI3LAa6STOdyRqn8JQOhg/GmkfuhgFKcTxd4BHNrS6Z4gabVdSZXHT0p0PTRWNCWAMQ5QoaW8xy664XC5a1FVBY2sF2JMWSuEkocQRkMghRSKwDT4K2KSrbMFySpfCe9eDetfCPmDIAlSUtdPQWQwhdTPCExbNTT7oxE/pBQShAl5vw0uysg4D4Ca6ncjKmzsjlIUxY1GNmJyKoJQh+m2eoTRCuc+DyffBUBM4ccMz/s1ALuK78blqqPFthZV9WI0DsNkCqvy6iOFBOE6mFXY7XtQFCcaTUyk4aFGKyJCEOwBFUSg+mjYDBFp6QmSJAS9xjioLsRSJCJGdru4Ll1Qsxk66kBvoclbBkBioLpKoyPJmwKqSrtjd1cDxz7gdFaxffutrFw5j29XzmXL1uupqPgXLba1eL02ysqfwedzDGjMHyqiBOYIgq+tDY+/r5EuPR2NP8Wi9d+sfa1tKJ6QmdKRWoEUDtniTyP1QwcTKp2OPaSl0/2G4hVurdAzgZEkYfgma4Vepq26++388PmceNyCyBqw+KMv5t4rcg4CjJ0iMKqqBsPrydnnCnGlpIHMaTDnRrjwdfh9aajstfz7bsftgoFGYKo3iyoWjSEU7fqhIHu2+NzYKoIC15TkE9HpEnC5a2lq+ia4adCBV5spPjM9pY+6gySJHk8aPbTXkGM5idjYCXi9rRTt+mv36SNXe5cmjt0h5AfzPW1tohGjxTI2pKMJYNpl4vhVG0QfqgD6Sh+FIzYdFojGuIYVT6KRzaiqt9t0WyD64hwxB7tjDyAHyRaAPjaXuFZBEBv68N4JQFVVqqvfYdXqRVTXvOvXi8lYLGPJyryIsWPvx2gchs/XTn39/kV2fiiIEpgjBIrLJUS7iLLc8AiDbDQim82AKpoX+hEgMAe7785QIqiDcTp6rLQCf+l0y+FTOt0vBFJCGn3vpbYaXcifpKNO/Pj3gIBwV6u1ovX4r1dP5OggwuAX8brd9SiKm/b27bhcNciyiYSkY+HGdXDbXrjmK9HPZ8ypogw513/Tq+inp0YgAtNTH6QAAgTH65/JJg7vX8ThSILBIgghBNNIsmwgPU04aleHpZGCFUj4f1f6IoCdoTMGe1vJlWsYO/Z+JElLff2yYFVS0P8FQpVfYU0cu0Nc3HQkSYvTVUVd/afi1AIC3nBYUmDcWeL12n+LZ8UXLI3uF4EBmHIxjDgRyeskxi6inV3SSB4nFH0EQHN2tv+cxofaFgDE5whdF9DY8BV9weVuYPOWa9m+4/f4fO1YrVOYOuUljjt2I0fN+pAxY+4mM+NcMtKFIWJ1zbt9jPjjQJTAHAFQvV7c5eWoioJsNqPLyOiiaQkQGp9fzKuqKqorpIE5UiHrdMHz76zxCYevuQVUJYzMHQHoK30UDmOccJAFfyqpqybE623H6xUCTIMhHTz+m/Mh1r8A6HWJSJIeUHG5aoONBRMTjxbuwLIG9N1chxz/Ta/8u74rsVxtwpQM+o4gdDZp+6GljwIIppFC0ZYMfzVSfcPnuP3RumALAa//f9D5+vQHOaJqiPLviLWMIS/3OgB8PvG9TfRXFQH9Sh8BaLUxWK3ClC+QcuyxB1KgHHrrO2BvgqpCcLaAIS5E5PqCJIkKK10MluYWIKwnktclUlSPT4WqjSDJNJld/vc2N3Kc+ByS/ASmqfk7fL6erRDq6j5h9epFNDR8jiTpGJH/O6ZP+w+JiUej1Voitk33E5impm+7WBL8GBElMIc5VK8Xd1kZqtuNpNOhz87uVpyqsVqF8ZvXg9LWBl4vqv8mtz8pJEmSWLp06YD2Of7447npppuCf+fl5e1X6bbGr4Px9UBgVFXF2xTW9+hIESwHCEx3N+7uYM0S0RqfO7IRIX7TOr++RK9PQiPpQtGFwyACI0kyRqOY1Tud1cGbUZ/uu1nT/amJ2lC1UE8IRF8MVhF96A16S+R1STpIfYoONsKFvH4CGBs7ltjYCaiqh5ra94GwFgJ2/3encxuB/iDXL9D1d3jOy7s+2FfIYhmDXh8mCq4uFM8pBX0OG0rNBM5/QvcbZs+C9Iki1brx5bD2AfMGZiaYkAvz7yDGLiKYHc0bYe1zgrh8/DuR+rJmoZ79L5o7RJl0RHQJID4HS4cPg1eHojgjSsED8Ho72LbtFrZsvQGPpwmLZQwzZ7xHXt51yHL352s25/pdilVqapb2/z39QDEgAnPvvfcyc+ZMYmNjSU1N5ayzzqKoqChiG6fTyQ033EBSUhIWi4VzzjmH2trIEtCKigpOO+00zGYzqamp3HrrrXg7pQeWL1/OtGnTMBgMjBw5khdeeGFw7/AIhurz4S4vR3E6MU+ciGnMGGS9HkmSujzu/Nvfgo6v3qYmlEAFkl5PeUUFkiRRWFh4SN7H2rVrI3otDRQhHUz3qROlre2Qdp0eNAIpJF0/S5xlTUic6mwNLg54vvh8TiRJRq9PDZEXWRs0sFu8eDGTJk3CarVitVqZM2cO//tf96ZmBwKBpo6trYW0tW0BICnphN52iUhNBG6MPSJQTdSXgBfETDs8yjAUXagPR2QfJQTcbVURBDDTL+atrnoLl7sBt7sekLC0+SMFA9HABI81S1QvNZdCazWyrGf8uIeJjR1Pbk6n7/8ukQ4K9ovqBQEdDIAs64kx9xAtkySY6S+pXvvvYJlzv9NH4Zj5i1BTx+qvRdfq1n3CIPHUh+DXG7HnT8PlqkGS9MTHTY/cPz4HCUhuFYSwoVMayeHYx/oN51NTuxSQyc29jpkz3iU2dmyfp5aRfg4A1TXvdLHOGGqoqkrl3pfYsPHnffa6OhQYEIFZsWIFN9xwA6tWreKzzz7D4/Fwyimn0BE2M/7tb3/Lf//7X9566y1WrFhBVVUVZ599dnC9z+fjtNNOw+1289133/Hiiy/ywgsvcPvttwe3KS0t5bTTTuOEE06gsLCQm266iV/84hd8+umnQ/CWjwyoioK7ogLFIcql95WWUl1dTXV1Nf/4xz+wWq3Bv6urq/nd734XTCMp7e0orSKVcDikj1JSUjDvR1onoINR3e4IkTL4tUE1YuatSUg4pKXTPp8PpZ9+Nfg8wh0UBpbiCRjSeZ3g8+DzOeiwlwR70BgMaWL2FkxPmYIC3mHDhnHfffexfv161q1bx4knnsiZZ57Jtm3b+n/8/UDAzG5f1esAWK2TMRhS+t4xkJqo6EPIu8tPxvKO7n27AMJv0j/UFJLeLPr9QEQaKS3tDGRZT3tHEdVVbwFgNuehaff3MoodBIExWkUEBIKapdjYccya+QHp6WGd7Jv2iNJmWdsvciF0MCKKbIkZ03vDz4nniXRrSzlU+qMegyEwsozlhAcBsJtkfHHpsOhB+PVG4TujNdDsN+eLj5uGRtPpO+zXrCXXtADQ2PhVkGy0tKxj7bqzaG/fiU6XxLRprzFyxO+Q5f79VqemLkSWTdjtpbT6y9MPBBTFw86iP7Fr1500N39HyZ5e2jUcIgzo1/6TTz7h8ssvZ/z48UyePJkXXniBiooK1q8Xqm+bzca///1vHnnkEU488USmT5/OkiVL+O6771i1SnyYli1bxvbt23nllVeYMmUKixYt4q677uKpp57C7Y8a/POf/2T48OE8/PDDjB07lhtvvJFzzz2XRx99dIjfvoCqqvh89kPy6I5Bq4qCp7ISpaMDSZbR5+aSmZdHeno66enpxMXFIUlS8O/U1FQeeeQRcvLziZ8+naPOPZePPxChYVmvZ/jw4QBMnToVSZI4/vjjAREZOfnkk0lOTiYuLo7jjjuODRsG5oba0dHBpZdeisViISMjg4cf7vohD08hqarKHXfcQU5ODgaDgczMTH79618Ht3355ZeZMWMGsbGxpKen87Of/Yz6xsZgS4CvPvkESZL46KOPmDR+PGarlWPPO4/te/YExbsvvPAC8fHxLF26lFGjRmE0GlmwYAGVfhF0AO+//z7Tpk3DaDSSn5/PnXfeGREJfOSRR5g4cSIxMTFkZ2dz/fXX0x4WBQoc54MPPmDcuHEYDAYqKir6dV0lrZ7nXnuPn/7iVsyWWEaNGsUHH3wQsc22bds4/fTTsVqtxMbGMm/ePErKykFnQgUWL36EcePGk5w0gRkzzuTFF5eFwvSerumjM844g1NPPZVRo0YxevRo7rnnHiwWS/C7eaARMLNzOCoASE7q542lU2qiWyg+2PmxeD3m9P6NG05gfmgeMOEYHukHA6LXUErKAgDKyhcDoronaJg4mAgMRGqWeoK/goecOX6LgN6h0RiJi5sC9KJ/CUBvhimXhP5OGC4E2oOAPv0oDBphQFl47FS80y8SEUE/ujSnDIc1CyQNCU12ZEmP07mPjo5dVFW9xYaNl/hTRuOYNXMpCfEzB3ReWq2F1NSFQFc/n6GCx2OjcNOVVFX9hwBNqKv7JPjdPVywX/asNn/DvET/zH/9+vV4PB7mz58f3GbMmDHk5OTw/fffM3v2bL7//nsmTpxIWlroC7JgwQKuu+46tm3bxtSpU/n+++8jxghsE66r6AyXy4UrrKlha2trj9t2hqI4WL5iYr+3H0ocf9wWNJrQTSZgVOdra/N7veT2KUp97LHHePjhh3nmmWeYNGoU/37qKc678UbWL13K2MxM1qxZw6xZs/j8888ZP348er8mpq2tjcsuu4wnnngCVVV5+OGHOfXUUykuLiY2NrZf53/rrbeyYsUK3n//fVJTU/njH//Ihg0bmDJlSrfbv/POOzz66KO88cYbjB8/npqaGjZtCtltezwe7rrrLgoKCqirq+Pmm2/m8ssv5/3nl6A4HChOEeL+3W9/y4O/+x1pycnc8dRTnPub37Br0aIgI7fb7dxzzz289NJL6PV6rr/+ei688EJWrlwJwDfffMOll17K448/LohBSUkwzfXXv/4VAFmWefzxxxk+fDh79uzh+uuv5/e//z1PPx0ykrLb7dx///0899xzJCUlkZqayp49e/p1Xe985Fke+NsfefDxf/LEE09w8cUXU15eTmJiIvv27ePYY4/l+OOP58svv8RqtbJy5Uq8Xi8+g5kX33uPv93zKA8+eBvTps1k+/YqfvnL67Bak7nsssvC0lPdf3Z8Ph9vvfUWHR0dzJkzp9tthhqBCEwAySnze9iyEzqlJrB2kyLau1ZUaBniejcsC0fgJq0z9y/tdKQi7xjRfLHMr4PxR+QyM86jtva/QZFtbMwYaBPRmEETmNy5sHpx72XvgfTRqFP6PWz2sMuw28tIz/hp3xvPvApWPSVeDyb64ockSYyb9DibN19Li20t6zdcyJTJz2MwpKGqPpqbBfHvIuAFobmxZqGxVZBgGkejvZCt234TrGhKTVnEuHEPRPz2DwQZ6WdTU/MedXUfMXrUX9BojH3v1E/Y7eVs2nw1dnsJGo2ZCWMeorLqVZqaV1JR+TwFo+8YsmPtLwZNYBRF4aabbuLoo49mwgQhqqqpqUGv1xPfSYeQlpZGjT/MX1NTE0FeAusD63rbprW1FYfDgambBn333nsvd95552DfzmEDb3V10KhOn5ODxtK3PuKhhx7iD3/4AxdeeCGqqnLPH/7AirVrefLll3n6+ONJSRFh+qSkJNLTQ+K8E0+M/HI/++yzxMfHs2LFCk4/ve9ZbHt7O//+97955ZVXOOkkIcZ88cUXGdbZbTYMFRUVpKenM3/+fHQ6HTk5OcyaNSu4/sorrwy+zs/P5/HHH2fmzJnYUdEDqkNEFv54zTWcNHcu2uQUXjruOLKzs3nvvfc4//zzAUGEnnzySY466qjgeY0dOzZI5u68807+7//+T9zs/ce66667+P3vfx8kMJ2FyHfffTfXXnttBIHxeDw8/fTTTJ48ecDX9fLzz+CiCy8CSwp///vfefzxx1mzZg0LFy7kqaeeIi4ujjfeeAOd39Nm9OjR+Hx2Ojr2cPd9i7nnnls4//zL0eniGTdOYufOXTzzzDNcdunPQw0gO6WntmzZwpw5c3A6nVgsFt577z3GjeumLPUAIODGC8LYzhLTt4BTbGyFtAnCPKziO5hwTtdtdvxXPI9eIByM+4PATTpxxCH3yTmgGDZL+Ny014rqnxSh7UhImIPRkBnsT2Ux5IW0U4OOwPjJcN02UQnUuUTa3REy1hsAgUlNXRiMOvSJpBEiCrfzQxh/Vr+P0R0SE+YwfdprFG66kvb2naxbfx5Tp7yI19uG12tDo7EQG9vD5Dc+B2wVJMt5NFIYJC/Dh/+G4Xk3dvWyGQASEmYH/3f1DZ+RnnbGoMcKorGEltV3slm/Go/sxeCRmLzFRuxX5yMnmmiaEENV1dvkD/8NOt2h6WzfGYMmMDfccANbt27l22+/7Xvjg4DbbruNm2++Ofh3a2sr2f4a/b4gyyaOP27LgTq1Po8dgGK34/W76eqHDUPTjyhIa2srVVVVHH20CLNLkoQmIZE5U6awZdeuXj1gamtr+fOf/8zy5cupq6vD5/Nht9upqOhfmLCkpAS32x0kCSCicQUFPd+YzjvvPP7xj3+Qn5/PwoULOfXUUznjjDPQ+ns1rV+/njvuuINNmzbR3Nwc1JTsbWggX5JQfaKy6qipUwXBs1pJAgoKCtixY0fwOFqtlpkzQ6HZMWPGEB8fz44dO5g1axabNm1i5cqV3HPPPcFtfD4fTqcTu92O2Wzm888/595772Xnzp20trbi9Xoj1gPo9XomTRJlnqqq4vXaqKws4u67n+Cbb1Z3f139acNJY0cFK5BiYmKwWq3U1YkWAIWFhcybNy9IXgJwu5vp6OigtLSSG2+4g1//+q7gOq/XS1xcnL8fjCqM4TSRN/OCggIKCwux2Wy8/fbbXHbZZaxYseKgkJiAGy9AcvJJA6sWyz1aEJjybgiMqoqbFcDYfqaPIHgjJ3Ny79sd6dAZRRSr7Bvx8L9vSZLJyDiX0rLHAbDgvykZrP2vjOsMS4poDdCwCypXQ8GiyPV7VgjzxvicflUgDRpn/wtslUNyjNjY8cyY/hYbCy/H4Shn3frzSUw8BoCEhKN6rBgiPgfKIdlpZZekR5I0jBv3IGmpi7rffgCQJJn0jLMpK3uS6up3hoTANH7xSzYl7kGVRXf4ydtaMbjFb1VCkwOLmk270sTefa8xPO+G/T7eUGBQBObGG2/kww8/5Ouvv46Ybaenp+N2u2lpaYmIwtTW1gZn/unp6axZsyZivECVUvg2nSuXamtrsVqt3UZfAAwGA4ZBClYlSRp0KG+ooKpq0GVXEx+/X40ItQnxosmjLIOmZ3Ouyy67jMbGRh577DFyc3MxGAzMmTMnqEU6EMjOzqaoqIjPP/+czz77jOuvv54HH3yQFStW4Ha7WbBgAQsWLODVV18lJSWFiooKFixYgMfrDbZMANDn5qKxDr7Dcnt7O3feeWeEwDwAo9FIWVkZp59+Otdddx333HMPiYmJfPvtt1x11VW43e4ggQl8Hj2eVlzuWhSfk2uuuZmmJhv/+Mcj5OXld72uPiHe1el0oA19niVJChK2nj7nPl87HR1ilvyvB//MUcfOD/nDABqNJtJfphNJ0Ov1jBwpKm6mT5/O2rVreeyxx3jmmWcGdP0GA2NYBCY5eYCh/dw5PacmarcJp1mtEUb2My0FYpb+86WQOXVg53IkIm9eiMDMvCq4OCPjXCoqn8NgSMfg9Ou/Bht9CSBnjiAw5Su7EpjiZeJ51IIDG/XSm4eUIJlMOcyY/iaFm66irW0rtbVCr5aQ0Ev61S/kNdqamHXCUjQaCyZT1pCdU0a6IDBNTStxumowGgZR+u6H2ribXeZiVFlLimYk40dejWZKpjAa3PEB0pd3kduayLa4JvbufYmc7F8I/6ZDjAHFsFRV5cYbb+S9997jyy+/DIpDA5g+fTo6nY4vvvgiuKyoqIiKiopgnn3OnDls2bIlONME+Oyzz7BarcFZ4Jw5cyLGCGxzsHL1hwJKe7swapMktKn9N5GyWq1kZmYGtR0Akk7H6u3bGT9tGpIkBTUvPl+k+dnKlSv59a9/zamnnsr48eMxGAw0NDT0+9gjRoxAp9OxevXq4LLm5mZ27drVy17i5nzGGWfw+OOPs3z5cr7//nu2bNnCzp07aWxs5L777mPevHmMGTMm4nOiy8xE60+HrQkTxQaOOXZsqATR6/Wybl2ou3FRUREtLS3BbaZNm0ZRUREjR47s8pBlmfXr16MoCg8//DCzZ89m9OjRVFVF9jQJCLDt9hIcjnIUfxnz6tWFXHvtz1iw4Pjur2uAYMi6YDfxzpg0aRLffPMNnrCqK0XxoChuUlOTyMxIZ0/5PkYOS4k49+HDh4f5y/Rd3aQoSoR27EBCq40lLfV0EuJnk5BwVN87hCMgDq3bLlIT4Qikj0acOLCu27JGtCrorUfODwXhfZHCCgdMpiyOmvUx06a9jtTh/67tL4EJiq47kU1VDRGY0Qv27xiHAHp9MtOmvkZiYkhj1a3+JYCAe3ZLBRZLwZCSF/B7wsTNBBRqqpfu11gNG/6O3axFq8iMO/odNOPPFXqmlNGijxSQWlmHwZCB293gL/8+9BhQBOaGG27gtdde4/333yc2NjaoWYmLi8NkMhEXF8dVV13FzTffTGJiIlarlV/96lfMmTOH2bNFLf8pp5zCuHHj+PnPf84DDzxATU0Nf/7zn7nhhhuCEZRrr72WJ598kt///vdceeWVfPnll7z55pt89NFHQ/z2Dw+oqorXfy21SUnIAzSeu/XWW/nrX//KiBEjmDJlCkuWLKFw0yZefe01AFJTUzGZTHzyyScMGzYMo9FIXFwco0aNClb9tLa2cuutt/Y48+8OFouFq666iltvvTUoYP3Tn/6E3Esp8wsvvIDP5+Ooo47CbDbzyiuvYDKZyM3NRVEU9Ho9TzzxBNdeey1bt27lrrtCKRJZr0djEQZlf/vb30hKSiItLY0//elPJCcnc9ZZZwW31el0/OpXv+Lxxx9Hq9Vy4403Mnv27KDe5vbbb+f0008nJyeHc889F1mW2bRpE1u3buXuu+9m5MiReDwennjiCc444wxWrlzJP//5z+D4qqr6S5cVfD4HkiSj0yWh1yczYkQ+b7zxIbNmHYPLZeh6XYMRkp5nMDfeeCNPPPEEF154IbfddhtxcXF8++0XTJqUyZgx47jz9j/z69/+jjhrLAvPvxKX2826detobm7m5p+f5h8/Mqp42223sWjRInJycmhra+O1115j+fLlB9WeYMKExwa3oyUFkkaJ8tvOqYlA+qi/1Uc/RgQMATvqhRg6MWTcZzL5U+2BCqTBlFCHI9c/0awuFJqXAKms3Sa8VLQmISw+AqHVxjB50rOU7HkECSnoFdMtwgjMgNBSAd89CSNP6pPoZWScTYttLdU175Cb+8vBmXh6XZTbV0AsZMWe0MX9lxQx6ZOby8jJuo/iPQ9QUfEcmRnn7ZeOZ0igDgAIK8QujyVLlgS3cTgc6vXXX68mJCSoZrNZ/elPf6pWV1dHjFNWVqYuWrRINZlManJysnrLLbeoHo8nYpuvvvpKnTJliqrX69X8/PyIY/QHNptNBVSbzdZlncPhULdv3646HI4BjXmg4GlqUu1btqiO7dtVpdN16A5LlixR4+Lign/7fD71jjvuULOyslSdTqdOnjxZ/d///hexz7/+9S81OztblWVZPe6441RVVdUNGzaoM2bMUI1Gozpq1Cj1rbfeUnNzc9VHH300uB+gvvfeez2eS1tbm3rJJZeoZrNZTUtLUx944AH1uOOOU3/zm98Etwkf87333lOPOuoo1Wq1qjExMers2bPVzz//PLjta6+9publ5akGg0GdM2eO+sEHH6iAunHjRlVVxecCUP/73/+q48ePV/V6vTpr1ix106ZNXa7PO++8o+bn56sGg0GdP3++Wl5eHnHun3zyiTp37lzVZDKpVqtVnTVrlvrss88G1z/yyCNqRkaGajKZ1AULFqgvvfSSCqjNzc2q12tXn376LjUuLlZ1OKpUn88d3G/16uXq1KnjVaPR0P11rS8W1/X1FyPOJy4uLuJzvmnTJvWUU05RzWazGhsbqx599Cy1sPBj1eGoUlVFUV998u/qlPEFql6vVxMSEtRjjz1Wffedt1V130ZV3bdBVT3OiPGvvPJKNTc3V9Xr9WpKSop60kknqcuWLevxf6uqh9l35f0bVfWvVlX99M+hZY17xLI7ElS1o/HQnduRgGeOF9dq81vdr1/2F7H+f/+3/8d6ZLwYq+Sr0LKvHxLLXjlv/8c/EtBUJt7v31JU1efre3ufT1XX/EtV78kU+92VJj7fvcDjaVW//Gqc+vkX+WpLy8ZBnWbz+gfVz7/IV7/4LF91duztuoGiqOp9uar6V6vqqVylLl8xWf38i3y1rv7zrtsOEXq7f4dDUtUDbOV3iNDa2kpcXBw2mw1rJ62E0+mktLSU4cOHYzQOXfnZYKAqCq5dxaheD7r0dLTJyX3v9CPG8uXLOeGEE2hubu5S7RbACy+8wE033URLS8sBOw+PpwWHoxKNxkxMTKSHiGhWKByqY2PHIUlhOiRVhZotoPoguWBAYsn29iIUxY3JnIdOGyucZ12tonFhIOzvtkNDkRDwpk/cb53BUH9XtrbZ6fApHBUfOcvbWNGMLElMzo7veedNb8B7v4SsGXC1P8X83ROw7M9C43H5h/t9fj9ofHSLsMSfc6NomNkZ7/4SNr8B8++EY27av2O9czVseROO+wOc8Eex7N8LhLncaQ+H+hb9kOHzwt2p4rt+S1HvDTKb9sAHvw6ZDWpNoiJsxIlwybu9fo+3bbuFmtqlxMSMZtTI20hMnDegSMzmDydTb24ng9GMO7EHZ+7nF4kKwLP/xW5zGeUVzxAfN5Pp09/o93EGgt7u3+GI9kI6xPA2NqJ6PUg6XUSH6SgObyiKv9N3N+6ZsqxHlkUa0Ovt1L/J5xI/aEigM6IoHjo6SnC7G/s4nhtFESJgbUBwbvBXqbnaQhuGN3A8zEqDfarKuYUlnLlxNx/WtQSXtzk9XPSvVZy9+Du+Le5Fg5XTKTUBsCNQfTQEZaQ/dAQaGu7rwaxyf03swhHoIh4wtLM3wV5/8caoI0//Mij4vWCAntNIig9WLYbFRwvyojPDwvvh2m9E6XvJl7Dl7V4Pk5N7NRqNhY6OXRRuuoING39GS8u6XvcJoGPvF9SbxO9H7rg/97xh6hjxXLeD7OzLkCQdLba12GyF/TrOgUKUwBxCqF4vvvp6ALRpaYfUBj+KgSFAJgJEpTM0GpH3D5iEBRE0mDOBJOP2NOLz2XG5alHVntsQeL3t/nHNoYhOkMB0QGDfgXS4PsjY63TT4hVC8l/tKKewVZzrnvoOnB4Fn6Jy3avr2V3Xfc8r4nPEDUHxwt510F4n9DAAY047GG/hyEagp1T1pm67mQ+ZBgZCBGbvWvC6xY1YVSB1HMT3z97iB4HedDBuO7z4E/jk/8T3Nm8eXLcSZl8runQfd6vY7pP/6ypcD0OsZQxz53xBdvaVyLKelpY1rN9wAYWbrqS1bWuvp1ex4z6QJJJd8cSk99KCI8VPYOp3YjCkkZ72E7F/xXO9jn+gEb1jHkJ46+tRFQXZaNyvsukfE44//nhUVe0xfQRw+eWXH9D0EfQegQHQaHsgMGEdqFVVxesRbtaq6sPrbaMnBMYJECNAlA3LWkAJRSTCeyAdZiixh6qdHIrKZVv2UOV0U9oQukZtTi9XvbiW5o5uSvklKXJmv/MjQBVl0HE9mydG4UfyKNGF29MB9UVd1wcjMIMvxw0da7Qo7/c6RcQs6L578v6PfSQhSGDKu65b9zyUfyv+J6c9Apd+ECGuZu5vhIDW3gCf/aXXw+j1yYwe9SfmzP6SzMwLkSQNjY0rWLv2TIqL/97t5MjVUUmNJBqg5mb3kdJLCUVgAHJyRCl+Xf2n2O3dvLeDhCiBOURQ3O6gaZ02PX1w6vEoDglUVe2TwGg1QuPh8zlQ1bDZbliERFGcwUgOCF1NT8fz+glMRIWAJIE+EIVpF/oaT8CB9/CLwOxxiGt2bIKFMTFGat1eLttSSlGDiLjMH5tGdqKJ8kY7v3xlPW5vNxGpYGPH76LVRwOFrIGMKeL1vvWR67xusPvTmEORQpKk0P+q9OtQZ+gfS/oogJ4iMB4HrPRX5C28V3jzdI7Aa/Vwhn+bja9E9LLqCUZjBmPH3MPso5aRniYaaFZU/pstW2/E53NEbLt3019RZAlrh0zc2Kt7HzjVb1HRXAYeBxZLAUlJxwEKdXWHrjo4SmAOEby1taCqyBZLsDQ4iiMDquoNzmh6SiHJsq6rDkZVI5osBgiL7O9j4vW2oSjezkOhKG5UxQN0Y7ho8H92XG3+9gGK6BukPfQmU50RiMBMijXz0sThJOm0bGl38KbXjgrMyEvg35fNJNagZU1pE396b0vXZqeBCEzlWuHqClH9y0CQ5Tftq+qkg+kQqWxkHZiGyCY+4Aez9jlwNInGjdkD9P850tETgdnwkujdFZcDky7sef+co2CGv73KhzeFJih9wGzOY/z4Rxg/7lEkSU99/ads2HgxLn/Xeq+3g70dghDlWk9G0vThqBKTAqZEQBUmhUB+/s1MnfIyubnX9eucDgSiBOYQQPV68fmbTerShmC2E8VBRUj/ouvVB6GLDsbrFDoASUbVGvF6RfrIoE/1kxg1uCwcofSRqevxAjoYT4eIwkC3DryHA/b4CUy+2UCOycALE4djkCX2GSW8o6wMT45hdFosT148DVmCt9bv5Zmv90QOklwgfki9DlA8whvmQFrS/9DQk5C3XfhQYUnt0VxxwAj4wbRVi+cRJwlh648J3REYjxO+fVS8Puamvnt3nfRXERVr3A3fPDygw6en/4SpU19Cq42ntXUT69adS0dHCVVFj+HVKJgcPlKm9iLeDUCSQlGYup0AWGMnkJg495BmD6IE5hDA12IT0RejCXkAxnFRHB7oK30UQCDd4/X5iUVY+sjnc6AoHiRJRquNRaeNF5t0k0by+ffvYjAFItIS6HcUmEUfhvoXgBKHmD2OMInrNjMuhkcKhKDTlx/LDq1ItR03OoW/njEegPs/2cknW2tCg8hyKDUBA+t9FAVk+QlM7Tbwhjkwtw1hBVIAaRNDKU4YUPPGHwyCBKYS/G1CKHxFkLrYTJh6Sd9jmOJh0QPi9bePBglEf5EQP5OZM97GZMrB6axk3fpzKa95BYAc32gka2YfI/gRFPLu6H27g4gogTkE8LU0A6BJiD+0JxLFoNBfAhOIwCg+p0gNuUMEJhBp0Wpj/S6+8QD4fHZ8vtCNRVXVYAoqQsAbjkAUJrDfYah/cfoU9jlFW4R8c+i6zYsxo9ktopFP1Dbi9v/IXzY3j0vn5KKq8Jf3t0amkgJpJIAx0fTRgBCfKyJYigdqwipUhrKEOgCNVjSRBED68Ql4QVTNSRrx3eyoE1qjb/8h1h1zU/9TvePOhNELxf9tWT8iJp1gNg9nxvS3ibNOxettxS250LkVMsbd2v9BOkVgDgdECcxBhuJ0ojidIEnRyqMjFH2VUAcgdDDiB8rn6whGYFSdCU+QwMQHtw1GbLwtYcdyoape8XnpqeGoITby78OQwJQ5XaiAVSuTrAulEcoa7GhL2pB8Kh1hJAfg/xaJGV99mwubI7ScEScAEiTk/TgaMQ4lJCkUhQnXwQxlCXU4AmQzazrE/AhNOjt7wWx6XXTJtqTBtEv7P44kwYK/i9e7PxPGdwOEXp/E1KmvkKoVRGR4YwyaEQNofhpI1UYjMD9e+JpbANDExiJpD4988PLly5EkKVh6/MILL/Rapnwk4/jjj+emm27arzH6G4GBsHJqb0dQwOvTyKjB9FEoLaT1R2E8npZgxCGkfzH3rLfRh1cmHZ4C3qD+xWSMyJmXNrQjAWafeL+VzlBVllmvJdkiSOLe5rAKirTxcMXHopN01Dtp4Aj4wezrhsAMZQQGRHXN1EtEpc2PFYE0UmNJSMNy9G8GnupNGiF0RADrlgzqVDSSnombajj2u0ay868bmFYuJVCJVB6KJh9iRL/9BxGqquKztQCgGQRBuPzyy5Ekqctj4cKFQ3qeF1xwQZ8dpQ80DlcSJUqoAxGYvomC1p/28XpbARUkDV5VfPm1WmsEKdH5/1YUNz6f3b+fv3xa00ulmkYnrMdBPO+HqE5V1S5dy4cCgQqkEebIa7bH7wGT5DfnCycwAMMSRDRpb3OnH8zcuZA4fMjP80eBzG4iMAdCAwOiounMp8JSST9CBAjMyseEH4w5GaZfMbixZgr/FTa+0u+KpAjs+h80FqPTWAcWAQLRUNWcRHgl0qFGlMAcRCjt7aheL5JGgzzI0umFCxdSXV0d8Xj99deH9DxNJhOpqalDOuYPBarqRhARCUnS9bl9UAejelAA1ZyAxxNIH0WmECVJg1Yr+n54vC1+MtEeMU6PMPr7hRj62K4P2Gw2amtrcblcfW88AAQ8YPJNkQSmtF4QmEyDuJYVXQiMIGaVTZEeFlHsBwIppPqiUBuKYAppCEzsoohEgMAEUi9zfzWgHmgRGLVApKQcTbD9/YHvH/CemXll19RzfxCIwtQfHjqYKIFBzDo7fL4D/mhrbMauqriscdj9xxxoL02DwUB6enrEIyEh5NsgSRLPPfccP/3pTzGbzYwaNYoPPvggYoyPP/6Y0aNHYzKZOOGEEygrK4tY3zn6cccddzBlyhRefvll8vLyiIuL48ILL6StLeQc29bWxsUXX0xMTAwZGRk8+uijfaZrNm3axAknnEBsbCxWq5Xp06ezbt06li9fzhVXXIHNZgtGme644w4AmpubufTSS0lISMBsNrNo0SKKi4sjxl25ciXHH388ZrOZhIQEFixYQHNzc7fn8NFHHxEXF8err74KiHTarFmziImJIT4+nqOPPpry8pDTZDD6Iun7VT4ou+3Iij8dZLbgM8ejql4/WelKYnU68b/0emwoit8ET5LRaPoIN1vSxQ/lfrioqqqKwyGIgtM5iNldL9jTQwQm4MI7wiK8cPodgYli8LCkgnUYoEJVoVh2oFJIUYQIDIiIVCCKMhhotDD9cvF63fMD27dilWi9odHDUdcO7vipkY68hxqHhwjjEMOuKIz4esvBO2BDHeyqA6Dk2InEaDR97DAw3HnnnTzwwAM8+OCDPPHEE1x88cWUl5eTmJhIZWUlZ599NjfccAPXXHMN69at45ZbbulzzJKSEpYuXcqHH35Ic3Mz559/Pvfddx/33CO62t58882sXLmSDz74gLS0NG6//XY2bNjAlClTehzz4osvZurUqSxevBiNRkNhYSE6nY65c+fyj3/8g9tvv52iImF5bvFHrC6//HKKi4v54IMPsFqt/OEPf+DUU09l+/bt6HQ6CgsLOemkk7jyyit57LHH0Gq1fPXVV92mRV577TWuvfZaXnvtNU4//XS8Xi9nnXUWV199Na+//jput5s1a9ZEEJWB6F9w2qCpFK1Bwi1L+AxmVK+ouOmcPgpAo4lBkrSoqhenU5QPa3vTvwQgy/7w7uDh8XiChNrpdBI3hCLzkjAPmAB8ikp5kyAmExNioLWVCkdk5Cc7URC3CA1MFPuPrKnQulekkfKOiRKYA4lwAjPnhsFFPsIx7VJYcb/o7F27TWjC+oOVj4vnSRcMPtIW1hPpcECUwBxh+PDDD4M38wD++Mc/8sc//jH49+WXX85FF10EwN///ncef/xx1qxZw8KFC1m8eDEjRozg4YeFmKygoIAtW7Zw//3393pcRVF44YUXiI0VX76f//znfPHFF9xzzz20tbXx4osv8tprr3HSSUJktmTJEjIze/cXqKio4NZbb2XMGPGlGDVqVHBdXFwckiSRnh76ogWIy8qVK5k7V1Q3vPrqq2RnZ7N06VLOO+88HnjgAWbMmMHTTz8d3G/8+K5f8Keeeoo//elP/Pe//+W4444DRAt3m83G6aefzogRIwAYO3Zsp+vQT/2Ln7yAikaOAZx4fR2iogiCZdOdIUkSOl08bndDmID34Dg1h0ddfD4fXm9XV+DBwObx0uARY4WnkKpaHLi9CnqNzKQkC5T3HIGpjEZghhaZ02DHf4WQ19EMPv91t0RTx0OOlDGis7Q+BmZds//jxaaL5qXb34e1/4bTH+l7n/pdUOS3/J/768EfO1hKHY3AHDYwyzIlx048oMdw7ylFcTrQpaWhSQrNlM0DrKI44YQTWLx4ccSyxMTEiL8nTZoUfB0TE4PVaqWuTkR8duzYwVFHRdp5z5kzh76Ql5cXJC8AGRkZwTH37NmDx+Nh1qyQUC8uLo6Cgt4dUm+++WZ+8Ytf8PLLLzN//nzOO++8IHHoDjt27ECr1Uacf1JSEgUFBezYIb5QhYWFnHfeeb0e9+2336auro6VK1cyc+bM4PLExEQuv/xyFixYwMknn8z8+fM5//zzycjICG4TisD0UkIdRl4wxqOJGwbtO4P7SpKmV02LTpeA22/5DaFKpgONzroXl8uFZgiig3sc4uaYptdi0YbGC6SPcpLM5PqJTa3bi9OnYNSI70V2QigCo6pqtGfYUCG8lDoQfTElHJYVbEc8LCnwi8/AYBXtFIYCM64UBGbzf+DkO/uO6nz/hHguOA1SRg/+uIEITEu5aCCrPzi/TT0hqoFBzHpjNJoD9jB5vRhdTsySTGxCQsS6gf4gx8TEMHLkyIhHZwKj00WKSyVJQgm4QA4SB2LMO+64g23btnHaaafx5ZdfMm7cON577739GtPUD2fjqVOnkpKSwvPPP99Fg7RkyRK+//575s6dy3/+8x9Gjx7NqlWrguv7TCF5XRHkhYRc4Qfj73cEoNXF9fp/12iMwe0lSUYjH3hnXUVR8HiE10rgGg6VkHePXUR28nvQvwxPjiFRpyHGT1r2ukJRmMx4cS52t4+m7jpURzE4BJo6tlSINARE00cHEhmTh7ZqbvhxkDQS3O2w+c3et22rgU1viNdH70f0BYSXj9nv59NdR/ODjCiBOQgIeb9YkHR9V64cSIwdO5Y1a9ZELAu/QQ8G+fn56HQ61q5dG1xms9n6VYo9evRofvvb37Js2TLOPvtsliwR/gZ6vb6LbmXs2LF4vV5Wr14dXNbY2EhRURHjxo0DRPTpiy++6PWYI0aM4KuvvuL999/nV7/6VZf1U6dO5bbbbuO7775jwoQJvPbaawCoqoKiiJt8jwSmox5QhTdLQq7wZSFUTg2g0/Y9CwuIeTUay0GJOgTIilarxWwWaRu32z1gkXl3KPHrWkaYjBHLAwQmPzkGSZLINoqoVqUjRFSMOg2pseJaR3UwQwhTvOgjBbDrU/EcJTBHDiQp1ORx3fOiUWxPWP1PkSLMPgpyZu//sQNppMNABxMlMAcY++v90hkul4uampqIR0NDQ987+nHttddSXFzMrbfeSlFREa+99hovvPDCfp1TbGwsl112GbfeeitfffUV27Zt46qrrkKW5R5vvg6HgxtvvJHly5dTXl7OypUrWbt2bVBzkpeXR3t7O1988QUNDQ3Y7XZGjRrFmWeeydVXX823337Lpk2buOSSS8jKyuLMM0Xr+Ntuu421a9dy/fXXs3nzZnbu3MnixYu7XKPRo0fz1Vdf8c477wQrpUpLS7ntttv4/vvvKS8vZ9myZRQXFwfPKaB/kSQNktRNakXxgb1JvLakBckLhHQskqTtuyQa0OuSMBqHYTT2s0/JfiJAYAwGA3q9PhhhC0Rl9gd7uhHwQmQEBiDHT2A6l1JnJwYqkaIEZkgRSCMVLxPPUQJzZGHyRaA1Qu1WqFzT/TauNljrr1Y6+jdDc9zDSMgbJTAHGEpHB6rHI7xfYvdTfQ588sknZGRkRDyOOeaYfu+fk5PDO++8w9KlS5k8eTL//Oc/+fvf/77f5/XII48wZ84cTj/9dObPn8/RRx/N2LFjMRqN3W6v0WhobGzk0ksvZfTo0Zx//vksWrSIO++8E4C5c+dy7bXXcsEFF5CSksIDD4hmZkuWLGH69OmcfvrpzJkzB1VV+fjjj4MprtGjR7Ns2TI2bdrErFmzmDNnDu+//z7ablyPCwoK+PLLL3n99de55ZZbMJvN7Ny5k3POOYfRo0dzzTXXcMMNN/DLX/4SiNS/dEvM7E2g+oRgr1NOWquNxWBIx2TK6VdERZIk9PoEZPnAR+xUVQ0KeA0Gg//YgkwMCYEJRGD6IDDBCExPXjBRIe/QImBo52wRz0PdRiCKAwtzIkw4R7zuqaR6/Yvgsolo2+hFQ3PcYCn1oScwkjoUMeLDEK2trcTFxWGz2bBarRHrnE4npaWlDB8+vMcb7FDBXVmJz2ZDk5iIvo+qnB8SOjo6yMrK4uGHH+aqq/bD9+AwgstVh8tVi04Xj8mUHblSVYUy3+eCuGEQk3JoTnIQ8Hg81NeLTtbp6enIskx7ezutra3BFhOD/a6oqsqob7bQ7lP4etYYRseIMVxeH2P/8gmKCmv+dBKpsUb+WVHHHSVVnJkazzPj84JjPPRpEU9+tZtLZudw91kHVmz/o0LlGvh3WIPFU+6BuTceuvOJYuDYux6eO1FMmm7ZKUhNAB4HPDEdWvfBGY/D9MuG5phlK+GFU0V5+E0Hxn6kt/t3OKJVSAcQituNr9Xv+3EY2uIPJTZu3MjOnTuZNWsWNpuNv/3tbwDB1M4PAb0KeF1tgrxIGtHt9whCIH2k1+uR/VVxBoN4j+HeMINBvdtLu09BBnJNocqtyiY7igoxeg0pFnGsHP/6Ckf3EZhoCmmIkT4RZC0o/nL5aArpyEPWNCEQrt4E/5wn0tbuNlEhFCyNTxPeL0OFgAampQJc7WA4ODYP3SGaQjqA8DU2gqoix8Qgmw+/DsFDjYceeojJkyczf/58Ojo6+Oabb0hO/uF0oO21C3WHKCnHnAjy0BoTHmgECEx4hEWr1QbJzP74wQQEvNlGPYYwy4A9/hYCw1Nigim1nlNIfi+YpmgKaUihM4VuRhBNIR2JkCSYfb143boXbBWRvj6yFk74I+iGMNNgTgxFmBsObSVSNAJzgKB6vXj99vXa5CMnnTBYTJ06lfXr1x/q0zgw8PeL6TEC43GGesocQakjEOXT4QLeACRJwmg04na794vA9CTgLWsM6F9Cs7cAgWnweOnw+YIO1eFuvFEvmCFG5jSo8acBohGYIxOTLoD4XBEB1scKbxaDRTzrLaLZ61AjZYyouKzbGepufggQJTAHCN7GRlAUZKMR2XJozX6i2A/4PNBYgoKKahFfly4RmA6hH8EQd8QZgbndgaiS3EXoHCA0+xWB6aMHUkDACxCv02LVyrR6FfY6PRTECAKTEWdCksDlVahvd5Eae2B1az8qZE2DDS+K11ECc2RCkiC3bzPSIUXqWCj7JtSg8hDhR51COlD6ZdXnw9ckymm1KSnRGeORDFcboKLI4n/YpYRa8YrOsCAcN48whEdfOn9O9Xq9vyO2j46OjkGNv8fhN7Hr1IU6kELKT44k992lkfRamQyrIC1RHcwQI2uGeNbFDJ1LbBQ/fARLqaMppIOOQMmt3W7vl3PrQOFrakb1+ZD0euReFNRRHAFwtwOg+NMZstcrcswmfwdwexOoivBj0B86Mdtg0V36KACNRoOiKPh8PiorK0lKGnizyFAEpnsTu+GdCEyO0cC2dicVDheKovD2229jtVoZlhBHlc3J3mYH03ISiGKIkDYeTviTqJyLTrSi6C+CPZEObSn1j5LAaDQa4uPjg718zGbzkEVJVEXBXV+Hqiho4+JgiOzYf0xwu1vweBoxGDLQag+h+FlVod0GiorLaMbj7kDrUXC2lYLVI7xeWmpB8bcNOML+1z6fL+j/Eu4FE/jbbrdjs9koLy/HbDb32lm82/FVlTJ/RVG4BqbD5aWuTVyrvF4iMLW1tWzfvh2AnOEnsIaokHfIIUlw3O8P9VlEcaQhEIGxHdpKpB8lgQGCXY4DJGaooHR04LPZQNag02rBn0qKov9wuWpRVS+SVI9enzp4cqkq4iEP8mPu80BbNSDhNttRFCdaVYfW5YR9DeJL62oTpYtWA0gtgzvOIYLb7cZut6PRaHpMEel0OoqLi7FYLAMW0O51uvGoKgZZIssQEhIGoi9JMXriTJECw3ACY/OGCGGCoxJIiKaQoojicIA5UWim2mtFGmnYoRHy/mgJjCRJZGRkkJqaOiRuoyC0LxW//CXsqyLpmquJnzMEfSd+ZOjoKGXzlr8E/87NvY7MjLMHNoiqiv4uK+4XZk5nPTU4pfyWt2HlfZA5nU0jwW7fw5jRfyNh3Wew65PQdlMvgynzBj7+Icann35KcXEx06dPj+hgHoBOp0NRFLRaLe3t7dTV1ZGW1n+hZyB9NNxkQA4jPj2ljyDMC8bpxuazBZf76svRYmVv1I03iigOD6QU+AnMjiiBOVTQaDRoNEPj29H68cco69aji48n9cwzkQ+wy+8PEVVVy1CUKrTaOLxeG5WVDzIsayF6fT/N4exN8NHNsC2sq/XHv4HrVg68QmjPp9BeiZp5KXb7iyiKk7j44RhPuw+c9bB9qTCum34hHGH/a0VRKCoqwm639+qyq9FoyM3NpaSkhD179gyIwPS3hUA4AhGYvU43LR0tofP1eRihaWRvc1RTFkUUhwVmXQMTzoW8/reyGWoMuArp66+/5owzziAzMxNJkli6dGnE+ssvvxxJkiIeCxcujNimqamJiy++GKvVSnx8PFdddRXt7e0R22zevJl58+ZhNBrJzs4O9sI51Gh8fgkVV15F/RNP0v7tSnxtwv9DVVUanv0XAAk/v+RHYVx3IFBXLyIbo0b+EYtlLF5vK3tK/9G/nYs/h6fnCPIiaWDe7yAmFRqLYeVjAzsRxSfKBAFXzkQUxYkkaTEah4FGC+c8B8f9AX7yBMRn9zHY4Yeamhrsdjt6vZ7s7N7Pf8SIEQCUlJQM6BiBCEznCqQggUnpmcA0eXzU+l2sExMFeS3Q1LGv2Y6i/CC7n0QRxZGFsWeI9gQJeYfsFAYcgeno6GDy5MlceeWVnH1296H9hQsXsmTJkuDfnSscLr74Yqqrq/nss8/weDxcccUVXHPNNbz22muA6INwyimnMH/+fP75z3+yZcsWrrzySuLj47nmmmsGespDio7vvgs+AJAkDKNGoc/NxbVzJ7LZTOLFFx/SczxSYbeX0tGxC0nSkpJyMiZTNhs2/ox9+14nK+tnxFrGdL+juwOW/QXW/Vv8nTwafvqM8LhIHQvvXAVfPwTjz4bkkT0ev67uE1zuerIyL0Su2SqqjQxW7FZxozWZcpADehqNTjhcHqHYvXs3AMOHD+8zApmfn09x6jA+NyRyisNJqikUrXl1dTlrS5u4+6cTsRgif05K++hC3bmEGiBWqyFBq6HZ66O8Q4iK582bx0cffUSi10G8p5W6NhfpcUdWxCuKKKIYegyYwCxatIhFi3rvamkwGIIi2c7YsWMHn3zyCWvXrmXGDOFB8MQTT3Dqqafy0EMPkZmZyauvvorb7eb5559Hr9czfvx4CgsLeeSRR3okMC6XK1gSCoIEHQik3nor9hNPwLGxEEdhIZ7KSly7duHatQuA+AsuQPMD6XvU6Pbyl937WJBs5czUUOlqbauTv324nbOnZnHS2KEzv6qrE9GXhIQ56HRxJCQcRWrKIurq/0fxrruYOvWV7kWk7/0SdvxXvD7qWph/h7BJB9GttfBVKPkSPvotXPpBt+WiHR0lbNl6I6BSW/M+ExyTMALkzcPurADAbM4fsvd6KOHz+di4cSMAo0aN6nP7tLQ01uaPp9Vg4qZ123ltnuhirKoq9/1vJ21OL0kWA385fVzEfoE2AiPCIjCqqrKnXkRbO1cgBZBt1NPc7mCf20u6//gTJkygsLCQAm09e5vtUQITRRRRHBgju+XLl5OamkpBQQHXXXcdjY2NwXXff/898fHxQfICMH/+fGRZZvXq1cFtjj32WPT6kOPpggULKCoqotlvz98Z9957L3FxccFHX2HxwcJYMJrEn/2MrAcfYORnyxj1zddkPfE4iVddSfx555J87S8PyHEPBe4s2ce7tc1ct62czxtDhPAvS7fy0eZqrntlA6v3NPYywsAQSB+lpiwILhs58v+QZT3NLauor1/Wdae2Wtj5kXh98duw6P4QeQFBVk57WPi0lH4Nm9/s9thl5YsBkZqwtW5kjfMVGhN0kH88dnspAGZz3n6/x8MBhYWFNDc3ExMT0614tzOavT5aDeKafumVeXubMK8qb7TT5hQuvS98V8b2qtBnxOlT2OsMlFCHyEaz3UOrf5+8pB4IjF/IW+83DIyPj2fmzJliH7mJsprufwOiiCKKHxeGnMAsXLiQl156iS+++IL777+fFStWsGjRInw+HyBy76mpqRH7aLVaEhMTqampCW7TWSwY+DuwTWfcdttt2Gy24KOysnKo31q30KakYD35ZNJuvZWMu+5CE/fDcLNca+vgTf+NQgGu2VbGljY7XxXVsWx7LQBun8I1L6+npL69l5H6B4djL21tWwGZlJSTg8tNpmHk5FwNQPHue/H5OnmtbHtPlEoPmwmjTqZbJOaHvC4+vU0IfSOOXUFt7QcATBj/GLExY/FofBROsFJirqDDLrQfZtPw/X6fhxper5evv/4agGOOOSZiktATtrRFli7/tayOvTU1bNkXViWkqPzl/a1BfUqZ04UKxGk1JOlCKarSBvFZyYo3YdR1n7oK6GDajGZ0Oh0mk4msrCx8xng0ksqeoq39f8NRRBHFDxZDTmAuvPBCfvKTnzBx4kTOOussPvzwQ9auXcvy5cuH+lARMBgMWK3WiEcUg4NXUblt114AzktP4NgEC3afwiWb9/Cn/wljsZ/PzmVqTjw2h4crlqyloX3/TNzq6z8FID5+Jnp9ZAfrvNxrMRjScTorqax8PnLHLW+J5wnn9n6AOb8S5kv2Rvjs9ohVZeX/RFV9JCUeS1ra6UxP+g1ZVQ6QJMrqX6epSYh5zeYjn8Bs2LABm81GbGxsRBS0N2xuE6XLx8bHEOPz0GiO5Xeff8uWUjGZmD82FbNew/ryZt5eLz43e8JKqMPTfsEu1D2kjyBEYFqNZuLj44P7xw4rAKB93y4URen3e44iiih+mDjgvZDy8/NJTk4OigbT09O7mMd5vV6ampqCupn09HRqa2sjtgn83ZO2Jop+wOOAF8/ocgPvjBerGtja7iBOq+GvI7J4bsJwCmKM1Lq9lObHkJJg5A+LxvCvS2eQk2imosnOL15ch9PjG/Sp1fkJTHj6KACNxsyIEbcCUFb+NHZ7uVjRVAr71gkjufE/7f0AWj2c/g/xeuPLUC5E2E5nFdXV7wKQl3eDOF7ZSsbs7mC8fSIaTaia7EjXwHg8Hr75RpCxefPmBVtq9IVNAQKTaOWvo4YB8G16HtXF36PFx8nj0vjt/NEA3Pu/HTR3uHts4hjqQt0zgckJRGAMZuLCIprDR43BrWqQ3R3s2bOnX+ceRRRR/HBxwAnM3r17aWxsJCMjA4A5c+bQ0tLC+vXrg9t8+eWXKIrCUUcdFdzm66+/jjCY++yzzygoKCAhIdoHZdCoXCN0IN8/Dd7uIyb1bg/3l1YD8H/5GSTrtVi1Gh7KyUBy+VBjdVjmpmPQaUi2GFhyxUziTDoKK1v47X8KB1Xi6nLVYbNtACAltSuBAUhP+wlx1qn4fHbWb7iAtrZtsPVtsXL4sRDbDzFx7hyYdpl4/d+bwOOkvOJZVNVDQvxs4uP9EYk9y8Uxsy9i5oylxMVNIzl5fpfI0JGGdevW0dbWhtVqZdq0af3eb7M/hTQ51swlOelMizHg1WhZn5vHsbo9jEuP5fKj8yhIi6XZ7uGBT3cGPWB6LKHuLQJjCqWQwglMbmocu31JwfcSRRRR/LgxYALT3t5OYWEhhYWFAJSWllJYWEhFRQXt7e3ceuutrFq1irKyMr744gvOPPNMRo4cyYIF4sY0duxYFi5cyNVXX82aNWtYuXIlN954IxdeeCGZmZkA/OxnP0Ov13PVVVexbds2/vOf//DYY49x8803D907/zGiyT9rVTxQ072O4J6Salq9ChMtJi7NDDXve3ZZMbr1jciKyg6vh9/vqkRVVUakWHj259PRa2T+t7WG+z7p2tzL57NTXbMUj6f7yjAhzlWxWqdiNHQfYZMkmYkTn8JiGYPbXc/6DRfRuEeU3TPxvP5fg/l3QEwKNBTh+uTXVFX9BwhFX7A3QVWheJ1/HDExI5gx/S0mT3rmiO4q7na7+fbbbwE47rjj0Gr7V4DY7PFS4RfjTow1IUsSD4/LQwb2pGRBip7d679mz+5ibj46iTjJwXtr9rCpSWhdOkdg+pVCMggC49bp0cXFB5cPSzBR5BP6uaKiImw2W3e7RxFFFD8SDJjArFu3jqlTpzJ16lQAbr75ZqZOncrtt9+ORqNh8+bN/OQnP2H06NFcddVVTJ8+nW+++SbCC+bVV19lzJgxnHTSSZx66qkcc8wxPPvss8H1cXFxLFu2jNLSUqZPn84tt9zC7bfffsg9YI54NIWF3fet77J6na2DN2qEwPXe0cPQ+G/YX+2s47Ptteg7vPw9NwMZeL26iWcq6wE4Kj+JB88T1SzPfr2Ht9ZFCqhL9jzK9u23sGHDhbjdDV2OG6w+6iH6EoDBkMb0aW+QED8bn6+DTcNsVKfHwJjT+/f+QfTwOPtZQKKi6b8oips461QSEuaI9WXfACqkjIXYH066cu3atXR0dBAfHz+gpowBAW+uUU+8TpCesRYTJxlFVdK3IyezfvMmXn/9dVZ8+h5jctswzraw3SVIT45eg83u4ZVV5Zz11Ep21gjjx94ITIxWQ4xPRF8dlpCWLc1qxC6bqVFiUVWVDRs29P8CRBFFFD84DNgH5vjjj0dVe04TfPrpp32OkZiYGDSt6wmTJk0K5uujGCKEE5iqyB9/nxoS7l6YnsiMOHGDcXp83PHfbQBcecxwLh+Zjteo4c/F+/hHeS2XZCZh0Wo4c0oWpQ0d/OPzYh75bBdnTslCr5Xx+VxUV78DQHtHERs2XsLUKS9jMKQA4HY30dKyBuhe/9IZWm0sU6Y8z/avTqVWLmP7aBOuuv+Qm3NN/yMkI07EfcLN7HW/AECedVFoX3/6iPzj+jfWEQCXyxURfRlI64yA/mVSbKSz9MgWH5/ho9UUw6Zpx+D2KWy3JOCRxdiSqjK8vool7zbwaakHt1eIbjWyxFlTsshN6t2p2upy0GHW0WoMER2NLJEZb2Jncwrp+jY2bNjAscceO2StQKKIIoojCwdcAxPFYYSm0tDrThGYl6oa2eIX7v5pREZw+bNf76G80U6a1cCvTxKmZ1dkJTPCZKDF6+PlqpAPzHXHjyA11kC1zcnSwn0A1Nd/gtdrw6BPw2BIp6OjmA0bf4bLJUTZDQ2fo6o+LJZxmEw5/XobsqRn/OZacirFzbWk5AF2Fd+Jqva/MqUyy4yikYht85D08aOh0uoggTm+32Md7li9ejUOh4OkpKR++b6EI6B/mRRrili+a18rup0tAKyNSWSTNRmPrGGU2cCpWiOnfPctp+xYy7aSfbi9CmPSY/nzaWNZddtJPHz+5F7JpqIomDtEpKZFG1nmPSzBRIWSgEZvpK2tLVgcEEUU/YHi9OKpjzYE/aEgSmB+LFCUiAiM2lBMRUsD79Y2c9uuvfy9pAqA3+el02pz8ea6Sv7w9mae+krcIP502rigVbxGkrghR2gRnqmsx+UvaTVoNfxinig1/ueKEhRFZV/VGwBkZl3EtKmvYTRkYrfvYf2Gi3A6q7o1r+sTlWuQbJWM2iczKv8PgMTevS9TuffFfu3u8dio3PcyAMObYpFaKuHda6C5TFwjSQO5R/f/fA5jOBwOvvO3vRho9AVCJdSTwyIwqqqydV8rcq2TE2NjSNRpuDQziY+njeLrWWP419EFJPtTTMfmmvjwV8fwv9/M4xfz8kmJ7buhZltbG7EOoZWpI5LoZCeYUZDRJucBBB2Ff8hw7mqmdXklqi9aOr6/aHxlB7WPrMdZHDVD/CHgR9+N+keD9hrwOngj/VQ+SzuBtaYR1G3cG7FJvEvhiSUbucvuiVh+fEEKZ0zKiFh2TnoCD5TWUOP28E5NMz/zC34vmpXDk1/uZk99B8s2r0HXsgaQycw4F6Mxg2nTXmfDxotxOMpZv+FnuFzCSyQ1NbLhZ68IeL+MOZ2cvGuQtEZ27bqTkpKHSE46EbM5t9fdK/e+hM/XTkzMaJIX3AvPL4Ddn8F/fi42GDYDjD8MH6E1a9bgdDpJSUlhwoQJA9q3xeOlPEzAG0BlkwObw4NBI/PClBHotZHzII0EZx1VwBdf7GVSipYJWQMzd7TZbMQ6BXGqdEZ+FocliPNoMmURw06KiooE4YmN7XVMb5MTTawOqQfzvMMVPpuLxpe3o3oUvA0OEs4ZdUSLyQ8lvM1OXLtbALB9XIrhV/FIcvRaHsmIRmB+LGjaww7zcG4q+AMfxc+izpCEDoWpsWbOiLWgK2zE8XUNLXYPBq3MrLxErjt+BO+e4uJf5w7v8qNpkGWuzRY6lqcq6vD5dVGxRh2XzskDYHOxiHIkJx2P0SgIkMk0jOnTXsdkysHprERVPZjNI4mJ6bnJYgR8XuG+CzBRmNcNy7qEhPjZKIqTHTtv6zWV1Na2jYoKIRjPy7seKXNKyB+mZrN4/oGkjxRFCdoVzJs3D1ke2Nc9IODNMepJ0IXmOgEH3oL02C7kJYBAB+mmpqZu1/eGlpaWMALjjlg3LEFEgiodWoYNG4aqqmzatKnX8dyVbdQ8uJamd4r7dXxVVamtrT0szPJsn5ahesR52NfV0vbVwXEY/yHCsSVUQOCp7sBeWNfL1lEcCYgSmB8LmvawOVaYjY2V2nl/443sqnuc/80YzVEOGU2tk+nD4njv+rlsuWMBb147hz8ML2Xa11ege+UsQRw64ZLMJOK1GkocLj6uD5W0Xn50HjE6H6NjhWV9ZtaFEfsZjZlMm/Z60Nk2Le20/r+P0uVgbwBzUpBoSJLM2LH3IssmWlpWs29f9wJxp7OaTZuuxuezk5hwDGmpp4oVUy6CGVeGNvyBEJiSkhJaW1sxmUyMHTt2wPuHBLyR+pcAgektshLwaxoMgQmPwFQ43RFFA9mJ4lwqmxxBL5uNGzf2Wljg3NUMqriBKa6un+Nw+Hw+3n33XRYvXsyHH3444HMfSrgr27BvEDfZmNliAtC6rBz7xuiNdzBwbBUERpsmSHDrsvIgOYziyESUwPxY0LSHnTGCMMyN1XNU6xZM+9YCUOQvbZ03KoWpOQmhWfX298Vz7VZYv6TLkBathiuyhLnbExW1wZtIssXAtbOriNV30OFNICmxa0WP0ZDO9GlvMm7sg+T6ex31C1tERRPjzgJNyEnWZMphpN+td3fJ/Tgckekxr7eDTZuvweWuJSZmFBMnPokkhaUTFt4HBadB/gmir9IPAIEy40mTJvXbdTccm9tDBnbh2OonMBN7ITCBCIzdbsfpdA7ouDabjViXIDAdPoVmb8jhORCBqWl1UjBmLDqdjsbGRioqKnocz1Pl79XlU3EVt/S4naIoLF26lC1btgDi+lVVVQ3o3IcKqqrS8qHQrJmnpZJw1kgsx2YB0PT2LpwlLT3u621y4m3Zv9YePzR4W1y4K9pAguRLx6GJ0+NrcdH+/aH5/0YxNIgSmB8LGkvYGSOs8MemZAn7/da90FZDUa0gMGPSw3QEig+Kw7o/f3VPsFLH53NRVfU2DsdefjEsBZMssbnNwTfNoaaOM1JE9OXL8llsq+ro9pT0+kQyMs5Go4mc4aOq4lidQ/geB+z4r3jdjXndsGE/Jz5uJj6fnZ07/xgkVKrqY9u2m2hv345Ol8TkSc+h1XbSTGgNcNFrcOnSCGJ0pKK9vZ2iItE1eiCuu+HY3E0JtaqqwQhMbwTGaDRiNov9euog3xNaWlrQKgoJkvj/haeRUiwGUZ6vqDQ51aCupzdPGHd16PPn2N599/Rw8iLLctBU89NPP+01unOg4Nhcj7u8FUknE7cgD4C4hcMxTUwGn0rjyzvw1IWqaVRFxbG9kfp/b6HmgbXUProeny1KYgIIpI/0uVa0SSasJ+cB0PplJUonzV8URw6iBOZAw9EMtdsO9VlAUyk7AgQmLh6SRWM839717PITmIJwArN3rWh8aIiD1HHifSy/F0Vxs2Xr9ezY+QfWrvspBk8pF/sFvE9UiNJou70ce/tqVFXim32z+eeKkv6do9cNm96Afx4DDwyHv2fC4mPgzcvgy7vFw90G1mGQfVSX3UOpJANNzSuDLru7iu+hofFLZNnA5EnPYjING8wVPKJQWFiIoihkZWV16ezeH9g8XsocXQW8e5uFgFenkRidbul1jMHqYAIOu5l+wW2FI0RgZFliWLw/jdRsD5Kzbdu2dRvpUZxefE2h5c6iJtRO7S4C5GXz5s1IksS5557LBRdcgFarpby8nB07dgzo/PcXituH7eMyAGKPz0YTJyq3JFki8fwC9LlWVKeXhue34qnpoHV5JTUPrKXxpe3BCJPq8tEa1csE4dgiTDfNE0XE2DwtFV26GdXppXV59DodqYgSmAONd6+BxXOh6JNDdw6qSnNrHTV+87iCGCNkTQegrWQNTo+CQSuTmxTmjrrLf76j5ov0CqCu/TfbNlxNY+NyADyeJjZuvITLkhxoJfimuZ2NrXaqqt8EwGiZQ6MziY+3VrOnPhSd6QKnDVY+Bo9Nhvd+KVJWAF4H1G6B7Uvh6wfh+yfF8onnQA+CVLN5OCPybwGgePe9lJQ8zF5/efW4cQ8TFzdlABfuyES4S+306dMHNcYWf/oo26gnsQcBr0Hbe0XPYHQwqqrS0tICQI6/j1JnIW+WvxJpb7ODYcOGkZKSgtfrZevWru0xAukjjVWPZNSidHhxV4RaWiiKwvvvvx8kL+eddx7jxo0jLi6OuXPnAqIPm9fbu3ZmIOjYWEfdM5txbG3oNrrT/s0+fDYXmngDsf60UQCSTibp0nFok4z4WlzU/mMDrZ+U4WtxIZu1WI4bRuIFYnLSsbYGb9PA0ndHIvqKkIWnj0x+AiPJEtaFIqXe/l0V3uYf/nX6ISJKYA4kvG7Ys0K8/vyvIi1zKNBex069mIVnG3RYtBrIEq0gvJWiKd6oNAua8JLCAOEavQjyj0Mdezo7R5qoa/0WSdIxftyjWCxjcbsbqNl+KWcmibTLE+XVVFeLJoujh1/C/LGpqKowxOsCZyt8+id4ZLzokN1WBZY0OOmvcGsJ/GoDXPQfOOVumH455B4jIi+zem8pkZ19ub/xYztl5U8DMCL/VtJSFw32Ch5RKC8vp6mpCb1ez/jx4wc1Rk8Gdv1JHwUQiMAMJIXkcDiCTVzzYwWhruhEYLITRWpqb5MdSZKCbU26SyO5/elL3bBYjGMEoXLsEIRKURQ++OADNm3aFIy8jBs3Lrjv0UcfjcViobm5mTVr1vR4zs7iZprf342vte+UjeLy0fL+btylNhpf2UHji9sjSIbP5qLNHxGIWzS827JvTYyO5CsmIMdo/e/NQsJ5o8m4bRbxi4ZjnpqKYVQ8+FRav+hZG/RDwHfffcfdd9/dqwYqIN7V51rRWEM+RMaCBAz5ceBVaV1WfsDPNYqhR5TAHEjUbAaf/0etfqdIjxwKNO0JpY8s/huSPwJjadwMqBSkhfmeNJdB/Q5h6DbyJFRVZfe4YVRlGEFVmRB3CenpP2HqlJewxBTgdtdxTMtfAPhfQytlbgN6fTLJySdy3fEjAHhnw15qbJ1mOf/9tYiquNtE76Ezn4abtsC8myEmGZJGQMFCmPsrOOMxuOIjuGoZxPWeApIkDWPH3o8sCxfXzIzzyc395f5dwyMIgRv5hAkTInqQDQTdGdhBSMDbH2+XwaSQAumjmJgY8mKMAFQ6OpdShyIwAJMnT0aWZaqqqqipqYnYNhCB0WfGYBorUp1Ovw5m8+bNFBYWIkkS55xzTheyZzAYOOmkkwBYsWIFHR2RWi7F6aXp7V00/HsrHd9X0/JB36lS+/paVKcP2awFjYRzZxO1j66n9asKVK+C7RNRNq3PtWKa1HP3c22yibSbppN20zTSbpxKzPS0CLJjPVl4Idk31B5RzrOK3UPbN3v7rUvZtm0bPp+vVw1UQP9imhB5PSVJIu5UEYWxF9bhruolShzFYYkogTmQqPTP2jT+m8hXfwfPIQhVNoUEvGP8NwVSx4NGj9HbSq5US0G4nmGXv59VzmwwJ1Ja9iQV9SKqMnZXO6lfvwkeJ3p9IlOnvkRMzChSPZuYKW1CRWIZi8jIOBdZ1jE9N5FZeYl4fCqvrQ6b5VRv8vu5SHDBK3D99zD1YiGmHQLExIxg8uTnGTnyNgoK7vzRmH85HA62b98ODF68C91HYPor4A1gMAQmkD6Ki4sjx9h9CilQiRQgMDExMYwZMwboGoXxBCIwmRaMBQkgS3jrHXgaHMFqo2OPPbZHk7/JkyeTnp6Oy+Vi+fLlweWOnU3UPrIe+7ra0LJtjXhquxesgxDatq8ULTasJ+eS9ptpGPLjUD0KrZ+WU/Po+mCJdPzp+X1+ZjWxenTp3TfFNORYMY5NBBVaPz/8ojAdHR189NFHNDRENne1LSvH9lEpzUv7bhGhKAr19ULbUlxc3K1vj8/mwl0uUoaB9FE49MNiMU1OARVs/yvtsj6KwxtRAnMgsddPYI7+DVizRNXP2ucO/nmElVAHIzBaPaSLvjiTpT0UpIdFYIr+J55HL6Sicgmlpf8Qf+b/gUx7ErSUB/Uoen0yU6e+gtk8gmOVjwHYwmQyM84PDnf+zGwAvi4O+7H68h7xPPFcGHsGHACCkZgwh9ycXwQjMT8GbNmyBa/XS2pqKllZWX3v0A1avT72OETkMLwCaW+zgxa7EPBGCL57QEAD09raGkwL9YVABCY+Pp5so/i/VTpdkV4wCSERbwABsrZ58+bgsVSvEqzU0WXGIBu1ImUANG/ex549Iq3ZW38oWZZZsEC0uVi3bh21FVU0vVlE4wvb8LW60SYZSfnlJEzjk0CFtuV7exzLubMJb6MTyaTFPD0NXaqZ5KsnknBBAbJFh69RTG7M01LRZ/d9fftCIArj2FyPp6ZnYnUosGrVKtauXcuyZaFKR1VRg+kex5aGXskgiM+K2y3IbUdHR7cl7/aw9JE2rvvJUdwpuaCRcBW34NjW0O02URyeiBKYA4lK4bPC8Hlw/G3i9TcPCdHqQYQaRmCCERjAmyG0A5PlklAJtasNykTn4qasDIqL7wYgf/hvyc67Bk6+U2z3zSPQKn4wDPpkpk19hammDiTVR42USYscaj0wZ4QI3W/ZZ6PN6RGRqeJPRYoqcF2i2G+Ei3enTZs26KjTFn/6aJhRFyHgDaSPRqf1LeAFERnR6wUJCURW+kJ4BCbLqEMCHIpKgyckog33ggl0uc7Pz8dqteJ0Otm5cycAnlo7KCqyWRus5DGOFVGh7Zu2oaoqaWlpJCUl9XpOw4cPZ8yYMaiqyodL3hPmchJYjski9TfTMAyPI/ZE0YjUXliHt9GBoiisWLGCZ555JhglaP9WRF8ss9KR9f6u3ZJEzNRU0m+ZgeXoTAyjE4hbNLxf16ov6DMtIg2lisjG4YR9+8S1KC0tDQqk3RWtKO1+oqvSZxVVXV2koV9xcVen5WD6qJvoSwDaJBOxxwiy37x0d7Ss+ghClMAcKLRWiYiLJEPmNJh8ESSPFuXIKx8/qKeyr7WZVm0sWlRGmEOzkBqLECxO0+4hNdBkr+RLUDyoicPZXf8qAJmZF5CXd4NYP/E8IaT1dMAXdwXHMhhSmTftecYaRB55ZUson5wVbyIvyYxPUVlb1gRf/E2smHqx0LlEMSSorq6mpqYGjUYz4K7T4QikjzrrXwaSPgJxcx5oGikQgYmLi8Mgy6QbhDg8XAeTbNFj1MmoKlS1iHOVZTko5g20TwjoX3SZliCZC+hgipvFDb2/Iuf5J56EjESlWs/OuFqSfzmJ+NPzg0REn+VPUalQ81kxL730El999RXV1dWsW7cOd1U7rj02kCVi5mZ2GV82aYk/YwQpV05AEzt0EUPr/FyQhO7HvbdtyMbdH6iqGoyWeDweysvF/8KxVWiTdMNEOtuxqb5X/U6AwARI8q5duyLW+1p7Tx+Fwzo/F22KCaXNEzQQjOLwR5TAHCgE9C9p48FgAY0WTrpdLFv1NLTV9rzvUEJV2ekWP94jDTL6sPLj7ZLoPzSOMqRAhZS/+qi+YBJtbVvQaGIYkX9LaDYvSbDgXvF68xvQEMpVGwypnJg+CoBvmyMFcYEoTNWGT6DsG9Do4djfD+17PQzQ0dHBK6+8wldffXXQjx2IvowdOzZoIjcYBA3sLN0TmIE0ZxwsgYmPjwcIppHCK5EkSeqigwGYOnUqkiRRVlZGbW1tUJSpywjpRLSJRrwpWqokURkVXnXUG/Sb7Yz3ilTot66tvPDJ68EUVACxJ+awV27klR0fUlZWFly+a9cu2r4RqSXTxOQeUxkHArpUM+aponP84RKFaW5ujvDsKS4uRlVD6SPrCdlB/U7blz1HYQIEJpA+rK6uprU1VCLv2NIAKuhzYvu85pJOJuHc0SCBfUMdjqKBt8CI4uAjSmAOFAIEZtis0LIxpwubeo8dvn7g4JxHRwM79OkAjLVG5tXXtyfRqpow4BJVR373XRXYYxaCtuzsK9DrO4XYh00X5dWqAivuj1h1TIKYPX3b3BahW5gzIhlQmVHylFgw/QqIzx6693kYwOPx8Prrr7N7926+/vpr2toO3ozX7XYHRan7I96FngW8/Wkh0Bn99YLxdXjwdXgiUkggGklCVyFvdzqY+Pj4YM+n1atXBwW8+sxIw719KW2okkqyIZ7k5N5n5gCeOjutX1Uy0zuC48bPwWAwUFNTw0svvcRrr71GfX09Pp+Pb3ev5RN9IU7JTZIxnquvvhqNRkNzczPVmwV5CKQqDiasJ+WALOHa1Yyr7OCmr7tDIPoSmBTt3r0bT1UHvhYXkk7GMCpBnDMiJedpcHQ7ToDADB8+PKj3Ck8j2fuRPgqHIdeKxR8da3m3GMU5dN4/URwYRAnMgUJAwJsdRmAkCebfIV6vfwEa++lQuz9o2hOqQLJEViwU1XWwWRHr2LdePOwN1GTG0+GpQquNIzfnF92Pe/z/ieetb0N9KHQ7My4GnSSxz+WJmDXPyU/iJHkDY3xFqFoTzLtl6N7jYQBFUXj33XfZu1fMtFVVZdu2g+fAvG7dOlwuFwkJCeTl5Q16nDavj5JuBLz7Whw02z1o5f4JeAPojxeMr8ND7SPr2PfwGux2QUg6R2B67ErdFBB1yC8AANhPSURBVJlimD17NiDEvG3V4pi6zMjP/W6X0F/kOZNRvb0381MVleZ3i8GnYi5I4vhzT+HXv/41s2bNQpZldu3axdNPP83ixYv55ptvABjjzeSM9qmkW1OC/4sK6tHnWodEnDtQaJNMxMwQPlC2T8pQfX23RvA2OKh9bAN1izfRvqp6SHUhAQIzYcIEJEmioaGBmnViwmQsSEDWa9APi8U4JhCF6VpF5fP5ghVMqampjB4tGtUGCIyv1d3v9FE4rAvy0CQZ8dnc2D6OViUd7ogSmCFCQ8NXbNn6K9zuJvC6RJkwdG0MmHcMjDwZFK/oL3SgEVGBZIxYVVTTxmbVr0HZtwGK/ociQelwMWPNzf1l155BAWROEc0PO0VhYjQaplnFzSU8jZQSo+OPRtGIsXTEJRA7cHv7wxmff/45O3bsQKPRMHHiREDcRPsDu92Oz9c/k8Nal4cHS6spc4RM09avXx+s5hg7aRpyDy7F/cEWf/Qly6AjSd+9gNfYjblaT+hPCql95T6UDi+tDhGx0uv1GI3is5pt6iECkxjpBRNcnp1NRkYGXq+XHb5K0Mpok0NEzG63U1YlbojD3Sm4SnuPSHSsq8Fd1oqkl4k/a6QQ3cbEcOqpp3L99ddTUFCAqqo0NDSg1+s555xzODFzFlqvTNs3exk1QqRpK+UGLMd01b4cLMSemANaGXdZK81v7+rSTiEcXpuL+ue24KnuwF3eSsvS3VT9fTWNr+7AsbOpXwSoNwQEvPn5+eTkiEjLrh2ib1e4V0t4FMbbGPl/bmpqwufzodPpiIuLCxKYkpISvF6vqCZSQZ8dizY+8nevOzQ0NFBcXIys15BwtkiDd6ypwbm7e+LtbXbiKm/FXdWOp8GBz+bCa/dw644KbiuqxBt2fb0+hZvfLOTvH+9A6eW6RzFwaPveJIq+4PPZ2b7j93g8TZhNeYzQzwOfG8xJkJjfdYf5f4Xdn8HWd+DYWyF17AE7N09TKcXm+UBkBZLN7qHa5mSTHEZgVIWqdCMOjRO9PoXsYT/vffDj/w+KPgp7H8KL4+gEC6ttHXzb3Bbsk8T2pYxQymhVTfxHfzY/pNqjNWvW8N133wFw5plnkp+fz9atW6mqqqKhoaHXNEV5eTkvvvgikydP5swzz+z1OCV2Jxdu2kOl083ODif/njCcdevW8eGHHwKw3ZuKs9HKKfvxXnoysBuogDeAAIFpaWnB5/Oh0USSH8XhpX2lmJG3S0IXEauLCaYXAimkii5mdv4ITHNkBEaSJGbPns17773Hdu1epqWMR9KEqrF27tyJqqokG+OJc5px7mjCOCqh23P3tYZm4dZT8tAmRN4Ik5OTueiiiygrK6OoqIgZM2aQlJSEQ9dE4wvb6FhVTeaceABqNDak/N57Rx1IaOMNJF1UQOOrO7BvrEPSysT/dCRSuPs24Gt30/DcFnwtLrRJRmJmpWPfWIenxo5jSwOOLQ3IFh3GMYkYhsdhGB6HJsHQ74o3RVGorq4GIDMzk/b2dsrLyynvqGGMJl1EXfzQZ8diGJ2Aa1czrV9Vknju6OC6QPooNTUVWZZJT08nNjaWtrY2SotLiF0pyHB/oi9er5cXX3yRtrY2rrnmGjJHZBIzO4OOVdU0v1NM2k3TkfQy3lo7jq0Nwu+numuJ98Z4DS8fJT6XPkXl/jHZSJLE18X1vLtBkDaNLPGHhWP6da2i6BvRCMwQYF/Vf/B4xAyzpmYpasVqsWLYrO79TdInCj0MwMZXDui57bE14Zb1xOBlmDFU3bCrTnzBayx+8lS7FV/DNkpzxBcwL+8GNJo+hKAZk4SHCyqsuC+4+Jh4EbVZ2dIudDA+rzDxA57znsaX5T+cMsVdu3bxv/8J35wTTzyRSZMmYbFYGDFCEMOALqUnrFixAkVR2LJlS9DTojtsbLVzxobiYCRiRVMbq9aGk5c01nhzWL6r+/46/UVhsAN1ZAuBzXv9At5hfRMYxS4qOZrfLSbWbEGj0aAoSlCgG47276pQXT60qWaUyeJzY27TBD1AAimkvS43SoQXTFcRbwDjx4/HrDNhl1yUmyN9PQJpvbEjxU3Esb2xx+vV8t8SVKcP3TBLUBvRHfLy8liwYEGwHNtYkIAuMwbVrSCvaCJeMaOiUlJ6EFLGvcA0PpnEC8aAJPoktXxQEvHeFX+DSG+9A59V5v2Y9XzZsoGUX08l9VdTsRydiRyjQ2n3YF9XS/Nbu6h5YC01966h8fWdtH9fhbcHvUoAjY2NuN1udDodycnJjBoloh1VchPaEbHIxsg5tXW+PwqzoS6i5UI4gQFBXANjbfl0Hd4GB5o4fTB11hu2bdsW1KsFxNdxi/LQxBvwNbtoWLKV2ofWib5Tn1cI8iKDJtGIHKtHMmpAlliWETr3l2qaeLpSlM9/UBjyp1m8vITXVh9+xoJHKqIEZj/h87moKP9X8G+nq4rmus/EH9kze9gLmHqJeN78H/AN/oZut5dit/dcXbDDIVITY3Q+5DAytbNGfGET0/PAkg6o7M004TbIGI3DyMq8oH8ncJxfC7NtKdQKB9jpcWaMskSd20txuwO+uhsai1FMiSxRFlJc105d25HfPK2qqoq33noLVVWZOnUq8+bNC64LlDFv3ry5xxtkdXV1sJLF6/Wye3f37qMrmto4p3A3TR4fkywmEnUa2n0KS779HoCt3jTUrEkYtBpqWp0U1w3OEt3m8fJpg9ANHJ0QSh1W2xx8VyJKXOfkJ3a7L/idZtdUU/PQOtq/3UfHmhravqgICnk762AUly/kTHtiNg7/ZNmiGGh6owjVq5Bp0CMDLkWlzh0SVQZSSPVtLpyeyPSbVqtlglmkTTfZioPX3263U1oqIiqTjp4GWhlfiwtvbddSXcf2RlHFIkPC2aO6RCp6gyRJxJ6QE/w7RxJNVDuX+R4KmCenkHCeqLbpWFWN7aNSVFVFcftoeGEbnqoO5BgdthPMVNfVsHHjRlauXIk+y0L8GSPI+OMskq4Yj+XYYehzYkGW8LW6cWyqp+X9EmoeWkfNw+to+XgPrj22LummgP4lPT0djUZDWloaMbIRn6TQkNaVwBtyrKKvk6LSFuYL05nAAME0UmlTJaqsknjRGGSzrtfroaoqq1evDv5dWSmOIRu0JJwjCJG7rBVvoxO0EsaxiSScO5qMP80m4/czyfzTUWTdMZf0u4/myxHiM3lirfg9v6ukireqGvlsu6g4XTRBFFP85f2tLC+K9LA51FB9Ch1ra2j6TxHt31fha+t5MnU4IUpg9hPVNe/gctdiMKSTkX42ADXeHWJleAVSZ4ycDzEp0FEPu7/ocTNVVdnR7uCJ8lpeq24MLlcUlU3lFXy76id8t/p0XK5uyrJVlSKfCHuPjYmcURfViBtVQUYcZE3Dq5EozxbbDB/+q/6716ZPgHFnEh6FMcgyM+OEcPLbzx+Hbx8FQD7hj+RkiC/x9yWN3Q53pCBQceTxeMjPz+f000+PCKOPGTMGnU5Hc3NzUNjbGYG0U0CzsmPHji7bvFfbzCWb92D3KcxLsPDu1JFMUMSPS0VCKlu96SSOmsHLv5jN7HwRAVhRVD+o9/SfmiYcisLYGCMzrKHo2+urK/ApKkcNT2RkaveaKPfeNuoWb6Ll3d0odi+aBFG22rZiL/Em4fLcWQfTsaoaxe5Fm2zCNCklGKGJ1ZnxVHfQ+nkFOlkiI+AFE6aDiTPpsBjEjLe7KExBexoaVabGVh+8/jt37kRRFNLS0kjJSMU4Kl6c11u7aHqziJYPSrAtK6Pt6720vC+iJZZ5w7pUMfUHpvFJaFPF92l0gegO3ZPd/cFGzLQ0En4qbs7t3+7D9kkZja/sEFofo4bkqyZQZQv9nnz55ZdB4idpZEwFicSfOpzU66eQeccckq+eiHV+jnA59rdqaP96H/XPbqbq7lU0vrEzGFELEJjMTBHR8rW4GOYWpLhS6f6mHtDCdKyvDUZ4uiMww0ypaFSZNtmJ75gEDHl9RwsrKysjHHwrKiqChNc4KoG4M/IxT0sl8WdjyPzLbJIvG0/MjDQ0MZHE6NuWNho9PhJ1Gp5ISObCcvFZvbmokjazhmEJJp762TTOnpaFT1G54dUNbKs69BVhqkehfVUVNQ+uo/mdYuwb62h5v4Tqv6+m/tnNtK86vMlMlMDsBxTFQ3n5PwHIzbmGTH/Uoi7eh0+jgaxeylk1Opjkj3IUvhqxyuFT+Lyxlf/btZcZ32/nhLVF3LOnmpt3VvLQhnL+753NzL73Cx58/1k02JFUO2u3PNj1GI5mdhjFD8WYhMhS6F01YpZekG6BrGlUZBnx6GTMhmzS084a2IU47v8ACba/DzVbAThGIyI8Kz1G0BrhzKdg1tXM9fvBrNpzZBOYuro62traMJlMnH/++V20HXq9PljS210aqaWlha1bxbUKWNXv2rUr6EoK8Nzeeq7bXo5HVTkzNZ5XJuWzd3cxmm2FYvuELEZMnsPTl0zHqNNw7Ggx0/+6eOAERlFVXtgn/idXZCUHyZjbq/DaGjEr/fmc3K772T00v1tM3VOFeCrbkAwa4k7PJ/13M4T/iAqmGnFDCCcwqscX9EaJPX4YkiwFCUzaTBE9aVtRiavMRo4poIMJCZeFF0zXUmoQ2hVDh8wIRaQPVq1aBYTSRwHvl4A+wrOvHfuGOtq/q6Lty0psH5fis7nQJBqDN8+BQpIlEi8cg+WYLArOmIbRaMThcPRIZg82YmalE3+mSHO2r9iLa1czkk4m+YoJ6DMtwe7OCQkJqKrK22+/HeGxEoCs12AcEY91fi4p10wi8/bZJP5sDOapqchmLarDi6Ownvpnt+BpcATJQqDs2bGtkWGK+E3YXda9gZwhLw7DyHhQVOqeLqR1Q3XwsxQgMIrLS/tbe8hQ4gHYZ+16rt0hEH2ZMGECsizT0dERESmMPTqLxPMLME9KQTb0LBl9r7YFgDNS4kmcn8cfHHqOq/XgAdxTkzhmSjqyLHHf2ZOYk59Eh9vHlS+spdoWIt+qquJtcgoS8d8SbP8rpX11Nc7iZryNDlRfiPwqTi+emg4cO5toX1WF7dMybJ+W0fp5Oa3LK2n7dh/tq6roWFuDY3sj7so2vC2uYNWd4vbR9u0+qh9cS8vSEnwtLmSLDssxWaJSTgXXHhstS0Nkpu2bvXjq7fuVoh5qREW8+4GamvdxOveh0yWRmXkBsmzApEnCQSN1+cPJ0HffaC2IyReJnkJF/wN7E5gTuX9PNf+srMMRplY3yhIGr4pNhof31qFfV4ekws9Hbwpu47Atpb39l1gso0Ljh3WhHhMX6nWkqio7AxGYNCtt5iwqnOJmkD/y98jyAD8WaeNg/E9h27uw/F4YdTJHf/M8TH6c7xJmoFy5DDlzMiAM7f71TWkwJXGkIvAjl5KSEqyY6YyJEyeyefNmtm7dyoIFCyJIzvfff4+qquTn5zNz5ky+/vprOjo6KCsrY+TIkXzd1Mafi0V65aqsZO4alYUsSXz0+QqybeLHu8Nq4Xdzx6LViHnIcaOTuQtYXdqEw+3DpO9/tdDXzW3scbiI1cickxYStX66rYaGdhcpsQYWjE/vsl/Di9uD5armqanELRqOxioIR/wZ+ThLWrB06EAXSWA61tSgtHvQxBuCRmsBD5iUCcMwtzuwb6ij6T9FZJ+Wyvd0X0q9s6atSwQmYGA3yTqKXR3VbN++nZqammAUIeC+a56SimzS4rO5UZxeVKcPxSWeVa9C7HHDgk67g4E+0xKM3owcOZKtW7dSXFwcrLw51LDMyRQdsD8qBY1E0qXjMORacbvdwa7eP/vZz3jrrbeoq6vj7bff5rLLLutC1sMhG7WYJ6VgnpSCqqi4K1pp+e8ePPvaqXtuE9XekIAXwLG1gSwlEVmSaGxspKmpKSj8DkfCT0fS+MoOPNUdlL61EdWgYjKasFgsqKpK87u78TY4yLWks9fbxK7iXRx9zNG9vn+bzRZsfHr00UfT0tLC3r17qays7PYceoJLUfi4vgWAn6YlIGkkUi4awz2Pb+Aao8z2OA3LdAq/c3tJ1mv558+nc+7i7yiua+fPz67l/pl5SFUduMpaUVp7iXZIoLHqUZw+VFf/qha7HcakBVVFdYoxNHF6Yo/LJmZmqKO5t8mJY2sD9i0NeCrbcO2x4dpjw/ZRKZokI6aCxKCQW9IdujhINAIzSKiqj7LypwHIzfkFGo0RSZJId4kf+ZrU3nOvgEi/ZEwGxQNb3ubLxlYeLa/FoahkGnRcmpnEyxOH86A1CedXVeBWUGN1HHVsDi9eXsD4ZJFTL2/NQZZUviuMLMvuaCyl3CRmOmPCUkg1rU5anV60sorB9QZrq/6GTytjNY0mNXXh4C7IcX8AJNj5Ifz3N0y2bSVGcdGstbA9NkSqZuYlopElyhvt7GvpXfB3OCNwMw7oO7pDfn4+MTEx2O12SkpCAk673R50zZ07dy6yLAe7KQfSSIFWDD9JjeduP3mpq6ujraEao9tFokfMpL4OK1UfkWIhK96E26uwqnRgBHHJPiF2PT89kZiwPkcvfy/0VRfNykGnify58NSKMls0EinXTCTxgoIgeQGQzToSzxmFVRXpqKZacQzVq9C2IhB9yUbSyPh8vuAMPz4+nvifjECTIESUKWUi/dBjKXUnLxhPtbgmGdmZ5OXloaoqb775ZjB9FKgKk2QJ09gkLLMzsB6fTdzCPBLOHEniBQUkXTwW/bCh82wJCEwPBx1MOGLnDSP56omk/WpqsBpr3759KIpCbGwsycnJnH/++ej1eioqKvjii57T3Z0hyRKGvDiSrxiPNslIg60Jr9eLwWAgMTERX5vwatGjJTtLmFp2188IhJdN6g1TiD0phyaN+P/GO404tzeJKMOmepBh0llzAJEKcjh6/31Zu3YtqqqSm5tLRkYG2dniHAI6mP7iy8ZW2nwKmQYds/ypc228kfKpSTy6wUGmXaHK4+XkdUXcWlTJigYbj07K5iXZwp2NEs5PynFsbhDkRZaCovGYORkYxySiTTWDVgYVfDZ3kLzIZi26zBiM45KImZ0h9pmVjnlaKqbJKZjGJwlB+TALmjg9+KvxVIcg6ZpEI/FnjyT91plY5mYGyQsIx+rYY4eRdsMU0n8/k7jT80UUTCPha3TS/l0VDc9vpepv39OxtmZA12soEY3ADBK1tR/hcJSj1caTlXVxcHnGvhZKc6FJ04DTWYXR2If3w5SLoXoTjk1vcptyDABXD0vmbyOzkCQJm8PDSR+tRfKqzNca+BwP22MlMmI2Ual6sVjG4FJ+i6Jei8b9DXUNa0hNFtqboqYGYBQpip3kME+Popo2EgzN3DjtdcpKReO75OT5jB1zL5I0SE6bOgYmnCOM7SQZ3Yl/ZrY1mS+a2ljZ0s4Ef1lurFHHpGFxbKxo4fuSRs6dPmxwxzvECERgeiMwGo2GCRMmsHr1ajZv3hwUGa5btw6Px0NaWlqwWmns2LGsX7+enTt3ctppp7HbLkTOM62hkuJ169YBUKnEMy3GzOduJ181tXFOupgtSpLEsaOTeX1NJSuK6jmhILXzKXWLSqebz/zi3cuzQmWnO2taWVPWhEaW+NmsrlED+yaRqjKOSsCQH9/t2MaCRNImZkNRIc0tzficHhybGvC1upGtoSqRtjbh3CzLMhaLBVmWSTy/gPpnN5OypxUmmiKMEYFu2wkAIQfeDAuz02ZTVlYWJJz9bR0w1Bg5UnjI1NbW0tLSEjTqGyyqqqr44osvaG1tpaCggAkTJpCWljaoBp7GEZHnEriBZ2eLMuDk5GTOOuss3nzzTb777juys7OD6dH+QGPRk3zlBLY/9REokKxakXxg394Iquh9NGrMaMr3VrB7926OOuqobseRtDJxJ+fibtsKmyHea6bx5e3BaXjcguHEThhG8vJkGhoaKCkpYcKECd2O5fF4gj2zAsfLzs7m+++/HzCBWVrXAojJRnihxIv1Nqa6nTy2QeLaWWaq8fByVSMvA7Ks8v/snXd4HOXV9n8z27t6L5YsWZJ77xUDpgaDaaYTSkIKJLwhedNICCQkJG8gEJpD6BB6Cd3GuGIb9ypZVrV610rb28z3x+yuJEtylY3h831duiTtzs7Ozs48z3nOuc99F00xM6U9SEajlxaXnz2EKJUlRqpEZhtNXDYhg6x45RqXZRnJGSDY6UU0KOakx5odlGUZ2RMk5PAj+yU0aSYE1ZHHe3WcHsvsdCyz05F8QXzldrz7O/GUdiB1+1HFHVln52ThTAbmOCDLUjT7kpV5M2p1uFQU8GKoLSbGHgBkmpr+e+Sdjb4cRA2Pasdw0OsnVafhFzmp0YHob5+V0ub0MTzRxFNzChhu0NEWCPJ4XaQGfAE3zp3PthYlXbp59/3RGuV+pzKwF6n6dvzUN3zAfTP/zDDLfkTRQGHhnxg75im02qNPmw6I8/4M038IN34Ac+6OdrL080UKk003VHxzreuPJoABoqJ2+/fvx+fzEQgEonX3WbNmRb/nYcOGodPpcLlc1NXVccClfGd5YfNNv9/Prl1KyXB/KImF8QpBcXWHo0978bzj4MG8WN+GBMyJNZPfSysokn1ZNCqZFFvfQUqWZWXVCxjHJx52/5mXjEZAIIhE/bv7erIvczMQ1MoQFOG/WK3WKKlZl2PDNC2VVI/y+WoP0YIZyE4AekpImjQTI0aM6PMdHa1541DDZDKRkaEE64NlGY4GDoeD999/n2XLllFRUUFrayvr16/nqaee4vHHH2f16tVRhdrjRYT/0rvUNXLkyKjK8XvvvXfU3lYRqOMNOAuVCTfObaDjtf1R7yPDqJ526qqqKgKBw3dltnnsAKTkZYAASKAvjMM8R8k2RxYKh8t27dmzB4/Hg81mi2Y/IxmYlpaWPl5Nh4MrGGJ5m3LtLk7quc7anT6+LG/jCXwMM+t4d62Th7e7ufqgnxxnCEkQ2Bej4vnhOv4828aeuUl0xOtwyzJbD3byyOdlnPePtby5tRZZlhEEAZVFiy7LiibReFylTUEQEI0aNMkmtJmWowpeDoWoU2MYlUDsknxSfzmVpB9PQDfMeuQXniScCWCOA62tK3C5ylCpzGRk3NDzROMukAKk2pXyUWPTO0cmPJniKRt5Df/MvAaAB/LTMYdT+Dtr7bz8lTKJ3L94NGatmnvzlIzOO95xtJJIctIFGLVq8vN+ii+kwUAxlXUfA7A/qOynyKBkX4JBB/uKf0aK/CdMGg8euYBpUz8gPe2q41q59YM5Ec77k6I2TI8v0ka7s48y5czhyip/Y8XgGhynOyID+JFq5enp6cTFxREMBtm/fz+7du3C5XJhs9n6TKZqtTo68O4pKaE6PFlHAoq9e/fi8/nolnQ0SlYuyozDpBJpCwTZ6+zJQMzMS0AlClS2uvrJ7A8EnyTxSmMPeTcChzfAuzsUDs510/uTdwP1ToLtXgSNiL4ovt/zvaEx6rCalWC2eXcNoQ4volmDaWoPp+ZQE8cIbOdmkxHOCtZ7/YR6XS8D2QlI3iChdmXy0aQpmZzICrt3+ejrwNFMrIMhGAyyfv16HnvsMXbs2AEowfFll11GUVERKpWKtrY2Vq9ezT//+U9eeumlIwYCA0GSpCjRODKhR3DOOeeQmZmJz+fj5ZdfPuYgpsmuBLyJ2PDsa8dXZgfAMDqepKQkrFYrwWCwjxHmQIh0IA1bMJLEO8ZhXZRN3NUF0Vb3yHkuLy8fsOtLluUosTtiCQFgsViIiYlBluWoWvCRsLy9G48kk2PQMq6XdtLHexoJSTJFGTZSrx+FWa9mbjf8zhbLmgkj2Da9iEcKM5kTayYIbDTIZC/K5oO75/LgZWOYnB2L2x/inrd2c9drO3F4Tz/tLEEQ0KabjysQGiqcCWCOEbIsU12tGBJmZt6IRtMr+gz7HyUZJyGKOtzuChyOwwuZybLML1KvJSBqONu+jQvCg3IwJPHrd/cgy3DZhPTopH9uvJXJRjcBtLyjvgNjWO/i0knj2NmhdLPs2/8QkhSkRIgBoMBmo6trJ5s3f4empneRZIH/VixCk7ws+vqTgVFmAzFqRbNkt7NnkpmUHYtWJdLY5eVg+5En2dMNwWAwytc4UgZGEISoJsyuXbvYuFHRbpk+fXo/MmRkJfhVldJ5ZBBF0sItxJHyUWkokUSLnkSTjjnhAHF1R49ppFWvYWJWDHB0WZgPWux0BEKk6zScG9/TdvrO9nrc/hB5SeZoxqw33LvD5aPCOETdkVeD8UnK9esQlWDLMie9zyryUBPHCESjhvyzhqGSZAJAfWtPNi8jzIHpdAdw+pTurYhCqsqmjba6TpkyhfPOO48lS5Yc8ThPJqI6JVVVA4oWyrKM3W6noaGBiooK9uzZw+bNm1m1ahWPP/44n3/+OX6/n/T0dG655RaWLFnC2LFjueqqq7jnnntYvHhxtFRVUVHBihUrjvkY29ra8Hq9aDQaUlL6krZVKhWXX345NpuNjo4O/v3vf/dpQT4cgsFglBicd9F4JXMCqJOMaBKNCIJAXp5iuzCYHhKA1+uNBruJiYnosqxYF2T1EcDLzMxEr9fjdrtZvXp1v3NdXV1NS0sLGo2mn/HpsfJg3m1WMrGLk2KRJImXXnqJ//znP3wQFq/7zrg01AkGUn4xlbTfTif20ny0GRbSDTquTo3njXHDeSA/Ha0gsLy9m+vLasjMj+X1783gnkUFqESB/+5q4IJH17GjZnA/sf9fcSaAOUa0t6/G4dyHSmUkM+Omvk/WKqUBdfp0EhMVQffGxncOu7+3mzvZ4NdhCPn4Y+lDCBVfAPDSpoPsa+jGqlfzqwt76s2CIHCT+n0EWWJtaBzbupQBWxQFFky6G4ffhElVx659yygxKDdjjLSNbduvwuOtQadL5/+2/4T3Ky6kMPXwk++JQiUIzIhRJtkve5WRDFoV48OT7DexGyky2Wo0GkymI3Sa0VNGqqyspL29Hb1eP6BjdF5eHmq1moNhgm6+UYcoCNTX19PQ0IAgipSHEhieqLzn/DgleP6ivW/L6Nx8paRzNHowEfLu9WnxqMMrWFmWeWmTkvm7fnp2v+ycLMl4dimvM447fPkogkimymlVdF9M01P7PD9YBgbAMimZ1KByDCWrekQbrXoNNoMSpNSFy0g95aMe7RaVSsX06dP7aIZ8HUhKSsJmsxEMBqMdUaCc77KyMp588kkeeeQRli1bxksvvcTbb7/Nxx9/zJo1a+js7MRsNrN48WJuueWWftkRvV7P+PHjue6667jmGiWbu3nz5mPO9kTKR+np6QN2G9lsNm699VZSUlJwuVw899xzR1USa2lpQZIkDAYDqdNyiVmcB2oR88ye6yBSRjrc/lpblWvaYrFgNA6sFK5SqZgwYQIAa9eu5Z///Cc7duyIZmMi2Zdx48ZhMPTVxzqWAMYeCLIqvHhYnBwbDTxLS0tprq1AEODCscrnE7WqaLm0NwRB4NaMRD6ZPIJ8o44mf4ArdlbwUHUTt88bzhvfm0F6jIHaDg9XPLWRJ1aXn/FT6oVjDmDWrl3LxRdfTFpaGoIg8N577/V5XpZl7r33XlJTUzEYDJx99tn9LsiOjg6uvfZarFYrMTEx3HLLLTidfXkSu3fvZs6cOej1ejIzM3nooYeO/dOdBFSX/Q2A9NSr+3JGZBlqtyh/Z07tEbVr/gBJGrg1zh4I8rtyJVL/qVxKtrcJdr5CU5eX/1uuDDz/e34RCWZd9DWBgJ247veYyyoAfldeHy3DzMjLptx9OQClja/Spo1DkCXkpr8hy0GSky4iKfc19rfnYNCoonLsJxOzwlmCQ3kwET2YbyIPpjf/5WhKb/Hx8VHdC1AyAjqdrt92Op2O4cOHYzcq5Za8cPkokn0R4zLxoSEvSTmnC+KU7bZ2u3AEe9oq5xUoQcWGinYCof4p9Ah2O9xs63ajEYQezypgY2U75S1OjFoVl01M7/c6f003oS4fgk6FvuDoeFORAMaXqyXlZ5P7aWoMloEBZZDPjlEmmqpmB57SntJFTyeSktmJEHg1xyE+d7LRW+4+MiY2NDTw4osv8sorr9DS0hIlMSclJZGdnU1RURGTJk3i3HPP5cc//jHjx48/ollnfn5+tGz2/vvv9xtbD4fIxH24Vm+LxcJNN91Ebm4ugUCAV199NVrWGgy9BewEQcA8LZX0P8zEPL2nySE3NxdRFOno6KC9feCFzUACdgPhnHPO4bLLLsNms9Hd3c3777/P008/zY4dOygtVYwjByILRwKYurq6I4oOftzaRUCWKTLpKTDpo6raAOPUDUzJjiXVZjjMHnowymzg08kjuDY1Dhn4x8Fmfrq/hknZsXx81xwuGptKUJJ56NNS/vBh8VHt8/8HHHMA43K5GDduHI8//viAzz/00EM8+uijPPXUU3z11VeYTCYWLVrUhxR17bXXsm/fPlasWMGHH37I2rVruf3226PPd3d3c+6555Kdnc22bdv461//yu9//3uWLVt2HB9xaJHfbCKxzUfWJy/C2r+BK3yjddWCswkEFaRNIC5uFlptEsGgnbb2VQPu60+VjbQHguQbdXx/tLJioPQT/v7+Rpy+IBOyYrh6St+VVmvr58hykBsNmzGIIlu73fy3uedmXzL7x7R64mlRKxNSEs2YVCpGFj3EqFGPUN4WrhMnmxGPQR79eDErnIHZ3OXE12tAiJQlNlV+83gwR8t/6Y1IGUmlUjF16uAKzYWFhXSGA5h8ow6PxxMVvGvWKsFEXmLYLdygI9egIyjD+s6eMtLoNBtxJi1OX5DtBwdPO0eyLxcl2kjU9rT9R8i7l05Ix6LvLwcQ6T4yjIo/ag2ISKltMN5EJAMzUAADkB2eCBoMouLhE85SZcT0NXUMhDMw2tQjZ8a+DkTKSKWlpbz99tssW7aMqqoqVCoVM2bM4Gc/+xk/+9nP+MEPfsDNN9/MVVddxcUXX8zMmTMHDHoHw9lnn01SUhIul4v333//qO+xSAbm0AzPodDr9VxzzTWMHTsWWZZ5//33WbNmzaDvE+GURPRfgH72DDqdLho4RYKMQ3G0AYwoiowdO5Yf/ehHnHPOOeh0Opqbm3n//fcBGD58OImJ/bOHSUlJaLVafD5fNNszGN5rUe6tS8O6Sb2zanGih7NSgwO+bjCYVCr+rzCLp0YqnLN3mjtp9PmxGTQ8tnQC9y9WOqr+s7mGLs/px4n5OnDMAcz555/PAw88wKWXXtrvOVmWeeSRR/jNb37DJZdcwtixY3nxxRdpaGiIZmpKSkr49NNPeeaZZ5g2bRqzZ8/mscce47XXXotG6a+88gp+v59nn32WUaNGcfXVV3PnnXfy97//fdDj8vl8dHd39/k5GbDFT2dsjRFdZxN8cT88PBL+eyfsek3ZIGU0aE0IgoqUFMVduKnx3X772drl4sUGJfD4y4hMtKljIGUsSAH0pe+iEgX+uHhMvyCjpVUh6BalzOaHccpg8Zvde/hox0pkWSYnKZZO8WZqUW6CbKmBqVP+S2rqEgRBiHogFaQMncbF4VBo0hOvUeORZHZ09/BdxmfFoNeItDn9x+3d83XhaDuQemP8+PEUFRVx3nnnYbEMfu4LCgqiGZgUKcju3bsJBAIkJiZS3K0EE8OTerILkSzMql48GFEUmJOvcE4G48F0BoLR+n1v8m5Tl5flYe+WG2YM6/c6OSQrHkGA4SjLR9AT7HV0dPSb5GRZPmwJCXpMHRutakLtXhxrwq2+kQxMpwc5KBFoUa6x0zEDA5CTk4NarcbhcEQVmseMGcOPfvQjFi1aNGhZ5Fih0WhYsmQJKpWKsrIytmzZcsTXOJ3O6LUd6Zg6HNRqNZdeeimzZyuk/VWrVrF8+fIBtz3UQmAwRNrcN23aNCAJ+WgDmAg0Gg2zZs3irrvuYvr06dHs1YwZMwbcXqVSRT/74cpILb5ANKt8SVIMgUAgun11SBkXQvX7jmtxtjg5luk2ExLweqMS8AuCwLVTMxmdqMYfDPLfXUfHPfq2Y0g5MFVVVTQ1NXH22WdHH7PZbEybNi1KXty4cSMxMTFMnjw5us3ZZ5+NKIrR9tKNGzcyd+5ctNoeUaxFixZRWlrazxAuggcffBCbzRb9OdIK4rgx5274yR649Gkl4Ah6YfsLsCosItfL/yg1RQny2tpX4/f3XXk+UKFcgFemxDIzXGZhvKInc4VqDTfPHMbItL7taYFAFx0din9OkpzNHZ9cTr6rmlZNLLfY47l6xUeUdbaxdO53OehU/FfEmhB3vtlOTZgsG/VASjk1rW+CIES7kV6ob4u2/OrUKqYMUya1FzdWn9IsTGcg2E8UDZTWx6au/u2TBz0+6nptH7kGJa2J5u6ja7fU6XRcddVVTJlyGINPwGAw0GUOfzf1NdHy0cRJk6kJl0nyegUw83sFML3PYZQHc2DgAOblhna8kswosz7qWwXw0qZqQpLM1Jy4AYNcX6UdyRlANKrR58Uc4VP3IBLs+Xy+fgJj27dvJxAIoFKpsFoHvi6zwgFMa5oSsHSvVmwGxvsEbkTLtF2dND28DUIygl4d9WI63aDRaKLaJDk5Odx+++0sWbLkmILho0VycjLnnqtw8ZYvXx6d/AdDJPuSlJTUjxsyGARB4Oyzz+aCCy4AlLE7ItIYQSAQiL73kQKYCRMmYLVa6e7ujl77vXGsAUwERqOR8847jzvvvJNbb701ShgeCJG5I3I+BsIHrXYkYKLVSLZBR21tLaFQCEFrYGMgG0lQ0drSfNwt80tTlQz1fxo7aA13lz3++ONMdmxkhvogb2w5Nq2abyuGNICJsMyTk/tamCcnJ0efa2pq6nfxqdVq4uLi+mwz0D56v8eh+OUvf0lXV1f051jFiI4Jah2Muxq+txZu/gSKLoaIAFzewuhmZnMBFstoZDlATe2/o4+7QxJbupVa/f8M62H6t+ZcjF9WMUas5heOB8HZd/JpbVuBLAcwazMxvfYDTO4WPmv5Fz8NlaCT/KzRZLBgRzWP7N9Fm1bpLhKcEp+XNHP2w2v4+/JSihsjFgKnJgMDcG1qPCLwboudXx6oi060S8PiaC9vquGvn5WekiDmoMfH/M37mfNVCZXuHm+dsmYHC/++hnP+vqaPU3aLL8DCLaWcv+1AtAQWCWD+/EUtVz29cUiPu9kfxCeqEGSZqk1f0traikajwZY+nKAkY9KqSLH2aLLMjDWjFQRqvX4qe3kFzRmhZFX21nfT5vT1eY/tXS7+Vq3cR7dkJEZ5PBvK23hqjVLHv2nmsAGPL1o+GpNwTO2TWq02mnnqXUaqq6vj44+VrOK8efPQaAZWsI5kYOpUsuJOHJRpfWo34za3cRt6RjqkaPu0cULi0MgCnCRceOGF3HXXXdxwww1HnNBPFFOnTiUvL49gMMjbb7992Nbq3gJ2x/M+8+fPB+Cjjz7qM/42NTUhyzJms3nQADUCjUbDvHnzAFi3bh0+n3Ltlru93LOviuawl0+k/LO3vov7PthH+yHX+GCIiYk5YnbpaIi874W9jxYnxQBE+S9NkhUfGpJylUzS4cpqh8M8vYgBmYNeP796+TVWr14d5QUNV7VTWt/OvoYuQkGJjkYXVbvbKN/WQvm2Fsq2Nis/W5TfTZVdeJ2HLznJsozPHaCr1U3Qf/w2Baca3xolXp1Od0w14iGBIED2TOWn86DCgwlroESQM+zH7N7zPWprnyMj/Tr0+lR2OdyEZEjRaqIrS4DtbSo2BK/jt5qX0ZT+F2rWw4V/g1GXgSDQ0vIJAEnlFeB3wLA5GJe+xi90Zq4u38S9e7fzmW0iT3UDOmVg/Om8cSzbIrK+vI1Hv+hpTzxVJSSAuXEWHi3K4sclNbzQ0I5GFLg/L50LxqRy33dG8bv/7uOJ1RWoVSJ3nzPipB1Hmz/I0l2VNPuV2vSyulb+PCKDBruHG57djN2t3OQvbzzI3ecqGazn6ttwhiScIYlyt4+RJn00gOkIanG0u2ns8pIWc3Qr1iMhosBr9bjwu5Qgd8yYMdR0Kcc2PMncZ3I2qVRMizGxrtPJqg4Hw41KcJNk0TMy1UpxYzfrylq5dIIyaDf5Aty8twqfJHNegpWrwyq+Ne1ufvDqdkKSzKUT0jl/dH/fIzko4dmrDKKGsUdfPoogNjYWh8NBR0cHGRkZOJ1O3njjDUKhEIWFhdFSxEDIDBs6NvoDmC/Ox//EbmR/CClWx/L2burU8L83TkSTakJlPkon9a8JGo3mpGRcBoIgCCxevJgnn3yS5uZmVq5cyXnnDWwXMpCA3bFg7ty5NDc3U1JSwmuvvcbtt9+OzWbrR+A9EsaPH8/69evp7Ozkq6++Yu7cufxfVRPvtnSRWjiJG2v2RbPzf/l0P+vK2qjr9PCvGyYfYc9HRigkkRinLJY7Ozup3t+IXmtEVAkIooAoCrRKIbZ0uxBQzBuhh/9ywG1EqxZZcsFZ/PvJEurr61nx9iaEbiVwsyYasCUasCUYsCYaMIatN3yuIK4uHwcra9i5bxu1TZUMyx9LSVoO+1OymSDoyEwaTlntbrrddi4NdPP533ayxishH2VXks6oJibZiC3JgCVWj8cZwNnpxdHhw9npJeDtCVxMMTqsCfrocZpjdYNyJlPzYrAmDM34d6wY0gAmohvQ3NxMampPe1xzczPjx4+PbnNoKjMYDNLR0RF9fUpKCs3NzX22ifx/qDbBaYPYbOXnECQkLMRmm0xX11Yqq/7ByKI/R1ufJ9mMfW7o7TWdvBBaRFzRPO5yPAzNe+Ct78Ledwgs+j0d7esASGp2Qd45cNVLoFEunOy86byQOYqVnz/Jbymi0piJMeRm5ohRzBlr5dO9Tdz/YTENXV6SLDoSLac22Ls8JY6ALPPT/bU8U9eGWhD43fA0bpw5jEBI4oGPSnh0ZRkaUeDHC/OPvMNjhCsY4rrdlVR6fMSoVdiDIV5v7OCOlHhufXYzjV1erHo13d4gL39Vww8W5CGLAi809HRJ7XN6yJKDBAIBJBlcsjL4lDR2D1kAE1HgTZF6VkyTJ0/m3VLlmokQeHtjQZxVCWDaHdya0RNYzCtIpLixm7UH2rh0QgbekMR391bR7A9SYNLzz6JsREHA6Qty24tbsbsDjMuw8eBlYwacaLwHOpG9QUSLFl3OwGTbwyEuLo6amho6OzsJhUK8+eabdHd3R6XqD9ddk6zVoBUE/LJMi0VN1q+ngiDgkSQeuPczCMJPM8zoDUfhQfYNg0+SKHZ6cQZDOEMhHCEJRzBEpy+I3i8xTqXF5Q/h9AXp7vDgrnGRHmNg0Tk5GK1azGYzl1xyCa+++iqbNm1i5MiR/YKUQCBAY6NitHi85XdRFFm8eDHt7e20tLTw+uuvc/PNN/fjv3hdAbpaPLi6fCRkmrHG9713VCoVCxYs4J133uHLL79kypQp0Yx1Y0wCVYKyyJEkmZ01dgBWFDfz6d4mzjsk8JYlGafdR3ebJ/zjxWn34XcH8XmC+D09v/3eIFJQCQZU8UZCGjfvPLkOna+v+OGWPB1MMpHeFuD9ezZgjFNRLygk5XR3LLNtZtYvK0fbnUzQWM/m7RuJ6RiHQP97Sq0VCUkSXlU7HlMdAW1X9LnRtW2UpOVQFZ+B50szNSUyIVMsWOxYdW2oO9KRAY1ORUyyEbVW7HPfCoJyjhztXpydPnzuIM1V3TRXDc4PValFQkEJl92Hy+6jsbxr0G0jOPeWUd+OACYnJ4eUlBRWrlwZDVi6u7v56quvuOOOOwCFPGW329m2bRuTJk0C4IsvvkCSpGhb24wZM/j1r39NIBCIppRXrFhBQUHBKVu5DBUEQSA/7xds3XYFjY1vk5X5XbaFyZiTrH07JXaEb8bUgqkw4QtY/zCsfQj2f0ir80vkXBUmVxBT9vlw+bNKKas3dBYWXvhzZpd+xhubniFVr0NtmAnA+WNSmV+QxOtbak4Z/+VQLE2NJyjL3FNax1O1rWgEgV/lpnLrnFyCksyfP9nP/604gFolcsf84UP2vn5J4tZ91ex0uInTqPjvxHxu31tNscvLVZ/uoanFSYpVz5vfn8HVyzZRb/fw7o56pAwTHYGeVck+p4fpfoW450aLFK7AljR2s7AoecD3PlaUh8taheFrIy0tjbS0NMrX7QT6EngjWBBn4Q8VsMHuwBuS0IdLO3PzE3lydQVrD7QSCkn8/EAt27vdxKhVvDAmB7NahSTJ3P36TkqbHSRadDx9/WT0vUzdeiMiXmccm9Cvg+Ro0JvIu2LFCg4ePIhWq+Wqq64a1NE7AlEQyNBrqfT4qPX6yQ5zXIyIJJi1tDn91Ha4saUfe2B1uuPqXRVstLsGfd5W5mDyPje5QRUpIREBaACe+7ye9PwYhk9MInd8NhMmTGDHjh188MEHfO9730Ot7hn+GxoakCQJs9l8QmOsTqdj6dKlLFu2jIaGBt549e1oYFS53kX5f9fic/ftzolPN5E9JoFhYxJIzrEiigKjR49m/fr1tLS08OGXG6lT9XT8fWBN5jf+AB0dXhy+nn394f19jFBrcNS7aarsoq3OSXe7JxqUHAu0QRsejRssLizmDGRJRpJkZEnmQJZy7RXWBQgFJNrsrRALqqCBaV4zeAO0EEAvZuA2NBLUdpM330BSbDpdbR66Wjx0t3pwdLpwqBrxWOsIqSO8MIE4bQbZiUVYTXFsCvio1UDL3HjO6hLxBkzsaK4ioO3ifXM33790ApfOzDpiZivgC9HV6sHe7Kar1Y2z04fBrMEcp8cSq8ccp8Mcq0etFfG6AnS3eulu89DV5sHe5qbK7SflkCqdPyTR4fJHs0hfB445gHE6nX2UEquqqti5cydxcXFkZWXxk5/8hAceeID8/HxycnL47W9/S1paGosXLwaIdmLcdtttPPXUUwQCAX70ox9x9dVXRyP0a665hvvuu49bbrmFX/ziF+zdu5d//OMfPPzww0PzqU8xbLaJJCaeS2vrcsor/sY2550ATLL2dBwEQxK76+wATMiKAbUW5v8CCi+A935AS0w1oCJJzIMrXgDV4F+drmAR1+efo4TgvWDQqrhp1slT3j0aXJ+WQECS+VVZPY/VtKARBX6ek8r35w0nJMn89bNS/vLpfjQqgVvn5J7w+0myzN37a1nV4cAgirw8Jpc8o57b0hP46YE6qi0qEg1qXvjuVDLjjNw8axgPfFTCM+urCM5SgpIik54Sl5dip4c2WQlguiUdhSkW9jc5KGl0HO4Qjgll4RLSnOHDyGRB1G6gPNypNXyADEyhSU+KVkOTP8DaTgfnJiiT+KTsWExaFe0uP7/fW8MbHXZE4OlRwxhmUAbhR1aWsby4Ga1K5OnrJ/XzPIqeR38Ib3G4fHQM3Ue9EQlgIr5QAJdeeumA7awDISscwBxq6pgea6TN6aeu083ob1kAc9DjY6NdKVcUmPRYVCr0Mvg6fdQ3OanP0NOVbyHkUZFSolw7LrOIwxMkJSRSf8BO/QE7a18/QGJOElq1ntbWVj5693Nmz5yNKUaHzqju0z59IvwhrytAa5mPXPNU9rnXUhY2iwVwNagQJSXgMMXoMFg0tNc5aa930V7vYvunB9GbNWSNiiM22cSI9Am0tHzGR2VVUBhHst9DyOejzRLDz3dUM/9ggPE+FSNMBkzOEDF2mU8e2dXvmERRwByvx5agx5pgwByrR29SozUoPzqDGq1RjVavRqNTodGp2LM3jvfeew9bjsQNt8yM7qsjEOS3X+4FGf5w6wTivbDi88/YWwptISt12iBXTM8iOz+W5Bwr676S2LJlC03eA5y3SNlPd3c3W7ZsYevW7VFCu06nY/LkyUydOrWPlMBttS3cW97AjmE6/jJFKWt3Pl9CdXU1Ol0bbxU3ctms/pn/Q6HRqUjIMJOQceTuPINZi8GsJTnHil+SuH53FWs6/Tw9KptLwn5Pbn+Qpf/6il3Ndmju5LaCryexcMwBzNatW1mwYEH0/7vvvhuAG2+8keeff56f//znuFwubr/9dux2O7Nnz+bTTz/ts8J65ZVX+NGPfsTChQsRRZElS5bw6KOPRp+32WwsX76cH/7wh0yaNImEhATuvffePlox3zQMz72HtraV7G/fTYsQRC3AWEtPALO/yYE3IGHRq/tMUqHEfA7MnUl7k5KGTZ77xGGDlyiOIHb1deK7GYkEZZl7yxv4e3UzBSY9lyTF8sMFeQRCEo98XsYDH5UwPMl81I7Kg+H+igbeau5ELcAzo4cx0WZClmV2fFUPxhDoVVx/2cgoJ+iqKZk88nkZB0IBAm4vRpXIfXnpXLmrgn1OD5vrlIE+qDZyz6ICbnlhKyWNQ9eyX+ZSJvYii4lJYTKjLMtUhCX08wbIwAiCwPw4C681dXDDnirGWQycn2BjUYKN6cMTWN5s51/tnSAInCPoyAwpE9Qnexp5dKXSJfHHS0czMWvwQci7vwPZL6GK06PNPD7+VO9OJIA5c+Yck6txpkELnQObOu6qtfdzpf4mwe8NcnBvOx2NLjQ6lTKpGtS8LSufabxayy+rROpK2uls6pEj2Fgg8fl4I6vHGimakMQ947MwWrX89bP9PP15JSMCKs6xWgi2eGmt9KDTD8Mfs58de7+ienUQdUgpPXTF7gMB3PUa1r5+AKNVi8mmRatXo9KIqDUiaq0KlUZEpRbxuQI4w2WGyO/uNi+tB7uJcFbNxlyc1goADFoTF94+CVuiwqnQhG0kvK4ANfvaqd7TTs2+drzOAAe+UugCMjLqOAuNJiVjHN/aTGFTNe9OnMcnbhexxQ7O8WjBE8mSCrgFmfThNkaMTCB5mBVbUpi/cYx+PZEyWkNDA8FgMJqtWtHWTUiGkSY9uRYDWKClUxmbdwpmUkdbOPuawuh+Zs+ezbZt26iurmbLli3U1NSwb9++qEheTEwM06ZNY+LEiQNyOJckx3F/RSO7nR72OtyMthgZO3Ys1dXVDFe18V5FGzXt7qhr9VBCCpf814Q1pp6ubeWSpFiCIYkfv7qDXbV2YowaFhR+fQrXxxzAzJ8//7CsakEQ+MMf/sAf/vCHQbeJi4vj1VdfPez7jB07lnXr1h3r4Z22MJlySUu9kg0NygQ4ymzA0OumivhcjM+MiZKl3O4q9uz9MU5nCSAwfPg9mCwFp/zYTwZuz0yizhtgWV0r7zfbo5H9XQvzqe/08Oa2Oj7c1XhCAcwzda08WauUPf5emMXCeGUg/OcX5byxuQ5NroVAvpXPvW7uCTu+WvQarpqSyZNuJShZmhLHFJsJEegIhNhW10Y6kJ+VwrjMGACq2l24/UGM2hOryDqCIZr8Cvcl4kIN0Njlxe0PoRYFsgcZqH6QlUSVx8fmLhe7HB52OTz8uaqJtOF6pPR4EATEeher99az5tNK8pLM1Icn/O/OyuGKyYPzHiRfEOd6pcZvHHv8HT69hf/y8vL6LISOBhHC+6Et8AOZOn4T4PcEqd7bRsW2Vg7uaycU6K/8+s4CCyRpSNrcyZ6ycA5fgE4dlMoBLsrPYHy2hb8dbObJkJNsRzc3WRP42bkF+AISz6yvYlugk79eO5IRQQ3tDWnsqO6kO9CMO7YcS9sYAv4QHrkTBOiqEtlzoO6EPldcmolhY+LJGjWBrcVr2bFzB3kFueQO4FquN2kYMTWFEVNTCIUkmiq6qD9gx9mhcFX0HYU0hbvukh3tJDm6mFru46t8PR9ONnLO5x3MHJHIpAnJPLe/gdf3N1Go1vDBoiw0J2AyGBcXh9FoxO1209jYGA1oPmmzA3B+opIlcTqdUU5nk2ThplF9OTg2m40JEyawbds2Pvroo+jj2dnZTJ8+nYKCgsNyv+K1as5LsPFBq51XGzv4k8VIUVERH330ETF4iRM8vLG1lp8tGvp54U+Vjbzd3IkoyyDLbO92s6vbxWufV7Byfws6tci/b5w84KLqVOFb04X0TUBOzp2UNz4HwChNG9Bz0UX4LxPCq+CWlk8pLvkFoZATjSaO0aMeIS5u1qk+5JOKS5NjWVbXyrpOB0FJRi0KCILAJePTeXNbHevKWqNW8scKSZb5vyqlVfjXualcGe628QVDPL5aKYH+ZkwmD/q72e30sKnLFfVtmjcxlcdL/SDLLNQbMahEhht1lLl9tKkF0oF5Y3JIMCtk6FaHj9ImR/S7O15EykdJWjU2Tc+tGSkfZccbBx2UR5j0vD8xn1Z/gOVt3XzS1sW6TgcNgSCoBEYb9VwzPIZVPjUbK9qj+5ydl8CvLigccJ8AwS4f7c/tI9DkQtCIGCcfP9fHYDAwatQouru7WbJkyREl8Q9F5iABTG8xu9MRfm9QyVR0+HDaFUJly0EHtcUdhII9QYs10UBGQSyhgITPE6QtEKQ2Ubn2p/pVjJqbTmZRLIE4Lec9+SVqUeCfZ+VgNajxyzKP1rTwvwfq0IkCS1Pj+fWFRfiCEi9tOsjPPy7msaUTuXBBIeM7k3niiSfwYeecW2KIsyTx4mvrUIkq5l0yHq8zhLvbj7vLT8AXJOiXCAUlgv4QoYBEMCChM6oxxegwx+gw9fpJzrH2IeWmDL+IEQUjjqqzSaUSSR8RS/qInvvIL43l96t3ApDc3UFCQjwv3zyZOZv30wS8N0bPH64qIt6s4+dj4lj+93b2Nzn49/oqvj/v+Hl0giCQmZlJaWkptbW1ZGZm4gqFosapF4a7jyLO2R2SAR8aFo3q32Qye/Zs9uzZQzAYZPTo0UyfPv2Y2uevSY3jg1Y77zR3cu/wNAwGAwUFBRQXF5OrauOtbXX89JwRqIZQWf2Zulb+WaMEZvNKt1Mbm0R5ciY/31JJ6eZaRAEeXTqBSdlHr0Z+MnAmgDmF0OmSqNHOAD8kOd5FkqYiigqhd3s0A2PiQNkD1NYqgY7NNpnRo/+BXneadl+dAMZaDNGOoB0Od1RQbfKwWHRqkRaHjwPNzuNq+d7n9NAZDGFWidyR2ZPF2X7QjjcgkWjRcfv0YZQfqOOlhnaW1bZGA5gPHcrkLrZ4+bSjlrOy4hhpNlDm9uG1GMAOw9KUfRalWml1tFLSeOIBTITAm2/sy0OJlI8G4r8cikSthmvT4rk2LR5XMMSqDgfFLg83pyeQqNXw3RnD6PIEWF3aQnWbm5tmDUM9SFDkr3fS9sI+pG4/ollDwo2j0Jxgt8EVV1xx3K89Ygam8/TIwMiyTHN1N3tW13FwT3s/0mpvxCQbGT4xkbxJScSn922Rf7mhHbm0lrEWAz/85fjo40+uVsoyM4bHYzMq48cvc1PxSjLL6lq5e38telHk0uRY7vvOKHzBEG9sreOu13agVYucMzKZBQsWsHz5cj5fuYKZMxVuRkZmBhPOHjak50KlUh1TmfBQ7HV4CAoier8Pm8dFcu4wLBo115mt/K2jg1COmWYk4oF4s45fXVDEPW/t5pHPD3DhmFQy446/tNI7gAFY1e7AK8lk67UUhX3KIu3TjZKVsRm2AbsRY2Nj+fGPf4woikdl/noo5sZZSNdpqPcF+KSti0uTYxk7dizFxcXkqTvY1u1h7YHWISvlfNhi57dlSsZ1alUxBc21xAX9lCdnskf2o1EL3HfhyAGDtVONMwHMKYQ3JFEWUMoY2f4vaWh4g5SU71Dfsp2R1ve4MKMGVWsDtQGldTcr6zaG5/5PNMj5tkElCMyJtfBBq53VHd3RAEavUTE1J451ZW2sK2s9rgBmXVjme3qMOeqyDLAxbB45c3g8giBwW0YiLzW082lbF1VuHzaNijebFKE19UEn7zns3LOokIww78hhVoKICJ+jKNXC2gOtQ8KDKQu3UPcuH0FPBuZYU7UmtYqLkmK4iJg+j9sMGi4Z39+ksTc8Je10/Gc/sl9CnWQk4aZRqOMO3yl0shHVgvEF8EkSunAGJzO2l53AABk7vyTxUFUTixJsfVSHXb4gD684wGUTM/qpXh8Kl93H1k+qqdzRSkyykYzCWDIK40gaZkEVDgCDgRDlW1vYs7qOloN9id1avQpznF7JWMTqsCUaGDYmgbg006AZxo9b7QBckNCXmPzZPiWzeG6vCUQQBO7LS8MrSbzY0M6PSw4yzKBjgtXIg5eNxReUeH9nAz96dTsf/Hg206ZNY/fu3TQ1NbFqleLVdtLUy08AW8Pt07mSH4GeVmyxxYvY7kFKNvCz0lo+mJiPShC4fFIG72yvZ2NlO79+by8v3DzluEuevQXtZFnmkzalpfj8RFt0n70DmKWHmdAPZx9yJKgEgatS4/h7dTOvNrZzaXIseXl5ilqyx0OK2M1rW2qGJIDZZHfyw5KDyMCohiom1Bxg3rx51DklvnB102myMmNOBtcPYDPydeBMAHMKscfpISBDnCpAYrCFA2X3U3rgd4DMkrD0STAAanUMI4v+QmLi2Yfd37cB8+OUAGZNh4N7chTtIL/fz7QkmXVlMuvK2o6rGylibjgntu+k/2WF0kkza7ii7TDCpOesOAtfdDh4pq6VJK0GjyQz2mzAZDayq9POKxuqqZX8oId2kxW9Xh+VWh+Zqkx8QxHARDMwpoEzMHlJZnwHu+l86wDqRCOGUfHoC+NQmYY2wHVuaMD+QQXIoMuLIf7aIkTD1z9UJGjUGEQBjyTT4A2QEw70Iqtetz9Eh8tPvLlvAPh2cyf/rGlhfaeTTyf3CCW++lUNz6yv4kCLkxe/O7DBpsfpZ/unB9mzpj7KUXF3+2kos7P5gyo0OhXpI2KwxBso29KM16VwmES1QP7kZEbNTiM+3Yz2GM+fIxiKeu2cHy5XgOJVtbPWDsC5I/uW8wRB4M8jMmgPBPmotYsfFFfz+eQCTGoV/3fFODpcftaVtXHnf3bw3g9ncfHFF/PMM89EOY3HK2B3MrE17J92YX4OC1MXR7vydtR0oqmxQ7KB7d1uXmpo56b0BARB4I+Xjua8f6xj7YFWPtrTyEVjj0/tOC0tDZVKhdPpZE9JCSvalUxaJKC02+10dHQgydAsWVg0amikFAbC1SlxPFzdzLpOJwc9PrINOkaOHMm2bdvIFTtYWdJCq8N3QvpeB1xebtyjiFwO72hmVtkuRo8aRUL+BH68bAN56U1sGTGKcm3wuEv7Q43Tt1XlW4itYQG7KTFxmIw5yHIAkPHJKWxunEiJ8yYmTXyd2bPWf6uCl+bmZl555RXq6vqTA+eGvXx2ONx0BZQB4v3336dt26dMU9fwVVUbvuCxSVsHJJlN4XM9O7Zn5eP0BdkVHvxnDI+PPv79cInpP00d/LteIf1+LzOR2+bkkIbAnNVNXLFJKfHZjRbMvcioRb0CGOkoFTEHQ4QDc2gJqbwlLGJnM9Dxn/0EWz14i9vpfPMAjQ9souXp3TjW1RNsPzEOiCzJ2D+qxP5fJXgxTk4m4eZRp0XwAsoEnREuI/VupdZrVCRblYF7IB7M9vAkuN/lIdSrAWFHrfKdDhR8+twBvvpvJS/9eiM7P68lFJBIHW7jgh+MZd41BQyfmITOpCbgC1G9p509q+vwugKYY3VMX5zLTQ/O4uybRpKaF3PMwQvAyvZu/LJMnlHHiF4ZuRXFSvZlYlYMydb+GTFREPi/gkzSdRqqPH5+HS4FqFUi/3flOOJNWvY3OXjo01LS09Oj2ltwdAaOpxoR0c9p8TbGjx+PRqOJCtgJPolbE5V78S+VjXSEx4/cRDM/COtI/fGjEtz+Y3OFjkCj0USd4x9ftZ7uoESSVs3kcBYvkn1pk01kJVrJSzp56uZZBh1zw2PZa2GDx4jDfa6mE1kK8s72EyNf31tWT1cwRIariwX7viIzPZ1LLrmE376/D6dfJtlvQB0KUofImpbBXe5PJU6Pken/E2wLp0Mn28xMLPgPTlcpFnMhN79Yzpfl7fzx0tHExBy5p/+bhlWrVlFWVkZHRwd33HFHHwGtTL2WPKOOcrePL+1ORnu62bdvHwBF6hacAS3bqjuZmZcw2O77YafDjTskEadRRWvVAFuqOghKMllxxj618Tmx5qjWizukDFKXJMUg6/2kiGaSJYEkH5j9QZxaNb6EnpVWboIJrVrE5Q9R2+kmO/7Ya9ygBF3VnggHpmfC6nIHol5GKdva8Nt9qOL0GCck4S1uJ9Dowl/Vhb+qi66PKjFNSyHmouEImmNbm8ghic63ynDvUIh71kXDsMzPOC1WWb2RqddS5vYNyINp7vZR2+mOdodFsD1833klmUq3L5rhiqi4tjp8tDl9JJh1yJLMvvUNbHqvIspdScyyMO2SXLJGxkXPx+i56ciSTFudk9r9HXQ1u8NibPHH3LI7ED6OlCsSbH2+g8/2KS3Gh+MfxGjUPFaUzZKd5bzW1MGCeAuXJMWSZNHz0OVjueWFrTz7ZRVzRySwYMEC2tvbo103pxMafX7qfQFEYEIvyYnyVicOXxCjVsU9hel84XZT4vLyl8pG/lKglH2+P284b22ro67TwxOrKo67S+fss8+mqamJtWplobLQZkQcoHx0KvggS1PjWNPp4NXGdu4elkJmZiYxMTHY7XYyRTv/2VzDbXNyB5X8PxxKnB5WdzoQZJm5e78i3mLh6quvZneDk521drRqkT/ecD71n69mR1wqj+wrY37ytCPv+CTjTAbmFGJbeCU4yWpCp0skPm42KnU8u2qVwWpC5jdLZfho4Ha7OXDgAADt7e1s2bKl3zbzwiuL1R0Oli9fDkB8vJIhmaKpY9Wmbcf0nuvC5aOZMeboYAOwoRf/pTcEQeD2zJ4Wz5vTE1D7JewvFJMiCdQj8QF+0pzK99fUqSbQovytVomMSFbKVCdSRqry+AjKYFKJpOp6SkLl4fLRBUYD/u0tIEDc5fnYzskm+a6JpPx8CraLc9Hl2kAA11dNtDy585iyMZI/RPuLxUrwIkLsFSOwLjgxQbOThaywAF+/TqTYgTuRXKEQ+1095pzFLuX5lm4vDb2cx/c3OuhscvHu37ez5tVSfO4gsakmzvveaK745WSyR8X3Ox+CKJCYZWHiudksuL6I3PGJQxK8eEMSK9uVaynSrgtgd/vZVKmUQI80Yc6MNXNXthJo31NaGz1fC4uSuWGGskj62Zu7cQTg2muv5fzzzz/h4x5qbO1S7rGRZgMmdY869PaDyup/bIYNvVrFH/OVzNFLDe3sdSiv0WtU/OZCxVBx2dpKDrYPrmR8OKhUKi67/HIOJiqcMcPeHYRCIWRZprLy1AYwFyTaSNSqafYH+bStC1EUGTNmDAAFmk6q292sL287wl4GxlNhuYmc1gYSpCBLly7FYrHwzDrlM146Pp1km4E78pQAcbOsobrTfuIf6gRxJoA5RWjw+mn0BVAJMM7aw1Qva3HgDK8mTqXB4qlCRLQpknVZvXo1LlffwWReuIy0ormduro6NBoNN954Iwm5owHwlW+KtiseDSLcgTmxfc/nl+XK4D9QNuey5FhyDFriNWquT4ql7YV9BBpdCCYNfzQHeCVGIBFl8mtWG2h5bAfOrxqRZZmisDVD8Qko8kZMHPOMuj4TZUWLEwvwI58S1JhnpaPLjYk+r47TY5mVTuLtY0m4eTSiSU2gwUXzYzvw7D3yYBZyBWh7Zg/e0k4EjUj8DaMwTTp5tfwTRaSVusbTV9d8MC2YPQ4PoV6VvRKncp4jPBIAUYa9K2p47YHNNJZ3odapmH1lPlf/dirDJySd8kBubacDV0giVadhfK/Mw8qSFoKSTEGyhWEJR870/c+wFCZajXQHJX5cfDBaPvvVBUWMSDbT5vTxi7d2nxIX+ONBhMDbW7Ecejo2I8KLM2PNXJIUgwT8uqw++nkWjUpmTn4C/pDE/R+WHPdxlARkXBot2mAAVelePv30U9ra2nA6HYRkAZU5gbEZJ18BWiuKXJeqLL6eq1fu7UgZKVWwoyPAS5sOHvN+m30B3m5WylLj6sq59NJLSUlJ4WC7i8/CJctb5ygK7hePHUWGx4Ekivx1654T/kwnijMBzClChIw20mTApOpZTUT0X8ZlxAxpH//pgt27dwOwYMECUlJS8Pl8fPHFF322mRljRi1AYwi69EZmzJiB1WrlisUXUh2KRUTmP/95rZ8J6EDwhKQo12h2LwJvp8tPcThDMiM3vt/rdKLIiskFfDmlEN6qwF/VjaBTkXjLaF7+2Tw+/ckc4tx2ABriLcgBCfu75bS/WMz4GGUyOZEMTESBtx//pdXJT9BjDYE60YBt0eAlRv2IWJLunIg224rsDdH+cgn2DyuRQ/0F0gCCdh+tT+/CX+NAMKhJuHUMhsKvV9fhSBislTqiBVN7SAYmwn+JDHS7O5w4OrzsOtCOWYLMoMgNDh2h3XakoEzWqHiW3juVcWdlHlcqfigQ6XY5L8HWJ4MY6T46WrKoRhR4YmQ2JpXIpi4Xjx5Uyk96jYp/XD0BrVpk5f6W45r0TgUi/JfJtr7B2vbwmNlbOfre4WkYRJGvuly826I8LwgCv7t4JGpR4POSZlaXHnn8GAiRct5csw6VLLNlyxY++OADAJolM+eMPjqX7aHAdWnxiMAGu5NSl5fExMSwcbJMkbqFlSVN1NuPjQv3bF0rQRmSu9qZm5YUbXt/dn0VsgzzCxLJT1YWg4IgcGO6sgD8LKiivfPr5cKcCWBOESL8l4mHrCYiCrwTsmJO9SGddHR0dFBbW4sgCIwZMyaapt6+fTtNTU3R7cxqFQWCMsm2pmQya5Yi2JdsNdAcN5ZmyYzP5+WVV16hu/vwQcLWLhd+WSZVpyHX0MMliaTeRySbB2Xqm1Qi0geViuePWiDhxpFo08xY9RpMWhWGFsWU7qBFi/WCYaAS8JZ0MGdtM5eiYX/DCQQwgxB4teVdLEKLDMRdWYAwiNFiBGqbjsTbx2Ceo6S8nevraXlqN/YPKxWC7sdVdH1SRden1bQ+uZNgiweVVUvS98eiy/56TD6PBZkDkHihJwNTd4gWzNYOJRuX26Bsv62pmxd/tQHjZ83c0W3gaqeOREnEp4JzbhnJRT8a288d+VQiKMl8Fp4wL+xVPvL4Q6wtU9L8i0YffblimEHHgyOUEsvfqpuiwX1RqpX/PU8RMPzjRyWUNg2dn9dQwCdJ7HYoE3Fv09sudyAqK9B7zEzXa7krWyHj/6G8AVeY+J+XZOGmmcOUxz8oxh8cOJgfDLIs80mr8n1cPTyLs846CyDqHdUkWTn3JHYfHYp0vZbzwl1Qz4ezMOPGjQNgvLqBizT7eOnj9VGrgiPBHZJ4rlYJ7CY0VLJo0SJAKVe+sVUhBd92SBforaNGYAwFceqNPLmhPyXgVOJMAHOKcCyriW8L9uxRUow5OTlYrVays7MZNWoUsizz6aefRlO9Xq8X20FFnMuVW9DHE2ROQQpf+PORtGa6urp46aWXWLNmDVu3bqWkpISamhra29sJBJT21Qj/ZXZsX1GwL6P8F2X1IAclgu0efJV2XDta6F5VS/vLJbi3NoMA8UuL+pRquru7sTm7ESUJhyTTNTWZ5DsnoM2yIAYk/gcDv7QLdNYc2X5+IEQCmDxTz2cPOf1c0KhMvN3j44/ag0hQicRcmEv89UUIehWBWgfO9fU419XjXFuHY00djtW1hLr8qBMNJP5gHJrk4yMfn2pkhbVgWvxBPL0yS5nRAMaDJMmEQhK7VtbyZb0dgAmVSoary6TCrxcIIRNCRlAJ7NUEed7qI3fiqS8XHYrNXS46AiFi1Sqm23oyiGsOtOINSGTEGqKt+0eLK5JjuTQphpAMPy45iBS+726eNYx5IxLxBSXueau/CeLXib0OD35ZJk6jIsfQ43Yc6RzLjjf2a5f/fmYS2XotTf4AD4ezTQB3nZ1PgllHZZuL576sOqbjKHZ5Oej1oxcFFsRbmDNnTrSVG8CpjWPqsFObtbwpnAF5s6kDZzDE1KlTmTdvHqJaQ5zowXvgS5588kn27t17xEDmP3UtdMtg9bi4rnB41O7jla9q8ARCFKVa+3EGDWoVl8Yp1+Z/PRJtbcfHuxkKnAlgTgF8ksQe5wCrCU/PamL8tywDI8syu3Ypg2KkTgtwzjnnoFarqa6upqREqUuvX7+elFal3XMvaoK92pFn5yXgQ816ijCZTLS2trJq1So+/PBDXn/9dZ599lkee+wx/vrXv9LW1sZ6e1giP6bvZL+hop00BC52CzT/Yzv1v/mSpr9upXXZHjpfL6X7s2q8+5QsTexl+RhG9b1pOzs7UckS8T5lhV/i9KBJNpH4/XHEfGc4HmTGosb51B66VhxEPoaVnizL/VR4ZVmm/e0yrLJAOSESFg076v1FYBiVQPKdE7Gek41lfgbmeRmY56Zjnp2OeVYa1rOzSPz+ONQxX69A3bEgVq3CFCbK1vXKwqTG6BEF8Acl9m5r4vX7N/PpB+V0GUUEWebOK0eSHiZHZ901ir/HeHkyMcBtj85jbaxEtyxR1XZ8RM+hxMdhr51zEqx9BBiXR8tHKcccZAmCwF8KMjGqRKo8fkrCpGZBEPjrFWMRBdhd10XDMZYeTiZ6+C99hf52HGbBp1eJ3J+vZB6frm2lIrwosOg1/OI8pQvp0ZVlNHd7+712METEBOfHWTCpVIrVySWXgDWF+pCVSUW5gypZnyzMiTWTZ9ThDEm81dyJKIosWLCAn/zkJ5SJmfhlFa2trbz11ls8+eST0W6pQyHJMo9VhhV32+uZO3s2oNxDL2yoBuC2OTkDXm8/LFQ4MTVxyawpKT0Jn/LocCaAOQXY5/Dgk/qvJiKaJFlxRhLMA5c1vqmor6+no6MDjUbTR0o8JiYmKl2+fPly2tvb2bRpEwkOOxYBHCGJnY6eMsDUnDi0apHKbjh78dXMmTOHCRMmMGLECDIyMoiNjUWtVuP3+9m0ew87w5yHWWH+S7DLR8OKav63Fd7AQvJOpfUYALWAOl6PLteGcWISlgWZJNw6GtOU/in6znCtN1NWWmv3hQNSQRQwz0zjyTw9XxJAkGQcK2tofXo3kv/o9GsafQFcIQmVAFkqFa4tTbQ8sQt/SQcBZP6u9ZM0gET50UAdp8e6MAvbeTnEnJ9DzAW5xFyUS8zFw7GenT3kIngnG4IgDOiJJAckpqsMXO7Usu7fJXQ2uWlNVwKzArOB/IJ4iszKOVzVqGTJxmTY0KjEKHm+eAhdxY8HvcsVFyTERB8PhCQ+Lzly+/ThYFWrmBbO/m4MB/kASRY9Y9KVksRXVe3Hte+TgUgH0mTroRnrCIE3ZsDXnRNv5aw4CwFZ5t6yhujjSyZmMD4zBpc/xF8+2X9UxyDLMh+1RtrZe95PrdbwmS+fFYECFo0+PpG8E4EgCNyYpmRhnq9vi2ayrWYTU2fO5S3fWFrMw9Hr9bS2tvLiiy+ybt26ftmYdw820IQKbcDPT8aPRKtV7qv/7mqgxeEj2aobVAQw16hjhkkHgkBN5vF7Tp0ozgQwpwBbo/yXvquJI92M32REyLuFhYX9bOJnz56NxWLBbrfz7LPPEgwGycnOZn64thsxTIOwrUA4RbujOcjChQu55JJLuOaaa7j11lu56667+M53vgPAitpGJCDHoCVDr8X+3wqaHtyMtLKWkaiQUJRlYy/LJ/VX00i/fxYp90wh8fax2Jbk8W7jap5b8Ro+X98OF1D4PADD1cr3FwlgIkjPsvELPHw63IBgUOOvdShS/EchbhfJvmQFBdr/vIXOt8sI1DqQBXgUL6qUweXm/39EhMhb0eVh/6ZGPnpiN8/+bD2z2iAnqAIRxp+die07irJshHc2KhzA7AkHuRPCejERMcL9XzMPZLfTQ70vgEEUo515oPC3ur1B4k1aJmUff6k54vW1odPZ5/FpYVL7poqO4973UCPCGZxk6+EMSpIc7R4bzHdMEATuz09HIwis7Ohm/ub9/KO6mVqfn/u+MwpBgHd21HPRY+v419pKGrsGzzpt6XKx3+VFLwqcm9BTtvtifwuNXV6sejWz849en2oocWVKLAZRZL/LGxXtBLh6aiaSqOHjtjjOv/oWxo0bhyzLrFy5ktdffx2Pp+fz/r1UIW/PdNuZNFopi8myzDPrKgG4aWYOWvXgIcKvCrJ4aUwOd2Z/fV2LZwKYU4CI/svkfgReOzD4zfhNRSgUYu/evUDf8lEEWq2Wc845ByDaUn3uuecyP04ZJFY1dtL+2n58lcrqZ054kBhM4yA/Px9RFCkWlYltTqwFT0k7zg3KCqzOrOL/8PDOjHgSbx2DaWoKKqu2T1CwZ88eqquraW5uZsOGDf3eI5KBKQpzVIqdfdPQkUnwvz4vCTeNArVC8LV/UHHYNtVAs4vtyxX+T1abH9kbQhWnx3reMD6anci7BMg7ChPHbxNkWcbrCtBa66ByZyv71tWz/bODbHi7nC9eKkEqVwKNTz6rYuXzJVTvbiMUlPAbRDbpAsiLUph1eT67w4P1hPB9FxE1rAspWbSI4F1hJID5mjMwkezLWfEWDL3KEj3eR8kn1Kk4MxzAbOpyRnkwANNzlQXC6ZKBafD6aRhMwM4bxKBRUXgYyYnhRj2/y0tDKwjsd3l5sKqRaZtK+FVLC7PPzkHUq9hb380fPy5h5p+/4MqnN/LSpoN0uPoSw5fVKaTpJcmxxPZyh382zKNZOi0L/RFI9ScLNo2aJcnKvBFpqQZItuqjWbrXdzSxePFiLr74YlQqFaWlpSxbtozGxkY+LC6lQmtElCR+NWVMdCxcX97G/iYHRq2Ka6Ye3lpiis3EOQk2VF/j4uqMEu8pQIT535v/0nc1EfM1HNXxo7y8nOXLlzNy5EjmzZvXLztQXl6O2+3GZDKRmzuwj9GYMWPYvHkzdXV1jB49mvT0dOaGSwI7vV5a9jrx7GzFMD6RuRMTeRBlJeoPSv1WBQaDgdzcXF63KWJ0My1G7C8qQYF5bjp376qigQAvjUxkIIRCIVavXh39f8OGDUyZMgWzuVcbdjiAGR9jhVY/VR4frlAo2hIfCWBKmxyoMszEXVlAx6v7cW1sRB1nwDKnv3mia0cL9nfKKM/TAFryjToSbslDNzwGQRTY958dAAw/RhPHbxp87gC7V9XRXNWNo8OLo91LwDd4+U0YoYNYE3ajQFyaieETEhk+MYmXiutZt7Kc9GAQSZaj5cSJ4ftuZDgD49IK6IDxkQxMeDL8ujMwy3up70YgyzJflChdIueOPDGxtHEWIwZRpCMQotTljZbUJg+LQxSgut1NU5eXFNvXy4mKSk4cRsDuSLyTWzMSuTw5lo9bu3i3pZMvO53KQlIE04I0fqAxsXV3C5urO9hcpfz83/JS3v3BLHISTNR6/XwcDihvzegZN0oau9lQ0Y5KFLjhazY0vDkjgZcb2/m41U6zL0BymON13fRsPtrTyHs76vnf8wuZNGkSqampvPHGG3R2dvLvf/+blUWTIS6FabKPsemp0X3+Kyxcd+XkzKjT+emMMxmYIYDkDxHs8BLs7E8Oa/IFqPcFEOhZCQJUtrno8gTQqcXo5PdNwPbt23nllVdoaWlh9erVfPTRR/1qq5Hy0ejRo1GpBl6hCILAFVdcwfz587ngggsASBdUDPPKhASB7Rl6EMCzsxXry6XcojXg84eiZbdDkVZQRLtZGfjH7rQTsvtQxejoHJ9AQ5cXrUpkcvbA3QI7duzAbrdjMplITU0lEAiwZs2aPttEApjhifEkadXIwP5eWZjsOCNGrQpfUKK63YVxbCK2CxSiW9fHlX1E5eSAROc7ZXS+XoockKhJVDJHY6ZkoM+PRQivsqMu1N/SDEwwEGLH8hpe+u1GNn9QxcG97XQ0uKLBi8GiISnbwrAx8RROT2Hc2ZlM+04usyYqE7lqhJWl905j6sW5xKebyYhTApXaTjflbh+OkIRBFCkIE6NzDTo0AqAWiUswkBqeqEeEA5jGLi92t5+vA23+IMVhcm3v8tHBdjcNXV40KoHpA+gXHQs0osDUMA9mQy8ejFWvYVTa6cOD2dZ1BAG7oyyjxWjUXJMWz5vj89g5cxQP5KczwqjHJUlsNsi8/r3pbPjfs/jVBYUMizdidwf48ydKY8Gzda1IwNxYczTQA6JdTOeNTiH9OHlpQ4VRZgNTbSaCMrzc0PO9Tc+NIz/JjNsf4t3tCkk3LS2N22+/nfz8fDpVGvbHKi3nv57Qw08sbXKw9kArogDfnZVzaj/MceJMBuYY4Vhbh6+yi5DTj+QMILkCyIGeCVxfFIft/Bw0ScrNF6nlFpr0mNW9Bex6VhOaU8xiPx7IssyqVatYu3YtoDjX1tTUsHXrVnw+H4sXL0alUuH1eiktVVjpEX2CwWCz2Zg/f350/51vH2CaP0B1tpZds5O44qI47O9X4K91cDMa5iNyYHP9gAN5W3I6OJuId3bh39iKFj0xi/N4p7ZHZ8eg7R9MBQKB6GeaM2cOycnJvPDCC2zbto3p06cTHx+Px+OJ1o5jYmIYZXbS0uFgn9PDpPCEIIoCBSkWdtTYKW50kJdkwTwnnWCHF9emRtpfKyXxdi0qk4b2V0oINLhAAMtZWVQbHeAPkt+rhVqSZCp7uVB/myCFJPZvamLLh1U4OxX+T2yKkTHzM7AlGbDE6bHE6VEP8H0B2Fxefr95P/t9flr9ARK1ykoxcp521NjZEJbiH2cxRLt51KJAoizSgERGdo/HkFWvISPWQF2nh/1NjhMOFI4HEWJtoUkf/TwAG8P6RRMyYwe8fo8VM2JMrOl0sMHu5JZemYVpOXHsqe9iU2U7l4zvny08ldjaPbDkxOE6kI6EJJ2GWzMSWZRgY/ZXJay3O/m8vZtzEmzcPnc4CwqSWPTIWj7b18yaijZeaVTO+229zlGb08d7O5Wy9Okywd+UnsDmLhcvNbRzZ3YyGlFAEASun5HNve/v46VNB7lhRjaCIGA0Glm6dCkr1m5FlkUmaEUmx8dE9/XE6nJAIYpnxZ9evliD4fSfOU8z+BucePd3EKhzErL7eoIXtQgCeEs6aH5kG53vlhFy+NkWYdMfejMegYx2OiEYDPLuu+/2mehvvvlmlixZgiiK7Nmzh9dff51AIEBJSQnBYJCEhISwQuTRwbm+Ac/uNqZ1KKvvtU4X2gwLiXeMI3ZJPgGtSA4qztrZhf2Tqn7k2K0eRQcmzd5KtdCCYUwChsI4NkTsA4YPTLbbvn073d3dWCwWJk2aRE5ODvn5+UiSxMqVK4Ge7IvJZEKn00VLEYcSeXs7U4OSZYq5eDj6wjgISrQ/v4/mx3YQaHAhmtQk3Dwa5qfTEnbLzeslYldv9+ALSmhVIhmxX+9Kb6jg9wYp/aqJ1+7fzKqX9uPs9GGO1XHWDYVcfe80xszPIGtkPLEppkGDF4B8k55JViMBWebF+p6V57gMW3Tl+U6VkvGacMgqXuMOZ3cS+p7TwpSvlwfzZTiAmRXTN1jdWKF8vunDhyaoivBgNtqdfbhZkaDtq8qvl8jrkyT2hAXsJh8iOVE2gIDdsSJTr40GJX+oaIhKNuQnW7g6zPn4+VcVdAclcg06Fsb3ZMdf/aoGf1BiXGbMadN4cWGijQSNmiZ/ICqACHDphHRMWhXlLc5oEAxQ5fXzOUrG91dFPUHYrlo77+9sQBDghwvyTt0HOEGcCWCOEaZJycQuySf+hpEk/mAcKfdMJu2+maTfP5Pkn05CPzIeJMVUr+mvW9hcowwI/RV47UBPJ8TpCq9XUcDdvXs3giBw8cUXs3Dhwqi67tVXX41arebAgQO8/PLLbN++HVDIu0fbOeOrtNP1icJ8P2tqBmoBqj1+qj0+BFHANCUFww/H8S5Ket+5po625/chuQPRfUT8j9LtbVSr24i5OBdJkqM376y8/hOA3++PBmVz585Fo1FWvgsXLgSguLiYurq6aAATG6sEm5FulsGIvL0tBQSVQNzSQjTpZiR3ENkbQpttJfnOiehHxEY7kFK0Gqy9MnSR8lFOgumU60wMJXweJWj5+MndPHvPej5/rpjOJjc6k5qZS/K49g/TKZqZdsyy/RFewgsNbfjDJUxBELhp1jAAdoVb8Scc0obrbFUe9xn6ntORqUrZpuQE/KxOBF+GBRhn9bK/kOWe63cg+4vjwXirEYMoKDwYd8/1OyUnDkFQStstx6CTMtTY00vAblgvyYkIXzA7/sQlJ+7MTiZOo6LM7YtmWgB+evYIjFoVNVblPrwlIyFq5eAPSlHLhe/OGnbadAXqRJFr05Rr46/VTfjC94JFr+HSiUom7W+flRIKB2r3VzQQlOHseCtzwqVKWZb540dK6ezSCemMTj/5vk5DhW/uyPg1QZ8fq0yoI+PRZVlRxxsQdYrAkSbJSMINI0m8fSyaTAuBgMTekDLJ5qyox/5xFe4dLThqu6kIEwZPZwE7t9vNs88+S1VVFRqNhmuuuYZJkyb12WbEiBFcd911aLVaDh48SG1tLUDUJfVICHX5aH91P0hgnJBE8qyM6Mor0pUBkJJs5sNkDb/DTUgl4DvQSfPjOwk0u6j3+qn0+BBlmVR7G01CJx4xwP4mBx0uP0atirEZMf3ee8uWLbhcLmJiYpgwYULPe6WkRMtfn3/+ebSFOqJSOdKsZEqKXZ4+3Rw9k2DfVbyoU5Fw4yj0I+OxLMwi8fYxqGzKILy1V4mxNyL1/hHfEINPWZJxdfloruqmfFsLO5bX8NHju3j2nnV8/lwxVbvaCAUkrIkGplw4jOsfmMmEc7JQH2cXx4WJNpK1alr8QT5s7bvytBjV+AzKfnsvHFodPrrDLuKNh/C2op1ITac+A9PsC1Dm9iHQ0+oMUNHqpNXhQ6sWh4zorxXFaDZ4o72n/dZm0EQVfjdVfX1ZmEjDw+RDJSfCBN6hWPBZ1Sp+NkzhUT1U1YQjbDuQaNFxzvxsZJMaMSixuBeZ+qM9DbSGtVEuGHP0meVTgdszEknQqCl1eflbVY9Fyx3z8zDr1GyvsfPMuko2dDr5tK0blaB4R0Xw2b5mNld3oNeI3LOo4Ov4CMeNMxyYkwBdro2kH4xjx45GvF0tGIMyqcVdOOkZaD/FTIVKJqbRjWzVnzYRfW9s2LCBlpYWzGYz11xzDWlpA4saDRs2jJtuuomXX34Zt9tNVlZWNFtxOMhBifZXSpCcATSpJmIuzUMQBJakxLKpy8Wyula+m5GATlTi7EsmpPHQp6XI1hB/lA2E2r20PL6TVd9RvF5GdklkCGZasVNaWsoOt3IMU4bF9etc8vl8rF+/HoB58+ZF3bIjWLBgAXv37qW6ujrqvxT5THkGPTpRwBWSqPH6GRb2XCoIlyGau310uPzEmXpWkCqrloQbRvY7B5+1Kfs+K75voLKiWBEuW1AwcOfU1w1Jkqk/0EnppiaaKrpwdvoIDaI+HJNsJG9SEsMnJhKfbh6Sa10rityYnsBDVU08U9fKZeGWUqNWzdwp6bwtBtEG5aj6LihpctGhlOtqfH5cwVC0yyXSllva7CAkyafUWDVCqB1tNvRp142UjyZnxw5pu+6MGDPrOp1s6HRyc3pPaXVaTjz7GrrZVNnOd8adeoE2ICpieWjGenedHRi6kvv1aQn8u66NCo+Pxw4286vwhF4Xo4EuH0Kti7e+quV784YjyzL/Xq+Qd2+YMey04yzGa9U8VJDBd/dW83hNC+cl2JhkM5EeY+C3FxXxi7f38LcVB0jVKtne61LjGRFeMPmDUpS4fNucXFJt36xy9en1TXyLIAgC+1OViW2s2UD8pXmYpqeizbYSVAtoESgKibQ/X0zrsj34ar5eDYpD4fV62bJFMeq68MILBw1eIkhLS+O73/0u48ePjxqCHQ4hV4C2F4sVJ2S9mvjrihDDvIcrU+JI0Wpo9AV4s6mn6+i66dlY9Gq+6HSyZ2Eaulwbsl9i1X6lzXRKR5BRE5TMT0lJCRsqBi8fbdq0CY/HQ3x8/IBaNTExMUybNg3oEbGLBDBqUYh2tvTmwZh1arLD5LejcabuDAT5qkuZvBb1Wu3VdrjZ3+RAJQqcVZh0xP2cSnQ2udj4XgUv/XoD/31kJ6Wbmuhq9RAKSggCmGN1pOTayJ+cxNSLc7j63qlc8/tpTPtOLgkZliEN1K9Pi0crCGzvdrO9l5hXVq7yPQU7vFS09jy+s9aOEJAwhDu097t6dZHFm9BrRLwBiYPtp9ZS4Mtw+XNm7CH8lyEuH0UwOA8mrAdT+fV1IkVKf+N7BTCyLLOnvkc9eSigEQV+Gw5altW1Uuf1U+L08GWXEwFQ1bj456pyOlx+th7sZG99Nzq1eERtlK8LFyTGsCQ5Fgm4a39N1CfsysmZLChIxJuo44DXj1kl8rOcnnb8lzcdpLrdTYJZx/fmfX2KuseLMxmYk4iIDsWERAvmvJ60452vbmfr7ib+mJ1Mfr0Hf1UXrU/swjAqHuuiYdEOpq8Tke6ihIQECgqOLq2YkJDA4sWLj7id72A3Ha+WEOryg1okfmkB6l4OwDpR5I6sRH5X3sA/a5q5OiUOtShg1Wu4aeYwHvuinEc3VfHfO2ax59MKVuiVCWBBaiyjpw5n9ZZ1VFRW8qXHAqiZO6JvFsPj8UTF6ubPnz9oq/fs2bPZvn07Xq8y0fXOKo00G9jt9LDP6eHCxJjo40UpVg62uylp7GZW3uFVOle2dxOSlfJRdi/n7Ej2ZXJ2LDFG7WAvPyFIIQmPM4DerEF1mBWlq8tH60EHrbUOqve001LdE5jpjGolszIhCVuSAVOs7rD7GmokajUsTo7hjaZO/l3fxsRwaaQyqJRtRbufFzdW84dLRgM9PIosjZpSKUixq6eLTCUKFCRb2FXXxf4mB7mnsHX9S3uY/9KrfCRJMpvChNoZQ0TgjWCC1YheFGgLBClz+6Kr8alhHkxFq4sWh5cky6nVg+kKBKnyKDy3sb0E7Bq7vLQ5/ahE4ZiNLA+HRQlWZsSY2Gh38efKRnThrNv5CTaaYh0UN3b38U66bGIGsaaTcz8OBf6Yn876Tgflbh9/rmrkvrx0BEHgd5eO5rONSpZlSlAV7XLrcgd49IsyAP7n3BGYdd+8cOCbd8TfIOwcYDUBsLu+iwZkxIVZpCRZ6F5Rg3t7M5597XiK29EXxCHoVIoeiCiEf4OgVSGaNKjMGkSz0pIrmjSoLFoEzeATR7Ddg7fMjq+8E19lF5I3hKAWENQiqEQEjYigFlDHGdBmWxDTjWzauAmAWbNmIYZLOJIvSKDRpfy0uBFUIqJJg2hSozJqEM3K8ajjDVEtk96QZRnnunq6Pq0GSUadYCDu2iK0qf2dkK9Li+cfB5up9vj5b6s9WiK4eVYOz6yrYm99N2vKW/lXpoi/Q2C2pGbhwlxUOjWJiYm0traSLnQxauyYaIdJBBs2bMDn85GUlNTHWfZQGI1GZs+ezeeffw70cGCgN5G3byfSyDQrn+5rorjhyBmYT8NdA+cl9F1VRnxvzhk5NBLdsiRjb3HTctBBy8HuaEAS9CtZE6NNhzlWhzlWjzlOh1oj0lbnpPWgA3d3X10UQRTIGhVH4fRUho2NP24Oy1DhloxE3mjq5L8tdu4dnkayTsP28MJB6ArwVn0dP1tUgFmrZle4DDHOZqK0s6sfCbswxaoEMI3dp4znUO/1U+XxIwLTewUwB1oU/pZBMzB/60SgE0UmWU18aXey0e6MBjAxRi2FKVZKGrvZXNUxqA/OyULE8DZLryWuVyltd51yn4xItgxpKU0QBH43PJ3zth3greZOtOHs4PcyEwleaOHaZ77i5U097t3fDRPET1fEaNT8X2EW1+2uZFltK+cn2JgeY+Y9ezeSXgWeIFs2NlBcmMnINCuPfVGG3R2gINnClZMzv+7DPy6cCWBOEnySREl4gBzfazXR5Q5Q3a4MsGPTbahNWuKuGIFlbjpdn1bjLenAu//YSXSiSY3KplN+YpTfoQ4v3nI7oY7+XQWyX0b29+UsBFs8ePd3sF9Vj1PjxCToyaw00F5cQqDBSbD96LoTBJ0K3TAr2hwbulwb2nQzsi9Ex5sH8JYon80wLpHYy/IQB4n6TSoVt2ck8ueqJv5xsJnFSTGIgkCcScu107J4Zn0Vf9haTUm6Dq0g8NCMfFThfcm2dGhtJVdj5zcX9gg1ybLMl19+ybp16wAl+xIJzgbDtGnT2L9/Pzqdro8yb4TIu2+QTqQjGQP6JIlVYc+nKQEVNfvaQQC3P0TDATuZkshEg4HGii5ElYBKLSCKIqJKCWh97gAeZwCvw4/bEcDr9ONxBvB7QgR8wT6/Pa4AwUGUbWUZXHYfLrtCwD0UggCxqSYSMy0k51gZPjEJo/X0WYWOsxiZajOxucvFiw1t3JSeQK3XjwCM0Gmo6PDx5tY65o1IxOENoteIzEqy8kZnFyWHBJ+FERL2KVTkjbRPj7UY+3ShRfkvw2IP60dzvJgRY+ZLu5MNdic39uHBxFHSqPBgTnUAE8lYj7P0XfDtqbcDyng51BhvNXJ5cixvNXfil2XGWhRxOCHGzIKCRFaVKnYCc/ITyE8+/Qn1Z8dbWZoax38aO/jJ/hpeHzecx2qUEvtEt0BxQOZ/3tzFY0sn8MLGagB+dWHRKeV8DSXOBDDHiP2bGmmu7MbrDuBzBfC6gvjcyu9QQMJg0WCK0dGUpCEwTMYqC3h2deAZFY/BomV3+GbMijP2SUdqkk0k3DgKf60Df003sgTIsqJ3Ev6RfCEkV4BQWEBPcgYIufwQlJFcQSRXUBFIOxQqAW2WBX1eLLr8GNQ2HXJQQg7Jyu+ghOyXCDS58Fbb2V2+EYDR/ky8W1r77sqqRZNmRpNiRJZQjsMdPh5XgJDDj+wL4S3txFuq8FcErYigUSG5AqBWtFFMU1OOyIe4OT2Bx2taKHV5+ayti/PDpZrb5ubywlc1lMQpA/4PspLINSolmE6XnzcrZBYAmaouYvXK4B8IBPjggw+iKsFTpkzp45I9GDQaDbfeemu/x8dYjKgExRG5zusnI2wwOC5coy9tdtDp8g+acv6y04krJGELQMnDe+ntj3tFWKdh4zMlRzy+o4VaI5KYZSEx20JStpWkbAu2RAMeZwBnhw9npxdnpw9HpyLjH59mJjHLQkKGGY3u682yHAm3ZChiXi/Ut1NkUjJjeUYdt0zP4Vfv7uGFDdVY9MpQNybdxthwRrTY5UGW5eh1OFAb/MlGhP8y+1D+SziAGeryUQSH8mAi52B6bjzPb6j+WvRgdoX1X8Za+hJJIxmYoeK/HIr/zU3lw1Y7XknmtozE6Ln41QVFrDnQiiSfPsJ1R4P78tJZ2+Gg2uPn/G0HcIUkxluMPDcpi/OK2ylp7OaKpzYQCMnMHZHIvBGnZ6PA0eBMAHOMqNnbTtnWlkGfd3b6cHb62KrSwTATiU0+Vq4tQRAgZbiNRpNATEiIGskdCm2mBW3m0Uf6siwje4IE7T5C3X5Cdh+hLuVHNGrQ5cWgy7EhHsUkpM+LoSbWTne5G71Oz4zvzIdmPyqTBk2qCU2qCZX58KtvWZIJNLrwVXXhq+zCX92l6J/4JVTxeuKvKUKbfnT8AptGzXczEvnHwWYeOdjMeQmKemqyVU/uzFR26WX0AbmPG+pfl5dy0KPBa9Cjl7xUVFSQkZHBa6+9Rn19PYIgcP755zN16tSjOobBYFWrmGgxsaXbxeoOB9eFtRiSrHoKki2UNjv4sqJtwFVsMBDixW11oIHhB72o1AJxqSZkGeo73Tg8ivNwnFGLFJKQQjJSSCYU/lsOyeiMavQWLQazBoNFi8GiwWDWoDWo0erVaPQqtDo1GoMKnUGNLdGAOAA/xWTTYbLpSM755thZHIoLEmJI1TXQ6Avw56pGQPE/Wjw8jT9/UkJNh5unViveWOMzYxhu1KERBLqDEnW+AJnh4DPSiVTX6aHbG8Cq7+sFs73bxUetXSxNjesjOripsp3Vpa1cNz2LjNhj468Nxn/5KtzKPNQE3ggmWo3oRIEWf5AKjy/6eabmKGXSshYnbU7fUWmuuEMSbzV18H6LnctTYlmaqhyz0xfkjS21fLqviZtnDuP8I5TlogReS18C794wgXfsSQpgMvRanh41jL0OD5cm9fDc8pMtPHzVeJq6vMw/TbsBB4JVreLhwiyu3FVBR0DJvN6Xl0ayVc8Di8fww1e30+kOIArw6wuOvIg7nXEmgDlG5IxPxJZsRG/UoDep0Zk06E0adEY1KrWI2+HH3eVnU2cb4GOcyUBCJrTVOmksV27E29Aj7HSyVjygvNagTDi68OSj0ohIkpJ9if4OyegMamJTTX1S+IIgIBg1aI0aOGSulCWZrlYPdXvaoryH1loHoYCEWqtCo1Wh1qnQaEU0ehV5k5L4skRpLZ46bSoxE49dUlwQBbTpZrTpZiyz05ElmWCLm2CHF91w26Alo8FwW0Yiy2pb2OXwsKbTwfw4K+VuL/sMMsgQ2tNBWVE34zJj2FVr5z+bawCBoqIiqop3sHHjRux2O93d3ej1eq688spBDSaPFfPjLGzpdrGqozsawICSbi5tVnxFDg1gaos7WPVaKV9O04FGZJZKx9LfjiUm2YgvGGLS/Z/j1AR59weTvhEqzacDNKLATWkJPFjVGBUGnGA1YtSquXpqFsvWVlLZpmQmx2XGoBVF8o06il1eSpyeaAATY9SSatPT2OXlQJODycOUyfyAy8tfqhr5KKw383JDO8+NzsHmCfHQp6WsOaBkKd/aVsezN00+as7KQY+POm8AtUDUowiU8mOXJ4BZp2bMSRIV06tEJlqNbLS72Gh3RgOYOJOWwhQL+5scbK7qOCwXqMHr57n6Nl5uaKczrKWypctFFiq+2NbAG1tqcfiUtvXihm4mZseSbB2YGNwZCFITNnMd0ysDU9fpodMdQKNSrDpOFhYl2Pp0AkbwddsqHC/mxlm4KT2B5+vbuDDRxrRwgHzh2FQ+3ZfGB7sauGpK1kk9p6cCZwKYY0T+5MMTK61hifKDX7WDGxbPyuLcS2x0t3uo3t3GG+8dIMkHqq4Ae1bVHdcxGCwa4lJNxKWa0MVKaPRqxKAOjyOAx6FwIdzdfuxNLvzegbkPQb+El0Cfx6qqquiKa0StVkdbiE8UgiigSTGhSelP1D0aJGjVXJcWz7/q2nikupl5sRZ+daCOoAxpPmhv9fL4qnKevG4Sv31/L7IMl01IZ8H0OKqKd1BTU6PsJyGBpUuXEh8/dCva+XEW/lrdxPpOJ15/EEeTh/YGJ/lNQc5xa/BvbGOluwQkGVkGt8NPbXEHDbEqHEYDBgTuvmEMhjD3YVNlB05fkCSLjnFDTNz8tuO6tHj+frAJX1hxNKIjcv30bJ5ZV0nEeSLiQD3SbKDY5aXY6eHcXhNXYYqFxi4vJU0OUlPM/K26idcbO5BQNCfS9VpqvX4u31GGak8nqkYPalHJCtbbPVz19Cb+ec0EFhYdmYAdKR9NsJj6uC5vCrcxTxkWe1JVmGfEmNlod7Gh08n1aYfwYDpd/LmhhZclN4laDYlaNQkaNWJAYvnuRio0Mk1GETlcBU4QRYyiSE0wyBVf7keztR0ByE00IQoC5S1O/vBhMY9fM3HAY9kdLh/lGLTE9CLwRtqnC1Os6NSndynzdMMDeemcFWfpo+4M8LcrxnLx2FTmfYOySoPhTABzEuAMhigLy3RHvFis8QaSJyXy8me7MejhjUsm4Gh04/cG8XuC+L2h8O8gwYCEKApRwqYY7kTyOPx0t3vxOALUO+zUlrXRkbgZkIltm4xK6p/uValF4jPMJGVZFA5ElgWdUU3AFyLgDxH0hQj6JVoOdrNig8IPidNkoVGdmFz3UOKOzCSer29nU5eLe8vrWdvpRCcKPDw6k5vW1LO8uJn7Pyxmd10XFp2a/72gkASTFovFgsPhIC8vj8svvxy9/sTaQv3eYLhEqPBF/B0eTAboIsR9f9hARlswuu141OCH/Rsa++xDEMA+Kx4IclaiNRq8AHwebp9eWJR8zNL6/78jXqvmsuRY/tPYgV4UolyYzDgjZxcls7y4mQSzLuogXGQ2QHNn1AE6gsJUK1+Ut/FCp53ffGWPBkTnJ9j4YWoC73xZzQseD6FkA9LYOApzZJbNyCfBouMHr2xnXVkbt724lfsuGc3107MPe8wRAu+p5r9EMDPGzN9pZqPd1YcHE5NpwadL4oBW5kDHAITmGAFQthU7fKiqnThavXQbVDArGSleT/74JH4zIZu5+YmUNHVz8WPr+Wh3I1dObh2QcxEpH421HCpgd3L5L99mqEWhT3AegU6t4txRKQO84puHIQ9gfv/733Pffff1eaygoID9+xWaotfr5X/+53947bXX8Pl8LFq0iCeeeILk5J4VS01NDXfccQerVq3CbDZz44038uCDD/ZTSz1dsdvhQQbSdZo+zrK7IjoUKRbGzDw+hn/AF6KzyUVHg4u9+/bQXqdMmqphTYwdNguDOcyHsGixJhiITTUelTaHJt5HYJsdZAgeTOC9v+/gwh+OxWQ7uYGMx+nH5w4qAZU3hN+r/C1LMrEpJmJTjaTptVyVEsfLje38q04x6ftxVjLzMuK4cEQSu/a2sW1VLVNkNedkJFDy4UF87iDp4iRcBjvWjmGser4MlUZErRGjv9VaFRqdKvxb+V8Kybi7/EopsNun/N3tx2X34XMH+x1/1gwTJVk6KpI1DHdDfLqZ+DQTH5e1UN3hZn5BIlNz45VSnwiZRXFcUV8HrmCf9mlZlnu1T59e4nXfFHw/M4n/ttg5J96KplcAeMf84aw+0Mr5o3uI4yPDrcOHdiLFJBrwT09kr14GCabbTPxmeBoGV5DvP7uF2g4PaiBjegoHbSr2WASe6OjkwfgMnr1pCr9+dw9vbK3jt+/tpa7TzS8WFQ4YjMqyHM3A9F4hB0MSm6P8l8PrCJ0oJllNaAWBJn+AKo+fHIOWJ2tb+VtXJ+hUCI4Avx+ThUeQWVHeyo4WB2hV6E0aRpv1jAuqUGk0tKVqaLP4sLsDCH6RHQaZlkwDE3LjEEWBUWk2bpqZw7NfVnHv+3v57Cdz+7VDRwKYwTqQTlYp7Qy+2TgpEcGoUaOi2hlAn8Djpz/9KR999BFvvvkmNpuNH/3oR1x22WV8+eWXAIRCIS688EJSUlLYsGEDjY2N3HDDDWg0Gv70pz+djMMdcuwYTP8lvJoYl3n8N6NGpwp3kVjZUb06+nir+yA5M88hIyPjuPYbOf/5wwvxuS201jh46y9buehH44hP60sw9HQrk7osy4gqMZotUtp9RYxW7YA6MBF4nH4ObG6mdFMTrTWHb1kVRIGYZCPjso28mgWSAMkhgZyPmni+tpyiLj9F9ARZgb1d7O1l2QBWahm6jgqtXoU5Tq/opsTpOTdJpAQ33VPjuOVHI6IT5IF1Gl77qASdLsj3F/WsxA96fBQf8KIS6ON0u7e+m8YuLwaNalDn7DM4PApMenbPHIX+kIB9QlYs2397DsZek2ZEx6fC7cMTkjCoRD5qtfMXpx3ZrEH0hXhhUh5nJ1h5Z3s9v3p3D76gRGacgb9cNpaZeQk8U9fKb8vqeamhnQZvgGWjs/nLkrFkxBr5+4oDPL2mkvpOD3+/cny/VuhKj48mfwCtIDCpl+HkvoZuHL4gVr2akWknl1htCPNgNnW5WN7WxZYwSRkgpsOPZ1sbluRk1u9tZF9ZG1rghhnZ/OackYO2dvskiYVbSsNiak08OEIZj+4+dwQf72nkYLubJ1aVc/e5fcUxewKYHv6LLMs9GZgzAcwZDICTEsCo1WpSUvqnqLq6uvj3v//Nq6++yllnnQXAc889R1FREZs2bWL69OksX76c4uJiPv/8c5KTkxk/fjz3338/v/jFL/j973+PVjtwF4zP58Pn80X/j/jXDDXe3F7Lh61djFdridFrsOg1mHVqrHo1KTY9uYnmqJ7B+ENWExEhraEQpvL5fFRUKJ0VmZmZ1NbW8sknn3DLLbccUdvkUOzatYvi4mIAzl60AP35Fj78527szW7eeWgbGUVxUa0QV5dfae0+DHRGNYlZFpKHWUkapgRbBquGg3vaKd3URPWeNqRQzz40OhUavZIN0erVaHQqZFmmo9GFzxWks9EFjS4m+o1sz9WxcF03Tc092RC/XqRBCjB5RAKpiSZ0BjU6oxqdUYNaIxIMSISCEqGARDAQIhiQCPolguESWsAfIuBT/hdEAaNVi9GmxWjVYrJqMVi1mGxKwKIz9L1lRnj9/GNjMbvdHrqCoWj9fk5+IlDCV1XteAOh6Ipzedj7aKrN1Eesa0U4+zJ3RMKQinX9/wbTIDyJQ1VGE7Vq4jVq2gNBSpwePm7r4p9hvQxVpw/1zg5yJhZw7/v7oi7ECwoSeeSqCdiMSlb11oxE0nUaflB8kJUd3TxY2cgD+RncuTCf9BgDv3h7Nx/ubiQvycxPzh7R5/0j2ZdJNiOGXgFXxD5gak78KdHmmBFjZlOXi99XNACgEQTuz0+nYmsjL0kyv3p3DwB6jcifLxvL4gmHJ7XqRJE/j8jg8p0VPF/fxpUpcUywGjHr1Pzu4pHc8cp2nlxTwSUT0hkeVjtu8wep8yp8vN4lpIPtbhzeIFq1yIhvgAbLGZx6nJQApqysjLS0NPR6PTNmzODBBx8kKyuLbdu2EQgEOPvss6PbFhYWkpWVxcaNG5k+fTobN25kzJgxfUpKixYt4o477mDfvn19XIN748EHH+xXujoZ+F1rGx1agZV7W1HXu6OPxwsuslSd/HDpRT0KvIe0A0YzMEMQwJSVlREMBomNjeXKK6/kscceo76+nj179kSdlI8En8/Hxx9/zK5duwD6nPclP5/Ex0/uprG8i8odfbVgBAEMVi2iKERbfKWQhCTJhAISPneQuv2d1O3v8TFSqcU+Zn+JWRYKZ6SSPyUJwyCt2bKslHPa6py01zsZXufAvi9AamEy8QvNJGSYiUszodKq8AZCmL4GKex0vZZ8o44yt491nU4uTooBYESymRSrnqZuL1uqO8IBDXw2iPpuxD7gnJHfjtr06YaDu3eSmD0Moy0GULr3Rpr1rOt0cuPeKlr9SkD8vcxEtuyppNgvsfRfm2h1KIuiuxbmc9fC/H7loPMTY3hmtMi1uyt5ob6d2zISyTboWDIpA5Uo8JPXd7JsbSXXTssm0dKTKVwf5r/Miuk7MZ8q/ksEM2PMPHxQufbSdRr+NXoYE60mPmoP8NJGhQCfk2Diyesm9lO0HgyzYy1RcbhflNbyyeQRqASB80anRMXhfvveXl65dRqCILA7PF4ON+iw9ApAd4cJvEWp1pMi5ncG33wM+Yg/bdo0nn/+eQoKCmhsbOS+++5jzpw57N27l6amJrRaLTExMX1ek5ycTFOTYgPe1NTUJ3iJPB95bjD88pe/5O67747+393dTWbm0Msjz7eZecfjwlIYy4J4Gy5vEKfHR17rbgz4eG3FGmrHKa7DvQWZDra76fIE0KrEIWldKylRRM5GjhyJxWJhzpw5rFy5ks8//5zCwkJ0usNzVxobG3nrrbdob29HEATmzZvH3Llzo8/rTRouuWsCpZubCPolzDE6TOEfo1UzoKYIQCgk0VHvouVgN83V3bRUO+hocBIKShisWgqmJlM4I5X4o9CCEQQh+p7Zow8/oH8dwUsEC+KslLlbWd3RHQ1gBEFgTn4Cb26rY11ZG3PyE7EHgmwcxLyxpLEbUeC0M2/8NqB65zbefvB3ZI+dwOW/vj/6+EiTgXWdTlr9QYwqkb8XZLI4OZb/SWmjuKGbVocPq17NI1eP56zCwbuKFsZbmR9rYXWngwcrG3lq1DAALhmfxnNfVrGrrotHV5Zx/2LFk0mWZTYMIGAXCElsqT65+i+HYmqMidkxZmwaFQ+NyCReq9xH8woSmZAVw7B4E/ddMqqfJs6R8Lu8NFa0d7Pb6eG5+jZuDQvE3fed0Wx4eA0bKtp5f2cDiyekRwOYcYeU3KP6L2fKR2cwCIZ81D///POjf48dO5Zp06aRnZ3NG2+8gcFw8qy6dTrdESftocCfJuXwyYZiOtUS15yfz+xYC1u3buXDD5WVmldQOB3DDTpsvUoEkfJRUdqJryYCgQBlZYoJV0RNdvr06Wzfvp3Ozk7Wr1/PwoULB3ytLMts3ryZ5cuXEwqFsFgsLFmyhGHDhvXbVqURGTnr2MjGKpUY7XYaNUdJNwd8IbrbPcQmGwcNfL7JmB9nYVldK6s7HH26OeaMSOTNbXWsPdDKry4o4osOByFZ4WoM62XeuLIkYt4YR9xpbBb3TUXNPqW7rmbPLjxOBwazsoCYHmPi6bpWcg06nh0zjMJw59K0nDje3l5HUaqVp66bSHb8kSUAfjM8lTVbHbzXYuf7mW7GW40IgsD/nl/E0n9t4j+ba/ju7BxyEkyUur20BYIYRCHapQiwu86O2x8i1qiJiuqdbOhEkbcm5PV73KxT8+4PZh33fhO1Gn6Vm8ovDtTx58pGLkqMIUWnISveyJ0L8/nrZ6U88FExCwqSogq84/op8NqBMx1IZzA4TvpsEhMTw4gRIygvLyclJQW/34/dbu+zTXNzc5Qzk5KSQnNzc7/nI8993YjRqLkqVRG4WlbbSjAYjHrryAjYrUqadTAC7/ghuBkrKirw+/1YrVbS05UgQaPRcO655wKKWWFnZ2e/1zU2NvLqq6/yySefEAqFGDFiBN///vcHDF6GEhqdivg087cyeAHFhE8nCtT7ApS5e3hYs/MSEATY3+Sgpds7qHnjiiE2bzyDvmiqUIJ9WZao3rkt+vh5CTY+mzyCz6cURIMXgMsnZfD+D2fx3g9nHlXwAjDaYmRJ2HD0gYoG5LAB4Izh8SwoSCQoyfz1M6UTM8J/mWIzoevFV4uUj6bnxn8r2uivT4tnotWIMyTxx8qG6OO3zcklL8lMm9PPP1aWDdiBJEkye+sVvtjJUuA9g28+TvqM4nQ6qaioIDU1lUmTJqHRaFi5cmX0+dLSUmpqapgxYwYAM2bMYM+ePbS09Mj1r1ixAqvVysiRI0/24R4Vbs1QukRWtHfz0bYddHV1YTabGTttLq0WZRDLPYRMuHsICbyR8lFRUVEfP6HCwkJycnIIhUIsX74cUDIuZWVlvPDCCzz99NOUlZWhUqk477zzWLp0KSbT8QnMnUEPjCqRaWEl1dUdPeTxOJM22j2x8kArX7Qrzy1K6OESdHkCUd+Zs88EMEMOWZJoriyP/l+xbXP0b0EQGGcxYjwksBZFxerjWIXTfp6TglYQWG93Ro06AX5xfiGCAB/vaWJ9dTuvNyrfd2/+S6fLz3s7lUn+VPFfTjZEQeCP+UoX0jvNndR4lOBeqxb57UXKWP7KjjoafAEEYIy5J4isanfh9Cnmm3mJR2c9cgb//2HIA5if/exnrFmzhurqajZs2MCll16KSqVi6dKl2Gw2brnlFu6++25WrVrFtm3buPnmm5kxYwbTp08H4Nxzz2XkyJFcf/317Nq1i88++4zf/OY3/PCHPzwlJaKjQZ5Rz8I4KzLwdLXCy5kzZw4XL5xFSziAqdl5ILp9MCRFFSVPpIUaIBgMUlpaCtDPjFAQBM477zwEQaCkpISVK1fyxBNP8Morr1BVVYUgCIwePZrbb7+d6dOnH9FM8QyOHvPjlKBk9SHCX3PD5N0XGtpwhiSStOo+5O5/ra0kKMnkJZnJSTgTTA41Opsa8Ht6yPbVu7YRCvbX8xkKZBl03Bxe3DxQ0UAonIUpTLGyZGIGskbg5pKD7HZ6sKhEFifHANDi8HL1sk2UtziJM2k571siMgaKkOe8WAshGZ6s7WkGmJufwJh0G26jMgXlGXV9Osj2hDPWo9JsJ1WN+Ay+2RjyK6Ouro6lS5dSUFDAlVdeSXx8PJs2bSIxURnIH374YS666CKWLFnC3LlzSUlJ4Z133om+XqVS8eGHH6JSqZgxYwbXXXcdN9xwA3/4wx+G+lBPCLdnKp9nd3wqmphYJk6cSKsEHq0OQZaQ92/HE+5sKGtx4g1ImHVqchNObDVRXV2N1+vFZDKRlZXV7/nk5GQmT54MwLp162htbUWr1TJjxgzuuusuLr/88n4k6TM4cSyIU1bTG+1OvKGebqs5+QlINg07w7HJT4elIIYDx3VlrTy+WskO3LUw/9Qe8EmGLEkEA4Ejb3iSESkfpeYVYLBY8blcNBwYOpfvQ3FXdjJWtUixy8vbzT1l3Bvn5xKYkohDL2IWBN6ekEe2QUe93cOVT22ktNlBkkXH67dPJ2kQv6BvKn6crRDT/9PYTqtfuSYEQeCO+cORbQrna5TpUP7LGf2XMzgyhpzE+9prrx32eb1ez+OPP87jjz8+6DbZ2dl8/PHHQ31oQ4oZZh3xHiftBjPuKbPRaDTsDHN7Yl0O4iQn//l8M9+9YGa0fDQ63XrCte2IXkthYeGgei8LFiygvLycUCjEtGnTmDRp0gnL6J/B4VFo0pOi1dDkD7C5y8XccEAzPN1KcFw8iAJzzEZuCps+tnR7+clrO5FlWDo1i4vHHZ8y8+mGoN/P7pWfsfm9N0AQuPZPf8cSd2Rhvj1fLEdUqRg1b2Dy+fGiqULJhKbkjyA2LZ3itV9QuX0LmSPHDOn7RBCnUfPjrGT+WNnIXyob+U5iDB2BIN+vqEOyaMAXIq3Kzai5BqraXFz3zFfU2z2kxxh49bZpR825+SZhVoyZCRYjOxxunqlr45e5ikHkolEp6MvrcAL+tr6KyGcUeM/gaHAmN3ec2L59O6NqlNXdZ4KeoCRHBezSwkJve7dvRpZldkUVeGNO6D0lSYpaMhyOD2Q0Grnzzju5++67mTVr1png5RRAEATmhYOWVWEejCzL/PxAHZJBheAOMt0pIAgCIUnmrtd20u7yU5hi4XcXnx7crhNBKBhg14qP+fdPbmfV80/jsnfi6uxg3asvHPG1VTu3sfzpR/n0iYc5uHvnkB5XJAOTkptP7sSpQF8ezMnArRmJpOk01PsCPFDZwCU7yqnw+EjTaojfZafmYDd//ayUK5/eSL3dQ26iibfumDFo8LJ39ed8/u8nCfi8Az5/ukMQBO4MZ2Geq2/FEXauVokCYqySgdm2pxlf+PHQGQLvGRwlzgQwxwG/38+6desY0VKLVZCp8wX4rL0rKmD3nYJhSLKANWjns83F0QzMiQrY1dTU4Ha70ev1R+wcOsNvOfWYHw5gIjyYf9e38XFbFypAs6uDzQcUH6dHV5axsbIdo1bF49dO/EYr74aCQfZ8sZxnf/I9Pn/mCZztbZjjE5i+5GoQBErWrTpsySbo9/PFs09F/1/xzD+HbKIOBYO0VlUCkDw8n2HjJiKqVHQ21NHZWD8k7zEQDCqRe3IUHsszdW3UehWfof9OyucnM3IAeGpNBa0OH4UpFt743gxSbQNLTHS3trBi2T/ZtfwjNr71n5N2zCcbixJs5Bt1dAclnq9X7oMmX4BuWQZZxt7k5t3tyndS0erEEwhh1KrIPUPgPYPD4EwAcxzYunUrLpeLBKuVGzOUlcXTta3RdsCz0pMgTuGnrFy9lv2NyoR2oquJ3uUjleqbO+l9WzE31oIAlLi8LG/r4r5ypavkrrRExO4A22s6WVHczKNfKFmBP106Jiqn/k3FBw//meVPP0p3awum2DjOuvl73PLIMmZdeR2j5yuK26ueX4YsSQO+fst/38be3Ig5Ng5zfAJdzU1sePPVITm29roaggE/WoORuNR0dEYjGUWKmFzl9q1D8h6D4cqUOArDhpEFJj3vTcgnQ6/l+hnZUUfscZkxvHb7dBLMgzcnfPXuG0ghhUu39cN3aamuPKnHfbIgCgI/ylK4d8vqWvGGpKiAXbKgQgjJPL22kpAkRwm8o9NsQ26nUL+/mK/ee/OkEbnP4NTiTABzjPD7/axfvx6AuXPn8t3MRNQCbO5y0R2U0IsCBSYD31m0AACjuxmj7CHepI0OXMcDSZL6tE+fwemHeK06qr58y95qArLMBQk27hmRRlackUBI5gevbEOW4arJmUf0lTnd0VZTTcXWTQiiyLzrb+GWR//FhPMuRh32K5t99Q1oDQaaKsooXreq3+vtzU1sfu9NAObdcCtn33IHANs+eq9P6/PxIlI+Ss7NQwjzxSJlpMrtJ7eMpBIEXhyTw73D03h3Qh7JOkXJVq9R8cJ3p/KbC4t45dZpxBgHFy7samlm7+oVACQNG44sSSx/+jEkKXRSj/1k4bLkWNJ1Glr9QV5v6ohmrGcnWokxaqhqc/HJ3sZox+ZQC9jJksSHjz7E+v+8wM7PPhzSfZ/B14MzAcwxYsuWLbjdbmJjYxk3bhypOi3fSYqNPj/abEAjCkwuHIbLkIQgwChVE2MzbCdU1qmvr8fhcKDVasnNzR2Kj3IGJwELwu3UAVkmU6/l4cJMBEFg7v9r7z7Do6rWBgw/M5NJ752QRugkgdAJHYEggggooqAgFqzH3lBE8BwOlk+s2PWgKArYKAJKr6GF0AKEJCQESCe9TV3fjyEDQxKSQCqsm2uuGfZeu7zZk8w7a6/SwdSQVWcQdPRxYu640KY8zXpxeON6ANr27EuvsRNQW1vWJDi4utFv4j0A7Fi62KI7sxCCLYu/RK/TEhgeQcfIQbTt2ZcOkYMufVAbru+DOrOi/UvbSz28Qnr2BuDciWNoSkuua/8VTu7axk+vPVcp6Qq0s+GJQG+LSTsB2nk78vCgkEoTTF5pz+/LMBoMBIZHMOHVN7GxdyDzdAKx61bXy3k3NrVSweOBphrrRalZHCwwvR96uDowPTIYgM+3Jl026W39JjDn449TfMF0+2rvH8st3o9SyyQTmDoQQpjHYBkyZIj5Nk7FwHZgOQLvwAGmobjbqXII976+IeIral86dOiAWl23eUmkxlPRnVqtUPBlaJB5OomhHUx/uO3UKhZN7Y6ddcu+BajTlHPiYq1KtxG3Vluu++hxuPq2oiQ/j71/LDcvTzqwl9MH96NUWTH8wcfMyf0tD8zExsGBrJQkYtauvK5zzKgigXHz9cPdzx+jwUDK4djr2j+Ykpe1n7xPRlICe35fdt37q5CfkU7cto0A9J80FUc3dwbfNwOAncuWUJCVebXNm60prTxwV6tILdeyNc90az3CyZ4H+gdjb60iLq2Q2NR8oP57IJ3cvcP8uqyokJi/ru/9JTU9mcDUgUKh4IEHHmDSpEmEh1/qhtnD2YF+F0dijXS91KZh3ICuFKpcUCkEjheufeyJ3Nxcjh41TWsvbx81b31cHHi7gz9Lurahh/OlXiW3dPJm9pjO/PBQH9p5N848Nw0pfvcONKUluHj7ENS16hniAazUaoZOexgw3RrKz0hHV17O5sVfAtDr9gm4+/mbyzu4ujHk/ocA2L38J/Izq5/A9Wr0Wi05Z1MA8G3bwWJdSM/6uY10au8u1n76PkIYL+5vP2VFhTVsVTt7fl+GMBoJ7taD1h1Nv/Phw6Lw7xyGXqNh47efmacraEnsVUoe8fcy/1+lgC6Odrg5WHNvn0vjWjnZWBFcj13KjQYDp/aYbv2HDRsJwIE1v1NaWFBvx5Aan0xg6kipVBIaGlqpEe03YW1YHNaG2y6b50ahUDD97jsASDsdT0pKSp2PFx8fz1dffUVRURHOzs60b39jDXh2o1EoFDzQ2tM8Mm8FpVLBw4NC6B3s3kRnVr+ObDLdPgq/ZZS5fUl1Qnr0Iahrdwx6Pdt+/JY9fyyjKCcbZy9v+k2cXKl82NCRBIR2Ra/VsOHrT6/pgzor5TRGgwE7J2ecPL0s1oX0MN1GSo49cM3tSZJi9vLXR+8ijEZChwzHO7gtRoOek7u21bjt6dj9rPnoXXLOnqlyfV5GGsd3bAZMtS8VFEolI2c+hcrKipRDMZzcvb3K7cuLi+vt9lhDmNHaE4eLo+t2crDF7uLrhwe1Qa0y1cSF1sOYWZc7G3eUssICbJ2cGfHwE3gHt0VbVsb+Vb/V2zGkxicTmHriaW3FrV6V27l06xhCz549AVi7di2GWt7XNxqNbN68mZ9//pny8nJat27NQw89hLW1nK1YalrZZ5JJT4hHqVKZv81ejUKhYNj0R1AolSTu32P+0Bg2fSZqm8pjFCkUCkY+8iRWamtSjx7i+PbNdT7HzNOXbh9d+Tvp16EzNg4OlBUVkp5wqqrNryr5UAyrFy7AaDDQacAQoh57mtAhtwAQt+3q56rTlLNu0QfE797O0tkvkrB3d6Uye377BWE00iaiJ63ad7RY5+7nT9+LSd+WxV9RVlSIEIKc1BT2/rGcn994iUUP38t3zz5KSX7lCV2bA1e1FQ+0Nt127+Nyqca6lYsdd/Yw1cb1qedEvyLZ69C3PyorNQPvuR+AQ+vXUJSbU6/HkhqPTGAawfDhw7GzsyMrK4t9+2quti4pKeGnn35i+3bTL13v3r2ZMWMGLi5yUCep6VU03m3Xqx8Orm41lDbx8A8kImoMYOoNEtKjN2179a22vFur1vS7614Ati35ts4NLs09kK64fQSgsrKiTYRpuo263kY6c/QQK//vPxj0ejr0HcDoJ59HqVTRaeBQlCoVmacTuHAutdrtj23dSPnF20y68jJWLfwvu5YtMXczz007x4kdWwHL2pfL9bnjLjz8AykrLOC3/87hm389zPcvPcXOX34wjbkjBKUF+Wz/8bs6xdaYXm3Tii+6BPFKG8t5n+aOC+WjeyJ4bGjbejuWQa8jYd8uADr1HwxAcERPWncKRa/Tsue3q48eLzVfMoFpBPb29owYcXFMjC1bKCoqqrbsuXPn+Oqrr0hKSsLKyooJEyYwZswYrKzqfdYHSaozXfmlxrtdR4yu07aRk6bg4OqG2taOYQ88WmOvvF5jJ+DWyo+yokJi19et22tVDXgvV3Eb6fTB/bXe57mTcfz57r8x6HS07dWX255+CeXFW8n2zi606W5KiuK2bapye6PBQMyaPwAYNv0Retxmur285/dl/Pnev9GUlphqX4QpwfNtVzn5AlBZqYl69F+gUJB5OpHC7Eys1NaE9OjNiIefYPzLb4BCwfEdWzh34lit42tMaqWC8T5uuF7RQ0uh09Am5yhWBm29HSvlcCyakhIcXN1o3dnU+0+hUJhrYY5t2UBeRlq9HU9qPDKBaSTdu3endevWaLVa/vnnn0rrhRDs2bOH7777joKCAtzd3XnkkUfo1q1bE5ytVKEoN4efXnuOpW+8SGFOds0b3OBO7t6OtqwUV59WBIZ1rdO2do5OTHv3E2Z88DmuPjXPuKyysiLyTlMtzIHVv6MprV0tjLaslNy0c0D1CUxwRE8UCiU5qSkUZmfVuM/sM8n8+c5b6LUa2kT0ZOyzr6K64ktF6GDTPE4ndmypsm1Nwr7dFGRlYuvkTPjwUQyb/gijn3welVrN6YP7+fHVZzm5y1TrWl3tSwW/Dp0Z9ejTRIway/iX3+CJb5cy4ZU36TbyNtr27EvXW0YBsOm7L667O3pjiv71JzZ8/Sl/f/Fxve0zPtrU+6hD5ECUykttF/07h9EmoidGg4Hdy3+qt+NJjUcmMI1EqVQyZoypCv3o0aMkJyeb15WVlbFs2TLWr1+P0WikU6dOzJw5U84a3cQKc7JZPncWGUkJpJ86yc9vvEh2akpTn1aTOrJxHQDhw2tuvFsVexfXWk3uWKHjgMG4+/lTXlLMwXW16/aaeToRhMDJw6vaW1x2jk74XezdkxSz96r7K8jK4LcFb6IpLaF1py7c/sJrWFUxlEGbHr2xdXSiOC+X1CvmdBJCmNv+dB811tz2p8vgW7hn3rs4eniSn5mOEEba9uqHT0i7GuMMGzaS4Q8+RtuefSu1JRp47zRsHZ3ISU1pUYO2VdSIndqzk/Mnj1/3/nRaDYn79wCXbh9dbsA90wBTYp59JrnSeql5kwlMI/Lz86N3b1PVdUWD3nPnzvHll19y8uRJlEolo0ePZvLkyXICxiZWkJXJ8nmvkp+Zjou3Dx7+gRTnXuCXOS+TeuxIU59ek8hMTiIjKQGlyso8TUBDUypVRF5sCxOz5k/KS4pr3Kam20cVKtrgbP/xfxzesLbK3k6lF9uZlOTl4hkQxPiX5lQasK+ClVpNpwFDAIi7ouHx2bgjZJ5OxMrahohRYyzW+bZtz/0LPiSoa3fsnF0YOPm+GmOsiZ2TM4PunQ7AruU/NdsGvZfLz0gnL/3SrZytS76pdgqK2kqOPYCuvAwnTy9ate9Uab1Pm7Z0iBwEQrBz2ZLrOpbU+GQC08huueUW7O3tyc7O5ueff+a7774jPz8fNzc3HnroIfr27SsnYmxi+ZkZLJv3KgVZmbj6tuLuN9/mnnnv0rpTKNqyUn5fMKdW3WVvNBW1L+37RGLv4tpox+0QORAP/0A0pSUcrMXgdhkXR8StqRYjYuRtBHXtjl6nZeM3n7Hy/+ZbjAtiutZzyUtPw9nLmztfewtbx6vPXRU6xHQbKXFftEVX5oral7BhI7F3rtwY397Flbte/zePffkDnoHBNcZYG2G3jMQnpD3astJm3aC3QsrhgwB4BgajtrUjI/HUdf+exV+8JdcxclC1f1cH3H0fCqWS0zH7OBt3c345aalkAtPI7OzsGDnS1PU0MTERo9FIly5dePTRR2ndumXPjXMjyEs/z7J5r1KUk41bq9bc/eYCnD29sHV05K7X/02HfgMx6PX89fF7HFj9e4scTOxaaMtKObHT9GFS18a710upVNF/0hQAYv5aSVlx9Y3gATKTTF2jrxzA7kpqW1vunDWPodMeRmVlRdKBPfzw8r84c/QQBr2Ole//l8zTCdg5OXPna//G0d2jxnP1CWmHh38gep2W+GjTwGlZKadJOXwQhUJJr7Hja4y1viiVKtP8Us28QW+F5MMxgOlWT9/xkwDY/vP31zw7ubaslNOxB8z7rI67X2u6DjeNJr3puy/kRI8tiExgmkC3bt1o164dVlZW3HbbbUyaNEneMmpCBr2O0sIC0k6dZPm8WRRfyMG9dQCT575t0V7Dytqasc+8bO49su3H79i25JtGT2LKi4uvu2q9rk7u2o6uvAy3Vq0JCA2veYN61r5Pf7wCg9GWlRKz5s9qy5UWFpiH2fdpW3M7EoVSSc8x45kyfyHufv6U5OXy6/w3+GnWc6QePYTaxpaJr87F3a92Xy4UCgVdBpvGhDm+3dQb6cDq3wFTTZKLd82Nl+uTb7sOhN8SBdStQW9+ZgbfPTuTxS88wY6li0lPiG/Q95xBr+PsxVuzwRE96THmDpw8vSi+kHPNQ/4nxexDr9Xg6tsK7zZX75Y98J5p2Dm7cOFcaq1q+aTmQfbNbQJKpZIpU6ZgNBpl9+hGlpVymoNrV5GRdApNSTHlpSXoNRqLMp4BQUx6Y36Vt0kUSiXDpj+Ck4cn25Z8S8xfK1GqrBg05YFGufV3fMcW1i1aiFdAEP3uvIf2ffpfU2Paukg7dcLcPqDr8FFNcotToVQSefdUVv3ffA6uW0WP28ZVeSumYkJFt1Z+2Dpc/XbP5byDQ7jv7Q/ZtuRbDm9YR3ZqCkqVFeNefL3a7szV6TJoGDt//oHzJ4+TeuyweRC13rdPrNN+6svAe6aRsHe3qUHvP3/RY/S4q5bXlpXy57tvmdujXDiXyr6Vv+Lg5k7bHn1o27svgWERVTZkvlbnT55ApynH3sUV76A2KJRKBk15gLUfv8e+P1cQNmwkjm51G9yu4ufeqf/gGt+zto6ODJ46g78//5Ddvy6lY//BOF8xgrPU/MgamCaiVCpl8tJIhBAkxx5gxX9ms+SVp4nbtpEL51Ipzsu1SF6s7ewJ6tqdSXP+W2Mbj15jJzBy5lOAqX3Dnt8bfjCssqJCtiz+CoQgOzWF1R+8zfcvPcXJXduueUj8mpzYtY3lb71GWWEB3sFtCR9e/cSNDa1dr354B7dFV17GgYvjqVwp4+LtI5+Quk+5obaxZcTDTzLuxdcJ6BLO2OdeIfgq8zxVx9Hdg6CuEQCsXrgAYTQSGNatVj2LGoK9swsDL/a22fHz95y5oofU5YTRyNpPF3LhXCoOrm5EPfY0HSIHYW1nR0leLkc2reePt+fx+SNTWbdoIacP7seg1133OaZcvH0U3K2HOSHv1H8wrdp3RKcpZ9eyH+u0v/LiYlIOmdrUdLzK7aMKcRfiSPArwrN9O/QaDVt/+LqOEUhNQX6CSjcsvU7HiR1biPnrT/PoqAqlkg59BxA6ZDj2rm7YOjhgY++Itb1dndsfdB1+K7py0x+73ct/Qm1jS6+xExoiFAB2/vwD5cVFeAYE0b5vfw6uXcWFc6n89fF77P71Z/pNuJtOA4fUSzsKIQTRv/5M9K9LAWjbqx+3/esFrG3trnvf10qhUND/7qn8+e5bHFq/hl5jxldKNC/1QKpbrcnl2veOpH3vyOs5VboMGU7K4YPmXlO9x915Xfu7XuHDo0g6sIfkQzH88c5cxjzzMu379K9UbvevS0k6sAeVlRXjXngdvw6dCB8WhV6n49zxoyQe2EvSgT0U517g+PbNHN++GRsHB9r1jqRj5CCCwiPMg/vVRcqhiwlMRE/zMoVCwdBpD/PzGy9xbOsGut86Fu/gkFrtL3F/NEaDHs+AIDwDgqotV64v5+PYj/nx+I8IBK4+au5I9CNh7242bV3O0MF3oqrh90kIQXHuBS6cP0te2jk8/AMJDLMcvyujxDQpqa9D495CvNHJBEZqdoxGA3lp53FvHXDNtyuE0chv898wN1y0trMj/JYoeoy+A2cv73o7155j7rj4DXEJ25Z8i9rGhm4jb6u3/VfISDzFkc1/AzD8ocfx7xxGj9vuIHb9ag7+tZK8tHOsW7SQpIP7GfOvF6/pQ6SCXqvl7y8+MvcA6XX7RAZNmV6vDUyvVUiP3vi2bU9GUgLrP/uA9v0G4NE6AHe/AGwdHc23kGrqQt3Q2vXuh7WdPdqyUryC2lx1xu7GoFSqGPfibNZ+8h4Je3ezeuHbjHr8GXOvKYD46J3mYfVHzvwXfh0udTu2UqsJ7taD4G49GD7jUdJOnSQ+egen9uykJD+PuK0bidu6Ea/AYEY9/mydapuKcy+YxldSKAgKj7BY59ehMx0jBxEfvYNtS77hrtnza/ybUFqQz76VvwKm3kfVOZJ9hNd3vk5KYYqprFtHEhWJxAUXEpbszPbvv+Wt859wS8gIZobPpJVjK8DUXuf4ji2cizvKhfPnyE07h668zLxfhVLJ/W9/hFdQGzJLMvk49mNWJ61GIAj1CCUqOIqRQSMJcAqo9c+oIRVqC0kuSCa5IJnc8lz6+PYh1CO0RfSGVYgbtBtFYWEhLi4uFBQU4OzsXPMGUrMgjEZWvj+fpAN7CQzrxshHnsLVt1Wd93Nk099s+OoT1LZ2RN51L12Hj8LG3qEBztj0DWznz9+b/mgqFIx+4jlzQ876YDQaWPr6i2SeTqDLoGGMfuoFi/Wa0lIO/b2G3SuWYjTo6dh/MLc99cI1JTGlhQWsfO8/pJ06gVKlYvhDT9B1+Kj6CqVeJB+K4fcFb1Zabu/iSmlBPgqFkn8tXo66iRvGb//pf+xf/Tt3vDibdleZ96kxGQ0GNnz9Kce2bABg2AMz6TF6HFkpp/l5zkvoNRp6jhnP0GkP125/RgNpJ09wMnoH8bu2UV5SjEKppM8dk+h35z21aidzbMsG/v7iI3zbdWDq/IWV1hdkZfK/5x/DoNNxy4OP0X3U2Gr3VVZcxIp5s8hOTcHRw5P7/vtBpcEMtQYtnx/+nO+OfYdRGPG282Zu/7kM8h9EgaaAbac3c/K971GV6Iltn8/h9gVYK62Z0uEeBhV04PCqlZVGb1Yolbj6+oEwkpeehk+79hTc1Y7FcYspN5h6USkVSoziUkPozu6diQqO4rY2t+Hn6Ffjz+l6CSFILUolNiuWYznHOF1wmuSCZHLKKk9m2dqxNaOCRzEqeBSd3TubkxmdUUdiXiJHc45yLOcYR3OOMn/gfLp4dKnXc63t57dMYKRmJfq3ny2G9baytqH/pCn0HDO+1h/I5cXFfPfsTMqKChk67WF6jhnfQGd7iRCCLYu/Inb9ahQKJWOffZkO/QbWy76PbFzPhq8/xdrOngc//LLa0WUTD+y9OEuynk4DhjD6qefrVGtSWljA8nmzuHAuFRsHB8Y9/1qlqvDmIj56J+dPxnHh/Flyz5+lOPeCeV2r9h2Z8p/3m/DsTIxGA+XFxVU2Nm5KQgi2LfnG3Lun97g7iY/eQWF2FkFduzPx1bnXlvwW5LPpuy84tcfUfdzDP5BRjz9DiYcKa5U1rRxaoVZVTmhWf/gOp6J34DeyPwW93UkpTMHNxo1WDq1o5diKVg6tyPgnmsMrTecbMWoMQ6c9UmkqB01pCSv+PZvM0wk4uLoxee7buLUy9R4r15eTUphCUn4S3x77loQ8063GsSFjebXPq7jYWF6j+OgdrPnwHRRWKhLucCU9IZ5uiS44l5rO397Vla7DR+Md1Ab31gG4+vqislJTeCGbb56bidDoiA69QHxQMd29u/NSr5do5diKzamb+efMP+zP2G9OZpQKJcMChjG181R6+fSqt5oPg9HA0ZyjHMw6yKGsQxzOPkxueW6VZb3tvWnj0gY7Kzv2pu+lTH+pRinQKZBevr1ILkjmxIUT5oSswuy+s5ncaXK9nHMFmcA0UAJTlJuDpqQEYTRiNBgwGg3m12pbO7yDQ1pE1VtzlHwoht/fngtCMPCeaaQeO2Qe9da7TVuiHn0anxq6Q4Kpu+ihv9fg4R/I/e98XOkPXUMRRiP/fPUJx7ZswEptzT3/fq9W53s1pYUF/O+5xygvLjJ/W76ahP3RrPngbYwGA10GDWPUE8/WKonRlJay4t+vk3k6AUd3D+6a/R88WjePKu7a0JaVknv+HPlZGfh16NwgPUiEEORr8nG2dq6xXURzJIQw/20SQrDn918sviy4tfJjyn8W1jhYX01O7d3Fpm8/p7QgH6GAY20KONQ+H2GlxMfeh9aOrfF38sfTzpPkvNP4/C8Ra52CvyIzyHbTVL1TAT1PexAebzo3n44dmfjiHHNyqCsv59f/ziEt/jjWjg60fngsiVbp5lsjacVpCC591LnbujOn3xyGBw2v+nBC8Ov8N0g9egilygqjwTQ2TJm1gaMhBeR3diCq3a2U6ErI1+RToCkgX5NPTlkO3id19Dvujk4tCH/5YW4LH1/pMyG3PJfNqZtZl7yOfRmXZkTv6NaRqZ2nclvIbdioqh7xuSbxufGsOb2GtafXklVmWVNkrbQm1DOUCK8I2ru1p41LG4Kdg3FQO5CZlMD5+OPYuruSZJPF1oJotp/fgcZgeU2c1E6EeYYR5hlGuGc4Ed4RuNnWblb62pIJTAMlMGs+fMc8OVhVvAKD6Tl2Ap0GDEZlVX/dDG90BVkZ/Pjqs5SXFNN1xK2MfOQphBDEbd3ItiXfmqume42dwIDJ91X7s80+k8ySV55BCCN3zf5PpXvqDc1oNPDnu/8mOfYAzl4+3LfgA+ycrv39989Xn3B00994BQZz39sf1eqbccLe3az+8G2E0UjokOFEPfb0VZMYnVbD7wve5NzxY9g6OXPP3Hfw8G85yUtjiMuJY2HMQvZl7MNJ7USEdwQ9fHrQ06cnoR6hWKus6+U4GoOGzJJMMkoyyCjNMD2XZKAxaPB18KWVQyv8HPzwdTS9trOqvlG13qjnZO5J9mfsZ3/Gfg5mHcRB7cCkDpO4q8NdeNp5cnDdarYs/hJrO3um/Of9ernuOWU5LNr9AVlrdhOSZrpte95bw4aeGXDFdzuvPGvGRLdCY2Vkz50quniF0s61HYWaQtJL0k2P4nSyy7IRCAIy7Rh02BNrvRKNgwKPe4cQ3qEfBz7/Dl1yFjq1YF2fdHJdKveMcrFxIcQlhFCPUB7p+gjutlfvlp2bdp4fXnoSg16PrZMzvcZOIK2Dgs+Of2lulFsVJysnJh9oiz4tjw6Rg7j92Veuepyk/CR+OvETq5NWm2s33KzdCPcOx0HtgIPaAUe1I/ZqexzVjqaHtaN5uaO1KanbkrqFNafXkJifeOlcrJ3o49uHCK8IIrwj6OLRxeK9WlpYwIkdWzm25R9yzp6xOC9rOzvc/QPRuFuR72IgKDyCHh0HEOQchFLRsB2YZQLTQAnMhq8+JWHfbpQqFQqlEqVKhVJpel2Um2Puluvo5k730ePoOuJWi/EojEYDxRcuUJCdiVJlhV+HTjd9jY1Oq+GXOS+TlZyEb9v2TJ73rsW985L8PDYv/opTFxPHwPAIxj3/Gjb29hb7EUKwbO6rnD8ZR4e+A7j9+VmNGkeF8uJifnztWQoyMwju1oMJr755TQ1g0xPiWfrGiyAEk+e9g3+n0Fpve2rPTtZ89K4piRk6gqiZ/6oy+THo9ax6fz6nD+7H2s6Ou+csaLLuvs3RuaJzfBz7MeuS11VbxlppTVevrgwLGEZUcFS1PU2EEBzLOca6lHUcyT5Cmb6Mcn055YZyNAYN5frySt92a+Jk7YSztbPpYeNsfp1VmsXBrIOU6Eqq3E6tVDMqeBRTOk3Bt9QRGwfH66610hq0/HjiR7468pX5uOONA/DYlIlBp6PHpEm4De7G+eLznCs6R3ZZNu4xhZRtP05In35MeGF2tfvWGXQkFSSx7ew2oo9uInBTAS6lavRKI3nOOrzybdCpjPzTJ5M8dyOdPTrT1asrbV3b0sa5DSGuITUmLFU5c/QQeelpdBk0FGs7098bjUHDb6d+I6UwBVcbV4uHi60Lwc7BFJ/L4KfXnkMYjUx49U1CuveutG9hNJJ4YA85Z89QkpdLXk4m5zOSKcnLxVoDWrWRAgcdRfZ6Chx0FDroKbLXIRSg1itRGxRY6ZWo9QqsDAqK7Q3kOmnR2SsZGjiUMW3GMMh/kEXCIoSgrKiQjMRTxG3dSOKBvebaJSu1NQFhXSnOyyX3XGqVIxK7tfIjuFtPgiN6ENAlvNIkovVFJjBN0AamvLiYwxvXEbt+NSV5pnuNals72nTvRXmRaYTQogs5FqNhegWH0Hf83bTvG9ksenk0NiEEf3/xEXFbN2Ln5Mx9b3+Is2fVvYQS9u1m3acL0WnK8Q5uy8RZcy3ag5zYtY21H7+HlbUNMz74vNr9NIbsM8ksnf0ieq2GfhMnM2Dy/XXa3tRw9wUyTycSOmQ4tz7xXJ3PIT56B399/B7CaMTBzZ0ug28hbOgI3P38zcdY9+lCTu7ahpXamjtfewv/LmF1Ps6NKL88ny+PfMkv8b+gN+pRoGBsyFgej3icQm0hBzMPmh5ZByu1K+ju3d3cANLD1oOE/ATWJ69nXfI6zhWfq/HYtipbfB188XHwwdfeF18HX2ytbMkoySCtOI30knTSitMo1ZfWuC8nayd6+fSil08vevr2JKUghaUnl3Ik+9KcP+Ge4YwJGUOYZxgd3Tpia1Xzh1J+eT4phSkkFySTUpjCmcIzHM05Slap6ZZFmEcYr/R5hQjvCHODeoVSyd1z/ot/50vvsaWvv0B6YjxRjz1N+LCoGo9b4Wx2Mqs+XEB5ommwPaNKgdOUAfTqNYIwz7BaxdDQti75lpg1f+Ds5c0D//eZRaPy8yePs+X7r8y95uqTtb093kEheAYG4+7XmtLCAvNEmfmZaWhKLJNan5D2hA0bSacBg81ftg16PXnp58k+k0x2agrpp06SduqExWeXSq3Gv3MYvW6feE3jJV2NTGCasBGvXqcjfvd2Dqz+vVK1HIBSZYWzlxcl+fnm7ndufv70ueMuOg8c2mhtNpqDI5vWs+GrT1EolNz5+ls13vLJSErg97fnUlZYgIuPL3fOmodbq9Zoy0r533OPUZyXy4DJ99NvYv02KrsWJ3ZsYe2npsakd7z0Rq16ogghSDl8kF3LlpB5OhEbewdmfPBFtQ13a3Jqz042fvMZZUWF5mV+HToTOnQEmacTOLJxPUqVijteml3lt8SbTWphKsvjl/N7wu8U6UxzLkW2iuS5ns/R2aNzpfJCCFIKU9idtpu/U/4mNivWvE6BAl8HX9JL0s3L7KzsGBowlKH+Q3G1dcVWZYutlS22KltsrGxwVDvibO1cY62sEIJCbSEXyi5QqC2kUFtIgabA/NpJ7UQv3160d21fZXuduJw4lp5cyrrkdeiMl263qBQq2rm2I9QzlC7uXVAqlWSVZpFVmkVmSSaZpaZHkbbq+ai87bx5tuezjAkZY77NIIRg3aKFnNixBUc3d+5/52PsXVwpKyrks0emghDM/HyxxbQdtWE0Gti9fCkJ+3ZzywOPmgcPbC605WUsfuEJinKy6T3uTgZPnUFhTjY7li42D1FgbWdPh34DcHT3xNHNHUd3dxxc3bF3caW8uIi89PPkpaddfD5PQVYmCoUCta0tals7rG3tsLa1RWmlpiAzndy0c7WaLsLJ04v2vSMJGzYSr6A2tYpHU1pKatxhUmJjSD4cQ1FONgC3P/dqvXVYqCATmGbQC0kIwZkjsWQmJ+Hk4YmzlzcuXj44urmjUCopKy4idt0qYtetNg945ezlTZfBw7Gxt8dKbY1KrTY9rNQYL87ZU1pYQGlBAaWF+ZQVFqC2tcOnTVu827TFJ6Qdrt6+VQ4vL4RAr9Wg1+kQBsPFRshGhNH07OTuiZV1/dzLr4muvJyT0dvZ9M1nGPR6Bt473TyBW03yMtL47b9zKMjMwM7ZhYmvvMmpvbvYv+o3XHx8eeD/Pmu0OGqy+X9fErt+NdZ29ty34ANzr4iqnDtxjJ2/LOH8yTjAVHs36rFn6Bh5fX8cDHodp2P2c2zrBpJjYxCXdeVEoWDM0y9ddbK7G53BaGD7ue0si1/GrrRd5uUd3TryfM/n6d+68oBv1ckoyeCflH/4O+VvjuSYajmsldYM8h/ErW1uZXDrwdir7WvYS+O5UHaBlUkricmM4VjOsWp7qVTF18GXYOdg08MlmDbObeju073Kdjna8jJ+mvUcuWnnTD2dZs3lVPRO/vr4PTwDg5n+3qf1GVazkRSzjz/ffQuFUkn3UWM5sulv9FoNKBSE3xLFwMn31+vM7nqdjtzzZ801J/kZaTi4uOHq2wrXVn64+bTCxbcVautrayBcQQhB7vlzpByOIXToiDpN21EbMoFpBglMbWnLSjn0z1pi/vqT0oL8696ftZ093m1CsLF3pLy4yPQoKaa8uAiDrvphv63U1vh16kJQeASBYd3wbhNivq0ljEbyM9PJSjlNZnISF86ewcbBERdvX1x9fHHx8cXV2xcHV7dq5+YRRiPnThwjbttmTu3dZa59atc7knEvvFantkAl+Xn8/vZcspKTUNvYYtDrMRr0jH95Dm179qnDT6thGfQ6lr/1Omnxx/HwD2TK/PdRqqww6LTotVr0Wg1FF3LY9+cKki+ORqpSq4mIGkOf8ZPqvQtucV4ux7dv5tjWjeRnpDHi4Seb3TgvDaFQW0heeR7F2mIKtYUU64op0haRVpzGqqRV5loSBQoGth7I5I6TGeQ/6LoaK54vPs/p/NNEeEfgZO1UX6E0GCEEmaWZxF2IIy4njhO5J1AqTD2HvO298bH3Mb/2c/SrcyKWc/YMP732PHqthv53T6UgM4O4bZvodftEhtz3YANF1fRWLfwvCXt3m//fulMowx6Yed09FG9kN0QCs2jRIt577z0yMjLo1q0bn3zyCX361O7DqTETmIySDPak7yG5IBkXGxfcbd0tHh52HrXqEqfTaojbuomMpFMYdDoMeh0GnQ69zvSsslJh5+yKvYsL9s6u2Du7YOfsTFlREVnJSWQmJ5J9JvmqScrlFEolSqUShUoFAtM3g8vYOjjSunMYmpJislKS0JaVVbOnS1RqNQ6ubtg7u2Dv4ordxWeEID56J4XZmeayrj6tCB06gp5j7rimxmDaslJWLVzAmSOmavs23Xsx8dW5dd5PQyvOy+XHV5+hJD/vquWUKhVhw0bSb+I9OHnUrTq9roQQ6DWaJh/srSHklOVw4sIJTuSe4PiF45y4cIK0krSrbuNq48qE9hOY1GFSsxkh9UYUt20T6z/7AIVCiZWNDbryMia9Mb/ZjjdUH4pyc1g6+0UUCgWDp86gY+Sgm77jRk1afAKzbNkypk2bxhdffEHfvn358MMPWbFiBfHx8Xh719w4syETmGJtMQcyDxCdFk10ejTJBclXLW+lsCLMM4zevr3p7dubCO+Iq3Z/vB4GvZ7c82fJTE7CoNNh6+iEraMjto5O2Dk6YePgiNrWBoVCafFLZKoSPMuZo4dJPXaIs3FH0ZZZNhJUqdV4BQbj3aYtnoHBaMvKKMjKoCAzg4KsDApzshFG45WnZMHazp6OkQMJHTICv46dr/sX2aDXsWXx16QnxHP787Nw9Wmec42cOxnHb/PnWCaJCgVWamvUNja0iehJ5F1TrmnU4easoq1Gdmk22WXZ5JTlkFeeR4G2wNRmQ1Nofq1AgYuNi/nhauOKi40LOoOOnLIcLpRfIKcsh5yyHHLLc9EatICp1qSie64QgmJdcZXnYm9lj5O1k8XD2dqZSL9IRgWPuuZxN6S6Wf/5h8Rt3QiYJtB84tuf63Vm6+bIoNebeq7KxKVWWnwC07dvX3r37s2nn5rujRqNRgICAvjXv/7Fq6++WuP2DZXAvLbjNdYmr8UgLjWUUiqUhHqEEuoRSqm+lAvlF8gtyyVPk0duWS5ao9ZiH2qlmnDPcMI9w3GwdsBOZYedlR12atOzwWgguyzb/Ec/uyybnNIcyg3lqJVqrFXWWCutTc8qawQCnUGH1qBFa9Sang1aU2MvpRoblQ3WKmvztmqlGpVChUqpsngWCAxGAwZhQKfXYpVZhk1GOdirMXo7oPRwxMba1nxslVKFEiVKhemhEECRBmWpHmWZHkWpHkq1iFItCq0Bx3YBeIZ3wtbOARuVDTYqG9Sqi+dy8aFUKE3PSiVGoxGDMGAUl54FAgUKc1nzsS//w3DZO9ogDOiMOrRGLTqDDp1Rh86gw4gRtVKNldIKK6WV+bVKoTJ/ICpQmPZ98dNRIKj4dREX/1Wco96oR2fUoTfqMQiD+edoFEbzQ1tWCnqjOWlRWV065uX7FEKYB91SKpTmn7FKeenno7hyQI1qzg8wL6v4+VWMAFrxf/PxhGk7vVFfuWGoppByQ7l5XIqKMSgc1A4oFAryy/PJ0+RZPFckHJc3Em0MChQEuwTT2b0zXTy60MWjCx3dO+Js3bxvJd8sdJpylr7+AjlnzxDSozcTXqk8LYR0c6vt53ez7O6i1WqJiYlh1qxL43golUpGjBhBdHR0ldtoNBo0mkvfbgsLC6ssd70crR0xCAOBToFE+kXSr1U/evv2rjQUdQUhBOeLz5sHk9qXsY/M0kwOZpm6YDZ7FXcyii8+6srm4gOgCNh9lbLSDcvFxgUvOy887Dxwt3XH1cYVZ2tnc21LRXJRMappxcim+Zp81Eq1eVtPO0887DzwsPXA1srWItmrSMJ8HHxwUDfMvFfS9VPb2DL+5TfY+8dyut96e1OfjtSCNcsEJicnB4PBgI+Pj8VyHx8fTp48WeU2CxYsYN68eQ1+btNDpzM9dDqtHavvTXI5hUKBv5M//k7+TGg/ASEEZ4vOsi9jH8kFyZTpyyo9lAolXnZeeNl74WXnhaedJ172Xthb2VeqZdEYNCgUCosamYrXAmEud/l2FbUERmFEb9SbazgUKFApVVgprCxqZ/RGPRqDxny8itcVNQsV3+orHpfXSBiMl15X1IJcvg+NQWPexiBMvaH0Qm8e9tyiVuZiTYtRGBFCYBCGS8+XVbtU1E4oFAqUKFGr1KiVaosaKKVCaa4xufz5ylqJimfzPi+7XVFRE2SltDL/3CpqdK4874oHgF7oMRgv/vwvvq7Yn0Jx8XFZrU9VNVHVvt8ui/3y/1f87CqOoeRSrZV5+cV1KoXKYmC0igTDWmVNmb6MEl2JxcNgNOBq64qbrRtuNm642lx8betmfv/W10i10o3BxduXqEefburTkFq4ZpnAXItZs2bx/PPPm/9fWFhIQED9N8arbeJSHYVCQaBzIIHOgfV0RpIkSZJ082mWCYynpycqlYrMzEyL5ZmZmfj6Vt1I08bGBhsb2QhPkiRJkm4GDTsj0zWytramZ8+ebNq0ybzMaDSyadMmIiMjm/DMJEmSJElqDpplDQzA888/z/Tp0+nVqxd9+vThww8/pKSkhBkzZjT1qUmSJEmS1MSabQIzefJksrOzmTNnDhkZGURERLB+/fpKDXslSZIkSbr5NNtxYK5XS5pKQJIkSZIkk9p+fjfLNjCSJEmSJElXIxMYSZIkSZJaHJnASJIkSZLU4sgERpIkSZKkFkcmMJIkSZIktTgygZEkSZIkqcWRCYwkSZIkSS2OTGAkSZIkSWpxZAIjSZIkSVKL02ynErheFQMMFxYWNvGZSJIkSZJUWxWf2zVNFHDDJjBFRUUABAQENPGZSJIkSZJUV0VFRbi4uFS7/oadC8loNJKWloaTkxMKhaLe9ltYWEhAQABnz569KeZYupnilbHeuG6meGWsN66bJV4hBEVFRfj5+aFUVt/S5YatgVEqlfj7+zfY/p2dnW/oN9CVbqZ4Zaw3rpspXhnrjetmiPdqNS8VZCNeSZIkSZJaHJnASJIkSZLU4sgEpo5sbGx48803sbGxaepTaRQ3U7wy1hvXzRSvjPXGdbPFW5MbthGvJEmSJEk3LlkDI0mSJElSiyMTGEmSJEmSWhyZwEiSJEmS1OLIBEaSJEmSpBbnpkxgtm/fzu23346fnx8KhYI///zTYn1mZiYPPPAAfn5+2Nvbc+utt5KQkGBRZujQoSgUCovHY489ZlEmNTWVMWPGYG9vj7e3Ny+99BJ6vb6hw6ukPuIFiI6O5pZbbsHBwQFnZ2cGDx5MWVmZeX1ubi5Tp07F2dkZV1dXHnroIYqLixs6PAvXG2tKSkql61rxWLFihblcc7i29XFdMzIyuP/++/H19cXBwYEePXrw22+/WZRpDtcV6ifepKQkJkyYgJeXF87Oztx9991kZmZalGkO8S5YsIDevXvj5OSEt7c348ePJz4+3qJMeXk5Tz75JB4eHjg6OnLnnXdWiqU279OtW7fSo0cPbGxsaNeuHYsXL27o8CzUV6xPP/00PXv2xMbGhoiIiCqPdeTIEQYNGoStrS0BAQG8++67DRVWleoj1sOHD3PvvfcSEBCAnZ0dnTt35qOPPqp0rKa+ro3hpkxgSkpK6NatG4sWLaq0TgjB+PHjOX36NCtXriQ2NpagoCBGjBhBSUmJRdlHHnmE9PR08+PyXwaDwcCYMWPQarXs3r2b77//nsWLFzNnzpwGj+9K9RFvdHQ0t956K1FRUezbt4/9+/fz1FNPWQzzPHXqVOLi4tiwYQNr1qxh+/btzJw5s1FirHC9sQYEBFhc0/T0dObNm4ejoyOjR48Gms+1rY/rOm3aNOLj41m1ahVHjx5l4sSJ3H333cTGxprLNIfrCtcfb0lJCVFRUSgUCjZv3syuXbvQarXcfvvtGI1G876aQ7zbtm3jySefZM+ePWzYsAGdTkdUVJTFtXvuuedYvXo1K1asYNu2baSlpTFx4kTz+tq8T5OTkxkzZgzDhg3j0KFDPPvsszz88MP8/fffLSrWCg8++CCTJ0+u8jiFhYVERUURFBRETEwM7733HnPnzuWrr75qsNiuVB+xxsTE4O3tzY8//khcXByvv/46s2bN4tNPPzWXaQ7XtVGImxwg/vjjD/P/4+PjBSCOHTtmXmYwGISXl5f4+uuvzcuGDBkinnnmmWr3u3btWqFUKkVGRoZ52eeffy6cnZ2FRqOp1xjq4lrj7du3r5g9e3a1+z1+/LgAxP79+83L1q1bJxQKhTh//nz9BlFL1xrrlSIiIsSDDz5o/n9zvLbXGquDg4P44YcfLPbl7u5uLtMcr6sQ1xbv33//LZRKpSgoKDCXyc/PFwqFQmzYsEEI0XzjzcrKEoDYtm2bEMJ03mq1WqxYscJc5sSJEwIQ0dHRQojavU9ffvllERoaanGsyZMni1GjRjV0SNW6llgv9+abb4pu3bpVWv7ZZ58JNzc3i9/RV155RXTs2LH+g6il6421whNPPCGGDRtm/n9zvK4N4aasgbkajUYDgK2trXmZUqnExsaGnTt3WpT96aef8PT0JCwsjFmzZlFaWmpeFx0dTXh4OD4+PuZlo0aNorCwkLi4uAaOovZqE29WVhZ79+7F29ub/v374+Pjw5AhQyx+HtHR0bi6utKrVy/zshEjRqBUKtm7d28jRXN1dbm2FWJiYjh06BAPPfSQeVlLuLa1jbV///4sW7aM3NxcjEYjv/zyC+Xl5QwdOhRoGdcVahevRqNBoVBYDAJma2uLUqk0l2mu8RYUFADg7u4OmN6XOp2OESNGmMt06tSJwMBAoqOjgdq9T6Ojoy32UVGmYh9N4VpirY3o6GgGDx6MtbW1edmoUaOIj48nLy+vns6+buor1oKCAvM+oHle14YgE5grVLxZZs2aRV5eHlqtlnfeeYdz586Rnp5uLjdlyhR+/PFHtmzZwqxZs1iyZAn33XefeX1GRobFHw7A/P+MjIzGCaYWahPv6dOnAZg7dy6PPPII69evp0ePHgwfPtzcxiAjIwNvb2+LfVtZWeHu7t5s4q3ttb3ct99+S+fOnenfv795WUu4trWNdfny5eh0Ojw8PLCxseHRRx/ljz/+oF27dkDLuK5Qu3j79euHg4MDr7zyCqWlpZSUlPDiiy9iMBjMZZpjvEajkWeffZYBAwYQFhYGmM7T2toaV1dXi7I+Pj7m86zN+7S6MoWFhRbt2xrLtcZaG83t97a+Yt29ezfLli2zuM3Z3K5rQ5EJzBXUajW///47p06dwt3dHXt7e7Zs2cLo0aMt2nvMnDmTUaNGER4eztSpU/nhhx/4448/SEpKasKzr7vaxFvRPuDRRx9lxowZdO/enQ8++ICOHTvy3XffNeXp10ltr22FsrIyli5dalH70lLUNtY33niD/Px8Nm7cyIEDB3j++ee5++67OXr0aBOefd3VJl4vLy9WrFjB6tWrcXR0xMXFhfz8fHr06FHl9W8unnzySY4dO8Yvv/zS1KfS4GSsdXPs2DHuuOMO3nzzTaKiourx7FoGq6Y+geaoZ8+eHDp0iIKCArRaLV5eXvTt29eiWvlKffv2BSAxMZG2bdvi6+vLvn37LMpUtCT39fVtuJO/BjXF26pVKwC6dOlisV3nzp1JTU0FTDFlZWVZrNfr9eTm5jareOtybX/99VdKS0uZNm2axfKWcm1rijUpKYlPP/2UY8eOERoaCkC3bt3YsWMHixYt4osvvmgx1xVqd22joqJISkoiJycHKysrXF1d8fX1JSQkBGh+7+OnnnrK3JDY39/fvNzX1xetVkt+fr7Ft/XMzEzzedbmferr61upN09mZibOzs7Y2dk1REjVup5Ya6O6WCvWNab6iPX48eMMHz6cmTNnMnv2bIt1zem6NqTm+7WjGXBxccHLy4uEhAQOHDjAHXfcUW3ZQ4cOAZc+7CMjIzl69KjFH8MNGzbg7OxcKRFoLqqLNzg4GD8/v0rd/U6dOkVQUBBgijc/P5+YmBjz+s2bN2M0Gs3JXXNSm2v77bffMm7cOLy8vCyWt7RrW12sFW22rqx9UKlU5lq3lnZdoXbX1tPTE1dXVzZv3kxWVhbjxo0Dmk+8Qgieeuop/vjjDzZv3kybNm0s1vfs2RO1Ws2mTZvMy+Lj40lNTSUyMhKo3fs0MjLSYh8VZSr20RjqI9baiIyMZPv27eh0OvOyDRs20LFjR9zc3K4/kFqor1jj4uIYNmwY06dPZ/78+ZWO0xyua6No4kbETaKoqEjExsaK2NhYAYiFCxeK2NhYcebMGSGEEMuXLxdbtmwRSUlJ4s8//xRBQUFi4sSJ5u0TExPFW2+9JQ4cOCCSk5PFypUrRUhIiBg8eLC5jF6vF2FhYSIqKkocOnRIrF+/Xnh5eYlZs2a1uHiFEOKDDz4Qzs7OYsWKFSIhIUHMnj1b2NraisTERHOZW2+9VXTv3l3s3btX7Ny5U7Rv317ce++9LS5WIYRISEgQCoVCrFu3rtK65nJtrzdWrVYr2rVrJwYNGiT27t0rEhMTxf/93/8JhUIh/vrrL3O55nBd6yNeIYT47rvvRHR0tEhMTBRLliwR7u7u4vnnn7co0xziffzxx4WLi4vYunWrSE9PNz9KS0vNZR577DERGBgoNm/eLA4cOCAiIyNFZGSkeX1t3qenT58W9vb24qWXXhInTpwQixYtEiqVSqxfv75FxSqE6Xc2NjZWPProo6JDhw7m90pFr6P8/Hzh4+Mj7r//fnHs2DHxyy+/CHt7e/Hll1+2qFiPHj0qvLy8xH333Wexj6ysLHOZ5nBdG8NNmcBs2bJFAJUe06dPF0II8dFHHwl/f3+hVqtFYGCgmD17tkXXu9TUVDF48GDh7u4ubGxsRLt27cRLL71k0T1TCCFSUlLE6NGjhZ2dnfD09BQvvPCC0Ol0jRmqEOL6462wYMEC4e/vL+zt7UVkZKTYsWOHxfoLFy6Ie++9Vzg6OgpnZ2cxY8YMUVRU1BghmtVXrLNmzRIBAQHCYDBUeZzmcG3rI9ZTp06JiRMnCm9vb2Fvby+6du1aqVt1c7iuQtRPvK+88orw8fERarVatG/fXrz//vvCaDRalGkO8VYVJyD+97//mcuUlZWJJ554Qri5uQl7e3sxYcIEkZ6ebrGf2rxPt2zZIiIiIoS1tbUICQmxOEZjqK9YhwwZUuV+kpOTzWUOHz4sBg4cKGxsbETr1q3F22+/3UhRmtRHrG+++WaV+wgKCrI4VlNf18agEEKI+qrNkSRJkiRJagyyDYwkSZIkSS2OTGAkSZIkSWpxZAIjSZIkSVKLIxMYSZIkSZJaHJnASJIkSZLU4sgERpIkSZKkFkcmMJIkSZIktTgygZEkSZIkqcWRCYwkSZIkSS2OTGAkSZIkSWpxZAIjSdJNxWAwmGfbliSp5ZIJjCRJTeaHH37Aw8MDjUZjsXz8+PHcf//9AKxcuZIePXpga2tLSEgI8+bNQ6/Xm8suXLiQ8PBwHBwcCAgI4IknnqC4uNi8fvHixbi6urJq1Sq6dOmCjY0NqampjROgJEkNRiYwkiQ1mUmTJmEwGFi1apV5WVZWFn/99RcPPvggO3bsYNq0aTzzzDMcP36cL7/8ksWLFzN//nxzeaVSyccff0xcXBzff/89mzdv5uWXX7Y4TmlpKe+88w7ffPMNcXFxeHt7N1qMkiQ1DDkbtSRJTeqJJ54gJSWFtWvXAqYalUWLFpGYmMjIkSMZPnw4s2bNMpf/8ccfefnll0lLS6tyf7/++iuPPfYYOTk5gKkGZsaMGRw6dIhu3bo1fECSJDUKmcBIktSkYmNj6d27N2fOnKF169Z07dqVSZMm8cYbb+Dl5UVxcTEqlcpc3mAwUF5eTklJCfb29mzcuJEFCxZw8uRJCgsL0ev1FusXL17Mo48+Snl5OQqFogkjlSSpPlk19QlIknRz6969O926deOHH34gKiqKuLg4/vrrLwCKi4uZN28eEydOrLSdra0tKSkpjB07lscff5z58+fj7u7Ozp07eeihh9Bqtdjb2wNgZ2cnkxdJusHIBEaSpCb38MMP8+GHH3L+/HlGjBhBQEAAAD169CA+Pp527dpVuV1MTAxGo5H3338fpdLUpG/58uWNdt6SJDUdmcBIktTkpkyZwosvvsjXX3/NDz/8YF4+Z84cxo4dS2BgIHfddRdKpZLDhw9z7Ngx/vOf/9CuXTt0Oh2ffPIJt99+O7t27eKLL75owkgkSWossheSJElNzsXFhTvvvBNHR0fGjx9vXj5q1CjWrFnDP//8Q+/evenXrx8ffPABQUFBAHTr1o2FCxfyzjvvEBYWxk8//cSCBQuaKApJkhqTbMQrSVKzMHz4cEJDQ/n444+b+lQkSWoBZAIjSVKTysvLY+vWrdx1110cP36cjh07NvUpSZLUAsg2MJIkNanu3buTl5fHO++8I5MXSZJqTdbASJIkSZLU4shGvJIkSZIktTgygZEkSZIkqcWRCYwkSZIkSS2OTGAkSZIkSWpxZAIjSZIkSVKLIxMYSZIkSZJaHJnASJIkSZLU4sgERpIkSZKkFuf/AaFoRR+6+Zl0AAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "timeseries.set_index('year').sort_index().plot.line()\n" + ] + }, + { + "cell_type": "markdown", + "id": "4b15e937", + "metadata": {}, + "source": [ + "### Downloading to Local Pandas (Optional Handoff)\n", + "\n", + "If you need to use local Python libraries that are not supported by BigFrames (such as custom plotting libraries or local ML frameworks), you can explicitly download the final transformed remote DataFrame into a standard local Pandas DataFrame using `.to_pandas()`:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "97757974", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Time periodBeginning stocksProductionImports 2Total supply 3Food useSeed useFeed and residual useTotal domestic use 3Exports 2Total disappearance 3Ending stocks
year
1950-01-01 00:00:00+00:00MY Jun-May496.01019.011.01526.0580.0--109.0689.0345.01034.0492.0
1951-01-01 00:00:00+00:00MY Jun-May492.0988.030.01510.0585.0--110.0695.0485.01180.0330.0
1952-01-01 00:00:00+00:00MY Jun-May330.01306.024.01660.0578.0--78.0656.0332.0988.0672.0
1953-01-01 00:00:00+00:00MY Jun-May672.01173.06.01851.0556.0--87.0643.0214.0857.0994.0
1954-01-01 00:00:00+00:00MY Jun-May994.0984.03.01981.0552.0--53.0605.0267.0872.01109.0
.......................................
2022-01-01 00:00:00+00:00MY Jun-May674.4311649.713121.5852445.729971.67768.36975.5031115.549760.6121876.161569.568
2023-01-01 00:00:00+00:00MY Jun-May569.5681803.942137.7982511.308961.30362.04685.6171108.966705.9081814.874696.434
2024-01-01 00:00:00+00:00MY Jun-May696.4341978.697148.9542824.085969.49361.1112.8631143.456825.8951969.351854.734
2025-01-01 00:00:00+00:00MY Jun-May854.7341984.537125.02964.271960.059.7100.01119.7910.02029.7934.571
2026-01-01 00:00:00+00:00MY Jun-May934.5711561.322140.02635.893960.05980.01099.0775.01874.0761.893
\n", + "

77 rows × 12 columns

\n", + "
" + ], + "text/plain": [ + " Time period Beginning stocks Production \\\n", + "year \n", + "1950-01-01 00:00:00+00:00 MY Jun-May 496.0 1019.0 \n", + "1951-01-01 00:00:00+00:00 MY Jun-May 492.0 988.0 \n", + "1952-01-01 00:00:00+00:00 MY Jun-May 330.0 1306.0 \n", + "1953-01-01 00:00:00+00:00 MY Jun-May 672.0 1173.0 \n", + "1954-01-01 00:00:00+00:00 MY Jun-May 994.0 984.0 \n", + "... ... ... ... \n", + "2022-01-01 00:00:00+00:00 MY Jun-May 674.431 1649.713 \n", + "2023-01-01 00:00:00+00:00 MY Jun-May 569.568 1803.942 \n", + "2024-01-01 00:00:00+00:00 MY Jun-May 696.434 1978.697 \n", + "2025-01-01 00:00:00+00:00 MY Jun-May 854.734 1984.537 \n", + "2026-01-01 00:00:00+00:00 MY Jun-May 934.571 1561.322 \n", + "\n", + " Imports 2 Total supply 3 Food use Seed use \\\n", + "year \n", + "1950-01-01 00:00:00+00:00 11.0 1526.0 580.0 -- \n", + "1951-01-01 00:00:00+00:00 30.0 1510.0 585.0 -- \n", + "1952-01-01 00:00:00+00:00 24.0 1660.0 578.0 -- \n", + "1953-01-01 00:00:00+00:00 6.0 1851.0 556.0 -- \n", + "1954-01-01 00:00:00+00:00 3.0 1981.0 552.0 -- \n", + "... ... ... ... ... \n", + "2022-01-01 00:00:00+00:00 121.585 2445.729 971.677 68.369 \n", + "2023-01-01 00:00:00+00:00 137.798 2511.308 961.303 62.046 \n", + "2024-01-01 00:00:00+00:00 148.954 2824.085 969.493 61.1 \n", + "2025-01-01 00:00:00+00:00 125.0 2964.271 960.0 59.7 \n", + "2026-01-01 00:00:00+00:00 140.0 2635.893 960.0 59 \n", + "\n", + " Feed and residual use Total domestic use 3 \\\n", + "year \n", + "1950-01-01 00:00:00+00:00 109.0 689.0 \n", + "1951-01-01 00:00:00+00:00 110.0 695.0 \n", + "1952-01-01 00:00:00+00:00 78.0 656.0 \n", + "1953-01-01 00:00:00+00:00 87.0 643.0 \n", + "1954-01-01 00:00:00+00:00 53.0 605.0 \n", + "... ... ... \n", + "2022-01-01 00:00:00+00:00 75.503 1115.549 \n", + "2023-01-01 00:00:00+00:00 85.617 1108.966 \n", + "2024-01-01 00:00:00+00:00 112.863 1143.456 \n", + "2025-01-01 00:00:00+00:00 100.0 1119.7 \n", + "2026-01-01 00:00:00+00:00 80.0 1099.0 \n", + "\n", + " Exports 2 Total disappearance 3 Ending stocks \n", + "year \n", + "1950-01-01 00:00:00+00:00 345.0 1034.0 492.0 \n", + "1951-01-01 00:00:00+00:00 485.0 1180.0 330.0 \n", + "1952-01-01 00:00:00+00:00 332.0 988.0 672.0 \n", + "1953-01-01 00:00:00+00:00 214.0 857.0 994.0 \n", + "1954-01-01 00:00:00+00:00 267.0 872.0 1109.0 \n", + "... ... ... ... \n", + "2022-01-01 00:00:00+00:00 760.612 1876.161 569.568 \n", + "2023-01-01 00:00:00+00:00 705.908 1814.874 696.434 \n", + "2024-01-01 00:00:00+00:00 825.895 1969.351 854.734 \n", + "2025-01-01 00:00:00+00:00 910.0 2029.7 934.571 \n", + "2026-01-01 00:00:00+00:00 775.0 1874.0 761.893 \n", + "\n", + "[77 rows x 12 columns]" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pddf = timeseries.set_index('year').sort_index().to_pandas()\n", + "pddf\n" + ] + }, + { + "cell_type": "markdown", + "id": "9c1242ab", + "metadata": {}, + "source": [ + "## Conclusion: The Power of Hybrid Chaining\n", + "\n", + "By leveraging BigQuery DataFrames and the `%%bqsql` magic, you have built a powerful, interoperable pipeline that seamlessly transitions between SQL and Python.\n", + "\n", + "This hybrid approach offers several key benefits:\n", + "- **Optimal Tool Selection**: Use SQL for what it does best (complex queries, window functions, regex extractions on large sets) and Python for what it does best (visualization, statistical analysis, ML, orchestrating workflow).\n", + "- **Improved Readability**: Instead of massive, unreadable SQL queries with dozens of CTEs, or long, complex Pandas method chains, you can split your pipeline into logical steps, alternating between SQL and Python.\n", + "- **Seamless Scaling**: The exact same `%%bqsql` code can scale from a tiny local Pandas DataFrame to billions of rows in a production BigQuery table. You only need to swap the initial local Pandas DataFrame with a BigQuery DataFrame reference.\n", + "\n", + "\n", + "## Next Steps\n", + "\n", + "In addition to the `%%bqsql` cell magic, BigFrames also registers a **BigQuery Accessor** on standard Pandas DataFrames, allowing you to run SQL scalar functions directly on local pandas data. \n", + "\n", + "For example, you can call powerful Google Cloud community UDFs from [BigQuery Utils](https://github.com/GoogleCloudPlatform/bigquery-utils/tree/master/udfs#bigquery-udfs), [BigFunctions](https://unytics.io/bigfunctions/bigfunctions/#function-categories), or [CARTO Analytics Toolbox for BigQuery](https://docs.carto.com/data-and-analysis/analytics-toolbox-for-bigquery) using `df.bigquery.sql_scalar(...)`:\n" + ] + }, + { + "cell_type": "markdown", + "id": "6a7928bd", + "metadata": {}, + "source": [ + "### Scaling Up: Advanced BigQuery Features\n", + "\n", + "While the BigQuery sandbox offers a powerful environment to test these hybrid Python-SQL workflows for free, some advanced features like BigQuery Machine Learning (BQML) are restricted. By connecting a billing account to your Google Cloud project, you can unlock advanced capabilities such as `ML.FORECAST` (or the `AI.FORECAST` function) to predict time-series data using Google's state-of-the-art foundational models directly from your SQL/Python chain.\n", + "\n", + "### Feedback & Community\n", + "\n", + "The BigFrames team would love to hear your feedback on the hybrid Python-SQL experience:\n", + "* **Email**: [bigframes-feedback@google.com](mailto:bigframes-feedback@google.com)\n", + "* **Issues**: File bug reports or feature requests on the [open-source BigFrames repository](https://github.com/googleapis/google-cloud-python/issues).\n", + "* **Updates**: To receive news and updates, subscribe to the [BigFrames email list](https://docs.google.com/forms/d/10EnDyYdYUW9HvelHYuBRC8L3GdGVl3rX0aroinbRZyc/edit?resourcekey=0-QUsnpzF91gm9hsp04rSA6Q).\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bc1a6dbe-170e-4380-83da-779f37e1c00a", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.14.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 1255547fae362a468f8aa079b62a9f11c2bd34ea Mon Sep 17 00:00:00 2001 From: Tomo Suzuki Date: Tue, 9 Jun 2026 12:51:37 -0400 Subject: [PATCH 048/174] chore: librarian release pull request: 20260609T161736Z (#17405) PR created by the Librarian CLI to initialize a release. Merging this PR will auto trigger a release. Librarian Version: v0.16.1-0.20260608172125-d123ec9cac76 Language Image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:234b9d1f2ddb057ed7ac6a38db0bf8163d839c65c6cf88ade52530cddebce59e
google-cloud-agentidentitycredentials: v0.1.0 ## [v0.1.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-agentidentitycredentials-v0.0.0...google-cloud-agentidentitycredentials-v0.1.0) (2026-06-09) ### Features * add google-cloud-agentidentitycredentials (#17399) ([6e0f0ece](https://github.com/googleapis/google-cloud-python/commit/6e0f0ece))
--- .librarian/state.yaml | 2 +- librarian.yaml | 2 +- .../google-cloud-agentidentitycredentials/CHANGELOG.md | 7 +++++++ .../google/cloud/agentidentitycredentials/gapic_version.py | 2 +- .../cloud/agentidentitycredentials_v1/gapic_version.py | 2 +- ..._metadata_google.cloud.agentidentitycredentials.v1.json | 2 +- 6 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index e7edb1d6fa21..c2472c8546cb 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -515,7 +515,7 @@ libraries: - packages/google-cloud-advisorynotifications/docs/ tag_format: '{id}-v{version}' - id: google-cloud-agentidentitycredentials - version: 0.0.0 + version: 0.1.0 last_generated_commit: "" apis: - path: google/cloud/agentidentitycredentials/v1 diff --git a/librarian.yaml b/librarian.yaml index 80f260642d86..0bf20ac53fc2 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -280,7 +280,7 @@ libraries: metadata_name_override: advisorynotifications default_version: v1 - name: google-cloud-agentidentitycredentials - version: 0.0.0 + version: 0.1.0 apis: - path: google/cloud/agentidentitycredentials/v1 copyright_year: "2026" diff --git a/packages/google-cloud-agentidentitycredentials/CHANGELOG.md b/packages/google-cloud-agentidentitycredentials/CHANGELOG.md index b008a19d3788..d35246d2c538 100644 --- a/packages/google-cloud-agentidentitycredentials/CHANGELOG.md +++ b/packages/google-cloud-agentidentitycredentials/CHANGELOG.md @@ -3,3 +3,10 @@ [PyPI History][1] [1]: https://pypi.org/project/google-cloud-agentidentitycredentials/#history + +## [0.1.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-agentidentitycredentials-v0.0.0...google-cloud-agentidentitycredentials-v0.1.0) (2026-06-09) + + +### Features + +* add google-cloud-agentidentitycredentials (#17399) ([6e0f0ecebde0dd92d8789f470a27c49d9971cf87](https://github.com/googleapis/google-cloud-python/commit/6e0f0ecebde0dd92d8789f470a27c49d9971cf87)) diff --git a/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials/gapic_version.py b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials/gapic_version.py index e89a0031d71b..075b8773ece3 100644 --- a/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials/gapic_version.py +++ b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.0.0" # {x-release-please-version} +__version__ = "0.1.0" # {x-release-please-version} diff --git a/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/gapic_version.py b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/gapic_version.py index e89a0031d71b..075b8773ece3 100644 --- a/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/gapic_version.py +++ b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.0.0" # {x-release-please-version} +__version__ = "0.1.0" # {x-release-please-version} diff --git a/packages/google-cloud-agentidentitycredentials/samples/generated_samples/snippet_metadata_google.cloud.agentidentitycredentials.v1.json b/packages/google-cloud-agentidentitycredentials/samples/generated_samples/snippet_metadata_google.cloud.agentidentitycredentials.v1.json index 11df3850aef6..d6b757c4fd12 100644 --- a/packages/google-cloud-agentidentitycredentials/samples/generated_samples/snippet_metadata_google.cloud.agentidentitycredentials.v1.json +++ b/packages/google-cloud-agentidentitycredentials/samples/generated_samples/snippet_metadata_google.cloud.agentidentitycredentials.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-agentidentitycredentials", - "version": "0.0.0" + "version": "0.1.0" }, "snippets": [ { From 978de980a37722e36ae45d8fae89113b5f19e9c6 Mon Sep 17 00:00:00 2001 From: Anthonios Partheniou Date: Tue, 9 Jun 2026 13:11:44 -0400 Subject: [PATCH 049/174] chore: generate spanner (#17406) Fixes https://github.com/googleapis/google-cloud-python/issues/17281 Fixes https://github.com/googleapis/google-cloud-python/issues/17373 `docker run -u $(id -u):$(id -g) -v .:/repo -v ~/.cache:/.cache -w /repo docker.io/library/librarian-python: generate -v google-cloud-spanner` produced no diff with these changes. This PR is needed to update the post processing following https://github.com/googleapis/google-cloud-python/pull/17344 which added handwritten changes on top of the auto-generated files `noxfile.py` and `setup.py` for `google-cloud-spanner`. --- .../spanner-integration.yaml | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/.librarian/generator-input/client-post-processing/spanner-integration.yaml b/.librarian/generator-input/client-post-processing/spanner-integration.yaml index f00d166046ff..42b8909c01d4 100644 --- a/.librarian/generator-input/client-post-processing/spanner-integration.yaml +++ b/.librarian/generator-input/client-post-processing/spanner-integration.yaml @@ -146,7 +146,17 @@ replacements: "google-cloud-monitoring >= 2.16.0", "mmh3 >= 4.1.0", ] - extras = {"libcst": "libcst >= 0.2.5"} + extras = { + "libcst": "libcst >= 0.2.5", + "test": [ + "pytest", + "mock", + "asyncmock", + "pytest-cov", + "pytest-asyncio", + "pytest-xdist", + ], + } count: 1 - paths: [packages/google-cloud-spanner/docs/index.rst] before: '(?s)API Reference\n-------------.*' @@ -647,6 +657,7 @@ replacements: "pytest", "pytest-cov", "pytest-asyncio", + "pytest-xdist", ] MOCK_SERVER_ADDITIONAL_DEPENDENCIES = [ "google-cloud-testutils", @@ -844,6 +855,8 @@ replacements: # Run py.test against the unit tests. args = [ "py.test", + "-n", + "auto", "-s", f"--junitxml=unit_{session.python}_sponge_log.xml", "--cov=google", @@ -1358,7 +1371,6 @@ replacements: def mypy(session): """Run the type checker.""" session.skip("Mypy is not yet supported") - # TODO(https://github.com/googleapis/gapic-generator-python/issues/2579): # use the latest version of mypy session.install( @@ -1401,6 +1413,25 @@ replacements: libcst==0.2.5 googleapis-common-protos==1.60.0 count: 1 + - paths: [ + packages/google-cloud-spanner/noxfile.py + ] + before: | + session.install\(\*dep_paths, "--no-deps", "--ignore-installed"\) + [\s\S]*?session.run\(\s+"py.test",\s+"tests/unit", + after: | + session.install(*dep_paths, "--no-deps", "--ignore-installed") + session.install("pytest-xdist") + print( + f"Installed {', '.join(core_dependencies_from_source)} locally from {deps_dir}" + ) + + session.run( + "py.test", + "-n", + "auto", + "tests/unit", + count: 1 - paths: [packages/google-cloud-spanner/testing/constraints-3.10.txt] before: 'grpcio==1.59.0\n(?!grpcio-status)' after: | From 568b2eae03b44a41a073685fc4ab08cd60e17ccf Mon Sep 17 00:00:00 2001 From: TrevorBergeron Date: Tue, 9 Jun 2026 12:22:52 -0700 Subject: [PATCH 050/174] chore(bigframes): Add simple Python bytecode translation (#17320) --- packages/bigframes/bigframes/core/bytecode.py | 263 +++++++++++++ .../bigframes/core/py_expressions.py | 366 ++++++++++++++++++ packages/bigframes/noxfile.py | 2 - .../tests/unit/core/test_bytecode.py | 91 +++++ 4 files changed, 720 insertions(+), 2 deletions(-) create mode 100644 packages/bigframes/bigframes/core/bytecode.py create mode 100644 packages/bigframes/bigframes/core/py_expressions.py create mode 100644 packages/bigframes/tests/unit/core/test_bytecode.py diff --git a/packages/bigframes/bigframes/core/bytecode.py b/packages/bigframes/bigframes/core/bytecode.py new file mode 100644 index 000000000000..5887254eb4de --- /dev/null +++ b/packages/bigframes/bigframes/core/bytecode.py @@ -0,0 +1,263 @@ +# Copyright 2026 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 dis +import operator +import sys +from types import ModuleType +from typing import Callable + +import bigframes.core.py_expressions as py_exprs +from bigframes.core import expression + +_BINARY_OP_MAP = { + "+": operator.add, + "-": operator.sub, + "*": operator.mul, + "/": operator.truediv, + "//": operator.floordiv, + "%": operator.mod, + "**": operator.pow, +} + +_COMPARE_OP_MAP = { + "==": operator.eq, + "!=": operator.ne, + "<": operator.lt, + "<=": operator.le, + ">": operator.gt, + ">=": operator.ge, +} + +_OLD_BINARY_OP_MAP = { + "BINARY_ADD": operator.add, + "INPLACE_ADD": operator.add, + "BINARY_SUBTRACT": operator.sub, + "INPLACE_SUBTRACT": operator.sub, + "BINARY_MULTIPLY": operator.mul, + "INPLACE_MULTIPLY": operator.mul, + "BINARY_TRUE_DIVIDE": operator.truediv, + "INPLACE_TRUE_DIVIDE": operator.truediv, + "BINARY_FLOOR_DIVIDE": operator.floordiv, + "INPLACE_FLOOR_DIVIDE": operator.floordiv, + "BINARY_MODULO": operator.mod, + "INPLACE_MODULO": operator.mod, + "BINARY_POWER": operator.pow, + "INPLACE_POWER": operator.pow, +} + + +_NULL = py_exprs.PyObject(None) + + +def _compile_bytecode_to_py_expr(func: Callable) -> expression.Expression: + instructions = list(dis.get_instructions(func)) + + stack: list[expression.Expression] = [] + globals_dict = func.__globals__ + import builtins + + builtins_dict = builtins.__dict__ + + closure_dict = {} + if func.__closure__: + free_vars = func.__code__.co_freevars + for var, cell in zip(free_vars, func.__closure__): + try: + closure_dict[var] = cell.cell_contents + except ValueError: + pass + + for inst in instructions: + opname = inst.opname + + if opname in ("RESUME", "PRECALL"): + continue + + elif opname in ("LOAD_FAST_LOAD_FAST", "LOAD_FAST_BORROW_LOAD_FAST_BORROW"): + var1, var2 = inst.argval + stack.append(expression.UnboundVariableExpression(var1)) + stack.append(expression.UnboundVariableExpression(var2)) + + elif opname.startswith("LOAD_FAST"): + stack.append(expression.UnboundVariableExpression(inst.argval)) + + elif opname in ("LOAD_CONST", "LOAD_SMALL_INT"): + stack.append(py_exprs.PyObject(inst.argval)) + + elif opname == "LOAD_GLOBAL": + # In Python 3.11+, the lowest bit of inst.arg indicates that a NULL + # should be pushed before the global variable. + if sys.version_info >= (3, 11) and inst.arg is not None and (inst.arg & 1): + stack.append(_NULL) + name = inst.argval + found = False + val = None + if name in closure_dict: + val = closure_dict[name] + found = True + elif name in globals_dict: + val = globals_dict[name] + found = True + elif name in builtins_dict: + val = builtins_dict[name] + found = True + + if found: + if isinstance(val, ModuleType): + stack.append(py_exprs.Module(val)) + else: + stack.append(py_exprs.PyObject(val)) + else: + stack.append(expression.UnboundVariableExpression(name)) + + elif opname in ("LOAD_ATTR", "LOAD_METHOD"): + if not stack: + raise ValueError("Stack is empty") + target = stack.pop() + stack.append(py_exprs.GetAttr(target, inst.argval)) + if opname == "LOAD_METHOD": + if isinstance(target, py_exprs.Module): + stack.append(_NULL) + else: + stack.append(target) + + elif opname == "PUSH_NULL": + stack.append(_NULL) + + elif opname == "BINARY_OP": + if len(stack) < 2: + raise ValueError("Stack is empty") + right = stack.pop() + left = stack.pop() + op_symbol = inst.argrepr + if not op_symbol and isinstance(inst.argval, str): + op_symbol = inst.argval + if op_symbol and op_symbol.endswith("="): + op_symbol = op_symbol[:-1] + + if op_symbol not in _BINARY_OP_MAP: + raise ValueError(f"Unsupported binary operator: {op_symbol}") + stack.append( + py_exprs.Call( + py_exprs.PyObject(_BINARY_OP_MAP[op_symbol]), (left, right) + ) + ) + + # Support older Python versions compatibility + elif opname in _OLD_BINARY_OP_MAP: + if len(stack) < 2: + raise ValueError("Stack has < 2 elements") + right = stack.pop() + left = stack.pop() + stack.append( + py_exprs.Call( + py_exprs.PyObject(_OLD_BINARY_OP_MAP[opname]), (left, right) + ) + ) + + elif opname == "COMPARE_OP": + if len(stack) < 2: + raise ValueError("Stack has < 2 elements") + right = stack.pop() + left = stack.pop() + op_symbol = inst.argval + if op_symbol not in _COMPARE_OP_MAP: + raise ValueError(f"Unsupported compare operator: {op_symbol}") + stack.append( + py_exprs.Call( + py_exprs.PyObject(_COMPARE_OP_MAP[op_symbol]), (left, right) + ) + ) + + elif opname in ("UNARY_NEGATIVE", "UNARY_INVERT"): + if not stack: + raise ValueError("Stack is empty") + target = stack.pop() + stack.append( + py_exprs.Call( + py_exprs.PyObject( + operator.neg if opname == "UNARY_NEGATIVE" else operator.invert + ), + (target,), + ) + ) + + elif opname == "UNARY_POSITIVE": + if not stack: + raise ValueError("Stack is empty") + target = stack.pop() + stack.append(py_exprs.Call(py_exprs.PyObject(operator.pos), (target,))) + + elif opname == "CALL_INTRINSIC_1": + if inst.argrepr == "INTRINSIC_UNARY_POSITIVE": + if not stack: + raise ValueError("Stack is empty") + target = stack.pop() + stack.append(py_exprs.Call(py_exprs.PyObject(operator.pos), (target,))) + else: + raise ValueError(f"Unsupported intrinsic: {inst.argrepr}") + + elif opname in ("CALL", "CALL_FUNCTION", "CALL_METHOD"): + num_args = inst.arg + assert num_args is not None + if len(stack) < num_args: + raise ValueError("Stack has < 2 elements") + args = [stack.pop() for _ in range(num_args)][::-1] + # In Python 3.11, LOAD_GLOBAL with NULL push puts NULL below the global. + # If NULL is below the callable on the stack, swap them to match + # the expected layout [callable, NULL]. + if len(stack) >= 2 and stack[-2] == _NULL: + stack[-1], stack[-2] = stack[-2], stack[-1] + if stack and stack[-1] == _NULL: + stack.pop() + elif ( + stack + and stack[-1] != _NULL + and isinstance(stack[-1], expression.Expression) + ): + self_arg = stack.pop() + args = [self_arg] + args + if not stack: + raise ValueError("Stack is empty") + callable_expr = stack.pop() + stack.append(py_exprs.Call(callable_expr, tuple(args))) + + elif opname == "RETURN_VALUE": + if not stack: + raise ValueError("Stack is empty") + return stack[-1] + + elif opname in ("STORE_FAST", "POP_TOP"): + if stack: + stack.pop() + + else: + raise ValueError(f"Unsupported opcode: {opname}") + + raise ValueError("No return value found") + + +def dis_to_expr(func: Callable, unpack_mode: bool = False) -> expression.Expression: + """ + Try to convert a python function to a BigQuery expression. + + Unpack mode is whether SQL columns are addressed as attributes of a single + python argument (e.g. row.col1), or as separate arguments (e.g. col1). + + This is "best effort" - if the function contains operations that cannot + be converted to BigQuery expressions, it will raise an Exception. + """ + py_expr = _compile_bytecode_to_py_expr(func) + return py_exprs.resolve_py_exprs(py_expr, unpack_mode=unpack_mode) diff --git a/packages/bigframes/bigframes/core/py_expressions.py b/packages/bigframes/bigframes/core/py_expressions.py new file mode 100644 index 000000000000..f29a35b0d161 --- /dev/null +++ b/packages/bigframes/bigframes/core/py_expressions.py @@ -0,0 +1,366 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import annotations + +import dataclasses +import itertools +from types import ModuleType +from typing import Callable, Hashable, Mapping, Tuple + +import bigframes.operations.python_op_maps as python_op_maps +from bigframes import dtypes +from bigframes.core import identifiers +from bigframes.core.expression import ( + Expression, + OpExpression, + UnboundVariableExpression, + const, +) +from bigframes.operations import NUMPY_TO_BINOP, NUMPY_TO_OP, generic_ops, numeric_ops + +_CALLABLE_TO_OP = { + **NUMPY_TO_OP, + **NUMPY_TO_BINOP, +} + +_BUILTIN_CALLABLES = { + str: generic_ops.AsTypeOp(dtypes.STRING_DTYPE), + abs: numeric_ops.abs_op, +} + + +@dataclasses.dataclass(frozen=True) +class GetAttr(Expression): + input: Expression + attr: str + + @property + def column_references( + self, + ) -> Tuple[identifiers.ColumnId, ...]: + return self.input.column_references + + @property + def free_variables(self) -> tuple[Hashable, ...]: + return self.input.free_variables + + @property + def is_const(self) -> bool: + return False + + @property + def children(self): + return (self.input,) + + @property + def nullable(self) -> bool: + return True + + @property + def is_resolved(self) -> bool: + return False + + @property + def output_type(self) -> dtypes.ExpressionType: + raise ValueError(f"Type of expression {self} has not been fixed.") + + @property + def is_bijective(self) -> bool: + # TODO: Mark individual functions as bijective? + return False + + @property + def deterministic(self) -> bool: + return True + + def transform_children(self, t: Callable[[Expression], Expression]) -> Expression: + new_input = t(self.input) + if new_input != self.input: + return dataclasses.replace(self, input=new_input) + return self + + def bind_variables( + self, + bindings: Mapping[Hashable, Expression], + allow_partial_bindings: bool = False, + ) -> GetAttr: + return GetAttr( + self.input.bind_variables( + bindings, allow_partial_bindings=allow_partial_bindings + ), + self.attr, + ) + + def bind_refs( + self, + bindings: Mapping[identifiers.ColumnId, Expression], + allow_partial_bindings: bool = False, + ) -> GetAttr: + return GetAttr( + self.input.bind_refs( + bindings, allow_partial_bindings=allow_partial_bindings + ), + self.attr, + ) + + +@dataclasses.dataclass(frozen=True) +class Module(Expression): + """An expression representing a module reference.""" + + module: ModuleType + + @property + def is_const(self) -> bool: + return True + + @property + def column_references(self) -> Tuple[identifiers.ColumnId, ...]: + return () + + @property + def nullable(self) -> bool: + return True # type: ignore + + @property + def is_resolved(self) -> bool: + return False + + @property + def output_type(self) -> dtypes.ExpressionType: + raise ValueError("Module expression does not have a type.") + + def bind_variables( + self, + bindings: Mapping[Hashable, Expression], + allow_partial_bindings: bool = False, + ) -> Expression: + return self + + def bind_refs( + self, + bindings: Mapping[identifiers.ColumnId, Expression], + allow_partial_bindings: bool = False, + ) -> Module: + return self + + @property + def is_bijective(self) -> bool: + # () <-> value + return True + + def transform_children(self, t: Callable[[Expression], Expression]) -> Expression: + return self + + +@dataclasses.dataclass(frozen=True) +class PyObject(Expression): + """An expression representing a module reference.""" + + value: Hashable + + @property + def is_const(self) -> bool: + return True + + @property + def column_references(self) -> Tuple[identifiers.ColumnId, ...]: + return () + + @property + def nullable(self) -> bool: + return True # type: ignore + + @property + def is_resolved(self) -> bool: + return False + + @property + def output_type(self) -> dtypes.ExpressionType: + raise ValueError("PyObject expression does not have a type.") + + def bind_variables( + self, + bindings: Mapping[Hashable, Expression], + allow_partial_bindings: bool = False, + ) -> Expression: + return self + + def bind_refs( + self, + bindings: Mapping[identifiers.ColumnId, Expression], + allow_partial_bindings: bool = False, + ) -> PyObject: + return self + + @property + def is_bijective(self) -> bool: + # () <-> value + return True + + def transform_children(self, t: Callable[[Expression], Expression]) -> Expression: + return self + + +@dataclasses.dataclass(frozen=True) +class Call(Expression): + """An expression representing a scalar constant.""" + + # TODO: Further constrain? + callable: Expression + inputs: Tuple[Expression, ...] + + @property + def column_references( + self, + ) -> Tuple[identifiers.ColumnId, ...]: + return tuple( + itertools.chain.from_iterable( + map(lambda x: x.column_references, self.children) + ) + ) + + @property + def free_variables(self) -> tuple[Hashable, ...]: + return tuple( + itertools.chain.from_iterable( + map(lambda x: x.free_variables, self.children) + ) + ) + + @property + def is_const(self) -> bool: + return False + + @property + def children(self): + return (self.callable, *self.inputs) + + @property + def nullable(self) -> bool: + return True + + @property + def is_resolved(self) -> bool: + return False + + @property + def output_type(self) -> dtypes.ExpressionType: + raise ValueError(f"Type of expression {self} has not been fixed.") + + @property + def is_bijective(self) -> bool: + # TODO: Mark individual functions as bijective? + return False + + @property + def deterministic(self) -> bool: + return True + + def transform_children(self, t: Callable[[Expression], Expression]) -> Expression: + return dataclasses.replace( + self, + callable=t(self.callable), + inputs=tuple(t(input) for input in self.inputs), + ) + + def bind_variables( + self, + bindings: Mapping[Hashable, Expression], + allow_partial_bindings: bool = False, + ) -> Call: + return Call( + callable=self.callable.bind_variables( + bindings, allow_partial_bindings=allow_partial_bindings + ), + inputs=tuple( + input.bind_variables( + bindings, allow_partial_bindings=allow_partial_bindings + ) + for input in self.inputs + ), + ) + + def bind_refs( + self, + bindings: Mapping[identifiers.ColumnId, Expression], + allow_partial_bindings: bool = False, + ) -> Call: + return Call( + callable=self.callable.bind_refs( + bindings, allow_partial_bindings=allow_partial_bindings + ), + inputs=tuple( + input.bind_refs(bindings, allow_partial_bindings=allow_partial_bindings) + for input in self.inputs + ), + ) + + +# TODO: Mode that resolves free variable attrs as columns +def resolve_py_exprs(expression: Expression, unpack_mode: bool = False) -> Expression: + """Replace all PyObject, attribute, call expressions. Bottom-up.""" + + def resolve_expr_if_call(expression: Expression) -> Expression: + if isinstance(expression, Call): + return resolve_call(expression) + return expression + + # this function assumes attrs that become callables have been resolved + # also, we don't yet handle resolving attrs that are column accesses + def resolve_attrs(expression: Expression) -> Expression: + if isinstance(expression, GetAttr): + if isinstance(expression.input, Module): + # resolves things like Math.pi + return PyObject(getattr(expression.input.module, expression.attr)) + if not unpack_mode and isinstance( + expression.input, UnboundVariableExpression + ): + return UnboundVariableExpression(expression.attr) + return expression + + def resolve_pyobjs(expression: Expression) -> Expression: + if isinstance(expression, PyObject): + return const(expression.value) + return expression + + wo_calls = expression.bottom_up(resolve_expr_if_call) + wo_attrs = wo_calls.bottom_up(resolve_attrs) + wo_pyobjs = wo_attrs.bottom_up(resolve_pyobjs) + return wo_pyobjs + + +def resolve_call(call: Call) -> Expression: + callable = call.callable + if isinstance(callable, GetAttr): + attr = callable.attr + if isinstance(callable.input, Module): + fn = getattr(callable.input.module, attr) + if fn in python_op_maps.PYTHON_TO_BIGFRAMES: + op = python_op_maps.PYTHON_TO_BIGFRAMES[fn] + return OpExpression(op, call.inputs) + if fn in _CALLABLE_TO_OP: + op = _CALLABLE_TO_OP[fn] + return OpExpression(op, call.inputs) + elif isinstance(callable, PyObject): + if callable.value in python_op_maps.PYTHON_TO_BIGFRAMES: + op = python_op_maps.PYTHON_TO_BIGFRAMES[callable.value] # type: ignore + return OpExpression(op, call.inputs) + if callable.value in _BUILTIN_CALLABLES: + return OpExpression(_BUILTIN_CALLABLES[callable.value], call.inputs) + + raise NotImplementedError( + f"No implementation available for call expression: {call}" + ) diff --git a/packages/bigframes/noxfile.py b/packages/bigframes/noxfile.py index 7ba8f04d4075..e7c105a552e8 100644 --- a/packages/bigframes/noxfile.py +++ b/packages/bigframes/noxfile.py @@ -123,9 +123,7 @@ # TODO(tswast): Consider removing this when unit_noextras and cover is run # from GitHub actions. "unit_noextras", - "system-3.10", # No extras. "system-3.12", # No extras. - f"system-{DEFAULT_PYTHON_VERSION}", # All extras. "cover", # TODO(b/401609005): remove "cleanup", diff --git a/packages/bigframes/tests/unit/core/test_bytecode.py b/packages/bigframes/tests/unit/core/test_bytecode.py new file mode 100644 index 000000000000..e718d252c601 --- /dev/null +++ b/packages/bigframes/tests/unit/core/test_bytecode.py @@ -0,0 +1,91 @@ +# Copyright 2026 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 math + +import pytest + +import bigframes.core.expression as ex +import bigframes.operations as ops +from bigframes.core.bytecode import dis_to_expr + + +def test_dis_to_expr_simple_arithmetic(): + func = lambda row: row.x + 1 + expr = dis_to_expr(func, unpack_mode=False) + assert expr is not None + + expected = ops.add_op.as_expr(ex.free_var("x"), ex.const(1)) + assert expr == expected + + +def test_dis_to_expr_unpack_mode(): + func = lambda col1, col2: col1 * col2 + expr = dis_to_expr(func, unpack_mode=True) + assert expr is not None + + expected = ops.mul_op.as_expr(ex.free_var("col1"), ex.free_var("col2")) + assert expr == expected + + +def test_dis_to_expr_math_function(): + func = lambda row: math.sin(row.x) + expr = dis_to_expr(func, unpack_mode=False) + assert expr is not None + + expected = ops.numeric_ops.sin_op.as_expr(ex.free_var("x")) + assert expr == expected + + +def test_dis_to_expr_negation(): + func = lambda row: -row.x + expr = dis_to_expr(func, unpack_mode=False) + assert expr is not None + + expected = ops.numeric_ops.neg_op.as_expr(ex.free_var("x")) + assert expr == expected + + +def test_dis_to_expr_comparison(): + func = lambda row: row.x == row.y + expr = dis_to_expr(func, unpack_mode=False) + assert expr is not None + + expected = ops.comparison_ops.eq_op.as_expr(ex.free_var("x"), ex.free_var("y")) + assert expr == expected + + +def test_dis_to_expr_unsupported(): + # Control flow or unsupported structures should return None + def func_with_loop(row): + res = 0 + for val in range(int(row.x)): + res += val + return res + + with pytest.raises(ValueError): + dis_to_expr(func_with_loop, unpack_mode=False) + + +global_none_val = None + + +def test_dis_to_expr_global_none(): + # Test resolving a global variable explicitly set to None + func = lambda row: row.x == global_none_val + expr = dis_to_expr(func, unpack_mode=False) + assert expr is not None + + expected = ops.comparison_ops.eq_op.as_expr(ex.free_var("x"), ex.const(None)) + assert expr == expected From 384724c2d4c955e15274e9824bcdb93c685b79f6 Mon Sep 17 00:00:00 2001 From: Anvit Tawar Date: Tue, 9 Jun 2026 15:27:41 -0400 Subject: [PATCH 051/174] feat: support row_range in sample_row_keys method (#17330) Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly: - [x] Make sure to open an issue as a [bug/issue](https://github.com/googleapis/google-cloud-python/issues) before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea - [x] Ensure the tests and linter pass - [x] Code coverage does not decrease (if any source code was changed) - [x] Appropriate docs were updated (if necessary) Fixes #17329 --- .../cloud/bigtable/data/_async/client.py | 9 +++-- .../bigtable/data/_sync_autogen/client.py | 9 +++-- .../handlers/client_handler_data_async.py | 6 +++- .../client_handler_data_sync_autogen.py | 7 +++- .../tests/system/data/test_system_async.py | 34 +++++++++++++++++++ .../tests/system/data/test_system_autogen.py | 25 ++++++++++++++ .../tests/unit/data/_async/test_client.py | 26 ++++++++++++++ .../unit/data/_sync_autogen/test_client.py | 22 ++++++++++++ 8 files changed, 132 insertions(+), 6 deletions(-) diff --git a/packages/google-cloud-bigtable/google/cloud/bigtable/data/_async/client.py b/packages/google-cloud-bigtable/google/cloud/bigtable/data/_async/client.py index 24da33318677..fefa480e8ad7 100644 --- a/packages/google-cloud-bigtable/google/cloud/bigtable/data/_async/client.py +++ b/packages/google-cloud-bigtable/google/cloud/bigtable/data/_async/client.py @@ -84,7 +84,7 @@ from google.cloud.bigtable.data.execute_query.values import ExecuteQueryValueType from google.cloud.bigtable.data.mutations import Mutation, RowMutationEntry from google.cloud.bigtable.data.read_modify_write_rules import ReadModifyWriteRule -from google.cloud.bigtable.data.read_rows_query import ReadRowsQuery +from google.cloud.bigtable.data.read_rows_query import ReadRowsQuery, RowRange from google.cloud.bigtable.data.row import Row from google.cloud.bigtable.data.row_filters import ( CellsRowLimitFilter, @@ -1412,6 +1412,7 @@ async def row_exists( async def sample_row_keys( self, *, + row_range: RowRange | None = None, operation_timeout: float | TABLE_DEFAULT = TABLE_DEFAULT.DEFAULT, attempt_timeout: float | None | TABLE_DEFAULT = TABLE_DEFAULT.DEFAULT, retryable_errors: Sequence[type[Exception]] @@ -1429,6 +1430,8 @@ async def sample_row_keys( row_keys, along with offset positions in the table Args: + row_range: the range of rows to sample. If not provided, samples the + entire table. operation_timeout: the time budget for the entire operation, in seconds. Failed requests will be retried within the budget.i Defaults to the Table's default_operation_timeout @@ -1466,7 +1469,9 @@ async def sample_row_keys( async def execute_rpc(): results = await self.client._gapic_client.sample_row_keys( request=SampleRowKeysRequest( - app_profile_id=self.app_profile_id, **self._request_path + app_profile_id=self.app_profile_id, + row_range=row_range._to_pb() if row_range is not None else None, + **self._request_path, ), timeout=next(attempt_timeout_gen), retry=None, diff --git a/packages/google-cloud-bigtable/google/cloud/bigtable/data/_sync_autogen/client.py b/packages/google-cloud-bigtable/google/cloud/bigtable/data/_sync_autogen/client.py index 636ea854137d..77d8cd7df7b0 100644 --- a/packages/google-cloud-bigtable/google/cloud/bigtable/data/_sync_autogen/client.py +++ b/packages/google-cloud-bigtable/google/cloud/bigtable/data/_sync_autogen/client.py @@ -85,7 +85,7 @@ from google.cloud.bigtable.data.execute_query.values import ExecuteQueryValueType from google.cloud.bigtable.data.mutations import Mutation, RowMutationEntry from google.cloud.bigtable.data.read_modify_write_rules import ReadModifyWriteRule -from google.cloud.bigtable.data.read_rows_query import ReadRowsQuery +from google.cloud.bigtable.data.read_rows_query import ReadRowsQuery, RowRange from google.cloud.bigtable.data.row import Row from google.cloud.bigtable.data.row_filters import ( CellsRowLimitFilter, @@ -1160,6 +1160,7 @@ def row_exists( def sample_row_keys( self, *, + row_range: RowRange | None = None, operation_timeout: float | TABLE_DEFAULT = TABLE_DEFAULT.DEFAULT, attempt_timeout: float | None | TABLE_DEFAULT = TABLE_DEFAULT.DEFAULT, retryable_errors: Sequence[type[Exception]] @@ -1176,6 +1177,8 @@ def sample_row_keys( row_keys, along with offset positions in the table Args: + row_range: the range of rows to sample. If not provided, samples the + entire table. operation_timeout: the time budget for the entire operation, in seconds. Failed requests will be retried within the budget.i Defaults to the Table's default_operation_timeout @@ -1208,7 +1211,9 @@ def sample_row_keys( def execute_rpc(): results = self.client._gapic_client.sample_row_keys( request=SampleRowKeysRequest( - app_profile_id=self.app_profile_id, **self._request_path + app_profile_id=self.app_profile_id, + row_range=row_range._to_pb() if row_range is not None else None, + **self._request_path, ), timeout=next(attempt_timeout_gen), retry=None, diff --git a/packages/google-cloud-bigtable/test_proxy/handlers/client_handler_data_async.py b/packages/google-cloud-bigtable/test_proxy/handlers/client_handler_data_async.py index 246b7fcd70cc..38084e991514 100644 --- a/packages/google-cloud-bigtable/test_proxy/handlers/client_handler_data_async.py +++ b/packages/google-cloud-bigtable/test_proxy/handlers/client_handler_data_async.py @@ -250,7 +250,11 @@ async def SampleRowKeys(self, request, **kwargs): kwargs["operation_timeout"] = ( kwargs.get("operation_timeout", self.per_operation_timeout) or 20 ) - result = CrossSync.rm_aio(await table.sample_row_keys(**kwargs)) + row_range = None + if "row_range" in request: + from google.cloud.bigtable.data.read_rows_query import RowRange + row_range = RowRange._from_dict(request["row_range"]) + result = CrossSync.rm_aio(await table.sample_row_keys(row_range=row_range, **kwargs)) return result @error_safe diff --git a/packages/google-cloud-bigtable/test_proxy/handlers/client_handler_data_sync_autogen.py b/packages/google-cloud-bigtable/test_proxy/handlers/client_handler_data_sync_autogen.py index b2864db94b21..869014be0598 100644 --- a/packages/google-cloud-bigtable/test_proxy/handlers/client_handler_data_sync_autogen.py +++ b/packages/google-cloud-bigtable/test_proxy/handlers/client_handler_data_sync_autogen.py @@ -187,7 +187,12 @@ async def SampleRowKeys(self, request, **kwargs): kwargs["operation_timeout"] = ( kwargs.get("operation_timeout", self.per_operation_timeout) or 20 ) - result = table.sample_row_keys(**kwargs) + row_range = None + if "row_range" in request: + from google.cloud.bigtable.data.read_rows_query import RowRange + + row_range = RowRange._from_dict(request["row_range"]) + result = table.sample_row_keys(row_range=row_range, **kwargs) return result @error_safe diff --git a/packages/google-cloud-bigtable/tests/system/data/test_system_async.py b/packages/google-cloud-bigtable/tests/system/data/test_system_async.py index b65f05e4bd17..db98cd92b584 100644 --- a/packages/google-cloud-bigtable/tests/system/data/test_system_async.py +++ b/packages/google-cloud-bigtable/tests/system/data/test_system_async.py @@ -346,6 +346,40 @@ async def test_sample_row_keys( assert results[-1][0] == b"" assert isinstance(results[-1][1], int) + @pytest.mark.skipif( + bool(os.environ.get(BIGTABLE_EMULATOR)), reason="emulator doesn't use splits" + ) + @pytest.mark.usefixtures("client") + @pytest.mark.usefixtures("target") + @CrossSync.Retry( + predicate=retry.if_exception_type(ClientError), initial=1, maximum=5 + ) + @CrossSync.pytest + async def test_sample_row_keys_w_row_range( + self, client, target, column_split_config + ): + """ + Sample keys with row range should return samples within the range, + with the last key matching the end of the range. + """ + if len(column_split_config) < 4: + pytest.skip("Not enough splits in column_split_config for this test") + + from google.cloud.bigtable.data import RowRange + + start_key = column_split_config[1] + end_key = column_split_config[3] + row_range = RowRange(start_key=start_key, end_key=end_key) + + results = await target.sample_row_keys(row_range=row_range) + assert len(results) == 2 + + assert results[0][0] == column_split_config[2] + assert results[1][0] == column_split_config[3] + + for _, offset in results: + assert isinstance(offset, int) + @pytest.mark.usefixtures("client") @pytest.mark.usefixtures("target") @CrossSync.pytest diff --git a/packages/google-cloud-bigtable/tests/system/data/test_system_autogen.py b/packages/google-cloud-bigtable/tests/system/data/test_system_autogen.py index c31b2c20a4b8..b6dc02a5564f 100644 --- a/packages/google-cloud-bigtable/tests/system/data/test_system_autogen.py +++ b/packages/google-cloud-bigtable/tests/system/data/test_system_autogen.py @@ -270,6 +270,31 @@ def test_sample_row_keys(self, client, target, temp_rows, column_split_config): assert results[-1][0] == b"" assert isinstance(results[-1][1], int) + @pytest.mark.skipif( + bool(os.environ.get(BIGTABLE_EMULATOR)), reason="emulator doesn't use splits" + ) + @pytest.mark.usefixtures("client") + @pytest.mark.usefixtures("target") + @CrossSync._Sync_Impl.Retry( + predicate=retry.if_exception_type(ClientError), initial=1, maximum=5 + ) + def test_sample_row_keys_w_row_range(self, client, target, column_split_config): + """Sample keys with row range should return samples within the range, + with the last key matching the end of the range.""" + if len(column_split_config) < 4: + pytest.skip("Not enough splits in column_split_config for this test") + from google.cloud.bigtable.data import RowRange + + start_key = column_split_config[1] + end_key = column_split_config[3] + row_range = RowRange(start_key=start_key, end_key=end_key) + results = target.sample_row_keys(row_range=row_range) + assert len(results) == 2 + assert results[0][0] == column_split_config[2] + assert results[1][0] == column_split_config[3] + for _, offset in results: + assert isinstance(offset, int) + @pytest.mark.usefixtures("client") @pytest.mark.usefixtures("target") def test_bulk_mutations_set_cell(self, client, target, temp_rows): diff --git a/packages/google-cloud-bigtable/tests/unit/data/_async/test_client.py b/packages/google-cloud-bigtable/tests/unit/data/_async/test_client.py index 76b7d5c3f3f4..8d2aa9872d01 100644 --- a/packages/google-cloud-bigtable/tests/unit/data/_async/test_client.py +++ b/packages/google-cloud-bigtable/tests/unit/data/_async/test_client.py @@ -2451,6 +2451,32 @@ async def test_sample_row_keys(self): assert result[1] == samples[1] assert result[2] == samples[2] + @CrossSync.pytest + async def test_sample_row_keys_w_row_range(self): + """ + Test that method returns the expected key samples when row_range is provided + """ + samples = [ + (b"a_key1", 100), + (b"b", 200), + ] + from google.cloud.bigtable.data import RowRange + + row_range = RowRange(start_key=b"a", end_key=b"b") + async with self._make_client() as client: + async with client.get_table("instance", "table") as table: + with mock.patch.object( + table.client._gapic_client, "sample_row_keys", CrossSync.Mock() + ) as sample_row_keys: + sample_row_keys.return_value = self._make_gapic_stream(samples) + result = await table.sample_row_keys(row_range=row_range) + assert len(result) == 2 + assert result[0] == samples[0] + assert result[1] == samples[1] + sample_row_keys.assert_called_once() + called_request = sample_row_keys.call_args[1]["request"] + assert called_request.row_range == row_range._to_pb() + @CrossSync.pytest async def test_sample_row_keys_bad_timeout(self): """ diff --git a/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_client.py b/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_client.py index 9a7939ce7c1c..ca5158381774 100644 --- a/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_client.py +++ b/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_client.py @@ -2030,6 +2030,28 @@ def test_sample_row_keys(self): assert result[1] == samples[1] assert result[2] == samples[2] + def test_sample_row_keys_w_row_range(self): + """Test that method returns the expected key samples when row_range is provided""" + samples = [(b"a_key1", 100), (b"b", 200)] + from google.cloud.bigtable.data import RowRange + + row_range = RowRange(start_key=b"a", end_key=b"b") + with self._make_client() as client: + with client.get_table("instance", "table") as table: + with mock.patch.object( + table.client._gapic_client, + "sample_row_keys", + CrossSync._Sync_Impl.Mock(), + ) as sample_row_keys: + sample_row_keys.return_value = self._make_gapic_stream(samples) + result = table.sample_row_keys(row_range=row_range) + assert len(result) == 2 + assert result[0] == samples[0] + assert result[1] == samples[1] + sample_row_keys.assert_called_once() + called_request = sample_row_keys.call_args[1]["request"] + assert called_request.row_range == row_range._to_pb() + def test_sample_row_keys_bad_timeout(self): """should raise error if timeout is negative""" with self._make_client() as client: From 3a90cc8e867c8a2d2f8060858fde9eda94f80a54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Swe=C3=B1a=20=28Swast=29?= Date: Wed, 10 Jun 2026 09:27:48 -0500 Subject: [PATCH 052/174] fix(bigframes): improve error message when unescaped `{` are found in SQL cells (#17346) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hints to the user that they may need to escape `{` and `}` characters by doubling them, and includes context as to where to correct such errors. Fixes internal issue b/517909919 🦕 --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- packages/bigframes/bigframes/core/pyformat.py | 187 +++++++++++++++++- .../tests/unit/core/test_pyformat.py | 132 ++++++++++++- 2 files changed, 312 insertions(+), 7 deletions(-) diff --git a/packages/bigframes/bigframes/core/pyformat.py b/packages/bigframes/bigframes/core/pyformat.py index 8f3c94054094..dfd91ba1ad00 100644 --- a/packages/bigframes/bigframes/core/pyformat.py +++ b/packages/bigframes/bigframes/core/pyformat.py @@ -162,6 +162,160 @@ def _parse_fields(sql_template: str) -> list[str]: ] +def _is_escaped_open_brace(sql_template: str, idx: int, literal_char: str) -> bool: + """Checks if the character at idx in sql_template is an escaped open brace '{{'.""" + return sql_template[idx : idx + 2] == "{{" and literal_char == "{" + + +def _is_escaped_close_brace(sql_template: str, idx: int, literal_char: str) -> bool: + """Checks if the character at idx in sql_template is an escaped close brace '}}'.""" + return sql_template[idx : idx + 2] == "}}" and literal_char == "}" + + +def _consume_literal(sql_template: str, current_idx: int, literal_text: str) -> int: + """Advances current_idx past literal_text in sql_template, accounting for escaped braces. + + A **literal** (or literal text) is the static part of the template string that + does not contain formatting placeholders. The string.Formatter parser resolves + escaped braces ('{{' and '}}') into single braces ('{' and '}') in its output + literal_text. + + This function aligns the resolved literal_text back to the original + sql_template by consuming 2 characters from sql_template ('{{' or '}}') for + every single escaped brace character in literal_text, and 1 character for + everything else. + + Returns: + int: the advanced current_idx in sql_template. + """ + lit_idx = 0 + while lit_idx < len(literal_text): + if _is_escaped_open_brace(sql_template, current_idx, literal_text[lit_idx]): + current_idx += 2 + lit_idx += 1 + elif _is_escaped_close_brace(sql_template, current_idx, literal_text[lit_idx]): + current_idx += 2 + lit_idx += 1 + elif ( + current_idx < len(sql_template) + and sql_template[current_idx] == literal_text[lit_idx] + ): + current_idx += 1 + lit_idx += 1 + else: + raise RuntimeError( + "Internal error: failed to align parsed SQL template with original query. " + f"Expected {literal_text[lit_idx]!r} at position {current_idx} in template, " + f"but found {sql_template[current_idx : current_idx + 2]!r}." + ) + return current_idx + + +def _is_escaped_brace(sql_template: str, idx: int) -> bool: + """Checks if the template has an escaped brace ('{{' or '}}') at the given index.""" + return sql_template[idx : idx + 2] in ("{{", "}}") + + +def _advance_past_field(sql_template: str, current_idx: int) -> int: + """Advances current_idx past the format field starting at current_idx. + + A **field** (or replacement field) is a placeholder in the template enclosed + in braces (e.g., "{my_var}" or "{json_col: { "val": 1 } }"). + + This function assumes current_idx points to the opening '{' of a field. + It parses forward, tracking nested braces to find the matching closing '}' + that terminates the field, while ignoring escaped braces ('{{' and '}}') + which do not affect the nesting level. + + Returns: + int: the index immediately after the closing '}' of the field. + """ + assert sql_template[current_idx] == "{" + brace_count = 1 + current_idx += 1 # past '{' + + while brace_count > 0 and current_idx < len(sql_template): + if _is_escaped_brace(sql_template, current_idx): + current_idx += 2 + elif sql_template[current_idx] == "{": + brace_count += 1 + current_idx += 1 + elif sql_template[current_idx] == "}": + brace_count -= 1 + current_idx += 1 + else: + current_idx += 1 + + return current_idx + + +def _find_all_field_positions(sql_template: str) -> dict[tuple[str, int], int]: + """Finds the character positions of all fields in the sql_template. + + Returns: + dict: a dict mapping (field_name, occurrence_idx) to character index. + """ + formatter = string.Formatter() + current_idx = 0 + seen_counts: dict[str, int] = {} + positions: dict[tuple[str, int], int] = {} + + for literal_text, field_name, _, _ in formatter.parse(sql_template): + current_idx = _consume_literal(sql_template, current_idx, literal_text) + + if field_name is not None: + occurrence_idx = seen_counts.get(field_name, 0) + seen_counts[field_name] = occurrence_idx + 1 + + positions[(field_name, occurrence_idx)] = current_idx + + current_idx = _advance_past_field(sql_template, current_idx) + + return positions + + +def get_error_context_at_pos(sql_template: str, pos: int) -> str: + """Create a helpful 'pointer' to where the problematic position is + in the original SQL. + + This should make the error message a lot friendlier, by providing more + context towards the problematic syntax. + """ + if pos == -1: + return "" + + lines = sql_template.splitlines(keepends=True) + + char_count = 0 + target_line_idx = -1 + for i, line in enumerate(lines): + if char_count <= pos < char_count + len(line): + target_line_idx = i + break + char_count += len(line) + + if target_line_idx == -1: + return "" + + col_offset = pos - char_count + + context_lines = [] + start_line = max(0, target_line_idx - 2) + end_line = min(len(lines), target_line_idx + 3) + + for i in range(start_line, end_line): + line_num = i + 1 + line_content = lines[i].rstrip("\r\n") + if i == target_line_idx: + context_lines.append(f"{line_num:4d}: {line_content}") + indent = 6 + col_offset + context_lines.append(" " * indent + "^") + else: + context_lines.append(f"{line_num:4d}: {line_content}") + + return "\n".join(context_lines) + + def pyformat( sql_template: str, *, @@ -185,13 +339,36 @@ def pyformat( Raises: TypeError: if a referenced variable is not of a supported type. - KeyError: if a referenced variable is not found. + ValueError: + if a referenced variable is not found (KeyError is caught and raised + as ValueError with context). """ - fields = _parse_fields(sql_template) - - format_kwargs = {} + try: + fields = _parse_fields(sql_template) + except ValueError as e: + raise ValueError( + "Failed to parse SQL template. " + "Did you mean to escape '{' and '}' by doubling them?\n" + f"Error details: {e}" + ) from e + + format_kwargs: dict[str, str] = {} + seen_counts: dict[str, int] = {} for name in fields: - value = pyformat_args[name] + seen_counts[name] = seen_counts.get(name, 0) + 1 + try: + value = pyformat_args[name] + except KeyError as e: + positions = _find_all_field_positions(sql_template) + occurrence_idx = seen_counts[name] - 1 + pos = positions.get((name, occurrence_idx), -1) + context = get_error_context_at_pos(sql_template, pos) + raise ValueError( + f"Undetected variable {name!r} in SQL template. " + "Did you mean to escape '{' and '}' by doubling them?\n" + f"{context}" + ) from e + format_kwargs[name] = _field_to_template_value( name, value, session=session, dry_run=dry_run ) diff --git a/packages/bigframes/tests/unit/core/test_pyformat.py b/packages/bigframes/tests/unit/core/test_pyformat.py index be7f52f4d5d4..239a59237f63 100644 --- a/packages/bigframes/tests/unit/core/test_pyformat.py +++ b/packages/bigframes/tests/unit/core/test_pyformat.py @@ -62,6 +62,72 @@ def test_parse_fields(sql_template: str, expected: List[str]): assert fields == expected +def test_get_error_context_at_pos_invalid_pos(): + assert pyformat.get_error_context_at_pos("SELECT 1", -1) == "" + assert pyformat.get_error_context_at_pos("SELECT 1", 100) == "" + + +def test_get_error_context_at_pos_single_line(): + sql = "SELECT {foo}" + # pos of '{' is 7 + context = pyformat.get_error_context_at_pos(sql, 7) + expected = " 1: SELECT {foo}\n ^" + assert context == expected + + +def test_get_error_context_at_pos_multi_line(): + sql = "SELECT 1\nFROM my_table\nWHERE col = {foo}\nAND active = True\nLIMIT 10" + # Lines: + # 1: SELECT 1 (len 9 including \n) + # 2: FROM my_table (len 14 including \n) -> total 23 + # 3: WHERE col = {foo} -> '{' is at 23 + 12 = 35 + + context = pyformat.get_error_context_at_pos(sql, 35) + expected = ( + " 1: SELECT 1\n" + " 2: FROM my_table\n" + " 3: WHERE col = {foo}\n" + " ^\n" + " 4: AND active = True\n" + " 5: LIMIT 10" + ) + assert context == expected + + +def test_get_error_context_at_pos_multi_line_limits(): + # Test that it only shows at most 2 lines before and 2 lines after + sql = ( + "LINE 1\n" + "LINE 2\n" + "LINE 3\n" + "LINE 4\n" + "LINE 5\n" + "TARGET {foo}\n" + "LINE 7\n" + "LINE 8\n" + "LINE 9\n" + "LINE 10" + ) + # Line lengths: + # LINE 1\n (7) + # LINE 2\n (7) -> 14 + # LINE 3\n (7) -> 21 + # LINE 4\n (7) -> 28 + # LINE 5\n (7) -> 35 + # TARGET {foo}\n -> '{' is at 35 + 7 = 42 + + context = pyformat.get_error_context_at_pos(sql, 42) + expected = ( + " 4: LINE 4\n" + " 5: LINE 5\n" + " 6: TARGET {foo}\n" + " ^\n" + " 7: LINE 7\n" + " 8: LINE 8" + ) + assert context == expected + + def test_pyformat_with_unsupported_type_raises_typeerror(session): pyformat_args = {"my_object": object()} sql = "SELECT {my_object}" @@ -70,13 +136,75 @@ def test_pyformat_with_unsupported_type_raises_typeerror(session): pyformat.pyformat(sql, pyformat_args=pyformat_args, session=session) -def test_pyformat_with_missing_variable_raises_keyerror(session): +def test_pyformat_with_missing_variable_raises_valueerror(session): pyformat_args: Dict[str, Any] = {} sql = "SELECT {my_object}" - with pytest.raises(KeyError, match="my_object"): + with pytest.raises(ValueError) as exc_info: pyformat.pyformat(sql, pyformat_args=pyformat_args, session=session) + err_msg = str(exc_info.value) + assert "Undetected variable 'my_object' in SQL template" in err_msg + assert "Did you mean to escape '{' and '}'" in err_msg + assert " 1: SELECT {my_object}" in err_msg + assert " ^" in err_msg + + +def test_pyformat_with_unescaped_braces_raises_valueerror_with_context(session): + pyformat_args = {"active": True} + sql = """SELECT * FROM my_table +WHERE json_col = { "generation_config": { "temperature": 0.9 } } +AND active = {active} +""" + + with pytest.raises(ValueError) as exc_info: + pyformat.pyformat(sql, pyformat_args=pyformat_args, session=session) + + err_msg = str(exc_info.value) + assert "Undetected variable ' \"generation_config\"' in SQL template" in err_msg + assert "Did you mean to escape '{' and '}'" in err_msg + # The triple quote string starts with SELECT immediately, so lines are: + # 1: SELECT * FROM my_table + # 2: WHERE json_col = { "generation_config": { "temperature": 0.9 } } + # 3: AND active = {active} + assert " 1: SELECT * FROM my_table" in err_msg + assert ( + ' 2: WHERE json_col = { "generation_config": { "temperature": 0.9 } }' + in err_msg + ) + assert " ^" in err_msg + assert " 3: AND active = {active}" in err_msg + + +@pytest.mark.parametrize( + ("sql_template", "expected_error"), + ( + pytest.param( + "SELECT {foo", + "expected '}' before end of string", + id="missing_closing_brace", + ), + pytest.param( + "SELECT foo}", + "Single '}' encountered in format string", + id="missing_opening_brace", + ), + ), +) +def test_pyformat_with_malformed_template_raises_valueerror( + session, sql_template: str, expected_error: str +): + pyformat_args: Dict[str, Any] = {} + + # Case 1: Single '{' (unmatched) + with pytest.raises(ValueError) as exc_info: + pyformat.pyformat(sql_template, pyformat_args=pyformat_args, session=session) + + error_message = str(exc_info.value) + assert "Failed to parse SQL template" in error_message + assert "Did you mean to escape '{' and '}'" in error_message + assert expected_error in error_message + def test_pyformat_with_no_variables(session): pyformat_args: Dict[str, Any] = {} From 1b8892956d2b1814830a81ab52f8138ee6710944 Mon Sep 17 00:00:00 2001 From: sofisl <55454395+sofisl@users.noreply.github.com> Date: Wed, 10 Jun 2026 09:41:15 -0700 Subject: [PATCH 053/174] chore: update librarian to v0.19.0 (#17410) --- librarian.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librarian.yaml b/librarian.yaml index 0bf20ac53fc2..7cc0c054d524 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. language: python -version: v0.16.1-0.20260608172125-d123ec9cac76 +version: v0.19.0 repo: googleapis/google-cloud-python sources: googleapis: From ca02afce77af166d9e69cd65caf94fe5db505b30 Mon Sep 17 00:00:00 2001 From: sofisl <55454395+sofisl@users.noreply.github.com> Date: Wed, 10 Jun 2026 16:43:52 -0700 Subject: [PATCH 054/174] feat(google/developers/knowledge/v1): add google-developer-knowledge (#17417) FIxes b/503382870 --- .librarian/state.yaml | 14 +++--- librarian.yaml | 4 +- .../.coveragerc | 4 +- .../.flake8 | 0 .../.repo-metadata.json | 6 +-- .../google-developer-knowledge/CHANGELOG.md | 5 ++ .../LICENSE | 0 .../MANIFEST.in | 0 .../README.rst | 16 +++--- .../docs/CHANGELOG.md | 0 .../docs/README.rst | 16 +++--- .../docs/_static/custom.css | 0 .../docs/_templates/layout.html | 0 .../docs/conf.py | 24 ++++----- .../developer_knowledge.rst | 10 ++++ .../docs/developer_knowledge_v1/services_.rst | 6 +++ .../docs/developer_knowledge_v1/types_.rst | 6 +++ .../docs/index.rst | 6 +-- .../docs/multiprocessing.rst | 0 .../google/developer_knowledge}/__init__.py | 8 +-- .../developer_knowledge}/gapic_version.py | 0 .../google/developer_knowledge/py.typed | 2 + .../developer_knowledge_v1}/__init__.py | 8 +-- .../gapic_metadata.json | 2 +- .../developer_knowledge_v1}/gapic_version.py | 0 .../google/developer_knowledge_v1/py.typed | 2 + .../services/__init__.py | 0 .../services/developer_knowledge/__init__.py | 0 .../developer_knowledge/async_client.py | 36 ++++++------- .../services/developer_knowledge/client.py | 36 ++++++------- .../services/developer_knowledge/pagers.py | 18 +++---- .../developer_knowledge/transports/README.rst | 0 .../transports/__init__.py | 0 .../developer_knowledge/transports/base.py | 4 +- .../developer_knowledge/transports/grpc.py | 2 +- .../transports/grpc_asyncio.py | 2 +- .../developer_knowledge/transports/rest.py | 2 +- .../transports/rest_base.py | 2 +- .../developer_knowledge_v1}/types/__init__.py | 0 .../types/developerknowledge.py | 12 ++--- .../mypy.ini | 0 .../noxfile.py | 2 +- ...per_knowledge_batch_get_documents_async.py | 8 +-- ...oper_knowledge_batch_get_documents_sync.py | 8 +-- ..._developer_knowledge_get_document_async.py | 8 +-- ...d_developer_knowledge_get_document_sync.py | 8 +-- ..._knowledge_search_document_chunks_async.py | 8 +-- ...r_knowledge_search_document_chunks_sync.py | 8 +-- ...tadata_google.developers.knowledge.v1.json | 50 +++++++++---------- .../setup.py | 8 +-- .../testing/constraints-3.10.txt | 0 .../testing/constraints-3.11.txt | 0 .../testing/constraints-3.12.txt | 0 .../testing/constraints-3.13.txt | 0 .../testing/constraints-3.14.txt | 0 .../tests/__init__.py | 0 .../tests/unit/__init__.py | 0 .../tests/unit/gapic/__init__.py | 0 .../gapic/developer_knowledge_v1}/__init__.py | 0 .../test_developer_knowledge.py | 12 ++--- .../google-developers-knowledge/CHANGELOG.md | 5 -- .../developer_knowledge.rst | 10 ---- .../developers_knowledge_v1/services_.rst | 6 --- .../docs/developers_knowledge_v1/types_.rst | 6 --- .../google/developers_knowledge/py.typed | 2 - .../google/developers_knowledge_v1/py.typed | 2 - 66 files changed, 202 insertions(+), 202 deletions(-) rename packages/{google-developers-knowledge => google-developer-knowledge}/.coveragerc (65%) rename packages/{google-developers-knowledge => google-developer-knowledge}/.flake8 (100%) rename packages/{google-developers-knowledge => google-developer-knowledge}/.repo-metadata.json (83%) create mode 100644 packages/google-developer-knowledge/CHANGELOG.md rename packages/{google-developers-knowledge => google-developer-knowledge}/LICENSE (100%) rename packages/{google-developers-knowledge => google-developer-knowledge}/MANIFEST.in (100%) rename packages/{google-developers-knowledge => google-developer-knowledge}/README.rst (95%) rename packages/{google-developers-knowledge => google-developer-knowledge}/docs/CHANGELOG.md (100%) rename packages/{google-developers-knowledge => google-developer-knowledge}/docs/README.rst (95%) rename packages/{google-developers-knowledge => google-developer-knowledge}/docs/_static/custom.css (100%) rename packages/{google-developers-knowledge => google-developer-knowledge}/docs/_templates/layout.html (100%) rename packages/{google-developers-knowledge => google-developer-knowledge}/docs/conf.py (95%) create mode 100644 packages/google-developer-knowledge/docs/developer_knowledge_v1/developer_knowledge.rst create mode 100644 packages/google-developer-knowledge/docs/developer_knowledge_v1/services_.rst create mode 100644 packages/google-developer-knowledge/docs/developer_knowledge_v1/types_.rst rename packages/{google-developers-knowledge => google-developer-knowledge}/docs/index.rst (58%) rename packages/{google-developers-knowledge => google-developer-knowledge}/docs/multiprocessing.rst (100%) rename packages/{google-developers-knowledge/google/developers_knowledge => google-developer-knowledge/google/developer_knowledge}/__init__.py (79%) rename packages/{google-developers-knowledge/google/developers_knowledge => google-developer-knowledge/google/developer_knowledge}/gapic_version.py (100%) create mode 100644 packages/google-developer-knowledge/google/developer_knowledge/py.typed rename packages/{google-developers-knowledge/google/developers_knowledge_v1 => google-developer-knowledge/google/developer_knowledge_v1}/__init__.py (94%) rename packages/{google-developers-knowledge/google/developers_knowledge_v1 => google-developer-knowledge/google/developer_knowledge_v1}/gapic_metadata.json (97%) rename packages/{google-developers-knowledge/google/developers_knowledge_v1 => google-developer-knowledge/google/developer_knowledge_v1}/gapic_version.py (100%) create mode 100644 packages/google-developer-knowledge/google/developer_knowledge_v1/py.typed rename packages/{google-developers-knowledge/google/developers_knowledge_v1 => google-developer-knowledge/google/developer_knowledge_v1}/services/__init__.py (100%) rename packages/{google-developers-knowledge/google/developers_knowledge_v1 => google-developer-knowledge/google/developer_knowledge_v1}/services/developer_knowledge/__init__.py (100%) rename packages/{google-developers-knowledge/google/developers_knowledge_v1 => google-developer-knowledge/google/developer_knowledge_v1}/services/developer_knowledge/async_client.py (94%) rename packages/{google-developers-knowledge/google/developers_knowledge_v1 => google-developer-knowledge/google/developer_knowledge_v1}/services/developer_knowledge/client.py (96%) rename packages/{google-developers-knowledge/google/developers_knowledge_v1 => google-developer-knowledge/google/developer_knowledge_v1}/services/developer_knowledge/pagers.py (90%) rename packages/{google-developers-knowledge/google/developers_knowledge_v1 => google-developer-knowledge/google/developer_knowledge_v1}/services/developer_knowledge/transports/README.rst (100%) rename packages/{google-developers-knowledge/google/developers_knowledge_v1 => google-developer-knowledge/google/developer_knowledge_v1}/services/developer_knowledge/transports/__init__.py (100%) rename packages/{google-developers-knowledge/google/developers_knowledge_v1 => google-developer-knowledge/google/developer_knowledge_v1}/services/developer_knowledge/transports/base.py (98%) rename packages/{google-developers-knowledge/google/developers_knowledge_v1 => google-developer-knowledge/google/developer_knowledge_v1}/services/developer_knowledge/transports/grpc.py (99%) rename packages/{google-developers-knowledge/google/developers_knowledge_v1 => google-developer-knowledge/google/developer_knowledge_v1}/services/developer_knowledge/transports/grpc_asyncio.py (99%) rename packages/{google-developers-knowledge/google/developers_knowledge_v1 => google-developer-knowledge/google/developer_knowledge_v1}/services/developer_knowledge/transports/rest.py (99%) rename packages/{google-developers-knowledge/google/developers_knowledge_v1 => google-developer-knowledge/google/developer_knowledge_v1}/services/developer_knowledge/transports/rest_base.py (99%) rename packages/{google-developers-knowledge/google/developers_knowledge_v1 => google-developer-knowledge/google/developer_knowledge_v1}/types/__init__.py (100%) rename packages/{google-developers-knowledge/google/developers_knowledge_v1 => google-developer-knowledge/google/developer_knowledge_v1}/types/developerknowledge.py (97%) rename packages/{google-developers-knowledge => google-developer-knowledge}/mypy.ini (100%) rename packages/{google-developers-knowledge => google-developer-knowledge}/noxfile.py (99%) rename packages/{google-developers-knowledge => google-developer-knowledge}/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_batch_get_documents_async.py (88%) rename packages/{google-developers-knowledge => google-developer-knowledge}/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_batch_get_documents_sync.py (88%) rename packages/{google-developers-knowledge => google-developer-knowledge}/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_get_document_async.py (88%) rename packages/{google-developers-knowledge => google-developer-knowledge}/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_get_document_sync.py (88%) rename packages/{google-developers-knowledge => google-developer-knowledge}/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_search_document_chunks_async.py (88%) rename packages/{google-developers-knowledge => google-developer-knowledge}/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_search_document_chunks_sync.py (88%) rename packages/{google-developers-knowledge => google-developer-knowledge}/samples/generated_samples/snippet_metadata_google.developers.knowledge.v1.json (84%) rename packages/{google-developers-knowledge => google-developer-knowledge}/setup.py (93%) rename packages/{google-developers-knowledge => google-developer-knowledge}/testing/constraints-3.10.txt (100%) rename packages/{google-developers-knowledge => google-developer-knowledge}/testing/constraints-3.11.txt (100%) rename packages/{google-developers-knowledge => google-developer-knowledge}/testing/constraints-3.12.txt (100%) rename packages/{google-developers-knowledge => google-developer-knowledge}/testing/constraints-3.13.txt (100%) rename packages/{google-developers-knowledge => google-developer-knowledge}/testing/constraints-3.14.txt (100%) rename packages/{google-developers-knowledge => google-developer-knowledge}/tests/__init__.py (100%) rename packages/{google-developers-knowledge => google-developer-knowledge}/tests/unit/__init__.py (100%) rename packages/{google-developers-knowledge => google-developer-knowledge}/tests/unit/gapic/__init__.py (100%) rename packages/{google-developers-knowledge/tests/unit/gapic/developers_knowledge_v1 => google-developer-knowledge/tests/unit/gapic/developer_knowledge_v1}/__init__.py (100%) rename packages/{google-developers-knowledge/tests/unit/gapic/developers_knowledge_v1 => google-developer-knowledge/tests/unit/gapic/developer_knowledge_v1}/test_developer_knowledge.py (99%) delete mode 100644 packages/google-developers-knowledge/CHANGELOG.md delete mode 100644 packages/google-developers-knowledge/docs/developers_knowledge_v1/developer_knowledge.rst delete mode 100644 packages/google-developers-knowledge/docs/developers_knowledge_v1/services_.rst delete mode 100644 packages/google-developers-knowledge/docs/developers_knowledge_v1/types_.rst delete mode 100644 packages/google-developers-knowledge/google/developers_knowledge/py.typed delete mode 100644 packages/google-developers-knowledge/google/developers_knowledge_v1/py.typed diff --git a/.librarian/state.yaml b/.librarian/state.yaml index c2472c8546cb..d69a10f8d167 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -5420,21 +5420,21 @@ libraries: - packages/google-crc32c/README.rst - packages/google-crc32c/docs/ tag_format: '{id}-v{version}' - - id: google-developers-knowledge + - id: google-developer-knowledge version: 0.0.0 last_generated_commit: "" apis: - path: google/developers/knowledge/v1 source_roots: - - packages/google-developers-knowledge + - packages/google-developer-knowledge preserve_regex: [] remove_regex: [] release_exclude_paths: - - packages/google-developers-knowledge/.repo-metadata.json - - packages/google-developers-knowledge/noxfile.py - - packages/google-developers-knowledge/tests/ - - packages/google-developers-knowledge/README.rst - - packages/google-developers-knowledge/docs/ + - packages/google-developer-knowledge/.repo-metadata.json + - packages/google-developer-knowledge/noxfile.py + - packages/google-developer-knowledge/tests/ + - packages/google-developer-knowledge/README.rst + - packages/google-developer-knowledge/docs/ tag_format: '{id}-v{version}' - id: google-devicesandservices-health version: 0.1.0 diff --git a/librarian.yaml b/librarian.yaml index 7cc0c054d524..b14185f4a14c 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -2226,7 +2226,7 @@ libraries: skip_release: true python: library_type: OTHER - - name: google-developers-knowledge + - name: google-developer-knowledge version: 0.0.0 apis: - path: google/developers/knowledge/v1 @@ -2235,7 +2235,7 @@ libraries: opt_args_by_api: google/developers/knowledge/v1: - python-gapic-namespace=google - - python-gapic-name=developers_knowledge + - python-gapic-name=developer_knowledge default_version: v1 - name: google-devicesandservices-health version: 0.1.0 diff --git a/packages/google-developers-knowledge/.coveragerc b/packages/google-developer-knowledge/.coveragerc similarity index 65% rename from packages/google-developers-knowledge/.coveragerc rename to packages/google-developer-knowledge/.coveragerc index 2eb560db0b14..d34e3e6c67a9 100644 --- a/packages/google-developers-knowledge/.coveragerc +++ b/packages/google-developer-knowledge/.coveragerc @@ -4,8 +4,8 @@ branch = True [report] show_missing = True omit = - google/developers_knowledge/__init__.py - google/developers_knowledge/gapic_version.py + google/developer_knowledge/__init__.py + google/developer_knowledge/gapic_version.py exclude_lines = # Re-enable the standard pragma pragma: NO COVER diff --git a/packages/google-developers-knowledge/.flake8 b/packages/google-developer-knowledge/.flake8 similarity index 100% rename from packages/google-developers-knowledge/.flake8 rename to packages/google-developer-knowledge/.flake8 diff --git a/packages/google-developers-knowledge/.repo-metadata.json b/packages/google-developer-knowledge/.repo-metadata.json similarity index 83% rename from packages/google-developers-knowledge/.repo-metadata.json rename to packages/google-developer-knowledge/.repo-metadata.json index 4195a25dae2a..01dce5bb220a 100644 --- a/packages/google-developers-knowledge/.repo-metadata.json +++ b/packages/google-developer-knowledge/.repo-metadata.json @@ -2,13 +2,13 @@ "api_description": "The Developer Knowledge API provides access to Google's developer knowledge.", "api_id": "developerknowledge.googleapis.com", "api_shortname": "developerknowledge", - "client_documentation": "https://googleapis.dev/python/google-developers-knowledge/latest", + "client_documentation": "https://googleapis.dev/python/google-developer-knowledge/latest", "default_version": "v1", - "distribution_name": "google-developers-knowledge", + "distribution_name": "google-developer-knowledge", "issue_tracker": "https://issuetracker.google.com/issues/new?component=190865\u0026template=1161103", "language": "python", "library_type": "GAPIC_AUTO", - "name": "google-developers-knowledge", + "name": "google-developer-knowledge", "name_pretty": "Developer Knowledge", "product_documentation": "https://developers.google.com/knowledge", "release_level": "preview", diff --git a/packages/google-developer-knowledge/CHANGELOG.md b/packages/google-developer-knowledge/CHANGELOG.md new file mode 100644 index 000000000000..da1b0f4b4eb8 --- /dev/null +++ b/packages/google-developer-knowledge/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +[PyPI History][1] + +[1]: https://pypi.org/project/google-developer-knowledge/#history diff --git a/packages/google-developers-knowledge/LICENSE b/packages/google-developer-knowledge/LICENSE similarity index 100% rename from packages/google-developers-knowledge/LICENSE rename to packages/google-developer-knowledge/LICENSE diff --git a/packages/google-developers-knowledge/MANIFEST.in b/packages/google-developer-knowledge/MANIFEST.in similarity index 100% rename from packages/google-developers-knowledge/MANIFEST.in rename to packages/google-developer-knowledge/MANIFEST.in diff --git a/packages/google-developers-knowledge/README.rst b/packages/google-developer-knowledge/README.rst similarity index 95% rename from packages/google-developers-knowledge/README.rst rename to packages/google-developer-knowledge/README.rst index c11f928f2ee9..db9b1db7212e 100644 --- a/packages/google-developers-knowledge/README.rst +++ b/packages/google-developer-knowledge/README.rst @@ -10,12 +10,12 @@ Python Client for Developer Knowledge .. |preview| image:: https://img.shields.io/badge/support-preview-orange.svg :target: https://github.com/googleapis/google-cloud-python/blob/main/README.rst#stability-levels -.. |pypi| image:: https://img.shields.io/pypi/v/google-developers-knowledge.svg - :target: https://pypi.org/project/google-developers-knowledge/ -.. |versions| image:: https://img.shields.io/pypi/pyversions/google-developers-knowledge.svg - :target: https://pypi.org/project/google-developers-knowledge/ +.. |pypi| image:: https://img.shields.io/pypi/v/google-developer-knowledge.svg + :target: https://pypi.org/project/google-developer-knowledge/ +.. |versions| image:: https://img.shields.io/pypi/pyversions/google-developer-knowledge.svg + :target: https://pypi.org/project/google-developer-knowledge/ .. _Developer Knowledge: https://developers.google.com/knowledge -.. _Client Library Documentation: https://googleapis.dev/python/google-developers-knowledge/latest +.. _Client Library Documentation: https://googleapis.dev/python/google-developer-knowledge/latest .. _Product Documentation: https://developers.google.com/knowledge Quick Start @@ -53,7 +53,7 @@ Code samples and snippets Code samples and snippets live in the `samples/`_ folder. -.. _samples/: https://github.com/googleapis/google-cloud-python/tree/main/packages/google-developers-knowledge/samples +.. _samples/: https://github.com/googleapis/google-cloud-python/tree/main/packages/google-developer-knowledge/samples Supported Python Versions @@ -83,7 +83,7 @@ Mac/Linux python3 -m venv source /bin/activate - pip install google-developers-knowledge + pip install google-developer-knowledge Windows @@ -93,7 +93,7 @@ Windows py -m venv .\\Scripts\activate - pip install google-developers-knowledge + pip install google-developer-knowledge Next Steps ~~~~~~~~~~ diff --git a/packages/google-developers-knowledge/docs/CHANGELOG.md b/packages/google-developer-knowledge/docs/CHANGELOG.md similarity index 100% rename from packages/google-developers-knowledge/docs/CHANGELOG.md rename to packages/google-developer-knowledge/docs/CHANGELOG.md diff --git a/packages/google-developers-knowledge/docs/README.rst b/packages/google-developer-knowledge/docs/README.rst similarity index 95% rename from packages/google-developers-knowledge/docs/README.rst rename to packages/google-developer-knowledge/docs/README.rst index c11f928f2ee9..db9b1db7212e 100644 --- a/packages/google-developers-knowledge/docs/README.rst +++ b/packages/google-developer-knowledge/docs/README.rst @@ -10,12 +10,12 @@ Python Client for Developer Knowledge .. |preview| image:: https://img.shields.io/badge/support-preview-orange.svg :target: https://github.com/googleapis/google-cloud-python/blob/main/README.rst#stability-levels -.. |pypi| image:: https://img.shields.io/pypi/v/google-developers-knowledge.svg - :target: https://pypi.org/project/google-developers-knowledge/ -.. |versions| image:: https://img.shields.io/pypi/pyversions/google-developers-knowledge.svg - :target: https://pypi.org/project/google-developers-knowledge/ +.. |pypi| image:: https://img.shields.io/pypi/v/google-developer-knowledge.svg + :target: https://pypi.org/project/google-developer-knowledge/ +.. |versions| image:: https://img.shields.io/pypi/pyversions/google-developer-knowledge.svg + :target: https://pypi.org/project/google-developer-knowledge/ .. _Developer Knowledge: https://developers.google.com/knowledge -.. _Client Library Documentation: https://googleapis.dev/python/google-developers-knowledge/latest +.. _Client Library Documentation: https://googleapis.dev/python/google-developer-knowledge/latest .. _Product Documentation: https://developers.google.com/knowledge Quick Start @@ -53,7 +53,7 @@ Code samples and snippets Code samples and snippets live in the `samples/`_ folder. -.. _samples/: https://github.com/googleapis/google-cloud-python/tree/main/packages/google-developers-knowledge/samples +.. _samples/: https://github.com/googleapis/google-cloud-python/tree/main/packages/google-developer-knowledge/samples Supported Python Versions @@ -83,7 +83,7 @@ Mac/Linux python3 -m venv source /bin/activate - pip install google-developers-knowledge + pip install google-developer-knowledge Windows @@ -93,7 +93,7 @@ Windows py -m venv .\\Scripts\activate - pip install google-developers-knowledge + pip install google-developer-knowledge Next Steps ~~~~~~~~~~ diff --git a/packages/google-developers-knowledge/docs/_static/custom.css b/packages/google-developer-knowledge/docs/_static/custom.css similarity index 100% rename from packages/google-developers-knowledge/docs/_static/custom.css rename to packages/google-developer-knowledge/docs/_static/custom.css diff --git a/packages/google-developers-knowledge/docs/_templates/layout.html b/packages/google-developer-knowledge/docs/_templates/layout.html similarity index 100% rename from packages/google-developers-knowledge/docs/_templates/layout.html rename to packages/google-developer-knowledge/docs/_templates/layout.html diff --git a/packages/google-developers-knowledge/docs/conf.py b/packages/google-developer-knowledge/docs/conf.py similarity index 95% rename from packages/google-developers-knowledge/docs/conf.py rename to packages/google-developer-knowledge/docs/conf.py index 465dfefb7d33..4a928dbb9fe2 100644 --- a/packages/google-developers-knowledge/docs/conf.py +++ b/packages/google-developer-knowledge/docs/conf.py @@ -13,7 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. ## -# google-developers-knowledge documentation build configuration file +# google-developer-knowledge documentation build configuration file # # This file is execfile()d with the current directory set to its # containing dir. @@ -82,7 +82,7 @@ root_doc = "index" # General information about the project. -project = "google-developers-knowledge" +project = "google-developer-knowledge" copyright = "2026, Google, LLC" author = "Google APIs" @@ -156,7 +156,7 @@ # further. For a list of options available for each theme, see the # documentation. html_theme_options = { - "description": "Google Client Libraries for google-developers-knowledge", + "description": "Google Client Libraries for google-developer-knowledge", "github_user": "googleapis", "github_repo": "google-cloud-python", "github_banner": True, @@ -250,7 +250,7 @@ # html_search_scorer = 'scorer.js' # Output file base name for HTML help builder. -htmlhelp_basename = "google-developers-knowledge-doc" +htmlhelp_basename = "google-developer-knowledge-doc" # -- Options for warnings ------------------------------------------------------ @@ -283,8 +283,8 @@ latex_documents = [ ( root_doc, - "google-developers-knowledge.tex", - "google-developers-knowledge Documentation", + "google-developer-knowledge.tex", + "google-developer-knowledge Documentation", author, "manual", ) @@ -318,8 +318,8 @@ man_pages = [ ( root_doc, - "google-developers-knowledge", - "google-developers-knowledge Documentation", + "google-developer-knowledge", + "google-developer-knowledge Documentation", [author], 1, ) @@ -337,11 +337,11 @@ texinfo_documents = [ ( root_doc, - "google-developers-knowledge", - "google-developers-knowledge Documentation", + "google-developer-knowledge", + "google-developer-knowledge Documentation", author, - "google-developers-knowledge", - "google-developers-knowledge Library", + "google-developer-knowledge", + "google-developer-knowledge Library", "APIs", ) ] diff --git a/packages/google-developer-knowledge/docs/developer_knowledge_v1/developer_knowledge.rst b/packages/google-developer-knowledge/docs/developer_knowledge_v1/developer_knowledge.rst new file mode 100644 index 000000000000..f6ca08a1129e --- /dev/null +++ b/packages/google-developer-knowledge/docs/developer_knowledge_v1/developer_knowledge.rst @@ -0,0 +1,10 @@ +DeveloperKnowledge +------------------------------------ + +.. automodule:: google.developer_knowledge_v1.services.developer_knowledge + :members: + :inherited-members: + +.. automodule:: google.developer_knowledge_v1.services.developer_knowledge.pagers + :members: + :inherited-members: diff --git a/packages/google-developer-knowledge/docs/developer_knowledge_v1/services_.rst b/packages/google-developer-knowledge/docs/developer_knowledge_v1/services_.rst new file mode 100644 index 000000000000..d4f41c5bc5ee --- /dev/null +++ b/packages/google-developer-knowledge/docs/developer_knowledge_v1/services_.rst @@ -0,0 +1,6 @@ +Services for Google Developer Knowledge v1 API +============================================== +.. toctree:: + :maxdepth: 2 + + developer_knowledge diff --git a/packages/google-developer-knowledge/docs/developer_knowledge_v1/types_.rst b/packages/google-developer-knowledge/docs/developer_knowledge_v1/types_.rst new file mode 100644 index 000000000000..503f58bffe75 --- /dev/null +++ b/packages/google-developer-knowledge/docs/developer_knowledge_v1/types_.rst @@ -0,0 +1,6 @@ +Types for Google Developer Knowledge v1 API +=========================================== + +.. automodule:: google.developer_knowledge_v1.types + :members: + :show-inheritance: diff --git a/packages/google-developers-knowledge/docs/index.rst b/packages/google-developer-knowledge/docs/index.rst similarity index 58% rename from packages/google-developers-knowledge/docs/index.rst rename to packages/google-developer-knowledge/docs/index.rst index 83367bc76281..d1e9ac7d8da5 100644 --- a/packages/google-developers-knowledge/docs/index.rst +++ b/packages/google-developer-knowledge/docs/index.rst @@ -8,14 +8,14 @@ API Reference .. toctree:: :maxdepth: 2 - developers_knowledge_v1/services_ - developers_knowledge_v1/types_ + developer_knowledge_v1/services_ + developer_knowledge_v1/types_ Changelog --------- -For a list of all ``google-developers-knowledge`` releases: +For a list of all ``google-developer-knowledge`` releases: .. toctree:: :maxdepth: 2 diff --git a/packages/google-developers-knowledge/docs/multiprocessing.rst b/packages/google-developer-knowledge/docs/multiprocessing.rst similarity index 100% rename from packages/google-developers-knowledge/docs/multiprocessing.rst rename to packages/google-developer-knowledge/docs/multiprocessing.rst diff --git a/packages/google-developers-knowledge/google/developers_knowledge/__init__.py b/packages/google-developer-knowledge/google/developer_knowledge/__init__.py similarity index 79% rename from packages/google-developers-knowledge/google/developers_knowledge/__init__.py rename to packages/google-developer-knowledge/google/developer_knowledge/__init__.py index e5e9b8075191..f5dd69b3d8f1 100644 --- a/packages/google-developers-knowledge/google/developers_knowledge/__init__.py +++ b/packages/google-developer-knowledge/google/developer_knowledge/__init__.py @@ -13,18 +13,18 @@ # See the License for the specific language governing permissions and # limitations under the License. # -from google.developers_knowledge import gapic_version as package_version +from google.developer_knowledge import gapic_version as package_version __version__ = package_version.__version__ -from google.developers_knowledge_v1.services.developer_knowledge.async_client import ( +from google.developer_knowledge_v1.services.developer_knowledge.async_client import ( DeveloperKnowledgeAsyncClient, ) -from google.developers_knowledge_v1.services.developer_knowledge.client import ( +from google.developer_knowledge_v1.services.developer_knowledge.client import ( DeveloperKnowledgeClient, ) -from google.developers_knowledge_v1.types.developerknowledge import ( +from google.developer_knowledge_v1.types.developerknowledge import ( BatchGetDocumentsRequest, BatchGetDocumentsResponse, Document, diff --git a/packages/google-developers-knowledge/google/developers_knowledge/gapic_version.py b/packages/google-developer-knowledge/google/developer_knowledge/gapic_version.py similarity index 100% rename from packages/google-developers-knowledge/google/developers_knowledge/gapic_version.py rename to packages/google-developer-knowledge/google/developer_knowledge/gapic_version.py diff --git a/packages/google-developer-knowledge/google/developer_knowledge/py.typed b/packages/google-developer-knowledge/google/developer_knowledge/py.typed new file mode 100644 index 000000000000..d36d74a92a11 --- /dev/null +++ b/packages/google-developer-knowledge/google/developer_knowledge/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-developer-knowledge package uses inline types. diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/__init__.py b/packages/google-developer-knowledge/google/developer_knowledge_v1/__init__.py similarity index 94% rename from packages/google-developers-knowledge/google/developers_knowledge_v1/__init__.py rename to packages/google-developer-knowledge/google/developer_knowledge_v1/__init__.py index e9e476db76c8..7ea2fc16961e 100644 --- a/packages/google-developers-knowledge/google/developers_knowledge_v1/__init__.py +++ b/packages/google-developer-knowledge/google/developer_knowledge_v1/__init__.py @@ -17,7 +17,7 @@ import google.api_core as api_core -from google.developers_knowledge_v1 import gapic_version as package_version +from google.developer_knowledge_v1 import gapic_version as package_version __version__ = package_version.__version__ @@ -41,8 +41,8 @@ if hasattr(api_core, "check_python_version") and hasattr( api_core, "check_dependency_versions" ): # pragma: NO COVER - api_core.check_python_version("google.developers_knowledge_v1") # type: ignore - api_core.check_dependency_versions("google.developers_knowledge_v1") # type: ignore + api_core.check_python_version("google.developer_knowledge_v1") # type: ignore + api_core.check_dependency_versions("google.developer_knowledge_v1") # type: ignore else: # pragma: NO COVER # An older version of api_core is installed which does not define the # functions above. We do equivalent checks manually. @@ -50,7 +50,7 @@ import warnings _py_version_str = sys.version.split()[0] - _package_label = "google.developers_knowledge_v1" + _package_label = "google.developer_knowledge_v1" if sys.version_info < (3, 10): warnings.warn( "You are using a non-supported Python version " diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/gapic_metadata.json b/packages/google-developer-knowledge/google/developer_knowledge_v1/gapic_metadata.json similarity index 97% rename from packages/google-developers-knowledge/google/developers_knowledge_v1/gapic_metadata.json rename to packages/google-developer-knowledge/google/developer_knowledge_v1/gapic_metadata.json index 0d8e9e182579..916b67b30e82 100644 --- a/packages/google-developers-knowledge/google/developers_knowledge_v1/gapic_metadata.json +++ b/packages/google-developer-knowledge/google/developer_knowledge_v1/gapic_metadata.json @@ -1,7 +1,7 @@ { "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", "language": "python", - "libraryPackage": "google.developers_knowledge_v1", + "libraryPackage": "google.developer_knowledge_v1", "protoPackage": "google.developers.knowledge.v1", "schema": "1.0", "services": { diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/gapic_version.py b/packages/google-developer-knowledge/google/developer_knowledge_v1/gapic_version.py similarity index 100% rename from packages/google-developers-knowledge/google/developers_knowledge_v1/gapic_version.py rename to packages/google-developer-knowledge/google/developer_knowledge_v1/gapic_version.py diff --git a/packages/google-developer-knowledge/google/developer_knowledge_v1/py.typed b/packages/google-developer-knowledge/google/developer_knowledge_v1/py.typed new file mode 100644 index 000000000000..d36d74a92a11 --- /dev/null +++ b/packages/google-developer-knowledge/google/developer_knowledge_v1/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-developer-knowledge package uses inline types. diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/__init__.py b/packages/google-developer-knowledge/google/developer_knowledge_v1/services/__init__.py similarity index 100% rename from packages/google-developers-knowledge/google/developers_knowledge_v1/services/__init__.py rename to packages/google-developer-knowledge/google/developer_knowledge_v1/services/__init__.py diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/__init__.py b/packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/__init__.py similarity index 100% rename from packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/__init__.py rename to packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/__init__.py diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/async_client.py b/packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/async_client.py similarity index 94% rename from packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/async_client.py rename to packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/async_client.py index b7c29b9ab0c1..291147ece4ac 100644 --- a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/async_client.py +++ b/packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/async_client.py @@ -37,7 +37,7 @@ from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -from google.developers_knowledge_v1 import gapic_version as package_version +from google.developer_knowledge_v1 import gapic_version as package_version try: OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None] @@ -46,8 +46,8 @@ import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore -from google.developers_knowledge_v1.services.developer_knowledge import pagers -from google.developers_knowledge_v1.types import developerknowledge +from google.developer_knowledge_v1.services.developer_knowledge import pagers +from google.developer_knowledge_v1.types import developerknowledge from .client import DeveloperKnowledgeClient from .transports.base import DEFAULT_CLIENT_INFO, DeveloperKnowledgeTransport @@ -350,14 +350,14 @@ async def search_document_chunks( # - It may require specifying regional endpoints when creating the service # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google import developers_knowledge_v1 + from google import developer_knowledge_v1 async def sample_search_document_chunks(): # Create a client - client = developers_knowledge_v1.DeveloperKnowledgeAsyncClient() + client = developer_knowledge_v1.DeveloperKnowledgeAsyncClient() # Initialize request argument(s) - request = developers_knowledge_v1.SearchDocumentChunksRequest( + request = developer_knowledge_v1.SearchDocumentChunksRequest( query="query_value", ) @@ -369,7 +369,7 @@ async def sample_search_document_chunks(): print(response) Args: - request (Optional[Union[google.developers_knowledge_v1.types.SearchDocumentChunksRequest, dict]]): + request (Optional[Union[google.developer_knowledge_v1.types.SearchDocumentChunksRequest, dict]]): The request object. Request message for [DeveloperKnowledge.SearchDocumentChunks][google.developers.knowledge.v1.DeveloperKnowledge.SearchDocumentChunks]. retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, @@ -381,7 +381,7 @@ async def sample_search_document_chunks(): be of type `bytes`. Returns: - google.developers_knowledge_v1.services.developer_knowledge.pagers.SearchDocumentChunksAsyncPager: + google.developer_knowledge_v1.services.developer_knowledge.pagers.SearchDocumentChunksAsyncPager: Response message for [DeveloperKnowledge.SearchDocumentChunks][google.developers.knowledge.v1.DeveloperKnowledge.SearchDocumentChunks]. @@ -447,14 +447,14 @@ async def get_document( # - It may require specifying regional endpoints when creating the service # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google import developers_knowledge_v1 + from google import developer_knowledge_v1 async def sample_get_document(): # Create a client - client = developers_knowledge_v1.DeveloperKnowledgeAsyncClient() + client = developer_knowledge_v1.DeveloperKnowledgeAsyncClient() # Initialize request argument(s) - request = developers_knowledge_v1.GetDocumentRequest( + request = developer_knowledge_v1.GetDocumentRequest( name="name_value", ) @@ -465,7 +465,7 @@ async def sample_get_document(): print(response) Args: - request (Optional[Union[google.developers_knowledge_v1.types.GetDocumentRequest, dict]]): + request (Optional[Union[google.developer_knowledge_v1.types.GetDocumentRequest, dict]]): The request object. Request message for [DeveloperKnowledge.GetDocument][google.developers.knowledge.v1.DeveloperKnowledge.GetDocument]. name (:class:`str`): @@ -486,7 +486,7 @@ async def sample_get_document(): be of type `bytes`. Returns: - google.developers_knowledge_v1.types.Document: + google.developer_knowledge_v1.types.Document: A Document represents a piece of content from the Developer Knowledge corpus. @@ -563,14 +563,14 @@ async def batch_get_documents( # - It may require specifying regional endpoints when creating the service # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google import developers_knowledge_v1 + from google import developer_knowledge_v1 async def sample_batch_get_documents(): # Create a client - client = developers_knowledge_v1.DeveloperKnowledgeAsyncClient() + client = developer_knowledge_v1.DeveloperKnowledgeAsyncClient() # Initialize request argument(s) - request = developers_knowledge_v1.BatchGetDocumentsRequest( + request = developer_knowledge_v1.BatchGetDocumentsRequest( names=['names_value1', 'names_value2'], ) @@ -581,7 +581,7 @@ async def sample_batch_get_documents(): print(response) Args: - request (Optional[Union[google.developers_knowledge_v1.types.BatchGetDocumentsRequest, dict]]): + request (Optional[Union[google.developer_knowledge_v1.types.BatchGetDocumentsRequest, dict]]): The request object. Request message for [DeveloperKnowledge.BatchGetDocuments][google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments]. retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, @@ -593,7 +593,7 @@ async def sample_batch_get_documents(): be of type `bytes`. Returns: - google.developers_knowledge_v1.types.BatchGetDocumentsResponse: + google.developer_knowledge_v1.types.BatchGetDocumentsResponse: Response message for [DeveloperKnowledge.BatchGetDocuments][google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments]. diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/client.py b/packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/client.py similarity index 96% rename from packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/client.py rename to packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/client.py index 8adfa8990176..ecee688d155d 100644 --- a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/client.py +++ b/packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/client.py @@ -45,7 +45,7 @@ from google.auth.transport.grpc import SslCredentials # type: ignore from google.oauth2 import service_account # type: ignore -from google.developers_knowledge_v1 import gapic_version as package_version +from google.developer_knowledge_v1 import gapic_version as package_version try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] @@ -63,8 +63,8 @@ import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore -from google.developers_knowledge_v1.services.developer_knowledge import pagers -from google.developers_knowledge_v1.types import developerknowledge +from google.developer_knowledge_v1.services.developer_knowledge import pagers +from google.developer_knowledge_v1.types import developerknowledge from .transports.base import DEFAULT_CLIENT_INFO, DeveloperKnowledgeTransport from .transports.grpc import DeveloperKnowledgeGrpcTransport @@ -776,14 +776,14 @@ def search_document_chunks( # - It may require specifying regional endpoints when creating the service # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google import developers_knowledge_v1 + from google import developer_knowledge_v1 def sample_search_document_chunks(): # Create a client - client = developers_knowledge_v1.DeveloperKnowledgeClient() + client = developer_knowledge_v1.DeveloperKnowledgeClient() # Initialize request argument(s) - request = developers_knowledge_v1.SearchDocumentChunksRequest( + request = developer_knowledge_v1.SearchDocumentChunksRequest( query="query_value", ) @@ -795,7 +795,7 @@ def sample_search_document_chunks(): print(response) Args: - request (Union[google.developers_knowledge_v1.types.SearchDocumentChunksRequest, dict]): + request (Union[google.developer_knowledge_v1.types.SearchDocumentChunksRequest, dict]): The request object. Request message for [DeveloperKnowledge.SearchDocumentChunks][google.developers.knowledge.v1.DeveloperKnowledge.SearchDocumentChunks]. retry (google.api_core.retry.Retry): Designation of what errors, if any, @@ -807,7 +807,7 @@ def sample_search_document_chunks(): be of type `bytes`. Returns: - google.developers_knowledge_v1.services.developer_knowledge.pagers.SearchDocumentChunksPager: + google.developer_knowledge_v1.services.developer_knowledge.pagers.SearchDocumentChunksPager: Response message for [DeveloperKnowledge.SearchDocumentChunks][google.developers.knowledge.v1.DeveloperKnowledge.SearchDocumentChunks]. @@ -871,14 +871,14 @@ def get_document( # - It may require specifying regional endpoints when creating the service # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google import developers_knowledge_v1 + from google import developer_knowledge_v1 def sample_get_document(): # Create a client - client = developers_knowledge_v1.DeveloperKnowledgeClient() + client = developer_knowledge_v1.DeveloperKnowledgeClient() # Initialize request argument(s) - request = developers_knowledge_v1.GetDocumentRequest( + request = developer_knowledge_v1.GetDocumentRequest( name="name_value", ) @@ -889,7 +889,7 @@ def sample_get_document(): print(response) Args: - request (Union[google.developers_knowledge_v1.types.GetDocumentRequest, dict]): + request (Union[google.developer_knowledge_v1.types.GetDocumentRequest, dict]): The request object. Request message for [DeveloperKnowledge.GetDocument][google.developers.knowledge.v1.DeveloperKnowledge.GetDocument]. name (str): @@ -910,7 +910,7 @@ def sample_get_document(): be of type `bytes`. Returns: - google.developers_knowledge_v1.types.Document: + google.developer_knowledge_v1.types.Document: A Document represents a piece of content from the Developer Knowledge corpus. @@ -984,14 +984,14 @@ def batch_get_documents( # - It may require specifying regional endpoints when creating the service # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google import developers_knowledge_v1 + from google import developer_knowledge_v1 def sample_batch_get_documents(): # Create a client - client = developers_knowledge_v1.DeveloperKnowledgeClient() + client = developer_knowledge_v1.DeveloperKnowledgeClient() # Initialize request argument(s) - request = developers_knowledge_v1.BatchGetDocumentsRequest( + request = developer_knowledge_v1.BatchGetDocumentsRequest( names=['names_value1', 'names_value2'], ) @@ -1002,7 +1002,7 @@ def sample_batch_get_documents(): print(response) Args: - request (Union[google.developers_knowledge_v1.types.BatchGetDocumentsRequest, dict]): + request (Union[google.developer_knowledge_v1.types.BatchGetDocumentsRequest, dict]): The request object. Request message for [DeveloperKnowledge.BatchGetDocuments][google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments]. retry (google.api_core.retry.Retry): Designation of what errors, if any, @@ -1014,7 +1014,7 @@ def sample_batch_get_documents(): be of type `bytes`. Returns: - google.developers_knowledge_v1.types.BatchGetDocumentsResponse: + google.developer_knowledge_v1.types.BatchGetDocumentsResponse: Response message for [DeveloperKnowledge.BatchGetDocuments][google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments]. diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/pagers.py b/packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/pagers.py similarity index 90% rename from packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/pagers.py rename to packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/pagers.py index a99ffe3675f9..e3a51b0a50b7 100644 --- a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/pagers.py +++ b/packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/pagers.py @@ -38,14 +38,14 @@ OptionalRetry = Union[retries.Retry, object, None] # type: ignore OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore -from google.developers_knowledge_v1.types import developerknowledge +from google.developer_knowledge_v1.types import developerknowledge class SearchDocumentChunksPager: """A pager for iterating through ``search_document_chunks`` requests. This class thinly wraps an initial - :class:`google.developers_knowledge_v1.types.SearchDocumentChunksResponse` object, and + :class:`google.developer_knowledge_v1.types.SearchDocumentChunksResponse` object, and provides an ``__iter__`` method to iterate through its ``results`` field. @@ -54,7 +54,7 @@ class SearchDocumentChunksPager: through the ``results`` field on the corresponding responses. - All the usual :class:`google.developers_knowledge_v1.types.SearchDocumentChunksResponse` + All the usual :class:`google.developer_knowledge_v1.types.SearchDocumentChunksResponse` attributes are available on the pager. If multiple requests are made, only the most recent response is retained, and thus used for attribute lookup. """ @@ -74,9 +74,9 @@ def __init__( Args: method (Callable): The method that was originally called, and which instantiated this pager. - request (google.developers_knowledge_v1.types.SearchDocumentChunksRequest): + request (google.developer_knowledge_v1.types.SearchDocumentChunksRequest): The initial request object. - response (google.developers_knowledge_v1.types.SearchDocumentChunksResponse): + response (google.developer_knowledge_v1.types.SearchDocumentChunksResponse): The initial response object. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. @@ -121,7 +121,7 @@ class SearchDocumentChunksAsyncPager: """A pager for iterating through ``search_document_chunks`` requests. This class thinly wraps an initial - :class:`google.developers_knowledge_v1.types.SearchDocumentChunksResponse` object, and + :class:`google.developer_knowledge_v1.types.SearchDocumentChunksResponse` object, and provides an ``__aiter__`` method to iterate through its ``results`` field. @@ -130,7 +130,7 @@ class SearchDocumentChunksAsyncPager: through the ``results`` field on the corresponding responses. - All the usual :class:`google.developers_knowledge_v1.types.SearchDocumentChunksResponse` + All the usual :class:`google.developer_knowledge_v1.types.SearchDocumentChunksResponse` attributes are available on the pager. If multiple requests are made, only the most recent response is retained, and thus used for attribute lookup. """ @@ -152,9 +152,9 @@ def __init__( Args: method (Callable): The method that was originally called, and which instantiated this pager. - request (google.developers_knowledge_v1.types.SearchDocumentChunksRequest): + request (google.developer_knowledge_v1.types.SearchDocumentChunksRequest): The initial request object. - response (google.developers_knowledge_v1.types.SearchDocumentChunksResponse): + response (google.developer_knowledge_v1.types.SearchDocumentChunksResponse): The initial response object. retry (google.api_core.retry.AsyncRetry): Designation of what errors, if any, should be retried. diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/README.rst b/packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/transports/README.rst similarity index 100% rename from packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/README.rst rename to packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/transports/README.rst diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/__init__.py b/packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/transports/__init__.py similarity index 100% rename from packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/__init__.py rename to packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/transports/__init__.py diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/base.py b/packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/transports/base.py similarity index 98% rename from packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/base.py rename to packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/transports/base.py index f02e32c7be8c..90552d56a2f6 100644 --- a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/base.py +++ b/packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/transports/base.py @@ -25,8 +25,8 @@ from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -from google.developers_knowledge_v1 import gapic_version as package_version -from google.developers_knowledge_v1.types import developerknowledge +from google.developer_knowledge_v1 import gapic_version as package_version +from google.developer_knowledge_v1.types import developerknowledge DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=package_version.__version__ diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/grpc.py b/packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/transports/grpc.py similarity index 99% rename from packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/grpc.py rename to packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/transports/grpc.py index 51d25b504688..1007e369e9d6 100644 --- a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/grpc.py +++ b/packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/transports/grpc.py @@ -28,7 +28,7 @@ from google.auth.transport.grpc import SslCredentials # type: ignore from google.protobuf.json_format import MessageToJson -from google.developers_knowledge_v1.types import developerknowledge +from google.developer_knowledge_v1.types import developerknowledge from .base import DEFAULT_CLIENT_INFO, DeveloperKnowledgeTransport diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/grpc_asyncio.py b/packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/transports/grpc_asyncio.py similarity index 99% rename from packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/grpc_asyncio.py rename to packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/transports/grpc_asyncio.py index f446f2be32ca..331ebebd80f6 100644 --- a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/grpc_asyncio.py +++ b/packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/transports/grpc_asyncio.py @@ -31,7 +31,7 @@ from google.protobuf.json_format import MessageToJson from grpc.experimental import aio # type: ignore -from google.developers_knowledge_v1.types import developerknowledge +from google.developer_knowledge_v1.types import developerknowledge from .base import DEFAULT_CLIENT_INFO, DeveloperKnowledgeTransport from .grpc import DeveloperKnowledgeGrpcTransport diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/rest.py b/packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/transports/rest.py similarity index 99% rename from packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/rest.py rename to packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/transports/rest.py index bdd1bf490fcf..0e1a6c3c94f6 100644 --- a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/rest.py +++ b/packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/transports/rest.py @@ -28,7 +28,7 @@ from google.protobuf import json_format from requests import __version__ as requests_version -from google.developers_knowledge_v1.types import developerknowledge +from google.developer_knowledge_v1.types import developerknowledge from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO from .rest_base import _BaseDeveloperKnowledgeRestTransport diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/rest_base.py b/packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/transports/rest_base.py similarity index 99% rename from packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/rest_base.py rename to packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/transports/rest_base.py index b0e62a922cfa..b272e84d47a7 100644 --- a/packages/google-developers-knowledge/google/developers_knowledge_v1/services/developer_knowledge/transports/rest_base.py +++ b/packages/google-developer-knowledge/google/developer_knowledge_v1/services/developer_knowledge/transports/rest_base.py @@ -20,7 +20,7 @@ from google.api_core import gapic_v1, path_template from google.protobuf import json_format -from google.developers_knowledge_v1.types import developerknowledge +from google.developer_knowledge_v1.types import developerknowledge from .base import DEFAULT_CLIENT_INFO, DeveloperKnowledgeTransport diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/types/__init__.py b/packages/google-developer-knowledge/google/developer_knowledge_v1/types/__init__.py similarity index 100% rename from packages/google-developers-knowledge/google/developers_knowledge_v1/types/__init__.py rename to packages/google-developer-knowledge/google/developer_knowledge_v1/types/__init__.py diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/types/developerknowledge.py b/packages/google-developer-knowledge/google/developer_knowledge_v1/types/developerknowledge.py similarity index 97% rename from packages/google-developers-knowledge/google/developers_knowledge_v1/types/developerknowledge.py rename to packages/google-developer-knowledge/google/developer_knowledge_v1/types/developerknowledge.py index c39eb80c82cb..783cf222a991 100644 --- a/packages/google-developers-knowledge/google/developers_knowledge_v1/types/developerknowledge.py +++ b/packages/google-developer-knowledge/google/developer_knowledge_v1/types/developerknowledge.py @@ -105,7 +105,7 @@ class Document(proto.Message): Output only. Represents the timestamp when the content or metadata of the document was last updated. - view (google.developers_knowledge_v1.types.DocumentView): + view (google.developer_knowledge_v1.types.DocumentView): Output only. Specifies the [DocumentView][google.developers.knowledge.v1.DocumentView] of the document. @@ -239,7 +239,7 @@ class SearchDocumentChunksResponse(proto.Message): [DeveloperKnowledge.SearchDocumentChunks][google.developers.knowledge.v1.DeveloperKnowledge.SearchDocumentChunks]. Attributes: - results (MutableSequence[google.developers_knowledge_v1.types.DocumentChunk]): + results (MutableSequence[google.developer_knowledge_v1.types.DocumentChunk]): Contains the search results for the given query. Each [DocumentChunk][google.developers.knowledge.v1.DocumentChunk] in this list contains a snippet of content relevant to the @@ -280,7 +280,7 @@ class GetDocumentRequest(proto.Message): Required. Specifies the name of the document to retrieve. Format: ``documents/{uri_without_scheme}`` Example: ``documents/docs.cloud.google.com/storage/docs/creating-buckets`` - view (google.developers_knowledge_v1.types.DocumentView): + view (google.developer_knowledge_v1.types.DocumentView): Optional. Specifies the [DocumentView][google.developers.knowledge.v1.DocumentView] of the document. If unspecified, @@ -312,7 +312,7 @@ class BatchGetDocumentsRequest(proto.Message): Format: ``documents/{uri_without_scheme}`` Example: ``documents/docs.cloud.google.com/storage/docs/creating-buckets`` - view (google.developers_knowledge_v1.types.DocumentView): + view (google.developer_knowledge_v1.types.DocumentView): Optional. Specifies the [DocumentView][google.developers.knowledge.v1.DocumentView] of the document. If unspecified, @@ -336,7 +336,7 @@ class BatchGetDocumentsResponse(proto.Message): [DeveloperKnowledge.BatchGetDocuments][google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments]. Attributes: - documents (MutableSequence[google.developers_knowledge_v1.types.Document]): + documents (MutableSequence[google.developer_knowledge_v1.types.Document]): Contains the documents requested. """ @@ -371,7 +371,7 @@ class DocumentChunk(proto.Message): content (str): Output only. Contains the content of the document chunk. - document (google.developers_knowledge_v1.types.Document): + document (google.developer_knowledge_v1.types.Document): Output only. Represents metadata about the [Document][google.developers.knowledge.v1.Document] this chunk is from. The diff --git a/packages/google-developers-knowledge/mypy.ini b/packages/google-developer-knowledge/mypy.ini similarity index 100% rename from packages/google-developers-knowledge/mypy.ini rename to packages/google-developer-knowledge/mypy.ini diff --git a/packages/google-developers-knowledge/noxfile.py b/packages/google-developer-knowledge/noxfile.py similarity index 99% rename from packages/google-developers-knowledge/noxfile.py rename to packages/google-developer-knowledge/noxfile.py index e61a256304dd..24048446e495 100644 --- a/packages/google-developers-knowledge/noxfile.py +++ b/packages/google-developer-knowledge/noxfile.py @@ -53,7 +53,7 @@ ) else: LOWER_BOUND_CONSTRAINTS_FILE = CURRENT_DIRECTORY / "constraints.txt" -PACKAGE_NAME = "google-developers-knowledge" +PACKAGE_NAME = "google-developer-knowledge" UNIT_TEST_STANDARD_DEPENDENCIES = [ "mock", diff --git a/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_batch_get_documents_async.py b/packages/google-developer-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_batch_get_documents_async.py similarity index 88% rename from packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_batch_get_documents_async.py rename to packages/google-developer-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_batch_get_documents_async.py index 8d801d2c521f..033fce92a244 100644 --- a/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_batch_get_documents_async.py +++ b/packages/google-developer-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_batch_get_documents_async.py @@ -20,7 +20,7 @@ # It may require modifications to work in your environment. # To install the latest published package dependency, execute the following: -# python3 -m pip install google-developers-knowledge +# python3 -m pip install google-developer-knowledge # [START developerknowledge_v1_generated_DeveloperKnowledge_BatchGetDocuments_async] @@ -31,15 +31,15 @@ # - It may require specifying regional endpoints when creating the service # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html -from google import developers_knowledge_v1 +from google import developer_knowledge_v1 async def sample_batch_get_documents(): # Create a client - client = developers_knowledge_v1.DeveloperKnowledgeAsyncClient() + client = developer_knowledge_v1.DeveloperKnowledgeAsyncClient() # Initialize request argument(s) - request = developers_knowledge_v1.BatchGetDocumentsRequest( + request = developer_knowledge_v1.BatchGetDocumentsRequest( names=["names_value1", "names_value2"], ) diff --git a/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_batch_get_documents_sync.py b/packages/google-developer-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_batch_get_documents_sync.py similarity index 88% rename from packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_batch_get_documents_sync.py rename to packages/google-developer-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_batch_get_documents_sync.py index 75c3d903bd65..5fbfbb2dc0da 100644 --- a/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_batch_get_documents_sync.py +++ b/packages/google-developer-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_batch_get_documents_sync.py @@ -20,7 +20,7 @@ # It may require modifications to work in your environment. # To install the latest published package dependency, execute the following: -# python3 -m pip install google-developers-knowledge +# python3 -m pip install google-developer-knowledge # [START developerknowledge_v1_generated_DeveloperKnowledge_BatchGetDocuments_sync] @@ -31,15 +31,15 @@ # - It may require specifying regional endpoints when creating the service # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html -from google import developers_knowledge_v1 +from google import developer_knowledge_v1 def sample_batch_get_documents(): # Create a client - client = developers_knowledge_v1.DeveloperKnowledgeClient() + client = developer_knowledge_v1.DeveloperKnowledgeClient() # Initialize request argument(s) - request = developers_knowledge_v1.BatchGetDocumentsRequest( + request = developer_knowledge_v1.BatchGetDocumentsRequest( names=["names_value1", "names_value2"], ) diff --git a/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_get_document_async.py b/packages/google-developer-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_get_document_async.py similarity index 88% rename from packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_get_document_async.py rename to packages/google-developer-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_get_document_async.py index 70d14f7df658..aab407c50893 100644 --- a/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_get_document_async.py +++ b/packages/google-developer-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_get_document_async.py @@ -20,7 +20,7 @@ # It may require modifications to work in your environment. # To install the latest published package dependency, execute the following: -# python3 -m pip install google-developers-knowledge +# python3 -m pip install google-developer-knowledge # [START developerknowledge_v1_generated_DeveloperKnowledge_GetDocument_async] @@ -31,15 +31,15 @@ # - It may require specifying regional endpoints when creating the service # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html -from google import developers_knowledge_v1 +from google import developer_knowledge_v1 async def sample_get_document(): # Create a client - client = developers_knowledge_v1.DeveloperKnowledgeAsyncClient() + client = developer_knowledge_v1.DeveloperKnowledgeAsyncClient() # Initialize request argument(s) - request = developers_knowledge_v1.GetDocumentRequest( + request = developer_knowledge_v1.GetDocumentRequest( name="name_value", ) diff --git a/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_get_document_sync.py b/packages/google-developer-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_get_document_sync.py similarity index 88% rename from packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_get_document_sync.py rename to packages/google-developer-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_get_document_sync.py index ab34304febdc..f5c4566bb8a1 100644 --- a/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_get_document_sync.py +++ b/packages/google-developer-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_get_document_sync.py @@ -20,7 +20,7 @@ # It may require modifications to work in your environment. # To install the latest published package dependency, execute the following: -# python3 -m pip install google-developers-knowledge +# python3 -m pip install google-developer-knowledge # [START developerknowledge_v1_generated_DeveloperKnowledge_GetDocument_sync] @@ -31,15 +31,15 @@ # - It may require specifying regional endpoints when creating the service # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html -from google import developers_knowledge_v1 +from google import developer_knowledge_v1 def sample_get_document(): # Create a client - client = developers_knowledge_v1.DeveloperKnowledgeClient() + client = developer_knowledge_v1.DeveloperKnowledgeClient() # Initialize request argument(s) - request = developers_knowledge_v1.GetDocumentRequest( + request = developer_knowledge_v1.GetDocumentRequest( name="name_value", ) diff --git a/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_search_document_chunks_async.py b/packages/google-developer-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_search_document_chunks_async.py similarity index 88% rename from packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_search_document_chunks_async.py rename to packages/google-developer-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_search_document_chunks_async.py index a164870b859a..687042ffea9e 100644 --- a/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_search_document_chunks_async.py +++ b/packages/google-developer-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_search_document_chunks_async.py @@ -20,7 +20,7 @@ # It may require modifications to work in your environment. # To install the latest published package dependency, execute the following: -# python3 -m pip install google-developers-knowledge +# python3 -m pip install google-developer-knowledge # [START developerknowledge_v1_generated_DeveloperKnowledge_SearchDocumentChunks_async] @@ -31,15 +31,15 @@ # - It may require specifying regional endpoints when creating the service # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html -from google import developers_knowledge_v1 +from google import developer_knowledge_v1 async def sample_search_document_chunks(): # Create a client - client = developers_knowledge_v1.DeveloperKnowledgeAsyncClient() + client = developer_knowledge_v1.DeveloperKnowledgeAsyncClient() # Initialize request argument(s) - request = developers_knowledge_v1.SearchDocumentChunksRequest( + request = developer_knowledge_v1.SearchDocumentChunksRequest( query="query_value", ) diff --git a/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_search_document_chunks_sync.py b/packages/google-developer-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_search_document_chunks_sync.py similarity index 88% rename from packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_search_document_chunks_sync.py rename to packages/google-developer-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_search_document_chunks_sync.py index c2c30cbad088..e5c7c64f2aa8 100644 --- a/packages/google-developers-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_search_document_chunks_sync.py +++ b/packages/google-developer-knowledge/samples/generated_samples/developerknowledge_v1_generated_developer_knowledge_search_document_chunks_sync.py @@ -20,7 +20,7 @@ # It may require modifications to work in your environment. # To install the latest published package dependency, execute the following: -# python3 -m pip install google-developers-knowledge +# python3 -m pip install google-developer-knowledge # [START developerknowledge_v1_generated_DeveloperKnowledge_SearchDocumentChunks_sync] @@ -31,15 +31,15 @@ # - It may require specifying regional endpoints when creating the service # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html -from google import developers_knowledge_v1 +from google import developer_knowledge_v1 def sample_search_document_chunks(): # Create a client - client = developers_knowledge_v1.DeveloperKnowledgeClient() + client = developer_knowledge_v1.DeveloperKnowledgeClient() # Initialize request argument(s) - request = developers_knowledge_v1.SearchDocumentChunksRequest( + request = developer_knowledge_v1.SearchDocumentChunksRequest( query="query_value", ) diff --git a/packages/google-developers-knowledge/samples/generated_samples/snippet_metadata_google.developers.knowledge.v1.json b/packages/google-developer-knowledge/samples/generated_samples/snippet_metadata_google.developers.knowledge.v1.json similarity index 84% rename from packages/google-developers-knowledge/samples/generated_samples/snippet_metadata_google.developers.knowledge.v1.json rename to packages/google-developer-knowledge/samples/generated_samples/snippet_metadata_google.developers.knowledge.v1.json index 71c0bd01267e..f9250f284097 100644 --- a/packages/google-developers-knowledge/samples/generated_samples/snippet_metadata_google.developers.knowledge.v1.json +++ b/packages/google-developer-knowledge/samples/generated_samples/snippet_metadata_google.developers.knowledge.v1.json @@ -7,7 +7,7 @@ } ], "language": "PYTHON", - "name": "google-developers-knowledge", + "name": "google-developer-knowledge", "version": "0.0.0" }, "snippets": [ @@ -16,10 +16,10 @@ "clientMethod": { "async": true, "client": { - "fullName": "google.developers_knowledge_v1.DeveloperKnowledgeAsyncClient", + "fullName": "google.developer_knowledge_v1.DeveloperKnowledgeAsyncClient", "shortName": "DeveloperKnowledgeAsyncClient" }, - "fullName": "google.developers_knowledge_v1.DeveloperKnowledgeAsyncClient.batch_get_documents", + "fullName": "google.developer_knowledge_v1.DeveloperKnowledgeAsyncClient.batch_get_documents", "method": { "fullName": "google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments", "service": { @@ -31,7 +31,7 @@ "parameters": [ { "name": "request", - "type": "google.developers_knowledge_v1.types.BatchGetDocumentsRequest" + "type": "google.developer_knowledge_v1.types.BatchGetDocumentsRequest" }, { "name": "retry", @@ -46,7 +46,7 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.developers_knowledge_v1.types.BatchGetDocumentsResponse", + "resultType": "google.developer_knowledge_v1.types.BatchGetDocumentsResponse", "shortName": "batch_get_documents" }, "description": "Sample for BatchGetDocuments", @@ -92,10 +92,10 @@ "canonical": true, "clientMethod": { "client": { - "fullName": "google.developers_knowledge_v1.DeveloperKnowledgeClient", + "fullName": "google.developer_knowledge_v1.DeveloperKnowledgeClient", "shortName": "DeveloperKnowledgeClient" }, - "fullName": "google.developers_knowledge_v1.DeveloperKnowledgeClient.batch_get_documents", + "fullName": "google.developer_knowledge_v1.DeveloperKnowledgeClient.batch_get_documents", "method": { "fullName": "google.developers.knowledge.v1.DeveloperKnowledge.BatchGetDocuments", "service": { @@ -107,7 +107,7 @@ "parameters": [ { "name": "request", - "type": "google.developers_knowledge_v1.types.BatchGetDocumentsRequest" + "type": "google.developer_knowledge_v1.types.BatchGetDocumentsRequest" }, { "name": "retry", @@ -122,7 +122,7 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.developers_knowledge_v1.types.BatchGetDocumentsResponse", + "resultType": "google.developer_knowledge_v1.types.BatchGetDocumentsResponse", "shortName": "batch_get_documents" }, "description": "Sample for BatchGetDocuments", @@ -169,10 +169,10 @@ "clientMethod": { "async": true, "client": { - "fullName": "google.developers_knowledge_v1.DeveloperKnowledgeAsyncClient", + "fullName": "google.developer_knowledge_v1.DeveloperKnowledgeAsyncClient", "shortName": "DeveloperKnowledgeAsyncClient" }, - "fullName": "google.developers_knowledge_v1.DeveloperKnowledgeAsyncClient.get_document", + "fullName": "google.developer_knowledge_v1.DeveloperKnowledgeAsyncClient.get_document", "method": { "fullName": "google.developers.knowledge.v1.DeveloperKnowledge.GetDocument", "service": { @@ -184,7 +184,7 @@ "parameters": [ { "name": "request", - "type": "google.developers_knowledge_v1.types.GetDocumentRequest" + "type": "google.developer_knowledge_v1.types.GetDocumentRequest" }, { "name": "name", @@ -203,7 +203,7 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.developers_knowledge_v1.types.Document", + "resultType": "google.developer_knowledge_v1.types.Document", "shortName": "get_document" }, "description": "Sample for GetDocument", @@ -249,10 +249,10 @@ "canonical": true, "clientMethod": { "client": { - "fullName": "google.developers_knowledge_v1.DeveloperKnowledgeClient", + "fullName": "google.developer_knowledge_v1.DeveloperKnowledgeClient", "shortName": "DeveloperKnowledgeClient" }, - "fullName": "google.developers_knowledge_v1.DeveloperKnowledgeClient.get_document", + "fullName": "google.developer_knowledge_v1.DeveloperKnowledgeClient.get_document", "method": { "fullName": "google.developers.knowledge.v1.DeveloperKnowledge.GetDocument", "service": { @@ -264,7 +264,7 @@ "parameters": [ { "name": "request", - "type": "google.developers_knowledge_v1.types.GetDocumentRequest" + "type": "google.developer_knowledge_v1.types.GetDocumentRequest" }, { "name": "name", @@ -283,7 +283,7 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.developers_knowledge_v1.types.Document", + "resultType": "google.developer_knowledge_v1.types.Document", "shortName": "get_document" }, "description": "Sample for GetDocument", @@ -330,10 +330,10 @@ "clientMethod": { "async": true, "client": { - "fullName": "google.developers_knowledge_v1.DeveloperKnowledgeAsyncClient", + "fullName": "google.developer_knowledge_v1.DeveloperKnowledgeAsyncClient", "shortName": "DeveloperKnowledgeAsyncClient" }, - "fullName": "google.developers_knowledge_v1.DeveloperKnowledgeAsyncClient.search_document_chunks", + "fullName": "google.developer_knowledge_v1.DeveloperKnowledgeAsyncClient.search_document_chunks", "method": { "fullName": "google.developers.knowledge.v1.DeveloperKnowledge.SearchDocumentChunks", "service": { @@ -345,7 +345,7 @@ "parameters": [ { "name": "request", - "type": "google.developers_knowledge_v1.types.SearchDocumentChunksRequest" + "type": "google.developer_knowledge_v1.types.SearchDocumentChunksRequest" }, { "name": "retry", @@ -360,7 +360,7 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.developers_knowledge_v1.services.developer_knowledge.pagers.SearchDocumentChunksAsyncPager", + "resultType": "google.developer_knowledge_v1.services.developer_knowledge.pagers.SearchDocumentChunksAsyncPager", "shortName": "search_document_chunks" }, "description": "Sample for SearchDocumentChunks", @@ -406,10 +406,10 @@ "canonical": true, "clientMethod": { "client": { - "fullName": "google.developers_knowledge_v1.DeveloperKnowledgeClient", + "fullName": "google.developer_knowledge_v1.DeveloperKnowledgeClient", "shortName": "DeveloperKnowledgeClient" }, - "fullName": "google.developers_knowledge_v1.DeveloperKnowledgeClient.search_document_chunks", + "fullName": "google.developer_knowledge_v1.DeveloperKnowledgeClient.search_document_chunks", "method": { "fullName": "google.developers.knowledge.v1.DeveloperKnowledge.SearchDocumentChunks", "service": { @@ -421,7 +421,7 @@ "parameters": [ { "name": "request", - "type": "google.developers_knowledge_v1.types.SearchDocumentChunksRequest" + "type": "google.developer_knowledge_v1.types.SearchDocumentChunksRequest" }, { "name": "retry", @@ -436,7 +436,7 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.developers_knowledge_v1.services.developer_knowledge.pagers.SearchDocumentChunksPager", + "resultType": "google.developer_knowledge_v1.services.developer_knowledge.pagers.SearchDocumentChunksPager", "shortName": "search_document_chunks" }, "description": "Sample for SearchDocumentChunks", diff --git a/packages/google-developers-knowledge/setup.py b/packages/google-developer-knowledge/setup.py similarity index 93% rename from packages/google-developers-knowledge/setup.py rename to packages/google-developer-knowledge/setup.py index 5784d51f6ece..7feece0e9cd6 100644 --- a/packages/google-developers-knowledge/setup.py +++ b/packages/google-developer-knowledge/setup.py @@ -21,15 +21,15 @@ package_root = os.path.abspath(os.path.dirname(__file__)) -name = "google-developers-knowledge" +name = "google-developer-knowledge" -description = "Google Developers Knowledge API client library" +description = "Google Developer Knowledge API client library" version = None with open( - os.path.join(package_root, "google/developers_knowledge/gapic_version.py") + os.path.join(package_root, "google/developer_knowledge/gapic_version.py") ) as fp: version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) assert len(version_candidates) == 1 @@ -52,7 +52,7 @@ "protobuf >= 4.25.8, < 8.0.0", ] extras = {} -url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-developers-knowledge" +url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-developer-knowledge" package_root = os.path.abspath(os.path.dirname(__file__)) diff --git a/packages/google-developers-knowledge/testing/constraints-3.10.txt b/packages/google-developer-knowledge/testing/constraints-3.10.txt similarity index 100% rename from packages/google-developers-knowledge/testing/constraints-3.10.txt rename to packages/google-developer-knowledge/testing/constraints-3.10.txt diff --git a/packages/google-developers-knowledge/testing/constraints-3.11.txt b/packages/google-developer-knowledge/testing/constraints-3.11.txt similarity index 100% rename from packages/google-developers-knowledge/testing/constraints-3.11.txt rename to packages/google-developer-knowledge/testing/constraints-3.11.txt diff --git a/packages/google-developers-knowledge/testing/constraints-3.12.txt b/packages/google-developer-knowledge/testing/constraints-3.12.txt similarity index 100% rename from packages/google-developers-knowledge/testing/constraints-3.12.txt rename to packages/google-developer-knowledge/testing/constraints-3.12.txt diff --git a/packages/google-developers-knowledge/testing/constraints-3.13.txt b/packages/google-developer-knowledge/testing/constraints-3.13.txt similarity index 100% rename from packages/google-developers-knowledge/testing/constraints-3.13.txt rename to packages/google-developer-knowledge/testing/constraints-3.13.txt diff --git a/packages/google-developers-knowledge/testing/constraints-3.14.txt b/packages/google-developer-knowledge/testing/constraints-3.14.txt similarity index 100% rename from packages/google-developers-knowledge/testing/constraints-3.14.txt rename to packages/google-developer-knowledge/testing/constraints-3.14.txt diff --git a/packages/google-developers-knowledge/tests/__init__.py b/packages/google-developer-knowledge/tests/__init__.py similarity index 100% rename from packages/google-developers-knowledge/tests/__init__.py rename to packages/google-developer-knowledge/tests/__init__.py diff --git a/packages/google-developers-knowledge/tests/unit/__init__.py b/packages/google-developer-knowledge/tests/unit/__init__.py similarity index 100% rename from packages/google-developers-knowledge/tests/unit/__init__.py rename to packages/google-developer-knowledge/tests/unit/__init__.py diff --git a/packages/google-developers-knowledge/tests/unit/gapic/__init__.py b/packages/google-developer-knowledge/tests/unit/gapic/__init__.py similarity index 100% rename from packages/google-developers-knowledge/tests/unit/gapic/__init__.py rename to packages/google-developer-knowledge/tests/unit/gapic/__init__.py diff --git a/packages/google-developers-knowledge/tests/unit/gapic/developers_knowledge_v1/__init__.py b/packages/google-developer-knowledge/tests/unit/gapic/developer_knowledge_v1/__init__.py similarity index 100% rename from packages/google-developers-knowledge/tests/unit/gapic/developers_knowledge_v1/__init__.py rename to packages/google-developer-knowledge/tests/unit/gapic/developer_knowledge_v1/__init__.py diff --git a/packages/google-developers-knowledge/tests/unit/gapic/developers_knowledge_v1/test_developer_knowledge.py b/packages/google-developer-knowledge/tests/unit/gapic/developer_knowledge_v1/test_developer_knowledge.py similarity index 99% rename from packages/google-developers-knowledge/tests/unit/gapic/developers_knowledge_v1/test_developer_knowledge.py rename to packages/google-developer-knowledge/tests/unit/gapic/developer_knowledge_v1/test_developer_knowledge.py index b92aec170daa..1e0b3891eb92 100644 --- a/packages/google-developers-knowledge/tests/unit/gapic/developers_knowledge_v1/test_developer_knowledge.py +++ b/packages/google-developer-knowledge/tests/unit/gapic/developer_knowledge_v1/test_developer_knowledge.py @@ -53,13 +53,13 @@ from google.auth.exceptions import MutualTLSChannelError from google.oauth2 import service_account -from google.developers_knowledge_v1.services.developer_knowledge import ( +from google.developer_knowledge_v1.services.developer_knowledge import ( DeveloperKnowledgeAsyncClient, DeveloperKnowledgeClient, pagers, transports, ) -from google.developers_knowledge_v1.types import developerknowledge +from google.developer_knowledge_v1.types import developerknowledge CRED_INFO_JSON = { "credential_source": "/path/to/file", @@ -1278,7 +1278,7 @@ def test_developer_knowledge_client_client_options_credentials_file( def test_developer_knowledge_client_client_options_from_dict(): with mock.patch( - "google.developers_knowledge_v1.services.developer_knowledge.transports.DeveloperKnowledgeGrpcTransport.__init__" + "google.developer_knowledge_v1.services.developer_knowledge.transports.DeveloperKnowledgeGrpcTransport.__init__" ) as grpc_transport: grpc_transport.return_value = None client = DeveloperKnowledgeClient( @@ -3614,7 +3614,7 @@ def test_developer_knowledge_base_transport_error(): def test_developer_knowledge_base_transport(): # Instantiate the base transport. with mock.patch( - "google.developers_knowledge_v1.services.developer_knowledge.transports.DeveloperKnowledgeTransport.__init__" + "google.developer_knowledge_v1.services.developer_knowledge.transports.DeveloperKnowledgeTransport.__init__" ) as Transport: Transport.return_value = None transport = transports.DeveloperKnowledgeTransport( @@ -3651,7 +3651,7 @@ def test_developer_knowledge_base_transport_with_credentials_file(): google.auth, "load_credentials_from_file", autospec=True ) as load_creds, mock.patch( - "google.developers_knowledge_v1.services.developer_knowledge.transports.DeveloperKnowledgeTransport._prep_wrapped_messages" + "google.developer_knowledge_v1.services.developer_knowledge.transports.DeveloperKnowledgeTransport._prep_wrapped_messages" ) as Transport, ): Transport.return_value = None @@ -3673,7 +3673,7 @@ def test_developer_knowledge_base_transport_with_adc(): with ( mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( - "google.developers_knowledge_v1.services.developer_knowledge.transports.DeveloperKnowledgeTransport._prep_wrapped_messages" + "google.developer_knowledge_v1.services.developer_knowledge.transports.DeveloperKnowledgeTransport._prep_wrapped_messages" ) as Transport, ): Transport.return_value = None diff --git a/packages/google-developers-knowledge/CHANGELOG.md b/packages/google-developers-knowledge/CHANGELOG.md deleted file mode 100644 index 6abef3a7fecc..000000000000 --- a/packages/google-developers-knowledge/CHANGELOG.md +++ /dev/null @@ -1,5 +0,0 @@ -# Changelog - -[PyPI History][1] - -[1]: https://pypi.org/project/google-developers-knowledge/#history diff --git a/packages/google-developers-knowledge/docs/developers_knowledge_v1/developer_knowledge.rst b/packages/google-developers-knowledge/docs/developers_knowledge_v1/developer_knowledge.rst deleted file mode 100644 index fbfc3c907022..000000000000 --- a/packages/google-developers-knowledge/docs/developers_knowledge_v1/developer_knowledge.rst +++ /dev/null @@ -1,10 +0,0 @@ -DeveloperKnowledge ------------------------------------- - -.. automodule:: google.developers_knowledge_v1.services.developer_knowledge - :members: - :inherited-members: - -.. automodule:: google.developers_knowledge_v1.services.developer_knowledge.pagers - :members: - :inherited-members: diff --git a/packages/google-developers-knowledge/docs/developers_knowledge_v1/services_.rst b/packages/google-developers-knowledge/docs/developers_knowledge_v1/services_.rst deleted file mode 100644 index 7073d3f33ded..000000000000 --- a/packages/google-developers-knowledge/docs/developers_knowledge_v1/services_.rst +++ /dev/null @@ -1,6 +0,0 @@ -Services for Google Developers Knowledge v1 API -=============================================== -.. toctree:: - :maxdepth: 2 - - developer_knowledge diff --git a/packages/google-developers-knowledge/docs/developers_knowledge_v1/types_.rst b/packages/google-developers-knowledge/docs/developers_knowledge_v1/types_.rst deleted file mode 100644 index 66703edbc136..000000000000 --- a/packages/google-developers-knowledge/docs/developers_knowledge_v1/types_.rst +++ /dev/null @@ -1,6 +0,0 @@ -Types for Google Developers Knowledge v1 API -============================================ - -.. automodule:: google.developers_knowledge_v1.types - :members: - :show-inheritance: diff --git a/packages/google-developers-knowledge/google/developers_knowledge/py.typed b/packages/google-developers-knowledge/google/developers_knowledge/py.typed deleted file mode 100644 index 184e0e4d53ea..000000000000 --- a/packages/google-developers-knowledge/google/developers_knowledge/py.typed +++ /dev/null @@ -1,2 +0,0 @@ -# Marker file for PEP 561. -# The google-developers-knowledge package uses inline types. diff --git a/packages/google-developers-knowledge/google/developers_knowledge_v1/py.typed b/packages/google-developers-knowledge/google/developers_knowledge_v1/py.typed deleted file mode 100644 index 184e0e4d53ea..000000000000 --- a/packages/google-developers-knowledge/google/developers_knowledge_v1/py.typed +++ /dev/null @@ -1,2 +0,0 @@ -# Marker file for PEP 561. -# The google-developers-knowledge package uses inline types. From 59fe7cf83c123102baf5439af4acd6218d7ce01b Mon Sep 17 00:00:00 2001 From: sofisl <55454395+sofisl@users.noreply.github.com> Date: Wed, 10 Jun 2026 16:59:19 -0700 Subject: [PATCH 055/174] feat: update API sources and regenerate (#17413) Update the googleapis source commit to d8daa97972d091191898915589335cef66fcdc8a and regenerate Python client libraries. --- librarian.yaml | 5 +- .../services/alloy_db_admin/async_client.py | 2 +- .../services/alloy_db_admin/client.py | 2 +- .../cloud/alloydb_v1/types/resources.py | 3 + ...ed_alloy_db_admin_upgrade_cluster_async.py | 2 +- ...ted_alloy_db_admin_upgrade_cluster_sync.py | 2 +- .../google/cloud/ces_v1beta/__init__.py | 30 +- .../cloud/ces_v1beta/gapic_metadata.json | 45 + .../services/agent_service/async_client.py | 2 + .../services/agent_service/client.py | 2 + .../evaluation_service/async_client.py | 411 + .../services/evaluation_service/client.py | 406 + .../evaluation_service/transports/base.py | 42 + .../evaluation_service/transports/grpc.py | 86 + .../transports/grpc_asyncio.py | 104 + .../evaluation_service/transports/rest.py | 749 +- .../transports/rest_base.py | 173 + .../services/tool_service/async_client.py | 9 +- .../services/tool_service/client.py | 9 +- .../google/cloud/ces_v1beta/types/__init__.py | 36 + .../google/cloud/ces_v1beta/types/agent.py | 17 + .../cloud/ces_v1beta/types/agent_card.py | 216 + .../cloud/ces_v1beta/types/agent_service.py | 35 + .../google/cloud/ces_v1beta/types/app.py | 101 +- .../cloud/ces_v1beta/types/conversation.py | 16 +- .../cloud/ces_v1beta/types/deployment.py | 102 + .../cloud/ces_v1beta/types/evaluation.py | 150 +- .../types/evaluation_metrics_config.py | 220 + .../ces_v1beta/types/evaluation_service.py | 125 + .../google/cloud/ces_v1beta/types/mcp_tool.py | 38 + .../cloud/ces_v1beta/types/mcp_toolset.py | 93 +- .../cloud/ces_v1beta/types/python_function.py | 10 + .../cloud/ces_v1beta/types/session_service.py | 7 + .../google/cloud/ces_v1beta/types/tool.py | 22 +- .../cloud/ces_v1beta/types/tool_service.py | 29 +- .../cloud/ces_v1beta/types/widget_tool.py | 61 + ...service_export_evaluation_results_async.py | 58 + ..._service_export_evaluation_results_sync.py | 58 + ...on_service_export_evaluation_runs_async.py | 58 + ...ion_service_export_evaluation_runs_sync.py | 58 + ...ice_run_evaluation_result_metrics_async.py | 57 + ...vice_run_evaluation_result_metrics_sync.py | 57 + ...ppet_metadata_google.cloud.ces.v1beta.json | 499 + .../gapic/ces_v1beta/test_agent_service.py | 358 + .../ces_v1beta/test_evaluation_service.py | 8218 ++- .../gapic/ces_v1beta/test_tool_service.py | 1 + .../confidential_computing/async_client.py | 2 + .../services/confidential_computing/client.py | 22 + .../confidentialcomputing_v1/types/service.py | 8 + .../test_confidential_computing.py | 52 +- .../google/cloud/modelarmor/__init__.py | 2 + .../google/cloud/modelarmor_v1/__init__.py | 2 + .../cloud/modelarmor_v1/gapic_metadata.json | 30 + .../services/model_armor/async_client.py | 177 + .../services/model_armor/client.py | 176 + .../services/model_armor/transports/base.py | 34 + .../services/model_armor/transports/grpc.py | 60 + .../model_armor/transports/grpc_asyncio.py | 72 + .../services/model_armor/transports/rest.py | 61 + .../model_armor/transports/rest_base.py | 8 + .../cloud/modelarmor_v1/types/__init__.py | 2 + .../cloud/modelarmor_v1/types/service.py | 50 + ...or_stream_sanitize_model_response_async.py | 68 + ...mor_stream_sanitize_model_response_sync.py | 68 + ...armor_stream_sanitize_user_prompt_async.py | 68 + ..._armor_stream_sanitize_user_prompt_sync.py | 68 + ...t_metadata_google.cloud.modelarmor.v1.json | 306 + .../gapic/modelarmor_v1/test_model_armor.py | 404 + .../google/cloud/oracledatabase/__init__.py | 198 + .../cloud/oracledatabase_v1/__init__.py | 198 + .../oracledatabase_v1/gapic_metadata.json | 345 + .../services/oracle_database/async_client.py | 3264 +- .../services/oracle_database/client.py | 3393 +- .../services/oracle_database/pagers.py | 1226 + .../oracle_database/transports/base.py | 495 + .../oracle_database/transports/grpc.py | 750 + .../transports/grpc_asyncio.py | 1427 +- .../oracle_database/transports/rest.py | 11127 +++- .../oracle_database/transports/rest_base.py | 1739 +- .../cloud/oracledatabase_v1/types/__init__.py | 198 + .../types/autonomous_database.py | 193 +- .../cloud/oracledatabase_v1/types/database.py | 49 +- .../oracledatabase_v1/types/db_system.py | 11 +- .../types/exascale_db_storage_vault.py | 8 + .../types/goldengate_connection.py | 4128 ++ .../types/goldengate_connection_assignment.py | 496 + .../types/goldengate_connection_type.py | 266 + .../types/goldengate_deployment.py | 1270 + .../goldengate_deployment_environment.py | 249 + .../types/goldengate_deployment_type.py | 285 + .../types/goldengate_deployment_version.py | 280 + .../oracledatabase_v1/types/oracledatabase.py | 42 +- .../oracledatabase_v1/types/vm_cluster.py | 4 +- ..._goldengate_connection_assignment_async.py | 69 + ...e_goldengate_connection_assignment_sync.py | 69 + ...base_create_goldengate_connection_async.py | 66 + ...abase_create_goldengate_connection_sync.py | 66 + ...base_create_goldengate_deployment_async.py | 67 + ...abase_create_goldengate_deployment_sync.py | 67 + ..._goldengate_connection_assignment_async.py | 57 + ...e_goldengate_connection_assignment_sync.py | 57 + ...base_delete_goldengate_connection_async.py | 57 + ...abase_delete_goldengate_connection_sync.py | 57 + ...base_delete_goldengate_deployment_async.py | 57 + ...abase_delete_goldengate_deployment_sync.py | 57 + ...base_failover_autonomous_database_async.py | 1 - ...abase_failover_autonomous_database_sync.py | 1 - ..._goldengate_connection_assignment_async.py | 53 + ...t_goldengate_connection_assignment_sync.py | 53 + ...atabase_get_goldengate_connection_async.py | 53 + ...database_get_goldengate_connection_sync.py | 53 + ...se_get_goldengate_connection_type_async.py | 53 + ...ase_get_goldengate_connection_type_sync.py | 53 + ...atabase_get_goldengate_deployment_async.py | 53 + ...goldengate_deployment_environment_async.py | 53 + ..._goldengate_deployment_environment_sync.py | 53 + ...database_get_goldengate_deployment_sync.py | 53 + ...se_get_goldengate_deployment_type_async.py | 53 + ...ase_get_goldengate_deployment_type_sync.py | 53 + ...get_goldengate_deployment_version_async.py | 53 + ..._get_goldengate_deployment_version_sync.py | 53 + ...goldengate_connection_assignments_async.py | 54 + ..._goldengate_connection_assignments_sync.py | 54 + ..._list_goldengate_connection_types_async.py | 54 + ...e_list_goldengate_connection_types_sync.py | 54 + ...abase_list_goldengate_connections_async.py | 54 + ...tabase_list_goldengate_connections_sync.py | 54 + ...oldengate_deployment_environments_async.py | 54 + ...goldengate_deployment_environments_sync.py | 54 + ..._list_goldengate_deployment_types_async.py | 54 + ...e_list_goldengate_deployment_types_sync.py | 54 + ...st_goldengate_deployment_versions_async.py | 54 + ...ist_goldengate_deployment_versions_sync.py | 54 + ...abase_list_goldengate_deployments_async.py | 54 + ...tabase_list_goldengate_deployments_sync.py | 54 + ...abase_start_goldengate_deployment_async.py | 57 + ...tabase_start_goldengate_deployment_sync.py | 57 + ...tabase_stop_goldengate_deployment_async.py | 57 + ...atabase_stop_goldengate_deployment_sync.py | 57 + ...se_switchover_autonomous_database_async.py | 1 - ...ase_switchover_autonomous_database_sync.py | 1 - ..._goldengate_connection_assignment_async.py | 53 + ...t_goldengate_connection_assignment_sync.py | 53 + ...tadata_google.cloud.oracledatabase.v1.json | 6331 ++- .../oracledatabase_v1/test_oracle_database.py | 45053 ++++++++++++---- 145 files changed, 80238 insertions(+), 19893 deletions(-) create mode 100644 packages/google-cloud-ces/google/cloud/ces_v1beta/types/agent_card.py create mode 100644 packages/google-cloud-ces/google/cloud/ces_v1beta/types/evaluation_metrics_config.py create mode 100644 packages/google-cloud-ces/samples/generated_samples/ces_v1beta_generated_evaluation_service_export_evaluation_results_async.py create mode 100644 packages/google-cloud-ces/samples/generated_samples/ces_v1beta_generated_evaluation_service_export_evaluation_results_sync.py create mode 100644 packages/google-cloud-ces/samples/generated_samples/ces_v1beta_generated_evaluation_service_export_evaluation_runs_async.py create mode 100644 packages/google-cloud-ces/samples/generated_samples/ces_v1beta_generated_evaluation_service_export_evaluation_runs_sync.py create mode 100644 packages/google-cloud-ces/samples/generated_samples/ces_v1beta_generated_evaluation_service_run_evaluation_result_metrics_async.py create mode 100644 packages/google-cloud-ces/samples/generated_samples/ces_v1beta_generated_evaluation_service_run_evaluation_result_metrics_sync.py create mode 100644 packages/google-cloud-modelarmor/samples/generated_samples/modelarmor_v1_generated_model_armor_stream_sanitize_model_response_async.py create mode 100644 packages/google-cloud-modelarmor/samples/generated_samples/modelarmor_v1_generated_model_armor_stream_sanitize_model_response_sync.py create mode 100644 packages/google-cloud-modelarmor/samples/generated_samples/modelarmor_v1_generated_model_armor_stream_sanitize_user_prompt_async.py create mode 100644 packages/google-cloud-modelarmor/samples/generated_samples/modelarmor_v1_generated_model_armor_stream_sanitize_user_prompt_sync.py create mode 100644 packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/goldengate_connection.py create mode 100644 packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/goldengate_connection_assignment.py create mode 100644 packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/goldengate_connection_type.py create mode 100644 packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/goldengate_deployment.py create mode 100644 packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/goldengate_deployment_environment.py create mode 100644 packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/goldengate_deployment_type.py create mode 100644 packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/goldengate_deployment_version.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_create_goldengate_connection_assignment_async.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_create_goldengate_connection_assignment_sync.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_create_goldengate_connection_async.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_create_goldengate_connection_sync.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_create_goldengate_deployment_async.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_create_goldengate_deployment_sync.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_delete_goldengate_connection_assignment_async.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_delete_goldengate_connection_assignment_sync.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_delete_goldengate_connection_async.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_delete_goldengate_connection_sync.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_delete_goldengate_deployment_async.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_delete_goldengate_deployment_sync.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_connection_assignment_async.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_connection_assignment_sync.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_connection_async.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_connection_sync.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_connection_type_async.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_connection_type_sync.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_async.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_environment_async.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_environment_sync.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_sync.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_type_async.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_type_sync.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_version_async.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_version_sync.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_connection_assignments_async.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_connection_assignments_sync.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_connection_types_async.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_connection_types_sync.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_connections_async.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_connections_sync.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_environments_async.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_environments_sync.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_types_async.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_types_sync.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_versions_async.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_versions_sync.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployments_async.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployments_sync.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_start_goldengate_deployment_async.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_start_goldengate_deployment_sync.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_stop_goldengate_deployment_async.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_stop_goldengate_deployment_sync.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_test_goldengate_connection_assignment_async.py create mode 100644 packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_test_goldengate_connection_assignment_sync.py diff --git a/librarian.yaml b/librarian.yaml index b14185f4a14c..9d89020f6cbe 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -16,8 +16,8 @@ version: v0.19.0 repo: googleapis/google-cloud-python sources: googleapis: - commit: ff15be54722218705740b9fc6223d264c4cdb6dd - sha256: 13dc3b1a01767be8d486980d3ddcb7fe6f6b89c3da8d41c358d5c2536c86de3c + commit: d8daa97972d091191898915589335cef66fcdc8a + sha256: 7dbdf2b1b667fe57128d41c77e530a2541767772cfe3487713f29b7b25d9f5ad default: output: packages tag_format: '{name}-v{version}' @@ -1151,6 +1151,7 @@ libraries: - docs/firestore_v1/transaction.rst - docs/firestore_v1/transforms.rst - docs/firestore_v1/types.rst + skip_generate: true skip_release: true python: library_type: GAPIC_COMBO diff --git a/packages/google-cloud-alloydb/google/cloud/alloydb_v1/services/alloy_db_admin/async_client.py b/packages/google-cloud-alloydb/google/cloud/alloydb_v1/services/alloy_db_admin/async_client.py index a4ac623f4067..d69ac8371553 100644 --- a/packages/google-cloud-alloydb/google/cloud/alloydb_v1/services/alloy_db_admin/async_client.py +++ b/packages/google-cloud-alloydb/google/cloud/alloydb_v1/services/alloy_db_admin/async_client.py @@ -1257,7 +1257,7 @@ async def sample_upgrade_cluster(): # Initialize request argument(s) request = alloydb_v1.UpgradeClusterRequest( name="name_value", - version="POSTGRES_17", + version="POSTGRES_18", ) # Make the request diff --git a/packages/google-cloud-alloydb/google/cloud/alloydb_v1/services/alloy_db_admin/client.py b/packages/google-cloud-alloydb/google/cloud/alloydb_v1/services/alloy_db_admin/client.py index 85cef8bbfc33..4438212295a2 100644 --- a/packages/google-cloud-alloydb/google/cloud/alloydb_v1/services/alloy_db_admin/client.py +++ b/packages/google-cloud-alloydb/google/cloud/alloydb_v1/services/alloy_db_admin/client.py @@ -1875,7 +1875,7 @@ def sample_upgrade_cluster(): # Initialize request argument(s) request = alloydb_v1.UpgradeClusterRequest( name="name_value", - version="POSTGRES_17", + version="POSTGRES_18", ) # Make the request diff --git a/packages/google-cloud-alloydb/google/cloud/alloydb_v1/types/resources.py b/packages/google-cloud-alloydb/google/cloud/alloydb_v1/types/resources.py index bad6a904c58b..03dc46f9b812 100644 --- a/packages/google-cloud-alloydb/google/cloud/alloydb_v1/types/resources.py +++ b/packages/google-cloud-alloydb/google/cloud/alloydb_v1/types/resources.py @@ -123,6 +123,8 @@ class DatabaseVersion(proto.Enum): The database version is Postgres 16. POSTGRES_17 (5): The database version is Postgres 17. + POSTGRES_18 (6): + The database version is Postgres 18. """ DATABASE_VERSION_UNSPECIFIED = 0 @@ -131,6 +133,7 @@ class DatabaseVersion(proto.Enum): POSTGRES_15 = 3 POSTGRES_16 = 4 POSTGRES_17 = 5 + POSTGRES_18 = 6 class SubscriptionType(proto.Enum): diff --git a/packages/google-cloud-alloydb/samples/generated_samples/alloydb_v1_generated_alloy_db_admin_upgrade_cluster_async.py b/packages/google-cloud-alloydb/samples/generated_samples/alloydb_v1_generated_alloy_db_admin_upgrade_cluster_async.py index 468e489cb04a..8807ad7a3861 100644 --- a/packages/google-cloud-alloydb/samples/generated_samples/alloydb_v1_generated_alloy_db_admin_upgrade_cluster_async.py +++ b/packages/google-cloud-alloydb/samples/generated_samples/alloydb_v1_generated_alloy_db_admin_upgrade_cluster_async.py @@ -41,7 +41,7 @@ async def sample_upgrade_cluster(): # Initialize request argument(s) request = alloydb_v1.UpgradeClusterRequest( name="name_value", - version="POSTGRES_17", + version="POSTGRES_18", ) # Make the request diff --git a/packages/google-cloud-alloydb/samples/generated_samples/alloydb_v1_generated_alloy_db_admin_upgrade_cluster_sync.py b/packages/google-cloud-alloydb/samples/generated_samples/alloydb_v1_generated_alloy_db_admin_upgrade_cluster_sync.py index a0785cb953e1..8bbdc785cc4e 100644 --- a/packages/google-cloud-alloydb/samples/generated_samples/alloydb_v1_generated_alloy_db_admin_upgrade_cluster_sync.py +++ b/packages/google-cloud-alloydb/samples/generated_samples/alloydb_v1_generated_alloy_db_admin_upgrade_cluster_sync.py @@ -41,7 +41,7 @@ def sample_upgrade_cluster(): # Initialize request argument(s) request = alloydb_v1.UpgradeClusterRequest( name="name_value", - version="POSTGRES_17", + version="POSTGRES_18", ) # Make the request diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/__init__.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/__init__.py index e4c758a90649..481866dfbb65 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/__init__.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/__init__.py @@ -32,6 +32,7 @@ from .services.tool_service import ToolServiceAsyncClient, ToolServiceClient from .services.widget_service import WidgetServiceAsyncClient, WidgetServiceClient from .types.agent import Agent +from .types.agent_card import AgentCard, AgentInterface, AgentSkill, RemoteAgentTool from .types.agent_service import ( BatchDeleteConversationsRequest, BatchDeleteConversationsResponse, @@ -129,6 +130,7 @@ RedactionConfig, SynthesizeSpeechConfig, TimeZoneSettings, + VpcScSettings, ) from .types.app_version import AppSnapshot, AppVersion from .types.auth import ( @@ -158,7 +160,7 @@ from .types.conversation import Conversation from .types.data_store import DataStore from .types.data_store_tool import DataStoreTool -from .types.deployment import Deployment +from .types.deployment import Deployment, ExperimentConfig from .types.evaluation import ( AggregatedMetrics, Evaluation, @@ -174,6 +176,7 @@ RunEvaluationRequest, ScheduledEvaluationRun, ) +from .types.evaluation_metrics_config import EvaluationMetricsConfig from .types.evaluation_service import ( CreateEvaluationDatasetRequest, CreateEvaluationExpectationRequest, @@ -186,7 +189,11 @@ DeleteEvaluationRunOperationMetadata, DeleteEvaluationRunRequest, DeleteScheduledEvaluationRunRequest, + ExportEvaluationResultsOperationMetadata, + ExportEvaluationResultsRequest, ExportEvaluationResultsResponse, + ExportEvaluationRunsOperationMetadata, + ExportEvaluationRunsRequest, ExportEvaluationRunsResponse, ExportEvaluationsRequest, ExportEvaluationsResponse, @@ -216,6 +223,9 @@ ListScheduledEvaluationRunsResponse, RunEvaluationOperationMetadata, RunEvaluationResponse, + RunEvaluationResultMetricsOperationMetadata, + RunEvaluationResultMetricsRequest, + RunEvaluationResultMetricsResponse, TestPersonaVoiceRequest, TestPersonaVoiceResponse, UpdateEvaluationDatasetRequest, @@ -242,7 +252,7 @@ from .types.google_search_tool import GoogleSearchTool from .types.guardrail import Guardrail from .types.mcp_tool import McpTool -from .types.mcp_toolset import McpToolset +from .types.mcp_toolset import McpToolDefinition, McpToolOverride, McpToolset from .types.mocks import MockedToolCall from .types.omnichannel import Omnichannel, OmnichannelIntegrationConfig from .types.omnichannel_service import OmnichannelOperationMetadata @@ -379,7 +389,10 @@ def _get_version(dependency_name): "WidgetServiceAsyncClient", "Action", "Agent", + "AgentCard", + "AgentInterface", "AgentServiceClient", + "AgentSkill", "AgentTool", "AgentTransfer", "AggregatedMetrics", @@ -454,6 +467,7 @@ def _get_version(dependency_name): "EvaluationDataset", "EvaluationErrorInfo", "EvaluationExpectation", + "EvaluationMetricsConfig", "EvaluationMetricsThresholds", "EvaluationPersona", "EvaluationResult", @@ -466,9 +480,14 @@ def _get_version(dependency_name): "ExecuteToolRequest", "ExecuteToolResponse", "ExecutionType", + "ExperimentConfig", "ExportAppRequest", "ExportAppResponse", + "ExportEvaluationResultsOperationMetadata", + "ExportEvaluationResultsRequest", "ExportEvaluationResultsResponse", + "ExportEvaluationRunsOperationMetadata", + "ExportEvaluationRunsRequest", "ExportEvaluationRunsResponse", "ExportEvaluationsRequest", "ExportEvaluationsResponse", @@ -549,6 +568,8 @@ def _get_version(dependency_name): "ListToolsetsResponse", "LoggingSettings", "McpTool", + "McpToolDefinition", + "McpToolOverride", "McpToolset", "Message", "MetricAnalysisSettings", @@ -570,6 +591,7 @@ def _get_version(dependency_name): "QualityReport", "RecognitionResult", "RedactionConfig", + "RemoteAgentTool", "RestoreAppVersionRequest", "RestoreAppVersionResponse", "RetrieveToolSchemaRequest", @@ -579,6 +601,9 @@ def _get_version(dependency_name): "RunEvaluationOperationMetadata", "RunEvaluationRequest", "RunEvaluationResponse", + "RunEvaluationResultMetricsOperationMetadata", + "RunEvaluationResultMetricsRequest", + "RunEvaluationResultMetricsResponse", "RunSessionRequest", "RunSessionResponse", "ScheduledEvaluationRun", @@ -623,6 +648,7 @@ def _get_version(dependency_name): "UpdateToolsetRequest", "UploadEvaluationAudioRequest", "UploadEvaluationAudioResponse", + "VpcScSettings", "WebSearchQuery", "WidgetServiceClient", "WidgetTool", diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/gapic_metadata.json b/packages/google-cloud-ces/google/cloud/ces_v1beta/gapic_metadata.json index dafb8cabd826..3087689d4deb 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/gapic_metadata.json +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/gapic_metadata.json @@ -844,6 +844,16 @@ "delete_scheduled_evaluation_run" ] }, + "ExportEvaluationResults": { + "methods": [ + "export_evaluation_results" + ] + }, + "ExportEvaluationRuns": { + "methods": [ + "export_evaluation_runs" + ] + }, "ExportEvaluations": { "methods": [ "export_evaluations" @@ -924,6 +934,11 @@ "run_evaluation" ] }, + "RunEvaluationResultMetrics": { + "methods": [ + "run_evaluation_result_metrics" + ] + }, "TestPersonaVoice": { "methods": [ "test_persona_voice" @@ -1009,6 +1024,16 @@ "delete_scheduled_evaluation_run" ] }, + "ExportEvaluationResults": { + "methods": [ + "export_evaluation_results" + ] + }, + "ExportEvaluationRuns": { + "methods": [ + "export_evaluation_runs" + ] + }, "ExportEvaluations": { "methods": [ "export_evaluations" @@ -1089,6 +1114,11 @@ "run_evaluation" ] }, + "RunEvaluationResultMetrics": { + "methods": [ + "run_evaluation_result_metrics" + ] + }, "TestPersonaVoice": { "methods": [ "test_persona_voice" @@ -1174,6 +1204,16 @@ "delete_scheduled_evaluation_run" ] }, + "ExportEvaluationResults": { + "methods": [ + "export_evaluation_results" + ] + }, + "ExportEvaluationRuns": { + "methods": [ + "export_evaluation_runs" + ] + }, "ExportEvaluations": { "methods": [ "export_evaluations" @@ -1254,6 +1294,11 @@ "run_evaluation" ] }, + "RunEvaluationResultMetrics": { + "methods": [ + "run_evaluation_result_metrics" + ] + }, "TestPersonaVoice": { "methods": [ "test_persona_voice" diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/services/agent_service/async_client.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/services/agent_service/async_client.py index a50189f0b3eb..e6c75d744c9a 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/services/agent_service/async_client.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/services/agent_service/async_client.py @@ -46,6 +46,7 @@ import google.api_core.operation as operation # type: ignore import google.api_core.operation_async as operation_async # type: ignore +import google.protobuf.duration_pb2 as duration_pb2 # type: ignore import google.protobuf.empty_pb2 as empty_pb2 # type: ignore import google.protobuf.field_mask_pb2 as field_mask_pb2 # type: ignore import google.protobuf.struct_pb2 as struct_pb2 # type: ignore @@ -56,6 +57,7 @@ from google.cloud.ces_v1beta.services.agent_service import pagers from google.cloud.ces_v1beta.types import ( agent, + agent_card, agent_service, agent_tool, agent_transfers, diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/services/agent_service/client.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/services/agent_service/client.py index 150f45cf8a5b..f597780f2eb3 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/services/agent_service/client.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/services/agent_service/client.py @@ -63,6 +63,7 @@ import google.api_core.operation as operation # type: ignore import google.api_core.operation_async as operation_async # type: ignore +import google.protobuf.duration_pb2 as duration_pb2 # type: ignore import google.protobuf.empty_pb2 as empty_pb2 # type: ignore import google.protobuf.field_mask_pb2 as field_mask_pb2 # type: ignore import google.protobuf.struct_pb2 as struct_pb2 # type: ignore @@ -73,6 +74,7 @@ from google.cloud.ces_v1beta.services.agent_service import pagers from google.cloud.ces_v1beta.types import ( agent, + agent_card, agent_service, agent_tool, agent_transfers, diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/services/evaluation_service/async_client.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/services/evaluation_service/async_client.py index 12ef7b4bae63..01b63e1822eb 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/services/evaluation_service/async_client.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/services/evaluation_service/async_client.py @@ -59,6 +59,7 @@ agent_service, app, evaluation, + evaluation_metrics_config, evaluation_service, golden_run, ) @@ -4338,6 +4339,416 @@ async def sample_export_evaluations(): # Done; return the response. return response + async def export_evaluation_runs( + self, + request: Optional[ + Union[evaluation_service.ExportEvaluationRunsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + names: Optional[MutableSequence[str]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""Exports evaluations runs. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import ces_v1beta + + async def sample_export_evaluation_runs(): + # Create a client + client = ces_v1beta.EvaluationServiceAsyncClient() + + # Initialize request argument(s) + request = ces_v1beta.ExportEvaluationRunsRequest( + parent="parent_value", + names=['names_value1', 'names_value2'], + ) + + # Make the request + operation = await client.export_evaluation_runs(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.ces_v1beta.types.ExportEvaluationRunsRequest, dict]]): + The request object. Request message for + [EvaluationService.ExportEvaluationRuns][google.cloud.ces.v1beta.EvaluationService.ExportEvaluationRuns]. + parent (:class:`str`): + Required. The resource name of the app to export + evaluation runs from. Format: + ``projects/{project}/locations/{location}/apps/{app}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + names (:class:`MutableSequence[str]`): + Required. The resource names of the + evaluation runs to export. + + This corresponds to the ``names`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + 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.ces_v1beta.types.ExportEvaluationRunsResponse` Response message for + [EvaluationService.ExportEvaluationRuns][google.cloud.ces.v1beta.EvaluationService.ExportEvaluationRuns]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, names] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, evaluation_service.ExportEvaluationRunsRequest): + request = evaluation_service.ExportEvaluationRunsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if names: + request.names.extend(names) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.export_evaluation_runs + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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, + evaluation_service.ExportEvaluationRunsResponse, + metadata_type=evaluation_service.ExportEvaluationRunsOperationMetadata, + ) + + # Done; return the response. + return response + + async def export_evaluation_results( + self, + request: Optional[ + Union[evaluation_service.ExportEvaluationResultsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + names: Optional[MutableSequence[str]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""Exports evaluations results. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import ces_v1beta + + async def sample_export_evaluation_results(): + # Create a client + client = ces_v1beta.EvaluationServiceAsyncClient() + + # Initialize request argument(s) + request = ces_v1beta.ExportEvaluationResultsRequest( + parent="parent_value", + names=['names_value1', 'names_value2'], + ) + + # Make the request + operation = await client.export_evaluation_results(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.ces_v1beta.types.ExportEvaluationResultsRequest, dict]]): + The request object. Request message for + [EvaluationService.ExportEvaluationResults][google.cloud.ces.v1beta.EvaluationService.ExportEvaluationResults]. + parent (:class:`str`): + Required. The resource name of the evaluation to export + evaluation results from. Format: + ``projects/{project}/locations/{location}/apps/{app}/evaluations/{evaluation}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + names (:class:`MutableSequence[str]`): + Required. The resource names of the + evaluation results to export. + + This corresponds to the ``names`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + 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.ces_v1beta.types.ExportEvaluationResultsResponse` Response message for + [EvaluationService.ExportEvaluationResults][google.cloud.ces.v1beta.EvaluationService.ExportEvaluationResults]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, names] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, evaluation_service.ExportEvaluationResultsRequest): + request = evaluation_service.ExportEvaluationResultsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if names: + request.names.extend(names) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.export_evaluation_results + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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, + evaluation_service.ExportEvaluationResultsResponse, + metadata_type=evaluation_service.ExportEvaluationResultsOperationMetadata, + ) + + # Done; return the response. + return response + + async def run_evaluation_result_metrics( + self, + request: Optional[ + Union[evaluation_service.RunEvaluationResultMetricsRequest, dict] + ] = None, + *, + evaluation_result_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""Runs metrics on an existing evaluation result. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import ces_v1beta + + async def sample_run_evaluation_result_metrics(): + # Create a client + client = ces_v1beta.EvaluationServiceAsyncClient() + + # Initialize request argument(s) + request = ces_v1beta.RunEvaluationResultMetricsRequest( + evaluation_result_id="evaluation_result_id_value", + ) + + # Make the request + operation = await client.run_evaluation_result_metrics(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.ces_v1beta.types.RunEvaluationResultMetricsRequest, dict]]): + The request object. Request message for + [EvaluationService.RunEvaluationResultMetrics][google.cloud.ces.v1beta.EvaluationService.RunEvaluationResultMetrics]. + evaluation_result_id (:class:`str`): + Required. The evaluation result to run metrics for. + Format: + ``projects/{project}/locations/{location}/apps/{app}/evaluations/{evaluation}/results/{evaluation_result_id}`` + + This corresponds to the ``evaluation_result_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + 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.ces_v1beta.types.RunEvaluationResultMetricsResponse` Response message for + [EvaluationService.RunEvaluationResultMetrics][google.cloud.ces.v1beta.EvaluationService.RunEvaluationResultMetrics]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [evaluation_result_id] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, evaluation_service.RunEvaluationResultMetricsRequest + ): + request = evaluation_service.RunEvaluationResultMetricsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if evaluation_result_id is not None: + request.evaluation_result_id = evaluation_result_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.run_evaluation_result_metrics + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("evaluation_result_id", request.evaluation_result_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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, + evaluation_service.RunEvaluationResultMetricsResponse, + metadata_type=evaluation_service.RunEvaluationResultMetricsOperationMetadata, + ) + + # Done; return the response. + return response + async def list_operations( self, request: Optional[Union[operations_pb2.ListOperationsRequest, dict]] = None, diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/services/evaluation_service/client.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/services/evaluation_service/client.py index 5970277fcce8..dfd9aa0e4880 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/services/evaluation_service/client.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/services/evaluation_service/client.py @@ -76,6 +76,7 @@ agent_service, app, evaluation, + evaluation_metrics_config, evaluation_service, golden_run, ) @@ -4971,6 +4972,411 @@ def sample_export_evaluations(): # Done; return the response. return response + def export_evaluation_runs( + self, + request: Optional[ + Union[evaluation_service.ExportEvaluationRunsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + names: Optional[MutableSequence[str]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Exports evaluations runs. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import ces_v1beta + + def sample_export_evaluation_runs(): + # Create a client + client = ces_v1beta.EvaluationServiceClient() + + # Initialize request argument(s) + request = ces_v1beta.ExportEvaluationRunsRequest( + parent="parent_value", + names=['names_value1', 'names_value2'], + ) + + # Make the request + operation = client.export_evaluation_runs(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.ces_v1beta.types.ExportEvaluationRunsRequest, dict]): + The request object. Request message for + [EvaluationService.ExportEvaluationRuns][google.cloud.ces.v1beta.EvaluationService.ExportEvaluationRuns]. + parent (str): + Required. The resource name of the app to export + evaluation runs from. Format: + ``projects/{project}/locations/{location}/apps/{app}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + names (MutableSequence[str]): + Required. The resource names of the + evaluation runs to export. + + This corresponds to the ``names`` 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.ces_v1beta.types.ExportEvaluationRunsResponse` Response message for + [EvaluationService.ExportEvaluationRuns][google.cloud.ces.v1beta.EvaluationService.ExportEvaluationRuns]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, names] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, evaluation_service.ExportEvaluationRunsRequest): + request = evaluation_service.ExportEvaluationRunsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if names is not None: + request.names = names + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.export_evaluation_runs] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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, + evaluation_service.ExportEvaluationRunsResponse, + metadata_type=evaluation_service.ExportEvaluationRunsOperationMetadata, + ) + + # Done; return the response. + return response + + def export_evaluation_results( + self, + request: Optional[ + Union[evaluation_service.ExportEvaluationResultsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + names: Optional[MutableSequence[str]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Exports evaluations results. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import ces_v1beta + + def sample_export_evaluation_results(): + # Create a client + client = ces_v1beta.EvaluationServiceClient() + + # Initialize request argument(s) + request = ces_v1beta.ExportEvaluationResultsRequest( + parent="parent_value", + names=['names_value1', 'names_value2'], + ) + + # Make the request + operation = client.export_evaluation_results(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.ces_v1beta.types.ExportEvaluationResultsRequest, dict]): + The request object. Request message for + [EvaluationService.ExportEvaluationResults][google.cloud.ces.v1beta.EvaluationService.ExportEvaluationResults]. + parent (str): + Required. The resource name of the evaluation to export + evaluation results from. Format: + ``projects/{project}/locations/{location}/apps/{app}/evaluations/{evaluation}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + names (MutableSequence[str]): + Required. The resource names of the + evaluation results to export. + + This corresponds to the ``names`` 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.ces_v1beta.types.ExportEvaluationResultsResponse` Response message for + [EvaluationService.ExportEvaluationResults][google.cloud.ces.v1beta.EvaluationService.ExportEvaluationResults]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, names] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, evaluation_service.ExportEvaluationResultsRequest): + request = evaluation_service.ExportEvaluationResultsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if names is not None: + request.names = names + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.export_evaluation_results + ] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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, + evaluation_service.ExportEvaluationResultsResponse, + metadata_type=evaluation_service.ExportEvaluationResultsOperationMetadata, + ) + + # Done; return the response. + return response + + def run_evaluation_result_metrics( + self, + request: Optional[ + Union[evaluation_service.RunEvaluationResultMetricsRequest, dict] + ] = None, + *, + evaluation_result_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Runs metrics on an existing evaluation result. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import ces_v1beta + + def sample_run_evaluation_result_metrics(): + # Create a client + client = ces_v1beta.EvaluationServiceClient() + + # Initialize request argument(s) + request = ces_v1beta.RunEvaluationResultMetricsRequest( + evaluation_result_id="evaluation_result_id_value", + ) + + # Make the request + operation = client.run_evaluation_result_metrics(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.ces_v1beta.types.RunEvaluationResultMetricsRequest, dict]): + The request object. Request message for + [EvaluationService.RunEvaluationResultMetrics][google.cloud.ces.v1beta.EvaluationService.RunEvaluationResultMetrics]. + evaluation_result_id (str): + Required. The evaluation result to run metrics for. + Format: + ``projects/{project}/locations/{location}/apps/{app}/evaluations/{evaluation}/results/{evaluation_result_id}`` + + This corresponds to the ``evaluation_result_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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.ces_v1beta.types.RunEvaluationResultMetricsResponse` Response message for + [EvaluationService.RunEvaluationResultMetrics][google.cloud.ces.v1beta.EvaluationService.RunEvaluationResultMetrics]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [evaluation_result_id] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, evaluation_service.RunEvaluationResultMetricsRequest + ): + request = evaluation_service.RunEvaluationResultMetricsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if evaluation_result_id is not None: + request.evaluation_result_id = evaluation_result_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.run_evaluation_result_metrics + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("evaluation_result_id", request.evaluation_result_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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, + evaluation_service.RunEvaluationResultMetricsResponse, + metadata_type=evaluation_service.RunEvaluationResultMetricsOperationMetadata, + ) + + # Done; return the response. + return response + def __enter__(self) -> "EvaluationServiceClient": return self diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/services/evaluation_service/transports/base.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/services/evaluation_service/transports/base.py index ffe680dd2321..36d84279a696 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/services/evaluation_service/transports/base.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/services/evaluation_service/transports/base.py @@ -309,6 +309,21 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.export_evaluation_runs: gapic_v1.method.wrap_method( + self.export_evaluation_runs, + default_timeout=None, + client_info=client_info, + ), + self.export_evaluation_results: gapic_v1.method.wrap_method( + self.export_evaluation_results, + default_timeout=None, + client_info=client_info, + ), + self.run_evaluation_result_metrics: gapic_v1.method.wrap_method( + self.run_evaluation_result_metrics, + default_timeout=None, + client_info=client_info, + ), self.get_location: gapic_v1.method.wrap_method( self.get_location, default_timeout=None, @@ -685,6 +700,33 @@ def export_evaluations( ]: raise NotImplementedError() + @property + def export_evaluation_runs( + self, + ) -> Callable[ + [evaluation_service.ExportEvaluationRunsRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def export_evaluation_results( + self, + ) -> Callable[ + [evaluation_service.ExportEvaluationResultsRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def run_evaluation_result_metrics( + self, + ) -> Callable[ + [evaluation_service.RunEvaluationResultMetricsRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + @property def list_operations( self, diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/services/evaluation_service/transports/grpc.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/services/evaluation_service/transports/grpc.py index 5c44ba90da45..43bc1f08eaca 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/services/evaluation_service/transports/grpc.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/services/evaluation_service/transports/grpc.py @@ -1277,6 +1277,92 @@ def export_evaluations( ) return self._stubs["export_evaluations"] + @property + def export_evaluation_runs( + self, + ) -> Callable[ + [evaluation_service.ExportEvaluationRunsRequest], operations_pb2.Operation + ]: + r"""Return a callable for the export evaluation runs method over gRPC. + + Exports evaluations runs. + + Returns: + Callable[[~.ExportEvaluationRunsRequest], + ~.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 "export_evaluation_runs" not in self._stubs: + self._stubs["export_evaluation_runs"] = self._logged_channel.unary_unary( + "/google.cloud.ces.v1beta.EvaluationService/ExportEvaluationRuns", + request_serializer=evaluation_service.ExportEvaluationRunsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["export_evaluation_runs"] + + @property + def export_evaluation_results( + self, + ) -> Callable[ + [evaluation_service.ExportEvaluationResultsRequest], operations_pb2.Operation + ]: + r"""Return a callable for the export evaluation results method over gRPC. + + Exports evaluations results. + + Returns: + Callable[[~.ExportEvaluationResultsRequest], + ~.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 "export_evaluation_results" not in self._stubs: + self._stubs["export_evaluation_results"] = self._logged_channel.unary_unary( + "/google.cloud.ces.v1beta.EvaluationService/ExportEvaluationResults", + request_serializer=evaluation_service.ExportEvaluationResultsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["export_evaluation_results"] + + @property + def run_evaluation_result_metrics( + self, + ) -> Callable[ + [evaluation_service.RunEvaluationResultMetricsRequest], operations_pb2.Operation + ]: + r"""Return a callable for the run evaluation result metrics method over gRPC. + + Runs metrics on an existing evaluation result. + + Returns: + Callable[[~.RunEvaluationResultMetricsRequest], + ~.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 "run_evaluation_result_metrics" not in self._stubs: + self._stubs["run_evaluation_result_metrics"] = ( + self._logged_channel.unary_unary( + "/google.cloud.ces.v1beta.EvaluationService/RunEvaluationResultMetrics", + request_serializer=evaluation_service.RunEvaluationResultMetricsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + ) + return self._stubs["run_evaluation_result_metrics"] + def close(self): self._logged_channel.close() diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/services/evaluation_service/transports/grpc_asyncio.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/services/evaluation_service/transports/grpc_asyncio.py index f8a3eea12bb8..d7c9e17078c5 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/services/evaluation_service/transports/grpc_asyncio.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/services/evaluation_service/transports/grpc_asyncio.py @@ -1306,6 +1306,95 @@ def export_evaluations( ) return self._stubs["export_evaluations"] + @property + def export_evaluation_runs( + self, + ) -> Callable[ + [evaluation_service.ExportEvaluationRunsRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the export evaluation runs method over gRPC. + + Exports evaluations runs. + + Returns: + Callable[[~.ExportEvaluationRunsRequest], + 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 "export_evaluation_runs" not in self._stubs: + self._stubs["export_evaluation_runs"] = self._logged_channel.unary_unary( + "/google.cloud.ces.v1beta.EvaluationService/ExportEvaluationRuns", + request_serializer=evaluation_service.ExportEvaluationRunsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["export_evaluation_runs"] + + @property + def export_evaluation_results( + self, + ) -> Callable[ + [evaluation_service.ExportEvaluationResultsRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the export evaluation results method over gRPC. + + Exports evaluations results. + + Returns: + Callable[[~.ExportEvaluationResultsRequest], + 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 "export_evaluation_results" not in self._stubs: + self._stubs["export_evaluation_results"] = self._logged_channel.unary_unary( + "/google.cloud.ces.v1beta.EvaluationService/ExportEvaluationResults", + request_serializer=evaluation_service.ExportEvaluationResultsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["export_evaluation_results"] + + @property + def run_evaluation_result_metrics( + self, + ) -> Callable[ + [evaluation_service.RunEvaluationResultMetricsRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the run evaluation result metrics method over gRPC. + + Runs metrics on an existing evaluation result. + + Returns: + Callable[[~.RunEvaluationResultMetricsRequest], + 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 "run_evaluation_result_metrics" not in self._stubs: + self._stubs["run_evaluation_result_metrics"] = ( + self._logged_channel.unary_unary( + "/google.cloud.ces.v1beta.EvaluationService/RunEvaluationResultMetrics", + request_serializer=evaluation_service.RunEvaluationResultMetricsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + ) + return self._stubs["run_evaluation_result_metrics"] + def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { @@ -1469,6 +1558,21 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.export_evaluation_runs: self._wrap_method( + self.export_evaluation_runs, + default_timeout=None, + client_info=client_info, + ), + self.export_evaluation_results: self._wrap_method( + self.export_evaluation_results, + default_timeout=None, + client_info=client_info, + ), + self.run_evaluation_result_metrics: self._wrap_method( + self.run_evaluation_result_metrics, + default_timeout=None, + client_info=client_info, + ), self.get_location: self._wrap_method( self.get_location, default_timeout=None, diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/services/evaluation_service/transports/rest.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/services/evaluation_service/transports/rest.py index c0d10bfd75cb..11f9cbdd0b05 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/services/evaluation_service/transports/rest.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/services/evaluation_service/transports/rest.py @@ -136,6 +136,22 @@ def pre_delete_scheduled_evaluation_run(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata + def pre_export_evaluation_results(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_export_evaluation_results(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_export_evaluation_runs(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_export_evaluation_runs(self, response): + logging.log(f"Received response: {response}") + return response + def pre_export_evaluations(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -264,6 +280,14 @@ def post_run_evaluation(self, response): logging.log(f"Received response: {response}") return response + def pre_run_evaluation_result_metrics(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_run_evaluation_result_metrics(self, response): + logging.log(f"Received response: {response}") + return response + def pre_test_persona_voice(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -642,6 +666,104 @@ def pre_delete_scheduled_evaluation_run( """ return request, metadata + def pre_export_evaluation_results( + self, + request: evaluation_service.ExportEvaluationResultsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + evaluation_service.ExportEvaluationResultsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for export_evaluation_results + + Override in a subclass to manipulate the request or metadata + before they are sent to the EvaluationService server. + """ + return request, metadata + + def post_export_evaluation_results( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for export_evaluation_results + + DEPRECATED. Please use the `post_export_evaluation_results_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the EvaluationService server but before + it is returned to user code. This `post_export_evaluation_results` interceptor runs + before the `post_export_evaluation_results_with_metadata` interceptor. + """ + return response + + def post_export_evaluation_results_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for export_evaluation_results + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EvaluationService server but before it is returned to user code. + + We recommend only using this `post_export_evaluation_results_with_metadata` + interceptor in new development instead of the `post_export_evaluation_results` interceptor. + When both interceptors are used, this `post_export_evaluation_results_with_metadata` interceptor runs after the + `post_export_evaluation_results` interceptor. The (possibly modified) response returned by + `post_export_evaluation_results` will be passed to + `post_export_evaluation_results_with_metadata`. + """ + return response, metadata + + def pre_export_evaluation_runs( + self, + request: evaluation_service.ExportEvaluationRunsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + evaluation_service.ExportEvaluationRunsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for export_evaluation_runs + + Override in a subclass to manipulate the request or metadata + before they are sent to the EvaluationService server. + """ + return request, metadata + + def post_export_evaluation_runs( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for export_evaluation_runs + + DEPRECATED. Please use the `post_export_evaluation_runs_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the EvaluationService server but before + it is returned to user code. This `post_export_evaluation_runs` interceptor runs + before the `post_export_evaluation_runs_with_metadata` interceptor. + """ + return response + + def post_export_evaluation_runs_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for export_evaluation_runs + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EvaluationService server but before it is returned to user code. + + We recommend only using this `post_export_evaluation_runs_with_metadata` + interceptor in new development instead of the `post_export_evaluation_runs` interceptor. + When both interceptors are used, this `post_export_evaluation_runs_with_metadata` interceptor runs after the + `post_export_evaluation_runs` interceptor. The (possibly modified) response returned by + `post_export_evaluation_runs` will be passed to + `post_export_evaluation_runs_with_metadata`. + """ + return response, metadata + def pre_export_evaluations( self, request: evaluation_service.ExportEvaluationsRequest, @@ -1446,6 +1568,55 @@ def post_run_evaluation_with_metadata( """ return response, metadata + def pre_run_evaluation_result_metrics( + self, + request: evaluation_service.RunEvaluationResultMetricsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + evaluation_service.RunEvaluationResultMetricsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for run_evaluation_result_metrics + + Override in a subclass to manipulate the request or metadata + before they are sent to the EvaluationService server. + """ + return request, metadata + + def post_run_evaluation_result_metrics( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for run_evaluation_result_metrics + + DEPRECATED. Please use the `post_run_evaluation_result_metrics_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the EvaluationService server but before + it is returned to user code. This `post_run_evaluation_result_metrics` interceptor runs + before the `post_run_evaluation_result_metrics_with_metadata` interceptor. + """ + return response + + def post_run_evaluation_result_metrics_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for run_evaluation_result_metrics + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EvaluationService server but before it is returned to user code. + + We recommend only using this `post_run_evaluation_result_metrics_with_metadata` + interceptor in new development instead of the `post_run_evaluation_result_metrics` interceptor. + When both interceptors are used, this `post_run_evaluation_result_metrics_with_metadata` interceptor runs after the + `post_run_evaluation_result_metrics` interceptor. The (possibly modified) response returned by + `post_run_evaluation_result_metrics` will be passed to + `post_run_evaluation_result_metrics_with_metadata`. + """ + return response, metadata + def pre_test_persona_voice( self, request: evaluation_service.TestPersonaVoiceRequest, @@ -3181,7 +3352,270 @@ def __call__( ) # Jsonify the query params - query_params = _BaseEvaluationServiceRestTransport._BaseDeleteEvaluationRun._get_query_params_json( + query_params = _BaseEvaluationServiceRestTransport._BaseDeleteEvaluationRun._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.ces_v1beta.EvaluationServiceClient.DeleteEvaluationRun", + extra={ + "serviceName": "google.cloud.ces.v1beta.EvaluationService", + "rpcName": "DeleteEvaluationRun", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + EvaluationServiceRestTransport._DeleteEvaluationRun._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_delete_evaluation_run(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_evaluation_run_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.ces_v1beta.EvaluationServiceClient.delete_evaluation_run", + extra={ + "serviceName": "google.cloud.ces.v1beta.EvaluationService", + "rpcName": "DeleteEvaluationRun", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _DeleteScheduledEvaluationRun( + _BaseEvaluationServiceRestTransport._BaseDeleteScheduledEvaluationRun, + EvaluationServiceRestStub, + ): + def __hash__(self): + return hash("EvaluationServiceRestTransport.DeleteScheduledEvaluationRun") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: evaluation_service.DeleteScheduledEvaluationRunRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + r"""Call the delete scheduled + evaluation run method over HTTP. + + Args: + request (~.evaluation_service.DeleteScheduledEvaluationRunRequest): + The request object. Request message for + [EvaluationService.DeleteScheduledEvaluationRun][google.cloud.ces.v1beta.EvaluationService.DeleteScheduledEvaluationRun]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + + http_options = _BaseEvaluationServiceRestTransport._BaseDeleteScheduledEvaluationRun._get_http_options() + + request, metadata = self._interceptor.pre_delete_scheduled_evaluation_run( + request, metadata + ) + transcoded_request = _BaseEvaluationServiceRestTransport._BaseDeleteScheduledEvaluationRun._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseEvaluationServiceRestTransport._BaseDeleteScheduledEvaluationRun._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.ces_v1beta.EvaluationServiceClient.DeleteScheduledEvaluationRun", + extra={ + "serviceName": "google.cloud.ces.v1beta.EvaluationService", + "rpcName": "DeleteScheduledEvaluationRun", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = EvaluationServiceRestTransport._DeleteScheduledEvaluationRun._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + class _ExportEvaluationResults( + _BaseEvaluationServiceRestTransport._BaseExportEvaluationResults, + EvaluationServiceRestStub, + ): + def __hash__(self): + return hash("EvaluationServiceRestTransport.ExportEvaluationResults") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: evaluation_service.ExportEvaluationResultsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the export evaluation results method over HTTP. + + Args: + request (~.evaluation_service.ExportEvaluationResultsRequest): + The request object. Request message for + [EvaluationService.ExportEvaluationResults][google.cloud.ces.v1beta.EvaluationService.ExportEvaluationResults]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseEvaluationServiceRestTransport._BaseExportEvaluationResults._get_http_options() + + request, metadata = self._interceptor.pre_export_evaluation_results( + request, metadata + ) + transcoded_request = _BaseEvaluationServiceRestTransport._BaseExportEvaluationResults._get_transcoded_request( + http_options, request + ) + + body = _BaseEvaluationServiceRestTransport._BaseExportEvaluationResults._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseEvaluationServiceRestTransport._BaseExportEvaluationResults._get_query_params_json( transcoded_request ) @@ -3203,10 +3637,10 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.ces_v1beta.EvaluationServiceClient.DeleteEvaluationRun", + f"Sending request for google.cloud.ces_v1beta.EvaluationServiceClient.ExportEvaluationResults", extra={ "serviceName": "google.cloud.ces.v1beta.EvaluationService", - "rpcName": "DeleteEvaluationRun", + "rpcName": "ExportEvaluationResults", "httpRequest": http_request, "metadata": http_request["headers"], }, @@ -3214,13 +3648,14 @@ def __call__( # Send the request response = ( - EvaluationServiceRestTransport._DeleteEvaluationRun._get_response( + EvaluationServiceRestTransport._ExportEvaluationResults._get_response( self._host, metadata, query_params, self._session, timeout, transcoded_request, + body, ) ) @@ -3233,9 +3668,9 @@ def __call__( resp = operations_pb2.Operation() json_format.Parse(response.content, resp, ignore_unknown_fields=True) - resp = self._interceptor.post_delete_evaluation_run(resp) + resp = self._interceptor.post_export_evaluation_results(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_delete_evaluation_run_with_metadata( + resp, _ = self._interceptor.post_export_evaluation_results_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( @@ -3251,22 +3686,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.ces_v1beta.EvaluationServiceClient.delete_evaluation_run", + "Received response for google.cloud.ces_v1beta.EvaluationServiceClient.export_evaluation_results", extra={ "serviceName": "google.cloud.ces.v1beta.EvaluationService", - "rpcName": "DeleteEvaluationRun", + "rpcName": "ExportEvaluationResults", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _DeleteScheduledEvaluationRun( - _BaseEvaluationServiceRestTransport._BaseDeleteScheduledEvaluationRun, + class _ExportEvaluationRuns( + _BaseEvaluationServiceRestTransport._BaseExportEvaluationRuns, EvaluationServiceRestStub, ): def __hash__(self): - return hash("EvaluationServiceRestTransport.DeleteScheduledEvaluationRun") + return hash("EvaluationServiceRestTransport.ExportEvaluationRuns") @staticmethod def _get_response( @@ -3287,44 +3722,55 @@ def _get_response( timeout=timeout, headers=headers, params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, ) return response def __call__( self, - request: evaluation_service.DeleteScheduledEvaluationRunRequest, + request: evaluation_service.ExportEvaluationRunsRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ): - r"""Call the delete scheduled - evaluation run method over HTTP. + ) -> operations_pb2.Operation: + r"""Call the export evaluation runs method over HTTP. + + Args: + request (~.evaluation_service.ExportEvaluationRunsRequest): + The request object. Request message for + [EvaluationService.ExportEvaluationRuns][google.cloud.ces.v1beta.EvaluationService.ExportEvaluationRuns]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. - Args: - request (~.evaluation_service.DeleteScheduledEvaluationRunRequest): - The request object. Request message for - [EvaluationService.DeleteScheduledEvaluationRun][google.cloud.ces.v1beta.EvaluationService.DeleteScheduledEvaluationRun]. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. """ - http_options = _BaseEvaluationServiceRestTransport._BaseDeleteScheduledEvaluationRun._get_http_options() + http_options = _BaseEvaluationServiceRestTransport._BaseExportEvaluationRuns._get_http_options() - request, metadata = self._interceptor.pre_delete_scheduled_evaluation_run( + request, metadata = self._interceptor.pre_export_evaluation_runs( request, metadata ) - transcoded_request = _BaseEvaluationServiceRestTransport._BaseDeleteScheduledEvaluationRun._get_transcoded_request( + transcoded_request = _BaseEvaluationServiceRestTransport._BaseExportEvaluationRuns._get_transcoded_request( http_options, request ) + body = _BaseEvaluationServiceRestTransport._BaseExportEvaluationRuns._get_request_body_json( + transcoded_request + ) + # Jsonify the query params - query_params = _BaseEvaluationServiceRestTransport._BaseDeleteScheduledEvaluationRun._get_query_params_json( + query_params = _BaseEvaluationServiceRestTransport._BaseExportEvaluationRuns._get_query_params_json( transcoded_request ) @@ -3346,23 +3792,26 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.ces_v1beta.EvaluationServiceClient.DeleteScheduledEvaluationRun", + f"Sending request for google.cloud.ces_v1beta.EvaluationServiceClient.ExportEvaluationRuns", extra={ "serviceName": "google.cloud.ces.v1beta.EvaluationService", - "rpcName": "DeleteScheduledEvaluationRun", + "rpcName": "ExportEvaluationRuns", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = EvaluationServiceRestTransport._DeleteScheduledEvaluationRun._get_response( - self._host, - metadata, - query_params, - self._session, - timeout, - transcoded_request, + response = ( + EvaluationServiceRestTransport._ExportEvaluationRuns._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -3370,6 +3819,38 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_export_evaluation_runs(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_export_evaluation_runs_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.ces_v1beta.EvaluationServiceClient.export_evaluation_runs", + extra={ + "serviceName": "google.cloud.ces.v1beta.EvaluationService", + "rpcName": "ExportEvaluationRuns", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + class _ExportEvaluations( _BaseEvaluationServiceRestTransport._BaseExportEvaluations, EvaluationServiceRestStub, @@ -5799,6 +6280,162 @@ def __call__( ) return resp + class _RunEvaluationResultMetrics( + _BaseEvaluationServiceRestTransport._BaseRunEvaluationResultMetrics, + EvaluationServiceRestStub, + ): + def __hash__(self): + return hash("EvaluationServiceRestTransport.RunEvaluationResultMetrics") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: evaluation_service.RunEvaluationResultMetricsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the run evaluation result + metrics method over HTTP. + + Args: + request (~.evaluation_service.RunEvaluationResultMetricsRequest): + The request object. Request message for + [EvaluationService.RunEvaluationResultMetrics][google.cloud.ces.v1beta.EvaluationService.RunEvaluationResultMetrics]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseEvaluationServiceRestTransport._BaseRunEvaluationResultMetrics._get_http_options() + + request, metadata = self._interceptor.pre_run_evaluation_result_metrics( + request, metadata + ) + transcoded_request = _BaseEvaluationServiceRestTransport._BaseRunEvaluationResultMetrics._get_transcoded_request( + http_options, request + ) + + body = _BaseEvaluationServiceRestTransport._BaseRunEvaluationResultMetrics._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseEvaluationServiceRestTransport._BaseRunEvaluationResultMetrics._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.ces_v1beta.EvaluationServiceClient.RunEvaluationResultMetrics", + extra={ + "serviceName": "google.cloud.ces.v1beta.EvaluationService", + "rpcName": "RunEvaluationResultMetrics", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = EvaluationServiceRestTransport._RunEvaluationResultMetrics._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_run_evaluation_result_metrics(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = ( + self._interceptor.post_run_evaluation_result_metrics_with_metadata( + resp, response_metadata + ) + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.ces_v1beta.EvaluationServiceClient.run_evaluation_result_metrics", + extra={ + "serviceName": "google.cloud.ces.v1beta.EvaluationService", + "rpcName": "RunEvaluationResultMetrics", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + class _TestPersonaVoice( _BaseEvaluationServiceRestTransport._BaseTestPersonaVoice, EvaluationServiceRestStub, @@ -6856,6 +7493,28 @@ def delete_scheduled_evaluation_run( self._session, self._host, self._interceptor ) # type: ignore + @property + def export_evaluation_results( + self, + ) -> Callable[ + [evaluation_service.ExportEvaluationResultsRequest], operations_pb2.Operation + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ExportEvaluationResults( + self._session, self._host, self._interceptor + ) # type: ignore + + @property + def export_evaluation_runs( + self, + ) -> Callable[ + [evaluation_service.ExportEvaluationRunsRequest], operations_pb2.Operation + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ExportEvaluationRuns(self._session, self._host, self._interceptor) # type: ignore + @property def export_evaluations( self, @@ -7030,6 +7689,18 @@ def run_evaluation( # In C++ this would require a dynamic_cast return self._RunEvaluation(self._session, self._host, self._interceptor) # type: ignore + @property + def run_evaluation_result_metrics( + self, + ) -> Callable[ + [evaluation_service.RunEvaluationResultMetricsRequest], operations_pb2.Operation + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._RunEvaluationResultMetrics( + self._session, self._host, self._interceptor + ) # type: ignore + @property def test_persona_voice( self, diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/services/evaluation_service/transports/rest_base.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/services/evaluation_service/transports/rest_base.py index a14e916d72d8..270223109978 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/services/evaluation_service/transports/rest_base.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/services/evaluation_service/transports/rest_base.py @@ -609,6 +609,120 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params + class _BaseExportEvaluationResults: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1beta/{parent=projects/*/locations/*/apps/*/evaluations/*}/results:export", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = evaluation_service.ExportEvaluationResultsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseEvaluationServiceRestTransport._BaseExportEvaluationResults._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseExportEvaluationRuns: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1beta/{parent=projects/*/locations/*/apps/*}/evaluationRuns:export", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = evaluation_service.ExportEvaluationRunsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseEvaluationServiceRestTransport._BaseExportEvaluationRuns._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + class _BaseExportEvaluations: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -1405,6 +1519,65 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params + class _BaseRunEvaluationResultMetrics: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1beta/{evaluation_result_id=projects/*/locations/*/apps/*/evaluations/*/results/*}:runEvaluationResultMetrics", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = evaluation_service.RunEvaluationResultMetricsRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseEvaluationServiceRestTransport._BaseRunEvaluationResultMetrics._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + class _BaseTestPersonaVoice: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/services/tool_service/async_client.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/services/tool_service/async_client.py index 7f218960239f..667765374183 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/services/tool_service/async_client.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/services/tool_service/async_client.py @@ -48,7 +48,14 @@ from google.cloud.location import locations_pb2 # type: ignore from google.longrunning import operations_pb2 # type: ignore -from google.cloud.ces_v1beta.types import schema, tool, tool_service, toolset_tool +from google.cloud.ces_v1beta.types import ( + schema, + search_suggestions, + session_service, + tool, + tool_service, + toolset_tool, +) from .client import ToolServiceClient from .transports.base import DEFAULT_CLIENT_INFO, ToolServiceTransport diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/services/tool_service/client.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/services/tool_service/client.py index d70d8470225e..628bb214109e 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/services/tool_service/client.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/services/tool_service/client.py @@ -65,7 +65,14 @@ from google.cloud.location import locations_pb2 # type: ignore from google.longrunning import operations_pb2 # type: ignore -from google.cloud.ces_v1beta.types import schema, tool, tool_service, toolset_tool +from google.cloud.ces_v1beta.types import ( + schema, + search_suggestions, + session_service, + tool, + tool_service, + toolset_tool, +) from .transports.base import DEFAULT_CLIENT_INFO, ToolServiceTransport from .transports.grpc import ToolServiceGrpcTransport diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/__init__.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/__init__.py index 38b685ded67e..9be98ff2c10b 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/__init__.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/__init__.py @@ -16,6 +16,12 @@ from .agent import ( Agent, ) +from .agent_card import ( + AgentCard, + AgentInterface, + AgentSkill, + RemoteAgentTool, +) from .agent_service import ( BatchDeleteConversationsRequest, BatchDeleteConversationsResponse, @@ -115,6 +121,7 @@ RedactionConfig, SynthesizeSpeechConfig, TimeZoneSettings, + VpcScSettings, ) from .app_version import ( AppSnapshot, @@ -166,6 +173,7 @@ ) from .deployment import ( Deployment, + ExperimentConfig, ) from .evaluation import ( AggregatedMetrics, @@ -182,6 +190,9 @@ RunEvaluationRequest, ScheduledEvaluationRun, ) +from .evaluation_metrics_config import ( + EvaluationMetricsConfig, +) from .evaluation_service import ( CreateEvaluationDatasetRequest, CreateEvaluationExpectationRequest, @@ -194,7 +205,11 @@ DeleteEvaluationRunOperationMetadata, DeleteEvaluationRunRequest, DeleteScheduledEvaluationRunRequest, + ExportEvaluationResultsOperationMetadata, + ExportEvaluationResultsRequest, ExportEvaluationResultsResponse, + ExportEvaluationRunsOperationMetadata, + ExportEvaluationRunsRequest, ExportEvaluationRunsResponse, ExportEvaluationsRequest, ExportEvaluationsResponse, @@ -224,6 +239,9 @@ ListScheduledEvaluationRunsResponse, RunEvaluationOperationMetadata, RunEvaluationResponse, + RunEvaluationResultMetricsOperationMetadata, + RunEvaluationResultMetricsRequest, + RunEvaluationResultMetricsResponse, TestPersonaVoiceRequest, TestPersonaVoiceResponse, UpdateEvaluationDatasetRequest, @@ -267,6 +285,8 @@ McpTool, ) from .mcp_toolset import ( + McpToolDefinition, + McpToolOverride, McpToolset, ) from .mocks import ( @@ -350,6 +370,10 @@ __all__ = ( "Agent", + "AgentCard", + "AgentInterface", + "AgentSkill", + "RemoteAgentTool", "BatchDeleteConversationsRequest", "BatchDeleteConversationsResponse", "CreateAgentRequest", @@ -442,6 +466,7 @@ "RedactionConfig", "SynthesizeSpeechConfig", "TimeZoneSettings", + "VpcScSettings", "AppSnapshot", "AppVersion", "ApiAuthentication", @@ -469,6 +494,7 @@ "DataStore", "DataStoreTool", "Deployment", + "ExperimentConfig", "AggregatedMetrics", "Evaluation", "EvaluationConfig", @@ -482,6 +508,7 @@ "PersonaRunConfig", "RunEvaluationRequest", "ScheduledEvaluationRun", + "EvaluationMetricsConfig", "CreateEvaluationDatasetRequest", "CreateEvaluationExpectationRequest", "CreateEvaluationRequest", @@ -493,7 +520,11 @@ "DeleteEvaluationRunOperationMetadata", "DeleteEvaluationRunRequest", "DeleteScheduledEvaluationRunRequest", + "ExportEvaluationResultsOperationMetadata", + "ExportEvaluationResultsRequest", "ExportEvaluationResultsResponse", + "ExportEvaluationRunsOperationMetadata", + "ExportEvaluationRunsRequest", "ExportEvaluationRunsResponse", "ExportEvaluationsRequest", "ExportEvaluationsResponse", @@ -523,6 +554,9 @@ "ListScheduledEvaluationRunsResponse", "RunEvaluationOperationMetadata", "RunEvaluationResponse", + "RunEvaluationResultMetricsOperationMetadata", + "RunEvaluationResultMetricsRequest", + "RunEvaluationResultMetricsResponse", "TestPersonaVoiceRequest", "TestPersonaVoiceResponse", "UpdateEvaluationDatasetRequest", @@ -548,6 +582,8 @@ "GoogleSearchTool", "Guardrail", "McpTool", + "McpToolDefinition", + "McpToolOverride", "McpToolset", "MockedToolCall", "Omnichannel", diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/agent.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/agent.py index 2a04b2acd5f5..d49925b7833d 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/agent.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/agent.py @@ -152,6 +152,9 @@ class Agent(proto.Message): Optional. Agent transfer rules. If multiple rules match, the first one in the list will be used. + validation_errors (MutableSequence[str]): + Output only. Misconfigurations or errors in + the agent that may affect agent quality. """ class LlmAgent(proto.Message): @@ -201,6 +204,12 @@ class RemoteDialogflowAgent(proto.Message): ```allow_playback_interruption`` `__ set to true will be interruptable, all other messages follow the app-level barge-in settings. + language_code_variable (str): + Optional. The name of the variable that + contains the language code to be used for the + Dialogflow session. If unspecified, the default + language code of the Dialogflow agent will be + used. """ agent: str = proto.Field( @@ -229,6 +238,10 @@ class RemoteDialogflowAgent(proto.Message): proto.BOOL, number=6, ) + language_code_variable: str = proto.Field( + proto.STRING, + number=7, + ) class AgentToolset(proto.Message): r"""A toolset with a selection of its tools. @@ -354,6 +367,10 @@ class AgentToolset(proto.Message): number=30, message=agent_transfers.TransferRule, ) + validation_errors: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=32, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/agent_card.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/agent_card.py new file mode 100644 index 000000000000..7d1e4ba85bb2 --- /dev/null +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/agent_card.py @@ -0,0 +1,216 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.ces.v1beta", + manifest={ + "AgentCard", + "AgentInterface", + "AgentSkill", + "RemoteAgentTool", + }, +) + + +class AgentCard(proto.Message): + r"""AgentCard conveys key information about a remote agent. + It is a trimmed version of the AgentCard defined in the A2A + protocol + https://a2a-protocol.org/dev/specification/#441-agentcard + + Attributes: + name (str): + Required. A human-readable name for the + agent. + description (str): + Required. A description of the agent's domain + of action/solution space. + supported_interfaces (MutableSequence[google.cloud.ces_v1beta.types.AgentInterface]): + Required. Ordered list of supported + interfaces. The first entry is preferred. + version (str): + Required. The version of the agent. + skills (MutableSequence[google.cloud.ces_v1beta.types.AgentSkill]): + Required. Skills represent a unit of ability + an agent can perform. This may somewhat abstract + but represents a more focused set of actions + that the agent is highly likely to succeed at. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + description: str = proto.Field( + proto.STRING, + number=2, + ) + supported_interfaces: MutableSequence["AgentInterface"] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message="AgentInterface", + ) + version: str = proto.Field( + proto.STRING, + number=5, + ) + skills: MutableSequence["AgentSkill"] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message="AgentSkill", + ) + + +class AgentInterface(proto.Message): + r"""Declares a combination of a target URL, transport and + protocol version for interacting with the agent. This allows + agents to expose the same functionality over multiple protocol + binding mechanisms. + + Attributes: + url (str): + Required. The URL where this interface is + available. Must be a valid absolute HTTPS URL in + production. Example: + + "https://api.example.com/a2a/v1", + "https://grpc.example.com/a2a". + protocol_binding (str): + Required. The protocol binding supported at this URL. This + is an open form string, to be easily extended for other + protocol bindings. The core ones officially supported are + ``JSONRPC``, ``GRPC`` and ``HTTP+JSON``. + tenant (str): + Tenant ID to be used in the request when + calling the agent. + protocol_version (str): + Required. The version of the A2A protocol + this interface exposes. Use the latest supported + minor version per major version. Examples: + "0.3", "1.0". + """ + + url: str = proto.Field( + proto.STRING, + number=1, + ) + protocol_binding: str = proto.Field( + proto.STRING, + number=2, + ) + tenant: str = proto.Field( + proto.STRING, + number=3, + ) + protocol_version: str = proto.Field( + proto.STRING, + number=4, + ) + + +class AgentSkill(proto.Message): + r"""Represents a distinct capability or function that an agent + can perform. + + Attributes: + id (str): + Required. A unique identifier for the agent's + skill. + name (str): + Required. A human-readable name for the + skill. + description (str): + Required. A detailed description of the + skill. + tags (MutableSequence[str]): + Required. A set of keywords describing the + skill's capabilities. + examples (MutableSequence[str]): + Example prompts or scenarios that this skill + can handle. + input_modes (MutableSequence[str]): + The set of supported input media types for + this skill, overriding the agent's defaults. + output_modes (MutableSequence[str]): + The set of supported output media types for + this skill, overriding the agent's defaults. + """ + + id: str = proto.Field( + proto.STRING, + number=1, + ) + name: str = proto.Field( + proto.STRING, + number=2, + ) + description: str = proto.Field( + proto.STRING, + number=3, + ) + tags: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=4, + ) + examples: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=5, + ) + input_modes: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=6, + ) + output_modes: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=7, + ) + + +class RemoteAgentTool(proto.Message): + r"""Represents a tool that allows the agent to call another + remote agent. + + Attributes: + name (str): + Required. The name of the tool. + description (str): + Required. The description of the tool. + agent_card (google.cloud.ces_v1beta.types.AgentCard): + Required. The agent card of the remote agent + that this tool invokes. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + description: str = proto.Field( + proto.STRING, + number=2, + ) + agent_card: "AgentCard" = proto.Field( + proto.MESSAGE, + number=3, + message="AgentCard", + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/agent_service.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/agent_service.py index a8bcc60eabd2..035e75b78496 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/agent_service.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/agent_service.py @@ -2131,6 +2131,11 @@ class GenerateAppResourceRequest(proto.Message): assistant, can be empty for generating a new toolset. + This field is a member of `oneof`_ ``resource``. + app_version_context (google.cloud.ces_v1beta.types.GenerateAppResourceRequest.AppVersionContext): + The app version context specifying the base + snapshot and target agent. + This field is a member of `oneof`_ ``resource``. parent (str): Required. The resource name of the app to @@ -2158,6 +2163,30 @@ class GenerateAppResourceRequest(proto.Message): hill climbing fixes. """ + class AppVersionContext(proto.Message): + r"""The app version context specifying the base snapshot and + target agent. + + Attributes: + app_version (str): + The resource name of the app version to be used by the LLM + assistant. Format: + ``projects/{project}/locations/{location}/apps/{app}/versions/{version}`` + agent_resource_name (str): + The resource name of the target agent to be used by the LLM + assistant. Format: + ``projects/{project}/locations/{location}/apps/{app}/agents/{agent}`` + """ + + app_version: str = proto.Field( + proto.STRING, + number=1, + ) + agent_resource_name: str = proto.Field( + proto.STRING, + number=2, + ) + class RefineInstructions(proto.Message): r"""The instructions to be used to refine a part of the resource. The part of the resource can be specified with a start index, @@ -2410,6 +2439,12 @@ class HillClimbingFixConfig(proto.Message): oneof="resource", message=gcc_toolset.Toolset, ) + app_version_context: AppVersionContext = proto.Field( + proto.MESSAGE, + number=12, + oneof="resource", + message=AppVersionContext, + ) parent: str = proto.Field( proto.STRING, number=1, diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/app.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/app.py index 8bd6b64321e1..ec727c8d5608 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/app.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/app.py @@ -21,7 +21,13 @@ import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore import proto # type: ignore -from google.cloud.ces_v1beta.types import bigquery_export, common, fakes, golden_run +from google.cloud.ces_v1beta.types import ( + bigquery_export, + common, + evaluation_metrics_config, + fakes, + golden_run, +) from google.cloud.ces_v1beta.types import schema as gcc_schema __protobuf__ = proto.module( @@ -40,6 +46,7 @@ "EvaluationMetricsThresholds", "EvaluationSettings", "ClientCertificateSettings", + "VpcScSettings", "ConversationLoggingSettings", "CloudLoggingSettings", "AudioRecordingConfig", @@ -135,6 +142,8 @@ class App(proto.Message): client_certificate_settings (google.cloud.ces_v1beta.types.ClientCertificateSettings): Optional. The default client certificate settings for the app. + vpc_sc_settings (google.cloud.ces_v1beta.types.VpcScSettings): + Optional. VPC-SC settings for the app. locked (bool): Optional. Indicates whether the app is locked for changes. If the app is locked, modifications @@ -147,6 +156,9 @@ class App(proto.Message): evaluation_settings (google.cloud.ces_v1beta.types.EvaluationSettings): Optional. The evaluation settings for the app. + validation_errors (MutableSequence[str]): + Output only. Misconfigurations or warnings in + the app. """ class ToolExecutionMode(proto.Enum): @@ -319,6 +331,11 @@ class VariableDeclaration(proto.Message): number=25, message="ClientCertificateSettings", ) + vpc_sc_settings: "VpcScSettings" = proto.Field( + proto.MESSAGE, + number=26, + message="VpcScSettings", + ) locked: bool = proto.Field( proto.BOOL, number=29, @@ -333,6 +350,10 @@ class VariableDeclaration(proto.Message): number=33, message="EvaluationSettings", ) + validation_errors: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=39, + ) class TimeZoneSettings(proto.Message): @@ -651,13 +672,20 @@ class LoggingSettings(proto.Message): Optional. Configuration for how sensitive data should be redacted. audio_recording_config (google.cloud.ces_v1beta.types.AudioRecordingConfig): - Optional. Configuration for how audio - interactions should be recorded. + Optional. Configuration for how audio interactions should be + recorded. The audio is subject to redaction as configured in + [RedactionConfig][google.cloud.ces.v1beta.LoggingSettings.redaction_config]. + unredacted_audio_recording_config (google.cloud.ces_v1beta.types.AudioRecordingConfig): + Optional. Configures an additional recording of unredacted + audio. This can be used to maintain a raw audio copy when + audio redaction is + [enabled][google.cloud.ces.v1beta.RedactionConfig.enable_redaction], + typically for auditing or monitoring purposes. bigquery_export_settings (google.cloud.ces_v1beta.types.BigQueryExportSettings): - Optional. Settings to describe the BigQuery - export behaviors for the app. The conversation - data will be exported to BigQuery tables if it - is enabled. + Optional. Configures the BigQuery export behaviors for the + app. The conversation data is subject to redaction as + configured in + [RedactionConfig][google.cloud.ces.v1beta.LoggingSettings.redaction_config]. cloud_logging_settings (google.cloud.ces_v1beta.types.CloudLoggingSettings): Optional. Settings to describe the Cloud Logging behaviors for the app. @@ -685,6 +713,11 @@ class LoggingSettings(proto.Message): number=2, message="AudioRecordingConfig", ) + unredacted_audio_recording_config: "AudioRecordingConfig" = proto.Field( + proto.MESSAGE, + number=8, + message="AudioRecordingConfig", + ) bigquery_export_settings: bigquery_export.BigQueryExportSettings = proto.Field( proto.MESSAGE, number=3, @@ -1041,6 +1074,12 @@ class EvaluationSettings(proto.Message): scenario_evaluation_tool_call_behaviour (google.cloud.ces_v1beta.types.EvaluationToolCallBehaviour): Optional. Configures the default tool call behaviour for scenario evaluations. + metrics_config (google.cloud.ces_v1beta.types.EvaluationMetricsConfig): + Optional. Configures the default metrics for + evaluations. + scenario_execution_mode (google.cloud.ces_v1beta.types.EvaluationSettings.ScenarioExecutionMode): + Optional. The execution mode for scenario evaluations. If + not provided, will default to QUALITY_OPTIMIZED. """ class ScenarioConversationInitiator(proto.Enum): @@ -1060,6 +1099,22 @@ class ScenarioConversationInitiator(proto.Enum): USER = 1 AGENT = 2 + class ScenarioExecutionMode(proto.Enum): + r"""The execution mode for scenario evaluations. + + Values: + SCENARIO_EXECUTION_MODE_UNSPECIFIED (0): + Unspecified execution mode. Defaults to QUALITY_OPTIMIZED. + QUALITY_OPTIMIZED (1): + Quality optimized mode. + SPEED_OPTIMIZED (2): + Speed optimized mode. + """ + + SCENARIO_EXECUTION_MODE_UNSPECIFIED = 0 + QUALITY_OPTIMIZED = 1 + SPEED_OPTIMIZED = 2 + scenario_conversation_initiator: ScenarioConversationInitiator = proto.Field( proto.ENUM, number=1, @@ -1084,6 +1139,16 @@ class ScenarioConversationInitiator(proto.Enum): enum=fakes.EvaluationToolCallBehaviour, ) ) + metrics_config: evaluation_metrics_config.EvaluationMetricsConfig = proto.Field( + proto.MESSAGE, + number=5, + message=evaluation_metrics_config.EvaluationMetricsConfig, + ) + scenario_execution_mode: ScenarioExecutionMode = proto.Field( + proto.ENUM, + number=6, + enum=ScenarioExecutionMode, + ) class ClientCertificateSettings(proto.Message): @@ -1121,6 +1186,28 @@ class ClientCertificateSettings(proto.Message): ) +class VpcScSettings(proto.Message): + r"""VPC-SC settings for the app. + + Attributes: + allowed_origins (MutableSequence[str]): + Optional. The allowed HTTP(s) origins that + OpenAPI tools in the App are able to directly + call when VPC Service Controls are enabled. + These strings must match the origin exactly, + including the port if specified. For example, + "https://example.com" or + "https://example.com:443". This list does not + yet apply to Python tools that may make direct + HTTP calls. + """ + + allowed_origins: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + + class ConversationLoggingSettings(proto.Message): r"""Settings to describe the conversation logging behaviors for the app. diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/conversation.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/conversation.py index b20a89036114..1ac6c33352cf 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/conversation.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/conversation.py @@ -133,22 +133,24 @@ class InputType(proto.Enum): INPUT_TYPE_UNSPECIFIED (0): Unspecified input type. INPUT_TYPE_TEXT (1): - The input message is text. + Text input. + INPUT_TYPE_EVENT (7): + Event input. INPUT_TYPE_AUDIO (2): - The input message is audio. + Audio input. INPUT_TYPE_IMAGE (3): - The input message is image. + Image input. INPUT_TYPE_BLOB (4): - The input message is blob file. + Blob input. INPUT_TYPE_TOOL_RESPONSE (5): - The input message is client function tool - response. + Client function tool response input. INPUT_TYPE_VARIABLES (6): - The input message are variables. + Variables input. """ INPUT_TYPE_UNSPECIFIED = 0 INPUT_TYPE_TEXT = 1 + INPUT_TYPE_EVENT = 7 INPUT_TYPE_AUDIO = 2 INPUT_TYPE_IMAGE = 3 INPUT_TYPE_BLOB = 4 diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/deployment.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/deployment.py index 6505df69341d..4cedd0b6c297 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/deployment.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/deployment.py @@ -25,11 +25,105 @@ __protobuf__ = proto.module( package="google.cloud.ces.v1beta", manifest={ + "ExperimentConfig", "Deployment", }, ) +class ExperimentConfig(proto.Message): + r"""Experiment for the deployment. + + Attributes: + version_release (google.cloud.ces_v1beta.types.ExperimentConfig.VersionRelease): + Optional. Version release for the experiment. + """ + + class State(proto.Enum): + r"""State of the experiment. + + Values: + STATE_UNSPECIFIED (0): + Unspecified state. + PENDING (1): + Pending state. Experiment is pending and not + valid. + RUNNING (2): + Running state. Experiment is running and + valid. + DONE (3): + Done state. Experiment is done and no longer + valid. + EXPIRED (4): + Expired state. Experiment is expired and no + longer valid. + """ + + STATE_UNSPECIFIED = 0 + PENDING = 1 + RUNNING = 2 + DONE = 3 + EXPIRED = 4 + + class VersionRelease(proto.Message): + r"""Version release for the experiment. + + Attributes: + state (google.cloud.ces_v1beta.types.ExperimentConfig.State): + Optional. State of the version release. + traffic_allocations (MutableSequence[google.cloud.ces_v1beta.types.ExperimentConfig.VersionRelease.TrafficAllocation]): + Optional. Traffic allocations for the version + release. + """ + + class TrafficAllocation(proto.Message): + r"""Traffic allocation for the version release. + + Attributes: + id (str): + Optional. Id of the traffic allocation. + Free format string, up to 128 characters. + traffic_percentage (int): + Optional. Traffic percentage of the traffic + allocation. Must be between 0 and 100. + app_version (str): + Optional. App version of the traffic allocation. Format: + ``projects/{project}/locations/{location}/apps/{app}/versions/{version}`` + """ + + id: str = proto.Field( + proto.STRING, + number=1, + ) + traffic_percentage: int = proto.Field( + proto.INT32, + number=2, + ) + app_version: str = proto.Field( + proto.STRING, + number=3, + ) + + state: "ExperimentConfig.State" = proto.Field( + proto.ENUM, + number=1, + enum="ExperimentConfig.State", + ) + traffic_allocations: MutableSequence[ + "ExperimentConfig.VersionRelease.TrafficAllocation" + ] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="ExperimentConfig.VersionRelease.TrafficAllocation", + ) + + version_release: VersionRelease = proto.Field( + proto.MESSAGE, + number=1, + message=VersionRelease, + ) + + class Deployment(proto.Message): r"""A deployment represents an immutable, queryable version of the app. It is used to deploy an app version with a specific @@ -62,6 +156,9 @@ class Deployment(proto.Message): hasn't changed during a read-modify-write operation. If the etag is empty, the update will overwrite any concurrent changes. + experiment_config (google.cloud.ces_v1beta.types.ExperimentConfig): + Optional. Experiment configuration for the + deployment. """ name: str = proto.Field( @@ -95,6 +192,11 @@ class Deployment(proto.Message): proto.STRING, number=7, ) + experiment_config: "ExperimentConfig" = proto.Field( + proto.MESSAGE, + number=9, + message="ExperimentConfig", + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/evaluation.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/evaluation.py index 5e95f81c6976..09894264d3b1 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/evaluation.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/evaluation.py @@ -26,6 +26,7 @@ from google.cloud.ces_v1beta.types import app as gcc_app from google.cloud.ces_v1beta.types import ( common, + evaluation_metrics_config, example, fakes, golden_run, @@ -383,6 +384,12 @@ class Evaluation(proto.Message): evaluation. This is only populated if include_last_ten_results is set to true in the ListEvaluationsRequest or GetEvaluationRequest. + evaluation_metrics_threshold_override (google.cloud.ces_v1beta.types.EvaluationMetricsThresholds): + Optional. Overrides metrics thresholds for + this specific evaluation. + evaluation_metrics_config_override (google.cloud.ces_v1beta.types.EvaluationMetricsConfig): + Optional. Overrides metrics config for this + specific evaluation. """ class GoldenExpectation(proto.Message): @@ -429,11 +436,31 @@ class GoldenExpectation(proto.Message): parameters of interest specified. Any parameters not specified will be hallucinated by the LLM. + This field is a member of `oneof`_ ``condition``. + no_tool_calls (bool): + Optional. Check that no tools were called + during this turn. + This field is a member of `oneof`_ ``condition``. note (str): Optional. A note for this requirement, useful in reporting when specific checks fail. E.g., "Check_Payment_Tool_Called". + skip_evaluation (bool): + Optional. If set to true, this specific + expectation will not be evaluated. + expectation_level_metrics_thresholds_override (google.cloud.ces_v1beta.types.EvaluationMetricsThresholds.GoldenEvaluationMetricsThresholds.ExpectationLevelMetricsThresholds): + Optional. Overrides metrics at the step + level. + agent_response_semantic_similarity_metrics_config_override (google.cloud.ces_v1beta.types.EvaluationMetricsConfig.SemanticSimilarityMetricsConfig): + Optional. Overrides for agent_response semantic similarity + metrics. + agent_response_hallucination_metrics_config_override (google.cloud.ces_v1beta.types.EvaluationMetricsConfig.HallucinationMetricsConfig): + Optional. Overrides for agent_response hallucination + metrics. + comparison_type (google.cloud.ces_v1beta.types.EvaluationMetricsConfig.ComparisonType): + Optional. The comparison type to use for the + expectation check. """ tool_call: example.ToolCall = proto.Field( @@ -472,10 +499,39 @@ class GoldenExpectation(proto.Message): oneof="condition", message=example.ToolResponse, ) + no_tool_calls: bool = proto.Field( + proto.BOOL, + number=13, + oneof="condition", + ) note: str = proto.Field( proto.STRING, number=1, ) + skip_evaluation: bool = proto.Field( + proto.BOOL, + number=8, + ) + expectation_level_metrics_thresholds_override: gcc_app.EvaluationMetricsThresholds.GoldenEvaluationMetricsThresholds.ExpectationLevelMetricsThresholds = proto.Field( + proto.MESSAGE, + number=9, + message=gcc_app.EvaluationMetricsThresholds.GoldenEvaluationMetricsThresholds.ExpectationLevelMetricsThresholds, + ) + agent_response_semantic_similarity_metrics_config_override: evaluation_metrics_config.EvaluationMetricsConfig.SemanticSimilarityMetricsConfig = proto.Field( + proto.MESSAGE, + number=10, + message=evaluation_metrics_config.EvaluationMetricsConfig.SemanticSimilarityMetricsConfig, + ) + agent_response_hallucination_metrics_config_override: evaluation_metrics_config.EvaluationMetricsConfig.HallucinationMetricsConfig = proto.Field( + proto.MESSAGE, + number=11, + message=evaluation_metrics_config.EvaluationMetricsConfig.HallucinationMetricsConfig, + ) + comparison_type: evaluation_metrics_config.EvaluationMetricsConfig.ComparisonType = proto.Field( + proto.ENUM, + number=12, + enum=evaluation_metrics_config.EvaluationMetricsConfig.ComparisonType, + ) class Step(proto.Message): r"""A step defines a singular action to happen during the @@ -534,7 +590,14 @@ class GoldenTurn(proto.Message): root_span (google.cloud.ces_v1beta.types.Span): Optional. The root span of the golden turn for processing and maintaining audio - information. + information. The uri for the audio must contain + audio saved in 16Khz sample rate. + turn_level_metrics_thresholds_override (google.cloud.ces_v1beta.types.EvaluationMetricsThresholds.GoldenEvaluationMetricsThresholds.TurnLevelMetricsThresholds): + Optional. Overrides for turn-level metric + thresholds. + hallucination_metric_behavior_override (google.cloud.ces_v1beta.types.EvaluationMetricsThresholds.HallucinationMetricBehavior): + Optional. Override for turn-level + hallucination metric behavior. """ steps: MutableSequence["Evaluation.Step"] = proto.RepeatedField( @@ -547,6 +610,16 @@ class GoldenTurn(proto.Message): number=2, message=common.Span, ) + turn_level_metrics_thresholds_override: gcc_app.EvaluationMetricsThresholds.GoldenEvaluationMetricsThresholds.TurnLevelMetricsThresholds = proto.Field( + proto.MESSAGE, + number=3, + message=gcc_app.EvaluationMetricsThresholds.GoldenEvaluationMetricsThresholds.TurnLevelMetricsThresholds, + ) + hallucination_metric_behavior_override: gcc_app.EvaluationMetricsThresholds.HallucinationMetricBehavior = proto.Field( + proto.ENUM, + number=4, + enum=gcc_app.EvaluationMetricsThresholds.HallucinationMetricBehavior, + ) class Golden(proto.Message): r"""The steps required to replay a golden conversation. @@ -554,7 +627,8 @@ class Golden(proto.Message): Attributes: turns (MutableSequence[google.cloud.ces_v1beta.types.Evaluation.GoldenTurn]): Required. The golden turns required to replay - a golden conversation. + a golden conversation. The maximum number of + allowed turns is 100. evaluation_expectations (MutableSequence[str]): Optional. The evaluation expectations to evaluate the replayed conversation against. Format: @@ -646,8 +720,8 @@ class Scenario(proto.Message): scenario. max_turns (int): Optional. The maximum number of turns to - simulate. If not specified, the simulation will - continue until the task is complete. + simulate. The maximum allowed value is 100. The + default value is 100. rubrics (MutableSequence[str]): Required. The rubrics to score the scenario against. @@ -674,6 +748,9 @@ class Scenario(proto.Message): Optional. The evaluation expectations to evaluate the conversation produced by the simulation against. Format: ``projects/{project}/locations/{location}/apps/{app}/evaluationExpectations/{evaluationExpectation}`` + scenario_execution_mode (google.cloud.ces_v1beta.types.EvaluationSettings.ScenarioExecutionMode): + Optional. The execution mode for scenario + evaluations. """ class TaskCompletionBehavior(proto.Enum): @@ -781,6 +858,13 @@ class UserFact(proto.Message): proto.STRING, number=10, ) + scenario_execution_mode: gcc_app.EvaluationSettings.ScenarioExecutionMode = ( + proto.Field( + proto.ENUM, + number=12, + enum=gcc_app.EvaluationSettings.ScenarioExecutionMode, + ) + ) golden: Golden = proto.Field( proto.MESSAGE, @@ -859,6 +943,18 @@ class UserFact(proto.Message): number=19, message="EvaluationResult", ) + evaluation_metrics_threshold_override: gcc_app.EvaluationMetricsThresholds = ( + proto.Field( + proto.MESSAGE, + number=20, + message=gcc_app.EvaluationMetricsThresholds, + ) + ) + evaluation_metrics_config_override: evaluation_metrics_config.EvaluationMetricsConfig = proto.Field( + proto.MESSAGE, + number=21, + message=evaluation_metrics_config.EvaluationMetricsConfig, + ) class EvaluationDataset(proto.Message): @@ -1055,6 +1151,8 @@ class ExecutionState(proto.Enum): EXECUTION_STATE_UNSPECIFIED (0): Evaluation result execution state is not specified. + QUEUED (5): + Evaluation result execution is queued. RUNNING (1): Evaluation result execution is running. COMPLETED (2): @@ -1062,12 +1160,16 @@ class ExecutionState(proto.Enum): ERROR (3): Evaluation result execution failed due to an internal error. + CANCELLED (4): + Evaluation result execution was cancelled. """ EXECUTION_STATE_UNSPECIFIED = 0 + QUEUED = 5 RUNNING = 1 COMPLETED = 2 ERROR = 3 + CANCELLED = 4 class GoldenExpectationOutcome(proto.Message): r"""Specifies the expectation and the result of that expectation. @@ -1099,6 +1201,13 @@ class GoldenExpectationOutcome(proto.Message): Output only. The result of the agent transfer expectation. + This field is a member of `oneof`_ ``result``. + observed_payload (google.protobuf.struct_pb2.Struct): + Output only. An observed custom payload. + There are no expectations for custom payloads. + This is only used for metrics calculation. The + outcome is always SKIPPED. + This field is a member of `oneof`_ ``result``. expectation (google.cloud.ces_v1beta.types.Evaluation.GoldenExpectation): Output only. The expectation that was @@ -1176,6 +1285,12 @@ class ToolInvocationResult(proto.Message): oneof="result", message=example.AgentTransfer, ) + observed_payload: struct_pb2.Struct = proto.Field( + proto.MESSAGE, + number=9, + oneof="result", + message=struct_pb2.Struct, + ) expectation: "Evaluation.GoldenExpectation" = proto.Field( proto.MESSAGE, number=1, @@ -2131,6 +2246,10 @@ class EvaluationRun(proto.Message): golden_run_method (google.cloud.ces_v1beta.types.GoldenRunMethod): Output only. The method used to run the evaluation. + operation (str): + Output only. The operation that created this evaluation run. + Format: + ``projects/{project}/locations/{location}/operations/{operation}`` """ class EvaluationType(proto.Enum): @@ -2160,18 +2279,24 @@ class EvaluationRunState(proto.Enum): Values: EVALUATION_RUN_STATE_UNSPECIFIED (0): Evaluation run state is not specified. + QUEUED (5): + Indicates the evaluation run is queued. RUNNING (1): Evaluation run is running. COMPLETED (2): Evaluation run has completed. ERROR (3): The evaluation run has an error. + CANCELLED (4): + Evaluation run was cancelled. """ EVALUATION_RUN_STATE_UNSPECIFIED = 0 + QUEUED = 5 RUNNING = 1 COMPLETED = 2 ERROR = 3 + CANCELLED = 4 class Progress(proto.Message): r"""The progress of the evaluation run. @@ -2195,6 +2320,9 @@ class Progress(proto.Message): Output only. Number of completed evaluation results with an outcome of PASS. (EvaluationResult.execution_state is COMPLETED and EvaluationResult.evaluation_status is PASS). + cancelled_count (int): + Output only. Number of evaluation results that were + cancelled. (EvaluationResult.execution_state is CANCELLED). """ total_count: int = proto.Field( @@ -2217,6 +2345,10 @@ class Progress(proto.Message): proto.INT32, number=5, ) + cancelled_count: int = proto.Field( + proto.INT32, + number=6, + ) class EvaluationRunSummary(proto.Message): r"""Contains the summary of passed and failed result counts for a @@ -2359,6 +2491,10 @@ class EvaluationRunSummary(proto.Message): number=21, enum=golden_run.GoldenRunMethod, ) + operation: str = proto.Field( + proto.STRING, + number=26, + ) class LatencyReport(proto.Message): @@ -2714,6 +2850,8 @@ class EvaluationErrorInfo(proto.Message): session_id (str): Output only. The session ID for the conversation that caused the error. + user_facing_error_message (str): + Output only. The user facing error message. """ class ErrorType(proto.Enum): @@ -2758,6 +2896,10 @@ class ErrorType(proto.Enum): proto.STRING, number=3, ) + user_facing_error_message: str = proto.Field( + proto.STRING, + number=4, + ) class RunEvaluationRequest(proto.Message): diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/evaluation_metrics_config.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/evaluation_metrics_config.py new file mode 100644 index 000000000000..0d04e4237312 --- /dev/null +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/evaluation_metrics_config.py @@ -0,0 +1,220 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.ces.v1beta", + manifest={ + "EvaluationMetricsConfig", + }, +) + + +class EvaluationMetricsConfig(proto.Message): + r"""Configures the metrics for an evaluation. + + Attributes: + golden_metrics_config (google.cloud.ces_v1beta.types.EvaluationMetricsConfig.GoldenMetricsConfig): + Optional. Configuration for the golden + metrics for the evaluation. + scenario_metrics_config (google.cloud.ces_v1beta.types.EvaluationMetricsConfig.ScenarioMetricsConfig): + Optional. Configuration for the scenario + metrics for the evaluation. + """ + + class ComparisonType(proto.Enum): + r"""Supported comparison types for checking the agent's response. + + Values: + COMPARISON_TYPE_UNSPECIFIED (0): + Unspecified comparison type. Behavior defaults to + SEMANTIC_SIMILARITY for agent responses and tool calls. + EQUALS (1): + Exact string match. + CONTAINS (2): + Substring match (checks if the expected + string is contained in the actual response). + SEMANTIC_SIMILARITY (3): + Semantic similarity match (evaluates meaning + similarity using an LLM). + """ + + COMPARISON_TYPE_UNSPECIFIED = 0 + EQUALS = 1 + CONTAINS = 2 + SEMANTIC_SIMILARITY = 3 + + class SemanticSimilarityMetricsConfig(proto.Message): + r"""Configuration for similarity metrics for the evaluation. To disable + the metric, set the message but do not set the + ``enable_semantic_similarity_metrics`` field to true (or explicitly + set it to false). To unset the configuration and fallback to the + default behavior, omit the message entirely. + + Attributes: + enable_semantic_similarity_metrics (bool): + Optional. Whether to calculate semantic + similarity metrics for the evaluation. + """ + + enable_semantic_similarity_metrics: bool = proto.Field( + proto.BOOL, + number=1, + ) + + class ToolCorrectnessMetricsConfig(proto.Message): + r"""Configuration for correctness metrics for the evaluation. To disable + the metric, set the message but do not set the + ``enable_tool_correctness_metrics`` field to true (or explicitly set + it to false). To unset the configuration and fallback to the default + behavior, omit the message entirely. + + Attributes: + enable_tool_correctness_metrics (bool): + Optional. Whether to calculate tool + correctness metrics for the evaluation. + """ + + enable_tool_correctness_metrics: bool = proto.Field( + proto.BOOL, + number=1, + ) + + class HallucinationMetricsConfig(proto.Message): + r"""Configuration for the hallucination metrics for the evaluation. To + disable the metric, set the message but do not set the + ``enable_hallucination_metrics`` field to true (or explicitly set it + to false). To unset the configuration and fallback to the default + behavior, omit the message entirely. + + Attributes: + enable_hallucination_metrics (bool): + Optional. Whether to calculate hallucination + metrics for the evaluation. + """ + + enable_hallucination_metrics: bool = proto.Field( + proto.BOOL, + number=1, + ) + + class UserGoalMetMetricsConfig(proto.Message): + r"""Configuration for the user goal met metrics for the evaluation. To + disable the metric, set the message but do not set the + ``enable_user_goal_met_metrics`` field to true (or explicitly set it + to false). To unset the configuration and fallback to the default + behavior, omit the message entirely. + + Attributes: + enable_user_goal_met_metrics (bool): + Optional. Whether to calculate the user goal + met metrics for the evaluation. + """ + + enable_user_goal_met_metrics: bool = proto.Field( + proto.BOOL, + number=1, + ) + + class ExpectationsMetMetricsConfig(proto.Message): + r"""Configuration for the expectation level metrics for the evaluation. + To disable the metric, set the message but do not set the + ``enable_expectations_met_metrics`` field to true (or explicitly set + it to false). To unset the configuration and fallback to the default + behavior, omit the message entirely. + + Attributes: + enable_expectations_met_metrics (bool): + Optional. Whether to calculate the + expectation level metrics for the evaluation. + """ + + enable_expectations_met_metrics: bool = proto.Field( + proto.BOOL, + number=1, + ) + + class GoldenMetricsConfig(proto.Message): + r"""Configuration for the golden metrics for the evaluation. + + Attributes: + semantic_similarity_metrics_config (google.cloud.ces_v1beta.types.EvaluationMetricsConfig.SemanticSimilarityMetricsConfig): + Optional. Global configuration for semantic + similarity metrics. + tool_correctness_metrics_config (google.cloud.ces_v1beta.types.EvaluationMetricsConfig.ToolCorrectnessMetricsConfig): + Optional. Configuration for turn level tool + correctness metrics. + step_tool_correctness_metrics_config (google.cloud.ces_v1beta.types.EvaluationMetricsConfig.ToolCorrectnessMetricsConfig): + Optional. Configuration for step level tool + correctness metrics. + """ + + semantic_similarity_metrics_config: "EvaluationMetricsConfig.SemanticSimilarityMetricsConfig" = proto.Field( + proto.MESSAGE, + number=1, + message="EvaluationMetricsConfig.SemanticSimilarityMetricsConfig", + ) + tool_correctness_metrics_config: "EvaluationMetricsConfig.ToolCorrectnessMetricsConfig" = proto.Field( + proto.MESSAGE, + number=2, + message="EvaluationMetricsConfig.ToolCorrectnessMetricsConfig", + ) + step_tool_correctness_metrics_config: "EvaluationMetricsConfig.ToolCorrectnessMetricsConfig" = proto.Field( + proto.MESSAGE, + number=6, + message="EvaluationMetricsConfig.ToolCorrectnessMetricsConfig", + ) + + class ScenarioMetricsConfig(proto.Message): + r"""Configuration for the scenario metrics for the evaluation. + + Attributes: + user_goal_met_metrics_config (google.cloud.ces_v1beta.types.EvaluationMetricsConfig.UserGoalMetMetricsConfig): + Optional. Configuration for user goal met + metrics. + expectations_met_metrics_config (google.cloud.ces_v1beta.types.EvaluationMetricsConfig.ExpectationsMetMetricsConfig): + Optional. Configuration for expectation level + metrics. + """ + + user_goal_met_metrics_config: "EvaluationMetricsConfig.UserGoalMetMetricsConfig" = proto.Field( + proto.MESSAGE, + number=2, + message="EvaluationMetricsConfig.UserGoalMetMetricsConfig", + ) + expectations_met_metrics_config: "EvaluationMetricsConfig.ExpectationsMetMetricsConfig" = proto.Field( + proto.MESSAGE, + number=3, + message="EvaluationMetricsConfig.ExpectationsMetMetricsConfig", + ) + + golden_metrics_config: GoldenMetricsConfig = proto.Field( + proto.MESSAGE, + number=1, + message=GoldenMetricsConfig, + ) + scenario_metrics_config: ScenarioMetricsConfig = proto.Field( + proto.MESSAGE, + number=2, + message=ScenarioMetricsConfig, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/evaluation_service.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/evaluation_service.py index 83c34fc5f438..3a8f57b0d4a8 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/evaluation_service.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/evaluation_service.py @@ -28,6 +28,8 @@ __protobuf__ = proto.module( package="google.cloud.ces.v1beta", manifest={ + "RunEvaluationResultMetricsRequest", + "RunEvaluationResultMetricsResponse", "RunEvaluationResponse", "RunEvaluationOperationMetadata", "GenerateEvaluationOperationMetadata", @@ -75,12 +77,50 @@ "ExportOptions", "ExportEvaluationsRequest", "ExportEvaluationsResponse", + "ExportEvaluationResultsRequest", "ExportEvaluationResultsResponse", + "ExportEvaluationRunsRequest", "ExportEvaluationRunsResponse", + "ExportEvaluationRunsOperationMetadata", + "ExportEvaluationResultsOperationMetadata", + "RunEvaluationResultMetricsOperationMetadata", }, ) +class RunEvaluationResultMetricsRequest(proto.Message): + r"""Request message for + [EvaluationService.RunEvaluationResultMetrics][google.cloud.ces.v1beta.EvaluationService.RunEvaluationResultMetrics]. + + Attributes: + evaluation_result_id (str): + Required. The evaluation result to run metrics for. Format: + ``projects/{project}/locations/{location}/apps/{app}/evaluations/{evaluation}/results/{evaluation_result_id}`` + """ + + evaluation_result_id: str = proto.Field( + proto.STRING, + number=1, + ) + + +class RunEvaluationResultMetricsResponse(proto.Message): + r"""Response message for + [EvaluationService.RunEvaluationResultMetrics][google.cloud.ces.v1beta.EvaluationService.RunEvaluationResultMetrics]. + + Attributes: + status (google.cloud.ces_v1beta.types.EvaluationResult.Outcome): + Output only. The status of the evaluation + result metrics calculation. + """ + + status: gcc_evaluation.EvaluationResult.Outcome = proto.Field( + proto.ENUM, + number=1, + enum=gcc_evaluation.EvaluationResult.Outcome, + ) + + class RunEvaluationResponse(proto.Message): r"""Response message for [EvaluationService.RunEvaluation][google.cloud.ces.v1beta.EvaluationService.RunEvaluation]. @@ -1677,6 +1717,38 @@ class ExportEvaluationsResponse(proto.Message): ) +class ExportEvaluationResultsRequest(proto.Message): + r"""Request message for + [EvaluationService.ExportEvaluationResults][google.cloud.ces.v1beta.EvaluationService.ExportEvaluationResults]. + + Attributes: + parent (str): + Required. The resource name of the evaluation to export + evaluation results from. Format: + ``projects/{project}/locations/{location}/apps/{app}/evaluations/{evaluation}`` + names (MutableSequence[str]): + Required. The resource names of the + evaluation results to export. + export_options (google.cloud.ces_v1beta.types.ExportOptions): + Optional. The export options for the + evaluation results. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + names: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + export_options: "ExportOptions" = proto.Field( + proto.MESSAGE, + number=3, + message="ExportOptions", + ) + + class ExportEvaluationResultsResponse(proto.Message): r"""Response message for [EvaluationService.ExportEvaluationResults][google.cloud.ces.v1beta.EvaluationService.ExportEvaluationResults]. @@ -1714,6 +1786,38 @@ class ExportEvaluationResultsResponse(proto.Message): ) +class ExportEvaluationRunsRequest(proto.Message): + r"""Request message for + [EvaluationService.ExportEvaluationRuns][google.cloud.ces.v1beta.EvaluationService.ExportEvaluationRuns]. + + Attributes: + parent (str): + Required. The resource name of the app to export evaluation + runs from. Format: + ``projects/{project}/locations/{location}/apps/{app}`` + names (MutableSequence[str]): + Required. The resource names of the + evaluation runs to export. + export_options (google.cloud.ces_v1beta.types.ExportOptions): + Optional. The export options for the + evaluation runs. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + names: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + export_options: "ExportOptions" = proto.Field( + proto.MESSAGE, + number=3, + message="ExportOptions", + ) + + class ExportEvaluationRunsResponse(proto.Message): r"""Response message for [EvaluationService.ExportEvaluationRuns][google.cloud.ces.v1beta.EvaluationService.ExportEvaluationRuns]. @@ -1751,4 +1855,25 @@ class ExportEvaluationRunsResponse(proto.Message): ) +class ExportEvaluationRunsOperationMetadata(proto.Message): + r"""Operation metadata for + [EvaluationService.ExportEvaluationRuns][google.cloud.ces.v1beta.EvaluationService.ExportEvaluationRuns]. + + """ + + +class ExportEvaluationResultsOperationMetadata(proto.Message): + r"""Operation metadata for + [EvaluationService.ExportEvaluationResults][google.cloud.ces.v1beta.EvaluationService.ExportEvaluationResults]. + + """ + + +class RunEvaluationResultMetricsOperationMetadata(proto.Message): + r"""Operation metadata for + [EvaluationService.RunEvaluationResultMetrics][google.cloud.ces.v1beta.EvaluationService.RunEvaluationResultMetrics]. + + """ + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/mcp_tool.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/mcp_tool.py index 17546ea42540..ab5c07111ff9 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/mcp_tool.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/mcp_tool.py @@ -38,6 +38,10 @@ class McpTool(proto.Message): Attributes: name (str): Required. The name of the MCP tool. + name_override (str): + Optional. The name override of the MCP tool. + This is populated if the name was overridden by + a Toolset override. description (str): Optional. The description of the MCP tool. input_schema (google.cloud.ces_v1beta.types.Schema): @@ -76,12 +80,41 @@ class McpTool(proto.Message): the session variables. See https://docs.cloud.google.com/customer-engagement-ai/conversational-agents/ps/tool/open-api#openapi-injection for more details. + state (google.cloud.ces_v1beta.types.McpTool.State): + Output only. The dynamic availability state + of the tool on the external server. """ + class State(proto.Enum): + r"""Represents the dynamic availability state of the tool. + + Values: + STATE_UNSPECIFIED (0): + Default state. + ACTIVE (1): + The tool is available and actively offered by + the server. + INACTIVE (2): + The tool is configured or pinned, but + currently not offered by the server. + STALE (3): + The tool exists on the server, but does not + match the version on the server. + """ + + STATE_UNSPECIFIED = 0 + ACTIVE = 1 + INACTIVE = 2 + STALE = 3 + name: str = proto.Field( proto.STRING, number=1, ) + name_override: str = proto.Field( + proto.STRING, + number=13, + ) description: str = proto.Field( proto.STRING, number=2, @@ -120,6 +153,11 @@ class McpTool(proto.Message): proto.STRING, number=9, ) + state: State = proto.Field( + proto.ENUM, + number=12, + enum=State, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/mcp_toolset.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/mcp_toolset.py index 7cf5df2d4d49..2b5c39651d82 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/mcp_toolset.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/mcp_toolset.py @@ -19,12 +19,14 @@ import proto # type: ignore -from google.cloud.ces_v1beta.types import auth, common +from google.cloud.ces_v1beta.types import auth, common, schema __protobuf__ = proto.module( package="google.cloud.ces.v1beta", manifest={ "McpToolset", + "McpToolOverride", + "McpToolDefinition", }, ) @@ -65,6 +67,12 @@ class McpToolset(proto.Message): the session variables. See https://docs.cloud.google.com/customer-engagement-ai/conversational-agents/ps/tool/open-api#openapi-injection for more details. + tool_overrides (MutableSequence[google.cloud.ces_v1beta.types.McpToolOverride]): + Optional. Overrides for individual tools + within this toolset. This allows overriding + specific details like descriptions, names, or + pinning the tools' states so they aren't fully + dynamic. """ server_address: str = proto.Field( @@ -91,6 +99,89 @@ class McpToolset(proto.Message): proto.STRING, number=5, ) + tool_overrides: MutableSequence["McpToolOverride"] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message="McpToolOverride", + ) + + +class McpToolOverride(proto.Message): + r"""Overrides associated with a given tool in a Toolset. + This enables "pinning" or "overriding" of tool definitions from + the external dynamic server. + + Attributes: + tool (str): + Required. The original name of the tool as it + is emitted by the MCP server. + name_override (str): + Optional. If present, this tool uses this + name in the Agent instead of the original name. + This is primarily used as an alias if the MCP + server offers poorly named tools. + description_override (str): + Optional. If present, this tool uses this + description instead of the original description + from the server. + snapshot (google.cloud.ces_v1beta.types.McpToolDefinition): + Output only. If present, this tool is + "Pinned" and uses the snapshot values as + fallbacks if the server becomes temporarily + unavailable or if no Override is present. + """ + + tool: str = proto.Field( + proto.STRING, + number=1, + ) + name_override: str = proto.Field( + proto.STRING, + number=2, + ) + description_override: str = proto.Field( + proto.STRING, + number=3, + ) + snapshot: "McpToolDefinition" = proto.Field( + proto.MESSAGE, + number=4, + message="McpToolDefinition", + ) + + +class McpToolDefinition(proto.Message): + r"""Container for a tool's core definition elements that are + snapshot. Schemas in the snapshot are used as-is and cannot be + overridden. + + Attributes: + description (str): + Output only. The description of the MCP tool. This can be + overridden by ``description_override`` in + ``McpToolOverride``. + input_schema (google.cloud.ces_v1beta.types.Schema): + Output only. The schema of the input + arguments of the MCP tool. + output_schema (google.cloud.ces_v1beta.types.Schema): + Output only. The schema of the output + arguments of the MCP tool. + """ + + description: str = proto.Field( + proto.STRING, + number=1, + ) + input_schema: schema.Schema = proto.Field( + proto.MESSAGE, + number=2, + message=schema.Schema, + ) + output_schema: schema.Schema = proto.Field( + proto.MESSAGE, + number=3, + message=schema.Schema, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/python_function.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/python_function.py index 43522e6e35b8..1dbaf9759e0d 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/python_function.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/python_function.py @@ -19,6 +19,8 @@ import proto # type: ignore +from google.cloud.ces_v1beta.types import common + __protobuf__ = proto.module( package="google.cloud.ces.v1beta", manifest={ @@ -44,6 +46,9 @@ class PythonFunction(proto.Message): Output only. The description of the Python function, parsed from the python code's docstring. + service_directory_config (google.cloud.ces_v1beta.types.ServiceDirectoryConfig): + Optional. Service Directory configuration for + the tool. """ name: str = proto.Field( @@ -58,6 +63,11 @@ class PythonFunction(proto.Message): proto.STRING, number=3, ) + service_directory_config: common.ServiceDirectoryConfig = proto.Field( + proto.MESSAGE, + number=4, + message=common.ServiceDirectoryConfig, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/session_service.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/session_service.py index 51ee29545080..bf4214dcd939 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/session_service.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/session_service.py @@ -361,6 +361,9 @@ class CitedChunk(proto.Message): Title of the cited document. text (str): Text used for citation. + requires_attribution (bool): + Whether this citation requires attribution to + be shown to the end users. """ uri: str = proto.Field( @@ -375,6 +378,10 @@ class CitedChunk(proto.Message): proto.STRING, number=3, ) + requires_attribution: bool = proto.Field( + proto.BOOL, + number=4, + ) cited_chunks: MutableSequence[CitedChunk] = proto.RepeatedField( proto.MESSAGE, diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/tool.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/tool.py index 53f46b9244cc..522f9fc453f4 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/tool.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/tool.py @@ -17,12 +17,13 @@ from typing import MutableMapping, MutableSequence +import google.protobuf.duration_pb2 as duration_pb2 # type: ignore import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore import proto # type: ignore +from google.cloud.ces_v1beta.types import agent_card, common, fakes from google.cloud.ces_v1beta.types import agent_tool as gcc_agent_tool from google.cloud.ces_v1beta.types import client_function as gcc_client_function -from google.cloud.ces_v1beta.types import common, fakes from google.cloud.ces_v1beta.types import connector_tool as gcc_connector_tool from google.cloud.ces_v1beta.types import data_store_tool as gcc_data_store_tool from google.cloud.ces_v1beta.types import file_search_tool as gcc_file_search_tool @@ -98,6 +99,10 @@ class Tool(proto.Message): widget_tool (google.cloud.ces_v1beta.types.WidgetTool): Optional. The widget tool. + This field is a member of `oneof`_ ``tool_type``. + remote_agent_tool (google.cloud.ces_v1beta.types.RemoteAgentTool): + Optional. The remote agent tool. + This field is a member of `oneof`_ ``tool_type``. name (str): Identifier. The resource name of the tool. Format: @@ -116,6 +121,10 @@ class Tool(proto.Message): ``name`` property. execution_type (google.cloud.ces_v1beta.types.ExecutionType): Optional. The execution type of the tool. + timeout (google.protobuf.duration_pb2.Duration): + Optional. The timeout for the tool execution. If not set, + the default timeout is 30 seconds for ``SYNCHRONOUS`` tools + and 60 seconds for ``ASYNCHRONOUS`` tools. create_time (google.protobuf.timestamp_pb2.Timestamp): Output only. Timestamp when the tool was created. @@ -202,6 +211,12 @@ class Tool(proto.Message): oneof="tool_type", message=gcc_widget_tool.WidgetTool, ) + remote_agent_tool: agent_card.RemoteAgentTool = proto.Field( + proto.MESSAGE, + number=25, + oneof="tool_type", + message=agent_card.RemoteAgentTool, + ) name: str = proto.Field( proto.STRING, number=1, @@ -215,6 +230,11 @@ class Tool(proto.Message): number=12, enum=common.ExecutionType, ) + timeout: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=22, + message=duration_pb2.Duration, + ) create_time: timestamp_pb2.Timestamp = proto.Field( proto.MESSAGE, number=6, diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/tool_service.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/tool_service.py index 8b3442379966..e4861ebddd72 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/tool_service.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/tool_service.py @@ -20,7 +20,7 @@ import google.protobuf.struct_pb2 as struct_pb2 # type: ignore import proto # type: ignore -from google.cloud.ces_v1beta.types import schema, session_service +from google.cloud.ces_v1beta.types import schema, search_suggestions, session_service from google.cloud.ces_v1beta.types import tool as gcc_tool from google.cloud.ces_v1beta.types import toolset_tool as gcc_toolset_tool @@ -157,6 +157,13 @@ class ExecuteToolResponse(proto.Message): variables (google.protobuf.struct_pb2.Struct): The variable values at the end of the tool execution. + citations (google.cloud.ces_v1beta.types.Citations): + Citations that provide the source information + for the tool's execution. + google_search_suggestions (google.cloud.ces_v1beta.types.GoogleSearchSuggestions): + The suggestions returned from Google Search + as a result of invoking the Google Search Tool + during the tool execution. """ tool: str = proto.Field( @@ -180,6 +187,16 @@ class ExecuteToolResponse(proto.Message): number=4, message=struct_pb2.Struct, ) + citations: session_service.Citations = proto.Field( + proto.MESSAGE, + number=5, + message=session_service.Citations, + ) + google_search_suggestions: search_suggestions.GoogleSearchSuggestions = proto.Field( + proto.MESSAGE, + number=6, + message=search_suggestions.GoogleSearchSuggestions, + ) class RetrieveToolSchemaRequest(proto.Message): @@ -294,6 +311,12 @@ class RetrieveToolsRequest(proto.Message): Optional. The identifiers of the tools to retrieve from the toolset. If empty, all tools in the toolset will be returned. + bypass_persistence_config (bool): + Optional. If true, the returned tools will + contain raw descriptions and schemas directly + from the server, bypassing any stored + persistence configurations + (overrides/snapshots). """ toolset: str = proto.Field( @@ -304,6 +327,10 @@ class RetrieveToolsRequest(proto.Message): proto.STRING, number=3, ) + bypass_persistence_config: bool = proto.Field( + proto.BOOL, + number=4, + ) class RetrieveToolsResponse(proto.Message): diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/widget_tool.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/widget_tool.py index e5d0af9a2133..dca82bbf7459 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/widget_tool.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/widget_tool.py @@ -62,6 +62,9 @@ class WidgetTool(proto.Message): Optional. The mapping that defines how data from a source tool is mapped to the widget's input parameters. + text_response_config (google.cloud.ces_v1beta.types.WidgetTool.TextResponseConfig): + Optional. Configuration for always-included + text responses. """ class WidgetType(proto.Enum): @@ -111,6 +114,59 @@ class WidgetType(proto.Enum): APPOINTMENT_SCHEDULER = 11 CONTACT_FORM = 12 + class TextResponseConfig(proto.Message): + r"""Configuration for the text response returned with the widget. + + Attributes: + type_ (google.cloud.ces_v1beta.types.WidgetTool.TextResponseConfig.Type): + Optional. The strategy for providing the text + response. + static_text (str): + Optional. The static text response to return + when type is STATIC. + text_response_instruction (str): + Optional. Instruction for the LLM on how to generate the + text response. Used as the description for the text response + parameter if type is LLM_GENERATED. + """ + + class Type(proto.Enum): + r"""Defines how the text response is produced. + + Values: + TYPE_UNSPECIFIED (0): + Unspecified type. + NONE (1): + The LLM dynamically decides whether to + generate a text response alongside the widget + based on the conversation context. + LLM_GENERATED (2): + The LLM is explicitly required to generate a + text response. + STATIC (3): + A pre-defined static text response is always + used. + """ + + TYPE_UNSPECIFIED = 0 + NONE = 1 + LLM_GENERATED = 2 + STATIC = 3 + + type_: "WidgetTool.TextResponseConfig.Type" = proto.Field( + proto.ENUM, + number=1, + enum="WidgetTool.TextResponseConfig.Type", + ) + static_text: str = proto.Field( + proto.STRING, + number=2, + ) + text_response_instruction: str = proto.Field( + proto.STRING, + number=3, + ) + class DataMapping(proto.Message): r"""Configuration for mapping data from a source tool to the widget's input parameters. @@ -205,6 +261,11 @@ class Mode(proto.Enum): number=6, message=DataMapping, ) + text_response_config: TextResponseConfig = proto.Field( + proto.MESSAGE, + number=7, + message=TextResponseConfig, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-ces/samples/generated_samples/ces_v1beta_generated_evaluation_service_export_evaluation_results_async.py b/packages/google-cloud-ces/samples/generated_samples/ces_v1beta_generated_evaluation_service_export_evaluation_results_async.py new file mode 100644 index 000000000000..475c2cd0ed17 --- /dev/null +++ b/packages/google-cloud-ces/samples/generated_samples/ces_v1beta_generated_evaluation_service_export_evaluation_results_async.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ExportEvaluationResults +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-ces + + +# [START ces_v1beta_generated_EvaluationService_ExportEvaluationResults_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import ces_v1beta + + +async def sample_export_evaluation_results(): + # Create a client + client = ces_v1beta.EvaluationServiceAsyncClient() + + # Initialize request argument(s) + request = ces_v1beta.ExportEvaluationResultsRequest( + parent="parent_value", + names=["names_value1", "names_value2"], + ) + + # Make the request + operation = await client.export_evaluation_results(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + +# [END ces_v1beta_generated_EvaluationService_ExportEvaluationResults_async] diff --git a/packages/google-cloud-ces/samples/generated_samples/ces_v1beta_generated_evaluation_service_export_evaluation_results_sync.py b/packages/google-cloud-ces/samples/generated_samples/ces_v1beta_generated_evaluation_service_export_evaluation_results_sync.py new file mode 100644 index 000000000000..bed15bb2086c --- /dev/null +++ b/packages/google-cloud-ces/samples/generated_samples/ces_v1beta_generated_evaluation_service_export_evaluation_results_sync.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ExportEvaluationResults +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-ces + + +# [START ces_v1beta_generated_EvaluationService_ExportEvaluationResults_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import ces_v1beta + + +def sample_export_evaluation_results(): + # Create a client + client = ces_v1beta.EvaluationServiceClient() + + # Initialize request argument(s) + request = ces_v1beta.ExportEvaluationResultsRequest( + parent="parent_value", + names=["names_value1", "names_value2"], + ) + + # Make the request + operation = client.export_evaluation_results(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + +# [END ces_v1beta_generated_EvaluationService_ExportEvaluationResults_sync] diff --git a/packages/google-cloud-ces/samples/generated_samples/ces_v1beta_generated_evaluation_service_export_evaluation_runs_async.py b/packages/google-cloud-ces/samples/generated_samples/ces_v1beta_generated_evaluation_service_export_evaluation_runs_async.py new file mode 100644 index 000000000000..5cedb83f1d10 --- /dev/null +++ b/packages/google-cloud-ces/samples/generated_samples/ces_v1beta_generated_evaluation_service_export_evaluation_runs_async.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ExportEvaluationRuns +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-ces + + +# [START ces_v1beta_generated_EvaluationService_ExportEvaluationRuns_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import ces_v1beta + + +async def sample_export_evaluation_runs(): + # Create a client + client = ces_v1beta.EvaluationServiceAsyncClient() + + # Initialize request argument(s) + request = ces_v1beta.ExportEvaluationRunsRequest( + parent="parent_value", + names=["names_value1", "names_value2"], + ) + + # Make the request + operation = await client.export_evaluation_runs(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + +# [END ces_v1beta_generated_EvaluationService_ExportEvaluationRuns_async] diff --git a/packages/google-cloud-ces/samples/generated_samples/ces_v1beta_generated_evaluation_service_export_evaluation_runs_sync.py b/packages/google-cloud-ces/samples/generated_samples/ces_v1beta_generated_evaluation_service_export_evaluation_runs_sync.py new file mode 100644 index 000000000000..009942d18854 --- /dev/null +++ b/packages/google-cloud-ces/samples/generated_samples/ces_v1beta_generated_evaluation_service_export_evaluation_runs_sync.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ExportEvaluationRuns +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-ces + + +# [START ces_v1beta_generated_EvaluationService_ExportEvaluationRuns_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import ces_v1beta + + +def sample_export_evaluation_runs(): + # Create a client + client = ces_v1beta.EvaluationServiceClient() + + # Initialize request argument(s) + request = ces_v1beta.ExportEvaluationRunsRequest( + parent="parent_value", + names=["names_value1", "names_value2"], + ) + + # Make the request + operation = client.export_evaluation_runs(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + +# [END ces_v1beta_generated_EvaluationService_ExportEvaluationRuns_sync] diff --git a/packages/google-cloud-ces/samples/generated_samples/ces_v1beta_generated_evaluation_service_run_evaluation_result_metrics_async.py b/packages/google-cloud-ces/samples/generated_samples/ces_v1beta_generated_evaluation_service_run_evaluation_result_metrics_async.py new file mode 100644 index 000000000000..0b8453560128 --- /dev/null +++ b/packages/google-cloud-ces/samples/generated_samples/ces_v1beta_generated_evaluation_service_run_evaluation_result_metrics_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for RunEvaluationResultMetrics +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-ces + + +# [START ces_v1beta_generated_EvaluationService_RunEvaluationResultMetrics_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import ces_v1beta + + +async def sample_run_evaluation_result_metrics(): + # Create a client + client = ces_v1beta.EvaluationServiceAsyncClient() + + # Initialize request argument(s) + request = ces_v1beta.RunEvaluationResultMetricsRequest( + evaluation_result_id="evaluation_result_id_value", + ) + + # Make the request + operation = await client.run_evaluation_result_metrics(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + +# [END ces_v1beta_generated_EvaluationService_RunEvaluationResultMetrics_async] diff --git a/packages/google-cloud-ces/samples/generated_samples/ces_v1beta_generated_evaluation_service_run_evaluation_result_metrics_sync.py b/packages/google-cloud-ces/samples/generated_samples/ces_v1beta_generated_evaluation_service_run_evaluation_result_metrics_sync.py new file mode 100644 index 000000000000..578ba7b5be2b --- /dev/null +++ b/packages/google-cloud-ces/samples/generated_samples/ces_v1beta_generated_evaluation_service_run_evaluation_result_metrics_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for RunEvaluationResultMetrics +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-ces + + +# [START ces_v1beta_generated_EvaluationService_RunEvaluationResultMetrics_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import ces_v1beta + + +def sample_run_evaluation_result_metrics(): + # Create a client + client = ces_v1beta.EvaluationServiceClient() + + # Initialize request argument(s) + request = ces_v1beta.RunEvaluationResultMetricsRequest( + evaluation_result_id="evaluation_result_id_value", + ) + + # Make the request + operation = client.run_evaluation_result_metrics(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + +# [END ces_v1beta_generated_EvaluationService_RunEvaluationResultMetrics_sync] diff --git a/packages/google-cloud-ces/samples/generated_samples/snippet_metadata_google.cloud.ces.v1beta.json b/packages/google-cloud-ces/samples/generated_samples/snippet_metadata_google.cloud.ces.v1beta.json index 6a2d1585f052..0d389ae737b9 100644 --- a/packages/google-cloud-ces/samples/generated_samples/snippet_metadata_google.cloud.ces.v1beta.json +++ b/packages/google-cloud-ces/samples/generated_samples/snippet_metadata_google.cloud.ces.v1beta.json @@ -10026,6 +10026,344 @@ ], "title": "ces_v1beta_generated_evaluation_service_delete_scheduled_evaluation_run_sync.py" }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.ces_v1beta.EvaluationServiceAsyncClient", + "shortName": "EvaluationServiceAsyncClient" + }, + "fullName": "google.cloud.ces_v1beta.EvaluationServiceAsyncClient.export_evaluation_results", + "method": { + "fullName": "google.cloud.ces.v1beta.EvaluationService.ExportEvaluationResults", + "service": { + "fullName": "google.cloud.ces.v1beta.EvaluationService", + "shortName": "EvaluationService" + }, + "shortName": "ExportEvaluationResults" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.ces_v1beta.types.ExportEvaluationResultsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "names", + "type": "MutableSequence[str]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "export_evaluation_results" + }, + "description": "Sample for ExportEvaluationResults", + "file": "ces_v1beta_generated_evaluation_service_export_evaluation_results_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "ces_v1beta_generated_EvaluationService_ExportEvaluationResults_async", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "ces_v1beta_generated_evaluation_service_export_evaluation_results_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.ces_v1beta.EvaluationServiceClient", + "shortName": "EvaluationServiceClient" + }, + "fullName": "google.cloud.ces_v1beta.EvaluationServiceClient.export_evaluation_results", + "method": { + "fullName": "google.cloud.ces.v1beta.EvaluationService.ExportEvaluationResults", + "service": { + "fullName": "google.cloud.ces.v1beta.EvaluationService", + "shortName": "EvaluationService" + }, + "shortName": "ExportEvaluationResults" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.ces_v1beta.types.ExportEvaluationResultsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "names", + "type": "MutableSequence[str]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "export_evaluation_results" + }, + "description": "Sample for ExportEvaluationResults", + "file": "ces_v1beta_generated_evaluation_service_export_evaluation_results_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "ces_v1beta_generated_EvaluationService_ExportEvaluationResults_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "ces_v1beta_generated_evaluation_service_export_evaluation_results_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.ces_v1beta.EvaluationServiceAsyncClient", + "shortName": "EvaluationServiceAsyncClient" + }, + "fullName": "google.cloud.ces_v1beta.EvaluationServiceAsyncClient.export_evaluation_runs", + "method": { + "fullName": "google.cloud.ces.v1beta.EvaluationService.ExportEvaluationRuns", + "service": { + "fullName": "google.cloud.ces.v1beta.EvaluationService", + "shortName": "EvaluationService" + }, + "shortName": "ExportEvaluationRuns" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.ces_v1beta.types.ExportEvaluationRunsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "names", + "type": "MutableSequence[str]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "export_evaluation_runs" + }, + "description": "Sample for ExportEvaluationRuns", + "file": "ces_v1beta_generated_evaluation_service_export_evaluation_runs_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "ces_v1beta_generated_EvaluationService_ExportEvaluationRuns_async", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "ces_v1beta_generated_evaluation_service_export_evaluation_runs_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.ces_v1beta.EvaluationServiceClient", + "shortName": "EvaluationServiceClient" + }, + "fullName": "google.cloud.ces_v1beta.EvaluationServiceClient.export_evaluation_runs", + "method": { + "fullName": "google.cloud.ces.v1beta.EvaluationService.ExportEvaluationRuns", + "service": { + "fullName": "google.cloud.ces.v1beta.EvaluationService", + "shortName": "EvaluationService" + }, + "shortName": "ExportEvaluationRuns" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.ces_v1beta.types.ExportEvaluationRunsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "names", + "type": "MutableSequence[str]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "export_evaluation_runs" + }, + "description": "Sample for ExportEvaluationRuns", + "file": "ces_v1beta_generated_evaluation_service_export_evaluation_runs_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "ces_v1beta_generated_EvaluationService_ExportEvaluationRuns_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "ces_v1beta_generated_evaluation_service_export_evaluation_runs_sync.py" + }, { "canonical": true, "clientMethod": { @@ -12441,6 +12779,167 @@ ], "title": "ces_v1beta_generated_evaluation_service_list_scheduled_evaluation_runs_sync.py" }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.ces_v1beta.EvaluationServiceAsyncClient", + "shortName": "EvaluationServiceAsyncClient" + }, + "fullName": "google.cloud.ces_v1beta.EvaluationServiceAsyncClient.run_evaluation_result_metrics", + "method": { + "fullName": "google.cloud.ces.v1beta.EvaluationService.RunEvaluationResultMetrics", + "service": { + "fullName": "google.cloud.ces.v1beta.EvaluationService", + "shortName": "EvaluationService" + }, + "shortName": "RunEvaluationResultMetrics" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.ces_v1beta.types.RunEvaluationResultMetricsRequest" + }, + { + "name": "evaluation_result_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "run_evaluation_result_metrics" + }, + "description": "Sample for RunEvaluationResultMetrics", + "file": "ces_v1beta_generated_evaluation_service_run_evaluation_result_metrics_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "ces_v1beta_generated_EvaluationService_RunEvaluationResultMetrics_async", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "ces_v1beta_generated_evaluation_service_run_evaluation_result_metrics_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.ces_v1beta.EvaluationServiceClient", + "shortName": "EvaluationServiceClient" + }, + "fullName": "google.cloud.ces_v1beta.EvaluationServiceClient.run_evaluation_result_metrics", + "method": { + "fullName": "google.cloud.ces.v1beta.EvaluationService.RunEvaluationResultMetrics", + "service": { + "fullName": "google.cloud.ces.v1beta.EvaluationService", + "shortName": "EvaluationService" + }, + "shortName": "RunEvaluationResultMetrics" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.ces_v1beta.types.RunEvaluationResultMetricsRequest" + }, + { + "name": "evaluation_result_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "run_evaluation_result_metrics" + }, + "description": "Sample for RunEvaluationResultMetrics", + "file": "ces_v1beta_generated_evaluation_service_run_evaluation_result_metrics_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "ces_v1beta_generated_EvaluationService_RunEvaluationResultMetrics_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "ces_v1beta_generated_evaluation_service_run_evaluation_result_metrics_sync.py" + }, { "canonical": true, "clientMethod": { diff --git a/packages/google-cloud-ces/tests/unit/gapic/ces_v1beta/test_agent_service.py b/packages/google-cloud-ces/tests/unit/gapic/ces_v1beta/test_agent_service.py index 11f7b2fae5ea..8c34161fe618 100644 --- a/packages/google-cloud-ces/tests/unit/gapic/ces_v1beta/test_agent_service.py +++ b/packages/google-cloud-ces/tests/unit/gapic/ces_v1beta/test_agent_service.py @@ -71,6 +71,7 @@ ) from google.cloud.ces_v1beta.types import ( agent, + agent_card, agent_service, agent_tool, agent_transfers, @@ -87,6 +88,7 @@ data_store, data_store_tool, deployment, + evaluation_metrics_config, example, fakes, file_context, @@ -1914,6 +1916,7 @@ def test_get_app(request_type, transport: str = "grpc"): etag="etag_value", deployment_count=1737, locked=True, + validation_errors=["validation_errors_value"], ) response = client.get_app(request) @@ -1936,6 +1939,7 @@ def test_get_app(request_type, transport: str = "grpc"): assert response.etag == "etag_value" assert response.deployment_count == 1737 assert response.locked is True + assert response.validation_errors == ["validation_errors_value"] def test_get_app_non_empty_request_with_auto_populated_field(): @@ -2076,6 +2080,7 @@ async def test_get_app_async(request_type, transport: str = "grpc_asyncio"): etag="etag_value", deployment_count=1737, locked=True, + validation_errors=["validation_errors_value"], ) ) response = await client.get_app(request) @@ -2099,6 +2104,7 @@ async def test_get_app_async(request_type, transport: str = "grpc_asyncio"): assert response.etag == "etag_value" assert response.deployment_count == 1737 assert response.locked is True + assert response.validation_errors == ["validation_errors_value"] def test_get_app_field_headers(): @@ -2620,6 +2626,7 @@ def test_update_app(request_type, transport: str = "grpc"): etag="etag_value", deployment_count=1737, locked=True, + validation_errors=["validation_errors_value"], ) response = client.update_app(request) @@ -2642,6 +2649,7 @@ def test_update_app(request_type, transport: str = "grpc"): assert response.etag == "etag_value" assert response.deployment_count == 1737 assert response.locked is True + assert response.validation_errors == ["validation_errors_value"] def test_update_app_non_empty_request_with_auto_populated_field(): @@ -2778,6 +2786,7 @@ async def test_update_app_async(request_type, transport: str = "grpc_asyncio"): etag="etag_value", deployment_count=1737, locked=True, + validation_errors=["validation_errors_value"], ) ) response = await client.update_app(request) @@ -2801,6 +2810,7 @@ async def test_update_app_async(request_type, transport: str = "grpc_asyncio"): assert response.etag == "etag_value" assert response.deployment_count == 1737 assert response.locked is True + assert response.validation_errors == ["validation_errors_value"] def test_update_app_field_headers(): @@ -5216,6 +5226,7 @@ def test_get_agent(request_type, transport: str = "grpc"): guardrails=["guardrails_value"], etag="etag_value", generated_summary="generated_summary_value", + validation_errors=["validation_errors_value"], ) response = client.get_agent(request) @@ -5236,6 +5247,7 @@ def test_get_agent(request_type, transport: str = "grpc"): assert response.guardrails == ["guardrails_value"] assert response.etag == "etag_value" assert response.generated_summary == "generated_summary_value" + assert response.validation_errors == ["validation_errors_value"] def test_get_agent_non_empty_request_with_auto_populated_field(): @@ -5374,6 +5386,7 @@ async def test_get_agent_async(request_type, transport: str = "grpc_asyncio"): guardrails=["guardrails_value"], etag="etag_value", generated_summary="generated_summary_value", + validation_errors=["validation_errors_value"], ) ) response = await client.get_agent(request) @@ -5395,6 +5408,7 @@ async def test_get_agent_async(request_type, transport: str = "grpc_asyncio"): assert response.guardrails == ["guardrails_value"] assert response.etag == "etag_value" assert response.generated_summary == "generated_summary_value" + assert response.validation_errors == ["validation_errors_value"] def test_get_agent_field_headers(): @@ -5566,6 +5580,7 @@ def test_create_agent(request_type, transport: str = "grpc"): guardrails=["guardrails_value"], etag="etag_value", generated_summary="generated_summary_value", + validation_errors=["validation_errors_value"], ) response = client.create_agent(request) @@ -5586,6 +5601,7 @@ def test_create_agent(request_type, transport: str = "grpc"): assert response.guardrails == ["guardrails_value"] assert response.etag == "etag_value" assert response.generated_summary == "generated_summary_value" + assert response.validation_errors == ["validation_errors_value"] def test_create_agent_non_empty_request_with_auto_populated_field(): @@ -5728,6 +5744,7 @@ async def test_create_agent_async(request_type, transport: str = "grpc_asyncio") guardrails=["guardrails_value"], etag="etag_value", generated_summary="generated_summary_value", + validation_errors=["validation_errors_value"], ) ) response = await client.create_agent(request) @@ -5749,6 +5766,7 @@ async def test_create_agent_async(request_type, transport: str = "grpc_asyncio") assert response.guardrails == ["guardrails_value"] assert response.etag == "etag_value" assert response.generated_summary == "generated_summary_value" + assert response.validation_errors == ["validation_errors_value"] def test_create_agent_field_headers(): @@ -5940,6 +5958,7 @@ def test_update_agent(request_type, transport: str = "grpc"): guardrails=["guardrails_value"], etag="etag_value", generated_summary="generated_summary_value", + validation_errors=["validation_errors_value"], ) response = client.update_agent(request) @@ -5960,6 +5979,7 @@ def test_update_agent(request_type, transport: str = "grpc"): assert response.guardrails == ["guardrails_value"] assert response.etag == "etag_value" assert response.generated_summary == "generated_summary_value" + assert response.validation_errors == ["validation_errors_value"] def test_update_agent_non_empty_request_with_auto_populated_field(): @@ -6096,6 +6116,7 @@ async def test_update_agent_async(request_type, transport: str = "grpc_asyncio") guardrails=["guardrails_value"], etag="etag_value", generated_summary="generated_summary_value", + validation_errors=["validation_errors_value"], ) ) response = await client.update_agent(request) @@ -6117,6 +6138,7 @@ async def test_update_agent_async(request_type, transport: str = "grpc_asyncio") assert response.guardrails == ["guardrails_value"] assert response.etag == "etag_value" assert response.generated_summary == "generated_summary_value" + assert response.validation_errors == ["validation_errors_value"] def test_update_agent_field_headers(): @@ -32266,6 +32288,7 @@ async def test_get_app_empty_call_grpc_asyncio(): etag="etag_value", deployment_count=1737, locked=True, + validation_errors=["validation_errors_value"], ) ) await client.get_app(request=None) @@ -32326,6 +32349,7 @@ async def test_update_app_empty_call_grpc_asyncio(): etag="etag_value", deployment_count=1737, locked=True, + validation_errors=["validation_errors_value"], ) ) await client.update_app(request=None) @@ -32516,6 +32540,7 @@ async def test_get_agent_empty_call_grpc_asyncio(): guardrails=["guardrails_value"], etag="etag_value", generated_summary="generated_summary_value", + validation_errors=["validation_errors_value"], ) ) await client.get_agent(request=None) @@ -32550,6 +32575,7 @@ async def test_create_agent_empty_call_grpc_asyncio(): guardrails=["guardrails_value"], etag="etag_value", generated_summary="generated_summary_value", + validation_errors=["validation_errors_value"], ) ) await client.create_agent(request=None) @@ -32584,6 +32610,7 @@ async def test_update_agent_empty_call_grpc_asyncio(): guardrails=["guardrails_value"], etag="etag_value", generated_summary="generated_summary_value", + validation_errors=["validation_errors_value"], ) ) await client.update_agent(request=None) @@ -33842,6 +33869,7 @@ def test_get_app_rest_call_success(request_type): etag="etag_value", deployment_count=1737, locked=True, + validation_errors=["validation_errors_value"], ) # Wrap the value into a proper Response obj @@ -33869,6 +33897,7 @@ def test_get_app_rest_call_success(request_type): assert response.etag == "etag_value" assert response.deployment_count == 1737 assert response.locked is True + assert response.validation_errors == ["validation_errors_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) @@ -34006,6 +34035,7 @@ def test_create_app_rest_call_success(request_type): "gcs_bucket": "gcs_bucket_value", "gcs_path_prefix": "gcs_path_prefix_value", }, + "unredacted_audio_recording_config": {}, "bigquery_export_settings": { "enabled": True, "project": "project_value", @@ -34115,6 +34145,9 @@ def test_create_app_rest_call_success(request_type): "private_key": "private_key_value", "passphrase": "passphrase_value", }, + "vpc_sc_settings": { + "allowed_origins": ["allowed_origins_value1", "allowed_origins_value2"] + }, "locked": True, "evaluation_personas": [ { @@ -34134,7 +34167,28 @@ def test_create_app_rest_call_success(request_type): "golden_run_method": 1, "golden_evaluation_tool_call_behaviour": 1, "scenario_evaluation_tool_call_behaviour": 1, + "metrics_config": { + "golden_metrics_config": { + "semantic_similarity_metrics_config": { + "enable_semantic_similarity_metrics": True + }, + "tool_correctness_metrics_config": { + "enable_tool_correctness_metrics": True + }, + "step_tool_correctness_metrics_config": {}, + }, + "scenario_metrics_config": { + "user_goal_met_metrics_config": { + "enable_user_goal_met_metrics": True + }, + "expectations_met_metrics_config": { + "enable_expectations_met_metrics": True + }, + }, + }, + "scenario_execution_mode": 1, }, + "validation_errors": ["validation_errors_value1", "validation_errors_value2"], } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -34361,6 +34415,7 @@ def test_update_app_rest_call_success(request_type): "gcs_bucket": "gcs_bucket_value", "gcs_path_prefix": "gcs_path_prefix_value", }, + "unredacted_audio_recording_config": {}, "bigquery_export_settings": { "enabled": True, "project": "project_value", @@ -34470,6 +34525,9 @@ def test_update_app_rest_call_success(request_type): "private_key": "private_key_value", "passphrase": "passphrase_value", }, + "vpc_sc_settings": { + "allowed_origins": ["allowed_origins_value1", "allowed_origins_value2"] + }, "locked": True, "evaluation_personas": [ { @@ -34489,7 +34547,28 @@ def test_update_app_rest_call_success(request_type): "golden_run_method": 1, "golden_evaluation_tool_call_behaviour": 1, "scenario_evaluation_tool_call_behaviour": 1, + "metrics_config": { + "golden_metrics_config": { + "semantic_similarity_metrics_config": { + "enable_semantic_similarity_metrics": True + }, + "tool_correctness_metrics_config": { + "enable_tool_correctness_metrics": True + }, + "step_tool_correctness_metrics_config": {}, + }, + "scenario_metrics_config": { + "user_goal_met_metrics_config": { + "enable_user_goal_met_metrics": True + }, + "expectations_met_metrics_config": { + "enable_expectations_met_metrics": True + }, + }, + }, + "scenario_execution_mode": 1, }, + "validation_errors": ["validation_errors_value1", "validation_errors_value2"], } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -34575,6 +34654,7 @@ def get_message_fields(field): etag="etag_value", deployment_count=1737, locked=True, + validation_errors=["validation_errors_value"], ) # Wrap the value into a proper Response obj @@ -34602,6 +34682,7 @@ def get_message_fields(field): assert response.etag == "etag_value" assert response.deployment_count == 1737 assert response.locked is True + assert response.validation_errors == ["validation_errors_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) @@ -35576,6 +35657,7 @@ def test_get_agent_rest_call_success(request_type): guardrails=["guardrails_value"], etag="etag_value", generated_summary="generated_summary_value", + validation_errors=["validation_errors_value"], ) # Wrap the value into a proper Response obj @@ -35601,6 +35683,7 @@ def test_get_agent_rest_call_success(request_type): assert response.guardrails == ["guardrails_value"] assert response.etag == "etag_value" assert response.generated_summary == "generated_summary_value" + assert response.validation_errors == ["validation_errors_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) @@ -35712,6 +35795,7 @@ def test_create_agent_rest_call_success(request_type): "input_variable_mapping": {}, "output_variable_mapping": {}, "respect_response_interruption_settings": True, + "language_code_variable": "language_code_variable_value", }, "name": "name_value", "display_name": "display_name_value", @@ -35755,6 +35839,7 @@ def test_create_agent_rest_call_success(request_type): "direction": 1, } ], + "validation_errors": ["validation_errors_value1", "validation_errors_value2"], } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -35838,6 +35923,7 @@ def get_message_fields(field): guardrails=["guardrails_value"], etag="etag_value", generated_summary="generated_summary_value", + validation_errors=["validation_errors_value"], ) # Wrap the value into a proper Response obj @@ -35863,6 +35949,7 @@ def get_message_fields(field): assert response.guardrails == ["guardrails_value"] assert response.etag == "etag_value" assert response.generated_summary == "generated_summary_value" + assert response.validation_errors == ["validation_errors_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) @@ -35984,6 +36071,7 @@ def test_update_agent_rest_call_success(request_type): "input_variable_mapping": {}, "output_variable_mapping": {}, "respect_response_interruption_settings": True, + "language_code_variable": "language_code_variable_value", }, "name": "projects/sample1/locations/sample2/apps/sample3/agents/sample4", "display_name": "display_name_value", @@ -36027,6 +36115,7 @@ def test_update_agent_rest_call_success(request_type): "direction": 1, } ], + "validation_errors": ["validation_errors_value1", "validation_errors_value2"], } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -36110,6 +36199,7 @@ def get_message_fields(field): guardrails=["guardrails_value"], etag="etag_value", generated_summary="generated_summary_value", + validation_errors=["validation_errors_value"], ) # Wrap the value into a proper Response obj @@ -36135,6 +36225,7 @@ def get_message_fields(field): assert response.guardrails == ["guardrails_value"] assert response.etag == "etag_value" assert response.generated_summary == "generated_summary_value" + assert response.validation_errors == ["validation_errors_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) @@ -38225,9 +38316,11 @@ def test_create_tool_rest_call_success(request_type): "name": "name_value", "python_code": "python_code_value", "description": "description_value", + "service_directory_config": {}, }, "mcp_tool": { "name": "name_value", + "name_override": "name_override_value", "description": "description_value", "input_schema": {}, "output_schema": {}, @@ -38236,6 +38329,7 @@ def test_create_tool_rest_call_success(request_type): "tls_config": {}, "service_directory_config": {}, "custom_headers": {}, + "state": 1, }, "file_search_tool": { "corpus_type": 1, @@ -38263,10 +38357,44 @@ def test_create_tool_rest_call_success(request_type): "mode": 1, "python_script": "python_script_value", }, + "text_response_config": { + "type_": 1, + "static_text": "static_text_value", + "text_response_instruction": "text_response_instruction_value", + }, + }, + "remote_agent_tool": { + "name": "name_value", + "description": "description_value", + "agent_card": { + "name": "name_value", + "description": "description_value", + "supported_interfaces": [ + { + "url": "url_value", + "protocol_binding": "protocol_binding_value", + "tenant": "tenant_value", + "protocol_version": "protocol_version_value", + } + ], + "version": "version_value", + "skills": [ + { + "id": "id_value", + "name": "name_value", + "description": "description_value", + "tags": ["tags_value1", "tags_value2"], + "examples": ["examples_value1", "examples_value2"], + "input_modes": ["input_modes_value1", "input_modes_value2"], + "output_modes": ["output_modes_value1", "output_modes_value2"], + } + ], + }, }, "name": "name_value", "display_name": "display_name_value", "execution_type": 1, + "timeout": {"seconds": 751, "nanos": 543}, "create_time": {}, "update_time": {}, "etag": "etag_value", @@ -38664,9 +38792,11 @@ def test_update_tool_rest_call_success(request_type): "name": "name_value", "python_code": "python_code_value", "description": "description_value", + "service_directory_config": {}, }, "mcp_tool": { "name": "name_value", + "name_override": "name_override_value", "description": "description_value", "input_schema": {}, "output_schema": {}, @@ -38675,6 +38805,7 @@ def test_update_tool_rest_call_success(request_type): "tls_config": {}, "service_directory_config": {}, "custom_headers": {}, + "state": 1, }, "file_search_tool": { "corpus_type": 1, @@ -38702,10 +38833,44 @@ def test_update_tool_rest_call_success(request_type): "mode": 1, "python_script": "python_script_value", }, + "text_response_config": { + "type_": 1, + "static_text": "static_text_value", + "text_response_instruction": "text_response_instruction_value", + }, + }, + "remote_agent_tool": { + "name": "name_value", + "description": "description_value", + "agent_card": { + "name": "name_value", + "description": "description_value", + "supported_interfaces": [ + { + "url": "url_value", + "protocol_binding": "protocol_binding_value", + "tenant": "tenant_value", + "protocol_version": "protocol_version_value", + } + ], + "version": "version_value", + "skills": [ + { + "id": "id_value", + "name": "name_value", + "description": "description_value", + "tags": ["tags_value1", "tags_value2"], + "examples": ["examples_value1", "examples_value2"], + "input_modes": ["input_modes_value1", "input_modes_value2"], + "output_modes": ["output_modes_value1", "output_modes_value2"], + } + ], + }, }, "name": "projects/sample1/locations/sample2/apps/sample3/tools/sample4", "display_name": "display_name_value", "execution_type": 1, + "timeout": {"seconds": 751, "nanos": 543}, "create_time": {}, "update_time": {}, "etag": "etag_value", @@ -40258,6 +40423,18 @@ def test_create_deployment_rest_call_success(request_type): "create_time": {"seconds": 751, "nanos": 543}, "update_time": {}, "etag": "etag_value", + "experiment_config": { + "version_release": { + "state": 1, + "traffic_allocations": [ + { + "id": "id_value", + "traffic_percentage": 1884, + "app_version": "app_version_value", + } + ], + } + }, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -40500,6 +40677,18 @@ def test_update_deployment_rest_call_success(request_type): "create_time": {"seconds": 751, "nanos": 543}, "update_time": {}, "etag": "etag_value", + "experiment_config": { + "version_release": { + "state": 1, + "traffic_allocations": [ + { + "id": "id_value", + "traffic_percentage": 1884, + "app_version": "app_version_value", + } + ], + } + }, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -41119,6 +41308,45 @@ def test_create_toolset_rest_call_success(request_type): ] }, "custom_headers": {}, + "tool_overrides": [ + { + "tool": "tool_value", + "name_override": "name_override_value", + "description_override": "description_override_value", + "snapshot": { + "description": "description_value", + "input_schema": { + "type_": 1, + "properties": {}, + "required": ["required_value1", "required_value2"], + "description": "description_value", + "items": {}, + "nullable": True, + "unique_items": True, + "prefix_items": {}, + "additional_properties": {}, + "any_of": {}, + "enum": ["enum_value1", "enum_value2"], + "default": { + "null_value": 0, + "number_value": 0.1285, + "string_value": "string_value_value", + "bool_value": True, + "struct_value": {"fields": {}}, + "list_value": {"values": {}}, + }, + "ref": "ref_value", + "defs": {}, + "title": "title_value", + "min_items": 965, + "max_items": 967, + "minimum": 0.764, + "maximum": 0.766, + }, + "output_schema": {}, + }, + } + ], }, "open_api_toolset": { "open_api_schema": "open_api_schema_value", @@ -41405,6 +41633,45 @@ def test_update_toolset_rest_call_success(request_type): ] }, "custom_headers": {}, + "tool_overrides": [ + { + "tool": "tool_value", + "name_override": "name_override_value", + "description_override": "description_override_value", + "snapshot": { + "description": "description_value", + "input_schema": { + "type_": 1, + "properties": {}, + "required": ["required_value1", "required_value2"], + "description": "description_value", + "items": {}, + "nullable": True, + "unique_items": True, + "prefix_items": {}, + "additional_properties": {}, + "any_of": {}, + "enum": ["enum_value1", "enum_value2"], + "default": { + "null_value": 0, + "number_value": 0.1285, + "string_value": "string_value_value", + "bool_value": True, + "struct_value": {"fields": {}}, + "list_value": {"values": {}}, + }, + "ref": "ref_value", + "defs": {}, + "title": "title_value", + "min_items": 965, + "max_items": 967, + "minimum": 0.764, + "maximum": 0.766, + }, + "output_schema": {}, + }, + } + ], }, "open_api_toolset": { "open_api_schema": "open_api_schema_value", @@ -42092,6 +42359,7 @@ def test_create_app_version_rest_call_success(request_type): "gcs_bucket": "gcs_bucket_value", "gcs_path_prefix": "gcs_path_prefix_value", }, + "unredacted_audio_recording_config": {}, "bigquery_export_settings": { "enabled": True, "project": "project_value", @@ -42203,6 +42471,12 @@ def test_create_app_version_rest_call_success(request_type): "private_key": "private_key_value", "passphrase": "passphrase_value", }, + "vpc_sc_settings": { + "allowed_origins": [ + "allowed_origins_value1", + "allowed_origins_value2", + ] + }, "locked": True, "evaluation_personas": [ { @@ -42222,7 +42496,31 @@ def test_create_app_version_rest_call_success(request_type): "golden_run_method": 1, "golden_evaluation_tool_call_behaviour": 1, "scenario_evaluation_tool_call_behaviour": 1, + "metrics_config": { + "golden_metrics_config": { + "semantic_similarity_metrics_config": { + "enable_semantic_similarity_metrics": True + }, + "tool_correctness_metrics_config": { + "enable_tool_correctness_metrics": True + }, + "step_tool_correctness_metrics_config": {}, + }, + "scenario_metrics_config": { + "user_goal_met_metrics_config": { + "enable_user_goal_met_metrics": True + }, + "expectations_met_metrics_config": { + "enable_expectations_met_metrics": True + }, + }, + }, + "scenario_execution_mode": 1, }, + "validation_errors": [ + "validation_errors_value1", + "validation_errors_value2", + ], }, "agents": [ { @@ -42234,6 +42532,7 @@ def test_create_app_version_rest_call_success(request_type): "input_variable_mapping": {}, "output_variable_mapping": {}, "respect_response_interruption_settings": True, + "language_code_variable": "language_code_variable_value", }, "name": "name_value", "display_name": "display_name_value", @@ -42281,6 +42580,10 @@ def test_create_app_version_rest_call_success(request_type): "direction": 1, } ], + "validation_errors": [ + "validation_errors_value1", + "validation_errors_value2", + ], } ], "tools": [ @@ -42451,9 +42754,11 @@ def test_create_app_version_rest_call_success(request_type): "name": "name_value", "python_code": "python_code_value", "description": "description_value", + "service_directory_config": {}, }, "mcp_tool": { "name": "name_value", + "name_override": "name_override_value", "description": "description_value", "input_schema": {}, "output_schema": {}, @@ -42462,6 +42767,7 @@ def test_create_app_version_rest_call_success(request_type): "tls_config": {}, "service_directory_config": {}, "custom_headers": {}, + "state": 1, }, "file_search_tool": { "corpus_type": 1, @@ -42492,10 +42798,50 @@ def test_create_app_version_rest_call_success(request_type): "mode": 1, "python_script": "python_script_value", }, + "text_response_config": { + "type_": 1, + "static_text": "static_text_value", + "text_response_instruction": "text_response_instruction_value", + }, + }, + "remote_agent_tool": { + "name": "name_value", + "description": "description_value", + "agent_card": { + "name": "name_value", + "description": "description_value", + "supported_interfaces": [ + { + "url": "url_value", + "protocol_binding": "protocol_binding_value", + "tenant": "tenant_value", + "protocol_version": "protocol_version_value", + } + ], + "version": "version_value", + "skills": [ + { + "id": "id_value", + "name": "name_value", + "description": "description_value", + "tags": ["tags_value1", "tags_value2"], + "examples": ["examples_value1", "examples_value2"], + "input_modes": [ + "input_modes_value1", + "input_modes_value2", + ], + "output_modes": [ + "output_modes_value1", + "output_modes_value2", + ], + } + ], + }, }, "name": "name_value", "display_name": "display_name_value", "execution_type": 1, + "timeout": {}, "create_time": {}, "update_time": {}, "etag": "etag_value", @@ -42628,6 +42974,18 @@ def test_create_app_version_rest_call_success(request_type): "service_directory_config": {}, "tls_config": {}, "custom_headers": {}, + "tool_overrides": [ + { + "tool": "tool_value", + "name_override": "name_override_value", + "description_override": "description_override_value", + "snapshot": { + "description": "description_value", + "input_schema": {}, + "output_schema": {}, + }, + } + ], }, "open_api_toolset": { "open_api_schema": "open_api_schema_value", diff --git a/packages/google-cloud-ces/tests/unit/gapic/ces_v1beta/test_evaluation_service.py b/packages/google-cloud-ces/tests/unit/gapic/ces_v1beta/test_evaluation_service.py index 3fb631bf3d04..ec4d158b24a6 100644 --- a/packages/google-cloud-ces/tests/unit/gapic/ces_v1beta/test_evaluation_service.py +++ b/packages/google-cloud-ces/tests/unit/gapic/ces_v1beta/test_evaluation_service.py @@ -76,6 +76,7 @@ app, common, evaluation, + evaluation_metrics_config, evaluation_service, example, fakes, @@ -6225,7 +6226,7 @@ def test_get_evaluation_result(request_type, transport: str = "grpc"): app_version="app_version_value", app_version_display_name="app_version_display_name_value", changelog="changelog_value", - execution_state=evaluation.EvaluationResult.ExecutionState.RUNNING, + execution_state=evaluation.EvaluationResult.ExecutionState.QUEUED, golden_run_method=golden_run.GoldenRunMethod.STABLE, ) response = client.get_evaluation_result(request) @@ -6246,9 +6247,7 @@ def test_get_evaluation_result(request_type, transport: str = "grpc"): assert response.app_version == "app_version_value" assert response.app_version_display_name == "app_version_display_name_value" assert response.changelog == "changelog_value" - assert ( - response.execution_state == evaluation.EvaluationResult.ExecutionState.RUNNING - ) + assert response.execution_state == evaluation.EvaluationResult.ExecutionState.QUEUED assert response.golden_run_method == golden_run.GoldenRunMethod.STABLE @@ -6400,7 +6399,7 @@ async def test_get_evaluation_result_async( app_version="app_version_value", app_version_display_name="app_version_display_name_value", changelog="changelog_value", - execution_state=evaluation.EvaluationResult.ExecutionState.RUNNING, + execution_state=evaluation.EvaluationResult.ExecutionState.QUEUED, golden_run_method=golden_run.GoldenRunMethod.STABLE, ) ) @@ -6422,9 +6421,7 @@ async def test_get_evaluation_result_async( assert response.app_version == "app_version_value" assert response.app_version_display_name == "app_version_display_name_value" assert response.changelog == "changelog_value" - assert ( - response.execution_state == evaluation.EvaluationResult.ExecutionState.RUNNING - ) + assert response.execution_state == evaluation.EvaluationResult.ExecutionState.QUEUED assert response.golden_run_method == golden_run.GoldenRunMethod.STABLE @@ -6977,10 +6974,11 @@ def test_get_evaluation_run(request_type, transport: str = "grpc"): evaluations=["evaluations_value"], evaluation_dataset="evaluation_dataset_value", evaluation_type=evaluation.EvaluationRun.EvaluationType.GOLDEN, - state=evaluation.EvaluationRun.EvaluationRunState.RUNNING, + state=evaluation.EvaluationRun.EvaluationRunState.QUEUED, run_count=989, scheduled_evaluation_run="scheduled_evaluation_run_value", golden_run_method=golden_run.GoldenRunMethod.STABLE, + operation="operation_value", ) response = client.get_evaluation_run(request) @@ -7002,10 +7000,11 @@ def test_get_evaluation_run(request_type, transport: str = "grpc"): assert response.evaluations == ["evaluations_value"] assert response.evaluation_dataset == "evaluation_dataset_value" assert response.evaluation_type == evaluation.EvaluationRun.EvaluationType.GOLDEN - assert response.state == evaluation.EvaluationRun.EvaluationRunState.RUNNING + assert response.state == evaluation.EvaluationRun.EvaluationRunState.QUEUED assert response.run_count == 989 assert response.scheduled_evaluation_run == "scheduled_evaluation_run_value" assert response.golden_run_method == golden_run.GoldenRunMethod.STABLE + assert response.operation == "operation_value" def test_get_evaluation_run_non_empty_request_with_auto_populated_field(): @@ -7155,10 +7154,11 @@ async def test_get_evaluation_run_async(request_type, transport: str = "grpc_asy evaluations=["evaluations_value"], evaluation_dataset="evaluation_dataset_value", evaluation_type=evaluation.EvaluationRun.EvaluationType.GOLDEN, - state=evaluation.EvaluationRun.EvaluationRunState.RUNNING, + state=evaluation.EvaluationRun.EvaluationRunState.QUEUED, run_count=989, scheduled_evaluation_run="scheduled_evaluation_run_value", golden_run_method=golden_run.GoldenRunMethod.STABLE, + operation="operation_value", ) ) response = await client.get_evaluation_run(request) @@ -7181,10 +7181,11 @@ async def test_get_evaluation_run_async(request_type, transport: str = "grpc_asy assert response.evaluations == ["evaluations_value"] assert response.evaluation_dataset == "evaluation_dataset_value" assert response.evaluation_type == evaluation.EvaluationRun.EvaluationType.GOLDEN - assert response.state == evaluation.EvaluationRun.EvaluationRunState.RUNNING + assert response.state == evaluation.EvaluationRun.EvaluationRunState.QUEUED assert response.run_count == 989 assert response.scheduled_evaluation_run == "scheduled_evaluation_run_value" assert response.golden_run_method == golden_run.GoldenRunMethod.STABLE + assert response.operation == "operation_value" def test_get_evaluation_run_field_headers(): @@ -14302,13 +14303,79 @@ async def test_export_evaluations_flattened_error_async(): ) -def test_run_evaluation_rest_use_cached_wrapped_rpc(): +@pytest.mark.parametrize( + "request_type", + [ + evaluation_service.ExportEvaluationRunsRequest(), + {}, + ], +) +def test_export_evaluation_runs(request_type, transport: str = "grpc"): + client = EvaluationServiceClient( + 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.export_evaluation_runs), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.export_evaluation_runs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = evaluation_service.ExportEvaluationRunsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_export_evaluation_runs_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = evaluation_service.ExportEvaluationRunsRequest( + parent="parent_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.export_evaluation_runs), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.export_evaluation_runs(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = evaluation_service.ExportEvaluationRunsRequest( + parent="parent_value", + ) + assert args[0] == request_msg + + +def test_export_evaluation_runs_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) # Should wrap all calls on client creation @@ -14316,177 +14383,47 @@ def test_run_evaluation_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.run_evaluation in client._transport._wrapped_methods + assert ( + client._transport.export_evaluation_runs + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.run_evaluation] = mock_rpc - + client._transport._wrapped_methods[client._transport.export_evaluation_runs] = ( + mock_rpc + ) request = {} - client.run_evaluation(request) + client.export_evaluation_runs(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper wrapper_fn.reset_mock() - client.run_evaluation(request) + client.export_evaluation_runs(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_run_evaluation_rest_required_fields( - request_type=evaluation.RunEvaluationRequest, +@pytest.mark.asyncio +async def test_export_evaluation_runs_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", ): - transport_class = transports.EvaluationServiceRestTransport - - request_init = {} - request_init["app"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).run_evaluation._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["app"] = "app_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).run_evaluation._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "app" in jsonified_request - assert jsonified_request["app"] == "app_value" - - client = EvaluationServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "post", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - response = client.run_evaluation(request) - - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) - - -def test_run_evaluation_rest_unset_required_fields(): - transport = transports.EvaluationServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.run_evaluation._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("app",))) - - -def test_run_evaluation_rest_flattened(): - client = EvaluationServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # get arguments that satisfy an http rule for this method - sample_request = {"app": "projects/sample1/locations/sample2/apps/sample3"} - - # get truthy value for each flattened field - mock_args = dict( - app="app_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - client.run_evaluation(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1beta/{app=projects/*/locations/*/apps/*}:runEvaluation" - % client.transport._host, - args[1], - ) - - -def test_run_evaluation_rest_flattened_error(transport: str = "rest"): - client = EvaluationServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.run_evaluation( - evaluation.RunEvaluationRequest(), - app="app_value", - ) - - -def test_upload_evaluation_audio_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = EvaluationServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = EvaluationServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, ) # Should wrap all calls on client creation @@ -14495,40 +14432,1598 @@ def test_upload_evaluation_audio_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.upload_evaluation_audio - in client._transport._wrapped_methods + client._client._transport.export_evaluation_runs + in client._client._transport._wrapped_methods ) # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[ - client._transport.upload_evaluation_audio + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.export_evaluation_runs ] = mock_rpc request = {} - client.upload_evaluation_audio(request) + await client.export_evaluation_runs(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.upload_evaluation_audio(request) + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + await client.export_evaluation_runs(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_upload_evaluation_audio_rest_required_fields( - request_type=evaluation_service.UploadEvaluationAudioRequest, +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + evaluation_service.ExportEvaluationRunsRequest(), + {}, + ], +) +async def test_export_evaluation_runs_async( + request_type, transport: str = "grpc_asyncio" ): - transport_class = transports.EvaluationServiceRestTransport + client = EvaluationServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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.export_evaluation_runs), "__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.export_evaluation_runs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = evaluation_service.ExportEvaluationRunsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_export_evaluation_runs_field_headers(): + client = EvaluationServiceClient( + 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 = evaluation_service.ExportEvaluationRunsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.export_evaluation_runs), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.export_evaluation_runs(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_export_evaluation_runs_field_headers_async(): + client = EvaluationServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = evaluation_service.ExportEvaluationRunsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.export_evaluation_runs), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.export_evaluation_runs(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_export_evaluation_runs_flattened(): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.export_evaluation_runs), "__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.export_evaluation_runs( + parent="parent_value", + names=["names_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].names + mock_val = ["names_value"] + assert arg == mock_val + + +def test_export_evaluation_runs_flattened_error(): + client = EvaluationServiceClient( + 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.export_evaluation_runs( + evaluation_service.ExportEvaluationRunsRequest(), + parent="parent_value", + names=["names_value"], + ) + + +@pytest.mark.asyncio +async def test_export_evaluation_runs_flattened_async(): + client = EvaluationServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.export_evaluation_runs), "__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.export_evaluation_runs( + parent="parent_value", + names=["names_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].names + mock_val = ["names_value"] + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_export_evaluation_runs_flattened_error_async(): + client = EvaluationServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.export_evaluation_runs( + evaluation_service.ExportEvaluationRunsRequest(), + parent="parent_value", + names=["names_value"], + ) + + +@pytest.mark.parametrize( + "request_type", + [ + evaluation_service.ExportEvaluationResultsRequest(), + {}, + ], +) +def test_export_evaluation_results(request_type, transport: str = "grpc"): + client = EvaluationServiceClient( + 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.export_evaluation_results), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.export_evaluation_results(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = evaluation_service.ExportEvaluationResultsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_export_evaluation_results_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = evaluation_service.ExportEvaluationResultsRequest( + parent="parent_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.export_evaluation_results), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.export_evaluation_results(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = evaluation_service.ExportEvaluationResultsRequest( + parent="parent_value", + ) + assert args[0] == request_msg + + +def test_export_evaluation_results_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.export_evaluation_results + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.export_evaluation_results + ] = mock_rpc + request = {} + client.export_evaluation_results(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.export_evaluation_results(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_export_evaluation_results_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = EvaluationServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.export_evaluation_results + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.export_evaluation_results + ] = mock_rpc + + request = {} + await client.export_evaluation_results(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + await client.export_evaluation_results(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + evaluation_service.ExportEvaluationResultsRequest(), + {}, + ], +) +async def test_export_evaluation_results_async( + request_type, transport: str = "grpc_asyncio" +): + client = EvaluationServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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.export_evaluation_results), "__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.export_evaluation_results(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = evaluation_service.ExportEvaluationResultsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_export_evaluation_results_field_headers(): + client = EvaluationServiceClient( + 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 = evaluation_service.ExportEvaluationResultsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.export_evaluation_results), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.export_evaluation_results(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_export_evaluation_results_field_headers_async(): + client = EvaluationServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = evaluation_service.ExportEvaluationResultsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.export_evaluation_results), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.export_evaluation_results(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_export_evaluation_results_flattened(): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.export_evaluation_results), "__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.export_evaluation_results( + parent="parent_value", + names=["names_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].names + mock_val = ["names_value"] + assert arg == mock_val + + +def test_export_evaluation_results_flattened_error(): + client = EvaluationServiceClient( + 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.export_evaluation_results( + evaluation_service.ExportEvaluationResultsRequest(), + parent="parent_value", + names=["names_value"], + ) + + +@pytest.mark.asyncio +async def test_export_evaluation_results_flattened_async(): + client = EvaluationServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.export_evaluation_results), "__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.export_evaluation_results( + parent="parent_value", + names=["names_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].names + mock_val = ["names_value"] + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_export_evaluation_results_flattened_error_async(): + client = EvaluationServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.export_evaluation_results( + evaluation_service.ExportEvaluationResultsRequest(), + parent="parent_value", + names=["names_value"], + ) + + +@pytest.mark.parametrize( + "request_type", + [ + evaluation_service.RunEvaluationResultMetricsRequest(), + {}, + ], +) +def test_run_evaluation_result_metrics(request_type, transport: str = "grpc"): + client = EvaluationServiceClient( + 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.run_evaluation_result_metrics), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.run_evaluation_result_metrics(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = evaluation_service.RunEvaluationResultMetricsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_run_evaluation_result_metrics_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = evaluation_service.RunEvaluationResultMetricsRequest( + evaluation_result_id="evaluation_result_id_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.run_evaluation_result_metrics), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.run_evaluation_result_metrics(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = evaluation_service.RunEvaluationResultMetricsRequest( + evaluation_result_id="evaluation_result_id_value", + ) + assert args[0] == request_msg + + +def test_run_evaluation_result_metrics_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.run_evaluation_result_metrics + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.run_evaluation_result_metrics + ] = mock_rpc + request = {} + client.run_evaluation_result_metrics(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.run_evaluation_result_metrics(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_run_evaluation_result_metrics_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = EvaluationServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.run_evaluation_result_metrics + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.run_evaluation_result_metrics + ] = mock_rpc + + request = {} + await client.run_evaluation_result_metrics(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + await client.run_evaluation_result_metrics(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + evaluation_service.RunEvaluationResultMetricsRequest(), + {}, + ], +) +async def test_run_evaluation_result_metrics_async( + request_type, transport: str = "grpc_asyncio" +): + client = EvaluationServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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.run_evaluation_result_metrics), "__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.run_evaluation_result_metrics(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = evaluation_service.RunEvaluationResultMetricsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_run_evaluation_result_metrics_field_headers(): + client = EvaluationServiceClient( + 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 = evaluation_service.RunEvaluationResultMetricsRequest() + + request.evaluation_result_id = "evaluation_result_id_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.run_evaluation_result_metrics), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.run_evaluation_result_metrics(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", + "evaluation_result_id=evaluation_result_id_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_run_evaluation_result_metrics_field_headers_async(): + client = EvaluationServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = evaluation_service.RunEvaluationResultMetricsRequest() + + request.evaluation_result_id = "evaluation_result_id_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.run_evaluation_result_metrics), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.run_evaluation_result_metrics(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", + "evaluation_result_id=evaluation_result_id_value", + ) in kw["metadata"] + + +def test_run_evaluation_result_metrics_flattened(): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.run_evaluation_result_metrics), "__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.run_evaluation_result_metrics( + evaluation_result_id="evaluation_result_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].evaluation_result_id + mock_val = "evaluation_result_id_value" + assert arg == mock_val + + +def test_run_evaluation_result_metrics_flattened_error(): + client = EvaluationServiceClient( + 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.run_evaluation_result_metrics( + evaluation_service.RunEvaluationResultMetricsRequest(), + evaluation_result_id="evaluation_result_id_value", + ) + + +@pytest.mark.asyncio +async def test_run_evaluation_result_metrics_flattened_async(): + client = EvaluationServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.run_evaluation_result_metrics), "__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.run_evaluation_result_metrics( + evaluation_result_id="evaluation_result_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].evaluation_result_id + mock_val = "evaluation_result_id_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_run_evaluation_result_metrics_flattened_error_async(): + client = EvaluationServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.run_evaluation_result_metrics( + evaluation_service.RunEvaluationResultMetricsRequest(), + evaluation_result_id="evaluation_result_id_value", + ) + + +def test_run_evaluation_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.run_evaluation in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.run_evaluation] = mock_rpc + + request = {} + client.run_evaluation(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.run_evaluation(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_run_evaluation_rest_required_fields( + request_type=evaluation.RunEvaluationRequest, +): + transport_class = transports.EvaluationServiceRestTransport + + request_init = {} + request_init["app"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).run_evaluation._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["app"] = "app_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).run_evaluation._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "app" in jsonified_request + assert jsonified_request["app"] == "app_value" + + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.run_evaluation(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_run_evaluation_rest_unset_required_fields(): + transport = transports.EvaluationServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.run_evaluation._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("app",))) + + +def test_run_evaluation_rest_flattened(): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = {"app": "projects/sample1/locations/sample2/apps/sample3"} + + # get truthy value for each flattened field + mock_args = dict( + app="app_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.run_evaluation(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1beta/{app=projects/*/locations/*/apps/*}:runEvaluation" + % client.transport._host, + args[1], + ) + + +def test_run_evaluation_rest_flattened_error(transport: str = "rest"): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.run_evaluation( + evaluation.RunEvaluationRequest(), + app="app_value", + ) + + +def test_upload_evaluation_audio_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.upload_evaluation_audio + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.upload_evaluation_audio + ] = mock_rpc + + request = {} + client.upload_evaluation_audio(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.upload_evaluation_audio(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_upload_evaluation_audio_rest_required_fields( + request_type=evaluation_service.UploadEvaluationAudioRequest, +): + transport_class = transports.EvaluationServiceRestTransport + + request_init = {} + request_init["name"] = "" + request_init["audio_content"] = b"" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).upload_evaluation_audio._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + jsonified_request["audioContent"] = b"audio_content_blob" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).upload_evaluation_audio._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + assert "audioContent" in jsonified_request + assert jsonified_request["audioContent"] == b"audio_content_blob" + + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = evaluation_service.UploadEvaluationAudioResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = evaluation_service.UploadEvaluationAudioResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.upload_evaluation_audio(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_upload_evaluation_audio_rest_unset_required_fields(): + transport = transports.EvaluationServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.upload_evaluation_audio._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "name", + "audioContent", + ) + ) + ) + + +def test_upload_evaluation_audio_rest_flattened(): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = evaluation_service.UploadEvaluationAudioResponse() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + audio_content=b"audio_content_blob", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = evaluation_service.UploadEvaluationAudioResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.upload_evaluation_audio(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1beta/{name=projects/*/locations/*/apps/*/evaluations/*}:uploadEvaluationAudio" + % client.transport._host, + args[1], + ) + + +def test_upload_evaluation_audio_rest_flattened_error(transport: str = "rest"): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.upload_evaluation_audio( + evaluation_service.UploadEvaluationAudioRequest(), + name="name_value", + audio_content=b"audio_content_blob", + ) + + +def test_create_evaluation_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.create_evaluation in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.create_evaluation] = ( + mock_rpc + ) + + request = {} + client.create_evaluation(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.create_evaluation(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_create_evaluation_rest_required_fields( + request_type=evaluation_service.CreateEvaluationRequest, +): + transport_class = transports.EvaluationServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_evaluation._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_evaluation._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("evaluation_id",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcc_evaluation.Evaluation() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = gcc_evaluation.Evaluation.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.create_evaluation(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_create_evaluation_rest_unset_required_fields(): + transport = transports.EvaluationServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.create_evaluation._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("evaluationId",)) + & set( + ( + "parent", + "evaluation", + ) + ) + ) + + +def test_create_evaluation_rest_flattened(): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcc_evaluation.Evaluation() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2/apps/sample3"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + evaluation=gcc_evaluation.Evaluation( + golden=gcc_evaluation.Evaluation.Golden( + turns=[ + gcc_evaluation.Evaluation.GoldenTurn( + steps=[ + gcc_evaluation.Evaluation.Step( + user_input=session_service.SessionInput( + text="text_value" + ) + ) + ] + ) + ] + ) + ), + evaluation_id="evaluation_id_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = gcc_evaluation.Evaluation.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.create_evaluation(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1beta/{parent=projects/*/locations/*/apps/*}/evaluations" + % client.transport._host, + args[1], + ) + + +def test_create_evaluation_rest_flattened_error(transport: str = "rest"): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_evaluation( + evaluation_service.CreateEvaluationRequest(), + parent="parent_value", + evaluation=gcc_evaluation.Evaluation( + golden=gcc_evaluation.Evaluation.Golden( + turns=[ + gcc_evaluation.Evaluation.GoldenTurn( + steps=[ + gcc_evaluation.Evaluation.Step( + user_input=session_service.SessionInput( + text="text_value" + ) + ) + ] + ) + ] + ) + ), + evaluation_id="evaluation_id_value", + ) + + +def test_generate_evaluation_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.generate_evaluation in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.generate_evaluation] = ( + mock_rpc + ) + + request = {} + client.generate_evaluation(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.generate_evaluation(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_generate_evaluation_rest_required_fields( + request_type=evaluation_service.GenerateEvaluationRequest, +): + transport_class = transports.EvaluationServiceRestTransport request_init = {} - request_init["name"] = "" - request_init["audio_content"] = b"" + request_init["conversation"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -14539,24 +16034,21 @@ def test_upload_evaluation_audio_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).upload_evaluation_audio._get_unset_required_fields(jsonified_request) + ).generate_evaluation._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["name"] = "name_value" - jsonified_request["audioContent"] = b"audio_content_blob" + jsonified_request["conversation"] = "conversation_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).upload_evaluation_audio._get_unset_required_fields(jsonified_request) + ).generate_evaluation._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" - assert "audioContent" in jsonified_request - assert jsonified_request["audioContent"] == b"audio_content_blob" + assert "conversation" in jsonified_request + assert jsonified_request["conversation"] == "conversation_value" client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -14565,7 +16057,7 @@ def test_upload_evaluation_audio_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = evaluation_service.UploadEvaluationAudioResponse() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -14585,42 +16077,29 @@ def test_upload_evaluation_audio_rest_required_fields( response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = evaluation_service.UploadEvaluationAudioResponse.pb( - return_value - ) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.upload_evaluation_audio(request) + response = client.generate_evaluation(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_upload_evaluation_audio_rest_unset_required_fields(): +def test_generate_evaluation_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.upload_evaluation_audio._get_unset_required_fields({}) - assert set(unset_fields) == ( - set(()) - & set( - ( - "name", - "audioContent", - ) - ) - ) + unset_fields = transport.generate_evaluation._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("conversation",))) -def test_upload_evaluation_audio_rest_flattened(): +def test_generate_evaluation_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -14629,44 +16108,41 @@ def test_upload_evaluation_audio_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation_service.UploadEvaluationAudioResponse() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method sample_request = { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4" + "conversation": "projects/sample1/locations/sample2/apps/sample3/conversations/sample4" } # get truthy value for each flattened field mock_args = dict( - name="name_value", - audio_content=b"audio_content_blob", + conversation="conversation_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = evaluation_service.UploadEvaluationAudioResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.upload_evaluation_audio(**mock_args) + client.generate_evaluation(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1beta/{name=projects/*/locations/*/apps/*/evaluations/*}:uploadEvaluationAudio" + "%s/v1beta/{conversation=projects/*/locations/*/apps/*/conversations/*}:generateEvaluation" % client.transport._host, args[1], ) -def test_upload_evaluation_audio_rest_flattened_error(transport: str = "rest"): +def test_generate_evaluation_rest_flattened_error(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -14675,14 +16151,13 @@ def test_upload_evaluation_audio_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.upload_evaluation_audio( - evaluation_service.UploadEvaluationAudioRequest(), - name="name_value", - audio_content=b"audio_content_blob", + client.generate_evaluation( + evaluation_service.GenerateEvaluationRequest(), + conversation="conversation_value", ) -def test_create_evaluation_rest_use_cached_wrapped_rpc(): +def test_import_evaluations_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -14696,32 +16171,217 @@ def test_create_evaluation_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.create_evaluation in client._transport._wrapped_methods + assert ( + client._transport.import_evaluations in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.import_evaluations] = ( + mock_rpc + ) + + request = {} + client.import_evaluations(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.import_evaluations(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_import_evaluations_rest_required_fields( + request_type=evaluation_service.ImportEvaluationsRequest, +): + transport_class = transports.EvaluationServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).import_evaluations._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).import_evaluations._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.import_evaluations(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_import_evaluations_rest_unset_required_fields(): + transport = transports.EvaluationServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.import_evaluations._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent",))) + + +def test_import_evaluations_rest_flattened(): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2/apps/sample3"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.import_evaluations(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1beta/{parent=projects/*/locations/*/apps/*}:importEvaluations" + % client.transport._host, + args[1], + ) + + +def test_import_evaluations_rest_flattened_error(transport: str = "rest"): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.import_evaluations( + evaluation_service.ImportEvaluationsRequest(), + parent="parent_value", + ) + + +def test_create_evaluation_dataset_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.create_evaluation_dataset + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.create_evaluation] = ( - mock_rpc - ) + client._transport._wrapped_methods[ + client._transport.create_evaluation_dataset + ] = mock_rpc request = {} - client.create_evaluation(request) + client.create_evaluation_dataset(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.create_evaluation(request) + client.create_evaluation_dataset(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_create_evaluation_rest_required_fields( - request_type=evaluation_service.CreateEvaluationRequest, +def test_create_evaluation_dataset_rest_required_fields( + request_type=evaluation_service.CreateEvaluationDatasetRequest, ): transport_class = transports.EvaluationServiceRestTransport @@ -14737,7 +16397,7 @@ def test_create_evaluation_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_evaluation._get_unset_required_fields(jsonified_request) + ).create_evaluation_dataset._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -14746,9 +16406,9 @@ def test_create_evaluation_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_evaluation._get_unset_required_fields(jsonified_request) + ).create_evaluation_dataset._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("evaluation_id",)) + assert not set(unset_fields) - set(("evaluation_dataset_id",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -14762,7 +16422,7 @@ def test_create_evaluation_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = gcc_evaluation.Evaluation() + return_value = evaluation.EvaluationDataset() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -14784,38 +16444,38 @@ def test_create_evaluation_rest_required_fields( response_value.status_code = 200 # Convert return value to protobuf type - return_value = gcc_evaluation.Evaluation.pb(return_value) + return_value = evaluation.EvaluationDataset.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_evaluation(request) + response = client.create_evaluation_dataset(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_create_evaluation_rest_unset_required_fields(): +def test_create_evaluation_dataset_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.create_evaluation._get_unset_required_fields({}) + unset_fields = transport.create_evaluation_dataset._get_unset_required_fields({}) assert set(unset_fields) == ( - set(("evaluationId",)) + set(("evaluationDatasetId",)) & set( ( "parent", - "evaluation", + "evaluationDataset", ) ) ) -def test_create_evaluation_rest_flattened(): +def test_create_evaluation_dataset_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -14824,7 +16484,7 @@ def test_create_evaluation_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = gcc_evaluation.Evaluation() + return_value = evaluation.EvaluationDataset() # get arguments that satisfy an http rule for this method sample_request = {"parent": "projects/sample1/locations/sample2/apps/sample3"} @@ -14832,22 +16492,8 @@ def test_create_evaluation_rest_flattened(): # get truthy value for each flattened field mock_args = dict( parent="parent_value", - evaluation=gcc_evaluation.Evaluation( - golden=gcc_evaluation.Evaluation.Golden( - turns=[ - gcc_evaluation.Evaluation.GoldenTurn( - steps=[ - gcc_evaluation.Evaluation.Step( - user_input=session_service.SessionInput( - text="text_value" - ) - ) - ] - ) - ] - ) - ), - evaluation_id="evaluation_id_value", + evaluation_dataset=evaluation.EvaluationDataset(name="name_value"), + evaluation_dataset_id="evaluation_dataset_id_value", ) mock_args.update(sample_request) @@ -14855,26 +16501,26 @@ def test_create_evaluation_rest_flattened(): response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = gcc_evaluation.Evaluation.pb(return_value) + return_value = evaluation.EvaluationDataset.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_evaluation(**mock_args) + client.create_evaluation_dataset(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1beta/{parent=projects/*/locations/*/apps/*}/evaluations" + "%s/v1beta/{parent=projects/*/locations/*/apps/*}/evaluationDatasets" % client.transport._host, args[1], ) -def test_create_evaluation_rest_flattened_error(transport: str = "rest"): +def test_create_evaluation_dataset_rest_flattened_error(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -14883,29 +16529,15 @@ def test_create_evaluation_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.create_evaluation( - evaluation_service.CreateEvaluationRequest(), + client.create_evaluation_dataset( + evaluation_service.CreateEvaluationDatasetRequest(), parent="parent_value", - evaluation=gcc_evaluation.Evaluation( - golden=gcc_evaluation.Evaluation.Golden( - turns=[ - gcc_evaluation.Evaluation.GoldenTurn( - steps=[ - gcc_evaluation.Evaluation.Step( - user_input=session_service.SessionInput( - text="text_value" - ) - ) - ] - ) - ] - ) - ), - evaluation_id="evaluation_id_value", + evaluation_dataset=evaluation.EvaluationDataset(name="name_value"), + evaluation_dataset_id="evaluation_dataset_id_value", ) -def test_generate_evaluation_rest_use_cached_wrapped_rpc(): +def test_update_evaluation_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -14919,43 +16551,36 @@ def test_generate_evaluation_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert ( - client._transport.generate_evaluation in client._transport._wrapped_methods - ) + assert client._transport.update_evaluation in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.generate_evaluation] = ( + client._transport._wrapped_methods[client._transport.update_evaluation] = ( mock_rpc ) request = {} - client.generate_evaluation(request) + client.update_evaluation(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.generate_evaluation(request) + client.update_evaluation(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_generate_evaluation_rest_required_fields( - request_type=evaluation_service.GenerateEvaluationRequest, +def test_update_evaluation_rest_required_fields( + request_type=evaluation_service.UpdateEvaluationRequest, ): transport_class = transports.EvaluationServiceRestTransport request_init = {} - request_init["conversation"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -14966,21 +16591,19 @@ def test_generate_evaluation_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).generate_evaluation._get_unset_required_fields(jsonified_request) + ).update_evaluation._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["conversation"] = "conversation_value" - unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).generate_evaluation._get_unset_required_fields(jsonified_request) + ).update_evaluation._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "conversation" in jsonified_request - assert jsonified_request["conversation"] == "conversation_value" client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -14989,7 +16612,7 @@ def test_generate_evaluation_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = gcc_evaluation.Evaluation() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -15001,7 +16624,7 @@ def test_generate_evaluation_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "post", + "method": "patch", "query_params": pb_request, } transcode_result["body"] = pb_request @@ -15009,29 +16632,32 @@ def test_generate_evaluation_rest_required_fields( response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = gcc_evaluation.Evaluation.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.generate_evaluation(request) + response = client.update_evaluation(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_generate_evaluation_rest_unset_required_fields(): +def test_update_evaluation_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.generate_evaluation._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("conversation",))) + unset_fields = transport.update_evaluation._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("evaluation",))) -def test_generate_evaluation_rest_flattened(): +def test_update_evaluation_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -15040,41 +16666,60 @@ def test_generate_evaluation_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = gcc_evaluation.Evaluation() # get arguments that satisfy an http rule for this method sample_request = { - "conversation": "projects/sample1/locations/sample2/apps/sample3/conversations/sample4" + "evaluation": { + "name": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4" + } } # get truthy value for each flattened field mock_args = dict( - conversation="conversation_value", + evaluation=gcc_evaluation.Evaluation( + golden=gcc_evaluation.Evaluation.Golden( + turns=[ + gcc_evaluation.Evaluation.GoldenTurn( + steps=[ + gcc_evaluation.Evaluation.Step( + user_input=session_service.SessionInput( + text="text_value" + ) + ) + ] + ) + ] + ) + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = gcc_evaluation.Evaluation.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.generate_evaluation(**mock_args) + client.update_evaluation(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1beta/{conversation=projects/*/locations/*/apps/*/conversations/*}:generateEvaluation" + "%s/v1beta/{evaluation.name=projects/*/locations/*/apps/*/evaluations/*}" % client.transport._host, args[1], ) -def test_generate_evaluation_rest_flattened_error(transport: str = "rest"): +def test_update_evaluation_rest_flattened_error(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -15083,13 +16728,28 @@ def test_generate_evaluation_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.generate_evaluation( - evaluation_service.GenerateEvaluationRequest(), - conversation="conversation_value", + client.update_evaluation( + evaluation_service.UpdateEvaluationRequest(), + evaluation=gcc_evaluation.Evaluation( + golden=gcc_evaluation.Evaluation.Golden( + turns=[ + gcc_evaluation.Evaluation.GoldenTurn( + steps=[ + gcc_evaluation.Evaluation.Step( + user_input=session_service.SessionInput( + text="text_value" + ) + ) + ] + ) + ] + ) + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) -def test_import_evaluations_rest_use_cached_wrapped_rpc(): +def test_update_evaluation_dataset_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -15104,7 +16764,8 @@ def test_import_evaluations_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.import_evaluations in client._transport._wrapped_methods + client._transport.update_evaluation_dataset + in client._transport._wrapped_methods ) # Replace cached wrapped function with mock @@ -15112,34 +16773,29 @@ def test_import_evaluations_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.import_evaluations] = ( - mock_rpc - ) + client._transport._wrapped_methods[ + client._transport.update_evaluation_dataset + ] = mock_rpc request = {} - client.import_evaluations(request) + client.update_evaluation_dataset(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.import_evaluations(request) + client.update_evaluation_dataset(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_import_evaluations_rest_required_fields( - request_type=evaluation_service.ImportEvaluationsRequest, +def test_update_evaluation_dataset_rest_required_fields( + request_type=evaluation_service.UpdateEvaluationDatasetRequest, ): transport_class = transports.EvaluationServiceRestTransport request_init = {} - request_init["parent"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -15150,21 +16806,19 @@ def test_import_evaluations_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).import_evaluations._get_unset_required_fields(jsonified_request) + ).update_evaluation_dataset._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["parent"] = "parent_value" - unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).import_evaluations._get_unset_required_fields(jsonified_request) + ).update_evaluation_dataset._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -15173,7 +16827,7 @@ def test_import_evaluations_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = evaluation.EvaluationDataset() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -15185,7 +16839,7 @@ def test_import_evaluations_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "post", + "method": "patch", "query_params": pb_request, } transcode_result["body"] = pb_request @@ -15193,29 +16847,32 @@ def test_import_evaluations_rest_required_fields( response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = evaluation.EvaluationDataset.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.import_evaluations(request) + response = client.update_evaluation_dataset(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_import_evaluations_rest_unset_required_fields(): +def test_update_evaluation_dataset_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.import_evaluations._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("parent",))) + unset_fields = transport.update_evaluation_dataset._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("evaluationDataset",))) -def test_import_evaluations_rest_flattened(): +def test_update_evaluation_dataset_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -15224,39 +16881,46 @@ def test_import_evaluations_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = evaluation.EvaluationDataset() # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2/apps/sample3"} + sample_request = { + "evaluation_dataset": { + "name": "projects/sample1/locations/sample2/apps/sample3/evaluationDatasets/sample4" + } + } # get truthy value for each flattened field mock_args = dict( - parent="parent_value", + evaluation_dataset=evaluation.EvaluationDataset(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = evaluation.EvaluationDataset.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.import_evaluations(**mock_args) + client.update_evaluation_dataset(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1beta/{parent=projects/*/locations/*/apps/*}:importEvaluations" + "%s/v1beta/{evaluation_dataset.name=projects/*/locations/*/apps/*/evaluationDatasets/*}" % client.transport._host, args[1], ) -def test_import_evaluations_rest_flattened_error(transport: str = "rest"): +def test_update_evaluation_dataset_rest_flattened_error(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -15265,13 +16929,14 @@ def test_import_evaluations_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.import_evaluations( - evaluation_service.ImportEvaluationsRequest(), - parent="parent_value", + client.update_evaluation_dataset( + evaluation_service.UpdateEvaluationDatasetRequest(), + evaluation_dataset=evaluation.EvaluationDataset(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) -def test_create_evaluation_dataset_rest_use_cached_wrapped_rpc(): +def test_delete_evaluation_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -15285,40 +16950,37 @@ def test_create_evaluation_dataset_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert ( - client._transport.create_evaluation_dataset - in client._transport._wrapped_methods - ) + assert client._transport.delete_evaluation in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[ - client._transport.create_evaluation_dataset - ] = mock_rpc + client._transport._wrapped_methods[client._transport.delete_evaluation] = ( + mock_rpc + ) request = {} - client.create_evaluation_dataset(request) + client.delete_evaluation(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.create_evaluation_dataset(request) + client.delete_evaluation(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_create_evaluation_dataset_rest_required_fields( - request_type=evaluation_service.CreateEvaluationDatasetRequest, +def test_delete_evaluation_rest_required_fields( + request_type=evaluation_service.DeleteEvaluationRequest, ): transport_class = transports.EvaluationServiceRestTransport request_init = {} - request_init["parent"] = "" + request_init["name"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -15329,23 +16991,28 @@ def test_create_evaluation_dataset_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_evaluation_dataset._get_unset_required_fields(jsonified_request) + ).delete_evaluation._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["parent"] = "parent_value" + jsonified_request["name"] = "name_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_evaluation_dataset._get_unset_required_fields(jsonified_request) + ).delete_evaluation._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("evaluation_dataset_id",)) + assert not set(unset_fields) - set( + ( + "etag", + "force", + ) + ) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -15354,7 +17021,7 @@ def test_create_evaluation_dataset_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = evaluation.EvaluationDataset() + return_value = None # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -15366,48 +17033,44 @@ def test_create_evaluation_dataset_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "post", + "method": "delete", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = evaluation.EvaluationDataset.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + json_return_value = "" response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_evaluation_dataset(request) + response = client.delete_evaluation(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_create_evaluation_dataset_rest_unset_required_fields(): +def test_delete_evaluation_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.create_evaluation_dataset._get_unset_required_fields({}) + unset_fields = transport.delete_evaluation._get_unset_required_fields({}) assert set(unset_fields) == ( - set(("evaluationDatasetId",)) - & set( + set( ( - "parent", - "evaluationDataset", + "etag", + "force", ) ) + & set(("name",)) ) -def test_create_evaluation_dataset_rest_flattened(): +def test_delete_evaluation_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -15416,43 +17079,41 @@ def test_create_evaluation_dataset_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation.EvaluationDataset() + return_value = None # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2/apps/sample3"} + sample_request = { + "name": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4" + } # get truthy value for each flattened field mock_args = dict( - parent="parent_value", - evaluation_dataset=evaluation.EvaluationDataset(name="name_value"), - evaluation_dataset_id="evaluation_dataset_id_value", + name="name_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = evaluation.EvaluationDataset.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + json_return_value = "" response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_evaluation_dataset(**mock_args) + client.delete_evaluation(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1beta/{parent=projects/*/locations/*/apps/*}/evaluationDatasets" + "%s/v1beta/{name=projects/*/locations/*/apps/*/evaluations/*}" % client.transport._host, args[1], ) -def test_create_evaluation_dataset_rest_flattened_error(transport: str = "rest"): +def test_delete_evaluation_rest_flattened_error(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -15461,15 +17122,13 @@ def test_create_evaluation_dataset_rest_flattened_error(transport: str = "rest") # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.create_evaluation_dataset( - evaluation_service.CreateEvaluationDatasetRequest(), - parent="parent_value", - evaluation_dataset=evaluation.EvaluationDataset(name="name_value"), - evaluation_dataset_id="evaluation_dataset_id_value", + client.delete_evaluation( + evaluation_service.DeleteEvaluationRequest(), + name="name_value", ) -def test_update_evaluation_rest_use_cached_wrapped_rpc(): +def test_delete_evaluation_result_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -15483,36 +17142,40 @@ def test_update_evaluation_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.update_evaluation in client._transport._wrapped_methods + assert ( + client._transport.delete_evaluation_result + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.update_evaluation] = ( - mock_rpc - ) + client._transport._wrapped_methods[ + client._transport.delete_evaluation_result + ] = mock_rpc request = {} - client.update_evaluation(request) + client.delete_evaluation_result(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.update_evaluation(request) + client.delete_evaluation_result(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_update_evaluation_rest_required_fields( - request_type=evaluation_service.UpdateEvaluationRequest, +def test_delete_evaluation_result_rest_required_fields( + request_type=evaluation_service.DeleteEvaluationResultRequest, ): transport_class = transports.EvaluationServiceRestTransport request_init = {} + request_init["name"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -15523,19 +17186,21 @@ def test_update_evaluation_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_evaluation._get_unset_required_fields(jsonified_request) + ).delete_evaluation_result._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present + jsonified_request["name"] = "name_value" + unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_evaluation._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("update_mask",)) + ).delete_evaluation_result._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -15544,7 +17209,7 @@ def test_update_evaluation_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = gcc_evaluation.Evaluation() + return_value = None # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -15556,40 +17221,36 @@ def test_update_evaluation_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "patch", + "method": "delete", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = gcc_evaluation.Evaluation.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + json_return_value = "" response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_evaluation(request) + response = client.delete_evaluation_result(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_update_evaluation_rest_unset_required_fields(): +def test_delete_evaluation_result_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.update_evaluation._get_unset_required_fields({}) - assert set(unset_fields) == (set(("updateMask",)) & set(("evaluation",))) + unset_fields = transport.delete_evaluation_result._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) -def test_update_evaluation_rest_flattened(): +def test_delete_evaluation_result_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -15598,60 +17259,41 @@ def test_update_evaluation_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = gcc_evaluation.Evaluation() + return_value = None # get arguments that satisfy an http rule for this method sample_request = { - "evaluation": { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4" - } + "name": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4/results/sample5" } # get truthy value for each flattened field mock_args = dict( - evaluation=gcc_evaluation.Evaluation( - golden=gcc_evaluation.Evaluation.Golden( - turns=[ - gcc_evaluation.Evaluation.GoldenTurn( - steps=[ - gcc_evaluation.Evaluation.Step( - user_input=session_service.SessionInput( - text="text_value" - ) - ) - ] - ) - ] - ) - ), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + name="name_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = gcc_evaluation.Evaluation.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + json_return_value = "" response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_evaluation(**mock_args) + client.delete_evaluation_result(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1beta/{evaluation.name=projects/*/locations/*/apps/*/evaluations/*}" + "%s/v1beta/{name=projects/*/locations/*/apps/*/evaluations/*/results/*}" % client.transport._host, args[1], ) -def test_update_evaluation_rest_flattened_error(transport: str = "rest"): +def test_delete_evaluation_result_rest_flattened_error(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -15660,28 +17302,13 @@ def test_update_evaluation_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.update_evaluation( - evaluation_service.UpdateEvaluationRequest(), - evaluation=gcc_evaluation.Evaluation( - golden=gcc_evaluation.Evaluation.Golden( - turns=[ - gcc_evaluation.Evaluation.GoldenTurn( - steps=[ - gcc_evaluation.Evaluation.Step( - user_input=session_service.SessionInput( - text="text_value" - ) - ) - ] - ) - ] - ) - ), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + client.delete_evaluation_result( + evaluation_service.DeleteEvaluationResultRequest(), + name="name_value", ) -def test_update_evaluation_dataset_rest_use_cached_wrapped_rpc(): +def test_delete_evaluation_dataset_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -15696,7 +17323,7 @@ def test_update_evaluation_dataset_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.update_evaluation_dataset + client._transport.delete_evaluation_dataset in client._transport._wrapped_methods ) @@ -15706,28 +17333,29 @@ def test_update_evaluation_dataset_rest_use_cached_wrapped_rpc(): "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ - client._transport.update_evaluation_dataset + client._transport.delete_evaluation_dataset ] = mock_rpc request = {} - client.update_evaluation_dataset(request) + client.delete_evaluation_dataset(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.update_evaluation_dataset(request) + client.delete_evaluation_dataset(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_update_evaluation_dataset_rest_required_fields( - request_type=evaluation_service.UpdateEvaluationDatasetRequest, +def test_delete_evaluation_dataset_rest_required_fields( + request_type=evaluation_service.DeleteEvaluationDatasetRequest, ): transport_class = transports.EvaluationServiceRestTransport request_init = {} + request_init["name"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -15738,19 +17366,23 @@ def test_update_evaluation_dataset_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_evaluation_dataset._get_unset_required_fields(jsonified_request) + ).delete_evaluation_dataset._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present + jsonified_request["name"] = "name_value" + unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_evaluation_dataset._get_unset_required_fields(jsonified_request) + ).delete_evaluation_dataset._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("update_mask",)) + assert not set(unset_fields) - set(("etag",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -15759,7 +17391,7 @@ def test_update_evaluation_dataset_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = evaluation.EvaluationDataset() + return_value = None # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -15771,40 +17403,36 @@ def test_update_evaluation_dataset_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "patch", + "method": "delete", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = evaluation.EvaluationDataset.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + json_return_value = "" response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_evaluation_dataset(request) + response = client.delete_evaluation_dataset(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_update_evaluation_dataset_rest_unset_required_fields(): +def test_delete_evaluation_dataset_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.update_evaluation_dataset._get_unset_required_fields({}) - assert set(unset_fields) == (set(("updateMask",)) & set(("evaluationDataset",))) + unset_fields = transport.delete_evaluation_dataset._get_unset_required_fields({}) + assert set(unset_fields) == (set(("etag",)) & set(("name",))) -def test_update_evaluation_dataset_rest_flattened(): +def test_delete_evaluation_dataset_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -15813,46 +17441,41 @@ def test_update_evaluation_dataset_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation.EvaluationDataset() + return_value = None # get arguments that satisfy an http rule for this method sample_request = { - "evaluation_dataset": { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluationDatasets/sample4" - } + "name": "projects/sample1/locations/sample2/apps/sample3/evaluationDatasets/sample4" } # get truthy value for each flattened field mock_args = dict( - evaluation_dataset=evaluation.EvaluationDataset(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + name="name_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = evaluation.EvaluationDataset.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + json_return_value = "" response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_evaluation_dataset(**mock_args) + client.delete_evaluation_dataset(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1beta/{evaluation_dataset.name=projects/*/locations/*/apps/*/evaluationDatasets/*}" + "%s/v1beta/{name=projects/*/locations/*/apps/*/evaluationDatasets/*}" % client.transport._host, args[1], ) -def test_update_evaluation_dataset_rest_flattened_error(transport: str = "rest"): +def test_delete_evaluation_dataset_rest_flattened_error(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -15861,14 +17484,13 @@ def test_update_evaluation_dataset_rest_flattened_error(transport: str = "rest") # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.update_evaluation_dataset( - evaluation_service.UpdateEvaluationDatasetRequest(), - evaluation_dataset=evaluation.EvaluationDataset(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + client.delete_evaluation_dataset( + evaluation_service.DeleteEvaluationDatasetRequest(), + name="name_value", ) -def test_delete_evaluation_rest_use_cached_wrapped_rpc(): +def test_delete_evaluation_run_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -15882,32 +17504,39 @@ def test_delete_evaluation_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.delete_evaluation in client._transport._wrapped_methods + assert ( + client._transport.delete_evaluation_run + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.delete_evaluation] = ( + client._transport._wrapped_methods[client._transport.delete_evaluation_run] = ( mock_rpc ) request = {} - client.delete_evaluation(request) + client.delete_evaluation_run(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.delete_evaluation(request) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_evaluation_run(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_delete_evaluation_rest_required_fields( - request_type=evaluation_service.DeleteEvaluationRequest, +def test_delete_evaluation_run_rest_required_fields( + request_type=evaluation_service.DeleteEvaluationRunRequest, ): transport_class = transports.EvaluationServiceRestTransport @@ -15923,7 +17552,7 @@ def test_delete_evaluation_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_evaluation._get_unset_required_fields(jsonified_request) + ).delete_evaluation_run._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -15932,14 +17561,7 @@ def test_delete_evaluation_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_evaluation._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "etag", - "force", - ) - ) + ).delete_evaluation_run._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -15953,7 +17575,7 @@ def test_delete_evaluation_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = None + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -15972,37 +17594,29 @@ def test_delete_evaluation_rest_required_fields( response_value = Response() response_value.status_code = 200 - json_return_value = "" + json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_evaluation(request) + response = client.delete_evaluation_run(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_delete_evaluation_rest_unset_required_fields(): +def test_delete_evaluation_run_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.delete_evaluation._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "etag", - "force", - ) - ) - & set(("name",)) - ) + unset_fields = transport.delete_evaluation_run._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) -def test_delete_evaluation_rest_flattened(): +def test_delete_evaluation_run_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -16011,11 +17625,11 @@ def test_delete_evaluation_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = None + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method sample_request = { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4" + "name": "projects/sample1/locations/sample2/apps/sample3/evaluationRuns/sample4" } # get truthy value for each flattened field @@ -16027,25 +17641,25 @@ def test_delete_evaluation_rest_flattened(): # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - json_return_value = "" + json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_evaluation(**mock_args) + client.delete_evaluation_run(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1beta/{name=projects/*/locations/*/apps/*/evaluations/*}" + "%s/v1beta/{name=projects/*/locations/*/apps/*/evaluationRuns/*}" % client.transport._host, args[1], ) -def test_delete_evaluation_rest_flattened_error(transport: str = "rest"): +def test_delete_evaluation_run_rest_flattened_error(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -16054,13 +17668,13 @@ def test_delete_evaluation_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.delete_evaluation( - evaluation_service.DeleteEvaluationRequest(), + client.delete_evaluation_run( + evaluation_service.DeleteEvaluationRunRequest(), name="name_value", ) -def test_delete_evaluation_result_rest_use_cached_wrapped_rpc(): +def test_get_evaluation_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -16074,35 +17688,30 @@ def test_delete_evaluation_result_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert ( - client._transport.delete_evaluation_result - in client._transport._wrapped_methods - ) + assert client._transport.get_evaluation in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[ - client._transport.delete_evaluation_result - ] = mock_rpc + client._transport._wrapped_methods[client._transport.get_evaluation] = mock_rpc request = {} - client.delete_evaluation_result(request) + client.get_evaluation(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.delete_evaluation_result(request) + client.get_evaluation(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_delete_evaluation_result_rest_required_fields( - request_type=evaluation_service.DeleteEvaluationResultRequest, +def test_get_evaluation_rest_required_fields( + request_type=evaluation_service.GetEvaluationRequest, ): transport_class = transports.EvaluationServiceRestTransport @@ -16118,7 +17727,7 @@ def test_delete_evaluation_result_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_evaluation_result._get_unset_required_fields(jsonified_request) + ).get_evaluation._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -16127,7 +17736,7 @@ def test_delete_evaluation_result_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_evaluation_result._get_unset_required_fields(jsonified_request) + ).get_evaluation._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -16141,7 +17750,7 @@ def test_delete_evaluation_result_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = None + return_value = evaluation.Evaluation() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -16153,36 +17762,39 @@ def test_delete_evaluation_result_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "delete", + "method": "get", "query_params": pb_request, } transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - json_return_value = "" + + # Convert return value to protobuf type + return_value = evaluation.Evaluation.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_evaluation_result(request) + response = client.get_evaluation(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_delete_evaluation_result_rest_unset_required_fields(): +def test_get_evaluation_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.delete_evaluation_result._get_unset_required_fields({}) + unset_fields = transport.get_evaluation._get_unset_required_fields({}) assert set(unset_fields) == (set(()) & set(("name",))) -def test_delete_evaluation_result_rest_flattened(): +def test_get_evaluation_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -16191,11 +17803,11 @@ def test_delete_evaluation_result_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = None + return_value = evaluation.Evaluation() # get arguments that satisfy an http rule for this method sample_request = { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4/results/sample5" + "name": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4" } # get truthy value for each flattened field @@ -16207,25 +17819,27 @@ def test_delete_evaluation_result_rest_flattened(): # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - json_return_value = "" + # Convert return value to protobuf type + return_value = evaluation.Evaluation.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_evaluation_result(**mock_args) + client.get_evaluation(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1beta/{name=projects/*/locations/*/apps/*/evaluations/*/results/*}" + "%s/v1beta/{name=projects/*/locations/*/apps/*/evaluations/*}" % client.transport._host, args[1], ) -def test_delete_evaluation_result_rest_flattened_error(transport: str = "rest"): +def test_get_evaluation_rest_flattened_error(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -16234,13 +17848,13 @@ def test_delete_evaluation_result_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.delete_evaluation_result( - evaluation_service.DeleteEvaluationResultRequest(), + client.get_evaluation( + evaluation_service.GetEvaluationRequest(), name="name_value", ) -def test_delete_evaluation_dataset_rest_use_cached_wrapped_rpc(): +def test_get_evaluation_result_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -16255,7 +17869,7 @@ def test_delete_evaluation_dataset_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.delete_evaluation_dataset + client._transport.get_evaluation_result in client._transport._wrapped_methods ) @@ -16264,25 +17878,25 @@ def test_delete_evaluation_dataset_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[ - client._transport.delete_evaluation_dataset - ] = mock_rpc + client._transport._wrapped_methods[client._transport.get_evaluation_result] = ( + mock_rpc + ) request = {} - client.delete_evaluation_dataset(request) + client.get_evaluation_result(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.delete_evaluation_dataset(request) + client.get_evaluation_result(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_delete_evaluation_dataset_rest_required_fields( - request_type=evaluation_service.DeleteEvaluationDatasetRequest, +def test_get_evaluation_result_rest_required_fields( + request_type=evaluation_service.GetEvaluationResultRequest, ): transport_class = transports.EvaluationServiceRestTransport @@ -16298,7 +17912,7 @@ def test_delete_evaluation_dataset_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_evaluation_dataset._get_unset_required_fields(jsonified_request) + ).get_evaluation_result._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -16307,9 +17921,7 @@ def test_delete_evaluation_dataset_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_evaluation_dataset._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("etag",)) + ).get_evaluation_result._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -16323,7 +17935,7 @@ def test_delete_evaluation_dataset_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = None + return_value = evaluation.EvaluationResult() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -16335,36 +17947,39 @@ def test_delete_evaluation_dataset_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "delete", + "method": "get", "query_params": pb_request, } transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - json_return_value = "" + + # Convert return value to protobuf type + return_value = evaluation.EvaluationResult.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_evaluation_dataset(request) + response = client.get_evaluation_result(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_delete_evaluation_dataset_rest_unset_required_fields(): +def test_get_evaluation_result_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.delete_evaluation_dataset._get_unset_required_fields({}) - assert set(unset_fields) == (set(("etag",)) & set(("name",))) + unset_fields = transport.get_evaluation_result._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) -def test_delete_evaluation_dataset_rest_flattened(): +def test_get_evaluation_result_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -16373,11 +17988,11 @@ def test_delete_evaluation_dataset_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = None + return_value = evaluation.EvaluationResult() # get arguments that satisfy an http rule for this method sample_request = { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluationDatasets/sample4" + "name": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4/results/sample5" } # get truthy value for each flattened field @@ -16389,25 +18004,27 @@ def test_delete_evaluation_dataset_rest_flattened(): # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - json_return_value = "" + # Convert return value to protobuf type + return_value = evaluation.EvaluationResult.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_evaluation_dataset(**mock_args) + client.get_evaluation_result(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1beta/{name=projects/*/locations/*/apps/*/evaluationDatasets/*}" + "%s/v1beta/{name=projects/*/locations/*/apps/*/evaluations/*/results/*}" % client.transport._host, args[1], ) -def test_delete_evaluation_dataset_rest_flattened_error(transport: str = "rest"): +def test_get_evaluation_result_rest_flattened_error(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -16416,13 +18033,13 @@ def test_delete_evaluation_dataset_rest_flattened_error(transport: str = "rest") # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.delete_evaluation_dataset( - evaluation_service.DeleteEvaluationDatasetRequest(), + client.get_evaluation_result( + evaluation_service.GetEvaluationResultRequest(), name="name_value", ) -def test_delete_evaluation_run_rest_use_cached_wrapped_rpc(): +def test_get_evaluation_dataset_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -16437,7 +18054,7 @@ def test_delete_evaluation_run_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.delete_evaluation_run + client._transport.get_evaluation_dataset in client._transport._wrapped_methods ) @@ -16446,29 +18063,25 @@ def test_delete_evaluation_run_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.delete_evaluation_run] = ( + client._transport._wrapped_methods[client._transport.get_evaluation_dataset] = ( mock_rpc ) request = {} - client.delete_evaluation_run(request) + client.get_evaluation_dataset(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.delete_evaluation_run(request) + client.get_evaluation_dataset(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_delete_evaluation_run_rest_required_fields( - request_type=evaluation_service.DeleteEvaluationRunRequest, +def test_get_evaluation_dataset_rest_required_fields( + request_type=evaluation_service.GetEvaluationDatasetRequest, ): transport_class = transports.EvaluationServiceRestTransport @@ -16484,7 +18097,7 @@ def test_delete_evaluation_run_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_evaluation_run._get_unset_required_fields(jsonified_request) + ).get_evaluation_dataset._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -16493,7 +18106,7 @@ def test_delete_evaluation_run_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_evaluation_run._get_unset_required_fields(jsonified_request) + ).get_evaluation_dataset._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -16507,7 +18120,7 @@ def test_delete_evaluation_run_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = evaluation.EvaluationDataset() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -16519,36 +18132,39 @@ def test_delete_evaluation_run_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "delete", + "method": "get", "query_params": pb_request, } transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = evaluation.EvaluationDataset.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_evaluation_run(request) + response = client.get_evaluation_dataset(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_delete_evaluation_run_rest_unset_required_fields(): +def test_get_evaluation_dataset_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.delete_evaluation_run._get_unset_required_fields({}) + unset_fields = transport.get_evaluation_dataset._get_unset_required_fields({}) assert set(unset_fields) == (set(()) & set(("name",))) -def test_delete_evaluation_run_rest_flattened(): +def test_get_evaluation_dataset_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -16557,11 +18173,11 @@ def test_delete_evaluation_run_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = evaluation.EvaluationDataset() # get arguments that satisfy an http rule for this method sample_request = { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluationRuns/sample4" + "name": "projects/sample1/locations/sample2/apps/sample3/evaluationDatasets/sample4" } # get truthy value for each flattened field @@ -16573,25 +18189,27 @@ def test_delete_evaluation_run_rest_flattened(): # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = evaluation.EvaluationDataset.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_evaluation_run(**mock_args) + client.get_evaluation_dataset(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1beta/{name=projects/*/locations/*/apps/*/evaluationRuns/*}" + "%s/v1beta/{name=projects/*/locations/*/apps/*/evaluationDatasets/*}" % client.transport._host, args[1], ) -def test_delete_evaluation_run_rest_flattened_error(transport: str = "rest"): +def test_get_evaluation_dataset_rest_flattened_error(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -16600,13 +18218,13 @@ def test_delete_evaluation_run_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.delete_evaluation_run( - evaluation_service.DeleteEvaluationRunRequest(), + client.get_evaluation_dataset( + evaluation_service.GetEvaluationDatasetRequest(), name="name_value", ) -def test_get_evaluation_rest_use_cached_wrapped_rpc(): +def test_get_evaluation_run_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -16620,30 +18238,34 @@ def test_get_evaluation_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.get_evaluation in client._transport._wrapped_methods + assert ( + client._transport.get_evaluation_run in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.get_evaluation] = mock_rpc + client._transport._wrapped_methods[client._transport.get_evaluation_run] = ( + mock_rpc + ) request = {} - client.get_evaluation(request) + client.get_evaluation_run(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.get_evaluation(request) + client.get_evaluation_run(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_get_evaluation_rest_required_fields( - request_type=evaluation_service.GetEvaluationRequest, +def test_get_evaluation_run_rest_required_fields( + request_type=evaluation_service.GetEvaluationRunRequest, ): transport_class = transports.EvaluationServiceRestTransport @@ -16659,7 +18281,7 @@ def test_get_evaluation_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_evaluation._get_unset_required_fields(jsonified_request) + ).get_evaluation_run._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -16668,7 +18290,7 @@ def test_get_evaluation_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_evaluation._get_unset_required_fields(jsonified_request) + ).get_evaluation_run._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -16682,7 +18304,7 @@ def test_get_evaluation_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = evaluation.Evaluation() + return_value = evaluation.EvaluationRun() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -16703,30 +18325,30 @@ def test_get_evaluation_rest_required_fields( response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation.Evaluation.pb(return_value) + return_value = evaluation.EvaluationRun.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_evaluation(request) + response = client.get_evaluation_run(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_get_evaluation_rest_unset_required_fields(): +def test_get_evaluation_run_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.get_evaluation._get_unset_required_fields({}) + unset_fields = transport.get_evaluation_run._get_unset_required_fields({}) assert set(unset_fields) == (set(()) & set(("name",))) -def test_get_evaluation_rest_flattened(): +def test_get_evaluation_run_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -16735,11 +18357,11 @@ def test_get_evaluation_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation.Evaluation() + return_value = evaluation.EvaluationRun() # get arguments that satisfy an http rule for this method sample_request = { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4" + "name": "projects/sample1/locations/sample2/apps/sample3/evaluationRuns/sample4" } # get truthy value for each flattened field @@ -16752,26 +18374,26 @@ def test_get_evaluation_rest_flattened(): response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation.Evaluation.pb(return_value) + return_value = evaluation.EvaluationRun.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_evaluation(**mock_args) + client.get_evaluation_run(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1beta/{name=projects/*/locations/*/apps/*/evaluations/*}" + "%s/v1beta/{name=projects/*/locations/*/apps/*/evaluationRuns/*}" % client.transport._host, args[1], ) -def test_get_evaluation_rest_flattened_error(transport: str = "rest"): +def test_get_evaluation_run_rest_flattened_error(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -16780,13 +18402,13 @@ def test_get_evaluation_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.get_evaluation( - evaluation_service.GetEvaluationRequest(), + client.get_evaluation_run( + evaluation_service.GetEvaluationRunRequest(), name="name_value", ) -def test_get_evaluation_result_rest_use_cached_wrapped_rpc(): +def test_list_evaluations_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -16800,40 +18422,37 @@ def test_get_evaluation_result_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert ( - client._transport.get_evaluation_result - in client._transport._wrapped_methods - ) + assert client._transport.list_evaluations in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.get_evaluation_result] = ( + client._transport._wrapped_methods[client._transport.list_evaluations] = ( mock_rpc ) request = {} - client.get_evaluation_result(request) + client.list_evaluations(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.get_evaluation_result(request) + client.list_evaluations(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_get_evaluation_result_rest_required_fields( - request_type=evaluation_service.GetEvaluationResultRequest, +def test_list_evaluations_rest_required_fields( + request_type=evaluation_service.ListEvaluationsRequest, ): transport_class = transports.EvaluationServiceRestTransport request_init = {} - request_init["name"] = "" + request_init["parent"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -16844,21 +18463,33 @@ def test_get_evaluation_result_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_evaluation_result._get_unset_required_fields(jsonified_request) + ).list_evaluations._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["name"] = "name_value" + jsonified_request["parent"] = "parent_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_evaluation_result._get_unset_required_fields(jsonified_request) + ).list_evaluations._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "evaluation_filter", + "evaluation_run_filter", + "filter", + "last_ten_results", + "order_by", + "page_size", + "page_token", + ) + ) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -16867,7 +18498,7 @@ def test_get_evaluation_result_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = evaluation.EvaluationResult() + return_value = evaluation_service.ListEvaluationsResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -16888,30 +18519,43 @@ def test_get_evaluation_result_rest_required_fields( response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation.EvaluationResult.pb(return_value) + return_value = evaluation_service.ListEvaluationsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_evaluation_result(request) + response = client.list_evaluations(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_get_evaluation_result_rest_unset_required_fields(): +def test_list_evaluations_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.get_evaluation_result._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + unset_fields = transport.list_evaluations._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "evaluationFilter", + "evaluationRunFilter", + "filter", + "lastTenResults", + "orderBy", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) -def test_get_evaluation_result_rest_flattened(): +def test_list_evaluations_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -16920,16 +18564,14 @@ def test_get_evaluation_result_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation.EvaluationResult() + return_value = evaluation_service.ListEvaluationsResponse() # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4/results/sample5" - } + sample_request = {"parent": "projects/sample1/locations/sample2/apps/sample3"} # get truthy value for each flattened field mock_args = dict( - name="name_value", + parent="parent_value", ) mock_args.update(sample_request) @@ -16937,26 +18579,26 @@ def test_get_evaluation_result_rest_flattened(): response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation.EvaluationResult.pb(return_value) + return_value = evaluation_service.ListEvaluationsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_evaluation_result(**mock_args) + client.list_evaluations(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1beta/{name=projects/*/locations/*/apps/*/evaluations/*/results/*}" + "%s/v1beta/{parent=projects/*/locations/*/apps/*}/evaluations" % client.transport._host, args[1], ) -def test_get_evaluation_result_rest_flattened_error(transport: str = "rest"): +def test_list_evaluations_rest_flattened_error(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -16965,13 +18607,76 @@ def test_get_evaluation_result_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.get_evaluation_result( - evaluation_service.GetEvaluationResultRequest(), - name="name_value", + client.list_evaluations( + evaluation_service.ListEvaluationsRequest(), + parent="parent_value", ) -def test_get_evaluation_dataset_rest_use_cached_wrapped_rpc(): +def test_list_evaluations_rest_pager(transport: str = "rest"): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + evaluation_service.ListEvaluationsResponse( + evaluations=[ + evaluation.Evaluation(), + evaluation.Evaluation(), + evaluation.Evaluation(), + ], + next_page_token="abc", + ), + evaluation_service.ListEvaluationsResponse( + evaluations=[], + next_page_token="def", + ), + evaluation_service.ListEvaluationsResponse( + evaluations=[ + evaluation.Evaluation(), + ], + next_page_token="ghi", + ), + evaluation_service.ListEvaluationsResponse( + evaluations=[ + evaluation.Evaluation(), + evaluation.Evaluation(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + evaluation_service.ListEvaluationsResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2/apps/sample3"} + + pager = client.list_evaluations(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, evaluation.Evaluation) for i in results) + + pages = list(client.list_evaluations(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_list_evaluation_results_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -16986,7 +18691,7 @@ def test_get_evaluation_dataset_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.get_evaluation_dataset + client._transport.list_evaluation_results in client._transport._wrapped_methods ) @@ -16995,30 +18700,30 @@ def test_get_evaluation_dataset_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.get_evaluation_dataset] = ( - mock_rpc - ) + client._transport._wrapped_methods[ + client._transport.list_evaluation_results + ] = mock_rpc request = {} - client.get_evaluation_dataset(request) + client.list_evaluation_results(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.get_evaluation_dataset(request) + client.list_evaluation_results(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_get_evaluation_dataset_rest_required_fields( - request_type=evaluation_service.GetEvaluationDatasetRequest, +def test_list_evaluation_results_rest_required_fields( + request_type=evaluation_service.ListEvaluationResultsRequest, ): transport_class = transports.EvaluationServiceRestTransport request_init = {} - request_init["name"] = "" + request_init["parent"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -17029,21 +18734,30 @@ def test_get_evaluation_dataset_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_evaluation_dataset._get_unset_required_fields(jsonified_request) + ).list_evaluation_results._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["name"] = "name_value" + jsonified_request["parent"] = "parent_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_evaluation_dataset._get_unset_required_fields(jsonified_request) + ).list_evaluation_results._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + ) + ) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -17052,7 +18766,7 @@ def test_get_evaluation_dataset_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = evaluation.EvaluationDataset() + return_value = evaluation_service.ListEvaluationResultsResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -17073,30 +18787,42 @@ def test_get_evaluation_dataset_rest_required_fields( response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation.EvaluationDataset.pb(return_value) + return_value = evaluation_service.ListEvaluationResultsResponse.pb( + return_value + ) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_evaluation_dataset(request) + response = client.list_evaluation_results(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_get_evaluation_dataset_rest_unset_required_fields(): +def test_list_evaluation_results_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.get_evaluation_dataset._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + unset_fields = transport.list_evaluation_results._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) -def test_get_evaluation_dataset_rest_flattened(): +def test_list_evaluation_results_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -17105,16 +18831,16 @@ def test_get_evaluation_dataset_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation.EvaluationDataset() + return_value = evaluation_service.ListEvaluationResultsResponse() # get arguments that satisfy an http rule for this method sample_request = { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluationDatasets/sample4" + "parent": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4" } # get truthy value for each flattened field mock_args = dict( - name="name_value", + parent="parent_value", ) mock_args.update(sample_request) @@ -17122,26 +18848,26 @@ def test_get_evaluation_dataset_rest_flattened(): response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation.EvaluationDataset.pb(return_value) + return_value = evaluation_service.ListEvaluationResultsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_evaluation_dataset(**mock_args) + client.list_evaluation_results(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1beta/{name=projects/*/locations/*/apps/*/evaluationDatasets/*}" + "%s/v1beta/{parent=projects/*/locations/*/apps/*/evaluations/*}/results" % client.transport._host, args[1], ) -def test_get_evaluation_dataset_rest_flattened_error(transport: str = "rest"): +def test_list_evaluation_results_rest_flattened_error(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -17150,13 +18876,79 @@ def test_get_evaluation_dataset_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.get_evaluation_dataset( - evaluation_service.GetEvaluationDatasetRequest(), - name="name_value", + client.list_evaluation_results( + evaluation_service.ListEvaluationResultsRequest(), + parent="parent_value", ) -def test_get_evaluation_run_rest_use_cached_wrapped_rpc(): +def test_list_evaluation_results_rest_pager(transport: str = "rest"): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + evaluation_service.ListEvaluationResultsResponse( + evaluation_results=[ + evaluation.EvaluationResult(), + evaluation.EvaluationResult(), + evaluation.EvaluationResult(), + ], + next_page_token="abc", + ), + evaluation_service.ListEvaluationResultsResponse( + evaluation_results=[], + next_page_token="def", + ), + evaluation_service.ListEvaluationResultsResponse( + evaluation_results=[ + evaluation.EvaluationResult(), + ], + next_page_token="ghi", + ), + evaluation_service.ListEvaluationResultsResponse( + evaluation_results=[ + evaluation.EvaluationResult(), + evaluation.EvaluationResult(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + evaluation_service.ListEvaluationResultsResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = { + "parent": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4" + } + + pager = client.list_evaluation_results(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, evaluation.EvaluationResult) for i in results) + + pages = list(client.list_evaluation_results(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_list_evaluation_datasets_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -17171,7 +18963,8 @@ def test_get_evaluation_run_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.get_evaluation_run in client._transport._wrapped_methods + client._transport.list_evaluation_datasets + in client._transport._wrapped_methods ) # Replace cached wrapped function with mock @@ -17179,30 +18972,30 @@ def test_get_evaluation_run_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.get_evaluation_run] = ( - mock_rpc - ) + client._transport._wrapped_methods[ + client._transport.list_evaluation_datasets + ] = mock_rpc request = {} - client.get_evaluation_run(request) + client.list_evaluation_datasets(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.get_evaluation_run(request) + client.list_evaluation_datasets(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_get_evaluation_run_rest_required_fields( - request_type=evaluation_service.GetEvaluationRunRequest, +def test_list_evaluation_datasets_rest_required_fields( + request_type=evaluation_service.ListEvaluationDatasetsRequest, ): transport_class = transports.EvaluationServiceRestTransport request_init = {} - request_init["name"] = "" + request_init["parent"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -17213,21 +19006,30 @@ def test_get_evaluation_run_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_evaluation_run._get_unset_required_fields(jsonified_request) + ).list_evaluation_datasets._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["name"] = "name_value" + jsonified_request["parent"] = "parent_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_evaluation_run._get_unset_required_fields(jsonified_request) + ).list_evaluation_datasets._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + ) + ) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -17236,7 +19038,7 @@ def test_get_evaluation_run_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = evaluation.EvaluationRun() + return_value = evaluation_service.ListEvaluationDatasetsResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -17257,30 +19059,42 @@ def test_get_evaluation_run_rest_required_fields( response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation.EvaluationRun.pb(return_value) + return_value = evaluation_service.ListEvaluationDatasetsResponse.pb( + return_value + ) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_evaluation_run(request) + response = client.list_evaluation_datasets(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_get_evaluation_run_rest_unset_required_fields(): +def test_list_evaluation_datasets_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.get_evaluation_run._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + unset_fields = transport.list_evaluation_datasets._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) -def test_get_evaluation_run_rest_flattened(): +def test_list_evaluation_datasets_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -17289,16 +19103,14 @@ def test_get_evaluation_run_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation.EvaluationRun() + return_value = evaluation_service.ListEvaluationDatasetsResponse() # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluationRuns/sample4" - } + sample_request = {"parent": "projects/sample1/locations/sample2/apps/sample3"} # get truthy value for each flattened field mock_args = dict( - name="name_value", + parent="parent_value", ) mock_args.update(sample_request) @@ -17306,41 +19118,107 @@ def test_get_evaluation_run_rest_flattened(): response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation.EvaluationRun.pb(return_value) + return_value = evaluation_service.ListEvaluationDatasetsResponse.pb( + return_value + ) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_evaluation_run(**mock_args) + client.list_evaluation_datasets(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1beta/{parent=projects/*/locations/*/apps/*}/evaluationDatasets" + % client.transport._host, + args[1], + ) + + +def test_list_evaluation_datasets_rest_flattened_error(transport: str = "rest"): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_evaluation_datasets( + evaluation_service.ListEvaluationDatasetsRequest(), + parent="parent_value", + ) + + +def test_list_evaluation_datasets_rest_pager(transport: str = "rest"): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + evaluation_service.ListEvaluationDatasetsResponse( + evaluation_datasets=[ + evaluation.EvaluationDataset(), + evaluation.EvaluationDataset(), + evaluation.EvaluationDataset(), + ], + next_page_token="abc", + ), + evaluation_service.ListEvaluationDatasetsResponse( + evaluation_datasets=[], + next_page_token="def", + ), + evaluation_service.ListEvaluationDatasetsResponse( + evaluation_datasets=[ + evaluation.EvaluationDataset(), + ], + next_page_token="ghi", + ), + evaluation_service.ListEvaluationDatasetsResponse( + evaluation_datasets=[ + evaluation.EvaluationDataset(), + evaluation.EvaluationDataset(), + ], + ), + ) + # Two responses for two calls + response = response + response - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1beta/{name=projects/*/locations/*/apps/*/evaluationRuns/*}" - % client.transport._host, - args[1], + # Wrap the values into proper Response objs + response = tuple( + evaluation_service.ListEvaluationDatasetsResponse.to_json(x) + for x in response ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + sample_request = {"parent": "projects/sample1/locations/sample2/apps/sample3"} -def test_get_evaluation_run_rest_flattened_error(transport: str = "rest"): - client = EvaluationServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) + pager = client.list_evaluation_datasets(request=sample_request) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.get_evaluation_run( - evaluation_service.GetEvaluationRunRequest(), - name="name_value", - ) + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, evaluation.EvaluationDataset) for i in results) + + pages = list(client.list_evaluation_datasets(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token -def test_list_evaluations_rest_use_cached_wrapped_rpc(): +def test_list_evaluation_runs_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -17354,32 +19232,34 @@ def test_list_evaluations_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.list_evaluations in client._transport._wrapped_methods + assert ( + client._transport.list_evaluation_runs in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.list_evaluations] = ( + client._transport._wrapped_methods[client._transport.list_evaluation_runs] = ( mock_rpc ) request = {} - client.list_evaluations(request) + client.list_evaluation_runs(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_evaluations(request) + client.list_evaluation_runs(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_evaluations_rest_required_fields( - request_type=evaluation_service.ListEvaluationsRequest, +def test_list_evaluation_runs_rest_required_fields( + request_type=evaluation_service.ListEvaluationRunsRequest, ): transport_class = transports.EvaluationServiceRestTransport @@ -17395,7 +19275,7 @@ def test_list_evaluations_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_evaluations._get_unset_required_fields(jsonified_request) + ).list_evaluation_runs._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -17404,14 +19284,11 @@ def test_list_evaluations_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_evaluations._get_unset_required_fields(jsonified_request) + ).list_evaluation_runs._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. assert not set(unset_fields) - set( ( - "evaluation_filter", - "evaluation_run_filter", "filter", - "last_ten_results", "order_by", "page_size", "page_token", @@ -17430,7 +19307,7 @@ def test_list_evaluations_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = evaluation_service.ListEvaluationsResponse() + return_value = evaluation_service.ListEvaluationRunsResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -17451,33 +19328,32 @@ def test_list_evaluations_rest_required_fields( response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation_service.ListEvaluationsResponse.pb(return_value) + return_value = evaluation_service.ListEvaluationRunsResponse.pb( + return_value + ) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_evaluations(request) + response = client.list_evaluation_runs(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_list_evaluations_rest_unset_required_fields(): +def test_list_evaluation_runs_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.list_evaluations._get_unset_required_fields({}) + unset_fields = transport.list_evaluation_runs._get_unset_required_fields({}) assert set(unset_fields) == ( set( ( - "evaluationFilter", - "evaluationRunFilter", "filter", - "lastTenResults", "orderBy", "pageSize", "pageToken", @@ -17487,7 +19363,7 @@ def test_list_evaluations_rest_unset_required_fields(): ) -def test_list_evaluations_rest_flattened(): +def test_list_evaluation_runs_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -17496,7 +19372,7 @@ def test_list_evaluations_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation_service.ListEvaluationsResponse() + return_value = evaluation_service.ListEvaluationRunsResponse() # get arguments that satisfy an http rule for this method sample_request = {"parent": "projects/sample1/locations/sample2/apps/sample3"} @@ -17511,26 +19387,26 @@ def test_list_evaluations_rest_flattened(): response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation_service.ListEvaluationsResponse.pb(return_value) + return_value = evaluation_service.ListEvaluationRunsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_evaluations(**mock_args) + client.list_evaluation_runs(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1beta/{parent=projects/*/locations/*/apps/*}/evaluations" + "%s/v1beta/{parent=projects/*/locations/*/apps/*}/evaluationRuns" % client.transport._host, args[1], ) -def test_list_evaluations_rest_flattened_error(transport: str = "rest"): +def test_list_evaluation_runs_rest_flattened_error(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -17539,13 +19415,13 @@ def test_list_evaluations_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_evaluations( - evaluation_service.ListEvaluationsRequest(), + client.list_evaluation_runs( + evaluation_service.ListEvaluationRunsRequest(), parent="parent_value", ) -def test_list_evaluations_rest_pager(transport: str = "rest"): +def test_list_evaluation_runs_rest_pager(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -17557,28 +19433,28 @@ def test_list_evaluations_rest_pager(transport: str = "rest"): # with mock.patch.object(path_template, 'transcode') as transcode: # Set the response as a series of pages response = ( - evaluation_service.ListEvaluationsResponse( - evaluations=[ - evaluation.Evaluation(), - evaluation.Evaluation(), - evaluation.Evaluation(), + evaluation_service.ListEvaluationRunsResponse( + evaluation_runs=[ + evaluation.EvaluationRun(), + evaluation.EvaluationRun(), + evaluation.EvaluationRun(), ], next_page_token="abc", ), - evaluation_service.ListEvaluationsResponse( - evaluations=[], + evaluation_service.ListEvaluationRunsResponse( + evaluation_runs=[], next_page_token="def", ), - evaluation_service.ListEvaluationsResponse( - evaluations=[ - evaluation.Evaluation(), + evaluation_service.ListEvaluationRunsResponse( + evaluation_runs=[ + evaluation.EvaluationRun(), ], next_page_token="ghi", ), - evaluation_service.ListEvaluationsResponse( - evaluations=[ - evaluation.Evaluation(), - evaluation.Evaluation(), + evaluation_service.ListEvaluationRunsResponse( + evaluation_runs=[ + evaluation.EvaluationRun(), + evaluation.EvaluationRun(), ], ), ) @@ -17587,7 +19463,7 @@ def test_list_evaluations_rest_pager(transport: str = "rest"): # Wrap the values into proper Response objs response = tuple( - evaluation_service.ListEvaluationsResponse.to_json(x) for x in response + evaluation_service.ListEvaluationRunsResponse.to_json(x) for x in response ) return_values = tuple(Response() for i in response) for return_val, response_val in zip(return_values, response): @@ -17597,18 +19473,18 @@ def test_list_evaluations_rest_pager(transport: str = "rest"): sample_request = {"parent": "projects/sample1/locations/sample2/apps/sample3"} - pager = client.list_evaluations(request=sample_request) + pager = client.list_evaluation_runs(request=sample_request) results = list(pager) assert len(results) == 6 - assert all(isinstance(i, evaluation.Evaluation) for i in results) + assert all(isinstance(i, evaluation.EvaluationRun) for i in results) - pages = list(client.list_evaluations(request=sample_request).pages) + pages = list(client.list_evaluation_runs(request=sample_request).pages) for page_, token in zip(pages, ["abc", "def", "ghi", ""]): assert page_.raw_page.next_page_token == token -def test_list_evaluation_results_rest_use_cached_wrapped_rpc(): +def test_list_evaluation_expectations_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -17623,7 +19499,7 @@ def test_list_evaluation_results_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.list_evaluation_results + client._transport.list_evaluation_expectations in client._transport._wrapped_methods ) @@ -17633,24 +19509,24 @@ def test_list_evaluation_results_rest_use_cached_wrapped_rpc(): "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ - client._transport.list_evaluation_results + client._transport.list_evaluation_expectations ] = mock_rpc request = {} - client.list_evaluation_results(request) + client.list_evaluation_expectations(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_evaluation_results(request) + client.list_evaluation_expectations(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_evaluation_results_rest_required_fields( - request_type=evaluation_service.ListEvaluationResultsRequest, +def test_list_evaluation_expectations_rest_required_fields( + request_type=evaluation_service.ListEvaluationExpectationsRequest, ): transport_class = transports.EvaluationServiceRestTransport @@ -17666,7 +19542,7 @@ def test_list_evaluation_results_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_evaluation_results._get_unset_required_fields(jsonified_request) + ).list_evaluation_expectations._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -17675,7 +19551,7 @@ def test_list_evaluation_results_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_evaluation_results._get_unset_required_fields(jsonified_request) + ).list_evaluation_expectations._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. assert not set(unset_fields) - set( ( @@ -17698,7 +19574,7 @@ def test_list_evaluation_results_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = evaluation_service.ListEvaluationResultsResponse() + return_value = evaluation_service.ListEvaluationExpectationsResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -17719,7 +19595,7 @@ def test_list_evaluation_results_rest_required_fields( response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation_service.ListEvaluationResultsResponse.pb( + return_value = evaluation_service.ListEvaluationExpectationsResponse.pb( return_value ) json_return_value = json_format.MessageToJson(return_value) @@ -17728,19 +19604,19 @@ def test_list_evaluation_results_rest_required_fields( req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_evaluation_results(request) + response = client.list_evaluation_expectations(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_list_evaluation_results_rest_unset_required_fields(): +def test_list_evaluation_expectations_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.list_evaluation_results._get_unset_required_fields({}) + unset_fields = transport.list_evaluation_expectations._get_unset_required_fields({}) assert set(unset_fields) == ( set( ( @@ -17754,7 +19630,7 @@ def test_list_evaluation_results_rest_unset_required_fields(): ) -def test_list_evaluation_results_rest_flattened(): +def test_list_evaluation_expectations_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -17763,12 +19639,10 @@ def test_list_evaluation_results_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation_service.ListEvaluationResultsResponse() + return_value = evaluation_service.ListEvaluationExpectationsResponse() # get arguments that satisfy an http rule for this method - sample_request = { - "parent": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4" - } + sample_request = {"parent": "projects/sample1/locations/sample2/apps/sample3"} # get truthy value for each flattened field mock_args = dict( @@ -17780,26 +19654,28 @@ def test_list_evaluation_results_rest_flattened(): response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation_service.ListEvaluationResultsResponse.pb(return_value) + return_value = evaluation_service.ListEvaluationExpectationsResponse.pb( + return_value + ) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_evaluation_results(**mock_args) + client.list_evaluation_expectations(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1beta/{parent=projects/*/locations/*/apps/*/evaluations/*}/results" + "%s/v1beta/{parent=projects/*/locations/*/apps/*}/evaluationExpectations" % client.transport._host, args[1], ) -def test_list_evaluation_results_rest_flattened_error(transport: str = "rest"): +def test_list_evaluation_expectations_rest_flattened_error(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -17808,13 +19684,13 @@ def test_list_evaluation_results_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_evaluation_results( - evaluation_service.ListEvaluationResultsRequest(), + client.list_evaluation_expectations( + evaluation_service.ListEvaluationExpectationsRequest(), parent="parent_value", ) -def test_list_evaluation_results_rest_pager(transport: str = "rest"): +def test_list_evaluation_expectations_rest_pager(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -17826,28 +19702,28 @@ def test_list_evaluation_results_rest_pager(transport: str = "rest"): # with mock.patch.object(path_template, 'transcode') as transcode: # Set the response as a series of pages response = ( - evaluation_service.ListEvaluationResultsResponse( - evaluation_results=[ - evaluation.EvaluationResult(), - evaluation.EvaluationResult(), - evaluation.EvaluationResult(), + evaluation_service.ListEvaluationExpectationsResponse( + evaluation_expectations=[ + evaluation.EvaluationExpectation(), + evaluation.EvaluationExpectation(), + evaluation.EvaluationExpectation(), ], next_page_token="abc", ), - evaluation_service.ListEvaluationResultsResponse( - evaluation_results=[], + evaluation_service.ListEvaluationExpectationsResponse( + evaluation_expectations=[], next_page_token="def", ), - evaluation_service.ListEvaluationResultsResponse( - evaluation_results=[ - evaluation.EvaluationResult(), + evaluation_service.ListEvaluationExpectationsResponse( + evaluation_expectations=[ + evaluation.EvaluationExpectation(), ], next_page_token="ghi", ), - evaluation_service.ListEvaluationResultsResponse( - evaluation_results=[ - evaluation.EvaluationResult(), - evaluation.EvaluationResult(), + evaluation_service.ListEvaluationExpectationsResponse( + evaluation_expectations=[ + evaluation.EvaluationExpectation(), + evaluation.EvaluationExpectation(), ], ), ) @@ -17856,7 +19732,7 @@ def test_list_evaluation_results_rest_pager(transport: str = "rest"): # Wrap the values into proper Response objs response = tuple( - evaluation_service.ListEvaluationResultsResponse.to_json(x) + evaluation_service.ListEvaluationExpectationsResponse.to_json(x) for x in response ) return_values = tuple(Response() for i in response) @@ -17865,22 +19741,20 @@ def test_list_evaluation_results_rest_pager(transport: str = "rest"): return_val.status_code = 200 req.side_effect = return_values - sample_request = { - "parent": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4" - } + sample_request = {"parent": "projects/sample1/locations/sample2/apps/sample3"} - pager = client.list_evaluation_results(request=sample_request) + pager = client.list_evaluation_expectations(request=sample_request) results = list(pager) assert len(results) == 6 - assert all(isinstance(i, evaluation.EvaluationResult) for i in results) + assert all(isinstance(i, evaluation.EvaluationExpectation) for i in results) - pages = list(client.list_evaluation_results(request=sample_request).pages) + pages = list(client.list_evaluation_expectations(request=sample_request).pages) for page_, token in zip(pages, ["abc", "def", "ghi", ""]): assert page_.raw_page.next_page_token == token -def test_list_evaluation_datasets_rest_use_cached_wrapped_rpc(): +def test_get_evaluation_expectation_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -17895,7 +19769,7 @@ def test_list_evaluation_datasets_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.list_evaluation_datasets + client._transport.get_evaluation_expectation in client._transport._wrapped_methods ) @@ -17905,29 +19779,29 @@ def test_list_evaluation_datasets_rest_use_cached_wrapped_rpc(): "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ - client._transport.list_evaluation_datasets + client._transport.get_evaluation_expectation ] = mock_rpc request = {} - client.list_evaluation_datasets(request) + client.get_evaluation_expectation(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_evaluation_datasets(request) + client.get_evaluation_expectation(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_evaluation_datasets_rest_required_fields( - request_type=evaluation_service.ListEvaluationDatasetsRequest, +def test_get_evaluation_expectation_rest_required_fields( + request_type=evaluation_service.GetEvaluationExpectationRequest, ): transport_class = transports.EvaluationServiceRestTransport request_init = {} - request_init["parent"] = "" + request_init["name"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -17938,30 +19812,21 @@ def test_list_evaluation_datasets_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_evaluation_datasets._get_unset_required_fields(jsonified_request) + ).get_evaluation_expectation._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["parent"] = "parent_value" + jsonified_request["name"] = "name_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_evaluation_datasets._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "filter", - "order_by", - "page_size", - "page_token", - ) - ) + ).get_evaluation_expectation._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -17970,7 +19835,7 @@ def test_list_evaluation_datasets_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = evaluation_service.ListEvaluationDatasetsResponse() + return_value = evaluation.EvaluationExpectation() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -17991,42 +19856,30 @@ def test_list_evaluation_datasets_rest_required_fields( response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation_service.ListEvaluationDatasetsResponse.pb( - return_value - ) + return_value = evaluation.EvaluationExpectation.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_evaluation_datasets(request) + response = client.get_evaluation_expectation(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_list_evaluation_datasets_rest_unset_required_fields(): +def test_get_evaluation_expectation_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.list_evaluation_datasets._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "filter", - "orderBy", - "pageSize", - "pageToken", - ) - ) - & set(("parent",)) - ) + unset_fields = transport.get_evaluation_expectation._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) -def test_list_evaluation_datasets_rest_flattened(): +def test_get_evaluation_expectation_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -18035,14 +19888,16 @@ def test_list_evaluation_datasets_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation_service.ListEvaluationDatasetsResponse() + return_value = evaluation.EvaluationExpectation() # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2/apps/sample3"} + sample_request = { + "name": "projects/sample1/locations/sample2/apps/sample3/evaluationExpectations/sample4" + } # get truthy value for each flattened field mock_args = dict( - parent="parent_value", + name="name_value", ) mock_args.update(sample_request) @@ -18050,28 +19905,26 @@ def test_list_evaluation_datasets_rest_flattened(): response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation_service.ListEvaluationDatasetsResponse.pb( - return_value - ) + return_value = evaluation.EvaluationExpectation.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_evaluation_datasets(**mock_args) + client.get_evaluation_expectation(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1beta/{parent=projects/*/locations/*/apps/*}/evaluationDatasets" + "%s/v1beta/{name=projects/*/locations/*/apps/*/evaluationExpectations/*}" % client.transport._host, args[1], ) -def test_list_evaluation_datasets_rest_flattened_error(transport: str = "rest"): +def test_get_evaluation_expectation_rest_flattened_error(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -18080,77 +19933,13 @@ def test_list_evaluation_datasets_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_evaluation_datasets( - evaluation_service.ListEvaluationDatasetsRequest(), - parent="parent_value", - ) - - -def test_list_evaluation_datasets_rest_pager(transport: str = "rest"): - client = EvaluationServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - evaluation_service.ListEvaluationDatasetsResponse( - evaluation_datasets=[ - evaluation.EvaluationDataset(), - evaluation.EvaluationDataset(), - evaluation.EvaluationDataset(), - ], - next_page_token="abc", - ), - evaluation_service.ListEvaluationDatasetsResponse( - evaluation_datasets=[], - next_page_token="def", - ), - evaluation_service.ListEvaluationDatasetsResponse( - evaluation_datasets=[ - evaluation.EvaluationDataset(), - ], - next_page_token="ghi", - ), - evaluation_service.ListEvaluationDatasetsResponse( - evaluation_datasets=[ - evaluation.EvaluationDataset(), - evaluation.EvaluationDataset(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple( - evaluation_service.ListEvaluationDatasetsResponse.to_json(x) - for x in response + client.get_evaluation_expectation( + evaluation_service.GetEvaluationExpectationRequest(), + name="name_value", ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "projects/sample1/locations/sample2/apps/sample3"} - - pager = client.list_evaluation_datasets(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, evaluation.EvaluationDataset) for i in results) - - pages = list(client.list_evaluation_datasets(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token -def test_list_evaluation_runs_rest_use_cached_wrapped_rpc(): +def test_create_evaluation_expectation_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -18165,7 +19954,8 @@ def test_list_evaluation_runs_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.list_evaluation_runs in client._transport._wrapped_methods + client._transport.create_evaluation_expectation + in client._transport._wrapped_methods ) # Replace cached wrapped function with mock @@ -18173,25 +19963,25 @@ def test_list_evaluation_runs_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.list_evaluation_runs] = ( - mock_rpc - ) + client._transport._wrapped_methods[ + client._transport.create_evaluation_expectation + ] = mock_rpc request = {} - client.list_evaluation_runs(request) + client.create_evaluation_expectation(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_evaluation_runs(request) + client.create_evaluation_expectation(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_evaluation_runs_rest_required_fields( - request_type=evaluation_service.ListEvaluationRunsRequest, +def test_create_evaluation_expectation_rest_required_fields( + request_type=evaluation_service.CreateEvaluationExpectationRequest, ): transport_class = transports.EvaluationServiceRestTransport @@ -18207,7 +19997,7 @@ def test_list_evaluation_runs_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_evaluation_runs._get_unset_required_fields(jsonified_request) + ).create_evaluation_expectation._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -18216,16 +20006,9 @@ def test_list_evaluation_runs_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_evaluation_runs._get_unset_required_fields(jsonified_request) + ).create_evaluation_expectation._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "filter", - "order_by", - "page_size", - "page_token", - ) - ) + assert not set(unset_fields) - set(("evaluation_expectation_id",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -18239,7 +20022,7 @@ def test_list_evaluation_runs_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = evaluation_service.ListEvaluationRunsResponse() + return_value = evaluation.EvaluationExpectation() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -18251,51 +20034,50 @@ def test_list_evaluation_runs_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "post", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation_service.ListEvaluationRunsResponse.pb( - return_value - ) + return_value = evaluation.EvaluationExpectation.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_evaluation_runs(request) + response = client.create_evaluation_expectation(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_list_evaluation_runs_rest_unset_required_fields(): +def test_create_evaluation_expectation_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.list_evaluation_runs._get_unset_required_fields({}) + unset_fields = transport.create_evaluation_expectation._get_unset_required_fields( + {} + ) assert set(unset_fields) == ( - set( + set(("evaluationExpectationId",)) + & set( ( - "filter", - "orderBy", - "pageSize", - "pageToken", + "parent", + "evaluationExpectation", ) ) - & set(("parent",)) ) -def test_list_evaluation_runs_rest_flattened(): +def test_create_evaluation_expectation_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -18304,7 +20086,7 @@ def test_list_evaluation_runs_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation_service.ListEvaluationRunsResponse() + return_value = evaluation.EvaluationExpectation() # get arguments that satisfy an http rule for this method sample_request = {"parent": "projects/sample1/locations/sample2/apps/sample3"} @@ -18312,111 +20094,60 @@ def test_list_evaluation_runs_rest_flattened(): # get truthy value for each flattened field mock_args = dict( parent="parent_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = evaluation_service.ListEvaluationRunsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - client.list_evaluation_runs(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1beta/{parent=projects/*/locations/*/apps/*}/evaluationRuns" - % client.transport._host, - args[1], - ) - - -def test_list_evaluation_runs_rest_flattened_error(transport: str = "rest"): - client = EvaluationServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.list_evaluation_runs( - evaluation_service.ListEvaluationRunsRequest(), - parent="parent_value", - ) - - -def test_list_evaluation_runs_rest_pager(transport: str = "rest"): - client = EvaluationServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - evaluation_service.ListEvaluationRunsResponse( - evaluation_runs=[ - evaluation.EvaluationRun(), - evaluation.EvaluationRun(), - evaluation.EvaluationRun(), - ], - next_page_token="abc", - ), - evaluation_service.ListEvaluationRunsResponse( - evaluation_runs=[], - next_page_token="def", - ), - evaluation_service.ListEvaluationRunsResponse( - evaluation_runs=[ - evaluation.EvaluationRun(), - ], - next_page_token="ghi", - ), - evaluation_service.ListEvaluationRunsResponse( - evaluation_runs=[ - evaluation.EvaluationRun(), - evaluation.EvaluationRun(), - ], + evaluation_expectation=evaluation.EvaluationExpectation( + llm_criteria=evaluation.EvaluationExpectation.LlmCriteria( + prompt="prompt_value" + ) ), + evaluation_expectation_id="evaluation_expectation_id_value", ) - # Two responses for two calls - response = response + response + mock_args.update(sample_request) - # Wrap the values into proper Response objs - response = tuple( - evaluation_service.ListEvaluationRunsResponse.to_json(x) for x in response - ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = evaluation.EvaluationExpectation.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - sample_request = {"parent": "projects/sample1/locations/sample2/apps/sample3"} + client.create_evaluation_expectation(**mock_args) - pager = client.list_evaluation_runs(request=sample_request) + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1beta/{parent=projects/*/locations/*/apps/*}/evaluationExpectations" + % client.transport._host, + args[1], + ) - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, evaluation.EvaluationRun) for i in results) - pages = list(client.list_evaluation_runs(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token +def test_create_evaluation_expectation_rest_flattened_error(transport: str = "rest"): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_evaluation_expectation( + evaluation_service.CreateEvaluationExpectationRequest(), + parent="parent_value", + evaluation_expectation=evaluation.EvaluationExpectation( + llm_criteria=evaluation.EvaluationExpectation.LlmCriteria( + prompt="prompt_value" + ) + ), + evaluation_expectation_id="evaluation_expectation_id_value", + ) -def test_list_evaluation_expectations_rest_use_cached_wrapped_rpc(): +def test_update_evaluation_expectation_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -18431,7 +20162,7 @@ def test_list_evaluation_expectations_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.list_evaluation_expectations + client._transport.update_evaluation_expectation in client._transport._wrapped_methods ) @@ -18441,29 +20172,28 @@ def test_list_evaluation_expectations_rest_use_cached_wrapped_rpc(): "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ - client._transport.list_evaluation_expectations + client._transport.update_evaluation_expectation ] = mock_rpc request = {} - client.list_evaluation_expectations(request) + client.update_evaluation_expectation(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_evaluation_expectations(request) + client.update_evaluation_expectation(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_evaluation_expectations_rest_required_fields( - request_type=evaluation_service.ListEvaluationExpectationsRequest, +def test_update_evaluation_expectation_rest_required_fields( + request_type=evaluation_service.UpdateEvaluationExpectationRequest, ): transport_class = transports.EvaluationServiceRestTransport request_init = {} - request_init["parent"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -18474,30 +20204,19 @@ def test_list_evaluation_expectations_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_evaluation_expectations._get_unset_required_fields(jsonified_request) + ).update_evaluation_expectation._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["parent"] = "parent_value" - unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_evaluation_expectations._get_unset_required_fields(jsonified_request) + ).update_evaluation_expectation._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "filter", - "order_by", - "page_size", - "page_token", - ) - ) + assert not set(unset_fields) - set(("update_mask",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -18506,7 +20225,7 @@ def test_list_evaluation_expectations_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = evaluation_service.ListEvaluationExpectationsResponse() + return_value = evaluation.EvaluationExpectation() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -18518,51 +20237,42 @@ def test_list_evaluation_expectations_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "patch", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation_service.ListEvaluationExpectationsResponse.pb( - return_value - ) + return_value = evaluation.EvaluationExpectation.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_evaluation_expectations(request) + response = client.update_evaluation_expectation(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_list_evaluation_expectations_rest_unset_required_fields(): +def test_update_evaluation_expectation_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.list_evaluation_expectations._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "filter", - "orderBy", - "pageSize", - "pageToken", - ) - ) - & set(("parent",)) + unset_fields = transport.update_evaluation_expectation._get_unset_required_fields( + {} ) + assert set(unset_fields) == (set(("updateMask",)) & set(("evaluationExpectation",))) -def test_list_evaluation_expectations_rest_flattened(): +def test_update_evaluation_expectation_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -18571,14 +20281,23 @@ def test_list_evaluation_expectations_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation_service.ListEvaluationExpectationsResponse() + return_value = evaluation.EvaluationExpectation() # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2/apps/sample3"} + sample_request = { + "evaluation_expectation": { + "name": "projects/sample1/locations/sample2/apps/sample3/evaluationExpectations/sample4" + } + } # get truthy value for each flattened field mock_args = dict( - parent="parent_value", + evaluation_expectation=evaluation.EvaluationExpectation( + llm_criteria=evaluation.EvaluationExpectation.LlmCriteria( + prompt="prompt_value" + ) + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) mock_args.update(sample_request) @@ -18586,28 +20305,26 @@ def test_list_evaluation_expectations_rest_flattened(): response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation_service.ListEvaluationExpectationsResponse.pb( - return_value - ) + return_value = evaluation.EvaluationExpectation.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_evaluation_expectations(**mock_args) + client.update_evaluation_expectation(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1beta/{parent=projects/*/locations/*/apps/*}/evaluationExpectations" + "%s/v1beta/{evaluation_expectation.name=projects/*/locations/*/apps/*/evaluationExpectations/*}" % client.transport._host, args[1], ) -def test_list_evaluation_expectations_rest_flattened_error(transport: str = "rest"): +def test_update_evaluation_expectation_rest_flattened_error(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -18616,77 +20333,18 @@ def test_list_evaluation_expectations_rest_flattened_error(transport: str = "res # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_evaluation_expectations( - evaluation_service.ListEvaluationExpectationsRequest(), - parent="parent_value", - ) - - -def test_list_evaluation_expectations_rest_pager(transport: str = "rest"): - client = EvaluationServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - evaluation_service.ListEvaluationExpectationsResponse( - evaluation_expectations=[ - evaluation.EvaluationExpectation(), - evaluation.EvaluationExpectation(), - evaluation.EvaluationExpectation(), - ], - next_page_token="abc", - ), - evaluation_service.ListEvaluationExpectationsResponse( - evaluation_expectations=[], - next_page_token="def", - ), - evaluation_service.ListEvaluationExpectationsResponse( - evaluation_expectations=[ - evaluation.EvaluationExpectation(), - ], - next_page_token="ghi", - ), - evaluation_service.ListEvaluationExpectationsResponse( - evaluation_expectations=[ - evaluation.EvaluationExpectation(), - evaluation.EvaluationExpectation(), - ], + client.update_evaluation_expectation( + evaluation_service.UpdateEvaluationExpectationRequest(), + evaluation_expectation=evaluation.EvaluationExpectation( + llm_criteria=evaluation.EvaluationExpectation.LlmCriteria( + prompt="prompt_value" + ) ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple( - evaluation_service.ListEvaluationExpectationsResponse.to_json(x) - for x in response - ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "projects/sample1/locations/sample2/apps/sample3"} - - pager = client.list_evaluation_expectations(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, evaluation.EvaluationExpectation) for i in results) - - pages = list(client.list_evaluation_expectations(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token -def test_get_evaluation_expectation_rest_use_cached_wrapped_rpc(): +def test_delete_evaluation_expectation_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -18701,7 +20359,7 @@ def test_get_evaluation_expectation_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.get_evaluation_expectation + client._transport.delete_evaluation_expectation in client._transport._wrapped_methods ) @@ -18711,24 +20369,24 @@ def test_get_evaluation_expectation_rest_use_cached_wrapped_rpc(): "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ - client._transport.get_evaluation_expectation + client._transport.delete_evaluation_expectation ] = mock_rpc request = {} - client.get_evaluation_expectation(request) + client.delete_evaluation_expectation(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.get_evaluation_expectation(request) + client.delete_evaluation_expectation(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_get_evaluation_expectation_rest_required_fields( - request_type=evaluation_service.GetEvaluationExpectationRequest, +def test_delete_evaluation_expectation_rest_required_fields( + request_type=evaluation_service.DeleteEvaluationExpectationRequest, ): transport_class = transports.EvaluationServiceRestTransport @@ -18744,7 +20402,7 @@ def test_get_evaluation_expectation_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_evaluation_expectation._get_unset_required_fields(jsonified_request) + ).delete_evaluation_expectation._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -18753,7 +20411,9 @@ def test_get_evaluation_expectation_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_evaluation_expectation._get_unset_required_fields(jsonified_request) + ).delete_evaluation_expectation._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("etag",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -18767,7 +20427,7 @@ def test_get_evaluation_expectation_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = evaluation.EvaluationExpectation() + return_value = None # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -18779,39 +20439,38 @@ def test_get_evaluation_expectation_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "delete", "query_params": pb_request, } transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = evaluation.EvaluationExpectation.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + json_return_value = "" response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_evaluation_expectation(request) + response = client.delete_evaluation_expectation(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_get_evaluation_expectation_rest_unset_required_fields(): +def test_delete_evaluation_expectation_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.get_evaluation_expectation._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + unset_fields = transport.delete_evaluation_expectation._get_unset_required_fields( + {} + ) + assert set(unset_fields) == (set(("etag",)) & set(("name",))) -def test_get_evaluation_expectation_rest_flattened(): +def test_delete_evaluation_expectation_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -18820,7 +20479,7 @@ def test_get_evaluation_expectation_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation.EvaluationExpectation() + return_value = None # get arguments that satisfy an http rule for this method sample_request = { @@ -18836,14 +20495,12 @@ def test_get_evaluation_expectation_rest_flattened(): # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = evaluation.EvaluationExpectation.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + json_return_value = "" response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_evaluation_expectation(**mock_args) + client.delete_evaluation_expectation(**mock_args) # Establish that the underlying call was made with the expected # request object values. @@ -18856,7 +20513,7 @@ def test_get_evaluation_expectation_rest_flattened(): ) -def test_get_evaluation_expectation_rest_flattened_error(transport: str = "rest"): +def test_delete_evaluation_expectation_rest_flattened_error(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -18865,13 +20522,13 @@ def test_get_evaluation_expectation_rest_flattened_error(transport: str = "rest" # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.get_evaluation_expectation( - evaluation_service.GetEvaluationExpectationRequest(), + client.delete_evaluation_expectation( + evaluation_service.DeleteEvaluationExpectationRequest(), name="name_value", ) -def test_create_evaluation_expectation_rest_use_cached_wrapped_rpc(): +def test_create_scheduled_evaluation_run_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -18886,7 +20543,7 @@ def test_create_evaluation_expectation_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.create_evaluation_expectation + client._transport.create_scheduled_evaluation_run in client._transport._wrapped_methods ) @@ -18896,24 +20553,24 @@ def test_create_evaluation_expectation_rest_use_cached_wrapped_rpc(): "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ - client._transport.create_evaluation_expectation + client._transport.create_scheduled_evaluation_run ] = mock_rpc request = {} - client.create_evaluation_expectation(request) + client.create_scheduled_evaluation_run(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.create_evaluation_expectation(request) + client.create_scheduled_evaluation_run(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_create_evaluation_expectation_rest_required_fields( - request_type=evaluation_service.CreateEvaluationExpectationRequest, +def test_create_scheduled_evaluation_run_rest_required_fields( + request_type=evaluation_service.CreateScheduledEvaluationRunRequest, ): transport_class = transports.EvaluationServiceRestTransport @@ -18929,7 +20586,7 @@ def test_create_evaluation_expectation_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_evaluation_expectation._get_unset_required_fields(jsonified_request) + ).create_scheduled_evaluation_run._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -18938,9 +20595,9 @@ def test_create_evaluation_expectation_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_evaluation_expectation._get_unset_required_fields(jsonified_request) + ).create_scheduled_evaluation_run._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("evaluation_expectation_id",)) + assert not set(unset_fields) - set(("scheduled_evaluation_run_id",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -18954,7 +20611,7 @@ def test_create_evaluation_expectation_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = evaluation.EvaluationExpectation() + return_value = evaluation.ScheduledEvaluationRun() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -18976,40 +20633,40 @@ def test_create_evaluation_expectation_rest_required_fields( response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation.EvaluationExpectation.pb(return_value) + return_value = evaluation.ScheduledEvaluationRun.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_evaluation_expectation(request) + response = client.create_scheduled_evaluation_run(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_create_evaluation_expectation_rest_unset_required_fields(): +def test_create_scheduled_evaluation_run_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.create_evaluation_expectation._get_unset_required_fields( + unset_fields = transport.create_scheduled_evaluation_run._get_unset_required_fields( {} ) assert set(unset_fields) == ( - set(("evaluationExpectationId",)) + set(("scheduledEvaluationRunId",)) & set( ( "parent", - "evaluationExpectation", + "scheduledEvaluationRun", ) ) ) -def test_create_evaluation_expectation_rest_flattened(): +def test_create_scheduled_evaluation_run_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -19018,7 +20675,7 @@ def test_create_evaluation_expectation_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation.EvaluationExpectation() + return_value = evaluation.ScheduledEvaluationRun() # get arguments that satisfy an http rule for this method sample_request = {"parent": "projects/sample1/locations/sample2/apps/sample3"} @@ -19026,12 +20683,10 @@ def test_create_evaluation_expectation_rest_flattened(): # get truthy value for each flattened field mock_args = dict( parent="parent_value", - evaluation_expectation=evaluation.EvaluationExpectation( - llm_criteria=evaluation.EvaluationExpectation.LlmCriteria( - prompt="prompt_value" - ) + scheduled_evaluation_run=evaluation.ScheduledEvaluationRun( + name="name_value" ), - evaluation_expectation_id="evaluation_expectation_id_value", + scheduled_evaluation_run_id="scheduled_evaluation_run_id_value", ) mock_args.update(sample_request) @@ -19039,26 +20694,26 @@ def test_create_evaluation_expectation_rest_flattened(): response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation.EvaluationExpectation.pb(return_value) + return_value = evaluation.ScheduledEvaluationRun.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_evaluation_expectation(**mock_args) + client.create_scheduled_evaluation_run(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1beta/{parent=projects/*/locations/*/apps/*}/evaluationExpectations" + "%s/v1beta/{parent=projects/*/locations/*/apps/*}/scheduledEvaluationRuns" % client.transport._host, args[1], ) -def test_create_evaluation_expectation_rest_flattened_error(transport: str = "rest"): +def test_create_scheduled_evaluation_run_rest_flattened_error(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -19067,19 +20722,17 @@ def test_create_evaluation_expectation_rest_flattened_error(transport: str = "re # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.create_evaluation_expectation( - evaluation_service.CreateEvaluationExpectationRequest(), + client.create_scheduled_evaluation_run( + evaluation_service.CreateScheduledEvaluationRunRequest(), parent="parent_value", - evaluation_expectation=evaluation.EvaluationExpectation( - llm_criteria=evaluation.EvaluationExpectation.LlmCriteria( - prompt="prompt_value" - ) + scheduled_evaluation_run=evaluation.ScheduledEvaluationRun( + name="name_value" ), - evaluation_expectation_id="evaluation_expectation_id_value", + scheduled_evaluation_run_id="scheduled_evaluation_run_id_value", ) -def test_update_evaluation_expectation_rest_use_cached_wrapped_rpc(): +def test_get_scheduled_evaluation_run_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -19094,7 +20747,7 @@ def test_update_evaluation_expectation_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.update_evaluation_expectation + client._transport.get_scheduled_evaluation_run in client._transport._wrapped_methods ) @@ -19104,28 +20757,29 @@ def test_update_evaluation_expectation_rest_use_cached_wrapped_rpc(): "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ - client._transport.update_evaluation_expectation + client._transport.get_scheduled_evaluation_run ] = mock_rpc request = {} - client.update_evaluation_expectation(request) + client.get_scheduled_evaluation_run(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.update_evaluation_expectation(request) + client.get_scheduled_evaluation_run(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_update_evaluation_expectation_rest_required_fields( - request_type=evaluation_service.UpdateEvaluationExpectationRequest, +def test_get_scheduled_evaluation_run_rest_required_fields( + request_type=evaluation_service.GetScheduledEvaluationRunRequest, ): transport_class = transports.EvaluationServiceRestTransport request_init = {} + request_init["name"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -19136,19 +20790,21 @@ def test_update_evaluation_expectation_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_evaluation_expectation._get_unset_required_fields(jsonified_request) + ).get_scheduled_evaluation_run._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present + jsonified_request["name"] = "name_value" + unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_evaluation_expectation._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("update_mask",)) + ).get_scheduled_evaluation_run._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -19157,7 +20813,7 @@ def test_update_evaluation_expectation_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = evaluation.EvaluationExpectation() + return_value = evaluation.ScheduledEvaluationRun() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -19169,42 +20825,39 @@ def test_update_evaluation_expectation_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "patch", + "method": "get", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation.EvaluationExpectation.pb(return_value) + return_value = evaluation.ScheduledEvaluationRun.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_evaluation_expectation(request) + response = client.get_scheduled_evaluation_run(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_update_evaluation_expectation_rest_unset_required_fields(): +def test_get_scheduled_evaluation_run_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.update_evaluation_expectation._get_unset_required_fields( - {} - ) - assert set(unset_fields) == (set(("updateMask",)) & set(("evaluationExpectation",))) + unset_fields = transport.get_scheduled_evaluation_run._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) -def test_update_evaluation_expectation_rest_flattened(): +def test_get_scheduled_evaluation_run_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -19213,23 +20866,16 @@ def test_update_evaluation_expectation_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation.EvaluationExpectation() + return_value = evaluation.ScheduledEvaluationRun() # get arguments that satisfy an http rule for this method sample_request = { - "evaluation_expectation": { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluationExpectations/sample4" - } + "name": "projects/sample1/locations/sample2/apps/sample3/scheduledEvaluationRuns/sample4" } # get truthy value for each flattened field mock_args = dict( - evaluation_expectation=evaluation.EvaluationExpectation( - llm_criteria=evaluation.EvaluationExpectation.LlmCriteria( - prompt="prompt_value" - ) - ), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + name="name_value", ) mock_args.update(sample_request) @@ -19237,26 +20883,26 @@ def test_update_evaluation_expectation_rest_flattened(): response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation.EvaluationExpectation.pb(return_value) + return_value = evaluation.ScheduledEvaluationRun.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_evaluation_expectation(**mock_args) + client.get_scheduled_evaluation_run(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1beta/{evaluation_expectation.name=projects/*/locations/*/apps/*/evaluationExpectations/*}" + "%s/v1beta/{name=projects/*/locations/*/apps/*/scheduledEvaluationRuns/*}" % client.transport._host, args[1], ) -def test_update_evaluation_expectation_rest_flattened_error(transport: str = "rest"): +def test_get_scheduled_evaluation_run_rest_flattened_error(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -19265,18 +20911,13 @@ def test_update_evaluation_expectation_rest_flattened_error(transport: str = "re # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.update_evaluation_expectation( - evaluation_service.UpdateEvaluationExpectationRequest(), - evaluation_expectation=evaluation.EvaluationExpectation( - llm_criteria=evaluation.EvaluationExpectation.LlmCriteria( - prompt="prompt_value" - ) - ), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + client.get_scheduled_evaluation_run( + evaluation_service.GetScheduledEvaluationRunRequest(), + name="name_value", ) -def test_delete_evaluation_expectation_rest_use_cached_wrapped_rpc(): +def test_list_scheduled_evaluation_runs_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -19291,7 +20932,7 @@ def test_delete_evaluation_expectation_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.delete_evaluation_expectation + client._transport.list_scheduled_evaluation_runs in client._transport._wrapped_methods ) @@ -19301,29 +20942,29 @@ def test_delete_evaluation_expectation_rest_use_cached_wrapped_rpc(): "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ - client._transport.delete_evaluation_expectation + client._transport.list_scheduled_evaluation_runs ] = mock_rpc request = {} - client.delete_evaluation_expectation(request) + client.list_scheduled_evaluation_runs(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.delete_evaluation_expectation(request) + client.list_scheduled_evaluation_runs(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_delete_evaluation_expectation_rest_required_fields( - request_type=evaluation_service.DeleteEvaluationExpectationRequest, +def test_list_scheduled_evaluation_runs_rest_required_fields( + request_type=evaluation_service.ListScheduledEvaluationRunsRequest, ): transport_class = transports.EvaluationServiceRestTransport request_init = {} - request_init["name"] = "" + request_init["parent"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -19334,23 +20975,30 @@ def test_delete_evaluation_expectation_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_evaluation_expectation._get_unset_required_fields(jsonified_request) + ).list_scheduled_evaluation_runs._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["name"] = "name_value" + jsonified_request["parent"] = "parent_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_evaluation_expectation._get_unset_required_fields(jsonified_request) + ).list_scheduled_evaluation_runs._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("etag",)) + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + ) + ) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -19359,7 +21007,7 @@ def test_delete_evaluation_expectation_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = None + return_value = evaluation_service.ListScheduledEvaluationRunsResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -19371,38 +21019,53 @@ def test_delete_evaluation_expectation_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "delete", + "method": "get", "query_params": pb_request, } transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - json_return_value = "" + + # Convert return value to protobuf type + return_value = evaluation_service.ListScheduledEvaluationRunsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_evaluation_expectation(request) + response = client.list_scheduled_evaluation_runs(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_delete_evaluation_expectation_rest_unset_required_fields(): +def test_list_scheduled_evaluation_runs_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.delete_evaluation_expectation._get_unset_required_fields( + unset_fields = transport.list_scheduled_evaluation_runs._get_unset_required_fields( {} ) - assert set(unset_fields) == (set(("etag",)) & set(("name",))) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) -def test_delete_evaluation_expectation_rest_flattened(): +def test_list_scheduled_evaluation_runs_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -19411,56 +21074,124 @@ def test_delete_evaluation_expectation_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = None + return_value = evaluation_service.ListScheduledEvaluationRunsResponse() # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluationExpectations/sample4" - } + sample_request = {"parent": "projects/sample1/locations/sample2/apps/sample3"} # get truthy value for each flattened field mock_args = dict( - name="name_value", + parent="parent_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - json_return_value = "" + # Convert return value to protobuf type + return_value = evaluation_service.ListScheduledEvaluationRunsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_evaluation_expectation(**mock_args) + client.list_scheduled_evaluation_runs(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1beta/{name=projects/*/locations/*/apps/*/evaluationExpectations/*}" + "%s/v1beta/{parent=projects/*/locations/*/apps/*}/scheduledEvaluationRuns" % client.transport._host, args[1], ) -def test_delete_evaluation_expectation_rest_flattened_error(transport: str = "rest"): +def test_list_scheduled_evaluation_runs_rest_flattened_error(transport: str = "rest"): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_scheduled_evaluation_runs( + evaluation_service.ListScheduledEvaluationRunsRequest(), + parent="parent_value", + ) + + +def test_list_scheduled_evaluation_runs_rest_pager(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.delete_evaluation_expectation( - evaluation_service.DeleteEvaluationExpectationRequest(), - name="name_value", + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + evaluation_service.ListScheduledEvaluationRunsResponse( + scheduled_evaluation_runs=[ + evaluation.ScheduledEvaluationRun(), + evaluation.ScheduledEvaluationRun(), + evaluation.ScheduledEvaluationRun(), + ], + next_page_token="abc", + ), + evaluation_service.ListScheduledEvaluationRunsResponse( + scheduled_evaluation_runs=[], + next_page_token="def", + ), + evaluation_service.ListScheduledEvaluationRunsResponse( + scheduled_evaluation_runs=[ + evaluation.ScheduledEvaluationRun(), + ], + next_page_token="ghi", + ), + evaluation_service.ListScheduledEvaluationRunsResponse( + scheduled_evaluation_runs=[ + evaluation.ScheduledEvaluationRun(), + evaluation.ScheduledEvaluationRun(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + evaluation_service.ListScheduledEvaluationRunsResponse.to_json(x) + for x in response ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2/apps/sample3"} + pager = client.list_scheduled_evaluation_runs(request=sample_request) -def test_create_scheduled_evaluation_run_rest_use_cached_wrapped_rpc(): + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, evaluation.ScheduledEvaluationRun) for i in results) + + pages = list( + client.list_scheduled_evaluation_runs(request=sample_request).pages + ) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_update_scheduled_evaluation_run_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -19475,7 +21206,7 @@ def test_create_scheduled_evaluation_run_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.create_scheduled_evaluation_run + client._transport.update_scheduled_evaluation_run in client._transport._wrapped_methods ) @@ -19485,29 +21216,28 @@ def test_create_scheduled_evaluation_run_rest_use_cached_wrapped_rpc(): "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ - client._transport.create_scheduled_evaluation_run + client._transport.update_scheduled_evaluation_run ] = mock_rpc request = {} - client.create_scheduled_evaluation_run(request) + client.update_scheduled_evaluation_run(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.create_scheduled_evaluation_run(request) + client.update_scheduled_evaluation_run(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_create_scheduled_evaluation_run_rest_required_fields( - request_type=evaluation_service.CreateScheduledEvaluationRunRequest, +def test_update_scheduled_evaluation_run_rest_required_fields( + request_type=evaluation_service.UpdateScheduledEvaluationRunRequest, ): transport_class = transports.EvaluationServiceRestTransport request_init = {} - request_init["parent"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -19518,23 +21248,19 @@ def test_create_scheduled_evaluation_run_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_scheduled_evaluation_run._get_unset_required_fields(jsonified_request) + ).update_scheduled_evaluation_run._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["parent"] = "parent_value" - unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_scheduled_evaluation_run._get_unset_required_fields(jsonified_request) + ).update_scheduled_evaluation_run._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("scheduled_evaluation_run_id",)) + assert not set(unset_fields) - set(("update_mask",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -19555,7 +21281,7 @@ def test_create_scheduled_evaluation_run_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "post", + "method": "patch", "query_params": pb_request, } transcode_result["body"] = pb_request @@ -19572,33 +21298,27 @@ def test_create_scheduled_evaluation_run_rest_required_fields( req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_scheduled_evaluation_run(request) + response = client.update_scheduled_evaluation_run(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_create_scheduled_evaluation_run_rest_unset_required_fields(): +def test_update_scheduled_evaluation_run_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.create_scheduled_evaluation_run._get_unset_required_fields( + unset_fields = transport.update_scheduled_evaluation_run._get_unset_required_fields( {} ) assert set(unset_fields) == ( - set(("scheduledEvaluationRunId",)) - & set( - ( - "parent", - "scheduledEvaluationRun", - ) - ) + set(("updateMask",)) & set(("scheduledEvaluationRun",)) ) -def test_create_scheduled_evaluation_run_rest_flattened(): +def test_update_scheduled_evaluation_run_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -19610,15 +21330,18 @@ def test_create_scheduled_evaluation_run_rest_flattened(): return_value = evaluation.ScheduledEvaluationRun() # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2/apps/sample3"} + sample_request = { + "scheduled_evaluation_run": { + "name": "projects/sample1/locations/sample2/apps/sample3/scheduledEvaluationRuns/sample4" + } + } # get truthy value for each flattened field mock_args = dict( - parent="parent_value", scheduled_evaluation_run=evaluation.ScheduledEvaluationRun( name="name_value" ), - scheduled_evaluation_run_id="scheduled_evaluation_run_id_value", + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) mock_args.update(sample_request) @@ -19632,20 +21355,20 @@ def test_create_scheduled_evaluation_run_rest_flattened(): req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_scheduled_evaluation_run(**mock_args) + client.update_scheduled_evaluation_run(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1beta/{parent=projects/*/locations/*/apps/*}/scheduledEvaluationRuns" + "%s/v1beta/{scheduled_evaluation_run.name=projects/*/locations/*/apps/*/scheduledEvaluationRuns/*}" % client.transport._host, args[1], ) -def test_create_scheduled_evaluation_run_rest_flattened_error(transport: str = "rest"): +def test_update_scheduled_evaluation_run_rest_flattened_error(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -19654,17 +21377,16 @@ def test_create_scheduled_evaluation_run_rest_flattened_error(transport: str = " # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.create_scheduled_evaluation_run( - evaluation_service.CreateScheduledEvaluationRunRequest(), - parent="parent_value", + client.update_scheduled_evaluation_run( + evaluation_service.UpdateScheduledEvaluationRunRequest(), scheduled_evaluation_run=evaluation.ScheduledEvaluationRun( name="name_value" ), - scheduled_evaluation_run_id="scheduled_evaluation_run_id_value", + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) -def test_get_scheduled_evaluation_run_rest_use_cached_wrapped_rpc(): +def test_delete_scheduled_evaluation_run_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -19679,7 +21401,7 @@ def test_get_scheduled_evaluation_run_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.get_scheduled_evaluation_run + client._transport.delete_scheduled_evaluation_run in client._transport._wrapped_methods ) @@ -19689,24 +21411,24 @@ def test_get_scheduled_evaluation_run_rest_use_cached_wrapped_rpc(): "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ - client._transport.get_scheduled_evaluation_run + client._transport.delete_scheduled_evaluation_run ] = mock_rpc request = {} - client.get_scheduled_evaluation_run(request) + client.delete_scheduled_evaluation_run(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.get_scheduled_evaluation_run(request) + client.delete_scheduled_evaluation_run(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_get_scheduled_evaluation_run_rest_required_fields( - request_type=evaluation_service.GetScheduledEvaluationRunRequest, +def test_delete_scheduled_evaluation_run_rest_required_fields( + request_type=evaluation_service.DeleteScheduledEvaluationRunRequest, ): transport_class = transports.EvaluationServiceRestTransport @@ -19722,7 +21444,7 @@ def test_get_scheduled_evaluation_run_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_scheduled_evaluation_run._get_unset_required_fields(jsonified_request) + ).delete_scheduled_evaluation_run._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -19731,7 +21453,9 @@ def test_get_scheduled_evaluation_run_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_scheduled_evaluation_run._get_unset_required_fields(jsonified_request) + ).delete_scheduled_evaluation_run._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("etag",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -19745,7 +21469,7 @@ def test_get_scheduled_evaluation_run_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = evaluation.ScheduledEvaluationRun() + return_value = None # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -19757,39 +21481,38 @@ def test_get_scheduled_evaluation_run_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "delete", "query_params": pb_request, } transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = evaluation.ScheduledEvaluationRun.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + json_return_value = "" response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_scheduled_evaluation_run(request) + response = client.delete_scheduled_evaluation_run(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_get_scheduled_evaluation_run_rest_unset_required_fields(): +def test_delete_scheduled_evaluation_run_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.get_scheduled_evaluation_run._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + unset_fields = transport.delete_scheduled_evaluation_run._get_unset_required_fields( + {} + ) + assert set(unset_fields) == (set(("etag",)) & set(("name",))) -def test_get_scheduled_evaluation_run_rest_flattened(): +def test_delete_scheduled_evaluation_run_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -19798,7 +21521,7 @@ def test_get_scheduled_evaluation_run_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation.ScheduledEvaluationRun() + return_value = None # get arguments that satisfy an http rule for this method sample_request = { @@ -19814,14 +21537,12 @@ def test_get_scheduled_evaluation_run_rest_flattened(): # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = evaluation.ScheduledEvaluationRun.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + json_return_value = "" response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_scheduled_evaluation_run(**mock_args) + client.delete_scheduled_evaluation_run(**mock_args) # Establish that the underlying call was made with the expected # request object values. @@ -19834,7 +21555,7 @@ def test_get_scheduled_evaluation_run_rest_flattened(): ) -def test_get_scheduled_evaluation_run_rest_flattened_error(transport: str = "rest"): +def test_delete_scheduled_evaluation_run_rest_flattened_error(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -19843,13 +21564,13 @@ def test_get_scheduled_evaluation_run_rest_flattened_error(transport: str = "res # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.get_scheduled_evaluation_run( - evaluation_service.GetScheduledEvaluationRunRequest(), + client.delete_scheduled_evaluation_run( + evaluation_service.DeleteScheduledEvaluationRunRequest(), name="name_value", ) -def test_list_scheduled_evaluation_runs_rest_use_cached_wrapped_rpc(): +def test_test_persona_voice_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -19864,8 +21585,7 @@ def test_list_scheduled_evaluation_runs_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.list_scheduled_evaluation_runs - in client._transport._wrapped_methods + client._transport.test_persona_voice in client._transport._wrapped_methods ) # Replace cached wrapped function with mock @@ -19873,30 +21593,32 @@ def test_list_scheduled_evaluation_runs_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[ - client._transport.list_scheduled_evaluation_runs - ] = mock_rpc + client._transport._wrapped_methods[client._transport.test_persona_voice] = ( + mock_rpc + ) request = {} - client.list_scheduled_evaluation_runs(request) + client.test_persona_voice(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_scheduled_evaluation_runs(request) + client.test_persona_voice(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_scheduled_evaluation_runs_rest_required_fields( - request_type=evaluation_service.ListScheduledEvaluationRunsRequest, +def test_test_persona_voice_rest_required_fields( + request_type=evaluation_service.TestPersonaVoiceRequest, ): transport_class = transports.EvaluationServiceRestTransport request_init = {} - request_init["parent"] = "" + request_init["app"] = "" + request_init["persona_id"] = "" + request_init["text"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -19907,30 +21629,27 @@ def test_list_scheduled_evaluation_runs_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_scheduled_evaluation_runs._get_unset_required_fields(jsonified_request) + ).test_persona_voice._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["parent"] = "parent_value" + jsonified_request["app"] = "app_value" + jsonified_request["personaId"] = "persona_id_value" + jsonified_request["text"] = "text_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_scheduled_evaluation_runs._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "filter", - "order_by", - "page_size", - "page_token", - ) - ) + ).test_persona_voice._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" + assert "app" in jsonified_request + assert jsonified_request["app"] == "app_value" + assert "personaId" in jsonified_request + assert jsonified_request["personaId"] == "persona_id_value" + assert "text" in jsonified_request + assert jsonified_request["text"] == "text_value" client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -19939,7 +21658,7 @@ def test_list_scheduled_evaluation_runs_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = evaluation_service.ListScheduledEvaluationRunsResponse() + return_value = evaluation_service.TestPersonaVoiceResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -19951,53 +21670,49 @@ def test_list_scheduled_evaluation_runs_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "post", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation_service.ListScheduledEvaluationRunsResponse.pb( - return_value - ) + return_value = evaluation_service.TestPersonaVoiceResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_scheduled_evaluation_runs(request) + response = client.test_persona_voice(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_list_scheduled_evaluation_runs_rest_unset_required_fields(): +def test_test_persona_voice_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.list_scheduled_evaluation_runs._get_unset_required_fields( - {} - ) + unset_fields = transport.test_persona_voice._get_unset_required_fields({}) assert set(unset_fields) == ( - set( + set(()) + & set( ( - "filter", - "orderBy", - "pageSize", - "pageToken", + "app", + "personaId", + "text", ) ) - & set(("parent",)) ) -def test_list_scheduled_evaluation_runs_rest_flattened(): +def test_test_persona_voice_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -20006,14 +21721,14 @@ def test_list_scheduled_evaluation_runs_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation_service.ListScheduledEvaluationRunsResponse() + return_value = evaluation_service.TestPersonaVoiceResponse() # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2/apps/sample3"} + sample_request = {"app": "projects/sample1/locations/sample2/apps/sample3"} # get truthy value for each flattened field mock_args = dict( - parent="parent_value", + app="app_value", ) mock_args.update(sample_request) @@ -20021,28 +21736,26 @@ def test_list_scheduled_evaluation_runs_rest_flattened(): response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation_service.ListScheduledEvaluationRunsResponse.pb( - return_value - ) + return_value = evaluation_service.TestPersonaVoiceResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_scheduled_evaluation_runs(**mock_args) + client.test_persona_voice(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1beta/{parent=projects/*/locations/*/apps/*}/scheduledEvaluationRuns" + "%s/v1beta/{app=projects/*/locations/*/apps/*}:testPersonaVoice" % client.transport._host, args[1], ) -def test_list_scheduled_evaluation_runs_rest_flattened_error(transport: str = "rest"): +def test_test_persona_voice_rest_flattened_error(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -20051,79 +21764,13 @@ def test_list_scheduled_evaluation_runs_rest_flattened_error(transport: str = "r # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_scheduled_evaluation_runs( - evaluation_service.ListScheduledEvaluationRunsRequest(), - parent="parent_value", - ) - - -def test_list_scheduled_evaluation_runs_rest_pager(transport: str = "rest"): - client = EvaluationServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - evaluation_service.ListScheduledEvaluationRunsResponse( - scheduled_evaluation_runs=[ - evaluation.ScheduledEvaluationRun(), - evaluation.ScheduledEvaluationRun(), - evaluation.ScheduledEvaluationRun(), - ], - next_page_token="abc", - ), - evaluation_service.ListScheduledEvaluationRunsResponse( - scheduled_evaluation_runs=[], - next_page_token="def", - ), - evaluation_service.ListScheduledEvaluationRunsResponse( - scheduled_evaluation_runs=[ - evaluation.ScheduledEvaluationRun(), - ], - next_page_token="ghi", - ), - evaluation_service.ListScheduledEvaluationRunsResponse( - scheduled_evaluation_runs=[ - evaluation.ScheduledEvaluationRun(), - evaluation.ScheduledEvaluationRun(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple( - evaluation_service.ListScheduledEvaluationRunsResponse.to_json(x) - for x in response - ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "projects/sample1/locations/sample2/apps/sample3"} - - pager = client.list_scheduled_evaluation_runs(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, evaluation.ScheduledEvaluationRun) for i in results) - - pages = list( - client.list_scheduled_evaluation_runs(request=sample_request).pages + client.test_persona_voice( + evaluation_service.TestPersonaVoiceRequest(), + app="app_value", ) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token -def test_update_scheduled_evaluation_run_rest_use_cached_wrapped_rpc(): +def test_export_evaluations_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -20138,8 +21785,7 @@ def test_update_scheduled_evaluation_run_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.update_scheduled_evaluation_run - in client._transport._wrapped_methods + client._transport.export_evaluations in client._transport._wrapped_methods ) # Replace cached wrapped function with mock @@ -20147,29 +21793,35 @@ def test_update_scheduled_evaluation_run_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[ - client._transport.update_scheduled_evaluation_run - ] = mock_rpc + client._transport._wrapped_methods[client._transport.export_evaluations] = ( + mock_rpc + ) request = {} - client.update_scheduled_evaluation_run(request) + client.export_evaluations(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.update_scheduled_evaluation_run(request) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.export_evaluations(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_update_scheduled_evaluation_run_rest_required_fields( - request_type=evaluation_service.UpdateScheduledEvaluationRunRequest, +def test_export_evaluations_rest_required_fields( + request_type=evaluation_service.ExportEvaluationsRequest, ): transport_class = transports.EvaluationServiceRestTransport request_init = {} + request_init["parent"] = "" + request_init["names"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -20180,19 +21832,24 @@ def test_update_scheduled_evaluation_run_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_scheduled_evaluation_run._get_unset_required_fields(jsonified_request) + ).export_evaluations._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present + jsonified_request["parent"] = "parent_value" + jsonified_request["names"] = "names_value" + unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_scheduled_evaluation_run._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("update_mask",)) + ).export_evaluations._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "names" in jsonified_request + assert jsonified_request["names"] == "names_value" client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -20201,7 +21858,7 @@ def test_update_scheduled_evaluation_run_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = evaluation.ScheduledEvaluationRun() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -20213,7 +21870,7 @@ def test_update_scheduled_evaluation_run_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "patch", + "method": "post", "query_params": pb_request, } transcode_result["body"] = pb_request @@ -20221,36 +21878,37 @@ def test_update_scheduled_evaluation_run_rest_required_fields( response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = evaluation.ScheduledEvaluationRun.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_scheduled_evaluation_run(request) + response = client.export_evaluations(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_update_scheduled_evaluation_run_rest_unset_required_fields(): +def test_export_evaluations_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.update_scheduled_evaluation_run._get_unset_required_fields( - {} - ) + unset_fields = transport.export_evaluations._get_unset_required_fields({}) assert set(unset_fields) == ( - set(("updateMask",)) & set(("scheduledEvaluationRun",)) + set(()) + & set( + ( + "parent", + "names", + ) + ) ) -def test_update_scheduled_evaluation_run_rest_flattened(): +def test_export_evaluations_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -20259,48 +21917,39 @@ def test_update_scheduled_evaluation_run_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation.ScheduledEvaluationRun() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = { - "scheduled_evaluation_run": { - "name": "projects/sample1/locations/sample2/apps/sample3/scheduledEvaluationRuns/sample4" - } - } + sample_request = {"parent": "projects/sample1/locations/sample2/apps/sample3"} # get truthy value for each flattened field mock_args = dict( - scheduled_evaluation_run=evaluation.ScheduledEvaluationRun( - name="name_value" - ), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + parent="parent_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = evaluation.ScheduledEvaluationRun.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_scheduled_evaluation_run(**mock_args) + client.export_evaluations(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1beta/{scheduled_evaluation_run.name=projects/*/locations/*/apps/*/scheduledEvaluationRuns/*}" + "%s/v1beta/{parent=projects/*/locations/*/apps/*}/evaluations:export" % client.transport._host, args[1], ) -def test_update_scheduled_evaluation_run_rest_flattened_error(transport: str = "rest"): +def test_export_evaluations_rest_flattened_error(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -20309,16 +21958,13 @@ def test_update_scheduled_evaluation_run_rest_flattened_error(transport: str = " # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.update_scheduled_evaluation_run( - evaluation_service.UpdateScheduledEvaluationRunRequest(), - scheduled_evaluation_run=evaluation.ScheduledEvaluationRun( - name="name_value" - ), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + client.export_evaluations( + evaluation_service.ExportEvaluationsRequest(), + parent="parent_value", ) -def test_delete_scheduled_evaluation_run_rest_use_cached_wrapped_rpc(): +def test_export_evaluation_runs_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -20333,7 +21979,7 @@ def test_delete_scheduled_evaluation_run_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.delete_scheduled_evaluation_run + client._transport.export_evaluation_runs in client._transport._wrapped_methods ) @@ -20342,30 +21988,35 @@ def test_delete_scheduled_evaluation_run_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[ - client._transport.delete_scheduled_evaluation_run - ] = mock_rpc + client._transport._wrapped_methods[client._transport.export_evaluation_runs] = ( + mock_rpc + ) request = {} - client.delete_scheduled_evaluation_run(request) + client.export_evaluation_runs(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.delete_scheduled_evaluation_run(request) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.export_evaluation_runs(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_delete_scheduled_evaluation_run_rest_required_fields( - request_type=evaluation_service.DeleteScheduledEvaluationRunRequest, +def test_export_evaluation_runs_rest_required_fields( + request_type=evaluation_service.ExportEvaluationRunsRequest, ): transport_class = transports.EvaluationServiceRestTransport request_init = {} - request_init["name"] = "" + request_init["parent"] = "" + request_init["names"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -20376,23 +22027,24 @@ def test_delete_scheduled_evaluation_run_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_scheduled_evaluation_run._get_unset_required_fields(jsonified_request) + ).export_evaluation_runs._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["name"] = "name_value" + jsonified_request["parent"] = "parent_value" + jsonified_request["names"] = "names_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_scheduled_evaluation_run._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("etag",)) + ).export_evaluation_runs._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "names" in jsonified_request + assert jsonified_request["names"] == "names_value" client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -20401,7 +22053,7 @@ def test_delete_scheduled_evaluation_run_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = None + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -20413,38 +22065,45 @@ def test_delete_scheduled_evaluation_run_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "delete", + "method": "post", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - json_return_value = "" + json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_scheduled_evaluation_run(request) + response = client.export_evaluation_runs(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_delete_scheduled_evaluation_run_rest_unset_required_fields(): +def test_export_evaluation_runs_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.delete_scheduled_evaluation_run._get_unset_required_fields( - {} + unset_fields = transport.export_evaluation_runs._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "names", + ) + ) ) - assert set(unset_fields) == (set(("etag",)) & set(("name",))) -def test_delete_scheduled_evaluation_run_rest_flattened(): +def test_export_evaluation_runs_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -20453,41 +22112,40 @@ def test_delete_scheduled_evaluation_run_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = None + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/apps/sample3/scheduledEvaluationRuns/sample4" - } + sample_request = {"parent": "projects/sample1/locations/sample2/apps/sample3"} # get truthy value for each flattened field mock_args = dict( - name="name_value", + parent="parent_value", + names=["names_value"], ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - json_return_value = "" + json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_scheduled_evaluation_run(**mock_args) + client.export_evaluation_runs(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1beta/{name=projects/*/locations/*/apps/*/scheduledEvaluationRuns/*}" + "%s/v1beta/{parent=projects/*/locations/*/apps/*}/evaluationRuns:export" % client.transport._host, args[1], ) -def test_delete_scheduled_evaluation_run_rest_flattened_error(transport: str = "rest"): +def test_export_evaluation_runs_rest_flattened_error(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -20496,13 +22154,14 @@ def test_delete_scheduled_evaluation_run_rest_flattened_error(transport: str = " # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.delete_scheduled_evaluation_run( - evaluation_service.DeleteScheduledEvaluationRunRequest(), - name="name_value", + client.export_evaluation_runs( + evaluation_service.ExportEvaluationRunsRequest(), + parent="parent_value", + names=["names_value"], ) -def test_test_persona_voice_rest_use_cached_wrapped_rpc(): +def test_export_evaluation_results_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -20517,7 +22176,8 @@ def test_test_persona_voice_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.test_persona_voice in client._transport._wrapped_methods + client._transport.export_evaluation_results + in client._transport._wrapped_methods ) # Replace cached wrapped function with mock @@ -20525,32 +22185,35 @@ def test_test_persona_voice_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.test_persona_voice] = ( - mock_rpc - ) + client._transport._wrapped_methods[ + client._transport.export_evaluation_results + ] = mock_rpc request = {} - client.test_persona_voice(request) + client.export_evaluation_results(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.test_persona_voice(request) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.export_evaluation_results(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_test_persona_voice_rest_required_fields( - request_type=evaluation_service.TestPersonaVoiceRequest, +def test_export_evaluation_results_rest_required_fields( + request_type=evaluation_service.ExportEvaluationResultsRequest, ): transport_class = transports.EvaluationServiceRestTransport request_init = {} - request_init["app"] = "" - request_init["persona_id"] = "" - request_init["text"] = "" + request_init["parent"] = "" + request_init["names"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -20561,27 +22224,24 @@ def test_test_persona_voice_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).test_persona_voice._get_unset_required_fields(jsonified_request) + ).export_evaluation_results._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["app"] = "app_value" - jsonified_request["personaId"] = "persona_id_value" - jsonified_request["text"] = "text_value" + jsonified_request["parent"] = "parent_value" + jsonified_request["names"] = "names_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).test_persona_voice._get_unset_required_fields(jsonified_request) + ).export_evaluation_results._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "app" in jsonified_request - assert jsonified_request["app"] == "app_value" - assert "personaId" in jsonified_request - assert jsonified_request["personaId"] == "persona_id_value" - assert "text" in jsonified_request - assert jsonified_request["text"] == "text_value" + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "names" in jsonified_request + assert jsonified_request["names"] == "names_value" client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -20590,7 +22250,7 @@ def test_test_persona_voice_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = evaluation_service.TestPersonaVoiceResponse() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -20610,41 +22270,37 @@ def test_test_persona_voice_rest_required_fields( response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = evaluation_service.TestPersonaVoiceResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.test_persona_voice(request) + response = client.export_evaluation_results(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_test_persona_voice_rest_unset_required_fields(): +def test_export_evaluation_results_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.test_persona_voice._get_unset_required_fields({}) + unset_fields = transport.export_evaluation_results._get_unset_required_fields({}) assert set(unset_fields) == ( set(()) & set( ( - "app", - "personaId", - "text", + "parent", + "names", ) ) ) -def test_test_persona_voice_rest_flattened(): +def test_export_evaluation_results_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -20653,41 +22309,42 @@ def test_test_persona_voice_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation_service.TestPersonaVoiceResponse() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = {"app": "projects/sample1/locations/sample2/apps/sample3"} + sample_request = { + "parent": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4" + } # get truthy value for each flattened field mock_args = dict( - app="app_value", + parent="parent_value", + names=["names_value"], ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = evaluation_service.TestPersonaVoiceResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.test_persona_voice(**mock_args) + client.export_evaluation_results(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1beta/{app=projects/*/locations/*/apps/*}:testPersonaVoice" + "%s/v1beta/{parent=projects/*/locations/*/apps/*/evaluations/*}/results:export" % client.transport._host, args[1], ) -def test_test_persona_voice_rest_flattened_error(transport: str = "rest"): +def test_export_evaluation_results_rest_flattened_error(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -20696,13 +22353,14 @@ def test_test_persona_voice_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.test_persona_voice( - evaluation_service.TestPersonaVoiceRequest(), - app="app_value", + client.export_evaluation_results( + evaluation_service.ExportEvaluationResultsRequest(), + parent="parent_value", + names=["names_value"], ) -def test_export_evaluations_rest_use_cached_wrapped_rpc(): +def test_run_evaluation_result_metrics_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -20717,7 +22375,8 @@ def test_export_evaluations_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.export_evaluations in client._transport._wrapped_methods + client._transport.run_evaluation_result_metrics + in client._transport._wrapped_methods ) # Replace cached wrapped function with mock @@ -20725,12 +22384,12 @@ def test_export_evaluations_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.export_evaluations] = ( - mock_rpc - ) + client._transport._wrapped_methods[ + client._transport.run_evaluation_result_metrics + ] = mock_rpc request = {} - client.export_evaluations(request) + client.run_evaluation_result_metrics(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 @@ -20739,21 +22398,20 @@ def test_export_evaluations_rest_use_cached_wrapped_rpc(): # subsequent calls should use the cached wrapper wrapper_fn.reset_mock() - client.export_evaluations(request) + client.run_evaluation_result_metrics(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_export_evaluations_rest_required_fields( - request_type=evaluation_service.ExportEvaluationsRequest, +def test_run_evaluation_result_metrics_rest_required_fields( + request_type=evaluation_service.RunEvaluationResultMetricsRequest, ): transport_class = transports.EvaluationServiceRestTransport request_init = {} - request_init["parent"] = "" - request_init["names"] = "" + request_init["evaluation_result_id"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -20764,24 +22422,21 @@ def test_export_evaluations_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).export_evaluations._get_unset_required_fields(jsonified_request) + ).run_evaluation_result_metrics._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["parent"] = "parent_value" - jsonified_request["names"] = "names_value" + jsonified_request["evaluationResultId"] = "evaluation_result_id_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).export_evaluations._get_unset_required_fields(jsonified_request) + ).run_evaluation_result_metrics._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" - assert "names" in jsonified_request - assert jsonified_request["names"] == "names_value" + assert "evaluationResultId" in jsonified_request + assert jsonified_request["evaluationResultId"] == "evaluation_result_id_value" client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -20816,31 +22471,25 @@ def test_export_evaluations_rest_required_fields( req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.export_evaluations(request) + response = client.run_evaluation_result_metrics(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_export_evaluations_rest_unset_required_fields(): +def test_run_evaluation_result_metrics_rest_unset_required_fields(): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.export_evaluations._get_unset_required_fields({}) - assert set(unset_fields) == ( - set(()) - & set( - ( - "parent", - "names", - ) - ) + unset_fields = transport.run_evaluation_result_metrics._get_unset_required_fields( + {} ) + assert set(unset_fields) == (set(()) & set(("evaluationResultId",))) -def test_export_evaluations_rest_flattened(): +def test_run_evaluation_result_metrics_rest_flattened(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -20852,11 +22501,13 @@ def test_export_evaluations_rest_flattened(): return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2/apps/sample3"} + sample_request = { + "evaluation_result_id": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4/results/sample5" + } # get truthy value for each flattened field mock_args = dict( - parent="parent_value", + evaluation_result_id="evaluation_result_id_value", ) mock_args.update(sample_request) @@ -20868,20 +22519,20 @@ def test_export_evaluations_rest_flattened(): req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.export_evaluations(**mock_args) + client.run_evaluation_result_metrics(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1beta/{parent=projects/*/locations/*/apps/*}/evaluations:export" + "%s/v1beta/{evaluation_result_id=projects/*/locations/*/apps/*/evaluations/*/results/*}:runEvaluationResultMetrics" % client.transport._host, args[1], ) -def test_export_evaluations_rest_flattened_error(transport: str = "rest"): +def test_run_evaluation_result_metrics_rest_flattened_error(transport: str = "rest"): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -20890,9 +22541,9 @@ def test_export_evaluations_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.export_evaluations( - evaluation_service.ExportEvaluationsRequest(), - parent="parent_value", + client.run_evaluation_result_metrics( + evaluation_service.RunEvaluationResultMetricsRequest(), + evaluation_result_id="evaluation_result_id_value", ) @@ -21700,6 +23351,72 @@ def test_export_evaluations_empty_call_grpc(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_export_evaluation_runs_empty_call_grpc(): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.export_evaluation_runs), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.export_evaluation_runs(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = evaluation_service.ExportEvaluationRunsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_export_evaluation_results_empty_call_grpc(): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.export_evaluation_results), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.export_evaluation_results(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = evaluation_service.ExportEvaluationResultsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_run_evaluation_result_metrics_empty_call_grpc(): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.run_evaluation_result_metrics), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.run_evaluation_result_metrics(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = evaluation_service.RunEvaluationResultMetricsRequest() + assert args[0] == request_msg + + def test_transport_kind_grpc_asyncio(): transport = EvaluationServiceAsyncClient.get_transport_class("grpc_asyncio")( credentials=async_anonymous_credentials() @@ -22116,7 +23833,7 @@ async def test_get_evaluation_result_empty_call_grpc_asyncio(): app_version="app_version_value", app_version_display_name="app_version_display_name_value", changelog="changelog_value", - execution_state=evaluation.EvaluationResult.ExecutionState.RUNNING, + execution_state=evaluation.EvaluationResult.ExecutionState.QUEUED, golden_run_method=golden_run.GoldenRunMethod.STABLE, ) ) @@ -22188,10 +23905,11 @@ async def test_get_evaluation_run_empty_call_grpc_asyncio(): evaluations=["evaluations_value"], evaluation_dataset="evaluation_dataset_value", evaluation_type=evaluation.EvaluationRun.EvaluationType.GOLDEN, - state=evaluation.EvaluationRun.EvaluationRunState.RUNNING, + state=evaluation.EvaluationRun.EvaluationRunState.QUEUED, run_count=989, scheduled_evaluation_run="scheduled_evaluation_run_value", golden_run_method=golden_run.GoldenRunMethod.STABLE, + operation="operation_value", ) ) await client.get_evaluation_run(request=None) @@ -22526,14 +24244,102 @@ async def test_get_scheduled_evaluation_run_empty_call_grpc_asyncio(): # Establish that the underlying stub method was called. call.assert_called() _, args, _ = call.mock_calls[0] - request_msg = evaluation_service.GetScheduledEvaluationRunRequest() + request_msg = evaluation_service.GetScheduledEvaluationRunRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_scheduled_evaluation_runs_empty_call_grpc_asyncio(): + client = EvaluationServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_scheduled_evaluation_runs), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + evaluation_service.ListScheduledEvaluationRunsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_scheduled_evaluation_runs(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = evaluation_service.ListScheduledEvaluationRunsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_scheduled_evaluation_run_empty_call_grpc_asyncio(): + client = EvaluationServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_scheduled_evaluation_run), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + evaluation.ScheduledEvaluationRun( + name="name_value", + display_name="display_name_value", + description="description_value", + active=True, + last_completed_run="last_completed_run_value", + total_executions=1738, + created_by="created_by_value", + last_updated_by="last_updated_by_value", + etag="etag_value", + ) + ) + await client.update_scheduled_evaluation_run(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = evaluation_service.UpdateScheduledEvaluationRunRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_scheduled_evaluation_run_empty_call_grpc_asyncio(): + client = EvaluationServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_scheduled_evaluation_run), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_scheduled_evaluation_run(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = evaluation_service.DeleteScheduledEvaluationRunRequest() assert args[0] == request_msg # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @pytest.mark.asyncio -async def test_list_scheduled_evaluation_runs_empty_call_grpc_asyncio(): +async def test_test_persona_voice_empty_call_grpc_asyncio(): client = EvaluationServiceAsyncClient( credentials=async_anonymous_credentials(), transport="grpc_asyncio", @@ -22541,27 +24347,27 @@ async def test_list_scheduled_evaluation_runs_empty_call_grpc_asyncio(): # Mock the actual call, and fake the request. with mock.patch.object( - type(client.transport.list_scheduled_evaluation_runs), "__call__" + type(client.transport.test_persona_voice), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - evaluation_service.ListScheduledEvaluationRunsResponse( - next_page_token="next_page_token_value", + evaluation_service.TestPersonaVoiceResponse( + audio=b"audio_blob", ) ) - await client.list_scheduled_evaluation_runs(request=None) + await client.test_persona_voice(request=None) # Establish that the underlying stub method was called. call.assert_called() _, args, _ = call.mock_calls[0] - request_msg = evaluation_service.ListScheduledEvaluationRunsRequest() + request_msg = evaluation_service.TestPersonaVoiceRequest() assert args[0] == request_msg # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @pytest.mark.asyncio -async def test_update_scheduled_evaluation_run_empty_call_grpc_asyncio(): +async def test_export_evaluations_empty_call_grpc_asyncio(): client = EvaluationServiceAsyncClient( credentials=async_anonymous_credentials(), transport="grpc_asyncio", @@ -22569,35 +24375,25 @@ async def test_update_scheduled_evaluation_run_empty_call_grpc_asyncio(): # Mock the actual call, and fake the request. with mock.patch.object( - type(client.transport.update_scheduled_evaluation_run), "__call__" + type(client.transport.export_evaluations), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - evaluation.ScheduledEvaluationRun( - name="name_value", - display_name="display_name_value", - description="description_value", - active=True, - last_completed_run="last_completed_run_value", - total_executions=1738, - created_by="created_by_value", - last_updated_by="last_updated_by_value", - etag="etag_value", - ) + operations_pb2.Operation(name="operations/spam") ) - await client.update_scheduled_evaluation_run(request=None) + await client.export_evaluations(request=None) # Establish that the underlying stub method was called. call.assert_called() _, args, _ = call.mock_calls[0] - request_msg = evaluation_service.UpdateScheduledEvaluationRunRequest() + request_msg = evaluation_service.ExportEvaluationsRequest() assert args[0] == request_msg # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @pytest.mark.asyncio -async def test_delete_scheduled_evaluation_run_empty_call_grpc_asyncio(): +async def test_export_evaluation_runs_empty_call_grpc_asyncio(): client = EvaluationServiceAsyncClient( credentials=async_anonymous_credentials(), transport="grpc_asyncio", @@ -22605,23 +24401,25 @@ async def test_delete_scheduled_evaluation_run_empty_call_grpc_asyncio(): # Mock the actual call, and fake the request. with mock.patch.object( - type(client.transport.delete_scheduled_evaluation_run), "__call__" + type(client.transport.export_evaluation_runs), "__call__" ) as call: # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - await client.delete_scheduled_evaluation_run(request=None) + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.export_evaluation_runs(request=None) # Establish that the underlying stub method was called. call.assert_called() _, args, _ = call.mock_calls[0] - request_msg = evaluation_service.DeleteScheduledEvaluationRunRequest() + request_msg = evaluation_service.ExportEvaluationRunsRequest() assert args[0] == request_msg # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @pytest.mark.asyncio -async def test_test_persona_voice_empty_call_grpc_asyncio(): +async def test_export_evaluation_results_empty_call_grpc_asyncio(): client = EvaluationServiceAsyncClient( credentials=async_anonymous_credentials(), transport="grpc_asyncio", @@ -22629,27 +24427,25 @@ async def test_test_persona_voice_empty_call_grpc_asyncio(): # Mock the actual call, and fake the request. with mock.patch.object( - type(client.transport.test_persona_voice), "__call__" + type(client.transport.export_evaluation_results), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - evaluation_service.TestPersonaVoiceResponse( - audio=b"audio_blob", - ) + operations_pb2.Operation(name="operations/spam") ) - await client.test_persona_voice(request=None) + await client.export_evaluation_results(request=None) # Establish that the underlying stub method was called. call.assert_called() _, args, _ = call.mock_calls[0] - request_msg = evaluation_service.TestPersonaVoiceRequest() + request_msg = evaluation_service.ExportEvaluationResultsRequest() assert args[0] == request_msg # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @pytest.mark.asyncio -async def test_export_evaluations_empty_call_grpc_asyncio(): +async def test_run_evaluation_result_metrics_empty_call_grpc_asyncio(): client = EvaluationServiceAsyncClient( credentials=async_anonymous_credentials(), transport="grpc_asyncio", @@ -22657,18 +24453,18 @@ async def test_export_evaluations_empty_call_grpc_asyncio(): # Mock the actual call, and fake the request. with mock.patch.object( - type(client.transport.export_evaluations), "__call__" + type(client.transport.run_evaluation_result_metrics), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") ) - await client.export_evaluations(request=None) + await client.run_evaluation_result_metrics(request=None) # Establish that the underlying stub method was called. call.assert_called() _, args, _ = call.mock_calls[0] - request_msg = evaluation_service.ExportEvaluationsRequest() + request_msg = evaluation_service.RunEvaluationResultMetricsRequest() assert args[0] == request_msg @@ -23055,7 +24851,19 @@ def test_create_evaluation_rest_call_success(request_type): "agent_transfer": {}, "updated_variables": {}, "mock_tool_response": {}, + "no_tool_calls": True, "note": "note_value", + "skip_evaluation": True, + "expectation_level_metrics_thresholds_override": { + "tool_invocation_parameter_correctness_threshold": 0.5037 + }, + "agent_response_semantic_similarity_metrics_config_override": { + "enable_semantic_similarity_metrics": True + }, + "agent_response_hallucination_metrics_config_override": { + "enable_hallucination_metrics": True + }, + "comparison_type": 1, }, } ], @@ -23067,6 +24875,12 @@ def test_create_evaluation_rest_call_success(request_type): "attributes": {}, "child_spans": {}, }, + "turn_level_metrics_thresholds_override": { + "semantic_similarity_success_threshold": 3966, + "overall_tool_invocation_correctness_threshold": 0.4833, + "semantic_similarity_channel": 1, + }, + "hallucination_metric_behavior_override": 1, } ], "evaluation_expectations": [ @@ -23095,6 +24909,7 @@ def test_create_evaluation_rest_call_success(request_type): "evaluation_expectations_value1", "evaluation_expectations_value2", ], + "scenario_execution_mode": 1, }, "name": "name_value", "display_name": "display_name_value", @@ -23149,6 +24964,7 @@ def test_create_evaluation_rest_call_success(request_type): "observed_tool_response": {}, "observed_agent_response": {}, "observed_agent_transfer": {}, + "observed_payload": {}, "expectation": {}, "outcome": 1, "semantic_similarity_result": { @@ -23190,6 +25006,7 @@ def test_create_evaluation_rest_call_success(request_type): "error_type": 1, "error_message": "error_message_value", "session_id": "session_id_value", + "user_facing_error_message": "user_facing_error_message_value", }, "span_latencies": [ { @@ -23283,17 +25100,11 @@ def test_create_evaluation_rest_call_success(request_type): "app_version_display_name": "app_version_display_name_value", "changelog": "changelog_value", "changelog_create_time": {}, - "execution_state": 1, + "execution_state": 5, "evaluation_metrics_thresholds": { "golden_evaluation_metrics_thresholds": { - "turn_level_metrics_thresholds": { - "semantic_similarity_success_threshold": 3966, - "overall_tool_invocation_correctness_threshold": 0.4833, - "semantic_similarity_channel": 1, - }, - "expectation_level_metrics_thresholds": { - "tool_invocation_parameter_correctness_threshold": 0.5037 - }, + "turn_level_metrics_thresholds": {}, + "expectation_level_metrics_thresholds": {}, "tool_matching_settings": {"extra_tool_call_behavior": 1}, }, "hallucination_metric_behavior": 1, @@ -23314,6 +25125,22 @@ def test_create_evaluation_rest_call_success(request_type): }, "invalid": True, "last_ten_results": {}, + "evaluation_metrics_threshold_override": {}, + "evaluation_metrics_config_override": { + "golden_metrics_config": { + "semantic_similarity_metrics_config": {}, + "tool_correctness_metrics_config": { + "enable_tool_correctness_metrics": True + }, + "step_tool_correctness_metrics_config": {}, + }, + "scenario_metrics_config": { + "user_goal_met_metrics_config": {"enable_user_goal_met_metrics": True}, + "expectations_met_metrics_config": { + "enable_expectations_met_metrics": True + }, + }, + }, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -24119,7 +25946,19 @@ def test_update_evaluation_rest_call_success(request_type): "agent_transfer": {}, "updated_variables": {}, "mock_tool_response": {}, + "no_tool_calls": True, "note": "note_value", + "skip_evaluation": True, + "expectation_level_metrics_thresholds_override": { + "tool_invocation_parameter_correctness_threshold": 0.5037 + }, + "agent_response_semantic_similarity_metrics_config_override": { + "enable_semantic_similarity_metrics": True + }, + "agent_response_hallucination_metrics_config_override": { + "enable_hallucination_metrics": True + }, + "comparison_type": 1, }, } ], @@ -24131,6 +25970,12 @@ def test_update_evaluation_rest_call_success(request_type): "attributes": {}, "child_spans": {}, }, + "turn_level_metrics_thresholds_override": { + "semantic_similarity_success_threshold": 3966, + "overall_tool_invocation_correctness_threshold": 0.4833, + "semantic_similarity_channel": 1, + }, + "hallucination_metric_behavior_override": 1, } ], "evaluation_expectations": [ @@ -24159,6 +26004,7 @@ def test_update_evaluation_rest_call_success(request_type): "evaluation_expectations_value1", "evaluation_expectations_value2", ], + "scenario_execution_mode": 1, }, "name": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4", "display_name": "display_name_value", @@ -24213,6 +26059,7 @@ def test_update_evaluation_rest_call_success(request_type): "observed_tool_response": {}, "observed_agent_response": {}, "observed_agent_transfer": {}, + "observed_payload": {}, "expectation": {}, "outcome": 1, "semantic_similarity_result": { @@ -24254,6 +26101,7 @@ def test_update_evaluation_rest_call_success(request_type): "error_type": 1, "error_message": "error_message_value", "session_id": "session_id_value", + "user_facing_error_message": "user_facing_error_message_value", }, "span_latencies": [ { @@ -24347,17 +26195,11 @@ def test_update_evaluation_rest_call_success(request_type): "app_version_display_name": "app_version_display_name_value", "changelog": "changelog_value", "changelog_create_time": {}, - "execution_state": 1, + "execution_state": 5, "evaluation_metrics_thresholds": { "golden_evaluation_metrics_thresholds": { - "turn_level_metrics_thresholds": { - "semantic_similarity_success_threshold": 3966, - "overall_tool_invocation_correctness_threshold": 0.4833, - "semantic_similarity_channel": 1, - }, - "expectation_level_metrics_thresholds": { - "tool_invocation_parameter_correctness_threshold": 0.5037 - }, + "turn_level_metrics_thresholds": {}, + "expectation_level_metrics_thresholds": {}, "tool_matching_settings": {"extra_tool_call_behavior": 1}, }, "hallucination_metric_behavior": 1, @@ -24376,15 +26218,298 @@ def test_update_evaluation_rest_call_success(request_type): }, "golden_run_method": 1, }, - "invalid": True, - "last_ten_results": {}, + "invalid": True, + "last_ten_results": {}, + "evaluation_metrics_threshold_override": {}, + "evaluation_metrics_config_override": { + "golden_metrics_config": { + "semantic_similarity_metrics_config": {}, + "tool_correctness_metrics_config": { + "enable_tool_correctness_metrics": True + }, + "step_tool_correctness_metrics_config": {}, + }, + "scenario_metrics_config": { + "user_goal_met_metrics_config": {"enable_user_goal_met_metrics": True}, + "expectations_met_metrics_config": { + "enable_expectations_met_metrics": True + }, + }, + }, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = evaluation_service.UpdateEvaluationRequest.meta.fields["evaluation"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["evaluation"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["evaluation"][field])): + del request_init["evaluation"][field][i][subfield] + else: + del request_init["evaluation"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcc_evaluation.Evaluation( + name="name_value", + display_name="display_name_value", + description="description_value", + tags=["tags_value"], + evaluation_datasets=["evaluation_datasets_value"], + created_by="created_by_value", + last_updated_by="last_updated_by_value", + evaluation_runs=["evaluation_runs_value"], + etag="etag_value", + invalid=True, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = gcc_evaluation.Evaluation.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.update_evaluation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcc_evaluation.Evaluation) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.tags == ["tags_value"] + assert response.evaluation_datasets == ["evaluation_datasets_value"] + assert response.created_by == "created_by_value" + assert response.last_updated_by == "last_updated_by_value" + assert response.evaluation_runs == ["evaluation_runs_value"] + assert response.etag == "etag_value" + assert response.invalid is True + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_evaluation_rest_interceptors(null_interceptor): + transport = transports.EvaluationServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.EvaluationServiceRestInterceptor(), + ) + client = EvaluationServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.EvaluationServiceRestInterceptor, "post_update_evaluation" + ) as post, + mock.patch.object( + transports.EvaluationServiceRestInterceptor, + "post_update_evaluation_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.EvaluationServiceRestInterceptor, "pre_update_evaluation" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = evaluation_service.UpdateEvaluationRequest.pb( + evaluation_service.UpdateEvaluationRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = gcc_evaluation.Evaluation.to_json(gcc_evaluation.Evaluation()) + req.return_value.content = return_value + + request = evaluation_service.UpdateEvaluationRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcc_evaluation.Evaluation() + post_with_metadata.return_value = gcc_evaluation.Evaluation(), metadata + + client.update_evaluation( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_update_evaluation_dataset_rest_bad_request( + request_type=evaluation_service.UpdateEvaluationDatasetRequest, +): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "evaluation_dataset": { + "name": "projects/sample1/locations/sample2/apps/sample3/evaluationDatasets/sample4" + } + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.update_evaluation_dataset(request) + + +@pytest.mark.parametrize( + "request_type", + [ + evaluation_service.UpdateEvaluationDatasetRequest, + dict, + ], +) +def test_update_evaluation_dataset_rest_call_success(request_type): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "evaluation_dataset": { + "name": "projects/sample1/locations/sample2/apps/sample3/evaluationDatasets/sample4" + } + } + request_init["evaluation_dataset"] = { + "name": "projects/sample1/locations/sample2/apps/sample3/evaluationDatasets/sample4", + "display_name": "display_name_value", + "evaluations": ["evaluations_value1", "evaluations_value2"], + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "etag": "etag_value", + "created_by": "created_by_value", + "last_updated_by": "last_updated_by_value", + "aggregated_metrics": { + "metrics_by_app_version": [ + { + "app_version_id": "app_version_id_value", + "tool_metrics": [ + {"tool": "tool_value", "pass_count": 1087, "fail_count": 1060} + ], + "semantic_similarity_metrics": [{"score": 0.54}], + "hallucination_metrics": [{"score": 0.54}], + "tool_call_latency_metrics": [ + { + "tool": "tool_value", + "average_latency": {"seconds": 751, "nanos": 543}, + } + ], + "turn_latency_metrics": [{"average_latency": {}}], + "pass_count": 1087, + "fail_count": 1060, + "metrics_by_turn": [ + { + "turn_index": 1088, + "tool_metrics": {}, + "semantic_similarity_metrics": {}, + "hallucination_metrics": {}, + "tool_call_latency_metrics": {}, + "turn_latency_metrics": {}, + } + ], + } + ] + }, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = evaluation_service.UpdateEvaluationRequest.meta.fields["evaluation"] + test_field = evaluation_service.UpdateEvaluationDatasetRequest.meta.fields[ + "evaluation_dataset" + ] def get_message_fields(field): # Given a field which is a message (composite type), return a list with @@ -24412,7 +26537,7 @@ def get_message_fields(field): # For each item in the sample request, create a list of sub fields which are not present at runtime # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["evaluation"].items(): # pragma: NO COVER + for field, value in request_init["evaluation_dataset"].items(): # pragma: NO COVER result = None is_repeated = False # For repeated fields @@ -24442,56 +26567,180 @@ def get_message_fields(field): subfield = subfield_to_delete.get("subfield") if subfield: if field_repeated: - for i in range(0, len(request_init["evaluation"][field])): - del request_init["evaluation"][field][i][subfield] + for i in range(0, len(request_init["evaluation_dataset"][field])): + del request_init["evaluation_dataset"][field][i][subfield] else: - del request_init["evaluation"][field][subfield] + del request_init["evaluation_dataset"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = evaluation.EvaluationDataset( + name="name_value", + display_name="display_name_value", + evaluations=["evaluations_value"], + etag="etag_value", + created_by="created_by_value", + last_updated_by="last_updated_by_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = evaluation.EvaluationDataset.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.update_evaluation_dataset(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, evaluation.EvaluationDataset) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.evaluations == ["evaluations_value"] + assert response.etag == "etag_value" + assert response.created_by == "created_by_value" + assert response.last_updated_by == "last_updated_by_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_evaluation_dataset_rest_interceptors(null_interceptor): + transport = transports.EvaluationServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.EvaluationServiceRestInterceptor(), + ) + client = EvaluationServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.EvaluationServiceRestInterceptor, + "post_update_evaluation_dataset", + ) as post, + mock.patch.object( + transports.EvaluationServiceRestInterceptor, + "post_update_evaluation_dataset_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.EvaluationServiceRestInterceptor, "pre_update_evaluation_dataset" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = evaluation_service.UpdateEvaluationDatasetRequest.pb( + evaluation_service.UpdateEvaluationDatasetRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = evaluation.EvaluationDataset.to_json( + evaluation.EvaluationDataset() + ) + req.return_value.content = return_value + + request = evaluation_service.UpdateEvaluationDatasetRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = evaluation.EvaluationDataset() + post_with_metadata.return_value = evaluation.EvaluationDataset(), metadata + + client.update_evaluation_dataset( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_delete_evaluation_rest_bad_request( + request_type=evaluation_service.DeleteEvaluationRequest, +): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.delete_evaluation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + evaluation_service.DeleteEvaluationRequest, + dict, + ], +) +def test_delete_evaluation_rest_call_success(request_type): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4" + } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = gcc_evaluation.Evaluation( - name="name_value", - display_name="display_name_value", - description="description_value", - tags=["tags_value"], - evaluation_datasets=["evaluation_datasets_value"], - created_by="created_by_value", - last_updated_by="last_updated_by_value", - evaluation_runs=["evaluation_runs_value"], - etag="etag_value", - invalid=True, - ) + return_value = None # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = gcc_evaluation.Evaluation.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + json_return_value = "" response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_evaluation(request) + response = client.delete_evaluation(request) # Establish that the response is the type that we expect. - assert isinstance(response, gcc_evaluation.Evaluation) - assert response.name == "name_value" - assert response.display_name == "display_name_value" - assert response.description == "description_value" - assert response.tags == ["tags_value"] - assert response.evaluation_datasets == ["evaluation_datasets_value"] - assert response.created_by == "created_by_value" - assert response.last_updated_by == "last_updated_by_value" - assert response.evaluation_runs == ["evaluation_runs_value"] - assert response.etag == "etag_value" - assert response.invalid is True + assert response is None @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_evaluation_rest_interceptors(null_interceptor): +def test_delete_evaluation_rest_interceptors(null_interceptor): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -24504,21 +26753,12 @@ def test_update_evaluation_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.EvaluationServiceRestInterceptor, "post_update_evaluation" - ) as post, - mock.patch.object( - transports.EvaluationServiceRestInterceptor, - "post_update_evaluation_with_metadata", - ) as post_with_metadata, - mock.patch.object( - transports.EvaluationServiceRestInterceptor, "pre_update_evaluation" + transports.EvaluationServiceRestInterceptor, "pre_delete_evaluation" ) as pre, ): pre.assert_not_called() - post.assert_not_called() - post_with_metadata.assert_not_called() - pb_message = evaluation_service.UpdateEvaluationRequest.pb( - evaluation_service.UpdateEvaluationRequest() + pb_message = evaluation_service.DeleteEvaluationRequest.pb( + evaluation_service.DeleteEvaluationRequest() ) transcode.return_value = { "method": "post", @@ -24530,19 +26770,15 @@ def test_update_evaluation_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = gcc_evaluation.Evaluation.to_json(gcc_evaluation.Evaluation()) - req.return_value.content = return_value - request = evaluation_service.UpdateEvaluationRequest() + request = evaluation_service.DeleteEvaluationRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = gcc_evaluation.Evaluation() - post_with_metadata.return_value = gcc_evaluation.Evaluation(), metadata - client.update_evaluation( + client.delete_evaluation( request, metadata=[ ("key", "val"), @@ -24551,21 +26787,17 @@ def test_update_evaluation_rest_interceptors(null_interceptor): ) pre.assert_called_once() - post.assert_called_once() - post_with_metadata.assert_called_once() -def test_update_evaluation_dataset_rest_bad_request( - request_type=evaluation_service.UpdateEvaluationDatasetRequest, +def test_delete_evaluation_result_rest_bad_request( + request_type=evaluation_service.DeleteEvaluationResultRequest, ): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "evaluation_dataset": { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluationDatasets/sample4" - } + "name": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4/results/sample5" } request = request_type(**request_init) @@ -24582,175 +26814,161 @@ def test_update_evaluation_dataset_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_evaluation_dataset(request) + client.delete_evaluation_result(request) @pytest.mark.parametrize( "request_type", [ - evaluation_service.UpdateEvaluationDatasetRequest, + evaluation_service.DeleteEvaluationResultRequest, dict, ], ) -def test_update_evaluation_dataset_rest_call_success(request_type): +def test_delete_evaluation_result_rest_call_success(request_type): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "evaluation_dataset": { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluationDatasets/sample4" - } - } - request_init["evaluation_dataset"] = { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluationDatasets/sample4", - "display_name": "display_name_value", - "evaluations": ["evaluations_value1", "evaluations_value2"], - "create_time": {"seconds": 751, "nanos": 543}, - "update_time": {}, - "etag": "etag_value", - "created_by": "created_by_value", - "last_updated_by": "last_updated_by_value", - "aggregated_metrics": { - "metrics_by_app_version": [ - { - "app_version_id": "app_version_id_value", - "tool_metrics": [ - {"tool": "tool_value", "pass_count": 1087, "fail_count": 1060} - ], - "semantic_similarity_metrics": [{"score": 0.54}], - "hallucination_metrics": [{"score": 0.54}], - "tool_call_latency_metrics": [ - { - "tool": "tool_value", - "average_latency": {"seconds": 751, "nanos": 543}, - } - ], - "turn_latency_metrics": [{"average_latency": {}}], - "pass_count": 1087, - "fail_count": 1060, - "metrics_by_turn": [ - { - "turn_index": 1088, - "tool_metrics": {}, - "semantic_similarity_metrics": {}, - "hallucination_metrics": {}, - "tool_call_latency_metrics": {}, - "turn_latency_metrics": {}, - } - ], - } - ] - }, + "name": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4/results/sample5" } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 + request = request_type(**request_init) - # Determine if the message type is proto-plus or protobuf - test_field = evaluation_service.UpdateEvaluationDatasetRequest.meta.fields[ - "evaluation_dataset" - ] + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = "" + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.delete_evaluation_result(request) - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + # Establish that the response is the type that we expect. + assert response is None - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_evaluation_result_rest_interceptors(null_interceptor): + transport = transports.EvaluationServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.EvaluationServiceRestInterceptor(), + ) + client = EvaluationServiceClient(transport=transport) - subfields_not_in_runtime = [] + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.EvaluationServiceRestInterceptor, "pre_delete_evaluation_result" + ) as pre, + ): + pre.assert_not_called() + pb_message = evaluation_service.DeleteEvaluationResultRequest.pb( + evaluation_service.DeleteEvaluationResultRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + request = evaluation_service.DeleteEvaluationResultRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_evaluation_result( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + + +def test_delete_evaluation_dataset_rest_bad_request( + request_type=evaluation_service.DeleteEvaluationDatasetRequest, +): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/apps/sample3/evaluationDatasets/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.delete_evaluation_dataset(request) - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["evaluation_dataset"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) +@pytest.mark.parametrize( + "request_type", + [ + evaluation_service.DeleteEvaluationDatasetRequest, + dict, + ], +) +def test_delete_evaluation_dataset_rest_call_success(request_type): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["evaluation_dataset"][field])): - del request_init["evaluation_dataset"][field][i][subfield] - else: - del request_init["evaluation_dataset"][field][subfield] + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/apps/sample3/evaluationDatasets/sample4" + } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation.EvaluationDataset( - name="name_value", - display_name="display_name_value", - evaluations=["evaluations_value"], - etag="etag_value", - created_by="created_by_value", - last_updated_by="last_updated_by_value", - ) + return_value = None # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = evaluation.EvaluationDataset.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + json_return_value = "" response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_evaluation_dataset(request) + response = client.delete_evaluation_dataset(request) # Establish that the response is the type that we expect. - assert isinstance(response, evaluation.EvaluationDataset) - assert response.name == "name_value" - assert response.display_name == "display_name_value" - assert response.evaluations == ["evaluations_value"] - assert response.etag == "etag_value" - assert response.created_by == "created_by_value" - assert response.last_updated_by == "last_updated_by_value" + assert response is None @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_evaluation_dataset_rest_interceptors(null_interceptor): +def test_delete_evaluation_dataset_rest_interceptors(null_interceptor): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -24763,22 +26981,12 @@ def test_update_evaluation_dataset_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.EvaluationServiceRestInterceptor, - "post_update_evaluation_dataset", - ) as post, - mock.patch.object( - transports.EvaluationServiceRestInterceptor, - "post_update_evaluation_dataset_with_metadata", - ) as post_with_metadata, - mock.patch.object( - transports.EvaluationServiceRestInterceptor, "pre_update_evaluation_dataset" + transports.EvaluationServiceRestInterceptor, "pre_delete_evaluation_dataset" ) as pre, ): pre.assert_not_called() - post.assert_not_called() - post_with_metadata.assert_not_called() - pb_message = evaluation_service.UpdateEvaluationDatasetRequest.pb( - evaluation_service.UpdateEvaluationDatasetRequest() + pb_message = evaluation_service.DeleteEvaluationDatasetRequest.pb( + evaluation_service.DeleteEvaluationDatasetRequest() ) transcode.return_value = { "method": "post", @@ -24790,21 +26998,15 @@ def test_update_evaluation_dataset_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = evaluation.EvaluationDataset.to_json( - evaluation.EvaluationDataset() - ) - req.return_value.content = return_value - request = evaluation_service.UpdateEvaluationDatasetRequest() + request = evaluation_service.DeleteEvaluationDatasetRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = evaluation.EvaluationDataset() - post_with_metadata.return_value = evaluation.EvaluationDataset(), metadata - client.update_evaluation_dataset( + client.delete_evaluation_dataset( request, metadata=[ ("key", "val"), @@ -24813,19 +27015,17 @@ def test_update_evaluation_dataset_rest_interceptors(null_interceptor): ) pre.assert_called_once() - post.assert_called_once() - post_with_metadata.assert_called_once() -def test_delete_evaluation_rest_bad_request( - request_type=evaluation_service.DeleteEvaluationRequest, +def test_delete_evaluation_run_rest_bad_request( + request_type=evaluation_service.DeleteEvaluationRunRequest, ): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4" + "name": "projects/sample1/locations/sample2/apps/sample3/evaluationRuns/sample4" } request = request_type(**request_init) @@ -24842,47 +27042,47 @@ def test_delete_evaluation_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_evaluation(request) + client.delete_evaluation_run(request) @pytest.mark.parametrize( "request_type", [ - evaluation_service.DeleteEvaluationRequest, + evaluation_service.DeleteEvaluationRunRequest, dict, ], ) -def test_delete_evaluation_rest_call_success(request_type): +def test_delete_evaluation_run_rest_call_success(request_type): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4" + "name": "projects/sample1/locations/sample2/apps/sample3/evaluationRuns/sample4" } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = None + return_value = operations_pb2.Operation(name="operations/spam") # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 - json_return_value = "" + json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_evaluation(request) + response = client.delete_evaluation_run(request) # Establish that the response is the type that we expect. - assert response is None + json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_evaluation_rest_interceptors(null_interceptor): +def test_delete_evaluation_run_rest_interceptors(null_interceptor): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -24894,13 +27094,23 @@ def test_delete_evaluation_rest_interceptors(null_interceptor): with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.EvaluationServiceRestInterceptor, "pre_delete_evaluation" + transports.EvaluationServiceRestInterceptor, "post_delete_evaluation_run" + ) as post, + mock.patch.object( + transports.EvaluationServiceRestInterceptor, + "post_delete_evaluation_run_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.EvaluationServiceRestInterceptor, "pre_delete_evaluation_run" ) as pre, ): pre.assert_not_called() - pb_message = evaluation_service.DeleteEvaluationRequest.pb( - evaluation_service.DeleteEvaluationRequest() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = evaluation_service.DeleteEvaluationRunRequest.pb( + evaluation_service.DeleteEvaluationRunRequest() ) transcode.return_value = { "method": "post", @@ -24912,15 +27122,19 @@ def test_delete_evaluation_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value - request = evaluation_service.DeleteEvaluationRequest() + request = evaluation_service.DeleteEvaluationRunRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.delete_evaluation( + client.delete_evaluation_run( request, metadata=[ ("key", "val"), @@ -24929,17 +27143,19 @@ def test_delete_evaluation_rest_interceptors(null_interceptor): ) pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() -def test_delete_evaluation_result_rest_bad_request( - request_type=evaluation_service.DeleteEvaluationResultRequest, +def test_get_evaluation_rest_bad_request( + request_type=evaluation_service.GetEvaluationRequest, ): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4/results/sample5" + "name": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4" } request = request_type(**request_init) @@ -24956,47 +27172,71 @@ def test_delete_evaluation_result_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_evaluation_result(request) + client.get_evaluation(request) @pytest.mark.parametrize( "request_type", [ - evaluation_service.DeleteEvaluationResultRequest, + evaluation_service.GetEvaluationRequest, dict, ], ) -def test_delete_evaluation_result_rest_call_success(request_type): +def test_get_evaluation_rest_call_success(request_type): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4/results/sample5" + "name": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4" } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = None + return_value = evaluation.Evaluation( + name="name_value", + display_name="display_name_value", + description="description_value", + tags=["tags_value"], + evaluation_datasets=["evaluation_datasets_value"], + created_by="created_by_value", + last_updated_by="last_updated_by_value", + evaluation_runs=["evaluation_runs_value"], + etag="etag_value", + invalid=True, + ) # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 - json_return_value = "" + + # Convert return value to protobuf type + return_value = evaluation.Evaluation.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_evaluation_result(request) + response = client.get_evaluation(request) # Establish that the response is the type that we expect. - assert response is None + assert isinstance(response, evaluation.Evaluation) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.tags == ["tags_value"] + assert response.evaluation_datasets == ["evaluation_datasets_value"] + assert response.created_by == "created_by_value" + assert response.last_updated_by == "last_updated_by_value" + assert response.evaluation_runs == ["evaluation_runs_value"] + assert response.etag == "etag_value" + assert response.invalid is True @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_evaluation_result_rest_interceptors(null_interceptor): +def test_get_evaluation_rest_interceptors(null_interceptor): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -25009,12 +27249,21 @@ def test_delete_evaluation_result_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.EvaluationServiceRestInterceptor, "pre_delete_evaluation_result" + transports.EvaluationServiceRestInterceptor, "post_get_evaluation" + ) as post, + mock.patch.object( + transports.EvaluationServiceRestInterceptor, + "post_get_evaluation_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.EvaluationServiceRestInterceptor, "pre_get_evaluation" ) as pre, ): pre.assert_not_called() - pb_message = evaluation_service.DeleteEvaluationResultRequest.pb( - evaluation_service.DeleteEvaluationResultRequest() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = evaluation_service.GetEvaluationRequest.pb( + evaluation_service.GetEvaluationRequest() ) transcode.return_value = { "method": "post", @@ -25026,15 +27275,19 @@ def test_delete_evaluation_result_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = evaluation.Evaluation.to_json(evaluation.Evaluation()) + req.return_value.content = return_value - request = evaluation_service.DeleteEvaluationResultRequest() + request = evaluation_service.GetEvaluationRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata + post.return_value = evaluation.Evaluation() + post_with_metadata.return_value = evaluation.Evaluation(), metadata - client.delete_evaluation_result( + client.get_evaluation( request, metadata=[ ("key", "val"), @@ -25043,17 +27296,19 @@ def test_delete_evaluation_result_rest_interceptors(null_interceptor): ) pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() -def test_delete_evaluation_dataset_rest_bad_request( - request_type=evaluation_service.DeleteEvaluationDatasetRequest, +def test_get_evaluation_result_rest_bad_request( + request_type=evaluation_service.GetEvaluationResultRequest, ): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluationDatasets/sample4" + "name": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4/results/sample5" } request = request_type(**request_init) @@ -25070,47 +27325,71 @@ def test_delete_evaluation_dataset_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_evaluation_dataset(request) + client.get_evaluation_result(request) @pytest.mark.parametrize( "request_type", [ - evaluation_service.DeleteEvaluationDatasetRequest, + evaluation_service.GetEvaluationResultRequest, dict, ], ) -def test_delete_evaluation_dataset_rest_call_success(request_type): +def test_get_evaluation_result_rest_call_success(request_type): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluationDatasets/sample4" + "name": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4/results/sample5" } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = None + return_value = evaluation.EvaluationResult( + name="name_value", + display_name="display_name_value", + evaluation_status=evaluation.EvaluationResult.Outcome.PASS, + evaluation_run="evaluation_run_value", + initiated_by="initiated_by_value", + app_version="app_version_value", + app_version_display_name="app_version_display_name_value", + changelog="changelog_value", + execution_state=evaluation.EvaluationResult.ExecutionState.QUEUED, + golden_run_method=golden_run.GoldenRunMethod.STABLE, + ) # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 - json_return_value = "" + + # Convert return value to protobuf type + return_value = evaluation.EvaluationResult.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_evaluation_dataset(request) + response = client.get_evaluation_result(request) # Establish that the response is the type that we expect. - assert response is None + assert isinstance(response, evaluation.EvaluationResult) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.evaluation_status == evaluation.EvaluationResult.Outcome.PASS + assert response.evaluation_run == "evaluation_run_value" + assert response.initiated_by == "initiated_by_value" + assert response.app_version == "app_version_value" + assert response.app_version_display_name == "app_version_display_name_value" + assert response.changelog == "changelog_value" + assert response.execution_state == evaluation.EvaluationResult.ExecutionState.QUEUED + assert response.golden_run_method == golden_run.GoldenRunMethod.STABLE @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_evaluation_dataset_rest_interceptors(null_interceptor): +def test_get_evaluation_result_rest_interceptors(null_interceptor): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -25123,12 +27402,21 @@ def test_delete_evaluation_dataset_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.EvaluationServiceRestInterceptor, "pre_delete_evaluation_dataset" + transports.EvaluationServiceRestInterceptor, "post_get_evaluation_result" + ) as post, + mock.patch.object( + transports.EvaluationServiceRestInterceptor, + "post_get_evaluation_result_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.EvaluationServiceRestInterceptor, "pre_get_evaluation_result" ) as pre, ): pre.assert_not_called() - pb_message = evaluation_service.DeleteEvaluationDatasetRequest.pb( - evaluation_service.DeleteEvaluationDatasetRequest() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = evaluation_service.GetEvaluationResultRequest.pb( + evaluation_service.GetEvaluationResultRequest() ) transcode.return_value = { "method": "post", @@ -25140,15 +27428,21 @@ def test_delete_evaluation_dataset_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = evaluation.EvaluationResult.to_json( + evaluation.EvaluationResult() + ) + req.return_value.content = return_value - request = evaluation_service.DeleteEvaluationDatasetRequest() + request = evaluation_service.GetEvaluationResultRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata + post.return_value = evaluation.EvaluationResult() + post_with_metadata.return_value = evaluation.EvaluationResult(), metadata - client.delete_evaluation_dataset( + client.get_evaluation_result( request, metadata=[ ("key", "val"), @@ -25157,17 +27451,19 @@ def test_delete_evaluation_dataset_rest_interceptors(null_interceptor): ) pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() -def test_delete_evaluation_run_rest_bad_request( - request_type=evaluation_service.DeleteEvaluationRunRequest, +def test_get_evaluation_dataset_rest_bad_request( + request_type=evaluation_service.GetEvaluationDatasetRequest, ): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluationRuns/sample4" + "name": "projects/sample1/locations/sample2/apps/sample3/evaluationDatasets/sample4" } request = request_type(**request_init) @@ -25184,47 +27480,63 @@ def test_delete_evaluation_run_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_evaluation_run(request) + client.get_evaluation_dataset(request) @pytest.mark.parametrize( "request_type", [ - evaluation_service.DeleteEvaluationRunRequest, + evaluation_service.GetEvaluationDatasetRequest, dict, ], ) -def test_delete_evaluation_run_rest_call_success(request_type): +def test_get_evaluation_dataset_rest_call_success(request_type): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluationRuns/sample4" + "name": "projects/sample1/locations/sample2/apps/sample3/evaluationDatasets/sample4" } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = evaluation.EvaluationDataset( + name="name_value", + display_name="display_name_value", + evaluations=["evaluations_value"], + etag="etag_value", + created_by="created_by_value", + last_updated_by="last_updated_by_value", + ) # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = evaluation.EvaluationDataset.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_evaluation_run(request) + response = client.get_evaluation_dataset(request) # Establish that the response is the type that we expect. - json_return_value = json_format.MessageToJson(return_value) + assert isinstance(response, evaluation.EvaluationDataset) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.evaluations == ["evaluations_value"] + assert response.etag == "etag_value" + assert response.created_by == "created_by_value" + assert response.last_updated_by == "last_updated_by_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_evaluation_run_rest_interceptors(null_interceptor): +def test_get_evaluation_dataset_rest_interceptors(null_interceptor): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -25236,23 +27548,22 @@ def test_delete_evaluation_run_rest_interceptors(null_interceptor): with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, - mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.EvaluationServiceRestInterceptor, "post_delete_evaluation_run" + transports.EvaluationServiceRestInterceptor, "post_get_evaluation_dataset" ) as post, mock.patch.object( transports.EvaluationServiceRestInterceptor, - "post_delete_evaluation_run_with_metadata", + "post_get_evaluation_dataset_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.EvaluationServiceRestInterceptor, "pre_delete_evaluation_run" + transports.EvaluationServiceRestInterceptor, "pre_get_evaluation_dataset" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = evaluation_service.DeleteEvaluationRunRequest.pb( - evaluation_service.DeleteEvaluationRunRequest() + pb_message = evaluation_service.GetEvaluationDatasetRequest.pb( + evaluation_service.GetEvaluationDatasetRequest() ) transcode.return_value = { "method": "post", @@ -25264,19 +27575,21 @@ def test_delete_evaluation_run_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = json_format.MessageToJson(operations_pb2.Operation()) + return_value = evaluation.EvaluationDataset.to_json( + evaluation.EvaluationDataset() + ) req.return_value.content = return_value - request = evaluation_service.DeleteEvaluationRunRequest() + request = evaluation_service.GetEvaluationDatasetRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() - post_with_metadata.return_value = operations_pb2.Operation(), metadata + post.return_value = evaluation.EvaluationDataset() + post_with_metadata.return_value = evaluation.EvaluationDataset(), metadata - client.delete_evaluation_run( + client.get_evaluation_dataset( request, metadata=[ ("key", "val"), @@ -25289,15 +27602,15 @@ def test_delete_evaluation_run_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_get_evaluation_rest_bad_request( - request_type=evaluation_service.GetEvaluationRequest, +def test_get_evaluation_run_rest_bad_request( + request_type=evaluation_service.GetEvaluationRunRequest, ): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4" + "name": "projects/sample1/locations/sample2/apps/sample3/evaluationRuns/sample4" } request = request_type(**request_init) @@ -25314,41 +27627,46 @@ def test_get_evaluation_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_evaluation(request) + client.get_evaluation_run(request) @pytest.mark.parametrize( "request_type", [ - evaluation_service.GetEvaluationRequest, + evaluation_service.GetEvaluationRunRequest, dict, ], ) -def test_get_evaluation_rest_call_success(request_type): +def test_get_evaluation_run_rest_call_success(request_type): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4" + "name": "projects/sample1/locations/sample2/apps/sample3/evaluationRuns/sample4" } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation.Evaluation( + return_value = evaluation.EvaluationRun( name="name_value", display_name="display_name_value", - description="description_value", - tags=["tags_value"], - evaluation_datasets=["evaluation_datasets_value"], - created_by="created_by_value", - last_updated_by="last_updated_by_value", - evaluation_runs=["evaluation_runs_value"], - etag="etag_value", - invalid=True, + evaluation_results=["evaluation_results_value"], + initiated_by="initiated_by_value", + app_version="app_version_value", + app_version_display_name="app_version_display_name_value", + changelog="changelog_value", + evaluations=["evaluations_value"], + evaluation_dataset="evaluation_dataset_value", + evaluation_type=evaluation.EvaluationRun.EvaluationType.GOLDEN, + state=evaluation.EvaluationRun.EvaluationRunState.QUEUED, + run_count=989, + scheduled_evaluation_run="scheduled_evaluation_run_value", + golden_run_method=golden_run.GoldenRunMethod.STABLE, + operation="operation_value", ) # Wrap the value into a proper Response obj @@ -25356,29 +27674,34 @@ def test_get_evaluation_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation.Evaluation.pb(return_value) + return_value = evaluation.EvaluationRun.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_evaluation(request) + response = client.get_evaluation_run(request) # Establish that the response is the type that we expect. - assert isinstance(response, evaluation.Evaluation) + assert isinstance(response, evaluation.EvaluationRun) assert response.name == "name_value" assert response.display_name == "display_name_value" - assert response.description == "description_value" - assert response.tags == ["tags_value"] - assert response.evaluation_datasets == ["evaluation_datasets_value"] - assert response.created_by == "created_by_value" - assert response.last_updated_by == "last_updated_by_value" - assert response.evaluation_runs == ["evaluation_runs_value"] - assert response.etag == "etag_value" - assert response.invalid is True + assert response.evaluation_results == ["evaluation_results_value"] + assert response.initiated_by == "initiated_by_value" + assert response.app_version == "app_version_value" + assert response.app_version_display_name == "app_version_display_name_value" + assert response.changelog == "changelog_value" + assert response.evaluations == ["evaluations_value"] + assert response.evaluation_dataset == "evaluation_dataset_value" + assert response.evaluation_type == evaluation.EvaluationRun.EvaluationType.GOLDEN + assert response.state == evaluation.EvaluationRun.EvaluationRunState.QUEUED + assert response.run_count == 989 + assert response.scheduled_evaluation_run == "scheduled_evaluation_run_value" + assert response.golden_run_method == golden_run.GoldenRunMethod.STABLE + assert response.operation == "operation_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_evaluation_rest_interceptors(null_interceptor): +def test_get_evaluation_run_rest_interceptors(null_interceptor): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -25391,21 +27714,21 @@ def test_get_evaluation_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.EvaluationServiceRestInterceptor, "post_get_evaluation" + transports.EvaluationServiceRestInterceptor, "post_get_evaluation_run" ) as post, mock.patch.object( transports.EvaluationServiceRestInterceptor, - "post_get_evaluation_with_metadata", + "post_get_evaluation_run_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.EvaluationServiceRestInterceptor, "pre_get_evaluation" + transports.EvaluationServiceRestInterceptor, "pre_get_evaluation_run" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = evaluation_service.GetEvaluationRequest.pb( - evaluation_service.GetEvaluationRequest() + pb_message = evaluation_service.GetEvaluationRunRequest.pb( + evaluation_service.GetEvaluationRunRequest() ) transcode.return_value = { "method": "post", @@ -25417,19 +27740,19 @@ def test_get_evaluation_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = evaluation.Evaluation.to_json(evaluation.Evaluation()) + return_value = evaluation.EvaluationRun.to_json(evaluation.EvaluationRun()) req.return_value.content = return_value - request = evaluation_service.GetEvaluationRequest() + request = evaluation_service.GetEvaluationRunRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = evaluation.Evaluation() - post_with_metadata.return_value = evaluation.Evaluation(), metadata + post.return_value = evaluation.EvaluationRun() + post_with_metadata.return_value = evaluation.EvaluationRun(), metadata - client.get_evaluation( + client.get_evaluation_run( request, metadata=[ ("key", "val"), @@ -25442,16 +27765,14 @@ def test_get_evaluation_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_get_evaluation_result_rest_bad_request( - request_type=evaluation_service.GetEvaluationResultRequest, +def test_list_evaluations_rest_bad_request( + request_type=evaluation_service.ListEvaluationsRequest, ): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4/results/sample5" - } + request_init = {"parent": "projects/sample1/locations/sample2/apps/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -25467,41 +27788,30 @@ def test_get_evaluation_result_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_evaluation_result(request) + client.list_evaluations(request) @pytest.mark.parametrize( "request_type", [ - evaluation_service.GetEvaluationResultRequest, + evaluation_service.ListEvaluationsRequest, dict, ], ) -def test_get_evaluation_result_rest_call_success(request_type): +def test_list_evaluations_rest_call_success(request_type): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4/results/sample5" - } + request_init = {"parent": "projects/sample1/locations/sample2/apps/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation.EvaluationResult( - name="name_value", - display_name="display_name_value", - evaluation_status=evaluation.EvaluationResult.Outcome.PASS, - evaluation_run="evaluation_run_value", - initiated_by="initiated_by_value", - app_version="app_version_value", - app_version_display_name="app_version_display_name_value", - changelog="changelog_value", - execution_state=evaluation.EvaluationResult.ExecutionState.RUNNING, - golden_run_method=golden_run.GoldenRunMethod.STABLE, + return_value = evaluation_service.ListEvaluationsResponse( + next_page_token="next_page_token_value", ) # Wrap the value into a proper Response obj @@ -25509,31 +27819,20 @@ def test_get_evaluation_result_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation.EvaluationResult.pb(return_value) + return_value = evaluation_service.ListEvaluationsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_evaluation_result(request) + response = client.list_evaluations(request) # Establish that the response is the type that we expect. - assert isinstance(response, evaluation.EvaluationResult) - assert response.name == "name_value" - assert response.display_name == "display_name_value" - assert response.evaluation_status == evaluation.EvaluationResult.Outcome.PASS - assert response.evaluation_run == "evaluation_run_value" - assert response.initiated_by == "initiated_by_value" - assert response.app_version == "app_version_value" - assert response.app_version_display_name == "app_version_display_name_value" - assert response.changelog == "changelog_value" - assert ( - response.execution_state == evaluation.EvaluationResult.ExecutionState.RUNNING - ) - assert response.golden_run_method == golden_run.GoldenRunMethod.STABLE + assert isinstance(response, pagers.ListEvaluationsPager) + assert response.next_page_token == "next_page_token_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_evaluation_result_rest_interceptors(null_interceptor): +def test_list_evaluations_rest_interceptors(null_interceptor): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -25546,21 +27845,21 @@ def test_get_evaluation_result_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.EvaluationServiceRestInterceptor, "post_get_evaluation_result" + transports.EvaluationServiceRestInterceptor, "post_list_evaluations" ) as post, mock.patch.object( transports.EvaluationServiceRestInterceptor, - "post_get_evaluation_result_with_metadata", + "post_list_evaluations_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.EvaluationServiceRestInterceptor, "pre_get_evaluation_result" + transports.EvaluationServiceRestInterceptor, "pre_list_evaluations" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = evaluation_service.GetEvaluationResultRequest.pb( - evaluation_service.GetEvaluationResultRequest() + pb_message = evaluation_service.ListEvaluationsRequest.pb( + evaluation_service.ListEvaluationsRequest() ) transcode.return_value = { "method": "post", @@ -25572,21 +27871,24 @@ def test_get_evaluation_result_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = evaluation.EvaluationResult.to_json( - evaluation.EvaluationResult() + return_value = evaluation_service.ListEvaluationsResponse.to_json( + evaluation_service.ListEvaluationsResponse() ) req.return_value.content = return_value - request = evaluation_service.GetEvaluationResultRequest() + request = evaluation_service.ListEvaluationsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = evaluation.EvaluationResult() - post_with_metadata.return_value = evaluation.EvaluationResult(), metadata + post.return_value = evaluation_service.ListEvaluationsResponse() + post_with_metadata.return_value = ( + evaluation_service.ListEvaluationsResponse(), + metadata, + ) - client.get_evaluation_result( + client.list_evaluations( request, metadata=[ ("key", "val"), @@ -25599,15 +27901,15 @@ def test_get_evaluation_result_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_get_evaluation_dataset_rest_bad_request( - request_type=evaluation_service.GetEvaluationDatasetRequest, +def test_list_evaluation_results_rest_bad_request( + request_type=evaluation_service.ListEvaluationResultsRequest, ): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluationDatasets/sample4" + "parent": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4" } request = request_type(**request_init) @@ -25624,37 +27926,32 @@ def test_get_evaluation_dataset_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_evaluation_dataset(request) + client.list_evaluation_results(request) @pytest.mark.parametrize( "request_type", [ - evaluation_service.GetEvaluationDatasetRequest, + evaluation_service.ListEvaluationResultsRequest, dict, ], ) -def test_get_evaluation_dataset_rest_call_success(request_type): +def test_list_evaluation_results_rest_call_success(request_type): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluationDatasets/sample4" + "parent": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4" } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation.EvaluationDataset( - name="name_value", - display_name="display_name_value", - evaluations=["evaluations_value"], - etag="etag_value", - created_by="created_by_value", - last_updated_by="last_updated_by_value", + return_value = evaluation_service.ListEvaluationResultsResponse( + next_page_token="next_page_token_value", ) # Wrap the value into a proper Response obj @@ -25662,25 +27959,20 @@ def test_get_evaluation_dataset_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation.EvaluationDataset.pb(return_value) + return_value = evaluation_service.ListEvaluationResultsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_evaluation_dataset(request) + response = client.list_evaluation_results(request) # Establish that the response is the type that we expect. - assert isinstance(response, evaluation.EvaluationDataset) - assert response.name == "name_value" - assert response.display_name == "display_name_value" - assert response.evaluations == ["evaluations_value"] - assert response.etag == "etag_value" - assert response.created_by == "created_by_value" - assert response.last_updated_by == "last_updated_by_value" + assert isinstance(response, pagers.ListEvaluationResultsPager) + assert response.next_page_token == "next_page_token_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_evaluation_dataset_rest_interceptors(null_interceptor): +def test_list_evaluation_results_rest_interceptors(null_interceptor): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -25693,21 +27985,21 @@ def test_get_evaluation_dataset_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.EvaluationServiceRestInterceptor, "post_get_evaluation_dataset" + transports.EvaluationServiceRestInterceptor, "post_list_evaluation_results" ) as post, mock.patch.object( transports.EvaluationServiceRestInterceptor, - "post_get_evaluation_dataset_with_metadata", + "post_list_evaluation_results_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.EvaluationServiceRestInterceptor, "pre_get_evaluation_dataset" + transports.EvaluationServiceRestInterceptor, "pre_list_evaluation_results" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = evaluation_service.GetEvaluationDatasetRequest.pb( - evaluation_service.GetEvaluationDatasetRequest() + pb_message = evaluation_service.ListEvaluationResultsRequest.pb( + evaluation_service.ListEvaluationResultsRequest() ) transcode.return_value = { "method": "post", @@ -25719,21 +28011,24 @@ def test_get_evaluation_dataset_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = evaluation.EvaluationDataset.to_json( - evaluation.EvaluationDataset() + return_value = evaluation_service.ListEvaluationResultsResponse.to_json( + evaluation_service.ListEvaluationResultsResponse() ) req.return_value.content = return_value - request = evaluation_service.GetEvaluationDatasetRequest() + request = evaluation_service.ListEvaluationResultsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = evaluation.EvaluationDataset() - post_with_metadata.return_value = evaluation.EvaluationDataset(), metadata + post.return_value = evaluation_service.ListEvaluationResultsResponse() + post_with_metadata.return_value = ( + evaluation_service.ListEvaluationResultsResponse(), + metadata, + ) - client.get_evaluation_dataset( + client.list_evaluation_results( request, metadata=[ ("key", "val"), @@ -25746,16 +28041,14 @@ def test_get_evaluation_dataset_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_get_evaluation_run_rest_bad_request( - request_type=evaluation_service.GetEvaluationRunRequest, +def test_list_evaluation_datasets_rest_bad_request( + request_type=evaluation_service.ListEvaluationDatasetsRequest, ): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluationRuns/sample4" - } + request_init = {"parent": "projects/sample1/locations/sample2/apps/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -25771,45 +28064,30 @@ def test_get_evaluation_run_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_evaluation_run(request) + client.list_evaluation_datasets(request) @pytest.mark.parametrize( "request_type", [ - evaluation_service.GetEvaluationRunRequest, + evaluation_service.ListEvaluationDatasetsRequest, dict, ], ) -def test_get_evaluation_run_rest_call_success(request_type): +def test_list_evaluation_datasets_rest_call_success(request_type): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluationRuns/sample4" - } + request_init = {"parent": "projects/sample1/locations/sample2/apps/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation.EvaluationRun( - name="name_value", - display_name="display_name_value", - evaluation_results=["evaluation_results_value"], - initiated_by="initiated_by_value", - app_version="app_version_value", - app_version_display_name="app_version_display_name_value", - changelog="changelog_value", - evaluations=["evaluations_value"], - evaluation_dataset="evaluation_dataset_value", - evaluation_type=evaluation.EvaluationRun.EvaluationType.GOLDEN, - state=evaluation.EvaluationRun.EvaluationRunState.RUNNING, - run_count=989, - scheduled_evaluation_run="scheduled_evaluation_run_value", - golden_run_method=golden_run.GoldenRunMethod.STABLE, + return_value = evaluation_service.ListEvaluationDatasetsResponse( + next_page_token="next_page_token_value", ) # Wrap the value into a proper Response obj @@ -25817,33 +28095,22 @@ def test_get_evaluation_run_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation.EvaluationRun.pb(return_value) + return_value = evaluation_service.ListEvaluationDatasetsResponse.pb( + return_value + ) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_evaluation_run(request) + response = client.list_evaluation_datasets(request) # Establish that the response is the type that we expect. - assert isinstance(response, evaluation.EvaluationRun) - assert response.name == "name_value" - assert response.display_name == "display_name_value" - assert response.evaluation_results == ["evaluation_results_value"] - assert response.initiated_by == "initiated_by_value" - assert response.app_version == "app_version_value" - assert response.app_version_display_name == "app_version_display_name_value" - assert response.changelog == "changelog_value" - assert response.evaluations == ["evaluations_value"] - assert response.evaluation_dataset == "evaluation_dataset_value" - assert response.evaluation_type == evaluation.EvaluationRun.EvaluationType.GOLDEN - assert response.state == evaluation.EvaluationRun.EvaluationRunState.RUNNING - assert response.run_count == 989 - assert response.scheduled_evaluation_run == "scheduled_evaluation_run_value" - assert response.golden_run_method == golden_run.GoldenRunMethod.STABLE + assert isinstance(response, pagers.ListEvaluationDatasetsPager) + assert response.next_page_token == "next_page_token_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_evaluation_run_rest_interceptors(null_interceptor): +def test_list_evaluation_datasets_rest_interceptors(null_interceptor): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -25856,21 +28123,21 @@ def test_get_evaluation_run_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.EvaluationServiceRestInterceptor, "post_get_evaluation_run" + transports.EvaluationServiceRestInterceptor, "post_list_evaluation_datasets" ) as post, mock.patch.object( transports.EvaluationServiceRestInterceptor, - "post_get_evaluation_run_with_metadata", + "post_list_evaluation_datasets_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.EvaluationServiceRestInterceptor, "pre_get_evaluation_run" + transports.EvaluationServiceRestInterceptor, "pre_list_evaluation_datasets" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = evaluation_service.GetEvaluationRunRequest.pb( - evaluation_service.GetEvaluationRunRequest() + pb_message = evaluation_service.ListEvaluationDatasetsRequest.pb( + evaluation_service.ListEvaluationDatasetsRequest() ) transcode.return_value = { "method": "post", @@ -25882,19 +28149,24 @@ def test_get_evaluation_run_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = evaluation.EvaluationRun.to_json(evaluation.EvaluationRun()) + return_value = evaluation_service.ListEvaluationDatasetsResponse.to_json( + evaluation_service.ListEvaluationDatasetsResponse() + ) req.return_value.content = return_value - request = evaluation_service.GetEvaluationRunRequest() + request = evaluation_service.ListEvaluationDatasetsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = evaluation.EvaluationRun() - post_with_metadata.return_value = evaluation.EvaluationRun(), metadata + post.return_value = evaluation_service.ListEvaluationDatasetsResponse() + post_with_metadata.return_value = ( + evaluation_service.ListEvaluationDatasetsResponse(), + metadata, + ) - client.get_evaluation_run( + client.list_evaluation_datasets( request, metadata=[ ("key", "val"), @@ -25907,8 +28179,8 @@ def test_get_evaluation_run_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_evaluations_rest_bad_request( - request_type=evaluation_service.ListEvaluationsRequest, +def test_list_evaluation_runs_rest_bad_request( + request_type=evaluation_service.ListEvaluationRunsRequest, ): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" @@ -25930,17 +28202,17 @@ def test_list_evaluations_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_evaluations(request) + client.list_evaluation_runs(request) @pytest.mark.parametrize( "request_type", [ - evaluation_service.ListEvaluationsRequest, + evaluation_service.ListEvaluationRunsRequest, dict, ], ) -def test_list_evaluations_rest_call_success(request_type): +def test_list_evaluation_runs_rest_call_success(request_type): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -25952,7 +28224,7 @@ def test_list_evaluations_rest_call_success(request_type): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation_service.ListEvaluationsResponse( + return_value = evaluation_service.ListEvaluationRunsResponse( next_page_token="next_page_token_value", ) @@ -25961,20 +28233,20 @@ def test_list_evaluations_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation_service.ListEvaluationsResponse.pb(return_value) + return_value = evaluation_service.ListEvaluationRunsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_evaluations(request) + response = client.list_evaluation_runs(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListEvaluationsPager) + assert isinstance(response, pagers.ListEvaluationRunsPager) assert response.next_page_token == "next_page_token_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_evaluations_rest_interceptors(null_interceptor): +def test_list_evaluation_runs_rest_interceptors(null_interceptor): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -25987,21 +28259,21 @@ def test_list_evaluations_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.EvaluationServiceRestInterceptor, "post_list_evaluations" + transports.EvaluationServiceRestInterceptor, "post_list_evaluation_runs" ) as post, mock.patch.object( transports.EvaluationServiceRestInterceptor, - "post_list_evaluations_with_metadata", + "post_list_evaluation_runs_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.EvaluationServiceRestInterceptor, "pre_list_evaluations" + transports.EvaluationServiceRestInterceptor, "pre_list_evaluation_runs" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = evaluation_service.ListEvaluationsRequest.pb( - evaluation_service.ListEvaluationsRequest() + pb_message = evaluation_service.ListEvaluationRunsRequest.pb( + evaluation_service.ListEvaluationRunsRequest() ) transcode.return_value = { "method": "post", @@ -26013,24 +28285,24 @@ def test_list_evaluations_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = evaluation_service.ListEvaluationsResponse.to_json( - evaluation_service.ListEvaluationsResponse() + return_value = evaluation_service.ListEvaluationRunsResponse.to_json( + evaluation_service.ListEvaluationRunsResponse() ) req.return_value.content = return_value - request = evaluation_service.ListEvaluationsRequest() + request = evaluation_service.ListEvaluationRunsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = evaluation_service.ListEvaluationsResponse() + post.return_value = evaluation_service.ListEvaluationRunsResponse() post_with_metadata.return_value = ( - evaluation_service.ListEvaluationsResponse(), + evaluation_service.ListEvaluationRunsResponse(), metadata, ) - client.list_evaluations( + client.list_evaluation_runs( request, metadata=[ ("key", "val"), @@ -26043,16 +28315,14 @@ def test_list_evaluations_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_evaluation_results_rest_bad_request( - request_type=evaluation_service.ListEvaluationResultsRequest, +def test_list_evaluation_expectations_rest_bad_request( + request_type=evaluation_service.ListEvaluationExpectationsRequest, ): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "parent": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4" - } + request_init = {"parent": "projects/sample1/locations/sample2/apps/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -26068,31 +28338,29 @@ def test_list_evaluation_results_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_evaluation_results(request) + client.list_evaluation_expectations(request) @pytest.mark.parametrize( "request_type", [ - evaluation_service.ListEvaluationResultsRequest, + evaluation_service.ListEvaluationExpectationsRequest, dict, ], ) -def test_list_evaluation_results_rest_call_success(request_type): +def test_list_evaluation_expectations_rest_call_success(request_type): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "parent": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4" - } + request_init = {"parent": "projects/sample1/locations/sample2/apps/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation_service.ListEvaluationResultsResponse( + return_value = evaluation_service.ListEvaluationExpectationsResponse( next_page_token="next_page_token_value", ) @@ -26101,20 +28369,22 @@ def test_list_evaluation_results_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation_service.ListEvaluationResultsResponse.pb(return_value) + return_value = evaluation_service.ListEvaluationExpectationsResponse.pb( + return_value + ) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_evaluation_results(request) + response = client.list_evaluation_expectations(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListEvaluationResultsPager) + assert isinstance(response, pagers.ListEvaluationExpectationsPager) assert response.next_page_token == "next_page_token_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_evaluation_results_rest_interceptors(null_interceptor): +def test_list_evaluation_expectations_rest_interceptors(null_interceptor): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -26127,21 +28397,23 @@ def test_list_evaluation_results_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.EvaluationServiceRestInterceptor, "post_list_evaluation_results" + transports.EvaluationServiceRestInterceptor, + "post_list_evaluation_expectations", ) as post, mock.patch.object( transports.EvaluationServiceRestInterceptor, - "post_list_evaluation_results_with_metadata", + "post_list_evaluation_expectations_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.EvaluationServiceRestInterceptor, "pre_list_evaluation_results" + transports.EvaluationServiceRestInterceptor, + "pre_list_evaluation_expectations", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = evaluation_service.ListEvaluationResultsRequest.pb( - evaluation_service.ListEvaluationResultsRequest() + pb_message = evaluation_service.ListEvaluationExpectationsRequest.pb( + evaluation_service.ListEvaluationExpectationsRequest() ) transcode.return_value = { "method": "post", @@ -26153,24 +28425,24 @@ def test_list_evaluation_results_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = evaluation_service.ListEvaluationResultsResponse.to_json( - evaluation_service.ListEvaluationResultsResponse() + return_value = evaluation_service.ListEvaluationExpectationsResponse.to_json( + evaluation_service.ListEvaluationExpectationsResponse() ) req.return_value.content = return_value - request = evaluation_service.ListEvaluationResultsRequest() + request = evaluation_service.ListEvaluationExpectationsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = evaluation_service.ListEvaluationResultsResponse() + post.return_value = evaluation_service.ListEvaluationExpectationsResponse() post_with_metadata.return_value = ( - evaluation_service.ListEvaluationResultsResponse(), + evaluation_service.ListEvaluationExpectationsResponse(), metadata, ) - client.list_evaluation_results( + client.list_evaluation_expectations( request, metadata=[ ("key", "val"), @@ -26183,14 +28455,16 @@ def test_list_evaluation_results_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_evaluation_datasets_rest_bad_request( - request_type=evaluation_service.ListEvaluationDatasetsRequest, +def test_get_evaluation_expectation_rest_bad_request( + request_type=evaluation_service.GetEvaluationExpectationRequest, ): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2/apps/sample3"} + request_init = { + "name": "projects/sample1/locations/sample2/apps/sample3/evaluationExpectations/sample4" + } request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -26206,30 +28480,35 @@ def test_list_evaluation_datasets_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_evaluation_datasets(request) + client.get_evaluation_expectation(request) @pytest.mark.parametrize( "request_type", [ - evaluation_service.ListEvaluationDatasetsRequest, + evaluation_service.GetEvaluationExpectationRequest, dict, ], ) -def test_list_evaluation_datasets_rest_call_success(request_type): +def test_get_evaluation_expectation_rest_call_success(request_type): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2/apps/sample3"} + request_init = { + "name": "projects/sample1/locations/sample2/apps/sample3/evaluationExpectations/sample4" + } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = evaluation_service.ListEvaluationDatasetsResponse( - next_page_token="next_page_token_value", + # Designate an appropriate value for the returned response. + return_value = evaluation.EvaluationExpectation( + name="name_value", + display_name="display_name_value", + tags=["tags_value"], + etag="etag_value", ) # Wrap the value into a proper Response obj @@ -26237,22 +28516,23 @@ def test_list_evaluation_datasets_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation_service.ListEvaluationDatasetsResponse.pb( - return_value - ) + return_value = evaluation.EvaluationExpectation.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_evaluation_datasets(request) + response = client.get_evaluation_expectation(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListEvaluationDatasetsPager) - assert response.next_page_token == "next_page_token_value" + assert isinstance(response, evaluation.EvaluationExpectation) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.tags == ["tags_value"] + assert response.etag == "etag_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_evaluation_datasets_rest_interceptors(null_interceptor): +def test_get_evaluation_expectation_rest_interceptors(null_interceptor): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -26265,21 +28545,23 @@ def test_list_evaluation_datasets_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.EvaluationServiceRestInterceptor, "post_list_evaluation_datasets" + transports.EvaluationServiceRestInterceptor, + "post_get_evaluation_expectation", ) as post, mock.patch.object( transports.EvaluationServiceRestInterceptor, - "post_list_evaluation_datasets_with_metadata", + "post_get_evaluation_expectation_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.EvaluationServiceRestInterceptor, "pre_list_evaluation_datasets" + transports.EvaluationServiceRestInterceptor, + "pre_get_evaluation_expectation", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = evaluation_service.ListEvaluationDatasetsRequest.pb( - evaluation_service.ListEvaluationDatasetsRequest() + pb_message = evaluation_service.GetEvaluationExpectationRequest.pb( + evaluation_service.GetEvaluationExpectationRequest() ) transcode.return_value = { "method": "post", @@ -26291,24 +28573,21 @@ def test_list_evaluation_datasets_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = evaluation_service.ListEvaluationDatasetsResponse.to_json( - evaluation_service.ListEvaluationDatasetsResponse() + return_value = evaluation.EvaluationExpectation.to_json( + evaluation.EvaluationExpectation() ) req.return_value.content = return_value - request = evaluation_service.ListEvaluationDatasetsRequest() + request = evaluation_service.GetEvaluationExpectationRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = evaluation_service.ListEvaluationDatasetsResponse() - post_with_metadata.return_value = ( - evaluation_service.ListEvaluationDatasetsResponse(), - metadata, - ) + post.return_value = evaluation.EvaluationExpectation() + post_with_metadata.return_value = evaluation.EvaluationExpectation(), metadata - client.list_evaluation_datasets( + client.get_evaluation_expectation( request, metadata=[ ("key", "val"), @@ -26321,8 +28600,8 @@ def test_list_evaluation_datasets_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_evaluation_runs_rest_bad_request( - request_type=evaluation_service.ListEvaluationRunsRequest, +def test_create_evaluation_expectation_rest_bad_request( + request_type=evaluation_service.CreateEvaluationExpectationRequest, ): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" @@ -26344,30 +28623,113 @@ def test_list_evaluation_runs_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_evaluation_runs(request) + client.create_evaluation_expectation(request) @pytest.mark.parametrize( "request_type", [ - evaluation_service.ListEvaluationRunsRequest, + evaluation_service.CreateEvaluationExpectationRequest, dict, ], ) -def test_list_evaluation_runs_rest_call_success(request_type): +def test_create_evaluation_expectation_rest_call_success(request_type): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = {"parent": "projects/sample1/locations/sample2/apps/sample3"} + request_init["evaluation_expectation"] = { + "llm_criteria": {"prompt": "prompt_value"}, + "name": "name_value", + "display_name": "display_name_value", + "tags": ["tags_value1", "tags_value2"], + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "etag": "etag_value", + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = evaluation_service.CreateEvaluationExpectationRequest.meta.fields[ + "evaluation_expectation" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init[ + "evaluation_expectation" + ].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["evaluation_expectation"][field])): + del request_init["evaluation_expectation"][field][i][subfield] + else: + del request_init["evaluation_expectation"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation_service.ListEvaluationRunsResponse( - next_page_token="next_page_token_value", + return_value = evaluation.EvaluationExpectation( + name="name_value", + display_name="display_name_value", + tags=["tags_value"], + etag="etag_value", ) # Wrap the value into a proper Response obj @@ -26375,20 +28737,23 @@ def test_list_evaluation_runs_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation_service.ListEvaluationRunsResponse.pb(return_value) + return_value = evaluation.EvaluationExpectation.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_evaluation_runs(request) + response = client.create_evaluation_expectation(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListEvaluationRunsPager) - assert response.next_page_token == "next_page_token_value" + assert isinstance(response, evaluation.EvaluationExpectation) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.tags == ["tags_value"] + assert response.etag == "etag_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_evaluation_runs_rest_interceptors(null_interceptor): +def test_create_evaluation_expectation_rest_interceptors(null_interceptor): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -26401,21 +28766,23 @@ def test_list_evaluation_runs_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.EvaluationServiceRestInterceptor, "post_list_evaluation_runs" + transports.EvaluationServiceRestInterceptor, + "post_create_evaluation_expectation", ) as post, mock.patch.object( transports.EvaluationServiceRestInterceptor, - "post_list_evaluation_runs_with_metadata", + "post_create_evaluation_expectation_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.EvaluationServiceRestInterceptor, "pre_list_evaluation_runs" + transports.EvaluationServiceRestInterceptor, + "pre_create_evaluation_expectation", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = evaluation_service.ListEvaluationRunsRequest.pb( - evaluation_service.ListEvaluationRunsRequest() + pb_message = evaluation_service.CreateEvaluationExpectationRequest.pb( + evaluation_service.CreateEvaluationExpectationRequest() ) transcode.return_value = { "method": "post", @@ -26427,24 +28794,21 @@ def test_list_evaluation_runs_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = evaluation_service.ListEvaluationRunsResponse.to_json( - evaluation_service.ListEvaluationRunsResponse() + return_value = evaluation.EvaluationExpectation.to_json( + evaluation.EvaluationExpectation() ) req.return_value.content = return_value - request = evaluation_service.ListEvaluationRunsRequest() + request = evaluation_service.CreateEvaluationExpectationRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = evaluation_service.ListEvaluationRunsResponse() - post_with_metadata.return_value = ( - evaluation_service.ListEvaluationRunsResponse(), - metadata, - ) + post.return_value = evaluation.EvaluationExpectation() + post_with_metadata.return_value = evaluation.EvaluationExpectation(), metadata - client.list_evaluation_runs( + client.create_evaluation_expectation( request, metadata=[ ("key", "val"), @@ -26457,14 +28821,18 @@ def test_list_evaluation_runs_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_evaluation_expectations_rest_bad_request( - request_type=evaluation_service.ListEvaluationExpectationsRequest, +def test_update_evaluation_expectation_rest_bad_request( + request_type=evaluation_service.UpdateEvaluationExpectationRequest, ): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2/apps/sample3"} + request_init = { + "evaluation_expectation": { + "name": "projects/sample1/locations/sample2/apps/sample3/evaluationExpectations/sample4" + } + } request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -26480,30 +28848,117 @@ def test_list_evaluation_expectations_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_evaluation_expectations(request) + client.update_evaluation_expectation(request) @pytest.mark.parametrize( "request_type", [ - evaluation_service.ListEvaluationExpectationsRequest, + evaluation_service.UpdateEvaluationExpectationRequest, dict, ], ) -def test_list_evaluation_expectations_rest_call_success(request_type): +def test_update_evaluation_expectation_rest_call_success(request_type): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2/apps/sample3"} + # send a request that will satisfy transcoding + request_init = { + "evaluation_expectation": { + "name": "projects/sample1/locations/sample2/apps/sample3/evaluationExpectations/sample4" + } + } + request_init["evaluation_expectation"] = { + "llm_criteria": {"prompt": "prompt_value"}, + "name": "projects/sample1/locations/sample2/apps/sample3/evaluationExpectations/sample4", + "display_name": "display_name_value", + "tags": ["tags_value1", "tags_value2"], + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "etag": "etag_value", + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = evaluation_service.UpdateEvaluationExpectationRequest.meta.fields[ + "evaluation_expectation" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init[ + "evaluation_expectation" + ].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["evaluation_expectation"][field])): + del request_init["evaluation_expectation"][field][i][subfield] + else: + del request_init["evaluation_expectation"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation_service.ListEvaluationExpectationsResponse( - next_page_token="next_page_token_value", + return_value = evaluation.EvaluationExpectation( + name="name_value", + display_name="display_name_value", + tags=["tags_value"], + etag="etag_value", ) # Wrap the value into a proper Response obj @@ -26511,22 +28966,23 @@ def test_list_evaluation_expectations_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation_service.ListEvaluationExpectationsResponse.pb( - return_value - ) + return_value = evaluation.EvaluationExpectation.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_evaluation_expectations(request) + response = client.update_evaluation_expectation(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListEvaluationExpectationsPager) - assert response.next_page_token == "next_page_token_value" + assert isinstance(response, evaluation.EvaluationExpectation) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.tags == ["tags_value"] + assert response.etag == "etag_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_evaluation_expectations_rest_interceptors(null_interceptor): +def test_update_evaluation_expectation_rest_interceptors(null_interceptor): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -26540,22 +28996,22 @@ def test_list_evaluation_expectations_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( transports.EvaluationServiceRestInterceptor, - "post_list_evaluation_expectations", + "post_update_evaluation_expectation", ) as post, mock.patch.object( transports.EvaluationServiceRestInterceptor, - "post_list_evaluation_expectations_with_metadata", + "post_update_evaluation_expectation_with_metadata", ) as post_with_metadata, mock.patch.object( transports.EvaluationServiceRestInterceptor, - "pre_list_evaluation_expectations", + "pre_update_evaluation_expectation", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = evaluation_service.ListEvaluationExpectationsRequest.pb( - evaluation_service.ListEvaluationExpectationsRequest() + pb_message = evaluation_service.UpdateEvaluationExpectationRequest.pb( + evaluation_service.UpdateEvaluationExpectationRequest() ) transcode.return_value = { "method": "post", @@ -26567,24 +29023,21 @@ def test_list_evaluation_expectations_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = evaluation_service.ListEvaluationExpectationsResponse.to_json( - evaluation_service.ListEvaluationExpectationsResponse() + return_value = evaluation.EvaluationExpectation.to_json( + evaluation.EvaluationExpectation() ) req.return_value.content = return_value - request = evaluation_service.ListEvaluationExpectationsRequest() + request = evaluation_service.UpdateEvaluationExpectationRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = evaluation_service.ListEvaluationExpectationsResponse() - post_with_metadata.return_value = ( - evaluation_service.ListEvaluationExpectationsResponse(), - metadata, - ) + post.return_value = evaluation.EvaluationExpectation() + post_with_metadata.return_value = evaluation.EvaluationExpectation(), metadata - client.list_evaluation_expectations( + client.update_evaluation_expectation( request, metadata=[ ("key", "val"), @@ -26597,8 +29050,8 @@ def test_list_evaluation_expectations_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_get_evaluation_expectation_rest_bad_request( - request_type=evaluation_service.GetEvaluationExpectationRequest, +def test_delete_evaluation_expectation_rest_bad_request( + request_type=evaluation_service.DeleteEvaluationExpectationRequest, ): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" @@ -26622,17 +29075,17 @@ def test_get_evaluation_expectation_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_evaluation_expectation(request) + client.delete_evaluation_expectation(request) @pytest.mark.parametrize( "request_type", [ - evaluation_service.GetEvaluationExpectationRequest, + evaluation_service.DeleteEvaluationExpectationRequest, dict, ], ) -def test_get_evaluation_expectation_rest_call_success(request_type): +def test_delete_evaluation_expectation_rest_call_success(request_type): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -26646,35 +29099,23 @@ def test_get_evaluation_expectation_rest_call_success(request_type): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation.EvaluationExpectation( - name="name_value", - display_name="display_name_value", - tags=["tags_value"], - etag="etag_value", - ) + return_value = None # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = evaluation.EvaluationExpectation.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + json_return_value = "" response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_evaluation_expectation(request) + response = client.delete_evaluation_expectation(request) # Establish that the response is the type that we expect. - assert isinstance(response, evaluation.EvaluationExpectation) - assert response.name == "name_value" - assert response.display_name == "display_name_value" - assert response.tags == ["tags_value"] - assert response.etag == "etag_value" + assert response is None @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_evaluation_expectation_rest_interceptors(null_interceptor): +def test_delete_evaluation_expectation_rest_interceptors(null_interceptor): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -26688,22 +29129,12 @@ def test_get_evaluation_expectation_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( transports.EvaluationServiceRestInterceptor, - "post_get_evaluation_expectation", - ) as post, - mock.patch.object( - transports.EvaluationServiceRestInterceptor, - "post_get_evaluation_expectation_with_metadata", - ) as post_with_metadata, - mock.patch.object( - transports.EvaluationServiceRestInterceptor, - "pre_get_evaluation_expectation", + "pre_delete_evaluation_expectation", ) as pre, ): pre.assert_not_called() - post.assert_not_called() - post_with_metadata.assert_not_called() - pb_message = evaluation_service.GetEvaluationExpectationRequest.pb( - evaluation_service.GetEvaluationExpectationRequest() + pb_message = evaluation_service.DeleteEvaluationExpectationRequest.pb( + evaluation_service.DeleteEvaluationExpectationRequest() ) transcode.return_value = { "method": "post", @@ -26715,21 +29146,15 @@ def test_get_evaluation_expectation_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = evaluation.EvaluationExpectation.to_json( - evaluation.EvaluationExpectation() - ) - req.return_value.content = return_value - request = evaluation_service.GetEvaluationExpectationRequest() + request = evaluation_service.DeleteEvaluationExpectationRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = evaluation.EvaluationExpectation() - post_with_metadata.return_value = evaluation.EvaluationExpectation(), metadata - client.get_evaluation_expectation( + client.delete_evaluation_expectation( request, metadata=[ ("key", "val"), @@ -26738,12 +29163,10 @@ def test_get_evaluation_expectation_rest_interceptors(null_interceptor): ) pre.assert_called_once() - post.assert_called_once() - post_with_metadata.assert_called_once() -def test_create_evaluation_expectation_rest_bad_request( - request_type=evaluation_service.CreateEvaluationExpectationRequest, +def test_create_scheduled_evaluation_run_rest_bad_request( + request_type=evaluation_service.CreateScheduledEvaluationRunRequest, ): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" @@ -26765,30 +29188,71 @@ def test_create_evaluation_expectation_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_evaluation_expectation(request) + client.create_scheduled_evaluation_run(request) @pytest.mark.parametrize( "request_type", [ - evaluation_service.CreateEvaluationExpectationRequest, + evaluation_service.CreateScheduledEvaluationRunRequest, dict, ], ) -def test_create_evaluation_expectation_rest_call_success(request_type): +def test_create_scheduled_evaluation_run_rest_call_success(request_type): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = {"parent": "projects/sample1/locations/sample2/apps/sample3"} - request_init["evaluation_expectation"] = { - "llm_criteria": {"prompt": "prompt_value"}, + request_init["scheduled_evaluation_run"] = { "name": "name_value", "display_name": "display_name_value", - "tags": ["tags_value1", "tags_value2"], - "create_time": {"seconds": 751, "nanos": 543}, + "request": { + "app": "app_value", + "evaluations": ["evaluations_value1", "evaluations_value2"], + "evaluation_dataset": "evaluation_dataset_value", + "display_name": "display_name_value", + "app_version": "app_version_value", + "config": { + "input_audio_config": { + "audio_encoding": 1, + "sample_rate_hertz": 1817, + "noise_suppression_level": "noise_suppression_level_value", + }, + "output_audio_config": {"audio_encoding": 1, "sample_rate_hertz": 1817}, + "evaluation_channel": 1, + "tool_call_behaviour": 1, + }, + "run_count": 989, + "persona_run_configs": [{"persona": "persona_value", "task_count": 1083}], + "optimization_config": { + "generate_loss_report": True, + "assistant_session": "assistant_session_value", + "report_summary": "report_summary_value", + "should_suggest_fix": True, + "status": 1, + "error_message": "error_message_value", + "loss_report": {"fields": {}}, + }, + "scheduled_evaluation_run": "scheduled_evaluation_run_value", + "golden_run_method": 1, + "generate_latency_report": True, + }, + "description": "description_value", + "scheduling_config": { + "frequency": 1, + "start_time": {"seconds": 751, "nanos": 543}, + "days_of_week": [1265, 1266], + }, + "active": True, + "last_completed_run": "last_completed_run_value", + "total_executions": 1738, + "next_scheduled_execution_time": {}, + "create_time": {}, + "created_by": "created_by_value", "update_time": {}, + "last_updated_by": "last_updated_by_value", "etag": "etag_value", } # The version of a generated dependency at test runtime may differ from the version used during generation. @@ -26796,8 +29260,8 @@ def test_create_evaluation_expectation_rest_call_success(request_type): # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = evaluation_service.CreateEvaluationExpectationRequest.meta.fields[ - "evaluation_expectation" + test_field = evaluation_service.CreateScheduledEvaluationRunRequest.meta.fields[ + "scheduled_evaluation_run" ] def get_message_fields(field): @@ -26827,7 +29291,7 @@ def get_message_fields(field): # For each item in the sample request, create a list of sub fields which are not present at runtime # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime for field, value in request_init[ - "evaluation_expectation" + "scheduled_evaluation_run" ].items(): # pragma: NO COVER result = None is_repeated = False @@ -26858,19 +29322,24 @@ def get_message_fields(field): subfield = subfield_to_delete.get("subfield") if subfield: if field_repeated: - for i in range(0, len(request_init["evaluation_expectation"][field])): - del request_init["evaluation_expectation"][field][i][subfield] + for i in range(0, len(request_init["scheduled_evaluation_run"][field])): + del request_init["scheduled_evaluation_run"][field][i][subfield] else: - del request_init["evaluation_expectation"][field][subfield] + del request_init["scheduled_evaluation_run"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation.EvaluationExpectation( + return_value = evaluation.ScheduledEvaluationRun( name="name_value", display_name="display_name_value", - tags=["tags_value"], + description="description_value", + active=True, + last_completed_run="last_completed_run_value", + total_executions=1738, + created_by="created_by_value", + last_updated_by="last_updated_by_value", etag="etag_value", ) @@ -26879,23 +29348,28 @@ def get_message_fields(field): response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation.EvaluationExpectation.pb(return_value) + return_value = evaluation.ScheduledEvaluationRun.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_evaluation_expectation(request) + response = client.create_scheduled_evaluation_run(request) # Establish that the response is the type that we expect. - assert isinstance(response, evaluation.EvaluationExpectation) + assert isinstance(response, evaluation.ScheduledEvaluationRun) assert response.name == "name_value" assert response.display_name == "display_name_value" - assert response.tags == ["tags_value"] + assert response.description == "description_value" + assert response.active is True + assert response.last_completed_run == "last_completed_run_value" + assert response.total_executions == 1738 + assert response.created_by == "created_by_value" + assert response.last_updated_by == "last_updated_by_value" assert response.etag == "etag_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_evaluation_expectation_rest_interceptors(null_interceptor): +def test_create_scheduled_evaluation_run_rest_interceptors(null_interceptor): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -26909,22 +29383,22 @@ def test_create_evaluation_expectation_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( transports.EvaluationServiceRestInterceptor, - "post_create_evaluation_expectation", + "post_create_scheduled_evaluation_run", ) as post, mock.patch.object( transports.EvaluationServiceRestInterceptor, - "post_create_evaluation_expectation_with_metadata", + "post_create_scheduled_evaluation_run_with_metadata", ) as post_with_metadata, mock.patch.object( transports.EvaluationServiceRestInterceptor, - "pre_create_evaluation_expectation", + "pre_create_scheduled_evaluation_run", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = evaluation_service.CreateEvaluationExpectationRequest.pb( - evaluation_service.CreateEvaluationExpectationRequest() + pb_message = evaluation_service.CreateScheduledEvaluationRunRequest.pb( + evaluation_service.CreateScheduledEvaluationRunRequest() ) transcode.return_value = { "method": "post", @@ -26936,21 +29410,21 @@ def test_create_evaluation_expectation_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = evaluation.EvaluationExpectation.to_json( - evaluation.EvaluationExpectation() + return_value = evaluation.ScheduledEvaluationRun.to_json( + evaluation.ScheduledEvaluationRun() ) req.return_value.content = return_value - request = evaluation_service.CreateEvaluationExpectationRequest() + request = evaluation_service.CreateScheduledEvaluationRunRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = evaluation.EvaluationExpectation() - post_with_metadata.return_value = evaluation.EvaluationExpectation(), metadata + post.return_value = evaluation.ScheduledEvaluationRun() + post_with_metadata.return_value = evaluation.ScheduledEvaluationRun(), metadata - client.create_evaluation_expectation( + client.create_scheduled_evaluation_run( request, metadata=[ ("key", "val"), @@ -26963,17 +29437,15 @@ def test_create_evaluation_expectation_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_update_evaluation_expectation_rest_bad_request( - request_type=evaluation_service.UpdateEvaluationExpectationRequest, +def test_get_scheduled_evaluation_run_rest_bad_request( + request_type=evaluation_service.GetScheduledEvaluationRunRequest, ): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "evaluation_expectation": { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluationExpectations/sample4" - } + "name": "projects/sample1/locations/sample2/apps/sample3/scheduledEvaluationRuns/sample4" } request = request_type(**request_init) @@ -26990,116 +29462,39 @@ def test_update_evaluation_expectation_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_evaluation_expectation(request) + client.get_scheduled_evaluation_run(request) @pytest.mark.parametrize( "request_type", [ - evaluation_service.UpdateEvaluationExpectationRequest, + evaluation_service.GetScheduledEvaluationRunRequest, dict, ], ) -def test_update_evaluation_expectation_rest_call_success(request_type): +def test_get_scheduled_evaluation_run_rest_call_success(request_type): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "evaluation_expectation": { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluationExpectations/sample4" - } - } - request_init["evaluation_expectation"] = { - "llm_criteria": {"prompt": "prompt_value"}, - "name": "projects/sample1/locations/sample2/apps/sample3/evaluationExpectations/sample4", - "display_name": "display_name_value", - "tags": ["tags_value1", "tags_value2"], - "create_time": {"seconds": 751, "nanos": 543}, - "update_time": {}, - "etag": "etag_value", + "name": "projects/sample1/locations/sample2/apps/sample3/scheduledEvaluationRuns/sample4" } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = evaluation_service.UpdateEvaluationExpectationRequest.meta.fields[ - "evaluation_expectation" - ] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init[ - "evaluation_expectation" - ].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["evaluation_expectation"][field])): - del request_init["evaluation_expectation"][field][i][subfield] - else: - del request_init["evaluation_expectation"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation.EvaluationExpectation( + return_value = evaluation.ScheduledEvaluationRun( name="name_value", display_name="display_name_value", - tags=["tags_value"], + description="description_value", + active=True, + last_completed_run="last_completed_run_value", + total_executions=1738, + created_by="created_by_value", + last_updated_by="last_updated_by_value", etag="etag_value", ) @@ -27108,23 +29503,28 @@ def get_message_fields(field): response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation.EvaluationExpectation.pb(return_value) + return_value = evaluation.ScheduledEvaluationRun.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_evaluation_expectation(request) + response = client.get_scheduled_evaluation_run(request) # Establish that the response is the type that we expect. - assert isinstance(response, evaluation.EvaluationExpectation) + assert isinstance(response, evaluation.ScheduledEvaluationRun) assert response.name == "name_value" assert response.display_name == "display_name_value" - assert response.tags == ["tags_value"] + assert response.description == "description_value" + assert response.active is True + assert response.last_completed_run == "last_completed_run_value" + assert response.total_executions == 1738 + assert response.created_by == "created_by_value" + assert response.last_updated_by == "last_updated_by_value" assert response.etag == "etag_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_evaluation_expectation_rest_interceptors(null_interceptor): +def test_get_scheduled_evaluation_run_rest_interceptors(null_interceptor): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -27138,22 +29538,22 @@ def test_update_evaluation_expectation_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( transports.EvaluationServiceRestInterceptor, - "post_update_evaluation_expectation", + "post_get_scheduled_evaluation_run", ) as post, mock.patch.object( transports.EvaluationServiceRestInterceptor, - "post_update_evaluation_expectation_with_metadata", + "post_get_scheduled_evaluation_run_with_metadata", ) as post_with_metadata, mock.patch.object( transports.EvaluationServiceRestInterceptor, - "pre_update_evaluation_expectation", + "pre_get_scheduled_evaluation_run", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = evaluation_service.UpdateEvaluationExpectationRequest.pb( - evaluation_service.UpdateEvaluationExpectationRequest() + pb_message = evaluation_service.GetScheduledEvaluationRunRequest.pb( + evaluation_service.GetScheduledEvaluationRunRequest() ) transcode.return_value = { "method": "post", @@ -27165,21 +29565,21 @@ def test_update_evaluation_expectation_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = evaluation.EvaluationExpectation.to_json( - evaluation.EvaluationExpectation() + return_value = evaluation.ScheduledEvaluationRun.to_json( + evaluation.ScheduledEvaluationRun() ) req.return_value.content = return_value - request = evaluation_service.UpdateEvaluationExpectationRequest() + request = evaluation_service.GetScheduledEvaluationRunRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = evaluation.EvaluationExpectation() - post_with_metadata.return_value = evaluation.EvaluationExpectation(), metadata + post.return_value = evaluation.ScheduledEvaluationRun() + post_with_metadata.return_value = evaluation.ScheduledEvaluationRun(), metadata - client.update_evaluation_expectation( + client.get_scheduled_evaluation_run( request, metadata=[ ("key", "val"), @@ -27192,16 +29592,14 @@ def test_update_evaluation_expectation_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_delete_evaluation_expectation_rest_bad_request( - request_type=evaluation_service.DeleteEvaluationExpectationRequest, +def test_list_scheduled_evaluation_runs_rest_bad_request( + request_type=evaluation_service.ListScheduledEvaluationRunsRequest, ): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluationExpectations/sample4" - } + request_init = {"parent": "projects/sample1/locations/sample2/apps/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -27217,47 +29615,53 @@ def test_delete_evaluation_expectation_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_evaluation_expectation(request) + client.list_scheduled_evaluation_runs(request) @pytest.mark.parametrize( "request_type", [ - evaluation_service.DeleteEvaluationExpectationRequest, + evaluation_service.ListScheduledEvaluationRunsRequest, dict, ], ) -def test_delete_evaluation_expectation_rest_call_success(request_type): +def test_list_scheduled_evaluation_runs_rest_call_success(request_type): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/apps/sample3/evaluationExpectations/sample4" - } + request_init = {"parent": "projects/sample1/locations/sample2/apps/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = None + return_value = evaluation_service.ListScheduledEvaluationRunsResponse( + next_page_token="next_page_token_value", + ) # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 - json_return_value = "" + + # Convert return value to protobuf type + return_value = evaluation_service.ListScheduledEvaluationRunsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_evaluation_expectation(request) + response = client.list_scheduled_evaluation_runs(request) # Establish that the response is the type that we expect. - assert response is None + assert isinstance(response, pagers.ListScheduledEvaluationRunsPager) + assert response.next_page_token == "next_page_token_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_evaluation_expectation_rest_interceptors(null_interceptor): +def test_list_scheduled_evaluation_runs_rest_interceptors(null_interceptor): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -27271,12 +29675,22 @@ def test_delete_evaluation_expectation_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( transports.EvaluationServiceRestInterceptor, - "pre_delete_evaluation_expectation", + "post_list_scheduled_evaluation_runs", + ) as post, + mock.patch.object( + transports.EvaluationServiceRestInterceptor, + "post_list_scheduled_evaluation_runs_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.EvaluationServiceRestInterceptor, + "pre_list_scheduled_evaluation_runs", ) as pre, ): pre.assert_not_called() - pb_message = evaluation_service.DeleteEvaluationExpectationRequest.pb( - evaluation_service.DeleteEvaluationExpectationRequest() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = evaluation_service.ListScheduledEvaluationRunsRequest.pb( + evaluation_service.ListScheduledEvaluationRunsRequest() ) transcode.return_value = { "method": "post", @@ -27288,15 +29702,24 @@ def test_delete_evaluation_expectation_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = evaluation_service.ListScheduledEvaluationRunsResponse.to_json( + evaluation_service.ListScheduledEvaluationRunsResponse() + ) + req.return_value.content = return_value - request = evaluation_service.DeleteEvaluationExpectationRequest() + request = evaluation_service.ListScheduledEvaluationRunsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata + post.return_value = evaluation_service.ListScheduledEvaluationRunsResponse() + post_with_metadata.return_value = ( + evaluation_service.ListScheduledEvaluationRunsResponse(), + metadata, + ) - client.delete_evaluation_expectation( + client.list_scheduled_evaluation_runs( request, metadata=[ ("key", "val"), @@ -27305,16 +29728,22 @@ def test_delete_evaluation_expectation_rest_interceptors(null_interceptor): ) pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() -def test_create_scheduled_evaluation_run_rest_bad_request( - request_type=evaluation_service.CreateScheduledEvaluationRunRequest, +def test_update_scheduled_evaluation_run_rest_bad_request( + request_type=evaluation_service.UpdateScheduledEvaluationRunRequest, ): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2/apps/sample3"} + request_init = { + "scheduled_evaluation_run": { + "name": "projects/sample1/locations/sample2/apps/sample3/scheduledEvaluationRuns/sample4" + } + } request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -27330,25 +29759,29 @@ def test_create_scheduled_evaluation_run_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_scheduled_evaluation_run(request) + client.update_scheduled_evaluation_run(request) @pytest.mark.parametrize( "request_type", [ - evaluation_service.CreateScheduledEvaluationRunRequest, + evaluation_service.UpdateScheduledEvaluationRunRequest, dict, ], ) -def test_create_scheduled_evaluation_run_rest_call_success(request_type): +def test_update_scheduled_evaluation_run_rest_call_success(request_type): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2/apps/sample3"} + request_init = { + "scheduled_evaluation_run": { + "name": "projects/sample1/locations/sample2/apps/sample3/scheduledEvaluationRuns/sample4" + } + } request_init["scheduled_evaluation_run"] = { - "name": "name_value", + "name": "projects/sample1/locations/sample2/apps/sample3/scheduledEvaluationRuns/sample4", "display_name": "display_name_value", "request": { "app": "app_value", @@ -27402,7 +29835,7 @@ def test_create_scheduled_evaluation_run_rest_call_success(request_type): # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = evaluation_service.CreateScheduledEvaluationRunRequest.meta.fields[ + test_field = evaluation_service.UpdateScheduledEvaluationRunRequest.meta.fields[ "scheduled_evaluation_run" ] @@ -27495,7 +29928,7 @@ def get_message_fields(field): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_scheduled_evaluation_run(request) + response = client.update_scheduled_evaluation_run(request) # Establish that the response is the type that we expect. assert isinstance(response, evaluation.ScheduledEvaluationRun) @@ -27511,7 +29944,7 @@ def get_message_fields(field): @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_scheduled_evaluation_run_rest_interceptors(null_interceptor): +def test_update_scheduled_evaluation_run_rest_interceptors(null_interceptor): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -27525,22 +29958,22 @@ def test_create_scheduled_evaluation_run_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( transports.EvaluationServiceRestInterceptor, - "post_create_scheduled_evaluation_run", + "post_update_scheduled_evaluation_run", ) as post, mock.patch.object( transports.EvaluationServiceRestInterceptor, - "post_create_scheduled_evaluation_run_with_metadata", + "post_update_scheduled_evaluation_run_with_metadata", ) as post_with_metadata, mock.patch.object( transports.EvaluationServiceRestInterceptor, - "pre_create_scheduled_evaluation_run", + "pre_update_scheduled_evaluation_run", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = evaluation_service.CreateScheduledEvaluationRunRequest.pb( - evaluation_service.CreateScheduledEvaluationRunRequest() + pb_message = evaluation_service.UpdateScheduledEvaluationRunRequest.pb( + evaluation_service.UpdateScheduledEvaluationRunRequest() ) transcode.return_value = { "method": "post", @@ -27557,7 +29990,7 @@ def test_create_scheduled_evaluation_run_rest_interceptors(null_interceptor): ) req.return_value.content = return_value - request = evaluation_service.CreateScheduledEvaluationRunRequest() + request = evaluation_service.UpdateScheduledEvaluationRunRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -27566,7 +29999,7 @@ def test_create_scheduled_evaluation_run_rest_interceptors(null_interceptor): post.return_value = evaluation.ScheduledEvaluationRun() post_with_metadata.return_value = evaluation.ScheduledEvaluationRun(), metadata - client.create_scheduled_evaluation_run( + client.update_scheduled_evaluation_run( request, metadata=[ ("key", "val"), @@ -27579,8 +30012,8 @@ def test_create_scheduled_evaluation_run_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_get_scheduled_evaluation_run_rest_bad_request( - request_type=evaluation_service.GetScheduledEvaluationRunRequest, +def test_delete_scheduled_evaluation_run_rest_bad_request( + request_type=evaluation_service.DeleteScheduledEvaluationRunRequest, ): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" @@ -27604,17 +30037,17 @@ def test_get_scheduled_evaluation_run_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_scheduled_evaluation_run(request) + client.delete_scheduled_evaluation_run(request) @pytest.mark.parametrize( "request_type", [ - evaluation_service.GetScheduledEvaluationRunRequest, + evaluation_service.DeleteScheduledEvaluationRunRequest, dict, ], ) -def test_get_scheduled_evaluation_run_rest_call_success(request_type): +def test_delete_scheduled_evaluation_run_rest_call_success(request_type): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -27628,45 +30061,23 @@ def test_get_scheduled_evaluation_run_rest_call_success(request_type): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation.ScheduledEvaluationRun( - name="name_value", - display_name="display_name_value", - description="description_value", - active=True, - last_completed_run="last_completed_run_value", - total_executions=1738, - created_by="created_by_value", - last_updated_by="last_updated_by_value", - etag="etag_value", - ) + return_value = None # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = evaluation.ScheduledEvaluationRun.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + json_return_value = "" response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_scheduled_evaluation_run(request) + response = client.delete_scheduled_evaluation_run(request) # Establish that the response is the type that we expect. - assert isinstance(response, evaluation.ScheduledEvaluationRun) - assert response.name == "name_value" - assert response.display_name == "display_name_value" - assert response.description == "description_value" - assert response.active is True - assert response.last_completed_run == "last_completed_run_value" - assert response.total_executions == 1738 - assert response.created_by == "created_by_value" - assert response.last_updated_by == "last_updated_by_value" - assert response.etag == "etag_value" + assert response is None @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_scheduled_evaluation_run_rest_interceptors(null_interceptor): +def test_delete_scheduled_evaluation_run_rest_interceptors(null_interceptor): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -27680,22 +30091,12 @@ def test_get_scheduled_evaluation_run_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( transports.EvaluationServiceRestInterceptor, - "post_get_scheduled_evaluation_run", - ) as post, - mock.patch.object( - transports.EvaluationServiceRestInterceptor, - "post_get_scheduled_evaluation_run_with_metadata", - ) as post_with_metadata, - mock.patch.object( - transports.EvaluationServiceRestInterceptor, - "pre_get_scheduled_evaluation_run", + "pre_delete_scheduled_evaluation_run", ) as pre, ): pre.assert_not_called() - post.assert_not_called() - post_with_metadata.assert_not_called() - pb_message = evaluation_service.GetScheduledEvaluationRunRequest.pb( - evaluation_service.GetScheduledEvaluationRunRequest() + pb_message = evaluation_service.DeleteScheduledEvaluationRunRequest.pb( + evaluation_service.DeleteScheduledEvaluationRunRequest() ) transcode.return_value = { "method": "post", @@ -27707,21 +30108,15 @@ def test_get_scheduled_evaluation_run_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = evaluation.ScheduledEvaluationRun.to_json( - evaluation.ScheduledEvaluationRun() - ) - req.return_value.content = return_value - request = evaluation_service.GetScheduledEvaluationRunRequest() + request = evaluation_service.DeleteScheduledEvaluationRunRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = evaluation.ScheduledEvaluationRun() - post_with_metadata.return_value = evaluation.ScheduledEvaluationRun(), metadata - client.get_scheduled_evaluation_run( + client.delete_scheduled_evaluation_run( request, metadata=[ ("key", "val"), @@ -27730,18 +30125,16 @@ def test_get_scheduled_evaluation_run_rest_interceptors(null_interceptor): ) pre.assert_called_once() - post.assert_called_once() - post_with_metadata.assert_called_once() -def test_list_scheduled_evaluation_runs_rest_bad_request( - request_type=evaluation_service.ListScheduledEvaluationRunsRequest, +def test_test_persona_voice_rest_bad_request( + request_type=evaluation_service.TestPersonaVoiceRequest, ): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2/apps/sample3"} + request_init = {"app": "projects/sample1/locations/sample2/apps/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -27757,30 +30150,30 @@ def test_list_scheduled_evaluation_runs_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_scheduled_evaluation_runs(request) + client.test_persona_voice(request) @pytest.mark.parametrize( "request_type", [ - evaluation_service.ListScheduledEvaluationRunsRequest, + evaluation_service.TestPersonaVoiceRequest, dict, ], ) -def test_list_scheduled_evaluation_runs_rest_call_success(request_type): +def test_test_persona_voice_rest_call_success(request_type): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2/apps/sample3"} + request_init = {"app": "projects/sample1/locations/sample2/apps/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation_service.ListScheduledEvaluationRunsResponse( - next_page_token="next_page_token_value", + return_value = evaluation_service.TestPersonaVoiceResponse( + audio=b"audio_blob", ) # Wrap the value into a proper Response obj @@ -27788,22 +30181,20 @@ def test_list_scheduled_evaluation_runs_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = evaluation_service.ListScheduledEvaluationRunsResponse.pb( - return_value - ) + return_value = evaluation_service.TestPersonaVoiceResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_scheduled_evaluation_runs(request) + response = client.test_persona_voice(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListScheduledEvaluationRunsPager) - assert response.next_page_token == "next_page_token_value" + assert isinstance(response, evaluation_service.TestPersonaVoiceResponse) + assert response.audio == b"audio_blob" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_scheduled_evaluation_runs_rest_interceptors(null_interceptor): +def test_test_persona_voice_rest_interceptors(null_interceptor): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -27816,23 +30207,21 @@ def test_list_scheduled_evaluation_runs_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.EvaluationServiceRestInterceptor, - "post_list_scheduled_evaluation_runs", + transports.EvaluationServiceRestInterceptor, "post_test_persona_voice" ) as post, mock.patch.object( transports.EvaluationServiceRestInterceptor, - "post_list_scheduled_evaluation_runs_with_metadata", + "post_test_persona_voice_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.EvaluationServiceRestInterceptor, - "pre_list_scheduled_evaluation_runs", + transports.EvaluationServiceRestInterceptor, "pre_test_persona_voice" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = evaluation_service.ListScheduledEvaluationRunsRequest.pb( - evaluation_service.ListScheduledEvaluationRunsRequest() + pb_message = evaluation_service.TestPersonaVoiceRequest.pb( + evaluation_service.TestPersonaVoiceRequest() ) transcode.return_value = { "method": "post", @@ -27844,24 +30233,24 @@ def test_list_scheduled_evaluation_runs_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = evaluation_service.ListScheduledEvaluationRunsResponse.to_json( - evaluation_service.ListScheduledEvaluationRunsResponse() + return_value = evaluation_service.TestPersonaVoiceResponse.to_json( + evaluation_service.TestPersonaVoiceResponse() ) req.return_value.content = return_value - request = evaluation_service.ListScheduledEvaluationRunsRequest() + request = evaluation_service.TestPersonaVoiceRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = evaluation_service.ListScheduledEvaluationRunsResponse() + post.return_value = evaluation_service.TestPersonaVoiceResponse() post_with_metadata.return_value = ( - evaluation_service.ListScheduledEvaluationRunsResponse(), + evaluation_service.TestPersonaVoiceResponse(), metadata, ) - client.list_scheduled_evaluation_runs( + client.test_persona_voice( request, metadata=[ ("key", "val"), @@ -27874,18 +30263,14 @@ def test_list_scheduled_evaluation_runs_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_update_scheduled_evaluation_run_rest_bad_request( - request_type=evaluation_service.UpdateScheduledEvaluationRunRequest, +def test_export_evaluations_rest_bad_request( + request_type=evaluation_service.ExportEvaluationsRequest, ): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "scheduled_evaluation_run": { - "name": "projects/sample1/locations/sample2/apps/sample3/scheduledEvaluationRuns/sample4" - } - } + request_init = {"parent": "projects/sample1/locations/sample2/apps/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -27897,196 +30282,49 @@ def test_update_scheduled_evaluation_run_rest_bad_request( response_value = mock.Mock() json_return_value = "" response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_scheduled_evaluation_run(request) - - -@pytest.mark.parametrize( - "request_type", - [ - evaluation_service.UpdateScheduledEvaluationRunRequest, - dict, - ], -) -def test_update_scheduled_evaluation_run_rest_call_success(request_type): - client = EvaluationServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - # send a request that will satisfy transcoding - request_init = { - "scheduled_evaluation_run": { - "name": "projects/sample1/locations/sample2/apps/sample3/scheduledEvaluationRuns/sample4" - } - } - request_init["scheduled_evaluation_run"] = { - "name": "projects/sample1/locations/sample2/apps/sample3/scheduledEvaluationRuns/sample4", - "display_name": "display_name_value", - "request": { - "app": "app_value", - "evaluations": ["evaluations_value1", "evaluations_value2"], - "evaluation_dataset": "evaluation_dataset_value", - "display_name": "display_name_value", - "app_version": "app_version_value", - "config": { - "input_audio_config": { - "audio_encoding": 1, - "sample_rate_hertz": 1817, - "noise_suppression_level": "noise_suppression_level_value", - }, - "output_audio_config": {"audio_encoding": 1, "sample_rate_hertz": 1817}, - "evaluation_channel": 1, - "tool_call_behaviour": 1, - }, - "run_count": 989, - "persona_run_configs": [{"persona": "persona_value", "task_count": 1083}], - "optimization_config": { - "generate_loss_report": True, - "assistant_session": "assistant_session_value", - "report_summary": "report_summary_value", - "should_suggest_fix": True, - "status": 1, - "error_message": "error_message_value", - "loss_report": {"fields": {}}, - }, - "scheduled_evaluation_run": "scheduled_evaluation_run_value", - "golden_run_method": 1, - "generate_latency_report": True, - }, - "description": "description_value", - "scheduling_config": { - "frequency": 1, - "start_time": {"seconds": 751, "nanos": 543}, - "days_of_week": [1265, 1266], - }, - "active": True, - "last_completed_run": "last_completed_run_value", - "total_executions": 1738, - "next_scheduled_execution_time": {}, - "create_time": {}, - "created_by": "created_by_value", - "update_time": {}, - "last_updated_by": "last_updated_by_value", - "etag": "etag_value", - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = evaluation_service.UpdateScheduledEvaluationRunRequest.meta.fields[ - "scheduled_evaluation_run" - ] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init[ - "scheduled_evaluation_run" - ].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.export_evaluations(request) - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["scheduled_evaluation_run"][field])): - del request_init["scheduled_evaluation_run"][field][i][subfield] - else: - del request_init["scheduled_evaluation_run"][field][subfield] +@pytest.mark.parametrize( + "request_type", + [ + evaluation_service.ExportEvaluationsRequest, + dict, + ], +) +def test_export_evaluations_rest_call_success(request_type): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2/apps/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation.ScheduledEvaluationRun( - name="name_value", - display_name="display_name_value", - description="description_value", - active=True, - last_completed_run="last_completed_run_value", - total_executions=1738, - created_by="created_by_value", - last_updated_by="last_updated_by_value", - etag="etag_value", - ) + return_value = operations_pb2.Operation(name="operations/spam") # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = evaluation.ScheduledEvaluationRun.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_scheduled_evaluation_run(request) + response = client.export_evaluations(request) # Establish that the response is the type that we expect. - assert isinstance(response, evaluation.ScheduledEvaluationRun) - assert response.name == "name_value" - assert response.display_name == "display_name_value" - assert response.description == "description_value" - assert response.active is True - assert response.last_completed_run == "last_completed_run_value" - assert response.total_executions == 1738 - assert response.created_by == "created_by_value" - assert response.last_updated_by == "last_updated_by_value" - assert response.etag == "etag_value" + json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_scheduled_evaluation_run_rest_interceptors(null_interceptor): +def test_export_evaluations_rest_interceptors(null_interceptor): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -28098,24 +30336,23 @@ def test_update_scheduled_evaluation_run_rest_interceptors(null_interceptor): with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.EvaluationServiceRestInterceptor, - "post_update_scheduled_evaluation_run", + transports.EvaluationServiceRestInterceptor, "post_export_evaluations" ) as post, mock.patch.object( transports.EvaluationServiceRestInterceptor, - "post_update_scheduled_evaluation_run_with_metadata", + "post_export_evaluations_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.EvaluationServiceRestInterceptor, - "pre_update_scheduled_evaluation_run", + transports.EvaluationServiceRestInterceptor, "pre_export_evaluations" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = evaluation_service.UpdateScheduledEvaluationRunRequest.pb( - evaluation_service.UpdateScheduledEvaluationRunRequest() + pb_message = evaluation_service.ExportEvaluationsRequest.pb( + evaluation_service.ExportEvaluationsRequest() ) transcode.return_value = { "method": "post", @@ -28127,21 +30364,19 @@ def test_update_scheduled_evaluation_run_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = evaluation.ScheduledEvaluationRun.to_json( - evaluation.ScheduledEvaluationRun() - ) + return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = evaluation_service.UpdateScheduledEvaluationRunRequest() + request = evaluation_service.ExportEvaluationsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = evaluation.ScheduledEvaluationRun() - post_with_metadata.return_value = evaluation.ScheduledEvaluationRun(), metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.update_scheduled_evaluation_run( + client.export_evaluations( request, metadata=[ ("key", "val"), @@ -28154,16 +30389,14 @@ def test_update_scheduled_evaluation_run_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_delete_scheduled_evaluation_run_rest_bad_request( - request_type=evaluation_service.DeleteScheduledEvaluationRunRequest, +def test_export_evaluation_runs_rest_bad_request( + request_type=evaluation_service.ExportEvaluationRunsRequest, ): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/apps/sample3/scheduledEvaluationRuns/sample4" - } + request_init = {"parent": "projects/sample1/locations/sample2/apps/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -28179,47 +30412,45 @@ def test_delete_scheduled_evaluation_run_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_scheduled_evaluation_run(request) + client.export_evaluation_runs(request) @pytest.mark.parametrize( "request_type", [ - evaluation_service.DeleteScheduledEvaluationRunRequest, + evaluation_service.ExportEvaluationRunsRequest, dict, ], ) -def test_delete_scheduled_evaluation_run_rest_call_success(request_type): +def test_export_evaluation_runs_rest_call_success(request_type): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/apps/sample3/scheduledEvaluationRuns/sample4" - } + request_init = {"parent": "projects/sample1/locations/sample2/apps/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = None + return_value = operations_pb2.Operation(name="operations/spam") # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 - json_return_value = "" + json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_scheduled_evaluation_run(request) + response = client.export_evaluation_runs(request) # Establish that the response is the type that we expect. - assert response is None + json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_scheduled_evaluation_run_rest_interceptors(null_interceptor): +def test_export_evaluation_runs_rest_interceptors(null_interceptor): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -28231,14 +30462,23 @@ def test_delete_scheduled_evaluation_run_rest_interceptors(null_interceptor): with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), + mock.patch.object( + transports.EvaluationServiceRestInterceptor, "post_export_evaluation_runs" + ) as post, mock.patch.object( transports.EvaluationServiceRestInterceptor, - "pre_delete_scheduled_evaluation_run", + "post_export_evaluation_runs_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.EvaluationServiceRestInterceptor, "pre_export_evaluation_runs" ) as pre, ): pre.assert_not_called() - pb_message = evaluation_service.DeleteScheduledEvaluationRunRequest.pb( - evaluation_service.DeleteScheduledEvaluationRunRequest() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = evaluation_service.ExportEvaluationRunsRequest.pb( + evaluation_service.ExportEvaluationRunsRequest() ) transcode.return_value = { "method": "post", @@ -28250,15 +30490,19 @@ def test_delete_scheduled_evaluation_run_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value - request = evaluation_service.DeleteScheduledEvaluationRunRequest() + request = evaluation_service.ExportEvaluationRunsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.delete_scheduled_evaluation_run( + client.export_evaluation_runs( request, metadata=[ ("key", "val"), @@ -28267,16 +30511,20 @@ def test_delete_scheduled_evaluation_run_rest_interceptors(null_interceptor): ) pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() -def test_test_persona_voice_rest_bad_request( - request_type=evaluation_service.TestPersonaVoiceRequest, +def test_export_evaluation_results_rest_bad_request( + request_type=evaluation_service.ExportEvaluationResultsRequest, ): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"app": "projects/sample1/locations/sample2/apps/sample3"} + request_init = { + "parent": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4" + } request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -28292,51 +30540,47 @@ def test_test_persona_voice_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.test_persona_voice(request) + client.export_evaluation_results(request) @pytest.mark.parametrize( "request_type", [ - evaluation_service.TestPersonaVoiceRequest, + evaluation_service.ExportEvaluationResultsRequest, dict, ], ) -def test_test_persona_voice_rest_call_success(request_type): +def test_export_evaluation_results_rest_call_success(request_type): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"app": "projects/sample1/locations/sample2/apps/sample3"} + request_init = { + "parent": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4" + } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = evaluation_service.TestPersonaVoiceResponse( - audio=b"audio_blob", - ) + return_value = operations_pb2.Operation(name="operations/spam") # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = evaluation_service.TestPersonaVoiceResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.test_persona_voice(request) + response = client.export_evaluation_results(request) # Establish that the response is the type that we expect. - assert isinstance(response, evaluation_service.TestPersonaVoiceResponse) - assert response.audio == b"audio_blob" + json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_test_persona_voice_rest_interceptors(null_interceptor): +def test_export_evaluation_results_rest_interceptors(null_interceptor): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -28348,22 +30592,24 @@ def test_test_persona_voice_rest_interceptors(null_interceptor): with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.EvaluationServiceRestInterceptor, "post_test_persona_voice" + transports.EvaluationServiceRestInterceptor, + "post_export_evaluation_results", ) as post, mock.patch.object( transports.EvaluationServiceRestInterceptor, - "post_test_persona_voice_with_metadata", + "post_export_evaluation_results_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.EvaluationServiceRestInterceptor, "pre_test_persona_voice" + transports.EvaluationServiceRestInterceptor, "pre_export_evaluation_results" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = evaluation_service.TestPersonaVoiceRequest.pb( - evaluation_service.TestPersonaVoiceRequest() + pb_message = evaluation_service.ExportEvaluationResultsRequest.pb( + evaluation_service.ExportEvaluationResultsRequest() ) transcode.return_value = { "method": "post", @@ -28375,24 +30621,19 @@ def test_test_persona_voice_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = evaluation_service.TestPersonaVoiceResponse.to_json( - evaluation_service.TestPersonaVoiceResponse() - ) + return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = evaluation_service.TestPersonaVoiceRequest() + request = evaluation_service.ExportEvaluationResultsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = evaluation_service.TestPersonaVoiceResponse() - post_with_metadata.return_value = ( - evaluation_service.TestPersonaVoiceResponse(), - metadata, - ) + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.test_persona_voice( + client.export_evaluation_results( request, metadata=[ ("key", "val"), @@ -28405,14 +30646,16 @@ def test_test_persona_voice_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_export_evaluations_rest_bad_request( - request_type=evaluation_service.ExportEvaluationsRequest, +def test_run_evaluation_result_metrics_rest_bad_request( + request_type=evaluation_service.RunEvaluationResultMetricsRequest, ): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2/apps/sample3"} + request_init = { + "evaluation_result_id": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4/results/sample5" + } request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -28428,23 +30671,25 @@ def test_export_evaluations_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.export_evaluations(request) + client.run_evaluation_result_metrics(request) @pytest.mark.parametrize( "request_type", [ - evaluation_service.ExportEvaluationsRequest, + evaluation_service.RunEvaluationResultMetricsRequest, dict, ], ) -def test_export_evaluations_rest_call_success(request_type): +def test_run_evaluation_result_metrics_rest_call_success(request_type): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2/apps/sample3"} + request_init = { + "evaluation_result_id": "projects/sample1/locations/sample2/apps/sample3/evaluations/sample4/results/sample5" + } request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -28459,14 +30704,14 @@ def test_export_evaluations_rest_call_success(request_type): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.export_evaluations(request) + response = client.run_evaluation_result_metrics(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_export_evaluations_rest_interceptors(null_interceptor): +def test_run_evaluation_result_metrics_rest_interceptors(null_interceptor): transport = transports.EvaluationServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -28480,21 +30725,23 @@ def test_export_evaluations_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.EvaluationServiceRestInterceptor, "post_export_evaluations" + transports.EvaluationServiceRestInterceptor, + "post_run_evaluation_result_metrics", ) as post, mock.patch.object( transports.EvaluationServiceRestInterceptor, - "post_export_evaluations_with_metadata", + "post_run_evaluation_result_metrics_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.EvaluationServiceRestInterceptor, "pre_export_evaluations" + transports.EvaluationServiceRestInterceptor, + "pre_run_evaluation_result_metrics", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = evaluation_service.ExportEvaluationsRequest.pb( - evaluation_service.ExportEvaluationsRequest() + pb_message = evaluation_service.RunEvaluationResultMetricsRequest.pb( + evaluation_service.RunEvaluationResultMetricsRequest() ) transcode.return_value = { "method": "post", @@ -28509,7 +30756,7 @@ def test_export_evaluations_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = evaluation_service.ExportEvaluationsRequest() + request = evaluation_service.RunEvaluationResultMetricsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -28518,7 +30765,7 @@ def test_export_evaluations_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.export_evaluations( + client.run_evaluation_result_metrics( request, metadata=[ ("key", "val"), @@ -29578,6 +31825,69 @@ def test_export_evaluations_empty_call_rest(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_export_evaluation_runs_empty_call_rest(): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.export_evaluation_runs), "__call__" + ) as call: + client.export_evaluation_runs(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = evaluation_service.ExportEvaluationRunsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_export_evaluation_results_empty_call_rest(): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.export_evaluation_results), "__call__" + ) as call: + client.export_evaluation_results(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = evaluation_service.ExportEvaluationResultsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_run_evaluation_result_metrics_empty_call_rest(): + client = EvaluationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.run_evaluation_result_metrics), "__call__" + ) as call: + client.run_evaluation_result_metrics(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = evaluation_service.RunEvaluationResultMetricsRequest() + assert args[0] == request_msg + + def test_evaluation_service_rest_lro_client(): client = EvaluationServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -29660,6 +31970,9 @@ def test_evaluation_service_base_transport(): "delete_scheduled_evaluation_run", "test_persona_voice", "export_evaluations", + "export_evaluation_runs", + "export_evaluation_results", + "run_evaluation_result_metrics", "get_location", "list_locations", "get_operation", @@ -30042,6 +32355,15 @@ def test_evaluation_service_client_transport_session_collision(transport_name): session1 = client1.transport.export_evaluations._session session2 = client2.transport.export_evaluations._session assert session1 != session2 + session1 = client1.transport.export_evaluation_runs._session + session2 = client2.transport.export_evaluation_runs._session + assert session1 != session2 + session1 = client1.transport.export_evaluation_results._session + session2 = client2.transport.export_evaluation_results._session + assert session1 != session2 + session1 = client1.transport.run_evaluation_result_metrics._session + session2 = client2.transport.run_evaluation_result_metrics._session + assert session1 != session2 def test_evaluation_service_grpc_transport_channel(): diff --git a/packages/google-cloud-ces/tests/unit/gapic/ces_v1beta/test_tool_service.py b/packages/google-cloud-ces/tests/unit/gapic/ces_v1beta/test_tool_service.py index 91b7ed58b66b..f689fda479f7 100644 --- a/packages/google-cloud-ces/tests/unit/gapic/ces_v1beta/test_tool_service.py +++ b/packages/google-cloud-ces/tests/unit/gapic/ces_v1beta/test_tool_service.py @@ -63,6 +63,7 @@ from google.cloud.ces_v1beta.types import ( mocks, schema, + search_suggestions, session_service, tool, tool_service, diff --git a/packages/google-cloud-confidentialcomputing/google/cloud/confidentialcomputing_v1/services/confidential_computing/async_client.py b/packages/google-cloud-confidentialcomputing/google/cloud/confidentialcomputing_v1/services/confidential_computing/async_client.py index dc575bbe56f4..f5fc593fff9f 100644 --- a/packages/google-cloud-confidentialcomputing/google/cloud/confidentialcomputing_v1/services/confidential_computing/async_client.py +++ b/packages/google-cloud-confidentialcomputing/google/cloud/confidentialcomputing_v1/services/confidential_computing/async_client.py @@ -80,6 +80,8 @@ class ConfidentialComputingAsyncClient: parse_challenge_path = staticmethod( ConfidentialComputingClient.parse_challenge_path ) + instance_path = staticmethod(ConfidentialComputingClient.instance_path) + parse_instance_path = staticmethod(ConfidentialComputingClient.parse_instance_path) common_billing_account_path = staticmethod( ConfidentialComputingClient.common_billing_account_path ) diff --git a/packages/google-cloud-confidentialcomputing/google/cloud/confidentialcomputing_v1/services/confidential_computing/client.py b/packages/google-cloud-confidentialcomputing/google/cloud/confidentialcomputing_v1/services/confidential_computing/client.py index 170c3616a4c0..ae062b8399cf 100644 --- a/packages/google-cloud-confidentialcomputing/google/cloud/confidentialcomputing_v1/services/confidential_computing/client.py +++ b/packages/google-cloud-confidentialcomputing/google/cloud/confidentialcomputing_v1/services/confidential_computing/client.py @@ -251,6 +251,28 @@ def parse_challenge_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def instance_path( + project: str, + zone: str, + instance: str, + ) -> str: + """Returns a fully-qualified instance string.""" + return "projects/{project}/zones/{zone}/instances/{instance}".format( + project=project, + zone=zone, + instance=instance, + ) + + @staticmethod + def parse_instance_path(path: str) -> Dict[str, str]: + """Parses a instance path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/zones/(?P.+?)/instances/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def common_billing_account_path( billing_account: str, diff --git a/packages/google-cloud-confidentialcomputing/google/cloud/confidentialcomputing_v1/types/service.py b/packages/google-cloud-confidentialcomputing/google/cloud/confidentialcomputing_v1/types/service.py index eb0ab92b3e37..da138cc82134 100644 --- a/packages/google-cloud-confidentialcomputing/google/cloud/confidentialcomputing_v1/types/service.py +++ b/packages/google-cloud-confidentialcomputing/google/cloud/confidentialcomputing_v1/types/service.py @@ -254,6 +254,10 @@ class VerifyAttestationRequest(proto.Message): attester (str): Optional. An optional indicator of the attester, only applies to certain products. + instance (str): + Optional. Optional resource link of the Compute Engine + instance. Format: + ``projects/{project_number}/zones/{zone}/instances/{instance_id}`` """ td_ccel: "TdxCcelAttestation" = proto.Field( @@ -302,6 +306,10 @@ class VerifyAttestationRequest(proto.Message): proto.STRING, number=8, ) + instance: str = proto.Field( + proto.STRING, + number=10, + ) class NvidiaAttestation(proto.Message): diff --git a/packages/google-cloud-confidentialcomputing/tests/unit/gapic/confidentialcomputing_v1/test_confidential_computing.py b/packages/google-cloud-confidentialcomputing/tests/unit/gapic/confidentialcomputing_v1/test_confidential_computing.py index d41ba1beb121..5254bb67e682 100644 --- a/packages/google-cloud-confidentialcomputing/tests/unit/gapic/confidentialcomputing_v1/test_confidential_computing.py +++ b/packages/google-cloud-confidentialcomputing/tests/unit/gapic/confidentialcomputing_v1/test_confidential_computing.py @@ -1779,6 +1779,7 @@ def test_verify_attestation_non_empty_request_with_auto_populated_field(): request = service.VerifyAttestationRequest( challenge="challenge_value", attester="attester_value", + instance="instance_value", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1794,6 +1795,7 @@ def test_verify_attestation_non_empty_request_with_auto_populated_field(): request_msg = service.VerifyAttestationRequest( challenge="challenge_value", attester="attester_value", + instance="instance_value", ) assert args[0] == request_msg @@ -4713,8 +4715,34 @@ def test_parse_challenge_path(): assert expected == actual +def test_instance_path(): + project = "cuttlefish" + zone = "mussel" + instance = "winkle" + expected = "projects/{project}/zones/{zone}/instances/{instance}".format( + project=project, + zone=zone, + instance=instance, + ) + actual = ConfidentialComputingClient.instance_path(project, zone, instance) + assert expected == actual + + +def test_parse_instance_path(): + expected = { + "project": "nautilus", + "zone": "scallop", + "instance": "abalone", + } + path = ConfidentialComputingClient.instance_path(**expected) + + # Check that the path construction is reversible. + actual = ConfidentialComputingClient.parse_instance_path(path) + assert expected == actual + + def test_common_billing_account_path(): - billing_account = "cuttlefish" + billing_account = "squid" expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -4724,7 +4752,7 @@ def test_common_billing_account_path(): def test_parse_common_billing_account_path(): expected = { - "billing_account": "mussel", + "billing_account": "clam", } path = ConfidentialComputingClient.common_billing_account_path(**expected) @@ -4734,7 +4762,7 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): - folder = "winkle" + folder = "whelk" expected = "folders/{folder}".format( folder=folder, ) @@ -4744,7 +4772,7 @@ def test_common_folder_path(): def test_parse_common_folder_path(): expected = { - "folder": "nautilus", + "folder": "octopus", } path = ConfidentialComputingClient.common_folder_path(**expected) @@ -4754,7 +4782,7 @@ def test_parse_common_folder_path(): def test_common_organization_path(): - organization = "scallop" + organization = "oyster" expected = "organizations/{organization}".format( organization=organization, ) @@ -4764,7 +4792,7 @@ def test_common_organization_path(): def test_parse_common_organization_path(): expected = { - "organization": "abalone", + "organization": "nudibranch", } path = ConfidentialComputingClient.common_organization_path(**expected) @@ -4774,7 +4802,7 @@ def test_parse_common_organization_path(): def test_common_project_path(): - project = "squid" + project = "cuttlefish" expected = "projects/{project}".format( project=project, ) @@ -4784,7 +4812,7 @@ def test_common_project_path(): def test_parse_common_project_path(): expected = { - "project": "clam", + "project": "mussel", } path = ConfidentialComputingClient.common_project_path(**expected) @@ -4794,8 +4822,8 @@ def test_parse_common_project_path(): def test_common_location_path(): - project = "whelk" - location = "octopus" + project = "winkle" + location = "nautilus" expected = "projects/{project}/locations/{location}".format( project=project, location=location, @@ -4806,8 +4834,8 @@ def test_common_location_path(): def test_parse_common_location_path(): expected = { - "project": "oyster", - "location": "nudibranch", + "project": "scallop", + "location": "abalone", } path = ConfidentialComputingClient.common_location_path(**expected) diff --git a/packages/google-cloud-modelarmor/google/cloud/modelarmor/__init__.py b/packages/google-cloud-modelarmor/google/cloud/modelarmor/__init__.py index e5440e5731c7..b41a7aadfa95 100644 --- a/packages/google-cloud-modelarmor/google/cloud/modelarmor/__init__.py +++ b/packages/google-cloud-modelarmor/google/cloud/modelarmor/__init__.py @@ -63,6 +63,7 @@ SdpFinding, SdpFindingLikelihood, SdpInspectResult, + StreamingMode, Template, UpdateFloorSettingRequest, UpdateTemplateRequest, @@ -118,4 +119,5 @@ "InvocationResult", "RaiFilterType", "SdpFindingLikelihood", + "StreamingMode", ) diff --git a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/__init__.py b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/__init__.py index 4f3cb402738e..c93c523b3f4a 100644 --- a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/__init__.py +++ b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/__init__.py @@ -65,6 +65,7 @@ SdpFinding, SdpFindingLikelihood, SdpInspectResult, + StreamingMode, Template, UpdateFloorSettingRequest, UpdateTemplateRequest, @@ -198,6 +199,7 @@ def _get_version(dependency_name): "SdpFinding", "SdpFindingLikelihood", "SdpInspectResult", + "StreamingMode", "Template", "UpdateFloorSettingRequest", "UpdateTemplateRequest", diff --git a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/gapic_metadata.json b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/gapic_metadata.json index 1597fcac7630..e675dbab5676 100644 --- a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/gapic_metadata.json +++ b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/gapic_metadata.json @@ -45,6 +45,16 @@ "sanitize_user_prompt" ] }, + "StreamSanitizeModelResponse": { + "methods": [ + "stream_sanitize_model_response" + ] + }, + "StreamSanitizeUserPrompt": { + "methods": [ + "stream_sanitize_user_prompt" + ] + }, "UpdateFloorSetting": { "methods": [ "update_floor_setting" @@ -95,6 +105,16 @@ "sanitize_user_prompt" ] }, + "StreamSanitizeModelResponse": { + "methods": [ + "stream_sanitize_model_response" + ] + }, + "StreamSanitizeUserPrompt": { + "methods": [ + "stream_sanitize_user_prompt" + ] + }, "UpdateFloorSetting": { "methods": [ "update_floor_setting" @@ -145,6 +165,16 @@ "sanitize_user_prompt" ] }, + "StreamSanitizeModelResponse": { + "methods": [ + "stream_sanitize_model_response" + ] + }, + "StreamSanitizeUserPrompt": { + "methods": [ + "stream_sanitize_user_prompt" + ] + }, "UpdateFloorSetting": { "methods": [ "update_floor_setting" diff --git a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/services/model_armor/async_client.py b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/services/model_armor/async_client.py index 608d54bbdf89..e594d0e5c71e 100644 --- a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/services/model_armor/async_client.py +++ b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/services/model_armor/async_client.py @@ -17,6 +17,9 @@ import re from collections import OrderedDict from typing import ( + AsyncIterable, + AsyncIterator, + Awaitable, Callable, Dict, Mapping, @@ -1280,6 +1283,180 @@ async def sample_sanitize_model_response(): # Done; return the response. return response + def stream_sanitize_user_prompt( + self, + requests: Optional[AsyncIterator[service.SanitizeUserPromptRequest]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> Awaitable[AsyncIterable[service.SanitizeUserPromptResponse]]: + r"""Streaming version of Sanitize User Prompt. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import modelarmor_v1 + + async def sample_stream_sanitize_user_prompt(): + # Create a client + client = modelarmor_v1.ModelArmorAsyncClient() + + # Initialize request argument(s) + user_prompt_data = modelarmor_v1.DataItem() + user_prompt_data.text = "text_value" + + request = modelarmor_v1.SanitizeUserPromptRequest( + name="name_value", + user_prompt_data=user_prompt_data, + ) + + # This method expects an iterator which contains + # 'modelarmor_v1.SanitizeUserPromptRequest' objects + # Here we create a generator that yields a single `request` for + # demonstrative purposes. + requests = [request] + + def request_generator(): + for request in requests: + yield request + + # Make the request + stream = await client.stream_sanitize_user_prompt(requests=request_generator()) + + # Handle the response + async for response in stream: + print(response) + + Args: + requests (AsyncIterator[`google.cloud.modelarmor_v1.types.SanitizeUserPromptRequest`]): + The request object AsyncIterator. Sanitize User Prompt request. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + AsyncIterable[google.cloud.modelarmor_v1.types.SanitizeUserPromptResponse]: + Sanitized User Prompt Response. + """ + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.stream_sanitize_user_prompt + ] + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = rpc( + requests, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def stream_sanitize_model_response( + self, + requests: Optional[AsyncIterator[service.SanitizeModelResponseRequest]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> Awaitable[AsyncIterable[service.SanitizeModelResponseResponse]]: + r"""Streaming version of Sanitizes Model Response. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import modelarmor_v1 + + async def sample_stream_sanitize_model_response(): + # Create a client + client = modelarmor_v1.ModelArmorAsyncClient() + + # Initialize request argument(s) + model_response_data = modelarmor_v1.DataItem() + model_response_data.text = "text_value" + + request = modelarmor_v1.SanitizeModelResponseRequest( + name="name_value", + model_response_data=model_response_data, + ) + + # This method expects an iterator which contains + # 'modelarmor_v1.SanitizeModelResponseRequest' objects + # Here we create a generator that yields a single `request` for + # demonstrative purposes. + requests = [request] + + def request_generator(): + for request in requests: + yield request + + # Make the request + stream = await client.stream_sanitize_model_response(requests=request_generator()) + + # Handle the response + async for response in stream: + print(response) + + Args: + requests (AsyncIterator[`google.cloud.modelarmor_v1.types.SanitizeModelResponseRequest`]): + The request object AsyncIterator. Sanitize Model Response request. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + AsyncIterable[google.cloud.modelarmor_v1.types.SanitizeModelResponseResponse]: + Sanitized Model Response Response. + """ + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.stream_sanitize_model_response + ] + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = rpc( + requests, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + async def get_location( self, request: Optional[Union[locations_pb2.GetLocationRequest, dict]] = None, diff --git a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/services/model_armor/client.py b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/services/model_armor/client.py index 520dddae959d..8e5c48862d87 100644 --- a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/services/model_armor/client.py +++ b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/services/model_armor/client.py @@ -23,6 +23,8 @@ from typing import ( Callable, Dict, + Iterable, + Iterator, Mapping, MutableMapping, MutableSequence, @@ -1710,6 +1712,180 @@ def sample_sanitize_model_response(): # Done; return the response. return response + def stream_sanitize_user_prompt( + self, + requests: Optional[Iterator[service.SanitizeUserPromptRequest]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> Iterable[service.SanitizeUserPromptResponse]: + r"""Streaming version of Sanitize User Prompt. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import modelarmor_v1 + + def sample_stream_sanitize_user_prompt(): + # Create a client + client = modelarmor_v1.ModelArmorClient() + + # Initialize request argument(s) + user_prompt_data = modelarmor_v1.DataItem() + user_prompt_data.text = "text_value" + + request = modelarmor_v1.SanitizeUserPromptRequest( + name="name_value", + user_prompt_data=user_prompt_data, + ) + + # This method expects an iterator which contains + # 'modelarmor_v1.SanitizeUserPromptRequest' objects + # Here we create a generator that yields a single `request` for + # demonstrative purposes. + requests = [request] + + def request_generator(): + for request in requests: + yield request + + # Make the request + stream = client.stream_sanitize_user_prompt(requests=request_generator()) + + # Handle the response + for response in stream: + print(response) + + Args: + requests (Iterator[google.cloud.modelarmor_v1.types.SanitizeUserPromptRequest]): + The request object iterator. Sanitize User Prompt 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + Iterable[google.cloud.modelarmor_v1.types.SanitizeUserPromptResponse]: + Sanitized User Prompt Response. + """ + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.stream_sanitize_user_prompt + ] + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + requests, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def stream_sanitize_model_response( + self, + requests: Optional[Iterator[service.SanitizeModelResponseRequest]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> Iterable[service.SanitizeModelResponseResponse]: + r"""Streaming version of Sanitizes Model Response. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import modelarmor_v1 + + def sample_stream_sanitize_model_response(): + # Create a client + client = modelarmor_v1.ModelArmorClient() + + # Initialize request argument(s) + model_response_data = modelarmor_v1.DataItem() + model_response_data.text = "text_value" + + request = modelarmor_v1.SanitizeModelResponseRequest( + name="name_value", + model_response_data=model_response_data, + ) + + # This method expects an iterator which contains + # 'modelarmor_v1.SanitizeModelResponseRequest' objects + # Here we create a generator that yields a single `request` for + # demonstrative purposes. + requests = [request] + + def request_generator(): + for request in requests: + yield request + + # Make the request + stream = client.stream_sanitize_model_response(requests=request_generator()) + + # Handle the response + for response in stream: + print(response) + + Args: + requests (Iterator[google.cloud.modelarmor_v1.types.SanitizeModelResponseRequest]): + The request object iterator. Sanitize Model Response 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + Iterable[google.cloud.modelarmor_v1.types.SanitizeModelResponseResponse]: + Sanitized Model Response Response. + """ + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.stream_sanitize_model_response + ] + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + requests, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + def __enter__(self) -> "ModelArmorClient": return self diff --git a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/services/model_armor/transports/base.py b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/services/model_armor/transports/base.py index 1705fb185db6..575fb054b294 100644 --- a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/services/model_armor/transports/base.py +++ b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/services/model_armor/transports/base.py @@ -234,6 +234,16 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), + self.stream_sanitize_user_prompt: gapic_v1.method.wrap_method( + self.stream_sanitize_user_prompt, + default_timeout=None, + client_info=client_info, + ), + self.stream_sanitize_model_response: gapic_v1.method.wrap_method( + self.stream_sanitize_model_response, + default_timeout=None, + client_info=client_info, + ), self.get_location: gapic_v1.method.wrap_method( self.get_location, default_timeout=None, @@ -342,6 +352,30 @@ def sanitize_model_response( ]: raise NotImplementedError() + @property + def stream_sanitize_user_prompt( + self, + ) -> Callable[ + [service.SanitizeUserPromptRequest], + Union[ + service.SanitizeUserPromptResponse, + Awaitable[service.SanitizeUserPromptResponse], + ], + ]: + raise NotImplementedError() + + @property + def stream_sanitize_model_response( + self, + ) -> Callable[ + [service.SanitizeModelResponseRequest], + Union[ + service.SanitizeModelResponseResponse, + Awaitable[service.SanitizeModelResponseResponse], + ], + ]: + raise NotImplementedError() + @property def get_location( self, diff --git a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/services/model_armor/transports/grpc.py b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/services/model_armor/transports/grpc.py index e9f69d3ed9b8..0362a5ccc9e8 100644 --- a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/services/model_armor/transports/grpc.py +++ b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/services/model_armor/transports/grpc.py @@ -565,6 +565,66 @@ def sanitize_model_response( ) return self._stubs["sanitize_model_response"] + @property + def stream_sanitize_user_prompt( + self, + ) -> Callable[ + [service.SanitizeUserPromptRequest], service.SanitizeUserPromptResponse + ]: + r"""Return a callable for the stream sanitize user prompt method over gRPC. + + Streaming version of Sanitize User Prompt. + + Returns: + Callable[[~.SanitizeUserPromptRequest], + ~.SanitizeUserPromptResponse]: + 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 "stream_sanitize_user_prompt" not in self._stubs: + self._stubs["stream_sanitize_user_prompt"] = ( + self._logged_channel.stream_stream( + "/google.cloud.modelarmor.v1.ModelArmor/StreamSanitizeUserPrompt", + request_serializer=service.SanitizeUserPromptRequest.serialize, + response_deserializer=service.SanitizeUserPromptResponse.deserialize, + ) + ) + return self._stubs["stream_sanitize_user_prompt"] + + @property + def stream_sanitize_model_response( + self, + ) -> Callable[ + [service.SanitizeModelResponseRequest], service.SanitizeModelResponseResponse + ]: + r"""Return a callable for the stream sanitize model response method over gRPC. + + Streaming version of Sanitizes Model Response. + + Returns: + Callable[[~.SanitizeModelResponseRequest], + ~.SanitizeModelResponseResponse]: + 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 "stream_sanitize_model_response" not in self._stubs: + self._stubs["stream_sanitize_model_response"] = ( + self._logged_channel.stream_stream( + "/google.cloud.modelarmor.v1.ModelArmor/StreamSanitizeModelResponse", + request_serializer=service.SanitizeModelResponseRequest.serialize, + response_deserializer=service.SanitizeModelResponseResponse.deserialize, + ) + ) + return self._stubs["stream_sanitize_model_response"] + def close(self): self._logged_channel.close() diff --git a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/services/model_armor/transports/grpc_asyncio.py b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/services/model_armor/transports/grpc_asyncio.py index 7a44d18f9e54..c9fff56abec8 100644 --- a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/services/model_armor/transports/grpc_asyncio.py +++ b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/services/model_armor/transports/grpc_asyncio.py @@ -579,6 +579,68 @@ def sanitize_model_response( ) return self._stubs["sanitize_model_response"] + @property + def stream_sanitize_user_prompt( + self, + ) -> Callable[ + [service.SanitizeUserPromptRequest], + Awaitable[service.SanitizeUserPromptResponse], + ]: + r"""Return a callable for the stream sanitize user prompt method over gRPC. + + Streaming version of Sanitize User Prompt. + + Returns: + Callable[[~.SanitizeUserPromptRequest], + Awaitable[~.SanitizeUserPromptResponse]]: + 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 "stream_sanitize_user_prompt" not in self._stubs: + self._stubs["stream_sanitize_user_prompt"] = ( + self._logged_channel.stream_stream( + "/google.cloud.modelarmor.v1.ModelArmor/StreamSanitizeUserPrompt", + request_serializer=service.SanitizeUserPromptRequest.serialize, + response_deserializer=service.SanitizeUserPromptResponse.deserialize, + ) + ) + return self._stubs["stream_sanitize_user_prompt"] + + @property + def stream_sanitize_model_response( + self, + ) -> Callable[ + [service.SanitizeModelResponseRequest], + Awaitable[service.SanitizeModelResponseResponse], + ]: + r"""Return a callable for the stream sanitize model response method over gRPC. + + Streaming version of Sanitizes Model Response. + + Returns: + Callable[[~.SanitizeModelResponseRequest], + Awaitable[~.SanitizeModelResponseResponse]]: + 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 "stream_sanitize_model_response" not in self._stubs: + self._stubs["stream_sanitize_model_response"] = ( + self._logged_channel.stream_stream( + "/google.cloud.modelarmor.v1.ModelArmor/StreamSanitizeModelResponse", + request_serializer=service.SanitizeModelResponseRequest.serialize, + response_deserializer=service.SanitizeModelResponseResponse.deserialize, + ) + ) + return self._stubs["stream_sanitize_model_response"] + def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { @@ -672,6 +734,16 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), + self.stream_sanitize_user_prompt: self._wrap_method( + self.stream_sanitize_user_prompt, + default_timeout=None, + client_info=client_info, + ), + self.stream_sanitize_model_response: self._wrap_method( + self.stream_sanitize_model_response, + default_timeout=None, + client_info=client_info, + ), self.get_location: self._wrap_method( self.get_location, default_timeout=None, diff --git a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/services/model_armor/transports/rest.py b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/services/model_armor/transports/rest.py index 731a96b8adc9..dba1a866b9f6 100644 --- a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/services/model_armor/transports/rest.py +++ b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/services/model_armor/transports/rest.py @@ -1691,6 +1691,43 @@ def __call__( ) return resp + class _StreamSanitizeModelResponse( + _BaseModelArmorRestTransport._BaseStreamSanitizeModelResponse, + ModelArmorRestStub, + ): + def __hash__(self): + return hash("ModelArmorRestTransport.StreamSanitizeModelResponse") + + def __call__( + self, + request: service.SanitizeModelResponseRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> rest_streaming.ResponseIterator: + raise NotImplementedError( + "Method StreamSanitizeModelResponse is not available over REST transport" + ) + + class _StreamSanitizeUserPrompt( + _BaseModelArmorRestTransport._BaseStreamSanitizeUserPrompt, ModelArmorRestStub + ): + def __hash__(self): + return hash("ModelArmorRestTransport.StreamSanitizeUserPrompt") + + def __call__( + self, + request: service.SanitizeUserPromptRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> rest_streaming.ResponseIterator: + raise NotImplementedError( + "Method StreamSanitizeUserPrompt is not available over REST transport" + ) + class _UpdateFloorSetting( _BaseModelArmorRestTransport._BaseUpdateFloorSetting, ModelArmorRestStub ): @@ -2057,6 +2094,30 @@ def sanitize_user_prompt( # In C++ this would require a dynamic_cast return self._SanitizeUserPrompt(self._session, self._host, self._interceptor) # type: ignore + @property + def stream_sanitize_model_response( + self, + ) -> Callable[ + [service.SanitizeModelResponseRequest], service.SanitizeModelResponseResponse + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._StreamSanitizeModelResponse( + self._session, self._host, self._interceptor + ) # type: ignore + + @property + def stream_sanitize_user_prompt( + self, + ) -> Callable[ + [service.SanitizeUserPromptRequest], service.SanitizeUserPromptResponse + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._StreamSanitizeUserPrompt( + self._session, self._host, self._interceptor + ) # type: ignore + @property def update_floor_setting( self, diff --git a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/services/model_armor/transports/rest_base.py b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/services/model_armor/transports/rest_base.py index 4fc5ff490866..c70a5a387a89 100644 --- a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/services/model_armor/transports/rest_base.py +++ b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/services/model_armor/transports/rest_base.py @@ -458,6 +458,14 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params + class _BaseStreamSanitizeModelResponse: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + class _BaseStreamSanitizeUserPrompt: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + class _BaseUpdateFloorSetting: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") diff --git a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/types/__init__.py b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/types/__init__.py index d7ac393cbe7a..803dc9a29614 100644 --- a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/types/__init__.py +++ b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/types/__init__.py @@ -54,6 +54,7 @@ SdpFinding, SdpFindingLikelihood, SdpInspectResult, + StreamingMode, Template, UpdateFloorSettingRequest, UpdateTemplateRequest, @@ -107,4 +108,5 @@ "InvocationResult", "RaiFilterType", "SdpFindingLikelihood", + "StreamingMode", ) diff --git a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/types/service.py b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/types/service.py index 4499ee07e551..7187ce979be8 100644 --- a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/types/service.py +++ b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/types/service.py @@ -30,6 +30,7 @@ "DetectionConfidenceLevel", "SdpFindingLikelihood", "InvocationResult", + "StreamingMode", "Template", "FloorSetting", "AiPlatformFloorSetting", @@ -205,6 +206,23 @@ class InvocationResult(proto.Enum): FAILURE = 3 +class StreamingMode(proto.Enum): + r"""Streaming Mode for Sanitize\* API. + + Values: + STREAMING_MODE_UNSPECIFIED (0): + Default value. + STREAMING_MODE_BUFFERED (1): + Buffered Streaming mode. + STREAMING_MODE_REALTIME (2): + Real Time Streaming mode. + """ + + STREAMING_MODE_UNSPECIFIED = 0 + STREAMING_MODE_BUFFERED = 1 + STREAMING_MODE_REALTIME = 2 + + class Template(proto.Message): r"""Message describing Template resource @@ -1076,6 +1094,8 @@ class SdpAdvancedConfig(proto.Message): class SanitizeUserPromptRequest(proto.Message): r"""Sanitize User Prompt request. + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + Attributes: name (str): Required. Represents resource name of @@ -1086,6 +1106,10 @@ class SanitizeUserPromptRequest(proto.Message): multi_language_detection_metadata (google.cloud.modelarmor_v1.types.MultiLanguageDetectionMetadata): Optional. Metadata related to Multi Language Detection. + streaming_mode (google.cloud.modelarmor_v1.types.StreamingMode): + Optional. Streaming Mode for StreamSanitize\* API. + + This field is a member of `oneof`_ ``_streaming_mode``. """ name: str = proto.Field( @@ -1102,11 +1126,19 @@ class SanitizeUserPromptRequest(proto.Message): number=6, message="MultiLanguageDetectionMetadata", ) + streaming_mode: "StreamingMode" = proto.Field( + proto.ENUM, + number=7, + optional=True, + enum="StreamingMode", + ) class SanitizeModelResponseRequest(proto.Message): r"""Sanitize Model Response request. + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + Attributes: name (str): Required. Represents resource name of @@ -1120,6 +1152,10 @@ class SanitizeModelResponseRequest(proto.Message): multi_language_detection_metadata (google.cloud.modelarmor_v1.types.MultiLanguageDetectionMetadata): Optional. Metadata related for multi language detection. + streaming_mode (google.cloud.modelarmor_v1.types.StreamingMode): + Optional. Streaming Mode for StreamSanitize\* API. + + This field is a member of `oneof`_ ``_streaming_mode``. """ name: str = proto.Field( @@ -1140,6 +1176,12 @@ class SanitizeModelResponseRequest(proto.Message): number=7, message="MultiLanguageDetectionMetadata", ) + streaming_mode: "StreamingMode" = proto.Field( + proto.ENUM, + number=8, + optional=True, + enum="StreamingMode", + ) class SanitizeUserPromptResponse(proto.Message): @@ -1217,6 +1259,9 @@ class SanitizationMetadata(proto.Message): Passthrough field defined in TemplateMetadata to indicate whether to ignore partial invocation failures. + stream_chunk_processed (google.cloud.modelarmor_v1.types.DataItem): + Output only. The stream chunk processed by + the Sanitization service. """ error_code: int = proto.Field( @@ -1231,6 +1276,11 @@ class SanitizationMetadata(proto.Message): proto.BOOL, number=3, ) + stream_chunk_processed: "DataItem" = proto.Field( + proto.MESSAGE, + number=4, + message="DataItem", + ) filter_match_state: "FilterMatchState" = proto.Field( proto.ENUM, diff --git a/packages/google-cloud-modelarmor/samples/generated_samples/modelarmor_v1_generated_model_armor_stream_sanitize_model_response_async.py b/packages/google-cloud-modelarmor/samples/generated_samples/modelarmor_v1_generated_model_armor_stream_sanitize_model_response_async.py new file mode 100644 index 000000000000..d5b66a4ec3f4 --- /dev/null +++ b/packages/google-cloud-modelarmor/samples/generated_samples/modelarmor_v1_generated_model_armor_stream_sanitize_model_response_async.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for StreamSanitizeModelResponse +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-modelarmor + + +# [START modelarmor_v1_generated_ModelArmor_StreamSanitizeModelResponse_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import modelarmor_v1 + + +async def sample_stream_sanitize_model_response(): + # Create a client + client = modelarmor_v1.ModelArmorAsyncClient() + + # Initialize request argument(s) + model_response_data = modelarmor_v1.DataItem() + model_response_data.text = "text_value" + + request = modelarmor_v1.SanitizeModelResponseRequest( + name="name_value", + model_response_data=model_response_data, + ) + + # This method expects an iterator which contains + # 'modelarmor_v1.SanitizeModelResponseRequest' objects + # Here we create a generator that yields a single `request` for + # demonstrative purposes. + requests = [request] + + def request_generator(): + for request in requests: + yield request + + # Make the request + stream = await client.stream_sanitize_model_response(requests=request_generator()) + + # Handle the response + async for response in stream: + print(response) + + +# [END modelarmor_v1_generated_ModelArmor_StreamSanitizeModelResponse_async] diff --git a/packages/google-cloud-modelarmor/samples/generated_samples/modelarmor_v1_generated_model_armor_stream_sanitize_model_response_sync.py b/packages/google-cloud-modelarmor/samples/generated_samples/modelarmor_v1_generated_model_armor_stream_sanitize_model_response_sync.py new file mode 100644 index 000000000000..7c1a141649a3 --- /dev/null +++ b/packages/google-cloud-modelarmor/samples/generated_samples/modelarmor_v1_generated_model_armor_stream_sanitize_model_response_sync.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for StreamSanitizeModelResponse +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-modelarmor + + +# [START modelarmor_v1_generated_ModelArmor_StreamSanitizeModelResponse_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import modelarmor_v1 + + +def sample_stream_sanitize_model_response(): + # Create a client + client = modelarmor_v1.ModelArmorClient() + + # Initialize request argument(s) + model_response_data = modelarmor_v1.DataItem() + model_response_data.text = "text_value" + + request = modelarmor_v1.SanitizeModelResponseRequest( + name="name_value", + model_response_data=model_response_data, + ) + + # This method expects an iterator which contains + # 'modelarmor_v1.SanitizeModelResponseRequest' objects + # Here we create a generator that yields a single `request` for + # demonstrative purposes. + requests = [request] + + def request_generator(): + for request in requests: + yield request + + # Make the request + stream = client.stream_sanitize_model_response(requests=request_generator()) + + # Handle the response + for response in stream: + print(response) + + +# [END modelarmor_v1_generated_ModelArmor_StreamSanitizeModelResponse_sync] diff --git a/packages/google-cloud-modelarmor/samples/generated_samples/modelarmor_v1_generated_model_armor_stream_sanitize_user_prompt_async.py b/packages/google-cloud-modelarmor/samples/generated_samples/modelarmor_v1_generated_model_armor_stream_sanitize_user_prompt_async.py new file mode 100644 index 000000000000..e8fa7e643f8d --- /dev/null +++ b/packages/google-cloud-modelarmor/samples/generated_samples/modelarmor_v1_generated_model_armor_stream_sanitize_user_prompt_async.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for StreamSanitizeUserPrompt +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-modelarmor + + +# [START modelarmor_v1_generated_ModelArmor_StreamSanitizeUserPrompt_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import modelarmor_v1 + + +async def sample_stream_sanitize_user_prompt(): + # Create a client + client = modelarmor_v1.ModelArmorAsyncClient() + + # Initialize request argument(s) + user_prompt_data = modelarmor_v1.DataItem() + user_prompt_data.text = "text_value" + + request = modelarmor_v1.SanitizeUserPromptRequest( + name="name_value", + user_prompt_data=user_prompt_data, + ) + + # This method expects an iterator which contains + # 'modelarmor_v1.SanitizeUserPromptRequest' objects + # Here we create a generator that yields a single `request` for + # demonstrative purposes. + requests = [request] + + def request_generator(): + for request in requests: + yield request + + # Make the request + stream = await client.stream_sanitize_user_prompt(requests=request_generator()) + + # Handle the response + async for response in stream: + print(response) + + +# [END modelarmor_v1_generated_ModelArmor_StreamSanitizeUserPrompt_async] diff --git a/packages/google-cloud-modelarmor/samples/generated_samples/modelarmor_v1_generated_model_armor_stream_sanitize_user_prompt_sync.py b/packages/google-cloud-modelarmor/samples/generated_samples/modelarmor_v1_generated_model_armor_stream_sanitize_user_prompt_sync.py new file mode 100644 index 000000000000..2b1e32fe5439 --- /dev/null +++ b/packages/google-cloud-modelarmor/samples/generated_samples/modelarmor_v1_generated_model_armor_stream_sanitize_user_prompt_sync.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for StreamSanitizeUserPrompt +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-modelarmor + + +# [START modelarmor_v1_generated_ModelArmor_StreamSanitizeUserPrompt_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import modelarmor_v1 + + +def sample_stream_sanitize_user_prompt(): + # Create a client + client = modelarmor_v1.ModelArmorClient() + + # Initialize request argument(s) + user_prompt_data = modelarmor_v1.DataItem() + user_prompt_data.text = "text_value" + + request = modelarmor_v1.SanitizeUserPromptRequest( + name="name_value", + user_prompt_data=user_prompt_data, + ) + + # This method expects an iterator which contains + # 'modelarmor_v1.SanitizeUserPromptRequest' objects + # Here we create a generator that yields a single `request` for + # demonstrative purposes. + requests = [request] + + def request_generator(): + for request in requests: + yield request + + # Make the request + stream = client.stream_sanitize_user_prompt(requests=request_generator()) + + # Handle the response + for response in stream: + print(response) + + +# [END modelarmor_v1_generated_ModelArmor_StreamSanitizeUserPrompt_sync] diff --git a/packages/google-cloud-modelarmor/samples/generated_samples/snippet_metadata_google.cloud.modelarmor.v1.json b/packages/google-cloud-modelarmor/samples/generated_samples/snippet_metadata_google.cloud.modelarmor.v1.json index 5c4dd1c2f263..acc1dee1e100 100644 --- a/packages/google-cloud-modelarmor/samples/generated_samples/snippet_metadata_google.cloud.modelarmor.v1.json +++ b/packages/google-cloud-modelarmor/samples/generated_samples/snippet_metadata_google.cloud.modelarmor.v1.json @@ -1132,6 +1132,312 @@ ], "title": "modelarmor_v1_generated_model_armor_sanitize_user_prompt_sync.py" }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.modelarmor_v1.ModelArmorAsyncClient", + "shortName": "ModelArmorAsyncClient" + }, + "fullName": "google.cloud.modelarmor_v1.ModelArmorAsyncClient.stream_sanitize_model_response", + "method": { + "fullName": "google.cloud.modelarmor.v1.ModelArmor.StreamSanitizeModelResponse", + "service": { + "fullName": "google.cloud.modelarmor.v1.ModelArmor", + "shortName": "ModelArmor" + }, + "shortName": "StreamSanitizeModelResponse" + }, + "parameters": [ + { + "name": "requests", + "type": "Iterator[google.cloud.modelarmor_v1.types.SanitizeModelResponseRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "Iterable[google.cloud.modelarmor_v1.types.SanitizeModelResponseResponse]", + "shortName": "stream_sanitize_model_response" + }, + "description": "Sample for StreamSanitizeModelResponse", + "file": "modelarmor_v1_generated_model_armor_stream_sanitize_model_response_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "modelarmor_v1_generated_ModelArmor_StreamSanitizeModelResponse_async", + "segments": [ + { + "end": 66, + "start": 27, + "type": "FULL" + }, + { + "end": 66, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 59, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 62, + "start": 60, + "type": "REQUEST_EXECUTION" + }, + { + "end": 67, + "start": 63, + "type": "RESPONSE_HANDLING" + } + ], + "title": "modelarmor_v1_generated_model_armor_stream_sanitize_model_response_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.modelarmor_v1.ModelArmorClient", + "shortName": "ModelArmorClient" + }, + "fullName": "google.cloud.modelarmor_v1.ModelArmorClient.stream_sanitize_model_response", + "method": { + "fullName": "google.cloud.modelarmor.v1.ModelArmor.StreamSanitizeModelResponse", + "service": { + "fullName": "google.cloud.modelarmor.v1.ModelArmor", + "shortName": "ModelArmor" + }, + "shortName": "StreamSanitizeModelResponse" + }, + "parameters": [ + { + "name": "requests", + "type": "Iterator[google.cloud.modelarmor_v1.types.SanitizeModelResponseRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "Iterable[google.cloud.modelarmor_v1.types.SanitizeModelResponseResponse]", + "shortName": "stream_sanitize_model_response" + }, + "description": "Sample for StreamSanitizeModelResponse", + "file": "modelarmor_v1_generated_model_armor_stream_sanitize_model_response_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "modelarmor_v1_generated_ModelArmor_StreamSanitizeModelResponse_sync", + "segments": [ + { + "end": 66, + "start": 27, + "type": "FULL" + }, + { + "end": 66, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 59, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 62, + "start": 60, + "type": "REQUEST_EXECUTION" + }, + { + "end": 67, + "start": 63, + "type": "RESPONSE_HANDLING" + } + ], + "title": "modelarmor_v1_generated_model_armor_stream_sanitize_model_response_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.modelarmor_v1.ModelArmorAsyncClient", + "shortName": "ModelArmorAsyncClient" + }, + "fullName": "google.cloud.modelarmor_v1.ModelArmorAsyncClient.stream_sanitize_user_prompt", + "method": { + "fullName": "google.cloud.modelarmor.v1.ModelArmor.StreamSanitizeUserPrompt", + "service": { + "fullName": "google.cloud.modelarmor.v1.ModelArmor", + "shortName": "ModelArmor" + }, + "shortName": "StreamSanitizeUserPrompt" + }, + "parameters": [ + { + "name": "requests", + "type": "Iterator[google.cloud.modelarmor_v1.types.SanitizeUserPromptRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "Iterable[google.cloud.modelarmor_v1.types.SanitizeUserPromptResponse]", + "shortName": "stream_sanitize_user_prompt" + }, + "description": "Sample for StreamSanitizeUserPrompt", + "file": "modelarmor_v1_generated_model_armor_stream_sanitize_user_prompt_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "modelarmor_v1_generated_ModelArmor_StreamSanitizeUserPrompt_async", + "segments": [ + { + "end": 66, + "start": 27, + "type": "FULL" + }, + { + "end": 66, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 59, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 62, + "start": 60, + "type": "REQUEST_EXECUTION" + }, + { + "end": 67, + "start": 63, + "type": "RESPONSE_HANDLING" + } + ], + "title": "modelarmor_v1_generated_model_armor_stream_sanitize_user_prompt_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.modelarmor_v1.ModelArmorClient", + "shortName": "ModelArmorClient" + }, + "fullName": "google.cloud.modelarmor_v1.ModelArmorClient.stream_sanitize_user_prompt", + "method": { + "fullName": "google.cloud.modelarmor.v1.ModelArmor.StreamSanitizeUserPrompt", + "service": { + "fullName": "google.cloud.modelarmor.v1.ModelArmor", + "shortName": "ModelArmor" + }, + "shortName": "StreamSanitizeUserPrompt" + }, + "parameters": [ + { + "name": "requests", + "type": "Iterator[google.cloud.modelarmor_v1.types.SanitizeUserPromptRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "Iterable[google.cloud.modelarmor_v1.types.SanitizeUserPromptResponse]", + "shortName": "stream_sanitize_user_prompt" + }, + "description": "Sample for StreamSanitizeUserPrompt", + "file": "modelarmor_v1_generated_model_armor_stream_sanitize_user_prompt_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "modelarmor_v1_generated_ModelArmor_StreamSanitizeUserPrompt_sync", + "segments": [ + { + "end": 66, + "start": 27, + "type": "FULL" + }, + { + "end": 66, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 59, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 62, + "start": 60, + "type": "REQUEST_EXECUTION" + }, + { + "end": 67, + "start": 63, + "type": "RESPONSE_HANDLING" + } + ], + "title": "modelarmor_v1_generated_model_armor_stream_sanitize_user_prompt_sync.py" + }, { "canonical": true, "clientMethod": { diff --git a/packages/google-cloud-modelarmor/tests/unit/gapic/modelarmor_v1/test_model_armor.py b/packages/google-cloud-modelarmor/tests/unit/gapic/modelarmor_v1/test_model_armor.py index cd9535a7e721..871aa451e671 100644 --- a/packages/google-cloud-modelarmor/tests/unit/gapic/modelarmor_v1/test_model_armor.py +++ b/packages/google-cloud-modelarmor/tests/unit/gapic/modelarmor_v1/test_model_armor.py @@ -4333,6 +4333,326 @@ async def test_sanitize_model_response_field_headers_async(): ) in kw["metadata"] +@pytest.mark.parametrize( + "request_type", + [ + service.SanitizeUserPromptRequest(), + {}, + ], +) +def test_stream_sanitize_user_prompt(request_type, transport: str = "grpc"): + client = ModelArmorClient( + 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 + requests = [request] + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.stream_sanitize_user_prompt), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = iter([service.SanitizeUserPromptResponse()]) + response = client.stream_sanitize_user_prompt(iter(requests)) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert next(args[0]) == request + + # Establish that the response is the type that we expect. + for message in response: + assert isinstance(message, service.SanitizeUserPromptResponse) + + +def test_stream_sanitize_user_prompt_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ModelArmorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.stream_sanitize_user_prompt + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.stream_sanitize_user_prompt + ] = mock_rpc + request = [{}] + client.stream_sanitize_user_prompt(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.stream_sanitize_user_prompt(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_stream_sanitize_user_prompt_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = ModelArmorAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.stream_sanitize_user_prompt + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.stream_sanitize_user_prompt + ] = mock_rpc + + request = [{}] + await client.stream_sanitize_user_prompt(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.stream_sanitize_user_prompt(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + service.SanitizeUserPromptRequest(), + {}, + ], +) +async def test_stream_sanitize_user_prompt_async( + request_type, transport: str = "grpc_asyncio" +): + client = ModelArmorAsyncClient( + credentials=async_anonymous_credentials(), + 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 + requests = [request] + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.stream_sanitize_user_prompt), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = mock.Mock(aio.StreamStreamCall, autospec=True) + call.return_value.read = mock.AsyncMock( + side_effect=[service.SanitizeUserPromptResponse()] + ) + response = await client.stream_sanitize_user_prompt(iter(requests)) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert next(args[0]) == request + + # Establish that the response is the type that we expect. + message = await response.read() + assert isinstance(message, service.SanitizeUserPromptResponse) + + +@pytest.mark.parametrize( + "request_type", + [ + service.SanitizeModelResponseRequest(), + {}, + ], +) +def test_stream_sanitize_model_response(request_type, transport: str = "grpc"): + client = ModelArmorClient( + 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 + requests = [request] + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.stream_sanitize_model_response), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = iter([service.SanitizeModelResponseResponse()]) + response = client.stream_sanitize_model_response(iter(requests)) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert next(args[0]) == request + + # Establish that the response is the type that we expect. + for message in response: + assert isinstance(message, service.SanitizeModelResponseResponse) + + +def test_stream_sanitize_model_response_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ModelArmorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.stream_sanitize_model_response + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.stream_sanitize_model_response + ] = mock_rpc + request = [{}] + client.stream_sanitize_model_response(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.stream_sanitize_model_response(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_stream_sanitize_model_response_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = ModelArmorAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.stream_sanitize_model_response + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.stream_sanitize_model_response + ] = mock_rpc + + request = [{}] + await client.stream_sanitize_model_response(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.stream_sanitize_model_response(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + service.SanitizeModelResponseRequest(), + {}, + ], +) +async def test_stream_sanitize_model_response_async( + request_type, transport: str = "grpc_asyncio" +): + client = ModelArmorAsyncClient( + credentials=async_anonymous_credentials(), + 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 + requests = [request] + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.stream_sanitize_model_response), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = mock.Mock(aio.StreamStreamCall, autospec=True) + call.return_value.read = mock.AsyncMock( + side_effect=[service.SanitizeModelResponseResponse()] + ) + response = await client.stream_sanitize_model_response(iter(requests)) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert next(args[0]) == request + + # Establish that the response is the type that we expect. + message = await response.read() + assert isinstance(message, service.SanitizeModelResponseResponse) + + def test_list_templates_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -5985,6 +6305,56 @@ def test_sanitize_model_response_rest_unset_required_fields(): ) +def test_stream_sanitize_user_prompt_rest_no_http_options(): + client = ModelArmorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = service.SanitizeUserPromptRequest() + requests = [request] + with pytest.raises(RuntimeError): + client.stream_sanitize_user_prompt(requests) + + +def test_stream_sanitize_model_response_rest_no_http_options(): + client = ModelArmorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = service.SanitizeModelResponseRequest() + requests = [request] + with pytest.raises(RuntimeError): + client.stream_sanitize_model_response(requests) + + +def test_stream_sanitize_user_prompt_rest_error(): + client = ModelArmorClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # Since a `google.api.http` annotation is required for using a rest transport + # method, this should error. + with pytest.raises(NotImplementedError) as not_implemented_error: + client.stream_sanitize_user_prompt({}) + assert ( + "Method StreamSanitizeUserPrompt is not available over REST transport" + in str(not_implemented_error.value) + ) + + +def test_stream_sanitize_model_response_rest_error(): + client = ModelArmorClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # Since a `google.api.http` annotation is required for using a rest transport + # method, this should error. + with pytest.raises(NotImplementedError) as not_implemented_error: + client.stream_sanitize_model_response({}) + assert ( + "Method StreamSanitizeModelResponse is not available over REST transport" + in str(not_implemented_error.value) + ) + + def test_credentials_transport_error(): # It is an error to provide credentials and a transport instance. transport = transports.ModelArmorGrpcTransport( @@ -8000,6 +8370,32 @@ def test_sanitize_model_response_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() +def test_stream_sanitize_user_prompt_rest_error(): + client = ModelArmorClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + with pytest.raises(NotImplementedError) as not_implemented_error: + client.stream_sanitize_user_prompt({}) + assert ( + "Method StreamSanitizeUserPrompt is not available over REST transport" + in str(not_implemented_error.value) + ) + + +def test_stream_sanitize_model_response_rest_error(): + client = ModelArmorClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + with pytest.raises(NotImplementedError) as not_implemented_error: + client.stream_sanitize_model_response({}) + assert ( + "Method StreamSanitizeModelResponse is not available over REST transport" + in str(not_implemented_error.value) + ) + + def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): client = ModelArmorClient( credentials=ga_credentials.AnonymousCredentials(), @@ -8350,6 +8746,8 @@ def test_model_armor_base_transport(): "update_floor_setting", "sanitize_user_prompt", "sanitize_model_response", + "stream_sanitize_user_prompt", + "stream_sanitize_model_response", "get_location", "list_locations", ) @@ -8641,6 +9039,12 @@ def test_model_armor_client_transport_session_collision(transport_name): session1 = client1.transport.sanitize_model_response._session session2 = client2.transport.sanitize_model_response._session assert session1 != session2 + session1 = client1.transport.stream_sanitize_user_prompt._session + session2 = client2.transport.stream_sanitize_user_prompt._session + assert session1 != session2 + session1 = client1.transport.stream_sanitize_model_response._session + session2 = client2.transport.stream_sanitize_model_response._session + assert session1 != session2 def test_model_armor_grpc_transport_channel(): diff --git a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase/__init__.py b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase/__init__.py index 0ef7367c5e02..fc97096ed96f 100644 --- a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase/__init__.py +++ b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase/__init__.py @@ -124,6 +124,112 @@ ListExascaleDbStorageVaultsResponse, ) from google.cloud.oracledatabase_v1.types.gi_version import GiVersion +from google.cloud.oracledatabase_v1.types.goldengate_connection import ( + AmazonS3IcebergStorage, + AzureDataLakeStorageIcebergStorage, + CreateGoldengateConnectionRequest, + DeleteGoldengateConnectionRequest, + GetGoldengateConnectionRequest, + GlueIcebergCatalog, + GoldengateAmazonKinesisConnectionProperties, + GoldengateAmazonRedshiftConnectionProperties, + GoldengateAmazonS3ConnectionProperties, + GoldengateAzureDataLakeStorageConnectionProperties, + GoldengateAzureSynapseAnalyticsConnectionProperties, + GoldengateConnection, + GoldengateConnectionProperties, + GoldengateDatabricksConnectionProperties, + GoldengateDb2ConnectionProperties, + GoldengateElasticsearchConnectionProperties, + GoldengateGenericConnectionProperties, + GoldengateGoldengateConnectionProperties, + GoldengateGoogleBigQueryConnectionProperties, + GoldengateGoogleCloudStorageConnectionProperties, + GoldengateGooglePubsubConnectionProperties, + GoldengateHdfsConnectionProperties, + GoldengateIcebergConnectionProperties, + GoldengateJavaMessageServiceConnectionProperties, + GoldengateKafkaConnectionProperties, + GoldengateKafkaSchemaRegistryConnectionProperties, + GoldengateMicrosoftFabricConnectionProperties, + GoldengateMicrosoftSqlserverConnectionProperties, + GoldengateMongodbConnectionProperties, + GoldengateMysqlConnectionProperties, + GoldengateOciObjectStorageConnectionProperties, + GoldengateOracleAIDataPlatformConnectionProperties, + GoldengateOracleConnectionProperties, + GoldengateOracleNosqlConnectionProperties, + GoldengatePostgresqlConnectionProperties, + GoldengateRedisConnectionProperties, + GoldengateSnowflakeConnectionProperties, + GoogleCloudStorageIcebergStorage, + IcebergCatalog, + IcebergStorage, + KafkaBootstrapServer, + ListGoldengateConnectionsRequest, + ListGoldengateConnectionsResponse, + NameValuePair, + NessieIcebergCatalog, + PolarisIcebergCatalog, + RestIcebergCatalog, +) +from google.cloud.oracledatabase_v1.types.goldengate_connection_assignment import ( + CreateGoldengateConnectionAssignmentRequest, + DeleteGoldengateConnectionAssignmentRequest, + GetGoldengateConnectionAssignmentRequest, + GoldengateConnectionAssignment, + GoldengateConnectionAssignmentProperties, + ListGoldengateConnectionAssignmentsRequest, + ListGoldengateConnectionAssignmentsResponse, + TestConnectionAssignmentError, + TestGoldengateConnectionAssignmentRequest, + TestGoldengateConnectionAssignmentResponse, +) +from google.cloud.oracledatabase_v1.types.goldengate_connection_type import ( + GetGoldengateConnectionTypeRequest, + GoldengateConnectionType, + ListGoldengateConnectionTypesRequest, + ListGoldengateConnectionTypesResponse, +) +from google.cloud.oracledatabase_v1.types.goldengate_deployment import ( + CreateGoldengateDeploymentRequest, + DeleteGoldengateDeploymentRequest, + DeploymentDiagnosticData, + GetGoldengateDeploymentRequest, + GoldengateBackupSchedule, + GoldengateDeployment, + GoldengateDeploymentLock, + GoldengateDeploymentProperties, + GoldengateGroupToRolesMapping, + GoldengateMaintenanceConfig, + GoldengateMaintenanceWindow, + GoldengateOggDeployment, + GoldengatePlacement, + IngressIp, + ListGoldengateDeploymentsRequest, + ListGoldengateDeploymentsResponse, + StartGoldengateDeploymentRequest, + StopGoldengateDeploymentRequest, +) +from google.cloud.oracledatabase_v1.types.goldengate_deployment_environment import ( + GetGoldengateDeploymentEnvironmentRequest, + GoldengateDeploymentEnvironment, + ListGoldengateDeploymentEnvironmentsRequest, + ListGoldengateDeploymentEnvironmentsResponse, +) +from google.cloud.oracledatabase_v1.types.goldengate_deployment_type import ( + GetGoldengateDeploymentTypeRequest, + GoldengateDeploymentType, + ListGoldengateDeploymentTypesRequest, + ListGoldengateDeploymentTypesResponse, +) +from google.cloud.oracledatabase_v1.types.goldengate_deployment_version import ( + GetGoldengateDeploymentVersionRequest, + GoldengateDeploymentVersion, + GoldengateDeploymentVersionProperties, + ListGoldengateDeploymentVersionsRequest, + ListGoldengateDeploymentVersionsResponse, +) from google.cloud.oracledatabase_v1.types.location_metadata import LocationMetadata from google.cloud.oracledatabase_v1.types.minor_version import ( ListMinorVersionsRequest, @@ -289,6 +395,98 @@ "ListExascaleDbStorageVaultsRequest", "ListExascaleDbStorageVaultsResponse", "GiVersion", + "AmazonS3IcebergStorage", + "AzureDataLakeStorageIcebergStorage", + "CreateGoldengateConnectionRequest", + "DeleteGoldengateConnectionRequest", + "GetGoldengateConnectionRequest", + "GlueIcebergCatalog", + "GoldengateAmazonKinesisConnectionProperties", + "GoldengateAmazonRedshiftConnectionProperties", + "GoldengateAmazonS3ConnectionProperties", + "GoldengateAzureDataLakeStorageConnectionProperties", + "GoldengateAzureSynapseAnalyticsConnectionProperties", + "GoldengateConnection", + "GoldengateConnectionProperties", + "GoldengateDatabricksConnectionProperties", + "GoldengateDb2ConnectionProperties", + "GoldengateElasticsearchConnectionProperties", + "GoldengateGenericConnectionProperties", + "GoldengateGoldengateConnectionProperties", + "GoldengateGoogleBigQueryConnectionProperties", + "GoldengateGoogleCloudStorageConnectionProperties", + "GoldengateGooglePubsubConnectionProperties", + "GoldengateHdfsConnectionProperties", + "GoldengateIcebergConnectionProperties", + "GoldengateJavaMessageServiceConnectionProperties", + "GoldengateKafkaConnectionProperties", + "GoldengateKafkaSchemaRegistryConnectionProperties", + "GoldengateMicrosoftFabricConnectionProperties", + "GoldengateMicrosoftSqlserverConnectionProperties", + "GoldengateMongodbConnectionProperties", + "GoldengateMysqlConnectionProperties", + "GoldengateOciObjectStorageConnectionProperties", + "GoldengateOracleAIDataPlatformConnectionProperties", + "GoldengateOracleConnectionProperties", + "GoldengateOracleNosqlConnectionProperties", + "GoldengatePostgresqlConnectionProperties", + "GoldengateRedisConnectionProperties", + "GoldengateSnowflakeConnectionProperties", + "GoogleCloudStorageIcebergStorage", + "IcebergCatalog", + "IcebergStorage", + "KafkaBootstrapServer", + "ListGoldengateConnectionsRequest", + "ListGoldengateConnectionsResponse", + "NameValuePair", + "NessieIcebergCatalog", + "PolarisIcebergCatalog", + "RestIcebergCatalog", + "CreateGoldengateConnectionAssignmentRequest", + "DeleteGoldengateConnectionAssignmentRequest", + "GetGoldengateConnectionAssignmentRequest", + "GoldengateConnectionAssignment", + "GoldengateConnectionAssignmentProperties", + "ListGoldengateConnectionAssignmentsRequest", + "ListGoldengateConnectionAssignmentsResponse", + "TestConnectionAssignmentError", + "TestGoldengateConnectionAssignmentRequest", + "TestGoldengateConnectionAssignmentResponse", + "GetGoldengateConnectionTypeRequest", + "GoldengateConnectionType", + "ListGoldengateConnectionTypesRequest", + "ListGoldengateConnectionTypesResponse", + "CreateGoldengateDeploymentRequest", + "DeleteGoldengateDeploymentRequest", + "DeploymentDiagnosticData", + "GetGoldengateDeploymentRequest", + "GoldengateBackupSchedule", + "GoldengateDeployment", + "GoldengateDeploymentLock", + "GoldengateDeploymentProperties", + "GoldengateGroupToRolesMapping", + "GoldengateMaintenanceConfig", + "GoldengateMaintenanceWindow", + "GoldengateOggDeployment", + "GoldengatePlacement", + "IngressIp", + "ListGoldengateDeploymentsRequest", + "ListGoldengateDeploymentsResponse", + "StartGoldengateDeploymentRequest", + "StopGoldengateDeploymentRequest", + "GetGoldengateDeploymentEnvironmentRequest", + "GoldengateDeploymentEnvironment", + "ListGoldengateDeploymentEnvironmentsRequest", + "ListGoldengateDeploymentEnvironmentsResponse", + "GetGoldengateDeploymentTypeRequest", + "GoldengateDeploymentType", + "ListGoldengateDeploymentTypesRequest", + "ListGoldengateDeploymentTypesResponse", + "GetGoldengateDeploymentVersionRequest", + "GoldengateDeploymentVersion", + "GoldengateDeploymentVersionProperties", + "ListGoldengateDeploymentVersionsRequest", + "ListGoldengateDeploymentVersionsResponse", "LocationMetadata", "ListMinorVersionsRequest", "ListMinorVersionsResponse", diff --git a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/__init__.py b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/__init__.py index 6d7061680f24..9ba5e09b5c0f 100644 --- a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/__init__.py +++ b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/__init__.py @@ -117,6 +117,112 @@ ListExascaleDbStorageVaultsResponse, ) from .types.gi_version import GiVersion +from .types.goldengate_connection import ( + AmazonS3IcebergStorage, + AzureDataLakeStorageIcebergStorage, + CreateGoldengateConnectionRequest, + DeleteGoldengateConnectionRequest, + GetGoldengateConnectionRequest, + GlueIcebergCatalog, + GoldengateAmazonKinesisConnectionProperties, + GoldengateAmazonRedshiftConnectionProperties, + GoldengateAmazonS3ConnectionProperties, + GoldengateAzureDataLakeStorageConnectionProperties, + GoldengateAzureSynapseAnalyticsConnectionProperties, + GoldengateConnection, + GoldengateConnectionProperties, + GoldengateDatabricksConnectionProperties, + GoldengateDb2ConnectionProperties, + GoldengateElasticsearchConnectionProperties, + GoldengateGenericConnectionProperties, + GoldengateGoldengateConnectionProperties, + GoldengateGoogleBigQueryConnectionProperties, + GoldengateGoogleCloudStorageConnectionProperties, + GoldengateGooglePubsubConnectionProperties, + GoldengateHdfsConnectionProperties, + GoldengateIcebergConnectionProperties, + GoldengateJavaMessageServiceConnectionProperties, + GoldengateKafkaConnectionProperties, + GoldengateKafkaSchemaRegistryConnectionProperties, + GoldengateMicrosoftFabricConnectionProperties, + GoldengateMicrosoftSqlserverConnectionProperties, + GoldengateMongodbConnectionProperties, + GoldengateMysqlConnectionProperties, + GoldengateOciObjectStorageConnectionProperties, + GoldengateOracleAIDataPlatformConnectionProperties, + GoldengateOracleConnectionProperties, + GoldengateOracleNosqlConnectionProperties, + GoldengatePostgresqlConnectionProperties, + GoldengateRedisConnectionProperties, + GoldengateSnowflakeConnectionProperties, + GoogleCloudStorageIcebergStorage, + IcebergCatalog, + IcebergStorage, + KafkaBootstrapServer, + ListGoldengateConnectionsRequest, + ListGoldengateConnectionsResponse, + NameValuePair, + NessieIcebergCatalog, + PolarisIcebergCatalog, + RestIcebergCatalog, +) +from .types.goldengate_connection_assignment import ( + CreateGoldengateConnectionAssignmentRequest, + DeleteGoldengateConnectionAssignmentRequest, + GetGoldengateConnectionAssignmentRequest, + GoldengateConnectionAssignment, + GoldengateConnectionAssignmentProperties, + ListGoldengateConnectionAssignmentsRequest, + ListGoldengateConnectionAssignmentsResponse, + TestConnectionAssignmentError, + TestGoldengateConnectionAssignmentRequest, + TestGoldengateConnectionAssignmentResponse, +) +from .types.goldengate_connection_type import ( + GetGoldengateConnectionTypeRequest, + GoldengateConnectionType, + ListGoldengateConnectionTypesRequest, + ListGoldengateConnectionTypesResponse, +) +from .types.goldengate_deployment import ( + CreateGoldengateDeploymentRequest, + DeleteGoldengateDeploymentRequest, + DeploymentDiagnosticData, + GetGoldengateDeploymentRequest, + GoldengateBackupSchedule, + GoldengateDeployment, + GoldengateDeploymentLock, + GoldengateDeploymentProperties, + GoldengateGroupToRolesMapping, + GoldengateMaintenanceConfig, + GoldengateMaintenanceWindow, + GoldengateOggDeployment, + GoldengatePlacement, + IngressIp, + ListGoldengateDeploymentsRequest, + ListGoldengateDeploymentsResponse, + StartGoldengateDeploymentRequest, + StopGoldengateDeploymentRequest, +) +from .types.goldengate_deployment_environment import ( + GetGoldengateDeploymentEnvironmentRequest, + GoldengateDeploymentEnvironment, + ListGoldengateDeploymentEnvironmentsRequest, + ListGoldengateDeploymentEnvironmentsResponse, +) +from .types.goldengate_deployment_type import ( + GetGoldengateDeploymentTypeRequest, + GoldengateDeploymentType, + ListGoldengateDeploymentTypesRequest, + ListGoldengateDeploymentTypesResponse, +) +from .types.goldengate_deployment_version import ( + GetGoldengateDeploymentVersionRequest, + GoldengateDeploymentVersion, + GoldengateDeploymentVersionProperties, + ListGoldengateDeploymentVersionsRequest, + ListGoldengateDeploymentVersionsResponse, +) from .types.location_metadata import LocationMetadata from .types.minor_version import ( ListMinorVersionsRequest, @@ -291,6 +397,7 @@ def _get_version(dependency_name): __all__ = ( "OracleDatabaseAsyncClient", "AllConnectionStrings", + "AmazonS3IcebergStorage", "AutonomousDatabase", "AutonomousDatabaseApex", "AutonomousDatabaseBackup", @@ -301,6 +408,7 @@ def _get_version(dependency_name): "AutonomousDatabaseProperties", "AutonomousDatabaseStandbySummary", "AutonomousDbVersion", + "AzureDataLakeStorageIcebergStorage", "CloudAccountDetails", "CloudExadataInfrastructure", "CloudExadataInfrastructureProperties", @@ -313,6 +421,9 @@ def _get_version(dependency_name): "CreateDbSystemRequest", "CreateExadbVmClusterRequest", "CreateExascaleDbStorageVaultRequest", + "CreateGoldengateConnectionAssignmentRequest", + "CreateGoldengateConnectionRequest", + "CreateGoldengateDeploymentRequest", "CreateOdbNetworkRequest", "CreateOdbSubnetRequest", "CustomerContact", @@ -345,8 +456,12 @@ def _get_version(dependency_name): "DeleteDbSystemRequest", "DeleteExadbVmClusterRequest", "DeleteExascaleDbStorageVaultRequest", + "DeleteGoldengateConnectionAssignmentRequest", + "DeleteGoldengateConnectionRequest", + "DeleteGoldengateDeploymentRequest", "DeleteOdbNetworkRequest", "DeleteOdbSubnetRequest", + "DeploymentDiagnosticData", "EncryptionKey", "EncryptionKeyHistoryEntry", "Entitlement", @@ -367,11 +482,71 @@ def _get_version(dependency_name): "GetDbSystemRequest", "GetExadbVmClusterRequest", "GetExascaleDbStorageVaultRequest", + "GetGoldengateConnectionAssignmentRequest", + "GetGoldengateConnectionRequest", + "GetGoldengateConnectionTypeRequest", + "GetGoldengateDeploymentEnvironmentRequest", + "GetGoldengateDeploymentRequest", + "GetGoldengateDeploymentTypeRequest", + "GetGoldengateDeploymentVersionRequest", "GetOdbNetworkRequest", "GetOdbSubnetRequest", "GetPluggableDatabaseRequest", "GiVersion", + "GlueIcebergCatalog", + "GoldengateAmazonKinesisConnectionProperties", + "GoldengateAmazonRedshiftConnectionProperties", + "GoldengateAmazonS3ConnectionProperties", + "GoldengateAzureDataLakeStorageConnectionProperties", + "GoldengateAzureSynapseAnalyticsConnectionProperties", + "GoldengateBackupSchedule", + "GoldengateConnection", + "GoldengateConnectionAssignment", + "GoldengateConnectionAssignmentProperties", + "GoldengateConnectionProperties", + "GoldengateConnectionType", + "GoldengateDatabricksConnectionProperties", + "GoldengateDb2ConnectionProperties", + "GoldengateDeployment", + "GoldengateDeploymentEnvironment", + "GoldengateDeploymentLock", + "GoldengateDeploymentProperties", + "GoldengateDeploymentType", + "GoldengateDeploymentVersion", + "GoldengateDeploymentVersionProperties", + "GoldengateElasticsearchConnectionProperties", + "GoldengateGenericConnectionProperties", + "GoldengateGoldengateConnectionProperties", + "GoldengateGoogleBigQueryConnectionProperties", + "GoldengateGoogleCloudStorageConnectionProperties", + "GoldengateGooglePubsubConnectionProperties", + "GoldengateGroupToRolesMapping", + "GoldengateHdfsConnectionProperties", + "GoldengateIcebergConnectionProperties", + "GoldengateJavaMessageServiceConnectionProperties", + "GoldengateKafkaConnectionProperties", + "GoldengateKafkaSchemaRegistryConnectionProperties", + "GoldengateMaintenanceConfig", + "GoldengateMaintenanceWindow", + "GoldengateMicrosoftFabricConnectionProperties", + "GoldengateMicrosoftSqlserverConnectionProperties", + "GoldengateMongodbConnectionProperties", + "GoldengateMysqlConnectionProperties", + "GoldengateOciObjectStorageConnectionProperties", + "GoldengateOggDeployment", + "GoldengateOracleAIDataPlatformConnectionProperties", + "GoldengateOracleConnectionProperties", + "GoldengateOracleNosqlConnectionProperties", + "GoldengatePlacement", + "GoldengatePostgresqlConnectionProperties", + "GoldengateRedisConnectionProperties", + "GoldengateSnowflakeConnectionProperties", + "GoogleCloudStorageIcebergStorage", + "IcebergCatalog", + "IcebergStorage", "IdentityConnector", + "IngressIp", + "KafkaBootstrapServer", "ListAutonomousDatabaseBackupsRequest", "ListAutonomousDatabaseBackupsResponse", "ListAutonomousDatabaseCharacterSetsRequest", @@ -408,6 +583,20 @@ def _get_version(dependency_name): "ListExascaleDbStorageVaultsResponse", "ListGiVersionsRequest", "ListGiVersionsResponse", + "ListGoldengateConnectionAssignmentsRequest", + "ListGoldengateConnectionAssignmentsResponse", + "ListGoldengateConnectionTypesRequest", + "ListGoldengateConnectionTypesResponse", + "ListGoldengateConnectionsRequest", + "ListGoldengateConnectionsResponse", + "ListGoldengateDeploymentEnvironmentsRequest", + "ListGoldengateDeploymentEnvironmentsResponse", + "ListGoldengateDeploymentTypesRequest", + "ListGoldengateDeploymentTypesResponse", + "ListGoldengateDeploymentVersionsRequest", + "ListGoldengateDeploymentVersionsResponse", + "ListGoldengateDeploymentsRequest", + "ListGoldengateDeploymentsResponse", "ListMinorVersionsRequest", "ListMinorVersionsResponse", "ListOdbNetworksRequest", @@ -419,6 +608,8 @@ def _get_version(dependency_name): "LocationMetadata", "MaintenanceWindow", "MinorVersion", + "NameValuePair", + "NessieIcebergCatalog", "OdbNetwork", "OdbSubnet", "OperationMetadata", @@ -428,16 +619,23 @@ def _get_version(dependency_name): "PluggableDatabaseConnectionStrings", "PluggableDatabaseNodeLevelDetails", "PluggableDatabaseProperties", + "PolarisIcebergCatalog", "RemoveVirtualMachineExadbVmClusterRequest", + "RestIcebergCatalog", "RestartAutonomousDatabaseRequest", "RestoreAutonomousDatabaseRequest", "ScheduledOperationDetails", "SourceConfig", "StartAutonomousDatabaseRequest", + "StartGoldengateDeploymentRequest", "State", "StopAutonomousDatabaseRequest", + "StopGoldengateDeploymentRequest", "StorageSizeDetails", "SwitchoverAutonomousDatabaseRequest", + "TestConnectionAssignmentError", + "TestGoldengateConnectionAssignmentRequest", + "TestGoldengateConnectionAssignmentResponse", "UpdateAutonomousDatabaseRequest", "UpdateExadbVmClusterRequest", ) diff --git a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/gapic_metadata.json b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/gapic_metadata.json index ce858f41ca92..37e347c4472b 100644 --- a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/gapic_metadata.json +++ b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/gapic_metadata.json @@ -40,6 +40,21 @@ "create_exascale_db_storage_vault" ] }, + "CreateGoldengateConnection": { + "methods": [ + "create_goldengate_connection" + ] + }, + "CreateGoldengateConnectionAssignment": { + "methods": [ + "create_goldengate_connection_assignment" + ] + }, + "CreateGoldengateDeployment": { + "methods": [ + "create_goldengate_deployment" + ] + }, "CreateOdbNetwork": { "methods": [ "create_odb_network" @@ -80,6 +95,21 @@ "delete_exascale_db_storage_vault" ] }, + "DeleteGoldengateConnection": { + "methods": [ + "delete_goldengate_connection" + ] + }, + "DeleteGoldengateConnectionAssignment": { + "methods": [ + "delete_goldengate_connection_assignment" + ] + }, + "DeleteGoldengateDeployment": { + "methods": [ + "delete_goldengate_deployment" + ] + }, "DeleteOdbNetwork": { "methods": [ "delete_odb_network" @@ -135,6 +165,41 @@ "get_exascale_db_storage_vault" ] }, + "GetGoldengateConnection": { + "methods": [ + "get_goldengate_connection" + ] + }, + "GetGoldengateConnectionAssignment": { + "methods": [ + "get_goldengate_connection_assignment" + ] + }, + "GetGoldengateConnectionType": { + "methods": [ + "get_goldengate_connection_type" + ] + }, + "GetGoldengateDeployment": { + "methods": [ + "get_goldengate_deployment" + ] + }, + "GetGoldengateDeploymentEnvironment": { + "methods": [ + "get_goldengate_deployment_environment" + ] + }, + "GetGoldengateDeploymentType": { + "methods": [ + "get_goldengate_deployment_type" + ] + }, + "GetGoldengateDeploymentVersion": { + "methods": [ + "get_goldengate_deployment_version" + ] + }, "GetOdbNetwork": { "methods": [ "get_odb_network" @@ -240,6 +305,41 @@ "list_gi_versions" ] }, + "ListGoldengateConnectionAssignments": { + "methods": [ + "list_goldengate_connection_assignments" + ] + }, + "ListGoldengateConnectionTypes": { + "methods": [ + "list_goldengate_connection_types" + ] + }, + "ListGoldengateConnections": { + "methods": [ + "list_goldengate_connections" + ] + }, + "ListGoldengateDeploymentEnvironments": { + "methods": [ + "list_goldengate_deployment_environments" + ] + }, + "ListGoldengateDeploymentTypes": { + "methods": [ + "list_goldengate_deployment_types" + ] + }, + "ListGoldengateDeploymentVersions": { + "methods": [ + "list_goldengate_deployment_versions" + ] + }, + "ListGoldengateDeployments": { + "methods": [ + "list_goldengate_deployments" + ] + }, "ListMinorVersions": { "methods": [ "list_minor_versions" @@ -280,16 +380,31 @@ "start_autonomous_database" ] }, + "StartGoldengateDeployment": { + "methods": [ + "start_goldengate_deployment" + ] + }, "StopAutonomousDatabase": { "methods": [ "stop_autonomous_database" ] }, + "StopGoldengateDeployment": { + "methods": [ + "stop_goldengate_deployment" + ] + }, "SwitchoverAutonomousDatabase": { "methods": [ "switchover_autonomous_database" ] }, + "TestGoldengateConnectionAssignment": { + "methods": [ + "test_goldengate_connection_assignment" + ] + }, "UpdateAutonomousDatabase": { "methods": [ "update_autonomous_database" @@ -335,6 +450,21 @@ "create_exascale_db_storage_vault" ] }, + "CreateGoldengateConnection": { + "methods": [ + "create_goldengate_connection" + ] + }, + "CreateGoldengateConnectionAssignment": { + "methods": [ + "create_goldengate_connection_assignment" + ] + }, + "CreateGoldengateDeployment": { + "methods": [ + "create_goldengate_deployment" + ] + }, "CreateOdbNetwork": { "methods": [ "create_odb_network" @@ -375,6 +505,21 @@ "delete_exascale_db_storage_vault" ] }, + "DeleteGoldengateConnection": { + "methods": [ + "delete_goldengate_connection" + ] + }, + "DeleteGoldengateConnectionAssignment": { + "methods": [ + "delete_goldengate_connection_assignment" + ] + }, + "DeleteGoldengateDeployment": { + "methods": [ + "delete_goldengate_deployment" + ] + }, "DeleteOdbNetwork": { "methods": [ "delete_odb_network" @@ -430,6 +575,41 @@ "get_exascale_db_storage_vault" ] }, + "GetGoldengateConnection": { + "methods": [ + "get_goldengate_connection" + ] + }, + "GetGoldengateConnectionAssignment": { + "methods": [ + "get_goldengate_connection_assignment" + ] + }, + "GetGoldengateConnectionType": { + "methods": [ + "get_goldengate_connection_type" + ] + }, + "GetGoldengateDeployment": { + "methods": [ + "get_goldengate_deployment" + ] + }, + "GetGoldengateDeploymentEnvironment": { + "methods": [ + "get_goldengate_deployment_environment" + ] + }, + "GetGoldengateDeploymentType": { + "methods": [ + "get_goldengate_deployment_type" + ] + }, + "GetGoldengateDeploymentVersion": { + "methods": [ + "get_goldengate_deployment_version" + ] + }, "GetOdbNetwork": { "methods": [ "get_odb_network" @@ -535,6 +715,41 @@ "list_gi_versions" ] }, + "ListGoldengateConnectionAssignments": { + "methods": [ + "list_goldengate_connection_assignments" + ] + }, + "ListGoldengateConnectionTypes": { + "methods": [ + "list_goldengate_connection_types" + ] + }, + "ListGoldengateConnections": { + "methods": [ + "list_goldengate_connections" + ] + }, + "ListGoldengateDeploymentEnvironments": { + "methods": [ + "list_goldengate_deployment_environments" + ] + }, + "ListGoldengateDeploymentTypes": { + "methods": [ + "list_goldengate_deployment_types" + ] + }, + "ListGoldengateDeploymentVersions": { + "methods": [ + "list_goldengate_deployment_versions" + ] + }, + "ListGoldengateDeployments": { + "methods": [ + "list_goldengate_deployments" + ] + }, "ListMinorVersions": { "methods": [ "list_minor_versions" @@ -575,16 +790,31 @@ "start_autonomous_database" ] }, + "StartGoldengateDeployment": { + "methods": [ + "start_goldengate_deployment" + ] + }, "StopAutonomousDatabase": { "methods": [ "stop_autonomous_database" ] }, + "StopGoldengateDeployment": { + "methods": [ + "stop_goldengate_deployment" + ] + }, "SwitchoverAutonomousDatabase": { "methods": [ "switchover_autonomous_database" ] }, + "TestGoldengateConnectionAssignment": { + "methods": [ + "test_goldengate_connection_assignment" + ] + }, "UpdateAutonomousDatabase": { "methods": [ "update_autonomous_database" @@ -630,6 +860,21 @@ "create_exascale_db_storage_vault" ] }, + "CreateGoldengateConnection": { + "methods": [ + "create_goldengate_connection" + ] + }, + "CreateGoldengateConnectionAssignment": { + "methods": [ + "create_goldengate_connection_assignment" + ] + }, + "CreateGoldengateDeployment": { + "methods": [ + "create_goldengate_deployment" + ] + }, "CreateOdbNetwork": { "methods": [ "create_odb_network" @@ -670,6 +915,21 @@ "delete_exascale_db_storage_vault" ] }, + "DeleteGoldengateConnection": { + "methods": [ + "delete_goldengate_connection" + ] + }, + "DeleteGoldengateConnectionAssignment": { + "methods": [ + "delete_goldengate_connection_assignment" + ] + }, + "DeleteGoldengateDeployment": { + "methods": [ + "delete_goldengate_deployment" + ] + }, "DeleteOdbNetwork": { "methods": [ "delete_odb_network" @@ -725,6 +985,41 @@ "get_exascale_db_storage_vault" ] }, + "GetGoldengateConnection": { + "methods": [ + "get_goldengate_connection" + ] + }, + "GetGoldengateConnectionAssignment": { + "methods": [ + "get_goldengate_connection_assignment" + ] + }, + "GetGoldengateConnectionType": { + "methods": [ + "get_goldengate_connection_type" + ] + }, + "GetGoldengateDeployment": { + "methods": [ + "get_goldengate_deployment" + ] + }, + "GetGoldengateDeploymentEnvironment": { + "methods": [ + "get_goldengate_deployment_environment" + ] + }, + "GetGoldengateDeploymentType": { + "methods": [ + "get_goldengate_deployment_type" + ] + }, + "GetGoldengateDeploymentVersion": { + "methods": [ + "get_goldengate_deployment_version" + ] + }, "GetOdbNetwork": { "methods": [ "get_odb_network" @@ -830,6 +1125,41 @@ "list_gi_versions" ] }, + "ListGoldengateConnectionAssignments": { + "methods": [ + "list_goldengate_connection_assignments" + ] + }, + "ListGoldengateConnectionTypes": { + "methods": [ + "list_goldengate_connection_types" + ] + }, + "ListGoldengateConnections": { + "methods": [ + "list_goldengate_connections" + ] + }, + "ListGoldengateDeploymentEnvironments": { + "methods": [ + "list_goldengate_deployment_environments" + ] + }, + "ListGoldengateDeploymentTypes": { + "methods": [ + "list_goldengate_deployment_types" + ] + }, + "ListGoldengateDeploymentVersions": { + "methods": [ + "list_goldengate_deployment_versions" + ] + }, + "ListGoldengateDeployments": { + "methods": [ + "list_goldengate_deployments" + ] + }, "ListMinorVersions": { "methods": [ "list_minor_versions" @@ -870,16 +1200,31 @@ "start_autonomous_database" ] }, + "StartGoldengateDeployment": { + "methods": [ + "start_goldengate_deployment" + ] + }, "StopAutonomousDatabase": { "methods": [ "stop_autonomous_database" ] }, + "StopGoldengateDeployment": { + "methods": [ + "stop_goldengate_deployment" + ] + }, "SwitchoverAutonomousDatabase": { "methods": [ "switchover_autonomous_database" ] }, + "TestGoldengateConnectionAssignment": { + "methods": [ + "test_goldengate_connection_assignment" + ] + }, "UpdateAutonomousDatabase": { "methods": [ "update_autonomous_database" diff --git a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/async_client.py b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/async_client.py index 04b8ccf3ce01..0ea413a24cf3 100644 --- a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/async_client.py +++ b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/async_client.py @@ -72,6 +72,13 @@ exadb_vm_cluster, exascale_db_storage_vault, gi_version, + goldengate_connection, + goldengate_connection_assignment, + goldengate_connection_type, + goldengate_deployment, + goldengate_deployment_environment, + goldengate_deployment_type, + goldengate_deployment_version, minor_version, odb_network, odb_subnet, @@ -89,6 +96,15 @@ from google.cloud.oracledatabase_v1.types import ( exascale_db_storage_vault as gco_exascale_db_storage_vault, ) +from google.cloud.oracledatabase_v1.types import ( + goldengate_connection as gco_goldengate_connection, +) +from google.cloud.oracledatabase_v1.types import ( + goldengate_connection_assignment as gco_goldengate_connection_assignment, +) +from google.cloud.oracledatabase_v1.types import ( + goldengate_deployment as gco_goldengate_deployment, +) from google.cloud.oracledatabase_v1.types import odb_network as gco_odb_network from google.cloud.oracledatabase_v1.types import odb_subnet as gco_odb_subnet @@ -194,6 +210,48 @@ class OracleDatabaseAsyncClient: ) gi_version_path = staticmethod(OracleDatabaseClient.gi_version_path) parse_gi_version_path = staticmethod(OracleDatabaseClient.parse_gi_version_path) + goldengate_connection_path = staticmethod( + OracleDatabaseClient.goldengate_connection_path + ) + parse_goldengate_connection_path = staticmethod( + OracleDatabaseClient.parse_goldengate_connection_path + ) + goldengate_connection_assignment_path = staticmethod( + OracleDatabaseClient.goldengate_connection_assignment_path + ) + parse_goldengate_connection_assignment_path = staticmethod( + OracleDatabaseClient.parse_goldengate_connection_assignment_path + ) + goldengate_connection_type_path = staticmethod( + OracleDatabaseClient.goldengate_connection_type_path + ) + parse_goldengate_connection_type_path = staticmethod( + OracleDatabaseClient.parse_goldengate_connection_type_path + ) + goldengate_deployment_path = staticmethod( + OracleDatabaseClient.goldengate_deployment_path + ) + parse_goldengate_deployment_path = staticmethod( + OracleDatabaseClient.parse_goldengate_deployment_path + ) + goldengate_deployment_environment_path = staticmethod( + OracleDatabaseClient.goldengate_deployment_environment_path + ) + parse_goldengate_deployment_environment_path = staticmethod( + OracleDatabaseClient.parse_goldengate_deployment_environment_path + ) + goldengate_deployment_type_path = staticmethod( + OracleDatabaseClient.goldengate_deployment_type_path + ) + parse_goldengate_deployment_type_path = staticmethod( + OracleDatabaseClient.parse_goldengate_deployment_type_path + ) + goldengate_deployment_version_path = staticmethod( + OracleDatabaseClient.goldengate_deployment_version_path + ) + parse_goldengate_deployment_version_path = staticmethod( + OracleDatabaseClient.parse_goldengate_deployment_version_path + ) minor_version_path = staticmethod(OracleDatabaseClient.minor_version_path) parse_minor_version_path = staticmethod( OracleDatabaseClient.parse_minor_version_path @@ -208,6 +266,10 @@ class OracleDatabaseAsyncClient: parse_pluggable_database_path = staticmethod( OracleDatabaseClient.parse_pluggable_database_path ) + secret_version_path = staticmethod(OracleDatabaseClient.secret_version_path) + parse_secret_version_path = staticmethod( + OracleDatabaseClient.parse_secret_version_path + ) common_billing_account_path = staticmethod( OracleDatabaseClient.common_billing_account_path ) @@ -4018,7 +4080,6 @@ async def sample_switchover_autonomous_database(): # Initialize request argument(s) request = oracledatabase_v1.SwitchoverAutonomousDatabaseRequest( name="name_value", - peer_autonomous_database="peer_autonomous_database_value", ) # Make the request @@ -4044,8 +4105,10 @@ async def sample_switchover_autonomous_database(): on the ``request`` instance; if ``request`` is provided, this should not be set. peer_autonomous_database (:class:`str`): - Required. The peer database name to - switch over to. + Optional. The peer database name to + switch over to. Required for + cross-region standby, and must be + omitted for in-region Data Guard. This corresponds to the ``peer_autonomous_database`` field on the ``request`` instance; if ``request`` is provided, this @@ -4158,7 +4221,6 @@ async def sample_failover_autonomous_database(): # Initialize request argument(s) request = oracledatabase_v1.FailoverAutonomousDatabaseRequest( name="name_value", - peer_autonomous_database="peer_autonomous_database_value", ) # Make the request @@ -4184,8 +4246,10 @@ async def sample_failover_autonomous_database(): on the ``request`` instance; if ``request`` is provided, this should not be set. peer_autonomous_database (:class:`str`): - Required. The peer database name to - fail over to. + Optional. The peer database name to + fail over to. Required for cross-region + standby, and must be omitted for + in-region Data Guard. This corresponds to the ``peer_autonomous_database`` field on the ``request`` instance; if ``request`` is provided, this @@ -7852,16 +7916,19 @@ async def sample_delete_db_system(): # Done; return the response. return response - async def list_db_versions( + async def list_goldengate_deployments( self, - request: Optional[Union[db_version.ListDbVersionsRequest, dict]] = None, + request: Optional[ + Union[goldengate_deployment.ListGoldengateDeploymentsRequest, dict] + ] = None, *, parent: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> pagers.ListDbVersionsAsyncPager: - r"""List DbVersions for the given project and location. + ) -> pagers.ListGoldengateDeploymentsAsyncPager: + r"""Lists all the GoldengateDeployments for the given + project and location. .. code-block:: python @@ -7874,29 +7941,30 @@ async def list_db_versions( # https://googleapis.dev/python/google-api-core/latest/client_options.html from google.cloud import oracledatabase_v1 - async def sample_list_db_versions(): + async def sample_list_goldengate_deployments(): # Create a client client = oracledatabase_v1.OracleDatabaseAsyncClient() # Initialize request argument(s) - request = oracledatabase_v1.ListDbVersionsRequest( + request = oracledatabase_v1.ListGoldengateDeploymentsRequest( parent="parent_value", ) # Make the request - page_result = client.list_db_versions(request=request) + page_result = client.list_goldengate_deployments(request=request) # Handle the response async for response in page_result: print(response) Args: - request (Optional[Union[google.cloud.oracledatabase_v1.types.ListDbVersionsRequest, dict]]): - The request object. The request for ``DbVersions.List``. + request (Optional[Union[google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentsRequest, dict]]): + The request object. The request for ``GoldengateDeployment.List``. parent (:class:`str`): - Required. The parent value for the - DbVersion resource with the format: - projects/{project}/locations/{location} + Required. The parent value for + GoldengateDeployments in the following + format: + projects/{project}/locations/{location}. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -7910,8 +7978,8 @@ async def sample_list_db_versions(): be of type `bytes`. Returns: - google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDbVersionsAsyncPager: - The response for DbVersions.List. + google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGoldengateDeploymentsAsyncPager: + The response for GoldengateDeployment.List. Iterating over this object will yield results and resolve additional pages automatically. @@ -7932,8 +8000,10 @@ async def sample_list_db_versions(): # - Use the request object if provided (there's no risk of modifying the input as # there are no flattened fields), or create one. - if not isinstance(request, db_version.ListDbVersionsRequest): - request = db_version.ListDbVersionsRequest(request) + if not isinstance( + request, goldengate_deployment.ListGoldengateDeploymentsRequest + ): + request = goldengate_deployment.ListGoldengateDeploymentsRequest(request) # If we have keyword arguments corresponding to fields on the # request, apply these. @@ -7943,7 +8013,7 @@ async def sample_list_db_versions(): # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. rpc = self._client._transport._wrapped_methods[ - self._client._transport.list_db_versions + self._client._transport.list_goldengate_deployments ] # Certain fields should be provided within the metadata header; @@ -7965,7 +8035,7 @@ async def sample_list_db_versions(): # This method is paged; wrap the response in a pager, which provides # an `__aiter__` convenience method. - response = pagers.ListDbVersionsAsyncPager( + response = pagers.ListGoldengateDeploymentsAsyncPager( method=rpc, request=request, response=response, @@ -7977,19 +8047,138 @@ async def sample_list_db_versions(): # Done; return the response. return response - async def list_database_character_sets( + async def get_goldengate_deployment( self, request: Optional[ - Union[database_character_set.ListDatabaseCharacterSetsRequest, dict] + Union[goldengate_deployment.GetGoldengateDeploymentRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> goldengate_deployment.GoldengateDeployment: + r"""Gets details of a single GoldengateDeployment. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + async def sample_get_goldengate_deployment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.GetGoldengateDeploymentRequest( + name="name_value", + ) + + # Make the request + response = await client.get_goldengate_deployment(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.oracledatabase_v1.types.GetGoldengateDeploymentRequest, dict]]): + The request object. The request for ``GoldengateDeployment.Get``. + name (:class:`str`): + Required. The name of the GoldengateDeployment in the + following format: + projects/{project}/locations/{location}/goldengateDeployments/{goldengate_deployment}. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.types.GoldengateDeployment: + GoldengateDeployment Goldengate + Deployment resource model. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, goldengate_deployment.GetGoldengateDeploymentRequest + ): + request = goldengate_deployment.GetGoldengateDeploymentRequest(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._client._transport._wrapped_methods[ + self._client._transport.get_goldengate_deployment + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def create_goldengate_deployment( + self, + request: Optional[ + Union[gco_goldengate_deployment.CreateGoldengateDeploymentRequest, dict] ] = None, *, parent: Optional[str] = None, + goldengate_deployment: Optional[ + gco_goldengate_deployment.GoldengateDeployment + ] = None, + goldengate_deployment_id: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> pagers.ListDatabaseCharacterSetsAsyncPager: - r"""List DatabaseCharacterSets for the given project and - location. + ) -> operation_async.AsyncOperation: + r"""Creates a new GoldengateDeployment in a given project + and location. .. code-block:: python @@ -8002,34 +8191,62 @@ async def list_database_character_sets( # https://googleapis.dev/python/google-api-core/latest/client_options.html from google.cloud import oracledatabase_v1 - async def sample_list_database_character_sets(): + async def sample_create_goldengate_deployment(): # Create a client client = oracledatabase_v1.OracleDatabaseAsyncClient() # Initialize request argument(s) - request = oracledatabase_v1.ListDatabaseCharacterSetsRequest( + goldengate_deployment = oracledatabase_v1.GoldengateDeployment() + goldengate_deployment.properties.deployment_type = "deployment_type_value" + goldengate_deployment.properties.ogg_data.admin_password = "admin_password_value" + goldengate_deployment.properties.ogg_data.deployment = "deployment_value" + goldengate_deployment.properties.ogg_data.admin_username = "admin_username_value" + goldengate_deployment.odb_subnet = "odb_subnet_value" + goldengate_deployment.display_name = "display_name_value" + + request = oracledatabase_v1.CreateGoldengateDeploymentRequest( parent="parent_value", + goldengate_deployment_id="goldengate_deployment_id_value", + goldengate_deployment=goldengate_deployment, ) # Make the request - page_result = client.list_database_character_sets(request=request) + operation = await client.create_goldengate_deployment(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() # Handle the response - async for response in page_result: - print(response) + print(response) Args: - request (Optional[Union[google.cloud.oracledatabase_v1.types.ListDatabaseCharacterSetsRequest, dict]]): - The request object. The request for ``DatabaseCharacterSet.List``. + request (Optional[Union[google.cloud.oracledatabase_v1.types.CreateGoldengateDeploymentRequest, dict]]): + The request object. The request for ``GoldengateDeployment.Create``. parent (:class:`str`): - Required. The parent value for - DatabaseCharacterSets in the following + Required. The value for parent of the + GoldengateDeployment in the following format: projects/{project}/locations/{location}. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. + goldengate_deployment (:class:`google.cloud.oracledatabase_v1.types.GoldengateDeployment`): + Required. The resource being created. + This corresponds to the ``goldengate_deployment`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + goldengate_deployment_id (:class:`str`): + Required. The ID of the GoldengateDeployment to create. + This value is restricted to + (^\ `a-z <[a-z0-9-]{0,61}[a-z0-9]>`__?$) and must be a + maximum of 63 characters in length. The value must start + with a letter and end with a letter or a number. + + This corresponds to the ``goldengate_deployment_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -8039,17 +8256,19 @@ async def sample_list_database_character_sets(): be of type `bytes`. Returns: - google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDatabaseCharacterSetsAsyncPager: - The response for DatabaseCharacterSet.List. + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. - Iterating over this object will yield results and - resolve additional pages automatically. + The result type for the operation will be + :class:`google.cloud.oracledatabase_v1.types.GoldengateDeployment` + GoldengateDeployment Goldengate Deployment resource + model. """ # Create or coerce a protobuf request object. # - Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - flattened_params = [parent] + flattened_params = [parent, goldengate_deployment, goldengate_deployment_id] has_flattened_params = ( len([param for param in flattened_params if param is not None]) > 0 ) @@ -8062,19 +8281,25 @@ async def sample_list_database_character_sets(): # - Use the request object if provided (there's no risk of modifying the input as # there are no flattened fields), or create one. if not isinstance( - request, database_character_set.ListDatabaseCharacterSetsRequest + request, gco_goldengate_deployment.CreateGoldengateDeploymentRequest ): - request = database_character_set.ListDatabaseCharacterSetsRequest(request) + request = gco_goldengate_deployment.CreateGoldengateDeploymentRequest( + request + ) # If we have keyword arguments corresponding to fields on the # request, apply these. if parent is not None: request.parent = parent + if goldengate_deployment is not None: + request.goldengate_deployment = goldengate_deployment + if goldengate_deployment_id is not None: + request.goldengate_deployment_id = goldengate_deployment_id # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. rpc = self._client._transport._wrapped_methods[ - self._client._transport.list_database_character_sets + self._client._transport.create_goldengate_deployment ] # Certain fields should be provided within the metadata header; @@ -8094,12 +8319,2947 @@ async def sample_list_database_character_sets(): metadata=metadata, ) - # This method is paged; wrap the response in a pager, which provides - # an `__aiter__` convenience method. - response = pagers.ListDatabaseCharacterSetsAsyncPager( - method=rpc, - request=request, - response=response, + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + gco_goldengate_deployment.GoldengateDeployment, + metadata_type=oracledatabase.OperationMetadata, + ) + + # Done; return the response. + return response + + async def delete_goldengate_deployment( + self, + request: Optional[ + Union[goldengate_deployment.DeleteGoldengateDeploymentRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""Deletes a single GoldengateDeployment. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + async def sample_delete_goldengate_deployment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.DeleteGoldengateDeploymentRequest( + name="name_value", + ) + + # Make the request + operation = await client.delete_goldengate_deployment(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.oracledatabase_v1.types.DeleteGoldengateDeploymentRequest, dict]]): + The request object. The request for ``GoldengateDeployment.Delete``. + name (:class:`str`): + Required. The name of the GoldengateDeployment in the + following format: + projects/{project}/locations/{location}/goldengateDeployments/{goldengate_deployment}. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, goldengate_deployment.DeleteGoldengateDeploymentRequest + ): + request = goldengate_deployment.DeleteGoldengateDeploymentRequest(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._client._transport._wrapped_methods[ + self._client._transport.delete_goldengate_deployment + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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, + empty_pb2.Empty, + metadata_type=oracledatabase.OperationMetadata, + ) + + # Done; return the response. + return response + + async def stop_goldengate_deployment( + self, + request: Optional[ + Union[goldengate_deployment.StopGoldengateDeploymentRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""Stops a single GoldengateDeployment. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + async def sample_stop_goldengate_deployment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.StopGoldengateDeploymentRequest( + name="name_value", + ) + + # Make the request + operation = await client.stop_goldengate_deployment(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.oracledatabase_v1.types.StopGoldengateDeploymentRequest, dict]]): + The request object. The request for ``GoldengateDeployment.Stop``. + name (:class:`str`): + Required. The name of the Goldengate Deployment in the + following format: + projects/{project}/locations/{location}/goldengateDeployments/{goldengate_deployment}. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + 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.oracledatabase_v1.types.GoldengateDeployment` + GoldengateDeployment Goldengate Deployment resource + model. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, goldengate_deployment.StopGoldengateDeploymentRequest + ): + request = goldengate_deployment.StopGoldengateDeploymentRequest(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._client._transport._wrapped_methods[ + self._client._transport.stop_goldengate_deployment + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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, + goldengate_deployment.GoldengateDeployment, + metadata_type=oracledatabase.OperationMetadata, + ) + + # Done; return the response. + return response + + async def start_goldengate_deployment( + self, + request: Optional[ + Union[goldengate_deployment.StartGoldengateDeploymentRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""Starts a single GoldengateDeployment. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + async def sample_start_goldengate_deployment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.StartGoldengateDeploymentRequest( + name="name_value", + ) + + # Make the request + operation = await client.start_goldengate_deployment(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.oracledatabase_v1.types.StartGoldengateDeploymentRequest, dict]]): + The request object. The request for ``GoldengateDeployment.Start``. + name (:class:`str`): + Required. The name of the Goldengate Deployment in the + following format: + projects/{project}/locations/{location}/goldengateDeployments/{goldengate_deployment}. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + 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.oracledatabase_v1.types.GoldengateDeployment` + GoldengateDeployment Goldengate Deployment resource + model. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, goldengate_deployment.StartGoldengateDeploymentRequest + ): + request = goldengate_deployment.StartGoldengateDeploymentRequest(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._client._transport._wrapped_methods[ + self._client._transport.start_goldengate_deployment + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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, + goldengate_deployment.GoldengateDeployment, + metadata_type=oracledatabase.OperationMetadata, + ) + + # Done; return the response. + return response + + async def list_goldengate_connections( + self, + request: Optional[ + Union[goldengate_connection.ListGoldengateConnectionsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListGoldengateConnectionsAsyncPager: + r"""Lists all the GoldengateConnections for the given + project and location. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + async def sample_list_goldengate_connections(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListGoldengateConnectionsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_goldengate_connections(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.oracledatabase_v1.types.ListGoldengateConnectionsRequest, dict]]): + The request object. The request for ``GoldengateConnection.List``. + parent (:class:`str`): + Required. The parent value for + GoldengateConnections in the following + format: + projects/{project}/locations/{location}. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGoldengateConnectionsAsyncPager: + The response for GoldengateConnection.List. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, goldengate_connection.ListGoldengateConnectionsRequest + ): + request = goldengate_connection.ListGoldengateConnectionsRequest(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._client._transport._wrapped_methods[ + self._client._transport.list_goldengate_connections + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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.ListGoldengateConnectionsAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_goldengate_connection( + self, + request: Optional[ + Union[goldengate_connection.GetGoldengateConnectionRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> goldengate_connection.GoldengateConnection: + r"""Gets details of a single GoldengateConnection. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + async def sample_get_goldengate_connection(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.GetGoldengateConnectionRequest( + name="name_value", + ) + + # Make the request + response = await client.get_goldengate_connection(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.oracledatabase_v1.types.GetGoldengateConnectionRequest, dict]]): + The request object. The request for ``GoldengateConnection.Get``. + name (:class:`str`): + Required. The name of the GoldengateConnection in the + following format: + projects/{project}/locations/{location}/goldengateConnections/{goldengate_connection}. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.types.GoldengateConnection: + Details of the GoldengateConnection + resource. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, goldengate_connection.GetGoldengateConnectionRequest + ): + request = goldengate_connection.GetGoldengateConnectionRequest(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._client._transport._wrapped_methods[ + self._client._transport.get_goldengate_connection + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def create_goldengate_connection( + self, + request: Optional[ + Union[gco_goldengate_connection.CreateGoldengateConnectionRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + goldengate_connection: Optional[ + gco_goldengate_connection.GoldengateConnection + ] = None, + goldengate_connection_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""Creates a new GoldengateConnection in a given project + and location. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + async def sample_create_goldengate_connection(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + goldengate_connection = oracledatabase_v1.GoldengateConnection() + goldengate_connection.properties.oracle_connection_properties.password = "password_value" + goldengate_connection.properties.connection_type = "ICEBERG" + goldengate_connection.properties.display_name = "display_name_value" + + request = oracledatabase_v1.CreateGoldengateConnectionRequest( + parent="parent_value", + goldengate_connection_id="goldengate_connection_id_value", + goldengate_connection=goldengate_connection, + ) + + # Make the request + operation = await client.create_goldengate_connection(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.oracledatabase_v1.types.CreateGoldengateConnectionRequest, dict]]): + The request object. The request for ``GoldengateConnection.Create``. + parent (:class:`str`): + Required. The value for parent of the + GoldengateConnection in the following + format: + projects/{project}/locations/{location}. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + goldengate_connection (:class:`google.cloud.oracledatabase_v1.types.GoldengateConnection`): + Required. The resource being created. + This corresponds to the ``goldengate_connection`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + goldengate_connection_id (:class:`str`): + Required. The ID of the GoldengateConnection to create. + This value is restricted to + (^\ `a-z <[a-z0-9-]{0,61}[a-z0-9]>`__?$) and must be a + maximum of 63 characters in length. The value must start + with a letter and end with a letter or a number. + + This corresponds to the ``goldengate_connection_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + 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.oracledatabase_v1.types.GoldengateConnection` + Details of the GoldengateConnection resource. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, goldengate_connection, goldengate_connection_id] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, gco_goldengate_connection.CreateGoldengateConnectionRequest + ): + request = gco_goldengate_connection.CreateGoldengateConnectionRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if goldengate_connection is not None: + request.goldengate_connection = goldengate_connection + if goldengate_connection_id is not None: + request.goldengate_connection_id = goldengate_connection_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.create_goldengate_connection + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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, + gco_goldengate_connection.GoldengateConnection, + metadata_type=oracledatabase.OperationMetadata, + ) + + # Done; return the response. + return response + + async def delete_goldengate_connection( + self, + request: Optional[ + Union[goldengate_connection.DeleteGoldengateConnectionRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""Deletes a single GoldengateConnection. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + async def sample_delete_goldengate_connection(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.DeleteGoldengateConnectionRequest( + name="name_value", + ) + + # Make the request + operation = await client.delete_goldengate_connection(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.oracledatabase_v1.types.DeleteGoldengateConnectionRequest, dict]]): + The request object. The request for ``GoldengateConnection.Delete``. + name (:class:`str`): + Required. The name of the GoldengateConnection in the + following format: + projects/{project}/locations/{location}/goldengateConnections/{goldengate_connection}. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, goldengate_connection.DeleteGoldengateConnectionRequest + ): + request = goldengate_connection.DeleteGoldengateConnectionRequest(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._client._transport._wrapped_methods[ + self._client._transport.delete_goldengate_connection + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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, + empty_pb2.Empty, + metadata_type=oracledatabase.OperationMetadata, + ) + + # Done; return the response. + return response + + async def get_goldengate_deployment_version( + self, + request: Optional[ + Union[ + goldengate_deployment_version.GetGoldengateDeploymentVersionRequest, + dict, + ] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> goldengate_deployment_version.GoldengateDeploymentVersion: + r"""Gets details of a single GoldengateDeploymentVersion. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + async def sample_get_goldengate_deployment_version(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.GetGoldengateDeploymentVersionRequest( + name="name_value", + ) + + # Make the request + response = await client.get_goldengate_deployment_version(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.oracledatabase_v1.types.GetGoldengateDeploymentVersionRequest, dict]]): + The request object. Message for getting a + GoldengateDeploymentVersion. + name (:class:`str`): + Required. The name of the GoldengateDeploymentVersion to + retrieve. Format: + projects/{project}/locations/{location}/goldengateDeploymentVersions/{goldengate_deployment_version} + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.types.GoldengateDeploymentVersion: + Details of the Goldengate Deployment + Version resource. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, goldengate_deployment_version.GetGoldengateDeploymentVersionRequest + ): + request = ( + goldengate_deployment_version.GetGoldengateDeploymentVersionRequest( + 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._client._transport._wrapped_methods[ + self._client._transport.get_goldengate_deployment_version + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_goldengate_deployment_versions( + self, + request: Optional[ + Union[ + goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest, + dict, + ] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListGoldengateDeploymentVersionsAsyncPager: + r"""Lists GoldengateDeploymentVersions in a given project + and location. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + async def sample_list_goldengate_deployment_versions(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListGoldengateDeploymentVersionsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_goldengate_deployment_versions(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentVersionsRequest, dict]]): + The request object. Message for listing + GoldengateDeploymentVersions. + parent (:class:`str`): + Required. Parent value for + ListGoldengateDeploymentVersionsRequest + Format: + projects/{project}/locations/{location} + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGoldengateDeploymentVersionsAsyncPager: + Message for response to listing + GoldengateDeploymentVersions + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest, + ): + request = ( + goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest( + 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._client._transport._wrapped_methods[ + self._client._transport.list_goldengate_deployment_versions + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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.ListGoldengateDeploymentVersionsAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_goldengate_deployment_type( + self, + request: Optional[ + Union[goldengate_deployment_type.GetGoldengateDeploymentTypeRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> goldengate_deployment_type.GoldengateDeploymentType: + r"""Gets details of a single GoldenGateDeploymentType. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + async def sample_get_goldengate_deployment_type(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.GetGoldengateDeploymentTypeRequest( + name="name_value", + ) + + # Make the request + response = await client.get_goldengate_deployment_type(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.oracledatabase_v1.types.GetGoldengateDeploymentTypeRequest, dict]]): + The request object. Message for getting a + GoldengateDeploymentType. + name (:class:`str`): + Required. The name of the GoldengateDeploymentType to + retrieve. Format: + projects/{project}/locations/{location}/goldengateDeploymentTypes/{goldengate_deployment_type} + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.types.GoldengateDeploymentType: + Details of the Goldengate Deployment + Type resource. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, goldengate_deployment_type.GetGoldengateDeploymentTypeRequest + ): + request = goldengate_deployment_type.GetGoldengateDeploymentTypeRequest( + 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._client._transport._wrapped_methods[ + self._client._transport.get_goldengate_deployment_type + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_goldengate_deployment_types( + self, + request: Optional[ + Union[goldengate_deployment_type.ListGoldengateDeploymentTypesRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListGoldengateDeploymentTypesAsyncPager: + r"""Lists GoldenGateDeploymentTypes in a given project + and location. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + async def sample_list_goldengate_deployment_types(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListGoldengateDeploymentTypesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_goldengate_deployment_types(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentTypesRequest, dict]]): + The request object. Message for listing + GoldengateDeploymentTypes. + parent (:class:`str`): + Required. The parent resource. + Format: + projects/{project}/locations/{location} + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGoldengateDeploymentTypesAsyncPager: + Message for response to listing + GoldengateDeploymentTypes + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, goldengate_deployment_type.ListGoldengateDeploymentTypesRequest + ): + request = goldengate_deployment_type.ListGoldengateDeploymentTypesRequest( + 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._client._transport._wrapped_methods[ + self._client._transport.list_goldengate_deployment_types + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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.ListGoldengateDeploymentTypesAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_goldengate_deployment_environment( + self, + request: Optional[ + Union[ + goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest, + dict, + ] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> goldengate_deployment_environment.GoldengateDeploymentEnvironment: + r"""Gets details of a single + GoldengateDeploymentEnvironment. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + async def sample_get_goldengate_deployment_environment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.GetGoldengateDeploymentEnvironmentRequest( + name="name_value", + ) + + # Make the request + response = await client.get_goldengate_deployment_environment(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.oracledatabase_v1.types.GetGoldengateDeploymentEnvironmentRequest, dict]]): + The request object. Message for getting a + GoldengateDeploymentEnvironment. + name (:class:`str`): + Required. Name of the resource with the format: + projects/{project}/locations/{location}/goldengateDeploymentEnvironments/{goldengate_deployment_environment} + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.types.GoldengateDeploymentEnvironment: + Details of the Goldengate Deployment + Environment resource. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest, + ): + request = goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest( + 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._client._transport._wrapped_methods[ + self._client._transport.get_goldengate_deployment_environment + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_goldengate_deployment_environments( + self, + request: Optional[ + Union[ + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest, + dict, + ] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListGoldengateDeploymentEnvironmentsAsyncPager: + r"""Lists GoldengateDeploymentEnvironments in a given + project and location. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + async def sample_list_goldengate_deployment_environments(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListGoldengateDeploymentEnvironmentsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_goldengate_deployment_environments(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentEnvironmentsRequest, dict]]): + The request object. Message for listing + GoldengateDeploymentEnvironments. + parent (:class:`str`): + Required. The parent, which owns this + collection of + GoldengateDeploymentEnvironments. + Format: + + projects/{project}/locations/{location} + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGoldengateDeploymentEnvironmentsAsyncPager: + Message for response to listing + GoldengateDeploymentEnvironments + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest, + ): + request = goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest( + 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._client._transport._wrapped_methods[ + self._client._transport.list_goldengate_deployment_environments + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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.ListGoldengateDeploymentEnvironmentsAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_goldengate_connection_type( + self, + request: Optional[ + Union[goldengate_connection_type.GetGoldengateConnectionTypeRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> goldengate_connection_type.GoldengateConnectionType: + r"""Gets details of a single GoldengateConnectionType. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + async def sample_get_goldengate_connection_type(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.GetGoldengateConnectionTypeRequest( + name="name_value", + ) + + # Make the request + response = await client.get_goldengate_connection_type(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.oracledatabase_v1.types.GetGoldengateConnectionTypeRequest, dict]]): + The request object. Message for getting a + GoldengateConnectionType. + name (:class:`str`): + Required. Name of the resource in the format: + projects/{project}/locations/{location}/goldengateConnectionTypes/{goldengate_connection_type} + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.types.GoldengateConnectionType: + Details of the Goldengate Connection + Type resource. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, goldengate_connection_type.GetGoldengateConnectionTypeRequest + ): + request = goldengate_connection_type.GetGoldengateConnectionTypeRequest( + 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._client._transport._wrapped_methods[ + self._client._transport.get_goldengate_connection_type + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_goldengate_connection_types( + self, + request: Optional[ + Union[goldengate_connection_type.ListGoldengateConnectionTypesRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListGoldengateConnectionTypesAsyncPager: + r"""Lists GoldengateConnectionTypes in a given project + and location. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + async def sample_list_goldengate_connection_types(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListGoldengateConnectionTypesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_goldengate_connection_types(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.oracledatabase_v1.types.ListGoldengateConnectionTypesRequest, dict]]): + The request object. Message for listing + GoldengateConnectionTypes. + parent (:class:`str`): + Required. Parent value for + ListGoldengateConnectionTypesRequest + Format: + projects/{project}/locations/{location} + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGoldengateConnectionTypesAsyncPager: + Message for response to listing + GoldengateConnectionTypes + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, goldengate_connection_type.ListGoldengateConnectionTypesRequest + ): + request = goldengate_connection_type.ListGoldengateConnectionTypesRequest( + 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._client._transport._wrapped_methods[ + self._client._transport.list_goldengate_connection_types + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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.ListGoldengateConnectionTypesAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_db_versions( + self, + request: Optional[Union[db_version.ListDbVersionsRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListDbVersionsAsyncPager: + r"""List DbVersions for the given project and location. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + async def sample_list_db_versions(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListDbVersionsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_db_versions(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.oracledatabase_v1.types.ListDbVersionsRequest, dict]]): + The request object. The request for ``DbVersions.List``. + parent (:class:`str`): + Required. The parent value for the + DbVersion resource with the format: + projects/{project}/locations/{location} + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDbVersionsAsyncPager: + The response for DbVersions.List. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, db_version.ListDbVersionsRequest): + request = db_version.ListDbVersionsRequest(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._client._transport._wrapped_methods[ + self._client._transport.list_db_versions + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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.ListDbVersionsAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_database_character_sets( + self, + request: Optional[ + Union[database_character_set.ListDatabaseCharacterSetsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListDatabaseCharacterSetsAsyncPager: + r"""List DatabaseCharacterSets for the given project and + location. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + async def sample_list_database_character_sets(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListDatabaseCharacterSetsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_database_character_sets(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.oracledatabase_v1.types.ListDatabaseCharacterSetsRequest, dict]]): + The request object. The request for ``DatabaseCharacterSet.List``. + parent (:class:`str`): + Required. The parent value for + DatabaseCharacterSets in the following + format: + projects/{project}/locations/{location}. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDatabaseCharacterSetsAsyncPager: + The response for DatabaseCharacterSet.List. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, database_character_set.ListDatabaseCharacterSetsRequest + ): + request = database_character_set.ListDatabaseCharacterSetsRequest(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._client._transport._wrapped_methods[ + self._client._transport.list_database_character_sets + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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.ListDatabaseCharacterSetsAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_goldengate_connection_assignments( + self, + request: Optional[ + Union[ + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest, + dict, + ] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListGoldengateConnectionAssignmentsAsyncPager: + r"""Lists GoldengateConnectionAssignments in a given + project and location. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + async def sample_list_goldengate_connection_assignments(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListGoldengateConnectionAssignmentsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_goldengate_connection_assignments(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.oracledatabase_v1.types.ListGoldengateConnectionAssignmentsRequest, dict]]): + The request object. Request message for listing + GoldengateConnectionAssignments. + parent (:class:`str`): + Required. The parent value for the + GoldengateConnectionAssignments. Format: + projects/{project}/locations/{location} + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGoldengateConnectionAssignmentsAsyncPager: + Response message for listing + GoldengateConnectionAssignments. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest, + ): + request = goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest( + 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._client._transport._wrapped_methods[ + self._client._transport.list_goldengate_connection_assignments + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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.ListGoldengateConnectionAssignmentsAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_goldengate_connection_assignment( + self, + request: Optional[ + Union[ + goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest, + dict, + ] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> goldengate_connection_assignment.GoldengateConnectionAssignment: + r"""Gets details of a single + GoldengateConnectionAssignment. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + async def sample_get_goldengate_connection_assignment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.GetGoldengateConnectionAssignmentRequest( + name="name_value", + ) + + # Make the request + response = await client.get_goldengate_connection_assignment(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.oracledatabase_v1.types.GetGoldengateConnectionAssignmentRequest, dict]]): + The request object. Request message for getting a + GoldengateConnectionAssignment. + name (:class:`str`): + Required. The name of the GoldengateConnectionAssignment + to retrieve. Format: + projects/{project}/locations/{location}/goldengateConnectionAssignments/{goldengate_connection_assignment} + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.types.GoldengateConnectionAssignment: + Represents the metadata of a + Goldengate Connection Assignment. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest, + ): + request = goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest( + 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._client._transport._wrapped_methods[ + self._client._transport.get_goldengate_connection_assignment + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def create_goldengate_connection_assignment( + self, + request: Optional[ + Union[ + gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest, + dict, + ] + ] = None, + *, + parent: Optional[str] = None, + goldengate_connection_assignment: Optional[ + gco_goldengate_connection_assignment.GoldengateConnectionAssignment + ] = None, + goldengate_connection_assignment_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""Creates a new GoldengateConnectionAssignment in a + given project and location. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + async def sample_create_goldengate_connection_assignment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + goldengate_connection_assignment = oracledatabase_v1.GoldengateConnectionAssignment() + goldengate_connection_assignment.properties.goldengate_connection = "goldengate_connection_value" + goldengate_connection_assignment.properties.goldengate_deployment = "goldengate_deployment_value" + + request = oracledatabase_v1.CreateGoldengateConnectionAssignmentRequest( + parent="parent_value", + goldengate_connection_assignment_id="goldengate_connection_assignment_id_value", + goldengate_connection_assignment=goldengate_connection_assignment, + ) + + # Make the request + operation = await client.create_goldengate_connection_assignment(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.oracledatabase_v1.types.CreateGoldengateConnectionAssignmentRequest, dict]]): + The request object. Request message for creating a + GoldengateConnectionAssignment. + parent (:class:`str`): + Required. The parent resource where + this GoldengateConnectionAssignment will + be created. Format: + projects/{project}/locations/{location} + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + goldengate_connection_assignment (:class:`google.cloud.oracledatabase_v1.types.GoldengateConnectionAssignment`): + Required. The + GoldengateConnectionAssignment to + create. + + This corresponds to the ``goldengate_connection_assignment`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + goldengate_connection_assignment_id (:class:`str`): + Required. The ID of the + GoldengateConnectionAssignment to + create. + + This corresponds to the ``goldengate_connection_assignment_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + 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.oracledatabase_v1.types.GoldengateConnectionAssignment` + Represents the metadata of a Goldengate Connection + Assignment. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [ + parent, + goldengate_connection_assignment, + goldengate_connection_assignment_id, + ] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest, + ): + request = gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if goldengate_connection_assignment is not None: + request.goldengate_connection_assignment = goldengate_connection_assignment + if goldengate_connection_assignment_id is not None: + request.goldengate_connection_assignment_id = ( + goldengate_connection_assignment_id + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.create_goldengate_connection_assignment + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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, + gco_goldengate_connection_assignment.GoldengateConnectionAssignment, + metadata_type=oracledatabase.OperationMetadata, + ) + + # Done; return the response. + return response + + async def delete_goldengate_connection_assignment( + self, + request: Optional[ + Union[ + goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest, + dict, + ] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""Deletes a single GoldengateConnectionAssignment. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + async def sample_delete_goldengate_connection_assignment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.DeleteGoldengateConnectionAssignmentRequest( + name="name_value", + ) + + # Make the request + operation = await client.delete_goldengate_connection_assignment(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.oracledatabase_v1.types.DeleteGoldengateConnectionAssignmentRequest, dict]]): + The request object. Request message for deleting a + GoldengateConnectionAssignment. + name (:class:`str`): + Required. The name of the GoldengateConnectionAssignment + to delete. Format: + projects/{project}/locations/{location}/goldengateConnectionAssignments/{goldengate_connection_assignment} + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest, + ): + request = goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest( + 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._client._transport._wrapped_methods[ + self._client._transport.delete_goldengate_connection_assignment + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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, + empty_pb2.Empty, + metadata_type=oracledatabase.OperationMetadata, + ) + + # Done; return the response. + return response + + async def test_goldengate_connection_assignment( + self, + request: Optional[ + Union[ + goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest, + dict, + ] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse: + r"""Tests a single GoldengateConnectionAssignment. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + async def sample_test_goldengate_connection_assignment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.TestGoldengateConnectionAssignmentRequest( + name="name_value", + ) + + # Make the request + response = await client.test_goldengate_connection_assignment(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.oracledatabase_v1.types.TestGoldengateConnectionAssignmentRequest, dict]]): + The request object. Request message for + TestGoldengateConnectionAssignment. + name (:class:`str`): + Required. Name of the connection assignment for which to + test connection. + projects/{project}/locations/{region}/goldengateConnectionAssignments/{goldengate_connection_assignment} + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.types.TestGoldengateConnectionAssignmentResponse: + The result of the connectivity test + performed between the Goldengate + deployment and the associated database / + service. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest, + ): + request = goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest( + 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._client._transport._wrapped_methods[ + self._client._transport.test_goldengate_connection_assignment + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata, diff --git a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/client.py b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/client.py index d8fa76257bdf..e9186be91c05 100644 --- a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/client.py +++ b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/client.py @@ -89,6 +89,13 @@ exadb_vm_cluster, exascale_db_storage_vault, gi_version, + goldengate_connection, + goldengate_connection_assignment, + goldengate_connection_type, + goldengate_deployment, + goldengate_deployment_environment, + goldengate_deployment_type, + goldengate_deployment_version, minor_version, odb_network, odb_subnet, @@ -106,6 +113,15 @@ from google.cloud.oracledatabase_v1.types import ( exascale_db_storage_vault as gco_exascale_db_storage_vault, ) +from google.cloud.oracledatabase_v1.types import ( + goldengate_connection as gco_goldengate_connection, +) +from google.cloud.oracledatabase_v1.types import ( + goldengate_connection_assignment as gco_goldengate_connection_assignment, +) +from google.cloud.oracledatabase_v1.types import ( + goldengate_deployment as gco_goldengate_deployment, +) from google.cloud.oracledatabase_v1.types import odb_network as gco_odb_network from google.cloud.oracledatabase_v1.types import odb_subnet as gco_odb_subnet @@ -697,6 +713,160 @@ def parse_gi_version_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def goldengate_connection_path( + project: str, + location: str, + goldengate_connection: str, + ) -> str: + """Returns a fully-qualified goldengate_connection string.""" + return "projects/{project}/locations/{location}/goldengateConnections/{goldengate_connection}".format( + project=project, + location=location, + goldengate_connection=goldengate_connection, + ) + + @staticmethod + def parse_goldengate_connection_path(path: str) -> Dict[str, str]: + """Parses a goldengate_connection path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/goldengateConnections/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def goldengate_connection_assignment_path( + project: str, + location: str, + goldengate_connection_assignment: str, + ) -> str: + """Returns a fully-qualified goldengate_connection_assignment string.""" + return "projects/{project}/locations/{location}/goldengateConnectionAssignments/{goldengate_connection_assignment}".format( + project=project, + location=location, + goldengate_connection_assignment=goldengate_connection_assignment, + ) + + @staticmethod + def parse_goldengate_connection_assignment_path(path: str) -> Dict[str, str]: + """Parses a goldengate_connection_assignment path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/goldengateConnectionAssignments/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def goldengate_connection_type_path( + project: str, + location: str, + goldengate_connection_type: str, + ) -> str: + """Returns a fully-qualified goldengate_connection_type string.""" + return "projects/{project}/locations/{location}/goldengateConnectionTypes/{goldengate_connection_type}".format( + project=project, + location=location, + goldengate_connection_type=goldengate_connection_type, + ) + + @staticmethod + def parse_goldengate_connection_type_path(path: str) -> Dict[str, str]: + """Parses a goldengate_connection_type path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/goldengateConnectionTypes/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def goldengate_deployment_path( + project: str, + location: str, + goldengate_deployment: str, + ) -> str: + """Returns a fully-qualified goldengate_deployment string.""" + return "projects/{project}/locations/{location}/goldengateDeployments/{goldengate_deployment}".format( + project=project, + location=location, + goldengate_deployment=goldengate_deployment, + ) + + @staticmethod + def parse_goldengate_deployment_path(path: str) -> Dict[str, str]: + """Parses a goldengate_deployment path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/goldengateDeployments/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def goldengate_deployment_environment_path( + project: str, + location: str, + goldengate_deployment_environment: str, + ) -> str: + """Returns a fully-qualified goldengate_deployment_environment string.""" + return "projects/{project}/locations/{location}/goldengateDeploymentEnvironments/{goldengate_deployment_environment}".format( + project=project, + location=location, + goldengate_deployment_environment=goldengate_deployment_environment, + ) + + @staticmethod + def parse_goldengate_deployment_environment_path(path: str) -> Dict[str, str]: + """Parses a goldengate_deployment_environment path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/goldengateDeploymentEnvironments/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def goldengate_deployment_type_path( + project: str, + location: str, + goldengate_deployment_type: str, + ) -> str: + """Returns a fully-qualified goldengate_deployment_type string.""" + return "projects/{project}/locations/{location}/goldengateDeploymentTypes/{goldengate_deployment_type}".format( + project=project, + location=location, + goldengate_deployment_type=goldengate_deployment_type, + ) + + @staticmethod + def parse_goldengate_deployment_type_path(path: str) -> Dict[str, str]: + """Parses a goldengate_deployment_type path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/goldengateDeploymentTypes/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def goldengate_deployment_version_path( + project: str, + location: str, + goldengate_deployment_version: str, + ) -> str: + """Returns a fully-qualified goldengate_deployment_version string.""" + return "projects/{project}/locations/{location}/goldengateDeploymentVersions/{goldengate_deployment_version}".format( + project=project, + location=location, + goldengate_deployment_version=goldengate_deployment_version, + ) + + @staticmethod + def parse_goldengate_deployment_version_path(path: str) -> Dict[str, str]: + """Parses a goldengate_deployment_version path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/goldengateDeploymentVersions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def minor_version_path( project: str, @@ -810,6 +980,28 @@ def parse_pluggable_database_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def secret_version_path( + project: str, + secret: str, + secret_version: str, + ) -> str: + """Returns a fully-qualified secret_version string.""" + return "projects/{project}/secrets/{secret}/versions/{secret_version}".format( + project=project, + secret=secret, + secret_version=secret_version, + ) + + @staticmethod + def parse_secret_version_path(path: str) -> Dict[str, str]: + """Parses a secret_version path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/secrets/(?P.+?)/versions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def common_billing_account_path( billing_account: str, @@ -4832,7 +5024,6 @@ def sample_switchover_autonomous_database(): # Initialize request argument(s) request = oracledatabase_v1.SwitchoverAutonomousDatabaseRequest( name="name_value", - peer_autonomous_database="peer_autonomous_database_value", ) # Make the request @@ -4858,8 +5049,10 @@ def sample_switchover_autonomous_database(): on the ``request`` instance; if ``request`` is provided, this should not be set. peer_autonomous_database (str): - Required. The peer database name to - switch over to. + Optional. The peer database name to + switch over to. Required for + cross-region standby, and must be + omitted for in-region Data Guard. This corresponds to the ``peer_autonomous_database`` field on the ``request`` instance; if ``request`` is provided, this @@ -4971,7 +5164,6 @@ def sample_failover_autonomous_database(): # Initialize request argument(s) request = oracledatabase_v1.FailoverAutonomousDatabaseRequest( name="name_value", - peer_autonomous_database="peer_autonomous_database_value", ) # Make the request @@ -4997,8 +5189,10 @@ def sample_failover_autonomous_database(): on the ``request`` instance; if ``request`` is provided, this should not be set. peer_autonomous_database (str): - Required. The peer database name to - fail over to. + Optional. The peer database name to + fail over to. Required for cross-region + standby, and must be omitted for + in-region Data Guard. This corresponds to the ``peer_autonomous_database`` field on the ``request`` instance; if ``request`` is provided, this @@ -8595,16 +8789,19 @@ def sample_delete_db_system(): # Done; return the response. return response - def list_db_versions( + def list_goldengate_deployments( self, - request: Optional[Union[db_version.ListDbVersionsRequest, dict]] = None, + request: Optional[ + Union[goldengate_deployment.ListGoldengateDeploymentsRequest, dict] + ] = None, *, parent: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> pagers.ListDbVersionsPager: - r"""List DbVersions for the given project and location. + ) -> pagers.ListGoldengateDeploymentsPager: + r"""Lists all the GoldengateDeployments for the given + project and location. .. code-block:: python @@ -8617,29 +8814,30 @@ def list_db_versions( # https://googleapis.dev/python/google-api-core/latest/client_options.html from google.cloud import oracledatabase_v1 - def sample_list_db_versions(): + def sample_list_goldengate_deployments(): # Create a client client = oracledatabase_v1.OracleDatabaseClient() # Initialize request argument(s) - request = oracledatabase_v1.ListDbVersionsRequest( + request = oracledatabase_v1.ListGoldengateDeploymentsRequest( parent="parent_value", ) # Make the request - page_result = client.list_db_versions(request=request) + page_result = client.list_goldengate_deployments(request=request) # Handle the response for response in page_result: print(response) Args: - request (Union[google.cloud.oracledatabase_v1.types.ListDbVersionsRequest, dict]): - The request object. The request for ``DbVersions.List``. + request (Union[google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentsRequest, dict]): + The request object. The request for ``GoldengateDeployment.List``. parent (str): - Required. The parent value for the - DbVersion resource with the format: - projects/{project}/locations/{location} + Required. The parent value for + GoldengateDeployments in the following + format: + projects/{project}/locations/{location}. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -8653,8 +8851,8 @@ def sample_list_db_versions(): be of type `bytes`. Returns: - google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDbVersionsPager: - The response for DbVersions.List. + google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGoldengateDeploymentsPager: + The response for GoldengateDeployment.List. Iterating over this object will yield results and resolve additional pages automatically. @@ -8675,8 +8873,10 @@ def sample_list_db_versions(): # - Use the request object if provided (there's no risk of modifying the input as # there are no flattened fields), or create one. - if not isinstance(request, db_version.ListDbVersionsRequest): - request = db_version.ListDbVersionsRequest(request) + if not isinstance( + request, goldengate_deployment.ListGoldengateDeploymentsRequest + ): + request = goldengate_deployment.ListGoldengateDeploymentsRequest(request) # If we have keyword arguments corresponding to fields on the # request, apply these. if parent is not None: @@ -8684,7 +8884,9 @@ def sample_list_db_versions(): # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.list_db_versions] + rpc = self._transport._wrapped_methods[ + self._transport.list_goldengate_deployments + ] # Certain fields should be provided within the metadata header; # add these here. @@ -8705,7 +8907,7 @@ def sample_list_db_versions(): # This method is paged; wrap the response in a pager, which provides # an `__iter__` convenience method. - response = pagers.ListDbVersionsPager( + response = pagers.ListGoldengateDeploymentsPager( method=rpc, request=request, response=response, @@ -8717,19 +8919,18 @@ def sample_list_db_versions(): # Done; return the response. return response - def list_database_character_sets( + def get_goldengate_deployment( self, request: Optional[ - Union[database_character_set.ListDatabaseCharacterSetsRequest, dict] + Union[goldengate_deployment.GetGoldengateDeploymentRequest, dict] ] = None, *, - parent: Optional[str] = None, + name: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> pagers.ListDatabaseCharacterSetsPager: - r"""List DatabaseCharacterSets for the given project and - location. + ) -> goldengate_deployment.GoldengateDeployment: + r"""Gets details of a single GoldengateDeployment. .. code-block:: python @@ -8742,32 +8943,30 @@ def list_database_character_sets( # https://googleapis.dev/python/google-api-core/latest/client_options.html from google.cloud import oracledatabase_v1 - def sample_list_database_character_sets(): + def sample_get_goldengate_deployment(): # Create a client client = oracledatabase_v1.OracleDatabaseClient() # Initialize request argument(s) - request = oracledatabase_v1.ListDatabaseCharacterSetsRequest( - parent="parent_value", + request = oracledatabase_v1.GetGoldengateDeploymentRequest( + name="name_value", ) # Make the request - page_result = client.list_database_character_sets(request=request) + response = client.get_goldengate_deployment(request=request) # Handle the response - for response in page_result: - print(response) + print(response) Args: - request (Union[google.cloud.oracledatabase_v1.types.ListDatabaseCharacterSetsRequest, dict]): - The request object. The request for ``DatabaseCharacterSet.List``. - parent (str): - Required. The parent value for - DatabaseCharacterSets in the following - format: - projects/{project}/locations/{location}. + request (Union[google.cloud.oracledatabase_v1.types.GetGoldengateDeploymentRequest, dict]): + The request object. The request for ``GoldengateDeployment.Get``. + name (str): + Required. The name of the GoldengateDeployment in the + following format: + projects/{project}/locations/{location}/goldengateDeployments/{goldengate_deployment}. - This corresponds to the ``parent`` field + 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, @@ -8779,17 +8978,15 @@ def sample_list_database_character_sets(): be of type `bytes`. Returns: - google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDatabaseCharacterSetsPager: - The response for DatabaseCharacterSet.List. - - Iterating over this object will yield results and - resolve additional pages automatically. + google.cloud.oracledatabase_v1.types.GoldengateDeployment: + GoldengateDeployment Goldengate + Deployment resource model. """ # Create or coerce a protobuf request object. # - Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - flattened_params = [parent] + flattened_params = [name] has_flattened_params = ( len([param for param in flattened_params if param is not None]) > 0 ) @@ -8802,24 +8999,24 @@ def sample_list_database_character_sets(): # - Use the request object if provided (there's no risk of modifying the input as # there are no flattened fields), or create one. if not isinstance( - request, database_character_set.ListDatabaseCharacterSetsRequest + request, goldengate_deployment.GetGoldengateDeploymentRequest ): - request = database_character_set.ListDatabaseCharacterSetsRequest(request) + request = goldengate_deployment.GetGoldengateDeploymentRequest(request) # If we have keyword arguments corresponding to fields on the # request, apply these. - if parent is not None: - request.parent = parent + 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.list_database_character_sets + self._transport.get_goldengate_deployment ] # 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),)), + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), ) # Validate the universe domain. @@ -8833,12 +9030,3084 @@ def sample_list_database_character_sets(): metadata=metadata, ) - # This method is paged; wrap the response in a pager, which provides - # an `__iter__` convenience method. - response = pagers.ListDatabaseCharacterSetsPager( - method=rpc, - request=request, - response=response, + # Done; return the response. + return response + + def create_goldengate_deployment( + self, + request: Optional[ + Union[gco_goldengate_deployment.CreateGoldengateDeploymentRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + goldengate_deployment: Optional[ + gco_goldengate_deployment.GoldengateDeployment + ] = None, + goldengate_deployment_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Creates a new GoldengateDeployment in a given project + and location. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + def sample_create_goldengate_deployment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + goldengate_deployment = oracledatabase_v1.GoldengateDeployment() + goldengate_deployment.properties.deployment_type = "deployment_type_value" + goldengate_deployment.properties.ogg_data.admin_password = "admin_password_value" + goldengate_deployment.properties.ogg_data.deployment = "deployment_value" + goldengate_deployment.properties.ogg_data.admin_username = "admin_username_value" + goldengate_deployment.odb_subnet = "odb_subnet_value" + goldengate_deployment.display_name = "display_name_value" + + request = oracledatabase_v1.CreateGoldengateDeploymentRequest( + parent="parent_value", + goldengate_deployment_id="goldengate_deployment_id_value", + goldengate_deployment=goldengate_deployment, + ) + + # Make the request + operation = client.create_goldengate_deployment(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.oracledatabase_v1.types.CreateGoldengateDeploymentRequest, dict]): + The request object. The request for ``GoldengateDeployment.Create``. + parent (str): + Required. The value for parent of the + GoldengateDeployment in the following + format: + projects/{project}/locations/{location}. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + goldengate_deployment (google.cloud.oracledatabase_v1.types.GoldengateDeployment): + Required. The resource being created. + This corresponds to the ``goldengate_deployment`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + goldengate_deployment_id (str): + Required. The ID of the GoldengateDeployment to create. + This value is restricted to + (^\ `a-z <[a-z0-9-]{0,61}[a-z0-9]>`__?$) and must be a + maximum of 63 characters in length. The value must start + with a letter and end with a letter or a number. + + This corresponds to the ``goldengate_deployment_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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.oracledatabase_v1.types.GoldengateDeployment` + GoldengateDeployment Goldengate Deployment resource + model. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, goldengate_deployment, goldengate_deployment_id] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, gco_goldengate_deployment.CreateGoldengateDeploymentRequest + ): + request = gco_goldengate_deployment.CreateGoldengateDeploymentRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if goldengate_deployment is not None: + request.goldengate_deployment = goldengate_deployment + if goldengate_deployment_id is not None: + request.goldengate_deployment_id = goldengate_deployment_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.create_goldengate_deployment + ] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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, + gco_goldengate_deployment.GoldengateDeployment, + metadata_type=oracledatabase.OperationMetadata, + ) + + # Done; return the response. + return response + + def delete_goldengate_deployment( + self, + request: Optional[ + Union[goldengate_deployment.DeleteGoldengateDeploymentRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Deletes a single GoldengateDeployment. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + def sample_delete_goldengate_deployment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.DeleteGoldengateDeploymentRequest( + name="name_value", + ) + + # Make the request + operation = client.delete_goldengate_deployment(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.oracledatabase_v1.types.DeleteGoldengateDeploymentRequest, dict]): + The request object. The request for ``GoldengateDeployment.Delete``. + name (str): + Required. The name of the GoldengateDeployment in the + following format: + projects/{project}/locations/{location}/goldengateDeployments/{goldengate_deployment}. + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, goldengate_deployment.DeleteGoldengateDeploymentRequest + ): + request = goldengate_deployment.DeleteGoldengateDeploymentRequest(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_goldengate_deployment + ] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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, + empty_pb2.Empty, + metadata_type=oracledatabase.OperationMetadata, + ) + + # Done; return the response. + return response + + def stop_goldengate_deployment( + self, + request: Optional[ + Union[goldengate_deployment.StopGoldengateDeploymentRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Stops a single GoldengateDeployment. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + def sample_stop_goldengate_deployment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.StopGoldengateDeploymentRequest( + name="name_value", + ) + + # Make the request + operation = client.stop_goldengate_deployment(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.oracledatabase_v1.types.StopGoldengateDeploymentRequest, dict]): + The request object. The request for ``GoldengateDeployment.Stop``. + name (str): + Required. The name of the Goldengate Deployment in the + following format: + projects/{project}/locations/{location}/goldengateDeployments/{goldengate_deployment}. + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.oracledatabase_v1.types.GoldengateDeployment` + GoldengateDeployment Goldengate Deployment resource + model. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, goldengate_deployment.StopGoldengateDeploymentRequest + ): + request = goldengate_deployment.StopGoldengateDeploymentRequest(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.stop_goldengate_deployment + ] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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, + goldengate_deployment.GoldengateDeployment, + metadata_type=oracledatabase.OperationMetadata, + ) + + # Done; return the response. + return response + + def start_goldengate_deployment( + self, + request: Optional[ + Union[goldengate_deployment.StartGoldengateDeploymentRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Starts a single GoldengateDeployment. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + def sample_start_goldengate_deployment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.StartGoldengateDeploymentRequest( + name="name_value", + ) + + # Make the request + operation = client.start_goldengate_deployment(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.oracledatabase_v1.types.StartGoldengateDeploymentRequest, dict]): + The request object. The request for ``GoldengateDeployment.Start``. + name (str): + Required. The name of the Goldengate Deployment in the + following format: + projects/{project}/locations/{location}/goldengateDeployments/{goldengate_deployment}. + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.oracledatabase_v1.types.GoldengateDeployment` + GoldengateDeployment Goldengate Deployment resource + model. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, goldengate_deployment.StartGoldengateDeploymentRequest + ): + request = goldengate_deployment.StartGoldengateDeploymentRequest(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.start_goldengate_deployment + ] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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, + goldengate_deployment.GoldengateDeployment, + metadata_type=oracledatabase.OperationMetadata, + ) + + # Done; return the response. + return response + + def list_goldengate_connections( + self, + request: Optional[ + Union[goldengate_connection.ListGoldengateConnectionsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListGoldengateConnectionsPager: + r"""Lists all the GoldengateConnections for the given + project and location. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + def sample_list_goldengate_connections(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListGoldengateConnectionsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_goldengate_connections(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.oracledatabase_v1.types.ListGoldengateConnectionsRequest, dict]): + The request object. The request for ``GoldengateConnection.List``. + parent (str): + Required. The parent value for + GoldengateConnections in the following + format: + projects/{project}/locations/{location}. + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGoldengateConnectionsPager: + The response for GoldengateConnection.List. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, goldengate_connection.ListGoldengateConnectionsRequest + ): + request = goldengate_connection.ListGoldengateConnectionsRequest(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_goldengate_connections + ] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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.ListGoldengateConnectionsPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_goldengate_connection( + self, + request: Optional[ + Union[goldengate_connection.GetGoldengateConnectionRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> goldengate_connection.GoldengateConnection: + r"""Gets details of a single GoldengateConnection. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + def sample_get_goldengate_connection(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.GetGoldengateConnectionRequest( + name="name_value", + ) + + # Make the request + response = client.get_goldengate_connection(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.oracledatabase_v1.types.GetGoldengateConnectionRequest, dict]): + The request object. The request for ``GoldengateConnection.Get``. + name (str): + Required. The name of the GoldengateConnection in the + following format: + projects/{project}/locations/{location}/goldengateConnections/{goldengate_connection}. + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.types.GoldengateConnection: + Details of the GoldengateConnection + resource. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, goldengate_connection.GetGoldengateConnectionRequest + ): + request = goldengate_connection.GetGoldengateConnectionRequest(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_goldengate_connection + ] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def create_goldengate_connection( + self, + request: Optional[ + Union[gco_goldengate_connection.CreateGoldengateConnectionRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + goldengate_connection: Optional[ + gco_goldengate_connection.GoldengateConnection + ] = None, + goldengate_connection_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Creates a new GoldengateConnection in a given project + and location. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + def sample_create_goldengate_connection(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + goldengate_connection = oracledatabase_v1.GoldengateConnection() + goldengate_connection.properties.oracle_connection_properties.password = "password_value" + goldengate_connection.properties.connection_type = "ICEBERG" + goldengate_connection.properties.display_name = "display_name_value" + + request = oracledatabase_v1.CreateGoldengateConnectionRequest( + parent="parent_value", + goldengate_connection_id="goldengate_connection_id_value", + goldengate_connection=goldengate_connection, + ) + + # Make the request + operation = client.create_goldengate_connection(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.oracledatabase_v1.types.CreateGoldengateConnectionRequest, dict]): + The request object. The request for ``GoldengateConnection.Create``. + parent (str): + Required. The value for parent of the + GoldengateConnection in the following + format: + projects/{project}/locations/{location}. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + goldengate_connection (google.cloud.oracledatabase_v1.types.GoldengateConnection): + Required. The resource being created. + This corresponds to the ``goldengate_connection`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + goldengate_connection_id (str): + Required. The ID of the GoldengateConnection to create. + This value is restricted to + (^\ `a-z <[a-z0-9-]{0,61}[a-z0-9]>`__?$) and must be a + maximum of 63 characters in length. The value must start + with a letter and end with a letter or a number. + + This corresponds to the ``goldengate_connection_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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.oracledatabase_v1.types.GoldengateConnection` + Details of the GoldengateConnection resource. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, goldengate_connection, goldengate_connection_id] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, gco_goldengate_connection.CreateGoldengateConnectionRequest + ): + request = gco_goldengate_connection.CreateGoldengateConnectionRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if goldengate_connection is not None: + request.goldengate_connection = goldengate_connection + if goldengate_connection_id is not None: + request.goldengate_connection_id = goldengate_connection_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.create_goldengate_connection + ] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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, + gco_goldengate_connection.GoldengateConnection, + metadata_type=oracledatabase.OperationMetadata, + ) + + # Done; return the response. + return response + + def delete_goldengate_connection( + self, + request: Optional[ + Union[goldengate_connection.DeleteGoldengateConnectionRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Deletes a single GoldengateConnection. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + def sample_delete_goldengate_connection(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.DeleteGoldengateConnectionRequest( + name="name_value", + ) + + # Make the request + operation = client.delete_goldengate_connection(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.oracledatabase_v1.types.DeleteGoldengateConnectionRequest, dict]): + The request object. The request for ``GoldengateConnection.Delete``. + name (str): + Required. The name of the GoldengateConnection in the + following format: + projects/{project}/locations/{location}/goldengateConnections/{goldengate_connection}. + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, goldengate_connection.DeleteGoldengateConnectionRequest + ): + request = goldengate_connection.DeleteGoldengateConnectionRequest(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_goldengate_connection + ] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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, + empty_pb2.Empty, + metadata_type=oracledatabase.OperationMetadata, + ) + + # Done; return the response. + return response + + def get_goldengate_deployment_version( + self, + request: Optional[ + Union[ + goldengate_deployment_version.GetGoldengateDeploymentVersionRequest, + dict, + ] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> goldengate_deployment_version.GoldengateDeploymentVersion: + r"""Gets details of a single GoldengateDeploymentVersion. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + def sample_get_goldengate_deployment_version(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.GetGoldengateDeploymentVersionRequest( + name="name_value", + ) + + # Make the request + response = client.get_goldengate_deployment_version(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.oracledatabase_v1.types.GetGoldengateDeploymentVersionRequest, dict]): + The request object. Message for getting a + GoldengateDeploymentVersion. + name (str): + Required. The name of the GoldengateDeploymentVersion to + retrieve. Format: + projects/{project}/locations/{location}/goldengateDeploymentVersions/{goldengate_deployment_version} + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.types.GoldengateDeploymentVersion: + Details of the Goldengate Deployment + Version resource. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, goldengate_deployment_version.GetGoldengateDeploymentVersionRequest + ): + request = ( + goldengate_deployment_version.GetGoldengateDeploymentVersionRequest( + 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_goldengate_deployment_version + ] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_goldengate_deployment_versions( + self, + request: Optional[ + Union[ + goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest, + dict, + ] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListGoldengateDeploymentVersionsPager: + r"""Lists GoldengateDeploymentVersions in a given project + and location. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + def sample_list_goldengate_deployment_versions(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListGoldengateDeploymentVersionsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_goldengate_deployment_versions(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentVersionsRequest, dict]): + The request object. Message for listing + GoldengateDeploymentVersions. + parent (str): + Required. Parent value for + ListGoldengateDeploymentVersionsRequest + Format: + projects/{project}/locations/{location} + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGoldengateDeploymentVersionsPager: + Message for response to listing + GoldengateDeploymentVersions + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest, + ): + request = ( + goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest( + 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_goldengate_deployment_versions + ] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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.ListGoldengateDeploymentVersionsPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_goldengate_deployment_type( + self, + request: Optional[ + Union[goldengate_deployment_type.GetGoldengateDeploymentTypeRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> goldengate_deployment_type.GoldengateDeploymentType: + r"""Gets details of a single GoldenGateDeploymentType. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + def sample_get_goldengate_deployment_type(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.GetGoldengateDeploymentTypeRequest( + name="name_value", + ) + + # Make the request + response = client.get_goldengate_deployment_type(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.oracledatabase_v1.types.GetGoldengateDeploymentTypeRequest, dict]): + The request object. Message for getting a + GoldengateDeploymentType. + name (str): + Required. The name of the GoldengateDeploymentType to + retrieve. Format: + projects/{project}/locations/{location}/goldengateDeploymentTypes/{goldengate_deployment_type} + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.types.GoldengateDeploymentType: + Details of the Goldengate Deployment + Type resource. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, goldengate_deployment_type.GetGoldengateDeploymentTypeRequest + ): + request = goldengate_deployment_type.GetGoldengateDeploymentTypeRequest( + 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_goldengate_deployment_type + ] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_goldengate_deployment_types( + self, + request: Optional[ + Union[goldengate_deployment_type.ListGoldengateDeploymentTypesRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListGoldengateDeploymentTypesPager: + r"""Lists GoldenGateDeploymentTypes in a given project + and location. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + def sample_list_goldengate_deployment_types(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListGoldengateDeploymentTypesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_goldengate_deployment_types(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentTypesRequest, dict]): + The request object. Message for listing + GoldengateDeploymentTypes. + parent (str): + Required. The parent resource. + Format: + projects/{project}/locations/{location} + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGoldengateDeploymentTypesPager: + Message for response to listing + GoldengateDeploymentTypes + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, goldengate_deployment_type.ListGoldengateDeploymentTypesRequest + ): + request = goldengate_deployment_type.ListGoldengateDeploymentTypesRequest( + 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_goldengate_deployment_types + ] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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.ListGoldengateDeploymentTypesPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_goldengate_deployment_environment( + self, + request: Optional[ + Union[ + goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest, + dict, + ] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> goldengate_deployment_environment.GoldengateDeploymentEnvironment: + r"""Gets details of a single + GoldengateDeploymentEnvironment. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + def sample_get_goldengate_deployment_environment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.GetGoldengateDeploymentEnvironmentRequest( + name="name_value", + ) + + # Make the request + response = client.get_goldengate_deployment_environment(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.oracledatabase_v1.types.GetGoldengateDeploymentEnvironmentRequest, dict]): + The request object. Message for getting a + GoldengateDeploymentEnvironment. + name (str): + Required. Name of the resource with the format: + projects/{project}/locations/{location}/goldengateDeploymentEnvironments/{goldengate_deployment_environment} + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.types.GoldengateDeploymentEnvironment: + Details of the Goldengate Deployment + Environment resource. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest, + ): + request = goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest( + 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_goldengate_deployment_environment + ] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_goldengate_deployment_environments( + self, + request: Optional[ + Union[ + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest, + dict, + ] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListGoldengateDeploymentEnvironmentsPager: + r"""Lists GoldengateDeploymentEnvironments in a given + project and location. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + def sample_list_goldengate_deployment_environments(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListGoldengateDeploymentEnvironmentsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_goldengate_deployment_environments(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentEnvironmentsRequest, dict]): + The request object. Message for listing + GoldengateDeploymentEnvironments. + parent (str): + Required. The parent, which owns this + collection of + GoldengateDeploymentEnvironments. + Format: + + projects/{project}/locations/{location} + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGoldengateDeploymentEnvironmentsPager: + Message for response to listing + GoldengateDeploymentEnvironments + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest, + ): + request = goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest( + 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_goldengate_deployment_environments + ] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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.ListGoldengateDeploymentEnvironmentsPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_goldengate_connection_type( + self, + request: Optional[ + Union[goldengate_connection_type.GetGoldengateConnectionTypeRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> goldengate_connection_type.GoldengateConnectionType: + r"""Gets details of a single GoldengateConnectionType. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + def sample_get_goldengate_connection_type(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.GetGoldengateConnectionTypeRequest( + name="name_value", + ) + + # Make the request + response = client.get_goldengate_connection_type(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.oracledatabase_v1.types.GetGoldengateConnectionTypeRequest, dict]): + The request object. Message for getting a + GoldengateConnectionType. + name (str): + Required. Name of the resource in the format: + projects/{project}/locations/{location}/goldengateConnectionTypes/{goldengate_connection_type} + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.types.GoldengateConnectionType: + Details of the Goldengate Connection + Type resource. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, goldengate_connection_type.GetGoldengateConnectionTypeRequest + ): + request = goldengate_connection_type.GetGoldengateConnectionTypeRequest( + 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_goldengate_connection_type + ] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_goldengate_connection_types( + self, + request: Optional[ + Union[goldengate_connection_type.ListGoldengateConnectionTypesRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListGoldengateConnectionTypesPager: + r"""Lists GoldengateConnectionTypes in a given project + and location. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + def sample_list_goldengate_connection_types(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListGoldengateConnectionTypesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_goldengate_connection_types(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.oracledatabase_v1.types.ListGoldengateConnectionTypesRequest, dict]): + The request object. Message for listing + GoldengateConnectionTypes. + parent (str): + Required. Parent value for + ListGoldengateConnectionTypesRequest + Format: + projects/{project}/locations/{location} + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGoldengateConnectionTypesPager: + Message for response to listing + GoldengateConnectionTypes + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, goldengate_connection_type.ListGoldengateConnectionTypesRequest + ): + request = goldengate_connection_type.ListGoldengateConnectionTypesRequest( + 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_goldengate_connection_types + ] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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.ListGoldengateConnectionTypesPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_db_versions( + self, + request: Optional[Union[db_version.ListDbVersionsRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListDbVersionsPager: + r"""List DbVersions for the given project and location. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + def sample_list_db_versions(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListDbVersionsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_db_versions(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.oracledatabase_v1.types.ListDbVersionsRequest, dict]): + The request object. The request for ``DbVersions.List``. + parent (str): + Required. The parent value for the + DbVersion resource with the format: + projects/{project}/locations/{location} + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDbVersionsPager: + The response for DbVersions.List. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, db_version.ListDbVersionsRequest): + request = db_version.ListDbVersionsRequest(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_db_versions] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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.ListDbVersionsPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_database_character_sets( + self, + request: Optional[ + Union[database_character_set.ListDatabaseCharacterSetsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListDatabaseCharacterSetsPager: + r"""List DatabaseCharacterSets for the given project and + location. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + def sample_list_database_character_sets(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListDatabaseCharacterSetsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_database_character_sets(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.oracledatabase_v1.types.ListDatabaseCharacterSetsRequest, dict]): + The request object. The request for ``DatabaseCharacterSet.List``. + parent (str): + Required. The parent value for + DatabaseCharacterSets in the following + format: + projects/{project}/locations/{location}. + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDatabaseCharacterSetsPager: + The response for DatabaseCharacterSet.List. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, database_character_set.ListDatabaseCharacterSetsRequest + ): + request = database_character_set.ListDatabaseCharacterSetsRequest(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_database_character_sets + ] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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.ListDatabaseCharacterSetsPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_goldengate_connection_assignments( + self, + request: Optional[ + Union[ + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest, + dict, + ] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListGoldengateConnectionAssignmentsPager: + r"""Lists GoldengateConnectionAssignments in a given + project and location. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + def sample_list_goldengate_connection_assignments(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListGoldengateConnectionAssignmentsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_goldengate_connection_assignments(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.oracledatabase_v1.types.ListGoldengateConnectionAssignmentsRequest, dict]): + The request object. Request message for listing + GoldengateConnectionAssignments. + parent (str): + Required. The parent value for the + GoldengateConnectionAssignments. Format: + projects/{project}/locations/{location} + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGoldengateConnectionAssignmentsPager: + Response message for listing + GoldengateConnectionAssignments. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest, + ): + request = goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest( + 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_goldengate_connection_assignments + ] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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.ListGoldengateConnectionAssignmentsPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_goldengate_connection_assignment( + self, + request: Optional[ + Union[ + goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest, + dict, + ] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> goldengate_connection_assignment.GoldengateConnectionAssignment: + r"""Gets details of a single + GoldengateConnectionAssignment. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + def sample_get_goldengate_connection_assignment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.GetGoldengateConnectionAssignmentRequest( + name="name_value", + ) + + # Make the request + response = client.get_goldengate_connection_assignment(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.oracledatabase_v1.types.GetGoldengateConnectionAssignmentRequest, dict]): + The request object. Request message for getting a + GoldengateConnectionAssignment. + name (str): + Required. The name of the GoldengateConnectionAssignment + to retrieve. Format: + projects/{project}/locations/{location}/goldengateConnectionAssignments/{goldengate_connection_assignment} + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.types.GoldengateConnectionAssignment: + Represents the metadata of a + Goldengate Connection Assignment. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest, + ): + request = goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest( + 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_goldengate_connection_assignment + ] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def create_goldengate_connection_assignment( + self, + request: Optional[ + Union[ + gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest, + dict, + ] + ] = None, + *, + parent: Optional[str] = None, + goldengate_connection_assignment: Optional[ + gco_goldengate_connection_assignment.GoldengateConnectionAssignment + ] = None, + goldengate_connection_assignment_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Creates a new GoldengateConnectionAssignment in a + given project and location. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + def sample_create_goldengate_connection_assignment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + goldengate_connection_assignment = oracledatabase_v1.GoldengateConnectionAssignment() + goldengate_connection_assignment.properties.goldengate_connection = "goldengate_connection_value" + goldengate_connection_assignment.properties.goldengate_deployment = "goldengate_deployment_value" + + request = oracledatabase_v1.CreateGoldengateConnectionAssignmentRequest( + parent="parent_value", + goldengate_connection_assignment_id="goldengate_connection_assignment_id_value", + goldengate_connection_assignment=goldengate_connection_assignment, + ) + + # Make the request + operation = client.create_goldengate_connection_assignment(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.oracledatabase_v1.types.CreateGoldengateConnectionAssignmentRequest, dict]): + The request object. Request message for creating a + GoldengateConnectionAssignment. + parent (str): + Required. The parent resource where + this GoldengateConnectionAssignment will + be created. Format: + projects/{project}/locations/{location} + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + goldengate_connection_assignment (google.cloud.oracledatabase_v1.types.GoldengateConnectionAssignment): + Required. The + GoldengateConnectionAssignment to + create. + + This corresponds to the ``goldengate_connection_assignment`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + goldengate_connection_assignment_id (str): + Required. The ID of the + GoldengateConnectionAssignment to + create. + + This corresponds to the ``goldengate_connection_assignment_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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.oracledatabase_v1.types.GoldengateConnectionAssignment` + Represents the metadata of a Goldengate Connection + Assignment. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [ + parent, + goldengate_connection_assignment, + goldengate_connection_assignment_id, + ] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest, + ): + request = gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if goldengate_connection_assignment is not None: + request.goldengate_connection_assignment = ( + goldengate_connection_assignment + ) + if goldengate_connection_assignment_id is not None: + request.goldengate_connection_assignment_id = ( + goldengate_connection_assignment_id + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.create_goldengate_connection_assignment + ] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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, + gco_goldengate_connection_assignment.GoldengateConnectionAssignment, + metadata_type=oracledatabase.OperationMetadata, + ) + + # Done; return the response. + return response + + def delete_goldengate_connection_assignment( + self, + request: Optional[ + Union[ + goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest, + dict, + ] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Deletes a single GoldengateConnectionAssignment. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + def sample_delete_goldengate_connection_assignment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.DeleteGoldengateConnectionAssignmentRequest( + name="name_value", + ) + + # Make the request + operation = client.delete_goldengate_connection_assignment(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.oracledatabase_v1.types.DeleteGoldengateConnectionAssignmentRequest, dict]): + The request object. Request message for deleting a + GoldengateConnectionAssignment. + name (str): + Required. The name of the GoldengateConnectionAssignment + to delete. Format: + projects/{project}/locations/{location}/goldengateConnectionAssignments/{goldengate_connection_assignment} + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest, + ): + request = goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest( + 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_goldengate_connection_assignment + ] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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, + empty_pb2.Empty, + metadata_type=oracledatabase.OperationMetadata, + ) + + # Done; return the response. + return response + + def test_goldengate_connection_assignment( + self, + request: Optional[ + Union[ + goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest, + dict, + ] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse: + r"""Tests a single GoldengateConnectionAssignment. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import oracledatabase_v1 + + def sample_test_goldengate_connection_assignment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.TestGoldengateConnectionAssignmentRequest( + name="name_value", + ) + + # Make the request + response = client.test_goldengate_connection_assignment(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.oracledatabase_v1.types.TestGoldengateConnectionAssignmentRequest, dict]): + The request object. Request message for + TestGoldengateConnectionAssignment. + name (str): + Required. Name of the connection assignment for which to + test connection. + projects/{project}/locations/{region}/goldengateConnectionAssignments/{goldengate_connection_assignment} + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.oracledatabase_v1.types.TestGoldengateConnectionAssignmentResponse: + The result of the connectivity test + performed between the Goldengate + deployment and the associated database / + service. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest, + ): + request = goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest( + 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.test_goldengate_connection_assignment + ] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, diff --git a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/pagers.py b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/pagers.py index bc13e6203595..cc780af52233 100644 --- a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/pagers.py +++ b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/pagers.py @@ -56,6 +56,13 @@ exadb_vm_cluster, exascale_db_storage_vault, gi_version, + goldengate_connection, + goldengate_connection_assignment, + goldengate_connection_type, + goldengate_deployment, + goldengate_deployment_environment, + goldengate_deployment_type, + goldengate_deployment_version, minor_version, odb_network, odb_subnet, @@ -3265,6 +3272,1041 @@ def __repr__(self) -> str: return "{0}<{1!r}>".format(self.__class__.__name__, self._response) +class ListGoldengateDeploymentsPager: + """A pager for iterating through ``list_goldengate_deployments`` requests. + + This class thinly wraps an initial + :class:`google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``goldengate_deployments`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListGoldengateDeployments`` requests and continue to iterate + through the ``goldengate_deployments`` field on the + corresponding responses. + + All the usual :class:`google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentsResponse` + 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[..., goldengate_deployment.ListGoldengateDeploymentsResponse], + request: goldengate_deployment.ListGoldengateDeploymentsRequest, + response: goldengate_deployment.ListGoldengateDeploymentsResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentsRequest): + The initial request object. + response (google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentsResponse): + The initial response object. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = goldengate_deployment.ListGoldengateDeploymentsRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages( + self, + ) -> Iterator[goldengate_deployment.ListGoldengateDeploymentsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __iter__(self) -> Iterator[goldengate_deployment.GoldengateDeployment]: + for page in self.pages: + yield from page.goldengate_deployments + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListGoldengateDeploymentsAsyncPager: + """A pager for iterating through ``list_goldengate_deployments`` requests. + + This class thinly wraps an initial + :class:`google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``goldengate_deployments`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListGoldengateDeployments`` requests and continue to iterate + through the ``goldengate_deployments`` field on the + corresponding responses. + + All the usual :class:`google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentsResponse` + 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[goldengate_deployment.ListGoldengateDeploymentsResponse] + ], + request: goldengate_deployment.ListGoldengateDeploymentsRequest, + response: goldengate_deployment.ListGoldengateDeploymentsResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentsRequest): + The initial request object. + response (google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentsResponse): + The initial response object. + retry (google.api_core.retry.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = goldengate_deployment.ListGoldengateDeploymentsRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[goldengate_deployment.ListGoldengateDeploymentsResponse]: + 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, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __aiter__(self) -> AsyncIterator[goldengate_deployment.GoldengateDeployment]: + async def async_generator(): + async for page in self.pages: + for response in page.goldengate_deployments: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListGoldengateConnectionsPager: + """A pager for iterating through ``list_goldengate_connections`` requests. + + This class thinly wraps an initial + :class:`google.cloud.oracledatabase_v1.types.ListGoldengateConnectionsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``goldengate_connections`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListGoldengateConnections`` requests and continue to iterate + through the ``goldengate_connections`` field on the + corresponding responses. + + All the usual :class:`google.cloud.oracledatabase_v1.types.ListGoldengateConnectionsResponse` + 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[..., goldengate_connection.ListGoldengateConnectionsResponse], + request: goldengate_connection.ListGoldengateConnectionsRequest, + response: goldengate_connection.ListGoldengateConnectionsResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.oracledatabase_v1.types.ListGoldengateConnectionsRequest): + The initial request object. + response (google.cloud.oracledatabase_v1.types.ListGoldengateConnectionsResponse): + The initial response object. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = goldengate_connection.ListGoldengateConnectionsRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages( + self, + ) -> Iterator[goldengate_connection.ListGoldengateConnectionsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __iter__(self) -> Iterator[goldengate_connection.GoldengateConnection]: + for page in self.pages: + yield from page.goldengate_connections + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListGoldengateConnectionsAsyncPager: + """A pager for iterating through ``list_goldengate_connections`` requests. + + This class thinly wraps an initial + :class:`google.cloud.oracledatabase_v1.types.ListGoldengateConnectionsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``goldengate_connections`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListGoldengateConnections`` requests and continue to iterate + through the ``goldengate_connections`` field on the + corresponding responses. + + All the usual :class:`google.cloud.oracledatabase_v1.types.ListGoldengateConnectionsResponse` + 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[goldengate_connection.ListGoldengateConnectionsResponse] + ], + request: goldengate_connection.ListGoldengateConnectionsRequest, + response: goldengate_connection.ListGoldengateConnectionsResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.oracledatabase_v1.types.ListGoldengateConnectionsRequest): + The initial request object. + response (google.cloud.oracledatabase_v1.types.ListGoldengateConnectionsResponse): + The initial response object. + retry (google.api_core.retry.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = goldengate_connection.ListGoldengateConnectionsRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[goldengate_connection.ListGoldengateConnectionsResponse]: + 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, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __aiter__(self) -> AsyncIterator[goldengate_connection.GoldengateConnection]: + async def async_generator(): + async for page in self.pages: + for response in page.goldengate_connections: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListGoldengateDeploymentVersionsPager: + """A pager for iterating through ``list_goldengate_deployment_versions`` requests. + + This class thinly wraps an initial + :class:`google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentVersionsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``goldengate_deployment_versions`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListGoldengateDeploymentVersions`` requests and continue to iterate + through the ``goldengate_deployment_versions`` field on the + corresponding responses. + + All the usual :class:`google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentVersionsResponse` + 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[ + ..., goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse + ], + request: goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest, + response: goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentVersionsRequest): + The initial request object. + response (google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentVersionsResponse): + The initial response object. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = ( + goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest( + request + ) + ) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages( + self, + ) -> Iterator[ + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse + ]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __iter__( + self, + ) -> Iterator[goldengate_deployment_version.GoldengateDeploymentVersion]: + for page in self.pages: + yield from page.goldengate_deployment_versions + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListGoldengateDeploymentVersionsAsyncPager: + """A pager for iterating through ``list_goldengate_deployment_versions`` requests. + + This class thinly wraps an initial + :class:`google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentVersionsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``goldengate_deployment_versions`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListGoldengateDeploymentVersions`` requests and continue to iterate + through the ``goldengate_deployment_versions`` field on the + corresponding responses. + + All the usual :class:`google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentVersionsResponse` + 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[ + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse + ], + ], + request: goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest, + response: goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentVersionsRequest): + The initial request object. + response (google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentVersionsResponse): + The initial response object. + retry (google.api_core.retry.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = ( + goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest( + request + ) + ) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[ + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse + ]: + 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, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __aiter__( + self, + ) -> AsyncIterator[goldengate_deployment_version.GoldengateDeploymentVersion]: + async def async_generator(): + async for page in self.pages: + for response in page.goldengate_deployment_versions: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListGoldengateDeploymentTypesPager: + """A pager for iterating through ``list_goldengate_deployment_types`` requests. + + This class thinly wraps an initial + :class:`google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentTypesResponse` object, and + provides an ``__iter__`` method to iterate through its + ``goldengate_deployment_types`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListGoldengateDeploymentTypes`` requests and continue to iterate + through the ``goldengate_deployment_types`` field on the + corresponding responses. + + All the usual :class:`google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentTypesResponse` + 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[ + ..., goldengate_deployment_type.ListGoldengateDeploymentTypesResponse + ], + request: goldengate_deployment_type.ListGoldengateDeploymentTypesRequest, + response: goldengate_deployment_type.ListGoldengateDeploymentTypesResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentTypesRequest): + The initial request object. + response (google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentTypesResponse): + The initial response object. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = goldengate_deployment_type.ListGoldengateDeploymentTypesRequest( + request + ) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages( + self, + ) -> Iterator[goldengate_deployment_type.ListGoldengateDeploymentTypesResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __iter__(self) -> Iterator[goldengate_deployment_type.GoldengateDeploymentType]: + for page in self.pages: + yield from page.goldengate_deployment_types + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListGoldengateDeploymentTypesAsyncPager: + """A pager for iterating through ``list_goldengate_deployment_types`` requests. + + This class thinly wraps an initial + :class:`google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentTypesResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``goldengate_deployment_types`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListGoldengateDeploymentTypes`` requests and continue to iterate + through the ``goldengate_deployment_types`` field on the + corresponding responses. + + All the usual :class:`google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentTypesResponse` + 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[goldengate_deployment_type.ListGoldengateDeploymentTypesResponse], + ], + request: goldengate_deployment_type.ListGoldengateDeploymentTypesRequest, + response: goldengate_deployment_type.ListGoldengateDeploymentTypesResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentTypesRequest): + The initial request object. + response (google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentTypesResponse): + The initial response object. + retry (google.api_core.retry.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = goldengate_deployment_type.ListGoldengateDeploymentTypesRequest( + request + ) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[ + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse + ]: + 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, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __aiter__( + self, + ) -> AsyncIterator[goldengate_deployment_type.GoldengateDeploymentType]: + async def async_generator(): + async for page in self.pages: + for response in page.goldengate_deployment_types: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListGoldengateDeploymentEnvironmentsPager: + """A pager for iterating through ``list_goldengate_deployment_environments`` requests. + + This class thinly wraps an initial + :class:`google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentEnvironmentsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``goldengate_deployment_environments`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListGoldengateDeploymentEnvironments`` requests and continue to iterate + through the ``goldengate_deployment_environments`` field on the + corresponding responses. + + All the usual :class:`google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentEnvironmentsResponse` + 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[ + ..., + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse, + ], + request: goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest, + response: goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentEnvironmentsRequest): + The initial request object. + response (google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentEnvironmentsResponse): + The initial response object. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest( + request + ) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages( + self, + ) -> Iterator[ + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse + ]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __iter__( + self, + ) -> Iterator[goldengate_deployment_environment.GoldengateDeploymentEnvironment]: + for page in self.pages: + yield from page.goldengate_deployment_environments + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListGoldengateDeploymentEnvironmentsAsyncPager: + """A pager for iterating through ``list_goldengate_deployment_environments`` requests. + + This class thinly wraps an initial + :class:`google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentEnvironmentsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``goldengate_deployment_environments`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListGoldengateDeploymentEnvironments`` requests and continue to iterate + through the ``goldengate_deployment_environments`` field on the + corresponding responses. + + All the usual :class:`google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentEnvironmentsResponse` + 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[ + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse + ], + ], + request: goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest, + response: goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentEnvironmentsRequest): + The initial request object. + response (google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentEnvironmentsResponse): + The initial response object. + retry (google.api_core.retry.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest( + request + ) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[ + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse + ]: + 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, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __aiter__( + self, + ) -> AsyncIterator[ + goldengate_deployment_environment.GoldengateDeploymentEnvironment + ]: + async def async_generator(): + async for page in self.pages: + for response in page.goldengate_deployment_environments: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListGoldengateConnectionTypesPager: + """A pager for iterating through ``list_goldengate_connection_types`` requests. + + This class thinly wraps an initial + :class:`google.cloud.oracledatabase_v1.types.ListGoldengateConnectionTypesResponse` object, and + provides an ``__iter__`` method to iterate through its + ``goldengate_connection_types`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListGoldengateConnectionTypes`` requests and continue to iterate + through the ``goldengate_connection_types`` field on the + corresponding responses. + + All the usual :class:`google.cloud.oracledatabase_v1.types.ListGoldengateConnectionTypesResponse` + 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[ + ..., goldengate_connection_type.ListGoldengateConnectionTypesResponse + ], + request: goldengate_connection_type.ListGoldengateConnectionTypesRequest, + response: goldengate_connection_type.ListGoldengateConnectionTypesResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.oracledatabase_v1.types.ListGoldengateConnectionTypesRequest): + The initial request object. + response (google.cloud.oracledatabase_v1.types.ListGoldengateConnectionTypesResponse): + The initial response object. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = goldengate_connection_type.ListGoldengateConnectionTypesRequest( + request + ) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages( + self, + ) -> Iterator[goldengate_connection_type.ListGoldengateConnectionTypesResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __iter__(self) -> Iterator[goldengate_connection_type.GoldengateConnectionType]: + for page in self.pages: + yield from page.goldengate_connection_types + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListGoldengateConnectionTypesAsyncPager: + """A pager for iterating through ``list_goldengate_connection_types`` requests. + + This class thinly wraps an initial + :class:`google.cloud.oracledatabase_v1.types.ListGoldengateConnectionTypesResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``goldengate_connection_types`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListGoldengateConnectionTypes`` requests and continue to iterate + through the ``goldengate_connection_types`` field on the + corresponding responses. + + All the usual :class:`google.cloud.oracledatabase_v1.types.ListGoldengateConnectionTypesResponse` + 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[goldengate_connection_type.ListGoldengateConnectionTypesResponse], + ], + request: goldengate_connection_type.ListGoldengateConnectionTypesRequest, + response: goldengate_connection_type.ListGoldengateConnectionTypesResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.oracledatabase_v1.types.ListGoldengateConnectionTypesRequest): + The initial request object. + response (google.cloud.oracledatabase_v1.types.ListGoldengateConnectionTypesResponse): + The initial response object. + retry (google.api_core.retry.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = goldengate_connection_type.ListGoldengateConnectionTypesRequest( + request + ) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[ + goldengate_connection_type.ListGoldengateConnectionTypesResponse + ]: + 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, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __aiter__( + self, + ) -> AsyncIterator[goldengate_connection_type.GoldengateConnectionType]: + async def async_generator(): + async for page in self.pages: + for response in page.goldengate_connection_types: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + class ListDbVersionsPager: """A pager for iterating through ``list_db_versions`` requests. @@ -3581,3 +4623,187 @@ async def async_generator(): def __repr__(self) -> str: return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListGoldengateConnectionAssignmentsPager: + """A pager for iterating through ``list_goldengate_connection_assignments`` requests. + + This class thinly wraps an initial + :class:`google.cloud.oracledatabase_v1.types.ListGoldengateConnectionAssignmentsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``goldengate_connection_assignments`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListGoldengateConnectionAssignments`` requests and continue to iterate + through the ``goldengate_connection_assignments`` field on the + corresponding responses. + + All the usual :class:`google.cloud.oracledatabase_v1.types.ListGoldengateConnectionAssignmentsResponse` + 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[ + ..., + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse, + ], + request: goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest, + response: goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.oracledatabase_v1.types.ListGoldengateConnectionAssignmentsRequest): + The initial request object. + response (google.cloud.oracledatabase_v1.types.ListGoldengateConnectionAssignmentsResponse): + The initial response object. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = ( + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest( + request + ) + ) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages( + self, + ) -> Iterator[ + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse + ]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __iter__( + self, + ) -> Iterator[goldengate_connection_assignment.GoldengateConnectionAssignment]: + for page in self.pages: + yield from page.goldengate_connection_assignments + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListGoldengateConnectionAssignmentsAsyncPager: + """A pager for iterating through ``list_goldengate_connection_assignments`` requests. + + This class thinly wraps an initial + :class:`google.cloud.oracledatabase_v1.types.ListGoldengateConnectionAssignmentsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``goldengate_connection_assignments`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListGoldengateConnectionAssignments`` requests and continue to iterate + through the ``goldengate_connection_assignments`` field on the + corresponding responses. + + All the usual :class:`google.cloud.oracledatabase_v1.types.ListGoldengateConnectionAssignmentsResponse` + 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[ + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse + ], + ], + request: goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest, + response: goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.oracledatabase_v1.types.ListGoldengateConnectionAssignmentsRequest): + The initial request object. + response (google.cloud.oracledatabase_v1.types.ListGoldengateConnectionAssignmentsResponse): + The initial response object. + retry (google.api_core.retry.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = ( + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest( + request + ) + ) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[ + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse + ]: + 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, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __aiter__( + self, + ) -> AsyncIterator[goldengate_connection_assignment.GoldengateConnectionAssignment]: + async def async_generator(): + async for page in self.pages: + for response in page.goldengate_connection_assignments: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/transports/base.py b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/transports/base.py index c4cedff908e5..db62bd8f855e 100644 --- a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/transports/base.py +++ b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/transports/base.py @@ -38,6 +38,13 @@ exadata_infra, exadb_vm_cluster, exascale_db_storage_vault, + goldengate_connection, + goldengate_connection_assignment, + goldengate_connection_type, + goldengate_deployment, + goldengate_deployment_environment, + goldengate_deployment_type, + goldengate_deployment_version, minor_version, odb_network, odb_subnet, @@ -49,6 +56,15 @@ from google.cloud.oracledatabase_v1.types import ( exascale_db_storage_vault as gco_exascale_db_storage_vault, ) +from google.cloud.oracledatabase_v1.types import ( + goldengate_connection as gco_goldengate_connection, +) +from google.cloud.oracledatabase_v1.types import ( + goldengate_connection_assignment as gco_goldengate_connection_assignment, +) +from google.cloud.oracledatabase_v1.types import ( + goldengate_deployment as gco_goldengate_deployment, +) from google.cloud.oracledatabase_v1.types import odb_network as gco_odb_network from google.cloud.oracledatabase_v1.types import odb_subnet as gco_odb_subnet @@ -746,6 +762,176 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.list_goldengate_deployments: gapic_v1.method.wrap_method( + self.list_goldengate_deployments, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.get_goldengate_deployment: gapic_v1.method.wrap_method( + self.get_goldengate_deployment, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.create_goldengate_deployment: gapic_v1.method.wrap_method( + self.create_goldengate_deployment, + default_timeout=None, + client_info=client_info, + ), + self.delete_goldengate_deployment: gapic_v1.method.wrap_method( + self.delete_goldengate_deployment, + default_timeout=None, + client_info=client_info, + ), + self.stop_goldengate_deployment: gapic_v1.method.wrap_method( + self.stop_goldengate_deployment, + default_timeout=None, + client_info=client_info, + ), + self.start_goldengate_deployment: gapic_v1.method.wrap_method( + self.start_goldengate_deployment, + default_timeout=None, + client_info=client_info, + ), + self.list_goldengate_connections: gapic_v1.method.wrap_method( + self.list_goldengate_connections, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.get_goldengate_connection: gapic_v1.method.wrap_method( + self.get_goldengate_connection, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.create_goldengate_connection: gapic_v1.method.wrap_method( + self.create_goldengate_connection, + default_timeout=None, + client_info=client_info, + ), + self.delete_goldengate_connection: gapic_v1.method.wrap_method( + self.delete_goldengate_connection, + default_timeout=None, + client_info=client_info, + ), + self.get_goldengate_deployment_version: gapic_v1.method.wrap_method( + self.get_goldengate_deployment_version, + default_timeout=None, + client_info=client_info, + ), + self.list_goldengate_deployment_versions: gapic_v1.method.wrap_method( + self.list_goldengate_deployment_versions, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.get_goldengate_deployment_type: gapic_v1.method.wrap_method( + self.get_goldengate_deployment_type, + default_timeout=None, + client_info=client_info, + ), + self.list_goldengate_deployment_types: gapic_v1.method.wrap_method( + self.list_goldengate_deployment_types, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.get_goldengate_deployment_environment: gapic_v1.method.wrap_method( + self.get_goldengate_deployment_environment, + default_timeout=None, + client_info=client_info, + ), + self.list_goldengate_deployment_environments: gapic_v1.method.wrap_method( + self.list_goldengate_deployment_environments, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.get_goldengate_connection_type: gapic_v1.method.wrap_method( + self.get_goldengate_connection_type, + default_timeout=None, + client_info=client_info, + ), + self.list_goldengate_connection_types: gapic_v1.method.wrap_method( + self.list_goldengate_connection_types, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), self.list_db_versions: gapic_v1.method.wrap_method( self.list_db_versions, default_retry=retries.Retry( @@ -776,6 +962,51 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), + self.list_goldengate_connection_assignments: gapic_v1.method.wrap_method( + self.list_goldengate_connection_assignments, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.get_goldengate_connection_assignment: gapic_v1.method.wrap_method( + self.get_goldengate_connection_assignment, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.create_goldengate_connection_assignment: gapic_v1.method.wrap_method( + self.create_goldengate_connection_assignment, + default_timeout=None, + client_info=client_info, + ), + self.delete_goldengate_connection_assignment: gapic_v1.method.wrap_method( + self.delete_goldengate_connection_assignment, + default_timeout=None, + client_info=client_info, + ), + self.test_goldengate_connection_assignment: gapic_v1.method.wrap_method( + self.test_goldengate_connection_assignment, + default_timeout=None, + client_info=client_info, + ), self.get_location: gapic_v1.method.wrap_method( self.get_location, default_timeout=None, @@ -1403,6 +1634,210 @@ def delete_db_system( ]: raise NotImplementedError() + @property + def list_goldengate_deployments( + self, + ) -> Callable[ + [goldengate_deployment.ListGoldengateDeploymentsRequest], + Union[ + goldengate_deployment.ListGoldengateDeploymentsResponse, + Awaitable[goldengate_deployment.ListGoldengateDeploymentsResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_goldengate_deployment( + self, + ) -> Callable[ + [goldengate_deployment.GetGoldengateDeploymentRequest], + Union[ + goldengate_deployment.GoldengateDeployment, + Awaitable[goldengate_deployment.GoldengateDeployment], + ], + ]: + raise NotImplementedError() + + @property + def create_goldengate_deployment( + self, + ) -> Callable[ + [gco_goldengate_deployment.CreateGoldengateDeploymentRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def delete_goldengate_deployment( + self, + ) -> Callable[ + [goldengate_deployment.DeleteGoldengateDeploymentRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def stop_goldengate_deployment( + self, + ) -> Callable[ + [goldengate_deployment.StopGoldengateDeploymentRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def start_goldengate_deployment( + self, + ) -> Callable[ + [goldengate_deployment.StartGoldengateDeploymentRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def list_goldengate_connections( + self, + ) -> Callable[ + [goldengate_connection.ListGoldengateConnectionsRequest], + Union[ + goldengate_connection.ListGoldengateConnectionsResponse, + Awaitable[goldengate_connection.ListGoldengateConnectionsResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_goldengate_connection( + self, + ) -> Callable[ + [goldengate_connection.GetGoldengateConnectionRequest], + Union[ + goldengate_connection.GoldengateConnection, + Awaitable[goldengate_connection.GoldengateConnection], + ], + ]: + raise NotImplementedError() + + @property + def create_goldengate_connection( + self, + ) -> Callable[ + [gco_goldengate_connection.CreateGoldengateConnectionRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def delete_goldengate_connection( + self, + ) -> Callable[ + [goldengate_connection.DeleteGoldengateConnectionRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def get_goldengate_deployment_version( + self, + ) -> Callable[ + [goldengate_deployment_version.GetGoldengateDeploymentVersionRequest], + Union[ + goldengate_deployment_version.GoldengateDeploymentVersion, + Awaitable[goldengate_deployment_version.GoldengateDeploymentVersion], + ], + ]: + raise NotImplementedError() + + @property + def list_goldengate_deployment_versions( + self, + ) -> Callable[ + [goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest], + Union[ + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse, + Awaitable[ + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def get_goldengate_deployment_type( + self, + ) -> Callable[ + [goldengate_deployment_type.GetGoldengateDeploymentTypeRequest], + Union[ + goldengate_deployment_type.GoldengateDeploymentType, + Awaitable[goldengate_deployment_type.GoldengateDeploymentType], + ], + ]: + raise NotImplementedError() + + @property + def list_goldengate_deployment_types( + self, + ) -> Callable[ + [goldengate_deployment_type.ListGoldengateDeploymentTypesRequest], + Union[ + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse, + Awaitable[goldengate_deployment_type.ListGoldengateDeploymentTypesResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_goldengate_deployment_environment( + self, + ) -> Callable[ + [goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest], + Union[ + goldengate_deployment_environment.GoldengateDeploymentEnvironment, + Awaitable[ + goldengate_deployment_environment.GoldengateDeploymentEnvironment + ], + ], + ]: + raise NotImplementedError() + + @property + def list_goldengate_deployment_environments( + self, + ) -> Callable[ + [goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest], + Union[ + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse, + Awaitable[ + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def get_goldengate_connection_type( + self, + ) -> Callable[ + [goldengate_connection_type.GetGoldengateConnectionTypeRequest], + Union[ + goldengate_connection_type.GoldengateConnectionType, + Awaitable[goldengate_connection_type.GoldengateConnectionType], + ], + ]: + raise NotImplementedError() + + @property + def list_goldengate_connection_types( + self, + ) -> Callable[ + [goldengate_connection_type.ListGoldengateConnectionTypesRequest], + Union[ + goldengate_connection_type.ListGoldengateConnectionTypesResponse, + Awaitable[goldengate_connection_type.ListGoldengateConnectionTypesResponse], + ], + ]: + raise NotImplementedError() + @property def list_db_versions( self, @@ -1427,6 +1862,66 @@ def list_database_character_sets( ]: raise NotImplementedError() + @property + def list_goldengate_connection_assignments( + self, + ) -> Callable[ + [goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest], + Union[ + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse, + Awaitable[ + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def get_goldengate_connection_assignment( + self, + ) -> Callable[ + [goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest], + Union[ + goldengate_connection_assignment.GoldengateConnectionAssignment, + Awaitable[goldengate_connection_assignment.GoldengateConnectionAssignment], + ], + ]: + raise NotImplementedError() + + @property + def create_goldengate_connection_assignment( + self, + ) -> Callable[ + [ + gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest + ], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def delete_goldengate_connection_assignment( + self, + ) -> Callable[ + [goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def test_goldengate_connection_assignment( + self, + ) -> Callable[ + [goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest], + Union[ + goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse, + Awaitable[ + goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse + ], + ], + ]: + raise NotImplementedError() + @property def list_operations( self, diff --git a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/transports/grpc.py b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/transports/grpc.py index 1186dcdd8e89..2432898a7eb2 100644 --- a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/transports/grpc.py +++ b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/transports/grpc.py @@ -40,6 +40,13 @@ exadata_infra, exadb_vm_cluster, exascale_db_storage_vault, + goldengate_connection, + goldengate_connection_assignment, + goldengate_connection_type, + goldengate_deployment, + goldengate_deployment_environment, + goldengate_deployment_type, + goldengate_deployment_version, minor_version, odb_network, odb_subnet, @@ -51,6 +58,15 @@ from google.cloud.oracledatabase_v1.types import ( exascale_db_storage_vault as gco_exascale_db_storage_vault, ) +from google.cloud.oracledatabase_v1.types import ( + goldengate_connection as gco_goldengate_connection, +) +from google.cloud.oracledatabase_v1.types import ( + goldengate_connection_assignment as gco_goldengate_connection_assignment, +) +from google.cloud.oracledatabase_v1.types import ( + goldengate_deployment as gco_goldengate_deployment, +) from google.cloud.oracledatabase_v1.types import odb_network as gco_odb_network from google.cloud.oracledatabase_v1.types import odb_subnet as gco_odb_subnet @@ -2013,6 +2029,575 @@ def delete_db_system( ) return self._stubs["delete_db_system"] + @property + def list_goldengate_deployments( + self, + ) -> Callable[ + [goldengate_deployment.ListGoldengateDeploymentsRequest], + goldengate_deployment.ListGoldengateDeploymentsResponse, + ]: + r"""Return a callable for the list goldengate deployments method over gRPC. + + Lists all the GoldengateDeployments for the given + project and location. + + Returns: + Callable[[~.ListGoldengateDeploymentsRequest], + ~.ListGoldengateDeploymentsResponse]: + 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_goldengate_deployments" not in self._stubs: + self._stubs["list_goldengate_deployments"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/ListGoldengateDeployments", + request_serializer=goldengate_deployment.ListGoldengateDeploymentsRequest.serialize, + response_deserializer=goldengate_deployment.ListGoldengateDeploymentsResponse.deserialize, + ) + ) + return self._stubs["list_goldengate_deployments"] + + @property + def get_goldengate_deployment( + self, + ) -> Callable[ + [goldengate_deployment.GetGoldengateDeploymentRequest], + goldengate_deployment.GoldengateDeployment, + ]: + r"""Return a callable for the get goldengate deployment method over gRPC. + + Gets details of a single GoldengateDeployment. + + Returns: + Callable[[~.GetGoldengateDeploymentRequest], + ~.GoldengateDeployment]: + 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_goldengate_deployment" not in self._stubs: + self._stubs["get_goldengate_deployment"] = self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/GetGoldengateDeployment", + request_serializer=goldengate_deployment.GetGoldengateDeploymentRequest.serialize, + response_deserializer=goldengate_deployment.GoldengateDeployment.deserialize, + ) + return self._stubs["get_goldengate_deployment"] + + @property + def create_goldengate_deployment( + self, + ) -> Callable[ + [gco_goldengate_deployment.CreateGoldengateDeploymentRequest], + operations_pb2.Operation, + ]: + r"""Return a callable for the create goldengate deployment method over gRPC. + + Creates a new GoldengateDeployment in a given project + and location. + + Returns: + Callable[[~.CreateGoldengateDeploymentRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_goldengate_deployment" not in self._stubs: + self._stubs["create_goldengate_deployment"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/CreateGoldengateDeployment", + request_serializer=gco_goldengate_deployment.CreateGoldengateDeploymentRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + ) + return self._stubs["create_goldengate_deployment"] + + @property + def delete_goldengate_deployment( + self, + ) -> Callable[ + [goldengate_deployment.DeleteGoldengateDeploymentRequest], + operations_pb2.Operation, + ]: + r"""Return a callable for the delete goldengate deployment method over gRPC. + + Deletes a single GoldengateDeployment. + + Returns: + Callable[[~.DeleteGoldengateDeploymentRequest], + ~.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 "delete_goldengate_deployment" not in self._stubs: + self._stubs["delete_goldengate_deployment"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/DeleteGoldengateDeployment", + request_serializer=goldengate_deployment.DeleteGoldengateDeploymentRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + ) + return self._stubs["delete_goldengate_deployment"] + + @property + def stop_goldengate_deployment( + self, + ) -> Callable[ + [goldengate_deployment.StopGoldengateDeploymentRequest], + operations_pb2.Operation, + ]: + r"""Return a callable for the stop goldengate deployment method over gRPC. + + Stops a single GoldengateDeployment. + + Returns: + Callable[[~.StopGoldengateDeploymentRequest], + ~.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 "stop_goldengate_deployment" not in self._stubs: + self._stubs["stop_goldengate_deployment"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/StopGoldengateDeployment", + request_serializer=goldengate_deployment.StopGoldengateDeploymentRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + ) + return self._stubs["stop_goldengate_deployment"] + + @property + def start_goldengate_deployment( + self, + ) -> Callable[ + [goldengate_deployment.StartGoldengateDeploymentRequest], + operations_pb2.Operation, + ]: + r"""Return a callable for the start goldengate deployment method over gRPC. + + Starts a single GoldengateDeployment. + + Returns: + Callable[[~.StartGoldengateDeploymentRequest], + ~.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 "start_goldengate_deployment" not in self._stubs: + self._stubs["start_goldengate_deployment"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/StartGoldengateDeployment", + request_serializer=goldengate_deployment.StartGoldengateDeploymentRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + ) + return self._stubs["start_goldengate_deployment"] + + @property + def list_goldengate_connections( + self, + ) -> Callable[ + [goldengate_connection.ListGoldengateConnectionsRequest], + goldengate_connection.ListGoldengateConnectionsResponse, + ]: + r"""Return a callable for the list goldengate connections method over gRPC. + + Lists all the GoldengateConnections for the given + project and location. + + Returns: + Callable[[~.ListGoldengateConnectionsRequest], + ~.ListGoldengateConnectionsResponse]: + 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_goldengate_connections" not in self._stubs: + self._stubs["list_goldengate_connections"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/ListGoldengateConnections", + request_serializer=goldengate_connection.ListGoldengateConnectionsRequest.serialize, + response_deserializer=goldengate_connection.ListGoldengateConnectionsResponse.deserialize, + ) + ) + return self._stubs["list_goldengate_connections"] + + @property + def get_goldengate_connection( + self, + ) -> Callable[ + [goldengate_connection.GetGoldengateConnectionRequest], + goldengate_connection.GoldengateConnection, + ]: + r"""Return a callable for the get goldengate connection method over gRPC. + + Gets details of a single GoldengateConnection. + + Returns: + Callable[[~.GetGoldengateConnectionRequest], + ~.GoldengateConnection]: + 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_goldengate_connection" not in self._stubs: + self._stubs["get_goldengate_connection"] = self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/GetGoldengateConnection", + request_serializer=goldengate_connection.GetGoldengateConnectionRequest.serialize, + response_deserializer=goldengate_connection.GoldengateConnection.deserialize, + ) + return self._stubs["get_goldengate_connection"] + + @property + def create_goldengate_connection( + self, + ) -> Callable[ + [gco_goldengate_connection.CreateGoldengateConnectionRequest], + operations_pb2.Operation, + ]: + r"""Return a callable for the create goldengate connection method over gRPC. + + Creates a new GoldengateConnection in a given project + and location. + + Returns: + Callable[[~.CreateGoldengateConnectionRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_goldengate_connection" not in self._stubs: + self._stubs["create_goldengate_connection"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/CreateGoldengateConnection", + request_serializer=gco_goldengate_connection.CreateGoldengateConnectionRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + ) + return self._stubs["create_goldengate_connection"] + + @property + def delete_goldengate_connection( + self, + ) -> Callable[ + [goldengate_connection.DeleteGoldengateConnectionRequest], + operations_pb2.Operation, + ]: + r"""Return a callable for the delete goldengate connection method over gRPC. + + Deletes a single GoldengateConnection. + + Returns: + Callable[[~.DeleteGoldengateConnectionRequest], + ~.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 "delete_goldengate_connection" not in self._stubs: + self._stubs["delete_goldengate_connection"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/DeleteGoldengateConnection", + request_serializer=goldengate_connection.DeleteGoldengateConnectionRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + ) + return self._stubs["delete_goldengate_connection"] + + @property + def get_goldengate_deployment_version( + self, + ) -> Callable[ + [goldengate_deployment_version.GetGoldengateDeploymentVersionRequest], + goldengate_deployment_version.GoldengateDeploymentVersion, + ]: + r"""Return a callable for the get goldengate deployment + version method over gRPC. + + Gets details of a single GoldengateDeploymentVersion. + + Returns: + Callable[[~.GetGoldengateDeploymentVersionRequest], + ~.GoldengateDeploymentVersion]: + 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_goldengate_deployment_version" not in self._stubs: + self._stubs["get_goldengate_deployment_version"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/GetGoldengateDeploymentVersion", + request_serializer=goldengate_deployment_version.GetGoldengateDeploymentVersionRequest.serialize, + response_deserializer=goldengate_deployment_version.GoldengateDeploymentVersion.deserialize, + ) + ) + return self._stubs["get_goldengate_deployment_version"] + + @property + def list_goldengate_deployment_versions( + self, + ) -> Callable[ + [goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest], + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse, + ]: + r"""Return a callable for the list goldengate deployment + versions method over gRPC. + + Lists GoldengateDeploymentVersions in a given project + and location. + + Returns: + Callable[[~.ListGoldengateDeploymentVersionsRequest], + ~.ListGoldengateDeploymentVersionsResponse]: + 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_goldengate_deployment_versions" not in self._stubs: + self._stubs["list_goldengate_deployment_versions"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/ListGoldengateDeploymentVersions", + request_serializer=goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest.serialize, + response_deserializer=goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse.deserialize, + ) + ) + return self._stubs["list_goldengate_deployment_versions"] + + @property + def get_goldengate_deployment_type( + self, + ) -> Callable[ + [goldengate_deployment_type.GetGoldengateDeploymentTypeRequest], + goldengate_deployment_type.GoldengateDeploymentType, + ]: + r"""Return a callable for the get goldengate deployment type method over gRPC. + + Gets details of a single GoldenGateDeploymentType. + + Returns: + Callable[[~.GetGoldengateDeploymentTypeRequest], + ~.GoldengateDeploymentType]: + 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_goldengate_deployment_type" not in self._stubs: + self._stubs["get_goldengate_deployment_type"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/GetGoldengateDeploymentType", + request_serializer=goldengate_deployment_type.GetGoldengateDeploymentTypeRequest.serialize, + response_deserializer=goldengate_deployment_type.GoldengateDeploymentType.deserialize, + ) + ) + return self._stubs["get_goldengate_deployment_type"] + + @property + def list_goldengate_deployment_types( + self, + ) -> Callable[ + [goldengate_deployment_type.ListGoldengateDeploymentTypesRequest], + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse, + ]: + r"""Return a callable for the list goldengate deployment + types method over gRPC. + + Lists GoldenGateDeploymentTypes in a given project + and location. + + Returns: + Callable[[~.ListGoldengateDeploymentTypesRequest], + ~.ListGoldengateDeploymentTypesResponse]: + 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_goldengate_deployment_types" not in self._stubs: + self._stubs["list_goldengate_deployment_types"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/ListGoldengateDeploymentTypes", + request_serializer=goldengate_deployment_type.ListGoldengateDeploymentTypesRequest.serialize, + response_deserializer=goldengate_deployment_type.ListGoldengateDeploymentTypesResponse.deserialize, + ) + ) + return self._stubs["list_goldengate_deployment_types"] + + @property + def get_goldengate_deployment_environment( + self, + ) -> Callable[ + [goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest], + goldengate_deployment_environment.GoldengateDeploymentEnvironment, + ]: + r"""Return a callable for the get goldengate deployment + environment method over gRPC. + + Gets details of a single + GoldengateDeploymentEnvironment. + + Returns: + Callable[[~.GetGoldengateDeploymentEnvironmentRequest], + ~.GoldengateDeploymentEnvironment]: + 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_goldengate_deployment_environment" not in self._stubs: + self._stubs["get_goldengate_deployment_environment"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/GetGoldengateDeploymentEnvironment", + request_serializer=goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest.serialize, + response_deserializer=goldengate_deployment_environment.GoldengateDeploymentEnvironment.deserialize, + ) + ) + return self._stubs["get_goldengate_deployment_environment"] + + @property + def list_goldengate_deployment_environments( + self, + ) -> Callable[ + [goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest], + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse, + ]: + r"""Return a callable for the list goldengate deployment + environments method over gRPC. + + Lists GoldengateDeploymentEnvironments in a given + project and location. + + Returns: + Callable[[~.ListGoldengateDeploymentEnvironmentsRequest], + ~.ListGoldengateDeploymentEnvironmentsResponse]: + 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_goldengate_deployment_environments" not in self._stubs: + self._stubs["list_goldengate_deployment_environments"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/ListGoldengateDeploymentEnvironments", + request_serializer=goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest.serialize, + response_deserializer=goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse.deserialize, + ) + ) + return self._stubs["list_goldengate_deployment_environments"] + + @property + def get_goldengate_connection_type( + self, + ) -> Callable[ + [goldengate_connection_type.GetGoldengateConnectionTypeRequest], + goldengate_connection_type.GoldengateConnectionType, + ]: + r"""Return a callable for the get goldengate connection type method over gRPC. + + Gets details of a single GoldengateConnectionType. + + Returns: + Callable[[~.GetGoldengateConnectionTypeRequest], + ~.GoldengateConnectionType]: + 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_goldengate_connection_type" not in self._stubs: + self._stubs["get_goldengate_connection_type"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/GetGoldengateConnectionType", + request_serializer=goldengate_connection_type.GetGoldengateConnectionTypeRequest.serialize, + response_deserializer=goldengate_connection_type.GoldengateConnectionType.deserialize, + ) + ) + return self._stubs["get_goldengate_connection_type"] + + @property + def list_goldengate_connection_types( + self, + ) -> Callable[ + [goldengate_connection_type.ListGoldengateConnectionTypesRequest], + goldengate_connection_type.ListGoldengateConnectionTypesResponse, + ]: + r"""Return a callable for the list goldengate connection + types method over gRPC. + + Lists GoldengateConnectionTypes in a given project + and location. + + Returns: + Callable[[~.ListGoldengateConnectionTypesRequest], + ~.ListGoldengateConnectionTypesResponse]: + 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_goldengate_connection_types" not in self._stubs: + self._stubs["list_goldengate_connection_types"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/ListGoldengateConnectionTypes", + request_serializer=goldengate_connection_type.ListGoldengateConnectionTypesRequest.serialize, + response_deserializer=goldengate_connection_type.ListGoldengateConnectionTypesResponse.deserialize, + ) + ) + return self._stubs["list_goldengate_connection_types"] + @property def list_db_versions( self, @@ -2073,6 +2658,171 @@ def list_database_character_sets( ) return self._stubs["list_database_character_sets"] + @property + def list_goldengate_connection_assignments( + self, + ) -> Callable[ + [goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest], + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse, + ]: + r"""Return a callable for the list goldengate connection + assignments method over gRPC. + + Lists GoldengateConnectionAssignments in a given + project and location. + + Returns: + Callable[[~.ListGoldengateConnectionAssignmentsRequest], + ~.ListGoldengateConnectionAssignmentsResponse]: + 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_goldengate_connection_assignments" not in self._stubs: + self._stubs["list_goldengate_connection_assignments"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/ListGoldengateConnectionAssignments", + request_serializer=goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest.serialize, + response_deserializer=goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse.deserialize, + ) + ) + return self._stubs["list_goldengate_connection_assignments"] + + @property + def get_goldengate_connection_assignment( + self, + ) -> Callable[ + [goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest], + goldengate_connection_assignment.GoldengateConnectionAssignment, + ]: + r"""Return a callable for the get goldengate connection + assignment method over gRPC. + + Gets details of a single + GoldengateConnectionAssignment. + + Returns: + Callable[[~.GetGoldengateConnectionAssignmentRequest], + ~.GoldengateConnectionAssignment]: + 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_goldengate_connection_assignment" not in self._stubs: + self._stubs["get_goldengate_connection_assignment"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/GetGoldengateConnectionAssignment", + request_serializer=goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest.serialize, + response_deserializer=goldengate_connection_assignment.GoldengateConnectionAssignment.deserialize, + ) + ) + return self._stubs["get_goldengate_connection_assignment"] + + @property + def create_goldengate_connection_assignment( + self, + ) -> Callable[ + [ + gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest + ], + operations_pb2.Operation, + ]: + r"""Return a callable for the create goldengate connection + assignment method over gRPC. + + Creates a new GoldengateConnectionAssignment in a + given project and location. + + Returns: + Callable[[~.CreateGoldengateConnectionAssignmentRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_goldengate_connection_assignment" not in self._stubs: + self._stubs["create_goldengate_connection_assignment"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/CreateGoldengateConnectionAssignment", + request_serializer=gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + ) + return self._stubs["create_goldengate_connection_assignment"] + + @property + def delete_goldengate_connection_assignment( + self, + ) -> Callable[ + [goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest], + operations_pb2.Operation, + ]: + r"""Return a callable for the delete goldengate connection + assignment method over gRPC. + + Deletes a single GoldengateConnectionAssignment. + + Returns: + Callable[[~.DeleteGoldengateConnectionAssignmentRequest], + ~.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 "delete_goldengate_connection_assignment" not in self._stubs: + self._stubs["delete_goldengate_connection_assignment"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/DeleteGoldengateConnectionAssignment", + request_serializer=goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + ) + return self._stubs["delete_goldengate_connection_assignment"] + + @property + def test_goldengate_connection_assignment( + self, + ) -> Callable[ + [goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest], + goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse, + ]: + r"""Return a callable for the test goldengate connection + assignment method over gRPC. + + Tests a single GoldengateConnectionAssignment. + + Returns: + Callable[[~.TestGoldengateConnectionAssignmentRequest], + ~.TestGoldengateConnectionAssignmentResponse]: + 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 "test_goldengate_connection_assignment" not in self._stubs: + self._stubs["test_goldengate_connection_assignment"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/TestGoldengateConnectionAssignment", + request_serializer=goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest.serialize, + response_deserializer=goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse.deserialize, + ) + ) + return self._stubs["test_goldengate_connection_assignment"] + def close(self): self._logged_channel.close() diff --git a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/transports/grpc_asyncio.py b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/transports/grpc_asyncio.py index c035b1aece4e..7c8aa556ea65 100644 --- a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/transports/grpc_asyncio.py +++ b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/transports/grpc_asyncio.py @@ -43,6 +43,13 @@ exadata_infra, exadb_vm_cluster, exascale_db_storage_vault, + goldengate_connection, + goldengate_connection_assignment, + goldengate_connection_type, + goldengate_deployment, + goldengate_deployment_environment, + goldengate_deployment_type, + goldengate_deployment_version, minor_version, odb_network, odb_subnet, @@ -54,6 +61,15 @@ from google.cloud.oracledatabase_v1.types import ( exascale_db_storage_vault as gco_exascale_db_storage_vault, ) +from google.cloud.oracledatabase_v1.types import ( + goldengate_connection as gco_goldengate_connection, +) +from google.cloud.oracledatabase_v1.types import ( + goldengate_connection_assignment as gco_goldengate_connection_assignment, +) +from google.cloud.oracledatabase_v1.types import ( + goldengate_deployment as gco_goldengate_deployment, +) from google.cloud.oracledatabase_v1.types import odb_network as gco_odb_network from google.cloud.oracledatabase_v1.types import odb_subnet as gco_odb_subnet @@ -2063,18 +2079,20 @@ def delete_db_system( return self._stubs["delete_db_system"] @property - def list_db_versions( + def list_goldengate_deployments( self, ) -> Callable[ - [db_version.ListDbVersionsRequest], Awaitable[db_version.ListDbVersionsResponse] + [goldengate_deployment.ListGoldengateDeploymentsRequest], + Awaitable[goldengate_deployment.ListGoldengateDeploymentsResponse], ]: - r"""Return a callable for the list db versions method over gRPC. + r"""Return a callable for the list goldengate deployments method over gRPC. - List DbVersions for the given project and location. + Lists all the GoldengateDeployments for the given + project and location. Returns: - Callable[[~.ListDbVersionsRequest], - Awaitable[~.ListDbVersionsResponse]]: + Callable[[~.ListGoldengateDeploymentsRequest], + Awaitable[~.ListGoldengateDeploymentsResponse]]: A function that, when called, will call the underlying RPC on the server. """ @@ -2082,29 +2100,30 @@ def list_db_versions( # the request. # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. - if "list_db_versions" not in self._stubs: - self._stubs["list_db_versions"] = self._logged_channel.unary_unary( - "/google.cloud.oracledatabase.v1.OracleDatabase/ListDbVersions", - request_serializer=db_version.ListDbVersionsRequest.serialize, - response_deserializer=db_version.ListDbVersionsResponse.deserialize, + if "list_goldengate_deployments" not in self._stubs: + self._stubs["list_goldengate_deployments"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/ListGoldengateDeployments", + request_serializer=goldengate_deployment.ListGoldengateDeploymentsRequest.serialize, + response_deserializer=goldengate_deployment.ListGoldengateDeploymentsResponse.deserialize, + ) ) - return self._stubs["list_db_versions"] + return self._stubs["list_goldengate_deployments"] @property - def list_database_character_sets( + def get_goldengate_deployment( self, ) -> Callable[ - [database_character_set.ListDatabaseCharacterSetsRequest], - Awaitable[database_character_set.ListDatabaseCharacterSetsResponse], + [goldengate_deployment.GetGoldengateDeploymentRequest], + Awaitable[goldengate_deployment.GoldengateDeployment], ]: - r"""Return a callable for the list database character sets method over gRPC. + r"""Return a callable for the get goldengate deployment method over gRPC. - List DatabaseCharacterSets for the given project and - location. + Gets details of a single GoldengateDeployment. Returns: - Callable[[~.ListDatabaseCharacterSetsRequest], - Awaitable[~.ListDatabaseCharacterSetsResponse]]: + Callable[[~.GetGoldengateDeploymentRequest], + Awaitable[~.GoldengateDeployment]]: A function that, when called, will call the underlying RPC on the server. """ @@ -2112,217 +2131,956 @@ def list_database_character_sets( # the request. # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. - if "list_database_character_sets" not in self._stubs: - self._stubs["list_database_character_sets"] = ( + if "get_goldengate_deployment" not in self._stubs: + self._stubs["get_goldengate_deployment"] = self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/GetGoldengateDeployment", + request_serializer=goldengate_deployment.GetGoldengateDeploymentRequest.serialize, + response_deserializer=goldengate_deployment.GoldengateDeployment.deserialize, + ) + return self._stubs["get_goldengate_deployment"] + + @property + def create_goldengate_deployment( + self, + ) -> Callable[ + [gco_goldengate_deployment.CreateGoldengateDeploymentRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the create goldengate deployment method over gRPC. + + Creates a new GoldengateDeployment in a given project + and location. + + Returns: + Callable[[~.CreateGoldengateDeploymentRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_goldengate_deployment" not in self._stubs: + self._stubs["create_goldengate_deployment"] = ( self._logged_channel.unary_unary( - "/google.cloud.oracledatabase.v1.OracleDatabase/ListDatabaseCharacterSets", - request_serializer=database_character_set.ListDatabaseCharacterSetsRequest.serialize, - response_deserializer=database_character_set.ListDatabaseCharacterSetsResponse.deserialize, + "/google.cloud.oracledatabase.v1.OracleDatabase/CreateGoldengateDeployment", + request_serializer=gco_goldengate_deployment.CreateGoldengateDeploymentRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, ) ) - return self._stubs["list_database_character_sets"] + return self._stubs["create_goldengate_deployment"] - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.list_cloud_exadata_infrastructures: self._wrap_method( - self.list_cloud_exadata_infrastructures, - default_retry=retries.AsyncRetry( - initial=1.0, - maximum=10.0, - multiplier=1.3, - predicate=retries.if_exception_type( - core_exceptions.DeadlineExceeded, - core_exceptions.ServiceUnavailable, - ), - deadline=60.0, - ), - default_timeout=60.0, - client_info=client_info, - ), - self.get_cloud_exadata_infrastructure: self._wrap_method( - self.get_cloud_exadata_infrastructure, - default_retry=retries.AsyncRetry( - initial=1.0, - maximum=10.0, - multiplier=1.3, - predicate=retries.if_exception_type( - core_exceptions.DeadlineExceeded, - core_exceptions.ServiceUnavailable, - ), - deadline=60.0, - ), - default_timeout=60.0, - client_info=client_info, - ), - self.create_cloud_exadata_infrastructure: self._wrap_method( - self.create_cloud_exadata_infrastructure, - default_timeout=None, - client_info=client_info, - ), - self.delete_cloud_exadata_infrastructure: self._wrap_method( - self.delete_cloud_exadata_infrastructure, - default_timeout=None, - client_info=client_info, - ), - self.list_cloud_vm_clusters: self._wrap_method( - self.list_cloud_vm_clusters, - default_retry=retries.AsyncRetry( - initial=1.0, - maximum=10.0, - multiplier=1.3, - predicate=retries.if_exception_type( - core_exceptions.DeadlineExceeded, - core_exceptions.ServiceUnavailable, - ), - deadline=60.0, - ), - default_timeout=60.0, - client_info=client_info, - ), - self.get_cloud_vm_cluster: self._wrap_method( - self.get_cloud_vm_cluster, - default_retry=retries.AsyncRetry( - initial=1.0, - maximum=10.0, - multiplier=1.3, - predicate=retries.if_exception_type( - core_exceptions.DeadlineExceeded, - core_exceptions.ServiceUnavailable, - ), - deadline=60.0, - ), - default_timeout=60.0, - client_info=client_info, - ), - self.create_cloud_vm_cluster: self._wrap_method( - self.create_cloud_vm_cluster, - default_timeout=None, - client_info=client_info, - ), - self.delete_cloud_vm_cluster: self._wrap_method( - self.delete_cloud_vm_cluster, - default_timeout=None, - client_info=client_info, - ), - self.list_entitlements: self._wrap_method( - self.list_entitlements, - default_retry=retries.AsyncRetry( - initial=1.0, - maximum=10.0, - multiplier=1.3, - predicate=retries.if_exception_type( - core_exceptions.DeadlineExceeded, - core_exceptions.ServiceUnavailable, - ), - deadline=60.0, - ), - default_timeout=60.0, - client_info=client_info, - ), - self.list_db_servers: self._wrap_method( - self.list_db_servers, - default_retry=retries.AsyncRetry( - initial=1.0, - maximum=10.0, - multiplier=1.3, - predicate=retries.if_exception_type( - core_exceptions.DeadlineExceeded, - core_exceptions.ServiceUnavailable, - ), - deadline=60.0, - ), - default_timeout=60.0, - client_info=client_info, - ), - self.list_db_nodes: self._wrap_method( - self.list_db_nodes, - default_retry=retries.AsyncRetry( - initial=1.0, - maximum=10.0, - multiplier=1.3, - predicate=retries.if_exception_type( - core_exceptions.DeadlineExceeded, - core_exceptions.ServiceUnavailable, - ), - deadline=60.0, - ), - default_timeout=60.0, - client_info=client_info, - ), - self.list_gi_versions: self._wrap_method( - self.list_gi_versions, - default_retry=retries.AsyncRetry( - initial=1.0, - maximum=10.0, - multiplier=1.3, - predicate=retries.if_exception_type( - core_exceptions.DeadlineExceeded, - core_exceptions.ServiceUnavailable, - ), - deadline=60.0, - ), - default_timeout=60.0, - client_info=client_info, - ), - self.list_minor_versions: self._wrap_method( - self.list_minor_versions, - default_retry=retries.AsyncRetry( - initial=1.0, - maximum=10.0, - multiplier=1.3, - predicate=retries.if_exception_type( - core_exceptions.DeadlineExceeded, - core_exceptions.ServiceUnavailable, - ), - deadline=60.0, - ), - default_timeout=60.0, - client_info=client_info, - ), - self.list_db_system_shapes: self._wrap_method( - self.list_db_system_shapes, - default_retry=retries.AsyncRetry( - initial=1.0, - maximum=10.0, - multiplier=1.3, - predicate=retries.if_exception_type( - core_exceptions.DeadlineExceeded, - core_exceptions.ServiceUnavailable, - ), - deadline=60.0, - ), - default_timeout=60.0, - client_info=client_info, - ), - self.list_autonomous_databases: self._wrap_method( - self.list_autonomous_databases, - default_retry=retries.AsyncRetry( - initial=1.0, - maximum=10.0, - multiplier=1.3, - predicate=retries.if_exception_type( - core_exceptions.DeadlineExceeded, - core_exceptions.ServiceUnavailable, - ), - deadline=60.0, - ), - default_timeout=60.0, - client_info=client_info, - ), - self.get_autonomous_database: self._wrap_method( - self.get_autonomous_database, - default_retry=retries.AsyncRetry( - initial=1.0, - maximum=10.0, - multiplier=1.3, - predicate=retries.if_exception_type( - core_exceptions.DeadlineExceeded, - core_exceptions.ServiceUnavailable, - ), - deadline=60.0, - ), - default_timeout=60.0, + @property + def delete_goldengate_deployment( + self, + ) -> Callable[ + [goldengate_deployment.DeleteGoldengateDeploymentRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the delete goldengate deployment method over gRPC. + + Deletes a single GoldengateDeployment. + + Returns: + Callable[[~.DeleteGoldengateDeploymentRequest], + 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 "delete_goldengate_deployment" not in self._stubs: + self._stubs["delete_goldengate_deployment"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/DeleteGoldengateDeployment", + request_serializer=goldengate_deployment.DeleteGoldengateDeploymentRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + ) + return self._stubs["delete_goldengate_deployment"] + + @property + def stop_goldengate_deployment( + self, + ) -> Callable[ + [goldengate_deployment.StopGoldengateDeploymentRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the stop goldengate deployment method over gRPC. + + Stops a single GoldengateDeployment. + + Returns: + Callable[[~.StopGoldengateDeploymentRequest], + 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 "stop_goldengate_deployment" not in self._stubs: + self._stubs["stop_goldengate_deployment"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/StopGoldengateDeployment", + request_serializer=goldengate_deployment.StopGoldengateDeploymentRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + ) + return self._stubs["stop_goldengate_deployment"] + + @property + def start_goldengate_deployment( + self, + ) -> Callable[ + [goldengate_deployment.StartGoldengateDeploymentRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the start goldengate deployment method over gRPC. + + Starts a single GoldengateDeployment. + + Returns: + Callable[[~.StartGoldengateDeploymentRequest], + 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 "start_goldengate_deployment" not in self._stubs: + self._stubs["start_goldengate_deployment"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/StartGoldengateDeployment", + request_serializer=goldengate_deployment.StartGoldengateDeploymentRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + ) + return self._stubs["start_goldengate_deployment"] + + @property + def list_goldengate_connections( + self, + ) -> Callable[ + [goldengate_connection.ListGoldengateConnectionsRequest], + Awaitable[goldengate_connection.ListGoldengateConnectionsResponse], + ]: + r"""Return a callable for the list goldengate connections method over gRPC. + + Lists all the GoldengateConnections for the given + project and location. + + Returns: + Callable[[~.ListGoldengateConnectionsRequest], + Awaitable[~.ListGoldengateConnectionsResponse]]: + 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_goldengate_connections" not in self._stubs: + self._stubs["list_goldengate_connections"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/ListGoldengateConnections", + request_serializer=goldengate_connection.ListGoldengateConnectionsRequest.serialize, + response_deserializer=goldengate_connection.ListGoldengateConnectionsResponse.deserialize, + ) + ) + return self._stubs["list_goldengate_connections"] + + @property + def get_goldengate_connection( + self, + ) -> Callable[ + [goldengate_connection.GetGoldengateConnectionRequest], + Awaitable[goldengate_connection.GoldengateConnection], + ]: + r"""Return a callable for the get goldengate connection method over gRPC. + + Gets details of a single GoldengateConnection. + + Returns: + Callable[[~.GetGoldengateConnectionRequest], + Awaitable[~.GoldengateConnection]]: + 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_goldengate_connection" not in self._stubs: + self._stubs["get_goldengate_connection"] = self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/GetGoldengateConnection", + request_serializer=goldengate_connection.GetGoldengateConnectionRequest.serialize, + response_deserializer=goldengate_connection.GoldengateConnection.deserialize, + ) + return self._stubs["get_goldengate_connection"] + + @property + def create_goldengate_connection( + self, + ) -> Callable[ + [gco_goldengate_connection.CreateGoldengateConnectionRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the create goldengate connection method over gRPC. + + Creates a new GoldengateConnection in a given project + and location. + + Returns: + Callable[[~.CreateGoldengateConnectionRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_goldengate_connection" not in self._stubs: + self._stubs["create_goldengate_connection"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/CreateGoldengateConnection", + request_serializer=gco_goldengate_connection.CreateGoldengateConnectionRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + ) + return self._stubs["create_goldengate_connection"] + + @property + def delete_goldengate_connection( + self, + ) -> Callable[ + [goldengate_connection.DeleteGoldengateConnectionRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the delete goldengate connection method over gRPC. + + Deletes a single GoldengateConnection. + + Returns: + Callable[[~.DeleteGoldengateConnectionRequest], + 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 "delete_goldengate_connection" not in self._stubs: + self._stubs["delete_goldengate_connection"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/DeleteGoldengateConnection", + request_serializer=goldengate_connection.DeleteGoldengateConnectionRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + ) + return self._stubs["delete_goldengate_connection"] + + @property + def get_goldengate_deployment_version( + self, + ) -> Callable[ + [goldengate_deployment_version.GetGoldengateDeploymentVersionRequest], + Awaitable[goldengate_deployment_version.GoldengateDeploymentVersion], + ]: + r"""Return a callable for the get goldengate deployment + version method over gRPC. + + Gets details of a single GoldengateDeploymentVersion. + + Returns: + Callable[[~.GetGoldengateDeploymentVersionRequest], + Awaitable[~.GoldengateDeploymentVersion]]: + 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_goldengate_deployment_version" not in self._stubs: + self._stubs["get_goldengate_deployment_version"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/GetGoldengateDeploymentVersion", + request_serializer=goldengate_deployment_version.GetGoldengateDeploymentVersionRequest.serialize, + response_deserializer=goldengate_deployment_version.GoldengateDeploymentVersion.deserialize, + ) + ) + return self._stubs["get_goldengate_deployment_version"] + + @property + def list_goldengate_deployment_versions( + self, + ) -> Callable[ + [goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest], + Awaitable[ + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse + ], + ]: + r"""Return a callable for the list goldengate deployment + versions method over gRPC. + + Lists GoldengateDeploymentVersions in a given project + and location. + + Returns: + Callable[[~.ListGoldengateDeploymentVersionsRequest], + Awaitable[~.ListGoldengateDeploymentVersionsResponse]]: + 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_goldengate_deployment_versions" not in self._stubs: + self._stubs["list_goldengate_deployment_versions"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/ListGoldengateDeploymentVersions", + request_serializer=goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest.serialize, + response_deserializer=goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse.deserialize, + ) + ) + return self._stubs["list_goldengate_deployment_versions"] + + @property + def get_goldengate_deployment_type( + self, + ) -> Callable[ + [goldengate_deployment_type.GetGoldengateDeploymentTypeRequest], + Awaitable[goldengate_deployment_type.GoldengateDeploymentType], + ]: + r"""Return a callable for the get goldengate deployment type method over gRPC. + + Gets details of a single GoldenGateDeploymentType. + + Returns: + Callable[[~.GetGoldengateDeploymentTypeRequest], + Awaitable[~.GoldengateDeploymentType]]: + 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_goldengate_deployment_type" not in self._stubs: + self._stubs["get_goldengate_deployment_type"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/GetGoldengateDeploymentType", + request_serializer=goldengate_deployment_type.GetGoldengateDeploymentTypeRequest.serialize, + response_deserializer=goldengate_deployment_type.GoldengateDeploymentType.deserialize, + ) + ) + return self._stubs["get_goldengate_deployment_type"] + + @property + def list_goldengate_deployment_types( + self, + ) -> Callable[ + [goldengate_deployment_type.ListGoldengateDeploymentTypesRequest], + Awaitable[goldengate_deployment_type.ListGoldengateDeploymentTypesResponse], + ]: + r"""Return a callable for the list goldengate deployment + types method over gRPC. + + Lists GoldenGateDeploymentTypes in a given project + and location. + + Returns: + Callable[[~.ListGoldengateDeploymentTypesRequest], + Awaitable[~.ListGoldengateDeploymentTypesResponse]]: + 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_goldengate_deployment_types" not in self._stubs: + self._stubs["list_goldengate_deployment_types"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/ListGoldengateDeploymentTypes", + request_serializer=goldengate_deployment_type.ListGoldengateDeploymentTypesRequest.serialize, + response_deserializer=goldengate_deployment_type.ListGoldengateDeploymentTypesResponse.deserialize, + ) + ) + return self._stubs["list_goldengate_deployment_types"] + + @property + def get_goldengate_deployment_environment( + self, + ) -> Callable[ + [goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest], + Awaitable[goldengate_deployment_environment.GoldengateDeploymentEnvironment], + ]: + r"""Return a callable for the get goldengate deployment + environment method over gRPC. + + Gets details of a single + GoldengateDeploymentEnvironment. + + Returns: + Callable[[~.GetGoldengateDeploymentEnvironmentRequest], + Awaitable[~.GoldengateDeploymentEnvironment]]: + 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_goldengate_deployment_environment" not in self._stubs: + self._stubs["get_goldengate_deployment_environment"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/GetGoldengateDeploymentEnvironment", + request_serializer=goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest.serialize, + response_deserializer=goldengate_deployment_environment.GoldengateDeploymentEnvironment.deserialize, + ) + ) + return self._stubs["get_goldengate_deployment_environment"] + + @property + def list_goldengate_deployment_environments( + self, + ) -> Callable[ + [goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest], + Awaitable[ + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse + ], + ]: + r"""Return a callable for the list goldengate deployment + environments method over gRPC. + + Lists GoldengateDeploymentEnvironments in a given + project and location. + + Returns: + Callable[[~.ListGoldengateDeploymentEnvironmentsRequest], + Awaitable[~.ListGoldengateDeploymentEnvironmentsResponse]]: + 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_goldengate_deployment_environments" not in self._stubs: + self._stubs["list_goldengate_deployment_environments"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/ListGoldengateDeploymentEnvironments", + request_serializer=goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest.serialize, + response_deserializer=goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse.deserialize, + ) + ) + return self._stubs["list_goldengate_deployment_environments"] + + @property + def get_goldengate_connection_type( + self, + ) -> Callable[ + [goldengate_connection_type.GetGoldengateConnectionTypeRequest], + Awaitable[goldengate_connection_type.GoldengateConnectionType], + ]: + r"""Return a callable for the get goldengate connection type method over gRPC. + + Gets details of a single GoldengateConnectionType. + + Returns: + Callable[[~.GetGoldengateConnectionTypeRequest], + Awaitable[~.GoldengateConnectionType]]: + 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_goldengate_connection_type" not in self._stubs: + self._stubs["get_goldengate_connection_type"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/GetGoldengateConnectionType", + request_serializer=goldengate_connection_type.GetGoldengateConnectionTypeRequest.serialize, + response_deserializer=goldengate_connection_type.GoldengateConnectionType.deserialize, + ) + ) + return self._stubs["get_goldengate_connection_type"] + + @property + def list_goldengate_connection_types( + self, + ) -> Callable[ + [goldengate_connection_type.ListGoldengateConnectionTypesRequest], + Awaitable[goldengate_connection_type.ListGoldengateConnectionTypesResponse], + ]: + r"""Return a callable for the list goldengate connection + types method over gRPC. + + Lists GoldengateConnectionTypes in a given project + and location. + + Returns: + Callable[[~.ListGoldengateConnectionTypesRequest], + Awaitable[~.ListGoldengateConnectionTypesResponse]]: + 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_goldengate_connection_types" not in self._stubs: + self._stubs["list_goldengate_connection_types"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/ListGoldengateConnectionTypes", + request_serializer=goldengate_connection_type.ListGoldengateConnectionTypesRequest.serialize, + response_deserializer=goldengate_connection_type.ListGoldengateConnectionTypesResponse.deserialize, + ) + ) + return self._stubs["list_goldengate_connection_types"] + + @property + def list_db_versions( + self, + ) -> Callable[ + [db_version.ListDbVersionsRequest], Awaitable[db_version.ListDbVersionsResponse] + ]: + r"""Return a callable for the list db versions method over gRPC. + + List DbVersions for the given project and location. + + Returns: + Callable[[~.ListDbVersionsRequest], + Awaitable[~.ListDbVersionsResponse]]: + 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_db_versions" not in self._stubs: + self._stubs["list_db_versions"] = self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/ListDbVersions", + request_serializer=db_version.ListDbVersionsRequest.serialize, + response_deserializer=db_version.ListDbVersionsResponse.deserialize, + ) + return self._stubs["list_db_versions"] + + @property + def list_database_character_sets( + self, + ) -> Callable[ + [database_character_set.ListDatabaseCharacterSetsRequest], + Awaitable[database_character_set.ListDatabaseCharacterSetsResponse], + ]: + r"""Return a callable for the list database character sets method over gRPC. + + List DatabaseCharacterSets for the given project and + location. + + Returns: + Callable[[~.ListDatabaseCharacterSetsRequest], + Awaitable[~.ListDatabaseCharacterSetsResponse]]: + 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_database_character_sets" not in self._stubs: + self._stubs["list_database_character_sets"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/ListDatabaseCharacterSets", + request_serializer=database_character_set.ListDatabaseCharacterSetsRequest.serialize, + response_deserializer=database_character_set.ListDatabaseCharacterSetsResponse.deserialize, + ) + ) + return self._stubs["list_database_character_sets"] + + @property + def list_goldengate_connection_assignments( + self, + ) -> Callable[ + [goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest], + Awaitable[ + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse + ], + ]: + r"""Return a callable for the list goldengate connection + assignments method over gRPC. + + Lists GoldengateConnectionAssignments in a given + project and location. + + Returns: + Callable[[~.ListGoldengateConnectionAssignmentsRequest], + Awaitable[~.ListGoldengateConnectionAssignmentsResponse]]: + 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_goldengate_connection_assignments" not in self._stubs: + self._stubs["list_goldengate_connection_assignments"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/ListGoldengateConnectionAssignments", + request_serializer=goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest.serialize, + response_deserializer=goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse.deserialize, + ) + ) + return self._stubs["list_goldengate_connection_assignments"] + + @property + def get_goldengate_connection_assignment( + self, + ) -> Callable[ + [goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest], + Awaitable[goldengate_connection_assignment.GoldengateConnectionAssignment], + ]: + r"""Return a callable for the get goldengate connection + assignment method over gRPC. + + Gets details of a single + GoldengateConnectionAssignment. + + Returns: + Callable[[~.GetGoldengateConnectionAssignmentRequest], + Awaitable[~.GoldengateConnectionAssignment]]: + 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_goldengate_connection_assignment" not in self._stubs: + self._stubs["get_goldengate_connection_assignment"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/GetGoldengateConnectionAssignment", + request_serializer=goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest.serialize, + response_deserializer=goldengate_connection_assignment.GoldengateConnectionAssignment.deserialize, + ) + ) + return self._stubs["get_goldengate_connection_assignment"] + + @property + def create_goldengate_connection_assignment( + self, + ) -> Callable[ + [ + gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest + ], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the create goldengate connection + assignment method over gRPC. + + Creates a new GoldengateConnectionAssignment in a + given project and location. + + Returns: + Callable[[~.CreateGoldengateConnectionAssignmentRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_goldengate_connection_assignment" not in self._stubs: + self._stubs["create_goldengate_connection_assignment"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/CreateGoldengateConnectionAssignment", + request_serializer=gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + ) + return self._stubs["create_goldengate_connection_assignment"] + + @property + def delete_goldengate_connection_assignment( + self, + ) -> Callable[ + [goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the delete goldengate connection + assignment method over gRPC. + + Deletes a single GoldengateConnectionAssignment. + + Returns: + Callable[[~.DeleteGoldengateConnectionAssignmentRequest], + 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 "delete_goldengate_connection_assignment" not in self._stubs: + self._stubs["delete_goldengate_connection_assignment"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/DeleteGoldengateConnectionAssignment", + request_serializer=goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + ) + return self._stubs["delete_goldengate_connection_assignment"] + + @property + def test_goldengate_connection_assignment( + self, + ) -> Callable[ + [goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest], + Awaitable[ + goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse + ], + ]: + r"""Return a callable for the test goldengate connection + assignment method over gRPC. + + Tests a single GoldengateConnectionAssignment. + + Returns: + Callable[[~.TestGoldengateConnectionAssignmentRequest], + Awaitable[~.TestGoldengateConnectionAssignmentResponse]]: + 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 "test_goldengate_connection_assignment" not in self._stubs: + self._stubs["test_goldengate_connection_assignment"] = ( + self._logged_channel.unary_unary( + "/google.cloud.oracledatabase.v1.OracleDatabase/TestGoldengateConnectionAssignment", + request_serializer=goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest.serialize, + response_deserializer=goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse.deserialize, + ) + ) + return self._stubs["test_goldengate_connection_assignment"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.list_cloud_exadata_infrastructures: self._wrap_method( + self.list_cloud_exadata_infrastructures, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.get_cloud_exadata_infrastructure: self._wrap_method( + self.get_cloud_exadata_infrastructure, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.create_cloud_exadata_infrastructure: self._wrap_method( + self.create_cloud_exadata_infrastructure, + default_timeout=None, + client_info=client_info, + ), + self.delete_cloud_exadata_infrastructure: self._wrap_method( + self.delete_cloud_exadata_infrastructure, + default_timeout=None, + client_info=client_info, + ), + self.list_cloud_vm_clusters: self._wrap_method( + self.list_cloud_vm_clusters, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.get_cloud_vm_cluster: self._wrap_method( + self.get_cloud_vm_cluster, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.create_cloud_vm_cluster: self._wrap_method( + self.create_cloud_vm_cluster, + default_timeout=None, + client_info=client_info, + ), + self.delete_cloud_vm_cluster: self._wrap_method( + self.delete_cloud_vm_cluster, + default_timeout=None, + client_info=client_info, + ), + self.list_entitlements: self._wrap_method( + self.list_entitlements, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.list_db_servers: self._wrap_method( + self.list_db_servers, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.list_db_nodes: self._wrap_method( + self.list_db_nodes, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.list_gi_versions: self._wrap_method( + self.list_gi_versions, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.list_minor_versions: self._wrap_method( + self.list_minor_versions, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.list_db_system_shapes: self._wrap_method( + self.list_db_system_shapes, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.list_autonomous_databases: self._wrap_method( + self.list_autonomous_databases, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.get_autonomous_database: self._wrap_method( + self.get_autonomous_database, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, client_info=client_info, ), self.create_autonomous_database: self._wrap_method( @@ -2705,6 +3463,176 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.list_goldengate_deployments: self._wrap_method( + self.list_goldengate_deployments, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.get_goldengate_deployment: self._wrap_method( + self.get_goldengate_deployment, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.create_goldengate_deployment: self._wrap_method( + self.create_goldengate_deployment, + default_timeout=None, + client_info=client_info, + ), + self.delete_goldengate_deployment: self._wrap_method( + self.delete_goldengate_deployment, + default_timeout=None, + client_info=client_info, + ), + self.stop_goldengate_deployment: self._wrap_method( + self.stop_goldengate_deployment, + default_timeout=None, + client_info=client_info, + ), + self.start_goldengate_deployment: self._wrap_method( + self.start_goldengate_deployment, + default_timeout=None, + client_info=client_info, + ), + self.list_goldengate_connections: self._wrap_method( + self.list_goldengate_connections, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.get_goldengate_connection: self._wrap_method( + self.get_goldengate_connection, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.create_goldengate_connection: self._wrap_method( + self.create_goldengate_connection, + default_timeout=None, + client_info=client_info, + ), + self.delete_goldengate_connection: self._wrap_method( + self.delete_goldengate_connection, + default_timeout=None, + client_info=client_info, + ), + self.get_goldengate_deployment_version: self._wrap_method( + self.get_goldengate_deployment_version, + default_timeout=None, + client_info=client_info, + ), + self.list_goldengate_deployment_versions: self._wrap_method( + self.list_goldengate_deployment_versions, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.get_goldengate_deployment_type: self._wrap_method( + self.get_goldengate_deployment_type, + default_timeout=None, + client_info=client_info, + ), + self.list_goldengate_deployment_types: self._wrap_method( + self.list_goldengate_deployment_types, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.get_goldengate_deployment_environment: self._wrap_method( + self.get_goldengate_deployment_environment, + default_timeout=None, + client_info=client_info, + ), + self.list_goldengate_deployment_environments: self._wrap_method( + self.list_goldengate_deployment_environments, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.get_goldengate_connection_type: self._wrap_method( + self.get_goldengate_connection_type, + default_timeout=None, + client_info=client_info, + ), + self.list_goldengate_connection_types: self._wrap_method( + self.list_goldengate_connection_types, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), self.list_db_versions: self._wrap_method( self.list_db_versions, default_retry=retries.AsyncRetry( @@ -2735,6 +3663,51 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), + self.list_goldengate_connection_assignments: self._wrap_method( + self.list_goldengate_connection_assignments, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.get_goldengate_connection_assignment: self._wrap_method( + self.get_goldengate_connection_assignment, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.create_goldengate_connection_assignment: self._wrap_method( + self.create_goldengate_connection_assignment, + default_timeout=None, + client_info=client_info, + ), + self.delete_goldengate_connection_assignment: self._wrap_method( + self.delete_goldengate_connection_assignment, + default_timeout=None, + client_info=client_info, + ), + self.test_goldengate_connection_assignment: self._wrap_method( + self.test_goldengate_connection_assignment, + default_timeout=None, + client_info=client_info, + ), self.get_location: self._wrap_method( self.get_location, default_timeout=None, diff --git a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/transports/rest.py b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/transports/rest.py index 0af0ced60d89..c876eaea4d4e 100644 --- a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/transports/rest.py +++ b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/transports/rest.py @@ -40,6 +40,13 @@ exadata_infra, exadb_vm_cluster, exascale_db_storage_vault, + goldengate_connection, + goldengate_connection_assignment, + goldengate_connection_type, + goldengate_deployment, + goldengate_deployment_environment, + goldengate_deployment_type, + goldengate_deployment_version, minor_version, odb_network, odb_subnet, @@ -51,6 +58,15 @@ from google.cloud.oracledatabase_v1.types import ( exascale_db_storage_vault as gco_exascale_db_storage_vault, ) +from google.cloud.oracledatabase_v1.types import ( + goldengate_connection as gco_goldengate_connection, +) +from google.cloud.oracledatabase_v1.types import ( + goldengate_connection_assignment as gco_goldengate_connection_assignment, +) +from google.cloud.oracledatabase_v1.types import ( + goldengate_deployment as gco_goldengate_deployment, +) from google.cloud.oracledatabase_v1.types import odb_network as gco_odb_network from google.cloud.oracledatabase_v1.types import odb_subnet as gco_odb_subnet @@ -144,6 +160,30 @@ def post_create_exascale_db_storage_vault(self, response): logging.log(f"Received response: {response}") return response + def pre_create_goldengate_connection(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_goldengate_connection(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_create_goldengate_connection_assignment(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_goldengate_connection_assignment(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_create_goldengate_deployment(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_goldengate_deployment(self, response): + logging.log(f"Received response: {response}") + return response + def pre_create_odb_network(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -208,6 +248,30 @@ def post_delete_exascale_db_storage_vault(self, response): logging.log(f"Received response: {response}") return response + def pre_delete_goldengate_connection(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_delete_goldengate_connection(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_delete_goldengate_connection_assignment(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_delete_goldengate_connection_assignment(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_delete_goldengate_deployment(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_delete_goldengate_deployment(self, response): + logging.log(f"Received response: {response}") + return response + def pre_delete_odb_network(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -296,6 +360,62 @@ def post_get_exascale_db_storage_vault(self, response): logging.log(f"Received response: {response}") return response + def pre_get_goldengate_connection(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_goldengate_connection(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_goldengate_connection_assignment(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_goldengate_connection_assignment(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_goldengate_connection_type(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_goldengate_connection_type(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_goldengate_deployment(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_goldengate_deployment(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_goldengate_deployment_environment(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_goldengate_deployment_environment(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_goldengate_deployment_type(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_goldengate_deployment_type(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_goldengate_deployment_version(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_goldengate_deployment_version(self, response): + logging.log(f"Received response: {response}") + return response + def pre_get_odb_network(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -464,6 +584,62 @@ def post_list_gi_versions(self, response): logging.log(f"Received response: {response}") return response + def pre_list_goldengate_connection_assignments(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_goldengate_connection_assignments(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_goldengate_connections(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_goldengate_connections(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_goldengate_connection_types(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_goldengate_connection_types(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_goldengate_deployment_environments(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_goldengate_deployment_environments(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_goldengate_deployments(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_goldengate_deployments(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_goldengate_deployment_types(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_goldengate_deployment_types(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_goldengate_deployment_versions(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_goldengate_deployment_versions(self, response): + logging.log(f"Received response: {response}") + return response + def pre_list_minor_versions(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -528,6 +704,14 @@ def post_start_autonomous_database(self, response): logging.log(f"Received response: {response}") return response + def pre_start_goldengate_deployment(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_start_goldengate_deployment(self, response): + logging.log(f"Received response: {response}") + return response + def pre_stop_autonomous_database(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -536,6 +720,14 @@ def post_stop_autonomous_database(self, response): logging.log(f"Received response: {response}") return response + def pre_stop_goldengate_deployment(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_stop_goldengate_deployment(self, response): + logging.log(f"Received response: {response}") + return response + def pre_switchover_autonomous_database(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -544,6 +736,14 @@ def post_switchover_autonomous_database(self, response): logging.log(f"Received response: {response}") return response + def pre_test_goldengate_connection_assignment(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_test_goldengate_connection_assignment(self, response): + logging.log(f"Received response: {response}") + return response + def pre_update_autonomous_database(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -859,6 +1059,153 @@ def post_create_exascale_db_storage_vault_with_metadata( """ return response, metadata + def pre_create_goldengate_connection( + self, + request: gco_goldengate_connection.CreateGoldengateConnectionRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gco_goldengate_connection.CreateGoldengateConnectionRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for create_goldengate_connection + + Override in a subclass to manipulate the request or metadata + before they are sent to the OracleDatabase server. + """ + return request, metadata + + def post_create_goldengate_connection( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for create_goldengate_connection + + DEPRECATED. Please use the `post_create_goldengate_connection_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the OracleDatabase server but before + it is returned to user code. This `post_create_goldengate_connection` interceptor runs + before the `post_create_goldengate_connection_with_metadata` interceptor. + """ + return response + + def post_create_goldengate_connection_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_goldengate_connection + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the OracleDatabase server but before it is returned to user code. + + We recommend only using this `post_create_goldengate_connection_with_metadata` + interceptor in new development instead of the `post_create_goldengate_connection` interceptor. + When both interceptors are used, this `post_create_goldengate_connection_with_metadata` interceptor runs after the + `post_create_goldengate_connection` interceptor. The (possibly modified) response returned by + `post_create_goldengate_connection` will be passed to + `post_create_goldengate_connection_with_metadata`. + """ + return response, metadata + + def pre_create_goldengate_connection_assignment( + self, + request: gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for create_goldengate_connection_assignment + + Override in a subclass to manipulate the request or metadata + before they are sent to the OracleDatabase server. + """ + return request, metadata + + def post_create_goldengate_connection_assignment( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for create_goldengate_connection_assignment + + DEPRECATED. Please use the `post_create_goldengate_connection_assignment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the OracleDatabase server but before + it is returned to user code. This `post_create_goldengate_connection_assignment` interceptor runs + before the `post_create_goldengate_connection_assignment_with_metadata` interceptor. + """ + return response + + def post_create_goldengate_connection_assignment_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_goldengate_connection_assignment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the OracleDatabase server but before it is returned to user code. + + We recommend only using this `post_create_goldengate_connection_assignment_with_metadata` + interceptor in new development instead of the `post_create_goldengate_connection_assignment` interceptor. + When both interceptors are used, this `post_create_goldengate_connection_assignment_with_metadata` interceptor runs after the + `post_create_goldengate_connection_assignment` interceptor. The (possibly modified) response returned by + `post_create_goldengate_connection_assignment` will be passed to + `post_create_goldengate_connection_assignment_with_metadata`. + """ + return response, metadata + + def pre_create_goldengate_deployment( + self, + request: gco_goldengate_deployment.CreateGoldengateDeploymentRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gco_goldengate_deployment.CreateGoldengateDeploymentRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for create_goldengate_deployment + + Override in a subclass to manipulate the request or metadata + before they are sent to the OracleDatabase server. + """ + return request, metadata + + def post_create_goldengate_deployment( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for create_goldengate_deployment + + DEPRECATED. Please use the `post_create_goldengate_deployment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the OracleDatabase server but before + it is returned to user code. This `post_create_goldengate_deployment` interceptor runs + before the `post_create_goldengate_deployment_with_metadata` interceptor. + """ + return response + + def post_create_goldengate_deployment_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_goldengate_deployment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the OracleDatabase server but before it is returned to user code. + + We recommend only using this `post_create_goldengate_deployment_with_metadata` + interceptor in new development instead of the `post_create_goldengate_deployment` interceptor. + When both interceptors are used, this `post_create_goldengate_deployment_with_metadata` interceptor runs after the + `post_create_goldengate_deployment` interceptor. The (possibly modified) response returned by + `post_create_goldengate_deployment` will be passed to + `post_create_goldengate_deployment_with_metadata`. + """ + return response, metadata + def pre_create_odb_network( self, request: gco_odb_network.CreateOdbNetworkRequest, @@ -1248,49 +1595,196 @@ def post_delete_exascale_db_storage_vault_with_metadata( """ return response, metadata - def pre_delete_odb_network( + def pre_delete_goldengate_connection( self, - request: odb_network.DeleteOdbNetworkRequest, + request: goldengate_connection.DeleteGoldengateConnectionRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - odb_network.DeleteOdbNetworkRequest, Sequence[Tuple[str, Union[str, bytes]]] + goldengate_connection.DeleteGoldengateConnectionRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: - """Pre-rpc interceptor for delete_odb_network + """Pre-rpc interceptor for delete_goldengate_connection Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_delete_odb_network( + def post_delete_goldengate_connection( self, response: operations_pb2.Operation ) -> operations_pb2.Operation: - """Post-rpc interceptor for delete_odb_network + """Post-rpc interceptor for delete_goldengate_connection - DEPRECATED. Please use the `post_delete_odb_network_with_metadata` + DEPRECATED. Please use the `post_delete_goldengate_connection_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_delete_odb_network` interceptor runs - before the `post_delete_odb_network_with_metadata` interceptor. + it is returned to user code. This `post_delete_goldengate_connection` interceptor runs + before the `post_delete_goldengate_connection_with_metadata` interceptor. """ return response - def post_delete_odb_network_with_metadata( + def post_delete_goldengate_connection_with_metadata( self, response: operations_pb2.Operation, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: - """Post-rpc interceptor for delete_odb_network + """Post-rpc interceptor for delete_goldengate_connection Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_delete_odb_network_with_metadata` - interceptor in new development instead of the `post_delete_odb_network` interceptor. - When both interceptors are used, this `post_delete_odb_network_with_metadata` interceptor runs after the - `post_delete_odb_network` interceptor. The (possibly modified) response returned by + We recommend only using this `post_delete_goldengate_connection_with_metadata` + interceptor in new development instead of the `post_delete_goldengate_connection` interceptor. + When both interceptors are used, this `post_delete_goldengate_connection_with_metadata` interceptor runs after the + `post_delete_goldengate_connection` interceptor. The (possibly modified) response returned by + `post_delete_goldengate_connection` will be passed to + `post_delete_goldengate_connection_with_metadata`. + """ + return response, metadata + + def pre_delete_goldengate_connection_assignment( + self, + request: goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for delete_goldengate_connection_assignment + + Override in a subclass to manipulate the request or metadata + before they are sent to the OracleDatabase server. + """ + return request, metadata + + def post_delete_goldengate_connection_assignment( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for delete_goldengate_connection_assignment + + DEPRECATED. Please use the `post_delete_goldengate_connection_assignment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the OracleDatabase server but before + it is returned to user code. This `post_delete_goldengate_connection_assignment` interceptor runs + before the `post_delete_goldengate_connection_assignment_with_metadata` interceptor. + """ + return response + + def post_delete_goldengate_connection_assignment_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_goldengate_connection_assignment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the OracleDatabase server but before it is returned to user code. + + We recommend only using this `post_delete_goldengate_connection_assignment_with_metadata` + interceptor in new development instead of the `post_delete_goldengate_connection_assignment` interceptor. + When both interceptors are used, this `post_delete_goldengate_connection_assignment_with_metadata` interceptor runs after the + `post_delete_goldengate_connection_assignment` interceptor. The (possibly modified) response returned by + `post_delete_goldengate_connection_assignment` will be passed to + `post_delete_goldengate_connection_assignment_with_metadata`. + """ + return response, metadata + + def pre_delete_goldengate_deployment( + self, + request: goldengate_deployment.DeleteGoldengateDeploymentRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + goldengate_deployment.DeleteGoldengateDeploymentRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for delete_goldengate_deployment + + Override in a subclass to manipulate the request or metadata + before they are sent to the OracleDatabase server. + """ + return request, metadata + + def post_delete_goldengate_deployment( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for delete_goldengate_deployment + + DEPRECATED. Please use the `post_delete_goldengate_deployment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the OracleDatabase server but before + it is returned to user code. This `post_delete_goldengate_deployment` interceptor runs + before the `post_delete_goldengate_deployment_with_metadata` interceptor. + """ + return response + + def post_delete_goldengate_deployment_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_goldengate_deployment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the OracleDatabase server but before it is returned to user code. + + We recommend only using this `post_delete_goldengate_deployment_with_metadata` + interceptor in new development instead of the `post_delete_goldengate_deployment` interceptor. + When both interceptors are used, this `post_delete_goldengate_deployment_with_metadata` interceptor runs after the + `post_delete_goldengate_deployment` interceptor. The (possibly modified) response returned by + `post_delete_goldengate_deployment` will be passed to + `post_delete_goldengate_deployment_with_metadata`. + """ + return response, metadata + + def pre_delete_odb_network( + self, + request: odb_network.DeleteOdbNetworkRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + odb_network.DeleteOdbNetworkRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for delete_odb_network + + Override in a subclass to manipulate the request or metadata + before they are sent to the OracleDatabase server. + """ + return request, metadata + + def post_delete_odb_network( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for delete_odb_network + + DEPRECATED. Please use the `post_delete_odb_network_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the OracleDatabase server but before + it is returned to user code. This `post_delete_odb_network` interceptor runs + before the `post_delete_odb_network_with_metadata` interceptor. + """ + return response + + def post_delete_odb_network_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_odb_network + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the OracleDatabase server but before it is returned to user code. + + We recommend only using this `post_delete_odb_network_with_metadata` + interceptor in new development instead of the `post_delete_odb_network` interceptor. + When both interceptors are used, this `post_delete_odb_network_with_metadata` interceptor runs after the + `post_delete_odb_network` interceptor. The (possibly modified) response returned by `post_delete_odb_network` will be passed to `post_delete_odb_network_with_metadata`. """ @@ -1786,1962 +2280,6176 @@ def post_get_exascale_db_storage_vault_with_metadata( """ return response, metadata - def pre_get_odb_network( + def pre_get_goldengate_connection( self, - request: odb_network.GetOdbNetworkRequest, + request: goldengate_connection.GetGoldengateConnectionRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - odb_network.GetOdbNetworkRequest, Sequence[Tuple[str, Union[str, bytes]]] + goldengate_connection.GetGoldengateConnectionRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: - """Pre-rpc interceptor for get_odb_network + """Pre-rpc interceptor for get_goldengate_connection Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_get_odb_network( - self, response: odb_network.OdbNetwork - ) -> odb_network.OdbNetwork: - """Post-rpc interceptor for get_odb_network + def post_get_goldengate_connection( + self, response: goldengate_connection.GoldengateConnection + ) -> goldengate_connection.GoldengateConnection: + """Post-rpc interceptor for get_goldengate_connection - DEPRECATED. Please use the `post_get_odb_network_with_metadata` + DEPRECATED. Please use the `post_get_goldengate_connection_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_get_odb_network` interceptor runs - before the `post_get_odb_network_with_metadata` interceptor. + it is returned to user code. This `post_get_goldengate_connection` interceptor runs + before the `post_get_goldengate_connection_with_metadata` interceptor. """ return response - def post_get_odb_network_with_metadata( + def post_get_goldengate_connection_with_metadata( self, - response: odb_network.OdbNetwork, + response: goldengate_connection.GoldengateConnection, metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[odb_network.OdbNetwork, Sequence[Tuple[str, Union[str, bytes]]]]: - """Post-rpc interceptor for get_odb_network + ) -> Tuple[ + goldengate_connection.GoldengateConnection, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for get_goldengate_connection Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_get_odb_network_with_metadata` - interceptor in new development instead of the `post_get_odb_network` interceptor. - When both interceptors are used, this `post_get_odb_network_with_metadata` interceptor runs after the - `post_get_odb_network` interceptor. The (possibly modified) response returned by - `post_get_odb_network` will be passed to - `post_get_odb_network_with_metadata`. + We recommend only using this `post_get_goldengate_connection_with_metadata` + interceptor in new development instead of the `post_get_goldengate_connection` interceptor. + When both interceptors are used, this `post_get_goldengate_connection_with_metadata` interceptor runs after the + `post_get_goldengate_connection` interceptor. The (possibly modified) response returned by + `post_get_goldengate_connection` will be passed to + `post_get_goldengate_connection_with_metadata`. """ return response, metadata - def pre_get_odb_subnet( + def pre_get_goldengate_connection_assignment( self, - request: odb_subnet.GetOdbSubnetRequest, + request: goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[odb_subnet.GetOdbSubnetRequest, Sequence[Tuple[str, Union[str, bytes]]]]: - """Pre-rpc interceptor for get_odb_subnet + ) -> Tuple[ + goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for get_goldengate_connection_assignment Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_get_odb_subnet( - self, response: odb_subnet.OdbSubnet - ) -> odb_subnet.OdbSubnet: - """Post-rpc interceptor for get_odb_subnet + def post_get_goldengate_connection_assignment( + self, response: goldengate_connection_assignment.GoldengateConnectionAssignment + ) -> goldengate_connection_assignment.GoldengateConnectionAssignment: + """Post-rpc interceptor for get_goldengate_connection_assignment - DEPRECATED. Please use the `post_get_odb_subnet_with_metadata` + DEPRECATED. Please use the `post_get_goldengate_connection_assignment_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_get_odb_subnet` interceptor runs - before the `post_get_odb_subnet_with_metadata` interceptor. + it is returned to user code. This `post_get_goldengate_connection_assignment` interceptor runs + before the `post_get_goldengate_connection_assignment_with_metadata` interceptor. """ return response - def post_get_odb_subnet_with_metadata( + def post_get_goldengate_connection_assignment_with_metadata( self, - response: odb_subnet.OdbSubnet, + response: goldengate_connection_assignment.GoldengateConnectionAssignment, metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[odb_subnet.OdbSubnet, Sequence[Tuple[str, Union[str, bytes]]]]: - """Post-rpc interceptor for get_odb_subnet + ) -> Tuple[ + goldengate_connection_assignment.GoldengateConnectionAssignment, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for get_goldengate_connection_assignment Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_get_odb_subnet_with_metadata` - interceptor in new development instead of the `post_get_odb_subnet` interceptor. - When both interceptors are used, this `post_get_odb_subnet_with_metadata` interceptor runs after the - `post_get_odb_subnet` interceptor. The (possibly modified) response returned by - `post_get_odb_subnet` will be passed to - `post_get_odb_subnet_with_metadata`. + We recommend only using this `post_get_goldengate_connection_assignment_with_metadata` + interceptor in new development instead of the `post_get_goldengate_connection_assignment` interceptor. + When both interceptors are used, this `post_get_goldengate_connection_assignment_with_metadata` interceptor runs after the + `post_get_goldengate_connection_assignment` interceptor. The (possibly modified) response returned by + `post_get_goldengate_connection_assignment` will be passed to + `post_get_goldengate_connection_assignment_with_metadata`. """ return response, metadata - def pre_get_pluggable_database( + def pre_get_goldengate_connection_type( self, - request: pluggable_database.GetPluggableDatabaseRequest, + request: goldengate_connection_type.GetGoldengateConnectionTypeRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - pluggable_database.GetPluggableDatabaseRequest, + goldengate_connection_type.GetGoldengateConnectionTypeRequest, Sequence[Tuple[str, Union[str, bytes]]], ]: - """Pre-rpc interceptor for get_pluggable_database + """Pre-rpc interceptor for get_goldengate_connection_type Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_get_pluggable_database( - self, response: pluggable_database.PluggableDatabase - ) -> pluggable_database.PluggableDatabase: - """Post-rpc interceptor for get_pluggable_database + def post_get_goldengate_connection_type( + self, response: goldengate_connection_type.GoldengateConnectionType + ) -> goldengate_connection_type.GoldengateConnectionType: + """Post-rpc interceptor for get_goldengate_connection_type - DEPRECATED. Please use the `post_get_pluggable_database_with_metadata` + DEPRECATED. Please use the `post_get_goldengate_connection_type_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_get_pluggable_database` interceptor runs - before the `post_get_pluggable_database_with_metadata` interceptor. + it is returned to user code. This `post_get_goldengate_connection_type` interceptor runs + before the `post_get_goldengate_connection_type_with_metadata` interceptor. """ return response - def post_get_pluggable_database_with_metadata( + def post_get_goldengate_connection_type_with_metadata( self, - response: pluggable_database.PluggableDatabase, + response: goldengate_connection_type.GoldengateConnectionType, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - pluggable_database.PluggableDatabase, Sequence[Tuple[str, Union[str, bytes]]] + goldengate_connection_type.GoldengateConnectionType, + Sequence[Tuple[str, Union[str, bytes]]], ]: - """Post-rpc interceptor for get_pluggable_database + """Post-rpc interceptor for get_goldengate_connection_type Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_get_pluggable_database_with_metadata` - interceptor in new development instead of the `post_get_pluggable_database` interceptor. - When both interceptors are used, this `post_get_pluggable_database_with_metadata` interceptor runs after the - `post_get_pluggable_database` interceptor. The (possibly modified) response returned by - `post_get_pluggable_database` will be passed to - `post_get_pluggable_database_with_metadata`. + We recommend only using this `post_get_goldengate_connection_type_with_metadata` + interceptor in new development instead of the `post_get_goldengate_connection_type` interceptor. + When both interceptors are used, this `post_get_goldengate_connection_type_with_metadata` interceptor runs after the + `post_get_goldengate_connection_type` interceptor. The (possibly modified) response returned by + `post_get_goldengate_connection_type` will be passed to + `post_get_goldengate_connection_type_with_metadata`. """ return response, metadata - def pre_list_autonomous_database_backups( + def pre_get_goldengate_deployment( self, - request: oracledatabase.ListAutonomousDatabaseBackupsRequest, + request: goldengate_deployment.GetGoldengateDeploymentRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - oracledatabase.ListAutonomousDatabaseBackupsRequest, + goldengate_deployment.GetGoldengateDeploymentRequest, Sequence[Tuple[str, Union[str, bytes]]], ]: - """Pre-rpc interceptor for list_autonomous_database_backups + """Pre-rpc interceptor for get_goldengate_deployment Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_list_autonomous_database_backups( - self, response: oracledatabase.ListAutonomousDatabaseBackupsResponse - ) -> oracledatabase.ListAutonomousDatabaseBackupsResponse: - """Post-rpc interceptor for list_autonomous_database_backups + def post_get_goldengate_deployment( + self, response: goldengate_deployment.GoldengateDeployment + ) -> goldengate_deployment.GoldengateDeployment: + """Post-rpc interceptor for get_goldengate_deployment - DEPRECATED. Please use the `post_list_autonomous_database_backups_with_metadata` + DEPRECATED. Please use the `post_get_goldengate_deployment_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_list_autonomous_database_backups` interceptor runs - before the `post_list_autonomous_database_backups_with_metadata` interceptor. + it is returned to user code. This `post_get_goldengate_deployment` interceptor runs + before the `post_get_goldengate_deployment_with_metadata` interceptor. """ return response - def post_list_autonomous_database_backups_with_metadata( + def post_get_goldengate_deployment_with_metadata( self, - response: oracledatabase.ListAutonomousDatabaseBackupsResponse, + response: goldengate_deployment.GoldengateDeployment, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - oracledatabase.ListAutonomousDatabaseBackupsResponse, + goldengate_deployment.GoldengateDeployment, Sequence[Tuple[str, Union[str, bytes]]], ]: - """Post-rpc interceptor for list_autonomous_database_backups + """Post-rpc interceptor for get_goldengate_deployment Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_list_autonomous_database_backups_with_metadata` - interceptor in new development instead of the `post_list_autonomous_database_backups` interceptor. - When both interceptors are used, this `post_list_autonomous_database_backups_with_metadata` interceptor runs after the - `post_list_autonomous_database_backups` interceptor. The (possibly modified) response returned by - `post_list_autonomous_database_backups` will be passed to - `post_list_autonomous_database_backups_with_metadata`. + We recommend only using this `post_get_goldengate_deployment_with_metadata` + interceptor in new development instead of the `post_get_goldengate_deployment` interceptor. + When both interceptors are used, this `post_get_goldengate_deployment_with_metadata` interceptor runs after the + `post_get_goldengate_deployment` interceptor. The (possibly modified) response returned by + `post_get_goldengate_deployment` will be passed to + `post_get_goldengate_deployment_with_metadata`. """ return response, metadata - def pre_list_autonomous_database_character_sets( + def pre_get_goldengate_deployment_environment( self, - request: oracledatabase.ListAutonomousDatabaseCharacterSetsRequest, + request: goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - oracledatabase.ListAutonomousDatabaseCharacterSetsRequest, + goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest, Sequence[Tuple[str, Union[str, bytes]]], ]: - """Pre-rpc interceptor for list_autonomous_database_character_sets + """Pre-rpc interceptor for get_goldengate_deployment_environment Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_list_autonomous_database_character_sets( - self, response: oracledatabase.ListAutonomousDatabaseCharacterSetsResponse - ) -> oracledatabase.ListAutonomousDatabaseCharacterSetsResponse: - """Post-rpc interceptor for list_autonomous_database_character_sets + def post_get_goldengate_deployment_environment( + self, + response: goldengate_deployment_environment.GoldengateDeploymentEnvironment, + ) -> goldengate_deployment_environment.GoldengateDeploymentEnvironment: + """Post-rpc interceptor for get_goldengate_deployment_environment - DEPRECATED. Please use the `post_list_autonomous_database_character_sets_with_metadata` + DEPRECATED. Please use the `post_get_goldengate_deployment_environment_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_list_autonomous_database_character_sets` interceptor runs - before the `post_list_autonomous_database_character_sets_with_metadata` interceptor. + it is returned to user code. This `post_get_goldengate_deployment_environment` interceptor runs + before the `post_get_goldengate_deployment_environment_with_metadata` interceptor. """ return response - def post_list_autonomous_database_character_sets_with_metadata( + def post_get_goldengate_deployment_environment_with_metadata( self, - response: oracledatabase.ListAutonomousDatabaseCharacterSetsResponse, + response: goldengate_deployment_environment.GoldengateDeploymentEnvironment, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - oracledatabase.ListAutonomousDatabaseCharacterSetsResponse, + goldengate_deployment_environment.GoldengateDeploymentEnvironment, Sequence[Tuple[str, Union[str, bytes]]], ]: - """Post-rpc interceptor for list_autonomous_database_character_sets + """Post-rpc interceptor for get_goldengate_deployment_environment Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_list_autonomous_database_character_sets_with_metadata` - interceptor in new development instead of the `post_list_autonomous_database_character_sets` interceptor. - When both interceptors are used, this `post_list_autonomous_database_character_sets_with_metadata` interceptor runs after the - `post_list_autonomous_database_character_sets` interceptor. The (possibly modified) response returned by - `post_list_autonomous_database_character_sets` will be passed to - `post_list_autonomous_database_character_sets_with_metadata`. + We recommend only using this `post_get_goldengate_deployment_environment_with_metadata` + interceptor in new development instead of the `post_get_goldengate_deployment_environment` interceptor. + When both interceptors are used, this `post_get_goldengate_deployment_environment_with_metadata` interceptor runs after the + `post_get_goldengate_deployment_environment` interceptor. The (possibly modified) response returned by + `post_get_goldengate_deployment_environment` will be passed to + `post_get_goldengate_deployment_environment_with_metadata`. """ return response, metadata - def pre_list_autonomous_databases( + def pre_get_goldengate_deployment_type( self, - request: oracledatabase.ListAutonomousDatabasesRequest, + request: goldengate_deployment_type.GetGoldengateDeploymentTypeRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - oracledatabase.ListAutonomousDatabasesRequest, + goldengate_deployment_type.GetGoldengateDeploymentTypeRequest, Sequence[Tuple[str, Union[str, bytes]]], ]: - """Pre-rpc interceptor for list_autonomous_databases + """Pre-rpc interceptor for get_goldengate_deployment_type Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_list_autonomous_databases( - self, response: oracledatabase.ListAutonomousDatabasesResponse - ) -> oracledatabase.ListAutonomousDatabasesResponse: - """Post-rpc interceptor for list_autonomous_databases + def post_get_goldengate_deployment_type( + self, response: goldengate_deployment_type.GoldengateDeploymentType + ) -> goldengate_deployment_type.GoldengateDeploymentType: + """Post-rpc interceptor for get_goldengate_deployment_type - DEPRECATED. Please use the `post_list_autonomous_databases_with_metadata` + DEPRECATED. Please use the `post_get_goldengate_deployment_type_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_list_autonomous_databases` interceptor runs - before the `post_list_autonomous_databases_with_metadata` interceptor. + it is returned to user code. This `post_get_goldengate_deployment_type` interceptor runs + before the `post_get_goldengate_deployment_type_with_metadata` interceptor. """ return response - def post_list_autonomous_databases_with_metadata( + def post_get_goldengate_deployment_type_with_metadata( self, - response: oracledatabase.ListAutonomousDatabasesResponse, + response: goldengate_deployment_type.GoldengateDeploymentType, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - oracledatabase.ListAutonomousDatabasesResponse, + goldengate_deployment_type.GoldengateDeploymentType, Sequence[Tuple[str, Union[str, bytes]]], ]: - """Post-rpc interceptor for list_autonomous_databases + """Post-rpc interceptor for get_goldengate_deployment_type Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_list_autonomous_databases_with_metadata` - interceptor in new development instead of the `post_list_autonomous_databases` interceptor. - When both interceptors are used, this `post_list_autonomous_databases_with_metadata` interceptor runs after the - `post_list_autonomous_databases` interceptor. The (possibly modified) response returned by - `post_list_autonomous_databases` will be passed to - `post_list_autonomous_databases_with_metadata`. + We recommend only using this `post_get_goldengate_deployment_type_with_metadata` + interceptor in new development instead of the `post_get_goldengate_deployment_type` interceptor. + When both interceptors are used, this `post_get_goldengate_deployment_type_with_metadata` interceptor runs after the + `post_get_goldengate_deployment_type` interceptor. The (possibly modified) response returned by + `post_get_goldengate_deployment_type` will be passed to + `post_get_goldengate_deployment_type_with_metadata`. """ return response, metadata - def pre_list_autonomous_db_versions( + def pre_get_goldengate_deployment_version( self, - request: oracledatabase.ListAutonomousDbVersionsRequest, + request: goldengate_deployment_version.GetGoldengateDeploymentVersionRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - oracledatabase.ListAutonomousDbVersionsRequest, + goldengate_deployment_version.GetGoldengateDeploymentVersionRequest, Sequence[Tuple[str, Union[str, bytes]]], ]: - """Pre-rpc interceptor for list_autonomous_db_versions + """Pre-rpc interceptor for get_goldengate_deployment_version Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_list_autonomous_db_versions( - self, response: oracledatabase.ListAutonomousDbVersionsResponse - ) -> oracledatabase.ListAutonomousDbVersionsResponse: - """Post-rpc interceptor for list_autonomous_db_versions + def post_get_goldengate_deployment_version( + self, response: goldengate_deployment_version.GoldengateDeploymentVersion + ) -> goldengate_deployment_version.GoldengateDeploymentVersion: + """Post-rpc interceptor for get_goldengate_deployment_version - DEPRECATED. Please use the `post_list_autonomous_db_versions_with_metadata` + DEPRECATED. Please use the `post_get_goldengate_deployment_version_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_list_autonomous_db_versions` interceptor runs - before the `post_list_autonomous_db_versions_with_metadata` interceptor. + it is returned to user code. This `post_get_goldengate_deployment_version` interceptor runs + before the `post_get_goldengate_deployment_version_with_metadata` interceptor. """ return response - def post_list_autonomous_db_versions_with_metadata( + def post_get_goldengate_deployment_version_with_metadata( self, - response: oracledatabase.ListAutonomousDbVersionsResponse, + response: goldengate_deployment_version.GoldengateDeploymentVersion, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - oracledatabase.ListAutonomousDbVersionsResponse, + goldengate_deployment_version.GoldengateDeploymentVersion, Sequence[Tuple[str, Union[str, bytes]]], ]: - """Post-rpc interceptor for list_autonomous_db_versions + """Post-rpc interceptor for get_goldengate_deployment_version Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_list_autonomous_db_versions_with_metadata` - interceptor in new development instead of the `post_list_autonomous_db_versions` interceptor. - When both interceptors are used, this `post_list_autonomous_db_versions_with_metadata` interceptor runs after the - `post_list_autonomous_db_versions` interceptor. The (possibly modified) response returned by - `post_list_autonomous_db_versions` will be passed to - `post_list_autonomous_db_versions_with_metadata`. + We recommend only using this `post_get_goldengate_deployment_version_with_metadata` + interceptor in new development instead of the `post_get_goldengate_deployment_version` interceptor. + When both interceptors are used, this `post_get_goldengate_deployment_version_with_metadata` interceptor runs after the + `post_get_goldengate_deployment_version` interceptor. The (possibly modified) response returned by + `post_get_goldengate_deployment_version` will be passed to + `post_get_goldengate_deployment_version_with_metadata`. """ return response, metadata - def pre_list_cloud_exadata_infrastructures( + def pre_get_odb_network( self, - request: oracledatabase.ListCloudExadataInfrastructuresRequest, + request: odb_network.GetOdbNetworkRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - oracledatabase.ListCloudExadataInfrastructuresRequest, - Sequence[Tuple[str, Union[str, bytes]]], + odb_network.GetOdbNetworkRequest, Sequence[Tuple[str, Union[str, bytes]]] ]: - """Pre-rpc interceptor for list_cloud_exadata_infrastructures + """Pre-rpc interceptor for get_odb_network Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_list_cloud_exadata_infrastructures( - self, response: oracledatabase.ListCloudExadataInfrastructuresResponse - ) -> oracledatabase.ListCloudExadataInfrastructuresResponse: - """Post-rpc interceptor for list_cloud_exadata_infrastructures + def post_get_odb_network( + self, response: odb_network.OdbNetwork + ) -> odb_network.OdbNetwork: + """Post-rpc interceptor for get_odb_network - DEPRECATED. Please use the `post_list_cloud_exadata_infrastructures_with_metadata` + DEPRECATED. Please use the `post_get_odb_network_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_list_cloud_exadata_infrastructures` interceptor runs - before the `post_list_cloud_exadata_infrastructures_with_metadata` interceptor. + it is returned to user code. This `post_get_odb_network` interceptor runs + before the `post_get_odb_network_with_metadata` interceptor. """ return response - def post_list_cloud_exadata_infrastructures_with_metadata( + def post_get_odb_network_with_metadata( self, - response: oracledatabase.ListCloudExadataInfrastructuresResponse, + response: odb_network.OdbNetwork, metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[ - oracledatabase.ListCloudExadataInfrastructuresResponse, - Sequence[Tuple[str, Union[str, bytes]]], - ]: - """Post-rpc interceptor for list_cloud_exadata_infrastructures + ) -> Tuple[odb_network.OdbNetwork, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_odb_network Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_list_cloud_exadata_infrastructures_with_metadata` - interceptor in new development instead of the `post_list_cloud_exadata_infrastructures` interceptor. - When both interceptors are used, this `post_list_cloud_exadata_infrastructures_with_metadata` interceptor runs after the - `post_list_cloud_exadata_infrastructures` interceptor. The (possibly modified) response returned by - `post_list_cloud_exadata_infrastructures` will be passed to - `post_list_cloud_exadata_infrastructures_with_metadata`. + We recommend only using this `post_get_odb_network_with_metadata` + interceptor in new development instead of the `post_get_odb_network` interceptor. + When both interceptors are used, this `post_get_odb_network_with_metadata` interceptor runs after the + `post_get_odb_network` interceptor. The (possibly modified) response returned by + `post_get_odb_network` will be passed to + `post_get_odb_network_with_metadata`. """ return response, metadata - def pre_list_cloud_vm_clusters( + def pre_get_odb_subnet( self, - request: oracledatabase.ListCloudVmClustersRequest, + request: odb_subnet.GetOdbSubnetRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[ - oracledatabase.ListCloudVmClustersRequest, - Sequence[Tuple[str, Union[str, bytes]]], - ]: - """Pre-rpc interceptor for list_cloud_vm_clusters + ) -> Tuple[odb_subnet.GetOdbSubnetRequest, Sequence[Tuple[str, Union[str, bytes]]]]: + """Pre-rpc interceptor for get_odb_subnet Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_list_cloud_vm_clusters( - self, response: oracledatabase.ListCloudVmClustersResponse - ) -> oracledatabase.ListCloudVmClustersResponse: - """Post-rpc interceptor for list_cloud_vm_clusters + def post_get_odb_subnet( + self, response: odb_subnet.OdbSubnet + ) -> odb_subnet.OdbSubnet: + """Post-rpc interceptor for get_odb_subnet - DEPRECATED. Please use the `post_list_cloud_vm_clusters_with_metadata` + DEPRECATED. Please use the `post_get_odb_subnet_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_list_cloud_vm_clusters` interceptor runs - before the `post_list_cloud_vm_clusters_with_metadata` interceptor. + it is returned to user code. This `post_get_odb_subnet` interceptor runs + before the `post_get_odb_subnet_with_metadata` interceptor. """ return response - def post_list_cloud_vm_clusters_with_metadata( + def post_get_odb_subnet_with_metadata( self, - response: oracledatabase.ListCloudVmClustersResponse, + response: odb_subnet.OdbSubnet, metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[ - oracledatabase.ListCloudVmClustersResponse, - Sequence[Tuple[str, Union[str, bytes]]], - ]: - """Post-rpc interceptor for list_cloud_vm_clusters + ) -> Tuple[odb_subnet.OdbSubnet, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_odb_subnet Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_list_cloud_vm_clusters_with_metadata` - interceptor in new development instead of the `post_list_cloud_vm_clusters` interceptor. - When both interceptors are used, this `post_list_cloud_vm_clusters_with_metadata` interceptor runs after the - `post_list_cloud_vm_clusters` interceptor. The (possibly modified) response returned by - `post_list_cloud_vm_clusters` will be passed to - `post_list_cloud_vm_clusters_with_metadata`. + We recommend only using this `post_get_odb_subnet_with_metadata` + interceptor in new development instead of the `post_get_odb_subnet` interceptor. + When both interceptors are used, this `post_get_odb_subnet_with_metadata` interceptor runs after the + `post_get_odb_subnet` interceptor. The (possibly modified) response returned by + `post_get_odb_subnet` will be passed to + `post_get_odb_subnet_with_metadata`. """ return response, metadata - def pre_list_database_character_sets( + def pre_get_pluggable_database( self, - request: database_character_set.ListDatabaseCharacterSetsRequest, + request: pluggable_database.GetPluggableDatabaseRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - database_character_set.ListDatabaseCharacterSetsRequest, + pluggable_database.GetPluggableDatabaseRequest, Sequence[Tuple[str, Union[str, bytes]]], ]: - """Pre-rpc interceptor for list_database_character_sets + """Pre-rpc interceptor for get_pluggable_database Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_list_database_character_sets( - self, response: database_character_set.ListDatabaseCharacterSetsResponse - ) -> database_character_set.ListDatabaseCharacterSetsResponse: - """Post-rpc interceptor for list_database_character_sets + def post_get_pluggable_database( + self, response: pluggable_database.PluggableDatabase + ) -> pluggable_database.PluggableDatabase: + """Post-rpc interceptor for get_pluggable_database - DEPRECATED. Please use the `post_list_database_character_sets_with_metadata` + DEPRECATED. Please use the `post_get_pluggable_database_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_list_database_character_sets` interceptor runs - before the `post_list_database_character_sets_with_metadata` interceptor. + it is returned to user code. This `post_get_pluggable_database` interceptor runs + before the `post_get_pluggable_database_with_metadata` interceptor. """ return response - def post_list_database_character_sets_with_metadata( + def post_get_pluggable_database_with_metadata( self, - response: database_character_set.ListDatabaseCharacterSetsResponse, + response: pluggable_database.PluggableDatabase, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - database_character_set.ListDatabaseCharacterSetsResponse, - Sequence[Tuple[str, Union[str, bytes]]], + pluggable_database.PluggableDatabase, Sequence[Tuple[str, Union[str, bytes]]] ]: - """Post-rpc interceptor for list_database_character_sets + """Post-rpc interceptor for get_pluggable_database Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_list_database_character_sets_with_metadata` - interceptor in new development instead of the `post_list_database_character_sets` interceptor. - When both interceptors are used, this `post_list_database_character_sets_with_metadata` interceptor runs after the - `post_list_database_character_sets` interceptor. The (possibly modified) response returned by - `post_list_database_character_sets` will be passed to - `post_list_database_character_sets_with_metadata`. + We recommend only using this `post_get_pluggable_database_with_metadata` + interceptor in new development instead of the `post_get_pluggable_database` interceptor. + When both interceptors are used, this `post_get_pluggable_database_with_metadata` interceptor runs after the + `post_get_pluggable_database` interceptor. The (possibly modified) response returned by + `post_get_pluggable_database` will be passed to + `post_get_pluggable_database_with_metadata`. """ return response, metadata - def pre_list_databases( + def pre_list_autonomous_database_backups( self, - request: database.ListDatabasesRequest, + request: oracledatabase.ListAutonomousDatabaseBackupsRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[database.ListDatabasesRequest, Sequence[Tuple[str, Union[str, bytes]]]]: - """Pre-rpc interceptor for list_databases + ) -> Tuple[ + oracledatabase.ListAutonomousDatabaseBackupsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for list_autonomous_database_backups Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_list_databases( - self, response: database.ListDatabasesResponse - ) -> database.ListDatabasesResponse: - """Post-rpc interceptor for list_databases + def post_list_autonomous_database_backups( + self, response: oracledatabase.ListAutonomousDatabaseBackupsResponse + ) -> oracledatabase.ListAutonomousDatabaseBackupsResponse: + """Post-rpc interceptor for list_autonomous_database_backups - DEPRECATED. Please use the `post_list_databases_with_metadata` + DEPRECATED. Please use the `post_list_autonomous_database_backups_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_list_databases` interceptor runs - before the `post_list_databases_with_metadata` interceptor. + it is returned to user code. This `post_list_autonomous_database_backups` interceptor runs + before the `post_list_autonomous_database_backups_with_metadata` interceptor. """ return response - def post_list_databases_with_metadata( + def post_list_autonomous_database_backups_with_metadata( self, - response: database.ListDatabasesResponse, + response: oracledatabase.ListAutonomousDatabaseBackupsResponse, metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[database.ListDatabasesResponse, Sequence[Tuple[str, Union[str, bytes]]]]: - """Post-rpc interceptor for list_databases + ) -> Tuple[ + oracledatabase.ListAutonomousDatabaseBackupsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_autonomous_database_backups Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_list_databases_with_metadata` - interceptor in new development instead of the `post_list_databases` interceptor. - When both interceptors are used, this `post_list_databases_with_metadata` interceptor runs after the - `post_list_databases` interceptor. The (possibly modified) response returned by - `post_list_databases` will be passed to - `post_list_databases_with_metadata`. + We recommend only using this `post_list_autonomous_database_backups_with_metadata` + interceptor in new development instead of the `post_list_autonomous_database_backups` interceptor. + When both interceptors are used, this `post_list_autonomous_database_backups_with_metadata` interceptor runs after the + `post_list_autonomous_database_backups` interceptor. The (possibly modified) response returned by + `post_list_autonomous_database_backups` will be passed to + `post_list_autonomous_database_backups_with_metadata`. """ return response, metadata - def pre_list_db_nodes( + def pre_list_autonomous_database_character_sets( self, - request: oracledatabase.ListDbNodesRequest, + request: oracledatabase.ListAutonomousDatabaseCharacterSetsRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - oracledatabase.ListDbNodesRequest, Sequence[Tuple[str, Union[str, bytes]]] + oracledatabase.ListAutonomousDatabaseCharacterSetsRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: - """Pre-rpc interceptor for list_db_nodes + """Pre-rpc interceptor for list_autonomous_database_character_sets Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_list_db_nodes( - self, response: oracledatabase.ListDbNodesResponse - ) -> oracledatabase.ListDbNodesResponse: - """Post-rpc interceptor for list_db_nodes + def post_list_autonomous_database_character_sets( + self, response: oracledatabase.ListAutonomousDatabaseCharacterSetsResponse + ) -> oracledatabase.ListAutonomousDatabaseCharacterSetsResponse: + """Post-rpc interceptor for list_autonomous_database_character_sets - DEPRECATED. Please use the `post_list_db_nodes_with_metadata` + DEPRECATED. Please use the `post_list_autonomous_database_character_sets_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_list_db_nodes` interceptor runs - before the `post_list_db_nodes_with_metadata` interceptor. + it is returned to user code. This `post_list_autonomous_database_character_sets` interceptor runs + before the `post_list_autonomous_database_character_sets_with_metadata` interceptor. """ return response - def post_list_db_nodes_with_metadata( + def post_list_autonomous_database_character_sets_with_metadata( self, - response: oracledatabase.ListDbNodesResponse, + response: oracledatabase.ListAutonomousDatabaseCharacterSetsResponse, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - oracledatabase.ListDbNodesResponse, Sequence[Tuple[str, Union[str, bytes]]] + oracledatabase.ListAutonomousDatabaseCharacterSetsResponse, + Sequence[Tuple[str, Union[str, bytes]]], ]: - """Post-rpc interceptor for list_db_nodes + """Post-rpc interceptor for list_autonomous_database_character_sets Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_list_db_nodes_with_metadata` - interceptor in new development instead of the `post_list_db_nodes` interceptor. - When both interceptors are used, this `post_list_db_nodes_with_metadata` interceptor runs after the - `post_list_db_nodes` interceptor. The (possibly modified) response returned by - `post_list_db_nodes` will be passed to - `post_list_db_nodes_with_metadata`. + We recommend only using this `post_list_autonomous_database_character_sets_with_metadata` + interceptor in new development instead of the `post_list_autonomous_database_character_sets` interceptor. + When both interceptors are used, this `post_list_autonomous_database_character_sets_with_metadata` interceptor runs after the + `post_list_autonomous_database_character_sets` interceptor. The (possibly modified) response returned by + `post_list_autonomous_database_character_sets` will be passed to + `post_list_autonomous_database_character_sets_with_metadata`. """ return response, metadata - def pre_list_db_servers( + def pre_list_autonomous_databases( self, - request: oracledatabase.ListDbServersRequest, + request: oracledatabase.ListAutonomousDatabasesRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - oracledatabase.ListDbServersRequest, Sequence[Tuple[str, Union[str, bytes]]] + oracledatabase.ListAutonomousDatabasesRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: - """Pre-rpc interceptor for list_db_servers + """Pre-rpc interceptor for list_autonomous_databases Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_list_db_servers( - self, response: oracledatabase.ListDbServersResponse - ) -> oracledatabase.ListDbServersResponse: - """Post-rpc interceptor for list_db_servers - - DEPRECATED. Please use the `post_list_db_servers_with_metadata` + def post_list_autonomous_databases( + self, response: oracledatabase.ListAutonomousDatabasesResponse + ) -> oracledatabase.ListAutonomousDatabasesResponse: + """Post-rpc interceptor for list_autonomous_databases + + DEPRECATED. Please use the `post_list_autonomous_databases_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_list_db_servers` interceptor runs - before the `post_list_db_servers_with_metadata` interceptor. + it is returned to user code. This `post_list_autonomous_databases` interceptor runs + before the `post_list_autonomous_databases_with_metadata` interceptor. """ return response - def post_list_db_servers_with_metadata( + def post_list_autonomous_databases_with_metadata( self, - response: oracledatabase.ListDbServersResponse, + response: oracledatabase.ListAutonomousDatabasesResponse, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - oracledatabase.ListDbServersResponse, Sequence[Tuple[str, Union[str, bytes]]] + oracledatabase.ListAutonomousDatabasesResponse, + Sequence[Tuple[str, Union[str, bytes]]], ]: - """Post-rpc interceptor for list_db_servers + """Post-rpc interceptor for list_autonomous_databases Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_list_db_servers_with_metadata` - interceptor in new development instead of the `post_list_db_servers` interceptor. - When both interceptors are used, this `post_list_db_servers_with_metadata` interceptor runs after the - `post_list_db_servers` interceptor. The (possibly modified) response returned by - `post_list_db_servers` will be passed to - `post_list_db_servers_with_metadata`. + We recommend only using this `post_list_autonomous_databases_with_metadata` + interceptor in new development instead of the `post_list_autonomous_databases` interceptor. + When both interceptors are used, this `post_list_autonomous_databases_with_metadata` interceptor runs after the + `post_list_autonomous_databases` interceptor. The (possibly modified) response returned by + `post_list_autonomous_databases` will be passed to + `post_list_autonomous_databases_with_metadata`. """ return response, metadata - def pre_list_db_system_initial_storage_sizes( + def pre_list_autonomous_db_versions( self, - request: db_system_initial_storage_size.ListDbSystemInitialStorageSizesRequest, + request: oracledatabase.ListAutonomousDbVersionsRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - db_system_initial_storage_size.ListDbSystemInitialStorageSizesRequest, + oracledatabase.ListAutonomousDbVersionsRequest, Sequence[Tuple[str, Union[str, bytes]]], ]: - """Pre-rpc interceptor for list_db_system_initial_storage_sizes + """Pre-rpc interceptor for list_autonomous_db_versions Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_list_db_system_initial_storage_sizes( - self, - response: db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse, - ) -> db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse: - """Post-rpc interceptor for list_db_system_initial_storage_sizes + def post_list_autonomous_db_versions( + self, response: oracledatabase.ListAutonomousDbVersionsResponse + ) -> oracledatabase.ListAutonomousDbVersionsResponse: + """Post-rpc interceptor for list_autonomous_db_versions - DEPRECATED. Please use the `post_list_db_system_initial_storage_sizes_with_metadata` + DEPRECATED. Please use the `post_list_autonomous_db_versions_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_list_db_system_initial_storage_sizes` interceptor runs - before the `post_list_db_system_initial_storage_sizes_with_metadata` interceptor. + it is returned to user code. This `post_list_autonomous_db_versions` interceptor runs + before the `post_list_autonomous_db_versions_with_metadata` interceptor. """ return response - def post_list_db_system_initial_storage_sizes_with_metadata( + def post_list_autonomous_db_versions_with_metadata( self, - response: db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse, + response: oracledatabase.ListAutonomousDbVersionsResponse, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse, + oracledatabase.ListAutonomousDbVersionsResponse, Sequence[Tuple[str, Union[str, bytes]]], ]: - """Post-rpc interceptor for list_db_system_initial_storage_sizes + """Post-rpc interceptor for list_autonomous_db_versions Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_list_db_system_initial_storage_sizes_with_metadata` - interceptor in new development instead of the `post_list_db_system_initial_storage_sizes` interceptor. - When both interceptors are used, this `post_list_db_system_initial_storage_sizes_with_metadata` interceptor runs after the - `post_list_db_system_initial_storage_sizes` interceptor. The (possibly modified) response returned by - `post_list_db_system_initial_storage_sizes` will be passed to - `post_list_db_system_initial_storage_sizes_with_metadata`. + We recommend only using this `post_list_autonomous_db_versions_with_metadata` + interceptor in new development instead of the `post_list_autonomous_db_versions` interceptor. + When both interceptors are used, this `post_list_autonomous_db_versions_with_metadata` interceptor runs after the + `post_list_autonomous_db_versions` interceptor. The (possibly modified) response returned by + `post_list_autonomous_db_versions` will be passed to + `post_list_autonomous_db_versions_with_metadata`. """ return response, metadata - def pre_list_db_systems( + def pre_list_cloud_exadata_infrastructures( self, - request: db_system.ListDbSystemsRequest, + request: oracledatabase.ListCloudExadataInfrastructuresRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[db_system.ListDbSystemsRequest, Sequence[Tuple[str, Union[str, bytes]]]]: - """Pre-rpc interceptor for list_db_systems + ) -> Tuple[ + oracledatabase.ListCloudExadataInfrastructuresRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for list_cloud_exadata_infrastructures Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_list_db_systems( - self, response: db_system.ListDbSystemsResponse - ) -> db_system.ListDbSystemsResponse: - """Post-rpc interceptor for list_db_systems + def post_list_cloud_exadata_infrastructures( + self, response: oracledatabase.ListCloudExadataInfrastructuresResponse + ) -> oracledatabase.ListCloudExadataInfrastructuresResponse: + """Post-rpc interceptor for list_cloud_exadata_infrastructures - DEPRECATED. Please use the `post_list_db_systems_with_metadata` + DEPRECATED. Please use the `post_list_cloud_exadata_infrastructures_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_list_db_systems` interceptor runs - before the `post_list_db_systems_with_metadata` interceptor. + it is returned to user code. This `post_list_cloud_exadata_infrastructures` interceptor runs + before the `post_list_cloud_exadata_infrastructures_with_metadata` interceptor. """ return response - def post_list_db_systems_with_metadata( + def post_list_cloud_exadata_infrastructures_with_metadata( self, - response: db_system.ListDbSystemsResponse, + response: oracledatabase.ListCloudExadataInfrastructuresResponse, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - db_system.ListDbSystemsResponse, Sequence[Tuple[str, Union[str, bytes]]] + oracledatabase.ListCloudExadataInfrastructuresResponse, + Sequence[Tuple[str, Union[str, bytes]]], ]: - """Post-rpc interceptor for list_db_systems + """Post-rpc interceptor for list_cloud_exadata_infrastructures Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_list_db_systems_with_metadata` - interceptor in new development instead of the `post_list_db_systems` interceptor. - When both interceptors are used, this `post_list_db_systems_with_metadata` interceptor runs after the - `post_list_db_systems` interceptor. The (possibly modified) response returned by - `post_list_db_systems` will be passed to - `post_list_db_systems_with_metadata`. + We recommend only using this `post_list_cloud_exadata_infrastructures_with_metadata` + interceptor in new development instead of the `post_list_cloud_exadata_infrastructures` interceptor. + When both interceptors are used, this `post_list_cloud_exadata_infrastructures_with_metadata` interceptor runs after the + `post_list_cloud_exadata_infrastructures` interceptor. The (possibly modified) response returned by + `post_list_cloud_exadata_infrastructures` will be passed to + `post_list_cloud_exadata_infrastructures_with_metadata`. """ return response, metadata - def pre_list_db_system_shapes( + def pre_list_cloud_vm_clusters( self, - request: oracledatabase.ListDbSystemShapesRequest, + request: oracledatabase.ListCloudVmClustersRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - oracledatabase.ListDbSystemShapesRequest, + oracledatabase.ListCloudVmClustersRequest, Sequence[Tuple[str, Union[str, bytes]]], ]: - """Pre-rpc interceptor for list_db_system_shapes + """Pre-rpc interceptor for list_cloud_vm_clusters Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_list_db_system_shapes( - self, response: oracledatabase.ListDbSystemShapesResponse - ) -> oracledatabase.ListDbSystemShapesResponse: - """Post-rpc interceptor for list_db_system_shapes + def post_list_cloud_vm_clusters( + self, response: oracledatabase.ListCloudVmClustersResponse + ) -> oracledatabase.ListCloudVmClustersResponse: + """Post-rpc interceptor for list_cloud_vm_clusters - DEPRECATED. Please use the `post_list_db_system_shapes_with_metadata` + DEPRECATED. Please use the `post_list_cloud_vm_clusters_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_list_db_system_shapes` interceptor runs - before the `post_list_db_system_shapes_with_metadata` interceptor. + it is returned to user code. This `post_list_cloud_vm_clusters` interceptor runs + before the `post_list_cloud_vm_clusters_with_metadata` interceptor. """ return response - def post_list_db_system_shapes_with_metadata( + def post_list_cloud_vm_clusters_with_metadata( self, - response: oracledatabase.ListDbSystemShapesResponse, + response: oracledatabase.ListCloudVmClustersResponse, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - oracledatabase.ListDbSystemShapesResponse, + oracledatabase.ListCloudVmClustersResponse, Sequence[Tuple[str, Union[str, bytes]]], ]: - """Post-rpc interceptor for list_db_system_shapes + """Post-rpc interceptor for list_cloud_vm_clusters Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_list_db_system_shapes_with_metadata` - interceptor in new development instead of the `post_list_db_system_shapes` interceptor. - When both interceptors are used, this `post_list_db_system_shapes_with_metadata` interceptor runs after the - `post_list_db_system_shapes` interceptor. The (possibly modified) response returned by - `post_list_db_system_shapes` will be passed to - `post_list_db_system_shapes_with_metadata`. + We recommend only using this `post_list_cloud_vm_clusters_with_metadata` + interceptor in new development instead of the `post_list_cloud_vm_clusters` interceptor. + When both interceptors are used, this `post_list_cloud_vm_clusters_with_metadata` interceptor runs after the + `post_list_cloud_vm_clusters` interceptor. The (possibly modified) response returned by + `post_list_cloud_vm_clusters` will be passed to + `post_list_cloud_vm_clusters_with_metadata`. """ return response, metadata - def pre_list_db_versions( + def pre_list_database_character_sets( self, - request: db_version.ListDbVersionsRequest, + request: database_character_set.ListDatabaseCharacterSetsRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - db_version.ListDbVersionsRequest, Sequence[Tuple[str, Union[str, bytes]]] + database_character_set.ListDatabaseCharacterSetsRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: - """Pre-rpc interceptor for list_db_versions + """Pre-rpc interceptor for list_database_character_sets Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_list_db_versions( - self, response: db_version.ListDbVersionsResponse - ) -> db_version.ListDbVersionsResponse: - """Post-rpc interceptor for list_db_versions + def post_list_database_character_sets( + self, response: database_character_set.ListDatabaseCharacterSetsResponse + ) -> database_character_set.ListDatabaseCharacterSetsResponse: + """Post-rpc interceptor for list_database_character_sets - DEPRECATED. Please use the `post_list_db_versions_with_metadata` + DEPRECATED. Please use the `post_list_database_character_sets_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_list_db_versions` interceptor runs - before the `post_list_db_versions_with_metadata` interceptor. + it is returned to user code. This `post_list_database_character_sets` interceptor runs + before the `post_list_database_character_sets_with_metadata` interceptor. """ return response - def post_list_db_versions_with_metadata( + def post_list_database_character_sets_with_metadata( self, - response: db_version.ListDbVersionsResponse, + response: database_character_set.ListDatabaseCharacterSetsResponse, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - db_version.ListDbVersionsResponse, Sequence[Tuple[str, Union[str, bytes]]] + database_character_set.ListDatabaseCharacterSetsResponse, + Sequence[Tuple[str, Union[str, bytes]]], ]: - """Post-rpc interceptor for list_db_versions + """Post-rpc interceptor for list_database_character_sets Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_list_db_versions_with_metadata` - interceptor in new development instead of the `post_list_db_versions` interceptor. - When both interceptors are used, this `post_list_db_versions_with_metadata` interceptor runs after the - `post_list_db_versions` interceptor. The (possibly modified) response returned by - `post_list_db_versions` will be passed to - `post_list_db_versions_with_metadata`. + We recommend only using this `post_list_database_character_sets_with_metadata` + interceptor in new development instead of the `post_list_database_character_sets` interceptor. + When both interceptors are used, this `post_list_database_character_sets_with_metadata` interceptor runs after the + `post_list_database_character_sets` interceptor. The (possibly modified) response returned by + `post_list_database_character_sets` will be passed to + `post_list_database_character_sets_with_metadata`. """ return response, metadata - def pre_list_entitlements( + def pre_list_databases( self, - request: oracledatabase.ListEntitlementsRequest, + request: database.ListDatabasesRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[ - oracledatabase.ListEntitlementsRequest, Sequence[Tuple[str, Union[str, bytes]]] - ]: - """Pre-rpc interceptor for list_entitlements + ) -> Tuple[database.ListDatabasesRequest, Sequence[Tuple[str, Union[str, bytes]]]]: + """Pre-rpc interceptor for list_databases Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_list_entitlements( - self, response: oracledatabase.ListEntitlementsResponse - ) -> oracledatabase.ListEntitlementsResponse: - """Post-rpc interceptor for list_entitlements + def post_list_databases( + self, response: database.ListDatabasesResponse + ) -> database.ListDatabasesResponse: + """Post-rpc interceptor for list_databases - DEPRECATED. Please use the `post_list_entitlements_with_metadata` + DEPRECATED. Please use the `post_list_databases_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_list_entitlements` interceptor runs - before the `post_list_entitlements_with_metadata` interceptor. + it is returned to user code. This `post_list_databases` interceptor runs + before the `post_list_databases_with_metadata` interceptor. """ return response - def post_list_entitlements_with_metadata( + def post_list_databases_with_metadata( self, - response: oracledatabase.ListEntitlementsResponse, + response: database.ListDatabasesResponse, metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[ - oracledatabase.ListEntitlementsResponse, Sequence[Tuple[str, Union[str, bytes]]] - ]: - """Post-rpc interceptor for list_entitlements + ) -> Tuple[database.ListDatabasesResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_databases Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_list_entitlements_with_metadata` - interceptor in new development instead of the `post_list_entitlements` interceptor. - When both interceptors are used, this `post_list_entitlements_with_metadata` interceptor runs after the - `post_list_entitlements` interceptor. The (possibly modified) response returned by - `post_list_entitlements` will be passed to - `post_list_entitlements_with_metadata`. + We recommend only using this `post_list_databases_with_metadata` + interceptor in new development instead of the `post_list_databases` interceptor. + When both interceptors are used, this `post_list_databases_with_metadata` interceptor runs after the + `post_list_databases` interceptor. The (possibly modified) response returned by + `post_list_databases` will be passed to + `post_list_databases_with_metadata`. """ return response, metadata - def pre_list_exadb_vm_clusters( + def pre_list_db_nodes( self, - request: oracledatabase.ListExadbVmClustersRequest, + request: oracledatabase.ListDbNodesRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - oracledatabase.ListExadbVmClustersRequest, - Sequence[Tuple[str, Union[str, bytes]]], + oracledatabase.ListDbNodesRequest, Sequence[Tuple[str, Union[str, bytes]]] ]: - """Pre-rpc interceptor for list_exadb_vm_clusters + """Pre-rpc interceptor for list_db_nodes Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_list_exadb_vm_clusters( - self, response: oracledatabase.ListExadbVmClustersResponse - ) -> oracledatabase.ListExadbVmClustersResponse: - """Post-rpc interceptor for list_exadb_vm_clusters + def post_list_db_nodes( + self, response: oracledatabase.ListDbNodesResponse + ) -> oracledatabase.ListDbNodesResponse: + """Post-rpc interceptor for list_db_nodes - DEPRECATED. Please use the `post_list_exadb_vm_clusters_with_metadata` + DEPRECATED. Please use the `post_list_db_nodes_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_list_exadb_vm_clusters` interceptor runs - before the `post_list_exadb_vm_clusters_with_metadata` interceptor. + it is returned to user code. This `post_list_db_nodes` interceptor runs + before the `post_list_db_nodes_with_metadata` interceptor. """ return response - def post_list_exadb_vm_clusters_with_metadata( + def post_list_db_nodes_with_metadata( self, - response: oracledatabase.ListExadbVmClustersResponse, + response: oracledatabase.ListDbNodesResponse, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - oracledatabase.ListExadbVmClustersResponse, - Sequence[Tuple[str, Union[str, bytes]]], + oracledatabase.ListDbNodesResponse, Sequence[Tuple[str, Union[str, bytes]]] ]: - """Post-rpc interceptor for list_exadb_vm_clusters + """Post-rpc interceptor for list_db_nodes Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_list_exadb_vm_clusters_with_metadata` - interceptor in new development instead of the `post_list_exadb_vm_clusters` interceptor. - When both interceptors are used, this `post_list_exadb_vm_clusters_with_metadata` interceptor runs after the - `post_list_exadb_vm_clusters` interceptor. The (possibly modified) response returned by - `post_list_exadb_vm_clusters` will be passed to - `post_list_exadb_vm_clusters_with_metadata`. + We recommend only using this `post_list_db_nodes_with_metadata` + interceptor in new development instead of the `post_list_db_nodes` interceptor. + When both interceptors are used, this `post_list_db_nodes_with_metadata` interceptor runs after the + `post_list_db_nodes` interceptor. The (possibly modified) response returned by + `post_list_db_nodes` will be passed to + `post_list_db_nodes_with_metadata`. """ return response, metadata - def pre_list_exascale_db_storage_vaults( + def pre_list_db_servers( self, - request: exascale_db_storage_vault.ListExascaleDbStorageVaultsRequest, + request: oracledatabase.ListDbServersRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - exascale_db_storage_vault.ListExascaleDbStorageVaultsRequest, - Sequence[Tuple[str, Union[str, bytes]]], + oracledatabase.ListDbServersRequest, Sequence[Tuple[str, Union[str, bytes]]] ]: - """Pre-rpc interceptor for list_exascale_db_storage_vaults + """Pre-rpc interceptor for list_db_servers Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_list_exascale_db_storage_vaults( - self, response: exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse - ) -> exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse: - """Post-rpc interceptor for list_exascale_db_storage_vaults + def post_list_db_servers( + self, response: oracledatabase.ListDbServersResponse + ) -> oracledatabase.ListDbServersResponse: + """Post-rpc interceptor for list_db_servers - DEPRECATED. Please use the `post_list_exascale_db_storage_vaults_with_metadata` + DEPRECATED. Please use the `post_list_db_servers_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_list_exascale_db_storage_vaults` interceptor runs - before the `post_list_exascale_db_storage_vaults_with_metadata` interceptor. + it is returned to user code. This `post_list_db_servers` interceptor runs + before the `post_list_db_servers_with_metadata` interceptor. """ return response - def post_list_exascale_db_storage_vaults_with_metadata( + def post_list_db_servers_with_metadata( self, - response: exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse, + response: oracledatabase.ListDbServersResponse, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse, - Sequence[Tuple[str, Union[str, bytes]]], + oracledatabase.ListDbServersResponse, Sequence[Tuple[str, Union[str, bytes]]] ]: - """Post-rpc interceptor for list_exascale_db_storage_vaults + """Post-rpc interceptor for list_db_servers Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_list_exascale_db_storage_vaults_with_metadata` - interceptor in new development instead of the `post_list_exascale_db_storage_vaults` interceptor. - When both interceptors are used, this `post_list_exascale_db_storage_vaults_with_metadata` interceptor runs after the - `post_list_exascale_db_storage_vaults` interceptor. The (possibly modified) response returned by - `post_list_exascale_db_storage_vaults` will be passed to - `post_list_exascale_db_storage_vaults_with_metadata`. + We recommend only using this `post_list_db_servers_with_metadata` + interceptor in new development instead of the `post_list_db_servers` interceptor. + When both interceptors are used, this `post_list_db_servers_with_metadata` interceptor runs after the + `post_list_db_servers` interceptor. The (possibly modified) response returned by + `post_list_db_servers` will be passed to + `post_list_db_servers_with_metadata`. """ return response, metadata - def pre_list_gi_versions( + def pre_list_db_system_initial_storage_sizes( self, - request: oracledatabase.ListGiVersionsRequest, + request: db_system_initial_storage_size.ListDbSystemInitialStorageSizesRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - oracledatabase.ListGiVersionsRequest, Sequence[Tuple[str, Union[str, bytes]]] + db_system_initial_storage_size.ListDbSystemInitialStorageSizesRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: - """Pre-rpc interceptor for list_gi_versions + """Pre-rpc interceptor for list_db_system_initial_storage_sizes Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_list_gi_versions( - self, response: oracledatabase.ListGiVersionsResponse - ) -> oracledatabase.ListGiVersionsResponse: - """Post-rpc interceptor for list_gi_versions + def post_list_db_system_initial_storage_sizes( + self, + response: db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse, + ) -> db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse: + """Post-rpc interceptor for list_db_system_initial_storage_sizes - DEPRECATED. Please use the `post_list_gi_versions_with_metadata` + DEPRECATED. Please use the `post_list_db_system_initial_storage_sizes_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_list_gi_versions` interceptor runs - before the `post_list_gi_versions_with_metadata` interceptor. + it is returned to user code. This `post_list_db_system_initial_storage_sizes` interceptor runs + before the `post_list_db_system_initial_storage_sizes_with_metadata` interceptor. """ return response - def post_list_gi_versions_with_metadata( + def post_list_db_system_initial_storage_sizes_with_metadata( self, - response: oracledatabase.ListGiVersionsResponse, + response: db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - oracledatabase.ListGiVersionsResponse, Sequence[Tuple[str, Union[str, bytes]]] + db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse, + Sequence[Tuple[str, Union[str, bytes]]], ]: - """Post-rpc interceptor for list_gi_versions + """Post-rpc interceptor for list_db_system_initial_storage_sizes Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_list_gi_versions_with_metadata` - interceptor in new development instead of the `post_list_gi_versions` interceptor. - When both interceptors are used, this `post_list_gi_versions_with_metadata` interceptor runs after the - `post_list_gi_versions` interceptor. The (possibly modified) response returned by - `post_list_gi_versions` will be passed to - `post_list_gi_versions_with_metadata`. + We recommend only using this `post_list_db_system_initial_storage_sizes_with_metadata` + interceptor in new development instead of the `post_list_db_system_initial_storage_sizes` interceptor. + When both interceptors are used, this `post_list_db_system_initial_storage_sizes_with_metadata` interceptor runs after the + `post_list_db_system_initial_storage_sizes` interceptor. The (possibly modified) response returned by + `post_list_db_system_initial_storage_sizes` will be passed to + `post_list_db_system_initial_storage_sizes_with_metadata`. """ return response, metadata - def pre_list_minor_versions( + def pre_list_db_systems( self, - request: minor_version.ListMinorVersionsRequest, + request: db_system.ListDbSystemsRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[ - minor_version.ListMinorVersionsRequest, Sequence[Tuple[str, Union[str, bytes]]] - ]: - """Pre-rpc interceptor for list_minor_versions + ) -> Tuple[db_system.ListDbSystemsRequest, Sequence[Tuple[str, Union[str, bytes]]]]: + """Pre-rpc interceptor for list_db_systems Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_list_minor_versions( - self, response: minor_version.ListMinorVersionsResponse - ) -> minor_version.ListMinorVersionsResponse: - """Post-rpc interceptor for list_minor_versions + def post_list_db_systems( + self, response: db_system.ListDbSystemsResponse + ) -> db_system.ListDbSystemsResponse: + """Post-rpc interceptor for list_db_systems - DEPRECATED. Please use the `post_list_minor_versions_with_metadata` + DEPRECATED. Please use the `post_list_db_systems_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_list_minor_versions` interceptor runs - before the `post_list_minor_versions_with_metadata` interceptor. + it is returned to user code. This `post_list_db_systems` interceptor runs + before the `post_list_db_systems_with_metadata` interceptor. """ return response - def post_list_minor_versions_with_metadata( + def post_list_db_systems_with_metadata( self, - response: minor_version.ListMinorVersionsResponse, + response: db_system.ListDbSystemsResponse, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - minor_version.ListMinorVersionsResponse, Sequence[Tuple[str, Union[str, bytes]]] + db_system.ListDbSystemsResponse, Sequence[Tuple[str, Union[str, bytes]]] ]: - """Post-rpc interceptor for list_minor_versions + """Post-rpc interceptor for list_db_systems Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_list_minor_versions_with_metadata` - interceptor in new development instead of the `post_list_minor_versions` interceptor. - When both interceptors are used, this `post_list_minor_versions_with_metadata` interceptor runs after the - `post_list_minor_versions` interceptor. The (possibly modified) response returned by - `post_list_minor_versions` will be passed to - `post_list_minor_versions_with_metadata`. + We recommend only using this `post_list_db_systems_with_metadata` + interceptor in new development instead of the `post_list_db_systems` interceptor. + When both interceptors are used, this `post_list_db_systems_with_metadata` interceptor runs after the + `post_list_db_systems` interceptor. The (possibly modified) response returned by + `post_list_db_systems` will be passed to + `post_list_db_systems_with_metadata`. """ return response, metadata - def pre_list_odb_networks( + def pre_list_db_system_shapes( self, - request: odb_network.ListOdbNetworksRequest, + request: oracledatabase.ListDbSystemShapesRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - odb_network.ListOdbNetworksRequest, Sequence[Tuple[str, Union[str, bytes]]] + oracledatabase.ListDbSystemShapesRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: - """Pre-rpc interceptor for list_odb_networks + """Pre-rpc interceptor for list_db_system_shapes Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_list_odb_networks( - self, response: odb_network.ListOdbNetworksResponse - ) -> odb_network.ListOdbNetworksResponse: - """Post-rpc interceptor for list_odb_networks + def post_list_db_system_shapes( + self, response: oracledatabase.ListDbSystemShapesResponse + ) -> oracledatabase.ListDbSystemShapesResponse: + """Post-rpc interceptor for list_db_system_shapes - DEPRECATED. Please use the `post_list_odb_networks_with_metadata` + DEPRECATED. Please use the `post_list_db_system_shapes_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_list_odb_networks` interceptor runs - before the `post_list_odb_networks_with_metadata` interceptor. + it is returned to user code. This `post_list_db_system_shapes` interceptor runs + before the `post_list_db_system_shapes_with_metadata` interceptor. """ return response - def post_list_odb_networks_with_metadata( + def post_list_db_system_shapes_with_metadata( self, - response: odb_network.ListOdbNetworksResponse, + response: oracledatabase.ListDbSystemShapesResponse, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - odb_network.ListOdbNetworksResponse, Sequence[Tuple[str, Union[str, bytes]]] + oracledatabase.ListDbSystemShapesResponse, + Sequence[Tuple[str, Union[str, bytes]]], ]: - """Post-rpc interceptor for list_odb_networks + """Post-rpc interceptor for list_db_system_shapes Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_list_odb_networks_with_metadata` - interceptor in new development instead of the `post_list_odb_networks` interceptor. - When both interceptors are used, this `post_list_odb_networks_with_metadata` interceptor runs after the - `post_list_odb_networks` interceptor. The (possibly modified) response returned by - `post_list_odb_networks` will be passed to - `post_list_odb_networks_with_metadata`. + We recommend only using this `post_list_db_system_shapes_with_metadata` + interceptor in new development instead of the `post_list_db_system_shapes` interceptor. + When both interceptors are used, this `post_list_db_system_shapes_with_metadata` interceptor runs after the + `post_list_db_system_shapes` interceptor. The (possibly modified) response returned by + `post_list_db_system_shapes` will be passed to + `post_list_db_system_shapes_with_metadata`. """ return response, metadata - def pre_list_odb_subnets( + def pre_list_db_versions( self, - request: odb_subnet.ListOdbSubnetsRequest, + request: db_version.ListDbVersionsRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - odb_subnet.ListOdbSubnetsRequest, Sequence[Tuple[str, Union[str, bytes]]] + db_version.ListDbVersionsRequest, Sequence[Tuple[str, Union[str, bytes]]] ]: - """Pre-rpc interceptor for list_odb_subnets + """Pre-rpc interceptor for list_db_versions Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_list_odb_subnets( - self, response: odb_subnet.ListOdbSubnetsResponse - ) -> odb_subnet.ListOdbSubnetsResponse: - """Post-rpc interceptor for list_odb_subnets + def post_list_db_versions( + self, response: db_version.ListDbVersionsResponse + ) -> db_version.ListDbVersionsResponse: + """Post-rpc interceptor for list_db_versions - DEPRECATED. Please use the `post_list_odb_subnets_with_metadata` + DEPRECATED. Please use the `post_list_db_versions_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_list_odb_subnets` interceptor runs - before the `post_list_odb_subnets_with_metadata` interceptor. + it is returned to user code. This `post_list_db_versions` interceptor runs + before the `post_list_db_versions_with_metadata` interceptor. """ return response - def post_list_odb_subnets_with_metadata( + def post_list_db_versions_with_metadata( self, - response: odb_subnet.ListOdbSubnetsResponse, + response: db_version.ListDbVersionsResponse, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - odb_subnet.ListOdbSubnetsResponse, Sequence[Tuple[str, Union[str, bytes]]] + db_version.ListDbVersionsResponse, Sequence[Tuple[str, Union[str, bytes]]] ]: - """Post-rpc interceptor for list_odb_subnets + """Post-rpc interceptor for list_db_versions Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_list_odb_subnets_with_metadata` - interceptor in new development instead of the `post_list_odb_subnets` interceptor. - When both interceptors are used, this `post_list_odb_subnets_with_metadata` interceptor runs after the - `post_list_odb_subnets` interceptor. The (possibly modified) response returned by - `post_list_odb_subnets` will be passed to - `post_list_odb_subnets_with_metadata`. - """ - return response, metadata + We recommend only using this `post_list_db_versions_with_metadata` + interceptor in new development instead of the `post_list_db_versions` interceptor. + When both interceptors are used, this `post_list_db_versions_with_metadata` interceptor runs after the + `post_list_db_versions` interceptor. The (possibly modified) response returned by + `post_list_db_versions` will be passed to + `post_list_db_versions_with_metadata`. + """ + return response, metadata - def pre_list_pluggable_databases( + def pre_list_entitlements( self, - request: pluggable_database.ListPluggableDatabasesRequest, + request: oracledatabase.ListEntitlementsRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - pluggable_database.ListPluggableDatabasesRequest, - Sequence[Tuple[str, Union[str, bytes]]], + oracledatabase.ListEntitlementsRequest, Sequence[Tuple[str, Union[str, bytes]]] ]: - """Pre-rpc interceptor for list_pluggable_databases + """Pre-rpc interceptor for list_entitlements Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_list_pluggable_databases( - self, response: pluggable_database.ListPluggableDatabasesResponse - ) -> pluggable_database.ListPluggableDatabasesResponse: - """Post-rpc interceptor for list_pluggable_databases + def post_list_entitlements( + self, response: oracledatabase.ListEntitlementsResponse + ) -> oracledatabase.ListEntitlementsResponse: + """Post-rpc interceptor for list_entitlements - DEPRECATED. Please use the `post_list_pluggable_databases_with_metadata` + DEPRECATED. Please use the `post_list_entitlements_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_list_pluggable_databases` interceptor runs - before the `post_list_pluggable_databases_with_metadata` interceptor. + it is returned to user code. This `post_list_entitlements` interceptor runs + before the `post_list_entitlements_with_metadata` interceptor. """ return response - def post_list_pluggable_databases_with_metadata( + def post_list_entitlements_with_metadata( self, - response: pluggable_database.ListPluggableDatabasesResponse, + response: oracledatabase.ListEntitlementsResponse, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - pluggable_database.ListPluggableDatabasesResponse, - Sequence[Tuple[str, Union[str, bytes]]], + oracledatabase.ListEntitlementsResponse, Sequence[Tuple[str, Union[str, bytes]]] ]: - """Post-rpc interceptor for list_pluggable_databases + """Post-rpc interceptor for list_entitlements Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_list_pluggable_databases_with_metadata` - interceptor in new development instead of the `post_list_pluggable_databases` interceptor. - When both interceptors are used, this `post_list_pluggable_databases_with_metadata` interceptor runs after the - `post_list_pluggable_databases` interceptor. The (possibly modified) response returned by - `post_list_pluggable_databases` will be passed to - `post_list_pluggable_databases_with_metadata`. + We recommend only using this `post_list_entitlements_with_metadata` + interceptor in new development instead of the `post_list_entitlements` interceptor. + When both interceptors are used, this `post_list_entitlements_with_metadata` interceptor runs after the + `post_list_entitlements` interceptor. The (possibly modified) response returned by + `post_list_entitlements` will be passed to + `post_list_entitlements_with_metadata`. """ return response, metadata - def pre_remove_virtual_machine_exadb_vm_cluster( + def pre_list_exadb_vm_clusters( self, - request: oracledatabase.RemoveVirtualMachineExadbVmClusterRequest, + request: oracledatabase.ListExadbVmClustersRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - oracledatabase.RemoveVirtualMachineExadbVmClusterRequest, + oracledatabase.ListExadbVmClustersRequest, Sequence[Tuple[str, Union[str, bytes]]], ]: - """Pre-rpc interceptor for remove_virtual_machine_exadb_vm_cluster + """Pre-rpc interceptor for list_exadb_vm_clusters Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_remove_virtual_machine_exadb_vm_cluster( - self, response: operations_pb2.Operation - ) -> operations_pb2.Operation: - """Post-rpc interceptor for remove_virtual_machine_exadb_vm_cluster + def post_list_exadb_vm_clusters( + self, response: oracledatabase.ListExadbVmClustersResponse + ) -> oracledatabase.ListExadbVmClustersResponse: + """Post-rpc interceptor for list_exadb_vm_clusters - DEPRECATED. Please use the `post_remove_virtual_machine_exadb_vm_cluster_with_metadata` + DEPRECATED. Please use the `post_list_exadb_vm_clusters_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_remove_virtual_machine_exadb_vm_cluster` interceptor runs - before the `post_remove_virtual_machine_exadb_vm_cluster_with_metadata` interceptor. + it is returned to user code. This `post_list_exadb_vm_clusters` interceptor runs + before the `post_list_exadb_vm_clusters_with_metadata` interceptor. """ return response - def post_remove_virtual_machine_exadb_vm_cluster_with_metadata( + def post_list_exadb_vm_clusters_with_metadata( self, - response: operations_pb2.Operation, + response: oracledatabase.ListExadbVmClustersResponse, metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: - """Post-rpc interceptor for remove_virtual_machine_exadb_vm_cluster + ) -> Tuple[ + oracledatabase.ListExadbVmClustersResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_exadb_vm_clusters Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_remove_virtual_machine_exadb_vm_cluster_with_metadata` - interceptor in new development instead of the `post_remove_virtual_machine_exadb_vm_cluster` interceptor. - When both interceptors are used, this `post_remove_virtual_machine_exadb_vm_cluster_with_metadata` interceptor runs after the - `post_remove_virtual_machine_exadb_vm_cluster` interceptor. The (possibly modified) response returned by - `post_remove_virtual_machine_exadb_vm_cluster` will be passed to - `post_remove_virtual_machine_exadb_vm_cluster_with_metadata`. + We recommend only using this `post_list_exadb_vm_clusters_with_metadata` + interceptor in new development instead of the `post_list_exadb_vm_clusters` interceptor. + When both interceptors are used, this `post_list_exadb_vm_clusters_with_metadata` interceptor runs after the + `post_list_exadb_vm_clusters` interceptor. The (possibly modified) response returned by + `post_list_exadb_vm_clusters` will be passed to + `post_list_exadb_vm_clusters_with_metadata`. """ return response, metadata - def pre_restart_autonomous_database( + def pre_list_exascale_db_storage_vaults( self, - request: oracledatabase.RestartAutonomousDatabaseRequest, + request: exascale_db_storage_vault.ListExascaleDbStorageVaultsRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - oracledatabase.RestartAutonomousDatabaseRequest, + exascale_db_storage_vault.ListExascaleDbStorageVaultsRequest, Sequence[Tuple[str, Union[str, bytes]]], ]: - """Pre-rpc interceptor for restart_autonomous_database + """Pre-rpc interceptor for list_exascale_db_storage_vaults Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_restart_autonomous_database( - self, response: operations_pb2.Operation - ) -> operations_pb2.Operation: - """Post-rpc interceptor for restart_autonomous_database + def post_list_exascale_db_storage_vaults( + self, response: exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse + ) -> exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse: + """Post-rpc interceptor for list_exascale_db_storage_vaults - DEPRECATED. Please use the `post_restart_autonomous_database_with_metadata` + DEPRECATED. Please use the `post_list_exascale_db_storage_vaults_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_restart_autonomous_database` interceptor runs - before the `post_restart_autonomous_database_with_metadata` interceptor. + it is returned to user code. This `post_list_exascale_db_storage_vaults` interceptor runs + before the `post_list_exascale_db_storage_vaults_with_metadata` interceptor. """ return response - def post_restart_autonomous_database_with_metadata( + def post_list_exascale_db_storage_vaults_with_metadata( self, - response: operations_pb2.Operation, + response: exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse, metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: - """Post-rpc interceptor for restart_autonomous_database + ) -> Tuple[ + exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_exascale_db_storage_vaults Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_restart_autonomous_database_with_metadata` - interceptor in new development instead of the `post_restart_autonomous_database` interceptor. - When both interceptors are used, this `post_restart_autonomous_database_with_metadata` interceptor runs after the - `post_restart_autonomous_database` interceptor. The (possibly modified) response returned by - `post_restart_autonomous_database` will be passed to - `post_restart_autonomous_database_with_metadata`. + We recommend only using this `post_list_exascale_db_storage_vaults_with_metadata` + interceptor in new development instead of the `post_list_exascale_db_storage_vaults` interceptor. + When both interceptors are used, this `post_list_exascale_db_storage_vaults_with_metadata` interceptor runs after the + `post_list_exascale_db_storage_vaults` interceptor. The (possibly modified) response returned by + `post_list_exascale_db_storage_vaults` will be passed to + `post_list_exascale_db_storage_vaults_with_metadata`. """ return response, metadata - def pre_restore_autonomous_database( + def pre_list_gi_versions( self, - request: oracledatabase.RestoreAutonomousDatabaseRequest, + request: oracledatabase.ListGiVersionsRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - oracledatabase.RestoreAutonomousDatabaseRequest, - Sequence[Tuple[str, Union[str, bytes]]], + oracledatabase.ListGiVersionsRequest, Sequence[Tuple[str, Union[str, bytes]]] ]: - """Pre-rpc interceptor for restore_autonomous_database + """Pre-rpc interceptor for list_gi_versions Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_restore_autonomous_database( - self, response: operations_pb2.Operation - ) -> operations_pb2.Operation: - """Post-rpc interceptor for restore_autonomous_database + def post_list_gi_versions( + self, response: oracledatabase.ListGiVersionsResponse + ) -> oracledatabase.ListGiVersionsResponse: + """Post-rpc interceptor for list_gi_versions - DEPRECATED. Please use the `post_restore_autonomous_database_with_metadata` + DEPRECATED. Please use the `post_list_gi_versions_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_restore_autonomous_database` interceptor runs - before the `post_restore_autonomous_database_with_metadata` interceptor. + it is returned to user code. This `post_list_gi_versions` interceptor runs + before the `post_list_gi_versions_with_metadata` interceptor. """ return response - def post_restore_autonomous_database_with_metadata( + def post_list_gi_versions_with_metadata( self, - response: operations_pb2.Operation, + response: oracledatabase.ListGiVersionsResponse, metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: - """Post-rpc interceptor for restore_autonomous_database + ) -> Tuple[ + oracledatabase.ListGiVersionsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_gi_versions Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_restore_autonomous_database_with_metadata` - interceptor in new development instead of the `post_restore_autonomous_database` interceptor. - When both interceptors are used, this `post_restore_autonomous_database_with_metadata` interceptor runs after the - `post_restore_autonomous_database` interceptor. The (possibly modified) response returned by - `post_restore_autonomous_database` will be passed to - `post_restore_autonomous_database_with_metadata`. + We recommend only using this `post_list_gi_versions_with_metadata` + interceptor in new development instead of the `post_list_gi_versions` interceptor. + When both interceptors are used, this `post_list_gi_versions_with_metadata` interceptor runs after the + `post_list_gi_versions` interceptor. The (possibly modified) response returned by + `post_list_gi_versions` will be passed to + `post_list_gi_versions_with_metadata`. """ return response, metadata - def pre_start_autonomous_database( + def pre_list_goldengate_connection_assignments( self, - request: oracledatabase.StartAutonomousDatabaseRequest, + request: goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - oracledatabase.StartAutonomousDatabaseRequest, + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest, Sequence[Tuple[str, Union[str, bytes]]], ]: - """Pre-rpc interceptor for start_autonomous_database + """Pre-rpc interceptor for list_goldengate_connection_assignments Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_start_autonomous_database( - self, response: operations_pb2.Operation - ) -> operations_pb2.Operation: - """Post-rpc interceptor for start_autonomous_database + def post_list_goldengate_connection_assignments( + self, + response: goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse, + ) -> goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse: + """Post-rpc interceptor for list_goldengate_connection_assignments - DEPRECATED. Please use the `post_start_autonomous_database_with_metadata` + DEPRECATED. Please use the `post_list_goldengate_connection_assignments_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_start_autonomous_database` interceptor runs - before the `post_start_autonomous_database_with_metadata` interceptor. + it is returned to user code. This `post_list_goldengate_connection_assignments` interceptor runs + before the `post_list_goldengate_connection_assignments_with_metadata` interceptor. """ return response - def post_start_autonomous_database_with_metadata( + def post_list_goldengate_connection_assignments_with_metadata( self, - response: operations_pb2.Operation, + response: goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse, metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: - """Post-rpc interceptor for start_autonomous_database + ) -> Tuple[ + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_goldengate_connection_assignments Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_start_autonomous_database_with_metadata` - interceptor in new development instead of the `post_start_autonomous_database` interceptor. - When both interceptors are used, this `post_start_autonomous_database_with_metadata` interceptor runs after the - `post_start_autonomous_database` interceptor. The (possibly modified) response returned by - `post_start_autonomous_database` will be passed to - `post_start_autonomous_database_with_metadata`. + We recommend only using this `post_list_goldengate_connection_assignments_with_metadata` + interceptor in new development instead of the `post_list_goldengate_connection_assignments` interceptor. + When both interceptors are used, this `post_list_goldengate_connection_assignments_with_metadata` interceptor runs after the + `post_list_goldengate_connection_assignments` interceptor. The (possibly modified) response returned by + `post_list_goldengate_connection_assignments` will be passed to + `post_list_goldengate_connection_assignments_with_metadata`. """ return response, metadata - def pre_stop_autonomous_database( + def pre_list_goldengate_connections( self, - request: oracledatabase.StopAutonomousDatabaseRequest, + request: goldengate_connection.ListGoldengateConnectionsRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - oracledatabase.StopAutonomousDatabaseRequest, + goldengate_connection.ListGoldengateConnectionsRequest, Sequence[Tuple[str, Union[str, bytes]]], ]: - """Pre-rpc interceptor for stop_autonomous_database + """Pre-rpc interceptor for list_goldengate_connections Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_stop_autonomous_database( - self, response: operations_pb2.Operation - ) -> operations_pb2.Operation: - """Post-rpc interceptor for stop_autonomous_database + def post_list_goldengate_connections( + self, response: goldengate_connection.ListGoldengateConnectionsResponse + ) -> goldengate_connection.ListGoldengateConnectionsResponse: + """Post-rpc interceptor for list_goldengate_connections - DEPRECATED. Please use the `post_stop_autonomous_database_with_metadata` + DEPRECATED. Please use the `post_list_goldengate_connections_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_stop_autonomous_database` interceptor runs - before the `post_stop_autonomous_database_with_metadata` interceptor. + it is returned to user code. This `post_list_goldengate_connections` interceptor runs + before the `post_list_goldengate_connections_with_metadata` interceptor. """ return response - def post_stop_autonomous_database_with_metadata( + def post_list_goldengate_connections_with_metadata( self, - response: operations_pb2.Operation, + response: goldengate_connection.ListGoldengateConnectionsResponse, metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: - """Post-rpc interceptor for stop_autonomous_database + ) -> Tuple[ + goldengate_connection.ListGoldengateConnectionsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_goldengate_connections Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_stop_autonomous_database_with_metadata` - interceptor in new development instead of the `post_stop_autonomous_database` interceptor. - When both interceptors are used, this `post_stop_autonomous_database_with_metadata` interceptor runs after the - `post_stop_autonomous_database` interceptor. The (possibly modified) response returned by - `post_stop_autonomous_database` will be passed to - `post_stop_autonomous_database_with_metadata`. + We recommend only using this `post_list_goldengate_connections_with_metadata` + interceptor in new development instead of the `post_list_goldengate_connections` interceptor. + When both interceptors are used, this `post_list_goldengate_connections_with_metadata` interceptor runs after the + `post_list_goldengate_connections` interceptor. The (possibly modified) response returned by + `post_list_goldengate_connections` will be passed to + `post_list_goldengate_connections_with_metadata`. """ return response, metadata - def pre_switchover_autonomous_database( + def pre_list_goldengate_connection_types( self, - request: oracledatabase.SwitchoverAutonomousDatabaseRequest, + request: goldengate_connection_type.ListGoldengateConnectionTypesRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - oracledatabase.SwitchoverAutonomousDatabaseRequest, + goldengate_connection_type.ListGoldengateConnectionTypesRequest, Sequence[Tuple[str, Union[str, bytes]]], ]: - """Pre-rpc interceptor for switchover_autonomous_database + """Pre-rpc interceptor for list_goldengate_connection_types Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_switchover_autonomous_database( - self, response: operations_pb2.Operation - ) -> operations_pb2.Operation: - """Post-rpc interceptor for switchover_autonomous_database + def post_list_goldengate_connection_types( + self, response: goldengate_connection_type.ListGoldengateConnectionTypesResponse + ) -> goldengate_connection_type.ListGoldengateConnectionTypesResponse: + """Post-rpc interceptor for list_goldengate_connection_types - DEPRECATED. Please use the `post_switchover_autonomous_database_with_metadata` + DEPRECATED. Please use the `post_list_goldengate_connection_types_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_switchover_autonomous_database` interceptor runs - before the `post_switchover_autonomous_database_with_metadata` interceptor. + it is returned to user code. This `post_list_goldengate_connection_types` interceptor runs + before the `post_list_goldengate_connection_types_with_metadata` interceptor. """ return response - def post_switchover_autonomous_database_with_metadata( + def post_list_goldengate_connection_types_with_metadata( self, - response: operations_pb2.Operation, + response: goldengate_connection_type.ListGoldengateConnectionTypesResponse, metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: - """Post-rpc interceptor for switchover_autonomous_database + ) -> Tuple[ + goldengate_connection_type.ListGoldengateConnectionTypesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_goldengate_connection_types Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_switchover_autonomous_database_with_metadata` - interceptor in new development instead of the `post_switchover_autonomous_database` interceptor. - When both interceptors are used, this `post_switchover_autonomous_database_with_metadata` interceptor runs after the - `post_switchover_autonomous_database` interceptor. The (possibly modified) response returned by - `post_switchover_autonomous_database` will be passed to - `post_switchover_autonomous_database_with_metadata`. + We recommend only using this `post_list_goldengate_connection_types_with_metadata` + interceptor in new development instead of the `post_list_goldengate_connection_types` interceptor. + When both interceptors are used, this `post_list_goldengate_connection_types_with_metadata` interceptor runs after the + `post_list_goldengate_connection_types` interceptor. The (possibly modified) response returned by + `post_list_goldengate_connection_types` will be passed to + `post_list_goldengate_connection_types_with_metadata`. """ return response, metadata - def pre_update_autonomous_database( + def pre_list_goldengate_deployment_environments( self, - request: oracledatabase.UpdateAutonomousDatabaseRequest, + request: goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - oracledatabase.UpdateAutonomousDatabaseRequest, + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest, Sequence[Tuple[str, Union[str, bytes]]], ]: - """Pre-rpc interceptor for update_autonomous_database + """Pre-rpc interceptor for list_goldengate_deployment_environments Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_update_autonomous_database( - self, response: operations_pb2.Operation - ) -> operations_pb2.Operation: - """Post-rpc interceptor for update_autonomous_database + def post_list_goldengate_deployment_environments( + self, + response: goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse, + ) -> goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse: + """Post-rpc interceptor for list_goldengate_deployment_environments - DEPRECATED. Please use the `post_update_autonomous_database_with_metadata` + DEPRECATED. Please use the `post_list_goldengate_deployment_environments_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_update_autonomous_database` interceptor runs - before the `post_update_autonomous_database_with_metadata` interceptor. + it is returned to user code. This `post_list_goldengate_deployment_environments` interceptor runs + before the `post_list_goldengate_deployment_environments_with_metadata` interceptor. """ return response - def post_update_autonomous_database_with_metadata( + def post_list_goldengate_deployment_environments_with_metadata( self, - response: operations_pb2.Operation, + response: goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse, metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: - """Post-rpc interceptor for update_autonomous_database + ) -> Tuple[ + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_goldengate_deployment_environments Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_update_autonomous_database_with_metadata` - interceptor in new development instead of the `post_update_autonomous_database` interceptor. - When both interceptors are used, this `post_update_autonomous_database_with_metadata` interceptor runs after the - `post_update_autonomous_database` interceptor. The (possibly modified) response returned by - `post_update_autonomous_database` will be passed to - `post_update_autonomous_database_with_metadata`. + We recommend only using this `post_list_goldengate_deployment_environments_with_metadata` + interceptor in new development instead of the `post_list_goldengate_deployment_environments` interceptor. + When both interceptors are used, this `post_list_goldengate_deployment_environments_with_metadata` interceptor runs after the + `post_list_goldengate_deployment_environments` interceptor. The (possibly modified) response returned by + `post_list_goldengate_deployment_environments` will be passed to + `post_list_goldengate_deployment_environments_with_metadata`. """ return response, metadata - def pre_update_exadb_vm_cluster( + def pre_list_goldengate_deployments( self, - request: oracledatabase.UpdateExadbVmClusterRequest, + request: goldengate_deployment.ListGoldengateDeploymentsRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - oracledatabase.UpdateExadbVmClusterRequest, + goldengate_deployment.ListGoldengateDeploymentsRequest, Sequence[Tuple[str, Union[str, bytes]]], ]: - """Pre-rpc interceptor for update_exadb_vm_cluster + """Pre-rpc interceptor for list_goldengate_deployments Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_update_exadb_vm_cluster( - self, response: operations_pb2.Operation - ) -> operations_pb2.Operation: - """Post-rpc interceptor for update_exadb_vm_cluster + def post_list_goldengate_deployments( + self, response: goldengate_deployment.ListGoldengateDeploymentsResponse + ) -> goldengate_deployment.ListGoldengateDeploymentsResponse: + """Post-rpc interceptor for list_goldengate_deployments - DEPRECATED. Please use the `post_update_exadb_vm_cluster_with_metadata` + DEPRECATED. Please use the `post_list_goldengate_deployments_with_metadata` interceptor instead. Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. This `post_update_exadb_vm_cluster` interceptor runs - before the `post_update_exadb_vm_cluster_with_metadata` interceptor. + it is returned to user code. This `post_list_goldengate_deployments` interceptor runs + before the `post_list_goldengate_deployments_with_metadata` interceptor. """ return response - def post_update_exadb_vm_cluster_with_metadata( + def post_list_goldengate_deployments_with_metadata( self, - response: operations_pb2.Operation, + response: goldengate_deployment.ListGoldengateDeploymentsResponse, metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: - """Post-rpc interceptor for update_exadb_vm_cluster + ) -> Tuple[ + goldengate_deployment.ListGoldengateDeploymentsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_goldengate_deployments Override in a subclass to read or manipulate the response or metadata after it is returned by the OracleDatabase server but before it is returned to user code. - We recommend only using this `post_update_exadb_vm_cluster_with_metadata` - interceptor in new development instead of the `post_update_exadb_vm_cluster` interceptor. - When both interceptors are used, this `post_update_exadb_vm_cluster_with_metadata` interceptor runs after the - `post_update_exadb_vm_cluster` interceptor. The (possibly modified) response returned by - `post_update_exadb_vm_cluster` will be passed to - `post_update_exadb_vm_cluster_with_metadata`. + We recommend only using this `post_list_goldengate_deployments_with_metadata` + interceptor in new development instead of the `post_list_goldengate_deployments` interceptor. + When both interceptors are used, this `post_list_goldengate_deployments_with_metadata` interceptor runs after the + `post_list_goldengate_deployments` interceptor. The (possibly modified) response returned by + `post_list_goldengate_deployments` will be passed to + `post_list_goldengate_deployments_with_metadata`. """ return response, metadata - def pre_get_location( + def pre_list_goldengate_deployment_types( self, - request: locations_pb2.GetLocationRequest, + request: goldengate_deployment_type.ListGoldengateDeploymentTypesRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - locations_pb2.GetLocationRequest, Sequence[Tuple[str, Union[str, bytes]]] + goldengate_deployment_type.ListGoldengateDeploymentTypesRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: - """Pre-rpc interceptor for get_location + """Pre-rpc interceptor for list_goldengate_deployment_types Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_get_location( - self, response: locations_pb2.Location - ) -> locations_pb2.Location: - """Post-rpc interceptor for get_location + def post_list_goldengate_deployment_types( + self, response: goldengate_deployment_type.ListGoldengateDeploymentTypesResponse + ) -> goldengate_deployment_type.ListGoldengateDeploymentTypesResponse: + """Post-rpc interceptor for list_goldengate_deployment_types - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_goldengate_deployment_types_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. + it is returned to user code. This `post_list_goldengate_deployment_types` interceptor runs + before the `post_list_goldengate_deployment_types_with_metadata` interceptor. """ return response - def pre_list_locations( + def post_list_goldengate_deployment_types_with_metadata( self, - request: locations_pb2.ListLocationsRequest, + response: goldengate_deployment_type.ListGoldengateDeploymentTypesResponse, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - locations_pb2.ListLocationsRequest, Sequence[Tuple[str, Union[str, bytes]]] + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse, + Sequence[Tuple[str, Union[str, bytes]]], ]: - """Pre-rpc interceptor for list_locations + """Post-rpc interceptor for list_goldengate_deployment_types - Override in a subclass to manipulate the request or metadata - before they are sent to the OracleDatabase server. - """ - return request, metadata - - def post_list_locations( - self, response: locations_pb2.ListLocationsResponse - ) -> locations_pb2.ListLocationsResponse: - """Post-rpc interceptor for list_locations + Override in a subclass to read or manipulate the response or metadata after it + is returned by the OracleDatabase server but before it is returned to user code. - Override in a subclass to manipulate the response - after it is returned by the OracleDatabase server but before - it is returned to user code. + We recommend only using this `post_list_goldengate_deployment_types_with_metadata` + interceptor in new development instead of the `post_list_goldengate_deployment_types` interceptor. + When both interceptors are used, this `post_list_goldengate_deployment_types_with_metadata` interceptor runs after the + `post_list_goldengate_deployment_types` interceptor. The (possibly modified) response returned by + `post_list_goldengate_deployment_types` will be passed to + `post_list_goldengate_deployment_types_with_metadata`. """ - return response + return response, metadata - def pre_cancel_operation( + def pre_list_goldengate_deployment_versions( self, - request: operations_pb2.CancelOperationRequest, + request: goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - operations_pb2.CancelOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: - """Pre-rpc interceptor for cancel_operation + """Pre-rpc interceptor for list_goldengate_deployment_versions Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_cancel_operation(self, response: None) -> None: - """Post-rpc interceptor for cancel_operation + def post_list_goldengate_deployment_versions( + self, + response: goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse, + ) -> goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse: + """Post-rpc interceptor for list_goldengate_deployment_versions - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_goldengate_deployment_versions_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. + it is returned to user code. This `post_list_goldengate_deployment_versions` interceptor runs + before the `post_list_goldengate_deployment_versions_with_metadata` interceptor. """ return response - def pre_delete_operation( + def post_list_goldengate_deployment_versions_with_metadata( self, - request: operations_pb2.DeleteOperationRequest, + response: goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - operations_pb2.DeleteOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse, + Sequence[Tuple[str, Union[str, bytes]]], ]: - """Pre-rpc interceptor for delete_operation + """Post-rpc interceptor for list_goldengate_deployment_versions + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the OracleDatabase server but before it is returned to user code. + + We recommend only using this `post_list_goldengate_deployment_versions_with_metadata` + interceptor in new development instead of the `post_list_goldengate_deployment_versions` interceptor. + When both interceptors are used, this `post_list_goldengate_deployment_versions_with_metadata` interceptor runs after the + `post_list_goldengate_deployment_versions` interceptor. The (possibly modified) response returned by + `post_list_goldengate_deployment_versions` will be passed to + `post_list_goldengate_deployment_versions_with_metadata`. + """ + return response, metadata + + def pre_list_minor_versions( + self, + request: minor_version.ListMinorVersionsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + minor_version.ListMinorVersionsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for list_minor_versions Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_delete_operation(self, response: None) -> None: - """Post-rpc interceptor for delete_operation + def post_list_minor_versions( + self, response: minor_version.ListMinorVersionsResponse + ) -> minor_version.ListMinorVersionsResponse: + """Post-rpc interceptor for list_minor_versions - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_minor_versions_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. + it is returned to user code. This `post_list_minor_versions` interceptor runs + before the `post_list_minor_versions_with_metadata` interceptor. """ return response - def pre_get_operation( + def post_list_minor_versions_with_metadata( self, - request: operations_pb2.GetOperationRequest, + response: minor_version.ListMinorVersionsResponse, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + minor_version.ListMinorVersionsResponse, Sequence[Tuple[str, Union[str, bytes]]] ]: - """Pre-rpc interceptor for get_operation + """Post-rpc interceptor for list_minor_versions + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the OracleDatabase server but before it is returned to user code. + + We recommend only using this `post_list_minor_versions_with_metadata` + interceptor in new development instead of the `post_list_minor_versions` interceptor. + When both interceptors are used, this `post_list_minor_versions_with_metadata` interceptor runs after the + `post_list_minor_versions` interceptor. The (possibly modified) response returned by + `post_list_minor_versions` will be passed to + `post_list_minor_versions_with_metadata`. + """ + return response, metadata + + def pre_list_odb_networks( + self, + request: odb_network.ListOdbNetworksRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + odb_network.ListOdbNetworksRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for list_odb_networks Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_get_operation( - self, response: operations_pb2.Operation - ) -> operations_pb2.Operation: - """Post-rpc interceptor for get_operation + def post_list_odb_networks( + self, response: odb_network.ListOdbNetworksResponse + ) -> odb_network.ListOdbNetworksResponse: + """Post-rpc interceptor for list_odb_networks - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_odb_networks_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. + it is returned to user code. This `post_list_odb_networks` interceptor runs + before the `post_list_odb_networks_with_metadata` interceptor. """ return response - def pre_list_operations( + def post_list_odb_networks_with_metadata( self, - request: operations_pb2.ListOperationsRequest, + response: odb_network.ListOdbNetworksResponse, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - operations_pb2.ListOperationsRequest, Sequence[Tuple[str, Union[str, bytes]]] + odb_network.ListOdbNetworksResponse, Sequence[Tuple[str, Union[str, bytes]]] ]: - """Pre-rpc interceptor for list_operations + """Post-rpc interceptor for list_odb_networks + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the OracleDatabase server but before it is returned to user code. + + We recommend only using this `post_list_odb_networks_with_metadata` + interceptor in new development instead of the `post_list_odb_networks` interceptor. + When both interceptors are used, this `post_list_odb_networks_with_metadata` interceptor runs after the + `post_list_odb_networks` interceptor. The (possibly modified) response returned by + `post_list_odb_networks` will be passed to + `post_list_odb_networks_with_metadata`. + """ + return response, metadata + + def pre_list_odb_subnets( + self, + request: odb_subnet.ListOdbSubnetsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + odb_subnet.ListOdbSubnetsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for list_odb_subnets Override in a subclass to manipulate the request or metadata before they are sent to the OracleDatabase server. """ return request, metadata - def post_list_operations( - self, response: operations_pb2.ListOperationsResponse - ) -> operations_pb2.ListOperationsResponse: - """Post-rpc interceptor for list_operations + def post_list_odb_subnets( + self, response: odb_subnet.ListOdbSubnetsResponse + ) -> odb_subnet.ListOdbSubnetsResponse: + """Post-rpc interceptor for list_odb_subnets - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_odb_subnets_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the OracleDatabase server but before - it is returned to user code. + it is returned to user code. This `post_list_odb_subnets` interceptor runs + before the `post_list_odb_subnets_with_metadata` interceptor. """ return response + def post_list_odb_subnets_with_metadata( + self, + response: odb_subnet.ListOdbSubnetsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + odb_subnet.ListOdbSubnetsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_odb_subnets -@dataclasses.dataclass -class OracleDatabaseRestStub: - _session: AuthorizedSession - _host: str - _interceptor: OracleDatabaseRestInterceptor - - -class OracleDatabaseRestTransport(_BaseOracleDatabaseRestTransport): - """REST backend synchronous transport for OracleDatabase. + Override in a subclass to read or manipulate the response or metadata after it + is returned by the OracleDatabase server but before it is returned to user code. - Service describing handlers for resources + We recommend only using this `post_list_odb_subnets_with_metadata` + interceptor in new development instead of the `post_list_odb_subnets` interceptor. + When both interceptors are used, this `post_list_odb_subnets_with_metadata` interceptor runs after the + `post_list_odb_subnets` interceptor. The (possibly modified) response returned by + `post_list_odb_subnets` will be passed to + `post_list_odb_subnets_with_metadata`. + """ + return response, metadata - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. + def pre_list_pluggable_databases( + self, + request: pluggable_database.ListPluggableDatabasesRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + pluggable_database.ListPluggableDatabasesRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for list_pluggable_databases - It sends JSON representations of protocol buffers over HTTP/1.1 - """ + Override in a subclass to manipulate the request or metadata + before they are sent to the OracleDatabase server. + """ + return request, metadata - def __init__( + def post_list_pluggable_databases( + self, response: pluggable_database.ListPluggableDatabasesResponse + ) -> pluggable_database.ListPluggableDatabasesResponse: + """Post-rpc interceptor for list_pluggable_databases + + DEPRECATED. Please use the `post_list_pluggable_databases_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the OracleDatabase server but before + it is returned to user code. This `post_list_pluggable_databases` interceptor runs + before the `post_list_pluggable_databases_with_metadata` interceptor. + """ + return response + + def post_list_pluggable_databases_with_metadata( self, - *, - host: str = "oracledatabase.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - url_scheme: str = "https", - interceptor: Optional[OracleDatabaseRestInterceptor] = None, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. + response: pluggable_database.ListPluggableDatabasesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + pluggable_database.ListPluggableDatabasesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_pluggable_databases - Args: - host (Optional[str]): - The hostname to connect to (default: 'oracledatabase.googleapis.com'). - 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. + Override in a subclass to read or manipulate the response or metadata after it + is returned by the OracleDatabase server but before it is returned to user code. - credentials_file (Optional[str]): Deprecated. A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if ``channel`` is provided. This argument will be - removed in the next major version of this library. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if ``channel`` is provided. - client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client - certificate to configure mutual TLS HTTP channel. It is ignored - if ``channel`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you are developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - url_scheme: the protocol scheme for the API endpoint. Normally - "https", but for testing or local servers, - "http" can be specified. - interceptor (Optional[OracleDatabaseRestInterceptor]): Interceptor used - to manipulate requests, request metadata, and responses. - api_audience (Optional[str]): The intended audience for the API calls - to the service that will be set when using certain 3rd party - authentication flows. Audience is typically a resource identifier. - If not set, the host value will be used as a default. + We recommend only using this `post_list_pluggable_databases_with_metadata` + interceptor in new development instead of the `post_list_pluggable_databases` interceptor. + When both interceptors are used, this `post_list_pluggable_databases_with_metadata` interceptor runs after the + `post_list_pluggable_databases` interceptor. The (possibly modified) response returned by + `post_list_pluggable_databases` will be passed to + `post_list_pluggable_databases_with_metadata`. """ - # Run the base constructor - # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. - # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the - # credentials object - super().__init__( - host=host, - credentials=credentials, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - url_scheme=url_scheme, - api_audience=api_audience, - ) - self._session = AuthorizedSession( - self._credentials, default_host=self.DEFAULT_HOST - ) - self._operations_client: Optional[operations_v1.AbstractOperationsClient] = None - if client_cert_source_for_mtls: - self._session.configure_mtls_channel(client_cert_source_for_mtls) - self._interceptor = interceptor or OracleDatabaseRestInterceptor() - self._prep_wrapped_messages(client_info) + return response, metadata - @property - def operations_client(self) -> operations_v1.AbstractOperationsClient: - """Create the client designed to process long-running operations. + def pre_remove_virtual_machine_exadb_vm_cluster( + self, + request: oracledatabase.RemoveVirtualMachineExadbVmClusterRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + oracledatabase.RemoveVirtualMachineExadbVmClusterRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for remove_virtual_machine_exadb_vm_cluster - This property caches on the instance; repeated calls return the same - client. + Override in a subclass to manipulate the request or metadata + before they are sent to the OracleDatabase server. """ - # Only create a new client if we do not already have one. - if self._operations_client is None: - http_options: Dict[str, List[Dict[str, str]]] = { - "google.longrunning.Operations.CancelOperation": [ - { - "method": "post", - "uri": "/v1/{name=projects/*/locations/*/operations/*}:cancel", - "body": "*", - }, - ], - "google.longrunning.Operations.DeleteOperation": [ - { - "method": "delete", - "uri": "/v1/{name=projects/*/locations/*/operations/*}", - }, - ], - "google.longrunning.Operations.GetOperation": [ - { - "method": "get", - "uri": "/v1/{name=projects/*/locations/*/operations/*}", - }, - ], - "google.longrunning.Operations.ListOperations": [ - { - "method": "get", - "uri": "/v1/{name=projects/*/locations/*}/operations", + return request, metadata + + def post_remove_virtual_machine_exadb_vm_cluster( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for remove_virtual_machine_exadb_vm_cluster + + DEPRECATED. Please use the `post_remove_virtual_machine_exadb_vm_cluster_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the OracleDatabase server but before + it is returned to user code. This `post_remove_virtual_machine_exadb_vm_cluster` interceptor runs + before the `post_remove_virtual_machine_exadb_vm_cluster_with_metadata` interceptor. + """ + return response + + def post_remove_virtual_machine_exadb_vm_cluster_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for remove_virtual_machine_exadb_vm_cluster + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the OracleDatabase server but before it is returned to user code. + + We recommend only using this `post_remove_virtual_machine_exadb_vm_cluster_with_metadata` + interceptor in new development instead of the `post_remove_virtual_machine_exadb_vm_cluster` interceptor. + When both interceptors are used, this `post_remove_virtual_machine_exadb_vm_cluster_with_metadata` interceptor runs after the + `post_remove_virtual_machine_exadb_vm_cluster` interceptor. The (possibly modified) response returned by + `post_remove_virtual_machine_exadb_vm_cluster` will be passed to + `post_remove_virtual_machine_exadb_vm_cluster_with_metadata`. + """ + return response, metadata + + def pre_restart_autonomous_database( + self, + request: oracledatabase.RestartAutonomousDatabaseRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + oracledatabase.RestartAutonomousDatabaseRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for restart_autonomous_database + + Override in a subclass to manipulate the request or metadata + before they are sent to the OracleDatabase server. + """ + return request, metadata + + def post_restart_autonomous_database( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for restart_autonomous_database + + DEPRECATED. Please use the `post_restart_autonomous_database_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the OracleDatabase server but before + it is returned to user code. This `post_restart_autonomous_database` interceptor runs + before the `post_restart_autonomous_database_with_metadata` interceptor. + """ + return response + + def post_restart_autonomous_database_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for restart_autonomous_database + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the OracleDatabase server but before it is returned to user code. + + We recommend only using this `post_restart_autonomous_database_with_metadata` + interceptor in new development instead of the `post_restart_autonomous_database` interceptor. + When both interceptors are used, this `post_restart_autonomous_database_with_metadata` interceptor runs after the + `post_restart_autonomous_database` interceptor. The (possibly modified) response returned by + `post_restart_autonomous_database` will be passed to + `post_restart_autonomous_database_with_metadata`. + """ + return response, metadata + + def pre_restore_autonomous_database( + self, + request: oracledatabase.RestoreAutonomousDatabaseRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + oracledatabase.RestoreAutonomousDatabaseRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for restore_autonomous_database + + Override in a subclass to manipulate the request or metadata + before they are sent to the OracleDatabase server. + """ + return request, metadata + + def post_restore_autonomous_database( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for restore_autonomous_database + + DEPRECATED. Please use the `post_restore_autonomous_database_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the OracleDatabase server but before + it is returned to user code. This `post_restore_autonomous_database` interceptor runs + before the `post_restore_autonomous_database_with_metadata` interceptor. + """ + return response + + def post_restore_autonomous_database_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for restore_autonomous_database + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the OracleDatabase server but before it is returned to user code. + + We recommend only using this `post_restore_autonomous_database_with_metadata` + interceptor in new development instead of the `post_restore_autonomous_database` interceptor. + When both interceptors are used, this `post_restore_autonomous_database_with_metadata` interceptor runs after the + `post_restore_autonomous_database` interceptor. The (possibly modified) response returned by + `post_restore_autonomous_database` will be passed to + `post_restore_autonomous_database_with_metadata`. + """ + return response, metadata + + def pre_start_autonomous_database( + self, + request: oracledatabase.StartAutonomousDatabaseRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + oracledatabase.StartAutonomousDatabaseRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for start_autonomous_database + + Override in a subclass to manipulate the request or metadata + before they are sent to the OracleDatabase server. + """ + return request, metadata + + def post_start_autonomous_database( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for start_autonomous_database + + DEPRECATED. Please use the `post_start_autonomous_database_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the OracleDatabase server but before + it is returned to user code. This `post_start_autonomous_database` interceptor runs + before the `post_start_autonomous_database_with_metadata` interceptor. + """ + return response + + def post_start_autonomous_database_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for start_autonomous_database + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the OracleDatabase server but before it is returned to user code. + + We recommend only using this `post_start_autonomous_database_with_metadata` + interceptor in new development instead of the `post_start_autonomous_database` interceptor. + When both interceptors are used, this `post_start_autonomous_database_with_metadata` interceptor runs after the + `post_start_autonomous_database` interceptor. The (possibly modified) response returned by + `post_start_autonomous_database` will be passed to + `post_start_autonomous_database_with_metadata`. + """ + return response, metadata + + def pre_start_goldengate_deployment( + self, + request: goldengate_deployment.StartGoldengateDeploymentRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + goldengate_deployment.StartGoldengateDeploymentRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for start_goldengate_deployment + + Override in a subclass to manipulate the request or metadata + before they are sent to the OracleDatabase server. + """ + return request, metadata + + def post_start_goldengate_deployment( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for start_goldengate_deployment + + DEPRECATED. Please use the `post_start_goldengate_deployment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the OracleDatabase server but before + it is returned to user code. This `post_start_goldengate_deployment` interceptor runs + before the `post_start_goldengate_deployment_with_metadata` interceptor. + """ + return response + + def post_start_goldengate_deployment_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for start_goldengate_deployment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the OracleDatabase server but before it is returned to user code. + + We recommend only using this `post_start_goldengate_deployment_with_metadata` + interceptor in new development instead of the `post_start_goldengate_deployment` interceptor. + When both interceptors are used, this `post_start_goldengate_deployment_with_metadata` interceptor runs after the + `post_start_goldengate_deployment` interceptor. The (possibly modified) response returned by + `post_start_goldengate_deployment` will be passed to + `post_start_goldengate_deployment_with_metadata`. + """ + return response, metadata + + def pre_stop_autonomous_database( + self, + request: oracledatabase.StopAutonomousDatabaseRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + oracledatabase.StopAutonomousDatabaseRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for stop_autonomous_database + + Override in a subclass to manipulate the request or metadata + before they are sent to the OracleDatabase server. + """ + return request, metadata + + def post_stop_autonomous_database( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for stop_autonomous_database + + DEPRECATED. Please use the `post_stop_autonomous_database_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the OracleDatabase server but before + it is returned to user code. This `post_stop_autonomous_database` interceptor runs + before the `post_stop_autonomous_database_with_metadata` interceptor. + """ + return response + + def post_stop_autonomous_database_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for stop_autonomous_database + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the OracleDatabase server but before it is returned to user code. + + We recommend only using this `post_stop_autonomous_database_with_metadata` + interceptor in new development instead of the `post_stop_autonomous_database` interceptor. + When both interceptors are used, this `post_stop_autonomous_database_with_metadata` interceptor runs after the + `post_stop_autonomous_database` interceptor. The (possibly modified) response returned by + `post_stop_autonomous_database` will be passed to + `post_stop_autonomous_database_with_metadata`. + """ + return response, metadata + + def pre_stop_goldengate_deployment( + self, + request: goldengate_deployment.StopGoldengateDeploymentRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + goldengate_deployment.StopGoldengateDeploymentRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for stop_goldengate_deployment + + Override in a subclass to manipulate the request or metadata + before they are sent to the OracleDatabase server. + """ + return request, metadata + + def post_stop_goldengate_deployment( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for stop_goldengate_deployment + + DEPRECATED. Please use the `post_stop_goldengate_deployment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the OracleDatabase server but before + it is returned to user code. This `post_stop_goldengate_deployment` interceptor runs + before the `post_stop_goldengate_deployment_with_metadata` interceptor. + """ + return response + + def post_stop_goldengate_deployment_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for stop_goldengate_deployment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the OracleDatabase server but before it is returned to user code. + + We recommend only using this `post_stop_goldengate_deployment_with_metadata` + interceptor in new development instead of the `post_stop_goldengate_deployment` interceptor. + When both interceptors are used, this `post_stop_goldengate_deployment_with_metadata` interceptor runs after the + `post_stop_goldengate_deployment` interceptor. The (possibly modified) response returned by + `post_stop_goldengate_deployment` will be passed to + `post_stop_goldengate_deployment_with_metadata`. + """ + return response, metadata + + def pre_switchover_autonomous_database( + self, + request: oracledatabase.SwitchoverAutonomousDatabaseRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + oracledatabase.SwitchoverAutonomousDatabaseRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for switchover_autonomous_database + + Override in a subclass to manipulate the request or metadata + before they are sent to the OracleDatabase server. + """ + return request, metadata + + def post_switchover_autonomous_database( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for switchover_autonomous_database + + DEPRECATED. Please use the `post_switchover_autonomous_database_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the OracleDatabase server but before + it is returned to user code. This `post_switchover_autonomous_database` interceptor runs + before the `post_switchover_autonomous_database_with_metadata` interceptor. + """ + return response + + def post_switchover_autonomous_database_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for switchover_autonomous_database + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the OracleDatabase server but before it is returned to user code. + + We recommend only using this `post_switchover_autonomous_database_with_metadata` + interceptor in new development instead of the `post_switchover_autonomous_database` interceptor. + When both interceptors are used, this `post_switchover_autonomous_database_with_metadata` interceptor runs after the + `post_switchover_autonomous_database` interceptor. The (possibly modified) response returned by + `post_switchover_autonomous_database` will be passed to + `post_switchover_autonomous_database_with_metadata`. + """ + return response, metadata + + def pre_test_goldengate_connection_assignment( + self, + request: goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for test_goldengate_connection_assignment + + Override in a subclass to manipulate the request or metadata + before they are sent to the OracleDatabase server. + """ + return request, metadata + + def post_test_goldengate_connection_assignment( + self, + response: goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse, + ) -> goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse: + """Post-rpc interceptor for test_goldengate_connection_assignment + + DEPRECATED. Please use the `post_test_goldengate_connection_assignment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the OracleDatabase server but before + it is returned to user code. This `post_test_goldengate_connection_assignment` interceptor runs + before the `post_test_goldengate_connection_assignment_with_metadata` interceptor. + """ + return response + + def post_test_goldengate_connection_assignment_with_metadata( + self, + response: goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for test_goldengate_connection_assignment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the OracleDatabase server but before it is returned to user code. + + We recommend only using this `post_test_goldengate_connection_assignment_with_metadata` + interceptor in new development instead of the `post_test_goldengate_connection_assignment` interceptor. + When both interceptors are used, this `post_test_goldengate_connection_assignment_with_metadata` interceptor runs after the + `post_test_goldengate_connection_assignment` interceptor. The (possibly modified) response returned by + `post_test_goldengate_connection_assignment` will be passed to + `post_test_goldengate_connection_assignment_with_metadata`. + """ + return response, metadata + + def pre_update_autonomous_database( + self, + request: oracledatabase.UpdateAutonomousDatabaseRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + oracledatabase.UpdateAutonomousDatabaseRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for update_autonomous_database + + Override in a subclass to manipulate the request or metadata + before they are sent to the OracleDatabase server. + """ + return request, metadata + + def post_update_autonomous_database( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for update_autonomous_database + + DEPRECATED. Please use the `post_update_autonomous_database_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the OracleDatabase server but before + it is returned to user code. This `post_update_autonomous_database` interceptor runs + before the `post_update_autonomous_database_with_metadata` interceptor. + """ + return response + + def post_update_autonomous_database_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_autonomous_database + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the OracleDatabase server but before it is returned to user code. + + We recommend only using this `post_update_autonomous_database_with_metadata` + interceptor in new development instead of the `post_update_autonomous_database` interceptor. + When both interceptors are used, this `post_update_autonomous_database_with_metadata` interceptor runs after the + `post_update_autonomous_database` interceptor. The (possibly modified) response returned by + `post_update_autonomous_database` will be passed to + `post_update_autonomous_database_with_metadata`. + """ + return response, metadata + + def pre_update_exadb_vm_cluster( + self, + request: oracledatabase.UpdateExadbVmClusterRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + oracledatabase.UpdateExadbVmClusterRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for update_exadb_vm_cluster + + Override in a subclass to manipulate the request or metadata + before they are sent to the OracleDatabase server. + """ + return request, metadata + + def post_update_exadb_vm_cluster( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for update_exadb_vm_cluster + + DEPRECATED. Please use the `post_update_exadb_vm_cluster_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the OracleDatabase server but before + it is returned to user code. This `post_update_exadb_vm_cluster` interceptor runs + before the `post_update_exadb_vm_cluster_with_metadata` interceptor. + """ + return response + + def post_update_exadb_vm_cluster_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_exadb_vm_cluster + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the OracleDatabase server but before it is returned to user code. + + We recommend only using this `post_update_exadb_vm_cluster_with_metadata` + interceptor in new development instead of the `post_update_exadb_vm_cluster` interceptor. + When both interceptors are used, this `post_update_exadb_vm_cluster_with_metadata` interceptor runs after the + `post_update_exadb_vm_cluster` interceptor. The (possibly modified) response returned by + `post_update_exadb_vm_cluster` will be passed to + `post_update_exadb_vm_cluster_with_metadata`. + """ + return response, metadata + + def pre_get_location( + self, + request: locations_pb2.GetLocationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + locations_pb2.GetLocationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_location + + Override in a subclass to manipulate the request or metadata + before they are sent to the OracleDatabase server. + """ + return request, metadata + + def post_get_location( + self, response: locations_pb2.Location + ) -> locations_pb2.Location: + """Post-rpc interceptor for get_location + + Override in a subclass to manipulate the response + after it is returned by the OracleDatabase server but before + it is returned to user code. + """ + return response + + def pre_list_locations( + self, + request: locations_pb2.ListLocationsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + locations_pb2.ListLocationsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for list_locations + + Override in a subclass to manipulate the request or metadata + before they are sent to the OracleDatabase server. + """ + return request, metadata + + def post_list_locations( + self, response: locations_pb2.ListLocationsResponse + ) -> locations_pb2.ListLocationsResponse: + """Post-rpc interceptor for list_locations + + Override in a subclass to manipulate the response + after it is returned by the OracleDatabase server but before + it is returned to user code. + """ + return response + + def pre_cancel_operation( + self, + request: operations_pb2.CancelOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.CancelOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for cancel_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the OracleDatabase server. + """ + return request, metadata + + def post_cancel_operation(self, response: None) -> None: + """Post-rpc interceptor for cancel_operation + + Override in a subclass to manipulate the response + after it is returned by the OracleDatabase server but before + it is returned to user code. + """ + return response + + def pre_delete_operation( + self, + request: operations_pb2.DeleteOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.DeleteOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for delete_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the OracleDatabase server. + """ + return request, metadata + + def post_delete_operation(self, response: None) -> None: + """Post-rpc interceptor for delete_operation + + Override in a subclass to manipulate the response + after it is returned by the OracleDatabase server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the OracleDatabase server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the OracleDatabase server but before + it is returned to user code. + """ + return response + + def pre_list_operations( + self, + request: operations_pb2.ListOperationsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.ListOperationsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the OracleDatabase server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the OracleDatabase server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class OracleDatabaseRestStub: + _session: AuthorizedSession + _host: str + _interceptor: OracleDatabaseRestInterceptor + + +class OracleDatabaseRestTransport(_BaseOracleDatabaseRestTransport): + """REST backend synchronous transport for OracleDatabase. + + Service describing handlers for resources + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "oracledatabase.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[OracleDatabaseRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'oracledatabase.googleapis.com'). + 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]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. This argument will be + removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + interceptor (Optional[OracleDatabaseRestInterceptor]): Interceptor used + to manipulate requests, request metadata, and responses. + api_audience (Optional[str]): The intended audience for the API calls + to the service that will be set when using certain 3rd party + authentication flows. Audience is typically a resource identifier. + If not set, the host value will be used as a default. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + self._operations_client: Optional[operations_v1.AbstractOperationsClient] = None + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or OracleDatabaseRestInterceptor() + self._prep_wrapped_messages(client_info) + + @property + def operations_client(self) -> operations_v1.AbstractOperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Only create a new client if we do not already have one. + if self._operations_client is None: + http_options: Dict[str, List[Dict[str, str]]] = { + "google.longrunning.Operations.CancelOperation": [ + { + "method": "post", + "uri": "/v1/{name=projects/*/locations/*/operations/*}:cancel", + "body": "*", + }, + ], + "google.longrunning.Operations.DeleteOperation": [ + { + "method": "delete", + "uri": "/v1/{name=projects/*/locations/*/operations/*}", + }, + ], + "google.longrunning.Operations.GetOperation": [ + { + "method": "get", + "uri": "/v1/{name=projects/*/locations/*/operations/*}", + }, + ], + "google.longrunning.Operations.ListOperations": [ + { + "method": "get", + "uri": "/v1/{name=projects/*/locations/*}/operations", + }, + ], + } + + rest_transport = operations_v1.OperationsRestTransport( + host=self._host, + # use the credentials which are saved + credentials=self._credentials, + scopes=self._scopes, + http_options=http_options, + path_prefix="v1", + ) + + self._operations_client = operations_v1.AbstractOperationsClient( + transport=rest_transport + ) + + # Return the client from cache. + return self._operations_client + + class _CreateAutonomousDatabase( + _BaseOracleDatabaseRestTransport._BaseCreateAutonomousDatabase, + OracleDatabaseRestStub, + ): + def __hash__(self): + return hash("OracleDatabaseRestTransport.CreateAutonomousDatabase") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: oracledatabase.CreateAutonomousDatabaseRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the create autonomous + database method over HTTP. + + Args: + request (~.oracledatabase.CreateAutonomousDatabaseRequest): + The request object. The request for ``AutonomousDatabase.Create``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseOracleDatabaseRestTransport._BaseCreateAutonomousDatabase._get_http_options() + + request, metadata = self._interceptor.pre_create_autonomous_database( + request, metadata + ) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseCreateAutonomousDatabase._get_transcoded_request( + http_options, request + ) + + body = _BaseOracleDatabaseRestTransport._BaseCreateAutonomousDatabase._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseOracleDatabaseRestTransport._BaseCreateAutonomousDatabase._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.CreateAutonomousDatabase", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "CreateAutonomousDatabase", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + OracleDatabaseRestTransport._CreateAutonomousDatabase._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_create_autonomous_database(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_autonomous_database_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.create_autonomous_database", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "CreateAutonomousDatabase", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _CreateCloudExadataInfrastructure( + _BaseOracleDatabaseRestTransport._BaseCreateCloudExadataInfrastructure, + OracleDatabaseRestStub, + ): + def __hash__(self): + return hash("OracleDatabaseRestTransport.CreateCloudExadataInfrastructure") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: oracledatabase.CreateCloudExadataInfrastructureRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the create cloud exadata + infrastructure method over HTTP. + + Args: + request (~.oracledatabase.CreateCloudExadataInfrastructureRequest): + The request object. The request for ``CloudExadataInfrastructure.Create``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseOracleDatabaseRestTransport._BaseCreateCloudExadataInfrastructure._get_http_options() + + request, metadata = ( + self._interceptor.pre_create_cloud_exadata_infrastructure( + request, metadata + ) + ) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseCreateCloudExadataInfrastructure._get_transcoded_request( + http_options, request + ) + + body = _BaseOracleDatabaseRestTransport._BaseCreateCloudExadataInfrastructure._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseOracleDatabaseRestTransport._BaseCreateCloudExadataInfrastructure._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.CreateCloudExadataInfrastructure", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "CreateCloudExadataInfrastructure", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = OracleDatabaseRestTransport._CreateCloudExadataInfrastructure._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_create_cloud_exadata_infrastructure(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = ( + self._interceptor.post_create_cloud_exadata_infrastructure_with_metadata( + resp, response_metadata + ) + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.create_cloud_exadata_infrastructure", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "CreateCloudExadataInfrastructure", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _CreateCloudVmCluster( + _BaseOracleDatabaseRestTransport._BaseCreateCloudVmCluster, + OracleDatabaseRestStub, + ): + def __hash__(self): + return hash("OracleDatabaseRestTransport.CreateCloudVmCluster") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: oracledatabase.CreateCloudVmClusterRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the create cloud vm cluster method over HTTP. + + Args: + request (~.oracledatabase.CreateCloudVmClusterRequest): + The request object. The request for ``CloudVmCluster.Create``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseOracleDatabaseRestTransport._BaseCreateCloudVmCluster._get_http_options() + + request, metadata = self._interceptor.pre_create_cloud_vm_cluster( + request, metadata + ) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseCreateCloudVmCluster._get_transcoded_request( + http_options, request + ) + + body = _BaseOracleDatabaseRestTransport._BaseCreateCloudVmCluster._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseOracleDatabaseRestTransport._BaseCreateCloudVmCluster._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.CreateCloudVmCluster", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "CreateCloudVmCluster", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = OracleDatabaseRestTransport._CreateCloudVmCluster._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_create_cloud_vm_cluster(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_cloud_vm_cluster_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.create_cloud_vm_cluster", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "CreateCloudVmCluster", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _CreateDbSystem( + _BaseOracleDatabaseRestTransport._BaseCreateDbSystem, OracleDatabaseRestStub + ): + def __hash__(self): + return hash("OracleDatabaseRestTransport.CreateDbSystem") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: gco_db_system.CreateDbSystemRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the create db system method over HTTP. + + Args: + request (~.gco_db_system.CreateDbSystemRequest): + The request object. The request for ``DbSystem.Create``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = ( + _BaseOracleDatabaseRestTransport._BaseCreateDbSystem._get_http_options() + ) + + request, metadata = self._interceptor.pre_create_db_system( + request, metadata + ) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseCreateDbSystem._get_transcoded_request( + http_options, request + ) + + body = _BaseOracleDatabaseRestTransport._BaseCreateDbSystem._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseOracleDatabaseRestTransport._BaseCreateDbSystem._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.CreateDbSystem", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "CreateDbSystem", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = OracleDatabaseRestTransport._CreateDbSystem._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_create_db_system(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_db_system_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.create_db_system", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "CreateDbSystem", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _CreateExadbVmCluster( + _BaseOracleDatabaseRestTransport._BaseCreateExadbVmCluster, + OracleDatabaseRestStub, + ): + def __hash__(self): + return hash("OracleDatabaseRestTransport.CreateExadbVmCluster") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: oracledatabase.CreateExadbVmClusterRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the create exadb vm cluster method over HTTP. + + Args: + request (~.oracledatabase.CreateExadbVmClusterRequest): + The request object. The request for ``ExadbVmCluster.Create``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseOracleDatabaseRestTransport._BaseCreateExadbVmCluster._get_http_options() + + request, metadata = self._interceptor.pre_create_exadb_vm_cluster( + request, metadata + ) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseCreateExadbVmCluster._get_transcoded_request( + http_options, request + ) + + body = _BaseOracleDatabaseRestTransport._BaseCreateExadbVmCluster._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseOracleDatabaseRestTransport._BaseCreateExadbVmCluster._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.CreateExadbVmCluster", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "CreateExadbVmCluster", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = OracleDatabaseRestTransport._CreateExadbVmCluster._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_create_exadb_vm_cluster(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_exadb_vm_cluster_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.create_exadb_vm_cluster", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "CreateExadbVmCluster", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _CreateExascaleDbStorageVault( + _BaseOracleDatabaseRestTransport._BaseCreateExascaleDbStorageVault, + OracleDatabaseRestStub, + ): + def __hash__(self): + return hash("OracleDatabaseRestTransport.CreateExascaleDbStorageVault") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: gco_exascale_db_storage_vault.CreateExascaleDbStorageVaultRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the create exascale db + storage vault method over HTTP. + + Args: + request (~.gco_exascale_db_storage_vault.CreateExascaleDbStorageVaultRequest): + The request object. The request for ``ExascaleDbStorageVault.Create``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseOracleDatabaseRestTransport._BaseCreateExascaleDbStorageVault._get_http_options() + + request, metadata = self._interceptor.pre_create_exascale_db_storage_vault( + request, metadata + ) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseCreateExascaleDbStorageVault._get_transcoded_request( + http_options, request + ) + + body = _BaseOracleDatabaseRestTransport._BaseCreateExascaleDbStorageVault._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseOracleDatabaseRestTransport._BaseCreateExascaleDbStorageVault._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.CreateExascaleDbStorageVault", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "CreateExascaleDbStorageVault", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + OracleDatabaseRestTransport._CreateExascaleDbStorageVault._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_create_exascale_db_storage_vault(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = ( + self._interceptor.post_create_exascale_db_storage_vault_with_metadata( + resp, response_metadata + ) + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.create_exascale_db_storage_vault", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "CreateExascaleDbStorageVault", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _CreateGoldengateConnection( + _BaseOracleDatabaseRestTransport._BaseCreateGoldengateConnection, + OracleDatabaseRestStub, + ): + def __hash__(self): + return hash("OracleDatabaseRestTransport.CreateGoldengateConnection") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: gco_goldengate_connection.CreateGoldengateConnectionRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the create goldengate + connection method over HTTP. + + Args: + request (~.gco_goldengate_connection.CreateGoldengateConnectionRequest): + The request object. The request for ``GoldengateConnection.Create``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseOracleDatabaseRestTransport._BaseCreateGoldengateConnection._get_http_options() + + request, metadata = self._interceptor.pre_create_goldengate_connection( + request, metadata + ) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseCreateGoldengateConnection._get_transcoded_request( + http_options, request + ) + + body = _BaseOracleDatabaseRestTransport._BaseCreateGoldengateConnection._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseOracleDatabaseRestTransport._BaseCreateGoldengateConnection._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.CreateGoldengateConnection", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "CreateGoldengateConnection", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + OracleDatabaseRestTransport._CreateGoldengateConnection._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_create_goldengate_connection(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_goldengate_connection_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.create_goldengate_connection", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "CreateGoldengateConnection", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _CreateGoldengateConnectionAssignment( + _BaseOracleDatabaseRestTransport._BaseCreateGoldengateConnectionAssignment, + OracleDatabaseRestStub, + ): + def __hash__(self): + return hash( + "OracleDatabaseRestTransport.CreateGoldengateConnectionAssignment" + ) + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the create goldengate + connection assignment method over HTTP. + + Args: + request (~.gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest): + The request object. Request message for creating a + GoldengateConnectionAssignment. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseOracleDatabaseRestTransport._BaseCreateGoldengateConnectionAssignment._get_http_options() + + request, metadata = ( + self._interceptor.pre_create_goldengate_connection_assignment( + request, metadata + ) + ) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseCreateGoldengateConnectionAssignment._get_transcoded_request( + http_options, request + ) + + body = _BaseOracleDatabaseRestTransport._BaseCreateGoldengateConnectionAssignment._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseOracleDatabaseRestTransport._BaseCreateGoldengateConnectionAssignment._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.CreateGoldengateConnectionAssignment", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "CreateGoldengateConnectionAssignment", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = OracleDatabaseRestTransport._CreateGoldengateConnectionAssignment._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_create_goldengate_connection_assignment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = ( + self._interceptor.post_create_goldengate_connection_assignment_with_metadata( + resp, response_metadata + ) + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.create_goldengate_connection_assignment", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "CreateGoldengateConnectionAssignment", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _CreateGoldengateDeployment( + _BaseOracleDatabaseRestTransport._BaseCreateGoldengateDeployment, + OracleDatabaseRestStub, + ): + def __hash__(self): + return hash("OracleDatabaseRestTransport.CreateGoldengateDeployment") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: gco_goldengate_deployment.CreateGoldengateDeploymentRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the create goldengate + deployment method over HTTP. + + Args: + request (~.gco_goldengate_deployment.CreateGoldengateDeploymentRequest): + The request object. The request for ``GoldengateDeployment.Create``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseOracleDatabaseRestTransport._BaseCreateGoldengateDeployment._get_http_options() + + request, metadata = self._interceptor.pre_create_goldengate_deployment( + request, metadata + ) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseCreateGoldengateDeployment._get_transcoded_request( + http_options, request + ) + + body = _BaseOracleDatabaseRestTransport._BaseCreateGoldengateDeployment._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseOracleDatabaseRestTransport._BaseCreateGoldengateDeployment._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.CreateGoldengateDeployment", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "CreateGoldengateDeployment", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + OracleDatabaseRestTransport._CreateGoldengateDeployment._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_create_goldengate_deployment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_goldengate_deployment_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.create_goldengate_deployment", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "CreateGoldengateDeployment", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _CreateOdbNetwork( + _BaseOracleDatabaseRestTransport._BaseCreateOdbNetwork, OracleDatabaseRestStub + ): + def __hash__(self): + return hash("OracleDatabaseRestTransport.CreateOdbNetwork") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: gco_odb_network.CreateOdbNetworkRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the create odb network method over HTTP. + + Args: + request (~.gco_odb_network.CreateOdbNetworkRequest): + The request object. The request for ``OdbNetwork.Create``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseOracleDatabaseRestTransport._BaseCreateOdbNetwork._get_http_options() + + request, metadata = self._interceptor.pre_create_odb_network( + request, metadata + ) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseCreateOdbNetwork._get_transcoded_request( + http_options, request + ) + + body = _BaseOracleDatabaseRestTransport._BaseCreateOdbNetwork._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseOracleDatabaseRestTransport._BaseCreateOdbNetwork._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.CreateOdbNetwork", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "CreateOdbNetwork", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = OracleDatabaseRestTransport._CreateOdbNetwork._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_create_odb_network(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_odb_network_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.create_odb_network", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "CreateOdbNetwork", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _CreateOdbSubnet( + _BaseOracleDatabaseRestTransport._BaseCreateOdbSubnet, OracleDatabaseRestStub + ): + def __hash__(self): + return hash("OracleDatabaseRestTransport.CreateOdbSubnet") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: gco_odb_subnet.CreateOdbSubnetRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the create odb subnet method over HTTP. + + Args: + request (~.gco_odb_subnet.CreateOdbSubnetRequest): + The request object. The request for ``OdbSubnet.Create``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseOracleDatabaseRestTransport._BaseCreateOdbSubnet._get_http_options() + + request, metadata = self._interceptor.pre_create_odb_subnet( + request, metadata + ) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseCreateOdbSubnet._get_transcoded_request( + http_options, request + ) + + body = _BaseOracleDatabaseRestTransport._BaseCreateOdbSubnet._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseOracleDatabaseRestTransport._BaseCreateOdbSubnet._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.CreateOdbSubnet", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "CreateOdbSubnet", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = OracleDatabaseRestTransport._CreateOdbSubnet._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_create_odb_subnet(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_odb_subnet_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.create_odb_subnet", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "CreateOdbSubnet", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _DeleteAutonomousDatabase( + _BaseOracleDatabaseRestTransport._BaseDeleteAutonomousDatabase, + OracleDatabaseRestStub, + ): + def __hash__(self): + return hash("OracleDatabaseRestTransport.DeleteAutonomousDatabase") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: oracledatabase.DeleteAutonomousDatabaseRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the delete autonomous + database method over HTTP. + + Args: + request (~.oracledatabase.DeleteAutonomousDatabaseRequest): + The request object. The request for ``AutonomousDatabase.Delete``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseOracleDatabaseRestTransport._BaseDeleteAutonomousDatabase._get_http_options() + + request, metadata = self._interceptor.pre_delete_autonomous_database( + request, metadata + ) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseDeleteAutonomousDatabase._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseOracleDatabaseRestTransport._BaseDeleteAutonomousDatabase._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.DeleteAutonomousDatabase", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "DeleteAutonomousDatabase", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + OracleDatabaseRestTransport._DeleteAutonomousDatabase._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_delete_autonomous_database(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_autonomous_database_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_autonomous_database", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "DeleteAutonomousDatabase", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _DeleteCloudExadataInfrastructure( + _BaseOracleDatabaseRestTransport._BaseDeleteCloudExadataInfrastructure, + OracleDatabaseRestStub, + ): + def __hash__(self): + return hash("OracleDatabaseRestTransport.DeleteCloudExadataInfrastructure") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: oracledatabase.DeleteCloudExadataInfrastructureRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the delete cloud exadata + infrastructure method over HTTP. + + Args: + request (~.oracledatabase.DeleteCloudExadataInfrastructureRequest): + The request object. The request for ``CloudExadataInfrastructure.Delete``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseOracleDatabaseRestTransport._BaseDeleteCloudExadataInfrastructure._get_http_options() + + request, metadata = ( + self._interceptor.pre_delete_cloud_exadata_infrastructure( + request, metadata + ) + ) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseDeleteCloudExadataInfrastructure._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseOracleDatabaseRestTransport._BaseDeleteCloudExadataInfrastructure._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.DeleteCloudExadataInfrastructure", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "DeleteCloudExadataInfrastructure", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = OracleDatabaseRestTransport._DeleteCloudExadataInfrastructure._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_delete_cloud_exadata_infrastructure(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = ( + self._interceptor.post_delete_cloud_exadata_infrastructure_with_metadata( + resp, response_metadata + ) + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_cloud_exadata_infrastructure", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "DeleteCloudExadataInfrastructure", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _DeleteCloudVmCluster( + _BaseOracleDatabaseRestTransport._BaseDeleteCloudVmCluster, + OracleDatabaseRestStub, + ): + def __hash__(self): + return hash("OracleDatabaseRestTransport.DeleteCloudVmCluster") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: oracledatabase.DeleteCloudVmClusterRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the delete cloud vm cluster method over HTTP. + + Args: + request (~.oracledatabase.DeleteCloudVmClusterRequest): + The request object. The request for ``CloudVmCluster.Delete``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseOracleDatabaseRestTransport._BaseDeleteCloudVmCluster._get_http_options() + + request, metadata = self._interceptor.pre_delete_cloud_vm_cluster( + request, metadata + ) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseDeleteCloudVmCluster._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseOracleDatabaseRestTransport._BaseDeleteCloudVmCluster._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.DeleteCloudVmCluster", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "DeleteCloudVmCluster", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = OracleDatabaseRestTransport._DeleteCloudVmCluster._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_delete_cloud_vm_cluster(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_cloud_vm_cluster_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_cloud_vm_cluster", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "DeleteCloudVmCluster", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _DeleteDbSystem( + _BaseOracleDatabaseRestTransport._BaseDeleteDbSystem, OracleDatabaseRestStub + ): + def __hash__(self): + return hash("OracleDatabaseRestTransport.DeleteDbSystem") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: db_system.DeleteDbSystemRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the delete db system method over HTTP. + + Args: + request (~.db_system.DeleteDbSystemRequest): + The request object. The request for ``DbSystem.Delete``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = ( + _BaseOracleDatabaseRestTransport._BaseDeleteDbSystem._get_http_options() + ) + + request, metadata = self._interceptor.pre_delete_db_system( + request, metadata + ) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseDeleteDbSystem._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseOracleDatabaseRestTransport._BaseDeleteDbSystem._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.DeleteDbSystem", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "DeleteDbSystem", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = OracleDatabaseRestTransport._DeleteDbSystem._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_delete_db_system(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_db_system_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_db_system", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "DeleteDbSystem", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _DeleteExadbVmCluster( + _BaseOracleDatabaseRestTransport._BaseDeleteExadbVmCluster, + OracleDatabaseRestStub, + ): + def __hash__(self): + return hash("OracleDatabaseRestTransport.DeleteExadbVmCluster") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: oracledatabase.DeleteExadbVmClusterRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the delete exadb vm cluster method over HTTP. + + Args: + request (~.oracledatabase.DeleteExadbVmClusterRequest): + The request object. The request for ``ExadbVmCluster.Delete``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseOracleDatabaseRestTransport._BaseDeleteExadbVmCluster._get_http_options() + + request, metadata = self._interceptor.pre_delete_exadb_vm_cluster( + request, metadata + ) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseDeleteExadbVmCluster._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseOracleDatabaseRestTransport._BaseDeleteExadbVmCluster._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.DeleteExadbVmCluster", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "DeleteExadbVmCluster", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = OracleDatabaseRestTransport._DeleteExadbVmCluster._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_delete_exadb_vm_cluster(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_exadb_vm_cluster_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_exadb_vm_cluster", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "DeleteExadbVmCluster", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _DeleteExascaleDbStorageVault( + _BaseOracleDatabaseRestTransport._BaseDeleteExascaleDbStorageVault, + OracleDatabaseRestStub, + ): + def __hash__(self): + return hash("OracleDatabaseRestTransport.DeleteExascaleDbStorageVault") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: exascale_db_storage_vault.DeleteExascaleDbStorageVaultRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the delete exascale db + storage vault method over HTTP. + + Args: + request (~.exascale_db_storage_vault.DeleteExascaleDbStorageVaultRequest): + The request object. The request message for + ``ExascaleDbStorageVault.Delete``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseOracleDatabaseRestTransport._BaseDeleteExascaleDbStorageVault._get_http_options() + + request, metadata = self._interceptor.pre_delete_exascale_db_storage_vault( + request, metadata + ) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseDeleteExascaleDbStorageVault._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseOracleDatabaseRestTransport._BaseDeleteExascaleDbStorageVault._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.DeleteExascaleDbStorageVault", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "DeleteExascaleDbStorageVault", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + OracleDatabaseRestTransport._DeleteExascaleDbStorageVault._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_delete_exascale_db_storage_vault(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = ( + self._interceptor.post_delete_exascale_db_storage_vault_with_metadata( + resp, response_metadata + ) + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_exascale_db_storage_vault", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "DeleteExascaleDbStorageVault", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _DeleteGoldengateConnection( + _BaseOracleDatabaseRestTransport._BaseDeleteGoldengateConnection, + OracleDatabaseRestStub, + ): + def __hash__(self): + return hash("OracleDatabaseRestTransport.DeleteGoldengateConnection") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: goldengate_connection.DeleteGoldengateConnectionRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the delete goldengate + connection method over HTTP. + + Args: + request (~.goldengate_connection.DeleteGoldengateConnectionRequest): + The request object. The request for ``GoldengateConnection.Delete``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseOracleDatabaseRestTransport._BaseDeleteGoldengateConnection._get_http_options() + + request, metadata = self._interceptor.pre_delete_goldengate_connection( + request, metadata + ) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseDeleteGoldengateConnection._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseOracleDatabaseRestTransport._BaseDeleteGoldengateConnection._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.DeleteGoldengateConnection", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "DeleteGoldengateConnection", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + OracleDatabaseRestTransport._DeleteGoldengateConnection._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_delete_goldengate_connection(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_goldengate_connection_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_goldengate_connection", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "DeleteGoldengateConnection", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _DeleteGoldengateConnectionAssignment( + _BaseOracleDatabaseRestTransport._BaseDeleteGoldengateConnectionAssignment, + OracleDatabaseRestStub, + ): + def __hash__(self): + return hash( + "OracleDatabaseRestTransport.DeleteGoldengateConnectionAssignment" + ) + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the delete goldengate + connection assignment method over HTTP. + + Args: + request (~.goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest): + The request object. Request message for deleting a + GoldengateConnectionAssignment. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseOracleDatabaseRestTransport._BaseDeleteGoldengateConnectionAssignment._get_http_options() + + request, metadata = ( + self._interceptor.pre_delete_goldengate_connection_assignment( + request, metadata + ) + ) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseDeleteGoldengateConnectionAssignment._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseOracleDatabaseRestTransport._BaseDeleteGoldengateConnectionAssignment._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.DeleteGoldengateConnectionAssignment", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "DeleteGoldengateConnectionAssignment", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = OracleDatabaseRestTransport._DeleteGoldengateConnectionAssignment._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_delete_goldengate_connection_assignment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = ( + self._interceptor.post_delete_goldengate_connection_assignment_with_metadata( + resp, response_metadata + ) + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_goldengate_connection_assignment", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "DeleteGoldengateConnectionAssignment", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _DeleteGoldengateDeployment( + _BaseOracleDatabaseRestTransport._BaseDeleteGoldengateDeployment, + OracleDatabaseRestStub, + ): + def __hash__(self): + return hash("OracleDatabaseRestTransport.DeleteGoldengateDeployment") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: goldengate_deployment.DeleteGoldengateDeploymentRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the delete goldengate + deployment method over HTTP. + + Args: + request (~.goldengate_deployment.DeleteGoldengateDeploymentRequest): + The request object. The request for ``GoldengateDeployment.Delete``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseOracleDatabaseRestTransport._BaseDeleteGoldengateDeployment._get_http_options() + + request, metadata = self._interceptor.pre_delete_goldengate_deployment( + request, metadata + ) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseDeleteGoldengateDeployment._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseOracleDatabaseRestTransport._BaseDeleteGoldengateDeployment._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.DeleteGoldengateDeployment", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "DeleteGoldengateDeployment", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + OracleDatabaseRestTransport._DeleteGoldengateDeployment._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_delete_goldengate_deployment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_goldengate_deployment_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_goldengate_deployment", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "DeleteGoldengateDeployment", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _DeleteOdbNetwork( + _BaseOracleDatabaseRestTransport._BaseDeleteOdbNetwork, OracleDatabaseRestStub + ): + def __hash__(self): + return hash("OracleDatabaseRestTransport.DeleteOdbNetwork") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: odb_network.DeleteOdbNetworkRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the delete odb network method over HTTP. + + Args: + request (~.odb_network.DeleteOdbNetworkRequest): + The request object. The request for ``OdbNetwork.Delete``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseOracleDatabaseRestTransport._BaseDeleteOdbNetwork._get_http_options() + + request, metadata = self._interceptor.pre_delete_odb_network( + request, metadata + ) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseDeleteOdbNetwork._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseOracleDatabaseRestTransport._BaseDeleteOdbNetwork._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.DeleteOdbNetwork", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "DeleteOdbNetwork", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = OracleDatabaseRestTransport._DeleteOdbNetwork._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_delete_odb_network(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_odb_network_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_odb_network", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "DeleteOdbNetwork", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _DeleteOdbSubnet( + _BaseOracleDatabaseRestTransport._BaseDeleteOdbSubnet, OracleDatabaseRestStub + ): + def __hash__(self): + return hash("OracleDatabaseRestTransport.DeleteOdbSubnet") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: odb_subnet.DeleteOdbSubnetRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the delete odb subnet method over HTTP. + + Args: + request (~.odb_subnet.DeleteOdbSubnetRequest): + The request object. The request for ``OdbSubnet.Delete``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseOracleDatabaseRestTransport._BaseDeleteOdbSubnet._get_http_options() + + request, metadata = self._interceptor.pre_delete_odb_subnet( + request, metadata + ) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseDeleteOdbSubnet._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseOracleDatabaseRestTransport._BaseDeleteOdbSubnet._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.DeleteOdbSubnet", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "DeleteOdbSubnet", + "httpRequest": http_request, + "metadata": http_request["headers"], }, - ], - } + ) - rest_transport = operations_v1.OperationsRestTransport( - host=self._host, - # use the credentials which are saved - credentials=self._credentials, - scopes=self._scopes, - http_options=http_options, - path_prefix="v1", + # Send the request + response = OracleDatabaseRestTransport._DeleteOdbSubnet._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) - self._operations_client = operations_v1.AbstractOperationsClient( - transport=rest_transport - ) + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) - # Return the client from cache. - return self._operations_client + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) - class _CreateAutonomousDatabase( - _BaseOracleDatabaseRestTransport._BaseCreateAutonomousDatabase, + resp = self._interceptor.post_delete_odb_subnet(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_odb_subnet_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_odb_subnet", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "DeleteOdbSubnet", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _FailoverAutonomousDatabase( + _BaseOracleDatabaseRestTransport._BaseFailoverAutonomousDatabase, OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.CreateAutonomousDatabase") + return hash("OracleDatabaseRestTransport.FailoverAutonomousDatabase") @staticmethod def _get_response( @@ -3768,18 +8476,19 @@ def _get_response( def __call__( self, - request: oracledatabase.CreateAutonomousDatabaseRequest, + request: oracledatabase.FailoverAutonomousDatabaseRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> operations_pb2.Operation: - r"""Call the create autonomous + r"""Call the failover autonomous database method over HTTP. Args: - request (~.oracledatabase.CreateAutonomousDatabaseRequest): - The request object. The request for ``AutonomousDatabase.Create``. + request (~.oracledatabase.FailoverAutonomousDatabaseRequest): + The request object. The request for + ``OracleDatabase.FailoverAutonomousDatabase``. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -3796,21 +8505,21 @@ def __call__( """ - http_options = _BaseOracleDatabaseRestTransport._BaseCreateAutonomousDatabase._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseFailoverAutonomousDatabase._get_http_options() - request, metadata = self._interceptor.pre_create_autonomous_database( + request, metadata = self._interceptor.pre_failover_autonomous_database( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseCreateAutonomousDatabase._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseFailoverAutonomousDatabase._get_transcoded_request( http_options, request ) - body = _BaseOracleDatabaseRestTransport._BaseCreateAutonomousDatabase._get_request_body_json( + body = _BaseOracleDatabaseRestTransport._BaseFailoverAutonomousDatabase._get_request_body_json( transcoded_request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseCreateAutonomousDatabase._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseFailoverAutonomousDatabase._get_query_params_json( transcoded_request ) @@ -3832,10 +8541,10 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.CreateAutonomousDatabase", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.FailoverAutonomousDatabase", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "CreateAutonomousDatabase", + "rpcName": "FailoverAutonomousDatabase", "httpRequest": http_request, "metadata": http_request["headers"], }, @@ -3843,7 +8552,7 @@ def __call__( # Send the request response = ( - OracleDatabaseRestTransport._CreateAutonomousDatabase._get_response( + OracleDatabaseRestTransport._FailoverAutonomousDatabase._get_response( self._host, metadata, query_params, @@ -3859,20 +8568,180 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) - # Return the response - resp = operations_pb2.Operation() - json_format.Parse(response.content, resp, ignore_unknown_fields=True) + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_failover_autonomous_database(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_failover_autonomous_database_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.failover_autonomous_database", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "FailoverAutonomousDatabase", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _GenerateAutonomousDatabaseWallet( + _BaseOracleDatabaseRestTransport._BaseGenerateAutonomousDatabaseWallet, + OracleDatabaseRestStub, + ): + def __hash__(self): + return hash("OracleDatabaseRestTransport.GenerateAutonomousDatabaseWallet") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: oracledatabase.GenerateAutonomousDatabaseWalletRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> oracledatabase.GenerateAutonomousDatabaseWalletResponse: + r"""Call the generate autonomous + database wallet method over HTTP. + + Args: + request (~.oracledatabase.GenerateAutonomousDatabaseWalletRequest): + The request object. The request for ``AutonomousDatabase.GenerateWallet``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.oracledatabase.GenerateAutonomousDatabaseWalletResponse: + The response for ``AutonomousDatabase.GenerateWallet``. + """ + + http_options = _BaseOracleDatabaseRestTransport._BaseGenerateAutonomousDatabaseWallet._get_http_options() + + request, metadata = ( + self._interceptor.pre_generate_autonomous_database_wallet( + request, metadata + ) + ) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseGenerateAutonomousDatabaseWallet._get_transcoded_request( + http_options, request + ) + + body = _BaseOracleDatabaseRestTransport._BaseGenerateAutonomousDatabaseWallet._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseOracleDatabaseRestTransport._BaseGenerateAutonomousDatabaseWallet._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.GenerateAutonomousDatabaseWallet", + extra={ + "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", + "rpcName": "GenerateAutonomousDatabaseWallet", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = OracleDatabaseRestTransport._GenerateAutonomousDatabaseWallet._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = oracledatabase.GenerateAutonomousDatabaseWalletResponse() + pb_resp = oracledatabase.GenerateAutonomousDatabaseWalletResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_create_autonomous_database(resp) + resp = self._interceptor.post_generate_autonomous_database_wallet(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_create_autonomous_database_with_metadata( - resp, response_metadata + resp, _ = ( + self._interceptor.post_generate_autonomous_database_wallet_with_metadata( + resp, response_metadata + ) ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = json_format.MessageToJson(resp) + response_payload = ( + oracledatabase.GenerateAutonomousDatabaseWalletResponse.to_json( + response + ) + ) except: response_payload = None http_response = { @@ -3881,22 +8750,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.create_autonomous_database", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.generate_autonomous_database_wallet", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "CreateAutonomousDatabase", + "rpcName": "GenerateAutonomousDatabaseWallet", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _CreateCloudExadataInfrastructure( - _BaseOracleDatabaseRestTransport._BaseCreateCloudExadataInfrastructure, + class _GetAutonomousDatabase( + _BaseOracleDatabaseRestTransport._BaseGetAutonomousDatabase, OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.CreateCloudExadataInfrastructure") + return hash("OracleDatabaseRestTransport.GetAutonomousDatabase") @staticmethod def _get_response( @@ -3917,57 +8786,49 @@ def _get_response( timeout=timeout, headers=headers, params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, ) return response def __call__( self, - request: oracledatabase.CreateCloudExadataInfrastructureRequest, + request: oracledatabase.GetAutonomousDatabaseRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> operations_pb2.Operation: - r"""Call the create cloud exadata - infrastructure method over HTTP. + ) -> autonomous_database.AutonomousDatabase: + r"""Call the get autonomous database method over HTTP. - Args: - request (~.oracledatabase.CreateCloudExadataInfrastructureRequest): - The request object. The request for ``CloudExadataInfrastructure.Create``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + Args: + request (~.oracledatabase.GetAutonomousDatabaseRequest): + The request object. The request for ``AutonomousDatabase.Get``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. - Returns: - ~.operations_pb2.Operation: - This resource represents a - long-running operation that is the - result of a network API call. + Returns: + ~.autonomous_database.AutonomousDatabase: + Details of the Autonomous Database + resource. + https://docs.oracle.com/en-us/iaas/api/#/en/database/20160918/AutonomousDatabase/ """ - http_options = _BaseOracleDatabaseRestTransport._BaseCreateCloudExadataInfrastructure._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseGetAutonomousDatabase._get_http_options() - request, metadata = ( - self._interceptor.pre_create_cloud_exadata_infrastructure( - request, metadata - ) + request, metadata = self._interceptor.pre_get_autonomous_database( + request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseCreateCloudExadataInfrastructure._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseGetAutonomousDatabase._get_transcoded_request( http_options, request ) - body = _BaseOracleDatabaseRestTransport._BaseCreateCloudExadataInfrastructure._get_request_body_json( - transcoded_request - ) - # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseCreateCloudExadataInfrastructure._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseGetAutonomousDatabase._get_query_params_json( transcoded_request ) @@ -3989,24 +8850,23 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.CreateCloudExadataInfrastructure", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.GetAutonomousDatabase", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "CreateCloudExadataInfrastructure", + "rpcName": "GetAutonomousDatabase", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._CreateCloudExadataInfrastructure._get_response( + response = OracleDatabaseRestTransport._GetAutonomousDatabase._get_response( self._host, metadata, query_params, self._session, timeout, transcoded_request, - body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -4015,21 +8875,23 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = operations_pb2.Operation() - json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = autonomous_database.AutonomousDatabase() + pb_resp = autonomous_database.AutonomousDatabase.pb(resp) - resp = self._interceptor.post_create_cloud_exadata_infrastructure(resp) + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_autonomous_database(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = ( - self._interceptor.post_create_cloud_exadata_infrastructure_with_metadata( - resp, response_metadata - ) + resp, _ = self._interceptor.post_get_autonomous_database_with_metadata( + resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = json_format.MessageToJson(resp) + response_payload = autonomous_database.AutonomousDatabase.to_json( + response + ) except: response_payload = None http_response = { @@ -4038,22 +8900,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.create_cloud_exadata_infrastructure", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.get_autonomous_database", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "CreateCloudExadataInfrastructure", + "rpcName": "GetAutonomousDatabase", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _CreateCloudVmCluster( - _BaseOracleDatabaseRestTransport._BaseCreateCloudVmCluster, + class _GetCloudExadataInfrastructure( + _BaseOracleDatabaseRestTransport._BaseGetCloudExadataInfrastructure, OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.CreateCloudVmCluster") + return hash("OracleDatabaseRestTransport.GetCloudExadataInfrastructure") @staticmethod def _get_response( @@ -4074,54 +8936,50 @@ def _get_response( timeout=timeout, headers=headers, params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, ) return response def __call__( self, - request: oracledatabase.CreateCloudVmClusterRequest, + request: oracledatabase.GetCloudExadataInfrastructureRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> operations_pb2.Operation: - r"""Call the create cloud vm cluster method over HTTP. + ) -> exadata_infra.CloudExadataInfrastructure: + r"""Call the get cloud exadata + infrastructure method over HTTP. - Args: - request (~.oracledatabase.CreateCloudVmClusterRequest): - The request object. The request for ``CloudVmCluster.Create``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + Args: + request (~.oracledatabase.GetCloudExadataInfrastructureRequest): + The request object. The request for ``CloudExadataInfrastructure.Get``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. - Returns: - ~.operations_pb2.Operation: - This resource represents a - long-running operation that is the - result of a network API call. + Returns: + ~.exadata_infra.CloudExadataInfrastructure: + Represents CloudExadataInfrastructure + resource. + https://docs.oracle.com/en-us/iaas/api/#/en/database/20160918/CloudExadataInfrastructure/ """ - http_options = _BaseOracleDatabaseRestTransport._BaseCreateCloudVmCluster._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseGetCloudExadataInfrastructure._get_http_options() - request, metadata = self._interceptor.pre_create_cloud_vm_cluster( + request, metadata = self._interceptor.pre_get_cloud_exadata_infrastructure( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseCreateCloudVmCluster._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseGetCloudExadataInfrastructure._get_transcoded_request( http_options, request ) - body = _BaseOracleDatabaseRestTransport._BaseCreateCloudVmCluster._get_request_body_json( - transcoded_request - ) - # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseCreateCloudVmCluster._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseGetCloudExadataInfrastructure._get_query_params_json( transcoded_request ) @@ -4143,24 +9001,23 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.CreateCloudVmCluster", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.GetCloudExadataInfrastructure", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "CreateCloudVmCluster", + "rpcName": "GetCloudExadataInfrastructure", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._CreateCloudVmCluster._get_response( + response = OracleDatabaseRestTransport._GetCloudExadataInfrastructure._get_response( self._host, metadata, query_params, self._session, timeout, transcoded_request, - body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -4169,19 +9026,25 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = operations_pb2.Operation() - json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = exadata_infra.CloudExadataInfrastructure() + pb_resp = exadata_infra.CloudExadataInfrastructure.pb(resp) - resp = self._interceptor.post_create_cloud_vm_cluster(resp) + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_cloud_exadata_infrastructure(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_create_cloud_vm_cluster_with_metadata( - resp, response_metadata + resp, _ = ( + self._interceptor.post_get_cloud_exadata_infrastructure_with_metadata( + resp, response_metadata + ) ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = json_format.MessageToJson(resp) + response_payload = exadata_infra.CloudExadataInfrastructure.to_json( + response + ) except: response_payload = None http_response = { @@ -4190,21 +9053,21 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.create_cloud_vm_cluster", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.get_cloud_exadata_infrastructure", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "CreateCloudVmCluster", + "rpcName": "GetCloudExadataInfrastructure", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _CreateDbSystem( - _BaseOracleDatabaseRestTransport._BaseCreateDbSystem, OracleDatabaseRestStub + class _GetCloudVmCluster( + _BaseOracleDatabaseRestTransport._BaseGetCloudVmCluster, OracleDatabaseRestStub ): def __hash__(self): - return hash("OracleDatabaseRestTransport.CreateDbSystem") + return hash("OracleDatabaseRestTransport.GetCloudVmCluster") @staticmethod def _get_response( @@ -4225,23 +9088,22 @@ def _get_response( timeout=timeout, headers=headers, params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, ) return response def __call__( self, - request: gco_db_system.CreateDbSystemRequest, + request: oracledatabase.GetCloudVmClusterRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> operations_pb2.Operation: - r"""Call the create db system method over HTTP. + ) -> vm_cluster.CloudVmCluster: + r"""Call the get cloud vm cluster method over HTTP. Args: - request (~.gco_db_system.CreateDbSystemRequest): - The request object. The request for ``DbSystem.Create``. + request (~.oracledatabase.GetCloudVmClusterRequest): + The request object. The request for ``CloudVmCluster.Get``. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -4251,30 +9113,24 @@ def __call__( be of type `bytes`. Returns: - ~.operations_pb2.Operation: - This resource represents a - long-running operation that is the - result of a network API call. + ~.vm_cluster.CloudVmCluster: + Details of the Cloud VM Cluster + resource. + https://docs.oracle.com/en-us/iaas/api/#/en/database/20160918/CloudVmCluster/ """ - http_options = ( - _BaseOracleDatabaseRestTransport._BaseCreateDbSystem._get_http_options() - ) + http_options = _BaseOracleDatabaseRestTransport._BaseGetCloudVmCluster._get_http_options() - request, metadata = self._interceptor.pre_create_db_system( + request, metadata = self._interceptor.pre_get_cloud_vm_cluster( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseCreateDbSystem._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseGetCloudVmCluster._get_transcoded_request( http_options, request ) - body = _BaseOracleDatabaseRestTransport._BaseCreateDbSystem._get_request_body_json( - transcoded_request - ) - # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseCreateDbSystem._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseGetCloudVmCluster._get_query_params_json( transcoded_request ) @@ -4296,24 +9152,23 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.CreateDbSystem", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.GetCloudVmCluster", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "CreateDbSystem", + "rpcName": "GetCloudVmCluster", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._CreateDbSystem._get_response( + response = OracleDatabaseRestTransport._GetCloudVmCluster._get_response( self._host, metadata, query_params, self._session, timeout, transcoded_request, - body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -4322,19 +9177,21 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = operations_pb2.Operation() - json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = vm_cluster.CloudVmCluster() + pb_resp = vm_cluster.CloudVmCluster.pb(resp) - resp = self._interceptor.post_create_db_system(resp) + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_cloud_vm_cluster(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_create_db_system_with_metadata( + resp, _ = self._interceptor.post_get_cloud_vm_cluster_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = json_format.MessageToJson(resp) + response_payload = vm_cluster.CloudVmCluster.to_json(response) except: response_payload = None http_response = { @@ -4343,22 +9200,21 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.create_db_system", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.get_cloud_vm_cluster", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "CreateDbSystem", + "rpcName": "GetCloudVmCluster", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _CreateExadbVmCluster( - _BaseOracleDatabaseRestTransport._BaseCreateExadbVmCluster, - OracleDatabaseRestStub, + class _GetDatabase( + _BaseOracleDatabaseRestTransport._BaseGetDatabase, OracleDatabaseRestStub ): def __hash__(self): - return hash("OracleDatabaseRestTransport.CreateExadbVmCluster") + return hash("OracleDatabaseRestTransport.GetDatabase") @staticmethod def _get_response( @@ -4379,23 +9235,22 @@ def _get_response( timeout=timeout, headers=headers, params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, ) return response def __call__( self, - request: oracledatabase.CreateExadbVmClusterRequest, + request: database.GetDatabaseRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> operations_pb2.Operation: - r"""Call the create exadb vm cluster method over HTTP. + ) -> database.Database: + r"""Call the get database method over HTTP. Args: - request (~.oracledatabase.CreateExadbVmClusterRequest): - The request object. The request for ``ExadbVmCluster.Create``. + request (~.database.GetDatabaseRequest): + The request object. The request for ``Database.Get``. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -4405,28 +9260,23 @@ def __call__( be of type `bytes`. Returns: - ~.operations_pb2.Operation: - This resource represents a - long-running operation that is the - result of a network API call. + ~.database.Database: + Details of the Database resource. + https://docs.oracle.com/en-us/iaas/api/#/en/database/20160918/Database/ """ - http_options = _BaseOracleDatabaseRestTransport._BaseCreateExadbVmCluster._get_http_options() - - request, metadata = self._interceptor.pre_create_exadb_vm_cluster( - request, metadata - ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseCreateExadbVmCluster._get_transcoded_request( - http_options, request + http_options = ( + _BaseOracleDatabaseRestTransport._BaseGetDatabase._get_http_options() ) - body = _BaseOracleDatabaseRestTransport._BaseCreateExadbVmCluster._get_request_body_json( - transcoded_request + request, metadata = self._interceptor.pre_get_database(request, metadata) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseGetDatabase._get_transcoded_request( + http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseCreateExadbVmCluster._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseGetDatabase._get_query_params_json( transcoded_request ) @@ -4448,24 +9298,23 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.CreateExadbVmCluster", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.GetDatabase", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "CreateExadbVmCluster", + "rpcName": "GetDatabase", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._CreateExadbVmCluster._get_response( + response = OracleDatabaseRestTransport._GetDatabase._get_response( self._host, metadata, query_params, self._session, timeout, transcoded_request, - body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -4474,19 +9323,21 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = operations_pb2.Operation() - json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = database.Database() + pb_resp = database.Database.pb(resp) - resp = self._interceptor.post_create_exadb_vm_cluster(resp) + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_database(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_create_exadb_vm_cluster_with_metadata( + resp, _ = self._interceptor.post_get_database_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = json_format.MessageToJson(resp) + response_payload = database.Database.to_json(response) except: response_payload = None http_response = { @@ -4495,22 +9346,21 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.create_exadb_vm_cluster", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.get_database", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "CreateExadbVmCluster", + "rpcName": "GetDatabase", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _CreateExascaleDbStorageVault( - _BaseOracleDatabaseRestTransport._BaseCreateExascaleDbStorageVault, - OracleDatabaseRestStub, + class _GetDbSystem( + _BaseOracleDatabaseRestTransport._BaseGetDbSystem, OracleDatabaseRestStub ): def __hash__(self): - return hash("OracleDatabaseRestTransport.CreateExascaleDbStorageVault") + return hash("OracleDatabaseRestTransport.GetDbSystem") @staticmethod def _get_response( @@ -4531,55 +9381,49 @@ def _get_response( timeout=timeout, headers=headers, params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, ) return response def __call__( self, - request: gco_exascale_db_storage_vault.CreateExascaleDbStorageVaultRequest, + request: db_system.GetDbSystemRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> operations_pb2.Operation: - r"""Call the create exascale db - storage vault method over HTTP. + ) -> db_system.DbSystem: + r"""Call the get db system method over HTTP. - Args: - request (~.gco_exascale_db_storage_vault.CreateExascaleDbStorageVaultRequest): - The request object. The request for ``ExascaleDbStorageVault.Create``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + Args: + request (~.db_system.GetDbSystemRequest): + The request object. The request for ``DbSystem.Get``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. - Returns: - ~.operations_pb2.Operation: - This resource represents a - long-running operation that is the - result of a network API call. + Returns: + ~.db_system.DbSystem: + Details of the DbSystem (BaseDB) + resource. + https://docs.oracle.com/en-us/iaas/api/#/en/database/20160918/DbSystem/ """ - http_options = _BaseOracleDatabaseRestTransport._BaseCreateExascaleDbStorageVault._get_http_options() - - request, metadata = self._interceptor.pre_create_exascale_db_storage_vault( - request, metadata - ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseCreateExascaleDbStorageVault._get_transcoded_request( - http_options, request + http_options = ( + _BaseOracleDatabaseRestTransport._BaseGetDbSystem._get_http_options() ) - body = _BaseOracleDatabaseRestTransport._BaseCreateExascaleDbStorageVault._get_request_body_json( - transcoded_request + request, metadata = self._interceptor.pre_get_db_system(request, metadata) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseGetDbSystem._get_transcoded_request( + http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseCreateExascaleDbStorageVault._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseGetDbSystem._get_query_params_json( transcoded_request ) @@ -4601,26 +9445,23 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.CreateExascaleDbStorageVault", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.GetDbSystem", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "CreateExascaleDbStorageVault", + "rpcName": "GetDbSystem", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = ( - OracleDatabaseRestTransport._CreateExascaleDbStorageVault._get_response( - self._host, - metadata, - query_params, - self._session, - timeout, - transcoded_request, - body, - ) + response = OracleDatabaseRestTransport._GetDbSystem._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -4629,21 +9470,21 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = operations_pb2.Operation() - json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = db_system.DbSystem() + pb_resp = db_system.DbSystem.pb(resp) - resp = self._interceptor.post_create_exascale_db_storage_vault(resp) + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_db_system(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = ( - self._interceptor.post_create_exascale_db_storage_vault_with_metadata( - resp, response_metadata - ) + resp, _ = self._interceptor.post_get_db_system_with_metadata( + resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = json_format.MessageToJson(resp) + response_payload = db_system.DbSystem.to_json(response) except: response_payload = None http_response = { @@ -4652,21 +9493,21 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.create_exascale_db_storage_vault", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.get_db_system", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "CreateExascaleDbStorageVault", + "rpcName": "GetDbSystem", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _CreateOdbNetwork( - _BaseOracleDatabaseRestTransport._BaseCreateOdbNetwork, OracleDatabaseRestStub + class _GetExadbVmCluster( + _BaseOracleDatabaseRestTransport._BaseGetExadbVmCluster, OracleDatabaseRestStub ): def __hash__(self): - return hash("OracleDatabaseRestTransport.CreateOdbNetwork") + return hash("OracleDatabaseRestTransport.GetExadbVmCluster") @staticmethod def _get_response( @@ -4687,23 +9528,22 @@ def _get_response( timeout=timeout, headers=headers, params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, ) return response def __call__( self, - request: gco_odb_network.CreateOdbNetworkRequest, + request: oracledatabase.GetExadbVmClusterRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> operations_pb2.Operation: - r"""Call the create odb network method over HTTP. + ) -> exadb_vm_cluster.ExadbVmCluster: + r"""Call the get exadb vm cluster method over HTTP. Args: - request (~.gco_odb_network.CreateOdbNetworkRequest): - The request object. The request for ``OdbNetwork.Create``. + request (~.oracledatabase.GetExadbVmClusterRequest): + The request object. The request for ``ExadbVmCluster.Get``. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -4713,28 +9553,25 @@ def __call__( be of type `bytes`. Returns: - ~.operations_pb2.Operation: - This resource represents a - long-running operation that is the - result of a network API call. + ~.exadb_vm_cluster.ExadbVmCluster: + ExadbVmCluster represents a cluster + of VMs that are used to run Exadata + workloads. + https://docs.oracle.com/en-us/iaas/api/#/en/database/20160918/ExadbVmCluster/ """ - http_options = _BaseOracleDatabaseRestTransport._BaseCreateOdbNetwork._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseGetExadbVmCluster._get_http_options() - request, metadata = self._interceptor.pre_create_odb_network( + request, metadata = self._interceptor.pre_get_exadb_vm_cluster( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseCreateOdbNetwork._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseGetExadbVmCluster._get_transcoded_request( http_options, request ) - body = _BaseOracleDatabaseRestTransport._BaseCreateOdbNetwork._get_request_body_json( - transcoded_request - ) - # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseCreateOdbNetwork._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseGetExadbVmCluster._get_query_params_json( transcoded_request ) @@ -4756,24 +9593,23 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.CreateOdbNetwork", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.GetExadbVmCluster", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "CreateOdbNetwork", + "rpcName": "GetExadbVmCluster", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._CreateOdbNetwork._get_response( + response = OracleDatabaseRestTransport._GetExadbVmCluster._get_response( self._host, metadata, query_params, self._session, timeout, transcoded_request, - body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -4782,19 +9618,21 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = operations_pb2.Operation() - json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = exadb_vm_cluster.ExadbVmCluster() + pb_resp = exadb_vm_cluster.ExadbVmCluster.pb(resp) - resp = self._interceptor.post_create_odb_network(resp) + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_exadb_vm_cluster(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_create_odb_network_with_metadata( + resp, _ = self._interceptor.post_get_exadb_vm_cluster_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = json_format.MessageToJson(resp) + response_payload = exadb_vm_cluster.ExadbVmCluster.to_json(response) except: response_payload = None http_response = { @@ -4803,21 +9641,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.create_odb_network", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.get_exadb_vm_cluster", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "CreateOdbNetwork", + "rpcName": "GetExadbVmCluster", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _CreateOdbSubnet( - _BaseOracleDatabaseRestTransport._BaseCreateOdbSubnet, OracleDatabaseRestStub + class _GetExascaleDbStorageVault( + _BaseOracleDatabaseRestTransport._BaseGetExascaleDbStorageVault, + OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.CreateOdbSubnet") + return hash("OracleDatabaseRestTransport.GetExascaleDbStorageVault") @staticmethod def _get_response( @@ -4838,54 +9677,50 @@ def _get_response( timeout=timeout, headers=headers, params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, ) return response def __call__( self, - request: gco_odb_subnet.CreateOdbSubnetRequest, + request: exascale_db_storage_vault.GetExascaleDbStorageVaultRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> operations_pb2.Operation: - r"""Call the create odb subnet method over HTTP. + ) -> exascale_db_storage_vault.ExascaleDbStorageVault: + r"""Call the get exascale db storage + vault method over HTTP. - Args: - request (~.gco_odb_subnet.CreateOdbSubnetRequest): - The request object. The request for ``OdbSubnet.Create``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + Args: + request (~.exascale_db_storage_vault.GetExascaleDbStorageVaultRequest): + The request object. The request for ``ExascaleDbStorageVault.Get``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. - Returns: - ~.operations_pb2.Operation: - This resource represents a - long-running operation that is the - result of a network API call. + Returns: + ~.exascale_db_storage_vault.ExascaleDbStorageVault: + ExascaleDbStorageVault represents a + storage vault exadb vm cluster resource. + https://docs.oracle.com/en-us/iaas/api/#/en/database/20160918/ExascaleDbStorageVault/ """ - http_options = _BaseOracleDatabaseRestTransport._BaseCreateOdbSubnet._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseGetExascaleDbStorageVault._get_http_options() - request, metadata = self._interceptor.pre_create_odb_subnet( + request, metadata = self._interceptor.pre_get_exascale_db_storage_vault( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseCreateOdbSubnet._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseGetExascaleDbStorageVault._get_transcoded_request( http_options, request ) - body = _BaseOracleDatabaseRestTransport._BaseCreateOdbSubnet._get_request_body_json( - transcoded_request - ) - # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseCreateOdbSubnet._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseGetExascaleDbStorageVault._get_query_params_json( transcoded_request ) @@ -4907,24 +9742,25 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.CreateOdbSubnet", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.GetExascaleDbStorageVault", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "CreateOdbSubnet", + "rpcName": "GetExascaleDbStorageVault", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._CreateOdbSubnet._get_response( - self._host, - metadata, - query_params, - self._session, - timeout, - transcoded_request, - body, + response = ( + OracleDatabaseRestTransport._GetExascaleDbStorageVault._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -4933,19 +9769,27 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = operations_pb2.Operation() - json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = exascale_db_storage_vault.ExascaleDbStorageVault() + pb_resp = exascale_db_storage_vault.ExascaleDbStorageVault.pb(resp) - resp = self._interceptor.post_create_odb_subnet(resp) + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_exascale_db_storage_vault(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_create_odb_subnet_with_metadata( - resp, response_metadata + resp, _ = ( + self._interceptor.post_get_exascale_db_storage_vault_with_metadata( + resp, response_metadata + ) ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = json_format.MessageToJson(resp) + response_payload = ( + exascale_db_storage_vault.ExascaleDbStorageVault.to_json( + response + ) + ) except: response_payload = None http_response = { @@ -4954,22 +9798,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.create_odb_subnet", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.get_exascale_db_storage_vault", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "CreateOdbSubnet", + "rpcName": "GetExascaleDbStorageVault", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _DeleteAutonomousDatabase( - _BaseOracleDatabaseRestTransport._BaseDeleteAutonomousDatabase, + class _GetGoldengateConnection( + _BaseOracleDatabaseRestTransport._BaseGetGoldengateConnection, OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.DeleteAutonomousDatabase") + return hash("OracleDatabaseRestTransport.GetGoldengateConnection") @staticmethod def _get_response( @@ -4995,45 +9839,43 @@ def _get_response( def __call__( self, - request: oracledatabase.DeleteAutonomousDatabaseRequest, + request: goldengate_connection.GetGoldengateConnectionRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> operations_pb2.Operation: - r"""Call the delete autonomous - database method over HTTP. + ) -> goldengate_connection.GoldengateConnection: + r"""Call the get goldengate connection method over HTTP. - Args: - request (~.oracledatabase.DeleteAutonomousDatabaseRequest): - The request object. The request for ``AutonomousDatabase.Delete``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + Args: + request (~.goldengate_connection.GetGoldengateConnectionRequest): + The request object. The request for ``GoldengateConnection.Get``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. - Returns: - ~.operations_pb2.Operation: - This resource represents a - long-running operation that is the - result of a network API call. + Returns: + ~.goldengate_connection.GoldengateConnection: + Details of the GoldengateConnection + resource. """ - http_options = _BaseOracleDatabaseRestTransport._BaseDeleteAutonomousDatabase._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseGetGoldengateConnection._get_http_options() - request, metadata = self._interceptor.pre_delete_autonomous_database( + request, metadata = self._interceptor.pre_get_goldengate_connection( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseDeleteAutonomousDatabase._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseGetGoldengateConnection._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseDeleteAutonomousDatabase._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseGetGoldengateConnection._get_query_params_json( transcoded_request ) @@ -5055,10 +9897,10 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.DeleteAutonomousDatabase", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.GetGoldengateConnection", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "DeleteAutonomousDatabase", + "rpcName": "GetGoldengateConnection", "httpRequest": http_request, "metadata": http_request["headers"], }, @@ -5066,7 +9908,7 @@ def __call__( # Send the request response = ( - OracleDatabaseRestTransport._DeleteAutonomousDatabase._get_response( + OracleDatabaseRestTransport._GetGoldengateConnection._get_response( self._host, metadata, query_params, @@ -5082,19 +9924,23 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = operations_pb2.Operation() - json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = goldengate_connection.GoldengateConnection() + pb_resp = goldengate_connection.GoldengateConnection.pb(resp) - resp = self._interceptor.post_delete_autonomous_database(resp) + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_goldengate_connection(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_delete_autonomous_database_with_metadata( + resp, _ = self._interceptor.post_get_goldengate_connection_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = json_format.MessageToJson(resp) + response_payload = ( + goldengate_connection.GoldengateConnection.to_json(response) + ) except: response_payload = None http_response = { @@ -5103,22 +9949,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_autonomous_database", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.get_goldengate_connection", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "DeleteAutonomousDatabase", + "rpcName": "GetGoldengateConnection", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _DeleteCloudExadataInfrastructure( - _BaseOracleDatabaseRestTransport._BaseDeleteCloudExadataInfrastructure, + class _GetGoldengateConnectionAssignment( + _BaseOracleDatabaseRestTransport._BaseGetGoldengateConnectionAssignment, OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.DeleteCloudExadataInfrastructure") + return hash("OracleDatabaseRestTransport.GetGoldengateConnectionAssignment") @staticmethod def _get_response( @@ -5144,18 +9990,19 @@ def _get_response( def __call__( self, - request: oracledatabase.DeleteCloudExadataInfrastructureRequest, + request: goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> operations_pb2.Operation: - r"""Call the delete cloud exadata - infrastructure method over HTTP. + ) -> goldengate_connection_assignment.GoldengateConnectionAssignment: + r"""Call the get goldengate connection + assignment method over HTTP. Args: - request (~.oracledatabase.DeleteCloudExadataInfrastructureRequest): - The request object. The request for ``CloudExadataInfrastructure.Delete``. + request (~.goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest): + The request object. Request message for getting a + GoldengateConnectionAssignment. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -5165,26 +10012,25 @@ def __call__( be of type `bytes`. Returns: - ~.operations_pb2.Operation: - This resource represents a - long-running operation that is the - result of a network API call. + ~.goldengate_connection_assignment.GoldengateConnectionAssignment: + Represents the metadata of a + Goldengate Connection Assignment. """ - http_options = _BaseOracleDatabaseRestTransport._BaseDeleteCloudExadataInfrastructure._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseGetGoldengateConnectionAssignment._get_http_options() request, metadata = ( - self._interceptor.pre_delete_cloud_exadata_infrastructure( + self._interceptor.pre_get_goldengate_connection_assignment( request, metadata ) ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseDeleteCloudExadataInfrastructure._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseGetGoldengateConnectionAssignment._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseDeleteCloudExadataInfrastructure._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseGetGoldengateConnectionAssignment._get_query_params_json( transcoded_request ) @@ -5206,17 +10052,17 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.DeleteCloudExadataInfrastructure", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.GetGoldengateConnectionAssignment", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "DeleteCloudExadataInfrastructure", + "rpcName": "GetGoldengateConnectionAssignment", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._DeleteCloudExadataInfrastructure._get_response( + response = OracleDatabaseRestTransport._GetGoldengateConnectionAssignment._get_response( self._host, metadata, query_params, @@ -5231,13 +10077,17 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = operations_pb2.Operation() - json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = goldengate_connection_assignment.GoldengateConnectionAssignment() + pb_resp = ( + goldengate_connection_assignment.GoldengateConnectionAssignment.pb(resp) + ) - resp = self._interceptor.post_delete_cloud_exadata_infrastructure(resp) + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_goldengate_connection_assignment(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] resp, _ = ( - self._interceptor.post_delete_cloud_exadata_infrastructure_with_metadata( + self._interceptor.post_get_goldengate_connection_assignment_with_metadata( resp, response_metadata ) ) @@ -5245,7 +10095,9 @@ def __call__( logging.DEBUG ): # pragma: NO COVER try: - response_payload = json_format.MessageToJson(resp) + response_payload = goldengate_connection_assignment.GoldengateConnectionAssignment.to_json( + response + ) except: response_payload = None http_response = { @@ -5254,22 +10106,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_cloud_exadata_infrastructure", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.get_goldengate_connection_assignment", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "DeleteCloudExadataInfrastructure", + "rpcName": "GetGoldengateConnectionAssignment", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _DeleteCloudVmCluster( - _BaseOracleDatabaseRestTransport._BaseDeleteCloudVmCluster, + class _GetGoldengateConnectionType( + _BaseOracleDatabaseRestTransport._BaseGetGoldengateConnectionType, OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.DeleteCloudVmCluster") + return hash("OracleDatabaseRestTransport.GetGoldengateConnectionType") @staticmethod def _get_response( @@ -5295,44 +10147,45 @@ def _get_response( def __call__( self, - request: oracledatabase.DeleteCloudVmClusterRequest, + request: goldengate_connection_type.GetGoldengateConnectionTypeRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> operations_pb2.Operation: - r"""Call the delete cloud vm cluster method over HTTP. + ) -> goldengate_connection_type.GoldengateConnectionType: + r"""Call the get goldengate connection + type method over HTTP. - Args: - request (~.oracledatabase.DeleteCloudVmClusterRequest): - The request object. The request for ``CloudVmCluster.Delete``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + Args: + request (~.goldengate_connection_type.GetGoldengateConnectionTypeRequest): + The request object. Message for getting a + GoldengateConnectionType. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. - Returns: - ~.operations_pb2.Operation: - This resource represents a - long-running operation that is the - result of a network API call. + Returns: + ~.goldengate_connection_type.GoldengateConnectionType: + Details of the Goldengate Connection + Type resource. """ - http_options = _BaseOracleDatabaseRestTransport._BaseDeleteCloudVmCluster._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseGetGoldengateConnectionType._get_http_options() - request, metadata = self._interceptor.pre_delete_cloud_vm_cluster( + request, metadata = self._interceptor.pre_get_goldengate_connection_type( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseDeleteCloudVmCluster._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseGetGoldengateConnectionType._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseDeleteCloudVmCluster._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseGetGoldengateConnectionType._get_query_params_json( transcoded_request ) @@ -5354,23 +10207,25 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.DeleteCloudVmCluster", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.GetGoldengateConnectionType", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "DeleteCloudVmCluster", + "rpcName": "GetGoldengateConnectionType", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._DeleteCloudVmCluster._get_response( - self._host, - metadata, - query_params, - self._session, - timeout, - transcoded_request, + response = ( + OracleDatabaseRestTransport._GetGoldengateConnectionType._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -5379,19 +10234,27 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = operations_pb2.Operation() - json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = goldengate_connection_type.GoldengateConnectionType() + pb_resp = goldengate_connection_type.GoldengateConnectionType.pb(resp) - resp = self._interceptor.post_delete_cloud_vm_cluster(resp) + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_goldengate_connection_type(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_delete_cloud_vm_cluster_with_metadata( - resp, response_metadata + resp, _ = ( + self._interceptor.post_get_goldengate_connection_type_with_metadata( + resp, response_metadata + ) ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = json_format.MessageToJson(resp) + response_payload = ( + goldengate_connection_type.GoldengateConnectionType.to_json( + response + ) + ) except: response_payload = None http_response = { @@ -5400,21 +10263,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_cloud_vm_cluster", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.get_goldengate_connection_type", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "DeleteCloudVmCluster", + "rpcName": "GetGoldengateConnectionType", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _DeleteDbSystem( - _BaseOracleDatabaseRestTransport._BaseDeleteDbSystem, OracleDatabaseRestStub + class _GetGoldengateDeployment( + _BaseOracleDatabaseRestTransport._BaseGetGoldengateDeployment, + OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.DeleteDbSystem") + return hash("OracleDatabaseRestTransport.GetGoldengateDeployment") @staticmethod def _get_response( @@ -5440,17 +10304,17 @@ def _get_response( def __call__( self, - request: db_system.DeleteDbSystemRequest, + request: goldengate_deployment.GetGoldengateDeploymentRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> operations_pb2.Operation: - r"""Call the delete db system method over HTTP. + ) -> goldengate_deployment.GoldengateDeployment: + r"""Call the get goldengate deployment method over HTTP. Args: - request (~.db_system.DeleteDbSystemRequest): - The request object. The request for ``DbSystem.Delete``. + request (~.goldengate_deployment.GetGoldengateDeploymentRequest): + The request object. The request for ``GoldengateDeployment.Get``. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -5460,26 +10324,23 @@ def __call__( be of type `bytes`. Returns: - ~.operations_pb2.Operation: - This resource represents a - long-running operation that is the - result of a network API call. + ~.goldengate_deployment.GoldengateDeployment: + GoldengateDeployment Goldengate + Deployment resource model. """ - http_options = ( - _BaseOracleDatabaseRestTransport._BaseDeleteDbSystem._get_http_options() - ) + http_options = _BaseOracleDatabaseRestTransport._BaseGetGoldengateDeployment._get_http_options() - request, metadata = self._interceptor.pre_delete_db_system( + request, metadata = self._interceptor.pre_get_goldengate_deployment( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseDeleteDbSystem._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseGetGoldengateDeployment._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseDeleteDbSystem._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseGetGoldengateDeployment._get_query_params_json( transcoded_request ) @@ -5501,23 +10362,25 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.DeleteDbSystem", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.GetGoldengateDeployment", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "DeleteDbSystem", + "rpcName": "GetGoldengateDeployment", "httpRequest": http_request, "metadata": http_request["headers"], }, ) - - # Send the request - response = OracleDatabaseRestTransport._DeleteDbSystem._get_response( - self._host, - metadata, - query_params, - self._session, - timeout, - transcoded_request, + + # Send the request + response = ( + OracleDatabaseRestTransport._GetGoldengateDeployment._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -5526,19 +10389,23 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = operations_pb2.Operation() - json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = goldengate_deployment.GoldengateDeployment() + pb_resp = goldengate_deployment.GoldengateDeployment.pb(resp) - resp = self._interceptor.post_delete_db_system(resp) + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_goldengate_deployment(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_delete_db_system_with_metadata( + resp, _ = self._interceptor.post_get_goldengate_deployment_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = json_format.MessageToJson(resp) + response_payload = ( + goldengate_deployment.GoldengateDeployment.to_json(response) + ) except: response_payload = None http_response = { @@ -5547,22 +10414,24 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_db_system", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.get_goldengate_deployment", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "DeleteDbSystem", + "rpcName": "GetGoldengateDeployment", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _DeleteExadbVmCluster( - _BaseOracleDatabaseRestTransport._BaseDeleteExadbVmCluster, + class _GetGoldengateDeploymentEnvironment( + _BaseOracleDatabaseRestTransport._BaseGetGoldengateDeploymentEnvironment, OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.DeleteExadbVmCluster") + return hash( + "OracleDatabaseRestTransport.GetGoldengateDeploymentEnvironment" + ) @staticmethod def _get_response( @@ -5588,44 +10457,47 @@ def _get_response( def __call__( self, - request: oracledatabase.DeleteExadbVmClusterRequest, + request: goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> operations_pb2.Operation: - r"""Call the delete exadb vm cluster method over HTTP. + ) -> goldengate_deployment_environment.GoldengateDeploymentEnvironment: + r"""Call the get goldengate deployment + environment method over HTTP. - Args: - request (~.oracledatabase.DeleteExadbVmClusterRequest): - The request object. The request for ``ExadbVmCluster.Delete``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + Args: + request (~.goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest): + The request object. Message for getting a + GoldengateDeploymentEnvironment. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. - Returns: - ~.operations_pb2.Operation: - This resource represents a - long-running operation that is the - result of a network API call. + Returns: + ~.goldengate_deployment_environment.GoldengateDeploymentEnvironment: + Details of the Goldengate Deployment + Environment resource. """ - http_options = _BaseOracleDatabaseRestTransport._BaseDeleteExadbVmCluster._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseGetGoldengateDeploymentEnvironment._get_http_options() - request, metadata = self._interceptor.pre_delete_exadb_vm_cluster( - request, metadata + request, metadata = ( + self._interceptor.pre_get_goldengate_deployment_environment( + request, metadata + ) ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseDeleteExadbVmCluster._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseGetGoldengateDeploymentEnvironment._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseDeleteExadbVmCluster._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseGetGoldengateDeploymentEnvironment._get_query_params_json( transcoded_request ) @@ -5647,17 +10519,17 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.DeleteExadbVmCluster", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.GetGoldengateDeploymentEnvironment", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "DeleteExadbVmCluster", + "rpcName": "GetGoldengateDeploymentEnvironment", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._DeleteExadbVmCluster._get_response( + response = OracleDatabaseRestTransport._GetGoldengateDeploymentEnvironment._get_response( self._host, metadata, query_params, @@ -5672,19 +10544,29 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = operations_pb2.Operation() - json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = goldengate_deployment_environment.GoldengateDeploymentEnvironment() + pb_resp = ( + goldengate_deployment_environment.GoldengateDeploymentEnvironment.pb( + resp + ) + ) - resp = self._interceptor.post_delete_exadb_vm_cluster(resp) + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_goldengate_deployment_environment(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_delete_exadb_vm_cluster_with_metadata( - resp, response_metadata + resp, _ = ( + self._interceptor.post_get_goldengate_deployment_environment_with_metadata( + resp, response_metadata + ) ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = json_format.MessageToJson(resp) + response_payload = goldengate_deployment_environment.GoldengateDeploymentEnvironment.to_json( + response + ) except: response_payload = None http_response = { @@ -5693,22 +10575,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_exadb_vm_cluster", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.get_goldengate_deployment_environment", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "DeleteExadbVmCluster", + "rpcName": "GetGoldengateDeploymentEnvironment", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _DeleteExascaleDbStorageVault( - _BaseOracleDatabaseRestTransport._BaseDeleteExascaleDbStorageVault, + class _GetGoldengateDeploymentType( + _BaseOracleDatabaseRestTransport._BaseGetGoldengateDeploymentType, OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.DeleteExascaleDbStorageVault") + return hash("OracleDatabaseRestTransport.GetGoldengateDeploymentType") @staticmethod def _get_response( @@ -5734,19 +10616,19 @@ def _get_response( def __call__( self, - request: exascale_db_storage_vault.DeleteExascaleDbStorageVaultRequest, + request: goldengate_deployment_type.GetGoldengateDeploymentTypeRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> operations_pb2.Operation: - r"""Call the delete exascale db - storage vault method over HTTP. + ) -> goldengate_deployment_type.GoldengateDeploymentType: + r"""Call the get goldengate deployment + type method over HTTP. Args: - request (~.exascale_db_storage_vault.DeleteExascaleDbStorageVaultRequest): - The request object. The request message for - ``ExascaleDbStorageVault.Delete``. + request (~.goldengate_deployment_type.GetGoldengateDeploymentTypeRequest): + The request object. Message for getting a + GoldengateDeploymentType. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -5756,24 +10638,23 @@ def __call__( be of type `bytes`. Returns: - ~.operations_pb2.Operation: - This resource represents a - long-running operation that is the - result of a network API call. + ~.goldengate_deployment_type.GoldengateDeploymentType: + Details of the Goldengate Deployment + Type resource. """ - http_options = _BaseOracleDatabaseRestTransport._BaseDeleteExascaleDbStorageVault._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseGetGoldengateDeploymentType._get_http_options() - request, metadata = self._interceptor.pre_delete_exascale_db_storage_vault( + request, metadata = self._interceptor.pre_get_goldengate_deployment_type( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseDeleteExascaleDbStorageVault._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseGetGoldengateDeploymentType._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseDeleteExascaleDbStorageVault._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseGetGoldengateDeploymentType._get_query_params_json( transcoded_request ) @@ -5795,10 +10676,10 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.DeleteExascaleDbStorageVault", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.GetGoldengateDeploymentType", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "DeleteExascaleDbStorageVault", + "rpcName": "GetGoldengateDeploymentType", "httpRequest": http_request, "metadata": http_request["headers"], }, @@ -5806,7 +10687,7 @@ def __call__( # Send the request response = ( - OracleDatabaseRestTransport._DeleteExascaleDbStorageVault._get_response( + OracleDatabaseRestTransport._GetGoldengateDeploymentType._get_response( self._host, metadata, query_params, @@ -5822,13 +10703,15 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = operations_pb2.Operation() - json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = goldengate_deployment_type.GoldengateDeploymentType() + pb_resp = goldengate_deployment_type.GoldengateDeploymentType.pb(resp) - resp = self._interceptor.post_delete_exascale_db_storage_vault(resp) + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_goldengate_deployment_type(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] resp, _ = ( - self._interceptor.post_delete_exascale_db_storage_vault_with_metadata( + self._interceptor.post_get_goldengate_deployment_type_with_metadata( resp, response_metadata ) ) @@ -5836,7 +10719,11 @@ def __call__( logging.DEBUG ): # pragma: NO COVER try: - response_payload = json_format.MessageToJson(resp) + response_payload = ( + goldengate_deployment_type.GoldengateDeploymentType.to_json( + response + ) + ) except: response_payload = None http_response = { @@ -5845,21 +10732,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_exascale_db_storage_vault", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.get_goldengate_deployment_type", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "DeleteExascaleDbStorageVault", + "rpcName": "GetGoldengateDeploymentType", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _DeleteOdbNetwork( - _BaseOracleDatabaseRestTransport._BaseDeleteOdbNetwork, OracleDatabaseRestStub + class _GetGoldengateDeploymentVersion( + _BaseOracleDatabaseRestTransport._BaseGetGoldengateDeploymentVersion, + OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.DeleteOdbNetwork") + return hash("OracleDatabaseRestTransport.GetGoldengateDeploymentVersion") @staticmethod def _get_response( @@ -5885,44 +10773,45 @@ def _get_response( def __call__( self, - request: odb_network.DeleteOdbNetworkRequest, + request: goldengate_deployment_version.GetGoldengateDeploymentVersionRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> operations_pb2.Operation: - r"""Call the delete odb network method over HTTP. + ) -> goldengate_deployment_version.GoldengateDeploymentVersion: + r"""Call the get goldengate deployment + version method over HTTP. - Args: - request (~.odb_network.DeleteOdbNetworkRequest): - The request object. The request for ``OdbNetwork.Delete``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + Args: + request (~.goldengate_deployment_version.GetGoldengateDeploymentVersionRequest): + The request object. Message for getting a + GoldengateDeploymentVersion. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. - Returns: - ~.operations_pb2.Operation: - This resource represents a - long-running operation that is the - result of a network API call. + Returns: + ~.goldengate_deployment_version.GoldengateDeploymentVersion: + Details of the Goldengate Deployment + Version resource. """ - http_options = _BaseOracleDatabaseRestTransport._BaseDeleteOdbNetwork._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseGetGoldengateDeploymentVersion._get_http_options() - request, metadata = self._interceptor.pre_delete_odb_network( + request, metadata = self._interceptor.pre_get_goldengate_deployment_version( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseDeleteOdbNetwork._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseGetGoldengateDeploymentVersion._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseDeleteOdbNetwork._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseGetGoldengateDeploymentVersion._get_query_params_json( transcoded_request ) @@ -5944,17 +10833,17 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.DeleteOdbNetwork", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.GetGoldengateDeploymentVersion", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "DeleteOdbNetwork", + "rpcName": "GetGoldengateDeploymentVersion", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._DeleteOdbNetwork._get_response( + response = OracleDatabaseRestTransport._GetGoldengateDeploymentVersion._get_response( self._host, metadata, query_params, @@ -5969,19 +10858,25 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = operations_pb2.Operation() - json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = goldengate_deployment_version.GoldengateDeploymentVersion() + pb_resp = goldengate_deployment_version.GoldengateDeploymentVersion.pb(resp) - resp = self._interceptor.post_delete_odb_network(resp) + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_goldengate_deployment_version(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_delete_odb_network_with_metadata( - resp, response_metadata + resp, _ = ( + self._interceptor.post_get_goldengate_deployment_version_with_metadata( + resp, response_metadata + ) ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = json_format.MessageToJson(resp) + response_payload = goldengate_deployment_version.GoldengateDeploymentVersion.to_json( + response + ) except: response_payload = None http_response = { @@ -5990,21 +10885,21 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_odb_network", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.get_goldengate_deployment_version", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "DeleteOdbNetwork", + "rpcName": "GetGoldengateDeploymentVersion", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _DeleteOdbSubnet( - _BaseOracleDatabaseRestTransport._BaseDeleteOdbSubnet, OracleDatabaseRestStub + class _GetOdbNetwork( + _BaseOracleDatabaseRestTransport._BaseGetOdbNetwork, OracleDatabaseRestStub ): def __hash__(self): - return hash("OracleDatabaseRestTransport.DeleteOdbSubnet") + return hash("OracleDatabaseRestTransport.GetOdbNetwork") @staticmethod def _get_response( @@ -6030,17 +10925,17 @@ def _get_response( def __call__( self, - request: odb_subnet.DeleteOdbSubnetRequest, + request: odb_network.GetOdbNetworkRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> operations_pb2.Operation: - r"""Call the delete odb subnet method over HTTP. + ) -> odb_network.OdbNetwork: + r"""Call the get odb network method over HTTP. Args: - request (~.odb_subnet.DeleteOdbSubnetRequest): - The request object. The request for ``OdbSubnet.Delete``. + request (~.odb_network.GetOdbNetworkRequest): + The request object. The request for ``OdbNetwork.Get``. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -6050,24 +10945,21 @@ def __call__( be of type `bytes`. Returns: - ~.operations_pb2.Operation: - This resource represents a - long-running operation that is the - result of a network API call. - + ~.odb_network.OdbNetwork: + Represents OdbNetwork resource. """ - http_options = _BaseOracleDatabaseRestTransport._BaseDeleteOdbSubnet._get_http_options() - - request, metadata = self._interceptor.pre_delete_odb_subnet( - request, metadata + http_options = ( + _BaseOracleDatabaseRestTransport._BaseGetOdbNetwork._get_http_options() ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseDeleteOdbSubnet._get_transcoded_request( + + request, metadata = self._interceptor.pre_get_odb_network(request, metadata) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseGetOdbNetwork._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseDeleteOdbSubnet._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseGetOdbNetwork._get_query_params_json( transcoded_request ) @@ -6089,17 +10981,17 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.DeleteOdbSubnet", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.GetOdbNetwork", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "DeleteOdbSubnet", + "rpcName": "GetOdbNetwork", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._DeleteOdbSubnet._get_response( + response = OracleDatabaseRestTransport._GetOdbNetwork._get_response( self._host, metadata, query_params, @@ -6114,19 +11006,21 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = operations_pb2.Operation() - json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = odb_network.OdbNetwork() + pb_resp = odb_network.OdbNetwork.pb(resp) - resp = self._interceptor.post_delete_odb_subnet(resp) + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_odb_network(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_delete_odb_subnet_with_metadata( + resp, _ = self._interceptor.post_get_odb_network_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = json_format.MessageToJson(resp) + response_payload = odb_network.OdbNetwork.to_json(response) except: response_payload = None http_response = { @@ -6135,22 +11029,21 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_odb_subnet", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.get_odb_network", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "DeleteOdbSubnet", + "rpcName": "GetOdbNetwork", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _FailoverAutonomousDatabase( - _BaseOracleDatabaseRestTransport._BaseFailoverAutonomousDatabase, - OracleDatabaseRestStub, + class _GetOdbSubnet( + _BaseOracleDatabaseRestTransport._BaseGetOdbSubnet, OracleDatabaseRestStub ): def __hash__(self): - return hash("OracleDatabaseRestTransport.FailoverAutonomousDatabase") + return hash("OracleDatabaseRestTransport.GetOdbSubnet") @staticmethod def _get_response( @@ -6171,56 +11064,46 @@ def _get_response( timeout=timeout, headers=headers, params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, ) return response def __call__( self, - request: oracledatabase.FailoverAutonomousDatabaseRequest, + request: odb_subnet.GetOdbSubnetRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> operations_pb2.Operation: - r"""Call the failover autonomous - database method over HTTP. - - Args: - request (~.oracledatabase.FailoverAutonomousDatabaseRequest): - The request object. The request for - ``OracleDatabase.FailoverAutonomousDatabase``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + ) -> odb_subnet.OdbSubnet: + r"""Call the get odb subnet method over HTTP. - Returns: - ~.operations_pb2.Operation: - This resource represents a - long-running operation that is the - result of a network API call. + Args: + request (~.odb_subnet.GetOdbSubnetRequest): + The request object. The request for ``OdbSubnet.Get``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.odb_subnet.OdbSubnet: + Represents OdbSubnet resource. """ - http_options = _BaseOracleDatabaseRestTransport._BaseFailoverAutonomousDatabase._get_http_options() - - request, metadata = self._interceptor.pre_failover_autonomous_database( - request, metadata - ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseFailoverAutonomousDatabase._get_transcoded_request( - http_options, request + http_options = ( + _BaseOracleDatabaseRestTransport._BaseGetOdbSubnet._get_http_options() ) - body = _BaseOracleDatabaseRestTransport._BaseFailoverAutonomousDatabase._get_request_body_json( - transcoded_request + request, metadata = self._interceptor.pre_get_odb_subnet(request, metadata) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseGetOdbSubnet._get_transcoded_request( + http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseFailoverAutonomousDatabase._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseGetOdbSubnet._get_query_params_json( transcoded_request ) @@ -6242,26 +11125,23 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.FailoverAutonomousDatabase", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.GetOdbSubnet", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "FailoverAutonomousDatabase", + "rpcName": "GetOdbSubnet", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = ( - OracleDatabaseRestTransport._FailoverAutonomousDatabase._get_response( - self._host, - metadata, - query_params, - self._session, - timeout, - transcoded_request, - body, - ) + response = OracleDatabaseRestTransport._GetOdbSubnet._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -6270,19 +11150,21 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = operations_pb2.Operation() - json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = odb_subnet.OdbSubnet() + pb_resp = odb_subnet.OdbSubnet.pb(resp) - resp = self._interceptor.post_failover_autonomous_database(resp) + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_odb_subnet(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_failover_autonomous_database_with_metadata( + resp, _ = self._interceptor.post_get_odb_subnet_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = json_format.MessageToJson(resp) + response_payload = odb_subnet.OdbSubnet.to_json(response) except: response_payload = None http_response = { @@ -6291,22 +11173,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.failover_autonomous_database", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.get_odb_subnet", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "FailoverAutonomousDatabase", + "rpcName": "GetOdbSubnet", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _GenerateAutonomousDatabaseWallet( - _BaseOracleDatabaseRestTransport._BaseGenerateAutonomousDatabaseWallet, + class _GetPluggableDatabase( + _BaseOracleDatabaseRestTransport._BaseGetPluggableDatabase, OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.GenerateAutonomousDatabaseWallet") + return hash("OracleDatabaseRestTransport.GetPluggableDatabase") @staticmethod def _get_response( @@ -6327,54 +11209,48 @@ def _get_response( timeout=timeout, headers=headers, params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, ) return response def __call__( self, - request: oracledatabase.GenerateAutonomousDatabaseWalletRequest, + request: pluggable_database.GetPluggableDatabaseRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> oracledatabase.GenerateAutonomousDatabaseWalletResponse: - r"""Call the generate autonomous - database wallet method over HTTP. + ) -> pluggable_database.PluggableDatabase: + r"""Call the get pluggable database method over HTTP. - Args: - request (~.oracledatabase.GenerateAutonomousDatabaseWalletRequest): - The request object. The request for ``AutonomousDatabase.GenerateWallet``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + Args: + request (~.pluggable_database.GetPluggableDatabaseRequest): + The request object. The request for ``PluggableDatabase.Get``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.pluggable_database.PluggableDatabase: + The PluggableDatabase resource. + https://docs.oracle.com/en-us/iaas/api/#/en/database/20160918/PluggableDatabase/ - Returns: - ~.oracledatabase.GenerateAutonomousDatabaseWalletResponse: - The response for ``AutonomousDatabase.GenerateWallet``. """ - http_options = _BaseOracleDatabaseRestTransport._BaseGenerateAutonomousDatabaseWallet._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseGetPluggableDatabase._get_http_options() - request, metadata = ( - self._interceptor.pre_generate_autonomous_database_wallet( - request, metadata - ) + request, metadata = self._interceptor.pre_get_pluggable_database( + request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseGenerateAutonomousDatabaseWallet._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseGetPluggableDatabase._get_transcoded_request( http_options, request ) - body = _BaseOracleDatabaseRestTransport._BaseGenerateAutonomousDatabaseWallet._get_request_body_json( - transcoded_request - ) - # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseGenerateAutonomousDatabaseWallet._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseGetPluggableDatabase._get_query_params_json( transcoded_request ) @@ -6396,24 +11272,23 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.GenerateAutonomousDatabaseWallet", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.GetPluggableDatabase", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "GenerateAutonomousDatabaseWallet", + "rpcName": "GetPluggableDatabase", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._GenerateAutonomousDatabaseWallet._get_response( + response = OracleDatabaseRestTransport._GetPluggableDatabase._get_response( self._host, metadata, query_params, self._session, timeout, transcoded_request, - body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -6422,26 +11297,22 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = oracledatabase.GenerateAutonomousDatabaseWalletResponse() - pb_resp = oracledatabase.GenerateAutonomousDatabaseWalletResponse.pb(resp) + resp = pluggable_database.PluggableDatabase() + pb_resp = pluggable_database.PluggableDatabase.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_generate_autonomous_database_wallet(resp) + resp = self._interceptor.post_get_pluggable_database(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = ( - self._interceptor.post_generate_autonomous_database_wallet_with_metadata( - resp, response_metadata - ) + resp, _ = self._interceptor.post_get_pluggable_database_with_metadata( + resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = ( - oracledatabase.GenerateAutonomousDatabaseWalletResponse.to_json( - response - ) + response_payload = pluggable_database.PluggableDatabase.to_json( + response ) except: response_payload = None @@ -6451,22 +11322,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.generate_autonomous_database_wallet", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.get_pluggable_database", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "GenerateAutonomousDatabaseWallet", + "rpcName": "GetPluggableDatabase", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _GetAutonomousDatabase( - _BaseOracleDatabaseRestTransport._BaseGetAutonomousDatabase, + class _ListAutonomousDatabaseBackups( + _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabaseBackups, OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.GetAutonomousDatabase") + return hash("OracleDatabaseRestTransport.ListAutonomousDatabaseBackups") @staticmethod def _get_response( @@ -6492,44 +11363,42 @@ def _get_response( def __call__( self, - request: oracledatabase.GetAutonomousDatabaseRequest, + request: oracledatabase.ListAutonomousDatabaseBackupsRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> autonomous_database.AutonomousDatabase: - r"""Call the get autonomous database method over HTTP. - - Args: - request (~.oracledatabase.GetAutonomousDatabaseRequest): - The request object. The request for ``AutonomousDatabase.Get``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + ) -> oracledatabase.ListAutonomousDatabaseBackupsResponse: + r"""Call the list autonomous database + backups method over HTTP. - Returns: - ~.autonomous_database.AutonomousDatabase: - Details of the Autonomous Database - resource. - https://docs.oracle.com/en-us/iaas/api/#/en/database/20160918/AutonomousDatabase/ + Args: + request (~.oracledatabase.ListAutonomousDatabaseBackupsRequest): + The request object. The request for ``AutonomousDatabaseBackup.List``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.oracledatabase.ListAutonomousDatabaseBackupsResponse: + The response for ``AutonomousDatabaseBackup.List``. """ - http_options = _BaseOracleDatabaseRestTransport._BaseGetAutonomousDatabase._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabaseBackups._get_http_options() - request, metadata = self._interceptor.pre_get_autonomous_database( + request, metadata = self._interceptor.pre_list_autonomous_database_backups( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseGetAutonomousDatabase._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabaseBackups._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseGetAutonomousDatabase._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabaseBackups._get_query_params_json( transcoded_request ) @@ -6551,17 +11420,17 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.GetAutonomousDatabase", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListAutonomousDatabaseBackups", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "GetAutonomousDatabase", + "rpcName": "ListAutonomousDatabaseBackups", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._GetAutonomousDatabase._get_response( + response = OracleDatabaseRestTransport._ListAutonomousDatabaseBackups._get_response( self._host, metadata, query_params, @@ -6576,22 +11445,26 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = autonomous_database.AutonomousDatabase() - pb_resp = autonomous_database.AutonomousDatabase.pb(resp) + resp = oracledatabase.ListAutonomousDatabaseBackupsResponse() + pb_resp = oracledatabase.ListAutonomousDatabaseBackupsResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_get_autonomous_database(resp) + resp = self._interceptor.post_list_autonomous_database_backups(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_get_autonomous_database_with_metadata( - resp, response_metadata + resp, _ = ( + self._interceptor.post_list_autonomous_database_backups_with_metadata( + resp, response_metadata + ) ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = autonomous_database.AutonomousDatabase.to_json( - response + response_payload = ( + oracledatabase.ListAutonomousDatabaseBackupsResponse.to_json( + response + ) ) except: response_payload = None @@ -6601,22 +11474,24 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.get_autonomous_database", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_autonomous_database_backups", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "GetAutonomousDatabase", + "rpcName": "ListAutonomousDatabaseBackups", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _GetCloudExadataInfrastructure( - _BaseOracleDatabaseRestTransport._BaseGetCloudExadataInfrastructure, + class _ListAutonomousDatabaseCharacterSets( + _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabaseCharacterSets, OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.GetCloudExadataInfrastructure") + return hash( + "OracleDatabaseRestTransport.ListAutonomousDatabaseCharacterSets" + ) @staticmethod def _get_response( @@ -6642,18 +11517,18 @@ def _get_response( def __call__( self, - request: oracledatabase.GetCloudExadataInfrastructureRequest, + request: oracledatabase.ListAutonomousDatabaseCharacterSetsRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> exadata_infra.CloudExadataInfrastructure: - r"""Call the get cloud exadata - infrastructure method over HTTP. + ) -> oracledatabase.ListAutonomousDatabaseCharacterSetsResponse: + r"""Call the list autonomous database + character sets method over HTTP. Args: - request (~.oracledatabase.GetCloudExadataInfrastructureRequest): - The request object. The request for ``CloudExadataInfrastructure.Get``. + request (~.oracledatabase.ListAutonomousDatabaseCharacterSetsRequest): + The request object. The request for ``AutonomousDatabaseCharacterSet.List``. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -6663,24 +11538,25 @@ def __call__( be of type `bytes`. Returns: - ~.exadata_infra.CloudExadataInfrastructure: - Represents CloudExadataInfrastructure - resource. - https://docs.oracle.com/en-us/iaas/api/#/en/database/20160918/CloudExadataInfrastructure/ + ~.oracledatabase.ListAutonomousDatabaseCharacterSetsResponse: + The response for + ``AutonomousDatabaseCharacterSet.List``. """ - http_options = _BaseOracleDatabaseRestTransport._BaseGetCloudExadataInfrastructure._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabaseCharacterSets._get_http_options() - request, metadata = self._interceptor.pre_get_cloud_exadata_infrastructure( - request, metadata + request, metadata = ( + self._interceptor.pre_list_autonomous_database_character_sets( + request, metadata + ) ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseGetCloudExadataInfrastructure._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabaseCharacterSets._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseGetCloudExadataInfrastructure._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabaseCharacterSets._get_query_params_json( transcoded_request ) @@ -6702,17 +11578,17 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.GetCloudExadataInfrastructure", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListAutonomousDatabaseCharacterSets", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "GetCloudExadataInfrastructure", + "rpcName": "ListAutonomousDatabaseCharacterSets", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._GetCloudExadataInfrastructure._get_response( + response = OracleDatabaseRestTransport._ListAutonomousDatabaseCharacterSets._get_response( self._host, metadata, query_params, @@ -6727,15 +11603,17 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = exadata_infra.CloudExadataInfrastructure() - pb_resp = exadata_infra.CloudExadataInfrastructure.pb(resp) + resp = oracledatabase.ListAutonomousDatabaseCharacterSetsResponse() + pb_resp = oracledatabase.ListAutonomousDatabaseCharacterSetsResponse.pb( + resp + ) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_get_cloud_exadata_infrastructure(resp) + resp = self._interceptor.post_list_autonomous_database_character_sets(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] resp, _ = ( - self._interceptor.post_get_cloud_exadata_infrastructure_with_metadata( + self._interceptor.post_list_autonomous_database_character_sets_with_metadata( resp, response_metadata ) ) @@ -6743,7 +11621,7 @@ def __call__( logging.DEBUG ): # pragma: NO COVER try: - response_payload = exadata_infra.CloudExadataInfrastructure.to_json( + response_payload = oracledatabase.ListAutonomousDatabaseCharacterSetsResponse.to_json( response ) except: @@ -6754,21 +11632,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.get_cloud_exadata_infrastructure", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_autonomous_database_character_sets", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "GetCloudExadataInfrastructure", + "rpcName": "ListAutonomousDatabaseCharacterSets", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _GetCloudVmCluster( - _BaseOracleDatabaseRestTransport._BaseGetCloudVmCluster, OracleDatabaseRestStub + class _ListAutonomousDatabases( + _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabases, + OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.GetCloudVmCluster") + return hash("OracleDatabaseRestTransport.ListAutonomousDatabases") @staticmethod def _get_response( @@ -6794,17 +11673,17 @@ def _get_response( def __call__( self, - request: oracledatabase.GetCloudVmClusterRequest, + request: oracledatabase.ListAutonomousDatabasesRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> vm_cluster.CloudVmCluster: - r"""Call the get cloud vm cluster method over HTTP. + ) -> oracledatabase.ListAutonomousDatabasesResponse: + r"""Call the list autonomous databases method over HTTP. Args: - request (~.oracledatabase.GetCloudVmClusterRequest): - The request object. The request for ``CloudVmCluster.Get``. + request (~.oracledatabase.ListAutonomousDatabasesRequest): + The request object. The request for ``AutonomousDatabase.List``. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -6814,24 +11693,21 @@ def __call__( be of type `bytes`. Returns: - ~.vm_cluster.CloudVmCluster: - Details of the Cloud VM Cluster - resource. - https://docs.oracle.com/en-us/iaas/api/#/en/database/20160918/CloudVmCluster/ - + ~.oracledatabase.ListAutonomousDatabasesResponse: + The response for ``AutonomousDatabase.List``. """ - http_options = _BaseOracleDatabaseRestTransport._BaseGetCloudVmCluster._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabases._get_http_options() - request, metadata = self._interceptor.pre_get_cloud_vm_cluster( + request, metadata = self._interceptor.pre_list_autonomous_databases( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseGetCloudVmCluster._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabases._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseGetCloudVmCluster._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabases._get_query_params_json( transcoded_request ) @@ -6853,23 +11729,25 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.GetCloudVmCluster", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListAutonomousDatabases", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "GetCloudVmCluster", + "rpcName": "ListAutonomousDatabases", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._GetCloudVmCluster._get_response( - self._host, - metadata, - query_params, - self._session, - timeout, - transcoded_request, + response = ( + OracleDatabaseRestTransport._ListAutonomousDatabases._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -6878,21 +11756,23 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = vm_cluster.CloudVmCluster() - pb_resp = vm_cluster.CloudVmCluster.pb(resp) + resp = oracledatabase.ListAutonomousDatabasesResponse() + pb_resp = oracledatabase.ListAutonomousDatabasesResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_get_cloud_vm_cluster(resp) + resp = self._interceptor.post_list_autonomous_databases(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_get_cloud_vm_cluster_with_metadata( + resp, _ = self._interceptor.post_list_autonomous_databases_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = vm_cluster.CloudVmCluster.to_json(response) + response_payload = ( + oracledatabase.ListAutonomousDatabasesResponse.to_json(response) + ) except: response_payload = None http_response = { @@ -6901,21 +11781,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.get_cloud_vm_cluster", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_autonomous_databases", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "GetCloudVmCluster", + "rpcName": "ListAutonomousDatabases", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _GetDatabase( - _BaseOracleDatabaseRestTransport._BaseGetDatabase, OracleDatabaseRestStub + class _ListAutonomousDbVersions( + _BaseOracleDatabaseRestTransport._BaseListAutonomousDbVersions, + OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.GetDatabase") + return hash("OracleDatabaseRestTransport.ListAutonomousDbVersions") @staticmethod def _get_response( @@ -6941,43 +11822,42 @@ def _get_response( def __call__( self, - request: database.GetDatabaseRequest, + request: oracledatabase.ListAutonomousDbVersionsRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> database.Database: - r"""Call the get database method over HTTP. - - Args: - request (~.database.GetDatabaseRequest): - The request object. The request for ``Database.Get``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + ) -> oracledatabase.ListAutonomousDbVersionsResponse: + r"""Call the list autonomous db + versions method over HTTP. - Returns: - ~.database.Database: - Details of the Database resource. - https://docs.oracle.com/en-us/iaas/api/#/en/database/20160918/Database/ + Args: + request (~.oracledatabase.ListAutonomousDbVersionsRequest): + The request object. The request for ``AutonomousDbVersion.List``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.oracledatabase.ListAutonomousDbVersionsResponse: + The response for ``AutonomousDbVersion.List``. """ - http_options = ( - _BaseOracleDatabaseRestTransport._BaseGetDatabase._get_http_options() - ) + http_options = _BaseOracleDatabaseRestTransport._BaseListAutonomousDbVersions._get_http_options() - request, metadata = self._interceptor.pre_get_database(request, metadata) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseGetDatabase._get_transcoded_request( + request, metadata = self._interceptor.pre_list_autonomous_db_versions( + request, metadata + ) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseListAutonomousDbVersions._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseGetDatabase._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseListAutonomousDbVersions._get_query_params_json( transcoded_request ) @@ -6999,23 +11879,25 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.GetDatabase", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListAutonomousDbVersions", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "GetDatabase", + "rpcName": "ListAutonomousDbVersions", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._GetDatabase._get_response( - self._host, - metadata, - query_params, - self._session, - timeout, - transcoded_request, + response = ( + OracleDatabaseRestTransport._ListAutonomousDbVersions._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -7024,21 +11906,25 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = database.Database() - pb_resp = database.Database.pb(resp) + resp = oracledatabase.ListAutonomousDbVersionsResponse() + pb_resp = oracledatabase.ListAutonomousDbVersionsResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_get_database(resp) + resp = self._interceptor.post_list_autonomous_db_versions(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_get_database_with_metadata( + resp, _ = self._interceptor.post_list_autonomous_db_versions_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = database.Database.to_json(response) + response_payload = ( + oracledatabase.ListAutonomousDbVersionsResponse.to_json( + response + ) + ) except: response_payload = None http_response = { @@ -7047,21 +11933,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.get_database", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_autonomous_db_versions", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "GetDatabase", + "rpcName": "ListAutonomousDbVersions", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _GetDbSystem( - _BaseOracleDatabaseRestTransport._BaseGetDbSystem, OracleDatabaseRestStub + class _ListCloudExadataInfrastructures( + _BaseOracleDatabaseRestTransport._BaseListCloudExadataInfrastructures, + OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.GetDbSystem") + return hash("OracleDatabaseRestTransport.ListCloudExadataInfrastructures") @staticmethod def _get_response( @@ -7087,44 +11974,44 @@ def _get_response( def __call__( self, - request: db_system.GetDbSystemRequest, + request: oracledatabase.ListCloudExadataInfrastructuresRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> db_system.DbSystem: - r"""Call the get db system method over HTTP. - - Args: - request (~.db_system.GetDbSystemRequest): - The request object. The request for ``DbSystem.Get``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + ) -> oracledatabase.ListCloudExadataInfrastructuresResponse: + r"""Call the list cloud exadata + infrastructures method over HTTP. - Returns: - ~.db_system.DbSystem: - Details of the DbSystem (BaseDB) - resource. - https://docs.oracle.com/en-us/iaas/api/#/en/database/20160918/DbSystem/ + Args: + request (~.oracledatabase.ListCloudExadataInfrastructuresRequest): + The request object. The request for ``CloudExadataInfrastructures.List``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.oracledatabase.ListCloudExadataInfrastructuresResponse: + The response for ``CloudExadataInfrastructures.list``. """ - http_options = ( - _BaseOracleDatabaseRestTransport._BaseGetDbSystem._get_http_options() - ) + http_options = _BaseOracleDatabaseRestTransport._BaseListCloudExadataInfrastructures._get_http_options() - request, metadata = self._interceptor.pre_get_db_system(request, metadata) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseGetDbSystem._get_transcoded_request( + request, metadata = ( + self._interceptor.pre_list_cloud_exadata_infrastructures( + request, metadata + ) + ) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseListCloudExadataInfrastructures._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseGetDbSystem._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseListCloudExadataInfrastructures._get_query_params_json( transcoded_request ) @@ -7146,17 +12033,17 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.GetDbSystem", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListCloudExadataInfrastructures", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "GetDbSystem", + "rpcName": "ListCloudExadataInfrastructures", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._GetDbSystem._get_response( + response = OracleDatabaseRestTransport._ListCloudExadataInfrastructures._get_response( self._host, metadata, query_params, @@ -7171,21 +12058,27 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = db_system.DbSystem() - pb_resp = db_system.DbSystem.pb(resp) + resp = oracledatabase.ListCloudExadataInfrastructuresResponse() + pb_resp = oracledatabase.ListCloudExadataInfrastructuresResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_get_db_system(resp) + resp = self._interceptor.post_list_cloud_exadata_infrastructures(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_get_db_system_with_metadata( - resp, response_metadata + resp, _ = ( + self._interceptor.post_list_cloud_exadata_infrastructures_with_metadata( + resp, response_metadata + ) ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = db_system.DbSystem.to_json(response) + response_payload = ( + oracledatabase.ListCloudExadataInfrastructuresResponse.to_json( + response + ) + ) except: response_payload = None http_response = { @@ -7194,21 +12087,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.get_db_system", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_cloud_exadata_infrastructures", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "GetDbSystem", + "rpcName": "ListCloudExadataInfrastructures", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _GetExadbVmCluster( - _BaseOracleDatabaseRestTransport._BaseGetExadbVmCluster, OracleDatabaseRestStub + class _ListCloudVmClusters( + _BaseOracleDatabaseRestTransport._BaseListCloudVmClusters, + OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.GetExadbVmCluster") + return hash("OracleDatabaseRestTransport.ListCloudVmClusters") @staticmethod def _get_response( @@ -7234,17 +12128,17 @@ def _get_response( def __call__( self, - request: oracledatabase.GetExadbVmClusterRequest, + request: oracledatabase.ListCloudVmClustersRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> exadb_vm_cluster.ExadbVmCluster: - r"""Call the get exadb vm cluster method over HTTP. + ) -> oracledatabase.ListCloudVmClustersResponse: + r"""Call the list cloud vm clusters method over HTTP. Args: - request (~.oracledatabase.GetExadbVmClusterRequest): - The request object. The request for ``ExadbVmCluster.Get``. + request (~.oracledatabase.ListCloudVmClustersRequest): + The request object. The request for ``CloudVmCluster.List``. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -7254,25 +12148,21 @@ def __call__( be of type `bytes`. Returns: - ~.exadb_vm_cluster.ExadbVmCluster: - ExadbVmCluster represents a cluster - of VMs that are used to run Exadata - workloads. - https://docs.oracle.com/en-us/iaas/api/#/en/database/20160918/ExadbVmCluster/ - + ~.oracledatabase.ListCloudVmClustersResponse: + The response for ``CloudVmCluster.List``. """ - http_options = _BaseOracleDatabaseRestTransport._BaseGetExadbVmCluster._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseListCloudVmClusters._get_http_options() - request, metadata = self._interceptor.pre_get_exadb_vm_cluster( + request, metadata = self._interceptor.pre_list_cloud_vm_clusters( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseGetExadbVmCluster._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseListCloudVmClusters._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseGetExadbVmCluster._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseListCloudVmClusters._get_query_params_json( transcoded_request ) @@ -7294,17 +12184,17 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.GetExadbVmCluster", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListCloudVmClusters", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "GetExadbVmCluster", + "rpcName": "ListCloudVmClusters", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._GetExadbVmCluster._get_response( + response = OracleDatabaseRestTransport._ListCloudVmClusters._get_response( self._host, metadata, query_params, @@ -7319,21 +12209,23 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = exadb_vm_cluster.ExadbVmCluster() - pb_resp = exadb_vm_cluster.ExadbVmCluster.pb(resp) + resp = oracledatabase.ListCloudVmClustersResponse() + pb_resp = oracledatabase.ListCloudVmClustersResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_get_exadb_vm_cluster(resp) + resp = self._interceptor.post_list_cloud_vm_clusters(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_get_exadb_vm_cluster_with_metadata( + resp, _ = self._interceptor.post_list_cloud_vm_clusters_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = exadb_vm_cluster.ExadbVmCluster.to_json(response) + response_payload = ( + oracledatabase.ListCloudVmClustersResponse.to_json(response) + ) except: response_payload = None http_response = { @@ -7342,22 +12234,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.get_exadb_vm_cluster", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_cloud_vm_clusters", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "GetExadbVmCluster", + "rpcName": "ListCloudVmClusters", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _GetExascaleDbStorageVault( - _BaseOracleDatabaseRestTransport._BaseGetExascaleDbStorageVault, + class _ListDatabaseCharacterSets( + _BaseOracleDatabaseRestTransport._BaseListDatabaseCharacterSets, OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.GetExascaleDbStorageVault") + return hash("OracleDatabaseRestTransport.ListDatabaseCharacterSets") @staticmethod def _get_response( @@ -7383,18 +12275,18 @@ def _get_response( def __call__( self, - request: exascale_db_storage_vault.GetExascaleDbStorageVaultRequest, + request: database_character_set.ListDatabaseCharacterSetsRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> exascale_db_storage_vault.ExascaleDbStorageVault: - r"""Call the get exascale db storage - vault method over HTTP. + ) -> database_character_set.ListDatabaseCharacterSetsResponse: + r"""Call the list database character + sets method over HTTP. Args: - request (~.exascale_db_storage_vault.GetExascaleDbStorageVaultRequest): - The request object. The request for ``ExascaleDbStorageVault.Get``. + request (~.database_character_set.ListDatabaseCharacterSetsRequest): + The request object. The request for ``DatabaseCharacterSet.List``. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -7404,24 +12296,21 @@ def __call__( be of type `bytes`. Returns: - ~.exascale_db_storage_vault.ExascaleDbStorageVault: - ExascaleDbStorageVault represents a - storage vault exadb vm cluster resource. - https://docs.oracle.com/en-us/iaas/api/#/en/database/20160918/ExascaleDbStorageVault/ - + ~.database_character_set.ListDatabaseCharacterSetsResponse: + The response for ``DatabaseCharacterSet.List``. """ - http_options = _BaseOracleDatabaseRestTransport._BaseGetExascaleDbStorageVault._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseListDatabaseCharacterSets._get_http_options() - request, metadata = self._interceptor.pre_get_exascale_db_storage_vault( + request, metadata = self._interceptor.pre_list_database_character_sets( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseGetExascaleDbStorageVault._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseListDatabaseCharacterSets._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseGetExascaleDbStorageVault._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseListDatabaseCharacterSets._get_query_params_json( transcoded_request ) @@ -7443,10 +12332,10 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.GetExascaleDbStorageVault", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListDatabaseCharacterSets", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "GetExascaleDbStorageVault", + "rpcName": "ListDatabaseCharacterSets", "httpRequest": http_request, "metadata": http_request["headers"], }, @@ -7454,7 +12343,7 @@ def __call__( # Send the request response = ( - OracleDatabaseRestTransport._GetExascaleDbStorageVault._get_response( + OracleDatabaseRestTransport._ListDatabaseCharacterSets._get_response( self._host, metadata, query_params, @@ -7470,26 +12359,22 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = exascale_db_storage_vault.ExascaleDbStorageVault() - pb_resp = exascale_db_storage_vault.ExascaleDbStorageVault.pb(resp) + resp = database_character_set.ListDatabaseCharacterSetsResponse() + pb_resp = database_character_set.ListDatabaseCharacterSetsResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_get_exascale_db_storage_vault(resp) + resp = self._interceptor.post_list_database_character_sets(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = ( - self._interceptor.post_get_exascale_db_storage_vault_with_metadata( - resp, response_metadata - ) + resp, _ = self._interceptor.post_list_database_character_sets_with_metadata( + resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = ( - exascale_db_storage_vault.ExascaleDbStorageVault.to_json( - response - ) + response_payload = database_character_set.ListDatabaseCharacterSetsResponse.to_json( + response ) except: response_payload = None @@ -7499,21 +12384,21 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.get_exascale_db_storage_vault", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_database_character_sets", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "GetExascaleDbStorageVault", + "rpcName": "ListDatabaseCharacterSets", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _GetOdbNetwork( - _BaseOracleDatabaseRestTransport._BaseGetOdbNetwork, OracleDatabaseRestStub + class _ListDatabases( + _BaseOracleDatabaseRestTransport._BaseListDatabases, OracleDatabaseRestStub ): def __hash__(self): - return hash("OracleDatabaseRestTransport.GetOdbNetwork") + return hash("OracleDatabaseRestTransport.ListDatabases") @staticmethod def _get_response( @@ -7539,17 +12424,17 @@ def _get_response( def __call__( self, - request: odb_network.GetOdbNetworkRequest, + request: database.ListDatabasesRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> odb_network.OdbNetwork: - r"""Call the get odb network method over HTTP. + ) -> database.ListDatabasesResponse: + r"""Call the list databases method over HTTP. Args: - request (~.odb_network.GetOdbNetworkRequest): - The request object. The request for ``OdbNetwork.Get``. + request (~.database.ListDatabasesRequest): + The request object. The request for ``Database.List``. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -7559,21 +12444,21 @@ def __call__( be of type `bytes`. Returns: - ~.odb_network.OdbNetwork: - Represents OdbNetwork resource. + ~.database.ListDatabasesResponse: + The response for ``Database.List``. """ http_options = ( - _BaseOracleDatabaseRestTransport._BaseGetOdbNetwork._get_http_options() + _BaseOracleDatabaseRestTransport._BaseListDatabases._get_http_options() ) - request, metadata = self._interceptor.pre_get_odb_network(request, metadata) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseGetOdbNetwork._get_transcoded_request( + request, metadata = self._interceptor.pre_list_databases(request, metadata) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseListDatabases._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseGetOdbNetwork._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseListDatabases._get_query_params_json( transcoded_request ) @@ -7595,17 +12480,17 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.GetOdbNetwork", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListDatabases", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "GetOdbNetwork", + "rpcName": "ListDatabases", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._GetOdbNetwork._get_response( + response = OracleDatabaseRestTransport._ListDatabases._get_response( self._host, metadata, query_params, @@ -7620,21 +12505,21 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = odb_network.OdbNetwork() - pb_resp = odb_network.OdbNetwork.pb(resp) + resp = database.ListDatabasesResponse() + pb_resp = database.ListDatabasesResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_get_odb_network(resp) + resp = self._interceptor.post_list_databases(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_get_odb_network_with_metadata( + resp, _ = self._interceptor.post_list_databases_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = odb_network.OdbNetwork.to_json(response) + response_payload = database.ListDatabasesResponse.to_json(response) except: response_payload = None http_response = { @@ -7643,21 +12528,21 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.get_odb_network", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_databases", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "GetOdbNetwork", + "rpcName": "ListDatabases", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _GetOdbSubnet( - _BaseOracleDatabaseRestTransport._BaseGetOdbSubnet, OracleDatabaseRestStub + class _ListDbNodes( + _BaseOracleDatabaseRestTransport._BaseListDbNodes, OracleDatabaseRestStub ): def __hash__(self): - return hash("OracleDatabaseRestTransport.GetOdbSubnet") + return hash("OracleDatabaseRestTransport.ListDbNodes") @staticmethod def _get_response( @@ -7683,17 +12568,17 @@ def _get_response( def __call__( self, - request: odb_subnet.GetOdbSubnetRequest, + request: oracledatabase.ListDbNodesRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> odb_subnet.OdbSubnet: - r"""Call the get odb subnet method over HTTP. + ) -> oracledatabase.ListDbNodesResponse: + r"""Call the list db nodes method over HTTP. Args: - request (~.odb_subnet.GetOdbSubnetRequest): - The request object. The request for ``OdbSubnet.Get``. + request (~.oracledatabase.ListDbNodesRequest): + The request object. The request for ``DbNode.List``. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -7703,21 +12588,21 @@ def __call__( be of type `bytes`. Returns: - ~.odb_subnet.OdbSubnet: - Represents OdbSubnet resource. + ~.oracledatabase.ListDbNodesResponse: + The response for ``DbNode.List``. """ http_options = ( - _BaseOracleDatabaseRestTransport._BaseGetOdbSubnet._get_http_options() + _BaseOracleDatabaseRestTransport._BaseListDbNodes._get_http_options() ) - request, metadata = self._interceptor.pre_get_odb_subnet(request, metadata) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseGetOdbSubnet._get_transcoded_request( + request, metadata = self._interceptor.pre_list_db_nodes(request, metadata) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseListDbNodes._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseGetOdbSubnet._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseListDbNodes._get_query_params_json( transcoded_request ) @@ -7739,17 +12624,17 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.GetOdbSubnet", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListDbNodes", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "GetOdbSubnet", + "rpcName": "ListDbNodes", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._GetOdbSubnet._get_response( + response = OracleDatabaseRestTransport._ListDbNodes._get_response( self._host, metadata, query_params, @@ -7764,21 +12649,23 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = odb_subnet.OdbSubnet() - pb_resp = odb_subnet.OdbSubnet.pb(resp) + resp = oracledatabase.ListDbNodesResponse() + pb_resp = oracledatabase.ListDbNodesResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_get_odb_subnet(resp) + resp = self._interceptor.post_list_db_nodes(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_get_odb_subnet_with_metadata( + resp, _ = self._interceptor.post_list_db_nodes_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = odb_subnet.OdbSubnet.to_json(response) + response_payload = oracledatabase.ListDbNodesResponse.to_json( + response + ) except: response_payload = None http_response = { @@ -7787,22 +12674,21 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.get_odb_subnet", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_db_nodes", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "GetOdbSubnet", + "rpcName": "ListDbNodes", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _GetPluggableDatabase( - _BaseOracleDatabaseRestTransport._BaseGetPluggableDatabase, - OracleDatabaseRestStub, + class _ListDbServers( + _BaseOracleDatabaseRestTransport._BaseListDbServers, OracleDatabaseRestStub ): def __hash__(self): - return hash("OracleDatabaseRestTransport.GetPluggableDatabase") + return hash("OracleDatabaseRestTransport.ListDbServers") @staticmethod def _get_response( @@ -7828,17 +12714,17 @@ def _get_response( def __call__( self, - request: pluggable_database.GetPluggableDatabaseRequest, + request: oracledatabase.ListDbServersRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> pluggable_database.PluggableDatabase: - r"""Call the get pluggable database method over HTTP. + ) -> oracledatabase.ListDbServersResponse: + r"""Call the list db servers method over HTTP. Args: - request (~.pluggable_database.GetPluggableDatabaseRequest): - The request object. The request for ``PluggableDatabase.Get``. + request (~.oracledatabase.ListDbServersRequest): + The request object. The request for ``DbServer.List``. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -7848,23 +12734,21 @@ def __call__( be of type `bytes`. Returns: - ~.pluggable_database.PluggableDatabase: - The PluggableDatabase resource. - https://docs.oracle.com/en-us/iaas/api/#/en/database/20160918/PluggableDatabase/ - + ~.oracledatabase.ListDbServersResponse: + The response for ``DbServer.List``. """ - http_options = _BaseOracleDatabaseRestTransport._BaseGetPluggableDatabase._get_http_options() - - request, metadata = self._interceptor.pre_get_pluggable_database( - request, metadata + http_options = ( + _BaseOracleDatabaseRestTransport._BaseListDbServers._get_http_options() ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseGetPluggableDatabase._get_transcoded_request( + + request, metadata = self._interceptor.pre_list_db_servers(request, metadata) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseListDbServers._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseGetPluggableDatabase._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseListDbServers._get_query_params_json( transcoded_request ) @@ -7886,17 +12770,17 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.GetPluggableDatabase", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListDbServers", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "GetPluggableDatabase", + "rpcName": "ListDbServers", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._GetPluggableDatabase._get_response( + response = OracleDatabaseRestTransport._ListDbServers._get_response( self._host, metadata, query_params, @@ -7911,21 +12795,21 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = pluggable_database.PluggableDatabase() - pb_resp = pluggable_database.PluggableDatabase.pb(resp) + resp = oracledatabase.ListDbServersResponse() + pb_resp = oracledatabase.ListDbServersResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_get_pluggable_database(resp) + resp = self._interceptor.post_list_db_servers(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_get_pluggable_database_with_metadata( + resp, _ = self._interceptor.post_list_db_servers_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = pluggable_database.PluggableDatabase.to_json( + response_payload = oracledatabase.ListDbServersResponse.to_json( response ) except: @@ -7936,22 +12820,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.get_pluggable_database", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_db_servers", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "GetPluggableDatabase", + "rpcName": "ListDbServers", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _ListAutonomousDatabaseBackups( - _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabaseBackups, + class _ListDbSystemInitialStorageSizes( + _BaseOracleDatabaseRestTransport._BaseListDbSystemInitialStorageSizes, OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.ListAutonomousDatabaseBackups") + return hash("OracleDatabaseRestTransport.ListDbSystemInitialStorageSizes") @staticmethod def _get_response( @@ -7977,18 +12861,18 @@ def _get_response( def __call__( self, - request: oracledatabase.ListAutonomousDatabaseBackupsRequest, + request: db_system_initial_storage_size.ListDbSystemInitialStorageSizesRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> oracledatabase.ListAutonomousDatabaseBackupsResponse: - r"""Call the list autonomous database - backups method over HTTP. + ) -> db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse: + r"""Call the list db system initial + storage sizes method over HTTP. Args: - request (~.oracledatabase.ListAutonomousDatabaseBackupsRequest): - The request object. The request for ``AutonomousDatabaseBackup.List``. + request (~.db_system_initial_storage_size.ListDbSystemInitialStorageSizesRequest): + The request object. The request for ``DbSystemInitialStorageSizes.List``. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -7998,21 +12882,23 @@ def __call__( be of type `bytes`. Returns: - ~.oracledatabase.ListAutonomousDatabaseBackupsResponse: - The response for ``AutonomousDatabaseBackup.List``. + ~.db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse: + The response for ``DbSystemInitialStorageSizes.List``. """ - http_options = _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabaseBackups._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseListDbSystemInitialStorageSizes._get_http_options() - request, metadata = self._interceptor.pre_list_autonomous_database_backups( - request, metadata + request, metadata = ( + self._interceptor.pre_list_db_system_initial_storage_sizes( + request, metadata + ) ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabaseBackups._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseListDbSystemInitialStorageSizes._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabaseBackups._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseListDbSystemInitialStorageSizes._get_query_params_json( transcoded_request ) @@ -8034,17 +12920,17 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListAutonomousDatabaseBackups", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListDbSystemInitialStorageSizes", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListAutonomousDatabaseBackups", + "rpcName": "ListDbSystemInitialStorageSizes", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._ListAutonomousDatabaseBackups._get_response( + response = OracleDatabaseRestTransport._ListDbSystemInitialStorageSizes._get_response( self._host, metadata, query_params, @@ -8059,15 +12945,19 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = oracledatabase.ListAutonomousDatabaseBackupsResponse() - pb_resp = oracledatabase.ListAutonomousDatabaseBackupsResponse.pb(resp) + resp = ( + db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse() + ) + pb_resp = db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse.pb( + resp + ) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_autonomous_database_backups(resp) + resp = self._interceptor.post_list_db_system_initial_storage_sizes(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] resp, _ = ( - self._interceptor.post_list_autonomous_database_backups_with_metadata( + self._interceptor.post_list_db_system_initial_storage_sizes_with_metadata( resp, response_metadata ) ) @@ -8075,10 +12965,8 @@ def __call__( logging.DEBUG ): # pragma: NO COVER try: - response_payload = ( - oracledatabase.ListAutonomousDatabaseBackupsResponse.to_json( - response - ) + response_payload = db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse.to_json( + response ) except: response_payload = None @@ -8088,24 +12976,21 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_autonomous_database_backups", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_db_system_initial_storage_sizes", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListAutonomousDatabaseBackups", + "rpcName": "ListDbSystemInitialStorageSizes", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _ListAutonomousDatabaseCharacterSets( - _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabaseCharacterSets, - OracleDatabaseRestStub, + class _ListDbSystems( + _BaseOracleDatabaseRestTransport._BaseListDbSystems, OracleDatabaseRestStub ): def __hash__(self): - return hash( - "OracleDatabaseRestTransport.ListAutonomousDatabaseCharacterSets" - ) + return hash("OracleDatabaseRestTransport.ListDbSystems") @staticmethod def _get_response( @@ -8131,46 +13016,41 @@ def _get_response( def __call__( self, - request: oracledatabase.ListAutonomousDatabaseCharacterSetsRequest, + request: db_system.ListDbSystemsRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> oracledatabase.ListAutonomousDatabaseCharacterSetsResponse: - r"""Call the list autonomous database - character sets method over HTTP. - - Args: - request (~.oracledatabase.ListAutonomousDatabaseCharacterSetsRequest): - The request object. The request for ``AutonomousDatabaseCharacterSet.List``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + ) -> db_system.ListDbSystemsResponse: + r"""Call the list db systems method over HTTP. - Returns: - ~.oracledatabase.ListAutonomousDatabaseCharacterSetsResponse: - The response for - ``AutonomousDatabaseCharacterSet.List``. + Args: + request (~.db_system.ListDbSystemsRequest): + The request object. The request for ``DbSystem.List``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.db_system.ListDbSystemsResponse: + The response for ``DbSystem.List``. """ - http_options = _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabaseCharacterSets._get_http_options() - - request, metadata = ( - self._interceptor.pre_list_autonomous_database_character_sets( - request, metadata - ) + http_options = ( + _BaseOracleDatabaseRestTransport._BaseListDbSystems._get_http_options() ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabaseCharacterSets._get_transcoded_request( + + request, metadata = self._interceptor.pre_list_db_systems(request, metadata) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseListDbSystems._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabaseCharacterSets._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseListDbSystems._get_query_params_json( transcoded_request ) @@ -8192,17 +13072,17 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListAutonomousDatabaseCharacterSets", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListDbSystems", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListAutonomousDatabaseCharacterSets", + "rpcName": "ListDbSystems", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._ListAutonomousDatabaseCharacterSets._get_response( + response = OracleDatabaseRestTransport._ListDbSystems._get_response( self._host, metadata, query_params, @@ -8217,27 +13097,21 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = oracledatabase.ListAutonomousDatabaseCharacterSetsResponse() - pb_resp = oracledatabase.ListAutonomousDatabaseCharacterSetsResponse.pb( - resp - ) + resp = db_system.ListDbSystemsResponse() + pb_resp = db_system.ListDbSystemsResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_autonomous_database_character_sets(resp) + resp = self._interceptor.post_list_db_systems(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = ( - self._interceptor.post_list_autonomous_database_character_sets_with_metadata( - resp, response_metadata - ) + resp, _ = self._interceptor.post_list_db_systems_with_metadata( + resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = oracledatabase.ListAutonomousDatabaseCharacterSetsResponse.to_json( - response - ) + response_payload = db_system.ListDbSystemsResponse.to_json(response) except: response_payload = None http_response = { @@ -8246,22 +13120,21 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_autonomous_database_character_sets", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_db_systems", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListAutonomousDatabaseCharacterSets", + "rpcName": "ListDbSystems", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _ListAutonomousDatabases( - _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabases, - OracleDatabaseRestStub, + class _ListDbSystemShapes( + _BaseOracleDatabaseRestTransport._BaseListDbSystemShapes, OracleDatabaseRestStub ): def __hash__(self): - return hash("OracleDatabaseRestTransport.ListAutonomousDatabases") + return hash("OracleDatabaseRestTransport.ListDbSystemShapes") @staticmethod def _get_response( @@ -8287,17 +13160,17 @@ def _get_response( def __call__( self, - request: oracledatabase.ListAutonomousDatabasesRequest, + request: oracledatabase.ListDbSystemShapesRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> oracledatabase.ListAutonomousDatabasesResponse: - r"""Call the list autonomous databases method over HTTP. + ) -> oracledatabase.ListDbSystemShapesResponse: + r"""Call the list db system shapes method over HTTP. Args: - request (~.oracledatabase.ListAutonomousDatabasesRequest): - The request object. The request for ``AutonomousDatabase.List``. + request (~.oracledatabase.ListDbSystemShapesRequest): + The request object. The request for ``DbSystemShape.List``. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -8307,21 +13180,21 @@ def __call__( be of type `bytes`. Returns: - ~.oracledatabase.ListAutonomousDatabasesResponse: - The response for ``AutonomousDatabase.List``. + ~.oracledatabase.ListDbSystemShapesResponse: + The response for ``DbSystemShape.List``. """ - http_options = _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabases._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseListDbSystemShapes._get_http_options() - request, metadata = self._interceptor.pre_list_autonomous_databases( + request, metadata = self._interceptor.pre_list_db_system_shapes( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabases._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseListDbSystemShapes._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabases._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseListDbSystemShapes._get_query_params_json( transcoded_request ) @@ -8343,25 +13216,23 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListAutonomousDatabases", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListDbSystemShapes", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListAutonomousDatabases", + "rpcName": "ListDbSystemShapes", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = ( - OracleDatabaseRestTransport._ListAutonomousDatabases._get_response( - self._host, - metadata, - query_params, - self._session, - timeout, - transcoded_request, - ) + response = OracleDatabaseRestTransport._ListDbSystemShapes._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -8370,14 +13241,14 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = oracledatabase.ListAutonomousDatabasesResponse() - pb_resp = oracledatabase.ListAutonomousDatabasesResponse.pb(resp) + resp = oracledatabase.ListDbSystemShapesResponse() + pb_resp = oracledatabase.ListDbSystemShapesResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_autonomous_databases(resp) + resp = self._interceptor.post_list_db_system_shapes(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_list_autonomous_databases_with_metadata( + resp, _ = self._interceptor.post_list_db_system_shapes_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( @@ -8385,7 +13256,7 @@ def __call__( ): # pragma: NO COVER try: response_payload = ( - oracledatabase.ListAutonomousDatabasesResponse.to_json(response) + oracledatabase.ListDbSystemShapesResponse.to_json(response) ) except: response_payload = None @@ -8395,22 +13266,21 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_autonomous_databases", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_db_system_shapes", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListAutonomousDatabases", + "rpcName": "ListDbSystemShapes", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _ListAutonomousDbVersions( - _BaseOracleDatabaseRestTransport._BaseListAutonomousDbVersions, - OracleDatabaseRestStub, + class _ListDbVersions( + _BaseOracleDatabaseRestTransport._BaseListDbVersions, OracleDatabaseRestStub ): def __hash__(self): - return hash("OracleDatabaseRestTransport.ListAutonomousDbVersions") + return hash("OracleDatabaseRestTransport.ListDbVersions") @staticmethod def _get_response( @@ -8436,42 +13306,43 @@ def _get_response( def __call__( self, - request: oracledatabase.ListAutonomousDbVersionsRequest, + request: db_version.ListDbVersionsRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> oracledatabase.ListAutonomousDbVersionsResponse: - r"""Call the list autonomous db - versions method over HTTP. + ) -> db_version.ListDbVersionsResponse: + r"""Call the list db versions method over HTTP. - Args: - request (~.oracledatabase.ListAutonomousDbVersionsRequest): - The request object. The request for ``AutonomousDbVersion.List``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + Args: + request (~.db_version.ListDbVersionsRequest): + The request object. The request for ``DbVersions.List``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. - Returns: - ~.oracledatabase.ListAutonomousDbVersionsResponse: - The response for ``AutonomousDbVersion.List``. + Returns: + ~.db_version.ListDbVersionsResponse: + The response for ``DbVersions.List``. """ - http_options = _BaseOracleDatabaseRestTransport._BaseListAutonomousDbVersions._get_http_options() + http_options = ( + _BaseOracleDatabaseRestTransport._BaseListDbVersions._get_http_options() + ) - request, metadata = self._interceptor.pre_list_autonomous_db_versions( + request, metadata = self._interceptor.pre_list_db_versions( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseListAutonomousDbVersions._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseListDbVersions._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseListAutonomousDbVersions._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseListDbVersions._get_query_params_json( transcoded_request ) @@ -8493,25 +13364,23 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListAutonomousDbVersions", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListDbVersions", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListAutonomousDbVersions", + "rpcName": "ListDbVersions", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = ( - OracleDatabaseRestTransport._ListAutonomousDbVersions._get_response( - self._host, - metadata, - query_params, - self._session, - timeout, - transcoded_request, - ) + response = OracleDatabaseRestTransport._ListDbVersions._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -8520,24 +13389,22 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = oracledatabase.ListAutonomousDbVersionsResponse() - pb_resp = oracledatabase.ListAutonomousDbVersionsResponse.pb(resp) + resp = db_version.ListDbVersionsResponse() + pb_resp = db_version.ListDbVersionsResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_autonomous_db_versions(resp) + resp = self._interceptor.post_list_db_versions(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_list_autonomous_db_versions_with_metadata( + resp, _ = self._interceptor.post_list_db_versions_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = ( - oracledatabase.ListAutonomousDbVersionsResponse.to_json( - response - ) + response_payload = db_version.ListDbVersionsResponse.to_json( + response ) except: response_payload = None @@ -8547,22 +13414,21 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_autonomous_db_versions", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_db_versions", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListAutonomousDbVersions", + "rpcName": "ListDbVersions", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _ListCloudExadataInfrastructures( - _BaseOracleDatabaseRestTransport._BaseListCloudExadataInfrastructures, - OracleDatabaseRestStub, + class _ListEntitlements( + _BaseOracleDatabaseRestTransport._BaseListEntitlements, OracleDatabaseRestStub ): def __hash__(self): - return hash("OracleDatabaseRestTransport.ListCloudExadataInfrastructures") + return hash("OracleDatabaseRestTransport.ListEntitlements") @staticmethod def _get_response( @@ -8588,44 +13454,41 @@ def _get_response( def __call__( self, - request: oracledatabase.ListCloudExadataInfrastructuresRequest, + request: oracledatabase.ListEntitlementsRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> oracledatabase.ListCloudExadataInfrastructuresResponse: - r"""Call the list cloud exadata - infrastructures method over HTTP. + ) -> oracledatabase.ListEntitlementsResponse: + r"""Call the list entitlements method over HTTP. - Args: - request (~.oracledatabase.ListCloudExadataInfrastructuresRequest): - The request object. The request for ``CloudExadataInfrastructures.List``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + Args: + request (~.oracledatabase.ListEntitlementsRequest): + The request object. The request for ``Entitlement.List``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. - Returns: - ~.oracledatabase.ListCloudExadataInfrastructuresResponse: - The response for ``CloudExadataInfrastructures.list``. + Returns: + ~.oracledatabase.ListEntitlementsResponse: + The response for ``Entitlement.List``. """ - http_options = _BaseOracleDatabaseRestTransport._BaseListCloudExadataInfrastructures._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseListEntitlements._get_http_options() - request, metadata = ( - self._interceptor.pre_list_cloud_exadata_infrastructures( - request, metadata - ) + request, metadata = self._interceptor.pre_list_entitlements( + request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseListCloudExadataInfrastructures._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseListEntitlements._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseListCloudExadataInfrastructures._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseListEntitlements._get_query_params_json( transcoded_request ) @@ -8647,17 +13510,17 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListCloudExadataInfrastructures", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListEntitlements", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListCloudExadataInfrastructures", + "rpcName": "ListEntitlements", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._ListCloudExadataInfrastructures._get_response( + response = OracleDatabaseRestTransport._ListEntitlements._get_response( self._host, metadata, query_params, @@ -8672,26 +13535,22 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = oracledatabase.ListCloudExadataInfrastructuresResponse() - pb_resp = oracledatabase.ListCloudExadataInfrastructuresResponse.pb(resp) + resp = oracledatabase.ListEntitlementsResponse() + pb_resp = oracledatabase.ListEntitlementsResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_cloud_exadata_infrastructures(resp) + resp = self._interceptor.post_list_entitlements(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = ( - self._interceptor.post_list_cloud_exadata_infrastructures_with_metadata( - resp, response_metadata - ) + resp, _ = self._interceptor.post_list_entitlements_with_metadata( + resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = ( - oracledatabase.ListCloudExadataInfrastructuresResponse.to_json( - response - ) + response_payload = oracledatabase.ListEntitlementsResponse.to_json( + response ) except: response_payload = None @@ -8701,22 +13560,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_cloud_exadata_infrastructures", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_entitlements", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListCloudExadataInfrastructures", + "rpcName": "ListEntitlements", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _ListCloudVmClusters( - _BaseOracleDatabaseRestTransport._BaseListCloudVmClusters, + class _ListExadbVmClusters( + _BaseOracleDatabaseRestTransport._BaseListExadbVmClusters, OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.ListCloudVmClusters") + return hash("OracleDatabaseRestTransport.ListExadbVmClusters") @staticmethod def _get_response( @@ -8742,17 +13601,17 @@ def _get_response( def __call__( self, - request: oracledatabase.ListCloudVmClustersRequest, + request: oracledatabase.ListExadbVmClustersRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> oracledatabase.ListCloudVmClustersResponse: - r"""Call the list cloud vm clusters method over HTTP. + ) -> oracledatabase.ListExadbVmClustersResponse: + r"""Call the list exadb vm clusters method over HTTP. Args: - request (~.oracledatabase.ListCloudVmClustersRequest): - The request object. The request for ``CloudVmCluster.List``. + request (~.oracledatabase.ListExadbVmClustersRequest): + The request object. The request for ``ExadbVmCluster.List``. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -8762,21 +13621,21 @@ def __call__( be of type `bytes`. Returns: - ~.oracledatabase.ListCloudVmClustersResponse: - The response for ``CloudVmCluster.List``. + ~.oracledatabase.ListExadbVmClustersResponse: + The response for ``ExadbVmCluster.List``. """ - http_options = _BaseOracleDatabaseRestTransport._BaseListCloudVmClusters._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseListExadbVmClusters._get_http_options() - request, metadata = self._interceptor.pre_list_cloud_vm_clusters( + request, metadata = self._interceptor.pre_list_exadb_vm_clusters( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseListCloudVmClusters._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseListExadbVmClusters._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseListCloudVmClusters._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseListExadbVmClusters._get_query_params_json( transcoded_request ) @@ -8798,17 +13657,17 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListCloudVmClusters", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListExadbVmClusters", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListCloudVmClusters", + "rpcName": "ListExadbVmClusters", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._ListCloudVmClusters._get_response( + response = OracleDatabaseRestTransport._ListExadbVmClusters._get_response( self._host, metadata, query_params, @@ -8823,14 +13682,14 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = oracledatabase.ListCloudVmClustersResponse() - pb_resp = oracledatabase.ListCloudVmClustersResponse.pb(resp) + resp = oracledatabase.ListExadbVmClustersResponse() + pb_resp = oracledatabase.ListExadbVmClustersResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_cloud_vm_clusters(resp) + resp = self._interceptor.post_list_exadb_vm_clusters(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_list_cloud_vm_clusters_with_metadata( + resp, _ = self._interceptor.post_list_exadb_vm_clusters_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( @@ -8838,7 +13697,7 @@ def __call__( ): # pragma: NO COVER try: response_payload = ( - oracledatabase.ListCloudVmClustersResponse.to_json(response) + oracledatabase.ListExadbVmClustersResponse.to_json(response) ) except: response_payload = None @@ -8848,22 +13707,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_cloud_vm_clusters", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_exadb_vm_clusters", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListCloudVmClusters", + "rpcName": "ListExadbVmClusters", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _ListDatabaseCharacterSets( - _BaseOracleDatabaseRestTransport._BaseListDatabaseCharacterSets, + class _ListExascaleDbStorageVaults( + _BaseOracleDatabaseRestTransport._BaseListExascaleDbStorageVaults, OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.ListDatabaseCharacterSets") + return hash("OracleDatabaseRestTransport.ListExascaleDbStorageVaults") @staticmethod def _get_response( @@ -8889,18 +13748,18 @@ def _get_response( def __call__( self, - request: database_character_set.ListDatabaseCharacterSetsRequest, + request: exascale_db_storage_vault.ListExascaleDbStorageVaultsRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> database_character_set.ListDatabaseCharacterSetsResponse: - r"""Call the list database character - sets method over HTTP. + ) -> exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse: + r"""Call the list exascale db storage + vaults method over HTTP. Args: - request (~.database_character_set.ListDatabaseCharacterSetsRequest): - The request object. The request for ``DatabaseCharacterSet.List``. + request (~.exascale_db_storage_vault.ListExascaleDbStorageVaultsRequest): + The request object. The request for ``ExascaleDbStorageVault.List``. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -8910,21 +13769,21 @@ def __call__( be of type `bytes`. Returns: - ~.database_character_set.ListDatabaseCharacterSetsResponse: - The response for ``DatabaseCharacterSet.List``. + ~.exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse: + The response for ``ExascaleDbStorageVault.List``. """ - http_options = _BaseOracleDatabaseRestTransport._BaseListDatabaseCharacterSets._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseListExascaleDbStorageVaults._get_http_options() - request, metadata = self._interceptor.pre_list_database_character_sets( + request, metadata = self._interceptor.pre_list_exascale_db_storage_vaults( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseListDatabaseCharacterSets._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseListExascaleDbStorageVaults._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseListDatabaseCharacterSets._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseListExascaleDbStorageVaults._get_query_params_json( transcoded_request ) @@ -8946,10 +13805,10 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListDatabaseCharacterSets", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListExascaleDbStorageVaults", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListDatabaseCharacterSets", + "rpcName": "ListExascaleDbStorageVaults", "httpRequest": http_request, "metadata": http_request["headers"], }, @@ -8957,7 +13816,7 @@ def __call__( # Send the request response = ( - OracleDatabaseRestTransport._ListDatabaseCharacterSets._get_response( + OracleDatabaseRestTransport._ListExascaleDbStorageVaults._get_response( self._host, metadata, query_params, @@ -8973,21 +13832,25 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = database_character_set.ListDatabaseCharacterSetsResponse() - pb_resp = database_character_set.ListDatabaseCharacterSetsResponse.pb(resp) + resp = exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse() + pb_resp = exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse.pb( + resp + ) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_database_character_sets(resp) - response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_list_database_character_sets_with_metadata( - resp, response_metadata + resp = self._interceptor.post_list_exascale_db_storage_vaults(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = ( + self._interceptor.post_list_exascale_db_storage_vaults_with_metadata( + resp, response_metadata + ) ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = database_character_set.ListDatabaseCharacterSetsResponse.to_json( + response_payload = exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse.to_json( response ) except: @@ -8998,21 +13861,21 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_database_character_sets", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_exascale_db_storage_vaults", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListDatabaseCharacterSets", + "rpcName": "ListExascaleDbStorageVaults", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _ListDatabases( - _BaseOracleDatabaseRestTransport._BaseListDatabases, OracleDatabaseRestStub + class _ListGiVersions( + _BaseOracleDatabaseRestTransport._BaseListGiVersions, OracleDatabaseRestStub ): def __hash__(self): - return hash("OracleDatabaseRestTransport.ListDatabases") + return hash("OracleDatabaseRestTransport.ListGiVersions") @staticmethod def _get_response( @@ -9038,17 +13901,17 @@ def _get_response( def __call__( self, - request: database.ListDatabasesRequest, + request: oracledatabase.ListGiVersionsRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> database.ListDatabasesResponse: - r"""Call the list databases method over HTTP. + ) -> oracledatabase.ListGiVersionsResponse: + r"""Call the list gi versions method over HTTP. Args: - request (~.database.ListDatabasesRequest): - The request object. The request for ``Database.List``. + request (~.oracledatabase.ListGiVersionsRequest): + The request object. The request for ``GiVersion.List``. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -9058,21 +13921,23 @@ def __call__( be of type `bytes`. Returns: - ~.database.ListDatabasesResponse: - The response for ``Database.List``. + ~.oracledatabase.ListGiVersionsResponse: + The response for ``GiVersion.List``. """ http_options = ( - _BaseOracleDatabaseRestTransport._BaseListDatabases._get_http_options() + _BaseOracleDatabaseRestTransport._BaseListGiVersions._get_http_options() ) - request, metadata = self._interceptor.pre_list_databases(request, metadata) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseListDatabases._get_transcoded_request( + request, metadata = self._interceptor.pre_list_gi_versions( + request, metadata + ) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseListGiVersions._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseListDatabases._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseListGiVersions._get_query_params_json( transcoded_request ) @@ -9094,17 +13959,17 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListDatabases", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListGiVersions", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListDatabases", + "rpcName": "ListGiVersions", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._ListDatabases._get_response( + response = OracleDatabaseRestTransport._ListGiVersions._get_response( self._host, metadata, query_params, @@ -9119,21 +13984,23 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = database.ListDatabasesResponse() - pb_resp = database.ListDatabasesResponse.pb(resp) + resp = oracledatabase.ListGiVersionsResponse() + pb_resp = oracledatabase.ListGiVersionsResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_databases(resp) + resp = self._interceptor.post_list_gi_versions(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_list_databases_with_metadata( + resp, _ = self._interceptor.post_list_gi_versions_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = database.ListDatabasesResponse.to_json(response) + response_payload = oracledatabase.ListGiVersionsResponse.to_json( + response + ) except: response_payload = None http_response = { @@ -9142,21 +14009,24 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_databases", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_gi_versions", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListDatabases", + "rpcName": "ListGiVersions", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _ListDbNodes( - _BaseOracleDatabaseRestTransport._BaseListDbNodes, OracleDatabaseRestStub + class _ListGoldengateConnectionAssignments( + _BaseOracleDatabaseRestTransport._BaseListGoldengateConnectionAssignments, + OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.ListDbNodes") + return hash( + "OracleDatabaseRestTransport.ListGoldengateConnectionAssignments" + ) @staticmethod def _get_response( @@ -9182,41 +14052,49 @@ def _get_response( def __call__( self, - request: oracledatabase.ListDbNodesRequest, + request: goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> oracledatabase.ListDbNodesResponse: - r"""Call the list db nodes method over HTTP. + ) -> ( + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse + ): + r"""Call the list goldengate + connection assignments method over HTTP. - Args: - request (~.oracledatabase.ListDbNodesRequest): - The request object. The request for ``DbNode.List``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + Args: + request (~.goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest): + The request object. Request message for listing + GoldengateConnectionAssignments. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse: + Response message for listing + GoldengateConnectionAssignments. - Returns: - ~.oracledatabase.ListDbNodesResponse: - The response for ``DbNode.List``. """ - http_options = ( - _BaseOracleDatabaseRestTransport._BaseListDbNodes._get_http_options() - ) + http_options = _BaseOracleDatabaseRestTransport._BaseListGoldengateConnectionAssignments._get_http_options() - request, metadata = self._interceptor.pre_list_db_nodes(request, metadata) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseListDbNodes._get_transcoded_request( + request, metadata = ( + self._interceptor.pre_list_goldengate_connection_assignments( + request, metadata + ) + ) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseListGoldengateConnectionAssignments._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseListDbNodes._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseListGoldengateConnectionAssignments._get_query_params_json( transcoded_request ) @@ -9238,17 +14116,17 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListDbNodes", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListGoldengateConnectionAssignments", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListDbNodes", + "rpcName": "ListGoldengateConnectionAssignments", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._ListDbNodes._get_response( + response = OracleDatabaseRestTransport._ListGoldengateConnectionAssignments._get_response( self._host, metadata, query_params, @@ -9263,21 +14141,25 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = oracledatabase.ListDbNodesResponse() - pb_resp = oracledatabase.ListDbNodesResponse.pb(resp) + resp = goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse() + pb_resp = goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse.pb( + resp + ) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_db_nodes(resp) + resp = self._interceptor.post_list_goldengate_connection_assignments(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_list_db_nodes_with_metadata( - resp, response_metadata + resp, _ = ( + self._interceptor.post_list_goldengate_connection_assignments_with_metadata( + resp, response_metadata + ) ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = oracledatabase.ListDbNodesResponse.to_json( + response_payload = goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse.to_json( response ) except: @@ -9288,21 +14170,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_db_nodes", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_goldengate_connection_assignments", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListDbNodes", + "rpcName": "ListGoldengateConnectionAssignments", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _ListDbServers( - _BaseOracleDatabaseRestTransport._BaseListDbServers, OracleDatabaseRestStub + class _ListGoldengateConnections( + _BaseOracleDatabaseRestTransport._BaseListGoldengateConnections, + OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.ListDbServers") + return hash("OracleDatabaseRestTransport.ListGoldengateConnections") @staticmethod def _get_response( @@ -9328,41 +14211,42 @@ def _get_response( def __call__( self, - request: oracledatabase.ListDbServersRequest, + request: goldengate_connection.ListGoldengateConnectionsRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> oracledatabase.ListDbServersResponse: - r"""Call the list db servers method over HTTP. + ) -> goldengate_connection.ListGoldengateConnectionsResponse: + r"""Call the list goldengate + connections method over HTTP. - Args: - request (~.oracledatabase.ListDbServersRequest): - The request object. The request for ``DbServer.List``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + Args: + request (~.goldengate_connection.ListGoldengateConnectionsRequest): + The request object. The request for ``GoldengateConnection.List``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. - Returns: - ~.oracledatabase.ListDbServersResponse: - The response for ``DbServer.List``. + Returns: + ~.goldengate_connection.ListGoldengateConnectionsResponse: + The response for ``GoldengateConnection.List``. """ - http_options = ( - _BaseOracleDatabaseRestTransport._BaseListDbServers._get_http_options() - ) + http_options = _BaseOracleDatabaseRestTransport._BaseListGoldengateConnections._get_http_options() - request, metadata = self._interceptor.pre_list_db_servers(request, metadata) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseListDbServers._get_transcoded_request( + request, metadata = self._interceptor.pre_list_goldengate_connections( + request, metadata + ) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseListGoldengateConnections._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseListDbServers._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseListGoldengateConnections._get_query_params_json( transcoded_request ) @@ -9384,23 +14268,25 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListDbServers", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListGoldengateConnections", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListDbServers", + "rpcName": "ListGoldengateConnections", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._ListDbServers._get_response( - self._host, - metadata, - query_params, - self._session, - timeout, - transcoded_request, + response = ( + OracleDatabaseRestTransport._ListGoldengateConnections._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -9409,22 +14295,24 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = oracledatabase.ListDbServersResponse() - pb_resp = oracledatabase.ListDbServersResponse.pb(resp) + resp = goldengate_connection.ListGoldengateConnectionsResponse() + pb_resp = goldengate_connection.ListGoldengateConnectionsResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_db_servers(resp) + resp = self._interceptor.post_list_goldengate_connections(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_list_db_servers_with_metadata( + resp, _ = self._interceptor.post_list_goldengate_connections_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = oracledatabase.ListDbServersResponse.to_json( - response + response_payload = ( + goldengate_connection.ListGoldengateConnectionsResponse.to_json( + response + ) ) except: response_payload = None @@ -9434,22 +14322,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_db_servers", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_goldengate_connections", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListDbServers", + "rpcName": "ListGoldengateConnections", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _ListDbSystemInitialStorageSizes( - _BaseOracleDatabaseRestTransport._BaseListDbSystemInitialStorageSizes, + class _ListGoldengateConnectionTypes( + _BaseOracleDatabaseRestTransport._BaseListGoldengateConnectionTypes, OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.ListDbSystemInitialStorageSizes") + return hash("OracleDatabaseRestTransport.ListGoldengateConnectionTypes") @staticmethod def _get_response( @@ -9475,18 +14363,19 @@ def _get_response( def __call__( self, - request: db_system_initial_storage_size.ListDbSystemInitialStorageSizesRequest, + request: goldengate_connection_type.ListGoldengateConnectionTypesRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse: - r"""Call the list db system initial - storage sizes method over HTTP. + ) -> goldengate_connection_type.ListGoldengateConnectionTypesResponse: + r"""Call the list goldengate + connection types method over HTTP. Args: - request (~.db_system_initial_storage_size.ListDbSystemInitialStorageSizesRequest): - The request object. The request for ``DbSystemInitialStorageSizes.List``. + request (~.goldengate_connection_type.ListGoldengateConnectionTypesRequest): + The request object. Message for listing + GoldengateConnectionTypes. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -9496,23 +14385,23 @@ def __call__( be of type `bytes`. Returns: - ~.db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse: - The response for ``DbSystemInitialStorageSizes.List``. + ~.goldengate_connection_type.ListGoldengateConnectionTypesResponse: + Message for response to listing + GoldengateConnectionTypes + """ - http_options = _BaseOracleDatabaseRestTransport._BaseListDbSystemInitialStorageSizes._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseListGoldengateConnectionTypes._get_http_options() - request, metadata = ( - self._interceptor.pre_list_db_system_initial_storage_sizes( - request, metadata - ) + request, metadata = self._interceptor.pre_list_goldengate_connection_types( + request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseListDbSystemInitialStorageSizes._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseListGoldengateConnectionTypes._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseListDbSystemInitialStorageSizes._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseListGoldengateConnectionTypes._get_query_params_json( transcoded_request ) @@ -9534,17 +14423,17 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListDbSystemInitialStorageSizes", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListGoldengateConnectionTypes", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListDbSystemInitialStorageSizes", + "rpcName": "ListGoldengateConnectionTypes", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._ListDbSystemInitialStorageSizes._get_response( + response = OracleDatabaseRestTransport._ListGoldengateConnectionTypes._get_response( self._host, metadata, query_params, @@ -9559,19 +14448,19 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = ( - db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse() - ) - pb_resp = db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse.pb( - resp + resp = goldengate_connection_type.ListGoldengateConnectionTypesResponse() + pb_resp = ( + goldengate_connection_type.ListGoldengateConnectionTypesResponse.pb( + resp + ) ) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_db_system_initial_storage_sizes(resp) + resp = self._interceptor.post_list_goldengate_connection_types(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] resp, _ = ( - self._interceptor.post_list_db_system_initial_storage_sizes_with_metadata( + self._interceptor.post_list_goldengate_connection_types_with_metadata( resp, response_metadata ) ) @@ -9579,7 +14468,7 @@ def __call__( logging.DEBUG ): # pragma: NO COVER try: - response_payload = db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse.to_json( + response_payload = goldengate_connection_type.ListGoldengateConnectionTypesResponse.to_json( response ) except: @@ -9590,21 +14479,24 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_db_system_initial_storage_sizes", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_goldengate_connection_types", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListDbSystemInitialStorageSizes", + "rpcName": "ListGoldengateConnectionTypes", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _ListDbSystems( - _BaseOracleDatabaseRestTransport._BaseListDbSystems, OracleDatabaseRestStub + class _ListGoldengateDeploymentEnvironments( + _BaseOracleDatabaseRestTransport._BaseListGoldengateDeploymentEnvironments, + OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.ListDbSystems") + return hash( + "OracleDatabaseRestTransport.ListGoldengateDeploymentEnvironments" + ) @staticmethod def _get_response( @@ -9630,41 +14522,47 @@ def _get_response( def __call__( self, - request: db_system.ListDbSystemsRequest, + request: goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> db_system.ListDbSystemsResponse: - r"""Call the list db systems method over HTTP. + ) -> goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse: + r"""Call the list goldengate + deployment environments method over HTTP. - Args: - request (~.db_system.ListDbSystemsRequest): - The request object. The request for ``DbSystem.List``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + Args: + request (~.goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest): + The request object. Message for listing + GoldengateDeploymentEnvironments. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse: + Message for response to listing + GoldengateDeploymentEnvironments - Returns: - ~.db_system.ListDbSystemsResponse: - The response for ``DbSystem.List``. """ - http_options = ( - _BaseOracleDatabaseRestTransport._BaseListDbSystems._get_http_options() - ) + http_options = _BaseOracleDatabaseRestTransport._BaseListGoldengateDeploymentEnvironments._get_http_options() - request, metadata = self._interceptor.pre_list_db_systems(request, metadata) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseListDbSystems._get_transcoded_request( + request, metadata = ( + self._interceptor.pre_list_goldengate_deployment_environments( + request, metadata + ) + ) + transcoded_request = _BaseOracleDatabaseRestTransport._BaseListGoldengateDeploymentEnvironments._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseListDbSystems._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseListGoldengateDeploymentEnvironments._get_query_params_json( transcoded_request ) @@ -9686,17 +14584,17 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListDbSystems", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListGoldengateDeploymentEnvironments", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListDbSystems", + "rpcName": "ListGoldengateDeploymentEnvironments", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._ListDbSystems._get_response( + response = OracleDatabaseRestTransport._ListGoldengateDeploymentEnvironments._get_response( self._host, metadata, query_params, @@ -9711,21 +14609,27 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = db_system.ListDbSystemsResponse() - pb_resp = db_system.ListDbSystemsResponse.pb(resp) + resp = goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse() + pb_resp = goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse.pb( + resp + ) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_db_systems(resp) + resp = self._interceptor.post_list_goldengate_deployment_environments(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_list_db_systems_with_metadata( - resp, response_metadata + resp, _ = ( + self._interceptor.post_list_goldengate_deployment_environments_with_metadata( + resp, response_metadata + ) ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = db_system.ListDbSystemsResponse.to_json(response) + response_payload = goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse.to_json( + response + ) except: response_payload = None http_response = { @@ -9734,21 +14638,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_db_systems", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_goldengate_deployment_environments", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListDbSystems", + "rpcName": "ListGoldengateDeploymentEnvironments", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _ListDbSystemShapes( - _BaseOracleDatabaseRestTransport._BaseListDbSystemShapes, OracleDatabaseRestStub + class _ListGoldengateDeployments( + _BaseOracleDatabaseRestTransport._BaseListGoldengateDeployments, + OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.ListDbSystemShapes") + return hash("OracleDatabaseRestTransport.ListGoldengateDeployments") @staticmethod def _get_response( @@ -9774,41 +14679,42 @@ def _get_response( def __call__( self, - request: oracledatabase.ListDbSystemShapesRequest, + request: goldengate_deployment.ListGoldengateDeploymentsRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> oracledatabase.ListDbSystemShapesResponse: - r"""Call the list db system shapes method over HTTP. + ) -> goldengate_deployment.ListGoldengateDeploymentsResponse: + r"""Call the list goldengate + deployments method over HTTP. - Args: - request (~.oracledatabase.ListDbSystemShapesRequest): - The request object. The request for ``DbSystemShape.List``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + Args: + request (~.goldengate_deployment.ListGoldengateDeploymentsRequest): + The request object. The request for ``GoldengateDeployment.List``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. - Returns: - ~.oracledatabase.ListDbSystemShapesResponse: - The response for ``DbSystemShape.List``. + Returns: + ~.goldengate_deployment.ListGoldengateDeploymentsResponse: + The response for ``GoldengateDeployment.List``. """ - http_options = _BaseOracleDatabaseRestTransport._BaseListDbSystemShapes._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseListGoldengateDeployments._get_http_options() - request, metadata = self._interceptor.pre_list_db_system_shapes( + request, metadata = self._interceptor.pre_list_goldengate_deployments( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseListDbSystemShapes._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseListGoldengateDeployments._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseListDbSystemShapes._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseListGoldengateDeployments._get_query_params_json( transcoded_request ) @@ -9830,23 +14736,25 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListDbSystemShapes", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListGoldengateDeployments", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListDbSystemShapes", + "rpcName": "ListGoldengateDeployments", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._ListDbSystemShapes._get_response( - self._host, - metadata, - query_params, - self._session, - timeout, - transcoded_request, + response = ( + OracleDatabaseRestTransport._ListGoldengateDeployments._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -9855,14 +14763,14 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = oracledatabase.ListDbSystemShapesResponse() - pb_resp = oracledatabase.ListDbSystemShapesResponse.pb(resp) + resp = goldengate_deployment.ListGoldengateDeploymentsResponse() + pb_resp = goldengate_deployment.ListGoldengateDeploymentsResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_db_system_shapes(resp) + resp = self._interceptor.post_list_goldengate_deployments(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_list_db_system_shapes_with_metadata( + resp, _ = self._interceptor.post_list_goldengate_deployments_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( @@ -9870,7 +14778,9 @@ def __call__( ): # pragma: NO COVER try: response_payload = ( - oracledatabase.ListDbSystemShapesResponse.to_json(response) + goldengate_deployment.ListGoldengateDeploymentsResponse.to_json( + response + ) ) except: response_payload = None @@ -9880,21 +14790,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_db_system_shapes", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_goldengate_deployments", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListDbSystemShapes", + "rpcName": "ListGoldengateDeployments", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _ListDbVersions( - _BaseOracleDatabaseRestTransport._BaseListDbVersions, OracleDatabaseRestStub + class _ListGoldengateDeploymentTypes( + _BaseOracleDatabaseRestTransport._BaseListGoldengateDeploymentTypes, + OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.ListDbVersions") + return hash("OracleDatabaseRestTransport.ListGoldengateDeploymentTypes") @staticmethod def _get_response( @@ -9920,43 +14831,45 @@ def _get_response( def __call__( self, - request: db_version.ListDbVersionsRequest, + request: goldengate_deployment_type.ListGoldengateDeploymentTypesRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> db_version.ListDbVersionsResponse: - r"""Call the list db versions method over HTTP. + ) -> goldengate_deployment_type.ListGoldengateDeploymentTypesResponse: + r"""Call the list goldengate + deployment types method over HTTP. - Args: - request (~.db_version.ListDbVersionsRequest): - The request object. The request for ``DbVersions.List``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + Args: + request (~.goldengate_deployment_type.ListGoldengateDeploymentTypesRequest): + The request object. Message for listing + GoldengateDeploymentTypes. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.goldengate_deployment_type.ListGoldengateDeploymentTypesResponse: + Message for response to listing + GoldengateDeploymentTypes - Returns: - ~.db_version.ListDbVersionsResponse: - The response for ``DbVersions.List``. """ - http_options = ( - _BaseOracleDatabaseRestTransport._BaseListDbVersions._get_http_options() - ) + http_options = _BaseOracleDatabaseRestTransport._BaseListGoldengateDeploymentTypes._get_http_options() - request, metadata = self._interceptor.pre_list_db_versions( + request, metadata = self._interceptor.pre_list_goldengate_deployment_types( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseListDbVersions._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseListGoldengateDeploymentTypes._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseListDbVersions._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseListGoldengateDeploymentTypes._get_query_params_json( transcoded_request ) @@ -9978,17 +14891,17 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListDbVersions", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListGoldengateDeploymentTypes", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListDbVersions", + "rpcName": "ListGoldengateDeploymentTypes", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._ListDbVersions._get_response( + response = OracleDatabaseRestTransport._ListGoldengateDeploymentTypes._get_response( self._host, metadata, query_params, @@ -10003,21 +14916,27 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = db_version.ListDbVersionsResponse() - pb_resp = db_version.ListDbVersionsResponse.pb(resp) + resp = goldengate_deployment_type.ListGoldengateDeploymentTypesResponse() + pb_resp = ( + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse.pb( + resp + ) + ) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_db_versions(resp) + resp = self._interceptor.post_list_goldengate_deployment_types(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_list_db_versions_with_metadata( - resp, response_metadata + resp, _ = ( + self._interceptor.post_list_goldengate_deployment_types_with_metadata( + resp, response_metadata + ) ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = db_version.ListDbVersionsResponse.to_json( + response_payload = goldengate_deployment_type.ListGoldengateDeploymentTypesResponse.to_json( response ) except: @@ -10028,21 +14947,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_db_versions", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_goldengate_deployment_types", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListDbVersions", + "rpcName": "ListGoldengateDeploymentTypes", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _ListEntitlements( - _BaseOracleDatabaseRestTransport._BaseListEntitlements, OracleDatabaseRestStub + class _ListGoldengateDeploymentVersions( + _BaseOracleDatabaseRestTransport._BaseListGoldengateDeploymentVersions, + OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.ListEntitlements") + return hash("OracleDatabaseRestTransport.ListGoldengateDeploymentVersions") @staticmethod def _get_response( @@ -10068,41 +14988,47 @@ def _get_response( def __call__( self, - request: oracledatabase.ListEntitlementsRequest, + request: goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> oracledatabase.ListEntitlementsResponse: - r"""Call the list entitlements method over HTTP. + ) -> goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse: + r"""Call the list goldengate + deployment versions method over HTTP. - Args: - request (~.oracledatabase.ListEntitlementsRequest): - The request object. The request for ``Entitlement.List``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + Args: + request (~.goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest): + The request object. Message for listing + GoldengateDeploymentVersions. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse: + Message for response to listing + GoldengateDeploymentVersions - Returns: - ~.oracledatabase.ListEntitlementsResponse: - The response for ``Entitlement.List``. """ - http_options = _BaseOracleDatabaseRestTransport._BaseListEntitlements._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseListGoldengateDeploymentVersions._get_http_options() - request, metadata = self._interceptor.pre_list_entitlements( - request, metadata + request, metadata = ( + self._interceptor.pre_list_goldengate_deployment_versions( + request, metadata + ) ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseListEntitlements._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseListGoldengateDeploymentVersions._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseListEntitlements._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseListGoldengateDeploymentVersions._get_query_params_json( transcoded_request ) @@ -10124,17 +15050,17 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListEntitlements", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListGoldengateDeploymentVersions", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListEntitlements", + "rpcName": "ListGoldengateDeploymentVersions", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._ListEntitlements._get_response( + response = OracleDatabaseRestTransport._ListGoldengateDeploymentVersions._get_response( self._host, metadata, query_params, @@ -10149,21 +15075,27 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = oracledatabase.ListEntitlementsResponse() - pb_resp = oracledatabase.ListEntitlementsResponse.pb(resp) + resp = ( + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse() + ) + pb_resp = goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse.pb( + resp + ) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_entitlements(resp) + resp = self._interceptor.post_list_goldengate_deployment_versions(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_list_entitlements_with_metadata( - resp, response_metadata + resp, _ = ( + self._interceptor.post_list_goldengate_deployment_versions_with_metadata( + resp, response_metadata + ) ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = oracledatabase.ListEntitlementsResponse.to_json( + response_payload = goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse.to_json( response ) except: @@ -10174,22 +15106,21 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_entitlements", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_goldengate_deployment_versions", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListEntitlements", + "rpcName": "ListGoldengateDeploymentVersions", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _ListExadbVmClusters( - _BaseOracleDatabaseRestTransport._BaseListExadbVmClusters, - OracleDatabaseRestStub, + class _ListMinorVersions( + _BaseOracleDatabaseRestTransport._BaseListMinorVersions, OracleDatabaseRestStub ): def __hash__(self): - return hash("OracleDatabaseRestTransport.ListExadbVmClusters") + return hash("OracleDatabaseRestTransport.ListMinorVersions") @staticmethod def _get_response( @@ -10215,17 +15146,17 @@ def _get_response( def __call__( self, - request: oracledatabase.ListExadbVmClustersRequest, + request: minor_version.ListMinorVersionsRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> oracledatabase.ListExadbVmClustersResponse: - r"""Call the list exadb vm clusters method over HTTP. + ) -> minor_version.ListMinorVersionsResponse: + r"""Call the list minor versions method over HTTP. Args: - request (~.oracledatabase.ListExadbVmClustersRequest): - The request object. The request for ``ExadbVmCluster.List``. + request (~.minor_version.ListMinorVersionsRequest): + The request object. The request for ``MinorVersion.List``. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -10235,21 +15166,21 @@ def __call__( be of type `bytes`. Returns: - ~.oracledatabase.ListExadbVmClustersResponse: - The response for ``ExadbVmCluster.List``. + ~.minor_version.ListMinorVersionsResponse: + The response for ``MinorVersion.List``. """ - http_options = _BaseOracleDatabaseRestTransport._BaseListExadbVmClusters._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseListMinorVersions._get_http_options() - request, metadata = self._interceptor.pre_list_exadb_vm_clusters( + request, metadata = self._interceptor.pre_list_minor_versions( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseListExadbVmClusters._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseListMinorVersions._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseListExadbVmClusters._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseListMinorVersions._get_query_params_json( transcoded_request ) @@ -10271,17 +15202,17 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListExadbVmClusters", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListMinorVersions", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListExadbVmClusters", + "rpcName": "ListMinorVersions", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._ListExadbVmClusters._get_response( + response = OracleDatabaseRestTransport._ListMinorVersions._get_response( self._host, metadata, query_params, @@ -10296,22 +15227,22 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = oracledatabase.ListExadbVmClustersResponse() - pb_resp = oracledatabase.ListExadbVmClustersResponse.pb(resp) + resp = minor_version.ListMinorVersionsResponse() + pb_resp = minor_version.ListMinorVersionsResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_exadb_vm_clusters(resp) + resp = self._interceptor.post_list_minor_versions(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_list_exadb_vm_clusters_with_metadata( + resp, _ = self._interceptor.post_list_minor_versions_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = ( - oracledatabase.ListExadbVmClustersResponse.to_json(response) + response_payload = minor_version.ListMinorVersionsResponse.to_json( + response ) except: response_payload = None @@ -10321,22 +15252,21 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_exadb_vm_clusters", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_minor_versions", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListExadbVmClusters", + "rpcName": "ListMinorVersions", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _ListExascaleDbStorageVaults( - _BaseOracleDatabaseRestTransport._BaseListExascaleDbStorageVaults, - OracleDatabaseRestStub, + class _ListOdbNetworks( + _BaseOracleDatabaseRestTransport._BaseListOdbNetworks, OracleDatabaseRestStub ): def __hash__(self): - return hash("OracleDatabaseRestTransport.ListExascaleDbStorageVaults") + return hash("OracleDatabaseRestTransport.ListOdbNetworks") @staticmethod def _get_response( @@ -10362,42 +15292,41 @@ def _get_response( def __call__( self, - request: exascale_db_storage_vault.ListExascaleDbStorageVaultsRequest, + request: odb_network.ListOdbNetworksRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse: - r"""Call the list exascale db storage - vaults method over HTTP. + ) -> odb_network.ListOdbNetworksResponse: + r"""Call the list odb networks method over HTTP. - Args: - request (~.exascale_db_storage_vault.ListExascaleDbStorageVaultsRequest): - The request object. The request for ``ExascaleDbStorageVault.List``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + Args: + request (~.odb_network.ListOdbNetworksRequest): + The request object. The request for ``OdbNetwork.List``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. - Returns: - ~.exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse: - The response for ``ExascaleDbStorageVault.List``. + Returns: + ~.odb_network.ListOdbNetworksResponse: + The response for ``OdbNetwork.List``. """ - http_options = _BaseOracleDatabaseRestTransport._BaseListExascaleDbStorageVaults._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseListOdbNetworks._get_http_options() - request, metadata = self._interceptor.pre_list_exascale_db_storage_vaults( + request, metadata = self._interceptor.pre_list_odb_networks( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseListExascaleDbStorageVaults._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseListOdbNetworks._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseListExascaleDbStorageVaults._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseListOdbNetworks._get_query_params_json( transcoded_request ) @@ -10419,25 +15348,23 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListExascaleDbStorageVaults", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListOdbNetworks", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListExascaleDbStorageVaults", + "rpcName": "ListOdbNetworks", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = ( - OracleDatabaseRestTransport._ListExascaleDbStorageVaults._get_response( - self._host, - metadata, - query_params, - self._session, - timeout, - transcoded_request, - ) + response = OracleDatabaseRestTransport._ListOdbNetworks._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -10446,25 +15373,21 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse() - pb_resp = exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse.pb( - resp - ) + resp = odb_network.ListOdbNetworksResponse() + pb_resp = odb_network.ListOdbNetworksResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_exascale_db_storage_vaults(resp) + resp = self._interceptor.post_list_odb_networks(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = ( - self._interceptor.post_list_exascale_db_storage_vaults_with_metadata( - resp, response_metadata - ) + resp, _ = self._interceptor.post_list_odb_networks_with_metadata( + resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse.to_json( + response_payload = odb_network.ListOdbNetworksResponse.to_json( response ) except: @@ -10475,21 +15398,21 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_exascale_db_storage_vaults", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_odb_networks", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListExascaleDbStorageVaults", + "rpcName": "ListOdbNetworks", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _ListGiVersions( - _BaseOracleDatabaseRestTransport._BaseListGiVersions, OracleDatabaseRestStub + class _ListOdbSubnets( + _BaseOracleDatabaseRestTransport._BaseListOdbSubnets, OracleDatabaseRestStub ): def __hash__(self): - return hash("OracleDatabaseRestTransport.ListGiVersions") + return hash("OracleDatabaseRestTransport.ListOdbSubnets") @staticmethod def _get_response( @@ -10515,17 +15438,17 @@ def _get_response( def __call__( self, - request: oracledatabase.ListGiVersionsRequest, + request: odb_subnet.ListOdbSubnetsRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> oracledatabase.ListGiVersionsResponse: - r"""Call the list gi versions method over HTTP. + ) -> odb_subnet.ListOdbSubnetsResponse: + r"""Call the list odb subnets method over HTTP. Args: - request (~.oracledatabase.ListGiVersionsRequest): - The request object. The request for ``GiVersion.List``. + request (~.odb_subnet.ListOdbSubnetsRequest): + The request object. The request for ``OdbSubnet.List``. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -10535,23 +15458,23 @@ def __call__( be of type `bytes`. Returns: - ~.oracledatabase.ListGiVersionsResponse: - The response for ``GiVersion.List``. + ~.odb_subnet.ListOdbSubnetsResponse: + The response for ``OdbSubnet.List``. """ http_options = ( - _BaseOracleDatabaseRestTransport._BaseListGiVersions._get_http_options() + _BaseOracleDatabaseRestTransport._BaseListOdbSubnets._get_http_options() ) - request, metadata = self._interceptor.pre_list_gi_versions( + request, metadata = self._interceptor.pre_list_odb_subnets( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseListGiVersions._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseListOdbSubnets._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseListGiVersions._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseListOdbSubnets._get_query_params_json( transcoded_request ) @@ -10573,17 +15496,17 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListGiVersions", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListOdbSubnets", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListGiVersions", + "rpcName": "ListOdbSubnets", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._ListGiVersions._get_response( + response = OracleDatabaseRestTransport._ListOdbSubnets._get_response( self._host, metadata, query_params, @@ -10598,21 +15521,21 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = oracledatabase.ListGiVersionsResponse() - pb_resp = oracledatabase.ListGiVersionsResponse.pb(resp) + resp = odb_subnet.ListOdbSubnetsResponse() + pb_resp = odb_subnet.ListOdbSubnetsResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_gi_versions(resp) + resp = self._interceptor.post_list_odb_subnets(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_list_gi_versions_with_metadata( + resp, _ = self._interceptor.post_list_odb_subnets_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = oracledatabase.ListGiVersionsResponse.to_json( + response_payload = odb_subnet.ListOdbSubnetsResponse.to_json( response ) except: @@ -10623,21 +15546,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_gi_versions", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_odb_subnets", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListGiVersions", + "rpcName": "ListOdbSubnets", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _ListMinorVersions( - _BaseOracleDatabaseRestTransport._BaseListMinorVersions, OracleDatabaseRestStub + class _ListPluggableDatabases( + _BaseOracleDatabaseRestTransport._BaseListPluggableDatabases, + OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.ListMinorVersions") + return hash("OracleDatabaseRestTransport.ListPluggableDatabases") @staticmethod def _get_response( @@ -10663,17 +15587,17 @@ def _get_response( def __call__( self, - request: minor_version.ListMinorVersionsRequest, + request: pluggable_database.ListPluggableDatabasesRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> minor_version.ListMinorVersionsResponse: - r"""Call the list minor versions method over HTTP. + ) -> pluggable_database.ListPluggableDatabasesResponse: + r"""Call the list pluggable databases method over HTTP. Args: - request (~.minor_version.ListMinorVersionsRequest): - The request object. The request for ``MinorVersion.List``. + request (~.pluggable_database.ListPluggableDatabasesRequest): + The request object. The request for ``PluggableDatabase.List``. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -10683,21 +15607,21 @@ def __call__( be of type `bytes`. Returns: - ~.minor_version.ListMinorVersionsResponse: - The response for ``MinorVersion.List``. + ~.pluggable_database.ListPluggableDatabasesResponse: + The response for ``PluggableDatabase.List``. """ - http_options = _BaseOracleDatabaseRestTransport._BaseListMinorVersions._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseListPluggableDatabases._get_http_options() - request, metadata = self._interceptor.pre_list_minor_versions( + request, metadata = self._interceptor.pre_list_pluggable_databases( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseListMinorVersions._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseListPluggableDatabases._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseListMinorVersions._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseListPluggableDatabases._get_query_params_json( transcoded_request ) @@ -10719,23 +15643,25 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListMinorVersions", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListPluggableDatabases", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListMinorVersions", + "rpcName": "ListPluggableDatabases", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._ListMinorVersions._get_response( - self._host, - metadata, - query_params, - self._session, - timeout, - transcoded_request, + response = ( + OracleDatabaseRestTransport._ListPluggableDatabases._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -10744,22 +15670,24 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = minor_version.ListMinorVersionsResponse() - pb_resp = minor_version.ListMinorVersionsResponse.pb(resp) + resp = pluggable_database.ListPluggableDatabasesResponse() + pb_resp = pluggable_database.ListPluggableDatabasesResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_minor_versions(resp) + resp = self._interceptor.post_list_pluggable_databases(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_list_minor_versions_with_metadata( + resp, _ = self._interceptor.post_list_pluggable_databases_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = minor_version.ListMinorVersionsResponse.to_json( - response + response_payload = ( + pluggable_database.ListPluggableDatabasesResponse.to_json( + response + ) ) except: response_payload = None @@ -10769,21 +15697,24 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_minor_versions", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_pluggable_databases", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListMinorVersions", + "rpcName": "ListPluggableDatabases", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _ListOdbNetworks( - _BaseOracleDatabaseRestTransport._BaseListOdbNetworks, OracleDatabaseRestStub + class _RemoveVirtualMachineExadbVmCluster( + _BaseOracleDatabaseRestTransport._BaseRemoveVirtualMachineExadbVmCluster, + OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.ListOdbNetworks") + return hash( + "OracleDatabaseRestTransport.RemoveVirtualMachineExadbVmCluster" + ) @staticmethod def _get_response( @@ -10804,46 +15735,57 @@ def _get_response( timeout=timeout, headers=headers, params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, ) return response def __call__( self, - request: odb_network.ListOdbNetworksRequest, + request: oracledatabase.RemoveVirtualMachineExadbVmClusterRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> odb_network.ListOdbNetworksResponse: - r"""Call the list odb networks method over HTTP. + ) -> operations_pb2.Operation: + r"""Call the remove virtual machine + exadb vm cluster method over HTTP. - Args: - request (~.odb_network.ListOdbNetworksRequest): - The request object. The request for ``OdbNetwork.List``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + Args: + request (~.oracledatabase.RemoveVirtualMachineExadbVmClusterRequest): + The request object. The request for ``ExadbVmCluster.RemoveVirtualMachine``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. - Returns: - ~.odb_network.ListOdbNetworksResponse: - The response for ``OdbNetwork.List``. """ - http_options = _BaseOracleDatabaseRestTransport._BaseListOdbNetworks._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseRemoveVirtualMachineExadbVmCluster._get_http_options() - request, metadata = self._interceptor.pre_list_odb_networks( - request, metadata + request, metadata = ( + self._interceptor.pre_remove_virtual_machine_exadb_vm_cluster( + request, metadata + ) ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseListOdbNetworks._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseRemoveVirtualMachineExadbVmCluster._get_transcoded_request( http_options, request ) + body = _BaseOracleDatabaseRestTransport._BaseRemoveVirtualMachineExadbVmCluster._get_request_body_json( + transcoded_request + ) + # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseListOdbNetworks._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseRemoveVirtualMachineExadbVmCluster._get_query_params_json( transcoded_request ) @@ -10865,23 +15807,24 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListOdbNetworks", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.RemoveVirtualMachineExadbVmCluster", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListOdbNetworks", + "rpcName": "RemoveVirtualMachineExadbVmCluster", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._ListOdbNetworks._get_response( + response = OracleDatabaseRestTransport._RemoveVirtualMachineExadbVmCluster._get_response( self._host, metadata, query_params, self._session, timeout, transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -10890,23 +15833,21 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = odb_network.ListOdbNetworksResponse() - pb_resp = odb_network.ListOdbNetworksResponse.pb(resp) - - json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_odb_networks(resp) + resp = self._interceptor.post_remove_virtual_machine_exadb_vm_cluster(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_list_odb_networks_with_metadata( - resp, response_metadata + resp, _ = ( + self._interceptor.post_remove_virtual_machine_exadb_vm_cluster_with_metadata( + resp, response_metadata + ) ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = odb_network.ListOdbNetworksResponse.to_json( - response - ) + response_payload = json_format.MessageToJson(resp) except: response_payload = None http_response = { @@ -10915,21 +15856,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_odb_networks", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.remove_virtual_machine_exadb_vm_cluster", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListOdbNetworks", + "rpcName": "RemoveVirtualMachineExadbVmCluster", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _ListOdbSubnets( - _BaseOracleDatabaseRestTransport._BaseListOdbSubnets, OracleDatabaseRestStub + class _RestartAutonomousDatabase( + _BaseOracleDatabaseRestTransport._BaseRestartAutonomousDatabase, + OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.ListOdbSubnets") + return hash("OracleDatabaseRestTransport.RestartAutonomousDatabase") @staticmethod def _get_response( @@ -10950,48 +15892,55 @@ def _get_response( timeout=timeout, headers=headers, params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, ) return response def __call__( self, - request: odb_subnet.ListOdbSubnetsRequest, + request: oracledatabase.RestartAutonomousDatabaseRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> odb_subnet.ListOdbSubnetsResponse: - r"""Call the list odb subnets method over HTTP. + ) -> operations_pb2.Operation: + r"""Call the restart autonomous + database method over HTTP. - Args: - request (~.odb_subnet.ListOdbSubnetsRequest): - The request object. The request for ``OdbSubnet.List``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + Args: + request (~.oracledatabase.RestartAutonomousDatabaseRequest): + The request object. The request for ``AutonomousDatabase.Restart``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. - Returns: - ~.odb_subnet.ListOdbSubnetsResponse: - The response for ``OdbSubnet.List``. """ - http_options = ( - _BaseOracleDatabaseRestTransport._BaseListOdbSubnets._get_http_options() - ) + http_options = _BaseOracleDatabaseRestTransport._BaseRestartAutonomousDatabase._get_http_options() - request, metadata = self._interceptor.pre_list_odb_subnets( + request, metadata = self._interceptor.pre_restart_autonomous_database( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseListOdbSubnets._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseRestartAutonomousDatabase._get_transcoded_request( http_options, request ) + body = _BaseOracleDatabaseRestTransport._BaseRestartAutonomousDatabase._get_request_body_json( + transcoded_request + ) + # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseListOdbSubnets._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseRestartAutonomousDatabase._get_query_params_json( transcoded_request ) @@ -11013,23 +15962,26 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListOdbSubnets", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.RestartAutonomousDatabase", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListOdbSubnets", + "rpcName": "RestartAutonomousDatabase", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._ListOdbSubnets._get_response( - self._host, - metadata, - query_params, - self._session, - timeout, - transcoded_request, + response = ( + OracleDatabaseRestTransport._RestartAutonomousDatabase._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -11038,23 +15990,19 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = odb_subnet.ListOdbSubnetsResponse() - pb_resp = odb_subnet.ListOdbSubnetsResponse.pb(resp) - - json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_odb_subnets(resp) + resp = self._interceptor.post_restart_autonomous_database(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_list_odb_subnets_with_metadata( + resp, _ = self._interceptor.post_restart_autonomous_database_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = odb_subnet.ListOdbSubnetsResponse.to_json( - response - ) + response_payload = json_format.MessageToJson(resp) except: response_payload = None http_response = { @@ -11063,22 +16011,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_odb_subnets", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.restart_autonomous_database", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListOdbSubnets", + "rpcName": "RestartAutonomousDatabase", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _ListPluggableDatabases( - _BaseOracleDatabaseRestTransport._BaseListPluggableDatabases, + class _RestoreAutonomousDatabase( + _BaseOracleDatabaseRestTransport._BaseRestoreAutonomousDatabase, OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.ListPluggableDatabases") + return hash("OracleDatabaseRestTransport.RestoreAutonomousDatabase") @staticmethod def _get_response( @@ -11099,46 +16047,55 @@ def _get_response( timeout=timeout, headers=headers, params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, ) return response def __call__( self, - request: pluggable_database.ListPluggableDatabasesRequest, + request: oracledatabase.RestoreAutonomousDatabaseRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> pluggable_database.ListPluggableDatabasesResponse: - r"""Call the list pluggable databases method over HTTP. + ) -> operations_pb2.Operation: + r"""Call the restore autonomous + database method over HTTP. - Args: - request (~.pluggable_database.ListPluggableDatabasesRequest): - The request object. The request for ``PluggableDatabase.List``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + Args: + request (~.oracledatabase.RestoreAutonomousDatabaseRequest): + The request object. The request for ``AutonomousDatabase.Restore``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. - Returns: - ~.pluggable_database.ListPluggableDatabasesResponse: - The response for ``PluggableDatabase.List``. """ - http_options = _BaseOracleDatabaseRestTransport._BaseListPluggableDatabases._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseRestoreAutonomousDatabase._get_http_options() - request, metadata = self._interceptor.pre_list_pluggable_databases( + request, metadata = self._interceptor.pre_restore_autonomous_database( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseListPluggableDatabases._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseRestoreAutonomousDatabase._get_transcoded_request( http_options, request ) + body = _BaseOracleDatabaseRestTransport._BaseRestoreAutonomousDatabase._get_request_body_json( + transcoded_request + ) + # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseListPluggableDatabases._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseRestoreAutonomousDatabase._get_query_params_json( transcoded_request ) @@ -11160,10 +16117,10 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.ListPluggableDatabases", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.RestoreAutonomousDatabase", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListPluggableDatabases", + "rpcName": "RestoreAutonomousDatabase", "httpRequest": http_request, "metadata": http_request["headers"], }, @@ -11171,13 +16128,14 @@ def __call__( # Send the request response = ( - OracleDatabaseRestTransport._ListPluggableDatabases._get_response( + OracleDatabaseRestTransport._RestoreAutonomousDatabase._get_response( self._host, metadata, query_params, self._session, timeout, transcoded_request, + body, ) ) @@ -11187,25 +16145,19 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = pluggable_database.ListPluggableDatabasesResponse() - pb_resp = pluggable_database.ListPluggableDatabasesResponse.pb(resp) - - json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_pluggable_databases(resp) + resp = self._interceptor.post_restore_autonomous_database(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_list_pluggable_databases_with_metadata( + resp, _ = self._interceptor.post_restore_autonomous_database_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = ( - pluggable_database.ListPluggableDatabasesResponse.to_json( - response - ) - ) + response_payload = json_format.MessageToJson(resp) except: response_payload = None http_response = { @@ -11214,24 +16166,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.list_pluggable_databases", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.restore_autonomous_database", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "ListPluggableDatabases", + "rpcName": "RestoreAutonomousDatabase", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _RemoveVirtualMachineExadbVmCluster( - _BaseOracleDatabaseRestTransport._BaseRemoveVirtualMachineExadbVmCluster, + class _StartAutonomousDatabase( + _BaseOracleDatabaseRestTransport._BaseStartAutonomousDatabase, OracleDatabaseRestStub, ): def __hash__(self): - return hash( - "OracleDatabaseRestTransport.RemoveVirtualMachineExadbVmCluster" - ) + return hash("OracleDatabaseRestTransport.StartAutonomousDatabase") @staticmethod def _get_response( @@ -11258,51 +16208,48 @@ def _get_response( def __call__( self, - request: oracledatabase.RemoveVirtualMachineExadbVmClusterRequest, + request: oracledatabase.StartAutonomousDatabaseRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> operations_pb2.Operation: - r"""Call the remove virtual machine - exadb vm cluster method over HTTP. + r"""Call the start autonomous database method over HTTP. - Args: - request (~.oracledatabase.RemoveVirtualMachineExadbVmClusterRequest): - The request object. The request for ``ExadbVmCluster.RemoveVirtualMachine``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + Args: + request (~.oracledatabase.StartAutonomousDatabaseRequest): + The request object. The request for ``AutonomousDatabase.Start``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. - Returns: - ~.operations_pb2.Operation: - This resource represents a - long-running operation that is the - result of a network API call. + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. """ - http_options = _BaseOracleDatabaseRestTransport._BaseRemoveVirtualMachineExadbVmCluster._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseStartAutonomousDatabase._get_http_options() - request, metadata = ( - self._interceptor.pre_remove_virtual_machine_exadb_vm_cluster( - request, metadata - ) + request, metadata = self._interceptor.pre_start_autonomous_database( + request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseRemoveVirtualMachineExadbVmCluster._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseStartAutonomousDatabase._get_transcoded_request( http_options, request ) - body = _BaseOracleDatabaseRestTransport._BaseRemoveVirtualMachineExadbVmCluster._get_request_body_json( + body = _BaseOracleDatabaseRestTransport._BaseStartAutonomousDatabase._get_request_body_json( transcoded_request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseRemoveVirtualMachineExadbVmCluster._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseStartAutonomousDatabase._get_query_params_json( transcoded_request ) @@ -11324,24 +16271,26 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.RemoveVirtualMachineExadbVmCluster", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.StartAutonomousDatabase", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "RemoveVirtualMachineExadbVmCluster", + "rpcName": "StartAutonomousDatabase", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = OracleDatabaseRestTransport._RemoveVirtualMachineExadbVmCluster._get_response( - self._host, - metadata, - query_params, - self._session, - timeout, - transcoded_request, - body, + response = ( + OracleDatabaseRestTransport._StartAutonomousDatabase._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -11353,12 +16302,10 @@ def __call__( resp = operations_pb2.Operation() json_format.Parse(response.content, resp, ignore_unknown_fields=True) - resp = self._interceptor.post_remove_virtual_machine_exadb_vm_cluster(resp) + resp = self._interceptor.post_start_autonomous_database(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = ( - self._interceptor.post_remove_virtual_machine_exadb_vm_cluster_with_metadata( - resp, response_metadata - ) + resp, _ = self._interceptor.post_start_autonomous_database_with_metadata( + resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG @@ -11373,22 +16320,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.remove_virtual_machine_exadb_vm_cluster", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.start_autonomous_database", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "RemoveVirtualMachineExadbVmCluster", + "rpcName": "StartAutonomousDatabase", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _RestartAutonomousDatabase( - _BaseOracleDatabaseRestTransport._BaseRestartAutonomousDatabase, + class _StartGoldengateDeployment( + _BaseOracleDatabaseRestTransport._BaseStartGoldengateDeployment, OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.RestartAutonomousDatabase") + return hash("OracleDatabaseRestTransport.StartGoldengateDeployment") @staticmethod def _get_response( @@ -11415,18 +16362,18 @@ def _get_response( def __call__( self, - request: oracledatabase.RestartAutonomousDatabaseRequest, + request: goldengate_deployment.StartGoldengateDeploymentRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> operations_pb2.Operation: - r"""Call the restart autonomous - database method over HTTP. + r"""Call the start goldengate + deployment method over HTTP. Args: - request (~.oracledatabase.RestartAutonomousDatabaseRequest): - The request object. The request for ``AutonomousDatabase.Restart``. + request (~.goldengate_deployment.StartGoldengateDeploymentRequest): + The request object. The request for ``GoldengateDeployment.Start``. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -11443,21 +16390,21 @@ def __call__( """ - http_options = _BaseOracleDatabaseRestTransport._BaseRestartAutonomousDatabase._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseStartGoldengateDeployment._get_http_options() - request, metadata = self._interceptor.pre_restart_autonomous_database( + request, metadata = self._interceptor.pre_start_goldengate_deployment( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseRestartAutonomousDatabase._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseStartGoldengateDeployment._get_transcoded_request( http_options, request ) - body = _BaseOracleDatabaseRestTransport._BaseRestartAutonomousDatabase._get_request_body_json( + body = _BaseOracleDatabaseRestTransport._BaseStartGoldengateDeployment._get_request_body_json( transcoded_request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseRestartAutonomousDatabase._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseStartGoldengateDeployment._get_query_params_json( transcoded_request ) @@ -11479,10 +16426,10 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.RestartAutonomousDatabase", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.StartGoldengateDeployment", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "RestartAutonomousDatabase", + "rpcName": "StartGoldengateDeployment", "httpRequest": http_request, "metadata": http_request["headers"], }, @@ -11490,7 +16437,7 @@ def __call__( # Send the request response = ( - OracleDatabaseRestTransport._RestartAutonomousDatabase._get_response( + OracleDatabaseRestTransport._StartGoldengateDeployment._get_response( self._host, metadata, query_params, @@ -11510,9 +16457,9 @@ def __call__( resp = operations_pb2.Operation() json_format.Parse(response.content, resp, ignore_unknown_fields=True) - resp = self._interceptor.post_restart_autonomous_database(resp) + resp = self._interceptor.post_start_goldengate_deployment(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_restart_autonomous_database_with_metadata( + resp, _ = self._interceptor.post_start_goldengate_deployment_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( @@ -11528,22 +16475,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.restart_autonomous_database", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.start_goldengate_deployment", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "RestartAutonomousDatabase", + "rpcName": "StartGoldengateDeployment", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _RestoreAutonomousDatabase( - _BaseOracleDatabaseRestTransport._BaseRestoreAutonomousDatabase, + class _StopAutonomousDatabase( + _BaseOracleDatabaseRestTransport._BaseStopAutonomousDatabase, OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.RestoreAutonomousDatabase") + return hash("OracleDatabaseRestTransport.StopAutonomousDatabase") @staticmethod def _get_response( @@ -11570,49 +16517,48 @@ def _get_response( def __call__( self, - request: oracledatabase.RestoreAutonomousDatabaseRequest, + request: oracledatabase.StopAutonomousDatabaseRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> operations_pb2.Operation: - r"""Call the restore autonomous - database method over HTTP. + r"""Call the stop autonomous database method over HTTP. - Args: - request (~.oracledatabase.RestoreAutonomousDatabaseRequest): - The request object. The request for ``AutonomousDatabase.Restore``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + Args: + request (~.oracledatabase.StopAutonomousDatabaseRequest): + The request object. The request for ``AutonomousDatabase.Stop``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. - Returns: - ~.operations_pb2.Operation: - This resource represents a - long-running operation that is the - result of a network API call. + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. """ - http_options = _BaseOracleDatabaseRestTransport._BaseRestoreAutonomousDatabase._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseStopAutonomousDatabase._get_http_options() - request, metadata = self._interceptor.pre_restore_autonomous_database( + request, metadata = self._interceptor.pre_stop_autonomous_database( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseRestoreAutonomousDatabase._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseStopAutonomousDatabase._get_transcoded_request( http_options, request ) - body = _BaseOracleDatabaseRestTransport._BaseRestoreAutonomousDatabase._get_request_body_json( + body = _BaseOracleDatabaseRestTransport._BaseStopAutonomousDatabase._get_request_body_json( transcoded_request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseRestoreAutonomousDatabase._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseStopAutonomousDatabase._get_query_params_json( transcoded_request ) @@ -11634,10 +16580,10 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.RestoreAutonomousDatabase", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.StopAutonomousDatabase", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "RestoreAutonomousDatabase", + "rpcName": "StopAutonomousDatabase", "httpRequest": http_request, "metadata": http_request["headers"], }, @@ -11645,7 +16591,7 @@ def __call__( # Send the request response = ( - OracleDatabaseRestTransport._RestoreAutonomousDatabase._get_response( + OracleDatabaseRestTransport._StopAutonomousDatabase._get_response( self._host, metadata, query_params, @@ -11665,9 +16611,9 @@ def __call__( resp = operations_pb2.Operation() json_format.Parse(response.content, resp, ignore_unknown_fields=True) - resp = self._interceptor.post_restore_autonomous_database(resp) + resp = self._interceptor.post_stop_autonomous_database(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_restore_autonomous_database_with_metadata( + resp, _ = self._interceptor.post_stop_autonomous_database_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( @@ -11683,22 +16629,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.restore_autonomous_database", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.stop_autonomous_database", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "RestoreAutonomousDatabase", + "rpcName": "StopAutonomousDatabase", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _StartAutonomousDatabase( - _BaseOracleDatabaseRestTransport._BaseStartAutonomousDatabase, + class _StopGoldengateDeployment( + _BaseOracleDatabaseRestTransport._BaseStopGoldengateDeployment, OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.StartAutonomousDatabase") + return hash("OracleDatabaseRestTransport.StopGoldengateDeployment") @staticmethod def _get_response( @@ -11725,48 +16671,49 @@ def _get_response( def __call__( self, - request: oracledatabase.StartAutonomousDatabaseRequest, + request: goldengate_deployment.StopGoldengateDeploymentRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> operations_pb2.Operation: - r"""Call the start autonomous database method over HTTP. + r"""Call the stop goldengate + deployment method over HTTP. - Args: - request (~.oracledatabase.StartAutonomousDatabaseRequest): - The request object. The request for ``AutonomousDatabase.Start``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + Args: + request (~.goldengate_deployment.StopGoldengateDeploymentRequest): + The request object. The request for ``GoldengateDeployment.Stop``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. - Returns: - ~.operations_pb2.Operation: - This resource represents a - long-running operation that is the - result of a network API call. + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. """ - http_options = _BaseOracleDatabaseRestTransport._BaseStartAutonomousDatabase._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseStopGoldengateDeployment._get_http_options() - request, metadata = self._interceptor.pre_start_autonomous_database( + request, metadata = self._interceptor.pre_stop_goldengate_deployment( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseStartAutonomousDatabase._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseStopGoldengateDeployment._get_transcoded_request( http_options, request ) - body = _BaseOracleDatabaseRestTransport._BaseStartAutonomousDatabase._get_request_body_json( + body = _BaseOracleDatabaseRestTransport._BaseStopGoldengateDeployment._get_request_body_json( transcoded_request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseStartAutonomousDatabase._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseStopGoldengateDeployment._get_query_params_json( transcoded_request ) @@ -11788,10 +16735,10 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.StartAutonomousDatabase", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.StopGoldengateDeployment", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "StartAutonomousDatabase", + "rpcName": "StopGoldengateDeployment", "httpRequest": http_request, "metadata": http_request["headers"], }, @@ -11799,7 +16746,7 @@ def __call__( # Send the request response = ( - OracleDatabaseRestTransport._StartAutonomousDatabase._get_response( + OracleDatabaseRestTransport._StopGoldengateDeployment._get_response( self._host, metadata, query_params, @@ -11819,9 +16766,9 @@ def __call__( resp = operations_pb2.Operation() json_format.Parse(response.content, resp, ignore_unknown_fields=True) - resp = self._interceptor.post_start_autonomous_database(resp) + resp = self._interceptor.post_stop_goldengate_deployment(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_start_autonomous_database_with_metadata( + resp, _ = self._interceptor.post_stop_goldengate_deployment_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( @@ -11837,22 +16784,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.start_autonomous_database", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.stop_goldengate_deployment", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "StartAutonomousDatabase", + "rpcName": "StopGoldengateDeployment", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _StopAutonomousDatabase( - _BaseOracleDatabaseRestTransport._BaseStopAutonomousDatabase, + class _SwitchoverAutonomousDatabase( + _BaseOracleDatabaseRestTransport._BaseSwitchoverAutonomousDatabase, OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.StopAutonomousDatabase") + return hash("OracleDatabaseRestTransport.SwitchoverAutonomousDatabase") @staticmethod def _get_response( @@ -11879,48 +16826,50 @@ def _get_response( def __call__( self, - request: oracledatabase.StopAutonomousDatabaseRequest, + request: oracledatabase.SwitchoverAutonomousDatabaseRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> operations_pb2.Operation: - r"""Call the stop autonomous database method over HTTP. + r"""Call the switchover autonomous + database method over HTTP. - Args: - request (~.oracledatabase.StopAutonomousDatabaseRequest): - The request object. The request for ``AutonomousDatabase.Stop``. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + Args: + request (~.oracledatabase.SwitchoverAutonomousDatabaseRequest): + The request object. The request for + ``OracleDatabase.SwitchoverAutonomousDatabase``. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. - Returns: - ~.operations_pb2.Operation: - This resource represents a - long-running operation that is the - result of a network API call. + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. """ - http_options = _BaseOracleDatabaseRestTransport._BaseStopAutonomousDatabase._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseSwitchoverAutonomousDatabase._get_http_options() - request, metadata = self._interceptor.pre_stop_autonomous_database( + request, metadata = self._interceptor.pre_switchover_autonomous_database( request, metadata ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseStopAutonomousDatabase._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseSwitchoverAutonomousDatabase._get_transcoded_request( http_options, request ) - body = _BaseOracleDatabaseRestTransport._BaseStopAutonomousDatabase._get_request_body_json( + body = _BaseOracleDatabaseRestTransport._BaseSwitchoverAutonomousDatabase._get_request_body_json( transcoded_request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseStopAutonomousDatabase._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseSwitchoverAutonomousDatabase._get_query_params_json( transcoded_request ) @@ -11942,10 +16891,10 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.StopAutonomousDatabase", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.SwitchoverAutonomousDatabase", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "StopAutonomousDatabase", + "rpcName": "SwitchoverAutonomousDatabase", "httpRequest": http_request, "metadata": http_request["headers"], }, @@ -11953,7 +16902,7 @@ def __call__( # Send the request response = ( - OracleDatabaseRestTransport._StopAutonomousDatabase._get_response( + OracleDatabaseRestTransport._SwitchoverAutonomousDatabase._get_response( self._host, metadata, query_params, @@ -11973,10 +16922,12 @@ def __call__( resp = operations_pb2.Operation() json_format.Parse(response.content, resp, ignore_unknown_fields=True) - resp = self._interceptor.post_stop_autonomous_database(resp) + resp = self._interceptor.post_switchover_autonomous_database(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_stop_autonomous_database_with_metadata( - resp, response_metadata + resp, _ = ( + self._interceptor.post_switchover_autonomous_database_with_metadata( + resp, response_metadata + ) ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG @@ -11991,22 +16942,24 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.stop_autonomous_database", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.switchover_autonomous_database", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "StopAutonomousDatabase", + "rpcName": "SwitchoverAutonomousDatabase", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _SwitchoverAutonomousDatabase( - _BaseOracleDatabaseRestTransport._BaseSwitchoverAutonomousDatabase, + class _TestGoldengateConnectionAssignment( + _BaseOracleDatabaseRestTransport._BaseTestGoldengateConnectionAssignment, OracleDatabaseRestStub, ): def __hash__(self): - return hash("OracleDatabaseRestTransport.SwitchoverAutonomousDatabase") + return hash( + "OracleDatabaseRestTransport.TestGoldengateConnectionAssignment" + ) @staticmethod def _get_response( @@ -12033,19 +16986,21 @@ def _get_response( def __call__( self, - request: oracledatabase.SwitchoverAutonomousDatabaseRequest, + request: goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> operations_pb2.Operation: - r"""Call the switchover autonomous - database method over HTTP. + ) -> ( + goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse + ): + r"""Call the test goldengate + connection assignment method over HTTP. Args: - request (~.oracledatabase.SwitchoverAutonomousDatabaseRequest): - The request object. The request for - ``OracleDatabase.SwitchoverAutonomousDatabase``. + request (~.goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest): + The request object. Request message for + TestGoldengateConnectionAssignment. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -12055,28 +17010,31 @@ def __call__( be of type `bytes`. Returns: - ~.operations_pb2.Operation: - This resource represents a - long-running operation that is the - result of a network API call. + ~.goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse: + The result of the connectivity test + performed between the Goldengate + deployment and the associated database / + service. """ - http_options = _BaseOracleDatabaseRestTransport._BaseSwitchoverAutonomousDatabase._get_http_options() + http_options = _BaseOracleDatabaseRestTransport._BaseTestGoldengateConnectionAssignment._get_http_options() - request, metadata = self._interceptor.pre_switchover_autonomous_database( - request, metadata + request, metadata = ( + self._interceptor.pre_test_goldengate_connection_assignment( + request, metadata + ) ) - transcoded_request = _BaseOracleDatabaseRestTransport._BaseSwitchoverAutonomousDatabase._get_transcoded_request( + transcoded_request = _BaseOracleDatabaseRestTransport._BaseTestGoldengateConnectionAssignment._get_transcoded_request( http_options, request ) - body = _BaseOracleDatabaseRestTransport._BaseSwitchoverAutonomousDatabase._get_request_body_json( + body = _BaseOracleDatabaseRestTransport._BaseTestGoldengateConnectionAssignment._get_request_body_json( transcoded_request ) # Jsonify the query params - query_params = _BaseOracleDatabaseRestTransport._BaseSwitchoverAutonomousDatabase._get_query_params_json( + query_params = _BaseOracleDatabaseRestTransport._BaseTestGoldengateConnectionAssignment._get_query_params_json( transcoded_request ) @@ -12098,26 +17056,24 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.SwitchoverAutonomousDatabase", + f"Sending request for google.cloud.oracledatabase_v1.OracleDatabaseClient.TestGoldengateConnectionAssignment", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "SwitchoverAutonomousDatabase", + "rpcName": "TestGoldengateConnectionAssignment", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = ( - OracleDatabaseRestTransport._SwitchoverAutonomousDatabase._get_response( - self._host, - metadata, - query_params, - self._session, - timeout, - transcoded_request, - body, - ) + response = OracleDatabaseRestTransport._TestGoldengateConnectionAssignment._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -12126,13 +17082,17 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = operations_pb2.Operation() - json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse() + pb_resp = goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse.pb( + resp + ) - resp = self._interceptor.post_switchover_autonomous_database(resp) + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_test_goldengate_connection_assignment(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] resp, _ = ( - self._interceptor.post_switchover_autonomous_database_with_metadata( + self._interceptor.post_test_goldengate_connection_assignment_with_metadata( resp, response_metadata ) ) @@ -12140,7 +17100,9 @@ def __call__( logging.DEBUG ): # pragma: NO COVER try: - response_payload = json_format.MessageToJson(resp) + response_payload = goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse.to_json( + response + ) except: response_payload = None http_response = { @@ -12149,10 +17111,10 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.switchover_autonomous_database", + "Received response for google.cloud.oracledatabase_v1.OracleDatabaseClient.test_goldengate_connection_assignment", extra={ "serviceName": "google.cloud.oracledatabase.v1.OracleDatabase", - "rpcName": "SwitchoverAutonomousDatabase", + "rpcName": "TestGoldengateConnectionAssignment", "metadata": http_response["headers"], "httpResponse": http_response, }, @@ -12535,6 +17497,47 @@ def create_exascale_db_storage_vault( self._session, self._host, self._interceptor ) # type: ignore + @property + def create_goldengate_connection( + self, + ) -> Callable[ + [gco_goldengate_connection.CreateGoldengateConnectionRequest], + operations_pb2.Operation, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateGoldengateConnection( + self._session, self._host, self._interceptor + ) # type: ignore + + @property + def create_goldengate_connection_assignment( + self, + ) -> Callable[ + [ + gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest + ], + operations_pb2.Operation, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateGoldengateConnectionAssignment( + self._session, self._host, self._interceptor + ) # type: ignore + + @property + def create_goldengate_deployment( + self, + ) -> Callable[ + [gco_goldengate_deployment.CreateGoldengateDeploymentRequest], + operations_pb2.Operation, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateGoldengateDeployment( + self._session, self._host, self._interceptor + ) # type: ignore + @property def create_odb_network( self, @@ -12617,6 +17620,45 @@ def delete_exascale_db_storage_vault( self._session, self._host, self._interceptor ) # type: ignore + @property + def delete_goldengate_connection( + self, + ) -> Callable[ + [goldengate_connection.DeleteGoldengateConnectionRequest], + operations_pb2.Operation, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteGoldengateConnection( + self._session, self._host, self._interceptor + ) # type: ignore + + @property + def delete_goldengate_connection_assignment( + self, + ) -> Callable[ + [goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest], + operations_pb2.Operation, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteGoldengateConnectionAssignment( + self._session, self._host, self._interceptor + ) # type: ignore + + @property + def delete_goldengate_deployment( + self, + ) -> Callable[ + [goldengate_deployment.DeleteGoldengateDeploymentRequest], + operations_pb2.Operation, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteGoldengateDeployment( + self._session, self._host, self._interceptor + ) # type: ignore + @property def delete_odb_network( self, @@ -12729,6 +17771,97 @@ def get_exascale_db_storage_vault( self._session, self._host, self._interceptor ) # type: ignore + @property + def get_goldengate_connection( + self, + ) -> Callable[ + [goldengate_connection.GetGoldengateConnectionRequest], + goldengate_connection.GoldengateConnection, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetGoldengateConnection( + self._session, self._host, self._interceptor + ) # type: ignore + + @property + def get_goldengate_connection_assignment( + self, + ) -> Callable[ + [goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest], + goldengate_connection_assignment.GoldengateConnectionAssignment, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetGoldengateConnectionAssignment( + self._session, self._host, self._interceptor + ) # type: ignore + + @property + def get_goldengate_connection_type( + self, + ) -> Callable[ + [goldengate_connection_type.GetGoldengateConnectionTypeRequest], + goldengate_connection_type.GoldengateConnectionType, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetGoldengateConnectionType( + self._session, self._host, self._interceptor + ) # type: ignore + + @property + def get_goldengate_deployment( + self, + ) -> Callable[ + [goldengate_deployment.GetGoldengateDeploymentRequest], + goldengate_deployment.GoldengateDeployment, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetGoldengateDeployment( + self._session, self._host, self._interceptor + ) # type: ignore + + @property + def get_goldengate_deployment_environment( + self, + ) -> Callable[ + [goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest], + goldengate_deployment_environment.GoldengateDeploymentEnvironment, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetGoldengateDeploymentEnvironment( + self._session, self._host, self._interceptor + ) # type: ignore + + @property + def get_goldengate_deployment_type( + self, + ) -> Callable[ + [goldengate_deployment_type.GetGoldengateDeploymentTypeRequest], + goldengate_deployment_type.GoldengateDeploymentType, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetGoldengateDeploymentType( + self._session, self._host, self._interceptor + ) # type: ignore + + @property + def get_goldengate_deployment_version( + self, + ) -> Callable[ + [goldengate_deployment_version.GetGoldengateDeploymentVersionRequest], + goldengate_deployment_version.GoldengateDeploymentVersion, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetGoldengateDeploymentVersion( + self._session, self._host, self._interceptor + ) # type: ignore + @property def get_odb_network( self, @@ -12960,6 +18093,97 @@ def list_gi_versions( # In C++ this would require a dynamic_cast return self._ListGiVersions(self._session, self._host, self._interceptor) # type: ignore + @property + def list_goldengate_connection_assignments( + self, + ) -> Callable[ + [goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest], + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListGoldengateConnectionAssignments( + self._session, self._host, self._interceptor + ) # type: ignore + + @property + def list_goldengate_connections( + self, + ) -> Callable[ + [goldengate_connection.ListGoldengateConnectionsRequest], + goldengate_connection.ListGoldengateConnectionsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListGoldengateConnections( + self._session, self._host, self._interceptor + ) # type: ignore + + @property + def list_goldengate_connection_types( + self, + ) -> Callable[ + [goldengate_connection_type.ListGoldengateConnectionTypesRequest], + goldengate_connection_type.ListGoldengateConnectionTypesResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListGoldengateConnectionTypes( + self._session, self._host, self._interceptor + ) # type: ignore + + @property + def list_goldengate_deployment_environments( + self, + ) -> Callable[ + [goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest], + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListGoldengateDeploymentEnvironments( + self._session, self._host, self._interceptor + ) # type: ignore + + @property + def list_goldengate_deployments( + self, + ) -> Callable[ + [goldengate_deployment.ListGoldengateDeploymentsRequest], + goldengate_deployment.ListGoldengateDeploymentsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListGoldengateDeployments( + self._session, self._host, self._interceptor + ) # type: ignore + + @property + def list_goldengate_deployment_types( + self, + ) -> Callable[ + [goldengate_deployment_type.ListGoldengateDeploymentTypesRequest], + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListGoldengateDeploymentTypes( + self._session, self._host, self._interceptor + ) # type: ignore + + @property + def list_goldengate_deployment_versions( + self, + ) -> Callable[ + [goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest], + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListGoldengateDeploymentVersions( + self._session, self._host, self._interceptor + ) # type: ignore + @property def list_minor_versions( self, @@ -13053,6 +18277,19 @@ def start_autonomous_database( self._session, self._host, self._interceptor ) # type: ignore + @property + def start_goldengate_deployment( + self, + ) -> Callable[ + [goldengate_deployment.StartGoldengateDeploymentRequest], + operations_pb2.Operation, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._StartGoldengateDeployment( + self._session, self._host, self._interceptor + ) # type: ignore + @property def stop_autonomous_database( self, @@ -13065,6 +18302,19 @@ def stop_autonomous_database( self._session, self._host, self._interceptor ) # type: ignore + @property + def stop_goldengate_deployment( + self, + ) -> Callable[ + [goldengate_deployment.StopGoldengateDeploymentRequest], + operations_pb2.Operation, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._StopGoldengateDeployment( + self._session, self._host, self._interceptor + ) # type: ignore + @property def switchover_autonomous_database( self, @@ -13077,6 +18327,19 @@ def switchover_autonomous_database( self._session, self._host, self._interceptor ) # type: ignore + @property + def test_goldengate_connection_assignment( + self, + ) -> Callable[ + [goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest], + goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._TestGoldengateConnectionAssignment( + self._session, self._host, self._interceptor + ) # type: ignore + @property def update_autonomous_database( self, diff --git a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/transports/rest_base.py b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/transports/rest_base.py index 8d7cc5100ca7..d7418c921f71 100644 --- a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/transports/rest_base.py +++ b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/services/oracle_database/transports/rest_base.py @@ -32,6 +32,13 @@ exadata_infra, exadb_vm_cluster, exascale_db_storage_vault, + goldengate_connection, + goldengate_connection_assignment, + goldengate_connection_type, + goldengate_deployment, + goldengate_deployment_environment, + goldengate_deployment_type, + goldengate_deployment_version, minor_version, odb_network, odb_subnet, @@ -43,6 +50,15 @@ from google.cloud.oracledatabase_v1.types import ( exascale_db_storage_vault as gco_exascale_db_storage_vault, ) +from google.cloud.oracledatabase_v1.types import ( + goldengate_connection as gco_goldengate_connection, +) +from google.cloud.oracledatabase_v1.types import ( + goldengate_connection_assignment as gco_goldengate_connection_assignment, +) +from google.cloud.oracledatabase_v1.types import ( + goldengate_deployment as gco_goldengate_deployment, +) from google.cloud.oracledatabase_v1.types import odb_network as gco_odb_network from google.cloud.oracledatabase_v1.types import odb_subnet as gco_odb_subnet @@ -471,12 +487,12 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseCreateOdbNetwork: + class _BaseCreateGoldengateConnection: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "odbNetworkId": "", + "goldengateConnectionId": "", } @classmethod @@ -492,15 +508,17 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "post", - "uri": "/v1/{parent=projects/*/locations/*}/odbNetworks", - "body": "odb_network", + "uri": "/v1/{parent=projects/*/locations/*}/goldengateConnections", + "body": "goldengate_connection", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = gco_odb_network.CreateOdbNetworkRequest.pb(request) + pb_request = gco_goldengate_connection.CreateGoldengateConnectionRequest.pb( + request + ) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -522,7 +540,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseCreateOdbNetwork._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseCreateGoldengateConnection._get_unset_required_fields( query_params ) ) @@ -530,12 +548,12 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseCreateOdbSubnet: + class _BaseCreateGoldengateConnectionAssignment: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "odbSubnetId": "", + "goldengateConnectionAssignmentId": "", } @classmethod @@ -551,15 +569,17 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "post", - "uri": "/v1/{parent=projects/*/locations/*/odbNetworks/*}/odbSubnets", - "body": "odb_subnet", + "uri": "/v1/{parent=projects/*/locations/*}/goldengateConnectionAssignments", + "body": "goldengate_connection_assignment", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = gco_odb_subnet.CreateOdbSubnetRequest.pb(request) + pb_request = gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest.pb( + request + ) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -581,7 +601,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseCreateOdbSubnet._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseCreateGoldengateConnectionAssignment._get_unset_required_fields( query_params ) ) @@ -589,11 +609,13 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseDeleteAutonomousDatabase: + class _BaseCreateGoldengateDeployment: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "goldengateDeploymentId": "", + } @classmethod def _get_unset_required_fields(cls, message_dict): @@ -607,18 +629,30 @@ def _get_unset_required_fields(cls, message_dict): def _get_http_options(): http_options: List[Dict[str, str]] = [ { - "method": "delete", - "uri": "/v1/{name=projects/*/locations/*/autonomousDatabases/*}", + "method": "post", + "uri": "/v1/{parent=projects/*/locations/*}/goldengateDeployments", + "body": "goldengate_deployment", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = oracledatabase.DeleteAutonomousDatabaseRequest.pb(request) + pb_request = gco_goldengate_deployment.CreateGoldengateDeploymentRequest.pb( + request + ) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + @staticmethod def _get_query_params_json(transcoded_request): query_params = json.loads( @@ -628,7 +662,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseDeleteAutonomousDatabase._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseCreateGoldengateDeployment._get_unset_required_fields( query_params ) ) @@ -636,11 +670,13 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseDeleteCloudExadataInfrastructure: + class _BaseCreateOdbNetwork: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "odbNetworkId": "", + } @classmethod def _get_unset_required_fields(cls, message_dict): @@ -654,20 +690,28 @@ def _get_unset_required_fields(cls, message_dict): def _get_http_options(): http_options: List[Dict[str, str]] = [ { - "method": "delete", - "uri": "/v1/{name=projects/*/locations/*/cloudExadataInfrastructures/*}", + "method": "post", + "uri": "/v1/{parent=projects/*/locations/*}/odbNetworks", + "body": "odb_network", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = oracledatabase.DeleteCloudExadataInfrastructureRequest.pb( - request - ) + pb_request = gco_odb_network.CreateOdbNetworkRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + @staticmethod def _get_query_params_json(transcoded_request): query_params = json.loads( @@ -677,7 +721,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseDeleteCloudExadataInfrastructure._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseCreateOdbNetwork._get_unset_required_fields( query_params ) ) @@ -685,11 +729,13 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseDeleteCloudVmCluster: + class _BaseCreateOdbSubnet: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "odbSubnetId": "", + } @classmethod def _get_unset_required_fields(cls, message_dict): @@ -703,18 +749,28 @@ def _get_unset_required_fields(cls, message_dict): def _get_http_options(): http_options: List[Dict[str, str]] = [ { - "method": "delete", - "uri": "/v1/{name=projects/*/locations/*/cloudVmClusters/*}", + "method": "post", + "uri": "/v1/{parent=projects/*/locations/*/odbNetworks/*}/odbSubnets", + "body": "odb_subnet", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = oracledatabase.DeleteCloudVmClusterRequest.pb(request) + pb_request = gco_odb_subnet.CreateOdbSubnetRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + @staticmethod def _get_query_params_json(transcoded_request): query_params = json.loads( @@ -724,7 +780,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseDeleteCloudVmCluster._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseCreateOdbSubnet._get_unset_required_fields( query_params ) ) @@ -732,7 +788,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseDeleteDbSystem: + class _BaseDeleteAutonomousDatabase: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -751,14 +807,14 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "delete", - "uri": "/v1/{name=projects/*/locations/*/dbSystems/*}", + "uri": "/v1/{name=projects/*/locations/*/autonomousDatabases/*}", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = db_system.DeleteDbSystemRequest.pb(request) + pb_request = oracledatabase.DeleteAutonomousDatabaseRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -771,7 +827,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseDeleteDbSystem._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseDeleteAutonomousDatabase._get_unset_required_fields( query_params ) ) @@ -779,7 +835,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseDeleteExadbVmCluster: + class _BaseDeleteCloudExadataInfrastructure: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -798,14 +854,16 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "delete", - "uri": "/v1/{name=projects/*/locations/*/exadbVmClusters/*}", + "uri": "/v1/{name=projects/*/locations/*/cloudExadataInfrastructures/*}", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = oracledatabase.DeleteExadbVmClusterRequest.pb(request) + pb_request = oracledatabase.DeleteCloudExadataInfrastructureRequest.pb( + request + ) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -818,7 +876,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseDeleteExadbVmCluster._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseDeleteCloudExadataInfrastructure._get_unset_required_fields( query_params ) ) @@ -826,7 +884,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseDeleteExascaleDbStorageVault: + class _BaseDeleteCloudVmCluster: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -845,18 +903,14 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "delete", - "uri": "/v1/{name=projects/*/locations/*/exascaleDbStorageVaults/*}", + "uri": "/v1/{name=projects/*/locations/*/cloudVmClusters/*}", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = ( - exascale_db_storage_vault.DeleteExascaleDbStorageVaultRequest.pb( - request - ) - ) + pb_request = oracledatabase.DeleteCloudVmClusterRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -869,7 +923,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseDeleteExascaleDbStorageVault._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseDeleteCloudVmCluster._get_unset_required_fields( query_params ) ) @@ -877,7 +931,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseDeleteOdbNetwork: + class _BaseDeleteDbSystem: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -896,14 +950,14 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "delete", - "uri": "/v1/{name=projects/*/locations/*/odbNetworks/*}", + "uri": "/v1/{name=projects/*/locations/*/dbSystems/*}", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = odb_network.DeleteOdbNetworkRequest.pb(request) + pb_request = db_system.DeleteDbSystemRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -916,7 +970,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseDeleteOdbNetwork._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseDeleteDbSystem._get_unset_required_fields( query_params ) ) @@ -924,7 +978,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseDeleteOdbSubnet: + class _BaseDeleteExadbVmCluster: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -943,14 +997,14 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "delete", - "uri": "/v1/{name=projects/*/locations/*/odbNetworks/*/odbSubnets/*}", + "uri": "/v1/{name=projects/*/locations/*/exadbVmClusters/*}", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = odb_subnet.DeleteOdbSubnetRequest.pb(request) + pb_request = oracledatabase.DeleteExadbVmClusterRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -963,7 +1017,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseDeleteOdbSubnet._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseDeleteExadbVmCluster._get_unset_required_fields( query_params ) ) @@ -971,7 +1025,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseFailoverAutonomousDatabase: + class _BaseDeleteExascaleDbStorageVault: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -989,28 +1043,22 @@ def _get_unset_required_fields(cls, message_dict): def _get_http_options(): http_options: List[Dict[str, str]] = [ { - "method": "post", - "uri": "/v1/{name=projects/*/locations/*/autonomousDatabases/*}:failover", - "body": "*", + "method": "delete", + "uri": "/v1/{name=projects/*/locations/*/exascaleDbStorageVaults/*}", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = oracledatabase.FailoverAutonomousDatabaseRequest.pb(request) + pb_request = ( + exascale_db_storage_vault.DeleteExascaleDbStorageVaultRequest.pb( + request + ) + ) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request - @staticmethod - def _get_request_body_json(transcoded_request): - # Jsonify the request body - - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True - ) - return body - @staticmethod def _get_query_params_json(transcoded_request): query_params = json.loads( @@ -1020,7 +1068,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseFailoverAutonomousDatabase._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseDeleteExascaleDbStorageVault._get_unset_required_fields( query_params ) ) @@ -1028,7 +1076,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseGenerateAutonomousDatabaseWallet: + class _BaseDeleteGoldengateConnection: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -1046,30 +1094,20 @@ def _get_unset_required_fields(cls, message_dict): def _get_http_options(): http_options: List[Dict[str, str]] = [ { - "method": "post", - "uri": "/v1/{name=projects/*/locations/*/autonomousDatabases/*}:generateWallet", - "body": "*", + "method": "delete", + "uri": "/v1/{name=projects/*/locations/*/goldengateConnections/*}", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = oracledatabase.GenerateAutonomousDatabaseWalletRequest.pb( + pb_request = goldengate_connection.DeleteGoldengateConnectionRequest.pb( request ) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request - @staticmethod - def _get_request_body_json(transcoded_request): - # Jsonify the request body - - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True - ) - return body - @staticmethod def _get_query_params_json(transcoded_request): query_params = json.loads( @@ -1079,7 +1117,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseGenerateAutonomousDatabaseWallet._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseDeleteGoldengateConnection._get_unset_required_fields( query_params ) ) @@ -1087,7 +1125,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseGetAutonomousDatabase: + class _BaseDeleteGoldengateConnectionAssignment: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -1105,15 +1143,17 @@ def _get_unset_required_fields(cls, message_dict): def _get_http_options(): http_options: List[Dict[str, str]] = [ { - "method": "get", - "uri": "/v1/{name=projects/*/locations/*/autonomousDatabases/*}", + "method": "delete", + "uri": "/v1/{name=projects/*/locations/*/goldengateConnectionAssignments/*}", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = oracledatabase.GetAutonomousDatabaseRequest.pb(request) + pb_request = goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest.pb( + request + ) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -1126,7 +1166,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseGetAutonomousDatabase._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseDeleteGoldengateConnectionAssignment._get_unset_required_fields( query_params ) ) @@ -1134,7 +1174,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseGetCloudExadataInfrastructure: + class _BaseDeleteGoldengateDeployment: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -1152,15 +1192,17 @@ def _get_unset_required_fields(cls, message_dict): def _get_http_options(): http_options: List[Dict[str, str]] = [ { - "method": "get", - "uri": "/v1/{name=projects/*/locations/*/cloudExadataInfrastructures/*}", + "method": "delete", + "uri": "/v1/{name=projects/*/locations/*/goldengateDeployments/*}", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = oracledatabase.GetCloudExadataInfrastructureRequest.pb(request) + pb_request = goldengate_deployment.DeleteGoldengateDeploymentRequest.pb( + request + ) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -1173,7 +1215,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseGetCloudExadataInfrastructure._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseDeleteGoldengateDeployment._get_unset_required_fields( query_params ) ) @@ -1181,7 +1223,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseGetCloudVmCluster: + class _BaseDeleteOdbNetwork: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -1199,15 +1241,15 @@ def _get_unset_required_fields(cls, message_dict): def _get_http_options(): http_options: List[Dict[str, str]] = [ { - "method": "get", - "uri": "/v1/{name=projects/*/locations/*/cloudVmClusters/*}", + "method": "delete", + "uri": "/v1/{name=projects/*/locations/*/odbNetworks/*}", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = oracledatabase.GetCloudVmClusterRequest.pb(request) + pb_request = odb_network.DeleteOdbNetworkRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -1220,7 +1262,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseGetCloudVmCluster._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseDeleteOdbNetwork._get_unset_required_fields( query_params ) ) @@ -1228,7 +1270,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseGetDatabase: + class _BaseDeleteOdbSubnet: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -1246,15 +1288,15 @@ def _get_unset_required_fields(cls, message_dict): def _get_http_options(): http_options: List[Dict[str, str]] = [ { - "method": "get", - "uri": "/v1/{name=projects/*/locations/*/databases/*}", + "method": "delete", + "uri": "/v1/{name=projects/*/locations/*/odbNetworks/*/odbSubnets/*}", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = database.GetDatabaseRequest.pb(request) + pb_request = odb_subnet.DeleteOdbSubnetRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -1267,7 +1309,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseGetDatabase._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseDeleteOdbSubnet._get_unset_required_fields( query_params ) ) @@ -1275,7 +1317,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseGetDbSystem: + class _BaseFailoverAutonomousDatabase: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -1293,18 +1335,28 @@ def _get_unset_required_fields(cls, message_dict): def _get_http_options(): http_options: List[Dict[str, str]] = [ { - "method": "get", - "uri": "/v1/{name=projects/*/locations/*/dbSystems/*}", + "method": "post", + "uri": "/v1/{name=projects/*/locations/*/autonomousDatabases/*}:failover", + "body": "*", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = db_system.GetDbSystemRequest.pb(request) + pb_request = oracledatabase.FailoverAutonomousDatabaseRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + @staticmethod def _get_query_params_json(transcoded_request): query_params = json.loads( @@ -1314,7 +1366,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseGetDbSystem._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseFailoverAutonomousDatabase._get_unset_required_fields( query_params ) ) @@ -1322,7 +1374,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseGetExadbVmCluster: + class _BaseGenerateAutonomousDatabaseWallet: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -1340,18 +1392,30 @@ def _get_unset_required_fields(cls, message_dict): def _get_http_options(): http_options: List[Dict[str, str]] = [ { - "method": "get", - "uri": "/v1/{name=projects/*/locations/*/exadbVmClusters/*}", + "method": "post", + "uri": "/v1/{name=projects/*/locations/*/autonomousDatabases/*}:generateWallet", + "body": "*", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = oracledatabase.GetExadbVmClusterRequest.pb(request) + pb_request = oracledatabase.GenerateAutonomousDatabaseWalletRequest.pb( + request + ) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + @staticmethod def _get_query_params_json(transcoded_request): query_params = json.loads( @@ -1361,7 +1425,289 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseGetExadbVmCluster._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseGenerateAutonomousDatabaseWallet._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetAutonomousDatabase: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=projects/*/locations/*/autonomousDatabases/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = oracledatabase.GetAutonomousDatabaseRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseOracleDatabaseRestTransport._BaseGetAutonomousDatabase._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetCloudExadataInfrastructure: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=projects/*/locations/*/cloudExadataInfrastructures/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = oracledatabase.GetCloudExadataInfrastructureRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseOracleDatabaseRestTransport._BaseGetCloudExadataInfrastructure._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetCloudVmCluster: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=projects/*/locations/*/cloudVmClusters/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = oracledatabase.GetCloudVmClusterRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseOracleDatabaseRestTransport._BaseGetCloudVmCluster._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetDatabase: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=projects/*/locations/*/databases/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = database.GetDatabaseRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseOracleDatabaseRestTransport._BaseGetDatabase._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetDbSystem: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=projects/*/locations/*/dbSystems/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = db_system.GetDbSystemRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseOracleDatabaseRestTransport._BaseGetDbSystem._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetExadbVmCluster: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=projects/*/locations/*/exadbVmClusters/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = oracledatabase.GetExadbVmClusterRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseOracleDatabaseRestTransport._BaseGetExadbVmCluster._get_unset_required_fields( query_params ) ) @@ -1388,14 +1734,743 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "get", - "uri": "/v1/{name=projects/*/locations/*/exascaleDbStorageVaults/*}", + "uri": "/v1/{name=projects/*/locations/*/exascaleDbStorageVaults/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = exascale_db_storage_vault.GetExascaleDbStorageVaultRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseOracleDatabaseRestTransport._BaseGetExascaleDbStorageVault._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetGoldengateConnection: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=projects/*/locations/*/goldengateConnections/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = goldengate_connection.GetGoldengateConnectionRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseOracleDatabaseRestTransport._BaseGetGoldengateConnection._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetGoldengateConnectionAssignment: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=projects/*/locations/*/goldengateConnectionAssignments/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseOracleDatabaseRestTransport._BaseGetGoldengateConnectionAssignment._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetGoldengateConnectionType: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=projects/*/locations/*/goldengateConnectionTypes/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = ( + goldengate_connection_type.GetGoldengateConnectionTypeRequest.pb( + request + ) + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseOracleDatabaseRestTransport._BaseGetGoldengateConnectionType._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetGoldengateDeployment: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=projects/*/locations/*/goldengateDeployments/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = goldengate_deployment.GetGoldengateDeploymentRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseOracleDatabaseRestTransport._BaseGetGoldengateDeployment._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetGoldengateDeploymentEnvironment: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=projects/*/locations/*/goldengateDeploymentEnvironments/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseOracleDatabaseRestTransport._BaseGetGoldengateDeploymentEnvironment._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetGoldengateDeploymentType: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=projects/*/locations/*/goldengateDeploymentTypes/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = ( + goldengate_deployment_type.GetGoldengateDeploymentTypeRequest.pb( + request + ) + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseOracleDatabaseRestTransport._BaseGetGoldengateDeploymentType._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetGoldengateDeploymentVersion: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=projects/*/locations/*/goldengateDeploymentVersions/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = ( + goldengate_deployment_version.GetGoldengateDeploymentVersionRequest.pb( + request + ) + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseOracleDatabaseRestTransport._BaseGetGoldengateDeploymentVersion._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetOdbNetwork: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=projects/*/locations/*/odbNetworks/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = odb_network.GetOdbNetworkRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseOracleDatabaseRestTransport._BaseGetOdbNetwork._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetOdbSubnet: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=projects/*/locations/*/odbNetworks/*/odbSubnets/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = odb_subnet.GetOdbSubnetRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseOracleDatabaseRestTransport._BaseGetOdbSubnet._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetPluggableDatabase: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=projects/*/locations/*/pluggableDatabases/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = pluggable_database.GetPluggableDatabaseRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseOracleDatabaseRestTransport._BaseGetPluggableDatabase._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListAutonomousDatabaseBackups: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=projects/*/locations/*}/autonomousDatabaseBackups", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = oracledatabase.ListAutonomousDatabaseBackupsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabaseBackups._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListAutonomousDatabaseCharacterSets: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=projects/*/locations/*}/autonomousDatabaseCharacterSets", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = oracledatabase.ListAutonomousDatabaseCharacterSetsRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabaseCharacterSets._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListAutonomousDatabases: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=projects/*/locations/*}/autonomousDatabases", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = exascale_db_storage_vault.GetExascaleDbStorageVaultRequest.pb( + pb_request = oracledatabase.ListAutonomousDatabasesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabases._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListAutonomousDbVersions: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=projects/*/locations/*}/autonomousDbVersions", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = oracledatabase.ListAutonomousDbVersionsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseOracleDatabaseRestTransport._BaseListAutonomousDbVersions._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListCloudExadataInfrastructures: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=projects/*/locations/*}/cloudExadataInfrastructures", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = oracledatabase.ListCloudExadataInfrastructuresRequest.pb( request ) transcoded_request = path_template.transcode(http_options, pb_request) @@ -1410,7 +2485,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseGetExascaleDbStorageVault._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseListCloudExadataInfrastructures._get_unset_required_fields( query_params ) ) @@ -1418,7 +2493,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseGetOdbNetwork: + class _BaseListCloudVmClusters: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -1437,14 +2512,14 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "get", - "uri": "/v1/{name=projects/*/locations/*/odbNetworks/*}", + "uri": "/v1/{parent=projects/*/locations/*}/cloudVmClusters", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = odb_network.GetOdbNetworkRequest.pb(request) + pb_request = oracledatabase.ListCloudVmClustersRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -1457,7 +2532,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseGetOdbNetwork._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseListCloudVmClusters._get_unset_required_fields( query_params ) ) @@ -1465,7 +2540,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseGetOdbSubnet: + class _BaseListDatabaseCharacterSets: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -1484,14 +2559,16 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "get", - "uri": "/v1/{name=projects/*/locations/*/odbNetworks/*/odbSubnets/*}", + "uri": "/v1/{parent=projects/*/locations/*}/databaseCharacterSets", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = odb_subnet.GetOdbSubnetRequest.pb(request) + pb_request = database_character_set.ListDatabaseCharacterSetsRequest.pb( + request + ) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -1504,7 +2581,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseGetOdbSubnet._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseListDatabaseCharacterSets._get_unset_required_fields( query_params ) ) @@ -1512,7 +2589,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseGetPluggableDatabase: + class _BaseListDatabases: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -1531,14 +2608,14 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "get", - "uri": "/v1/{name=projects/*/locations/*/pluggableDatabases/*}", + "uri": "/v1/{parent=projects/*/locations/*}/databases", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = pluggable_database.GetPluggableDatabaseRequest.pb(request) + pb_request = database.ListDatabasesRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -1551,7 +2628,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseGetPluggableDatabase._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseListDatabases._get_unset_required_fields( query_params ) ) @@ -1559,7 +2636,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseListAutonomousDatabaseBackups: + class _BaseListDbNodes: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -1578,14 +2655,114 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "get", - "uri": "/v1/{parent=projects/*/locations/*}/autonomousDatabaseBackups", + "uri": "/v1/{parent=projects/*/locations/*/cloudVmClusters/*}/dbNodes", + }, + { + "method": "get", + "uri": "/v1/{parent=projects/*/locations/*/exadbVmClusters/*}/dbNodes", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = oracledatabase.ListAutonomousDatabaseBackupsRequest.pb(request) + pb_request = oracledatabase.ListDbNodesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseOracleDatabaseRestTransport._BaseListDbNodes._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListDbServers: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=projects/*/locations/*/cloudExadataInfrastructures/*}/dbServers", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = oracledatabase.ListDbServersRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseOracleDatabaseRestTransport._BaseListDbServers._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListDbSystemInitialStorageSizes: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=projects/*/locations/*}/dbSystemInitialStorageSizes", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = db_system_initial_storage_size.ListDbSystemInitialStorageSizesRequest.pb( + request + ) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -1598,7 +2775,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabaseBackups._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseListDbSystemInitialStorageSizes._get_unset_required_fields( query_params ) ) @@ -1606,7 +2783,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseListAutonomousDatabaseCharacterSets: + class _BaseListDbSystems: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -1625,16 +2802,14 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "get", - "uri": "/v1/{parent=projects/*/locations/*}/autonomousDatabaseCharacterSets", + "uri": "/v1/{parent=projects/*/locations/*}/dbSystems", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = oracledatabase.ListAutonomousDatabaseCharacterSetsRequest.pb( - request - ) + pb_request = db_system.ListDbSystemsRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -1647,7 +2822,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabaseCharacterSets._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseListDbSystems._get_unset_required_fields( query_params ) ) @@ -1655,7 +2830,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseListAutonomousDatabases: + class _BaseListDbSystemShapes: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -1674,14 +2849,14 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "get", - "uri": "/v1/{parent=projects/*/locations/*}/autonomousDatabases", + "uri": "/v1/{parent=projects/*/locations/*}/dbSystemShapes", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = oracledatabase.ListAutonomousDatabasesRequest.pb(request) + pb_request = oracledatabase.ListDbSystemShapesRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -1694,7 +2869,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseListAutonomousDatabases._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseListDbSystemShapes._get_unset_required_fields( query_params ) ) @@ -1702,7 +2877,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseListAutonomousDbVersions: + class _BaseListDbVersions: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -1721,14 +2896,14 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "get", - "uri": "/v1/{parent=projects/*/locations/*}/autonomousDbVersions", + "uri": "/v1/{parent=projects/*/locations/*}/dbVersions", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = oracledatabase.ListAutonomousDbVersionsRequest.pb(request) + pb_request = db_version.ListDbVersionsRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -1741,7 +2916,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseListAutonomousDbVersions._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseListDbVersions._get_unset_required_fields( query_params ) ) @@ -1749,7 +2924,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseListCloudExadataInfrastructures: + class _BaseListEntitlements: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -1768,16 +2943,14 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "get", - "uri": "/v1/{parent=projects/*/locations/*}/cloudExadataInfrastructures", + "uri": "/v1/{parent=projects/*/locations/*}/entitlements", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = oracledatabase.ListCloudExadataInfrastructuresRequest.pb( - request - ) + pb_request = oracledatabase.ListEntitlementsRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -1790,7 +2963,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseListCloudExadataInfrastructures._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseListEntitlements._get_unset_required_fields( query_params ) ) @@ -1798,7 +2971,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseListCloudVmClusters: + class _BaseListExadbVmClusters: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -1817,14 +2990,14 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "get", - "uri": "/v1/{parent=projects/*/locations/*}/cloudVmClusters", + "uri": "/v1/{parent=projects/*/locations/*}/exadbVmClusters", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = oracledatabase.ListCloudVmClustersRequest.pb(request) + pb_request = oracledatabase.ListExadbVmClustersRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -1837,7 +3010,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseListCloudVmClusters._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseListExadbVmClusters._get_unset_required_fields( query_params ) ) @@ -1845,7 +3018,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseListDatabaseCharacterSets: + class _BaseListExascaleDbStorageVaults: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -1864,15 +3037,15 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "get", - "uri": "/v1/{parent=projects/*/locations/*}/databaseCharacterSets", + "uri": "/v1/{parent=projects/*/locations/*}/exascaleDbStorageVaults", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = database_character_set.ListDatabaseCharacterSetsRequest.pb( - request + pb_request = ( + exascale_db_storage_vault.ListExascaleDbStorageVaultsRequest.pb(request) ) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -1886,7 +3059,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseListDatabaseCharacterSets._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseListExascaleDbStorageVaults._get_unset_required_fields( query_params ) ) @@ -1894,7 +3067,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseListDatabases: + class _BaseListGiVersions: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -1913,14 +3086,14 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "get", - "uri": "/v1/{parent=projects/*/locations/*}/databases", + "uri": "/v1/{parent=projects/*/locations/*}/giVersions", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = database.ListDatabasesRequest.pb(request) + pb_request = oracledatabase.ListGiVersionsRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -1933,7 +3106,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseListDatabases._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseListGiVersions._get_unset_required_fields( query_params ) ) @@ -1941,7 +3114,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseListDbNodes: + class _BaseListGoldengateConnectionAssignments: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -1960,18 +3133,16 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "get", - "uri": "/v1/{parent=projects/*/locations/*/cloudVmClusters/*}/dbNodes", - }, - { - "method": "get", - "uri": "/v1/{parent=projects/*/locations/*/exadbVmClusters/*}/dbNodes", + "uri": "/v1/{parent=projects/*/locations/*}/goldengateConnectionAssignments", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = oracledatabase.ListDbNodesRequest.pb(request) + pb_request = goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest.pb( + request + ) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -1984,7 +3155,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseListDbNodes._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseListGoldengateConnectionAssignments._get_unset_required_fields( query_params ) ) @@ -1992,7 +3163,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseListDbServers: + class _BaseListGoldengateConnections: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -2011,14 +3182,16 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "get", - "uri": "/v1/{parent=projects/*/locations/*/cloudExadataInfrastructures/*}/dbServers", + "uri": "/v1/{parent=projects/*/locations/*}/goldengateConnections", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = oracledatabase.ListDbServersRequest.pb(request) + pb_request = goldengate_connection.ListGoldengateConnectionsRequest.pb( + request + ) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -2031,7 +3204,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseListDbServers._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseListGoldengateConnections._get_unset_required_fields( query_params ) ) @@ -2039,7 +3212,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseListDbSystemInitialStorageSizes: + class _BaseListGoldengateConnectionTypes: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -2058,15 +3231,17 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "get", - "uri": "/v1/{parent=projects/*/locations/*}/dbSystemInitialStorageSizes", + "uri": "/v1/{parent=projects/*/locations/*}/goldengateConnectionTypes", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = db_system_initial_storage_size.ListDbSystemInitialStorageSizesRequest.pb( - request + pb_request = ( + goldengate_connection_type.ListGoldengateConnectionTypesRequest.pb( + request + ) ) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -2080,7 +3255,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseListDbSystemInitialStorageSizes._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseListGoldengateConnectionTypes._get_unset_required_fields( query_params ) ) @@ -2088,7 +3263,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseListDbSystems: + class _BaseListGoldengateDeploymentEnvironments: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -2107,14 +3282,16 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "get", - "uri": "/v1/{parent=projects/*/locations/*}/dbSystems", + "uri": "/v1/{parent=projects/*/locations/*}/goldengateDeploymentEnvironments", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = db_system.ListDbSystemsRequest.pb(request) + pb_request = goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest.pb( + request + ) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -2127,7 +3304,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseListDbSystems._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseListGoldengateDeploymentEnvironments._get_unset_required_fields( query_params ) ) @@ -2135,7 +3312,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseListDbSystemShapes: + class _BaseListGoldengateDeployments: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -2154,14 +3331,16 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "get", - "uri": "/v1/{parent=projects/*/locations/*}/dbSystemShapes", + "uri": "/v1/{parent=projects/*/locations/*}/goldengateDeployments", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = oracledatabase.ListDbSystemShapesRequest.pb(request) + pb_request = goldengate_deployment.ListGoldengateDeploymentsRequest.pb( + request + ) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -2174,7 +3353,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseListDbSystemShapes._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseListGoldengateDeployments._get_unset_required_fields( query_params ) ) @@ -2182,7 +3361,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseListDbVersions: + class _BaseListGoldengateDeploymentTypes: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -2201,14 +3380,18 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "get", - "uri": "/v1/{parent=projects/*/locations/*}/dbVersions", + "uri": "/v1/{parent=projects/*/locations/*}/goldengateDeploymentTypes", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = db_version.ListDbVersionsRequest.pb(request) + pb_request = ( + goldengate_deployment_type.ListGoldengateDeploymentTypesRequest.pb( + request + ) + ) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -2221,7 +3404,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseListDbVersions._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseListGoldengateDeploymentTypes._get_unset_required_fields( query_params ) ) @@ -2229,7 +3412,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseListEntitlements: + class _BaseListGoldengateDeploymentVersions: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -2248,14 +3431,16 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "get", - "uri": "/v1/{parent=projects/*/locations/*}/entitlements", + "uri": "/v1/{parent=projects/*/locations/*}/goldengateDeploymentVersions", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = oracledatabase.ListEntitlementsRequest.pb(request) + pb_request = goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest.pb( + request + ) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -2268,7 +3453,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseListEntitlements._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseListGoldengateDeploymentVersions._get_unset_required_fields( query_params ) ) @@ -2276,7 +3461,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseListExadbVmClusters: + class _BaseListMinorVersions: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -2295,14 +3480,14 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "get", - "uri": "/v1/{parent=projects/*/locations/*}/exadbVmClusters", + "uri": "/v1/{parent=projects/*/locations/*/giVersions/*}/minorVersions", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = oracledatabase.ListExadbVmClustersRequest.pb(request) + pb_request = minor_version.ListMinorVersionsRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -2315,7 +3500,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseListExadbVmClusters._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseListMinorVersions._get_unset_required_fields( query_params ) ) @@ -2323,7 +3508,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseListExascaleDbStorageVaults: + class _BaseListOdbNetworks: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -2342,16 +3527,14 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "get", - "uri": "/v1/{parent=projects/*/locations/*}/exascaleDbStorageVaults", + "uri": "/v1/{parent=projects/*/locations/*}/odbNetworks", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = ( - exascale_db_storage_vault.ListExascaleDbStorageVaultsRequest.pb(request) - ) + pb_request = odb_network.ListOdbNetworksRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -2364,7 +3547,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseListExascaleDbStorageVaults._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseListOdbNetworks._get_unset_required_fields( query_params ) ) @@ -2372,7 +3555,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseListGiVersions: + class _BaseListOdbSubnets: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -2391,14 +3574,14 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "get", - "uri": "/v1/{parent=projects/*/locations/*}/giVersions", + "uri": "/v1/{parent=projects/*/locations/*/odbNetworks/*}/odbSubnets", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = oracledatabase.ListGiVersionsRequest.pb(request) + pb_request = odb_subnet.ListOdbSubnetsRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -2411,7 +3594,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseListGiVersions._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseListOdbSubnets._get_unset_required_fields( query_params ) ) @@ -2419,7 +3602,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseListMinorVersions: + class _BaseListPluggableDatabases: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -2438,14 +3621,14 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "get", - "uri": "/v1/{parent=projects/*/locations/*/giVersions/*}/minorVersions", + "uri": "/v1/{parent=projects/*/locations/*}/pluggableDatabases", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = minor_version.ListMinorVersionsRequest.pb(request) + pb_request = pluggable_database.ListPluggableDatabasesRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -2458,7 +3641,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseListMinorVersions._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseListPluggableDatabases._get_unset_required_fields( query_params ) ) @@ -2466,7 +3649,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseListOdbNetworks: + class _BaseRemoveVirtualMachineExadbVmCluster: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -2484,18 +3667,30 @@ def _get_unset_required_fields(cls, message_dict): def _get_http_options(): http_options: List[Dict[str, str]] = [ { - "method": "get", - "uri": "/v1/{parent=projects/*/locations/*}/odbNetworks", + "method": "post", + "uri": "/v1/{name=projects/*/locations/*/exadbVmClusters/*}:removeVirtualMachine", + "body": "*", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = odb_network.ListOdbNetworksRequest.pb(request) + pb_request = oracledatabase.RemoveVirtualMachineExadbVmClusterRequest.pb( + request + ) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + @staticmethod def _get_query_params_json(transcoded_request): query_params = json.loads( @@ -2505,7 +3700,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseListOdbNetworks._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseRemoveVirtualMachineExadbVmCluster._get_unset_required_fields( query_params ) ) @@ -2513,7 +3708,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseListOdbSubnets: + class _BaseRestartAutonomousDatabase: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -2531,18 +3726,28 @@ def _get_unset_required_fields(cls, message_dict): def _get_http_options(): http_options: List[Dict[str, str]] = [ { - "method": "get", - "uri": "/v1/{parent=projects/*/locations/*/odbNetworks/*}/odbSubnets", + "method": "post", + "uri": "/v1/{name=projects/*/locations/*/autonomousDatabases/*}:restart", + "body": "*", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = odb_subnet.ListOdbSubnetsRequest.pb(request) + pb_request = oracledatabase.RestartAutonomousDatabaseRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + @staticmethod def _get_query_params_json(transcoded_request): query_params = json.loads( @@ -2552,7 +3757,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseListOdbSubnets._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseRestartAutonomousDatabase._get_unset_required_fields( query_params ) ) @@ -2560,7 +3765,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseListPluggableDatabases: + class _BaseRestoreAutonomousDatabase: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -2578,18 +3783,28 @@ def _get_unset_required_fields(cls, message_dict): def _get_http_options(): http_options: List[Dict[str, str]] = [ { - "method": "get", - "uri": "/v1/{parent=projects/*/locations/*}/pluggableDatabases", + "method": "post", + "uri": "/v1/{name=projects/*/locations/*/autonomousDatabases/*}:restore", + "body": "*", }, ] return http_options @staticmethod def _get_transcoded_request(http_options, request): - pb_request = pluggable_database.ListPluggableDatabasesRequest.pb(request) + pb_request = oracledatabase.RestoreAutonomousDatabaseRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + @staticmethod def _get_query_params_json(transcoded_request): query_params = json.loads( @@ -2599,7 +3814,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseListPluggableDatabases._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseRestoreAutonomousDatabase._get_unset_required_fields( query_params ) ) @@ -2607,7 +3822,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseRemoveVirtualMachineExadbVmCluster: + class _BaseStartAutonomousDatabase: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -2626,7 +3841,7 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "post", - "uri": "/v1/{name=projects/*/locations/*/exadbVmClusters/*}:removeVirtualMachine", + "uri": "/v1/{name=projects/*/locations/*/autonomousDatabases/*}:start", "body": "*", }, ] @@ -2634,9 +3849,7 @@ def _get_http_options(): @staticmethod def _get_transcoded_request(http_options, request): - pb_request = oracledatabase.RemoveVirtualMachineExadbVmClusterRequest.pb( - request - ) + pb_request = oracledatabase.StartAutonomousDatabaseRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -2658,7 +3871,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseRemoveVirtualMachineExadbVmCluster._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseStartAutonomousDatabase._get_unset_required_fields( query_params ) ) @@ -2666,7 +3879,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseRestartAutonomousDatabase: + class _BaseStartGoldengateDeployment: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -2685,7 +3898,7 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "post", - "uri": "/v1/{name=projects/*/locations/*/autonomousDatabases/*}:restart", + "uri": "/v1/{name=projects/*/locations/*/goldengateDeployments/*}:start", "body": "*", }, ] @@ -2693,7 +3906,9 @@ def _get_http_options(): @staticmethod def _get_transcoded_request(http_options, request): - pb_request = oracledatabase.RestartAutonomousDatabaseRequest.pb(request) + pb_request = goldengate_deployment.StartGoldengateDeploymentRequest.pb( + request + ) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -2715,7 +3930,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseRestartAutonomousDatabase._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseStartGoldengateDeployment._get_unset_required_fields( query_params ) ) @@ -2723,7 +3938,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseRestoreAutonomousDatabase: + class _BaseStopAutonomousDatabase: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -2742,7 +3957,7 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "post", - "uri": "/v1/{name=projects/*/locations/*/autonomousDatabases/*}:restore", + "uri": "/v1/{name=projects/*/locations/*/autonomousDatabases/*}:stop", "body": "*", }, ] @@ -2750,7 +3965,7 @@ def _get_http_options(): @staticmethod def _get_transcoded_request(http_options, request): - pb_request = oracledatabase.RestoreAutonomousDatabaseRequest.pb(request) + pb_request = oracledatabase.StopAutonomousDatabaseRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -2772,7 +3987,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseRestoreAutonomousDatabase._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseStopAutonomousDatabase._get_unset_required_fields( query_params ) ) @@ -2780,7 +3995,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseStartAutonomousDatabase: + class _BaseStopGoldengateDeployment: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -2799,7 +4014,7 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "post", - "uri": "/v1/{name=projects/*/locations/*/autonomousDatabases/*}:start", + "uri": "/v1/{name=projects/*/locations/*/goldengateDeployments/*}:stop", "body": "*", }, ] @@ -2807,7 +4022,9 @@ def _get_http_options(): @staticmethod def _get_transcoded_request(http_options, request): - pb_request = oracledatabase.StartAutonomousDatabaseRequest.pb(request) + pb_request = goldengate_deployment.StopGoldengateDeploymentRequest.pb( + request + ) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -2829,7 +4046,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseStartAutonomousDatabase._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseStopGoldengateDeployment._get_unset_required_fields( query_params ) ) @@ -2837,7 +4054,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseStopAutonomousDatabase: + class _BaseSwitchoverAutonomousDatabase: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -2856,7 +4073,7 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "post", - "uri": "/v1/{name=projects/*/locations/*/autonomousDatabases/*}:stop", + "uri": "/v1/{name=projects/*/locations/*/autonomousDatabases/*}:switchover", "body": "*", }, ] @@ -2864,7 +4081,7 @@ def _get_http_options(): @staticmethod def _get_transcoded_request(http_options, request): - pb_request = oracledatabase.StopAutonomousDatabaseRequest.pb(request) + pb_request = oracledatabase.SwitchoverAutonomousDatabaseRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -2886,7 +4103,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseStopAutonomousDatabase._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseSwitchoverAutonomousDatabase._get_unset_required_fields( query_params ) ) @@ -2894,7 +4111,7 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params - class _BaseSwitchoverAutonomousDatabase: + class _BaseTestGoldengateConnectionAssignment: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -2913,7 +4130,7 @@ def _get_http_options(): http_options: List[Dict[str, str]] = [ { "method": "post", - "uri": "/v1/{name=projects/*/locations/*/autonomousDatabases/*}:switchover", + "uri": "/v1/{name=projects/*/locations/*/goldengateConnectionAssignments/*}:test", "body": "*", }, ] @@ -2921,7 +4138,9 @@ def _get_http_options(): @staticmethod def _get_transcoded_request(http_options, request): - pb_request = oracledatabase.SwitchoverAutonomousDatabaseRequest.pb(request) + pb_request = goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest.pb( + request + ) transcoded_request = path_template.transcode(http_options, pb_request) return transcoded_request @@ -2943,7 +4162,7 @@ def _get_query_params_json(transcoded_request): ) ) query_params.update( - _BaseOracleDatabaseRestTransport._BaseSwitchoverAutonomousDatabase._get_unset_required_fields( + _BaseOracleDatabaseRestTransport._BaseTestGoldengateConnectionAssignment._get_unset_required_fields( query_params ) ) diff --git a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/__init__.py b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/__init__.py index b77cd6f2b0a7..43350c6fc802 100644 --- a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/__init__.py +++ b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/__init__.py @@ -123,6 +123,112 @@ from .gi_version import ( GiVersion, ) +from .goldengate_connection import ( + AmazonS3IcebergStorage, + AzureDataLakeStorageIcebergStorage, + CreateGoldengateConnectionRequest, + DeleteGoldengateConnectionRequest, + GetGoldengateConnectionRequest, + GlueIcebergCatalog, + GoldengateAmazonKinesisConnectionProperties, + GoldengateAmazonRedshiftConnectionProperties, + GoldengateAmazonS3ConnectionProperties, + GoldengateAzureDataLakeStorageConnectionProperties, + GoldengateAzureSynapseAnalyticsConnectionProperties, + GoldengateConnection, + GoldengateConnectionProperties, + GoldengateDatabricksConnectionProperties, + GoldengateDb2ConnectionProperties, + GoldengateElasticsearchConnectionProperties, + GoldengateGenericConnectionProperties, + GoldengateGoldengateConnectionProperties, + GoldengateGoogleBigQueryConnectionProperties, + GoldengateGoogleCloudStorageConnectionProperties, + GoldengateGooglePubsubConnectionProperties, + GoldengateHdfsConnectionProperties, + GoldengateIcebergConnectionProperties, + GoldengateJavaMessageServiceConnectionProperties, + GoldengateKafkaConnectionProperties, + GoldengateKafkaSchemaRegistryConnectionProperties, + GoldengateMicrosoftFabricConnectionProperties, + GoldengateMicrosoftSqlserverConnectionProperties, + GoldengateMongodbConnectionProperties, + GoldengateMysqlConnectionProperties, + GoldengateOciObjectStorageConnectionProperties, + GoldengateOracleAIDataPlatformConnectionProperties, + GoldengateOracleConnectionProperties, + GoldengateOracleNosqlConnectionProperties, + GoldengatePostgresqlConnectionProperties, + GoldengateRedisConnectionProperties, + GoldengateSnowflakeConnectionProperties, + GoogleCloudStorageIcebergStorage, + IcebergCatalog, + IcebergStorage, + KafkaBootstrapServer, + ListGoldengateConnectionsRequest, + ListGoldengateConnectionsResponse, + NameValuePair, + NessieIcebergCatalog, + PolarisIcebergCatalog, + RestIcebergCatalog, +) +from .goldengate_connection_assignment import ( + CreateGoldengateConnectionAssignmentRequest, + DeleteGoldengateConnectionAssignmentRequest, + GetGoldengateConnectionAssignmentRequest, + GoldengateConnectionAssignment, + GoldengateConnectionAssignmentProperties, + ListGoldengateConnectionAssignmentsRequest, + ListGoldengateConnectionAssignmentsResponse, + TestConnectionAssignmentError, + TestGoldengateConnectionAssignmentRequest, + TestGoldengateConnectionAssignmentResponse, +) +from .goldengate_connection_type import ( + GetGoldengateConnectionTypeRequest, + GoldengateConnectionType, + ListGoldengateConnectionTypesRequest, + ListGoldengateConnectionTypesResponse, +) +from .goldengate_deployment import ( + CreateGoldengateDeploymentRequest, + DeleteGoldengateDeploymentRequest, + DeploymentDiagnosticData, + GetGoldengateDeploymentRequest, + GoldengateBackupSchedule, + GoldengateDeployment, + GoldengateDeploymentLock, + GoldengateDeploymentProperties, + GoldengateGroupToRolesMapping, + GoldengateMaintenanceConfig, + GoldengateMaintenanceWindow, + GoldengateOggDeployment, + GoldengatePlacement, + IngressIp, + ListGoldengateDeploymentsRequest, + ListGoldengateDeploymentsResponse, + StartGoldengateDeploymentRequest, + StopGoldengateDeploymentRequest, +) +from .goldengate_deployment_environment import ( + GetGoldengateDeploymentEnvironmentRequest, + GoldengateDeploymentEnvironment, + ListGoldengateDeploymentEnvironmentsRequest, + ListGoldengateDeploymentEnvironmentsResponse, +) +from .goldengate_deployment_type import ( + GetGoldengateDeploymentTypeRequest, + GoldengateDeploymentType, + ListGoldengateDeploymentTypesRequest, + ListGoldengateDeploymentTypesResponse, +) +from .goldengate_deployment_version import ( + GetGoldengateDeploymentVersionRequest, + GoldengateDeploymentVersion, + GoldengateDeploymentVersionProperties, + ListGoldengateDeploymentVersionsRequest, + ListGoldengateDeploymentVersionsResponse, +) from .location_metadata import ( LocationMetadata, ) @@ -288,6 +394,98 @@ "ListExascaleDbStorageVaultsRequest", "ListExascaleDbStorageVaultsResponse", "GiVersion", + "AmazonS3IcebergStorage", + "AzureDataLakeStorageIcebergStorage", + "CreateGoldengateConnectionRequest", + "DeleteGoldengateConnectionRequest", + "GetGoldengateConnectionRequest", + "GlueIcebergCatalog", + "GoldengateAmazonKinesisConnectionProperties", + "GoldengateAmazonRedshiftConnectionProperties", + "GoldengateAmazonS3ConnectionProperties", + "GoldengateAzureDataLakeStorageConnectionProperties", + "GoldengateAzureSynapseAnalyticsConnectionProperties", + "GoldengateConnection", + "GoldengateConnectionProperties", + "GoldengateDatabricksConnectionProperties", + "GoldengateDb2ConnectionProperties", + "GoldengateElasticsearchConnectionProperties", + "GoldengateGenericConnectionProperties", + "GoldengateGoldengateConnectionProperties", + "GoldengateGoogleBigQueryConnectionProperties", + "GoldengateGoogleCloudStorageConnectionProperties", + "GoldengateGooglePubsubConnectionProperties", + "GoldengateHdfsConnectionProperties", + "GoldengateIcebergConnectionProperties", + "GoldengateJavaMessageServiceConnectionProperties", + "GoldengateKafkaConnectionProperties", + "GoldengateKafkaSchemaRegistryConnectionProperties", + "GoldengateMicrosoftFabricConnectionProperties", + "GoldengateMicrosoftSqlserverConnectionProperties", + "GoldengateMongodbConnectionProperties", + "GoldengateMysqlConnectionProperties", + "GoldengateOciObjectStorageConnectionProperties", + "GoldengateOracleAIDataPlatformConnectionProperties", + "GoldengateOracleConnectionProperties", + "GoldengateOracleNosqlConnectionProperties", + "GoldengatePostgresqlConnectionProperties", + "GoldengateRedisConnectionProperties", + "GoldengateSnowflakeConnectionProperties", + "GoogleCloudStorageIcebergStorage", + "IcebergCatalog", + "IcebergStorage", + "KafkaBootstrapServer", + "ListGoldengateConnectionsRequest", + "ListGoldengateConnectionsResponse", + "NameValuePair", + "NessieIcebergCatalog", + "PolarisIcebergCatalog", + "RestIcebergCatalog", + "CreateGoldengateConnectionAssignmentRequest", + "DeleteGoldengateConnectionAssignmentRequest", + "GetGoldengateConnectionAssignmentRequest", + "GoldengateConnectionAssignment", + "GoldengateConnectionAssignmentProperties", + "ListGoldengateConnectionAssignmentsRequest", + "ListGoldengateConnectionAssignmentsResponse", + "TestConnectionAssignmentError", + "TestGoldengateConnectionAssignmentRequest", + "TestGoldengateConnectionAssignmentResponse", + "GetGoldengateConnectionTypeRequest", + "GoldengateConnectionType", + "ListGoldengateConnectionTypesRequest", + "ListGoldengateConnectionTypesResponse", + "CreateGoldengateDeploymentRequest", + "DeleteGoldengateDeploymentRequest", + "DeploymentDiagnosticData", + "GetGoldengateDeploymentRequest", + "GoldengateBackupSchedule", + "GoldengateDeployment", + "GoldengateDeploymentLock", + "GoldengateDeploymentProperties", + "GoldengateGroupToRolesMapping", + "GoldengateMaintenanceConfig", + "GoldengateMaintenanceWindow", + "GoldengateOggDeployment", + "GoldengatePlacement", + "IngressIp", + "ListGoldengateDeploymentsRequest", + "ListGoldengateDeploymentsResponse", + "StartGoldengateDeploymentRequest", + "StopGoldengateDeploymentRequest", + "GetGoldengateDeploymentEnvironmentRequest", + "GoldengateDeploymentEnvironment", + "ListGoldengateDeploymentEnvironmentsRequest", + "ListGoldengateDeploymentEnvironmentsResponse", + "GetGoldengateDeploymentTypeRequest", + "GoldengateDeploymentType", + "ListGoldengateDeploymentTypesRequest", + "ListGoldengateDeploymentTypesResponse", + "GetGoldengateDeploymentVersionRequest", + "GoldengateDeploymentVersion", + "GoldengateDeploymentVersionProperties", + "ListGoldengateDeploymentVersionsRequest", + "ListGoldengateDeploymentVersionsResponse", "LocationMetadata", "ListMinorVersionsRequest", "ListMinorVersionsResponse", diff --git a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/autonomous_database.py b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/autonomous_database.py index 10e8c971862a..88c288633202 100644 --- a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/autonomous_database.py +++ b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/autonomous_database.py @@ -229,22 +229,30 @@ class AutonomousDatabase(proto.Message): the following format: projects/{project}/locations/{region}/autonomousDatabases/{autonomous_database} database (str): - Optional. The name of the Autonomous - Database. The database name must be unique in - the project. The name must begin with a letter - and can contain a maximum of 30 alphanumeric - characters. + Optional. Immutable. The name of the + Autonomous Database. The database name must be + unique in the project. The name must begin with + a letter and can contain a maximum of 30 + alphanumeric characters. display_name (str): - Optional. The display name for the Autonomous - Database. The name does not have to be unique - within your project. + Optional. Immutable. The display name for the + Autonomous Database. The name does not have to + be unique within your project. entitlement_id (str): Output only. The ID of the subscription entitlement associated with the Autonomous Database. admin_password (str): - Optional. The password for the default ADMIN - user. + Optional. Immutable. The password for the default ADMIN + user. Note: Only one of ``admin_password_secret_version`` or + ``admin_password`` can be populated. + admin_password_secret_version (str): + Optional. Immutable. The resource name of a secret version + in Secret Manager which contains the database admin user's + password. Format: + projects/{project}/secrets/{secret}/versions/{version}. + Note: Only one of ``admin_password_secret_version`` or + ``admin_password`` can be populated. properties (google.cloud.oracledatabase_v1.types.AutonomousDatabaseProperties): Optional. The properties of the Autonomous Database. @@ -252,28 +260,31 @@ class AutonomousDatabase(proto.Message): Optional. The labels or tags associated with the Autonomous Database. network (str): - Optional. The name of the VPC network used by - the Autonomous Database in the following format: + Optional. Immutable. The name of the VPC + network used by the Autonomous Database in the + following format: + projects/{project}/global/networks/{network} cidr (str): - Optional. The subnet CIDR range for the - Autonomous Database. + Optional. Immutable. The subnet CIDR range + for the Autonomous Database. odb_network (str): - Optional. The name of the OdbNetwork associated with the - Autonomous Database. Format: + Optional. Immutable. The name of the OdbNetwork associated + with the Autonomous Database. Format: projects/{project}/locations/{location}/odbNetworks/{odb_network} It is optional but if specified, this should match the parent ODBNetwork of the OdbSubnet. odb_subnet (str): - Optional. The name of the OdbSubnet associated with the - Autonomous Database. Format: + Optional. Immutable. The name of the OdbSubnet associated + with the Autonomous Database. Format: projects/{project}/locations/{location}/odbNetworks/{odb_network}/odbSubnets/{odb_subnet} source_config (google.cloud.oracledatabase_v1.types.SourceConfig): - Optional. The source Autonomous Database - configuration for the standby Autonomous - Database. The source Autonomous Database is - configured while creating the Peer Autonomous - Database and can't be updated after creation. + Optional. Immutable. The source Autonomous + Database configuration for the standby + Autonomous Database. The source Autonomous + Database is configured while creating the Peer + Autonomous Database and can't be updated after + creation. peer_autonomous_databases (MutableSequence[str]): Output only. The peer Autonomous Database names of the given Autonomous Database. @@ -306,6 +317,10 @@ class AutonomousDatabase(proto.Message): proto.STRING, number=6, ) + admin_password_secret_version: str = proto.Field( + proto.STRING, + number=18, + ) properties: "AutonomousDatabaseProperties" = proto.Field( proto.MESSAGE, number=7, @@ -386,68 +401,72 @@ class AutonomousDatabaseProperties(proto.Message): Output only. OCID of the Autonomous Database. https://docs.oracle.com/en-us/iaas/Content/General/Concepts/identifiers.htm#Oracle compute_count (float): - Optional. The number of compute servers for - the Autonomous Database. + Optional. Immutable. The number of compute + servers for the Autonomous Database. cpu_core_count (int): - Optional. The number of CPU cores to be made - available to the database. + Optional. Immutable. The number of CPU cores + to be made available to the database. data_storage_size_tb (int): - Optional. The size of the data stored in the - database, in terabytes. + Optional. Immutable. The size of the data + stored in the database, in terabytes. data_storage_size_gb (int): - Optional. The size of the data stored in the - database, in gigabytes. + Optional. Immutable. The size of the data + stored in the database, in gigabytes. db_workload (google.cloud.oracledatabase_v1.types.DBWorkload): - Required. The workload type of the Autonomous - Database. + Required. Immutable. The workload type of the + Autonomous Database. db_edition (google.cloud.oracledatabase_v1.types.AutonomousDatabaseProperties.DatabaseEdition): - Optional. The edition of the Autonomous - Databases. + Optional. Immutable. The edition of the + Autonomous Databases. character_set (str): - Optional. The character set for the - Autonomous Database. The default is AL32UTF8. + Optional. Immutable. The character set for + the Autonomous Database. The default is + AL32UTF8. n_character_set (str): - Optional. The national character set for the - Autonomous Database. The default is AL16UTF16. + Optional. Immutable. The national character + set for the Autonomous Database. The default is + AL16UTF16. private_endpoint_ip (str): - Optional. The private endpoint IP address for - the Autonomous Database. + Optional. Immutable. The private endpoint IP + address for the Autonomous Database. private_endpoint_label (str): - Optional. The private endpoint label for the - Autonomous Database. + Optional. Immutable. The private endpoint + label for the Autonomous Database. db_version (str): - Optional. The Oracle Database version for the - Autonomous Database. + Optional. Immutable. The Oracle Database + version for the Autonomous Database. is_auto_scaling_enabled (bool): - Optional. This field indicates if auto - scaling is enabled for the Autonomous Database - CPU core count. + Optional. Immutable. This field indicates if + auto scaling is enabled for the Autonomous + Database CPU core count. is_storage_auto_scaling_enabled (bool): - Optional. This field indicates if auto - scaling is enabled for the Autonomous Database - storage. + Optional. Immutable. This field indicates if + auto scaling is enabled for the Autonomous + Database storage. license_type (google.cloud.oracledatabase_v1.types.AutonomousDatabaseProperties.LicenseType): - Required. The license type used for the - Autonomous Database. + Required. Immutable. The license type used + for the Autonomous Database. customer_contacts (MutableSequence[google.cloud.oracledatabase_v1.types.CustomerContact]): - Optional. The list of customer contacts. + Optional. Immutable. The list of customer + contacts. secret_id (str): - Optional. The ID of the Oracle Cloud - Infrastructure vault secret. + Optional. Immutable. The ID of the Oracle + Cloud Infrastructure vault secret. vault_id (str): - Optional. The ID of the Oracle Cloud - Infrastructure vault. + Optional. Immutable. The ID of the Oracle + Cloud Infrastructure vault. maintenance_schedule_type (google.cloud.oracledatabase_v1.types.AutonomousDatabaseProperties.MaintenanceScheduleType): - Optional. The maintenance schedule of the - Autonomous Database. + Optional. Immutable. The maintenance schedule + of the Autonomous Database. mtls_connection_required (bool): - Optional. This field specifies if the - Autonomous Database requires mTLS connections. + Optional. Immutable. This field specifies if + the Autonomous Database requires mTLS + connections. backup_retention_period_days (int): - Optional. The retention period for the - Autonomous Database. This field is specified in - days, can range from 1 day to 60 days, and has a - default value of 60 days. + Optional. Immutable. The retention period for + the Autonomous Database. This field is specified + in days, can range from 1 day to 60 days, and + has a default value of 60 days. actual_used_data_storage_size_tb (float): Output only. The amount of storage currently being used for user and system data, in @@ -501,13 +520,15 @@ class AutonomousDatabaseProperties(proto.Message): Output only. The memory assigned to in-memory tables in an Autonomous Database. is_local_data_guard_enabled (bool): - Output only. This field indicates whether the - Autonomous Database has local (in-region) Data + Output only. Deprecated: Please use + ``local_data_guard_enabled`` instead. This field indicates + whether the Autonomous Database has local (in-region) Data Guard enabled. local_adg_auto_failover_max_data_loss_limit (int): - Output only. This field indicates the maximum - data loss limit for an Autonomous Database, in - seconds. + Output only. Deprecated: Please use + ``local_adg_auto_failover_max_data_loss_limit_duration`` + instead. This field indicates the maximum data loss limit + for an Autonomous Database, in seconds. local_standby_db (google.cloud.oracledatabase_v1.types.AutonomousDatabaseStandbySummary): Output only. The details of the Autonomous Data Guard standby database. @@ -588,8 +609,8 @@ class AutonomousDatabaseProperties(proto.Message): Output only. The date and time when maintenance will end. allowlisted_ips (MutableSequence[str]): - Optional. The list of allowlisted IP - addresses for the Autonomous Database. + Optional. Immutable. The list of allowlisted + IP addresses for the Autonomous Database. encryption_key (google.cloud.oracledatabase_v1.types.EncryptionKey): Optional. The encryption key used to encrypt the Autonomous Database. Updating this field will add a new entry in the @@ -603,6 +624,19 @@ class AutonomousDatabaseProperties(proto.Message): service account on which customers can grant roles to access resources in the customer project. + local_data_guard_enabled (bool): + Optional. Indicates whether the Autonomous + Database has a local (in-region) standby + database. Not applicable to cross-region Data + Guard or dedicated Exadata infrastructure. + + This field is a member of `oneof`_ ``_local_data_guard_enabled``. + local_adg_auto_failover_max_data_loss_limit_duration (int): + Optional. This field indicates the maximum + data loss limit for an Autonomous Database, in + seconds. + + This field is a member of `oneof`_ ``_local_adg_auto_failover_max_data_loss_limit_duration``. """ class DatabaseEdition(proto.Enum): @@ -668,11 +702,14 @@ class LocalDisasterRecoveryType(proto.Enum): Autonomous Data Guard recovery. BACKUP_BASED (2): Backup based recovery. + NOT_AVAILABLE (3): + Local disaster recovery is not available. """ LOCAL_DISASTER_RECOVERY_TYPE_UNSPECIFIED = 0 ADG = 1 BACKUP_BASED = 2 + NOT_AVAILABLE = 3 class DataSafeState(proto.Enum): r"""Varies states of the Data Safe registration for the @@ -1108,6 +1145,16 @@ class Role(proto.Enum): proto.STRING, number=70, ) + local_data_guard_enabled: bool = proto.Field( + proto.BOOL, + number=71, + optional=True, + ) + local_adg_auto_failover_max_data_loss_limit_duration: int = proto.Field( + proto.INT32, + number=72, + optional=True, + ) class EncryptionKeyHistoryEntry(proto.Message): diff --git a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/database.py b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/database.py index e44f36142087..613969432b3e 100644 --- a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/database.py +++ b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/database.py @@ -55,11 +55,27 @@ class Database(proto.Message): Optional. The DB_UNIQUE_NAME of the Oracle Database being backed up. admin_password (str): - Required. The password for the default ADMIN - user. + Optional. The password for the default ADMIN user. Note: + Only one of ``admin_password_secret_version`` or + ``admin_password`` can be populated. + admin_password_secret_version (str): + Optional. The resource name of a secret version in Secret + Manager which contains the database admin user's password. + Format: + projects/{project}/secrets/{secret}/versions/{version}. + Note: Only one of ``admin_password_secret_version`` or + ``admin_password`` can be populated. tde_wallet_password (str): - Optional. The TDE wallet password for the - database. + Optional. The TDE wallet password for the database. Note: + Only one of ``tde_wallet_password_secret_version`` or + ``tde_wallet_password`` can be populated. + tde_wallet_password_secret_version (str): + Optional. The resource name of a secret version in Secret + Manager which contains the TDE wallet password for the + database. Format: + projects/{project}/secrets/{secret}/versions/{version}. + Note: Only one of ``tde_wallet_password_secret_version`` or + ``tde_wallet_password`` can be populated. character_set (str): Optional. The character set for the database. The default is AL32UTF8. @@ -85,6 +101,15 @@ class Database(proto.Message): ops_insights_status (google.cloud.oracledatabase_v1.types.Database.OperationsInsightsStatus): Output only. The Status of Operations Insights for this Database. + pluggable_database_id (str): + Optional. The ID of the pluggable database + associated with the Database. The ID must be + unique within the project and location. + pluggable_database_name (str): + Optional. The pluggable database associated + with the Database. The name must begin with an + alphabetic character and can contain a maximum + of thirty alphanumeric characters. """ class OperationsInsightsStatus(proto.Enum): @@ -137,10 +162,18 @@ class OperationsInsightsStatus(proto.Enum): proto.STRING, number=4, ) + admin_password_secret_version: str = proto.Field( + proto.STRING, + number=17, + ) tde_wallet_password: str = proto.Field( proto.STRING, number=5, ) + tde_wallet_password_secret_version: str = proto.Field( + proto.STRING, + number=18, + ) character_set: str = proto.Field( proto.STRING, number=6, @@ -180,6 +213,14 @@ class OperationsInsightsStatus(proto.Enum): number=14, enum=OperationsInsightsStatus, ) + pluggable_database_id: str = proto.Field( + proto.STRING, + number=15, + ) + pluggable_database_name: str = proto.Field( + proto.STRING, + number=16, + ) class DatabaseProperties(proto.Message): diff --git a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/db_system.py b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/db_system.py index f6d8e28caa96..3b2f64da9edc 100644 --- a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/db_system.py +++ b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/db_system.py @@ -418,7 +418,8 @@ class StorageManagement(proto.Enum): STORAGE_MANAGEMENT_UNSPECIFIED (0): The storage management is unspecified. ASM (1): - Automatic storage management. + Automatic storage management. This option is + not supported. Only LVM is supported. LVM (2): Logical Volume management. """ @@ -630,6 +631,10 @@ class ListDbSystemsResponse(proto.Message): next_page_token (str): A token identifying a page of results the server should return. + unreachable (MutableSequence[str]): + Unreachable locations when listing resources + across all locations using wildcard location + '-'. """ @property @@ -645,6 +650,10 @@ def raw_page(self): proto.STRING, number=2, ) + unreachable: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/exascale_db_storage_vault.py b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/exascale_db_storage_vault.py index 9b541e025f23..653a53faabf5 100644 --- a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/exascale_db_storage_vault.py +++ b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/exascale_db_storage_vault.py @@ -346,6 +346,10 @@ class ListExascaleDbStorageVaultsResponse(proto.Message): token can be provided to a subsequent ListExascaleDbStorageVaults call to list the next page. If empty, there are no more pages. + unreachable (MutableSequence[str]): + Unreachable locations when listing resources + across all locations using wildcard location + '-'. """ @property @@ -363,6 +367,10 @@ def raw_page(self): proto.STRING, number=2, ) + unreachable: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) class CreateExascaleDbStorageVaultRequest(proto.Message): diff --git a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/goldengate_connection.py b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/goldengate_connection.py new file mode 100644 index 000000000000..1edfde9df848 --- /dev/null +++ b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/goldengate_connection.py @@ -0,0 +1,4128 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.oracledatabase.v1", + manifest={ + "GoldengateConnection", + "GoldengateConnectionProperties", + "GoldengateOracleConnectionProperties", + "GoldengateGoldengateConnectionProperties", + "GoldengateGenericConnectionProperties", + "GoldengateGoogleCloudStorageConnectionProperties", + "GoldengateGoogleBigQueryConnectionProperties", + "GoldengateMysqlConnectionProperties", + "GoldengateKafkaConnectionProperties", + "GoldengateKafkaSchemaRegistryConnectionProperties", + "GoldengateOciObjectStorageConnectionProperties", + "GoldengateAzureDataLakeStorageConnectionProperties", + "GoldengateAzureSynapseAnalyticsConnectionProperties", + "GoldengatePostgresqlConnectionProperties", + "GoldengateMicrosoftSqlserverConnectionProperties", + "GoldengateAmazonS3ConnectionProperties", + "GoldengateHdfsConnectionProperties", + "GoldengateJavaMessageServiceConnectionProperties", + "GoldengateMongodbConnectionProperties", + "GoldengateOracleNosqlConnectionProperties", + "GoldengateSnowflakeConnectionProperties", + "GoldengateAmazonRedshiftConnectionProperties", + "GoldengateElasticsearchConnectionProperties", + "GoldengateAmazonKinesisConnectionProperties", + "GoldengateDb2ConnectionProperties", + "GoldengateRedisConnectionProperties", + "GoldengateDatabricksConnectionProperties", + "GoldengateGooglePubsubConnectionProperties", + "GoldengateMicrosoftFabricConnectionProperties", + "GoldengateOracleAIDataPlatformConnectionProperties", + "GlueIcebergCatalog", + "NessieIcebergCatalog", + "PolarisIcebergCatalog", + "RestIcebergCatalog", + "IcebergCatalog", + "AmazonS3IcebergStorage", + "GoogleCloudStorageIcebergStorage", + "AzureDataLakeStorageIcebergStorage", + "IcebergStorage", + "GoldengateIcebergConnectionProperties", + "CreateGoldengateConnectionRequest", + "DeleteGoldengateConnectionRequest", + "GetGoldengateConnectionRequest", + "ListGoldengateConnectionsRequest", + "ListGoldengateConnectionsResponse", + "NameValuePair", + "KafkaBootstrapServer", + }, +) + + +class GoldengateConnection(proto.Message): + r"""Details of the GoldengateConnection resource. + + Attributes: + name (str): + Identifier. The name of the GoldengateConnection resource in + the following format: + projects/{project}/locations/{region}/goldengateConnections/{goldengate_connection} + properties (google.cloud.oracledatabase_v1.types.GoldengateConnectionProperties): + Required. The properties of the + GoldengateConnection. + gcp_oracle_zone (str): + Optional. The GCP Oracle zone where Oracle + GoldengateConnection is hosted. Example: + us-east4-b-r2. If not specified, the system will + pick a zone based on availability. + labels (MutableMapping[str, str]): + Optional. The labels or tags associated with + the GoldengateConnection. + odb_network (str): + Optional. The name of the OdbNetwork associated with the + GoldengateConnection. The format is + projects/{project}/locations/{location}/odbNetworks/{odb_network}. + It is optional but if specified, this should match the + parent ODBNetwork of the OdbSubnet. + odb_subnet (str): + Optional. The name of the OdbSubnet associated with the + GoldengateConnection for IP allocation. Format: + projects/{project}/locations/{location}/odbNetworks/{odb_network}/odbSubnets/{odb_subnet} + entitlement_id (str): + Output only. The ID of the subscription + entitlement associated with the + GoldengateConnection. + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The date and time that the + GoldengateConnection was created. + oci_url (str): + Output only. HTTPS link to OCI resources + exposed to Customer via UI Interface. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + properties: "GoldengateConnectionProperties" = proto.Field( + proto.MESSAGE, + number=2, + message="GoldengateConnectionProperties", + ) + gcp_oracle_zone: str = proto.Field( + proto.STRING, + number=3, + ) + labels: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=4, + ) + odb_network: str = proto.Field( + proto.STRING, + number=5, + ) + odb_subnet: str = proto.Field( + proto.STRING, + number=6, + ) + entitlement_id: str = proto.Field( + proto.STRING, + number=7, + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=8, + message=timestamp_pb2.Timestamp, + ) + oci_url: str = proto.Field( + proto.STRING, + number=9, + ) + + +class GoldengateConnectionProperties(proto.Message): + r"""The properties of a GoldengateConnection. + + 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: + oracle_connection_properties (google.cloud.oracledatabase_v1.types.GoldengateOracleConnectionProperties): + Properties for an Oracle Database Connection. + + This field is a member of `oneof`_ ``connection_details``. + goldengate_connection_properties (google.cloud.oracledatabase_v1.types.GoldengateGoldengateConnectionProperties): + Properties for a Goldengate Connection. + + This field is a member of `oneof`_ ``connection_details``. + generic_connection_properties (google.cloud.oracledatabase_v1.types.GoldengateGenericConnectionProperties): + Properties for a Generic Connection. + + This field is a member of `oneof`_ ``connection_details``. + google_cloud_storage_connection_properties (google.cloud.oracledatabase_v1.types.GoldengateGoogleCloudStorageConnectionProperties): + Properties for a Google Cloud Storage + Connection. + + This field is a member of `oneof`_ ``connection_details``. + google_big_query_connection_properties (google.cloud.oracledatabase_v1.types.GoldengateGoogleBigQueryConnectionProperties): + Properties for a Google BigQuery Connection. + + This field is a member of `oneof`_ ``connection_details``. + mysql_connection_properties (google.cloud.oracledatabase_v1.types.GoldengateMysqlConnectionProperties): + Properties for a Mysql Connection. + + This field is a member of `oneof`_ ``connection_details``. + kafka_connection_properties (google.cloud.oracledatabase_v1.types.GoldengateKafkaConnectionProperties): + Properties for a Kafka Connection. + + This field is a member of `oneof`_ ``connection_details``. + kafka_schema_registry_connection_properties (google.cloud.oracledatabase_v1.types.GoldengateKafkaSchemaRegistryConnectionProperties): + Properties for a Kafka Schema Registry + Connection. + + This field is a member of `oneof`_ ``connection_details``. + oci_object_storage_connection_properties (google.cloud.oracledatabase_v1.types.GoldengateOciObjectStorageConnectionProperties): + Properties for an OCI Object Storage + Connection. + + This field is a member of `oneof`_ ``connection_details``. + azure_data_lake_storage_connection_properties (google.cloud.oracledatabase_v1.types.GoldengateAzureDataLakeStorageConnectionProperties): + Properties for an Azure Data Lake Storage + Connection. + + This field is a member of `oneof`_ ``connection_details``. + azure_synapse_analytics_connection_properties (google.cloud.oracledatabase_v1.types.GoldengateAzureSynapseAnalyticsConnectionProperties): + Properties for an Azure Synapse Analytics + connection. + + This field is a member of `oneof`_ ``connection_details``. + postgresql_connection_properties (google.cloud.oracledatabase_v1.types.GoldengatePostgresqlConnectionProperties): + Properties for a PostgreSQL connection. + + This field is a member of `oneof`_ ``connection_details``. + microsoft_sqlserver_connection_properties (google.cloud.oracledatabase_v1.types.GoldengateMicrosoftSqlserverConnectionProperties): + Properties for a Microsoft SQL Server + connection. + + This field is a member of `oneof`_ ``connection_details``. + amazon_s3_connection_properties (google.cloud.oracledatabase_v1.types.GoldengateAmazonS3ConnectionProperties): + Properties for an Amazon S3 connection. + + This field is a member of `oneof`_ ``connection_details``. + hdfs_connection_properties (google.cloud.oracledatabase_v1.types.GoldengateHdfsConnectionProperties): + Properties for an HDFS connection. + + This field is a member of `oneof`_ ``connection_details``. + java_message_service_connection_properties (google.cloud.oracledatabase_v1.types.GoldengateJavaMessageServiceConnectionProperties): + Properties for a Java Message Service + connection. + + This field is a member of `oneof`_ ``connection_details``. + mongodb_connection_properties (google.cloud.oracledatabase_v1.types.GoldengateMongodbConnectionProperties): + Properties for a MongoDB connection. + + This field is a member of `oneof`_ ``connection_details``. + oracle_nosql_connection_properties (google.cloud.oracledatabase_v1.types.GoldengateOracleNosqlConnectionProperties): + Properties for an Oracle NoSQL connection. + + This field is a member of `oneof`_ ``connection_details``. + snowflake_connection_properties (google.cloud.oracledatabase_v1.types.GoldengateSnowflakeConnectionProperties): + Properties for a Snowflake connection. + + This field is a member of `oneof`_ ``connection_details``. + amazon_redshift_connection_properties (google.cloud.oracledatabase_v1.types.GoldengateAmazonRedshiftConnectionProperties): + Properties for an Amazon Redshift connection. + + This field is a member of `oneof`_ ``connection_details``. + elasticsearch_connection_properties (google.cloud.oracledatabase_v1.types.GoldengateElasticsearchConnectionProperties): + Properties for an Elasticsearch connection. + + This field is a member of `oneof`_ ``connection_details``. + amazon_kinesis_connection_properties (google.cloud.oracledatabase_v1.types.GoldengateAmazonKinesisConnectionProperties): + Properties for an Amazon Kinesis connection. + + This field is a member of `oneof`_ ``connection_details``. + db2_connection_properties (google.cloud.oracledatabase_v1.types.GoldengateDb2ConnectionProperties): + Properties for a DB2 connection. + + This field is a member of `oneof`_ ``connection_details``. + redis_connection_properties (google.cloud.oracledatabase_v1.types.GoldengateRedisConnectionProperties): + Properties for a Redis connection. + + This field is a member of `oneof`_ ``connection_details``. + databricks_connection_properties (google.cloud.oracledatabase_v1.types.GoldengateDatabricksConnectionProperties): + Properties for a Databricks connection. + + This field is a member of `oneof`_ ``connection_details``. + google_pubsub_connection_properties (google.cloud.oracledatabase_v1.types.GoldengateGooglePubsubConnectionProperties): + Properties for a Google Pub/Sub connection. + + This field is a member of `oneof`_ ``connection_details``. + microsoft_fabric_connection_properties (google.cloud.oracledatabase_v1.types.GoldengateMicrosoftFabricConnectionProperties): + Properties for a Microsoft Fabric connection. + + This field is a member of `oneof`_ ``connection_details``. + oracle_ai_data_platform_connection_properties (google.cloud.oracledatabase_v1.types.GoldengateOracleAIDataPlatformConnectionProperties): + Properties for an Oracle AI Data Platform + connection. + + This field is a member of `oneof`_ ``connection_details``. + iceberg_connection_properties (google.cloud.oracledatabase_v1.types.GoldengateIcebergConnectionProperties): + Properties for an Iceberg connection. + + This field is a member of `oneof`_ ``connection_details``. + connection_type (google.cloud.oracledatabase_v1.types.GoldengateConnectionProperties.GoldengateConnectionType): + Required. The connection type. + ocid (str): + Output only. The [OCID] of the connection being referenced. + display_name (str): + Required. An object's Display Name. + description (str): + Optional. Metadata about this specific + object. + lifecycle_state (google.cloud.oracledatabase_v1.types.GoldengateConnectionProperties.GoldengateConnectionLifecycleState): + Output only. The lifecycle state of the + connection. + lifecycle_details (str): + Output only. Describes the object's current + state in detail. For example, it can be used to + provide actionable information for a resource in + a Failed state. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time the resource was last + updated. + routing_method (google.cloud.oracledatabase_v1.types.GoldengateConnectionProperties.GoldengateConnectionRoutingMethod): + Optional. The routing method for the + GoldengateConnection. + ingress_ip_addresses (MutableSequence[str]): + Output only. The Ingress IPs of the + GoldengateConnection. + """ + + class GoldengateConnectionType(proto.Enum): + r"""Enum for Connection type. + + Values: + GOLDENGATE_CONNECTION_TYPE_UNSPECIFIED (0): + Connection type unspecified. + GOLDENGATE (1): + Goldengate connection type. + KAFKA (2): + Kafka connection type. + KAFKA_SCHEMA_REGISTRY (3): + Kafka schema registry connection type. + MYSQL (4): + MySQL connection type. + JAVA_MESSAGE_SERVICE (5): + Java message service connection type. + MICROSOFT_SQLSERVER (6): + Microsoft SQL Server connection type. + OCI_OBJECT_STORAGE (7): + OCI object storage connection type. + ORACLE (8): + Oracle connection type. + AZURE_DATA_LAKE_STORAGE (9): + Azure data lake storage connection type. + POSTGRESQL (10): + PostgreSQL connection type. + AZURE_SYNAPSE_ANALYTICS (11): + Azure synapse analytics connection type. + SNOWFLAKE (12): + Snowflake connection type. + AMAZON_S3 (13): + Amazon S3 connection type. + HDFS (14): + HDFS connection type. + ORACLE_AI_DATA_PLATFORM (15): + Oracle AI data platform connection type. + ORACLE_NOSQL (16): + Oracle NoSQL connection type. + MONGODB (17): + MongoDB connection type. + AMAZON_KINESIS (18): + Amazon Kinesis connection type. + AMAZON_REDSHIFT (19): + Amazon Redshift connection type. + DB2 (20): + DB2 connection type. + REDIS (21): + Redis connection type. + ELASTICSEARCH (22): + Elasticsearch connection type. + GENERIC (23): + Generic connection type. + GOOGLE_CLOUD_STORAGE (24): + Google Cloud Storage connection type. + GOOGLE_BIGQUERY (25): + Google BigQuery connection type. + DATABRICKS (26): + Databricks connection type. + GOOGLE_PUBSUB (27): + Google Pub/Sub connection type. + MICROSOFT_FABRIC (28): + Microsoft Fabric connection type. + ICEBERG (29): + Iceberg connection type. + """ + + GOLDENGATE_CONNECTION_TYPE_UNSPECIFIED = 0 + GOLDENGATE = 1 + KAFKA = 2 + KAFKA_SCHEMA_REGISTRY = 3 + MYSQL = 4 + JAVA_MESSAGE_SERVICE = 5 + MICROSOFT_SQLSERVER = 6 + OCI_OBJECT_STORAGE = 7 + ORACLE = 8 + AZURE_DATA_LAKE_STORAGE = 9 + POSTGRESQL = 10 + AZURE_SYNAPSE_ANALYTICS = 11 + SNOWFLAKE = 12 + AMAZON_S3 = 13 + HDFS = 14 + ORACLE_AI_DATA_PLATFORM = 15 + ORACLE_NOSQL = 16 + MONGODB = 17 + AMAZON_KINESIS = 18 + AMAZON_REDSHIFT = 19 + DB2 = 20 + REDIS = 21 + ELASTICSEARCH = 22 + GENERIC = 23 + GOOGLE_CLOUD_STORAGE = 24 + GOOGLE_BIGQUERY = 25 + DATABRICKS = 26 + GOOGLE_PUBSUB = 27 + MICROSOFT_FABRIC = 28 + ICEBERG = 29 + + class GoldengateConnectionLifecycleState(proto.Enum): + r"""Possible lifecycle states for connection. + + Values: + GOLDENGATE_CONNECTION_LIFECYCLE_STATE_UNSPECIFIED (0): + Default unspecified value. + CREATING (1): + Indicates that the resource is in + provisioning state. + ACTIVE (2): + Indicates that the resource is in active + state. + UPDATING (3): + Indicates that the resource is in updating + state. + DELETING (4): + Indicates that the resource is in deleting + state. + DELETED (5): + Indicates that the resource is in deleted + state. + FAILED (6): + Indicates that the resource is in failed + state. + """ + + GOLDENGATE_CONNECTION_LIFECYCLE_STATE_UNSPECIFIED = 0 + CREATING = 1 + ACTIVE = 2 + UPDATING = 3 + DELETING = 4 + DELETED = 5 + FAILED = 6 + + class GoldengateConnectionRoutingMethod(proto.Enum): + r"""The various routing methods of the GoldengateConnection. + + Values: + GOLDENGATE_CONNECTION_ROUTING_METHOD_UNSPECIFIED (0): + Default unspecified value. + SHARED_DEPLOYMENT_ENDPOINT (1): + Network traffic flows from the assigned + deployment's private endpoint through the + deployment's subnet. + DEDICATED_ENDPOINT (2): + A dedicated private endpoint is created in + the target VCN subnet for the connection. + """ + + GOLDENGATE_CONNECTION_ROUTING_METHOD_UNSPECIFIED = 0 + SHARED_DEPLOYMENT_ENDPOINT = 1 + DEDICATED_ENDPOINT = 2 + + oracle_connection_properties: "GoldengateOracleConnectionProperties" = proto.Field( + proto.MESSAGE, + number=9, + oneof="connection_details", + message="GoldengateOracleConnectionProperties", + ) + goldengate_connection_properties: "GoldengateGoldengateConnectionProperties" = ( + proto.Field( + proto.MESSAGE, + number=10, + oneof="connection_details", + message="GoldengateGoldengateConnectionProperties", + ) + ) + generic_connection_properties: "GoldengateGenericConnectionProperties" = ( + proto.Field( + proto.MESSAGE, + number=11, + oneof="connection_details", + message="GoldengateGenericConnectionProperties", + ) + ) + google_cloud_storage_connection_properties: "GoldengateGoogleCloudStorageConnectionProperties" = proto.Field( + proto.MESSAGE, + number=12, + oneof="connection_details", + message="GoldengateGoogleCloudStorageConnectionProperties", + ) + google_big_query_connection_properties: "GoldengateGoogleBigQueryConnectionProperties" = proto.Field( + proto.MESSAGE, + number=13, + oneof="connection_details", + message="GoldengateGoogleBigQueryConnectionProperties", + ) + mysql_connection_properties: "GoldengateMysqlConnectionProperties" = proto.Field( + proto.MESSAGE, + number=14, + oneof="connection_details", + message="GoldengateMysqlConnectionProperties", + ) + kafka_connection_properties: "GoldengateKafkaConnectionProperties" = proto.Field( + proto.MESSAGE, + number=15, + oneof="connection_details", + message="GoldengateKafkaConnectionProperties", + ) + kafka_schema_registry_connection_properties: "GoldengateKafkaSchemaRegistryConnectionProperties" = proto.Field( + proto.MESSAGE, + number=16, + oneof="connection_details", + message="GoldengateKafkaSchemaRegistryConnectionProperties", + ) + oci_object_storage_connection_properties: "GoldengateOciObjectStorageConnectionProperties" = proto.Field( + proto.MESSAGE, + number=17, + oneof="connection_details", + message="GoldengateOciObjectStorageConnectionProperties", + ) + azure_data_lake_storage_connection_properties: "GoldengateAzureDataLakeStorageConnectionProperties" = proto.Field( + proto.MESSAGE, + number=18, + oneof="connection_details", + message="GoldengateAzureDataLakeStorageConnectionProperties", + ) + azure_synapse_analytics_connection_properties: "GoldengateAzureSynapseAnalyticsConnectionProperties" = proto.Field( + proto.MESSAGE, + number=19, + oneof="connection_details", + message="GoldengateAzureSynapseAnalyticsConnectionProperties", + ) + postgresql_connection_properties: "GoldengatePostgresqlConnectionProperties" = ( + proto.Field( + proto.MESSAGE, + number=20, + oneof="connection_details", + message="GoldengatePostgresqlConnectionProperties", + ) + ) + microsoft_sqlserver_connection_properties: "GoldengateMicrosoftSqlserverConnectionProperties" = proto.Field( + proto.MESSAGE, + number=21, + oneof="connection_details", + message="GoldengateMicrosoftSqlserverConnectionProperties", + ) + amazon_s3_connection_properties: "GoldengateAmazonS3ConnectionProperties" = ( + proto.Field( + proto.MESSAGE, + number=22, + oneof="connection_details", + message="GoldengateAmazonS3ConnectionProperties", + ) + ) + hdfs_connection_properties: "GoldengateHdfsConnectionProperties" = proto.Field( + proto.MESSAGE, + number=23, + oneof="connection_details", + message="GoldengateHdfsConnectionProperties", + ) + java_message_service_connection_properties: "GoldengateJavaMessageServiceConnectionProperties" = proto.Field( + proto.MESSAGE, + number=24, + oneof="connection_details", + message="GoldengateJavaMessageServiceConnectionProperties", + ) + mongodb_connection_properties: "GoldengateMongodbConnectionProperties" = ( + proto.Field( + proto.MESSAGE, + number=25, + oneof="connection_details", + message="GoldengateMongodbConnectionProperties", + ) + ) + oracle_nosql_connection_properties: "GoldengateOracleNosqlConnectionProperties" = ( + proto.Field( + proto.MESSAGE, + number=26, + oneof="connection_details", + message="GoldengateOracleNosqlConnectionProperties", + ) + ) + snowflake_connection_properties: "GoldengateSnowflakeConnectionProperties" = ( + proto.Field( + proto.MESSAGE, + number=27, + oneof="connection_details", + message="GoldengateSnowflakeConnectionProperties", + ) + ) + amazon_redshift_connection_properties: "GoldengateAmazonRedshiftConnectionProperties" = proto.Field( + proto.MESSAGE, + number=28, + oneof="connection_details", + message="GoldengateAmazonRedshiftConnectionProperties", + ) + elasticsearch_connection_properties: "GoldengateElasticsearchConnectionProperties" = proto.Field( + proto.MESSAGE, + number=29, + oneof="connection_details", + message="GoldengateElasticsearchConnectionProperties", + ) + amazon_kinesis_connection_properties: "GoldengateAmazonKinesisConnectionProperties" = proto.Field( + proto.MESSAGE, + number=31, + oneof="connection_details", + message="GoldengateAmazonKinesisConnectionProperties", + ) + db2_connection_properties: "GoldengateDb2ConnectionProperties" = proto.Field( + proto.MESSAGE, + number=32, + oneof="connection_details", + message="GoldengateDb2ConnectionProperties", + ) + redis_connection_properties: "GoldengateRedisConnectionProperties" = proto.Field( + proto.MESSAGE, + number=33, + oneof="connection_details", + message="GoldengateRedisConnectionProperties", + ) + databricks_connection_properties: "GoldengateDatabricksConnectionProperties" = ( + proto.Field( + proto.MESSAGE, + number=34, + oneof="connection_details", + message="GoldengateDatabricksConnectionProperties", + ) + ) + google_pubsub_connection_properties: "GoldengateGooglePubsubConnectionProperties" = proto.Field( + proto.MESSAGE, + number=35, + oneof="connection_details", + message="GoldengateGooglePubsubConnectionProperties", + ) + microsoft_fabric_connection_properties: "GoldengateMicrosoftFabricConnectionProperties" = proto.Field( + proto.MESSAGE, + number=36, + oneof="connection_details", + message="GoldengateMicrosoftFabricConnectionProperties", + ) + oracle_ai_data_platform_connection_properties: "GoldengateOracleAIDataPlatformConnectionProperties" = proto.Field( + proto.MESSAGE, + number=37, + oneof="connection_details", + message="GoldengateOracleAIDataPlatformConnectionProperties", + ) + iceberg_connection_properties: "GoldengateIcebergConnectionProperties" = ( + proto.Field( + proto.MESSAGE, + number=38, + oneof="connection_details", + message="GoldengateIcebergConnectionProperties", + ) + ) + connection_type: GoldengateConnectionType = proto.Field( + proto.ENUM, + number=1, + enum=GoldengateConnectionType, + ) + ocid: str = proto.Field( + proto.STRING, + number=2, + ) + display_name: str = proto.Field( + proto.STRING, + number=3, + ) + description: str = proto.Field( + proto.STRING, + number=4, + ) + lifecycle_state: GoldengateConnectionLifecycleState = proto.Field( + proto.ENUM, + number=5, + enum=GoldengateConnectionLifecycleState, + ) + lifecycle_details: str = proto.Field( + proto.STRING, + number=6, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=7, + message=timestamp_pb2.Timestamp, + ) + routing_method: GoldengateConnectionRoutingMethod = proto.Field( + proto.ENUM, + number=8, + enum=GoldengateConnectionRoutingMethod, + ) + ingress_ip_addresses: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=39, + ) + + +class GoldengateOracleConnectionProperties(proto.Message): + r"""The properties of Goldengate Oracle Database Connection. + + 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: + password (str): + Optional. Input only. The password Oracle + Goldengate uses in plain text. + + This field is a member of `oneof`_ ``connection_password_options``. + password_secret_version (str): + Optional. Input only. The resource name of a + secret version in Secret Manager which contains + the password Oracle Goldengate uses. Format: + + projects/{project}/secrets/{secret}/versions/{version}. + + This field is a member of `oneof`_ ``connection_password_options``. + technology_type (str): + Optional. The technology type. + username (str): + Optional. The username Oracle Goldengate uses + to connect. + authentication_mode (google.cloud.oracledatabase_v1.types.GoldengateOracleConnectionProperties.OracleAuthenticationMode): + Optional. Authentication mode. + connection_string (str): + Optional. Connect descriptor or Easy Connect + Naming method used to connect to a database. + session_mode (google.cloud.oracledatabase_v1.types.GoldengateOracleConnectionProperties.SessionMode): + Optional. The mode of the database connection + session to be established by the data client. + gcp_oracle_database_id (str): + Optional. Autonomous AI Database instance id of database in + Oracle Database @ Google Cloud. If gcp_oracle_database_id is + provided, connection_string must be empty. Format: + projects/{project}/locations/{location}/autonomousDatabases/{autonomous_database} + wallet_file (str): + Optional. The wallet contents Oracle + Goldengate uses to make connections to a + database. This attribute is expected to be + base64 encoded. + """ + + class OracleAuthenticationMode(proto.Enum): + r"""Enum for Authentication mode. + + Values: + ORACLE_AUTHENTICATION_MODE_UNSPECIFIED (0): + Authentication mode not specified. + TLS (1): + TLS authentication mode. + MTLS (2): + MTLS authentication mode. + """ + + ORACLE_AUTHENTICATION_MODE_UNSPECIFIED = 0 + TLS = 1 + MTLS = 2 + + class SessionMode(proto.Enum): + r"""The various session modes of the GoldengateConnection. + + Values: + SESSION_MODE_UNSPECIFIED (0): + Default unspecified value. + DIRECT (1): + Indicates that the resource is using direct + session mode. + REDIRECT (2): + Indicates that the resource is using redirect + session mode. + """ + + SESSION_MODE_UNSPECIFIED = 0 + DIRECT = 1 + REDIRECT = 2 + + password: str = proto.Field( + proto.STRING, + number=10, + oneof="connection_password_options", + ) + password_secret_version: str = proto.Field( + proto.STRING, + number=11, + oneof="connection_password_options", + ) + technology_type: str = proto.Field( + proto.STRING, + number=1, + ) + username: str = proto.Field( + proto.STRING, + number=2, + ) + authentication_mode: OracleAuthenticationMode = proto.Field( + proto.ENUM, + number=3, + enum=OracleAuthenticationMode, + ) + connection_string: str = proto.Field( + proto.STRING, + number=4, + ) + session_mode: SessionMode = proto.Field( + proto.ENUM, + number=5, + enum=SessionMode, + ) + gcp_oracle_database_id: str = proto.Field( + proto.STRING, + number=6, + ) + wallet_file: str = proto.Field( + proto.STRING, + number=9, + ) + + +class GoldengateGoldengateConnectionProperties(proto.Message): + r"""The properties of GoldengateGoldengateConnectionProperties. + + 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: + password (str): + Optional. Input only. The password used to + connect to the Oracle Goldengate in plain text. + + This field is a member of `oneof`_ ``connection_password_options``. + password_secret_version (str): + Optional. Input only. The resource name of a + secret version in Secret Manager which contains + the password used to connect to the Oracle + Goldengate. Format: + + projects/{project}/secrets/{secret}/versions/{version}. + + This field is a member of `oneof`_ ``connection_password_options``. + technology_type (str): + Optional. The technology type. + goldengate_deployment_id (str): + Optional. The name of the GoldengateDeployment associated + with the GoldengateConnection. Format: + projects/{project}/locations/{location}/goldengateDeployments/{goldengate_deployment} + host (str): + Optional. The host of the + GoldengateConnection. + port (int): + Optional. The port of the + GoldengateConnection. + username (str): + Optional. The username credential. + """ + + password: str = proto.Field( + proto.STRING, + number=7, + oneof="connection_password_options", + ) + password_secret_version: str = proto.Field( + proto.STRING, + number=8, + oneof="connection_password_options", + ) + technology_type: str = proto.Field( + proto.STRING, + number=1, + ) + goldengate_deployment_id: str = proto.Field( + proto.STRING, + number=2, + ) + host: str = proto.Field( + proto.STRING, + number=3, + ) + port: int = proto.Field( + proto.INT32, + number=4, + ) + username: str = proto.Field( + proto.STRING, + number=5, + ) + + +class GoldengateGenericConnectionProperties(proto.Message): + r"""The properties of GoldengateGenericConnectionProperties. + + Attributes: + technology_type (str): + Optional. The technology type. + host (str): + Optional. The host of the GenericConnection. + """ + + technology_type: str = proto.Field( + proto.STRING, + number=1, + ) + host: str = proto.Field( + proto.STRING, + number=2, + ) + + +class GoldengateGoogleCloudStorageConnectionProperties(proto.Message): + r"""The properties of + GoldengateGoogleCloudStorageConnectionProperties. + + Attributes: + technology_type (str): + Optional. The technology type. + service_account_key_file (str): + Optional. The base64 encoded content of the + service account key file containing the + credentials required to use Google Cloud + Storage. + """ + + technology_type: str = proto.Field( + proto.STRING, + number=1, + ) + service_account_key_file: str = proto.Field( + proto.STRING, + number=3, + ) + + +class GoldengateGoogleBigQueryConnectionProperties(proto.Message): + r"""The properties of + GoldengateGoogleBigQueryConnectionProperties. + + Attributes: + technology_type (str): + Optional. The technology type. + service_account_key_file (str): + Optional. The base64 encoded content of the + service account key file containing the + credentials required to use Google BigQuery. + """ + + technology_type: str = proto.Field( + proto.STRING, + number=1, + ) + service_account_key_file: str = proto.Field( + proto.STRING, + number=3, + ) + + +class GoldengateMysqlConnectionProperties(proto.Message): + r"""Properties of GoldengateMysqlConnection. + + 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: + password (str): + Optional. Input only. The password Oracle + Goldengate uses to connect to MySQL in plain + text. + + This field is a member of `oneof`_ ``connection_password_options``. + password_secret_version (str): + Optional. Input only. The resource name of a + secret version in Secret Manager which contains + the password Oracle Goldengate uses to connect + to MySQL. Format: + projects/{project}/secrets/{secret}/versions/{version}. + + This field is a member of `oneof`_ ``connection_password_options``. + technology_type (str): + Optional. The technology type of + MysqlConnection. + username (str): + Optional. The username Oracle Goldengate uses + to connect the associated system of the given + technology. + host (str): + Optional. The name or address of a host. + port (int): + Optional. The port of an endpoint usually + specified for a connection. + database (str): + Optional. The name of the database. + security_protocol (google.cloud.oracledatabase_v1.types.GoldengateMysqlConnectionProperties.MysqlSecurityProtocol): + Optional. Security Type for MySQL. + ssl_mode (google.cloud.oracledatabase_v1.types.GoldengateMysqlConnectionProperties.SSLMode): + Optional. SSL modes for MySQL. + ssl_ca_file (str): + Optional. Database Certificate - The base64 + encoded content of a .pem or .crt file + containing the server public key (for 1 and + 2-way SSL). + ssl_crl_file (str): + Optional. The base64 encoded list of + certificates revoked by the trusted certificate + authorities (Trusted CA). + ssl_cert_file (str): + Optional. Client Certificate - The base64 + encoded content of a .pem or .crt file + containing the client public key (for 2-way + SSL). + ssl_key_file (str): + Optional. Client Key - The base64 encoded + content of a .pem or .crt file containing the + client private key (for 2-way SSL). + additional_attributes (MutableSequence[google.cloud.oracledatabase_v1.types.NameValuePair]): + Optional. An array of name-value pair + attribute entries. Used as additional parameters + in connection string. + db_system_id (str): + Optional. The OCID of the database system + being referenced. + """ + + class MysqlSecurityProtocol(proto.Enum): + r"""Enum for Security Type for MySQL. + + Values: + MYSQL_SECURITY_PROTOCOL_UNSPECIFIED (0): + Security type not specified. + PLAIN (1): + Plain text communication. + TLS (2): + Transport Layer Security. + MTLS (3): + Mutual Transport Layer Security. + """ + + MYSQL_SECURITY_PROTOCOL_UNSPECIFIED = 0 + PLAIN = 1 + TLS = 2 + MTLS = 3 + + class SSLMode(proto.Enum): + r"""Enum for SSL modes for MySQL. + + Values: + SSL_MODE_UNSPECIFIED (0): + SSL mode not specified. + DISABLED (1): + SSL is disabled. + PREFERRED (2): + SSL is preferred. + REQUIRED (3): + SSL is required. + VERIFY_CA (4): + SSL is required and certificate is verified. + VERIFY_IDENTITY (5): + SSL is required and certificate and hostname + are verified. + """ + + SSL_MODE_UNSPECIFIED = 0 + DISABLED = 1 + PREFERRED = 2 + REQUIRED = 3 + VERIFY_CA = 4 + VERIFY_IDENTITY = 5 + + password: str = proto.Field( + proto.STRING, + number=15, + oneof="connection_password_options", + ) + password_secret_version: str = proto.Field( + proto.STRING, + number=16, + oneof="connection_password_options", + ) + technology_type: str = proto.Field( + proto.STRING, + number=1, + ) + username: str = proto.Field( + proto.STRING, + number=2, + ) + host: str = proto.Field( + proto.STRING, + number=4, + ) + port: int = proto.Field( + proto.INT32, + number=5, + ) + database: str = proto.Field( + proto.STRING, + number=6, + ) + security_protocol: MysqlSecurityProtocol = proto.Field( + proto.ENUM, + number=7, + enum=MysqlSecurityProtocol, + ) + ssl_mode: SSLMode = proto.Field( + proto.ENUM, + number=8, + enum=SSLMode, + ) + ssl_ca_file: str = proto.Field( + proto.STRING, + number=9, + ) + ssl_crl_file: str = proto.Field( + proto.STRING, + number=10, + ) + ssl_cert_file: str = proto.Field( + proto.STRING, + number=11, + ) + ssl_key_file: str = proto.Field( + proto.STRING, + number=12, + ) + additional_attributes: MutableSequence["NameValuePair"] = proto.RepeatedField( + proto.MESSAGE, + number=13, + message="NameValuePair", + ) + db_system_id: str = proto.Field( + proto.STRING, + number=14, + ) + + +class GoldengateKafkaConnectionProperties(proto.Message): + r"""The properties of GoldengateKafkaConnection. + + 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: + password (str): + Optional. Input only. The password for Kafka + basic/SASL auth in plain text. + + This field is a member of `oneof`_ ``connection_password_options``. + password_secret_version (str): + Optional. Input only. The resource name of a + secret version in Secret Manager which contains + the password for Kafka basic/SASL auth. Format: + + projects/{project}/secrets/{secret}/versions/{version}. + + This field is a member of `oneof`_ ``connection_password_options``. + trust_store_password (str): + Optional. Input only. The TrustStore password + in plain text. + + This field is a member of `oneof`_ ``trust_store_password_options``. + trust_store_password_secret_version (str): + Optional. Input only. The resource name of a + secret version in Secret Manager which contains + the TrustStore password. Format: + + projects/{project}/secrets/{secret}/versions/{version}. + + This field is a member of `oneof`_ ``trust_store_password_options``. + key_store_password (str): + Optional. Input only. The KeyStore password + in plain text. + + This field is a member of `oneof`_ ``key_store_password_options``. + key_store_password_secret_version (str): + Optional. Input only. The resource name of a + secret version in Secret Manager which contains + the KeyStore password. Format: + + projects/{project}/secrets/{secret}/versions/{version}. + + This field is a member of `oneof`_ ``key_store_password_options``. + ssl_key_password (str): + Optional. Input only. The password for the + cert inside of the KeyStore in plain text. + + This field is a member of `oneof`_ ``ssl_key_password_options``. + ssl_key_password_secret_version (str): + Optional. Input only. The resource name of a + secret version in Secret Manager which contains + the password for the cert inside of the + KeyStore. Format: + projects/{project}/secrets/{secret}/versions/{version}. + + This field is a member of `oneof`_ ``ssl_key_password_options``. + technology_type (str): + Optional. The technology type of + KafkaConnection. + stream_pool_id (str): + Optional. The OCID of the stream pool being + referenced. + cluster_id (str): + Optional. The OCID of the Kafka cluster being + referenced from OCI Streaming with Apache Kafka. + bootstrap_servers (MutableSequence[google.cloud.oracledatabase_v1.types.KafkaBootstrapServer]): + Optional. Kafka bootstrap. Equivalent of + bootstrap.servers configuration property in + Kafka: list of KafkaBootstrapServer objects + specified by host/port. Used for establishing + the initial connection to the Kafka cluster. + Example: + "server1.example.com:9092,server2.example.com:9092". + security_protocol (google.cloud.oracledatabase_v1.types.GoldengateKafkaConnectionProperties.KafkaSecurityProtocol): + Optional. Security Type for Kafka. + username (str): + Optional. The username Oracle Goldengate uses + to connect the associated system of the given + technology. + trust_store_file (str): + Optional. The base64 encoded content of the + TrustStore file. + key_store_file (str): + Optional. The base64 encoded content of the + KeyStore file. + consumer_properties_file (str): + Optional. The base64 encoded content of the + consumer.properties file. + producer_properties_file (str): + Optional. The base64 encoded content of the + producer.properties file. + use_resource_principal (bool): + Optional. Specifies that the user intends to + authenticate to the instance using a resource + principal. Applicable only for OCI Streaming + connections. + """ + + class KafkaSecurityProtocol(proto.Enum): + r"""Enum for Security Type for Kafka. + + Values: + KAFKA_SECURITY_PROTOCOL_UNSPECIFIED (0): + Security type not specified. + SSL (1): + SSL security protocol. + SASL_SSL (2): + SASL SSL security protocol. + PLAINTEXT (3): + Plaintext security protocol. + SASL_PLAINTEXT (4): + SASL Plaintext security protocol. + """ + + KAFKA_SECURITY_PROTOCOL_UNSPECIFIED = 0 + SSL = 1 + SASL_SSL = 2 + PLAINTEXT = 3 + SASL_PLAINTEXT = 4 + + password: str = proto.Field( + proto.STRING, + number=16, + oneof="connection_password_options", + ) + password_secret_version: str = proto.Field( + proto.STRING, + number=20, + oneof="connection_password_options", + ) + trust_store_password: str = proto.Field( + proto.STRING, + number=17, + oneof="trust_store_password_options", + ) + trust_store_password_secret_version: str = proto.Field( + proto.STRING, + number=21, + oneof="trust_store_password_options", + ) + key_store_password: str = proto.Field( + proto.STRING, + number=18, + oneof="key_store_password_options", + ) + key_store_password_secret_version: str = proto.Field( + proto.STRING, + number=22, + oneof="key_store_password_options", + ) + ssl_key_password: str = proto.Field( + proto.STRING, + number=19, + oneof="ssl_key_password_options", + ) + ssl_key_password_secret_version: str = proto.Field( + proto.STRING, + number=23, + oneof="ssl_key_password_options", + ) + technology_type: str = proto.Field( + proto.STRING, + number=1, + ) + stream_pool_id: str = proto.Field( + proto.STRING, + number=2, + ) + cluster_id: str = proto.Field( + proto.STRING, + number=3, + ) + bootstrap_servers: MutableSequence["KafkaBootstrapServer"] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message="KafkaBootstrapServer", + ) + security_protocol: KafkaSecurityProtocol = proto.Field( + proto.ENUM, + number=5, + enum=KafkaSecurityProtocol, + ) + username: str = proto.Field( + proto.STRING, + number=6, + ) + trust_store_file: str = proto.Field( + proto.STRING, + number=8, + ) + key_store_file: str = proto.Field( + proto.STRING, + number=10, + ) + consumer_properties_file: str = proto.Field( + proto.STRING, + number=13, + ) + producer_properties_file: str = proto.Field( + proto.STRING, + number=14, + ) + use_resource_principal: bool = proto.Field( + proto.BOOL, + number=15, + ) + + +class GoldengateKafkaSchemaRegistryConnectionProperties(proto.Message): + r"""The properties of GoldengateKafkaSchemaRegistryConnection. + + 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: + password (str): + Optional. Input only. The password to access + Schema Registry in plain text. + + This field is a member of `oneof`_ ``connection_password_options``. + password_secret_version (str): + Optional. Input only. The resource name of a + secret version in Secret Manager which contains + the password to access Schema Registry using + basic authentication. Format: + + projects/{project}/secrets/{secret}/versions/{version}. + + This field is a member of `oneof`_ ``connection_password_options``. + trust_store_password (str): + Optional. Input only. The TrustStore password + in plain text. + + This field is a member of `oneof`_ ``trust_store_password_options``. + trust_store_password_secret_version (str): + Optional. Input only. The resource name of a + secret version in Secret Manager which contains + the TrustStore password. Format: + + projects/{project}/secrets/{secret}/versions/{version}. + + This field is a member of `oneof`_ ``trust_store_password_options``. + key_store_password (str): + Optional. Input only. The KeyStore password + in plain text. + + This field is a member of `oneof`_ ``key_store_password_options``. + key_store_password_secret_version (str): + Optional. Input only. The resource name of a + secret version in Secret Manager which contains + the KeyStore password. Format: + + projects/{project}/secrets/{secret}/versions/{version}. + + This field is a member of `oneof`_ ``key_store_password_options``. + ssl_key_password (str): + Optional. Input only. The password for the + cert inside the KeyStore in plain text. + + This field is a member of `oneof`_ ``ssl_key_password_options``. + ssl_key_password_secret_version (str): + Optional. Input only. The resource name of a + secret version in Secret Manager which contains + the password for the cert inside the KeyStore. + Format: + projects/{project}/secrets/{secret}/versions/{version}. + + This field is a member of `oneof`_ ``ssl_key_password_options``. + technology_type (str): + Optional. The technology type of + KafkaSchemaRegistryConnection. + url (str): + Optional. Kafka Schema Registry URL. + e.g.: 'https://server1.us.oracle.com:8081' + authentication_type (google.cloud.oracledatabase_v1.types.GoldengateKafkaSchemaRegistryConnectionProperties.AuthenticationType): + Optional. Used authentication mechanism to + access Schema Registry. + username (str): + Optional. The username to access Schema + Registry using basic authentication. This value + is injected into + 'schema.registry.basic.auth.user.info=user:password' + configuration property. + trust_store_file (str): + Optional. The base64 encoded content of the + TrustStore file. + key_store_file (str): + Optional. The base64 encoded content of the + KeyStore file. + """ + + class AuthenticationType(proto.Enum): + r"""Enum for authentication mechanism to access Schema Registry. + + Values: + AUTHENTICATION_TYPE_UNSPECIFIED (0): + Authentication type not specified. + NONE (1): + No authentication. + BASIC (2): + Basic authentication. + MUTUAL (3): + Mutual authentication. + """ + + AUTHENTICATION_TYPE_UNSPECIFIED = 0 + NONE = 1 + BASIC = 2 + MUTUAL = 3 + + password: str = proto.Field( + proto.STRING, + number=11, + oneof="connection_password_options", + ) + password_secret_version: str = proto.Field( + proto.STRING, + number=15, + oneof="connection_password_options", + ) + trust_store_password: str = proto.Field( + proto.STRING, + number=12, + oneof="trust_store_password_options", + ) + trust_store_password_secret_version: str = proto.Field( + proto.STRING, + number=16, + oneof="trust_store_password_options", + ) + key_store_password: str = proto.Field( + proto.STRING, + number=13, + oneof="key_store_password_options", + ) + key_store_password_secret_version: str = proto.Field( + proto.STRING, + number=17, + oneof="key_store_password_options", + ) + ssl_key_password: str = proto.Field( + proto.STRING, + number=14, + oneof="ssl_key_password_options", + ) + ssl_key_password_secret_version: str = proto.Field( + proto.STRING, + number=18, + oneof="ssl_key_password_options", + ) + technology_type: str = proto.Field( + proto.STRING, + number=1, + ) + url: str = proto.Field( + proto.STRING, + number=2, + ) + authentication_type: AuthenticationType = proto.Field( + proto.ENUM, + number=3, + enum=AuthenticationType, + ) + username: str = proto.Field( + proto.STRING, + number=4, + ) + trust_store_file: str = proto.Field( + proto.STRING, + number=6, + ) + key_store_file: str = proto.Field( + proto.STRING, + number=8, + ) + + +class GoldengateOciObjectStorageConnectionProperties(proto.Message): + r"""The properties of GoldengateOciObjectStorageConnection. + + Attributes: + technology_type (str): + Optional. The technology type of + OciObjectStorageConnection. + tenancy_id (str): + Optional. The OCID of the related OCI + tenancy. + region (str): + Optional. The name of the region of OCI + Object Storage. e.g.: us-ashburn-1 If the region + is not provided, backend will default to the + default region. + user_id (str): + Optional. The OCID of the OCI user who will + access the Object Storage. The user must have + write access to the bucket they want to connect + to. + private_key_file (str): + Optional. The content of the private key file + (PEM file) corresponding to the API key of the + fingerprint. + private_key_passphrase_secret (str): + Optional. The passphrase of the private key. + public_key_fingerprint (str): + Optional. The fingerprint of the API Key of + the user specified by the userId. + use_resource_principal (bool): + Optional. Specifies that the user intends to + authenticate to the instance using a resource + principal. + """ + + technology_type: str = proto.Field( + proto.STRING, + number=1, + ) + tenancy_id: str = proto.Field( + proto.STRING, + number=2, + ) + region: str = proto.Field( + proto.STRING, + number=3, + ) + user_id: str = proto.Field( + proto.STRING, + number=4, + ) + private_key_file: str = proto.Field( + proto.STRING, + number=5, + ) + private_key_passphrase_secret: str = proto.Field( + proto.STRING, + number=6, + ) + public_key_fingerprint: str = proto.Field( + proto.STRING, + number=7, + ) + use_resource_principal: bool = proto.Field( + proto.BOOL, + number=8, + ) + + +class GoldengateAzureDataLakeStorageConnectionProperties(proto.Message): + r"""The properties of GoldengateAzureDataLakeStorageConnection. + + Attributes: + technology_type (str): + Optional. The technology type of + AzureDataLakeStorageConnection. + authentication_type (google.cloud.oracledatabase_v1.types.GoldengateAzureDataLakeStorageConnectionProperties.AuthenticationType): + Optional. Authentication mechanism to access + Azure Data Lake Storage. + account (str): + Optional. Sets the Azure storage account + name. + account_key_secret (str): + Optional. Azure storage account key. This property is + required when 'authentication_type' is set to 'SHARED_KEY'. + sas_token_secret (str): + Optional. Credential that uses a shared + access signature (SAS) to authenticate to an + Azure Service. + azure_tenant_id (str): + Optional. Azure tenant ID of the application. This property + is required when 'authentication_type' is set to + 'AZURE_ACTIVE_DIRECTORY'. + client_id (str): + Optional. Azure client ID of the application. This property + is required when 'authentication_type' is set to + 'AZURE_ACTIVE_DIRECTORY'. + client_secret (str): + Optional. Azure client secret (aka + application password) for authentication. + endpoint (str): + Optional. Azure Storage service endpoint. + e.g: https://test.blob.core.windows.net + azure_authority_host (str): + Optional. The endpoint used for + authentication with Microsoft Entra ID (formerly + Azure Active Directory). Default value: + + https://login.microsoftonline.com + """ + + class AuthenticationType(proto.Enum): + r"""Enum for authentication mechanism to access Azure Data Lake + Storage. + + Values: + AUTHENTICATION_TYPE_UNSPECIFIED (0): + Authentication type not specified. + SHARED_KEY (1): + Shared key authentication. + SHARED_ACCESS_SIGNATURE (2): + Shared access signature authentication. + AZURE_ACTIVE_DIRECTORY (3): + Azure active directory authentication. + """ + + AUTHENTICATION_TYPE_UNSPECIFIED = 0 + SHARED_KEY = 1 + SHARED_ACCESS_SIGNATURE = 2 + AZURE_ACTIVE_DIRECTORY = 3 + + technology_type: str = proto.Field( + proto.STRING, + number=1, + ) + authentication_type: AuthenticationType = proto.Field( + proto.ENUM, + number=2, + enum=AuthenticationType, + ) + account: str = proto.Field( + proto.STRING, + number=3, + ) + account_key_secret: str = proto.Field( + proto.STRING, + number=4, + ) + sas_token_secret: str = proto.Field( + proto.STRING, + number=5, + ) + azure_tenant_id: str = proto.Field( + proto.STRING, + number=6, + ) + client_id: str = proto.Field( + proto.STRING, + number=7, + ) + client_secret: str = proto.Field( + proto.STRING, + number=8, + ) + endpoint: str = proto.Field( + proto.STRING, + number=9, + ) + azure_authority_host: str = proto.Field( + proto.STRING, + number=10, + ) + + +class GoldengateAzureSynapseAnalyticsConnectionProperties(proto.Message): + r"""The properties of GoldengateAzureSynapseAnalyticsConnection. + + 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: + password (str): + Optional. Input only. The password Oracle + Goldengate uses for Azure Synapse Analytics + connection in plain text. + + This field is a member of `oneof`_ ``connection_password_options``. + password_secret_version (str): + Optional. Input only. The resource name of a + secret version in Secret Manager which contains + the password Oracle Goldengate uses for Azure + Synapse Analytics connection. Format: + + projects/{project}/secrets/{secret}/versions/{version}. + + This field is a member of `oneof`_ ``connection_password_options``. + technology_type (str): + Optional. The technology type of + AzureSynapseAnalyticsConnection. + connection_string (str): + Optional. JDBC connection string. e.g.: + 'jdbc:sqlserver://.sql.azuresynapse.net:1433;database=;encrypt=true;trustServerCertificate=false;hostNameInCertificate=\*.sql.azuresynapse.net;loginTimeout=300;' + username (str): + Optional. The username Oracle Goldengate uses + to connect the associated system of the given + technology. + """ + + password: str = proto.Field( + proto.STRING, + number=5, + oneof="connection_password_options", + ) + password_secret_version: str = proto.Field( + proto.STRING, + number=6, + oneof="connection_password_options", + ) + technology_type: str = proto.Field( + proto.STRING, + number=1, + ) + connection_string: str = proto.Field( + proto.STRING, + number=2, + ) + username: str = proto.Field( + proto.STRING, + number=3, + ) + + +class GoldengatePostgresqlConnectionProperties(proto.Message): + r"""The properties of GoldengatePostgresqlConnection. + + 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: + password (str): + Optional. Input only. The password Oracle + Goldengate uses for PostgreSQL connection in + plain text. + + This field is a member of `oneof`_ ``connection_password_options``. + password_secret_version (str): + Optional. Input only. The resource name of a + secret version in Secret Manager which contains + the password Oracle Goldengate uses for + PostgreSQL connection. Format: + + projects/{project}/secrets/{secret}/versions/{version}. + + This field is a member of `oneof`_ ``connection_password_options``. + technology_type (str): + Optional. The technology type of + PostgresqlConnection. + database (str): + Optional. The name of the database. + host (str): + Optional. The name or address of a host. + port (int): + Optional. The port of an endpoint usually + specified for a connection. + username (str): + Optional. The username Oracle Goldengate uses + to connect the associated system of the given + technology. + additional_attributes (MutableSequence[google.cloud.oracledatabase_v1.types.NameValuePair]): + Optional. An array of name-value pair + attribute entries. Used as additional parameters + in connection string. + security_protocol (google.cloud.oracledatabase_v1.types.GoldengatePostgresqlConnectionProperties.PostgresqlSecurityProtocol): + Optional. Security protocol for PostgreSQL. + ssl_mode (google.cloud.oracledatabase_v1.types.GoldengatePostgresqlConnectionProperties.PostgresqlSslMode): + Optional. SSL modes for PostgreSQL. + ssl_ca_file (str): + Optional. The base64 encoded certificate of + the trusted certificate authorities (Trusted CA) + for PostgreSQL. + ssl_crl_file (str): + Optional. The base64 encoded list of + certificates revoked by the trusted certificate + authorities (Trusted CA). + ssl_cert_file (str): + Optional. The base64 encoded certificate of + the PostgreSQL server. + ssl_key_file (str): + Optional. The base64 encoded private key of + the PostgreSQL server. + db_system_id (str): + Optional. The OCID of the database system + being referenced. + """ + + class PostgresqlSecurityProtocol(proto.Enum): + r"""Enum for Security protocol for PostgreSQL. + + Values: + POSTGRESQL_SECURITY_PROTOCOL_UNSPECIFIED (0): + Security protocol not specified. + PLAIN (1): + Plain text communication. + TLS (2): + Transport Layer Security. + MTLS (3): + Mutual Transport Layer Security. + """ + + POSTGRESQL_SECURITY_PROTOCOL_UNSPECIFIED = 0 + PLAIN = 1 + TLS = 2 + MTLS = 3 + + class PostgresqlSslMode(proto.Enum): + r"""Enum for SSL modes for PostgreSQL. + + Values: + POSTGRESQL_SSL_MODE_UNSPECIFIED (0): + SSL mode not specified. + PREFER (1): + Prefer SSL. + REQUIRE (2): + Require SSL. + VERIFY_CA (3): + Verify Certificate Authority. + VERIFY_FULL (4): + Verify Full. + """ + + POSTGRESQL_SSL_MODE_UNSPECIFIED = 0 + PREFER = 1 + REQUIRE = 2 + VERIFY_CA = 3 + VERIFY_FULL = 4 + + password: str = proto.Field( + proto.STRING, + number=15, + oneof="connection_password_options", + ) + password_secret_version: str = proto.Field( + proto.STRING, + number=16, + oneof="connection_password_options", + ) + technology_type: str = proto.Field( + proto.STRING, + number=1, + ) + database: str = proto.Field( + proto.STRING, + number=2, + ) + host: str = proto.Field( + proto.STRING, + number=3, + ) + port: int = proto.Field( + proto.INT32, + number=4, + ) + username: str = proto.Field( + proto.STRING, + number=5, + ) + additional_attributes: MutableSequence["NameValuePair"] = proto.RepeatedField( + proto.MESSAGE, + number=7, + message="NameValuePair", + ) + security_protocol: PostgresqlSecurityProtocol = proto.Field( + proto.ENUM, + number=8, + enum=PostgresqlSecurityProtocol, + ) + ssl_mode: PostgresqlSslMode = proto.Field( + proto.ENUM, + number=9, + enum=PostgresqlSslMode, + ) + ssl_ca_file: str = proto.Field( + proto.STRING, + number=10, + ) + ssl_crl_file: str = proto.Field( + proto.STRING, + number=11, + ) + ssl_cert_file: str = proto.Field( + proto.STRING, + number=12, + ) + ssl_key_file: str = proto.Field( + proto.STRING, + number=13, + ) + db_system_id: str = proto.Field( + proto.STRING, + number=14, + ) + + +class GoldengateMicrosoftSqlserverConnectionProperties(proto.Message): + r"""The properties of GoldengateMicrosoftSqlserverConnection. + + 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: + password (str): + Optional. Input only. The password Oracle + Goldengate uses for Microsoft SQL Server + connection in plain text. + + This field is a member of `oneof`_ ``connection_password_options``. + password_secret_version (str): + Optional. Input only. The resource name of a + secret version in Secret Manager which contains + the password Oracle Goldengate uses for + Microsoft SQL Server connection. Format: + + projects/{project}/secrets/{secret}/versions/{version}. + + This field is a member of `oneof`_ ``connection_password_options``. + technology_type (str): + Optional. The technology type of + MicrosoftSqlserverConnection. + database (str): + Optional. The name of the database. + host (str): + Optional. The name or address of a host. + port (int): + Optional. The port of an endpoint usually + specified for a connection. + username (str): + Optional. The username Oracle Goldengate uses + to connect to the Microsoft SQL Server. + additional_attributes (MutableSequence[google.cloud.oracledatabase_v1.types.NameValuePair]): + Optional. An array of name-value pair + attribute entries. Used as additional parameters + in connection string. + security_protocol (google.cloud.oracledatabase_v1.types.GoldengateMicrosoftSqlserverConnectionProperties.MicrosoftSqlserverSecurityProtocol): + Optional. Security Type for Microsoft SQL + Server. + ssl_ca_file (str): + Optional. Database Certificate - The base64 + encoded content of a .pem or .crt file + containing the server public key (for 1-way + SSL). + server_certificate_validation_required (bool): + Optional. If set to true, the driver + validates the certificate that is sent by the + database server. + """ + + class MicrosoftSqlserverSecurityProtocol(proto.Enum): + r"""Enum for Security Type for Microsoft SQL Server. + + Values: + MICROSOFT_SQLSERVER_SECURITY_PROTOCOL_UNSPECIFIED (0): + Security type not specified. + PLAIN (1): + Plain text communication. + TLS (2): + Transport Layer Security. + """ + + MICROSOFT_SQLSERVER_SECURITY_PROTOCOL_UNSPECIFIED = 0 + PLAIN = 1 + TLS = 2 + + password: str = proto.Field( + proto.STRING, + number=11, + oneof="connection_password_options", + ) + password_secret_version: str = proto.Field( + proto.STRING, + number=12, + oneof="connection_password_options", + ) + technology_type: str = proto.Field( + proto.STRING, + number=1, + ) + database: str = proto.Field( + proto.STRING, + number=2, + ) + host: str = proto.Field( + proto.STRING, + number=3, + ) + port: int = proto.Field( + proto.INT32, + number=4, + ) + username: str = proto.Field( + proto.STRING, + number=5, + ) + additional_attributes: MutableSequence["NameValuePair"] = proto.RepeatedField( + proto.MESSAGE, + number=7, + message="NameValuePair", + ) + security_protocol: MicrosoftSqlserverSecurityProtocol = proto.Field( + proto.ENUM, + number=8, + enum=MicrosoftSqlserverSecurityProtocol, + ) + ssl_ca_file: str = proto.Field( + proto.STRING, + number=9, + ) + server_certificate_validation_required: bool = proto.Field( + proto.BOOL, + number=10, + ) + + +class GoldengateAmazonS3ConnectionProperties(proto.Message): + r"""The properties of GoldengateAmazonS3Connection. + + Attributes: + technology_type (str): + Optional. The technology type of + AmazonS3Connection. + access_key_id (str): + Optional. Access key ID to access the Amazon + S3 bucket. + secret_access_key_secret (str): + Optional. Secret access key to access the + Amazon S3 bucket. + endpoint (str): + Optional. The Amazon Endpoint for S3. + region (str): + Optional. The name of the AWS region where + the bucket is created. + """ + + technology_type: str = proto.Field( + proto.STRING, + number=1, + ) + access_key_id: str = proto.Field( + proto.STRING, + number=2, + ) + secret_access_key_secret: str = proto.Field( + proto.STRING, + number=3, + ) + endpoint: str = proto.Field( + proto.STRING, + number=4, + ) + region: str = proto.Field( + proto.STRING, + number=5, + ) + + +class GoldengateHdfsConnectionProperties(proto.Message): + r"""The properties of GoldengateHdfsConnection. + + Attributes: + technology_type (str): + Optional. The technology type of + HdfsConnection. + core_site_xml (str): + Optional. The content of the Hadoop + Distributed File System configuration file + (core-site.xml). + """ + + technology_type: str = proto.Field( + proto.STRING, + number=1, + ) + core_site_xml: str = proto.Field( + proto.STRING, + number=2, + ) + + +class GoldengateJavaMessageServiceConnectionProperties(proto.Message): + r"""The properties of GoldengateJavaMessageServiceConnection. + + 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: + password (str): + Optional. Input only. The password Oracle + Goldengate uses to connect the Java Message + Service in plain text. + + This field is a member of `oneof`_ ``connection_password_options``. + password_secret_version (str): + Optional. Input only. The resource name of a + secret version in Secret Manager which contains + the password Oracle Goldengate uses to connect + the associated Java Message Service. Format: + + projects/{project}/secrets/{secret}/versions/{version}. + + This field is a member of `oneof`_ ``connection_password_options``. + trust_store_password (str): + Optional. Input only. The TrustStore password + in plain text. + + This field is a member of `oneof`_ ``trust_store_password_options``. + trust_store_password_secret_version (str): + Optional. Input only. The resource name of a + secret version in Secret Manager which contains + the TrustStore password. Format: + + projects/{project}/secrets/{secret}/versions/{version}. + + This field is a member of `oneof`_ ``trust_store_password_options``. + key_store_password (str): + Optional. Input only. The KeyStore password + in plain text. + + This field is a member of `oneof`_ ``key_store_password_options``. + key_store_password_secret_version (str): + Optional. Input only. The resource name of a + secret version in Secret Manager which contains + the KeyStore password. Format: + + projects/{project}/secrets/{secret}/versions/{version}. + + This field is a member of `oneof`_ ``key_store_password_options``. + ssl_key_password (str): + Optional. Input only. The password for the + cert inside of the KeyStore in plain text. + + This field is a member of `oneof`_ ``ssl_key_password_options``. + ssl_key_password_secret_version (str): + Optional. Input only. The resource name of a + secret version in Secret Manager which contains + the password for the cert inside of the + KeyStore. Format: + projects/{project}/secrets/{secret}/versions/{version}. + + This field is a member of `oneof`_ ``ssl_key_password_options``. + technology_type (str): + Optional. The technology type of + JavaMessageServiceConnection. + use_jndi (bool): + Optional. If set to true, Java Naming and + Directory Interface (JNDI) properties should be + provided. + jndi_connection_factory (str): + Optional. The Connection Factory can be + looked up using this name. e.g.: + 'ConnectionFactory' + jndi_provider_url (str): + Optional. The URL that Java Message Service + will use to contact the JNDI provider. e.g.: + 'tcp://myjms.host.domain:61616?jms.prefetchPolicy.all=1000' + jndi_initial_context_factory (str): + Optional. The implementation of + javax.naming.spi.InitialContextFactory interface + used to obtain initial naming context. + jndi_security_principal (str): + Optional. Specifies the identity of the + principal (user) to be authenticated. + jndi_security_credentials_secret (str): + Optional. The password associated to the + principal. + connection_url (str): + Optional. Connection URL of the Java Message + Service, specifying the protocol, host, and + port. e.g.: 'mq://myjms.host.domain:7676' + connection_factory (str): + Optional. The Java class implementing + javax.jms.ConnectionFactory interface supplied + by the JMS provider. + username (str): + Optional. The username Oracle Goldengate uses + to connect to the Java Message Service. + security_protocol (google.cloud.oracledatabase_v1.types.GoldengateJavaMessageServiceConnectionProperties.JmsSecurityProtocol): + Optional. Security protocol for Java Message + Service. + authentication_type (google.cloud.oracledatabase_v1.types.GoldengateJavaMessageServiceConnectionProperties.JmsAuthenticationType): + Optional. Authentication type for Java + Message Service. + trust_store_file (str): + Optional. The base64 encoded content of the + TrustStore file. + key_store_file (str): + Optional. The base64 encoded content of the + KeyStore file. + """ + + class JmsSecurityProtocol(proto.Enum): + r"""Enum for Security protocol for Java Message Service. + + Values: + JMS_SECURITY_PROTOCOL_UNSPECIFIED (0): + Security protocol not specified. + PLAIN (1): + Plain text communication. + TLS (2): + Transport Layer Security. + MTLS (3): + Mutual Transport Layer Security. + """ + + JMS_SECURITY_PROTOCOL_UNSPECIFIED = 0 + PLAIN = 1 + TLS = 2 + MTLS = 3 + + class JmsAuthenticationType(proto.Enum): + r"""Enum for Authentication type for Java Message Service. + + Values: + JMS_AUTHENTICATION_TYPE_UNSPECIFIED (0): + Authentication type not specified. + NONE (1): + No authentication. + BASIC (2): + Basic authentication. + """ + + JMS_AUTHENTICATION_TYPE_UNSPECIFIED = 0 + NONE = 1 + BASIC = 2 + + password: str = proto.Field( + proto.STRING, + number=19, + oneof="connection_password_options", + ) + password_secret_version: str = proto.Field( + proto.STRING, + number=23, + oneof="connection_password_options", + ) + trust_store_password: str = proto.Field( + proto.STRING, + number=20, + oneof="trust_store_password_options", + ) + trust_store_password_secret_version: str = proto.Field( + proto.STRING, + number=24, + oneof="trust_store_password_options", + ) + key_store_password: str = proto.Field( + proto.STRING, + number=21, + oneof="key_store_password_options", + ) + key_store_password_secret_version: str = proto.Field( + proto.STRING, + number=25, + oneof="key_store_password_options", + ) + ssl_key_password: str = proto.Field( + proto.STRING, + number=22, + oneof="ssl_key_password_options", + ) + ssl_key_password_secret_version: str = proto.Field( + proto.STRING, + number=26, + oneof="ssl_key_password_options", + ) + technology_type: str = proto.Field( + proto.STRING, + number=1, + ) + use_jndi: bool = proto.Field( + proto.BOOL, + number=2, + ) + jndi_connection_factory: str = proto.Field( + proto.STRING, + number=3, + ) + jndi_provider_url: str = proto.Field( + proto.STRING, + number=4, + ) + jndi_initial_context_factory: str = proto.Field( + proto.STRING, + number=5, + ) + jndi_security_principal: str = proto.Field( + proto.STRING, + number=6, + ) + jndi_security_credentials_secret: str = proto.Field( + proto.STRING, + number=7, + ) + connection_url: str = proto.Field( + proto.STRING, + number=8, + ) + connection_factory: str = proto.Field( + proto.STRING, + number=9, + ) + username: str = proto.Field( + proto.STRING, + number=10, + ) + security_protocol: JmsSecurityProtocol = proto.Field( + proto.ENUM, + number=12, + enum=JmsSecurityProtocol, + ) + authentication_type: JmsAuthenticationType = proto.Field( + proto.ENUM, + number=13, + enum=JmsAuthenticationType, + ) + trust_store_file: str = proto.Field( + proto.STRING, + number=14, + ) + key_store_file: str = proto.Field( + proto.STRING, + number=16, + ) + + +class GoldengateMongodbConnectionProperties(proto.Message): + r"""The properties of GoldengateMongodbConnection. + + 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: + password (str): + Optional. Input only. The password Oracle + Goldengate uses to connect the Mongodb + connection in plain text. + + This field is a member of `oneof`_ ``connection_password_options``. + password_secret_version (str): + Optional. Input only. The resource name of a + secret version in Secret Manager which contains + the password Oracle Goldengate uses to connect + the Mongodb connection. Format: + + projects/{project}/secrets/{secret}/versions/{version}. + + This field is a member of `oneof`_ ``connection_password_options``. + tls_certificate_key_file_password (str): + Optional. Input only. The Client Certificate + key file password in plain text. + + This field is a member of `oneof`_ ``tls_certificate_key_file_password_options``. + tls_certificate_key_file_password_secret_version (str): + Optional. Input only. The resource name of a + secret version in Secret Manager which contains + the Client Certificate key file password in + Secret Manager. Format: + projects/{project}/secrets/{secret}/versions/{version}. + + This field is a member of `oneof`_ ``tls_certificate_key_file_password_options``. + technology_type (str): + Optional. The technology type of + MongodbConnection. + connection_string (str): + Optional. MongoDB connection string. + e.g.: + 'mongodb://mongodb0.example.com:27017/recordsrecords' + username (str): + Optional. The username Oracle Goldengate uses + to connect to the database. + database_id (str): + Optional. The OCID of the Oracle Autonomous + Json Database. + security_protocol (google.cloud.oracledatabase_v1.types.GoldengateMongodbConnectionProperties.MongodbSecurityProtocol): + Optional. Security Type for MongoDB. + tls_ca_file (str): + Optional. Database Certificate - The base64 + encoded content of a .pem file, containing the + server public key (for 1 and 2-way SSL). + tls_certificate_key_file (str): + Optional. Client Certificate - The base64 + encoded content of a .pem file, containing the + client public key (for 2-way SSL). + """ + + class MongodbSecurityProtocol(proto.Enum): + r"""Enum for Security Type for MongoDB. + + Values: + MONGODB_SECURITY_PROTOCOL_UNSPECIFIED (0): + Security type not specified. + PLAIN (1): + Plain text communication. + TLS (2): + Transport Layer Security. + MTLS (3): + Mutual Transport Layer Security. + """ + + MONGODB_SECURITY_PROTOCOL_UNSPECIFIED = 0 + PLAIN = 1 + TLS = 2 + MTLS = 3 + + password: str = proto.Field( + proto.STRING, + number=10, + oneof="connection_password_options", + ) + password_secret_version: str = proto.Field( + proto.STRING, + number=12, + oneof="connection_password_options", + ) + tls_certificate_key_file_password: str = proto.Field( + proto.STRING, + number=11, + oneof="tls_certificate_key_file_password_options", + ) + tls_certificate_key_file_password_secret_version: str = proto.Field( + proto.STRING, + number=13, + oneof="tls_certificate_key_file_password_options", + ) + technology_type: str = proto.Field( + proto.STRING, + number=1, + ) + connection_string: str = proto.Field( + proto.STRING, + number=2, + ) + username: str = proto.Field( + proto.STRING, + number=3, + ) + database_id: str = proto.Field( + proto.STRING, + number=5, + ) + security_protocol: MongodbSecurityProtocol = proto.Field( + proto.ENUM, + number=6, + enum=MongodbSecurityProtocol, + ) + tls_ca_file: str = proto.Field( + proto.STRING, + number=7, + ) + tls_certificate_key_file: str = proto.Field( + proto.STRING, + number=8, + ) + + +class GoldengateOracleNosqlConnectionProperties(proto.Message): + r"""The properties of GoldengateOracleNosqlConnection. + + Attributes: + technology_type (str): + Optional. The technology type of + OracleNosqlConnection. + tenancy_id (str): + Optional. The OCID of the OCI tenancy. + region (str): + Optional. The name of the region. e.g.: + us-ashburn-1 + user_id (str): + Optional. The OCID of the OCI user who will + access the Oracle NoSQL database. + private_key_file (str): + Optional. The content of the private key file + (PEM file) corresponding to the API key of the + fingerprint. + private_key_passphrase_secret (str): + Optional. The passphrase of the private key. + public_key_fingerprint (str): + Optional. The fingerprint of the API Key of + the user specified by the userId. + use_resource_principal (bool): + Optional. Specifies that the user intends to + authenticate to the instance using a resource + principal. + """ + + technology_type: str = proto.Field( + proto.STRING, + number=1, + ) + tenancy_id: str = proto.Field( + proto.STRING, + number=2, + ) + region: str = proto.Field( + proto.STRING, + number=3, + ) + user_id: str = proto.Field( + proto.STRING, + number=4, + ) + private_key_file: str = proto.Field( + proto.STRING, + number=5, + ) + private_key_passphrase_secret: str = proto.Field( + proto.STRING, + number=6, + ) + public_key_fingerprint: str = proto.Field( + proto.STRING, + number=7, + ) + use_resource_principal: bool = proto.Field( + proto.BOOL, + number=8, + ) + + +class GoldengateSnowflakeConnectionProperties(proto.Message): + r"""The properties of GoldengateSnowflakeConnection. + + 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: + password (str): + Optional. Input only. The password Oracle + Goldengate uses to connect to Snowflake platform + in plain text. + + This field is a member of `oneof`_ ``connection_password_options``. + password_secret_version (str): + Optional. Input only. The resource name of a + secret version in Secret Manager which contains + the password Oracle Goldengate uses to connect + to Snowflake platform. Format: + + projects/{project}/secrets/{secret}/versions/{version}. + + This field is a member of `oneof`_ ``connection_password_options``. + technology_type (str): + Optional. The technology type of + SnowflakeConnection. + connection_url (str): + Optional. JDBC connection URL. e.g.: + 'jdbc:snowflake://.snowflakecomputing.com/?warehouse=&db=' + authentication_type (google.cloud.oracledatabase_v1.types.GoldengateSnowflakeConnectionProperties.AuthenticationType): + Optional. Used authentication mechanism to + access Snowflake. + username (str): + Optional. The username Oracle Goldengate uses + to connect to Snowflake. + private_key_file (str): + Optional. The content of private key file in + PEM format. + private_key_passphrase_secret (str): + Optional. Password if the private key file is + encrypted. + """ + + class AuthenticationType(proto.Enum): + r"""Enum for authentication mechanism to access Snowflake. + + Values: + AUTHENTICATION_TYPE_UNSPECIFIED (0): + Authentication type not specified. + BASIC (1): + Basic authentication. + KEY_PAIR (2): + Key pair authentication. + """ + + AUTHENTICATION_TYPE_UNSPECIFIED = 0 + BASIC = 1 + KEY_PAIR = 2 + + password: str = proto.Field( + proto.STRING, + number=8, + oneof="connection_password_options", + ) + password_secret_version: str = proto.Field( + proto.STRING, + number=9, + oneof="connection_password_options", + ) + technology_type: str = proto.Field( + proto.STRING, + number=1, + ) + connection_url: str = proto.Field( + proto.STRING, + number=2, + ) + authentication_type: AuthenticationType = proto.Field( + proto.ENUM, + number=3, + enum=AuthenticationType, + ) + username: str = proto.Field( + proto.STRING, + number=4, + ) + private_key_file: str = proto.Field( + proto.STRING, + number=6, + ) + private_key_passphrase_secret: str = proto.Field( + proto.STRING, + number=7, + ) + + +class GoldengateAmazonRedshiftConnectionProperties(proto.Message): + r"""The properties of GoldengateAmazonRedshiftConnection. + + 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: + password (str): + Optional. Input only. The password Oracle + Goldengate uses for Amazon Redshift connection + in plain text. + + This field is a member of `oneof`_ ``connection_password_options``. + password_secret_version (str): + Optional. Input only. The resource name of a + secret version in Secret Manager which contains + the password Oracle Goldengate uses for Amazon + Redshift connection. Format: + + projects/{project}/secrets/{secret}/versions/{version}. + + This field is a member of `oneof`_ ``connection_password_options``. + technology_type (str): + Optional. The technology type of + AmazonRedshiftConnection. + connection_url (str): + Optional. Connection URL. + e.g.: + + 'jdbc:redshift://aws-redshift-instance.aaaaaaaaaaaa.us-east-2.redshift.amazonaws.com:5439/mydb' + username (str): + Optional. The username Oracle Goldengate uses + to connect the associated system of the given + technology. + """ + + password: str = proto.Field( + proto.STRING, + number=5, + oneof="connection_password_options", + ) + password_secret_version: str = proto.Field( + proto.STRING, + number=6, + oneof="connection_password_options", + ) + technology_type: str = proto.Field( + proto.STRING, + number=1, + ) + connection_url: str = proto.Field( + proto.STRING, + number=2, + ) + username: str = proto.Field( + proto.STRING, + number=3, + ) + + +class GoldengateElasticsearchConnectionProperties(proto.Message): + r"""The properties of GoldengateElasticsearchConnection. + + 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: + password (str): + Optional. Input only. The password Oracle + Goldengate uses for Elastic Search connection in + plain text. + + This field is a member of `oneof`_ ``connection_password_options``. + password_secret_version (str): + Optional. Input only. The resource name of a + secret version in Secret Manager which contains + the password Oracle Goldengate uses for Elastic + Search connection. Format: + + projects/{project}/secrets/{secret}/versions/{version}. + + This field is a member of `oneof`_ ``connection_password_options``. + technology_type (str): + Optional. The technology type of + ElasticsearchConnection. + servers (str): + Optional. Comma separated list of + Elasticsearch server addresses, specified as + host:port entries, where :port is optional. If + port is not specified, it defaults to 9200. + Example: + + "server1.example.com:4000,server2.example.com:4000". + security_protocol (google.cloud.oracledatabase_v1.types.GoldengateElasticsearchConnectionProperties.ElasticsearchSecurityProtocol): + Optional. Security protocol for + Elasticsearch. + authentication_type (google.cloud.oracledatabase_v1.types.GoldengateElasticsearchConnectionProperties.ElasticsearchAuthenticationType): + Optional. Authentication type for + Elasticsearch. + username (str): + Optional. The username Oracle Goldengate uses + to connect the associated system of the given + technology. + fingerprint (str): + Optional. Fingerprint required by TLS + security protocol. Eg.: + '6152b2dfbff200f973c5074a5b91d06ab3b472c07c09a1ea57bb7fd406cdce9c' + """ + + class ElasticsearchSecurityProtocol(proto.Enum): + r"""Enum for Security protocol for Elasticsearch. + + Values: + ELASTICSEARCH_SECURITY_PROTOCOL_UNSPECIFIED (0): + Security protocol not specified. + PLAIN (1): + Plain text communication. + TLS (2): + Transport Layer Security. + """ + + ELASTICSEARCH_SECURITY_PROTOCOL_UNSPECIFIED = 0 + PLAIN = 1 + TLS = 2 + + class ElasticsearchAuthenticationType(proto.Enum): + r"""Enum for Authentication type for Elasticsearch. + + Values: + ELASTICSEARCH_AUTHENTICATION_TYPE_UNSPECIFIED (0): + Authentication type not specified. + NONE (1): + No authentication. + BASIC (2): + Basic authentication. + """ + + ELASTICSEARCH_AUTHENTICATION_TYPE_UNSPECIFIED = 0 + NONE = 1 + BASIC = 2 + + password: str = proto.Field( + proto.STRING, + number=8, + oneof="connection_password_options", + ) + password_secret_version: str = proto.Field( + proto.STRING, + number=9, + oneof="connection_password_options", + ) + technology_type: str = proto.Field( + proto.STRING, + number=1, + ) + servers: str = proto.Field( + proto.STRING, + number=2, + ) + security_protocol: ElasticsearchSecurityProtocol = proto.Field( + proto.ENUM, + number=3, + enum=ElasticsearchSecurityProtocol, + ) + authentication_type: ElasticsearchAuthenticationType = proto.Field( + proto.ENUM, + number=4, + enum=ElasticsearchAuthenticationType, + ) + username: str = proto.Field( + proto.STRING, + number=5, + ) + fingerprint: str = proto.Field( + proto.STRING, + number=7, + ) + + +class GoldengateAmazonKinesisConnectionProperties(proto.Message): + r"""The properties of GoldengateAmazonKinesisConnection. + + Attributes: + technology_type (str): + Optional. The technology type of + AmazonKinesisConnection. + access_key_id (str): + Optional. Access key ID to access the Amazon + Kinesis. + secret_access_key_secret (str): + Optional. Secret access key to access the + Amazon Kinesis. + endpoint (str): + Optional. The endpoint URL of the Amazon + Kinesis service. e.g.: + 'https://kinesis.us-east-1.amazonaws.com' If not + provided, Goldengate will default to + 'https://kinesis..amazonaws.com'. + aws_region (str): + Optional. The name of the AWS region. + If not provided, Goldengate will default to + 'us-west-1'. + """ + + technology_type: str = proto.Field( + proto.STRING, + number=1, + ) + access_key_id: str = proto.Field( + proto.STRING, + number=2, + ) + secret_access_key_secret: str = proto.Field( + proto.STRING, + number=3, + ) + endpoint: str = proto.Field( + proto.STRING, + number=4, + ) + aws_region: str = proto.Field( + proto.STRING, + number=5, + ) + + +class GoldengateDb2ConnectionProperties(proto.Message): + r"""The properties of GoldengateDb2Connection. + + 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: + password (str): + Optional. Input only. The password Oracle + Goldengate uses for Db2 connection in plain + text. + + This field is a member of `oneof`_ ``connection_password_options``. + password_secret_version (str): + Optional. Input only. The resource name of a + secret version in Secret Manager which contains + the password Oracle Goldengate uses for Db2 + connection. Format: + + projects/{project}/secrets/{secret}/versions/{version}. + + This field is a member of `oneof`_ ``connection_password_options``. + technology_type (str): + Optional. The technology type of + Db2Connection. + host (str): + Optional. The name or address of a host. + port (int): + Optional. The port of an endpoint usually + specified for a connection. + database (str): + Optional. The name of the database. + username (str): + Optional. The username Oracle Goldengate uses + to connect to the DB2 database. + security_protocol (google.cloud.oracledatabase_v1.types.GoldengateDb2ConnectionProperties.Db2SecurityProtocol): + Optional. Security protocol for the DB2 + database. + additional_attributes (MutableSequence[google.cloud.oracledatabase_v1.types.NameValuePair]): + Optional. An array of name-value pair + attribute entries. Used as additional parameters + in connection string. + ssl_client_keystoredb_file (str): + Optional. The keystore file created at the + client containing the server certificate / CA + root certificate. Not supported for IBM Db2 for + i. + ssl_client_keystash_file (str): + Optional. The keystash file which contains + the encrypted password to the key database file. + Not supported for IBM Db2 for i. + ssl_server_certificate_file (str): + Optional. The file which contains the + self-signed server certificate / Certificate + Authority (CA) certificate. + """ + + class Db2SecurityProtocol(proto.Enum): + r"""Enum for Security protocol for the DB2 database. + + Values: + DB2_SECURITY_PROTOCOL_UNSPECIFIED (0): + Security protocol not specified. + PLAIN (1): + Plain text communication. + TLS (2): + Transport Layer Security. + """ + + DB2_SECURITY_PROTOCOL_UNSPECIFIED = 0 + PLAIN = 1 + TLS = 2 + + password: str = proto.Field( + proto.STRING, + number=12, + oneof="connection_password_options", + ) + password_secret_version: str = proto.Field( + proto.STRING, + number=13, + oneof="connection_password_options", + ) + technology_type: str = proto.Field( + proto.STRING, + number=1, + ) + host: str = proto.Field( + proto.STRING, + number=2, + ) + port: int = proto.Field( + proto.INT32, + number=3, + ) + database: str = proto.Field( + proto.STRING, + number=4, + ) + username: str = proto.Field( + proto.STRING, + number=5, + ) + security_protocol: Db2SecurityProtocol = proto.Field( + proto.ENUM, + number=6, + enum=Db2SecurityProtocol, + ) + additional_attributes: MutableSequence["NameValuePair"] = proto.RepeatedField( + proto.MESSAGE, + number=8, + message="NameValuePair", + ) + ssl_client_keystoredb_file: str = proto.Field( + proto.STRING, + number=9, + ) + ssl_client_keystash_file: str = proto.Field( + proto.STRING, + number=10, + ) + ssl_server_certificate_file: str = proto.Field( + proto.STRING, + number=11, + ) + + +class GoldengateRedisConnectionProperties(proto.Message): + r"""The properties of GoldengateRedisConnection. + + 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: + password (str): + Optional. Input only. The password Oracle + Goldengate uses for Redis connection in plain + text. + + This field is a member of `oneof`_ ``connection_password_options``. + password_secret_version (str): + Optional. Input only. The resource name of a + secret version in Secret Manager which contains + the password Oracle Goldengate uses for Redis + connection. Format: + + projects/{project}/secrets/{secret}/versions/{version}. + + This field is a member of `oneof`_ ``connection_password_options``. + trust_store_password (str): + Optional. Input only. The TrustStore password + in plain text. + + This field is a member of `oneof`_ ``trust_store_password_options``. + trust_store_password_secret_version (str): + Optional. Input only. The resource name of a + secret version in Secret Manager which contains + the TrustStore password. Format: + + projects/{project}/secrets/{secret}/versions/{version}. + + This field is a member of `oneof`_ ``trust_store_password_options``. + key_store_password (str): + Optional. Input only. The KeyStore password + in plain text. + + This field is a member of `oneof`_ ``key_store_password_options``. + key_store_password_secret_version (str): + Optional. Input only. The resource name of a + secret version in Secret Manager which contains + the KeyStore password. Format: + + projects/{project}/secrets/{secret}/versions/{version}. + + This field is a member of `oneof`_ ``key_store_password_options``. + technology_type (str): + Optional. The technology type of + RedisConnection. + servers (str): + Optional. Comma separated list of Redis + server addresses, specified as host:port + entries, where :port is optional. If port is not + specified, it defaults to 6379. Example: + + "server1.example.com:6379,server2.example.com:6379". + security_protocol (google.cloud.oracledatabase_v1.types.GoldengateRedisConnectionProperties.RedisSecurityProtocol): + Optional. Security protocol for Redis. + authentication_type (google.cloud.oracledatabase_v1.types.GoldengateRedisConnectionProperties.RedisAuthenticationType): + Optional. Authentication type for Redis. + username (str): + Optional. The username Oracle Goldengate uses + to connect the associated system of the given + technology. + redis_cluster_id (str): + Optional. The OCID of the Redis cluster. + trust_store_file (str): + Optional. The base64 encoded content of the + TrustStore file. + key_store_file (str): + Optional. The base64 encoded content of the + KeyStore file. + """ + + class RedisSecurityProtocol(proto.Enum): + r"""Enum for Security protocol for Redis. + + Values: + REDIS_SECURITY_PROTOCOL_UNSPECIFIED (0): + Security protocol not specified. + PLAIN (1): + Plain text communication. + TLS (2): + Transport Layer Security. + MTLS (3): + Mutual Transport Layer Security. + """ + + REDIS_SECURITY_PROTOCOL_UNSPECIFIED = 0 + PLAIN = 1 + TLS = 2 + MTLS = 3 + + class RedisAuthenticationType(proto.Enum): + r"""Enum for Authentication type for Redis. + + Values: + REDIS_AUTHENTICATION_TYPE_UNSPECIFIED (0): + Authentication type not specified. + NONE (1): + No authentication. + BASIC (2): + Basic authentication. + """ + + REDIS_AUTHENTICATION_TYPE_UNSPECIFIED = 0 + NONE = 1 + BASIC = 2 + + password: str = proto.Field( + proto.STRING, + number=12, + oneof="connection_password_options", + ) + password_secret_version: str = proto.Field( + proto.STRING, + number=15, + oneof="connection_password_options", + ) + trust_store_password: str = proto.Field( + proto.STRING, + number=13, + oneof="trust_store_password_options", + ) + trust_store_password_secret_version: str = proto.Field( + proto.STRING, + number=16, + oneof="trust_store_password_options", + ) + key_store_password: str = proto.Field( + proto.STRING, + number=14, + oneof="key_store_password_options", + ) + key_store_password_secret_version: str = proto.Field( + proto.STRING, + number=17, + oneof="key_store_password_options", + ) + technology_type: str = proto.Field( + proto.STRING, + number=1, + ) + servers: str = proto.Field( + proto.STRING, + number=2, + ) + security_protocol: RedisSecurityProtocol = proto.Field( + proto.ENUM, + number=3, + enum=RedisSecurityProtocol, + ) + authentication_type: RedisAuthenticationType = proto.Field( + proto.ENUM, + number=4, + enum=RedisAuthenticationType, + ) + username: str = proto.Field( + proto.STRING, + number=5, + ) + redis_cluster_id: str = proto.Field( + proto.STRING, + number=7, + ) + trust_store_file: str = proto.Field( + proto.STRING, + number=8, + ) + key_store_file: str = proto.Field( + proto.STRING, + number=10, + ) + + +class GoldengateDatabricksConnectionProperties(proto.Message): + r"""The properties of GoldengateDatabricksConnection. + + 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: + password (str): + Optional. Input only. The password used to + connect to Databricks in plain text. + + This field is a member of `oneof`_ ``connection_password_options``. + password_secret_version (str): + Optional. Input only. The resource name of a + secret version in Secret Manager which contains + the password used to connect to Databricks. + Format: + projects/{project}/secrets/{secret}/versions/{version}. + + This field is a member of `oneof`_ ``connection_password_options``. + technology_type (str): + Optional. The technology type of + DatabricksConnection. + authentication_type (google.cloud.oracledatabase_v1.types.GoldengateDatabricksConnectionProperties.DatabricksAuthenticationType): + Optional. Authentication type for Databricks. + connection_url (str): + Optional. Connection URL. + e.g.: + + 'jdbc:databricks://adb-33934.4.azuredatabricks.net:443/default;transportMode=http;ssl=1;httpPath=sql/protocolv1/o/3393########44/0##3-7-hlrb' + client_id (str): + Optional. OAuth client id, only applicable for + authentication_type == OAUTH_M2M + client_secret (str): + Optional. OAuth client secret, only applicable for + authentication_type == OAUTH_M2M + storage_credential (str): + Optional. External storage credential name to + access files on object storage such as ADLS + Gen2, S3 or Cloud Storage. + """ + + class DatabricksAuthenticationType(proto.Enum): + r"""Enum for authentication type for Databricks. + + Values: + DATABRICKS_AUTHENTICATION_TYPE_UNSPECIFIED (0): + Authentication type not specified. + PERSONAL_ACCESS_TOKEN (1): + Personal access token authentication. + OAUTH_M2M (2): + OAuth M2M authentication. + """ + + DATABRICKS_AUTHENTICATION_TYPE_UNSPECIFIED = 0 + PERSONAL_ACCESS_TOKEN = 1 + OAUTH_M2M = 2 + + password: str = proto.Field( + proto.STRING, + number=8, + oneof="connection_password_options", + ) + password_secret_version: str = proto.Field( + proto.STRING, + number=9, + oneof="connection_password_options", + ) + technology_type: str = proto.Field( + proto.STRING, + number=1, + ) + authentication_type: DatabricksAuthenticationType = proto.Field( + proto.ENUM, + number=2, + enum=DatabricksAuthenticationType, + ) + connection_url: str = proto.Field( + proto.STRING, + number=3, + ) + client_id: str = proto.Field( + proto.STRING, + number=5, + ) + client_secret: str = proto.Field( + proto.STRING, + number=6, + ) + storage_credential: str = proto.Field( + proto.STRING, + number=7, + ) + + +class GoldengateGooglePubsubConnectionProperties(proto.Message): + r"""The properties of GoldengateGooglePubsubConnection. + + Attributes: + technology_type (str): + Optional. The technology type of + GooglePubsubConnection. + service_account_key_file (str): + Optional. The base64 encoded content of the + service account key file containing the + credentials required to use Google Pub/Sub. + """ + + technology_type: str = proto.Field( + proto.STRING, + number=1, + ) + service_account_key_file: str = proto.Field( + proto.STRING, + number=2, + ) + + +class GoldengateMicrosoftFabricConnectionProperties(proto.Message): + r"""The properties of GoldengateMicrosoftFabricConnection. + + Attributes: + technology_type (str): + Optional. The technology type of + MicrosoftFabricConnection. + tenant_id (str): + Optional. Azure tenant ID of the application. + client_id (str): + Optional. Azure client ID of the application. + client_secret (str): + Optional. Client secret associated with the + client id. + endpoint (str): + Optional. Optional Microsoft Fabric service + endpoint. Default value: + https://onelake.dfs.fabric.microsoft.com + """ + + technology_type: str = proto.Field( + proto.STRING, + number=1, + ) + tenant_id: str = proto.Field( + proto.STRING, + number=2, + ) + client_id: str = proto.Field( + proto.STRING, + number=3, + ) + client_secret: str = proto.Field( + proto.STRING, + number=4, + ) + endpoint: str = proto.Field( + proto.STRING, + number=5, + ) + + +class GoldengateOracleAIDataPlatformConnectionProperties(proto.Message): + r"""The properties of GoldengateOracleAIDataPlatformConnection. + + Attributes: + technology_type (str): + Optional. The technology type of + OracleAiDataPlatformConnection. + connection_url (str): + Optional. Connection URL. It must start with + 'jdbc:spark://' + tenancy_id (str): + Optional. The OCID of the related OCI + tenancy. + region (str): + Optional. The name of the region. e.g.: + us-ashburn-1 + user_id (str): + Optional. The OCID of the OCI user who will + access. + private_key_file (str): + Optional. The content of the private key file + (PEM file) corresponding to the API key of the + fingerprint. + private_key_passphrase_secret (str): + Optional. The passphrase of the private key. + public_key_fingerprint (str): + Optional. The fingerprint of the API Key of the user + specified by the user_id. + use_resource_principal (bool): + Optional. Specifies that the user intends to + authenticate to the instance using a resource + principal. + """ + + technology_type: str = proto.Field( + proto.STRING, + number=1, + ) + connection_url: str = proto.Field( + proto.STRING, + number=2, + ) + tenancy_id: str = proto.Field( + proto.STRING, + number=3, + ) + region: str = proto.Field( + proto.STRING, + number=4, + ) + user_id: str = proto.Field( + proto.STRING, + number=5, + ) + private_key_file: str = proto.Field( + proto.STRING, + number=6, + ) + private_key_passphrase_secret: str = proto.Field( + proto.STRING, + number=7, + ) + public_key_fingerprint: str = proto.Field( + proto.STRING, + number=8, + ) + use_resource_principal: bool = proto.Field( + proto.BOOL, + number=9, + ) + + +class GlueIcebergCatalog(proto.Message): + r"""The Glue Iceberg catalog. + + Attributes: + glue_id (str): + Required. The catalog ID of Glue. + """ + + glue_id: str = proto.Field( + proto.STRING, + number=1, + ) + + +class NessieIcebergCatalog(proto.Message): + r"""The Nessie Iceberg catalog. + + Attributes: + uri (str): + Required. The Nessie uri. + branch (str): + Required. The Nessie branch. + """ + + uri: str = proto.Field( + proto.STRING, + number=1, + ) + branch: str = proto.Field( + proto.STRING, + number=2, + ) + + +class PolarisIcebergCatalog(proto.Message): + r"""The Polaris Iceberg catalog. + + Attributes: + uri (str): + Required. The Polaris uri. + polaris_catalog (str): + Required. The catalog name within Polaris. + client_id (str): + Required. The Polaris client ID. + principal_role (str): + Required. The Polaris principal role. + client_secret (str): + Optional. The Polaris client secret. + """ + + uri: str = proto.Field( + proto.STRING, + number=1, + ) + polaris_catalog: str = proto.Field( + proto.STRING, + number=2, + ) + client_id: str = proto.Field( + proto.STRING, + number=3, + ) + principal_role: str = proto.Field( + proto.STRING, + number=4, + ) + client_secret: str = proto.Field( + proto.STRING, + number=5, + ) + + +class RestIcebergCatalog(proto.Message): + r"""The REST Iceberg catalog. + + Attributes: + uri (str): + Required. The REST uri. + properties (str): + Optional. The base64 encoded content of the + configuration file containing additional + properties for the REST catalog. + """ + + uri: str = proto.Field( + proto.STRING, + number=1, + ) + properties: str = proto.Field( + proto.STRING, + number=2, + ) + + +class IcebergCatalog(proto.Message): + r"""The Iceberg catalog details. + + 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: + glue_iceberg_catalog (google.cloud.oracledatabase_v1.types.GlueIcebergCatalog): + The Glue Iceberg catalog. + + This field is a member of `oneof`_ ``catalog_details``. + nessie_iceberg_catalog (google.cloud.oracledatabase_v1.types.NessieIcebergCatalog): + The Nessie Iceberg catalog. + + This field is a member of `oneof`_ ``catalog_details``. + polaris_iceberg_catalog (google.cloud.oracledatabase_v1.types.PolarisIcebergCatalog): + The Polaris Iceberg catalog. + + This field is a member of `oneof`_ ``catalog_details``. + rest_iceberg_catalog (google.cloud.oracledatabase_v1.types.RestIcebergCatalog): + The REST Iceberg catalog. + + This field is a member of `oneof`_ ``catalog_details``. + catalog_type (google.cloud.oracledatabase_v1.types.IcebergCatalog.CatalogType): + Required. The type of Iceberg catalog. + """ + + class CatalogType(proto.Enum): + r"""The type of Iceberg catalog. + + Values: + CATALOG_TYPE_UNSPECIFIED (0): + Catalog type not specified. + GLUE (1): + Glue catalog. + HADOOP (2): + Hadoop catalog. + NESSIE (3): + Nessie catalog. + POLARIS (4): + Polaris catalog. + REST (5): + REST catalog. + """ + + CATALOG_TYPE_UNSPECIFIED = 0 + GLUE = 1 + HADOOP = 2 + NESSIE = 3 + POLARIS = 4 + REST = 5 + + glue_iceberg_catalog: "GlueIcebergCatalog" = proto.Field( + proto.MESSAGE, + number=1, + oneof="catalog_details", + message="GlueIcebergCatalog", + ) + nessie_iceberg_catalog: "NessieIcebergCatalog" = proto.Field( + proto.MESSAGE, + number=3, + oneof="catalog_details", + message="NessieIcebergCatalog", + ) + polaris_iceberg_catalog: "PolarisIcebergCatalog" = proto.Field( + proto.MESSAGE, + number=4, + oneof="catalog_details", + message="PolarisIcebergCatalog", + ) + rest_iceberg_catalog: "RestIcebergCatalog" = proto.Field( + proto.MESSAGE, + number=5, + oneof="catalog_details", + message="RestIcebergCatalog", + ) + catalog_type: CatalogType = proto.Field( + proto.ENUM, + number=6, + enum=CatalogType, + ) + + +class AmazonS3IcebergStorage(proto.Message): + r"""The Amazon S3 Iceberg storage. + + Attributes: + scheme_type (google.cloud.oracledatabase_v1.types.AmazonS3IcebergStorage.SchemeType): + Required. The scheme type of Amazon S3. + access_key_id (str): + Required. The access key ID of Amazon S3. + region (str): + Required. The region of Amazon S3. + bucket (str): + Required. The bucket of Amazon S3. + endpoint (str): + Optional. The endpoint of Amazon S3. + secret_access_key_secret (str): + Optional. The secret access key of Amazon S3. + """ + + class SchemeType(proto.Enum): + r"""Enum for scheme type of Amazon S3. + + Values: + SCHEME_TYPE_UNSPECIFIED (0): + Scheme type not specified. + S3 (1): + S3 scheme. + S3A (2): + S3A scheme. + """ + + SCHEME_TYPE_UNSPECIFIED = 0 + S3 = 1 + S3A = 2 + + scheme_type: SchemeType = proto.Field( + proto.ENUM, + number=1, + enum=SchemeType, + ) + access_key_id: str = proto.Field( + proto.STRING, + number=2, + ) + region: str = proto.Field( + proto.STRING, + number=3, + ) + bucket: str = proto.Field( + proto.STRING, + number=4, + ) + endpoint: str = proto.Field( + proto.STRING, + number=5, + ) + secret_access_key_secret: str = proto.Field( + proto.STRING, + number=6, + ) + + +class GoogleCloudStorageIcebergStorage(proto.Message): + r"""The Google Cloud Storage Iceberg storage. + + Attributes: + bucket (str): + Required. The bucket of Google Cloud Storage. + project_id (str): + Required. The project ID of Google Cloud + Storage. + service_account_key_file (str): + Optional. The base64 encoded content of the + service account key file of Google Cloud + Storage. + """ + + bucket: str = proto.Field( + proto.STRING, + number=1, + ) + project_id: str = proto.Field( + proto.STRING, + number=2, + ) + service_account_key_file: str = proto.Field( + proto.STRING, + number=3, + ) + + +class AzureDataLakeStorageIcebergStorage(proto.Message): + r"""The Azure Data Lake Storage Iceberg storage. + + Attributes: + azure_account (str): + Required. The account of Azure Data Lake + Storage. + container (str): + Required. The container of Azure Data Lake + Storage. + account_key_secret (str): + Optional. The account key of Azure Data Lake + Storage. + endpoint (str): + Optional. The endpoint of Azure Data Lake + Storage. + """ + + azure_account: str = proto.Field( + proto.STRING, + number=1, + ) + container: str = proto.Field( + proto.STRING, + number=2, + ) + account_key_secret: str = proto.Field( + proto.STRING, + number=3, + ) + endpoint: str = proto.Field( + proto.STRING, + number=4, + ) + + +class IcebergStorage(proto.Message): + r"""The Iceberg storage details. + + 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: + amazon_s3_iceberg_storage (google.cloud.oracledatabase_v1.types.AmazonS3IcebergStorage): + The Amazon S3 Iceberg storage. + + This field is a member of `oneof`_ ``storage_details``. + google_cloud_storage_iceberg_storage (google.cloud.oracledatabase_v1.types.GoogleCloudStorageIcebergStorage): + The Google Cloud Storage Iceberg storage. + + This field is a member of `oneof`_ ``storage_details``. + azure_data_lake_storage_iceberg_storage (google.cloud.oracledatabase_v1.types.AzureDataLakeStorageIcebergStorage): + The Azure Data Lake Storage Iceberg storage. + + This field is a member of `oneof`_ ``storage_details``. + storage_type (google.cloud.oracledatabase_v1.types.IcebergStorage.StorageType): + Required. The type of Iceberg storage. + """ + + class StorageType(proto.Enum): + r"""The type of Iceberg storage. + + Values: + STORAGE_TYPE_UNSPECIFIED (0): + Storage type not specified. + AMAZON_S3 (1): + Amazon S3 storage. + GOOGLE_CLOUD_STORAGE (2): + Google Cloud Storage storage. + AZURE_DATA_LAKE_STORAGE (3): + Azure Data Lake Storage storage. + """ + + STORAGE_TYPE_UNSPECIFIED = 0 + AMAZON_S3 = 1 + GOOGLE_CLOUD_STORAGE = 2 + AZURE_DATA_LAKE_STORAGE = 3 + + amazon_s3_iceberg_storage: "AmazonS3IcebergStorage" = proto.Field( + proto.MESSAGE, + number=1, + oneof="storage_details", + message="AmazonS3IcebergStorage", + ) + google_cloud_storage_iceberg_storage: "GoogleCloudStorageIcebergStorage" = ( + proto.Field( + proto.MESSAGE, + number=2, + oneof="storage_details", + message="GoogleCloudStorageIcebergStorage", + ) + ) + azure_data_lake_storage_iceberg_storage: "AzureDataLakeStorageIcebergStorage" = ( + proto.Field( + proto.MESSAGE, + number=3, + oneof="storage_details", + message="AzureDataLakeStorageIcebergStorage", + ) + ) + storage_type: StorageType = proto.Field( + proto.ENUM, + number=4, + enum=StorageType, + ) + + +class GoldengateIcebergConnectionProperties(proto.Message): + r"""The properties of GoldengateIcebergConnection. + + Attributes: + technology_type (str): + Required. The technology type of Iceberg + connection. + catalog (google.cloud.oracledatabase_v1.types.IcebergCatalog): + Required. The Iceberg catalog. + storage (google.cloud.oracledatabase_v1.types.IcebergStorage): + Required. The Iceberg storage. + """ + + technology_type: str = proto.Field( + proto.STRING, + number=1, + ) + catalog: "IcebergCatalog" = proto.Field( + proto.MESSAGE, + number=2, + message="IcebergCatalog", + ) + storage: "IcebergStorage" = proto.Field( + proto.MESSAGE, + number=3, + message="IcebergStorage", + ) + + +class CreateGoldengateConnectionRequest(proto.Message): + r"""The request for ``GoldengateConnection.Create``. + + Attributes: + parent (str): + Required. The value for parent of the + GoldengateConnection in the following format: + projects/{project}/locations/{location}. + goldengate_connection_id (str): + Required. The ID of the GoldengateConnection to create. This + value is restricted to + (^\ `a-z <[a-z0-9-]{0,61}[a-z0-9]>`__?$) and must be a + maximum of 63 characters in length. The value must start + with a letter and end with a letter or a number. + goldengate_connection (google.cloud.oracledatabase_v1.types.GoldengateConnection): + Required. The resource being created. + request_id (str): + Optional. An optional request ID to identify + requests. Specify a unique request ID so that if + you must retry your request, the server will + know to ignore the request if it has already + been completed. The server will guarantee that + for at least 60 minutes since the first request. + + For example, consider a situation where you make + an initial request and the request times out. If + you make the request again with the same request + ID, the server can check if original operation + with the same request ID was received, and if + so, will ignore the second request. This + prevents clients from accidentally creating + duplicate commitments. + + The request ID must be a valid UUID with the + exception that zero UUID is not supported + (00000000-0000-0000-0000-000000000000). + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + goldengate_connection_id: str = proto.Field( + proto.STRING, + number=2, + ) + goldengate_connection: "GoldengateConnection" = proto.Field( + proto.MESSAGE, + number=3, + message="GoldengateConnection", + ) + request_id: str = proto.Field( + proto.STRING, + number=4, + ) + + +class DeleteGoldengateConnectionRequest(proto.Message): + r"""The request for ``GoldengateConnection.Delete``. + + Attributes: + name (str): + Required. The name of the GoldengateConnection in the + following format: + projects/{project}/locations/{location}/goldengateConnections/{goldengate_connection}. + request_id (str): + Optional. An optional ID to identify the + request. This value is used to identify + duplicate requests. If you make a request with + the same request ID and the original request is + still in progress or completed, the server + ignores the second request. This prevents + clients from accidentally creating duplicate + commitments. + + The request ID must be a valid UUID with the + exception that zero UUID is not supported + (00000000-0000-0000-0000-000000000000). + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + request_id: str = proto.Field( + proto.STRING, + number=2, + ) + + +class GetGoldengateConnectionRequest(proto.Message): + r"""The request for ``GoldengateConnection.Get``. + + Attributes: + name (str): + Required. The name of the GoldengateConnection in the + following format: + projects/{project}/locations/{location}/goldengateConnections/{goldengate_connection}. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListGoldengateConnectionsRequest(proto.Message): + r"""The request for ``GoldengateConnection.List``. + + Attributes: + parent (str): + Required. The parent value for + GoldengateConnections in the following format: + projects/{project}/locations/{location}. + page_size (int): + Optional. The maximum number of items to + return. If unspecified, at most 50 + GoldengateConnections will be returned. The + maximum value is 1000; values above 1000 will be + coerced to 1000. + page_token (str): + Optional. A page token, received from a + previous ListGoldengateConnections call. Provide + this to retrieve the subsequent page. + filter (str): + Optional. An expression for filtering the + results of the request. + order_by (str): + Optional. An expression for ordering the + results of the request. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + order_by: str = proto.Field( + proto.STRING, + number=5, + ) + + +class ListGoldengateConnectionsResponse(proto.Message): + r"""The response for ``GoldengateConnection.List``. + + Attributes: + goldengate_connections (MutableSequence[google.cloud.oracledatabase_v1.types.GoldengateConnection]): + The list of GoldengateConnections. + next_page_token (str): + A token identifying a page of results the + server should return. + unreachable (MutableSequence[str]): + Optional. Locations that could not be + reached. + """ + + @property + def raw_page(self): + return self + + goldengate_connections: MutableSequence["GoldengateConnection"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=1, + message="GoldengateConnection", + ) + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + unreachable: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + + +class NameValuePair(proto.Message): + r"""A name-value pair representing an attribute entry usable in a + list of attributes. + + Attributes: + key (str): + Required. The name of the property entry. + value (str): + Required. The value of the property entry. + """ + + key: str = proto.Field( + proto.STRING, + number=1, + ) + value: str = proto.Field( + proto.STRING, + number=2, + ) + + +class KafkaBootstrapServer(proto.Message): + r"""Represents a Kafka bootstrap server with host name, optional + port defaults to 9092, and an optional private ip. + + Attributes: + host (str): + Required. The name or address of a host. + port (int): + Optional. The port of an endpoint usually + specified for a connection. + private_ip_address (str): + Optional. The private IP address of the + connection's endpoint in the customer's VCN, + typically a database endpoint or a big data + endpoint (e.g. Kafka bootstrap server). In case + the privateIp is provided, the subnetId must + also be provided. In case the privateIp (and the + subnetId) is not provided it is assumed the + datasource is publicly accessible. In case the + connection is accessible only privately, the + lack of privateIp will result in not being able + to access the connection. + """ + + host: str = proto.Field( + proto.STRING, + number=1, + ) + port: int = proto.Field( + proto.INT32, + number=2, + ) + private_ip_address: str = proto.Field( + proto.STRING, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/goldengate_connection_assignment.py b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/goldengate_connection_assignment.py new file mode 100644 index 000000000000..723c9718ac94 --- /dev/null +++ b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/goldengate_connection_assignment.py @@ -0,0 +1,496 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.oracledatabase.v1", + manifest={ + "GoldengateConnectionAssignment", + "GoldengateConnectionAssignmentProperties", + "ListGoldengateConnectionAssignmentsRequest", + "ListGoldengateConnectionAssignmentsResponse", + "GetGoldengateConnectionAssignmentRequest", + "CreateGoldengateConnectionAssignmentRequest", + "TestGoldengateConnectionAssignmentRequest", + "TestConnectionAssignmentError", + "TestGoldengateConnectionAssignmentResponse", + "DeleteGoldengateConnectionAssignmentRequest", + }, +) + + +class GoldengateConnectionAssignment(proto.Message): + r"""Represents the metadata of a Goldengate Connection + Assignment. + + Attributes: + name (str): + Identifier. The name of the GoldengateConnectionAssignment + resource in the following format: + projects/{project}/locations/{region}/goldengateConnectionAssignments/{goldengate_connection_assignment} + properties (google.cloud.oracledatabase_v1.types.GoldengateConnectionAssignmentProperties): + Required. The properties of the + GoldengateConnectionAssignment. + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time when the connection + assignment was created. + labels (MutableMapping[str, str]): + Optional. The labels or tags associated with + the GoldengateConnectionAssignment. + display_name (str): + Optional. The display name for the + GoldengateConnectionAssignment. + entitlement_id (str): + Output only. The OCID of the entitlement + linked to this resource. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + properties: "GoldengateConnectionAssignmentProperties" = proto.Field( + proto.MESSAGE, + number=2, + message="GoldengateConnectionAssignmentProperties", + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + labels: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=4, + ) + display_name: str = proto.Field( + proto.STRING, + number=5, + ) + entitlement_id: str = proto.Field( + proto.STRING, + number=6, + ) + + +class GoldengateConnectionAssignmentProperties(proto.Message): + r"""The properties of a GoldengateConnectionAssignment. + + Attributes: + ocid (str): + Output only. The + `OCID `__ + of the connection assignment being referenced. + goldengate_connection (str): + Required. The GoldengateConnection resource to be assigned. + Format: + projects/{project}/locations/{location}/goldengateConnections/{goldengate_connection} + goldengate_deployment (str): + Required. The GoldenGateDeployment to assign the connection + to. Format: + projects/{project}/locations/{location}/goldengateDeployments/{goldengate_deployment} + alias (str): + Output only. Credential store alias. + state (google.cloud.oracledatabase_v1.types.GoldengateConnectionAssignmentProperties.State): + Output only. The lifecycle state of the + connection assignment. + """ + + class State(proto.Enum): + r"""Possible lifecycle states for connection assignments. + + Values: + STATE_UNSPECIFIED (0): + Lifecycle state is unspecified. + CREATING (1): + Connection assignment is being created. + ACTIVE (2): + Connection assignment is active. + FAILED (3): + Connection assignment failed. + UPDATING (4): + Connection assignment is being updated. + DELETING (5): + Connection assignment is being deleted. + """ + + STATE_UNSPECIFIED = 0 + CREATING = 1 + ACTIVE = 2 + FAILED = 3 + UPDATING = 4 + DELETING = 5 + + ocid: str = proto.Field( + proto.STRING, + number=1, + ) + goldengate_connection: str = proto.Field( + proto.STRING, + number=2, + ) + goldengate_deployment: str = proto.Field( + proto.STRING, + number=3, + ) + alias: str = proto.Field( + proto.STRING, + number=4, + ) + state: State = proto.Field( + proto.ENUM, + number=5, + enum=State, + ) + + +class ListGoldengateConnectionAssignmentsRequest(proto.Message): + r"""Request message for listing GoldengateConnectionAssignments. + + Attributes: + parent (str): + Required. The parent value for the + GoldengateConnectionAssignments. Format: + projects/{project}/locations/{location} + page_size (int): + Optional. The maximum number of + GoldengateConnectionAssignments to return. The + service may return fewer than this value. If + unspecified, at most 50 + GoldengateConnectionAssignments will be + returned. The maximum value is 1000; values + above 1000 will be coerced to 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListGoldengateConnectionAssignments`` call. Provide this + to retrieve the subsequent page. + + When paginating, all other parameters provided to + ``ListGoldengateConnectionAssignments`` must match the call + that provided the page token. + filter (str): + Optional. A filter expression that filters + GoldengateConnectionAssignments listed in the + response. + order_by (str): + Optional. A comma-separated list of fields to + order by, sorted in ascending order. Use "DESC" + after a field name for descending. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + order_by: str = proto.Field( + proto.STRING, + number=5, + ) + + +class ListGoldengateConnectionAssignmentsResponse(proto.Message): + r"""Response message for listing GoldengateConnectionAssignments. + + Attributes: + goldengate_connection_assignments (MutableSequence[google.cloud.oracledatabase_v1.types.GoldengateConnectionAssignment]): + The list of GoldengateConnectionAssignments. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + unreachable (MutableSequence[str]): + Unreachable locations when listing resources + across all locations using wildcard location + '-'. + """ + + @property + def raw_page(self): + return self + + goldengate_connection_assignments: MutableSequence[ + "GoldengateConnectionAssignment" + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="GoldengateConnectionAssignment", + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + unreachable: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + + +class GetGoldengateConnectionAssignmentRequest(proto.Message): + r"""Request message for getting a GoldengateConnectionAssignment. + + Attributes: + name (str): + Required. The name of the GoldengateConnectionAssignment to + retrieve. Format: + projects/{project}/locations/{location}/goldengateConnectionAssignments/{goldengate_connection_assignment} + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class CreateGoldengateConnectionAssignmentRequest(proto.Message): + r"""Request message for creating a + GoldengateConnectionAssignment. + + Attributes: + parent (str): + Required. The parent resource where this + GoldengateConnectionAssignment will be created. + Format: projects/{project}/locations/{location} + goldengate_connection_assignment_id (str): + Required. The ID of the + GoldengateConnectionAssignment to create. + goldengate_connection_assignment (google.cloud.oracledatabase_v1.types.GoldengateConnectionAssignment): + Required. The GoldengateConnectionAssignment + to create. + request_id (str): + Optional. An optional request ID to identify + requests. Specify a unique request ID so that if + you must retry your request, the server will + know to ignore the request if it has already + been completed. The server will guarantee that + for at least 60 minutes since the first request. + + For example, consider a situation where you make + an initial request and the request times out. If + you make the request again with the same request + ID, the server can check if original operation + with the same request ID was received, and if + so, will ignore the second request. This + prevents clients from accidentally creating + duplicate commitments. + + The request ID must be a valid UUID with the + exception that zero UUID is not supported + (00000000-0000-0000-0000-000000000000). + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + goldengate_connection_assignment_id: str = proto.Field( + proto.STRING, + number=2, + ) + goldengate_connection_assignment: "GoldengateConnectionAssignment" = proto.Field( + proto.MESSAGE, + number=3, + message="GoldengateConnectionAssignment", + ) + request_id: str = proto.Field( + proto.STRING, + number=4, + ) + + +class TestGoldengateConnectionAssignmentRequest(proto.Message): + r"""Request message for TestGoldengateConnectionAssignment. + + Attributes: + name (str): + Required. Name of the connection assignment for which to + test connection. + projects/{project}/locations/{region}/goldengateConnectionAssignments/{goldengate_connection_assignment} + type_ (google.cloud.oracledatabase_v1.types.TestGoldengateConnectionAssignmentRequest.TestType): + Optional. The type of the test of the + assigned connection. The only type actually + supported is DEFAULT. + """ + + class TestType(proto.Enum): + r"""The type of test to perform. + + Values: + TEST_TYPE_UNSPECIFIED (0): + The default value. This value is unused. + DEFAULT (1): + The default connection test. + """ + + TEST_TYPE_UNSPECIFIED = 0 + DEFAULT = 1 + + name: str = proto.Field( + proto.STRING, + number=1, + ) + type_: TestType = proto.Field( + proto.ENUM, + number=2, + enum=TestType, + ) + + +class TestConnectionAssignmentError(proto.Message): + r"""Error details for TestGoldengateConnectionAssignment. + + Attributes: + code (str): + A short error code that defines the error, + meant for programmatic parsing. + message (str): + A human-readable error message. + action (str): + The text describing the action required to + fix the issue. + issue (str): + The text describing the root cause of the + reported issue. + """ + + code: str = proto.Field( + proto.STRING, + number=1, + ) + message: str = proto.Field( + proto.STRING, + number=2, + ) + action: str = proto.Field( + proto.STRING, + number=3, + ) + issue: str = proto.Field( + proto.STRING, + number=4, + ) + + +class TestGoldengateConnectionAssignmentResponse(proto.Message): + r"""The result of the connectivity test performed between the + Goldengate deployment and the associated database / service. + + Attributes: + result_type (google.cloud.oracledatabase_v1.types.TestGoldengateConnectionAssignmentResponse.ResultType): + Type of the result i.e. Success, Failure or + Timeout. + error (google.cloud.oracledatabase_v1.types.TestConnectionAssignmentError): + Error details if test connection failed. + errors (MutableSequence[google.cloud.oracledatabase_v1.types.TestConnectionAssignmentError]): + List of test connection assignment error + objects. + """ + + class ResultType(proto.Enum): + r"""Type of the result. + + Values: + RESULT_TYPE_UNSPECIFIED (0): + Result type is unspecified. + SUCCEEDED (1): + Test connection succeeded. + FAILED (2): + Test connection failed. + TIMED_OUT (3): + Test connection timed out. + """ + + RESULT_TYPE_UNSPECIFIED = 0 + SUCCEEDED = 1 + FAILED = 2 + TIMED_OUT = 3 + + result_type: ResultType = proto.Field( + proto.ENUM, + number=1, + enum=ResultType, + ) + error: "TestConnectionAssignmentError" = proto.Field( + proto.MESSAGE, + number=2, + message="TestConnectionAssignmentError", + ) + errors: MutableSequence["TestConnectionAssignmentError"] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message="TestConnectionAssignmentError", + ) + + +class DeleteGoldengateConnectionAssignmentRequest(proto.Message): + r"""Request message for deleting a + GoldengateConnectionAssignment. + + Attributes: + name (str): + Required. The name of the GoldengateConnectionAssignment to + delete. Format: + projects/{project}/locations/{location}/goldengateConnectionAssignments/{goldengate_connection_assignment} + request_id (str): + Optional. An optional request ID to identify + requests. Specify a unique request ID so that if + you must retry your request, the server will + know to ignore the request if it has already + been completed. The server will guarantee that + for at least 60 minutes after the first request. + + For example, consider a situation where you make + an initial request and the request times out. If + you make the request again with the same request + ID, the server can check if original operation + with the same request ID was received, and if + so, will ignore the second request. This + prevents clients from accidentally creating + duplicate commitments. + + The request ID must be a valid UUID with the + exception that zero UUID is not supported + (00000000-0000-0000-0000-000000000000). + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + request_id: str = proto.Field( + proto.STRING, + number=2, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/goldengate_connection_type.py b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/goldengate_connection_type.py new file mode 100644 index 000000000000..9509e3f6e6ac --- /dev/null +++ b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/goldengate_connection_type.py @@ -0,0 +1,266 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.oracledatabase.v1", + manifest={ + "GoldengateConnectionType", + "GetGoldengateConnectionTypeRequest", + "ListGoldengateConnectionTypesRequest", + "ListGoldengateConnectionTypesResponse", + }, +) + + +class GoldengateConnectionType(proto.Message): + r"""Details of the Goldengate Connection Type resource. + + Attributes: + name (str): + Identifier. The name of the Goldengate Connection Type + resource with the format: + projects/{project}/locations/{region}/goldengateConnectionTypes/{goldengate_connection_type} + connection_type (google.cloud.oracledatabase_v1.types.GoldengateConnectionType.ConnectionType): + Output only. The connection type of the + Goldengate Connection Type resource. + technology_types (MutableSequence[str]): + Output only. The technology type of the + Goldengate Connection Type resource. + """ + + class ConnectionType(proto.Enum): + r"""The connection type of the Goldengate Connection Type + resource. + + Values: + CONNECTION_TYPE_UNSPECIFIED (0): + Default unspecified value. + GOLDENGATE (1): + Goldengate Connection Type category is + GOLDENGATE. + KAFKA (2): + Goldengate Connection Type category is KAFKA. + KAFKA_SCHEMA_REGISTRY (3): + Goldengate Connection Type category is + KAFKA_SCHEMA_REGISTRY. + MYSQL (4): + Goldengate Connection Type category is MYSQL. + JAVA_MESSAGE_SERVICE (5): + Goldengate Connection Type category is JAVA_MESSAGE_SERVICE. + MICROSOFT_SQLSERVER (6): + Goldengate Connection Type category is MICROSOFT_SQLSERVER. + OCI_OBJECT_STORAGE (7): + Goldengate Connection Type category is OCI_OBJECT_STORAGE. + ORACLE (8): + Goldengate Connection Type category is + ORACLE. + AZURE_DATA_LAKE_STORAGE (9): + Goldengate Connection Type category is + AZURE_DATA_LAKE_STORAGE. + POSTGRESQL (10): + Goldengate Connection Type category is + POSTGRESQL. + AZURE_SYNAPSE_ANALYTICS (11): + Goldengate Connection Type category is + AZURE_SYNAPSE_ANALYTICS. + SNOWFLAKE (12): + Goldengate Connection Type category is + SNOWFLAKE. + AMAZON_S3 (13): + Goldengate Connection Type category is AMAZON_S3. + HDFS (14): + Goldengate Connection Type category is HDFS. + ORACLE_AI_DATA_PLATFORM (15): + Goldengate Connection Type category is + ORACLE_AI_DATA_PLATFORM. + ORACLE_NOSQL (16): + Goldengate Connection Type category is ORACLE_NOSQL. + MONGODB (17): + Goldengate Connection Type category is + MONGODB. + AMAZON_KINESIS (18): + Goldengate Connection Type category is AMAZON_KINESIS. + AMAZON_REDSHIFT (19): + Goldengate Connection Type category is AMAZON_REDSHIFT. + DB2 (20): + Goldengate Connection Type category is DB2. + REDIS (21): + Goldengate Connection Type category is REDIS. + ELASTICSEARCH (22): + Goldengate Connection Type category is + ELASTICSEARCH. + GENERIC (23): + Goldengate Connection Type category is + GENERIC. + GOOGLE_CLOUD_STORAGE (24): + Goldengate Connection Type category is GOOGLE_CLOUD_STORAGE. + GOOGLE_BIGQUERY (25): + Goldengate Connection Type category is GOOGLE_BIGQUERY. + DATABRICKS (26): + Goldengate Connection Type category is + DATABRICKS. + GOOGLE_PUBSUB (27): + Goldengate Connection Type category is GOOGLE_PUBSUB. + MICROSOFT_FABRIC (28): + Goldengate Connection Type category is MICROSOFT_FABRIC. + ICEBERG (29): + Goldengate Connection Type category is + ICEBERG. + """ + + CONNECTION_TYPE_UNSPECIFIED = 0 + GOLDENGATE = 1 + KAFKA = 2 + KAFKA_SCHEMA_REGISTRY = 3 + MYSQL = 4 + JAVA_MESSAGE_SERVICE = 5 + MICROSOFT_SQLSERVER = 6 + OCI_OBJECT_STORAGE = 7 + ORACLE = 8 + AZURE_DATA_LAKE_STORAGE = 9 + POSTGRESQL = 10 + AZURE_SYNAPSE_ANALYTICS = 11 + SNOWFLAKE = 12 + AMAZON_S3 = 13 + HDFS = 14 + ORACLE_AI_DATA_PLATFORM = 15 + ORACLE_NOSQL = 16 + MONGODB = 17 + AMAZON_KINESIS = 18 + AMAZON_REDSHIFT = 19 + DB2 = 20 + REDIS = 21 + ELASTICSEARCH = 22 + GENERIC = 23 + GOOGLE_CLOUD_STORAGE = 24 + GOOGLE_BIGQUERY = 25 + DATABRICKS = 26 + GOOGLE_PUBSUB = 27 + MICROSOFT_FABRIC = 28 + ICEBERG = 29 + + name: str = proto.Field( + proto.STRING, + number=1, + ) + connection_type: ConnectionType = proto.Field( + proto.ENUM, + number=2, + enum=ConnectionType, + ) + technology_types: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + + +class GetGoldengateConnectionTypeRequest(proto.Message): + r"""Message for getting a GoldengateConnectionType. + + Attributes: + name (str): + Required. Name of the resource in the format: + projects/{project}/locations/{location}/goldengateConnectionTypes/{goldengate_connection_type} + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListGoldengateConnectionTypesRequest(proto.Message): + r"""Message for listing GoldengateConnectionTypes. + + Attributes: + parent (str): + Required. Parent value for + ListGoldengateConnectionTypesRequest Format: + projects/{project}/locations/{location} + page_size (int): + Optional. Requested page size. Server may + return fewer items than requested. If + unspecified, server will pick an appropriate + default. + page_token (str): + Optional. A token identifying a page of + results the server should return. + filter (str): + Optional. An expression for filtering the results of the + request. The connection_type field must be specified in the + format: ``connection_type="ORACLE"``. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + + +class ListGoldengateConnectionTypesResponse(proto.Message): + r"""Message for response to listing GoldengateConnectionTypes + + Attributes: + goldengate_connection_types (MutableSequence[google.cloud.oracledatabase_v1.types.GoldengateConnectionType]): + The list of GoldengateConnectionType + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + unreachable (MutableSequence[str]): + Unordered list. Locations that could not be + reached. + """ + + @property + def raw_page(self): + return self + + goldengate_connection_types: MutableSequence["GoldengateConnectionType"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=1, + message="GoldengateConnectionType", + ) + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + unreachable: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/goldengate_deployment.py b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/goldengate_deployment.py new file mode 100644 index 000000000000..fa63055ca2e2 --- /dev/null +++ b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/goldengate_deployment.py @@ -0,0 +1,1270 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore +import google.type.dayofweek_pb2 as dayofweek_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.oracledatabase.v1", + manifest={ + "GoldengateDeployment", + "GoldengateDeploymentProperties", + "GoldengateOggDeployment", + "GoldengateMaintenanceWindow", + "GoldengateMaintenanceConfig", + "DeploymentDiagnosticData", + "GoldengateBackupSchedule", + "IngressIp", + "GoldengateDeploymentLock", + "GoldengatePlacement", + "GoldengateGroupToRolesMapping", + "CreateGoldengateDeploymentRequest", + "DeleteGoldengateDeploymentRequest", + "GetGoldengateDeploymentRequest", + "ListGoldengateDeploymentsRequest", + "ListGoldengateDeploymentsResponse", + "StopGoldengateDeploymentRequest", + "StartGoldengateDeploymentRequest", + }, +) + + +class GoldengateDeployment(proto.Message): + r"""GoldengateDeployment Goldengate Deployment resource model. + + Attributes: + name (str): + Identifier. The name of the GoldengateDeployment resource in + the following format: + projects/{project}/locations/{region}/goldengateDeployments/{goldengate_deployment} + properties (google.cloud.oracledatabase_v1.types.GoldengateDeploymentProperties): + Required. The properties of the + GoldengateDeployment. + gcp_oracle_zone (str): + Optional. The GCP Oracle zone where Oracle + GoldengateDeployment is hosted. Example: + us-east4-b-r2. If not specified, the system will + pick a zone based on availability. + labels (MutableMapping[str, str]): + Optional. The labels or tags associated with + the GoldengateDeployment. + odb_network (str): + Optional. The name of the OdbNetwork + associated with the GoldengateDeployment. + odb_subnet (str): + Required. The name of the OdbSubnet + associated with the GoldengateDeployment for IP + allocation. + entitlement_id (str): + Output only. The ID of the subscription + entitlement associated with the + GoldengateDeployment + display_name (str): + Required. The display name for the + GoldengateDeployment. + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The date and time that the + GoldengateDeployment was created. + oci_url (str): + Output only. HTTPS link to OCI resources + exposed to Customer via UI Interface. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + properties: "GoldengateDeploymentProperties" = proto.Field( + proto.MESSAGE, + number=2, + message="GoldengateDeploymentProperties", + ) + gcp_oracle_zone: str = proto.Field( + proto.STRING, + number=3, + ) + labels: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=4, + ) + odb_network: str = proto.Field( + proto.STRING, + number=5, + ) + odb_subnet: str = proto.Field( + proto.STRING, + number=6, + ) + entitlement_id: str = proto.Field( + proto.STRING, + number=7, + ) + display_name: str = proto.Field( + proto.STRING, + number=8, + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=9, + message=timestamp_pb2.Timestamp, + ) + oci_url: str = proto.Field( + proto.STRING, + number=10, + ) + + +class GoldengateDeploymentProperties(proto.Message): + r"""Properties of GoldengateDeployment. + + Attributes: + ocid (str): + Output only. OCID of the + GoldengateDeployment. + lifecycle_state (google.cloud.oracledatabase_v1.types.GoldengateDeploymentProperties.GoldengateDeploymentLifecycleState): + Output only. State of the + GoldengateDeployment. + license_model (google.cloud.oracledatabase_v1.types.GoldengateDeploymentProperties.LicenseModel): + Optional. The Oracle license model that + applies to a Deployment. + environment_type (str): + Optional. The environment type of the + GoldengateDeployment. + cpu_core_count (int): + Optional. The Minimum number of OCPUs to be + made available for this Deployment. + is_auto_scaling_enabled (bool): + Optional. Indicates if auto scaling is + enabled for the Deployment's CPU core count. + description (str): + Optional. The description of the + GoldengateDeployment. + deployment_type (str): + Required. A valid Goldengate Deployment type. For a list of + supported types, use the ``ListGoldengateDeploymentTypes`` + operation. + ogg_data (google.cloud.oracledatabase_v1.types.GoldengateOggDeployment): + Required. The ogg data of the + GoldengateDeployment. + maintenance_window (google.cloud.oracledatabase_v1.types.GoldengateMaintenanceWindow): + Optional. The maintenance window of the + GoldengateDeployment. + maintenance_config (google.cloud.oracledatabase_v1.types.GoldengateMaintenanceConfig): + Optional. The maintenance configuration of + the GoldengateDeployment. + fqdn (str): + Output only. The Fully Qualified Domain Name + of the GoldengateDeployment. + lifecycle_sub_state (google.cloud.oracledatabase_v1.types.GoldengateDeploymentProperties.GoldengateDeploymentLifecycleSubState): + Output only. The lifecycle sub-state of the + GoldengateDeployment. + category (google.cloud.oracledatabase_v1.types.GoldengateDeploymentProperties.GoldengateDeploymentCategory): + Output only. The category of the + GoldengateDeployment. + deployment_backup_id (str): + Output only. The deployment backup id of the + GoldengateDeployment. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time the + GoldengateDeployment was updated. + lifecycle_details (str): + Output only. The lifecycle details of the + GoldengateDeployment. + healthy (bool): + Output only. Whether the GoldengateDeployment + is healthy. + load_balancer_subnet_id (str): + Output only. The load balancer subnet id of + the GoldengateDeployment. + load_balancer_id (str): + Output only. The load balancer id of the + GoldengateDeployment. + nsg_ids (MutableSequence[str]): + Output only. The nsg ids of the + GoldengateDeployment. + is_public (bool): + Output only. Whether the GoldengateDeployment + is public. + public_ip_address (str): + Output only. The public ip address of the + GoldengateDeployment. + private_ip_address (str): + Output only. The private ip address of the + GoldengateDeployment. + deployment_url (str): + Output only. The deployment url of the + GoldengateDeployment. + is_latest_version (bool): + Output only. Whether the GoldengateDeployment + is of the latest version. + upgrade_required_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time upgrade required of the + GoldengateDeployment. + storage_utilization_bytes (int): + Output only. The storage utilization in bytes + of the GoldengateDeployment. + is_storage_utilization_limit_exceeded (bool): + Output only. Whether storage utilization + limit is exceeded of the GoldengateDeployment. + deployment_diagnostic_data (google.cloud.oracledatabase_v1.types.DeploymentDiagnosticData): + Output only. The deployment diagnostic data + of the GoldengateDeployment. + backup_schedule (google.cloud.oracledatabase_v1.types.GoldengateBackupSchedule): + Output only. The backup schedule of the + GoldengateDeployment. + next_maintenance_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time of next maintenance of + the GoldengateDeployment. + next_maintenance_action_type (google.cloud.oracledatabase_v1.types.GoldengateDeploymentProperties.NextMaintenanceActionType): + Output only. The next maintenance action type + of the GoldengateDeployment. + next_maintenance_description (str): + Output only. The next maintenance description + of the GoldengateDeployment. + ogg_version_support_end_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time ogg version supported + until of the GoldengateDeployment. + ingress_ips (MutableSequence[google.cloud.oracledatabase_v1.types.IngressIp]): + Output only. The ingress ips of the + GoldengateDeployment. + deployment_role (google.cloud.oracledatabase_v1.types.GoldengateDeploymentProperties.GoldengateDeploymentRoleType): + Output only. The deployment role of the + GoldengateDeployment. + last_backup_schedule_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time last backup scheduled + of the GoldengateDeployment. + next_backup_schedule_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time next backup scheduled + of the GoldengateDeployment. + role_change_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time when the role of the + GoldengateDeployment was changed. + locks (MutableSequence[google.cloud.oracledatabase_v1.types.GoldengateDeploymentLock]): + Output only. The locks of the + GoldengateDeployment. + placements (MutableSequence[google.cloud.oracledatabase_v1.types.GoldengatePlacement]): + Output only. The placements of the + GoldengateDeployment. + """ + + class GoldengateDeploymentLifecycleState(proto.Enum): + r"""The various lifecycle states of the GoldengateDeployment. + + Values: + GOLDENGATE_DEPLOYMENT_LIFECYCLE_STATE_UNSPECIFIED (0): + Default unspecified value. + CREATING (1): + The deployment is being created. + UPDATING (2): + The deployment is being updated. + ACTIVE (3): + The deployment is active. + INACTIVE (4): + The deployment is inactive. + DELETING (5): + The deployment is being deleted. + DELETED (6): + The deployment is deleted. + FAILED (7): + The deployment failed. + NEEDS_ATTENTION (8): + The deployment needs attention. + IN_PROGRESS (9): + The deployment is in progress. + CANCELLING (10): + The deployment is canceling. + CANCELLED (11): + The deployment is canceled. + SUCCEEDED (12): + The deployment succeeded. + WAITING (13): + The deployment is waiting. + """ + + GOLDENGATE_DEPLOYMENT_LIFECYCLE_STATE_UNSPECIFIED = 0 + CREATING = 1 + UPDATING = 2 + ACTIVE = 3 + INACTIVE = 4 + DELETING = 5 + DELETED = 6 + FAILED = 7 + NEEDS_ATTENTION = 8 + IN_PROGRESS = 9 + CANCELLING = 10 + CANCELLED = 11 + SUCCEEDED = 12 + WAITING = 13 + + class LicenseModel(proto.Enum): + r"""The license model of the GoldengateDeployment. + + Values: + LICENSE_MODEL_UNSPECIFIED (0): + The license model is unspecified. + LICENSE_INCLUDED (1): + The license model is included. + BRING_YOUR_OWN_LICENSE (2): + The license model is bring your own license. + """ + + LICENSE_MODEL_UNSPECIFIED = 0 + LICENSE_INCLUDED = 1 + BRING_YOUR_OWN_LICENSE = 2 + + class GoldengateDeploymentLifecycleSubState(proto.Enum): + r"""The various lifecycle sub-states of the GoldengateDeployment. + + Values: + GOLDENGATE_DEPLOYMENT_LIFECYCLE_SUB_STATE_UNSPECIFIED (0): + The lifecycle sub-state is unspecified. + RECOVERING (1): + The deployment is recovering. + STARTING (2): + The deployment is starting. + STOPPING (3): + The deployment is stopping. + MOVING (4): + The deployment is moving. + UPGRADING (5): + The deployment is upgrading. + RESTORING (6): + The deployment is restoring. + BACKING_UP (7): + The deployment is backing up. + ROLLING_BACK (8): + The deployment is rolling back. + """ + + GOLDENGATE_DEPLOYMENT_LIFECYCLE_SUB_STATE_UNSPECIFIED = 0 + RECOVERING = 1 + STARTING = 2 + STOPPING = 3 + MOVING = 4 + UPGRADING = 5 + RESTORING = 6 + BACKING_UP = 7 + ROLLING_BACK = 8 + + class GoldengateDeploymentCategory(proto.Enum): + r"""The category of the GoldengateDeployment. + + Values: + GOLDENGATE_DEPLOYMENT_CATEGORY_UNSPECIFIED (0): + The category is unspecified. + DATA_REPLICATION (1): + The deployment is data replication. + DATA_TRANSFORMS (2): + The deployment is data transforms. + """ + + GOLDENGATE_DEPLOYMENT_CATEGORY_UNSPECIFIED = 0 + DATA_REPLICATION = 1 + DATA_TRANSFORMS = 2 + + class NextMaintenanceActionType(proto.Enum): + r"""The various next maintenance action types of the + GoldengateDeployment. + + Values: + NEXT_MAINTENANCE_ACTION_TYPE_UNSPECIFIED (0): + The next maintenance action type is + unspecified. + UPGRADE (1): + The next maintenance action type is upgrade. + """ + + NEXT_MAINTENANCE_ACTION_TYPE_UNSPECIFIED = 0 + UPGRADE = 1 + + class GoldengateDeploymentRoleType(proto.Enum): + r"""The deployment role type of the GoldengateDeployment. + + Values: + GOLDENGATE_DEPLOYMENT_ROLE_TYPE_UNSPECIFIED (0): + The deployment role type is unspecified. + PRIMARY (1): + The deployment role type is primary. + STANDBY (2): + The deployment role type is standby. + """ + + GOLDENGATE_DEPLOYMENT_ROLE_TYPE_UNSPECIFIED = 0 + PRIMARY = 1 + STANDBY = 2 + + ocid: str = proto.Field( + proto.STRING, + number=1, + ) + lifecycle_state: GoldengateDeploymentLifecycleState = proto.Field( + proto.ENUM, + number=2, + enum=GoldengateDeploymentLifecycleState, + ) + license_model: LicenseModel = proto.Field( + proto.ENUM, + number=3, + enum=LicenseModel, + ) + environment_type: str = proto.Field( + proto.STRING, + number=4, + ) + cpu_core_count: int = proto.Field( + proto.INT32, + number=5, + ) + is_auto_scaling_enabled: bool = proto.Field( + proto.BOOL, + number=6, + ) + description: str = proto.Field( + proto.STRING, + number=7, + ) + deployment_type: str = proto.Field( + proto.STRING, + number=8, + ) + ogg_data: "GoldengateOggDeployment" = proto.Field( + proto.MESSAGE, + number=9, + message="GoldengateOggDeployment", + ) + maintenance_window: "GoldengateMaintenanceWindow" = proto.Field( + proto.MESSAGE, + number=10, + message="GoldengateMaintenanceWindow", + ) + maintenance_config: "GoldengateMaintenanceConfig" = proto.Field( + proto.MESSAGE, + number=11, + message="GoldengateMaintenanceConfig", + ) + fqdn: str = proto.Field( + proto.STRING, + number=12, + ) + lifecycle_sub_state: GoldengateDeploymentLifecycleSubState = proto.Field( + proto.ENUM, + number=13, + enum=GoldengateDeploymentLifecycleSubState, + ) + category: GoldengateDeploymentCategory = proto.Field( + proto.ENUM, + number=14, + enum=GoldengateDeploymentCategory, + ) + deployment_backup_id: str = proto.Field( + proto.STRING, + number=15, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=16, + message=timestamp_pb2.Timestamp, + ) + lifecycle_details: str = proto.Field( + proto.STRING, + number=17, + ) + healthy: bool = proto.Field( + proto.BOOL, + number=18, + ) + load_balancer_subnet_id: str = proto.Field( + proto.STRING, + number=19, + ) + load_balancer_id: str = proto.Field( + proto.STRING, + number=20, + ) + nsg_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=21, + ) + is_public: bool = proto.Field( + proto.BOOL, + number=22, + ) + public_ip_address: str = proto.Field( + proto.STRING, + number=23, + ) + private_ip_address: str = proto.Field( + proto.STRING, + number=24, + ) + deployment_url: str = proto.Field( + proto.STRING, + number=25, + ) + is_latest_version: bool = proto.Field( + proto.BOOL, + number=26, + ) + upgrade_required_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=27, + message=timestamp_pb2.Timestamp, + ) + storage_utilization_bytes: int = proto.Field( + proto.INT64, + number=28, + ) + is_storage_utilization_limit_exceeded: bool = proto.Field( + proto.BOOL, + number=29, + ) + deployment_diagnostic_data: "DeploymentDiagnosticData" = proto.Field( + proto.MESSAGE, + number=30, + message="DeploymentDiagnosticData", + ) + backup_schedule: "GoldengateBackupSchedule" = proto.Field( + proto.MESSAGE, + number=31, + message="GoldengateBackupSchedule", + ) + next_maintenance_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=32, + message=timestamp_pb2.Timestamp, + ) + next_maintenance_action_type: NextMaintenanceActionType = proto.Field( + proto.ENUM, + number=33, + enum=NextMaintenanceActionType, + ) + next_maintenance_description: str = proto.Field( + proto.STRING, + number=34, + ) + ogg_version_support_end_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=35, + message=timestamp_pb2.Timestamp, + ) + ingress_ips: MutableSequence["IngressIp"] = proto.RepeatedField( + proto.MESSAGE, + number=36, + message="IngressIp", + ) + deployment_role: GoldengateDeploymentRoleType = proto.Field( + proto.ENUM, + number=37, + enum=GoldengateDeploymentRoleType, + ) + last_backup_schedule_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=38, + message=timestamp_pb2.Timestamp, + ) + next_backup_schedule_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=39, + message=timestamp_pb2.Timestamp, + ) + role_change_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=40, + message=timestamp_pb2.Timestamp, + ) + locks: MutableSequence["GoldengateDeploymentLock"] = proto.RepeatedField( + proto.MESSAGE, + number=41, + message="GoldengateDeploymentLock", + ) + placements: MutableSequence["GoldengatePlacement"] = proto.RepeatedField( + proto.MESSAGE, + number=42, + message="GoldengatePlacement", + ) + + +class GoldengateOggDeployment(proto.Message): + r"""The Ogg data of the GoldengateDeployment. + + 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: + admin_password (str): + Optional. The Goldengate deployment console + password in plain text. + + This field is a member of `oneof`_ ``deployment_password_options``. + admin_password_secret_version (str): + Optional. Input only. The Goldengate + deployment console password secret version. + + This field is a member of `oneof`_ ``deployment_password_options``. + deployment (str): + Required. The name given to the Goldengate + service deployment. The name must be 1 to 32 + characters long, must contain only alphanumeric + characters and must start with a letter. + admin_username (str): + Required. The Goldengate deployment console + username. + ogg_version (str): + Optional. Version of OGG + certificate (str): + Output only. The certificate of the + GoldengateDeployment. + credential_store (google.cloud.oracledatabase_v1.types.GoldengateOggDeployment.CredentialStore): + Output only. The credential store of the + GoldengateDeployment. + identity_domain_id (str): + Output only. The identity domain id of the + GoldengateDeployment. + password_secret_id (str): + Output only. The password secret id of the + GoldengateDeployment. + group_roles_mapping (google.cloud.oracledatabase_v1.types.GoldengateGroupToRolesMapping): + Output only. The group to roles mapping of + the GoldengateDeployment. + """ + + class CredentialStore(proto.Enum): + r"""The credential store of the GoldengateDeployment. + + Values: + CREDENTIAL_STORE_UNSPECIFIED (0): + The credential store is unspecified. + GOLDENGATE (1): + The credential store is Goldengate. + IAM (2): + The credential store is IAM. + """ + + CREDENTIAL_STORE_UNSPECIFIED = 0 + GOLDENGATE = 1 + IAM = 2 + + admin_password: str = proto.Field( + proto.STRING, + number=3, + oneof="deployment_password_options", + ) + admin_password_secret_version: str = proto.Field( + proto.STRING, + number=10, + oneof="deployment_password_options", + ) + deployment: str = proto.Field( + proto.STRING, + number=1, + ) + admin_username: str = proto.Field( + proto.STRING, + number=2, + ) + ogg_version: str = proto.Field( + proto.STRING, + number=4, + ) + certificate: str = proto.Field( + proto.STRING, + number=5, + ) + credential_store: CredentialStore = proto.Field( + proto.ENUM, + number=6, + enum=CredentialStore, + ) + identity_domain_id: str = proto.Field( + proto.STRING, + number=7, + ) + password_secret_id: str = proto.Field( + proto.STRING, + number=8, + ) + group_roles_mapping: "GoldengateGroupToRolesMapping" = proto.Field( + proto.MESSAGE, + number=9, + message="GoldengateGroupToRolesMapping", + ) + + +class GoldengateMaintenanceWindow(proto.Message): + r"""The maintenance window of the GoldengateDeployment. + + Attributes: + day (google.type.dayofweek_pb2.DayOfWeek): + Required. Days of the week. + start_hour (int): + Required. Start hour for maintenance period. + Hour is in UTC. + """ + + day: dayofweek_pb2.DayOfWeek = proto.Field( + proto.ENUM, + number=1, + enum=dayofweek_pb2.DayOfWeek, + ) + start_hour: int = proto.Field( + proto.INT32, + number=2, + ) + + +class GoldengateMaintenanceConfig(proto.Message): + r"""The maintenance configuration of the GoldengateDeployment. + + Attributes: + is_interim_release_auto_upgrade_enabled (bool): + Optional. By default auto upgrade for interim releases are + not enabled. If auto-upgrade is enabled for interim release, + you have to specify interim_release_upgrade_period_days too. + interim_release_upgrade_period_days (int): + Optional. Defines auto upgrade period for + interim releases. This period must be shorter or + equal to bundle release upgrade period. + bundle_release_upgrade_period_days (int): + Optional. Defines auto upgrade period for + bundle releases. Manually configured period + cannot be longer than service defined period for + bundle releases. This period must be shorter or + equal to major release upgrade period. Not + passing this field during create will equate to + using the service default. + major_release_upgrade_period_days (int): + Optional. Defines auto upgrade period for + major releases. Manually configured period + cannot be longer than service defined period for + major releases. Not passing this field during + create will equate to using the service default. + security_patch_upgrade_period_days (int): + Optional. Defines auto upgrade period for + releases with security fix. Manually configured + period cannot be longer than service defined + period for security releases. Not passing this + field during create will equate to using the + service default. + """ + + is_interim_release_auto_upgrade_enabled: bool = proto.Field( + proto.BOOL, + number=1, + ) + interim_release_upgrade_period_days: int = proto.Field( + proto.INT32, + number=2, + ) + bundle_release_upgrade_period_days: int = proto.Field( + proto.INT32, + number=3, + ) + major_release_upgrade_period_days: int = proto.Field( + proto.INT32, + number=4, + ) + security_patch_upgrade_period_days: int = proto.Field( + proto.INT32, + number=5, + ) + + +class DeploymentDiagnosticData(proto.Message): + r"""The deployment diagnostic data. + + Attributes: + namespace (str): + Output only. The namespace name. + bucket (str): + Output only. The bucket name. + object_ (str): + Output only. The object name. + diagnostic_state (google.cloud.oracledatabase_v1.types.DeploymentDiagnosticData.DiagnosticState): + Output only. The diagnostic state. + diagnostic_start_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time diagnostic start. + diagnostic_end_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time diagnostic end. + """ + + class DiagnosticState(proto.Enum): + r"""The possible states of the diagnostic data. + + Values: + DIAGNOSTIC_STATE_UNSPECIFIED (0): + The diagnostic state is unspecified. + IN_PROGRESS (1): + The diagnostic is in progress. + SUCCEEDED (2): + The diagnostic completed successfully. + FAILED (3): + The diagnostic failed. + """ + + DIAGNOSTIC_STATE_UNSPECIFIED = 0 + IN_PROGRESS = 1 + SUCCEEDED = 2 + FAILED = 3 + + namespace: str = proto.Field( + proto.STRING, + number=1, + ) + bucket: str = proto.Field( + proto.STRING, + number=2, + ) + object_: str = proto.Field( + proto.STRING, + number=3, + ) + diagnostic_state: DiagnosticState = proto.Field( + proto.ENUM, + number=4, + enum=DiagnosticState, + ) + diagnostic_start_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + diagnostic_end_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=6, + message=timestamp_pb2.Timestamp, + ) + + +class GoldengateBackupSchedule(proto.Message): + r"""The backup schedule of the GoldengateDeployment. + + Attributes: + bucket (str): + Output only. The bucket name. + compartment_id (str): + Output only. The compartment id. + frequency_backup_scheduled (google.cloud.oracledatabase_v1.types.GoldengateBackupSchedule.FrequencyBackupScheduled): + Output only. The frequency backup scheduled. + metadata_only (bool): + Output only. If metadata only. + namespace (str): + Output only. The namespace name. + backup_scheduled_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The timestamp of when the backup + was scheduled. + """ + + class FrequencyBackupScheduled(proto.Enum): + r"""Enum for frequency backup scheduled. + + Values: + FREQUENCY_BACKUP_SCHEDULED_UNSPECIFIED (0): + The frequency backup scheduled is + unspecified. + DAILY (1): + The frequency backup scheduled is daily. + WEEKLY (2): + The frequency backup scheduled is weekly. + MONTHLY (3): + The frequency backup scheduled is monthly. + """ + + FREQUENCY_BACKUP_SCHEDULED_UNSPECIFIED = 0 + DAILY = 1 + WEEKLY = 2 + MONTHLY = 3 + + bucket: str = proto.Field( + proto.STRING, + number=1, + ) + compartment_id: str = proto.Field( + proto.STRING, + number=2, + ) + frequency_backup_scheduled: FrequencyBackupScheduled = proto.Field( + proto.ENUM, + number=3, + enum=FrequencyBackupScheduled, + ) + metadata_only: bool = proto.Field( + proto.BOOL, + number=4, + ) + namespace: str = proto.Field( + proto.STRING, + number=5, + ) + backup_scheduled_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=6, + message=timestamp_pb2.Timestamp, + ) + + +class IngressIp(proto.Message): + r"""The ingress IPs of the GoldengateDeployment. + + Attributes: + ingress_ip_address (str): + Output only. The ingress IP. + """ + + ingress_ip_address: str = proto.Field( + proto.STRING, + number=1, + ) + + +class GoldengateDeploymentLock(proto.Message): + r"""The lock of the GoldengateDeployment. + + Attributes: + type_ (google.cloud.oracledatabase_v1.types.GoldengateDeploymentLock.LockType): + Output only. The type of lock. + compartment_id (str): + Output only. The compartment id. + related_resource_id (str): + Output only. The related resource id. + message (str): + Output only. The message. + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time created. + """ + + class LockType(proto.Enum): + r"""The type of lock. + + Values: + LOCK_TYPE_UNSPECIFIED (0): + The lock type is unspecified. + FULL (1): + The lock type is full. + DELETE (2): + The lock type is delete. + """ + + LOCK_TYPE_UNSPECIFIED = 0 + FULL = 1 + DELETE = 2 + + type_: LockType = proto.Field( + proto.ENUM, + number=1, + enum=LockType, + ) + compartment_id: str = proto.Field( + proto.STRING, + number=2, + ) + related_resource_id: str = proto.Field( + proto.STRING, + number=3, + ) + message: str = proto.Field( + proto.STRING, + number=4, + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + + +class GoldengatePlacement(proto.Message): + r"""The placement of the GoldengateDeployment. + + Attributes: + availability_domain (str): + Output only. The availability domain. + fault_domain (str): + Output only. The fault domain. + """ + + availability_domain: str = proto.Field( + proto.STRING, + number=1, + ) + fault_domain: str = proto.Field( + proto.STRING, + number=2, + ) + + +class GoldengateGroupToRolesMapping(proto.Message): + r"""The group to roles mapping of the GoldengateDeployment. + + Attributes: + security_group_id (str): + Output only. The security group id. + administrator_group_id (str): + Output only. The administrator group id. + operator_group_id (str): + Output only. The operator group id. + user_group_id (str): + Output only. The user group id. + """ + + security_group_id: str = proto.Field( + proto.STRING, + number=1, + ) + administrator_group_id: str = proto.Field( + proto.STRING, + number=2, + ) + operator_group_id: str = proto.Field( + proto.STRING, + number=3, + ) + user_group_id: str = proto.Field( + proto.STRING, + number=4, + ) + + +class CreateGoldengateDeploymentRequest(proto.Message): + r"""The request for ``GoldengateDeployment.Create``. + + Attributes: + parent (str): + Required. The value for parent of the + GoldengateDeployment in the following format: + projects/{project}/locations/{location}. + goldengate_deployment_id (str): + Required. The ID of the GoldengateDeployment to create. This + value is restricted to + (^\ `a-z <[a-z0-9-]{0,61}[a-z0-9]>`__?$) and must be a + maximum of 63 characters in length. The value must start + with a letter and end with a letter or a number. + goldengate_deployment (google.cloud.oracledatabase_v1.types.GoldengateDeployment): + Required. The resource being created. + request_id (str): + Optional. An optional request ID to identify + requests. Specify a unique request ID so that if + you must retry your request, the server will + know to ignore the request if it has already + been completed. The server will guarantee that + for at least 60 minutes since the first request. + + For example, consider a situation where you make + an initial request and the request times out. If + you make the request again with the same request + ID, the server can check if original operation + with the same request ID was received, and if + so, will ignore the second request. This + prevents clients from accidentally creating + duplicate commitments. + + The request ID must be a valid UUID with the + exception that zero UUID is not supported + (00000000-0000-0000-0000-000000000000). + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + goldengate_deployment_id: str = proto.Field( + proto.STRING, + number=2, + ) + goldengate_deployment: "GoldengateDeployment" = proto.Field( + proto.MESSAGE, + number=3, + message="GoldengateDeployment", + ) + request_id: str = proto.Field( + proto.STRING, + number=4, + ) + + +class DeleteGoldengateDeploymentRequest(proto.Message): + r"""The request for ``GoldengateDeployment.Delete``. + + Attributes: + name (str): + Required. The name of the GoldengateDeployment in the + following format: + projects/{project}/locations/{location}/goldengateDeployments/{goldengate_deployment}. + request_id (str): + Optional. An optional ID to identify the + request. This value is used to identify + duplicate requests. If you make a request with + the same request ID and the original request is + still in progress or completed, the server + ignores the second request. This prevents + clients from accidentally creating duplicate + commitments. + + The request ID must be a valid UUID with the + exception that zero UUID is not supported + (00000000-0000-0000-0000-000000000000). + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + request_id: str = proto.Field( + proto.STRING, + number=2, + ) + + +class GetGoldengateDeploymentRequest(proto.Message): + r"""The request for ``GoldengateDeployment.Get``. + + Attributes: + name (str): + Required. The name of the GoldengateDeployment in the + following format: + projects/{project}/locations/{location}/goldengateDeployments/{goldengate_deployment}. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListGoldengateDeploymentsRequest(proto.Message): + r"""The request for ``GoldengateDeployment.List``. + + Attributes: + parent (str): + Required. The parent value for + GoldengateDeployments in the following format: + projects/{project}/locations/{location}. + page_size (int): + Optional. The maximum number of items to + return. If unspecified, at most 50 + GoldengateDeployments will be returned. The + maximum value is 1000; values above 1000 will be + coerced to 1000. + page_token (str): + Optional. A page token, received from a + previous ListGoldengateDeployments call. Provide + this to retrieve the subsequent page. + filter (str): + Optional. An expression for filtering the + results of the request. + order_by (str): + Optional. An expression for ordering the + results of the request. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + order_by: str = proto.Field( + proto.STRING, + number=5, + ) + + +class ListGoldengateDeploymentsResponse(proto.Message): + r"""The response for ``GoldengateDeployment.List``. + + Attributes: + goldengate_deployments (MutableSequence[google.cloud.oracledatabase_v1.types.GoldengateDeployment]): + The list of GoldengateDeployments. + next_page_token (str): + A token identifying a page of results the + server should return. + unreachable (MutableSequence[str]): + Optional. Locations that could not be + reached. + """ + + @property + def raw_page(self): + return self + + goldengate_deployments: MutableSequence["GoldengateDeployment"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=1, + message="GoldengateDeployment", + ) + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + unreachable: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + + +class StopGoldengateDeploymentRequest(proto.Message): + r"""The request for ``GoldengateDeployment.Stop``. + + Attributes: + name (str): + Required. The name of the Goldengate Deployment in the + following format: + projects/{project}/locations/{location}/goldengateDeployments/{goldengate_deployment}. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class StartGoldengateDeploymentRequest(proto.Message): + r"""The request for ``GoldengateDeployment.Start``. + + Attributes: + name (str): + Required. The name of the Goldengate Deployment in the + following format: + projects/{project}/locations/{location}/goldengateDeployments/{goldengate_deployment}. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/goldengate_deployment_environment.py b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/goldengate_deployment_environment.py new file mode 100644 index 000000000000..5060749fc32b --- /dev/null +++ b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/goldengate_deployment_environment.py @@ -0,0 +1,249 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.oracledatabase.v1", + manifest={ + "GoldengateDeploymentEnvironment", + "GetGoldengateDeploymentEnvironmentRequest", + "ListGoldengateDeploymentEnvironmentsRequest", + "ListGoldengateDeploymentEnvironmentsResponse", + }, +) + + +class GoldengateDeploymentEnvironment(proto.Message): + r"""Details of the Goldengate Deployment Environment resource. + + Attributes: + name (str): + Identifier. The name of the Goldengate Deployment + Environment resource with the format: + projects/{project}/locations/{location}/goldengateDeploymentEnvironments/{goldengate_deployment_environment} + category (google.cloud.oracledatabase_v1.types.GoldengateDeploymentEnvironment.DeploymentCategory): + Output only. The category of the Goldengate + Deployment Environment resource. + display_name (str): + The display name of the Goldengate Deployment + Environment resource. + default_cpu_core_count (int): + Output only. The default CPU core count of + the Goldengate Deployment Environment resource. + environment_type (google.cloud.oracledatabase_v1.types.GoldengateDeploymentEnvironment.DeploymentEnvironmentType): + Output only. The environment type of the + Goldengate Deployment Environment resource. + auto_scaling_enabled (bool): + Output only. Whether auto scaling is enabled + by default for the Goldengate Deployment + Environment resource. + max_cpu_core_count (int): + Output only. The max CPU core count of the + Goldengate Deployment Environment resource. + memory_gb_per_cpu_core (int): + Output only. The memory per CPU core in GBs + of the Goldengate Deployment Environment + resource. + min_cpu_core_count (int): + Output only. The min CPU core count of the + Goldengate Deployment Environment resource. + network_bandwidth_gbps_per_cpu_core (int): + Output only. The network bandwidth per CPU + core in Gbps of the Goldengate Deployment + Environment resource. + storage_usage_limit_gb_per_cpu_core (int): + Output only. The storage usage limit per CPU + core in GBs of the Goldengate Deployment + Environment resource. + """ + + class DeploymentCategory(proto.Enum): + r"""Deployment category of the Goldengate Deployment resource. + + Values: + DEPLOYMENT_CATEGORY_UNSPECIFIED (0): + Default unspecified value. + DATA_REPLICATION_CATEGORY (1): + Goldengate Deployment Environment category is + DATA_REPLICATION_CATEGORY. + DATA_TRANSFORMS_CATEGORY (2): + Goldengate Deployment Environment category is + DATA_TRANSFORMS_CATEGORY. + """ + + DEPLOYMENT_CATEGORY_UNSPECIFIED = 0 + DATA_REPLICATION_CATEGORY = 1 + DATA_TRANSFORMS_CATEGORY = 2 + + class DeploymentEnvironmentType(proto.Enum): + r"""The environment type of the Goldengate Deployment Environment + resource. + + Values: + DEPLOYMENT_ENVIRONMENT_TYPE_UNSPECIFIED (0): + Default unspecified value. + PRODUCTION (1): + Goldengate Deployment Environment type is + PRODUCTION. + DEVELOPMENT_OR_TESTING (2): + Goldengate Deployment Environment type is + DEVELOPMENT_OR_TESTING. + """ + + DEPLOYMENT_ENVIRONMENT_TYPE_UNSPECIFIED = 0 + PRODUCTION = 1 + DEVELOPMENT_OR_TESTING = 2 + + name: str = proto.Field( + proto.STRING, + number=1, + ) + category: DeploymentCategory = proto.Field( + proto.ENUM, + number=2, + enum=DeploymentCategory, + ) + display_name: str = proto.Field( + proto.STRING, + number=3, + ) + default_cpu_core_count: int = proto.Field( + proto.INT32, + number=4, + ) + environment_type: DeploymentEnvironmentType = proto.Field( + proto.ENUM, + number=5, + enum=DeploymentEnvironmentType, + ) + auto_scaling_enabled: bool = proto.Field( + proto.BOOL, + number=6, + ) + max_cpu_core_count: int = proto.Field( + proto.INT32, + number=7, + ) + memory_gb_per_cpu_core: int = proto.Field( + proto.INT32, + number=8, + ) + min_cpu_core_count: int = proto.Field( + proto.INT32, + number=9, + ) + network_bandwidth_gbps_per_cpu_core: int = proto.Field( + proto.INT32, + number=10, + ) + storage_usage_limit_gb_per_cpu_core: int = proto.Field( + proto.INT32, + number=11, + ) + + +class GetGoldengateDeploymentEnvironmentRequest(proto.Message): + r"""Message for getting a GoldengateDeploymentEnvironment. + + Attributes: + name (str): + Required. Name of the resource with the format: + projects/{project}/locations/{location}/goldengateDeploymentEnvironments/{goldengate_deployment_environment} + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListGoldengateDeploymentEnvironmentsRequest(proto.Message): + r"""Message for listing GoldengateDeploymentEnvironments. + + Attributes: + parent (str): + Required. The parent, which owns this + collection of GoldengateDeploymentEnvironments. + Format: + + projects/{project}/locations/{location} + page_size (int): + Optional. The maximum number of items to + return. If unspecified, at most 50 deployment + environments will be returned. The maximum value + is 1000; values above 1000 will be coerced to + 1000. + page_token (str): + Optional. A token identifying a page of + results the server should return. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListGoldengateDeploymentEnvironmentsResponse(proto.Message): + r"""Message for response to listing + GoldengateDeploymentEnvironments + + Attributes: + goldengate_deployment_environments (MutableSequence[google.cloud.oracledatabase_v1.types.GoldengateDeploymentEnvironment]): + The list of GoldengateDeploymentEnvironment + next_page_token (str): + A token identifying a page of results the + server should return. If this field is empty, + there are no subsequent pages. + unreachable (MutableSequence[str]): + Unordered list. Locations that could not be + reached. + """ + + @property + def raw_page(self): + return self + + goldengate_deployment_environments: MutableSequence[ + "GoldengateDeploymentEnvironment" + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="GoldengateDeploymentEnvironment", + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + unreachable: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/goldengate_deployment_type.py b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/goldengate_deployment_type.py new file mode 100644 index 000000000000..8b5baabe4539 --- /dev/null +++ b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/goldengate_deployment_type.py @@ -0,0 +1,285 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.oracledatabase.v1", + manifest={ + "GoldengateDeploymentType", + "GetGoldengateDeploymentTypeRequest", + "ListGoldengateDeploymentTypesRequest", + "ListGoldengateDeploymentTypesResponse", + }, +) + + +class GoldengateDeploymentType(proto.Message): + r"""Details of the Goldengate Deployment Type resource. + + Attributes: + name (str): + Identifier. The name of the Goldengate Deployment Type + resource with the format: + projects/{project}/locations/{region}/goldengateDeploymentTypes/{goldengate_deployment_type} + deployment_type (google.cloud.oracledatabase_v1.types.GoldengateDeploymentType.DeploymentType): + Output only. The deployment type of the + Goldengate Deployment Type resource. + category (google.cloud.oracledatabase_v1.types.GoldengateDeploymentType.DeploymentCategory): + Output only. The category of the Goldengate + Deployment Type resource. + connection_types (MutableSequence[str]): + Output only. The connection types of the + Goldengate Deployment Type resource. + display_name (str): + Output only. The display name of the + Goldengate Deployment Type resource. + ogg_version (str): + Output only. The Ogg version of the + Goldengate Deployment Type resource. + source_technologies (MutableSequence[str]): + Output only. The source technologies of the + Goldengate Deployment Type resource. + supported_capabilities (MutableSequence[str]): + Output only. The supported capabilities of + the Goldengate Deployment Type resource. + supported_technologies_url (str): + Output only. The supported technologies URL + of the Goldengate Deployment Type resource. + target_technologies (MutableSequence[str]): + Output only. The target technologies of the + Goldengate Deployment Type resource. + default_username (str): + Output only. The default username of the + Goldengate Deployment Type resource. + """ + + class DeploymentType(proto.Enum): + r"""The deployment type of the Goldengate Deployment Type + resource. + + Values: + DEPLOYMENT_TYPE_UNSPECIFIED (0): + Default unspecified value. + OGG (1): + Goldengate Deployment Type category is OGG. + DATABASE_ORACLE (2): + Goldengate Deployment Type category is DATABASE_ORACLE. + BIGDATA (3): + Goldengate Deployment Type category is + BIGDATA. + DATABASE_MICROSOFT_SQLSERVER (4): + Goldengate Deployment Type category is + DATABASE_MICROSOFT_SQLSERVER. + DATABASE_MYSQL (5): + Goldengate Deployment Type category is DATABASE_MYSQL. + DATABASE_POSTGRESQL (6): + Goldengate Deployment Type category is DATABASE_POSTGRESQL. + DATABASE_DB2ZOS (7): + Goldengate Deployment Type category is DATABASE_DB2ZOS. + DATABASE_DB2I (8): + Goldengate Deployment Type category is DATABASE_DB2I. + GGSA (9): + Goldengate Deployment Type category is GGSA. + DATA_TRANSFORMS (10): + Goldengate Deployment Type category is DATA_TRANSFORMS. + """ + + DEPLOYMENT_TYPE_UNSPECIFIED = 0 + OGG = 1 + DATABASE_ORACLE = 2 + BIGDATA = 3 + DATABASE_MICROSOFT_SQLSERVER = 4 + DATABASE_MYSQL = 5 + DATABASE_POSTGRESQL = 6 + DATABASE_DB2ZOS = 7 + DATABASE_DB2I = 8 + GGSA = 9 + DATA_TRANSFORMS = 10 + + class DeploymentCategory(proto.Enum): + r"""The category of the Goldengate Deployment Type resource. + + Values: + DEPLOYMENT_CATEGORY_UNSPECIFIED (0): + Default unspecified value. + DATA_REPLICATION_CATEGORY (1): + Goldengate Deployment Type category is + DATA_REPLICATION_CATEGORY. + DATA_TRANSFORMS_CATEGORY (2): + Goldengate Deployment Type category is + DATA_TRANSFORMS_CATEGORY. + """ + + DEPLOYMENT_CATEGORY_UNSPECIFIED = 0 + DATA_REPLICATION_CATEGORY = 1 + DATA_TRANSFORMS_CATEGORY = 2 + + name: str = proto.Field( + proto.STRING, + number=1, + ) + deployment_type: DeploymentType = proto.Field( + proto.ENUM, + number=2, + enum=DeploymentType, + ) + category: DeploymentCategory = proto.Field( + proto.ENUM, + number=3, + enum=DeploymentCategory, + ) + connection_types: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=4, + ) + display_name: str = proto.Field( + proto.STRING, + number=5, + ) + ogg_version: str = proto.Field( + proto.STRING, + number=6, + ) + source_technologies: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=7, + ) + supported_capabilities: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=8, + ) + supported_technologies_url: str = proto.Field( + proto.STRING, + number=9, + ) + target_technologies: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=10, + ) + default_username: str = proto.Field( + proto.STRING, + number=11, + ) + + +class GetGoldengateDeploymentTypeRequest(proto.Message): + r"""Message for getting a GoldengateDeploymentType. + + Attributes: + name (str): + Required. The name of the GoldengateDeploymentType to + retrieve. Format: + projects/{project}/locations/{location}/goldengateDeploymentTypes/{goldengate_deployment_type} + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListGoldengateDeploymentTypesRequest(proto.Message): + r"""Message for listing GoldengateDeploymentTypes. + + Attributes: + parent (str): + Required. The parent resource. + Format: projects/{project}/locations/{location} + page_size (int): + Optional. Requested page size. Server may + return fewer items than requested. If + unspecified, server will pick an appropriate + default. + page_token (str): + Optional. A token identifying a page of + results the server should return. + filter (str): + Optional. An expression for filtering the results of the + request. Either the deployment_type and ogg_version fields + must be specified in the format: + ``deployment_type="DATABASE_ORACLE"`` or + ``ogg_version="version"``. Allowed values for + deployment_type are: ``DATABASE_ORACLE``, ``BIGDATA``, + ``DATABASE_MICROSOFT_SQLSERVER``, ``DATABASE_MYSQL``, + ``DATABASE_POSTGRESQL``, ``DATABASE_DB2ZOS``, + ``DATABASE_DB2I``, ``GGSA``, ``DATA_TRANSFORMS``. + order_by (str): + Optional. Hint for how to order the results + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + order_by: str = proto.Field( + proto.STRING, + number=5, + ) + + +class ListGoldengateDeploymentTypesResponse(proto.Message): + r"""Message for response to listing GoldengateDeploymentTypes + + Attributes: + goldengate_deployment_types (MutableSequence[google.cloud.oracledatabase_v1.types.GoldengateDeploymentType]): + The list of GoldengateDeploymentType + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + unreachable (MutableSequence[str]): + Unordered list. The resource names of + locations that could not be reached. + """ + + @property + def raw_page(self): + return self + + goldengate_deployment_types: MutableSequence["GoldengateDeploymentType"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=1, + message="GoldengateDeploymentType", + ) + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + unreachable: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/goldengate_deployment_version.py b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/goldengate_deployment_version.py new file mode 100644 index 000000000000..04c76c522e15 --- /dev/null +++ b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/goldengate_deployment_version.py @@ -0,0 +1,280 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.oracledatabase.v1", + manifest={ + "GoldengateDeploymentVersion", + "GoldengateDeploymentVersionProperties", + "GetGoldengateDeploymentVersionRequest", + "ListGoldengateDeploymentVersionsRequest", + "ListGoldengateDeploymentVersionsResponse", + }, +) + + +class GoldengateDeploymentVersion(proto.Message): + r"""Details of the Goldengate Deployment Version resource. + + Attributes: + name (str): + Identifier. The name of the Goldengate Deployment Version + resource with the format: + projects/{project}/locations/{location}/goldengateDeploymentVersions/{goldengate_deployment_version} + ocid (str): + Output only. The deployment version ocid of + the Goldengate Deployment Version resource. + properties (google.cloud.oracledatabase_v1.types.GoldengateDeploymentVersionProperties): + Output only. The technology type of the + Goldengate Deployment Version resource. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + ocid: str = proto.Field( + proto.STRING, + number=2, + ) + properties: "GoldengateDeploymentVersionProperties" = proto.Field( + proto.MESSAGE, + number=3, + message="GoldengateDeploymentVersionProperties", + ) + + +class GoldengateDeploymentVersionProperties(proto.Message): + r"""Properties of GoldengateDeploymentVersion. + + Attributes: + deployment_type (google.cloud.oracledatabase_v1.types.GoldengateDeploymentVersionProperties.DeploymentType): + Output only. The deployment type of the + Goldengate Deployment Version resource. + security_fix (bool): + Optional. Whether the Goldengate Deployment + Version resource is a security fix. + ogg_version (str): + Output only. The OGG version of the + Goldengate Deployment Version resource. + release_type (google.cloud.oracledatabase_v1.types.GoldengateDeploymentVersionProperties.DeploymentReleaseType): + Output only. The release type of the + Goldengate Deployment Version resource. + release_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The release time of the + Goldengate Deployment Version resource. + support_end_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The support end time of the + Goldengate Deployment Version resource. + """ + + class DeploymentType(proto.Enum): + r"""The deployment type of the Goldengate Deployment Version + resource. + + Values: + DEPLOYMENT_TYPE_UNSPECIFIED (0): + Default unspecified value. + OGG (1): + Goldengate Deployment Type category is OGG. + DATABASE_ORACLE (2): + Goldengate Deployment Type category is DATABASE_ORACLE. + BIGDATA (3): + Goldengate Deployment Type category is + BIGDATA. + DATABASE_MICROSOFT_SQLSERVER (4): + Goldengate Deployment Type category is + DATABASE_MICROSOFT_SQLSERVER. + DATABASE_MYSQL (5): + Goldengate Deployment Type category is DATABASE_MYSQL. + DATABASE_POSTGRESQL (6): + Goldengate Deployment Type category is DATABASE_POSTGRESQL. + DATABASE_DB2ZOS (7): + Goldengate Deployment Type category is DATABASE_DB2ZOS. + DATABASE_DB2I (8): + Goldengate Deployment Type category is DATABASE_DB2I. + GGSA (9): + Goldengate Deployment Type category is GGSA. + DATA_TRANSFORMS (10): + Goldengate Deployment Type category is DATA_TRANSFORMS. + """ + + DEPLOYMENT_TYPE_UNSPECIFIED = 0 + OGG = 1 + DATABASE_ORACLE = 2 + BIGDATA = 3 + DATABASE_MICROSOFT_SQLSERVER = 4 + DATABASE_MYSQL = 5 + DATABASE_POSTGRESQL = 6 + DATABASE_DB2ZOS = 7 + DATABASE_DB2I = 8 + GGSA = 9 + DATA_TRANSFORMS = 10 + + class DeploymentReleaseType(proto.Enum): + r"""The release type of the Goldengate Deployment Version + resource. + + Values: + DEPLOYMENT_RELEASE_TYPE_UNSPECIFIED (0): + Default unspecified value. + MAJOR (1): + Goldengate Deployment Version release type is + MAJOR. + BUNDLE (2): + Goldengate Deployment Version release type is + BUNDLE. + MINOR (3): + Goldengate Deployment Version release type is + MINOR. + """ + + DEPLOYMENT_RELEASE_TYPE_UNSPECIFIED = 0 + MAJOR = 1 + BUNDLE = 2 + MINOR = 3 + + deployment_type: DeploymentType = proto.Field( + proto.ENUM, + number=1, + enum=DeploymentType, + ) + security_fix: bool = proto.Field( + proto.BOOL, + number=2, + ) + ogg_version: str = proto.Field( + proto.STRING, + number=3, + ) + release_type: DeploymentReleaseType = proto.Field( + proto.ENUM, + number=4, + enum=DeploymentReleaseType, + ) + release_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + support_end_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=6, + message=timestamp_pb2.Timestamp, + ) + + +class GetGoldengateDeploymentVersionRequest(proto.Message): + r"""Message for getting a GoldengateDeploymentVersion. + + Attributes: + name (str): + Required. The name of the GoldengateDeploymentVersion to + retrieve. Format: + projects/{project}/locations/{location}/goldengateDeploymentVersions/{goldengate_deployment_version} + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListGoldengateDeploymentVersionsRequest(proto.Message): + r"""Message for listing GoldengateDeploymentVersions. + + Attributes: + parent (str): + Required. Parent value for + ListGoldengateDeploymentVersionsRequest Format: + projects/{project}/locations/{location} + page_size (int): + Optional. Requested page size. Server may + return fewer items than requested. If + unspecified, server will pick an appropriate + default. The maximum value is 1000; values above + 1000 will be coerced to 1000. + page_token (str): + Optional. A token identifying a page of + results the server should return. + filter (str): + Optional. An expression for filtering the results of the + request. Either the deployment_id and deployment_type fields + must be specified in the format: ``deployment_id="id"`` or + ``deployment_type="DATABASE_ORACLE"``. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + + +class ListGoldengateDeploymentVersionsResponse(proto.Message): + r"""Message for response to listing GoldengateDeploymentVersions + + Attributes: + goldengate_deployment_versions (MutableSequence[google.cloud.oracledatabase_v1.types.GoldengateDeploymentVersion]): + The list of GoldengateDeploymentVersion + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + unreachable (MutableSequence[str]): + Unordered list. Locations that could not be + reached. + """ + + @property + def raw_page(self): + return self + + goldengate_deployment_versions: MutableSequence["GoldengateDeploymentVersion"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=1, + message="GoldengateDeploymentVersion", + ) + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + unreachable: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/oracledatabase.py b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/oracledatabase.py index 48d99ab2bb90..1d3b2ed6caa4 100644 --- a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/oracledatabase.py +++ b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/oracledatabase.py @@ -150,6 +150,10 @@ class ListCloudExadataInfrastructuresResponse(proto.Message): The list of Exadata Infrastructures. next_page_token (str): A token for fetching next page of response. + unreachable (MutableSequence[str]): + Unreachable locations when listing resources + across all locations using wildcard location + '-'. """ @property @@ -167,6 +171,10 @@ def raw_page(self): proto.STRING, number=2, ) + unreachable: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) class GetCloudExadataInfrastructureRequest(proto.Message): @@ -326,6 +334,10 @@ class ListCloudVmClustersResponse(proto.Message): The list of VM Clusters. next_page_token (str): A token to fetch the next page of results. + unreachable (MutableSequence[str]): + Unreachable locations when listing resources + across all locations using wildcard location + '-'. """ @property @@ -341,6 +353,10 @@ def raw_page(self): proto.STRING, number=2, ) + unreachable: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) class GetCloudVmClusterRequest(proto.Message): @@ -886,6 +902,10 @@ class ListAutonomousDatabasesResponse(proto.Message): next_page_token (str): A token identifying a page of results the server should return. + unreachable (MutableSequence[str]): + Unreachable locations when listing resources + across all locations using wildcard location + '-'. """ @property @@ -903,6 +923,10 @@ def raw_page(self): proto.STRING, number=2, ) + unreachable: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) class GetAutonomousDatabaseRequest(proto.Message): @@ -1129,8 +1153,9 @@ class SwitchoverAutonomousDatabaseRequest(proto.Message): following format: projects/{project}/locations/{location}/autonomousDatabases/{autonomous_database}. peer_autonomous_database (str): - Required. The peer database name to switch - over to. + Optional. The peer database name to switch + over to. Required for cross-region standby, and + must be omitted for in-region Data Guard. """ name: str = proto.Field( @@ -1152,8 +1177,9 @@ class FailoverAutonomousDatabaseRequest(proto.Message): following format: projects/{project}/locations/{location}/autonomousDatabases/{autonomous_database}. peer_autonomous_database (str): - Required. The peer database name to fail over - to. + Optional. The peer database name to fail over + to. Required for cross-region standby, and must + be omitted for in-region Data Guard. """ name: str = proto.Field( @@ -1588,6 +1614,10 @@ class ListExadbVmClustersResponse(proto.Message): next_page_token (str): A token identifying a page of results the server should return. + unreachable (MutableSequence[str]): + Unreachable locations when listing resources + across all locations using wildcard location + '-'. """ @property @@ -1605,6 +1635,10 @@ def raw_page(self): proto.STRING, number=2, ) + unreachable: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) class UpdateExadbVmClusterRequest(proto.Message): diff --git a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/vm_cluster.py b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/vm_cluster.py index daa1d54eb03d..6e9e5a276313 100644 --- a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/vm_cluster.py +++ b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/types/vm_cluster.py @@ -202,9 +202,9 @@ class CloudVmClusterProperties(proto.Message): state (google.cloud.oracledatabase_v1.types.CloudVmClusterProperties.State): Output only. State of the cluster. scan_listener_port_tcp (int): - Output only. SCAN listener port - TCP + Optional. SCAN listener port - TCP scan_listener_port_tcp_ssl (int): - Output only. SCAN listener port - TLS + Optional. SCAN listener port - TLS domain (str): Output only. Parent DNS domain where SCAN DNS and hosts names are qualified. ex: diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_create_goldengate_connection_assignment_async.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_create_goldengate_connection_assignment_async.py new file mode 100644 index 000000000000..e36779d1f849 --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_create_goldengate_connection_assignment_async.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateGoldengateConnectionAssignment +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_CreateGoldengateConnectionAssignment_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +async def sample_create_goldengate_connection_assignment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + goldengate_connection_assignment = ( + oracledatabase_v1.GoldengateConnectionAssignment() + ) + goldengate_connection_assignment.properties.goldengate_connection = ( + "goldengate_connection_value" + ) + goldengate_connection_assignment.properties.goldengate_deployment = ( + "goldengate_deployment_value" + ) + + request = oracledatabase_v1.CreateGoldengateConnectionAssignmentRequest( + parent="parent_value", + goldengate_connection_assignment_id="goldengate_connection_assignment_id_value", + goldengate_connection_assignment=goldengate_connection_assignment, + ) + + # Make the request + operation = await client.create_goldengate_connection_assignment(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_CreateGoldengateConnectionAssignment_async] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_create_goldengate_connection_assignment_sync.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_create_goldengate_connection_assignment_sync.py new file mode 100644 index 000000000000..a7fd4fb6c33f --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_create_goldengate_connection_assignment_sync.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateGoldengateConnectionAssignment +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_CreateGoldengateConnectionAssignment_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +def sample_create_goldengate_connection_assignment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + goldengate_connection_assignment = ( + oracledatabase_v1.GoldengateConnectionAssignment() + ) + goldengate_connection_assignment.properties.goldengate_connection = ( + "goldengate_connection_value" + ) + goldengate_connection_assignment.properties.goldengate_deployment = ( + "goldengate_deployment_value" + ) + + request = oracledatabase_v1.CreateGoldengateConnectionAssignmentRequest( + parent="parent_value", + goldengate_connection_assignment_id="goldengate_connection_assignment_id_value", + goldengate_connection_assignment=goldengate_connection_assignment, + ) + + # Make the request + operation = client.create_goldengate_connection_assignment(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_CreateGoldengateConnectionAssignment_sync] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_create_goldengate_connection_async.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_create_goldengate_connection_async.py new file mode 100644 index 000000000000..58411419e995 --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_create_goldengate_connection_async.py @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateGoldengateConnection +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_CreateGoldengateConnection_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +async def sample_create_goldengate_connection(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + goldengate_connection = oracledatabase_v1.GoldengateConnection() + goldengate_connection.properties.oracle_connection_properties.password = ( + "password_value" + ) + goldengate_connection.properties.connection_type = "ICEBERG" + goldengate_connection.properties.display_name = "display_name_value" + + request = oracledatabase_v1.CreateGoldengateConnectionRequest( + parent="parent_value", + goldengate_connection_id="goldengate_connection_id_value", + goldengate_connection=goldengate_connection, + ) + + # Make the request + operation = await client.create_goldengate_connection(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_CreateGoldengateConnection_async] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_create_goldengate_connection_sync.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_create_goldengate_connection_sync.py new file mode 100644 index 000000000000..b7351bdcd03f --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_create_goldengate_connection_sync.py @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateGoldengateConnection +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_CreateGoldengateConnection_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +def sample_create_goldengate_connection(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + goldengate_connection = oracledatabase_v1.GoldengateConnection() + goldengate_connection.properties.oracle_connection_properties.password = ( + "password_value" + ) + goldengate_connection.properties.connection_type = "ICEBERG" + goldengate_connection.properties.display_name = "display_name_value" + + request = oracledatabase_v1.CreateGoldengateConnectionRequest( + parent="parent_value", + goldengate_connection_id="goldengate_connection_id_value", + goldengate_connection=goldengate_connection, + ) + + # Make the request + operation = client.create_goldengate_connection(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_CreateGoldengateConnection_sync] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_create_goldengate_deployment_async.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_create_goldengate_deployment_async.py new file mode 100644 index 000000000000..1d0e5998b2b5 --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_create_goldengate_deployment_async.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateGoldengateDeployment +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_CreateGoldengateDeployment_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +async def sample_create_goldengate_deployment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + goldengate_deployment = oracledatabase_v1.GoldengateDeployment() + goldengate_deployment.properties.deployment_type = "deployment_type_value" + goldengate_deployment.properties.ogg_data.admin_password = "admin_password_value" + goldengate_deployment.properties.ogg_data.deployment = "deployment_value" + goldengate_deployment.properties.ogg_data.admin_username = "admin_username_value" + goldengate_deployment.odb_subnet = "odb_subnet_value" + goldengate_deployment.display_name = "display_name_value" + + request = oracledatabase_v1.CreateGoldengateDeploymentRequest( + parent="parent_value", + goldengate_deployment_id="goldengate_deployment_id_value", + goldengate_deployment=goldengate_deployment, + ) + + # Make the request + operation = await client.create_goldengate_deployment(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_CreateGoldengateDeployment_async] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_create_goldengate_deployment_sync.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_create_goldengate_deployment_sync.py new file mode 100644 index 000000000000..4b9e6fdf44d6 --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_create_goldengate_deployment_sync.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateGoldengateDeployment +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_CreateGoldengateDeployment_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +def sample_create_goldengate_deployment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + goldengate_deployment = oracledatabase_v1.GoldengateDeployment() + goldengate_deployment.properties.deployment_type = "deployment_type_value" + goldengate_deployment.properties.ogg_data.admin_password = "admin_password_value" + goldengate_deployment.properties.ogg_data.deployment = "deployment_value" + goldengate_deployment.properties.ogg_data.admin_username = "admin_username_value" + goldengate_deployment.odb_subnet = "odb_subnet_value" + goldengate_deployment.display_name = "display_name_value" + + request = oracledatabase_v1.CreateGoldengateDeploymentRequest( + parent="parent_value", + goldengate_deployment_id="goldengate_deployment_id_value", + goldengate_deployment=goldengate_deployment, + ) + + # Make the request + operation = client.create_goldengate_deployment(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_CreateGoldengateDeployment_sync] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_delete_goldengate_connection_assignment_async.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_delete_goldengate_connection_assignment_async.py new file mode 100644 index 000000000000..d3b1a16bb4ab --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_delete_goldengate_connection_assignment_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteGoldengateConnectionAssignment +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_DeleteGoldengateConnectionAssignment_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +async def sample_delete_goldengate_connection_assignment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.DeleteGoldengateConnectionAssignmentRequest( + name="name_value", + ) + + # Make the request + operation = await client.delete_goldengate_connection_assignment(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_DeleteGoldengateConnectionAssignment_async] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_delete_goldengate_connection_assignment_sync.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_delete_goldengate_connection_assignment_sync.py new file mode 100644 index 000000000000..16933eaa613d --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_delete_goldengate_connection_assignment_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteGoldengateConnectionAssignment +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_DeleteGoldengateConnectionAssignment_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +def sample_delete_goldengate_connection_assignment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.DeleteGoldengateConnectionAssignmentRequest( + name="name_value", + ) + + # Make the request + operation = client.delete_goldengate_connection_assignment(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_DeleteGoldengateConnectionAssignment_sync] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_delete_goldengate_connection_async.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_delete_goldengate_connection_async.py new file mode 100644 index 000000000000..ce3732a8bc55 --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_delete_goldengate_connection_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteGoldengateConnection +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_DeleteGoldengateConnection_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +async def sample_delete_goldengate_connection(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.DeleteGoldengateConnectionRequest( + name="name_value", + ) + + # Make the request + operation = await client.delete_goldengate_connection(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_DeleteGoldengateConnection_async] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_delete_goldengate_connection_sync.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_delete_goldengate_connection_sync.py new file mode 100644 index 000000000000..a254804fdf20 --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_delete_goldengate_connection_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteGoldengateConnection +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_DeleteGoldengateConnection_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +def sample_delete_goldengate_connection(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.DeleteGoldengateConnectionRequest( + name="name_value", + ) + + # Make the request + operation = client.delete_goldengate_connection(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_DeleteGoldengateConnection_sync] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_delete_goldengate_deployment_async.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_delete_goldengate_deployment_async.py new file mode 100644 index 000000000000..b248b9ca8003 --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_delete_goldengate_deployment_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteGoldengateDeployment +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_DeleteGoldengateDeployment_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +async def sample_delete_goldengate_deployment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.DeleteGoldengateDeploymentRequest( + name="name_value", + ) + + # Make the request + operation = await client.delete_goldengate_deployment(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_DeleteGoldengateDeployment_async] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_delete_goldengate_deployment_sync.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_delete_goldengate_deployment_sync.py new file mode 100644 index 000000000000..ac319d7a52ce --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_delete_goldengate_deployment_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteGoldengateDeployment +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_DeleteGoldengateDeployment_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +def sample_delete_goldengate_deployment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.DeleteGoldengateDeploymentRequest( + name="name_value", + ) + + # Make the request + operation = client.delete_goldengate_deployment(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_DeleteGoldengateDeployment_sync] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_failover_autonomous_database_async.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_failover_autonomous_database_async.py index 6e3e8691f557..bab1e7576d56 100644 --- a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_failover_autonomous_database_async.py +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_failover_autonomous_database_async.py @@ -41,7 +41,6 @@ async def sample_failover_autonomous_database(): # Initialize request argument(s) request = oracledatabase_v1.FailoverAutonomousDatabaseRequest( name="name_value", - peer_autonomous_database="peer_autonomous_database_value", ) # Make the request diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_failover_autonomous_database_sync.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_failover_autonomous_database_sync.py index 87c4949f4a72..b8b4b032f4fe 100644 --- a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_failover_autonomous_database_sync.py +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_failover_autonomous_database_sync.py @@ -41,7 +41,6 @@ def sample_failover_autonomous_database(): # Initialize request argument(s) request = oracledatabase_v1.FailoverAutonomousDatabaseRequest( name="name_value", - peer_autonomous_database="peer_autonomous_database_value", ) # Make the request diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_connection_assignment_async.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_connection_assignment_async.py new file mode 100644 index 000000000000..a75fb8b2f908 --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_connection_assignment_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetGoldengateConnectionAssignment +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_GetGoldengateConnectionAssignment_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +async def sample_get_goldengate_connection_assignment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.GetGoldengateConnectionAssignmentRequest( + name="name_value", + ) + + # Make the request + response = await client.get_goldengate_connection_assignment(request=request) + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_GetGoldengateConnectionAssignment_async] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_connection_assignment_sync.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_connection_assignment_sync.py new file mode 100644 index 000000000000..8406a09d83d5 --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_connection_assignment_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetGoldengateConnectionAssignment +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_GetGoldengateConnectionAssignment_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +def sample_get_goldengate_connection_assignment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.GetGoldengateConnectionAssignmentRequest( + name="name_value", + ) + + # Make the request + response = client.get_goldengate_connection_assignment(request=request) + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_GetGoldengateConnectionAssignment_sync] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_connection_async.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_connection_async.py new file mode 100644 index 000000000000..15a6967012bc --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_connection_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetGoldengateConnection +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_GetGoldengateConnection_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +async def sample_get_goldengate_connection(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.GetGoldengateConnectionRequest( + name="name_value", + ) + + # Make the request + response = await client.get_goldengate_connection(request=request) + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_GetGoldengateConnection_async] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_connection_sync.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_connection_sync.py new file mode 100644 index 000000000000..1659d13b0669 --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_connection_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetGoldengateConnection +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_GetGoldengateConnection_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +def sample_get_goldengate_connection(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.GetGoldengateConnectionRequest( + name="name_value", + ) + + # Make the request + response = client.get_goldengate_connection(request=request) + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_GetGoldengateConnection_sync] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_connection_type_async.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_connection_type_async.py new file mode 100644 index 000000000000..d59cb77e131a --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_connection_type_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetGoldengateConnectionType +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_GetGoldengateConnectionType_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +async def sample_get_goldengate_connection_type(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.GetGoldengateConnectionTypeRequest( + name="name_value", + ) + + # Make the request + response = await client.get_goldengate_connection_type(request=request) + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_GetGoldengateConnectionType_async] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_connection_type_sync.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_connection_type_sync.py new file mode 100644 index 000000000000..efb71477e349 --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_connection_type_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetGoldengateConnectionType +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_GetGoldengateConnectionType_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +def sample_get_goldengate_connection_type(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.GetGoldengateConnectionTypeRequest( + name="name_value", + ) + + # Make the request + response = client.get_goldengate_connection_type(request=request) + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_GetGoldengateConnectionType_sync] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_async.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_async.py new file mode 100644 index 000000000000..1994b289ee5a --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetGoldengateDeployment +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_GetGoldengateDeployment_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +async def sample_get_goldengate_deployment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.GetGoldengateDeploymentRequest( + name="name_value", + ) + + # Make the request + response = await client.get_goldengate_deployment(request=request) + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_GetGoldengateDeployment_async] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_environment_async.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_environment_async.py new file mode 100644 index 000000000000..25a2fa4dd733 --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_environment_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetGoldengateDeploymentEnvironment +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_GetGoldengateDeploymentEnvironment_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +async def sample_get_goldengate_deployment_environment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.GetGoldengateDeploymentEnvironmentRequest( + name="name_value", + ) + + # Make the request + response = await client.get_goldengate_deployment_environment(request=request) + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_GetGoldengateDeploymentEnvironment_async] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_environment_sync.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_environment_sync.py new file mode 100644 index 000000000000..1cf4864f65d6 --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_environment_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetGoldengateDeploymentEnvironment +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_GetGoldengateDeploymentEnvironment_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +def sample_get_goldengate_deployment_environment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.GetGoldengateDeploymentEnvironmentRequest( + name="name_value", + ) + + # Make the request + response = client.get_goldengate_deployment_environment(request=request) + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_GetGoldengateDeploymentEnvironment_sync] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_sync.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_sync.py new file mode 100644 index 000000000000..a57d19b10638 --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetGoldengateDeployment +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_GetGoldengateDeployment_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +def sample_get_goldengate_deployment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.GetGoldengateDeploymentRequest( + name="name_value", + ) + + # Make the request + response = client.get_goldengate_deployment(request=request) + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_GetGoldengateDeployment_sync] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_type_async.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_type_async.py new file mode 100644 index 000000000000..347daf35a32a --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_type_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetGoldengateDeploymentType +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_GetGoldengateDeploymentType_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +async def sample_get_goldengate_deployment_type(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.GetGoldengateDeploymentTypeRequest( + name="name_value", + ) + + # Make the request + response = await client.get_goldengate_deployment_type(request=request) + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_GetGoldengateDeploymentType_async] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_type_sync.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_type_sync.py new file mode 100644 index 000000000000..1d863b308017 --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_type_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetGoldengateDeploymentType +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_GetGoldengateDeploymentType_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +def sample_get_goldengate_deployment_type(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.GetGoldengateDeploymentTypeRequest( + name="name_value", + ) + + # Make the request + response = client.get_goldengate_deployment_type(request=request) + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_GetGoldengateDeploymentType_sync] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_version_async.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_version_async.py new file mode 100644 index 000000000000..266a043a75d2 --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_version_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetGoldengateDeploymentVersion +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_GetGoldengateDeploymentVersion_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +async def sample_get_goldengate_deployment_version(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.GetGoldengateDeploymentVersionRequest( + name="name_value", + ) + + # Make the request + response = await client.get_goldengate_deployment_version(request=request) + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_GetGoldengateDeploymentVersion_async] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_version_sync.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_version_sync.py new file mode 100644 index 000000000000..1870b1192aae --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_version_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetGoldengateDeploymentVersion +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_GetGoldengateDeploymentVersion_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +def sample_get_goldengate_deployment_version(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.GetGoldengateDeploymentVersionRequest( + name="name_value", + ) + + # Make the request + response = client.get_goldengate_deployment_version(request=request) + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_GetGoldengateDeploymentVersion_sync] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_connection_assignments_async.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_connection_assignments_async.py new file mode 100644 index 000000000000..b80df423bd1d --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_connection_assignments_async.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListGoldengateConnectionAssignments +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_ListGoldengateConnectionAssignments_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +async def sample_list_goldengate_connection_assignments(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListGoldengateConnectionAssignmentsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_goldengate_connection_assignments(request=request) + + # Handle the response + async for response in page_result: + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_ListGoldengateConnectionAssignments_async] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_connection_assignments_sync.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_connection_assignments_sync.py new file mode 100644 index 000000000000..6fa5b5b62a2f --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_connection_assignments_sync.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListGoldengateConnectionAssignments +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_ListGoldengateConnectionAssignments_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +def sample_list_goldengate_connection_assignments(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListGoldengateConnectionAssignmentsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_goldengate_connection_assignments(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_ListGoldengateConnectionAssignments_sync] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_connection_types_async.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_connection_types_async.py new file mode 100644 index 000000000000..6aafe8311ef7 --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_connection_types_async.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListGoldengateConnectionTypes +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_ListGoldengateConnectionTypes_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +async def sample_list_goldengate_connection_types(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListGoldengateConnectionTypesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_goldengate_connection_types(request=request) + + # Handle the response + async for response in page_result: + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_ListGoldengateConnectionTypes_async] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_connection_types_sync.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_connection_types_sync.py new file mode 100644 index 000000000000..e78ad81e3641 --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_connection_types_sync.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListGoldengateConnectionTypes +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_ListGoldengateConnectionTypes_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +def sample_list_goldengate_connection_types(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListGoldengateConnectionTypesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_goldengate_connection_types(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_ListGoldengateConnectionTypes_sync] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_connections_async.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_connections_async.py new file mode 100644 index 000000000000..1c62f7caa17c --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_connections_async.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListGoldengateConnections +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_ListGoldengateConnections_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +async def sample_list_goldengate_connections(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListGoldengateConnectionsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_goldengate_connections(request=request) + + # Handle the response + async for response in page_result: + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_ListGoldengateConnections_async] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_connections_sync.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_connections_sync.py new file mode 100644 index 000000000000..c8391073af47 --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_connections_sync.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListGoldengateConnections +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_ListGoldengateConnections_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +def sample_list_goldengate_connections(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListGoldengateConnectionsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_goldengate_connections(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_ListGoldengateConnections_sync] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_environments_async.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_environments_async.py new file mode 100644 index 000000000000..ba674ff15ec5 --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_environments_async.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListGoldengateDeploymentEnvironments +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_ListGoldengateDeploymentEnvironments_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +async def sample_list_goldengate_deployment_environments(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListGoldengateDeploymentEnvironmentsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_goldengate_deployment_environments(request=request) + + # Handle the response + async for response in page_result: + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_ListGoldengateDeploymentEnvironments_async] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_environments_sync.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_environments_sync.py new file mode 100644 index 000000000000..b910048acdea --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_environments_sync.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListGoldengateDeploymentEnvironments +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_ListGoldengateDeploymentEnvironments_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +def sample_list_goldengate_deployment_environments(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListGoldengateDeploymentEnvironmentsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_goldengate_deployment_environments(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_ListGoldengateDeploymentEnvironments_sync] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_types_async.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_types_async.py new file mode 100644 index 000000000000..7924c246b7bd --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_types_async.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListGoldengateDeploymentTypes +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_ListGoldengateDeploymentTypes_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +async def sample_list_goldengate_deployment_types(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListGoldengateDeploymentTypesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_goldengate_deployment_types(request=request) + + # Handle the response + async for response in page_result: + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_ListGoldengateDeploymentTypes_async] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_types_sync.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_types_sync.py new file mode 100644 index 000000000000..175adc9d91bc --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_types_sync.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListGoldengateDeploymentTypes +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_ListGoldengateDeploymentTypes_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +def sample_list_goldengate_deployment_types(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListGoldengateDeploymentTypesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_goldengate_deployment_types(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_ListGoldengateDeploymentTypes_sync] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_versions_async.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_versions_async.py new file mode 100644 index 000000000000..1df60f6544b5 --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_versions_async.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListGoldengateDeploymentVersions +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_ListGoldengateDeploymentVersions_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +async def sample_list_goldengate_deployment_versions(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListGoldengateDeploymentVersionsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_goldengate_deployment_versions(request=request) + + # Handle the response + async for response in page_result: + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_ListGoldengateDeploymentVersions_async] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_versions_sync.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_versions_sync.py new file mode 100644 index 000000000000..1d687202021a --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_versions_sync.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListGoldengateDeploymentVersions +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_ListGoldengateDeploymentVersions_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +def sample_list_goldengate_deployment_versions(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListGoldengateDeploymentVersionsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_goldengate_deployment_versions(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_ListGoldengateDeploymentVersions_sync] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployments_async.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployments_async.py new file mode 100644 index 000000000000..b21cb469eb8c --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployments_async.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListGoldengateDeployments +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_ListGoldengateDeployments_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +async def sample_list_goldengate_deployments(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListGoldengateDeploymentsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_goldengate_deployments(request=request) + + # Handle the response + async for response in page_result: + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_ListGoldengateDeployments_async] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployments_sync.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployments_sync.py new file mode 100644 index 000000000000..94d260dc452f --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_list_goldengate_deployments_sync.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListGoldengateDeployments +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_ListGoldengateDeployments_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +def sample_list_goldengate_deployments(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.ListGoldengateDeploymentsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_goldengate_deployments(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_ListGoldengateDeployments_sync] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_start_goldengate_deployment_async.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_start_goldengate_deployment_async.py new file mode 100644 index 000000000000..4d99181c4168 --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_start_goldengate_deployment_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for StartGoldengateDeployment +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_StartGoldengateDeployment_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +async def sample_start_goldengate_deployment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.StartGoldengateDeploymentRequest( + name="name_value", + ) + + # Make the request + operation = await client.start_goldengate_deployment(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_StartGoldengateDeployment_async] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_start_goldengate_deployment_sync.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_start_goldengate_deployment_sync.py new file mode 100644 index 000000000000..f1b0b29f1d94 --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_start_goldengate_deployment_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for StartGoldengateDeployment +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_StartGoldengateDeployment_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +def sample_start_goldengate_deployment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.StartGoldengateDeploymentRequest( + name="name_value", + ) + + # Make the request + operation = client.start_goldengate_deployment(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_StartGoldengateDeployment_sync] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_stop_goldengate_deployment_async.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_stop_goldengate_deployment_async.py new file mode 100644 index 000000000000..66a2339b18af --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_stop_goldengate_deployment_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for StopGoldengateDeployment +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_StopGoldengateDeployment_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +async def sample_stop_goldengate_deployment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.StopGoldengateDeploymentRequest( + name="name_value", + ) + + # Make the request + operation = await client.stop_goldengate_deployment(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_StopGoldengateDeployment_async] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_stop_goldengate_deployment_sync.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_stop_goldengate_deployment_sync.py new file mode 100644 index 000000000000..0617aa666eb9 --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_stop_goldengate_deployment_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for StopGoldengateDeployment +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_StopGoldengateDeployment_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +def sample_stop_goldengate_deployment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.StopGoldengateDeploymentRequest( + name="name_value", + ) + + # Make the request + operation = client.stop_goldengate_deployment(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_StopGoldengateDeployment_sync] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_switchover_autonomous_database_async.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_switchover_autonomous_database_async.py index 26945f1620cc..7817f7ebfd03 100644 --- a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_switchover_autonomous_database_async.py +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_switchover_autonomous_database_async.py @@ -41,7 +41,6 @@ async def sample_switchover_autonomous_database(): # Initialize request argument(s) request = oracledatabase_v1.SwitchoverAutonomousDatabaseRequest( name="name_value", - peer_autonomous_database="peer_autonomous_database_value", ) # Make the request diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_switchover_autonomous_database_sync.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_switchover_autonomous_database_sync.py index 740d3d903be2..9f8ddb72fbbb 100644 --- a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_switchover_autonomous_database_sync.py +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_switchover_autonomous_database_sync.py @@ -41,7 +41,6 @@ def sample_switchover_autonomous_database(): # Initialize request argument(s) request = oracledatabase_v1.SwitchoverAutonomousDatabaseRequest( name="name_value", - peer_autonomous_database="peer_autonomous_database_value", ) # Make the request diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_test_goldengate_connection_assignment_async.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_test_goldengate_connection_assignment_async.py new file mode 100644 index 000000000000..0c519f3156fc --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_test_goldengate_connection_assignment_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for TestGoldengateConnectionAssignment +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_TestGoldengateConnectionAssignment_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +async def sample_test_goldengate_connection_assignment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseAsyncClient() + + # Initialize request argument(s) + request = oracledatabase_v1.TestGoldengateConnectionAssignmentRequest( + name="name_value", + ) + + # Make the request + response = await client.test_goldengate_connection_assignment(request=request) + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_TestGoldengateConnectionAssignment_async] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_test_goldengate_connection_assignment_sync.py b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_test_goldengate_connection_assignment_sync.py new file mode 100644 index 000000000000..b581fe9d028c --- /dev/null +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_test_goldengate_connection_assignment_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for TestGoldengateConnectionAssignment +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-oracledatabase + + +# [START oracledatabase_v1_generated_OracleDatabase_TestGoldengateConnectionAssignment_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import oracledatabase_v1 + + +def sample_test_goldengate_connection_assignment(): + # Create a client + client = oracledatabase_v1.OracleDatabaseClient() + + # Initialize request argument(s) + request = oracledatabase_v1.TestGoldengateConnectionAssignmentRequest( + name="name_value", + ) + + # Make the request + response = client.test_goldengate_connection_assignment(request=request) + + # Handle the response + print(response) + + +# [END oracledatabase_v1_generated_OracleDatabase_TestGoldengateConnectionAssignment_sync] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/snippet_metadata_google.cloud.oracledatabase.v1.json b/packages/google-cloud-oracledatabase/samples/generated_samples/snippet_metadata_google.cloud.oracledatabase.v1.json index f6dfedaa0098..8dbb40f31646 100644 --- a/packages/google-cloud-oracledatabase/samples/generated_samples/snippet_metadata_google.cloud.oracledatabase.v1.json +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/snippet_metadata_google.cloud.oracledatabase.v1.json @@ -1081,30 +1081,30 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.create_odb_network", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.create_goldengate_connection_assignment", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.CreateOdbNetwork", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.CreateGoldengateConnectionAssignment", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "CreateOdbNetwork" + "shortName": "CreateGoldengateConnectionAssignment" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.CreateOdbNetworkRequest" + "type": "google.cloud.oracledatabase_v1.types.CreateGoldengateConnectionAssignmentRequest" }, { "name": "parent", "type": "str" }, { - "name": "odb_network", - "type": "google.cloud.oracledatabase_v1.types.OdbNetwork" + "name": "goldengate_connection_assignment", + "type": "google.cloud.oracledatabase_v1.types.GoldengateConnectionAssignment" }, { - "name": "odb_network_id", + "name": "goldengate_connection_assignment_id", "type": "str" }, { @@ -1121,21 +1121,21 @@ } ], "resultType": "google.api_core.operation_async.AsyncOperation", - "shortName": "create_odb_network" + "shortName": "create_goldengate_connection_assignment" }, - "description": "Sample for CreateOdbNetwork", - "file": "oracledatabase_v1_generated_oracle_database_create_odb_network_async.py", + "description": "Sample for CreateGoldengateConnectionAssignment", + "file": "oracledatabase_v1_generated_oracle_database_create_goldengate_connection_assignment_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_CreateOdbNetwork_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_CreateGoldengateConnectionAssignment_async", "segments": [ { - "end": 60, + "end": 61, "start": 27, "type": "FULL" }, { - "end": 60, + "end": 61, "start": 27, "type": "SHORT" }, @@ -1145,22 +1145,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 50, + "end": 51, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 57, - "start": 51, + "end": 58, + "start": 52, "type": "REQUEST_EXECUTION" }, { - "end": 61, - "start": 58, + "end": 62, + "start": 59, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_create_odb_network_async.py" + "title": "oracledatabase_v1_generated_oracle_database_create_goldengate_connection_assignment_async.py" }, { "canonical": true, @@ -1169,30 +1169,30 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.create_odb_network", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.create_goldengate_connection_assignment", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.CreateOdbNetwork", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.CreateGoldengateConnectionAssignment", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "CreateOdbNetwork" + "shortName": "CreateGoldengateConnectionAssignment" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.CreateOdbNetworkRequest" + "type": "google.cloud.oracledatabase_v1.types.CreateGoldengateConnectionAssignmentRequest" }, { "name": "parent", "type": "str" }, { - "name": "odb_network", - "type": "google.cloud.oracledatabase_v1.types.OdbNetwork" + "name": "goldengate_connection_assignment", + "type": "google.cloud.oracledatabase_v1.types.GoldengateConnectionAssignment" }, { - "name": "odb_network_id", + "name": "goldengate_connection_assignment_id", "type": "str" }, { @@ -1209,21 +1209,21 @@ } ], "resultType": "google.api_core.operation.Operation", - "shortName": "create_odb_network" + "shortName": "create_goldengate_connection_assignment" }, - "description": "Sample for CreateOdbNetwork", - "file": "oracledatabase_v1_generated_oracle_database_create_odb_network_sync.py", + "description": "Sample for CreateGoldengateConnectionAssignment", + "file": "oracledatabase_v1_generated_oracle_database_create_goldengate_connection_assignment_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_CreateOdbNetwork_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_CreateGoldengateConnectionAssignment_sync", "segments": [ { - "end": 60, + "end": 61, "start": 27, "type": "FULL" }, { - "end": 60, + "end": 61, "start": 27, "type": "SHORT" }, @@ -1233,22 +1233,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 50, + "end": 51, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 57, - "start": 51, + "end": 58, + "start": 52, "type": "REQUEST_EXECUTION" }, { - "end": 61, - "start": 58, + "end": 62, + "start": 59, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_create_odb_network_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_create_goldengate_connection_assignment_sync.py" }, { "canonical": true, @@ -1258,30 +1258,30 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.create_odb_subnet", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.create_goldengate_connection", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.CreateOdbSubnet", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.CreateGoldengateConnection", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "CreateOdbSubnet" + "shortName": "CreateGoldengateConnection" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.CreateOdbSubnetRequest" + "type": "google.cloud.oracledatabase_v1.types.CreateGoldengateConnectionRequest" }, { "name": "parent", "type": "str" }, { - "name": "odb_subnet", - "type": "google.cloud.oracledatabase_v1.types.OdbSubnet" + "name": "goldengate_connection", + "type": "google.cloud.oracledatabase_v1.types.GoldengateConnection" }, { - "name": "odb_subnet_id", + "name": "goldengate_connection_id", "type": "str" }, { @@ -1298,21 +1298,21 @@ } ], "resultType": "google.api_core.operation_async.AsyncOperation", - "shortName": "create_odb_subnet" + "shortName": "create_goldengate_connection" }, - "description": "Sample for CreateOdbSubnet", - "file": "oracledatabase_v1_generated_oracle_database_create_odb_subnet_async.py", + "description": "Sample for CreateGoldengateConnection", + "file": "oracledatabase_v1_generated_oracle_database_create_goldengate_connection_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_CreateOdbSubnet_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_CreateGoldengateConnection_async", "segments": [ { - "end": 61, + "end": 62, "start": 27, "type": "FULL" }, { - "end": 61, + "end": 62, "start": 27, "type": "SHORT" }, @@ -1322,22 +1322,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 51, + "end": 52, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 58, - "start": 52, + "end": 59, + "start": 53, "type": "REQUEST_EXECUTION" }, { - "end": 62, - "start": 59, + "end": 63, + "start": 60, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_create_odb_subnet_async.py" + "title": "oracledatabase_v1_generated_oracle_database_create_goldengate_connection_async.py" }, { "canonical": true, @@ -1346,30 +1346,30 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.create_odb_subnet", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.create_goldengate_connection", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.CreateOdbSubnet", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.CreateGoldengateConnection", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "CreateOdbSubnet" + "shortName": "CreateGoldengateConnection" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.CreateOdbSubnetRequest" + "type": "google.cloud.oracledatabase_v1.types.CreateGoldengateConnectionRequest" }, { "name": "parent", "type": "str" }, { - "name": "odb_subnet", - "type": "google.cloud.oracledatabase_v1.types.OdbSubnet" + "name": "goldengate_connection", + "type": "google.cloud.oracledatabase_v1.types.GoldengateConnection" }, { - "name": "odb_subnet_id", + "name": "goldengate_connection_id", "type": "str" }, { @@ -1386,21 +1386,21 @@ } ], "resultType": "google.api_core.operation.Operation", - "shortName": "create_odb_subnet" + "shortName": "create_goldengate_connection" }, - "description": "Sample for CreateOdbSubnet", - "file": "oracledatabase_v1_generated_oracle_database_create_odb_subnet_sync.py", + "description": "Sample for CreateGoldengateConnection", + "file": "oracledatabase_v1_generated_oracle_database_create_goldengate_connection_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_CreateOdbSubnet_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_CreateGoldengateConnection_sync", "segments": [ { - "end": 61, + "end": 62, "start": 27, "type": "FULL" }, { - "end": 61, + "end": 62, "start": 27, "type": "SHORT" }, @@ -1410,22 +1410,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 51, + "end": 52, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 58, - "start": 52, + "end": 59, + "start": 53, "type": "REQUEST_EXECUTION" }, { - "end": 62, - "start": 59, + "end": 63, + "start": 60, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_create_odb_subnet_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_create_goldengate_connection_sync.py" }, { "canonical": true, @@ -1435,22 +1435,30 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.delete_autonomous_database", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.create_goldengate_deployment", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteAutonomousDatabase", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.CreateGoldengateDeployment", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "DeleteAutonomousDatabase" + "shortName": "CreateGoldengateDeployment" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.DeleteAutonomousDatabaseRequest" + "type": "google.cloud.oracledatabase_v1.types.CreateGoldengateDeploymentRequest" }, { - "name": "name", + "name": "parent", + "type": "str" + }, + { + "name": "goldengate_deployment", + "type": "google.cloud.oracledatabase_v1.types.GoldengateDeployment" + }, + { + "name": "goldengate_deployment_id", "type": "str" }, { @@ -1467,21 +1475,21 @@ } ], "resultType": "google.api_core.operation_async.AsyncOperation", - "shortName": "delete_autonomous_database" + "shortName": "create_goldengate_deployment" }, - "description": "Sample for DeleteAutonomousDatabase", - "file": "oracledatabase_v1_generated_oracle_database_delete_autonomous_database_async.py", + "description": "Sample for CreateGoldengateDeployment", + "file": "oracledatabase_v1_generated_oracle_database_create_goldengate_deployment_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteAutonomousDatabase_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_CreateGoldengateDeployment_async", "segments": [ { - "end": 55, + "end": 65, "start": 27, "type": "FULL" }, { - "end": 55, + "end": 65, "start": 27, "type": "SHORT" }, @@ -1491,22 +1499,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 55, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 52, - "start": 46, + "end": 62, + "start": 56, "type": "REQUEST_EXECUTION" }, { - "end": 56, - "start": 53, + "end": 66, + "start": 63, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_delete_autonomous_database_async.py" + "title": "oracledatabase_v1_generated_oracle_database_create_goldengate_deployment_async.py" }, { "canonical": true, @@ -1515,22 +1523,30 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_autonomous_database", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.create_goldengate_deployment", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteAutonomousDatabase", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.CreateGoldengateDeployment", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "DeleteAutonomousDatabase" + "shortName": "CreateGoldengateDeployment" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.DeleteAutonomousDatabaseRequest" + "type": "google.cloud.oracledatabase_v1.types.CreateGoldengateDeploymentRequest" }, { - "name": "name", + "name": "parent", + "type": "str" + }, + { + "name": "goldengate_deployment", + "type": "google.cloud.oracledatabase_v1.types.GoldengateDeployment" + }, + { + "name": "goldengate_deployment_id", "type": "str" }, { @@ -1547,21 +1563,21 @@ } ], "resultType": "google.api_core.operation.Operation", - "shortName": "delete_autonomous_database" + "shortName": "create_goldengate_deployment" }, - "description": "Sample for DeleteAutonomousDatabase", - "file": "oracledatabase_v1_generated_oracle_database_delete_autonomous_database_sync.py", + "description": "Sample for CreateGoldengateDeployment", + "file": "oracledatabase_v1_generated_oracle_database_create_goldengate_deployment_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteAutonomousDatabase_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_CreateGoldengateDeployment_sync", "segments": [ { - "end": 55, + "end": 65, "start": 27, "type": "FULL" }, { - "end": 55, + "end": 65, "start": 27, "type": "SHORT" }, @@ -1571,22 +1587,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 55, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 52, - "start": 46, + "end": 62, + "start": 56, "type": "REQUEST_EXECUTION" }, { - "end": 56, - "start": 53, + "end": 66, + "start": 63, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_delete_autonomous_database_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_create_goldengate_deployment_sync.py" }, { "canonical": true, @@ -1596,22 +1612,30 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.delete_cloud_exadata_infrastructure", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.create_odb_network", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteCloudExadataInfrastructure", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.CreateOdbNetwork", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "DeleteCloudExadataInfrastructure" + "shortName": "CreateOdbNetwork" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.DeleteCloudExadataInfrastructureRequest" + "type": "google.cloud.oracledatabase_v1.types.CreateOdbNetworkRequest" }, { - "name": "name", + "name": "parent", + "type": "str" + }, + { + "name": "odb_network", + "type": "google.cloud.oracledatabase_v1.types.OdbNetwork" + }, + { + "name": "odb_network_id", "type": "str" }, { @@ -1628,21 +1652,21 @@ } ], "resultType": "google.api_core.operation_async.AsyncOperation", - "shortName": "delete_cloud_exadata_infrastructure" + "shortName": "create_odb_network" }, - "description": "Sample for DeleteCloudExadataInfrastructure", - "file": "oracledatabase_v1_generated_oracle_database_delete_cloud_exadata_infrastructure_async.py", + "description": "Sample for CreateOdbNetwork", + "file": "oracledatabase_v1_generated_oracle_database_create_odb_network_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteCloudExadataInfrastructure_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_CreateOdbNetwork_async", "segments": [ { - "end": 55, + "end": 60, "start": 27, "type": "FULL" }, { - "end": 55, + "end": 60, "start": 27, "type": "SHORT" }, @@ -1652,22 +1676,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 50, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 52, - "start": 46, + "end": 57, + "start": 51, "type": "REQUEST_EXECUTION" }, { - "end": 56, - "start": 53, + "end": 61, + "start": 58, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_delete_cloud_exadata_infrastructure_async.py" + "title": "oracledatabase_v1_generated_oracle_database_create_odb_network_async.py" }, { "canonical": true, @@ -1676,22 +1700,30 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_cloud_exadata_infrastructure", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.create_odb_network", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteCloudExadataInfrastructure", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.CreateOdbNetwork", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "DeleteCloudExadataInfrastructure" + "shortName": "CreateOdbNetwork" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.DeleteCloudExadataInfrastructureRequest" + "type": "google.cloud.oracledatabase_v1.types.CreateOdbNetworkRequest" }, { - "name": "name", + "name": "parent", + "type": "str" + }, + { + "name": "odb_network", + "type": "google.cloud.oracledatabase_v1.types.OdbNetwork" + }, + { + "name": "odb_network_id", "type": "str" }, { @@ -1708,21 +1740,21 @@ } ], "resultType": "google.api_core.operation.Operation", - "shortName": "delete_cloud_exadata_infrastructure" + "shortName": "create_odb_network" }, - "description": "Sample for DeleteCloudExadataInfrastructure", - "file": "oracledatabase_v1_generated_oracle_database_delete_cloud_exadata_infrastructure_sync.py", + "description": "Sample for CreateOdbNetwork", + "file": "oracledatabase_v1_generated_oracle_database_create_odb_network_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteCloudExadataInfrastructure_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_CreateOdbNetwork_sync", "segments": [ { - "end": 55, + "end": 60, "start": 27, "type": "FULL" }, { - "end": 55, + "end": 60, "start": 27, "type": "SHORT" }, @@ -1732,22 +1764,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 50, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 52, - "start": 46, + "end": 57, + "start": 51, "type": "REQUEST_EXECUTION" }, { - "end": 56, - "start": 53, + "end": 61, + "start": 58, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_delete_cloud_exadata_infrastructure_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_create_odb_network_sync.py" }, { "canonical": true, @@ -1757,22 +1789,30 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.delete_cloud_vm_cluster", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.create_odb_subnet", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteCloudVmCluster", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.CreateOdbSubnet", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "DeleteCloudVmCluster" + "shortName": "CreateOdbSubnet" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.DeleteCloudVmClusterRequest" + "type": "google.cloud.oracledatabase_v1.types.CreateOdbSubnetRequest" }, { - "name": "name", + "name": "parent", + "type": "str" + }, + { + "name": "odb_subnet", + "type": "google.cloud.oracledatabase_v1.types.OdbSubnet" + }, + { + "name": "odb_subnet_id", "type": "str" }, { @@ -1789,21 +1829,21 @@ } ], "resultType": "google.api_core.operation_async.AsyncOperation", - "shortName": "delete_cloud_vm_cluster" + "shortName": "create_odb_subnet" }, - "description": "Sample for DeleteCloudVmCluster", - "file": "oracledatabase_v1_generated_oracle_database_delete_cloud_vm_cluster_async.py", + "description": "Sample for CreateOdbSubnet", + "file": "oracledatabase_v1_generated_oracle_database_create_odb_subnet_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteCloudVmCluster_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_CreateOdbSubnet_async", "segments": [ { - "end": 55, + "end": 61, "start": 27, "type": "FULL" }, { - "end": 55, + "end": 61, "start": 27, "type": "SHORT" }, @@ -1813,22 +1853,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 51, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 52, - "start": 46, + "end": 58, + "start": 52, "type": "REQUEST_EXECUTION" }, { - "end": 56, - "start": 53, + "end": 62, + "start": 59, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_delete_cloud_vm_cluster_async.py" + "title": "oracledatabase_v1_generated_oracle_database_create_odb_subnet_async.py" }, { "canonical": true, @@ -1837,22 +1877,30 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_cloud_vm_cluster", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.create_odb_subnet", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteCloudVmCluster", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.CreateOdbSubnet", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "DeleteCloudVmCluster" + "shortName": "CreateOdbSubnet" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.DeleteCloudVmClusterRequest" + "type": "google.cloud.oracledatabase_v1.types.CreateOdbSubnetRequest" }, { - "name": "name", + "name": "parent", + "type": "str" + }, + { + "name": "odb_subnet", + "type": "google.cloud.oracledatabase_v1.types.OdbSubnet" + }, + { + "name": "odb_subnet_id", "type": "str" }, { @@ -1869,21 +1917,21 @@ } ], "resultType": "google.api_core.operation.Operation", - "shortName": "delete_cloud_vm_cluster" + "shortName": "create_odb_subnet" }, - "description": "Sample for DeleteCloudVmCluster", - "file": "oracledatabase_v1_generated_oracle_database_delete_cloud_vm_cluster_sync.py", + "description": "Sample for CreateOdbSubnet", + "file": "oracledatabase_v1_generated_oracle_database_create_odb_subnet_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteCloudVmCluster_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_CreateOdbSubnet_sync", "segments": [ { - "end": 55, + "end": 61, "start": 27, "type": "FULL" }, { - "end": 55, + "end": 61, "start": 27, "type": "SHORT" }, @@ -1893,22 +1941,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 51, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 52, - "start": 46, + "end": 58, + "start": 52, "type": "REQUEST_EXECUTION" }, { - "end": 56, - "start": 53, + "end": 62, + "start": 59, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_delete_cloud_vm_cluster_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_create_odb_subnet_sync.py" }, { "canonical": true, @@ -1918,19 +1966,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.delete_db_system", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.delete_autonomous_database", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteDbSystem", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteAutonomousDatabase", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "DeleteDbSystem" + "shortName": "DeleteAutonomousDatabase" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.DeleteDbSystemRequest" + "type": "google.cloud.oracledatabase_v1.types.DeleteAutonomousDatabaseRequest" }, { "name": "name", @@ -1950,13 +1998,13 @@ } ], "resultType": "google.api_core.operation_async.AsyncOperation", - "shortName": "delete_db_system" + "shortName": "delete_autonomous_database" }, - "description": "Sample for DeleteDbSystem", - "file": "oracledatabase_v1_generated_oracle_database_delete_db_system_async.py", + "description": "Sample for DeleteAutonomousDatabase", + "file": "oracledatabase_v1_generated_oracle_database_delete_autonomous_database_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteDbSystem_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteAutonomousDatabase_async", "segments": [ { "end": 55, @@ -1989,7 +2037,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_delete_db_system_async.py" + "title": "oracledatabase_v1_generated_oracle_database_delete_autonomous_database_async.py" }, { "canonical": true, @@ -1998,19 +2046,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_db_system", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_autonomous_database", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteDbSystem", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteAutonomousDatabase", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "DeleteDbSystem" + "shortName": "DeleteAutonomousDatabase" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.DeleteDbSystemRequest" + "type": "google.cloud.oracledatabase_v1.types.DeleteAutonomousDatabaseRequest" }, { "name": "name", @@ -2030,13 +2078,13 @@ } ], "resultType": "google.api_core.operation.Operation", - "shortName": "delete_db_system" + "shortName": "delete_autonomous_database" }, - "description": "Sample for DeleteDbSystem", - "file": "oracledatabase_v1_generated_oracle_database_delete_db_system_sync.py", + "description": "Sample for DeleteAutonomousDatabase", + "file": "oracledatabase_v1_generated_oracle_database_delete_autonomous_database_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteDbSystem_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteAutonomousDatabase_sync", "segments": [ { "end": 55, @@ -2069,7 +2117,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_delete_db_system_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_delete_autonomous_database_sync.py" }, { "canonical": true, @@ -2079,19 +2127,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.delete_exadb_vm_cluster", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.delete_cloud_exadata_infrastructure", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteExadbVmCluster", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteCloudExadataInfrastructure", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "DeleteExadbVmCluster" + "shortName": "DeleteCloudExadataInfrastructure" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.DeleteExadbVmClusterRequest" + "type": "google.cloud.oracledatabase_v1.types.DeleteCloudExadataInfrastructureRequest" }, { "name": "name", @@ -2111,13 +2159,13 @@ } ], "resultType": "google.api_core.operation_async.AsyncOperation", - "shortName": "delete_exadb_vm_cluster" + "shortName": "delete_cloud_exadata_infrastructure" }, - "description": "Sample for DeleteExadbVmCluster", - "file": "oracledatabase_v1_generated_oracle_database_delete_exadb_vm_cluster_async.py", + "description": "Sample for DeleteCloudExadataInfrastructure", + "file": "oracledatabase_v1_generated_oracle_database_delete_cloud_exadata_infrastructure_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteExadbVmCluster_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteCloudExadataInfrastructure_async", "segments": [ { "end": 55, @@ -2150,7 +2198,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_delete_exadb_vm_cluster_async.py" + "title": "oracledatabase_v1_generated_oracle_database_delete_cloud_exadata_infrastructure_async.py" }, { "canonical": true, @@ -2159,19 +2207,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_exadb_vm_cluster", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_cloud_exadata_infrastructure", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteExadbVmCluster", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteCloudExadataInfrastructure", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "DeleteExadbVmCluster" + "shortName": "DeleteCloudExadataInfrastructure" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.DeleteExadbVmClusterRequest" + "type": "google.cloud.oracledatabase_v1.types.DeleteCloudExadataInfrastructureRequest" }, { "name": "name", @@ -2191,13 +2239,13 @@ } ], "resultType": "google.api_core.operation.Operation", - "shortName": "delete_exadb_vm_cluster" + "shortName": "delete_cloud_exadata_infrastructure" }, - "description": "Sample for DeleteExadbVmCluster", - "file": "oracledatabase_v1_generated_oracle_database_delete_exadb_vm_cluster_sync.py", + "description": "Sample for DeleteCloudExadataInfrastructure", + "file": "oracledatabase_v1_generated_oracle_database_delete_cloud_exadata_infrastructure_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteExadbVmCluster_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteCloudExadataInfrastructure_sync", "segments": [ { "end": 55, @@ -2230,7 +2278,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_delete_exadb_vm_cluster_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_delete_cloud_exadata_infrastructure_sync.py" }, { "canonical": true, @@ -2240,19 +2288,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.delete_exascale_db_storage_vault", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.delete_cloud_vm_cluster", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteExascaleDbStorageVault", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteCloudVmCluster", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "DeleteExascaleDbStorageVault" + "shortName": "DeleteCloudVmCluster" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.DeleteExascaleDbStorageVaultRequest" + "type": "google.cloud.oracledatabase_v1.types.DeleteCloudVmClusterRequest" }, { "name": "name", @@ -2272,13 +2320,13 @@ } ], "resultType": "google.api_core.operation_async.AsyncOperation", - "shortName": "delete_exascale_db_storage_vault" + "shortName": "delete_cloud_vm_cluster" }, - "description": "Sample for DeleteExascaleDbStorageVault", - "file": "oracledatabase_v1_generated_oracle_database_delete_exascale_db_storage_vault_async.py", + "description": "Sample for DeleteCloudVmCluster", + "file": "oracledatabase_v1_generated_oracle_database_delete_cloud_vm_cluster_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteExascaleDbStorageVault_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteCloudVmCluster_async", "segments": [ { "end": 55, @@ -2311,7 +2359,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_delete_exascale_db_storage_vault_async.py" + "title": "oracledatabase_v1_generated_oracle_database_delete_cloud_vm_cluster_async.py" }, { "canonical": true, @@ -2320,19 +2368,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_exascale_db_storage_vault", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_cloud_vm_cluster", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteExascaleDbStorageVault", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteCloudVmCluster", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "DeleteExascaleDbStorageVault" + "shortName": "DeleteCloudVmCluster" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.DeleteExascaleDbStorageVaultRequest" + "type": "google.cloud.oracledatabase_v1.types.DeleteCloudVmClusterRequest" }, { "name": "name", @@ -2352,13 +2400,13 @@ } ], "resultType": "google.api_core.operation.Operation", - "shortName": "delete_exascale_db_storage_vault" + "shortName": "delete_cloud_vm_cluster" }, - "description": "Sample for DeleteExascaleDbStorageVault", - "file": "oracledatabase_v1_generated_oracle_database_delete_exascale_db_storage_vault_sync.py", + "description": "Sample for DeleteCloudVmCluster", + "file": "oracledatabase_v1_generated_oracle_database_delete_cloud_vm_cluster_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteExascaleDbStorageVault_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteCloudVmCluster_sync", "segments": [ { "end": 55, @@ -2391,7 +2439,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_delete_exascale_db_storage_vault_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_delete_cloud_vm_cluster_sync.py" }, { "canonical": true, @@ -2401,19 +2449,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.delete_odb_network", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.delete_db_system", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteOdbNetwork", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteDbSystem", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "DeleteOdbNetwork" + "shortName": "DeleteDbSystem" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.DeleteOdbNetworkRequest" + "type": "google.cloud.oracledatabase_v1.types.DeleteDbSystemRequest" }, { "name": "name", @@ -2433,13 +2481,13 @@ } ], "resultType": "google.api_core.operation_async.AsyncOperation", - "shortName": "delete_odb_network" + "shortName": "delete_db_system" }, - "description": "Sample for DeleteOdbNetwork", - "file": "oracledatabase_v1_generated_oracle_database_delete_odb_network_async.py", + "description": "Sample for DeleteDbSystem", + "file": "oracledatabase_v1_generated_oracle_database_delete_db_system_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteOdbNetwork_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteDbSystem_async", "segments": [ { "end": 55, @@ -2472,7 +2520,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_delete_odb_network_async.py" + "title": "oracledatabase_v1_generated_oracle_database_delete_db_system_async.py" }, { "canonical": true, @@ -2481,19 +2529,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_odb_network", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_db_system", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteOdbNetwork", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteDbSystem", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "DeleteOdbNetwork" + "shortName": "DeleteDbSystem" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.DeleteOdbNetworkRequest" + "type": "google.cloud.oracledatabase_v1.types.DeleteDbSystemRequest" }, { "name": "name", @@ -2513,13 +2561,13 @@ } ], "resultType": "google.api_core.operation.Operation", - "shortName": "delete_odb_network" + "shortName": "delete_db_system" }, - "description": "Sample for DeleteOdbNetwork", - "file": "oracledatabase_v1_generated_oracle_database_delete_odb_network_sync.py", + "description": "Sample for DeleteDbSystem", + "file": "oracledatabase_v1_generated_oracle_database_delete_db_system_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteOdbNetwork_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteDbSystem_sync", "segments": [ { "end": 55, @@ -2552,7 +2600,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_delete_odb_network_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_delete_db_system_sync.py" }, { "canonical": true, @@ -2562,19 +2610,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.delete_odb_subnet", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.delete_exadb_vm_cluster", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteOdbSubnet", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteExadbVmCluster", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "DeleteOdbSubnet" + "shortName": "DeleteExadbVmCluster" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.DeleteOdbSubnetRequest" + "type": "google.cloud.oracledatabase_v1.types.DeleteExadbVmClusterRequest" }, { "name": "name", @@ -2594,13 +2642,13 @@ } ], "resultType": "google.api_core.operation_async.AsyncOperation", - "shortName": "delete_odb_subnet" + "shortName": "delete_exadb_vm_cluster" }, - "description": "Sample for DeleteOdbSubnet", - "file": "oracledatabase_v1_generated_oracle_database_delete_odb_subnet_async.py", + "description": "Sample for DeleteExadbVmCluster", + "file": "oracledatabase_v1_generated_oracle_database_delete_exadb_vm_cluster_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteOdbSubnet_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteExadbVmCluster_async", "segments": [ { "end": 55, @@ -2633,7 +2681,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_delete_odb_subnet_async.py" + "title": "oracledatabase_v1_generated_oracle_database_delete_exadb_vm_cluster_async.py" }, { "canonical": true, @@ -2642,19 +2690,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_odb_subnet", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_exadb_vm_cluster", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteOdbSubnet", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteExadbVmCluster", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "DeleteOdbSubnet" + "shortName": "DeleteExadbVmCluster" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.DeleteOdbSubnetRequest" + "type": "google.cloud.oracledatabase_v1.types.DeleteExadbVmClusterRequest" }, { "name": "name", @@ -2674,13 +2722,13 @@ } ], "resultType": "google.api_core.operation.Operation", - "shortName": "delete_odb_subnet" + "shortName": "delete_exadb_vm_cluster" }, - "description": "Sample for DeleteOdbSubnet", - "file": "oracledatabase_v1_generated_oracle_database_delete_odb_subnet_sync.py", + "description": "Sample for DeleteExadbVmCluster", + "file": "oracledatabase_v1_generated_oracle_database_delete_exadb_vm_cluster_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteOdbSubnet_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteExadbVmCluster_sync", "segments": [ { "end": 55, @@ -2713,7 +2761,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_delete_odb_subnet_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_delete_exadb_vm_cluster_sync.py" }, { "canonical": true, @@ -2723,28 +2771,24 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.failover_autonomous_database", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.delete_exascale_db_storage_vault", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.FailoverAutonomousDatabase", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteExascaleDbStorageVault", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "FailoverAutonomousDatabase" + "shortName": "DeleteExascaleDbStorageVault" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.FailoverAutonomousDatabaseRequest" + "type": "google.cloud.oracledatabase_v1.types.DeleteExascaleDbStorageVaultRequest" }, { "name": "name", "type": "str" }, - { - "name": "peer_autonomous_database", - "type": "str" - }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -2759,21 +2803,21 @@ } ], "resultType": "google.api_core.operation_async.AsyncOperation", - "shortName": "failover_autonomous_database" + "shortName": "delete_exascale_db_storage_vault" }, - "description": "Sample for FailoverAutonomousDatabase", - "file": "oracledatabase_v1_generated_oracle_database_failover_autonomous_database_async.py", + "description": "Sample for DeleteExascaleDbStorageVault", + "file": "oracledatabase_v1_generated_oracle_database_delete_exascale_db_storage_vault_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_FailoverAutonomousDatabase_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteExascaleDbStorageVault_async", "segments": [ { - "end": 56, + "end": 55, "start": 27, "type": "FULL" }, { - "end": 56, + "end": 55, "start": 27, "type": "SHORT" }, @@ -2783,22 +2827,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 46, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 53, - "start": 47, + "end": 52, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 57, - "start": 54, + "end": 56, + "start": 53, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_failover_autonomous_database_async.py" + "title": "oracledatabase_v1_generated_oracle_database_delete_exascale_db_storage_vault_async.py" }, { "canonical": true, @@ -2807,28 +2851,24 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.failover_autonomous_database", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_exascale_db_storage_vault", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.FailoverAutonomousDatabase", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteExascaleDbStorageVault", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "FailoverAutonomousDatabase" + "shortName": "DeleteExascaleDbStorageVault" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.FailoverAutonomousDatabaseRequest" + "type": "google.cloud.oracledatabase_v1.types.DeleteExascaleDbStorageVaultRequest" }, { "name": "name", "type": "str" }, - { - "name": "peer_autonomous_database", - "type": "str" - }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -2843,21 +2883,21 @@ } ], "resultType": "google.api_core.operation.Operation", - "shortName": "failover_autonomous_database" + "shortName": "delete_exascale_db_storage_vault" }, - "description": "Sample for FailoverAutonomousDatabase", - "file": "oracledatabase_v1_generated_oracle_database_failover_autonomous_database_sync.py", + "description": "Sample for DeleteExascaleDbStorageVault", + "file": "oracledatabase_v1_generated_oracle_database_delete_exascale_db_storage_vault_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_FailoverAutonomousDatabase_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteExascaleDbStorageVault_sync", "segments": [ { - "end": 56, + "end": 55, "start": 27, "type": "FULL" }, { - "end": 56, + "end": 55, "start": 27, "type": "SHORT" }, @@ -2867,22 +2907,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 46, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 53, - "start": 47, + "end": 52, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 57, - "start": 54, + "end": 56, + "start": 53, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_failover_autonomous_database_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_delete_exascale_db_storage_vault_sync.py" }, { "canonical": true, @@ -2892,36 +2932,24 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.generate_autonomous_database_wallet", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.delete_goldengate_connection_assignment", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GenerateAutonomousDatabaseWallet", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteGoldengateConnectionAssignment", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "GenerateAutonomousDatabaseWallet" + "shortName": "DeleteGoldengateConnectionAssignment" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.GenerateAutonomousDatabaseWalletRequest" + "type": "google.cloud.oracledatabase_v1.types.DeleteGoldengateConnectionAssignmentRequest" }, { "name": "name", "type": "str" }, - { - "name": "type_", - "type": "google.cloud.oracledatabase_v1.types.GenerateType" - }, - { - "name": "is_regional", - "type": "bool" - }, - { - "name": "password", - "type": "str" - }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -2935,22 +2963,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.types.GenerateAutonomousDatabaseWalletResponse", - "shortName": "generate_autonomous_database_wallet" + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "delete_goldengate_connection_assignment" }, - "description": "Sample for GenerateAutonomousDatabaseWallet", - "file": "oracledatabase_v1_generated_oracle_database_generate_autonomous_database_wallet_async.py", + "description": "Sample for DeleteGoldengateConnectionAssignment", + "file": "oracledatabase_v1_generated_oracle_database_delete_goldengate_connection_assignment_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_GenerateAutonomousDatabaseWallet_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteGoldengateConnectionAssignment_async", "segments": [ { - "end": 52, + "end": 55, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 55, "start": 27, "type": "SHORT" }, @@ -2960,22 +2988,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 46, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 49, - "start": 47, + "end": 52, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 53, - "start": 50, + "end": 56, + "start": 53, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_generate_autonomous_database_wallet_async.py" + "title": "oracledatabase_v1_generated_oracle_database_delete_goldengate_connection_assignment_async.py" }, { "canonical": true, @@ -2984,36 +3012,24 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.generate_autonomous_database_wallet", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_goldengate_connection_assignment", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GenerateAutonomousDatabaseWallet", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteGoldengateConnectionAssignment", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "GenerateAutonomousDatabaseWallet" + "shortName": "DeleteGoldengateConnectionAssignment" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.GenerateAutonomousDatabaseWalletRequest" + "type": "google.cloud.oracledatabase_v1.types.DeleteGoldengateConnectionAssignmentRequest" }, { "name": "name", "type": "str" }, - { - "name": "type_", - "type": "google.cloud.oracledatabase_v1.types.GenerateType" - }, - { - "name": "is_regional", - "type": "bool" - }, - { - "name": "password", - "type": "str" - }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -3027,22 +3043,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.types.GenerateAutonomousDatabaseWalletResponse", - "shortName": "generate_autonomous_database_wallet" + "resultType": "google.api_core.operation.Operation", + "shortName": "delete_goldengate_connection_assignment" }, - "description": "Sample for GenerateAutonomousDatabaseWallet", - "file": "oracledatabase_v1_generated_oracle_database_generate_autonomous_database_wallet_sync.py", + "description": "Sample for DeleteGoldengateConnectionAssignment", + "file": "oracledatabase_v1_generated_oracle_database_delete_goldengate_connection_assignment_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_GenerateAutonomousDatabaseWallet_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteGoldengateConnectionAssignment_sync", "segments": [ { - "end": 52, + "end": 55, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 55, "start": 27, "type": "SHORT" }, @@ -3052,22 +3068,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 46, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 49, - "start": 47, + "end": 52, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 53, - "start": 50, + "end": 56, + "start": 53, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_generate_autonomous_database_wallet_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_delete_goldengate_connection_assignment_sync.py" }, { "canonical": true, @@ -3077,19 +3093,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.get_autonomous_database", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.delete_goldengate_connection", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetAutonomousDatabase", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteGoldengateConnection", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "GetAutonomousDatabase" + "shortName": "DeleteGoldengateConnection" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.GetAutonomousDatabaseRequest" + "type": "google.cloud.oracledatabase_v1.types.DeleteGoldengateConnectionRequest" }, { "name": "name", @@ -3108,22 +3124,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.types.AutonomousDatabase", - "shortName": "get_autonomous_database" + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "delete_goldengate_connection" }, - "description": "Sample for GetAutonomousDatabase", - "file": "oracledatabase_v1_generated_oracle_database_get_autonomous_database_async.py", + "description": "Sample for DeleteGoldengateConnection", + "file": "oracledatabase_v1_generated_oracle_database_delete_goldengate_connection_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetAutonomousDatabase_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteGoldengateConnection_async", "segments": [ { - "end": 51, + "end": 55, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 55, "start": 27, "type": "SHORT" }, @@ -3138,17 +3154,17 @@ "type": "REQUEST_INITIALIZATION" }, { - "end": 48, + "end": 52, "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 52, - "start": 49, + "end": 56, + "start": 53, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_get_autonomous_database_async.py" + "title": "oracledatabase_v1_generated_oracle_database_delete_goldengate_connection_async.py" }, { "canonical": true, @@ -3157,19 +3173,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.get_autonomous_database", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_goldengate_connection", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetAutonomousDatabase", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteGoldengateConnection", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "GetAutonomousDatabase" + "shortName": "DeleteGoldengateConnection" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.GetAutonomousDatabaseRequest" + "type": "google.cloud.oracledatabase_v1.types.DeleteGoldengateConnectionRequest" }, { "name": "name", @@ -3188,22 +3204,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.types.AutonomousDatabase", - "shortName": "get_autonomous_database" + "resultType": "google.api_core.operation.Operation", + "shortName": "delete_goldengate_connection" }, - "description": "Sample for GetAutonomousDatabase", - "file": "oracledatabase_v1_generated_oracle_database_get_autonomous_database_sync.py", + "description": "Sample for DeleteGoldengateConnection", + "file": "oracledatabase_v1_generated_oracle_database_delete_goldengate_connection_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetAutonomousDatabase_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteGoldengateConnection_sync", "segments": [ { - "end": 51, + "end": 55, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 55, "start": 27, "type": "SHORT" }, @@ -3218,17 +3234,17 @@ "type": "REQUEST_INITIALIZATION" }, { - "end": 48, + "end": 52, "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 52, - "start": 49, + "end": 56, + "start": 53, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_get_autonomous_database_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_delete_goldengate_connection_sync.py" }, { "canonical": true, @@ -3238,19 +3254,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.get_cloud_exadata_infrastructure", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.delete_goldengate_deployment", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetCloudExadataInfrastructure", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteGoldengateDeployment", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "GetCloudExadataInfrastructure" + "shortName": "DeleteGoldengateDeployment" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.GetCloudExadataInfrastructureRequest" + "type": "google.cloud.oracledatabase_v1.types.DeleteGoldengateDeploymentRequest" }, { "name": "name", @@ -3269,22 +3285,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.types.CloudExadataInfrastructure", - "shortName": "get_cloud_exadata_infrastructure" + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "delete_goldengate_deployment" }, - "description": "Sample for GetCloudExadataInfrastructure", - "file": "oracledatabase_v1_generated_oracle_database_get_cloud_exadata_infrastructure_async.py", + "description": "Sample for DeleteGoldengateDeployment", + "file": "oracledatabase_v1_generated_oracle_database_delete_goldengate_deployment_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetCloudExadataInfrastructure_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteGoldengateDeployment_async", "segments": [ { - "end": 51, + "end": 55, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 55, "start": 27, "type": "SHORT" }, @@ -3299,17 +3315,17 @@ "type": "REQUEST_INITIALIZATION" }, { - "end": 48, + "end": 52, "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 52, - "start": 49, + "end": 56, + "start": 53, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_get_cloud_exadata_infrastructure_async.py" + "title": "oracledatabase_v1_generated_oracle_database_delete_goldengate_deployment_async.py" }, { "canonical": true, @@ -3318,19 +3334,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.get_cloud_exadata_infrastructure", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_goldengate_deployment", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetCloudExadataInfrastructure", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteGoldengateDeployment", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "GetCloudExadataInfrastructure" + "shortName": "DeleteGoldengateDeployment" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.GetCloudExadataInfrastructureRequest" + "type": "google.cloud.oracledatabase_v1.types.DeleteGoldengateDeploymentRequest" }, { "name": "name", @@ -3349,22 +3365,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.types.CloudExadataInfrastructure", - "shortName": "get_cloud_exadata_infrastructure" + "resultType": "google.api_core.operation.Operation", + "shortName": "delete_goldengate_deployment" }, - "description": "Sample for GetCloudExadataInfrastructure", - "file": "oracledatabase_v1_generated_oracle_database_get_cloud_exadata_infrastructure_sync.py", + "description": "Sample for DeleteGoldengateDeployment", + "file": "oracledatabase_v1_generated_oracle_database_delete_goldengate_deployment_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetCloudExadataInfrastructure_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteGoldengateDeployment_sync", "segments": [ { - "end": 51, + "end": 55, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 55, "start": 27, "type": "SHORT" }, @@ -3379,17 +3395,17 @@ "type": "REQUEST_INITIALIZATION" }, { - "end": 48, + "end": 52, "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 52, - "start": 49, + "end": 56, + "start": 53, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_get_cloud_exadata_infrastructure_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_delete_goldengate_deployment_sync.py" }, { "canonical": true, @@ -3399,19 +3415,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.get_cloud_vm_cluster", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.delete_odb_network", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetCloudVmCluster", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteOdbNetwork", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "GetCloudVmCluster" + "shortName": "DeleteOdbNetwork" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.GetCloudVmClusterRequest" + "type": "google.cloud.oracledatabase_v1.types.DeleteOdbNetworkRequest" }, { "name": "name", @@ -3430,22 +3446,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.types.CloudVmCluster", - "shortName": "get_cloud_vm_cluster" + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "delete_odb_network" }, - "description": "Sample for GetCloudVmCluster", - "file": "oracledatabase_v1_generated_oracle_database_get_cloud_vm_cluster_async.py", + "description": "Sample for DeleteOdbNetwork", + "file": "oracledatabase_v1_generated_oracle_database_delete_odb_network_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetCloudVmCluster_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteOdbNetwork_async", "segments": [ { - "end": 51, + "end": 55, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 55, "start": 27, "type": "SHORT" }, @@ -3460,17 +3476,17 @@ "type": "REQUEST_INITIALIZATION" }, { - "end": 48, + "end": 52, "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 52, - "start": 49, + "end": 56, + "start": 53, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_get_cloud_vm_cluster_async.py" + "title": "oracledatabase_v1_generated_oracle_database_delete_odb_network_async.py" }, { "canonical": true, @@ -3479,19 +3495,1017 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.get_cloud_vm_cluster", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_odb_network", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetCloudVmCluster", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteOdbNetwork", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "GetCloudVmCluster" + "shortName": "DeleteOdbNetwork" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.GetCloudVmClusterRequest" + "type": "google.cloud.oracledatabase_v1.types.DeleteOdbNetworkRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "delete_odb_network" + }, + "description": "Sample for DeleteOdbNetwork", + "file": "oracledatabase_v1_generated_oracle_database_delete_odb_network_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteOdbNetwork_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_delete_odb_network_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", + "shortName": "OracleDatabaseAsyncClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.delete_odb_subnet", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteOdbSubnet", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "DeleteOdbSubnet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.DeleteOdbSubnetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "delete_odb_subnet" + }, + "description": "Sample for DeleteOdbSubnet", + "file": "oracledatabase_v1_generated_oracle_database_delete_odb_subnet_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteOdbSubnet_async", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_delete_odb_subnet_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", + "shortName": "OracleDatabaseClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.delete_odb_subnet", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.DeleteOdbSubnet", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "DeleteOdbSubnet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.DeleteOdbSubnetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "delete_odb_subnet" + }, + "description": "Sample for DeleteOdbSubnet", + "file": "oracledatabase_v1_generated_oracle_database_delete_odb_subnet_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_DeleteOdbSubnet_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_delete_odb_subnet_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", + "shortName": "OracleDatabaseAsyncClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.failover_autonomous_database", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.FailoverAutonomousDatabase", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "FailoverAutonomousDatabase" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.FailoverAutonomousDatabaseRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "peer_autonomous_database", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "failover_autonomous_database" + }, + "description": "Sample for FailoverAutonomousDatabase", + "file": "oracledatabase_v1_generated_oracle_database_failover_autonomous_database_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_FailoverAutonomousDatabase_async", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_failover_autonomous_database_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", + "shortName": "OracleDatabaseClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.failover_autonomous_database", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.FailoverAutonomousDatabase", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "FailoverAutonomousDatabase" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.FailoverAutonomousDatabaseRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "peer_autonomous_database", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "failover_autonomous_database" + }, + "description": "Sample for FailoverAutonomousDatabase", + "file": "oracledatabase_v1_generated_oracle_database_failover_autonomous_database_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_FailoverAutonomousDatabase_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_failover_autonomous_database_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", + "shortName": "OracleDatabaseAsyncClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.generate_autonomous_database_wallet", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GenerateAutonomousDatabaseWallet", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GenerateAutonomousDatabaseWallet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GenerateAutonomousDatabaseWalletRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "type_", + "type": "google.cloud.oracledatabase_v1.types.GenerateType" + }, + { + "name": "is_regional", + "type": "bool" + }, + { + "name": "password", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.GenerateAutonomousDatabaseWalletResponse", + "shortName": "generate_autonomous_database_wallet" + }, + "description": "Sample for GenerateAutonomousDatabaseWallet", + "file": "oracledatabase_v1_generated_oracle_database_generate_autonomous_database_wallet_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GenerateAutonomousDatabaseWallet_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_generate_autonomous_database_wallet_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", + "shortName": "OracleDatabaseClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.generate_autonomous_database_wallet", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GenerateAutonomousDatabaseWallet", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GenerateAutonomousDatabaseWallet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GenerateAutonomousDatabaseWalletRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "type_", + "type": "google.cloud.oracledatabase_v1.types.GenerateType" + }, + { + "name": "is_regional", + "type": "bool" + }, + { + "name": "password", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.GenerateAutonomousDatabaseWalletResponse", + "shortName": "generate_autonomous_database_wallet" + }, + "description": "Sample for GenerateAutonomousDatabaseWallet", + "file": "oracledatabase_v1_generated_oracle_database_generate_autonomous_database_wallet_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GenerateAutonomousDatabaseWallet_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_generate_autonomous_database_wallet_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", + "shortName": "OracleDatabaseAsyncClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.get_autonomous_database", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetAutonomousDatabase", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetAutonomousDatabase" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetAutonomousDatabaseRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.AutonomousDatabase", + "shortName": "get_autonomous_database" + }, + "description": "Sample for GetAutonomousDatabase", + "file": "oracledatabase_v1_generated_oracle_database_get_autonomous_database_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetAutonomousDatabase_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_autonomous_database_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", + "shortName": "OracleDatabaseClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.get_autonomous_database", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetAutonomousDatabase", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetAutonomousDatabase" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetAutonomousDatabaseRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.AutonomousDatabase", + "shortName": "get_autonomous_database" + }, + "description": "Sample for GetAutonomousDatabase", + "file": "oracledatabase_v1_generated_oracle_database_get_autonomous_database_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetAutonomousDatabase_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_autonomous_database_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", + "shortName": "OracleDatabaseAsyncClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.get_cloud_exadata_infrastructure", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetCloudExadataInfrastructure", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetCloudExadataInfrastructure" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetCloudExadataInfrastructureRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.CloudExadataInfrastructure", + "shortName": "get_cloud_exadata_infrastructure" + }, + "description": "Sample for GetCloudExadataInfrastructure", + "file": "oracledatabase_v1_generated_oracle_database_get_cloud_exadata_infrastructure_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetCloudExadataInfrastructure_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_cloud_exadata_infrastructure_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", + "shortName": "OracleDatabaseClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.get_cloud_exadata_infrastructure", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetCloudExadataInfrastructure", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetCloudExadataInfrastructure" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetCloudExadataInfrastructureRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.CloudExadataInfrastructure", + "shortName": "get_cloud_exadata_infrastructure" + }, + "description": "Sample for GetCloudExadataInfrastructure", + "file": "oracledatabase_v1_generated_oracle_database_get_cloud_exadata_infrastructure_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetCloudExadataInfrastructure_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_cloud_exadata_infrastructure_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", + "shortName": "OracleDatabaseAsyncClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.get_cloud_vm_cluster", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetCloudVmCluster", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetCloudVmCluster" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetCloudVmClusterRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.CloudVmCluster", + "shortName": "get_cloud_vm_cluster" + }, + "description": "Sample for GetCloudVmCluster", + "file": "oracledatabase_v1_generated_oracle_database_get_cloud_vm_cluster_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetCloudVmCluster_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_cloud_vm_cluster_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", + "shortName": "OracleDatabaseClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.get_cloud_vm_cluster", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetCloudVmCluster", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetCloudVmCluster" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetCloudVmClusterRequest" }, { "name": "name", @@ -3513,19 +4527,2756 @@ "resultType": "google.cloud.oracledatabase_v1.types.CloudVmCluster", "shortName": "get_cloud_vm_cluster" }, - "description": "Sample for GetCloudVmCluster", - "file": "oracledatabase_v1_generated_oracle_database_get_cloud_vm_cluster_sync.py", + "description": "Sample for GetCloudVmCluster", + "file": "oracledatabase_v1_generated_oracle_database_get_cloud_vm_cluster_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetCloudVmCluster_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_cloud_vm_cluster_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", + "shortName": "OracleDatabaseAsyncClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.get_database", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetDatabase", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetDatabase" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetDatabaseRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.Database", + "shortName": "get_database" + }, + "description": "Sample for GetDatabase", + "file": "oracledatabase_v1_generated_oracle_database_get_database_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetDatabase_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_database_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", + "shortName": "OracleDatabaseClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.get_database", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetDatabase", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetDatabase" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetDatabaseRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.Database", + "shortName": "get_database" + }, + "description": "Sample for GetDatabase", + "file": "oracledatabase_v1_generated_oracle_database_get_database_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetDatabase_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_database_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", + "shortName": "OracleDatabaseAsyncClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.get_db_system", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetDbSystem", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetDbSystem" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetDbSystemRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.DbSystem", + "shortName": "get_db_system" + }, + "description": "Sample for GetDbSystem", + "file": "oracledatabase_v1_generated_oracle_database_get_db_system_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetDbSystem_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_db_system_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", + "shortName": "OracleDatabaseClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.get_db_system", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetDbSystem", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetDbSystem" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetDbSystemRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.DbSystem", + "shortName": "get_db_system" + }, + "description": "Sample for GetDbSystem", + "file": "oracledatabase_v1_generated_oracle_database_get_db_system_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetDbSystem_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_db_system_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", + "shortName": "OracleDatabaseAsyncClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.get_exadb_vm_cluster", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetExadbVmCluster", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetExadbVmCluster" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetExadbVmClusterRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.ExadbVmCluster", + "shortName": "get_exadb_vm_cluster" + }, + "description": "Sample for GetExadbVmCluster", + "file": "oracledatabase_v1_generated_oracle_database_get_exadb_vm_cluster_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetExadbVmCluster_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_exadb_vm_cluster_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", + "shortName": "OracleDatabaseClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.get_exadb_vm_cluster", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetExadbVmCluster", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetExadbVmCluster" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetExadbVmClusterRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.ExadbVmCluster", + "shortName": "get_exadb_vm_cluster" + }, + "description": "Sample for GetExadbVmCluster", + "file": "oracledatabase_v1_generated_oracle_database_get_exadb_vm_cluster_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetExadbVmCluster_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_exadb_vm_cluster_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", + "shortName": "OracleDatabaseAsyncClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.get_exascale_db_storage_vault", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetExascaleDbStorageVault", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetExascaleDbStorageVault" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetExascaleDbStorageVaultRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.ExascaleDbStorageVault", + "shortName": "get_exascale_db_storage_vault" + }, + "description": "Sample for GetExascaleDbStorageVault", + "file": "oracledatabase_v1_generated_oracle_database_get_exascale_db_storage_vault_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetExascaleDbStorageVault_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_exascale_db_storage_vault_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", + "shortName": "OracleDatabaseClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.get_exascale_db_storage_vault", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetExascaleDbStorageVault", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetExascaleDbStorageVault" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetExascaleDbStorageVaultRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.ExascaleDbStorageVault", + "shortName": "get_exascale_db_storage_vault" + }, + "description": "Sample for GetExascaleDbStorageVault", + "file": "oracledatabase_v1_generated_oracle_database_get_exascale_db_storage_vault_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetExascaleDbStorageVault_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_exascale_db_storage_vault_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", + "shortName": "OracleDatabaseAsyncClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.get_goldengate_connection_assignment", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetGoldengateConnectionAssignment", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetGoldengateConnectionAssignment" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetGoldengateConnectionAssignmentRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.GoldengateConnectionAssignment", + "shortName": "get_goldengate_connection_assignment" + }, + "description": "Sample for GetGoldengateConnectionAssignment", + "file": "oracledatabase_v1_generated_oracle_database_get_goldengate_connection_assignment_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetGoldengateConnectionAssignment_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_goldengate_connection_assignment_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", + "shortName": "OracleDatabaseClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.get_goldengate_connection_assignment", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetGoldengateConnectionAssignment", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetGoldengateConnectionAssignment" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetGoldengateConnectionAssignmentRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.GoldengateConnectionAssignment", + "shortName": "get_goldengate_connection_assignment" + }, + "description": "Sample for GetGoldengateConnectionAssignment", + "file": "oracledatabase_v1_generated_oracle_database_get_goldengate_connection_assignment_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetGoldengateConnectionAssignment_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_goldengate_connection_assignment_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", + "shortName": "OracleDatabaseAsyncClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.get_goldengate_connection_type", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetGoldengateConnectionType", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetGoldengateConnectionType" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetGoldengateConnectionTypeRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.GoldengateConnectionType", + "shortName": "get_goldengate_connection_type" + }, + "description": "Sample for GetGoldengateConnectionType", + "file": "oracledatabase_v1_generated_oracle_database_get_goldengate_connection_type_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetGoldengateConnectionType_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_goldengate_connection_type_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", + "shortName": "OracleDatabaseClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.get_goldengate_connection_type", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetGoldengateConnectionType", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetGoldengateConnectionType" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetGoldengateConnectionTypeRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.GoldengateConnectionType", + "shortName": "get_goldengate_connection_type" + }, + "description": "Sample for GetGoldengateConnectionType", + "file": "oracledatabase_v1_generated_oracle_database_get_goldengate_connection_type_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetGoldengateConnectionType_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_goldengate_connection_type_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", + "shortName": "OracleDatabaseAsyncClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.get_goldengate_connection", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetGoldengateConnection", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetGoldengateConnection" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetGoldengateConnectionRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.GoldengateConnection", + "shortName": "get_goldengate_connection" + }, + "description": "Sample for GetGoldengateConnection", + "file": "oracledatabase_v1_generated_oracle_database_get_goldengate_connection_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetGoldengateConnection_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_goldengate_connection_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", + "shortName": "OracleDatabaseClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.get_goldengate_connection", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetGoldengateConnection", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetGoldengateConnection" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetGoldengateConnectionRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.GoldengateConnection", + "shortName": "get_goldengate_connection" + }, + "description": "Sample for GetGoldengateConnection", + "file": "oracledatabase_v1_generated_oracle_database_get_goldengate_connection_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetGoldengateConnection_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_goldengate_connection_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", + "shortName": "OracleDatabaseAsyncClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.get_goldengate_deployment_environment", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetGoldengateDeploymentEnvironment", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetGoldengateDeploymentEnvironment" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetGoldengateDeploymentEnvironmentRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.GoldengateDeploymentEnvironment", + "shortName": "get_goldengate_deployment_environment" + }, + "description": "Sample for GetGoldengateDeploymentEnvironment", + "file": "oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_environment_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetGoldengateDeploymentEnvironment_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_environment_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", + "shortName": "OracleDatabaseClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.get_goldengate_deployment_environment", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetGoldengateDeploymentEnvironment", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetGoldengateDeploymentEnvironment" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetGoldengateDeploymentEnvironmentRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.GoldengateDeploymentEnvironment", + "shortName": "get_goldengate_deployment_environment" + }, + "description": "Sample for GetGoldengateDeploymentEnvironment", + "file": "oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_environment_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetGoldengateDeploymentEnvironment_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_environment_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", + "shortName": "OracleDatabaseAsyncClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.get_goldengate_deployment_type", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetGoldengateDeploymentType", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetGoldengateDeploymentType" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetGoldengateDeploymentTypeRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.GoldengateDeploymentType", + "shortName": "get_goldengate_deployment_type" + }, + "description": "Sample for GetGoldengateDeploymentType", + "file": "oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_type_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetGoldengateDeploymentType_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_type_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", + "shortName": "OracleDatabaseClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.get_goldengate_deployment_type", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetGoldengateDeploymentType", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetGoldengateDeploymentType" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetGoldengateDeploymentTypeRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.GoldengateDeploymentType", + "shortName": "get_goldengate_deployment_type" + }, + "description": "Sample for GetGoldengateDeploymentType", + "file": "oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_type_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetGoldengateDeploymentType_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_type_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", + "shortName": "OracleDatabaseAsyncClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.get_goldengate_deployment_version", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetGoldengateDeploymentVersion", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetGoldengateDeploymentVersion" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetGoldengateDeploymentVersionRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.GoldengateDeploymentVersion", + "shortName": "get_goldengate_deployment_version" + }, + "description": "Sample for GetGoldengateDeploymentVersion", + "file": "oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_version_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetGoldengateDeploymentVersion_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_version_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", + "shortName": "OracleDatabaseClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.get_goldengate_deployment_version", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetGoldengateDeploymentVersion", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetGoldengateDeploymentVersion" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetGoldengateDeploymentVersionRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.GoldengateDeploymentVersion", + "shortName": "get_goldengate_deployment_version" + }, + "description": "Sample for GetGoldengateDeploymentVersion", + "file": "oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_version_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetGoldengateDeploymentVersion_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_version_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", + "shortName": "OracleDatabaseAsyncClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.get_goldengate_deployment", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetGoldengateDeployment", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetGoldengateDeployment" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetGoldengateDeploymentRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.GoldengateDeployment", + "shortName": "get_goldengate_deployment" + }, + "description": "Sample for GetGoldengateDeployment", + "file": "oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetGoldengateDeployment_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", + "shortName": "OracleDatabaseClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.get_goldengate_deployment", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetGoldengateDeployment", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetGoldengateDeployment" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetGoldengateDeploymentRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.GoldengateDeployment", + "shortName": "get_goldengate_deployment" + }, + "description": "Sample for GetGoldengateDeployment", + "file": "oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetGoldengateDeployment_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", + "shortName": "OracleDatabaseAsyncClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.get_odb_network", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetOdbNetwork", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetOdbNetwork" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetOdbNetworkRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.OdbNetwork", + "shortName": "get_odb_network" + }, + "description": "Sample for GetOdbNetwork", + "file": "oracledatabase_v1_generated_oracle_database_get_odb_network_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetOdbNetwork_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_odb_network_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", + "shortName": "OracleDatabaseClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.get_odb_network", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetOdbNetwork", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetOdbNetwork" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetOdbNetworkRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.OdbNetwork", + "shortName": "get_odb_network" + }, + "description": "Sample for GetOdbNetwork", + "file": "oracledatabase_v1_generated_oracle_database_get_odb_network_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetOdbNetwork_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_odb_network_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", + "shortName": "OracleDatabaseAsyncClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.get_odb_subnet", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetOdbSubnet", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetOdbSubnet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetOdbSubnetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.OdbSubnet", + "shortName": "get_odb_subnet" + }, + "description": "Sample for GetOdbSubnet", + "file": "oracledatabase_v1_generated_oracle_database_get_odb_subnet_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetOdbSubnet_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_odb_subnet_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", + "shortName": "OracleDatabaseClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.get_odb_subnet", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetOdbSubnet", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetOdbSubnet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetOdbSubnetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.OdbSubnet", + "shortName": "get_odb_subnet" + }, + "description": "Sample for GetOdbSubnet", + "file": "oracledatabase_v1_generated_oracle_database_get_odb_subnet_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetOdbSubnet_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_odb_subnet_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", + "shortName": "OracleDatabaseAsyncClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.get_pluggable_database", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetPluggableDatabase", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetPluggableDatabase" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetPluggableDatabaseRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.PluggableDatabase", + "shortName": "get_pluggable_database" + }, + "description": "Sample for GetPluggableDatabase", + "file": "oracledatabase_v1_generated_oracle_database_get_pluggable_database_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetPluggableDatabase_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_pluggable_database_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", + "shortName": "OracleDatabaseClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.get_pluggable_database", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetPluggableDatabase", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "GetPluggableDatabase" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.GetPluggableDatabaseRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.types.PluggableDatabase", + "shortName": "get_pluggable_database" + }, + "description": "Sample for GetPluggableDatabase", + "file": "oracledatabase_v1_generated_oracle_database_get_pluggable_database_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetPluggableDatabase_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_get_pluggable_database_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", + "shortName": "OracleDatabaseAsyncClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_autonomous_database_backups", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListAutonomousDatabaseBackups", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "ListAutonomousDatabaseBackups" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.ListAutonomousDatabaseBackupsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListAutonomousDatabaseBackupsAsyncPager", + "shortName": "list_autonomous_database_backups" + }, + "description": "Sample for ListAutonomousDatabaseBackups", + "file": "oracledatabase_v1_generated_oracle_database_list_autonomous_database_backups_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListAutonomousDatabaseBackups_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_list_autonomous_database_backups_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", + "shortName": "OracleDatabaseClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_autonomous_database_backups", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListAutonomousDatabaseBackups", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "ListAutonomousDatabaseBackups" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.ListAutonomousDatabaseBackupsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListAutonomousDatabaseBackupsPager", + "shortName": "list_autonomous_database_backups" + }, + "description": "Sample for ListAutonomousDatabaseBackups", + "file": "oracledatabase_v1_generated_oracle_database_list_autonomous_database_backups_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListAutonomousDatabaseBackups_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_list_autonomous_database_backups_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", + "shortName": "OracleDatabaseAsyncClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_autonomous_database_character_sets", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListAutonomousDatabaseCharacterSets", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "ListAutonomousDatabaseCharacterSets" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.ListAutonomousDatabaseCharacterSetsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListAutonomousDatabaseCharacterSetsAsyncPager", + "shortName": "list_autonomous_database_character_sets" + }, + "description": "Sample for ListAutonomousDatabaseCharacterSets", + "file": "oracledatabase_v1_generated_oracle_database_list_autonomous_database_character_sets_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListAutonomousDatabaseCharacterSets_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_list_autonomous_database_character_sets_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", + "shortName": "OracleDatabaseClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_autonomous_database_character_sets", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListAutonomousDatabaseCharacterSets", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "ListAutonomousDatabaseCharacterSets" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.ListAutonomousDatabaseCharacterSetsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListAutonomousDatabaseCharacterSetsPager", + "shortName": "list_autonomous_database_character_sets" + }, + "description": "Sample for ListAutonomousDatabaseCharacterSets", + "file": "oracledatabase_v1_generated_oracle_database_list_autonomous_database_character_sets_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListAutonomousDatabaseCharacterSets_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_list_autonomous_database_character_sets_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", + "shortName": "OracleDatabaseAsyncClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_autonomous_databases", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListAutonomousDatabases", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "ListAutonomousDatabases" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.ListAutonomousDatabasesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListAutonomousDatabasesAsyncPager", + "shortName": "list_autonomous_databases" + }, + "description": "Sample for ListAutonomousDatabases", + "file": "oracledatabase_v1_generated_oracle_database_list_autonomous_databases_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListAutonomousDatabases_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "oracledatabase_v1_generated_oracle_database_list_autonomous_databases_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", + "shortName": "OracleDatabaseClient" + }, + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_autonomous_databases", + "method": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListAutonomousDatabases", + "service": { + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", + "shortName": "OracleDatabase" + }, + "shortName": "ListAutonomousDatabases" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.oracledatabase_v1.types.ListAutonomousDatabasesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListAutonomousDatabasesPager", + "shortName": "list_autonomous_databases" + }, + "description": "Sample for ListAutonomousDatabases", + "file": "oracledatabase_v1_generated_oracle_database_list_autonomous_databases_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetCloudVmCluster_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListAutonomousDatabases_sync", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -3545,12 +7296,12 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_get_cloud_vm_cluster_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_list_autonomous_databases_sync.py" }, { "canonical": true, @@ -3560,22 +7311,22 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.get_database", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_autonomous_db_versions", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetDatabase", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListAutonomousDbVersions", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "GetDatabase" + "shortName": "ListAutonomousDbVersions" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.GetDatabaseRequest" + "type": "google.cloud.oracledatabase_v1.types.ListAutonomousDbVersionsRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -3591,22 +7342,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.types.Database", - "shortName": "get_database" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListAutonomousDbVersionsAsyncPager", + "shortName": "list_autonomous_db_versions" }, - "description": "Sample for GetDatabase", - "file": "oracledatabase_v1_generated_oracle_database_get_database_async.py", + "description": "Sample for ListAutonomousDbVersions", + "file": "oracledatabase_v1_generated_oracle_database_list_autonomous_db_versions_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetDatabase_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListAutonomousDbVersions_async", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -3626,12 +7377,12 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_get_database_async.py" + "title": "oracledatabase_v1_generated_oracle_database_list_autonomous_db_versions_async.py" }, { "canonical": true, @@ -3640,22 +7391,22 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.get_database", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_autonomous_db_versions", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetDatabase", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListAutonomousDbVersions", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "GetDatabase" + "shortName": "ListAutonomousDbVersions" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.GetDatabaseRequest" + "type": "google.cloud.oracledatabase_v1.types.ListAutonomousDbVersionsRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -3671,22 +7422,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.types.Database", - "shortName": "get_database" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListAutonomousDbVersionsPager", + "shortName": "list_autonomous_db_versions" }, - "description": "Sample for GetDatabase", - "file": "oracledatabase_v1_generated_oracle_database_get_database_sync.py", + "description": "Sample for ListAutonomousDbVersions", + "file": "oracledatabase_v1_generated_oracle_database_list_autonomous_db_versions_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetDatabase_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListAutonomousDbVersions_sync", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -3706,12 +7457,12 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_get_database_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_list_autonomous_db_versions_sync.py" }, { "canonical": true, @@ -3721,22 +7472,22 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.get_db_system", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_cloud_exadata_infrastructures", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetDbSystem", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListCloudExadataInfrastructures", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "GetDbSystem" + "shortName": "ListCloudExadataInfrastructures" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.GetDbSystemRequest" + "type": "google.cloud.oracledatabase_v1.types.ListCloudExadataInfrastructuresRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -3752,22 +7503,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.types.DbSystem", - "shortName": "get_db_system" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListCloudExadataInfrastructuresAsyncPager", + "shortName": "list_cloud_exadata_infrastructures" }, - "description": "Sample for GetDbSystem", - "file": "oracledatabase_v1_generated_oracle_database_get_db_system_async.py", + "description": "Sample for ListCloudExadataInfrastructures", + "file": "oracledatabase_v1_generated_oracle_database_list_cloud_exadata_infrastructures_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetDbSystem_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListCloudExadataInfrastructures_async", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -3787,12 +7538,12 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_get_db_system_async.py" + "title": "oracledatabase_v1_generated_oracle_database_list_cloud_exadata_infrastructures_async.py" }, { "canonical": true, @@ -3801,22 +7552,22 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.get_db_system", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_cloud_exadata_infrastructures", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetDbSystem", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListCloudExadataInfrastructures", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "GetDbSystem" + "shortName": "ListCloudExadataInfrastructures" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.GetDbSystemRequest" + "type": "google.cloud.oracledatabase_v1.types.ListCloudExadataInfrastructuresRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -3832,22 +7583,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.types.DbSystem", - "shortName": "get_db_system" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListCloudExadataInfrastructuresPager", + "shortName": "list_cloud_exadata_infrastructures" }, - "description": "Sample for GetDbSystem", - "file": "oracledatabase_v1_generated_oracle_database_get_db_system_sync.py", + "description": "Sample for ListCloudExadataInfrastructures", + "file": "oracledatabase_v1_generated_oracle_database_list_cloud_exadata_infrastructures_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetDbSystem_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListCloudExadataInfrastructures_sync", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -3867,12 +7618,12 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_get_db_system_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_list_cloud_exadata_infrastructures_sync.py" }, { "canonical": true, @@ -3882,22 +7633,22 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.get_exadb_vm_cluster", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_cloud_vm_clusters", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetExadbVmCluster", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListCloudVmClusters", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "GetExadbVmCluster" + "shortName": "ListCloudVmClusters" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.GetExadbVmClusterRequest" + "type": "google.cloud.oracledatabase_v1.types.ListCloudVmClustersRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -3913,22 +7664,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.types.ExadbVmCluster", - "shortName": "get_exadb_vm_cluster" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListCloudVmClustersAsyncPager", + "shortName": "list_cloud_vm_clusters" }, - "description": "Sample for GetExadbVmCluster", - "file": "oracledatabase_v1_generated_oracle_database_get_exadb_vm_cluster_async.py", + "description": "Sample for ListCloudVmClusters", + "file": "oracledatabase_v1_generated_oracle_database_list_cloud_vm_clusters_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetExadbVmCluster_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListCloudVmClusters_async", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -3948,12 +7699,12 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_get_exadb_vm_cluster_async.py" + "title": "oracledatabase_v1_generated_oracle_database_list_cloud_vm_clusters_async.py" }, { "canonical": true, @@ -3962,22 +7713,22 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.get_exadb_vm_cluster", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_cloud_vm_clusters", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetExadbVmCluster", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListCloudVmClusters", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "GetExadbVmCluster" + "shortName": "ListCloudVmClusters" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.GetExadbVmClusterRequest" + "type": "google.cloud.oracledatabase_v1.types.ListCloudVmClustersRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -3993,22 +7744,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.types.ExadbVmCluster", - "shortName": "get_exadb_vm_cluster" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListCloudVmClustersPager", + "shortName": "list_cloud_vm_clusters" }, - "description": "Sample for GetExadbVmCluster", - "file": "oracledatabase_v1_generated_oracle_database_get_exadb_vm_cluster_sync.py", + "description": "Sample for ListCloudVmClusters", + "file": "oracledatabase_v1_generated_oracle_database_list_cloud_vm_clusters_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetExadbVmCluster_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListCloudVmClusters_sync", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -4028,12 +7779,12 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_get_exadb_vm_cluster_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_list_cloud_vm_clusters_sync.py" }, { "canonical": true, @@ -4043,22 +7794,22 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.get_exascale_db_storage_vault", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_database_character_sets", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetExascaleDbStorageVault", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDatabaseCharacterSets", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "GetExascaleDbStorageVault" + "shortName": "ListDatabaseCharacterSets" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.GetExascaleDbStorageVaultRequest" + "type": "google.cloud.oracledatabase_v1.types.ListDatabaseCharacterSetsRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -4074,22 +7825,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.types.ExascaleDbStorageVault", - "shortName": "get_exascale_db_storage_vault" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDatabaseCharacterSetsAsyncPager", + "shortName": "list_database_character_sets" }, - "description": "Sample for GetExascaleDbStorageVault", - "file": "oracledatabase_v1_generated_oracle_database_get_exascale_db_storage_vault_async.py", + "description": "Sample for ListDatabaseCharacterSets", + "file": "oracledatabase_v1_generated_oracle_database_list_database_character_sets_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetExascaleDbStorageVault_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDatabaseCharacterSets_async", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -4109,12 +7860,12 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_get_exascale_db_storage_vault_async.py" + "title": "oracledatabase_v1_generated_oracle_database_list_database_character_sets_async.py" }, { "canonical": true, @@ -4123,22 +7874,22 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.get_exascale_db_storage_vault", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_database_character_sets", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetExascaleDbStorageVault", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDatabaseCharacterSets", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "GetExascaleDbStorageVault" + "shortName": "ListDatabaseCharacterSets" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.GetExascaleDbStorageVaultRequest" + "type": "google.cloud.oracledatabase_v1.types.ListDatabaseCharacterSetsRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -4154,22 +7905,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.types.ExascaleDbStorageVault", - "shortName": "get_exascale_db_storage_vault" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDatabaseCharacterSetsPager", + "shortName": "list_database_character_sets" }, - "description": "Sample for GetExascaleDbStorageVault", - "file": "oracledatabase_v1_generated_oracle_database_get_exascale_db_storage_vault_sync.py", + "description": "Sample for ListDatabaseCharacterSets", + "file": "oracledatabase_v1_generated_oracle_database_list_database_character_sets_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetExascaleDbStorageVault_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDatabaseCharacterSets_sync", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -4189,12 +7940,12 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_get_exascale_db_storage_vault_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_list_database_character_sets_sync.py" }, { "canonical": true, @@ -4204,22 +7955,22 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.get_odb_network", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_databases", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetOdbNetwork", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDatabases", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "GetOdbNetwork" + "shortName": "ListDatabases" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.GetOdbNetworkRequest" + "type": "google.cloud.oracledatabase_v1.types.ListDatabasesRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -4235,22 +7986,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.types.OdbNetwork", - "shortName": "get_odb_network" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDatabasesAsyncPager", + "shortName": "list_databases" }, - "description": "Sample for GetOdbNetwork", - "file": "oracledatabase_v1_generated_oracle_database_get_odb_network_async.py", + "description": "Sample for ListDatabases", + "file": "oracledatabase_v1_generated_oracle_database_list_databases_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetOdbNetwork_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDatabases_async", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -4270,12 +8021,12 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_get_odb_network_async.py" + "title": "oracledatabase_v1_generated_oracle_database_list_databases_async.py" }, { "canonical": true, @@ -4284,22 +8035,22 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.get_odb_network", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_databases", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetOdbNetwork", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDatabases", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "GetOdbNetwork" + "shortName": "ListDatabases" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.GetOdbNetworkRequest" + "type": "google.cloud.oracledatabase_v1.types.ListDatabasesRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -4315,22 +8066,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.types.OdbNetwork", - "shortName": "get_odb_network" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDatabasesPager", + "shortName": "list_databases" }, - "description": "Sample for GetOdbNetwork", - "file": "oracledatabase_v1_generated_oracle_database_get_odb_network_sync.py", + "description": "Sample for ListDatabases", + "file": "oracledatabase_v1_generated_oracle_database_list_databases_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetOdbNetwork_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDatabases_sync", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -4350,12 +8101,12 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_get_odb_network_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_list_databases_sync.py" }, { "canonical": true, @@ -4365,22 +8116,22 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.get_odb_subnet", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_db_nodes", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetOdbSubnet", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDbNodes", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "GetOdbSubnet" + "shortName": "ListDbNodes" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.GetOdbSubnetRequest" + "type": "google.cloud.oracledatabase_v1.types.ListDbNodesRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -4396,22 +8147,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.types.OdbSubnet", - "shortName": "get_odb_subnet" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDbNodesAsyncPager", + "shortName": "list_db_nodes" }, - "description": "Sample for GetOdbSubnet", - "file": "oracledatabase_v1_generated_oracle_database_get_odb_subnet_async.py", + "description": "Sample for ListDbNodes", + "file": "oracledatabase_v1_generated_oracle_database_list_db_nodes_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetOdbSubnet_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDbNodes_async", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -4431,12 +8182,12 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_get_odb_subnet_async.py" + "title": "oracledatabase_v1_generated_oracle_database_list_db_nodes_async.py" }, { "canonical": true, @@ -4445,22 +8196,22 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.get_odb_subnet", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_db_nodes", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetOdbSubnet", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDbNodes", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "GetOdbSubnet" + "shortName": "ListDbNodes" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.GetOdbSubnetRequest" + "type": "google.cloud.oracledatabase_v1.types.ListDbNodesRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -4476,22 +8227,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.types.OdbSubnet", - "shortName": "get_odb_subnet" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDbNodesPager", + "shortName": "list_db_nodes" }, - "description": "Sample for GetOdbSubnet", - "file": "oracledatabase_v1_generated_oracle_database_get_odb_subnet_sync.py", + "description": "Sample for ListDbNodes", + "file": "oracledatabase_v1_generated_oracle_database_list_db_nodes_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetOdbSubnet_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDbNodes_sync", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -4511,12 +8262,12 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_get_odb_subnet_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_list_db_nodes_sync.py" }, { "canonical": true, @@ -4526,22 +8277,22 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.get_pluggable_database", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_db_servers", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetPluggableDatabase", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDbServers", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "GetPluggableDatabase" + "shortName": "ListDbServers" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.GetPluggableDatabaseRequest" + "type": "google.cloud.oracledatabase_v1.types.ListDbServersRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -4557,22 +8308,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.types.PluggableDatabase", - "shortName": "get_pluggable_database" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDbServersAsyncPager", + "shortName": "list_db_servers" }, - "description": "Sample for GetPluggableDatabase", - "file": "oracledatabase_v1_generated_oracle_database_get_pluggable_database_async.py", + "description": "Sample for ListDbServers", + "file": "oracledatabase_v1_generated_oracle_database_list_db_servers_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetPluggableDatabase_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDbServers_async", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -4592,12 +8343,12 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_get_pluggable_database_async.py" + "title": "oracledatabase_v1_generated_oracle_database_list_db_servers_async.py" }, { "canonical": true, @@ -4606,22 +8357,22 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.get_pluggable_database", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_db_servers", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.GetPluggableDatabase", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDbServers", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "GetPluggableDatabase" + "shortName": "ListDbServers" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.GetPluggableDatabaseRequest" + "type": "google.cloud.oracledatabase_v1.types.ListDbServersRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -4637,22 +8388,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.types.PluggableDatabase", - "shortName": "get_pluggable_database" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDbServersPager", + "shortName": "list_db_servers" }, - "description": "Sample for GetPluggableDatabase", - "file": "oracledatabase_v1_generated_oracle_database_get_pluggable_database_sync.py", + "description": "Sample for ListDbServers", + "file": "oracledatabase_v1_generated_oracle_database_list_db_servers_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_GetPluggableDatabase_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDbServers_sync", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -4672,12 +8423,12 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_get_pluggable_database_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_list_db_servers_sync.py" }, { "canonical": true, @@ -4687,19 +8438,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_autonomous_database_backups", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_db_system_initial_storage_sizes", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListAutonomousDatabaseBackups", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDbSystemInitialStorageSizes", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListAutonomousDatabaseBackups" + "shortName": "ListDbSystemInitialStorageSizes" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListAutonomousDatabaseBackupsRequest" + "type": "google.cloud.oracledatabase_v1.types.ListDbSystemInitialStorageSizesRequest" }, { "name": "parent", @@ -4718,14 +8469,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListAutonomousDatabaseBackupsAsyncPager", - "shortName": "list_autonomous_database_backups" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDbSystemInitialStorageSizesAsyncPager", + "shortName": "list_db_system_initial_storage_sizes" }, - "description": "Sample for ListAutonomousDatabaseBackups", - "file": "oracledatabase_v1_generated_oracle_database_list_autonomous_database_backups_async.py", + "description": "Sample for ListDbSystemInitialStorageSizes", + "file": "oracledatabase_v1_generated_oracle_database_list_db_system_initial_storage_sizes_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListAutonomousDatabaseBackups_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDbSystemInitialStorageSizes_async", "segments": [ { "end": 52, @@ -4758,7 +8509,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_autonomous_database_backups_async.py" + "title": "oracledatabase_v1_generated_oracle_database_list_db_system_initial_storage_sizes_async.py" }, { "canonical": true, @@ -4767,19 +8518,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_autonomous_database_backups", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_db_system_initial_storage_sizes", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListAutonomousDatabaseBackups", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDbSystemInitialStorageSizes", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListAutonomousDatabaseBackups" + "shortName": "ListDbSystemInitialStorageSizes" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListAutonomousDatabaseBackupsRequest" + "type": "google.cloud.oracledatabase_v1.types.ListDbSystemInitialStorageSizesRequest" }, { "name": "parent", @@ -4798,14 +8549,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListAutonomousDatabaseBackupsPager", - "shortName": "list_autonomous_database_backups" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDbSystemInitialStorageSizesPager", + "shortName": "list_db_system_initial_storage_sizes" }, - "description": "Sample for ListAutonomousDatabaseBackups", - "file": "oracledatabase_v1_generated_oracle_database_list_autonomous_database_backups_sync.py", + "description": "Sample for ListDbSystemInitialStorageSizes", + "file": "oracledatabase_v1_generated_oracle_database_list_db_system_initial_storage_sizes_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListAutonomousDatabaseBackups_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDbSystemInitialStorageSizes_sync", "segments": [ { "end": 52, @@ -4838,7 +8589,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_autonomous_database_backups_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_list_db_system_initial_storage_sizes_sync.py" }, { "canonical": true, @@ -4848,19 +8599,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_autonomous_database_character_sets", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_db_system_shapes", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListAutonomousDatabaseCharacterSets", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDbSystemShapes", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListAutonomousDatabaseCharacterSets" + "shortName": "ListDbSystemShapes" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListAutonomousDatabaseCharacterSetsRequest" + "type": "google.cloud.oracledatabase_v1.types.ListDbSystemShapesRequest" }, { "name": "parent", @@ -4879,14 +8630,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListAutonomousDatabaseCharacterSetsAsyncPager", - "shortName": "list_autonomous_database_character_sets" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDbSystemShapesAsyncPager", + "shortName": "list_db_system_shapes" }, - "description": "Sample for ListAutonomousDatabaseCharacterSets", - "file": "oracledatabase_v1_generated_oracle_database_list_autonomous_database_character_sets_async.py", + "description": "Sample for ListDbSystemShapes", + "file": "oracledatabase_v1_generated_oracle_database_list_db_system_shapes_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListAutonomousDatabaseCharacterSets_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDbSystemShapes_async", "segments": [ { "end": 52, @@ -4919,7 +8670,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_autonomous_database_character_sets_async.py" + "title": "oracledatabase_v1_generated_oracle_database_list_db_system_shapes_async.py" }, { "canonical": true, @@ -4928,19 +8679,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_autonomous_database_character_sets", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_db_system_shapes", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListAutonomousDatabaseCharacterSets", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDbSystemShapes", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListAutonomousDatabaseCharacterSets" + "shortName": "ListDbSystemShapes" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListAutonomousDatabaseCharacterSetsRequest" + "type": "google.cloud.oracledatabase_v1.types.ListDbSystemShapesRequest" }, { "name": "parent", @@ -4959,14 +8710,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListAutonomousDatabaseCharacterSetsPager", - "shortName": "list_autonomous_database_character_sets" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDbSystemShapesPager", + "shortName": "list_db_system_shapes" }, - "description": "Sample for ListAutonomousDatabaseCharacterSets", - "file": "oracledatabase_v1_generated_oracle_database_list_autonomous_database_character_sets_sync.py", + "description": "Sample for ListDbSystemShapes", + "file": "oracledatabase_v1_generated_oracle_database_list_db_system_shapes_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListAutonomousDatabaseCharacterSets_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDbSystemShapes_sync", "segments": [ { "end": 52, @@ -4999,7 +8750,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_autonomous_database_character_sets_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_list_db_system_shapes_sync.py" }, { "canonical": true, @@ -5009,19 +8760,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_autonomous_databases", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_db_systems", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListAutonomousDatabases", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDbSystems", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListAutonomousDatabases" + "shortName": "ListDbSystems" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListAutonomousDatabasesRequest" + "type": "google.cloud.oracledatabase_v1.types.ListDbSystemsRequest" }, { "name": "parent", @@ -5040,14 +8791,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListAutonomousDatabasesAsyncPager", - "shortName": "list_autonomous_databases" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDbSystemsAsyncPager", + "shortName": "list_db_systems" }, - "description": "Sample for ListAutonomousDatabases", - "file": "oracledatabase_v1_generated_oracle_database_list_autonomous_databases_async.py", + "description": "Sample for ListDbSystems", + "file": "oracledatabase_v1_generated_oracle_database_list_db_systems_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListAutonomousDatabases_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDbSystems_async", "segments": [ { "end": 52, @@ -5080,7 +8831,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_autonomous_databases_async.py" + "title": "oracledatabase_v1_generated_oracle_database_list_db_systems_async.py" }, { "canonical": true, @@ -5089,19 +8840,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_autonomous_databases", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_db_systems", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListAutonomousDatabases", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDbSystems", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListAutonomousDatabases" + "shortName": "ListDbSystems" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListAutonomousDatabasesRequest" + "type": "google.cloud.oracledatabase_v1.types.ListDbSystemsRequest" }, { "name": "parent", @@ -5120,14 +8871,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListAutonomousDatabasesPager", - "shortName": "list_autonomous_databases" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDbSystemsPager", + "shortName": "list_db_systems" }, - "description": "Sample for ListAutonomousDatabases", - "file": "oracledatabase_v1_generated_oracle_database_list_autonomous_databases_sync.py", + "description": "Sample for ListDbSystems", + "file": "oracledatabase_v1_generated_oracle_database_list_db_systems_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListAutonomousDatabases_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDbSystems_sync", "segments": [ { "end": 52, @@ -5160,7 +8911,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_autonomous_databases_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_list_db_systems_sync.py" }, { "canonical": true, @@ -5170,19 +8921,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_autonomous_db_versions", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_db_versions", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListAutonomousDbVersions", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDbVersions", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListAutonomousDbVersions" + "shortName": "ListDbVersions" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListAutonomousDbVersionsRequest" + "type": "google.cloud.oracledatabase_v1.types.ListDbVersionsRequest" }, { "name": "parent", @@ -5201,14 +8952,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListAutonomousDbVersionsAsyncPager", - "shortName": "list_autonomous_db_versions" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDbVersionsAsyncPager", + "shortName": "list_db_versions" }, - "description": "Sample for ListAutonomousDbVersions", - "file": "oracledatabase_v1_generated_oracle_database_list_autonomous_db_versions_async.py", + "description": "Sample for ListDbVersions", + "file": "oracledatabase_v1_generated_oracle_database_list_db_versions_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListAutonomousDbVersions_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDbVersions_async", "segments": [ { "end": 52, @@ -5241,7 +8992,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_autonomous_db_versions_async.py" + "title": "oracledatabase_v1_generated_oracle_database_list_db_versions_async.py" }, { "canonical": true, @@ -5250,19 +9001,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_autonomous_db_versions", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_db_versions", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListAutonomousDbVersions", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDbVersions", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListAutonomousDbVersions" + "shortName": "ListDbVersions" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListAutonomousDbVersionsRequest" + "type": "google.cloud.oracledatabase_v1.types.ListDbVersionsRequest" }, { "name": "parent", @@ -5281,14 +9032,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListAutonomousDbVersionsPager", - "shortName": "list_autonomous_db_versions" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDbVersionsPager", + "shortName": "list_db_versions" }, - "description": "Sample for ListAutonomousDbVersions", - "file": "oracledatabase_v1_generated_oracle_database_list_autonomous_db_versions_sync.py", + "description": "Sample for ListDbVersions", + "file": "oracledatabase_v1_generated_oracle_database_list_db_versions_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListAutonomousDbVersions_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDbVersions_sync", "segments": [ { "end": 52, @@ -5321,7 +9072,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_autonomous_db_versions_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_list_db_versions_sync.py" }, { "canonical": true, @@ -5331,19 +9082,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_cloud_exadata_infrastructures", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_entitlements", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListCloudExadataInfrastructures", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListEntitlements", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListCloudExadataInfrastructures" + "shortName": "ListEntitlements" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListCloudExadataInfrastructuresRequest" + "type": "google.cloud.oracledatabase_v1.types.ListEntitlementsRequest" }, { "name": "parent", @@ -5362,14 +9113,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListCloudExadataInfrastructuresAsyncPager", - "shortName": "list_cloud_exadata_infrastructures" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListEntitlementsAsyncPager", + "shortName": "list_entitlements" }, - "description": "Sample for ListCloudExadataInfrastructures", - "file": "oracledatabase_v1_generated_oracle_database_list_cloud_exadata_infrastructures_async.py", + "description": "Sample for ListEntitlements", + "file": "oracledatabase_v1_generated_oracle_database_list_entitlements_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListCloudExadataInfrastructures_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListEntitlements_async", "segments": [ { "end": 52, @@ -5402,7 +9153,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_cloud_exadata_infrastructures_async.py" + "title": "oracledatabase_v1_generated_oracle_database_list_entitlements_async.py" }, { "canonical": true, @@ -5411,19 +9162,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_cloud_exadata_infrastructures", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_entitlements", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListCloudExadataInfrastructures", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListEntitlements", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListCloudExadataInfrastructures" + "shortName": "ListEntitlements" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListCloudExadataInfrastructuresRequest" + "type": "google.cloud.oracledatabase_v1.types.ListEntitlementsRequest" }, { "name": "parent", @@ -5442,14 +9193,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListCloudExadataInfrastructuresPager", - "shortName": "list_cloud_exadata_infrastructures" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListEntitlementsPager", + "shortName": "list_entitlements" }, - "description": "Sample for ListCloudExadataInfrastructures", - "file": "oracledatabase_v1_generated_oracle_database_list_cloud_exadata_infrastructures_sync.py", + "description": "Sample for ListEntitlements", + "file": "oracledatabase_v1_generated_oracle_database_list_entitlements_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListCloudExadataInfrastructures_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListEntitlements_sync", "segments": [ { "end": 52, @@ -5482,7 +9233,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_cloud_exadata_infrastructures_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_list_entitlements_sync.py" }, { "canonical": true, @@ -5492,19 +9243,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_cloud_vm_clusters", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_exadb_vm_clusters", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListCloudVmClusters", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListExadbVmClusters", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListCloudVmClusters" + "shortName": "ListExadbVmClusters" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListCloudVmClustersRequest" + "type": "google.cloud.oracledatabase_v1.types.ListExadbVmClustersRequest" }, { "name": "parent", @@ -5523,14 +9274,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListCloudVmClustersAsyncPager", - "shortName": "list_cloud_vm_clusters" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListExadbVmClustersAsyncPager", + "shortName": "list_exadb_vm_clusters" }, - "description": "Sample for ListCloudVmClusters", - "file": "oracledatabase_v1_generated_oracle_database_list_cloud_vm_clusters_async.py", + "description": "Sample for ListExadbVmClusters", + "file": "oracledatabase_v1_generated_oracle_database_list_exadb_vm_clusters_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListCloudVmClusters_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListExadbVmClusters_async", "segments": [ { "end": 52, @@ -5563,7 +9314,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_cloud_vm_clusters_async.py" + "title": "oracledatabase_v1_generated_oracle_database_list_exadb_vm_clusters_async.py" }, { "canonical": true, @@ -5572,19 +9323,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_cloud_vm_clusters", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_exadb_vm_clusters", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListCloudVmClusters", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListExadbVmClusters", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListCloudVmClusters" + "shortName": "ListExadbVmClusters" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListCloudVmClustersRequest" + "type": "google.cloud.oracledatabase_v1.types.ListExadbVmClustersRequest" }, { "name": "parent", @@ -5603,14 +9354,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListCloudVmClustersPager", - "shortName": "list_cloud_vm_clusters" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListExadbVmClustersPager", + "shortName": "list_exadb_vm_clusters" }, - "description": "Sample for ListCloudVmClusters", - "file": "oracledatabase_v1_generated_oracle_database_list_cloud_vm_clusters_sync.py", + "description": "Sample for ListExadbVmClusters", + "file": "oracledatabase_v1_generated_oracle_database_list_exadb_vm_clusters_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListCloudVmClusters_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListExadbVmClusters_sync", "segments": [ { "end": 52, @@ -5643,7 +9394,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_cloud_vm_clusters_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_list_exadb_vm_clusters_sync.py" }, { "canonical": true, @@ -5653,19 +9404,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_database_character_sets", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_exascale_db_storage_vaults", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDatabaseCharacterSets", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListExascaleDbStorageVaults", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListDatabaseCharacterSets" + "shortName": "ListExascaleDbStorageVaults" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListDatabaseCharacterSetsRequest" + "type": "google.cloud.oracledatabase_v1.types.ListExascaleDbStorageVaultsRequest" }, { "name": "parent", @@ -5684,14 +9435,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDatabaseCharacterSetsAsyncPager", - "shortName": "list_database_character_sets" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListExascaleDbStorageVaultsAsyncPager", + "shortName": "list_exascale_db_storage_vaults" }, - "description": "Sample for ListDatabaseCharacterSets", - "file": "oracledatabase_v1_generated_oracle_database_list_database_character_sets_async.py", + "description": "Sample for ListExascaleDbStorageVaults", + "file": "oracledatabase_v1_generated_oracle_database_list_exascale_db_storage_vaults_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDatabaseCharacterSets_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListExascaleDbStorageVaults_async", "segments": [ { "end": 52, @@ -5724,7 +9475,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_database_character_sets_async.py" + "title": "oracledatabase_v1_generated_oracle_database_list_exascale_db_storage_vaults_async.py" }, { "canonical": true, @@ -5733,19 +9484,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_database_character_sets", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_exascale_db_storage_vaults", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDatabaseCharacterSets", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListExascaleDbStorageVaults", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListDatabaseCharacterSets" + "shortName": "ListExascaleDbStorageVaults" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListDatabaseCharacterSetsRequest" + "type": "google.cloud.oracledatabase_v1.types.ListExascaleDbStorageVaultsRequest" }, { "name": "parent", @@ -5764,14 +9515,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDatabaseCharacterSetsPager", - "shortName": "list_database_character_sets" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListExascaleDbStorageVaultsPager", + "shortName": "list_exascale_db_storage_vaults" }, - "description": "Sample for ListDatabaseCharacterSets", - "file": "oracledatabase_v1_generated_oracle_database_list_database_character_sets_sync.py", + "description": "Sample for ListExascaleDbStorageVaults", + "file": "oracledatabase_v1_generated_oracle_database_list_exascale_db_storage_vaults_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDatabaseCharacterSets_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListExascaleDbStorageVaults_sync", "segments": [ { "end": 52, @@ -5804,7 +9555,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_database_character_sets_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_list_exascale_db_storage_vaults_sync.py" }, { "canonical": true, @@ -5814,19 +9565,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_databases", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_gi_versions", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDatabases", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListGiVersions", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListDatabases" + "shortName": "ListGiVersions" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListDatabasesRequest" + "type": "google.cloud.oracledatabase_v1.types.ListGiVersionsRequest" }, { "name": "parent", @@ -5845,14 +9596,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDatabasesAsyncPager", - "shortName": "list_databases" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGiVersionsAsyncPager", + "shortName": "list_gi_versions" }, - "description": "Sample for ListDatabases", - "file": "oracledatabase_v1_generated_oracle_database_list_databases_async.py", + "description": "Sample for ListGiVersions", + "file": "oracledatabase_v1_generated_oracle_database_list_gi_versions_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDatabases_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListGiVersions_async", "segments": [ { "end": 52, @@ -5885,7 +9636,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_databases_async.py" + "title": "oracledatabase_v1_generated_oracle_database_list_gi_versions_async.py" }, { "canonical": true, @@ -5894,19 +9645,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_databases", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_gi_versions", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDatabases", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListGiVersions", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListDatabases" + "shortName": "ListGiVersions" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListDatabasesRequest" + "type": "google.cloud.oracledatabase_v1.types.ListGiVersionsRequest" }, { "name": "parent", @@ -5925,14 +9676,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDatabasesPager", - "shortName": "list_databases" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGiVersionsPager", + "shortName": "list_gi_versions" }, - "description": "Sample for ListDatabases", - "file": "oracledatabase_v1_generated_oracle_database_list_databases_sync.py", + "description": "Sample for ListGiVersions", + "file": "oracledatabase_v1_generated_oracle_database_list_gi_versions_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDatabases_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListGiVersions_sync", "segments": [ { "end": 52, @@ -5965,7 +9716,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_databases_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_list_gi_versions_sync.py" }, { "canonical": true, @@ -5975,19 +9726,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_db_nodes", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_goldengate_connection_assignments", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDbNodes", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListGoldengateConnectionAssignments", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListDbNodes" + "shortName": "ListGoldengateConnectionAssignments" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListDbNodesRequest" + "type": "google.cloud.oracledatabase_v1.types.ListGoldengateConnectionAssignmentsRequest" }, { "name": "parent", @@ -6006,14 +9757,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDbNodesAsyncPager", - "shortName": "list_db_nodes" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGoldengateConnectionAssignmentsAsyncPager", + "shortName": "list_goldengate_connection_assignments" }, - "description": "Sample for ListDbNodes", - "file": "oracledatabase_v1_generated_oracle_database_list_db_nodes_async.py", + "description": "Sample for ListGoldengateConnectionAssignments", + "file": "oracledatabase_v1_generated_oracle_database_list_goldengate_connection_assignments_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDbNodes_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListGoldengateConnectionAssignments_async", "segments": [ { "end": 52, @@ -6046,7 +9797,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_db_nodes_async.py" + "title": "oracledatabase_v1_generated_oracle_database_list_goldengate_connection_assignments_async.py" }, { "canonical": true, @@ -6055,19 +9806,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_db_nodes", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_goldengate_connection_assignments", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDbNodes", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListGoldengateConnectionAssignments", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListDbNodes" + "shortName": "ListGoldengateConnectionAssignments" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListDbNodesRequest" + "type": "google.cloud.oracledatabase_v1.types.ListGoldengateConnectionAssignmentsRequest" }, { "name": "parent", @@ -6086,14 +9837,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDbNodesPager", - "shortName": "list_db_nodes" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGoldengateConnectionAssignmentsPager", + "shortName": "list_goldengate_connection_assignments" }, - "description": "Sample for ListDbNodes", - "file": "oracledatabase_v1_generated_oracle_database_list_db_nodes_sync.py", + "description": "Sample for ListGoldengateConnectionAssignments", + "file": "oracledatabase_v1_generated_oracle_database_list_goldengate_connection_assignments_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDbNodes_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListGoldengateConnectionAssignments_sync", "segments": [ { "end": 52, @@ -6126,7 +9877,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_db_nodes_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_list_goldengate_connection_assignments_sync.py" }, { "canonical": true, @@ -6136,19 +9887,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_db_servers", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_goldengate_connection_types", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDbServers", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListGoldengateConnectionTypes", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListDbServers" + "shortName": "ListGoldengateConnectionTypes" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListDbServersRequest" + "type": "google.cloud.oracledatabase_v1.types.ListGoldengateConnectionTypesRequest" }, { "name": "parent", @@ -6167,14 +9918,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDbServersAsyncPager", - "shortName": "list_db_servers" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGoldengateConnectionTypesAsyncPager", + "shortName": "list_goldengate_connection_types" }, - "description": "Sample for ListDbServers", - "file": "oracledatabase_v1_generated_oracle_database_list_db_servers_async.py", + "description": "Sample for ListGoldengateConnectionTypes", + "file": "oracledatabase_v1_generated_oracle_database_list_goldengate_connection_types_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDbServers_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListGoldengateConnectionTypes_async", "segments": [ { "end": 52, @@ -6207,7 +9958,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_db_servers_async.py" + "title": "oracledatabase_v1_generated_oracle_database_list_goldengate_connection_types_async.py" }, { "canonical": true, @@ -6216,19 +9967,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_db_servers", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_goldengate_connection_types", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDbServers", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListGoldengateConnectionTypes", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListDbServers" + "shortName": "ListGoldengateConnectionTypes" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListDbServersRequest" + "type": "google.cloud.oracledatabase_v1.types.ListGoldengateConnectionTypesRequest" }, { "name": "parent", @@ -6247,14 +9998,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDbServersPager", - "shortName": "list_db_servers" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGoldengateConnectionTypesPager", + "shortName": "list_goldengate_connection_types" }, - "description": "Sample for ListDbServers", - "file": "oracledatabase_v1_generated_oracle_database_list_db_servers_sync.py", + "description": "Sample for ListGoldengateConnectionTypes", + "file": "oracledatabase_v1_generated_oracle_database_list_goldengate_connection_types_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDbServers_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListGoldengateConnectionTypes_sync", "segments": [ { "end": 52, @@ -6287,7 +10038,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_db_servers_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_list_goldengate_connection_types_sync.py" }, { "canonical": true, @@ -6297,19 +10048,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_db_system_initial_storage_sizes", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_goldengate_connections", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDbSystemInitialStorageSizes", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListGoldengateConnections", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListDbSystemInitialStorageSizes" + "shortName": "ListGoldengateConnections" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListDbSystemInitialStorageSizesRequest" + "type": "google.cloud.oracledatabase_v1.types.ListGoldengateConnectionsRequest" }, { "name": "parent", @@ -6328,14 +10079,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDbSystemInitialStorageSizesAsyncPager", - "shortName": "list_db_system_initial_storage_sizes" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGoldengateConnectionsAsyncPager", + "shortName": "list_goldengate_connections" }, - "description": "Sample for ListDbSystemInitialStorageSizes", - "file": "oracledatabase_v1_generated_oracle_database_list_db_system_initial_storage_sizes_async.py", + "description": "Sample for ListGoldengateConnections", + "file": "oracledatabase_v1_generated_oracle_database_list_goldengate_connections_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDbSystemInitialStorageSizes_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListGoldengateConnections_async", "segments": [ { "end": 52, @@ -6368,7 +10119,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_db_system_initial_storage_sizes_async.py" + "title": "oracledatabase_v1_generated_oracle_database_list_goldengate_connections_async.py" }, { "canonical": true, @@ -6377,19 +10128,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_db_system_initial_storage_sizes", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_goldengate_connections", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDbSystemInitialStorageSizes", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListGoldengateConnections", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListDbSystemInitialStorageSizes" + "shortName": "ListGoldengateConnections" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListDbSystemInitialStorageSizesRequest" + "type": "google.cloud.oracledatabase_v1.types.ListGoldengateConnectionsRequest" }, { "name": "parent", @@ -6408,14 +10159,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDbSystemInitialStorageSizesPager", - "shortName": "list_db_system_initial_storage_sizes" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGoldengateConnectionsPager", + "shortName": "list_goldengate_connections" }, - "description": "Sample for ListDbSystemInitialStorageSizes", - "file": "oracledatabase_v1_generated_oracle_database_list_db_system_initial_storage_sizes_sync.py", + "description": "Sample for ListGoldengateConnections", + "file": "oracledatabase_v1_generated_oracle_database_list_goldengate_connections_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDbSystemInitialStorageSizes_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListGoldengateConnections_sync", "segments": [ { "end": 52, @@ -6448,7 +10199,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_db_system_initial_storage_sizes_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_list_goldengate_connections_sync.py" }, { "canonical": true, @@ -6458,19 +10209,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_db_system_shapes", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_goldengate_deployment_environments", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDbSystemShapes", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListGoldengateDeploymentEnvironments", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListDbSystemShapes" + "shortName": "ListGoldengateDeploymentEnvironments" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListDbSystemShapesRequest" + "type": "google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentEnvironmentsRequest" }, { "name": "parent", @@ -6489,14 +10240,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDbSystemShapesAsyncPager", - "shortName": "list_db_system_shapes" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGoldengateDeploymentEnvironmentsAsyncPager", + "shortName": "list_goldengate_deployment_environments" }, - "description": "Sample for ListDbSystemShapes", - "file": "oracledatabase_v1_generated_oracle_database_list_db_system_shapes_async.py", + "description": "Sample for ListGoldengateDeploymentEnvironments", + "file": "oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_environments_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDbSystemShapes_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListGoldengateDeploymentEnvironments_async", "segments": [ { "end": 52, @@ -6529,7 +10280,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_db_system_shapes_async.py" + "title": "oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_environments_async.py" }, { "canonical": true, @@ -6538,19 +10289,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_db_system_shapes", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_goldengate_deployment_environments", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDbSystemShapes", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListGoldengateDeploymentEnvironments", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListDbSystemShapes" + "shortName": "ListGoldengateDeploymentEnvironments" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListDbSystemShapesRequest" + "type": "google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentEnvironmentsRequest" }, { "name": "parent", @@ -6569,14 +10320,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDbSystemShapesPager", - "shortName": "list_db_system_shapes" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGoldengateDeploymentEnvironmentsPager", + "shortName": "list_goldengate_deployment_environments" }, - "description": "Sample for ListDbSystemShapes", - "file": "oracledatabase_v1_generated_oracle_database_list_db_system_shapes_sync.py", + "description": "Sample for ListGoldengateDeploymentEnvironments", + "file": "oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_environments_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDbSystemShapes_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListGoldengateDeploymentEnvironments_sync", "segments": [ { "end": 52, @@ -6609,7 +10360,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_db_system_shapes_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_environments_sync.py" }, { "canonical": true, @@ -6619,19 +10370,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_db_systems", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_goldengate_deployment_types", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDbSystems", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListGoldengateDeploymentTypes", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListDbSystems" + "shortName": "ListGoldengateDeploymentTypes" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListDbSystemsRequest" + "type": "google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentTypesRequest" }, { "name": "parent", @@ -6650,14 +10401,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDbSystemsAsyncPager", - "shortName": "list_db_systems" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGoldengateDeploymentTypesAsyncPager", + "shortName": "list_goldengate_deployment_types" }, - "description": "Sample for ListDbSystems", - "file": "oracledatabase_v1_generated_oracle_database_list_db_systems_async.py", + "description": "Sample for ListGoldengateDeploymentTypes", + "file": "oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_types_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDbSystems_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListGoldengateDeploymentTypes_async", "segments": [ { "end": 52, @@ -6690,7 +10441,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_db_systems_async.py" + "title": "oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_types_async.py" }, { "canonical": true, @@ -6699,19 +10450,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_db_systems", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_goldengate_deployment_types", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDbSystems", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListGoldengateDeploymentTypes", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListDbSystems" + "shortName": "ListGoldengateDeploymentTypes" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListDbSystemsRequest" + "type": "google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentTypesRequest" }, { "name": "parent", @@ -6730,14 +10481,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDbSystemsPager", - "shortName": "list_db_systems" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGoldengateDeploymentTypesPager", + "shortName": "list_goldengate_deployment_types" }, - "description": "Sample for ListDbSystems", - "file": "oracledatabase_v1_generated_oracle_database_list_db_systems_sync.py", + "description": "Sample for ListGoldengateDeploymentTypes", + "file": "oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_types_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDbSystems_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListGoldengateDeploymentTypes_sync", "segments": [ { "end": 52, @@ -6770,7 +10521,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_db_systems_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_types_sync.py" }, { "canonical": true, @@ -6780,19 +10531,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_db_versions", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_goldengate_deployment_versions", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDbVersions", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListGoldengateDeploymentVersions", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListDbVersions" + "shortName": "ListGoldengateDeploymentVersions" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListDbVersionsRequest" + "type": "google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentVersionsRequest" }, { "name": "parent", @@ -6811,14 +10562,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDbVersionsAsyncPager", - "shortName": "list_db_versions" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGoldengateDeploymentVersionsAsyncPager", + "shortName": "list_goldengate_deployment_versions" }, - "description": "Sample for ListDbVersions", - "file": "oracledatabase_v1_generated_oracle_database_list_db_versions_async.py", + "description": "Sample for ListGoldengateDeploymentVersions", + "file": "oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_versions_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDbVersions_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListGoldengateDeploymentVersions_async", "segments": [ { "end": 52, @@ -6851,7 +10602,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_db_versions_async.py" + "title": "oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_versions_async.py" }, { "canonical": true, @@ -6860,19 +10611,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_db_versions", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_goldengate_deployment_versions", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListDbVersions", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListGoldengateDeploymentVersions", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListDbVersions" + "shortName": "ListGoldengateDeploymentVersions" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListDbVersionsRequest" + "type": "google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentVersionsRequest" }, { "name": "parent", @@ -6891,14 +10642,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListDbVersionsPager", - "shortName": "list_db_versions" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGoldengateDeploymentVersionsPager", + "shortName": "list_goldengate_deployment_versions" }, - "description": "Sample for ListDbVersions", - "file": "oracledatabase_v1_generated_oracle_database_list_db_versions_sync.py", + "description": "Sample for ListGoldengateDeploymentVersions", + "file": "oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_versions_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListDbVersions_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListGoldengateDeploymentVersions_sync", "segments": [ { "end": 52, @@ -6931,7 +10682,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_db_versions_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_list_goldengate_deployment_versions_sync.py" }, { "canonical": true, @@ -6941,19 +10692,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_entitlements", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_goldengate_deployments", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListEntitlements", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListGoldengateDeployments", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListEntitlements" + "shortName": "ListGoldengateDeployments" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListEntitlementsRequest" + "type": "google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentsRequest" }, { "name": "parent", @@ -6972,14 +10723,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListEntitlementsAsyncPager", - "shortName": "list_entitlements" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGoldengateDeploymentsAsyncPager", + "shortName": "list_goldengate_deployments" }, - "description": "Sample for ListEntitlements", - "file": "oracledatabase_v1_generated_oracle_database_list_entitlements_async.py", + "description": "Sample for ListGoldengateDeployments", + "file": "oracledatabase_v1_generated_oracle_database_list_goldengate_deployments_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListEntitlements_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListGoldengateDeployments_async", "segments": [ { "end": 52, @@ -7012,7 +10763,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_entitlements_async.py" + "title": "oracledatabase_v1_generated_oracle_database_list_goldengate_deployments_async.py" }, { "canonical": true, @@ -7021,19 +10772,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_entitlements", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_goldengate_deployments", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListEntitlements", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListGoldengateDeployments", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListEntitlements" + "shortName": "ListGoldengateDeployments" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListEntitlementsRequest" + "type": "google.cloud.oracledatabase_v1.types.ListGoldengateDeploymentsRequest" }, { "name": "parent", @@ -7052,14 +10803,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListEntitlementsPager", - "shortName": "list_entitlements" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGoldengateDeploymentsPager", + "shortName": "list_goldengate_deployments" }, - "description": "Sample for ListEntitlements", - "file": "oracledatabase_v1_generated_oracle_database_list_entitlements_sync.py", + "description": "Sample for ListGoldengateDeployments", + "file": "oracledatabase_v1_generated_oracle_database_list_goldengate_deployments_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListEntitlements_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListGoldengateDeployments_sync", "segments": [ { "end": 52, @@ -7092,7 +10843,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_entitlements_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_list_goldengate_deployments_sync.py" }, { "canonical": true, @@ -7102,19 +10853,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_exadb_vm_clusters", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_minor_versions", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListExadbVmClusters", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListMinorVersions", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListExadbVmClusters" + "shortName": "ListMinorVersions" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListExadbVmClustersRequest" + "type": "google.cloud.oracledatabase_v1.types.ListMinorVersionsRequest" }, { "name": "parent", @@ -7133,14 +10884,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListExadbVmClustersAsyncPager", - "shortName": "list_exadb_vm_clusters" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListMinorVersionsAsyncPager", + "shortName": "list_minor_versions" }, - "description": "Sample for ListExadbVmClusters", - "file": "oracledatabase_v1_generated_oracle_database_list_exadb_vm_clusters_async.py", + "description": "Sample for ListMinorVersions", + "file": "oracledatabase_v1_generated_oracle_database_list_minor_versions_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListExadbVmClusters_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListMinorVersions_async", "segments": [ { "end": 52, @@ -7173,7 +10924,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_exadb_vm_clusters_async.py" + "title": "oracledatabase_v1_generated_oracle_database_list_minor_versions_async.py" }, { "canonical": true, @@ -7182,19 +10933,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_exadb_vm_clusters", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_minor_versions", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListExadbVmClusters", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListMinorVersions", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListExadbVmClusters" + "shortName": "ListMinorVersions" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListExadbVmClustersRequest" + "type": "google.cloud.oracledatabase_v1.types.ListMinorVersionsRequest" }, { "name": "parent", @@ -7213,14 +10964,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListExadbVmClustersPager", - "shortName": "list_exadb_vm_clusters" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListMinorVersionsPager", + "shortName": "list_minor_versions" }, - "description": "Sample for ListExadbVmClusters", - "file": "oracledatabase_v1_generated_oracle_database_list_exadb_vm_clusters_sync.py", + "description": "Sample for ListMinorVersions", + "file": "oracledatabase_v1_generated_oracle_database_list_minor_versions_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListExadbVmClusters_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListMinorVersions_sync", "segments": [ { "end": 52, @@ -7253,7 +11004,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_exadb_vm_clusters_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_list_minor_versions_sync.py" }, { "canonical": true, @@ -7263,19 +11014,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_exascale_db_storage_vaults", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_odb_networks", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListExascaleDbStorageVaults", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListOdbNetworks", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListExascaleDbStorageVaults" + "shortName": "ListOdbNetworks" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListExascaleDbStorageVaultsRequest" + "type": "google.cloud.oracledatabase_v1.types.ListOdbNetworksRequest" }, { "name": "parent", @@ -7294,14 +11045,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListExascaleDbStorageVaultsAsyncPager", - "shortName": "list_exascale_db_storage_vaults" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListOdbNetworksAsyncPager", + "shortName": "list_odb_networks" }, - "description": "Sample for ListExascaleDbStorageVaults", - "file": "oracledatabase_v1_generated_oracle_database_list_exascale_db_storage_vaults_async.py", + "description": "Sample for ListOdbNetworks", + "file": "oracledatabase_v1_generated_oracle_database_list_odb_networks_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListExascaleDbStorageVaults_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListOdbNetworks_async", "segments": [ { "end": 52, @@ -7334,7 +11085,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_exascale_db_storage_vaults_async.py" + "title": "oracledatabase_v1_generated_oracle_database_list_odb_networks_async.py" }, { "canonical": true, @@ -7343,19 +11094,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_exascale_db_storage_vaults", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_odb_networks", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListExascaleDbStorageVaults", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListOdbNetworks", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListExascaleDbStorageVaults" + "shortName": "ListOdbNetworks" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListExascaleDbStorageVaultsRequest" + "type": "google.cloud.oracledatabase_v1.types.ListOdbNetworksRequest" }, { "name": "parent", @@ -7374,14 +11125,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListExascaleDbStorageVaultsPager", - "shortName": "list_exascale_db_storage_vaults" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListOdbNetworksPager", + "shortName": "list_odb_networks" }, - "description": "Sample for ListExascaleDbStorageVaults", - "file": "oracledatabase_v1_generated_oracle_database_list_exascale_db_storage_vaults_sync.py", + "description": "Sample for ListOdbNetworks", + "file": "oracledatabase_v1_generated_oracle_database_list_odb_networks_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListExascaleDbStorageVaults_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListOdbNetworks_sync", "segments": [ { "end": 52, @@ -7414,7 +11165,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_exascale_db_storage_vaults_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_list_odb_networks_sync.py" }, { "canonical": true, @@ -7424,19 +11175,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_gi_versions", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_odb_subnets", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListGiVersions", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListOdbSubnets", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListGiVersions" + "shortName": "ListOdbSubnets" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListGiVersionsRequest" + "type": "google.cloud.oracledatabase_v1.types.ListOdbSubnetsRequest" }, { "name": "parent", @@ -7455,14 +11206,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGiVersionsAsyncPager", - "shortName": "list_gi_versions" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListOdbSubnetsAsyncPager", + "shortName": "list_odb_subnets" }, - "description": "Sample for ListGiVersions", - "file": "oracledatabase_v1_generated_oracle_database_list_gi_versions_async.py", + "description": "Sample for ListOdbSubnets", + "file": "oracledatabase_v1_generated_oracle_database_list_odb_subnets_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListGiVersions_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListOdbSubnets_async", "segments": [ { "end": 52, @@ -7495,7 +11246,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_gi_versions_async.py" + "title": "oracledatabase_v1_generated_oracle_database_list_odb_subnets_async.py" }, { "canonical": true, @@ -7504,19 +11255,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_gi_versions", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_odb_subnets", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListGiVersions", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListOdbSubnets", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListGiVersions" + "shortName": "ListOdbSubnets" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListGiVersionsRequest" + "type": "google.cloud.oracledatabase_v1.types.ListOdbSubnetsRequest" }, { "name": "parent", @@ -7535,14 +11286,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListGiVersionsPager", - "shortName": "list_gi_versions" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListOdbSubnetsPager", + "shortName": "list_odb_subnets" }, - "description": "Sample for ListGiVersions", - "file": "oracledatabase_v1_generated_oracle_database_list_gi_versions_sync.py", + "description": "Sample for ListOdbSubnets", + "file": "oracledatabase_v1_generated_oracle_database_list_odb_subnets_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListGiVersions_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListOdbSubnets_sync", "segments": [ { "end": 52, @@ -7575,7 +11326,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_gi_versions_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_list_odb_subnets_sync.py" }, { "canonical": true, @@ -7585,19 +11336,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_minor_versions", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_pluggable_databases", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListMinorVersions", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListPluggableDatabases", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListMinorVersions" + "shortName": "ListPluggableDatabases" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListMinorVersionsRequest" + "type": "google.cloud.oracledatabase_v1.types.ListPluggableDatabasesRequest" }, { "name": "parent", @@ -7616,14 +11367,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListMinorVersionsAsyncPager", - "shortName": "list_minor_versions" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListPluggableDatabasesAsyncPager", + "shortName": "list_pluggable_databases" }, - "description": "Sample for ListMinorVersions", - "file": "oracledatabase_v1_generated_oracle_database_list_minor_versions_async.py", + "description": "Sample for ListPluggableDatabases", + "file": "oracledatabase_v1_generated_oracle_database_list_pluggable_databases_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListMinorVersions_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListPluggableDatabases_async", "segments": [ { "end": 52, @@ -7656,7 +11407,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_minor_versions_async.py" + "title": "oracledatabase_v1_generated_oracle_database_list_pluggable_databases_async.py" }, { "canonical": true, @@ -7665,19 +11416,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_minor_versions", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_pluggable_databases", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListMinorVersions", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListPluggableDatabases", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListMinorVersions" + "shortName": "ListPluggableDatabases" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListMinorVersionsRequest" + "type": "google.cloud.oracledatabase_v1.types.ListPluggableDatabasesRequest" }, { "name": "parent", @@ -7696,14 +11447,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListMinorVersionsPager", - "shortName": "list_minor_versions" + "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListPluggableDatabasesPager", + "shortName": "list_pluggable_databases" }, - "description": "Sample for ListMinorVersions", - "file": "oracledatabase_v1_generated_oracle_database_list_minor_versions_sync.py", + "description": "Sample for ListPluggableDatabases", + "file": "oracledatabase_v1_generated_oracle_database_list_pluggable_databases_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListMinorVersions_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListPluggableDatabases_sync", "segments": [ { "end": 52, @@ -7736,7 +11487,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_minor_versions_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_list_pluggable_databases_sync.py" }, { "canonical": true, @@ -7746,24 +11497,28 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_odb_networks", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.remove_virtual_machine_exadb_vm_cluster", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListOdbNetworks", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.RemoveVirtualMachineExadbVmCluster", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListOdbNetworks" + "shortName": "RemoveVirtualMachineExadbVmCluster" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListOdbNetworksRequest" + "type": "google.cloud.oracledatabase_v1.types.RemoveVirtualMachineExadbVmClusterRequest" }, { - "name": "parent", + "name": "name", "type": "str" }, + { + "name": "hostnames", + "type": "MutableSequence[str]" + }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -7777,22 +11532,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListOdbNetworksAsyncPager", - "shortName": "list_odb_networks" + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "remove_virtual_machine_exadb_vm_cluster" }, - "description": "Sample for ListOdbNetworks", - "file": "oracledatabase_v1_generated_oracle_database_list_odb_networks_async.py", + "description": "Sample for RemoveVirtualMachineExadbVmCluster", + "file": "oracledatabase_v1_generated_oracle_database_remove_virtual_machine_exadb_vm_cluster_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListOdbNetworks_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_RemoveVirtualMachineExadbVmCluster_async", "segments": [ { - "end": 52, + "end": 56, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 56, "start": 27, "type": "SHORT" }, @@ -7802,22 +11557,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 46, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 48, - "start": 46, + "end": 53, + "start": 47, "type": "REQUEST_EXECUTION" }, { - "end": 53, - "start": 49, + "end": 57, + "start": 54, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_odb_networks_async.py" + "title": "oracledatabase_v1_generated_oracle_database_remove_virtual_machine_exadb_vm_cluster_async.py" }, { "canonical": true, @@ -7826,24 +11581,28 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_odb_networks", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.remove_virtual_machine_exadb_vm_cluster", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListOdbNetworks", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.RemoveVirtualMachineExadbVmCluster", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListOdbNetworks" + "shortName": "RemoveVirtualMachineExadbVmCluster" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListOdbNetworksRequest" + "type": "google.cloud.oracledatabase_v1.types.RemoveVirtualMachineExadbVmClusterRequest" }, { - "name": "parent", + "name": "name", "type": "str" }, + { + "name": "hostnames", + "type": "MutableSequence[str]" + }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -7857,22 +11616,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListOdbNetworksPager", - "shortName": "list_odb_networks" + "resultType": "google.api_core.operation.Operation", + "shortName": "remove_virtual_machine_exadb_vm_cluster" }, - "description": "Sample for ListOdbNetworks", - "file": "oracledatabase_v1_generated_oracle_database_list_odb_networks_sync.py", + "description": "Sample for RemoveVirtualMachineExadbVmCluster", + "file": "oracledatabase_v1_generated_oracle_database_remove_virtual_machine_exadb_vm_cluster_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListOdbNetworks_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_RemoveVirtualMachineExadbVmCluster_sync", "segments": [ { - "end": 52, + "end": 56, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 56, "start": 27, "type": "SHORT" }, @@ -7882,22 +11641,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 46, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 48, - "start": 46, + "end": 53, + "start": 47, "type": "REQUEST_EXECUTION" }, { - "end": 53, - "start": 49, + "end": 57, + "start": 54, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_odb_networks_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_remove_virtual_machine_exadb_vm_cluster_sync.py" }, { "canonical": true, @@ -7907,22 +11666,22 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_odb_subnets", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.restart_autonomous_database", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListOdbSubnets", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.RestartAutonomousDatabase", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListOdbSubnets" + "shortName": "RestartAutonomousDatabase" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListOdbSubnetsRequest" + "type": "google.cloud.oracledatabase_v1.types.RestartAutonomousDatabaseRequest" }, { - "name": "parent", + "name": "name", "type": "str" }, { @@ -7938,22 +11697,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListOdbSubnetsAsyncPager", - "shortName": "list_odb_subnets" + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "restart_autonomous_database" }, - "description": "Sample for ListOdbSubnets", - "file": "oracledatabase_v1_generated_oracle_database_list_odb_subnets_async.py", + "description": "Sample for RestartAutonomousDatabase", + "file": "oracledatabase_v1_generated_oracle_database_restart_autonomous_database_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListOdbSubnets_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_RestartAutonomousDatabase_async", "segments": [ { - "end": 52, + "end": 55, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 55, "start": 27, "type": "SHORT" }, @@ -7968,17 +11727,17 @@ "type": "REQUEST_INITIALIZATION" }, { - "end": 48, + "end": 52, "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 53, - "start": 49, + "end": 56, + "start": 53, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_odb_subnets_async.py" + "title": "oracledatabase_v1_generated_oracle_database_restart_autonomous_database_async.py" }, { "canonical": true, @@ -7987,22 +11746,22 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_odb_subnets", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.restart_autonomous_database", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListOdbSubnets", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.RestartAutonomousDatabase", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListOdbSubnets" + "shortName": "RestartAutonomousDatabase" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListOdbSubnetsRequest" + "type": "google.cloud.oracledatabase_v1.types.RestartAutonomousDatabaseRequest" }, { - "name": "parent", + "name": "name", "type": "str" }, { @@ -8018,22 +11777,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListOdbSubnetsPager", - "shortName": "list_odb_subnets" + "resultType": "google.api_core.operation.Operation", + "shortName": "restart_autonomous_database" }, - "description": "Sample for ListOdbSubnets", - "file": "oracledatabase_v1_generated_oracle_database_list_odb_subnets_sync.py", + "description": "Sample for RestartAutonomousDatabase", + "file": "oracledatabase_v1_generated_oracle_database_restart_autonomous_database_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListOdbSubnets_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_RestartAutonomousDatabase_sync", "segments": [ { - "end": 52, + "end": 55, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 55, "start": 27, "type": "SHORT" }, @@ -8048,17 +11807,17 @@ "type": "REQUEST_INITIALIZATION" }, { - "end": 48, + "end": 52, "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 53, - "start": 49, + "end": 56, + "start": 53, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_odb_subnets_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_restart_autonomous_database_sync.py" }, { "canonical": true, @@ -8068,24 +11827,28 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.list_pluggable_databases", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.restore_autonomous_database", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListPluggableDatabases", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.RestoreAutonomousDatabase", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListPluggableDatabases" + "shortName": "RestoreAutonomousDatabase" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListPluggableDatabasesRequest" + "type": "google.cloud.oracledatabase_v1.types.RestoreAutonomousDatabaseRequest" }, { - "name": "parent", + "name": "name", "type": "str" }, + { + "name": "restore_time", + "type": "google.protobuf.timestamp_pb2.Timestamp" + }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -8099,22 +11862,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListPluggableDatabasesAsyncPager", - "shortName": "list_pluggable_databases" + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "restore_autonomous_database" }, - "description": "Sample for ListPluggableDatabases", - "file": "oracledatabase_v1_generated_oracle_database_list_pluggable_databases_async.py", + "description": "Sample for RestoreAutonomousDatabase", + "file": "oracledatabase_v1_generated_oracle_database_restore_autonomous_database_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListPluggableDatabases_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_RestoreAutonomousDatabase_async", "segments": [ { - "end": 52, + "end": 55, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 55, "start": 27, "type": "SHORT" }, @@ -8129,17 +11892,17 @@ "type": "REQUEST_INITIALIZATION" }, { - "end": 48, + "end": 52, "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 53, - "start": 49, + "end": 56, + "start": 53, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_pluggable_databases_async.py" + "title": "oracledatabase_v1_generated_oracle_database_restore_autonomous_database_async.py" }, { "canonical": true, @@ -8148,24 +11911,28 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.list_pluggable_databases", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.restore_autonomous_database", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.ListPluggableDatabases", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.RestoreAutonomousDatabase", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "ListPluggableDatabases" + "shortName": "RestoreAutonomousDatabase" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.ListPluggableDatabasesRequest" + "type": "google.cloud.oracledatabase_v1.types.RestoreAutonomousDatabaseRequest" }, { - "name": "parent", + "name": "name", "type": "str" }, + { + "name": "restore_time", + "type": "google.protobuf.timestamp_pb2.Timestamp" + }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -8179,22 +11946,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.oracledatabase_v1.services.oracle_database.pagers.ListPluggableDatabasesPager", - "shortName": "list_pluggable_databases" + "resultType": "google.api_core.operation.Operation", + "shortName": "restore_autonomous_database" }, - "description": "Sample for ListPluggableDatabases", - "file": "oracledatabase_v1_generated_oracle_database_list_pluggable_databases_sync.py", + "description": "Sample for RestoreAutonomousDatabase", + "file": "oracledatabase_v1_generated_oracle_database_restore_autonomous_database_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_ListPluggableDatabases_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_RestoreAutonomousDatabase_sync", "segments": [ { - "end": 52, + "end": 55, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 55, "start": 27, "type": "SHORT" }, @@ -8209,17 +11976,17 @@ "type": "REQUEST_INITIALIZATION" }, { - "end": 48, + "end": 52, "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 53, - "start": 49, + "end": 56, + "start": 53, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_list_pluggable_databases_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_restore_autonomous_database_sync.py" }, { "canonical": true, @@ -8229,28 +11996,24 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.remove_virtual_machine_exadb_vm_cluster", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.start_autonomous_database", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.RemoveVirtualMachineExadbVmCluster", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.StartAutonomousDatabase", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "RemoveVirtualMachineExadbVmCluster" + "shortName": "StartAutonomousDatabase" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.RemoveVirtualMachineExadbVmClusterRequest" + "type": "google.cloud.oracledatabase_v1.types.StartAutonomousDatabaseRequest" }, { "name": "name", "type": "str" }, - { - "name": "hostnames", - "type": "MutableSequence[str]" - }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -8265,21 +12028,21 @@ } ], "resultType": "google.api_core.operation_async.AsyncOperation", - "shortName": "remove_virtual_machine_exadb_vm_cluster" + "shortName": "start_autonomous_database" }, - "description": "Sample for RemoveVirtualMachineExadbVmCluster", - "file": "oracledatabase_v1_generated_oracle_database_remove_virtual_machine_exadb_vm_cluster_async.py", + "description": "Sample for StartAutonomousDatabase", + "file": "oracledatabase_v1_generated_oracle_database_start_autonomous_database_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_RemoveVirtualMachineExadbVmCluster_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_StartAutonomousDatabase_async", "segments": [ { - "end": 56, + "end": 55, "start": 27, "type": "FULL" }, { - "end": 56, + "end": 55, "start": 27, "type": "SHORT" }, @@ -8289,22 +12052,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 46, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 53, - "start": 47, + "end": 52, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 57, - "start": 54, + "end": 56, + "start": 53, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_remove_virtual_machine_exadb_vm_cluster_async.py" + "title": "oracledatabase_v1_generated_oracle_database_start_autonomous_database_async.py" }, { "canonical": true, @@ -8313,28 +12076,24 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.remove_virtual_machine_exadb_vm_cluster", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.start_autonomous_database", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.RemoveVirtualMachineExadbVmCluster", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.StartAutonomousDatabase", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "RemoveVirtualMachineExadbVmCluster" + "shortName": "StartAutonomousDatabase" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.RemoveVirtualMachineExadbVmClusterRequest" + "type": "google.cloud.oracledatabase_v1.types.StartAutonomousDatabaseRequest" }, { "name": "name", "type": "str" }, - { - "name": "hostnames", - "type": "MutableSequence[str]" - }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -8349,21 +12108,21 @@ } ], "resultType": "google.api_core.operation.Operation", - "shortName": "remove_virtual_machine_exadb_vm_cluster" + "shortName": "start_autonomous_database" }, - "description": "Sample for RemoveVirtualMachineExadbVmCluster", - "file": "oracledatabase_v1_generated_oracle_database_remove_virtual_machine_exadb_vm_cluster_sync.py", + "description": "Sample for StartAutonomousDatabase", + "file": "oracledatabase_v1_generated_oracle_database_start_autonomous_database_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_RemoveVirtualMachineExadbVmCluster_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_StartAutonomousDatabase_sync", "segments": [ { - "end": 56, + "end": 55, "start": 27, "type": "FULL" }, { - "end": 56, + "end": 55, "start": 27, "type": "SHORT" }, @@ -8373,22 +12132,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 46, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 53, - "start": 47, + "end": 52, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 57, - "start": 54, + "end": 56, + "start": 53, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_remove_virtual_machine_exadb_vm_cluster_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_start_autonomous_database_sync.py" }, { "canonical": true, @@ -8398,19 +12157,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.restart_autonomous_database", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.start_goldengate_deployment", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.RestartAutonomousDatabase", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.StartGoldengateDeployment", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "RestartAutonomousDatabase" + "shortName": "StartGoldengateDeployment" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.RestartAutonomousDatabaseRequest" + "type": "google.cloud.oracledatabase_v1.types.StartGoldengateDeploymentRequest" }, { "name": "name", @@ -8430,13 +12189,13 @@ } ], "resultType": "google.api_core.operation_async.AsyncOperation", - "shortName": "restart_autonomous_database" + "shortName": "start_goldengate_deployment" }, - "description": "Sample for RestartAutonomousDatabase", - "file": "oracledatabase_v1_generated_oracle_database_restart_autonomous_database_async.py", + "description": "Sample for StartGoldengateDeployment", + "file": "oracledatabase_v1_generated_oracle_database_start_goldengate_deployment_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_RestartAutonomousDatabase_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_StartGoldengateDeployment_async", "segments": [ { "end": 55, @@ -8469,7 +12228,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_restart_autonomous_database_async.py" + "title": "oracledatabase_v1_generated_oracle_database_start_goldengate_deployment_async.py" }, { "canonical": true, @@ -8478,19 +12237,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.restart_autonomous_database", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.start_goldengate_deployment", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.RestartAutonomousDatabase", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.StartGoldengateDeployment", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "RestartAutonomousDatabase" + "shortName": "StartGoldengateDeployment" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.RestartAutonomousDatabaseRequest" + "type": "google.cloud.oracledatabase_v1.types.StartGoldengateDeploymentRequest" }, { "name": "name", @@ -8510,13 +12269,13 @@ } ], "resultType": "google.api_core.operation.Operation", - "shortName": "restart_autonomous_database" + "shortName": "start_goldengate_deployment" }, - "description": "Sample for RestartAutonomousDatabase", - "file": "oracledatabase_v1_generated_oracle_database_restart_autonomous_database_sync.py", + "description": "Sample for StartGoldengateDeployment", + "file": "oracledatabase_v1_generated_oracle_database_start_goldengate_deployment_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_RestartAutonomousDatabase_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_StartGoldengateDeployment_sync", "segments": [ { "end": 55, @@ -8549,7 +12308,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_restart_autonomous_database_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_start_goldengate_deployment_sync.py" }, { "canonical": true, @@ -8559,28 +12318,24 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.restore_autonomous_database", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.stop_autonomous_database", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.RestoreAutonomousDatabase", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.StopAutonomousDatabase", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "RestoreAutonomousDatabase" + "shortName": "StopAutonomousDatabase" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.RestoreAutonomousDatabaseRequest" + "type": "google.cloud.oracledatabase_v1.types.StopAutonomousDatabaseRequest" }, { "name": "name", "type": "str" }, - { - "name": "restore_time", - "type": "google.protobuf.timestamp_pb2.Timestamp" - }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -8595,13 +12350,13 @@ } ], "resultType": "google.api_core.operation_async.AsyncOperation", - "shortName": "restore_autonomous_database" + "shortName": "stop_autonomous_database" }, - "description": "Sample for RestoreAutonomousDatabase", - "file": "oracledatabase_v1_generated_oracle_database_restore_autonomous_database_async.py", + "description": "Sample for StopAutonomousDatabase", + "file": "oracledatabase_v1_generated_oracle_database_stop_autonomous_database_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_RestoreAutonomousDatabase_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_StopAutonomousDatabase_async", "segments": [ { "end": 55, @@ -8634,7 +12389,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_restore_autonomous_database_async.py" + "title": "oracledatabase_v1_generated_oracle_database_stop_autonomous_database_async.py" }, { "canonical": true, @@ -8643,28 +12398,24 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.restore_autonomous_database", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.stop_autonomous_database", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.RestoreAutonomousDatabase", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.StopAutonomousDatabase", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "RestoreAutonomousDatabase" + "shortName": "StopAutonomousDatabase" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.RestoreAutonomousDatabaseRequest" + "type": "google.cloud.oracledatabase_v1.types.StopAutonomousDatabaseRequest" }, { "name": "name", "type": "str" }, - { - "name": "restore_time", - "type": "google.protobuf.timestamp_pb2.Timestamp" - }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -8679,13 +12430,13 @@ } ], "resultType": "google.api_core.operation.Operation", - "shortName": "restore_autonomous_database" + "shortName": "stop_autonomous_database" }, - "description": "Sample for RestoreAutonomousDatabase", - "file": "oracledatabase_v1_generated_oracle_database_restore_autonomous_database_sync.py", + "description": "Sample for StopAutonomousDatabase", + "file": "oracledatabase_v1_generated_oracle_database_stop_autonomous_database_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_RestoreAutonomousDatabase_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_StopAutonomousDatabase_sync", "segments": [ { "end": 55, @@ -8718,7 +12469,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_restore_autonomous_database_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_stop_autonomous_database_sync.py" }, { "canonical": true, @@ -8728,19 +12479,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.start_autonomous_database", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.stop_goldengate_deployment", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.StartAutonomousDatabase", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.StopGoldengateDeployment", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "StartAutonomousDatabase" + "shortName": "StopGoldengateDeployment" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.StartAutonomousDatabaseRequest" + "type": "google.cloud.oracledatabase_v1.types.StopGoldengateDeploymentRequest" }, { "name": "name", @@ -8760,13 +12511,13 @@ } ], "resultType": "google.api_core.operation_async.AsyncOperation", - "shortName": "start_autonomous_database" + "shortName": "stop_goldengate_deployment" }, - "description": "Sample for StartAutonomousDatabase", - "file": "oracledatabase_v1_generated_oracle_database_start_autonomous_database_async.py", + "description": "Sample for StopGoldengateDeployment", + "file": "oracledatabase_v1_generated_oracle_database_stop_goldengate_deployment_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_StartAutonomousDatabase_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_StopGoldengateDeployment_async", "segments": [ { "end": 55, @@ -8799,7 +12550,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_start_autonomous_database_async.py" + "title": "oracledatabase_v1_generated_oracle_database_stop_goldengate_deployment_async.py" }, { "canonical": true, @@ -8808,19 +12559,19 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.start_autonomous_database", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.stop_goldengate_deployment", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.StartAutonomousDatabase", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.StopGoldengateDeployment", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "StartAutonomousDatabase" + "shortName": "StopGoldengateDeployment" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.StartAutonomousDatabaseRequest" + "type": "google.cloud.oracledatabase_v1.types.StopGoldengateDeploymentRequest" }, { "name": "name", @@ -8840,13 +12591,13 @@ } ], "resultType": "google.api_core.operation.Operation", - "shortName": "start_autonomous_database" + "shortName": "stop_goldengate_deployment" }, - "description": "Sample for StartAutonomousDatabase", - "file": "oracledatabase_v1_generated_oracle_database_start_autonomous_database_sync.py", + "description": "Sample for StopGoldengateDeployment", + "file": "oracledatabase_v1_generated_oracle_database_stop_goldengate_deployment_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_StartAutonomousDatabase_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_StopGoldengateDeployment_sync", "segments": [ { "end": 55, @@ -8879,7 +12630,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_start_autonomous_database_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_stop_goldengate_deployment_sync.py" }, { "canonical": true, @@ -8889,24 +12640,28 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.stop_autonomous_database", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.switchover_autonomous_database", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.StopAutonomousDatabase", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.SwitchoverAutonomousDatabase", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "StopAutonomousDatabase" + "shortName": "SwitchoverAutonomousDatabase" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.StopAutonomousDatabaseRequest" + "type": "google.cloud.oracledatabase_v1.types.SwitchoverAutonomousDatabaseRequest" }, { "name": "name", "type": "str" }, + { + "name": "peer_autonomous_database", + "type": "str" + }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -8921,13 +12676,13 @@ } ], "resultType": "google.api_core.operation_async.AsyncOperation", - "shortName": "stop_autonomous_database" + "shortName": "switchover_autonomous_database" }, - "description": "Sample for StopAutonomousDatabase", - "file": "oracledatabase_v1_generated_oracle_database_stop_autonomous_database_async.py", + "description": "Sample for SwitchoverAutonomousDatabase", + "file": "oracledatabase_v1_generated_oracle_database_switchover_autonomous_database_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_StopAutonomousDatabase_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_SwitchoverAutonomousDatabase_async", "segments": [ { "end": 55, @@ -8960,7 +12715,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_stop_autonomous_database_async.py" + "title": "oracledatabase_v1_generated_oracle_database_switchover_autonomous_database_async.py" }, { "canonical": true, @@ -8969,24 +12724,28 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.stop_autonomous_database", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.switchover_autonomous_database", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.StopAutonomousDatabase", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.SwitchoverAutonomousDatabase", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "StopAutonomousDatabase" + "shortName": "SwitchoverAutonomousDatabase" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.StopAutonomousDatabaseRequest" + "type": "google.cloud.oracledatabase_v1.types.SwitchoverAutonomousDatabaseRequest" }, { "name": "name", "type": "str" }, + { + "name": "peer_autonomous_database", + "type": "str" + }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -9001,13 +12760,13 @@ } ], "resultType": "google.api_core.operation.Operation", - "shortName": "stop_autonomous_database" + "shortName": "switchover_autonomous_database" }, - "description": "Sample for StopAutonomousDatabase", - "file": "oracledatabase_v1_generated_oracle_database_stop_autonomous_database_sync.py", + "description": "Sample for SwitchoverAutonomousDatabase", + "file": "oracledatabase_v1_generated_oracle_database_switchover_autonomous_database_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_StopAutonomousDatabase_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_SwitchoverAutonomousDatabase_sync", "segments": [ { "end": 55, @@ -9040,7 +12799,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_stop_autonomous_database_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_switchover_autonomous_database_sync.py" }, { "canonical": true, @@ -9050,28 +12809,24 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient", "shortName": "OracleDatabaseAsyncClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.switchover_autonomous_database", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseAsyncClient.test_goldengate_connection_assignment", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.SwitchoverAutonomousDatabase", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.TestGoldengateConnectionAssignment", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "SwitchoverAutonomousDatabase" + "shortName": "TestGoldengateConnectionAssignment" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.SwitchoverAutonomousDatabaseRequest" + "type": "google.cloud.oracledatabase_v1.types.TestGoldengateConnectionAssignmentRequest" }, { "name": "name", "type": "str" }, - { - "name": "peer_autonomous_database", - "type": "str" - }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -9085,22 +12840,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.api_core.operation_async.AsyncOperation", - "shortName": "switchover_autonomous_database" + "resultType": "google.cloud.oracledatabase_v1.types.TestGoldengateConnectionAssignmentResponse", + "shortName": "test_goldengate_connection_assignment" }, - "description": "Sample for SwitchoverAutonomousDatabase", - "file": "oracledatabase_v1_generated_oracle_database_switchover_autonomous_database_async.py", + "description": "Sample for TestGoldengateConnectionAssignment", + "file": "oracledatabase_v1_generated_oracle_database_test_goldengate_connection_assignment_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_SwitchoverAutonomousDatabase_async", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_TestGoldengateConnectionAssignment_async", "segments": [ { - "end": 56, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 56, + "end": 51, "start": 27, "type": "SHORT" }, @@ -9110,22 +12865,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 46, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 53, - "start": 47, + "end": 48, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 57, - "start": 54, + "end": 52, + "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_switchover_autonomous_database_async.py" + "title": "oracledatabase_v1_generated_oracle_database_test_goldengate_connection_assignment_async.py" }, { "canonical": true, @@ -9134,28 +12889,24 @@ "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient", "shortName": "OracleDatabaseClient" }, - "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.switchover_autonomous_database", + "fullName": "google.cloud.oracledatabase_v1.OracleDatabaseClient.test_goldengate_connection_assignment", "method": { - "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.SwitchoverAutonomousDatabase", + "fullName": "google.cloud.oracledatabase.v1.OracleDatabase.TestGoldengateConnectionAssignment", "service": { "fullName": "google.cloud.oracledatabase.v1.OracleDatabase", "shortName": "OracleDatabase" }, - "shortName": "SwitchoverAutonomousDatabase" + "shortName": "TestGoldengateConnectionAssignment" }, "parameters": [ { "name": "request", - "type": "google.cloud.oracledatabase_v1.types.SwitchoverAutonomousDatabaseRequest" + "type": "google.cloud.oracledatabase_v1.types.TestGoldengateConnectionAssignmentRequest" }, { "name": "name", "type": "str" }, - { - "name": "peer_autonomous_database", - "type": "str" - }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -9169,22 +12920,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.api_core.operation.Operation", - "shortName": "switchover_autonomous_database" + "resultType": "google.cloud.oracledatabase_v1.types.TestGoldengateConnectionAssignmentResponse", + "shortName": "test_goldengate_connection_assignment" }, - "description": "Sample for SwitchoverAutonomousDatabase", - "file": "oracledatabase_v1_generated_oracle_database_switchover_autonomous_database_sync.py", + "description": "Sample for TestGoldengateConnectionAssignment", + "file": "oracledatabase_v1_generated_oracle_database_test_goldengate_connection_assignment_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "oracledatabase_v1_generated_OracleDatabase_SwitchoverAutonomousDatabase_sync", + "regionTag": "oracledatabase_v1_generated_OracleDatabase_TestGoldengateConnectionAssignment_sync", "segments": [ { - "end": 56, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 56, + "end": 51, "start": 27, "type": "SHORT" }, @@ -9194,22 +12945,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 46, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 53, - "start": 47, + "end": 48, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 57, - "start": 54, + "end": 52, + "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "oracledatabase_v1_generated_oracle_database_switchover_autonomous_database_sync.py" + "title": "oracledatabase_v1_generated_oracle_database_test_goldengate_connection_assignment_sync.py" }, { "canonical": true, diff --git a/packages/google-cloud-oracledatabase/tests/unit/gapic/oracledatabase_v1/test_oracle_database.py b/packages/google-cloud-oracledatabase/tests/unit/gapic/oracledatabase_v1/test_oracle_database.py index 22add9db76df..89060d3db7f1 100644 --- a/packages/google-cloud-oracledatabase/tests/unit/gapic/oracledatabase_v1/test_oracle_database.py +++ b/packages/google-cloud-oracledatabase/tests/unit/gapic/oracledatabase_v1/test_oracle_database.py @@ -91,6 +91,13 @@ exadb_vm_cluster, exascale_db_storage_vault, gi_version, + goldengate_connection, + goldengate_connection_assignment, + goldengate_connection_type, + goldengate_deployment, + goldengate_deployment_environment, + goldengate_deployment_type, + goldengate_deployment_version, minor_version, odb_network, odb_subnet, @@ -108,6 +115,15 @@ from google.cloud.oracledatabase_v1.types import ( exascale_db_storage_vault as gco_exascale_db_storage_vault, ) +from google.cloud.oracledatabase_v1.types import ( + goldengate_connection as gco_goldengate_connection, +) +from google.cloud.oracledatabase_v1.types import ( + goldengate_connection_assignment as gco_goldengate_connection_assignment, +) +from google.cloud.oracledatabase_v1.types import ( + goldengate_deployment as gco_goldengate_deployment, +) from google.cloud.oracledatabase_v1.types import odb_network as gco_odb_network from google.cloud.oracledatabase_v1.types import odb_subnet as gco_odb_subnet @@ -1398,6 +1414,7 @@ def test_list_cloud_exadata_infrastructures(request_type, transport: str = "grpc # Designate an appropriate return value for the call. call.return_value = oracledatabase.ListCloudExadataInfrastructuresResponse( next_page_token="next_page_token_value", + unreachable=["unreachable_value"], ) response = client.list_cloud_exadata_infrastructures(request) @@ -1410,6 +1427,7 @@ def test_list_cloud_exadata_infrastructures(request_type, transport: str = "grpc # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListCloudExadataInfrastructuresPager) assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] def test_list_cloud_exadata_infrastructures_non_empty_request_with_auto_populated_field(): @@ -1559,6 +1577,7 @@ async def test_list_cloud_exadata_infrastructures_async( call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( oracledatabase.ListCloudExadataInfrastructuresResponse( next_page_token="next_page_token_value", + unreachable=["unreachable_value"], ) ) response = await client.list_cloud_exadata_infrastructures(request) @@ -1572,6 +1591,7 @@ async def test_list_cloud_exadata_infrastructures_async( # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListCloudExadataInfrastructuresAsyncPager) assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] def test_list_cloud_exadata_infrastructures_field_headers(): @@ -3040,6 +3060,7 @@ def test_list_cloud_vm_clusters(request_type, transport: str = "grpc"): # Designate an appropriate return value for the call. call.return_value = oracledatabase.ListCloudVmClustersResponse( next_page_token="next_page_token_value", + unreachable=["unreachable_value"], ) response = client.list_cloud_vm_clusters(request) @@ -3052,6 +3073,7 @@ def test_list_cloud_vm_clusters(request_type, transport: str = "grpc"): # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListCloudVmClustersPager) assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] def test_list_cloud_vm_clusters_non_empty_request_with_auto_populated_field(): @@ -3199,6 +3221,7 @@ async def test_list_cloud_vm_clusters_async( call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( oracledatabase.ListCloudVmClustersResponse( next_page_token="next_page_token_value", + unreachable=["unreachable_value"], ) ) response = await client.list_cloud_vm_clusters(request) @@ -3212,6 +3235,7 @@ async def test_list_cloud_vm_clusters_async( # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListCloudVmClustersAsyncPager) assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] def test_list_cloud_vm_clusters_field_headers(): @@ -7870,6 +7894,7 @@ def test_list_autonomous_databases(request_type, transport: str = "grpc"): # Designate an appropriate return value for the call. call.return_value = oracledatabase.ListAutonomousDatabasesResponse( next_page_token="next_page_token_value", + unreachable=["unreachable_value"], ) response = client.list_autonomous_databases(request) @@ -7882,6 +7907,7 @@ def test_list_autonomous_databases(request_type, transport: str = "grpc"): # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListAutonomousDatabasesPager) assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] def test_list_autonomous_databases_non_empty_request_with_auto_populated_field(): @@ -8031,6 +8057,7 @@ async def test_list_autonomous_databases_async( call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( oracledatabase.ListAutonomousDatabasesResponse( next_page_token="next_page_token_value", + unreachable=["unreachable_value"], ) ) response = await client.list_autonomous_databases(request) @@ -8044,6 +8071,7 @@ async def test_list_autonomous_databases_async( # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListAutonomousDatabasesAsyncPager) assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] def test_list_autonomous_databases_field_headers(): @@ -8429,6 +8457,7 @@ def test_get_autonomous_database(request_type, transport: str = "grpc"): display_name="display_name_value", entitlement_id="entitlement_id_value", admin_password="admin_password_value", + admin_password_secret_version="admin_password_secret_version_value", network="network_value", cidr="cidr_value", odb_network="odb_network_value", @@ -8453,6 +8482,9 @@ def test_get_autonomous_database(request_type, transport: str = "grpc"): assert response.display_name == "display_name_value" assert response.entitlement_id == "entitlement_id_value" assert response.admin_password == "admin_password_value" + assert ( + response.admin_password_secret_version == "admin_password_secret_version_value" + ) assert response.network == "network_value" assert response.cidr == "cidr_value" assert response.odb_network == "odb_network_value" @@ -8608,6 +8640,7 @@ async def test_get_autonomous_database_async( display_name="display_name_value", entitlement_id="entitlement_id_value", admin_password="admin_password_value", + admin_password_secret_version="admin_password_secret_version_value", network="network_value", cidr="cidr_value", odb_network="odb_network_value", @@ -8633,6 +8666,9 @@ async def test_get_autonomous_database_async( assert response.display_name == "display_name_value" assert response.entitlement_id == "entitlement_id_value" assert response.admin_password == "admin_password_value" + assert ( + response.admin_password_secret_version == "admin_password_secret_version_value" + ) assert response.network == "network_value" assert response.cidr == "cidr_value" assert response.odb_network == "odb_network_value" @@ -17257,6 +17293,7 @@ def test_list_exadb_vm_clusters(request_type, transport: str = "grpc"): # Designate an appropriate return value for the call. call.return_value = oracledatabase.ListExadbVmClustersResponse( next_page_token="next_page_token_value", + unreachable=["unreachable_value"], ) response = client.list_exadb_vm_clusters(request) @@ -17269,6 +17306,7 @@ def test_list_exadb_vm_clusters(request_type, transport: str = "grpc"): # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListExadbVmClustersPager) assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] def test_list_exadb_vm_clusters_non_empty_request_with_auto_populated_field(): @@ -17418,6 +17456,7 @@ async def test_list_exadb_vm_clusters_async( call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( oracledatabase.ListExadbVmClustersResponse( next_page_token="next_page_token_value", + unreachable=["unreachable_value"], ) ) response = await client.list_exadb_vm_clusters(request) @@ -17431,6 +17470,7 @@ async def test_list_exadb_vm_clusters_async( # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListExadbVmClustersAsyncPager) assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] def test_list_exadb_vm_clusters_field_headers(): @@ -19609,6 +19649,7 @@ def test_list_exascale_db_storage_vaults(request_type, transport: str = "grpc"): call.return_value = ( exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse( next_page_token="next_page_token_value", + unreachable=["unreachable_value"], ) ) response = client.list_exascale_db_storage_vaults(request) @@ -19622,6 +19663,7 @@ def test_list_exascale_db_storage_vaults(request_type, transport: str = "grpc"): # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListExascaleDbStorageVaultsPager) assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] def test_list_exascale_db_storage_vaults_non_empty_request_with_auto_populated_field(): @@ -19771,6 +19813,7 @@ async def test_list_exascale_db_storage_vaults_async( call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse( next_page_token="next_page_token_value", + unreachable=["unreachable_value"], ) ) response = await client.list_exascale_db_storage_vaults(request) @@ -19784,6 +19827,7 @@ async def test_list_exascale_db_storage_vaults_async( # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListExascaleDbStorageVaultsAsyncPager) assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] def test_list_exascale_db_storage_vaults_field_headers(): @@ -22352,7 +22396,9 @@ def test_get_database(request_type, transport: str = "grpc"): db_name="db_name_value", db_unique_name="db_unique_name_value", admin_password="admin_password_value", + admin_password_secret_version="admin_password_secret_version_value", tde_wallet_password="tde_wallet_password_value", + tde_wallet_password_secret_version="tde_wallet_password_secret_version_value", character_set="character_set_value", ncharacter_set="ncharacter_set_value", oci_url="oci_url_value", @@ -22360,6 +22406,8 @@ def test_get_database(request_type, transport: str = "grpc"): db_home_name="db_home_name_value", gcp_oracle_zone="gcp_oracle_zone_value", ops_insights_status=database.Database.OperationsInsightsStatus.ENABLING, + pluggable_database_id="pluggable_database_id_value", + pluggable_database_name="pluggable_database_name_value", ) response = client.get_database(request) @@ -22375,7 +22423,14 @@ def test_get_database(request_type, transport: str = "grpc"): assert response.db_name == "db_name_value" assert response.db_unique_name == "db_unique_name_value" assert response.admin_password == "admin_password_value" + assert ( + response.admin_password_secret_version == "admin_password_secret_version_value" + ) assert response.tde_wallet_password == "tde_wallet_password_value" + assert ( + response.tde_wallet_password_secret_version + == "tde_wallet_password_secret_version_value" + ) assert response.character_set == "character_set_value" assert response.ncharacter_set == "ncharacter_set_value" assert response.oci_url == "oci_url_value" @@ -22386,6 +22441,8 @@ def test_get_database(request_type, transport: str = "grpc"): response.ops_insights_status == database.Database.OperationsInsightsStatus.ENABLING ) + assert response.pluggable_database_id == "pluggable_database_id_value" + assert response.pluggable_database_name == "pluggable_database_name_value" def test_get_database_non_empty_request_with_auto_populated_field(): @@ -22521,7 +22578,9 @@ async def test_get_database_async(request_type, transport: str = "grpc_asyncio") db_name="db_name_value", db_unique_name="db_unique_name_value", admin_password="admin_password_value", + admin_password_secret_version="admin_password_secret_version_value", tde_wallet_password="tde_wallet_password_value", + tde_wallet_password_secret_version="tde_wallet_password_secret_version_value", character_set="character_set_value", ncharacter_set="ncharacter_set_value", oci_url="oci_url_value", @@ -22529,6 +22588,8 @@ async def test_get_database_async(request_type, transport: str = "grpc_asyncio") db_home_name="db_home_name_value", gcp_oracle_zone="gcp_oracle_zone_value", ops_insights_status=database.Database.OperationsInsightsStatus.ENABLING, + pluggable_database_id="pluggable_database_id_value", + pluggable_database_name="pluggable_database_name_value", ) ) response = await client.get_database(request) @@ -22545,7 +22606,14 @@ async def test_get_database_async(request_type, transport: str = "grpc_asyncio") assert response.db_name == "db_name_value" assert response.db_unique_name == "db_unique_name_value" assert response.admin_password == "admin_password_value" + assert ( + response.admin_password_secret_version == "admin_password_secret_version_value" + ) assert response.tde_wallet_password == "tde_wallet_password_value" + assert ( + response.tde_wallet_password_secret_version + == "tde_wallet_password_secret_version_value" + ) assert response.character_set == "character_set_value" assert response.ncharacter_set == "ncharacter_set_value" assert response.oci_url == "oci_url_value" @@ -22556,6 +22624,8 @@ async def test_get_database_async(request_type, transport: str = "grpc_asyncio") response.ops_insights_status == database.Database.OperationsInsightsStatus.ENABLING ) + assert response.pluggable_database_id == "pluggable_database_id_value" + assert response.pluggable_database_name == "pluggable_database_name_value" def test_get_database_field_headers(): @@ -23619,6 +23689,7 @@ def test_list_db_systems(request_type, transport: str = "grpc"): # Designate an appropriate return value for the call. call.return_value = db_system.ListDbSystemsResponse( next_page_token="next_page_token_value", + unreachable=["unreachable_value"], ) response = client.list_db_systems(request) @@ -23631,6 +23702,7 @@ def test_list_db_systems(request_type, transport: str = "grpc"): # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListDbSystemsPager) assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] def test_list_db_systems_non_empty_request_with_auto_populated_field(): @@ -23769,6 +23841,7 @@ async def test_list_db_systems_async(request_type, transport: str = "grpc_asynci call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( db_system.ListDbSystemsResponse( next_page_token="next_page_token_value", + unreachable=["unreachable_value"], ) ) response = await client.list_db_systems(request) @@ -23782,6 +23855,7 @@ async def test_list_db_systems_async(request_type, transport: str = "grpc_asynci # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListDbSystemsAsyncPager) assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] def test_list_db_systems_field_headers(): @@ -25146,11 +25220,11 @@ async def test_delete_db_system_flattened_error_async(): @pytest.mark.parametrize( "request_type", [ - db_version.ListDbVersionsRequest(), + goldengate_deployment.ListGoldengateDeploymentsRequest(), {}, ], ) -def test_list_db_versions(request_type, transport: str = "grpc"): +def test_list_goldengate_deployments(request_type, transport: str = "grpc"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -25161,25 +25235,29 @@ def test_list_db_versions(request_type, transport: str = "grpc"): request = request_type # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_db_versions), "__call__") as call: + with mock.patch.object( + type(client.transport.list_goldengate_deployments), "__call__" + ) as call: # Designate an appropriate return value for the call. - call.return_value = db_version.ListDbVersionsResponse( + call.return_value = goldengate_deployment.ListGoldengateDeploymentsResponse( next_page_token="next_page_token_value", + unreachable=["unreachable_value"], ) - response = client.list_db_versions(request) + response = client.list_goldengate_deployments(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - request = db_version.ListDbVersionsRequest() + request = goldengate_deployment.ListGoldengateDeploymentsRequest() assert args[0] == request # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListDbVersionsPager) + assert isinstance(response, pagers.ListGoldengateDeploymentsPager) assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] -def test_list_db_versions_non_empty_request_with_auto_populated_field(): +def test_list_goldengate_deployments_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. client = OracleDatabaseClient( @@ -25190,29 +25268,33 @@ def test_list_db_versions_non_empty_request_with_auto_populated_field(): # Populate all string fields in the request which are not UUID4 # since we want to check that UUID4 are populated automatically # if they meet the requirements of AIP 4235. - request = db_version.ListDbVersionsRequest( + request = goldengate_deployment.ListGoldengateDeploymentsRequest( parent="parent_value", page_token="page_token_value", filter="filter_value", + order_by="order_by_value", ) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_db_versions), "__call__") as call: + with mock.patch.object( + type(client.transport.list_goldengate_deployments), "__call__" + ) as call: call.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client.list_db_versions(request=request) + client.list_goldengate_deployments(request=request) call.assert_called() _, args, _ = call.mock_calls[0] - request_msg = db_version.ListDbVersionsRequest( + request_msg = goldengate_deployment.ListGoldengateDeploymentsRequest( parent="parent_value", page_token="page_token_value", filter="filter_value", + order_by="order_by_value", ) assert args[0] == request_msg -def test_list_db_versions_use_cached_wrapped_rpc(): +def test_list_goldengate_deployments_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -25226,23 +25308,26 @@ def test_list_db_versions_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.list_db_versions in client._transport._wrapped_methods + assert ( + client._transport.list_goldengate_deployments + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.list_db_versions] = ( - mock_rpc - ) + client._transport._wrapped_methods[ + client._transport.list_goldengate_deployments + ] = mock_rpc request = {} - client.list_db_versions(request) + client.list_goldengate_deployments(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_db_versions(request) + client.list_goldengate_deployments(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 @@ -25250,7 +25335,7 @@ def test_list_db_versions_use_cached_wrapped_rpc(): @pytest.mark.asyncio -async def test_list_db_versions_async_use_cached_wrapped_rpc( +async def test_list_goldengate_deployments_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", ): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, @@ -25267,7 +25352,7 @@ async def test_list_db_versions_async_use_cached_wrapped_rpc( # Ensure method has been cached assert ( - client._client._transport.list_db_versions + client._client._transport.list_goldengate_deployments in client._client._transport._wrapped_methods ) @@ -25275,16 +25360,16 @@ async def test_list_db_versions_async_use_cached_wrapped_rpc( mock_rpc = mock.AsyncMock() mock_rpc.return_value = mock.Mock() client._client._transport._wrapped_methods[ - client._client._transport.list_db_versions + client._client._transport.list_goldengate_deployments ] = mock_rpc request = {} - await client.list_db_versions(request) + await client.list_goldengate_deployments(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - await client.list_db_versions(request) + await client.list_goldengate_deployments(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 @@ -25295,11 +25380,13 @@ async def test_list_db_versions_async_use_cached_wrapped_rpc( @pytest.mark.parametrize( "request_type", [ - db_version.ListDbVersionsRequest(), + goldengate_deployment.ListGoldengateDeploymentsRequest(), {}, ], ) -async def test_list_db_versions_async(request_type, transport: str = "grpc_asyncio"): +async def test_list_goldengate_deployments_async( + request_type, transport: str = "grpc_asyncio" +): client = OracleDatabaseAsyncClient( credentials=async_anonymous_credentials(), transport=transport, @@ -25310,41 +25397,47 @@ async def test_list_db_versions_async(request_type, transport: str = "grpc_async request = request_type # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_db_versions), "__call__") as call: + with mock.patch.object( + type(client.transport.list_goldengate_deployments), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - db_version.ListDbVersionsResponse( + goldengate_deployment.ListGoldengateDeploymentsResponse( next_page_token="next_page_token_value", + unreachable=["unreachable_value"], ) ) - response = await client.list_db_versions(request) + response = await client.list_goldengate_deployments(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - request = db_version.ListDbVersionsRequest() + request = goldengate_deployment.ListGoldengateDeploymentsRequest() assert args[0] == request # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListDbVersionsAsyncPager) + assert isinstance(response, pagers.ListGoldengateDeploymentsAsyncPager) assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] -def test_list_db_versions_field_headers(): +def test_list_goldengate_deployments_field_headers(): client = OracleDatabaseClient( 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 = db_version.ListDbVersionsRequest() + request = goldengate_deployment.ListGoldengateDeploymentsRequest() request.parent = "parent_value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_db_versions), "__call__") as call: - call.return_value = db_version.ListDbVersionsResponse() - client.list_db_versions(request) + with mock.patch.object( + type(client.transport.list_goldengate_deployments), "__call__" + ) as call: + call.return_value = goldengate_deployment.ListGoldengateDeploymentsResponse() + client.list_goldengate_deployments(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) == 1 @@ -25360,23 +25453,25 @@ def test_list_db_versions_field_headers(): @pytest.mark.asyncio -async def test_list_db_versions_field_headers_async(): +async def test_list_goldengate_deployments_field_headers_async(): client = OracleDatabaseAsyncClient( credentials=async_anonymous_credentials(), ) # 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 = db_version.ListDbVersionsRequest() + request = goldengate_deployment.ListGoldengateDeploymentsRequest() request.parent = "parent_value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_db_versions), "__call__") as call: + with mock.patch.object( + type(client.transport.list_goldengate_deployments), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - db_version.ListDbVersionsResponse() + goldengate_deployment.ListGoldengateDeploymentsResponse() ) - await client.list_db_versions(request) + await client.list_goldengate_deployments(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) @@ -25391,18 +25486,20 @@ async def test_list_db_versions_field_headers_async(): ) in kw["metadata"] -def test_list_db_versions_flattened(): +def test_list_goldengate_deployments_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), ) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_db_versions), "__call__") as call: + with mock.patch.object( + type(client.transport.list_goldengate_deployments), "__call__" + ) as call: # Designate an appropriate return value for the call. - call.return_value = db_version.ListDbVersionsResponse() + call.return_value = goldengate_deployment.ListGoldengateDeploymentsResponse() # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. - client.list_db_versions( + client.list_goldengate_deployments( parent="parent_value", ) @@ -25415,7 +25512,7 @@ def test_list_db_versions_flattened(): assert arg == mock_val -def test_list_db_versions_flattened_error(): +def test_list_goldengate_deployments_flattened_error(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), ) @@ -25423,29 +25520,31 @@ def test_list_db_versions_flattened_error(): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_db_versions( - db_version.ListDbVersionsRequest(), + client.list_goldengate_deployments( + goldengate_deployment.ListGoldengateDeploymentsRequest(), parent="parent_value", ) @pytest.mark.asyncio -async def test_list_db_versions_flattened_async(): +async def test_list_goldengate_deployments_flattened_async(): client = OracleDatabaseAsyncClient( credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_db_versions), "__call__") as call: + with mock.patch.object( + type(client.transport.list_goldengate_deployments), "__call__" + ) as call: # Designate an appropriate return value for the call. - call.return_value = db_version.ListDbVersionsResponse() + call.return_value = goldengate_deployment.ListGoldengateDeploymentsResponse() call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - db_version.ListDbVersionsResponse() + goldengate_deployment.ListGoldengateDeploymentsResponse() ) # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. - response = await client.list_db_versions( + response = await client.list_goldengate_deployments( parent="parent_value", ) @@ -25459,7 +25558,7 @@ async def test_list_db_versions_flattened_async(): @pytest.mark.asyncio -async def test_list_db_versions_flattened_error_async(): +async def test_list_goldengate_deployments_flattened_error_async(): client = OracleDatabaseAsyncClient( credentials=async_anonymous_credentials(), ) @@ -25467,44 +25566,46 @@ async def test_list_db_versions_flattened_error_async(): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - await client.list_db_versions( - db_version.ListDbVersionsRequest(), + await client.list_goldengate_deployments( + goldengate_deployment.ListGoldengateDeploymentsRequest(), parent="parent_value", ) -def test_list_db_versions_pager(transport_name: str = "grpc"): +def test_list_goldengate_deployments_pager(transport_name: str = "grpc"): client = OracleDatabaseClient( 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_db_versions), "__call__") as call: + with mock.patch.object( + type(client.transport.list_goldengate_deployments), "__call__" + ) as call: # Set the response to a series of pages. call.side_effect = ( - db_version.ListDbVersionsResponse( - db_versions=[ - db_version.DbVersion(), - db_version.DbVersion(), - db_version.DbVersion(), + goldengate_deployment.ListGoldengateDeploymentsResponse( + goldengate_deployments=[ + goldengate_deployment.GoldengateDeployment(), + goldengate_deployment.GoldengateDeployment(), + goldengate_deployment.GoldengateDeployment(), ], next_page_token="abc", ), - db_version.ListDbVersionsResponse( - db_versions=[], + goldengate_deployment.ListGoldengateDeploymentsResponse( + goldengate_deployments=[], next_page_token="def", ), - db_version.ListDbVersionsResponse( - db_versions=[ - db_version.DbVersion(), + goldengate_deployment.ListGoldengateDeploymentsResponse( + goldengate_deployments=[ + goldengate_deployment.GoldengateDeployment(), ], next_page_token="ghi", ), - db_version.ListDbVersionsResponse( - db_versions=[ - db_version.DbVersion(), - db_version.DbVersion(), + goldengate_deployment.ListGoldengateDeploymentsResponse( + goldengate_deployments=[ + goldengate_deployment.GoldengateDeployment(), + goldengate_deployment.GoldengateDeployment(), ], ), RuntimeError, @@ -25516,7 +25617,9 @@ def test_list_db_versions_pager(transport_name: str = "grpc"): expected_metadata = tuple(expected_metadata) + ( gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), ) - pager = client.list_db_versions(request={}, retry=retry, timeout=timeout) + pager = client.list_goldengate_deployments( + request={}, retry=retry, timeout=timeout + ) assert pager._metadata == expected_metadata assert pager._retry == retry @@ -25524,89 +25627,95 @@ def test_list_db_versions_pager(transport_name: str = "grpc"): results = list(pager) assert len(results) == 6 - assert all(isinstance(i, db_version.DbVersion) for i in results) + assert all( + isinstance(i, goldengate_deployment.GoldengateDeployment) for i in results + ) -def test_list_db_versions_pages(transport_name: str = "grpc"): +def test_list_goldengate_deployments_pages(transport_name: str = "grpc"): client = OracleDatabaseClient( 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_db_versions), "__call__") as call: + with mock.patch.object( + type(client.transport.list_goldengate_deployments), "__call__" + ) as call: # Set the response to a series of pages. call.side_effect = ( - db_version.ListDbVersionsResponse( - db_versions=[ - db_version.DbVersion(), - db_version.DbVersion(), - db_version.DbVersion(), + goldengate_deployment.ListGoldengateDeploymentsResponse( + goldengate_deployments=[ + goldengate_deployment.GoldengateDeployment(), + goldengate_deployment.GoldengateDeployment(), + goldengate_deployment.GoldengateDeployment(), ], next_page_token="abc", ), - db_version.ListDbVersionsResponse( - db_versions=[], + goldengate_deployment.ListGoldengateDeploymentsResponse( + goldengate_deployments=[], next_page_token="def", ), - db_version.ListDbVersionsResponse( - db_versions=[ - db_version.DbVersion(), + goldengate_deployment.ListGoldengateDeploymentsResponse( + goldengate_deployments=[ + goldengate_deployment.GoldengateDeployment(), ], next_page_token="ghi", ), - db_version.ListDbVersionsResponse( - db_versions=[ - db_version.DbVersion(), - db_version.DbVersion(), + goldengate_deployment.ListGoldengateDeploymentsResponse( + goldengate_deployments=[ + goldengate_deployment.GoldengateDeployment(), + goldengate_deployment.GoldengateDeployment(), ], ), RuntimeError, ) - pages = list(client.list_db_versions(request={}).pages) + pages = list(client.list_goldengate_deployments(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_db_versions_async_pager(): +async def test_list_goldengate_deployments_async_pager(): client = OracleDatabaseAsyncClient( credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_db_versions), "__call__", new_callable=mock.AsyncMock + type(client.transport.list_goldengate_deployments), + "__call__", + new_callable=mock.AsyncMock, ) as call: # Set the response to a series of pages. call.side_effect = ( - db_version.ListDbVersionsResponse( - db_versions=[ - db_version.DbVersion(), - db_version.DbVersion(), - db_version.DbVersion(), + goldengate_deployment.ListGoldengateDeploymentsResponse( + goldengate_deployments=[ + goldengate_deployment.GoldengateDeployment(), + goldengate_deployment.GoldengateDeployment(), + goldengate_deployment.GoldengateDeployment(), ], next_page_token="abc", ), - db_version.ListDbVersionsResponse( - db_versions=[], + goldengate_deployment.ListGoldengateDeploymentsResponse( + goldengate_deployments=[], next_page_token="def", ), - db_version.ListDbVersionsResponse( - db_versions=[ - db_version.DbVersion(), + goldengate_deployment.ListGoldengateDeploymentsResponse( + goldengate_deployments=[ + goldengate_deployment.GoldengateDeployment(), ], next_page_token="ghi", ), - db_version.ListDbVersionsResponse( - db_versions=[ - db_version.DbVersion(), - db_version.DbVersion(), + goldengate_deployment.ListGoldengateDeploymentsResponse( + goldengate_deployments=[ + goldengate_deployment.GoldengateDeployment(), + goldengate_deployment.GoldengateDeployment(), ], ), RuntimeError, ) - async_pager = await client.list_db_versions( + async_pager = await client.list_goldengate_deployments( request={}, ) assert async_pager.next_page_token == "abc" @@ -25615,49 +25724,53 @@ async def test_list_db_versions_async_pager(): responses.append(response) assert len(responses) == 6 - assert all(isinstance(i, db_version.DbVersion) for i in responses) + assert all( + isinstance(i, goldengate_deployment.GoldengateDeployment) for i in responses + ) @pytest.mark.asyncio -async def test_list_db_versions_async_pages(): +async def test_list_goldengate_deployments_async_pages(): client = OracleDatabaseAsyncClient( credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_db_versions), "__call__", new_callable=mock.AsyncMock + type(client.transport.list_goldengate_deployments), + "__call__", + new_callable=mock.AsyncMock, ) as call: # Set the response to a series of pages. call.side_effect = ( - db_version.ListDbVersionsResponse( - db_versions=[ - db_version.DbVersion(), - db_version.DbVersion(), - db_version.DbVersion(), + goldengate_deployment.ListGoldengateDeploymentsResponse( + goldengate_deployments=[ + goldengate_deployment.GoldengateDeployment(), + goldengate_deployment.GoldengateDeployment(), + goldengate_deployment.GoldengateDeployment(), ], next_page_token="abc", ), - db_version.ListDbVersionsResponse( - db_versions=[], + goldengate_deployment.ListGoldengateDeploymentsResponse( + goldengate_deployments=[], next_page_token="def", ), - db_version.ListDbVersionsResponse( - db_versions=[ - db_version.DbVersion(), + goldengate_deployment.ListGoldengateDeploymentsResponse( + goldengate_deployments=[ + goldengate_deployment.GoldengateDeployment(), ], next_page_token="ghi", ), - db_version.ListDbVersionsResponse( - db_versions=[ - db_version.DbVersion(), - db_version.DbVersion(), + goldengate_deployment.ListGoldengateDeploymentsResponse( + goldengate_deployments=[ + goldengate_deployment.GoldengateDeployment(), + goldengate_deployment.GoldengateDeployment(), ], ), RuntimeError, ) pages = [] - async for page_ in (await client.list_db_versions(request={})).pages: + async for page_ in (await client.list_goldengate_deployments(request={})).pages: pages.append(page_) for page_, token in zip(pages, ["abc", "def", "ghi", ""]): assert page_.raw_page.next_page_token == token @@ -25666,11 +25779,11 @@ async def test_list_db_versions_async_pages(): @pytest.mark.parametrize( "request_type", [ - database_character_set.ListDatabaseCharacterSetsRequest(), + goldengate_deployment.GetGoldengateDeploymentRequest(), {}, ], ) -def test_list_database_character_sets(request_type, transport: str = "grpc"): +def test_get_goldengate_deployment(request_type, transport: str = "grpc"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -25682,26 +25795,38 @@ def test_list_database_character_sets(request_type, transport: str = "grpc"): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_database_character_sets), "__call__" + type(client.transport.get_goldengate_deployment), "__call__" ) as call: # Designate an appropriate return value for the call. - call.return_value = database_character_set.ListDatabaseCharacterSetsResponse( - next_page_token="next_page_token_value", + call.return_value = goldengate_deployment.GoldengateDeployment( + name="name_value", + gcp_oracle_zone="gcp_oracle_zone_value", + odb_network="odb_network_value", + odb_subnet="odb_subnet_value", + entitlement_id="entitlement_id_value", + display_name="display_name_value", + oci_url="oci_url_value", ) - response = client.list_database_character_sets(request) + response = client.get_goldengate_deployment(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - request = database_character_set.ListDatabaseCharacterSetsRequest() + request = goldengate_deployment.GetGoldengateDeploymentRequest() assert args[0] == request # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListDatabaseCharacterSetsPager) - assert response.next_page_token == "next_page_token_value" + assert isinstance(response, goldengate_deployment.GoldengateDeployment) + assert response.name == "name_value" + assert response.gcp_oracle_zone == "gcp_oracle_zone_value" + assert response.odb_network == "odb_network_value" + assert response.odb_subnet == "odb_subnet_value" + assert response.entitlement_id == "entitlement_id_value" + assert response.display_name == "display_name_value" + assert response.oci_url == "oci_url_value" -def test_list_database_character_sets_non_empty_request_with_auto_populated_field(): +def test_get_goldengate_deployment_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. client = OracleDatabaseClient( @@ -25712,31 +25837,27 @@ def test_list_database_character_sets_non_empty_request_with_auto_populated_fiel # Populate all string fields in the request which are not UUID4 # since we want to check that UUID4 are populated automatically # if they meet the requirements of AIP 4235. - request = database_character_set.ListDatabaseCharacterSetsRequest( - parent="parent_value", - page_token="page_token_value", - filter="filter_value", + request = goldengate_deployment.GetGoldengateDeploymentRequest( + name="name_value", ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_database_character_sets), "__call__" + type(client.transport.get_goldengate_deployment), "__call__" ) as call: call.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client.list_database_character_sets(request=request) + client.get_goldengate_deployment(request=request) call.assert_called() _, args, _ = call.mock_calls[0] - request_msg = database_character_set.ListDatabaseCharacterSetsRequest( - parent="parent_value", - page_token="page_token_value", - filter="filter_value", + request_msg = goldengate_deployment.GetGoldengateDeploymentRequest( + name="name_value", ) assert args[0] == request_msg -def test_list_database_character_sets_use_cached_wrapped_rpc(): +def test_get_goldengate_deployment_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -25751,7 +25872,7 @@ def test_list_database_character_sets_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.list_database_character_sets + client._transport.get_goldengate_deployment in client._transport._wrapped_methods ) @@ -25761,15 +25882,15 @@ def test_list_database_character_sets_use_cached_wrapped_rpc(): "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ - client._transport.list_database_character_sets + client._transport.get_goldengate_deployment ] = mock_rpc request = {} - client.list_database_character_sets(request) + client.get_goldengate_deployment(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_database_character_sets(request) + client.get_goldengate_deployment(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 @@ -25777,7 +25898,7 @@ def test_list_database_character_sets_use_cached_wrapped_rpc(): @pytest.mark.asyncio -async def test_list_database_character_sets_async_use_cached_wrapped_rpc( +async def test_get_goldengate_deployment_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", ): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, @@ -25794,7 +25915,7 @@ async def test_list_database_character_sets_async_use_cached_wrapped_rpc( # Ensure method has been cached assert ( - client._client._transport.list_database_character_sets + client._client._transport.get_goldengate_deployment in client._client._transport._wrapped_methods ) @@ -25802,16 +25923,16 @@ async def test_list_database_character_sets_async_use_cached_wrapped_rpc( mock_rpc = mock.AsyncMock() mock_rpc.return_value = mock.Mock() client._client._transport._wrapped_methods[ - client._client._transport.list_database_character_sets + client._client._transport.get_goldengate_deployment ] = mock_rpc request = {} - await client.list_database_character_sets(request) + await client.get_goldengate_deployment(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - await client.list_database_character_sets(request) + await client.get_goldengate_deployment(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 @@ -25822,11 +25943,11 @@ async def test_list_database_character_sets_async_use_cached_wrapped_rpc( @pytest.mark.parametrize( "request_type", [ - database_character_set.ListDatabaseCharacterSetsRequest(), + goldengate_deployment.GetGoldengateDeploymentRequest(), {}, ], ) -async def test_list_database_character_sets_async( +async def test_get_goldengate_deployment_async( request_type, transport: str = "grpc_asyncio" ): client = OracleDatabaseAsyncClient( @@ -25840,44 +25961,56 @@ async def test_list_database_character_sets_async( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_database_character_sets), "__call__" + type(client.transport.get_goldengate_deployment), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - database_character_set.ListDatabaseCharacterSetsResponse( - next_page_token="next_page_token_value", + goldengate_deployment.GoldengateDeployment( + name="name_value", + gcp_oracle_zone="gcp_oracle_zone_value", + odb_network="odb_network_value", + odb_subnet="odb_subnet_value", + entitlement_id="entitlement_id_value", + display_name="display_name_value", + oci_url="oci_url_value", ) ) - response = await client.list_database_character_sets(request) + response = await client.get_goldengate_deployment(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - request = database_character_set.ListDatabaseCharacterSetsRequest() + request = goldengate_deployment.GetGoldengateDeploymentRequest() assert args[0] == request # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListDatabaseCharacterSetsAsyncPager) - assert response.next_page_token == "next_page_token_value" + assert isinstance(response, goldengate_deployment.GoldengateDeployment) + assert response.name == "name_value" + assert response.gcp_oracle_zone == "gcp_oracle_zone_value" + assert response.odb_network == "odb_network_value" + assert response.odb_subnet == "odb_subnet_value" + assert response.entitlement_id == "entitlement_id_value" + assert response.display_name == "display_name_value" + assert response.oci_url == "oci_url_value" -def test_list_database_character_sets_field_headers(): +def test_get_goldengate_deployment_field_headers(): client = OracleDatabaseClient( 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 = database_character_set.ListDatabaseCharacterSetsRequest() + request = goldengate_deployment.GetGoldengateDeploymentRequest() - request.parent = "parent_value" + request.name = "name_value" # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_database_character_sets), "__call__" + type(client.transport.get_goldengate_deployment), "__call__" ) as call: - call.return_value = database_character_set.ListDatabaseCharacterSetsResponse() - client.list_database_character_sets(request) + call.return_value = goldengate_deployment.GoldengateDeployment() + client.get_goldengate_deployment(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) == 1 @@ -25888,30 +26021,30 @@ def test_list_database_character_sets_field_headers(): _, _, kw = call.mock_calls[0] assert ( "x-goog-request-params", - "parent=parent_value", + "name=name_value", ) in kw["metadata"] @pytest.mark.asyncio -async def test_list_database_character_sets_field_headers_async(): +async def test_get_goldengate_deployment_field_headers_async(): client = OracleDatabaseAsyncClient( credentials=async_anonymous_credentials(), ) # 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 = database_character_set.ListDatabaseCharacterSetsRequest() + request = goldengate_deployment.GetGoldengateDeploymentRequest() - request.parent = "parent_value" + request.name = "name_value" # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_database_character_sets), "__call__" + type(client.transport.get_goldengate_deployment), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - database_character_set.ListDatabaseCharacterSetsResponse() + goldengate_deployment.GoldengateDeployment() ) - await client.list_database_character_sets(request) + await client.get_goldengate_deployment(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) @@ -25922,37 +26055,37 @@ async def test_list_database_character_sets_field_headers_async(): _, _, kw = call.mock_calls[0] assert ( "x-goog-request-params", - "parent=parent_value", + "name=name_value", ) in kw["metadata"] -def test_list_database_character_sets_flattened(): +def test_get_goldengate_deployment_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_database_character_sets), "__call__" + type(client.transport.get_goldengate_deployment), "__call__" ) as call: # Designate an appropriate return value for the call. - call.return_value = database_character_set.ListDatabaseCharacterSetsResponse() + call.return_value = goldengate_deployment.GoldengateDeployment() # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. - client.list_database_character_sets( - parent="parent_value", + client.get_goldengate_deployment( + name="name_value", ) # Establish that the underlying call was made with the expected # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - arg = args[0].parent - mock_val = "parent_value" + arg = args[0].name + mock_val = "name_value" assert arg == mock_val -def test_list_database_character_sets_flattened_error(): +def test_get_goldengate_deployment_flattened_error(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), ) @@ -25960,45 +26093,45 @@ def test_list_database_character_sets_flattened_error(): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_database_character_sets( - database_character_set.ListDatabaseCharacterSetsRequest(), - parent="parent_value", + client.get_goldengate_deployment( + goldengate_deployment.GetGoldengateDeploymentRequest(), + name="name_value", ) @pytest.mark.asyncio -async def test_list_database_character_sets_flattened_async(): +async def test_get_goldengate_deployment_flattened_async(): client = OracleDatabaseAsyncClient( credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_database_character_sets), "__call__" + type(client.transport.get_goldengate_deployment), "__call__" ) as call: # Designate an appropriate return value for the call. - call.return_value = database_character_set.ListDatabaseCharacterSetsResponse() + call.return_value = goldengate_deployment.GoldengateDeployment() call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - database_character_set.ListDatabaseCharacterSetsResponse() + goldengate_deployment.GoldengateDeployment() ) # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. - response = await client.list_database_character_sets( - parent="parent_value", + response = await client.get_goldengate_deployment( + name="name_value", ) # Establish that the underlying call was made with the expected # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - arg = args[0].parent - mock_val = "parent_value" + arg = args[0].name + mock_val = "name_value" assert arg == mock_val @pytest.mark.asyncio -async def test_list_database_character_sets_flattened_error_async(): +async def test_get_goldengate_deployment_flattened_error_async(): client = OracleDatabaseAsyncClient( credentials=async_anonymous_credentials(), ) @@ -26006,226 +26139,135 @@ async def test_list_database_character_sets_flattened_error_async(): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - await client.list_database_character_sets( - database_character_set.ListDatabaseCharacterSetsRequest(), - parent="parent_value", + await client.get_goldengate_deployment( + goldengate_deployment.GetGoldengateDeploymentRequest(), + name="name_value", ) -def test_list_database_character_sets_pager(transport_name: str = "grpc"): +@pytest.mark.parametrize( + "request_type", + [ + gco_goldengate_deployment.CreateGoldengateDeploymentRequest(), + {}, + ], +) +def test_create_goldengate_deployment(request_type, transport: str = "grpc"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport_name, + 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_database_character_sets), "__call__" + type(client.transport.create_goldengate_deployment), "__call__" ) as call: - # Set the response to a series of pages. - call.side_effect = ( - database_character_set.ListDatabaseCharacterSetsResponse( - database_character_sets=[ - database_character_set.DatabaseCharacterSet(), - database_character_set.DatabaseCharacterSet(), - database_character_set.DatabaseCharacterSet(), - ], - next_page_token="abc", - ), - database_character_set.ListDatabaseCharacterSetsResponse( - database_character_sets=[], - next_page_token="def", - ), - database_character_set.ListDatabaseCharacterSetsResponse( - database_character_sets=[ - database_character_set.DatabaseCharacterSet(), - ], - next_page_token="ghi", - ), - database_character_set.ListDatabaseCharacterSetsResponse( - database_character_sets=[ - database_character_set.DatabaseCharacterSet(), - database_character_set.DatabaseCharacterSet(), - ], - ), - RuntimeError, - ) - - expected_metadata = () - retry = retries.Retry() - timeout = 5 - expected_metadata = tuple(expected_metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), - ) - pager = client.list_database_character_sets( - request={}, retry=retry, timeout=timeout - ) + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.create_goldengate_deployment(request) - assert pager._metadata == expected_metadata - assert pager._retry == retry - assert pager._timeout == timeout + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = gco_goldengate_deployment.CreateGoldengateDeploymentRequest() + assert args[0] == request - results = list(pager) - assert len(results) == 6 - assert all( - isinstance(i, database_character_set.DatabaseCharacterSet) for i in results - ) + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) -def test_list_database_character_sets_pages(transport_name: str = "grpc"): +def test_create_goldengate_deployment_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport_name, + transport="grpc", ) - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_database_character_sets), "__call__" - ) as call: - # Set the response to a series of pages. - call.side_effect = ( - database_character_set.ListDatabaseCharacterSetsResponse( - database_character_sets=[ - database_character_set.DatabaseCharacterSet(), - database_character_set.DatabaseCharacterSet(), - database_character_set.DatabaseCharacterSet(), - ], - next_page_token="abc", - ), - database_character_set.ListDatabaseCharacterSetsResponse( - database_character_sets=[], - next_page_token="def", - ), - database_character_set.ListDatabaseCharacterSetsResponse( - database_character_sets=[ - database_character_set.DatabaseCharacterSet(), - ], - next_page_token="ghi", - ), - database_character_set.ListDatabaseCharacterSetsResponse( - database_character_sets=[ - database_character_set.DatabaseCharacterSet(), - database_character_set.DatabaseCharacterSet(), - ], - ), - RuntimeError, - ) - pages = list(client.list_database_character_sets(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_database_character_sets_async_pager(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = gco_goldengate_deployment.CreateGoldengateDeploymentRequest( + parent="parent_value", + goldengate_deployment_id="goldengate_deployment_id_value", ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_database_character_sets), - "__call__", - new_callable=mock.AsyncMock, + type(client.transport.create_goldengate_deployment), "__call__" ) as call: - # Set the response to a series of pages. - call.side_effect = ( - database_character_set.ListDatabaseCharacterSetsResponse( - database_character_sets=[ - database_character_set.DatabaseCharacterSet(), - database_character_set.DatabaseCharacterSet(), - database_character_set.DatabaseCharacterSet(), - ], - next_page_token="abc", - ), - database_character_set.ListDatabaseCharacterSetsResponse( - database_character_sets=[], - next_page_token="def", - ), - database_character_set.ListDatabaseCharacterSetsResponse( - database_character_sets=[ - database_character_set.DatabaseCharacterSet(), - ], - next_page_token="ghi", - ), - database_character_set.ListDatabaseCharacterSetsResponse( - database_character_sets=[ - database_character_set.DatabaseCharacterSet(), - database_character_set.DatabaseCharacterSet(), - ], - ), - RuntimeError, + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. ) - async_pager = await client.list_database_character_sets( - request={}, + client.create_goldengate_deployment(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gco_goldengate_deployment.CreateGoldengateDeploymentRequest( + parent="parent_value", + goldengate_deployment_id="goldengate_deployment_id_value", ) - assert async_pager.next_page_token == "abc" - responses = [] - async for response in async_pager: # pragma: no branch - responses.append(response) + assert args[0] == request_msg - assert len(responses) == 6 - assert all( - isinstance(i, database_character_set.DatabaseCharacterSet) - for i in responses + +def test_create_goldengate_deployment_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() -@pytest.mark.asyncio -async def test_list_database_character_sets_async_pages(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - ) + # Ensure method has been cached + assert ( + client._transport.create_goldengate_deployment + in client._transport._wrapped_methods + ) - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_database_character_sets), - "__call__", - new_callable=mock.AsyncMock, - ) as call: - # Set the response to a series of pages. - call.side_effect = ( - database_character_set.ListDatabaseCharacterSetsResponse( - database_character_sets=[ - database_character_set.DatabaseCharacterSet(), - database_character_set.DatabaseCharacterSet(), - database_character_set.DatabaseCharacterSet(), - ], - next_page_token="abc", - ), - database_character_set.ListDatabaseCharacterSetsResponse( - database_character_sets=[], - next_page_token="def", - ), - database_character_set.ListDatabaseCharacterSetsResponse( - database_character_sets=[ - database_character_set.DatabaseCharacterSet(), - ], - next_page_token="ghi", - ), - database_character_set.ListDatabaseCharacterSetsResponse( - database_character_sets=[ - database_character_set.DatabaseCharacterSet(), - database_character_set.DatabaseCharacterSet(), - ], - ), - RuntimeError, + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. ) - pages = [] - async for page_ in ( - await client.list_database_character_sets(request={}) - ).pages: - pages.append(page_) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + client._transport._wrapped_methods[ + client._transport.create_goldengate_deployment + ] = mock_rpc + request = {} + client.create_goldengate_deployment(request) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 -def test_list_cloud_exadata_infrastructures_rest_use_cached_wrapped_rpc(): + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.create_goldengate_deployment(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_create_goldengate_deployment_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, ) # Should wrap all calls on client creation @@ -26234,276 +26276,327 @@ def test_list_cloud_exadata_infrastructures_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.list_cloud_exadata_infrastructures - in client._transport._wrapped_methods + client._client._transport.create_goldengate_deployment + in client._client._transport._wrapped_methods ) # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[ - client._transport.list_cloud_exadata_infrastructures + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.create_goldengate_deployment ] = mock_rpc request = {} - client.list_cloud_exadata_infrastructures(request) + await client.create_goldengate_deployment(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_cloud_exadata_infrastructures(request) + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + await client.create_goldengate_deployment(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_cloud_exadata_infrastructures_rest_required_fields( - request_type=oracledatabase.ListCloudExadataInfrastructuresRequest, +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + gco_goldengate_deployment.CreateGoldengateDeploymentRequest(), + {}, + ], +) +async def test_create_goldengate_deployment_async( + request_type, transport: str = "grpc_asyncio" ): - transport_class = transports.OracleDatabaseRestTransport - - request_init = {} - request_init["parent"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, ) - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_cloud_exadata_infrastructures._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # 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 - # verify required fields with default values are now present + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_goldengate_deployment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + response = await client.create_goldengate_deployment(request) - jsonified_request["parent"] = "parent_value" + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = gco_goldengate_deployment.CreateGoldengateDeploymentRequest() + assert args[0] == request - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_cloud_exadata_infrastructures._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "filter", - "order_by", - "page_size", - "page_token", - ) - ) - jsonified_request.update(unset_fields) + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" +def test_create_goldengate_deployment_field_headers(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListCloudExadataInfrastructuresResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - response_value = Response() - response_value.status_code = 200 + # 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 = gco_goldengate_deployment.CreateGoldengateDeploymentRequest() - # Convert return value to protobuf type - return_value = oracledatabase.ListCloudExadataInfrastructuresResponse.pb( - return_value - ) - json_return_value = json_format.MessageToJson(return_value) + request.parent = "parent_value" - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_goldengate_deployment), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_goldengate_deployment(request) - response = client.list_cloud_exadata_infrastructures(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 - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + # 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_cloud_exadata_infrastructures_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials +@pytest.mark.asyncio +async def test_create_goldengate_deployment_field_headers_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - unset_fields = ( - transport.list_cloud_exadata_infrastructures._get_unset_required_fields({}) - ) - assert set(unset_fields) == ( - set( - ( - "filter", - "orderBy", - "pageSize", - "pageToken", - ) + # 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 = gco_goldengate_deployment.CreateGoldengateDeploymentRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_goldengate_deployment), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") ) - & set(("parent",)) - ) + await client.create_goldengate_deployment(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request -def test_list_cloud_exadata_infrastructures_rest_flattened(): + # 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_goldengate_deployment_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListCloudExadataInfrastructuresResponse() + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_goldengate_deployment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_goldengate_deployment( + parent="parent_value", + goldengate_deployment=gco_goldengate_deployment.GoldengateDeployment( + name="name_value" + ), + goldengate_deployment_id="goldengate_deployment_id_value", + ) - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} + # 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].goldengate_deployment + mock_val = gco_goldengate_deployment.GoldengateDeployment(name="name_value") + assert arg == mock_val + arg = args[0].goldengate_deployment_id + mock_val = "goldengate_deployment_id_value" + assert arg == mock_val - # get truthy value for each flattened field - mock_args = dict( + +def test_create_goldengate_deployment_flattened_error(): + client = OracleDatabaseClient( + 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_goldengate_deployment( + gco_goldengate_deployment.CreateGoldengateDeploymentRequest(), parent="parent_value", + goldengate_deployment=gco_goldengate_deployment.GoldengateDeployment( + name="name_value" + ), + goldengate_deployment_id="goldengate_deployment_id_value", ) - mock_args.update(sample_request) - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = oracledatabase.ListCloudExadataInfrastructuresResponse.pb( - return_value - ) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_cloud_exadata_infrastructures(**mock_args) +@pytest.mark.asyncio +async def test_create_goldengate_deployment_flattened_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_goldengate_deployment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_goldengate_deployment( + parent="parent_value", + goldengate_deployment=gco_goldengate_deployment.GoldengateDeployment( + name="name_value" + ), + goldengate_deployment_id="goldengate_deployment_id_value", + ) # Establish that the underlying call was made with the expected # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/cloudExadataInfrastructures" - % client.transport._host, - args[1], - ) + 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].goldengate_deployment + mock_val = gco_goldengate_deployment.GoldengateDeployment(name="name_value") + assert arg == mock_val + arg = args[0].goldengate_deployment_id + mock_val = "goldengate_deployment_id_value" + assert arg == mock_val -def test_list_cloud_exadata_infrastructures_rest_flattened_error( - transport: str = "rest", -): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, +@pytest.mark.asyncio +async def test_create_goldengate_deployment_flattened_error_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_cloud_exadata_infrastructures( - oracledatabase.ListCloudExadataInfrastructuresRequest(), + await client.create_goldengate_deployment( + gco_goldengate_deployment.CreateGoldengateDeploymentRequest(), parent="parent_value", + goldengate_deployment=gco_goldengate_deployment.GoldengateDeployment( + name="name_value" + ), + goldengate_deployment_id="goldengate_deployment_id_value", ) -def test_list_cloud_exadata_infrastructures_rest_pager(transport: str = "rest"): +@pytest.mark.parametrize( + "request_type", + [ + goldengate_deployment.DeleteGoldengateDeploymentRequest(), + {}, + ], +) +def test_delete_goldengate_deployment(request_type, transport: str = "grpc"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - oracledatabase.ListCloudExadataInfrastructuresResponse( - cloud_exadata_infrastructures=[ - exadata_infra.CloudExadataInfrastructure(), - exadata_infra.CloudExadataInfrastructure(), - exadata_infra.CloudExadataInfrastructure(), - ], - next_page_token="abc", - ), - oracledatabase.ListCloudExadataInfrastructuresResponse( - cloud_exadata_infrastructures=[], - next_page_token="def", - ), - oracledatabase.ListCloudExadataInfrastructuresResponse( - cloud_exadata_infrastructures=[ - exadata_infra.CloudExadataInfrastructure(), - ], - next_page_token="ghi", - ), - oracledatabase.ListCloudExadataInfrastructuresResponse( - cloud_exadata_infrastructures=[ - exadata_infra.CloudExadataInfrastructure(), - exadata_infra.CloudExadataInfrastructure(), - ], - ), - ) - # Two responses for two calls - response = response + response + # 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 - # Wrap the values into proper Response objs - response = tuple( - oracledatabase.ListCloudExadataInfrastructuresResponse.to_json(x) - for x in response - ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_goldengate_deployment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.delete_goldengate_deployment(request) - sample_request = {"parent": "projects/sample1/locations/sample2"} + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = goldengate_deployment.DeleteGoldengateDeploymentRequest() + assert args[0] == request - pager = client.list_cloud_exadata_infrastructures(request=sample_request) + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) - results = list(pager) - assert len(results) == 6 - assert all( - isinstance(i, exadata_infra.CloudExadataInfrastructure) for i in results - ) - pages = list( - client.list_cloud_exadata_infrastructures(request=sample_request).pages +def test_delete_goldengate_deployment_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = goldengate_deployment.DeleteGoldengateDeploymentRequest( + name="name_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_goldengate_deployment), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. ) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + client.delete_goldengate_deployment(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment.DeleteGoldengateDeploymentRequest( + name="name_value", + ) + assert args[0] == request_msg -def test_get_cloud_exadata_infrastructure_rest_use_cached_wrapped_rpc(): +def test_delete_goldengate_deployment_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) # Should wrap all calls on client creation @@ -26512,7 +26605,7 @@ def test_get_cloud_exadata_infrastructure_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.get_cloud_exadata_infrastructure + client._transport.delete_goldengate_deployment in client._transport._wrapped_methods ) @@ -26522,412 +26615,337 @@ def test_get_cloud_exadata_infrastructure_rest_use_cached_wrapped_rpc(): "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ - client._transport.get_cloud_exadata_infrastructure + client._transport.delete_goldengate_deployment ] = mock_rpc - request = {} - client.get_cloud_exadata_infrastructure(request) + client.delete_goldengate_deployment(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.get_cloud_exadata_infrastructure(request) + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_goldengate_deployment(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_get_cloud_exadata_infrastructure_rest_required_fields( - request_type=oracledatabase.GetCloudExadataInfrastructureRequest, +@pytest.mark.asyncio +async def test_delete_goldengate_deployment_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", ): - transport_class = transports.OracleDatabaseRestTransport - - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - # verify fields with default values are dropped + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_cloud_exadata_infrastructure._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Ensure method has been cached + assert ( + client._client._transport.delete_goldengate_deployment + in client._client._transport._wrapped_methods + ) - # verify required fields with default values are now present + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.delete_goldengate_deployment + ] = mock_rpc - jsonified_request["name"] = "name_value" + request = {} + await client.delete_goldengate_deployment(request) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_cloud_exadata_infrastructure._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) + await client.delete_goldengate_deployment(request) - # Designate an appropriate value for the returned response. - return_value = exadata_infra.CloudExadataInfrastructure() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = exadata_infra.CloudExadataInfrastructure.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_cloud_exadata_infrastructure(request) +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + goldengate_deployment.DeleteGoldengateDeploymentRequest(), + {}, + ], +) +async def test_delete_goldengate_deployment_async( + request_type, transport: str = "grpc_asyncio" +): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + # 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_goldengate_deployment), "__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.delete_goldengate_deployment(request) -def test_get_cloud_exadata_infrastructure_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = goldengate_deployment.DeleteGoldengateDeploymentRequest() + assert args[0] == request - unset_fields = ( - transport.get_cloud_exadata_infrastructure._get_unset_required_fields({}) - ) - assert set(unset_fields) == (set(()) & set(("name",))) + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) -def test_get_cloud_exadata_infrastructure_rest_flattened(): +def test_delete_goldengate_deployment_field_headers(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = exadata_infra.CloudExadataInfrastructure() - - # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/cloudExadataInfrastructures/sample3" - } + # 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 = goldengate_deployment.DeleteGoldengateDeploymentRequest() - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) + request.name = "name_value" - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = exadata_infra.CloudExadataInfrastructure.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_goldengate_deployment), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_goldengate_deployment(request) - client.get_cloud_exadata_infrastructure(**mock_args) + # 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 underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/cloudExadataInfrastructures/*}" - % client.transport._host, - args[1], - ) + # 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_cloud_exadata_infrastructure_rest_flattened_error(transport: str = "rest"): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, +@pytest.mark.asyncio +async def test_delete_goldengate_deployment_field_headers_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.get_cloud_exadata_infrastructure( - oracledatabase.GetCloudExadataInfrastructureRequest(), - name="name_value", - ) - - -def test_create_cloud_exadata_infrastructure_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() + # 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 = goldengate_deployment.DeleteGoldengateDeploymentRequest() - # Ensure method has been cached - assert ( - client._transport.create_cloud_exadata_infrastructure - in client._transport._wrapped_methods - ) + request.name = "name_value" - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_goldengate_deployment), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") ) - client._transport._wrapped_methods[ - client._transport.create_cloud_exadata_infrastructure - ] = mock_rpc - - request = {} - client.create_cloud_exadata_infrastructure(request) + await client.delete_goldengate_deployment(request) # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.create_cloud_exadata_infrastructure(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 + 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_create_cloud_exadata_infrastructure_rest_required_fields( - request_type=oracledatabase.CreateCloudExadataInfrastructureRequest, -): - transport_class = transports.OracleDatabaseRestTransport - request_init = {} - request_init["parent"] = "" - request_init["cloud_exadata_infrastructure_id"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) +def test_delete_goldengate_deployment_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), ) - # verify fields with default values are dropped - assert "cloudExadataInfrastructureId" not in jsonified_request + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_goldengate_deployment), "__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.delete_goldengate_deployment( + name="name_value", + ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).create_cloud_exadata_infrastructure._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # 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 - # verify required fields with default values are now present - assert "cloudExadataInfrastructureId" in jsonified_request - assert ( - jsonified_request["cloudExadataInfrastructureId"] - == request_init["cloud_exadata_infrastructure_id"] - ) - jsonified_request["parent"] = "parent_value" - jsonified_request["cloudExadataInfrastructureId"] = ( - "cloud_exadata_infrastructure_id_value" +def test_delete_goldengate_deployment_flattened_error(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).create_cloud_exadata_infrastructure._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "cloud_exadata_infrastructure_id", - "request_id", + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_goldengate_deployment( + goldengate_deployment.DeleteGoldengateDeploymentRequest(), + name="name_value", ) - ) - jsonified_request.update(unset_fields) - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" - assert "cloudExadataInfrastructureId" in jsonified_request - assert ( - jsonified_request["cloudExadataInfrastructureId"] - == "cloud_exadata_infrastructure_id_value" - ) - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", +@pytest.mark.asyncio +async def test_delete_goldengate_deployment_flattened_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "post", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_goldengate_deployment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") - response = client.create_cloud_exadata_infrastructure(request) + 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.delete_goldengate_deployment( + name="name_value", + ) - expected_params = [ - ( - "cloudExadataInfrastructureId", - "", - ), - ("$alt", "json;enum-encoding=int"), - ] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + # 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 -def test_create_cloud_exadata_infrastructure_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials +@pytest.mark.asyncio +async def test_delete_goldengate_deployment_flattened_error_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - unset_fields = ( - transport.create_cloud_exadata_infrastructure._get_unset_required_fields({}) - ) - assert set(unset_fields) == ( - set( - ( - "cloudExadataInfrastructureId", - "requestId", - ) - ) - & set( - ( - "parent", - "cloudExadataInfrastructureId", - "cloudExadataInfrastructure", - ) + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_goldengate_deployment( + goldengate_deployment.DeleteGoldengateDeploymentRequest(), + name="name_value", ) - ) -def test_create_cloud_exadata_infrastructure_rest_flattened(): +@pytest.mark.parametrize( + "request_type", + [ + goldengate_deployment.StopGoldengateDeploymentRequest(), + {}, + ], +) +def test_stop_goldengate_deployment(request_type, transport: str = "grpc"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport=transport, ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} - - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", - cloud_exadata_infrastructure=exadata_infra.CloudExadataInfrastructure( - name="name_value" - ), - cloud_exadata_infrastructure_id="cloud_exadata_infrastructure_id_value", - ) - mock_args.update(sample_request) + # 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 - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.stop_goldengate_deployment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.stop_goldengate_deployment(request) - client.create_cloud_exadata_infrastructure(**mock_args) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = goldengate_deployment.StopGoldengateDeploymentRequest() + assert args[0] == request - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/cloudExadataInfrastructures" - % client.transport._host, - args[1], - ) + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) -def test_create_cloud_exadata_infrastructure_rest_flattened_error( - transport: str = "rest", -): +def test_stop_goldengate_deployment_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport="grpc", ) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.create_cloud_exadata_infrastructure( - oracledatabase.CreateCloudExadataInfrastructureRequest(), - parent="parent_value", - cloud_exadata_infrastructure=exadata_infra.CloudExadataInfrastructure( - name="name_value" - ), - cloud_exadata_infrastructure_id="cloud_exadata_infrastructure_id_value", + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = goldengate_deployment.StopGoldengateDeploymentRequest( + name="name_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.stop_goldengate_deployment), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.stop_goldengate_deployment(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment.StopGoldengateDeploymentRequest( + name="name_value", ) + assert args[0] == request_msg -def test_delete_cloud_exadata_infrastructure_rest_use_cached_wrapped_rpc(): +def test_stop_goldengate_deployment_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) # Should wrap all calls on client creation @@ -26936,7 +26954,7 @@ def test_delete_cloud_exadata_infrastructure_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.delete_cloud_exadata_infrastructure + client._transport.stop_goldengate_deployment in client._transport._wrapped_methods ) @@ -26946,191 +26964,337 @@ def test_delete_cloud_exadata_infrastructure_rest_use_cached_wrapped_rpc(): "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ - client._transport.delete_cloud_exadata_infrastructure + client._transport.stop_goldengate_deployment ] = mock_rpc - request = {} - client.delete_cloud_exadata_infrastructure(request) + client.stop_goldengate_deployment(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper wrapper_fn.reset_mock() - client.delete_cloud_exadata_infrastructure(request) + client.stop_goldengate_deployment(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_delete_cloud_exadata_infrastructure_rest_required_fields( - request_type=oracledatabase.DeleteCloudExadataInfrastructureRequest, +@pytest.mark.asyncio +async def test_stop_goldengate_deployment_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", ): - transport_class = transports.OracleDatabaseRestTransport + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # verify fields with default values are dropped + # Ensure method has been cached + assert ( + client._client._transport.stop_goldengate_deployment + in client._client._transport._wrapped_methods + ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).delete_cloud_exadata_infrastructure._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.stop_goldengate_deployment + ] = mock_rpc - # verify required fields with default values are now present + request = {} + await client.stop_goldengate_deployment(request) - jsonified_request["name"] = "name_value" + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).delete_cloud_exadata_infrastructure._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "force", - "request_id", - ) - ) - jsonified_request.update(unset_fields) + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + await client.stop_goldengate_deployment(request) + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + goldengate_deployment.StopGoldengateDeploymentRequest(), + {}, + ], +) +async def test_stop_goldengate_deployment_async( + request_type, transport: str = "grpc_asyncio" +): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + 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.stop_goldengate_deployment), "__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.stop_goldengate_deployment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = goldengate_deployment.StopGoldengateDeploymentRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_stop_goldengate_deployment_field_headers(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - request = request_type(**request_init) - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "delete", - "query_params": pb_request, - } - transcode.return_value = transcode_result + # 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 = goldengate_deployment.StopGoldengateDeploymentRequest() - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) + request.name = "name_value" - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.stop_goldengate_deployment), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.stop_goldengate_deployment(request) - response = client.delete_cloud_exadata_infrastructure(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 - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + # 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_cloud_exadata_infrastructure_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials +@pytest.mark.asyncio +async def test_stop_goldengate_deployment_field_headers_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - unset_fields = ( - transport.delete_cloud_exadata_infrastructure._get_unset_required_fields({}) - ) - assert set(unset_fields) == ( - set( - ( - "force", - "requestId", - ) + # 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 = goldengate_deployment.StopGoldengateDeploymentRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.stop_goldengate_deployment), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") ) - & set(("name",)) - ) + await client.stop_goldengate_deployment(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request -def test_delete_cloud_exadata_infrastructure_rest_flattened(): + # 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_stop_goldengate_deployment_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.stop_goldengate_deployment), "__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.stop_goldengate_deployment( + name="name_value", + ) - # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/cloudExadataInfrastructures/sample3" - } + # 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 - # get truthy value for each flattened field - mock_args = dict( + +def test_stop_goldengate_deployment_flattened_error(): + client = OracleDatabaseClient( + 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.stop_goldengate_deployment( + goldengate_deployment.StopGoldengateDeploymentRequest(), name="name_value", ) - mock_args.update(sample_request) - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_cloud_exadata_infrastructure(**mock_args) +@pytest.mark.asyncio +async def test_stop_goldengate_deployment_flattened_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.stop_goldengate_deployment), "__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.stop_goldengate_deployment( + name="name_value", + ) # Establish that the underlying call was made with the expected # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/cloudExadataInfrastructures/*}" - % client.transport._host, - args[1], + 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_stop_goldengate_deployment_flattened_error_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.stop_goldengate_deployment( + goldengate_deployment.StopGoldengateDeploymentRequest(), + name="name_value", ) -def test_delete_cloud_exadata_infrastructure_rest_flattened_error( - transport: str = "rest", -): +@pytest.mark.parametrize( + "request_type", + [ + goldengate_deployment.StartGoldengateDeploymentRequest(), + {}, + ], +) +def test_start_goldengate_deployment(request_type, transport: str = "grpc"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.delete_cloud_exadata_infrastructure( - oracledatabase.DeleteCloudExadataInfrastructureRequest(), + # 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.start_goldengate_deployment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.start_goldengate_deployment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = goldengate_deployment.StartGoldengateDeploymentRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_start_goldengate_deployment_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = goldengate_deployment.StartGoldengateDeploymentRequest( + name="name_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.start_goldengate_deployment), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.start_goldengate_deployment(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment.StartGoldengateDeploymentRequest( name="name_value", ) + assert args[0] == request_msg -def test_list_cloud_vm_clusters_rest_use_cached_wrapped_rpc(): +def test_start_goldengate_deployment_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) # Should wrap all calls on client creation @@ -27139,7 +27303,7 @@ def test_list_cloud_vm_clusters_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.list_cloud_vm_clusters + client._transport.start_goldengate_deployment in client._transport._wrapped_methods ) @@ -27148,252 +27312,349 @@ def test_list_cloud_vm_clusters_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.list_cloud_vm_clusters] = ( - mock_rpc - ) - + client._transport._wrapped_methods[ + client._transport.start_goldengate_deployment + ] = mock_rpc request = {} - client.list_cloud_vm_clusters(request) + client.start_goldengate_deployment(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_cloud_vm_clusters(request) + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.start_goldengate_deployment(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_cloud_vm_clusters_rest_required_fields( - request_type=oracledatabase.ListCloudVmClustersRequest, +@pytest.mark.asyncio +async def test_start_goldengate_deployment_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", ): - transport_class = transports.OracleDatabaseRestTransport - - request_init = {} - request_init["parent"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_cloud_vm_clusters._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["parent"] = "parent_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_cloud_vm_clusters._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "filter", - "page_size", - "page_token", + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, ) - ) - jsonified_request.update(unset_fields) - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) + # Ensure method has been cached + assert ( + client._client._transport.start_goldengate_deployment + in client._client._transport._wrapped_methods + ) - # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListCloudVmClustersResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.start_goldengate_deployment + ] = mock_rpc - response_value = Response() - response_value.status_code = 200 + request = {} + await client.start_goldengate_deployment(request) - # Convert return value to protobuf type - return_value = oracledatabase.ListCloudVmClustersResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() - response = client.list_cloud_vm_clusters(request) + await client.start_goldengate_deployment(request) - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 -def test_list_cloud_vm_clusters_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + goldengate_deployment.StartGoldengateDeploymentRequest(), + {}, + ], +) +async def test_start_goldengate_deployment_async( + request_type, transport: str = "grpc_asyncio" +): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, ) - unset_fields = transport.list_cloud_vm_clusters._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "filter", - "pageSize", - "pageToken", - ) + # 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.start_goldengate_deployment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") ) - & set(("parent",)) - ) + response = await client.start_goldengate_deployment(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = goldengate_deployment.StartGoldengateDeploymentRequest() + assert args[0] == request -def test_list_cloud_vm_clusters_rest_flattened(): + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_start_goldengate_deployment_field_headers(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListCloudVmClustersResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} + # 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 = goldengate_deployment.StartGoldengateDeploymentRequest() - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", - ) - mock_args.update(sample_request) + request.name = "name_value" - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = oracledatabase.ListCloudVmClustersResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.start_goldengate_deployment), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.start_goldengate_deployment(request) - client.list_cloud_vm_clusters(**mock_args) + # 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 underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/cloudVmClusters" - % client.transport._host, - args[1], - ) + # 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_list_cloud_vm_clusters_rest_flattened_error(transport: str = "rest"): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, +@pytest.mark.asyncio +async def test_start_goldengate_deployment_field_headers_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.list_cloud_vm_clusters( - oracledatabase.ListCloudVmClustersRequest(), - parent="parent_value", + # 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 = goldengate_deployment.StartGoldengateDeploymentRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.start_goldengate_deployment), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") ) + await client.start_goldengate_deployment(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request -def test_list_cloud_vm_clusters_rest_pager(transport: str = "rest"): + # 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_start_goldengate_deployment_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - oracledatabase.ListCloudVmClustersResponse( - cloud_vm_clusters=[ - vm_cluster.CloudVmCluster(), - vm_cluster.CloudVmCluster(), - vm_cluster.CloudVmCluster(), - ], - next_page_token="abc", - ), - oracledatabase.ListCloudVmClustersResponse( - cloud_vm_clusters=[], - next_page_token="def", - ), - oracledatabase.ListCloudVmClustersResponse( - cloud_vm_clusters=[ - vm_cluster.CloudVmCluster(), - ], - next_page_token="ghi", - ), - oracledatabase.ListCloudVmClustersResponse( - cloud_vm_clusters=[ - vm_cluster.CloudVmCluster(), - vm_cluster.CloudVmCluster(), - ], - ), + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.start_goldengate_deployment), "__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.start_goldengate_deployment( + name="name_value", ) - # Two responses for two calls - response = response + response - # Wrap the values into proper Response objs - response = tuple( - oracledatabase.ListCloudVmClustersResponse.to_json(x) for x in response + # 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_start_goldengate_deployment_flattened_error(): + client = OracleDatabaseClient( + 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.start_goldengate_deployment( + goldengate_deployment.StartGoldengateDeploymentRequest(), + name="name_value", ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - sample_request = {"parent": "projects/sample1/locations/sample2"} - pager = client.list_cloud_vm_clusters(request=sample_request) +@pytest.mark.asyncio +async def test_start_goldengate_deployment_flattened_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, vm_cluster.CloudVmCluster) for i in results) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.start_goldengate_deployment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") - pages = list(client.list_cloud_vm_clusters(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + 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.start_goldengate_deployment( + 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 -def test_get_cloud_vm_cluster_rest_use_cached_wrapped_rpc(): +@pytest.mark.asyncio +async def test_start_goldengate_deployment_flattened_error_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.start_goldengate_deployment( + goldengate_deployment.StartGoldengateDeploymentRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + goldengate_connection.ListGoldengateConnectionsRequest(), + {}, + ], +) +def test_list_goldengate_connections(request_type, transport: str = "grpc"): + client = OracleDatabaseClient( + 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_goldengate_connections), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = goldengate_connection.ListGoldengateConnectionsResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + response = client.list_goldengate_connections(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = goldengate_connection.ListGoldengateConnectionsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListGoldengateConnectionsPager) + assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] + + +def test_list_goldengate_connections_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = goldengate_connection.ListGoldengateConnectionsRequest( + parent="parent_value", + page_token="page_token_value", + filter="filter_value", + order_by="order_by_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connections), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.list_goldengate_connections(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_connection.ListGoldengateConnectionsRequest( + parent="parent_value", + page_token="page_token_value", + filter="filter_value", + order_by="order_by_value", + ) + assert args[0] == request_msg + + +def test_list_goldengate_connections_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) # Should wrap all calls on client creation @@ -27402,7 +27663,8 @@ def test_get_cloud_vm_cluster_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.get_cloud_vm_cluster in client._transport._wrapped_methods + client._transport.list_goldengate_connections + in client._transport._wrapped_methods ) # Replace cached wrapped function with mock @@ -27410,395 +27672,550 @@ def test_get_cloud_vm_cluster_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.get_cloud_vm_cluster] = ( - mock_rpc + client._transport._wrapped_methods[ + client._transport.list_goldengate_connections + ] = mock_rpc + request = {} + client.list_goldengate_connections(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_goldengate_connections(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_list_goldengate_connections_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.list_goldengate_connections + in client._client._transport._wrapped_methods ) + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.list_goldengate_connections + ] = mock_rpc + request = {} - client.get_cloud_vm_cluster(request) + await client.list_goldengate_connections(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.get_cloud_vm_cluster(request) + await client.list_goldengate_connections(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_get_cloud_vm_cluster_rest_required_fields( - request_type=oracledatabase.GetCloudVmClusterRequest, +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + goldengate_connection.ListGoldengateConnectionsRequest(), + {}, + ], +) +async def test_list_goldengate_connections_async( + request_type, transport: str = "grpc_asyncio" ): - transport_class = transports.OracleDatabaseRestTransport - - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, ) - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_cloud_vm_cluster._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # 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 - # verify required fields with default values are now present + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connections), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_connection.ListGoldengateConnectionsResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + response = await client.list_goldengate_connections(request) - jsonified_request["name"] = "name_value" + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = goldengate_connection.ListGoldengateConnectionsRequest() + assert args[0] == request - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_cloud_vm_cluster._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListGoldengateConnectionsAsyncPager) + assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" +def test_list_goldengate_connections_field_headers(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = vm_cluster.CloudVmCluster() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - response_value = Response() - response_value.status_code = 200 + # 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 = goldengate_connection.ListGoldengateConnectionsRequest() - # Convert return value to protobuf type - return_value = vm_cluster.CloudVmCluster.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + request.parent = "parent_value" - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connections), "__call__" + ) as call: + call.return_value = goldengate_connection.ListGoldengateConnectionsResponse() + client.list_goldengate_connections(request) - response = client.get_cloud_vm_cluster(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 - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + # 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_get_cloud_vm_cluster_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials +@pytest.mark.asyncio +async def test_list_goldengate_connections_field_headers_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - unset_fields = transport.get_cloud_vm_cluster._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + # 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 = goldengate_connection.ListGoldengateConnectionsRequest() + request.parent = "parent_value" -def test_get_cloud_vm_cluster_rest_flattened(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connections), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_connection.ListGoldengateConnectionsResponse() + ) + await client.list_goldengate_connections(request) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = vm_cluster.CloudVmCluster() + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request - # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/cloudVmClusters/sample3" - } + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = vm_cluster.CloudVmCluster.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} +def test_list_goldengate_connections_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + ) - client.get_cloud_vm_cluster(**mock_args) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connections), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = goldengate_connection.ListGoldengateConnectionsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_goldengate_connections( + parent="parent_value", + ) # Establish that the underlying call was made with the expected # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/cloudVmClusters/*}" - % client.transport._host, - args[1], - ) + 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_get_cloud_vm_cluster_rest_flattened_error(transport: str = "rest"): +def test_list_goldengate_connections_flattened_error(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, ) # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.get_cloud_vm_cluster( - oracledatabase.GetCloudVmClusterRequest(), - name="name_value", + client.list_goldengate_connections( + goldengate_connection.ListGoldengateConnectionsRequest(), + parent="parent_value", ) -def test_create_cloud_vm_cluster_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) +@pytest.mark.asyncio +async def test_list_goldengate_connections_flattened_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connections), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = goldengate_connection.ListGoldengateConnectionsResponse() - # Ensure method has been cached - assert ( - client._transport.create_cloud_vm_cluster - in client._transport._wrapped_methods + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_connection.ListGoldengateConnectionsResponse() ) - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_goldengate_connections( + parent="parent_value", ) - client._transport._wrapped_methods[ - client._transport.create_cloud_vm_cluster - ] = mock_rpc - - request = {} - client.create_cloud_vm_cluster(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.create_cloud_vm_cluster(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 + # 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 -def test_create_cloud_vm_cluster_rest_required_fields( - request_type=oracledatabase.CreateCloudVmClusterRequest, -): - transport_class = transports.OracleDatabaseRestTransport - request_init = {} - request_init["parent"] = "" - request_init["cloud_vm_cluster_id"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) +@pytest.mark.asyncio +async def test_list_goldengate_connections_flattened_error_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - # verify fields with default values are dropped - assert "cloudVmClusterId" not in jsonified_request - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).create_cloud_vm_cluster._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - assert "cloudVmClusterId" in jsonified_request - assert jsonified_request["cloudVmClusterId"] == request_init["cloud_vm_cluster_id"] + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_goldengate_connections( + goldengate_connection.ListGoldengateConnectionsRequest(), + parent="parent_value", + ) - jsonified_request["parent"] = "parent_value" - jsonified_request["cloudVmClusterId"] = "cloud_vm_cluster_id_value" - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).create_cloud_vm_cluster._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "cloud_vm_cluster_id", - "request_id", - ) +def test_list_goldengate_connections_pager(transport_name: str = "grpc"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, ) - jsonified_request.update(unset_fields) - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" - assert "cloudVmClusterId" in jsonified_request - assert jsonified_request["cloudVmClusterId"] == "cloud_vm_cluster_id_value" + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connections), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + goldengate_connection.ListGoldengateConnectionsResponse( + goldengate_connections=[ + goldengate_connection.GoldengateConnection(), + goldengate_connection.GoldengateConnection(), + goldengate_connection.GoldengateConnection(), + ], + next_page_token="abc", + ), + goldengate_connection.ListGoldengateConnectionsResponse( + goldengate_connections=[], + next_page_token="def", + ), + goldengate_connection.ListGoldengateConnectionsResponse( + goldengate_connections=[ + goldengate_connection.GoldengateConnection(), + ], + next_page_token="ghi", + ), + goldengate_connection.ListGoldengateConnectionsResponse( + goldengate_connections=[ + goldengate_connection.GoldengateConnection(), + goldengate_connection.GoldengateConnection(), + ], + ), + RuntimeError, + ) + + expected_metadata = () + retry = retries.Retry() + timeout = 5 + expected_metadata = tuple(expected_metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_goldengate_connections( + request={}, retry=retry, timeout=timeout + ) + + assert pager._metadata == expected_metadata + assert pager._retry == retry + assert pager._timeout == timeout + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, goldengate_connection.GoldengateConnection) for i in results + ) + +def test_list_goldengate_connections_pages(transport_name: str = "grpc"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport=transport_name, ) - request = request_type(**request_init) - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "post", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connections), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + goldengate_connection.ListGoldengateConnectionsResponse( + goldengate_connections=[ + goldengate_connection.GoldengateConnection(), + goldengate_connection.GoldengateConnection(), + goldengate_connection.GoldengateConnection(), + ], + next_page_token="abc", + ), + goldengate_connection.ListGoldengateConnectionsResponse( + goldengate_connections=[], + next_page_token="def", + ), + goldengate_connection.ListGoldengateConnectionsResponse( + goldengate_connections=[ + goldengate_connection.GoldengateConnection(), + ], + next_page_token="ghi", + ), + goldengate_connection.ListGoldengateConnectionsResponse( + goldengate_connections=[ + goldengate_connection.GoldengateConnection(), + goldengate_connection.GoldengateConnection(), + ], + ), + RuntimeError, + ) + pages = list(client.list_goldengate_connections(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} +@pytest.mark.asyncio +async def test_list_goldengate_connections_async_pager(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) - response = client.create_cloud_vm_cluster(request) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connections), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + goldengate_connection.ListGoldengateConnectionsResponse( + goldengate_connections=[ + goldengate_connection.GoldengateConnection(), + goldengate_connection.GoldengateConnection(), + goldengate_connection.GoldengateConnection(), + ], + next_page_token="abc", + ), + goldengate_connection.ListGoldengateConnectionsResponse( + goldengate_connections=[], + next_page_token="def", + ), + goldengate_connection.ListGoldengateConnectionsResponse( + goldengate_connections=[ + goldengate_connection.GoldengateConnection(), + ], + next_page_token="ghi", + ), + goldengate_connection.ListGoldengateConnectionsResponse( + goldengate_connections=[ + goldengate_connection.GoldengateConnection(), + goldengate_connection.GoldengateConnection(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_goldengate_connections( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) - expected_params = [ - ( - "cloudVmClusterId", - "", - ), - ("$alt", "json;enum-encoding=int"), - ] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + assert len(responses) == 6 + assert all( + isinstance(i, goldengate_connection.GoldengateConnection) for i in responses + ) -def test_create_cloud_vm_cluster_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials +@pytest.mark.asyncio +async def test_list_goldengate_connections_async_pages(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - unset_fields = transport.create_cloud_vm_cluster._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "cloudVmClusterId", - "requestId", - ) - ) - & set( - ( - "parent", - "cloudVmClusterId", - "cloudVmCluster", - ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connections), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + goldengate_connection.ListGoldengateConnectionsResponse( + goldengate_connections=[ + goldengate_connection.GoldengateConnection(), + goldengate_connection.GoldengateConnection(), + goldengate_connection.GoldengateConnection(), + ], + next_page_token="abc", + ), + goldengate_connection.ListGoldengateConnectionsResponse( + goldengate_connections=[], + next_page_token="def", + ), + goldengate_connection.ListGoldengateConnectionsResponse( + goldengate_connections=[ + goldengate_connection.GoldengateConnection(), + ], + next_page_token="ghi", + ), + goldengate_connection.ListGoldengateConnectionsResponse( + goldengate_connections=[ + goldengate_connection.GoldengateConnection(), + goldengate_connection.GoldengateConnection(), + ], + ), + RuntimeError, ) - ) + pages = [] + async for page_ in (await client.list_goldengate_connections(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token -def test_create_cloud_vm_cluster_rest_flattened(): +@pytest.mark.parametrize( + "request_type", + [ + goldengate_connection.GetGoldengateConnectionRequest(), + {}, + ], +) +def test_get_goldengate_connection(request_type, transport: str = "grpc"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport=transport, ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} + # 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 - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", - cloud_vm_cluster=vm_cluster.CloudVmCluster(name="name_value"), - cloud_vm_cluster_id="cloud_vm_cluster_id_value", + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_connection), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = goldengate_connection.GoldengateConnection( + name="name_value", + gcp_oracle_zone="gcp_oracle_zone_value", + odb_network="odb_network_value", + odb_subnet="odb_subnet_value", + entitlement_id="entitlement_id_value", + oci_url="oci_url_value", ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_goldengate_connection(request) - client.create_cloud_vm_cluster(**mock_args) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = goldengate_connection.GetGoldengateConnectionRequest() + assert args[0] == request - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/cloudVmClusters" - % client.transport._host, - args[1], - ) + # Establish that the response is the type that we expect. + assert isinstance(response, goldengate_connection.GoldengateConnection) + assert response.name == "name_value" + assert response.gcp_oracle_zone == "gcp_oracle_zone_value" + assert response.odb_network == "odb_network_value" + assert response.odb_subnet == "odb_subnet_value" + assert response.entitlement_id == "entitlement_id_value" + assert response.oci_url == "oci_url_value" -def test_create_cloud_vm_cluster_rest_flattened_error(transport: str = "rest"): +def test_get_goldengate_connection_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport="grpc", ) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.create_cloud_vm_cluster( - oracledatabase.CreateCloudVmClusterRequest(), - parent="parent_value", - cloud_vm_cluster=vm_cluster.CloudVmCluster(name="name_value"), - cloud_vm_cluster_id="cloud_vm_cluster_id_value", + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = goldengate_connection.GetGoldengateConnectionRequest( + name="name_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_connection), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.get_goldengate_connection(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_connection.GetGoldengateConnectionRequest( + name="name_value", ) + assert args[0] == request_msg -def test_delete_cloud_vm_cluster_rest_use_cached_wrapped_rpc(): +def test_get_goldengate_connection_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) # Should wrap all calls on client creation @@ -27807,7 +28224,7 @@ def test_delete_cloud_vm_cluster_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.delete_cloud_vm_cluster + client._transport.get_goldengate_connection in client._transport._wrapped_methods ) @@ -27817,187 +28234,342 @@ def test_delete_cloud_vm_cluster_rest_use_cached_wrapped_rpc(): "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ - client._transport.delete_cloud_vm_cluster + client._transport.get_goldengate_connection ] = mock_rpc - request = {} - client.delete_cloud_vm_cluster(request) + client.get_goldengate_connection(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.delete_cloud_vm_cluster(request) + client.get_goldengate_connection(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_delete_cloud_vm_cluster_rest_required_fields( - request_type=oracledatabase.DeleteCloudVmClusterRequest, +@pytest.mark.asyncio +async def test_get_goldengate_connection_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", ): - transport_class = transports.OracleDatabaseRestTransport + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # verify fields with default values are dropped + # Ensure method has been cached + assert ( + client._client._transport.get_goldengate_connection + in client._client._transport._wrapped_methods + ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).delete_cloud_vm_cluster._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.get_goldengate_connection + ] = mock_rpc - # verify required fields with default values are now present + request = {} + await client.get_goldengate_connection(request) - jsonified_request["name"] = "name_value" + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).delete_cloud_vm_cluster._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "force", - "request_id", - ) + await client.get_goldengate_connection(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + goldengate_connection.GetGoldengateConnectionRequest(), + {}, + ], +) +async def test_get_goldengate_connection_async( + request_type, transport: str = "grpc_asyncio" +): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, ) - jsonified_request.update(unset_fields) - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + # 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_goldengate_connection), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_connection.GoldengateConnection( + name="name_value", + gcp_oracle_zone="gcp_oracle_zone_value", + odb_network="odb_network_value", + odb_subnet="odb_subnet_value", + entitlement_id="entitlement_id_value", + oci_url="oci_url_value", + ) + ) + response = await client.get_goldengate_connection(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = goldengate_connection.GetGoldengateConnectionRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, goldengate_connection.GoldengateConnection) + assert response.name == "name_value" + assert response.gcp_oracle_zone == "gcp_oracle_zone_value" + assert response.odb_network == "odb_network_value" + assert response.odb_subnet == "odb_subnet_value" + assert response.entitlement_id == "entitlement_id_value" + assert response.oci_url == "oci_url_value" + +def test_get_goldengate_connection_field_headers(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - request = request_type(**request_init) - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "delete", - "query_params": pb_request, - } - transcode.return_value = transcode_result + # 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 = goldengate_connection.GetGoldengateConnectionRequest() - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) + request.name = "name_value" - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_connection), "__call__" + ) as call: + call.return_value = goldengate_connection.GoldengateConnection() + client.get_goldengate_connection(request) - response = client.delete_cloud_vm_cluster(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 - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + # 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_cloud_vm_cluster_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials +@pytest.mark.asyncio +async def test_get_goldengate_connection_field_headers_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - unset_fields = transport.delete_cloud_vm_cluster._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "force", - "requestId", - ) + # 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 = goldengate_connection.GetGoldengateConnectionRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_connection), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_connection.GoldengateConnection() ) - & set(("name",)) - ) + await client.get_goldengate_connection(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_cloud_vm_cluster_rest_flattened(): +def test_get_goldengate_connection_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/cloudVmClusters/sample3" - } - - # get truthy value for each flattened field - mock_args = dict( + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_connection), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = goldengate_connection.GoldengateConnection() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_goldengate_connection( name="name_value", ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - client.delete_cloud_vm_cluster(**mock_args) # Establish that the underlying call was made with the expected # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/cloudVmClusters/*}" - % client.transport._host, - args[1], - ) + 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_cloud_vm_cluster_rest_flattened_error(transport: str = "rest"): +def test_get_goldengate_connection_flattened_error(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, ) # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.delete_cloud_vm_cluster( - oracledatabase.DeleteCloudVmClusterRequest(), + client.get_goldengate_connection( + goldengate_connection.GetGoldengateConnectionRequest(), name="name_value", ) -def test_list_entitlements_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", +@pytest.mark.asyncio +async def test_get_goldengate_connection_flattened_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_connection), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = goldengate_connection.GoldengateConnection() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_connection.GoldengateConnection() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_goldengate_connection( + 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_goldengate_connection_flattened_error_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_goldengate_connection( + goldengate_connection.GetGoldengateConnectionRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + gco_goldengate_connection.CreateGoldengateConnectionRequest(), + {}, + ], +) +def test_create_goldengate_connection(request_type, transport: str = "grpc"): + client = OracleDatabaseClient( + 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_goldengate_connection), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.create_goldengate_connection(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = gco_goldengate_connection.CreateGoldengateConnectionRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_create_goldengate_connection_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = gco_goldengate_connection.CreateGoldengateConnectionRequest( + parent="parent_value", + goldengate_connection_id="goldengate_connection_id_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_goldengate_connection), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.create_goldengate_connection(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gco_goldengate_connection.CreateGoldengateConnectionRequest( + parent="parent_value", + goldengate_connection_id="goldengate_connection_id_value", + ) + assert args[0] == request_msg + + +def test_create_goldengate_connection_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) # Should wrap all calls on client creation @@ -28005,257 +28577,376 @@ def test_list_entitlements_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.list_entitlements in client._transport._wrapped_methods + assert ( + client._transport.create_goldengate_connection + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.list_entitlements] = ( - mock_rpc - ) - + client._transport._wrapped_methods[ + client._transport.create_goldengate_connection + ] = mock_rpc request = {} - client.list_entitlements(request) + client.create_goldengate_connection(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_entitlements(request) + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.create_goldengate_connection(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_entitlements_rest_required_fields( - request_type=oracledatabase.ListEntitlementsRequest, +@pytest.mark.asyncio +async def test_create_goldengate_connection_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", ): - transport_class = transports.OracleDatabaseRestTransport + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - request_init = {} - request_init["parent"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # verify fields with default values are dropped + # Ensure method has been cached + assert ( + client._client._transport.create_goldengate_connection + in client._client._transport._wrapped_methods + ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_entitlements._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.create_goldengate_connection + ] = mock_rpc - # verify required fields with default values are now present + request = {} + await client.create_goldengate_connection(request) - jsonified_request["parent"] = "parent_value" + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_entitlements._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "page_size", - "page_token", - ) + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + await client.create_goldengate_connection(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + gco_goldengate_connection.CreateGoldengateConnectionRequest(), + {}, + ], +) +async def test_create_goldengate_connection_async( + request_type, transport: str = "grpc_asyncio" +): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, ) - jsonified_request.update(unset_fields) - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" + # 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_goldengate_connection), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + response = await client.create_goldengate_connection(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = gco_goldengate_connection.CreateGoldengateConnectionRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + +def test_create_goldengate_connection_field_headers(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListEntitlementsResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - response_value = Response() - response_value.status_code = 200 + # 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 = gco_goldengate_connection.CreateGoldengateConnectionRequest() - # Convert return value to protobuf type - return_value = oracledatabase.ListEntitlementsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + request.parent = "parent_value" - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_goldengate_connection), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_goldengate_connection(request) - response = client.list_entitlements(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 - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + # 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_entitlements_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials +@pytest.mark.asyncio +async def test_create_goldengate_connection_field_headers_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - unset_fields = transport.list_entitlements._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "pageSize", - "pageToken", - ) + # 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 = gco_goldengate_connection.CreateGoldengateConnectionRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_goldengate_connection), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") ) - & set(("parent",)) - ) + await client.create_goldengate_connection(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request -def test_list_entitlements_rest_flattened(): + # 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_goldengate_connection_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListEntitlementsResponse() + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_goldengate_connection), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_goldengate_connection( + parent="parent_value", + goldengate_connection=gco_goldengate_connection.GoldengateConnection( + name="name_value" + ), + goldengate_connection_id="goldengate_connection_id_value", + ) - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} + # 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].goldengate_connection + mock_val = gco_goldengate_connection.GoldengateConnection(name="name_value") + assert arg == mock_val + arg = args[0].goldengate_connection_id + mock_val = "goldengate_connection_id_value" + assert arg == mock_val - # get truthy value for each flattened field - mock_args = dict( + +def test_create_goldengate_connection_flattened_error(): + client = OracleDatabaseClient( + 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_goldengate_connection( + gco_goldengate_connection.CreateGoldengateConnectionRequest(), parent="parent_value", + goldengate_connection=gco_goldengate_connection.GoldengateConnection( + name="name_value" + ), + goldengate_connection_id="goldengate_connection_id_value", ) - mock_args.update(sample_request) - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = oracledatabase.ListEntitlementsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_entitlements(**mock_args) +@pytest.mark.asyncio +async def test_create_goldengate_connection_flattened_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_goldengate_connection), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_goldengate_connection( + parent="parent_value", + goldengate_connection=gco_goldengate_connection.GoldengateConnection( + name="name_value" + ), + goldengate_connection_id="goldengate_connection_id_value", + ) # Establish that the underlying call was made with the expected # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/entitlements" - % client.transport._host, - args[1], - ) + 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].goldengate_connection + mock_val = gco_goldengate_connection.GoldengateConnection(name="name_value") + assert arg == mock_val + arg = args[0].goldengate_connection_id + mock_val = "goldengate_connection_id_value" + assert arg == mock_val -def test_list_entitlements_rest_flattened_error(transport: str = "rest"): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, +@pytest.mark.asyncio +async def test_create_goldengate_connection_flattened_error_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_entitlements( - oracledatabase.ListEntitlementsRequest(), + await client.create_goldengate_connection( + gco_goldengate_connection.CreateGoldengateConnectionRequest(), parent="parent_value", + goldengate_connection=gco_goldengate_connection.GoldengateConnection( + name="name_value" + ), + goldengate_connection_id="goldengate_connection_id_value", ) -def test_list_entitlements_rest_pager(transport: str = "rest"): +@pytest.mark.parametrize( + "request_type", + [ + goldengate_connection.DeleteGoldengateConnectionRequest(), + {}, + ], +) +def test_delete_goldengate_connection(request_type, transport: str = "grpc"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - oracledatabase.ListEntitlementsResponse( - entitlements=[ - entitlement.Entitlement(), - entitlement.Entitlement(), - entitlement.Entitlement(), - ], - next_page_token="abc", - ), - oracledatabase.ListEntitlementsResponse( - entitlements=[], - next_page_token="def", - ), - oracledatabase.ListEntitlementsResponse( - entitlements=[ - entitlement.Entitlement(), - ], - next_page_token="ghi", - ), - oracledatabase.ListEntitlementsResponse( - entitlements=[ - entitlement.Entitlement(), - entitlement.Entitlement(), - ], - ), - ) - # Two responses for two calls - response = response + response + # 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 - # Wrap the values into proper Response objs - response = tuple( - oracledatabase.ListEntitlementsResponse.to_json(x) for x in response - ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_goldengate_connection), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.delete_goldengate_connection(request) - sample_request = {"parent": "projects/sample1/locations/sample2"} + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = goldengate_connection.DeleteGoldengateConnectionRequest() + assert args[0] == request - pager = client.list_entitlements(request=sample_request) + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, entitlement.Entitlement) for i in results) - pages = list(client.list_entitlements(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token +def test_delete_goldengate_connection_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = goldengate_connection.DeleteGoldengateConnectionRequest( + name="name_value", + ) -def test_list_db_servers_rest_use_cached_wrapped_rpc(): + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_goldengate_connection), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.delete_goldengate_connection(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_connection.DeleteGoldengateConnectionRequest( + name="name_value", + ) + assert args[0] == request_msg + + +def test_delete_goldengate_connection_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) # Should wrap all calls on client creation @@ -28263,259 +28954,357 @@ def test_list_db_servers_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.list_db_servers in client._transport._wrapped_methods + assert ( + client._transport.delete_goldengate_connection + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.list_db_servers] = mock_rpc - + client._transport._wrapped_methods[ + client._transport.delete_goldengate_connection + ] = mock_rpc request = {} - client.list_db_servers(request) + client.delete_goldengate_connection(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_db_servers(request) + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_goldengate_connection(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_db_servers_rest_required_fields( - request_type=oracledatabase.ListDbServersRequest, +@pytest.mark.asyncio +async def test_delete_goldengate_connection_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", ): - transport_class = transports.OracleDatabaseRestTransport + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - request_init = {} - request_init["parent"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # verify fields with default values are dropped + # Ensure method has been cached + assert ( + client._client._transport.delete_goldengate_connection + in client._client._transport._wrapped_methods + ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_db_servers._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.delete_goldengate_connection + ] = mock_rpc - # verify required fields with default values are now present + request = {} + await client.delete_goldengate_connection(request) - jsonified_request["parent"] = "parent_value" + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_db_servers._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "page_size", - "page_token", - ) + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + await client.delete_goldengate_connection(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + goldengate_connection.DeleteGoldengateConnectionRequest(), + {}, + ], +) +async def test_delete_goldengate_connection_async( + request_type, transport: str = "grpc_asyncio" +): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, ) - jsonified_request.update(unset_fields) - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" + # 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_goldengate_connection), "__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.delete_goldengate_connection(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = goldengate_connection.DeleteGoldengateConnectionRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + +def test_delete_goldengate_connection_field_headers(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListDbServersResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - response_value = Response() - response_value.status_code = 200 + # 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 = goldengate_connection.DeleteGoldengateConnectionRequest() - # Convert return value to protobuf type - return_value = oracledatabase.ListDbServersResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + request.name = "name_value" - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_goldengate_connection), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_goldengate_connection(request) - response = client.list_db_servers(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 - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + # 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_list_db_servers_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials +@pytest.mark.asyncio +async def test_delete_goldengate_connection_field_headers_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - unset_fields = transport.list_db_servers._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "pageSize", - "pageToken", - ) + # 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 = goldengate_connection.DeleteGoldengateConnectionRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_goldengate_connection), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") ) - & set(("parent",)) - ) + await client.delete_goldengate_connection(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request -def test_list_db_servers_rest_flattened(): + # 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_goldengate_connection_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListDbServersResponse() + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_goldengate_connection), "__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.delete_goldengate_connection( + name="name_value", + ) - # get arguments that satisfy an http rule for this method - sample_request = { - "parent": "projects/sample1/locations/sample2/cloudExadataInfrastructures/sample3" - } + # 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 - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", + +def test_delete_goldengate_connection_flattened_error(): + client = OracleDatabaseClient( + 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_goldengate_connection( + goldengate_connection.DeleteGoldengateConnectionRequest(), + name="name_value", ) - mock_args.update(sample_request) - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = oracledatabase.ListDbServersResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_db_servers(**mock_args) +@pytest.mark.asyncio +async def test_delete_goldengate_connection_flattened_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_goldengate_connection), "__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.delete_goldengate_connection( + name="name_value", + ) # Establish that the underlying call was made with the expected # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*/cloudExadataInfrastructures/*}/dbServers" - % client.transport._host, - args[1], - ) + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val -def test_list_db_servers_rest_flattened_error(transport: str = "rest"): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, +@pytest.mark.asyncio +async def test_delete_goldengate_connection_flattened_error_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_db_servers( - oracledatabase.ListDbServersRequest(), - parent="parent_value", + await client.delete_goldengate_connection( + goldengate_connection.DeleteGoldengateConnectionRequest(), + name="name_value", ) -def test_list_db_servers_rest_pager(transport: str = "rest"): +@pytest.mark.parametrize( + "request_type", + [ + goldengate_deployment_version.GetGoldengateDeploymentVersionRequest(), + {}, + ], +) +def test_get_goldengate_deployment_version(request_type, transport: str = "grpc"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - oracledatabase.ListDbServersResponse( - db_servers=[ - db_server.DbServer(), - db_server.DbServer(), - db_server.DbServer(), - ], - next_page_token="abc", - ), - oracledatabase.ListDbServersResponse( - db_servers=[], - next_page_token="def", - ), - oracledatabase.ListDbServersResponse( - db_servers=[ - db_server.DbServer(), - ], - next_page_token="ghi", - ), - oracledatabase.ListDbServersResponse( - db_servers=[ - db_server.DbServer(), - db_server.DbServer(), - ], - ), - ) - # Two responses for two calls - response = response + response + # 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 - # Wrap the values into proper Response objs - response = tuple( - oracledatabase.ListDbServersResponse.to_json(x) for x in response + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment_version), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = goldengate_deployment_version.GoldengateDeploymentVersion( + name="name_value", + ocid="ocid_value", ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values + response = client.get_goldengate_deployment_version(request) - sample_request = { - "parent": "projects/sample1/locations/sample2/cloudExadataInfrastructures/sample3" - } + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = goldengate_deployment_version.GetGoldengateDeploymentVersionRequest() + assert args[0] == request - pager = client.list_db_servers(request=sample_request) + # Establish that the response is the type that we expect. + assert isinstance( + response, goldengate_deployment_version.GoldengateDeploymentVersion + ) + assert response.name == "name_value" + assert response.ocid == "ocid_value" - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, db_server.DbServer) for i in results) - pages = list(client.list_db_servers(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token +def test_get_goldengate_deployment_version_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = goldengate_deployment_version.GetGoldengateDeploymentVersionRequest( + name="name_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment_version), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.get_goldengate_deployment_version(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ( + goldengate_deployment_version.GetGoldengateDeploymentVersionRequest( + name="name_value", + ) + ) + assert args[0] == request_msg -def test_list_db_nodes_rest_use_cached_wrapped_rpc(): +def test_get_goldengate_deployment_version_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) # Should wrap all calls on client creation @@ -28523,259 +29312,360 @@ def test_list_db_nodes_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.list_db_nodes in client._transport._wrapped_methods + assert ( + client._transport.get_goldengate_deployment_version + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.list_db_nodes] = mock_rpc - + client._transport._wrapped_methods[ + client._transport.get_goldengate_deployment_version + ] = mock_rpc request = {} - client.list_db_nodes(request) + client.get_goldengate_deployment_version(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_db_nodes(request) + client.get_goldengate_deployment_version(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_db_nodes_rest_required_fields( - request_type=oracledatabase.ListDbNodesRequest, +@pytest.mark.asyncio +async def test_get_goldengate_deployment_version_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", ): - transport_class = transports.OracleDatabaseRestTransport + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - request_init = {} - request_init["parent"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # verify fields with default values are dropped + # Ensure method has been cached + assert ( + client._client._transport.get_goldengate_deployment_version + in client._client._transport._wrapped_methods + ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_db_nodes._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.get_goldengate_deployment_version + ] = mock_rpc - # verify required fields with default values are now present + request = {} + await client.get_goldengate_deployment_version(request) - jsonified_request["parent"] = "parent_value" + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_db_nodes._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "page_size", - "page_token", - ) - ) - jsonified_request.update(unset_fields) + await client.get_goldengate_deployment_version(request) - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + goldengate_deployment_version.GetGoldengateDeploymentVersionRequest(), + {}, + ], +) +async def test_get_goldengate_deployment_version_async( + request_type, transport: str = "grpc_asyncio" +): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, ) - request = request_type(**request_init) - # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListDbNodesResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result + # 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 - response_value = Response() - response_value.status_code = 200 + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment_version), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_deployment_version.GoldengateDeploymentVersion( + name="name_value", + ocid="ocid_value", + ) + ) + response = await client.get_goldengate_deployment_version(request) - # Convert return value to protobuf type - return_value = oracledatabase.ListDbNodesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = goldengate_deployment_version.GetGoldengateDeploymentVersionRequest() + assert args[0] == request - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Establish that the response is the type that we expect. + assert isinstance( + response, goldengate_deployment_version.GoldengateDeploymentVersion + ) + assert response.name == "name_value" + assert response.ocid == "ocid_value" - response = client.list_db_nodes(request) - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) +def test_get_goldengate_deployment_version_field_headers(): + client = OracleDatabaseClient( + 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 = goldengate_deployment_version.GetGoldengateDeploymentVersionRequest() -def test_list_db_nodes_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment_version), "__call__" + ) as call: + call.return_value = goldengate_deployment_version.GoldengateDeploymentVersion() + client.get_goldengate_deployment_version(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_goldengate_deployment_version_field_headers_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - unset_fields = transport.list_db_nodes._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "pageSize", - "pageToken", - ) + # 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 = goldengate_deployment_version.GetGoldengateDeploymentVersionRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment_version), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_deployment_version.GoldengateDeploymentVersion() ) - & set(("parent",)) - ) + await client.get_goldengate_deployment_version(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request -def test_list_db_nodes_rest_flattened(): + # 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_goldengate_deployment_version_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListDbNodesResponse() + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment_version), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = goldengate_deployment_version.GoldengateDeploymentVersion() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_goldengate_deployment_version( + name="name_value", + ) - # get arguments that satisfy an http rule for this method - sample_request = { - "parent": "projects/sample1/locations/sample2/cloudVmClusters/sample3" - } + # 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 - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", + +def test_get_goldengate_deployment_version_flattened_error(): + client = OracleDatabaseClient( + 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_goldengate_deployment_version( + goldengate_deployment_version.GetGoldengateDeploymentVersionRequest(), + name="name_value", ) - mock_args.update(sample_request) - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = oracledatabase.ListDbNodesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_db_nodes(**mock_args) +@pytest.mark.asyncio +async def test_get_goldengate_deployment_version_flattened_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment_version), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = goldengate_deployment_version.GoldengateDeploymentVersion() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_deployment_version.GoldengateDeploymentVersion() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_goldengate_deployment_version( + name="name_value", + ) # Establish that the underlying call was made with the expected # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*/cloudVmClusters/*}/dbNodes" - % client.transport._host, - args[1], - ) + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val -def test_list_db_nodes_rest_flattened_error(transport: str = "rest"): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, +@pytest.mark.asyncio +async def test_get_goldengate_deployment_version_flattened_error_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_db_nodes( - oracledatabase.ListDbNodesRequest(), - parent="parent_value", + await client.get_goldengate_deployment_version( + goldengate_deployment_version.GetGoldengateDeploymentVersionRequest(), + name="name_value", ) -def test_list_db_nodes_rest_pager(transport: str = "rest"): +@pytest.mark.parametrize( + "request_type", + [ + goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest(), + {}, + ], +) +def test_list_goldengate_deployment_versions(request_type, transport: str = "grpc"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - oracledatabase.ListDbNodesResponse( - db_nodes=[ - db_node.DbNode(), - db_node.DbNode(), - db_node.DbNode(), - ], - next_page_token="abc", - ), - oracledatabase.ListDbNodesResponse( - db_nodes=[], - next_page_token="def", - ), - oracledatabase.ListDbNodesResponse( - db_nodes=[ - db_node.DbNode(), - ], - next_page_token="ghi", - ), - oracledatabase.ListDbNodesResponse( - db_nodes=[ - db_node.DbNode(), - db_node.DbNode(), - ], - ), + # 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_goldengate_deployment_versions), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) ) - # Two responses for two calls - response = response + response + response = client.list_goldengate_deployment_versions(request) - # Wrap the values into proper Response objs - response = tuple( - oracledatabase.ListDbNodesResponse.to_json(x) for x in response + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = ( + goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest() ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values + assert args[0] == request - sample_request = { - "parent": "projects/sample1/locations/sample2/cloudVmClusters/sample3" - } + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListGoldengateDeploymentVersionsPager) + assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] - pager = client.list_db_nodes(request=sample_request) - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, db_node.DbNode) for i in results) +def test_list_goldengate_deployment_versions_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) - pages = list(client.list_db_nodes(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest( + parent="parent_value", + page_token="page_token_value", + filter="filter_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_versions), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.list_goldengate_deployment_versions(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ( + goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest( + parent="parent_value", + page_token="page_token_value", + filter="filter_value", + ) + ) + assert args[0] == request_msg -def test_list_gi_versions_rest_use_cached_wrapped_rpc(): +def test_list_goldengate_deployment_versions_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) # Should wrap all calls on client creation @@ -28783,258 +29673,588 @@ def test_list_gi_versions_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.list_gi_versions in client._transport._wrapped_methods + assert ( + client._transport.list_goldengate_deployment_versions + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.list_gi_versions] = ( - mock_rpc - ) - + client._transport._wrapped_methods[ + client._transport.list_goldengate_deployment_versions + ] = mock_rpc request = {} - client.list_gi_versions(request) + client.list_goldengate_deployment_versions(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_gi_versions(request) + client.list_goldengate_deployment_versions(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_gi_versions_rest_required_fields( - request_type=oracledatabase.ListGiVersionsRequest, +@pytest.mark.asyncio +async def test_list_goldengate_deployment_versions_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", ): - transport_class = transports.OracleDatabaseRestTransport + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - request_init = {} - request_init["parent"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # verify fields with default values are dropped + # Ensure method has been cached + assert ( + client._client._transport.list_goldengate_deployment_versions + in client._client._transport._wrapped_methods + ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_gi_versions._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.list_goldengate_deployment_versions + ] = mock_rpc - # verify required fields with default values are now present + request = {} + await client.list_goldengate_deployment_versions(request) - jsonified_request["parent"] = "parent_value" + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_gi_versions._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "filter", - "page_size", - "page_token", - ) + await client.list_goldengate_deployment_versions(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest(), + {}, + ], +) +async def test_list_goldengate_deployment_versions_async( + request_type, transport: str = "grpc_asyncio" +): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, ) - jsonified_request.update(unset_fields) - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" + # 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_goldengate_deployment_versions), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + response = await client.list_goldengate_deployment_versions(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = ( + goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest() + ) + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListGoldengateDeploymentVersionsAsyncPager) + assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] + +def test_list_goldengate_deployment_versions_field_headers(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListGiVersionsResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - response_value = Response() - response_value.status_code = 200 + # 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 = goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest() - # Convert return value to protobuf type - return_value = oracledatabase.ListGiVersionsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + request.parent = "parent_value" - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_versions), "__call__" + ) as call: + call.return_value = ( + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse() + ) + client.list_goldengate_deployment_versions(request) - response = client.list_gi_versions(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 - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + # 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_gi_versions_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials +@pytest.mark.asyncio +async def test_list_goldengate_deployment_versions_field_headers_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - unset_fields = transport.list_gi_versions._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "filter", - "pageSize", - "pageToken", - ) + # 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 = goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_versions), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse() ) - & set(("parent",)) - ) + await client.list_goldengate_deployment_versions(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request -def test_list_gi_versions_rest_flattened(): + # 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_goldengate_deployment_versions_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListGiVersionsResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} - - # get truthy value for each flattened field - mock_args = dict( + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_versions), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_goldengate_deployment_versions( parent="parent_value", ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = oracledatabase.ListGiVersionsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - client.list_gi_versions(**mock_args) # Establish that the underlying call was made with the expected # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/giVersions" % client.transport._host, - args[1], - ) + 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_gi_versions_rest_flattened_error(transport: str = "rest"): +def test_list_goldengate_deployment_versions_flattened_error(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, ) # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_gi_versions( - oracledatabase.ListGiVersionsRequest(), + client.list_goldengate_deployment_versions( + goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest(), parent="parent_value", ) -def test_list_gi_versions_rest_pager(transport: str = "rest"): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, +@pytest.mark.asyncio +async def test_list_goldengate_deployment_versions_flattened_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - oracledatabase.ListGiVersionsResponse( - gi_versions=[ - gi_version.GiVersion(), - gi_version.GiVersion(), - gi_version.GiVersion(), + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_versions), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse() + ) + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_goldengate_deployment_versions( + 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_goldengate_deployment_versions_flattened_error_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_goldengate_deployment_versions( + goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest(), + parent="parent_value", + ) + + +def test_list_goldengate_deployment_versions_pager(transport_name: str = "grpc"): + client = OracleDatabaseClient( + 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_goldengate_deployment_versions), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse( + goldengate_deployment_versions=[ + goldengate_deployment_version.GoldengateDeploymentVersion(), + goldengate_deployment_version.GoldengateDeploymentVersion(), + goldengate_deployment_version.GoldengateDeploymentVersion(), ], next_page_token="abc", ), - oracledatabase.ListGiVersionsResponse( - gi_versions=[], + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse( + goldengate_deployment_versions=[], next_page_token="def", ), - oracledatabase.ListGiVersionsResponse( - gi_versions=[ - gi_version.GiVersion(), + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse( + goldengate_deployment_versions=[ + goldengate_deployment_version.GoldengateDeploymentVersion(), ], next_page_token="ghi", ), - oracledatabase.ListGiVersionsResponse( - gi_versions=[ - gi_version.GiVersion(), - gi_version.GiVersion(), + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse( + goldengate_deployment_versions=[ + goldengate_deployment_version.GoldengateDeploymentVersion(), + goldengate_deployment_version.GoldengateDeploymentVersion(), ], ), + RuntimeError, ) - # Two responses for two calls - response = response + response - # Wrap the values into proper Response objs - response = tuple( - oracledatabase.ListGiVersionsResponse.to_json(x) for x in response + expected_metadata = () + retry = retries.Retry() + timeout = 5 + expected_metadata = tuple(expected_metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_goldengate_deployment_versions( + request={}, retry=retry, timeout=timeout ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "projects/sample1/locations/sample2"} - pager = client.list_gi_versions(request=sample_request) + assert pager._metadata == expected_metadata + assert pager._retry == retry + assert pager._timeout == timeout results = list(pager) assert len(results) == 6 - assert all(isinstance(i, gi_version.GiVersion) for i in results) + assert all( + isinstance(i, goldengate_deployment_version.GoldengateDeploymentVersion) + for i in results + ) - pages = list(client.list_gi_versions(request=sample_request).pages) + +def test_list_goldengate_deployment_versions_pages(transport_name: str = "grpc"): + client = OracleDatabaseClient( + 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_goldengate_deployment_versions), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse( + goldengate_deployment_versions=[ + goldengate_deployment_version.GoldengateDeploymentVersion(), + goldengate_deployment_version.GoldengateDeploymentVersion(), + goldengate_deployment_version.GoldengateDeploymentVersion(), + ], + next_page_token="abc", + ), + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse( + goldengate_deployment_versions=[], + next_page_token="def", + ), + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse( + goldengate_deployment_versions=[ + goldengate_deployment_version.GoldengateDeploymentVersion(), + ], + next_page_token="ghi", + ), + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse( + goldengate_deployment_versions=[ + goldengate_deployment_version.GoldengateDeploymentVersion(), + goldengate_deployment_version.GoldengateDeploymentVersion(), + ], + ), + RuntimeError, + ) + pages = list(client.list_goldengate_deployment_versions(request={}).pages) for page_, token in zip(pages, ["abc", "def", "ghi", ""]): assert page_.raw_page.next_page_token == token -def test_list_minor_versions_rest_use_cached_wrapped_rpc(): +@pytest.mark.asyncio +async def test_list_goldengate_deployment_versions_async_pager(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_versions), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse( + goldengate_deployment_versions=[ + goldengate_deployment_version.GoldengateDeploymentVersion(), + goldengate_deployment_version.GoldengateDeploymentVersion(), + goldengate_deployment_version.GoldengateDeploymentVersion(), + ], + next_page_token="abc", + ), + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse( + goldengate_deployment_versions=[], + next_page_token="def", + ), + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse( + goldengate_deployment_versions=[ + goldengate_deployment_version.GoldengateDeploymentVersion(), + ], + next_page_token="ghi", + ), + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse( + goldengate_deployment_versions=[ + goldengate_deployment_version.GoldengateDeploymentVersion(), + goldengate_deployment_version.GoldengateDeploymentVersion(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_goldengate_deployment_versions( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all( + isinstance(i, goldengate_deployment_version.GoldengateDeploymentVersion) + for i in responses + ) + + +@pytest.mark.asyncio +async def test_list_goldengate_deployment_versions_async_pages(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_versions), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse( + goldengate_deployment_versions=[ + goldengate_deployment_version.GoldengateDeploymentVersion(), + goldengate_deployment_version.GoldengateDeploymentVersion(), + goldengate_deployment_version.GoldengateDeploymentVersion(), + ], + next_page_token="abc", + ), + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse( + goldengate_deployment_versions=[], + next_page_token="def", + ), + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse( + goldengate_deployment_versions=[ + goldengate_deployment_version.GoldengateDeploymentVersion(), + ], + next_page_token="ghi", + ), + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse( + goldengate_deployment_versions=[ + goldengate_deployment_version.GoldengateDeploymentVersion(), + goldengate_deployment_version.GoldengateDeploymentVersion(), + ], + ), + RuntimeError, + ) + pages = [] + async for page_ in ( + await client.list_goldengate_deployment_versions(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", + [ + goldengate_deployment_type.GetGoldengateDeploymentTypeRequest(), + {}, + ], +) +def test_get_goldengate_deployment_type(request_type, transport: str = "grpc"): + client = OracleDatabaseClient( + 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_goldengate_deployment_type), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = goldengate_deployment_type.GoldengateDeploymentType( + name="name_value", + deployment_type=goldengate_deployment_type.GoldengateDeploymentType.DeploymentType.OGG, + category=goldengate_deployment_type.GoldengateDeploymentType.DeploymentCategory.DATA_REPLICATION_CATEGORY, + connection_types=["connection_types_value"], + display_name="display_name_value", + ogg_version="ogg_version_value", + source_technologies=["source_technologies_value"], + supported_capabilities=["supported_capabilities_value"], + supported_technologies_url="supported_technologies_url_value", + target_technologies=["target_technologies_value"], + default_username="default_username_value", + ) + response = client.get_goldengate_deployment_type(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = goldengate_deployment_type.GetGoldengateDeploymentTypeRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, goldengate_deployment_type.GoldengateDeploymentType) + assert response.name == "name_value" + assert ( + response.deployment_type + == goldengate_deployment_type.GoldengateDeploymentType.DeploymentType.OGG + ) + assert ( + response.category + == goldengate_deployment_type.GoldengateDeploymentType.DeploymentCategory.DATA_REPLICATION_CATEGORY + ) + assert response.connection_types == ["connection_types_value"] + assert response.display_name == "display_name_value" + assert response.ogg_version == "ogg_version_value" + assert response.source_technologies == ["source_technologies_value"] + assert response.supported_capabilities == ["supported_capabilities_value"] + assert response.supported_technologies_url == "supported_technologies_url_value" + assert response.target_technologies == ["target_technologies_value"] + assert response.default_username == "default_username_value" + + +def test_get_goldengate_deployment_type_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = goldengate_deployment_type.GetGoldengateDeploymentTypeRequest( + name="name_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment_type), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.get_goldengate_deployment_type(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment_type.GetGoldengateDeploymentTypeRequest( + name="name_value", + ) + assert args[0] == request_msg + + +def test_get_goldengate_deployment_type_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) # Should wrap all calls on client creation @@ -29043,7 +30263,8 @@ def test_list_minor_versions_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.list_minor_versions in client._transport._wrapped_methods + client._transport.get_goldengate_deployment_type + in client._transport._wrapped_methods ) # Replace cached wrapped function with mock @@ -29051,256 +30272,370 @@ def test_list_minor_versions_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.list_minor_versions] = ( - mock_rpc - ) - + client._transport._wrapped_methods[ + client._transport.get_goldengate_deployment_type + ] = mock_rpc request = {} - client.list_minor_versions(request) + client.get_goldengate_deployment_type(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_minor_versions(request) + client.get_goldengate_deployment_type(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_minor_versions_rest_required_fields( - request_type=minor_version.ListMinorVersionsRequest, +@pytest.mark.asyncio +async def test_get_goldengate_deployment_type_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", ): - transport_class = transports.OracleDatabaseRestTransport + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - request_init = {} - request_init["parent"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # verify fields with default values are dropped + # Ensure method has been cached + assert ( + client._client._transport.get_goldengate_deployment_type + in client._client._transport._wrapped_methods + ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_minor_versions._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.get_goldengate_deployment_type + ] = mock_rpc - # verify required fields with default values are now present + request = {} + await client.get_goldengate_deployment_type(request) - jsonified_request["parent"] = "parent_value" + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_minor_versions._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "filter", - "page_size", - "page_token", + await client.get_goldengate_deployment_type(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + goldengate_deployment_type.GetGoldengateDeploymentTypeRequest(), + {}, + ], +) +async def test_get_goldengate_deployment_type_async( + request_type, transport: str = "grpc_asyncio" +): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + 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_goldengate_deployment_type), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_deployment_type.GoldengateDeploymentType( + name="name_value", + deployment_type=goldengate_deployment_type.GoldengateDeploymentType.DeploymentType.OGG, + category=goldengate_deployment_type.GoldengateDeploymentType.DeploymentCategory.DATA_REPLICATION_CATEGORY, + connection_types=["connection_types_value"], + display_name="display_name_value", + ogg_version="ogg_version_value", + source_technologies=["source_technologies_value"], + supported_capabilities=["supported_capabilities_value"], + supported_technologies_url="supported_technologies_url_value", + target_technologies=["target_technologies_value"], + default_username="default_username_value", + ) ) + response = await client.get_goldengate_deployment_type(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = goldengate_deployment_type.GetGoldengateDeploymentTypeRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, goldengate_deployment_type.GoldengateDeploymentType) + assert response.name == "name_value" + assert ( + response.deployment_type + == goldengate_deployment_type.GoldengateDeploymentType.DeploymentType.OGG ) - jsonified_request.update(unset_fields) + assert ( + response.category + == goldengate_deployment_type.GoldengateDeploymentType.DeploymentCategory.DATA_REPLICATION_CATEGORY + ) + assert response.connection_types == ["connection_types_value"] + assert response.display_name == "display_name_value" + assert response.ogg_version == "ogg_version_value" + assert response.source_technologies == ["source_technologies_value"] + assert response.supported_capabilities == ["supported_capabilities_value"] + assert response.supported_technologies_url == "supported_technologies_url_value" + assert response.target_technologies == ["target_technologies_value"] + assert response.default_username == "default_username_value" - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" +def test_get_goldengate_deployment_type_field_headers(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - request = request_type(**request_init) - # Designate an appropriate value for the returned response. - return_value = minor_version.ListMinorVersionsResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 + # 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 = goldengate_deployment_type.GetGoldengateDeploymentTypeRequest() - # Convert return value to protobuf type - return_value = minor_version.ListMinorVersionsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + request.name = "name_value" - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment_type), "__call__" + ) as call: + call.return_value = goldengate_deployment_type.GoldengateDeploymentType() + client.get_goldengate_deployment_type(request) - response = client.list_minor_versions(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 - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + # 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_list_minor_versions_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials +@pytest.mark.asyncio +async def test_get_goldengate_deployment_type_field_headers_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - unset_fields = transport.list_minor_versions._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "filter", - "pageSize", - "pageToken", - ) + # 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 = goldengate_deployment_type.GetGoldengateDeploymentTypeRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment_type), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_deployment_type.GoldengateDeploymentType() ) - & set(("parent",)) - ) + await client.get_goldengate_deployment_type(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request -def test_list_minor_versions_rest_flattened(): + # 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_goldengate_deployment_type_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = minor_version.ListMinorVersionsResponse() - - # get arguments that satisfy an http rule for this method - sample_request = { - "parent": "projects/sample1/locations/sample2/giVersions/sample3" - } - - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment_type), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = goldengate_deployment_type.GoldengateDeploymentType() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_goldengate_deployment_type( + name="name_value", ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = minor_version.ListMinorVersionsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - client.list_minor_versions(**mock_args) # Establish that the underlying call was made with the expected # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*/giVersions/*}/minorVersions" - % client.transport._host, - args[1], - ) + 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_list_minor_versions_rest_flattened_error(transport: str = "rest"): +def test_get_goldengate_deployment_type_flattened_error(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, ) # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_minor_versions( - minor_version.ListMinorVersionsRequest(), - parent="parent_value", + client.get_goldengate_deployment_type( + goldengate_deployment_type.GetGoldengateDeploymentTypeRequest(), + name="name_value", ) -def test_list_minor_versions_rest_pager(transport: str = "rest"): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, +@pytest.mark.asyncio +async def test_get_goldengate_deployment_type_flattened_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - minor_version.ListMinorVersionsResponse( - minor_versions=[ - minor_version.MinorVersion(), - minor_version.MinorVersion(), - minor_version.MinorVersion(), - ], - next_page_token="abc", - ), - minor_version.ListMinorVersionsResponse( - minor_versions=[], - next_page_token="def", - ), - minor_version.ListMinorVersionsResponse( - minor_versions=[ - minor_version.MinorVersion(), - ], - next_page_token="ghi", - ), - minor_version.ListMinorVersionsResponse( - minor_versions=[ - minor_version.MinorVersion(), - minor_version.MinorVersion(), - ], - ), + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment_type), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = goldengate_deployment_type.GoldengateDeploymentType() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_deployment_type.GoldengateDeploymentType() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_goldengate_deployment_type( + name="name_value", ) - # Two responses for two calls - response = response + response - # Wrap the values into proper Response objs - response = tuple( - minor_version.ListMinorVersionsResponse.to_json(x) for x in response + # 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_goldengate_deployment_type_flattened_error_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_goldengate_deployment_type( + goldengate_deployment_type.GetGoldengateDeploymentTypeRequest(), + name="name_value", ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - sample_request = { - "parent": "projects/sample1/locations/sample2/giVersions/sample3" - } - pager = client.list_minor_versions(request=sample_request) +@pytest.mark.parametrize( + "request_type", + [ + goldengate_deployment_type.ListGoldengateDeploymentTypesRequest(), + {}, + ], +) +def test_list_goldengate_deployment_types(request_type, transport: str = "grpc"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, minor_version.MinorVersion) for i in results) + # 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 - pages = list(client.list_minor_versions(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_types), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + response = client.list_goldengate_deployment_types(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = goldengate_deployment_type.ListGoldengateDeploymentTypesRequest() + assert args[0] == request -def test_list_db_system_shapes_rest_use_cached_wrapped_rpc(): + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListGoldengateDeploymentTypesPager) + assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] + + +def test_list_goldengate_deployment_types_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = goldengate_deployment_type.ListGoldengateDeploymentTypesRequest( + parent="parent_value", + page_token="page_token_value", + filter="filter_value", + order_by="order_by_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_types), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.list_goldengate_deployment_types(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment_type.ListGoldengateDeploymentTypesRequest( + parent="parent_value", + page_token="page_token_value", + filter="filter_value", + order_by="order_by_value", + ) + assert args[0] == request_msg + + +def test_list_goldengate_deployment_types_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) # Should wrap all calls on client creation @@ -29309,7 +30644,7 @@ def test_list_db_system_shapes_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.list_db_system_shapes + client._transport.list_goldengate_deployment_types in client._transport._wrapped_methods ) @@ -29318,521 +30653,582 @@ def test_list_db_system_shapes_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.list_db_system_shapes] = ( - mock_rpc - ) - + client._transport._wrapped_methods[ + client._transport.list_goldengate_deployment_types + ] = mock_rpc request = {} - client.list_db_system_shapes(request) + client.list_goldengate_deployment_types(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_db_system_shapes(request) + client.list_goldengate_deployment_types(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_db_system_shapes_rest_required_fields( - request_type=oracledatabase.ListDbSystemShapesRequest, +@pytest.mark.asyncio +async def test_list_goldengate_deployment_types_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", ): - transport_class = transports.OracleDatabaseRestTransport + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - request_init = {} - request_init["parent"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # verify fields with default values are dropped + # Ensure method has been cached + assert ( + client._client._transport.list_goldengate_deployment_types + in client._client._transport._wrapped_methods + ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_db_system_shapes._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.list_goldengate_deployment_types + ] = mock_rpc - # verify required fields with default values are now present + request = {} + await client.list_goldengate_deployment_types(request) - jsonified_request["parent"] = "parent_value" + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_db_system_shapes._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "filter", - "page_size", - "page_token", - ) + await client.list_goldengate_deployment_types(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + goldengate_deployment_type.ListGoldengateDeploymentTypesRequest(), + {}, + ], +) +async def test_list_goldengate_deployment_types_async( + request_type, transport: str = "grpc_asyncio" +): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, ) - jsonified_request.update(unset_fields) - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" + # 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_goldengate_deployment_types), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + response = await client.list_goldengate_deployment_types(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = goldengate_deployment_type.ListGoldengateDeploymentTypesRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListGoldengateDeploymentTypesAsyncPager) + assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] + +def test_list_goldengate_deployment_types_field_headers(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListDbSystemShapesResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - response_value = Response() - response_value.status_code = 200 + # 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 = goldengate_deployment_type.ListGoldengateDeploymentTypesRequest() - # Convert return value to protobuf type - return_value = oracledatabase.ListDbSystemShapesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + request.parent = "parent_value" - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_types), "__call__" + ) as call: + call.return_value = ( + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse() + ) + client.list_goldengate_deployment_types(request) - response = client.list_db_system_shapes(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 - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + # 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_db_system_shapes_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials +@pytest.mark.asyncio +async def test_list_goldengate_deployment_types_field_headers_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - unset_fields = transport.list_db_system_shapes._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "filter", - "pageSize", - "pageToken", - ) + # 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 = goldengate_deployment_type.ListGoldengateDeploymentTypesRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_types), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse() ) - & set(("parent",)) - ) + await client.list_goldengate_deployment_types(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request -def test_list_db_system_shapes_rest_flattened(): + # 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_goldengate_deployment_types_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListDbSystemShapesResponse() + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_types), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_goldengate_deployment_types( + parent="parent_value", + ) - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} + # 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 - # get truthy value for each flattened field - mock_args = dict( + +def test_list_goldengate_deployment_types_flattened_error(): + client = OracleDatabaseClient( + 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_goldengate_deployment_types( + goldengate_deployment_type.ListGoldengateDeploymentTypesRequest(), parent="parent_value", ) - mock_args.update(sample_request) - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = oracledatabase.ListDbSystemShapesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_db_system_shapes(**mock_args) +@pytest.mark.asyncio +async def test_list_goldengate_deployment_types_flattened_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_types), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse() + ) + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_goldengate_deployment_types( + parent="parent_value", + ) # Establish that the underlying call was made with the expected # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/dbSystemShapes" - % client.transport._host, - args[1], - ) + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val -def test_list_db_system_shapes_rest_flattened_error(transport: str = "rest"): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, +@pytest.mark.asyncio +async def test_list_goldengate_deployment_types_flattened_error_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_db_system_shapes( - oracledatabase.ListDbSystemShapesRequest(), + await client.list_goldengate_deployment_types( + goldengate_deployment_type.ListGoldengateDeploymentTypesRequest(), parent="parent_value", ) -def test_list_db_system_shapes_rest_pager(transport: str = "rest"): +def test_list_goldengate_deployment_types_pager(transport_name: str = "grpc"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport=transport_name, ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - oracledatabase.ListDbSystemShapesResponse( - db_system_shapes=[ - db_system_shape.DbSystemShape(), - db_system_shape.DbSystemShape(), - db_system_shape.DbSystemShape(), + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_types), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse( + goldengate_deployment_types=[ + goldengate_deployment_type.GoldengateDeploymentType(), + goldengate_deployment_type.GoldengateDeploymentType(), + goldengate_deployment_type.GoldengateDeploymentType(), ], next_page_token="abc", ), - oracledatabase.ListDbSystemShapesResponse( - db_system_shapes=[], + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse( + goldengate_deployment_types=[], next_page_token="def", ), - oracledatabase.ListDbSystemShapesResponse( - db_system_shapes=[ - db_system_shape.DbSystemShape(), + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse( + goldengate_deployment_types=[ + goldengate_deployment_type.GoldengateDeploymentType(), ], next_page_token="ghi", ), - oracledatabase.ListDbSystemShapesResponse( - db_system_shapes=[ - db_system_shape.DbSystemShape(), - db_system_shape.DbSystemShape(), + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse( + goldengate_deployment_types=[ + goldengate_deployment_type.GoldengateDeploymentType(), + goldengate_deployment_type.GoldengateDeploymentType(), ], ), + RuntimeError, ) - # Two responses for two calls - response = response + response - # Wrap the values into proper Response objs - response = tuple( - oracledatabase.ListDbSystemShapesResponse.to_json(x) for x in response + expected_metadata = () + retry = retries.Retry() + timeout = 5 + expected_metadata = tuple(expected_metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_goldengate_deployment_types( + request={}, retry=retry, timeout=timeout ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "projects/sample1/locations/sample2"} - pager = client.list_db_system_shapes(request=sample_request) + assert pager._metadata == expected_metadata + assert pager._retry == retry + assert pager._timeout == timeout results = list(pager) assert len(results) == 6 - assert all(isinstance(i, db_system_shape.DbSystemShape) for i in results) - - pages = list(client.list_db_system_shapes(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token - - -def test_list_autonomous_databases_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + assert all( + isinstance(i, goldengate_deployment_type.GoldengateDeploymentType) + for i in results ) - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - # Ensure method has been cached - assert ( - client._transport.list_autonomous_databases - in client._transport._wrapped_methods - ) +def test_list_goldengate_deployment_types_pages(transport_name: str = "grpc"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_types), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse( + goldengate_deployment_types=[ + goldengate_deployment_type.GoldengateDeploymentType(), + goldengate_deployment_type.GoldengateDeploymentType(), + goldengate_deployment_type.GoldengateDeploymentType(), + ], + next_page_token="abc", + ), + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse( + goldengate_deployment_types=[], + next_page_token="def", + ), + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse( + goldengate_deployment_types=[ + goldengate_deployment_type.GoldengateDeploymentType(), + ], + next_page_token="ghi", + ), + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse( + goldengate_deployment_types=[ + goldengate_deployment_type.GoldengateDeploymentType(), + goldengate_deployment_type.GoldengateDeploymentType(), + ], + ), + RuntimeError, ) - client._transport._wrapped_methods[ - client._transport.list_autonomous_databases - ] = mock_rpc + pages = list(client.list_goldengate_deployment_types(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token - request = {} - client.list_autonomous_databases(request) - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.list_autonomous_databases(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_list_autonomous_databases_rest_required_fields( - request_type=oracledatabase.ListAutonomousDatabasesRequest, -): - transport_class = transports.OracleDatabaseRestTransport - - request_init = {} - request_init["parent"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) +@pytest.mark.asyncio +async def test_list_goldengate_deployment_types_async_pager(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_autonomous_databases._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["parent"] = "parent_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_autonomous_databases._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "filter", - "order_by", - "page_size", - "page_token", + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_types), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse( + goldengate_deployment_types=[ + goldengate_deployment_type.GoldengateDeploymentType(), + goldengate_deployment_type.GoldengateDeploymentType(), + goldengate_deployment_type.GoldengateDeploymentType(), + ], + next_page_token="abc", + ), + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse( + goldengate_deployment_types=[], + next_page_token="def", + ), + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse( + goldengate_deployment_types=[ + goldengate_deployment_type.GoldengateDeploymentType(), + ], + next_page_token="ghi", + ), + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse( + goldengate_deployment_types=[ + goldengate_deployment_type.GoldengateDeploymentType(), + goldengate_deployment_type.GoldengateDeploymentType(), + ], + ), + RuntimeError, ) - ) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" - - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListAutonomousDatabasesResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = oracledatabase.ListAutonomousDatabasesResponse.pb( - return_value - ) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - response = client.list_autonomous_databases(request) + async_pager = await client.list_goldengate_deployment_types( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + assert len(responses) == 6 + assert all( + isinstance(i, goldengate_deployment_type.GoldengateDeploymentType) + for i in responses + ) -def test_list_autonomous_databases_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials +@pytest.mark.asyncio +async def test_list_goldengate_deployment_types_async_pages(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - unset_fields = transport.list_autonomous_databases._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "filter", - "orderBy", - "pageSize", - "pageToken", - ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_types), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse( + goldengate_deployment_types=[ + goldengate_deployment_type.GoldengateDeploymentType(), + goldengate_deployment_type.GoldengateDeploymentType(), + goldengate_deployment_type.GoldengateDeploymentType(), + ], + next_page_token="abc", + ), + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse( + goldengate_deployment_types=[], + next_page_token="def", + ), + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse( + goldengate_deployment_types=[ + goldengate_deployment_type.GoldengateDeploymentType(), + ], + next_page_token="ghi", + ), + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse( + goldengate_deployment_types=[ + goldengate_deployment_type.GoldengateDeploymentType(), + goldengate_deployment_type.GoldengateDeploymentType(), + ], + ), + RuntimeError, ) - & set(("parent",)) - ) + pages = [] + async for page_ in ( + await client.list_goldengate_deployment_types(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token -def test_list_autonomous_databases_rest_flattened(): +@pytest.mark.parametrize( + "request_type", + [ + goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest(), + {}, + ], +) +def test_get_goldengate_deployment_environment(request_type, transport: str = "grpc"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport=transport, ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListAutonomousDatabasesResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} - - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = oracledatabase.ListAutonomousDatabasesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - client.list_autonomous_databases(**mock_args) + # 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 - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/autonomousDatabases" - % client.transport._host, - args[1], + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment_environment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = goldengate_deployment_environment.GoldengateDeploymentEnvironment( + name="name_value", + category=goldengate_deployment_environment.GoldengateDeploymentEnvironment.DeploymentCategory.DATA_REPLICATION_CATEGORY, + display_name="display_name_value", + default_cpu_core_count=2332, + environment_type=goldengate_deployment_environment.GoldengateDeploymentEnvironment.DeploymentEnvironmentType.PRODUCTION, + auto_scaling_enabled=True, + max_cpu_core_count=1917, + memory_gb_per_cpu_core=2326, + min_cpu_core_count=1915, + network_bandwidth_gbps_per_cpu_core=3710, + storage_usage_limit_gb_per_cpu_core=3684, ) + response = client.get_goldengate_deployment_environment(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest() + assert args[0] == request -def test_list_autonomous_databases_rest_flattened_error(transport: str = "rest"): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + # Establish that the response is the type that we expect. + assert isinstance( + response, goldengate_deployment_environment.GoldengateDeploymentEnvironment ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.list_autonomous_databases( - oracledatabase.ListAutonomousDatabasesRequest(), - parent="parent_value", - ) + assert response.name == "name_value" + assert ( + response.category + == goldengate_deployment_environment.GoldengateDeploymentEnvironment.DeploymentCategory.DATA_REPLICATION_CATEGORY + ) + assert response.display_name == "display_name_value" + assert response.default_cpu_core_count == 2332 + assert ( + response.environment_type + == goldengate_deployment_environment.GoldengateDeploymentEnvironment.DeploymentEnvironmentType.PRODUCTION + ) + assert response.auto_scaling_enabled is True + assert response.max_cpu_core_count == 1917 + assert response.memory_gb_per_cpu_core == 2326 + assert response.min_cpu_core_count == 1915 + assert response.network_bandwidth_gbps_per_cpu_core == 3710 + assert response.storage_usage_limit_gb_per_cpu_core == 3684 -def test_list_autonomous_databases_rest_pager(transport: str = "rest"): +def test_get_goldengate_deployment_environment_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport="grpc", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - oracledatabase.ListAutonomousDatabasesResponse( - autonomous_databases=[ - autonomous_database.AutonomousDatabase(), - autonomous_database.AutonomousDatabase(), - autonomous_database.AutonomousDatabase(), - ], - next_page_token="abc", - ), - oracledatabase.ListAutonomousDatabasesResponse( - autonomous_databases=[], - next_page_token="def", - ), - oracledatabase.ListAutonomousDatabasesResponse( - autonomous_databases=[ - autonomous_database.AutonomousDatabase(), - ], - next_page_token="ghi", - ), - oracledatabase.ListAutonomousDatabasesResponse( - autonomous_databases=[ - autonomous_database.AutonomousDatabase(), - autonomous_database.AutonomousDatabase(), - ], - ), + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = ( + goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest( + name="name_value", ) - # Two responses for two calls - response = response + response + ) - # Wrap the values into proper Response objs - response = tuple( - oracledatabase.ListAutonomousDatabasesResponse.to_json(x) for x in response + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment_environment), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "projects/sample1/locations/sample2"} - - pager = client.list_autonomous_databases(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all( - isinstance(i, autonomous_database.AutonomousDatabase) for i in results + client.get_goldengate_deployment_environment(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ( + goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest( + name="name_value", + ) ) - - pages = list(client.list_autonomous_databases(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + assert args[0] == request_msg -def test_get_autonomous_database_rest_use_cached_wrapped_rpc(): +def test_get_goldengate_deployment_environment_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) # Should wrap all calls on client creation @@ -29841,7 +31237,7 @@ def test_get_autonomous_database_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.get_autonomous_database + client._transport.get_goldengate_deployment_environment in client._transport._wrapped_methods ) @@ -29851,401 +31247,377 @@ def test_get_autonomous_database_rest_use_cached_wrapped_rpc(): "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ - client._transport.get_autonomous_database + client._transport.get_goldengate_deployment_environment ] = mock_rpc - request = {} - client.get_autonomous_database(request) + client.get_goldengate_deployment_environment(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.get_autonomous_database(request) + client.get_goldengate_deployment_environment(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_get_autonomous_database_rest_required_fields( - request_type=oracledatabase.GetAutonomousDatabaseRequest, +@pytest.mark.asyncio +async def test_get_goldengate_deployment_environment_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", ): - transport_class = transports.OracleDatabaseRestTransport - - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_autonomous_database._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - # verify required fields with default values are now present + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - jsonified_request["name"] = "name_value" + # Ensure method has been cached + assert ( + client._client._transport.get_goldengate_deployment_environment + in client._client._transport._wrapped_methods + ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_autonomous_database._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.get_goldengate_deployment_environment + ] = mock_rpc - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + request = {} + await client.get_goldengate_deployment_environment(request) - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - # Designate an appropriate value for the returned response. - return_value = autonomous_database.AutonomousDatabase() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result + await client.get_goldengate_deployment_environment(request) - response_value = Response() - response_value.status_code = 200 + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 - # Convert return value to protobuf type - return_value = autonomous_database.AutonomousDatabase.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest(), + {}, + ], +) +async def test_get_goldengate_deployment_environment_async( + request_type, transport: str = "grpc_asyncio" +): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - response = client.get_autonomous_database(request) + # 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 - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment_environment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_deployment_environment.GoldengateDeploymentEnvironment( + name="name_value", + category=goldengate_deployment_environment.GoldengateDeploymentEnvironment.DeploymentCategory.DATA_REPLICATION_CATEGORY, + display_name="display_name_value", + default_cpu_core_count=2332, + environment_type=goldengate_deployment_environment.GoldengateDeploymentEnvironment.DeploymentEnvironmentType.PRODUCTION, + auto_scaling_enabled=True, + max_cpu_core_count=1917, + memory_gb_per_cpu_core=2326, + min_cpu_core_count=1915, + network_bandwidth_gbps_per_cpu_core=3710, + storage_usage_limit_gb_per_cpu_core=3684, + ) + ) + response = await client.get_goldengate_deployment_environment(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest() + assert args[0] == request -def test_get_autonomous_database_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials + # Establish that the response is the type that we expect. + assert isinstance( + response, goldengate_deployment_environment.GoldengateDeploymentEnvironment ) - - unset_fields = transport.get_autonomous_database._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + assert response.name == "name_value" + assert ( + response.category + == goldengate_deployment_environment.GoldengateDeploymentEnvironment.DeploymentCategory.DATA_REPLICATION_CATEGORY + ) + assert response.display_name == "display_name_value" + assert response.default_cpu_core_count == 2332 + assert ( + response.environment_type + == goldengate_deployment_environment.GoldengateDeploymentEnvironment.DeploymentEnvironmentType.PRODUCTION + ) + assert response.auto_scaling_enabled is True + assert response.max_cpu_core_count == 1917 + assert response.memory_gb_per_cpu_core == 2326 + assert response.min_cpu_core_count == 1915 + assert response.network_bandwidth_gbps_per_cpu_core == 3710 + assert response.storage_usage_limit_gb_per_cpu_core == 3684 -def test_get_autonomous_database_rest_flattened(): +def test_get_goldengate_deployment_environment_field_headers(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = autonomous_database.AutonomousDatabase() + # 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 = ( + goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest() + ) - # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" - } + request.name = "name_value" - # get truthy value for each flattened field - mock_args = dict( - name="name_value", + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment_environment), "__call__" + ) as call: + call.return_value = ( + goldengate_deployment_environment.GoldengateDeploymentEnvironment() ) - mock_args.update(sample_request) + client.get_goldengate_deployment_environment(request) - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = autonomous_database.AutonomousDatabase.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request - client.get_autonomous_database(**mock_args) + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/autonomousDatabases/*}" - % client.transport._host, - args[1], - ) +@pytest.mark.asyncio +async def test_get_goldengate_deployment_environment_field_headers_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) -def test_get_autonomous_database_rest_flattened_error(transport: str = "rest"): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + # 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 = ( + goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest() ) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.get_autonomous_database( - oracledatabase.GetAutonomousDatabaseRequest(), - name="name_value", - ) - - -def test_create_autonomous_database_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert ( - client._transport.create_autonomous_database - in client._transport._wrapped_methods - ) + request.name = "name_value" - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment_environment), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_deployment_environment.GoldengateDeploymentEnvironment() ) - client._transport._wrapped_methods[ - client._transport.create_autonomous_database - ] = mock_rpc - - request = {} - client.create_autonomous_database(request) + await client.get_goldengate_deployment_environment(request) # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.create_autonomous_database(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_create_autonomous_database_rest_required_fields( - request_type=oracledatabase.CreateAutonomousDatabaseRequest, -): - transport_class = transports.OracleDatabaseRestTransport - - request_init = {} - request_init["parent"] = "" - request_init["autonomous_database_id"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request - # verify fields with default values are dropped - assert "autonomousDatabaseId" not in jsonified_request + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).create_autonomous_database._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - # verify required fields with default values are now present - assert "autonomousDatabaseId" in jsonified_request - assert ( - jsonified_request["autonomousDatabaseId"] - == request_init["autonomous_database_id"] +def test_get_goldengate_deployment_environment_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), ) - jsonified_request["parent"] = "parent_value" - jsonified_request["autonomousDatabaseId"] = "autonomous_database_id_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).create_autonomous_database._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "autonomous_database_id", - "request_id", + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment_environment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + goldengate_deployment_environment.GoldengateDeploymentEnvironment() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_goldengate_deployment_environment( + name="name_value", ) - ) - jsonified_request.update(unset_fields) - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" - assert "autonomousDatabaseId" in jsonified_request - assert jsonified_request["autonomousDatabaseId"] == "autonomous_database_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].name + mock_val = "name_value" + assert arg == mock_val + +def test_get_goldengate_deployment_environment_flattened_error(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - request = request_type(**request_init) - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "post", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_goldengate_deployment_environment( + goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest(), + name="name_value", + ) - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} +@pytest.mark.asyncio +async def test_get_goldengate_deployment_environment_flattened_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) - response = client.create_autonomous_database(request) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment_environment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + goldengate_deployment_environment.GoldengateDeploymentEnvironment() + ) - expected_params = [ - ( - "autonomousDatabaseId", - "", - ), - ("$alt", "json;enum-encoding=int"), - ] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_deployment_environment.GoldengateDeploymentEnvironment() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_goldengate_deployment_environment( + 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 -def test_create_autonomous_database_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials +@pytest.mark.asyncio +async def test_get_goldengate_deployment_environment_flattened_error_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - unset_fields = transport.create_autonomous_database._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "autonomousDatabaseId", - "requestId", - ) - ) - & set( - ( - "parent", - "autonomousDatabaseId", - "autonomousDatabase", - ) + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_goldengate_deployment_environment( + goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest(), + name="name_value", ) - ) -def test_create_autonomous_database_rest_flattened(): +@pytest.mark.parametrize( + "request_type", + [ + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest(), + {}, + ], +) +def test_list_goldengate_deployment_environments(request_type, transport: str = "grpc"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport=transport, ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} + # 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 - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", - autonomous_database=gco_autonomous_database.AutonomousDatabase( - name="name_value" - ), - autonomous_database_id="autonomous_database_id_value", + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_environments), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_goldengate_deployment_environments(request) - client.create_autonomous_database(**mock_args) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest() + assert args[0] == request - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/autonomousDatabases" - % client.transport._host, - args[1], - ) + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListGoldengateDeploymentEnvironmentsPager) + assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] -def test_create_autonomous_database_rest_flattened_error(transport: str = "rest"): +def test_list_goldengate_deployment_environments_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport="grpc", ) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.create_autonomous_database( - oracledatabase.CreateAutonomousDatabaseRequest(), + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = ( + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest( parent="parent_value", - autonomous_database=gco_autonomous_database.AutonomousDatabase( - name="name_value" - ), - autonomous_database_id="autonomous_database_id_value", + page_token="page_token_value", + ) + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_environments), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.list_goldengate_deployment_environments(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest( + parent="parent_value", + page_token="page_token_value", ) + assert args[0] == request_msg -def test_update_autonomous_database_rest_use_cached_wrapped_rpc(): +def test_list_goldengate_deployment_environments_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) # Should wrap all calls on client creation @@ -30254,7 +31626,7 @@ def test_update_autonomous_database_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.update_autonomous_database + client._transport.list_goldengate_deployment_environments in client._transport._wrapped_methods ) @@ -30264,377 +31636,558 @@ def test_update_autonomous_database_rest_use_cached_wrapped_rpc(): "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ - client._transport.update_autonomous_database + client._transport.list_goldengate_deployment_environments ] = mock_rpc - request = {} - client.update_autonomous_database(request) + client.list_goldengate_deployment_environments(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.update_autonomous_database(request) + client.list_goldengate_deployment_environments(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_update_autonomous_database_rest_required_fields( - request_type=oracledatabase.UpdateAutonomousDatabaseRequest, +@pytest.mark.asyncio +async def test_list_goldengate_deployment_environments_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", ): - transport_class = transports.OracleDatabaseRestTransport - - request_init = {} - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).update_autonomous_database._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).update_autonomous_database._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "request_id", - "update_mask", + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, ) - ) - jsonified_request.update(unset_fields) - # verify required fields with non-default values are left alone + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) + # Ensure method has been cached + assert ( + client._client._transport.list_goldengate_deployment_environments + in client._client._transport._wrapped_methods + ) - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "patch", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.list_goldengate_deployment_environments + ] = mock_rpc - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) + request = {} + await client.list_goldengate_deployment_environments(request) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - response = client.update_autonomous_database(request) + await client.list_goldengate_deployment_environments(request) - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 -def test_update_autonomous_database_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest(), + {}, + ], +) +async def test_list_goldengate_deployment_environments_async( + request_type, transport: str = "grpc_asyncio" +): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, ) - unset_fields = transport.update_autonomous_database._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "requestId", - "updateMask", + # 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_goldengate_deployment_environments), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], ) ) - & set(("autonomousDatabase",)) - ) + response = await client.list_goldengate_deployment_environments(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest() + assert args[0] == request + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListGoldengateDeploymentEnvironmentsAsyncPager) + assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] -def test_update_autonomous_database_rest_flattened(): + +def test_list_goldengate_deployment_environments_field_headers(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + # 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 = ( + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest() + ) - # get arguments that satisfy an http rule for this method - sample_request = { - "autonomous_database": { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" - } - } + request.parent = "parent_value" - # get truthy value for each flattened field - mock_args = dict( - autonomous_database=gco_autonomous_database.AutonomousDatabase( - name="name_value" - ), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), - ) - mock_args.update(sample_request) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_environments), "__call__" + ) as call: + call.return_value = goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse() + client.list_goldengate_deployment_environments(request) - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request - client.update_autonomous_database(**mock_args) + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{autonomous_database.name=projects/*/locations/*/autonomousDatabases/*}" - % client.transport._host, - args[1], - ) +@pytest.mark.asyncio +async def test_list_goldengate_deployment_environments_field_headers_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) -def test_update_autonomous_database_rest_flattened_error(transport: str = "rest"): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + # 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 = ( + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest() ) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.update_autonomous_database( - oracledatabase.UpdateAutonomousDatabaseRequest(), - autonomous_database=gco_autonomous_database.AutonomousDatabase( - name="name_value" - ), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_environments), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse() ) + await client.list_goldengate_deployment_environments(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request -def test_delete_autonomous_database_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - # Ensure method has been cached - assert ( - client._transport.delete_autonomous_database - in client._transport._wrapped_methods - ) +def test_list_goldengate_deployment_environments_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + ) - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_environments), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_goldengate_deployment_environments( + parent="parent_value", ) - client._transport._wrapped_methods[ - client._transport.delete_autonomous_database - ] = mock_rpc - request = {} - client.delete_autonomous_database(request) + # 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 - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() +def test_list_goldengate_deployment_environments_flattened_error(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + ) - client.delete_autonomous_database(request) + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_goldengate_deployment_environments( + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest(), + parent="parent_value", + ) - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 +@pytest.mark.asyncio +async def test_list_goldengate_deployment_environments_flattened_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) -def test_delete_autonomous_database_rest_required_fields( - request_type=oracledatabase.DeleteAutonomousDatabaseRequest, -): - transport_class = transports.OracleDatabaseRestTransport + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_environments), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse() - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_goldengate_deployment_environments( + 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_goldengate_deployment_environments_flattened_error_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - # verify fields with default values are dropped + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_goldengate_deployment_environments( + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest(), + parent="parent_value", + ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).delete_autonomous_database._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - # verify required fields with default values are now present +def test_list_goldengate_deployment_environments_pager(transport_name: str = "grpc"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) - jsonified_request["name"] = "name_value" + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_environments), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse( + goldengate_deployment_environments=[ + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + ], + next_page_token="abc", + ), + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse( + goldengate_deployment_environments=[], + next_page_token="def", + ), + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse( + goldengate_deployment_environments=[ + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + ], + next_page_token="ghi", + ), + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse( + goldengate_deployment_environments=[ + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + ], + ), + RuntimeError, + ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).delete_autonomous_database._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("request_id",)) - jsonified_request.update(unset_fields) + expected_metadata = () + retry = retries.Retry() + timeout = 5 + expected_metadata = tuple(expected_metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_goldengate_deployment_environments( + request={}, retry=retry, timeout=timeout + ) - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + assert pager._metadata == expected_metadata + assert pager._retry == retry + assert pager._timeout == timeout + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance( + i, goldengate_deployment_environment.GoldengateDeploymentEnvironment + ) + for i in results + ) + +def test_list_goldengate_deployment_environments_pages(transport_name: str = "grpc"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport=transport_name, ) - request = request_type(**request_init) - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "delete", - "query_params": pb_request, - } - transcode.return_value = transcode_result + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_environments), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse( + goldengate_deployment_environments=[ + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + ], + next_page_token="abc", + ), + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse( + goldengate_deployment_environments=[], + next_page_token="def", + ), + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse( + goldengate_deployment_environments=[ + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + ], + next_page_token="ghi", + ), + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse( + goldengate_deployment_environments=[ + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + ], + ), + RuntimeError, + ) + pages = list(client.list_goldengate_deployment_environments(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} +@pytest.mark.asyncio +async def test_list_goldengate_deployment_environments_async_pager(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) - response = client.delete_autonomous_database(request) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_environments), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse( + goldengate_deployment_environments=[ + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + ], + next_page_token="abc", + ), + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse( + goldengate_deployment_environments=[], + next_page_token="def", + ), + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse( + goldengate_deployment_environments=[ + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + ], + next_page_token="ghi", + ), + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse( + goldengate_deployment_environments=[ + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_goldengate_deployment_environments( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + assert len(responses) == 6 + assert all( + isinstance( + i, goldengate_deployment_environment.GoldengateDeploymentEnvironment + ) + for i in responses + ) -def test_delete_autonomous_database_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials +@pytest.mark.asyncio +async def test_list_goldengate_deployment_environments_async_pages(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - unset_fields = transport.delete_autonomous_database._get_unset_required_fields({}) - assert set(unset_fields) == (set(("requestId",)) & set(("name",))) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_environments), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse( + goldengate_deployment_environments=[ + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + ], + next_page_token="abc", + ), + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse( + goldengate_deployment_environments=[], + next_page_token="def", + ), + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse( + goldengate_deployment_environments=[ + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + ], + next_page_token="ghi", + ), + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse( + goldengate_deployment_environments=[ + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + ], + ), + RuntimeError, + ) + pages = [] + async for page_ in ( + await client.list_goldengate_deployment_environments(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token -def test_delete_autonomous_database_rest_flattened(): +@pytest.mark.parametrize( + "request_type", + [ + goldengate_connection_type.GetGoldengateConnectionTypeRequest(), + {}, + ], +) +def test_get_goldengate_connection_type(request_type, transport: str = "grpc"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport=transport, ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" - } + # 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 - # get truthy value for each flattened field - mock_args = dict( + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_connection_type), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = goldengate_connection_type.GoldengateConnectionType( name="name_value", + connection_type=goldengate_connection_type.GoldengateConnectionType.ConnectionType.GOLDENGATE, + technology_types=["technology_types_value"], ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_goldengate_connection_type(request) - client.delete_autonomous_database(**mock_args) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = goldengate_connection_type.GetGoldengateConnectionTypeRequest() + assert args[0] == request - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/autonomousDatabases/*}" - % client.transport._host, - args[1], - ) + # Establish that the response is the type that we expect. + assert isinstance(response, goldengate_connection_type.GoldengateConnectionType) + assert response.name == "name_value" + assert ( + response.connection_type + == goldengate_connection_type.GoldengateConnectionType.ConnectionType.GOLDENGATE + ) + assert response.technology_types == ["technology_types_value"] -def test_delete_autonomous_database_rest_flattened_error(transport: str = "rest"): +def test_get_goldengate_connection_type_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport="grpc", ) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.delete_autonomous_database( - oracledatabase.DeleteAutonomousDatabaseRequest(), + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = goldengate_connection_type.GetGoldengateConnectionTypeRequest( + name="name_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_connection_type), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.get_goldengate_connection_type(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_connection_type.GetGoldengateConnectionTypeRequest( name="name_value", ) + assert args[0] == request_msg -def test_restore_autonomous_database_rest_use_cached_wrapped_rpc(): +def test_get_goldengate_connection_type_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) # Should wrap all calls on client creation @@ -30643,7 +32196,7 @@ def test_restore_autonomous_database_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.restore_autonomous_database + client._transport.get_goldengate_connection_type in client._transport._wrapped_methods ) @@ -30653,183 +32206,348 @@ def test_restore_autonomous_database_rest_use_cached_wrapped_rpc(): "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ - client._transport.restore_autonomous_database + client._transport.get_goldengate_connection_type ] = mock_rpc - request = {} - client.restore_autonomous_database(request) + client.get_goldengate_connection_type(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.restore_autonomous_database(request) + client.get_goldengate_connection_type(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_restore_autonomous_database_rest_required_fields( - request_type=oracledatabase.RestoreAutonomousDatabaseRequest, +@pytest.mark.asyncio +async def test_get_goldengate_connection_type_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", ): - transport_class = transports.OracleDatabaseRestTransport + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # verify fields with default values are dropped + # Ensure method has been cached + assert ( + client._client._transport.get_goldengate_connection_type + in client._client._transport._wrapped_methods + ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).restore_autonomous_database._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.get_goldengate_connection_type + ] = mock_rpc - # verify required fields with default values are now present + request = {} + await client.get_goldengate_connection_type(request) - jsonified_request["name"] = "name_value" + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).restore_autonomous_database._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + await client.get_goldengate_connection_type(request) - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "post", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + goldengate_connection_type.GetGoldengateConnectionTypeRequest(), + {}, + ], +) +async def test_get_goldengate_connection_type_async( + request_type, transport: str = "grpc_asyncio" +): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) + # 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 - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_connection_type), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_connection_type.GoldengateConnectionType( + name="name_value", + connection_type=goldengate_connection_type.GoldengateConnectionType.ConnectionType.GOLDENGATE, + technology_types=["technology_types_value"], + ) + ) + response = await client.get_goldengate_connection_type(request) - response = client.restore_autonomous_database(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = goldengate_connection_type.GetGoldengateConnectionTypeRequest() + assert args[0] == request - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + # Establish that the response is the type that we expect. + assert isinstance(response, goldengate_connection_type.GoldengateConnectionType) + assert response.name == "name_value" + assert ( + response.connection_type + == goldengate_connection_type.GoldengateConnectionType.ConnectionType.GOLDENGATE + ) + assert response.technology_types == ["technology_types_value"] -def test_restore_autonomous_database_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials +def test_get_goldengate_connection_type_field_headers(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), ) - unset_fields = transport.restore_autonomous_database._get_unset_required_fields({}) - assert set(unset_fields) == ( - set(()) - & set( - ( - "name", - "restoreTime", - ) - ) + # 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 = goldengate_connection_type.GetGoldengateConnectionTypeRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_connection_type), "__call__" + ) as call: + call.return_value = goldengate_connection_type.GoldengateConnectionType() + client.get_goldengate_connection_type(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_goldengate_connection_type_field_headers_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) + # 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 = goldengate_connection_type.GetGoldengateConnectionTypeRequest() + + request.name = "name_value" -def test_restore_autonomous_database_rest_flattened(): + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_connection_type), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_connection_type.GoldengateConnectionType() + ) + await client.get_goldengate_connection_type(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_goldengate_connection_type_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_connection_type), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = goldengate_connection_type.GoldengateConnectionType() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_goldengate_connection_type( + name="name_value", + ) - # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" - } + # 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 - # get truthy value for each flattened field - mock_args = dict( + +def test_get_goldengate_connection_type_flattened_error(): + client = OracleDatabaseClient( + 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_goldengate_connection_type( + goldengate_connection_type.GetGoldengateConnectionTypeRequest(), name="name_value", - restore_time=timestamp_pb2.Timestamp(seconds=751), ) - mock_args.update(sample_request) - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.restore_autonomous_database(**mock_args) +@pytest.mark.asyncio +async def test_get_goldengate_connection_type_flattened_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_connection_type), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = goldengate_connection_type.GoldengateConnectionType() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_connection_type.GoldengateConnectionType() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_goldengate_connection_type( + name="name_value", + ) # Establish that the underlying call was made with the expected # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/autonomousDatabases/*}:restore" - % client.transport._host, - args[1], - ) + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val -def test_restore_autonomous_database_rest_flattened_error(transport: str = "rest"): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, +@pytest.mark.asyncio +async def test_get_goldengate_connection_type_flattened_error_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.restore_autonomous_database( - oracledatabase.RestoreAutonomousDatabaseRequest(), + await client.get_goldengate_connection_type( + goldengate_connection_type.GetGoldengateConnectionTypeRequest(), name="name_value", - restore_time=timestamp_pb2.Timestamp(seconds=751), ) -def test_generate_autonomous_database_wallet_rest_use_cached_wrapped_rpc(): +@pytest.mark.parametrize( + "request_type", + [ + goldengate_connection_type.ListGoldengateConnectionTypesRequest(), + {}, + ], +) +def test_list_goldengate_connection_types(request_type, transport: str = "grpc"): + client = OracleDatabaseClient( + 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_goldengate_connection_types), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + goldengate_connection_type.ListGoldengateConnectionTypesResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + response = client.list_goldengate_connection_types(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = goldengate_connection_type.ListGoldengateConnectionTypesRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListGoldengateConnectionTypesPager) + assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] + + +def test_list_goldengate_connection_types_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = goldengate_connection_type.ListGoldengateConnectionTypesRequest( + parent="parent_value", + page_token="page_token_value", + filter="filter_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connection_types), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.list_goldengate_connection_types(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_connection_type.ListGoldengateConnectionTypesRequest( + parent="parent_value", + page_token="page_token_value", + filter="filter_value", + ) + assert args[0] == request_msg + + +def test_list_goldengate_connection_types_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) # Should wrap all calls on client creation @@ -30838,7 +32556,7 @@ def test_generate_autonomous_database_wallet_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.generate_autonomous_database_wallet + client._transport.list_goldengate_connection_types in client._transport._wrapped_methods ) @@ -30848,465 +32566,549 @@ def test_generate_autonomous_database_wallet_rest_use_cached_wrapped_rpc(): "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ - client._transport.generate_autonomous_database_wallet + client._transport.list_goldengate_connection_types ] = mock_rpc - request = {} - client.generate_autonomous_database_wallet(request) + client.list_goldengate_connection_types(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.generate_autonomous_database_wallet(request) + client.list_goldengate_connection_types(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_generate_autonomous_database_wallet_rest_required_fields( - request_type=oracledatabase.GenerateAutonomousDatabaseWalletRequest, +@pytest.mark.asyncio +async def test_list_goldengate_connection_types_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", ): - transport_class = transports.OracleDatabaseRestTransport + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - request_init = {} - request_init["name"] = "" - request_init["password"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # verify fields with default values are dropped + # Ensure method has been cached + assert ( + client._client._transport.list_goldengate_connection_types + in client._client._transport._wrapped_methods + ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).generate_autonomous_database_wallet._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.list_goldengate_connection_types + ] = mock_rpc - # verify required fields with default values are now present + request = {} + await client.list_goldengate_connection_types(request) - jsonified_request["name"] = "name_value" - jsonified_request["password"] = "password_value" + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).generate_autonomous_database_wallet._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + await client.list_goldengate_connection_types(request) - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" - assert "password" in jsonified_request - assert jsonified_request["password"] == "password_value" + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + goldengate_connection_type.ListGoldengateConnectionTypesRequest(), + {}, + ], +) +async def test_list_goldengate_connection_types_async( + request_type, transport: str = "grpc_asyncio" +): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + 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_goldengate_connection_types), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_connection_type.ListGoldengateConnectionTypesResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + response = await client.list_goldengate_connection_types(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = goldengate_connection_type.ListGoldengateConnectionTypesRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListGoldengateConnectionTypesAsyncPager) + assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] + +def test_list_goldengate_connection_types_field_headers(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = oracledatabase.GenerateAutonomousDatabaseWalletResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "post", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result - response_value = Response() - response_value.status_code = 200 + # 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 = goldengate_connection_type.ListGoldengateConnectionTypesRequest() - # Convert return value to protobuf type - return_value = oracledatabase.GenerateAutonomousDatabaseWalletResponse.pb( - return_value - ) - json_return_value = json_format.MessageToJson(return_value) + request.parent = "parent_value" - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connection_types), "__call__" + ) as call: + call.return_value = ( + goldengate_connection_type.ListGoldengateConnectionTypesResponse() + ) + client.list_goldengate_connection_types(request) - response = client.generate_autonomous_database_wallet(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 - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + # 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_generate_autonomous_database_wallet_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials +@pytest.mark.asyncio +async def test_list_goldengate_connection_types_field_headers_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - unset_fields = ( - transport.generate_autonomous_database_wallet._get_unset_required_fields({}) - ) - assert set(unset_fields) == ( - set(()) - & set( - ( - "name", - "password", - ) + # 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 = goldengate_connection_type.ListGoldengateConnectionTypesRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connection_types), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_connection_type.ListGoldengateConnectionTypesResponse() ) - ) + await client.list_goldengate_connection_types(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request -def test_generate_autonomous_database_wallet_rest_flattened(): + # 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_goldengate_connection_types_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = oracledatabase.GenerateAutonomousDatabaseWalletResponse() - - # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" - } - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - type_=autonomous_database.GenerateType.ALL, - is_regional=True, - password="password_value", + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connection_types), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + goldengate_connection_type.ListGoldengateConnectionTypesResponse() ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = oracledatabase.GenerateAutonomousDatabaseWalletResponse.pb( - return_value + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_goldengate_connection_types( + parent="parent_value", ) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - client.generate_autonomous_database_wallet(**mock_args) # Establish that the underlying call was made with the expected # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/autonomousDatabases/*}:generateWallet" - % client.transport._host, - args[1], - ) + 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_generate_autonomous_database_wallet_rest_flattened_error( - transport: str = "rest", -): +def test_list_goldengate_connection_types_flattened_error(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, ) # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.generate_autonomous_database_wallet( - oracledatabase.GenerateAutonomousDatabaseWalletRequest(), - name="name_value", - type_=autonomous_database.GenerateType.ALL, - is_regional=True, - password="password_value", + client.list_goldengate_connection_types( + goldengate_connection_type.ListGoldengateConnectionTypesRequest(), + parent="parent_value", ) -def test_list_autonomous_db_versions_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() +@pytest.mark.asyncio +async def test_list_goldengate_connection_types_flattened_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) - # Ensure method has been cached - assert ( - client._transport.list_autonomous_db_versions - in client._transport._wrapped_methods + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connection_types), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + goldengate_connection_type.ListGoldengateConnectionTypesResponse() ) - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_connection_type.ListGoldengateConnectionTypesResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_goldengate_connection_types( + parent="parent_value", ) - client._transport._wrapped_methods[ - client._transport.list_autonomous_db_versions - ] = mock_rpc - - request = {} - client.list_autonomous_db_versions(request) - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 + # 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 - client.list_autonomous_db_versions(request) - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_list_autonomous_db_versions_rest_required_fields( - request_type=oracledatabase.ListAutonomousDbVersionsRequest, -): - transport_class = transports.OracleDatabaseRestTransport - - request_init = {} - request_init["parent"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) +@pytest.mark.asyncio +async def test_list_goldengate_connection_types_flattened_error_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_autonomous_db_versions._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["parent"] = "parent_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_autonomous_db_versions._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "page_size", - "page_token", + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_goldengate_connection_types( + goldengate_connection_type.ListGoldengateConnectionTypesRequest(), + parent="parent_value", ) - ) - jsonified_request.update(unset_fields) - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" +def test_list_goldengate_connection_types_pager(transport_name: str = "grpc"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport=transport_name, ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListAutonomousDbVersionsResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = oracledatabase.ListAutonomousDbVersionsResponse.pb( - return_value - ) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_autonomous_db_versions(request) - - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connection_types), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + goldengate_connection_type.ListGoldengateConnectionTypesResponse( + goldengate_connection_types=[ + goldengate_connection_type.GoldengateConnectionType(), + goldengate_connection_type.GoldengateConnectionType(), + goldengate_connection_type.GoldengateConnectionType(), + ], + next_page_token="abc", + ), + goldengate_connection_type.ListGoldengateConnectionTypesResponse( + goldengate_connection_types=[], + next_page_token="def", + ), + goldengate_connection_type.ListGoldengateConnectionTypesResponse( + goldengate_connection_types=[ + goldengate_connection_type.GoldengateConnectionType(), + ], + next_page_token="ghi", + ), + goldengate_connection_type.ListGoldengateConnectionTypesResponse( + goldengate_connection_types=[ + goldengate_connection_type.GoldengateConnectionType(), + goldengate_connection_type.GoldengateConnectionType(), + ], + ), + RuntimeError, + ) + expected_metadata = () + retry = retries.Retry() + timeout = 5 + expected_metadata = tuple(expected_metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_goldengate_connection_types( + request={}, retry=retry, timeout=timeout + ) -def test_list_autonomous_db_versions_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) + assert pager._metadata == expected_metadata + assert pager._retry == retry + assert pager._timeout == timeout - unset_fields = transport.list_autonomous_db_versions._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "pageSize", - "pageToken", - ) + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, goldengate_connection_type.GoldengateConnectionType) + for i in results ) - & set(("parent",)) - ) -def test_list_autonomous_db_versions_rest_flattened(): +def test_list_goldengate_connection_types_pages(transport_name: str = "grpc"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport=transport_name, ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListAutonomousDbVersionsResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} - - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connection_types), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + goldengate_connection_type.ListGoldengateConnectionTypesResponse( + goldengate_connection_types=[ + goldengate_connection_type.GoldengateConnectionType(), + goldengate_connection_type.GoldengateConnectionType(), + goldengate_connection_type.GoldengateConnectionType(), + ], + next_page_token="abc", + ), + goldengate_connection_type.ListGoldengateConnectionTypesResponse( + goldengate_connection_types=[], + next_page_token="def", + ), + goldengate_connection_type.ListGoldengateConnectionTypesResponse( + goldengate_connection_types=[ + goldengate_connection_type.GoldengateConnectionType(), + ], + next_page_token="ghi", + ), + goldengate_connection_type.ListGoldengateConnectionTypesResponse( + goldengate_connection_types=[ + goldengate_connection_type.GoldengateConnectionType(), + goldengate_connection_type.GoldengateConnectionType(), + ], + ), + RuntimeError, ) - mock_args.update(sample_request) + pages = list(client.list_goldengate_connection_types(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = oracledatabase.ListAutonomousDbVersionsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_autonomous_db_versions(**mock_args) +@pytest.mark.asyncio +async def test_list_goldengate_connection_types_async_pager(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/autonomousDbVersions" - % client.transport._host, - args[1], + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connection_types), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + goldengate_connection_type.ListGoldengateConnectionTypesResponse( + goldengate_connection_types=[ + goldengate_connection_type.GoldengateConnectionType(), + goldengate_connection_type.GoldengateConnectionType(), + goldengate_connection_type.GoldengateConnectionType(), + ], + next_page_token="abc", + ), + goldengate_connection_type.ListGoldengateConnectionTypesResponse( + goldengate_connection_types=[], + next_page_token="def", + ), + goldengate_connection_type.ListGoldengateConnectionTypesResponse( + goldengate_connection_types=[ + goldengate_connection_type.GoldengateConnectionType(), + ], + next_page_token="ghi", + ), + goldengate_connection_type.ListGoldengateConnectionTypesResponse( + goldengate_connection_types=[ + goldengate_connection_type.GoldengateConnectionType(), + goldengate_connection_type.GoldengateConnectionType(), + ], + ), + RuntimeError, ) + async_pager = await client.list_goldengate_connection_types( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) - -def test_list_autonomous_db_versions_rest_flattened_error(transport: str = "rest"): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.list_autonomous_db_versions( - oracledatabase.ListAutonomousDbVersionsRequest(), - parent="parent_value", + assert len(responses) == 6 + assert all( + isinstance(i, goldengate_connection_type.GoldengateConnectionType) + for i in responses ) -def test_list_autonomous_db_versions_rest_pager(transport: str = "rest"): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, +@pytest.mark.asyncio +async def test_list_goldengate_connection_types_async_pages(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - oracledatabase.ListAutonomousDbVersionsResponse( - autonomous_db_versions=[ - autonomous_db_version.AutonomousDbVersion(), - autonomous_db_version.AutonomousDbVersion(), - autonomous_db_version.AutonomousDbVersion(), + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connection_types), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + goldengate_connection_type.ListGoldengateConnectionTypesResponse( + goldengate_connection_types=[ + goldengate_connection_type.GoldengateConnectionType(), + goldengate_connection_type.GoldengateConnectionType(), + goldengate_connection_type.GoldengateConnectionType(), ], next_page_token="abc", ), - oracledatabase.ListAutonomousDbVersionsResponse( - autonomous_db_versions=[], + goldengate_connection_type.ListGoldengateConnectionTypesResponse( + goldengate_connection_types=[], next_page_token="def", ), - oracledatabase.ListAutonomousDbVersionsResponse( - autonomous_db_versions=[ - autonomous_db_version.AutonomousDbVersion(), + goldengate_connection_type.ListGoldengateConnectionTypesResponse( + goldengate_connection_types=[ + goldengate_connection_type.GoldengateConnectionType(), ], next_page_token="ghi", ), - oracledatabase.ListAutonomousDbVersionsResponse( - autonomous_db_versions=[ - autonomous_db_version.AutonomousDbVersion(), - autonomous_db_version.AutonomousDbVersion(), + goldengate_connection_type.ListGoldengateConnectionTypesResponse( + goldengate_connection_types=[ + goldengate_connection_type.GoldengateConnectionType(), + goldengate_connection_type.GoldengateConnectionType(), ], ), + RuntimeError, ) - # Two responses for two calls - response = response + response + pages = [] + async for page_ in ( + await client.list_goldengate_connection_types(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token - # Wrap the values into proper Response objs - response = tuple( - oracledatabase.ListAutonomousDbVersionsResponse.to_json(x) for x in response - ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - sample_request = {"parent": "projects/sample1/locations/sample2"} +@pytest.mark.parametrize( + "request_type", + [ + db_version.ListDbVersionsRequest(), + {}, + ], +) +def test_list_db_versions(request_type, transport: str = "grpc"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) - pager = client.list_autonomous_db_versions(request=sample_request) + # 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 - results = list(pager) - assert len(results) == 6 - assert all( - isinstance(i, autonomous_db_version.AutonomousDbVersion) for i in results + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_db_versions), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = db_version.ListDbVersionsResponse( + next_page_token="next_page_token_value", ) + response = client.list_db_versions(request) - pages = list(client.list_autonomous_db_versions(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = db_version.ListDbVersionsRequest() + assert args[0] == request + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListDbVersionsPager) + assert response.next_page_token == "next_page_token_value" -def test_list_autonomous_database_character_sets_rest_use_cached_wrapped_rpc(): + +def test_list_db_versions_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = db_version.ListDbVersionsRequest( + parent="parent_value", + page_token="page_token_value", + filter="filter_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_db_versions), "__call__") as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.list_db_versions(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = db_version.ListDbVersionsRequest( + parent="parent_value", + page_token="page_token_value", + filter="filter_value", + ) + assert args[0] == request_msg + + +def test_list_db_versions_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) # Should wrap all calls on client creation @@ -31314,284 +33116,523 @@ def test_list_autonomous_database_character_sets_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert ( - client._transport.list_autonomous_database_character_sets - in client._transport._wrapped_methods - ) + assert client._transport.list_db_versions in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[ - client._transport.list_autonomous_database_character_sets - ] = mock_rpc - + client._transport._wrapped_methods[client._transport.list_db_versions] = ( + mock_rpc + ) request = {} - client.list_autonomous_database_character_sets(request) + client.list_db_versions(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_autonomous_database_character_sets(request) + client.list_db_versions(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_autonomous_database_character_sets_rest_required_fields( - request_type=oracledatabase.ListAutonomousDatabaseCharacterSetsRequest, +@pytest.mark.asyncio +async def test_list_db_versions_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", ): - transport_class = transports.OracleDatabaseRestTransport + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - request_init = {} - request_init["parent"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # verify fields with default values are dropped + # Ensure method has been cached + assert ( + client._client._transport.list_db_versions + in client._client._transport._wrapped_methods + ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_autonomous_database_character_sets._get_unset_required_fields( - jsonified_request - ) - jsonified_request.update(unset_fields) + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.list_db_versions + ] = mock_rpc - # verify required fields with default values are now present + request = {} + await client.list_db_versions(request) - jsonified_request["parent"] = "parent_value" + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_autonomous_database_character_sets._get_unset_required_fields( - jsonified_request - ) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "filter", - "page_size", - "page_token", - ) - ) - jsonified_request.update(unset_fields) + await client.list_db_versions(request) - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListAutonomousDatabaseCharacterSetsResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + db_version.ListDbVersionsRequest(), + {}, + ], +) +async def test_list_db_versions_async(request_type, transport: str = "grpc_asyncio"): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - response_value = Response() - response_value.status_code = 200 + # 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 - # Convert return value to protobuf type - return_value = ( - oracledatabase.ListAutonomousDatabaseCharacterSetsResponse.pb( - return_value - ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_db_versions), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + db_version.ListDbVersionsResponse( + next_page_token="next_page_token_value", ) - json_return_value = json_format.MessageToJson(return_value) + ) + response = await client.list_db_versions(request) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = db_version.ListDbVersionsRequest() + assert args[0] == request - response = client.list_autonomous_database_character_sets(request) + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListDbVersionsAsyncPager) + assert response.next_page_token == "next_page_token_value" - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) +def test_list_db_versions_field_headers(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + ) -def test_list_autonomous_database_character_sets_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - 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 = db_version.ListDbVersionsRequest() - unset_fields = ( - transport.list_autonomous_database_character_sets._get_unset_required_fields({}) + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_db_versions), "__call__") as call: + call.return_value = db_version.ListDbVersionsResponse() + client.list_db_versions(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_db_versions_field_headers_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - assert set(unset_fields) == ( - set( - ( - "filter", - "pageSize", - "pageToken", - ) + + # 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 = db_version.ListDbVersionsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_db_versions), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + db_version.ListDbVersionsResponse() ) - & set(("parent",)) - ) + await client.list_db_versions(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_autonomous_database_character_sets_rest_flattened(): + +def test_list_db_versions_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListAutonomousDatabaseCharacterSetsResponse() + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_db_versions), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = db_version.ListDbVersionsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_db_versions( + parent="parent_value", + ) - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} + # 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 - # get truthy value for each flattened field - mock_args = dict( + +def test_list_db_versions_flattened_error(): + client = OracleDatabaseClient( + 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_db_versions( + db_version.ListDbVersionsRequest(), parent="parent_value", ) - mock_args.update(sample_request) - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = oracledatabase.ListAutonomousDatabaseCharacterSetsResponse.pb( - return_value - ) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_autonomous_database_character_sets(**mock_args) +@pytest.mark.asyncio +async def test_list_db_versions_flattened_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_db_versions), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = db_version.ListDbVersionsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + db_version.ListDbVersionsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_db_versions( + parent="parent_value", + ) # Establish that the underlying call was made with the expected # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/autonomousDatabaseCharacterSets" - % client.transport._host, - args[1], - ) + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val -def test_list_autonomous_database_character_sets_rest_flattened_error( - transport: str = "rest", -): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, +@pytest.mark.asyncio +async def test_list_db_versions_flattened_error_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_autonomous_database_character_sets( - oracledatabase.ListAutonomousDatabaseCharacterSetsRequest(), + await client.list_db_versions( + db_version.ListDbVersionsRequest(), parent="parent_value", ) -def test_list_autonomous_database_character_sets_rest_pager(transport: str = "rest"): +def test_list_db_versions_pager(transport_name: str = "grpc"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport=transport_name, ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - oracledatabase.ListAutonomousDatabaseCharacterSetsResponse( - autonomous_database_character_sets=[ - autonomous_database_character_set.AutonomousDatabaseCharacterSet(), - autonomous_database_character_set.AutonomousDatabaseCharacterSet(), - autonomous_database_character_set.AutonomousDatabaseCharacterSet(), + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_db_versions), "__call__") as call: + # Set the response to a series of pages. + call.side_effect = ( + db_version.ListDbVersionsResponse( + db_versions=[ + db_version.DbVersion(), + db_version.DbVersion(), + db_version.DbVersion(), ], next_page_token="abc", ), - oracledatabase.ListAutonomousDatabaseCharacterSetsResponse( - autonomous_database_character_sets=[], + db_version.ListDbVersionsResponse( + db_versions=[], next_page_token="def", ), - oracledatabase.ListAutonomousDatabaseCharacterSetsResponse( - autonomous_database_character_sets=[ - autonomous_database_character_set.AutonomousDatabaseCharacterSet(), + db_version.ListDbVersionsResponse( + db_versions=[ + db_version.DbVersion(), ], next_page_token="ghi", ), - oracledatabase.ListAutonomousDatabaseCharacterSetsResponse( - autonomous_database_character_sets=[ - autonomous_database_character_set.AutonomousDatabaseCharacterSet(), - autonomous_database_character_set.AutonomousDatabaseCharacterSet(), + db_version.ListDbVersionsResponse( + db_versions=[ + db_version.DbVersion(), + db_version.DbVersion(), ], ), + RuntimeError, ) - # Two responses for two calls - response = response + response - # Wrap the values into proper Response objs - response = tuple( - oracledatabase.ListAutonomousDatabaseCharacterSetsResponse.to_json(x) - for x in response + expected_metadata = () + retry = retries.Retry() + timeout = 5 + expected_metadata = tuple(expected_metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "projects/sample1/locations/sample2"} + pager = client.list_db_versions(request={}, retry=retry, timeout=timeout) - pager = client.list_autonomous_database_character_sets(request=sample_request) + assert pager._metadata == expected_metadata + assert pager._retry == retry + assert pager._timeout == timeout results = list(pager) assert len(results) == 6 - assert all( - isinstance( - i, autonomous_database_character_set.AutonomousDatabaseCharacterSet - ) - for i in results + assert all(isinstance(i, db_version.DbVersion) for i in results) + + +def test_list_db_versions_pages(transport_name: str = "grpc"): + client = OracleDatabaseClient( + 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_db_versions), "__call__") as call: + # Set the response to a series of pages. + call.side_effect = ( + db_version.ListDbVersionsResponse( + db_versions=[ + db_version.DbVersion(), + db_version.DbVersion(), + db_version.DbVersion(), + ], + next_page_token="abc", + ), + db_version.ListDbVersionsResponse( + db_versions=[], + next_page_token="def", + ), + db_version.ListDbVersionsResponse( + db_versions=[ + db_version.DbVersion(), + ], + next_page_token="ghi", + ), + db_version.ListDbVersionsResponse( + db_versions=[ + db_version.DbVersion(), + db_version.DbVersion(), + ], + ), + RuntimeError, ) + pages = list(client.list_db_versions(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token - pages = list( - client.list_autonomous_database_character_sets(request=sample_request).pages + +@pytest.mark.asyncio +async def test_list_db_versions_async_pager(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_db_versions), "__call__", new_callable=mock.AsyncMock + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + db_version.ListDbVersionsResponse( + db_versions=[ + db_version.DbVersion(), + db_version.DbVersion(), + db_version.DbVersion(), + ], + next_page_token="abc", + ), + db_version.ListDbVersionsResponse( + db_versions=[], + next_page_token="def", + ), + db_version.ListDbVersionsResponse( + db_versions=[ + db_version.DbVersion(), + ], + next_page_token="ghi", + ), + db_version.ListDbVersionsResponse( + db_versions=[ + db_version.DbVersion(), + db_version.DbVersion(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_db_versions( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, db_version.DbVersion) for i in responses) + + +@pytest.mark.asyncio +async def test_list_db_versions_async_pages(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_db_versions), "__call__", new_callable=mock.AsyncMock + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + db_version.ListDbVersionsResponse( + db_versions=[ + db_version.DbVersion(), + db_version.DbVersion(), + db_version.DbVersion(), + ], + next_page_token="abc", + ), + db_version.ListDbVersionsResponse( + db_versions=[], + next_page_token="def", + ), + db_version.ListDbVersionsResponse( + db_versions=[ + db_version.DbVersion(), + ], + next_page_token="ghi", + ), + db_version.ListDbVersionsResponse( + db_versions=[ + db_version.DbVersion(), + db_version.DbVersion(), + ], + ), + RuntimeError, ) + pages = [] + async for page_ in (await client.list_db_versions(request={})).pages: + pages.append(page_) for page_, token in zip(pages, ["abc", "def", "ghi", ""]): assert page_.raw_page.next_page_token == token -def test_list_autonomous_database_backups_rest_use_cached_wrapped_rpc(): +@pytest.mark.parametrize( + "request_type", + [ + database_character_set.ListDatabaseCharacterSetsRequest(), + {}, + ], +) +def test_list_database_character_sets(request_type, transport: str = "grpc"): + client = OracleDatabaseClient( + 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_database_character_sets), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = database_character_set.ListDatabaseCharacterSetsResponse( + next_page_token="next_page_token_value", + ) + response = client.list_database_character_sets(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = database_character_set.ListDatabaseCharacterSetsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListDatabaseCharacterSetsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_database_character_sets_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = database_character_set.ListDatabaseCharacterSetsRequest( + parent="parent_value", + page_token="page_token_value", + filter="filter_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_database_character_sets), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.list_database_character_sets(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = database_character_set.ListDatabaseCharacterSetsRequest( + parent="parent_value", + page_token="page_token_value", + filter="filter_value", + ) + assert args[0] == request_msg + + +def test_list_database_character_sets_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) # Should wrap all calls on client creation @@ -31600,7 +33641,7 @@ def test_list_autonomous_database_backups_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.list_autonomous_database_backups + client._transport.list_database_character_sets in client._transport._wrapped_methods ) @@ -31610,448 +33651,552 @@ def test_list_autonomous_database_backups_rest_use_cached_wrapped_rpc(): "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ - client._transport.list_autonomous_database_backups + client._transport.list_database_character_sets ] = mock_rpc - request = {} - client.list_autonomous_database_backups(request) + client.list_database_character_sets(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_autonomous_database_backups(request) + client.list_database_character_sets(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_autonomous_database_backups_rest_required_fields( - request_type=oracledatabase.ListAutonomousDatabaseBackupsRequest, +@pytest.mark.asyncio +async def test_list_database_character_sets_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", ): - transport_class = transports.OracleDatabaseRestTransport + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - request_init = {} - request_init["parent"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # verify fields with default values are dropped + # Ensure method has been cached + assert ( + client._client._transport.list_database_character_sets + in client._client._transport._wrapped_methods + ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_autonomous_database_backups._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.list_database_character_sets + ] = mock_rpc - # verify required fields with default values are now present + request = {} + await client.list_database_character_sets(request) - jsonified_request["parent"] = "parent_value" + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_autonomous_database_backups._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "filter", - "page_size", - "page_token", - ) - ) - jsonified_request.update(unset_fields) + await client.list_database_character_sets(request) - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + database_character_set.ListDatabaseCharacterSetsRequest(), + {}, + ], +) +async def test_list_database_character_sets_async( + request_type, transport: str = "grpc_asyncio" +): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + 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_database_character_sets), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + database_character_set.ListDatabaseCharacterSetsResponse( + next_page_token="next_page_token_value", + ) + ) + response = await client.list_database_character_sets(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = database_character_set.ListDatabaseCharacterSetsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListDatabaseCharacterSetsAsyncPager) + assert response.next_page_token == "next_page_token_value" + +def test_list_database_character_sets_field_headers(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListAutonomousDatabaseBackupsResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - response_value = Response() - response_value.status_code = 200 + # 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 = database_character_set.ListDatabaseCharacterSetsRequest() - # Convert return value to protobuf type - return_value = oracledatabase.ListAutonomousDatabaseBackupsResponse.pb( - return_value - ) - json_return_value = json_format.MessageToJson(return_value) + request.parent = "parent_value" - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_database_character_sets), "__call__" + ) as call: + call.return_value = database_character_set.ListDatabaseCharacterSetsResponse() + client.list_database_character_sets(request) - response = client.list_autonomous_database_backups(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 - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + # 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_autonomous_database_backups_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials +@pytest.mark.asyncio +async def test_list_database_character_sets_field_headers_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - unset_fields = ( - transport.list_autonomous_database_backups._get_unset_required_fields({}) - ) - assert set(unset_fields) == ( - set( - ( - "filter", - "pageSize", - "pageToken", - ) + # 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 = database_character_set.ListDatabaseCharacterSetsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_database_character_sets), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + database_character_set.ListDatabaseCharacterSetsResponse() ) - & set(("parent",)) - ) + await client.list_database_character_sets(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request -def test_list_autonomous_database_backups_rest_flattened(): + # 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_database_character_sets_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListAutonomousDatabaseBackupsResponse() + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_database_character_sets), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = database_character_set.ListDatabaseCharacterSetsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_database_character_sets( + parent="parent_value", + ) - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} + # 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 - # get truthy value for each flattened field - mock_args = dict( + +def test_list_database_character_sets_flattened_error(): + client = OracleDatabaseClient( + 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_database_character_sets( + database_character_set.ListDatabaseCharacterSetsRequest(), parent="parent_value", ) - mock_args.update(sample_request) - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = oracledatabase.ListAutonomousDatabaseBackupsResponse.pb( - return_value - ) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_autonomous_database_backups(**mock_args) +@pytest.mark.asyncio +async def test_list_database_character_sets_flattened_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_database_character_sets), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = database_character_set.ListDatabaseCharacterSetsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + database_character_set.ListDatabaseCharacterSetsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_database_character_sets( + parent="parent_value", + ) # Establish that the underlying call was made with the expected # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/autonomousDatabaseBackups" - % client.transport._host, - args[1], - ) + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val -def test_list_autonomous_database_backups_rest_flattened_error(transport: str = "rest"): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, +@pytest.mark.asyncio +async def test_list_database_character_sets_flattened_error_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_autonomous_database_backups( - oracledatabase.ListAutonomousDatabaseBackupsRequest(), + await client.list_database_character_sets( + database_character_set.ListDatabaseCharacterSetsRequest(), parent="parent_value", ) -def test_list_autonomous_database_backups_rest_pager(transport: str = "rest"): +def test_list_database_character_sets_pager(transport_name: str = "grpc"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport=transport_name, ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - oracledatabase.ListAutonomousDatabaseBackupsResponse( - autonomous_database_backups=[ - autonomous_db_backup.AutonomousDatabaseBackup(), - autonomous_db_backup.AutonomousDatabaseBackup(), - autonomous_db_backup.AutonomousDatabaseBackup(), + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_database_character_sets), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + database_character_set.ListDatabaseCharacterSetsResponse( + database_character_sets=[ + database_character_set.DatabaseCharacterSet(), + database_character_set.DatabaseCharacterSet(), + database_character_set.DatabaseCharacterSet(), ], next_page_token="abc", ), - oracledatabase.ListAutonomousDatabaseBackupsResponse( - autonomous_database_backups=[], + database_character_set.ListDatabaseCharacterSetsResponse( + database_character_sets=[], next_page_token="def", ), - oracledatabase.ListAutonomousDatabaseBackupsResponse( - autonomous_database_backups=[ - autonomous_db_backup.AutonomousDatabaseBackup(), + database_character_set.ListDatabaseCharacterSetsResponse( + database_character_sets=[ + database_character_set.DatabaseCharacterSet(), ], next_page_token="ghi", ), - oracledatabase.ListAutonomousDatabaseBackupsResponse( - autonomous_database_backups=[ - autonomous_db_backup.AutonomousDatabaseBackup(), - autonomous_db_backup.AutonomousDatabaseBackup(), + database_character_set.ListDatabaseCharacterSetsResponse( + database_character_sets=[ + database_character_set.DatabaseCharacterSet(), + database_character_set.DatabaseCharacterSet(), ], ), + RuntimeError, ) - # Two responses for two calls - response = response + response - # Wrap the values into proper Response objs - response = tuple( - oracledatabase.ListAutonomousDatabaseBackupsResponse.to_json(x) - for x in response + expected_metadata = () + retry = retries.Retry() + timeout = 5 + expected_metadata = tuple(expected_metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_database_character_sets( + request={}, retry=retry, timeout=timeout ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "projects/sample1/locations/sample2"} - pager = client.list_autonomous_database_backups(request=sample_request) + assert pager._metadata == expected_metadata + assert pager._retry == retry + assert pager._timeout == timeout results = list(pager) assert len(results) == 6 assert all( - isinstance(i, autonomous_db_backup.AutonomousDatabaseBackup) - for i in results + isinstance(i, database_character_set.DatabaseCharacterSet) for i in results ) - pages = list( - client.list_autonomous_database_backups(request=sample_request).pages + +def test_list_database_character_sets_pages(transport_name: str = "grpc"): + client = OracleDatabaseClient( + 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_database_character_sets), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + database_character_set.ListDatabaseCharacterSetsResponse( + database_character_sets=[ + database_character_set.DatabaseCharacterSet(), + database_character_set.DatabaseCharacterSet(), + database_character_set.DatabaseCharacterSet(), + ], + next_page_token="abc", + ), + database_character_set.ListDatabaseCharacterSetsResponse( + database_character_sets=[], + next_page_token="def", + ), + database_character_set.ListDatabaseCharacterSetsResponse( + database_character_sets=[ + database_character_set.DatabaseCharacterSet(), + ], + next_page_token="ghi", + ), + database_character_set.ListDatabaseCharacterSetsResponse( + database_character_sets=[ + database_character_set.DatabaseCharacterSet(), + database_character_set.DatabaseCharacterSet(), + ], + ), + RuntimeError, ) + pages = list(client.list_database_character_sets(request={}).pages) for page_, token in zip(pages, ["abc", "def", "ghi", ""]): assert page_.raw_page.next_page_token == token -def test_stop_autonomous_database_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() +@pytest.mark.asyncio +async def test_list_database_character_sets_async_pager(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) - # Ensure method has been cached - assert ( - client._transport.stop_autonomous_database - in client._transport._wrapped_methods + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_database_character_sets), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + database_character_set.ListDatabaseCharacterSetsResponse( + database_character_sets=[ + database_character_set.DatabaseCharacterSet(), + database_character_set.DatabaseCharacterSet(), + database_character_set.DatabaseCharacterSet(), + ], + next_page_token="abc", + ), + database_character_set.ListDatabaseCharacterSetsResponse( + database_character_sets=[], + next_page_token="def", + ), + database_character_set.ListDatabaseCharacterSetsResponse( + database_character_sets=[ + database_character_set.DatabaseCharacterSet(), + ], + next_page_token="ghi", + ), + database_character_set.ListDatabaseCharacterSetsResponse( + database_character_sets=[ + database_character_set.DatabaseCharacterSet(), + database_character_set.DatabaseCharacterSet(), + ], + ), + RuntimeError, ) + async_pager = await client.list_database_character_sets( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. + assert len(responses) == 6 + assert all( + isinstance(i, database_character_set.DatabaseCharacterSet) + for i in responses ) - client._transport._wrapped_methods[ - client._transport.stop_autonomous_database - ] = mock_rpc - request = {} - client.stop_autonomous_database(request) - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 +@pytest.mark.asyncio +async def test_list_database_character_sets_async_pages(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_database_character_sets), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + database_character_set.ListDatabaseCharacterSetsResponse( + database_character_sets=[ + database_character_set.DatabaseCharacterSet(), + database_character_set.DatabaseCharacterSet(), + database_character_set.DatabaseCharacterSet(), + ], + next_page_token="abc", + ), + database_character_set.ListDatabaseCharacterSetsResponse( + database_character_sets=[], + next_page_token="def", + ), + database_character_set.ListDatabaseCharacterSetsResponse( + database_character_sets=[ + database_character_set.DatabaseCharacterSet(), + ], + next_page_token="ghi", + ), + database_character_set.ListDatabaseCharacterSetsResponse( + database_character_sets=[ + database_character_set.DatabaseCharacterSet(), + database_character_set.DatabaseCharacterSet(), + ], + ), + RuntimeError, + ) + pages = [] + async for page_ in ( + await client.list_database_character_sets(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token - client.stop_autonomous_database(request) - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 +@pytest.mark.parametrize( + "request_type", + [ + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest(), + {}, + ], +) +def test_list_goldengate_connection_assignments(request_type, transport: str = "grpc"): + client = OracleDatabaseClient( + 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 -def test_stop_autonomous_database_rest_required_fields( - request_type=oracledatabase.StopAutonomousDatabaseRequest, -): - transport_class = transports.OracleDatabaseRestTransport + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connection_assignments), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + response = client.list_goldengate_connection_assignments(request) - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).stop_autonomous_database._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["name"] = "name_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).stop_autonomous_database._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" - - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "post", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - response = client.stop_autonomous_database(request) - - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) - - -def test_stop_autonomous_database_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest() + assert args[0] == request - unset_fields = transport.stop_autonomous_database._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListGoldengateConnectionAssignmentsPager) + assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] -def test_stop_autonomous_database_rest_flattened(): +def test_list_goldengate_connection_assignments_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" - } - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - client.stop_autonomous_database(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/autonomousDatabases/*}:stop" - % client.transport._host, - args[1], + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = ( + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest( + parent="parent_value", + page_token="page_token_value", + filter="filter_value", + order_by="order_by_value", ) - - -def test_stop_autonomous_database_rest_flattened_error(transport: str = "rest"): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, ) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.stop_autonomous_database( - oracledatabase.StopAutonomousDatabaseRequest(), - name="name_value", + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connection_assignments), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.list_goldengate_connection_assignments(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ( + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest( + parent="parent_value", + page_token="page_token_value", + filter="filter_value", + order_by="order_by_value", + ) ) + assert args[0] == request_msg -def test_start_autonomous_database_rest_use_cached_wrapped_rpc(): +def test_list_goldengate_connection_assignments_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) # Should wrap all calls on client creation @@ -32060,7 +34205,7 @@ def test_start_autonomous_database_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.start_autonomous_database + client._transport.list_goldengate_connection_assignments in client._transport._wrapped_methods ) @@ -32070,173 +34215,31 @@ def test_start_autonomous_database_rest_use_cached_wrapped_rpc(): "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ - client._transport.start_autonomous_database + client._transport.list_goldengate_connection_assignments ] = mock_rpc - request = {} - client.start_autonomous_database(request) + client.list_goldengate_connection_assignments(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.start_autonomous_database(request) + client.list_goldengate_connection_assignments(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_start_autonomous_database_rest_required_fields( - request_type=oracledatabase.StartAutonomousDatabaseRequest, +@pytest.mark.asyncio +async def test_list_goldengate_connection_assignments_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", ): - transport_class = transports.OracleDatabaseRestTransport - - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).start_autonomous_database._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["name"] = "name_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).start_autonomous_database._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" - - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "post", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - response = client.start_autonomous_database(request) - - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) - - -def test_start_autonomous_database_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.start_autonomous_database._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) - - -def test_start_autonomous_database_rest_flattened(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" - } - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - client.start_autonomous_database(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/autonomousDatabases/*}:start" - % client.transport._host, - args[1], - ) - - -def test_start_autonomous_database_rest_flattened_error(transport: str = "rest"): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.start_autonomous_database( - oracledatabase.StartAutonomousDatabaseRequest(), - name="name_value", - ) - - -def test_restart_autonomous_database_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, ) # Should wrap all calls on client creation @@ -32245,386 +34248,530 @@ def test_restart_autonomous_database_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.restart_autonomous_database - in client._transport._wrapped_methods + client._client._transport.list_goldengate_connection_assignments + in client._client._transport._wrapped_methods ) # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[ - client._transport.restart_autonomous_database + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.list_goldengate_connection_assignments ] = mock_rpc request = {} - client.restart_autonomous_database(request) + await client.list_goldengate_connection_assignments(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.restart_autonomous_database(request) + await client.list_goldengate_connection_assignments(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_restart_autonomous_database_rest_required_fields( - request_type=oracledatabase.RestartAutonomousDatabaseRequest, +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest(), + {}, + ], +) +async def test_list_goldengate_connection_assignments_async( + request_type, transport: str = "grpc_asyncio" ): - transport_class = transports.OracleDatabaseRestTransport - - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, ) - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).restart_autonomous_database._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # 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 - # verify required fields with default values are now present + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connection_assignments), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + response = await client.list_goldengate_connection_assignments(request) - jsonified_request["name"] = "name_value" + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest() + assert args[0] == request - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).restart_autonomous_database._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListGoldengateConnectionAssignmentsAsyncPager) + assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" +def test_list_goldengate_connection_assignments_field_headers(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - request = request_type(**request_init) - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "post", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result + # 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 = ( + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest() + ) - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) + request.parent = "parent_value" - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connection_assignments), "__call__" + ) as call: + call.return_value = goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse() + client.list_goldengate_connection_assignments(request) - response = client.restart_autonomous_database(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 - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + # 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_restart_autonomous_database_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials +@pytest.mark.asyncio +async def test_list_goldengate_connection_assignments_field_headers_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - unset_fields = transport.restart_autonomous_database._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + # 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 = ( + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest() + ) + request.parent = "parent_value" -def test_restart_autonomous_database_rest_flattened(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connection_assignments), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse() + ) + await client.list_goldengate_connection_assignments(request) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request - # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" - } + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} +def test_list_goldengate_connection_assignments_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + ) - client.restart_autonomous_database(**mock_args) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connection_assignments), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_goldengate_connection_assignments( + parent="parent_value", + ) # Establish that the underlying call was made with the expected # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/autonomousDatabases/*}:restart" - % client.transport._host, - args[1], - ) + 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_restart_autonomous_database_rest_flattened_error(transport: str = "rest"): +def test_list_goldengate_connection_assignments_flattened_error(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, ) # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.restart_autonomous_database( - oracledatabase.RestartAutonomousDatabaseRequest(), - name="name_value", + client.list_goldengate_connection_assignments( + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest(), + parent="parent_value", ) -def test_switchover_autonomous_database_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) +@pytest.mark.asyncio +async def test_list_goldengate_connection_assignments_flattened_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connection_assignments), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse() - # Ensure method has been cached - assert ( - client._transport.switchover_autonomous_database - in client._transport._wrapped_methods + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse() ) - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_goldengate_connection_assignments( + parent="parent_value", ) - client._transport._wrapped_methods[ - client._transport.switchover_autonomous_database - ] = mock_rpc - - request = {} - client.switchover_autonomous_database(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() + # 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 - client.switchover_autonomous_database(request) - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 +@pytest.mark.asyncio +async def test_list_goldengate_connection_assignments_flattened_error_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_goldengate_connection_assignments( + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest(), + parent="parent_value", + ) -def test_switchover_autonomous_database_rest_required_fields( - request_type=oracledatabase.SwitchoverAutonomousDatabaseRequest, -): - transport_class = transports.OracleDatabaseRestTransport - request_init = {} - request_init["name"] = "" - request_init["peer_autonomous_database"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) +def test_list_goldengate_connection_assignments_pager(transport_name: str = "grpc"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, ) - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).switchover_autonomous_database._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connection_assignments), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse( + goldengate_connection_assignments=[ + goldengate_connection_assignment.GoldengateConnectionAssignment(), + goldengate_connection_assignment.GoldengateConnectionAssignment(), + goldengate_connection_assignment.GoldengateConnectionAssignment(), + ], + next_page_token="abc", + ), + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse( + goldengate_connection_assignments=[], + next_page_token="def", + ), + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse( + goldengate_connection_assignments=[ + goldengate_connection_assignment.GoldengateConnectionAssignment(), + ], + next_page_token="ghi", + ), + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse( + goldengate_connection_assignments=[ + goldengate_connection_assignment.GoldengateConnectionAssignment(), + goldengate_connection_assignment.GoldengateConnectionAssignment(), + ], + ), + RuntimeError, + ) - # verify required fields with default values are now present + expected_metadata = () + retry = retries.Retry() + timeout = 5 + expected_metadata = tuple(expected_metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_goldengate_connection_assignments( + request={}, retry=retry, timeout=timeout + ) - jsonified_request["name"] = "name_value" - jsonified_request["peerAutonomousDatabase"] = "peer_autonomous_database_value" + assert pager._metadata == expected_metadata + assert pager._retry == retry + assert pager._timeout == timeout - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).switchover_autonomous_database._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + results = list(pager) + assert len(results) == 6 + assert all( + isinstance( + i, goldengate_connection_assignment.GoldengateConnectionAssignment + ) + for i in results + ) - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" - assert "peerAutonomousDatabase" in jsonified_request - assert ( - jsonified_request["peerAutonomousDatabase"] == "peer_autonomous_database_value" - ) +def test_list_goldengate_connection_assignments_pages(transport_name: str = "grpc"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport=transport_name, ) - request = request_type(**request_init) - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "post", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connection_assignments), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse( + goldengate_connection_assignments=[ + goldengate_connection_assignment.GoldengateConnectionAssignment(), + goldengate_connection_assignment.GoldengateConnectionAssignment(), + goldengate_connection_assignment.GoldengateConnectionAssignment(), + ], + next_page_token="abc", + ), + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse( + goldengate_connection_assignments=[], + next_page_token="def", + ), + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse( + goldengate_connection_assignments=[ + goldengate_connection_assignment.GoldengateConnectionAssignment(), + ], + next_page_token="ghi", + ), + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse( + goldengate_connection_assignments=[ + goldengate_connection_assignment.GoldengateConnectionAssignment(), + goldengate_connection_assignment.GoldengateConnectionAssignment(), + ], + ), + RuntimeError, + ) + pages = list(client.list_goldengate_connection_assignments(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} +@pytest.mark.asyncio +async def test_list_goldengate_connection_assignments_async_pager(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) - response = client.switchover_autonomous_database(request) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connection_assignments), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse( + goldengate_connection_assignments=[ + goldengate_connection_assignment.GoldengateConnectionAssignment(), + goldengate_connection_assignment.GoldengateConnectionAssignment(), + goldengate_connection_assignment.GoldengateConnectionAssignment(), + ], + next_page_token="abc", + ), + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse( + goldengate_connection_assignments=[], + next_page_token="def", + ), + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse( + goldengate_connection_assignments=[ + goldengate_connection_assignment.GoldengateConnectionAssignment(), + ], + next_page_token="ghi", + ), + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse( + goldengate_connection_assignments=[ + goldengate_connection_assignment.GoldengateConnectionAssignment(), + goldengate_connection_assignment.GoldengateConnectionAssignment(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_goldengate_connection_assignments( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + assert len(responses) == 6 + assert all( + isinstance( + i, goldengate_connection_assignment.GoldengateConnectionAssignment + ) + for i in responses + ) -def test_switchover_autonomous_database_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials +@pytest.mark.asyncio +async def test_list_goldengate_connection_assignments_async_pages(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - unset_fields = transport.switchover_autonomous_database._get_unset_required_fields( - {} - ) - assert set(unset_fields) == ( - set(()) - & set( - ( - "name", - "peerAutonomousDatabase", - ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connection_assignments), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse( + goldengate_connection_assignments=[ + goldengate_connection_assignment.GoldengateConnectionAssignment(), + goldengate_connection_assignment.GoldengateConnectionAssignment(), + goldengate_connection_assignment.GoldengateConnectionAssignment(), + ], + next_page_token="abc", + ), + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse( + goldengate_connection_assignments=[], + next_page_token="def", + ), + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse( + goldengate_connection_assignments=[ + goldengate_connection_assignment.GoldengateConnectionAssignment(), + ], + next_page_token="ghi", + ), + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse( + goldengate_connection_assignments=[ + goldengate_connection_assignment.GoldengateConnectionAssignment(), + goldengate_connection_assignment.GoldengateConnectionAssignment(), + ], + ), + RuntimeError, ) - ) + pages = [] + async for page_ in ( + await client.list_goldengate_connection_assignments(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token -def test_switchover_autonomous_database_rest_flattened(): +@pytest.mark.parametrize( + "request_type", + [ + goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest(), + {}, + ], +) +def test_get_goldengate_connection_assignment(request_type, transport: str = "grpc"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport=transport, ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" - } + # 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 - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - peer_autonomous_database="peer_autonomous_database_value", + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_connection_assignment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + goldengate_connection_assignment.GoldengateConnectionAssignment( + name="name_value", + display_name="display_name_value", + entitlement_id="entitlement_id_value", + ) ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_goldengate_connection_assignment(request) - client.switchover_autonomous_database(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/autonomousDatabases/*}:switchover" - % client.transport._host, - args[1], + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = ( + goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest() ) + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance( + response, goldengate_connection_assignment.GoldengateConnectionAssignment + ) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.entitlement_id == "entitlement_id_value" -def test_switchover_autonomous_database_rest_flattened_error(transport: str = "rest"): +def test_get_goldengate_connection_assignment_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport="grpc", ) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.switchover_autonomous_database( - oracledatabase.SwitchoverAutonomousDatabaseRequest(), - name="name_value", - peer_autonomous_database="peer_autonomous_database_value", + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest( + name="name_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_connection_assignment), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.get_goldengate_connection_assignment(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ( + goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest( + name="name_value", + ) ) + assert args[0] == request_msg -def test_failover_autonomous_database_rest_use_cached_wrapped_rpc(): +def test_get_goldengate_connection_assignment_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) # Should wrap all calls on client creation @@ -32633,7 +34780,7 @@ def test_failover_autonomous_database_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.failover_autonomous_database + client._transport.get_goldengate_connection_assignment in client._transport._wrapped_methods ) @@ -32643,189 +34790,350 @@ def test_failover_autonomous_database_rest_use_cached_wrapped_rpc(): "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ - client._transport.failover_autonomous_database + client._transport.get_goldengate_connection_assignment ] = mock_rpc - request = {} - client.failover_autonomous_database(request) + client.get_goldengate_connection_assignment(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.failover_autonomous_database(request) + client.get_goldengate_connection_assignment(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_failover_autonomous_database_rest_required_fields( - request_type=oracledatabase.FailoverAutonomousDatabaseRequest, +@pytest.mark.asyncio +async def test_get_goldengate_connection_assignment_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", ): - transport_class = transports.OracleDatabaseRestTransport - - request_init = {} - request_init["name"] = "" - request_init["peer_autonomous_database"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).failover_autonomous_database._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["name"] = "name_value" - jsonified_request["peerAutonomousDatabase"] = "peer_autonomous_database_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).failover_autonomous_database._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" - assert "peerAutonomousDatabase" in jsonified_request - assert ( - jsonified_request["peerAutonomousDatabase"] == "peer_autonomous_database_value" - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) + # Ensure method has been cached + assert ( + client._client._transport.get_goldengate_connection_assignment + in client._client._transport._wrapped_methods + ) - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "post", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.get_goldengate_connection_assignment + ] = mock_rpc - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) + request = {} + await client.get_goldengate_connection_assignment(request) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - response = client.failover_autonomous_database(request) + await client.get_goldengate_connection_assignment(request) - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 -def test_failover_autonomous_database_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest(), + {}, + ], +) +async def test_get_goldengate_connection_assignment_async( + request_type, transport: str = "grpc_asyncio" +): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, ) - unset_fields = transport.failover_autonomous_database._get_unset_required_fields({}) - assert set(unset_fields) == ( - set(()) - & set( - ( - "name", - "peerAutonomousDatabase", + # 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_goldengate_connection_assignment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_connection_assignment.GoldengateConnectionAssignment( + name="name_value", + display_name="display_name_value", + entitlement_id="entitlement_id_value", ) ) + response = await client.get_goldengate_connection_assignment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = ( + goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest() + ) + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance( + response, goldengate_connection_assignment.GoldengateConnectionAssignment ) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.entitlement_id == "entitlement_id_value" -def test_failover_autonomous_database_rest_flattened(): +def test_get_goldengate_connection_assignment_field_headers(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + # 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 = ( + goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest() + ) - # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" - } + request.name = "name_value" - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - peer_autonomous_database="peer_autonomous_database_value", + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_connection_assignment), "__call__" + ) as call: + call.return_value = ( + goldengate_connection_assignment.GoldengateConnectionAssignment() ) - mock_args.update(sample_request) + client.get_goldengate_connection_assignment(request) - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request - client.failover_autonomous_database(**mock_args) + # 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_goldengate_connection_assignment_field_headers_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = ( + goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest() + ) + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_connection_assignment), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_connection_assignment.GoldengateConnectionAssignment() + ) + await client.get_goldengate_connection_assignment(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_goldengate_connection_assignment_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_connection_assignment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + goldengate_connection_assignment.GoldengateConnectionAssignment() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_goldengate_connection_assignment( + name="name_value", + ) # Establish that the underlying call was made with the expected # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/autonomousDatabases/*}:failover" - % client.transport._host, - args[1], - ) + 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_failover_autonomous_database_rest_flattened_error(transport: str = "rest"): +def test_get_goldengate_connection_assignment_flattened_error(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, ) # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.failover_autonomous_database( - oracledatabase.FailoverAutonomousDatabaseRequest(), + client.get_goldengate_connection_assignment( + goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest(), name="name_value", - peer_autonomous_database="peer_autonomous_database_value", ) -def test_list_odb_networks_rest_use_cached_wrapped_rpc(): +@pytest.mark.asyncio +async def test_get_goldengate_connection_assignment_flattened_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_connection_assignment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + goldengate_connection_assignment.GoldengateConnectionAssignment() + ) + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_connection_assignment.GoldengateConnectionAssignment() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_goldengate_connection_assignment( + 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_goldengate_connection_assignment_flattened_error_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_goldengate_connection_assignment( + goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest(), + {}, + ], +) +def test_create_goldengate_connection_assignment(request_type, transport: str = "grpc"): + client = OracleDatabaseClient( + 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_goldengate_connection_assignment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.create_goldengate_connection_assignment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_create_goldengate_connection_assignment_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest( + parent="parent_value", + goldengate_connection_assignment_id="goldengate_connection_assignment_id_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_goldengate_connection_assignment), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.create_goldengate_connection_assignment(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest( + parent="parent_value", + goldengate_connection_assignment_id="goldengate_connection_assignment_id_value", + ) + assert args[0] == request_msg + + +def test_create_goldengate_connection_assignment_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) # Should wrap all calls on client creation @@ -32833,261 +35141,382 @@ def test_list_odb_networks_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.list_odb_networks in client._transport._wrapped_methods + assert ( + client._transport.create_goldengate_connection_assignment + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.list_odb_networks] = ( - mock_rpc - ) - + client._transport._wrapped_methods[ + client._transport.create_goldengate_connection_assignment + ] = mock_rpc request = {} - client.list_odb_networks(request) + client.create_goldengate_connection_assignment(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_odb_networks(request) + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.create_goldengate_connection_assignment(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_odb_networks_rest_required_fields( - request_type=odb_network.ListOdbNetworksRequest, +@pytest.mark.asyncio +async def test_create_goldengate_connection_assignment_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", ): - transport_class = transports.OracleDatabaseRestTransport + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - request_init = {} - request_init["parent"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # verify fields with default values are dropped + # Ensure method has been cached + assert ( + client._client._transport.create_goldengate_connection_assignment + in client._client._transport._wrapped_methods + ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_odb_networks._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.create_goldengate_connection_assignment + ] = mock_rpc - # verify required fields with default values are now present + request = {} + await client.create_goldengate_connection_assignment(request) - jsonified_request["parent"] = "parent_value" + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_odb_networks._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "filter", - "order_by", - "page_size", - "page_token", - ) + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + await client.create_goldengate_connection_assignment(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest(), + {}, + ], +) +async def test_create_goldengate_connection_assignment_async( + request_type, transport: str = "grpc_asyncio" +): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, ) - jsonified_request.update(unset_fields) - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" + # 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_goldengate_connection_assignment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + response = await client.create_goldengate_connection_assignment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + +def test_create_goldengate_connection_assignment_field_headers(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = odb_network.ListOdbNetworksResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - response_value = Response() - response_value.status_code = 200 + # 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 = gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest() - # Convert return value to protobuf type - return_value = odb_network.ListOdbNetworksResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + request.parent = "parent_value" - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_goldengate_connection_assignment), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_goldengate_connection_assignment(request) - response = client.list_odb_networks(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 - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + # 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_odb_networks_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials +@pytest.mark.asyncio +async def test_create_goldengate_connection_assignment_field_headers_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - unset_fields = transport.list_odb_networks._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "filter", - "orderBy", - "pageSize", - "pageToken", - ) + # 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 = gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_goldengate_connection_assignment), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") ) - & set(("parent",)) - ) + await client.create_goldengate_connection_assignment(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request -def test_list_odb_networks_rest_flattened(): + # 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_goldengate_connection_assignment_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = odb_network.ListOdbNetworksResponse() + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_goldengate_connection_assignment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_goldengate_connection_assignment( + parent="parent_value", + goldengate_connection_assignment=gco_goldengate_connection_assignment.GoldengateConnectionAssignment( + name="name_value" + ), + goldengate_connection_assignment_id="goldengate_connection_assignment_id_value", + ) - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} + # 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].goldengate_connection_assignment + mock_val = gco_goldengate_connection_assignment.GoldengateConnectionAssignment( + name="name_value" + ) + assert arg == mock_val + arg = args[0].goldengate_connection_assignment_id + mock_val = "goldengate_connection_assignment_id_value" + assert arg == mock_val - # get truthy value for each flattened field - mock_args = dict( + +def test_create_goldengate_connection_assignment_flattened_error(): + client = OracleDatabaseClient( + 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_goldengate_connection_assignment( + gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest(), parent="parent_value", + goldengate_connection_assignment=gco_goldengate_connection_assignment.GoldengateConnectionAssignment( + name="name_value" + ), + goldengate_connection_assignment_id="goldengate_connection_assignment_id_value", ) - mock_args.update(sample_request) - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = odb_network.ListOdbNetworksResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_odb_networks(**mock_args) +@pytest.mark.asyncio +async def test_create_goldengate_connection_assignment_flattened_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_goldengate_connection_assignment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_goldengate_connection_assignment( + parent="parent_value", + goldengate_connection_assignment=gco_goldengate_connection_assignment.GoldengateConnectionAssignment( + name="name_value" + ), + goldengate_connection_assignment_id="goldengate_connection_assignment_id_value", + ) # Establish that the underlying call was made with the expected # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/odbNetworks" - % client.transport._host, - args[1], + 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].goldengate_connection_assignment + mock_val = gco_goldengate_connection_assignment.GoldengateConnectionAssignment( + name="name_value" ) + assert arg == mock_val + arg = args[0].goldengate_connection_assignment_id + mock_val = "goldengate_connection_assignment_id_value" + assert arg == mock_val -def test_list_odb_networks_rest_flattened_error(transport: str = "rest"): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, +@pytest.mark.asyncio +async def test_create_goldengate_connection_assignment_flattened_error_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_odb_networks( - odb_network.ListOdbNetworksRequest(), + await client.create_goldengate_connection_assignment( + gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest(), parent="parent_value", + goldengate_connection_assignment=gco_goldengate_connection_assignment.GoldengateConnectionAssignment( + name="name_value" + ), + goldengate_connection_assignment_id="goldengate_connection_assignment_id_value", ) -def test_list_odb_networks_rest_pager(transport: str = "rest"): +@pytest.mark.parametrize( + "request_type", + [ + goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest(), + {}, + ], +) +def test_delete_goldengate_connection_assignment(request_type, transport: str = "grpc"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - odb_network.ListOdbNetworksResponse( - odb_networks=[ - odb_network.OdbNetwork(), - odb_network.OdbNetwork(), - odb_network.OdbNetwork(), - ], - next_page_token="abc", - ), - odb_network.ListOdbNetworksResponse( - odb_networks=[], - next_page_token="def", - ), - odb_network.ListOdbNetworksResponse( - odb_networks=[ - odb_network.OdbNetwork(), - ], - next_page_token="ghi", - ), - odb_network.ListOdbNetworksResponse( - odb_networks=[ - odb_network.OdbNetwork(), - odb_network.OdbNetwork(), - ], - ), - ) - # Two responses for two calls - response = response + response + # 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 - # Wrap the values into proper Response objs - response = tuple( - odb_network.ListOdbNetworksResponse.to_json(x) for x in response - ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_goldengate_connection_assignment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.delete_goldengate_connection_assignment(request) - sample_request = {"parent": "projects/sample1/locations/sample2"} + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest() + assert args[0] == request - pager = client.list_odb_networks(request=sample_request) + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, odb_network.OdbNetwork) for i in results) - pages = list(client.list_odb_networks(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token +def test_delete_goldengate_connection_assignment_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = ( + goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest( + name="name_value", + ) + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_goldengate_connection_assignment), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.delete_goldengate_connection_assignment(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest( + name="name_value", + ) + assert args[0] == request_msg -def test_get_odb_network_rest_use_cached_wrapped_rpc(): +def test_delete_goldengate_connection_assignment_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) # Should wrap all calls on client creation @@ -33095,179 +35524,367 @@ def test_get_odb_network_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.get_odb_network in client._transport._wrapped_methods + assert ( + client._transport.delete_goldengate_connection_assignment + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.get_odb_network] = mock_rpc - + client._transport._wrapped_methods[ + client._transport.delete_goldengate_connection_assignment + ] = mock_rpc request = {} - client.get_odb_network(request) + client.delete_goldengate_connection_assignment(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.get_odb_network(request) + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_goldengate_connection_assignment(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_get_odb_network_rest_required_fields( - request_type=odb_network.GetOdbNetworkRequest, +@pytest.mark.asyncio +async def test_delete_goldengate_connection_assignment_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", ): - transport_class = transports.OracleDatabaseRestTransport + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # verify fields with default values are dropped + # Ensure method has been cached + assert ( + client._client._transport.delete_goldengate_connection_assignment + in client._client._transport._wrapped_methods + ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_odb_network._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.delete_goldengate_connection_assignment + ] = mock_rpc - # verify required fields with default values are now present + request = {} + await client.delete_goldengate_connection_assignment(request) - jsonified_request["name"] = "name_value" + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_odb_network._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + await client.delete_goldengate_connection_assignment(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest(), + {}, + ], +) +async def test_delete_goldengate_connection_assignment_async( + request_type, transport: str = "grpc_asyncio" +): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + 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_goldengate_connection_assignment), "__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.delete_goldengate_connection_assignment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + +def test_delete_goldengate_connection_assignment_field_headers(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - request = request_type(**request_init) - # Designate an appropriate value for the returned response. - return_value = odb_network.OdbNetwork() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result + # 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 = ( + goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest() + ) - response_value = Response() - response_value.status_code = 200 + request.name = "name_value" - # Convert return value to protobuf type - return_value = odb_network.OdbNetwork.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_goldengate_connection_assignment), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_goldengate_connection_assignment(request) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request - response = client.get_odb_network(request) + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) +@pytest.mark.asyncio +async def test_delete_goldengate_connection_assignment_field_headers_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) -def test_get_odb_network_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - 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 = ( + goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest() ) - unset_fields = transport.get_odb_network._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_goldengate_connection_assignment), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.delete_goldengate_connection_assignment(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request -def test_get_odb_network_rest_flattened(): + # 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_goldengate_connection_assignment_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = odb_network.OdbNetwork() + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_goldengate_connection_assignment), "__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.delete_goldengate_connection_assignment( + name="name_value", + ) - # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/odbNetworks/sample3" - } + # 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 - # get truthy value for each flattened field - mock_args = dict( + +def test_delete_goldengate_connection_assignment_flattened_error(): + client = OracleDatabaseClient( + 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_goldengate_connection_assignment( + goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest(), name="name_value", ) - mock_args.update(sample_request) - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = odb_network.OdbNetwork.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_odb_network(**mock_args) +@pytest.mark.asyncio +async def test_delete_goldengate_connection_assignment_flattened_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_goldengate_connection_assignment), "__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.delete_goldengate_connection_assignment( + name="name_value", + ) # Establish that the underlying call was made with the expected # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/odbNetworks/*}" - % client.transport._host, - args[1], + 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_goldengate_connection_assignment_flattened_error_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_goldengate_connection_assignment( + goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest(), + name="name_value", ) -def test_get_odb_network_rest_flattened_error(transport: str = "rest"): +@pytest.mark.parametrize( + "request_type", + [ + goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest(), + {}, + ], +) +def test_test_goldengate_connection_assignment(request_type, transport: str = "grpc"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.get_odb_network( - odb_network.GetOdbNetworkRequest(), + # 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.test_goldengate_connection_assignment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse( + result_type=goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse.ResultType.SUCCEEDED, + ) + response = client.test_goldengate_connection_assignment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = ( + goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest() + ) + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance( + response, + goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse, + ) + assert ( + response.result_type + == goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse.ResultType.SUCCEEDED + ) + + +def test_test_goldengate_connection_assignment_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = ( + goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest( name="name_value", ) + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.test_goldengate_connection_assignment), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.test_goldengate_connection_assignment(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ( + goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest( + name="name_value", + ) + ) + assert args[0] == request_msg -def test_create_odb_network_rest_use_cached_wrapped_rpc(): +def test_test_goldengate_connection_assignment_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) # Should wrap all calls on client creation @@ -33276,7 +35893,8 @@ def test_create_odb_network_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.create_odb_network in client._transport._wrapped_methods + client._transport.test_goldengate_connection_assignment + in client._transport._wrapped_methods ) # Replace cached wrapped function with mock @@ -33284,389 +35902,271 @@ def test_create_odb_network_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.create_odb_network] = ( - mock_rpc - ) - + client._transport._wrapped_methods[ + client._transport.test_goldengate_connection_assignment + ] = mock_rpc request = {} - client.create_odb_network(request) + client.test_goldengate_connection_assignment(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.create_odb_network(request) + client.test_goldengate_connection_assignment(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_create_odb_network_rest_required_fields( - request_type=gco_odb_network.CreateOdbNetworkRequest, +@pytest.mark.asyncio +async def test_test_goldengate_connection_assignment_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", ): - transport_class = transports.OracleDatabaseRestTransport + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - request_init = {} - request_init["parent"] = "" - request_init["odb_network_id"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # verify fields with default values are dropped - assert "odbNetworkId" not in jsonified_request + # Ensure method has been cached + assert ( + client._client._transport.test_goldengate_connection_assignment + in client._client._transport._wrapped_methods + ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).create_odb_network._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.test_goldengate_connection_assignment + ] = mock_rpc - # verify required fields with default values are now present - assert "odbNetworkId" in jsonified_request - assert jsonified_request["odbNetworkId"] == request_init["odb_network_id"] + request = {} + await client.test_goldengate_connection_assignment(request) - jsonified_request["parent"] = "parent_value" - jsonified_request["odbNetworkId"] = "odb_network_id_value" + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).create_odb_network._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "odb_network_id", - "request_id", - ) - ) - jsonified_request.update(unset_fields) + await client.test_goldengate_connection_assignment(request) - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" - assert "odbNetworkId" in jsonified_request - assert jsonified_request["odbNetworkId"] == "odb_network_id_value" + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "post", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - response = client.create_odb_network(request) - - expected_params = [ - ( - "odbNetworkId", - "", - ), - ("$alt", "json;enum-encoding=int"), - ] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) - - -def test_create_odb_network_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest(), + {}, + ], +) +async def test_test_goldengate_connection_assignment_async( + request_type, transport: str = "grpc_asyncio" +): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, ) - unset_fields = transport.create_odb_network._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "odbNetworkId", - "requestId", - ) - ) - & set( - ( - "parent", - "odbNetworkId", - "odbNetwork", + # 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.test_goldengate_connection_assignment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse( + result_type=goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse.ResultType.SUCCEEDED, ) ) - ) - - -def test_create_odb_network_rest_flattened(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} + response = await client.test_goldengate_connection_assignment(request) - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", - odb_network=gco_odb_network.OdbNetwork(name="name_value"), - odb_network_id="odb_network_id_value", + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = ( + goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest() ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - client.create_odb_network(**mock_args) + assert args[0] == request - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/odbNetworks" - % client.transport._host, - args[1], - ) + # Establish that the response is the type that we expect. + assert isinstance( + response, + goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse, + ) + assert ( + response.result_type + == goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse.ResultType.SUCCEEDED + ) -def test_create_odb_network_rest_flattened_error(transport: str = "rest"): +def test_test_goldengate_connection_assignment_field_headers(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, ) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.create_odb_network( - gco_odb_network.CreateOdbNetworkRequest(), - parent="parent_value", - odb_network=gco_odb_network.OdbNetwork(name="name_value"), - odb_network_id="odb_network_id_value", - ) - - -def test_delete_odb_network_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert ( - client._transport.delete_odb_network in client._transport._wrapped_methods - ) + # 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 = ( + goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest() + ) - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[client._transport.delete_odb_network] = ( - mock_rpc - ) + request.name = "name_value" - request = {} - client.delete_odb_network(request) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.test_goldengate_connection_assignment), "__call__" + ) as call: + call.return_value = goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse() + client.test_goldengate_connection_assignment(request) # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.delete_odb_network(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 + 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"] -def test_delete_odb_network_rest_required_fields( - request_type=odb_network.DeleteOdbNetworkRequest, -): - transport_class = transports.OracleDatabaseRestTransport - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) +@pytest.mark.asyncio +async def test_test_goldengate_connection_assignment_field_headers_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - # verify fields with default values are dropped + # 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 = ( + goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest() + ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).delete_odb_network._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + request.name = "name_value" - # verify required fields with default values are now present + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.test_goldengate_connection_assignment), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse() + ) + await client.test_goldengate_connection_assignment(request) - jsonified_request["name"] = "name_value" + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).delete_odb_network._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("request_id",)) - jsonified_request.update(unset_fields) + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" +def test_test_goldengate_connection_assignment_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "delete", - "query_params": pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_odb_network(request) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.test_goldengate_connection_assignment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.test_goldengate_connection_assignment( + name="name_value", + ) - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + # 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_odb_network_rest_unset_required_fields(): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials +def test_test_goldengate_connection_assignment_flattened_error(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), ) - unset_fields = transport.delete_odb_network._get_unset_required_fields({}) - assert set(unset_fields) == (set(("requestId",)) & set(("name",))) + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.test_goldengate_connection_assignment( + goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest(), + name="name_value", + ) -def test_delete_odb_network_rest_flattened(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", +@pytest.mark.asyncio +async def test_test_goldengate_connection_assignment_flattened_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/odbNetworks/sample3" - } + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.test_goldengate_connection_assignment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse() - # get truthy value for each flattened field - mock_args = dict( + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.test_goldengate_connection_assignment( name="name_value", ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - client.delete_odb_network(**mock_args) # Establish that the underlying call was made with the expected # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/odbNetworks/*}" - % client.transport._host, - args[1], - ) + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val -def test_delete_odb_network_rest_flattened_error(transport: str = "rest"): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, +@pytest.mark.asyncio +async def test_test_goldengate_connection_assignment_flattened_error_async(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.delete_odb_network( - odb_network.DeleteOdbNetworkRequest(), + await client.test_goldengate_connection_assignment( + goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest(), name="name_value", ) -def test_list_odb_subnets_rest_use_cached_wrapped_rpc(): +def test_list_cloud_exadata_infrastructures_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -33680,32 +36180,35 @@ def test_list_odb_subnets_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.list_odb_subnets in client._transport._wrapped_methods + assert ( + client._transport.list_cloud_exadata_infrastructures + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.list_odb_subnets] = ( - mock_rpc - ) + client._transport._wrapped_methods[ + client._transport.list_cloud_exadata_infrastructures + ] = mock_rpc request = {} - client.list_odb_subnets(request) + client.list_cloud_exadata_infrastructures(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_odb_subnets(request) + client.list_cloud_exadata_infrastructures(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_odb_subnets_rest_required_fields( - request_type=odb_subnet.ListOdbSubnetsRequest, +def test_list_cloud_exadata_infrastructures_rest_required_fields( + request_type=oracledatabase.ListCloudExadataInfrastructuresRequest, ): transport_class = transports.OracleDatabaseRestTransport @@ -33721,7 +36224,7 @@ def test_list_odb_subnets_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_odb_subnets._get_unset_required_fields(jsonified_request) + ).list_cloud_exadata_infrastructures._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -33730,7 +36233,7 @@ def test_list_odb_subnets_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_odb_subnets._get_unset_required_fields(jsonified_request) + ).list_cloud_exadata_infrastructures._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. assert not set(unset_fields) - set( ( @@ -33753,7 +36256,7 @@ def test_list_odb_subnets_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = odb_subnet.ListOdbSubnetsResponse() + return_value = oracledatabase.ListCloudExadataInfrastructuresResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -33774,26 +36277,30 @@ def test_list_odb_subnets_rest_required_fields( response_value.status_code = 200 # Convert return value to protobuf type - return_value = odb_subnet.ListOdbSubnetsResponse.pb(return_value) + return_value = oracledatabase.ListCloudExadataInfrastructuresResponse.pb( + return_value + ) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_odb_subnets(request) + response = client.list_cloud_exadata_infrastructures(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_list_odb_subnets_rest_unset_required_fields(): +def test_list_cloud_exadata_infrastructures_rest_unset_required_fields(): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.list_odb_subnets._get_unset_required_fields({}) + unset_fields = ( + transport.list_cloud_exadata_infrastructures._get_unset_required_fields({}) + ) assert set(unset_fields) == ( set( ( @@ -33807,7 +36314,7 @@ def test_list_odb_subnets_rest_unset_required_fields(): ) -def test_list_odb_subnets_rest_flattened(): +def test_list_cloud_exadata_infrastructures_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -33816,12 +36323,10 @@ def test_list_odb_subnets_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = odb_subnet.ListOdbSubnetsResponse() + return_value = oracledatabase.ListCloudExadataInfrastructuresResponse() # get arguments that satisfy an http rule for this method - sample_request = { - "parent": "projects/sample1/locations/sample2/odbNetworks/sample3" - } + sample_request = {"parent": "projects/sample1/locations/sample2"} # get truthy value for each flattened field mock_args = dict( @@ -33833,26 +36338,30 @@ def test_list_odb_subnets_rest_flattened(): response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = odb_subnet.ListOdbSubnetsResponse.pb(return_value) + return_value = oracledatabase.ListCloudExadataInfrastructuresResponse.pb( + return_value + ) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_odb_subnets(**mock_args) + client.list_cloud_exadata_infrastructures(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*/odbNetworks/*}/odbSubnets" + "%s/v1/{parent=projects/*/locations/*}/cloudExadataInfrastructures" % client.transport._host, args[1], ) -def test_list_odb_subnets_rest_flattened_error(transport: str = "rest"): +def test_list_cloud_exadata_infrastructures_rest_flattened_error( + transport: str = "rest", +): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -33861,13 +36370,13 @@ def test_list_odb_subnets_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_odb_subnets( - odb_subnet.ListOdbSubnetsRequest(), + client.list_cloud_exadata_infrastructures( + oracledatabase.ListCloudExadataInfrastructuresRequest(), parent="parent_value", ) -def test_list_odb_subnets_rest_pager(transport: str = "rest"): +def test_list_cloud_exadata_infrastructures_rest_pager(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -33879,28 +36388,28 @@ def test_list_odb_subnets_rest_pager(transport: str = "rest"): # with mock.patch.object(path_template, 'transcode') as transcode: # Set the response as a series of pages response = ( - odb_subnet.ListOdbSubnetsResponse( - odb_subnets=[ - odb_subnet.OdbSubnet(), - odb_subnet.OdbSubnet(), - odb_subnet.OdbSubnet(), + oracledatabase.ListCloudExadataInfrastructuresResponse( + cloud_exadata_infrastructures=[ + exadata_infra.CloudExadataInfrastructure(), + exadata_infra.CloudExadataInfrastructure(), + exadata_infra.CloudExadataInfrastructure(), ], next_page_token="abc", ), - odb_subnet.ListOdbSubnetsResponse( - odb_subnets=[], + oracledatabase.ListCloudExadataInfrastructuresResponse( + cloud_exadata_infrastructures=[], next_page_token="def", ), - odb_subnet.ListOdbSubnetsResponse( - odb_subnets=[ - odb_subnet.OdbSubnet(), + oracledatabase.ListCloudExadataInfrastructuresResponse( + cloud_exadata_infrastructures=[ + exadata_infra.CloudExadataInfrastructure(), ], next_page_token="ghi", ), - odb_subnet.ListOdbSubnetsResponse( - odb_subnets=[ - odb_subnet.OdbSubnet(), - odb_subnet.OdbSubnet(), + oracledatabase.ListCloudExadataInfrastructuresResponse( + cloud_exadata_infrastructures=[ + exadata_infra.CloudExadataInfrastructure(), + exadata_infra.CloudExadataInfrastructure(), ], ), ) @@ -33908,29 +36417,34 @@ def test_list_odb_subnets_rest_pager(transport: str = "rest"): response = response + response # Wrap the values into proper Response objs - response = tuple(odb_subnet.ListOdbSubnetsResponse.to_json(x) for x in response) + response = tuple( + oracledatabase.ListCloudExadataInfrastructuresResponse.to_json(x) + for x in response + ) return_values = tuple(Response() for i in response) for return_val, response_val in zip(return_values, response): return_val._content = response_val.encode("UTF-8") return_val.status_code = 200 req.side_effect = return_values - sample_request = { - "parent": "projects/sample1/locations/sample2/odbNetworks/sample3" - } + sample_request = {"parent": "projects/sample1/locations/sample2"} - pager = client.list_odb_subnets(request=sample_request) + pager = client.list_cloud_exadata_infrastructures(request=sample_request) results = list(pager) assert len(results) == 6 - assert all(isinstance(i, odb_subnet.OdbSubnet) for i in results) + assert all( + isinstance(i, exadata_infra.CloudExadataInfrastructure) for i in results + ) - pages = list(client.list_odb_subnets(request=sample_request).pages) + pages = list( + client.list_cloud_exadata_infrastructures(request=sample_request).pages + ) for page_, token in zip(pages, ["abc", "def", "ghi", ""]): assert page_.raw_page.next_page_token == token -def test_get_odb_subnet_rest_use_cached_wrapped_rpc(): +def test_get_cloud_exadata_infrastructure_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -33944,30 +36458,35 @@ def test_get_odb_subnet_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.get_odb_subnet in client._transport._wrapped_methods + assert ( + client._transport.get_cloud_exadata_infrastructure + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.get_odb_subnet] = mock_rpc + client._transport._wrapped_methods[ + client._transport.get_cloud_exadata_infrastructure + ] = mock_rpc request = {} - client.get_odb_subnet(request) + client.get_cloud_exadata_infrastructure(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.get_odb_subnet(request) + client.get_cloud_exadata_infrastructure(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_get_odb_subnet_rest_required_fields( - request_type=odb_subnet.GetOdbSubnetRequest, +def test_get_cloud_exadata_infrastructure_rest_required_fields( + request_type=oracledatabase.GetCloudExadataInfrastructureRequest, ): transport_class = transports.OracleDatabaseRestTransport @@ -33983,7 +36502,7 @@ def test_get_odb_subnet_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_odb_subnet._get_unset_required_fields(jsonified_request) + ).get_cloud_exadata_infrastructure._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -33992,7 +36511,7 @@ def test_get_odb_subnet_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_odb_subnet._get_unset_required_fields(jsonified_request) + ).get_cloud_exadata_infrastructure._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -34006,7 +36525,7 @@ def test_get_odb_subnet_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = odb_subnet.OdbSubnet() + return_value = exadata_infra.CloudExadataInfrastructure() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -34027,30 +36546,32 @@ def test_get_odb_subnet_rest_required_fields( response_value.status_code = 200 # Convert return value to protobuf type - return_value = odb_subnet.OdbSubnet.pb(return_value) + return_value = exadata_infra.CloudExadataInfrastructure.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_odb_subnet(request) + response = client.get_cloud_exadata_infrastructure(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_get_odb_subnet_rest_unset_required_fields(): +def test_get_cloud_exadata_infrastructure_rest_unset_required_fields(): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.get_odb_subnet._get_unset_required_fields({}) + unset_fields = ( + transport.get_cloud_exadata_infrastructure._get_unset_required_fields({}) + ) assert set(unset_fields) == (set(()) & set(("name",))) -def test_get_odb_subnet_rest_flattened(): +def test_get_cloud_exadata_infrastructure_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -34059,11 +36580,11 @@ def test_get_odb_subnet_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = odb_subnet.OdbSubnet() + return_value = exadata_infra.CloudExadataInfrastructure() # get arguments that satisfy an http rule for this method sample_request = { - "name": "projects/sample1/locations/sample2/odbNetworks/sample3/odbSubnets/sample4" + "name": "projects/sample1/locations/sample2/cloudExadataInfrastructures/sample3" } # get truthy value for each flattened field @@ -34076,26 +36597,26 @@ def test_get_odb_subnet_rest_flattened(): response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = odb_subnet.OdbSubnet.pb(return_value) + return_value = exadata_infra.CloudExadataInfrastructure.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_odb_subnet(**mock_args) + client.get_cloud_exadata_infrastructure(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/odbNetworks/*/odbSubnets/*}" + "%s/v1/{name=projects/*/locations/*/cloudExadataInfrastructures/*}" % client.transport._host, args[1], ) -def test_get_odb_subnet_rest_flattened_error(transport: str = "rest"): +def test_get_cloud_exadata_infrastructure_rest_flattened_error(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -34104,13 +36625,13 @@ def test_get_odb_subnet_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.get_odb_subnet( - odb_subnet.GetOdbSubnetRequest(), + client.get_cloud_exadata_infrastructure( + oracledatabase.GetCloudExadataInfrastructureRequest(), name="name_value", ) -def test_create_odb_subnet_rest_use_cached_wrapped_rpc(): +def test_create_cloud_exadata_infrastructure_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -34124,19 +36645,22 @@ def test_create_odb_subnet_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.create_odb_subnet in client._transport._wrapped_methods + assert ( + client._transport.create_cloud_exadata_infrastructure + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.create_odb_subnet] = ( - mock_rpc - ) + client._transport._wrapped_methods[ + client._transport.create_cloud_exadata_infrastructure + ] = mock_rpc request = {} - client.create_odb_subnet(request) + client.create_cloud_exadata_infrastructure(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 @@ -34145,21 +36669,21 @@ def test_create_odb_subnet_rest_use_cached_wrapped_rpc(): # subsequent calls should use the cached wrapper wrapper_fn.reset_mock() - client.create_odb_subnet(request) + client.create_cloud_exadata_infrastructure(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_create_odb_subnet_rest_required_fields( - request_type=gco_odb_subnet.CreateOdbSubnetRequest, +def test_create_cloud_exadata_infrastructure_rest_required_fields( + request_type=oracledatabase.CreateCloudExadataInfrastructureRequest, ): transport_class = transports.OracleDatabaseRestTransport request_init = {} request_init["parent"] = "" - request_init["odb_subnet_id"] = "" + request_init["cloud_exadata_infrastructure_id"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -34167,27 +36691,32 @@ def test_create_odb_subnet_rest_required_fields( ) # verify fields with default values are dropped - assert "odbSubnetId" not in jsonified_request + assert "cloudExadataInfrastructureId" not in jsonified_request unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_odb_subnet._get_unset_required_fields(jsonified_request) + ).create_cloud_exadata_infrastructure._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - assert "odbSubnetId" in jsonified_request - assert jsonified_request["odbSubnetId"] == request_init["odb_subnet_id"] + assert "cloudExadataInfrastructureId" in jsonified_request + assert ( + jsonified_request["cloudExadataInfrastructureId"] + == request_init["cloud_exadata_infrastructure_id"] + ) jsonified_request["parent"] = "parent_value" - jsonified_request["odbSubnetId"] = "odb_subnet_id_value" + jsonified_request["cloudExadataInfrastructureId"] = ( + "cloud_exadata_infrastructure_id_value" + ) unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_odb_subnet._get_unset_required_fields(jsonified_request) + ).create_cloud_exadata_infrastructure._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. assert not set(unset_fields) - set( ( - "odb_subnet_id", + "cloud_exadata_infrastructure_id", "request_id", ) ) @@ -34196,8 +36725,11 @@ def test_create_odb_subnet_rest_required_fields( # verify required fields with non-default values are left alone assert "parent" in jsonified_request assert jsonified_request["parent"] == "parent_value" - assert "odbSubnetId" in jsonified_request - assert jsonified_request["odbSubnetId"] == "odb_subnet_id_value" + assert "cloudExadataInfrastructureId" in jsonified_request + assert ( + jsonified_request["cloudExadataInfrastructureId"] + == "cloud_exadata_infrastructure_id_value" + ) client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), @@ -34232,11 +36764,11 @@ def test_create_odb_subnet_rest_required_fields( req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_odb_subnet(request) + response = client.create_cloud_exadata_infrastructure(request) expected_params = [ ( - "odbSubnetId", + "cloudExadataInfrastructureId", "", ), ("$alt", "json;enum-encoding=int"), @@ -34245,30 +36777,32 @@ def test_create_odb_subnet_rest_required_fields( assert sorted(expected_params) == sorted(actual_params) -def test_create_odb_subnet_rest_unset_required_fields(): +def test_create_cloud_exadata_infrastructure_rest_unset_required_fields(): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.create_odb_subnet._get_unset_required_fields({}) + unset_fields = ( + transport.create_cloud_exadata_infrastructure._get_unset_required_fields({}) + ) assert set(unset_fields) == ( set( ( - "odbSubnetId", + "cloudExadataInfrastructureId", "requestId", ) ) & set( ( "parent", - "odbSubnetId", - "odbSubnet", + "cloudExadataInfrastructureId", + "cloudExadataInfrastructure", ) ) ) -def test_create_odb_subnet_rest_flattened(): +def test_create_cloud_exadata_infrastructure_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -34280,15 +36814,15 @@ def test_create_odb_subnet_rest_flattened(): return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = { - "parent": "projects/sample1/locations/sample2/odbNetworks/sample3" - } + sample_request = {"parent": "projects/sample1/locations/sample2"} # get truthy value for each flattened field mock_args = dict( parent="parent_value", - odb_subnet=gco_odb_subnet.OdbSubnet(name="name_value"), - odb_subnet_id="odb_subnet_id_value", + cloud_exadata_infrastructure=exadata_infra.CloudExadataInfrastructure( + name="name_value" + ), + cloud_exadata_infrastructure_id="cloud_exadata_infrastructure_id_value", ) mock_args.update(sample_request) @@ -34300,20 +36834,22 @@ def test_create_odb_subnet_rest_flattened(): req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_odb_subnet(**mock_args) + client.create_cloud_exadata_infrastructure(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*/odbNetworks/*}/odbSubnets" + "%s/v1/{parent=projects/*/locations/*}/cloudExadataInfrastructures" % client.transport._host, args[1], ) -def test_create_odb_subnet_rest_flattened_error(transport: str = "rest"): +def test_create_cloud_exadata_infrastructure_rest_flattened_error( + transport: str = "rest", +): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -34322,15 +36858,17 @@ def test_create_odb_subnet_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.create_odb_subnet( - gco_odb_subnet.CreateOdbSubnetRequest(), + client.create_cloud_exadata_infrastructure( + oracledatabase.CreateCloudExadataInfrastructureRequest(), parent="parent_value", - odb_subnet=gco_odb_subnet.OdbSubnet(name="name_value"), - odb_subnet_id="odb_subnet_id_value", + cloud_exadata_infrastructure=exadata_infra.CloudExadataInfrastructure( + name="name_value" + ), + cloud_exadata_infrastructure_id="cloud_exadata_infrastructure_id_value", ) -def test_delete_odb_subnet_rest_use_cached_wrapped_rpc(): +def test_delete_cloud_exadata_infrastructure_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -34344,19 +36882,22 @@ def test_delete_odb_subnet_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.delete_odb_subnet in client._transport._wrapped_methods + assert ( + client._transport.delete_cloud_exadata_infrastructure + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.delete_odb_subnet] = ( - mock_rpc - ) + client._transport._wrapped_methods[ + client._transport.delete_cloud_exadata_infrastructure + ] = mock_rpc request = {} - client.delete_odb_subnet(request) + client.delete_cloud_exadata_infrastructure(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 @@ -34365,15 +36906,15 @@ def test_delete_odb_subnet_rest_use_cached_wrapped_rpc(): # subsequent calls should use the cached wrapper wrapper_fn.reset_mock() - client.delete_odb_subnet(request) + client.delete_cloud_exadata_infrastructure(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_delete_odb_subnet_rest_required_fields( - request_type=odb_subnet.DeleteOdbSubnetRequest, +def test_delete_cloud_exadata_infrastructure_rest_required_fields( + request_type=oracledatabase.DeleteCloudExadataInfrastructureRequest, ): transport_class = transports.OracleDatabaseRestTransport @@ -34389,7 +36930,7 @@ def test_delete_odb_subnet_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_odb_subnet._get_unset_required_fields(jsonified_request) + ).delete_cloud_exadata_infrastructure._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -34398,9 +36939,14 @@ def test_delete_odb_subnet_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_odb_subnet._get_unset_required_fields(jsonified_request) + ).delete_cloud_exadata_infrastructure._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("request_id",)) + assert not set(unset_fields) - set( + ( + "force", + "request_id", + ) + ) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -34439,23 +36985,33 @@ def test_delete_odb_subnet_rest_required_fields( req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_odb_subnet(request) + response = client.delete_cloud_exadata_infrastructure(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_delete_odb_subnet_rest_unset_required_fields(): +def test_delete_cloud_exadata_infrastructure_rest_unset_required_fields(): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.delete_odb_subnet._get_unset_required_fields({}) - assert set(unset_fields) == (set(("requestId",)) & set(("name",))) + unset_fields = ( + transport.delete_cloud_exadata_infrastructure._get_unset_required_fields({}) + ) + assert set(unset_fields) == ( + set( + ( + "force", + "requestId", + ) + ) + & set(("name",)) + ) -def test_delete_odb_subnet_rest_flattened(): +def test_delete_cloud_exadata_infrastructure_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -34468,7 +37024,7 @@ def test_delete_odb_subnet_rest_flattened(): # get arguments that satisfy an http rule for this method sample_request = { - "name": "projects/sample1/locations/sample2/odbNetworks/sample3/odbSubnets/sample4" + "name": "projects/sample1/locations/sample2/cloudExadataInfrastructures/sample3" } # get truthy value for each flattened field @@ -34485,20 +37041,22 @@ def test_delete_odb_subnet_rest_flattened(): req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_odb_subnet(**mock_args) + client.delete_cloud_exadata_infrastructure(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/odbNetworks/*/odbSubnets/*}" + "%s/v1/{name=projects/*/locations/*/cloudExadataInfrastructures/*}" % client.transport._host, args[1], ) -def test_delete_odb_subnet_rest_flattened_error(transport: str = "rest"): +def test_delete_cloud_exadata_infrastructure_rest_flattened_error( + transport: str = "rest", +): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -34507,13 +37065,13 @@ def test_delete_odb_subnet_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.delete_odb_subnet( - odb_subnet.DeleteOdbSubnetRequest(), + client.delete_cloud_exadata_infrastructure( + oracledatabase.DeleteCloudExadataInfrastructureRequest(), name="name_value", ) -def test_list_exadb_vm_clusters_rest_use_cached_wrapped_rpc(): +def test_list_cloud_vm_clusters_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -34528,7 +37086,7 @@ def test_list_exadb_vm_clusters_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.list_exadb_vm_clusters + client._transport.list_cloud_vm_clusters in client._transport._wrapped_methods ) @@ -34537,25 +37095,25 @@ def test_list_exadb_vm_clusters_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.list_exadb_vm_clusters] = ( + client._transport._wrapped_methods[client._transport.list_cloud_vm_clusters] = ( mock_rpc ) request = {} - client.list_exadb_vm_clusters(request) + client.list_cloud_vm_clusters(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_exadb_vm_clusters(request) + client.list_cloud_vm_clusters(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_exadb_vm_clusters_rest_required_fields( - request_type=oracledatabase.ListExadbVmClustersRequest, +def test_list_cloud_vm_clusters_rest_required_fields( + request_type=oracledatabase.ListCloudVmClustersRequest, ): transport_class = transports.OracleDatabaseRestTransport @@ -34571,7 +37129,7 @@ def test_list_exadb_vm_clusters_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_exadb_vm_clusters._get_unset_required_fields(jsonified_request) + ).list_cloud_vm_clusters._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -34580,12 +37138,11 @@ def test_list_exadb_vm_clusters_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_exadb_vm_clusters._get_unset_required_fields(jsonified_request) + ).list_cloud_vm_clusters._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. assert not set(unset_fields) - set( ( "filter", - "order_by", "page_size", "page_token", ) @@ -34603,7 +37160,7 @@ def test_list_exadb_vm_clusters_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListExadbVmClustersResponse() + return_value = oracledatabase.ListCloudVmClustersResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -34624,31 +37181,30 @@ def test_list_exadb_vm_clusters_rest_required_fields( response_value.status_code = 200 # Convert return value to protobuf type - return_value = oracledatabase.ListExadbVmClustersResponse.pb(return_value) + return_value = oracledatabase.ListCloudVmClustersResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_exadb_vm_clusters(request) + response = client.list_cloud_vm_clusters(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_list_exadb_vm_clusters_rest_unset_required_fields(): +def test_list_cloud_vm_clusters_rest_unset_required_fields(): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.list_exadb_vm_clusters._get_unset_required_fields({}) + unset_fields = transport.list_cloud_vm_clusters._get_unset_required_fields({}) assert set(unset_fields) == ( set( ( "filter", - "orderBy", "pageSize", "pageToken", ) @@ -34657,7 +37213,7 @@ def test_list_exadb_vm_clusters_rest_unset_required_fields(): ) -def test_list_exadb_vm_clusters_rest_flattened(): +def test_list_cloud_vm_clusters_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -34666,7 +37222,7 @@ def test_list_exadb_vm_clusters_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListExadbVmClustersResponse() + return_value = oracledatabase.ListCloudVmClustersResponse() # get arguments that satisfy an http rule for this method sample_request = {"parent": "projects/sample1/locations/sample2"} @@ -34681,26 +37237,26 @@ def test_list_exadb_vm_clusters_rest_flattened(): response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = oracledatabase.ListExadbVmClustersResponse.pb(return_value) + return_value = oracledatabase.ListCloudVmClustersResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_exadb_vm_clusters(**mock_args) + client.list_cloud_vm_clusters(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/exadbVmClusters" + "%s/v1/{parent=projects/*/locations/*}/cloudVmClusters" % client.transport._host, args[1], ) -def test_list_exadb_vm_clusters_rest_flattened_error(transport: str = "rest"): +def test_list_cloud_vm_clusters_rest_flattened_error(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -34709,13 +37265,13 @@ def test_list_exadb_vm_clusters_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_exadb_vm_clusters( - oracledatabase.ListExadbVmClustersRequest(), + client.list_cloud_vm_clusters( + oracledatabase.ListCloudVmClustersRequest(), parent="parent_value", ) -def test_list_exadb_vm_clusters_rest_pager(transport: str = "rest"): +def test_list_cloud_vm_clusters_rest_pager(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -34727,28 +37283,28 @@ def test_list_exadb_vm_clusters_rest_pager(transport: str = "rest"): # with mock.patch.object(path_template, 'transcode') as transcode: # Set the response as a series of pages response = ( - oracledatabase.ListExadbVmClustersResponse( - exadb_vm_clusters=[ - exadb_vm_cluster.ExadbVmCluster(), - exadb_vm_cluster.ExadbVmCluster(), - exadb_vm_cluster.ExadbVmCluster(), + oracledatabase.ListCloudVmClustersResponse( + cloud_vm_clusters=[ + vm_cluster.CloudVmCluster(), + vm_cluster.CloudVmCluster(), + vm_cluster.CloudVmCluster(), ], next_page_token="abc", ), - oracledatabase.ListExadbVmClustersResponse( - exadb_vm_clusters=[], + oracledatabase.ListCloudVmClustersResponse( + cloud_vm_clusters=[], next_page_token="def", ), - oracledatabase.ListExadbVmClustersResponse( - exadb_vm_clusters=[ - exadb_vm_cluster.ExadbVmCluster(), + oracledatabase.ListCloudVmClustersResponse( + cloud_vm_clusters=[ + vm_cluster.CloudVmCluster(), ], next_page_token="ghi", ), - oracledatabase.ListExadbVmClustersResponse( - exadb_vm_clusters=[ - exadb_vm_cluster.ExadbVmCluster(), - exadb_vm_cluster.ExadbVmCluster(), + oracledatabase.ListCloudVmClustersResponse( + cloud_vm_clusters=[ + vm_cluster.CloudVmCluster(), + vm_cluster.CloudVmCluster(), ], ), ) @@ -34757,7 +37313,7 @@ def test_list_exadb_vm_clusters_rest_pager(transport: str = "rest"): # Wrap the values into proper Response objs response = tuple( - oracledatabase.ListExadbVmClustersResponse.to_json(x) for x in response + oracledatabase.ListCloudVmClustersResponse.to_json(x) for x in response ) return_values = tuple(Response() for i in response) for return_val, response_val in zip(return_values, response): @@ -34767,18 +37323,18 @@ def test_list_exadb_vm_clusters_rest_pager(transport: str = "rest"): sample_request = {"parent": "projects/sample1/locations/sample2"} - pager = client.list_exadb_vm_clusters(request=sample_request) + pager = client.list_cloud_vm_clusters(request=sample_request) results = list(pager) assert len(results) == 6 - assert all(isinstance(i, exadb_vm_cluster.ExadbVmCluster) for i in results) + assert all(isinstance(i, vm_cluster.CloudVmCluster) for i in results) - pages = list(client.list_exadb_vm_clusters(request=sample_request).pages) + pages = list(client.list_cloud_vm_clusters(request=sample_request).pages) for page_, token in zip(pages, ["abc", "def", "ghi", ""]): assert page_.raw_page.next_page_token == token -def test_get_exadb_vm_cluster_rest_use_cached_wrapped_rpc(): +def test_get_cloud_vm_cluster_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -34793,7 +37349,7 @@ def test_get_exadb_vm_cluster_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.get_exadb_vm_cluster in client._transport._wrapped_methods + client._transport.get_cloud_vm_cluster in client._transport._wrapped_methods ) # Replace cached wrapped function with mock @@ -34801,25 +37357,25 @@ def test_get_exadb_vm_cluster_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.get_exadb_vm_cluster] = ( + client._transport._wrapped_methods[client._transport.get_cloud_vm_cluster] = ( mock_rpc ) request = {} - client.get_exadb_vm_cluster(request) + client.get_cloud_vm_cluster(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.get_exadb_vm_cluster(request) + client.get_cloud_vm_cluster(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_get_exadb_vm_cluster_rest_required_fields( - request_type=oracledatabase.GetExadbVmClusterRequest, +def test_get_cloud_vm_cluster_rest_required_fields( + request_type=oracledatabase.GetCloudVmClusterRequest, ): transport_class = transports.OracleDatabaseRestTransport @@ -34835,7 +37391,7 @@ def test_get_exadb_vm_cluster_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_exadb_vm_cluster._get_unset_required_fields(jsonified_request) + ).get_cloud_vm_cluster._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -34844,7 +37400,7 @@ def test_get_exadb_vm_cluster_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_exadb_vm_cluster._get_unset_required_fields(jsonified_request) + ).get_cloud_vm_cluster._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -34858,7 +37414,7 @@ def test_get_exadb_vm_cluster_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = exadb_vm_cluster.ExadbVmCluster() + return_value = vm_cluster.CloudVmCluster() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -34879,30 +37435,30 @@ def test_get_exadb_vm_cluster_rest_required_fields( response_value.status_code = 200 # Convert return value to protobuf type - return_value = exadb_vm_cluster.ExadbVmCluster.pb(return_value) + return_value = vm_cluster.CloudVmCluster.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_exadb_vm_cluster(request) + response = client.get_cloud_vm_cluster(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_get_exadb_vm_cluster_rest_unset_required_fields(): +def test_get_cloud_vm_cluster_rest_unset_required_fields(): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.get_exadb_vm_cluster._get_unset_required_fields({}) + unset_fields = transport.get_cloud_vm_cluster._get_unset_required_fields({}) assert set(unset_fields) == (set(()) & set(("name",))) -def test_get_exadb_vm_cluster_rest_flattened(): +def test_get_cloud_vm_cluster_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -34911,11 +37467,11 @@ def test_get_exadb_vm_cluster_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = exadb_vm_cluster.ExadbVmCluster() + return_value = vm_cluster.CloudVmCluster() # get arguments that satisfy an http rule for this method sample_request = { - "name": "projects/sample1/locations/sample2/exadbVmClusters/sample3" + "name": "projects/sample1/locations/sample2/cloudVmClusters/sample3" } # get truthy value for each flattened field @@ -34928,26 +37484,26 @@ def test_get_exadb_vm_cluster_rest_flattened(): response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = exadb_vm_cluster.ExadbVmCluster.pb(return_value) + return_value = vm_cluster.CloudVmCluster.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_exadb_vm_cluster(**mock_args) + client.get_cloud_vm_cluster(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/exadbVmClusters/*}" + "%s/v1/{name=projects/*/locations/*/cloudVmClusters/*}" % client.transport._host, args[1], ) -def test_get_exadb_vm_cluster_rest_flattened_error(transport: str = "rest"): +def test_get_cloud_vm_cluster_rest_flattened_error(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -34956,13 +37512,13 @@ def test_get_exadb_vm_cluster_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.get_exadb_vm_cluster( - oracledatabase.GetExadbVmClusterRequest(), + client.get_cloud_vm_cluster( + oracledatabase.GetCloudVmClusterRequest(), name="name_value", ) -def test_create_exadb_vm_cluster_rest_use_cached_wrapped_rpc(): +def test_create_cloud_vm_cluster_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -34977,7 +37533,7 @@ def test_create_exadb_vm_cluster_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.create_exadb_vm_cluster + client._transport.create_cloud_vm_cluster in client._transport._wrapped_methods ) @@ -34987,11 +37543,11 @@ def test_create_exadb_vm_cluster_rest_use_cached_wrapped_rpc(): "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ - client._transport.create_exadb_vm_cluster + client._transport.create_cloud_vm_cluster ] = mock_rpc request = {} - client.create_exadb_vm_cluster(request) + client.create_cloud_vm_cluster(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 @@ -35000,21 +37556,21 @@ def test_create_exadb_vm_cluster_rest_use_cached_wrapped_rpc(): # subsequent calls should use the cached wrapper wrapper_fn.reset_mock() - client.create_exadb_vm_cluster(request) + client.create_cloud_vm_cluster(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_create_exadb_vm_cluster_rest_required_fields( - request_type=oracledatabase.CreateExadbVmClusterRequest, +def test_create_cloud_vm_cluster_rest_required_fields( + request_type=oracledatabase.CreateCloudVmClusterRequest, ): transport_class = transports.OracleDatabaseRestTransport request_init = {} request_init["parent"] = "" - request_init["exadb_vm_cluster_id"] = "" + request_init["cloud_vm_cluster_id"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -35022,27 +37578,27 @@ def test_create_exadb_vm_cluster_rest_required_fields( ) # verify fields with default values are dropped - assert "exadbVmClusterId" not in jsonified_request + assert "cloudVmClusterId" not in jsonified_request unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_exadb_vm_cluster._get_unset_required_fields(jsonified_request) + ).create_cloud_vm_cluster._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - assert "exadbVmClusterId" in jsonified_request - assert jsonified_request["exadbVmClusterId"] == request_init["exadb_vm_cluster_id"] + assert "cloudVmClusterId" in jsonified_request + assert jsonified_request["cloudVmClusterId"] == request_init["cloud_vm_cluster_id"] jsonified_request["parent"] = "parent_value" - jsonified_request["exadbVmClusterId"] = "exadb_vm_cluster_id_value" + jsonified_request["cloudVmClusterId"] = "cloud_vm_cluster_id_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_exadb_vm_cluster._get_unset_required_fields(jsonified_request) + ).create_cloud_vm_cluster._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. assert not set(unset_fields) - set( ( - "exadb_vm_cluster_id", + "cloud_vm_cluster_id", "request_id", ) ) @@ -35051,8 +37607,8 @@ def test_create_exadb_vm_cluster_rest_required_fields( # verify required fields with non-default values are left alone assert "parent" in jsonified_request assert jsonified_request["parent"] == "parent_value" - assert "exadbVmClusterId" in jsonified_request - assert jsonified_request["exadbVmClusterId"] == "exadb_vm_cluster_id_value" + assert "cloudVmClusterId" in jsonified_request + assert jsonified_request["cloudVmClusterId"] == "cloud_vm_cluster_id_value" client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), @@ -35087,11 +37643,11 @@ def test_create_exadb_vm_cluster_rest_required_fields( req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_exadb_vm_cluster(request) + response = client.create_cloud_vm_cluster(request) expected_params = [ ( - "exadbVmClusterId", + "cloudVmClusterId", "", ), ("$alt", "json;enum-encoding=int"), @@ -35100,30 +37656,30 @@ def test_create_exadb_vm_cluster_rest_required_fields( assert sorted(expected_params) == sorted(actual_params) -def test_create_exadb_vm_cluster_rest_unset_required_fields(): +def test_create_cloud_vm_cluster_rest_unset_required_fields(): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.create_exadb_vm_cluster._get_unset_required_fields({}) + unset_fields = transport.create_cloud_vm_cluster._get_unset_required_fields({}) assert set(unset_fields) == ( set( ( - "exadbVmClusterId", + "cloudVmClusterId", "requestId", ) ) & set( ( "parent", - "exadbVmClusterId", - "exadbVmCluster", + "cloudVmClusterId", + "cloudVmCluster", ) ) ) -def test_create_exadb_vm_cluster_rest_flattened(): +def test_create_cloud_vm_cluster_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -35140,8 +37696,8 @@ def test_create_exadb_vm_cluster_rest_flattened(): # get truthy value for each flattened field mock_args = dict( parent="parent_value", - exadb_vm_cluster=gco_exadb_vm_cluster.ExadbVmCluster(name="name_value"), - exadb_vm_cluster_id="exadb_vm_cluster_id_value", + cloud_vm_cluster=vm_cluster.CloudVmCluster(name="name_value"), + cloud_vm_cluster_id="cloud_vm_cluster_id_value", ) mock_args.update(sample_request) @@ -35153,20 +37709,20 @@ def test_create_exadb_vm_cluster_rest_flattened(): req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_exadb_vm_cluster(**mock_args) + client.create_cloud_vm_cluster(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/exadbVmClusters" + "%s/v1/{parent=projects/*/locations/*}/cloudVmClusters" % client.transport._host, args[1], ) -def test_create_exadb_vm_cluster_rest_flattened_error(transport: str = "rest"): +def test_create_cloud_vm_cluster_rest_flattened_error(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -35175,15 +37731,15 @@ def test_create_exadb_vm_cluster_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.create_exadb_vm_cluster( - oracledatabase.CreateExadbVmClusterRequest(), + client.create_cloud_vm_cluster( + oracledatabase.CreateCloudVmClusterRequest(), parent="parent_value", - exadb_vm_cluster=gco_exadb_vm_cluster.ExadbVmCluster(name="name_value"), - exadb_vm_cluster_id="exadb_vm_cluster_id_value", + cloud_vm_cluster=vm_cluster.CloudVmCluster(name="name_value"), + cloud_vm_cluster_id="cloud_vm_cluster_id_value", ) -def test_delete_exadb_vm_cluster_rest_use_cached_wrapped_rpc(): +def test_delete_cloud_vm_cluster_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -35198,7 +37754,7 @@ def test_delete_exadb_vm_cluster_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.delete_exadb_vm_cluster + client._transport.delete_cloud_vm_cluster in client._transport._wrapped_methods ) @@ -35208,11 +37764,11 @@ def test_delete_exadb_vm_cluster_rest_use_cached_wrapped_rpc(): "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ - client._transport.delete_exadb_vm_cluster + client._transport.delete_cloud_vm_cluster ] = mock_rpc request = {} - client.delete_exadb_vm_cluster(request) + client.delete_cloud_vm_cluster(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 @@ -35221,15 +37777,15 @@ def test_delete_exadb_vm_cluster_rest_use_cached_wrapped_rpc(): # subsequent calls should use the cached wrapper wrapper_fn.reset_mock() - client.delete_exadb_vm_cluster(request) + client.delete_cloud_vm_cluster(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_delete_exadb_vm_cluster_rest_required_fields( - request_type=oracledatabase.DeleteExadbVmClusterRequest, +def test_delete_cloud_vm_cluster_rest_required_fields( + request_type=oracledatabase.DeleteCloudVmClusterRequest, ): transport_class = transports.OracleDatabaseRestTransport @@ -35245,7 +37801,7 @@ def test_delete_exadb_vm_cluster_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_exadb_vm_cluster._get_unset_required_fields(jsonified_request) + ).delete_cloud_vm_cluster._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -35254,9 +37810,14 @@ def test_delete_exadb_vm_cluster_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_exadb_vm_cluster._get_unset_required_fields(jsonified_request) + ).delete_cloud_vm_cluster._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("request_id",)) + assert not set(unset_fields) - set( + ( + "force", + "request_id", + ) + ) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -35295,23 +37856,31 @@ def test_delete_exadb_vm_cluster_rest_required_fields( req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_exadb_vm_cluster(request) + response = client.delete_cloud_vm_cluster(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_delete_exadb_vm_cluster_rest_unset_required_fields(): +def test_delete_cloud_vm_cluster_rest_unset_required_fields(): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.delete_exadb_vm_cluster._get_unset_required_fields({}) - assert set(unset_fields) == (set(("requestId",)) & set(("name",))) + unset_fields = transport.delete_cloud_vm_cluster._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "force", + "requestId", + ) + ) + & set(("name",)) + ) -def test_delete_exadb_vm_cluster_rest_flattened(): +def test_delete_cloud_vm_cluster_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -35324,7 +37893,7 @@ def test_delete_exadb_vm_cluster_rest_flattened(): # get arguments that satisfy an http rule for this method sample_request = { - "name": "projects/sample1/locations/sample2/exadbVmClusters/sample3" + "name": "projects/sample1/locations/sample2/cloudVmClusters/sample3" } # get truthy value for each flattened field @@ -35341,20 +37910,20 @@ def test_delete_exadb_vm_cluster_rest_flattened(): req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_exadb_vm_cluster(**mock_args) + client.delete_cloud_vm_cluster(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/exadbVmClusters/*}" + "%s/v1/{name=projects/*/locations/*/cloudVmClusters/*}" % client.transport._host, args[1], ) -def test_delete_exadb_vm_cluster_rest_flattened_error(transport: str = "rest"): +def test_delete_cloud_vm_cluster_rest_flattened_error(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -35363,13 +37932,13 @@ def test_delete_exadb_vm_cluster_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.delete_exadb_vm_cluster( - oracledatabase.DeleteExadbVmClusterRequest(), + client.delete_cloud_vm_cluster( + oracledatabase.DeleteCloudVmClusterRequest(), name="name_value", ) -def test_update_exadb_vm_cluster_rest_use_cached_wrapped_rpc(): +def test_list_entitlements_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -35383,43 +37952,37 @@ def test_update_exadb_vm_cluster_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert ( - client._transport.update_exadb_vm_cluster - in client._transport._wrapped_methods - ) + assert client._transport.list_entitlements in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[ - client._transport.update_exadb_vm_cluster - ] = mock_rpc + client._transport._wrapped_methods[client._transport.list_entitlements] = ( + mock_rpc + ) request = {} - client.update_exadb_vm_cluster(request) + client.list_entitlements(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.update_exadb_vm_cluster(request) + client.list_entitlements(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_update_exadb_vm_cluster_rest_required_fields( - request_type=oracledatabase.UpdateExadbVmClusterRequest, +def test_list_entitlements_rest_required_fields( + request_type=oracledatabase.ListEntitlementsRequest, ): transport_class = transports.OracleDatabaseRestTransport request_init = {} + request_init["parent"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -35430,24 +37993,28 @@ def test_update_exadb_vm_cluster_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_exadb_vm_cluster._get_unset_required_fields(jsonified_request) + ).list_entitlements._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present + jsonified_request["parent"] = "parent_value" + unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_exadb_vm_cluster._get_unset_required_fields(jsonified_request) + ).list_entitlements._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. assert not set(unset_fields) - set( ( - "request_id", - "update_mask", + "page_size", + "page_token", ) ) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), @@ -35456,7 +38023,7 @@ def test_update_exadb_vm_cluster_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = oracledatabase.ListEntitlementsResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -35468,45 +38035,47 @@ def test_update_exadb_vm_cluster_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "patch", + "method": "get", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = oracledatabase.ListEntitlementsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_exadb_vm_cluster(request) + response = client.list_entitlements(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_update_exadb_vm_cluster_rest_unset_required_fields(): +def test_list_entitlements_rest_unset_required_fields(): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.update_exadb_vm_cluster._get_unset_required_fields({}) + unset_fields = transport.list_entitlements._get_unset_required_fields({}) assert set(unset_fields) == ( set( ( - "requestId", - "updateMask", + "pageSize", + "pageToken", ) ) - & set(("exadbVmCluster",)) + & set(("parent",)) ) -def test_update_exadb_vm_cluster_rest_flattened(): +def test_list_entitlements_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -35515,44 +38084,41 @@ def test_update_exadb_vm_cluster_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = oracledatabase.ListEntitlementsResponse() # get arguments that satisfy an http rule for this method - sample_request = { - "exadb_vm_cluster": { - "name": "projects/sample1/locations/sample2/exadbVmClusters/sample3" - } - } + sample_request = {"parent": "projects/sample1/locations/sample2"} # get truthy value for each flattened field mock_args = dict( - exadb_vm_cluster=gco_exadb_vm_cluster.ExadbVmCluster(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + parent="parent_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = oracledatabase.ListEntitlementsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_exadb_vm_cluster(**mock_args) + client.list_entitlements(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{exadb_vm_cluster.name=projects/*/locations/*/exadbVmClusters/*}" + "%s/v1/{parent=projects/*/locations/*}/entitlements" % client.transport._host, args[1], ) -def test_update_exadb_vm_cluster_rest_flattened_error(transport: str = "rest"): +def test_list_entitlements_rest_flattened_error(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -35561,14 +38127,76 @@ def test_update_exadb_vm_cluster_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.update_exadb_vm_cluster( - oracledatabase.UpdateExadbVmClusterRequest(), - exadb_vm_cluster=gco_exadb_vm_cluster.ExadbVmCluster(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + client.list_entitlements( + oracledatabase.ListEntitlementsRequest(), + parent="parent_value", ) -def test_remove_virtual_machine_exadb_vm_cluster_rest_use_cached_wrapped_rpc(): +def test_list_entitlements_rest_pager(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + oracledatabase.ListEntitlementsResponse( + entitlements=[ + entitlement.Entitlement(), + entitlement.Entitlement(), + entitlement.Entitlement(), + ], + next_page_token="abc", + ), + oracledatabase.ListEntitlementsResponse( + entitlements=[], + next_page_token="def", + ), + oracledatabase.ListEntitlementsResponse( + entitlements=[ + entitlement.Entitlement(), + ], + next_page_token="ghi", + ), + oracledatabase.ListEntitlementsResponse( + entitlements=[ + entitlement.Entitlement(), + entitlement.Entitlement(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + oracledatabase.ListEntitlementsResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_entitlements(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, entitlement.Entitlement) for i in results) + + pages = list(client.list_entitlements(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_list_db_servers_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -35582,45 +38210,35 @@ def test_remove_virtual_machine_exadb_vm_cluster_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert ( - client._transport.remove_virtual_machine_exadb_vm_cluster - in client._transport._wrapped_methods - ) + assert client._transport.list_db_servers in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[ - client._transport.remove_virtual_machine_exadb_vm_cluster - ] = mock_rpc + client._transport._wrapped_methods[client._transport.list_db_servers] = mock_rpc request = {} - client.remove_virtual_machine_exadb_vm_cluster(request) + client.list_db_servers(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.remove_virtual_machine_exadb_vm_cluster(request) + client.list_db_servers(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_remove_virtual_machine_exadb_vm_cluster_rest_required_fields( - request_type=oracledatabase.RemoveVirtualMachineExadbVmClusterRequest, +def test_list_db_servers_rest_required_fields( + request_type=oracledatabase.ListDbServersRequest, ): transport_class = transports.OracleDatabaseRestTransport request_init = {} - request_init["name"] = "" - request_init["hostnames"] = "" + request_init["parent"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -35631,28 +38249,28 @@ def test_remove_virtual_machine_exadb_vm_cluster_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).remove_virtual_machine_exadb_vm_cluster._get_unset_required_fields( - jsonified_request - ) + ).list_db_servers._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["name"] = "name_value" - jsonified_request["hostnames"] = "hostnames_value" + jsonified_request["parent"] = "parent_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).remove_virtual_machine_exadb_vm_cluster._get_unset_required_fields( - jsonified_request + ).list_db_servers._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "page_size", + "page_token", + ) ) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" - assert "hostnames" in jsonified_request - assert jsonified_request["hostnames"] == "hostnames_value" + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), @@ -35661,7 +38279,7 @@ def test_remove_virtual_machine_exadb_vm_cluster_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = oracledatabase.ListDbServersResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -35673,47 +38291,47 @@ def test_remove_virtual_machine_exadb_vm_cluster_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "post", + "method": "get", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = oracledatabase.ListDbServersResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.remove_virtual_machine_exadb_vm_cluster(request) + response = client.list_db_servers(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_remove_virtual_machine_exadb_vm_cluster_rest_unset_required_fields(): +def test_list_db_servers_rest_unset_required_fields(): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = ( - transport.remove_virtual_machine_exadb_vm_cluster._get_unset_required_fields({}) - ) + unset_fields = transport.list_db_servers._get_unset_required_fields({}) assert set(unset_fields) == ( - set(()) - & set( + set( ( - "name", - "hostnames", + "pageSize", + "pageToken", ) ) + & set(("parent",)) ) -def test_remove_virtual_machine_exadb_vm_cluster_rest_flattened(): +def test_list_db_servers_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -35722,44 +38340,43 @@ def test_remove_virtual_machine_exadb_vm_cluster_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = oracledatabase.ListDbServersResponse() # get arguments that satisfy an http rule for this method sample_request = { - "name": "projects/sample1/locations/sample2/exadbVmClusters/sample3" + "parent": "projects/sample1/locations/sample2/cloudExadataInfrastructures/sample3" } # get truthy value for each flattened field mock_args = dict( - name="name_value", - hostnames=["hostnames_value"], + parent="parent_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = oracledatabase.ListDbServersResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.remove_virtual_machine_exadb_vm_cluster(**mock_args) + client.list_db_servers(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/exadbVmClusters/*}:removeVirtualMachine" + "%s/v1/{parent=projects/*/locations/*/cloudExadataInfrastructures/*}/dbServers" % client.transport._host, args[1], ) -def test_remove_virtual_machine_exadb_vm_cluster_rest_flattened_error( - transport: str = "rest", -): +def test_list_db_servers_rest_flattened_error(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -35768,14 +38385,78 @@ def test_remove_virtual_machine_exadb_vm_cluster_rest_flattened_error( # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.remove_virtual_machine_exadb_vm_cluster( - oracledatabase.RemoveVirtualMachineExadbVmClusterRequest(), - name="name_value", - hostnames=["hostnames_value"], + client.list_db_servers( + oracledatabase.ListDbServersRequest(), + parent="parent_value", ) -def test_list_exascale_db_storage_vaults_rest_use_cached_wrapped_rpc(): +def test_list_db_servers_rest_pager(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + oracledatabase.ListDbServersResponse( + db_servers=[ + db_server.DbServer(), + db_server.DbServer(), + db_server.DbServer(), + ], + next_page_token="abc", + ), + oracledatabase.ListDbServersResponse( + db_servers=[], + next_page_token="def", + ), + oracledatabase.ListDbServersResponse( + db_servers=[ + db_server.DbServer(), + ], + next_page_token="ghi", + ), + oracledatabase.ListDbServersResponse( + db_servers=[ + db_server.DbServer(), + db_server.DbServer(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + oracledatabase.ListDbServersResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = { + "parent": "projects/sample1/locations/sample2/cloudExadataInfrastructures/sample3" + } + + pager = client.list_db_servers(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, db_server.DbServer) for i in results) + + pages = list(client.list_db_servers(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_list_db_nodes_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -35789,35 +38470,30 @@ def test_list_exascale_db_storage_vaults_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert ( - client._transport.list_exascale_db_storage_vaults - in client._transport._wrapped_methods - ) + assert client._transport.list_db_nodes in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[ - client._transport.list_exascale_db_storage_vaults - ] = mock_rpc + client._transport._wrapped_methods[client._transport.list_db_nodes] = mock_rpc request = {} - client.list_exascale_db_storage_vaults(request) + client.list_db_nodes(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_exascale_db_storage_vaults(request) + client.list_db_nodes(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_exascale_db_storage_vaults_rest_required_fields( - request_type=exascale_db_storage_vault.ListExascaleDbStorageVaultsRequest, +def test_list_db_nodes_rest_required_fields( + request_type=oracledatabase.ListDbNodesRequest, ): transport_class = transports.OracleDatabaseRestTransport @@ -35833,7 +38509,7 @@ def test_list_exascale_db_storage_vaults_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_exascale_db_storage_vaults._get_unset_required_fields(jsonified_request) + ).list_db_nodes._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -35842,12 +38518,10 @@ def test_list_exascale_db_storage_vaults_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_exascale_db_storage_vaults._get_unset_required_fields(jsonified_request) + ).list_db_nodes._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. assert not set(unset_fields) - set( ( - "filter", - "order_by", "page_size", "page_token", ) @@ -35865,7 +38539,7 @@ def test_list_exascale_db_storage_vaults_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse() + return_value = oracledatabase.ListDbNodesResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -35886,37 +38560,29 @@ def test_list_exascale_db_storage_vaults_rest_required_fields( response_value.status_code = 200 # Convert return value to protobuf type - return_value = ( - exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse.pb( - return_value - ) - ) + return_value = oracledatabase.ListDbNodesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_exascale_db_storage_vaults(request) + response = client.list_db_nodes(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_list_exascale_db_storage_vaults_rest_unset_required_fields(): +def test_list_db_nodes_rest_unset_required_fields(): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.list_exascale_db_storage_vaults._get_unset_required_fields( - {} - ) + unset_fields = transport.list_db_nodes._get_unset_required_fields({}) assert set(unset_fields) == ( set( ( - "filter", - "orderBy", "pageSize", "pageToken", ) @@ -35925,7 +38591,7 @@ def test_list_exascale_db_storage_vaults_rest_unset_required_fields(): ) -def test_list_exascale_db_storage_vaults_rest_flattened(): +def test_list_db_nodes_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -35934,10 +38600,12 @@ def test_list_exascale_db_storage_vaults_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse() + return_value = oracledatabase.ListDbNodesResponse() # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} + sample_request = { + "parent": "projects/sample1/locations/sample2/cloudVmClusters/sample3" + } # get truthy value for each flattened field mock_args = dict( @@ -35949,28 +38617,26 @@ def test_list_exascale_db_storage_vaults_rest_flattened(): response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse.pb( - return_value - ) + return_value = oracledatabase.ListDbNodesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_exascale_db_storage_vaults(**mock_args) + client.list_db_nodes(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/exascaleDbStorageVaults" + "%s/v1/{parent=projects/*/locations/*/cloudVmClusters/*}/dbNodes" % client.transport._host, args[1], ) -def test_list_exascale_db_storage_vaults_rest_flattened_error(transport: str = "rest"): +def test_list_db_nodes_rest_flattened_error(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -35979,13 +38645,13 @@ def test_list_exascale_db_storage_vaults_rest_flattened_error(transport: str = " # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_exascale_db_storage_vaults( - exascale_db_storage_vault.ListExascaleDbStorageVaultsRequest(), + client.list_db_nodes( + oracledatabase.ListDbNodesRequest(), parent="parent_value", ) -def test_list_exascale_db_storage_vaults_rest_pager(transport: str = "rest"): +def test_list_db_nodes_rest_pager(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -35997,28 +38663,28 @@ def test_list_exascale_db_storage_vaults_rest_pager(transport: str = "rest"): # with mock.patch.object(path_template, 'transcode') as transcode: # Set the response as a series of pages response = ( - exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse( - exascale_db_storage_vaults=[ - exascale_db_storage_vault.ExascaleDbStorageVault(), - exascale_db_storage_vault.ExascaleDbStorageVault(), - exascale_db_storage_vault.ExascaleDbStorageVault(), + oracledatabase.ListDbNodesResponse( + db_nodes=[ + db_node.DbNode(), + db_node.DbNode(), + db_node.DbNode(), ], next_page_token="abc", ), - exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse( - exascale_db_storage_vaults=[], + oracledatabase.ListDbNodesResponse( + db_nodes=[], next_page_token="def", ), - exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse( - exascale_db_storage_vaults=[ - exascale_db_storage_vault.ExascaleDbStorageVault(), + oracledatabase.ListDbNodesResponse( + db_nodes=[ + db_node.DbNode(), ], next_page_token="ghi", ), - exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse( - exascale_db_storage_vaults=[ - exascale_db_storage_vault.ExascaleDbStorageVault(), - exascale_db_storage_vault.ExascaleDbStorageVault(), + oracledatabase.ListDbNodesResponse( + db_nodes=[ + db_node.DbNode(), + db_node.DbNode(), ], ), ) @@ -36027,8 +38693,7 @@ def test_list_exascale_db_storage_vaults_rest_pager(transport: str = "rest"): # Wrap the values into proper Response objs response = tuple( - exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse.to_json(x) - for x in response + oracledatabase.ListDbNodesResponse.to_json(x) for x in response ) return_values = tuple(Response() for i in response) for return_val, response_val in zip(return_values, response): @@ -36036,25 +38701,22 @@ def test_list_exascale_db_storage_vaults_rest_pager(transport: str = "rest"): return_val.status_code = 200 req.side_effect = return_values - sample_request = {"parent": "projects/sample1/locations/sample2"} + sample_request = { + "parent": "projects/sample1/locations/sample2/cloudVmClusters/sample3" + } - pager = client.list_exascale_db_storage_vaults(request=sample_request) + pager = client.list_db_nodes(request=sample_request) results = list(pager) assert len(results) == 6 - assert all( - isinstance(i, exascale_db_storage_vault.ExascaleDbStorageVault) - for i in results - ) + assert all(isinstance(i, db_node.DbNode) for i in results) - pages = list( - client.list_exascale_db_storage_vaults(request=sample_request).pages - ) + pages = list(client.list_db_nodes(request=sample_request).pages) for page_, token in zip(pages, ["abc", "def", "ghi", ""]): assert page_.raw_page.next_page_token == token -def test_get_exascale_db_storage_vault_rest_use_cached_wrapped_rpc(): +def test_list_gi_versions_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -36068,40 +38730,37 @@ def test_get_exascale_db_storage_vault_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert ( - client._transport.get_exascale_db_storage_vault - in client._transport._wrapped_methods - ) + assert client._transport.list_gi_versions in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[ - client._transport.get_exascale_db_storage_vault - ] = mock_rpc + client._transport._wrapped_methods[client._transport.list_gi_versions] = ( + mock_rpc + ) request = {} - client.get_exascale_db_storage_vault(request) + client.list_gi_versions(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.get_exascale_db_storage_vault(request) + client.list_gi_versions(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_get_exascale_db_storage_vault_rest_required_fields( - request_type=exascale_db_storage_vault.GetExascaleDbStorageVaultRequest, +def test_list_gi_versions_rest_required_fields( + request_type=oracledatabase.ListGiVersionsRequest, ): transport_class = transports.OracleDatabaseRestTransport request_init = {} - request_init["name"] = "" + request_init["parent"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -36112,21 +38771,29 @@ def test_get_exascale_db_storage_vault_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_exascale_db_storage_vault._get_unset_required_fields(jsonified_request) + ).list_gi_versions._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["name"] = "name_value" + jsonified_request["parent"] = "parent_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_exascale_db_storage_vault._get_unset_required_fields(jsonified_request) + ).list_gi_versions._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "page_size", + "page_token", + ) + ) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), @@ -36135,7 +38802,7 @@ def test_get_exascale_db_storage_vault_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = exascale_db_storage_vault.ExascaleDbStorageVault() + return_value = oracledatabase.ListGiVersionsResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -36156,34 +38823,39 @@ def test_get_exascale_db_storage_vault_rest_required_fields( response_value.status_code = 200 # Convert return value to protobuf type - return_value = exascale_db_storage_vault.ExascaleDbStorageVault.pb( - return_value - ) + return_value = oracledatabase.ListGiVersionsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_exascale_db_storage_vault(request) + response = client.list_gi_versions(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_get_exascale_db_storage_vault_rest_unset_required_fields(): +def test_list_gi_versions_rest_unset_required_fields(): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.get_exascale_db_storage_vault._get_unset_required_fields( - {} + unset_fields = transport.list_gi_versions._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) ) - assert set(unset_fields) == (set(()) & set(("name",))) -def test_get_exascale_db_storage_vault_rest_flattened(): +def test_list_gi_versions_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -36192,16 +38864,14 @@ def test_get_exascale_db_storage_vault_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = exascale_db_storage_vault.ExascaleDbStorageVault() + return_value = oracledatabase.ListGiVersionsResponse() # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/exascaleDbStorageVaults/sample3" - } + sample_request = {"parent": "projects/sample1/locations/sample2"} # get truthy value for each flattened field mock_args = dict( - name="name_value", + parent="parent_value", ) mock_args.update(sample_request) @@ -36209,26 +38879,25 @@ def test_get_exascale_db_storage_vault_rest_flattened(): response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = exascale_db_storage_vault.ExascaleDbStorageVault.pb(return_value) + return_value = oracledatabase.ListGiVersionsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_exascale_db_storage_vault(**mock_args) + client.list_gi_versions(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/exascaleDbStorageVaults/*}" - % client.transport._host, + "%s/v1/{parent=projects/*/locations/*}/giVersions" % client.transport._host, args[1], ) -def test_get_exascale_db_storage_vault_rest_flattened_error(transport: str = "rest"): +def test_list_gi_versions_rest_flattened_error(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -36237,13 +38906,76 @@ def test_get_exascale_db_storage_vault_rest_flattened_error(transport: str = "re # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.get_exascale_db_storage_vault( - exascale_db_storage_vault.GetExascaleDbStorageVaultRequest(), - name="name_value", + client.list_gi_versions( + oracledatabase.ListGiVersionsRequest(), + parent="parent_value", ) -def test_create_exascale_db_storage_vault_rest_use_cached_wrapped_rpc(): +def test_list_gi_versions_rest_pager(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + oracledatabase.ListGiVersionsResponse( + gi_versions=[ + gi_version.GiVersion(), + gi_version.GiVersion(), + gi_version.GiVersion(), + ], + next_page_token="abc", + ), + oracledatabase.ListGiVersionsResponse( + gi_versions=[], + next_page_token="def", + ), + oracledatabase.ListGiVersionsResponse( + gi_versions=[ + gi_version.GiVersion(), + ], + next_page_token="ghi", + ), + oracledatabase.ListGiVersionsResponse( + gi_versions=[ + gi_version.GiVersion(), + gi_version.GiVersion(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + oracledatabase.ListGiVersionsResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_gi_versions(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, gi_version.GiVersion) for i in results) + + pages = list(client.list_gi_versions(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_list_minor_versions_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -36258,8 +38990,7 @@ def test_create_exascale_db_storage_vault_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.create_exascale_db_storage_vault - in client._transport._wrapped_methods + client._transport.list_minor_versions in client._transport._wrapped_methods ) # Replace cached wrapped function with mock @@ -36267,35 +38998,30 @@ def test_create_exascale_db_storage_vault_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[ - client._transport.create_exascale_db_storage_vault - ] = mock_rpc + client._transport._wrapped_methods[client._transport.list_minor_versions] = ( + mock_rpc + ) request = {} - client.create_exascale_db_storage_vault(request) + client.list_minor_versions(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.create_exascale_db_storage_vault(request) + client.list_minor_versions(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_create_exascale_db_storage_vault_rest_required_fields( - request_type=gco_exascale_db_storage_vault.CreateExascaleDbStorageVaultRequest, +def test_list_minor_versions_rest_required_fields( + request_type=minor_version.ListMinorVersionsRequest, ): transport_class = transports.OracleDatabaseRestTransport request_init = {} request_init["parent"] = "" - request_init["exascale_db_storage_vault_id"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -36303,31 +39029,25 @@ def test_create_exascale_db_storage_vault_rest_required_fields( ) # verify fields with default values are dropped - assert "exascaleDbStorageVaultId" not in jsonified_request unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_exascale_db_storage_vault._get_unset_required_fields(jsonified_request) + ).list_minor_versions._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - assert "exascaleDbStorageVaultId" in jsonified_request - assert ( - jsonified_request["exascaleDbStorageVaultId"] - == request_init["exascale_db_storage_vault_id"] - ) jsonified_request["parent"] = "parent_value" - jsonified_request["exascaleDbStorageVaultId"] = "exascale_db_storage_vault_id_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_exascale_db_storage_vault._get_unset_required_fields(jsonified_request) + ).list_minor_versions._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. assert not set(unset_fields) - set( ( - "exascale_db_storage_vault_id", - "request_id", + "filter", + "page_size", + "page_token", ) ) jsonified_request.update(unset_fields) @@ -36335,11 +39055,6 @@ def test_create_exascale_db_storage_vault_rest_required_fields( # verify required fields with non-default values are left alone assert "parent" in jsonified_request assert jsonified_request["parent"] == "parent_value" - assert "exascaleDbStorageVaultId" in jsonified_request - assert ( - jsonified_request["exascaleDbStorageVaultId"] - == "exascale_db_storage_vault_id_value" - ) client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), @@ -36348,7 +39063,7 @@ def test_create_exascale_db_storage_vault_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = minor_version.ListMinorVersionsResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -36360,59 +39075,48 @@ def test_create_exascale_db_storage_vault_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "post", + "method": "get", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = minor_version.ListMinorVersionsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_exascale_db_storage_vault(request) + response = client.list_minor_versions(request) - expected_params = [ - ( - "exascaleDbStorageVaultId", - "", - ), - ("$alt", "json;enum-encoding=int"), - ] + expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_create_exascale_db_storage_vault_rest_unset_required_fields(): +def test_list_minor_versions_rest_unset_required_fields(): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = ( - transport.create_exascale_db_storage_vault._get_unset_required_fields({}) - ) + unset_fields = transport.list_minor_versions._get_unset_required_fields({}) assert set(unset_fields) == ( set( ( - "exascaleDbStorageVaultId", - "requestId", - ) - ) - & set( - ( - "parent", - "exascaleDbStorageVaultId", - "exascaleDbStorageVault", + "filter", + "pageSize", + "pageToken", ) ) + & set(("parent",)) ) -def test_create_exascale_db_storage_vault_rest_flattened(): +def test_list_minor_versions_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -36421,43 +39125,43 @@ def test_create_exascale_db_storage_vault_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = minor_version.ListMinorVersionsResponse() # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} + sample_request = { + "parent": "projects/sample1/locations/sample2/giVersions/sample3" + } # get truthy value for each flattened field mock_args = dict( parent="parent_value", - exascale_db_storage_vault=gco_exascale_db_storage_vault.ExascaleDbStorageVault( - name="name_value" - ), - exascale_db_storage_vault_id="exascale_db_storage_vault_id_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = minor_version.ListMinorVersionsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_exascale_db_storage_vault(**mock_args) + client.list_minor_versions(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/exascaleDbStorageVaults" + "%s/v1/{parent=projects/*/locations/*/giVersions/*}/minorVersions" % client.transport._host, args[1], ) -def test_create_exascale_db_storage_vault_rest_flattened_error(transport: str = "rest"): +def test_list_minor_versions_rest_flattened_error(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -36466,17 +39170,78 @@ def test_create_exascale_db_storage_vault_rest_flattened_error(transport: str = # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.create_exascale_db_storage_vault( - gco_exascale_db_storage_vault.CreateExascaleDbStorageVaultRequest(), + client.list_minor_versions( + minor_version.ListMinorVersionsRequest(), parent="parent_value", - exascale_db_storage_vault=gco_exascale_db_storage_vault.ExascaleDbStorageVault( - name="name_value" + ) + + +def test_list_minor_versions_rest_pager(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + minor_version.ListMinorVersionsResponse( + minor_versions=[ + minor_version.MinorVersion(), + minor_version.MinorVersion(), + minor_version.MinorVersion(), + ], + next_page_token="abc", ), - exascale_db_storage_vault_id="exascale_db_storage_vault_id_value", + minor_version.ListMinorVersionsResponse( + minor_versions=[], + next_page_token="def", + ), + minor_version.ListMinorVersionsResponse( + minor_versions=[ + minor_version.MinorVersion(), + ], + next_page_token="ghi", + ), + minor_version.ListMinorVersionsResponse( + minor_versions=[ + minor_version.MinorVersion(), + minor_version.MinorVersion(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + minor_version.ListMinorVersionsResponse.to_json(x) for x in response ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = { + "parent": "projects/sample1/locations/sample2/giVersions/sample3" + } + pager = client.list_minor_versions(request=sample_request) -def test_delete_exascale_db_storage_vault_rest_use_cached_wrapped_rpc(): + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, minor_version.MinorVersion) for i in results) + + pages = list(client.list_minor_versions(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_list_db_system_shapes_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -36491,7 +39256,7 @@ def test_delete_exascale_db_storage_vault_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.delete_exascale_db_storage_vault + client._transport.list_db_system_shapes in client._transport._wrapped_methods ) @@ -36500,34 +39265,30 @@ def test_delete_exascale_db_storage_vault_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[ - client._transport.delete_exascale_db_storage_vault - ] = mock_rpc + client._transport._wrapped_methods[client._transport.list_db_system_shapes] = ( + mock_rpc + ) request = {} - client.delete_exascale_db_storage_vault(request) + client.list_db_system_shapes(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.delete_exascale_db_storage_vault(request) + client.list_db_system_shapes(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_delete_exascale_db_storage_vault_rest_required_fields( - request_type=exascale_db_storage_vault.DeleteExascaleDbStorageVaultRequest, +def test_list_db_system_shapes_rest_required_fields( + request_type=oracledatabase.ListDbSystemShapesRequest, ): transport_class = transports.OracleDatabaseRestTransport request_init = {} - request_init["name"] = "" + request_init["parent"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -36538,23 +39299,29 @@ def test_delete_exascale_db_storage_vault_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_exascale_db_storage_vault._get_unset_required_fields(jsonified_request) + ).list_db_system_shapes._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["name"] = "name_value" + jsonified_request["parent"] = "parent_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_exascale_db_storage_vault._get_unset_required_fields(jsonified_request) + ).list_db_system_shapes._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("request_id",)) + assert not set(unset_fields) - set( + ( + "filter", + "page_size", + "page_token", + ) + ) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), @@ -36563,7 +39330,7 @@ def test_delete_exascale_db_storage_vault_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = oracledatabase.ListDbSystemShapesResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -36575,38 +39342,48 @@ def test_delete_exascale_db_storage_vault_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "delete", + "method": "get", "query_params": pb_request, } transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = oracledatabase.ListDbSystemShapesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_exascale_db_storage_vault(request) + response = client.list_db_system_shapes(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_delete_exascale_db_storage_vault_rest_unset_required_fields(): +def test_list_db_system_shapes_rest_unset_required_fields(): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = ( - transport.delete_exascale_db_storage_vault._get_unset_required_fields({}) + unset_fields = transport.list_db_system_shapes._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) ) - assert set(unset_fields) == (set(("requestId",)) & set(("name",))) -def test_delete_exascale_db_storage_vault_rest_flattened(): +def test_list_db_system_shapes_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -36615,41 +39392,41 @@ def test_delete_exascale_db_storage_vault_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = oracledatabase.ListDbSystemShapesResponse() # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/exascaleDbStorageVaults/sample3" - } + sample_request = {"parent": "projects/sample1/locations/sample2"} # get truthy value for each flattened field mock_args = dict( - name="name_value", + parent="parent_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = oracledatabase.ListDbSystemShapesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_exascale_db_storage_vault(**mock_args) + client.list_db_system_shapes(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/exascaleDbStorageVaults/*}" + "%s/v1/{parent=projects/*/locations/*}/dbSystemShapes" % client.transport._host, args[1], ) -def test_delete_exascale_db_storage_vault_rest_flattened_error(transport: str = "rest"): +def test_list_db_system_shapes_rest_flattened_error(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -36658,13 +39435,76 @@ def test_delete_exascale_db_storage_vault_rest_flattened_error(transport: str = # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.delete_exascale_db_storage_vault( - exascale_db_storage_vault.DeleteExascaleDbStorageVaultRequest(), - name="name_value", + client.list_db_system_shapes( + oracledatabase.ListDbSystemShapesRequest(), + parent="parent_value", ) -def test_list_db_system_initial_storage_sizes_rest_use_cached_wrapped_rpc(): +def test_list_db_system_shapes_rest_pager(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + oracledatabase.ListDbSystemShapesResponse( + db_system_shapes=[ + db_system_shape.DbSystemShape(), + db_system_shape.DbSystemShape(), + db_system_shape.DbSystemShape(), + ], + next_page_token="abc", + ), + oracledatabase.ListDbSystemShapesResponse( + db_system_shapes=[], + next_page_token="def", + ), + oracledatabase.ListDbSystemShapesResponse( + db_system_shapes=[ + db_system_shape.DbSystemShape(), + ], + next_page_token="ghi", + ), + oracledatabase.ListDbSystemShapesResponse( + db_system_shapes=[ + db_system_shape.DbSystemShape(), + db_system_shape.DbSystemShape(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + oracledatabase.ListDbSystemShapesResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_db_system_shapes(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, db_system_shape.DbSystemShape) for i in results) + + pages = list(client.list_db_system_shapes(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_list_autonomous_databases_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -36679,7 +39519,7 @@ def test_list_db_system_initial_storage_sizes_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.list_db_system_initial_storage_sizes + client._transport.list_autonomous_databases in client._transport._wrapped_methods ) @@ -36689,24 +39529,24 @@ def test_list_db_system_initial_storage_sizes_rest_use_cached_wrapped_rpc(): "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ - client._transport.list_db_system_initial_storage_sizes + client._transport.list_autonomous_databases ] = mock_rpc request = {} - client.list_db_system_initial_storage_sizes(request) + client.list_autonomous_databases(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_db_system_initial_storage_sizes(request) + client.list_autonomous_databases(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_db_system_initial_storage_sizes_rest_required_fields( - request_type=db_system_initial_storage_size.ListDbSystemInitialStorageSizesRequest, +def test_list_autonomous_databases_rest_required_fields( + request_type=oracledatabase.ListAutonomousDatabasesRequest, ): transport_class = transports.OracleDatabaseRestTransport @@ -36722,7 +39562,7 @@ def test_list_db_system_initial_storage_sizes_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_db_system_initial_storage_sizes._get_unset_required_fields(jsonified_request) + ).list_autonomous_databases._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -36731,10 +39571,12 @@ def test_list_db_system_initial_storage_sizes_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_db_system_initial_storage_sizes._get_unset_required_fields(jsonified_request) + ).list_autonomous_databases._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. assert not set(unset_fields) - set( ( + "filter", + "order_by", "page_size", "page_token", ) @@ -36752,9 +39594,7 @@ def test_list_db_system_initial_storage_sizes_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = ( - db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse() - ) + return_value = oracledatabase.ListAutonomousDatabasesResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -36775,7 +39615,7 @@ def test_list_db_system_initial_storage_sizes_rest_required_fields( response_value.status_code = 200 # Convert return value to protobuf type - return_value = db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse.pb( + return_value = oracledatabase.ListAutonomousDatabasesResponse.pb( return_value ) json_return_value = json_format.MessageToJson(return_value) @@ -36784,24 +39624,24 @@ def test_list_db_system_initial_storage_sizes_rest_required_fields( req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_db_system_initial_storage_sizes(request) + response = client.list_autonomous_databases(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_list_db_system_initial_storage_sizes_rest_unset_required_fields(): +def test_list_autonomous_databases_rest_unset_required_fields(): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = ( - transport.list_db_system_initial_storage_sizes._get_unset_required_fields({}) - ) + unset_fields = transport.list_autonomous_databases._get_unset_required_fields({}) assert set(unset_fields) == ( set( ( + "filter", + "orderBy", "pageSize", "pageToken", ) @@ -36810,7 +39650,7 @@ def test_list_db_system_initial_storage_sizes_rest_unset_required_fields(): ) -def test_list_db_system_initial_storage_sizes_rest_flattened(): +def test_list_autonomous_databases_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -36819,9 +39659,7 @@ def test_list_db_system_initial_storage_sizes_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = ( - db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse() - ) + return_value = oracledatabase.ListAutonomousDatabasesResponse() # get arguments that satisfy an http rule for this method sample_request = {"parent": "projects/sample1/locations/sample2"} @@ -36836,32 +39674,26 @@ def test_list_db_system_initial_storage_sizes_rest_flattened(): response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = ( - db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse.pb( - return_value - ) - ) + return_value = oracledatabase.ListAutonomousDatabasesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_db_system_initial_storage_sizes(**mock_args) + client.list_autonomous_databases(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/dbSystemInitialStorageSizes" + "%s/v1/{parent=projects/*/locations/*}/autonomousDatabases" % client.transport._host, args[1], ) -def test_list_db_system_initial_storage_sizes_rest_flattened_error( - transport: str = "rest", -): +def test_list_autonomous_databases_rest_flattened_error(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -36870,13 +39702,13 @@ def test_list_db_system_initial_storage_sizes_rest_flattened_error( # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_db_system_initial_storage_sizes( - db_system_initial_storage_size.ListDbSystemInitialStorageSizesRequest(), + client.list_autonomous_databases( + oracledatabase.ListAutonomousDatabasesRequest(), parent="parent_value", ) -def test_list_db_system_initial_storage_sizes_rest_pager(transport: str = "rest"): +def test_list_autonomous_databases_rest_pager(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -36888,28 +39720,28 @@ def test_list_db_system_initial_storage_sizes_rest_pager(transport: str = "rest" # with mock.patch.object(path_template, 'transcode') as transcode: # Set the response as a series of pages response = ( - db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse( - db_system_initial_storage_sizes=[ - db_system_initial_storage_size.DbSystemInitialStorageSize(), - db_system_initial_storage_size.DbSystemInitialStorageSize(), - db_system_initial_storage_size.DbSystemInitialStorageSize(), + oracledatabase.ListAutonomousDatabasesResponse( + autonomous_databases=[ + autonomous_database.AutonomousDatabase(), + autonomous_database.AutonomousDatabase(), + autonomous_database.AutonomousDatabase(), ], next_page_token="abc", ), - db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse( - db_system_initial_storage_sizes=[], + oracledatabase.ListAutonomousDatabasesResponse( + autonomous_databases=[], next_page_token="def", ), - db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse( - db_system_initial_storage_sizes=[ - db_system_initial_storage_size.DbSystemInitialStorageSize(), + oracledatabase.ListAutonomousDatabasesResponse( + autonomous_databases=[ + autonomous_database.AutonomousDatabase(), ], next_page_token="ghi", ), - db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse( - db_system_initial_storage_sizes=[ - db_system_initial_storage_size.DbSystemInitialStorageSize(), - db_system_initial_storage_size.DbSystemInitialStorageSize(), + oracledatabase.ListAutonomousDatabasesResponse( + autonomous_databases=[ + autonomous_database.AutonomousDatabase(), + autonomous_database.AutonomousDatabase(), ], ), ) @@ -36918,10 +39750,7 @@ def test_list_db_system_initial_storage_sizes_rest_pager(transport: str = "rest" # Wrap the values into proper Response objs response = tuple( - db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse.to_json( - x - ) - for x in response + oracledatabase.ListAutonomousDatabasesResponse.to_json(x) for x in response ) return_values = tuple(Response() for i in response) for return_val, response_val in zip(return_values, response): @@ -36931,23 +39760,20 @@ def test_list_db_system_initial_storage_sizes_rest_pager(transport: str = "rest" sample_request = {"parent": "projects/sample1/locations/sample2"} - pager = client.list_db_system_initial_storage_sizes(request=sample_request) + pager = client.list_autonomous_databases(request=sample_request) results = list(pager) assert len(results) == 6 assert all( - isinstance(i, db_system_initial_storage_size.DbSystemInitialStorageSize) - for i in results + isinstance(i, autonomous_database.AutonomousDatabase) for i in results ) - pages = list( - client.list_db_system_initial_storage_sizes(request=sample_request).pages - ) + pages = list(client.list_autonomous_databases(request=sample_request).pages) for page_, token in zip(pages, ["abc", "def", "ghi", ""]): assert page_.raw_page.next_page_token == token -def test_list_databases_rest_use_cached_wrapped_rpc(): +def test_get_autonomous_database_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -36961,35 +39787,40 @@ def test_list_databases_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.list_databases in client._transport._wrapped_methods + assert ( + client._transport.get_autonomous_database + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.list_databases] = mock_rpc + client._transport._wrapped_methods[ + client._transport.get_autonomous_database + ] = mock_rpc request = {} - client.list_databases(request) + client.get_autonomous_database(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_databases(request) + client.get_autonomous_database(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_databases_rest_required_fields( - request_type=database.ListDatabasesRequest, +def test_get_autonomous_database_rest_required_fields( + request_type=oracledatabase.GetAutonomousDatabaseRequest, ): transport_class = transports.OracleDatabaseRestTransport request_init = {} - request_init["parent"] = "" + request_init["name"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -37000,29 +39831,21 @@ def test_list_databases_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_databases._get_unset_required_fields(jsonified_request) + ).get_autonomous_database._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["parent"] = "parent_value" + jsonified_request["name"] = "name_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_databases._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "filter", - "page_size", - "page_token", - ) - ) + ).get_autonomous_database._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), @@ -37031,7 +39854,7 @@ def test_list_databases_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = database.ListDatabasesResponse() + return_value = autonomous_database.AutonomousDatabase() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -37052,39 +39875,30 @@ def test_list_databases_rest_required_fields( response_value.status_code = 200 # Convert return value to protobuf type - return_value = database.ListDatabasesResponse.pb(return_value) + return_value = autonomous_database.AutonomousDatabase.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_databases(request) + response = client.get_autonomous_database(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_list_databases_rest_unset_required_fields(): +def test_get_autonomous_database_rest_unset_required_fields(): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.list_databases._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "filter", - "pageSize", - "pageToken", - ) - ) - & set(("parent",)) - ) + unset_fields = transport.get_autonomous_database._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) -def test_list_databases_rest_flattened(): +def test_get_autonomous_database_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -37093,14 +39907,16 @@ def test_list_databases_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = database.ListDatabasesResponse() + return_value = autonomous_database.AutonomousDatabase() # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} + sample_request = { + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + } # get truthy value for each flattened field mock_args = dict( - parent="parent_value", + name="name_value", ) mock_args.update(sample_request) @@ -37108,25 +39924,26 @@ def test_list_databases_rest_flattened(): response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = database.ListDatabasesResponse.pb(return_value) + return_value = autonomous_database.AutonomousDatabase.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_databases(**mock_args) + client.get_autonomous_database(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/databases" % client.transport._host, + "%s/v1/{name=projects/*/locations/*/autonomousDatabases/*}" + % client.transport._host, args[1], ) -def test_list_databases_rest_flattened_error(transport: str = "rest"): +def test_get_autonomous_database_rest_flattened_error(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -37135,74 +39952,13 @@ def test_list_databases_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_databases( - database.ListDatabasesRequest(), - parent="parent_value", - ) - - -def test_list_databases_rest_pager(transport: str = "rest"): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - database.ListDatabasesResponse( - databases=[ - database.Database(), - database.Database(), - database.Database(), - ], - next_page_token="abc", - ), - database.ListDatabasesResponse( - databases=[], - next_page_token="def", - ), - database.ListDatabasesResponse( - databases=[ - database.Database(), - ], - next_page_token="ghi", - ), - database.ListDatabasesResponse( - databases=[ - database.Database(), - database.Database(), - ], - ), + client.get_autonomous_database( + oracledatabase.GetAutonomousDatabaseRequest(), + name="name_value", ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple(database.ListDatabasesResponse.to_json(x) for x in response) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "projects/sample1/locations/sample2"} - - pager = client.list_databases(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, database.Database) for i in results) - - pages = list(client.list_databases(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token -def test_get_database_rest_use_cached_wrapped_rpc(): +def test_create_autonomous_database_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -37216,33 +39972,45 @@ def test_get_database_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.get_database in client._transport._wrapped_methods + assert ( + client._transport.create_autonomous_database + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.get_database] = mock_rpc + client._transport._wrapped_methods[ + client._transport.create_autonomous_database + ] = mock_rpc request = {} - client.get_database(request) + client.create_autonomous_database(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.get_database(request) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.create_autonomous_database(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_get_database_rest_required_fields(request_type=database.GetDatabaseRequest): +def test_create_autonomous_database_rest_required_fields( + request_type=oracledatabase.CreateAutonomousDatabaseRequest, +): transport_class = transports.OracleDatabaseRestTransport request_init = {} - request_init["name"] = "" + request_init["parent"] = "" + request_init["autonomous_database_id"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -37250,24 +40018,40 @@ def test_get_database_rest_required_fields(request_type=database.GetDatabaseRequ ) # verify fields with default values are dropped + assert "autonomousDatabaseId" not in jsonified_request unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_database._get_unset_required_fields(jsonified_request) + ).create_autonomous_database._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present + assert "autonomousDatabaseId" in jsonified_request + assert ( + jsonified_request["autonomousDatabaseId"] + == request_init["autonomous_database_id"] + ) - jsonified_request["name"] = "name_value" + jsonified_request["parent"] = "parent_value" + jsonified_request["autonomousDatabaseId"] = "autonomous_database_id_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_database._get_unset_required_fields(jsonified_request) + ).create_autonomous_database._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "autonomous_database_id", + "request_id", + ) + ) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "autonomousDatabaseId" in jsonified_request + assert jsonified_request["autonomousDatabaseId"] == "autonomous_database_id_value" client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), @@ -37276,7 +40060,7 @@ def test_get_database_rest_required_fields(request_type=database.GetDatabaseRequ request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = database.Database() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -37288,39 +40072,57 @@ def test_get_database_rest_required_fields(request_type=database.GetDatabaseRequ pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "post", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = database.Database.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_database(request) + response = client.create_autonomous_database(request) - expected_params = [("$alt", "json;enum-encoding=int")] + expected_params = [ + ( + "autonomousDatabaseId", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_get_database_rest_unset_required_fields(): +def test_create_autonomous_database_rest_unset_required_fields(): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.get_database._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + unset_fields = transport.create_autonomous_database._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "autonomousDatabaseId", + "requestId", + ) + ) + & set( + ( + "parent", + "autonomousDatabaseId", + "autonomousDatabase", + ) + ) + ) -def test_get_database_rest_flattened(): +def test_create_autonomous_database_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -37329,42 +40131,43 @@ def test_get_database_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = database.Database() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/databases/sample3" - } + sample_request = {"parent": "projects/sample1/locations/sample2"} # get truthy value for each flattened field mock_args = dict( - name="name_value", + parent="parent_value", + autonomous_database=gco_autonomous_database.AutonomousDatabase( + name="name_value" + ), + autonomous_database_id="autonomous_database_id_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = database.Database.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_database(**mock_args) + client.create_autonomous_database(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/databases/*}" % client.transport._host, + "%s/v1/{parent=projects/*/locations/*}/autonomousDatabases" + % client.transport._host, args[1], ) -def test_get_database_rest_flattened_error(transport: str = "rest"): +def test_create_autonomous_database_rest_flattened_error(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -37373,13 +40176,17 @@ def test_get_database_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.get_database( - database.GetDatabaseRequest(), - name="name_value", + client.create_autonomous_database( + oracledatabase.CreateAutonomousDatabaseRequest(), + parent="parent_value", + autonomous_database=gco_autonomous_database.AutonomousDatabase( + name="name_value" + ), + autonomous_database_id="autonomous_database_id_value", ) -def test_list_pluggable_databases_rest_use_cached_wrapped_rpc(): +def test_update_autonomous_database_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -37394,7 +40201,7 @@ def test_list_pluggable_databases_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.list_pluggable_databases + client._transport.update_autonomous_database in client._transport._wrapped_methods ) @@ -37404,29 +40211,32 @@ def test_list_pluggable_databases_rest_use_cached_wrapped_rpc(): "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ - client._transport.list_pluggable_databases + client._transport.update_autonomous_database ] = mock_rpc request = {} - client.list_pluggable_databases(request) + client.update_autonomous_database(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_pluggable_databases(request) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.update_autonomous_database(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_pluggable_databases_rest_required_fields( - request_type=pluggable_database.ListPluggableDatabasesRequest, +def test_update_autonomous_database_rest_required_fields( + request_type=oracledatabase.UpdateAutonomousDatabaseRequest, ): transport_class = transports.OracleDatabaseRestTransport request_init = {} - request_init["parent"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -37437,29 +40247,24 @@ def test_list_pluggable_databases_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_pluggable_databases._get_unset_required_fields(jsonified_request) + ).update_autonomous_database._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["parent"] = "parent_value" - unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_pluggable_databases._get_unset_required_fields(jsonified_request) + ).update_autonomous_database._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. assert not set(unset_fields) - set( ( - "filter", - "page_size", - "page_token", + "request_id", + "update_mask", ) ) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), @@ -37468,7 +40273,7 @@ def test_list_pluggable_databases_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = pluggable_database.ListPluggableDatabasesResponse() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -37480,50 +40285,45 @@ def test_list_pluggable_databases_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "patch", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = pluggable_database.ListPluggableDatabasesResponse.pb( - return_value - ) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_pluggable_databases(request) + response = client.update_autonomous_database(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_list_pluggable_databases_rest_unset_required_fields(): +def test_update_autonomous_database_rest_unset_required_fields(): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.list_pluggable_databases._get_unset_required_fields({}) + unset_fields = transport.update_autonomous_database._get_unset_required_fields({}) assert set(unset_fields) == ( set( ( - "filter", - "pageSize", - "pageToken", + "requestId", + "updateMask", ) ) - & set(("parent",)) + & set(("autonomousDatabase",)) ) -def test_list_pluggable_databases_rest_flattened(): +def test_update_autonomous_database_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -37532,43 +40332,46 @@ def test_list_pluggable_databases_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = pluggable_database.ListPluggableDatabasesResponse() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} + sample_request = { + "autonomous_database": { + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + } + } # get truthy value for each flattened field mock_args = dict( - parent="parent_value", + autonomous_database=gco_autonomous_database.AutonomousDatabase( + name="name_value" + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = pluggable_database.ListPluggableDatabasesResponse.pb( - return_value - ) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_pluggable_databases(**mock_args) + client.update_autonomous_database(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/pluggableDatabases" + "%s/v1/{autonomous_database.name=projects/*/locations/*/autonomousDatabases/*}" % client.transport._host, args[1], ) -def test_list_pluggable_databases_rest_flattened_error(transport: str = "rest"): +def test_update_autonomous_database_rest_flattened_error(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -37577,77 +40380,16 @@ def test_list_pluggable_databases_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_pluggable_databases( - pluggable_database.ListPluggableDatabasesRequest(), - parent="parent_value", - ) - - -def test_list_pluggable_databases_rest_pager(transport: str = "rest"): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - pluggable_database.ListPluggableDatabasesResponse( - pluggable_databases=[ - pluggable_database.PluggableDatabase(), - pluggable_database.PluggableDatabase(), - pluggable_database.PluggableDatabase(), - ], - next_page_token="abc", - ), - pluggable_database.ListPluggableDatabasesResponse( - pluggable_databases=[], - next_page_token="def", - ), - pluggable_database.ListPluggableDatabasesResponse( - pluggable_databases=[ - pluggable_database.PluggableDatabase(), - ], - next_page_token="ghi", - ), - pluggable_database.ListPluggableDatabasesResponse( - pluggable_databases=[ - pluggable_database.PluggableDatabase(), - pluggable_database.PluggableDatabase(), - ], + client.update_autonomous_database( + oracledatabase.UpdateAutonomousDatabaseRequest(), + autonomous_database=gco_autonomous_database.AutonomousDatabase( + name="name_value" ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple( - pluggable_database.ListPluggableDatabasesResponse.to_json(x) - for x in response - ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "projects/sample1/locations/sample2"} - - pager = client.list_pluggable_databases(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, pluggable_database.PluggableDatabase) for i in results) - - pages = list(client.list_pluggable_databases(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token -def test_get_pluggable_database_rest_use_cached_wrapped_rpc(): +def test_delete_autonomous_database_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -37662,7 +40404,7 @@ def test_get_pluggable_database_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.get_pluggable_database + client._transport.delete_autonomous_database in client._transport._wrapped_methods ) @@ -37671,25 +40413,29 @@ def test_get_pluggable_database_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.get_pluggable_database] = ( - mock_rpc - ) + client._transport._wrapped_methods[ + client._transport.delete_autonomous_database + ] = mock_rpc request = {} - client.get_pluggable_database(request) + client.delete_autonomous_database(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.get_pluggable_database(request) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_autonomous_database(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_get_pluggable_database_rest_required_fields( - request_type=pluggable_database.GetPluggableDatabaseRequest, +def test_delete_autonomous_database_rest_required_fields( + request_type=oracledatabase.DeleteAutonomousDatabaseRequest, ): transport_class = transports.OracleDatabaseRestTransport @@ -37705,7 +40451,7 @@ def test_get_pluggable_database_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_pluggable_database._get_unset_required_fields(jsonified_request) + ).delete_autonomous_database._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -37714,7 +40460,9 @@ def test_get_pluggable_database_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_pluggable_database._get_unset_required_fields(jsonified_request) + ).delete_autonomous_database._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("request_id",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -37728,7 +40476,7 @@ def test_get_pluggable_database_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = pluggable_database.PluggableDatabase() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -37740,39 +40488,36 @@ def test_get_pluggable_database_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "delete", "query_params": pb_request, } transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = pluggable_database.PluggableDatabase.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_pluggable_database(request) + response = client.delete_autonomous_database(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_get_pluggable_database_rest_unset_required_fields(): +def test_delete_autonomous_database_rest_unset_required_fields(): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.get_pluggable_database._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + unset_fields = transport.delete_autonomous_database._get_unset_required_fields({}) + assert set(unset_fields) == (set(("requestId",)) & set(("name",))) -def test_get_pluggable_database_rest_flattened(): +def test_delete_autonomous_database_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -37781,11 +40526,11 @@ def test_get_pluggable_database_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = pluggable_database.PluggableDatabase() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method sample_request = { - "name": "projects/sample1/locations/sample2/pluggableDatabases/sample3" + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" } # get truthy value for each flattened field @@ -37797,27 +40542,25 @@ def test_get_pluggable_database_rest_flattened(): # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = pluggable_database.PluggableDatabase.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_pluggable_database(**mock_args) + client.delete_autonomous_database(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/pluggableDatabases/*}" + "%s/v1/{name=projects/*/locations/*/autonomousDatabases/*}" % client.transport._host, args[1], ) -def test_get_pluggable_database_rest_flattened_error(transport: str = "rest"): +def test_delete_autonomous_database_rest_flattened_error(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -37826,13 +40569,13 @@ def test_get_pluggable_database_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.get_pluggable_database( - pluggable_database.GetPluggableDatabaseRequest(), + client.delete_autonomous_database( + oracledatabase.DeleteAutonomousDatabaseRequest(), name="name_value", ) -def test_list_db_systems_rest_use_cached_wrapped_rpc(): +def test_restore_autonomous_database_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -37846,35 +40589,44 @@ def test_list_db_systems_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.list_db_systems in client._transport._wrapped_methods + assert ( + client._transport.restore_autonomous_database + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.list_db_systems] = mock_rpc + client._transport._wrapped_methods[ + client._transport.restore_autonomous_database + ] = mock_rpc request = {} - client.list_db_systems(request) + client.restore_autonomous_database(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_db_systems(request) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.restore_autonomous_database(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_db_systems_rest_required_fields( - request_type=db_system.ListDbSystemsRequest, +def test_restore_autonomous_database_rest_required_fields( + request_type=oracledatabase.RestoreAutonomousDatabaseRequest, ): transport_class = transports.OracleDatabaseRestTransport request_init = {} - request_init["parent"] = "" + request_init["name"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -37885,30 +40637,21 @@ def test_list_db_systems_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_db_systems._get_unset_required_fields(jsonified_request) + ).restore_autonomous_database._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["parent"] = "parent_value" + jsonified_request["name"] = "name_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_db_systems._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "filter", - "order_by", - "page_size", - "page_token", - ) - ) + ).restore_autonomous_database._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), @@ -37917,7 +40660,7 @@ def test_list_db_systems_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = db_system.ListDbSystemsResponse() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -37929,49 +40672,45 @@ def test_list_db_systems_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "post", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = db_system.ListDbSystemsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_db_systems(request) + response = client.restore_autonomous_database(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_list_db_systems_rest_unset_required_fields(): +def test_restore_autonomous_database_rest_unset_required_fields(): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.list_db_systems._get_unset_required_fields({}) + unset_fields = transport.restore_autonomous_database._get_unset_required_fields({}) assert set(unset_fields) == ( - set( + set(()) + & set( ( - "filter", - "orderBy", - "pageSize", - "pageToken", + "name", + "restoreTime", ) ) - & set(("parent",)) ) -def test_list_db_systems_rest_flattened(): +def test_restore_autonomous_database_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -37980,40 +40719,42 @@ def test_list_db_systems_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = db_system.ListDbSystemsResponse() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} + sample_request = { + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + } # get truthy value for each flattened field mock_args = dict( - parent="parent_value", + name="name_value", + restore_time=timestamp_pb2.Timestamp(seconds=751), ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = db_system.ListDbSystemsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_db_systems(**mock_args) + client.restore_autonomous_database(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/dbSystems" % client.transport._host, + "%s/v1/{name=projects/*/locations/*/autonomousDatabases/*}:restore" + % client.transport._host, args[1], ) -def test_list_db_systems_rest_flattened_error(transport: str = "rest"): +def test_restore_autonomous_database_rest_flattened_error(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -38022,74 +40763,14 @@ def test_list_db_systems_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_db_systems( - db_system.ListDbSystemsRequest(), - parent="parent_value", - ) - - -def test_list_db_systems_rest_pager(transport: str = "rest"): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - db_system.ListDbSystemsResponse( - db_systems=[ - db_system.DbSystem(), - db_system.DbSystem(), - db_system.DbSystem(), - ], - next_page_token="abc", - ), - db_system.ListDbSystemsResponse( - db_systems=[], - next_page_token="def", - ), - db_system.ListDbSystemsResponse( - db_systems=[ - db_system.DbSystem(), - ], - next_page_token="ghi", - ), - db_system.ListDbSystemsResponse( - db_systems=[ - db_system.DbSystem(), - db_system.DbSystem(), - ], - ), + client.restore_autonomous_database( + oracledatabase.RestoreAutonomousDatabaseRequest(), + name="name_value", + restore_time=timestamp_pb2.Timestamp(seconds=751), ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple(db_system.ListDbSystemsResponse.to_json(x) for x in response) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "projects/sample1/locations/sample2"} - - pager = client.list_db_systems(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, db_system.DbSystem) for i in results) - - pages = list(client.list_db_systems(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token -def test_get_db_system_rest_use_cached_wrapped_rpc(): +def test_generate_autonomous_database_wallet_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -38103,33 +40784,41 @@ def test_get_db_system_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.get_db_system in client._transport._wrapped_methods + assert ( + client._transport.generate_autonomous_database_wallet + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.get_db_system] = mock_rpc + client._transport._wrapped_methods[ + client._transport.generate_autonomous_database_wallet + ] = mock_rpc request = {} - client.get_db_system(request) + client.generate_autonomous_database_wallet(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.get_db_system(request) + client.generate_autonomous_database_wallet(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_get_db_system_rest_required_fields(request_type=db_system.GetDbSystemRequest): +def test_generate_autonomous_database_wallet_rest_required_fields( + request_type=oracledatabase.GenerateAutonomousDatabaseWalletRequest, +): transport_class = transports.OracleDatabaseRestTransport request_init = {} request_init["name"] = "" + request_init["password"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -38140,21 +40829,24 @@ def test_get_db_system_rest_required_fields(request_type=db_system.GetDbSystemRe unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_db_system._get_unset_required_fields(jsonified_request) + ).generate_autonomous_database_wallet._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present jsonified_request["name"] = "name_value" + jsonified_request["password"] = "password_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_db_system._get_unset_required_fields(jsonified_request) + ).generate_autonomous_database_wallet._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone assert "name" in jsonified_request assert jsonified_request["name"] == "name_value" + assert "password" in jsonified_request + assert jsonified_request["password"] == "password_value" client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), @@ -38163,7 +40855,7 @@ def test_get_db_system_rest_required_fields(request_type=db_system.GetDbSystemRe request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = db_system.DbSystem() + return_value = oracledatabase.GenerateAutonomousDatabaseWalletResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -38175,39 +40867,52 @@ def test_get_db_system_rest_required_fields(request_type=db_system.GetDbSystemRe pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "post", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = db_system.DbSystem.pb(return_value) + return_value = oracledatabase.GenerateAutonomousDatabaseWalletResponse.pb( + return_value + ) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_db_system(request) + response = client.generate_autonomous_database_wallet(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_get_db_system_rest_unset_required_fields(): +def test_generate_autonomous_database_wallet_rest_unset_required_fields(): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.get_db_system._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + unset_fields = ( + transport.generate_autonomous_database_wallet._get_unset_required_fields({}) + ) + assert set(unset_fields) == ( + set(()) + & set( + ( + "name", + "password", + ) + ) + ) -def test_get_db_system_rest_flattened(): +def test_generate_autonomous_database_wallet_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -38216,16 +40921,19 @@ def test_get_db_system_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = db_system.DbSystem() + return_value = oracledatabase.GenerateAutonomousDatabaseWalletResponse() # get arguments that satisfy an http rule for this method sample_request = { - "name": "projects/sample1/locations/sample2/dbSystems/sample3" + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" } # get truthy value for each flattened field mock_args = dict( name="name_value", + type_=autonomous_database.GenerateType.ALL, + is_regional=True, + password="password_value", ) mock_args.update(sample_request) @@ -38233,25 +40941,30 @@ def test_get_db_system_rest_flattened(): response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = db_system.DbSystem.pb(return_value) + return_value = oracledatabase.GenerateAutonomousDatabaseWalletResponse.pb( + return_value + ) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_db_system(**mock_args) + client.generate_autonomous_database_wallet(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/dbSystems/*}" % client.transport._host, + "%s/v1/{name=projects/*/locations/*/autonomousDatabases/*}:generateWallet" + % client.transport._host, args[1], ) -def test_get_db_system_rest_flattened_error(transport: str = "rest"): +def test_generate_autonomous_database_wallet_rest_flattened_error( + transport: str = "rest", +): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -38260,13 +40973,16 @@ def test_get_db_system_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.get_db_system( - db_system.GetDbSystemRequest(), + client.generate_autonomous_database_wallet( + oracledatabase.GenerateAutonomousDatabaseWalletRequest(), name="name_value", + type_=autonomous_database.GenerateType.ALL, + is_regional=True, + password="password_value", ) -def test_create_db_system_rest_use_cached_wrapped_rpc(): +def test_list_autonomous_db_versions_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -38280,42 +40996,40 @@ def test_create_db_system_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.create_db_system in client._transport._wrapped_methods + assert ( + client._transport.list_autonomous_db_versions + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.create_db_system] = ( - mock_rpc - ) + client._transport._wrapped_methods[ + client._transport.list_autonomous_db_versions + ] = mock_rpc request = {} - client.create_db_system(request) + client.list_autonomous_db_versions(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.create_db_system(request) + client.list_autonomous_db_versions(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_create_db_system_rest_required_fields( - request_type=gco_db_system.CreateDbSystemRequest, +def test_list_autonomous_db_versions_rest_required_fields( + request_type=oracledatabase.ListAutonomousDbVersionsRequest, ): transport_class = transports.OracleDatabaseRestTransport request_init = {} request_init["parent"] = "" - request_init["db_system_id"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -38323,28 +41037,24 @@ def test_create_db_system_rest_required_fields( ) # verify fields with default values are dropped - assert "dbSystemId" not in jsonified_request unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_db_system._get_unset_required_fields(jsonified_request) + ).list_autonomous_db_versions._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - assert "dbSystemId" in jsonified_request - assert jsonified_request["dbSystemId"] == request_init["db_system_id"] jsonified_request["parent"] = "parent_value" - jsonified_request["dbSystemId"] = "db_system_id_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_db_system._get_unset_required_fields(jsonified_request) + ).list_autonomous_db_versions._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. assert not set(unset_fields) - set( ( - "db_system_id", - "request_id", + "page_size", + "page_token", ) ) jsonified_request.update(unset_fields) @@ -38352,8 +41062,6 @@ def test_create_db_system_rest_required_fields( # verify required fields with non-default values are left alone assert "parent" in jsonified_request assert jsonified_request["parent"] == "parent_value" - assert "dbSystemId" in jsonified_request - assert jsonified_request["dbSystemId"] == "db_system_id_value" client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), @@ -38362,7 +41070,7 @@ def test_create_db_system_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = oracledatabase.ListAutonomousDbVersionsResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -38374,57 +41082,49 @@ def test_create_db_system_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "post", + "method": "get", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = oracledatabase.ListAutonomousDbVersionsResponse.pb( + return_value + ) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_db_system(request) + response = client.list_autonomous_db_versions(request) - expected_params = [ - ( - "dbSystemId", - "", - ), - ("$alt", "json;enum-encoding=int"), - ] + expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_create_db_system_rest_unset_required_fields(): +def test_list_autonomous_db_versions_rest_unset_required_fields(): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.create_db_system._get_unset_required_fields({}) + unset_fields = transport.list_autonomous_db_versions._get_unset_required_fields({}) assert set(unset_fields) == ( set( ( - "dbSystemId", - "requestId", - ) - ) - & set( - ( - "parent", - "dbSystemId", - "dbSystem", + "pageSize", + "pageToken", ) ) + & set(("parent",)) ) -def test_create_db_system_rest_flattened(): +def test_list_autonomous_db_versions_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -38433,7 +41133,7 @@ def test_create_db_system_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = oracledatabase.ListAutonomousDbVersionsResponse() # get arguments that satisfy an http rule for this method sample_request = {"parent": "projects/sample1/locations/sample2"} @@ -38441,32 +41141,33 @@ def test_create_db_system_rest_flattened(): # get truthy value for each flattened field mock_args = dict( parent="parent_value", - db_system=gco_db_system.DbSystem(name="name_value"), - db_system_id="db_system_id_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = oracledatabase.ListAutonomousDbVersionsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_db_system(**mock_args) + client.list_autonomous_db_versions(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/dbSystems" % client.transport._host, + "%s/v1/{parent=projects/*/locations/*}/autonomousDbVersions" + % client.transport._host, args[1], ) -def test_create_db_system_rest_flattened_error(transport: str = "rest"): +def test_list_autonomous_db_versions_rest_flattened_error(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -38475,15 +41176,78 @@ def test_create_db_system_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.create_db_system( - gco_db_system.CreateDbSystemRequest(), + client.list_autonomous_db_versions( + oracledatabase.ListAutonomousDbVersionsRequest(), parent="parent_value", - db_system=gco_db_system.DbSystem(name="name_value"), - db_system_id="db_system_id_value", ) -def test_delete_db_system_rest_use_cached_wrapped_rpc(): +def test_list_autonomous_db_versions_rest_pager(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + oracledatabase.ListAutonomousDbVersionsResponse( + autonomous_db_versions=[ + autonomous_db_version.AutonomousDbVersion(), + autonomous_db_version.AutonomousDbVersion(), + autonomous_db_version.AutonomousDbVersion(), + ], + next_page_token="abc", + ), + oracledatabase.ListAutonomousDbVersionsResponse( + autonomous_db_versions=[], + next_page_token="def", + ), + oracledatabase.ListAutonomousDbVersionsResponse( + autonomous_db_versions=[ + autonomous_db_version.AutonomousDbVersion(), + ], + next_page_token="ghi", + ), + oracledatabase.ListAutonomousDbVersionsResponse( + autonomous_db_versions=[ + autonomous_db_version.AutonomousDbVersion(), + autonomous_db_version.AutonomousDbVersion(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + oracledatabase.ListAutonomousDbVersionsResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_autonomous_db_versions(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, autonomous_db_version.AutonomousDbVersion) for i in results + ) + + pages = list(client.list_autonomous_db_versions(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_list_autonomous_database_character_sets_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -38497,41 +41261,40 @@ def test_delete_db_system_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.delete_db_system in client._transport._wrapped_methods + assert ( + client._transport.list_autonomous_database_character_sets + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.delete_db_system] = ( - mock_rpc - ) + client._transport._wrapped_methods[ + client._transport.list_autonomous_database_character_sets + ] = mock_rpc request = {} - client.delete_db_system(request) + client.list_autonomous_database_character_sets(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.delete_db_system(request) + client.list_autonomous_database_character_sets(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_delete_db_system_rest_required_fields( - request_type=db_system.DeleteDbSystemRequest, +def test_list_autonomous_database_character_sets_rest_required_fields( + request_type=oracledatabase.ListAutonomousDatabaseCharacterSetsRequest, ): transport_class = transports.OracleDatabaseRestTransport request_init = {} - request_init["name"] = "" + request_init["parent"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -38542,23 +41305,33 @@ def test_delete_db_system_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_db_system._get_unset_required_fields(jsonified_request) + ).list_autonomous_database_character_sets._get_unset_required_fields( + jsonified_request + ) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["name"] = "name_value" + jsonified_request["parent"] = "parent_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_db_system._get_unset_required_fields(jsonified_request) + ).list_autonomous_database_character_sets._get_unset_required_fields( + jsonified_request + ) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("request_id",)) + assert not set(unset_fields) - set( + ( + "filter", + "page_size", + "page_token", + ) + ) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), @@ -38567,7 +41340,7 @@ def test_delete_db_system_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = oracledatabase.ListAutonomousDatabaseCharacterSetsResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -38579,37 +41352,55 @@ def test_delete_db_system_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "delete", + "method": "get", "query_params": pb_request, } transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = ( + oracledatabase.ListAutonomousDatabaseCharacterSetsResponse.pb( + return_value + ) + ) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_db_system(request) + response = client.list_autonomous_database_character_sets(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_delete_db_system_rest_unset_required_fields(): +def test_list_autonomous_database_character_sets_rest_unset_required_fields(): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.delete_db_system._get_unset_required_fields({}) - assert set(unset_fields) == (set(("requestId",)) & set(("name",))) - - -def test_delete_db_system_rest_flattened(): - client = OracleDatabaseClient( + unset_fields = ( + transport.list_autonomous_database_character_sets._get_unset_required_fields({}) + ) + assert set(unset_fields) == ( + set( + ( + "filter", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +def test_list_autonomous_database_character_sets_rest_flattened(): + client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) @@ -38617,40 +41408,45 @@ def test_delete_db_system_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = oracledatabase.ListAutonomousDatabaseCharacterSetsResponse() # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/dbSystems/sample3" - } + sample_request = {"parent": "projects/sample1/locations/sample2"} # get truthy value for each flattened field mock_args = dict( - name="name_value", + parent="parent_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = oracledatabase.ListAutonomousDatabaseCharacterSetsResponse.pb( + return_value + ) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_db_system(**mock_args) + client.list_autonomous_database_character_sets(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/dbSystems/*}" % client.transport._host, + "%s/v1/{parent=projects/*/locations/*}/autonomousDatabaseCharacterSets" + % client.transport._host, args[1], ) -def test_delete_db_system_rest_flattened_error(transport: str = "rest"): +def test_list_autonomous_database_character_sets_rest_flattened_error( + transport: str = "rest", +): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -38659,13 +41455,84 @@ def test_delete_db_system_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.delete_db_system( - db_system.DeleteDbSystemRequest(), - name="name_value", + client.list_autonomous_database_character_sets( + oracledatabase.ListAutonomousDatabaseCharacterSetsRequest(), + parent="parent_value", ) -def test_list_db_versions_rest_use_cached_wrapped_rpc(): +def test_list_autonomous_database_character_sets_rest_pager(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + oracledatabase.ListAutonomousDatabaseCharacterSetsResponse( + autonomous_database_character_sets=[ + autonomous_database_character_set.AutonomousDatabaseCharacterSet(), + autonomous_database_character_set.AutonomousDatabaseCharacterSet(), + autonomous_database_character_set.AutonomousDatabaseCharacterSet(), + ], + next_page_token="abc", + ), + oracledatabase.ListAutonomousDatabaseCharacterSetsResponse( + autonomous_database_character_sets=[], + next_page_token="def", + ), + oracledatabase.ListAutonomousDatabaseCharacterSetsResponse( + autonomous_database_character_sets=[ + autonomous_database_character_set.AutonomousDatabaseCharacterSet(), + ], + next_page_token="ghi", + ), + oracledatabase.ListAutonomousDatabaseCharacterSetsResponse( + autonomous_database_character_sets=[ + autonomous_database_character_set.AutonomousDatabaseCharacterSet(), + autonomous_database_character_set.AutonomousDatabaseCharacterSet(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + oracledatabase.ListAutonomousDatabaseCharacterSetsResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_autonomous_database_character_sets(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance( + i, autonomous_database_character_set.AutonomousDatabaseCharacterSet + ) + for i in results + ) + + pages = list( + client.list_autonomous_database_character_sets(request=sample_request).pages + ) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_list_autonomous_database_backups_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -38679,32 +41546,35 @@ def test_list_db_versions_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.list_db_versions in client._transport._wrapped_methods + assert ( + client._transport.list_autonomous_database_backups + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.list_db_versions] = ( - mock_rpc - ) + client._transport._wrapped_methods[ + client._transport.list_autonomous_database_backups + ] = mock_rpc request = {} - client.list_db_versions(request) + client.list_autonomous_database_backups(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_db_versions(request) + client.list_autonomous_database_backups(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_db_versions_rest_required_fields( - request_type=db_version.ListDbVersionsRequest, +def test_list_autonomous_database_backups_rest_required_fields( + request_type=oracledatabase.ListAutonomousDatabaseBackupsRequest, ): transport_class = transports.OracleDatabaseRestTransport @@ -38720,7 +41590,7 @@ def test_list_db_versions_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_db_versions._get_unset_required_fields(jsonified_request) + ).list_autonomous_database_backups._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -38729,7 +41599,7 @@ def test_list_db_versions_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_db_versions._get_unset_required_fields(jsonified_request) + ).list_autonomous_database_backups._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. assert not set(unset_fields) - set( ( @@ -38751,7 +41621,7 @@ def test_list_db_versions_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = db_version.ListDbVersionsResponse() + return_value = oracledatabase.ListAutonomousDatabaseBackupsResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -38772,26 +41642,30 @@ def test_list_db_versions_rest_required_fields( response_value.status_code = 200 # Convert return value to protobuf type - return_value = db_version.ListDbVersionsResponse.pb(return_value) + return_value = oracledatabase.ListAutonomousDatabaseBackupsResponse.pb( + return_value + ) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_db_versions(request) + response = client.list_autonomous_database_backups(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_list_db_versions_rest_unset_required_fields(): +def test_list_autonomous_database_backups_rest_unset_required_fields(): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.list_db_versions._get_unset_required_fields({}) + unset_fields = ( + transport.list_autonomous_database_backups._get_unset_required_fields({}) + ) assert set(unset_fields) == ( set( ( @@ -38804,7 +41678,7 @@ def test_list_db_versions_rest_unset_required_fields(): ) -def test_list_db_versions_rest_flattened(): +def test_list_autonomous_database_backups_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -38813,7 +41687,7 @@ def test_list_db_versions_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = db_version.ListDbVersionsResponse() + return_value = oracledatabase.ListAutonomousDatabaseBackupsResponse() # get arguments that satisfy an http rule for this method sample_request = {"parent": "projects/sample1/locations/sample2"} @@ -38828,25 +41702,28 @@ def test_list_db_versions_rest_flattened(): response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = db_version.ListDbVersionsResponse.pb(return_value) + return_value = oracledatabase.ListAutonomousDatabaseBackupsResponse.pb( + return_value + ) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_db_versions(**mock_args) + client.list_autonomous_database_backups(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/dbVersions" % client.transport._host, + "%s/v1/{parent=projects/*/locations/*}/autonomousDatabaseBackups" + % client.transport._host, args[1], ) -def test_list_db_versions_rest_flattened_error(transport: str = "rest"): +def test_list_autonomous_database_backups_rest_flattened_error(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -38855,13 +41732,13 @@ def test_list_db_versions_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_db_versions( - db_version.ListDbVersionsRequest(), + client.list_autonomous_database_backups( + oracledatabase.ListAutonomousDatabaseBackupsRequest(), parent="parent_value", ) -def test_list_db_versions_rest_pager(transport: str = "rest"): +def test_list_autonomous_database_backups_rest_pager(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -38873,28 +41750,28 @@ def test_list_db_versions_rest_pager(transport: str = "rest"): # with mock.patch.object(path_template, 'transcode') as transcode: # Set the response as a series of pages response = ( - db_version.ListDbVersionsResponse( - db_versions=[ - db_version.DbVersion(), - db_version.DbVersion(), - db_version.DbVersion(), + oracledatabase.ListAutonomousDatabaseBackupsResponse( + autonomous_database_backups=[ + autonomous_db_backup.AutonomousDatabaseBackup(), + autonomous_db_backup.AutonomousDatabaseBackup(), + autonomous_db_backup.AutonomousDatabaseBackup(), ], next_page_token="abc", ), - db_version.ListDbVersionsResponse( - db_versions=[], + oracledatabase.ListAutonomousDatabaseBackupsResponse( + autonomous_database_backups=[], next_page_token="def", ), - db_version.ListDbVersionsResponse( - db_versions=[ - db_version.DbVersion(), + oracledatabase.ListAutonomousDatabaseBackupsResponse( + autonomous_database_backups=[ + autonomous_db_backup.AutonomousDatabaseBackup(), ], next_page_token="ghi", ), - db_version.ListDbVersionsResponse( - db_versions=[ - db_version.DbVersion(), - db_version.DbVersion(), + oracledatabase.ListAutonomousDatabaseBackupsResponse( + autonomous_database_backups=[ + autonomous_db_backup.AutonomousDatabaseBackup(), + autonomous_db_backup.AutonomousDatabaseBackup(), ], ), ) @@ -38902,7 +41779,10 @@ def test_list_db_versions_rest_pager(transport: str = "rest"): response = response + response # Wrap the values into proper Response objs - response = tuple(db_version.ListDbVersionsResponse.to_json(x) for x in response) + response = tuple( + oracledatabase.ListAutonomousDatabaseBackupsResponse.to_json(x) + for x in response + ) return_values = tuple(Response() for i in response) for return_val, response_val in zip(return_values, response): return_val._content = response_val.encode("UTF-8") @@ -38911,18 +41791,23 @@ def test_list_db_versions_rest_pager(transport: str = "rest"): sample_request = {"parent": "projects/sample1/locations/sample2"} - pager = client.list_db_versions(request=sample_request) + pager = client.list_autonomous_database_backups(request=sample_request) results = list(pager) assert len(results) == 6 - assert all(isinstance(i, db_version.DbVersion) for i in results) + assert all( + isinstance(i, autonomous_db_backup.AutonomousDatabaseBackup) + for i in results + ) - pages = list(client.list_db_versions(request=sample_request).pages) + pages = list( + client.list_autonomous_database_backups(request=sample_request).pages + ) for page_, token in zip(pages, ["abc", "def", "ghi", ""]): assert page_.raw_page.next_page_token == token -def test_list_database_character_sets_rest_use_cached_wrapped_rpc(): +def test_stop_autonomous_database_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -38937,7 +41822,7 @@ def test_list_database_character_sets_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.list_database_character_sets + client._transport.stop_autonomous_database in client._transport._wrapped_methods ) @@ -38947,29 +41832,33 @@ def test_list_database_character_sets_rest_use_cached_wrapped_rpc(): "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ - client._transport.list_database_character_sets + client._transport.stop_autonomous_database ] = mock_rpc request = {} - client.list_database_character_sets(request) + client.stop_autonomous_database(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_database_character_sets(request) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.stop_autonomous_database(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_database_character_sets_rest_required_fields( - request_type=database_character_set.ListDatabaseCharacterSetsRequest, +def test_stop_autonomous_database_rest_required_fields( + request_type=oracledatabase.StopAutonomousDatabaseRequest, ): transport_class = transports.OracleDatabaseRestTransport request_init = {} - request_init["parent"] = "" + request_init["name"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -38980,29 +41869,21 @@ def test_list_database_character_sets_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_database_character_sets._get_unset_required_fields(jsonified_request) + ).stop_autonomous_database._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["parent"] = "parent_value" + jsonified_request["name"] = "name_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_database_character_sets._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "filter", - "page_size", - "page_token", - ) - ) + ).stop_autonomous_database._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), @@ -39011,7 +41892,7 @@ def test_list_database_character_sets_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = database_character_set.ListDatabaseCharacterSetsResponse() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -39023,50 +41904,37 @@ def test_list_database_character_sets_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "post", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = database_character_set.ListDatabaseCharacterSetsResponse.pb( - return_value - ) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_database_character_sets(request) + response = client.stop_autonomous_database(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_list_database_character_sets_rest_unset_required_fields(): +def test_stop_autonomous_database_rest_unset_required_fields(): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.list_database_character_sets._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "filter", - "pageSize", - "pageToken", - ) - ) - & set(("parent",)) - ) + unset_fields = transport.stop_autonomous_database._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) -def test_list_database_character_sets_rest_flattened(): +def test_stop_autonomous_database_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -39075,43 +41943,41 @@ def test_list_database_character_sets_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = database_character_set.ListDatabaseCharacterSetsResponse() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} + sample_request = { + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + } # get truthy value for each flattened field mock_args = dict( - parent="parent_value", + name="name_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = database_character_set.ListDatabaseCharacterSetsResponse.pb( - return_value - ) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_database_character_sets(**mock_args) + client.stop_autonomous_database(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/databaseCharacterSets" + "%s/v1/{name=projects/*/locations/*/autonomousDatabases/*}:stop" % client.transport._host, args[1], ) -def test_list_database_character_sets_rest_flattened_error(transport: str = "rest"): +def test_stop_autonomous_database_rest_flattened_error(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -39120,3077 +41986,20207 @@ def test_list_database_character_sets_rest_flattened_error(transport: str = "res # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_database_character_sets( - database_character_set.ListDatabaseCharacterSetsRequest(), - parent="parent_value", + client.stop_autonomous_database( + oracledatabase.StopAutonomousDatabaseRequest(), + name="name_value", ) -def test_list_database_character_sets_rest_pager(transport: str = "rest"): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - database_character_set.ListDatabaseCharacterSetsResponse( - database_character_sets=[ - database_character_set.DatabaseCharacterSet(), - database_character_set.DatabaseCharacterSet(), - database_character_set.DatabaseCharacterSet(), - ], - next_page_token="abc", - ), - database_character_set.ListDatabaseCharacterSetsResponse( - database_character_sets=[], - next_page_token="def", - ), - database_character_set.ListDatabaseCharacterSetsResponse( - database_character_sets=[ - database_character_set.DatabaseCharacterSet(), - ], - next_page_token="ghi", - ), - database_character_set.ListDatabaseCharacterSetsResponse( - database_character_sets=[ - database_character_set.DatabaseCharacterSet(), - database_character_set.DatabaseCharacterSet(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple( - database_character_set.ListDatabaseCharacterSetsResponse.to_json(x) - for x in response +def test_start_autonomous_database_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "projects/sample1/locations/sample2"} - pager = client.list_database_character_sets(request=sample_request) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - results = list(pager) - assert len(results) == 6 - assert all( - isinstance(i, database_character_set.DatabaseCharacterSet) for i in results + # Ensure method has been cached + assert ( + client._transport.start_autonomous_database + in client._transport._wrapped_methods ) - pages = list(client.list_database_character_sets(request=sample_request).pages) - 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.OracleDatabaseGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. ) + client._transport._wrapped_methods[ + client._transport.start_autonomous_database + ] = mock_rpc - # It is an error to provide a credentials file and a transport instance. - transport = transports.OracleDatabaseGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = OracleDatabaseClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) + request = {} + client.start_autonomous_database(request) - # It is an error to provide an api_key and a transport instance. - transport = transports.OracleDatabaseGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = OracleDatabaseClient( - client_options=options, - transport=transport, - ) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = OracleDatabaseClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() - # It is an error to provide scopes and a transport instance. - transport = transports.OracleDatabaseGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = OracleDatabaseClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) + client.start_autonomous_database(request) + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.OracleDatabaseGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = OracleDatabaseClient(transport=transport) - assert client.transport is transport +def test_start_autonomous_database_rest_required_fields( + request_type=oracledatabase.StartAutonomousDatabaseRequest, +): + transport_class = transports.OracleDatabaseRestTransport -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.OracleDatabaseGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) ) - channel = transport.grpc_channel - assert channel - transport = transports.OracleDatabaseGrpcAsyncIOTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel + # verify fields with default values are dropped + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).start_autonomous_database._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) -@pytest.mark.parametrize( - "transport_class", - [ - transports.OracleDatabaseGrpcTransport, - transports.OracleDatabaseGrpcAsyncIOTransport, - transports.OracleDatabaseRestTransport, - ], -) -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() + # verify required fields with default values are now present + jsonified_request["name"] = "name_value" -def test_transport_kind_grpc(): - transport = OracleDatabaseClient.get_transport_class("grpc")( + unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ) - assert transport.kind == "grpc" + ).start_autonomous_database._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" -def test_initialize_client_w_grpc(): client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - assert client is not None + request = request_type(**request_init) + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_cloud_exadata_infrastructures_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_cloud_exadata_infrastructures), "__call__" - ) as call: - call.return_value = oracledatabase.ListCloudExadataInfrastructuresResponse() - client.list_cloud_exadata_infrastructures(request=None) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.ListCloudExadataInfrastructuresRequest() - assert args[0] == request_msg + response = client.start_autonomous_database(request) + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_cloud_exadata_infrastructure_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_cloud_exadata_infrastructure), "__call__" - ) as call: - call.return_value = exadata_infra.CloudExadataInfrastructure() - client.get_cloud_exadata_infrastructure(request=None) +def test_start_autonomous_database_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.GetCloudExadataInfrastructureRequest() - assert args[0] == request_msg + unset_fields = transport.start_autonomous_database._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_create_cloud_exadata_infrastructure_empty_call_grpc(): +def test_start_autonomous_database_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport="rest", ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_cloud_exadata_infrastructure), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.create_cloud_exadata_infrastructure(request=None) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.CreateCloudExadataInfrastructureRequest() - assert args[0] == request_msg + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + } + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_delete_cloud_exadata_infrastructure_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_cloud_exadata_infrastructure), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.delete_cloud_exadata_infrastructure(request=None) + client.start_autonomous_database(**mock_args) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.DeleteCloudExadataInfrastructureRequest() - assert args[0] == request_msg + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/autonomousDatabases/*}:start" + % client.transport._host, + args[1], + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_cloud_vm_clusters_empty_call_grpc(): +def test_start_autonomous_database_rest_flattened_error(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport=transport, ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_cloud_vm_clusters), "__call__" - ) as call: - call.return_value = oracledatabase.ListCloudVmClustersResponse() - client.list_cloud_vm_clusters(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.ListCloudVmClustersRequest() - assert args[0] == request_msg - + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.start_autonomous_database( + oracledatabase.StartAutonomousDatabaseRequest(), + name="name_value", + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_cloud_vm_cluster_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_cloud_vm_cluster), "__call__" - ) as call: - call.return_value = vm_cluster.CloudVmCluster() - client.get_cloud_vm_cluster(request=None) +def test_restart_autonomous_database_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.GetCloudVmClusterRequest() - assert args[0] == request_msg + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + # Ensure method has been cached + assert ( + client._transport.restart_autonomous_database + in client._transport._wrapped_methods + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_create_cloud_vm_cluster_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.restart_autonomous_database + ] = mock_rpc - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_cloud_vm_cluster), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.create_cloud_vm_cluster(request=None) + request = {} + client.restart_autonomous_database(request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.CreateCloudVmClusterRequest() - assert args[0] == request_msg + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_delete_cloud_vm_cluster_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + client.restart_autonomous_database(request) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_cloud_vm_cluster), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.delete_cloud_vm_cluster(request=None) + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.DeleteCloudVmClusterRequest() - assert args[0] == request_msg +def test_restart_autonomous_database_rest_required_fields( + request_type=oracledatabase.RestartAutonomousDatabaseRequest, +): + transport_class = transports.OracleDatabaseRestTransport -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_entitlements_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_entitlements), "__call__" - ) as call: - call.return_value = oracledatabase.ListEntitlementsResponse() - client.list_entitlements(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.ListEntitlementsRequest() - assert args[0] == request_msg + # verify fields with default values are dropped + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).restart_autonomous_database._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_db_servers_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # verify required fields with default values are now present - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_db_servers), "__call__") as call: - call.return_value = oracledatabase.ListDbServersResponse() - client.list_db_servers(request=None) + jsonified_request["name"] = "name_value" - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.ListDbServersRequest() - assert args[0] == request_msg + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).restart_autonomous_database._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_db_nodes_empty_call_grpc(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport="rest", ) + request = request_type(**request_init) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_db_nodes), "__call__") as call: - call.return_value = oracledatabase.ListDbNodesResponse() - client.list_db_nodes(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.ListDbNodesRequest() - assert args[0] == request_msg + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_gi_versions_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_gi_versions), "__call__") as call: - call.return_value = oracledatabase.ListGiVersionsResponse() - client.list_gi_versions(request=None) + response = client.restart_autonomous_database(request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.ListGiVersionsRequest() - assert args[0] == request_msg + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_minor_versions_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", +def test_restart_autonomous_database_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_minor_versions), "__call__" - ) as call: - call.return_value = minor_version.ListMinorVersionsResponse() - client.list_minor_versions(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = minor_version.ListMinorVersionsRequest() - assert args[0] == request_msg + unset_fields = transport.restart_autonomous_database._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_db_system_shapes_empty_call_grpc(): +def test_restart_autonomous_database_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport="rest", ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_db_system_shapes), "__call__" - ) as call: - call.return_value = oracledatabase.ListDbSystemShapesResponse() - client.list_db_system_shapes(request=None) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.ListDbSystemShapesRequest() - assert args[0] == request_msg + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + } + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_autonomous_databases_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_autonomous_databases), "__call__" - ) as call: - call.return_value = oracledatabase.ListAutonomousDatabasesResponse() - client.list_autonomous_databases(request=None) + client.restart_autonomous_database(**mock_args) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.ListAutonomousDatabasesRequest() - assert args[0] == request_msg + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/autonomousDatabases/*}:restart" + % client.transport._host, + args[1], + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_autonomous_database_empty_call_grpc(): +def test_restart_autonomous_database_rest_flattened_error(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport=transport, ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_autonomous_database), "__call__" - ) as call: - call.return_value = autonomous_database.AutonomousDatabase() - client.get_autonomous_database(request=None) + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.restart_autonomous_database( + oracledatabase.RestartAutonomousDatabaseRequest(), + name="name_value", + ) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.GetAutonomousDatabaseRequest() - assert args[0] == request_msg +def test_switchover_autonomous_database_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_create_autonomous_database_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_autonomous_database), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.create_autonomous_database(request=None) + # Ensure method has been cached + assert ( + client._transport.switchover_autonomous_database + in client._transport._wrapped_methods + ) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.CreateAutonomousDatabaseRequest() - assert args[0] == request_msg + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.switchover_autonomous_database + ] = mock_rpc + request = {} + client.switchover_autonomous_database(request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_update_autonomous_database_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.update_autonomous_database), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.update_autonomous_database(request=None) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.UpdateAutonomousDatabaseRequest() - assert args[0] == request_msg + client.switchover_autonomous_database(request) + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_delete_autonomous_database_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_autonomous_database), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.delete_autonomous_database(request=None) +def test_switchover_autonomous_database_rest_required_fields( + request_type=oracledatabase.SwitchoverAutonomousDatabaseRequest, +): + transport_class = transports.OracleDatabaseRestTransport - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.DeleteAutonomousDatabaseRequest() - assert args[0] == request_msg + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + # verify fields with default values are dropped -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_restore_autonomous_database_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).switchover_autonomous_database._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.restore_autonomous_database), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.restore_autonomous_database(request=None) + # verify required fields with default values are now present - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.RestoreAutonomousDatabaseRequest() - assert args[0] == request_msg + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).switchover_autonomous_database._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_generate_autonomous_database_wallet_empty_call_grpc(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport="rest", ) + request = request_type(**request_init) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.generate_autonomous_database_wallet), "__call__" - ) as call: - call.return_value = oracledatabase.GenerateAutonomousDatabaseWalletResponse() - client.generate_autonomous_database_wallet(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.GenerateAutonomousDatabaseWalletRequest() - assert args[0] == request_msg + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_autonomous_db_versions_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_autonomous_db_versions), "__call__" - ) as call: - call.return_value = oracledatabase.ListAutonomousDbVersionsResponse() - client.list_autonomous_db_versions(request=None) + response = client.switchover_autonomous_database(request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.ListAutonomousDbVersionsRequest() - assert args[0] == request_msg + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_autonomous_database_character_sets_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", +def test_switchover_autonomous_database_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_autonomous_database_character_sets), "__call__" - ) as call: - call.return_value = oracledatabase.ListAutonomousDatabaseCharacterSetsResponse() - client.list_autonomous_database_character_sets(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.ListAutonomousDatabaseCharacterSetsRequest() - assert args[0] == request_msg + unset_fields = transport.switchover_autonomous_database._get_unset_required_fields( + {} + ) + assert set(unset_fields) == (set(()) & set(("name",))) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_autonomous_database_backups_empty_call_grpc(): +def test_switchover_autonomous_database_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport="rest", ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_autonomous_database_backups), "__call__" - ) as call: - call.return_value = oracledatabase.ListAutonomousDatabaseBackupsResponse() - client.list_autonomous_database_backups(request=None) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.ListAutonomousDatabaseBackupsRequest() - assert args[0] == request_msg + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + } + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + peer_autonomous_database="peer_autonomous_database_value", + ) + mock_args.update(sample_request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_stop_autonomous_database_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.stop_autonomous_database), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.stop_autonomous_database(request=None) + client.switchover_autonomous_database(**mock_args) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.StopAutonomousDatabaseRequest() - assert args[0] == request_msg + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/autonomousDatabases/*}:switchover" + % client.transport._host, + args[1], + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_start_autonomous_database_empty_call_grpc(): +def test_switchover_autonomous_database_rest_flattened_error(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport=transport, ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.start_autonomous_database), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.start_autonomous_database(request=None) + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.switchover_autonomous_database( + oracledatabase.SwitchoverAutonomousDatabaseRequest(), + name="name_value", + peer_autonomous_database="peer_autonomous_database_value", + ) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.StartAutonomousDatabaseRequest() - assert args[0] == request_msg +def test_failover_autonomous_database_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_restart_autonomous_database_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.restart_autonomous_database), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.restart_autonomous_database(request=None) + # Ensure method has been cached + assert ( + client._transport.failover_autonomous_database + in client._transport._wrapped_methods + ) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.RestartAutonomousDatabaseRequest() - assert args[0] == request_msg + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.failover_autonomous_database + ] = mock_rpc + request = {} + client.failover_autonomous_database(request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_switchover_autonomous_database_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.switchover_autonomous_database), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.switchover_autonomous_database(request=None) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.SwitchoverAutonomousDatabaseRequest() - assert args[0] == request_msg + client.failover_autonomous_database(request) + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_failover_autonomous_database_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.failover_autonomous_database), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.failover_autonomous_database(request=None) +def test_failover_autonomous_database_rest_required_fields( + request_type=oracledatabase.FailoverAutonomousDatabaseRequest, +): + transport_class = transports.OracleDatabaseRestTransport - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.FailoverAutonomousDatabaseRequest() - assert args[0] == request_msg + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + # verify fields with default values are dropped -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_odb_networks_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).failover_autonomous_database._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_odb_networks), "__call__" - ) as call: - call.return_value = odb_network.ListOdbNetworksResponse() - client.list_odb_networks(request=None) + # verify required fields with default values are now present - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = odb_network.ListOdbNetworksRequest() - assert args[0] == request_msg + jsonified_request["name"] = "name_value" + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).failover_autonomous_database._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_odb_network_empty_call_grpc(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport="rest", ) + request = request_type(**request_init) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.get_odb_network), "__call__") as call: - call.return_value = odb_network.OdbNetwork() - client.get_odb_network(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = odb_network.GetOdbNetworkRequest() - assert args[0] == request_msg + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_create_odb_network_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_odb_network), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.create_odb_network(request=None) + response = client.failover_autonomous_database(request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gco_odb_network.CreateOdbNetworkRequest() - assert args[0] == request_msg + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_delete_odb_network_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", +def test_failover_autonomous_database_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_odb_network), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.delete_odb_network(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = odb_network.DeleteOdbNetworkRequest() - assert args[0] == request_msg + unset_fields = transport.failover_autonomous_database._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_odb_subnets_empty_call_grpc(): +def test_failover_autonomous_database_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport="rest", ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_odb_subnets), "__call__") as call: - call.return_value = odb_subnet.ListOdbSubnetsResponse() - client.list_odb_subnets(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = odb_subnet.ListOdbSubnetsRequest() - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_odb_subnet_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.get_odb_subnet), "__call__") as call: - call.return_value = odb_subnet.OdbSubnet() - client.get_odb_subnet(request=None) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = odb_subnet.GetOdbSubnetRequest() - assert args[0] == request_msg + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + } + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + peer_autonomous_database="peer_autonomous_database_value", + ) + mock_args.update(sample_request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_create_odb_subnet_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_odb_subnet), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.create_odb_subnet(request=None) + client.failover_autonomous_database(**mock_args) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gco_odb_subnet.CreateOdbSubnetRequest() - assert args[0] == request_msg + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/autonomousDatabases/*}:failover" + % client.transport._host, + args[1], + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_delete_odb_subnet_empty_call_grpc(): +def test_failover_autonomous_database_rest_flattened_error(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport=transport, ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_odb_subnet), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.delete_odb_subnet(request=None) + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.failover_autonomous_database( + oracledatabase.FailoverAutonomousDatabaseRequest(), + name="name_value", + peer_autonomous_database="peer_autonomous_database_value", + ) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = odb_subnet.DeleteOdbSubnetRequest() - assert args[0] == request_msg +def test_list_odb_networks_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_exadb_vm_clusters_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_exadb_vm_clusters), "__call__" - ) as call: - call.return_value = oracledatabase.ListExadbVmClustersResponse() - client.list_exadb_vm_clusters(request=None) + # Ensure method has been cached + assert client._transport.list_odb_networks in client._transport._wrapped_methods - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.ListExadbVmClustersRequest() - assert args[0] == request_msg + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.list_odb_networks] = ( + mock_rpc + ) + request = {} + client.list_odb_networks(request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_exadb_vm_cluster_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_exadb_vm_cluster), "__call__" - ) as call: - call.return_value = exadb_vm_cluster.ExadbVmCluster() - client.get_exadb_vm_cluster(request=None) + client.list_odb_networks(request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.GetExadbVmClusterRequest() - assert args[0] == request_msg + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_create_exadb_vm_cluster_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) +def test_list_odb_networks_rest_required_fields( + request_type=odb_network.ListOdbNetworksRequest, +): + transport_class = transports.OracleDatabaseRestTransport - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_exadb_vm_cluster), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.create_exadb_vm_cluster(request=None) + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.CreateExadbVmClusterRequest() - assert args[0] == request_msg + # verify fields with default values are dropped + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_odb_networks._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_delete_exadb_vm_cluster_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # verify required fields with default values are now present - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_exadb_vm_cluster), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.delete_exadb_vm_cluster(request=None) + jsonified_request["parent"] = "parent_value" - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.DeleteExadbVmClusterRequest() - assert args[0] == request_msg + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_odb_networks._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_update_exadb_vm_cluster_empty_call_grpc(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport="rest", ) + request = request_type(**request_init) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.update_exadb_vm_cluster), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.update_exadb_vm_cluster(request=None) + # Designate an appropriate value for the returned response. + return_value = odb_network.ListOdbNetworksResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.UpdateExadbVmClusterRequest() - assert args[0] == request_msg + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = odb_network.ListOdbNetworksResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_remove_virtual_machine_exadb_vm_cluster_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.remove_virtual_machine_exadb_vm_cluster), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.remove_virtual_machine_exadb_vm_cluster(request=None) + response = client.list_odb_networks(request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.RemoveVirtualMachineExadbVmClusterRequest() - assert args[0] == request_msg + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_exascale_db_storage_vaults_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", +def test_list_odb_networks_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_exascale_db_storage_vaults), "__call__" - ) as call: - call.return_value = ( - exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse() + unset_fields = transport.list_odb_networks._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + ) ) - client.list_exascale_db_storage_vaults(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = exascale_db_storage_vault.ListExascaleDbStorageVaultsRequest() - assert args[0] == request_msg + & set(("parent",)) + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_exascale_db_storage_vault_empty_call_grpc(): +def test_list_odb_networks_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport="rest", ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_exascale_db_storage_vault), "__call__" - ) as call: - call.return_value = exascale_db_storage_vault.ExascaleDbStorageVault() - client.get_exascale_db_storage_vault(request=None) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = odb_network.ListOdbNetworksResponse() - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = exascale_db_storage_vault.GetExascaleDbStorageVaultRequest() - assert args[0] == request_msg + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_create_exascale_db_storage_vault_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = odb_network.ListOdbNetworksResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_exascale_db_storage_vault), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.create_exascale_db_storage_vault(request=None) + client.list_odb_networks(**mock_args) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = ( - gco_exascale_db_storage_vault.CreateExascaleDbStorageVaultRequest() + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*}/odbNetworks" + % client.transport._host, + args[1], ) - assert args[0] == request_msg -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_delete_exascale_db_storage_vault_empty_call_grpc(): +def test_list_odb_networks_rest_flattened_error(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport=transport, ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_exascale_db_storage_vault), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.delete_exascale_db_storage_vault(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = exascale_db_storage_vault.DeleteExascaleDbStorageVaultRequest() - assert args[0] == request_msg + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_odb_networks( + odb_network.ListOdbNetworksRequest(), + parent="parent_value", + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_db_system_initial_storage_sizes_empty_call_grpc(): +def test_list_odb_networks_rest_pager(transport: str = "rest"): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport=transport, ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_db_system_initial_storage_sizes), "__call__" - ) as call: - call.return_value = ( - db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + odb_network.ListOdbNetworksResponse( + odb_networks=[ + odb_network.OdbNetwork(), + odb_network.OdbNetwork(), + odb_network.OdbNetwork(), + ], + next_page_token="abc", + ), + odb_network.ListOdbNetworksResponse( + odb_networks=[], + next_page_token="def", + ), + odb_network.ListOdbNetworksResponse( + odb_networks=[ + odb_network.OdbNetwork(), + ], + next_page_token="ghi", + ), + odb_network.ListOdbNetworksResponse( + odb_networks=[ + odb_network.OdbNetwork(), + odb_network.OdbNetwork(), + ], + ), ) - client.list_db_system_initial_storage_sizes(request=None) + # Two responses for two calls + response = response + response - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = ( - db_system_initial_storage_size.ListDbSystemInitialStorageSizesRequest() + # Wrap the values into proper Response objs + response = tuple( + odb_network.ListOdbNetworksResponse.to_json(x) for x in response ) - assert args[0] == request_msg - + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_databases_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + sample_request = {"parent": "projects/sample1/locations/sample2"} - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_databases), "__call__") as call: - call.return_value = database.ListDatabasesResponse() - client.list_databases(request=None) + pager = client.list_odb_networks(request=sample_request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = database.ListDatabasesRequest() - assert args[0] == request_msg + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, odb_network.OdbNetwork) for i in results) + pages = list(client.list_odb_networks(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_database_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.get_database), "__call__") as call: - call.return_value = database.Database() - client.get_database(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = database.GetDatabaseRequest() - assert args[0] == request_msg +def test_get_odb_network_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_pluggable_databases_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Ensure method has been cached + assert client._transport.get_odb_network in client._transport._wrapped_methods - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_pluggable_databases), "__call__" - ) as call: - call.return_value = pluggable_database.ListPluggableDatabasesResponse() - client.list_pluggable_databases(request=None) + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_odb_network] = mock_rpc - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = pluggable_database.ListPluggableDatabasesRequest() - assert args[0] == request_msg + request = {} + client.get_odb_network(request) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_pluggable_database_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + client.get_odb_network(request) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_pluggable_database), "__call__" - ) as call: - call.return_value = pluggable_database.PluggableDatabase() - client.get_pluggable_database(request=None) + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = pluggable_database.GetPluggableDatabaseRequest() - assert args[0] == request_msg +def test_get_odb_network_rest_required_fields( + request_type=odb_network.GetOdbNetworkRequest, +): + transport_class = transports.OracleDatabaseRestTransport -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_db_systems_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_db_systems), "__call__") as call: - call.return_value = db_system.ListDbSystemsResponse() - client.list_db_systems(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = db_system.ListDbSystemsRequest() - assert args[0] == request_msg + # verify fields with default values are dropped + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_odb_network._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_db_system_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # verify required fields with default values are now present - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.get_db_system), "__call__") as call: - call.return_value = db_system.DbSystem() - client.get_db_system(request=None) + jsonified_request["name"] = "name_value" - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = db_system.GetDbSystemRequest() - assert args[0] == request_msg + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_odb_network._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_create_db_system_empty_call_grpc(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport="rest", ) + request = request_type(**request_init) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.create_db_system), "__call__") as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.create_db_system(request=None) + # Designate an appropriate value for the returned response. + return_value = odb_network.OdbNetwork() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gco_db_system.CreateDbSystemRequest() - assert args[0] == request_msg + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = odb_network.OdbNetwork.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_delete_db_system_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.delete_db_system), "__call__") as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.delete_db_system(request=None) + response = client.get_odb_network(request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = db_system.DeleteDbSystemRequest() - assert args[0] == request_msg + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_db_versions_empty_call_grpc(): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", +def test_get_odb_network_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_db_versions), "__call__") as call: - call.return_value = db_version.ListDbVersionsResponse() - client.list_db_versions(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = db_version.ListDbVersionsRequest() - assert args[0] == request_msg + unset_fields = transport.get_odb_network._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_database_character_sets_empty_call_grpc(): +def test_get_odb_network_rest_flattened(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport="rest", ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_database_character_sets), "__call__" - ) as call: - call.return_value = database_character_set.ListDatabaseCharacterSetsResponse() - client.list_database_character_sets(request=None) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = odb_network.OdbNetwork() - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = database_character_set.ListDatabaseCharacterSetsRequest() - assert args[0] == request_msg + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/odbNetworks/sample3" + } + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) -def test_transport_kind_grpc_asyncio(): - transport = OracleDatabaseAsyncClient.get_transport_class("grpc_asyncio")( - credentials=async_anonymous_credentials() - ) - assert transport.kind == "grpc_asyncio" + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = odb_network.OdbNetwork.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_odb_network(**mock_args) -def test_initialize_client_w_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), transport="grpc_asyncio" - ) - assert client is not None + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/odbNetworks/*}" + % client.transport._host, + args[1], + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_cloud_exadata_infrastructures_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +def test_get_odb_network_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_cloud_exadata_infrastructures), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - oracledatabase.ListCloudExadataInfrastructuresResponse( - next_page_token="next_page_token_value", - ) + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_odb_network( + odb_network.GetOdbNetworkRequest(), + name="name_value", ) - await client.list_cloud_exadata_infrastructures(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.ListCloudExadataInfrastructuresRequest() - assert args[0] == request_msg -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_get_cloud_exadata_infrastructure_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_cloud_exadata_infrastructure), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - exadata_infra.CloudExadataInfrastructure( - name="name_value", - display_name="display_name_value", - gcp_oracle_zone="gcp_oracle_zone_value", - entitlement_id="entitlement_id_value", - ) +def test_create_odb_network_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - await client.get_cloud_exadata_infrastructure(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.GetCloudExadataInfrastructureRequest() - assert args[0] == request_msg + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_create_cloud_exadata_infrastructure_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + # Ensure method has been cached + assert ( + client._transport.create_odb_network in client._transport._wrapped_methods + ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_cloud_exadata_infrastructure), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.create_odb_network] = ( + mock_rpc ) - await client.create_cloud_exadata_infrastructure(request=None) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.CreateCloudExadataInfrastructureRequest() - assert args[0] == request_msg + request = {} + client.create_odb_network(request) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_delete_cloud_exadata_infrastructure_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_cloud_exadata_infrastructure), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.delete_cloud_exadata_infrastructure(request=None) + client.create_odb_network(request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.DeleteCloudExadataInfrastructureRequest() - assert args[0] == request_msg + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_cloud_vm_clusters_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +def test_create_odb_network_rest_required_fields( + request_type=gco_odb_network.CreateOdbNetworkRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["odb_network_id"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_cloud_vm_clusters), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - oracledatabase.ListCloudVmClustersResponse( - next_page_token="next_page_token_value", - ) - ) - await client.list_cloud_vm_clusters(request=None) + # verify fields with default values are dropped + assert "odbNetworkId" not in jsonified_request - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.ListCloudVmClustersRequest() - assert args[0] == request_msg + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_odb_network._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + # verify required fields with default values are now present + assert "odbNetworkId" in jsonified_request + assert jsonified_request["odbNetworkId"] == request_init["odb_network_id"] -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_get_cloud_vm_cluster_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + jsonified_request["parent"] = "parent_value" + jsonified_request["odbNetworkId"] = "odb_network_id_value" - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_cloud_vm_cluster), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - vm_cluster.CloudVmCluster( - name="name_value", - exadata_infrastructure="exadata_infrastructure_value", - display_name="display_name_value", - cidr="cidr_value", - backup_subnet_cidr="backup_subnet_cidr_value", - network="network_value", - gcp_oracle_zone="gcp_oracle_zone_value", - odb_network="odb_network_value", - odb_subnet="odb_subnet_value", - backup_odb_subnet="backup_odb_subnet_value", - ) + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_odb_network._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "odb_network_id", + "request_id", ) - await client.get_cloud_vm_cluster(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.GetCloudVmClusterRequest() - assert args[0] == request_msg + ) + jsonified_request.update(unset_fields) + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "odbNetworkId" in jsonified_request + assert jsonified_request["odbNetworkId"] == "odb_network_id_value" -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_create_cloud_vm_cluster_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) + request = request_type(**request_init) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_cloud_vm_cluster), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.create_cloud_vm_cluster(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.CreateCloudVmClusterRequest() - assert args[0] == request_msg + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_delete_cloud_vm_cluster_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_cloud_vm_cluster), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.delete_cloud_vm_cluster(request=None) + response = client.create_odb_network(request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.DeleteCloudVmClusterRequest() - assert args[0] == request_msg + expected_params = [ + ( + "odbNetworkId", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_entitlements_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +def test_create_odb_network_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_entitlements), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - oracledatabase.ListEntitlementsResponse( - next_page_token="next_page_token_value", + unset_fields = transport.create_odb_network._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "odbNetworkId", + "requestId", ) ) - await client.list_entitlements(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.ListEntitlementsRequest() - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_db_servers_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_db_servers), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - oracledatabase.ListDbServersResponse( - next_page_token="next_page_token_value", + & set( + ( + "parent", + "odbNetworkId", + "odbNetwork", ) ) - await client.list_db_servers(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.ListDbServersRequest() - assert args[0] == request_msg + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_db_nodes_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +def test_create_odb_network_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_db_nodes), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - oracledatabase.ListDbNodesResponse( - next_page_token="next_page_token_value", - ) - ) - await client.list_db_nodes(request=None) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.ListDbNodesRequest() - assert args[0] == request_msg + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + odb_network=gco_odb_network.OdbNetwork(name="name_value"), + odb_network_id="odb_network_id_value", + ) + mock_args.update(sample_request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_gi_versions_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_gi_versions), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - oracledatabase.ListGiVersionsResponse( - next_page_token="next_page_token_value", - ) - ) - await client.list_gi_versions(request=None) + client.create_odb_network(**mock_args) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.ListGiVersionsRequest() - assert args[0] == request_msg + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*}/odbNetworks" + % client.transport._host, + args[1], + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_minor_versions_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +def test_create_odb_network_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_minor_versions), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - minor_version.ListMinorVersionsResponse( - next_page_token="next_page_token_value", - ) + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_odb_network( + gco_odb_network.CreateOdbNetworkRequest(), + parent="parent_value", + odb_network=gco_odb_network.OdbNetwork(name="name_value"), + odb_network_id="odb_network_id_value", ) - await client.list_minor_versions(request=None) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = minor_version.ListMinorVersionsRequest() - assert args[0] == request_msg +def test_delete_odb_network_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_db_system_shapes_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_db_system_shapes), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - oracledatabase.ListDbSystemShapesResponse( - next_page_token="next_page_token_value", - ) + # Ensure method has been cached + assert ( + client._transport.delete_odb_network in client._transport._wrapped_methods ) - await client.list_db_system_shapes(request=None) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.ListDbSystemShapesRequest() - assert args[0] == request_msg + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.delete_odb_network] = ( + mock_rpc + ) + request = {} + client.delete_odb_network(request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_autonomous_databases_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_autonomous_databases), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - oracledatabase.ListAutonomousDatabasesResponse( - next_page_token="next_page_token_value", - ) - ) - await client.list_autonomous_databases(request=None) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.ListAutonomousDatabasesRequest() - assert args[0] == request_msg + client.delete_odb_network(request) + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_get_autonomous_database_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_autonomous_database), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - autonomous_database.AutonomousDatabase( - name="name_value", - database="database_value", - display_name="display_name_value", - entitlement_id="entitlement_id_value", - admin_password="admin_password_value", - network="network_value", - cidr="cidr_value", - odb_network="odb_network_value", - odb_subnet="odb_subnet_value", - peer_autonomous_databases=["peer_autonomous_databases_value"], - disaster_recovery_supported_locations=[ - "disaster_recovery_supported_locations_value" - ], - ) - ) - await client.get_autonomous_database(request=None) +def test_delete_odb_network_rest_required_fields( + request_type=odb_network.DeleteOdbNetworkRequest, +): + transport_class = transports.OracleDatabaseRestTransport - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.GetAutonomousDatabaseRequest() - assert args[0] == request_msg + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + # verify fields with default values are dropped -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_create_autonomous_database_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_odb_network._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_autonomous_database), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.create_autonomous_database(request=None) + # verify required fields with default values are now present - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.CreateAutonomousDatabaseRequest() - assert args[0] == request_msg + jsonified_request["name"] = "name_value" + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_odb_network._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("request_id",)) + jsonified_request.update(unset_fields) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_update_autonomous_database_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.update_autonomous_database), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.update_autonomous_database(request=None) + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.UpdateAutonomousDatabaseRequest() - assert args[0] == request_msg + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "delete", + "query_params": pb_request, + } + transcode.return_value = transcode_result + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_delete_autonomous_database_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_autonomous_database), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.delete_autonomous_database(request=None) + response = client.delete_odb_network(request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.DeleteAutonomousDatabaseRequest() - assert args[0] == request_msg + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_restore_autonomous_database_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +def test_delete_odb_network_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.restore_autonomous_database), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.restore_autonomous_database(request=None) + unset_fields = transport.delete_odb_network._get_unset_required_fields({}) + assert set(unset_fields) == (set(("requestId",)) & set(("name",))) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.RestoreAutonomousDatabaseRequest() - assert args[0] == request_msg +def test_delete_odb_network_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_generate_autonomous_database_wallet_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.generate_autonomous_database_wallet), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - oracledatabase.GenerateAutonomousDatabaseWalletResponse( - archive_content=b"archive_content_blob", - ) - ) - await client.generate_autonomous_database_wallet(request=None) + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/odbNetworks/sample3" + } - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.GenerateAutonomousDatabaseWalletRequest() - assert args[0] == request_msg + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_autonomous_db_versions_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + client.delete_odb_network(**mock_args) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_autonomous_db_versions), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - oracledatabase.ListAutonomousDbVersionsResponse( - next_page_token="next_page_token_value", - ) + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/odbNetworks/*}" + % client.transport._host, + args[1], ) - await client.list_autonomous_db_versions(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.ListAutonomousDbVersionsRequest() - assert args[0] == request_msg -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_autonomous_database_character_sets_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +def test_delete_odb_network_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_autonomous_database_character_sets), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - oracledatabase.ListAutonomousDatabaseCharacterSetsResponse( - next_page_token="next_page_token_value", - ) + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_odb_network( + odb_network.DeleteOdbNetworkRequest(), + name="name_value", ) - await client.list_autonomous_database_character_sets(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.ListAutonomousDatabaseCharacterSetsRequest() - assert args[0] == request_msg - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_autonomous_database_backups_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_autonomous_database_backups), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - oracledatabase.ListAutonomousDatabaseBackupsResponse( - next_page_token="next_page_token_value", - ) +def test_list_odb_subnets_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - await client.list_autonomous_database_backups(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.ListAutonomousDatabaseBackupsRequest() - assert args[0] == request_msg + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_stop_autonomous_database_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + # Ensure method has been cached + assert client._transport.list_odb_subnets in client._transport._wrapped_methods - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.stop_autonomous_database), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.list_odb_subnets] = ( + mock_rpc ) - await client.stop_autonomous_database(request=None) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.StopAutonomousDatabaseRequest() - assert args[0] == request_msg + request = {} + client.list_odb_subnets(request) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_start_autonomous_database_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + client.list_odb_subnets(request) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.start_autonomous_database), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.start_autonomous_database(request=None) + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.StartAutonomousDatabaseRequest() - assert args[0] == request_msg +def test_list_odb_subnets_rest_required_fields( + request_type=odb_subnet.ListOdbSubnetsRequest, +): + transport_class = transports.OracleDatabaseRestTransport -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_restart_autonomous_database_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.restart_autonomous_database), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.restart_autonomous_database(request=None) + # verify fields with default values are dropped - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.RestartAutonomousDatabaseRequest() - assert args[0] == request_msg + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_odb_subnets._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + # verify required fields with default values are now present -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_switchover_autonomous_database_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + jsonified_request["parent"] = "parent_value" - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.switchover_autonomous_database), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_odb_subnets._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", ) - await client.switchover_autonomous_database(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.SwitchoverAutonomousDatabaseRequest() - assert args[0] == request_msg + ) + jsonified_request.update(unset_fields) + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_failover_autonomous_database_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) + request = request_type(**request_init) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.failover_autonomous_database), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.failover_autonomous_database(request=None) + # Designate an appropriate value for the returned response. + return_value = odb_subnet.ListOdbSubnetsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.FailoverAutonomousDatabaseRequest() - assert args[0] == request_msg + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = odb_subnet.ListOdbSubnetsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_odb_networks_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_odb_networks), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - odb_network.ListOdbNetworksResponse( - next_page_token="next_page_token_value", - unreachable=["unreachable_value"], - ) - ) - await client.list_odb_networks(request=None) + response = client.list_odb_subnets(request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = odb_network.ListOdbNetworksRequest() - assert args[0] == request_msg + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_get_odb_network_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +def test_list_odb_subnets_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.get_odb_network), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - odb_network.OdbNetwork( - name="name_value", - network="network_value", - state=odb_network.OdbNetwork.State.PROVISIONING, - entitlement_id="entitlement_id_value", - gcp_oracle_zone="gcp_oracle_zone_value", + unset_fields = transport.list_odb_subnets._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", ) ) - await client.get_odb_network(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = odb_network.GetOdbNetworkRequest() - assert args[0] == request_msg + & set(("parent",)) + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_create_odb_network_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +def test_list_odb_subnets_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_odb_network), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.create_odb_network(request=None) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = odb_subnet.ListOdbSubnetsResponse() - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gco_odb_network.CreateOdbNetworkRequest() - assert args[0] == request_msg + # get arguments that satisfy an http rule for this method + sample_request = { + "parent": "projects/sample1/locations/sample2/odbNetworks/sample3" + } + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_delete_odb_network_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = odb_subnet.ListOdbSubnetsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_odb_network), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.delete_odb_network(request=None) + client.list_odb_subnets(**mock_args) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = odb_network.DeleteOdbNetworkRequest() - assert args[0] == request_msg + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*/odbNetworks/*}/odbSubnets" + % client.transport._host, + args[1], + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_odb_subnets_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +def test_list_odb_subnets_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_odb_subnets), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - odb_subnet.ListOdbSubnetsResponse( - next_page_token="next_page_token_value", - unreachable=["unreachable_value"], - ) + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_odb_subnets( + odb_subnet.ListOdbSubnetsRequest(), + parent="parent_value", ) - await client.list_odb_subnets(request=None) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = odb_subnet.ListOdbSubnetsRequest() - assert args[0] == request_msg +def test_list_odb_subnets_rest_pager(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_get_odb_subnet_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.get_odb_subnet), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - odb_subnet.OdbSubnet( - name="name_value", - cidr_range="cidr_range_value", - purpose=odb_subnet.OdbSubnet.Purpose.CLIENT_SUBNET, - state=odb_subnet.OdbSubnet.State.PROVISIONING, - ) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + odb_subnet.ListOdbSubnetsResponse( + odb_subnets=[ + odb_subnet.OdbSubnet(), + odb_subnet.OdbSubnet(), + odb_subnet.OdbSubnet(), + ], + next_page_token="abc", + ), + odb_subnet.ListOdbSubnetsResponse( + odb_subnets=[], + next_page_token="def", + ), + odb_subnet.ListOdbSubnetsResponse( + odb_subnets=[ + odb_subnet.OdbSubnet(), + ], + next_page_token="ghi", + ), + odb_subnet.ListOdbSubnetsResponse( + odb_subnets=[ + odb_subnet.OdbSubnet(), + odb_subnet.OdbSubnet(), + ], + ), ) - await client.get_odb_subnet(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = odb_subnet.GetOdbSubnetRequest() - assert args[0] == request_msg + # Two responses for two calls + response = response + response + # Wrap the values into proper Response objs + response = tuple(odb_subnet.ListOdbSubnetsResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_create_odb_subnet_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + sample_request = { + "parent": "projects/sample1/locations/sample2/odbNetworks/sample3" + } - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_odb_subnet), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.create_odb_subnet(request=None) + pager = client.list_odb_subnets(request=sample_request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gco_odb_subnet.CreateOdbSubnetRequest() - assert args[0] == request_msg + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, odb_subnet.OdbSubnet) for i in results) + pages = list(client.list_odb_subnets(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_delete_odb_subnet_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_odb_subnet), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") +def test_get_odb_subnet_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - await client.delete_odb_subnet(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = odb_subnet.DeleteOdbSubnetRequest() - assert args[0] == request_msg + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_exadb_vm_clusters_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + # Ensure method has been cached + assert client._transport.get_odb_subnet in client._transport._wrapped_methods - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_exadb_vm_clusters), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - oracledatabase.ListExadbVmClustersResponse( - next_page_token="next_page_token_value", - ) + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. ) - await client.list_exadb_vm_clusters(request=None) + client._transport._wrapped_methods[client._transport.get_odb_subnet] = mock_rpc - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.ListExadbVmClustersRequest() - assert args[0] == request_msg + request = {} + client.get_odb_subnet(request) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_get_exadb_vm_cluster_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + client.get_odb_subnet(request) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_exadb_vm_cluster), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - exadb_vm_cluster.ExadbVmCluster( - name="name_value", - gcp_oracle_zone="gcp_oracle_zone_value", - odb_network="odb_network_value", - odb_subnet="odb_subnet_value", - backup_odb_subnet="backup_odb_subnet_value", - display_name="display_name_value", - entitlement_id="entitlement_id_value", - ) - ) - await client.get_exadb_vm_cluster(request=None) + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.GetExadbVmClusterRequest() - assert args[0] == request_msg +def test_get_odb_subnet_rest_required_fields( + request_type=odb_subnet.GetOdbSubnetRequest, +): + transport_class = transports.OracleDatabaseRestTransport -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_create_exadb_vm_cluster_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_exadb_vm_cluster), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.create_exadb_vm_cluster(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.CreateExadbVmClusterRequest() - assert args[0] == request_msg + # verify fields with default values are dropped + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_odb_subnet._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_delete_exadb_vm_cluster_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + # verify required fields with default values are now present - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_exadb_vm_cluster), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.delete_exadb_vm_cluster(request=None) + jsonified_request["name"] = "name_value" - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.DeleteExadbVmClusterRequest() - assert args[0] == request_msg + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_odb_subnet._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_update_exadb_vm_cluster_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) + request = request_type(**request_init) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.update_exadb_vm_cluster), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.update_exadb_vm_cluster(request=None) + # Designate an appropriate value for the returned response. + return_value = odb_subnet.OdbSubnet() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.UpdateExadbVmClusterRequest() - assert args[0] == request_msg + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = odb_subnet.OdbSubnet.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_remove_virtual_machine_exadb_vm_cluster_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.remove_virtual_machine_exadb_vm_cluster), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.remove_virtual_machine_exadb_vm_cluster(request=None) + response = client.get_odb_subnet(request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = oracledatabase.RemoveVirtualMachineExadbVmClusterRequest() - assert args[0] == request_msg + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_exascale_db_storage_vaults_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +def test_get_odb_subnet_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_exascale_db_storage_vaults), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse( - next_page_token="next_page_token_value", - ) - ) - await client.list_exascale_db_storage_vaults(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = exascale_db_storage_vault.ListExascaleDbStorageVaultsRequest() - assert args[0] == request_msg + unset_fields = transport.get_odb_subnet._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_get_exascale_db_storage_vault_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +def test_get_odb_subnet_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_exascale_db_storage_vault), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - exascale_db_storage_vault.ExascaleDbStorageVault( - name="name_value", - display_name="display_name_value", - gcp_oracle_zone="gcp_oracle_zone_value", - entitlement_id="entitlement_id_value", - ) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = odb_subnet.OdbSubnet() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/odbNetworks/sample3/odbSubnets/sample4" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", ) - await client.get_exascale_db_storage_vault(request=None) + mock_args.update(sample_request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = exascale_db_storage_vault.GetExascaleDbStorageVaultRequest() - assert args[0] == request_msg + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = odb_subnet.OdbSubnet.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_odb_subnet(**mock_args) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_create_exascale_db_storage_vault_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/odbNetworks/*/odbSubnets/*}" + % client.transport._host, + args[1], + ) + + +def test_get_odb_subnet_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_exascale_db_storage_vault), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_odb_subnet( + odb_subnet.GetOdbSubnetRequest(), + name="name_value", ) - await client.create_exascale_db_storage_vault(request=None) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = ( - gco_exascale_db_storage_vault.CreateExascaleDbStorageVaultRequest() + +def test_create_odb_subnet_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - assert args[0] == request_msg + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_delete_exascale_db_storage_vault_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + # Ensure method has been cached + assert client._transport.create_odb_subnet in client._transport._wrapped_methods - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_exascale_db_storage_vault), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.create_odb_subnet] = ( + mock_rpc ) - await client.delete_exascale_db_storage_vault(request=None) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = exascale_db_storage_vault.DeleteExascaleDbStorageVaultRequest() - assert args[0] == request_msg + request = {} + client.create_odb_subnet(request) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_db_system_initial_storage_sizes_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.create_odb_subnet(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_create_odb_subnet_rest_required_fields( + request_type=gco_odb_subnet.CreateOdbSubnetRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["odb_subnet_id"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_db_system_initial_storage_sizes), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse( - next_page_token="next_page_token_value", - ) - ) - await client.list_db_system_initial_storage_sizes(request=None) + # verify fields with default values are dropped + assert "odbSubnetId" not in jsonified_request - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = ( - db_system_initial_storage_size.ListDbSystemInitialStorageSizesRequest() + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_odb_subnet._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "odbSubnetId" in jsonified_request + assert jsonified_request["odbSubnetId"] == request_init["odb_subnet_id"] + + jsonified_request["parent"] = "parent_value" + jsonified_request["odbSubnetId"] = "odb_subnet_id_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_odb_subnet._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "odb_subnet_id", + "request_id", ) - assert args[0] == request_msg + ) + jsonified_request.update(unset_fields) + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "odbSubnetId" in jsonified_request + assert jsonified_request["odbSubnetId"] == "odb_subnet_id_value" -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_databases_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) + request = request_type(**request_init) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_databases), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - database.ListDatabasesResponse( - next_page_token="next_page_token_value", - ) - ) - await client.list_databases(request=None) + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = database.ListDatabasesRequest() - assert args[0] == request_msg + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_get_database_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", + response = client.create_odb_subnet(request) + + expected_params = [ + ( + "odbSubnetId", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_create_odb_subnet_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.get_database), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - database.Database( - name="name_value", - db_name="db_name_value", - db_unique_name="db_unique_name_value", - admin_password="admin_password_value", - tde_wallet_password="tde_wallet_password_value", - character_set="character_set_value", - ncharacter_set="ncharacter_set_value", - oci_url="oci_url_value", - database_id="database_id_value", - db_home_name="db_home_name_value", - gcp_oracle_zone="gcp_oracle_zone_value", - ops_insights_status=database.Database.OperationsInsightsStatus.ENABLING, + unset_fields = transport.create_odb_subnet._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "odbSubnetId", + "requestId", ) ) - await client.get_database(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = database.GetDatabaseRequest() - assert args[0] == request_msg + & set( + ( + "parent", + "odbSubnetId", + "odbSubnet", + ) + ) + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_pluggable_databases_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +def test_create_odb_subnet_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_pluggable_databases), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - pluggable_database.ListPluggableDatabasesResponse( - next_page_token="next_page_token_value", - ) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = { + "parent": "projects/sample1/locations/sample2/odbNetworks/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + odb_subnet=gco_odb_subnet.OdbSubnet(name="name_value"), + odb_subnet_id="odb_subnet_id_value", ) - await client.list_pluggable_databases(request=None) + mock_args.update(sample_request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = pluggable_database.ListPluggableDatabasesRequest() - assert args[0] == request_msg + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.create_odb_subnet(**mock_args) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_get_pluggable_database_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*/odbNetworks/*}/odbSubnets" + % client.transport._host, + args[1], + ) + + +def test_create_odb_subnet_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_pluggable_database), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - pluggable_database.PluggableDatabase( - name="name_value", - oci_url="oci_url_value", - ) + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_odb_subnet( + gco_odb_subnet.CreateOdbSubnetRequest(), + parent="parent_value", + odb_subnet=gco_odb_subnet.OdbSubnet(name="name_value"), + odb_subnet_id="odb_subnet_id_value", ) - await client.get_pluggable_database(request=None) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = pluggable_database.GetPluggableDatabaseRequest() - assert args[0] == request_msg +def test_delete_odb_subnet_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_db_systems_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_db_systems), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - db_system.ListDbSystemsResponse( - next_page_token="next_page_token_value", - ) + # Ensure method has been cached + assert client._transport.delete_odb_subnet in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.delete_odb_subnet] = ( + mock_rpc ) - await client.list_db_systems(request=None) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = db_system.ListDbSystemsRequest() - assert args[0] == request_msg + request = {} + client.delete_odb_subnet(request) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_get_db_system_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_odb_subnet(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_delete_odb_subnet_rest_required_fields( + request_type=odb_subnet.DeleteOdbSubnetRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.get_db_system), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - db_system.DbSystem( - name="name_value", - gcp_oracle_zone="gcp_oracle_zone_value", - odb_network="odb_network_value", - odb_subnet="odb_subnet_value", - entitlement_id="entitlement_id_value", - display_name="display_name_value", - oci_url="oci_url_value", - ) - ) - await client.get_db_system(request=None) + # verify fields with default values are dropped - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = db_system.GetDbSystemRequest() - assert args[0] == request_msg + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_odb_subnet._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + # verify required fields with default values are now present -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_create_db_system_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_odb_subnet._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("request_id",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) + request = request_type(**request_init) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.create_db_system), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "delete", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.delete_odb_subnet(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_delete_odb_subnet_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.delete_odb_subnet._get_unset_required_fields({}) + assert set(unset_fields) == (set(("requestId",)) & set(("name",))) + + +def test_delete_odb_subnet_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/odbNetworks/sample3/odbSubnets/sample4" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", ) - await client.create_db_system(request=None) + mock_args.update(sample_request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gco_db_system.CreateDbSystemRequest() - assert args[0] == request_msg + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.delete_odb_subnet(**mock_args) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_delete_db_system_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/odbNetworks/*/odbSubnets/*}" + % client.transport._host, + args[1], + ) + + +def test_delete_odb_subnet_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_odb_subnet( + odb_subnet.DeleteOdbSubnetRequest(), + name="name_value", + ) + + +def test_list_exadb_vm_clusters_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_exadb_vm_clusters + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.list_exadb_vm_clusters] = ( + mock_rpc + ) + + request = {} + client.list_exadb_vm_clusters(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_exadb_vm_clusters(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_exadb_vm_clusters_rest_required_fields( + request_type=oracledatabase.ListExadbVmClustersRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_exadb_vm_clusters._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_exadb_vm_clusters._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = oracledatabase.ListExadbVmClustersResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = oracledatabase.ListExadbVmClustersResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_exadb_vm_clusters(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_list_exadb_vm_clusters_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_exadb_vm_clusters._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +def test_list_exadb_vm_clusters_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = oracledatabase.ListExadbVmClustersResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = oracledatabase.ListExadbVmClustersResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_exadb_vm_clusters(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*}/exadbVmClusters" + % client.transport._host, + args[1], + ) + + +def test_list_exadb_vm_clusters_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_exadb_vm_clusters( + oracledatabase.ListExadbVmClustersRequest(), + parent="parent_value", + ) + + +def test_list_exadb_vm_clusters_rest_pager(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + oracledatabase.ListExadbVmClustersResponse( + exadb_vm_clusters=[ + exadb_vm_cluster.ExadbVmCluster(), + exadb_vm_cluster.ExadbVmCluster(), + exadb_vm_cluster.ExadbVmCluster(), + ], + next_page_token="abc", + ), + oracledatabase.ListExadbVmClustersResponse( + exadb_vm_clusters=[], + next_page_token="def", + ), + oracledatabase.ListExadbVmClustersResponse( + exadb_vm_clusters=[ + exadb_vm_cluster.ExadbVmCluster(), + ], + next_page_token="ghi", + ), + oracledatabase.ListExadbVmClustersResponse( + exadb_vm_clusters=[ + exadb_vm_cluster.ExadbVmCluster(), + exadb_vm_cluster.ExadbVmCluster(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + oracledatabase.ListExadbVmClustersResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_exadb_vm_clusters(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, exadb_vm_cluster.ExadbVmCluster) for i in results) + + pages = list(client.list_exadb_vm_clusters(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_get_exadb_vm_cluster_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.get_exadb_vm_cluster in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_exadb_vm_cluster] = ( + mock_rpc + ) + + request = {} + client.get_exadb_vm_cluster(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_exadb_vm_cluster(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_exadb_vm_cluster_rest_required_fields( + request_type=oracledatabase.GetExadbVmClusterRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_exadb_vm_cluster._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_exadb_vm_cluster._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = exadb_vm_cluster.ExadbVmCluster() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = exadb_vm_cluster.ExadbVmCluster.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_exadb_vm_cluster(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_get_exadb_vm_cluster_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_exadb_vm_cluster._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_exadb_vm_cluster_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = exadb_vm_cluster.ExadbVmCluster() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/exadbVmClusters/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = exadb_vm_cluster.ExadbVmCluster.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_exadb_vm_cluster(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/exadbVmClusters/*}" + % client.transport._host, + args[1], + ) + + +def test_get_exadb_vm_cluster_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_exadb_vm_cluster( + oracledatabase.GetExadbVmClusterRequest(), + name="name_value", + ) + + +def test_create_exadb_vm_cluster_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.create_exadb_vm_cluster + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.create_exadb_vm_cluster + ] = mock_rpc + + request = {} + client.create_exadb_vm_cluster(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.create_exadb_vm_cluster(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_create_exadb_vm_cluster_rest_required_fields( + request_type=oracledatabase.CreateExadbVmClusterRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["exadb_vm_cluster_id"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + assert "exadbVmClusterId" not in jsonified_request + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_exadb_vm_cluster._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "exadbVmClusterId" in jsonified_request + assert jsonified_request["exadbVmClusterId"] == request_init["exadb_vm_cluster_id"] + + jsonified_request["parent"] = "parent_value" + jsonified_request["exadbVmClusterId"] = "exadb_vm_cluster_id_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_exadb_vm_cluster._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "exadb_vm_cluster_id", + "request_id", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "exadbVmClusterId" in jsonified_request + assert jsonified_request["exadbVmClusterId"] == "exadb_vm_cluster_id_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.create_exadb_vm_cluster(request) + + expected_params = [ + ( + "exadbVmClusterId", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_create_exadb_vm_cluster_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.create_exadb_vm_cluster._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "exadbVmClusterId", + "requestId", + ) + ) + & set( + ( + "parent", + "exadbVmClusterId", + "exadbVmCluster", + ) + ) + ) + + +def test_create_exadb_vm_cluster_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + exadb_vm_cluster=gco_exadb_vm_cluster.ExadbVmCluster(name="name_value"), + exadb_vm_cluster_id="exadb_vm_cluster_id_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.create_exadb_vm_cluster(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*}/exadbVmClusters" + % client.transport._host, + args[1], + ) + + +def test_create_exadb_vm_cluster_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_exadb_vm_cluster( + oracledatabase.CreateExadbVmClusterRequest(), + parent="parent_value", + exadb_vm_cluster=gco_exadb_vm_cluster.ExadbVmCluster(name="name_value"), + exadb_vm_cluster_id="exadb_vm_cluster_id_value", + ) + + +def test_delete_exadb_vm_cluster_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.delete_exadb_vm_cluster + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.delete_exadb_vm_cluster + ] = mock_rpc + + request = {} + client.delete_exadb_vm_cluster(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_exadb_vm_cluster(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_delete_exadb_vm_cluster_rest_required_fields( + request_type=oracledatabase.DeleteExadbVmClusterRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_exadb_vm_cluster._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_exadb_vm_cluster._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("request_id",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "delete", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.delete_exadb_vm_cluster(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_delete_exadb_vm_cluster_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.delete_exadb_vm_cluster._get_unset_required_fields({}) + assert set(unset_fields) == (set(("requestId",)) & set(("name",))) + + +def test_delete_exadb_vm_cluster_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/exadbVmClusters/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.delete_exadb_vm_cluster(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/exadbVmClusters/*}" + % client.transport._host, + args[1], + ) + + +def test_delete_exadb_vm_cluster_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_exadb_vm_cluster( + oracledatabase.DeleteExadbVmClusterRequest(), + name="name_value", + ) + + +def test_update_exadb_vm_cluster_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.update_exadb_vm_cluster + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.update_exadb_vm_cluster + ] = mock_rpc + + request = {} + client.update_exadb_vm_cluster(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.update_exadb_vm_cluster(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_update_exadb_vm_cluster_rest_required_fields( + request_type=oracledatabase.UpdateExadbVmClusterRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_exadb_vm_cluster._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_exadb_vm_cluster._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "request_id", + "update_mask", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.update_exadb_vm_cluster(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_update_exadb_vm_cluster_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_exadb_vm_cluster._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "requestId", + "updateMask", + ) + ) + & set(("exadbVmCluster",)) + ) + + +def test_update_exadb_vm_cluster_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = { + "exadb_vm_cluster": { + "name": "projects/sample1/locations/sample2/exadbVmClusters/sample3" + } + } + + # get truthy value for each flattened field + mock_args = dict( + exadb_vm_cluster=gco_exadb_vm_cluster.ExadbVmCluster(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.update_exadb_vm_cluster(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{exadb_vm_cluster.name=projects/*/locations/*/exadbVmClusters/*}" + % client.transport._host, + args[1], + ) + + +def test_update_exadb_vm_cluster_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_exadb_vm_cluster( + oracledatabase.UpdateExadbVmClusterRequest(), + exadb_vm_cluster=gco_exadb_vm_cluster.ExadbVmCluster(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_remove_virtual_machine_exadb_vm_cluster_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.remove_virtual_machine_exadb_vm_cluster + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.remove_virtual_machine_exadb_vm_cluster + ] = mock_rpc + + request = {} + client.remove_virtual_machine_exadb_vm_cluster(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.remove_virtual_machine_exadb_vm_cluster(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_remove_virtual_machine_exadb_vm_cluster_rest_required_fields( + request_type=oracledatabase.RemoveVirtualMachineExadbVmClusterRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["name"] = "" + request_init["hostnames"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).remove_virtual_machine_exadb_vm_cluster._get_unset_required_fields( + jsonified_request + ) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + jsonified_request["hostnames"] = "hostnames_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).remove_virtual_machine_exadb_vm_cluster._get_unset_required_fields( + jsonified_request + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + assert "hostnames" in jsonified_request + assert jsonified_request["hostnames"] == "hostnames_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.remove_virtual_machine_exadb_vm_cluster(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_remove_virtual_machine_exadb_vm_cluster_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = ( + transport.remove_virtual_machine_exadb_vm_cluster._get_unset_required_fields({}) + ) + assert set(unset_fields) == ( + set(()) + & set( + ( + "name", + "hostnames", + ) + ) + ) + + +def test_remove_virtual_machine_exadb_vm_cluster_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/exadbVmClusters/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + hostnames=["hostnames_value"], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.remove_virtual_machine_exadb_vm_cluster(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/exadbVmClusters/*}:removeVirtualMachine" + % client.transport._host, + args[1], + ) + + +def test_remove_virtual_machine_exadb_vm_cluster_rest_flattened_error( + transport: str = "rest", +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.remove_virtual_machine_exadb_vm_cluster( + oracledatabase.RemoveVirtualMachineExadbVmClusterRequest(), + name="name_value", + hostnames=["hostnames_value"], + ) + + +def test_list_exascale_db_storage_vaults_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_exascale_db_storage_vaults + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_exascale_db_storage_vaults + ] = mock_rpc + + request = {} + client.list_exascale_db_storage_vaults(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_exascale_db_storage_vaults(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_exascale_db_storage_vaults_rest_required_fields( + request_type=exascale_db_storage_vault.ListExascaleDbStorageVaultsRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_exascale_db_storage_vaults._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_exascale_db_storage_vaults._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = ( + exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse.pb( + return_value + ) + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_exascale_db_storage_vaults(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_list_exascale_db_storage_vaults_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_exascale_db_storage_vaults._get_unset_required_fields( + {} + ) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +def test_list_exascale_db_storage_vaults_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_exascale_db_storage_vaults(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*}/exascaleDbStorageVaults" + % client.transport._host, + args[1], + ) + + +def test_list_exascale_db_storage_vaults_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_exascale_db_storage_vaults( + exascale_db_storage_vault.ListExascaleDbStorageVaultsRequest(), + parent="parent_value", + ) + + +def test_list_exascale_db_storage_vaults_rest_pager(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse( + exascale_db_storage_vaults=[ + exascale_db_storage_vault.ExascaleDbStorageVault(), + exascale_db_storage_vault.ExascaleDbStorageVault(), + exascale_db_storage_vault.ExascaleDbStorageVault(), + ], + next_page_token="abc", + ), + exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse( + exascale_db_storage_vaults=[], + next_page_token="def", + ), + exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse( + exascale_db_storage_vaults=[ + exascale_db_storage_vault.ExascaleDbStorageVault(), + ], + next_page_token="ghi", + ), + exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse( + exascale_db_storage_vaults=[ + exascale_db_storage_vault.ExascaleDbStorageVault(), + exascale_db_storage_vault.ExascaleDbStorageVault(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_exascale_db_storage_vaults(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, exascale_db_storage_vault.ExascaleDbStorageVault) + for i in results + ) + + pages = list( + client.list_exascale_db_storage_vaults(request=sample_request).pages + ) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_get_exascale_db_storage_vault_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.get_exascale_db_storage_vault + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.get_exascale_db_storage_vault + ] = mock_rpc + + request = {} + client.get_exascale_db_storage_vault(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_exascale_db_storage_vault(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_exascale_db_storage_vault_rest_required_fields( + request_type=exascale_db_storage_vault.GetExascaleDbStorageVaultRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_exascale_db_storage_vault._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_exascale_db_storage_vault._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = exascale_db_storage_vault.ExascaleDbStorageVault() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = exascale_db_storage_vault.ExascaleDbStorageVault.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_exascale_db_storage_vault(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_get_exascale_db_storage_vault_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_exascale_db_storage_vault._get_unset_required_fields( + {} + ) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_exascale_db_storage_vault_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = exascale_db_storage_vault.ExascaleDbStorageVault() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/exascaleDbStorageVaults/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = exascale_db_storage_vault.ExascaleDbStorageVault.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_exascale_db_storage_vault(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/exascaleDbStorageVaults/*}" + % client.transport._host, + args[1], + ) + + +def test_get_exascale_db_storage_vault_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_exascale_db_storage_vault( + exascale_db_storage_vault.GetExascaleDbStorageVaultRequest(), + name="name_value", + ) + + +def test_create_exascale_db_storage_vault_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.create_exascale_db_storage_vault + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.create_exascale_db_storage_vault + ] = mock_rpc + + request = {} + client.create_exascale_db_storage_vault(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.create_exascale_db_storage_vault(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_create_exascale_db_storage_vault_rest_required_fields( + request_type=gco_exascale_db_storage_vault.CreateExascaleDbStorageVaultRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["exascale_db_storage_vault_id"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + assert "exascaleDbStorageVaultId" not in jsonified_request + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_exascale_db_storage_vault._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "exascaleDbStorageVaultId" in jsonified_request + assert ( + jsonified_request["exascaleDbStorageVaultId"] + == request_init["exascale_db_storage_vault_id"] + ) + + jsonified_request["parent"] = "parent_value" + jsonified_request["exascaleDbStorageVaultId"] = "exascale_db_storage_vault_id_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_exascale_db_storage_vault._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "exascale_db_storage_vault_id", + "request_id", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "exascaleDbStorageVaultId" in jsonified_request + assert ( + jsonified_request["exascaleDbStorageVaultId"] + == "exascale_db_storage_vault_id_value" + ) + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.create_exascale_db_storage_vault(request) + + expected_params = [ + ( + "exascaleDbStorageVaultId", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_create_exascale_db_storage_vault_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = ( + transport.create_exascale_db_storage_vault._get_unset_required_fields({}) + ) + assert set(unset_fields) == ( + set( + ( + "exascaleDbStorageVaultId", + "requestId", + ) + ) + & set( + ( + "parent", + "exascaleDbStorageVaultId", + "exascaleDbStorageVault", + ) + ) + ) + + +def test_create_exascale_db_storage_vault_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + exascale_db_storage_vault=gco_exascale_db_storage_vault.ExascaleDbStorageVault( + name="name_value" + ), + exascale_db_storage_vault_id="exascale_db_storage_vault_id_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.create_exascale_db_storage_vault(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*}/exascaleDbStorageVaults" + % client.transport._host, + args[1], + ) + + +def test_create_exascale_db_storage_vault_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_exascale_db_storage_vault( + gco_exascale_db_storage_vault.CreateExascaleDbStorageVaultRequest(), + parent="parent_value", + exascale_db_storage_vault=gco_exascale_db_storage_vault.ExascaleDbStorageVault( + name="name_value" + ), + exascale_db_storage_vault_id="exascale_db_storage_vault_id_value", + ) + + +def test_delete_exascale_db_storage_vault_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.delete_exascale_db_storage_vault + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.delete_exascale_db_storage_vault + ] = mock_rpc + + request = {} + client.delete_exascale_db_storage_vault(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_exascale_db_storage_vault(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_delete_exascale_db_storage_vault_rest_required_fields( + request_type=exascale_db_storage_vault.DeleteExascaleDbStorageVaultRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_exascale_db_storage_vault._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_exascale_db_storage_vault._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("request_id",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "delete", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.delete_exascale_db_storage_vault(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_delete_exascale_db_storage_vault_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = ( + transport.delete_exascale_db_storage_vault._get_unset_required_fields({}) + ) + assert set(unset_fields) == (set(("requestId",)) & set(("name",))) + + +def test_delete_exascale_db_storage_vault_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/exascaleDbStorageVaults/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.delete_exascale_db_storage_vault(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/exascaleDbStorageVaults/*}" + % client.transport._host, + args[1], + ) + + +def test_delete_exascale_db_storage_vault_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_exascale_db_storage_vault( + exascale_db_storage_vault.DeleteExascaleDbStorageVaultRequest(), + name="name_value", + ) + + +def test_list_db_system_initial_storage_sizes_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_db_system_initial_storage_sizes + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_db_system_initial_storage_sizes + ] = mock_rpc + + request = {} + client.list_db_system_initial_storage_sizes(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_db_system_initial_storage_sizes(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_db_system_initial_storage_sizes_rest_required_fields( + request_type=db_system_initial_storage_size.ListDbSystemInitialStorageSizesRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_db_system_initial_storage_sizes._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_db_system_initial_storage_sizes._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = ( + db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse() + ) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_db_system_initial_storage_sizes(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_list_db_system_initial_storage_sizes_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = ( + transport.list_db_system_initial_storage_sizes._get_unset_required_fields({}) + ) + assert set(unset_fields) == ( + set( + ( + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +def test_list_db_system_initial_storage_sizes_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = ( + db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse() + ) + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = ( + db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse.pb( + return_value + ) + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_db_system_initial_storage_sizes(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*}/dbSystemInitialStorageSizes" + % client.transport._host, + args[1], + ) + + +def test_list_db_system_initial_storage_sizes_rest_flattened_error( + transport: str = "rest", +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_db_system_initial_storage_sizes( + db_system_initial_storage_size.ListDbSystemInitialStorageSizesRequest(), + parent="parent_value", + ) + + +def test_list_db_system_initial_storage_sizes_rest_pager(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse( + db_system_initial_storage_sizes=[ + db_system_initial_storage_size.DbSystemInitialStorageSize(), + db_system_initial_storage_size.DbSystemInitialStorageSize(), + db_system_initial_storage_size.DbSystemInitialStorageSize(), + ], + next_page_token="abc", + ), + db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse( + db_system_initial_storage_sizes=[], + next_page_token="def", + ), + db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse( + db_system_initial_storage_sizes=[ + db_system_initial_storage_size.DbSystemInitialStorageSize(), + ], + next_page_token="ghi", + ), + db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse( + db_system_initial_storage_sizes=[ + db_system_initial_storage_size.DbSystemInitialStorageSize(), + db_system_initial_storage_size.DbSystemInitialStorageSize(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse.to_json( + x + ) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_db_system_initial_storage_sizes(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, db_system_initial_storage_size.DbSystemInitialStorageSize) + for i in results + ) + + pages = list( + client.list_db_system_initial_storage_sizes(request=sample_request).pages + ) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_list_databases_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.list_databases in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.list_databases] = mock_rpc + + request = {} + client.list_databases(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_databases(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_databases_rest_required_fields( + request_type=database.ListDatabasesRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_databases._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_databases._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = database.ListDatabasesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = database.ListDatabasesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_databases(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_list_databases_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_databases._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +def test_list_databases_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = database.ListDatabasesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = database.ListDatabasesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_databases(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*}/databases" % client.transport._host, + args[1], + ) + + +def test_list_databases_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_databases( + database.ListDatabasesRequest(), + parent="parent_value", + ) + + +def test_list_databases_rest_pager(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + database.ListDatabasesResponse( + databases=[ + database.Database(), + database.Database(), + database.Database(), + ], + next_page_token="abc", + ), + database.ListDatabasesResponse( + databases=[], + next_page_token="def", + ), + database.ListDatabasesResponse( + databases=[ + database.Database(), + ], + next_page_token="ghi", + ), + database.ListDatabasesResponse( + databases=[ + database.Database(), + database.Database(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(database.ListDatabasesResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_databases(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, database.Database) for i in results) + + pages = list(client.list_databases(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_get_database_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_database in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_database] = mock_rpc + + request = {} + client.get_database(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_database(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_database_rest_required_fields(request_type=database.GetDatabaseRequest): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_database._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_database._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = database.Database() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = database.Database.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_database(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_get_database_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_database._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_database_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = database.Database() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/databases/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = database.Database.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_database(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/databases/*}" % client.transport._host, + args[1], + ) + + +def test_get_database_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_database( + database.GetDatabaseRequest(), + name="name_value", + ) + + +def test_list_pluggable_databases_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_pluggable_databases + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_pluggable_databases + ] = mock_rpc + + request = {} + client.list_pluggable_databases(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_pluggable_databases(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_pluggable_databases_rest_required_fields( + request_type=pluggable_database.ListPluggableDatabasesRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_pluggable_databases._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_pluggable_databases._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = pluggable_database.ListPluggableDatabasesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = pluggable_database.ListPluggableDatabasesResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_pluggable_databases(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_list_pluggable_databases_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_pluggable_databases._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +def test_list_pluggable_databases_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = pluggable_database.ListPluggableDatabasesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = pluggable_database.ListPluggableDatabasesResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_pluggable_databases(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*}/pluggableDatabases" + % client.transport._host, + args[1], + ) + + +def test_list_pluggable_databases_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_pluggable_databases( + pluggable_database.ListPluggableDatabasesRequest(), + parent="parent_value", + ) + + +def test_list_pluggable_databases_rest_pager(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + pluggable_database.ListPluggableDatabasesResponse( + pluggable_databases=[ + pluggable_database.PluggableDatabase(), + pluggable_database.PluggableDatabase(), + pluggable_database.PluggableDatabase(), + ], + next_page_token="abc", + ), + pluggable_database.ListPluggableDatabasesResponse( + pluggable_databases=[], + next_page_token="def", + ), + pluggable_database.ListPluggableDatabasesResponse( + pluggable_databases=[ + pluggable_database.PluggableDatabase(), + ], + next_page_token="ghi", + ), + pluggable_database.ListPluggableDatabasesResponse( + pluggable_databases=[ + pluggable_database.PluggableDatabase(), + pluggable_database.PluggableDatabase(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + pluggable_database.ListPluggableDatabasesResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_pluggable_databases(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, pluggable_database.PluggableDatabase) for i in results) + + pages = list(client.list_pluggable_databases(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_get_pluggable_database_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.get_pluggable_database + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_pluggable_database] = ( + mock_rpc + ) + + request = {} + client.get_pluggable_database(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_pluggable_database(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_pluggable_database_rest_required_fields( + request_type=pluggable_database.GetPluggableDatabaseRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_pluggable_database._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_pluggable_database._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = pluggable_database.PluggableDatabase() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = pluggable_database.PluggableDatabase.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_pluggable_database(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_get_pluggable_database_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_pluggable_database._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_pluggable_database_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = pluggable_database.PluggableDatabase() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/pluggableDatabases/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = pluggable_database.PluggableDatabase.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_pluggable_database(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/pluggableDatabases/*}" + % client.transport._host, + args[1], + ) + + +def test_get_pluggable_database_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_pluggable_database( + pluggable_database.GetPluggableDatabaseRequest(), + name="name_value", + ) + + +def test_list_db_systems_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.list_db_systems in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.list_db_systems] = mock_rpc + + request = {} + client.list_db_systems(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_db_systems(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_db_systems_rest_required_fields( + request_type=db_system.ListDbSystemsRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_db_systems._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_db_systems._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = db_system.ListDbSystemsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = db_system.ListDbSystemsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_db_systems(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_list_db_systems_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_db_systems._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +def test_list_db_systems_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = db_system.ListDbSystemsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = db_system.ListDbSystemsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_db_systems(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*}/dbSystems" % client.transport._host, + args[1], + ) + + +def test_list_db_systems_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_db_systems( + db_system.ListDbSystemsRequest(), + parent="parent_value", + ) + + +def test_list_db_systems_rest_pager(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + db_system.ListDbSystemsResponse( + db_systems=[ + db_system.DbSystem(), + db_system.DbSystem(), + db_system.DbSystem(), + ], + next_page_token="abc", + ), + db_system.ListDbSystemsResponse( + db_systems=[], + next_page_token="def", + ), + db_system.ListDbSystemsResponse( + db_systems=[ + db_system.DbSystem(), + ], + next_page_token="ghi", + ), + db_system.ListDbSystemsResponse( + db_systems=[ + db_system.DbSystem(), + db_system.DbSystem(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(db_system.ListDbSystemsResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_db_systems(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, db_system.DbSystem) for i in results) + + pages = list(client.list_db_systems(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_get_db_system_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_db_system in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_db_system] = mock_rpc + + request = {} + client.get_db_system(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_db_system(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_db_system_rest_required_fields(request_type=db_system.GetDbSystemRequest): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_db_system._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_db_system._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = db_system.DbSystem() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = db_system.DbSystem.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_db_system(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_get_db_system_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_db_system._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_db_system_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = db_system.DbSystem() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/dbSystems/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = db_system.DbSystem.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_db_system(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/dbSystems/*}" % client.transport._host, + args[1], + ) + + +def test_get_db_system_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_db_system( + db_system.GetDbSystemRequest(), + name="name_value", + ) + + +def test_create_db_system_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.create_db_system in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.create_db_system] = ( + mock_rpc + ) + + request = {} + client.create_db_system(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.create_db_system(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_create_db_system_rest_required_fields( + request_type=gco_db_system.CreateDbSystemRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["db_system_id"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + assert "dbSystemId" not in jsonified_request + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_db_system._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "dbSystemId" in jsonified_request + assert jsonified_request["dbSystemId"] == request_init["db_system_id"] + + jsonified_request["parent"] = "parent_value" + jsonified_request["dbSystemId"] = "db_system_id_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_db_system._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "db_system_id", + "request_id", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "dbSystemId" in jsonified_request + assert jsonified_request["dbSystemId"] == "db_system_id_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.create_db_system(request) + + expected_params = [ + ( + "dbSystemId", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_create_db_system_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.create_db_system._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "dbSystemId", + "requestId", + ) + ) + & set( + ( + "parent", + "dbSystemId", + "dbSystem", + ) + ) + ) + + +def test_create_db_system_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + db_system=gco_db_system.DbSystem(name="name_value"), + db_system_id="db_system_id_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.create_db_system(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*}/dbSystems" % client.transport._host, + args[1], + ) + + +def test_create_db_system_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_db_system( + gco_db_system.CreateDbSystemRequest(), + parent="parent_value", + db_system=gco_db_system.DbSystem(name="name_value"), + db_system_id="db_system_id_value", + ) + + +def test_delete_db_system_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.delete_db_system in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.delete_db_system] = ( + mock_rpc + ) + + request = {} + client.delete_db_system(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_db_system(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_delete_db_system_rest_required_fields( + request_type=db_system.DeleteDbSystemRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_db_system._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_db_system._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("request_id",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "delete", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.delete_db_system(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_delete_db_system_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.delete_db_system._get_unset_required_fields({}) + assert set(unset_fields) == (set(("requestId",)) & set(("name",))) + + +def test_delete_db_system_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/dbSystems/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.delete_db_system(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/dbSystems/*}" % client.transport._host, + args[1], + ) + + +def test_delete_db_system_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_db_system( + db_system.DeleteDbSystemRequest(), + name="name_value", + ) + + +def test_list_goldengate_deployments_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_goldengate_deployments + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_goldengate_deployments + ] = mock_rpc + + request = {} + client.list_goldengate_deployments(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_goldengate_deployments(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_goldengate_deployments_rest_required_fields( + request_type=goldengate_deployment.ListGoldengateDeploymentsRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_goldengate_deployments._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_goldengate_deployments._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = goldengate_deployment.ListGoldengateDeploymentsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = goldengate_deployment.ListGoldengateDeploymentsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_goldengate_deployments(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_list_goldengate_deployments_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_goldengate_deployments._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +def test_list_goldengate_deployments_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = goldengate_deployment.ListGoldengateDeploymentsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = goldengate_deployment.ListGoldengateDeploymentsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_goldengate_deployments(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*}/goldengateDeployments" + % client.transport._host, + args[1], + ) + + +def test_list_goldengate_deployments_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_goldengate_deployments( + goldengate_deployment.ListGoldengateDeploymentsRequest(), + parent="parent_value", + ) + + +def test_list_goldengate_deployments_rest_pager(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + goldengate_deployment.ListGoldengateDeploymentsResponse( + goldengate_deployments=[ + goldengate_deployment.GoldengateDeployment(), + goldengate_deployment.GoldengateDeployment(), + goldengate_deployment.GoldengateDeployment(), + ], + next_page_token="abc", + ), + goldengate_deployment.ListGoldengateDeploymentsResponse( + goldengate_deployments=[], + next_page_token="def", + ), + goldengate_deployment.ListGoldengateDeploymentsResponse( + goldengate_deployments=[ + goldengate_deployment.GoldengateDeployment(), + ], + next_page_token="ghi", + ), + goldengate_deployment.ListGoldengateDeploymentsResponse( + goldengate_deployments=[ + goldengate_deployment.GoldengateDeployment(), + goldengate_deployment.GoldengateDeployment(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + goldengate_deployment.ListGoldengateDeploymentsResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_goldengate_deployments(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, goldengate_deployment.GoldengateDeployment) for i in results + ) + + pages = list(client.list_goldengate_deployments(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_get_goldengate_deployment_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.get_goldengate_deployment + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.get_goldengate_deployment + ] = mock_rpc + + request = {} + client.get_goldengate_deployment(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_goldengate_deployment(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_goldengate_deployment_rest_required_fields( + request_type=goldengate_deployment.GetGoldengateDeploymentRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_goldengate_deployment._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_goldengate_deployment._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = goldengate_deployment.GoldengateDeployment() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = goldengate_deployment.GoldengateDeployment.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_goldengate_deployment(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_get_goldengate_deployment_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_goldengate_deployment._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_goldengate_deployment_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = goldengate_deployment.GoldengateDeployment() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/goldengateDeployments/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = goldengate_deployment.GoldengateDeployment.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_goldengate_deployment(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/goldengateDeployments/*}" + % client.transport._host, + args[1], + ) + + +def test_get_goldengate_deployment_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_goldengate_deployment( + goldengate_deployment.GetGoldengateDeploymentRequest(), + name="name_value", + ) + + +def test_create_goldengate_deployment_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.create_goldengate_deployment + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.create_goldengate_deployment + ] = mock_rpc + + request = {} + client.create_goldengate_deployment(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.create_goldengate_deployment(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_create_goldengate_deployment_rest_required_fields( + request_type=gco_goldengate_deployment.CreateGoldengateDeploymentRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["goldengate_deployment_id"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + assert "goldengateDeploymentId" not in jsonified_request + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_goldengate_deployment._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "goldengateDeploymentId" in jsonified_request + assert ( + jsonified_request["goldengateDeploymentId"] + == request_init["goldengate_deployment_id"] + ) + + jsonified_request["parent"] = "parent_value" + jsonified_request["goldengateDeploymentId"] = "goldengate_deployment_id_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_goldengate_deployment._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "goldengate_deployment_id", + "request_id", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "goldengateDeploymentId" in jsonified_request + assert ( + jsonified_request["goldengateDeploymentId"] == "goldengate_deployment_id_value" + ) + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.create_goldengate_deployment(request) + + expected_params = [ + ( + "goldengateDeploymentId", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_create_goldengate_deployment_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.create_goldengate_deployment._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "goldengateDeploymentId", + "requestId", + ) + ) + & set( + ( + "parent", + "goldengateDeploymentId", + "goldengateDeployment", + ) + ) + ) + + +def test_create_goldengate_deployment_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + goldengate_deployment=gco_goldengate_deployment.GoldengateDeployment( + name="name_value" + ), + goldengate_deployment_id="goldengate_deployment_id_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.create_goldengate_deployment(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*}/goldengateDeployments" + % client.transport._host, + args[1], + ) + + +def test_create_goldengate_deployment_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_goldengate_deployment( + gco_goldengate_deployment.CreateGoldengateDeploymentRequest(), + parent="parent_value", + goldengate_deployment=gco_goldengate_deployment.GoldengateDeployment( + name="name_value" + ), + goldengate_deployment_id="goldengate_deployment_id_value", + ) + + +def test_delete_goldengate_deployment_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.delete_goldengate_deployment + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.delete_goldengate_deployment + ] = mock_rpc + + request = {} + client.delete_goldengate_deployment(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_goldengate_deployment(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_delete_goldengate_deployment_rest_required_fields( + request_type=goldengate_deployment.DeleteGoldengateDeploymentRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_goldengate_deployment._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_goldengate_deployment._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("request_id",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "delete", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.delete_goldengate_deployment(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_delete_goldengate_deployment_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.delete_goldengate_deployment._get_unset_required_fields({}) + assert set(unset_fields) == (set(("requestId",)) & set(("name",))) + + +def test_delete_goldengate_deployment_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/goldengateDeployments/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.delete_goldengate_deployment(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/goldengateDeployments/*}" + % client.transport._host, + args[1], + ) + + +def test_delete_goldengate_deployment_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_goldengate_deployment( + goldengate_deployment.DeleteGoldengateDeploymentRequest(), + name="name_value", + ) + + +def test_stop_goldengate_deployment_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.stop_goldengate_deployment + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.stop_goldengate_deployment + ] = mock_rpc + + request = {} + client.stop_goldengate_deployment(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.stop_goldengate_deployment(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_stop_goldengate_deployment_rest_required_fields( + request_type=goldengate_deployment.StopGoldengateDeploymentRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).stop_goldengate_deployment._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).stop_goldengate_deployment._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.stop_goldengate_deployment(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_stop_goldengate_deployment_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.stop_goldengate_deployment._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_stop_goldengate_deployment_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/goldengateDeployments/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.stop_goldengate_deployment(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/goldengateDeployments/*}:stop" + % client.transport._host, + args[1], + ) + + +def test_stop_goldengate_deployment_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.stop_goldengate_deployment( + goldengate_deployment.StopGoldengateDeploymentRequest(), + name="name_value", + ) + + +def test_start_goldengate_deployment_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.start_goldengate_deployment + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.start_goldengate_deployment + ] = mock_rpc + + request = {} + client.start_goldengate_deployment(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.start_goldengate_deployment(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_start_goldengate_deployment_rest_required_fields( + request_type=goldengate_deployment.StartGoldengateDeploymentRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).start_goldengate_deployment._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).start_goldengate_deployment._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.start_goldengate_deployment(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_start_goldengate_deployment_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.start_goldengate_deployment._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_start_goldengate_deployment_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/goldengateDeployments/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.start_goldengate_deployment(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/goldengateDeployments/*}:start" + % client.transport._host, + args[1], + ) + + +def test_start_goldengate_deployment_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.start_goldengate_deployment( + goldengate_deployment.StartGoldengateDeploymentRequest(), + name="name_value", + ) + + +def test_list_goldengate_connections_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_goldengate_connections + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_goldengate_connections + ] = mock_rpc + + request = {} + client.list_goldengate_connections(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_goldengate_connections(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_goldengate_connections_rest_required_fields( + request_type=goldengate_connection.ListGoldengateConnectionsRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_goldengate_connections._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_goldengate_connections._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = goldengate_connection.ListGoldengateConnectionsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = goldengate_connection.ListGoldengateConnectionsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_goldengate_connections(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_list_goldengate_connections_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_goldengate_connections._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +def test_list_goldengate_connections_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = goldengate_connection.ListGoldengateConnectionsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = goldengate_connection.ListGoldengateConnectionsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_goldengate_connections(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*}/goldengateConnections" + % client.transport._host, + args[1], + ) + + +def test_list_goldengate_connections_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_goldengate_connections( + goldengate_connection.ListGoldengateConnectionsRequest(), + parent="parent_value", + ) + + +def test_list_goldengate_connections_rest_pager(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + goldengate_connection.ListGoldengateConnectionsResponse( + goldengate_connections=[ + goldengate_connection.GoldengateConnection(), + goldengate_connection.GoldengateConnection(), + goldengate_connection.GoldengateConnection(), + ], + next_page_token="abc", + ), + goldengate_connection.ListGoldengateConnectionsResponse( + goldengate_connections=[], + next_page_token="def", + ), + goldengate_connection.ListGoldengateConnectionsResponse( + goldengate_connections=[ + goldengate_connection.GoldengateConnection(), + ], + next_page_token="ghi", + ), + goldengate_connection.ListGoldengateConnectionsResponse( + goldengate_connections=[ + goldengate_connection.GoldengateConnection(), + goldengate_connection.GoldengateConnection(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + goldengate_connection.ListGoldengateConnectionsResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_goldengate_connections(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, goldengate_connection.GoldengateConnection) for i in results + ) + + pages = list(client.list_goldengate_connections(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_get_goldengate_connection_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.get_goldengate_connection + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.get_goldengate_connection + ] = mock_rpc + + request = {} + client.get_goldengate_connection(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_goldengate_connection(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_goldengate_connection_rest_required_fields( + request_type=goldengate_connection.GetGoldengateConnectionRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_goldengate_connection._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_goldengate_connection._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = goldengate_connection.GoldengateConnection() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = goldengate_connection.GoldengateConnection.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_goldengate_connection(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_get_goldengate_connection_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_goldengate_connection._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_goldengate_connection_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = goldengate_connection.GoldengateConnection() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/goldengateConnections/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = goldengate_connection.GoldengateConnection.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_goldengate_connection(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/goldengateConnections/*}" + % client.transport._host, + args[1], + ) + + +def test_get_goldengate_connection_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_goldengate_connection( + goldengate_connection.GetGoldengateConnectionRequest(), + name="name_value", + ) + + +def test_create_goldengate_connection_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.create_goldengate_connection + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.create_goldengate_connection + ] = mock_rpc + + request = {} + client.create_goldengate_connection(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.create_goldengate_connection(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_create_goldengate_connection_rest_required_fields( + request_type=gco_goldengate_connection.CreateGoldengateConnectionRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["goldengate_connection_id"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + assert "goldengateConnectionId" not in jsonified_request + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_goldengate_connection._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "goldengateConnectionId" in jsonified_request + assert ( + jsonified_request["goldengateConnectionId"] + == request_init["goldengate_connection_id"] + ) + + jsonified_request["parent"] = "parent_value" + jsonified_request["goldengateConnectionId"] = "goldengate_connection_id_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_goldengate_connection._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "goldengate_connection_id", + "request_id", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "goldengateConnectionId" in jsonified_request + assert ( + jsonified_request["goldengateConnectionId"] == "goldengate_connection_id_value" + ) + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.create_goldengate_connection(request) + + expected_params = [ + ( + "goldengateConnectionId", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_create_goldengate_connection_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.create_goldengate_connection._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "goldengateConnectionId", + "requestId", + ) + ) + & set( + ( + "parent", + "goldengateConnectionId", + "goldengateConnection", + ) + ) + ) + + +def test_create_goldengate_connection_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + goldengate_connection=gco_goldengate_connection.GoldengateConnection( + name="name_value" + ), + goldengate_connection_id="goldengate_connection_id_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.create_goldengate_connection(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*}/goldengateConnections" + % client.transport._host, + args[1], + ) + + +def test_create_goldengate_connection_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_goldengate_connection( + gco_goldengate_connection.CreateGoldengateConnectionRequest(), + parent="parent_value", + goldengate_connection=gco_goldengate_connection.GoldengateConnection( + name="name_value" + ), + goldengate_connection_id="goldengate_connection_id_value", + ) + + +def test_delete_goldengate_connection_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.delete_goldengate_connection + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.delete_goldengate_connection + ] = mock_rpc + + request = {} + client.delete_goldengate_connection(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_goldengate_connection(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_delete_goldengate_connection_rest_required_fields( + request_type=goldengate_connection.DeleteGoldengateConnectionRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_goldengate_connection._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_goldengate_connection._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("request_id",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "delete", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.delete_goldengate_connection(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_delete_goldengate_connection_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.delete_goldengate_connection._get_unset_required_fields({}) + assert set(unset_fields) == (set(("requestId",)) & set(("name",))) + + +def test_delete_goldengate_connection_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/goldengateConnections/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.delete_goldengate_connection(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/goldengateConnections/*}" + % client.transport._host, + args[1], + ) + + +def test_delete_goldengate_connection_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_goldengate_connection( + goldengate_connection.DeleteGoldengateConnectionRequest(), + name="name_value", + ) + + +def test_get_goldengate_deployment_version_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.get_goldengate_deployment_version + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.get_goldengate_deployment_version + ] = mock_rpc + + request = {} + client.get_goldengate_deployment_version(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_goldengate_deployment_version(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_goldengate_deployment_version_rest_required_fields( + request_type=goldengate_deployment_version.GetGoldengateDeploymentVersionRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_goldengate_deployment_version._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_goldengate_deployment_version._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = goldengate_deployment_version.GoldengateDeploymentVersion() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = goldengate_deployment_version.GoldengateDeploymentVersion.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_goldengate_deployment_version(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_get_goldengate_deployment_version_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = ( + transport.get_goldengate_deployment_version._get_unset_required_fields({}) + ) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_goldengate_deployment_version_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = goldengate_deployment_version.GoldengateDeploymentVersion() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/goldengateDeploymentVersions/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = goldengate_deployment_version.GoldengateDeploymentVersion.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_goldengate_deployment_version(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/goldengateDeploymentVersions/*}" + % client.transport._host, + args[1], + ) + + +def test_get_goldengate_deployment_version_rest_flattened_error( + transport: str = "rest", +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_goldengate_deployment_version( + goldengate_deployment_version.GetGoldengateDeploymentVersionRequest(), + name="name_value", + ) + + +def test_list_goldengate_deployment_versions_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_goldengate_deployment_versions + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_goldengate_deployment_versions + ] = mock_rpc + + request = {} + client.list_goldengate_deployment_versions(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_goldengate_deployment_versions(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_goldengate_deployment_versions_rest_required_fields( + request_type=goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_goldengate_deployment_versions._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_goldengate_deployment_versions._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = ( + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse() + ) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_goldengate_deployment_versions(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_list_goldengate_deployment_versions_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = ( + transport.list_goldengate_deployment_versions._get_unset_required_fields({}) + ) + assert set(unset_fields) == ( + set( + ( + "filter", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +def test_list_goldengate_deployment_versions_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = ( + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse() + ) + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = ( + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse.pb( + return_value + ) + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_goldengate_deployment_versions(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*}/goldengateDeploymentVersions" + % client.transport._host, + args[1], + ) + + +def test_list_goldengate_deployment_versions_rest_flattened_error( + transport: str = "rest", +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_goldengate_deployment_versions( + goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest(), + parent="parent_value", + ) + + +def test_list_goldengate_deployment_versions_rest_pager(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse( + goldengate_deployment_versions=[ + goldengate_deployment_version.GoldengateDeploymentVersion(), + goldengate_deployment_version.GoldengateDeploymentVersion(), + goldengate_deployment_version.GoldengateDeploymentVersion(), + ], + next_page_token="abc", + ), + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse( + goldengate_deployment_versions=[], + next_page_token="def", + ), + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse( + goldengate_deployment_versions=[ + goldengate_deployment_version.GoldengateDeploymentVersion(), + ], + next_page_token="ghi", + ), + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse( + goldengate_deployment_versions=[ + goldengate_deployment_version.GoldengateDeploymentVersion(), + goldengate_deployment_version.GoldengateDeploymentVersion(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse.to_json( + x + ) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_goldengate_deployment_versions(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, goldengate_deployment_version.GoldengateDeploymentVersion) + for i in results + ) + + pages = list( + client.list_goldengate_deployment_versions(request=sample_request).pages + ) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_get_goldengate_deployment_type_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.get_goldengate_deployment_type + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.get_goldengate_deployment_type + ] = mock_rpc + + request = {} + client.get_goldengate_deployment_type(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_goldengate_deployment_type(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_goldengate_deployment_type_rest_required_fields( + request_type=goldengate_deployment_type.GetGoldengateDeploymentTypeRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_goldengate_deployment_type._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_goldengate_deployment_type._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = goldengate_deployment_type.GoldengateDeploymentType() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = goldengate_deployment_type.GoldengateDeploymentType.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_goldengate_deployment_type(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_get_goldengate_deployment_type_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_goldengate_deployment_type._get_unset_required_fields( + {} + ) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_goldengate_deployment_type_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = goldengate_deployment_type.GoldengateDeploymentType() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/goldengateDeploymentTypes/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = goldengate_deployment_type.GoldengateDeploymentType.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_goldengate_deployment_type(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/goldengateDeploymentTypes/*}" + % client.transport._host, + args[1], + ) + + +def test_get_goldengate_deployment_type_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_goldengate_deployment_type( + goldengate_deployment_type.GetGoldengateDeploymentTypeRequest(), + name="name_value", + ) + + +def test_list_goldengate_deployment_types_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_goldengate_deployment_types + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_goldengate_deployment_types + ] = mock_rpc + + request = {} + client.list_goldengate_deployment_types(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_goldengate_deployment_types(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_goldengate_deployment_types_rest_required_fields( + request_type=goldengate_deployment_type.ListGoldengateDeploymentTypesRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_goldengate_deployment_types._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_goldengate_deployment_types._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = goldengate_deployment_type.ListGoldengateDeploymentTypesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = ( + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse.pb( + return_value + ) + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_goldengate_deployment_types(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_list_goldengate_deployment_types_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = ( + transport.list_goldengate_deployment_types._get_unset_required_fields({}) + ) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +def test_list_goldengate_deployment_types_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = ( + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse() + ) + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = ( + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse.pb( + return_value + ) + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_goldengate_deployment_types(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*}/goldengateDeploymentTypes" + % client.transport._host, + args[1], + ) + + +def test_list_goldengate_deployment_types_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_goldengate_deployment_types( + goldengate_deployment_type.ListGoldengateDeploymentTypesRequest(), + parent="parent_value", + ) + + +def test_list_goldengate_deployment_types_rest_pager(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse( + goldengate_deployment_types=[ + goldengate_deployment_type.GoldengateDeploymentType(), + goldengate_deployment_type.GoldengateDeploymentType(), + goldengate_deployment_type.GoldengateDeploymentType(), + ], + next_page_token="abc", + ), + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse( + goldengate_deployment_types=[], + next_page_token="def", + ), + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse( + goldengate_deployment_types=[ + goldengate_deployment_type.GoldengateDeploymentType(), + ], + next_page_token="ghi", + ), + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse( + goldengate_deployment_types=[ + goldengate_deployment_type.GoldengateDeploymentType(), + goldengate_deployment_type.GoldengateDeploymentType(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_goldengate_deployment_types(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, goldengate_deployment_type.GoldengateDeploymentType) + for i in results + ) + + pages = list( + client.list_goldengate_deployment_types(request=sample_request).pages + ) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_get_goldengate_deployment_environment_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.get_goldengate_deployment_environment + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.get_goldengate_deployment_environment + ] = mock_rpc + + request = {} + client.get_goldengate_deployment_environment(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_goldengate_deployment_environment(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_goldengate_deployment_environment_rest_required_fields( + request_type=goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_goldengate_deployment_environment._get_unset_required_fields( + jsonified_request + ) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_goldengate_deployment_environment._get_unset_required_fields( + jsonified_request + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = goldengate_deployment_environment.GoldengateDeploymentEnvironment() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = ( + goldengate_deployment_environment.GoldengateDeploymentEnvironment.pb( + return_value + ) + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_goldengate_deployment_environment(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_get_goldengate_deployment_environment_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = ( + transport.get_goldengate_deployment_environment._get_unset_required_fields({}) + ) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_goldengate_deployment_environment_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = ( + goldengate_deployment_environment.GoldengateDeploymentEnvironment() + ) + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/goldengateDeploymentEnvironments/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = ( + goldengate_deployment_environment.GoldengateDeploymentEnvironment.pb( + return_value + ) + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_goldengate_deployment_environment(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/goldengateDeploymentEnvironments/*}" + % client.transport._host, + args[1], + ) + + +def test_get_goldengate_deployment_environment_rest_flattened_error( + transport: str = "rest", +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_goldengate_deployment_environment( + goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest(), + name="name_value", + ) + + +def test_list_goldengate_deployment_environments_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_goldengate_deployment_environments + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_goldengate_deployment_environments + ] = mock_rpc + + request = {} + client.list_goldengate_deployment_environments(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_goldengate_deployment_environments(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_goldengate_deployment_environments_rest_required_fields( + request_type=goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_goldengate_deployment_environments._get_unset_required_fields( + jsonified_request + ) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_goldengate_deployment_environments._get_unset_required_fields( + jsonified_request + ) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = ( + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse() + ) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_goldengate_deployment_environments(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_list_goldengate_deployment_environments_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = ( + transport.list_goldengate_deployment_environments._get_unset_required_fields({}) + ) + assert set(unset_fields) == ( + set( + ( + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +def test_list_goldengate_deployment_environments_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_goldengate_deployment_environments(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*}/goldengateDeploymentEnvironments" + % client.transport._host, + args[1], + ) + + +def test_list_goldengate_deployment_environments_rest_flattened_error( + transport: str = "rest", +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_goldengate_deployment_environments( + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest(), + parent="parent_value", + ) + + +def test_list_goldengate_deployment_environments_rest_pager(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse( + goldengate_deployment_environments=[ + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + ], + next_page_token="abc", + ), + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse( + goldengate_deployment_environments=[], + next_page_token="def", + ), + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse( + goldengate_deployment_environments=[ + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + ], + next_page_token="ghi", + ), + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse( + goldengate_deployment_environments=[ + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse.to_json( + x + ) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_goldengate_deployment_environments(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance( + i, goldengate_deployment_environment.GoldengateDeploymentEnvironment + ) + for i in results + ) + + pages = list( + client.list_goldengate_deployment_environments(request=sample_request).pages + ) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_get_goldengate_connection_type_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.get_goldengate_connection_type + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.get_goldengate_connection_type + ] = mock_rpc + + request = {} + client.get_goldengate_connection_type(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_goldengate_connection_type(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_goldengate_connection_type_rest_required_fields( + request_type=goldengate_connection_type.GetGoldengateConnectionTypeRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_goldengate_connection_type._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_goldengate_connection_type._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = goldengate_connection_type.GoldengateConnectionType() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = goldengate_connection_type.GoldengateConnectionType.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_goldengate_connection_type(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_get_goldengate_connection_type_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_goldengate_connection_type._get_unset_required_fields( + {} + ) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_goldengate_connection_type_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = goldengate_connection_type.GoldengateConnectionType() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/goldengateConnectionTypes/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = goldengate_connection_type.GoldengateConnectionType.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_goldengate_connection_type(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/goldengateConnectionTypes/*}" + % client.transport._host, + args[1], + ) + + +def test_get_goldengate_connection_type_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_goldengate_connection_type( + goldengate_connection_type.GetGoldengateConnectionTypeRequest(), + name="name_value", + ) + + +def test_list_goldengate_connection_types_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_goldengate_connection_types + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_goldengate_connection_types + ] = mock_rpc + + request = {} + client.list_goldengate_connection_types(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_goldengate_connection_types(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_goldengate_connection_types_rest_required_fields( + request_type=goldengate_connection_type.ListGoldengateConnectionTypesRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_goldengate_connection_types._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_goldengate_connection_types._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = goldengate_connection_type.ListGoldengateConnectionTypesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = ( + goldengate_connection_type.ListGoldengateConnectionTypesResponse.pb( + return_value + ) + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_goldengate_connection_types(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_list_goldengate_connection_types_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = ( + transport.list_goldengate_connection_types._get_unset_required_fields({}) + ) + assert set(unset_fields) == ( + set( + ( + "filter", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +def test_list_goldengate_connection_types_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = ( + goldengate_connection_type.ListGoldengateConnectionTypesResponse() + ) + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = ( + goldengate_connection_type.ListGoldengateConnectionTypesResponse.pb( + return_value + ) + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_goldengate_connection_types(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*}/goldengateConnectionTypes" + % client.transport._host, + args[1], + ) + + +def test_list_goldengate_connection_types_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_goldengate_connection_types( + goldengate_connection_type.ListGoldengateConnectionTypesRequest(), + parent="parent_value", + ) + + +def test_list_goldengate_connection_types_rest_pager(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + goldengate_connection_type.ListGoldengateConnectionTypesResponse( + goldengate_connection_types=[ + goldengate_connection_type.GoldengateConnectionType(), + goldengate_connection_type.GoldengateConnectionType(), + goldengate_connection_type.GoldengateConnectionType(), + ], + next_page_token="abc", + ), + goldengate_connection_type.ListGoldengateConnectionTypesResponse( + goldengate_connection_types=[], + next_page_token="def", + ), + goldengate_connection_type.ListGoldengateConnectionTypesResponse( + goldengate_connection_types=[ + goldengate_connection_type.GoldengateConnectionType(), + ], + next_page_token="ghi", + ), + goldengate_connection_type.ListGoldengateConnectionTypesResponse( + goldengate_connection_types=[ + goldengate_connection_type.GoldengateConnectionType(), + goldengate_connection_type.GoldengateConnectionType(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + goldengate_connection_type.ListGoldengateConnectionTypesResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_goldengate_connection_types(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, goldengate_connection_type.GoldengateConnectionType) + for i in results + ) + + pages = list( + client.list_goldengate_connection_types(request=sample_request).pages + ) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_list_db_versions_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.list_db_versions in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.list_db_versions] = ( + mock_rpc + ) + + request = {} + client.list_db_versions(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_db_versions(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_db_versions_rest_required_fields( + request_type=db_version.ListDbVersionsRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_db_versions._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_db_versions._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = db_version.ListDbVersionsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = db_version.ListDbVersionsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_db_versions(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_list_db_versions_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_db_versions._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +def test_list_db_versions_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = db_version.ListDbVersionsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = db_version.ListDbVersionsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_db_versions(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*}/dbVersions" % client.transport._host, + args[1], + ) + + +def test_list_db_versions_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_db_versions( + db_version.ListDbVersionsRequest(), + parent="parent_value", + ) + + +def test_list_db_versions_rest_pager(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + db_version.ListDbVersionsResponse( + db_versions=[ + db_version.DbVersion(), + db_version.DbVersion(), + db_version.DbVersion(), + ], + next_page_token="abc", + ), + db_version.ListDbVersionsResponse( + db_versions=[], + next_page_token="def", + ), + db_version.ListDbVersionsResponse( + db_versions=[ + db_version.DbVersion(), + ], + next_page_token="ghi", + ), + db_version.ListDbVersionsResponse( + db_versions=[ + db_version.DbVersion(), + db_version.DbVersion(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(db_version.ListDbVersionsResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_db_versions(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, db_version.DbVersion) for i in results) + + pages = list(client.list_db_versions(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_list_database_character_sets_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_database_character_sets + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_database_character_sets + ] = mock_rpc + + request = {} + client.list_database_character_sets(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_database_character_sets(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_database_character_sets_rest_required_fields( + request_type=database_character_set.ListDatabaseCharacterSetsRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_database_character_sets._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_database_character_sets._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = database_character_set.ListDatabaseCharacterSetsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = database_character_set.ListDatabaseCharacterSetsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_database_character_sets(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_list_database_character_sets_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_database_character_sets._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +def test_list_database_character_sets_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = database_character_set.ListDatabaseCharacterSetsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = database_character_set.ListDatabaseCharacterSetsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_database_character_sets(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*}/databaseCharacterSets" + % client.transport._host, + args[1], + ) + + +def test_list_database_character_sets_rest_flattened_error(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_database_character_sets( + database_character_set.ListDatabaseCharacterSetsRequest(), + parent="parent_value", + ) + + +def test_list_database_character_sets_rest_pager(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + database_character_set.ListDatabaseCharacterSetsResponse( + database_character_sets=[ + database_character_set.DatabaseCharacterSet(), + database_character_set.DatabaseCharacterSet(), + database_character_set.DatabaseCharacterSet(), + ], + next_page_token="abc", + ), + database_character_set.ListDatabaseCharacterSetsResponse( + database_character_sets=[], + next_page_token="def", + ), + database_character_set.ListDatabaseCharacterSetsResponse( + database_character_sets=[ + database_character_set.DatabaseCharacterSet(), + ], + next_page_token="ghi", + ), + database_character_set.ListDatabaseCharacterSetsResponse( + database_character_sets=[ + database_character_set.DatabaseCharacterSet(), + database_character_set.DatabaseCharacterSet(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + database_character_set.ListDatabaseCharacterSetsResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_database_character_sets(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, database_character_set.DatabaseCharacterSet) for i in results + ) + + pages = list(client.list_database_character_sets(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_list_goldengate_connection_assignments_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_goldengate_connection_assignments + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_goldengate_connection_assignments + ] = mock_rpc + + request = {} + client.list_goldengate_connection_assignments(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_goldengate_connection_assignments(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_goldengate_connection_assignments_rest_required_fields( + request_type=goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_goldengate_connection_assignments._get_unset_required_fields( + jsonified_request + ) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_goldengate_connection_assignments._get_unset_required_fields( + jsonified_request + ) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = ( + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse() + ) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_goldengate_connection_assignments(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_list_goldengate_connection_assignments_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = ( + transport.list_goldengate_connection_assignments._get_unset_required_fields({}) + ) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +def test_list_goldengate_connection_assignments_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_goldengate_connection_assignments(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*}/goldengateConnectionAssignments" + % client.transport._host, + args[1], + ) + + +def test_list_goldengate_connection_assignments_rest_flattened_error( + transport: str = "rest", +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_goldengate_connection_assignments( + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest(), + parent="parent_value", + ) + + +def test_list_goldengate_connection_assignments_rest_pager(transport: str = "rest"): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse( + goldengate_connection_assignments=[ + goldengate_connection_assignment.GoldengateConnectionAssignment(), + goldengate_connection_assignment.GoldengateConnectionAssignment(), + goldengate_connection_assignment.GoldengateConnectionAssignment(), + ], + next_page_token="abc", + ), + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse( + goldengate_connection_assignments=[], + next_page_token="def", + ), + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse( + goldengate_connection_assignments=[ + goldengate_connection_assignment.GoldengateConnectionAssignment(), + ], + next_page_token="ghi", + ), + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse( + goldengate_connection_assignments=[ + goldengate_connection_assignment.GoldengateConnectionAssignment(), + goldengate_connection_assignment.GoldengateConnectionAssignment(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse.to_json( + x + ) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_goldengate_connection_assignments(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance( + i, goldengate_connection_assignment.GoldengateConnectionAssignment + ) + for i in results + ) + + pages = list( + client.list_goldengate_connection_assignments(request=sample_request).pages + ) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_get_goldengate_connection_assignment_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.get_goldengate_connection_assignment + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.get_goldengate_connection_assignment + ] = mock_rpc + + request = {} + client.get_goldengate_connection_assignment(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_goldengate_connection_assignment(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_goldengate_connection_assignment_rest_required_fields( + request_type=goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_goldengate_connection_assignment._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_goldengate_connection_assignment._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = goldengate_connection_assignment.GoldengateConnectionAssignment() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = ( + goldengate_connection_assignment.GoldengateConnectionAssignment.pb( + return_value + ) + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_goldengate_connection_assignment(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_get_goldengate_connection_assignment_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = ( + transport.get_goldengate_connection_assignment._get_unset_required_fields({}) + ) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_goldengate_connection_assignment_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = goldengate_connection_assignment.GoldengateConnectionAssignment() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/goldengateConnectionAssignments/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = ( + goldengate_connection_assignment.GoldengateConnectionAssignment.pb( + return_value + ) + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_goldengate_connection_assignment(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/goldengateConnectionAssignments/*}" + % client.transport._host, + args[1], + ) + + +def test_get_goldengate_connection_assignment_rest_flattened_error( + transport: str = "rest", +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_goldengate_connection_assignment( + goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest(), + name="name_value", + ) + + +def test_create_goldengate_connection_assignment_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.create_goldengate_connection_assignment + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.create_goldengate_connection_assignment + ] = mock_rpc + + request = {} + client.create_goldengate_connection_assignment(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.create_goldengate_connection_assignment(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_create_goldengate_connection_assignment_rest_required_fields( + request_type=gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["goldengate_connection_assignment_id"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + assert "goldengateConnectionAssignmentId" not in jsonified_request + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_goldengate_connection_assignment._get_unset_required_fields( + jsonified_request + ) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "goldengateConnectionAssignmentId" in jsonified_request + assert ( + jsonified_request["goldengateConnectionAssignmentId"] + == request_init["goldengate_connection_assignment_id"] + ) + + jsonified_request["parent"] = "parent_value" + jsonified_request["goldengateConnectionAssignmentId"] = ( + "goldengate_connection_assignment_id_value" + ) + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_goldengate_connection_assignment._get_unset_required_fields( + jsonified_request + ) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "goldengate_connection_assignment_id", + "request_id", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "goldengateConnectionAssignmentId" in jsonified_request + assert ( + jsonified_request["goldengateConnectionAssignmentId"] + == "goldengate_connection_assignment_id_value" + ) + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.create_goldengate_connection_assignment(request) + + expected_params = [ + ( + "goldengateConnectionAssignmentId", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_create_goldengate_connection_assignment_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = ( + transport.create_goldengate_connection_assignment._get_unset_required_fields({}) + ) + assert set(unset_fields) == ( + set( + ( + "goldengateConnectionAssignmentId", + "requestId", + ) + ) + & set( + ( + "parent", + "goldengateConnectionAssignmentId", + "goldengateConnectionAssignment", + ) + ) + ) + + +def test_create_goldengate_connection_assignment_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + goldengate_connection_assignment=gco_goldengate_connection_assignment.GoldengateConnectionAssignment( + name="name_value" + ), + goldengate_connection_assignment_id="goldengate_connection_assignment_id_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.create_goldengate_connection_assignment(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*}/goldengateConnectionAssignments" + % client.transport._host, + args[1], + ) + + +def test_create_goldengate_connection_assignment_rest_flattened_error( + transport: str = "rest", +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_goldengate_connection_assignment( + gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest(), + parent="parent_value", + goldengate_connection_assignment=gco_goldengate_connection_assignment.GoldengateConnectionAssignment( + name="name_value" + ), + goldengate_connection_assignment_id="goldengate_connection_assignment_id_value", + ) + + +def test_delete_goldengate_connection_assignment_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.delete_goldengate_connection_assignment + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.delete_goldengate_connection_assignment + ] = mock_rpc + + request = {} + client.delete_goldengate_connection_assignment(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_goldengate_connection_assignment(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_delete_goldengate_connection_assignment_rest_required_fields( + request_type=goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_goldengate_connection_assignment._get_unset_required_fields( + jsonified_request + ) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_goldengate_connection_assignment._get_unset_required_fields( + jsonified_request + ) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("request_id",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "delete", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.delete_goldengate_connection_assignment(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_delete_goldengate_connection_assignment_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = ( + transport.delete_goldengate_connection_assignment._get_unset_required_fields({}) + ) + assert set(unset_fields) == (set(("requestId",)) & set(("name",))) + + +def test_delete_goldengate_connection_assignment_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/goldengateConnectionAssignments/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.delete_goldengate_connection_assignment(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/goldengateConnectionAssignments/*}" + % client.transport._host, + args[1], + ) + + +def test_delete_goldengate_connection_assignment_rest_flattened_error( + transport: str = "rest", +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_goldengate_connection_assignment( + goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest(), + name="name_value", + ) + + +def test_test_goldengate_connection_assignment_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.test_goldengate_connection_assignment + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.test_goldengate_connection_assignment + ] = mock_rpc + + request = {} + client.test_goldengate_connection_assignment(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.test_goldengate_connection_assignment(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_test_goldengate_connection_assignment_rest_required_fields( + request_type=goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest, +): + transport_class = transports.OracleDatabaseRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).test_goldengate_connection_assignment._get_unset_required_fields( + jsonified_request + ) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).test_goldengate_connection_assignment._get_unset_required_fields( + jsonified_request + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = ( + goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse() + ) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.test_goldengate_connection_assignment(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_test_goldengate_connection_assignment_rest_unset_required_fields(): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = ( + transport.test_goldengate_connection_assignment._get_unset_required_fields({}) + ) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_test_goldengate_connection_assignment_rest_flattened(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/goldengateConnectionAssignments/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.test_goldengate_connection_assignment(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/goldengateConnectionAssignments/*}:test" + % client.transport._host, + args[1], + ) + + +def test_test_goldengate_connection_assignment_rest_flattened_error( + transport: str = "rest", +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.test_goldengate_connection_assignment( + goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest(), + name="name_value", + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.OracleDatabaseGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.OracleDatabaseGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = OracleDatabaseClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.OracleDatabaseGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = OracleDatabaseClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = OracleDatabaseClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.OracleDatabaseGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = OracleDatabaseClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.OracleDatabaseGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = OracleDatabaseClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.OracleDatabaseGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.OracleDatabaseGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.OracleDatabaseGrpcTransport, + transports.OracleDatabaseGrpcAsyncIOTransport, + transports.OracleDatabaseRestTransport, + ], +) +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_kind_grpc(): + transport = OracleDatabaseClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_cloud_exadata_infrastructures_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_cloud_exadata_infrastructures), "__call__" + ) as call: + call.return_value = oracledatabase.ListCloudExadataInfrastructuresResponse() + client.list_cloud_exadata_infrastructures(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.ListCloudExadataInfrastructuresRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_cloud_exadata_infrastructure_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_cloud_exadata_infrastructure), "__call__" + ) as call: + call.return_value = exadata_infra.CloudExadataInfrastructure() + client.get_cloud_exadata_infrastructure(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.GetCloudExadataInfrastructureRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_cloud_exadata_infrastructure_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_cloud_exadata_infrastructure), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_cloud_exadata_infrastructure(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.CreateCloudExadataInfrastructureRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_cloud_exadata_infrastructure_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_cloud_exadata_infrastructure), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_cloud_exadata_infrastructure(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.DeleteCloudExadataInfrastructureRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_cloud_vm_clusters_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_cloud_vm_clusters), "__call__" + ) as call: + call.return_value = oracledatabase.ListCloudVmClustersResponse() + client.list_cloud_vm_clusters(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.ListCloudVmClustersRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_cloud_vm_cluster_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_cloud_vm_cluster), "__call__" + ) as call: + call.return_value = vm_cluster.CloudVmCluster() + client.get_cloud_vm_cluster(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.GetCloudVmClusterRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_cloud_vm_cluster_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_cloud_vm_cluster), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_cloud_vm_cluster(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.CreateCloudVmClusterRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_cloud_vm_cluster_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_cloud_vm_cluster), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_cloud_vm_cluster(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.DeleteCloudVmClusterRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_entitlements_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_entitlements), "__call__" + ) as call: + call.return_value = oracledatabase.ListEntitlementsResponse() + client.list_entitlements(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.ListEntitlementsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_db_servers_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_db_servers), "__call__") as call: + call.return_value = oracledatabase.ListDbServersResponse() + client.list_db_servers(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.ListDbServersRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_db_nodes_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_db_nodes), "__call__") as call: + call.return_value = oracledatabase.ListDbNodesResponse() + client.list_db_nodes(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.ListDbNodesRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_gi_versions_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_gi_versions), "__call__") as call: + call.return_value = oracledatabase.ListGiVersionsResponse() + client.list_gi_versions(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.ListGiVersionsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_minor_versions_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_minor_versions), "__call__" + ) as call: + call.return_value = minor_version.ListMinorVersionsResponse() + client.list_minor_versions(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = minor_version.ListMinorVersionsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_db_system_shapes_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_db_system_shapes), "__call__" + ) as call: + call.return_value = oracledatabase.ListDbSystemShapesResponse() + client.list_db_system_shapes(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.ListDbSystemShapesRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_autonomous_databases_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_autonomous_databases), "__call__" + ) as call: + call.return_value = oracledatabase.ListAutonomousDatabasesResponse() + client.list_autonomous_databases(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.ListAutonomousDatabasesRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_autonomous_database_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_autonomous_database), "__call__" + ) as call: + call.return_value = autonomous_database.AutonomousDatabase() + client.get_autonomous_database(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.GetAutonomousDatabaseRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_autonomous_database_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_autonomous_database), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_autonomous_database(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.CreateAutonomousDatabaseRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_autonomous_database_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_autonomous_database), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.update_autonomous_database(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.UpdateAutonomousDatabaseRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_autonomous_database_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_autonomous_database), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_autonomous_database(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.DeleteAutonomousDatabaseRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_restore_autonomous_database_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.restore_autonomous_database), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.restore_autonomous_database(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.RestoreAutonomousDatabaseRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_generate_autonomous_database_wallet_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.generate_autonomous_database_wallet), "__call__" + ) as call: + call.return_value = oracledatabase.GenerateAutonomousDatabaseWalletResponse() + client.generate_autonomous_database_wallet(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.GenerateAutonomousDatabaseWalletRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_autonomous_db_versions_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_autonomous_db_versions), "__call__" + ) as call: + call.return_value = oracledatabase.ListAutonomousDbVersionsResponse() + client.list_autonomous_db_versions(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.ListAutonomousDbVersionsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_autonomous_database_character_sets_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_autonomous_database_character_sets), "__call__" + ) as call: + call.return_value = oracledatabase.ListAutonomousDatabaseCharacterSetsResponse() + client.list_autonomous_database_character_sets(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.ListAutonomousDatabaseCharacterSetsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_autonomous_database_backups_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_autonomous_database_backups), "__call__" + ) as call: + call.return_value = oracledatabase.ListAutonomousDatabaseBackupsResponse() + client.list_autonomous_database_backups(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.ListAutonomousDatabaseBackupsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_stop_autonomous_database_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.stop_autonomous_database), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.stop_autonomous_database(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.StopAutonomousDatabaseRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_start_autonomous_database_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.start_autonomous_database), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.start_autonomous_database(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.StartAutonomousDatabaseRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_restart_autonomous_database_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.restart_autonomous_database), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.restart_autonomous_database(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.RestartAutonomousDatabaseRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_switchover_autonomous_database_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.switchover_autonomous_database), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.switchover_autonomous_database(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.SwitchoverAutonomousDatabaseRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_failover_autonomous_database_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.failover_autonomous_database), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.failover_autonomous_database(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.FailoverAutonomousDatabaseRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_odb_networks_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_odb_networks), "__call__" + ) as call: + call.return_value = odb_network.ListOdbNetworksResponse() + client.list_odb_networks(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = odb_network.ListOdbNetworksRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_odb_network_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_odb_network), "__call__") as call: + call.return_value = odb_network.OdbNetwork() + client.get_odb_network(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = odb_network.GetOdbNetworkRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_odb_network_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_odb_network), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_odb_network(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gco_odb_network.CreateOdbNetworkRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_odb_network_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_odb_network), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_odb_network(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = odb_network.DeleteOdbNetworkRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_odb_subnets_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_odb_subnets), "__call__") as call: + call.return_value = odb_subnet.ListOdbSubnetsResponse() + client.list_odb_subnets(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = odb_subnet.ListOdbSubnetsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_odb_subnet_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_odb_subnet), "__call__") as call: + call.return_value = odb_subnet.OdbSubnet() + client.get_odb_subnet(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = odb_subnet.GetOdbSubnetRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_odb_subnet_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_odb_subnet), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_odb_subnet(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gco_odb_subnet.CreateOdbSubnetRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_odb_subnet_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_odb_subnet), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_odb_subnet(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = odb_subnet.DeleteOdbSubnetRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_exadb_vm_clusters_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_exadb_vm_clusters), "__call__" + ) as call: + call.return_value = oracledatabase.ListExadbVmClustersResponse() + client.list_exadb_vm_clusters(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.ListExadbVmClustersRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_exadb_vm_cluster_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_exadb_vm_cluster), "__call__" + ) as call: + call.return_value = exadb_vm_cluster.ExadbVmCluster() + client.get_exadb_vm_cluster(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.GetExadbVmClusterRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_exadb_vm_cluster_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_exadb_vm_cluster), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_exadb_vm_cluster(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.CreateExadbVmClusterRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_exadb_vm_cluster_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_exadb_vm_cluster), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_exadb_vm_cluster(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.DeleteExadbVmClusterRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_exadb_vm_cluster_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_exadb_vm_cluster), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.update_exadb_vm_cluster(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.UpdateExadbVmClusterRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_remove_virtual_machine_exadb_vm_cluster_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.remove_virtual_machine_exadb_vm_cluster), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.remove_virtual_machine_exadb_vm_cluster(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.RemoveVirtualMachineExadbVmClusterRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_exascale_db_storage_vaults_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_exascale_db_storage_vaults), "__call__" + ) as call: + call.return_value = ( + exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse() + ) + client.list_exascale_db_storage_vaults(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = exascale_db_storage_vault.ListExascaleDbStorageVaultsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_exascale_db_storage_vault_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_exascale_db_storage_vault), "__call__" + ) as call: + call.return_value = exascale_db_storage_vault.ExascaleDbStorageVault() + client.get_exascale_db_storage_vault(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = exascale_db_storage_vault.GetExascaleDbStorageVaultRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_exascale_db_storage_vault_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_exascale_db_storage_vault), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_exascale_db_storage_vault(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ( + gco_exascale_db_storage_vault.CreateExascaleDbStorageVaultRequest() + ) + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_exascale_db_storage_vault_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_exascale_db_storage_vault), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_exascale_db_storage_vault(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = exascale_db_storage_vault.DeleteExascaleDbStorageVaultRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_db_system_initial_storage_sizes_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_db_system_initial_storage_sizes), "__call__" + ) as call: + call.return_value = ( + db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse() + ) + client.list_db_system_initial_storage_sizes(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ( + db_system_initial_storage_size.ListDbSystemInitialStorageSizesRequest() + ) + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_databases_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_databases), "__call__") as call: + call.return_value = database.ListDatabasesResponse() + client.list_databases(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = database.ListDatabasesRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_database_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_database), "__call__") as call: + call.return_value = database.Database() + client.get_database(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = database.GetDatabaseRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_pluggable_databases_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_pluggable_databases), "__call__" + ) as call: + call.return_value = pluggable_database.ListPluggableDatabasesResponse() + client.list_pluggable_databases(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = pluggable_database.ListPluggableDatabasesRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_pluggable_database_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_pluggable_database), "__call__" + ) as call: + call.return_value = pluggable_database.PluggableDatabase() + client.get_pluggable_database(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = pluggable_database.GetPluggableDatabaseRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_db_systems_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_db_systems), "__call__") as call: + call.return_value = db_system.ListDbSystemsResponse() + client.list_db_systems(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = db_system.ListDbSystemsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_db_system_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_db_system), "__call__") as call: + call.return_value = db_system.DbSystem() + client.get_db_system(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = db_system.GetDbSystemRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_db_system_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_db_system), "__call__") as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_db_system(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gco_db_system.CreateDbSystemRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_db_system_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_db_system), "__call__") as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_db_system(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = db_system.DeleteDbSystemRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_goldengate_deployments_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployments), "__call__" + ) as call: + call.return_value = goldengate_deployment.ListGoldengateDeploymentsResponse() + client.list_goldengate_deployments(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment.ListGoldengateDeploymentsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_goldengate_deployment_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment), "__call__" + ) as call: + call.return_value = goldengate_deployment.GoldengateDeployment() + client.get_goldengate_deployment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment.GetGoldengateDeploymentRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_goldengate_deployment_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_goldengate_deployment), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_goldengate_deployment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gco_goldengate_deployment.CreateGoldengateDeploymentRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_goldengate_deployment_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_goldengate_deployment), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_goldengate_deployment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment.DeleteGoldengateDeploymentRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_stop_goldengate_deployment_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.stop_goldengate_deployment), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.stop_goldengate_deployment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment.StopGoldengateDeploymentRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_start_goldengate_deployment_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.start_goldengate_deployment), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.start_goldengate_deployment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment.StartGoldengateDeploymentRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_goldengate_connections_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connections), "__call__" + ) as call: + call.return_value = goldengate_connection.ListGoldengateConnectionsResponse() + client.list_goldengate_connections(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_connection.ListGoldengateConnectionsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_goldengate_connection_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_connection), "__call__" + ) as call: + call.return_value = goldengate_connection.GoldengateConnection() + client.get_goldengate_connection(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_connection.GetGoldengateConnectionRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_goldengate_connection_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_goldengate_connection), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_goldengate_connection(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gco_goldengate_connection.CreateGoldengateConnectionRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_goldengate_connection_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_goldengate_connection), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_goldengate_connection(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_connection.DeleteGoldengateConnectionRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_goldengate_deployment_version_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment_version), "__call__" + ) as call: + call.return_value = goldengate_deployment_version.GoldengateDeploymentVersion() + client.get_goldengate_deployment_version(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ( + goldengate_deployment_version.GetGoldengateDeploymentVersionRequest() + ) + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_goldengate_deployment_versions_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_versions), "__call__" + ) as call: + call.return_value = ( + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse() + ) + client.list_goldengate_deployment_versions(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ( + goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest() + ) + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_goldengate_deployment_type_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment_type), "__call__" + ) as call: + call.return_value = goldengate_deployment_type.GoldengateDeploymentType() + client.get_goldengate_deployment_type(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment_type.GetGoldengateDeploymentTypeRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_goldengate_deployment_types_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_types), "__call__" + ) as call: + call.return_value = ( + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse() + ) + client.list_goldengate_deployment_types(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment_type.ListGoldengateDeploymentTypesRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_goldengate_deployment_environment_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment_environment), "__call__" + ) as call: + call.return_value = ( + goldengate_deployment_environment.GoldengateDeploymentEnvironment() + ) + client.get_goldengate_deployment_environment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_goldengate_deployment_environments_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_environments), "__call__" + ) as call: + call.return_value = goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse() + client.list_goldengate_deployment_environments(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_goldengate_connection_type_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_connection_type), "__call__" + ) as call: + call.return_value = goldengate_connection_type.GoldengateConnectionType() + client.get_goldengate_connection_type(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_connection_type.GetGoldengateConnectionTypeRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_goldengate_connection_types_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connection_types), "__call__" + ) as call: + call.return_value = ( + goldengate_connection_type.ListGoldengateConnectionTypesResponse() + ) + client.list_goldengate_connection_types(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_connection_type.ListGoldengateConnectionTypesRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_db_versions_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_db_versions), "__call__") as call: + call.return_value = db_version.ListDbVersionsResponse() + client.list_db_versions(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = db_version.ListDbVersionsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_database_character_sets_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_database_character_sets), "__call__" + ) as call: + call.return_value = database_character_set.ListDatabaseCharacterSetsResponse() + client.list_database_character_sets(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = database_character_set.ListDatabaseCharacterSetsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_goldengate_connection_assignments_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connection_assignments), "__call__" + ) as call: + call.return_value = goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse() + client.list_goldengate_connection_assignments(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_goldengate_connection_assignment_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_connection_assignment), "__call__" + ) as call: + call.return_value = ( + goldengate_connection_assignment.GoldengateConnectionAssignment() + ) + client.get_goldengate_connection_assignment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ( + goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest() + ) + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_goldengate_connection_assignment_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_goldengate_connection_assignment), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_goldengate_connection_assignment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_goldengate_connection_assignment_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_goldengate_connection_assignment), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_goldengate_connection_assignment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_test_goldengate_connection_assignment_empty_call_grpc(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.test_goldengate_connection_assignment), "__call__" + ) as call: + call.return_value = goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse() + client.test_goldengate_connection_assignment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ( + goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest() + ) + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = OracleDatabaseAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_cloud_exadata_infrastructures_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_cloud_exadata_infrastructures), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + oracledatabase.ListCloudExadataInfrastructuresResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + await client.list_cloud_exadata_infrastructures(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.ListCloudExadataInfrastructuresRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_cloud_exadata_infrastructure_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_cloud_exadata_infrastructure), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + exadata_infra.CloudExadataInfrastructure( + name="name_value", + display_name="display_name_value", + gcp_oracle_zone="gcp_oracle_zone_value", + entitlement_id="entitlement_id_value", + ) + ) + await client.get_cloud_exadata_infrastructure(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.GetCloudExadataInfrastructureRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_cloud_exadata_infrastructure_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_cloud_exadata_infrastructure), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.create_cloud_exadata_infrastructure(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.CreateCloudExadataInfrastructureRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_cloud_exadata_infrastructure_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_cloud_exadata_infrastructure), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.delete_cloud_exadata_infrastructure(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.DeleteCloudExadataInfrastructureRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_cloud_vm_clusters_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_cloud_vm_clusters), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + oracledatabase.ListCloudVmClustersResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + await client.list_cloud_vm_clusters(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.ListCloudVmClustersRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_cloud_vm_cluster_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_cloud_vm_cluster), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + vm_cluster.CloudVmCluster( + name="name_value", + exadata_infrastructure="exadata_infrastructure_value", + display_name="display_name_value", + cidr="cidr_value", + backup_subnet_cidr="backup_subnet_cidr_value", + network="network_value", + gcp_oracle_zone="gcp_oracle_zone_value", + odb_network="odb_network_value", + odb_subnet="odb_subnet_value", + backup_odb_subnet="backup_odb_subnet_value", + ) + ) + await client.get_cloud_vm_cluster(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.GetCloudVmClusterRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_cloud_vm_cluster_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_cloud_vm_cluster), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.create_cloud_vm_cluster(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.CreateCloudVmClusterRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_cloud_vm_cluster_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_cloud_vm_cluster), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.delete_cloud_vm_cluster(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.DeleteCloudVmClusterRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_entitlements_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_entitlements), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + oracledatabase.ListEntitlementsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_entitlements(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.ListEntitlementsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_db_servers_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_db_servers), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + oracledatabase.ListDbServersResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_db_servers(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.ListDbServersRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_db_nodes_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_db_nodes), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + oracledatabase.ListDbNodesResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_db_nodes(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.ListDbNodesRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_gi_versions_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_gi_versions), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + oracledatabase.ListGiVersionsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_gi_versions(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.ListGiVersionsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_minor_versions_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_minor_versions), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + minor_version.ListMinorVersionsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_minor_versions(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = minor_version.ListMinorVersionsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_db_system_shapes_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_db_system_shapes), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + oracledatabase.ListDbSystemShapesResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_db_system_shapes(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.ListDbSystemShapesRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_autonomous_databases_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_autonomous_databases), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + oracledatabase.ListAutonomousDatabasesResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + await client.list_autonomous_databases(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.ListAutonomousDatabasesRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_autonomous_database_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_autonomous_database), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + autonomous_database.AutonomousDatabase( + name="name_value", + database="database_value", + display_name="display_name_value", + entitlement_id="entitlement_id_value", + admin_password="admin_password_value", + admin_password_secret_version="admin_password_secret_version_value", + network="network_value", + cidr="cidr_value", + odb_network="odb_network_value", + odb_subnet="odb_subnet_value", + peer_autonomous_databases=["peer_autonomous_databases_value"], + disaster_recovery_supported_locations=[ + "disaster_recovery_supported_locations_value" + ], + ) + ) + await client.get_autonomous_database(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.GetAutonomousDatabaseRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_autonomous_database_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_autonomous_database), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.create_autonomous_database(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.CreateAutonomousDatabaseRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_autonomous_database_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_autonomous_database), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.update_autonomous_database(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.UpdateAutonomousDatabaseRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_autonomous_database_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_autonomous_database), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.delete_autonomous_database(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.DeleteAutonomousDatabaseRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_restore_autonomous_database_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.restore_autonomous_database), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.restore_autonomous_database(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.RestoreAutonomousDatabaseRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_generate_autonomous_database_wallet_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.generate_autonomous_database_wallet), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + oracledatabase.GenerateAutonomousDatabaseWalletResponse( + archive_content=b"archive_content_blob", + ) + ) + await client.generate_autonomous_database_wallet(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.GenerateAutonomousDatabaseWalletRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_autonomous_db_versions_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_autonomous_db_versions), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + oracledatabase.ListAutonomousDbVersionsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_autonomous_db_versions(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.ListAutonomousDbVersionsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_autonomous_database_character_sets_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_autonomous_database_character_sets), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + oracledatabase.ListAutonomousDatabaseCharacterSetsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_autonomous_database_character_sets(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.ListAutonomousDatabaseCharacterSetsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_autonomous_database_backups_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_autonomous_database_backups), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + oracledatabase.ListAutonomousDatabaseBackupsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_autonomous_database_backups(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.ListAutonomousDatabaseBackupsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_stop_autonomous_database_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.stop_autonomous_database), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.stop_autonomous_database(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.StopAutonomousDatabaseRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_start_autonomous_database_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.start_autonomous_database), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.start_autonomous_database(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.StartAutonomousDatabaseRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_restart_autonomous_database_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.restart_autonomous_database), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.restart_autonomous_database(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.RestartAutonomousDatabaseRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_switchover_autonomous_database_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.switchover_autonomous_database), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.switchover_autonomous_database(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.SwitchoverAutonomousDatabaseRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_failover_autonomous_database_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.failover_autonomous_database), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.failover_autonomous_database(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.FailoverAutonomousDatabaseRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_odb_networks_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_odb_networks), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + odb_network.ListOdbNetworksResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + await client.list_odb_networks(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = odb_network.ListOdbNetworksRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_odb_network_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_odb_network), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + odb_network.OdbNetwork( + name="name_value", + network="network_value", + state=odb_network.OdbNetwork.State.PROVISIONING, + entitlement_id="entitlement_id_value", + gcp_oracle_zone="gcp_oracle_zone_value", + ) + ) + await client.get_odb_network(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = odb_network.GetOdbNetworkRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_odb_network_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_odb_network), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.create_odb_network(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gco_odb_network.CreateOdbNetworkRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_odb_network_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_odb_network), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.delete_odb_network(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = odb_network.DeleteOdbNetworkRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_odb_subnets_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_odb_subnets), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + odb_subnet.ListOdbSubnetsResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + await client.list_odb_subnets(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = odb_subnet.ListOdbSubnetsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_odb_subnet_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_odb_subnet), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + odb_subnet.OdbSubnet( + name="name_value", + cidr_range="cidr_range_value", + purpose=odb_subnet.OdbSubnet.Purpose.CLIENT_SUBNET, + state=odb_subnet.OdbSubnet.State.PROVISIONING, + ) + ) + await client.get_odb_subnet(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = odb_subnet.GetOdbSubnetRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_odb_subnet_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_odb_subnet), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.create_odb_subnet(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gco_odb_subnet.CreateOdbSubnetRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_odb_subnet_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_odb_subnet), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.delete_odb_subnet(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = odb_subnet.DeleteOdbSubnetRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_exadb_vm_clusters_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_exadb_vm_clusters), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + oracledatabase.ListExadbVmClustersResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + await client.list_exadb_vm_clusters(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.ListExadbVmClustersRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_exadb_vm_cluster_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_exadb_vm_cluster), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + exadb_vm_cluster.ExadbVmCluster( + name="name_value", + gcp_oracle_zone="gcp_oracle_zone_value", + odb_network="odb_network_value", + odb_subnet="odb_subnet_value", + backup_odb_subnet="backup_odb_subnet_value", + display_name="display_name_value", + entitlement_id="entitlement_id_value", + ) + ) + await client.get_exadb_vm_cluster(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.GetExadbVmClusterRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_exadb_vm_cluster_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_exadb_vm_cluster), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.create_exadb_vm_cluster(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.CreateExadbVmClusterRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_exadb_vm_cluster_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_exadb_vm_cluster), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.delete_exadb_vm_cluster(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.DeleteExadbVmClusterRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_exadb_vm_cluster_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_exadb_vm_cluster), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.update_exadb_vm_cluster(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.UpdateExadbVmClusterRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_remove_virtual_machine_exadb_vm_cluster_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.remove_virtual_machine_exadb_vm_cluster), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.remove_virtual_machine_exadb_vm_cluster(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = oracledatabase.RemoveVirtualMachineExadbVmClusterRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_exascale_db_storage_vaults_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_exascale_db_storage_vaults), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + await client.list_exascale_db_storage_vaults(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = exascale_db_storage_vault.ListExascaleDbStorageVaultsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_exascale_db_storage_vault_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_exascale_db_storage_vault), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + exascale_db_storage_vault.ExascaleDbStorageVault( + name="name_value", + display_name="display_name_value", + gcp_oracle_zone="gcp_oracle_zone_value", + entitlement_id="entitlement_id_value", + ) + ) + await client.get_exascale_db_storage_vault(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = exascale_db_storage_vault.GetExascaleDbStorageVaultRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_exascale_db_storage_vault_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_exascale_db_storage_vault), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.create_exascale_db_storage_vault(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ( + gco_exascale_db_storage_vault.CreateExascaleDbStorageVaultRequest() + ) + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_exascale_db_storage_vault_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_exascale_db_storage_vault), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.delete_exascale_db_storage_vault(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = exascale_db_storage_vault.DeleteExascaleDbStorageVaultRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_db_system_initial_storage_sizes_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_db_system_initial_storage_sizes), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_db_system_initial_storage_sizes(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ( + db_system_initial_storage_size.ListDbSystemInitialStorageSizesRequest() + ) + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_databases_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_databases), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + database.ListDatabasesResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_databases(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = database.ListDatabasesRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_database_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_database), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + database.Database( + name="name_value", + db_name="db_name_value", + db_unique_name="db_unique_name_value", + admin_password="admin_password_value", + admin_password_secret_version="admin_password_secret_version_value", + tde_wallet_password="tde_wallet_password_value", + tde_wallet_password_secret_version="tde_wallet_password_secret_version_value", + character_set="character_set_value", + ncharacter_set="ncharacter_set_value", + oci_url="oci_url_value", + database_id="database_id_value", + db_home_name="db_home_name_value", + gcp_oracle_zone="gcp_oracle_zone_value", + ops_insights_status=database.Database.OperationsInsightsStatus.ENABLING, + pluggable_database_id="pluggable_database_id_value", + pluggable_database_name="pluggable_database_name_value", + ) + ) + await client.get_database(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = database.GetDatabaseRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_pluggable_databases_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_pluggable_databases), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + pluggable_database.ListPluggableDatabasesResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_pluggable_databases(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = pluggable_database.ListPluggableDatabasesRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_pluggable_database_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_pluggable_database), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + pluggable_database.PluggableDatabase( + name="name_value", + oci_url="oci_url_value", + ) + ) + await client.get_pluggable_database(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = pluggable_database.GetPluggableDatabaseRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_db_systems_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_db_systems), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + db_system.ListDbSystemsResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + await client.list_db_systems(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = db_system.ListDbSystemsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_db_system_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_db_system), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + db_system.DbSystem( + name="name_value", + gcp_oracle_zone="gcp_oracle_zone_value", + odb_network="odb_network_value", + odb_subnet="odb_subnet_value", + entitlement_id="entitlement_id_value", + display_name="display_name_value", + oci_url="oci_url_value", + ) + ) + await client.get_db_system(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = db_system.GetDbSystemRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_db_system_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_db_system), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.create_db_system(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gco_db_system.CreateDbSystemRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_db_system_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_db_system), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.delete_db_system(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = db_system.DeleteDbSystemRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_goldengate_deployments_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployments), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_deployment.ListGoldengateDeploymentsResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + await client.list_goldengate_deployments(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment.ListGoldengateDeploymentsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_goldengate_deployment_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_deployment.GoldengateDeployment( + name="name_value", + gcp_oracle_zone="gcp_oracle_zone_value", + odb_network="odb_network_value", + odb_subnet="odb_subnet_value", + entitlement_id="entitlement_id_value", + display_name="display_name_value", + oci_url="oci_url_value", + ) + ) + await client.get_goldengate_deployment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment.GetGoldengateDeploymentRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_goldengate_deployment_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_goldengate_deployment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.create_goldengate_deployment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gco_goldengate_deployment.CreateGoldengateDeploymentRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_goldengate_deployment_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_goldengate_deployment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.delete_goldengate_deployment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment.DeleteGoldengateDeploymentRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_stop_goldengate_deployment_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.stop_goldengate_deployment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.stop_goldengate_deployment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment.StopGoldengateDeploymentRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_start_goldengate_deployment_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.start_goldengate_deployment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.start_goldengate_deployment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment.StartGoldengateDeploymentRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_goldengate_connections_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connections), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_connection.ListGoldengateConnectionsResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + await client.list_goldengate_connections(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_connection.ListGoldengateConnectionsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_goldengate_connection_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_connection), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_connection.GoldengateConnection( + name="name_value", + gcp_oracle_zone="gcp_oracle_zone_value", + odb_network="odb_network_value", + odb_subnet="odb_subnet_value", + entitlement_id="entitlement_id_value", + oci_url="oci_url_value", + ) + ) + await client.get_goldengate_connection(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_connection.GetGoldengateConnectionRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_goldengate_connection_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_goldengate_connection), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.create_goldengate_connection(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gco_goldengate_connection.CreateGoldengateConnectionRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_goldengate_connection_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_goldengate_connection), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.delete_goldengate_connection(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_connection.DeleteGoldengateConnectionRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_goldengate_deployment_version_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment_version), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_deployment_version.GoldengateDeploymentVersion( + name="name_value", + ocid="ocid_value", + ) + ) + await client.get_goldengate_deployment_version(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ( + goldengate_deployment_version.GetGoldengateDeploymentVersionRequest() + ) + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_goldengate_deployment_versions_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_versions), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + await client.list_goldengate_deployment_versions(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ( + goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest() + ) + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_goldengate_deployment_type_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment_type), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_deployment_type.GoldengateDeploymentType( + name="name_value", + deployment_type=goldengate_deployment_type.GoldengateDeploymentType.DeploymentType.OGG, + category=goldengate_deployment_type.GoldengateDeploymentType.DeploymentCategory.DATA_REPLICATION_CATEGORY, + connection_types=["connection_types_value"], + display_name="display_name_value", + ogg_version="ogg_version_value", + source_technologies=["source_technologies_value"], + supported_capabilities=["supported_capabilities_value"], + supported_technologies_url="supported_technologies_url_value", + target_technologies=["target_technologies_value"], + default_username="default_username_value", + ) + ) + await client.get_goldengate_deployment_type(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment_type.GetGoldengateDeploymentTypeRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_goldengate_deployment_types_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_types), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + await client.list_goldengate_deployment_types(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment_type.ListGoldengateDeploymentTypesRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_goldengate_deployment_environment_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment_environment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_deployment_environment.GoldengateDeploymentEnvironment( + name="name_value", + category=goldengate_deployment_environment.GoldengateDeploymentEnvironment.DeploymentCategory.DATA_REPLICATION_CATEGORY, + display_name="display_name_value", + default_cpu_core_count=2332, + environment_type=goldengate_deployment_environment.GoldengateDeploymentEnvironment.DeploymentEnvironmentType.PRODUCTION, + auto_scaling_enabled=True, + max_cpu_core_count=1917, + memory_gb_per_cpu_core=2326, + min_cpu_core_count=1915, + network_bandwidth_gbps_per_cpu_core=3710, + storage_usage_limit_gb_per_cpu_core=3684, + ) + ) + await client.get_goldengate_deployment_environment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_goldengate_deployment_environments_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_environments), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + await client.list_goldengate_deployment_environments(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_goldengate_connection_type_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_connection_type), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_connection_type.GoldengateConnectionType( + name="name_value", + connection_type=goldengate_connection_type.GoldengateConnectionType.ConnectionType.GOLDENGATE, + technology_types=["technology_types_value"], + ) + ) + await client.get_goldengate_connection_type(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_connection_type.GetGoldengateConnectionTypeRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_goldengate_connection_types_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connection_types), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_connection_type.ListGoldengateConnectionTypesResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + await client.list_goldengate_connection_types(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_connection_type.ListGoldengateConnectionTypesRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_db_versions_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_db_versions), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + db_version.ListDbVersionsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_db_versions(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = db_version.ListDbVersionsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_database_character_sets_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_database_character_sets), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + database_character_set.ListDatabaseCharacterSetsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_database_character_sets(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = database_character_set.ListDatabaseCharacterSetsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_goldengate_connection_assignments_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connection_assignments), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + await client.list_goldengate_connection_assignments(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_goldengate_connection_assignment_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_connection_assignment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_connection_assignment.GoldengateConnectionAssignment( + name="name_value", + display_name="display_name_value", + entitlement_id="entitlement_id_value", + ) + ) + await client.get_goldengate_connection_assignment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ( + goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest() + ) + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_goldengate_connection_assignment_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_goldengate_connection_assignment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.create_goldengate_connection_assignment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_goldengate_connection_assignment_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_goldengate_connection_assignment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.delete_goldengate_connection_assignment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_test_goldengate_connection_assignment_empty_call_grpc_asyncio(): + client = OracleDatabaseAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.test_goldengate_connection_assignment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse( + result_type=goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse.ResultType.SUCCEEDED, + ) + ) + await client.test_goldengate_connection_assignment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ( + goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest() + ) + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = OracleDatabaseClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_list_cloud_exadata_infrastructures_rest_bad_request( + request_type=oracledatabase.ListCloudExadataInfrastructuresRequest, +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_cloud_exadata_infrastructures(request) + + +@pytest.mark.parametrize( + "request_type", + [ + oracledatabase.ListCloudExadataInfrastructuresRequest, + dict, + ], +) +def test_list_cloud_exadata_infrastructures_rest_call_success(request_type): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = oracledatabase.ListCloudExadataInfrastructuresResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = oracledatabase.ListCloudExadataInfrastructuresResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_cloud_exadata_infrastructures(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListCloudExadataInfrastructuresPager) + assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_cloud_exadata_infrastructures_rest_interceptors(null_interceptor): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.OracleDatabaseRestInterceptor(), + ) + client = OracleDatabaseClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_list_cloud_exadata_infrastructures", + ) as post, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_list_cloud_exadata_infrastructures_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "pre_list_cloud_exadata_infrastructures", + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = oracledatabase.ListCloudExadataInfrastructuresRequest.pb( + oracledatabase.ListCloudExadataInfrastructuresRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = oracledatabase.ListCloudExadataInfrastructuresResponse.to_json( + oracledatabase.ListCloudExadataInfrastructuresResponse() + ) + req.return_value.content = return_value + + request = oracledatabase.ListCloudExadataInfrastructuresRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = oracledatabase.ListCloudExadataInfrastructuresResponse() + post_with_metadata.return_value = ( + oracledatabase.ListCloudExadataInfrastructuresResponse(), + metadata, + ) + + client.list_cloud_exadata_infrastructures( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_cloud_exadata_infrastructure_rest_bad_request( + request_type=oracledatabase.GetCloudExadataInfrastructureRequest, +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/cloudExadataInfrastructures/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_cloud_exadata_infrastructure(request) + + +@pytest.mark.parametrize( + "request_type", + [ + oracledatabase.GetCloudExadataInfrastructureRequest, + dict, + ], +) +def test_get_cloud_exadata_infrastructure_rest_call_success(request_type): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/cloudExadataInfrastructures/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = exadata_infra.CloudExadataInfrastructure( + name="name_value", + display_name="display_name_value", + gcp_oracle_zone="gcp_oracle_zone_value", + entitlement_id="entitlement_id_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = exadata_infra.CloudExadataInfrastructure.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_cloud_exadata_infrastructure(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, exadata_infra.CloudExadataInfrastructure) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.gcp_oracle_zone == "gcp_oracle_zone_value" + assert response.entitlement_id == "entitlement_id_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_cloud_exadata_infrastructure_rest_interceptors(null_interceptor): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.OracleDatabaseRestInterceptor(), + ) + client = OracleDatabaseClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_get_cloud_exadata_infrastructure", + ) as post, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_get_cloud_exadata_infrastructure_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "pre_get_cloud_exadata_infrastructure", + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = oracledatabase.GetCloudExadataInfrastructureRequest.pb( + oracledatabase.GetCloudExadataInfrastructureRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = exadata_infra.CloudExadataInfrastructure.to_json( + exadata_infra.CloudExadataInfrastructure() + ) + req.return_value.content = return_value + + request = oracledatabase.GetCloudExadataInfrastructureRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = exadata_infra.CloudExadataInfrastructure() + post_with_metadata.return_value = ( + exadata_infra.CloudExadataInfrastructure(), + metadata, + ) + + client.get_cloud_exadata_infrastructure( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_create_cloud_exadata_infrastructure_rest_bad_request( + request_type=oracledatabase.CreateCloudExadataInfrastructureRequest, +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.create_cloud_exadata_infrastructure(request) + + +@pytest.mark.parametrize( + "request_type", + [ + oracledatabase.CreateCloudExadataInfrastructureRequest, + dict, + ], +) +def test_create_cloud_exadata_infrastructure_rest_call_success(request_type): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request_init["cloud_exadata_infrastructure"] = { + "name": "name_value", + "display_name": "display_name_value", + "gcp_oracle_zone": "gcp_oracle_zone_value", + "entitlement_id": "entitlement_id_value", + "properties": { + "ocid": "ocid_value", + "compute_count": 1413, + "storage_count": 1405, + "total_storage_size_gb": 2234, + "available_storage_size_gb": 2615, + "maintenance_window": { + "preference": 1, + "months": [1], + "weeks_of_month": [1497, 1498], + "days_of_week": [1], + "hours_of_day": [1283, 1284], + "lead_time_week": 1455, + "patching_mode": 1, + "custom_action_timeout_mins": 2804, + "is_custom_action_timeout_enabled": True, + }, + "state": 1, + "shape": "shape_value", + "oci_url": "oci_url_value", + "cpu_count": 976, + "max_cpu_count": 1397, + "memory_size_gb": 1499, + "max_memory_gb": 1382, + "db_node_storage_size_gb": 2401, + "max_db_node_storage_size_gb": 2822, + "data_storage_size_tb": 0.2109, + "max_data_storage_tb": 0.19920000000000002, + "activated_storage_count": 2449, + "additional_storage_count": 2549, + "db_server_version": "db_server_version_value", + "storage_server_version": "storage_server_version_value", + "next_maintenance_run_id": "next_maintenance_run_id_value", + "next_maintenance_run_time": {"seconds": 751, "nanos": 543}, + "next_security_maintenance_run_time": {}, + "customer_contacts": [{"email": "email_value"}], + "monthly_storage_server_version": "monthly_storage_server_version_value", + "monthly_db_server_version": "monthly_db_server_version_value", + "compute_model": 1, + "database_server_type": "database_server_type_value", + "storage_server_type": "storage_server_type_value", + }, + "labels": {}, + "create_time": {}, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = oracledatabase.CreateCloudExadataInfrastructureRequest.meta.fields[ + "cloud_exadata_infrastructure" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init[ + "cloud_exadata_infrastructure" + ].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range( + 0, len(request_init["cloud_exadata_infrastructure"][field]) + ): + del request_init["cloud_exadata_infrastructure"][field][i][subfield] + else: + del request_init["cloud_exadata_infrastructure"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.create_cloud_exadata_infrastructure(request) + + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_cloud_exadata_infrastructure_rest_interceptors(null_interceptor): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.OracleDatabaseRestInterceptor(), + ) + client = OracleDatabaseClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_create_cloud_exadata_infrastructure", + ) as post, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_create_cloud_exadata_infrastructure_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "pre_create_cloud_exadata_infrastructure", + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = oracledatabase.CreateCloudExadataInfrastructureRequest.pb( + oracledatabase.CreateCloudExadataInfrastructureRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value + + request = oracledatabase.CreateCloudExadataInfrastructureRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata + + client.create_cloud_exadata_infrastructure( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_delete_cloud_exadata_infrastructure_rest_bad_request( + request_type=oracledatabase.DeleteCloudExadataInfrastructureRequest, +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/cloudExadataInfrastructures/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.delete_cloud_exadata_infrastructure(request) + + +@pytest.mark.parametrize( + "request_type", + [ + oracledatabase.DeleteCloudExadataInfrastructureRequest, + dict, + ], +) +def test_delete_cloud_exadata_infrastructure_rest_call_success(request_type): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/cloudExadataInfrastructures/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.delete_cloud_exadata_infrastructure(request) + + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_cloud_exadata_infrastructure_rest_interceptors(null_interceptor): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.OracleDatabaseRestInterceptor(), + ) + client = OracleDatabaseClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_delete_cloud_exadata_infrastructure", + ) as post, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_delete_cloud_exadata_infrastructure_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "pre_delete_cloud_exadata_infrastructure", + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = oracledatabase.DeleteCloudExadataInfrastructureRequest.pb( + oracledatabase.DeleteCloudExadataInfrastructureRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value + + request = oracledatabase.DeleteCloudExadataInfrastructureRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata + + client.delete_cloud_exadata_infrastructure( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_cloud_vm_clusters_rest_bad_request( + request_type=oracledatabase.ListCloudVmClustersRequest, +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_cloud_vm_clusters(request) + + +@pytest.mark.parametrize( + "request_type", + [ + oracledatabase.ListCloudVmClustersRequest, + dict, + ], +) +def test_list_cloud_vm_clusters_rest_call_success(request_type): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = oracledatabase.ListCloudVmClustersResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = oracledatabase.ListCloudVmClustersResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_cloud_vm_clusters(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListCloudVmClustersPager) + assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_cloud_vm_clusters_rest_interceptors(null_interceptor): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.OracleDatabaseRestInterceptor(), + ) + client = OracleDatabaseClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "post_list_cloud_vm_clusters" + ) as post, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_list_cloud_vm_clusters_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "pre_list_cloud_vm_clusters" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = oracledatabase.ListCloudVmClustersRequest.pb( + oracledatabase.ListCloudVmClustersRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = oracledatabase.ListCloudVmClustersResponse.to_json( + oracledatabase.ListCloudVmClustersResponse() + ) + req.return_value.content = return_value + + request = oracledatabase.ListCloudVmClustersRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = oracledatabase.ListCloudVmClustersResponse() + post_with_metadata.return_value = ( + oracledatabase.ListCloudVmClustersResponse(), + metadata, + ) + + client.list_cloud_vm_clusters( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_cloud_vm_cluster_rest_bad_request( + request_type=oracledatabase.GetCloudVmClusterRequest, +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/cloudVmClusters/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_cloud_vm_cluster(request) + + +@pytest.mark.parametrize( + "request_type", + [ + oracledatabase.GetCloudVmClusterRequest, + dict, + ], +) +def test_get_cloud_vm_cluster_rest_call_success(request_type): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/cloudVmClusters/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = vm_cluster.CloudVmCluster( + name="name_value", + exadata_infrastructure="exadata_infrastructure_value", + display_name="display_name_value", + cidr="cidr_value", + backup_subnet_cidr="backup_subnet_cidr_value", + network="network_value", + gcp_oracle_zone="gcp_oracle_zone_value", + odb_network="odb_network_value", + odb_subnet="odb_subnet_value", + backup_odb_subnet="backup_odb_subnet_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = vm_cluster.CloudVmCluster.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_cloud_vm_cluster(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, vm_cluster.CloudVmCluster) + assert response.name == "name_value" + assert response.exadata_infrastructure == "exadata_infrastructure_value" + assert response.display_name == "display_name_value" + assert response.cidr == "cidr_value" + assert response.backup_subnet_cidr == "backup_subnet_cidr_value" + assert response.network == "network_value" + assert response.gcp_oracle_zone == "gcp_oracle_zone_value" + assert response.odb_network == "odb_network_value" + assert response.odb_subnet == "odb_subnet_value" + assert response.backup_odb_subnet == "backup_odb_subnet_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_cloud_vm_cluster_rest_interceptors(null_interceptor): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.OracleDatabaseRestInterceptor(), + ) + client = OracleDatabaseClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "post_get_cloud_vm_cluster" + ) as post, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_get_cloud_vm_cluster_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "pre_get_cloud_vm_cluster" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = oracledatabase.GetCloudVmClusterRequest.pb( + oracledatabase.GetCloudVmClusterRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = vm_cluster.CloudVmCluster.to_json(vm_cluster.CloudVmCluster()) + req.return_value.content = return_value + + request = oracledatabase.GetCloudVmClusterRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = vm_cluster.CloudVmCluster() + post_with_metadata.return_value = vm_cluster.CloudVmCluster(), metadata + + client.get_cloud_vm_cluster( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_create_cloud_vm_cluster_rest_bad_request( + request_type=oracledatabase.CreateCloudVmClusterRequest, +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.create_cloud_vm_cluster(request) + + +@pytest.mark.parametrize( + "request_type", + [ + oracledatabase.CreateCloudVmClusterRequest, + dict, + ], +) +def test_create_cloud_vm_cluster_rest_call_success(request_type): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request_init["cloud_vm_cluster"] = { + "name": "name_value", + "exadata_infrastructure": "exadata_infrastructure_value", + "display_name": "display_name_value", + "properties": { + "ocid": "ocid_value", + "license_type": 1, + "gi_version": "gi_version_value", + "time_zone": {"id": "id_value", "version": "version_value"}, + "ssh_public_keys": ["ssh_public_keys_value1", "ssh_public_keys_value2"], + "node_count": 1070, + "shape": "shape_value", + "ocpu_count": 0.1087, + "memory_size_gb": 1499, + "db_node_storage_size_gb": 2401, + "storage_size_gb": 1591, + "data_storage_size_tb": 0.2109, + "disk_redundancy": 1, + "sparse_diskgroup_enabled": True, + "local_backup_enabled": True, + "hostname_prefix": "hostname_prefix_value", + "diagnostics_data_collection_options": { + "diagnostics_events_enabled": True, + "health_monitoring_enabled": True, + "incident_logs_enabled": True, + }, + "state": 1, + "scan_listener_port_tcp": 2356, + "scan_listener_port_tcp_ssl": 2789, + "domain": "domain_value", + "scan_dns": "scan_dns_value", + "hostname": "hostname_value", + "cpu_core_count": 1496, + "system_version": "system_version_value", + "scan_ip_ids": ["scan_ip_ids_value1", "scan_ip_ids_value2"], + "scan_dns_record_id": "scan_dns_record_id_value", + "oci_url": "oci_url_value", + "db_server_ocids": ["db_server_ocids_value1", "db_server_ocids_value2"], + "compartment_id": "compartment_id_value", + "dns_listener_ip": "dns_listener_ip_value", + "cluster_name": "cluster_name_value", + "compute_model": 1, + }, + "labels": {}, + "create_time": {"seconds": 751, "nanos": 543}, + "cidr": "cidr_value", + "backup_subnet_cidr": "backup_subnet_cidr_value", + "network": "network_value", + "gcp_oracle_zone": "gcp_oracle_zone_value", + "odb_network": "odb_network_value", + "odb_subnet": "odb_subnet_value", + "backup_odb_subnet": "backup_odb_subnet_value", + "identity_connector": { + "service_agent_email": "service_agent_email_value", + "connection_state": 1, + }, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = oracledatabase.CreateCloudVmClusterRequest.meta.fields[ + "cloud_vm_cluster" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["cloud_vm_cluster"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["cloud_vm_cluster"][field])): + del request_init["cloud_vm_cluster"][field][i][subfield] + else: + del request_init["cloud_vm_cluster"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.create_cloud_vm_cluster(request) + + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_cloud_vm_cluster_rest_interceptors(null_interceptor): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.OracleDatabaseRestInterceptor(), + ) + client = OracleDatabaseClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "post_create_cloud_vm_cluster" + ) as post, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_create_cloud_vm_cluster_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "pre_create_cloud_vm_cluster" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = oracledatabase.CreateCloudVmClusterRequest.pb( + oracledatabase.CreateCloudVmClusterRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value + + request = oracledatabase.CreateCloudVmClusterRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata + + client.create_cloud_vm_cluster( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_delete_cloud_vm_cluster_rest_bad_request( + request_type=oracledatabase.DeleteCloudVmClusterRequest, +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/cloudVmClusters/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.delete_cloud_vm_cluster(request) + + +@pytest.mark.parametrize( + "request_type", + [ + oracledatabase.DeleteCloudVmClusterRequest, + dict, + ], +) +def test_delete_cloud_vm_cluster_rest_call_success(request_type): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/cloudVmClusters/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.delete_cloud_vm_cluster(request) + + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_cloud_vm_cluster_rest_interceptors(null_interceptor): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.OracleDatabaseRestInterceptor(), + ) + client = OracleDatabaseClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "post_delete_cloud_vm_cluster" + ) as post, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_delete_cloud_vm_cluster_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "pre_delete_cloud_vm_cluster" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = oracledatabase.DeleteCloudVmClusterRequest.pb( + oracledatabase.DeleteCloudVmClusterRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value + + request = oracledatabase.DeleteCloudVmClusterRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata + + client.delete_cloud_vm_cluster( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_entitlements_rest_bad_request( + request_type=oracledatabase.ListEntitlementsRequest, +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_entitlements(request) + + +@pytest.mark.parametrize( + "request_type", + [ + oracledatabase.ListEntitlementsRequest, + dict, + ], +) +def test_list_entitlements_rest_call_success(request_type): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = oracledatabase.ListEntitlementsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = oracledatabase.ListEntitlementsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_entitlements(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListEntitlementsPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_entitlements_rest_interceptors(null_interceptor): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.OracleDatabaseRestInterceptor(), + ) + client = OracleDatabaseClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "post_list_entitlements" + ) as post, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_list_entitlements_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "pre_list_entitlements" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = oracledatabase.ListEntitlementsRequest.pb( + oracledatabase.ListEntitlementsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = oracledatabase.ListEntitlementsResponse.to_json( + oracledatabase.ListEntitlementsResponse() + ) + req.return_value.content = return_value + + request = oracledatabase.ListEntitlementsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = oracledatabase.ListEntitlementsResponse() + post_with_metadata.return_value = ( + oracledatabase.ListEntitlementsResponse(), + metadata, + ) + + client.list_entitlements( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_db_servers_rest_bad_request( + request_type=oracledatabase.ListDbServersRequest, +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "parent": "projects/sample1/locations/sample2/cloudExadataInfrastructures/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_db_servers(request) + + +@pytest.mark.parametrize( + "request_type", + [ + oracledatabase.ListDbServersRequest, + dict, + ], +) +def test_list_db_servers_rest_call_success(request_type): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "parent": "projects/sample1/locations/sample2/cloudExadataInfrastructures/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = oracledatabase.ListDbServersResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = oracledatabase.ListDbServersResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_db_servers(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListDbServersPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_db_servers_rest_interceptors(null_interceptor): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.OracleDatabaseRestInterceptor(), + ) + client = OracleDatabaseClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "post_list_db_servers" + ) as post, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_list_db_servers_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "pre_list_db_servers" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = oracledatabase.ListDbServersRequest.pb( + oracledatabase.ListDbServersRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = oracledatabase.ListDbServersResponse.to_json( + oracledatabase.ListDbServersResponse() + ) + req.return_value.content = return_value + + request = oracledatabase.ListDbServersRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = oracledatabase.ListDbServersResponse() + post_with_metadata.return_value = ( + oracledatabase.ListDbServersResponse(), + metadata, + ) + + client.list_db_servers( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_db_nodes_rest_bad_request(request_type=oracledatabase.ListDbNodesRequest): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "parent": "projects/sample1/locations/sample2/cloudVmClusters/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_db_nodes(request) + + +@pytest.mark.parametrize( + "request_type", + [ + oracledatabase.ListDbNodesRequest, + dict, + ], +) +def test_list_db_nodes_rest_call_success(request_type): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "parent": "projects/sample1/locations/sample2/cloudVmClusters/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = oracledatabase.ListDbNodesResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = oracledatabase.ListDbNodesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_db_nodes(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListDbNodesPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_db_nodes_rest_interceptors(null_interceptor): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.OracleDatabaseRestInterceptor(), + ) + client = OracleDatabaseClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "post_list_db_nodes" + ) as post, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "post_list_db_nodes_with_metadata" + ) as post_with_metadata, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "pre_list_db_nodes" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = oracledatabase.ListDbNodesRequest.pb( + oracledatabase.ListDbNodesRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = oracledatabase.ListDbNodesResponse.to_json( + oracledatabase.ListDbNodesResponse() + ) + req.return_value.content = return_value + + request = oracledatabase.ListDbNodesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = oracledatabase.ListDbNodesResponse() + post_with_metadata.return_value = oracledatabase.ListDbNodesResponse(), metadata + + client.list_db_nodes( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_gi_versions_rest_bad_request( + request_type=oracledatabase.ListGiVersionsRequest, +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_gi_versions(request) + + +@pytest.mark.parametrize( + "request_type", + [ + oracledatabase.ListGiVersionsRequest, + dict, + ], +) +def test_list_gi_versions_rest_call_success(request_type): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = oracledatabase.ListGiVersionsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = oracledatabase.ListGiVersionsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_gi_versions(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListGiVersionsPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_gi_versions_rest_interceptors(null_interceptor): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.OracleDatabaseRestInterceptor(), + ) + client = OracleDatabaseClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "post_list_gi_versions" + ) as post, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_list_gi_versions_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "pre_list_gi_versions" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = oracledatabase.ListGiVersionsRequest.pb( + oracledatabase.ListGiVersionsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = oracledatabase.ListGiVersionsResponse.to_json( + oracledatabase.ListGiVersionsResponse() + ) + req.return_value.content = return_value + + request = oracledatabase.ListGiVersionsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = oracledatabase.ListGiVersionsResponse() + post_with_metadata.return_value = ( + oracledatabase.ListGiVersionsResponse(), + metadata, + ) + + client.list_gi_versions( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_minor_versions_rest_bad_request( + request_type=minor_version.ListMinorVersionsRequest, +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2/giVersions/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_minor_versions(request) + + +@pytest.mark.parametrize( + "request_type", + [ + minor_version.ListMinorVersionsRequest, + dict, + ], +) +def test_list_minor_versions_rest_call_success(request_type): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2/giVersions/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = minor_version.ListMinorVersionsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = minor_version.ListMinorVersionsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_minor_versions(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListMinorVersionsPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_minor_versions_rest_interceptors(null_interceptor): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.OracleDatabaseRestInterceptor(), + ) + client = OracleDatabaseClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "post_list_minor_versions" + ) as post, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_list_minor_versions_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "pre_list_minor_versions" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = minor_version.ListMinorVersionsRequest.pb( + minor_version.ListMinorVersionsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = minor_version.ListMinorVersionsResponse.to_json( + minor_version.ListMinorVersionsResponse() + ) + req.return_value.content = return_value + + request = minor_version.ListMinorVersionsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = minor_version.ListMinorVersionsResponse() + post_with_metadata.return_value = ( + minor_version.ListMinorVersionsResponse(), + metadata, + ) + + client.list_minor_versions( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_db_system_shapes_rest_bad_request( + request_type=oracledatabase.ListDbSystemShapesRequest, +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_db_system_shapes(request) + + +@pytest.mark.parametrize( + "request_type", + [ + oracledatabase.ListDbSystemShapesRequest, + dict, + ], +) +def test_list_db_system_shapes_rest_call_success(request_type): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = oracledatabase.ListDbSystemShapesResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = oracledatabase.ListDbSystemShapesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_db_system_shapes(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListDbSystemShapesPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_db_system_shapes_rest_interceptors(null_interceptor): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.OracleDatabaseRestInterceptor(), + ) + client = OracleDatabaseClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "post_list_db_system_shapes" + ) as post, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_list_db_system_shapes_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "pre_list_db_system_shapes" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = oracledatabase.ListDbSystemShapesRequest.pb( + oracledatabase.ListDbSystemShapesRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = oracledatabase.ListDbSystemShapesResponse.to_json( + oracledatabase.ListDbSystemShapesResponse() + ) + req.return_value.content = return_value + + request = oracledatabase.ListDbSystemShapesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = oracledatabase.ListDbSystemShapesResponse() + post_with_metadata.return_value = ( + oracledatabase.ListDbSystemShapesResponse(), + metadata, + ) + + client.list_db_system_shapes( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_autonomous_databases_rest_bad_request( + request_type=oracledatabase.ListAutonomousDatabasesRequest, +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_autonomous_databases(request) + + +@pytest.mark.parametrize( + "request_type", + [ + oracledatabase.ListAutonomousDatabasesRequest, + dict, + ], +) +def test_list_autonomous_databases_rest_call_success(request_type): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = oracledatabase.ListAutonomousDatabasesResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = oracledatabase.ListAutonomousDatabasesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_autonomous_databases(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListAutonomousDatabasesPager) + assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_autonomous_databases_rest_interceptors(null_interceptor): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.OracleDatabaseRestInterceptor(), + ) + client = OracleDatabaseClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "post_list_autonomous_databases" + ) as post, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_list_autonomous_databases_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "pre_list_autonomous_databases" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = oracledatabase.ListAutonomousDatabasesRequest.pb( + oracledatabase.ListAutonomousDatabasesRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = oracledatabase.ListAutonomousDatabasesResponse.to_json( + oracledatabase.ListAutonomousDatabasesResponse() + ) + req.return_value.content = return_value + + request = oracledatabase.ListAutonomousDatabasesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = oracledatabase.ListAutonomousDatabasesResponse() + post_with_metadata.return_value = ( + oracledatabase.ListAutonomousDatabasesResponse(), + metadata, + ) + + client.list_autonomous_databases( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_autonomous_database_rest_bad_request( + request_type=oracledatabase.GetAutonomousDatabaseRequest, +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_autonomous_database(request) + + +@pytest.mark.parametrize( + "request_type", + [ + oracledatabase.GetAutonomousDatabaseRequest, + dict, + ], +) +def test_get_autonomous_database_rest_call_success(request_type): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = autonomous_database.AutonomousDatabase( + name="name_value", + database="database_value", + display_name="display_name_value", + entitlement_id="entitlement_id_value", + admin_password="admin_password_value", + admin_password_secret_version="admin_password_secret_version_value", + network="network_value", + cidr="cidr_value", + odb_network="odb_network_value", + odb_subnet="odb_subnet_value", + peer_autonomous_databases=["peer_autonomous_databases_value"], + disaster_recovery_supported_locations=[ + "disaster_recovery_supported_locations_value" + ], + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = autonomous_database.AutonomousDatabase.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_autonomous_database(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, autonomous_database.AutonomousDatabase) + assert response.name == "name_value" + assert response.database == "database_value" + assert response.display_name == "display_name_value" + assert response.entitlement_id == "entitlement_id_value" + assert response.admin_password == "admin_password_value" + assert ( + response.admin_password_secret_version == "admin_password_secret_version_value" + ) + assert response.network == "network_value" + assert response.cidr == "cidr_value" + assert response.odb_network == "odb_network_value" + assert response.odb_subnet == "odb_subnet_value" + assert response.peer_autonomous_databases == ["peer_autonomous_databases_value"] + assert response.disaster_recovery_supported_locations == [ + "disaster_recovery_supported_locations_value" + ] + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_autonomous_database_rest_interceptors(null_interceptor): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.OracleDatabaseRestInterceptor(), + ) + client = OracleDatabaseClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "post_get_autonomous_database" + ) as post, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_get_autonomous_database_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "pre_get_autonomous_database" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = oracledatabase.GetAutonomousDatabaseRequest.pb( + oracledatabase.GetAutonomousDatabaseRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = autonomous_database.AutonomousDatabase.to_json( + autonomous_database.AutonomousDatabase() + ) + req.return_value.content = return_value + + request = oracledatabase.GetAutonomousDatabaseRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = autonomous_database.AutonomousDatabase() + post_with_metadata.return_value = ( + autonomous_database.AutonomousDatabase(), + metadata, + ) + + client.get_autonomous_database( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_create_autonomous_database_rest_bad_request( + request_type=oracledatabase.CreateAutonomousDatabaseRequest, +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.create_autonomous_database(request) + + +@pytest.mark.parametrize( + "request_type", + [ + oracledatabase.CreateAutonomousDatabaseRequest, + dict, + ], +) +def test_create_autonomous_database_rest_call_success(request_type): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request_init["autonomous_database"] = { + "name": "name_value", + "database": "database_value", + "display_name": "display_name_value", + "entitlement_id": "entitlement_id_value", + "admin_password": "admin_password_value", + "admin_password_secret_version": "admin_password_secret_version_value", + "properties": { + "ocid": "ocid_value", + "compute_count": 0.1413, + "cpu_core_count": 1496, + "data_storage_size_tb": 2109, + "data_storage_size_gb": 2096, + "db_workload": 1, + "db_edition": 1, + "character_set": "character_set_value", + "n_character_set": "n_character_set_value", + "private_endpoint_ip": "private_endpoint_ip_value", + "private_endpoint_label": "private_endpoint_label_value", + "db_version": "db_version_value", + "is_auto_scaling_enabled": True, + "is_storage_auto_scaling_enabled": True, + "license_type": 1, + "customer_contacts": [{"email": "email_value"}], + "secret_id": "secret_id_value", + "vault_id": "vault_id_value", + "maintenance_schedule_type": 1, + "mtls_connection_required": True, + "backup_retention_period_days": 2975, + "actual_used_data_storage_size_tb": 0.3366, + "allocated_storage_size_tb": 0.2636, + "apex_details": { + "apex_version": "apex_version_value", + "ords_version": "ords_version_value", + }, + "are_primary_allowlisted_ips_used": True, + "lifecycle_details": "lifecycle_details_value", + "state": 1, + "autonomous_container_database_id": "autonomous_container_database_id_value", + "available_upgrade_versions": [ + "available_upgrade_versions_value1", + "available_upgrade_versions_value2", + ], + "connection_strings": { + "all_connection_strings": { + "high": "high_value", + "low": "low_value", + "medium": "medium_value", + }, + "dedicated": "dedicated_value", + "high": "high_value", + "low": "low_value", + "medium": "medium_value", + "profiles": [ + { + "consumer_group": 1, + "display_name": "display_name_value", + "host_format": 1, + "is_regional": True, + "protocol": 1, + "session_mode": 1, + "syntax_format": 1, + "tls_authentication": 1, + "value": "value_value", + } + ], + }, + "connection_urls": { + "apex_uri": "apex_uri_value", + "database_transforms_uri": "database_transforms_uri_value", + "graph_studio_uri": "graph_studio_uri_value", + "machine_learning_notebook_uri": "machine_learning_notebook_uri_value", + "machine_learning_user_management_uri": "machine_learning_user_management_uri_value", + "mongo_db_uri": "mongo_db_uri_value", + "ords_uri": "ords_uri_value", + "sql_dev_web_uri": "sql_dev_web_uri_value", + }, + "failed_data_recovery_duration": {"seconds": 751, "nanos": 543}, + "memory_table_gbs": 1691, + "is_local_data_guard_enabled": True, + "local_adg_auto_failover_max_data_loss_limit": 4513, + "local_standby_db": { + "lag_time_duration": {}, + "lifecycle_details": "lifecycle_details_value", + "state": 1, + "data_guard_role_changed_time": {"seconds": 751, "nanos": 543}, + "disaster_recovery_role_changed_time": {}, + }, + "memory_per_oracle_compute_unit_gbs": 3626, + "local_disaster_recovery_type": 1, + "data_safe_state": 1, + "database_management_state": 1, + "open_mode": 1, + "operations_insights_state": 1, + "peer_db_ids": ["peer_db_ids_value1", "peer_db_ids_value2"], + "permission_level": 1, + "private_endpoint": "private_endpoint_value", + "refreshable_mode": 1, + "refreshable_state": 1, + "role": 1, + "scheduled_operation_details": [ + { + "day_of_week": 1, + "start_time": { + "hours": 561, + "minutes": 773, + "seconds": 751, + "nanos": 543, + }, + "stop_time": {}, + } + ], + "sql_web_developer_url": "sql_web_developer_url_value", + "supported_clone_regions": [ + "supported_clone_regions_value1", + "supported_clone_regions_value2", + ], + "used_data_storage_size_tbs": 2752, + "oci_url": "oci_url_value", + "total_auto_backup_storage_size_gbs": 0.36100000000000004, + "next_long_term_backup_time": {}, + "data_guard_role_changed_time": {}, + "disaster_recovery_role_changed_time": {}, + "maintenance_begin_time": {}, + "maintenance_end_time": {}, + "allowlisted_ips": ["allowlisted_ips_value1", "allowlisted_ips_value2"], + "encryption_key": {"provider": 1, "kms_key": "kms_key_value"}, + "encryption_key_history_entries": [ + {"encryption_key": {}, "activation_time": {}} + ], + "service_agent_email": "service_agent_email_value", + "local_data_guard_enabled": True, + "local_adg_auto_failover_max_data_loss_limit_duration": 5478, + }, + "labels": {}, + "network": "network_value", + "cidr": "cidr_value", + "odb_network": "odb_network_value", + "odb_subnet": "odb_subnet_value", + "source_config": { + "autonomous_database": "autonomous_database_value", + "automatic_backups_replication_enabled": True, + }, + "peer_autonomous_databases": [ + "peer_autonomous_databases_value1", + "peer_autonomous_databases_value2", + ], + "create_time": {}, + "disaster_recovery_supported_locations": [ + "disaster_recovery_supported_locations_value1", + "disaster_recovery_supported_locations_value2", + ], + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = oracledatabase.CreateAutonomousDatabaseRequest.meta.fields[ + "autonomous_database" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["autonomous_database"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["autonomous_database"][field])): + del request_init["autonomous_database"][field][i][subfield] + else: + del request_init["autonomous_database"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.create_autonomous_database(request) + + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_autonomous_database_rest_interceptors(null_interceptor): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.OracleDatabaseRestInterceptor(), + ) + client = OracleDatabaseClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "post_create_autonomous_database" + ) as post, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_create_autonomous_database_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "pre_create_autonomous_database" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = oracledatabase.CreateAutonomousDatabaseRequest.pb( + oracledatabase.CreateAutonomousDatabaseRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value + + request = oracledatabase.CreateAutonomousDatabaseRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata + + client.create_autonomous_database( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_update_autonomous_database_rest_bad_request( + request_type=oracledatabase.UpdateAutonomousDatabaseRequest, +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "autonomous_database": { + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + } + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.update_autonomous_database(request) + + +@pytest.mark.parametrize( + "request_type", + [ + oracledatabase.UpdateAutonomousDatabaseRequest, + dict, + ], +) +def test_update_autonomous_database_rest_call_success(request_type): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "autonomous_database": { + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + } + } + request_init["autonomous_database"] = { + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3", + "database": "database_value", + "display_name": "display_name_value", + "entitlement_id": "entitlement_id_value", + "admin_password": "admin_password_value", + "admin_password_secret_version": "admin_password_secret_version_value", + "properties": { + "ocid": "ocid_value", + "compute_count": 0.1413, + "cpu_core_count": 1496, + "data_storage_size_tb": 2109, + "data_storage_size_gb": 2096, + "db_workload": 1, + "db_edition": 1, + "character_set": "character_set_value", + "n_character_set": "n_character_set_value", + "private_endpoint_ip": "private_endpoint_ip_value", + "private_endpoint_label": "private_endpoint_label_value", + "db_version": "db_version_value", + "is_auto_scaling_enabled": True, + "is_storage_auto_scaling_enabled": True, + "license_type": 1, + "customer_contacts": [{"email": "email_value"}], + "secret_id": "secret_id_value", + "vault_id": "vault_id_value", + "maintenance_schedule_type": 1, + "mtls_connection_required": True, + "backup_retention_period_days": 2975, + "actual_used_data_storage_size_tb": 0.3366, + "allocated_storage_size_tb": 0.2636, + "apex_details": { + "apex_version": "apex_version_value", + "ords_version": "ords_version_value", + }, + "are_primary_allowlisted_ips_used": True, + "lifecycle_details": "lifecycle_details_value", + "state": 1, + "autonomous_container_database_id": "autonomous_container_database_id_value", + "available_upgrade_versions": [ + "available_upgrade_versions_value1", + "available_upgrade_versions_value2", + ], + "connection_strings": { + "all_connection_strings": { + "high": "high_value", + "low": "low_value", + "medium": "medium_value", + }, + "dedicated": "dedicated_value", + "high": "high_value", + "low": "low_value", + "medium": "medium_value", + "profiles": [ + { + "consumer_group": 1, + "display_name": "display_name_value", + "host_format": 1, + "is_regional": True, + "protocol": 1, + "session_mode": 1, + "syntax_format": 1, + "tls_authentication": 1, + "value": "value_value", + } + ], + }, + "connection_urls": { + "apex_uri": "apex_uri_value", + "database_transforms_uri": "database_transforms_uri_value", + "graph_studio_uri": "graph_studio_uri_value", + "machine_learning_notebook_uri": "machine_learning_notebook_uri_value", + "machine_learning_user_management_uri": "machine_learning_user_management_uri_value", + "mongo_db_uri": "mongo_db_uri_value", + "ords_uri": "ords_uri_value", + "sql_dev_web_uri": "sql_dev_web_uri_value", + }, + "failed_data_recovery_duration": {"seconds": 751, "nanos": 543}, + "memory_table_gbs": 1691, + "is_local_data_guard_enabled": True, + "local_adg_auto_failover_max_data_loss_limit": 4513, + "local_standby_db": { + "lag_time_duration": {}, + "lifecycle_details": "lifecycle_details_value", + "state": 1, + "data_guard_role_changed_time": {"seconds": 751, "nanos": 543}, + "disaster_recovery_role_changed_time": {}, + }, + "memory_per_oracle_compute_unit_gbs": 3626, + "local_disaster_recovery_type": 1, + "data_safe_state": 1, + "database_management_state": 1, + "open_mode": 1, + "operations_insights_state": 1, + "peer_db_ids": ["peer_db_ids_value1", "peer_db_ids_value2"], + "permission_level": 1, + "private_endpoint": "private_endpoint_value", + "refreshable_mode": 1, + "refreshable_state": 1, + "role": 1, + "scheduled_operation_details": [ + { + "day_of_week": 1, + "start_time": { + "hours": 561, + "minutes": 773, + "seconds": 751, + "nanos": 543, + }, + "stop_time": {}, + } + ], + "sql_web_developer_url": "sql_web_developer_url_value", + "supported_clone_regions": [ + "supported_clone_regions_value1", + "supported_clone_regions_value2", + ], + "used_data_storage_size_tbs": 2752, + "oci_url": "oci_url_value", + "total_auto_backup_storage_size_gbs": 0.36100000000000004, + "next_long_term_backup_time": {}, + "data_guard_role_changed_time": {}, + "disaster_recovery_role_changed_time": {}, + "maintenance_begin_time": {}, + "maintenance_end_time": {}, + "allowlisted_ips": ["allowlisted_ips_value1", "allowlisted_ips_value2"], + "encryption_key": {"provider": 1, "kms_key": "kms_key_value"}, + "encryption_key_history_entries": [ + {"encryption_key": {}, "activation_time": {}} + ], + "service_agent_email": "service_agent_email_value", + "local_data_guard_enabled": True, + "local_adg_auto_failover_max_data_loss_limit_duration": 5478, + }, + "labels": {}, + "network": "network_value", + "cidr": "cidr_value", + "odb_network": "odb_network_value", + "odb_subnet": "odb_subnet_value", + "source_config": { + "autonomous_database": "autonomous_database_value", + "automatic_backups_replication_enabled": True, + }, + "peer_autonomous_databases": [ + "peer_autonomous_databases_value1", + "peer_autonomous_databases_value2", + ], + "create_time": {}, + "disaster_recovery_supported_locations": [ + "disaster_recovery_supported_locations_value1", + "disaster_recovery_supported_locations_value2", + ], + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = oracledatabase.UpdateAutonomousDatabaseRequest.meta.fields[ + "autonomous_database" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["autonomous_database"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["autonomous_database"][field])): + del request_init["autonomous_database"][field][i][subfield] + else: + del request_init["autonomous_database"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.update_autonomous_database(request) + + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_autonomous_database_rest_interceptors(null_interceptor): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.OracleDatabaseRestInterceptor(), + ) + client = OracleDatabaseClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "post_update_autonomous_database" + ) as post, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_update_autonomous_database_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "pre_update_autonomous_database" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = oracledatabase.UpdateAutonomousDatabaseRequest.pb( + oracledatabase.UpdateAutonomousDatabaseRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value + + request = oracledatabase.UpdateAutonomousDatabaseRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata + + client.update_autonomous_database( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_delete_autonomous_database_rest_bad_request( + request_type=oracledatabase.DeleteAutonomousDatabaseRequest, +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.delete_autonomous_database(request) + + +@pytest.mark.parametrize( + "request_type", + [ + oracledatabase.DeleteAutonomousDatabaseRequest, + dict, + ], +) +def test_delete_autonomous_database_rest_call_success(request_type): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.delete_autonomous_database(request) + + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_autonomous_database_rest_interceptors(null_interceptor): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.OracleDatabaseRestInterceptor(), + ) + client = OracleDatabaseClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "post_delete_autonomous_database" + ) as post, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_delete_autonomous_database_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "pre_delete_autonomous_database" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = oracledatabase.DeleteAutonomousDatabaseRequest.pb( + oracledatabase.DeleteAutonomousDatabaseRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value + + request = oracledatabase.DeleteAutonomousDatabaseRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata + + client.delete_autonomous_database( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_restore_autonomous_database_rest_bad_request( + request_type=oracledatabase.RestoreAutonomousDatabaseRequest, +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.restore_autonomous_database(request) + + +@pytest.mark.parametrize( + "request_type", + [ + oracledatabase.RestoreAutonomousDatabaseRequest, + dict, + ], +) +def test_restore_autonomous_database_rest_call_success(request_type): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.restore_autonomous_database(request) + + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_restore_autonomous_database_rest_interceptors(null_interceptor): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.OracleDatabaseRestInterceptor(), + ) + client = OracleDatabaseClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "post_restore_autonomous_database" + ) as post, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_restore_autonomous_database_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "pre_restore_autonomous_database" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = oracledatabase.RestoreAutonomousDatabaseRequest.pb( + oracledatabase.RestoreAutonomousDatabaseRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value + + request = oracledatabase.RestoreAutonomousDatabaseRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata + + client.restore_autonomous_database( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_generate_autonomous_database_wallet_rest_bad_request( + request_type=oracledatabase.GenerateAutonomousDatabaseWalletRequest, +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.generate_autonomous_database_wallet(request) + + +@pytest.mark.parametrize( + "request_type", + [ + oracledatabase.GenerateAutonomousDatabaseWalletRequest, + dict, + ], +) +def test_generate_autonomous_database_wallet_rest_call_success(request_type): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = oracledatabase.GenerateAutonomousDatabaseWalletResponse( + archive_content=b"archive_content_blob", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = oracledatabase.GenerateAutonomousDatabaseWalletResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.generate_autonomous_database_wallet(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, oracledatabase.GenerateAutonomousDatabaseWalletResponse) + assert response.archive_content == b"archive_content_blob" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_generate_autonomous_database_wallet_rest_interceptors(null_interceptor): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.OracleDatabaseRestInterceptor(), + ) + client = OracleDatabaseClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_generate_autonomous_database_wallet", + ) as post, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_generate_autonomous_database_wallet_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "pre_generate_autonomous_database_wallet", + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = oracledatabase.GenerateAutonomousDatabaseWalletRequest.pb( + oracledatabase.GenerateAutonomousDatabaseWalletRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = oracledatabase.GenerateAutonomousDatabaseWalletResponse.to_json( + oracledatabase.GenerateAutonomousDatabaseWalletResponse() + ) + req.return_value.content = return_value + + request = oracledatabase.GenerateAutonomousDatabaseWalletRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = oracledatabase.GenerateAutonomousDatabaseWalletResponse() + post_with_metadata.return_value = ( + oracledatabase.GenerateAutonomousDatabaseWalletResponse(), + metadata, + ) + + client.generate_autonomous_database_wallet( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_autonomous_db_versions_rest_bad_request( + request_type=oracledatabase.ListAutonomousDbVersionsRequest, +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.delete_db_system), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.delete_db_system(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = db_system.DeleteDbSystemRequest() - assert args[0] == request_msg + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_autonomous_db_versions(request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_db_versions_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +@pytest.mark.parametrize( + "request_type", + [ + oracledatabase.ListAutonomousDbVersionsRequest, + dict, + ], +) +def test_list_autonomous_db_versions_rest_call_success(request_type): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_db_versions), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - db_version.ListDbVersionsResponse( - next_page_token="next_page_token_value", - ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = oracledatabase.ListAutonomousDbVersionsResponse( + next_page_token="next_page_token_value", ) - await client.list_db_versions(request=None) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = db_version.ListDbVersionsRequest() - assert args[0] == request_msg + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = oracledatabase.ListAutonomousDbVersionsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_autonomous_db_versions(request) + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListAutonomousDbVersionsPager) + assert response.next_page_token == "next_page_token_value" -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_database_character_sets_empty_call_grpc_asyncio(): - client = OracleDatabaseAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_autonomous_db_versions_rest_interceptors(null_interceptor): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.OracleDatabaseRestInterceptor(), ) + client = OracleDatabaseClient(transport=transport) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_database_character_sets), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - database_character_set.ListDatabaseCharacterSetsResponse( - next_page_token="next_page_token_value", - ) + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "post_list_autonomous_db_versions" + ) as post, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_list_autonomous_db_versions_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "pre_list_autonomous_db_versions" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = oracledatabase.ListAutonomousDbVersionsRequest.pb( + oracledatabase.ListAutonomousDbVersionsRequest() ) - await client.list_database_character_sets(request=None) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = database_character_set.ListDatabaseCharacterSetsRequest() - assert args[0] == request_msg + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = oracledatabase.ListAutonomousDbVersionsResponse.to_json( + oracledatabase.ListAutonomousDbVersionsResponse() + ) + req.return_value.content = return_value + request = oracledatabase.ListAutonomousDbVersionsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = oracledatabase.ListAutonomousDbVersionsResponse() + post_with_metadata.return_value = ( + oracledatabase.ListAutonomousDbVersionsResponse(), + metadata, + ) -def test_transport_kind_rest(): - transport = OracleDatabaseClient.get_transport_class("rest")( - credentials=ga_credentials.AnonymousCredentials() - ) - assert transport.kind == "rest" + client.list_autonomous_db_versions( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() -def test_list_cloud_exadata_infrastructures_rest_bad_request( - request_type=oracledatabase.ListCloudExadataInfrastructuresRequest, + +def test_list_autonomous_database_character_sets_rest_bad_request( + request_type=oracledatabase.ListAutonomousDatabaseCharacterSetsRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" @@ -42212,17 +62208,17 @@ def test_list_cloud_exadata_infrastructures_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_cloud_exadata_infrastructures(request) + client.list_autonomous_database_character_sets(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.ListCloudExadataInfrastructuresRequest, + oracledatabase.ListAutonomousDatabaseCharacterSetsRequest, dict, ], ) -def test_list_cloud_exadata_infrastructures_rest_call_success(request_type): +def test_list_autonomous_database_character_sets_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -42234,7 +62230,7 @@ def test_list_cloud_exadata_infrastructures_rest_call_success(request_type): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListCloudExadataInfrastructuresResponse( + return_value = oracledatabase.ListAutonomousDatabaseCharacterSetsResponse( next_page_token="next_page_token_value", ) @@ -42243,22 +62239,22 @@ def test_list_cloud_exadata_infrastructures_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = oracledatabase.ListCloudExadataInfrastructuresResponse.pb( + return_value = oracledatabase.ListAutonomousDatabaseCharacterSetsResponse.pb( return_value ) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_cloud_exadata_infrastructures(request) + response = client.list_autonomous_database_character_sets(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListCloudExadataInfrastructuresPager) + assert isinstance(response, pagers.ListAutonomousDatabaseCharacterSetsPager) assert response.next_page_token == "next_page_token_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_cloud_exadata_infrastructures_rest_interceptors(null_interceptor): +def test_list_autonomous_database_character_sets_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -42272,22 +62268,22 @@ def test_list_cloud_exadata_infrastructures_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_list_cloud_exadata_infrastructures", + "post_list_autonomous_database_character_sets", ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_list_cloud_exadata_infrastructures_with_metadata", + "post_list_autonomous_database_character_sets_with_metadata", ) as post_with_metadata, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "pre_list_cloud_exadata_infrastructures", + "pre_list_autonomous_database_character_sets", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.ListCloudExadataInfrastructuresRequest.pb( - oracledatabase.ListCloudExadataInfrastructuresRequest() + pb_message = oracledatabase.ListAutonomousDatabaseCharacterSetsRequest.pb( + oracledatabase.ListAutonomousDatabaseCharacterSetsRequest() ) transcode.return_value = { "method": "post", @@ -42299,24 +62295,26 @@ def test_list_cloud_exadata_infrastructures_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = oracledatabase.ListCloudExadataInfrastructuresResponse.to_json( - oracledatabase.ListCloudExadataInfrastructuresResponse() + return_value = ( + oracledatabase.ListAutonomousDatabaseCharacterSetsResponse.to_json( + oracledatabase.ListAutonomousDatabaseCharacterSetsResponse() + ) ) req.return_value.content = return_value - request = oracledatabase.ListCloudExadataInfrastructuresRequest() + request = oracledatabase.ListAutonomousDatabaseCharacterSetsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = oracledatabase.ListCloudExadataInfrastructuresResponse() + post.return_value = oracledatabase.ListAutonomousDatabaseCharacterSetsResponse() post_with_metadata.return_value = ( - oracledatabase.ListCloudExadataInfrastructuresResponse(), + oracledatabase.ListAutonomousDatabaseCharacterSetsResponse(), metadata, ) - client.list_cloud_exadata_infrastructures( + client.list_autonomous_database_character_sets( request, metadata=[ ("key", "val"), @@ -42329,16 +62327,14 @@ def test_list_cloud_exadata_infrastructures_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_get_cloud_exadata_infrastructure_rest_bad_request( - request_type=oracledatabase.GetCloudExadataInfrastructureRequest, +def test_list_autonomous_database_backups_rest_bad_request( + request_type=oracledatabase.ListAutonomousDatabaseBackupsRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/cloudExadataInfrastructures/sample3" - } + request_init = {"parent": "projects/sample1/locations/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -42354,35 +62350,30 @@ def test_get_cloud_exadata_infrastructure_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_cloud_exadata_infrastructure(request) + client.list_autonomous_database_backups(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.GetCloudExadataInfrastructureRequest, + oracledatabase.ListAutonomousDatabaseBackupsRequest, dict, ], ) -def test_get_cloud_exadata_infrastructure_rest_call_success(request_type): +def test_list_autonomous_database_backups_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/cloudExadataInfrastructures/sample3" - } + request_init = {"parent": "projects/sample1/locations/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = exadata_infra.CloudExadataInfrastructure( - name="name_value", - display_name="display_name_value", - gcp_oracle_zone="gcp_oracle_zone_value", - entitlement_id="entitlement_id_value", + return_value = oracledatabase.ListAutonomousDatabaseBackupsResponse( + next_page_token="next_page_token_value", ) # Wrap the value into a proper Response obj @@ -42390,23 +62381,22 @@ def test_get_cloud_exadata_infrastructure_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = exadata_infra.CloudExadataInfrastructure.pb(return_value) + return_value = oracledatabase.ListAutonomousDatabaseBackupsResponse.pb( + return_value + ) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_cloud_exadata_infrastructure(request) + response = client.list_autonomous_database_backups(request) # Establish that the response is the type that we expect. - assert isinstance(response, exadata_infra.CloudExadataInfrastructure) - assert response.name == "name_value" - assert response.display_name == "display_name_value" - assert response.gcp_oracle_zone == "gcp_oracle_zone_value" - assert response.entitlement_id == "entitlement_id_value" + assert isinstance(response, pagers.ListAutonomousDatabaseBackupsPager) + assert response.next_page_token == "next_page_token_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_cloud_exadata_infrastructure_rest_interceptors(null_interceptor): +def test_list_autonomous_database_backups_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -42420,22 +62410,22 @@ def test_get_cloud_exadata_infrastructure_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_get_cloud_exadata_infrastructure", + "post_list_autonomous_database_backups", ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_get_cloud_exadata_infrastructure_with_metadata", + "post_list_autonomous_database_backups_with_metadata", ) as post_with_metadata, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "pre_get_cloud_exadata_infrastructure", + "pre_list_autonomous_database_backups", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.GetCloudExadataInfrastructureRequest.pb( - oracledatabase.GetCloudExadataInfrastructureRequest() + pb_message = oracledatabase.ListAutonomousDatabaseBackupsRequest.pb( + oracledatabase.ListAutonomousDatabaseBackupsRequest() ) transcode.return_value = { "method": "post", @@ -42447,24 +62437,24 @@ def test_get_cloud_exadata_infrastructure_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = exadata_infra.CloudExadataInfrastructure.to_json( - exadata_infra.CloudExadataInfrastructure() + return_value = oracledatabase.ListAutonomousDatabaseBackupsResponse.to_json( + oracledatabase.ListAutonomousDatabaseBackupsResponse() ) req.return_value.content = return_value - request = oracledatabase.GetCloudExadataInfrastructureRequest() + request = oracledatabase.ListAutonomousDatabaseBackupsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = exadata_infra.CloudExadataInfrastructure() + post.return_value = oracledatabase.ListAutonomousDatabaseBackupsResponse() post_with_metadata.return_value = ( - exadata_infra.CloudExadataInfrastructure(), + oracledatabase.ListAutonomousDatabaseBackupsResponse(), metadata, ) - client.get_cloud_exadata_infrastructure( + client.list_autonomous_database_backups( request, metadata=[ ("key", "val"), @@ -42477,14 +62467,16 @@ def test_get_cloud_exadata_infrastructure_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_create_cloud_exadata_infrastructure_rest_bad_request( - request_type=oracledatabase.CreateCloudExadataInfrastructureRequest, +def test_stop_autonomous_database_rest_bad_request( + request_type=oracledatabase.StopAutonomousDatabaseRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} + request_init = { + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -42500,146 +62492,155 @@ def test_create_cloud_exadata_infrastructure_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_cloud_exadata_infrastructure(request) + client.stop_autonomous_database(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.CreateCloudExadataInfrastructureRequest, + oracledatabase.StopAutonomousDatabaseRequest, dict, ], ) -def test_create_cloud_exadata_infrastructure_rest_call_success(request_type): +def test_stop_autonomous_database_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} - request_init["cloud_exadata_infrastructure"] = { - "name": "name_value", - "display_name": "display_name_value", - "gcp_oracle_zone": "gcp_oracle_zone_value", - "entitlement_id": "entitlement_id_value", - "properties": { - "ocid": "ocid_value", - "compute_count": 1413, - "storage_count": 1405, - "total_storage_size_gb": 2234, - "available_storage_size_gb": 2615, - "maintenance_window": { - "preference": 1, - "months": [1], - "weeks_of_month": [1497, 1498], - "days_of_week": [1], - "hours_of_day": [1283, 1284], - "lead_time_week": 1455, - "patching_mode": 1, - "custom_action_timeout_mins": 2804, - "is_custom_action_timeout_enabled": True, - }, - "state": 1, - "shape": "shape_value", - "oci_url": "oci_url_value", - "cpu_count": 976, - "max_cpu_count": 1397, - "memory_size_gb": 1499, - "max_memory_gb": 1382, - "db_node_storage_size_gb": 2401, - "max_db_node_storage_size_gb": 2822, - "data_storage_size_tb": 0.2109, - "max_data_storage_tb": 0.19920000000000002, - "activated_storage_count": 2449, - "additional_storage_count": 2549, - "db_server_version": "db_server_version_value", - "storage_server_version": "storage_server_version_value", - "next_maintenance_run_id": "next_maintenance_run_id_value", - "next_maintenance_run_time": {"seconds": 751, "nanos": 543}, - "next_security_maintenance_run_time": {}, - "customer_contacts": [{"email": "email_value"}], - "monthly_storage_server_version": "monthly_storage_server_version_value", - "monthly_db_server_version": "monthly_db_server_version_value", - "compute_model": 1, - "database_server_type": "database_server_type_value", - "storage_server_type": "storage_server_type_value", - }, - "labels": {}, - "create_time": {}, + request_init = { + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 + request = request_type(**request_init) - # Determine if the message type is proto-plus or protobuf - test_field = oracledatabase.CreateCloudExadataInfrastructureRequest.meta.fields[ - "cloud_exadata_infrastructure" - ] + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.stop_autonomous_database(request) - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_stop_autonomous_database_rest_interceptors(null_interceptor): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.OracleDatabaseRestInterceptor(), + ) + client = OracleDatabaseClient(transport=transport) - subfields_not_in_runtime = [] + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "post_stop_autonomous_database" + ) as post, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_stop_autonomous_database_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "pre_stop_autonomous_database" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = oracledatabase.StopAutonomousDatabaseRequest.pb( + oracledatabase.StopAutonomousDatabaseRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init[ - "cloud_exadata_infrastructure" - ].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) + request = oracledatabase.StopAutonomousDatabaseRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata + + client.stop_autonomous_database( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_start_autonomous_database_rest_bad_request( + request_type=oracledatabase.StartAutonomousDatabaseRequest, +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.start_autonomous_database(request) + + +@pytest.mark.parametrize( + "request_type", + [ + oracledatabase.StartAutonomousDatabaseRequest, + dict, + ], +) +def test_start_autonomous_database_rest_call_success(request_type): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range( - 0, len(request_init["cloud_exadata_infrastructure"][field]) - ): - del request_init["cloud_exadata_infrastructure"][field][i][subfield] - else: - del request_init["cloud_exadata_infrastructure"][field][subfield] + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -42654,14 +62655,14 @@ def get_message_fields(field): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_cloud_exadata_infrastructure(request) + response = client.start_autonomous_database(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_cloud_exadata_infrastructure_rest_interceptors(null_interceptor): +def test_start_autonomous_database_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -42675,23 +62676,21 @@ def test_create_cloud_exadata_infrastructure_rest_interceptors(null_interceptor) mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.OracleDatabaseRestInterceptor, - "post_create_cloud_exadata_infrastructure", + transports.OracleDatabaseRestInterceptor, "post_start_autonomous_database" ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_create_cloud_exadata_infrastructure_with_metadata", + "post_start_autonomous_database_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, - "pre_create_cloud_exadata_infrastructure", + transports.OracleDatabaseRestInterceptor, "pre_start_autonomous_database" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.CreateCloudExadataInfrastructureRequest.pb( - oracledatabase.CreateCloudExadataInfrastructureRequest() + pb_message = oracledatabase.StartAutonomousDatabaseRequest.pb( + oracledatabase.StartAutonomousDatabaseRequest() ) transcode.return_value = { "method": "post", @@ -42706,7 +62705,7 @@ def test_create_cloud_exadata_infrastructure_rest_interceptors(null_interceptor) return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = oracledatabase.CreateCloudExadataInfrastructureRequest() + request = oracledatabase.StartAutonomousDatabaseRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -42715,7 +62714,7 @@ def test_create_cloud_exadata_infrastructure_rest_interceptors(null_interceptor) post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.create_cloud_exadata_infrastructure( + client.start_autonomous_database( request, metadata=[ ("key", "val"), @@ -42728,15 +62727,15 @@ def test_create_cloud_exadata_infrastructure_rest_interceptors(null_interceptor) post_with_metadata.assert_called_once() -def test_delete_cloud_exadata_infrastructure_rest_bad_request( - request_type=oracledatabase.DeleteCloudExadataInfrastructureRequest, +def test_restart_autonomous_database_rest_bad_request( + request_type=oracledatabase.RestartAutonomousDatabaseRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/cloudExadataInfrastructures/sample3" + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" } request = request_type(**request_init) @@ -42753,24 +62752,24 @@ def test_delete_cloud_exadata_infrastructure_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_cloud_exadata_infrastructure(request) + client.restart_autonomous_database(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.DeleteCloudExadataInfrastructureRequest, + oracledatabase.RestartAutonomousDatabaseRequest, dict, ], ) -def test_delete_cloud_exadata_infrastructure_rest_call_success(request_type): +def test_restart_autonomous_database_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/cloudExadataInfrastructures/sample3" + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" } request = request_type(**request_init) @@ -42786,14 +62785,14 @@ def test_delete_cloud_exadata_infrastructure_rest_call_success(request_type): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_cloud_exadata_infrastructure(request) + response = client.restart_autonomous_database(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_cloud_exadata_infrastructure_rest_interceptors(null_interceptor): +def test_restart_autonomous_database_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -42807,23 +62806,21 @@ def test_delete_cloud_exadata_infrastructure_rest_interceptors(null_interceptor) mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.OracleDatabaseRestInterceptor, - "post_delete_cloud_exadata_infrastructure", + transports.OracleDatabaseRestInterceptor, "post_restart_autonomous_database" ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_delete_cloud_exadata_infrastructure_with_metadata", + "post_restart_autonomous_database_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, - "pre_delete_cloud_exadata_infrastructure", + transports.OracleDatabaseRestInterceptor, "pre_restart_autonomous_database" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.DeleteCloudExadataInfrastructureRequest.pb( - oracledatabase.DeleteCloudExadataInfrastructureRequest() + pb_message = oracledatabase.RestartAutonomousDatabaseRequest.pb( + oracledatabase.RestartAutonomousDatabaseRequest() ) transcode.return_value = { "method": "post", @@ -42838,7 +62835,7 @@ def test_delete_cloud_exadata_infrastructure_rest_interceptors(null_interceptor) return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = oracledatabase.DeleteCloudExadataInfrastructureRequest() + request = oracledatabase.RestartAutonomousDatabaseRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -42847,7 +62844,7 @@ def test_delete_cloud_exadata_infrastructure_rest_interceptors(null_interceptor) post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.delete_cloud_exadata_infrastructure( + client.restart_autonomous_database( request, metadata=[ ("key", "val"), @@ -42860,14 +62857,16 @@ def test_delete_cloud_exadata_infrastructure_rest_interceptors(null_interceptor) post_with_metadata.assert_called_once() -def test_list_cloud_vm_clusters_rest_bad_request( - request_type=oracledatabase.ListCloudVmClustersRequest, +def test_switchover_autonomous_database_rest_bad_request( + request_type=oracledatabase.SwitchoverAutonomousDatabaseRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} + request_init = { + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -42883,51 +62882,47 @@ def test_list_cloud_vm_clusters_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_cloud_vm_clusters(request) + client.switchover_autonomous_database(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.ListCloudVmClustersRequest, + oracledatabase.SwitchoverAutonomousDatabaseRequest, dict, ], ) -def test_list_cloud_vm_clusters_rest_call_success(request_type): +def test_switchover_autonomous_database_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} + request_init = { + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListCloudVmClustersResponse( - next_page_token="next_page_token_value", - ) + return_value = operations_pb2.Operation(name="operations/spam") # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = oracledatabase.ListCloudVmClustersResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_cloud_vm_clusters(request) + response = client.switchover_autonomous_database(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListCloudVmClustersPager) - assert response.next_page_token == "next_page_token_value" + json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_cloud_vm_clusters_rest_interceptors(null_interceptor): +def test_switchover_autonomous_database_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -42939,22 +62934,25 @@ def test_list_cloud_vm_clusters_rest_interceptors(null_interceptor): with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_list_cloud_vm_clusters" + transports.OracleDatabaseRestInterceptor, + "post_switchover_autonomous_database", ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_list_cloud_vm_clusters_with_metadata", + "post_switchover_autonomous_database_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_list_cloud_vm_clusters" + transports.OracleDatabaseRestInterceptor, + "pre_switchover_autonomous_database", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.ListCloudVmClustersRequest.pb( - oracledatabase.ListCloudVmClustersRequest() + pb_message = oracledatabase.SwitchoverAutonomousDatabaseRequest.pb( + oracledatabase.SwitchoverAutonomousDatabaseRequest() ) transcode.return_value = { "method": "post", @@ -42966,24 +62964,19 @@ def test_list_cloud_vm_clusters_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = oracledatabase.ListCloudVmClustersResponse.to_json( - oracledatabase.ListCloudVmClustersResponse() - ) + return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = oracledatabase.ListCloudVmClustersRequest() + request = oracledatabase.SwitchoverAutonomousDatabaseRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = oracledatabase.ListCloudVmClustersResponse() - post_with_metadata.return_value = ( - oracledatabase.ListCloudVmClustersResponse(), - metadata, - ) + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.list_cloud_vm_clusters( + client.switchover_autonomous_database( request, metadata=[ ("key", "val"), @@ -42996,15 +62989,15 @@ def test_list_cloud_vm_clusters_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_get_cloud_vm_cluster_rest_bad_request( - request_type=oracledatabase.GetCloudVmClusterRequest, +def test_failover_autonomous_database_rest_bad_request( + request_type=oracledatabase.FailoverAutonomousDatabaseRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/cloudVmClusters/sample3" + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" } request = request_type(**request_init) @@ -43021,71 +63014,47 @@ def test_get_cloud_vm_cluster_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_cloud_vm_cluster(request) + client.failover_autonomous_database(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.GetCloudVmClusterRequest, + oracledatabase.FailoverAutonomousDatabaseRequest, dict, ], ) -def test_get_cloud_vm_cluster_rest_call_success(request_type): +def test_failover_autonomous_database_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/cloudVmClusters/sample3" + "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = vm_cluster.CloudVmCluster( - name="name_value", - exadata_infrastructure="exadata_infrastructure_value", - display_name="display_name_value", - cidr="cidr_value", - backup_subnet_cidr="backup_subnet_cidr_value", - network="network_value", - gcp_oracle_zone="gcp_oracle_zone_value", - odb_network="odb_network_value", - odb_subnet="odb_subnet_value", - backup_odb_subnet="backup_odb_subnet_value", - ) + return_value = operations_pb2.Operation(name="operations/spam") # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = vm_cluster.CloudVmCluster.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_cloud_vm_cluster(request) + response = client.failover_autonomous_database(request) # Establish that the response is the type that we expect. - assert isinstance(response, vm_cluster.CloudVmCluster) - assert response.name == "name_value" - assert response.exadata_infrastructure == "exadata_infrastructure_value" - assert response.display_name == "display_name_value" - assert response.cidr == "cidr_value" - assert response.backup_subnet_cidr == "backup_subnet_cidr_value" - assert response.network == "network_value" - assert response.gcp_oracle_zone == "gcp_oracle_zone_value" - assert response.odb_network == "odb_network_value" - assert response.odb_subnet == "odb_subnet_value" - assert response.backup_odb_subnet == "backup_odb_subnet_value" + json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_cloud_vm_cluster_rest_interceptors(null_interceptor): +def test_failover_autonomous_database_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -43097,22 +63066,24 @@ def test_get_cloud_vm_cluster_rest_interceptors(null_interceptor): with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_get_cloud_vm_cluster" + transports.OracleDatabaseRestInterceptor, + "post_failover_autonomous_database", ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_get_cloud_vm_cluster_with_metadata", + "post_failover_autonomous_database_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_get_cloud_vm_cluster" + transports.OracleDatabaseRestInterceptor, "pre_failover_autonomous_database" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.GetCloudVmClusterRequest.pb( - oracledatabase.GetCloudVmClusterRequest() + pb_message = oracledatabase.FailoverAutonomousDatabaseRequest.pb( + oracledatabase.FailoverAutonomousDatabaseRequest() ) transcode.return_value = { "method": "post", @@ -43124,19 +63095,19 @@ def test_get_cloud_vm_cluster_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = vm_cluster.CloudVmCluster.to_json(vm_cluster.CloudVmCluster()) + return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = oracledatabase.GetCloudVmClusterRequest() + request = oracledatabase.FailoverAutonomousDatabaseRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = vm_cluster.CloudVmCluster() - post_with_metadata.return_value = vm_cluster.CloudVmCluster(), metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.get_cloud_vm_cluster( + client.failover_autonomous_database( request, metadata=[ ("key", "val"), @@ -43149,8 +63120,8 @@ def test_get_cloud_vm_cluster_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_create_cloud_vm_cluster_rest_bad_request( - request_type=oracledatabase.CreateCloudVmClusterRequest, +def test_list_odb_networks_rest_bad_request( + request_type=odb_network.ListOdbNetworksRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" @@ -43172,171 +63143,53 @@ def test_create_cloud_vm_cluster_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_cloud_vm_cluster(request) + client.list_odb_networks(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.CreateCloudVmClusterRequest, + odb_network.ListOdbNetworksRequest, dict, ], ) -def test_create_cloud_vm_cluster_rest_call_success(request_type): +def test_list_odb_networks_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = {"parent": "projects/sample1/locations/sample2"} - request_init["cloud_vm_cluster"] = { - "name": "name_value", - "exadata_infrastructure": "exadata_infrastructure_value", - "display_name": "display_name_value", - "properties": { - "ocid": "ocid_value", - "license_type": 1, - "gi_version": "gi_version_value", - "time_zone": {"id": "id_value", "version": "version_value"}, - "ssh_public_keys": ["ssh_public_keys_value1", "ssh_public_keys_value2"], - "node_count": 1070, - "shape": "shape_value", - "ocpu_count": 0.1087, - "memory_size_gb": 1499, - "db_node_storage_size_gb": 2401, - "storage_size_gb": 1591, - "data_storage_size_tb": 0.2109, - "disk_redundancy": 1, - "sparse_diskgroup_enabled": True, - "local_backup_enabled": True, - "hostname_prefix": "hostname_prefix_value", - "diagnostics_data_collection_options": { - "diagnostics_events_enabled": True, - "health_monitoring_enabled": True, - "incident_logs_enabled": True, - }, - "state": 1, - "scan_listener_port_tcp": 2356, - "scan_listener_port_tcp_ssl": 2789, - "domain": "domain_value", - "scan_dns": "scan_dns_value", - "hostname": "hostname_value", - "cpu_core_count": 1496, - "system_version": "system_version_value", - "scan_ip_ids": ["scan_ip_ids_value1", "scan_ip_ids_value2"], - "scan_dns_record_id": "scan_dns_record_id_value", - "oci_url": "oci_url_value", - "db_server_ocids": ["db_server_ocids_value1", "db_server_ocids_value2"], - "compartment_id": "compartment_id_value", - "dns_listener_ip": "dns_listener_ip_value", - "cluster_name": "cluster_name_value", - "compute_model": 1, - }, - "labels": {}, - "create_time": {"seconds": 751, "nanos": 543}, - "cidr": "cidr_value", - "backup_subnet_cidr": "backup_subnet_cidr_value", - "network": "network_value", - "gcp_oracle_zone": "gcp_oracle_zone_value", - "odb_network": "odb_network_value", - "odb_subnet": "odb_subnet_value", - "backup_odb_subnet": "backup_odb_subnet_value", - "identity_connector": { - "service_agent_email": "service_agent_email_value", - "connection_state": 1, - }, - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = oracledatabase.CreateCloudVmClusterRequest.meta.fields[ - "cloud_vm_cluster" - ] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["cloud_vm_cluster"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["cloud_vm_cluster"][field])): - del request_init["cloud_vm_cluster"][field][i][subfield] - else: - del request_init["cloud_vm_cluster"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = odb_network.ListOdbNetworksResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = odb_network.ListOdbNetworksResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_cloud_vm_cluster(request) + response = client.list_odb_networks(request) # Establish that the response is the type that we expect. - json_return_value = json_format.MessageToJson(return_value) + assert isinstance(response, pagers.ListOdbNetworksPager) + assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_cloud_vm_cluster_rest_interceptors(null_interceptor): +def test_list_odb_networks_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -43348,23 +63201,22 @@ def test_create_cloud_vm_cluster_rest_interceptors(null_interceptor): with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, - mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_create_cloud_vm_cluster" + transports.OracleDatabaseRestInterceptor, "post_list_odb_networks" ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_create_cloud_vm_cluster_with_metadata", + "post_list_odb_networks_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_create_cloud_vm_cluster" + transports.OracleDatabaseRestInterceptor, "pre_list_odb_networks" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.CreateCloudVmClusterRequest.pb( - oracledatabase.CreateCloudVmClusterRequest() + pb_message = odb_network.ListOdbNetworksRequest.pb( + odb_network.ListOdbNetworksRequest() ) transcode.return_value = { "method": "post", @@ -43376,19 +63228,24 @@ def test_create_cloud_vm_cluster_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = json_format.MessageToJson(operations_pb2.Operation()) + return_value = odb_network.ListOdbNetworksResponse.to_json( + odb_network.ListOdbNetworksResponse() + ) req.return_value.content = return_value - request = oracledatabase.CreateCloudVmClusterRequest() + request = odb_network.ListOdbNetworksRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() - post_with_metadata.return_value = operations_pb2.Operation(), metadata + post.return_value = odb_network.ListOdbNetworksResponse() + post_with_metadata.return_value = ( + odb_network.ListOdbNetworksResponse(), + metadata, + ) - client.create_cloud_vm_cluster( + client.list_odb_networks( request, metadata=[ ("key", "val"), @@ -43401,16 +63258,14 @@ def test_create_cloud_vm_cluster_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_delete_cloud_vm_cluster_rest_bad_request( - request_type=oracledatabase.DeleteCloudVmClusterRequest, +def test_get_odb_network_rest_bad_request( + request_type=odb_network.GetOdbNetworkRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/cloudVmClusters/sample3" - } + request_init = {"name": "projects/sample1/locations/sample2/odbNetworks/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -43426,47 +63281,59 @@ def test_delete_cloud_vm_cluster_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_cloud_vm_cluster(request) + client.get_odb_network(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.DeleteCloudVmClusterRequest, + odb_network.GetOdbNetworkRequest, dict, ], ) -def test_delete_cloud_vm_cluster_rest_call_success(request_type): +def test_get_odb_network_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/cloudVmClusters/sample3" - } + request_init = {"name": "projects/sample1/locations/sample2/odbNetworks/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = odb_network.OdbNetwork( + name="name_value", + network="network_value", + state=odb_network.OdbNetwork.State.PROVISIONING, + entitlement_id="entitlement_id_value", + gcp_oracle_zone="gcp_oracle_zone_value", + ) # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = odb_network.OdbNetwork.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_cloud_vm_cluster(request) + response = client.get_odb_network(request) # Establish that the response is the type that we expect. - json_return_value = json_format.MessageToJson(return_value) + assert isinstance(response, odb_network.OdbNetwork) + assert response.name == "name_value" + assert response.network == "network_value" + assert response.state == odb_network.OdbNetwork.State.PROVISIONING + assert response.entitlement_id == "entitlement_id_value" + assert response.gcp_oracle_zone == "gcp_oracle_zone_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_cloud_vm_cluster_rest_interceptors(null_interceptor): +def test_get_odb_network_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -43478,23 +63345,22 @@ def test_delete_cloud_vm_cluster_rest_interceptors(null_interceptor): with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, - mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_delete_cloud_vm_cluster" + transports.OracleDatabaseRestInterceptor, "post_get_odb_network" ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_delete_cloud_vm_cluster_with_metadata", + "post_get_odb_network_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_delete_cloud_vm_cluster" + transports.OracleDatabaseRestInterceptor, "pre_get_odb_network" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.DeleteCloudVmClusterRequest.pb( - oracledatabase.DeleteCloudVmClusterRequest() + pb_message = odb_network.GetOdbNetworkRequest.pb( + odb_network.GetOdbNetworkRequest() ) transcode.return_value = { "method": "post", @@ -43506,19 +63372,19 @@ def test_delete_cloud_vm_cluster_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = json_format.MessageToJson(operations_pb2.Operation()) + return_value = odb_network.OdbNetwork.to_json(odb_network.OdbNetwork()) req.return_value.content = return_value - request = oracledatabase.DeleteCloudVmClusterRequest() + request = odb_network.GetOdbNetworkRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() - post_with_metadata.return_value = operations_pb2.Operation(), metadata + post.return_value = odb_network.OdbNetwork() + post_with_metadata.return_value = odb_network.OdbNetwork(), metadata - client.delete_cloud_vm_cluster( + client.get_odb_network( request, metadata=[ ("key", "val"), @@ -43531,8 +63397,8 @@ def test_delete_cloud_vm_cluster_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_entitlements_rest_bad_request( - request_type=oracledatabase.ListEntitlementsRequest, +def test_create_odb_network_rest_bad_request( + request_type=gco_odb_network.CreateOdbNetworkRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" @@ -43541,64 +63407,134 @@ def test_list_entitlements_rest_bad_request( request_init = {"parent": "projects/sample1/locations/sample2"} request = request_type(**request_init) - # Mock the http request call within the method and fake a BadRequest error. - with ( - mock.patch.object(Session, "request") as req, - pytest.raises(core_exceptions.BadRequest), - ): - # Wrap the value into a proper Response obj - response_value = mock.Mock() - json_return_value = "" - response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_entitlements(request) + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.create_odb_network(request) + + +@pytest.mark.parametrize( + "request_type", + [ + gco_odb_network.CreateOdbNetworkRequest, + dict, + ], +) +def test_create_odb_network_rest_call_success(request_type): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request_init["odb_network"] = { + "name": "name_value", + "network": "network_value", + "labels": {}, + "create_time": {"seconds": 751, "nanos": 543}, + "state": 1, + "entitlement_id": "entitlement_id_value", + "gcp_oracle_zone": "gcp_oracle_zone_value", + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = gco_odb_network.CreateOdbNetworkRequest.meta.fields["odb_network"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["odb_network"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value -@pytest.mark.parametrize( - "request_type", - [ - oracledatabase.ListEntitlementsRequest, - dict, - ], -) -def test_list_entitlements_rest_call_success(request_type): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) - # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["odb_network"][field])): + del request_init["odb_network"][field][i][subfield] + else: + del request_init["odb_network"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListEntitlementsResponse( - next_page_token="next_page_token_value", - ) + return_value = operations_pb2.Operation(name="operations/spam") # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = oracledatabase.ListEntitlementsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_entitlements(request) + response = client.create_odb_network(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListEntitlementsPager) - assert response.next_page_token == "next_page_token_value" + json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_entitlements_rest_interceptors(null_interceptor): +def test_create_odb_network_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -43610,22 +63546,23 @@ def test_list_entitlements_rest_interceptors(null_interceptor): with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_list_entitlements" + transports.OracleDatabaseRestInterceptor, "post_create_odb_network" ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_list_entitlements_with_metadata", + "post_create_odb_network_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_list_entitlements" + transports.OracleDatabaseRestInterceptor, "pre_create_odb_network" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.ListEntitlementsRequest.pb( - oracledatabase.ListEntitlementsRequest() + pb_message = gco_odb_network.CreateOdbNetworkRequest.pb( + gco_odb_network.CreateOdbNetworkRequest() ) transcode.return_value = { "method": "post", @@ -43637,24 +63574,19 @@ def test_list_entitlements_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = oracledatabase.ListEntitlementsResponse.to_json( - oracledatabase.ListEntitlementsResponse() - ) + return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = oracledatabase.ListEntitlementsRequest() + request = gco_odb_network.CreateOdbNetworkRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = oracledatabase.ListEntitlementsResponse() - post_with_metadata.return_value = ( - oracledatabase.ListEntitlementsResponse(), - metadata, - ) + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.list_entitlements( + client.create_odb_network( request, metadata=[ ("key", "val"), @@ -43667,16 +63599,14 @@ def test_list_entitlements_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_db_servers_rest_bad_request( - request_type=oracledatabase.ListDbServersRequest, +def test_delete_odb_network_rest_bad_request( + request_type=odb_network.DeleteOdbNetworkRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "parent": "projects/sample1/locations/sample2/cloudExadataInfrastructures/sample3" - } + request_init = {"name": "projects/sample1/locations/sample2/odbNetworks/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -43692,53 +63622,45 @@ def test_list_db_servers_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_db_servers(request) + client.delete_odb_network(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.ListDbServersRequest, + odb_network.DeleteOdbNetworkRequest, dict, ], ) -def test_list_db_servers_rest_call_success(request_type): +def test_delete_odb_network_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "parent": "projects/sample1/locations/sample2/cloudExadataInfrastructures/sample3" - } + request_init = {"name": "projects/sample1/locations/sample2/odbNetworks/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListDbServersResponse( - next_page_token="next_page_token_value", - ) + return_value = operations_pb2.Operation(name="operations/spam") # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = oracledatabase.ListDbServersResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_db_servers(request) + response = client.delete_odb_network(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListDbServersPager) - assert response.next_page_token == "next_page_token_value" + json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_db_servers_rest_interceptors(null_interceptor): +def test_delete_odb_network_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -43750,22 +63672,23 @@ def test_list_db_servers_rest_interceptors(null_interceptor): with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_list_db_servers" + transports.OracleDatabaseRestInterceptor, "post_delete_odb_network" ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_list_db_servers_with_metadata", + "post_delete_odb_network_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_list_db_servers" + transports.OracleDatabaseRestInterceptor, "pre_delete_odb_network" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.ListDbServersRequest.pb( - oracledatabase.ListDbServersRequest() + pb_message = odb_network.DeleteOdbNetworkRequest.pb( + odb_network.DeleteOdbNetworkRequest() ) transcode.return_value = { "method": "post", @@ -43777,24 +63700,19 @@ def test_list_db_servers_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = oracledatabase.ListDbServersResponse.to_json( - oracledatabase.ListDbServersResponse() - ) + return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = oracledatabase.ListDbServersRequest() + request = odb_network.DeleteOdbNetworkRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = oracledatabase.ListDbServersResponse() - post_with_metadata.return_value = ( - oracledatabase.ListDbServersResponse(), - metadata, - ) + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.list_db_servers( + client.delete_odb_network( request, metadata=[ ("key", "val"), @@ -43807,14 +63725,14 @@ def test_list_db_servers_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_db_nodes_rest_bad_request(request_type=oracledatabase.ListDbNodesRequest): +def test_list_odb_subnets_rest_bad_request( + request_type=odb_subnet.ListOdbSubnetsRequest, +): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "parent": "projects/sample1/locations/sample2/cloudVmClusters/sample3" - } + request_init = {"parent": "projects/sample1/locations/sample2/odbNetworks/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -43830,32 +63748,31 @@ def test_list_db_nodes_rest_bad_request(request_type=oracledatabase.ListDbNodesR response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_db_nodes(request) + client.list_odb_subnets(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.ListDbNodesRequest, + odb_subnet.ListOdbSubnetsRequest, dict, ], ) -def test_list_db_nodes_rest_call_success(request_type): +def test_list_odb_subnets_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "parent": "projects/sample1/locations/sample2/cloudVmClusters/sample3" - } + request_init = {"parent": "projects/sample1/locations/sample2/odbNetworks/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListDbNodesResponse( + return_value = odb_subnet.ListOdbSubnetsResponse( next_page_token="next_page_token_value", + unreachable=["unreachable_value"], ) # Wrap the value into a proper Response obj @@ -43863,20 +63780,21 @@ def test_list_db_nodes_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = oracledatabase.ListDbNodesResponse.pb(return_value) + return_value = odb_subnet.ListOdbSubnetsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_db_nodes(request) + response = client.list_odb_subnets(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListDbNodesPager) + assert isinstance(response, pagers.ListOdbSubnetsPager) assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_db_nodes_rest_interceptors(null_interceptor): +def test_list_odb_subnets_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -43889,20 +63807,21 @@ def test_list_db_nodes_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_list_db_nodes" + transports.OracleDatabaseRestInterceptor, "post_list_odb_subnets" ) as post, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_list_db_nodes_with_metadata" + transports.OracleDatabaseRestInterceptor, + "post_list_odb_subnets_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_list_db_nodes" + transports.OracleDatabaseRestInterceptor, "pre_list_odb_subnets" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.ListDbNodesRequest.pb( - oracledatabase.ListDbNodesRequest() + pb_message = odb_subnet.ListOdbSubnetsRequest.pb( + odb_subnet.ListOdbSubnetsRequest() ) transcode.return_value = { "method": "post", @@ -43914,21 +63833,21 @@ def test_list_db_nodes_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = oracledatabase.ListDbNodesResponse.to_json( - oracledatabase.ListDbNodesResponse() + return_value = odb_subnet.ListOdbSubnetsResponse.to_json( + odb_subnet.ListOdbSubnetsResponse() ) req.return_value.content = return_value - request = oracledatabase.ListDbNodesRequest() + request = odb_subnet.ListOdbSubnetsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = oracledatabase.ListDbNodesResponse() - post_with_metadata.return_value = oracledatabase.ListDbNodesResponse(), metadata + post.return_value = odb_subnet.ListOdbSubnetsResponse() + post_with_metadata.return_value = odb_subnet.ListOdbSubnetsResponse(), metadata - client.list_db_nodes( + client.list_odb_subnets( request, metadata=[ ("key", "val"), @@ -43941,14 +63860,14 @@ def test_list_db_nodes_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_gi_versions_rest_bad_request( - request_type=oracledatabase.ListGiVersionsRequest, -): +def test_get_odb_subnet_rest_bad_request(request_type=odb_subnet.GetOdbSubnetRequest): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} + request_init = { + "name": "projects/sample1/locations/sample2/odbNetworks/sample3/odbSubnets/sample4" + } request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -43964,30 +63883,35 @@ def test_list_gi_versions_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_gi_versions(request) + client.get_odb_subnet(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.ListGiVersionsRequest, + odb_subnet.GetOdbSubnetRequest, dict, ], ) -def test_list_gi_versions_rest_call_success(request_type): +def test_get_odb_subnet_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} + request_init = { + "name": "projects/sample1/locations/sample2/odbNetworks/sample3/odbSubnets/sample4" + } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListGiVersionsResponse( - next_page_token="next_page_token_value", + return_value = odb_subnet.OdbSubnet( + name="name_value", + cidr_range="cidr_range_value", + purpose=odb_subnet.OdbSubnet.Purpose.CLIENT_SUBNET, + state=odb_subnet.OdbSubnet.State.PROVISIONING, ) # Wrap the value into a proper Response obj @@ -43995,20 +63919,23 @@ def test_list_gi_versions_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = oracledatabase.ListGiVersionsResponse.pb(return_value) + return_value = odb_subnet.OdbSubnet.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_gi_versions(request) + response = client.get_odb_subnet(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListGiVersionsPager) - assert response.next_page_token == "next_page_token_value" + assert isinstance(response, odb_subnet.OdbSubnet) + assert response.name == "name_value" + assert response.cidr_range == "cidr_range_value" + assert response.purpose == odb_subnet.OdbSubnet.Purpose.CLIENT_SUBNET + assert response.state == odb_subnet.OdbSubnet.State.PROVISIONING @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_gi_versions_rest_interceptors(null_interceptor): +def test_get_odb_subnet_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -44021,22 +63948,20 @@ def test_list_gi_versions_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_list_gi_versions" + transports.OracleDatabaseRestInterceptor, "post_get_odb_subnet" ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_list_gi_versions_with_metadata", + "post_get_odb_subnet_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_list_gi_versions" + transports.OracleDatabaseRestInterceptor, "pre_get_odb_subnet" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.ListGiVersionsRequest.pb( - oracledatabase.ListGiVersionsRequest() - ) + pb_message = odb_subnet.GetOdbSubnetRequest.pb(odb_subnet.GetOdbSubnetRequest()) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -44047,24 +63972,19 @@ def test_list_gi_versions_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = oracledatabase.ListGiVersionsResponse.to_json( - oracledatabase.ListGiVersionsResponse() - ) + return_value = odb_subnet.OdbSubnet.to_json(odb_subnet.OdbSubnet()) req.return_value.content = return_value - request = oracledatabase.ListGiVersionsRequest() + request = odb_subnet.GetOdbSubnetRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = oracledatabase.ListGiVersionsResponse() - post_with_metadata.return_value = ( - oracledatabase.ListGiVersionsResponse(), - metadata, - ) + post.return_value = odb_subnet.OdbSubnet() + post_with_metadata.return_value = odb_subnet.OdbSubnet(), metadata - client.list_gi_versions( + client.get_odb_subnet( request, metadata=[ ("key", "val"), @@ -44077,14 +63997,14 @@ def test_list_gi_versions_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_minor_versions_rest_bad_request( - request_type=minor_version.ListMinorVersionsRequest, +def test_create_odb_subnet_rest_bad_request( + request_type=gco_odb_subnet.CreateOdbSubnetRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2/giVersions/sample3"} + request_init = {"parent": "projects/sample1/locations/sample2/odbNetworks/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -44100,51 +64020,120 @@ def test_list_minor_versions_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_minor_versions(request) + client.create_odb_subnet(request) @pytest.mark.parametrize( "request_type", [ - minor_version.ListMinorVersionsRequest, + gco_odb_subnet.CreateOdbSubnetRequest, dict, ], ) -def test_list_minor_versions_rest_call_success(request_type): +def test_create_odb_subnet_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2/giVersions/sample3"} + request_init = {"parent": "projects/sample1/locations/sample2/odbNetworks/sample3"} + request_init["odb_subnet"] = { + "name": "name_value", + "cidr_range": "cidr_range_value", + "purpose": 1, + "labels": {}, + "create_time": {"seconds": 751, "nanos": 543}, + "state": 1, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = gco_odb_subnet.CreateOdbSubnetRequest.meta.fields["odb_subnet"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["odb_subnet"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["odb_subnet"][field])): + del request_init["odb_subnet"][field][i][subfield] + else: + del request_init["odb_subnet"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = minor_version.ListMinorVersionsResponse( - next_page_token="next_page_token_value", - ) + return_value = operations_pb2.Operation(name="operations/spam") # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = minor_version.ListMinorVersionsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_minor_versions(request) + response = client.create_odb_subnet(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListMinorVersionsPager) - assert response.next_page_token == "next_page_token_value" + json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_minor_versions_rest_interceptors(null_interceptor): +def test_create_odb_subnet_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -44156,22 +64145,23 @@ def test_list_minor_versions_rest_interceptors(null_interceptor): with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_list_minor_versions" + transports.OracleDatabaseRestInterceptor, "post_create_odb_subnet" ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_list_minor_versions_with_metadata", + "post_create_odb_subnet_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_list_minor_versions" + transports.OracleDatabaseRestInterceptor, "pre_create_odb_subnet" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = minor_version.ListMinorVersionsRequest.pb( - minor_version.ListMinorVersionsRequest() + pb_message = gco_odb_subnet.CreateOdbSubnetRequest.pb( + gco_odb_subnet.CreateOdbSubnetRequest() ) transcode.return_value = { "method": "post", @@ -44183,24 +64173,19 @@ def test_list_minor_versions_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = minor_version.ListMinorVersionsResponse.to_json( - minor_version.ListMinorVersionsResponse() - ) + return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = minor_version.ListMinorVersionsRequest() + request = gco_odb_subnet.CreateOdbSubnetRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = minor_version.ListMinorVersionsResponse() - post_with_metadata.return_value = ( - minor_version.ListMinorVersionsResponse(), - metadata, - ) + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.list_minor_versions( + client.create_odb_subnet( request, metadata=[ ("key", "val"), @@ -44213,14 +64198,16 @@ def test_list_minor_versions_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_db_system_shapes_rest_bad_request( - request_type=oracledatabase.ListDbSystemShapesRequest, +def test_delete_odb_subnet_rest_bad_request( + request_type=odb_subnet.DeleteOdbSubnetRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} + request_init = { + "name": "projects/sample1/locations/sample2/odbNetworks/sample3/odbSubnets/sample4" + } request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -44236,51 +64223,47 @@ def test_list_db_system_shapes_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_db_system_shapes(request) + client.delete_odb_subnet(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.ListDbSystemShapesRequest, + odb_subnet.DeleteOdbSubnetRequest, dict, ], ) -def test_list_db_system_shapes_rest_call_success(request_type): +def test_delete_odb_subnet_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} + request_init = { + "name": "projects/sample1/locations/sample2/odbNetworks/sample3/odbSubnets/sample4" + } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListDbSystemShapesResponse( - next_page_token="next_page_token_value", - ) + return_value = operations_pb2.Operation(name="operations/spam") # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = oracledatabase.ListDbSystemShapesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_db_system_shapes(request) + response = client.delete_odb_subnet(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListDbSystemShapesPager) - assert response.next_page_token == "next_page_token_value" + json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_db_system_shapes_rest_interceptors(null_interceptor): +def test_delete_odb_subnet_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -44292,22 +64275,23 @@ def test_list_db_system_shapes_rest_interceptors(null_interceptor): with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_list_db_system_shapes" + transports.OracleDatabaseRestInterceptor, "post_delete_odb_subnet" ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_list_db_system_shapes_with_metadata", + "post_delete_odb_subnet_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_list_db_system_shapes" + transports.OracleDatabaseRestInterceptor, "pre_delete_odb_subnet" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.ListDbSystemShapesRequest.pb( - oracledatabase.ListDbSystemShapesRequest() + pb_message = odb_subnet.DeleteOdbSubnetRequest.pb( + odb_subnet.DeleteOdbSubnetRequest() ) transcode.return_value = { "method": "post", @@ -44319,24 +64303,19 @@ def test_list_db_system_shapes_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = oracledatabase.ListDbSystemShapesResponse.to_json( - oracledatabase.ListDbSystemShapesResponse() - ) + return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = oracledatabase.ListDbSystemShapesRequest() + request = odb_subnet.DeleteOdbSubnetRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = oracledatabase.ListDbSystemShapesResponse() - post_with_metadata.return_value = ( - oracledatabase.ListDbSystemShapesResponse(), - metadata, - ) + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.list_db_system_shapes( + client.delete_odb_subnet( request, metadata=[ ("key", "val"), @@ -44349,8 +64328,8 @@ def test_list_db_system_shapes_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_autonomous_databases_rest_bad_request( - request_type=oracledatabase.ListAutonomousDatabasesRequest, +def test_list_exadb_vm_clusters_rest_bad_request( + request_type=oracledatabase.ListExadbVmClustersRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" @@ -44372,17 +64351,17 @@ def test_list_autonomous_databases_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_autonomous_databases(request) + client.list_exadb_vm_clusters(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.ListAutonomousDatabasesRequest, + oracledatabase.ListExadbVmClustersRequest, dict, ], ) -def test_list_autonomous_databases_rest_call_success(request_type): +def test_list_exadb_vm_clusters_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -44394,8 +64373,9 @@ def test_list_autonomous_databases_rest_call_success(request_type): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListAutonomousDatabasesResponse( + return_value = oracledatabase.ListExadbVmClustersResponse( next_page_token="next_page_token_value", + unreachable=["unreachable_value"], ) # Wrap the value into a proper Response obj @@ -44403,20 +64383,21 @@ def test_list_autonomous_databases_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = oracledatabase.ListAutonomousDatabasesResponse.pb(return_value) + return_value = oracledatabase.ListExadbVmClustersResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_autonomous_databases(request) + response = client.list_exadb_vm_clusters(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListAutonomousDatabasesPager) + assert isinstance(response, pagers.ListExadbVmClustersPager) assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_autonomous_databases_rest_interceptors(null_interceptor): +def test_list_exadb_vm_clusters_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -44429,21 +64410,21 @@ def test_list_autonomous_databases_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_list_autonomous_databases" + transports.OracleDatabaseRestInterceptor, "post_list_exadb_vm_clusters" ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_list_autonomous_databases_with_metadata", + "post_list_exadb_vm_clusters_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_list_autonomous_databases" + transports.OracleDatabaseRestInterceptor, "pre_list_exadb_vm_clusters" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.ListAutonomousDatabasesRequest.pb( - oracledatabase.ListAutonomousDatabasesRequest() + pb_message = oracledatabase.ListExadbVmClustersRequest.pb( + oracledatabase.ListExadbVmClustersRequest() ) transcode.return_value = { "method": "post", @@ -44455,24 +64436,24 @@ def test_list_autonomous_databases_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = oracledatabase.ListAutonomousDatabasesResponse.to_json( - oracledatabase.ListAutonomousDatabasesResponse() + return_value = oracledatabase.ListExadbVmClustersResponse.to_json( + oracledatabase.ListExadbVmClustersResponse() ) req.return_value.content = return_value - request = oracledatabase.ListAutonomousDatabasesRequest() + request = oracledatabase.ListExadbVmClustersRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = oracledatabase.ListAutonomousDatabasesResponse() + post.return_value = oracledatabase.ListExadbVmClustersResponse() post_with_metadata.return_value = ( - oracledatabase.ListAutonomousDatabasesResponse(), + oracledatabase.ListExadbVmClustersResponse(), metadata, ) - client.list_autonomous_databases( + client.list_exadb_vm_clusters( request, metadata=[ ("key", "val"), @@ -44485,15 +64466,15 @@ def test_list_autonomous_databases_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_get_autonomous_database_rest_bad_request( - request_type=oracledatabase.GetAutonomousDatabaseRequest, +def test_get_exadb_vm_cluster_rest_bad_request( + request_type=oracledatabase.GetExadbVmClusterRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + "name": "projects/sample1/locations/sample2/exadbVmClusters/sample3" } request = request_type(**request_init) @@ -44510,44 +64491,38 @@ def test_get_autonomous_database_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_autonomous_database(request) + client.get_exadb_vm_cluster(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.GetAutonomousDatabaseRequest, + oracledatabase.GetExadbVmClusterRequest, dict, ], ) -def test_get_autonomous_database_rest_call_success(request_type): +def test_get_exadb_vm_cluster_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + "name": "projects/sample1/locations/sample2/exadbVmClusters/sample3" } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = autonomous_database.AutonomousDatabase( + return_value = exadb_vm_cluster.ExadbVmCluster( name="name_value", - database="database_value", - display_name="display_name_value", - entitlement_id="entitlement_id_value", - admin_password="admin_password_value", - network="network_value", - cidr="cidr_value", + gcp_oracle_zone="gcp_oracle_zone_value", odb_network="odb_network_value", odb_subnet="odb_subnet_value", - peer_autonomous_databases=["peer_autonomous_databases_value"], - disaster_recovery_supported_locations=[ - "disaster_recovery_supported_locations_value" - ], + backup_odb_subnet="backup_odb_subnet_value", + display_name="display_name_value", + entitlement_id="entitlement_id_value", ) # Wrap the value into a proper Response obj @@ -44555,32 +64530,26 @@ def test_get_autonomous_database_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = autonomous_database.AutonomousDatabase.pb(return_value) + return_value = exadb_vm_cluster.ExadbVmCluster.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_autonomous_database(request) + response = client.get_exadb_vm_cluster(request) # Establish that the response is the type that we expect. - assert isinstance(response, autonomous_database.AutonomousDatabase) + assert isinstance(response, exadb_vm_cluster.ExadbVmCluster) assert response.name == "name_value" - assert response.database == "database_value" - assert response.display_name == "display_name_value" - assert response.entitlement_id == "entitlement_id_value" - assert response.admin_password == "admin_password_value" - assert response.network == "network_value" - assert response.cidr == "cidr_value" + assert response.gcp_oracle_zone == "gcp_oracle_zone_value" assert response.odb_network == "odb_network_value" assert response.odb_subnet == "odb_subnet_value" - assert response.peer_autonomous_databases == ["peer_autonomous_databases_value"] - assert response.disaster_recovery_supported_locations == [ - "disaster_recovery_supported_locations_value" - ] + assert response.backup_odb_subnet == "backup_odb_subnet_value" + assert response.display_name == "display_name_value" + assert response.entitlement_id == "entitlement_id_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_autonomous_database_rest_interceptors(null_interceptor): +def test_get_exadb_vm_cluster_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -44593,21 +64562,21 @@ def test_get_autonomous_database_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_get_autonomous_database" + transports.OracleDatabaseRestInterceptor, "post_get_exadb_vm_cluster" ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_get_autonomous_database_with_metadata", + "post_get_exadb_vm_cluster_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_get_autonomous_database" + transports.OracleDatabaseRestInterceptor, "pre_get_exadb_vm_cluster" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.GetAutonomousDatabaseRequest.pb( - oracledatabase.GetAutonomousDatabaseRequest() + pb_message = oracledatabase.GetExadbVmClusterRequest.pb( + oracledatabase.GetExadbVmClusterRequest() ) transcode.return_value = { "method": "post", @@ -44619,24 +64588,21 @@ def test_get_autonomous_database_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = autonomous_database.AutonomousDatabase.to_json( - autonomous_database.AutonomousDatabase() + return_value = exadb_vm_cluster.ExadbVmCluster.to_json( + exadb_vm_cluster.ExadbVmCluster() ) req.return_value.content = return_value - request = oracledatabase.GetAutonomousDatabaseRequest() + request = oracledatabase.GetExadbVmClusterRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = autonomous_database.AutonomousDatabase() - post_with_metadata.return_value = ( - autonomous_database.AutonomousDatabase(), - metadata, - ) + post.return_value = exadb_vm_cluster.ExadbVmCluster() + post_with_metadata.return_value = exadb_vm_cluster.ExadbVmCluster(), metadata - client.get_autonomous_database( + client.get_exadb_vm_cluster( request, metadata=[ ("key", "val"), @@ -44649,8 +64615,8 @@ def test_get_autonomous_database_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_create_autonomous_database_rest_bad_request( - request_type=oracledatabase.CreateAutonomousDatabaseRequest, +def test_create_exadb_vm_cluster_rest_bad_request( + request_type=oracledatabase.CreateExadbVmClusterRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" @@ -44672,180 +64638,66 @@ def test_create_autonomous_database_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_autonomous_database(request) + client.create_exadb_vm_cluster(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.CreateAutonomousDatabaseRequest, + oracledatabase.CreateExadbVmClusterRequest, dict, ], ) -def test_create_autonomous_database_rest_call_success(request_type): +def test_create_exadb_vm_cluster_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = {"parent": "projects/sample1/locations/sample2"} - request_init["autonomous_database"] = { + request_init["exadb_vm_cluster"] = { "name": "name_value", - "database": "database_value", - "display_name": "display_name_value", - "entitlement_id": "entitlement_id_value", - "admin_password": "admin_password_value", "properties": { - "ocid": "ocid_value", - "compute_count": 0.1413, - "cpu_core_count": 1496, - "data_storage_size_tb": 2109, - "data_storage_size_gb": 2096, - "db_workload": 1, - "db_edition": 1, - "character_set": "character_set_value", - "n_character_set": "n_character_set_value", - "private_endpoint_ip": "private_endpoint_ip_value", - "private_endpoint_label": "private_endpoint_label_value", - "db_version": "db_version_value", - "is_auto_scaling_enabled": True, - "is_storage_auto_scaling_enabled": True, - "license_type": 1, - "customer_contacts": [{"email": "email_value"}], - "secret_id": "secret_id_value", - "vault_id": "vault_id_value", - "maintenance_schedule_type": 1, - "mtls_connection_required": True, - "backup_retention_period_days": 2975, - "actual_used_data_storage_size_tb": 0.3366, - "allocated_storage_size_tb": 0.2636, - "apex_details": { - "apex_version": "apex_version_value", - "ords_version": "ords_version_value", - }, - "are_primary_allowlisted_ips_used": True, - "lifecycle_details": "lifecycle_details_value", - "state": 1, - "autonomous_container_database_id": "autonomous_container_database_id_value", - "available_upgrade_versions": [ - "available_upgrade_versions_value1", - "available_upgrade_versions_value2", - ], - "connection_strings": { - "all_connection_strings": { - "high": "high_value", - "low": "low_value", - "medium": "medium_value", - }, - "dedicated": "dedicated_value", - "high": "high_value", - "low": "low_value", - "medium": "medium_value", - "profiles": [ - { - "consumer_group": 1, - "display_name": "display_name_value", - "host_format": 1, - "is_regional": True, - "protocol": 1, - "session_mode": 1, - "syntax_format": 1, - "tls_authentication": 1, - "value": "value_value", - } - ], - }, - "connection_urls": { - "apex_uri": "apex_uri_value", - "database_transforms_uri": "database_transforms_uri_value", - "graph_studio_uri": "graph_studio_uri_value", - "machine_learning_notebook_uri": "machine_learning_notebook_uri_value", - "machine_learning_user_management_uri": "machine_learning_user_management_uri_value", - "mongo_db_uri": "mongo_db_uri_value", - "ords_uri": "ords_uri_value", - "sql_dev_web_uri": "sql_dev_web_uri_value", - }, - "failed_data_recovery_duration": {"seconds": 751, "nanos": 543}, - "memory_table_gbs": 1691, - "is_local_data_guard_enabled": True, - "local_adg_auto_failover_max_data_loss_limit": 4513, - "local_standby_db": { - "lag_time_duration": {}, - "lifecycle_details": "lifecycle_details_value", - "state": 1, - "data_guard_role_changed_time": {"seconds": 751, "nanos": 543}, - "disaster_recovery_role_changed_time": {}, + "cluster_name": "cluster_name_value", + "grid_image_id": "grid_image_id_value", + "node_count": 1070, + "enabled_ecpu_count_per_node": 2826, + "additional_ecpu_count_per_node": 3160, + "vm_file_system_storage": {"size_in_gbs_per_node": 2103}, + "license_model": 1, + "exascale_db_storage_vault": "exascale_db_storage_vault_value", + "hostname_prefix": "hostname_prefix_value", + "hostname": "hostname_value", + "ssh_public_keys": ["ssh_public_keys_value1", "ssh_public_keys_value2"], + "data_collection_options": { + "is_diagnostics_events_enabled": True, + "is_health_monitoring_enabled": True, + "is_incident_logs_enabled": True, }, - "memory_per_oracle_compute_unit_gbs": 3626, - "local_disaster_recovery_type": 1, - "data_safe_state": 1, - "database_management_state": 1, - "open_mode": 1, - "operations_insights_state": 1, - "peer_db_ids": ["peer_db_ids_value1", "peer_db_ids_value2"], - "permission_level": 1, - "private_endpoint": "private_endpoint_value", - "refreshable_mode": 1, - "refreshable_state": 1, - "role": 1, - "scheduled_operation_details": [ - { - "day_of_week": 1, - "start_time": { - "hours": 561, - "minutes": 773, - "seconds": 751, - "nanos": 543, - }, - "stop_time": {}, - } - ], - "sql_web_developer_url": "sql_web_developer_url_value", - "supported_clone_regions": [ - "supported_clone_regions_value1", - "supported_clone_regions_value2", - ], - "used_data_storage_size_tbs": 2752, - "oci_url": "oci_url_value", - "total_auto_backup_storage_size_gbs": 0.36100000000000004, - "next_long_term_backup_time": {}, - "data_guard_role_changed_time": {}, - "disaster_recovery_role_changed_time": {}, - "maintenance_begin_time": {}, - "maintenance_end_time": {}, - "allowlisted_ips": ["allowlisted_ips_value1", "allowlisted_ips_value2"], - "encryption_key": {"provider": 1, "kms_key": "kms_key_value"}, - "encryption_key_history_entries": [ - {"encryption_key": {}, "activation_time": {}} - ], - "service_agent_email": "service_agent_email_value", + "time_zone": {"id": "id_value", "version": "version_value"}, + "lifecycle_state": 1, + "shape_attribute": 1, + "memory_size_gb": 1499, + "scan_listener_port_tcp": 2356, + "oci_uri": "oci_uri_value", + "gi_version": "gi_version_value", }, + "gcp_oracle_zone": "gcp_oracle_zone_value", "labels": {}, - "network": "network_value", - "cidr": "cidr_value", "odb_network": "odb_network_value", "odb_subnet": "odb_subnet_value", - "source_config": { - "autonomous_database": "autonomous_database_value", - "automatic_backups_replication_enabled": True, - }, - "peer_autonomous_databases": [ - "peer_autonomous_databases_value1", - "peer_autonomous_databases_value2", - ], - "create_time": {}, - "disaster_recovery_supported_locations": [ - "disaster_recovery_supported_locations_value1", - "disaster_recovery_supported_locations_value2", - ], + "backup_odb_subnet": "backup_odb_subnet_value", + "display_name": "display_name_value", + "create_time": {"seconds": 751, "nanos": 543}, + "entitlement_id": "entitlement_id_value", } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = oracledatabase.CreateAutonomousDatabaseRequest.meta.fields[ - "autonomous_database" + test_field = oracledatabase.CreateExadbVmClusterRequest.meta.fields[ + "exadb_vm_cluster" ] def get_message_fields(field): @@ -44874,7 +64726,7 @@ def get_message_fields(field): # For each item in the sample request, create a list of sub fields which are not present at runtime # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["autonomous_database"].items(): # pragma: NO COVER + for field, value in request_init["exadb_vm_cluster"].items(): # pragma: NO COVER result = None is_repeated = False # For repeated fields @@ -44904,10 +64756,10 @@ def get_message_fields(field): subfield = subfield_to_delete.get("subfield") if subfield: if field_repeated: - for i in range(0, len(request_init["autonomous_database"][field])): - del request_init["autonomous_database"][field][i][subfield] + for i in range(0, len(request_init["exadb_vm_cluster"][field])): + del request_init["exadb_vm_cluster"][field][i][subfield] else: - del request_init["autonomous_database"][field][subfield] + del request_init["exadb_vm_cluster"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -44922,14 +64774,14 @@ def get_message_fields(field): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_autonomous_database(request) + response = client.create_exadb_vm_cluster(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_autonomous_database_rest_interceptors(null_interceptor): +def test_create_exadb_vm_cluster_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -44943,21 +64795,21 @@ def test_create_autonomous_database_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_create_autonomous_database" + transports.OracleDatabaseRestInterceptor, "post_create_exadb_vm_cluster" ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_create_autonomous_database_with_metadata", + "post_create_exadb_vm_cluster_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_create_autonomous_database" + transports.OracleDatabaseRestInterceptor, "pre_create_exadb_vm_cluster" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.CreateAutonomousDatabaseRequest.pb( - oracledatabase.CreateAutonomousDatabaseRequest() + pb_message = oracledatabase.CreateExadbVmClusterRequest.pb( + oracledatabase.CreateExadbVmClusterRequest() ) transcode.return_value = { "method": "post", @@ -44972,7 +64824,7 @@ def test_create_autonomous_database_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = oracledatabase.CreateAutonomousDatabaseRequest() + request = oracledatabase.CreateExadbVmClusterRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -44981,7 +64833,7 @@ def test_create_autonomous_database_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.create_autonomous_database( + client.create_exadb_vm_cluster( request, metadata=[ ("key", "val"), @@ -44994,273 +64846,50 @@ def test_create_autonomous_database_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_update_autonomous_database_rest_bad_request( - request_type=oracledatabase.UpdateAutonomousDatabaseRequest, -): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - # send a request that will satisfy transcoding - request_init = { - "autonomous_database": { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" - } - } - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with ( - mock.patch.object(Session, "request") as req, - pytest.raises(core_exceptions.BadRequest), - ): - # Wrap the value into a proper Response obj - response_value = mock.Mock() - json_return_value = "" - response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_autonomous_database(request) - - -@pytest.mark.parametrize( - "request_type", - [ - oracledatabase.UpdateAutonomousDatabaseRequest, - dict, - ], -) -def test_update_autonomous_database_rest_call_success(request_type): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - # send a request that will satisfy transcoding - request_init = { - "autonomous_database": { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" - } - } - request_init["autonomous_database"] = { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3", - "database": "database_value", - "display_name": "display_name_value", - "entitlement_id": "entitlement_id_value", - "admin_password": "admin_password_value", - "properties": { - "ocid": "ocid_value", - "compute_count": 0.1413, - "cpu_core_count": 1496, - "data_storage_size_tb": 2109, - "data_storage_size_gb": 2096, - "db_workload": 1, - "db_edition": 1, - "character_set": "character_set_value", - "n_character_set": "n_character_set_value", - "private_endpoint_ip": "private_endpoint_ip_value", - "private_endpoint_label": "private_endpoint_label_value", - "db_version": "db_version_value", - "is_auto_scaling_enabled": True, - "is_storage_auto_scaling_enabled": True, - "license_type": 1, - "customer_contacts": [{"email": "email_value"}], - "secret_id": "secret_id_value", - "vault_id": "vault_id_value", - "maintenance_schedule_type": 1, - "mtls_connection_required": True, - "backup_retention_period_days": 2975, - "actual_used_data_storage_size_tb": 0.3366, - "allocated_storage_size_tb": 0.2636, - "apex_details": { - "apex_version": "apex_version_value", - "ords_version": "ords_version_value", - }, - "are_primary_allowlisted_ips_used": True, - "lifecycle_details": "lifecycle_details_value", - "state": 1, - "autonomous_container_database_id": "autonomous_container_database_id_value", - "available_upgrade_versions": [ - "available_upgrade_versions_value1", - "available_upgrade_versions_value2", - ], - "connection_strings": { - "all_connection_strings": { - "high": "high_value", - "low": "low_value", - "medium": "medium_value", - }, - "dedicated": "dedicated_value", - "high": "high_value", - "low": "low_value", - "medium": "medium_value", - "profiles": [ - { - "consumer_group": 1, - "display_name": "display_name_value", - "host_format": 1, - "is_regional": True, - "protocol": 1, - "session_mode": 1, - "syntax_format": 1, - "tls_authentication": 1, - "value": "value_value", - } - ], - }, - "connection_urls": { - "apex_uri": "apex_uri_value", - "database_transforms_uri": "database_transforms_uri_value", - "graph_studio_uri": "graph_studio_uri_value", - "machine_learning_notebook_uri": "machine_learning_notebook_uri_value", - "machine_learning_user_management_uri": "machine_learning_user_management_uri_value", - "mongo_db_uri": "mongo_db_uri_value", - "ords_uri": "ords_uri_value", - "sql_dev_web_uri": "sql_dev_web_uri_value", - }, - "failed_data_recovery_duration": {"seconds": 751, "nanos": 543}, - "memory_table_gbs": 1691, - "is_local_data_guard_enabled": True, - "local_adg_auto_failover_max_data_loss_limit": 4513, - "local_standby_db": { - "lag_time_duration": {}, - "lifecycle_details": "lifecycle_details_value", - "state": 1, - "data_guard_role_changed_time": {"seconds": 751, "nanos": 543}, - "disaster_recovery_role_changed_time": {}, - }, - "memory_per_oracle_compute_unit_gbs": 3626, - "local_disaster_recovery_type": 1, - "data_safe_state": 1, - "database_management_state": 1, - "open_mode": 1, - "operations_insights_state": 1, - "peer_db_ids": ["peer_db_ids_value1", "peer_db_ids_value2"], - "permission_level": 1, - "private_endpoint": "private_endpoint_value", - "refreshable_mode": 1, - "refreshable_state": 1, - "role": 1, - "scheduled_operation_details": [ - { - "day_of_week": 1, - "start_time": { - "hours": 561, - "minutes": 773, - "seconds": 751, - "nanos": 543, - }, - "stop_time": {}, - } - ], - "sql_web_developer_url": "sql_web_developer_url_value", - "supported_clone_regions": [ - "supported_clone_regions_value1", - "supported_clone_regions_value2", - ], - "used_data_storage_size_tbs": 2752, - "oci_url": "oci_url_value", - "total_auto_backup_storage_size_gbs": 0.36100000000000004, - "next_long_term_backup_time": {}, - "data_guard_role_changed_time": {}, - "disaster_recovery_role_changed_time": {}, - "maintenance_begin_time": {}, - "maintenance_end_time": {}, - "allowlisted_ips": ["allowlisted_ips_value1", "allowlisted_ips_value2"], - "encryption_key": {"provider": 1, "kms_key": "kms_key_value"}, - "encryption_key_history_entries": [ - {"encryption_key": {}, "activation_time": {}} - ], - "service_agent_email": "service_agent_email_value", - }, - "labels": {}, - "network": "network_value", - "cidr": "cidr_value", - "odb_network": "odb_network_value", - "odb_subnet": "odb_subnet_value", - "source_config": { - "autonomous_database": "autonomous_database_value", - "automatic_backups_replication_enabled": True, - }, - "peer_autonomous_databases": [ - "peer_autonomous_databases_value1", - "peer_autonomous_databases_value2", - ], - "create_time": {}, - "disaster_recovery_supported_locations": [ - "disaster_recovery_supported_locations_value1", - "disaster_recovery_supported_locations_value2", - ], - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = oracledatabase.UpdateAutonomousDatabaseRequest.meta.fields[ - "autonomous_database" - ] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] +def test_delete_exadb_vm_cluster_rest_bad_request( + request_type=oracledatabase.DeleteExadbVmClusterRequest, +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/exadbVmClusters/sample3" + } + request = request_type(**request_init) - subfields_not_in_runtime = [] + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.delete_exadb_vm_cluster(request) - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["autonomous_database"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) +@pytest.mark.parametrize( + "request_type", + [ + oracledatabase.DeleteExadbVmClusterRequest, + dict, + ], +) +def test_delete_exadb_vm_cluster_rest_call_success(request_type): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["autonomous_database"][field])): - del request_init["autonomous_database"][field][i][subfield] - else: - del request_init["autonomous_database"][field][subfield] + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/exadbVmClusters/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -45275,14 +64904,14 @@ def get_message_fields(field): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_autonomous_database(request) + response = client.delete_exadb_vm_cluster(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_autonomous_database_rest_interceptors(null_interceptor): +def test_delete_exadb_vm_cluster_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -45296,21 +64925,21 @@ def test_update_autonomous_database_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_update_autonomous_database" + transports.OracleDatabaseRestInterceptor, "post_delete_exadb_vm_cluster" ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_update_autonomous_database_with_metadata", + "post_delete_exadb_vm_cluster_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_update_autonomous_database" + transports.OracleDatabaseRestInterceptor, "pre_delete_exadb_vm_cluster" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.UpdateAutonomousDatabaseRequest.pb( - oracledatabase.UpdateAutonomousDatabaseRequest() + pb_message = oracledatabase.DeleteExadbVmClusterRequest.pb( + oracledatabase.DeleteExadbVmClusterRequest() ) transcode.return_value = { "method": "post", @@ -45325,7 +64954,7 @@ def test_update_autonomous_database_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = oracledatabase.UpdateAutonomousDatabaseRequest() + request = oracledatabase.DeleteExadbVmClusterRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -45334,7 +64963,7 @@ def test_update_autonomous_database_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.update_autonomous_database( + client.delete_exadb_vm_cluster( request, metadata=[ ("key", "val"), @@ -45347,15 +64976,17 @@ def test_update_autonomous_database_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_delete_autonomous_database_rest_bad_request( - request_type=oracledatabase.DeleteAutonomousDatabaseRequest, +def test_update_exadb_vm_cluster_rest_bad_request( + request_type=oracledatabase.UpdateExadbVmClusterRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + "exadb_vm_cluster": { + "name": "projects/sample1/locations/sample2/exadbVmClusters/sample3" + } } request = request_type(**request_init) @@ -45372,25 +65003,132 @@ def test_delete_autonomous_database_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_autonomous_database(request) + client.update_exadb_vm_cluster(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.DeleteAutonomousDatabaseRequest, + oracledatabase.UpdateExadbVmClusterRequest, dict, ], ) -def test_delete_autonomous_database_rest_call_success(request_type): +def test_update_exadb_vm_cluster_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + "exadb_vm_cluster": { + "name": "projects/sample1/locations/sample2/exadbVmClusters/sample3" + } + } + request_init["exadb_vm_cluster"] = { + "name": "projects/sample1/locations/sample2/exadbVmClusters/sample3", + "properties": { + "cluster_name": "cluster_name_value", + "grid_image_id": "grid_image_id_value", + "node_count": 1070, + "enabled_ecpu_count_per_node": 2826, + "additional_ecpu_count_per_node": 3160, + "vm_file_system_storage": {"size_in_gbs_per_node": 2103}, + "license_model": 1, + "exascale_db_storage_vault": "exascale_db_storage_vault_value", + "hostname_prefix": "hostname_prefix_value", + "hostname": "hostname_value", + "ssh_public_keys": ["ssh_public_keys_value1", "ssh_public_keys_value2"], + "data_collection_options": { + "is_diagnostics_events_enabled": True, + "is_health_monitoring_enabled": True, + "is_incident_logs_enabled": True, + }, + "time_zone": {"id": "id_value", "version": "version_value"}, + "lifecycle_state": 1, + "shape_attribute": 1, + "memory_size_gb": 1499, + "scan_listener_port_tcp": 2356, + "oci_uri": "oci_uri_value", + "gi_version": "gi_version_value", + }, + "gcp_oracle_zone": "gcp_oracle_zone_value", + "labels": {}, + "odb_network": "odb_network_value", + "odb_subnet": "odb_subnet_value", + "backup_odb_subnet": "backup_odb_subnet_value", + "display_name": "display_name_value", + "create_time": {"seconds": 751, "nanos": 543}, + "entitlement_id": "entitlement_id_value", } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = oracledatabase.UpdateExadbVmClusterRequest.meta.fields[ + "exadb_vm_cluster" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["exadb_vm_cluster"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["exadb_vm_cluster"][field])): + del request_init["exadb_vm_cluster"][field][i][subfield] + else: + del request_init["exadb_vm_cluster"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -45405,14 +65143,14 @@ def test_delete_autonomous_database_rest_call_success(request_type): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_autonomous_database(request) + response = client.update_exadb_vm_cluster(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_autonomous_database_rest_interceptors(null_interceptor): +def test_update_exadb_vm_cluster_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -45426,21 +65164,21 @@ def test_delete_autonomous_database_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_delete_autonomous_database" + transports.OracleDatabaseRestInterceptor, "post_update_exadb_vm_cluster" ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_delete_autonomous_database_with_metadata", + "post_update_exadb_vm_cluster_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_delete_autonomous_database" + transports.OracleDatabaseRestInterceptor, "pre_update_exadb_vm_cluster" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.DeleteAutonomousDatabaseRequest.pb( - oracledatabase.DeleteAutonomousDatabaseRequest() + pb_message = oracledatabase.UpdateExadbVmClusterRequest.pb( + oracledatabase.UpdateExadbVmClusterRequest() ) transcode.return_value = { "method": "post", @@ -45455,7 +65193,7 @@ def test_delete_autonomous_database_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = oracledatabase.DeleteAutonomousDatabaseRequest() + request = oracledatabase.UpdateExadbVmClusterRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -45464,7 +65202,7 @@ def test_delete_autonomous_database_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.delete_autonomous_database( + client.update_exadb_vm_cluster( request, metadata=[ ("key", "val"), @@ -45477,15 +65215,15 @@ def test_delete_autonomous_database_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_restore_autonomous_database_rest_bad_request( - request_type=oracledatabase.RestoreAutonomousDatabaseRequest, +def test_remove_virtual_machine_exadb_vm_cluster_rest_bad_request( + request_type=oracledatabase.RemoveVirtualMachineExadbVmClusterRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + "name": "projects/sample1/locations/sample2/exadbVmClusters/sample3" } request = request_type(**request_init) @@ -45502,24 +65240,24 @@ def test_restore_autonomous_database_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.restore_autonomous_database(request) + client.remove_virtual_machine_exadb_vm_cluster(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.RestoreAutonomousDatabaseRequest, + oracledatabase.RemoveVirtualMachineExadbVmClusterRequest, dict, ], ) -def test_restore_autonomous_database_rest_call_success(request_type): +def test_remove_virtual_machine_exadb_vm_cluster_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + "name": "projects/sample1/locations/sample2/exadbVmClusters/sample3" } request = request_type(**request_init) @@ -45535,14 +65273,14 @@ def test_restore_autonomous_database_rest_call_success(request_type): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.restore_autonomous_database(request) + response = client.remove_virtual_machine_exadb_vm_cluster(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_restore_autonomous_database_rest_interceptors(null_interceptor): +def test_remove_virtual_machine_exadb_vm_cluster_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -45556,21 +65294,23 @@ def test_restore_autonomous_database_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_restore_autonomous_database" + transports.OracleDatabaseRestInterceptor, + "post_remove_virtual_machine_exadb_vm_cluster", ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_restore_autonomous_database_with_metadata", + "post_remove_virtual_machine_exadb_vm_cluster_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_restore_autonomous_database" + transports.OracleDatabaseRestInterceptor, + "pre_remove_virtual_machine_exadb_vm_cluster", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.RestoreAutonomousDatabaseRequest.pb( - oracledatabase.RestoreAutonomousDatabaseRequest() + pb_message = oracledatabase.RemoveVirtualMachineExadbVmClusterRequest.pb( + oracledatabase.RemoveVirtualMachineExadbVmClusterRequest() ) transcode.return_value = { "method": "post", @@ -45585,7 +65325,7 @@ def test_restore_autonomous_database_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = oracledatabase.RestoreAutonomousDatabaseRequest() + request = oracledatabase.RemoveVirtualMachineExadbVmClusterRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -45594,7 +65334,7 @@ def test_restore_autonomous_database_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.restore_autonomous_database( + client.remove_virtual_machine_exadb_vm_cluster( request, metadata=[ ("key", "val"), @@ -45607,16 +65347,14 @@ def test_restore_autonomous_database_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_generate_autonomous_database_wallet_rest_bad_request( - request_type=oracledatabase.GenerateAutonomousDatabaseWalletRequest, +def test_list_exascale_db_storage_vaults_rest_bad_request( + request_type=exascale_db_storage_vault.ListExascaleDbStorageVaultsRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" - } + request_init = {"parent": "projects/sample1/locations/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -45632,32 +65370,31 @@ def test_generate_autonomous_database_wallet_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.generate_autonomous_database_wallet(request) + client.list_exascale_db_storage_vaults(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.GenerateAutonomousDatabaseWalletRequest, + exascale_db_storage_vault.ListExascaleDbStorageVaultsRequest, dict, ], ) -def test_generate_autonomous_database_wallet_rest_call_success(request_type): +def test_list_exascale_db_storage_vaults_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" - } + request_init = {"parent": "projects/sample1/locations/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = oracledatabase.GenerateAutonomousDatabaseWalletResponse( - archive_content=b"archive_content_blob", + return_value = exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], ) # Wrap the value into a proper Response obj @@ -45665,22 +65402,23 @@ def test_generate_autonomous_database_wallet_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = oracledatabase.GenerateAutonomousDatabaseWalletResponse.pb( + return_value = exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse.pb( return_value ) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.generate_autonomous_database_wallet(request) + response = client.list_exascale_db_storage_vaults(request) # Establish that the response is the type that we expect. - assert isinstance(response, oracledatabase.GenerateAutonomousDatabaseWalletResponse) - assert response.archive_content == b"archive_content_blob" + assert isinstance(response, pagers.ListExascaleDbStorageVaultsPager) + assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_generate_autonomous_database_wallet_rest_interceptors(null_interceptor): +def test_list_exascale_db_storage_vaults_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -45694,22 +65432,22 @@ def test_generate_autonomous_database_wallet_rest_interceptors(null_interceptor) mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_generate_autonomous_database_wallet", + "post_list_exascale_db_storage_vaults", ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_generate_autonomous_database_wallet_with_metadata", + "post_list_exascale_db_storage_vaults_with_metadata", ) as post_with_metadata, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "pre_generate_autonomous_database_wallet", + "pre_list_exascale_db_storage_vaults", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.GenerateAutonomousDatabaseWalletRequest.pb( - oracledatabase.GenerateAutonomousDatabaseWalletRequest() + pb_message = exascale_db_storage_vault.ListExascaleDbStorageVaultsRequest.pb( + exascale_db_storage_vault.ListExascaleDbStorageVaultsRequest() ) transcode.return_value = { "method": "post", @@ -45721,24 +65459,28 @@ def test_generate_autonomous_database_wallet_rest_interceptors(null_interceptor) req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = oracledatabase.GenerateAutonomousDatabaseWalletResponse.to_json( - oracledatabase.GenerateAutonomousDatabaseWalletResponse() + return_value = ( + exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse.to_json( + exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse() + ) ) req.return_value.content = return_value - request = oracledatabase.GenerateAutonomousDatabaseWalletRequest() + request = exascale_db_storage_vault.ListExascaleDbStorageVaultsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = oracledatabase.GenerateAutonomousDatabaseWalletResponse() + post.return_value = ( + exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse() + ) post_with_metadata.return_value = ( - oracledatabase.GenerateAutonomousDatabaseWalletResponse(), + exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse(), metadata, ) - client.generate_autonomous_database_wallet( + client.list_exascale_db_storage_vaults( request, metadata=[ ("key", "val"), @@ -45751,14 +65493,16 @@ def test_generate_autonomous_database_wallet_rest_interceptors(null_interceptor) post_with_metadata.assert_called_once() -def test_list_autonomous_db_versions_rest_bad_request( - request_type=oracledatabase.ListAutonomousDbVersionsRequest, +def test_get_exascale_db_storage_vault_rest_bad_request( + request_type=exascale_db_storage_vault.GetExascaleDbStorageVaultRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} + request_init = { + "name": "projects/sample1/locations/sample2/exascaleDbStorageVaults/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -45774,30 +65518,35 @@ def test_list_autonomous_db_versions_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_autonomous_db_versions(request) + client.get_exascale_db_storage_vault(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.ListAutonomousDbVersionsRequest, + exascale_db_storage_vault.GetExascaleDbStorageVaultRequest, dict, ], ) -def test_list_autonomous_db_versions_rest_call_success(request_type): +def test_get_exascale_db_storage_vault_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} + request_init = { + "name": "projects/sample1/locations/sample2/exascaleDbStorageVaults/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListAutonomousDbVersionsResponse( - next_page_token="next_page_token_value", + return_value = exascale_db_storage_vault.ExascaleDbStorageVault( + name="name_value", + display_name="display_name_value", + gcp_oracle_zone="gcp_oracle_zone_value", + entitlement_id="entitlement_id_value", ) # Wrap the value into a proper Response obj @@ -45805,20 +65554,23 @@ def test_list_autonomous_db_versions_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = oracledatabase.ListAutonomousDbVersionsResponse.pb(return_value) + return_value = exascale_db_storage_vault.ExascaleDbStorageVault.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_autonomous_db_versions(request) + response = client.get_exascale_db_storage_vault(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListAutonomousDbVersionsPager) - assert response.next_page_token == "next_page_token_value" + assert isinstance(response, exascale_db_storage_vault.ExascaleDbStorageVault) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.gcp_oracle_zone == "gcp_oracle_zone_value" + assert response.entitlement_id == "entitlement_id_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_autonomous_db_versions_rest_interceptors(null_interceptor): +def test_get_exascale_db_storage_vault_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -45831,21 +65583,23 @@ def test_list_autonomous_db_versions_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_list_autonomous_db_versions" + transports.OracleDatabaseRestInterceptor, + "post_get_exascale_db_storage_vault", ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_list_autonomous_db_versions_with_metadata", + "post_get_exascale_db_storage_vault_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_list_autonomous_db_versions" + transports.OracleDatabaseRestInterceptor, + "pre_get_exascale_db_storage_vault", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.ListAutonomousDbVersionsRequest.pb( - oracledatabase.ListAutonomousDbVersionsRequest() + pb_message = exascale_db_storage_vault.GetExascaleDbStorageVaultRequest.pb( + exascale_db_storage_vault.GetExascaleDbStorageVaultRequest() ) transcode.return_value = { "method": "post", @@ -45857,24 +65611,24 @@ def test_list_autonomous_db_versions_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = oracledatabase.ListAutonomousDbVersionsResponse.to_json( - oracledatabase.ListAutonomousDbVersionsResponse() + return_value = exascale_db_storage_vault.ExascaleDbStorageVault.to_json( + exascale_db_storage_vault.ExascaleDbStorageVault() ) req.return_value.content = return_value - request = oracledatabase.ListAutonomousDbVersionsRequest() + request = exascale_db_storage_vault.GetExascaleDbStorageVaultRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = oracledatabase.ListAutonomousDbVersionsResponse() + post.return_value = exascale_db_storage_vault.ExascaleDbStorageVault() post_with_metadata.return_value = ( - oracledatabase.ListAutonomousDbVersionsResponse(), + exascale_db_storage_vault.ExascaleDbStorageVault(), metadata, ) - client.list_autonomous_db_versions( + client.get_exascale_db_storage_vault( request, metadata=[ ("key", "val"), @@ -45887,8 +65641,8 @@ def test_list_autonomous_db_versions_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_autonomous_database_character_sets_rest_bad_request( - request_type=oracledatabase.ListAutonomousDatabaseCharacterSetsRequest, +def test_create_exascale_db_storage_vault_rest_bad_request( + request_type=gco_exascale_db_storage_vault.CreateExascaleDbStorageVaultRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" @@ -45910,53 +65664,144 @@ def test_list_autonomous_database_character_sets_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_autonomous_database_character_sets(request) + client.create_exascale_db_storage_vault(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.ListAutonomousDatabaseCharacterSetsRequest, + gco_exascale_db_storage_vault.CreateExascaleDbStorageVaultRequest, dict, ], ) -def test_list_autonomous_database_character_sets_rest_call_success(request_type): +def test_create_exascale_db_storage_vault_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = {"parent": "projects/sample1/locations/sample2"} + request_init["exascale_db_storage_vault"] = { + "name": "name_value", + "display_name": "display_name_value", + "gcp_oracle_zone": "gcp_oracle_zone_value", + "properties": { + "ocid": "ocid_value", + "time_zone": {"id": "id_value", "version": "version_value"}, + "exascale_db_storage_details": { + "available_size_gbs": 1878, + "total_size_gbs": 1497, + }, + "state": 1, + "description": "description_value", + "vm_cluster_ids": ["vm_cluster_ids_value1", "vm_cluster_ids_value2"], + "vm_cluster_count": 1740, + "additional_flash_cache_percent": 3113, + "oci_uri": "oci_uri_value", + "attached_shape_attributes": [1], + "available_shape_attributes": [1], + }, + "create_time": {"seconds": 751, "nanos": 543}, + "entitlement_id": "entitlement_id_value", + "labels": {}, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = ( + gco_exascale_db_storage_vault.CreateExascaleDbStorageVaultRequest.meta.fields[ + "exascale_db_storage_vault" + ] + ) + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init[ + "exascale_db_storage_vault" + ].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range( + 0, len(request_init["exascale_db_storage_vault"][field]) + ): + del request_init["exascale_db_storage_vault"][field][i][subfield] + else: + del request_init["exascale_db_storage_vault"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListAutonomousDatabaseCharacterSetsResponse( - next_page_token="next_page_token_value", - ) + return_value = operations_pb2.Operation(name="operations/spam") # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = oracledatabase.ListAutonomousDatabaseCharacterSetsResponse.pb( - return_value - ) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_autonomous_database_character_sets(request) + response = client.create_exascale_db_storage_vault(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListAutonomousDatabaseCharacterSetsPager) - assert response.next_page_token == "next_page_token_value" + json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_autonomous_database_character_sets_rest_interceptors(null_interceptor): +def test_create_exascale_db_storage_vault_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -45968,24 +65813,27 @@ def test_list_autonomous_database_character_sets_rest_interceptors(null_intercep with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_list_autonomous_database_character_sets", + "post_create_exascale_db_storage_vault", ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_list_autonomous_database_character_sets_with_metadata", + "post_create_exascale_db_storage_vault_with_metadata", ) as post_with_metadata, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "pre_list_autonomous_database_character_sets", + "pre_create_exascale_db_storage_vault", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.ListAutonomousDatabaseCharacterSetsRequest.pb( - oracledatabase.ListAutonomousDatabaseCharacterSetsRequest() + pb_message = ( + gco_exascale_db_storage_vault.CreateExascaleDbStorageVaultRequest.pb( + gco_exascale_db_storage_vault.CreateExascaleDbStorageVaultRequest() + ) ) transcode.return_value = { "method": "post", @@ -45997,26 +65845,19 @@ def test_list_autonomous_database_character_sets_rest_interceptors(null_intercep req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = ( - oracledatabase.ListAutonomousDatabaseCharacterSetsResponse.to_json( - oracledatabase.ListAutonomousDatabaseCharacterSetsResponse() - ) - ) + return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = oracledatabase.ListAutonomousDatabaseCharacterSetsRequest() + request = gco_exascale_db_storage_vault.CreateExascaleDbStorageVaultRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = oracledatabase.ListAutonomousDatabaseCharacterSetsResponse() - post_with_metadata.return_value = ( - oracledatabase.ListAutonomousDatabaseCharacterSetsResponse(), - metadata, - ) + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.list_autonomous_database_character_sets( + client.create_exascale_db_storage_vault( request, metadata=[ ("key", "val"), @@ -46029,14 +65870,16 @@ def test_list_autonomous_database_character_sets_rest_interceptors(null_intercep post_with_metadata.assert_called_once() -def test_list_autonomous_database_backups_rest_bad_request( - request_type=oracledatabase.ListAutonomousDatabaseBackupsRequest, +def test_delete_exascale_db_storage_vault_rest_bad_request( + request_type=exascale_db_storage_vault.DeleteExascaleDbStorageVaultRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} + request_init = { + "name": "projects/sample1/locations/sample2/exascaleDbStorageVaults/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -46052,53 +65895,47 @@ def test_list_autonomous_database_backups_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_autonomous_database_backups(request) + client.delete_exascale_db_storage_vault(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.ListAutonomousDatabaseBackupsRequest, + exascale_db_storage_vault.DeleteExascaleDbStorageVaultRequest, dict, ], ) -def test_list_autonomous_database_backups_rest_call_success(request_type): +def test_delete_exascale_db_storage_vault_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} + request_init = { + "name": "projects/sample1/locations/sample2/exascaleDbStorageVaults/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListAutonomousDatabaseBackupsResponse( - next_page_token="next_page_token_value", - ) + return_value = operations_pb2.Operation(name="operations/spam") # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = oracledatabase.ListAutonomousDatabaseBackupsResponse.pb( - return_value - ) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_autonomous_database_backups(request) + response = client.delete_exascale_db_storage_vault(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListAutonomousDatabaseBackupsPager) - assert response.next_page_token == "next_page_token_value" + json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_autonomous_database_backups_rest_interceptors(null_interceptor): +def test_delete_exascale_db_storage_vault_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -46110,24 +65947,25 @@ def test_list_autonomous_database_backups_rest_interceptors(null_interceptor): with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_list_autonomous_database_backups", + "post_delete_exascale_db_storage_vault", ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_list_autonomous_database_backups_with_metadata", + "post_delete_exascale_db_storage_vault_with_metadata", ) as post_with_metadata, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "pre_list_autonomous_database_backups", + "pre_delete_exascale_db_storage_vault", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.ListAutonomousDatabaseBackupsRequest.pb( - oracledatabase.ListAutonomousDatabaseBackupsRequest() + pb_message = exascale_db_storage_vault.DeleteExascaleDbStorageVaultRequest.pb( + exascale_db_storage_vault.DeleteExascaleDbStorageVaultRequest() ) transcode.return_value = { "method": "post", @@ -46139,24 +65977,19 @@ def test_list_autonomous_database_backups_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = oracledatabase.ListAutonomousDatabaseBackupsResponse.to_json( - oracledatabase.ListAutonomousDatabaseBackupsResponse() - ) + return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = oracledatabase.ListAutonomousDatabaseBackupsRequest() + request = exascale_db_storage_vault.DeleteExascaleDbStorageVaultRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = oracledatabase.ListAutonomousDatabaseBackupsResponse() - post_with_metadata.return_value = ( - oracledatabase.ListAutonomousDatabaseBackupsResponse(), - metadata, - ) + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.list_autonomous_database_backups( + client.delete_exascale_db_storage_vault( request, metadata=[ ("key", "val"), @@ -46169,16 +66002,14 @@ def test_list_autonomous_database_backups_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_stop_autonomous_database_rest_bad_request( - request_type=oracledatabase.StopAutonomousDatabaseRequest, +def test_list_db_system_initial_storage_sizes_rest_bad_request( + request_type=db_system_initial_storage_size.ListDbSystemInitialStorageSizesRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" - } + request_init = {"parent": "projects/sample1/locations/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -46194,47 +66025,57 @@ def test_stop_autonomous_database_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.stop_autonomous_database(request) + client.list_db_system_initial_storage_sizes(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.StopAutonomousDatabaseRequest, + db_system_initial_storage_size.ListDbSystemInitialStorageSizesRequest, dict, ], ) -def test_stop_autonomous_database_rest_call_success(request_type): +def test_list_db_system_initial_storage_sizes_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" - } + request_init = {"parent": "projects/sample1/locations/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = ( + db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse( + next_page_token="next_page_token_value", + ) + ) # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = ( + db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse.pb( + return_value + ) + ) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.stop_autonomous_database(request) + response = client.list_db_system_initial_storage_sizes(request) # Establish that the response is the type that we expect. - json_return_value = json_format.MessageToJson(return_value) + assert isinstance(response, pagers.ListDbSystemInitialStorageSizesPager) + assert response.next_page_token == "next_page_token_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_stop_autonomous_database_rest_interceptors(null_interceptor): +def test_list_db_system_initial_storage_sizes_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -46246,23 +66087,26 @@ def test_stop_autonomous_database_rest_interceptors(null_interceptor): with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, - mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_stop_autonomous_database" + transports.OracleDatabaseRestInterceptor, + "post_list_db_system_initial_storage_sizes", ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_stop_autonomous_database_with_metadata", + "post_list_db_system_initial_storage_sizes_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_stop_autonomous_database" + transports.OracleDatabaseRestInterceptor, + "pre_list_db_system_initial_storage_sizes", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.StopAutonomousDatabaseRequest.pb( - oracledatabase.StopAutonomousDatabaseRequest() + pb_message = ( + db_system_initial_storage_size.ListDbSystemInitialStorageSizesRequest.pb( + db_system_initial_storage_size.ListDbSystemInitialStorageSizesRequest() + ) ) transcode.return_value = { "method": "post", @@ -46274,19 +66118,28 @@ def test_stop_autonomous_database_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = json_format.MessageToJson(operations_pb2.Operation()) + return_value = db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse.to_json( + db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse() + ) req.return_value.content = return_value - request = oracledatabase.StopAutonomousDatabaseRequest() + request = ( + db_system_initial_storage_size.ListDbSystemInitialStorageSizesRequest() + ) metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() - post_with_metadata.return_value = operations_pb2.Operation(), metadata + post.return_value = ( + db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse() + ) + post_with_metadata.return_value = ( + db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse(), + metadata, + ) - client.stop_autonomous_database( + client.list_db_system_initial_storage_sizes( request, metadata=[ ("key", "val"), @@ -46299,16 +66152,12 @@ def test_stop_autonomous_database_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_start_autonomous_database_rest_bad_request( - request_type=oracledatabase.StartAutonomousDatabaseRequest, -): +def test_list_databases_rest_bad_request(request_type=database.ListDatabasesRequest): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" - } + request_init = {"parent": "projects/sample1/locations/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -46324,47 +66173,51 @@ def test_start_autonomous_database_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.start_autonomous_database(request) + client.list_databases(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.StartAutonomousDatabaseRequest, + database.ListDatabasesRequest, dict, ], ) -def test_start_autonomous_database_rest_call_success(request_type): +def test_list_databases_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" - } + request_init = {"parent": "projects/sample1/locations/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = database.ListDatabasesResponse( + next_page_token="next_page_token_value", + ) # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = database.ListDatabasesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.start_autonomous_database(request) + response = client.list_databases(request) # Establish that the response is the type that we expect. - json_return_value = json_format.MessageToJson(return_value) + assert isinstance(response, pagers.ListDatabasesPager) + assert response.next_page_token == "next_page_token_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_start_autonomous_database_rest_interceptors(null_interceptor): +def test_list_databases_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -46376,24 +66229,21 @@ def test_start_autonomous_database_rest_interceptors(null_interceptor): with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, - mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_start_autonomous_database" + transports.OracleDatabaseRestInterceptor, "post_list_databases" ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_start_autonomous_database_with_metadata", + "post_list_databases_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_start_autonomous_database" + transports.OracleDatabaseRestInterceptor, "pre_list_databases" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.StartAutonomousDatabaseRequest.pb( - oracledatabase.StartAutonomousDatabaseRequest() - ) + pb_message = database.ListDatabasesRequest.pb(database.ListDatabasesRequest()) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -46404,19 +66254,21 @@ def test_start_autonomous_database_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = json_format.MessageToJson(operations_pb2.Operation()) + return_value = database.ListDatabasesResponse.to_json( + database.ListDatabasesResponse() + ) req.return_value.content = return_value - request = oracledatabase.StartAutonomousDatabaseRequest() + request = database.ListDatabasesRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() - post_with_metadata.return_value = operations_pb2.Operation(), metadata + post.return_value = database.ListDatabasesResponse() + post_with_metadata.return_value = database.ListDatabasesResponse(), metadata - client.start_autonomous_database( + client.list_databases( request, metadata=[ ("key", "val"), @@ -46429,16 +66281,12 @@ def test_start_autonomous_database_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_restart_autonomous_database_rest_bad_request( - request_type=oracledatabase.RestartAutonomousDatabaseRequest, -): +def test_get_database_rest_bad_request(request_type=database.GetDatabaseRequest): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" - } + request_init = {"name": "projects/sample1/locations/sample2/databases/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -46454,47 +66302,89 @@ def test_restart_autonomous_database_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.restart_autonomous_database(request) + client.get_database(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.RestartAutonomousDatabaseRequest, + database.GetDatabaseRequest, dict, ], ) -def test_restart_autonomous_database_rest_call_success(request_type): +def test_get_database_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" - } + request_init = {"name": "projects/sample1/locations/sample2/databases/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = database.Database( + name="name_value", + db_name="db_name_value", + db_unique_name="db_unique_name_value", + admin_password="admin_password_value", + admin_password_secret_version="admin_password_secret_version_value", + tde_wallet_password="tde_wallet_password_value", + tde_wallet_password_secret_version="tde_wallet_password_secret_version_value", + character_set="character_set_value", + ncharacter_set="ncharacter_set_value", + oci_url="oci_url_value", + database_id="database_id_value", + db_home_name="db_home_name_value", + gcp_oracle_zone="gcp_oracle_zone_value", + ops_insights_status=database.Database.OperationsInsightsStatus.ENABLING, + pluggable_database_id="pluggable_database_id_value", + pluggable_database_name="pluggable_database_name_value", + ) # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = database.Database.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.restart_autonomous_database(request) + response = client.get_database(request) # Establish that the response is the type that we expect. - json_return_value = json_format.MessageToJson(return_value) + assert isinstance(response, database.Database) + assert response.name == "name_value" + assert response.db_name == "db_name_value" + assert response.db_unique_name == "db_unique_name_value" + assert response.admin_password == "admin_password_value" + assert ( + response.admin_password_secret_version == "admin_password_secret_version_value" + ) + assert response.tde_wallet_password == "tde_wallet_password_value" + assert ( + response.tde_wallet_password_secret_version + == "tde_wallet_password_secret_version_value" + ) + assert response.character_set == "character_set_value" + assert response.ncharacter_set == "ncharacter_set_value" + assert response.oci_url == "oci_url_value" + assert response.database_id == "database_id_value" + assert response.db_home_name == "db_home_name_value" + assert response.gcp_oracle_zone == "gcp_oracle_zone_value" + assert ( + response.ops_insights_status + == database.Database.OperationsInsightsStatus.ENABLING + ) + assert response.pluggable_database_id == "pluggable_database_id_value" + assert response.pluggable_database_name == "pluggable_database_name_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_restart_autonomous_database_rest_interceptors(null_interceptor): +def test_get_database_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -46506,24 +66396,20 @@ def test_restart_autonomous_database_rest_interceptors(null_interceptor): with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, - mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_restart_autonomous_database" + transports.OracleDatabaseRestInterceptor, "post_get_database" ) as post, mock.patch.object( - transports.OracleDatabaseRestInterceptor, - "post_restart_autonomous_database_with_metadata", + transports.OracleDatabaseRestInterceptor, "post_get_database_with_metadata" ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_restart_autonomous_database" + transports.OracleDatabaseRestInterceptor, "pre_get_database" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.RestartAutonomousDatabaseRequest.pb( - oracledatabase.RestartAutonomousDatabaseRequest() - ) + pb_message = database.GetDatabaseRequest.pb(database.GetDatabaseRequest()) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -46534,19 +66420,19 @@ def test_restart_autonomous_database_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = json_format.MessageToJson(operations_pb2.Operation()) + return_value = database.Database.to_json(database.Database()) req.return_value.content = return_value - request = oracledatabase.RestartAutonomousDatabaseRequest() + request = database.GetDatabaseRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() - post_with_metadata.return_value = operations_pb2.Operation(), metadata + post.return_value = database.Database() + post_with_metadata.return_value = database.Database(), metadata - client.restart_autonomous_database( + client.get_database( request, metadata=[ ("key", "val"), @@ -46559,16 +66445,14 @@ def test_restart_autonomous_database_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_switchover_autonomous_database_rest_bad_request( - request_type=oracledatabase.SwitchoverAutonomousDatabaseRequest, +def test_list_pluggable_databases_rest_bad_request( + request_type=pluggable_database.ListPluggableDatabasesRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" - } + request_init = {"parent": "projects/sample1/locations/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -46584,47 +66468,53 @@ def test_switchover_autonomous_database_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.switchover_autonomous_database(request) + client.list_pluggable_databases(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.SwitchoverAutonomousDatabaseRequest, + pluggable_database.ListPluggableDatabasesRequest, dict, ], ) -def test_switchover_autonomous_database_rest_call_success(request_type): +def test_list_pluggable_databases_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" - } + request_init = {"parent": "projects/sample1/locations/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = pluggable_database.ListPluggableDatabasesResponse( + next_page_token="next_page_token_value", + ) # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = pluggable_database.ListPluggableDatabasesResponse.pb( + return_value + ) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.switchover_autonomous_database(request) + response = client.list_pluggable_databases(request) # Establish that the response is the type that we expect. - json_return_value = json_format.MessageToJson(return_value) + assert isinstance(response, pagers.ListPluggableDatabasesPager) + assert response.next_page_token == "next_page_token_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_switchover_autonomous_database_rest_interceptors(null_interceptor): +def test_list_pluggable_databases_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -46636,25 +66526,22 @@ def test_switchover_autonomous_database_rest_interceptors(null_interceptor): with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, - mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.OracleDatabaseRestInterceptor, - "post_switchover_autonomous_database", + transports.OracleDatabaseRestInterceptor, "post_list_pluggable_databases" ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_switchover_autonomous_database_with_metadata", + "post_list_pluggable_databases_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, - "pre_switchover_autonomous_database", + transports.OracleDatabaseRestInterceptor, "pre_list_pluggable_databases" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.SwitchoverAutonomousDatabaseRequest.pb( - oracledatabase.SwitchoverAutonomousDatabaseRequest() + pb_message = pluggable_database.ListPluggableDatabasesRequest.pb( + pluggable_database.ListPluggableDatabasesRequest() ) transcode.return_value = { "method": "post", @@ -46666,19 +66553,24 @@ def test_switchover_autonomous_database_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = json_format.MessageToJson(operations_pb2.Operation()) + return_value = pluggable_database.ListPluggableDatabasesResponse.to_json( + pluggable_database.ListPluggableDatabasesResponse() + ) req.return_value.content = return_value - request = oracledatabase.SwitchoverAutonomousDatabaseRequest() + request = pluggable_database.ListPluggableDatabasesRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() - post_with_metadata.return_value = operations_pb2.Operation(), metadata + post.return_value = pluggable_database.ListPluggableDatabasesResponse() + post_with_metadata.return_value = ( + pluggable_database.ListPluggableDatabasesResponse(), + metadata, + ) - client.switchover_autonomous_database( + client.list_pluggable_databases( request, metadata=[ ("key", "val"), @@ -46691,15 +66583,15 @@ def test_switchover_autonomous_database_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_failover_autonomous_database_rest_bad_request( - request_type=oracledatabase.FailoverAutonomousDatabaseRequest, +def test_get_pluggable_database_rest_bad_request( + request_type=pluggable_database.GetPluggableDatabaseRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + "name": "projects/sample1/locations/sample2/pluggableDatabases/sample3" } request = request_type(**request_init) @@ -46716,47 +66608,55 @@ def test_failover_autonomous_database_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.failover_autonomous_database(request) + client.get_pluggable_database(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.FailoverAutonomousDatabaseRequest, + pluggable_database.GetPluggableDatabaseRequest, dict, ], ) -def test_failover_autonomous_database_rest_call_success(request_type): +def test_get_pluggable_database_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/autonomousDatabases/sample3" + "name": "projects/sample1/locations/sample2/pluggableDatabases/sample3" } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = pluggable_database.PluggableDatabase( + name="name_value", + oci_url="oci_url_value", + ) # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = pluggable_database.PluggableDatabase.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.failover_autonomous_database(request) + response = client.get_pluggable_database(request) # Establish that the response is the type that we expect. - json_return_value = json_format.MessageToJson(return_value) + assert isinstance(response, pluggable_database.PluggableDatabase) + assert response.name == "name_value" + assert response.oci_url == "oci_url_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_failover_autonomous_database_rest_interceptors(null_interceptor): +def test_get_pluggable_database_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -46768,24 +66668,22 @@ def test_failover_autonomous_database_rest_interceptors(null_interceptor): with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, - mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.OracleDatabaseRestInterceptor, - "post_failover_autonomous_database", + transports.OracleDatabaseRestInterceptor, "post_get_pluggable_database" ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_failover_autonomous_database_with_metadata", + "post_get_pluggable_database_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_failover_autonomous_database" + transports.OracleDatabaseRestInterceptor, "pre_get_pluggable_database" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.FailoverAutonomousDatabaseRequest.pb( - oracledatabase.FailoverAutonomousDatabaseRequest() + pb_message = pluggable_database.GetPluggableDatabaseRequest.pb( + pluggable_database.GetPluggableDatabaseRequest() ) transcode.return_value = { "method": "post", @@ -46797,19 +66695,24 @@ def test_failover_autonomous_database_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = json_format.MessageToJson(operations_pb2.Operation()) + return_value = pluggable_database.PluggableDatabase.to_json( + pluggable_database.PluggableDatabase() + ) req.return_value.content = return_value - request = oracledatabase.FailoverAutonomousDatabaseRequest() + request = pluggable_database.GetPluggableDatabaseRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() - post_with_metadata.return_value = operations_pb2.Operation(), metadata + post.return_value = pluggable_database.PluggableDatabase() + post_with_metadata.return_value = ( + pluggable_database.PluggableDatabase(), + metadata, + ) - client.failover_autonomous_database( + client.get_pluggable_database( request, metadata=[ ("key", "val"), @@ -46822,9 +66725,7 @@ def test_failover_autonomous_database_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_odb_networks_rest_bad_request( - request_type=odb_network.ListOdbNetworksRequest, -): +def test_list_db_systems_rest_bad_request(request_type=db_system.ListDbSystemsRequest): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -46845,17 +66746,17 @@ def test_list_odb_networks_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_odb_networks(request) + client.list_db_systems(request) @pytest.mark.parametrize( "request_type", [ - odb_network.ListOdbNetworksRequest, + db_system.ListDbSystemsRequest, dict, ], ) -def test_list_odb_networks_rest_call_success(request_type): +def test_list_db_systems_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -46867,7 +66768,7 @@ def test_list_odb_networks_rest_call_success(request_type): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = odb_network.ListOdbNetworksResponse( + return_value = db_system.ListDbSystemsResponse( next_page_token="next_page_token_value", unreachable=["unreachable_value"], ) @@ -46877,21 +66778,21 @@ def test_list_odb_networks_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = odb_network.ListOdbNetworksResponse.pb(return_value) + return_value = db_system.ListDbSystemsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_odb_networks(request) + response = client.list_db_systems(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListOdbNetworksPager) + assert isinstance(response, pagers.ListDbSystemsPager) assert response.next_page_token == "next_page_token_value" assert response.unreachable == ["unreachable_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_odb_networks_rest_interceptors(null_interceptor): +def test_list_db_systems_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -46904,22 +66805,20 @@ def test_list_odb_networks_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_list_odb_networks" + transports.OracleDatabaseRestInterceptor, "post_list_db_systems" ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_list_odb_networks_with_metadata", + "post_list_db_systems_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_list_odb_networks" + transports.OracleDatabaseRestInterceptor, "pre_list_db_systems" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = odb_network.ListOdbNetworksRequest.pb( - odb_network.ListOdbNetworksRequest() - ) + pb_message = db_system.ListDbSystemsRequest.pb(db_system.ListDbSystemsRequest()) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -46930,24 +66829,21 @@ def test_list_odb_networks_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = odb_network.ListOdbNetworksResponse.to_json( - odb_network.ListOdbNetworksResponse() + return_value = db_system.ListDbSystemsResponse.to_json( + db_system.ListDbSystemsResponse() ) req.return_value.content = return_value - request = odb_network.ListOdbNetworksRequest() + request = db_system.ListDbSystemsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = odb_network.ListOdbNetworksResponse() - post_with_metadata.return_value = ( - odb_network.ListOdbNetworksResponse(), - metadata, - ) + post.return_value = db_system.ListDbSystemsResponse() + post_with_metadata.return_value = db_system.ListDbSystemsResponse(), metadata - client.list_odb_networks( + client.list_db_systems( request, metadata=[ ("key", "val"), @@ -46960,14 +66856,12 @@ def test_list_odb_networks_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_get_odb_network_rest_bad_request( - request_type=odb_network.GetOdbNetworkRequest, -): +def test_get_db_system_rest_bad_request(request_type=db_system.GetDbSystemRequest): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/odbNetworks/sample3"} + request_init = {"name": "projects/sample1/locations/sample2/dbSystems/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -46983,34 +66877,36 @@ def test_get_odb_network_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_odb_network(request) + client.get_db_system(request) @pytest.mark.parametrize( "request_type", [ - odb_network.GetOdbNetworkRequest, + db_system.GetDbSystemRequest, dict, ], ) -def test_get_odb_network_rest_call_success(request_type): +def test_get_db_system_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/odbNetworks/sample3"} + request_init = {"name": "projects/sample1/locations/sample2/dbSystems/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = odb_network.OdbNetwork( + return_value = db_system.DbSystem( name="name_value", - network="network_value", - state=odb_network.OdbNetwork.State.PROVISIONING, - entitlement_id="entitlement_id_value", gcp_oracle_zone="gcp_oracle_zone_value", + odb_network="odb_network_value", + odb_subnet="odb_subnet_value", + entitlement_id="entitlement_id_value", + display_name="display_name_value", + oci_url="oci_url_value", ) # Wrap the value into a proper Response obj @@ -47018,24 +66914,26 @@ def test_get_odb_network_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = odb_network.OdbNetwork.pb(return_value) + return_value = db_system.DbSystem.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_odb_network(request) + response = client.get_db_system(request) # Establish that the response is the type that we expect. - assert isinstance(response, odb_network.OdbNetwork) + assert isinstance(response, db_system.DbSystem) assert response.name == "name_value" - assert response.network == "network_value" - assert response.state == odb_network.OdbNetwork.State.PROVISIONING - assert response.entitlement_id == "entitlement_id_value" assert response.gcp_oracle_zone == "gcp_oracle_zone_value" + assert response.odb_network == "odb_network_value" + assert response.odb_subnet == "odb_subnet_value" + assert response.entitlement_id == "entitlement_id_value" + assert response.display_name == "display_name_value" + assert response.oci_url == "oci_url_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_odb_network_rest_interceptors(null_interceptor): +def test_get_db_system_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -47048,22 +66946,19 @@ def test_get_odb_network_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_get_odb_network" + transports.OracleDatabaseRestInterceptor, "post_get_db_system" ) as post, mock.patch.object( - transports.OracleDatabaseRestInterceptor, - "post_get_odb_network_with_metadata", + transports.OracleDatabaseRestInterceptor, "post_get_db_system_with_metadata" ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_get_odb_network" + transports.OracleDatabaseRestInterceptor, "pre_get_db_system" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = odb_network.GetOdbNetworkRequest.pb( - odb_network.GetOdbNetworkRequest() - ) + pb_message = db_system.GetDbSystemRequest.pb(db_system.GetDbSystemRequest()) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -47074,19 +66969,19 @@ def test_get_odb_network_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = odb_network.OdbNetwork.to_json(odb_network.OdbNetwork()) + return_value = db_system.DbSystem.to_json(db_system.DbSystem()) req.return_value.content = return_value - request = odb_network.GetOdbNetworkRequest() + request = db_system.GetDbSystemRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = odb_network.OdbNetwork() - post_with_metadata.return_value = odb_network.OdbNetwork(), metadata + post.return_value = db_system.DbSystem() + post_with_metadata.return_value = db_system.DbSystem(), metadata - client.get_odb_network( + client.get_db_system( request, metadata=[ ("key", "val"), @@ -47099,8 +66994,8 @@ def test_get_odb_network_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_create_odb_network_rest_bad_request( - request_type=gco_odb_network.CreateOdbNetworkRequest, +def test_create_db_system_rest_bad_request( + request_type=gco_db_system.CreateDbSystemRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" @@ -47122,38 +67017,106 @@ def test_create_odb_network_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_odb_network(request) + client.create_db_system(request) @pytest.mark.parametrize( "request_type", [ - gco_odb_network.CreateOdbNetworkRequest, + gco_db_system.CreateDbSystemRequest, dict, ], ) -def test_create_odb_network_rest_call_success(request_type): +def test_create_db_system_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = {"parent": "projects/sample1/locations/sample2"} - request_init["odb_network"] = { + request_init["db_system"] = { "name": "name_value", - "network": "network_value", + "properties": { + "shape": "shape_value", + "compute_count": 1413, + "initial_data_storage_size_gb": 2937, + "database_edition": 1, + "license_model": 1, + "ssh_public_keys": ["ssh_public_keys_value1", "ssh_public_keys_value2"], + "hostname_prefix": "hostname_prefix_value", + "hostname": "hostname_value", + "private_ip": "private_ip_value", + "data_collection_options": { + "is_diagnostics_events_enabled": True, + "is_incident_logs_enabled": True, + }, + "time_zone": {"id": "id_value", "version": "version_value"}, + "lifecycle_state": 1, + "db_home": { + "display_name": "display_name_value", + "db_version": "db_version_value", + "database": { + "name": "name_value", + "db_name": "db_name_value", + "db_unique_name": "db_unique_name_value", + "admin_password": "admin_password_value", + "admin_password_secret_version": "admin_password_secret_version_value", + "tde_wallet_password": "tde_wallet_password_value", + "tde_wallet_password_secret_version": "tde_wallet_password_secret_version_value", + "character_set": "character_set_value", + "ncharacter_set": "ncharacter_set_value", + "oci_url": "oci_url_value", + "create_time": {"seconds": 751, "nanos": 543}, + "properties": { + "state": 1, + "db_version": "db_version_value", + "db_backup_config": { + "auto_backup_enabled": True, + "backup_destination_details": [{"type_": 1}], + "retention_period_days": 2250, + "backup_deletion_policy": 1, + "auto_full_backup_day": 1, + "auto_full_backup_window": 1, + "auto_incremental_backup_window": 1, + }, + "database_management_config": { + "management_state": 1, + "management_type": 1, + }, + }, + "database_id": "database_id_value", + "db_home_name": "db_home_name_value", + "gcp_oracle_zone": "gcp_oracle_zone_value", + "ops_insights_status": 1, + "pluggable_database_id": "pluggable_database_id_value", + "pluggable_database_name": "pluggable_database_name_value", + }, + "is_unified_auditing_enabled": True, + }, + "ocid": "ocid_value", + "memory_size_gb": 1499, + "compute_model": 1, + "data_storage_size_gb": 2096, + "reco_storage_size_gb": 2111, + "domain": "domain_value", + "node_count": 1070, + "db_system_options": {"storage_management": 1}, + }, + "gcp_oracle_zone": "gcp_oracle_zone_value", "labels": {}, - "create_time": {"seconds": 751, "nanos": 543}, - "state": 1, + "odb_network": "odb_network_value", + "odb_subnet": "odb_subnet_value", "entitlement_id": "entitlement_id_value", - "gcp_oracle_zone": "gcp_oracle_zone_value", + "display_name": "display_name_value", + "create_time": {}, + "oci_url": "oci_url_value", } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = gco_odb_network.CreateOdbNetworkRequest.meta.fields["odb_network"] + test_field = gco_db_system.CreateDbSystemRequest.meta.fields["db_system"] def get_message_fields(field): # Given a field which is a message (composite type), return a list with @@ -47181,7 +67144,7 @@ def get_message_fields(field): # For each item in the sample request, create a list of sub fields which are not present at runtime # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["odb_network"].items(): # pragma: NO COVER + for field, value in request_init["db_system"].items(): # pragma: NO COVER result = None is_repeated = False # For repeated fields @@ -47211,10 +67174,10 @@ def get_message_fields(field): subfield = subfield_to_delete.get("subfield") if subfield: if field_repeated: - for i in range(0, len(request_init["odb_network"][field])): - del request_init["odb_network"][field][i][subfield] + for i in range(0, len(request_init["db_system"][field])): + del request_init["db_system"][field][i][subfield] else: - del request_init["odb_network"][field][subfield] + del request_init["db_system"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -47229,14 +67192,14 @@ def get_message_fields(field): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_odb_network(request) + response = client.create_db_system(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_odb_network_rest_interceptors(null_interceptor): +def test_create_db_system_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -47250,21 +67213,21 @@ def test_create_odb_network_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_create_odb_network" + transports.OracleDatabaseRestInterceptor, "post_create_db_system" ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_create_odb_network_with_metadata", + "post_create_db_system_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_create_odb_network" + transports.OracleDatabaseRestInterceptor, "pre_create_db_system" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = gco_odb_network.CreateOdbNetworkRequest.pb( - gco_odb_network.CreateOdbNetworkRequest() + pb_message = gco_db_system.CreateDbSystemRequest.pb( + gco_db_system.CreateDbSystemRequest() ) transcode.return_value = { "method": "post", @@ -47279,7 +67242,7 @@ def test_create_odb_network_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = gco_odb_network.CreateOdbNetworkRequest() + request = gco_db_system.CreateDbSystemRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -47288,7 +67251,7 @@ def test_create_odb_network_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.create_odb_network( + client.create_db_system( request, metadata=[ ("key", "val"), @@ -47301,14 +67264,14 @@ def test_create_odb_network_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_delete_odb_network_rest_bad_request( - request_type=odb_network.DeleteOdbNetworkRequest, +def test_delete_db_system_rest_bad_request( + request_type=db_system.DeleteDbSystemRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/odbNetworks/sample3"} + request_init = {"name": "projects/sample1/locations/sample2/dbSystems/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -47324,23 +67287,23 @@ def test_delete_odb_network_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_odb_network(request) + client.delete_db_system(request) @pytest.mark.parametrize( "request_type", [ - odb_network.DeleteOdbNetworkRequest, + db_system.DeleteDbSystemRequest, dict, ], ) -def test_delete_odb_network_rest_call_success(request_type): +def test_delete_db_system_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/odbNetworks/sample3"} + request_init = {"name": "projects/sample1/locations/sample2/dbSystems/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -47355,14 +67318,14 @@ def test_delete_odb_network_rest_call_success(request_type): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_odb_network(request) + response = client.delete_db_system(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_odb_network_rest_interceptors(null_interceptor): +def test_delete_db_system_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -47376,21 +67339,21 @@ def test_delete_odb_network_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_delete_odb_network" + transports.OracleDatabaseRestInterceptor, "post_delete_db_system" ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_delete_odb_network_with_metadata", + "post_delete_db_system_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_delete_odb_network" + transports.OracleDatabaseRestInterceptor, "pre_delete_db_system" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = odb_network.DeleteOdbNetworkRequest.pb( - odb_network.DeleteOdbNetworkRequest() + pb_message = db_system.DeleteDbSystemRequest.pb( + db_system.DeleteDbSystemRequest() ) transcode.return_value = { "method": "post", @@ -47405,7 +67368,7 @@ def test_delete_odb_network_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = odb_network.DeleteOdbNetworkRequest() + request = db_system.DeleteDbSystemRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -47414,7 +67377,7 @@ def test_delete_odb_network_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.delete_odb_network( + client.delete_db_system( request, metadata=[ ("key", "val"), @@ -47427,14 +67390,14 @@ def test_delete_odb_network_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_odb_subnets_rest_bad_request( - request_type=odb_subnet.ListOdbSubnetsRequest, +def test_list_goldengate_deployments_rest_bad_request( + request_type=goldengate_deployment.ListGoldengateDeploymentsRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2/odbNetworks/sample3"} + request_init = {"parent": "projects/sample1/locations/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -47450,29 +67413,29 @@ def test_list_odb_subnets_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_odb_subnets(request) + client.list_goldengate_deployments(request) @pytest.mark.parametrize( "request_type", [ - odb_subnet.ListOdbSubnetsRequest, + goldengate_deployment.ListGoldengateDeploymentsRequest, dict, ], ) -def test_list_odb_subnets_rest_call_success(request_type): +def test_list_goldengate_deployments_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2/odbNetworks/sample3"} + request_init = {"parent": "projects/sample1/locations/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = odb_subnet.ListOdbSubnetsResponse( + return_value = goldengate_deployment.ListGoldengateDeploymentsResponse( next_page_token="next_page_token_value", unreachable=["unreachable_value"], ) @@ -47482,21 +67445,23 @@ def test_list_odb_subnets_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = odb_subnet.ListOdbSubnetsResponse.pb(return_value) + return_value = goldengate_deployment.ListGoldengateDeploymentsResponse.pb( + return_value + ) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_odb_subnets(request) + response = client.list_goldengate_deployments(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListOdbSubnetsPager) + assert isinstance(response, pagers.ListGoldengateDeploymentsPager) assert response.next_page_token == "next_page_token_value" assert response.unreachable == ["unreachable_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_odb_subnets_rest_interceptors(null_interceptor): +def test_list_goldengate_deployments_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -47509,21 +67474,21 @@ def test_list_odb_subnets_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_list_odb_subnets" + transports.OracleDatabaseRestInterceptor, "post_list_goldengate_deployments" ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_list_odb_subnets_with_metadata", + "post_list_goldengate_deployments_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_list_odb_subnets" + transports.OracleDatabaseRestInterceptor, "pre_list_goldengate_deployments" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = odb_subnet.ListOdbSubnetsRequest.pb( - odb_subnet.ListOdbSubnetsRequest() + pb_message = goldengate_deployment.ListGoldengateDeploymentsRequest.pb( + goldengate_deployment.ListGoldengateDeploymentsRequest() ) transcode.return_value = { "method": "post", @@ -47535,21 +67500,24 @@ def test_list_odb_subnets_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = odb_subnet.ListOdbSubnetsResponse.to_json( - odb_subnet.ListOdbSubnetsResponse() + return_value = goldengate_deployment.ListGoldengateDeploymentsResponse.to_json( + goldengate_deployment.ListGoldengateDeploymentsResponse() ) req.return_value.content = return_value - request = odb_subnet.ListOdbSubnetsRequest() + request = goldengate_deployment.ListGoldengateDeploymentsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = odb_subnet.ListOdbSubnetsResponse() - post_with_metadata.return_value = odb_subnet.ListOdbSubnetsResponse(), metadata + post.return_value = goldengate_deployment.ListGoldengateDeploymentsResponse() + post_with_metadata.return_value = ( + goldengate_deployment.ListGoldengateDeploymentsResponse(), + metadata, + ) - client.list_odb_subnets( + client.list_goldengate_deployments( request, metadata=[ ("key", "val"), @@ -47562,13 +67530,15 @@ def test_list_odb_subnets_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_get_odb_subnet_rest_bad_request(request_type=odb_subnet.GetOdbSubnetRequest): +def test_get_goldengate_deployment_rest_bad_request( + request_type=goldengate_deployment.GetGoldengateDeploymentRequest, +): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/odbNetworks/sample3/odbSubnets/sample4" + "name": "projects/sample1/locations/sample2/goldengateDeployments/sample3" } request = request_type(**request_init) @@ -47585,35 +67555,38 @@ def test_get_odb_subnet_rest_bad_request(request_type=odb_subnet.GetOdbSubnetReq response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_odb_subnet(request) + client.get_goldengate_deployment(request) @pytest.mark.parametrize( "request_type", [ - odb_subnet.GetOdbSubnetRequest, + goldengate_deployment.GetGoldengateDeploymentRequest, dict, ], ) -def test_get_odb_subnet_rest_call_success(request_type): +def test_get_goldengate_deployment_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/odbNetworks/sample3/odbSubnets/sample4" + "name": "projects/sample1/locations/sample2/goldengateDeployments/sample3" } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = odb_subnet.OdbSubnet( + return_value = goldengate_deployment.GoldengateDeployment( name="name_value", - cidr_range="cidr_range_value", - purpose=odb_subnet.OdbSubnet.Purpose.CLIENT_SUBNET, - state=odb_subnet.OdbSubnet.State.PROVISIONING, + gcp_oracle_zone="gcp_oracle_zone_value", + odb_network="odb_network_value", + odb_subnet="odb_subnet_value", + entitlement_id="entitlement_id_value", + display_name="display_name_value", + oci_url="oci_url_value", ) # Wrap the value into a proper Response obj @@ -47621,23 +67594,26 @@ def test_get_odb_subnet_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = odb_subnet.OdbSubnet.pb(return_value) + return_value = goldengate_deployment.GoldengateDeployment.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_odb_subnet(request) + response = client.get_goldengate_deployment(request) # Establish that the response is the type that we expect. - assert isinstance(response, odb_subnet.OdbSubnet) + assert isinstance(response, goldengate_deployment.GoldengateDeployment) assert response.name == "name_value" - assert response.cidr_range == "cidr_range_value" - assert response.purpose == odb_subnet.OdbSubnet.Purpose.CLIENT_SUBNET - assert response.state == odb_subnet.OdbSubnet.State.PROVISIONING + assert response.gcp_oracle_zone == "gcp_oracle_zone_value" + assert response.odb_network == "odb_network_value" + assert response.odb_subnet == "odb_subnet_value" + assert response.entitlement_id == "entitlement_id_value" + assert response.display_name == "display_name_value" + assert response.oci_url == "oci_url_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_odb_subnet_rest_interceptors(null_interceptor): +def test_get_goldengate_deployment_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -47650,20 +67626,22 @@ def test_get_odb_subnet_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_get_odb_subnet" + transports.OracleDatabaseRestInterceptor, "post_get_goldengate_deployment" ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_get_odb_subnet_with_metadata", + "post_get_goldengate_deployment_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_get_odb_subnet" + transports.OracleDatabaseRestInterceptor, "pre_get_goldengate_deployment" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = odb_subnet.GetOdbSubnetRequest.pb(odb_subnet.GetOdbSubnetRequest()) + pb_message = goldengate_deployment.GetGoldengateDeploymentRequest.pb( + goldengate_deployment.GetGoldengateDeploymentRequest() + ) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -47674,19 +67652,24 @@ def test_get_odb_subnet_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = odb_subnet.OdbSubnet.to_json(odb_subnet.OdbSubnet()) + return_value = goldengate_deployment.GoldengateDeployment.to_json( + goldengate_deployment.GoldengateDeployment() + ) req.return_value.content = return_value - request = odb_subnet.GetOdbSubnetRequest() + request = goldengate_deployment.GetGoldengateDeploymentRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = odb_subnet.OdbSubnet() - post_with_metadata.return_value = odb_subnet.OdbSubnet(), metadata + post.return_value = goldengate_deployment.GoldengateDeployment() + post_with_metadata.return_value = ( + goldengate_deployment.GoldengateDeployment(), + metadata, + ) - client.get_odb_subnet( + client.get_goldengate_deployment( request, metadata=[ ("key", "val"), @@ -47699,14 +67682,14 @@ def test_get_odb_subnet_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_create_odb_subnet_rest_bad_request( - request_type=gco_odb_subnet.CreateOdbSubnetRequest, +def test_create_goldengate_deployment_rest_bad_request( + request_type=gco_goldengate_deployment.CreateGoldengateDeploymentRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2/odbNetworks/sample3"} + request_init = {"parent": "projects/sample1/locations/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -47722,37 +67705,137 @@ def test_create_odb_subnet_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_odb_subnet(request) + client.create_goldengate_deployment(request) @pytest.mark.parametrize( "request_type", [ - gco_odb_subnet.CreateOdbSubnetRequest, + gco_goldengate_deployment.CreateGoldengateDeploymentRequest, dict, ], ) -def test_create_odb_subnet_rest_call_success(request_type): +def test_create_goldengate_deployment_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2/odbNetworks/sample3"} - request_init["odb_subnet"] = { + request_init = {"parent": "projects/sample1/locations/sample2"} + request_init["goldengate_deployment"] = { "name": "name_value", - "cidr_range": "cidr_range_value", - "purpose": 1, + "properties": { + "ocid": "ocid_value", + "lifecycle_state": 1, + "license_model": 1, + "environment_type": "environment_type_value", + "cpu_core_count": 1496, + "is_auto_scaling_enabled": True, + "description": "description_value", + "deployment_type": "deployment_type_value", + "ogg_data": { + "admin_password": "admin_password_value", + "admin_password_secret_version": "admin_password_secret_version_value", + "deployment": "deployment_value", + "admin_username": "admin_username_value", + "ogg_version": "ogg_version_value", + "certificate": "certificate_value", + "credential_store": 1, + "identity_domain_id": "identity_domain_id_value", + "password_secret_id": "password_secret_id_value", + "group_roles_mapping": { + "security_group_id": "security_group_id_value", + "administrator_group_id": "administrator_group_id_value", + "operator_group_id": "operator_group_id_value", + "user_group_id": "user_group_id_value", + }, + }, + "maintenance_window": {"day": 1, "start_hour": 1099}, + "maintenance_config": { + "is_interim_release_auto_upgrade_enabled": True, + "interim_release_upgrade_period_days": 3697, + "bundle_release_upgrade_period_days": 3571, + "major_release_upgrade_period_days": 3474, + "security_patch_upgrade_period_days": 3616, + }, + "fqdn": "fqdn_value", + "lifecycle_sub_state": 1, + "category": 1, + "deployment_backup_id": "deployment_backup_id_value", + "update_time": {"seconds": 751, "nanos": 543}, + "lifecycle_details": "lifecycle_details_value", + "healthy": True, + "load_balancer_subnet_id": "load_balancer_subnet_id_value", + "load_balancer_id": "load_balancer_id_value", + "nsg_ids": ["nsg_ids_value1", "nsg_ids_value2"], + "is_public": True, + "public_ip_address": "public_ip_address_value", + "private_ip_address": "private_ip_address_value", + "deployment_url": "deployment_url_value", + "is_latest_version": True, + "upgrade_required_time": {}, + "storage_utilization_bytes": 2710, + "is_storage_utilization_limit_exceeded": True, + "deployment_diagnostic_data": { + "namespace": "namespace_value", + "bucket": "bucket_value", + "object_": "object__value", + "diagnostic_state": 1, + "diagnostic_start_time": {}, + "diagnostic_end_time": {}, + }, + "backup_schedule": { + "bucket": "bucket_value", + "compartment_id": "compartment_id_value", + "frequency_backup_scheduled": 1, + "metadata_only": True, + "namespace": "namespace_value", + "backup_scheduled_time": {}, + }, + "next_maintenance_time": {}, + "next_maintenance_action_type": 1, + "next_maintenance_description": "next_maintenance_description_value", + "ogg_version_support_end_time": {}, + "ingress_ips": [{"ingress_ip_address": "ingress_ip_address_value"}], + "deployment_role": 1, + "last_backup_schedule_time": {}, + "next_backup_schedule_time": {}, + "role_change_time": {}, + "locks": [ + { + "type_": 1, + "compartment_id": "compartment_id_value", + "related_resource_id": "related_resource_id_value", + "message": "message_value", + "create_time": {}, + } + ], + "placements": [ + { + "availability_domain": "availability_domain_value", + "fault_domain": "fault_domain_value", + } + ], + }, + "gcp_oracle_zone": "gcp_oracle_zone_value", "labels": {}, - "create_time": {"seconds": 751, "nanos": 543}, - "state": 1, + "odb_network": "odb_network_value", + "odb_subnet": "odb_subnet_value", + "entitlement_id": "entitlement_id_value", + "display_name": "display_name_value", + "create_time": {}, + "oci_url": "oci_url_value", } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = gco_odb_subnet.CreateOdbSubnetRequest.meta.fields["odb_subnet"] + test_field = ( + gco_goldengate_deployment.CreateGoldengateDeploymentRequest.meta.fields[ + "goldengate_deployment" + ] + ) def get_message_fields(field): # Given a field which is a message (composite type), return a list with @@ -47780,7 +67863,9 @@ def get_message_fields(field): # For each item in the sample request, create a list of sub fields which are not present at runtime # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["odb_subnet"].items(): # pragma: NO COVER + for field, value in request_init[ + "goldengate_deployment" + ].items(): # pragma: NO COVER result = None is_repeated = False # For repeated fields @@ -47791,29 +67876,291 @@ def get_message_fields(field): if isinstance(value, dict): result = value - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["goldengate_deployment"][field])): + del request_init["goldengate_deployment"][field][i][subfield] + else: + del request_init["goldengate_deployment"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.create_goldengate_deployment(request) + + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_goldengate_deployment_rest_interceptors(null_interceptor): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.OracleDatabaseRestInterceptor(), + ) + client = OracleDatabaseClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_create_goldengate_deployment", + ) as post, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_create_goldengate_deployment_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "pre_create_goldengate_deployment" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = gco_goldengate_deployment.CreateGoldengateDeploymentRequest.pb( + gco_goldengate_deployment.CreateGoldengateDeploymentRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value + + request = gco_goldengate_deployment.CreateGoldengateDeploymentRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata + + client.create_goldengate_deployment( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_delete_goldengate_deployment_rest_bad_request( + request_type=goldengate_deployment.DeleteGoldengateDeploymentRequest, +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/goldengateDeployments/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.delete_goldengate_deployment(request) + + +@pytest.mark.parametrize( + "request_type", + [ + goldengate_deployment.DeleteGoldengateDeploymentRequest, + dict, + ], +) +def test_delete_goldengate_deployment_rest_call_success(request_type): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/goldengateDeployments/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.delete_goldengate_deployment(request) + + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_goldengate_deployment_rest_interceptors(null_interceptor): + transport = transports.OracleDatabaseRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.OracleDatabaseRestInterceptor(), + ) + client = OracleDatabaseClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_delete_goldengate_deployment", + ) as post, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, + "post_delete_goldengate_deployment_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.OracleDatabaseRestInterceptor, "pre_delete_goldengate_deployment" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = goldengate_deployment.DeleteGoldengateDeploymentRequest.pb( + goldengate_deployment.DeleteGoldengateDeploymentRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value + + request = goldengate_deployment.DeleteGoldengateDeploymentRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata + + client.delete_goldengate_deployment( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_stop_goldengate_deployment_rest_bad_request( + request_type=goldengate_deployment.StopGoldengateDeploymentRequest, +): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/goldengateDeployments/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.stop_goldengate_deployment(request) + - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["odb_subnet"][field])): - del request_init["odb_subnet"][field][i][subfield] - else: - del request_init["odb_subnet"][field][subfield] +@pytest.mark.parametrize( + "request_type", + [ + goldengate_deployment.StopGoldengateDeploymentRequest, + dict, + ], +) +def test_stop_goldengate_deployment_rest_call_success(request_type): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/goldengateDeployments/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -47828,14 +68175,14 @@ def get_message_fields(field): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_odb_subnet(request) + response = client.stop_goldengate_deployment(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_odb_subnet_rest_interceptors(null_interceptor): +def test_stop_goldengate_deployment_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -47849,21 +68196,21 @@ def test_create_odb_subnet_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_create_odb_subnet" + transports.OracleDatabaseRestInterceptor, "post_stop_goldengate_deployment" ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_create_odb_subnet_with_metadata", + "post_stop_goldengate_deployment_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_create_odb_subnet" + transports.OracleDatabaseRestInterceptor, "pre_stop_goldengate_deployment" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = gco_odb_subnet.CreateOdbSubnetRequest.pb( - gco_odb_subnet.CreateOdbSubnetRequest() + pb_message = goldengate_deployment.StopGoldengateDeploymentRequest.pb( + goldengate_deployment.StopGoldengateDeploymentRequest() ) transcode.return_value = { "method": "post", @@ -47878,7 +68225,7 @@ def test_create_odb_subnet_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = gco_odb_subnet.CreateOdbSubnetRequest() + request = goldengate_deployment.StopGoldengateDeploymentRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -47887,7 +68234,7 @@ def test_create_odb_subnet_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.create_odb_subnet( + client.stop_goldengate_deployment( request, metadata=[ ("key", "val"), @@ -47900,15 +68247,15 @@ def test_create_odb_subnet_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_delete_odb_subnet_rest_bad_request( - request_type=odb_subnet.DeleteOdbSubnetRequest, +def test_start_goldengate_deployment_rest_bad_request( + request_type=goldengate_deployment.StartGoldengateDeploymentRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/odbNetworks/sample3/odbSubnets/sample4" + "name": "projects/sample1/locations/sample2/goldengateDeployments/sample3" } request = request_type(**request_init) @@ -47925,24 +68272,24 @@ def test_delete_odb_subnet_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_odb_subnet(request) + client.start_goldengate_deployment(request) @pytest.mark.parametrize( "request_type", [ - odb_subnet.DeleteOdbSubnetRequest, + goldengate_deployment.StartGoldengateDeploymentRequest, dict, ], ) -def test_delete_odb_subnet_rest_call_success(request_type): +def test_start_goldengate_deployment_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/odbNetworks/sample3/odbSubnets/sample4" + "name": "projects/sample1/locations/sample2/goldengateDeployments/sample3" } request = request_type(**request_init) @@ -47958,14 +68305,14 @@ def test_delete_odb_subnet_rest_call_success(request_type): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_odb_subnet(request) + response = client.start_goldengate_deployment(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_odb_subnet_rest_interceptors(null_interceptor): +def test_start_goldengate_deployment_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -47979,21 +68326,21 @@ def test_delete_odb_subnet_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_delete_odb_subnet" + transports.OracleDatabaseRestInterceptor, "post_start_goldengate_deployment" ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_delete_odb_subnet_with_metadata", + "post_start_goldengate_deployment_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_delete_odb_subnet" + transports.OracleDatabaseRestInterceptor, "pre_start_goldengate_deployment" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = odb_subnet.DeleteOdbSubnetRequest.pb( - odb_subnet.DeleteOdbSubnetRequest() + pb_message = goldengate_deployment.StartGoldengateDeploymentRequest.pb( + goldengate_deployment.StartGoldengateDeploymentRequest() ) transcode.return_value = { "method": "post", @@ -48008,7 +68355,7 @@ def test_delete_odb_subnet_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = odb_subnet.DeleteOdbSubnetRequest() + request = goldengate_deployment.StartGoldengateDeploymentRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -48017,7 +68364,7 @@ def test_delete_odb_subnet_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.delete_odb_subnet( + client.start_goldengate_deployment( request, metadata=[ ("key", "val"), @@ -48030,8 +68377,8 @@ def test_delete_odb_subnet_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_exadb_vm_clusters_rest_bad_request( - request_type=oracledatabase.ListExadbVmClustersRequest, +def test_list_goldengate_connections_rest_bad_request( + request_type=goldengate_connection.ListGoldengateConnectionsRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" @@ -48053,17 +68400,17 @@ def test_list_exadb_vm_clusters_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_exadb_vm_clusters(request) + client.list_goldengate_connections(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.ListExadbVmClustersRequest, + goldengate_connection.ListGoldengateConnectionsRequest, dict, ], ) -def test_list_exadb_vm_clusters_rest_call_success(request_type): +def test_list_goldengate_connections_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -48075,8 +68422,9 @@ def test_list_exadb_vm_clusters_rest_call_success(request_type): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = oracledatabase.ListExadbVmClustersResponse( + return_value = goldengate_connection.ListGoldengateConnectionsResponse( next_page_token="next_page_token_value", + unreachable=["unreachable_value"], ) # Wrap the value into a proper Response obj @@ -48084,20 +68432,23 @@ def test_list_exadb_vm_clusters_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = oracledatabase.ListExadbVmClustersResponse.pb(return_value) + return_value = goldengate_connection.ListGoldengateConnectionsResponse.pb( + return_value + ) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_exadb_vm_clusters(request) + response = client.list_goldengate_connections(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListExadbVmClustersPager) + assert isinstance(response, pagers.ListGoldengateConnectionsPager) assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_exadb_vm_clusters_rest_interceptors(null_interceptor): +def test_list_goldengate_connections_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -48110,21 +68461,21 @@ def test_list_exadb_vm_clusters_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_list_exadb_vm_clusters" + transports.OracleDatabaseRestInterceptor, "post_list_goldengate_connections" ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_list_exadb_vm_clusters_with_metadata", + "post_list_goldengate_connections_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_list_exadb_vm_clusters" + transports.OracleDatabaseRestInterceptor, "pre_list_goldengate_connections" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.ListExadbVmClustersRequest.pb( - oracledatabase.ListExadbVmClustersRequest() + pb_message = goldengate_connection.ListGoldengateConnectionsRequest.pb( + goldengate_connection.ListGoldengateConnectionsRequest() ) transcode.return_value = { "method": "post", @@ -48136,24 +68487,24 @@ def test_list_exadb_vm_clusters_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = oracledatabase.ListExadbVmClustersResponse.to_json( - oracledatabase.ListExadbVmClustersResponse() + return_value = goldengate_connection.ListGoldengateConnectionsResponse.to_json( + goldengate_connection.ListGoldengateConnectionsResponse() ) req.return_value.content = return_value - request = oracledatabase.ListExadbVmClustersRequest() + request = goldengate_connection.ListGoldengateConnectionsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = oracledatabase.ListExadbVmClustersResponse() + post.return_value = goldengate_connection.ListGoldengateConnectionsResponse() post_with_metadata.return_value = ( - oracledatabase.ListExadbVmClustersResponse(), + goldengate_connection.ListGoldengateConnectionsResponse(), metadata, ) - client.list_exadb_vm_clusters( + client.list_goldengate_connections( request, metadata=[ ("key", "val"), @@ -48166,15 +68517,15 @@ def test_list_exadb_vm_clusters_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_get_exadb_vm_cluster_rest_bad_request( - request_type=oracledatabase.GetExadbVmClusterRequest, +def test_get_goldengate_connection_rest_bad_request( + request_type=goldengate_connection.GetGoldengateConnectionRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/exadbVmClusters/sample3" + "name": "projects/sample1/locations/sample2/goldengateConnections/sample3" } request = request_type(**request_init) @@ -48191,38 +68542,37 @@ def test_get_exadb_vm_cluster_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_exadb_vm_cluster(request) + client.get_goldengate_connection(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.GetExadbVmClusterRequest, + goldengate_connection.GetGoldengateConnectionRequest, dict, ], ) -def test_get_exadb_vm_cluster_rest_call_success(request_type): +def test_get_goldengate_connection_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/exadbVmClusters/sample3" + "name": "projects/sample1/locations/sample2/goldengateConnections/sample3" } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = exadb_vm_cluster.ExadbVmCluster( + return_value = goldengate_connection.GoldengateConnection( name="name_value", gcp_oracle_zone="gcp_oracle_zone_value", odb_network="odb_network_value", odb_subnet="odb_subnet_value", - backup_odb_subnet="backup_odb_subnet_value", - display_name="display_name_value", entitlement_id="entitlement_id_value", + oci_url="oci_url_value", ) # Wrap the value into a proper Response obj @@ -48230,26 +68580,25 @@ def test_get_exadb_vm_cluster_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = exadb_vm_cluster.ExadbVmCluster.pb(return_value) + return_value = goldengate_connection.GoldengateConnection.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_exadb_vm_cluster(request) + response = client.get_goldengate_connection(request) # Establish that the response is the type that we expect. - assert isinstance(response, exadb_vm_cluster.ExadbVmCluster) + assert isinstance(response, goldengate_connection.GoldengateConnection) assert response.name == "name_value" assert response.gcp_oracle_zone == "gcp_oracle_zone_value" assert response.odb_network == "odb_network_value" assert response.odb_subnet == "odb_subnet_value" - assert response.backup_odb_subnet == "backup_odb_subnet_value" - assert response.display_name == "display_name_value" assert response.entitlement_id == "entitlement_id_value" + assert response.oci_url == "oci_url_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_exadb_vm_cluster_rest_interceptors(null_interceptor): +def test_get_goldengate_connection_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -48262,21 +68611,21 @@ def test_get_exadb_vm_cluster_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_get_exadb_vm_cluster" + transports.OracleDatabaseRestInterceptor, "post_get_goldengate_connection" ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_get_exadb_vm_cluster_with_metadata", + "post_get_goldengate_connection_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_get_exadb_vm_cluster" + transports.OracleDatabaseRestInterceptor, "pre_get_goldengate_connection" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.GetExadbVmClusterRequest.pb( - oracledatabase.GetExadbVmClusterRequest() + pb_message = goldengate_connection.GetGoldengateConnectionRequest.pb( + goldengate_connection.GetGoldengateConnectionRequest() ) transcode.return_value = { "method": "post", @@ -48288,21 +68637,24 @@ def test_get_exadb_vm_cluster_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = exadb_vm_cluster.ExadbVmCluster.to_json( - exadb_vm_cluster.ExadbVmCluster() + return_value = goldengate_connection.GoldengateConnection.to_json( + goldengate_connection.GoldengateConnection() ) req.return_value.content = return_value - request = oracledatabase.GetExadbVmClusterRequest() + request = goldengate_connection.GetGoldengateConnectionRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = exadb_vm_cluster.ExadbVmCluster() - post_with_metadata.return_value = exadb_vm_cluster.ExadbVmCluster(), metadata + post.return_value = goldengate_connection.GoldengateConnection() + post_with_metadata.return_value = ( + goldengate_connection.GoldengateConnection(), + metadata, + ) - client.get_exadb_vm_cluster( + client.get_goldengate_connection( request, metadata=[ ("key", "val"), @@ -48315,8 +68667,8 @@ def test_get_exadb_vm_cluster_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_create_exadb_vm_cluster_rest_bad_request( - request_type=oracledatabase.CreateExadbVmClusterRequest, +def test_create_goldengate_connection_rest_bad_request( + request_type=gco_goldengate_connection.CreateGoldengateConnectionRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" @@ -48338,67 +68690,406 @@ def test_create_exadb_vm_cluster_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_exadb_vm_cluster(request) + client.create_goldengate_connection(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.CreateExadbVmClusterRequest, + gco_goldengate_connection.CreateGoldengateConnectionRequest, dict, ], ) -def test_create_exadb_vm_cluster_rest_call_success(request_type): +def test_create_goldengate_connection_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = {"parent": "projects/sample1/locations/sample2"} - request_init["exadb_vm_cluster"] = { + request_init["goldengate_connection"] = { "name": "name_value", "properties": { - "cluster_name": "cluster_name_value", - "grid_image_id": "grid_image_id_value", - "node_count": 1070, - "enabled_ecpu_count_per_node": 2826, - "additional_ecpu_count_per_node": 3160, - "vm_file_system_storage": {"size_in_gbs_per_node": 2103}, - "license_model": 1, - "exascale_db_storage_vault": "exascale_db_storage_vault_value", - "hostname_prefix": "hostname_prefix_value", - "hostname": "hostname_value", - "ssh_public_keys": ["ssh_public_keys_value1", "ssh_public_keys_value2"], - "data_collection_options": { - "is_diagnostics_events_enabled": True, - "is_health_monitoring_enabled": True, - "is_incident_logs_enabled": True, + "oracle_connection_properties": { + "password": "password_value", + "password_secret_version": "password_secret_version_value", + "technology_type": "technology_type_value", + "username": "username_value", + "authentication_mode": 1, + "connection_string": "connection_string_value", + "session_mode": 1, + "gcp_oracle_database_id": "gcp_oracle_database_id_value", + "wallet_file": "wallet_file_value", }, - "time_zone": {"id": "id_value", "version": "version_value"}, + "goldengate_connection_properties": { + "password": "password_value", + "password_secret_version": "password_secret_version_value", + "technology_type": "technology_type_value", + "goldengate_deployment_id": "goldengate_deployment_id_value", + "host": "host_value", + "port": 453, + "username": "username_value", + }, + "generic_connection_properties": { + "technology_type": "technology_type_value", + "host": "host_value", + }, + "google_cloud_storage_connection_properties": { + "technology_type": "technology_type_value", + "service_account_key_file": "service_account_key_file_value", + }, + "google_big_query_connection_properties": { + "technology_type": "technology_type_value", + "service_account_key_file": "service_account_key_file_value", + }, + "mysql_connection_properties": { + "password": "password_value", + "password_secret_version": "password_secret_version_value", + "technology_type": "technology_type_value", + "username": "username_value", + "host": "host_value", + "port": 453, + "database": "database_value", + "security_protocol": 1, + "ssl_mode": 1, + "ssl_ca_file": "ssl_ca_file_value", + "ssl_crl_file": "ssl_crl_file_value", + "ssl_cert_file": "ssl_cert_file_value", + "ssl_key_file": "ssl_key_file_value", + "additional_attributes": [{"key": "key_value", "value": "value_value"}], + "db_system_id": "db_system_id_value", + }, + "kafka_connection_properties": { + "password": "password_value", + "password_secret_version": "password_secret_version_value", + "trust_store_password": "trust_store_password_value", + "trust_store_password_secret_version": "trust_store_password_secret_version_value", + "key_store_password": "key_store_password_value", + "key_store_password_secret_version": "key_store_password_secret_version_value", + "ssl_key_password": "ssl_key_password_value", + "ssl_key_password_secret_version": "ssl_key_password_secret_version_value", + "technology_type": "technology_type_value", + "stream_pool_id": "stream_pool_id_value", + "cluster_id": "cluster_id_value", + "bootstrap_servers": [ + { + "host": "host_value", + "port": 453, + "private_ip_address": "private_ip_address_value", + } + ], + "security_protocol": 1, + "username": "username_value", + "trust_store_file": "trust_store_file_value", + "key_store_file": "key_store_file_value", + "consumer_properties_file": "consumer_properties_file_value", + "producer_properties_file": "producer_properties_file_value", + "use_resource_principal": True, + }, + "kafka_schema_registry_connection_properties": { + "password": "password_value", + "password_secret_version": "password_secret_version_value", + "trust_store_password": "trust_store_password_value", + "trust_store_password_secret_version": "trust_store_password_secret_version_value", + "key_store_password": "key_store_password_value", + "key_store_password_secret_version": "key_store_password_secret_version_value", + "ssl_key_password": "ssl_key_password_value", + "ssl_key_password_secret_version": "ssl_key_password_secret_version_value", + "technology_type": "technology_type_value", + "url": "url_value", + "authentication_type": 1, + "username": "username_value", + "trust_store_file": "trust_store_file_value", + "key_store_file": "key_store_file_value", + }, + "oci_object_storage_connection_properties": { + "technology_type": "technology_type_value", + "tenancy_id": "tenancy_id_value", + "region": "region_value", + "user_id": "user_id_value", + "private_key_file": "private_key_file_value", + "private_key_passphrase_secret": "private_key_passphrase_secret_value", + "public_key_fingerprint": "public_key_fingerprint_value", + "use_resource_principal": True, + }, + "azure_data_lake_storage_connection_properties": { + "technology_type": "technology_type_value", + "authentication_type": 1, + "account": "account_value", + "account_key_secret": "account_key_secret_value", + "sas_token_secret": "sas_token_secret_value", + "azure_tenant_id": "azure_tenant_id_value", + "client_id": "client_id_value", + "client_secret": "client_secret_value", + "endpoint": "endpoint_value", + "azure_authority_host": "azure_authority_host_value", + }, + "azure_synapse_analytics_connection_properties": { + "password": "password_value", + "password_secret_version": "password_secret_version_value", + "technology_type": "technology_type_value", + "connection_string": "connection_string_value", + "username": "username_value", + }, + "postgresql_connection_properties": { + "password": "password_value", + "password_secret_version": "password_secret_version_value", + "technology_type": "technology_type_value", + "database": "database_value", + "host": "host_value", + "port": 453, + "username": "username_value", + "additional_attributes": {}, + "security_protocol": 1, + "ssl_mode": 1, + "ssl_ca_file": "ssl_ca_file_value", + "ssl_crl_file": "ssl_crl_file_value", + "ssl_cert_file": "ssl_cert_file_value", + "ssl_key_file": "ssl_key_file_value", + "db_system_id": "db_system_id_value", + }, + "microsoft_sqlserver_connection_properties": { + "password": "password_value", + "password_secret_version": "password_secret_version_value", + "technology_type": "technology_type_value", + "database": "database_value", + "host": "host_value", + "port": 453, + "username": "username_value", + "additional_attributes": {}, + "security_protocol": 1, + "ssl_ca_file": "ssl_ca_file_value", + "server_certificate_validation_required": True, + }, + "amazon_s3_connection_properties": { + "technology_type": "technology_type_value", + "access_key_id": "access_key_id_value", + "secret_access_key_secret": "secret_access_key_secret_value", + "endpoint": "endpoint_value", + "region": "region_value", + }, + "hdfs_connection_properties": { + "technology_type": "technology_type_value", + "core_site_xml": "core_site_xml_value", + }, + "java_message_service_connection_properties": { + "password": "password_value", + "password_secret_version": "password_secret_version_value", + "trust_store_password": "trust_store_password_value", + "trust_store_password_secret_version": "trust_store_password_secret_version_value", + "key_store_password": "key_store_password_value", + "key_store_password_secret_version": "key_store_password_secret_version_value", + "ssl_key_password": "ssl_key_password_value", + "ssl_key_password_secret_version": "ssl_key_password_secret_version_value", + "technology_type": "technology_type_value", + "use_jndi": True, + "jndi_connection_factory": "jndi_connection_factory_value", + "jndi_provider_url": "jndi_provider_url_value", + "jndi_initial_context_factory": "jndi_initial_context_factory_value", + "jndi_security_principal": "jndi_security_principal_value", + "jndi_security_credentials_secret": "jndi_security_credentials_secret_value", + "connection_url": "connection_url_value", + "connection_factory": "connection_factory_value", + "username": "username_value", + "security_protocol": 1, + "authentication_type": 1, + "trust_store_file": "trust_store_file_value", + "key_store_file": "key_store_file_value", + }, + "mongodb_connection_properties": { + "password": "password_value", + "password_secret_version": "password_secret_version_value", + "tls_certificate_key_file_password": "tls_certificate_key_file_password_value", + "tls_certificate_key_file_password_secret_version": "tls_certificate_key_file_password_secret_version_value", + "technology_type": "technology_type_value", + "connection_string": "connection_string_value", + "username": "username_value", + "database_id": "database_id_value", + "security_protocol": 1, + "tls_ca_file": "tls_ca_file_value", + "tls_certificate_key_file": "tls_certificate_key_file_value", + }, + "oracle_nosql_connection_properties": { + "technology_type": "technology_type_value", + "tenancy_id": "tenancy_id_value", + "region": "region_value", + "user_id": "user_id_value", + "private_key_file": "private_key_file_value", + "private_key_passphrase_secret": "private_key_passphrase_secret_value", + "public_key_fingerprint": "public_key_fingerprint_value", + "use_resource_principal": True, + }, + "snowflake_connection_properties": { + "password": "password_value", + "password_secret_version": "password_secret_version_value", + "technology_type": "technology_type_value", + "connection_url": "connection_url_value", + "authentication_type": 1, + "username": "username_value", + "private_key_file": "private_key_file_value", + "private_key_passphrase_secret": "private_key_passphrase_secret_value", + }, + "amazon_redshift_connection_properties": { + "password": "password_value", + "password_secret_version": "password_secret_version_value", + "technology_type": "technology_type_value", + "connection_url": "connection_url_value", + "username": "username_value", + }, + "elasticsearch_connection_properties": { + "password": "password_value", + "password_secret_version": "password_secret_version_value", + "technology_type": "technology_type_value", + "servers": "servers_value", + "security_protocol": 1, + "authentication_type": 1, + "username": "username_value", + "fingerprint": "fingerprint_value", + }, + "amazon_kinesis_connection_properties": { + "technology_type": "technology_type_value", + "access_key_id": "access_key_id_value", + "secret_access_key_secret": "secret_access_key_secret_value", + "endpoint": "endpoint_value", + "aws_region": "aws_region_value", + }, + "db2_connection_properties": { + "password": "password_value", + "password_secret_version": "password_secret_version_value", + "technology_type": "technology_type_value", + "host": "host_value", + "port": 453, + "database": "database_value", + "username": "username_value", + "security_protocol": 1, + "additional_attributes": {}, + "ssl_client_keystoredb_file": "ssl_client_keystoredb_file_value", + "ssl_client_keystash_file": "ssl_client_keystash_file_value", + "ssl_server_certificate_file": "ssl_server_certificate_file_value", + }, + "redis_connection_properties": { + "password": "password_value", + "password_secret_version": "password_secret_version_value", + "trust_store_password": "trust_store_password_value", + "trust_store_password_secret_version": "trust_store_password_secret_version_value", + "key_store_password": "key_store_password_value", + "key_store_password_secret_version": "key_store_password_secret_version_value", + "technology_type": "technology_type_value", + "servers": "servers_value", + "security_protocol": 1, + "authentication_type": 1, + "username": "username_value", + "redis_cluster_id": "redis_cluster_id_value", + "trust_store_file": "trust_store_file_value", + "key_store_file": "key_store_file_value", + }, + "databricks_connection_properties": { + "password": "password_value", + "password_secret_version": "password_secret_version_value", + "technology_type": "technology_type_value", + "authentication_type": 1, + "connection_url": "connection_url_value", + "client_id": "client_id_value", + "client_secret": "client_secret_value", + "storage_credential": "storage_credential_value", + }, + "google_pubsub_connection_properties": { + "technology_type": "technology_type_value", + "service_account_key_file": "service_account_key_file_value", + }, + "microsoft_fabric_connection_properties": { + "technology_type": "technology_type_value", + "tenant_id": "tenant_id_value", + "client_id": "client_id_value", + "client_secret": "client_secret_value", + "endpoint": "endpoint_value", + }, + "oracle_ai_data_platform_connection_properties": { + "technology_type": "technology_type_value", + "connection_url": "connection_url_value", + "tenancy_id": "tenancy_id_value", + "region": "region_value", + "user_id": "user_id_value", + "private_key_file": "private_key_file_value", + "private_key_passphrase_secret": "private_key_passphrase_secret_value", + "public_key_fingerprint": "public_key_fingerprint_value", + "use_resource_principal": True, + }, + "iceberg_connection_properties": { + "technology_type": "technology_type_value", + "catalog": { + "glue_iceberg_catalog": {"glue_id": "glue_id_value"}, + "nessie_iceberg_catalog": { + "uri": "uri_value", + "branch": "branch_value", + }, + "polaris_iceberg_catalog": { + "uri": "uri_value", + "polaris_catalog": "polaris_catalog_value", + "client_id": "client_id_value", + "principal_role": "principal_role_value", + "client_secret": "client_secret_value", + }, + "rest_iceberg_catalog": { + "uri": "uri_value", + "properties": "properties_value", + }, + "catalog_type": 1, + }, + "storage": { + "amazon_s3_iceberg_storage": { + "scheme_type": 1, + "access_key_id": "access_key_id_value", + "region": "region_value", + "bucket": "bucket_value", + "endpoint": "endpoint_value", + "secret_access_key_secret": "secret_access_key_secret_value", + }, + "google_cloud_storage_iceberg_storage": { + "bucket": "bucket_value", + "project_id": "project_id_value", + "service_account_key_file": "service_account_key_file_value", + }, + "azure_data_lake_storage_iceberg_storage": { + "azure_account": "azure_account_value", + "container": "container_value", + "account_key_secret": "account_key_secret_value", + "endpoint": "endpoint_value", + }, + "storage_type": 1, + }, + }, + "connection_type": 1, + "ocid": "ocid_value", + "display_name": "display_name_value", + "description": "description_value", "lifecycle_state": 1, - "shape_attribute": 1, - "memory_size_gb": 1499, - "scan_listener_port_tcp": 2356, - "oci_uri": "oci_uri_value", - "gi_version": "gi_version_value", + "lifecycle_details": "lifecycle_details_value", + "update_time": {"seconds": 751, "nanos": 543}, + "routing_method": 1, + "ingress_ip_addresses": [ + "ingress_ip_addresses_value1", + "ingress_ip_addresses_value2", + ], }, "gcp_oracle_zone": "gcp_oracle_zone_value", "labels": {}, "odb_network": "odb_network_value", "odb_subnet": "odb_subnet_value", - "backup_odb_subnet": "backup_odb_subnet_value", - "display_name": "display_name_value", - "create_time": {"seconds": 751, "nanos": 543}, "entitlement_id": "entitlement_id_value", + "create_time": {}, + "oci_url": "oci_url_value", } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = oracledatabase.CreateExadbVmClusterRequest.meta.fields[ - "exadb_vm_cluster" - ] + test_field = ( + gco_goldengate_connection.CreateGoldengateConnectionRequest.meta.fields[ + "goldengate_connection" + ] + ) def get_message_fields(field): # Given a field which is a message (composite type), return a list with @@ -48426,7 +69117,9 @@ def get_message_fields(field): # For each item in the sample request, create a list of sub fields which are not present at runtime # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["exadb_vm_cluster"].items(): # pragma: NO COVER + for field, value in request_init[ + "goldengate_connection" + ].items(): # pragma: NO COVER result = None is_repeated = False # For repeated fields @@ -48456,10 +69149,10 @@ def get_message_fields(field): subfield = subfield_to_delete.get("subfield") if subfield: if field_repeated: - for i in range(0, len(request_init["exadb_vm_cluster"][field])): - del request_init["exadb_vm_cluster"][field][i][subfield] + for i in range(0, len(request_init["goldengate_connection"][field])): + del request_init["goldengate_connection"][field][i][subfield] else: - del request_init["exadb_vm_cluster"][field][subfield] + del request_init["goldengate_connection"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -48474,14 +69167,14 @@ def get_message_fields(field): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_exadb_vm_cluster(request) + response = client.create_goldengate_connection(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_exadb_vm_cluster_rest_interceptors(null_interceptor): +def test_create_goldengate_connection_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -48495,21 +69188,22 @@ def test_create_exadb_vm_cluster_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_create_exadb_vm_cluster" + transports.OracleDatabaseRestInterceptor, + "post_create_goldengate_connection", ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_create_exadb_vm_cluster_with_metadata", + "post_create_goldengate_connection_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_create_exadb_vm_cluster" + transports.OracleDatabaseRestInterceptor, "pre_create_goldengate_connection" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.CreateExadbVmClusterRequest.pb( - oracledatabase.CreateExadbVmClusterRequest() + pb_message = gco_goldengate_connection.CreateGoldengateConnectionRequest.pb( + gco_goldengate_connection.CreateGoldengateConnectionRequest() ) transcode.return_value = { "method": "post", @@ -48524,7 +69218,7 @@ def test_create_exadb_vm_cluster_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = oracledatabase.CreateExadbVmClusterRequest() + request = gco_goldengate_connection.CreateGoldengateConnectionRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -48533,7 +69227,7 @@ def test_create_exadb_vm_cluster_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.create_exadb_vm_cluster( + client.create_goldengate_connection( request, metadata=[ ("key", "val"), @@ -48546,15 +69240,15 @@ def test_create_exadb_vm_cluster_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_delete_exadb_vm_cluster_rest_bad_request( - request_type=oracledatabase.DeleteExadbVmClusterRequest, +def test_delete_goldengate_connection_rest_bad_request( + request_type=goldengate_connection.DeleteGoldengateConnectionRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/exadbVmClusters/sample3" + "name": "projects/sample1/locations/sample2/goldengateConnections/sample3" } request = request_type(**request_init) @@ -48571,24 +69265,24 @@ def test_delete_exadb_vm_cluster_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_exadb_vm_cluster(request) + client.delete_goldengate_connection(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.DeleteExadbVmClusterRequest, + goldengate_connection.DeleteGoldengateConnectionRequest, dict, ], ) -def test_delete_exadb_vm_cluster_rest_call_success(request_type): +def test_delete_goldengate_connection_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/exadbVmClusters/sample3" + "name": "projects/sample1/locations/sample2/goldengateConnections/sample3" } request = request_type(**request_init) @@ -48604,14 +69298,14 @@ def test_delete_exadb_vm_cluster_rest_call_success(request_type): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_exadb_vm_cluster(request) + response = client.delete_goldengate_connection(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_exadb_vm_cluster_rest_interceptors(null_interceptor): +def test_delete_goldengate_connection_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -48625,21 +69319,22 @@ def test_delete_exadb_vm_cluster_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_delete_exadb_vm_cluster" + transports.OracleDatabaseRestInterceptor, + "post_delete_goldengate_connection", ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_delete_exadb_vm_cluster_with_metadata", + "post_delete_goldengate_connection_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_delete_exadb_vm_cluster" + transports.OracleDatabaseRestInterceptor, "pre_delete_goldengate_connection" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.DeleteExadbVmClusterRequest.pb( - oracledatabase.DeleteExadbVmClusterRequest() + pb_message = goldengate_connection.DeleteGoldengateConnectionRequest.pb( + goldengate_connection.DeleteGoldengateConnectionRequest() ) transcode.return_value = { "method": "post", @@ -48654,7 +69349,7 @@ def test_delete_exadb_vm_cluster_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = oracledatabase.DeleteExadbVmClusterRequest() + request = goldengate_connection.DeleteGoldengateConnectionRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -48663,7 +69358,7 @@ def test_delete_exadb_vm_cluster_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.delete_exadb_vm_cluster( + client.delete_goldengate_connection( request, metadata=[ ("key", "val"), @@ -48676,17 +69371,15 @@ def test_delete_exadb_vm_cluster_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_update_exadb_vm_cluster_rest_bad_request( - request_type=oracledatabase.UpdateExadbVmClusterRequest, +def test_get_goldengate_deployment_version_rest_bad_request( + request_type=goldengate_deployment_version.GetGoldengateDeploymentVersionRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "exadb_vm_cluster": { - "name": "projects/sample1/locations/sample2/exadbVmClusters/sample3" - } + "name": "projects/sample1/locations/sample2/goldengateDeploymentVersions/sample3" } request = request_type(**request_init) @@ -48703,284 +69396,59 @@ def test_update_exadb_vm_cluster_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_exadb_vm_cluster(request) + client.get_goldengate_deployment_version(request) @pytest.mark.parametrize( "request_type", [ - oracledatabase.UpdateExadbVmClusterRequest, + goldengate_deployment_version.GetGoldengateDeploymentVersionRequest, dict, ], ) -def test_update_exadb_vm_cluster_rest_call_success(request_type): +def test_get_goldengate_deployment_version_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "exadb_vm_cluster": { - "name": "projects/sample1/locations/sample2/exadbVmClusters/sample3" - } - } - request_init["exadb_vm_cluster"] = { - "name": "projects/sample1/locations/sample2/exadbVmClusters/sample3", - "properties": { - "cluster_name": "cluster_name_value", - "grid_image_id": "grid_image_id_value", - "node_count": 1070, - "enabled_ecpu_count_per_node": 2826, - "additional_ecpu_count_per_node": 3160, - "vm_file_system_storage": {"size_in_gbs_per_node": 2103}, - "license_model": 1, - "exascale_db_storage_vault": "exascale_db_storage_vault_value", - "hostname_prefix": "hostname_prefix_value", - "hostname": "hostname_value", - "ssh_public_keys": ["ssh_public_keys_value1", "ssh_public_keys_value2"], - "data_collection_options": { - "is_diagnostics_events_enabled": True, - "is_health_monitoring_enabled": True, - "is_incident_logs_enabled": True, - }, - "time_zone": {"id": "id_value", "version": "version_value"}, - "lifecycle_state": 1, - "shape_attribute": 1, - "memory_size_gb": 1499, - "scan_listener_port_tcp": 2356, - "oci_uri": "oci_uri_value", - "gi_version": "gi_version_value", - }, - "gcp_oracle_zone": "gcp_oracle_zone_value", - "labels": {}, - "odb_network": "odb_network_value", - "odb_subnet": "odb_subnet_value", - "backup_odb_subnet": "backup_odb_subnet_value", - "display_name": "display_name_value", - "create_time": {"seconds": 751, "nanos": 543}, - "entitlement_id": "entitlement_id_value", + "name": "projects/sample1/locations/sample2/goldengateDeploymentVersions/sample3" } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = oracledatabase.UpdateExadbVmClusterRequest.meta.fields[ - "exadb_vm_cluster" - ] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["exadb_vm_cluster"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["exadb_vm_cluster"][field])): - del request_init["exadb_vm_cluster"][field][i][subfield] - else: - del request_init["exadb_vm_cluster"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = goldengate_deployment_version.GoldengateDeploymentVersion( + name="name_value", + ocid="ocid_value", + ) # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value.content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_exadb_vm_cluster(request) - - # Establish that the response is the type that we expect. - json_return_value = json_format.MessageToJson(return_value) - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_exadb_vm_cluster_rest_interceptors(null_interceptor): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.OracleDatabaseRestInterceptor(), - ) - client = OracleDatabaseClient(transport=transport) - - with ( - mock.patch.object(type(client.transport._session), "request") as req, - mock.patch.object(path_template, "transcode") as transcode, - mock.patch.object(operation.Operation, "_set_result_from_operation"), - mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_update_exadb_vm_cluster" - ) as post, - mock.patch.object( - transports.OracleDatabaseRestInterceptor, - "post_update_exadb_vm_cluster_with_metadata", - ) as post_with_metadata, - mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_update_exadb_vm_cluster" - ) as pre, - ): - pre.assert_not_called() - post.assert_not_called() - post_with_metadata.assert_not_called() - pb_message = oracledatabase.UpdateExadbVmClusterRequest.pb( - oracledatabase.UpdateExadbVmClusterRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = mock.Mock() - req.return_value.status_code = 200 - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = json_format.MessageToJson(operations_pb2.Operation()) - req.return_value.content = return_value - - request = oracledatabase.UpdateExadbVmClusterRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() - post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.update_exadb_vm_cluster( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], + # Convert return value to protobuf type + return_value = goldengate_deployment_version.GoldengateDeploymentVersion.pb( + return_value ) - - pre.assert_called_once() - post.assert_called_once() - post_with_metadata.assert_called_once() - - -def test_remove_virtual_machine_exadb_vm_cluster_rest_bad_request( - request_type=oracledatabase.RemoveVirtualMachineExadbVmClusterRequest, -): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/exadbVmClusters/sample3" - } - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with ( - mock.patch.object(Session, "request") as req, - pytest.raises(core_exceptions.BadRequest), - ): - # Wrap the value into a proper Response obj - response_value = mock.Mock() - json_return_value = "" - response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.remove_virtual_machine_exadb_vm_cluster(request) - - -@pytest.mark.parametrize( - "request_type", - [ - oracledatabase.RemoveVirtualMachineExadbVmClusterRequest, - dict, - ], -) -def test_remove_virtual_machine_exadb_vm_cluster_rest_call_success(request_type): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/exadbVmClusters/sample3" - } - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # Wrap the value into a proper Response obj - response_value = mock.Mock() - response_value.status_code = 200 json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.remove_virtual_machine_exadb_vm_cluster(request) + response = client.get_goldengate_deployment_version(request) # Establish that the response is the type that we expect. - json_return_value = json_format.MessageToJson(return_value) + assert isinstance( + response, goldengate_deployment_version.GoldengateDeploymentVersion + ) + assert response.name == "name_value" + assert response.ocid == "ocid_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_remove_virtual_machine_exadb_vm_cluster_rest_interceptors(null_interceptor): +def test_get_goldengate_deployment_version_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -48992,25 +69460,26 @@ def test_remove_virtual_machine_exadb_vm_cluster_rest_interceptors(null_intercep with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, - mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_remove_virtual_machine_exadb_vm_cluster", + "post_get_goldengate_deployment_version", ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_remove_virtual_machine_exadb_vm_cluster_with_metadata", + "post_get_goldengate_deployment_version_with_metadata", ) as post_with_metadata, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "pre_remove_virtual_machine_exadb_vm_cluster", + "pre_get_goldengate_deployment_version", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = oracledatabase.RemoveVirtualMachineExadbVmClusterRequest.pb( - oracledatabase.RemoveVirtualMachineExadbVmClusterRequest() + pb_message = ( + goldengate_deployment_version.GetGoldengateDeploymentVersionRequest.pb( + goldengate_deployment_version.GetGoldengateDeploymentVersionRequest() + ) ) transcode.return_value = { "method": "post", @@ -49022,19 +69491,26 @@ def test_remove_virtual_machine_exadb_vm_cluster_rest_interceptors(null_intercep req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = json_format.MessageToJson(operations_pb2.Operation()) + return_value = ( + goldengate_deployment_version.GoldengateDeploymentVersion.to_json( + goldengate_deployment_version.GoldengateDeploymentVersion() + ) + ) req.return_value.content = return_value - request = oracledatabase.RemoveVirtualMachineExadbVmClusterRequest() + request = goldengate_deployment_version.GetGoldengateDeploymentVersionRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() - post_with_metadata.return_value = operations_pb2.Operation(), metadata + post.return_value = goldengate_deployment_version.GoldengateDeploymentVersion() + post_with_metadata.return_value = ( + goldengate_deployment_version.GoldengateDeploymentVersion(), + metadata, + ) - client.remove_virtual_machine_exadb_vm_cluster( + client.get_goldengate_deployment_version( request, metadata=[ ("key", "val"), @@ -49047,8 +69523,8 @@ def test_remove_virtual_machine_exadb_vm_cluster_rest_interceptors(null_intercep post_with_metadata.assert_called_once() -def test_list_exascale_db_storage_vaults_rest_bad_request( - request_type=exascale_db_storage_vault.ListExascaleDbStorageVaultsRequest, +def test_list_goldengate_deployment_versions_rest_bad_request( + request_type=goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" @@ -49070,17 +69546,17 @@ def test_list_exascale_db_storage_vaults_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_exascale_db_storage_vaults(request) + client.list_goldengate_deployment_versions(request) @pytest.mark.parametrize( "request_type", [ - exascale_db_storage_vault.ListExascaleDbStorageVaultsRequest, + goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest, dict, ], ) -def test_list_exascale_db_storage_vaults_rest_call_success(request_type): +def test_list_goldengate_deployment_versions_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -49092,8 +69568,11 @@ def test_list_exascale_db_storage_vaults_rest_call_success(request_type): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse( - next_page_token="next_page_token_value", + return_value = ( + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) ) # Wrap the value into a proper Response obj @@ -49101,22 +69580,25 @@ def test_list_exascale_db_storage_vaults_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse.pb( - return_value + return_value = ( + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse.pb( + return_value + ) ) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_exascale_db_storage_vaults(request) + response = client.list_goldengate_deployment_versions(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListExascaleDbStorageVaultsPager) + assert isinstance(response, pagers.ListGoldengateDeploymentVersionsPager) assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_exascale_db_storage_vaults_rest_interceptors(null_interceptor): +def test_list_goldengate_deployment_versions_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -49130,22 +69612,24 @@ def test_list_exascale_db_storage_vaults_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_list_exascale_db_storage_vaults", + "post_list_goldengate_deployment_versions", ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_list_exascale_db_storage_vaults_with_metadata", + "post_list_goldengate_deployment_versions_with_metadata", ) as post_with_metadata, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "pre_list_exascale_db_storage_vaults", + "pre_list_goldengate_deployment_versions", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = exascale_db_storage_vault.ListExascaleDbStorageVaultsRequest.pb( - exascale_db_storage_vault.ListExascaleDbStorageVaultsRequest() + pb_message = ( + goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest.pb( + goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest() + ) ) transcode.return_value = { "method": "post", @@ -49157,28 +69641,28 @@ def test_list_exascale_db_storage_vaults_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = ( - exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse.to_json( - exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse() - ) + return_value = goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse.to_json( + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse() ) req.return_value.content = return_value - request = exascale_db_storage_vault.ListExascaleDbStorageVaultsRequest() + request = ( + goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest() + ) metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata post.return_value = ( - exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse() + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse() ) post_with_metadata.return_value = ( - exascale_db_storage_vault.ListExascaleDbStorageVaultsResponse(), + goldengate_deployment_version.ListGoldengateDeploymentVersionsResponse(), metadata, ) - client.list_exascale_db_storage_vaults( + client.list_goldengate_deployment_versions( request, metadata=[ ("key", "val"), @@ -49191,15 +69675,15 @@ def test_list_exascale_db_storage_vaults_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_get_exascale_db_storage_vault_rest_bad_request( - request_type=exascale_db_storage_vault.GetExascaleDbStorageVaultRequest, +def test_get_goldengate_deployment_type_rest_bad_request( + request_type=goldengate_deployment_type.GetGoldengateDeploymentTypeRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/exascaleDbStorageVaults/sample3" + "name": "projects/sample1/locations/sample2/goldengateDeploymentTypes/sample3" } request = request_type(**request_init) @@ -49216,35 +69700,42 @@ def test_get_exascale_db_storage_vault_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_exascale_db_storage_vault(request) + client.get_goldengate_deployment_type(request) @pytest.mark.parametrize( "request_type", [ - exascale_db_storage_vault.GetExascaleDbStorageVaultRequest, + goldengate_deployment_type.GetGoldengateDeploymentTypeRequest, dict, ], ) -def test_get_exascale_db_storage_vault_rest_call_success(request_type): +def test_get_goldengate_deployment_type_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/exascaleDbStorageVaults/sample3" + "name": "projects/sample1/locations/sample2/goldengateDeploymentTypes/sample3" } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = exascale_db_storage_vault.ExascaleDbStorageVault( + return_value = goldengate_deployment_type.GoldengateDeploymentType( name="name_value", + deployment_type=goldengate_deployment_type.GoldengateDeploymentType.DeploymentType.OGG, + category=goldengate_deployment_type.GoldengateDeploymentType.DeploymentCategory.DATA_REPLICATION_CATEGORY, + connection_types=["connection_types_value"], display_name="display_name_value", - gcp_oracle_zone="gcp_oracle_zone_value", - entitlement_id="entitlement_id_value", + ogg_version="ogg_version_value", + source_technologies=["source_technologies_value"], + supported_capabilities=["supported_capabilities_value"], + supported_technologies_url="supported_technologies_url_value", + target_technologies=["target_technologies_value"], + default_username="default_username_value", ) # Wrap the value into a proper Response obj @@ -49252,23 +69743,38 @@ def test_get_exascale_db_storage_vault_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = exascale_db_storage_vault.ExascaleDbStorageVault.pb(return_value) + return_value = goldengate_deployment_type.GoldengateDeploymentType.pb( + return_value + ) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_exascale_db_storage_vault(request) + response = client.get_goldengate_deployment_type(request) # Establish that the response is the type that we expect. - assert isinstance(response, exascale_db_storage_vault.ExascaleDbStorageVault) + assert isinstance(response, goldengate_deployment_type.GoldengateDeploymentType) assert response.name == "name_value" + assert ( + response.deployment_type + == goldengate_deployment_type.GoldengateDeploymentType.DeploymentType.OGG + ) + assert ( + response.category + == goldengate_deployment_type.GoldengateDeploymentType.DeploymentCategory.DATA_REPLICATION_CATEGORY + ) + assert response.connection_types == ["connection_types_value"] assert response.display_name == "display_name_value" - assert response.gcp_oracle_zone == "gcp_oracle_zone_value" - assert response.entitlement_id == "entitlement_id_value" + assert response.ogg_version == "ogg_version_value" + assert response.source_technologies == ["source_technologies_value"] + assert response.supported_capabilities == ["supported_capabilities_value"] + assert response.supported_technologies_url == "supported_technologies_url_value" + assert response.target_technologies == ["target_technologies_value"] + assert response.default_username == "default_username_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_exascale_db_storage_vault_rest_interceptors(null_interceptor): +def test_get_goldengate_deployment_type_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -49282,22 +69788,22 @@ def test_get_exascale_db_storage_vault_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_get_exascale_db_storage_vault", + "post_get_goldengate_deployment_type", ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_get_exascale_db_storage_vault_with_metadata", + "post_get_goldengate_deployment_type_with_metadata", ) as post_with_metadata, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "pre_get_exascale_db_storage_vault", + "pre_get_goldengate_deployment_type", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = exascale_db_storage_vault.GetExascaleDbStorageVaultRequest.pb( - exascale_db_storage_vault.GetExascaleDbStorageVaultRequest() + pb_message = goldengate_deployment_type.GetGoldengateDeploymentTypeRequest.pb( + goldengate_deployment_type.GetGoldengateDeploymentTypeRequest() ) transcode.return_value = { "method": "post", @@ -49309,24 +69815,24 @@ def test_get_exascale_db_storage_vault_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = exascale_db_storage_vault.ExascaleDbStorageVault.to_json( - exascale_db_storage_vault.ExascaleDbStorageVault() + return_value = goldengate_deployment_type.GoldengateDeploymentType.to_json( + goldengate_deployment_type.GoldengateDeploymentType() ) req.return_value.content = return_value - request = exascale_db_storage_vault.GetExascaleDbStorageVaultRequest() + request = goldengate_deployment_type.GetGoldengateDeploymentTypeRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = exascale_db_storage_vault.ExascaleDbStorageVault() + post.return_value = goldengate_deployment_type.GoldengateDeploymentType() post_with_metadata.return_value = ( - exascale_db_storage_vault.ExascaleDbStorageVault(), + goldengate_deployment_type.GoldengateDeploymentType(), metadata, ) - client.get_exascale_db_storage_vault( + client.get_goldengate_deployment_type( request, metadata=[ ("key", "val"), @@ -49339,8 +69845,8 @@ def test_get_exascale_db_storage_vault_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_create_exascale_db_storage_vault_rest_bad_request( - request_type=gco_exascale_db_storage_vault.CreateExascaleDbStorageVaultRequest, +def test_list_goldengate_deployment_types_rest_bad_request( + request_type=goldengate_deployment_type.ListGoldengateDeploymentTypesRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" @@ -49362,144 +69868,57 @@ def test_create_exascale_db_storage_vault_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_exascale_db_storage_vault(request) + client.list_goldengate_deployment_types(request) @pytest.mark.parametrize( "request_type", [ - gco_exascale_db_storage_vault.CreateExascaleDbStorageVaultRequest, + goldengate_deployment_type.ListGoldengateDeploymentTypesRequest, dict, ], ) -def test_create_exascale_db_storage_vault_rest_call_success(request_type): +def test_list_goldengate_deployment_types_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = {"parent": "projects/sample1/locations/sample2"} - request_init["exascale_db_storage_vault"] = { - "name": "name_value", - "display_name": "display_name_value", - "gcp_oracle_zone": "gcp_oracle_zone_value", - "properties": { - "ocid": "ocid_value", - "time_zone": {"id": "id_value", "version": "version_value"}, - "exascale_db_storage_details": { - "available_size_gbs": 1878, - "total_size_gbs": 1497, - }, - "state": 1, - "description": "description_value", - "vm_cluster_ids": ["vm_cluster_ids_value1", "vm_cluster_ids_value2"], - "vm_cluster_count": 1740, - "additional_flash_cache_percent": 3113, - "oci_uri": "oci_uri_value", - "attached_shape_attributes": [1], - "available_shape_attributes": [1], - }, - "create_time": {"seconds": 751, "nanos": 543}, - "entitlement_id": "entitlement_id_value", - "labels": {}, - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = ( - gco_exascale_db_storage_vault.CreateExascaleDbStorageVaultRequest.meta.fields[ - "exascale_db_storage_vault" - ] - ) - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init[ - "exascale_db_storage_vault" - ].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range( - 0, len(request_init["exascale_db_storage_vault"][field]) - ): - del request_init["exascale_db_storage_vault"][field][i][subfield] - else: - del request_init["exascale_db_storage_vault"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = goldengate_deployment_type.ListGoldengateDeploymentTypesResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = ( + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse.pb( + return_value + ) + ) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_exascale_db_storage_vault(request) + response = client.list_goldengate_deployment_types(request) # Establish that the response is the type that we expect. - json_return_value = json_format.MessageToJson(return_value) + assert isinstance(response, pagers.ListGoldengateDeploymentTypesPager) + assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_exascale_db_storage_vault_rest_interceptors(null_interceptor): +def test_list_goldengate_deployment_types_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -49511,27 +69930,24 @@ def test_create_exascale_db_storage_vault_rest_interceptors(null_interceptor): with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, - mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_create_exascale_db_storage_vault", + "post_list_goldengate_deployment_types", ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_create_exascale_db_storage_vault_with_metadata", + "post_list_goldengate_deployment_types_with_metadata", ) as post_with_metadata, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "pre_create_exascale_db_storage_vault", + "pre_list_goldengate_deployment_types", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = ( - gco_exascale_db_storage_vault.CreateExascaleDbStorageVaultRequest.pb( - gco_exascale_db_storage_vault.CreateExascaleDbStorageVaultRequest() - ) + pb_message = goldengate_deployment_type.ListGoldengateDeploymentTypesRequest.pb( + goldengate_deployment_type.ListGoldengateDeploymentTypesRequest() ) transcode.return_value = { "method": "post", @@ -49543,19 +69959,28 @@ def test_create_exascale_db_storage_vault_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = json_format.MessageToJson(operations_pb2.Operation()) + return_value = ( + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse.to_json( + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse() + ) + ) req.return_value.content = return_value - request = gco_exascale_db_storage_vault.CreateExascaleDbStorageVaultRequest() + request = goldengate_deployment_type.ListGoldengateDeploymentTypesRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() - post_with_metadata.return_value = operations_pb2.Operation(), metadata + post.return_value = ( + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse() + ) + post_with_metadata.return_value = ( + goldengate_deployment_type.ListGoldengateDeploymentTypesResponse(), + metadata, + ) - client.create_exascale_db_storage_vault( + client.list_goldengate_deployment_types( request, metadata=[ ("key", "val"), @@ -49568,15 +69993,15 @@ def test_create_exascale_db_storage_vault_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_delete_exascale_db_storage_vault_rest_bad_request( - request_type=exascale_db_storage_vault.DeleteExascaleDbStorageVaultRequest, +def test_get_goldengate_deployment_environment_rest_bad_request( + request_type=goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/exascaleDbStorageVaults/sample3" + "name": "projects/sample1/locations/sample2/goldengateDeploymentEnvironments/sample3" } request = request_type(**request_init) @@ -49593,47 +70018,85 @@ def test_delete_exascale_db_storage_vault_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_exascale_db_storage_vault(request) + client.get_goldengate_deployment_environment(request) @pytest.mark.parametrize( "request_type", [ - exascale_db_storage_vault.DeleteExascaleDbStorageVaultRequest, + goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest, dict, ], ) -def test_delete_exascale_db_storage_vault_rest_call_success(request_type): +def test_get_goldengate_deployment_environment_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/exascaleDbStorageVaults/sample3" + "name": "projects/sample1/locations/sample2/goldengateDeploymentEnvironments/sample3" } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = goldengate_deployment_environment.GoldengateDeploymentEnvironment( + name="name_value", + category=goldengate_deployment_environment.GoldengateDeploymentEnvironment.DeploymentCategory.DATA_REPLICATION_CATEGORY, + display_name="display_name_value", + default_cpu_core_count=2332, + environment_type=goldengate_deployment_environment.GoldengateDeploymentEnvironment.DeploymentEnvironmentType.PRODUCTION, + auto_scaling_enabled=True, + max_cpu_core_count=1917, + memory_gb_per_cpu_core=2326, + min_cpu_core_count=1915, + network_bandwidth_gbps_per_cpu_core=3710, + storage_usage_limit_gb_per_cpu_core=3684, + ) # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = ( + goldengate_deployment_environment.GoldengateDeploymentEnvironment.pb( + return_value + ) + ) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_exascale_db_storage_vault(request) + response = client.get_goldengate_deployment_environment(request) # Establish that the response is the type that we expect. - json_return_value = json_format.MessageToJson(return_value) + assert isinstance( + response, goldengate_deployment_environment.GoldengateDeploymentEnvironment + ) + assert response.name == "name_value" + assert ( + response.category + == goldengate_deployment_environment.GoldengateDeploymentEnvironment.DeploymentCategory.DATA_REPLICATION_CATEGORY + ) + assert response.display_name == "display_name_value" + assert response.default_cpu_core_count == 2332 + assert ( + response.environment_type + == goldengate_deployment_environment.GoldengateDeploymentEnvironment.DeploymentEnvironmentType.PRODUCTION + ) + assert response.auto_scaling_enabled is True + assert response.max_cpu_core_count == 1917 + assert response.memory_gb_per_cpu_core == 2326 + assert response.min_cpu_core_count == 1915 + assert response.network_bandwidth_gbps_per_cpu_core == 3710 + assert response.storage_usage_limit_gb_per_cpu_core == 3684 @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_exascale_db_storage_vault_rest_interceptors(null_interceptor): +def test_get_goldengate_deployment_environment_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -49645,25 +70108,24 @@ def test_delete_exascale_db_storage_vault_rest_interceptors(null_interceptor): with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, - mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_delete_exascale_db_storage_vault", + "post_get_goldengate_deployment_environment", ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_delete_exascale_db_storage_vault_with_metadata", + "post_get_goldengate_deployment_environment_with_metadata", ) as post_with_metadata, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "pre_delete_exascale_db_storage_vault", + "pre_get_goldengate_deployment_environment", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = exascale_db_storage_vault.DeleteExascaleDbStorageVaultRequest.pb( - exascale_db_storage_vault.DeleteExascaleDbStorageVaultRequest() + pb_message = goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest.pb( + goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest() ) transcode.return_value = { "method": "post", @@ -49675,19 +70137,28 @@ def test_delete_exascale_db_storage_vault_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = json_format.MessageToJson(operations_pb2.Operation()) + return_value = ( + goldengate_deployment_environment.GoldengateDeploymentEnvironment.to_json( + goldengate_deployment_environment.GoldengateDeploymentEnvironment() + ) + ) req.return_value.content = return_value - request = exascale_db_storage_vault.DeleteExascaleDbStorageVaultRequest() + request = goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() - post_with_metadata.return_value = operations_pb2.Operation(), metadata + post.return_value = ( + goldengate_deployment_environment.GoldengateDeploymentEnvironment() + ) + post_with_metadata.return_value = ( + goldengate_deployment_environment.GoldengateDeploymentEnvironment(), + metadata, + ) - client.delete_exascale_db_storage_vault( + client.get_goldengate_deployment_environment( request, metadata=[ ("key", "val"), @@ -49700,8 +70171,8 @@ def test_delete_exascale_db_storage_vault_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_db_system_initial_storage_sizes_rest_bad_request( - request_type=db_system_initial_storage_size.ListDbSystemInitialStorageSizesRequest, +def test_list_goldengate_deployment_environments_rest_bad_request( + request_type=goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" @@ -49723,17 +70194,17 @@ def test_list_db_system_initial_storage_sizes_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_db_system_initial_storage_sizes(request) + client.list_goldengate_deployment_environments(request) @pytest.mark.parametrize( "request_type", [ - db_system_initial_storage_size.ListDbSystemInitialStorageSizesRequest, + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest, dict, ], ) -def test_list_db_system_initial_storage_sizes_rest_call_success(request_type): +def test_list_goldengate_deployment_environments_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -49745,10 +70216,9 @@ def test_list_db_system_initial_storage_sizes_rest_call_success(request_type): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = ( - db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse( - next_page_token="next_page_token_value", - ) + return_value = goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], ) # Wrap the value into a proper Response obj @@ -49756,24 +70226,23 @@ def test_list_db_system_initial_storage_sizes_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = ( - db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse.pb( - return_value - ) + return_value = goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse.pb( + return_value ) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_db_system_initial_storage_sizes(request) + response = client.list_goldengate_deployment_environments(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListDbSystemInitialStorageSizesPager) + assert isinstance(response, pagers.ListGoldengateDeploymentEnvironmentsPager) assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_db_system_initial_storage_sizes_rest_interceptors(null_interceptor): +def test_list_goldengate_deployment_environments_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -49787,24 +70256,22 @@ def test_list_db_system_initial_storage_sizes_rest_interceptors(null_interceptor mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_list_db_system_initial_storage_sizes", + "post_list_goldengate_deployment_environments", ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_list_db_system_initial_storage_sizes_with_metadata", + "post_list_goldengate_deployment_environments_with_metadata", ) as post_with_metadata, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "pre_list_db_system_initial_storage_sizes", + "pre_list_goldengate_deployment_environments", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = ( - db_system_initial_storage_size.ListDbSystemInitialStorageSizesRequest.pb( - db_system_initial_storage_size.ListDbSystemInitialStorageSizesRequest() - ) + pb_message = goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest.pb( + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest() ) transcode.return_value = { "method": "post", @@ -49816,28 +70283,24 @@ def test_list_db_system_initial_storage_sizes_rest_interceptors(null_interceptor req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse.to_json( - db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse() + return_value = goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse.to_json( + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse() ) req.return_value.content = return_value - request = ( - db_system_initial_storage_size.ListDbSystemInitialStorageSizesRequest() - ) + request = goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = ( - db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse() - ) + post.return_value = goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse() post_with_metadata.return_value = ( - db_system_initial_storage_size.ListDbSystemInitialStorageSizesResponse(), + goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsResponse(), metadata, ) - client.list_db_system_initial_storage_sizes( + client.list_goldengate_deployment_environments( request, metadata=[ ("key", "val"), @@ -49850,12 +70313,16 @@ def test_list_db_system_initial_storage_sizes_rest_interceptors(null_interceptor post_with_metadata.assert_called_once() -def test_list_databases_rest_bad_request(request_type=database.ListDatabasesRequest): +def test_get_goldengate_connection_type_rest_bad_request( + request_type=goldengate_connection_type.GetGoldengateConnectionTypeRequest, +): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} + request_init = { + "name": "projects/sample1/locations/sample2/goldengateConnectionTypes/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -49871,30 +70338,34 @@ def test_list_databases_rest_bad_request(request_type=database.ListDatabasesRequ response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_databases(request) + client.get_goldengate_connection_type(request) @pytest.mark.parametrize( "request_type", [ - database.ListDatabasesRequest, + goldengate_connection_type.GetGoldengateConnectionTypeRequest, dict, ], ) -def test_list_databases_rest_call_success(request_type): +def test_get_goldengate_connection_type_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} + request_init = { + "name": "projects/sample1/locations/sample2/goldengateConnectionTypes/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = database.ListDatabasesResponse( - next_page_token="next_page_token_value", + return_value = goldengate_connection_type.GoldengateConnectionType( + name="name_value", + connection_type=goldengate_connection_type.GoldengateConnectionType.ConnectionType.GOLDENGATE, + technology_types=["technology_types_value"], ) # Wrap the value into a proper Response obj @@ -49902,20 +70373,27 @@ def test_list_databases_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = database.ListDatabasesResponse.pb(return_value) + return_value = goldengate_connection_type.GoldengateConnectionType.pb( + return_value + ) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_databases(request) + response = client.get_goldengate_connection_type(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListDatabasesPager) - assert response.next_page_token == "next_page_token_value" + assert isinstance(response, goldengate_connection_type.GoldengateConnectionType) + assert response.name == "name_value" + assert ( + response.connection_type + == goldengate_connection_type.GoldengateConnectionType.ConnectionType.GOLDENGATE + ) + assert response.technology_types == ["technology_types_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_databases_rest_interceptors(null_interceptor): +def test_get_goldengate_connection_type_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -49928,20 +70406,24 @@ def test_list_databases_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_list_databases" + transports.OracleDatabaseRestInterceptor, + "post_get_goldengate_connection_type", ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_list_databases_with_metadata", + "post_get_goldengate_connection_type_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_list_databases" + transports.OracleDatabaseRestInterceptor, + "pre_get_goldengate_connection_type", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = database.ListDatabasesRequest.pb(database.ListDatabasesRequest()) + pb_message = goldengate_connection_type.GetGoldengateConnectionTypeRequest.pb( + goldengate_connection_type.GetGoldengateConnectionTypeRequest() + ) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -49952,21 +70434,24 @@ def test_list_databases_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = database.ListDatabasesResponse.to_json( - database.ListDatabasesResponse() + return_value = goldengate_connection_type.GoldengateConnectionType.to_json( + goldengate_connection_type.GoldengateConnectionType() ) req.return_value.content = return_value - request = database.ListDatabasesRequest() + request = goldengate_connection_type.GetGoldengateConnectionTypeRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = database.ListDatabasesResponse() - post_with_metadata.return_value = database.ListDatabasesResponse(), metadata + post.return_value = goldengate_connection_type.GoldengateConnectionType() + post_with_metadata.return_value = ( + goldengate_connection_type.GoldengateConnectionType(), + metadata, + ) - client.list_databases( + client.get_goldengate_connection_type( request, metadata=[ ("key", "val"), @@ -49979,12 +70464,14 @@ def test_list_databases_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_get_database_rest_bad_request(request_type=database.GetDatabaseRequest): +def test_list_goldengate_connection_types_rest_bad_request( + request_type=goldengate_connection_type.ListGoldengateConnectionTypesRequest, +): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/databases/sample3"} + request_init = {"parent": "projects/sample1/locations/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -50000,41 +70487,31 @@ def test_get_database_rest_bad_request(request_type=database.GetDatabaseRequest) response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_database(request) + client.list_goldengate_connection_types(request) @pytest.mark.parametrize( "request_type", [ - database.GetDatabaseRequest, + goldengate_connection_type.ListGoldengateConnectionTypesRequest, dict, ], ) -def test_get_database_rest_call_success(request_type): +def test_list_goldengate_connection_types_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/databases/sample3"} + request_init = {"parent": "projects/sample1/locations/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = database.Database( - name="name_value", - db_name="db_name_value", - db_unique_name="db_unique_name_value", - admin_password="admin_password_value", - tde_wallet_password="tde_wallet_password_value", - character_set="character_set_value", - ncharacter_set="ncharacter_set_value", - oci_url="oci_url_value", - database_id="database_id_value", - db_home_name="db_home_name_value", - gcp_oracle_zone="gcp_oracle_zone_value", - ops_insights_status=database.Database.OperationsInsightsStatus.ENABLING, + return_value = goldengate_connection_type.ListGoldengateConnectionTypesResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], ) # Wrap the value into a proper Response obj @@ -50042,34 +70519,25 @@ def test_get_database_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = database.Database.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value.content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_database(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, database.Database) - assert response.name == "name_value" - assert response.db_name == "db_name_value" - assert response.db_unique_name == "db_unique_name_value" - assert response.admin_password == "admin_password_value" - assert response.tde_wallet_password == "tde_wallet_password_value" - assert response.character_set == "character_set_value" - assert response.ncharacter_set == "ncharacter_set_value" - assert response.oci_url == "oci_url_value" - assert response.database_id == "database_id_value" - assert response.db_home_name == "db_home_name_value" - assert response.gcp_oracle_zone == "gcp_oracle_zone_value" - assert ( - response.ops_insights_status - == database.Database.OperationsInsightsStatus.ENABLING - ) + return_value = ( + goldengate_connection_type.ListGoldengateConnectionTypesResponse.pb( + return_value + ) + ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_goldengate_connection_types(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListGoldengateConnectionTypesPager) + assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_database_rest_interceptors(null_interceptor): +def test_list_goldengate_connection_types_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -50082,19 +70550,24 @@ def test_get_database_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_get_database" + transports.OracleDatabaseRestInterceptor, + "post_list_goldengate_connection_types", ) as post, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_get_database_with_metadata" + transports.OracleDatabaseRestInterceptor, + "post_list_goldengate_connection_types_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_get_database" + transports.OracleDatabaseRestInterceptor, + "pre_list_goldengate_connection_types", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = database.GetDatabaseRequest.pb(database.GetDatabaseRequest()) + pb_message = goldengate_connection_type.ListGoldengateConnectionTypesRequest.pb( + goldengate_connection_type.ListGoldengateConnectionTypesRequest() + ) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -50105,19 +70578,28 @@ def test_get_database_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = database.Database.to_json(database.Database()) + return_value = ( + goldengate_connection_type.ListGoldengateConnectionTypesResponse.to_json( + goldengate_connection_type.ListGoldengateConnectionTypesResponse() + ) + ) req.return_value.content = return_value - request = database.GetDatabaseRequest() + request = goldengate_connection_type.ListGoldengateConnectionTypesRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = database.Database() - post_with_metadata.return_value = database.Database(), metadata + post.return_value = ( + goldengate_connection_type.ListGoldengateConnectionTypesResponse() + ) + post_with_metadata.return_value = ( + goldengate_connection_type.ListGoldengateConnectionTypesResponse(), + metadata, + ) - client.get_database( + client.list_goldengate_connection_types( request, metadata=[ ("key", "val"), @@ -50130,8 +70612,8 @@ def test_get_database_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_pluggable_databases_rest_bad_request( - request_type=pluggable_database.ListPluggableDatabasesRequest, +def test_list_db_versions_rest_bad_request( + request_type=db_version.ListDbVersionsRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" @@ -50153,17 +70635,17 @@ def test_list_pluggable_databases_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_pluggable_databases(request) + client.list_db_versions(request) @pytest.mark.parametrize( "request_type", [ - pluggable_database.ListPluggableDatabasesRequest, + db_version.ListDbVersionsRequest, dict, ], ) -def test_list_pluggable_databases_rest_call_success(request_type): +def test_list_db_versions_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -50175,7 +70657,7 @@ def test_list_pluggable_databases_rest_call_success(request_type): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = pluggable_database.ListPluggableDatabasesResponse( + return_value = db_version.ListDbVersionsResponse( next_page_token="next_page_token_value", ) @@ -50184,22 +70666,20 @@ def test_list_pluggable_databases_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = pluggable_database.ListPluggableDatabasesResponse.pb( - return_value - ) + return_value = db_version.ListDbVersionsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_pluggable_databases(request) + response = client.list_db_versions(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListPluggableDatabasesPager) + assert isinstance(response, pagers.ListDbVersionsPager) assert response.next_page_token == "next_page_token_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_pluggable_databases_rest_interceptors(null_interceptor): +def test_list_db_versions_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -50212,21 +70692,21 @@ def test_list_pluggable_databases_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_list_pluggable_databases" + transports.OracleDatabaseRestInterceptor, "post_list_db_versions" ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_list_pluggable_databases_with_metadata", + "post_list_db_versions_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_list_pluggable_databases" + transports.OracleDatabaseRestInterceptor, "pre_list_db_versions" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = pluggable_database.ListPluggableDatabasesRequest.pb( - pluggable_database.ListPluggableDatabasesRequest() + pb_message = db_version.ListDbVersionsRequest.pb( + db_version.ListDbVersionsRequest() ) transcode.return_value = { "method": "post", @@ -50238,24 +70718,21 @@ def test_list_pluggable_databases_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = pluggable_database.ListPluggableDatabasesResponse.to_json( - pluggable_database.ListPluggableDatabasesResponse() + return_value = db_version.ListDbVersionsResponse.to_json( + db_version.ListDbVersionsResponse() ) req.return_value.content = return_value - request = pluggable_database.ListPluggableDatabasesRequest() + request = db_version.ListDbVersionsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = pluggable_database.ListPluggableDatabasesResponse() - post_with_metadata.return_value = ( - pluggable_database.ListPluggableDatabasesResponse(), - metadata, - ) + post.return_value = db_version.ListDbVersionsResponse() + post_with_metadata.return_value = db_version.ListDbVersionsResponse(), metadata - client.list_pluggable_databases( + client.list_db_versions( request, metadata=[ ("key", "val"), @@ -50268,16 +70745,14 @@ def test_list_pluggable_databases_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_get_pluggable_database_rest_bad_request( - request_type=pluggable_database.GetPluggableDatabaseRequest, +def test_list_database_character_sets_rest_bad_request( + request_type=database_character_set.ListDatabaseCharacterSetsRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/pluggableDatabases/sample3" - } + request_init = {"parent": "projects/sample1/locations/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -50293,33 +70768,30 @@ def test_get_pluggable_database_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_pluggable_database(request) + client.list_database_character_sets(request) @pytest.mark.parametrize( "request_type", [ - pluggable_database.GetPluggableDatabaseRequest, + database_character_set.ListDatabaseCharacterSetsRequest, dict, ], ) -def test_get_pluggable_database_rest_call_success(request_type): +def test_list_database_character_sets_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/pluggableDatabases/sample3" - } + request_init = {"parent": "projects/sample1/locations/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = pluggable_database.PluggableDatabase( - name="name_value", - oci_url="oci_url_value", + return_value = database_character_set.ListDatabaseCharacterSetsResponse( + next_page_token="next_page_token_value", ) # Wrap the value into a proper Response obj @@ -50327,21 +70799,22 @@ def test_get_pluggable_database_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = pluggable_database.PluggableDatabase.pb(return_value) + return_value = database_character_set.ListDatabaseCharacterSetsResponse.pb( + return_value + ) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_pluggable_database(request) + response = client.list_database_character_sets(request) # Establish that the response is the type that we expect. - assert isinstance(response, pluggable_database.PluggableDatabase) - assert response.name == "name_value" - assert response.oci_url == "oci_url_value" + assert isinstance(response, pagers.ListDatabaseCharacterSetsPager) + assert response.next_page_token == "next_page_token_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_pluggable_database_rest_interceptors(null_interceptor): +def test_list_database_character_sets_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -50354,21 +70827,22 @@ def test_get_pluggable_database_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_get_pluggable_database" + transports.OracleDatabaseRestInterceptor, + "post_list_database_character_sets", ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_get_pluggable_database_with_metadata", + "post_list_database_character_sets_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_get_pluggable_database" + transports.OracleDatabaseRestInterceptor, "pre_list_database_character_sets" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = pluggable_database.GetPluggableDatabaseRequest.pb( - pluggable_database.GetPluggableDatabaseRequest() + pb_message = database_character_set.ListDatabaseCharacterSetsRequest.pb( + database_character_set.ListDatabaseCharacterSetsRequest() ) transcode.return_value = { "method": "post", @@ -50380,24 +70854,24 @@ def test_get_pluggable_database_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = pluggable_database.PluggableDatabase.to_json( - pluggable_database.PluggableDatabase() + return_value = database_character_set.ListDatabaseCharacterSetsResponse.to_json( + database_character_set.ListDatabaseCharacterSetsResponse() ) req.return_value.content = return_value - request = pluggable_database.GetPluggableDatabaseRequest() + request = database_character_set.ListDatabaseCharacterSetsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = pluggable_database.PluggableDatabase() + post.return_value = database_character_set.ListDatabaseCharacterSetsResponse() post_with_metadata.return_value = ( - pluggable_database.PluggableDatabase(), + database_character_set.ListDatabaseCharacterSetsResponse(), metadata, ) - client.get_pluggable_database( + client.list_database_character_sets( request, metadata=[ ("key", "val"), @@ -50410,7 +70884,9 @@ def test_get_pluggable_database_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_db_systems_rest_bad_request(request_type=db_system.ListDbSystemsRequest): +def test_list_goldengate_connection_assignments_rest_bad_request( + request_type=goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest, +): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -50431,17 +70907,17 @@ def test_list_db_systems_rest_bad_request(request_type=db_system.ListDbSystemsRe response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_db_systems(request) + client.list_goldengate_connection_assignments(request) @pytest.mark.parametrize( "request_type", [ - db_system.ListDbSystemsRequest, + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest, dict, ], ) -def test_list_db_systems_rest_call_success(request_type): +def test_list_goldengate_connection_assignments_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -50453,8 +70929,9 @@ def test_list_db_systems_rest_call_success(request_type): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = db_system.ListDbSystemsResponse( + return_value = goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse( next_page_token="next_page_token_value", + unreachable=["unreachable_value"], ) # Wrap the value into a proper Response obj @@ -50462,20 +70939,23 @@ def test_list_db_systems_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = db_system.ListDbSystemsResponse.pb(return_value) + return_value = goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse.pb( + return_value + ) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_db_systems(request) + response = client.list_goldengate_connection_assignments(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListDbSystemsPager) + assert isinstance(response, pagers.ListGoldengateConnectionAssignmentsPager) assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_db_systems_rest_interceptors(null_interceptor): +def test_list_goldengate_connection_assignments_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -50488,20 +70968,24 @@ def test_list_db_systems_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_list_db_systems" + transports.OracleDatabaseRestInterceptor, + "post_list_goldengate_connection_assignments", ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_list_db_systems_with_metadata", + "post_list_goldengate_connection_assignments_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_list_db_systems" + transports.OracleDatabaseRestInterceptor, + "pre_list_goldengate_connection_assignments", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = db_system.ListDbSystemsRequest.pb(db_system.ListDbSystemsRequest()) + pb_message = goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest.pb( + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest() + ) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -50512,21 +70996,24 @@ def test_list_db_systems_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = db_system.ListDbSystemsResponse.to_json( - db_system.ListDbSystemsResponse() + return_value = goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse.to_json( + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse() ) req.return_value.content = return_value - request = db_system.ListDbSystemsRequest() + request = goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = db_system.ListDbSystemsResponse() - post_with_metadata.return_value = db_system.ListDbSystemsResponse(), metadata + post.return_value = goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse() + post_with_metadata.return_value = ( + goldengate_connection_assignment.ListGoldengateConnectionAssignmentsResponse(), + metadata, + ) - client.list_db_systems( + client.list_goldengate_connection_assignments( request, metadata=[ ("key", "val"), @@ -50539,12 +71026,16 @@ def test_list_db_systems_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_get_db_system_rest_bad_request(request_type=db_system.GetDbSystemRequest): +def test_get_goldengate_connection_assignment_rest_bad_request( + request_type=goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest, +): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/dbSystems/sample3"} + request_init = { + "name": "projects/sample1/locations/sample2/goldengateConnectionAssignments/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -50560,36 +71051,34 @@ def test_get_db_system_rest_bad_request(request_type=db_system.GetDbSystemReques response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_db_system(request) + client.get_goldengate_connection_assignment(request) @pytest.mark.parametrize( "request_type", [ - db_system.GetDbSystemRequest, + goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest, dict, ], ) -def test_get_db_system_rest_call_success(request_type): +def test_get_goldengate_connection_assignment_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/dbSystems/sample3"} + request_init = { + "name": "projects/sample1/locations/sample2/goldengateConnectionAssignments/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = db_system.DbSystem( + return_value = goldengate_connection_assignment.GoldengateConnectionAssignment( name="name_value", - gcp_oracle_zone="gcp_oracle_zone_value", - odb_network="odb_network_value", - odb_subnet="odb_subnet_value", - entitlement_id="entitlement_id_value", display_name="display_name_value", - oci_url="oci_url_value", + entitlement_id="entitlement_id_value", ) # Wrap the value into a proper Response obj @@ -50597,26 +71086,28 @@ def test_get_db_system_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = db_system.DbSystem.pb(return_value) + return_value = ( + goldengate_connection_assignment.GoldengateConnectionAssignment.pb( + return_value + ) + ) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_db_system(request) + response = client.get_goldengate_connection_assignment(request) # Establish that the response is the type that we expect. - assert isinstance(response, db_system.DbSystem) + assert isinstance( + response, goldengate_connection_assignment.GoldengateConnectionAssignment + ) assert response.name == "name_value" - assert response.gcp_oracle_zone == "gcp_oracle_zone_value" - assert response.odb_network == "odb_network_value" - assert response.odb_subnet == "odb_subnet_value" - assert response.entitlement_id == "entitlement_id_value" assert response.display_name == "display_name_value" - assert response.oci_url == "oci_url_value" + assert response.entitlement_id == "entitlement_id_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_db_system_rest_interceptors(null_interceptor): +def test_get_goldengate_connection_assignment_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -50629,19 +71120,24 @@ def test_get_db_system_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_get_db_system" + transports.OracleDatabaseRestInterceptor, + "post_get_goldengate_connection_assignment", ) as post, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_get_db_system_with_metadata" + transports.OracleDatabaseRestInterceptor, + "post_get_goldengate_connection_assignment_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_get_db_system" + transports.OracleDatabaseRestInterceptor, + "pre_get_goldengate_connection_assignment", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = db_system.GetDbSystemRequest.pb(db_system.GetDbSystemRequest()) + pb_message = goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest.pb( + goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest() + ) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -50652,19 +71148,30 @@ def test_get_db_system_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = db_system.DbSystem.to_json(db_system.DbSystem()) + return_value = ( + goldengate_connection_assignment.GoldengateConnectionAssignment.to_json( + goldengate_connection_assignment.GoldengateConnectionAssignment() + ) + ) req.return_value.content = return_value - request = db_system.GetDbSystemRequest() + request = ( + goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest() + ) metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = db_system.DbSystem() - post_with_metadata.return_value = db_system.DbSystem(), metadata + post.return_value = ( + goldengate_connection_assignment.GoldengateConnectionAssignment() + ) + post_with_metadata.return_value = ( + goldengate_connection_assignment.GoldengateConnectionAssignment(), + metadata, + ) - client.get_db_system( + client.get_goldengate_connection_assignment( request, metadata=[ ("key", "val"), @@ -50677,8 +71184,8 @@ def test_get_db_system_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_create_db_system_rest_bad_request( - request_type=gco_db_system.CreateDbSystemRequest, +def test_create_goldengate_connection_assignment_rest_bad_request( + request_type=gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" @@ -50700,102 +71207,45 @@ def test_create_db_system_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_db_system(request) + client.create_goldengate_connection_assignment(request) @pytest.mark.parametrize( "request_type", [ - gco_db_system.CreateDbSystemRequest, + gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest, dict, ], ) -def test_create_db_system_rest_call_success(request_type): +def test_create_goldengate_connection_assignment_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = {"parent": "projects/sample1/locations/sample2"} - request_init["db_system"] = { + request_init["goldengate_connection_assignment"] = { "name": "name_value", "properties": { - "shape": "shape_value", - "compute_count": 1413, - "initial_data_storage_size_gb": 2937, - "database_edition": 1, - "license_model": 1, - "ssh_public_keys": ["ssh_public_keys_value1", "ssh_public_keys_value2"], - "hostname_prefix": "hostname_prefix_value", - "hostname": "hostname_value", - "private_ip": "private_ip_value", - "data_collection_options": { - "is_diagnostics_events_enabled": True, - "is_incident_logs_enabled": True, - }, - "time_zone": {"id": "id_value", "version": "version_value"}, - "lifecycle_state": 1, - "db_home": { - "display_name": "display_name_value", - "db_version": "db_version_value", - "database": { - "name": "name_value", - "db_name": "db_name_value", - "db_unique_name": "db_unique_name_value", - "admin_password": "admin_password_value", - "tde_wallet_password": "tde_wallet_password_value", - "character_set": "character_set_value", - "ncharacter_set": "ncharacter_set_value", - "oci_url": "oci_url_value", - "create_time": {"seconds": 751, "nanos": 543}, - "properties": { - "state": 1, - "db_version": "db_version_value", - "db_backup_config": { - "auto_backup_enabled": True, - "backup_destination_details": [{"type_": 1}], - "retention_period_days": 2250, - "backup_deletion_policy": 1, - "auto_full_backup_day": 1, - "auto_full_backup_window": 1, - "auto_incremental_backup_window": 1, - }, - "database_management_config": { - "management_state": 1, - "management_type": 1, - }, - }, - "database_id": "database_id_value", - "db_home_name": "db_home_name_value", - "gcp_oracle_zone": "gcp_oracle_zone_value", - "ops_insights_status": 1, - }, - "is_unified_auditing_enabled": True, - }, "ocid": "ocid_value", - "memory_size_gb": 1499, - "compute_model": 1, - "data_storage_size_gb": 2096, - "reco_storage_size_gb": 2111, - "domain": "domain_value", - "node_count": 1070, - "db_system_options": {"storage_management": 1}, + "goldengate_connection": "goldengate_connection_value", + "goldengate_deployment": "goldengate_deployment_value", + "alias": "alias_value", + "state": 1, }, - "gcp_oracle_zone": "gcp_oracle_zone_value", + "create_time": {"seconds": 751, "nanos": 543}, "labels": {}, - "odb_network": "odb_network_value", - "odb_subnet": "odb_subnet_value", - "entitlement_id": "entitlement_id_value", "display_name": "display_name_value", - "create_time": {}, - "oci_url": "oci_url_value", + "entitlement_id": "entitlement_id_value", } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = gco_db_system.CreateDbSystemRequest.meta.fields["db_system"] + test_field = gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest.meta.fields[ + "goldengate_connection_assignment" + ] def get_message_fields(field): # Given a field which is a message (composite type), return a list with @@ -50823,7 +71273,9 @@ def get_message_fields(field): # For each item in the sample request, create a list of sub fields which are not present at runtime # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["db_system"].items(): # pragma: NO COVER + for field, value in request_init[ + "goldengate_connection_assignment" + ].items(): # pragma: NO COVER result = None is_repeated = False # For repeated fields @@ -50853,10 +71305,14 @@ def get_message_fields(field): subfield = subfield_to_delete.get("subfield") if subfield: if field_repeated: - for i in range(0, len(request_init["db_system"][field])): - del request_init["db_system"][field][i][subfield] + for i in range( + 0, len(request_init["goldengate_connection_assignment"][field]) + ): + del request_init["goldengate_connection_assignment"][field][i][ + subfield + ] else: - del request_init["db_system"][field][subfield] + del request_init["goldengate_connection_assignment"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -50871,14 +71327,14 @@ def get_message_fields(field): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_db_system(request) + response = client.create_goldengate_connection_assignment(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_db_system_rest_interceptors(null_interceptor): +def test_create_goldengate_connection_assignment_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -50892,21 +71348,23 @@ def test_create_db_system_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_create_db_system" + transports.OracleDatabaseRestInterceptor, + "post_create_goldengate_connection_assignment", ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_create_db_system_with_metadata", + "post_create_goldengate_connection_assignment_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_create_db_system" + transports.OracleDatabaseRestInterceptor, + "pre_create_goldengate_connection_assignment", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = gco_db_system.CreateDbSystemRequest.pb( - gco_db_system.CreateDbSystemRequest() + pb_message = gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest.pb( + gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest() ) transcode.return_value = { "method": "post", @@ -50921,7 +71379,7 @@ def test_create_db_system_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = gco_db_system.CreateDbSystemRequest() + request = gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -50930,7 +71388,7 @@ def test_create_db_system_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.create_db_system( + client.create_goldengate_connection_assignment( request, metadata=[ ("key", "val"), @@ -50943,14 +71401,16 @@ def test_create_db_system_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_delete_db_system_rest_bad_request( - request_type=db_system.DeleteDbSystemRequest, +def test_delete_goldengate_connection_assignment_rest_bad_request( + request_type=goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/dbSystems/sample3"} + request_init = { + "name": "projects/sample1/locations/sample2/goldengateConnectionAssignments/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -50966,23 +71426,25 @@ def test_delete_db_system_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_db_system(request) + client.delete_goldengate_connection_assignment(request) @pytest.mark.parametrize( "request_type", [ - db_system.DeleteDbSystemRequest, + goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest, dict, ], ) -def test_delete_db_system_rest_call_success(request_type): +def test_delete_goldengate_connection_assignment_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/dbSystems/sample3"} + request_init = { + "name": "projects/sample1/locations/sample2/goldengateConnectionAssignments/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -50997,14 +71459,14 @@ def test_delete_db_system_rest_call_success(request_type): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_db_system(request) + response = client.delete_goldengate_connection_assignment(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_db_system_rest_interceptors(null_interceptor): +def test_delete_goldengate_connection_assignment_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -51018,21 +71480,23 @@ def test_delete_db_system_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_delete_db_system" + transports.OracleDatabaseRestInterceptor, + "post_delete_goldengate_connection_assignment", ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_delete_db_system_with_metadata", + "post_delete_goldengate_connection_assignment_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_delete_db_system" + transports.OracleDatabaseRestInterceptor, + "pre_delete_goldengate_connection_assignment", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = db_system.DeleteDbSystemRequest.pb( - db_system.DeleteDbSystemRequest() + pb_message = goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest.pb( + goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest() ) transcode.return_value = { "method": "post", @@ -51047,7 +71511,7 @@ def test_delete_db_system_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = db_system.DeleteDbSystemRequest() + request = goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -51056,140 +71520,7 @@ def test_delete_db_system_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.delete_db_system( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - post_with_metadata.assert_called_once() - - -def test_list_db_versions_rest_bad_request( - request_type=db_version.ListDbVersionsRequest, -): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with ( - mock.patch.object(Session, "request") as req, - pytest.raises(core_exceptions.BadRequest), - ): - # Wrap the value into a proper Response obj - response_value = mock.Mock() - json_return_value = "" - response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_db_versions(request) - - -@pytest.mark.parametrize( - "request_type", - [ - db_version.ListDbVersionsRequest, - dict, - ], -) -def test_list_db_versions_rest_call_success(request_type): - client = OracleDatabaseClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = db_version.ListDbVersionsResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = mock.Mock() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = db_version.ListDbVersionsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value.content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_db_versions(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListDbVersionsPager) - assert response.next_page_token == "next_page_token_value" - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_db_versions_rest_interceptors(null_interceptor): - transport = transports.OracleDatabaseRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.OracleDatabaseRestInterceptor(), - ) - client = OracleDatabaseClient(transport=transport) - - with ( - mock.patch.object(type(client.transport._session), "request") as req, - mock.patch.object(path_template, "transcode") as transcode, - mock.patch.object( - transports.OracleDatabaseRestInterceptor, "post_list_db_versions" - ) as post, - mock.patch.object( - transports.OracleDatabaseRestInterceptor, - "post_list_db_versions_with_metadata", - ) as post_with_metadata, - mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_list_db_versions" - ) as pre, - ): - pre.assert_not_called() - post.assert_not_called() - post_with_metadata.assert_not_called() - pb_message = db_version.ListDbVersionsRequest.pb( - db_version.ListDbVersionsRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = mock.Mock() - req.return_value.status_code = 200 - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = db_version.ListDbVersionsResponse.to_json( - db_version.ListDbVersionsResponse() - ) - req.return_value.content = return_value - - request = db_version.ListDbVersionsRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = db_version.ListDbVersionsResponse() - post_with_metadata.return_value = db_version.ListDbVersionsResponse(), metadata - - client.list_db_versions( + client.delete_goldengate_connection_assignment( request, metadata=[ ("key", "val"), @@ -51202,14 +71533,16 @@ def test_list_db_versions_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_database_character_sets_rest_bad_request( - request_type=database_character_set.ListDatabaseCharacterSetsRequest, +def test_test_goldengate_connection_assignment_rest_bad_request( + request_type=goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest, ): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} + request_init = { + "name": "projects/sample1/locations/sample2/goldengateConnectionAssignments/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -51225,30 +71558,32 @@ def test_list_database_character_sets_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_database_character_sets(request) + client.test_goldengate_connection_assignment(request) @pytest.mark.parametrize( "request_type", [ - database_character_set.ListDatabaseCharacterSetsRequest, + goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest, dict, ], ) -def test_list_database_character_sets_rest_call_success(request_type): +def test_test_goldengate_connection_assignment_rest_call_success(request_type): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} + request_init = { + "name": "projects/sample1/locations/sample2/goldengateConnectionAssignments/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = database_character_set.ListDatabaseCharacterSetsResponse( - next_page_token="next_page_token_value", + return_value = goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse( + result_type=goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse.ResultType.SUCCEEDED, ) # Wrap the value into a proper Response obj @@ -51256,22 +71591,28 @@ def test_list_database_character_sets_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = database_character_set.ListDatabaseCharacterSetsResponse.pb( + return_value = goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse.pb( return_value ) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_database_character_sets(request) + response = client.test_goldengate_connection_assignment(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListDatabaseCharacterSetsPager) - assert response.next_page_token == "next_page_token_value" + assert isinstance( + response, + goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse, + ) + assert ( + response.result_type + == goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse.ResultType.SUCCEEDED + ) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_database_character_sets_rest_interceptors(null_interceptor): +def test_test_goldengate_connection_assignment_rest_interceptors(null_interceptor): transport = transports.OracleDatabaseRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -51285,21 +71626,22 @@ def test_list_database_character_sets_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_list_database_character_sets", + "post_test_goldengate_connection_assignment", ) as post, mock.patch.object( transports.OracleDatabaseRestInterceptor, - "post_list_database_character_sets_with_metadata", + "post_test_goldengate_connection_assignment_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.OracleDatabaseRestInterceptor, "pre_list_database_character_sets" + transports.OracleDatabaseRestInterceptor, + "pre_test_goldengate_connection_assignment", ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = database_character_set.ListDatabaseCharacterSetsRequest.pb( - database_character_set.ListDatabaseCharacterSetsRequest() + pb_message = goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest.pb( + goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest() ) transcode.return_value = { "method": "post", @@ -51311,24 +71653,26 @@ def test_list_database_character_sets_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = database_character_set.ListDatabaseCharacterSetsResponse.to_json( - database_character_set.ListDatabaseCharacterSetsResponse() + return_value = goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse.to_json( + goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse() ) req.return_value.content = return_value - request = database_character_set.ListDatabaseCharacterSetsRequest() + request = ( + goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest() + ) metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = database_character_set.ListDatabaseCharacterSetsResponse() + post.return_value = goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse() post_with_metadata.return_value = ( - database_character_set.ListDatabaseCharacterSetsResponse(), + goldengate_connection_assignment.TestGoldengateConnectionAssignmentResponse(), metadata, ) - client.list_database_character_sets( + client.test_goldengate_connection_assignment( request, metadata=[ ("key", "val"), @@ -52878,6 +73222,388 @@ def test_delete_db_system_empty_call_rest(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_goldengate_deployments_empty_call_rest(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployments), "__call__" + ) as call: + client.list_goldengate_deployments(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment.ListGoldengateDeploymentsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_goldengate_deployment_empty_call_rest(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment), "__call__" + ) as call: + client.get_goldengate_deployment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment.GetGoldengateDeploymentRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_goldengate_deployment_empty_call_rest(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_goldengate_deployment), "__call__" + ) as call: + client.create_goldengate_deployment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gco_goldengate_deployment.CreateGoldengateDeploymentRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_goldengate_deployment_empty_call_rest(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_goldengate_deployment), "__call__" + ) as call: + client.delete_goldengate_deployment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment.DeleteGoldengateDeploymentRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_stop_goldengate_deployment_empty_call_rest(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.stop_goldengate_deployment), "__call__" + ) as call: + client.stop_goldengate_deployment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment.StopGoldengateDeploymentRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_start_goldengate_deployment_empty_call_rest(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.start_goldengate_deployment), "__call__" + ) as call: + client.start_goldengate_deployment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment.StartGoldengateDeploymentRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_goldengate_connections_empty_call_rest(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connections), "__call__" + ) as call: + client.list_goldengate_connections(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_connection.ListGoldengateConnectionsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_goldengate_connection_empty_call_rest(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_connection), "__call__" + ) as call: + client.get_goldengate_connection(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_connection.GetGoldengateConnectionRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_goldengate_connection_empty_call_rest(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_goldengate_connection), "__call__" + ) as call: + client.create_goldengate_connection(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gco_goldengate_connection.CreateGoldengateConnectionRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_goldengate_connection_empty_call_rest(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_goldengate_connection), "__call__" + ) as call: + client.delete_goldengate_connection(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_connection.DeleteGoldengateConnectionRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_goldengate_deployment_version_empty_call_rest(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment_version), "__call__" + ) as call: + client.get_goldengate_deployment_version(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ( + goldengate_deployment_version.GetGoldengateDeploymentVersionRequest() + ) + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_goldengate_deployment_versions_empty_call_rest(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_versions), "__call__" + ) as call: + client.list_goldengate_deployment_versions(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ( + goldengate_deployment_version.ListGoldengateDeploymentVersionsRequest() + ) + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_goldengate_deployment_type_empty_call_rest(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment_type), "__call__" + ) as call: + client.get_goldengate_deployment_type(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment_type.GetGoldengateDeploymentTypeRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_goldengate_deployment_types_empty_call_rest(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_types), "__call__" + ) as call: + client.list_goldengate_deployment_types(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment_type.ListGoldengateDeploymentTypesRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_goldengate_deployment_environment_empty_call_rest(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_deployment_environment), "__call__" + ) as call: + client.get_goldengate_deployment_environment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment_environment.GetGoldengateDeploymentEnvironmentRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_goldengate_deployment_environments_empty_call_rest(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_deployment_environments), "__call__" + ) as call: + client.list_goldengate_deployment_environments(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_deployment_environment.ListGoldengateDeploymentEnvironmentsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_goldengate_connection_type_empty_call_rest(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_connection_type), "__call__" + ) as call: + client.get_goldengate_connection_type(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_connection_type.GetGoldengateConnectionTypeRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_goldengate_connection_types_empty_call_rest(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connection_types), "__call__" + ) as call: + client.list_goldengate_connection_types(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_connection_type.ListGoldengateConnectionTypesRequest() + assert args[0] == request_msg + + # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. def test_list_db_versions_empty_call_rest(): @@ -52918,6 +73644,115 @@ def test_list_database_character_sets_empty_call_rest(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_goldengate_connection_assignments_empty_call_rest(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_goldengate_connection_assignments), "__call__" + ) as call: + client.list_goldengate_connection_assignments(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_connection_assignment.ListGoldengateConnectionAssignmentsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_goldengate_connection_assignment_empty_call_rest(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_goldengate_connection_assignment), "__call__" + ) as call: + client.get_goldengate_connection_assignment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ( + goldengate_connection_assignment.GetGoldengateConnectionAssignmentRequest() + ) + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_goldengate_connection_assignment_empty_call_rest(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_goldengate_connection_assignment), "__call__" + ) as call: + client.create_goldengate_connection_assignment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gco_goldengate_connection_assignment.CreateGoldengateConnectionAssignmentRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_goldengate_connection_assignment_empty_call_rest(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_goldengate_connection_assignment), "__call__" + ) as call: + client.delete_goldengate_connection_assignment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = goldengate_connection_assignment.DeleteGoldengateConnectionAssignmentRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_test_goldengate_connection_assignment_empty_call_rest(): + client = OracleDatabaseClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.test_goldengate_connection_assignment), "__call__" + ) as call: + client.test_goldengate_connection_assignment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ( + goldengate_connection_assignment.TestGoldengateConnectionAssignmentRequest() + ) + assert args[0] == request_msg + + def test_oracle_database_rest_lro_client(): client = OracleDatabaseClient( credentials=ga_credentials.AnonymousCredentials(), @@ -53024,8 +73859,31 @@ def test_oracle_database_base_transport(): "get_db_system", "create_db_system", "delete_db_system", + "list_goldengate_deployments", + "get_goldengate_deployment", + "create_goldengate_deployment", + "delete_goldengate_deployment", + "stop_goldengate_deployment", + "start_goldengate_deployment", + "list_goldengate_connections", + "get_goldengate_connection", + "create_goldengate_connection", + "delete_goldengate_connection", + "get_goldengate_deployment_version", + "list_goldengate_deployment_versions", + "get_goldengate_deployment_type", + "list_goldengate_deployment_types", + "get_goldengate_deployment_environment", + "list_goldengate_deployment_environments", + "get_goldengate_connection_type", + "list_goldengate_connection_types", "list_db_versions", "list_database_character_sets", + "list_goldengate_connection_assignments", + "get_goldengate_connection_assignment", + "create_goldengate_connection_assignment", + "delete_goldengate_connection_assignment", + "test_goldengate_connection_assignment", "get_location", "list_locations", "get_operation", @@ -53470,12 +74328,81 @@ def test_oracle_database_client_transport_session_collision(transport_name): session1 = client1.transport.delete_db_system._session session2 = client2.transport.delete_db_system._session assert session1 != session2 + session1 = client1.transport.list_goldengate_deployments._session + session2 = client2.transport.list_goldengate_deployments._session + assert session1 != session2 + session1 = client1.transport.get_goldengate_deployment._session + session2 = client2.transport.get_goldengate_deployment._session + assert session1 != session2 + session1 = client1.transport.create_goldengate_deployment._session + session2 = client2.transport.create_goldengate_deployment._session + assert session1 != session2 + session1 = client1.transport.delete_goldengate_deployment._session + session2 = client2.transport.delete_goldengate_deployment._session + assert session1 != session2 + session1 = client1.transport.stop_goldengate_deployment._session + session2 = client2.transport.stop_goldengate_deployment._session + assert session1 != session2 + session1 = client1.transport.start_goldengate_deployment._session + session2 = client2.transport.start_goldengate_deployment._session + assert session1 != session2 + session1 = client1.transport.list_goldengate_connections._session + session2 = client2.transport.list_goldengate_connections._session + assert session1 != session2 + session1 = client1.transport.get_goldengate_connection._session + session2 = client2.transport.get_goldengate_connection._session + assert session1 != session2 + session1 = client1.transport.create_goldengate_connection._session + session2 = client2.transport.create_goldengate_connection._session + assert session1 != session2 + session1 = client1.transport.delete_goldengate_connection._session + session2 = client2.transport.delete_goldengate_connection._session + assert session1 != session2 + session1 = client1.transport.get_goldengate_deployment_version._session + session2 = client2.transport.get_goldengate_deployment_version._session + assert session1 != session2 + session1 = client1.transport.list_goldengate_deployment_versions._session + session2 = client2.transport.list_goldengate_deployment_versions._session + assert session1 != session2 + session1 = client1.transport.get_goldengate_deployment_type._session + session2 = client2.transport.get_goldengate_deployment_type._session + assert session1 != session2 + session1 = client1.transport.list_goldengate_deployment_types._session + session2 = client2.transport.list_goldengate_deployment_types._session + assert session1 != session2 + session1 = client1.transport.get_goldengate_deployment_environment._session + session2 = client2.transport.get_goldengate_deployment_environment._session + assert session1 != session2 + session1 = client1.transport.list_goldengate_deployment_environments._session + session2 = client2.transport.list_goldengate_deployment_environments._session + assert session1 != session2 + session1 = client1.transport.get_goldengate_connection_type._session + session2 = client2.transport.get_goldengate_connection_type._session + assert session1 != session2 + session1 = client1.transport.list_goldengate_connection_types._session + session2 = client2.transport.list_goldengate_connection_types._session + assert session1 != session2 session1 = client1.transport.list_db_versions._session session2 = client2.transport.list_db_versions._session assert session1 != session2 session1 = client1.transport.list_database_character_sets._session session2 = client2.transport.list_database_character_sets._session assert session1 != session2 + session1 = client1.transport.list_goldengate_connection_assignments._session + session2 = client2.transport.list_goldengate_connection_assignments._session + assert session1 != session2 + session1 = client1.transport.get_goldengate_connection_assignment._session + session2 = client2.transport.get_goldengate_connection_assignment._session + assert session1 != session2 + session1 = client1.transport.create_goldengate_connection_assignment._session + session2 = client2.transport.create_goldengate_connection_assignment._session + assert session1 != session2 + session1 = client1.transport.delete_goldengate_connection_assignment._session + session2 = client2.transport.delete_goldengate_connection_assignment._session + assert session1 != session2 + session1 = client1.transport.test_goldengate_connection_assignment._session + session2 = client2.transport.test_goldengate_connection_assignment._session + assert session1 != session2 def test_oracle_database_grpc_transport_channel(): @@ -54172,11 +75099,207 @@ def test_parse_gi_version_path(): assert expected == actual -def test_minor_version_path(): +def test_goldengate_connection_path(): project = "squid" location = "clam" - gi_version = "whelk" - minor_version = "octopus" + goldengate_connection = "whelk" + expected = "projects/{project}/locations/{location}/goldengateConnections/{goldengate_connection}".format( + project=project, + location=location, + goldengate_connection=goldengate_connection, + ) + actual = OracleDatabaseClient.goldengate_connection_path( + project, location, goldengate_connection + ) + assert expected == actual + + +def test_parse_goldengate_connection_path(): + expected = { + "project": "octopus", + "location": "oyster", + "goldengate_connection": "nudibranch", + } + path = OracleDatabaseClient.goldengate_connection_path(**expected) + + # Check that the path construction is reversible. + actual = OracleDatabaseClient.parse_goldengate_connection_path(path) + assert expected == actual + + +def test_goldengate_connection_assignment_path(): + project = "cuttlefish" + location = "mussel" + goldengate_connection_assignment = "winkle" + expected = "projects/{project}/locations/{location}/goldengateConnectionAssignments/{goldengate_connection_assignment}".format( + project=project, + location=location, + goldengate_connection_assignment=goldengate_connection_assignment, + ) + actual = OracleDatabaseClient.goldengate_connection_assignment_path( + project, location, goldengate_connection_assignment + ) + assert expected == actual + + +def test_parse_goldengate_connection_assignment_path(): + expected = { + "project": "nautilus", + "location": "scallop", + "goldengate_connection_assignment": "abalone", + } + path = OracleDatabaseClient.goldengate_connection_assignment_path(**expected) + + # Check that the path construction is reversible. + actual = OracleDatabaseClient.parse_goldengate_connection_assignment_path(path) + assert expected == actual + + +def test_goldengate_connection_type_path(): + project = "squid" + location = "clam" + goldengate_connection_type = "whelk" + expected = "projects/{project}/locations/{location}/goldengateConnectionTypes/{goldengate_connection_type}".format( + project=project, + location=location, + goldengate_connection_type=goldengate_connection_type, + ) + actual = OracleDatabaseClient.goldengate_connection_type_path( + project, location, goldengate_connection_type + ) + assert expected == actual + + +def test_parse_goldengate_connection_type_path(): + expected = { + "project": "octopus", + "location": "oyster", + "goldengate_connection_type": "nudibranch", + } + path = OracleDatabaseClient.goldengate_connection_type_path(**expected) + + # Check that the path construction is reversible. + actual = OracleDatabaseClient.parse_goldengate_connection_type_path(path) + assert expected == actual + + +def test_goldengate_deployment_path(): + project = "cuttlefish" + location = "mussel" + goldengate_deployment = "winkle" + expected = "projects/{project}/locations/{location}/goldengateDeployments/{goldengate_deployment}".format( + project=project, + location=location, + goldengate_deployment=goldengate_deployment, + ) + actual = OracleDatabaseClient.goldengate_deployment_path( + project, location, goldengate_deployment + ) + assert expected == actual + + +def test_parse_goldengate_deployment_path(): + expected = { + "project": "nautilus", + "location": "scallop", + "goldengate_deployment": "abalone", + } + path = OracleDatabaseClient.goldengate_deployment_path(**expected) + + # Check that the path construction is reversible. + actual = OracleDatabaseClient.parse_goldengate_deployment_path(path) + assert expected == actual + + +def test_goldengate_deployment_environment_path(): + project = "squid" + location = "clam" + goldengate_deployment_environment = "whelk" + expected = "projects/{project}/locations/{location}/goldengateDeploymentEnvironments/{goldengate_deployment_environment}".format( + project=project, + location=location, + goldengate_deployment_environment=goldengate_deployment_environment, + ) + actual = OracleDatabaseClient.goldengate_deployment_environment_path( + project, location, goldengate_deployment_environment + ) + assert expected == actual + + +def test_parse_goldengate_deployment_environment_path(): + expected = { + "project": "octopus", + "location": "oyster", + "goldengate_deployment_environment": "nudibranch", + } + path = OracleDatabaseClient.goldengate_deployment_environment_path(**expected) + + # Check that the path construction is reversible. + actual = OracleDatabaseClient.parse_goldengate_deployment_environment_path(path) + assert expected == actual + + +def test_goldengate_deployment_type_path(): + project = "cuttlefish" + location = "mussel" + goldengate_deployment_type = "winkle" + expected = "projects/{project}/locations/{location}/goldengateDeploymentTypes/{goldengate_deployment_type}".format( + project=project, + location=location, + goldengate_deployment_type=goldengate_deployment_type, + ) + actual = OracleDatabaseClient.goldengate_deployment_type_path( + project, location, goldengate_deployment_type + ) + assert expected == actual + + +def test_parse_goldengate_deployment_type_path(): + expected = { + "project": "nautilus", + "location": "scallop", + "goldengate_deployment_type": "abalone", + } + path = OracleDatabaseClient.goldengate_deployment_type_path(**expected) + + # Check that the path construction is reversible. + actual = OracleDatabaseClient.parse_goldengate_deployment_type_path(path) + assert expected == actual + + +def test_goldengate_deployment_version_path(): + project = "squid" + location = "clam" + goldengate_deployment_version = "whelk" + expected = "projects/{project}/locations/{location}/goldengateDeploymentVersions/{goldengate_deployment_version}".format( + project=project, + location=location, + goldengate_deployment_version=goldengate_deployment_version, + ) + actual = OracleDatabaseClient.goldengate_deployment_version_path( + project, location, goldengate_deployment_version + ) + assert expected == actual + + +def test_parse_goldengate_deployment_version_path(): + expected = { + "project": "octopus", + "location": "oyster", + "goldengate_deployment_version": "nudibranch", + } + path = OracleDatabaseClient.goldengate_deployment_version_path(**expected) + + # Check that the path construction is reversible. + actual = OracleDatabaseClient.parse_goldengate_deployment_version_path(path) + assert expected == actual + + +def test_minor_version_path(): + project = "cuttlefish" + location = "mussel" + gi_version = "winkle" + minor_version = "nautilus" expected = "projects/{project}/locations/{location}/giVersions/{gi_version}/minorVersions/{minor_version}".format( project=project, location=location, @@ -54191,10 +75314,10 @@ def test_minor_version_path(): def test_parse_minor_version_path(): expected = { - "project": "oyster", - "location": "nudibranch", - "gi_version": "cuttlefish", - "minor_version": "mussel", + "project": "scallop", + "location": "abalone", + "gi_version": "squid", + "minor_version": "clam", } path = OracleDatabaseClient.minor_version_path(**expected) @@ -54204,8 +75327,8 @@ def test_parse_minor_version_path(): def test_network_path(): - project = "winkle" - network = "nautilus" + project = "whelk" + network = "octopus" expected = "projects/{project}/global/networks/{network}".format( project=project, network=network, @@ -54216,8 +75339,8 @@ def test_network_path(): def test_parse_network_path(): expected = { - "project": "scallop", - "network": "abalone", + "project": "oyster", + "network": "nudibranch", } path = OracleDatabaseClient.network_path(**expected) @@ -54227,9 +75350,9 @@ def test_parse_network_path(): def test_odb_network_path(): - project = "squid" - location = "clam" - odb_network = "whelk" + project = "cuttlefish" + location = "mussel" + odb_network = "winkle" expected = ( "projects/{project}/locations/{location}/odbNetworks/{odb_network}".format( project=project, @@ -54243,9 +75366,9 @@ def test_odb_network_path(): def test_parse_odb_network_path(): expected = { - "project": "octopus", - "location": "oyster", - "odb_network": "nudibranch", + "project": "nautilus", + "location": "scallop", + "odb_network": "abalone", } path = OracleDatabaseClient.odb_network_path(**expected) @@ -54255,10 +75378,10 @@ def test_parse_odb_network_path(): def test_odb_subnet_path(): - project = "cuttlefish" - location = "mussel" - odb_network = "winkle" - odb_subnet = "nautilus" + project = "squid" + location = "clam" + odb_network = "whelk" + odb_subnet = "octopus" expected = "projects/{project}/locations/{location}/odbNetworks/{odb_network}/odbSubnets/{odb_subnet}".format( project=project, location=location, @@ -54273,10 +75396,10 @@ def test_odb_subnet_path(): def test_parse_odb_subnet_path(): expected = { - "project": "scallop", - "location": "abalone", - "odb_network": "squid", - "odb_subnet": "clam", + "project": "oyster", + "location": "nudibranch", + "odb_network": "cuttlefish", + "odb_subnet": "mussel", } path = OracleDatabaseClient.odb_subnet_path(**expected) @@ -54286,9 +75409,9 @@ def test_parse_odb_subnet_path(): def test_pluggable_database_path(): - project = "whelk" - location = "octopus" - pluggable_database = "oyster" + project = "winkle" + location = "nautilus" + pluggable_database = "scallop" expected = "projects/{project}/locations/{location}/pluggableDatabases/{pluggable_database}".format( project=project, location=location, @@ -54302,9 +75425,9 @@ def test_pluggable_database_path(): def test_parse_pluggable_database_path(): expected = { - "project": "nudibranch", - "location": "cuttlefish", - "pluggable_database": "mussel", + "project": "abalone", + "location": "squid", + "pluggable_database": "clam", } path = OracleDatabaseClient.pluggable_database_path(**expected) @@ -54313,6 +75436,32 @@ def test_parse_pluggable_database_path(): assert expected == actual +def test_secret_version_path(): + project = "whelk" + secret = "octopus" + secret_version = "oyster" + expected = "projects/{project}/secrets/{secret}/versions/{secret_version}".format( + project=project, + secret=secret, + secret_version=secret_version, + ) + actual = OracleDatabaseClient.secret_version_path(project, secret, secret_version) + assert expected == actual + + +def test_parse_secret_version_path(): + expected = { + "project": "nudibranch", + "secret": "cuttlefish", + "secret_version": "mussel", + } + path = OracleDatabaseClient.secret_version_path(**expected) + + # Check that the path construction is reversible. + actual = OracleDatabaseClient.parse_secret_version_path(path) + assert expected == actual + + def test_common_billing_account_path(): billing_account = "winkle" expected = "billingAccounts/{billing_account}".format( From 57269d567227655e16a2c518e29129c31ebe65be Mon Sep 17 00:00:00 2001 From: amtk3 Date: Fri, 12 Jun 2026 01:05:38 +1000 Subject: [PATCH 056/174] fix(auth): configure mTLS for impersonated credentials (#17404) ### Description This PR configures `AuthorizedSession` to support mutual TLS (mTLS) when refreshing impersonated ID tokens or signing bytes. ### Context When using impersonated credentials (e.g., via `gcloud auth print-identity-token --impersonate-service-account=...`) in environments where mTLS is enforced by Context Aware Access (CAA) policies, the requests fail with `401 UNAUTHENTICATED` (specifically `ACCESS_TOKEN_TYPE_UNSUPPORTED`). Although the endpoint correctly resolves to the mTLS domain (`iamcredentials.mtls.googleapis.com`), the underlying `AuthorizedSession` created in `impersonated_credentials.py` is never configured with the client certificate, causing the TLS handshake to lack the required client cert. ### Changes * **`google/auth/impersonated_credentials.py`**: * Added `authed_session.configure_mtls_channel()` in `Credentials.sign_bytes` right after the session is created. * Added `authed_session.configure_mtls_channel()` in `IDTokenCredentials.refresh` right after the session is created. * **`tests/test_impersonated_credentials.py`**: * Added `test_sign_bytes_configures_mtls` and `test_id_token_refresh_configures_mtls` unit tests to verify `configure_mtls_channel` is invoked. --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: amtk3 <254821816+amtk3@users.noreply.github.com> --- .../google/auth/impersonated_credentials.py | 2 + .../tests/test_impersonated_credentials.py | 43 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/packages/google-auth/google/auth/impersonated_credentials.py b/packages/google-auth/google/auth/impersonated_credentials.py index 2f14d809319e..2838e138ff92 100644 --- a/packages/google-auth/google/auth/impersonated_credentials.py +++ b/packages/google-auth/google/auth/impersonated_credentials.py @@ -388,6 +388,7 @@ def sign_bytes(self, message): headers = {"Content-Type": "application/json"} authed_session = AuthorizedSession(self._source_credentials) + authed_session.configure_mtls_channel() try: retries = _exponential_backoff.ExponentialBackoff() @@ -627,6 +628,7 @@ def refresh(self, request): authed_session = AuthorizedSession( self._target_credentials._source_credentials, auth_request=request ) + authed_session.configure_mtls_channel() try: response = authed_session.post( diff --git a/packages/google-auth/tests/test_impersonated_credentials.py b/packages/google-auth/tests/test_impersonated_credentials.py index c286e3010f38..f937e871cdf9 100644 --- a/packages/google-auth/tests/test_impersonated_credentials.py +++ b/packages/google-auth/tests/test_impersonated_credentials.py @@ -639,6 +639,26 @@ def _sign_bytes_helper( assert signature == b"signature" + @mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel", + autospec=True, + ) + def test_sign_bytes_configures_mtls( + self, mock_configure_mtls, mock_donor_credentials, mock_authorizedsession_sign + ): + credentials = self.make_credentials(lifetime=None) + # Refresh is needed to make credentials valid before signing + request = self.make_request( + data=json.dumps( + {"accessToken": "token", "expireTime": "2026-06-09T00:00:00Z"} + ), + status=http_client.OK, + ) + credentials.refresh(request) + + credentials.sign_bytes(b"signed bytes") + mock_configure_mtls.assert_called_once() + def test_sign_bytes_failure(self): credentials = self.make_credentials(lifetime=None) @@ -751,6 +771,29 @@ def test_with_scopes_provide_default_scopes(self): ) assert credentials._target_scopes == ["fake_scope1"] + @mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel", + autospec=True, + ) + def test_id_token_refresh_configures_mtls( + self, mock_configure_mtls, mock_donor_credentials + ): + credentials = self.make_credentials(lifetime=None) + credentials.token = "token" + id_creds = impersonated_credentials.IDTokenCredentials( + credentials, target_audience="https://foo.bar" + ) + + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.post", autospec=True + ) as mock_post: + mock_post.return_value = MockResponse( + {"token": ID_TOKEN_DATA}, http_client.OK + ) + id_creds.refresh(None) + + mock_configure_mtls.assert_called_once() + def test_id_token_success( self, mock_donor_credentials, mock_authorizedsession_idtoken ): From 7d230af033a12f527b84baa3647e113c6e8c3d01 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jun 2026 11:07:44 -0400 Subject: [PATCH 057/174] chore(deps): bump pyspark from 3.5.1 to 3.5.2 in /packages/bigframes (#17400) Bumps [pyspark](https://github.com/apache/spark) from 3.5.1 to 3.5.2.
Commits
  • bb7846d Preparing Spark release v3.5.2-rc5
  • d13808c [SPARK-49099][SQL][FOLLOWUP][3.5] recover tests in DDLSuite
  • f2e2601 [SPARK-49099][SQL] CatalogManager.setCurrentNamespace should respect custom s...
  • b33a3ee [SPARK-48791][CORE][FOLLOW-UP][3.5] Fix regression caused by immutable conver...
  • 98eaaa5 [SPARK-49094][SQL] Fix ignoreCorruptFiles non-functioning for hive orc impl w...
  • 0008bd1 [SPARK-49000][SQL][3.5] Fix "select count(distinct 1) from t" where t is empt...
  • 4f9dbc3 [SPARK-49066][SQL][TESTS][3.5] Refactor OrcEncryptionSuite and make `spark....
  • a1e7fb1 [SPARK-49065][SQL] Rebasing in legacy formatters/parsers must support non JVM...
  • 94558f6 Revert "[SPARK-49000][SQL] Fix "select count(distinct 1) from t" where t is e...
  • 36f9a4b Revert "[SPARK-49066][SQL][TESTS] Refactor OrcEncryptionSuite and make `spa...
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pyspark&package-manager=pip&previous-version=3.5.1&new-version=3.5.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/googleapis/google-cloud-python/network/alerts).
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- packages/bigframes/testing/constraints-3.11.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bigframes/testing/constraints-3.11.txt b/packages/bigframes/testing/constraints-3.11.txt index be070f9732b9..6340dde0c545 100644 --- a/packages/bigframes/testing/constraints-3.11.txt +++ b/packages/bigframes/testing/constraints-3.11.txt @@ -444,7 +444,7 @@ pyproj==3.7.1 pyproject_hooks==1.2.0 pyshp==2.3.1 PySocks==1.7.1 -pyspark==3.5.1 +pyspark==3.5.2 pytensor==2.31.7 python-apt==0.0.0 python-box==7.3.2 From dd823f5edeef2550c52baf7e66ef306bd0a93707 Mon Sep 17 00:00:00 2001 From: Daniel Sanche Date: Thu, 11 Jun 2026 08:28:01 -0700 Subject: [PATCH 058/174] chore(bigtable): add bigtable samples (#17240) Adding back hand-written samples to python-bigtable There is an argument that these samples should live in https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main, but I think it's best to keep the generated and hand-written samples together for now. And then we can revisit this again after splitting the admin and data surfaces. Let me know if you disagree --- .../google-cloud-bigtable/CONTRIBUTING.rst | 6 +- .../samples/AUTHORING_GUIDE.md | 1 + .../samples/CONTRIBUTING.md | 1 + .../google-cloud-bigtable/samples/README.md | 24 + .../google-cloud-bigtable/samples/__init__.py | 0 .../samples/beam/__init__.py | 0 .../samples/beam/hello_world_write.py | 70 +++ .../samples/beam/hello_world_write_test.py | 48 ++ .../samples/beam/noxfile.py | 290 ++++++++++ .../samples/beam/noxfile_config.py | 45 ++ .../samples/beam/requirements-test.txt | 1 + .../samples/beam/requirements.txt | 5 + .../samples/hello/README.md | 52 ++ .../samples/hello/__init__.py | 0 .../samples/hello/async_main.py | 148 ++++++ .../samples/hello/async_main_test.py | 36 ++ .../samples/hello/main.py | 152 ++++++ .../samples/hello/main_test.py | 35 ++ .../samples/hello/noxfile.py | 292 ++++++++++ .../samples/hello/requirements-test.txt | 1 + .../samples/hello/requirements.txt | 2 + .../samples/hello_happybase/README.md | 52 ++ .../samples/hello_happybase/__init__.py | 0 .../samples/hello_happybase/main.py | 118 ++++ .../samples/hello_happybase/main_test.py | 45 ++ .../samples/hello_happybase/noxfile.py | 292 ++++++++++ .../hello_happybase/requirements-test.txt | 1 + .../samples/hello_happybase/requirements.txt | 2 + .../samples/instanceadmin/README.md | 52 ++ .../samples/instanceadmin/instanceadmin.py | 232 ++++++++ .../samples/instanceadmin/noxfile.py | 292 ++++++++++ .../instanceadmin/requirements-test.txt | 1 + .../samples/instanceadmin/requirements.txt | 2 + .../instanceadmin/test_instanceadmin.py | 179 +++++++ .../samples/metricscaler/Dockerfile | 24 + .../samples/metricscaler/README.md | 52 ++ .../samples/metricscaler/metricscaler.py | 234 ++++++++ .../samples/metricscaler/metricscaler_test.py | 225 ++++++++ .../samples/metricscaler/noxfile.py | 292 ++++++++++ .../samples/metricscaler/noxfile_config.py | 39 ++ .../metricscaler/requirements-test.txt | 3 + .../samples/metricscaler/requirements.txt | 2 + .../samples/quickstart/README.md | 52 ++ .../samples/quickstart/__init__.py | 0 .../samples/quickstart/main.py | 57 ++ .../samples/quickstart/main_async.py | 61 +++ .../samples/quickstart/main_async_test.py | 50 ++ .../samples/quickstart/main_test.py | 47 ++ .../samples/quickstart/noxfile.py | 292 ++++++++++ .../samples/quickstart/requirements-test.txt | 2 + .../samples/quickstart/requirements.txt | 1 + .../samples/quickstart_happybase/README.md | 52 ++ .../samples/quickstart_happybase/__init__.py | 0 .../samples/quickstart_happybase/main.py | 60 +++ .../samples/quickstart_happybase/main_test.py | 47 ++ .../samples/quickstart_happybase/noxfile.py | 292 ++++++++++ .../requirements-test.txt | 1 + .../quickstart_happybase/requirements.txt | 2 + .../samples/snippets/README.md | 33 ++ .../samples/snippets/__init__.py | 0 .../samples/snippets/data_client/__init__.py | 0 .../data_client/data_client_snippets_async.py | 315 +++++++++++ .../data_client_snippets_async_test.py | 117 ++++ .../samples/snippets/data_client/noxfile.py | 292 ++++++++++ .../data_client/requirements-test.txt | 2 + .../snippets/data_client/requirements.txt | 1 + .../samples/snippets/deletes/__init__.py | 0 .../snippets/deletes/deletes_async_test.py | 281 ++++++++++ .../snippets/deletes/deletes_snippets.py | 136 +++++ .../deletes/deletes_snippets_async.py | 124 +++++ .../samples/snippets/deletes/deletes_test.py | 139 +++++ .../samples/snippets/deletes/noxfile.py | 292 ++++++++++ .../snippets/deletes/requirements-test.txt | 2 + .../samples/snippets/deletes/requirements.txt | 1 + .../samples/snippets/filters/__init__.py | 0 .../snippets/filters/filter_snippets.py | 358 +++++++++++++ .../snippets/filters/filter_snippets_async.py | 389 ++++++++++++++ .../filters/filter_snippets_async_test.py | 450 ++++++++++++++++ .../samples/snippets/filters/filters_test.py | 237 +++++++++ .../samples/snippets/filters/noxfile.py | 292 ++++++++++ .../snippets/filters/requirements-test.txt | 2 + .../samples/snippets/filters/requirements.txt | 1 + .../snippets/filters/snapshots/__init__.py | 0 .../filters/snapshots/snap_filters_test.py | 503 ++++++++++++++++++ .../samples/snippets/reads/__init__.py | 0 .../samples/snippets/reads/noxfile.py | 292 ++++++++++ .../samples/snippets/reads/read_snippets.py | 170 ++++++ .../samples/snippets/reads/reads_test.py | 118 ++++ .../snippets/reads/requirements-test.txt | 1 + .../samples/snippets/reads/requirements.txt | 1 + .../snippets/reads/snapshots/__init__.py | 0 .../reads/snapshots/snap_reads_test.py | 141 +++++ .../samples/snippets/writes/__init__.py | 0 .../samples/snippets/writes/noxfile.py | 292 ++++++++++ .../snippets/writes/requirements-test.txt | 2 + .../samples/snippets/writes/requirements.txt | 1 + .../samples/snippets/writes/write_batch.py | 46 ++ .../snippets/writes/write_conditionally.py | 46 ++ .../snippets/writes/write_increment.py | 36 ++ .../samples/snippets/writes/write_simple.py | 42 ++ .../samples/snippets/writes/writes_test.py | 72 +++ .../samples/tableadmin/README.md | 52 ++ .../samples/tableadmin/__init__.py | 0 .../samples/tableadmin/noxfile.py | 292 ++++++++++ .../samples/tableadmin/requirements-test.txt | 2 + .../samples/tableadmin/requirements.txt | 1 + .../samples/tableadmin/tableadmin.py | 266 +++++++++ .../samples/tableadmin/tableadmin_test.py | 61 +++ .../samples/testdata/README.md | 5 + .../samples/testdata/descriptors.pb | Bin 0 -> 182 bytes .../samples/testdata/singer.proto | 15 + .../samples/testdata/singer_pb2.py | 28 + .../google-cloud-bigtable/samples/utils.py | 105 ++++ 113 files changed, 10415 insertions(+), 3 deletions(-) create mode 100644 packages/google-cloud-bigtable/samples/AUTHORING_GUIDE.md create mode 100644 packages/google-cloud-bigtable/samples/CONTRIBUTING.md create mode 100644 packages/google-cloud-bigtable/samples/README.md create mode 100644 packages/google-cloud-bigtable/samples/__init__.py create mode 100644 packages/google-cloud-bigtable/samples/beam/__init__.py create mode 100644 packages/google-cloud-bigtable/samples/beam/hello_world_write.py create mode 100644 packages/google-cloud-bigtable/samples/beam/hello_world_write_test.py create mode 100644 packages/google-cloud-bigtable/samples/beam/noxfile.py create mode 100644 packages/google-cloud-bigtable/samples/beam/noxfile_config.py create mode 100644 packages/google-cloud-bigtable/samples/beam/requirements-test.txt create mode 100644 packages/google-cloud-bigtable/samples/beam/requirements.txt create mode 100644 packages/google-cloud-bigtable/samples/hello/README.md create mode 100644 packages/google-cloud-bigtable/samples/hello/__init__.py create mode 100644 packages/google-cloud-bigtable/samples/hello/async_main.py create mode 100644 packages/google-cloud-bigtable/samples/hello/async_main_test.py create mode 100644 packages/google-cloud-bigtable/samples/hello/main.py create mode 100644 packages/google-cloud-bigtable/samples/hello/main_test.py create mode 100644 packages/google-cloud-bigtable/samples/hello/noxfile.py create mode 100644 packages/google-cloud-bigtable/samples/hello/requirements-test.txt create mode 100644 packages/google-cloud-bigtable/samples/hello/requirements.txt create mode 100644 packages/google-cloud-bigtable/samples/hello_happybase/README.md create mode 100644 packages/google-cloud-bigtable/samples/hello_happybase/__init__.py create mode 100644 packages/google-cloud-bigtable/samples/hello_happybase/main.py create mode 100644 packages/google-cloud-bigtable/samples/hello_happybase/main_test.py create mode 100644 packages/google-cloud-bigtable/samples/hello_happybase/noxfile.py create mode 100644 packages/google-cloud-bigtable/samples/hello_happybase/requirements-test.txt create mode 100644 packages/google-cloud-bigtable/samples/hello_happybase/requirements.txt create mode 100644 packages/google-cloud-bigtable/samples/instanceadmin/README.md create mode 100644 packages/google-cloud-bigtable/samples/instanceadmin/instanceadmin.py create mode 100644 packages/google-cloud-bigtable/samples/instanceadmin/noxfile.py create mode 100644 packages/google-cloud-bigtable/samples/instanceadmin/requirements-test.txt create mode 100644 packages/google-cloud-bigtable/samples/instanceadmin/requirements.txt create mode 100644 packages/google-cloud-bigtable/samples/instanceadmin/test_instanceadmin.py create mode 100644 packages/google-cloud-bigtable/samples/metricscaler/Dockerfile create mode 100644 packages/google-cloud-bigtable/samples/metricscaler/README.md create mode 100644 packages/google-cloud-bigtable/samples/metricscaler/metricscaler.py create mode 100644 packages/google-cloud-bigtable/samples/metricscaler/metricscaler_test.py create mode 100644 packages/google-cloud-bigtable/samples/metricscaler/noxfile.py create mode 100644 packages/google-cloud-bigtable/samples/metricscaler/noxfile_config.py create mode 100644 packages/google-cloud-bigtable/samples/metricscaler/requirements-test.txt create mode 100644 packages/google-cloud-bigtable/samples/metricscaler/requirements.txt create mode 100644 packages/google-cloud-bigtable/samples/quickstart/README.md create mode 100644 packages/google-cloud-bigtable/samples/quickstart/__init__.py create mode 100644 packages/google-cloud-bigtable/samples/quickstart/main.py create mode 100644 packages/google-cloud-bigtable/samples/quickstart/main_async.py create mode 100644 packages/google-cloud-bigtable/samples/quickstart/main_async_test.py create mode 100644 packages/google-cloud-bigtable/samples/quickstart/main_test.py create mode 100644 packages/google-cloud-bigtable/samples/quickstart/noxfile.py create mode 100644 packages/google-cloud-bigtable/samples/quickstart/requirements-test.txt create mode 100644 packages/google-cloud-bigtable/samples/quickstart/requirements.txt create mode 100644 packages/google-cloud-bigtable/samples/quickstart_happybase/README.md create mode 100644 packages/google-cloud-bigtable/samples/quickstart_happybase/__init__.py create mode 100644 packages/google-cloud-bigtable/samples/quickstart_happybase/main.py create mode 100644 packages/google-cloud-bigtable/samples/quickstart_happybase/main_test.py create mode 100644 packages/google-cloud-bigtable/samples/quickstart_happybase/noxfile.py create mode 100644 packages/google-cloud-bigtable/samples/quickstart_happybase/requirements-test.txt create mode 100644 packages/google-cloud-bigtable/samples/quickstart_happybase/requirements.txt create mode 100644 packages/google-cloud-bigtable/samples/snippets/README.md create mode 100644 packages/google-cloud-bigtable/samples/snippets/__init__.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/data_client/__init__.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/data_client/data_client_snippets_async.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/data_client/data_client_snippets_async_test.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/data_client/noxfile.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/data_client/requirements-test.txt create mode 100644 packages/google-cloud-bigtable/samples/snippets/data_client/requirements.txt create mode 100644 packages/google-cloud-bigtable/samples/snippets/deletes/__init__.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/deletes/deletes_async_test.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/deletes/deletes_snippets.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/deletes/deletes_snippets_async.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/deletes/deletes_test.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/deletes/noxfile.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/deletes/requirements-test.txt create mode 100644 packages/google-cloud-bigtable/samples/snippets/deletes/requirements.txt create mode 100644 packages/google-cloud-bigtable/samples/snippets/filters/__init__.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/filters/filter_snippets.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/filters/filter_snippets_async.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/filters/filter_snippets_async_test.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/filters/filters_test.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/filters/noxfile.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/filters/requirements-test.txt create mode 100644 packages/google-cloud-bigtable/samples/snippets/filters/requirements.txt create mode 100644 packages/google-cloud-bigtable/samples/snippets/filters/snapshots/__init__.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/filters/snapshots/snap_filters_test.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/reads/__init__.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/reads/noxfile.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/reads/read_snippets.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/reads/reads_test.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/reads/requirements-test.txt create mode 100644 packages/google-cloud-bigtable/samples/snippets/reads/requirements.txt create mode 100644 packages/google-cloud-bigtable/samples/snippets/reads/snapshots/__init__.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/reads/snapshots/snap_reads_test.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/writes/__init__.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/writes/noxfile.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/writes/requirements-test.txt create mode 100644 packages/google-cloud-bigtable/samples/snippets/writes/requirements.txt create mode 100644 packages/google-cloud-bigtable/samples/snippets/writes/write_batch.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/writes/write_conditionally.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/writes/write_increment.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/writes/write_simple.py create mode 100644 packages/google-cloud-bigtable/samples/snippets/writes/writes_test.py create mode 100644 packages/google-cloud-bigtable/samples/tableadmin/README.md create mode 100644 packages/google-cloud-bigtable/samples/tableadmin/__init__.py create mode 100644 packages/google-cloud-bigtable/samples/tableadmin/noxfile.py create mode 100644 packages/google-cloud-bigtable/samples/tableadmin/requirements-test.txt create mode 100644 packages/google-cloud-bigtable/samples/tableadmin/requirements.txt create mode 100644 packages/google-cloud-bigtable/samples/tableadmin/tableadmin.py create mode 100755 packages/google-cloud-bigtable/samples/tableadmin/tableadmin_test.py create mode 100644 packages/google-cloud-bigtable/samples/testdata/README.md create mode 100644 packages/google-cloud-bigtable/samples/testdata/descriptors.pb create mode 100644 packages/google-cloud-bigtable/samples/testdata/singer.proto create mode 100644 packages/google-cloud-bigtable/samples/testdata/singer_pb2.py create mode 100644 packages/google-cloud-bigtable/samples/utils.py diff --git a/packages/google-cloud-bigtable/CONTRIBUTING.rst b/packages/google-cloud-bigtable/CONTRIBUTING.rst index 0d771b8118cf..9de20daeac72 100644 --- a/packages/google-cloud-bigtable/CONTRIBUTING.rst +++ b/packages/google-cloud-bigtable/CONTRIBUTING.rst @@ -95,10 +95,10 @@ On Debian/Ubuntu:: ************ Coding Style ************ -- We use the automatic code formatter ``black``. You can run it using - the nox session ``blacken``. This will eliminate many lint errors. Run via:: +- We use the automatic code formatter ``ruff``. You can run it using + the nox session ``format``. This will eliminate many lint errors. Run via:: - $ nox -s blacken + $ nox -s format - PEP8 compliance is required, with exceptions defined in the linter configuration. If you have ``nox`` installed, you can test that you have not introduced diff --git a/packages/google-cloud-bigtable/samples/AUTHORING_GUIDE.md b/packages/google-cloud-bigtable/samples/AUTHORING_GUIDE.md new file mode 100644 index 000000000000..8249522ffc2d --- /dev/null +++ b/packages/google-cloud-bigtable/samples/AUTHORING_GUIDE.md @@ -0,0 +1 @@ +See https://github.com/GoogleCloudPlatform/python-docs-samples/blob/main/AUTHORING_GUIDE.md \ No newline at end of file diff --git a/packages/google-cloud-bigtable/samples/CONTRIBUTING.md b/packages/google-cloud-bigtable/samples/CONTRIBUTING.md new file mode 100644 index 000000000000..f5fe2e6baf13 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/CONTRIBUTING.md @@ -0,0 +1 @@ +See https://github.com/GoogleCloudPlatform/python-docs-samples/blob/main/CONTRIBUTING.md \ No newline at end of file diff --git a/packages/google-cloud-bigtable/samples/README.md b/packages/google-cloud-bigtable/samples/README.md new file mode 100644 index 000000000000..1301c6fb1f60 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/README.md @@ -0,0 +1,24 @@ +[//]: # "This README.md file is auto-generated, all changes to this file will be lost." +[//]: # "To regenerate it, use `python -m synthtool`." + +## Python Samples for Cloud Bigtable + +This directory contains samples for Cloud Bigtable, which may be used as a refererence for how to use this product. + +## Additional Information + +You can read the documentation for more details on API usage and use GitHub +to browse the source and [report issues][issues]. + +### Contributing +View the [contributing guidelines][contrib_guide], the [Python style guide][py_style] for more information. + +[authentication]: https://cloud.google.com/docs/authentication/getting-started +[enable_billing]:https://cloud.google.com/apis/docs/getting-started#enabling_billing +[client_library_python]: https://googlecloudplatform.github.io/google-cloud-python/ +[issues]: https://github.com/GoogleCloudPlatform/google-cloud-python/issues +[contrib_guide]: https://github.com/googleapis/google-cloud-python/blob/main/CONTRIBUTING.rst +[py_style]: http://google.github.io/styleguide/pyguide.html +[cloud_sdk]: https://cloud.google.com/sdk/docs +[gcloud_shell]: https://cloud.google.com/shell/docs +[gcloud_shell]: https://cloud.google.com/shell/docs diff --git a/packages/google-cloud-bigtable/samples/__init__.py b/packages/google-cloud-bigtable/samples/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-cloud-bigtable/samples/beam/__init__.py b/packages/google-cloud-bigtable/samples/beam/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-cloud-bigtable/samples/beam/hello_world_write.py b/packages/google-cloud-bigtable/samples/beam/hello_world_write.py new file mode 100644 index 000000000000..06c9505f2f29 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/beam/hello_world_write.py @@ -0,0 +1,70 @@ +# Copyright 2020 Google Inc. +# +# 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 datetime + +import apache_beam as beam +from apache_beam.io.gcp.bigtableio import WriteToBigTable +from apache_beam.options.pipeline_options import PipelineOptions + +from google.cloud.bigtable import row + + +class BigtableOptions(PipelineOptions): + @classmethod + def _add_argparse_args(cls, parser): + parser.add_argument( + "--bigtable-project", + help="The Bigtable project ID, this can be different than your " + "Dataflow project", + default="bigtable-project", + ) + parser.add_argument( + "--bigtable-instance", + help="The Bigtable instance ID", + default="bigtable-instance", + ) + parser.add_argument( + "--bigtable-table", + help="The Bigtable table ID in the instance.", + default="bigtable-table", + ) + + +class CreateRowFn(beam.DoFn): + def process(self, key): + direct_row = row.DirectRow(row_key=key) + direct_row.set_cell( + "stats_summary", b"os_build", b"android", datetime.datetime.now() + ) + return [direct_row] + + +def run(argv=None): + """Build and run the pipeline.""" + options = BigtableOptions(argv) + with beam.Pipeline(options=options) as p: + ( + p + | beam.Create(["phone#4c410523#20190501", "phone#4c410523#20190502"]) + | beam.ParDo(CreateRowFn()) + | WriteToBigTable( + project_id=options.bigtable_project, + instance_id=options.bigtable_instance, + table_id=options.bigtable_table, + ) + ) + + +if __name__ == "__main__": + run() diff --git a/packages/google-cloud-bigtable/samples/beam/hello_world_write_test.py b/packages/google-cloud-bigtable/samples/beam/hello_world_write_test.py new file mode 100644 index 000000000000..82490ec7855e --- /dev/null +++ b/packages/google-cloud-bigtable/samples/beam/hello_world_write_test.py @@ -0,0 +1,48 @@ +# Copyright 2020 Google Inc. +# +# 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 uuid + +import pytest + +from ..utils import create_table_cm +from . import hello_world_write + +PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"] +BIGTABLE_INSTANCE = os.environ["BIGTABLE_INSTANCE"] +TABLE_ID = f"mobile-time-series-beam-{str(uuid.uuid4())[:16]}" + + +@pytest.fixture(scope="module", autouse=True) +def table(): + with create_table_cm( + PROJECT, BIGTABLE_INSTANCE, TABLE_ID, {"stats_summary": None} + ) as table: + yield table + + +def test_hello_world_write(table): + hello_world_write.run( + [ + "--bigtable-project=%s" % PROJECT, + "--bigtable-instance=%s" % BIGTABLE_INSTANCE, + "--bigtable-table=%s" % TABLE_ID, + ] + ) + + rows = table.read_rows() + count = 0 + for _ in rows: + count += 1 + assert count == 2 diff --git a/packages/google-cloud-bigtable/samples/beam/noxfile.py b/packages/google-cloud-bigtable/samples/beam/noxfile.py new file mode 100644 index 000000000000..1b8f66b398c9 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/beam/noxfile.py @@ -0,0 +1,290 @@ +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import print_function + +import glob +import os +import sys +from pathlib import Path +from typing import Callable, Dict, Optional + +import nox + +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING +# DO NOT EDIT THIS FILE EVER! +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING + +BLACK_VERSION = "black==22.3.0" +ISORT_VERSION = "isort==5.10.1" + +# Copy `noxfile_config.py` to your directory and modify it instead. + +# `TEST_CONFIG` dict is a configuration hook that allows users to +# modify the test configurations. The values here should be in sync +# with `noxfile_config.py`. Users will copy `noxfile_config.py` into +# their directory and modify it. + +TEST_CONFIG = { + # You can opt out from the test for specific Python versions. + "ignored_versions": [], + # Old samples are opted out of enforcing Python type hints + # All new samples should feature them + "enforce_type_hints": False, + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", + # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + # If you need to use a specific version of pip, + # change pip_version_override to the string representation + # of the version number, for example, "20.2.4" + "pip_version_override": None, + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + "envs": {}, +} + + +try: + # Ensure we can import noxfile_config in the project's directory. + sys.path.append(".") + from noxfile_config import TEST_CONFIG_OVERRIDE +except ImportError as e: + print("No user noxfile_config found: detail: {}".format(e)) + TEST_CONFIG_OVERRIDE = {} + +# Update the TEST_CONFIG with the user supplied values. +TEST_CONFIG.update(TEST_CONFIG_OVERRIDE) + + +def get_pytest_env_vars() -> Dict[str, str]: + """Returns a dict for pytest invocation.""" + ret = {} + + # Override the GCLOUD_PROJECT and the alias. + env_key = TEST_CONFIG["gcloud_project_env"] + # This should error out if not set. + ret["GOOGLE_CLOUD_PROJECT"] = os.environ[env_key] + + # Apply user supplied envs. + ret.update(TEST_CONFIG["envs"]) + return ret + + +# DO NOT EDIT - automatically generated. +# All versions used to test samples. +ALL_VERSIONS = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + +# Any default versions that should be ignored. +IGNORED_VERSIONS = TEST_CONFIG["ignored_versions"] + +TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) + +# todo(kolea2): temporary workaround to install pinned dep version +INSTALL_LIBRARY_FROM_SOURCE = False + +# Error if a python version is missing +nox.options.error_on_missing_interpreters = True + +# +# Style Checks +# + + +# Linting with flake8. +# +# We ignore the following rules: +# E203: whitespace before ‘:’ +# E266: too many leading ‘#’ for block comment +# E501: line too long +# I202: Additional newline in a section of imports +# +# We also need to specify the rules which are ignored by default: +# ['E226', 'W504', 'E126', 'E123', 'W503', 'E24', 'E704', 'E121'] +FLAKE8_COMMON_ARGS = [ + "--show-source", + "--builtin=gettext", + "--max-complexity=20", + "--exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py", + "--ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202", + "--max-line-length=88", +] + + +@nox.session +def lint(session: nox.sessions.Session) -> None: + if not TEST_CONFIG["enforce_type_hints"]: + session.install("flake8") + else: + session.install("flake8", "flake8-annotations") + + args = FLAKE8_COMMON_ARGS + [ + ".", + ] + session.run("flake8", *args) + + +# +# Black +# + + +@nox.session +def blacken(session: nox.sessions.Session) -> None: + """Run black. Format code to uniform standard.""" + session.install(BLACK_VERSION) + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + session.run("black", *python_files) + + +# +# format = isort + black +# + + +@nox.session +def format(session: nox.sessions.Session) -> None: + """ + Run isort to sort imports. Then run black + to format code to uniform standard. + """ + session.install(BLACK_VERSION, ISORT_VERSION) + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + # Use the --fss option to sort imports using strict alphabetical order. + # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + session.run("isort", "--fss", *python_files) + session.run("black", *python_files) + + +# +# Sample Tests +# + + +PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] + + +def _session_tests( + session: nox.sessions.Session, post_install: Callable = None +) -> None: + # check for presence of tests + test_list = glob.glob("**/*_test.py", recursive=True) + glob.glob( + "**/test_*.py", recursive=True + ) + test_list.extend(glob.glob("**/tests", recursive=True)) + + if len(test_list) == 0: + print("No tests found, skipping directory.") + return + + if TEST_CONFIG["pip_version_override"]: + pip_version = TEST_CONFIG["pip_version_override"] + session.install(f"pip=={pip_version}") + """Runs py.test for a particular project.""" + concurrent_args = [] + if os.path.exists("requirements.txt"): + if os.path.exists("constraints.txt"): + session.install("-r", "requirements.txt", "-c", "constraints.txt") + else: + session.install("-r", "requirements.txt") + with open("requirements.txt") as rfile: + packages = rfile.read() + + if os.path.exists("requirements-test.txt"): + if os.path.exists("constraints-test.txt"): + session.install("-r", "requirements-test.txt", "-c", "constraints-test.txt") + else: + session.install("-r", "requirements-test.txt") + with open("requirements-test.txt") as rtfile: + packages += rtfile.read() + + if INSTALL_LIBRARY_FROM_SOURCE: + session.install("-e", _get_repo_root()) + + if post_install: + post_install(session) + + if "pytest-parallel" in packages: + concurrent_args.extend(["--workers", "auto", "--tests-per-worker", "auto"]) + elif "pytest-xdist" in packages: + concurrent_args.extend(["-n", "auto"]) + + session.run( + "pytest", + *(PYTEST_COMMON_ARGS + session.posargs + concurrent_args), + # Pytest will return 5 when no tests are collected. This can happen + # on travis where slow and flaky tests are excluded. + # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html + success_codes=[0, 5], + env=get_pytest_env_vars(), + ) + + +@nox.session(python=ALL_VERSIONS) +def py(session: nox.sessions.Session) -> None: + """Runs py.test for a sample using the specified version of Python.""" + if session.python in TESTED_VERSIONS: + _session_tests(session) + else: + session.skip( + "SKIPPED: {} tests are disabled for this sample.".format(session.python) + ) + + +# +# Readmegen +# + + +def _get_repo_root() -> Optional[str]: + """Returns the root folder of the project.""" + # Get root of this repository. Assume we don't have directories nested deeper than 10 items. + p = Path(os.getcwd()) + for i in range(10): + if p is None: + break + if Path(p / ".git").exists(): + return str(p) + # .git is not available in repos cloned via Cloud Build + # setup.py is always in the library's root, so use that instead + # https://github.com/googleapis/synthtool/issues/792 + if Path(p / "setup.py").exists(): + return str(p) + p = p.parent + raise Exception("Unable to detect repository root.") + + +GENERATED_READMES = sorted([x for x in Path(".").rglob("*.rst.in")]) + + +@nox.session +@nox.parametrize("path", GENERATED_READMES) +def readmegen(session: nox.sessions.Session, path: str) -> None: + """(Re-)generates the readme for a sample.""" + session.install("jinja2", "pyyaml") + dir_ = os.path.dirname(path) + + if os.path.exists(os.path.join(dir_, "requirements.txt")): + session.install("-r", os.path.join(dir_, "requirements.txt")) + + in_file = os.path.join(dir_, "README.rst.in") + session.run( + "python", _get_repo_root() + "/scripts/readme-gen/readme_gen.py", in_file + ) diff --git a/packages/google-cloud-bigtable/samples/beam/noxfile_config.py b/packages/google-cloud-bigtable/samples/beam/noxfile_config.py new file mode 100644 index 000000000000..66d7bc5aca17 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/beam/noxfile_config.py @@ -0,0 +1,45 @@ +# Copyright 2021 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. + +# Default TEST_CONFIG_OVERRIDE for python repos. + +# You can copy this file into your directory, then it will be imported from +# the noxfile.py. + +# The source of truth: +# https://github.com/GoogleCloudPlatform/python-docs-samples/blob/main/noxfile_config.py + +TEST_CONFIG_OVERRIDE = { + # You can opt out from the test for specific Python versions. + "ignored_versions": [ + "3.7", # Beam no longer supports Python 3.7 for new releases + "3.12", # Beam not yet supported for Python 3.12 + ], + # Old samples are opted out of enforcing Python type hints + # All new samples should feature them + "enforce_type_hints": False, + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", + # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + # If you need to use a specific version of pip, + # change pip_version_override to the string representation + # of the version number, for example, "20.2.4" + "pip_version_override": None, + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + "envs": {}, +} diff --git a/packages/google-cloud-bigtable/samples/beam/requirements-test.txt b/packages/google-cloud-bigtable/samples/beam/requirements-test.txt new file mode 100644 index 000000000000..e079f8a6038d --- /dev/null +++ b/packages/google-cloud-bigtable/samples/beam/requirements-test.txt @@ -0,0 +1 @@ +pytest diff --git a/packages/google-cloud-bigtable/samples/beam/requirements.txt b/packages/google-cloud-bigtable/samples/beam/requirements.txt new file mode 100644 index 000000000000..e709a03cb849 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/beam/requirements.txt @@ -0,0 +1,5 @@ +apache-beam===2.60.0; python_version == '3.8' +apache-beam===2.69.0; python_version == '3.9' +apache-beam==2.71.0; python_version >= '3.10' +google-cloud-bigtable==2.35.0 +google-cloud-core==2.5.0 diff --git a/packages/google-cloud-bigtable/samples/hello/README.md b/packages/google-cloud-bigtable/samples/hello/README.md new file mode 100644 index 000000000000..b3779fb43b27 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/hello/README.md @@ -0,0 +1,52 @@ +[//]: # "This README.md file is auto-generated, all changes to this file will be lost." +[//]: # "To regenerate it, use `python -m synthtool`." + +## Python Samples for Cloud Bigtable + +This directory contains samples for Cloud Bigtable, which may be used as a refererence for how to use this product. +Samples, quickstarts, and other documentation are available at cloud.google.com. + + +### Hello World in Cloud Bigtable + +Demonstrates how to connect to Cloud Bigtable and run some basic operations. More information available at: https://cloud.google.com/bigtable/docs/samples-python-hello + + +Open in Cloud Shell + + +To run this sample: + +1. If this is your first time working with GCP products, you will need to set up [the Cloud SDK][cloud_sdk] or utilize [Google Cloud Shell][gcloud_shell]. This sample may [require authentication][authentication] and you will need to [enable billing][enable_billing]. + +1. Make a fork of this repo and clone the branch locally, then navigate to the sample directory you want to use. + +1. Install the dependencies needed to run the samples. + + pip install -r requirements.txt + +1. Run the sample using + + python main.py + + + +
usage: main.py [-h] [--table TABLE] project_id instance_id
Demonstrates how to connect to Cloud Bigtable and run some basic operations.
Prerequisites: - Create a Cloud Bigtable cluster.
https://cloud.google.com/bigtable/docs/creating-cluster - Set your Google
Application Default Credentials.
https://developers.google.com/identity/protocols/application-default-
credentials


positional arguments:
  project_id     Your Cloud Platform project ID.
  instance_id    ID of the Cloud Bigtable instance to connect to.


optional arguments:
  -h, --help     show this help message and exit
  --table TABLE  Table to create and destroy. (default: Hello-Bigtable)
+ +## Additional Information + +You can read the documentation for more details on API usage and use GitHub +to browse the source and [report issues][issues]. + +### Contributing +View the [contributing guidelines][contrib_guide], the [Python style guide][py_style] for more information. + +[authentication]: https://cloud.google.com/docs/authentication/getting-started +[enable_billing]:https://cloud.google.com/apis/docs/getting-started#enabling_billing +[client_library_python]: https://googlecloudplatform.github.io/google-cloud-python/ +[issues]: https://github.com/GoogleCloudPlatform/google-cloud-python/issues +[contrib_guide]: https://github.com/googleapis/google-cloud-python/blob/main/CONTRIBUTING.rst +[py_style]: http://google.github.io/styleguide/pyguide.html +[cloud_sdk]: https://cloud.google.com/sdk/docs +[gcloud_shell]: https://cloud.google.com/shell/docs +[gcloud_shell]: https://cloud.google.com/shell/docs diff --git a/packages/google-cloud-bigtable/samples/hello/__init__.py b/packages/google-cloud-bigtable/samples/hello/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-cloud-bigtable/samples/hello/async_main.py b/packages/google-cloud-bigtable/samples/hello/async_main.py new file mode 100644 index 000000000000..c26a74faeead --- /dev/null +++ b/packages/google-cloud-bigtable/samples/hello/async_main.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python + +# Copyright 2024 Google Inc. +# +# 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. + +"""Demonstrates how to connect to Cloud Bigtable and run some basic operations with the async APIs + +Prerequisites: + +- Create a Cloud Bigtable instance. + https://cloud.google.com/bigtable/docs/creating-instance +- Set your Google Application Default Credentials. + https://developers.google.com/identity/protocols/application-default-credentials +""" + +import argparse +import asyncio + +# [START bigtable_async_hw_imports] +from google.cloud import bigtable +from google.cloud.bigtable.data import row_filters + +from ..utils import wait_for_table + +# [END bigtable_async_hw_imports] + +# use to ignore warnings +row_filters + + +async def main(project_id, instance_id, table_id): + # [START bigtable_async_hw_connect] + client = bigtable.data.BigtableDataClientAsync(project=project_id) + table = client.get_table(instance_id, table_id) + # [END bigtable_async_hw_connect] + + # [START bigtable_async_hw_create_table] + from google.cloud.bigtable import column_family + + # the async client only supports the data API. Table creation as an admin operation + # use admin client to create the table + print("Creating the {} table.".format(table_id)) + admin_client = bigtable.Client(project=project_id, admin=True) + admin_instance = admin_client.instance(instance_id) + admin_table = admin_instance.table(table_id) + + print("Creating column family cf1 with Max Version GC rule...") + # Create a column family with GC policy : most recent N versions + # Define the GC policy to retain only the most recent 2 versions + max_versions_rule = column_family.MaxVersionsGCRule(2) + column_family_id = b"cf1" + column_families = {column_family_id: max_versions_rule} + if not admin_table.exists(): + admin_table.create(column_families=column_families) + else: + print("Table {} already exists.".format(table_id)) + # [END bigtable_async_hw_create_table] + + try: + # let table creation complete + wait_for_table(admin_table) + # [START bigtable_async_hw_write_rows] + print("Writing some greetings to the table.") + greetings = [b"Hello World!", b"Hello Cloud Bigtable!", b"Hello Python!"] + mutations = [] + column = b"greeting" + for i, value in enumerate(greetings): + # Note: This example uses sequential numeric IDs for simplicity, + # but this can result in poor performance in a production + # application. Since rows are stored in sorted order by key, + # sequential keys can result in poor distribution of operations + # across nodes. + # + # We recommend that you use bytestrings directly for row keys + # where possible, rather than encoding strings. + # + # For more information about how to design a Bigtable schema for + # the best performance, see the documentation: + # + # https://cloud.google.com/bigtable/docs/schema-design + row_key = f"greeting{i}".encode() + row_mutation = bigtable.data.RowMutationEntry( + row_key, bigtable.data.SetCell(column_family_id, column, value) + ) + mutations.append(row_mutation) + await table.bulk_mutate_rows(mutations) + # [END bigtable_async_hw_write_rows] + + # [START bigtable_async_hw_create_filter] + # Create a filter to only retrieve the most recent version of the cell + # for each column across entire row. + row_filter = bigtable.data.row_filters.CellsColumnLimitFilter(1) + # [END bigtable_async_hw_create_filter] + + # [START bigtable_async_hw_get_with_filter] + # [START bigtable_async_hw_get_by_key] + print("Getting a single greeting by row key.") + key = "greeting0".encode() + + row = await table.read_row(key, row_filter=row_filter) + cell = row.cells[0] + print(cell.value.decode("utf-8")) + # [END bigtable_async_hw_get_by_key] + # [END bigtable_async_hw_get_with_filter] + + # [START bigtable_async_hw_scan_with_filter] + # [START bigtable_async_hw_scan_all] + print("Scanning for all greetings:") + query = bigtable.data.ReadRowsQuery(row_filter=row_filter) + async for row in await table.read_rows_stream(query): + cell = row.cells[0] + print(cell.value.decode("utf-8")) + # [END bigtable_async_hw_scan_all] + # [END bigtable_async_hw_scan_with_filter] + finally: + # [START bigtable_async_hw_delete_table] + # the async client only supports the data API. Table deletion as an admin operation + # use admin client to create the table + print("Deleting the {} table.".format(table_id)) + admin_table.delete() + # [END bigtable_async_hw_delete_table] + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description=__doc__, formatter_class=argparse.ArgumentDefaultsHelpFormatter + ) + parser.add_argument("project_id", help="Your Cloud Platform project ID.") + parser.add_argument( + "instance_id", help="ID of the Cloud Bigtable instance to connect to." + ) + parser.add_argument( + "--table", help="Table to create and destroy.", default="Hello-Bigtable" + ) + + args = parser.parse_args() + asyncio.run(main(args.project_id, args.instance_id, args.table)) diff --git a/packages/google-cloud-bigtable/samples/hello/async_main_test.py b/packages/google-cloud-bigtable/samples/hello/async_main_test.py new file mode 100644 index 000000000000..4f09d01e5630 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/hello/async_main_test.py @@ -0,0 +1,36 @@ +# Copyright 2024 Google Inc. +# +# 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 asyncio +import os +import uuid + +from .async_main import main + +PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"] +BIGTABLE_INSTANCE = os.environ["BIGTABLE_INSTANCE"] +TABLE_ID = f"hello-world-test-async-{str(uuid.uuid4())[:16]}" + + +def test_async_main(capsys): + asyncio.run(main(PROJECT, BIGTABLE_INSTANCE, TABLE_ID)) + + out, _ = capsys.readouterr() + assert "Creating the {} table.".format(TABLE_ID) in out + assert "Writing some greetings to the table." in out + assert "Getting a single greeting by row key." in out + assert "Hello World!" in out + assert "Scanning for all greetings" in out + assert "Hello Cloud Bigtable!" in out + assert "Deleting the {} table.".format(TABLE_ID) in out diff --git a/packages/google-cloud-bigtable/samples/hello/main.py b/packages/google-cloud-bigtable/samples/hello/main.py new file mode 100644 index 000000000000..13899a87425b --- /dev/null +++ b/packages/google-cloud-bigtable/samples/hello/main.py @@ -0,0 +1,152 @@ +#!/usr/bin/env python + +# Copyright 2016 Google Inc. +# +# 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. + +"""Demonstrates how to connect to Cloud Bigtable and run some basic operations. + +Prerequisites: + +- Create a Cloud Bigtable instance. + https://cloud.google.com/bigtable/docs/creating-instance +- Set your Google Application Default Credentials. + https://developers.google.com/identity/protocols/application-default-credentials +""" + +import argparse + +# [START bigtable_hw_imports] +from datetime import datetime, timezone + +from google.cloud import bigtable +from google.cloud.bigtable import column_family, row_filters + +from ..utils import wait_for_table + +# [END bigtable_hw_imports] + +# use to avoid warnings +row_filters +column_family + + +def main(project_id, instance_id, table_id): + # [START bigtable_hw_connect] + # The client must be created with admin=True because it will create a + # table. + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + # [END bigtable_hw_connect] + + # [START bigtable_hw_create_table] + print("Creating the {} table.".format(table_id)) + table = instance.table(table_id) + + print("Creating column family cf1 with Max Version GC rule...") + # Create a column family with GC policy : most recent N versions + # Define the GC policy to retain only the most recent 2 versions + max_versions_rule = bigtable.column_family.MaxVersionsGCRule(2) + column_family_id = b"cf1" + column_families = {column_family_id: max_versions_rule} + if not table.exists(): + table.create(column_families=column_families) + else: + print("Table {} already exists.".format(table_id)) + # [END bigtable_hw_create_table] + + try: + # let table creation complete + wait_for_table(table) + + # [START bigtable_hw_write_rows] + print("Writing some greetings to the table.") + greetings = [b"Hello World!", b"Hello Cloud Bigtable!", b"Hello Python!"] + rows = [] + column = b"greeting" + for i, value in enumerate(greetings): + # Note: This example uses sequential numeric IDs for simplicity, + # but this can result in poor performance in a production + # application. Since rows are stored in sorted order by key, + # sequential keys can result in poor distribution of operations + # across nodes. + # + # We recommend that you use bytestrings directly for row keys + # where possible, rather than encoding strings. + # + # For more information about how to design a Bigtable schema for + # the best performance, see the documentation: + # + # https://cloud.google.com/bigtable/docs/schema-design + row_key = f"greeting{i}".encode() + row = table.direct_row(row_key) + row.set_cell( + column_family_id, + column, + value, + timestamp=datetime.now(timezone.utc), + ) + rows.append(row) + table.mutate_rows(rows) + # [END bigtable_hw_write_rows] + + # [START bigtable_hw_create_filter] + # Create a filter to only retrieve the most recent version of the cell + # for each column across entire row. + row_filter = bigtable.row_filters.CellsColumnLimitFilter(1) + # [END bigtable_hw_create_filter] + + # [START bigtable_hw_get_with_filter] + # [START bigtable_hw_get_by_key] + print("Getting a single greeting by row key.") + key = b"greeting0" + + row = table.read_row(key, row_filter) + cell = row.cells[column_family_id.decode("utf-8")][column][0] + print(cell.value.decode("utf-8")) + # [END bigtable_hw_get_by_key] + # [END bigtable_hw_get_with_filter] + + # [START bigtable_hw_scan_with_filter] + # [START bigtable_hw_scan_all] + print("Scanning for all greetings:") + partial_rows = table.read_rows(filter_=row_filter) + + for row in partial_rows: + column_family_id_str = column_family_id.decode("utf-8") + cell = row.cells[column_family_id_str][column][0] + print(cell.value.decode("utf-8")) + # [END bigtable_hw_scan_all] + # [END bigtable_hw_scan_with_filter] + + finally: + # [START bigtable_hw_delete_table] + print("Deleting the {} table.".format(table_id)) + table.delete() + # [END bigtable_hw_delete_table] + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description=__doc__, formatter_class=argparse.ArgumentDefaultsHelpFormatter + ) + parser.add_argument("project_id", help="Your Cloud Platform project ID.") + parser.add_argument( + "instance_id", help="ID of the Cloud Bigtable instance to connect to." + ) + parser.add_argument( + "--table", help="Table to create and destroy.", default="Hello-Bigtable" + ) + + args = parser.parse_args() + main(args.project_id, args.instance_id, args.table) diff --git a/packages/google-cloud-bigtable/samples/hello/main_test.py b/packages/google-cloud-bigtable/samples/hello/main_test.py new file mode 100644 index 000000000000..28814d909d2c --- /dev/null +++ b/packages/google-cloud-bigtable/samples/hello/main_test.py @@ -0,0 +1,35 @@ +# Copyright 2016 Google Inc. +# +# 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 uuid + +from .main import main + +PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"] +BIGTABLE_INSTANCE = os.environ["BIGTABLE_INSTANCE"] +TABLE_ID = f"hello-world-test-{str(uuid.uuid4())[:16]}" + + +def test_main(capsys): + main(PROJECT, BIGTABLE_INSTANCE, TABLE_ID) + + out, _ = capsys.readouterr() + assert "Creating the {} table.".format(TABLE_ID) in out + assert "Writing some greetings to the table." in out + assert "Getting a single greeting by row key." in out + assert "Hello World!" in out + assert "Scanning for all greetings" in out + assert "Hello Cloud Bigtable!" in out + assert "Deleting the {} table.".format(TABLE_ID) in out diff --git a/packages/google-cloud-bigtable/samples/hello/noxfile.py b/packages/google-cloud-bigtable/samples/hello/noxfile.py new file mode 100644 index 000000000000..c0e60097b353 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/hello/noxfile.py @@ -0,0 +1,292 @@ +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import print_function + +import glob +import os +import sys +from pathlib import Path +from typing import Callable, Dict, Optional + +import nox + +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING +# DO NOT EDIT THIS FILE EVER! +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING + +BLACK_VERSION = "black==22.3.0" +ISORT_VERSION = "isort==5.10.1" + +# Copy `noxfile_config.py` to your directory and modify it instead. + +# `TEST_CONFIG` dict is a configuration hook that allows users to +# modify the test configurations. The values here should be in sync +# with `noxfile_config.py`. Users will copy `noxfile_config.py` into +# their directory and modify it. + +TEST_CONFIG = { + # You can opt out from the test for specific Python versions. + "ignored_versions": [], + # Old samples are opted out of enforcing Python type hints + # All new samples should feature them + "enforce_type_hints": False, + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", + # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + # If you need to use a specific version of pip, + # change pip_version_override to the string representation + # of the version number, for example, "20.2.4" + "pip_version_override": None, + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + "envs": {}, +} + + +try: + # Ensure we can import noxfile_config in the project's directory. + sys.path.append(".") + from noxfile_config import TEST_CONFIG_OVERRIDE +except ImportError as e: + print("No user noxfile_config found: detail: {}".format(e)) + TEST_CONFIG_OVERRIDE = {} + +# Update the TEST_CONFIG with the user supplied values. +TEST_CONFIG.update(TEST_CONFIG_OVERRIDE) + + +def get_pytest_env_vars() -> Dict[str, str]: + """Returns a dict for pytest invocation.""" + ret = {} + + # Override the GCLOUD_PROJECT and the alias. + env_key = TEST_CONFIG["gcloud_project_env"] + # This should error out if not set. + ret["GOOGLE_CLOUD_PROJECT"] = os.environ[env_key] + + # Apply user supplied envs. + ret.update(TEST_CONFIG["envs"]) + return ret + + +# DO NOT EDIT - automatically generated. +# All versions used to test samples. +ALL_VERSIONS = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + +# Any default versions that should be ignored. +IGNORED_VERSIONS = TEST_CONFIG["ignored_versions"] + +TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) + +INSTALL_LIBRARY_FROM_SOURCE = os.environ.get("INSTALL_LIBRARY_FROM_SOURCE", False) in ( + "True", + "true", +) + +# Error if a python version is missing +nox.options.error_on_missing_interpreters = True + +# +# Style Checks +# + + +# Linting with flake8. +# +# We ignore the following rules: +# E203: whitespace before ‘:’ +# E266: too many leading ‘#’ for block comment +# E501: line too long +# I202: Additional newline in a section of imports +# +# We also need to specify the rules which are ignored by default: +# ['E226', 'W504', 'E126', 'E123', 'W503', 'E24', 'E704', 'E121'] +FLAKE8_COMMON_ARGS = [ + "--show-source", + "--builtin=gettext", + "--max-complexity=20", + "--exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py", + "--ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202", + "--max-line-length=88", +] + + +@nox.session +def lint(session: nox.sessions.Session) -> None: + if not TEST_CONFIG["enforce_type_hints"]: + session.install("flake8") + else: + session.install("flake8", "flake8-annotations") + + args = FLAKE8_COMMON_ARGS + [ + ".", + ] + session.run("flake8", *args) + + +# +# Black +# + + +@nox.session +def blacken(session: nox.sessions.Session) -> None: + """Run black. Format code to uniform standard.""" + session.install(BLACK_VERSION) + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + session.run("black", *python_files) + + +# +# format = isort + black +# + + +@nox.session +def format(session: nox.sessions.Session) -> None: + """ + Run isort to sort imports. Then run black + to format code to uniform standard. + """ + session.install(BLACK_VERSION, ISORT_VERSION) + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + # Use the --fss option to sort imports using strict alphabetical order. + # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + session.run("isort", "--fss", *python_files) + session.run("black", *python_files) + + +# +# Sample Tests +# + + +PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] + + +def _session_tests( + session: nox.sessions.Session, post_install: Callable = None +) -> None: + # check for presence of tests + test_list = glob.glob("**/*_test.py", recursive=True) + glob.glob( + "**/test_*.py", recursive=True + ) + test_list.extend(glob.glob("**/tests", recursive=True)) + + if len(test_list) == 0: + print("No tests found, skipping directory.") + return + + if TEST_CONFIG["pip_version_override"]: + pip_version = TEST_CONFIG["pip_version_override"] + session.install(f"pip=={pip_version}") + """Runs py.test for a particular project.""" + concurrent_args = [] + if os.path.exists("requirements.txt"): + if os.path.exists("constraints.txt"): + session.install("-r", "requirements.txt", "-c", "constraints.txt") + else: + session.install("-r", "requirements.txt") + with open("requirements.txt") as rfile: + packages = rfile.read() + + if os.path.exists("requirements-test.txt"): + if os.path.exists("constraints-test.txt"): + session.install("-r", "requirements-test.txt", "-c", "constraints-test.txt") + else: + session.install("-r", "requirements-test.txt") + with open("requirements-test.txt") as rtfile: + packages += rtfile.read() + + if INSTALL_LIBRARY_FROM_SOURCE: + session.install("-e", _get_repo_root()) + + if post_install: + post_install(session) + + if "pytest-parallel" in packages: + concurrent_args.extend(["--workers", "auto", "--tests-per-worker", "auto"]) + elif "pytest-xdist" in packages: + concurrent_args.extend(["-n", "auto"]) + + session.run( + "pytest", + *(PYTEST_COMMON_ARGS + session.posargs + concurrent_args), + # Pytest will return 5 when no tests are collected. This can happen + # on travis where slow and flaky tests are excluded. + # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html + success_codes=[0, 5], + env=get_pytest_env_vars(), + ) + + +@nox.session(python=ALL_VERSIONS) +def py(session: nox.sessions.Session) -> None: + """Runs py.test for a sample using the specified version of Python.""" + if session.python in TESTED_VERSIONS: + _session_tests(session) + else: + session.skip( + "SKIPPED: {} tests are disabled for this sample.".format(session.python) + ) + + +# +# Readmegen +# + + +def _get_repo_root() -> Optional[str]: + """Returns the root folder of the project.""" + # Get root of this repository. Assume we don't have directories nested deeper than 10 items. + p = Path(os.getcwd()) + for i in range(10): + if p is None: + break + if Path(p / ".git").exists(): + return str(p) + # .git is not available in repos cloned via Cloud Build + # setup.py is always in the library's root, so use that instead + # https://github.com/googleapis/synthtool/issues/792 + if Path(p / "setup.py").exists(): + return str(p) + p = p.parent + raise Exception("Unable to detect repository root.") + + +GENERATED_READMES = sorted([x for x in Path(".").rglob("*.rst.in")]) + + +@nox.session +@nox.parametrize("path", GENERATED_READMES) +def readmegen(session: nox.sessions.Session, path: str) -> None: + """(Re-)generates the readme for a sample.""" + session.install("jinja2", "pyyaml") + dir_ = os.path.dirname(path) + + if os.path.exists(os.path.join(dir_, "requirements.txt")): + session.install("-r", os.path.join(dir_, "requirements.txt")) + + in_file = os.path.join(dir_, "README.rst.in") + session.run( + "python", _get_repo_root() + "/scripts/readme-gen/readme_gen.py", in_file + ) diff --git a/packages/google-cloud-bigtable/samples/hello/requirements-test.txt b/packages/google-cloud-bigtable/samples/hello/requirements-test.txt new file mode 100644 index 000000000000..e079f8a6038d --- /dev/null +++ b/packages/google-cloud-bigtable/samples/hello/requirements-test.txt @@ -0,0 +1 @@ +pytest diff --git a/packages/google-cloud-bigtable/samples/hello/requirements.txt b/packages/google-cloud-bigtable/samples/hello/requirements.txt new file mode 100644 index 000000000000..5113ca7f17bb --- /dev/null +++ b/packages/google-cloud-bigtable/samples/hello/requirements.txt @@ -0,0 +1,2 @@ +google-cloud-bigtable==2.35.0 +google-cloud-core==2.5.0 diff --git a/packages/google-cloud-bigtable/samples/hello_happybase/README.md b/packages/google-cloud-bigtable/samples/hello_happybase/README.md new file mode 100644 index 000000000000..fdbea4e63739 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/hello_happybase/README.md @@ -0,0 +1,52 @@ +[//]: # "This README.md file is auto-generated, all changes to this file will be lost." +[//]: # "To regenerate it, use `python -m synthtool`." + +## Python Samples for Cloud Bigtable + +This directory contains samples for Cloud Bigtable, which may be used as a refererence for how to use this product. +Samples, quickstarts, and other documentation are available at cloud.google.com. + + +### Hello World using HappyBase + +This sample demonstrates using the Google Cloud Client Library HappyBase package, an implementation of the HappyBase API to connect to and interact with Cloud Bigtable. More information available at: https://cloud.google.com/bigtable/docs/samples-python-hello-happybase + + +Open in Cloud Shell + + +To run this sample: + +1. If this is your first time working with GCP products, you will need to set up [the Cloud SDK][cloud_sdk] or utilize [Google Cloud Shell][gcloud_shell]. This sample may [require authetication][authentication] and you will need to [enable billing][enable_billing]. + +1. Make a fork of this repo and clone the branch locally, then navigate to the sample directory you want to use. + +1. Install the dependencies needed to run the samples. + + pip install -r requirements.txt + +1. Run the sample using + + python main.py + + + +
usage: main.py [-h] [--table TABLE] project_id instance_id
Demonstrates how to connect to Cloud Bigtable and run some basic operations.
Prerequisites: - Create a Cloud Bigtable cluster.
https://cloud.google.com/bigtable/docs/creating-cluster - Set your Google
Application Default Credentials.
https://developers.google.com/identity/protocols/application-default-
credentials


positional arguments:
  project_id     Your Cloud Platform project ID.
  instance_id    ID of the Cloud Bigtable instance to connect to.


optional arguments:
  -h, --help     show this help message and exit
  --table TABLE  Table to create and destroy. (default: Hello-Bigtable)
+ +## Additional Information + +You can read the documentation for more details on API usage and use GitHub +to browse the source and [report issues][issues]. + +### Contributing +View the [contributing guidelines][contrib_guide], the [Python style guide][py_style] for more information. + +[authentication]: https://cloud.google.com/docs/authentication/getting-started +[enable_billing]:https://cloud.google.com/apis/docs/getting-started#enabling_billing +[client_library_python]: https://googlecloudplatform.github.io/google-cloud-python/ +[issues]: https://github.com/GoogleCloudPlatform/google-cloud-python/issues +[contrib_guide]: https://github.com/googleapis/google-cloud-python/blob/main/CONTRIBUTING.rst +[py_style]: http://google.github.io/styleguide/pyguide.html +[cloud_sdk]: https://cloud.google.com/sdk/docs +[gcloud_shell]: https://cloud.google.com/shell/docs +[gcloud_shell]: https://cloud.google.com/shell/docs diff --git a/packages/google-cloud-bigtable/samples/hello_happybase/__init__.py b/packages/google-cloud-bigtable/samples/hello_happybase/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-cloud-bigtable/samples/hello_happybase/main.py b/packages/google-cloud-bigtable/samples/hello_happybase/main.py new file mode 100644 index 000000000000..54099a1fa630 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/hello_happybase/main.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python + +# Copyright 2016 Google Inc. +# +# 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. + +"""Demonstrates how to connect to Cloud Bigtable and run some basic operations. + +Prerequisites: + +- Create a Cloud Bigtable cluster. + https://cloud.google.com/bigtable/docs/creating-cluster +- Set your Google Application Default Credentials. + https://developers.google.com/identity/protocols/application-default-credentials +""" + +import argparse + +# [START bigtable_hw_imports_happybase] +from google.cloud import bigtable, happybase + +from ..utils import wait_for_table + +# [END bigtable_hw_imports_happybase] + + +def main(project_id, instance_id, table_name): + # [START bigtable_hw_connect_happybase] + # The client must be created with admin=True because it will create a + # table. + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + connection = happybase.Connection(instance=instance) + # [END bigtable_hw_connect_happybase] + + try: + # [START bigtable_hw_create_table_happybase] + print("Creating the {} table.".format(table_name)) + column_family_name = "cf1" + connection.create_table( + table_name, + {column_family_name: dict()}, # Use default options. + ) + # [END bigtable_hw_create_table_happybase] + + wait_for_table(instance.table(table_name)) + + # [START bigtable_hw_write_rows_happybase] + print("Writing some greetings to the table.") + table = connection.table(table_name) + column_name = "{fam}:greeting".format(fam=column_family_name) + greetings = [ + "Hello World!", + "Hello Cloud Bigtable!", + "Hello HappyBase!", + ] + + for i, value in enumerate(greetings): + # Note: This example uses sequential numeric IDs for simplicity, + # but this can result in poor performance in a production + # application. Since rows are stored in sorted order by key, + # sequential keys can result in poor distribution of operations + # across nodes. + # + # For more information about how to design a Bigtable schema for + # the best performance, see the documentation: + # + # https://cloud.google.com/bigtable/docs/schema-design + row_key = "greeting{}".format(i) + table.put(row_key, {column_name.encode("utf-8"): value.encode("utf-8")}) + # [END bigtable_hw_write_rows_happybase] + + # [START bigtable_hw_get_by_key_happybase] + print("Getting a single greeting by row key.") + key = "greeting0".encode("utf-8") + row = table.row(key) + print("\t{}: {}".format(key, row[column_name.encode("utf-8")])) + # [END bigtable_hw_get_by_key_happybase] + + # [START bigtable_hw_scan_all_happybase] + print("Scanning for all greetings:") + + for key, row in table.scan(): + print("\t{}: {}".format(key, row[column_name.encode("utf-8")])) + # [END bigtable_hw_scan_all_happybase] + + finally: + # [START bigtable_hw_delete_table_happybase] + print("Deleting the {} table.".format(table_name)) + connection.delete_table(table_name) + # [END bigtable_hw_delete_table_happybase] + connection.close() + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description=__doc__, formatter_class=argparse.ArgumentDefaultsHelpFormatter + ) + parser.add_argument("project_id", help="Your Cloud Platform project ID.") + parser.add_argument( + "instance_id", help="ID of the Cloud Bigtable instance to connect to." + ) + parser.add_argument( + "--table", help="Table to create and destroy.", default="Hello-Bigtable" + ) + + args = parser.parse_args() + main(args.project_id, args.instance_id, args.table) diff --git a/packages/google-cloud-bigtable/samples/hello_happybase/main_test.py b/packages/google-cloud-bigtable/samples/hello_happybase/main_test.py new file mode 100644 index 000000000000..b7c5ceea8ad9 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/hello_happybase/main_test.py @@ -0,0 +1,45 @@ +# Copyright 2016 Google Inc. +# +# 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 uuid + +from google.cloud import bigtable + +from .main import main + +PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"] +BIGTABLE_INSTANCE = os.environ["BIGTABLE_INSTANCE"] +TABLE_ID = f"hello-world-hb-test-{str(uuid.uuid4())[:16]}" + + +def test_main(capsys): + try: + main(PROJECT, BIGTABLE_INSTANCE, TABLE_ID) + + out, _ = capsys.readouterr() + assert "Creating the {} table.".format(TABLE_ID) in out + assert "Writing some greetings to the table." in out + assert "Getting a single greeting by row key." in out + assert "Hello World!" in out + assert "Scanning for all greetings" in out + assert "Hello Cloud Bigtable!" in out + assert "Deleting the {} table.".format(TABLE_ID) in out + finally: + # delete table + client = bigtable.Client(PROJECT, admin=True) + instance = client.instance(BIGTABLE_INSTANCE) + table = instance.table(TABLE_ID) + if table.exists(): + table.delete() diff --git a/packages/google-cloud-bigtable/samples/hello_happybase/noxfile.py b/packages/google-cloud-bigtable/samples/hello_happybase/noxfile.py new file mode 100644 index 000000000000..c0e60097b353 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/hello_happybase/noxfile.py @@ -0,0 +1,292 @@ +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import print_function + +import glob +import os +import sys +from pathlib import Path +from typing import Callable, Dict, Optional + +import nox + +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING +# DO NOT EDIT THIS FILE EVER! +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING + +BLACK_VERSION = "black==22.3.0" +ISORT_VERSION = "isort==5.10.1" + +# Copy `noxfile_config.py` to your directory and modify it instead. + +# `TEST_CONFIG` dict is a configuration hook that allows users to +# modify the test configurations. The values here should be in sync +# with `noxfile_config.py`. Users will copy `noxfile_config.py` into +# their directory and modify it. + +TEST_CONFIG = { + # You can opt out from the test for specific Python versions. + "ignored_versions": [], + # Old samples are opted out of enforcing Python type hints + # All new samples should feature them + "enforce_type_hints": False, + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", + # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + # If you need to use a specific version of pip, + # change pip_version_override to the string representation + # of the version number, for example, "20.2.4" + "pip_version_override": None, + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + "envs": {}, +} + + +try: + # Ensure we can import noxfile_config in the project's directory. + sys.path.append(".") + from noxfile_config import TEST_CONFIG_OVERRIDE +except ImportError as e: + print("No user noxfile_config found: detail: {}".format(e)) + TEST_CONFIG_OVERRIDE = {} + +# Update the TEST_CONFIG with the user supplied values. +TEST_CONFIG.update(TEST_CONFIG_OVERRIDE) + + +def get_pytest_env_vars() -> Dict[str, str]: + """Returns a dict for pytest invocation.""" + ret = {} + + # Override the GCLOUD_PROJECT and the alias. + env_key = TEST_CONFIG["gcloud_project_env"] + # This should error out if not set. + ret["GOOGLE_CLOUD_PROJECT"] = os.environ[env_key] + + # Apply user supplied envs. + ret.update(TEST_CONFIG["envs"]) + return ret + + +# DO NOT EDIT - automatically generated. +# All versions used to test samples. +ALL_VERSIONS = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + +# Any default versions that should be ignored. +IGNORED_VERSIONS = TEST_CONFIG["ignored_versions"] + +TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) + +INSTALL_LIBRARY_FROM_SOURCE = os.environ.get("INSTALL_LIBRARY_FROM_SOURCE", False) in ( + "True", + "true", +) + +# Error if a python version is missing +nox.options.error_on_missing_interpreters = True + +# +# Style Checks +# + + +# Linting with flake8. +# +# We ignore the following rules: +# E203: whitespace before ‘:’ +# E266: too many leading ‘#’ for block comment +# E501: line too long +# I202: Additional newline in a section of imports +# +# We also need to specify the rules which are ignored by default: +# ['E226', 'W504', 'E126', 'E123', 'W503', 'E24', 'E704', 'E121'] +FLAKE8_COMMON_ARGS = [ + "--show-source", + "--builtin=gettext", + "--max-complexity=20", + "--exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py", + "--ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202", + "--max-line-length=88", +] + + +@nox.session +def lint(session: nox.sessions.Session) -> None: + if not TEST_CONFIG["enforce_type_hints"]: + session.install("flake8") + else: + session.install("flake8", "flake8-annotations") + + args = FLAKE8_COMMON_ARGS + [ + ".", + ] + session.run("flake8", *args) + + +# +# Black +# + + +@nox.session +def blacken(session: nox.sessions.Session) -> None: + """Run black. Format code to uniform standard.""" + session.install(BLACK_VERSION) + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + session.run("black", *python_files) + + +# +# format = isort + black +# + + +@nox.session +def format(session: nox.sessions.Session) -> None: + """ + Run isort to sort imports. Then run black + to format code to uniform standard. + """ + session.install(BLACK_VERSION, ISORT_VERSION) + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + # Use the --fss option to sort imports using strict alphabetical order. + # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + session.run("isort", "--fss", *python_files) + session.run("black", *python_files) + + +# +# Sample Tests +# + + +PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] + + +def _session_tests( + session: nox.sessions.Session, post_install: Callable = None +) -> None: + # check for presence of tests + test_list = glob.glob("**/*_test.py", recursive=True) + glob.glob( + "**/test_*.py", recursive=True + ) + test_list.extend(glob.glob("**/tests", recursive=True)) + + if len(test_list) == 0: + print("No tests found, skipping directory.") + return + + if TEST_CONFIG["pip_version_override"]: + pip_version = TEST_CONFIG["pip_version_override"] + session.install(f"pip=={pip_version}") + """Runs py.test for a particular project.""" + concurrent_args = [] + if os.path.exists("requirements.txt"): + if os.path.exists("constraints.txt"): + session.install("-r", "requirements.txt", "-c", "constraints.txt") + else: + session.install("-r", "requirements.txt") + with open("requirements.txt") as rfile: + packages = rfile.read() + + if os.path.exists("requirements-test.txt"): + if os.path.exists("constraints-test.txt"): + session.install("-r", "requirements-test.txt", "-c", "constraints-test.txt") + else: + session.install("-r", "requirements-test.txt") + with open("requirements-test.txt") as rtfile: + packages += rtfile.read() + + if INSTALL_LIBRARY_FROM_SOURCE: + session.install("-e", _get_repo_root()) + + if post_install: + post_install(session) + + if "pytest-parallel" in packages: + concurrent_args.extend(["--workers", "auto", "--tests-per-worker", "auto"]) + elif "pytest-xdist" in packages: + concurrent_args.extend(["-n", "auto"]) + + session.run( + "pytest", + *(PYTEST_COMMON_ARGS + session.posargs + concurrent_args), + # Pytest will return 5 when no tests are collected. This can happen + # on travis where slow and flaky tests are excluded. + # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html + success_codes=[0, 5], + env=get_pytest_env_vars(), + ) + + +@nox.session(python=ALL_VERSIONS) +def py(session: nox.sessions.Session) -> None: + """Runs py.test for a sample using the specified version of Python.""" + if session.python in TESTED_VERSIONS: + _session_tests(session) + else: + session.skip( + "SKIPPED: {} tests are disabled for this sample.".format(session.python) + ) + + +# +# Readmegen +# + + +def _get_repo_root() -> Optional[str]: + """Returns the root folder of the project.""" + # Get root of this repository. Assume we don't have directories nested deeper than 10 items. + p = Path(os.getcwd()) + for i in range(10): + if p is None: + break + if Path(p / ".git").exists(): + return str(p) + # .git is not available in repos cloned via Cloud Build + # setup.py is always in the library's root, so use that instead + # https://github.com/googleapis/synthtool/issues/792 + if Path(p / "setup.py").exists(): + return str(p) + p = p.parent + raise Exception("Unable to detect repository root.") + + +GENERATED_READMES = sorted([x for x in Path(".").rglob("*.rst.in")]) + + +@nox.session +@nox.parametrize("path", GENERATED_READMES) +def readmegen(session: nox.sessions.Session, path: str) -> None: + """(Re-)generates the readme for a sample.""" + session.install("jinja2", "pyyaml") + dir_ = os.path.dirname(path) + + if os.path.exists(os.path.join(dir_, "requirements.txt")): + session.install("-r", os.path.join(dir_, "requirements.txt")) + + in_file = os.path.join(dir_, "README.rst.in") + session.run( + "python", _get_repo_root() + "/scripts/readme-gen/readme_gen.py", in_file + ) diff --git a/packages/google-cloud-bigtable/samples/hello_happybase/requirements-test.txt b/packages/google-cloud-bigtable/samples/hello_happybase/requirements-test.txt new file mode 100644 index 000000000000..e079f8a6038d --- /dev/null +++ b/packages/google-cloud-bigtable/samples/hello_happybase/requirements-test.txt @@ -0,0 +1 @@ +pytest diff --git a/packages/google-cloud-bigtable/samples/hello_happybase/requirements.txt b/packages/google-cloud-bigtable/samples/hello_happybase/requirements.txt new file mode 100644 index 000000000000..dc1a04f30378 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/hello_happybase/requirements.txt @@ -0,0 +1,2 @@ +google-cloud-happybase==0.33.0 +six==1.17.0 # See https://github.com/googleapis/google-cloud-python-happybase/issues/128 diff --git a/packages/google-cloud-bigtable/samples/instanceadmin/README.md b/packages/google-cloud-bigtable/samples/instanceadmin/README.md new file mode 100644 index 000000000000..675add700e93 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/instanceadmin/README.md @@ -0,0 +1,52 @@ +[//]: # "This README.md file is auto-generated, all changes to this file will be lost." +[//]: # "To regenerate it, use `python -m synthtool`." + +## Python Samples for Cloud Bigtable + +This directory contains samples for Cloud Bigtable, which may be used as a refererence for how to use this product. +Samples, quickstarts, and other documentation are available at cloud.google.com. + + +### cbt Command Demonstration + +This page explains how to use the cbt command to connect to a Cloud Bigtable instance, perform basic administrative tasks, and read and write data in a table. More information about this quickstart is available at https://cloud.google.com/bigtable/docs/quickstart-cbt + + +Open in Cloud Shell + + +To run this sample: + +1. If this is your first time working with GCP products, you will need to set up [the Cloud SDK][cloud_sdk] or utilize [Google Cloud Shell][gcloud_shell]. This sample may [require authetication][authentication] and you will need to [enable billing][enable_billing]. + +1. Make a fork of this repo and clone the branch locally, then navigate to the sample directory you want to use. + +1. Install the dependencies needed to run the samples. + + pip install -r requirements.txt + +1. Run the sample using + + python instanceadmin.py + + + +
usage: instanceadmin.py [-h] [run] [dev-instance] [del-instance] [add-cluster] [del-cluster] project_id instance_id cluster_id
Demonstrates how to connect to Cloud Bigtable and run some basic operations.
Prerequisites: - Create a Cloud Bigtable cluster.
https://cloud.google.com/bigtable/docs/creating-cluster - Set your Google
Application Default Credentials.
https://developers.google.com/identity/protocols/application-default-
credentials


positional arguments:
  project_id     Your Cloud Platform project ID.
  instance_id    ID of the Cloud Bigtable instance to connect to.


optional arguments:
  -h, --help     show this help message and exit
  --table TABLE  Table to create and destroy. (default: Hello-Bigtable)
+ +## Additional Information + +You can read the documentation for more details on API usage and use GitHub +to browse the source and [report issues][issues]. + +### Contributing +View the [contributing guidelines][contrib_guide], the [Python style guide][py_style] for more information. + +[authentication]: https://cloud.google.com/docs/authentication/getting-started +[enable_billing]:https://cloud.google.com/apis/docs/getting-started#enabling_billing +[client_library_python]: https://googlecloudplatform.github.io/google-cloud-python/ +[issues]: https://github.com/GoogleCloudPlatform/google-cloud-python/issues +[contrib_guide]: https://github.com/googleapis/google-cloud-python/blob/main/CONTRIBUTING.rst +[py_style]: http://google.github.io/styleguide/pyguide.html +[cloud_sdk]: https://cloud.google.com/sdk/docs +[gcloud_shell]: https://cloud.google.com/shell/docs +[gcloud_shell]: https://cloud.google.com/shell/docs diff --git a/packages/google-cloud-bigtable/samples/instanceadmin/instanceadmin.py b/packages/google-cloud-bigtable/samples/instanceadmin/instanceadmin.py new file mode 100644 index 000000000000..7341bfc46f19 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/instanceadmin/instanceadmin.py @@ -0,0 +1,232 @@ +#!/usr/bin/env python + +# Copyright 2018, 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. + +"""Demonstrates how to connect to Cloud Bigtable and run some basic operations. +# http://www.apache.org/licenses/LICENSE-2.0 +Prerequisites: +- Create a Cloud Bigtable project. + https://cloud.google.com/bigtable/docs/ +- Set your Google Application Default Credentials. + https://developers.google.com/identity/protocols/application-default-credentials + +Operations performed: +- Create a Cloud Bigtable Instance. +- List Instance for a Cloud Bigtable. +- Delete a Cloud Bigtable Instance. +- Create a Cloud Bigtable Cluster. +- List Cloud Bigtable Clusters. +- Delete a Cloud Bigtable Cluster. +""" + +import argparse + +from google.cloud import bigtable +from google.cloud.bigtable import enums + + +def run_instance_operations(project_id, instance_id, cluster_id): + """Check Instance exists. + Creates a Production instance with default Cluster. + List instances in a project. + List clusters in an instance. + + :type project_id: str + :param project_id: Project id of the client. + + :type instance_id: str + :param instance_id: Instance of the client. + """ + client = bigtable.Client(project=project_id, admin=True) + location_id = "us-central1-f" + serve_nodes = 1 + storage_type = enums.StorageType.SSD + labels = {"prod-label": "prod-label"} + instance = client.instance(instance_id, labels=labels) + + # [START bigtable_check_instance_exists] + if not instance.exists(): + print("Instance {} does not exist.".format(instance_id)) + else: + print("Instance {} already exists.".format(instance_id)) + # [END bigtable_check_instance_exists] + + # [START bigtable_create_prod_instance] + cluster = instance.cluster( + cluster_id, + location_id=location_id, + serve_nodes=serve_nodes, + default_storage_type=storage_type, + ) + if not instance.exists(): + print("\nCreating an instance") + # Create instance with given options + operation = instance.create(clusters=[cluster]) + # Ensure the operation completes. + operation.result(timeout=480) + print("\nCreated instance: {}".format(instance_id)) + # [END bigtable_create_prod_instance] + + # [START bigtable_list_instances] + print("\nListing instances:") + for instance_local in client.list_instances()[0]: + print(instance_local.instance_id) + # [END bigtable_list_instances] + + # [START bigtable_get_instance] + print( + "\nName of instance: {}\nLabels: {}".format( + instance.display_name, instance.labels + ) + ) + # [END bigtable_get_instance] + + # [START bigtable_get_clusters] + print("\nListing clusters...") + for cluster in instance.list_clusters()[0]: + print(cluster.cluster_id) + # [END bigtable_get_clusters] + + +def delete_instance(project_id, instance_id): + """Delete the Instance + + :type project_id: str + :param project_id: Project id of the client. + + :type instance_id: str + :param instance_id: Instance of the client. + """ + + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + # [START bigtable_delete_instance] + print("\nDeleting instance") + if not instance.exists(): + print("Instance {} does not exist.".format(instance_id)) + else: + instance.delete() + print("Deleted instance: {}".format(instance_id)) + # [END bigtable_delete_instance] + + +def add_cluster(project_id, instance_id, cluster_id): + """Add Cluster + + :type project_id: str + :param project_id: Project id of the client. + + :type instance_id: str + :param instance_id: Instance of the client. + + :type cluster_id: str + :param cluster_id: Cluster id. + """ + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + + location_id = "us-central1-a" + serve_nodes = 1 + storage_type = enums.StorageType.SSD + + if not instance.exists(): + print("Instance {} does not exist.".format(instance_id)) + else: + print("\nAdding cluster to instance {}".format(instance_id)) + # [START bigtable_create_cluster] + print("\nListing clusters...") + for cluster in instance.list_clusters()[0]: + print(cluster.cluster_id) + cluster = instance.cluster( + cluster_id, + location_id=location_id, + serve_nodes=serve_nodes, + default_storage_type=storage_type, + ) + if cluster.exists(): + print("\nCluster not created, as {} already exists.".format(cluster_id)) + else: + operation = cluster.create() + # Ensure the operation completes. + operation.result(timeout=480) + print("\nCluster created: {}".format(cluster_id)) + # [END bigtable_create_cluster] + + +def delete_cluster(project_id, instance_id, cluster_id): + """Delete the cluster + + :type project_id: str + :param project_id: Project id of the client. + + :type instance_id: str + :param instance_id: Instance of the client. + + :type cluster_id: str + :param cluster_id: Cluster id. + """ + + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + cluster = instance.cluster(cluster_id) + + # [START bigtable_delete_cluster] + print("\nDeleting cluster") + if cluster.exists(): + cluster.delete() + print("Cluster deleted: {}".format(cluster_id)) + else: + print("\nCluster {} does not exist.".format(cluster_id)) + + # [END bigtable_delete_cluster] + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description=__doc__, formatter_class=argparse.ArgumentDefaultsHelpFormatter + ) + + parser.add_argument( + "command", + help="run, del-instance, \ + add-cluster or del-cluster. \ + Operation to perform on Instance.", + ) + parser.add_argument("project_id", help="Your Cloud Platform project ID.") + parser.add_argument( + "instance_id", + help="ID of the Cloud Bigtable instance to \ + connect to.", + ) + parser.add_argument( + "cluster_id", + help="ID of the Cloud Bigtable cluster to \ + connect to.", + ) + + args = parser.parse_args() + + if args.command.lower() == "run": + run_instance_operations(args.project_id, args.instance_id, args.cluster_id) + elif args.command.lower() == "del-instance": + delete_instance(args.project_id, args.instance_id) + elif args.command.lower() == "add-cluster": + add_cluster(args.project_id, args.instance_id, args.cluster_id) + elif args.command.lower() == "del-cluster": + delete_cluster(args.project_id, args.instance_id, args.cluster_id) + else: + print( + "Command should be either run \n Use argument -h, \ + --help to show help and exit." + ) diff --git a/packages/google-cloud-bigtable/samples/instanceadmin/noxfile.py b/packages/google-cloud-bigtable/samples/instanceadmin/noxfile.py new file mode 100644 index 000000000000..c0e60097b353 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/instanceadmin/noxfile.py @@ -0,0 +1,292 @@ +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import print_function + +import glob +import os +import sys +from pathlib import Path +from typing import Callable, Dict, Optional + +import nox + +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING +# DO NOT EDIT THIS FILE EVER! +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING + +BLACK_VERSION = "black==22.3.0" +ISORT_VERSION = "isort==5.10.1" + +# Copy `noxfile_config.py` to your directory and modify it instead. + +# `TEST_CONFIG` dict is a configuration hook that allows users to +# modify the test configurations. The values here should be in sync +# with `noxfile_config.py`. Users will copy `noxfile_config.py` into +# their directory and modify it. + +TEST_CONFIG = { + # You can opt out from the test for specific Python versions. + "ignored_versions": [], + # Old samples are opted out of enforcing Python type hints + # All new samples should feature them + "enforce_type_hints": False, + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", + # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + # If you need to use a specific version of pip, + # change pip_version_override to the string representation + # of the version number, for example, "20.2.4" + "pip_version_override": None, + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + "envs": {}, +} + + +try: + # Ensure we can import noxfile_config in the project's directory. + sys.path.append(".") + from noxfile_config import TEST_CONFIG_OVERRIDE +except ImportError as e: + print("No user noxfile_config found: detail: {}".format(e)) + TEST_CONFIG_OVERRIDE = {} + +# Update the TEST_CONFIG with the user supplied values. +TEST_CONFIG.update(TEST_CONFIG_OVERRIDE) + + +def get_pytest_env_vars() -> Dict[str, str]: + """Returns a dict for pytest invocation.""" + ret = {} + + # Override the GCLOUD_PROJECT and the alias. + env_key = TEST_CONFIG["gcloud_project_env"] + # This should error out if not set. + ret["GOOGLE_CLOUD_PROJECT"] = os.environ[env_key] + + # Apply user supplied envs. + ret.update(TEST_CONFIG["envs"]) + return ret + + +# DO NOT EDIT - automatically generated. +# All versions used to test samples. +ALL_VERSIONS = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + +# Any default versions that should be ignored. +IGNORED_VERSIONS = TEST_CONFIG["ignored_versions"] + +TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) + +INSTALL_LIBRARY_FROM_SOURCE = os.environ.get("INSTALL_LIBRARY_FROM_SOURCE", False) in ( + "True", + "true", +) + +# Error if a python version is missing +nox.options.error_on_missing_interpreters = True + +# +# Style Checks +# + + +# Linting with flake8. +# +# We ignore the following rules: +# E203: whitespace before ‘:’ +# E266: too many leading ‘#’ for block comment +# E501: line too long +# I202: Additional newline in a section of imports +# +# We also need to specify the rules which are ignored by default: +# ['E226', 'W504', 'E126', 'E123', 'W503', 'E24', 'E704', 'E121'] +FLAKE8_COMMON_ARGS = [ + "--show-source", + "--builtin=gettext", + "--max-complexity=20", + "--exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py", + "--ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202", + "--max-line-length=88", +] + + +@nox.session +def lint(session: nox.sessions.Session) -> None: + if not TEST_CONFIG["enforce_type_hints"]: + session.install("flake8") + else: + session.install("flake8", "flake8-annotations") + + args = FLAKE8_COMMON_ARGS + [ + ".", + ] + session.run("flake8", *args) + + +# +# Black +# + + +@nox.session +def blacken(session: nox.sessions.Session) -> None: + """Run black. Format code to uniform standard.""" + session.install(BLACK_VERSION) + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + session.run("black", *python_files) + + +# +# format = isort + black +# + + +@nox.session +def format(session: nox.sessions.Session) -> None: + """ + Run isort to sort imports. Then run black + to format code to uniform standard. + """ + session.install(BLACK_VERSION, ISORT_VERSION) + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + # Use the --fss option to sort imports using strict alphabetical order. + # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + session.run("isort", "--fss", *python_files) + session.run("black", *python_files) + + +# +# Sample Tests +# + + +PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] + + +def _session_tests( + session: nox.sessions.Session, post_install: Callable = None +) -> None: + # check for presence of tests + test_list = glob.glob("**/*_test.py", recursive=True) + glob.glob( + "**/test_*.py", recursive=True + ) + test_list.extend(glob.glob("**/tests", recursive=True)) + + if len(test_list) == 0: + print("No tests found, skipping directory.") + return + + if TEST_CONFIG["pip_version_override"]: + pip_version = TEST_CONFIG["pip_version_override"] + session.install(f"pip=={pip_version}") + """Runs py.test for a particular project.""" + concurrent_args = [] + if os.path.exists("requirements.txt"): + if os.path.exists("constraints.txt"): + session.install("-r", "requirements.txt", "-c", "constraints.txt") + else: + session.install("-r", "requirements.txt") + with open("requirements.txt") as rfile: + packages = rfile.read() + + if os.path.exists("requirements-test.txt"): + if os.path.exists("constraints-test.txt"): + session.install("-r", "requirements-test.txt", "-c", "constraints-test.txt") + else: + session.install("-r", "requirements-test.txt") + with open("requirements-test.txt") as rtfile: + packages += rtfile.read() + + if INSTALL_LIBRARY_FROM_SOURCE: + session.install("-e", _get_repo_root()) + + if post_install: + post_install(session) + + if "pytest-parallel" in packages: + concurrent_args.extend(["--workers", "auto", "--tests-per-worker", "auto"]) + elif "pytest-xdist" in packages: + concurrent_args.extend(["-n", "auto"]) + + session.run( + "pytest", + *(PYTEST_COMMON_ARGS + session.posargs + concurrent_args), + # Pytest will return 5 when no tests are collected. This can happen + # on travis where slow and flaky tests are excluded. + # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html + success_codes=[0, 5], + env=get_pytest_env_vars(), + ) + + +@nox.session(python=ALL_VERSIONS) +def py(session: nox.sessions.Session) -> None: + """Runs py.test for a sample using the specified version of Python.""" + if session.python in TESTED_VERSIONS: + _session_tests(session) + else: + session.skip( + "SKIPPED: {} tests are disabled for this sample.".format(session.python) + ) + + +# +# Readmegen +# + + +def _get_repo_root() -> Optional[str]: + """Returns the root folder of the project.""" + # Get root of this repository. Assume we don't have directories nested deeper than 10 items. + p = Path(os.getcwd()) + for i in range(10): + if p is None: + break + if Path(p / ".git").exists(): + return str(p) + # .git is not available in repos cloned via Cloud Build + # setup.py is always in the library's root, so use that instead + # https://github.com/googleapis/synthtool/issues/792 + if Path(p / "setup.py").exists(): + return str(p) + p = p.parent + raise Exception("Unable to detect repository root.") + + +GENERATED_READMES = sorted([x for x in Path(".").rglob("*.rst.in")]) + + +@nox.session +@nox.parametrize("path", GENERATED_READMES) +def readmegen(session: nox.sessions.Session, path: str) -> None: + """(Re-)generates the readme for a sample.""" + session.install("jinja2", "pyyaml") + dir_ = os.path.dirname(path) + + if os.path.exists(os.path.join(dir_, "requirements.txt")): + session.install("-r", os.path.join(dir_, "requirements.txt")) + + in_file = os.path.join(dir_, "README.rst.in") + session.run( + "python", _get_repo_root() + "/scripts/readme-gen/readme_gen.py", in_file + ) diff --git a/packages/google-cloud-bigtable/samples/instanceadmin/requirements-test.txt b/packages/google-cloud-bigtable/samples/instanceadmin/requirements-test.txt new file mode 100644 index 000000000000..e079f8a6038d --- /dev/null +++ b/packages/google-cloud-bigtable/samples/instanceadmin/requirements-test.txt @@ -0,0 +1 @@ +pytest diff --git a/packages/google-cloud-bigtable/samples/instanceadmin/requirements.txt b/packages/google-cloud-bigtable/samples/instanceadmin/requirements.txt new file mode 100644 index 000000000000..67a1ea5b8d23 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/instanceadmin/requirements.txt @@ -0,0 +1,2 @@ +google-cloud-bigtable==2.35.0 +backoff==2.2.1 diff --git a/packages/google-cloud-bigtable/samples/instanceadmin/test_instanceadmin.py b/packages/google-cloud-bigtable/samples/instanceadmin/test_instanceadmin.py new file mode 100644 index 000000000000..5d1378fcd946 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/instanceadmin/test_instanceadmin.py @@ -0,0 +1,179 @@ +# Copyright 2018 Google Inc. +# +# 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 random +import time +import warnings + +import backoff +import instanceadmin +import pytest +from google.api_core import exceptions + +from google.cloud import bigtable + +PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"] +INSTANCE_ID_FORMAT = "instanceadmin-{:03}-{}" +CLUSTER_ID_FORMAT = "instanceadmin-{:03}" +ID_RANGE = 1000 + +INSTANCE = INSTANCE_ID_FORMAT.format(random.randrange(ID_RANGE), int(time.time())) +CLUSTER1 = CLUSTER_ID_FORMAT.format(random.randrange(ID_RANGE)) +CLUSTER2 = CLUSTER_ID_FORMAT.format(random.randrange(ID_RANGE)) + + +@pytest.fixture(scope="module", autouse=True) +def preclean(): + """In case any test instances weren't cleared out in a previous run. + + Deletes any test instances that were created over an hour ago. Newer instances may + be being used by a concurrent test run. + """ + client = bigtable.Client(project=PROJECT, admin=True) + for instance in client.list_instances()[0]: + if instance.instance_id.startswith("instanceadmin-"): + timestamp = instance.instance_id.split("-")[-1] + timestamp = int(timestamp) + if time.time() - timestamp > 3600: + warnings.warn( + f"Deleting leftover test instance: {instance.instance_id}" + ) + instance.delete() + + +@pytest.fixture +def dispose_of(): + instances = [] + + def disposal(instance): + instances.append(instance) + + yield disposal + + client = bigtable.Client(project=PROJECT, admin=True) + for instance_id in instances: + instance = client.instance(instance_id) + if instance.exists(): + instance.delete() + + +def test_run_instance_operations(capsys, dispose_of): + dispose_of(INSTANCE) + + instanceadmin.run_instance_operations(PROJECT, INSTANCE, CLUSTER1) + out = capsys.readouterr().out + assert f"Instance {INSTANCE} does not exist." in out + assert "Creating an instance" in out + assert f"Created instance: {INSTANCE}" in out + assert "Listing instances" in out + assert f"\n{INSTANCE}\n" in out + assert f"Name of instance: {INSTANCE}" in out + assert "Labels: {'prod-label': 'prod-label'}" in out + assert "Listing clusters..." in out + assert f"\n{CLUSTER1}\n" in out + + instanceadmin.run_instance_operations(PROJECT, INSTANCE, CLUSTER1) + out = capsys.readouterr().out + assert f"Instance {INSTANCE} already exists." in out + assert "Listing instances" in out + assert f"\n{INSTANCE}\n" in out + assert f"Name of instance: {INSTANCE}" in out + assert "Labels: {'prod-label': 'prod-label'}" in out + assert "Listing clusters..." in out + assert f"\n{CLUSTER1}\n" in out + + +def test_delete_instance(capsys, dispose_of): + from concurrent.futures import TimeoutError + + @backoff.on_exception(backoff.expo, TimeoutError) + def _set_up_instance(): + dispose_of(INSTANCE) + + # Can't delete it, it doesn't exist + instanceadmin.delete_instance(PROJECT, INSTANCE) + out = capsys.readouterr().out + assert "Deleting instance" in out + assert f"Instance {INSTANCE} does not exist" in out + + # Ok, create it then + instanceadmin.run_instance_operations(PROJECT, INSTANCE, CLUSTER1) + capsys.readouterr() # throw away output + + _set_up_instance() + + # Now delete it + instanceadmin.delete_instance(PROJECT, INSTANCE) + out = capsys.readouterr().out + assert "Deleting instance" in out + assert f"Deleted instance: {INSTANCE}" in out + + +def test_add_and_delete_cluster(capsys, dispose_of): + from concurrent.futures import TimeoutError + + @backoff.on_exception(backoff.expo, TimeoutError) + def _set_up_instance(): + dispose_of(INSTANCE) + + # This won't work, because the instance isn't created yet + instanceadmin.add_cluster(PROJECT, INSTANCE, CLUSTER2) + out = capsys.readouterr().out + assert f"Instance {INSTANCE} does not exist" in out + + # Get the instance created + instanceadmin.run_instance_operations(PROJECT, INSTANCE, CLUSTER1) + capsys.readouterr() # throw away output + + _set_up_instance() + + # Add a cluster to that instance + # Avoid failing for "instance is currently being changed" by + # applying an exponential backoff + backoff_503 = backoff.on_exception(backoff.expo, exceptions.ServiceUnavailable) + + backoff_503(instanceadmin.add_cluster)(PROJECT, INSTANCE, CLUSTER2) + out = capsys.readouterr().out + assert f"Adding cluster to instance {INSTANCE}" in out + assert "Listing clusters..." in out + assert f"\n{CLUSTER1}\n" in out + assert f"Cluster created: {CLUSTER2}" in out + + # Try to add the same cluster again, won't work + instanceadmin.add_cluster(PROJECT, INSTANCE, CLUSTER2) + out = capsys.readouterr().out + assert "Listing clusters..." in out + assert f"\n{CLUSTER1}\n" in out + assert f"\n{CLUSTER2}\n" in out + assert f"Cluster not created, as {CLUSTER2} already exists." + + # Now delete it + instanceadmin.delete_cluster(PROJECT, INSTANCE, CLUSTER2) + out = capsys.readouterr().out + assert "Deleting cluster" in out + assert f"Cluster deleted: {CLUSTER2}" in out + + # Verify deletion + instanceadmin.run_instance_operations(PROJECT, INSTANCE, CLUSTER1) + out = capsys.readouterr().out + assert "Listing clusters..." in out + assert f"\n{CLUSTER1}\n" in out + assert f"\n{CLUSTER2}\n" not in out + + # Try deleting it again, for fun (and coverage) + instanceadmin.delete_cluster(PROJECT, INSTANCE, CLUSTER2) + out = capsys.readouterr().out + assert "Deleting cluster" in out + assert f"Cluster {CLUSTER2} does not exist" in out diff --git a/packages/google-cloud-bigtable/samples/metricscaler/Dockerfile b/packages/google-cloud-bigtable/samples/metricscaler/Dockerfile new file mode 100644 index 000000000000..d8a5ec0c1a9b --- /dev/null +++ b/packages/google-cloud-bigtable/samples/metricscaler/Dockerfile @@ -0,0 +1,24 @@ +# 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 python:3 + +WORKDIR /usr/src/app + +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +COPY . . + +ENTRYPOINT [ "python", "./metricscaler.py"] +CMD ["--help"] diff --git a/packages/google-cloud-bigtable/samples/metricscaler/README.md b/packages/google-cloud-bigtable/samples/metricscaler/README.md new file mode 100644 index 000000000000..e1624bb1872e --- /dev/null +++ b/packages/google-cloud-bigtable/samples/metricscaler/README.md @@ -0,0 +1,52 @@ +[//]: # "This README.md file is auto-generated, all changes to this file will be lost." +[//]: # "To regenerate it, use `python -m synthtool`." + +## Python Samples for Cloud Bigtable + +This directory contains samples for Cloud Bigtable, which may be used as a refererence for how to use this product. +Samples, quickstarts, and other documentation are available at cloud.google.com. + + +### Metric Scaler + +This sample demonstrates how to use Stackdriver Monitoring to scale Cloud Bigtable based on CPU usage. + + +Open in Cloud Shell + + +To run this sample: + +1. If this is your first time working with GCP products, you will need to set up [the Cloud SDK][cloud_sdk] or utilize [Google Cloud Shell][gcloud_shell]. This sample may [require authetication][authentication] and you will need to [enable billing][enable_billing]. + +1. Make a fork of this repo and clone the branch locally, then navigate to the sample directory you want to use. + +1. Install the dependencies needed to run the samples. + + pip install -r requirements.txt + +1. Run the sample using + + python metricscaler.py + + + +
usage: metricscaler.py [-h] [--high_cpu_threshold HIGH_CPU_THRESHOLD] [--low_cpu_threshold LOW_CPU_THRESHOLD] [--short_sleep SHORT_SLEEP] [--long_sleep LONG_SLEEP] bigtable_instance bigtable_cluster
usage: metricscaler.py [-h] [--high_cpu_threshold HIGH_CPU_THRESHOLD]
                       [--low_cpu_threshold LOW_CPU_THRESHOLD]
                       [--short_sleep SHORT_SLEEP] [--long_sleep LONG_SLEEP]
                       bigtable_instance bigtable_cluster


Scales Cloud Bigtable clusters based on CPU usage.


positional arguments:
  bigtable_instance     ID of the Cloud Bigtable instance to connect to.
  bigtable_cluster      ID of the Cloud Bigtable cluster to connect to.


optional arguments:
  -h, --help            show this help message and exit
  --high_cpu_threshold HIGH_CPU_THRESHOLD
                        If Cloud Bigtable CPU usage is above this threshold,
                        scale up
  --low_cpu_threshold LOW_CPU_THRESHOLD
                        If Cloud Bigtable CPU usage is below this threshold,
                        scale down
  --short_sleep SHORT_SLEEP
                        How long to sleep in seconds between checking metrics
                        after no scale operation
  --long_sleep LONG_SLEEP
                        How long to sleep in seconds between checking metrics
                        after a scaling operation
+ +## Additional Information + +You can read the documentation for more details on API usage and use GitHub +to browse the source and [report issues][issues]. + +### Contributing +View the [contributing guidelines][contrib_guide], the [Python style guide][py_style] for more information. + +[authentication]: https://cloud.google.com/docs/authentication/getting-started +[enable_billing]:https://cloud.google.com/apis/docs/getting-started#enabling_billing +[client_library_python]: https://googlecloudplatform.github.io/google-cloud-python/ +[issues]: https://github.com/GoogleCloudPlatform/google-cloud-python/issues +[contrib_guide]: https://github.com/googleapis/google-cloud-python/blob/main/CONTRIBUTING.rst +[py_style]: http://google.github.io/styleguide/pyguide.html +[cloud_sdk]: https://cloud.google.com/sdk/docs +[gcloud_shell]: https://cloud.google.com/shell/docs +[gcloud_shell]: https://cloud.google.com/shell/docs diff --git a/packages/google-cloud-bigtable/samples/metricscaler/metricscaler.py b/packages/google-cloud-bigtable/samples/metricscaler/metricscaler.py new file mode 100644 index 000000000000..1f89e6aacc15 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/metricscaler/metricscaler.py @@ -0,0 +1,234 @@ +# Copyright 2017 Google Inc. +# +# 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. + +"""Sample that demonstrates how to use Stackdriver Monitoring metrics to +programmatically scale a Google Cloud Bigtable cluster.""" + +import argparse +import logging +import os +import time + +from google.cloud.monitoring_v3 import query + +from google.cloud import bigtable, monitoring_v3 +from google.cloud.bigtable import enums + +PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"] + +logger = logging.getLogger("bigtable.metricscaler") +logger.addHandler(logging.StreamHandler()) +logger.setLevel(logging.INFO) + + +def get_cpu_load(bigtable_instance, bigtable_cluster): + """Returns the most recent Cloud Bigtable CPU load measurement. + + Returns: + float: The most recent Cloud Bigtable CPU usage metric + """ + # [START bigtable_cpu] + client = monitoring_v3.MetricServiceClient() + cpu_query = query.Query( + client, + project=PROJECT, + metric_type="bigtable.googleapis.com/cluster/cpu_load", + minutes=5, + ) + cpu_query = cpu_query.select_resources( + instance=bigtable_instance, cluster=bigtable_cluster + ) + cpu = next(cpu_query.iter()) + return cpu.points[0].value.double_value + # [END bigtable_cpu] + + +def get_storage_utilization(bigtable_instance, bigtable_cluster): + """Returns the most recent Cloud Bigtable storage utilization measurement. + + Returns: + float: The most recent Cloud Bigtable storage utilization metric + """ + # [START bigtable_metric_scaler_storage_utilization] + client = monitoring_v3.MetricServiceClient() + utilization_query = query.Query( + client, + project=PROJECT, + metric_type="bigtable.googleapis.com/cluster/storage_utilization", + minutes=5, + ) + utilization_query = utilization_query.select_resources( + instance=bigtable_instance, cluster=bigtable_cluster + ) + utilization = next(utilization_query.iter()) + return utilization.points[0].value.double_value + # [END bigtable_metric_scaler_storage_utilization] + + +def scale_bigtable(bigtable_instance, bigtable_cluster, scale_up): + """Scales the number of Cloud Bigtable nodes up or down. + + Edits the number of nodes in the Cloud Bigtable cluster to be increased + or decreased, depending on the `scale_up` boolean argument. Currently + the `incremental` strategy from `strategies.py` is used. + + + Args: + bigtable_instance (str): Cloud Bigtable instance ID to scale + bigtable_cluster (str): Cloud Bigtable cluster ID to scale + scale_up (bool): If true, scale up, otherwise scale down + """ + + # The minimum number of nodes to use. The default minimum is 3. If you have + # a lot of data, the rule of thumb is to not go below 2.5 TB per node for + # SSD lusters, and 8 TB for HDD. The + # "bigtable.googleapis.com/disk/bytes_used" metric is useful in figuring + # out the minimum number of nodes. + min_node_count = 1 + + # The maximum number of nodes to use. The default maximum is 30 nodes per + # zone. If you need more quota, you can request more by following the + # instructions at https://cloud.google.com/bigtable/quota. + max_node_count = 30 + + # The number of nodes to change the cluster by. + size_change_step = 3 + + # [START bigtable_scale] + bigtable_client = bigtable.Client(admin=True) + instance = bigtable_client.instance(bigtable_instance) + instance.reload() + + if instance.type_ == enums.Instance.Type.DEVELOPMENT: + raise ValueError("Development instances cannot be scaled.") + + cluster = instance.cluster(bigtable_cluster) + cluster.reload() + + current_node_count = cluster.serve_nodes + + if scale_up: + if current_node_count < max_node_count: + new_node_count = min(current_node_count + size_change_step, max_node_count) + cluster.serve_nodes = new_node_count + operation = cluster.update() + response = operation.result(480) + logger.info( + "Scaled up from {} to {} nodes for {}.".format( + current_node_count, new_node_count, response.name + ) + ) + else: + if current_node_count > min_node_count: + new_node_count = max(current_node_count - size_change_step, min_node_count) + cluster.serve_nodes = new_node_count + operation = cluster.update() + response = operation.result(480) + logger.info( + "Scaled down from {} to {} nodes for {}.".format( + current_node_count, new_node_count, response.name + ) + ) + # [END bigtable_scale] + + +def main( + bigtable_instance, + bigtable_cluster, + high_cpu_threshold, + low_cpu_threshold, + high_storage_threshold, + short_sleep, + long_sleep, +): + """Main loop runner that autoscales Cloud Bigtable. + + Args: + bigtable_instance (str): Cloud Bigtable instance ID to autoscale + high_cpu_threshold (float): If CPU is higher than this, scale up. + low_cpu_threshold (float): If CPU is lower than this, scale down. + high_storage_threshold (float): If storage is higher than this, + scale up. + short_sleep (int): How long to sleep after no operation + long_sleep (int): How long to sleep after the number of nodes is + changed + """ + cluster_cpu = get_cpu_load(bigtable_instance, bigtable_cluster) + cluster_storage = get_storage_utilization(bigtable_instance, bigtable_cluster) + logger.info("Detected cpu of {}".format(cluster_cpu)) + logger.info("Detected storage utilization of {}".format(cluster_storage)) + try: + if cluster_cpu > high_cpu_threshold or cluster_storage > high_storage_threshold: + scale_bigtable(bigtable_instance, bigtable_cluster, True) + time.sleep(long_sleep) + elif cluster_cpu < low_cpu_threshold: + if cluster_storage < high_storage_threshold: + scale_bigtable(bigtable_instance, bigtable_cluster, False) + time.sleep(long_sleep) + else: + logger.info("CPU within threshold, sleeping.") + time.sleep(short_sleep) + except Exception as e: + logger.error("Error during scaling: %s", e) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description="Scales Cloud Bigtable clusters based on CPU usage." + ) + parser.add_argument( + "bigtable_instance", help="ID of the Cloud Bigtable instance to connect to." + ) + parser.add_argument( + "bigtable_cluster", help="ID of the Cloud Bigtable cluster to connect to." + ) + parser.add_argument( + "--high_cpu_threshold", + help="If Cloud Bigtable CPU usage is above this threshold, scale up", + default=0.6, + ) + parser.add_argument( + "--low_cpu_threshold", + help="If Cloud Bigtable CPU usage is below this threshold, scale down", + default=0.2, + ) + parser.add_argument( + "--high_storage_threshold", + help="If Cloud Bigtable storage utilization is above this threshold, scale up", + default=0.6, + ) + parser.add_argument( + "--short_sleep", + help="How long to sleep in seconds between checking metrics after no " + "scale operation", + default=60, + ) + parser.add_argument( + "--long_sleep", + help="How long to sleep in seconds between checking metrics after a " + "scaling operation", + default=60 * 10, + ) + args = parser.parse_args() + + while True: + main( + args.bigtable_instance, + args.bigtable_cluster, + float(args.high_cpu_threshold), + float(args.low_cpu_threshold), + float(args.high_storage_threshold), + int(args.short_sleep), + int(args.long_sleep), + ) diff --git a/packages/google-cloud-bigtable/samples/metricscaler/metricscaler_test.py b/packages/google-cloud-bigtable/samples/metricscaler/metricscaler_test.py new file mode 100644 index 000000000000..f769ce05e11f --- /dev/null +++ b/packages/google-cloud-bigtable/samples/metricscaler/metricscaler_test.py @@ -0,0 +1,225 @@ +# Copyright 2017 Google Inc. +# +# 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. + +"""Unit and system tests for metricscaler.py""" + +import os +import uuid + +import pytest +from metricscaler import get_cpu_load, get_storage_utilization, main, scale_bigtable +from mock import Mock, patch +from test_utils.retry import RetryInstanceState, RetryResult + +from google.cloud import bigtable +from google.cloud.bigtable import enums + +PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"] +BIGTABLE_ZONE = os.environ["BIGTABLE_ZONE"] +SIZE_CHANGE_STEP = 3 +INSTANCE_ID_FORMAT = "metric-scale-test-{}" +BIGTABLE_INSTANCE = INSTANCE_ID_FORMAT.format(str(uuid.uuid4())[:10]) +BIGTABLE_DEV_INSTANCE = INSTANCE_ID_FORMAT.format(str(uuid.uuid4())[:10]) + + +# System tests to verify API calls succeed + + +@patch("metricscaler.query") +def test_get_cpu_load(monitoring_v3_query): + iter_mock = monitoring_v3_query.Query().select_resources().iter + iter_mock.return_value = iter([Mock(points=[Mock(value=Mock(double_value=1.0))])]) + assert float(get_cpu_load(BIGTABLE_INSTANCE, BIGTABLE_INSTANCE)) > 0.0 + + +@patch("metricscaler.query") +def test_get_storage_utilization(monitoring_v3_query): + iter_mock = monitoring_v3_query.Query().select_resources().iter + iter_mock.return_value = iter([Mock(points=[Mock(value=Mock(double_value=1.0))])]) + assert float(get_storage_utilization(BIGTABLE_INSTANCE, BIGTABLE_INSTANCE)) > 0.0 + + +@pytest.fixture() +def instance(): + cluster_id = BIGTABLE_INSTANCE + + client = bigtable.Client(project=PROJECT, admin=True) + + serve_nodes = 1 + storage_type = enums.StorageType.SSD + production = enums.Instance.Type.PRODUCTION + labels = {"prod-label": "prod-label"} + instance = client.instance( + BIGTABLE_INSTANCE, instance_type=production, labels=labels + ) + + if not instance.exists(): + cluster = instance.cluster( + cluster_id, + location_id=BIGTABLE_ZONE, + serve_nodes=serve_nodes, + default_storage_type=storage_type, + ) + operation = instance.create(clusters=[cluster]) + response = operation.result(480) + print(f"Successfully created {response.name}") + + # Eventual consistency check + retry_found = RetryResult(bool) + retry_found(instance.exists)() + + yield + + instance.delete() + + +@pytest.fixture() +def dev_instance(): + cluster_id = BIGTABLE_DEV_INSTANCE + + client = bigtable.Client(project=PROJECT, admin=True) + + storage_type = enums.StorageType.SSD + development = enums.Instance.Type.DEVELOPMENT + labels = {"dev-label": "dev-label"} + instance = client.instance( + BIGTABLE_DEV_INSTANCE, instance_type=development, labels=labels + ) + + if not instance.exists(): + cluster = instance.cluster( + cluster_id, location_id=BIGTABLE_ZONE, default_storage_type=storage_type + ) + operation = instance.create(clusters=[cluster]) + response = operation.result(480) + print(f"Successfully created {response.name}") + + # Eventual consistency check + retry_found = RetryResult(bool) + retry_found(instance.exists)() + + yield + + instance.delete() + + +class ClusterNodeCountPredicate: + def __init__(self, expected_node_count): + self.expected_node_count = expected_node_count + + def __call__(self, cluster): + expected = self.expected_node_count + print(f"Expected node count: {expected}; found: {cluster.serve_nodes}") + return cluster.serve_nodes == expected + + +def test_scale_bigtable(instance): + bigtable_client = bigtable.Client(admin=True) + + instance = bigtable_client.instance(BIGTABLE_INSTANCE) + instance.reload() + + cluster = instance.cluster(BIGTABLE_INSTANCE) + + _nonzero_node_count = RetryInstanceState( + instance_predicate=lambda c: c.serve_nodes > 0, + max_tries=10, + ) + _nonzero_node_count(cluster.reload)() + + original_node_count = cluster.serve_nodes + + scale_bigtable(BIGTABLE_INSTANCE, BIGTABLE_INSTANCE, True) + + scaled_node_count_predicate = ClusterNodeCountPredicate( + original_node_count + SIZE_CHANGE_STEP + ) + scaled_node_count_predicate.__name__ = "scaled_node_count_predicate" + _scaled_node_count = RetryInstanceState( + instance_predicate=scaled_node_count_predicate, + max_tries=10, + ) + _scaled_node_count(cluster.reload)() + + scale_bigtable(BIGTABLE_INSTANCE, BIGTABLE_INSTANCE, False) + + restored_node_count_predicate = ClusterNodeCountPredicate(original_node_count) + restored_node_count_predicate.__name__ = "restored_node_count_predicate" + _restored_node_count = RetryInstanceState( + instance_predicate=restored_node_count_predicate, + max_tries=10, + ) + _restored_node_count(cluster.reload)() + + +def test_handle_dev_instance(capsys, dev_instance): + with pytest.raises(ValueError): + scale_bigtable(BIGTABLE_DEV_INSTANCE, BIGTABLE_DEV_INSTANCE, True) + + +@patch("time.sleep") +@patch("metricscaler.get_storage_utilization") +@patch("metricscaler.get_cpu_load") +@patch("metricscaler.scale_bigtable") +def test_main(scale_bigtable, get_cpu_load, get_storage_utilization, sleep): + SHORT_SLEEP = 5 + LONG_SLEEP = 10 + + # Test okay CPU, okay storage utilization + get_cpu_load.return_value = 0.5 + get_storage_utilization.return_value = 0.5 + + main(BIGTABLE_INSTANCE, BIGTABLE_INSTANCE, 0.6, 0.3, 0.6, SHORT_SLEEP, LONG_SLEEP) + scale_bigtable.assert_not_called() + scale_bigtable.reset_mock() + + # Test high CPU, okay storage utilization + get_cpu_load.return_value = 0.7 + get_storage_utilization.return_value = 0.5 + main(BIGTABLE_INSTANCE, BIGTABLE_INSTANCE, 0.6, 0.3, 0.6, SHORT_SLEEP, LONG_SLEEP) + scale_bigtable.assert_called_once_with(BIGTABLE_INSTANCE, BIGTABLE_INSTANCE, True) + scale_bigtable.reset_mock() + + # Test low CPU, okay storage utilization + get_storage_utilization.return_value = 0.5 + get_cpu_load.return_value = 0.2 + main(BIGTABLE_INSTANCE, BIGTABLE_INSTANCE, 0.6, 0.3, 0.6, SHORT_SLEEP, LONG_SLEEP) + scale_bigtable.assert_called_once_with(BIGTABLE_INSTANCE, BIGTABLE_INSTANCE, False) + scale_bigtable.reset_mock() + + # Test okay CPU, high storage utilization + get_cpu_load.return_value = 0.5 + get_storage_utilization.return_value = 0.7 + + main(BIGTABLE_INSTANCE, BIGTABLE_INSTANCE, 0.6, 0.3, 0.6, SHORT_SLEEP, LONG_SLEEP) + scale_bigtable.assert_called_once_with(BIGTABLE_INSTANCE, BIGTABLE_INSTANCE, True) + scale_bigtable.reset_mock() + + # Test high CPU, high storage utilization + get_cpu_load.return_value = 0.7 + get_storage_utilization.return_value = 0.7 + main(BIGTABLE_INSTANCE, BIGTABLE_INSTANCE, 0.6, 0.3, 0.6, SHORT_SLEEP, LONG_SLEEP) + scale_bigtable.assert_called_once_with(BIGTABLE_INSTANCE, BIGTABLE_INSTANCE, True) + scale_bigtable.reset_mock() + + # Test low CPU, high storage utilization + get_cpu_load.return_value = 0.2 + get_storage_utilization.return_value = 0.7 + main(BIGTABLE_INSTANCE, BIGTABLE_INSTANCE, 0.6, 0.3, 0.6, SHORT_SLEEP, LONG_SLEEP) + scale_bigtable.assert_called_once_with(BIGTABLE_INSTANCE, BIGTABLE_INSTANCE, True) + scale_bigtable.reset_mock() + + +if __name__ == "__main__": + test_get_cpu_load() diff --git a/packages/google-cloud-bigtable/samples/metricscaler/noxfile.py b/packages/google-cloud-bigtable/samples/metricscaler/noxfile.py new file mode 100644 index 000000000000..c0e60097b353 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/metricscaler/noxfile.py @@ -0,0 +1,292 @@ +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import print_function + +import glob +import os +import sys +from pathlib import Path +from typing import Callable, Dict, Optional + +import nox + +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING +# DO NOT EDIT THIS FILE EVER! +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING + +BLACK_VERSION = "black==22.3.0" +ISORT_VERSION = "isort==5.10.1" + +# Copy `noxfile_config.py` to your directory and modify it instead. + +# `TEST_CONFIG` dict is a configuration hook that allows users to +# modify the test configurations. The values here should be in sync +# with `noxfile_config.py`. Users will copy `noxfile_config.py` into +# their directory and modify it. + +TEST_CONFIG = { + # You can opt out from the test for specific Python versions. + "ignored_versions": [], + # Old samples are opted out of enforcing Python type hints + # All new samples should feature them + "enforce_type_hints": False, + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", + # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + # If you need to use a specific version of pip, + # change pip_version_override to the string representation + # of the version number, for example, "20.2.4" + "pip_version_override": None, + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + "envs": {}, +} + + +try: + # Ensure we can import noxfile_config in the project's directory. + sys.path.append(".") + from noxfile_config import TEST_CONFIG_OVERRIDE +except ImportError as e: + print("No user noxfile_config found: detail: {}".format(e)) + TEST_CONFIG_OVERRIDE = {} + +# Update the TEST_CONFIG with the user supplied values. +TEST_CONFIG.update(TEST_CONFIG_OVERRIDE) + + +def get_pytest_env_vars() -> Dict[str, str]: + """Returns a dict for pytest invocation.""" + ret = {} + + # Override the GCLOUD_PROJECT and the alias. + env_key = TEST_CONFIG["gcloud_project_env"] + # This should error out if not set. + ret["GOOGLE_CLOUD_PROJECT"] = os.environ[env_key] + + # Apply user supplied envs. + ret.update(TEST_CONFIG["envs"]) + return ret + + +# DO NOT EDIT - automatically generated. +# All versions used to test samples. +ALL_VERSIONS = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + +# Any default versions that should be ignored. +IGNORED_VERSIONS = TEST_CONFIG["ignored_versions"] + +TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) + +INSTALL_LIBRARY_FROM_SOURCE = os.environ.get("INSTALL_LIBRARY_FROM_SOURCE", False) in ( + "True", + "true", +) + +# Error if a python version is missing +nox.options.error_on_missing_interpreters = True + +# +# Style Checks +# + + +# Linting with flake8. +# +# We ignore the following rules: +# E203: whitespace before ‘:’ +# E266: too many leading ‘#’ for block comment +# E501: line too long +# I202: Additional newline in a section of imports +# +# We also need to specify the rules which are ignored by default: +# ['E226', 'W504', 'E126', 'E123', 'W503', 'E24', 'E704', 'E121'] +FLAKE8_COMMON_ARGS = [ + "--show-source", + "--builtin=gettext", + "--max-complexity=20", + "--exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py", + "--ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202", + "--max-line-length=88", +] + + +@nox.session +def lint(session: nox.sessions.Session) -> None: + if not TEST_CONFIG["enforce_type_hints"]: + session.install("flake8") + else: + session.install("flake8", "flake8-annotations") + + args = FLAKE8_COMMON_ARGS + [ + ".", + ] + session.run("flake8", *args) + + +# +# Black +# + + +@nox.session +def blacken(session: nox.sessions.Session) -> None: + """Run black. Format code to uniform standard.""" + session.install(BLACK_VERSION) + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + session.run("black", *python_files) + + +# +# format = isort + black +# + + +@nox.session +def format(session: nox.sessions.Session) -> None: + """ + Run isort to sort imports. Then run black + to format code to uniform standard. + """ + session.install(BLACK_VERSION, ISORT_VERSION) + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + # Use the --fss option to sort imports using strict alphabetical order. + # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + session.run("isort", "--fss", *python_files) + session.run("black", *python_files) + + +# +# Sample Tests +# + + +PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] + + +def _session_tests( + session: nox.sessions.Session, post_install: Callable = None +) -> None: + # check for presence of tests + test_list = glob.glob("**/*_test.py", recursive=True) + glob.glob( + "**/test_*.py", recursive=True + ) + test_list.extend(glob.glob("**/tests", recursive=True)) + + if len(test_list) == 0: + print("No tests found, skipping directory.") + return + + if TEST_CONFIG["pip_version_override"]: + pip_version = TEST_CONFIG["pip_version_override"] + session.install(f"pip=={pip_version}") + """Runs py.test for a particular project.""" + concurrent_args = [] + if os.path.exists("requirements.txt"): + if os.path.exists("constraints.txt"): + session.install("-r", "requirements.txt", "-c", "constraints.txt") + else: + session.install("-r", "requirements.txt") + with open("requirements.txt") as rfile: + packages = rfile.read() + + if os.path.exists("requirements-test.txt"): + if os.path.exists("constraints-test.txt"): + session.install("-r", "requirements-test.txt", "-c", "constraints-test.txt") + else: + session.install("-r", "requirements-test.txt") + with open("requirements-test.txt") as rtfile: + packages += rtfile.read() + + if INSTALL_LIBRARY_FROM_SOURCE: + session.install("-e", _get_repo_root()) + + if post_install: + post_install(session) + + if "pytest-parallel" in packages: + concurrent_args.extend(["--workers", "auto", "--tests-per-worker", "auto"]) + elif "pytest-xdist" in packages: + concurrent_args.extend(["-n", "auto"]) + + session.run( + "pytest", + *(PYTEST_COMMON_ARGS + session.posargs + concurrent_args), + # Pytest will return 5 when no tests are collected. This can happen + # on travis where slow and flaky tests are excluded. + # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html + success_codes=[0, 5], + env=get_pytest_env_vars(), + ) + + +@nox.session(python=ALL_VERSIONS) +def py(session: nox.sessions.Session) -> None: + """Runs py.test for a sample using the specified version of Python.""" + if session.python in TESTED_VERSIONS: + _session_tests(session) + else: + session.skip( + "SKIPPED: {} tests are disabled for this sample.".format(session.python) + ) + + +# +# Readmegen +# + + +def _get_repo_root() -> Optional[str]: + """Returns the root folder of the project.""" + # Get root of this repository. Assume we don't have directories nested deeper than 10 items. + p = Path(os.getcwd()) + for i in range(10): + if p is None: + break + if Path(p / ".git").exists(): + return str(p) + # .git is not available in repos cloned via Cloud Build + # setup.py is always in the library's root, so use that instead + # https://github.com/googleapis/synthtool/issues/792 + if Path(p / "setup.py").exists(): + return str(p) + p = p.parent + raise Exception("Unable to detect repository root.") + + +GENERATED_READMES = sorted([x for x in Path(".").rglob("*.rst.in")]) + + +@nox.session +@nox.parametrize("path", GENERATED_READMES) +def readmegen(session: nox.sessions.Session, path: str) -> None: + """(Re-)generates the readme for a sample.""" + session.install("jinja2", "pyyaml") + dir_ = os.path.dirname(path) + + if os.path.exists(os.path.join(dir_, "requirements.txt")): + session.install("-r", os.path.join(dir_, "requirements.txt")) + + in_file = os.path.join(dir_, "README.rst.in") + session.run( + "python", _get_repo_root() + "/scripts/readme-gen/readme_gen.py", in_file + ) diff --git a/packages/google-cloud-bigtable/samples/metricscaler/noxfile_config.py b/packages/google-cloud-bigtable/samples/metricscaler/noxfile_config.py new file mode 100644 index 000000000000..8a2d55bea291 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/metricscaler/noxfile_config.py @@ -0,0 +1,39 @@ +# Copyright 2021 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. + +# Default TEST_CONFIG_OVERRIDE for python repos. + +# You can copy this file into your directory, then it will be imported from +# the noxfile.py. + +# The source of truth: +# https://github.com/GoogleCloudPlatform/python-docs-samples/blob/main/noxfile_config.py + +TEST_CONFIG_OVERRIDE = { + # Old samples are opted out of enforcing Python type hints + # All new samples should feature them + "enforce_type_hints": False, + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + "gcloud_project_env": "BUILD_SPECIFIC_GCLOUD_PROJECT", + # If you need to use a specific version of pip, + # change pip_version_override to the string representation + # of the version number, for example, "20.2.4" + "pip_version_override": None, + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + "envs": {}, +} diff --git a/packages/google-cloud-bigtable/samples/metricscaler/requirements-test.txt b/packages/google-cloud-bigtable/samples/metricscaler/requirements-test.txt new file mode 100644 index 000000000000..d11108b81f7c --- /dev/null +++ b/packages/google-cloud-bigtable/samples/metricscaler/requirements-test.txt @@ -0,0 +1,3 @@ +pytest +mock==5.2.0 +google-cloud-testutils diff --git a/packages/google-cloud-bigtable/samples/metricscaler/requirements.txt b/packages/google-cloud-bigtable/samples/metricscaler/requirements.txt new file mode 100644 index 000000000000..257fd1ef67aa --- /dev/null +++ b/packages/google-cloud-bigtable/samples/metricscaler/requirements.txt @@ -0,0 +1,2 @@ +google-cloud-bigtable==2.35.0 +google-cloud-monitoring==2.29.0 diff --git a/packages/google-cloud-bigtable/samples/quickstart/README.md b/packages/google-cloud-bigtable/samples/quickstart/README.md new file mode 100644 index 000000000000..f61000e135d0 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/quickstart/README.md @@ -0,0 +1,52 @@ +[//]: # "This README.md file is auto-generated, all changes to this file will be lost." +[//]: # "To regenerate it, use `python -m synthtool`." + +## Python Samples for Cloud Bigtable + +This directory contains samples for Cloud Bigtable, which may be used as a refererence for how to use this product. +Samples, quickstarts, and other documentation are available at cloud.google.com. + + +### Quickstart + +Demonstrates of Cloud Bigtable. This sample creates a Bigtable client, connects to an instance and then to a table, then closes the connection. + + +Open in Cloud Shell + + +To run this sample: + +1. If this is your first time working with GCP products, you will need to set up [the Cloud SDK][cloud_sdk] or utilize [Google Cloud Shell][gcloud_shell]. This sample may [require authetication][authentication] and you will need to [enable billing][enable_billing]. + +1. Make a fork of this repo and clone the branch locally, then navigate to the sample directory you want to use. + +1. Install the dependencies needed to run the samples. + + pip install -r requirements.txt + +1. Run the sample using + + python main.py + + + +
usage: main.py [-h] [--table TABLE] project_id instance_id 


positional arguments:
  project_id     Your Cloud Platform project ID.
  instance_id    ID of the Cloud Bigtable instance to connect to.


optional arguments:
  -h, --help     show this help message and exit
  --table TABLE  Existing table used in the quickstart. (default: my-table)
+ +## Additional Information + +You can read the documentation for more details on API usage and use GitHub +to browse the source and [report issues][issues]. + +### Contributing +View the [contributing guidelines][contrib_guide], the [Python style guide][py_style] for more information. + +[authentication]: https://cloud.google.com/docs/authentication/getting-started +[enable_billing]:https://cloud.google.com/apis/docs/getting-started#enabling_billing +[client_library_python]: https://googlecloudplatform.github.io/google-cloud-python/ +[issues]: https://github.com/GoogleCloudPlatform/google-cloud-python/issues +[contrib_guide]: https://github.com/googleapis/google-cloud-python/blob/main/CONTRIBUTING.rst +[py_style]: http://google.github.io/styleguide/pyguide.html +[cloud_sdk]: https://cloud.google.com/sdk/docs +[gcloud_shell]: https://cloud.google.com/shell/docs +[gcloud_shell]: https://cloud.google.com/shell/docs diff --git a/packages/google-cloud-bigtable/samples/quickstart/__init__.py b/packages/google-cloud-bigtable/samples/quickstart/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-cloud-bigtable/samples/quickstart/main.py b/packages/google-cloud-bigtable/samples/quickstart/main.py new file mode 100644 index 000000000000..50bfe639426c --- /dev/null +++ b/packages/google-cloud-bigtable/samples/quickstart/main.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python + +# Copyright 2018 Google Inc. +# +# 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. + +# [START bigtable_quickstart] +import argparse + +from google.cloud import bigtable + + +def main(project_id="project-id", instance_id="instance-id", table_id="my-table"): + # Create a Cloud Bigtable client. + client = bigtable.Client(project=project_id) + + # Connect to an existing Cloud Bigtable instance. + instance = client.instance(instance_id) + + # Open an existing table. + table = instance.table(table_id) + + row_key = "r1" + row = table.read_row(row_key.encode("utf-8")) + + column_family_id = "cf1" + column_id = "c1".encode("utf-8") + value = row.cells[column_family_id][column_id][0].value.decode("utf-8") + + print("Row key: {}\nData: {}".format(row_key, value)) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description=__doc__, formatter_class=argparse.ArgumentDefaultsHelpFormatter + ) + parser.add_argument("project_id", help="Your Cloud Platform project ID.") + parser.add_argument( + "instance_id", help="ID of the Cloud Bigtable instance to connect to." + ) + parser.add_argument( + "--table", help="Existing table used in the quickstart.", default="my-table" + ) + + args = parser.parse_args() + main(args.project_id, args.instance_id, args.table) +# [END bigtable_quickstart] diff --git a/packages/google-cloud-bigtable/samples/quickstart/main_async.py b/packages/google-cloud-bigtable/samples/quickstart/main_async.py new file mode 100644 index 000000000000..c38985592e42 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/quickstart/main_async.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python + +# Copyright 2024 Google Inc. +# +# 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. + +# [START bigtable_quickstart_asyncio] +import argparse +import asyncio + +from google.cloud.bigtable.data import BigtableDataClientAsync + + +async def main(project_id="project-id", instance_id="instance-id", table_id="my-table"): + # Create a Cloud Bigtable client. + client = BigtableDataClientAsync(project=project_id) + + # Open an existing table. + table = client.get_table(instance_id, table_id) + + row_key = "r1" + row = await table.read_row(row_key) + + column_family_id = "cf1" + column_id = b"c1" + value = row.get_cells(column_family_id, column_id)[0].value.decode("utf-8") + + await table.close() + await client.close() + + print("Row key: {}\nData: {}".format(row_key, value)) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description=__doc__, formatter_class=argparse.ArgumentDefaultsHelpFormatter + ) + parser.add_argument("project_id", help="Your Cloud Platform project ID.") + parser.add_argument( + "instance_id", help="ID of the Cloud Bigtable instance to connect to." + ) + parser.add_argument( + "--table", help="Existing table used in the quickstart.", default="my-table" + ) + + args = parser.parse_args() + asyncio.get_event_loop().run_until_complete( + main(args.project_id, args.instance_id, args.table) + ) + +# [END bigtable_quickstart_asyncio] diff --git a/packages/google-cloud-bigtable/samples/quickstart/main_async_test.py b/packages/google-cloud-bigtable/samples/quickstart/main_async_test.py new file mode 100644 index 000000000000..a67c0d095ba0 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/quickstart/main_async_test.py @@ -0,0 +1,50 @@ +# Copyright 2024 Google Inc. +# +# 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 uuid +from typing import AsyncGenerator + +import pytest +import pytest_asyncio + +from google.cloud.bigtable.data import BigtableDataClientAsync, SetCell + +from ..utils import create_table_cm +from .main_async import main + +PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"] +BIGTABLE_INSTANCE = os.environ["BIGTABLE_INSTANCE"] +TABLE_ID = f"quickstart-async-test-{str(uuid.uuid4())[:16]}" + + +@pytest_asyncio.fixture +async def table_id() -> AsyncGenerator[str, None]: + with create_table_cm(PROJECT, BIGTABLE_INSTANCE, TABLE_ID, {"cf1": None}): + await _populate_table(TABLE_ID) + yield TABLE_ID + + +async def _populate_table(table_id: str): + async with BigtableDataClientAsync(project=PROJECT) as client: + async with client.get_table(BIGTABLE_INSTANCE, table_id) as table: + await table.mutate_row("r1", SetCell("cf1", "c1", "test-value")) + + +@pytest.mark.asyncio +async def test_main(capsys, table_id): + await main(PROJECT, BIGTABLE_INSTANCE, table_id) + + out, _ = capsys.readouterr() + assert "Row key: r1\nData: test-value\n" in out diff --git a/packages/google-cloud-bigtable/samples/quickstart/main_test.py b/packages/google-cloud-bigtable/samples/quickstart/main_test.py new file mode 100644 index 000000000000..88419abd7ec4 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/quickstart/main_test.py @@ -0,0 +1,47 @@ +# Copyright 2018 Google Inc. +# +# 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 uuid + +import pytest + +from ..utils import create_table_cm +from .main import main + +PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"] +BIGTABLE_INSTANCE = os.environ["BIGTABLE_INSTANCE"] +TABLE_ID = f"quickstart-test-{str(uuid.uuid4())[:16]}" + + +@pytest.fixture() +def table(): + column_family_id = "cf1" + column_families = {column_family_id: None} + with create_table_cm( + PROJECT, BIGTABLE_INSTANCE, TABLE_ID, column_families + ) as table: + row = table.direct_row("r1") + row.set_cell(column_family_id, "c1", "test-value") + row.commit() + + yield TABLE_ID + + +def test_main(capsys, table): + table_id = table + main(PROJECT, BIGTABLE_INSTANCE, table_id) + + out, _ = capsys.readouterr() + assert "Row key: r1\nData: test-value\n" in out diff --git a/packages/google-cloud-bigtable/samples/quickstart/noxfile.py b/packages/google-cloud-bigtable/samples/quickstart/noxfile.py new file mode 100644 index 000000000000..c0e60097b353 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/quickstart/noxfile.py @@ -0,0 +1,292 @@ +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import print_function + +import glob +import os +import sys +from pathlib import Path +from typing import Callable, Dict, Optional + +import nox + +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING +# DO NOT EDIT THIS FILE EVER! +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING + +BLACK_VERSION = "black==22.3.0" +ISORT_VERSION = "isort==5.10.1" + +# Copy `noxfile_config.py` to your directory and modify it instead. + +# `TEST_CONFIG` dict is a configuration hook that allows users to +# modify the test configurations. The values here should be in sync +# with `noxfile_config.py`. Users will copy `noxfile_config.py` into +# their directory and modify it. + +TEST_CONFIG = { + # You can opt out from the test for specific Python versions. + "ignored_versions": [], + # Old samples are opted out of enforcing Python type hints + # All new samples should feature them + "enforce_type_hints": False, + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", + # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + # If you need to use a specific version of pip, + # change pip_version_override to the string representation + # of the version number, for example, "20.2.4" + "pip_version_override": None, + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + "envs": {}, +} + + +try: + # Ensure we can import noxfile_config in the project's directory. + sys.path.append(".") + from noxfile_config import TEST_CONFIG_OVERRIDE +except ImportError as e: + print("No user noxfile_config found: detail: {}".format(e)) + TEST_CONFIG_OVERRIDE = {} + +# Update the TEST_CONFIG with the user supplied values. +TEST_CONFIG.update(TEST_CONFIG_OVERRIDE) + + +def get_pytest_env_vars() -> Dict[str, str]: + """Returns a dict for pytest invocation.""" + ret = {} + + # Override the GCLOUD_PROJECT and the alias. + env_key = TEST_CONFIG["gcloud_project_env"] + # This should error out if not set. + ret["GOOGLE_CLOUD_PROJECT"] = os.environ[env_key] + + # Apply user supplied envs. + ret.update(TEST_CONFIG["envs"]) + return ret + + +# DO NOT EDIT - automatically generated. +# All versions used to test samples. +ALL_VERSIONS = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + +# Any default versions that should be ignored. +IGNORED_VERSIONS = TEST_CONFIG["ignored_versions"] + +TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) + +INSTALL_LIBRARY_FROM_SOURCE = os.environ.get("INSTALL_LIBRARY_FROM_SOURCE", False) in ( + "True", + "true", +) + +# Error if a python version is missing +nox.options.error_on_missing_interpreters = True + +# +# Style Checks +# + + +# Linting with flake8. +# +# We ignore the following rules: +# E203: whitespace before ‘:’ +# E266: too many leading ‘#’ for block comment +# E501: line too long +# I202: Additional newline in a section of imports +# +# We also need to specify the rules which are ignored by default: +# ['E226', 'W504', 'E126', 'E123', 'W503', 'E24', 'E704', 'E121'] +FLAKE8_COMMON_ARGS = [ + "--show-source", + "--builtin=gettext", + "--max-complexity=20", + "--exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py", + "--ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202", + "--max-line-length=88", +] + + +@nox.session +def lint(session: nox.sessions.Session) -> None: + if not TEST_CONFIG["enforce_type_hints"]: + session.install("flake8") + else: + session.install("flake8", "flake8-annotations") + + args = FLAKE8_COMMON_ARGS + [ + ".", + ] + session.run("flake8", *args) + + +# +# Black +# + + +@nox.session +def blacken(session: nox.sessions.Session) -> None: + """Run black. Format code to uniform standard.""" + session.install(BLACK_VERSION) + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + session.run("black", *python_files) + + +# +# format = isort + black +# + + +@nox.session +def format(session: nox.sessions.Session) -> None: + """ + Run isort to sort imports. Then run black + to format code to uniform standard. + """ + session.install(BLACK_VERSION, ISORT_VERSION) + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + # Use the --fss option to sort imports using strict alphabetical order. + # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + session.run("isort", "--fss", *python_files) + session.run("black", *python_files) + + +# +# Sample Tests +# + + +PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] + + +def _session_tests( + session: nox.sessions.Session, post_install: Callable = None +) -> None: + # check for presence of tests + test_list = glob.glob("**/*_test.py", recursive=True) + glob.glob( + "**/test_*.py", recursive=True + ) + test_list.extend(glob.glob("**/tests", recursive=True)) + + if len(test_list) == 0: + print("No tests found, skipping directory.") + return + + if TEST_CONFIG["pip_version_override"]: + pip_version = TEST_CONFIG["pip_version_override"] + session.install(f"pip=={pip_version}") + """Runs py.test for a particular project.""" + concurrent_args = [] + if os.path.exists("requirements.txt"): + if os.path.exists("constraints.txt"): + session.install("-r", "requirements.txt", "-c", "constraints.txt") + else: + session.install("-r", "requirements.txt") + with open("requirements.txt") as rfile: + packages = rfile.read() + + if os.path.exists("requirements-test.txt"): + if os.path.exists("constraints-test.txt"): + session.install("-r", "requirements-test.txt", "-c", "constraints-test.txt") + else: + session.install("-r", "requirements-test.txt") + with open("requirements-test.txt") as rtfile: + packages += rtfile.read() + + if INSTALL_LIBRARY_FROM_SOURCE: + session.install("-e", _get_repo_root()) + + if post_install: + post_install(session) + + if "pytest-parallel" in packages: + concurrent_args.extend(["--workers", "auto", "--tests-per-worker", "auto"]) + elif "pytest-xdist" in packages: + concurrent_args.extend(["-n", "auto"]) + + session.run( + "pytest", + *(PYTEST_COMMON_ARGS + session.posargs + concurrent_args), + # Pytest will return 5 when no tests are collected. This can happen + # on travis where slow and flaky tests are excluded. + # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html + success_codes=[0, 5], + env=get_pytest_env_vars(), + ) + + +@nox.session(python=ALL_VERSIONS) +def py(session: nox.sessions.Session) -> None: + """Runs py.test for a sample using the specified version of Python.""" + if session.python in TESTED_VERSIONS: + _session_tests(session) + else: + session.skip( + "SKIPPED: {} tests are disabled for this sample.".format(session.python) + ) + + +# +# Readmegen +# + + +def _get_repo_root() -> Optional[str]: + """Returns the root folder of the project.""" + # Get root of this repository. Assume we don't have directories nested deeper than 10 items. + p = Path(os.getcwd()) + for i in range(10): + if p is None: + break + if Path(p / ".git").exists(): + return str(p) + # .git is not available in repos cloned via Cloud Build + # setup.py is always in the library's root, so use that instead + # https://github.com/googleapis/synthtool/issues/792 + if Path(p / "setup.py").exists(): + return str(p) + p = p.parent + raise Exception("Unable to detect repository root.") + + +GENERATED_READMES = sorted([x for x in Path(".").rglob("*.rst.in")]) + + +@nox.session +@nox.parametrize("path", GENERATED_READMES) +def readmegen(session: nox.sessions.Session, path: str) -> None: + """(Re-)generates the readme for a sample.""" + session.install("jinja2", "pyyaml") + dir_ = os.path.dirname(path) + + if os.path.exists(os.path.join(dir_, "requirements.txt")): + session.install("-r", os.path.join(dir_, "requirements.txt")) + + in_file = os.path.join(dir_, "README.rst.in") + session.run( + "python", _get_repo_root() + "/scripts/readme-gen/readme_gen.py", in_file + ) diff --git a/packages/google-cloud-bigtable/samples/quickstart/requirements-test.txt b/packages/google-cloud-bigtable/samples/quickstart/requirements-test.txt new file mode 100644 index 000000000000..ee4ba018603b --- /dev/null +++ b/packages/google-cloud-bigtable/samples/quickstart/requirements-test.txt @@ -0,0 +1,2 @@ +pytest +pytest-asyncio diff --git a/packages/google-cloud-bigtable/samples/quickstart/requirements.txt b/packages/google-cloud-bigtable/samples/quickstart/requirements.txt new file mode 100644 index 000000000000..730d25dec63f --- /dev/null +++ b/packages/google-cloud-bigtable/samples/quickstart/requirements.txt @@ -0,0 +1 @@ +google-cloud-bigtable==2.35.0 diff --git a/packages/google-cloud-bigtable/samples/quickstart_happybase/README.md b/packages/google-cloud-bigtable/samples/quickstart_happybase/README.md new file mode 100644 index 000000000000..6d4d8871e3cb --- /dev/null +++ b/packages/google-cloud-bigtable/samples/quickstart_happybase/README.md @@ -0,0 +1,52 @@ +[//]: # "This README.md file is auto-generated, all changes to this file will be lost." +[//]: # "To regenerate it, use `python -m synthtool`." + +## Python Samples for Cloud Bigtable + +This directory contains samples for Cloud Bigtable, which may be used as a refererence for how to use this product. +Samples, quickstarts, and other documentation are available at cloud.google.com. + + +### Quickstart using HappyBase + +Demonstrates of Cloud Bigtable using HappyBase. This sample creates a Bigtable client, connects to an instance and then to a table, then closes the connection. + + +Open in Cloud Shell + + +To run this sample: + +1. If this is your first time working with GCP products, you will need to set up [the Cloud SDK][cloud_sdk] or utilize [Google Cloud Shell][gcloud_shell]. This sample may [require authetication][authentication] and you will need to [enable billing][enable_billing]. + +1. Make a fork of this repo and clone the branch locally, then navigate to the sample directory you want to use. + +1. Install the dependencies needed to run the samples. + + pip install -r requirements.txt + +1. Run the sample using + + python main.py + + + +
usage: main.py [-h] [--table TABLE] project_id instance_id
usage: main.py [-h] [--table TABLE] project_id instance_id


positional arguments:
  project_id     Your Cloud Platform project ID.
  instance_id    ID of the Cloud Bigtable instance to connect to.


optional arguments:
  -h, --help     show this help message and exit
  --table TABLE  Existing table used in the quickstart. (default: my-table)browse the source and [report issues][issues]. + +### Contributing +View the [contributing guidelines][contrib_guide], the [Python style guide][py_style] for more information. + +[authentication]: https://cloud.google.com/docs/authentication/getting-started +[enable_billing]:https://cloud.google.com/apis/docs/getting-started#enabling_billing +[client_library_python]: https://googlecloudplatform.github.io/google-cloud-python/ +[issues]: https://github.com/GoogleCloudPlatform/google-cloud-python/issues +[contrib_guide]: https://github.com/googleapis/google-cloud-python/blob/main/CONTRIBUTING.rst +[py_style]: http://google.github.io/styleguide/pyguide.html +[cloud_sdk]: https://cloud.google.com/sdk/docs +[gcloud_shell]: https://cloud.google.com/shell/docs +[gcloud_shell]: https://cloud.google.com/shell/docs diff --git a/packages/google-cloud-bigtable/samples/quickstart_happybase/__init__.py b/packages/google-cloud-bigtable/samples/quickstart_happybase/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-cloud-bigtable/samples/quickstart_happybase/main.py b/packages/google-cloud-bigtable/samples/quickstart_happybase/main.py new file mode 100644 index 000000000000..6e474d141201 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/quickstart_happybase/main.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python + +# Copyright 2018 Google Inc. +# +# 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. +# [START bigtable_quickstart_happybase] +import argparse + +from google.cloud import bigtable, happybase + + +def main(project_id="project-id", instance_id="instance-id", table_id="my-table"): + # Creates a Bigtable client + client = bigtable.Client(project=project_id) + + # Connect to an existing instance:my-bigtable-instance + instance = client.instance(instance_id) + + connection = happybase.Connection(instance=instance) + + try: + # Connect to an existing table:my-table + table = connection.table(table_id) + + key = "r1" + row = table.row(key.encode("utf-8")) + + column = "cf1:c1".encode("utf-8") + value = row[column].decode("utf-8") + print("Row key: {}\nData: {}".format(key, value)) + + finally: + connection.close() + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description=__doc__, formatter_class=argparse.ArgumentDefaultsHelpFormatter + ) + parser.add_argument("project_id", help="Your Cloud Platform project ID.") + parser.add_argument( + "instance_id", help="ID of the Cloud Bigtable instance to connect to." + ) + parser.add_argument( + "--table", help="Existing table used in the quickstart.", default="my-table" + ) + + args = parser.parse_args() + main(args.project_id, args.instance_id, args.table) +# [END bigtable_quickstart_happybase] diff --git a/packages/google-cloud-bigtable/samples/quickstart_happybase/main_test.py b/packages/google-cloud-bigtable/samples/quickstart_happybase/main_test.py new file mode 100644 index 000000000000..0f0d1ecf5f5f --- /dev/null +++ b/packages/google-cloud-bigtable/samples/quickstart_happybase/main_test.py @@ -0,0 +1,47 @@ +# Copyright 2018 Google Inc. +# +# 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 uuid + +import pytest + +from ..utils import create_table_cm +from .main import main + +PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"] +BIGTABLE_INSTANCE = os.environ["BIGTABLE_INSTANCE"] +TABLE_ID = f"quickstart-hb-test-{str(uuid.uuid4())[:16]}" + + +@pytest.fixture() +def table(): + column_family_id = "cf1" + column_families = {column_family_id: None} + with create_table_cm( + PROJECT, BIGTABLE_INSTANCE, TABLE_ID, column_families + ) as table: + row = table.direct_row("r1") + row.set_cell(column_family_id, "c1", "test-value") + row.commit() + + yield TABLE_ID + + +def test_main(capsys, table): + table_id = table + main(PROJECT, BIGTABLE_INSTANCE, table_id) + + out, _ = capsys.readouterr() + assert "Row key: r1\nData: test-value\n" in out diff --git a/packages/google-cloud-bigtable/samples/quickstart_happybase/noxfile.py b/packages/google-cloud-bigtable/samples/quickstart_happybase/noxfile.py new file mode 100644 index 000000000000..c0e60097b353 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/quickstart_happybase/noxfile.py @@ -0,0 +1,292 @@ +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import print_function + +import glob +import os +import sys +from pathlib import Path +from typing import Callable, Dict, Optional + +import nox + +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING +# DO NOT EDIT THIS FILE EVER! +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING + +BLACK_VERSION = "black==22.3.0" +ISORT_VERSION = "isort==5.10.1" + +# Copy `noxfile_config.py` to your directory and modify it instead. + +# `TEST_CONFIG` dict is a configuration hook that allows users to +# modify the test configurations. The values here should be in sync +# with `noxfile_config.py`. Users will copy `noxfile_config.py` into +# their directory and modify it. + +TEST_CONFIG = { + # You can opt out from the test for specific Python versions. + "ignored_versions": [], + # Old samples are opted out of enforcing Python type hints + # All new samples should feature them + "enforce_type_hints": False, + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", + # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + # If you need to use a specific version of pip, + # change pip_version_override to the string representation + # of the version number, for example, "20.2.4" + "pip_version_override": None, + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + "envs": {}, +} + + +try: + # Ensure we can import noxfile_config in the project's directory. + sys.path.append(".") + from noxfile_config import TEST_CONFIG_OVERRIDE +except ImportError as e: + print("No user noxfile_config found: detail: {}".format(e)) + TEST_CONFIG_OVERRIDE = {} + +# Update the TEST_CONFIG with the user supplied values. +TEST_CONFIG.update(TEST_CONFIG_OVERRIDE) + + +def get_pytest_env_vars() -> Dict[str, str]: + """Returns a dict for pytest invocation.""" + ret = {} + + # Override the GCLOUD_PROJECT and the alias. + env_key = TEST_CONFIG["gcloud_project_env"] + # This should error out if not set. + ret["GOOGLE_CLOUD_PROJECT"] = os.environ[env_key] + + # Apply user supplied envs. + ret.update(TEST_CONFIG["envs"]) + return ret + + +# DO NOT EDIT - automatically generated. +# All versions used to test samples. +ALL_VERSIONS = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + +# Any default versions that should be ignored. +IGNORED_VERSIONS = TEST_CONFIG["ignored_versions"] + +TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) + +INSTALL_LIBRARY_FROM_SOURCE = os.environ.get("INSTALL_LIBRARY_FROM_SOURCE", False) in ( + "True", + "true", +) + +# Error if a python version is missing +nox.options.error_on_missing_interpreters = True + +# +# Style Checks +# + + +# Linting with flake8. +# +# We ignore the following rules: +# E203: whitespace before ‘:’ +# E266: too many leading ‘#’ for block comment +# E501: line too long +# I202: Additional newline in a section of imports +# +# We also need to specify the rules which are ignored by default: +# ['E226', 'W504', 'E126', 'E123', 'W503', 'E24', 'E704', 'E121'] +FLAKE8_COMMON_ARGS = [ + "--show-source", + "--builtin=gettext", + "--max-complexity=20", + "--exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py", + "--ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202", + "--max-line-length=88", +] + + +@nox.session +def lint(session: nox.sessions.Session) -> None: + if not TEST_CONFIG["enforce_type_hints"]: + session.install("flake8") + else: + session.install("flake8", "flake8-annotations") + + args = FLAKE8_COMMON_ARGS + [ + ".", + ] + session.run("flake8", *args) + + +# +# Black +# + + +@nox.session +def blacken(session: nox.sessions.Session) -> None: + """Run black. Format code to uniform standard.""" + session.install(BLACK_VERSION) + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + session.run("black", *python_files) + + +# +# format = isort + black +# + + +@nox.session +def format(session: nox.sessions.Session) -> None: + """ + Run isort to sort imports. Then run black + to format code to uniform standard. + """ + session.install(BLACK_VERSION, ISORT_VERSION) + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + # Use the --fss option to sort imports using strict alphabetical order. + # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + session.run("isort", "--fss", *python_files) + session.run("black", *python_files) + + +# +# Sample Tests +# + + +PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] + + +def _session_tests( + session: nox.sessions.Session, post_install: Callable = None +) -> None: + # check for presence of tests + test_list = glob.glob("**/*_test.py", recursive=True) + glob.glob( + "**/test_*.py", recursive=True + ) + test_list.extend(glob.glob("**/tests", recursive=True)) + + if len(test_list) == 0: + print("No tests found, skipping directory.") + return + + if TEST_CONFIG["pip_version_override"]: + pip_version = TEST_CONFIG["pip_version_override"] + session.install(f"pip=={pip_version}") + """Runs py.test for a particular project.""" + concurrent_args = [] + if os.path.exists("requirements.txt"): + if os.path.exists("constraints.txt"): + session.install("-r", "requirements.txt", "-c", "constraints.txt") + else: + session.install("-r", "requirements.txt") + with open("requirements.txt") as rfile: + packages = rfile.read() + + if os.path.exists("requirements-test.txt"): + if os.path.exists("constraints-test.txt"): + session.install("-r", "requirements-test.txt", "-c", "constraints-test.txt") + else: + session.install("-r", "requirements-test.txt") + with open("requirements-test.txt") as rtfile: + packages += rtfile.read() + + if INSTALL_LIBRARY_FROM_SOURCE: + session.install("-e", _get_repo_root()) + + if post_install: + post_install(session) + + if "pytest-parallel" in packages: + concurrent_args.extend(["--workers", "auto", "--tests-per-worker", "auto"]) + elif "pytest-xdist" in packages: + concurrent_args.extend(["-n", "auto"]) + + session.run( + "pytest", + *(PYTEST_COMMON_ARGS + session.posargs + concurrent_args), + # Pytest will return 5 when no tests are collected. This can happen + # on travis where slow and flaky tests are excluded. + # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html + success_codes=[0, 5], + env=get_pytest_env_vars(), + ) + + +@nox.session(python=ALL_VERSIONS) +def py(session: nox.sessions.Session) -> None: + """Runs py.test for a sample using the specified version of Python.""" + if session.python in TESTED_VERSIONS: + _session_tests(session) + else: + session.skip( + "SKIPPED: {} tests are disabled for this sample.".format(session.python) + ) + + +# +# Readmegen +# + + +def _get_repo_root() -> Optional[str]: + """Returns the root folder of the project.""" + # Get root of this repository. Assume we don't have directories nested deeper than 10 items. + p = Path(os.getcwd()) + for i in range(10): + if p is None: + break + if Path(p / ".git").exists(): + return str(p) + # .git is not available in repos cloned via Cloud Build + # setup.py is always in the library's root, so use that instead + # https://github.com/googleapis/synthtool/issues/792 + if Path(p / "setup.py").exists(): + return str(p) + p = p.parent + raise Exception("Unable to detect repository root.") + + +GENERATED_READMES = sorted([x for x in Path(".").rglob("*.rst.in")]) + + +@nox.session +@nox.parametrize("path", GENERATED_READMES) +def readmegen(session: nox.sessions.Session, path: str) -> None: + """(Re-)generates the readme for a sample.""" + session.install("jinja2", "pyyaml") + dir_ = os.path.dirname(path) + + if os.path.exists(os.path.join(dir_, "requirements.txt")): + session.install("-r", os.path.join(dir_, "requirements.txt")) + + in_file = os.path.join(dir_, "README.rst.in") + session.run( + "python", _get_repo_root() + "/scripts/readme-gen/readme_gen.py", in_file + ) diff --git a/packages/google-cloud-bigtable/samples/quickstart_happybase/requirements-test.txt b/packages/google-cloud-bigtable/samples/quickstart_happybase/requirements-test.txt new file mode 100644 index 000000000000..55b033e901cd --- /dev/null +++ b/packages/google-cloud-bigtable/samples/quickstart_happybase/requirements-test.txt @@ -0,0 +1 @@ +pytest \ No newline at end of file diff --git a/packages/google-cloud-bigtable/samples/quickstart_happybase/requirements.txt b/packages/google-cloud-bigtable/samples/quickstart_happybase/requirements.txt new file mode 100644 index 000000000000..dc1a04f30378 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/quickstart_happybase/requirements.txt @@ -0,0 +1,2 @@ +google-cloud-happybase==0.33.0 +six==1.17.0 # See https://github.com/googleapis/google-cloud-python-happybase/issues/128 diff --git a/packages/google-cloud-bigtable/samples/snippets/README.md b/packages/google-cloud-bigtable/samples/snippets/README.md new file mode 100644 index 000000000000..7c0dd4463214 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/README.md @@ -0,0 +1,33 @@ +[//]: # "This README.md file is auto-generated, all changes to this file will be lost." +[//]: # "To regenerate it, use `python -m synthtool`." + +## Python Samples for Cloud Bigtable + +This directory contains samples for Cloud Bigtable, which may be used as a reference for how to use this product. +Samples, quickstarts, and other documentation are available at [cloud.google.com](https://cloud.google.com/bigtable). + + +### Snippets + +This folder contains snippets for Python Cloud Bigtable. + + + + +## Additional Information + +You can read the documentation for more details on API usage and use GitHub +to [browse the source](https://github.com/googleapis/python-bigtable) and [report issues][issues]. + +### Contributing +View the [contributing guidelines][contrib_guide], the [Python style guide][py_style] for more information. + +[authentication]: https://cloud.google.com/docs/authentication/getting-started +[enable_billing]:https://cloud.google.com/apis/docs/getting-started#enabling_billing +[client_library_python]: https://googlecloudplatform.github.io/google-cloud-python/ +[issues]: https://github.com/GoogleCloudPlatform/google-cloud-python/issues +[contrib_guide]: https://github.com/googleapis/google-cloud-python/blob/main/CONTRIBUTING.rst +[py_style]: http://google.github.io/styleguide/pyguide.html +[cloud_sdk]: https://cloud.google.com/sdk/docs +[gcloud_shell]: https://cloud.google.com/shell/docs +[gcloud_shell]: https://cloud.google.com/shell/docs diff --git a/packages/google-cloud-bigtable/samples/snippets/__init__.py b/packages/google-cloud-bigtable/samples/snippets/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-cloud-bigtable/samples/snippets/data_client/__init__.py b/packages/google-cloud-bigtable/samples/snippets/data_client/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-cloud-bigtable/samples/snippets/data_client/data_client_snippets_async.py b/packages/google-cloud-bigtable/samples/snippets/data_client/data_client_snippets_async.py new file mode 100644 index 000000000000..2d5a7e39521a --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/data_client/data_client_snippets_async.py @@ -0,0 +1,315 @@ +#!/usr/bin/env python + +# Copyright 2024, 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. + + +async def write_simple(table): + # [START bigtable_async_write_simple] + from google.cloud.bigtable.data import BigtableDataClientAsync, SetCell + + async def write_simple(project_id, instance_id, table_id): + async with BigtableDataClientAsync(project=project_id) as client: + async with client.get_table(instance_id, table_id) as table: + family_id = "stats_summary" + row_key = b"phone#4c410523#20190501" + + cell_mutation = SetCell(family_id, "connected_cell", 1) + wifi_mutation = SetCell(family_id, "connected_wifi", 1) + os_mutation = SetCell(family_id, "os_build", "PQ2A.190405.003") + + await table.mutate_row(row_key, cell_mutation) + await table.mutate_row(row_key, wifi_mutation) + await table.mutate_row(row_key, os_mutation) + + # [END bigtable_async_write_simple] + await write_simple(table.client.project, table.instance_id, table.table_id) + + +async def write_batch(table): + # [START bigtable_async_writes_batch] + from google.cloud.bigtable.data import BigtableDataClientAsync + from google.cloud.bigtable.data.exceptions import MutationsExceptionGroup + from google.cloud.bigtable.data.mutations import RowMutationEntry, SetCell + + async def write_batch(project_id, instance_id, table_id): + async with BigtableDataClientAsync(project=project_id) as client: + async with client.get_table(instance_id, table_id) as table: + family_id = "stats_summary" + try: + async with table.mutations_batcher() as batcher: + mutation_list = [ + SetCell(family_id, "connected_cell", 1), + SetCell(family_id, "connected_wifi", 1), + SetCell(family_id, "os_build", "12155.0.0-rc1"), + ] + # awaiting the batcher.append method adds the RowMutationEntry + # to the batcher's queue to be written in the next flush. + await batcher.append( + RowMutationEntry("tablet#a0b81f74#20190501", mutation_list) + ) + await batcher.append( + RowMutationEntry("tablet#a0b81f74#20190502", mutation_list) + ) + except MutationsExceptionGroup as e: + # MutationsExceptionGroup contains a FailedMutationEntryError for + # each mutation that failed. + for sub_exception in e.exceptions: + failed_entry: RowMutationEntry = sub_exception.entry + cause: Exception = sub_exception.__cause__ + print( + f"Failed mutation: {failed_entry.row_key} with error: {cause!r}" + ) + + # [END bigtable_async_writes_batch] + await write_batch(table.client.project, table.instance_id, table.table_id) + + +async def write_increment(table): + # [START bigtable_async_write_increment] + from google.cloud.bigtable.data import BigtableDataClientAsync + from google.cloud.bigtable.data.read_modify_write_rules import IncrementRule + + async def write_increment(project_id, instance_id, table_id): + async with BigtableDataClientAsync(project=project_id) as client: + async with client.get_table(instance_id, table_id) as table: + family_id = "stats_summary" + row_key = "phone#4c410523#20190501" + + # Decrement the connected_wifi value by 1. + increment_rule = IncrementRule( + family_id, "connected_wifi", increment_amount=-1 + ) + result_row = await table.read_modify_write_row(row_key, increment_rule) + + # check result + cell = result_row[0] + print(f"{cell.row_key} value: {int(cell)}") + + # [END bigtable_async_write_increment] + await write_increment(table.client.project, table.instance_id, table.table_id) + + +async def write_conditional(table): + # [START bigtable_async_writes_conditional] + from google.cloud.bigtable.data import BigtableDataClientAsync, SetCell, row_filters + + async def write_conditional(project_id, instance_id, table_id): + async with BigtableDataClientAsync(project=project_id) as client: + async with client.get_table(instance_id, table_id) as table: + family_id = "stats_summary" + row_key = "phone#4c410523#20190501" + + row_filter = row_filters.RowFilterChain( + filters=[ + row_filters.FamilyNameRegexFilter(family_id), + row_filters.ColumnQualifierRegexFilter("os_build"), + row_filters.ValueRegexFilter("PQ2A\\..*"), + ] + ) + + if_true = SetCell(family_id, "os_name", "android") + result = await table.check_and_mutate_row( + row_key, + row_filter, + true_case_mutations=if_true, + false_case_mutations=None, + ) + if result is True: + print("The row os_name was set to android") + + # [END bigtable_async_writes_conditional] + await write_conditional(table.client.project, table.instance_id, table.table_id) + + +async def write_aggregate(table): + # [START bigtable_async_write_aggregate] + import time + + from google.cloud.bigtable.data import BigtableDataClientAsync + from google.cloud.bigtable.data.exceptions import MutationsExceptionGroup + from google.cloud.bigtable.data.mutations import AddToCell, RowMutationEntry + + async def write_aggregate(project_id, instance_id, table_id): + """Increments a value in a Bigtable table using AddToCell mutation.""" + async with BigtableDataClientAsync(project=project_id) as client: + table = client.get_table(instance_id, table_id) + row_key = "unique_device_ids_1" + try: + async with table.mutations_batcher() as batcher: + # The AddToCell mutation increments the value of a cell. + # The `counters` family must be set up to be an aggregate + # family with an int64 input type. + reading = AddToCell( + family="counters", + qualifier="odometer", + value=32304, + # Convert nanoseconds to microseconds + timestamp_micros=time.time_ns() // 1000, + ) + await batcher.append( + RowMutationEntry(row_key.encode("utf-8"), [reading]) + ) + except MutationsExceptionGroup as e: + # MutationsExceptionGroup contains a FailedMutationEntryError for + # each mutation that failed. + for sub_exception in e.exceptions: + failed_entry: RowMutationEntry = sub_exception.entry + cause: Exception = sub_exception.__cause__ + print( + f"Failed mutation for row {failed_entry.row_key!r} with error: {cause!r}" + ) + + # [END bigtable_async_write_aggregate] + await write_aggregate(table.client.project, table.instance_id, table.table_id) + + +async def read_row(table): + # [START bigtable_async_reads_row] + from google.cloud.bigtable.data import BigtableDataClientAsync + + async def read_row(project_id, instance_id, table_id): + async with BigtableDataClientAsync(project=project_id) as client: + async with client.get_table(instance_id, table_id) as table: + row_key = "phone#4c410523#20190501" + row = await table.read_row(row_key) + print(row) + + # [END bigtable_async_reads_row] + await read_row(table.client.project, table.instance_id, table.table_id) + + +async def read_row_partial(table): + # [START bigtable_async_reads_row_partial] + from google.cloud.bigtable.data import BigtableDataClientAsync, row_filters + + async def read_row_partial(project_id, instance_id, table_id): + async with BigtableDataClientAsync(project=project_id) as client: + async with client.get_table(instance_id, table_id) as table: + row_key = "phone#4c410523#20190501" + col_filter = row_filters.ColumnQualifierRegexFilter(b"os_build") + + row = await table.read_row(row_key, row_filter=col_filter) + print(row) + + # [END bigtable_async_reads_row_partial] + await read_row_partial(table.client.project, table.instance_id, table.table_id) + + +async def read_rows_multiple(table): + # [START bigtable_async_reads_rows] + from google.cloud.bigtable.data import BigtableDataClientAsync, ReadRowsQuery + + async def read_rows(project_id, instance_id, table_id): + async with BigtableDataClientAsync(project=project_id) as client: + async with client.get_table(instance_id, table_id) as table: + query = ReadRowsQuery( + row_keys=[b"phone#4c410523#20190501", b"phone#4c410523#20190502"] + ) + async for row in await table.read_rows_stream(query): + print(row) + + # [END bigtable_async_reads_rows] + await read_rows(table.client.project, table.instance_id, table.table_id) + + +async def read_row_range(table): + # [START bigtable_async_reads_row_range] + from google.cloud.bigtable.data import ( + BigtableDataClientAsync, + ReadRowsQuery, + RowRange, + ) + + async def read_row_range(project_id, instance_id, table_id): + async with BigtableDataClientAsync(project=project_id) as client: + async with client.get_table(instance_id, table_id) as table: + row_range = RowRange( + start_key=b"phone#4c410523#20190501", + end_key=b"phone#4c410523#201906201", + ) + query = ReadRowsQuery(row_ranges=[row_range]) + + async for row in await table.read_rows_stream(query): + print(row) + + # [END bigtable_async_reads_row_range] + await read_row_range(table.client.project, table.instance_id, table.table_id) + + +async def read_with_prefix(table): + # [START bigtable_async_reads_prefix] + from google.cloud.bigtable.data import ( + BigtableDataClientAsync, + ReadRowsQuery, + RowRange, + ) + + async def read_prefix(project_id, instance_id, table_id): + async with BigtableDataClientAsync(project=project_id) as client: + async with client.get_table(instance_id, table_id) as table: + prefix = "phone#" + end_key = prefix[:-1] + chr(ord(prefix[-1]) + 1) + prefix_range = RowRange(start_key=prefix, end_key=end_key) + query = ReadRowsQuery(row_ranges=[prefix_range]) + + async for row in await table.read_rows_stream(query): + print(row) + + # [END bigtable_async_reads_prefix] + await read_prefix(table.client.project, table.instance_id, table.table_id) + + +async def read_with_filter(table): + # [START bigtable_async_reads_filter] + from google.cloud.bigtable.data import ( + BigtableDataClientAsync, + ReadRowsQuery, + row_filters, + ) + + async def read_with_filter(project_id, instance_id, table_id): + async with BigtableDataClientAsync(project=project_id) as client: + async with client.get_table(instance_id, table_id) as table: + row_filter = row_filters.ValueRegexFilter(b"PQ2A.*$") + query = ReadRowsQuery(row_filter=row_filter) + + async for row in await table.read_rows_stream(query): + print(row) + + # [END bigtable_async_reads_filter] + await read_with_filter(table.client.project, table.instance_id, table.table_id) + + +async def execute_query(table): + # [START bigtable_async_execute_query] + from google.cloud.bigtable.data import BigtableDataClientAsync + + async def execute_query(project_id, instance_id, table_id): + async with BigtableDataClientAsync(project=project_id) as client: + query = ( + "SELECT _key, stats_summary['os_build'], " + "stats_summary['connected_cell'], " + "stats_summary['connected_wifi'] " + f"from `{table_id}` WHERE _key=@row_key" + ) + result = await client.execute_query( + query, + instance_id, + parameters={"row_key": b"phone#4c410523#20190501"}, + ) + results = [r async for r in result] + print(results) + + # [END bigtable_async_execute_query] + await execute_query(table.client.project, table.instance_id, table.table_id) diff --git a/packages/google-cloud-bigtable/samples/snippets/data_client/data_client_snippets_async_test.py b/packages/google-cloud-bigtable/samples/snippets/data_client/data_client_snippets_async_test.py new file mode 100644 index 000000000000..6742d2260a83 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/data_client/data_client_snippets_async_test.py @@ -0,0 +1,117 @@ +# Copyright 2024, 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 uuid + +import pytest +import pytest_asyncio + +from ...utils import create_table_cm +from . import data_client_snippets_async as data_snippets + +PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"] +BIGTABLE_INSTANCE = os.environ["BIGTABLE_INSTANCE"] +TABLE_ID = f"data-client-{str(uuid.uuid4())[:16]}" + + +@pytest.fixture(scope="session") +def column_family_config(): + from google.cloud.bigtable_admin_v2 import types + + int_aggregate_type = types.Type.Aggregate( + input_type=types.Type(int64_type={"encoding": {"big_endian_bytes": {}}}), + sum={}, + ) + + return { + "family": types.ColumnFamily(), + "stats_summary": types.ColumnFamily(), + "counters": types.ColumnFamily( + value_type=types.Type(aggregate_type=int_aggregate_type) + ), + } + + +@pytest.fixture(scope="session") +def table_id(column_family_config): + with create_table_cm(PROJECT, BIGTABLE_INSTANCE, TABLE_ID, column_family_config): + yield TABLE_ID + + +@pytest_asyncio.fixture +async def table(table_id): + from google.cloud.bigtable.data import BigtableDataClientAsync + + async with BigtableDataClientAsync(project=PROJECT) as client: + async with client.get_table(BIGTABLE_INSTANCE, table_id) as table: + yield table + + +@pytest.mark.asyncio +async def test_write_simple(table): + await data_snippets.write_simple(table) + + +@pytest.mark.asyncio +async def test_write_batch(table): + await data_snippets.write_batch(table) + + +@pytest.mark.asyncio +async def test_write_increment(table): + await data_snippets.write_increment(table) + + +@pytest.mark.asyncio +async def test_write_conditional(table): + await data_snippets.write_conditional(table) + + +@pytest.mark.asyncio +async def test_write_aggregate(table): + await data_snippets.write_aggregate(table) + + +@pytest.mark.asyncio +async def test_read_row(table): + await data_snippets.read_row(table) + + +@pytest.mark.asyncio +async def test_read_row_partial(table): + await data_snippets.read_row_partial(table) + + +@pytest.mark.asyncio +async def test_read_rows_multiple(table): + await data_snippets.read_rows_multiple(table) + + +@pytest.mark.asyncio +async def test_read_row_range(table): + await data_snippets.read_row_range(table) + + +@pytest.mark.asyncio +async def test_read_with_prefix(table): + await data_snippets.read_with_prefix(table) + + +@pytest.mark.asyncio +async def test_read_with_filter(table): + await data_snippets.read_with_filter(table) + + +@pytest.mark.asyncio +async def test_execute_query(table): + await data_snippets.execute_query(table) diff --git a/packages/google-cloud-bigtable/samples/snippets/data_client/noxfile.py b/packages/google-cloud-bigtable/samples/snippets/data_client/noxfile.py new file mode 100644 index 000000000000..c0e60097b353 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/data_client/noxfile.py @@ -0,0 +1,292 @@ +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import print_function + +import glob +import os +import sys +from pathlib import Path +from typing import Callable, Dict, Optional + +import nox + +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING +# DO NOT EDIT THIS FILE EVER! +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING + +BLACK_VERSION = "black==22.3.0" +ISORT_VERSION = "isort==5.10.1" + +# Copy `noxfile_config.py` to your directory and modify it instead. + +# `TEST_CONFIG` dict is a configuration hook that allows users to +# modify the test configurations. The values here should be in sync +# with `noxfile_config.py`. Users will copy `noxfile_config.py` into +# their directory and modify it. + +TEST_CONFIG = { + # You can opt out from the test for specific Python versions. + "ignored_versions": [], + # Old samples are opted out of enforcing Python type hints + # All new samples should feature them + "enforce_type_hints": False, + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", + # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + # If you need to use a specific version of pip, + # change pip_version_override to the string representation + # of the version number, for example, "20.2.4" + "pip_version_override": None, + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + "envs": {}, +} + + +try: + # Ensure we can import noxfile_config in the project's directory. + sys.path.append(".") + from noxfile_config import TEST_CONFIG_OVERRIDE +except ImportError as e: + print("No user noxfile_config found: detail: {}".format(e)) + TEST_CONFIG_OVERRIDE = {} + +# Update the TEST_CONFIG with the user supplied values. +TEST_CONFIG.update(TEST_CONFIG_OVERRIDE) + + +def get_pytest_env_vars() -> Dict[str, str]: + """Returns a dict for pytest invocation.""" + ret = {} + + # Override the GCLOUD_PROJECT and the alias. + env_key = TEST_CONFIG["gcloud_project_env"] + # This should error out if not set. + ret["GOOGLE_CLOUD_PROJECT"] = os.environ[env_key] + + # Apply user supplied envs. + ret.update(TEST_CONFIG["envs"]) + return ret + + +# DO NOT EDIT - automatically generated. +# All versions used to test samples. +ALL_VERSIONS = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + +# Any default versions that should be ignored. +IGNORED_VERSIONS = TEST_CONFIG["ignored_versions"] + +TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) + +INSTALL_LIBRARY_FROM_SOURCE = os.environ.get("INSTALL_LIBRARY_FROM_SOURCE", False) in ( + "True", + "true", +) + +# Error if a python version is missing +nox.options.error_on_missing_interpreters = True + +# +# Style Checks +# + + +# Linting with flake8. +# +# We ignore the following rules: +# E203: whitespace before ‘:’ +# E266: too many leading ‘#’ for block comment +# E501: line too long +# I202: Additional newline in a section of imports +# +# We also need to specify the rules which are ignored by default: +# ['E226', 'W504', 'E126', 'E123', 'W503', 'E24', 'E704', 'E121'] +FLAKE8_COMMON_ARGS = [ + "--show-source", + "--builtin=gettext", + "--max-complexity=20", + "--exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py", + "--ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202", + "--max-line-length=88", +] + + +@nox.session +def lint(session: nox.sessions.Session) -> None: + if not TEST_CONFIG["enforce_type_hints"]: + session.install("flake8") + else: + session.install("flake8", "flake8-annotations") + + args = FLAKE8_COMMON_ARGS + [ + ".", + ] + session.run("flake8", *args) + + +# +# Black +# + + +@nox.session +def blacken(session: nox.sessions.Session) -> None: + """Run black. Format code to uniform standard.""" + session.install(BLACK_VERSION) + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + session.run("black", *python_files) + + +# +# format = isort + black +# + + +@nox.session +def format(session: nox.sessions.Session) -> None: + """ + Run isort to sort imports. Then run black + to format code to uniform standard. + """ + session.install(BLACK_VERSION, ISORT_VERSION) + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + # Use the --fss option to sort imports using strict alphabetical order. + # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + session.run("isort", "--fss", *python_files) + session.run("black", *python_files) + + +# +# Sample Tests +# + + +PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] + + +def _session_tests( + session: nox.sessions.Session, post_install: Callable = None +) -> None: + # check for presence of tests + test_list = glob.glob("**/*_test.py", recursive=True) + glob.glob( + "**/test_*.py", recursive=True + ) + test_list.extend(glob.glob("**/tests", recursive=True)) + + if len(test_list) == 0: + print("No tests found, skipping directory.") + return + + if TEST_CONFIG["pip_version_override"]: + pip_version = TEST_CONFIG["pip_version_override"] + session.install(f"pip=={pip_version}") + """Runs py.test for a particular project.""" + concurrent_args = [] + if os.path.exists("requirements.txt"): + if os.path.exists("constraints.txt"): + session.install("-r", "requirements.txt", "-c", "constraints.txt") + else: + session.install("-r", "requirements.txt") + with open("requirements.txt") as rfile: + packages = rfile.read() + + if os.path.exists("requirements-test.txt"): + if os.path.exists("constraints-test.txt"): + session.install("-r", "requirements-test.txt", "-c", "constraints-test.txt") + else: + session.install("-r", "requirements-test.txt") + with open("requirements-test.txt") as rtfile: + packages += rtfile.read() + + if INSTALL_LIBRARY_FROM_SOURCE: + session.install("-e", _get_repo_root()) + + if post_install: + post_install(session) + + if "pytest-parallel" in packages: + concurrent_args.extend(["--workers", "auto", "--tests-per-worker", "auto"]) + elif "pytest-xdist" in packages: + concurrent_args.extend(["-n", "auto"]) + + session.run( + "pytest", + *(PYTEST_COMMON_ARGS + session.posargs + concurrent_args), + # Pytest will return 5 when no tests are collected. This can happen + # on travis where slow and flaky tests are excluded. + # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html + success_codes=[0, 5], + env=get_pytest_env_vars(), + ) + + +@nox.session(python=ALL_VERSIONS) +def py(session: nox.sessions.Session) -> None: + """Runs py.test for a sample using the specified version of Python.""" + if session.python in TESTED_VERSIONS: + _session_tests(session) + else: + session.skip( + "SKIPPED: {} tests are disabled for this sample.".format(session.python) + ) + + +# +# Readmegen +# + + +def _get_repo_root() -> Optional[str]: + """Returns the root folder of the project.""" + # Get root of this repository. Assume we don't have directories nested deeper than 10 items. + p = Path(os.getcwd()) + for i in range(10): + if p is None: + break + if Path(p / ".git").exists(): + return str(p) + # .git is not available in repos cloned via Cloud Build + # setup.py is always in the library's root, so use that instead + # https://github.com/googleapis/synthtool/issues/792 + if Path(p / "setup.py").exists(): + return str(p) + p = p.parent + raise Exception("Unable to detect repository root.") + + +GENERATED_READMES = sorted([x for x in Path(".").rglob("*.rst.in")]) + + +@nox.session +@nox.parametrize("path", GENERATED_READMES) +def readmegen(session: nox.sessions.Session, path: str) -> None: + """(Re-)generates the readme for a sample.""" + session.install("jinja2", "pyyaml") + dir_ = os.path.dirname(path) + + if os.path.exists(os.path.join(dir_, "requirements.txt")): + session.install("-r", os.path.join(dir_, "requirements.txt")) + + in_file = os.path.join(dir_, "README.rst.in") + session.run( + "python", _get_repo_root() + "/scripts/readme-gen/readme_gen.py", in_file + ) diff --git a/packages/google-cloud-bigtable/samples/snippets/data_client/requirements-test.txt b/packages/google-cloud-bigtable/samples/snippets/data_client/requirements-test.txt new file mode 100644 index 000000000000..ee4ba018603b --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/data_client/requirements-test.txt @@ -0,0 +1,2 @@ +pytest +pytest-asyncio diff --git a/packages/google-cloud-bigtable/samples/snippets/data_client/requirements.txt b/packages/google-cloud-bigtable/samples/snippets/data_client/requirements.txt new file mode 100644 index 000000000000..730d25dec63f --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/data_client/requirements.txt @@ -0,0 +1 @@ +google-cloud-bigtable==2.35.0 diff --git a/packages/google-cloud-bigtable/samples/snippets/deletes/__init__.py b/packages/google-cloud-bigtable/samples/snippets/deletes/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-cloud-bigtable/samples/snippets/deletes/deletes_async_test.py b/packages/google-cloud-bigtable/samples/snippets/deletes/deletes_async_test.py new file mode 100644 index 000000000000..f5e93995cff9 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/deletes/deletes_async_test.py @@ -0,0 +1,281 @@ +# Copyright 2024, 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 datetime +import os +import uuid +from typing import AsyncGenerator + +import pytest +import pytest_asyncio +from google.cloud._helpers import _microseconds_from_datetime + +from ...utils import create_table_cm +from . import deletes_snippets_async + +PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"] +BIGTABLE_INSTANCE = os.environ["BIGTABLE_INSTANCE"] +TABLE_ID = f"mobile-time-series-deletes-async-{str(uuid.uuid4())[:16]}" + + +@pytest.fixture(scope="module") +def event_loop(): + import asyncio + + loop = asyncio.get_event_loop_policy().new_event_loop() + yield loop + loop.close() + + +@pytest_asyncio.fixture(scope="module", autouse=True) +async def table_id() -> AsyncGenerator[str, None]: + with create_table_cm( + PROJECT, + BIGTABLE_INSTANCE, + TABLE_ID, + {"stats_summary": None, "cell_plan": None}, + verbose=False, + ): + await _populate_table(TABLE_ID) + yield TABLE_ID + + +async def _populate_table(table_id): + from google.cloud.bigtable.data import ( + BigtableDataClientAsync, + RowMutationEntry, + SetCell, + ) + + timestamp = datetime.datetime(2019, 5, 1) + timestamp_minus_hr = timestamp - datetime.timedelta(hours=1) + + async with BigtableDataClientAsync(project=PROJECT) as client: + async with client.get_table(BIGTABLE_INSTANCE, table_id) as table: + async with table.mutations_batcher() as batcher: + await batcher.append( + RowMutationEntry( + "phone#4c410523#20190501", + [ + SetCell( + "stats_summary", + "connected_cell", + 1, + _microseconds_from_datetime(timestamp), + ), + SetCell( + "stats_summary", + "connected_cell", + 1, + _microseconds_from_datetime(timestamp), + ), + SetCell( + "stats_summary", + "connected_wifi", + 1, + _microseconds_from_datetime(timestamp), + ), + SetCell( + "stats_summary", + "os_build", + "PQ2A.190405.003", + _microseconds_from_datetime(timestamp), + ), + SetCell( + "cell_plan", + "data_plan_01gb", + "true", + _microseconds_from_datetime(timestamp_minus_hr), + ), + SetCell( + "cell_plan", + "data_plan_01gb", + "false", + _microseconds_from_datetime(timestamp), + ), + SetCell( + "cell_plan", + "data_plan_05gb", + "true", + _microseconds_from_datetime(timestamp), + ), + ], + ) + ) + await batcher.append( + RowMutationEntry( + "phone#4c410523#20190502", + [ + SetCell( + "stats_summary", + "connected_cell", + 1, + _microseconds_from_datetime(timestamp), + ), + SetCell( + "stats_summary", + "connected_wifi", + 1, + _microseconds_from_datetime(timestamp), + ), + SetCell( + "stats_summary", + "os_build", + "PQ2A.190405.004", + _microseconds_from_datetime(timestamp), + ), + SetCell( + "cell_plan", + "data_plan_05gb", + "true", + _microseconds_from_datetime(timestamp), + ), + ], + ) + ) + await batcher.append( + RowMutationEntry( + "phone#4c410523#20190505", + [ + SetCell( + "stats_summary", + "connected_cell", + 0, + _microseconds_from_datetime(timestamp), + ), + SetCell( + "stats_summary", + "connected_wifi", + 1, + _microseconds_from_datetime(timestamp), + ), + SetCell( + "stats_summary", + "os_build", + "PQ2A.190406.000", + _microseconds_from_datetime(timestamp), + ), + SetCell( + "cell_plan", + "data_plan_05gb", + "true", + _microseconds_from_datetime(timestamp), + ), + ], + ) + ) + await batcher.append( + RowMutationEntry( + "phone#5c10102#20190501", + [ + SetCell( + "stats_summary", + "connected_cell", + 1, + _microseconds_from_datetime(timestamp), + ), + SetCell( + "stats_summary", + "connected_wifi", + 1, + _microseconds_from_datetime(timestamp), + ), + SetCell( + "stats_summary", + "os_build", + "PQ2A.190401.002", + _microseconds_from_datetime(timestamp), + ), + SetCell( + "cell_plan", + "data_plan_10gb", + "true", + _microseconds_from_datetime(timestamp), + ), + ], + ) + ) + await batcher.append( + RowMutationEntry( + "phone#5c10102#20190502", + [ + SetCell( + "stats_summary", + "connected_cell", + 1, + _microseconds_from_datetime(timestamp), + ), + SetCell( + "stats_summary", + "connected_wifi", + 0, + _microseconds_from_datetime(timestamp), + ), + SetCell( + "stats_summary", + "os_build", + "PQ2A.190406.000", + _microseconds_from_datetime(timestamp), + ), + SetCell( + "cell_plan", + "data_plan_10gb", + "true", + _microseconds_from_datetime(timestamp), + ), + ], + ) + ) + + +def assert_output_match(capsys, expected): + out, _ = capsys.readouterr() + assert out == expected + + +@pytest.mark.asyncio +async def test_delete_from_column(capsys, table_id): + await deletes_snippets_async.delete_from_column( + PROJECT, BIGTABLE_INSTANCE, table_id + ) + assert_output_match(capsys, "") + + +@pytest.mark.asyncio +async def test_delete_from_column_family(capsys, table_id): + await deletes_snippets_async.delete_from_column_family( + PROJECT, BIGTABLE_INSTANCE, table_id + ) + assert_output_match(capsys, "") + + +@pytest.mark.asyncio +async def test_delete_from_row(capsys, table_id): + await deletes_snippets_async.delete_from_row(PROJECT, BIGTABLE_INSTANCE, table_id) + assert_output_match(capsys, "") + + +@pytest.mark.asyncio +async def test_streaming_and_batching(capsys, table_id): + await deletes_snippets_async.streaming_and_batching( + PROJECT, BIGTABLE_INSTANCE, table_id + ) + assert_output_match(capsys, "") + + +@pytest.mark.asyncio +async def test_check_and_mutate(capsys, table_id): + await deletes_snippets_async.check_and_mutate(PROJECT, BIGTABLE_INSTANCE, table_id) + assert_output_match(capsys, "") diff --git a/packages/google-cloud-bigtable/samples/snippets/deletes/deletes_snippets.py b/packages/google-cloud-bigtable/samples/snippets/deletes/deletes_snippets.py new file mode 100644 index 000000000000..09f467577732 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/deletes/deletes_snippets.py @@ -0,0 +1,136 @@ +#!/usr/bin/env python + +# Copyright 2022, Google LLC +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# [START bigtable_delete_from_column] +def delete_from_column(project_id, instance_id, table_id): + from google.cloud.bigtable import Client + + client = Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + row = table.row("phone#4c410523#20190501") + row.delete_cell(column_family_id="cell_plan", column="data_plan_01gb") + row.commit() + + +# [END bigtable_delete_from_column] + + +# [START bigtable_delete_from_column_family] +def delete_from_column_family(project_id, instance_id, table_id): + from google.cloud.bigtable import Client + + client = Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + row = table.row("phone#4c410523#20190501") + row.delete_cells(column_family_id="cell_plan", columns=row.ALL_COLUMNS) + row.commit() + + +# [END bigtable_delete_from_column_family] + + +# [START bigtable_delete_from_row] +def delete_from_row(project_id, instance_id, table_id): + from google.cloud.bigtable import Client + + client = Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + row = table.row("phone#4c410523#20190501") + row.delete() + row.commit() + + +# [END bigtable_delete_from_row] + + +# [START bigtable_streaming_and_batching] +def streaming_and_batching(project_id, instance_id, table_id): + from google.cloud.bigtable import Client + + client = Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + batcher = table.mutations_batcher(flush_count=2) + rows = table.read_rows() + for row in rows: + row = table.row(row.row_key) + row.delete_cell(column_family_id="cell_plan", column="data_plan_01gb") + + batcher.mutate_rows(rows) + + +# [END bigtable_streaming_and_batching] + + +# [START bigtable_check_and_mutate] +def check_and_mutate(project_id, instance_id, table_id): + from google.cloud.bigtable import Client + + client = Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + row = table.row("phone#4c410523#20190501") + row.delete_cell(column_family_id="cell_plan", column="data_plan_01gb") + row.delete_cell(column_family_id="cell_plan", column="data_plan_05gb") + row.commit() + + +# [END bigtable_check_and_mutate] + + +# [START bigtable_drop_row_range] +def drop_row_range(project_id, instance_id, table_id): + from google.cloud.bigtable import Client + + client = Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + row_key_prefix = "phone#4c410523" + table.drop_by_prefix(row_key_prefix, timeout=200) + + +# [END bigtable_drop_row_range] + + +# [START bigtable_delete_column_family] +def delete_column_family(project_id, instance_id, table_id): + from google.cloud.bigtable import Client + + client = Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + column_family_id = "stats_summary" + column_family_obj = table.column_family(column_family_id) + column_family_obj.delete() + + +# [END bigtable_delete_column_family] + + +# [START bigtable_delete_table] +def delete_table(project_id, instance_id, table_id): + from google.cloud.bigtable import Client + + client = Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + table.delete() + + +# [END bigtable_delete_table] diff --git a/packages/google-cloud-bigtable/samples/snippets/deletes/deletes_snippets_async.py b/packages/google-cloud-bigtable/samples/snippets/deletes/deletes_snippets_async.py new file mode 100644 index 000000000000..b70d557e7610 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/deletes/deletes_snippets_async.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python + +# Copyright 2024, 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. + + +# [START bigtable_delete_from_column_asyncio] +async def delete_from_column(project_id, instance_id, table_id): + from google.cloud.bigtable.data import ( + BigtableDataClientAsync, + DeleteRangeFromColumn, + ) + + client = BigtableDataClientAsync(project=project_id) + table = client.get_table(instance_id, table_id) + + await table.mutate_row( + "phone#4c410523#20190501", + DeleteRangeFromColumn(family="cell_plan", qualifier=b"data_plan_01gb"), + ) + + await table.close() + await client.close() + + +# [END bigtable_delete_from_column_asyncio] + + +# [START bigtable_delete_from_column_family_asyncio] +async def delete_from_column_family(project_id, instance_id, table_id): + from google.cloud.bigtable.data import BigtableDataClientAsync, DeleteAllFromFamily + + client = BigtableDataClientAsync(project=project_id) + table = client.get_table(instance_id, table_id) + + await table.mutate_row("phone#4c410523#20190501", DeleteAllFromFamily("cell_plan")) + + await table.close() + await client.close() + + +# [END bigtable_delete_from_column_family_asyncio] + + +# [START bigtable_delete_from_row_asyncio] +async def delete_from_row(project_id, instance_id, table_id): + from google.cloud.bigtable.data import BigtableDataClientAsync, DeleteAllFromRow + + client = BigtableDataClientAsync(project=project_id) + table = client.get_table(instance_id, table_id) + + await table.mutate_row("phone#4c410523#20190501", DeleteAllFromRow()) + + await table.close() + await client.close() + + +# [END bigtable_delete_from_row_asyncio] + + +# [START bigtable_streaming_and_batching_asyncio] +async def streaming_and_batching(project_id, instance_id, table_id): + from google.cloud.bigtable.data import ( + BigtableDataClientAsync, + DeleteRangeFromColumn, + ReadRowsQuery, + RowMutationEntry, + ) + + client = BigtableDataClientAsync(project=project_id) + table = client.get_table(instance_id, table_id) + + async with table.mutations_batcher() as batcher: + async for row in await table.read_rows_stream(ReadRowsQuery(limit=10)): + await batcher.append( + RowMutationEntry( + row.row_key, + DeleteRangeFromColumn( + family="cell_plan", qualifier=b"data_plan_01gb" + ), + ) + ) + + await table.close() + await client.close() + + +# [END bigtable_streaming_and_batching_asyncio] + + +# [START bigtable_check_and_mutate_asyncio] +async def check_and_mutate(project_id, instance_id, table_id): + from google.cloud.bigtable.data import ( + BigtableDataClientAsync, + DeleteRangeFromColumn, + ) + from google.cloud.bigtable.data.row_filters import LiteralValueFilter + + client = BigtableDataClientAsync(project=project_id) + table = client.get_table(instance_id, table_id) + + await table.check_and_mutate_row( + "phone#4c410523#20190501", + predicate=LiteralValueFilter("PQ2A.190405.003"), + true_case_mutations=DeleteRangeFromColumn( + family="cell_plan", qualifier=b"data_plan_01gb" + ), + ) + + await table.close() + await client.close() + + +# [END bigtable_check_and_mutate_asyncio] diff --git a/packages/google-cloud-bigtable/samples/snippets/deletes/deletes_test.py b/packages/google-cloud-bigtable/samples/snippets/deletes/deletes_test.py new file mode 100644 index 000000000000..a683df541309 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/deletes/deletes_test.py @@ -0,0 +1,139 @@ +# 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 datetime +import os +import time +import uuid + +import pytest + +from ...utils import create_table_cm +from . import deletes_snippets + +PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"] +BIGTABLE_INSTANCE = os.environ["BIGTABLE_INSTANCE"] +TABLE_ID = f"mobile-time-series-deletes-{str(uuid.uuid4())[:16]}" + + +@pytest.fixture(scope="module") +def table_id(): + from google.cloud.bigtable.row_set import RowSet + + with create_table_cm( + PROJECT, + BIGTABLE_INSTANCE, + TABLE_ID, + {"stats_summary": None, "cell_plan": None}, + verbose=False, + ) as table: + timestamp = datetime.datetime(2019, 5, 1) + timestamp_minus_hr = datetime.datetime(2019, 5, 1) - datetime.timedelta(hours=1) + + row_keys = [ + "phone#4c410523#20190501", + "phone#4c410523#20190502", + "phone#4c410523#20190505", + "phone#5c10102#20190501", + "phone#5c10102#20190502", + ] + + rows = [table.direct_row(row_key) for row_key in row_keys] + + rows[0].set_cell("stats_summary", "connected_cell", 1, timestamp) + rows[0].set_cell("stats_summary", "connected_wifi", 1, timestamp) + rows[0].set_cell("stats_summary", "os_build", "PQ2A.190405.003", timestamp) + rows[0].set_cell("cell_plan", "data_plan_01gb", "true", timestamp_minus_hr) + rows[0].set_cell("cell_plan", "data_plan_01gb", "false", timestamp) + rows[0].set_cell("cell_plan", "data_plan_05gb", "true", timestamp) + rows[1].set_cell("stats_summary", "connected_cell", 1, timestamp) + rows[1].set_cell("stats_summary", "connected_wifi", 1, timestamp) + rows[1].set_cell("stats_summary", "os_build", "PQ2A.190405.004", timestamp) + rows[1].set_cell("cell_plan", "data_plan_05gb", "true", timestamp) + rows[2].set_cell("stats_summary", "connected_cell", 0, timestamp) + rows[2].set_cell("stats_summary", "connected_wifi", 1, timestamp) + rows[2].set_cell("stats_summary", "os_build", "PQ2A.190406.000", timestamp) + rows[2].set_cell("cell_plan", "data_plan_05gb", "true", timestamp) + rows[3].set_cell("stats_summary", "connected_cell", 1, timestamp) + rows[3].set_cell("stats_summary", "connected_wifi", 1, timestamp) + rows[3].set_cell("stats_summary", "os_build", "PQ2A.190401.002", timestamp) + rows[3].set_cell("cell_plan", "data_plan_10gb", "true", timestamp) + rows[4].set_cell("stats_summary", "connected_cell", 1, timestamp) + rows[4].set_cell("stats_summary", "connected_wifi", 0, timestamp) + rows[4].set_cell("stats_summary", "os_build", "PQ2A.190406.000", timestamp) + rows[4].set_cell("cell_plan", "data_plan_10gb", "true", timestamp) + + table.mutate_rows(rows) + + # Ensure mutations have propagated. + row_set = RowSet() + + for row_key in row_keys: + row_set.add_row_key(row_key) + + fetched = list(table.read_rows(row_set=row_set)) + + while len(fetched) < len(rows): + time.sleep(5) + fetched = list(table.read_rows(row_set=row_set)) + + yield TABLE_ID + + +def assert_output_match(capsys, expected): + out, _ = capsys.readouterr() + assert out == expected + + +def test_delete_from_column(capsys, table_id): + deletes_snippets.delete_from_column(PROJECT, BIGTABLE_INSTANCE, table_id) + assert_output_match(capsys, "") + + +def test_delete_from_column_family(capsys, table_id): + deletes_snippets.delete_from_column_family(PROJECT, BIGTABLE_INSTANCE, table_id) + assert_output_match(capsys, "") + + +def test_delete_from_row(capsys, table_id): + deletes_snippets.delete_from_row(PROJECT, BIGTABLE_INSTANCE, table_id) + assert_output_match(capsys, "") + + +def test_streaming_and_batching(capsys, table_id): + deletes_snippets.streaming_and_batching(PROJECT, BIGTABLE_INSTANCE, table_id) + assert_output_match(capsys, "") + + +def test_check_and_mutate(capsys, table_id): + deletes_snippets.check_and_mutate(PROJECT, BIGTABLE_INSTANCE, table_id) + assert_output_match(capsys, "") + + +def test_drop_row_range(capsys, table_id): + deletes_snippets.drop_row_range(PROJECT, BIGTABLE_INSTANCE, table_id) + assert_output_match(capsys, "") + + +def test_delete_column_family(capsys, table_id): + deletes_snippets.delete_column_family(PROJECT, BIGTABLE_INSTANCE, table_id) + assert_output_match(capsys, "") + + +def test_delete_table(capsys): + delete_table_id = f"to-delete-table-{str(uuid.uuid4())[:16]}" + with create_table_cm(PROJECT, BIGTABLE_INSTANCE, delete_table_id, verbose=False): + deletes_snippets.delete_table(PROJECT, BIGTABLE_INSTANCE, delete_table_id) + assert_output_match(capsys, "") diff --git a/packages/google-cloud-bigtable/samples/snippets/deletes/noxfile.py b/packages/google-cloud-bigtable/samples/snippets/deletes/noxfile.py new file mode 100644 index 000000000000..c0e60097b353 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/deletes/noxfile.py @@ -0,0 +1,292 @@ +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import print_function + +import glob +import os +import sys +from pathlib import Path +from typing import Callable, Dict, Optional + +import nox + +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING +# DO NOT EDIT THIS FILE EVER! +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING + +BLACK_VERSION = "black==22.3.0" +ISORT_VERSION = "isort==5.10.1" + +# Copy `noxfile_config.py` to your directory and modify it instead. + +# `TEST_CONFIG` dict is a configuration hook that allows users to +# modify the test configurations. The values here should be in sync +# with `noxfile_config.py`. Users will copy `noxfile_config.py` into +# their directory and modify it. + +TEST_CONFIG = { + # You can opt out from the test for specific Python versions. + "ignored_versions": [], + # Old samples are opted out of enforcing Python type hints + # All new samples should feature them + "enforce_type_hints": False, + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", + # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + # If you need to use a specific version of pip, + # change pip_version_override to the string representation + # of the version number, for example, "20.2.4" + "pip_version_override": None, + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + "envs": {}, +} + + +try: + # Ensure we can import noxfile_config in the project's directory. + sys.path.append(".") + from noxfile_config import TEST_CONFIG_OVERRIDE +except ImportError as e: + print("No user noxfile_config found: detail: {}".format(e)) + TEST_CONFIG_OVERRIDE = {} + +# Update the TEST_CONFIG with the user supplied values. +TEST_CONFIG.update(TEST_CONFIG_OVERRIDE) + + +def get_pytest_env_vars() -> Dict[str, str]: + """Returns a dict for pytest invocation.""" + ret = {} + + # Override the GCLOUD_PROJECT and the alias. + env_key = TEST_CONFIG["gcloud_project_env"] + # This should error out if not set. + ret["GOOGLE_CLOUD_PROJECT"] = os.environ[env_key] + + # Apply user supplied envs. + ret.update(TEST_CONFIG["envs"]) + return ret + + +# DO NOT EDIT - automatically generated. +# All versions used to test samples. +ALL_VERSIONS = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + +# Any default versions that should be ignored. +IGNORED_VERSIONS = TEST_CONFIG["ignored_versions"] + +TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) + +INSTALL_LIBRARY_FROM_SOURCE = os.environ.get("INSTALL_LIBRARY_FROM_SOURCE", False) in ( + "True", + "true", +) + +# Error if a python version is missing +nox.options.error_on_missing_interpreters = True + +# +# Style Checks +# + + +# Linting with flake8. +# +# We ignore the following rules: +# E203: whitespace before ‘:’ +# E266: too many leading ‘#’ for block comment +# E501: line too long +# I202: Additional newline in a section of imports +# +# We also need to specify the rules which are ignored by default: +# ['E226', 'W504', 'E126', 'E123', 'W503', 'E24', 'E704', 'E121'] +FLAKE8_COMMON_ARGS = [ + "--show-source", + "--builtin=gettext", + "--max-complexity=20", + "--exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py", + "--ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202", + "--max-line-length=88", +] + + +@nox.session +def lint(session: nox.sessions.Session) -> None: + if not TEST_CONFIG["enforce_type_hints"]: + session.install("flake8") + else: + session.install("flake8", "flake8-annotations") + + args = FLAKE8_COMMON_ARGS + [ + ".", + ] + session.run("flake8", *args) + + +# +# Black +# + + +@nox.session +def blacken(session: nox.sessions.Session) -> None: + """Run black. Format code to uniform standard.""" + session.install(BLACK_VERSION) + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + session.run("black", *python_files) + + +# +# format = isort + black +# + + +@nox.session +def format(session: nox.sessions.Session) -> None: + """ + Run isort to sort imports. Then run black + to format code to uniform standard. + """ + session.install(BLACK_VERSION, ISORT_VERSION) + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + # Use the --fss option to sort imports using strict alphabetical order. + # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + session.run("isort", "--fss", *python_files) + session.run("black", *python_files) + + +# +# Sample Tests +# + + +PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] + + +def _session_tests( + session: nox.sessions.Session, post_install: Callable = None +) -> None: + # check for presence of tests + test_list = glob.glob("**/*_test.py", recursive=True) + glob.glob( + "**/test_*.py", recursive=True + ) + test_list.extend(glob.glob("**/tests", recursive=True)) + + if len(test_list) == 0: + print("No tests found, skipping directory.") + return + + if TEST_CONFIG["pip_version_override"]: + pip_version = TEST_CONFIG["pip_version_override"] + session.install(f"pip=={pip_version}") + """Runs py.test for a particular project.""" + concurrent_args = [] + if os.path.exists("requirements.txt"): + if os.path.exists("constraints.txt"): + session.install("-r", "requirements.txt", "-c", "constraints.txt") + else: + session.install("-r", "requirements.txt") + with open("requirements.txt") as rfile: + packages = rfile.read() + + if os.path.exists("requirements-test.txt"): + if os.path.exists("constraints-test.txt"): + session.install("-r", "requirements-test.txt", "-c", "constraints-test.txt") + else: + session.install("-r", "requirements-test.txt") + with open("requirements-test.txt") as rtfile: + packages += rtfile.read() + + if INSTALL_LIBRARY_FROM_SOURCE: + session.install("-e", _get_repo_root()) + + if post_install: + post_install(session) + + if "pytest-parallel" in packages: + concurrent_args.extend(["--workers", "auto", "--tests-per-worker", "auto"]) + elif "pytest-xdist" in packages: + concurrent_args.extend(["-n", "auto"]) + + session.run( + "pytest", + *(PYTEST_COMMON_ARGS + session.posargs + concurrent_args), + # Pytest will return 5 when no tests are collected. This can happen + # on travis where slow and flaky tests are excluded. + # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html + success_codes=[0, 5], + env=get_pytest_env_vars(), + ) + + +@nox.session(python=ALL_VERSIONS) +def py(session: nox.sessions.Session) -> None: + """Runs py.test for a sample using the specified version of Python.""" + if session.python in TESTED_VERSIONS: + _session_tests(session) + else: + session.skip( + "SKIPPED: {} tests are disabled for this sample.".format(session.python) + ) + + +# +# Readmegen +# + + +def _get_repo_root() -> Optional[str]: + """Returns the root folder of the project.""" + # Get root of this repository. Assume we don't have directories nested deeper than 10 items. + p = Path(os.getcwd()) + for i in range(10): + if p is None: + break + if Path(p / ".git").exists(): + return str(p) + # .git is not available in repos cloned via Cloud Build + # setup.py is always in the library's root, so use that instead + # https://github.com/googleapis/synthtool/issues/792 + if Path(p / "setup.py").exists(): + return str(p) + p = p.parent + raise Exception("Unable to detect repository root.") + + +GENERATED_READMES = sorted([x for x in Path(".").rglob("*.rst.in")]) + + +@nox.session +@nox.parametrize("path", GENERATED_READMES) +def readmegen(session: nox.sessions.Session, path: str) -> None: + """(Re-)generates the readme for a sample.""" + session.install("jinja2", "pyyaml") + dir_ = os.path.dirname(path) + + if os.path.exists(os.path.join(dir_, "requirements.txt")): + session.install("-r", os.path.join(dir_, "requirements.txt")) + + in_file = os.path.join(dir_, "README.rst.in") + session.run( + "python", _get_repo_root() + "/scripts/readme-gen/readme_gen.py", in_file + ) diff --git a/packages/google-cloud-bigtable/samples/snippets/deletes/requirements-test.txt b/packages/google-cloud-bigtable/samples/snippets/deletes/requirements-test.txt new file mode 100644 index 000000000000..ee4ba018603b --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/deletes/requirements-test.txt @@ -0,0 +1,2 @@ +pytest +pytest-asyncio diff --git a/packages/google-cloud-bigtable/samples/snippets/deletes/requirements.txt b/packages/google-cloud-bigtable/samples/snippets/deletes/requirements.txt new file mode 100644 index 000000000000..730d25dec63f --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/deletes/requirements.txt @@ -0,0 +1 @@ +google-cloud-bigtable==2.35.0 diff --git a/packages/google-cloud-bigtable/samples/snippets/filters/__init__.py b/packages/google-cloud-bigtable/samples/snippets/filters/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-cloud-bigtable/samples/snippets/filters/filter_snippets.py b/packages/google-cloud-bigtable/samples/snippets/filters/filter_snippets.py new file mode 100644 index 000000000000..f2a1a0fd0a06 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/filters/filter_snippets.py @@ -0,0 +1,358 @@ +#!/usr/bin/env python + +# 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. + + +# [START bigtable_filters_limit_row_sample] +def filter_limit_row_sample(project_id, instance_id, table_id): + from google.cloud import bigtable + from google.cloud.bigtable import row_filters + + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + + rows = table.read_rows(filter_=row_filters.RowSampleFilter(0.75)) + for row in rows: + print_row(row) + + +# [END bigtable_filters_limit_row_sample] +# [START bigtable_filters_limit_row_regex] +def filter_limit_row_regex(project_id, instance_id, table_id): + from google.cloud import bigtable + from google.cloud.bigtable import row_filters + + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + + rows = table.read_rows( + filter_=row_filters.RowKeyRegexFilter(".*#20190501$".encode("utf-8")) + ) + for row in rows: + print_row(row) + + +# [END bigtable_filters_limit_row_regex] +# [START bigtable_filters_limit_cells_per_col] +def filter_limit_cells_per_col(project_id, instance_id, table_id): + from google.cloud import bigtable + from google.cloud.bigtable import row_filters + + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + + rows = table.read_rows(filter_=row_filters.CellsColumnLimitFilter(2)) + for row in rows: + print_row(row) + + +# [END bigtable_filters_limit_cells_per_col] +# [START bigtable_filters_limit_cells_per_row] +def filter_limit_cells_per_row(project_id, instance_id, table_id): + from google.cloud import bigtable + from google.cloud.bigtable import row_filters + + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + + rows = table.read_rows(filter_=row_filters.CellsRowLimitFilter(2)) + for row in rows: + print_row(row) + + +# [END bigtable_filters_limit_cells_per_row] +# [START bigtable_filters_limit_cells_per_row_offset] +def filter_limit_cells_per_row_offset(project_id, instance_id, table_id): + from google.cloud import bigtable + from google.cloud.bigtable import row_filters + + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + + rows = table.read_rows(filter_=row_filters.CellsRowOffsetFilter(2)) + for row in rows: + print_row(row) + + +# [END bigtable_filters_limit_cells_per_row_offset] +# [START bigtable_filters_limit_col_family_regex] +def filter_limit_col_family_regex(project_id, instance_id, table_id): + from google.cloud import bigtable + from google.cloud.bigtable import row_filters + + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + + rows = table.read_rows( + filter_=row_filters.FamilyNameRegexFilter("stats_.*$".encode("utf-8")) + ) + for row in rows: + print_row(row) + + +# [END bigtable_filters_limit_col_family_regex] +# [START bigtable_filters_limit_col_qualifier_regex] +def filter_limit_col_qualifier_regex(project_id, instance_id, table_id): + from google.cloud import bigtable + from google.cloud.bigtable import row_filters + + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + + rows = table.read_rows( + filter_=row_filters.ColumnQualifierRegexFilter("connected_.*$".encode("utf-8")) + ) + for row in rows: + print_row(row) + + +# [END bigtable_filters_limit_col_qualifier_regex] +# [START bigtable_filters_limit_col_range] +def filter_limit_col_range(project_id, instance_id, table_id): + from google.cloud import bigtable + from google.cloud.bigtable import row_filters + + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + + rows = table.read_rows( + filter_=row_filters.ColumnRangeFilter( + "cell_plan", b"data_plan_01gb", b"data_plan_10gb", inclusive_end=False + ) + ) + for row in rows: + print_row(row) + + +# [END bigtable_filters_limit_col_range] +# [START bigtable_filters_limit_value_range] +def filter_limit_value_range(project_id, instance_id, table_id): + from google.cloud import bigtable + from google.cloud.bigtable import row_filters + + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + + rows = table.read_rows( + filter_=row_filters.ValueRangeFilter(b"PQ2A.190405", b"PQ2A.190406") + ) + + for row in rows: + print_row(row) + + +# [END bigtable_filters_limit_value_range] +# [START bigtable_filters_limit_value_regex] + + +def filter_limit_value_regex(project_id, instance_id, table_id): + from google.cloud import bigtable + from google.cloud.bigtable import row_filters + + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + + rows = table.read_rows( + filter_=row_filters.ValueRegexFilter("PQ2A.*$".encode("utf-8")) + ) + for row in rows: + print_row(row) + + +# [END bigtable_filters_limit_value_regex] +# [START bigtable_filters_limit_timestamp_range] +def filter_limit_timestamp_range(project_id, instance_id, table_id): + import datetime + + from google.cloud import bigtable + from google.cloud.bigtable import row_filters + + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + + end = datetime.datetime(2019, 5, 1) + + rows = table.read_rows( + filter_=row_filters.TimestampRangeFilter(row_filters.TimestampRange(end=end)) + ) + for row in rows: + print_row(row) + + +# [END bigtable_filters_limit_timestamp_range] +# [START bigtable_filters_limit_block_all] +def filter_limit_block_all(project_id, instance_id, table_id): + from google.cloud import bigtable + from google.cloud.bigtable import row_filters + + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + + rows = table.read_rows(filter_=row_filters.BlockAllFilter(True)) + for row in rows: + print_row(row) + + +# [END bigtable_filters_limit_block_all] +# [START bigtable_filters_limit_pass_all] +def filter_limit_pass_all(project_id, instance_id, table_id): + from google.cloud import bigtable + from google.cloud.bigtable import row_filters + + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + + rows = table.read_rows(filter_=row_filters.PassAllFilter(True)) + for row in rows: + print_row(row) + + +# [END bigtable_filters_limit_pass_all] +# [START bigtable_filters_modify_strip_value] +def filter_modify_strip_value(project_id, instance_id, table_id): + from google.cloud import bigtable + from google.cloud.bigtable import row_filters + + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + + rows = table.read_rows(filter_=row_filters.StripValueTransformerFilter(True)) + for row in rows: + print_row(row) + + +# [END bigtable_filters_modify_strip_value] +# [START bigtable_filters_modify_apply_label] +def filter_modify_apply_label(project_id, instance_id, table_id): + from google.cloud import bigtable + from google.cloud.bigtable import row_filters + + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + + rows = table.read_rows(filter_=row_filters.ApplyLabelFilter(label="labelled")) + for row in rows: + print_row(row) + + +# [END bigtable_filters_modify_apply_label] +# [START bigtable_filters_composing_chain] +def filter_composing_chain(project_id, instance_id, table_id): + from google.cloud import bigtable + from google.cloud.bigtable import row_filters + + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + + rows = table.read_rows( + filter_=row_filters.RowFilterChain( + filters=[ + row_filters.CellsColumnLimitFilter(1), + row_filters.FamilyNameRegexFilter("cell_plan"), + ] + ) + ) + for row in rows: + print_row(row) + + +# [END bigtable_filters_composing_chain] +# [START bigtable_filters_composing_interleave] +def filter_composing_interleave(project_id, instance_id, table_id): + from google.cloud import bigtable + from google.cloud.bigtable import row_filters + + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + + rows = table.read_rows( + filter_=row_filters.RowFilterUnion( + filters=[ + row_filters.ValueRegexFilter("true"), + row_filters.ColumnQualifierRegexFilter("os_build"), + ] + ) + ) + for row in rows: + print_row(row) + + +# [END bigtable_filters_composing_interleave] +# [START bigtable_filters_composing_condition] +def filter_composing_condition(project_id, instance_id, table_id): + from google.cloud import bigtable + from google.cloud.bigtable import row_filters + + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + + rows = table.read_rows( + filter_=row_filters.ConditionalRowFilter( + base_filter=row_filters.RowFilterChain( + filters=[ + row_filters.ColumnQualifierRegexFilter("data_plan_10gb"), + row_filters.ValueRegexFilter("true"), + ] + ), + true_filter=row_filters.ApplyLabelFilter(label="passed-filter"), + false_filter=row_filters.ApplyLabelFilter(label="filtered-out"), + ) + ) + for row in rows: + print_row(row) + + +# [END bigtable_filters_composing_condition] + + +# [START bigtable_filters_print] +def print_row(row): + print("Reading data for {}:".format(row.row_key.decode("utf-8"))) + for cf, cols in sorted(row.cells.items()): + print("Column Family {}".format(cf)) + for col, cells in sorted(cols.items()): + for cell in cells: + labels = ( + " [{}]".format(",".join(cell.labels)) if len(cell.labels) else "" + ) + print( + "\t{}: {} @{}{}".format( + col.decode("utf-8"), + cell.value.decode("utf-8"), + cell.timestamp, + labels, + ) + ) + print("") + + +# [END bigtable_filters_print] diff --git a/packages/google-cloud-bigtable/samples/snippets/filters/filter_snippets_async.py b/packages/google-cloud-bigtable/samples/snippets/filters/filter_snippets_async.py new file mode 100644 index 000000000000..899d4c5c78e9 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/filters/filter_snippets_async.py @@ -0,0 +1,389 @@ +# Copyright 2024, 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. + + +# [START bigtable_filters_limit_row_sample_asyncio] +async def filter_limit_row_sample(project_id, instance_id, table_id): + from google.cloud.bigtable.data import ( + BigtableDataClientAsync, + ReadRowsQuery, + row_filters, + ) + + query = ReadRowsQuery(row_filter=row_filters.RowSampleFilter(0.75)) + + async with BigtableDataClientAsync(project=project_id) as client: + async with client.get_table(instance_id, table_id) as table: + for row in await table.read_rows(query): + print_row(row) + + +# [END bigtable_filters_limit_row_sample_asyncio] +# [START bigtable_filters_limit_row_regex_asyncio] +async def filter_limit_row_regex(project_id, instance_id, table_id): + from google.cloud.bigtable.data import ( + BigtableDataClientAsync, + ReadRowsQuery, + row_filters, + ) + + query = ReadRowsQuery( + row_filter=row_filters.RowKeyRegexFilter(".*#20190501$".encode("utf-8")) + ) + + async with BigtableDataClientAsync(project=project_id) as client: + async with client.get_table(instance_id, table_id) as table: + for row in await table.read_rows(query): + print_row(row) + + +# [END bigtable_filters_limit_row_regex_asyncio] +# [START bigtable_filters_limit_cells_per_col_asyncio] +async def filter_limit_cells_per_col(project_id, instance_id, table_id): + from google.cloud.bigtable.data import ( + BigtableDataClientAsync, + ReadRowsQuery, + row_filters, + ) + + query = ReadRowsQuery(row_filter=row_filters.CellsColumnLimitFilter(2)) + + async with BigtableDataClientAsync(project=project_id) as client: + async with client.get_table(instance_id, table_id) as table: + for row in await table.read_rows(query): + print_row(row) + + +# [END bigtable_filters_limit_cells_per_col_asyncio] +# [START bigtable_filters_limit_cells_per_row_asyncio] +async def filter_limit_cells_per_row(project_id, instance_id, table_id): + from google.cloud.bigtable.data import ( + BigtableDataClientAsync, + ReadRowsQuery, + row_filters, + ) + + query = ReadRowsQuery(row_filter=row_filters.CellsRowLimitFilter(2)) + + async with BigtableDataClientAsync(project=project_id) as client: + async with client.get_table(instance_id, table_id) as table: + for row in await table.read_rows(query): + print_row(row) + + +# [END bigtable_filters_limit_cells_per_row_asyncio] +# [START bigtable_filters_limit_cells_per_row_offset_asyncio] +async def filter_limit_cells_per_row_offset(project_id, instance_id, table_id): + from google.cloud.bigtable.data import ( + BigtableDataClientAsync, + ReadRowsQuery, + row_filters, + ) + + query = ReadRowsQuery(row_filter=row_filters.CellsRowOffsetFilter(2)) + + async with BigtableDataClientAsync(project=project_id) as client: + async with client.get_table(instance_id, table_id) as table: + for row in await table.read_rows(query): + print_row(row) + + +# [END bigtable_filters_limit_cells_per_row_offset_asyncio] +# [START bigtable_filters_limit_col_family_regex_asyncio] +async def filter_limit_col_family_regex(project_id, instance_id, table_id): + from google.cloud.bigtable.data import ( + BigtableDataClientAsync, + ReadRowsQuery, + row_filters, + ) + + query = ReadRowsQuery( + row_filter=row_filters.FamilyNameRegexFilter("stats_.*$".encode("utf-8")) + ) + + async with BigtableDataClientAsync(project=project_id) as client: + async with client.get_table(instance_id, table_id) as table: + for row in await table.read_rows(query): + print_row(row) + + +# [END bigtable_filters_limit_col_family_regex_asyncio] +# [START bigtable_filters_limit_col_qualifier_regex_asyncio] +async def filter_limit_col_qualifier_regex(project_id, instance_id, table_id): + from google.cloud.bigtable.data import ( + BigtableDataClientAsync, + ReadRowsQuery, + row_filters, + ) + + query = ReadRowsQuery( + row_filter=row_filters.ColumnQualifierRegexFilter( + "connected_.*$".encode("utf-8") + ) + ) + + async with BigtableDataClientAsync(project=project_id) as client: + async with client.get_table(instance_id, table_id) as table: + for row in await table.read_rows(query): + print_row(row) + + +# [END bigtable_filters_limit_col_qualifier_regex_asyncio] +# [START bigtable_filters_limit_col_range_asyncio] +async def filter_limit_col_range(project_id, instance_id, table_id): + from google.cloud.bigtable.data import ( + BigtableDataClientAsync, + ReadRowsQuery, + row_filters, + ) + + query = ReadRowsQuery( + row_filter=row_filters.ColumnRangeFilter( + "cell_plan", b"data_plan_01gb", b"data_plan_10gb", inclusive_end=False + ) + ) + + async with BigtableDataClientAsync(project=project_id) as client: + async with client.get_table(instance_id, table_id) as table: + for row in await table.read_rows(query): + print_row(row) + + +# [END bigtable_filters_limit_col_range_asyncio] +# [START bigtable_filters_limit_value_range_asyncio] +async def filter_limit_value_range(project_id, instance_id, table_id): + from google.cloud.bigtable.data import ( + BigtableDataClientAsync, + ReadRowsQuery, + row_filters, + ) + + query = ReadRowsQuery( + row_filter=row_filters.ValueRangeFilter(b"PQ2A.190405", b"PQ2A.190406") + ) + + async with BigtableDataClientAsync(project=project_id) as client: + async with client.get_table(instance_id, table_id) as table: + for row in await table.read_rows(query): + print_row(row) + + +# [END bigtable_filters_limit_value_range_asyncio] +# [START bigtable_filters_limit_value_regex_asyncio] + + +async def filter_limit_value_regex(project_id, instance_id, table_id): + from google.cloud.bigtable.data import ( + BigtableDataClientAsync, + ReadRowsQuery, + row_filters, + ) + + query = ReadRowsQuery( + row_filter=row_filters.ValueRegexFilter("PQ2A.*$".encode("utf-8")) + ) + + async with BigtableDataClientAsync(project=project_id) as client: + async with client.get_table(instance_id, table_id) as table: + for row in await table.read_rows(query): + print_row(row) + + +# [END bigtable_filters_limit_value_regex_asyncio] +# [START bigtable_filters_limit_timestamp_range_asyncio] +async def filter_limit_timestamp_range(project_id, instance_id, table_id): + import datetime + + from google.cloud.bigtable.data import ( + BigtableDataClientAsync, + ReadRowsQuery, + row_filters, + ) + + end = datetime.datetime(2019, 5, 1) + + query = ReadRowsQuery(row_filter=row_filters.TimestampRangeFilter(end=end)) + + async with BigtableDataClientAsync(project=project_id) as client: + async with client.get_table(instance_id, table_id) as table: + for row in await table.read_rows(query): + print_row(row) + + +# [END bigtable_filters_limit_timestamp_range_asyncio] +# [START bigtable_filters_limit_block_all_asyncio] +async def filter_limit_block_all(project_id, instance_id, table_id): + from google.cloud.bigtable.data import ( + BigtableDataClientAsync, + ReadRowsQuery, + row_filters, + ) + + query = ReadRowsQuery(row_filter=row_filters.BlockAllFilter(True)) + + async with BigtableDataClientAsync(project=project_id) as client: + async with client.get_table(instance_id, table_id) as table: + for row in await table.read_rows(query): + print_row(row) + + +# [END bigtable_filters_limit_block_all_asyncio] +# [START bigtable_filters_limit_pass_all_asyncio] +async def filter_limit_pass_all(project_id, instance_id, table_id): + from google.cloud.bigtable.data import ( + BigtableDataClientAsync, + ReadRowsQuery, + row_filters, + ) + + query = ReadRowsQuery(row_filter=row_filters.PassAllFilter(True)) + + async with BigtableDataClientAsync(project=project_id) as client: + async with client.get_table(instance_id, table_id) as table: + for row in await table.read_rows(query): + print_row(row) + + +# [END bigtable_filters_limit_pass_all_asyncio] +# [START bigtable_filters_modify_strip_value_asyncio] +async def filter_modify_strip_value(project_id, instance_id, table_id): + from google.cloud.bigtable.data import ( + BigtableDataClientAsync, + ReadRowsQuery, + row_filters, + ) + + query = ReadRowsQuery(row_filter=row_filters.StripValueTransformerFilter(True)) + + async with BigtableDataClientAsync(project=project_id) as client: + async with client.get_table(instance_id, table_id) as table: + for row in await table.read_rows(query): + print_row(row) + + +# [END bigtable_filters_modify_strip_value_asyncio] +# [START bigtable_filters_modify_apply_label_asyncio] +async def filter_modify_apply_label(project_id, instance_id, table_id): + from google.cloud.bigtable.data import ( + BigtableDataClientAsync, + ReadRowsQuery, + row_filters, + ) + + query = ReadRowsQuery(row_filter=row_filters.ApplyLabelFilter(label="labelled")) + + async with BigtableDataClientAsync(project=project_id) as client: + async with client.get_table(instance_id, table_id) as table: + for row in await table.read_rows(query): + print_row(row) + + +# [END bigtable_filters_modify_apply_label_asyncio] +# [START bigtable_filters_composing_chain_asyncio] +async def filter_composing_chain(project_id, instance_id, table_id): + from google.cloud.bigtable.data import ( + BigtableDataClientAsync, + ReadRowsQuery, + row_filters, + ) + + query = ReadRowsQuery( + row_filter=row_filters.RowFilterChain( + filters=[ + row_filters.CellsColumnLimitFilter(1), + row_filters.FamilyNameRegexFilter("cell_plan"), + ] + ) + ) + + async with BigtableDataClientAsync(project=project_id) as client: + async with client.get_table(instance_id, table_id) as table: + for row in await table.read_rows(query): + print_row(row) + + +# [END bigtable_filters_composing_chain_asyncio] +# [START bigtable_filters_composing_interleave_asyncio] +async def filter_composing_interleave(project_id, instance_id, table_id): + from google.cloud.bigtable.data import ( + BigtableDataClientAsync, + ReadRowsQuery, + row_filters, + ) + + query = ReadRowsQuery( + row_filter=row_filters.RowFilterUnion( + filters=[ + row_filters.ValueRegexFilter("true"), + row_filters.ColumnQualifierRegexFilter("os_build"), + ] + ) + ) + + async with BigtableDataClientAsync(project=project_id) as client: + async with client.get_table(instance_id, table_id) as table: + for row in await table.read_rows(query): + print_row(row) + + +# [END bigtable_filters_composing_interleave_asyncio] +# [START bigtable_filters_composing_condition_asyncio] +async def filter_composing_condition(project_id, instance_id, table_id): + from google.cloud.bigtable.data import ( + BigtableDataClientAsync, + ReadRowsQuery, + row_filters, + ) + + query = ReadRowsQuery( + row_filter=row_filters.ConditionalRowFilter( + predicate_filter=row_filters.RowFilterChain( + filters=[ + row_filters.ColumnQualifierRegexFilter("data_plan_10gb"), + row_filters.ValueRegexFilter("true"), + ] + ), + true_filter=row_filters.ApplyLabelFilter(label="passed-filter"), + false_filter=row_filters.ApplyLabelFilter(label="filtered-out"), + ) + ) + + async with BigtableDataClientAsync(project=project_id) as client: + async with client.get_table(instance_id, table_id) as table: + for row in await table.read_rows(query): + print_row(row) + + +# [END bigtable_filters_composing_condition_asyncio] + + +def print_row(row): + from google.cloud._helpers import _datetime_from_microseconds + + print("Reading data for {}:".format(row.row_key.decode("utf-8"))) + last_family = None + for cell in row.cells: + if last_family != cell.family: + print("Column Family {}".format(cell.family)) + last_family = cell.family + + labels = " [{}]".format(",".join(cell.labels)) if len(cell.labels) else "" + print( + "\t{}: {} @{}{}".format( + cell.qualifier.decode("utf-8"), + cell.value.decode("utf-8"), + _datetime_from_microseconds(cell.timestamp_micros), + labels, + ) + ) + print("") diff --git a/packages/google-cloud-bigtable/samples/snippets/filters/filter_snippets_async_test.py b/packages/google-cloud-bigtable/samples/snippets/filters/filter_snippets_async_test.py new file mode 100644 index 000000000000..3c961a27b752 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/filters/filter_snippets_async_test.py @@ -0,0 +1,450 @@ +# 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 datetime +import inspect +import os +import uuid +from typing import AsyncGenerator + +import pytest +import pytest_asyncio +from google.cloud._helpers import ( + _microseconds_from_datetime, +) + +from ...utils import create_table_cm +from . import filter_snippets_async +from .snapshots.snap_filters_test import snapshots + +PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"] +BIGTABLE_INSTANCE = os.environ["BIGTABLE_INSTANCE"] +TABLE_ID = f"mobile-time-series-filters-async-{str(uuid.uuid4())[:16]}" + + +@pytest.fixture(scope="module") +def event_loop(): + import asyncio + + loop = asyncio.get_event_loop_policy().new_event_loop() + yield loop + loop.close() + + +@pytest_asyncio.fixture(scope="module", autouse=True) +async def table_id() -> AsyncGenerator[str, None]: + with create_table_cm( + PROJECT, BIGTABLE_INSTANCE, TABLE_ID, {"stats_summary": None, "cell_plan": None} + ): + await _populate_table(TABLE_ID) + yield TABLE_ID + + +async def _populate_table(table_id): + from google.cloud.bigtable.data import ( + BigtableDataClientAsync, + RowMutationEntry, + SetCell, + ) + + timestamp = datetime.datetime(2019, 5, 1) + timestamp_minus_hr = timestamp - datetime.timedelta(hours=1) + + async with BigtableDataClientAsync(project=PROJECT) as client: + async with client.get_table(BIGTABLE_INSTANCE, table_id) as table: + async with table.mutations_batcher() as batcher: + await batcher.append( + RowMutationEntry( + "phone#4c410523#20190501", + [ + SetCell( + "stats_summary", + "connected_cell", + 1, + _microseconds_from_datetime(timestamp), + ), + SetCell( + "stats_summary", + "connected_cell", + 1, + _microseconds_from_datetime(timestamp), + ), + SetCell( + "stats_summary", + "connected_wifi", + 1, + _microseconds_from_datetime(timestamp), + ), + SetCell( + "stats_summary", + "os_build", + "PQ2A.190405.003", + _microseconds_from_datetime(timestamp), + ), + SetCell( + "cell_plan", + "data_plan_01gb", + "true", + _microseconds_from_datetime(timestamp_minus_hr), + ), + SetCell( + "cell_plan", + "data_plan_01gb", + "false", + _microseconds_from_datetime(timestamp), + ), + SetCell( + "cell_plan", + "data_plan_05gb", + "true", + _microseconds_from_datetime(timestamp), + ), + ], + ) + ) + await batcher.append( + RowMutationEntry( + "phone#4c410523#20190502", + [ + SetCell( + "stats_summary", + "connected_cell", + 1, + _microseconds_from_datetime(timestamp), + ), + SetCell( + "stats_summary", + "connected_wifi", + 1, + _microseconds_from_datetime(timestamp), + ), + SetCell( + "stats_summary", + "os_build", + "PQ2A.190405.004", + _microseconds_from_datetime(timestamp), + ), + SetCell( + "cell_plan", + "data_plan_05gb", + "true", + _microseconds_from_datetime(timestamp), + ), + ], + ) + ) + await batcher.append( + RowMutationEntry( + "phone#4c410523#20190505", + [ + SetCell( + "stats_summary", + "connected_cell", + 0, + _microseconds_from_datetime(timestamp), + ), + SetCell( + "stats_summary", + "connected_wifi", + 1, + _microseconds_from_datetime(timestamp), + ), + SetCell( + "stats_summary", + "os_build", + "PQ2A.190406.000", + _microseconds_from_datetime(timestamp), + ), + SetCell( + "cell_plan", + "data_plan_05gb", + "true", + _microseconds_from_datetime(timestamp), + ), + ], + ) + ) + await batcher.append( + RowMutationEntry( + "phone#5c10102#20190501", + [ + SetCell( + "stats_summary", + "connected_cell", + 1, + _microseconds_from_datetime(timestamp), + ), + SetCell( + "stats_summary", + "connected_wifi", + 1, + _microseconds_from_datetime(timestamp), + ), + SetCell( + "stats_summary", + "os_build", + "PQ2A.190401.002", + _microseconds_from_datetime(timestamp), + ), + SetCell( + "cell_plan", + "data_plan_10gb", + "true", + _microseconds_from_datetime(timestamp), + ), + ], + ) + ) + await batcher.append( + RowMutationEntry( + "phone#5c10102#20190502", + [ + SetCell( + "stats_summary", + "connected_cell", + 1, + _microseconds_from_datetime(timestamp), + ), + SetCell( + "stats_summary", + "connected_wifi", + 0, + _microseconds_from_datetime(timestamp), + ), + SetCell( + "stats_summary", + "os_build", + "PQ2A.190406.000", + _microseconds_from_datetime(timestamp), + ), + SetCell( + "cell_plan", + "data_plan_10gb", + "true", + _microseconds_from_datetime(timestamp), + ), + ], + ) + ) + + +def _datetime_to_micros(value: datetime.datetime) -> int: + """Uses the same conversion rules as the old client in""" + import calendar + import datetime as dt + + if not value.tzinfo: + value = value.replace(tzinfo=datetime.timezone.utc) + # Regardless of what timezone is on the value, convert it to UTC. + value = value.astimezone(datetime.timezone.utc) + # Convert the datetime to a microsecond timestamp. + return int(calendar.timegm(value.timetuple()) * 1e6) + value.microsecond + return int(dt.timestamp() * 1000 * 1000) + + +@pytest.mark.asyncio +async def test_filter_limit_row_sample(capsys, table_id): + await filter_snippets_async.filter_limit_row_sample( + PROJECT, BIGTABLE_INSTANCE, table_id + ) + + out, _ = capsys.readouterr() + assert "Reading data for" in out + + +@pytest.mark.asyncio +async def test_filter_limit_row_regex(capsys, table_id): + await filter_snippets_async.filter_limit_row_regex( + PROJECT, BIGTABLE_INSTANCE, table_id + ) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +@pytest.mark.asyncio +async def test_filter_limit_cells_per_col(capsys, table_id): + await filter_snippets_async.filter_limit_cells_per_col( + PROJECT, BIGTABLE_INSTANCE, table_id + ) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +@pytest.mark.asyncio +async def test_filter_limit_cells_per_row(capsys, table_id): + await filter_snippets_async.filter_limit_cells_per_row( + PROJECT, BIGTABLE_INSTANCE, table_id + ) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +@pytest.mark.asyncio +async def test_filter_limit_cells_per_row_offset(capsys, table_id): + await filter_snippets_async.filter_limit_cells_per_row_offset( + PROJECT, BIGTABLE_INSTANCE, table_id + ) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +@pytest.mark.asyncio +async def test_filter_limit_col_family_regex(capsys, table_id): + await filter_snippets_async.filter_limit_col_family_regex( + PROJECT, BIGTABLE_INSTANCE, table_id + ) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +@pytest.mark.asyncio +async def test_filter_limit_col_qualifier_regex(capsys, table_id): + await filter_snippets_async.filter_limit_col_qualifier_regex( + PROJECT, BIGTABLE_INSTANCE, table_id + ) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +@pytest.mark.asyncio +async def test_filter_limit_col_range(capsys, table_id): + await filter_snippets_async.filter_limit_col_range( + PROJECT, BIGTABLE_INSTANCE, table_id + ) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +@pytest.mark.asyncio +async def test_filter_limit_value_range(capsys, table_id): + await filter_snippets_async.filter_limit_value_range( + PROJECT, BIGTABLE_INSTANCE, table_id + ) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +@pytest.mark.asyncio +async def test_filter_limit_value_regex(capsys, table_id): + await filter_snippets_async.filter_limit_value_regex( + PROJECT, BIGTABLE_INSTANCE, table_id + ) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +@pytest.mark.asyncio +async def test_filter_limit_timestamp_range(capsys, table_id): + await filter_snippets_async.filter_limit_timestamp_range( + PROJECT, BIGTABLE_INSTANCE, table_id + ) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +@pytest.mark.asyncio +async def test_filter_limit_block_all(capsys, table_id): + await filter_snippets_async.filter_limit_block_all( + PROJECT, BIGTABLE_INSTANCE, table_id + ) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +@pytest.mark.asyncio +async def test_filter_limit_pass_all(capsys, table_id): + await filter_snippets_async.filter_limit_pass_all( + PROJECT, BIGTABLE_INSTANCE, table_id + ) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +@pytest.mark.asyncio +async def test_filter_modify_strip_value(capsys, table_id): + await filter_snippets_async.filter_modify_strip_value( + PROJECT, BIGTABLE_INSTANCE, table_id + ) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +@pytest.mark.asyncio +async def test_filter_modify_apply_label(capsys, table_id): + await filter_snippets_async.filter_modify_apply_label( + PROJECT, BIGTABLE_INSTANCE, table_id + ) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +@pytest.mark.asyncio +async def test_filter_composing_chain(capsys, table_id): + await filter_snippets_async.filter_composing_chain( + PROJECT, BIGTABLE_INSTANCE, table_id + ) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +@pytest.mark.asyncio +async def test_filter_composing_interleave(capsys, table_id): + await filter_snippets_async.filter_composing_interleave( + PROJECT, BIGTABLE_INSTANCE, table_id + ) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +@pytest.mark.asyncio +async def test_filter_composing_condition(capsys, table_id): + await filter_snippets_async.filter_composing_condition( + PROJECT, BIGTABLE_INSTANCE, table_id + ) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected diff --git a/packages/google-cloud-bigtable/samples/snippets/filters/filters_test.py b/packages/google-cloud-bigtable/samples/snippets/filters/filters_test.py new file mode 100644 index 000000000000..c5d780c90e80 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/filters/filters_test.py @@ -0,0 +1,237 @@ +# 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 datetime +import inspect +import os +import time +import uuid + +import pytest + +from ...utils import create_table_cm +from . import filter_snippets +from .snapshots.snap_filters_test import snapshots + +PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"] +BIGTABLE_INSTANCE = os.environ["BIGTABLE_INSTANCE"] +TABLE_ID = f"mobile-time-series-filters-{str(uuid.uuid4())[:16]}" + + +@pytest.fixture(scope="module", autouse=True) +def table_id(): + from google.cloud.bigtable.row_set import RowSet + + table_id = TABLE_ID + with create_table_cm( + PROJECT, BIGTABLE_INSTANCE, table_id, {"stats_summary": None, "cell_plan": None} + ) as table: + timestamp = datetime.datetime(2019, 5, 1) + timestamp_minus_hr = datetime.datetime(2019, 5, 1) - datetime.timedelta(hours=1) + + row_keys = [ + "phone#4c410523#20190501", + "phone#4c410523#20190502", + "phone#4c410523#20190505", + "phone#5c10102#20190501", + "phone#5c10102#20190502", + ] + + rows = [table.direct_row(row_key) for row_key in row_keys] + + rows[0].set_cell("stats_summary", "connected_cell", 1, timestamp) + rows[0].set_cell("stats_summary", "connected_wifi", 1, timestamp) + rows[0].set_cell("stats_summary", "os_build", "PQ2A.190405.003", timestamp) + rows[0].set_cell("cell_plan", "data_plan_01gb", "true", timestamp_minus_hr) + rows[0].set_cell("cell_plan", "data_plan_01gb", "false", timestamp) + rows[0].set_cell("cell_plan", "data_plan_05gb", "true", timestamp) + rows[1].set_cell("stats_summary", "connected_cell", 1, timestamp) + rows[1].set_cell("stats_summary", "connected_wifi", 1, timestamp) + rows[1].set_cell("stats_summary", "os_build", "PQ2A.190405.004", timestamp) + rows[1].set_cell("cell_plan", "data_plan_05gb", "true", timestamp) + rows[2].set_cell("stats_summary", "connected_cell", 0, timestamp) + rows[2].set_cell("stats_summary", "connected_wifi", 1, timestamp) + rows[2].set_cell("stats_summary", "os_build", "PQ2A.190406.000", timestamp) + rows[2].set_cell("cell_plan", "data_plan_05gb", "true", timestamp) + rows[3].set_cell("stats_summary", "connected_cell", 1, timestamp) + rows[3].set_cell("stats_summary", "connected_wifi", 1, timestamp) + rows[3].set_cell("stats_summary", "os_build", "PQ2A.190401.002", timestamp) + rows[3].set_cell("cell_plan", "data_plan_10gb", "true", timestamp) + rows[4].set_cell("stats_summary", "connected_cell", 1, timestamp) + rows[4].set_cell("stats_summary", "connected_wifi", 0, timestamp) + rows[4].set_cell("stats_summary", "os_build", "PQ2A.190406.000", timestamp) + rows[4].set_cell("cell_plan", "data_plan_10gb", "true", timestamp) + + table.mutate_rows(rows) + + # Ensure mutations have propagated. + row_set = RowSet() + + for row_key in row_keys: + row_set.add_row_key(row_key) + + fetched = list(table.read_rows(row_set=row_set)) + + while len(fetched) < len(rows): + time.sleep(5) + fetched = list(table.read_rows(row_set=row_set)) + + yield table_id + + +def test_filter_limit_row_sample(capsys, table_id): + filter_snippets.filter_limit_row_sample(PROJECT, BIGTABLE_INSTANCE, table_id) + + out, _ = capsys.readouterr() + assert "Reading data for" in out + + +def test_filter_limit_row_regex(capsys, table_id): + filter_snippets.filter_limit_row_regex(PROJECT, BIGTABLE_INSTANCE, table_id) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +def test_filter_limit_cells_per_col(capsys, table_id): + filter_snippets.filter_limit_cells_per_col(PROJECT, BIGTABLE_INSTANCE, table_id) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +def test_filter_limit_cells_per_row(capsys, table_id): + filter_snippets.filter_limit_cells_per_row(PROJECT, BIGTABLE_INSTANCE, table_id) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +def test_filter_limit_cells_per_row_offset(capsys, table_id): + filter_snippets.filter_limit_cells_per_row_offset( + PROJECT, BIGTABLE_INSTANCE, table_id + ) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +def test_filter_limit_col_family_regex(capsys, table_id): + filter_snippets.filter_limit_col_family_regex(PROJECT, BIGTABLE_INSTANCE, table_id) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +def test_filter_limit_col_qualifier_regex(capsys, table_id): + filter_snippets.filter_limit_col_qualifier_regex( + PROJECT, BIGTABLE_INSTANCE, table_id + ) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +def test_filter_limit_col_range(capsys, table_id): + filter_snippets.filter_limit_col_range(PROJECT, BIGTABLE_INSTANCE, table_id) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +def test_filter_limit_value_range(capsys, table_id): + filter_snippets.filter_limit_value_range(PROJECT, BIGTABLE_INSTANCE, table_id) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +def test_filter_limit_value_regex(capsys, table_id): + filter_snippets.filter_limit_value_regex(PROJECT, BIGTABLE_INSTANCE, table_id) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +def test_filter_limit_timestamp_range(capsys, table_id): + filter_snippets.filter_limit_timestamp_range(PROJECT, BIGTABLE_INSTANCE, table_id) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +def test_filter_limit_block_all(capsys, table_id): + filter_snippets.filter_limit_block_all(PROJECT, BIGTABLE_INSTANCE, table_id) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +def test_filter_limit_pass_all(capsys, table_id): + filter_snippets.filter_limit_pass_all(PROJECT, BIGTABLE_INSTANCE, table_id) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +def test_filter_modify_strip_value(capsys, table_id): + filter_snippets.filter_modify_strip_value(PROJECT, BIGTABLE_INSTANCE, table_id) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +def test_filter_modify_apply_label(capsys, table_id): + filter_snippets.filter_modify_apply_label(PROJECT, BIGTABLE_INSTANCE, table_id) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +def test_filter_composing_chain(capsys, table_id): + filter_snippets.filter_composing_chain(PROJECT, BIGTABLE_INSTANCE, table_id) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +def test_filter_composing_interleave(capsys, table_id): + filter_snippets.filter_composing_interleave(PROJECT, BIGTABLE_INSTANCE, table_id) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +def test_filter_composing_condition(capsys, table_id): + filter_snippets.filter_composing_condition(PROJECT, BIGTABLE_INSTANCE, table_id) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected diff --git a/packages/google-cloud-bigtable/samples/snippets/filters/noxfile.py b/packages/google-cloud-bigtable/samples/snippets/filters/noxfile.py new file mode 100644 index 000000000000..c0e60097b353 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/filters/noxfile.py @@ -0,0 +1,292 @@ +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import print_function + +import glob +import os +import sys +from pathlib import Path +from typing import Callable, Dict, Optional + +import nox + +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING +# DO NOT EDIT THIS FILE EVER! +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING + +BLACK_VERSION = "black==22.3.0" +ISORT_VERSION = "isort==5.10.1" + +# Copy `noxfile_config.py` to your directory and modify it instead. + +# `TEST_CONFIG` dict is a configuration hook that allows users to +# modify the test configurations. The values here should be in sync +# with `noxfile_config.py`. Users will copy `noxfile_config.py` into +# their directory and modify it. + +TEST_CONFIG = { + # You can opt out from the test for specific Python versions. + "ignored_versions": [], + # Old samples are opted out of enforcing Python type hints + # All new samples should feature them + "enforce_type_hints": False, + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", + # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + # If you need to use a specific version of pip, + # change pip_version_override to the string representation + # of the version number, for example, "20.2.4" + "pip_version_override": None, + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + "envs": {}, +} + + +try: + # Ensure we can import noxfile_config in the project's directory. + sys.path.append(".") + from noxfile_config import TEST_CONFIG_OVERRIDE +except ImportError as e: + print("No user noxfile_config found: detail: {}".format(e)) + TEST_CONFIG_OVERRIDE = {} + +# Update the TEST_CONFIG with the user supplied values. +TEST_CONFIG.update(TEST_CONFIG_OVERRIDE) + + +def get_pytest_env_vars() -> Dict[str, str]: + """Returns a dict for pytest invocation.""" + ret = {} + + # Override the GCLOUD_PROJECT and the alias. + env_key = TEST_CONFIG["gcloud_project_env"] + # This should error out if not set. + ret["GOOGLE_CLOUD_PROJECT"] = os.environ[env_key] + + # Apply user supplied envs. + ret.update(TEST_CONFIG["envs"]) + return ret + + +# DO NOT EDIT - automatically generated. +# All versions used to test samples. +ALL_VERSIONS = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + +# Any default versions that should be ignored. +IGNORED_VERSIONS = TEST_CONFIG["ignored_versions"] + +TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) + +INSTALL_LIBRARY_FROM_SOURCE = os.environ.get("INSTALL_LIBRARY_FROM_SOURCE", False) in ( + "True", + "true", +) + +# Error if a python version is missing +nox.options.error_on_missing_interpreters = True + +# +# Style Checks +# + + +# Linting with flake8. +# +# We ignore the following rules: +# E203: whitespace before ‘:’ +# E266: too many leading ‘#’ for block comment +# E501: line too long +# I202: Additional newline in a section of imports +# +# We also need to specify the rules which are ignored by default: +# ['E226', 'W504', 'E126', 'E123', 'W503', 'E24', 'E704', 'E121'] +FLAKE8_COMMON_ARGS = [ + "--show-source", + "--builtin=gettext", + "--max-complexity=20", + "--exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py", + "--ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202", + "--max-line-length=88", +] + + +@nox.session +def lint(session: nox.sessions.Session) -> None: + if not TEST_CONFIG["enforce_type_hints"]: + session.install("flake8") + else: + session.install("flake8", "flake8-annotations") + + args = FLAKE8_COMMON_ARGS + [ + ".", + ] + session.run("flake8", *args) + + +# +# Black +# + + +@nox.session +def blacken(session: nox.sessions.Session) -> None: + """Run black. Format code to uniform standard.""" + session.install(BLACK_VERSION) + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + session.run("black", *python_files) + + +# +# format = isort + black +# + + +@nox.session +def format(session: nox.sessions.Session) -> None: + """ + Run isort to sort imports. Then run black + to format code to uniform standard. + """ + session.install(BLACK_VERSION, ISORT_VERSION) + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + # Use the --fss option to sort imports using strict alphabetical order. + # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + session.run("isort", "--fss", *python_files) + session.run("black", *python_files) + + +# +# Sample Tests +# + + +PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] + + +def _session_tests( + session: nox.sessions.Session, post_install: Callable = None +) -> None: + # check for presence of tests + test_list = glob.glob("**/*_test.py", recursive=True) + glob.glob( + "**/test_*.py", recursive=True + ) + test_list.extend(glob.glob("**/tests", recursive=True)) + + if len(test_list) == 0: + print("No tests found, skipping directory.") + return + + if TEST_CONFIG["pip_version_override"]: + pip_version = TEST_CONFIG["pip_version_override"] + session.install(f"pip=={pip_version}") + """Runs py.test for a particular project.""" + concurrent_args = [] + if os.path.exists("requirements.txt"): + if os.path.exists("constraints.txt"): + session.install("-r", "requirements.txt", "-c", "constraints.txt") + else: + session.install("-r", "requirements.txt") + with open("requirements.txt") as rfile: + packages = rfile.read() + + if os.path.exists("requirements-test.txt"): + if os.path.exists("constraints-test.txt"): + session.install("-r", "requirements-test.txt", "-c", "constraints-test.txt") + else: + session.install("-r", "requirements-test.txt") + with open("requirements-test.txt") as rtfile: + packages += rtfile.read() + + if INSTALL_LIBRARY_FROM_SOURCE: + session.install("-e", _get_repo_root()) + + if post_install: + post_install(session) + + if "pytest-parallel" in packages: + concurrent_args.extend(["--workers", "auto", "--tests-per-worker", "auto"]) + elif "pytest-xdist" in packages: + concurrent_args.extend(["-n", "auto"]) + + session.run( + "pytest", + *(PYTEST_COMMON_ARGS + session.posargs + concurrent_args), + # Pytest will return 5 when no tests are collected. This can happen + # on travis where slow and flaky tests are excluded. + # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html + success_codes=[0, 5], + env=get_pytest_env_vars(), + ) + + +@nox.session(python=ALL_VERSIONS) +def py(session: nox.sessions.Session) -> None: + """Runs py.test for a sample using the specified version of Python.""" + if session.python in TESTED_VERSIONS: + _session_tests(session) + else: + session.skip( + "SKIPPED: {} tests are disabled for this sample.".format(session.python) + ) + + +# +# Readmegen +# + + +def _get_repo_root() -> Optional[str]: + """Returns the root folder of the project.""" + # Get root of this repository. Assume we don't have directories nested deeper than 10 items. + p = Path(os.getcwd()) + for i in range(10): + if p is None: + break + if Path(p / ".git").exists(): + return str(p) + # .git is not available in repos cloned via Cloud Build + # setup.py is always in the library's root, so use that instead + # https://github.com/googleapis/synthtool/issues/792 + if Path(p / "setup.py").exists(): + return str(p) + p = p.parent + raise Exception("Unable to detect repository root.") + + +GENERATED_READMES = sorted([x for x in Path(".").rglob("*.rst.in")]) + + +@nox.session +@nox.parametrize("path", GENERATED_READMES) +def readmegen(session: nox.sessions.Session, path: str) -> None: + """(Re-)generates the readme for a sample.""" + session.install("jinja2", "pyyaml") + dir_ = os.path.dirname(path) + + if os.path.exists(os.path.join(dir_, "requirements.txt")): + session.install("-r", os.path.join(dir_, "requirements.txt")) + + in_file = os.path.join(dir_, "README.rst.in") + session.run( + "python", _get_repo_root() + "/scripts/readme-gen/readme_gen.py", in_file + ) diff --git a/packages/google-cloud-bigtable/samples/snippets/filters/requirements-test.txt b/packages/google-cloud-bigtable/samples/snippets/filters/requirements-test.txt new file mode 100644 index 000000000000..ee4ba018603b --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/filters/requirements-test.txt @@ -0,0 +1,2 @@ +pytest +pytest-asyncio diff --git a/packages/google-cloud-bigtable/samples/snippets/filters/requirements.txt b/packages/google-cloud-bigtable/samples/snippets/filters/requirements.txt new file mode 100644 index 000000000000..730d25dec63f --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/filters/requirements.txt @@ -0,0 +1 @@ +google-cloud-bigtable==2.35.0 diff --git a/packages/google-cloud-bigtable/samples/snippets/filters/snapshots/__init__.py b/packages/google-cloud-bigtable/samples/snippets/filters/snapshots/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-cloud-bigtable/samples/snippets/filters/snapshots/snap_filters_test.py b/packages/google-cloud-bigtable/samples/snippets/filters/snapshots/snap_filters_test.py new file mode 100644 index 000000000000..0547ddddd858 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/filters/snapshots/snap_filters_test.py @@ -0,0 +1,503 @@ +# -*- coding: utf-8 -*- +# this was previously implemented using the `snapshottest` package (https://goo.gl/zC4yUc), +# which is not compatible with Python 3.12. So we moved to a standard dictionary storing +# expected outputs for each test +from __future__ import unicode_literals + +snapshots = {} + +snapshots["test_filter_limit_row_regex"] = """Reading data for phone#4c410523#20190501: +Column Family cell_plan +\tdata_plan_01gb: false @2019-05-01 00:00:00+00:00 +\tdata_plan_01gb: true @2019-04-30 23:00:00+00:00 +\tdata_plan_05gb: true @2019-05-01 00:00:00+00:00 +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190405.003 @2019-05-01 00:00:00+00:00 + +Reading data for phone#5c10102#20190501: +Column Family cell_plan +\tdata_plan_10gb: true @2019-05-01 00:00:00+00:00 +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190401.002 @2019-05-01 00:00:00+00:00 + +""" + +snapshots[ + "test_filter_limit_cells_per_col" +] = """Reading data for phone#4c410523#20190501: +Column Family cell_plan +\tdata_plan_01gb: false @2019-05-01 00:00:00+00:00 +\tdata_plan_01gb: true @2019-04-30 23:00:00+00:00 +\tdata_plan_05gb: true @2019-05-01 00:00:00+00:00 +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190405.003 @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190502: +Column Family cell_plan +\tdata_plan_05gb: true @2019-05-01 00:00:00+00:00 +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190405.004 @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190505: +Column Family cell_plan +\tdata_plan_05gb: true @2019-05-01 00:00:00+00:00 +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x00 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190406.000 @2019-05-01 00:00:00+00:00 + +Reading data for phone#5c10102#20190501: +Column Family cell_plan +\tdata_plan_10gb: true @2019-05-01 00:00:00+00:00 +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190401.002 @2019-05-01 00:00:00+00:00 + +Reading data for phone#5c10102#20190502: +Column Family cell_plan +\tdata_plan_10gb: true @2019-05-01 00:00:00+00:00 +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x00 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190406.000 @2019-05-01 00:00:00+00:00 + +""" + +snapshots[ + "test_filter_limit_cells_per_row" +] = """Reading data for phone#4c410523#20190501: +Column Family cell_plan +\tdata_plan_01gb: false @2019-05-01 00:00:00+00:00 +\tdata_plan_01gb: true @2019-04-30 23:00:00+00:00 + +Reading data for phone#4c410523#20190502: +Column Family cell_plan +\tdata_plan_05gb: true @2019-05-01 00:00:00+00:00 +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190505: +Column Family cell_plan +\tdata_plan_05gb: true @2019-05-01 00:00:00+00:00 +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x00 @2019-05-01 00:00:00+00:00 + +Reading data for phone#5c10102#20190501: +Column Family cell_plan +\tdata_plan_10gb: true @2019-05-01 00:00:00+00:00 +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 + +Reading data for phone#5c10102#20190502: +Column Family cell_plan +\tdata_plan_10gb: true @2019-05-01 00:00:00+00:00 +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 + +""" + +snapshots[ + "test_filter_limit_cells_per_row_offset" +] = """Reading data for phone#4c410523#20190501: +Column Family cell_plan +\tdata_plan_05gb: true @2019-05-01 00:00:00+00:00 +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190405.003 @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190502: +Column Family stats_summary +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190405.004 @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190505: +Column Family stats_summary +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190406.000 @2019-05-01 00:00:00+00:00 + +Reading data for phone#5c10102#20190501: +Column Family stats_summary +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190401.002 @2019-05-01 00:00:00+00:00 + +Reading data for phone#5c10102#20190502: +Column Family stats_summary +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x00 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190406.000 @2019-05-01 00:00:00+00:00 + +""" + +snapshots[ + "test_filter_limit_col_family_regex" +] = """Reading data for phone#4c410523#20190501: +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190405.003 @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190502: +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190405.004 @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190505: +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x00 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190406.000 @2019-05-01 00:00:00+00:00 + +Reading data for phone#5c10102#20190501: +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190401.002 @2019-05-01 00:00:00+00:00 + +Reading data for phone#5c10102#20190502: +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x00 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190406.000 @2019-05-01 00:00:00+00:00 + +""" + +snapshots[ + "test_filter_limit_col_qualifier_regex" +] = """Reading data for phone#4c410523#20190501: +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190502: +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190505: +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x00 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 + +Reading data for phone#5c10102#20190501: +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 + +Reading data for phone#5c10102#20190502: +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x00 @2019-05-01 00:00:00+00:00 + +""" + +snapshots["test_filter_limit_col_range"] = """Reading data for phone#4c410523#20190501: +Column Family cell_plan +\tdata_plan_01gb: false @2019-05-01 00:00:00+00:00 +\tdata_plan_01gb: true @2019-04-30 23:00:00+00:00 +\tdata_plan_05gb: true @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190502: +Column Family cell_plan +\tdata_plan_05gb: true @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190505: +Column Family cell_plan +\tdata_plan_05gb: true @2019-05-01 00:00:00+00:00 + +""" + +snapshots[ + "test_filter_limit_value_range" +] = """Reading data for phone#4c410523#20190501: +Column Family stats_summary +\tos_build: PQ2A.190405.003 @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190502: +Column Family stats_summary +\tos_build: PQ2A.190405.004 @2019-05-01 00:00:00+00:00 + +""" + +snapshots[ + "test_filter_limit_value_regex" +] = """Reading data for phone#4c410523#20190501: +Column Family stats_summary +\tos_build: PQ2A.190405.003 @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190502: +Column Family stats_summary +\tos_build: PQ2A.190405.004 @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190505: +Column Family stats_summary +\tos_build: PQ2A.190406.000 @2019-05-01 00:00:00+00:00 + +Reading data for phone#5c10102#20190501: +Column Family stats_summary +\tos_build: PQ2A.190401.002 @2019-05-01 00:00:00+00:00 + +Reading data for phone#5c10102#20190502: +Column Family stats_summary +\tos_build: PQ2A.190406.000 @2019-05-01 00:00:00+00:00 + +""" + +snapshots[ + "test_filter_limit_timestamp_range" +] = """Reading data for phone#4c410523#20190501: +Column Family cell_plan +\tdata_plan_01gb: true @2019-04-30 23:00:00+00:00 + +""" + +snapshots["test_filter_limit_block_all"] = "" + +snapshots["test_filter_limit_pass_all"] = """Reading data for phone#4c410523#20190501: +Column Family cell_plan +\tdata_plan_01gb: false @2019-05-01 00:00:00+00:00 +\tdata_plan_01gb: true @2019-04-30 23:00:00+00:00 +\tdata_plan_05gb: true @2019-05-01 00:00:00+00:00 +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190405.003 @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190502: +Column Family cell_plan +\tdata_plan_05gb: true @2019-05-01 00:00:00+00:00 +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190405.004 @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190505: +Column Family cell_plan +\tdata_plan_05gb: true @2019-05-01 00:00:00+00:00 +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x00 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190406.000 @2019-05-01 00:00:00+00:00 + +Reading data for phone#5c10102#20190501: +Column Family cell_plan +\tdata_plan_10gb: true @2019-05-01 00:00:00+00:00 +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190401.002 @2019-05-01 00:00:00+00:00 + +Reading data for phone#5c10102#20190502: +Column Family cell_plan +\tdata_plan_10gb: true @2019-05-01 00:00:00+00:00 +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x00 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190406.000 @2019-05-01 00:00:00+00:00 + +""" + +snapshots[ + "test_filter_modify_strip_value" +] = """Reading data for phone#4c410523#20190501: +Column Family cell_plan +\tdata_plan_01gb: @2019-05-01 00:00:00+00:00 +\tdata_plan_01gb: @2019-04-30 23:00:00+00:00 +\tdata_plan_05gb: @2019-05-01 00:00:00+00:00 +Column Family stats_summary +\tconnected_cell: @2019-05-01 00:00:00+00:00 +\tconnected_wifi: @2019-05-01 00:00:00+00:00 +\tos_build: @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190502: +Column Family cell_plan +\tdata_plan_05gb: @2019-05-01 00:00:00+00:00 +Column Family stats_summary +\tconnected_cell: @2019-05-01 00:00:00+00:00 +\tconnected_wifi: @2019-05-01 00:00:00+00:00 +\tos_build: @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190505: +Column Family cell_plan +\tdata_plan_05gb: @2019-05-01 00:00:00+00:00 +Column Family stats_summary +\tconnected_cell: @2019-05-01 00:00:00+00:00 +\tconnected_wifi: @2019-05-01 00:00:00+00:00 +\tos_build: @2019-05-01 00:00:00+00:00 + +Reading data for phone#5c10102#20190501: +Column Family cell_plan +\tdata_plan_10gb: @2019-05-01 00:00:00+00:00 +Column Family stats_summary +\tconnected_cell: @2019-05-01 00:00:00+00:00 +\tconnected_wifi: @2019-05-01 00:00:00+00:00 +\tos_build: @2019-05-01 00:00:00+00:00 + +Reading data for phone#5c10102#20190502: +Column Family cell_plan +\tdata_plan_10gb: @2019-05-01 00:00:00+00:00 +Column Family stats_summary +\tconnected_cell: @2019-05-01 00:00:00+00:00 +\tconnected_wifi: @2019-05-01 00:00:00+00:00 +\tos_build: @2019-05-01 00:00:00+00:00 + +""" + +snapshots[ + "test_filter_modify_apply_label" +] = """Reading data for phone#4c410523#20190501: +Column Family cell_plan +\tdata_plan_01gb: false @2019-05-01 00:00:00+00:00 [labelled] +\tdata_plan_01gb: true @2019-04-30 23:00:00+00:00 [labelled] +\tdata_plan_05gb: true @2019-05-01 00:00:00+00:00 [labelled] +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 [labelled] +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 [labelled] +\tos_build: PQ2A.190405.003 @2019-05-01 00:00:00+00:00 [labelled] + +Reading data for phone#4c410523#20190502: +Column Family cell_plan +\tdata_plan_05gb: true @2019-05-01 00:00:00+00:00 [labelled] +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 [labelled] +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 [labelled] +\tos_build: PQ2A.190405.004 @2019-05-01 00:00:00+00:00 [labelled] + +Reading data for phone#4c410523#20190505: +Column Family cell_plan +\tdata_plan_05gb: true @2019-05-01 00:00:00+00:00 [labelled] +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x00 @2019-05-01 00:00:00+00:00 [labelled] +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 [labelled] +\tos_build: PQ2A.190406.000 @2019-05-01 00:00:00+00:00 [labelled] + +Reading data for phone#5c10102#20190501: +Column Family cell_plan +\tdata_plan_10gb: true @2019-05-01 00:00:00+00:00 [labelled] +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 [labelled] +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 [labelled] +\tos_build: PQ2A.190401.002 @2019-05-01 00:00:00+00:00 [labelled] + +Reading data for phone#5c10102#20190502: +Column Family cell_plan +\tdata_plan_10gb: true @2019-05-01 00:00:00+00:00 [labelled] +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 [labelled] +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x00 @2019-05-01 00:00:00+00:00 [labelled] +\tos_build: PQ2A.190406.000 @2019-05-01 00:00:00+00:00 [labelled] + +""" + +snapshots["test_filter_composing_chain"] = """Reading data for phone#4c410523#20190501: +Column Family cell_plan +\tdata_plan_01gb: false @2019-05-01 00:00:00+00:00 +\tdata_plan_05gb: true @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190502: +Column Family cell_plan +\tdata_plan_05gb: true @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190505: +Column Family cell_plan +\tdata_plan_05gb: true @2019-05-01 00:00:00+00:00 + +Reading data for phone#5c10102#20190501: +Column Family cell_plan +\tdata_plan_10gb: true @2019-05-01 00:00:00+00:00 + +Reading data for phone#5c10102#20190502: +Column Family cell_plan +\tdata_plan_10gb: true @2019-05-01 00:00:00+00:00 + +""" + +snapshots[ + "test_filter_composing_interleave" +] = """Reading data for phone#4c410523#20190501: +Column Family cell_plan +\tdata_plan_01gb: true @2019-04-30 23:00:00+00:00 +\tdata_plan_05gb: true @2019-05-01 00:00:00+00:00 +Column Family stats_summary +\tos_build: PQ2A.190405.003 @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190502: +Column Family cell_plan +\tdata_plan_05gb: true @2019-05-01 00:00:00+00:00 +Column Family stats_summary +\tos_build: PQ2A.190405.004 @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190505: +Column Family cell_plan +\tdata_plan_05gb: true @2019-05-01 00:00:00+00:00 +Column Family stats_summary +\tos_build: PQ2A.190406.000 @2019-05-01 00:00:00+00:00 + +Reading data for phone#5c10102#20190501: +Column Family cell_plan +\tdata_plan_10gb: true @2019-05-01 00:00:00+00:00 +Column Family stats_summary +\tos_build: PQ2A.190401.002 @2019-05-01 00:00:00+00:00 + +Reading data for phone#5c10102#20190502: +Column Family cell_plan +\tdata_plan_10gb: true @2019-05-01 00:00:00+00:00 +Column Family stats_summary +\tos_build: PQ2A.190406.000 @2019-05-01 00:00:00+00:00 + +""" + +snapshots[ + "test_filter_composing_condition" +] = """Reading data for phone#4c410523#20190501: +Column Family cell_plan +\tdata_plan_01gb: false @2019-05-01 00:00:00+00:00 [filtered-out] +\tdata_plan_01gb: true @2019-04-30 23:00:00+00:00 [filtered-out] +\tdata_plan_05gb: true @2019-05-01 00:00:00+00:00 [filtered-out] +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 [filtered-out] +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 [filtered-out] +\tos_build: PQ2A.190405.003 @2019-05-01 00:00:00+00:00 [filtered-out] + +Reading data for phone#4c410523#20190502: +Column Family cell_plan +\tdata_plan_05gb: true @2019-05-01 00:00:00+00:00 [filtered-out] +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 [filtered-out] +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 [filtered-out] +\tos_build: PQ2A.190405.004 @2019-05-01 00:00:00+00:00 [filtered-out] + +Reading data for phone#4c410523#20190505: +Column Family cell_plan +\tdata_plan_05gb: true @2019-05-01 00:00:00+00:00 [filtered-out] +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x00 @2019-05-01 00:00:00+00:00 [filtered-out] +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 [filtered-out] +\tos_build: PQ2A.190406.000 @2019-05-01 00:00:00+00:00 [filtered-out] + +Reading data for phone#5c10102#20190501: +Column Family cell_plan +\tdata_plan_10gb: true @2019-05-01 00:00:00+00:00 [passed-filter] +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 [passed-filter] +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 [passed-filter] +\tos_build: PQ2A.190401.002 @2019-05-01 00:00:00+00:00 [passed-filter] + +Reading data for phone#5c10102#20190502: +Column Family cell_plan +\tdata_plan_10gb: true @2019-05-01 00:00:00+00:00 [passed-filter] +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 [passed-filter] +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x00 @2019-05-01 00:00:00+00:00 [passed-filter] +\tos_build: PQ2A.190406.000 @2019-05-01 00:00:00+00:00 [passed-filter] + +""" diff --git a/packages/google-cloud-bigtable/samples/snippets/reads/__init__.py b/packages/google-cloud-bigtable/samples/snippets/reads/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-cloud-bigtable/samples/snippets/reads/noxfile.py b/packages/google-cloud-bigtable/samples/snippets/reads/noxfile.py new file mode 100644 index 000000000000..c0e60097b353 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/reads/noxfile.py @@ -0,0 +1,292 @@ +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import print_function + +import glob +import os +import sys +from pathlib import Path +from typing import Callable, Dict, Optional + +import nox + +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING +# DO NOT EDIT THIS FILE EVER! +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING + +BLACK_VERSION = "black==22.3.0" +ISORT_VERSION = "isort==5.10.1" + +# Copy `noxfile_config.py` to your directory and modify it instead. + +# `TEST_CONFIG` dict is a configuration hook that allows users to +# modify the test configurations. The values here should be in sync +# with `noxfile_config.py`. Users will copy `noxfile_config.py` into +# their directory and modify it. + +TEST_CONFIG = { + # You can opt out from the test for specific Python versions. + "ignored_versions": [], + # Old samples are opted out of enforcing Python type hints + # All new samples should feature them + "enforce_type_hints": False, + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", + # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + # If you need to use a specific version of pip, + # change pip_version_override to the string representation + # of the version number, for example, "20.2.4" + "pip_version_override": None, + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + "envs": {}, +} + + +try: + # Ensure we can import noxfile_config in the project's directory. + sys.path.append(".") + from noxfile_config import TEST_CONFIG_OVERRIDE +except ImportError as e: + print("No user noxfile_config found: detail: {}".format(e)) + TEST_CONFIG_OVERRIDE = {} + +# Update the TEST_CONFIG with the user supplied values. +TEST_CONFIG.update(TEST_CONFIG_OVERRIDE) + + +def get_pytest_env_vars() -> Dict[str, str]: + """Returns a dict for pytest invocation.""" + ret = {} + + # Override the GCLOUD_PROJECT and the alias. + env_key = TEST_CONFIG["gcloud_project_env"] + # This should error out if not set. + ret["GOOGLE_CLOUD_PROJECT"] = os.environ[env_key] + + # Apply user supplied envs. + ret.update(TEST_CONFIG["envs"]) + return ret + + +# DO NOT EDIT - automatically generated. +# All versions used to test samples. +ALL_VERSIONS = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + +# Any default versions that should be ignored. +IGNORED_VERSIONS = TEST_CONFIG["ignored_versions"] + +TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) + +INSTALL_LIBRARY_FROM_SOURCE = os.environ.get("INSTALL_LIBRARY_FROM_SOURCE", False) in ( + "True", + "true", +) + +# Error if a python version is missing +nox.options.error_on_missing_interpreters = True + +# +# Style Checks +# + + +# Linting with flake8. +# +# We ignore the following rules: +# E203: whitespace before ‘:’ +# E266: too many leading ‘#’ for block comment +# E501: line too long +# I202: Additional newline in a section of imports +# +# We also need to specify the rules which are ignored by default: +# ['E226', 'W504', 'E126', 'E123', 'W503', 'E24', 'E704', 'E121'] +FLAKE8_COMMON_ARGS = [ + "--show-source", + "--builtin=gettext", + "--max-complexity=20", + "--exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py", + "--ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202", + "--max-line-length=88", +] + + +@nox.session +def lint(session: nox.sessions.Session) -> None: + if not TEST_CONFIG["enforce_type_hints"]: + session.install("flake8") + else: + session.install("flake8", "flake8-annotations") + + args = FLAKE8_COMMON_ARGS + [ + ".", + ] + session.run("flake8", *args) + + +# +# Black +# + + +@nox.session +def blacken(session: nox.sessions.Session) -> None: + """Run black. Format code to uniform standard.""" + session.install(BLACK_VERSION) + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + session.run("black", *python_files) + + +# +# format = isort + black +# + + +@nox.session +def format(session: nox.sessions.Session) -> None: + """ + Run isort to sort imports. Then run black + to format code to uniform standard. + """ + session.install(BLACK_VERSION, ISORT_VERSION) + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + # Use the --fss option to sort imports using strict alphabetical order. + # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + session.run("isort", "--fss", *python_files) + session.run("black", *python_files) + + +# +# Sample Tests +# + + +PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] + + +def _session_tests( + session: nox.sessions.Session, post_install: Callable = None +) -> None: + # check for presence of tests + test_list = glob.glob("**/*_test.py", recursive=True) + glob.glob( + "**/test_*.py", recursive=True + ) + test_list.extend(glob.glob("**/tests", recursive=True)) + + if len(test_list) == 0: + print("No tests found, skipping directory.") + return + + if TEST_CONFIG["pip_version_override"]: + pip_version = TEST_CONFIG["pip_version_override"] + session.install(f"pip=={pip_version}") + """Runs py.test for a particular project.""" + concurrent_args = [] + if os.path.exists("requirements.txt"): + if os.path.exists("constraints.txt"): + session.install("-r", "requirements.txt", "-c", "constraints.txt") + else: + session.install("-r", "requirements.txt") + with open("requirements.txt") as rfile: + packages = rfile.read() + + if os.path.exists("requirements-test.txt"): + if os.path.exists("constraints-test.txt"): + session.install("-r", "requirements-test.txt", "-c", "constraints-test.txt") + else: + session.install("-r", "requirements-test.txt") + with open("requirements-test.txt") as rtfile: + packages += rtfile.read() + + if INSTALL_LIBRARY_FROM_SOURCE: + session.install("-e", _get_repo_root()) + + if post_install: + post_install(session) + + if "pytest-parallel" in packages: + concurrent_args.extend(["--workers", "auto", "--tests-per-worker", "auto"]) + elif "pytest-xdist" in packages: + concurrent_args.extend(["-n", "auto"]) + + session.run( + "pytest", + *(PYTEST_COMMON_ARGS + session.posargs + concurrent_args), + # Pytest will return 5 when no tests are collected. This can happen + # on travis where slow and flaky tests are excluded. + # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html + success_codes=[0, 5], + env=get_pytest_env_vars(), + ) + + +@nox.session(python=ALL_VERSIONS) +def py(session: nox.sessions.Session) -> None: + """Runs py.test for a sample using the specified version of Python.""" + if session.python in TESTED_VERSIONS: + _session_tests(session) + else: + session.skip( + "SKIPPED: {} tests are disabled for this sample.".format(session.python) + ) + + +# +# Readmegen +# + + +def _get_repo_root() -> Optional[str]: + """Returns the root folder of the project.""" + # Get root of this repository. Assume we don't have directories nested deeper than 10 items. + p = Path(os.getcwd()) + for i in range(10): + if p is None: + break + if Path(p / ".git").exists(): + return str(p) + # .git is not available in repos cloned via Cloud Build + # setup.py is always in the library's root, so use that instead + # https://github.com/googleapis/synthtool/issues/792 + if Path(p / "setup.py").exists(): + return str(p) + p = p.parent + raise Exception("Unable to detect repository root.") + + +GENERATED_READMES = sorted([x for x in Path(".").rglob("*.rst.in")]) + + +@nox.session +@nox.parametrize("path", GENERATED_READMES) +def readmegen(session: nox.sessions.Session, path: str) -> None: + """(Re-)generates the readme for a sample.""" + session.install("jinja2", "pyyaml") + dir_ = os.path.dirname(path) + + if os.path.exists(os.path.join(dir_, "requirements.txt")): + session.install("-r", os.path.join(dir_, "requirements.txt")) + + in_file = os.path.join(dir_, "README.rst.in") + session.run( + "python", _get_repo_root() + "/scripts/readme-gen/readme_gen.py", in_file + ) diff --git a/packages/google-cloud-bigtable/samples/snippets/reads/read_snippets.py b/packages/google-cloud-bigtable/samples/snippets/reads/read_snippets.py new file mode 100644 index 000000000000..7bdf01c7c890 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/reads/read_snippets.py @@ -0,0 +1,170 @@ +#!/usr/bin/env python + +# 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. + +# [START bigtable_reads_row] +def read_row(project_id, instance_id, table_id): + from google.cloud import bigtable + + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + + row_key = "phone#4c410523#20190501" + + row = table.read_row(row_key) + print_row(row) + + +# [END bigtable_reads_row] + + +# [START bigtable_reads_row_partial] +def read_row_partial(project_id, instance_id, table_id): + from google.cloud import bigtable + from google.cloud.bigtable import row_filters + + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + + row_key = "phone#4c410523#20190501" + col_filter = row_filters.ColumnQualifierRegexFilter(b"os_build") + + row = table.read_row(row_key, filter_=col_filter) + print_row(row) + + +# [END bigtable_reads_row_partial] +# [START bigtable_reads_rows] +def read_rows(project_id, instance_id, table_id): + from google.cloud import bigtable + from google.cloud.bigtable.row_set import RowSet + + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + + row_set = RowSet() + row_set.add_row_key(b"phone#4c410523#20190501") + row_set.add_row_key(b"phone#4c410523#20190502") + + rows = table.read_rows(row_set=row_set) + for row in rows: + print_row(row) + + +# [END bigtable_reads_rows] +# [START bigtable_reads_row_range] +def read_row_range(project_id, instance_id, table_id): + from google.cloud import bigtable + from google.cloud.bigtable.row_set import RowSet + + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + + row_set = RowSet() + row_set.add_row_range_from_keys( + start_key=b"phone#4c410523#20190501", end_key=b"phone#4c410523#201906201" + ) + + rows = table.read_rows(row_set=row_set) + for row in rows: + print_row(row) + + +# [END bigtable_reads_row_range] +# [START bigtable_reads_row_ranges] +def read_row_ranges(project_id, instance_id, table_id): + from google.cloud import bigtable + from google.cloud.bigtable.row_set import RowSet + + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + + row_set = RowSet() + row_set.add_row_range_from_keys( + start_key=b"phone#4c410523#20190501", end_key=b"phone#4c410523#201906201" + ) + row_set.add_row_range_from_keys( + start_key=b"phone#5c10102#20190501", end_key=b"phone#5c10102#201906201" + ) + + rows = table.read_rows(row_set=row_set) + for row in rows: + print_row(row) + + +# [END bigtable_reads_row_ranges] +# [START bigtable_reads_prefix] +def read_prefix(project_id, instance_id, table_id): + from google.cloud import bigtable + from google.cloud.bigtable.row_set import RowSet + + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + prefix = "phone#" + end_key = prefix[:-1] + chr(ord(prefix[-1]) + 1) + + row_set = RowSet() + row_set.add_row_range_from_keys(prefix.encode("utf-8"), end_key.encode("utf-8")) + + rows = table.read_rows(row_set=row_set) + for row in rows: + print_row(row) + + +# [END bigtable_reads_prefix] +# [START bigtable_reads_filter] +def read_filter(project_id, instance_id, table_id): + from google.cloud import bigtable + from google.cloud.bigtable import row_filters + + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + + rows = table.read_rows(filter_=row_filters.ValueRegexFilter(b"PQ2A.*$")) + for row in rows: + print_row(row) + + +# [END bigtable_reads_filter] + + +# [START bigtable_reads_print] +def print_row(row): + print("Reading data for {}:".format(row.row_key.decode("utf-8"))) + for cf, cols in sorted(row.cells.items()): + print("Column Family {}".format(cf)) + for col, cells in sorted(cols.items()): + for cell in cells: + labels = ( + " [{}]".format(",".join(cell.labels)) if len(cell.labels) else "" + ) + print( + "\t{}: {} @{}{}".format( + col.decode("utf-8"), + cell.value.decode("utf-8"), + cell.timestamp, + labels, + ) + ) + print("") + + +# [END bigtable_reads_print] diff --git a/packages/google-cloud-bigtable/samples/snippets/reads/reads_test.py b/packages/google-cloud-bigtable/samples/snippets/reads/reads_test.py new file mode 100644 index 000000000000..251141954955 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/reads/reads_test.py @@ -0,0 +1,118 @@ +# 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 datetime +import inspect +import os +import uuid + +import pytest + +from ...utils import create_table_cm +from . import read_snippets +from .snapshots.snap_reads_test import snapshots + +PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"] +BIGTABLE_INSTANCE = os.environ["BIGTABLE_INSTANCE"] +TABLE_ID = f"mobile-time-series-reads-{str(uuid.uuid4())[:16]}" + + +@pytest.fixture(scope="module", autouse=True) +def table_id(): + with create_table_cm( + PROJECT, BIGTABLE_INSTANCE, TABLE_ID, {"stats_summary": None} + ) as table: + timestamp = datetime.datetime(2019, 5, 1) + rows = [ + table.direct_row("phone#4c410523#20190501"), + table.direct_row("phone#4c410523#20190502"), + table.direct_row("phone#4c410523#20190505"), + table.direct_row("phone#5c10102#20190501"), + table.direct_row("phone#5c10102#20190502"), + ] + + rows[0].set_cell("stats_summary", "connected_cell", 1, timestamp) + rows[0].set_cell("stats_summary", "connected_wifi", 1, timestamp) + rows[0].set_cell("stats_summary", "os_build", "PQ2A.190405.003", timestamp) + rows[1].set_cell("stats_summary", "connected_cell", 1, timestamp) + rows[1].set_cell("stats_summary", "connected_wifi", 1, timestamp) + rows[1].set_cell("stats_summary", "os_build", "PQ2A.190405.004", timestamp) + rows[2].set_cell("stats_summary", "connected_cell", 0, timestamp) + rows[2].set_cell("stats_summary", "connected_wifi", 1, timestamp) + rows[2].set_cell("stats_summary", "os_build", "PQ2A.190406.000", timestamp) + rows[3].set_cell("stats_summary", "connected_cell", 1, timestamp) + rows[3].set_cell("stats_summary", "connected_wifi", 1, timestamp) + rows[3].set_cell("stats_summary", "os_build", "PQ2A.190401.002", timestamp) + rows[4].set_cell("stats_summary", "connected_cell", 1, timestamp) + rows[4].set_cell("stats_summary", "connected_wifi", 0, timestamp) + rows[4].set_cell("stats_summary", "os_build", "PQ2A.190406.000", timestamp) + + table.mutate_rows(rows) + + yield TABLE_ID + + +def test_read_row(capsys, table_id): + read_snippets.read_row(PROJECT, BIGTABLE_INSTANCE, table_id) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +def test_read_row_partial(capsys, table_id): + read_snippets.read_row_partial(PROJECT, BIGTABLE_INSTANCE, table_id) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +def test_read_rows(capsys, table_id): + read_snippets.read_rows(PROJECT, BIGTABLE_INSTANCE, table_id) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +def test_read_row_range(capsys, table_id): + read_snippets.read_row_range(PROJECT, BIGTABLE_INSTANCE, table_id) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +def test_read_row_ranges(capsys, table_id): + read_snippets.read_row_ranges(PROJECT, BIGTABLE_INSTANCE, table_id) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +def test_read_prefix(capsys, table_id): + read_snippets.read_prefix(PROJECT, BIGTABLE_INSTANCE, table_id) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected + + +def test_read_filter(capsys, table_id): + read_snippets.read_filter(PROJECT, BIGTABLE_INSTANCE, table_id) + + out, _ = capsys.readouterr() + expected = snapshots[inspect.currentframe().f_code.co_name] + assert out == expected diff --git a/packages/google-cloud-bigtable/samples/snippets/reads/requirements-test.txt b/packages/google-cloud-bigtable/samples/snippets/reads/requirements-test.txt new file mode 100644 index 000000000000..e079f8a6038d --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/reads/requirements-test.txt @@ -0,0 +1 @@ +pytest diff --git a/packages/google-cloud-bigtable/samples/snippets/reads/requirements.txt b/packages/google-cloud-bigtable/samples/snippets/reads/requirements.txt new file mode 100644 index 000000000000..730d25dec63f --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/reads/requirements.txt @@ -0,0 +1 @@ +google-cloud-bigtable==2.35.0 diff --git a/packages/google-cloud-bigtable/samples/snippets/reads/snapshots/__init__.py b/packages/google-cloud-bigtable/samples/snippets/reads/snapshots/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-cloud-bigtable/samples/snippets/reads/snapshots/snap_reads_test.py b/packages/google-cloud-bigtable/samples/snippets/reads/snapshots/snap_reads_test.py new file mode 100644 index 000000000000..c2449d123a38 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/reads/snapshots/snap_reads_test.py @@ -0,0 +1,141 @@ +# -*- coding: utf-8 -*- +# this was previously implemented using the `snapshottest` package (https://goo.gl/zC4yUc), +# which is not compatible with Python 3.12. So we moved to a standard dictionary storing +# expected outputs for each test +from __future__ import unicode_literals + +snapshots = {} + +snapshots["test_read_row_partial"] = """Reading data for phone#4c410523#20190501: +Column Family stats_summary +\tos_build: PQ2A.190405.003 @2019-05-01 00:00:00+00:00 + +""" + +snapshots["test_read_rows"] = """Reading data for phone#4c410523#20190501: +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190405.003 @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190502: +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190405.004 @2019-05-01 00:00:00+00:00 + +""" + +snapshots["test_read_row_range"] = """Reading data for phone#4c410523#20190501: +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190405.003 @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190502: +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190405.004 @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190505: +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x00 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190406.000 @2019-05-01 00:00:00+00:00 + +""" + +snapshots["test_read_row_ranges"] = """Reading data for phone#4c410523#20190501: +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190405.003 @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190502: +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190405.004 @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190505: +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x00 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190406.000 @2019-05-01 00:00:00+00:00 + +Reading data for phone#5c10102#20190501: +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190401.002 @2019-05-01 00:00:00+00:00 + +Reading data for phone#5c10102#20190502: +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x00 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190406.000 @2019-05-01 00:00:00+00:00 + +""" + +snapshots["test_read_prefix"] = """Reading data for phone#4c410523#20190501: +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190405.003 @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190502: +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190405.004 @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190505: +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x00 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190406.000 @2019-05-01 00:00:00+00:00 + +Reading data for phone#5c10102#20190501: +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190401.002 @2019-05-01 00:00:00+00:00 + +Reading data for phone#5c10102#20190502: +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x00 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190406.000 @2019-05-01 00:00:00+00:00 + +""" + +snapshots["test_read_filter"] = """Reading data for phone#4c410523#20190501: +Column Family stats_summary +\tos_build: PQ2A.190405.003 @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190502: +Column Family stats_summary +\tos_build: PQ2A.190405.004 @2019-05-01 00:00:00+00:00 + +Reading data for phone#4c410523#20190505: +Column Family stats_summary +\tos_build: PQ2A.190406.000 @2019-05-01 00:00:00+00:00 + +Reading data for phone#5c10102#20190501: +Column Family stats_summary +\tos_build: PQ2A.190401.002 @2019-05-01 00:00:00+00:00 + +Reading data for phone#5c10102#20190502: +Column Family stats_summary +\tos_build: PQ2A.190406.000 @2019-05-01 00:00:00+00:00 + +""" + +snapshots["test_read_row"] = """Reading data for phone#4c410523#20190501: +Column Family stats_summary +\tconnected_cell: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tconnected_wifi: \x00\x00\x00\x00\x00\x00\x00\x01 @2019-05-01 00:00:00+00:00 +\tos_build: PQ2A.190405.003 @2019-05-01 00:00:00+00:00 + +""" diff --git a/packages/google-cloud-bigtable/samples/snippets/writes/__init__.py b/packages/google-cloud-bigtable/samples/snippets/writes/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-cloud-bigtable/samples/snippets/writes/noxfile.py b/packages/google-cloud-bigtable/samples/snippets/writes/noxfile.py new file mode 100644 index 000000000000..c0e60097b353 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/writes/noxfile.py @@ -0,0 +1,292 @@ +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import print_function + +import glob +import os +import sys +from pathlib import Path +from typing import Callable, Dict, Optional + +import nox + +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING +# DO NOT EDIT THIS FILE EVER! +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING + +BLACK_VERSION = "black==22.3.0" +ISORT_VERSION = "isort==5.10.1" + +# Copy `noxfile_config.py` to your directory and modify it instead. + +# `TEST_CONFIG` dict is a configuration hook that allows users to +# modify the test configurations. The values here should be in sync +# with `noxfile_config.py`. Users will copy `noxfile_config.py` into +# their directory and modify it. + +TEST_CONFIG = { + # You can opt out from the test for specific Python versions. + "ignored_versions": [], + # Old samples are opted out of enforcing Python type hints + # All new samples should feature them + "enforce_type_hints": False, + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", + # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + # If you need to use a specific version of pip, + # change pip_version_override to the string representation + # of the version number, for example, "20.2.4" + "pip_version_override": None, + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + "envs": {}, +} + + +try: + # Ensure we can import noxfile_config in the project's directory. + sys.path.append(".") + from noxfile_config import TEST_CONFIG_OVERRIDE +except ImportError as e: + print("No user noxfile_config found: detail: {}".format(e)) + TEST_CONFIG_OVERRIDE = {} + +# Update the TEST_CONFIG with the user supplied values. +TEST_CONFIG.update(TEST_CONFIG_OVERRIDE) + + +def get_pytest_env_vars() -> Dict[str, str]: + """Returns a dict for pytest invocation.""" + ret = {} + + # Override the GCLOUD_PROJECT and the alias. + env_key = TEST_CONFIG["gcloud_project_env"] + # This should error out if not set. + ret["GOOGLE_CLOUD_PROJECT"] = os.environ[env_key] + + # Apply user supplied envs. + ret.update(TEST_CONFIG["envs"]) + return ret + + +# DO NOT EDIT - automatically generated. +# All versions used to test samples. +ALL_VERSIONS = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + +# Any default versions that should be ignored. +IGNORED_VERSIONS = TEST_CONFIG["ignored_versions"] + +TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) + +INSTALL_LIBRARY_FROM_SOURCE = os.environ.get("INSTALL_LIBRARY_FROM_SOURCE", False) in ( + "True", + "true", +) + +# Error if a python version is missing +nox.options.error_on_missing_interpreters = True + +# +# Style Checks +# + + +# Linting with flake8. +# +# We ignore the following rules: +# E203: whitespace before ‘:’ +# E266: too many leading ‘#’ for block comment +# E501: line too long +# I202: Additional newline in a section of imports +# +# We also need to specify the rules which are ignored by default: +# ['E226', 'W504', 'E126', 'E123', 'W503', 'E24', 'E704', 'E121'] +FLAKE8_COMMON_ARGS = [ + "--show-source", + "--builtin=gettext", + "--max-complexity=20", + "--exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py", + "--ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202", + "--max-line-length=88", +] + + +@nox.session +def lint(session: nox.sessions.Session) -> None: + if not TEST_CONFIG["enforce_type_hints"]: + session.install("flake8") + else: + session.install("flake8", "flake8-annotations") + + args = FLAKE8_COMMON_ARGS + [ + ".", + ] + session.run("flake8", *args) + + +# +# Black +# + + +@nox.session +def blacken(session: nox.sessions.Session) -> None: + """Run black. Format code to uniform standard.""" + session.install(BLACK_VERSION) + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + session.run("black", *python_files) + + +# +# format = isort + black +# + + +@nox.session +def format(session: nox.sessions.Session) -> None: + """ + Run isort to sort imports. Then run black + to format code to uniform standard. + """ + session.install(BLACK_VERSION, ISORT_VERSION) + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + # Use the --fss option to sort imports using strict alphabetical order. + # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + session.run("isort", "--fss", *python_files) + session.run("black", *python_files) + + +# +# Sample Tests +# + + +PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] + + +def _session_tests( + session: nox.sessions.Session, post_install: Callable = None +) -> None: + # check for presence of tests + test_list = glob.glob("**/*_test.py", recursive=True) + glob.glob( + "**/test_*.py", recursive=True + ) + test_list.extend(glob.glob("**/tests", recursive=True)) + + if len(test_list) == 0: + print("No tests found, skipping directory.") + return + + if TEST_CONFIG["pip_version_override"]: + pip_version = TEST_CONFIG["pip_version_override"] + session.install(f"pip=={pip_version}") + """Runs py.test for a particular project.""" + concurrent_args = [] + if os.path.exists("requirements.txt"): + if os.path.exists("constraints.txt"): + session.install("-r", "requirements.txt", "-c", "constraints.txt") + else: + session.install("-r", "requirements.txt") + with open("requirements.txt") as rfile: + packages = rfile.read() + + if os.path.exists("requirements-test.txt"): + if os.path.exists("constraints-test.txt"): + session.install("-r", "requirements-test.txt", "-c", "constraints-test.txt") + else: + session.install("-r", "requirements-test.txt") + with open("requirements-test.txt") as rtfile: + packages += rtfile.read() + + if INSTALL_LIBRARY_FROM_SOURCE: + session.install("-e", _get_repo_root()) + + if post_install: + post_install(session) + + if "pytest-parallel" in packages: + concurrent_args.extend(["--workers", "auto", "--tests-per-worker", "auto"]) + elif "pytest-xdist" in packages: + concurrent_args.extend(["-n", "auto"]) + + session.run( + "pytest", + *(PYTEST_COMMON_ARGS + session.posargs + concurrent_args), + # Pytest will return 5 when no tests are collected. This can happen + # on travis where slow and flaky tests are excluded. + # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html + success_codes=[0, 5], + env=get_pytest_env_vars(), + ) + + +@nox.session(python=ALL_VERSIONS) +def py(session: nox.sessions.Session) -> None: + """Runs py.test for a sample using the specified version of Python.""" + if session.python in TESTED_VERSIONS: + _session_tests(session) + else: + session.skip( + "SKIPPED: {} tests are disabled for this sample.".format(session.python) + ) + + +# +# Readmegen +# + + +def _get_repo_root() -> Optional[str]: + """Returns the root folder of the project.""" + # Get root of this repository. Assume we don't have directories nested deeper than 10 items. + p = Path(os.getcwd()) + for i in range(10): + if p is None: + break + if Path(p / ".git").exists(): + return str(p) + # .git is not available in repos cloned via Cloud Build + # setup.py is always in the library's root, so use that instead + # https://github.com/googleapis/synthtool/issues/792 + if Path(p / "setup.py").exists(): + return str(p) + p = p.parent + raise Exception("Unable to detect repository root.") + + +GENERATED_READMES = sorted([x for x in Path(".").rglob("*.rst.in")]) + + +@nox.session +@nox.parametrize("path", GENERATED_READMES) +def readmegen(session: nox.sessions.Session, path: str) -> None: + """(Re-)generates the readme for a sample.""" + session.install("jinja2", "pyyaml") + dir_ = os.path.dirname(path) + + if os.path.exists(os.path.join(dir_, "requirements.txt")): + session.install("-r", os.path.join(dir_, "requirements.txt")) + + in_file = os.path.join(dir_, "README.rst.in") + session.run( + "python", _get_repo_root() + "/scripts/readme-gen/readme_gen.py", in_file + ) diff --git a/packages/google-cloud-bigtable/samples/snippets/writes/requirements-test.txt b/packages/google-cloud-bigtable/samples/snippets/writes/requirements-test.txt new file mode 100644 index 000000000000..5e15eb26f589 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/writes/requirements-test.txt @@ -0,0 +1,2 @@ +backoff==2.2.1 +pytest diff --git a/packages/google-cloud-bigtable/samples/snippets/writes/requirements.txt b/packages/google-cloud-bigtable/samples/snippets/writes/requirements.txt new file mode 100644 index 000000000000..54c0c14a3c5b --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/writes/requirements.txt @@ -0,0 +1 @@ +google-cloud-bigtable==2.35.0 \ No newline at end of file diff --git a/packages/google-cloud-bigtable/samples/snippets/writes/write_batch.py b/packages/google-cloud-bigtable/samples/snippets/writes/write_batch.py new file mode 100644 index 000000000000..a583bb7134e1 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/writes/write_batch.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python + +# Copyright 2019, 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. +# [START bigtable_writes_batch] +from datetime import datetime, timezone + +from google.cloud import bigtable +from google.cloud.bigtable.batcher import MutationsBatcher + + +def write_batch(project_id, instance_id, table_id): + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + + with MutationsBatcher(table=table) as batcher: + timestamp = datetime.now(timezone.utc) + column_family_id = "stats_summary" + + rows = [ + table.direct_row("tablet#a0b81f74#20190501"), + table.direct_row("tablet#a0b81f74#20190502"), + ] + + rows[0].set_cell(column_family_id, "connected_wifi", 1, timestamp) + rows[0].set_cell(column_family_id, "os_build", "12155.0.0-rc1", timestamp) + rows[1].set_cell(column_family_id, "connected_wifi", 1, timestamp) + rows[1].set_cell(column_family_id, "os_build", "12145.0.0-rc6", timestamp) + + batcher.mutate_rows(rows) + + print("Successfully wrote 2 rows.") + + +# [END bigtable_writes_batch] diff --git a/packages/google-cloud-bigtable/samples/snippets/writes/write_conditionally.py b/packages/google-cloud-bigtable/samples/snippets/writes/write_conditionally.py new file mode 100644 index 000000000000..b6f05fba77f4 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/writes/write_conditionally.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python + +# Copyright 2019, 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. +# [START bigtable_writes_conditional] +from datetime import datetime, timezone + +from google.cloud import bigtable +from google.cloud.bigtable import row_filters + + +def write_conditional(project_id, instance_id, table_id): + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + + timestamp = datetime.now(timezone.utc) + column_family_id = "stats_summary" + + row_key = "phone#4c410523#20190501" + + row_filter = row_filters.RowFilterChain( + filters=[ + row_filters.FamilyNameRegexFilter(column_family_id), + row_filters.ColumnQualifierRegexFilter("os_build"), + row_filters.ValueRegexFilter("PQ2A\\..*"), + ] + ) + row = table.conditional_row(row_key, filter_=row_filter) + row.set_cell(column_family_id, "os_name", "android", timestamp) + row.commit() + + print("Successfully updated row's os_name.") + + +# [END bigtable_writes_conditional] diff --git a/packages/google-cloud-bigtable/samples/snippets/writes/write_increment.py b/packages/google-cloud-bigtable/samples/snippets/writes/write_increment.py new file mode 100644 index 000000000000..ac8e2d16af34 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/writes/write_increment.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python + +# Copyright 2019, 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. +# [START bigtable_writes_increment] +from google.cloud import bigtable + + +def write_increment(project_id, instance_id, table_id): + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + + column_family_id = "stats_summary" + + row_key = "phone#4c410523#20190501" + row = table.append_row(row_key) + + # Decrement the connected_wifi value by 1. + row.increment_cell_value(column_family_id, "connected_wifi", -1) + row.commit() + + print("Successfully updated row {}.".format(row_key)) + + +# [END bigtable_writes_increment] diff --git a/packages/google-cloud-bigtable/samples/snippets/writes/write_simple.py b/packages/google-cloud-bigtable/samples/snippets/writes/write_simple.py new file mode 100644 index 000000000000..fb7074bc526e --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/writes/write_simple.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python + +# Copyright 2019, 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. + +# [START bigtable_writes_simple] +from datetime import datetime, timezone + +from google.cloud import bigtable + + +def write_simple(project_id, instance_id, table_id): + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + + timestamp = datetime.now(timezone.utc) + column_family_id = "stats_summary" + + row_key = "phone#4c410523#20190501" + + row = table.direct_row(row_key) + row.set_cell(column_family_id, "connected_cell", 1, timestamp) + row.set_cell(column_family_id, "connected_wifi", 1, timestamp) + row.set_cell(column_family_id, "os_build", "PQ2A.190405.003", timestamp) + + row.commit() + + print("Successfully wrote row {}.".format(row_key)) + + +# [END bigtable_writes_simple] diff --git a/packages/google-cloud-bigtable/samples/snippets/writes/writes_test.py b/packages/google-cloud-bigtable/samples/snippets/writes/writes_test.py new file mode 100644 index 000000000000..663122d3e783 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/snippets/writes/writes_test.py @@ -0,0 +1,72 @@ +# Copyright 2018 Google Inc. +# +# 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 uuid + +import backoff +import pytest +from google.api_core.exceptions import DeadlineExceeded + +from ...utils import create_table_cm +from .write_batch import write_batch +from .write_conditionally import write_conditional +from .write_increment import write_increment +from .write_simple import write_simple + +PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"] +BIGTABLE_INSTANCE = os.environ["BIGTABLE_INSTANCE"] +TABLE_ID = f"mobile-time-series-writes-{str(uuid.uuid4())[:16]}" + + +@pytest.fixture +def table_id(): + with create_table_cm(PROJECT, BIGTABLE_INSTANCE, TABLE_ID, {"stats_summary": None}): + yield TABLE_ID + + +def test_writes(capsys, table_id): + # `row.commit()` sometimes ends up with DeadlineExceeded, so now + # we put retries with a hard deadline. + @backoff.on_exception(backoff.expo, DeadlineExceeded, max_time=60) + def _write_simple(): + write_simple(PROJECT, BIGTABLE_INSTANCE, table_id) + + _write_simple() + out, _ = capsys.readouterr() + assert "Successfully wrote row" in out + + @backoff.on_exception(backoff.expo, DeadlineExceeded, max_time=60) + def _write_increment(): + write_increment(PROJECT, BIGTABLE_INSTANCE, table_id) + + _write_increment() + out, _ = capsys.readouterr() + assert "Successfully updated row" in out + + @backoff.on_exception(backoff.expo, DeadlineExceeded, max_time=60) + def _write_conditional(): + write_conditional(PROJECT, BIGTABLE_INSTANCE, table_id) + + _write_conditional() + out, _ = capsys.readouterr() + assert "Successfully updated row's os_name" in out + + @backoff.on_exception(backoff.expo, DeadlineExceeded, max_time=60) + def _write_batch(): + write_batch(PROJECT, BIGTABLE_INSTANCE, table_id) + + _write_batch() + out, _ = capsys.readouterr() + assert "Successfully wrote 2 rows" in out diff --git a/packages/google-cloud-bigtable/samples/tableadmin/README.md b/packages/google-cloud-bigtable/samples/tableadmin/README.md new file mode 100644 index 000000000000..b2f6a13af55a --- /dev/null +++ b/packages/google-cloud-bigtable/samples/tableadmin/README.md @@ -0,0 +1,52 @@ +[//]: # "This README.md file is auto-generated, all changes to this file will be lost." +[//]: # "To regenerate it, use `python -m synthtool`." + +## Python Samples for Cloud Bigtable + +This directory contains samples for Cloud Bigtable, which may be used as a refererence for how to use this product. +Samples, quickstarts, and other documentation are available at cloud.google.com. + + +### Table Admin + +Demonstrates how to connect to Cloud Bigtable and run some basic operations. + + +Open in Cloud Shell + + +To run this sample: + +1. If this is your first time working with GCP products, you will need to set up [the Cloud SDK][cloud_sdk] or utilize [Google Cloud Shell][gcloud_shell]. This sample may [require authetication][authentication] and you will need to [enable billing][enable_billing]. + +1. Make a fork of this repo and clone the branch locally, then navigate to the sample directory you want to use. + +1. Install the dependencies needed to run the samples. + + pip install -r requirements.txt + +1. Run the sample using + + python tableadmin.py + + + +
usage: tableadmin.py [-h] [run] [delete] [--table TABLE] project_id instance_id 


Demonstrates how to connect to Cloud Bigtable and run some basic operations.
Prerequisites: - Create a Cloud Bigtable cluster.
https://cloud.google.com/bigtable/docs/creating-cluster - Set your Google
Application Default Credentials.
https://developers.google.com/identity/protocols/application-default-
credentials


positional arguments:
  project_id     Your Cloud Platform project ID.
  instance_id    ID of the Cloud Bigtable instance to connect to.


optional arguments:
  -h, --help     show this help message and exit
  --table TABLE  Table to create and destroy. (default: Hello-Bigtable)
+ +## Additional Information + +You can read the documentation for more details on API usage and use GitHub +to browse the source and [report issues][issues]. + +### Contributing +View the [contributing guidelines][contrib_guide], the [Python style guide][py_style] for more information. + +[authentication]: https://cloud.google.com/docs/authentication/getting-started +[enable_billing]:https://cloud.google.com/apis/docs/getting-started#enabling_billing +[client_library_python]: https://googlecloudplatform.github.io/google-cloud-python/ +[issues]: https://github.com/GoogleCloudPlatform/google-cloud-python/issues +[contrib_guide]: https://github.com/googleapis/google-cloud-python/blob/main/CONTRIBUTING.rst +[py_style]: http://google.github.io/styleguide/pyguide.html +[cloud_sdk]: https://cloud.google.com/sdk/docs +[gcloud_shell]: https://cloud.google.com/shell/docs +[gcloud_shell]: https://cloud.google.com/shell/docs diff --git a/packages/google-cloud-bigtable/samples/tableadmin/__init__.py b/packages/google-cloud-bigtable/samples/tableadmin/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-cloud-bigtable/samples/tableadmin/noxfile.py b/packages/google-cloud-bigtable/samples/tableadmin/noxfile.py new file mode 100644 index 000000000000..c0e60097b353 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/tableadmin/noxfile.py @@ -0,0 +1,292 @@ +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import print_function + +import glob +import os +import sys +from pathlib import Path +from typing import Callable, Dict, Optional + +import nox + +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING +# DO NOT EDIT THIS FILE EVER! +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING + +BLACK_VERSION = "black==22.3.0" +ISORT_VERSION = "isort==5.10.1" + +# Copy `noxfile_config.py` to your directory and modify it instead. + +# `TEST_CONFIG` dict is a configuration hook that allows users to +# modify the test configurations. The values here should be in sync +# with `noxfile_config.py`. Users will copy `noxfile_config.py` into +# their directory and modify it. + +TEST_CONFIG = { + # You can opt out from the test for specific Python versions. + "ignored_versions": [], + # Old samples are opted out of enforcing Python type hints + # All new samples should feature them + "enforce_type_hints": False, + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", + # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + # If you need to use a specific version of pip, + # change pip_version_override to the string representation + # of the version number, for example, "20.2.4" + "pip_version_override": None, + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + "envs": {}, +} + + +try: + # Ensure we can import noxfile_config in the project's directory. + sys.path.append(".") + from noxfile_config import TEST_CONFIG_OVERRIDE +except ImportError as e: + print("No user noxfile_config found: detail: {}".format(e)) + TEST_CONFIG_OVERRIDE = {} + +# Update the TEST_CONFIG with the user supplied values. +TEST_CONFIG.update(TEST_CONFIG_OVERRIDE) + + +def get_pytest_env_vars() -> Dict[str, str]: + """Returns a dict for pytest invocation.""" + ret = {} + + # Override the GCLOUD_PROJECT and the alias. + env_key = TEST_CONFIG["gcloud_project_env"] + # This should error out if not set. + ret["GOOGLE_CLOUD_PROJECT"] = os.environ[env_key] + + # Apply user supplied envs. + ret.update(TEST_CONFIG["envs"]) + return ret + + +# DO NOT EDIT - automatically generated. +# All versions used to test samples. +ALL_VERSIONS = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + +# Any default versions that should be ignored. +IGNORED_VERSIONS = TEST_CONFIG["ignored_versions"] + +TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) + +INSTALL_LIBRARY_FROM_SOURCE = os.environ.get("INSTALL_LIBRARY_FROM_SOURCE", False) in ( + "True", + "true", +) + +# Error if a python version is missing +nox.options.error_on_missing_interpreters = True + +# +# Style Checks +# + + +# Linting with flake8. +# +# We ignore the following rules: +# E203: whitespace before ‘:’ +# E266: too many leading ‘#’ for block comment +# E501: line too long +# I202: Additional newline in a section of imports +# +# We also need to specify the rules which are ignored by default: +# ['E226', 'W504', 'E126', 'E123', 'W503', 'E24', 'E704', 'E121'] +FLAKE8_COMMON_ARGS = [ + "--show-source", + "--builtin=gettext", + "--max-complexity=20", + "--exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py", + "--ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202", + "--max-line-length=88", +] + + +@nox.session +def lint(session: nox.sessions.Session) -> None: + if not TEST_CONFIG["enforce_type_hints"]: + session.install("flake8") + else: + session.install("flake8", "flake8-annotations") + + args = FLAKE8_COMMON_ARGS + [ + ".", + ] + session.run("flake8", *args) + + +# +# Black +# + + +@nox.session +def blacken(session: nox.sessions.Session) -> None: + """Run black. Format code to uniform standard.""" + session.install(BLACK_VERSION) + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + session.run("black", *python_files) + + +# +# format = isort + black +# + + +@nox.session +def format(session: nox.sessions.Session) -> None: + """ + Run isort to sort imports. Then run black + to format code to uniform standard. + """ + session.install(BLACK_VERSION, ISORT_VERSION) + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + # Use the --fss option to sort imports using strict alphabetical order. + # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + session.run("isort", "--fss", *python_files) + session.run("black", *python_files) + + +# +# Sample Tests +# + + +PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] + + +def _session_tests( + session: nox.sessions.Session, post_install: Callable = None +) -> None: + # check for presence of tests + test_list = glob.glob("**/*_test.py", recursive=True) + glob.glob( + "**/test_*.py", recursive=True + ) + test_list.extend(glob.glob("**/tests", recursive=True)) + + if len(test_list) == 0: + print("No tests found, skipping directory.") + return + + if TEST_CONFIG["pip_version_override"]: + pip_version = TEST_CONFIG["pip_version_override"] + session.install(f"pip=={pip_version}") + """Runs py.test for a particular project.""" + concurrent_args = [] + if os.path.exists("requirements.txt"): + if os.path.exists("constraints.txt"): + session.install("-r", "requirements.txt", "-c", "constraints.txt") + else: + session.install("-r", "requirements.txt") + with open("requirements.txt") as rfile: + packages = rfile.read() + + if os.path.exists("requirements-test.txt"): + if os.path.exists("constraints-test.txt"): + session.install("-r", "requirements-test.txt", "-c", "constraints-test.txt") + else: + session.install("-r", "requirements-test.txt") + with open("requirements-test.txt") as rtfile: + packages += rtfile.read() + + if INSTALL_LIBRARY_FROM_SOURCE: + session.install("-e", _get_repo_root()) + + if post_install: + post_install(session) + + if "pytest-parallel" in packages: + concurrent_args.extend(["--workers", "auto", "--tests-per-worker", "auto"]) + elif "pytest-xdist" in packages: + concurrent_args.extend(["-n", "auto"]) + + session.run( + "pytest", + *(PYTEST_COMMON_ARGS + session.posargs + concurrent_args), + # Pytest will return 5 when no tests are collected. This can happen + # on travis where slow and flaky tests are excluded. + # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html + success_codes=[0, 5], + env=get_pytest_env_vars(), + ) + + +@nox.session(python=ALL_VERSIONS) +def py(session: nox.sessions.Session) -> None: + """Runs py.test for a sample using the specified version of Python.""" + if session.python in TESTED_VERSIONS: + _session_tests(session) + else: + session.skip( + "SKIPPED: {} tests are disabled for this sample.".format(session.python) + ) + + +# +# Readmegen +# + + +def _get_repo_root() -> Optional[str]: + """Returns the root folder of the project.""" + # Get root of this repository. Assume we don't have directories nested deeper than 10 items. + p = Path(os.getcwd()) + for i in range(10): + if p is None: + break + if Path(p / ".git").exists(): + return str(p) + # .git is not available in repos cloned via Cloud Build + # setup.py is always in the library's root, so use that instead + # https://github.com/googleapis/synthtool/issues/792 + if Path(p / "setup.py").exists(): + return str(p) + p = p.parent + raise Exception("Unable to detect repository root.") + + +GENERATED_READMES = sorted([x for x in Path(".").rglob("*.rst.in")]) + + +@nox.session +@nox.parametrize("path", GENERATED_READMES) +def readmegen(session: nox.sessions.Session, path: str) -> None: + """(Re-)generates the readme for a sample.""" + session.install("jinja2", "pyyaml") + dir_ = os.path.dirname(path) + + if os.path.exists(os.path.join(dir_, "requirements.txt")): + session.install("-r", os.path.join(dir_, "requirements.txt")) + + in_file = os.path.join(dir_, "README.rst.in") + session.run( + "python", _get_repo_root() + "/scripts/readme-gen/readme_gen.py", in_file + ) diff --git a/packages/google-cloud-bigtable/samples/tableadmin/requirements-test.txt b/packages/google-cloud-bigtable/samples/tableadmin/requirements-test.txt new file mode 100644 index 000000000000..f01fd134c400 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/tableadmin/requirements-test.txt @@ -0,0 +1,2 @@ +pytest +google-cloud-testutils==1.7.0 diff --git a/packages/google-cloud-bigtable/samples/tableadmin/requirements.txt b/packages/google-cloud-bigtable/samples/tableadmin/requirements.txt new file mode 100644 index 000000000000..730d25dec63f --- /dev/null +++ b/packages/google-cloud-bigtable/samples/tableadmin/requirements.txt @@ -0,0 +1 @@ +google-cloud-bigtable==2.35.0 diff --git a/packages/google-cloud-bigtable/samples/tableadmin/tableadmin.py b/packages/google-cloud-bigtable/samples/tableadmin/tableadmin.py new file mode 100644 index 000000000000..d62cfa3328b0 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/tableadmin/tableadmin.py @@ -0,0 +1,266 @@ +#!/usr/bin/env python + +# Copyright 2018, 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. + +"""Demonstrates how to connect to Cloud Bigtable and run some basic operations. +# http://www.apache.org/licenses/LICENSE-2.0 +Prerequisites: +- Create a Cloud Bigtable cluster. + https://cloud.google.com/bigtable/docs/creating-cluster +- Set your Google Application Default Credentials. + https://developers.google.com/identity/protocols/application-default-credentials + +Operations performed: +- Create a Cloud Bigtable table. +- List tables for a Cloud Bigtable instance. +- Print metadata of the newly created table. +- Create Column Families with different GC rules. + - GC Rules like: MaxAge, MaxVersions, Union, Intersection and Nested. +- Delete a Bigtable table. +""" + +import argparse +import datetime + +from google.cloud import bigtable +from google.cloud.bigtable import column_family + +from ..utils import create_table_cm + + +def run_table_operations(project_id, instance_id, table_id): + """Create a Bigtable table and perform basic operations on it + + :type project_id: str + :param project_id: Project id of the client. + + :type instance_id: str + :param instance_id: Instance of the client. + + :type table_id: str + :param table_id: Table id to create table. + """ + + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + with create_table_cm(project_id, instance_id, table_id, verbose=False) as table: + # [START bigtable_list_tables] + tables = instance.list_tables() + print("Listing tables in current project...") + if tables != []: + for tbl in tables: + print(tbl.table_id) + else: + print("No table exists in current project...") + # [END bigtable_list_tables] + + # [START bigtable_create_family_gc_max_age] + print("Creating column family cf1 with with MaxAge GC Rule...") + # Create a column family with GC policy : maximum age + # where age = current time minus cell timestamp + + # Define the GC rule to retain data with max age of 5 days + max_age_rule = column_family.MaxAgeGCRule(datetime.timedelta(days=5)) + + column_family1 = table.column_family("cf1", max_age_rule) + column_family1.create() + print("Created column family cf1 with MaxAge GC Rule.") + # [END bigtable_create_family_gc_max_age] + + # [START bigtable_create_family_gc_max_versions] + print("Creating column family cf2 with max versions GC rule...") + # Create a column family with GC policy : most recent N versions + # where 1 = most recent version + + # Define the GC policy to retain only the most recent 2 versions + max_versions_rule = column_family.MaxVersionsGCRule(2) + + column_family2 = table.column_family("cf2", max_versions_rule) + column_family2.create() + print("Created column family cf2 with Max Versions GC Rule.") + # [END bigtable_create_family_gc_max_versions] + + # [START bigtable_create_family_gc_union] + print("Creating column family cf3 with union GC rule...") + # Create a column family with GC policy to drop data that matches + # at least one condition. + # Define a GC rule to drop cells older than 5 days or not the + # most recent version + union_rule = column_family.GCRuleUnion( + [ + column_family.MaxAgeGCRule(datetime.timedelta(days=5)), + column_family.MaxVersionsGCRule(2), + ] + ) + + column_family3 = table.column_family("cf3", union_rule) + column_family3.create() + print("Created column family cf3 with Union GC rule") + # [END bigtable_create_family_gc_union] + + # [START bigtable_create_family_gc_intersection] + print("Creating column family cf4 with Intersection GC rule...") + # Create a column family with GC policy to drop data that matches + # all conditions + # GC rule: Drop cells older than 5 days AND older than the most + # recent 2 versions + intersection_rule = column_family.GCRuleIntersection( + [ + column_family.MaxAgeGCRule(datetime.timedelta(days=5)), + column_family.MaxVersionsGCRule(2), + ] + ) + + column_family4 = table.column_family("cf4", intersection_rule) + column_family4.create() + print("Created column family cf4 with Intersection GC rule.") + # [END bigtable_create_family_gc_intersection] + + # [START bigtable_create_family_gc_nested] + print("Creating column family cf5 with a Nested GC rule...") + # Create a column family with nested GC policies. + # Create a nested GC rule: + # Drop cells that are either older than the 10 recent versions + # OR + # Drop cells that are older than a month AND older than the + # 2 recent versions + rule1 = column_family.MaxVersionsGCRule(10) + rule2 = column_family.GCRuleIntersection( + [ + column_family.MaxAgeGCRule(datetime.timedelta(days=30)), + column_family.MaxVersionsGCRule(2), + ] + ) + + nested_rule = column_family.GCRuleUnion([rule1, rule2]) + + column_family5 = table.column_family("cf5", nested_rule) + column_family5.create() + print("Created column family cf5 with a Nested GC rule.") + # [END bigtable_create_family_gc_nested] + + # [START bigtable_list_column_families] + print("Printing Column Family and GC Rule for all column families...") + column_families = table.list_column_families() + for column_family_name, gc_rule in sorted(column_families.items()): + print("Column Family:", column_family_name) + print("GC Rule:") + print(gc_rule.to_pb()) + # Sample output: + # Column Family: cf4 + # GC Rule: + # gc_rule { + # intersection { + # rules { + # max_age { + # seconds: 432000 + # } + # } + # rules { + # max_num_versions: 2 + # } + # } + # } + # [END bigtable_list_column_families] + + print("Print column family cf1 GC rule before update...") + print("Column Family: cf1") + print(column_family1.to_pb()) + + # [START bigtable_update_gc_rule] + print("Updating column family cf1 GC rule...") + # Update the column family cf1 to update the GC rule + column_family1 = table.column_family("cf1", column_family.MaxVersionsGCRule(1)) + column_family1.update() + print("Updated column family cf1 GC rule\n") + # [END bigtable_update_gc_rule] + + print("Print column family cf1 GC rule after update...") + print("Column Family: cf1") + print(column_family1.to_pb()) + + # [START bigtable_delete_family] + print("Delete a column family cf2...") + # Delete a column family + column_family2.delete() + print("Column family cf2 deleted successfully.") + # [END bigtable_delete_family] + + print( + 'execute command "python tableadmin.py delete [project_id] \ + [instance_id] --table [tableName]" to delete the table.' + ) + + +def delete_table(project_id, instance_id, table_id): + """Delete bigtable. + + :type project_id: str + :param project_id: Project id of the client. + + :type instance_id: str + :param instance_id: Instance of the client. + + :type table_id: str + :param table_id: Table id to create table. + """ + + client = bigtable.Client(project=project_id, admin=True) + instance = client.instance(instance_id) + table = instance.table(table_id) + + # [START bigtable_delete_table] + # Delete the entire table + + print("Checking if table {} exists...".format(table_id)) + if table.exists(): + print("Table {} exists.".format(table_id)) + print("Deleting {} table.".format(table_id)) + table.delete() + print("Deleted {} table.".format(table_id)) + else: + print("Table {} does not exists.".format(table_id)) + # [END bigtable_delete_table] + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description=__doc__, formatter_class=argparse.ArgumentDefaultsHelpFormatter + ) + + parser.add_argument( + "command", + help="run or delete. \ + Operation to perform on table.", + ) + parser.add_argument( + "--table", help="Cloud Bigtable Table name.", default="Hello-Bigtable" + ) + + parser.add_argument("project_id", help="Your Cloud Platform project ID.") + parser.add_argument( + "instance_id", help="ID of the Cloud Bigtable instance to connect to." + ) + + args = parser.parse_args() + + if args.command.lower() == "run": + run_table_operations(args.project_id, args.instance_id, args.table) + elif args.command.lower() == "delete": + delete_table(args.project_id, args.instance_id, args.table) + else: + print( + "Command should be either run or delete.\n Use argument -h,\ + --help to show help and exit." + ) diff --git a/packages/google-cloud-bigtable/samples/tableadmin/tableadmin_test.py b/packages/google-cloud-bigtable/samples/tableadmin/tableadmin_test.py new file mode 100755 index 000000000000..1c4cc41a1964 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/tableadmin/tableadmin_test.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python + +# Copyright 2018, 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 uuid + +from google.api_core import exceptions +from test_utils.retry import RetryErrors + +from ..utils import create_table_cm +from .tableadmin import delete_table, run_table_operations + +PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"] +BIGTABLE_INSTANCE = os.environ["BIGTABLE_INSTANCE"] +TABLE_ID = f"tableadmin-test-{str(uuid.uuid4())[:16]}" + +retry_429_503 = RetryErrors(exceptions.TooManyRequests, exceptions.ServiceUnavailable) + + +def test_run_table_operations(capsys): + retry_429_503(run_table_operations)(PROJECT, BIGTABLE_INSTANCE, TABLE_ID) + out, _ = capsys.readouterr() + + assert "Listing tables in current project." in out + assert "Creating column family cf1 with with MaxAge GC Rule" in out + assert "Created column family cf1 with MaxAge GC Rule." in out + assert "Created column family cf2 with Max Versions GC Rule." in out + assert "Created column family cf3 with Union GC rule" in out + assert "Created column family cf4 with Intersection GC rule." in out + assert "Created column family cf5 with a Nested GC rule." in out + assert "Printing Column Family and GC Rule for all column families." in out + assert "Updating column family cf1 GC rule..." in out + assert "Updated column family cf1 GC rule" in out + assert "Print column family cf1 GC rule after update..." in out + assert "Column Family: cf1" in out + assert "max_num_versions: 1" in out + assert "Delete a column family cf2..." in out + assert "Column family cf2 deleted successfully." in out + + +def test_delete_table(capsys): + table_id = f"table-admin-to-delete-{str(uuid.uuid4())[:16]}" + with create_table_cm(PROJECT, BIGTABLE_INSTANCE, table_id, verbose=False): + delete_table(PROJECT, BIGTABLE_INSTANCE, table_id) + out, _ = capsys.readouterr() + + assert "Table " + table_id + " exists." in out + assert "Deleting " + table_id + " table." in out + assert "Deleted " + table_id + " table." in out diff --git a/packages/google-cloud-bigtable/samples/testdata/README.md b/packages/google-cloud-bigtable/samples/testdata/README.md new file mode 100644 index 000000000000..57520179f2dc --- /dev/null +++ b/packages/google-cloud-bigtable/samples/testdata/README.md @@ -0,0 +1,5 @@ +#### To generate singer_pb2.py and descriptors.pb file from singer.proto using `protoc` +```shell +cd samples +protoc --proto_path=testdata/ --include_imports --descriptor_set_out=testdata/descriptors.pb --python_out=testdata/ testdata/singer.proto +``` \ No newline at end of file diff --git a/packages/google-cloud-bigtable/samples/testdata/descriptors.pb b/packages/google-cloud-bigtable/samples/testdata/descriptors.pb new file mode 100644 index 0000000000000000000000000000000000000000..bddf04de378263f791d1d7f558e97f934b281d2b GIT binary patch literal 182 zcmd5Zl#{BLTUwl%tQ5q>77SJ> zB*ev%mzbL>!KlEf!5IW*3z=}Srl;l=rAjaX1^JBR^l%uX=MGX81W~M|$HfZf3$b%C o2lxjFFbHvQv3NN~MF}v1SZ@A4-U3V@R*=85w*Yez8`zD;07g_Xr2qf` literal 0 HcmV?d00001 diff --git a/packages/google-cloud-bigtable/samples/testdata/singer.proto b/packages/google-cloud-bigtable/samples/testdata/singer.proto new file mode 100644 index 000000000000..d60e0dfb3b2a --- /dev/null +++ b/packages/google-cloud-bigtable/samples/testdata/singer.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +package examples.bigtable.music; + +enum Genre { + POP = 0; + JAZZ = 1; + FOLK = 2; + ROCK = 3; +} + +message Singer { + string name = 1; + Genre genre = 2; +} diff --git a/packages/google-cloud-bigtable/samples/testdata/singer_pb2.py b/packages/google-cloud-bigtable/samples/testdata/singer_pb2.py new file mode 100644 index 000000000000..f5da249d4811 --- /dev/null +++ b/packages/google-cloud-bigtable/samples/testdata/singer_pb2.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: singer.proto +"""Generated protocol buffer code.""" + +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder + +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x0csinger.proto\x12\x17\x65xamples.bigtable.music"E\n\x06Singer\x12\x0c\n\x04name\x18\x01 \x01(\t\x12-\n\x05genre\x18\x02 \x01(\x0e\x32\x1e.examples.bigtable.music.Genre*.\n\x05Genre\x12\x07\n\x03POP\x10\x00\x12\x08\n\x04JAZZ\x10\x01\x12\x08\n\x04\x46OLK\x10\x02\x12\x08\n\x04ROCK\x10\x03\x62\x06proto3' +) + +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "singer_pb2", globals()) +if _descriptor._USE_C_DESCRIPTORS == False: + DESCRIPTOR._options = None + _GENRE._serialized_start = 112 + _GENRE._serialized_end = 158 + _SINGER._serialized_start = 41 + _SINGER._serialized_end = 110 +# @@protoc_insertion_point(module_scope) diff --git a/packages/google-cloud-bigtable/samples/utils.py b/packages/google-cloud-bigtable/samples/utils.py new file mode 100644 index 000000000000..d093d0427cbf --- /dev/null +++ b/packages/google-cloud-bigtable/samples/utils.py @@ -0,0 +1,105 @@ +# Copyright 2024, 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. +""" +Provides helper logic used across samples +""" + +from google.api_core import exceptions +from google.api_core.retry import Retry, if_exception_type + +from google.cloud import bigtable +from google.cloud.bigtable.column_family import ColumnFamily +from google.cloud.bigtable_admin_v2.types import ColumnFamily as ColumnFamily_pb + +delete_retry = Retry( + if_exception_type(exceptions.TooManyRequests, exceptions.ServiceUnavailable) +) + + +class create_table_cm: + """ + Create a new table using a context manager, to ensure that table.delete() is called to clean up + the table, even if an exception is thrown + """ + + def __init__(self, *args, verbose=True, **kwargs): + self._args = args + self._kwargs = kwargs + self._verbose = verbose + + def __enter__(self): + self._table = create_table(*self._args, **self._kwargs) + if self._verbose: + print(f"created table: {self._table.table_id}") + return self._table + + def __exit__(self, *args): + if self._table.exists(): + if self._verbose: + print(f"deleting table: {self._table.table_id}") + delete_retry(self._table.delete()) + else: + if self._verbose: + print(f"table {self._table.table_id} not found") + + +def create_table(project, instance_id, table_id, column_families={}): + """ + Creates a new table, and blocks until it reaches a ready state + """ + client = bigtable.Client(project=project, admin=True) + instance = client.instance(instance_id) + + table = instance.table(table_id) + if table.exists(): + table.delete() + + # convert column families to pb if needed + pb_families = { + id: ColumnFamily(id, table, rule).to_pb() + if not isinstance(rule, ColumnFamily_pb) + else rule + for (id, rule) in column_families.items() + } + + # create table using gapic layer + instance._client.table_admin_client.create_table( + request={ + "parent": instance.name, + "table_id": table_id, + "table": {"column_families": pb_families}, + } + ) + + wait_for_table(table) + + return table + + +@Retry( + on_error=if_exception_type( + exceptions.PreconditionFailed, + exceptions.FailedPrecondition, + exceptions.NotFound, + ), + timeout=120, +) +def wait_for_table(table): + """ + raises an exception if the table does not exist or is not ready to use + + Because this method is wrapped with an api_core.Retry decorator, it will + retry with backoff if the table is not ready + """ + if not table.exists(): + raise exceptions.NotFound From f59c2b2aa61316cf04b650933036ef50f6a1f08c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jun 2026 11:00:31 -0700 Subject: [PATCH 059/174] fix: bump pyarrow from 15.0.2 to 23.0.1 in /packages/bigframes (#17386) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [pyarrow](https://github.com/apache/arrow) from 15.0.2 to 23.0.1.
Release notes

Sourced from pyarrow's releases.

Apache Arrow 23.0.1

Release Notes URL: https://arrow.apache.org/release/23.0.1.html

Apache Arrow 23.0.1 RC0

Release Notes: Release Candidate: 23.0.1 RC0

Apache Arrow 23.0.0

Release Notes URL: https://arrow.apache.org/release/23.0.0.html

Apache Arrow 23.0.0 RC2

Release Notes: Release Candidate: 23.0.0 RC2

Apache Arrow 22.0.0

Release Notes URL: https://arrow.apache.org/release/22.0.0.html

Apache Arrow 22.0.0 RC1

Release Notes: Release Candidate: 22.0.0 RC1

Apache Arrow 22.0.0 RC0

Release Notes: Release Candidate: 22.0.0 RC0

Apache Arrow 21.0.0

Release Notes URL: https://arrow.apache.org/release/21.0.0.html

Apache Arrow 21.0.0 RC6

Release Notes: Release Candidate: 21.0.0 RC6

Apache Arrow 21.0.0 RC5

Release Notes: Release Candidate: 21.0.0 RC5

Apache Arrow 21.0.0 RC4

Release Notes: Release Candidate: 21.0.0 RC4

Apache Arrow 21.0.0 RC3

Release Notes: Release Candidate: 21.0.0 RC3

Apache Arrow 21.0.0 RC2

Release Notes: Release Candidate: 21.0.0 RC2

Apache Arrow 20.0.0

Release Notes URL: https://arrow.apache.org/release/20.0.0.html

Apache Arrow 20.0.0 RC2

Release Notes: Release Candidate: 20.0.0 RC2

Apache Arrow 20.0.0 RC1

Release Notes: Release Candidate: 20.0.0 RC1

Apache Arrow 20.0.0 RC0

Release Notes: Release Candidate: 20.0.0 RC0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pyarrow&package-manager=pip&previous-version=15.0.2&new-version=23.0.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/googleapis/google-cloud-python/network/alerts).
--------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Tim Sweña (Swast) --- packages/bigframes/setup.py | 2 +- packages/bigframes/testing/constraints-3.10.txt | 2 +- packages/bigframes/testing/constraints-3.11.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/bigframes/setup.py b/packages/bigframes/setup.py index 138c52879526..76b98b88d312 100644 --- a/packages/bigframes/setup.py +++ b/packages/bigframes/setup.py @@ -51,7 +51,7 @@ "numpy >=1.24.0", "pandas >=1.5.3", "pandas-gbq >=0.26.1", - "pyarrow >=15.0.2", + "pyarrow >=23.0.1", "pydata-google-auth >=1.8.2", "requests >=2.27.1", "shapely >=1.8.5", diff --git a/packages/bigframes/testing/constraints-3.10.txt b/packages/bigframes/testing/constraints-3.10.txt index 137710df3299..0c76f1dda750 100644 --- a/packages/bigframes/testing/constraints-3.10.txt +++ b/packages/bigframes/testing/constraints-3.10.txt @@ -16,7 +16,7 @@ grpc-google-iam-v1==0.14.2 numpy==1.24.0 pandas==1.5.3 pandas-gbq==0.26.1 -pyarrow==15.0.2 +pyarrow==23.0.1 pydata-google-auth==1.8.2 pyiceberg==0.7.1 requests==2.27.1 diff --git a/packages/bigframes/testing/constraints-3.11.txt b/packages/bigframes/testing/constraints-3.11.txt index 6340dde0c545..7bb201d16fcd 100644 --- a/packages/bigframes/testing/constraints-3.11.txt +++ b/packages/bigframes/testing/constraints-3.11.txt @@ -408,7 +408,7 @@ psygnal==0.14.0 ptyprocess==0.7.0 py-cpuinfo==9.0.0 py4j==0.10.9.7 -pyarrow==18.1.0 +pyarrow==23.0.1 pyasn1==0.6.1 pyasn1_modules==0.4.2 pycairo==1.28.0 From 2e75c78cdd09d4472ed412a2e925196effaea9fd Mon Sep 17 00:00:00 2001 From: sofisl <55454395+sofisl@users.noreply.github.com> Date: Thu, 11 Jun 2026 11:56:23 -0700 Subject: [PATCH 060/174] feat: update API sources and regenerate (#17431) --- librarian.yaml | 4 +- .../iceberg_catalog_service/async_client.py | 79 +- .../iceberg_catalog_service/client.py | 116 +- .../transports/grpc.py | 40 +- .../transports/grpc_asyncio.py | 40 +- .../transports/rest.py | 37 +- .../biglake_v1/types/iceberg_rest_catalog.py | 482 +- ...og_service_create_iceberg_catalog_async.py | 2 +- ...log_service_create_iceberg_catalog_sync.py | 2 +- ...og_service_update_iceberg_catalog_async.py | 2 +- ...log_service_update_iceberg_catalog_sync.py | 2 +- ...ppet_metadata_google.cloud.biglake.v1.json | 8 + .../test_iceberg_catalog_service.py | 296 +- .../filters/filter_snippets_async_test.py | 4 +- .../samples/snippets/reads/read_snippets.py | 1 + .../samples/testdata/singer_pb2.py | 15 + .../google/cloud/network_services/__init__.py | 18 + .../cloud/network_services_v1/__init__.py | 18 + .../network_services_v1/gapic_metadata.json | 75 + .../services/dep_service/async_client.py | 10 - .../services/dep_service/client.py | 10 - .../services/network_services/async_client.py | 723 +- .../services/network_services/client.py | 744 +- .../services/network_services/pagers.py | 157 + .../network_services/transports/base.py | 75 + .../network_services/transports/grpc.py | 140 + .../transports/grpc_asyncio.py | 171 + .../network_services/transports/rest.py | 1421 +- .../network_services/transports/rest_base.py | 259 + .../network_services_v1/types/__init__.py | 18 + .../types/agent_gateway.py | 515 + .../cloud/network_services_v1/types/common.py | 6 +- .../cloud/network_services_v1/types/dep.py | 162 +- .../types/endpoint_policy.py | 12 +- .../types/extensibility.py | 143 +- .../network_services_v1/types/gateway.py | 19 +- .../network_services_v1/types/grpc_route.py | 14 +- .../network_services_v1/types/http_route.py | 27 +- .../cloud/network_services_v1/types/mesh.py | 10 +- .../network_services_v1/types/tcp_route.py | 14 +- .../network_services_v1/types/tls_route.py | 25 +- ...ep_service_create_authz_extension_async.py | 2 - ...dep_service_create_authz_extension_sync.py | 2 - ..._service_create_lb_edge_extension_async.py | 1 - ...p_service_create_lb_edge_extension_sync.py | 1 - ...service_create_lb_route_extension_async.py | 1 - ..._service_create_lb_route_extension_sync.py | 1 - ...rvice_create_lb_traffic_extension_async.py | 1 - ...ervice_create_lb_traffic_extension_sync.py | 1 - ...ep_service_update_authz_extension_async.py | 2 - ...dep_service_update_authz_extension_sync.py | 2 - ..._service_update_lb_edge_extension_async.py | 1 - ...p_service_update_lb_edge_extension_sync.py | 1 - ...service_update_lb_route_extension_async.py | 1 - ..._service_update_lb_route_extension_sync.py | 1 - ...rvice_update_lb_traffic_extension_async.py | 1 - ...ervice_update_lb_traffic_extension_sync.py | 1 - ...ork_services_create_agent_gateway_async.py | 58 + ...work_services_create_agent_gateway_sync.py | 58 + ...ork_services_delete_agent_gateway_async.py | 57 + ...work_services_delete_agent_gateway_sync.py | 57 + ...etwork_services_get_agent_gateway_async.py | 53 + ...network_services_get_agent_gateway_sync.py | 53 + ...work_services_list_agent_gateways_async.py | 54 + ...twork_services_list_agent_gateways_sync.py | 54 + ...ork_services_update_agent_gateway_async.py | 55 + ...work_services_update_agent_gateway_sync.py | 55 + ...adata_google.cloud.networkservices.v1.json | 1349 +- .../network_services_v1/test_dep_service.py | 57 + .../test_network_services.py | 20730 ++++++++++------ 70 files changed, 19654 insertions(+), 8972 deletions(-) create mode 100644 packages/google-cloud-network-services/google/cloud/network_services_v1/types/agent_gateway.py create mode 100644 packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_create_agent_gateway_async.py create mode 100644 packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_create_agent_gateway_sync.py create mode 100644 packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_delete_agent_gateway_async.py create mode 100644 packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_delete_agent_gateway_sync.py create mode 100644 packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_get_agent_gateway_async.py create mode 100644 packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_get_agent_gateway_sync.py create mode 100644 packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_list_agent_gateways_async.py create mode 100644 packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_list_agent_gateways_sync.py create mode 100644 packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_update_agent_gateway_async.py create mode 100644 packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_update_agent_gateway_sync.py diff --git a/librarian.yaml b/librarian.yaml index 9d89020f6cbe..8a14680e872a 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -16,8 +16,8 @@ version: v0.19.0 repo: googleapis/google-cloud-python sources: googleapis: - commit: d8daa97972d091191898915589335cef66fcdc8a - sha256: 7dbdf2b1b667fe57128d41c77e530a2541767772cfe3487713f29b7b25d9f5ad + commit: f93e046328794785ad89869f00c0358dfcff2c35 + sha256: 415249f584d57e5a2298c36ae9ff71563403112dee04ac961023a1b0098404d2 default: output: packages tag_format: '{name}-v{version}' diff --git a/packages/google-cloud-biglake/google/cloud/biglake_v1/services/iceberg_catalog_service/async_client.py b/packages/google-cloud-biglake/google/cloud/biglake_v1/services/iceberg_catalog_service/async_client.py index 098c2af83bd2..eee3ae1e82ef 100644 --- a/packages/google-cloud-biglake/google/cloud/biglake_v1/services/iceberg_catalog_service/async_client.py +++ b/packages/google-cloud-biglake/google/cloud/biglake_v1/services/iceberg_catalog_service/async_client.py @@ -65,34 +65,15 @@ class IcebergCatalogServiceAsyncClient: - """Iceberg Catalog Service API: this implements the open-source Iceberg - REST Catalog API. See the API definition here: - https://github.com/apache/iceberg/blob/main/open-api/rest-catalog-open-api.yaml - - The API is defined as OpenAPI 3.1.1 spec. - - Currently we only support the following methods: - - - GetConfig/GetIcebergCatalogConfig - - ListIcebergNamespaces - - CheckIcebergNamespaceExists - - GetIcebergNamespace - - CreateIcebergNamespace (only supports single level) - - DeleteIcebergNamespace - - UpdateIcebergNamespace properties - - ListTableIdentifiers - - CreateIcebergTable - - DeleteIcebergTable - - GetIcebergTable - - UpdateIcebergTable (CommitTable) - - LoadIcebergTableCredentials - - RegisterTable - - Users are required to provided the ``X-Goog-User-Project`` header - with the project id or number which can be different from the bucket - project id. That project will be charged for the API calls and the - calling user must have access to that project. The caller must have - ``serviceusage.services.use`` permission on the project. + """Lakehouse runtime catalog supports the following catalog + management methods: + + - GetIcebergCatalog + - ListIcebergCatalogs + - DeleteIcebergCatalog + - UpdateIcebergCatalog + - CreateIcebergCatalog + - FailoverIcebergCatalog """ _client: IcebergCatalogServiceClient @@ -106,6 +87,10 @@ class IcebergCatalogServiceAsyncClient: catalog_path = staticmethod(IcebergCatalogServiceClient.catalog_path) parse_catalog_path = staticmethod(IcebergCatalogServiceClient.parse_catalog_path) + secret_path = staticmethod(IcebergCatalogServiceClient.secret_path) + parse_secret_path = staticmethod(IcebergCatalogServiceClient.parse_secret_path) + service_path = staticmethod(IcebergCatalogServiceClient.service_path) + parse_service_path = staticmethod(IcebergCatalogServiceClient.parse_service_path) common_billing_account_path = staticmethod( IcebergCatalogServiceClient.common_billing_account_path ) @@ -599,7 +584,7 @@ async def sample_update_iceberg_catalog(): # Initialize request argument(s) iceberg_catalog = biglake_v1.IcebergCatalog() - iceberg_catalog.catalog_type = "CATALOG_TYPE_GCS_BUCKET" + iceberg_catalog.catalog_type = "CATALOG_TYPE_FEDERATED" request = biglake_v1.UpdateIcebergCatalogRequest( iceberg_catalog=iceberg_catalog, @@ -701,12 +686,12 @@ async def create_iceberg_catalog( parent: Optional[str] = None, iceberg_catalog: Optional[iceberg_rest_catalog.IcebergCatalog] = None, iceberg_catalog_id: Optional[str] = None, + primary_location: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> iceberg_rest_catalog.IcebergCatalog: - r"""Creates the Iceberg REST Catalog. Currently only supports Google - Cloud Storage Bucket catalogs. Google Cloud Storage Bucket + r"""Creates the Iceberg REST Catalog. Google Cloud Storage Bucket catalog id is the bucket for which the catalog is created (e.g. ``my-catalog`` for ``gs://my-catalog``). @@ -730,7 +715,7 @@ async def sample_create_iceberg_catalog(): # Initialize request argument(s) iceberg_catalog = biglake_v1.IcebergCatalog() - iceberg_catalog.catalog_type = "CATALOG_TYPE_GCS_BUCKET" + iceberg_catalog.catalog_type = "CATALOG_TYPE_FEDERATED" request = biglake_v1.CreateIcebergCatalogRequest( parent="parent_value", @@ -770,6 +755,27 @@ async def sample_create_iceberg_catalog(): This corresponds to the ``iceberg_catalog_id`` field on the ``request`` instance; if ``request`` is provided, this should not be set. + primary_location (:class:`str`): + Optional. The primary location where the catalog + metadata will be stored. + + For Google Cloud Storage bucket catalogs and BigLake + catalogs, if this is not specified, then the region is + inferred from the bucket's region (``default_location`` + bucket for BigLake catalogs). If specified, the region + must be in jurisdiction (near the ``default_location`` + bucket's region and the ``restricted_locations`` + buckets' regions for BigLake catalogs). + + For federated catalogs, this must be specified and be a + Lakehouse-supported location + (https://docs.cloud.google.com/lakehouse/docs/locations). + It should be close to the remote catalog's location for + the best performance and cost. + + This corresponds to the ``primary_location`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -785,7 +791,12 @@ async def sample_create_iceberg_catalog(): # Create or coerce a protobuf request object. # - Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - flattened_params = [parent, iceberg_catalog, iceberg_catalog_id] + flattened_params = [ + parent, + iceberg_catalog, + iceberg_catalog_id, + primary_location, + ] has_flattened_params = ( len([param for param in flattened_params if param is not None]) > 0 ) @@ -808,6 +819,8 @@ async def sample_create_iceberg_catalog(): request.iceberg_catalog = iceberg_catalog if iceberg_catalog_id is not None: request.iceberg_catalog_id = iceberg_catalog_id + if primary_location is not None: + request.primary_location = primary_location # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. diff --git a/packages/google-cloud-biglake/google/cloud/biglake_v1/services/iceberg_catalog_service/client.py b/packages/google-cloud-biglake/google/cloud/biglake_v1/services/iceberg_catalog_service/client.py index cd136f108736..a1ebe3212e7d 100644 --- a/packages/google-cloud-biglake/google/cloud/biglake_v1/services/iceberg_catalog_service/client.py +++ b/packages/google-cloud-biglake/google/cloud/biglake_v1/services/iceberg_catalog_service/client.py @@ -109,34 +109,15 @@ def get_transport_class( class IcebergCatalogServiceClient(metaclass=IcebergCatalogServiceClientMeta): - """Iceberg Catalog Service API: this implements the open-source Iceberg - REST Catalog API. See the API definition here: - https://github.com/apache/iceberg/blob/main/open-api/rest-catalog-open-api.yaml - - The API is defined as OpenAPI 3.1.1 spec. - - Currently we only support the following methods: - - - GetConfig/GetIcebergCatalogConfig - - ListIcebergNamespaces - - CheckIcebergNamespaceExists - - GetIcebergNamespace - - CreateIcebergNamespace (only supports single level) - - DeleteIcebergNamespace - - UpdateIcebergNamespace properties - - ListTableIdentifiers - - CreateIcebergTable - - DeleteIcebergTable - - GetIcebergTable - - UpdateIcebergTable (CommitTable) - - LoadIcebergTableCredentials - - RegisterTable - - Users are required to provided the ``X-Goog-User-Project`` header - with the project id or number which can be different from the bucket - project id. That project will be charged for the API calls and the - calling user must have access to that project. The caller must have - ``serviceusage.services.use`` permission on the project. + """Lakehouse runtime catalog supports the following catalog + management methods: + + - GetIcebergCatalog + - ListIcebergCatalogs + - DeleteIcebergCatalog + - UpdateIcebergCatalog + - CreateIcebergCatalog + - FailoverIcebergCatalog """ @staticmethod @@ -274,6 +255,47 @@ def parse_catalog_path(path: str) -> Dict[str, str]: m = re.match(r"^projects/(?P.+?)/catalogs/(?P.+?)$", path) return m.groupdict() if m else {} + @staticmethod + def secret_path( + project: str, + secret: str, + ) -> str: + """Returns a fully-qualified secret string.""" + return "projects/{project}/secrets/{secret}".format( + project=project, + secret=secret, + ) + + @staticmethod + def parse_secret_path(path: str) -> Dict[str, str]: + """Parses a secret path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/secrets/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def service_path( + project: str, + location: str, + namespace: str, + service: str, + ) -> str: + """Returns a fully-qualified service string.""" + return "projects/{project}/locations/{location}/namespaces/{namespace}/services/{service}".format( + project=project, + location=location, + namespace=namespace, + service=service, + ) + + @staticmethod + def parse_service_path(path: str) -> Dict[str, str]: + """Parses a service path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/namespaces/(?P.+?)/services/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def common_billing_account_path( billing_account: str, @@ -1021,7 +1043,7 @@ def sample_update_iceberg_catalog(): # Initialize request argument(s) iceberg_catalog = biglake_v1.IcebergCatalog() - iceberg_catalog.catalog_type = "CATALOG_TYPE_GCS_BUCKET" + iceberg_catalog.catalog_type = "CATALOG_TYPE_FEDERATED" request = biglake_v1.UpdateIcebergCatalogRequest( iceberg_catalog=iceberg_catalog, @@ -1120,12 +1142,12 @@ def create_iceberg_catalog( parent: Optional[str] = None, iceberg_catalog: Optional[iceberg_rest_catalog.IcebergCatalog] = None, iceberg_catalog_id: Optional[str] = None, + primary_location: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> iceberg_rest_catalog.IcebergCatalog: - r"""Creates the Iceberg REST Catalog. Currently only supports Google - Cloud Storage Bucket catalogs. Google Cloud Storage Bucket + r"""Creates the Iceberg REST Catalog. Google Cloud Storage Bucket catalog id is the bucket for which the catalog is created (e.g. ``my-catalog`` for ``gs://my-catalog``). @@ -1149,7 +1171,7 @@ def sample_create_iceberg_catalog(): # Initialize request argument(s) iceberg_catalog = biglake_v1.IcebergCatalog() - iceberg_catalog.catalog_type = "CATALOG_TYPE_GCS_BUCKET" + iceberg_catalog.catalog_type = "CATALOG_TYPE_FEDERATED" request = biglake_v1.CreateIcebergCatalogRequest( parent="parent_value", @@ -1189,6 +1211,27 @@ def sample_create_iceberg_catalog(): This corresponds to the ``iceberg_catalog_id`` field on the ``request`` instance; if ``request`` is provided, this should not be set. + primary_location (str): + Optional. The primary location where the catalog + metadata will be stored. + + For Google Cloud Storage bucket catalogs and BigLake + catalogs, if this is not specified, then the region is + inferred from the bucket's region (``default_location`` + bucket for BigLake catalogs). If specified, the region + must be in jurisdiction (near the ``default_location`` + bucket's region and the ``restricted_locations`` + buckets' regions for BigLake catalogs). + + For federated catalogs, this must be specified and be a + Lakehouse-supported location + (https://docs.cloud.google.com/lakehouse/docs/locations). + It should be close to the remote catalog's location for + the best performance and cost. + + This corresponds to the ``primary_location`` 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. @@ -1204,7 +1247,12 @@ def sample_create_iceberg_catalog(): # Create or coerce a protobuf request object. # - Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - flattened_params = [parent, iceberg_catalog, iceberg_catalog_id] + flattened_params = [ + parent, + iceberg_catalog, + iceberg_catalog_id, + primary_location, + ] has_flattened_params = ( len([param for param in flattened_params if param is not None]) > 0 ) @@ -1226,6 +1274,8 @@ def sample_create_iceberg_catalog(): request.iceberg_catalog = iceberg_catalog if iceberg_catalog_id is not None: request.iceberg_catalog_id = iceberg_catalog_id + if primary_location is not None: + request.primary_location = primary_location # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. diff --git a/packages/google-cloud-biglake/google/cloud/biglake_v1/services/iceberg_catalog_service/transports/grpc.py b/packages/google-cloud-biglake/google/cloud/biglake_v1/services/iceberg_catalog_service/transports/grpc.py index 909305ed8c3e..bbae138cc8f0 100644 --- a/packages/google-cloud-biglake/google/cloud/biglake_v1/services/iceberg_catalog_service/transports/grpc.py +++ b/packages/google-cloud-biglake/google/cloud/biglake_v1/services/iceberg_catalog_service/transports/grpc.py @@ -110,34 +110,15 @@ def intercept_unary_unary(self, continuation, client_call_details, request): class IcebergCatalogServiceGrpcTransport(IcebergCatalogServiceTransport): """gRPC backend transport for IcebergCatalogService. - Iceberg Catalog Service API: this implements the open-source Iceberg - REST Catalog API. See the API definition here: - https://github.com/apache/iceberg/blob/main/open-api/rest-catalog-open-api.yaml - - The API is defined as OpenAPI 3.1.1 spec. - - Currently we only support the following methods: - - - GetConfig/GetIcebergCatalogConfig - - ListIcebergNamespaces - - CheckIcebergNamespaceExists - - GetIcebergNamespace - - CreateIcebergNamespace (only supports single level) - - DeleteIcebergNamespace - - UpdateIcebergNamespace properties - - ListTableIdentifiers - - CreateIcebergTable - - DeleteIcebergTable - - GetIcebergTable - - UpdateIcebergTable (CommitTable) - - LoadIcebergTableCredentials - - RegisterTable - - Users are required to provided the ``X-Goog-User-Project`` header - with the project id or number which can be different from the bucket - project id. That project will be charged for the API calls and the - calling user must have access to that project. The caller must have - ``serviceusage.services.use`` permission on the project. + Lakehouse runtime catalog supports the following catalog + management methods: + + - GetIcebergCatalog + - ListIcebergCatalogs + - DeleteIcebergCatalog + - UpdateIcebergCatalog + - CreateIcebergCatalog + - FailoverIcebergCatalog This class defines the same methods as the primary client, so the primary client can load the underlying transport implementation @@ -450,8 +431,7 @@ def create_iceberg_catalog( ]: r"""Return a callable for the create iceberg catalog method over gRPC. - Creates the Iceberg REST Catalog. Currently only supports Google - Cloud Storage Bucket catalogs. Google Cloud Storage Bucket + Creates the Iceberg REST Catalog. Google Cloud Storage Bucket catalog id is the bucket for which the catalog is created (e.g. ``my-catalog`` for ``gs://my-catalog``). diff --git a/packages/google-cloud-biglake/google/cloud/biglake_v1/services/iceberg_catalog_service/transports/grpc_asyncio.py b/packages/google-cloud-biglake/google/cloud/biglake_v1/services/iceberg_catalog_service/transports/grpc_asyncio.py index cab40d9a33c7..87a1b81b8599 100644 --- a/packages/google-cloud-biglake/google/cloud/biglake_v1/services/iceberg_catalog_service/transports/grpc_asyncio.py +++ b/packages/google-cloud-biglake/google/cloud/biglake_v1/services/iceberg_catalog_service/transports/grpc_asyncio.py @@ -116,34 +116,15 @@ async def intercept_unary_unary(self, continuation, client_call_details, request class IcebergCatalogServiceGrpcAsyncIOTransport(IcebergCatalogServiceTransport): """gRPC AsyncIO backend transport for IcebergCatalogService. - Iceberg Catalog Service API: this implements the open-source Iceberg - REST Catalog API. See the API definition here: - https://github.com/apache/iceberg/blob/main/open-api/rest-catalog-open-api.yaml - - The API is defined as OpenAPI 3.1.1 spec. - - Currently we only support the following methods: - - - GetConfig/GetIcebergCatalogConfig - - ListIcebergNamespaces - - CheckIcebergNamespaceExists - - GetIcebergNamespace - - CreateIcebergNamespace (only supports single level) - - DeleteIcebergNamespace - - UpdateIcebergNamespace properties - - ListTableIdentifiers - - CreateIcebergTable - - DeleteIcebergTable - - GetIcebergTable - - UpdateIcebergTable (CommitTable) - - LoadIcebergTableCredentials - - RegisterTable - - Users are required to provided the ``X-Goog-User-Project`` header - with the project id or number which can be different from the bucket - project id. That project will be charged for the API calls and the - calling user must have access to that project. The caller must have - ``serviceusage.services.use`` permission on the project. + Lakehouse runtime catalog supports the following catalog + management methods: + + - GetIcebergCatalog + - ListIcebergCatalogs + - DeleteIcebergCatalog + - UpdateIcebergCatalog + - CreateIcebergCatalog + - FailoverIcebergCatalog This class defines the same methods as the primary client, so the primary client can load the underlying transport implementation @@ -458,8 +439,7 @@ def create_iceberg_catalog( ]: r"""Return a callable for the create iceberg catalog method over gRPC. - Creates the Iceberg REST Catalog. Currently only supports Google - Cloud Storage Bucket catalogs. Google Cloud Storage Bucket + Creates the Iceberg REST Catalog. Google Cloud Storage Bucket catalog id is the bucket for which the catalog is created (e.g. ``my-catalog`` for ``gs://my-catalog``). diff --git a/packages/google-cloud-biglake/google/cloud/biglake_v1/services/iceberg_catalog_service/transports/rest.py b/packages/google-cloud-biglake/google/cloud/biglake_v1/services/iceberg_catalog_service/transports/rest.py index 32c2ab3e7df9..b54f7873effc 100644 --- a/packages/google-cloud-biglake/google/cloud/biglake_v1/services/iceberg_catalog_service/transports/rest.py +++ b/packages/google-cloud-biglake/google/cloud/biglake_v1/services/iceberg_catalog_service/transports/rest.py @@ -386,34 +386,15 @@ class IcebergCatalogServiceRestStub: class IcebergCatalogServiceRestTransport(_BaseIcebergCatalogServiceRestTransport): """REST backend synchronous transport for IcebergCatalogService. - Iceberg Catalog Service API: this implements the open-source Iceberg - REST Catalog API. See the API definition here: - https://github.com/apache/iceberg/blob/main/open-api/rest-catalog-open-api.yaml - - The API is defined as OpenAPI 3.1.1 spec. - - Currently we only support the following methods: - - - GetConfig/GetIcebergCatalogConfig - - ListIcebergNamespaces - - CheckIcebergNamespaceExists - - GetIcebergNamespace - - CreateIcebergNamespace (only supports single level) - - DeleteIcebergNamespace - - UpdateIcebergNamespace properties - - ListTableIdentifiers - - CreateIcebergTable - - DeleteIcebergTable - - GetIcebergTable - - UpdateIcebergTable (CommitTable) - - LoadIcebergTableCredentials - - RegisterTable - - Users are required to provided the ``X-Goog-User-Project`` header - with the project id or number which can be different from the bucket - project id. That project will be charged for the API calls and the - calling user must have access to that project. The caller must have - ``serviceusage.services.use`` permission on the project. + Lakehouse runtime catalog supports the following catalog + management methods: + + - GetIcebergCatalog + - ListIcebergCatalogs + - DeleteIcebergCatalog + - UpdateIcebergCatalog + - CreateIcebergCatalog + - FailoverIcebergCatalog This class defines the same methods as the primary client, so the primary client can load the underlying transport implementation diff --git a/packages/google-cloud-biglake/google/cloud/biglake_v1/types/iceberg_rest_catalog.py b/packages/google-cloud-biglake/google/cloud/biglake_v1/types/iceberg_rest_catalog.py index 0586927a4db2..662fe1644135 100644 --- a/packages/google-cloud-biglake/google/cloud/biglake_v1/types/iceberg_rest_catalog.py +++ b/packages/google-cloud-biglake/google/cloud/biglake_v1/types/iceberg_rest_catalog.py @@ -17,8 +17,10 @@ from typing import MutableMapping, MutableSequence +import google.protobuf.duration_pb2 as duration_pb2 # type: ignore import google.protobuf.field_mask_pb2 as field_mask_pb2 # type: ignore import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore +import google.rpc.status_pb2 as status_pb2 # type: ignore import proto # type: ignore __protobuf__ = proto.module( @@ -54,25 +56,64 @@ class IcebergCatalog(proto.Message): Output only. The service account used for credential vending, output only. Might be empty if Credential vending was never enabled for the - catalog. + catalog. For federated catalogs, the service + account will be always provisioned and will be + used to access the remote Iceberg REST Catalog + using access to Secret Manager secret or + identity federation. + biglake_service_account_unique_id (str): + Output only. The unique ID of the service + account. This is used for federation scenarios. catalog_type (google.cloud.biglake_v1.types.IcebergCatalog.CatalogType): Required. The catalog type. Required for CreateIcebergCatalog. default_location (str): - Optional. The default location for the - catalog. For the Google Cloud Storage Bucket - catalog this is output only. - catalog_regions (MutableSequence[str]): - Output only. The GCP region(s) where the - catalog metadata is stored. This will contain - one value for all locations, except for the - catalogs that are configured to use custom dual - region buckets. + Optional. The default storage location for the catalog, + e.g., ``gs://my-bucket``. For Google Cloud Storage bucket + catalogs, this is output only. + + For BigLake catalogs, this field must be provided and point + to a Google Cloud Storage bucket or a path within that + bucket. This path serves as the base directory for + constructing the full path to a table's data and metadata + directories when a location is not specified at the + namespace or table level. The full path is formed by + appending the namespace and table identifiers to the default + location. + storage_regions (MutableSequence[str]): + Output only. The GCP region(s) of the default location's + bucket, e.g. ``us-central1``, ``nam4`` or ``us``. This will + contain one value for all locations, except for the catalogs + that are configured to use custom dual region buckets, in + which case it will contain the two regions of the bucket. + The region(s) of this field should be in the jurisdiction of + or nearby the primary location of the catalog. create_time (google.protobuf.timestamp_pb2.Timestamp): Output only. When the catalog was created. update_time (google.protobuf.timestamp_pb2.Timestamp): Output only. When the catalog was last updated. + replicas (MutableSequence[google.cloud.biglake_v1.types.IcebergCatalog.Replica]): + Output only. The replicas for the catalog + metadata. + description (str): + Optional. A user-provided description of the + catalog. The description must be a UTF-8 string + with a maximum length of 1024 characters. + restricted_locations_config (google.cloud.biglake_v1.types.IcebergCatalog.RestrictedLocationsConfig): + Optional. Restricted locations configuration. This field is + currently only used for BigLake catalogs. + + If this field is unset, or if + ``restricted_locations_config.restricted_locations`` is + empty, all accessible locations are allowed. If + ``restricted_locations_config.restricted_locations`` is not + empty, only locations in ``default_location`` and + ``restricted_locations_config.restricted_locations`` are + allowed. + federated_catalog_options (google.cloud.biglake_v1.types.IcebergCatalog.FederatedCatalogOptions): + Optional. Configuration options for federated + catalogs. """ class CatalogType(proto.Enum): @@ -82,12 +123,17 @@ class CatalogType(proto.Enum): CATALOG_TYPE_UNSPECIFIED (0): Default value. This value is unused. CATALOG_TYPE_GCS_BUCKET (1): - Catalog type for Google Cloud Storage - Buckets. + Google Cloud Storage bucket catalog type. + CATALOG_TYPE_BIGLAKE (3): + BigLake catalog type. + CATALOG_TYPE_FEDERATED (4): + Federated catalog type. """ CATALOG_TYPE_UNSPECIFIED = 0 CATALOG_TYPE_GCS_BUCKET = 1 + CATALOG_TYPE_BIGLAKE = 3 + CATALOG_TYPE_FEDERATED = 4 class CredentialMode(proto.Enum): r"""The credential mode used for the catalog. @@ -119,6 +165,367 @@ class CredentialMode(proto.Enum): CREDENTIAL_MODE_END_USER = 1 CREDENTIAL_MODE_VENDED_CREDENTIALS = 2 + class Replica(proto.Message): + r"""The replica of the Catalog. + + Attributes: + region (str): + Output only. The region of the replica. For + example "us-east1". + state (google.cloud.biglake_v1.types.IcebergCatalog.Replica.State): + Output only. The current state of the + replica. + """ + + class State(proto.Enum): + r"""If the catalog is replicated to multiple regions, this enum + describes the current state of the replica. + + Values: + STATE_UNKNOWN (0): + The replica state is unknown. + STATE_PRIMARY (1): + The replica is the writable primary. + STATE_PRIMARY_IN_PROGRESS (2): + The replica has been recently assigned as the + primary, but not all namespaces are writeable + yet. + STATE_SECONDARY (3): + The replica is a read-only secondary replica. + """ + + STATE_UNKNOWN = 0 + STATE_PRIMARY = 1 + STATE_PRIMARY_IN_PROGRESS = 2 + STATE_SECONDARY = 3 + + region: str = proto.Field( + proto.STRING, + number=1, + ) + state: "IcebergCatalog.Replica.State" = proto.Field( + proto.ENUM, + number=2, + enum="IcebergCatalog.Replica.State", + ) + + class RestrictedLocationsConfig(proto.Message): + r"""Configuration of location restrictions. + + Attributes: + restricted_locations (MutableSequence[str]): + Optional. Additional Google Cloud Storage buckets and + locations (e.g., ``gs://my-other-bucket/...``) that are + permitted for use by resources within a catalog. This field + is currently only used for BigLake catalogs. + + If ``restricted_locations`` is empty and unrestricted + catalog creation is enabled, all accessible locations are + allowed. Otherwise, only ``default_location`` and locations + in this list are allowed. + """ + + restricted_locations: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + + class FederatedCatalogOptions(proto.Message): + r"""Configuration options for a federated catalog. + + 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: + unity_catalog_info (google.cloud.biglake_v1.types.IcebergCatalog.FederatedCatalogOptions.UnityCatalogInfo): + Optional. Info specific to a Unity Catalog by + Databricks. + + This field is a member of `oneof`_ ``remote_catalog_info``. + glue_catalog_info (google.cloud.biglake_v1.types.IcebergCatalog.FederatedCatalogOptions.GlueCatalogInfo): + Optional. Info specific to an AWS Glue + Catalog. + + This field is a member of `oneof`_ ``remote_catalog_info``. + secret_name (str): + Optional. The secret resource name in Secret Manager, in the + format + ``projects/{project_id}/locations/{location}/secrets/{secret_id}`` + or + ``projects/{project_id}/locations/{location}/secrets/{secret_id}/versions/{version_id}``. + + The project ID must match the catalog's project and location + must match the catalog's location. If the version is not + specified, the latest version will be used. + + This field is not used when + ``service_principal_application_id`` is set. + + This field is a member of `oneof`_ ``_secret_name``. + service_directory_name (str): + Optional. The service directory resource name for routing + traffic over a private network connection through + Cross-Cloud Interconnect, in the format + ``projects/{project_id}/locations/{location_id}/namespaces/{namespace_id}/services/{service_id}``. + + This field is a member of `oneof`_ ``_service_directory_name``. + refresh_options (google.cloud.biglake_v1.types.IcebergCatalog.FederatedCatalogOptions.RefreshOptions): + Optional. Refresh configuration. + refresh_status (google.cloud.biglake_v1.types.IcebergCatalog.FederatedCatalogOptions.RefreshStatus): + Output only. The status of the background + refresh operations. + """ + + class UnityCatalogInfo(proto.Message): + r"""Unity Catalog info. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + instance_name (str): + Required. The instance name is the first part + of the URL when logging into the Databricks + deployment. For example, for a Databricks on GCP + workspace URL https://1.1.gcp.databricks.com, + the instance name is 1.1.gcp.databricks.com. + + This field is a member of `oneof`_ ``_instance_name``. + catalog_name (str): + Required. The catalog name in Unity Catalog. + + This field is a member of `oneof`_ ``_catalog_name``. + service_principal_application_id (str): + Optional. The application ID of the Databricks service + principal that will be used to access the Unity Catalog in + the OIDC authentication flow. With OIDC, the secret_name + field is not used. + + This field is a member of `oneof`_ ``_service_principal_application_id``. + """ + + instance_name: str = proto.Field( + proto.STRING, + number=1, + optional=True, + ) + catalog_name: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + service_principal_application_id: str = proto.Field( + proto.STRING, + number=3, + optional=True, + ) + + class GlueCatalogInfo(proto.Message): + r"""AWS Glue Catalog info. We support regional AWS Glue default + account catalog and S3 Table Buckets. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + warehouse (str): + Required. Immutable. The warehouse to connect to a regional + AWS Glue Iceberg REST Catalog. For top level access, use the + AWS account ID (e.g. 111222333444). For an S3 table bucket, + the warehouse is of the form: 111222333444:s3tablescatalog/. + The URL to access catalog will be + https://glue.{aws_region}.amazonaws.com/iceberg/v1?warehouse={warehouse}. + Must be non-empty and is immutable. + + This field is a member of `oneof`_ ``_warehouse``. + aws_region (str): + Required. Immutable. The AWS region of the + Glue catalog to connect to. The region should be + in the same geographical region and jurisdiction + as the federated catalog. + Must be non-empty and is immutable. + + This field is a member of `oneof`_ ``_aws_region``. + aws_role_arn (str): + Required. The AWS role ARN of the Glue + catalog that the federated catalog will assume + to access the catalog. Must be non-empty. Can be + updated. + + This field is a member of `oneof`_ ``_aws_role_arn``. + """ + + warehouse: str = proto.Field( + proto.STRING, + number=1, + optional=True, + ) + aws_region: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + aws_role_arn: str = proto.Field( + proto.STRING, + number=3, + optional=True, + ) + + class RefreshSchedule(proto.Message): + r"""Schedule defines if and when metadata refresh should be + scheduled. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + refresh_interval (google.protobuf.duration_pb2.Duration): + Optional. The interval for refreshing + metadata from the remote catalog. If unset or if + the value is <= 0, the background refresh will + be disabled. If this field is updated for an + existing federated catalog, the previous + background refresh must complete before the new + refresh interval will take effect. + + This field is a member of `oneof`_ ``_refresh_interval``. + """ + + refresh_interval: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=1, + optional=True, + message=duration_pb2.Duration, + ) + + class RefreshScope(proto.Message): + r"""The scope defines a subset of namespaces to be refreshed. + + Attributes: + namespace_filters (MutableSequence[str]): + Optional. Filters to determine which namespaces are included + in the refresh process. + + - empty list means include all namespaces. + - "[namespaces]" means include the specified namespaces. + ['ns1', 'ns2'] : Discover only namespaces 'ns1' and 'ns2'. + The maximum number of namespace filters allowed is 32. + """ + + namespace_filters: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + + class RefreshOptions(proto.Message): + r"""Refresh configuration. + + Attributes: + refresh_schedule (google.cloud.biglake_v1.types.IcebergCatalog.FederatedCatalogOptions.RefreshSchedule): + Optional. Schedule defines if and when + metadata refresh should be scheduled. + refresh_scope (google.cloud.biglake_v1.types.IcebergCatalog.FederatedCatalogOptions.RefreshScope): + Optional. Refresh scope configurations. + """ + + refresh_schedule: "IcebergCatalog.FederatedCatalogOptions.RefreshSchedule" = proto.Field( + proto.MESSAGE, + number=1, + message="IcebergCatalog.FederatedCatalogOptions.RefreshSchedule", + ) + refresh_scope: "IcebergCatalog.FederatedCatalogOptions.RefreshScope" = ( + proto.Field( + proto.MESSAGE, + number=2, + message="IcebergCatalog.FederatedCatalogOptions.RefreshScope", + ) + ) + + class RefreshStatus(proto.Message): + r"""Remote catalog background refresh status. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + start_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. When the catalog refresh has + started, including in-progress refreshes. + + This field is a member of `oneof`_ ``_start_time``. + end_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. When the catalog refresh has + ended, unset for in-progress refreshes. + + This field is a member of `oneof`_ ``_end_time``. + status (google.rpc.status_pb2.Status): + Output only. The status of the last + background refresh operation, unset for + in-progress refreshes. + + This field is a member of `oneof`_ ``_status``. + """ + + start_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + optional=True, + message=timestamp_pb2.Timestamp, + ) + end_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + optional=True, + message=timestamp_pb2.Timestamp, + ) + status: status_pb2.Status = proto.Field( + proto.MESSAGE, + number=3, + optional=True, + message=status_pb2.Status, + ) + + unity_catalog_info: "IcebergCatalog.FederatedCatalogOptions.UnityCatalogInfo" = proto.Field( + proto.MESSAGE, + number=2, + oneof="remote_catalog_info", + message="IcebergCatalog.FederatedCatalogOptions.UnityCatalogInfo", + ) + glue_catalog_info: "IcebergCatalog.FederatedCatalogOptions.GlueCatalogInfo" = ( + proto.Field( + proto.MESSAGE, + number=4, + oneof="remote_catalog_info", + message="IcebergCatalog.FederatedCatalogOptions.GlueCatalogInfo", + ) + ) + secret_name: str = proto.Field( + proto.STRING, + number=1, + optional=True, + ) + service_directory_name: str = proto.Field( + proto.STRING, + number=5, + optional=True, + ) + refresh_options: "IcebergCatalog.FederatedCatalogOptions.RefreshOptions" = ( + proto.Field( + proto.MESSAGE, + number=3, + message="IcebergCatalog.FederatedCatalogOptions.RefreshOptions", + ) + ) + refresh_status: "IcebergCatalog.FederatedCatalogOptions.RefreshStatus" = ( + proto.Field( + proto.MESSAGE, + number=6, + message="IcebergCatalog.FederatedCatalogOptions.RefreshStatus", + ) + ) + name: str = proto.Field( proto.STRING, number=1, @@ -132,6 +539,10 @@ class CredentialMode(proto.Enum): proto.STRING, number=3, ) + biglake_service_account_unique_id: str = proto.Field( + proto.STRING, + number=14, + ) catalog_type: CatalogType = proto.Field( proto.ENUM, number=4, @@ -141,9 +552,9 @@ class CredentialMode(proto.Enum): proto.STRING, number=5, ) - catalog_regions: MutableSequence[str] = proto.RepeatedField( + storage_regions: MutableSequence[str] = proto.RepeatedField( proto.STRING, - number=6, + number=10, ) create_time: timestamp_pb2.Timestamp = proto.Field( proto.MESSAGE, @@ -155,6 +566,25 @@ class CredentialMode(proto.Enum): number=8, message=timestamp_pb2.Timestamp, ) + replicas: MutableSequence[Replica] = proto.RepeatedField( + proto.MESSAGE, + number=9, + message=Replica, + ) + description: str = proto.Field( + proto.STRING, + number=12, + ) + restricted_locations_config: RestrictedLocationsConfig = proto.Field( + proto.MESSAGE, + number=15, + message=RestrictedLocationsConfig, + ) + federated_catalog_options: FederatedCatalogOptions = proto.Field( + proto.MESSAGE, + number=13, + message=FederatedCatalogOptions, + ) class CreateIcebergCatalogRequest(proto.Message): @@ -172,6 +602,23 @@ class CreateIcebergCatalogRequest(proto.Message): - catalog_type. Optionally: credential_mode can be provided, if Credential Vending is desired. + primary_location (str): + Optional. The primary location where the catalog metadata + will be stored. + + For Google Cloud Storage bucket catalogs and BigLake + catalogs, if this is not specified, then the region is + inferred from the bucket's region (``default_location`` + bucket for BigLake catalogs). If specified, the region must + be in jurisdiction (near the ``default_location`` bucket's + region and the ``restricted_locations`` buckets' regions for + BigLake catalogs). + + For federated catalogs, this must be specified and be a + Lakehouse-supported location + (https://docs.cloud.google.com/lakehouse/docs/locations). It + should be close to the remote catalog's location for the + best performance and cost. """ parent: str = proto.Field( @@ -187,6 +634,10 @@ class CreateIcebergCatalogRequest(proto.Message): number=2, message="IcebergCatalog", ) + primary_location: str = proto.Field( + proto.STRING, + number=4, + ) class UpdateIcebergCatalogRequest(proto.Message): @@ -290,7 +741,8 @@ class ListIcebergCatalogsResponse(proto.Message): pagination. unreachable (MutableSequence[str]): Output only. The list of unreachable cloud - regions for router fanout. + regions. If non-empty, the result set might be + incomplete. """ @property diff --git a/packages/google-cloud-biglake/samples/generated_samples/biglake_v1_generated_iceberg_catalog_service_create_iceberg_catalog_async.py b/packages/google-cloud-biglake/samples/generated_samples/biglake_v1_generated_iceberg_catalog_service_create_iceberg_catalog_async.py index 8a751673904b..57e4bf36dfd8 100644 --- a/packages/google-cloud-biglake/samples/generated_samples/biglake_v1_generated_iceberg_catalog_service_create_iceberg_catalog_async.py +++ b/packages/google-cloud-biglake/samples/generated_samples/biglake_v1_generated_iceberg_catalog_service_create_iceberg_catalog_async.py @@ -40,7 +40,7 @@ async def sample_create_iceberg_catalog(): # Initialize request argument(s) iceberg_catalog = biglake_v1.IcebergCatalog() - iceberg_catalog.catalog_type = "CATALOG_TYPE_GCS_BUCKET" + iceberg_catalog.catalog_type = "CATALOG_TYPE_FEDERATED" request = biglake_v1.CreateIcebergCatalogRequest( parent="parent_value", diff --git a/packages/google-cloud-biglake/samples/generated_samples/biglake_v1_generated_iceberg_catalog_service_create_iceberg_catalog_sync.py b/packages/google-cloud-biglake/samples/generated_samples/biglake_v1_generated_iceberg_catalog_service_create_iceberg_catalog_sync.py index c32930d8200e..74e0b8e2077a 100644 --- a/packages/google-cloud-biglake/samples/generated_samples/biglake_v1_generated_iceberg_catalog_service_create_iceberg_catalog_sync.py +++ b/packages/google-cloud-biglake/samples/generated_samples/biglake_v1_generated_iceberg_catalog_service_create_iceberg_catalog_sync.py @@ -40,7 +40,7 @@ def sample_create_iceberg_catalog(): # Initialize request argument(s) iceberg_catalog = biglake_v1.IcebergCatalog() - iceberg_catalog.catalog_type = "CATALOG_TYPE_GCS_BUCKET" + iceberg_catalog.catalog_type = "CATALOG_TYPE_FEDERATED" request = biglake_v1.CreateIcebergCatalogRequest( parent="parent_value", diff --git a/packages/google-cloud-biglake/samples/generated_samples/biglake_v1_generated_iceberg_catalog_service_update_iceberg_catalog_async.py b/packages/google-cloud-biglake/samples/generated_samples/biglake_v1_generated_iceberg_catalog_service_update_iceberg_catalog_async.py index 3e587c3d94fc..7711224c12d0 100644 --- a/packages/google-cloud-biglake/samples/generated_samples/biglake_v1_generated_iceberg_catalog_service_update_iceberg_catalog_async.py +++ b/packages/google-cloud-biglake/samples/generated_samples/biglake_v1_generated_iceberg_catalog_service_update_iceberg_catalog_async.py @@ -40,7 +40,7 @@ async def sample_update_iceberg_catalog(): # Initialize request argument(s) iceberg_catalog = biglake_v1.IcebergCatalog() - iceberg_catalog.catalog_type = "CATALOG_TYPE_GCS_BUCKET" + iceberg_catalog.catalog_type = "CATALOG_TYPE_FEDERATED" request = biglake_v1.UpdateIcebergCatalogRequest( iceberg_catalog=iceberg_catalog, diff --git a/packages/google-cloud-biglake/samples/generated_samples/biglake_v1_generated_iceberg_catalog_service_update_iceberg_catalog_sync.py b/packages/google-cloud-biglake/samples/generated_samples/biglake_v1_generated_iceberg_catalog_service_update_iceberg_catalog_sync.py index 718966a119ce..63ec0400149a 100644 --- a/packages/google-cloud-biglake/samples/generated_samples/biglake_v1_generated_iceberg_catalog_service_update_iceberg_catalog_sync.py +++ b/packages/google-cloud-biglake/samples/generated_samples/biglake_v1_generated_iceberg_catalog_service_update_iceberg_catalog_sync.py @@ -40,7 +40,7 @@ def sample_update_iceberg_catalog(): # Initialize request argument(s) iceberg_catalog = biglake_v1.IcebergCatalog() - iceberg_catalog.catalog_type = "CATALOG_TYPE_GCS_BUCKET" + iceberg_catalog.catalog_type = "CATALOG_TYPE_FEDERATED" request = biglake_v1.UpdateIcebergCatalogRequest( iceberg_catalog=iceberg_catalog, diff --git a/packages/google-cloud-biglake/samples/generated_samples/snippet_metadata_google.cloud.biglake.v1.json b/packages/google-cloud-biglake/samples/generated_samples/snippet_metadata_google.cloud.biglake.v1.json index 0320d2ab7629..df3623823115 100644 --- a/packages/google-cloud-biglake/samples/generated_samples/snippet_metadata_google.cloud.biglake.v1.json +++ b/packages/google-cloud-biglake/samples/generated_samples/snippet_metadata_google.cloud.biglake.v1.json @@ -45,6 +45,10 @@ "name": "iceberg_catalog_id", "type": "str" }, + { + "name": "primary_location", + "type": "str" + }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -133,6 +137,10 @@ "name": "iceberg_catalog_id", "type": "str" }, + { + "name": "primary_location", + "type": "str" + }, { "name": "retry", "type": "google.api_core.retry.Retry" diff --git a/packages/google-cloud-biglake/tests/unit/gapic/biglake_v1/test_iceberg_catalog_service.py b/packages/google-cloud-biglake/tests/unit/gapic/biglake_v1/test_iceberg_catalog_service.py index 71db32ccb04c..78612c605685 100644 --- a/packages/google-cloud-biglake/tests/unit/gapic/biglake_v1/test_iceberg_catalog_service.py +++ b/packages/google-cloud-biglake/tests/unit/gapic/biglake_v1/test_iceberg_catalog_service.py @@ -39,8 +39,11 @@ HAS_GOOGLE_AUTH_AIO = False import google.auth +import google.protobuf.any_pb2 as any_pb2 # type: ignore +import google.protobuf.duration_pb2 as duration_pb2 # type: ignore import google.protobuf.field_mask_pb2 as field_mask_pb2 # type: ignore import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore +import google.rpc.status_pb2 as status_pb2 # type: ignore from google.api_core import ( client_options, gapic_v1, @@ -1416,9 +1419,11 @@ def test_get_iceberg_catalog(request_type, transport: str = "grpc"): name="name_value", credential_mode=iceberg_rest_catalog.IcebergCatalog.CredentialMode.CREDENTIAL_MODE_END_USER, biglake_service_account="biglake_service_account_value", + biglake_service_account_unique_id="biglake_service_account_unique_id_value", catalog_type=iceberg_rest_catalog.IcebergCatalog.CatalogType.CATALOG_TYPE_GCS_BUCKET, default_location="default_location_value", - catalog_regions=["catalog_regions_value"], + storage_regions=["storage_regions_value"], + description="description_value", ) response = client.get_iceberg_catalog(request) @@ -1436,12 +1441,17 @@ def test_get_iceberg_catalog(request_type, transport: str = "grpc"): == iceberg_rest_catalog.IcebergCatalog.CredentialMode.CREDENTIAL_MODE_END_USER ) assert response.biglake_service_account == "biglake_service_account_value" + assert ( + response.biglake_service_account_unique_id + == "biglake_service_account_unique_id_value" + ) assert ( response.catalog_type == iceberg_rest_catalog.IcebergCatalog.CatalogType.CATALOG_TYPE_GCS_BUCKET ) assert response.default_location == "default_location_value" - assert response.catalog_regions == ["catalog_regions_value"] + assert response.storage_regions == ["storage_regions_value"] + assert response.description == "description_value" def test_get_iceberg_catalog_non_empty_request_with_auto_populated_field(): @@ -1584,9 +1594,11 @@ async def test_get_iceberg_catalog_async(request_type, transport: str = "grpc_as name="name_value", credential_mode=iceberg_rest_catalog.IcebergCatalog.CredentialMode.CREDENTIAL_MODE_END_USER, biglake_service_account="biglake_service_account_value", + biglake_service_account_unique_id="biglake_service_account_unique_id_value", catalog_type=iceberg_rest_catalog.IcebergCatalog.CatalogType.CATALOG_TYPE_GCS_BUCKET, default_location="default_location_value", - catalog_regions=["catalog_regions_value"], + storage_regions=["storage_regions_value"], + description="description_value", ) ) response = await client.get_iceberg_catalog(request) @@ -1605,12 +1617,17 @@ async def test_get_iceberg_catalog_async(request_type, transport: str = "grpc_as == iceberg_rest_catalog.IcebergCatalog.CredentialMode.CREDENTIAL_MODE_END_USER ) assert response.biglake_service_account == "biglake_service_account_value" + assert ( + response.biglake_service_account_unique_id + == "biglake_service_account_unique_id_value" + ) assert ( response.catalog_type == iceberg_rest_catalog.IcebergCatalog.CatalogType.CATALOG_TYPE_GCS_BUCKET ) assert response.default_location == "default_location_value" - assert response.catalog_regions == ["catalog_regions_value"] + assert response.storage_regions == ["storage_regions_value"] + assert response.description == "description_value" def test_get_iceberg_catalog_field_headers(): @@ -2341,9 +2358,11 @@ def test_update_iceberg_catalog(request_type, transport: str = "grpc"): name="name_value", credential_mode=iceberg_rest_catalog.IcebergCatalog.CredentialMode.CREDENTIAL_MODE_END_USER, biglake_service_account="biglake_service_account_value", + biglake_service_account_unique_id="biglake_service_account_unique_id_value", catalog_type=iceberg_rest_catalog.IcebergCatalog.CatalogType.CATALOG_TYPE_GCS_BUCKET, default_location="default_location_value", - catalog_regions=["catalog_regions_value"], + storage_regions=["storage_regions_value"], + description="description_value", ) response = client.update_iceberg_catalog(request) @@ -2361,12 +2380,17 @@ def test_update_iceberg_catalog(request_type, transport: str = "grpc"): == iceberg_rest_catalog.IcebergCatalog.CredentialMode.CREDENTIAL_MODE_END_USER ) assert response.biglake_service_account == "biglake_service_account_value" + assert ( + response.biglake_service_account_unique_id + == "biglake_service_account_unique_id_value" + ) assert ( response.catalog_type == iceberg_rest_catalog.IcebergCatalog.CatalogType.CATALOG_TYPE_GCS_BUCKET ) assert response.default_location == "default_location_value" - assert response.catalog_regions == ["catalog_regions_value"] + assert response.storage_regions == ["storage_regions_value"] + assert response.description == "description_value" def test_update_iceberg_catalog_non_empty_request_with_auto_populated_field(): @@ -2508,9 +2532,11 @@ async def test_update_iceberg_catalog_async( name="name_value", credential_mode=iceberg_rest_catalog.IcebergCatalog.CredentialMode.CREDENTIAL_MODE_END_USER, biglake_service_account="biglake_service_account_value", + biglake_service_account_unique_id="biglake_service_account_unique_id_value", catalog_type=iceberg_rest_catalog.IcebergCatalog.CatalogType.CATALOG_TYPE_GCS_BUCKET, default_location="default_location_value", - catalog_regions=["catalog_regions_value"], + storage_regions=["storage_regions_value"], + description="description_value", ) ) response = await client.update_iceberg_catalog(request) @@ -2529,12 +2555,17 @@ async def test_update_iceberg_catalog_async( == iceberg_rest_catalog.IcebergCatalog.CredentialMode.CREDENTIAL_MODE_END_USER ) assert response.biglake_service_account == "biglake_service_account_value" + assert ( + response.biglake_service_account_unique_id + == "biglake_service_account_unique_id_value" + ) assert ( response.catalog_type == iceberg_rest_catalog.IcebergCatalog.CatalogType.CATALOG_TYPE_GCS_BUCKET ) assert response.default_location == "default_location_value" - assert response.catalog_regions == ["catalog_regions_value"] + assert response.storage_regions == ["storage_regions_value"] + assert response.description == "description_value" def test_update_iceberg_catalog_field_headers(): @@ -2724,9 +2755,11 @@ def test_create_iceberg_catalog(request_type, transport: str = "grpc"): name="name_value", credential_mode=iceberg_rest_catalog.IcebergCatalog.CredentialMode.CREDENTIAL_MODE_END_USER, biglake_service_account="biglake_service_account_value", + biglake_service_account_unique_id="biglake_service_account_unique_id_value", catalog_type=iceberg_rest_catalog.IcebergCatalog.CatalogType.CATALOG_TYPE_GCS_BUCKET, default_location="default_location_value", - catalog_regions=["catalog_regions_value"], + storage_regions=["storage_regions_value"], + description="description_value", ) response = client.create_iceberg_catalog(request) @@ -2744,12 +2777,17 @@ def test_create_iceberg_catalog(request_type, transport: str = "grpc"): == iceberg_rest_catalog.IcebergCatalog.CredentialMode.CREDENTIAL_MODE_END_USER ) assert response.biglake_service_account == "biglake_service_account_value" + assert ( + response.biglake_service_account_unique_id + == "biglake_service_account_unique_id_value" + ) assert ( response.catalog_type == iceberg_rest_catalog.IcebergCatalog.CatalogType.CATALOG_TYPE_GCS_BUCKET ) assert response.default_location == "default_location_value" - assert response.catalog_regions == ["catalog_regions_value"] + assert response.storage_regions == ["storage_regions_value"] + assert response.description == "description_value" def test_create_iceberg_catalog_non_empty_request_with_auto_populated_field(): @@ -2766,6 +2804,7 @@ def test_create_iceberg_catalog_non_empty_request_with_auto_populated_field(): request = iceberg_rest_catalog.CreateIcebergCatalogRequest( parent="parent_value", iceberg_catalog_id="iceberg_catalog_id_value", + primary_location="primary_location_value", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2781,6 +2820,7 @@ def test_create_iceberg_catalog_non_empty_request_with_auto_populated_field(): request_msg = iceberg_rest_catalog.CreateIcebergCatalogRequest( parent="parent_value", iceberg_catalog_id="iceberg_catalog_id_value", + primary_location="primary_location_value", ) assert args[0] == request_msg @@ -2897,9 +2937,11 @@ async def test_create_iceberg_catalog_async( name="name_value", credential_mode=iceberg_rest_catalog.IcebergCatalog.CredentialMode.CREDENTIAL_MODE_END_USER, biglake_service_account="biglake_service_account_value", + biglake_service_account_unique_id="biglake_service_account_unique_id_value", catalog_type=iceberg_rest_catalog.IcebergCatalog.CatalogType.CATALOG_TYPE_GCS_BUCKET, default_location="default_location_value", - catalog_regions=["catalog_regions_value"], + storage_regions=["storage_regions_value"], + description="description_value", ) ) response = await client.create_iceberg_catalog(request) @@ -2918,12 +2960,17 @@ async def test_create_iceberg_catalog_async( == iceberg_rest_catalog.IcebergCatalog.CredentialMode.CREDENTIAL_MODE_END_USER ) assert response.biglake_service_account == "biglake_service_account_value" + assert ( + response.biglake_service_account_unique_id + == "biglake_service_account_unique_id_value" + ) assert ( response.catalog_type == iceberg_rest_catalog.IcebergCatalog.CatalogType.CATALOG_TYPE_GCS_BUCKET ) assert response.default_location == "default_location_value" - assert response.catalog_regions == ["catalog_regions_value"] + assert response.storage_regions == ["storage_regions_value"] + assert response.description == "description_value" def test_create_iceberg_catalog_field_headers(): @@ -3008,6 +3055,7 @@ def test_create_iceberg_catalog_flattened(): parent="parent_value", iceberg_catalog=iceberg_rest_catalog.IcebergCatalog(name="name_value"), iceberg_catalog_id="iceberg_catalog_id_value", + primary_location="primary_location_value", ) # Establish that the underlying call was made with the expected @@ -3023,6 +3071,9 @@ def test_create_iceberg_catalog_flattened(): arg = args[0].iceberg_catalog_id mock_val = "iceberg_catalog_id_value" assert arg == mock_val + arg = args[0].primary_location + mock_val = "primary_location_value" + assert arg == mock_val def test_create_iceberg_catalog_flattened_error(): @@ -3038,6 +3089,7 @@ def test_create_iceberg_catalog_flattened_error(): parent="parent_value", iceberg_catalog=iceberg_rest_catalog.IcebergCatalog(name="name_value"), iceberg_catalog_id="iceberg_catalog_id_value", + primary_location="primary_location_value", ) @@ -3063,6 +3115,7 @@ async def test_create_iceberg_catalog_flattened_async(): parent="parent_value", iceberg_catalog=iceberg_rest_catalog.IcebergCatalog(name="name_value"), iceberg_catalog_id="iceberg_catalog_id_value", + primary_location="primary_location_value", ) # Establish that the underlying call was made with the expected @@ -3078,6 +3131,9 @@ async def test_create_iceberg_catalog_flattened_async(): arg = args[0].iceberg_catalog_id mock_val = "iceberg_catalog_id_value" assert arg == mock_val + arg = args[0].primary_location + mock_val = "primary_location_value" + assert arg == mock_val @pytest.mark.asyncio @@ -3094,6 +3150,7 @@ async def test_create_iceberg_catalog_flattened_error_async(): parent="parent_value", iceberg_catalog=iceberg_rest_catalog.IcebergCatalog(name="name_value"), iceberg_catalog_id="iceberg_catalog_id_value", + primary_location="primary_location_value", ) @@ -4155,7 +4212,12 @@ def test_create_iceberg_catalog_rest_required_fields( credentials=ga_credentials.AnonymousCredentials() ).create_iceberg_catalog._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("iceberg_catalog_id",)) + assert not set(unset_fields) - set( + ( + "iceberg_catalog_id", + "primary_location", + ) + ) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -4220,7 +4282,12 @@ def test_create_iceberg_catalog_rest_unset_required_fields(): unset_fields = transport.create_iceberg_catalog._get_unset_required_fields({}) assert set(unset_fields) == ( - set(("icebergCatalogId",)) + set( + ( + "icebergCatalogId", + "primaryLocation", + ) + ) & set( ( "parent", @@ -4250,6 +4317,7 @@ def test_create_iceberg_catalog_rest_flattened(): parent="parent_value", iceberg_catalog=iceberg_rest_catalog.IcebergCatalog(name="name_value"), iceberg_catalog_id="iceberg_catalog_id_value", + primary_location="primary_location_value", ) mock_args.update(sample_request) @@ -4290,6 +4358,7 @@ def test_create_iceberg_catalog_rest_flattened_error(transport: str = "rest"): parent="parent_value", iceberg_catalog=iceberg_rest_catalog.IcebergCatalog(name="name_value"), iceberg_catalog_id="iceberg_catalog_id_value", + primary_location="primary_location_value", ) @@ -4744,9 +4813,11 @@ async def test_get_iceberg_catalog_empty_call_grpc_asyncio(): name="name_value", credential_mode=iceberg_rest_catalog.IcebergCatalog.CredentialMode.CREDENTIAL_MODE_END_USER, biglake_service_account="biglake_service_account_value", + biglake_service_account_unique_id="biglake_service_account_unique_id_value", catalog_type=iceberg_rest_catalog.IcebergCatalog.CatalogType.CATALOG_TYPE_GCS_BUCKET, default_location="default_location_value", - catalog_regions=["catalog_regions_value"], + storage_regions=["storage_regions_value"], + description="description_value", ) ) await client.get_iceberg_catalog(request=None) @@ -4806,9 +4877,11 @@ async def test_update_iceberg_catalog_empty_call_grpc_asyncio(): name="name_value", credential_mode=iceberg_rest_catalog.IcebergCatalog.CredentialMode.CREDENTIAL_MODE_END_USER, biglake_service_account="biglake_service_account_value", + biglake_service_account_unique_id="biglake_service_account_unique_id_value", catalog_type=iceberg_rest_catalog.IcebergCatalog.CatalogType.CATALOG_TYPE_GCS_BUCKET, default_location="default_location_value", - catalog_regions=["catalog_regions_value"], + storage_regions=["storage_regions_value"], + description="description_value", ) ) await client.update_iceberg_catalog(request=None) @@ -4839,9 +4912,11 @@ async def test_create_iceberg_catalog_empty_call_grpc_asyncio(): name="name_value", credential_mode=iceberg_rest_catalog.IcebergCatalog.CredentialMode.CREDENTIAL_MODE_END_USER, biglake_service_account="biglake_service_account_value", + biglake_service_account_unique_id="biglake_service_account_unique_id_value", catalog_type=iceberg_rest_catalog.IcebergCatalog.CatalogType.CATALOG_TYPE_GCS_BUCKET, default_location="default_location_value", - catalog_regions=["catalog_regions_value"], + storage_regions=["storage_regions_value"], + description="description_value", ) ) await client.create_iceberg_catalog(request=None) @@ -4935,9 +5010,11 @@ def test_get_iceberg_catalog_rest_call_success(request_type): name="name_value", credential_mode=iceberg_rest_catalog.IcebergCatalog.CredentialMode.CREDENTIAL_MODE_END_USER, biglake_service_account="biglake_service_account_value", + biglake_service_account_unique_id="biglake_service_account_unique_id_value", catalog_type=iceberg_rest_catalog.IcebergCatalog.CatalogType.CATALOG_TYPE_GCS_BUCKET, default_location="default_location_value", - catalog_regions=["catalog_regions_value"], + storage_regions=["storage_regions_value"], + description="description_value", ) # Wrap the value into a proper Response obj @@ -4960,12 +5037,17 @@ def test_get_iceberg_catalog_rest_call_success(request_type): == iceberg_rest_catalog.IcebergCatalog.CredentialMode.CREDENTIAL_MODE_END_USER ) assert response.biglake_service_account == "biglake_service_account_value" + assert ( + response.biglake_service_account_unique_id + == "biglake_service_account_unique_id_value" + ) assert ( response.catalog_type == iceberg_rest_catalog.IcebergCatalog.CatalogType.CATALOG_TYPE_GCS_BUCKET ) assert response.default_location == "default_location_value" - assert response.catalog_regions == ["catalog_regions_value"] + assert response.storage_regions == ["storage_regions_value"] + assert response.description == "description_value" @pytest.mark.parametrize("null_interceptor", [True, False]) @@ -5221,11 +5303,59 @@ def test_update_iceberg_catalog_rest_call_success(request_type): "name": "projects/sample1/catalogs/sample2", "credential_mode": 1, "biglake_service_account": "biglake_service_account_value", + "biglake_service_account_unique_id": "biglake_service_account_unique_id_value", "catalog_type": 1, "default_location": "default_location_value", - "catalog_regions": ["catalog_regions_value1", "catalog_regions_value2"], + "storage_regions": ["storage_regions_value1", "storage_regions_value2"], "create_time": {"seconds": 751, "nanos": 543}, "update_time": {}, + "replicas": [{"region": "region_value", "state": 1}], + "description": "description_value", + "restricted_locations_config": { + "restricted_locations": [ + "restricted_locations_value1", + "restricted_locations_value2", + ] + }, + "federated_catalog_options": { + "unity_catalog_info": { + "instance_name": "instance_name_value", + "catalog_name": "catalog_name_value", + "service_principal_application_id": "service_principal_application_id_value", + }, + "glue_catalog_info": { + "warehouse": "warehouse_value", + "aws_region": "aws_region_value", + "aws_role_arn": "aws_role_arn_value", + }, + "secret_name": "secret_name_value", + "service_directory_name": "service_directory_name_value", + "refresh_options": { + "refresh_schedule": { + "refresh_interval": {"seconds": 751, "nanos": 543} + }, + "refresh_scope": { + "namespace_filters": [ + "namespace_filters_value1", + "namespace_filters_value2", + ] + }, + }, + "refresh_status": { + "start_time": {}, + "end_time": {}, + "status": { + "code": 411, + "message": "message_value", + "details": [ + { + "type_url": "type.googleapis.com/google.protobuf.Duration", + "value": b"\x08\x0c\x10\xdb\x07", + } + ], + }, + }, + }, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -5305,9 +5435,11 @@ def get_message_fields(field): name="name_value", credential_mode=iceberg_rest_catalog.IcebergCatalog.CredentialMode.CREDENTIAL_MODE_END_USER, biglake_service_account="biglake_service_account_value", + biglake_service_account_unique_id="biglake_service_account_unique_id_value", catalog_type=iceberg_rest_catalog.IcebergCatalog.CatalogType.CATALOG_TYPE_GCS_BUCKET, default_location="default_location_value", - catalog_regions=["catalog_regions_value"], + storage_regions=["storage_regions_value"], + description="description_value", ) # Wrap the value into a proper Response obj @@ -5330,12 +5462,17 @@ def get_message_fields(field): == iceberg_rest_catalog.IcebergCatalog.CredentialMode.CREDENTIAL_MODE_END_USER ) assert response.biglake_service_account == "biglake_service_account_value" + assert ( + response.biglake_service_account_unique_id + == "biglake_service_account_unique_id_value" + ) assert ( response.catalog_type == iceberg_rest_catalog.IcebergCatalog.CatalogType.CATALOG_TYPE_GCS_BUCKET ) assert response.default_location == "default_location_value" - assert response.catalog_regions == ["catalog_regions_value"] + assert response.storage_regions == ["storage_regions_value"] + assert response.description == "description_value" @pytest.mark.parametrize("null_interceptor", [True, False]) @@ -5454,11 +5591,59 @@ def test_create_iceberg_catalog_rest_call_success(request_type): "name": "name_value", "credential_mode": 1, "biglake_service_account": "biglake_service_account_value", + "biglake_service_account_unique_id": "biglake_service_account_unique_id_value", "catalog_type": 1, "default_location": "default_location_value", - "catalog_regions": ["catalog_regions_value1", "catalog_regions_value2"], + "storage_regions": ["storage_regions_value1", "storage_regions_value2"], "create_time": {"seconds": 751, "nanos": 543}, "update_time": {}, + "replicas": [{"region": "region_value", "state": 1}], + "description": "description_value", + "restricted_locations_config": { + "restricted_locations": [ + "restricted_locations_value1", + "restricted_locations_value2", + ] + }, + "federated_catalog_options": { + "unity_catalog_info": { + "instance_name": "instance_name_value", + "catalog_name": "catalog_name_value", + "service_principal_application_id": "service_principal_application_id_value", + }, + "glue_catalog_info": { + "warehouse": "warehouse_value", + "aws_region": "aws_region_value", + "aws_role_arn": "aws_role_arn_value", + }, + "secret_name": "secret_name_value", + "service_directory_name": "service_directory_name_value", + "refresh_options": { + "refresh_schedule": { + "refresh_interval": {"seconds": 751, "nanos": 543} + }, + "refresh_scope": { + "namespace_filters": [ + "namespace_filters_value1", + "namespace_filters_value2", + ] + }, + }, + "refresh_status": { + "start_time": {}, + "end_time": {}, + "status": { + "code": 411, + "message": "message_value", + "details": [ + { + "type_url": "type.googleapis.com/google.protobuf.Duration", + "value": b"\x08\x0c\x10\xdb\x07", + } + ], + }, + }, + }, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -5538,9 +5723,11 @@ def get_message_fields(field): name="name_value", credential_mode=iceberg_rest_catalog.IcebergCatalog.CredentialMode.CREDENTIAL_MODE_END_USER, biglake_service_account="biglake_service_account_value", + biglake_service_account_unique_id="biglake_service_account_unique_id_value", catalog_type=iceberg_rest_catalog.IcebergCatalog.CatalogType.CATALOG_TYPE_GCS_BUCKET, default_location="default_location_value", - catalog_regions=["catalog_regions_value"], + storage_regions=["storage_regions_value"], + description="description_value", ) # Wrap the value into a proper Response obj @@ -5563,12 +5750,17 @@ def get_message_fields(field): == iceberg_rest_catalog.IcebergCatalog.CredentialMode.CREDENTIAL_MODE_END_USER ) assert response.biglake_service_account == "biglake_service_account_value" + assert ( + response.biglake_service_account_unique_id + == "biglake_service_account_unique_id_value" + ) assert ( response.catalog_type == iceberg_rest_catalog.IcebergCatalog.CatalogType.CATALOG_TYPE_GCS_BUCKET ) assert response.default_location == "default_location_value" - assert response.catalog_regions == ["catalog_regions_value"] + assert response.storage_regions == ["storage_regions_value"] + assert response.description == "description_value" @pytest.mark.parametrize("null_interceptor", [True, False]) @@ -6378,6 +6570,60 @@ def test_parse_catalog_path(): assert expected == actual +def test_secret_path(): + project = "oyster" + secret = "nudibranch" + expected = "projects/{project}/secrets/{secret}".format( + project=project, + secret=secret, + ) + actual = IcebergCatalogServiceClient.secret_path(project, secret) + assert expected == actual + + +def test_parse_secret_path(): + expected = { + "project": "cuttlefish", + "secret": "mussel", + } + path = IcebergCatalogServiceClient.secret_path(**expected) + + # Check that the path construction is reversible. + actual = IcebergCatalogServiceClient.parse_secret_path(path) + assert expected == actual + + +def test_service_path(): + project = "winkle" + location = "nautilus" + namespace = "scallop" + service = "abalone" + expected = "projects/{project}/locations/{location}/namespaces/{namespace}/services/{service}".format( + project=project, + location=location, + namespace=namespace, + service=service, + ) + actual = IcebergCatalogServiceClient.service_path( + project, location, namespace, service + ) + assert expected == actual + + +def test_parse_service_path(): + expected = { + "project": "squid", + "location": "clam", + "namespace": "whelk", + "service": "octopus", + } + path = IcebergCatalogServiceClient.service_path(**expected) + + # Check that the path construction is reversible. + actual = IcebergCatalogServiceClient.parse_service_path(path) + assert expected == actual + + def test_common_billing_account_path(): billing_account = "oyster" expected = "billingAccounts/{billing_account}".format( diff --git a/packages/google-cloud-bigtable/samples/snippets/filters/filter_snippets_async_test.py b/packages/google-cloud-bigtable/samples/snippets/filters/filter_snippets_async_test.py index 3c961a27b752..b750564e2901 100644 --- a/packages/google-cloud-bigtable/samples/snippets/filters/filter_snippets_async_test.py +++ b/packages/google-cloud-bigtable/samples/snippets/filters/filter_snippets_async_test.py @@ -20,9 +20,7 @@ import pytest import pytest_asyncio -from google.cloud._helpers import ( - _microseconds_from_datetime, -) +from google.cloud._helpers import _microseconds_from_datetime from ...utils import create_table_cm from . import filter_snippets_async diff --git a/packages/google-cloud-bigtable/samples/snippets/reads/read_snippets.py b/packages/google-cloud-bigtable/samples/snippets/reads/read_snippets.py index 7bdf01c7c890..1d4ee3d8e650 100644 --- a/packages/google-cloud-bigtable/samples/snippets/reads/read_snippets.py +++ b/packages/google-cloud-bigtable/samples/snippets/reads/read_snippets.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. + # [START bigtable_reads_row] def read_row(project_id, instance_id, table_id): from google.cloud import bigtable diff --git a/packages/google-cloud-bigtable/samples/testdata/singer_pb2.py b/packages/google-cloud-bigtable/samples/testdata/singer_pb2.py index f5da249d4811..2579349f0753 100644 --- a/packages/google-cloud-bigtable/samples/testdata/singer_pb2.py +++ b/packages/google-cloud-bigtable/samples/testdata/singer_pb2.py @@ -1,4 +1,19 @@ # -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + # Generated by the protocol buffer compiler. DO NOT EDIT! # source: singer.proto """Generated protocol buffer code.""" diff --git a/packages/google-cloud-network-services/google/cloud/network_services/__init__.py b/packages/google-cloud-network-services/google/cloud/network_services/__init__.py index 2415456ba13a..7bec0680d7e7 100644 --- a/packages/google-cloud-network-services/google/cloud/network_services/__init__.py +++ b/packages/google-cloud-network-services/google/cloud/network_services/__init__.py @@ -30,6 +30,15 @@ from google.cloud.network_services_v1.services.network_services.client import ( NetworkServicesClient, ) +from google.cloud.network_services_v1.types.agent_gateway import ( + AgentGateway, + CreateAgentGatewayRequest, + DeleteAgentGatewayRequest, + GetAgentGatewayRequest, + ListAgentGatewaysRequest, + ListAgentGatewaysResponse, + UpdateAgentGatewayRequest, +) from google.cloud.network_services_v1.types.common import ( EndpointMatcher, EnvoyHeaders, @@ -38,6 +47,7 @@ ) from google.cloud.network_services_v1.types.dep import ( AuthzExtension, + BodySendMode, CreateAuthzExtensionRequest, CreateLbEdgeExtensionRequest, CreateLbRouteExtensionRequest, @@ -183,6 +193,13 @@ "DepServiceAsyncClient", "NetworkServicesClient", "NetworkServicesAsyncClient", + "AgentGateway", + "CreateAgentGatewayRequest", + "DeleteAgentGatewayRequest", + "GetAgentGatewayRequest", + "ListAgentGatewaysRequest", + "ListAgentGatewaysResponse", + "UpdateAgentGatewayRequest", "EndpointMatcher", "OperationMetadata", "TrafficPortSelector", @@ -216,6 +233,7 @@ "UpdateLbEdgeExtensionRequest", "UpdateLbRouteExtensionRequest", "UpdateLbTrafficExtensionRequest", + "BodySendMode", "EventType", "LoadBalancingScheme", "WireFormat", diff --git a/packages/google-cloud-network-services/google/cloud/network_services_v1/__init__.py b/packages/google-cloud-network-services/google/cloud/network_services_v1/__init__.py index 940453de77ee..ae423bbb90b7 100644 --- a/packages/google-cloud-network-services/google/cloud/network_services_v1/__init__.py +++ b/packages/google-cloud-network-services/google/cloud/network_services_v1/__init__.py @@ -25,6 +25,15 @@ from .services.dep_service import DepServiceAsyncClient, DepServiceClient from .services.network_services import NetworkServicesAsyncClient, NetworkServicesClient +from .types.agent_gateway import ( + AgentGateway, + CreateAgentGatewayRequest, + DeleteAgentGatewayRequest, + GetAgentGatewayRequest, + ListAgentGatewaysRequest, + ListAgentGatewaysResponse, + UpdateAgentGatewayRequest, +) from .types.common import ( EndpointMatcher, EnvoyHeaders, @@ -33,6 +42,7 @@ ) from .types.dep import ( AuthzExtension, + BodySendMode, CreateAuthzExtensionRequest, CreateLbEdgeExtensionRequest, CreateLbRouteExtensionRequest, @@ -259,7 +269,10 @@ def _get_version(dependency_name): __all__ = ( "DepServiceAsyncClient", "NetworkServicesAsyncClient", + "AgentGateway", "AuthzExtension", + "BodySendMode", + "CreateAgentGatewayRequest", "CreateAuthzExtensionRequest", "CreateEndpointPolicyRequest", "CreateGatewayRequest", @@ -275,6 +288,7 @@ def _get_version(dependency_name): "CreateTlsRouteRequest", "CreateWasmPluginRequest", "CreateWasmPluginVersionRequest", + "DeleteAgentGatewayRequest", "DeleteAuthzExtensionRequest", "DeleteEndpointPolicyRequest", "DeleteGatewayRequest", @@ -298,6 +312,7 @@ def _get_version(dependency_name): "ExtensionChain", "Gateway", "GatewayRouteView", + "GetAgentGatewayRequest", "GetAuthzExtensionRequest", "GetEndpointPolicyRequest", "GetGatewayRequest", @@ -320,6 +335,8 @@ def _get_version(dependency_name): "LbEdgeExtension", "LbRouteExtension", "LbTrafficExtension", + "ListAgentGatewaysRequest", + "ListAgentGatewaysResponse", "ListAuthzExtensionsRequest", "ListAuthzExtensionsResponse", "ListEndpointPoliciesRequest", @@ -364,6 +381,7 @@ def _get_version(dependency_name): "TcpRoute", "TlsRoute", "TrafficPortSelector", + "UpdateAgentGatewayRequest", "UpdateAuthzExtensionRequest", "UpdateEndpointPolicyRequest", "UpdateGatewayRequest", diff --git a/packages/google-cloud-network-services/google/cloud/network_services_v1/gapic_metadata.json b/packages/google-cloud-network-services/google/cloud/network_services_v1/gapic_metadata.json index 0a3314f7de1d..3598822b7781 100644 --- a/packages/google-cloud-network-services/google/cloud/network_services_v1/gapic_metadata.json +++ b/packages/google-cloud-network-services/google/cloud/network_services_v1/gapic_metadata.json @@ -329,6 +329,11 @@ "grpc": { "libraryClient": "NetworkServicesClient", "rpcs": { + "CreateAgentGateway": { + "methods": [ + "create_agent_gateway" + ] + }, "CreateEndpointPolicy": { "methods": [ "create_endpoint_policy" @@ -384,6 +389,11 @@ "create_wasm_plugin_version" ] }, + "DeleteAgentGateway": { + "methods": [ + "delete_agent_gateway" + ] + }, "DeleteEndpointPolicy": { "methods": [ "delete_endpoint_policy" @@ -439,6 +449,11 @@ "delete_wasm_plugin_version" ] }, + "GetAgentGateway": { + "methods": [ + "get_agent_gateway" + ] + }, "GetEndpointPolicy": { "methods": [ "get_endpoint_policy" @@ -504,6 +519,11 @@ "get_wasm_plugin_version" ] }, + "ListAgentGateways": { + "methods": [ + "list_agent_gateways" + ] + }, "ListEndpointPolicies": { "methods": [ "list_endpoint_policies" @@ -569,6 +589,11 @@ "list_wasm_plugins" ] }, + "UpdateAgentGateway": { + "methods": [ + "update_agent_gateway" + ] + }, "UpdateEndpointPolicy": { "methods": [ "update_endpoint_policy" @@ -624,6 +649,11 @@ "grpc-async": { "libraryClient": "NetworkServicesAsyncClient", "rpcs": { + "CreateAgentGateway": { + "methods": [ + "create_agent_gateway" + ] + }, "CreateEndpointPolicy": { "methods": [ "create_endpoint_policy" @@ -679,6 +709,11 @@ "create_wasm_plugin_version" ] }, + "DeleteAgentGateway": { + "methods": [ + "delete_agent_gateway" + ] + }, "DeleteEndpointPolicy": { "methods": [ "delete_endpoint_policy" @@ -734,6 +769,11 @@ "delete_wasm_plugin_version" ] }, + "GetAgentGateway": { + "methods": [ + "get_agent_gateway" + ] + }, "GetEndpointPolicy": { "methods": [ "get_endpoint_policy" @@ -799,6 +839,11 @@ "get_wasm_plugin_version" ] }, + "ListAgentGateways": { + "methods": [ + "list_agent_gateways" + ] + }, "ListEndpointPolicies": { "methods": [ "list_endpoint_policies" @@ -864,6 +909,11 @@ "list_wasm_plugins" ] }, + "UpdateAgentGateway": { + "methods": [ + "update_agent_gateway" + ] + }, "UpdateEndpointPolicy": { "methods": [ "update_endpoint_policy" @@ -919,6 +969,11 @@ "rest": { "libraryClient": "NetworkServicesClient", "rpcs": { + "CreateAgentGateway": { + "methods": [ + "create_agent_gateway" + ] + }, "CreateEndpointPolicy": { "methods": [ "create_endpoint_policy" @@ -974,6 +1029,11 @@ "create_wasm_plugin_version" ] }, + "DeleteAgentGateway": { + "methods": [ + "delete_agent_gateway" + ] + }, "DeleteEndpointPolicy": { "methods": [ "delete_endpoint_policy" @@ -1029,6 +1089,11 @@ "delete_wasm_plugin_version" ] }, + "GetAgentGateway": { + "methods": [ + "get_agent_gateway" + ] + }, "GetEndpointPolicy": { "methods": [ "get_endpoint_policy" @@ -1094,6 +1159,11 @@ "get_wasm_plugin_version" ] }, + "ListAgentGateways": { + "methods": [ + "list_agent_gateways" + ] + }, "ListEndpointPolicies": { "methods": [ "list_endpoint_policies" @@ -1159,6 +1229,11 @@ "list_wasm_plugins" ] }, + "UpdateAgentGateway": { + "methods": [ + "update_agent_gateway" + ] + }, "UpdateEndpointPolicy": { "methods": [ "update_endpoint_policy" diff --git a/packages/google-cloud-network-services/google/cloud/network_services_v1/services/dep_service/async_client.py b/packages/google-cloud-network-services/google/cloud/network_services_v1/services/dep_service/async_client.py index 6abe445a7417..26494e7670b0 100644 --- a/packages/google-cloud-network-services/google/cloud/network_services_v1/services/dep_service/async_client.py +++ b/packages/google-cloud-network-services/google/cloud/network_services_v1/services/dep_service/async_client.py @@ -592,7 +592,6 @@ async def sample_create_lb_traffic_extension(): lb_traffic_extension.name = "name_value" lb_traffic_extension.extension_chains.name = "name_value" lb_traffic_extension.extension_chains.match_condition.cel_expression = "cel_expression_value" - lb_traffic_extension.extension_chains.extensions.name = "name_value" lb_traffic_extension.extension_chains.extensions.service = "service_value" lb_traffic_extension.load_balancing_scheme = "EXTERNAL_MANAGED" @@ -748,7 +747,6 @@ async def sample_update_lb_traffic_extension(): lb_traffic_extension.name = "name_value" lb_traffic_extension.extension_chains.name = "name_value" lb_traffic_extension.extension_chains.match_condition.cel_expression = "cel_expression_value" - lb_traffic_extension.extension_chains.extensions.name = "name_value" lb_traffic_extension.extension_chains.extensions.service = "service_value" lb_traffic_extension.load_balancing_scheme = "EXTERNAL_MANAGED" @@ -1273,7 +1271,6 @@ async def sample_create_lb_route_extension(): lb_route_extension.forwarding_rules = ['forwarding_rules_value1', 'forwarding_rules_value2'] lb_route_extension.extension_chains.name = "name_value" lb_route_extension.extension_chains.match_condition.cel_expression = "cel_expression_value" - lb_route_extension.extension_chains.extensions.name = "name_value" lb_route_extension.extension_chains.extensions.service = "service_value" lb_route_extension.load_balancing_scheme = "EXTERNAL_MANAGED" @@ -1427,7 +1424,6 @@ async def sample_update_lb_route_extension(): lb_route_extension.forwarding_rules = ['forwarding_rules_value1', 'forwarding_rules_value2'] lb_route_extension.extension_chains.name = "name_value" lb_route_extension.extension_chains.match_condition.cel_expression = "cel_expression_value" - lb_route_extension.extension_chains.extensions.name = "name_value" lb_route_extension.extension_chains.extensions.service = "service_value" lb_route_extension.load_balancing_scheme = "EXTERNAL_MANAGED" @@ -1950,7 +1946,6 @@ async def sample_create_lb_edge_extension(): lb_edge_extension.forwarding_rules = ['forwarding_rules_value1', 'forwarding_rules_value2'] lb_edge_extension.extension_chains.name = "name_value" lb_edge_extension.extension_chains.match_condition.cel_expression = "cel_expression_value" - lb_edge_extension.extension_chains.extensions.name = "name_value" lb_edge_extension.extension_chains.extensions.service = "service_value" lb_edge_extension.load_balancing_scheme = "EXTERNAL_MANAGED" @@ -2105,7 +2100,6 @@ async def sample_update_lb_edge_extension(): lb_edge_extension.forwarding_rules = ['forwarding_rules_value1', 'forwarding_rules_value2'] lb_edge_extension.extension_chains.name = "name_value" lb_edge_extension.extension_chains.match_condition.cel_expression = "cel_expression_value" - lb_edge_extension.extension_chains.extensions.name = "name_value" lb_edge_extension.extension_chains.extensions.service = "service_value" lb_edge_extension.load_balancing_scheme = "EXTERNAL_MANAGED" @@ -2626,8 +2620,6 @@ async def sample_create_authz_extension(): # Initialize request argument(s) authz_extension = network_services_v1.AuthzExtension() authz_extension.name = "name_value" - authz_extension.load_balancing_scheme = "EXTERNAL_MANAGED" - authz_extension.authority = "authority_value" authz_extension.service = "service_value" request = network_services_v1.CreateAuthzExtensionRequest( @@ -2778,8 +2770,6 @@ async def sample_update_authz_extension(): # Initialize request argument(s) authz_extension = network_services_v1.AuthzExtension() authz_extension.name = "name_value" - authz_extension.load_balancing_scheme = "EXTERNAL_MANAGED" - authz_extension.authority = "authority_value" authz_extension.service = "service_value" request = network_services_v1.UpdateAuthzExtensionRequest( diff --git a/packages/google-cloud-network-services/google/cloud/network_services_v1/services/dep_service/client.py b/packages/google-cloud-network-services/google/cloud/network_services_v1/services/dep_service/client.py index 4afdfdb26c2b..79b465d8dcb0 100644 --- a/packages/google-cloud-network-services/google/cloud/network_services_v1/services/dep_service/client.py +++ b/packages/google-cloud-network-services/google/cloud/network_services_v1/services/dep_service/client.py @@ -1077,7 +1077,6 @@ def sample_create_lb_traffic_extension(): lb_traffic_extension.name = "name_value" lb_traffic_extension.extension_chains.name = "name_value" lb_traffic_extension.extension_chains.match_condition.cel_expression = "cel_expression_value" - lb_traffic_extension.extension_chains.extensions.name = "name_value" lb_traffic_extension.extension_chains.extensions.service = "service_value" lb_traffic_extension.load_balancing_scheme = "EXTERNAL_MANAGED" @@ -1232,7 +1231,6 @@ def sample_update_lb_traffic_extension(): lb_traffic_extension.name = "name_value" lb_traffic_extension.extension_chains.name = "name_value" lb_traffic_extension.extension_chains.match_condition.cel_expression = "cel_expression_value" - lb_traffic_extension.extension_chains.extensions.name = "name_value" lb_traffic_extension.extension_chains.extensions.service = "service_value" lb_traffic_extension.load_balancing_scheme = "EXTERNAL_MANAGED" @@ -1749,7 +1747,6 @@ def sample_create_lb_route_extension(): lb_route_extension.forwarding_rules = ['forwarding_rules_value1', 'forwarding_rules_value2'] lb_route_extension.extension_chains.name = "name_value" lb_route_extension.extension_chains.match_condition.cel_expression = "cel_expression_value" - lb_route_extension.extension_chains.extensions.name = "name_value" lb_route_extension.extension_chains.extensions.service = "service_value" lb_route_extension.load_balancing_scheme = "EXTERNAL_MANAGED" @@ -1902,7 +1899,6 @@ def sample_update_lb_route_extension(): lb_route_extension.forwarding_rules = ['forwarding_rules_value1', 'forwarding_rules_value2'] lb_route_extension.extension_chains.name = "name_value" lb_route_extension.extension_chains.match_condition.cel_expression = "cel_expression_value" - lb_route_extension.extension_chains.extensions.name = "name_value" lb_route_extension.extension_chains.extensions.service = "service_value" lb_route_extension.load_balancing_scheme = "EXTERNAL_MANAGED" @@ -2417,7 +2413,6 @@ def sample_create_lb_edge_extension(): lb_edge_extension.forwarding_rules = ['forwarding_rules_value1', 'forwarding_rules_value2'] lb_edge_extension.extension_chains.name = "name_value" lb_edge_extension.extension_chains.match_condition.cel_expression = "cel_expression_value" - lb_edge_extension.extension_chains.extensions.name = "name_value" lb_edge_extension.extension_chains.extensions.service = "service_value" lb_edge_extension.load_balancing_scheme = "EXTERNAL_MANAGED" @@ -2569,7 +2564,6 @@ def sample_update_lb_edge_extension(): lb_edge_extension.forwarding_rules = ['forwarding_rules_value1', 'forwarding_rules_value2'] lb_edge_extension.extension_chains.name = "name_value" lb_edge_extension.extension_chains.match_condition.cel_expression = "cel_expression_value" - lb_edge_extension.extension_chains.extensions.name = "name_value" lb_edge_extension.extension_chains.extensions.service = "service_value" lb_edge_extension.load_balancing_scheme = "EXTERNAL_MANAGED" @@ -3078,8 +3072,6 @@ def sample_create_authz_extension(): # Initialize request argument(s) authz_extension = network_services_v1.AuthzExtension() authz_extension.name = "name_value" - authz_extension.load_balancing_scheme = "EXTERNAL_MANAGED" - authz_extension.authority = "authority_value" authz_extension.service = "service_value" request = network_services_v1.CreateAuthzExtensionRequest( @@ -3227,8 +3219,6 @@ def sample_update_authz_extension(): # Initialize request argument(s) authz_extension = network_services_v1.AuthzExtension() authz_extension.name = "name_value" - authz_extension.load_balancing_scheme = "EXTERNAL_MANAGED" - authz_extension.authority = "authority_value" authz_extension.service = "service_value" request = network_services_v1.UpdateAuthzExtensionRequest( diff --git a/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/async_client.py b/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/async_client.py index 5e4f2cfec052..a55133f57f90 100644 --- a/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/async_client.py +++ b/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/async_client.py @@ -58,6 +58,7 @@ from google.cloud.network_services_v1.services.network_services import pagers from google.cloud.network_services_v1.types import ( + agent_gateway, common, endpoint_policy, extensibility, @@ -71,6 +72,7 @@ tcp_route, tls_route, ) +from google.cloud.network_services_v1.types import agent_gateway as gcn_agent_gateway from google.cloud.network_services_v1.types import ( endpoint_policy as gcn_endpoint_policy, ) @@ -115,6 +117,10 @@ class NetworkServicesAsyncClient: address_path = staticmethod(NetworkServicesClient.address_path) parse_address_path = staticmethod(NetworkServicesClient.parse_address_path) + agent_gateway_path = staticmethod(NetworkServicesClient.agent_gateway_path) + parse_agent_gateway_path = staticmethod( + NetworkServicesClient.parse_agent_gateway_path + ) authorization_policy_path = staticmethod( NetworkServicesClient.authorization_policy_path ) @@ -177,6 +183,10 @@ class NetworkServicesAsyncClient: ) subnetwork_path = staticmethod(NetworkServicesClient.subnetwork_path) parse_subnetwork_path = staticmethod(NetworkServicesClient.parse_subnetwork_path) + target_tcp_proxy_path = staticmethod(NetworkServicesClient.target_tcp_proxy_path) + parse_target_tcp_proxy_path = staticmethod( + NetworkServicesClient.parse_target_tcp_proxy_path + ) tcp_route_path = staticmethod(NetworkServicesClient.tcp_route_path) parse_tcp_route_path = staticmethod(NetworkServicesClient.parse_tcp_route_path) tls_route_path = staticmethod(NetworkServicesClient.tls_route_path) @@ -457,7 +467,7 @@ async def sample_list_endpoint_policies(): parent (:class:`str`): Required. The project and location from which the EndpointPolicies should be listed, specified in the - format ``projects/*/locations/global``. + format ``projects/*/locations/*``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -583,7 +593,7 @@ async def sample_get_endpoint_policy(): name (:class:`str`): Required. A name of the EndpointPolicy to get. Must be in the format - ``projects/*/locations/global/endpointPolicies/*``. + ``projects/*/locations/*/endpointPolicies/*``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -712,7 +722,7 @@ async def sample_create_endpoint_policy(): CreateEndpointPolicy method. parent (:class:`str`): Required. The parent resource of the EndpointPolicy. - Must be in the format ``projects/*/locations/global``. + Must be in the format ``projects/*/locations/*``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -1012,7 +1022,7 @@ async def sample_delete_endpoint_policy(): name (:class:`str`): Required. A name of the EndpointPolicy to delete. Must be in the format - ``projects/*/locations/global/endpointPolicies/*``. + ``projects/*/locations/*/endpointPolicies/*``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -3008,7 +3018,7 @@ async def sample_list_grpc_routes(): parent (:class:`str`): Required. The project and location from which the GrpcRoutes should be listed, specified in the format - ``projects/*/locations/global``. + ``projects/*/locations/*``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -3133,7 +3143,7 @@ async def sample_get_grpc_route(): method. name (:class:`str`): Required. A name of the GrpcRoute to get. Must be in the - format ``projects/*/locations/global/grpcRoutes/*``. + format ``projects/*/locations/*/grpcRoutes/*``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -3257,7 +3267,7 @@ async def sample_create_grpc_route(): method. parent (:class:`str`): Required. The parent resource of the GrpcRoute. Must be - in the format ``projects/*/locations/global``. + in the format ``projects/*/locations/*``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -3542,7 +3552,7 @@ async def sample_delete_grpc_route(): method. name (:class:`str`): Required. A name of the GrpcRoute to delete. Must be in - the format ``projects/*/locations/global/grpcRoutes/*``. + the format ``projects/*/locations/*/grpcRoutes/*``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -3673,7 +3683,7 @@ async def sample_list_http_routes(): parent (:class:`str`): Required. The project and location from which the HttpRoutes should be listed, specified in the format - ``projects/*/locations/global``. + ``projects/*/locations/*``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -3798,7 +3808,7 @@ async def sample_get_http_route(): method. name (:class:`str`): Required. A name of the HttpRoute to get. Must be in the - format ``projects/*/locations/global/httpRoutes/*``. + format ``projects/*/locations/*/httpRoutes/*``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -3921,7 +3931,7 @@ async def sample_create_http_route(): The request object. Request used by the HttpRoute method. parent (:class:`str`): Required. The parent resource of the HttpRoute. Must be - in the format ``projects/*/locations/global``. + in the format ``projects/*/locations/*``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -4206,7 +4216,7 @@ async def sample_delete_http_route(): method. name (:class:`str`): Required. A name of the HttpRoute to delete. Must be in - the format ``projects/*/locations/global/httpRoutes/*``. + the format ``projects/*/locations/*/httpRoutes/*``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -4337,7 +4347,7 @@ async def sample_list_tcp_routes(): parent (:class:`str`): Required. The project and location from which the TcpRoutes should be listed, specified in the format - ``projects/*/locations/global``. + ``projects/*/locations/*``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -4462,7 +4472,7 @@ async def sample_get_tcp_route(): method. name (:class:`str`): Required. A name of the TcpRoute to get. Must be in the - format ``projects/*/locations/global/tcpRoutes/*``. + format ``projects/*/locations/*/tcpRoutes/*``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -4581,7 +4591,7 @@ async def sample_create_tcp_route(): The request object. Request used by the TcpRoute method. parent (:class:`str`): Required. The parent resource of the TcpRoute. Must be - in the format ``projects/*/locations/global``. + in the format ``projects/*/locations/*``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -4862,7 +4872,7 @@ async def sample_delete_tcp_route(): method. name (:class:`str`): Required. A name of the TcpRoute to delete. Must be in - the format ``projects/*/locations/global/tcpRoutes/*``. + the format ``projects/*/locations/*/tcpRoutes/*``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -4993,7 +5003,7 @@ async def sample_list_tls_routes(): parent (:class:`str`): Required. The project and location from which the TlsRoutes should be listed, specified in the format - ``projects/*/locations/global``. + ``projects/*/locations/*``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -5118,7 +5128,7 @@ async def sample_get_tls_route(): method. name (:class:`str`): Required. A name of the TlsRoute to get. Must be in the - format ``projects/*/locations/global/tlsRoutes/*``. + format ``projects/*/locations/*/tlsRoutes/*``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -5241,7 +5251,7 @@ async def sample_create_tls_route(): The request object. Request used by the TlsRoute method. parent (:class:`str`): Required. The parent resource of the TlsRoute. Must be - in the format ``projects/*/locations/global``. + in the format ``projects/*/locations/*``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -5526,7 +5536,7 @@ async def sample_delete_tls_route(): method. name (:class:`str`): Required. A name of the TlsRoute to delete. Must be in - the format ``projects/*/locations/global/tlsRoutes/*``. + the format ``projects/*/locations/*/tlsRoutes/*``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -6350,7 +6360,7 @@ async def sample_list_meshes(): parent (:class:`str`): Required. The project and location from which the Meshes should be listed, specified in the format - ``projects/*/locations/global``. + ``projects/*/locations/*``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -6474,7 +6484,7 @@ async def sample_get_mesh(): The request object. Request used by the GetMesh method. name (:class:`str`): Required. A name of the Mesh to get. Must be in the - format ``projects/*/locations/global/meshes/*``. + format ``projects/*/locations/*/meshes/*``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -6594,7 +6604,7 @@ async def sample_create_mesh(): method. parent (:class:`str`): Required. The parent resource of the Mesh. Must be in - the format ``projects/*/locations/global``. + the format ``projects/*/locations/*``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -6879,7 +6889,7 @@ async def sample_delete_mesh(): method. name (:class:`str`): Required. A name of the Mesh to delete. Must be in the - format ``projects/*/locations/global/meshes/*``. + format ``projects/*/locations/*/meshes/*``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -8123,6 +8133,671 @@ async def sample_list_mesh_route_views(): # Done; return the response. return response + async def list_agent_gateways( + self, + request: Optional[Union[agent_gateway.ListAgentGatewaysRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListAgentGatewaysAsyncPager: + r"""Lists AgentGateways in a given project and location. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import network_services_v1 + + async def sample_list_agent_gateways(): + # Create a client + client = network_services_v1.NetworkServicesAsyncClient() + + # Initialize request argument(s) + request = network_services_v1.ListAgentGatewaysRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_agent_gateways(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.network_services_v1.types.ListAgentGatewaysRequest, dict]]): + The request object. Request used with the + ListAgentGateways method. + parent (:class:`str`): + Required. The project and location from which the + AgentGateways should be listed, specified in the format + ``projects/*/locations/*``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.network_services_v1.services.network_services.pagers.ListAgentGatewaysAsyncPager: + Response returned by the + ListAgentGateways method. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, agent_gateway.ListAgentGatewaysRequest): + request = agent_gateway.ListAgentGatewaysRequest(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._client._transport._wrapped_methods[ + self._client._transport.list_agent_gateways + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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.ListAgentGatewaysAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_agent_gateway( + self, + request: Optional[Union[agent_gateway.GetAgentGatewayRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> agent_gateway.AgentGateway: + r"""Gets details of a single AgentGateway. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import network_services_v1 + + async def sample_get_agent_gateway(): + # Create a client + client = network_services_v1.NetworkServicesAsyncClient() + + # Initialize request argument(s) + request = network_services_v1.GetAgentGatewayRequest( + name="name_value", + ) + + # Make the request + response = await client.get_agent_gateway(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.network_services_v1.types.GetAgentGatewayRequest, dict]]): + The request object. Request used by the GetAgentGateway + method. + name (:class:`str`): + Required. A name of the AgentGateway to get. Must be in + the format ``projects/*/locations/*/agentGateways/*``. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.network_services_v1.types.AgentGateway: + AgentGateway represents the agent + gateway resource. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, agent_gateway.GetAgentGatewayRequest): + request = agent_gateway.GetAgentGatewayRequest(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._client._transport._wrapped_methods[ + self._client._transport.get_agent_gateway + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def create_agent_gateway( + self, + request: Optional[ + Union[gcn_agent_gateway.CreateAgentGatewayRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + agent_gateway: Optional[gcn_agent_gateway.AgentGateway] = None, + agent_gateway_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""Creates a new AgentGateway in a given project and + location. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import network_services_v1 + + async def sample_create_agent_gateway(): + # Create a client + client = network_services_v1.NetworkServicesAsyncClient() + + # Initialize request argument(s) + request = network_services_v1.CreateAgentGatewayRequest( + parent="parent_value", + agent_gateway_id="agent_gateway_id_value", + ) + + # Make the request + operation = await client.create_agent_gateway(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.network_services_v1.types.CreateAgentGatewayRequest, dict]]): + The request object. Request used by the + CreateAgentGateway method. + parent (:class:`str`): + Required. The parent resource of the AgentGateway. Must + be in the format ``projects/*/locations/*``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + agent_gateway (:class:`google.cloud.network_services_v1.types.AgentGateway`): + Required. AgentGateway resource to be + created. + + This corresponds to the ``agent_gateway`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + agent_gateway_id (:class:`str`): + Required. Short name of the + AgentGateway resource to be created. + + This corresponds to the ``agent_gateway_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + 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.network_services_v1.types.AgentGateway` + AgentGateway represents the agent gateway resource. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, agent_gateway, agent_gateway_id] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, gcn_agent_gateway.CreateAgentGatewayRequest): + request = gcn_agent_gateway.CreateAgentGatewayRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if agent_gateway is not None: + request.agent_gateway = agent_gateway + if agent_gateway_id is not None: + request.agent_gateway_id = agent_gateway_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.create_agent_gateway + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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, + gcn_agent_gateway.AgentGateway, + metadata_type=common.OperationMetadata, + ) + + # Done; return the response. + return response + + async def update_agent_gateway( + self, + request: Optional[ + Union[gcn_agent_gateway.UpdateAgentGatewayRequest, dict] + ] = None, + *, + agent_gateway: Optional[gcn_agent_gateway.AgentGateway] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""Updates the parameters of a single AgentGateway. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import network_services_v1 + + async def sample_update_agent_gateway(): + # Create a client + client = network_services_v1.NetworkServicesAsyncClient() + + # Initialize request argument(s) + request = network_services_v1.UpdateAgentGatewayRequest( + ) + + # Make the request + operation = await client.update_agent_gateway(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.network_services_v1.types.UpdateAgentGatewayRequest, dict]]): + The request object. Request used by the + UpdateAgentGateway method. + agent_gateway (:class:`google.cloud.network_services_v1.types.AgentGateway`): + Required. Updated AgentGateway + resource. + + This corresponds to the ``agent_gateway`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Optional. Field mask is used to specify the fields to be + overwritten in the AgentGateway resource by the update. + The fields specified in the update_mask are relative to + the resource, not the full request. A field will be + overwritten if it is in the mask. If the user does not + provide a mask then all fields will be overwritten. + + 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_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + 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.network_services_v1.types.AgentGateway` + AgentGateway represents the agent gateway resource. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [agent_gateway, update_mask] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, gcn_agent_gateway.UpdateAgentGatewayRequest): + request = gcn_agent_gateway.UpdateAgentGatewayRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if agent_gateway is not None: + request.agent_gateway = agent_gateway + 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._client._transport._wrapped_methods[ + self._client._transport.update_agent_gateway + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("agent_gateway.name", request.agent_gateway.name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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, + gcn_agent_gateway.AgentGateway, + metadata_type=common.OperationMetadata, + ) + + # Done; return the response. + return response + + async def delete_agent_gateway( + self, + request: Optional[Union[agent_gateway.DeleteAgentGatewayRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""Deletes a single AgentGateway. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import network_services_v1 + + async def sample_delete_agent_gateway(): + # Create a client + client = network_services_v1.NetworkServicesAsyncClient() + + # Initialize request argument(s) + request = network_services_v1.DeleteAgentGatewayRequest( + name="name_value", + ) + + # Make the request + operation = await client.delete_agent_gateway(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.network_services_v1.types.DeleteAgentGatewayRequest, dict]]): + The request object. Request used by the + DeleteAgentGateway method. + name (:class:`str`): + Required. A name of the AgentGateway to delete. Must be + in the format + ``projects/*/locations/*/agentGateways/*``. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, agent_gateway.DeleteAgentGatewayRequest): + request = agent_gateway.DeleteAgentGatewayRequest(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._client._transport._wrapped_methods[ + self._client._transport.delete_agent_gateway + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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, + empty_pb2.Empty, + metadata_type=common.OperationMetadata, + ) + + # Done; return the response. + return response + async def list_operations( self, request: Optional[Union[operations_pb2.ListOperationsRequest, dict]] = None, diff --git a/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/client.py b/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/client.py index 2d673965f715..b8476bd428ee 100644 --- a/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/client.py +++ b/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/client.py @@ -75,6 +75,7 @@ from google.cloud.network_services_v1.services.network_services import pagers from google.cloud.network_services_v1.types import ( + agent_gateway, common, endpoint_policy, extensibility, @@ -88,6 +89,7 @@ tcp_route, tls_route, ) +from google.cloud.network_services_v1.types import agent_gateway as gcn_agent_gateway from google.cloud.network_services_v1.types import ( endpoint_policy as gcn_endpoint_policy, ) @@ -288,6 +290,28 @@ def parse_address_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def agent_gateway_path( + project: str, + location: str, + agent_gateway: str, + ) -> str: + """Returns a fully-qualified agent_gateway string.""" + return "projects/{project}/locations/{location}/agentGateways/{agent_gateway}".format( + project=project, + location=location, + agent_gateway=agent_gateway, + ) + + @staticmethod + def parse_agent_gateway_path(path: str) -> Dict[str, str]: + """Parses a agent_gateway path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/agentGateways/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def authorization_policy_path( project: str, @@ -689,6 +713,28 @@ def parse_subnetwork_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def target_tcp_proxy_path( + project: str, + location: str, + target_tcp_proxy: str, + ) -> str: + """Returns a fully-qualified target_tcp_proxy string.""" + return "projects/{project}/locations/{location}/targetTcpProxies/{target_tcp_proxy}".format( + project=project, + location=location, + target_tcp_proxy=target_tcp_proxy, + ) + + @staticmethod + def parse_target_tcp_proxy_path(path: str) -> Dict[str, str]: + """Parses a target_tcp_proxy path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/targetTcpProxies/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def tcp_route_path( project: str, @@ -1310,7 +1356,7 @@ def sample_list_endpoint_policies(): parent (str): Required. The project and location from which the EndpointPolicies should be listed, specified in the - format ``projects/*/locations/global``. + format ``projects/*/locations/*``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -1433,7 +1479,7 @@ def sample_get_endpoint_policy(): name (str): Required. A name of the EndpointPolicy to get. Must be in the format - ``projects/*/locations/global/endpointPolicies/*``. + ``projects/*/locations/*/endpointPolicies/*``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -1559,7 +1605,7 @@ def sample_create_endpoint_policy(): CreateEndpointPolicy method. parent (str): Required. The parent resource of the EndpointPolicy. - Must be in the format ``projects/*/locations/global``. + Must be in the format ``projects/*/locations/*``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -1853,7 +1899,7 @@ def sample_delete_endpoint_policy(): name (str): Required. A name of the EndpointPolicy to delete. Must be in the format - ``projects/*/locations/global/endpointPolicies/*``. + ``projects/*/locations/*/endpointPolicies/*``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -3810,7 +3856,7 @@ def sample_list_grpc_routes(): parent (str): Required. The project and location from which the GrpcRoutes should be listed, specified in the format - ``projects/*/locations/global``. + ``projects/*/locations/*``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -3932,7 +3978,7 @@ def sample_get_grpc_route(): method. name (str): Required. A name of the GrpcRoute to get. Must be in the - format ``projects/*/locations/global/grpcRoutes/*``. + format ``projects/*/locations/*/grpcRoutes/*``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -4053,7 +4099,7 @@ def sample_create_grpc_route(): method. parent (str): Required. The parent resource of the GrpcRoute. Must be - in the format ``projects/*/locations/global``. + in the format ``projects/*/locations/*``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -4332,7 +4378,7 @@ def sample_delete_grpc_route(): method. name (str): Required. A name of the GrpcRoute to delete. Must be in - the format ``projects/*/locations/global/grpcRoutes/*``. + the format ``projects/*/locations/*/grpcRoutes/*``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -4460,7 +4506,7 @@ def sample_list_http_routes(): parent (str): Required. The project and location from which the HttpRoutes should be listed, specified in the format - ``projects/*/locations/global``. + ``projects/*/locations/*``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -4582,7 +4628,7 @@ def sample_get_http_route(): method. name (str): Required. A name of the HttpRoute to get. Must be in the - format ``projects/*/locations/global/httpRoutes/*``. + format ``projects/*/locations/*/httpRoutes/*``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -4702,7 +4748,7 @@ def sample_create_http_route(): The request object. Request used by the HttpRoute method. parent (str): Required. The parent resource of the HttpRoute. Must be - in the format ``projects/*/locations/global``. + in the format ``projects/*/locations/*``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -4981,7 +5027,7 @@ def sample_delete_http_route(): method. name (str): Required. A name of the HttpRoute to delete. Must be in - the format ``projects/*/locations/global/httpRoutes/*``. + the format ``projects/*/locations/*/httpRoutes/*``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -5109,7 +5155,7 @@ def sample_list_tcp_routes(): parent (str): Required. The project and location from which the TcpRoutes should be listed, specified in the format - ``projects/*/locations/global``. + ``projects/*/locations/*``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -5231,7 +5277,7 @@ def sample_get_tcp_route(): method. name (str): Required. A name of the TcpRoute to get. Must be in the - format ``projects/*/locations/global/tcpRoutes/*``. + format ``projects/*/locations/*/tcpRoutes/*``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -5347,7 +5393,7 @@ def sample_create_tcp_route(): The request object. Request used by the TcpRoute method. parent (str): Required. The parent resource of the TcpRoute. Must be - in the format ``projects/*/locations/global``. + in the format ``projects/*/locations/*``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -5622,7 +5668,7 @@ def sample_delete_tcp_route(): method. name (str): Required. A name of the TcpRoute to delete. Must be in - the format ``projects/*/locations/global/tcpRoutes/*``. + the format ``projects/*/locations/*/tcpRoutes/*``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -5750,7 +5796,7 @@ def sample_list_tls_routes(): parent (str): Required. The project and location from which the TlsRoutes should be listed, specified in the format - ``projects/*/locations/global``. + ``projects/*/locations/*``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -5872,7 +5918,7 @@ def sample_get_tls_route(): method. name (str): Required. A name of the TlsRoute to get. Must be in the - format ``projects/*/locations/global/tlsRoutes/*``. + format ``projects/*/locations/*/tlsRoutes/*``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -5992,7 +6038,7 @@ def sample_create_tls_route(): The request object. Request used by the TlsRoute method. parent (str): Required. The parent resource of the TlsRoute. Must be - in the format ``projects/*/locations/global``. + in the format ``projects/*/locations/*``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -6271,7 +6317,7 @@ def sample_delete_tls_route(): method. name (str): Required. A name of the TlsRoute to delete. Must be in - the format ``projects/*/locations/global/tlsRoutes/*``. + the format ``projects/*/locations/*/tlsRoutes/*``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -7077,7 +7123,7 @@ def sample_list_meshes(): parent (str): Required. The project and location from which the Meshes should be listed, specified in the format - ``projects/*/locations/global``. + ``projects/*/locations/*``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -7198,7 +7244,7 @@ def sample_get_mesh(): The request object. Request used by the GetMesh method. name (str): Required. A name of the Mesh to get. Must be in the - format ``projects/*/locations/global/meshes/*``. + format ``projects/*/locations/*/meshes/*``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -7317,7 +7363,7 @@ def sample_create_mesh(): method. parent (str): Required. The parent resource of the Mesh. Must be in - the format ``projects/*/locations/global``. + the format ``projects/*/locations/*``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -7596,7 +7642,7 @@ def sample_delete_mesh(): method. name (str): Required. A name of the Mesh to delete. Must be in the - format ``projects/*/locations/global/meshes/*``. + format ``projects/*/locations/*/meshes/*``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -8810,6 +8856,656 @@ def sample_list_mesh_route_views(): # Done; return the response. return response + def list_agent_gateways( + self, + request: Optional[Union[agent_gateway.ListAgentGatewaysRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListAgentGatewaysPager: + r"""Lists AgentGateways in a given project and location. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import network_services_v1 + + def sample_list_agent_gateways(): + # Create a client + client = network_services_v1.NetworkServicesClient() + + # Initialize request argument(s) + request = network_services_v1.ListAgentGatewaysRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_agent_gateways(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.network_services_v1.types.ListAgentGatewaysRequest, dict]): + The request object. Request used with the + ListAgentGateways method. + parent (str): + Required. The project and location from which the + AgentGateways should be listed, specified in the format + ``projects/*/locations/*``. + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.network_services_v1.services.network_services.pagers.ListAgentGatewaysPager: + Response returned by the + ListAgentGateways method. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, agent_gateway.ListAgentGatewaysRequest): + request = agent_gateway.ListAgentGatewaysRequest(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_agent_gateways] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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.ListAgentGatewaysPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_agent_gateway( + self, + request: Optional[Union[agent_gateway.GetAgentGatewayRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> agent_gateway.AgentGateway: + r"""Gets details of a single AgentGateway. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import network_services_v1 + + def sample_get_agent_gateway(): + # Create a client + client = network_services_v1.NetworkServicesClient() + + # Initialize request argument(s) + request = network_services_v1.GetAgentGatewayRequest( + name="name_value", + ) + + # Make the request + response = client.get_agent_gateway(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.network_services_v1.types.GetAgentGatewayRequest, dict]): + The request object. Request used by the GetAgentGateway + method. + name (str): + Required. A name of the AgentGateway to get. Must be in + the format ``projects/*/locations/*/agentGateways/*``. + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.network_services_v1.types.AgentGateway: + AgentGateway represents the agent + gateway resource. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, agent_gateway.GetAgentGatewayRequest): + request = agent_gateway.GetAgentGatewayRequest(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_agent_gateway] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def create_agent_gateway( + self, + request: Optional[ + Union[gcn_agent_gateway.CreateAgentGatewayRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + agent_gateway: Optional[gcn_agent_gateway.AgentGateway] = None, + agent_gateway_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Creates a new AgentGateway in a given project and + location. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import network_services_v1 + + def sample_create_agent_gateway(): + # Create a client + client = network_services_v1.NetworkServicesClient() + + # Initialize request argument(s) + request = network_services_v1.CreateAgentGatewayRequest( + parent="parent_value", + agent_gateway_id="agent_gateway_id_value", + ) + + # Make the request + operation = client.create_agent_gateway(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.network_services_v1.types.CreateAgentGatewayRequest, dict]): + The request object. Request used by the + CreateAgentGateway method. + parent (str): + Required. The parent resource of the AgentGateway. Must + be in the format ``projects/*/locations/*``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + agent_gateway (google.cloud.network_services_v1.types.AgentGateway): + Required. AgentGateway resource to be + created. + + This corresponds to the ``agent_gateway`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + agent_gateway_id (str): + Required. Short name of the + AgentGateway resource to be created. + + This corresponds to the ``agent_gateway_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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.network_services_v1.types.AgentGateway` + AgentGateway represents the agent gateway resource. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, agent_gateway, agent_gateway_id] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, gcn_agent_gateway.CreateAgentGatewayRequest): + request = gcn_agent_gateway.CreateAgentGatewayRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if agent_gateway is not None: + request.agent_gateway = agent_gateway + if agent_gateway_id is not None: + request.agent_gateway_id = agent_gateway_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_agent_gateway] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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, + gcn_agent_gateway.AgentGateway, + metadata_type=common.OperationMetadata, + ) + + # Done; return the response. + return response + + def update_agent_gateway( + self, + request: Optional[ + Union[gcn_agent_gateway.UpdateAgentGatewayRequest, dict] + ] = None, + *, + agent_gateway: Optional[gcn_agent_gateway.AgentGateway] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Updates the parameters of a single AgentGateway. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import network_services_v1 + + def sample_update_agent_gateway(): + # Create a client + client = network_services_v1.NetworkServicesClient() + + # Initialize request argument(s) + request = network_services_v1.UpdateAgentGatewayRequest( + ) + + # Make the request + operation = client.update_agent_gateway(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.network_services_v1.types.UpdateAgentGatewayRequest, dict]): + The request object. Request used by the + UpdateAgentGateway method. + agent_gateway (google.cloud.network_services_v1.types.AgentGateway): + Required. Updated AgentGateway + resource. + + This corresponds to the ``agent_gateway`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Optional. Field mask is used to specify the fields to be + overwritten in the AgentGateway resource by the update. + The fields specified in the update_mask are relative to + the resource, not the full request. A field will be + overwritten if it is in the mask. If the user does not + provide a mask then all fields will be overwritten. + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.network_services_v1.types.AgentGateway` + AgentGateway represents the agent gateway resource. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [agent_gateway, update_mask] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, gcn_agent_gateway.UpdateAgentGatewayRequest): + request = gcn_agent_gateway.UpdateAgentGatewayRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if agent_gateway is not None: + request.agent_gateway = agent_gateway + 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_agent_gateway] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("agent_gateway.name", request.agent_gateway.name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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, + gcn_agent_gateway.AgentGateway, + metadata_type=common.OperationMetadata, + ) + + # Done; return the response. + return response + + def delete_agent_gateway( + self, + request: Optional[Union[agent_gateway.DeleteAgentGatewayRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Deletes a single AgentGateway. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import network_services_v1 + + def sample_delete_agent_gateway(): + # Create a client + client = network_services_v1.NetworkServicesClient() + + # Initialize request argument(s) + request = network_services_v1.DeleteAgentGatewayRequest( + name="name_value", + ) + + # Make the request + operation = client.delete_agent_gateway(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.network_services_v1.types.DeleteAgentGatewayRequest, dict]): + The request object. Request used by the + DeleteAgentGateway method. + name (str): + Required. A name of the AgentGateway to delete. Must be + in the format + ``projects/*/locations/*/agentGateways/*``. + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, agent_gateway.DeleteAgentGatewayRequest): + request = agent_gateway.DeleteAgentGatewayRequest(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_agent_gateway] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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, + empty_pb2.Empty, + metadata_type=common.OperationMetadata, + ) + + # Done; return the response. + return response + def __enter__(self) -> "NetworkServicesClient": return self diff --git a/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/pagers.py b/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/pagers.py index 3af46ee8792f..1d3fa398d197 100644 --- a/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/pagers.py +++ b/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/pagers.py @@ -39,6 +39,7 @@ OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore from google.cloud.network_services_v1.types import ( + agent_gateway, endpoint_policy, extensibility, gateway, @@ -2087,3 +2088,159 @@ async def async_generator(): def __repr__(self) -> str: return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListAgentGatewaysPager: + """A pager for iterating through ``list_agent_gateways`` requests. + + This class thinly wraps an initial + :class:`google.cloud.network_services_v1.types.ListAgentGatewaysResponse` object, and + provides an ``__iter__`` method to iterate through its + ``agent_gateways`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListAgentGateways`` requests and continue to iterate + through the ``agent_gateways`` field on the + corresponding responses. + + All the usual :class:`google.cloud.network_services_v1.types.ListAgentGatewaysResponse` + 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[..., agent_gateway.ListAgentGatewaysResponse], + request: agent_gateway.ListAgentGatewaysRequest, + response: agent_gateway.ListAgentGatewaysResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.network_services_v1.types.ListAgentGatewaysRequest): + The initial request object. + response (google.cloud.network_services_v1.types.ListAgentGatewaysResponse): + The initial response object. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = agent_gateway.ListAgentGatewaysRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[agent_gateway.ListAgentGatewaysResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __iter__(self) -> Iterator[agent_gateway.AgentGateway]: + for page in self.pages: + yield from page.agent_gateways + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListAgentGatewaysAsyncPager: + """A pager for iterating through ``list_agent_gateways`` requests. + + This class thinly wraps an initial + :class:`google.cloud.network_services_v1.types.ListAgentGatewaysResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``agent_gateways`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListAgentGateways`` requests and continue to iterate + through the ``agent_gateways`` field on the + corresponding responses. + + All the usual :class:`google.cloud.network_services_v1.types.ListAgentGatewaysResponse` + 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[agent_gateway.ListAgentGatewaysResponse]], + request: agent_gateway.ListAgentGatewaysRequest, + response: agent_gateway.ListAgentGatewaysResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.network_services_v1.types.ListAgentGatewaysRequest): + The initial request object. + response (google.cloud.network_services_v1.types.ListAgentGatewaysResponse): + The initial response object. + retry (google.api_core.retry.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = agent_gateway.ListAgentGatewaysRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[agent_gateway.ListAgentGatewaysResponse]: + 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, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __aiter__(self) -> AsyncIterator[agent_gateway.AgentGateway]: + async def async_generator(): + async for page in self.pages: + for response in page.agent_gateways: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/transports/base.py b/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/transports/base.py index 816ed741c1dc..3fd452dfab0b 100644 --- a/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/transports/base.py +++ b/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/transports/base.py @@ -33,6 +33,7 @@ from google.cloud.network_services_v1 import gapic_version as package_version from google.cloud.network_services_v1.types import ( + agent_gateway, endpoint_policy, extensibility, gateway, @@ -45,6 +46,7 @@ tcp_route, tls_route, ) +from google.cloud.network_services_v1.types import agent_gateway as gcn_agent_gateway from google.cloud.network_services_v1.types import ( endpoint_policy as gcn_endpoint_policy, ) @@ -465,6 +467,31 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.list_agent_gateways: gapic_v1.method.wrap_method( + self.list_agent_gateways, + default_timeout=None, + client_info=client_info, + ), + self.get_agent_gateway: gapic_v1.method.wrap_method( + self.get_agent_gateway, + default_timeout=None, + client_info=client_info, + ), + self.create_agent_gateway: gapic_v1.method.wrap_method( + self.create_agent_gateway, + default_timeout=None, + client_info=client_info, + ), + self.update_agent_gateway: gapic_v1.method.wrap_method( + self.update_agent_gateway, + default_timeout=None, + client_info=client_info, + ), + self.delete_agent_gateway: gapic_v1.method.wrap_method( + self.delete_agent_gateway, + default_timeout=None, + client_info=client_info, + ), self.get_location: gapic_v1.method.wrap_method( self.get_location, default_timeout=None, @@ -1084,6 +1111,54 @@ def list_mesh_route_views( ]: raise NotImplementedError() + @property + def list_agent_gateways( + self, + ) -> Callable[ + [agent_gateway.ListAgentGatewaysRequest], + Union[ + agent_gateway.ListAgentGatewaysResponse, + Awaitable[agent_gateway.ListAgentGatewaysResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_agent_gateway( + self, + ) -> Callable[ + [agent_gateway.GetAgentGatewayRequest], + Union[agent_gateway.AgentGateway, Awaitable[agent_gateway.AgentGateway]], + ]: + raise NotImplementedError() + + @property + def create_agent_gateway( + self, + ) -> Callable[ + [gcn_agent_gateway.CreateAgentGatewayRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def update_agent_gateway( + self, + ) -> Callable[ + [gcn_agent_gateway.UpdateAgentGatewayRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def delete_agent_gateway( + self, + ) -> Callable[ + [agent_gateway.DeleteAgentGatewayRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + @property def list_operations( self, diff --git a/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/transports/grpc.py b/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/transports/grpc.py index 68120140d2f0..ba228dd6cf0a 100644 --- a/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/transports/grpc.py +++ b/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/transports/grpc.py @@ -35,6 +35,7 @@ from google.protobuf.json_format import MessageToJson from google.cloud.network_services_v1.types import ( + agent_gateway, endpoint_policy, extensibility, gateway, @@ -47,6 +48,7 @@ tcp_route, tls_route, ) +from google.cloud.network_services_v1.types import agent_gateway as gcn_agent_gateway from google.cloud.network_services_v1.types import ( endpoint_policy as gcn_endpoint_policy, ) @@ -1949,6 +1951,144 @@ def list_mesh_route_views( ) return self._stubs["list_mesh_route_views"] + @property + def list_agent_gateways( + self, + ) -> Callable[ + [agent_gateway.ListAgentGatewaysRequest], + agent_gateway.ListAgentGatewaysResponse, + ]: + r"""Return a callable for the list agent gateways method over gRPC. + + Lists AgentGateways in a given project and location. + + Returns: + Callable[[~.ListAgentGatewaysRequest], + ~.ListAgentGatewaysResponse]: + 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_agent_gateways" not in self._stubs: + self._stubs["list_agent_gateways"] = self._logged_channel.unary_unary( + "/google.cloud.networkservices.v1.NetworkServices/ListAgentGateways", + request_serializer=agent_gateway.ListAgentGatewaysRequest.serialize, + response_deserializer=agent_gateway.ListAgentGatewaysResponse.deserialize, + ) + return self._stubs["list_agent_gateways"] + + @property + def get_agent_gateway( + self, + ) -> Callable[[agent_gateway.GetAgentGatewayRequest], agent_gateway.AgentGateway]: + r"""Return a callable for the get agent gateway method over gRPC. + + Gets details of a single AgentGateway. + + Returns: + Callable[[~.GetAgentGatewayRequest], + ~.AgentGateway]: + 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_agent_gateway" not in self._stubs: + self._stubs["get_agent_gateway"] = self._logged_channel.unary_unary( + "/google.cloud.networkservices.v1.NetworkServices/GetAgentGateway", + request_serializer=agent_gateway.GetAgentGatewayRequest.serialize, + response_deserializer=agent_gateway.AgentGateway.deserialize, + ) + return self._stubs["get_agent_gateway"] + + @property + def create_agent_gateway( + self, + ) -> Callable[ + [gcn_agent_gateway.CreateAgentGatewayRequest], operations_pb2.Operation + ]: + r"""Return a callable for the create agent gateway method over gRPC. + + Creates a new AgentGateway in a given project and + location. + + Returns: + Callable[[~.CreateAgentGatewayRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_agent_gateway" not in self._stubs: + self._stubs["create_agent_gateway"] = self._logged_channel.unary_unary( + "/google.cloud.networkservices.v1.NetworkServices/CreateAgentGateway", + request_serializer=gcn_agent_gateway.CreateAgentGatewayRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["create_agent_gateway"] + + @property + def update_agent_gateway( + self, + ) -> Callable[ + [gcn_agent_gateway.UpdateAgentGatewayRequest], operations_pb2.Operation + ]: + r"""Return a callable for the update agent gateway method over gRPC. + + Updates the parameters of a single AgentGateway. + + Returns: + Callable[[~.UpdateAgentGatewayRequest], + ~.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 "update_agent_gateway" not in self._stubs: + self._stubs["update_agent_gateway"] = self._logged_channel.unary_unary( + "/google.cloud.networkservices.v1.NetworkServices/UpdateAgentGateway", + request_serializer=gcn_agent_gateway.UpdateAgentGatewayRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["update_agent_gateway"] + + @property + def delete_agent_gateway( + self, + ) -> Callable[[agent_gateway.DeleteAgentGatewayRequest], operations_pb2.Operation]: + r"""Return a callable for the delete agent gateway method over gRPC. + + Deletes a single AgentGateway. + + Returns: + Callable[[~.DeleteAgentGatewayRequest], + ~.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 "delete_agent_gateway" not in self._stubs: + self._stubs["delete_agent_gateway"] = self._logged_channel.unary_unary( + "/google.cloud.networkservices.v1.NetworkServices/DeleteAgentGateway", + request_serializer=agent_gateway.DeleteAgentGatewayRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["delete_agent_gateway"] + def close(self): self._logged_channel.close() diff --git a/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/transports/grpc_asyncio.py b/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/transports/grpc_asyncio.py index e3a12d68dfea..2a83c39fdc93 100644 --- a/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/transports/grpc_asyncio.py +++ b/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/transports/grpc_asyncio.py @@ -38,6 +38,7 @@ from grpc.experimental import aio # type: ignore from google.cloud.network_services_v1.types import ( + agent_gateway, endpoint_policy, extensibility, gateway, @@ -50,6 +51,7 @@ tcp_route, tls_route, ) +from google.cloud.network_services_v1.types import agent_gateway as gcn_agent_gateway from google.cloud.network_services_v1.types import ( endpoint_policy as gcn_endpoint_policy, ) @@ -2022,6 +2024,150 @@ def list_mesh_route_views( ) return self._stubs["list_mesh_route_views"] + @property + def list_agent_gateways( + self, + ) -> Callable[ + [agent_gateway.ListAgentGatewaysRequest], + Awaitable[agent_gateway.ListAgentGatewaysResponse], + ]: + r"""Return a callable for the list agent gateways method over gRPC. + + Lists AgentGateways in a given project and location. + + Returns: + Callable[[~.ListAgentGatewaysRequest], + Awaitable[~.ListAgentGatewaysResponse]]: + 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_agent_gateways" not in self._stubs: + self._stubs["list_agent_gateways"] = self._logged_channel.unary_unary( + "/google.cloud.networkservices.v1.NetworkServices/ListAgentGateways", + request_serializer=agent_gateway.ListAgentGatewaysRequest.serialize, + response_deserializer=agent_gateway.ListAgentGatewaysResponse.deserialize, + ) + return self._stubs["list_agent_gateways"] + + @property + def get_agent_gateway( + self, + ) -> Callable[ + [agent_gateway.GetAgentGatewayRequest], Awaitable[agent_gateway.AgentGateway] + ]: + r"""Return a callable for the get agent gateway method over gRPC. + + Gets details of a single AgentGateway. + + Returns: + Callable[[~.GetAgentGatewayRequest], + Awaitable[~.AgentGateway]]: + 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_agent_gateway" not in self._stubs: + self._stubs["get_agent_gateway"] = self._logged_channel.unary_unary( + "/google.cloud.networkservices.v1.NetworkServices/GetAgentGateway", + request_serializer=agent_gateway.GetAgentGatewayRequest.serialize, + response_deserializer=agent_gateway.AgentGateway.deserialize, + ) + return self._stubs["get_agent_gateway"] + + @property + def create_agent_gateway( + self, + ) -> Callable[ + [gcn_agent_gateway.CreateAgentGatewayRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the create agent gateway method over gRPC. + + Creates a new AgentGateway in a given project and + location. + + Returns: + Callable[[~.CreateAgentGatewayRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_agent_gateway" not in self._stubs: + self._stubs["create_agent_gateway"] = self._logged_channel.unary_unary( + "/google.cloud.networkservices.v1.NetworkServices/CreateAgentGateway", + request_serializer=gcn_agent_gateway.CreateAgentGatewayRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["create_agent_gateway"] + + @property + def update_agent_gateway( + self, + ) -> Callable[ + [gcn_agent_gateway.UpdateAgentGatewayRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the update agent gateway method over gRPC. + + Updates the parameters of a single AgentGateway. + + Returns: + Callable[[~.UpdateAgentGatewayRequest], + 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 "update_agent_gateway" not in self._stubs: + self._stubs["update_agent_gateway"] = self._logged_channel.unary_unary( + "/google.cloud.networkservices.v1.NetworkServices/UpdateAgentGateway", + request_serializer=gcn_agent_gateway.UpdateAgentGatewayRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["update_agent_gateway"] + + @property + def delete_agent_gateway( + self, + ) -> Callable[ + [agent_gateway.DeleteAgentGatewayRequest], Awaitable[operations_pb2.Operation] + ]: + r"""Return a callable for the delete agent gateway method over gRPC. + + Deletes a single AgentGateway. + + Returns: + Callable[[~.DeleteAgentGatewayRequest], + 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 "delete_agent_gateway" not in self._stubs: + self._stubs["delete_agent_gateway"] = self._logged_channel.unary_unary( + "/google.cloud.networkservices.v1.NetworkServices/DeleteAgentGateway", + request_serializer=agent_gateway.DeleteAgentGatewayRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["delete_agent_gateway"] + def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { @@ -2315,6 +2461,31 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.list_agent_gateways: self._wrap_method( + self.list_agent_gateways, + default_timeout=None, + client_info=client_info, + ), + self.get_agent_gateway: self._wrap_method( + self.get_agent_gateway, + default_timeout=None, + client_info=client_info, + ), + self.create_agent_gateway: self._wrap_method( + self.create_agent_gateway, + default_timeout=None, + client_info=client_info, + ), + self.update_agent_gateway: self._wrap_method( + self.update_agent_gateway, + default_timeout=None, + client_info=client_info, + ), + self.delete_agent_gateway: self._wrap_method( + self.delete_agent_gateway, + default_timeout=None, + client_info=client_info, + ), self.get_location: self._wrap_method( self.get_location, default_timeout=None, diff --git a/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/transports/rest.py b/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/transports/rest.py index a417f9eaa720..be7f856c9835 100644 --- a/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/transports/rest.py +++ b/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/transports/rest.py @@ -35,6 +35,7 @@ from requests import __version__ as requests_version from google.cloud.network_services_v1.types import ( + agent_gateway, endpoint_policy, extensibility, gateway, @@ -47,6 +48,7 @@ tcp_route, tls_route, ) +from google.cloud.network_services_v1.types import agent_gateway as gcn_agent_gateway from google.cloud.network_services_v1.types import ( endpoint_policy as gcn_endpoint_policy, ) @@ -105,6 +107,14 @@ class NetworkServicesRestInterceptor: .. code-block:: python class MyCustomNetworkServicesInterceptor(NetworkServicesRestInterceptor): + def pre_create_agent_gateway(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_agent_gateway(self, response): + logging.log(f"Received response: {response}") + return response + def pre_create_endpoint_policy(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -193,6 +203,14 @@ def post_create_wasm_plugin_version(self, response): logging.log(f"Received response: {response}") return response + def pre_delete_agent_gateway(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_delete_agent_gateway(self, response): + logging.log(f"Received response: {response}") + return response + def pre_delete_endpoint_policy(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -281,6 +299,14 @@ def post_delete_wasm_plugin_version(self, response): logging.log(f"Received response: {response}") return response + def pre_get_agent_gateway(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_agent_gateway(self, response): + logging.log(f"Received response: {response}") + return response + def pre_get_endpoint_policy(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -385,6 +411,14 @@ def post_get_wasm_plugin_version(self, response): logging.log(f"Received response: {response}") return response + def pre_list_agent_gateways(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_agent_gateways(self, response): + logging.log(f"Received response: {response}") + return response + def pre_list_endpoint_policies(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -489,6 +523,14 @@ def post_list_wasm_plugin_versions(self, response): logging.log(f"Received response: {response}") return response + def pre_update_agent_gateway(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_agent_gateway(self, response): + logging.log(f"Received response: {response}") + return response + def pre_update_endpoint_policy(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -575,6 +617,55 @@ def post_update_wasm_plugin(self, response): """ + def pre_create_agent_gateway( + self, + request: gcn_agent_gateway.CreateAgentGatewayRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcn_agent_gateway.CreateAgentGatewayRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for create_agent_gateway + + Override in a subclass to manipulate the request or metadata + before they are sent to the NetworkServices server. + """ + return request, metadata + + def post_create_agent_gateway( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for create_agent_gateway + + DEPRECATED. Please use the `post_create_agent_gateway_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the NetworkServices server but before + it is returned to user code. This `post_create_agent_gateway` interceptor runs + before the `post_create_agent_gateway_with_metadata` interceptor. + """ + return response + + def post_create_agent_gateway_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_agent_gateway + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the NetworkServices server but before it is returned to user code. + + We recommend only using this `post_create_agent_gateway_with_metadata` + interceptor in new development instead of the `post_create_agent_gateway` interceptor. + When both interceptors are used, this `post_create_agent_gateway_with_metadata` interceptor runs after the + `post_create_agent_gateway` interceptor. The (possibly modified) response returned by + `post_create_agent_gateway` will be passed to + `post_create_agent_gateway_with_metadata`. + """ + return response, metadata + def pre_create_endpoint_policy( self, request: gcn_endpoint_policy.CreateEndpointPolicyRequest, @@ -1105,6 +1196,54 @@ def post_create_wasm_plugin_version_with_metadata( """ return response, metadata + def pre_delete_agent_gateway( + self, + request: agent_gateway.DeleteAgentGatewayRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + agent_gateway.DeleteAgentGatewayRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for delete_agent_gateway + + Override in a subclass to manipulate the request or metadata + before they are sent to the NetworkServices server. + """ + return request, metadata + + def post_delete_agent_gateway( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for delete_agent_gateway + + DEPRECATED. Please use the `post_delete_agent_gateway_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the NetworkServices server but before + it is returned to user code. This `post_delete_agent_gateway` interceptor runs + before the `post_delete_agent_gateway_with_metadata` interceptor. + """ + return response + + def post_delete_agent_gateway_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_agent_gateway + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the NetworkServices server but before it is returned to user code. + + We recommend only using this `post_delete_agent_gateway_with_metadata` + interceptor in new development instead of the `post_delete_agent_gateway` interceptor. + When both interceptors are used, this `post_delete_agent_gateway_with_metadata` interceptor runs after the + `post_delete_agent_gateway` interceptor. The (possibly modified) response returned by + `post_delete_agent_gateway` will be passed to + `post_delete_agent_gateway_with_metadata`. + """ + return response, metadata + def pre_delete_endpoint_policy( self, request: endpoint_policy.DeleteEndpointPolicyRequest, @@ -1633,6 +1772,54 @@ def post_delete_wasm_plugin_version_with_metadata( """ return response, metadata + def pre_get_agent_gateway( + self, + request: agent_gateway.GetAgentGatewayRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + agent_gateway.GetAgentGatewayRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_agent_gateway + + Override in a subclass to manipulate the request or metadata + before they are sent to the NetworkServices server. + """ + return request, metadata + + def post_get_agent_gateway( + self, response: agent_gateway.AgentGateway + ) -> agent_gateway.AgentGateway: + """Post-rpc interceptor for get_agent_gateway + + DEPRECATED. Please use the `post_get_agent_gateway_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the NetworkServices server but before + it is returned to user code. This `post_get_agent_gateway` interceptor runs + before the `post_get_agent_gateway_with_metadata` interceptor. + """ + return response + + def post_get_agent_gateway_with_metadata( + self, + response: agent_gateway.AgentGateway, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[agent_gateway.AgentGateway, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_agent_gateway + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the NetworkServices server but before it is returned to user code. + + We recommend only using this `post_get_agent_gateway_with_metadata` + interceptor in new development instead of the `post_get_agent_gateway` interceptor. + When both interceptors are used, this `post_get_agent_gateway_with_metadata` interceptor runs after the + `post_get_agent_gateway` interceptor. The (possibly modified) response returned by + `post_get_agent_gateway` will be passed to + `post_get_agent_gateway_with_metadata`. + """ + return response, metadata + def pre_get_endpoint_policy( self, request: endpoint_policy.GetEndpointPolicyRequest, @@ -2243,6 +2430,56 @@ def post_get_wasm_plugin_version_with_metadata( """ return response, metadata + def pre_list_agent_gateways( + self, + request: agent_gateway.ListAgentGatewaysRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + agent_gateway.ListAgentGatewaysRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for list_agent_gateways + + Override in a subclass to manipulate the request or metadata + before they are sent to the NetworkServices server. + """ + return request, metadata + + def post_list_agent_gateways( + self, response: agent_gateway.ListAgentGatewaysResponse + ) -> agent_gateway.ListAgentGatewaysResponse: + """Post-rpc interceptor for list_agent_gateways + + DEPRECATED. Please use the `post_list_agent_gateways_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the NetworkServices server but before + it is returned to user code. This `post_list_agent_gateways` interceptor runs + before the `post_list_agent_gateways_with_metadata` interceptor. + """ + return response + + def post_list_agent_gateways_with_metadata( + self, + response: agent_gateway.ListAgentGatewaysResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + agent_gateway.ListAgentGatewaysResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_agent_gateways + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the NetworkServices server but before it is returned to user code. + + We recommend only using this `post_list_agent_gateways_with_metadata` + interceptor in new development instead of the `post_list_agent_gateways` interceptor. + When both interceptors are used, this `post_list_agent_gateways_with_metadata` interceptor runs after the + `post_list_agent_gateways` interceptor. The (possibly modified) response returned by + `post_list_agent_gateways` will be passed to + `post_list_agent_gateways_with_metadata`. + """ + return response, metadata + def pre_list_endpoint_policies( self, request: endpoint_policy.ListEndpointPoliciesRequest, @@ -2890,6 +3127,55 @@ def post_list_wasm_plugin_versions_with_metadata( """ return response, metadata + def pre_update_agent_gateway( + self, + request: gcn_agent_gateway.UpdateAgentGatewayRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcn_agent_gateway.UpdateAgentGatewayRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for update_agent_gateway + + Override in a subclass to manipulate the request or metadata + before they are sent to the NetworkServices server. + """ + return request, metadata + + def post_update_agent_gateway( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for update_agent_gateway + + DEPRECATED. Please use the `post_update_agent_gateway_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the NetworkServices server but before + it is returned to user code. This `post_update_agent_gateway` interceptor runs + before the `post_update_agent_gateway_with_metadata` interceptor. + """ + return response + + def post_update_agent_gateway_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_agent_gateway + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the NetworkServices server but before it is returned to user code. + + We recommend only using this `post_update_agent_gateway_with_metadata` + interceptor in new development instead of the `post_update_agent_gateway` interceptor. + When both interceptors are used, this `post_update_agent_gateway_with_metadata` interceptor runs after the + `post_update_agent_gateway` interceptor. The (possibly modified) response returned by + `post_update_agent_gateway` will be passed to + `post_update_agent_gateway_with_metadata`. + """ + return response, metadata + def pre_update_endpoint_policy( self, request: gcn_endpoint_policy.UpdateEndpointPolicyRequest, @@ -3737,12 +4023,12 @@ def operations_client(self) -> operations_v1.AbstractOperationsClient: # Return the client from cache. return self._operations_client - class _CreateEndpointPolicy( - _BaseNetworkServicesRestTransport._BaseCreateEndpointPolicy, + class _CreateAgentGateway( + _BaseNetworkServicesRestTransport._BaseCreateAgentGateway, NetworkServicesRestStub, ): def __hash__(self): - return hash("NetworkServicesRestTransport.CreateEndpointPolicy") + return hash("NetworkServicesRestTransport.CreateAgentGateway") @staticmethod def _get_response( @@ -3769,18 +4055,18 @@ def _get_response( def __call__( self, - request: gcn_endpoint_policy.CreateEndpointPolicyRequest, + request: gcn_agent_gateway.CreateAgentGatewayRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> operations_pb2.Operation: - r"""Call the create endpoint policy method over HTTP. + r"""Call the create agent gateway method over HTTP. Args: - request (~.gcn_endpoint_policy.CreateEndpointPolicyRequest): - The request object. Request used with the - CreateEndpointPolicy method. + request (~.gcn_agent_gateway.CreateAgentGatewayRequest): + The request object. Request used by the + CreateAgentGateway method. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -3797,21 +4083,21 @@ def __call__( """ - http_options = _BaseNetworkServicesRestTransport._BaseCreateEndpointPolicy._get_http_options() + http_options = _BaseNetworkServicesRestTransport._BaseCreateAgentGateway._get_http_options() - request, metadata = self._interceptor.pre_create_endpoint_policy( + request, metadata = self._interceptor.pre_create_agent_gateway( request, metadata ) - transcoded_request = _BaseNetworkServicesRestTransport._BaseCreateEndpointPolicy._get_transcoded_request( + transcoded_request = _BaseNetworkServicesRestTransport._BaseCreateAgentGateway._get_transcoded_request( http_options, request ) - body = _BaseNetworkServicesRestTransport._BaseCreateEndpointPolicy._get_request_body_json( + body = _BaseNetworkServicesRestTransport._BaseCreateAgentGateway._get_request_body_json( transcoded_request ) # Jsonify the query params - query_params = _BaseNetworkServicesRestTransport._BaseCreateEndpointPolicy._get_query_params_json( + query_params = _BaseNetworkServicesRestTransport._BaseCreateAgentGateway._get_query_params_json( transcoded_request ) @@ -3833,17 +4119,17 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.networkservices_v1.NetworkServicesClient.CreateEndpointPolicy", + f"Sending request for google.cloud.networkservices_v1.NetworkServicesClient.CreateAgentGateway", extra={ "serviceName": "google.cloud.networkservices.v1.NetworkServices", - "rpcName": "CreateEndpointPolicy", + "rpcName": "CreateAgentGateway", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = NetworkServicesRestTransport._CreateEndpointPolicy._get_response( + response = NetworkServicesRestTransport._CreateAgentGateway._get_response( self._host, metadata, query_params, @@ -3862,9 +4148,9 @@ def __call__( resp = operations_pb2.Operation() json_format.Parse(response.content, resp, ignore_unknown_fields=True) - resp = self._interceptor.post_create_endpoint_policy(resp) + resp = self._interceptor.post_create_agent_gateway(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_create_endpoint_policy_with_metadata( + resp, _ = self._interceptor.post_create_agent_gateway_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( @@ -3880,21 +4166,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.networkservices_v1.NetworkServicesClient.create_endpoint_policy", + "Received response for google.cloud.networkservices_v1.NetworkServicesClient.create_agent_gateway", extra={ "serviceName": "google.cloud.networkservices.v1.NetworkServices", - "rpcName": "CreateEndpointPolicy", + "rpcName": "CreateAgentGateway", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _CreateGateway( - _BaseNetworkServicesRestTransport._BaseCreateGateway, NetworkServicesRestStub + class _CreateEndpointPolicy( + _BaseNetworkServicesRestTransport._BaseCreateEndpointPolicy, + NetworkServicesRestStub, ): def __hash__(self): - return hash("NetworkServicesRestTransport.CreateGateway") + return hash("NetworkServicesRestTransport.CreateEndpointPolicy") @staticmethod def _get_response( @@ -3921,18 +4208,18 @@ def _get_response( def __call__( self, - request: gcn_gateway.CreateGatewayRequest, + request: gcn_endpoint_policy.CreateEndpointPolicyRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> operations_pb2.Operation: - r"""Call the create gateway method over HTTP. + r"""Call the create endpoint policy method over HTTP. Args: - request (~.gcn_gateway.CreateGatewayRequest): - The request object. Request used by the CreateGateway - method. + request (~.gcn_endpoint_policy.CreateEndpointPolicyRequest): + The request object. Request used with the + CreateEndpointPolicy method. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -3949,21 +4236,21 @@ def __call__( """ - http_options = ( - _BaseNetworkServicesRestTransport._BaseCreateGateway._get_http_options() - ) + http_options = _BaseNetworkServicesRestTransport._BaseCreateEndpointPolicy._get_http_options() - request, metadata = self._interceptor.pre_create_gateway(request, metadata) - transcoded_request = _BaseNetworkServicesRestTransport._BaseCreateGateway._get_transcoded_request( + request, metadata = self._interceptor.pre_create_endpoint_policy( + request, metadata + ) + transcoded_request = _BaseNetworkServicesRestTransport._BaseCreateEndpointPolicy._get_transcoded_request( http_options, request ) - body = _BaseNetworkServicesRestTransport._BaseCreateGateway._get_request_body_json( + body = _BaseNetworkServicesRestTransport._BaseCreateEndpointPolicy._get_request_body_json( transcoded_request ) # Jsonify the query params - query_params = _BaseNetworkServicesRestTransport._BaseCreateGateway._get_query_params_json( + query_params = _BaseNetworkServicesRestTransport._BaseCreateEndpointPolicy._get_query_params_json( transcoded_request ) @@ -3985,17 +4272,17 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.networkservices_v1.NetworkServicesClient.CreateGateway", + f"Sending request for google.cloud.networkservices_v1.NetworkServicesClient.CreateEndpointPolicy", extra={ "serviceName": "google.cloud.networkservices.v1.NetworkServices", - "rpcName": "CreateGateway", + "rpcName": "CreateEndpointPolicy", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = NetworkServicesRestTransport._CreateGateway._get_response( + response = NetworkServicesRestTransport._CreateEndpointPolicy._get_response( self._host, metadata, query_params, @@ -4014,9 +4301,9 @@ def __call__( resp = operations_pb2.Operation() json_format.Parse(response.content, resp, ignore_unknown_fields=True) - resp = self._interceptor.post_create_gateway(resp) + resp = self._interceptor.post_create_endpoint_policy(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_create_gateway_with_metadata( + resp, _ = self._interceptor.post_create_endpoint_policy_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( @@ -4032,21 +4319,21 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.networkservices_v1.NetworkServicesClient.create_gateway", + "Received response for google.cloud.networkservices_v1.NetworkServicesClient.create_endpoint_policy", extra={ "serviceName": "google.cloud.networkservices.v1.NetworkServices", - "rpcName": "CreateGateway", + "rpcName": "CreateEndpointPolicy", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _CreateGrpcRoute( - _BaseNetworkServicesRestTransport._BaseCreateGrpcRoute, NetworkServicesRestStub + class _CreateGateway( + _BaseNetworkServicesRestTransport._BaseCreateGateway, NetworkServicesRestStub ): def __hash__(self): - return hash("NetworkServicesRestTransport.CreateGrpcRoute") + return hash("NetworkServicesRestTransport.CreateGateway") @staticmethod def _get_response( @@ -4073,13 +4360,165 @@ def _get_response( def __call__( self, - request: gcn_grpc_route.CreateGrpcRouteRequest, + request: gcn_gateway.CreateGatewayRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> operations_pb2.Operation: - r"""Call the create grpc route method over HTTP. + r"""Call the create gateway method over HTTP. + + Args: + request (~.gcn_gateway.CreateGatewayRequest): + The request object. Request used by the CreateGateway + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = ( + _BaseNetworkServicesRestTransport._BaseCreateGateway._get_http_options() + ) + + request, metadata = self._interceptor.pre_create_gateway(request, metadata) + transcoded_request = _BaseNetworkServicesRestTransport._BaseCreateGateway._get_transcoded_request( + http_options, request + ) + + body = _BaseNetworkServicesRestTransport._BaseCreateGateway._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseNetworkServicesRestTransport._BaseCreateGateway._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.networkservices_v1.NetworkServicesClient.CreateGateway", + extra={ + "serviceName": "google.cloud.networkservices.v1.NetworkServices", + "rpcName": "CreateGateway", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = NetworkServicesRestTransport._CreateGateway._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_create_gateway(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_gateway_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.networkservices_v1.NetworkServicesClient.create_gateway", + extra={ + "serviceName": "google.cloud.networkservices.v1.NetworkServices", + "rpcName": "CreateGateway", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _CreateGrpcRoute( + _BaseNetworkServicesRestTransport._BaseCreateGrpcRoute, NetworkServicesRestStub + ): + def __hash__(self): + return hash("NetworkServicesRestTransport.CreateGrpcRoute") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: gcn_grpc_route.CreateGrpcRouteRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the create grpc route method over HTTP. Args: request (~.gcn_grpc_route.CreateGrpcRouteRequest): @@ -5413,6 +5852,153 @@ def __call__( ) return resp + class _DeleteAgentGateway( + _BaseNetworkServicesRestTransport._BaseDeleteAgentGateway, + NetworkServicesRestStub, + ): + def __hash__(self): + return hash("NetworkServicesRestTransport.DeleteAgentGateway") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: agent_gateway.DeleteAgentGatewayRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the delete agent gateway method over HTTP. + + Args: + request (~.agent_gateway.DeleteAgentGatewayRequest): + The request object. Request used by the + DeleteAgentGateway 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseNetworkServicesRestTransport._BaseDeleteAgentGateway._get_http_options() + + request, metadata = self._interceptor.pre_delete_agent_gateway( + request, metadata + ) + transcoded_request = _BaseNetworkServicesRestTransport._BaseDeleteAgentGateway._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseNetworkServicesRestTransport._BaseDeleteAgentGateway._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.networkservices_v1.NetworkServicesClient.DeleteAgentGateway", + extra={ + "serviceName": "google.cloud.networkservices.v1.NetworkServices", + "rpcName": "DeleteAgentGateway", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = NetworkServicesRestTransport._DeleteAgentGateway._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_delete_agent_gateway(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_agent_gateway_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.networkservices_v1.NetworkServicesClient.delete_agent_gateway", + extra={ + "serviceName": "google.cloud.networkservices.v1.NetworkServices", + "rpcName": "DeleteAgentGateway", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + class _DeleteEndpointPolicy( _BaseNetworkServicesRestTransport._BaseDeleteEndpointPolicy, NetworkServicesRestStub, @@ -6781,25 +7367,172 @@ def __call__( but for metadata keys ending with the suffix `-bin`, the corresponding values must be of type `bytes`. - Returns: - ~.operations_pb2.Operation: - This resource represents a - long-running operation that is the - result of a network API call. + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseNetworkServicesRestTransport._BaseDeleteWasmPlugin._get_http_options() + + request, metadata = self._interceptor.pre_delete_wasm_plugin( + request, metadata + ) + transcoded_request = _BaseNetworkServicesRestTransport._BaseDeleteWasmPlugin._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseNetworkServicesRestTransport._BaseDeleteWasmPlugin._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.networkservices_v1.NetworkServicesClient.DeleteWasmPlugin", + extra={ + "serviceName": "google.cloud.networkservices.v1.NetworkServices", + "rpcName": "DeleteWasmPlugin", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = NetworkServicesRestTransport._DeleteWasmPlugin._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_delete_wasm_plugin(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_wasm_plugin_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.networkservices_v1.NetworkServicesClient.delete_wasm_plugin", + extra={ + "serviceName": "google.cloud.networkservices.v1.NetworkServices", + "rpcName": "DeleteWasmPlugin", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _DeleteWasmPluginVersion( + _BaseNetworkServicesRestTransport._BaseDeleteWasmPluginVersion, + NetworkServicesRestStub, + ): + def __hash__(self): + return hash("NetworkServicesRestTransport.DeleteWasmPluginVersion") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: extensibility.DeleteWasmPluginVersionRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the delete wasm plugin + version method over HTTP. + + Args: + request (~.extensibility.DeleteWasmPluginVersionRequest): + The request object. Request used by the ``DeleteWasmPluginVersion`` 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. """ - http_options = _BaseNetworkServicesRestTransport._BaseDeleteWasmPlugin._get_http_options() + http_options = _BaseNetworkServicesRestTransport._BaseDeleteWasmPluginVersion._get_http_options() - request, metadata = self._interceptor.pre_delete_wasm_plugin( + request, metadata = self._interceptor.pre_delete_wasm_plugin_version( request, metadata ) - transcoded_request = _BaseNetworkServicesRestTransport._BaseDeleteWasmPlugin._get_transcoded_request( + transcoded_request = _BaseNetworkServicesRestTransport._BaseDeleteWasmPluginVersion._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseNetworkServicesRestTransport._BaseDeleteWasmPlugin._get_query_params_json( + query_params = _BaseNetworkServicesRestTransport._BaseDeleteWasmPluginVersion._get_query_params_json( transcoded_request ) @@ -6821,23 +7554,25 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.networkservices_v1.NetworkServicesClient.DeleteWasmPlugin", + f"Sending request for google.cloud.networkservices_v1.NetworkServicesClient.DeleteWasmPluginVersion", extra={ "serviceName": "google.cloud.networkservices.v1.NetworkServices", - "rpcName": "DeleteWasmPlugin", + "rpcName": "DeleteWasmPluginVersion", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = NetworkServicesRestTransport._DeleteWasmPlugin._get_response( - self._host, - metadata, - query_params, - self._session, - timeout, - transcoded_request, + response = ( + NetworkServicesRestTransport._DeleteWasmPluginVersion._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -6849,9 +7584,9 @@ def __call__( resp = operations_pb2.Operation() json_format.Parse(response.content, resp, ignore_unknown_fields=True) - resp = self._interceptor.post_delete_wasm_plugin(resp) + resp = self._interceptor.post_delete_wasm_plugin_version(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_delete_wasm_plugin_with_metadata( + resp, _ = self._interceptor.post_delete_wasm_plugin_version_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( @@ -6867,22 +7602,21 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.networkservices_v1.NetworkServicesClient.delete_wasm_plugin", + "Received response for google.cloud.networkservices_v1.NetworkServicesClient.delete_wasm_plugin_version", extra={ "serviceName": "google.cloud.networkservices.v1.NetworkServices", - "rpcName": "DeleteWasmPlugin", + "rpcName": "DeleteWasmPluginVersion", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _DeleteWasmPluginVersion( - _BaseNetworkServicesRestTransport._BaseDeleteWasmPluginVersion, - NetworkServicesRestStub, + class _GetAgentGateway( + _BaseNetworkServicesRestTransport._BaseGetAgentGateway, NetworkServicesRestStub ): def __hash__(self): - return hash("NetworkServicesRestTransport.DeleteWasmPluginVersion") + return hash("NetworkServicesRestTransport.GetAgentGateway") @staticmethod def _get_response( @@ -6908,45 +7642,44 @@ def _get_response( def __call__( self, - request: extensibility.DeleteWasmPluginVersionRequest, + request: agent_gateway.GetAgentGatewayRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> operations_pb2.Operation: - r"""Call the delete wasm plugin - version method over HTTP. + ) -> agent_gateway.AgentGateway: + r"""Call the get agent gateway method over HTTP. - Args: - request (~.extensibility.DeleteWasmPluginVersionRequest): - The request object. Request used by the ``DeleteWasmPluginVersion`` 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. + Args: + request (~.agent_gateway.GetAgentGatewayRequest): + The request object. Request used by the GetAgentGateway + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. - Returns: - ~.operations_pb2.Operation: - This resource represents a - long-running operation that is the - result of a network API call. + Returns: + ~.agent_gateway.AgentGateway: + AgentGateway represents the agent + gateway resource. """ - http_options = _BaseNetworkServicesRestTransport._BaseDeleteWasmPluginVersion._get_http_options() + http_options = _BaseNetworkServicesRestTransport._BaseGetAgentGateway._get_http_options() - request, metadata = self._interceptor.pre_delete_wasm_plugin_version( + request, metadata = self._interceptor.pre_get_agent_gateway( request, metadata ) - transcoded_request = _BaseNetworkServicesRestTransport._BaseDeleteWasmPluginVersion._get_transcoded_request( + transcoded_request = _BaseNetworkServicesRestTransport._BaseGetAgentGateway._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseNetworkServicesRestTransport._BaseDeleteWasmPluginVersion._get_query_params_json( + query_params = _BaseNetworkServicesRestTransport._BaseGetAgentGateway._get_query_params_json( transcoded_request ) @@ -6968,25 +7701,23 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.networkservices_v1.NetworkServicesClient.DeleteWasmPluginVersion", + f"Sending request for google.cloud.networkservices_v1.NetworkServicesClient.GetAgentGateway", extra={ "serviceName": "google.cloud.networkservices.v1.NetworkServices", - "rpcName": "DeleteWasmPluginVersion", + "rpcName": "GetAgentGateway", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = ( - NetworkServicesRestTransport._DeleteWasmPluginVersion._get_response( - self._host, - metadata, - query_params, - self._session, - timeout, - transcoded_request, - ) + response = NetworkServicesRestTransport._GetAgentGateway._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -6995,19 +7726,21 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = operations_pb2.Operation() - json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = agent_gateway.AgentGateway() + pb_resp = agent_gateway.AgentGateway.pb(resp) - resp = self._interceptor.post_delete_wasm_plugin_version(resp) + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_agent_gateway(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_delete_wasm_plugin_version_with_metadata( + resp, _ = self._interceptor.post_get_agent_gateway_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = json_format.MessageToJson(resp) + response_payload = agent_gateway.AgentGateway.to_json(response) except: response_payload = None http_response = { @@ -7016,10 +7749,10 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.networkservices_v1.NetworkServicesClient.delete_wasm_plugin_version", + "Received response for google.cloud.networkservices_v1.NetworkServicesClient.get_agent_gateway", extra={ "serviceName": "google.cloud.networkservices.v1.NetworkServices", - "rpcName": "DeleteWasmPluginVersion", + "rpcName": "GetAgentGateway", "metadata": http_response["headers"], "httpResponse": http_response, }, @@ -8672,21 +9405,168 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.networkservices_v1.NetworkServicesClient.get_tls_route", + "Received response for google.cloud.networkservices_v1.NetworkServicesClient.get_tls_route", + extra={ + "serviceName": "google.cloud.networkservices.v1.NetworkServices", + "rpcName": "GetTlsRoute", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _GetWasmPlugin( + _BaseNetworkServicesRestTransport._BaseGetWasmPlugin, NetworkServicesRestStub + ): + def __hash__(self): + return hash("NetworkServicesRestTransport.GetWasmPlugin") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: extensibility.GetWasmPluginRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> extensibility.WasmPlugin: + r"""Call the get wasm plugin method over HTTP. + + Args: + request (~.extensibility.GetWasmPluginRequest): + The request object. Request used by the ``GetWasmPlugin`` 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.extensibility.WasmPlugin: + ``WasmPlugin`` is a resource representing a service + executing a customer-provided Wasm module. + + """ + + http_options = ( + _BaseNetworkServicesRestTransport._BaseGetWasmPlugin._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_wasm_plugin(request, metadata) + transcoded_request = _BaseNetworkServicesRestTransport._BaseGetWasmPlugin._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseNetworkServicesRestTransport._BaseGetWasmPlugin._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.networkservices_v1.NetworkServicesClient.GetWasmPlugin", + extra={ + "serviceName": "google.cloud.networkservices.v1.NetworkServices", + "rpcName": "GetWasmPlugin", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = NetworkServicesRestTransport._GetWasmPlugin._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = extensibility.WasmPlugin() + pb_resp = extensibility.WasmPlugin.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_wasm_plugin(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_wasm_plugin_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = extensibility.WasmPlugin.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.networkservices_v1.NetworkServicesClient.get_wasm_plugin", extra={ "serviceName": "google.cloud.networkservices.v1.NetworkServices", - "rpcName": "GetTlsRoute", + "rpcName": "GetWasmPlugin", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _GetWasmPlugin( - _BaseNetworkServicesRestTransport._BaseGetWasmPlugin, NetworkServicesRestStub + class _GetWasmPluginVersion( + _BaseNetworkServicesRestTransport._BaseGetWasmPluginVersion, + NetworkServicesRestStub, ): def __hash__(self): - return hash("NetworkServicesRestTransport.GetWasmPlugin") + return hash("NetworkServicesRestTransport.GetWasmPluginVersion") @staticmethod def _get_response( @@ -8712,17 +9592,17 @@ def _get_response( def __call__( self, - request: extensibility.GetWasmPluginRequest, + request: extensibility.GetWasmPluginVersionRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> extensibility.WasmPlugin: - r"""Call the get wasm plugin method over HTTP. + ) -> extensibility.WasmPluginVersion: + r"""Call the get wasm plugin version method over HTTP. Args: - request (~.extensibility.GetWasmPluginRequest): - The request object. Request used by the ``GetWasmPlugin`` method. + request (~.extensibility.GetWasmPluginVersionRequest): + The request object. Request used by the ``GetWasmPluginVersion`` method. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -8732,23 +9612,24 @@ def __call__( be of type `bytes`. Returns: - ~.extensibility.WasmPlugin: - ``WasmPlugin`` is a resource representing a service - executing a customer-provided Wasm module. + ~.extensibility.WasmPluginVersion: + A single immutable version of a ``WasmPlugin`` resource. + Defines the Wasm module used and optionally its runtime + config. """ - http_options = ( - _BaseNetworkServicesRestTransport._BaseGetWasmPlugin._get_http_options() - ) + http_options = _BaseNetworkServicesRestTransport._BaseGetWasmPluginVersion._get_http_options() - request, metadata = self._interceptor.pre_get_wasm_plugin(request, metadata) - transcoded_request = _BaseNetworkServicesRestTransport._BaseGetWasmPlugin._get_transcoded_request( + request, metadata = self._interceptor.pre_get_wasm_plugin_version( + request, metadata + ) + transcoded_request = _BaseNetworkServicesRestTransport._BaseGetWasmPluginVersion._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseNetworkServicesRestTransport._BaseGetWasmPlugin._get_query_params_json( + query_params = _BaseNetworkServicesRestTransport._BaseGetWasmPluginVersion._get_query_params_json( transcoded_request ) @@ -8770,17 +9651,17 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.networkservices_v1.NetworkServicesClient.GetWasmPlugin", + f"Sending request for google.cloud.networkservices_v1.NetworkServicesClient.GetWasmPluginVersion", extra={ "serviceName": "google.cloud.networkservices.v1.NetworkServices", - "rpcName": "GetWasmPlugin", + "rpcName": "GetWasmPluginVersion", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = NetworkServicesRestTransport._GetWasmPlugin._get_response( + response = NetworkServicesRestTransport._GetWasmPluginVersion._get_response( self._host, metadata, query_params, @@ -8795,21 +9676,21 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = extensibility.WasmPlugin() - pb_resp = extensibility.WasmPlugin.pb(resp) + resp = extensibility.WasmPluginVersion() + pb_resp = extensibility.WasmPluginVersion.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_get_wasm_plugin(resp) + resp = self._interceptor.post_get_wasm_plugin_version(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_get_wasm_plugin_with_metadata( + resp, _ = self._interceptor.post_get_wasm_plugin_version_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = extensibility.WasmPlugin.to_json(response) + response_payload = extensibility.WasmPluginVersion.to_json(response) except: response_payload = None http_response = { @@ -8818,22 +9699,22 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.networkservices_v1.NetworkServicesClient.get_wasm_plugin", + "Received response for google.cloud.networkservices_v1.NetworkServicesClient.get_wasm_plugin_version", extra={ "serviceName": "google.cloud.networkservices.v1.NetworkServices", - "rpcName": "GetWasmPlugin", + "rpcName": "GetWasmPluginVersion", "metadata": http_response["headers"], "httpResponse": http_response, }, ) return resp - class _GetWasmPluginVersion( - _BaseNetworkServicesRestTransport._BaseGetWasmPluginVersion, + class _ListAgentGateways( + _BaseNetworkServicesRestTransport._BaseListAgentGateways, NetworkServicesRestStub, ): def __hash__(self): - return hash("NetworkServicesRestTransport.GetWasmPluginVersion") + return hash("NetworkServicesRestTransport.ListAgentGateways") @staticmethod def _get_response( @@ -8859,17 +9740,18 @@ def _get_response( def __call__( self, - request: extensibility.GetWasmPluginVersionRequest, + request: agent_gateway.ListAgentGatewaysRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> extensibility.WasmPluginVersion: - r"""Call the get wasm plugin version method over HTTP. + ) -> agent_gateway.ListAgentGatewaysResponse: + r"""Call the list agent gateways method over HTTP. Args: - request (~.extensibility.GetWasmPluginVersionRequest): - The request object. Request used by the ``GetWasmPluginVersion`` method. + request (~.agent_gateway.ListAgentGatewaysRequest): + The request object. Request used with the + ListAgentGateways method. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -8879,24 +9761,23 @@ def __call__( be of type `bytes`. Returns: - ~.extensibility.WasmPluginVersion: - A single immutable version of a ``WasmPlugin`` resource. - Defines the Wasm module used and optionally its runtime - config. + ~.agent_gateway.ListAgentGatewaysResponse: + Response returned by the + ListAgentGateways method. """ - http_options = _BaseNetworkServicesRestTransport._BaseGetWasmPluginVersion._get_http_options() + http_options = _BaseNetworkServicesRestTransport._BaseListAgentGateways._get_http_options() - request, metadata = self._interceptor.pre_get_wasm_plugin_version( + request, metadata = self._interceptor.pre_list_agent_gateways( request, metadata ) - transcoded_request = _BaseNetworkServicesRestTransport._BaseGetWasmPluginVersion._get_transcoded_request( + transcoded_request = _BaseNetworkServicesRestTransport._BaseListAgentGateways._get_transcoded_request( http_options, request ) # Jsonify the query params - query_params = _BaseNetworkServicesRestTransport._BaseGetWasmPluginVersion._get_query_params_json( + query_params = _BaseNetworkServicesRestTransport._BaseListAgentGateways._get_query_params_json( transcoded_request ) @@ -8918,17 +9799,17 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.networkservices_v1.NetworkServicesClient.GetWasmPluginVersion", + f"Sending request for google.cloud.networkservices_v1.NetworkServicesClient.ListAgentGateways", extra={ "serviceName": "google.cloud.networkservices.v1.NetworkServices", - "rpcName": "GetWasmPluginVersion", + "rpcName": "ListAgentGateways", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = NetworkServicesRestTransport._GetWasmPluginVersion._get_response( + response = NetworkServicesRestTransport._ListAgentGateways._get_response( self._host, metadata, query_params, @@ -8943,21 +9824,23 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = extensibility.WasmPluginVersion() - pb_resp = extensibility.WasmPluginVersion.pb(resp) + resp = agent_gateway.ListAgentGatewaysResponse() + pb_resp = agent_gateway.ListAgentGatewaysResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_get_wasm_plugin_version(resp) + resp = self._interceptor.post_list_agent_gateways(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_get_wasm_plugin_version_with_metadata( + resp, _ = self._interceptor.post_list_agent_gateways_with_metadata( resp, response_metadata ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER try: - response_payload = extensibility.WasmPluginVersion.to_json(response) + response_payload = agent_gateway.ListAgentGatewaysResponse.to_json( + response + ) except: response_payload = None http_response = { @@ -8966,10 +9849,10 @@ def __call__( "status": response.status_code, } _LOGGER.debug( - "Received response for google.cloud.networkservices_v1.NetworkServicesClient.get_wasm_plugin_version", + "Received response for google.cloud.networkservices_v1.NetworkServicesClient.list_agent_gateways", extra={ "serviceName": "google.cloud.networkservices.v1.NetworkServices", - "rpcName": "GetWasmPluginVersion", + "rpcName": "ListAgentGateways", "metadata": http_response["headers"], "httpResponse": http_response, }, @@ -10915,6 +11798,159 @@ def __call__( ) return resp + class _UpdateAgentGateway( + _BaseNetworkServicesRestTransport._BaseUpdateAgentGateway, + NetworkServicesRestStub, + ): + def __hash__(self): + return hash("NetworkServicesRestTransport.UpdateAgentGateway") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: gcn_agent_gateway.UpdateAgentGatewayRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the update agent gateway method over HTTP. + + Args: + request (~.gcn_agent_gateway.UpdateAgentGatewayRequest): + The request object. Request used by the + UpdateAgentGateway 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = _BaseNetworkServicesRestTransport._BaseUpdateAgentGateway._get_http_options() + + request, metadata = self._interceptor.pre_update_agent_gateway( + request, metadata + ) + transcoded_request = _BaseNetworkServicesRestTransport._BaseUpdateAgentGateway._get_transcoded_request( + http_options, request + ) + + body = _BaseNetworkServicesRestTransport._BaseUpdateAgentGateway._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseNetworkServicesRestTransport._BaseUpdateAgentGateway._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.networkservices_v1.NetworkServicesClient.UpdateAgentGateway", + extra={ + "serviceName": "google.cloud.networkservices.v1.NetworkServices", + "rpcName": "UpdateAgentGateway", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = NetworkServicesRestTransport._UpdateAgentGateway._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_update_agent_gateway(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_agent_gateway_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.networkservices_v1.NetworkServicesClient.update_agent_gateway", + extra={ + "serviceName": "google.cloud.networkservices.v1.NetworkServices", + "rpcName": "UpdateAgentGateway", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + class _UpdateEndpointPolicy( _BaseNetworkServicesRestTransport._BaseUpdateEndpointPolicy, NetworkServicesRestStub, @@ -12439,6 +13475,16 @@ def __call__( ) return resp + @property + def create_agent_gateway( + self, + ) -> Callable[ + [gcn_agent_gateway.CreateAgentGatewayRequest], operations_pb2.Operation + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateAgentGateway(self._session, self._host, self._interceptor) # type: ignore + @property def create_endpoint_policy( self, @@ -12537,6 +13583,14 @@ def create_wasm_plugin_version( self._session, self._host, self._interceptor ) # type: ignore + @property + def delete_agent_gateway( + self, + ) -> Callable[[agent_gateway.DeleteAgentGatewayRequest], operations_pb2.Operation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteAgentGateway(self._session, self._host, self._interceptor) # type: ignore + @property def delete_endpoint_policy( self, @@ -12635,6 +13689,14 @@ def delete_wasm_plugin_version( self._session, self._host, self._interceptor ) # type: ignore + @property + def get_agent_gateway( + self, + ) -> Callable[[agent_gateway.GetAgentGatewayRequest], agent_gateway.AgentGateway]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetAgentGateway(self._session, self._host, self._interceptor) # type: ignore + @property def get_endpoint_policy( self, @@ -12743,6 +13805,17 @@ def get_wasm_plugin_version( # In C++ this would require a dynamic_cast return self._GetWasmPluginVersion(self._session, self._host, self._interceptor) # type: ignore + @property + def list_agent_gateways( + self, + ) -> Callable[ + [agent_gateway.ListAgentGatewaysRequest], + agent_gateway.ListAgentGatewaysResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListAgentGateways(self._session, self._host, self._interceptor) # type: ignore + @property def list_endpoint_policies( self, @@ -12872,6 +13945,16 @@ def list_wasm_plugin_versions( self._session, self._host, self._interceptor ) # type: ignore + @property + def update_agent_gateway( + self, + ) -> Callable[ + [gcn_agent_gateway.UpdateAgentGatewayRequest], operations_pb2.Operation + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateAgentGateway(self._session, self._host, self._interceptor) # type: ignore + @property def update_endpoint_policy( self, diff --git a/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/transports/rest_base.py b/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/transports/rest_base.py index f2b00448edec..d8904ad397bd 100644 --- a/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/transports/rest_base.py +++ b/packages/google-cloud-network-services/google/cloud/network_services_v1/services/network_services/transports/rest_base.py @@ -27,6 +27,7 @@ from google.protobuf import json_format from google.cloud.network_services_v1.types import ( + agent_gateway, endpoint_policy, extensibility, gateway, @@ -39,6 +40,7 @@ tcp_route, tls_route, ) +from google.cloud.network_services_v1.types import agent_gateway as gcn_agent_gateway from google.cloud.network_services_v1.types import ( endpoint_policy as gcn_endpoint_policy, ) @@ -120,6 +122,65 @@ def __init__( api_audience=api_audience, ) + class _BaseCreateAgentGateway: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "agentGatewayId": "", + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=projects/*/locations/*}/agentGateways", + "body": "agent_gateway", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = gcn_agent_gateway.CreateAgentGatewayRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseNetworkServicesRestTransport._BaseCreateAgentGateway._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + class _BaseCreateEndpointPolicy: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -769,6 +830,53 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params + class _BaseDeleteAgentGateway: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/v1/{name=projects/*/locations/*/agentGateways/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = agent_gateway.DeleteAgentGatewayRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseNetworkServicesRestTransport._BaseDeleteAgentGateway._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + class _BaseDeleteEndpointPolicy: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -1286,6 +1394,53 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params + class _BaseGetAgentGateway: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=projects/*/locations/*/agentGateways/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = agent_gateway.GetAgentGatewayRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseNetworkServicesRestTransport._BaseGetAgentGateway._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + class _BaseGetEndpointPolicy: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -1897,6 +2052,53 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params + class _BaseListAgentGateways: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=projects/*/locations/*}/agentGateways", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = agent_gateway.ListAgentGatewaysRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseNetworkServicesRestTransport._BaseListAgentGateways._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + class _BaseListEndpointPolicies: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -2508,6 +2710,63 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params + class _BaseUpdateAgentGateway: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v1/{agent_gateway.name=projects/*/locations/*/agentGateways/*}", + "body": "agent_gateway", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = gcn_agent_gateway.UpdateAgentGatewayRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseNetworkServicesRestTransport._BaseUpdateAgentGateway._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + class _BaseUpdateEndpointPolicy: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") diff --git a/packages/google-cloud-network-services/google/cloud/network_services_v1/types/__init__.py b/packages/google-cloud-network-services/google/cloud/network_services_v1/types/__init__.py index 5a1aceb06136..f05745737966 100644 --- a/packages/google-cloud-network-services/google/cloud/network_services_v1/types/__init__.py +++ b/packages/google-cloud-network-services/google/cloud/network_services_v1/types/__init__.py @@ -13,6 +13,15 @@ # See the License for the specific language governing permissions and # limitations under the License. # +from .agent_gateway import ( + AgentGateway, + CreateAgentGatewayRequest, + DeleteAgentGatewayRequest, + GetAgentGatewayRequest, + ListAgentGatewaysRequest, + ListAgentGatewaysResponse, + UpdateAgentGatewayRequest, +) from .common import ( EndpointMatcher, EnvoyHeaders, @@ -21,6 +30,7 @@ ) from .dep import ( AuthzExtension, + BodySendMode, CreateAuthzExtensionRequest, CreateLbEdgeExtensionRequest, CreateLbRouteExtensionRequest, @@ -162,6 +172,13 @@ ) __all__ = ( + "AgentGateway", + "CreateAgentGatewayRequest", + "DeleteAgentGatewayRequest", + "GetAgentGatewayRequest", + "ListAgentGatewaysRequest", + "ListAgentGatewaysResponse", + "UpdateAgentGatewayRequest", "EndpointMatcher", "OperationMetadata", "TrafficPortSelector", @@ -195,6 +212,7 @@ "UpdateLbEdgeExtensionRequest", "UpdateLbRouteExtensionRequest", "UpdateLbTrafficExtensionRequest", + "BodySendMode", "EventType", "LoadBalancingScheme", "WireFormat", diff --git a/packages/google-cloud-network-services/google/cloud/network_services_v1/types/agent_gateway.py b/packages/google-cloud-network-services/google/cloud/network_services_v1/types/agent_gateway.py new file mode 100644 index 000000000000..0bbb0e9f9893 --- /dev/null +++ b/packages/google-cloud-network-services/google/cloud/network_services_v1/types/agent_gateway.py @@ -0,0 +1,515 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import google.protobuf.field_mask_pb2 as field_mask_pb2 # type: ignore +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.networkservices.v1", + manifest={ + "AgentGateway", + "ListAgentGatewaysRequest", + "ListAgentGatewaysResponse", + "GetAgentGatewayRequest", + "CreateAgentGatewayRequest", + "UpdateAgentGatewayRequest", + "DeleteAgentGatewayRequest", + }, +) + + +class AgentGateway(proto.Message): + r"""AgentGateway represents the agent gateway resource. + + 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: + google_managed (google.cloud.network_services_v1.types.AgentGateway.GoogleManaged): + Optional. Proxy is orchestrated and managed + by GoogleCloud in a tenant project. + + This field is a member of `oneof`_ ``deployment_mode``. + self_managed (google.cloud.network_services_v1.types.AgentGateway.SelfManaged): + Optional. Attach to existing Application Load + Balancers or Secure Web Proxies. + + This field is a member of `oneof`_ ``deployment_mode``. + name (str): + Identifier. Name of the AgentGateway resource. It matches + pattern + ``projects/*/locations/*/agentGateways/``. + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The timestamp when the resource + was created. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The timestamp when the resource + was updated. + labels (MutableMapping[str, str]): + Optional. Set of label tags associated with + the AgentGateway resource. + description (str): + Optional. A free-text description of the + resource. Max length 1024 characters. + etag (str): + Optional. Etag of the resource. + If this is provided, it must match the server's + etag. If the provided etag does not match the + server's etag, the request will fail with a 409 + ABORTED error. + protocols (MutableSequence[google.cloud.network_services_v1.types.AgentGateway.Protocol]): + Optional. Deprecated. + registries (MutableSequence[str]): + Optional. A list of Agent registries containing the agents, + MCP servers and tools governed by the Agent Gateway. Note: + Currently limited to project-scoped registries Must be of + format + \`//agentregistry.googleapis.com/projects/{project}/locations/{location}/ + network_config (google.cloud.network_services_v1.types.AgentGateway.NetworkConfig): + Optional. Network configuration for the + AgentGateway. + agent_gateway_card (google.cloud.network_services_v1.types.AgentGateway.AgentGatewayOutputCard): + Output only. Field for populated AgentGateway + card. + """ + + class Protocol(proto.Enum): + r"""Enums of all supported protocols + + Values: + PROTOCOL_UNSPECIFIED (0): + Unspecified protocol. + MCP (1): + Message Control Plane protocol. + """ + + PROTOCOL_UNSPECIFIED = 0 + MCP = 1 + + class GoogleManaged(proto.Message): + r"""Configuration for Google Managed deployment mode. + Proxy is orchestrated and managed by GoogleCloud in a tenant + project. + + Attributes: + governed_access_path (google.cloud.network_services_v1.types.AgentGateway.GoogleManaged.GovernedAccessPath): + Optional. Operating Mode of Agent Gateway. + """ + + class GovernedAccessPath(proto.Enum): + r"""GovernedAccessPath defines the type of access to protect. + + Values: + GOVERNED_ACCESS_PATH_UNSPECIFIED (0): + Governed access path is not specified. + AGENT_TO_ANYWHERE (1): + Govern agent conections to destinations. + CLIENT_TO_AGENT (2): + Protect connection to Agent or Tool. + """ + + GOVERNED_ACCESS_PATH_UNSPECIFIED = 0 + AGENT_TO_ANYWHERE = 1 + CLIENT_TO_AGENT = 2 + + governed_access_path: "AgentGateway.GoogleManaged.GovernedAccessPath" = ( + proto.Field( + proto.ENUM, + number=1, + enum="AgentGateway.GoogleManaged.GovernedAccessPath", + ) + ) + + class SelfManaged(proto.Message): + r"""Configuration for Self Managed deployment mode. + Attach to existing Application Load Balancers or Secure Web + Proxies. + + Attributes: + resource_uri (str): + Optional. A supported Google Cloud networking + proxy in the Project and Location + """ + + resource_uri: str = proto.Field( + proto.STRING, + number=1, + ) + + class NetworkConfig(proto.Message): + r"""NetworkConfig contains network configurations for the + AgentGateway. + + Attributes: + egress (google.cloud.network_services_v1.types.AgentGateway.NetworkConfig.Egress): + Optional. Optional PSC-Interface network + attachment for connectivity to your private VPCs + network. + dns_peering_config (google.cloud.network_services_v1.types.AgentGateway.NetworkConfig.DnsPeeringConfig): + Optional. Optional DNS peering configuration + for connectivity to your private VPC network. + """ + + class Egress(proto.Message): + r"""Configuration for Egress + + Attributes: + network_attachment (str): + Optional. The URI of the Network Attachment + resource. + trust_config (google.cloud.network_services_v1.types.AgentGateway.NetworkConfig.Egress.TrustConfig): + Optional. TrustConfig defines the trust + configuration for egress. + """ + + class TrustConfig(proto.Message): + r"""TrustConfig defines the trust configuration for egress. + + Attributes: + pem_certificates (MutableSequence[str]): + Required. PEM encoded root certificates used + to validate the identity of the upstream + servers/destinations during egress connections. + """ + + pem_certificates: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + + network_attachment: str = proto.Field( + proto.STRING, + number=1, + ) + trust_config: "AgentGateway.NetworkConfig.Egress.TrustConfig" = proto.Field( + proto.MESSAGE, + number=2, + message="AgentGateway.NetworkConfig.Egress.TrustConfig", + ) + + class DnsPeeringConfig(proto.Message): + r"""DNS peering config for the user VPC network. + + Attributes: + domains (MutableSequence[str]): + Required. Domain names for which DNS queries + should be forwarded to the target network. + target_project (str): + Required. Target project ID to which DNS + queries should be forwarded to. This can be the + same project that contains the AgentGateway or a + different project. + target_network (str): + Required. Target network in 'target project' to which DNS + queries should be forwarded to. Must be in format of + ``projects/{project}/global/networks/{network}``. + """ + + domains: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + target_project: str = proto.Field( + proto.STRING, + number=2, + ) + target_network: str = proto.Field( + proto.STRING, + number=3, + ) + + egress: "AgentGateway.NetworkConfig.Egress" = proto.Field( + proto.MESSAGE, + number=1, + message="AgentGateway.NetworkConfig.Egress", + ) + dns_peering_config: "AgentGateway.NetworkConfig.DnsPeeringConfig" = proto.Field( + proto.MESSAGE, + number=2, + message="AgentGateway.NetworkConfig.DnsPeeringConfig", + ) + + class AgentGatewayOutputCard(proto.Message): + r"""AgentGatewayOutputCard contains informational output-only + fields + + Attributes: + mtls_endpoint (str): + Output only. mTLS Endpoint associated with + this AgentGateway + root_certificates (MutableSequence[str]): + Output only. Root Certificates for Agents to + validate this AgentGateway + service_extensions_service_account (str): + Output only. Service Account used by Service + Extensions to operate. + """ + + mtls_endpoint: str = proto.Field( + proto.STRING, + number=1, + ) + root_certificates: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=5, + ) + service_extensions_service_account: str = proto.Field( + proto.STRING, + number=4, + ) + + google_managed: GoogleManaged = proto.Field( + proto.MESSAGE, + number=8, + oneof="deployment_mode", + message=GoogleManaged, + ) + self_managed: SelfManaged = proto.Field( + proto.MESSAGE, + number=9, + oneof="deployment_mode", + message=SelfManaged, + ) + name: str = proto.Field( + proto.STRING, + number=1, + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + labels: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=4, + ) + description: str = proto.Field( + proto.STRING, + number=5, + ) + etag: str = proto.Field( + proto.STRING, + number=6, + ) + protocols: MutableSequence[Protocol] = proto.RepeatedField( + proto.ENUM, + number=12, + enum=Protocol, + ) + registries: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=13, + ) + network_config: NetworkConfig = proto.Field( + proto.MESSAGE, + number=10, + message=NetworkConfig, + ) + agent_gateway_card: AgentGatewayOutputCard = proto.Field( + proto.MESSAGE, + number=11, + message=AgentGatewayOutputCard, + ) + + +class ListAgentGatewaysRequest(proto.Message): + r"""Request used with the ListAgentGateways method. + + Attributes: + parent (str): + Required. The project and location from which the + AgentGateways should be listed, specified in the format + ``projects/*/locations/*``. + page_size (int): + Optional. Maximum number of AgentGateways to + return per call. + page_token (str): + Optional. The value returned by the last + ``ListAgentGatewaysResponse`` Indicates that this is a + continuation of a prior ``ListAgentGateways`` call, and that + the system should return the next page of data. + return_partial_success (bool): + Optional. If true, allow partial responses + for multi-regional Aggregated List requests. + Otherwise if one of the locations is down or + unreachable, the Aggregated List request will + fail. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + return_partial_success: bool = proto.Field( + proto.BOOL, + number=4, + ) + + +class ListAgentGatewaysResponse(proto.Message): + r"""Response returned by the ListAgentGateways method. + + Attributes: + agent_gateways (MutableSequence[google.cloud.network_services_v1.types.AgentGateway]): + List of AgentGateway resources. + next_page_token (str): + If there might be more results than those appearing in this + response, then ``next_page_token`` is included. To get the + next set of results, call this method again using the value + of ``next_page_token`` as ``page_token``. + unreachable (MutableSequence[str]): + Unreachable resources. Populated when the + request attempts to list all resources across + all supported locations, while some locations + are temporarily unavailable. + """ + + @property + def raw_page(self): + return self + + agent_gateways: MutableSequence["AgentGateway"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="AgentGateway", + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + unreachable: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + + +class GetAgentGatewayRequest(proto.Message): + r"""Request used by the GetAgentGateway method. + + Attributes: + name (str): + Required. A name of the AgentGateway to get. Must be in the + format ``projects/*/locations/*/agentGateways/*``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class CreateAgentGatewayRequest(proto.Message): + r"""Request used by the CreateAgentGateway method. + + Attributes: + parent (str): + Required. The parent resource of the AgentGateway. Must be + in the format ``projects/*/locations/*``. + agent_gateway_id (str): + Required. Short name of the AgentGateway + resource to be created. + agent_gateway (google.cloud.network_services_v1.types.AgentGateway): + Required. AgentGateway resource to be + created. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + agent_gateway_id: str = proto.Field( + proto.STRING, + number=2, + ) + agent_gateway: "AgentGateway" = proto.Field( + proto.MESSAGE, + number=3, + message="AgentGateway", + ) + + +class UpdateAgentGatewayRequest(proto.Message): + r"""Request used by the UpdateAgentGateway method. + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Optional. Field mask is used to specify the fields to be + overwritten in the AgentGateway resource by the update. The + fields specified in the update_mask are relative to the + resource, not the full request. A field will be overwritten + if it is in the mask. If the user does not provide a mask + then all fields will be overwritten. + agent_gateway (google.cloud.network_services_v1.types.AgentGateway): + Required. Updated AgentGateway resource. + """ + + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=1, + message=field_mask_pb2.FieldMask, + ) + agent_gateway: "AgentGateway" = proto.Field( + proto.MESSAGE, + number=2, + message="AgentGateway", + ) + + +class DeleteAgentGatewayRequest(proto.Message): + r"""Request used by the DeleteAgentGateway method. + + Attributes: + name (str): + Required. A name of the AgentGateway to delete. Must be in + the format ``projects/*/locations/*/agentGateways/*``. + etag (str): + Optional. The etag of the AgentGateway to + delete. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + etag: str = proto.Field( + proto.STRING, + number=2, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-network-services/google/cloud/network_services_v1/types/common.py b/packages/google-cloud-network-services/google/cloud/network_services_v1/types/common.py index e1afd94a954f..cf13886a1e53 100644 --- a/packages/google-cloud-network-services/google/cloud/network_services_v1/types/common.py +++ b/packages/google-cloud-network-services/google/cloud/network_services_v1/types/common.py @@ -42,9 +42,9 @@ class EnvoyHeaders(proto.Enum): DEBUG_HEADERS (2): Envoy will insert default internal debug headers into upstream requests: - x-envoy-attempt-count x-envoy-is-timeout-retry - x-envoy-expected-rq-timeout-ms - x-envoy-original-path + x-envoy-attempt-count, x-envoy-is-timeout-retry, + x-envoy-expected-rq-timeout-ms, + x-envoy-original-path, x-envoy-upstream-stream-duration-ms """ diff --git a/packages/google-cloud-network-services/google/cloud/network_services_v1/types/dep.py b/packages/google-cloud-network-services/google/cloud/network_services_v1/types/dep.py index ec484aa5bedc..2b04be1e8202 100644 --- a/packages/google-cloud-network-services/google/cloud/network_services_v1/types/dep.py +++ b/packages/google-cloud-network-services/google/cloud/network_services_v1/types/dep.py @@ -29,6 +29,7 @@ "EventType", "LoadBalancingScheme", "WireFormat", + "BodySendMode", "ExtensionChain", "LbTrafficExtension", "ListLbTrafficExtensionsRequest", @@ -132,10 +133,51 @@ class WireFormat(proto.Enum): specified. The backend service for the extension must use HTTP2 or H2C as the protocol. All ``supported_events`` for a client request are sent as part of the same gRPC stream. + EXT_AUTHZ_GRPC (3): + The extension service uses Envoy's ``ext_authz`` gRPC API. + The backend service for the extension must use HTTP2 or H2C + as the protocol. ``EXT_AUTHZ_GRPC`` is only supported for + regional ``AuthzExtension`` resources. """ WIRE_FORMAT_UNSPECIFIED = 0 EXT_PROC_GRPC = 1 + EXT_AUTHZ_GRPC = 3 + + +class BodySendMode(proto.Enum): + r"""The send mode for body processing. + + Values: + BODY_SEND_MODE_UNSPECIFIED (0): + Default value. Do not use. + BODY_SEND_MODE_STREAMED (1): + Calls to the extension are executed in the + streamed mode. Subsequent chunks will be sent + only after the previous chunks have been + processed. + + The content of the body chunks is sent one way + to the extension. Extension may send modified + chunks back. + + This is the default value if the processing mode + is not specified. + BODY_SEND_MODE_FULL_DUPLEX_STREAMED (2): + Calls are executed in the full duplex mode. Subsequent + chunks will be sent for processing without waiting for the + response for the previous chunk or for the response for + ``REQUEST_HEADERS`` event. + + Extension can freely modify or chunk the body contents. If + the extension doesn't send the body contents back, the next + extension in the chain or the upstream will receive an empty + body. + """ + + BODY_SEND_MODE_UNSPECIFIED = 0 + BODY_SEND_MODE_STREAMED = 1 + BODY_SEND_MODE_FULL_DUPLEX_STREAMED = 2 class ExtensionChain(proto.Message): @@ -188,7 +230,7 @@ class Extension(proto.Message): Attributes: name (str): - Required. The name for this extension. + Optional. The name for this extension. The name is logged as part of the HTTP request logs. The name must conform with RFC-1034, is restricted to lower-cased letters, numbers and @@ -196,6 +238,9 @@ class Extension(proto.Message): characters. Additionally, the first character must be a letter and the last a letter or a number. + + This field is required except for + AuthzExtension. authority (str): Optional. The ``:authority`` header in the gRPC request sent from Envoy to the extension service. Required for Callout @@ -239,6 +284,11 @@ class Extension(proto.Message): For the ``LbEdgeExtension`` resource, this field is required and must only contain ``REQUEST_HEADERS`` event. + + For the ``AuthzExtension`` resource, this field is optional. + ``REQUEST_HEADERS`` is the only supported event. If + unspecified, ``REQUEST_HEADERS`` event is assumed as + supported. timeout (google.protobuf.duration_pb2.Duration): Optional. Specifies the timeout for each individual message on the stream. The timeout must be between ``10``-``10000`` @@ -268,13 +318,27 @@ class Extension(proto.Message): to the extension (from the client or backend). If omitted, all headers are sent. Each element is a string indicating the header name. + forward_attributes (MutableSequence[str]): + Optional. List of the Envoy attributes to forward to the + extension server. The attributes provided here are included + as part of the ``ProcessingRequest.attributes`` field (of + type ``map``), where the + keys are the attribute names. Refer to the + `documentation `__ + for the names of attributes that can be forwarded. If + omitted, no attributes are sent. Each element is a string + indicating the attribute name. metadata (google.protobuf.struct_pb2.Struct): Optional. The metadata provided here is included as part of the ``metadata_context`` (of type ``google.protobuf.Struct``) in the ``ProcessingRequest`` message sent to the extension server. - The metadata is available under the namespace + For ``AuthzExtension`` resources, the metadata is available + under the namespace + ``com.google.authz_extension.``. For other + types of extensions, the metadata is available under the + namespace ``com.google....``. For example: ``com.google.lb_traffic_extension.lbtrafficextension1.chain1.ext1``. @@ -301,6 +365,49 @@ class Extension(proto.Message): - The length of each value must be less than 1024 characters. - All values must be strings. + request_body_send_mode (google.cloud.network_services_v1.types.BodySendMode): + Optional. Configures the send mode for request body + processing. + + The field can only be set if ``supported_events`` includes + ``REQUEST_BODY``. If ``supported_events`` includes + ``REQUEST_BODY``, but ``request_body_send_mode`` is unset, + the default value ``STREAMED`` is used. + + When this field is set to ``FULL_DUPLEX_STREAMED``, + ``supported_events`` must include both ``REQUEST_BODY`` and + ``REQUEST_TRAILERS``. + + This field can be set only for ``LbTrafficExtension`` and + ``LbRouteExtension`` resources, and only when the + ``service`` field of the extension points to a + ``BackendService``. Only ``FULL_DUPLEX_STREAMED`` mode is + supported for ``LbRouteExtension`` resources. + response_body_send_mode (google.cloud.network_services_v1.types.BodySendMode): + Optional. Configures the send mode for response processing. + If unspecified, the default value ``STREAMED`` is used. + + The field can only be set if ``supported_events`` includes + ``RESPONSE_BODY``. If ``supported_events`` includes + ``RESPONSE_BODY``, but ``response_body_send_mode`` is unset, + the default value ``STREAMED`` is used. + + When this field is set to ``FULL_DUPLEX_STREAMED``, + ``supported_events`` must include both ``RESPONSE_BODY`` and + ``RESPONSE_TRAILERS``. + + This field can be set only for ``LbTrafficExtension`` + resources, and only when the ``service`` field of the + extension points to a ``BackendService``. + observability_mode (bool): + Optional. When set to ``true``, the calls to the extension + backend are performed asynchronously, without pausing the + processing of the ongoing request. In this mode, only + ``STREAMED`` (default) body processing is supported. + Responses, if any, are ignored. + + Supported by regional ``LbTrafficExtension`` and + ``LbRouteExtension`` resources. """ name: str = proto.Field( @@ -333,11 +440,29 @@ class Extension(proto.Message): proto.STRING, number=7, ) + forward_attributes: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=8, + ) metadata: struct_pb2.Struct = proto.Field( proto.MESSAGE, number=9, message=struct_pb2.Struct, ) + request_body_send_mode: "BodySendMode" = proto.Field( + proto.ENUM, + number=14, + enum="BodySendMode", + ) + response_body_send_mode: "BodySendMode" = proto.Field( + proto.ENUM, + number=15, + enum="BodySendMode", + ) + observability_mode: bool = proto.Field( + proto.BOOL, + number=16, + ) name: str = proto.Field( proto.STRING, @@ -1401,15 +1526,18 @@ class AuthzExtension(proto.Message): labels `__ for Google Cloud resources. load_balancing_scheme (google.cloud.network_services_v1.types.LoadBalancingScheme): - Required. All backend services and forwarding rules + Optional. All backend services and forwarding rules referenced by this extension must share the same load balancing scheme. Supported values: ``INTERNAL_MANAGED``, - ``EXTERNAL_MANAGED``. For more information, refer to - `Backend services + ``EXTERNAL_MANAGED``. Can be omitted for AuthzExtensions + that do not reference a backend service. For more + information, refer to `Backend services overview `__. authority (str): - Required. The ``:authority`` header in the gRPC request sent - from Envoy to the extension service. + Optional. The ``:authority`` header in the gRPC request sent + from Envoy to the extension service. It is required when the + ``service`` field points to a backend service or a wasm + plugin. service (str): Required. The reference to the service that runs the extension. @@ -1458,10 +1586,22 @@ class AuthzExtension(proto.Message): to the extension (from the client). If omitted, all headers are sent. Each element is a string indicating the header name. + forward_attributes (MutableSequence[str]): + Optional. List of the Envoy attributes to forward to the + extension server. The attributes provided here are included + as part of the ``ProcessingRequest.attributes`` field (of + type ``map``), where the + keys are the attribute names. Refer to the + `documentation `__ + for the names of attributes that can be forwarded. If + omitted, no attributes are sent. Each element is a string + indicating the attribute name. wire_format (google.cloud.network_services_v1.types.WireFormat): Optional. The format of communication supported by the - callout extension. If not specified, the default value - ``EXT_PROC_GRPC`` is used. + callout extension. This field is supported only for regional + ``AuthzExtension`` resources. If not specified, the default + value ``EXT_PROC_GRPC`` is used. Global ``AuthzExtension`` + resources use the ``EXT_PROC_GRPC`` wire format. """ name: str = proto.Field( @@ -1518,6 +1658,10 @@ class AuthzExtension(proto.Message): proto.STRING, number=12, ) + forward_attributes: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=13, + ) wire_format: "WireFormat" = proto.Field( proto.ENUM, number=14, diff --git a/packages/google-cloud-network-services/google/cloud/network_services_v1/types/endpoint_policy.py b/packages/google-cloud-network-services/google/cloud/network_services_v1/types/endpoint_policy.py index 23283388dbf7..9038e860f3c5 100644 --- a/packages/google-cloud-network-services/google/cloud/network_services_v1/types/endpoint_policy.py +++ b/packages/google-cloud-network-services/google/cloud/network_services_v1/types/endpoint_policy.py @@ -47,7 +47,7 @@ class EndpointPolicy(proto.Message): name (str): Identifier. Name of the EndpointPolicy resource. It matches pattern - ``projects/{project}/locations/global/endpointPolicies/{endpoint_policy}``. + ``projects/{project}/locations/*/endpointPolicies/{endpoint_policy}``. create_time (google.protobuf.timestamp_pb2.Timestamp): Output only. The timestamp when the resource was created. @@ -173,7 +173,7 @@ class ListEndpointPoliciesRequest(proto.Message): parent (str): Required. The project and location from which the EndpointPolicies should be listed, specified in the format - ``projects/*/locations/global``. + ``projects/*/locations/*``. page_size (int): Maximum number of EndpointPolicies to return per call. @@ -251,8 +251,7 @@ class GetEndpointPolicyRequest(proto.Message): Attributes: name (str): Required. A name of the EndpointPolicy to get. Must be in - the format - ``projects/*/locations/global/endpointPolicies/*``. + the format ``projects/*/locations/*/endpointPolicies/*``. """ name: str = proto.Field( @@ -267,7 +266,7 @@ class CreateEndpointPolicyRequest(proto.Message): Attributes: parent (str): Required. The parent resource of the EndpointPolicy. Must be - in the format ``projects/*/locations/global``. + in the format ``projects/*/locations/*``. endpoint_policy_id (str): Required. Short name of the EndpointPolicy resource to be created. E.g. "CustomECS". @@ -324,8 +323,7 @@ class DeleteEndpointPolicyRequest(proto.Message): Attributes: name (str): Required. A name of the EndpointPolicy to delete. Must be in - the format - ``projects/*/locations/global/endpointPolicies/*``. + the format ``projects/*/locations/*/endpointPolicies/*``. """ name: str = proto.Field( diff --git a/packages/google-cloud-network-services/google/cloud/network_services_v1/types/extensibility.py b/packages/google-cloud-network-services/google/cloud/network_services_v1/types/extensibility.py index 9652bf63ef2f..607d5ada166c 100644 --- a/packages/google-cloud-network-services/google/cloud/network_services_v1/types/extensibility.py +++ b/packages/google-cloud-network-services/google/cloud/network_services_v1/types/extensibility.py @@ -148,11 +148,27 @@ class VersionDetails(proto.Message): plugin_config_uri (str): URI of the plugin configuration stored in the Artifact Registry. The configuration is provided to the plugin at - runtime through the ``ON_CONFIGURE`` callback. The container - image must contain only a single file with the name - ``plugin.config``. When a new ``WasmPluginVersion`` resource - is created, the digest of the container image is saved in - the ``plugin_config_digest`` field. + runtime through the ``ON_CONFIGURE`` callback. + + The URI can refer to one of the following repository + formats: + + - Container images: the ``plugin_config_uri`` must point to + a container that contains a single file with the name + ``plugin.config``. When a new ``WasmPluginVersion`` + resource is created, the digest of the image is saved in + the ``plugin_config_digest`` field. When pulling a + container image from Artifact Registry, the digest value + is used instead of an image tag. + + - Generic artifacts: the ``plugin_config_uri`` must be in + this format: + ``projects/{project}/locations/{location}/repositories/{repository}/ genericArtifacts/{package}:{version}``. + The specified package and version must contain a file with + the name ``plugin.config``. When a new + ``WasmPluginVersion`` resource is created, the checksum of + the contents of the file is saved in the + ``plugin_config_digest`` field. This field is a member of `oneof`_ ``plugin_config_source``. create_time (google.protobuf.timestamp_pb2.Timestamp): @@ -168,24 +184,40 @@ class VersionDetails(proto.Message): Optional. Set of labels associated with the ``WasmPluginVersion`` resource. image_uri (str): - Optional. URI of the container image containing the Wasm - module, stored in the Artifact Registry. The container image - must contain only a single file with the name - ``plugin.wasm``. When a new ``WasmPluginVersion`` resource - is created, the URI gets resolved to an image digest and - saved in the ``image_digest`` field. + Optional. URI of the image containing the Wasm module, + stored in Artifact Registry. + + The URI can refer to one of the following repository + formats: + + - Container images: the ``image_uri`` must point to a + container that contains a single file with the name + ``plugin.wasm``. When a new ``WasmPluginVersion`` resource + is created, the digest of the image is saved in the + ``image_digest`` field. When pulling a container image + from Artifact Registry, the digest value is used instead + of an image tag. + + - Generic artifacts: the ``image_uri`` must be in this + format: + ``projects/{project}/locations/{location}/repositories/{repository}/ genericArtifacts/{package}:{version}``. + The specified package and version must contain a file with + the name ``plugin.wasm``. When a new ``WasmPluginVersion`` + resource is created, the checksum of the contents of the + file is saved in the ``image_digest`` field. image_digest (str): - Output only. The resolved digest for the image specified in - ``image``. The digest is resolved during the creation of a - ``WasmPluginVersion`` resource. This field holds the digest - value regardless of whether a tag or digest was originally - specified in the ``image`` field. + Output only. This field holds the digest (usually checksum) + value for the plugin image. The value is calculated based on + the ``image_uri`` field. If the ``image_uri`` field refers + to a container image, the digest value is obtained from the + container image. If the ``image_uri`` field refers to a + generic artifact, the digest value is calculated based on + the contents of the file. plugin_config_digest (str): Output only. This field holds the digest (usually checksum) value for the plugin configuration. The value is calculated - based on the contents of the ``plugin_config_data`` field or - the container image defined by the ``plugin_config_uri`` - field. + based on the contents of ``plugin_config_data`` field or the + image defined by the ``plugin_config_uri`` field. """ plugin_config_data: bytes = proto.Field( @@ -255,8 +287,8 @@ class LogConfig(proto.Message): This field can be specified only if logging is enabled for this plugin. min_log_level (google.cloud.network_services_v1.types.WasmPlugin.LogConfig.LogLevel): - Non-empty default. Specificies the lowest level of the - plugin logs that are exported to Cloud Logging. This setting + Non-empty default. Specifies the lowest level of the plugin + logs that are exported to Cloud Logging. This setting relates to the logs generated by using logging statements in your Wasm code. @@ -393,11 +425,27 @@ class WasmPluginVersion(proto.Message): plugin_config_uri (str): URI of the plugin configuration stored in the Artifact Registry. The configuration is provided to the plugin at - runtime through the ``ON_CONFIGURE`` callback. The container - image must contain only a single file with the name - ``plugin.config``. When a new ``WasmPluginVersion`` resource - is created, the digest of the container image is saved in - the ``plugin_config_digest`` field. + runtime through the ``ON_CONFIGURE`` callback. + + The URI can refer to one of the following repository + formats: + + - Container images: the ``plugin_config_uri`` must point to + a container that contains a single file with the name + ``plugin.config``. When a new ``WasmPluginVersion`` + resource is created, the digest of the image is saved in + the ``plugin_config_digest`` field. When pulling a + container image from Artifact Registry, the digest value + is used instead of an image tag. + + - Generic artifacts: the ``plugin_config_uri`` must be in + this format: + ``projects/{project}/locations/{location}/repositories/{repository}/ genericArtifacts/{package}:{version}``. + The specified package and version must contain a file with + the name ``plugin.config``. When a new + ``WasmPluginVersion`` resource is created, the checksum of + the contents of the file is saved in the + ``plugin_config_digest`` field. This field is a member of `oneof`_ ``plugin_config_source``. name (str): @@ -417,23 +465,40 @@ class WasmPluginVersion(proto.Message): Optional. Set of labels associated with the ``WasmPluginVersion`` resource. image_uri (str): - Optional. URI of the container image containing the plugin, - stored in the Artifact Registry. When a new - ``WasmPluginVersion`` resource is created, the digest of the - container image is saved in the ``image_digest`` field. When - downloading an image, the digest value is used instead of an - image tag. + Optional. URI of the image containing the Wasm module, + stored in Artifact Registry. + + The URI can refer to one of the following repository + formats: + + - Container images: the ``image_uri`` must point to a + container that contains a single file with the name + ``plugin.wasm``. When a new ``WasmPluginVersion`` resource + is created, the digest of the image is saved in the + ``image_digest`` field. When pulling a container image + from Artifact Registry, the digest value is used instead + of an image tag. + + - Generic artifacts: the ``image_uri`` must be in this + format: + ``projects/{project}/locations/{location}/repositories/{repository}/ genericArtifacts/{package}:{version}``. + The specified package and version must contain a file with + the name ``plugin.wasm``. When a new ``WasmPluginVersion`` + resource is created, the checksum of the contents of the + file is saved in the ``image_digest`` field. image_digest (str): - Output only. The resolved digest for the image specified in - the ``image`` field. The digest is resolved during the - creation of ``WasmPluginVersion`` resource. This field holds - the digest value, regardless of whether a tag or digest was - originally specified in the ``image`` field. + Output only. This field holds the digest (usually checksum) + value for the plugin image. The value is calculated based on + the ``image_uri`` field. If the ``image_uri`` field refers + to a container image, the digest value is obtained from the + container image. If the ``image_uri`` field refers to a + generic artifact, the digest value is calculated based on + the contents of the file. plugin_config_digest (str): Output only. This field holds the digest (usually checksum) value for the plugin configuration. The value is calculated - based on the contents of ``plugin_config_data`` or the - container image defined by the ``plugin_config_uri`` field. + based on the contents of ``plugin_config_data`` field or the + image defined by the ``plugin_config_uri`` field. """ plugin_config_data: bytes = proto.Field( diff --git a/packages/google-cloud-network-services/google/cloud/network_services_v1/types/gateway.py b/packages/google-cloud-network-services/google/cloud/network_services_v1/types/gateway.py index b879ce113b1c..2dfde174e7b5 100644 --- a/packages/google-cloud-network-services/google/cloud/network_services_v1/types/gateway.py +++ b/packages/google-cloud-network-services/google/cloud/network_services_v1/types/gateway.py @@ -82,8 +82,12 @@ class Gateway(proto.Message): Required. One or more port numbers (1-65535), on which the Gateway will receive traffic. The proxy binds to the specified ports. Gateways of type 'SECURE_WEB_GATEWAY' are - limited to 1 port. Gateways of type 'OPEN_MESH' listen on + limited to 5 ports. Gateways of type 'OPEN_MESH' listen on 0.0.0.0 for IPv4 and :: for IPv6 and support multiple ports. + all_ports (bool): + Optional. If true, the Gateway will listen on all ports. + This is mutually exclusive with the ``ports`` field. This + field only applies to gateways of type 'SECURE_WEB_GATEWAY'. scope (str): Optional. Scope determines how configuration across multiple Gateway instances are merged. @@ -146,6 +150,11 @@ class Gateway(proto.Message): configurable only for gateways of type SECURE_WEB_GATEWAY. This field is required for gateways of type SECURE_WEB_GATEWAY. + allow_global_access (bool): + Optional. If true, the gateway will allow traffic from + clients outside of the region where the gateway is located. + This field is configurable only for gateways of type + SECURE_WEB_GATEWAY. """ class Type(proto.Enum): @@ -255,6 +264,10 @@ class RoutingMode(proto.Enum): proto.INT32, number=11, ) + all_ports: bool = proto.Field( + proto.BOOL, + number=34, + ) scope: str = proto.Field( proto.STRING, number=8, @@ -295,6 +308,10 @@ class RoutingMode(proto.Enum): number=32, enum=RoutingMode, ) + allow_global_access: bool = proto.Field( + proto.BOOL, + number=33, + ) class ListGatewaysRequest(proto.Message): diff --git a/packages/google-cloud-network-services/google/cloud/network_services_v1/types/grpc_route.py b/packages/google-cloud-network-services/google/cloud/network_services_v1/types/grpc_route.py index 54e025159223..58be9e7c3749 100644 --- a/packages/google-cloud-network-services/google/cloud/network_services_v1/types/grpc_route.py +++ b/packages/google-cloud-network-services/google/cloud/network_services_v1/types/grpc_route.py @@ -44,7 +44,7 @@ class GrpcRoute(proto.Message): name (str): Identifier. Name of the GrpcRoute resource. It matches pattern - ``projects/*/locations/global/grpcRoutes/`` + ``projects/*/locations/*/grpcRoutes/`` self_link (str): Output only. Server-defined URL of this resource @@ -106,14 +106,14 @@ class GrpcRoute(proto.Message): requests served by the mesh. Each mesh reference should match the pattern: - ``projects/*/locations/global/meshes/`` + ``projects/*/locations/*/meshes/`` gateways (MutableSequence[str]): Optional. Gateways defines a list of gateways this GrpcRoute is attached to, as one of the routing rules to route the requests served by the gateway. Each gateway reference should match the pattern: - ``projects/*/locations/global/gateways/`` + ``projects/*/locations/*/gateways/`` rules (MutableSequence[google.cloud.network_services_v1.types.GrpcRoute.RouteRule]): Required. A list of detailed rules defining how to route traffic. @@ -633,7 +633,7 @@ class ListGrpcRoutesRequest(proto.Message): parent (str): Required. The project and location from which the GrpcRoutes should be listed, specified in the format - ``projects/*/locations/global``. + ``projects/*/locations/*``. page_size (int): Maximum number of GrpcRoutes to return per call. @@ -711,7 +711,7 @@ class GetGrpcRouteRequest(proto.Message): Attributes: name (str): Required. A name of the GrpcRoute to get. Must be in the - format ``projects/*/locations/global/grpcRoutes/*``. + format ``projects/*/locations/*/grpcRoutes/*``. """ name: str = proto.Field( @@ -726,7 +726,7 @@ class CreateGrpcRouteRequest(proto.Message): Attributes: parent (str): Required. The parent resource of the GrpcRoute. Must be in - the format ``projects/*/locations/global``. + the format ``projects/*/locations/*``. grpc_route_id (str): Required. Short name of the GrpcRoute resource to be created. @@ -782,7 +782,7 @@ class DeleteGrpcRouteRequest(proto.Message): Attributes: name (str): Required. A name of the GrpcRoute to delete. Must be in the - format ``projects/*/locations/global/grpcRoutes/*``. + format ``projects/*/locations/*/grpcRoutes/*``. """ name: str = proto.Field( diff --git a/packages/google-cloud-network-services/google/cloud/network_services_v1/types/http_route.py b/packages/google-cloud-network-services/google/cloud/network_services_v1/types/http_route.py index 0dbd3ef1cd51..b4cc52fd59aa 100644 --- a/packages/google-cloud-network-services/google/cloud/network_services_v1/types/http_route.py +++ b/packages/google-cloud-network-services/google/cloud/network_services_v1/types/http_route.py @@ -44,7 +44,7 @@ class HttpRoute(proto.Message): name (str): Identifier. Name of the HttpRoute resource. It matches pattern - ``projects/*/locations/global/httpRoutes/http_route_name>``. + ``projects/*/locations/*/httpRoutes/http_route_name>``. self_link (str): Output only. Server-defined URL of this resource @@ -95,7 +95,7 @@ class HttpRoute(proto.Message): requests served by the mesh. Each mesh reference should match the pattern: - ``projects/*/locations/global/meshes/`` + ``projects/*/locations/*/meshes/`` The attached Mesh should be of a type SIDECAR gateways (MutableSequence[str]): @@ -104,7 +104,7 @@ class HttpRoute(proto.Message): requests served by the gateway. Each gateway reference should match the pattern: - ``projects/*/locations/global/gateways/`` + ``projects/*/locations/*/gateways/`` labels (MutableMapping[str, str]): Optional. Set of label tags associated with the HttpRoute resource. @@ -1120,7 +1120,7 @@ class ListHttpRoutesRequest(proto.Message): parent (str): Required. The project and location from which the HttpRoutes should be listed, specified in the format - ``projects/*/locations/global``. + ``projects/*/locations/*``. page_size (int): Maximum number of HttpRoutes to return per call. @@ -1135,6 +1135,9 @@ class ListHttpRoutesRequest(proto.Message): Otherwise if one of the locations is down or unreachable, the Aggregated List request will fail. + filter (str): + Optional. Filter expression to restrict the + list. """ parent: str = proto.Field( @@ -1153,6 +1156,10 @@ class ListHttpRoutesRequest(proto.Message): proto.BOOL, number=4, ) + filter: str = proto.Field( + proto.STRING, + number=5, + ) class ListHttpRoutesResponse(proto.Message): @@ -1198,7 +1205,7 @@ class GetHttpRouteRequest(proto.Message): Attributes: name (str): Required. A name of the HttpRoute to get. Must be in the - format ``projects/*/locations/global/httpRoutes/*``. + format ``projects/*/locations/*/httpRoutes/*``. """ name: str = proto.Field( @@ -1213,12 +1220,14 @@ class CreateHttpRouteRequest(proto.Message): Attributes: parent (str): Required. The parent resource of the HttpRoute. Must be in - the format ``projects/*/locations/global``. + the format ``projects/*/locations/*``. http_route_id (str): Required. Short name of the HttpRoute resource to be created. http_route (google.cloud.network_services_v1.types.HttpRoute): Required. HttpRoute resource to be created. + request_id (str): + Optional. Idempotent request UUID. """ parent: str = proto.Field( @@ -1234,6 +1243,10 @@ class CreateHttpRouteRequest(proto.Message): number=3, message="HttpRoute", ) + request_id: str = proto.Field( + proto.STRING, + number=4, + ) class UpdateHttpRouteRequest(proto.Message): @@ -1269,7 +1282,7 @@ class DeleteHttpRouteRequest(proto.Message): Attributes: name (str): Required. A name of the HttpRoute to delete. Must be in the - format ``projects/*/locations/global/httpRoutes/*``. + format ``projects/*/locations/*/httpRoutes/*``. """ name: str = proto.Field( diff --git a/packages/google-cloud-network-services/google/cloud/network_services_v1/types/mesh.py b/packages/google-cloud-network-services/google/cloud/network_services_v1/types/mesh.py index 68245ca40b68..7da44a79c75e 100644 --- a/packages/google-cloud-network-services/google/cloud/network_services_v1/types/mesh.py +++ b/packages/google-cloud-network-services/google/cloud/network_services_v1/types/mesh.py @@ -49,7 +49,7 @@ class Mesh(proto.Message): Attributes: name (str): Identifier. Name of the Mesh resource. It matches pattern - ``projects/*/locations/global/meshes/``. + ``projects/*/locations/*/meshes/``. self_link (str): Output only. Server-defined URL of this resource @@ -131,7 +131,7 @@ class ListMeshesRequest(proto.Message): parent (str): Required. The project and location from which the Meshes should be listed, specified in the format - ``projects/*/locations/global``. + ``projects/*/locations/*``. page_size (int): Maximum number of Meshes to return per call. page_token (str): @@ -208,7 +208,7 @@ class GetMeshRequest(proto.Message): Attributes: name (str): Required. A name of the Mesh to get. Must be in the format - ``projects/*/locations/global/meshes/*``. + ``projects/*/locations/*/meshes/*``. """ name: str = proto.Field( @@ -223,7 +223,7 @@ class CreateMeshRequest(proto.Message): Attributes: parent (str): Required. The parent resource of the Mesh. Must be in the - format ``projects/*/locations/global``. + format ``projects/*/locations/*``. mesh_id (str): Required. Short name of the Mesh resource to be created. @@ -279,7 +279,7 @@ class DeleteMeshRequest(proto.Message): Attributes: name (str): Required. A name of the Mesh to delete. Must be in the - format ``projects/*/locations/global/meshes/*``. + format ``projects/*/locations/*/meshes/*``. """ name: str = proto.Field( diff --git a/packages/google-cloud-network-services/google/cloud/network_services_v1/types/tcp_route.py b/packages/google-cloud-network-services/google/cloud/network_services_v1/types/tcp_route.py index 228cbc753905..8d95d7e8fdf5 100644 --- a/packages/google-cloud-network-services/google/cloud/network_services_v1/types/tcp_route.py +++ b/packages/google-cloud-network-services/google/cloud/network_services_v1/types/tcp_route.py @@ -44,7 +44,7 @@ class TcpRoute(proto.Message): name (str): Identifier. Name of the TcpRoute resource. It matches pattern - ``projects/*/locations/global/tcpRoutes/tcp_route_name>``. + ``projects/*/locations/*/tcpRoutes/tcp_route_name>``. self_link (str): Output only. Server-defined URL of this resource @@ -69,7 +69,7 @@ class TcpRoute(proto.Message): requests served by the mesh. Each mesh reference should match the pattern: - ``projects/*/locations/global/meshes/`` + ``projects/*/locations/*/meshes/`` The attached Mesh should be of a type SIDECAR gateways (MutableSequence[str]): @@ -78,7 +78,7 @@ class TcpRoute(proto.Message): requests served by the gateway. Each gateway reference should match the pattern: - ``projects/*/locations/global/gateways/`` + ``projects/*/locations/*/gateways/`` labels (MutableMapping[str, str]): Optional. Set of label tags associated with the TcpRoute resource. @@ -276,7 +276,7 @@ class ListTcpRoutesRequest(proto.Message): parent (str): Required. The project and location from which the TcpRoutes should be listed, specified in the format - ``projects/*/locations/global``. + ``projects/*/locations/*``. page_size (int): Maximum number of TcpRoutes to return per call. @@ -354,7 +354,7 @@ class GetTcpRouteRequest(proto.Message): Attributes: name (str): Required. A name of the TcpRoute to get. Must be in the - format ``projects/*/locations/global/tcpRoutes/*``. + format ``projects/*/locations/*/tcpRoutes/*``. """ name: str = proto.Field( @@ -369,7 +369,7 @@ class CreateTcpRouteRequest(proto.Message): Attributes: parent (str): Required. The parent resource of the TcpRoute. Must be in - the format ``projects/*/locations/global``. + the format ``projects/*/locations/*``. tcp_route_id (str): Required. Short name of the TcpRoute resource to be created. @@ -425,7 +425,7 @@ class DeleteTcpRouteRequest(proto.Message): Attributes: name (str): Required. A name of the TcpRoute to delete. Must be in the - format ``projects/*/locations/global/tcpRoutes/*``. + format ``projects/*/locations/*/tcpRoutes/*``. """ name: str = proto.Field( diff --git a/packages/google-cloud-network-services/google/cloud/network_services_v1/types/tls_route.py b/packages/google-cloud-network-services/google/cloud/network_services_v1/types/tls_route.py index 4c910bcd69cd..25219e4699dd 100644 --- a/packages/google-cloud-network-services/google/cloud/network_services_v1/types/tls_route.py +++ b/packages/google-cloud-network-services/google/cloud/network_services_v1/types/tls_route.py @@ -44,7 +44,7 @@ class TlsRoute(proto.Message): name (str): Identifier. Name of the TlsRoute resource. It matches pattern - ``projects/*/locations/global/tlsRoutes/tls_route_name>``. + ``projects/*/locations/*/tlsRoutes/tls_route_name>``. self_link (str): Output only. Server-defined URL of this resource @@ -69,7 +69,7 @@ class TlsRoute(proto.Message): requests served by the mesh. Each mesh reference should match the pattern: - ``projects/*/locations/global/meshes/`` + ``projects/*/locations/*/meshes/`` The attached Mesh should be of a type SIDECAR gateways (MutableSequence[str]): @@ -78,7 +78,14 @@ class TlsRoute(proto.Message): requests served by the gateway. Each gateway reference should match the pattern: - ``projects/*/locations/global/gateways/`` + ``projects/*/locations/*/gateways/`` + target_proxies (MutableSequence[str]): + Optional. TargetProxies defines a list of TargetTcpProxies + this TlsRoute is attached to, as one of the routing rules to + route the requests served by the TargetTcpProxy. + + Each TargetTcpProxy reference should match the pattern: + ``projects/*/locations/*/targetTcpProxies/`` labels (MutableMapping[str, str]): Optional. Set of label tags associated with the TlsRoute resource. @@ -232,6 +239,10 @@ class RouteDestination(proto.Message): proto.STRING, number=7, ) + target_proxies: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=13, + ) labels: MutableMapping[str, str] = proto.MapField( proto.STRING, proto.STRING, @@ -246,7 +257,7 @@ class ListTlsRoutesRequest(proto.Message): parent (str): Required. The project and location from which the TlsRoutes should be listed, specified in the format - ``projects/*/locations/global``. + ``projects/*/locations/*``. page_size (int): Maximum number of TlsRoutes to return per call. @@ -324,7 +335,7 @@ class GetTlsRouteRequest(proto.Message): Attributes: name (str): Required. A name of the TlsRoute to get. Must be in the - format ``projects/*/locations/global/tlsRoutes/*``. + format ``projects/*/locations/*/tlsRoutes/*``. """ name: str = proto.Field( @@ -339,7 +350,7 @@ class CreateTlsRouteRequest(proto.Message): Attributes: parent (str): Required. The parent resource of the TlsRoute. Must be in - the format ``projects/*/locations/global``. + the format ``projects/*/locations/*``. tls_route_id (str): Required. Short name of the TlsRoute resource to be created. @@ -395,7 +406,7 @@ class DeleteTlsRouteRequest(proto.Message): Attributes: name (str): Required. A name of the TlsRoute to delete. Must be in the - format ``projects/*/locations/global/tlsRoutes/*``. + format ``projects/*/locations/*/tlsRoutes/*``. """ name: str = proto.Field( diff --git a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_authz_extension_async.py b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_authz_extension_async.py index 2ef94239f3b7..3846293fab42 100644 --- a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_authz_extension_async.py +++ b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_authz_extension_async.py @@ -41,8 +41,6 @@ async def sample_create_authz_extension(): # Initialize request argument(s) authz_extension = network_services_v1.AuthzExtension() authz_extension.name = "name_value" - authz_extension.load_balancing_scheme = "EXTERNAL_MANAGED" - authz_extension.authority = "authority_value" authz_extension.service = "service_value" request = network_services_v1.CreateAuthzExtensionRequest( diff --git a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_authz_extension_sync.py b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_authz_extension_sync.py index 0e194e957bc7..4cf7ffd27337 100644 --- a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_authz_extension_sync.py +++ b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_authz_extension_sync.py @@ -41,8 +41,6 @@ def sample_create_authz_extension(): # Initialize request argument(s) authz_extension = network_services_v1.AuthzExtension() authz_extension.name = "name_value" - authz_extension.load_balancing_scheme = "EXTERNAL_MANAGED" - authz_extension.authority = "authority_value" authz_extension.service = "service_value" request = network_services_v1.CreateAuthzExtensionRequest( diff --git a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_lb_edge_extension_async.py b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_lb_edge_extension_async.py index f625cf6a5af5..1dc5756e2282 100644 --- a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_lb_edge_extension_async.py +++ b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_lb_edge_extension_async.py @@ -49,7 +49,6 @@ async def sample_create_lb_edge_extension(): lb_edge_extension.extension_chains.match_condition.cel_expression = ( "cel_expression_value" ) - lb_edge_extension.extension_chains.extensions.name = "name_value" lb_edge_extension.extension_chains.extensions.service = "service_value" lb_edge_extension.load_balancing_scheme = "EXTERNAL_MANAGED" diff --git a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_lb_edge_extension_sync.py b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_lb_edge_extension_sync.py index cf6982908d3e..ecb1e28837e2 100644 --- a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_lb_edge_extension_sync.py +++ b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_lb_edge_extension_sync.py @@ -49,7 +49,6 @@ def sample_create_lb_edge_extension(): lb_edge_extension.extension_chains.match_condition.cel_expression = ( "cel_expression_value" ) - lb_edge_extension.extension_chains.extensions.name = "name_value" lb_edge_extension.extension_chains.extensions.service = "service_value" lb_edge_extension.load_balancing_scheme = "EXTERNAL_MANAGED" diff --git a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_lb_route_extension_async.py b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_lb_route_extension_async.py index 089086ce9992..bc8e15df293b 100644 --- a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_lb_route_extension_async.py +++ b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_lb_route_extension_async.py @@ -49,7 +49,6 @@ async def sample_create_lb_route_extension(): lb_route_extension.extension_chains.match_condition.cel_expression = ( "cel_expression_value" ) - lb_route_extension.extension_chains.extensions.name = "name_value" lb_route_extension.extension_chains.extensions.service = "service_value" lb_route_extension.load_balancing_scheme = "EXTERNAL_MANAGED" diff --git a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_lb_route_extension_sync.py b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_lb_route_extension_sync.py index d6e429c371a0..557a6ea5c982 100644 --- a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_lb_route_extension_sync.py +++ b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_lb_route_extension_sync.py @@ -49,7 +49,6 @@ def sample_create_lb_route_extension(): lb_route_extension.extension_chains.match_condition.cel_expression = ( "cel_expression_value" ) - lb_route_extension.extension_chains.extensions.name = "name_value" lb_route_extension.extension_chains.extensions.service = "service_value" lb_route_extension.load_balancing_scheme = "EXTERNAL_MANAGED" diff --git a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_lb_traffic_extension_async.py b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_lb_traffic_extension_async.py index db6dee246ec5..ecb85f8230e0 100644 --- a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_lb_traffic_extension_async.py +++ b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_lb_traffic_extension_async.py @@ -45,7 +45,6 @@ async def sample_create_lb_traffic_extension(): lb_traffic_extension.extension_chains.match_condition.cel_expression = ( "cel_expression_value" ) - lb_traffic_extension.extension_chains.extensions.name = "name_value" lb_traffic_extension.extension_chains.extensions.service = "service_value" lb_traffic_extension.load_balancing_scheme = "EXTERNAL_MANAGED" diff --git a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_lb_traffic_extension_sync.py b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_lb_traffic_extension_sync.py index 6088394a7cf1..5d7f8b72e83a 100644 --- a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_lb_traffic_extension_sync.py +++ b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_create_lb_traffic_extension_sync.py @@ -45,7 +45,6 @@ def sample_create_lb_traffic_extension(): lb_traffic_extension.extension_chains.match_condition.cel_expression = ( "cel_expression_value" ) - lb_traffic_extension.extension_chains.extensions.name = "name_value" lb_traffic_extension.extension_chains.extensions.service = "service_value" lb_traffic_extension.load_balancing_scheme = "EXTERNAL_MANAGED" diff --git a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_authz_extension_async.py b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_authz_extension_async.py index 1545bcd4ec27..9aab556a4df2 100644 --- a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_authz_extension_async.py +++ b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_authz_extension_async.py @@ -41,8 +41,6 @@ async def sample_update_authz_extension(): # Initialize request argument(s) authz_extension = network_services_v1.AuthzExtension() authz_extension.name = "name_value" - authz_extension.load_balancing_scheme = "EXTERNAL_MANAGED" - authz_extension.authority = "authority_value" authz_extension.service = "service_value" request = network_services_v1.UpdateAuthzExtensionRequest( diff --git a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_authz_extension_sync.py b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_authz_extension_sync.py index c3d31d026404..8ef116979bec 100644 --- a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_authz_extension_sync.py +++ b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_authz_extension_sync.py @@ -41,8 +41,6 @@ def sample_update_authz_extension(): # Initialize request argument(s) authz_extension = network_services_v1.AuthzExtension() authz_extension.name = "name_value" - authz_extension.load_balancing_scheme = "EXTERNAL_MANAGED" - authz_extension.authority = "authority_value" authz_extension.service = "service_value" request = network_services_v1.UpdateAuthzExtensionRequest( diff --git a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_lb_edge_extension_async.py b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_lb_edge_extension_async.py index 4079c9a6697a..82e480e57c05 100644 --- a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_lb_edge_extension_async.py +++ b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_lb_edge_extension_async.py @@ -49,7 +49,6 @@ async def sample_update_lb_edge_extension(): lb_edge_extension.extension_chains.match_condition.cel_expression = ( "cel_expression_value" ) - lb_edge_extension.extension_chains.extensions.name = "name_value" lb_edge_extension.extension_chains.extensions.service = "service_value" lb_edge_extension.load_balancing_scheme = "EXTERNAL_MANAGED" diff --git a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_lb_edge_extension_sync.py b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_lb_edge_extension_sync.py index 5cfabd8ee546..55a247f194df 100644 --- a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_lb_edge_extension_sync.py +++ b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_lb_edge_extension_sync.py @@ -49,7 +49,6 @@ def sample_update_lb_edge_extension(): lb_edge_extension.extension_chains.match_condition.cel_expression = ( "cel_expression_value" ) - lb_edge_extension.extension_chains.extensions.name = "name_value" lb_edge_extension.extension_chains.extensions.service = "service_value" lb_edge_extension.load_balancing_scheme = "EXTERNAL_MANAGED" diff --git a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_lb_route_extension_async.py b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_lb_route_extension_async.py index a3e6bff4db4d..019e9164ce03 100644 --- a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_lb_route_extension_async.py +++ b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_lb_route_extension_async.py @@ -49,7 +49,6 @@ async def sample_update_lb_route_extension(): lb_route_extension.extension_chains.match_condition.cel_expression = ( "cel_expression_value" ) - lb_route_extension.extension_chains.extensions.name = "name_value" lb_route_extension.extension_chains.extensions.service = "service_value" lb_route_extension.load_balancing_scheme = "EXTERNAL_MANAGED" diff --git a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_lb_route_extension_sync.py b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_lb_route_extension_sync.py index 3afdd0c5fa7e..fcc53c4dbe11 100644 --- a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_lb_route_extension_sync.py +++ b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_lb_route_extension_sync.py @@ -49,7 +49,6 @@ def sample_update_lb_route_extension(): lb_route_extension.extension_chains.match_condition.cel_expression = ( "cel_expression_value" ) - lb_route_extension.extension_chains.extensions.name = "name_value" lb_route_extension.extension_chains.extensions.service = "service_value" lb_route_extension.load_balancing_scheme = "EXTERNAL_MANAGED" diff --git a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_lb_traffic_extension_async.py b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_lb_traffic_extension_async.py index e67bc558d7d4..747bda3e909d 100644 --- a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_lb_traffic_extension_async.py +++ b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_lb_traffic_extension_async.py @@ -45,7 +45,6 @@ async def sample_update_lb_traffic_extension(): lb_traffic_extension.extension_chains.match_condition.cel_expression = ( "cel_expression_value" ) - lb_traffic_extension.extension_chains.extensions.name = "name_value" lb_traffic_extension.extension_chains.extensions.service = "service_value" lb_traffic_extension.load_balancing_scheme = "EXTERNAL_MANAGED" diff --git a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_lb_traffic_extension_sync.py b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_lb_traffic_extension_sync.py index c05e0fb7ab7d..df1332a36862 100644 --- a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_lb_traffic_extension_sync.py +++ b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_dep_service_update_lb_traffic_extension_sync.py @@ -45,7 +45,6 @@ def sample_update_lb_traffic_extension(): lb_traffic_extension.extension_chains.match_condition.cel_expression = ( "cel_expression_value" ) - lb_traffic_extension.extension_chains.extensions.name = "name_value" lb_traffic_extension.extension_chains.extensions.service = "service_value" lb_traffic_extension.load_balancing_scheme = "EXTERNAL_MANAGED" diff --git a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_create_agent_gateway_async.py b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_create_agent_gateway_async.py new file mode 100644 index 000000000000..5a6ddac09764 --- /dev/null +++ b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_create_agent_gateway_async.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateAgentGateway +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-network-services + + +# [START networkservices_v1_generated_NetworkServices_CreateAgentGateway_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import network_services_v1 + + +async def sample_create_agent_gateway(): + # Create a client + client = network_services_v1.NetworkServicesAsyncClient() + + # Initialize request argument(s) + request = network_services_v1.CreateAgentGatewayRequest( + parent="parent_value", + agent_gateway_id="agent_gateway_id_value", + ) + + # Make the request + operation = await client.create_agent_gateway(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + +# [END networkservices_v1_generated_NetworkServices_CreateAgentGateway_async] diff --git a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_create_agent_gateway_sync.py b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_create_agent_gateway_sync.py new file mode 100644 index 000000000000..5a878783043a --- /dev/null +++ b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_create_agent_gateway_sync.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateAgentGateway +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-network-services + + +# [START networkservices_v1_generated_NetworkServices_CreateAgentGateway_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import network_services_v1 + + +def sample_create_agent_gateway(): + # Create a client + client = network_services_v1.NetworkServicesClient() + + # Initialize request argument(s) + request = network_services_v1.CreateAgentGatewayRequest( + parent="parent_value", + agent_gateway_id="agent_gateway_id_value", + ) + + # Make the request + operation = client.create_agent_gateway(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + +# [END networkservices_v1_generated_NetworkServices_CreateAgentGateway_sync] diff --git a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_delete_agent_gateway_async.py b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_delete_agent_gateway_async.py new file mode 100644 index 000000000000..4cd6ca2d6271 --- /dev/null +++ b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_delete_agent_gateway_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteAgentGateway +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-network-services + + +# [START networkservices_v1_generated_NetworkServices_DeleteAgentGateway_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import network_services_v1 + + +async def sample_delete_agent_gateway(): + # Create a client + client = network_services_v1.NetworkServicesAsyncClient() + + # Initialize request argument(s) + request = network_services_v1.DeleteAgentGatewayRequest( + name="name_value", + ) + + # Make the request + operation = await client.delete_agent_gateway(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + +# [END networkservices_v1_generated_NetworkServices_DeleteAgentGateway_async] diff --git a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_delete_agent_gateway_sync.py b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_delete_agent_gateway_sync.py new file mode 100644 index 000000000000..2ac7d846e0a6 --- /dev/null +++ b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_delete_agent_gateway_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteAgentGateway +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-network-services + + +# [START networkservices_v1_generated_NetworkServices_DeleteAgentGateway_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import network_services_v1 + + +def sample_delete_agent_gateway(): + # Create a client + client = network_services_v1.NetworkServicesClient() + + # Initialize request argument(s) + request = network_services_v1.DeleteAgentGatewayRequest( + name="name_value", + ) + + # Make the request + operation = client.delete_agent_gateway(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + +# [END networkservices_v1_generated_NetworkServices_DeleteAgentGateway_sync] diff --git a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_get_agent_gateway_async.py b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_get_agent_gateway_async.py new file mode 100644 index 000000000000..5023bb19b743 --- /dev/null +++ b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_get_agent_gateway_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetAgentGateway +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-network-services + + +# [START networkservices_v1_generated_NetworkServices_GetAgentGateway_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import network_services_v1 + + +async def sample_get_agent_gateway(): + # Create a client + client = network_services_v1.NetworkServicesAsyncClient() + + # Initialize request argument(s) + request = network_services_v1.GetAgentGatewayRequest( + name="name_value", + ) + + # Make the request + response = await client.get_agent_gateway(request=request) + + # Handle the response + print(response) + + +# [END networkservices_v1_generated_NetworkServices_GetAgentGateway_async] diff --git a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_get_agent_gateway_sync.py b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_get_agent_gateway_sync.py new file mode 100644 index 000000000000..4cd0fd9a8dd0 --- /dev/null +++ b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_get_agent_gateway_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetAgentGateway +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-network-services + + +# [START networkservices_v1_generated_NetworkServices_GetAgentGateway_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import network_services_v1 + + +def sample_get_agent_gateway(): + # Create a client + client = network_services_v1.NetworkServicesClient() + + # Initialize request argument(s) + request = network_services_v1.GetAgentGatewayRequest( + name="name_value", + ) + + # Make the request + response = client.get_agent_gateway(request=request) + + # Handle the response + print(response) + + +# [END networkservices_v1_generated_NetworkServices_GetAgentGateway_sync] diff --git a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_list_agent_gateways_async.py b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_list_agent_gateways_async.py new file mode 100644 index 000000000000..d5feb9f25b84 --- /dev/null +++ b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_list_agent_gateways_async.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListAgentGateways +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-network-services + + +# [START networkservices_v1_generated_NetworkServices_ListAgentGateways_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import network_services_v1 + + +async def sample_list_agent_gateways(): + # Create a client + client = network_services_v1.NetworkServicesAsyncClient() + + # Initialize request argument(s) + request = network_services_v1.ListAgentGatewaysRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_agent_gateways(request=request) + + # Handle the response + async for response in page_result: + print(response) + + +# [END networkservices_v1_generated_NetworkServices_ListAgentGateways_async] diff --git a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_list_agent_gateways_sync.py b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_list_agent_gateways_sync.py new file mode 100644 index 000000000000..91d8ced79b00 --- /dev/null +++ b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_list_agent_gateways_sync.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListAgentGateways +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-network-services + + +# [START networkservices_v1_generated_NetworkServices_ListAgentGateways_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import network_services_v1 + + +def sample_list_agent_gateways(): + # Create a client + client = network_services_v1.NetworkServicesClient() + + # Initialize request argument(s) + request = network_services_v1.ListAgentGatewaysRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_agent_gateways(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END networkservices_v1_generated_NetworkServices_ListAgentGateways_sync] diff --git a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_update_agent_gateway_async.py b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_update_agent_gateway_async.py new file mode 100644 index 000000000000..ab723589fa54 --- /dev/null +++ b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_update_agent_gateway_async.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateAgentGateway +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-network-services + + +# [START networkservices_v1_generated_NetworkServices_UpdateAgentGateway_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import network_services_v1 + + +async def sample_update_agent_gateway(): + # Create a client + client = network_services_v1.NetworkServicesAsyncClient() + + # Initialize request argument(s) + request = network_services_v1.UpdateAgentGatewayRequest() + + # Make the request + operation = await client.update_agent_gateway(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + +# [END networkservices_v1_generated_NetworkServices_UpdateAgentGateway_async] diff --git a/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_update_agent_gateway_sync.py b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_update_agent_gateway_sync.py new file mode 100644 index 000000000000..62f4b35e15e8 --- /dev/null +++ b/packages/google-cloud-network-services/samples/generated_samples/networkservices_v1_generated_network_services_update_agent_gateway_sync.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateAgentGateway +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-network-services + + +# [START networkservices_v1_generated_NetworkServices_UpdateAgentGateway_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import network_services_v1 + + +def sample_update_agent_gateway(): + # Create a client + client = network_services_v1.NetworkServicesClient() + + # Initialize request argument(s) + request = network_services_v1.UpdateAgentGatewayRequest() + + # Make the request + operation = client.update_agent_gateway(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + +# [END networkservices_v1_generated_NetworkServices_UpdateAgentGateway_sync] diff --git a/packages/google-cloud-network-services/samples/generated_samples/snippet_metadata_google.cloud.networkservices.v1.json b/packages/google-cloud-network-services/samples/generated_samples/snippet_metadata_google.cloud.networkservices.v1.json index 63ae4ff67dbe..f3c4a8668983 100644 --- a/packages/google-cloud-network-services/samples/generated_samples/snippet_metadata_google.cloud.networkservices.v1.json +++ b/packages/google-cloud-network-services/samples/generated_samples/snippet_metadata_google.cloud.networkservices.v1.json @@ -68,12 +68,12 @@ "regionTag": "networkservices_v1_generated_DepService_CreateAuthzExtension_async", "segments": [ { - "end": 63, + "end": 61, "start": 27, "type": "FULL" }, { - "end": 63, + "end": 61, "start": 27, "type": "SHORT" }, @@ -83,18 +83,18 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 53, + "end": 51, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 60, - "start": 54, + "end": 58, + "start": 52, "type": "REQUEST_EXECUTION" }, { - "end": 64, - "start": 61, + "end": 62, + "start": 59, "type": "RESPONSE_HANDLING" } ], @@ -156,12 +156,12 @@ "regionTag": "networkservices_v1_generated_DepService_CreateAuthzExtension_sync", "segments": [ { - "end": 63, + "end": 61, "start": 27, "type": "FULL" }, { - "end": 63, + "end": 61, "start": 27, "type": "SHORT" }, @@ -171,18 +171,18 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 53, + "end": 51, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 60, - "start": 54, + "end": 58, + "start": 52, "type": "REQUEST_EXECUTION" }, { - "end": 64, - "start": 61, + "end": 62, + "start": 59, "type": "RESPONSE_HANDLING" } ], @@ -245,12 +245,12 @@ "regionTag": "networkservices_v1_generated_DepService_CreateLbEdgeExtension_async", "segments": [ { - "end": 66, + "end": 65, "start": 27, "type": "FULL" }, { - "end": 66, + "end": 65, "start": 27, "type": "SHORT" }, @@ -260,18 +260,18 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 56, + "end": 55, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 63, - "start": 57, + "end": 62, + "start": 56, "type": "REQUEST_EXECUTION" }, { - "end": 67, - "start": 64, + "end": 66, + "start": 63, "type": "RESPONSE_HANDLING" } ], @@ -333,12 +333,12 @@ "regionTag": "networkservices_v1_generated_DepService_CreateLbEdgeExtension_sync", "segments": [ { - "end": 66, + "end": 65, "start": 27, "type": "FULL" }, { - "end": 66, + "end": 65, "start": 27, "type": "SHORT" }, @@ -348,18 +348,18 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 56, + "end": 55, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 63, - "start": 57, + "end": 62, + "start": 56, "type": "REQUEST_EXECUTION" }, { - "end": 67, - "start": 64, + "end": 66, + "start": 63, "type": "RESPONSE_HANDLING" } ], @@ -422,12 +422,12 @@ "regionTag": "networkservices_v1_generated_DepService_CreateLbRouteExtension_async", "segments": [ { - "end": 66, + "end": 65, "start": 27, "type": "FULL" }, { - "end": 66, + "end": 65, "start": 27, "type": "SHORT" }, @@ -437,18 +437,18 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 56, + "end": 55, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 63, - "start": 57, + "end": 62, + "start": 56, "type": "REQUEST_EXECUTION" }, { - "end": 67, - "start": 64, + "end": 66, + "start": 63, "type": "RESPONSE_HANDLING" } ], @@ -510,12 +510,12 @@ "regionTag": "networkservices_v1_generated_DepService_CreateLbRouteExtension_sync", "segments": [ { - "end": 66, + "end": 65, "start": 27, "type": "FULL" }, { - "end": 66, + "end": 65, "start": 27, "type": "SHORT" }, @@ -525,18 +525,18 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 56, + "end": 55, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 63, - "start": 57, + "end": 62, + "start": 56, "type": "REQUEST_EXECUTION" }, { - "end": 67, - "start": 64, + "end": 66, + "start": 63, "type": "RESPONSE_HANDLING" } ], @@ -599,12 +599,12 @@ "regionTag": "networkservices_v1_generated_DepService_CreateLbTrafficExtension_async", "segments": [ { - "end": 65, + "end": 64, "start": 27, "type": "FULL" }, { - "end": 65, + "end": 64, "start": 27, "type": "SHORT" }, @@ -614,18 +614,18 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 55, + "end": 54, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 62, - "start": 56, + "end": 61, + "start": 55, "type": "REQUEST_EXECUTION" }, { - "end": 66, - "start": 63, + "end": 65, + "start": 62, "type": "RESPONSE_HANDLING" } ], @@ -687,12 +687,12 @@ "regionTag": "networkservices_v1_generated_DepService_CreateLbTrafficExtension_sync", "segments": [ { - "end": 65, + "end": 64, "start": 27, "type": "FULL" }, { - "end": 65, + "end": 64, "start": 27, "type": "SHORT" }, @@ -702,18 +702,18 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 55, + "end": 54, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 62, - "start": 56, + "end": 61, + "start": 55, "type": "REQUEST_EXECUTION" }, { - "end": 66, - "start": 63, + "end": 65, + "start": 62, "type": "RESPONSE_HANDLING" } ], @@ -2704,12 +2704,12 @@ "regionTag": "networkservices_v1_generated_DepService_UpdateAuthzExtension_async", "segments": [ { - "end": 61, + "end": 59, "start": 27, "type": "FULL" }, { - "end": 61, + "end": 59, "start": 27, "type": "SHORT" }, @@ -2719,18 +2719,18 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 51, + "end": 49, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 58, - "start": 52, + "end": 56, + "start": 50, "type": "REQUEST_EXECUTION" }, { - "end": 62, - "start": 59, + "end": 60, + "start": 57, "type": "RESPONSE_HANDLING" } ], @@ -2788,12 +2788,12 @@ "regionTag": "networkservices_v1_generated_DepService_UpdateAuthzExtension_sync", "segments": [ { - "end": 61, + "end": 59, "start": 27, "type": "FULL" }, { - "end": 61, + "end": 59, "start": 27, "type": "SHORT" }, @@ -2803,18 +2803,18 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 51, + "end": 49, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 58, - "start": 52, + "end": 56, + "start": 50, "type": "REQUEST_EXECUTION" }, { - "end": 62, - "start": 59, + "end": 60, + "start": 57, "type": "RESPONSE_HANDLING" } ], @@ -2873,12 +2873,12 @@ "regionTag": "networkservices_v1_generated_DepService_UpdateLbEdgeExtension_async", "segments": [ { - "end": 64, + "end": 63, "start": 27, "type": "FULL" }, { - "end": 64, + "end": 63, "start": 27, "type": "SHORT" }, @@ -2888,18 +2888,18 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 54, + "end": 53, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 61, - "start": 55, + "end": 60, + "start": 54, "type": "REQUEST_EXECUTION" }, { - "end": 65, - "start": 62, + "end": 64, + "start": 61, "type": "RESPONSE_HANDLING" } ], @@ -2957,12 +2957,12 @@ "regionTag": "networkservices_v1_generated_DepService_UpdateLbEdgeExtension_sync", "segments": [ { - "end": 64, + "end": 63, "start": 27, "type": "FULL" }, { - "end": 64, + "end": 63, "start": 27, "type": "SHORT" }, @@ -2972,18 +2972,18 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 54, + "end": 53, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 61, - "start": 55, + "end": 60, + "start": 54, "type": "REQUEST_EXECUTION" }, { - "end": 65, - "start": 62, + "end": 64, + "start": 61, "type": "RESPONSE_HANDLING" } ], @@ -3042,12 +3042,12 @@ "regionTag": "networkservices_v1_generated_DepService_UpdateLbRouteExtension_async", "segments": [ { - "end": 64, + "end": 63, "start": 27, "type": "FULL" }, { - "end": 64, + "end": 63, "start": 27, "type": "SHORT" }, @@ -3057,18 +3057,18 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 54, + "end": 53, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 61, - "start": 55, + "end": 60, + "start": 54, "type": "REQUEST_EXECUTION" }, { - "end": 65, - "start": 62, + "end": 64, + "start": 61, "type": "RESPONSE_HANDLING" } ], @@ -3126,12 +3126,12 @@ "regionTag": "networkservices_v1_generated_DepService_UpdateLbRouteExtension_sync", "segments": [ { - "end": 64, + "end": 63, "start": 27, "type": "FULL" }, { - "end": 64, + "end": 63, "start": 27, "type": "SHORT" }, @@ -3141,18 +3141,18 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 54, + "end": 53, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 61, - "start": 55, + "end": 60, + "start": 54, "type": "REQUEST_EXECUTION" }, { - "end": 65, - "start": 62, + "end": 64, + "start": 61, "type": "RESPONSE_HANDLING" } ], @@ -3211,12 +3211,12 @@ "regionTag": "networkservices_v1_generated_DepService_UpdateLbTrafficExtension_async", "segments": [ { - "end": 63, + "end": 62, "start": 27, "type": "FULL" }, { - "end": 63, + "end": 62, "start": 27, "type": "SHORT" }, @@ -3226,18 +3226,18 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 53, + "end": 52, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 60, - "start": 54, + "end": 59, + "start": 53, "type": "REQUEST_EXECUTION" }, { - "end": 64, - "start": 61, + "end": 63, + "start": 60, "type": "RESPONSE_HANDLING" } ], @@ -3295,12 +3295,12 @@ "regionTag": "networkservices_v1_generated_DepService_UpdateLbTrafficExtension_sync", "segments": [ { - "end": 63, + "end": 62, "start": 27, "type": "FULL" }, { - "end": 63, + "end": 62, "start": 27, "type": "SHORT" }, @@ -3310,18 +3310,18 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 53, + "end": 52, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 60, - "start": 54, + "end": 59, + "start": 53, "type": "REQUEST_EXECUTION" }, { - "end": 64, - "start": 61, + "end": 63, + "start": 60, "type": "RESPONSE_HANDLING" } ], @@ -3335,30 +3335,30 @@ "fullName": "google.cloud.network_services_v1.NetworkServicesAsyncClient", "shortName": "NetworkServicesAsyncClient" }, - "fullName": "google.cloud.network_services_v1.NetworkServicesAsyncClient.create_endpoint_policy", + "fullName": "google.cloud.network_services_v1.NetworkServicesAsyncClient.create_agent_gateway", "method": { - "fullName": "google.cloud.networkservices.v1.NetworkServices.CreateEndpointPolicy", + "fullName": "google.cloud.networkservices.v1.NetworkServices.CreateAgentGateway", "service": { "fullName": "google.cloud.networkservices.v1.NetworkServices", "shortName": "NetworkServices" }, - "shortName": "CreateEndpointPolicy" + "shortName": "CreateAgentGateway" }, "parameters": [ { "name": "request", - "type": "google.cloud.network_services_v1.types.CreateEndpointPolicyRequest" + "type": "google.cloud.network_services_v1.types.CreateAgentGatewayRequest" }, { "name": "parent", "type": "str" }, { - "name": "endpoint_policy", - "type": "google.cloud.network_services_v1.types.EndpointPolicy" + "name": "agent_gateway", + "type": "google.cloud.network_services_v1.types.AgentGateway" }, { - "name": "endpoint_policy_id", + "name": "agent_gateway_id", "type": "str" }, { @@ -3375,21 +3375,21 @@ } ], "resultType": "google.api_core.operation_async.AsyncOperation", - "shortName": "create_endpoint_policy" + "shortName": "create_agent_gateway" }, - "description": "Sample for CreateEndpointPolicy", - "file": "networkservices_v1_generated_network_services_create_endpoint_policy_async.py", + "description": "Sample for CreateAgentGateway", + "file": "networkservices_v1_generated_network_services_create_agent_gateway_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "networkservices_v1_generated_NetworkServices_CreateEndpointPolicy_async", + "regionTag": "networkservices_v1_generated_NetworkServices_CreateAgentGateway_async", "segments": [ { - "end": 60, + "end": 56, "start": 27, "type": "FULL" }, { - "end": 60, + "end": 56, "start": 27, "type": "SHORT" }, @@ -3399,22 +3399,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 50, + "end": 46, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 57, - "start": 51, + "end": 53, + "start": 47, "type": "REQUEST_EXECUTION" }, { - "end": 61, - "start": 58, + "end": 57, + "start": 54, "type": "RESPONSE_HANDLING" } ], - "title": "networkservices_v1_generated_network_services_create_endpoint_policy_async.py" + "title": "networkservices_v1_generated_network_services_create_agent_gateway_async.py" }, { "canonical": true, @@ -3423,30 +3423,30 @@ "fullName": "google.cloud.network_services_v1.NetworkServicesClient", "shortName": "NetworkServicesClient" }, - "fullName": "google.cloud.network_services_v1.NetworkServicesClient.create_endpoint_policy", + "fullName": "google.cloud.network_services_v1.NetworkServicesClient.create_agent_gateway", "method": { - "fullName": "google.cloud.networkservices.v1.NetworkServices.CreateEndpointPolicy", + "fullName": "google.cloud.networkservices.v1.NetworkServices.CreateAgentGateway", "service": { "fullName": "google.cloud.networkservices.v1.NetworkServices", "shortName": "NetworkServices" }, - "shortName": "CreateEndpointPolicy" + "shortName": "CreateAgentGateway" }, "parameters": [ { "name": "request", - "type": "google.cloud.network_services_v1.types.CreateEndpointPolicyRequest" + "type": "google.cloud.network_services_v1.types.CreateAgentGatewayRequest" }, { "name": "parent", "type": "str" }, { - "name": "endpoint_policy", - "type": "google.cloud.network_services_v1.types.EndpointPolicy" + "name": "agent_gateway", + "type": "google.cloud.network_services_v1.types.AgentGateway" }, { - "name": "endpoint_policy_id", + "name": "agent_gateway_id", "type": "str" }, { @@ -3463,21 +3463,21 @@ } ], "resultType": "google.api_core.operation.Operation", - "shortName": "create_endpoint_policy" + "shortName": "create_agent_gateway" }, - "description": "Sample for CreateEndpointPolicy", - "file": "networkservices_v1_generated_network_services_create_endpoint_policy_sync.py", + "description": "Sample for CreateAgentGateway", + "file": "networkservices_v1_generated_network_services_create_agent_gateway_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "networkservices_v1_generated_NetworkServices_CreateEndpointPolicy_sync", + "regionTag": "networkservices_v1_generated_NetworkServices_CreateAgentGateway_sync", "segments": [ { - "end": 60, + "end": 56, "start": 27, "type": "FULL" }, { - "end": 60, + "end": 56, "start": 27, "type": "SHORT" }, @@ -3487,14 +3487,191 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 50, + "end": 46, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 57, - "start": 51, - "type": "REQUEST_EXECUTION" + "end": 53, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "networkservices_v1_generated_network_services_create_agent_gateway_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.network_services_v1.NetworkServicesAsyncClient", + "shortName": "NetworkServicesAsyncClient" + }, + "fullName": "google.cloud.network_services_v1.NetworkServicesAsyncClient.create_endpoint_policy", + "method": { + "fullName": "google.cloud.networkservices.v1.NetworkServices.CreateEndpointPolicy", + "service": { + "fullName": "google.cloud.networkservices.v1.NetworkServices", + "shortName": "NetworkServices" + }, + "shortName": "CreateEndpointPolicy" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.network_services_v1.types.CreateEndpointPolicyRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "endpoint_policy", + "type": "google.cloud.network_services_v1.types.EndpointPolicy" + }, + { + "name": "endpoint_policy_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "create_endpoint_policy" + }, + "description": "Sample for CreateEndpointPolicy", + "file": "networkservices_v1_generated_network_services_create_endpoint_policy_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "networkservices_v1_generated_NetworkServices_CreateEndpointPolicy_async", + "segments": [ + { + "end": 60, + "start": 27, + "type": "FULL" + }, + { + "end": 60, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 57, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 61, + "start": 58, + "type": "RESPONSE_HANDLING" + } + ], + "title": "networkservices_v1_generated_network_services_create_endpoint_policy_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.network_services_v1.NetworkServicesClient", + "shortName": "NetworkServicesClient" + }, + "fullName": "google.cloud.network_services_v1.NetworkServicesClient.create_endpoint_policy", + "method": { + "fullName": "google.cloud.networkservices.v1.NetworkServices.CreateEndpointPolicy", + "service": { + "fullName": "google.cloud.networkservices.v1.NetworkServices", + "shortName": "NetworkServices" + }, + "shortName": "CreateEndpointPolicy" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.network_services_v1.types.CreateEndpointPolicyRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "endpoint_policy", + "type": "google.cloud.network_services_v1.types.EndpointPolicy" + }, + { + "name": "endpoint_policy_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "create_endpoint_policy" + }, + "description": "Sample for CreateEndpointPolicy", + "file": "networkservices_v1_generated_network_services_create_endpoint_policy_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "networkservices_v1_generated_NetworkServices_CreateEndpointPolicy_sync", + "segments": [ + { + "end": 60, + "start": 27, + "type": "FULL" + }, + { + "end": 60, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 57, + "start": 51, + "type": "REQUEST_EXECUTION" }, { "end": 61, @@ -5282,19 +5459,19 @@ "fullName": "google.cloud.network_services_v1.NetworkServicesAsyncClient", "shortName": "NetworkServicesAsyncClient" }, - "fullName": "google.cloud.network_services_v1.NetworkServicesAsyncClient.delete_endpoint_policy", + "fullName": "google.cloud.network_services_v1.NetworkServicesAsyncClient.delete_agent_gateway", "method": { - "fullName": "google.cloud.networkservices.v1.NetworkServices.DeleteEndpointPolicy", + "fullName": "google.cloud.networkservices.v1.NetworkServices.DeleteAgentGateway", "service": { "fullName": "google.cloud.networkservices.v1.NetworkServices", "shortName": "NetworkServices" }, - "shortName": "DeleteEndpointPolicy" + "shortName": "DeleteAgentGateway" }, "parameters": [ { "name": "request", - "type": "google.cloud.network_services_v1.types.DeleteEndpointPolicyRequest" + "type": "google.cloud.network_services_v1.types.DeleteAgentGatewayRequest" }, { "name": "name", @@ -5314,13 +5491,13 @@ } ], "resultType": "google.api_core.operation_async.AsyncOperation", - "shortName": "delete_endpoint_policy" + "shortName": "delete_agent_gateway" }, - "description": "Sample for DeleteEndpointPolicy", - "file": "networkservices_v1_generated_network_services_delete_endpoint_policy_async.py", + "description": "Sample for DeleteAgentGateway", + "file": "networkservices_v1_generated_network_services_delete_agent_gateway_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "networkservices_v1_generated_NetworkServices_DeleteEndpointPolicy_async", + "regionTag": "networkservices_v1_generated_NetworkServices_DeleteAgentGateway_async", "segments": [ { "end": 55, @@ -5353,7 +5530,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "networkservices_v1_generated_network_services_delete_endpoint_policy_async.py" + "title": "networkservices_v1_generated_network_services_delete_agent_gateway_async.py" }, { "canonical": true, @@ -5362,19 +5539,19 @@ "fullName": "google.cloud.network_services_v1.NetworkServicesClient", "shortName": "NetworkServicesClient" }, - "fullName": "google.cloud.network_services_v1.NetworkServicesClient.delete_endpoint_policy", + "fullName": "google.cloud.network_services_v1.NetworkServicesClient.delete_agent_gateway", "method": { - "fullName": "google.cloud.networkservices.v1.NetworkServices.DeleteEndpointPolicy", + "fullName": "google.cloud.networkservices.v1.NetworkServices.DeleteAgentGateway", "service": { "fullName": "google.cloud.networkservices.v1.NetworkServices", "shortName": "NetworkServices" }, - "shortName": "DeleteEndpointPolicy" + "shortName": "DeleteAgentGateway" }, "parameters": [ { "name": "request", - "type": "google.cloud.network_services_v1.types.DeleteEndpointPolicyRequest" + "type": "google.cloud.network_services_v1.types.DeleteAgentGatewayRequest" }, { "name": "name", @@ -5394,13 +5571,13 @@ } ], "resultType": "google.api_core.operation.Operation", - "shortName": "delete_endpoint_policy" + "shortName": "delete_agent_gateway" }, - "description": "Sample for DeleteEndpointPolicy", - "file": "networkservices_v1_generated_network_services_delete_endpoint_policy_sync.py", + "description": "Sample for DeleteAgentGateway", + "file": "networkservices_v1_generated_network_services_delete_agent_gateway_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "networkservices_v1_generated_NetworkServices_DeleteEndpointPolicy_sync", + "regionTag": "networkservices_v1_generated_NetworkServices_DeleteAgentGateway_sync", "segments": [ { "end": 55, @@ -5433,7 +5610,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "networkservices_v1_generated_network_services_delete_endpoint_policy_sync.py" + "title": "networkservices_v1_generated_network_services_delete_agent_gateway_sync.py" }, { "canonical": true, @@ -5443,19 +5620,19 @@ "fullName": "google.cloud.network_services_v1.NetworkServicesAsyncClient", "shortName": "NetworkServicesAsyncClient" }, - "fullName": "google.cloud.network_services_v1.NetworkServicesAsyncClient.delete_gateway", + "fullName": "google.cloud.network_services_v1.NetworkServicesAsyncClient.delete_endpoint_policy", "method": { - "fullName": "google.cloud.networkservices.v1.NetworkServices.DeleteGateway", + "fullName": "google.cloud.networkservices.v1.NetworkServices.DeleteEndpointPolicy", "service": { "fullName": "google.cloud.networkservices.v1.NetworkServices", "shortName": "NetworkServices" }, - "shortName": "DeleteGateway" + "shortName": "DeleteEndpointPolicy" }, "parameters": [ { "name": "request", - "type": "google.cloud.network_services_v1.types.DeleteGatewayRequest" + "type": "google.cloud.network_services_v1.types.DeleteEndpointPolicyRequest" }, { "name": "name", @@ -5475,13 +5652,13 @@ } ], "resultType": "google.api_core.operation_async.AsyncOperation", - "shortName": "delete_gateway" + "shortName": "delete_endpoint_policy" }, - "description": "Sample for DeleteGateway", - "file": "networkservices_v1_generated_network_services_delete_gateway_async.py", + "description": "Sample for DeleteEndpointPolicy", + "file": "networkservices_v1_generated_network_services_delete_endpoint_policy_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "networkservices_v1_generated_NetworkServices_DeleteGateway_async", + "regionTag": "networkservices_v1_generated_NetworkServices_DeleteEndpointPolicy_async", "segments": [ { "end": 55, @@ -5514,7 +5691,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "networkservices_v1_generated_network_services_delete_gateway_async.py" + "title": "networkservices_v1_generated_network_services_delete_endpoint_policy_async.py" }, { "canonical": true, @@ -5523,19 +5700,19 @@ "fullName": "google.cloud.network_services_v1.NetworkServicesClient", "shortName": "NetworkServicesClient" }, - "fullName": "google.cloud.network_services_v1.NetworkServicesClient.delete_gateway", + "fullName": "google.cloud.network_services_v1.NetworkServicesClient.delete_endpoint_policy", "method": { - "fullName": "google.cloud.networkservices.v1.NetworkServices.DeleteGateway", + "fullName": "google.cloud.networkservices.v1.NetworkServices.DeleteEndpointPolicy", "service": { "fullName": "google.cloud.networkservices.v1.NetworkServices", "shortName": "NetworkServices" }, - "shortName": "DeleteGateway" + "shortName": "DeleteEndpointPolicy" }, "parameters": [ { "name": "request", - "type": "google.cloud.network_services_v1.types.DeleteGatewayRequest" + "type": "google.cloud.network_services_v1.types.DeleteEndpointPolicyRequest" }, { "name": "name", @@ -5555,13 +5732,13 @@ } ], "resultType": "google.api_core.operation.Operation", - "shortName": "delete_gateway" + "shortName": "delete_endpoint_policy" }, - "description": "Sample for DeleteGateway", - "file": "networkservices_v1_generated_network_services_delete_gateway_sync.py", + "description": "Sample for DeleteEndpointPolicy", + "file": "networkservices_v1_generated_network_services_delete_endpoint_policy_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "networkservices_v1_generated_NetworkServices_DeleteGateway_sync", + "regionTag": "networkservices_v1_generated_NetworkServices_DeleteEndpointPolicy_sync", "segments": [ { "end": 55, @@ -5594,7 +5771,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "networkservices_v1_generated_network_services_delete_gateway_sync.py" + "title": "networkservices_v1_generated_network_services_delete_endpoint_policy_sync.py" }, { "canonical": true, @@ -5604,19 +5781,19 @@ "fullName": "google.cloud.network_services_v1.NetworkServicesAsyncClient", "shortName": "NetworkServicesAsyncClient" }, - "fullName": "google.cloud.network_services_v1.NetworkServicesAsyncClient.delete_grpc_route", + "fullName": "google.cloud.network_services_v1.NetworkServicesAsyncClient.delete_gateway", "method": { - "fullName": "google.cloud.networkservices.v1.NetworkServices.DeleteGrpcRoute", + "fullName": "google.cloud.networkservices.v1.NetworkServices.DeleteGateway", "service": { "fullName": "google.cloud.networkservices.v1.NetworkServices", "shortName": "NetworkServices" }, - "shortName": "DeleteGrpcRoute" + "shortName": "DeleteGateway" }, "parameters": [ { "name": "request", - "type": "google.cloud.network_services_v1.types.DeleteGrpcRouteRequest" + "type": "google.cloud.network_services_v1.types.DeleteGatewayRequest" }, { "name": "name", @@ -5636,13 +5813,13 @@ } ], "resultType": "google.api_core.operation_async.AsyncOperation", - "shortName": "delete_grpc_route" + "shortName": "delete_gateway" }, - "description": "Sample for DeleteGrpcRoute", - "file": "networkservices_v1_generated_network_services_delete_grpc_route_async.py", + "description": "Sample for DeleteGateway", + "file": "networkservices_v1_generated_network_services_delete_gateway_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "networkservices_v1_generated_NetworkServices_DeleteGrpcRoute_async", + "regionTag": "networkservices_v1_generated_NetworkServices_DeleteGateway_async", "segments": [ { "end": 55, @@ -5675,7 +5852,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "networkservices_v1_generated_network_services_delete_grpc_route_async.py" + "title": "networkservices_v1_generated_network_services_delete_gateway_async.py" }, { "canonical": true, @@ -5684,14 +5861,175 @@ "fullName": "google.cloud.network_services_v1.NetworkServicesClient", "shortName": "NetworkServicesClient" }, - "fullName": "google.cloud.network_services_v1.NetworkServicesClient.delete_grpc_route", + "fullName": "google.cloud.network_services_v1.NetworkServicesClient.delete_gateway", "method": { - "fullName": "google.cloud.networkservices.v1.NetworkServices.DeleteGrpcRoute", + "fullName": "google.cloud.networkservices.v1.NetworkServices.DeleteGateway", "service": { "fullName": "google.cloud.networkservices.v1.NetworkServices", "shortName": "NetworkServices" }, - "shortName": "DeleteGrpcRoute" + "shortName": "DeleteGateway" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.network_services_v1.types.DeleteGatewayRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "delete_gateway" + }, + "description": "Sample for DeleteGateway", + "file": "networkservices_v1_generated_network_services_delete_gateway_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "networkservices_v1_generated_NetworkServices_DeleteGateway_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "networkservices_v1_generated_network_services_delete_gateway_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.network_services_v1.NetworkServicesAsyncClient", + "shortName": "NetworkServicesAsyncClient" + }, + "fullName": "google.cloud.network_services_v1.NetworkServicesAsyncClient.delete_grpc_route", + "method": { + "fullName": "google.cloud.networkservices.v1.NetworkServices.DeleteGrpcRoute", + "service": { + "fullName": "google.cloud.networkservices.v1.NetworkServices", + "shortName": "NetworkServices" + }, + "shortName": "DeleteGrpcRoute" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.network_services_v1.types.DeleteGrpcRouteRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "delete_grpc_route" + }, + "description": "Sample for DeleteGrpcRoute", + "file": "networkservices_v1_generated_network_services_delete_grpc_route_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "networkservices_v1_generated_NetworkServices_DeleteGrpcRoute_async", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "networkservices_v1_generated_network_services_delete_grpc_route_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.network_services_v1.NetworkServicesClient", + "shortName": "NetworkServicesClient" + }, + "fullName": "google.cloud.network_services_v1.NetworkServicesClient.delete_grpc_route", + "method": { + "fullName": "google.cloud.networkservices.v1.NetworkServices.DeleteGrpcRoute", + "service": { + "fullName": "google.cloud.networkservices.v1.NetworkServices", + "shortName": "NetworkServices" + }, + "shortName": "DeleteGrpcRoute" }, "parameters": [ { @@ -7045,6 +7383,167 @@ ], "title": "networkservices_v1_generated_network_services_delete_wasm_plugin_sync.py" }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.network_services_v1.NetworkServicesAsyncClient", + "shortName": "NetworkServicesAsyncClient" + }, + "fullName": "google.cloud.network_services_v1.NetworkServicesAsyncClient.get_agent_gateway", + "method": { + "fullName": "google.cloud.networkservices.v1.NetworkServices.GetAgentGateway", + "service": { + "fullName": "google.cloud.networkservices.v1.NetworkServices", + "shortName": "NetworkServices" + }, + "shortName": "GetAgentGateway" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.network_services_v1.types.GetAgentGatewayRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.network_services_v1.types.AgentGateway", + "shortName": "get_agent_gateway" + }, + "description": "Sample for GetAgentGateway", + "file": "networkservices_v1_generated_network_services_get_agent_gateway_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "networkservices_v1_generated_NetworkServices_GetAgentGateway_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "networkservices_v1_generated_network_services_get_agent_gateway_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.network_services_v1.NetworkServicesClient", + "shortName": "NetworkServicesClient" + }, + "fullName": "google.cloud.network_services_v1.NetworkServicesClient.get_agent_gateway", + "method": { + "fullName": "google.cloud.networkservices.v1.NetworkServices.GetAgentGateway", + "service": { + "fullName": "google.cloud.networkservices.v1.NetworkServices", + "shortName": "NetworkServices" + }, + "shortName": "GetAgentGateway" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.network_services_v1.types.GetAgentGatewayRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.network_services_v1.types.AgentGateway", + "shortName": "get_agent_gateway" + }, + "description": "Sample for GetAgentGateway", + "file": "networkservices_v1_generated_network_services_get_agent_gateway_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "networkservices_v1_generated_NetworkServices_GetAgentGateway_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "networkservices_v1_generated_network_services_get_agent_gateway_sync.py" + }, { "canonical": true, "clientMethod": { @@ -8694,14 +9193,175 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.network_services_v1.types.TlsRoute", - "shortName": "get_tls_route" + "resultType": "google.cloud.network_services_v1.types.TlsRoute", + "shortName": "get_tls_route" + }, + "description": "Sample for GetTlsRoute", + "file": "networkservices_v1_generated_network_services_get_tls_route_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "networkservices_v1_generated_NetworkServices_GetTlsRoute_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "networkservices_v1_generated_network_services_get_tls_route_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.network_services_v1.NetworkServicesClient", + "shortName": "NetworkServicesClient" + }, + "fullName": "google.cloud.network_services_v1.NetworkServicesClient.get_tls_route", + "method": { + "fullName": "google.cloud.networkservices.v1.NetworkServices.GetTlsRoute", + "service": { + "fullName": "google.cloud.networkservices.v1.NetworkServices", + "shortName": "NetworkServices" + }, + "shortName": "GetTlsRoute" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.network_services_v1.types.GetTlsRouteRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.network_services_v1.types.TlsRoute", + "shortName": "get_tls_route" + }, + "description": "Sample for GetTlsRoute", + "file": "networkservices_v1_generated_network_services_get_tls_route_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "networkservices_v1_generated_NetworkServices_GetTlsRoute_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "networkservices_v1_generated_network_services_get_tls_route_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.network_services_v1.NetworkServicesAsyncClient", + "shortName": "NetworkServicesAsyncClient" + }, + "fullName": "google.cloud.network_services_v1.NetworkServicesAsyncClient.get_wasm_plugin_version", + "method": { + "fullName": "google.cloud.networkservices.v1.NetworkServices.GetWasmPluginVersion", + "service": { + "fullName": "google.cloud.networkservices.v1.NetworkServices", + "shortName": "NetworkServices" + }, + "shortName": "GetWasmPluginVersion" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.network_services_v1.types.GetWasmPluginVersionRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.network_services_v1.types.WasmPluginVersion", + "shortName": "get_wasm_plugin_version" }, - "description": "Sample for GetTlsRoute", - "file": "networkservices_v1_generated_network_services_get_tls_route_async.py", + "description": "Sample for GetWasmPluginVersion", + "file": "networkservices_v1_generated_network_services_get_wasm_plugin_version_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "networkservices_v1_generated_NetworkServices_GetTlsRoute_async", + "regionTag": "networkservices_v1_generated_NetworkServices_GetWasmPluginVersion_async", "segments": [ { "end": 51, @@ -8734,7 +9394,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "networkservices_v1_generated_network_services_get_tls_route_async.py" + "title": "networkservices_v1_generated_network_services_get_wasm_plugin_version_async.py" }, { "canonical": true, @@ -8743,19 +9403,19 @@ "fullName": "google.cloud.network_services_v1.NetworkServicesClient", "shortName": "NetworkServicesClient" }, - "fullName": "google.cloud.network_services_v1.NetworkServicesClient.get_tls_route", + "fullName": "google.cloud.network_services_v1.NetworkServicesClient.get_wasm_plugin_version", "method": { - "fullName": "google.cloud.networkservices.v1.NetworkServices.GetTlsRoute", + "fullName": "google.cloud.networkservices.v1.NetworkServices.GetWasmPluginVersion", "service": { "fullName": "google.cloud.networkservices.v1.NetworkServices", "shortName": "NetworkServices" }, - "shortName": "GetTlsRoute" + "shortName": "GetWasmPluginVersion" }, "parameters": [ { "name": "request", - "type": "google.cloud.network_services_v1.types.GetTlsRouteRequest" + "type": "google.cloud.network_services_v1.types.GetWasmPluginVersionRequest" }, { "name": "name", @@ -8774,14 +9434,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.network_services_v1.types.TlsRoute", - "shortName": "get_tls_route" + "resultType": "google.cloud.network_services_v1.types.WasmPluginVersion", + "shortName": "get_wasm_plugin_version" }, - "description": "Sample for GetTlsRoute", - "file": "networkservices_v1_generated_network_services_get_tls_route_sync.py", + "description": "Sample for GetWasmPluginVersion", + "file": "networkservices_v1_generated_network_services_get_wasm_plugin_version_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "networkservices_v1_generated_NetworkServices_GetTlsRoute_sync", + "regionTag": "networkservices_v1_generated_NetworkServices_GetWasmPluginVersion_sync", "segments": [ { "end": 51, @@ -8814,7 +9474,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "networkservices_v1_generated_network_services_get_tls_route_sync.py" + "title": "networkservices_v1_generated_network_services_get_wasm_plugin_version_sync.py" }, { "canonical": true, @@ -8824,19 +9484,19 @@ "fullName": "google.cloud.network_services_v1.NetworkServicesAsyncClient", "shortName": "NetworkServicesAsyncClient" }, - "fullName": "google.cloud.network_services_v1.NetworkServicesAsyncClient.get_wasm_plugin_version", + "fullName": "google.cloud.network_services_v1.NetworkServicesAsyncClient.get_wasm_plugin", "method": { - "fullName": "google.cloud.networkservices.v1.NetworkServices.GetWasmPluginVersion", + "fullName": "google.cloud.networkservices.v1.NetworkServices.GetWasmPlugin", "service": { "fullName": "google.cloud.networkservices.v1.NetworkServices", "shortName": "NetworkServices" }, - "shortName": "GetWasmPluginVersion" + "shortName": "GetWasmPlugin" }, "parameters": [ { "name": "request", - "type": "google.cloud.network_services_v1.types.GetWasmPluginVersionRequest" + "type": "google.cloud.network_services_v1.types.GetWasmPluginRequest" }, { "name": "name", @@ -8855,14 +9515,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.network_services_v1.types.WasmPluginVersion", - "shortName": "get_wasm_plugin_version" + "resultType": "google.cloud.network_services_v1.types.WasmPlugin", + "shortName": "get_wasm_plugin" }, - "description": "Sample for GetWasmPluginVersion", - "file": "networkservices_v1_generated_network_services_get_wasm_plugin_version_async.py", + "description": "Sample for GetWasmPlugin", + "file": "networkservices_v1_generated_network_services_get_wasm_plugin_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "networkservices_v1_generated_NetworkServices_GetWasmPluginVersion_async", + "regionTag": "networkservices_v1_generated_NetworkServices_GetWasmPlugin_async", "segments": [ { "end": 51, @@ -8895,7 +9555,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "networkservices_v1_generated_network_services_get_wasm_plugin_version_async.py" + "title": "networkservices_v1_generated_network_services_get_wasm_plugin_async.py" }, { "canonical": true, @@ -8904,19 +9564,19 @@ "fullName": "google.cloud.network_services_v1.NetworkServicesClient", "shortName": "NetworkServicesClient" }, - "fullName": "google.cloud.network_services_v1.NetworkServicesClient.get_wasm_plugin_version", + "fullName": "google.cloud.network_services_v1.NetworkServicesClient.get_wasm_plugin", "method": { - "fullName": "google.cloud.networkservices.v1.NetworkServices.GetWasmPluginVersion", + "fullName": "google.cloud.networkservices.v1.NetworkServices.GetWasmPlugin", "service": { "fullName": "google.cloud.networkservices.v1.NetworkServices", "shortName": "NetworkServices" }, - "shortName": "GetWasmPluginVersion" + "shortName": "GetWasmPlugin" }, "parameters": [ { "name": "request", - "type": "google.cloud.network_services_v1.types.GetWasmPluginVersionRequest" + "type": "google.cloud.network_services_v1.types.GetWasmPluginRequest" }, { "name": "name", @@ -8935,14 +9595,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.network_services_v1.types.WasmPluginVersion", - "shortName": "get_wasm_plugin_version" + "resultType": "google.cloud.network_services_v1.types.WasmPlugin", + "shortName": "get_wasm_plugin" }, - "description": "Sample for GetWasmPluginVersion", - "file": "networkservices_v1_generated_network_services_get_wasm_plugin_version_sync.py", + "description": "Sample for GetWasmPlugin", + "file": "networkservices_v1_generated_network_services_get_wasm_plugin_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "networkservices_v1_generated_NetworkServices_GetWasmPluginVersion_sync", + "regionTag": "networkservices_v1_generated_NetworkServices_GetWasmPlugin_sync", "segments": [ { "end": 51, @@ -8975,7 +9635,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "networkservices_v1_generated_network_services_get_wasm_plugin_version_sync.py" + "title": "networkservices_v1_generated_network_services_get_wasm_plugin_sync.py" }, { "canonical": true, @@ -8985,22 +9645,22 @@ "fullName": "google.cloud.network_services_v1.NetworkServicesAsyncClient", "shortName": "NetworkServicesAsyncClient" }, - "fullName": "google.cloud.network_services_v1.NetworkServicesAsyncClient.get_wasm_plugin", + "fullName": "google.cloud.network_services_v1.NetworkServicesAsyncClient.list_agent_gateways", "method": { - "fullName": "google.cloud.networkservices.v1.NetworkServices.GetWasmPlugin", + "fullName": "google.cloud.networkservices.v1.NetworkServices.ListAgentGateways", "service": { "fullName": "google.cloud.networkservices.v1.NetworkServices", "shortName": "NetworkServices" }, - "shortName": "GetWasmPlugin" + "shortName": "ListAgentGateways" }, "parameters": [ { "name": "request", - "type": "google.cloud.network_services_v1.types.GetWasmPluginRequest" + "type": "google.cloud.network_services_v1.types.ListAgentGatewaysRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -9016,22 +9676,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.network_services_v1.types.WasmPlugin", - "shortName": "get_wasm_plugin" + "resultType": "google.cloud.network_services_v1.services.network_services.pagers.ListAgentGatewaysAsyncPager", + "shortName": "list_agent_gateways" }, - "description": "Sample for GetWasmPlugin", - "file": "networkservices_v1_generated_network_services_get_wasm_plugin_async.py", + "description": "Sample for ListAgentGateways", + "file": "networkservices_v1_generated_network_services_list_agent_gateways_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "networkservices_v1_generated_NetworkServices_GetWasmPlugin_async", + "regionTag": "networkservices_v1_generated_NetworkServices_ListAgentGateways_async", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -9051,12 +9711,12 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "networkservices_v1_generated_network_services_get_wasm_plugin_async.py" + "title": "networkservices_v1_generated_network_services_list_agent_gateways_async.py" }, { "canonical": true, @@ -9065,22 +9725,22 @@ "fullName": "google.cloud.network_services_v1.NetworkServicesClient", "shortName": "NetworkServicesClient" }, - "fullName": "google.cloud.network_services_v1.NetworkServicesClient.get_wasm_plugin", + "fullName": "google.cloud.network_services_v1.NetworkServicesClient.list_agent_gateways", "method": { - "fullName": "google.cloud.networkservices.v1.NetworkServices.GetWasmPlugin", + "fullName": "google.cloud.networkservices.v1.NetworkServices.ListAgentGateways", "service": { "fullName": "google.cloud.networkservices.v1.NetworkServices", "shortName": "NetworkServices" }, - "shortName": "GetWasmPlugin" + "shortName": "ListAgentGateways" }, "parameters": [ { "name": "request", - "type": "google.cloud.network_services_v1.types.GetWasmPluginRequest" + "type": "google.cloud.network_services_v1.types.ListAgentGatewaysRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -9096,22 +9756,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.network_services_v1.types.WasmPlugin", - "shortName": "get_wasm_plugin" + "resultType": "google.cloud.network_services_v1.services.network_services.pagers.ListAgentGatewaysPager", + "shortName": "list_agent_gateways" }, - "description": "Sample for GetWasmPlugin", - "file": "networkservices_v1_generated_network_services_get_wasm_plugin_sync.py", + "description": "Sample for ListAgentGateways", + "file": "networkservices_v1_generated_network_services_list_agent_gateways_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "networkservices_v1_generated_NetworkServices_GetWasmPlugin_sync", + "regionTag": "networkservices_v1_generated_NetworkServices_ListAgentGateways_sync", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -9131,12 +9791,12 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "networkservices_v1_generated_network_services_get_wasm_plugin_sync.py" + "title": "networkservices_v1_generated_network_services_list_agent_gateways_sync.py" }, { "canonical": true, @@ -11231,6 +11891,175 @@ ], "title": "networkservices_v1_generated_network_services_list_wasm_plugins_sync.py" }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.network_services_v1.NetworkServicesAsyncClient", + "shortName": "NetworkServicesAsyncClient" + }, + "fullName": "google.cloud.network_services_v1.NetworkServicesAsyncClient.update_agent_gateway", + "method": { + "fullName": "google.cloud.networkservices.v1.NetworkServices.UpdateAgentGateway", + "service": { + "fullName": "google.cloud.networkservices.v1.NetworkServices", + "shortName": "NetworkServices" + }, + "shortName": "UpdateAgentGateway" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.network_services_v1.types.UpdateAgentGatewayRequest" + }, + { + "name": "agent_gateway", + "type": "google.cloud.network_services_v1.types.AgentGateway" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "update_agent_gateway" + }, + "description": "Sample for UpdateAgentGateway", + "file": "networkservices_v1_generated_network_services_update_agent_gateway_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "networkservices_v1_generated_NetworkServices_UpdateAgentGateway_async", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "networkservices_v1_generated_network_services_update_agent_gateway_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.network_services_v1.NetworkServicesClient", + "shortName": "NetworkServicesClient" + }, + "fullName": "google.cloud.network_services_v1.NetworkServicesClient.update_agent_gateway", + "method": { + "fullName": "google.cloud.networkservices.v1.NetworkServices.UpdateAgentGateway", + "service": { + "fullName": "google.cloud.networkservices.v1.NetworkServices", + "shortName": "NetworkServices" + }, + "shortName": "UpdateAgentGateway" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.network_services_v1.types.UpdateAgentGatewayRequest" + }, + { + "name": "agent_gateway", + "type": "google.cloud.network_services_v1.types.AgentGateway" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "update_agent_gateway" + }, + "description": "Sample for UpdateAgentGateway", + "file": "networkservices_v1_generated_network_services_update_agent_gateway_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "networkservices_v1_generated_NetworkServices_UpdateAgentGateway_sync", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "networkservices_v1_generated_network_services_update_agent_gateway_sync.py" + }, { "canonical": true, "clientMethod": { diff --git a/packages/google-cloud-network-services/tests/unit/gapic/network_services_v1/test_dep_service.py b/packages/google-cloud-network-services/tests/unit/gapic/network_services_v1/test_dep_service.py index 662b5f55a83a..9d362799288a 100644 --- a/packages/google-cloud-network-services/tests/unit/gapic/network_services_v1/test_dep_service.py +++ b/packages/google-cloud-network-services/tests/unit/gapic/network_services_v1/test_dep_service.py @@ -7835,6 +7835,7 @@ def test_get_authz_extension(request_type, transport: str = "grpc"): service="service_value", fail_open=True, forward_headers=["forward_headers_value"], + forward_attributes=["forward_attributes_value"], wire_format=dep.WireFormat.EXT_PROC_GRPC, ) response = client.get_authz_extension(request) @@ -7854,6 +7855,7 @@ def test_get_authz_extension(request_type, transport: str = "grpc"): assert response.service == "service_value" assert response.fail_open is True assert response.forward_headers == ["forward_headers_value"] + assert response.forward_attributes == ["forward_attributes_value"] assert response.wire_format == dep.WireFormat.EXT_PROC_GRPC @@ -8001,6 +8003,7 @@ async def test_get_authz_extension_async(request_type, transport: str = "grpc_as service="service_value", fail_open=True, forward_headers=["forward_headers_value"], + forward_attributes=["forward_attributes_value"], wire_format=dep.WireFormat.EXT_PROC_GRPC, ) ) @@ -8021,6 +8024,7 @@ async def test_get_authz_extension_async(request_type, transport: str = "grpc_as assert response.service == "service_value" assert response.fail_open is True assert response.forward_headers == ["forward_headers_value"] + assert response.forward_attributes == ["forward_attributes_value"] assert response.wire_format == dep.WireFormat.EXT_PROC_GRPC @@ -14501,6 +14505,7 @@ async def test_get_authz_extension_empty_call_grpc_asyncio(): service="service_value", fail_open=True, forward_headers=["forward_headers_value"], + forward_attributes=["forward_attributes_value"], wire_format=dep.WireFormat.EXT_PROC_GRPC, ) ) @@ -14940,7 +14945,14 @@ def test_create_lb_traffic_extension_rest_call_success(request_type): "forward_headers_value1", "forward_headers_value2", ], + "forward_attributes": [ + "forward_attributes_value1", + "forward_attributes_value2", + ], "metadata": {"fields": {}}, + "request_body_send_mode": 1, + "response_body_send_mode": 1, + "observability_mode": True, } ], } @@ -15174,7 +15186,14 @@ def test_update_lb_traffic_extension_rest_call_success(request_type): "forward_headers_value1", "forward_headers_value2", ], + "forward_attributes": [ + "forward_attributes_value1", + "forward_attributes_value2", + ], "metadata": {"fields": {}}, + "request_body_send_mode": 1, + "response_body_send_mode": 1, + "observability_mode": True, } ], } @@ -15804,7 +15823,14 @@ def test_create_lb_route_extension_rest_call_success(request_type): "forward_headers_value1", "forward_headers_value2", ], + "forward_attributes": [ + "forward_attributes_value1", + "forward_attributes_value2", + ], "metadata": {"fields": {}}, + "request_body_send_mode": 1, + "response_body_send_mode": 1, + "observability_mode": True, } ], } @@ -16036,7 +16062,14 @@ def test_update_lb_route_extension_rest_call_success(request_type): "forward_headers_value1", "forward_headers_value2", ], + "forward_attributes": [ + "forward_attributes_value1", + "forward_attributes_value2", + ], "metadata": {"fields": {}}, + "request_body_send_mode": 1, + "response_body_send_mode": 1, + "observability_mode": True, } ], } @@ -16664,7 +16697,14 @@ def test_create_lb_edge_extension_rest_call_success(request_type): "forward_headers_value1", "forward_headers_value2", ], + "forward_attributes": [ + "forward_attributes_value1", + "forward_attributes_value2", + ], "metadata": {"fields": {}}, + "request_body_send_mode": 1, + "response_body_send_mode": 1, + "observability_mode": True, } ], } @@ -16895,7 +16935,14 @@ def test_update_lb_edge_extension_rest_call_success(request_type): "forward_headers_value1", "forward_headers_value2", ], + "forward_attributes": [ + "forward_attributes_value1", + "forward_attributes_value2", + ], "metadata": {"fields": {}}, + "request_body_send_mode": 1, + "response_body_send_mode": 1, + "observability_mode": True, } ], } @@ -17375,6 +17422,7 @@ def test_get_authz_extension_rest_call_success(request_type): service="service_value", fail_open=True, forward_headers=["forward_headers_value"], + forward_attributes=["forward_attributes_value"], wire_format=dep.WireFormat.EXT_PROC_GRPC, ) @@ -17399,6 +17447,7 @@ def test_get_authz_extension_rest_call_success(request_type): assert response.service == "service_value" assert response.fail_open is True assert response.forward_headers == ["forward_headers_value"] + assert response.forward_attributes == ["forward_attributes_value"] assert response.wire_format == dep.WireFormat.EXT_PROC_GRPC @@ -17518,6 +17567,10 @@ def test_create_authz_extension_rest_call_success(request_type): "fail_open": True, "metadata": {"fields": {}}, "forward_headers": ["forward_headers_value1", "forward_headers_value2"], + "forward_attributes": [ + "forward_attributes_value1", + "forward_attributes_value2", + ], "wire_format": 1, } # The version of a generated dependency at test runtime may differ from the version used during generation. @@ -17734,6 +17787,10 @@ def test_update_authz_extension_rest_call_success(request_type): "fail_open": True, "metadata": {"fields": {}}, "forward_headers": ["forward_headers_value1", "forward_headers_value2"], + "forward_attributes": [ + "forward_attributes_value1", + "forward_attributes_value2", + ], "wire_format": 1, } # The version of a generated dependency at test runtime may differ from the version used during generation. diff --git a/packages/google-cloud-network-services/tests/unit/gapic/network_services_v1/test_network_services.py b/packages/google-cloud-network-services/tests/unit/gapic/network_services_v1/test_network_services.py index 6847a6781589..e4538e8eb636 100644 --- a/packages/google-cloud-network-services/tests/unit/gapic/network_services_v1/test_network_services.py +++ b/packages/google-cloud-network-services/tests/unit/gapic/network_services_v1/test_network_services.py @@ -74,6 +74,7 @@ transports, ) from google.cloud.network_services_v1.types import ( + agent_gateway, common, endpoint_policy, extensibility, @@ -87,6 +88,7 @@ tcp_route, tls_route, ) +from google.cloud.network_services_v1.types import agent_gateway as gcn_agent_gateway from google.cloud.network_services_v1.types import ( endpoint_policy as gcn_endpoint_policy, ) @@ -7516,6 +7518,7 @@ def test_get_gateway(request_type, transport: str = "grpc"): type_=gateway.Gateway.Type.OPEN_MESH, addresses=["addresses_value"], ports=[568], + all_ports=True, scope="scope_value", server_tls_policy="server_tls_policy_value", certificate_urls=["certificate_urls_value"], @@ -7525,6 +7528,7 @@ def test_get_gateway(request_type, transport: str = "grpc"): ip_version=gateway.Gateway.IpVersion.IPV4, envoy_headers=common.EnvoyHeaders.NONE, routing_mode=gateway.Gateway.RoutingMode.NEXT_HOP_ROUTING_MODE, + allow_global_access=True, ) response = client.get_gateway(request) @@ -7542,6 +7546,7 @@ def test_get_gateway(request_type, transport: str = "grpc"): assert response.type_ == gateway.Gateway.Type.OPEN_MESH assert response.addresses == ["addresses_value"] assert response.ports == [568] + assert response.all_ports is True assert response.scope == "scope_value" assert response.server_tls_policy == "server_tls_policy_value" assert response.certificate_urls == ["certificate_urls_value"] @@ -7551,6 +7556,7 @@ def test_get_gateway(request_type, transport: str = "grpc"): assert response.ip_version == gateway.Gateway.IpVersion.IPV4 assert response.envoy_headers == common.EnvoyHeaders.NONE assert response.routing_mode == gateway.Gateway.RoutingMode.NEXT_HOP_ROUTING_MODE + assert response.allow_global_access is True def test_get_gateway_non_empty_request_with_auto_populated_field(): @@ -7688,6 +7694,7 @@ async def test_get_gateway_async(request_type, transport: str = "grpc_asyncio"): type_=gateway.Gateway.Type.OPEN_MESH, addresses=["addresses_value"], ports=[568], + all_ports=True, scope="scope_value", server_tls_policy="server_tls_policy_value", certificate_urls=["certificate_urls_value"], @@ -7697,6 +7704,7 @@ async def test_get_gateway_async(request_type, transport: str = "grpc_asyncio"): ip_version=gateway.Gateway.IpVersion.IPV4, envoy_headers=common.EnvoyHeaders.NONE, routing_mode=gateway.Gateway.RoutingMode.NEXT_HOP_ROUTING_MODE, + allow_global_access=True, ) ) response = await client.get_gateway(request) @@ -7715,6 +7723,7 @@ async def test_get_gateway_async(request_type, transport: str = "grpc_asyncio"): assert response.type_ == gateway.Gateway.Type.OPEN_MESH assert response.addresses == ["addresses_value"] assert response.ports == [568] + assert response.all_ports is True assert response.scope == "scope_value" assert response.server_tls_policy == "server_tls_policy_value" assert response.certificate_urls == ["certificate_urls_value"] @@ -7724,6 +7733,7 @@ async def test_get_gateway_async(request_type, transport: str = "grpc_asyncio"): assert response.ip_version == gateway.Gateway.IpVersion.IPV4 assert response.envoy_headers == common.EnvoyHeaders.NONE assert response.routing_mode == gateway.Gateway.RoutingMode.NEXT_HOP_ROUTING_MODE + assert response.allow_global_access is True def test_get_gateway_field_headers(): @@ -10855,6 +10865,7 @@ def test_list_http_routes_non_empty_request_with_auto_populated_field(): request = http_route.ListHttpRoutesRequest( parent="parent_value", page_token="page_token_value", + filter="filter_value", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -10868,6 +10879,7 @@ def test_list_http_routes_non_empty_request_with_auto_populated_field(): request_msg = http_route.ListHttpRoutesRequest( parent="parent_value", page_token="page_token_value", + filter="filter_value", ) assert args[0] == request_msg @@ -15149,6 +15161,7 @@ def test_get_tls_route(request_type, transport: str = "grpc"): description="description_value", meshes=["meshes_value"], gateways=["gateways_value"], + target_proxies=["target_proxies_value"], ) response = client.get_tls_route(request) @@ -15165,6 +15178,7 @@ def test_get_tls_route(request_type, transport: str = "grpc"): assert response.description == "description_value" assert response.meshes == ["meshes_value"] assert response.gateways == ["gateways_value"] + assert response.target_proxies == ["target_proxies_value"] def test_get_tls_route_non_empty_request_with_auto_populated_field(): @@ -15301,6 +15315,7 @@ async def test_get_tls_route_async(request_type, transport: str = "grpc_asyncio" description="description_value", meshes=["meshes_value"], gateways=["gateways_value"], + target_proxies=["target_proxies_value"], ) ) response = await client.get_tls_route(request) @@ -15318,6 +15333,7 @@ async def test_get_tls_route_async(request_type, transport: str = "grpc_asyncio" assert response.description == "description_value" assert response.meshes == ["meshes_value"] assert response.gateways == ["gateways_value"] + assert response.target_proxies == ["target_proxies_value"] def test_get_tls_route_field_headers(): @@ -24125,13 +24141,86 @@ async def test_list_mesh_route_views_async_pages(): assert page_.raw_page.next_page_token == token -def test_list_endpoint_policies_rest_use_cached_wrapped_rpc(): +@pytest.mark.parametrize( + "request_type", + [ + agent_gateway.ListAgentGatewaysRequest(), + {}, + ], +) +def test_list_agent_gateways(request_type, transport: str = "grpc"): + client = NetworkServicesClient( + 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_agent_gateways), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = agent_gateway.ListAgentGatewaysResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + response = client.list_agent_gateways(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = agent_gateway.ListAgentGatewaysRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListAgentGatewaysPager) + assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] + + +def test_list_agent_gateways_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = agent_gateway.ListAgentGatewaysRequest( + parent="parent_value", + page_token="page_token_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_agent_gateways), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.list_agent_gateways(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = agent_gateway.ListAgentGatewaysRequest( + parent="parent_value", + page_token="page_token_value", + ) + assert args[0] == request_msg + + +def test_list_agent_gateways_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) # Should wrap all calls on client creation @@ -24140,8 +24229,7 @@ def test_list_endpoint_policies_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.list_endpoint_policies - in client._transport._wrapped_methods + client._transport.list_agent_gateways in client._transport._wrapped_methods ) # Replace cached wrapped function with mock @@ -24149,436 +24237,540 @@ def test_list_endpoint_policies_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.list_endpoint_policies] = ( + client._transport._wrapped_methods[client._transport.list_agent_gateways] = ( mock_rpc ) - request = {} - client.list_endpoint_policies(request) + client.list_agent_gateways(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_endpoint_policies(request) + client.list_agent_gateways(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_endpoint_policies_rest_required_fields( - request_type=endpoint_policy.ListEndpointPoliciesRequest, +@pytest.mark.asyncio +async def test_list_agent_gateways_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", ): - transport_class = transports.NetworkServicesRestTransport + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - request_init = {} - request_init["parent"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # verify fields with default values are dropped + # Ensure method has been cached + assert ( + client._client._transport.list_agent_gateways + in client._client._transport._wrapped_methods + ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_endpoint_policies._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.list_agent_gateways + ] = mock_rpc - # verify required fields with default values are now present + request = {} + await client.list_agent_gateways(request) - jsonified_request["parent"] = "parent_value" + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_endpoint_policies._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "page_size", - "page_token", - "return_partial_success", - ) + await client.list_agent_gateways(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + agent_gateway.ListAgentGatewaysRequest(), + {}, + ], +) +async def test_list_agent_gateways_async(request_type, transport: str = "grpc_asyncio"): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, ) - jsonified_request.update(unset_fields) - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" + # 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_agent_gateways), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + agent_gateway.ListAgentGatewaysResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + response = await client.list_agent_gateways(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = agent_gateway.ListAgentGatewaysRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListAgentGatewaysAsyncPager) + assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] + +def test_list_agent_gateways_field_headers(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = endpoint_policy.ListEndpointPoliciesResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - response_value = Response() - response_value.status_code = 200 + # 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 = agent_gateway.ListAgentGatewaysRequest() - # Convert return value to protobuf type - return_value = endpoint_policy.ListEndpointPoliciesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + request.parent = "parent_value" - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_agent_gateways), "__call__" + ) as call: + call.return_value = agent_gateway.ListAgentGatewaysResponse() + client.list_agent_gateways(request) - response = client.list_endpoint_policies(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 - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + # 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_endpoint_policies_rest_unset_required_fields(): - transport = transports.NetworkServicesRestTransport( - credentials=ga_credentials.AnonymousCredentials +@pytest.mark.asyncio +async def test_list_agent_gateways_field_headers_async(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), ) - unset_fields = transport.list_endpoint_policies._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "pageSize", - "pageToken", - "returnPartialSuccess", - ) + # 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 = agent_gateway.ListAgentGatewaysRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_agent_gateways), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + agent_gateway.ListAgentGatewaysResponse() ) - & set(("parent",)) - ) + await client.list_agent_gateways(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_endpoint_policies_rest_flattened(): +def test_list_agent_gateways_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = endpoint_policy.ListEndpointPoliciesResponse() + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_agent_gateways), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = agent_gateway.ListAgentGatewaysResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_agent_gateways( + parent="parent_value", + ) - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} + # 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 - # get truthy value for each flattened field - mock_args = dict( + +def test_list_agent_gateways_flattened_error(): + client = NetworkServicesClient( + 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_agent_gateways( + agent_gateway.ListAgentGatewaysRequest(), parent="parent_value", ) - mock_args.update(sample_request) - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = endpoint_policy.ListEndpointPoliciesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_endpoint_policies(**mock_args) +@pytest.mark.asyncio +async def test_list_agent_gateways_flattened_async(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_agent_gateways), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = agent_gateway.ListAgentGatewaysResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + agent_gateway.ListAgentGatewaysResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_agent_gateways( + parent="parent_value", + ) # Establish that the underlying call was made with the expected # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/endpointPolicies" - % client.transport._host, - args[1], - ) + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val -def test_list_endpoint_policies_rest_flattened_error(transport: str = "rest"): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, +@pytest.mark.asyncio +async def test_list_agent_gateways_flattened_error_async(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_endpoint_policies( - endpoint_policy.ListEndpointPoliciesRequest(), + await client.list_agent_gateways( + agent_gateway.ListAgentGatewaysRequest(), parent="parent_value", ) -def test_list_endpoint_policies_rest_pager(transport: str = "rest"): +def test_list_agent_gateways_pager(transport_name: str = "grpc"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport=transport_name, ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - endpoint_policy.ListEndpointPoliciesResponse( - endpoint_policies=[ - endpoint_policy.EndpointPolicy(), - endpoint_policy.EndpointPolicy(), - endpoint_policy.EndpointPolicy(), + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_agent_gateways), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + agent_gateway.ListAgentGatewaysResponse( + agent_gateways=[ + agent_gateway.AgentGateway(), + agent_gateway.AgentGateway(), + agent_gateway.AgentGateway(), ], next_page_token="abc", ), - endpoint_policy.ListEndpointPoliciesResponse( - endpoint_policies=[], + agent_gateway.ListAgentGatewaysResponse( + agent_gateways=[], next_page_token="def", ), - endpoint_policy.ListEndpointPoliciesResponse( - endpoint_policies=[ - endpoint_policy.EndpointPolicy(), + agent_gateway.ListAgentGatewaysResponse( + agent_gateways=[ + agent_gateway.AgentGateway(), ], next_page_token="ghi", ), - endpoint_policy.ListEndpointPoliciesResponse( - endpoint_policies=[ - endpoint_policy.EndpointPolicy(), - endpoint_policy.EndpointPolicy(), + agent_gateway.ListAgentGatewaysResponse( + agent_gateways=[ + agent_gateway.AgentGateway(), + agent_gateway.AgentGateway(), ], ), + RuntimeError, ) - # Two responses for two calls - response = response + response - # Wrap the values into proper Response objs - response = tuple( - endpoint_policy.ListEndpointPoliciesResponse.to_json(x) for x in response + expected_metadata = () + retry = retries.Retry() + timeout = 5 + expected_metadata = tuple(expected_metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "projects/sample1/locations/sample2"} + pager = client.list_agent_gateways(request={}, retry=retry, timeout=timeout) - pager = client.list_endpoint_policies(request=sample_request) + assert pager._metadata == expected_metadata + assert pager._retry == retry + assert pager._timeout == timeout results = list(pager) assert len(results) == 6 - assert all(isinstance(i, endpoint_policy.EndpointPolicy) for i in results) + assert all(isinstance(i, agent_gateway.AgentGateway) for i in results) - pages = list(client.list_endpoint_policies(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token +def test_list_agent_gateways_pages(transport_name: str = "grpc"): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) -def test_get_endpoint_policy_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_agent_gateways), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + agent_gateway.ListAgentGatewaysResponse( + agent_gateways=[ + agent_gateway.AgentGateway(), + agent_gateway.AgentGateway(), + agent_gateway.AgentGateway(), + ], + next_page_token="abc", + ), + agent_gateway.ListAgentGatewaysResponse( + agent_gateways=[], + next_page_token="def", + ), + agent_gateway.ListAgentGatewaysResponse( + agent_gateways=[ + agent_gateway.AgentGateway(), + ], + next_page_token="ghi", + ), + agent_gateway.ListAgentGatewaysResponse( + agent_gateways=[ + agent_gateway.AgentGateway(), + agent_gateway.AgentGateway(), + ], + ), + RuntimeError, ) + pages = list(client.list_agent_gateways(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - # Ensure method has been cached - assert ( - client._transport.get_endpoint_policy in client._transport._wrapped_methods - ) +@pytest.mark.asyncio +async def test_list_agent_gateways_async_pager(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + ) - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_agent_gateways), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + agent_gateway.ListAgentGatewaysResponse( + agent_gateways=[ + agent_gateway.AgentGateway(), + agent_gateway.AgentGateway(), + agent_gateway.AgentGateway(), + ], + next_page_token="abc", + ), + agent_gateway.ListAgentGatewaysResponse( + agent_gateways=[], + next_page_token="def", + ), + agent_gateway.ListAgentGatewaysResponse( + agent_gateways=[ + agent_gateway.AgentGateway(), + ], + next_page_token="ghi", + ), + agent_gateway.ListAgentGatewaysResponse( + agent_gateways=[ + agent_gateway.AgentGateway(), + agent_gateway.AgentGateway(), + ], + ), + RuntimeError, ) - client._transport._wrapped_methods[client._transport.get_endpoint_policy] = ( - mock_rpc + async_pager = await client.list_agent_gateways( + request={}, ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) - request = {} - client.get_endpoint_policy(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 + assert len(responses) == 6 + assert all(isinstance(i, agent_gateway.AgentGateway) for i in responses) - client.get_endpoint_policy(request) - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 +@pytest.mark.asyncio +async def test_list_agent_gateways_async_pages(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_agent_gateways), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + agent_gateway.ListAgentGatewaysResponse( + agent_gateways=[ + agent_gateway.AgentGateway(), + agent_gateway.AgentGateway(), + agent_gateway.AgentGateway(), + ], + next_page_token="abc", + ), + agent_gateway.ListAgentGatewaysResponse( + agent_gateways=[], + next_page_token="def", + ), + agent_gateway.ListAgentGatewaysResponse( + agent_gateways=[ + agent_gateway.AgentGateway(), + ], + next_page_token="ghi", + ), + agent_gateway.ListAgentGatewaysResponse( + agent_gateways=[ + agent_gateway.AgentGateway(), + agent_gateway.AgentGateway(), + ], + ), + RuntimeError, + ) + pages = [] + async for page_ in (await client.list_agent_gateways(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token -def test_get_endpoint_policy_rest_required_fields( - request_type=endpoint_policy.GetEndpointPolicyRequest, -): - transport_class = transports.NetworkServicesRestTransport - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) +@pytest.mark.parametrize( + "request_type", + [ + agent_gateway.GetAgentGatewayRequest(), + {}, + ], +) +def test_get_agent_gateway(request_type, transport: str = "grpc"): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_endpoint_policy._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # 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 - # verify required fields with default values are now present + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_agent_gateway), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = agent_gateway.AgentGateway( + name="name_value", + description="description_value", + etag="etag_value", + protocols=[agent_gateway.AgentGateway.Protocol.MCP], + registries=["registries_value"], + ) + response = client.get_agent_gateway(request) - jsonified_request["name"] = "name_value" + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = agent_gateway.GetAgentGatewayRequest() + assert args[0] == request - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_endpoint_policy._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Establish that the response is the type that we expect. + assert isinstance(response, agent_gateway.AgentGateway) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.etag == "etag_value" + assert response.protocols == [agent_gateway.AgentGateway.Protocol.MCP] + assert response.registries == ["registries_value"] - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" +def test_get_agent_gateway_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = endpoint_policy.EndpointPolicy() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = endpoint_policy.EndpointPolicy.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - response = client.get_endpoint_policy(request) - - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) - - -def test_get_endpoint_policy_rest_unset_required_fields(): - transport = transports.NetworkServicesRestTransport( - credentials=ga_credentials.AnonymousCredentials + transport="grpc", ) - unset_fields = transport.get_endpoint_policy._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) - - -def test_get_endpoint_policy_rest_flattened(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = agent_gateway.GetAgentGatewayRequest( + name="name_value", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = endpoint_policy.EndpointPolicy() - - # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/endpointPolicies/sample3" - } - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = endpoint_policy.EndpointPolicy.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - client.get_endpoint_policy(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/endpointPolicies/*}" - % client.transport._host, - args[1], + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_agent_gateway), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. ) - - -def test_get_endpoint_policy_rest_flattened_error(transport: str = "rest"): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.get_endpoint_policy( - endpoint_policy.GetEndpointPolicyRequest(), + client.get_agent_gateway(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = agent_gateway.GetAgentGatewayRequest( name="name_value", ) + assert args[0] == request_msg -def test_create_endpoint_policy_rest_use_cached_wrapped_rpc(): +def test_get_agent_gateway_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) # Should wrap all calls on client creation @@ -24586,210 +24778,346 @@ def test_create_endpoint_policy_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert ( - client._transport.create_endpoint_policy - in client._transport._wrapped_methods - ) + assert client._transport.get_agent_gateway in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.create_endpoint_policy] = ( + client._transport._wrapped_methods[client._transport.get_agent_gateway] = ( mock_rpc ) - request = {} - client.create_endpoint_policy(request) + client.get_agent_gateway(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.create_endpoint_policy(request) + client.get_agent_gateway(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_create_endpoint_policy_rest_required_fields( - request_type=gcn_endpoint_policy.CreateEndpointPolicyRequest, +@pytest.mark.asyncio +async def test_get_agent_gateway_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", ): - transport_class = transports.NetworkServicesRestTransport + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - request_init = {} - request_init["parent"] = "" - request_init["endpoint_policy_id"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # verify fields with default values are dropped - assert "endpointPolicyId" not in jsonified_request + # Ensure method has been cached + assert ( + client._client._transport.get_agent_gateway + in client._client._transport._wrapped_methods + ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).create_endpoint_policy._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.get_agent_gateway + ] = mock_rpc - # verify required fields with default values are now present - assert "endpointPolicyId" in jsonified_request - assert jsonified_request["endpointPolicyId"] == request_init["endpoint_policy_id"] + request = {} + await client.get_agent_gateway(request) - jsonified_request["parent"] = "parent_value" - jsonified_request["endpointPolicyId"] = "endpoint_policy_id_value" + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).create_endpoint_policy._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("endpoint_policy_id",)) - jsonified_request.update(unset_fields) + await client.get_agent_gateway(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + agent_gateway.GetAgentGatewayRequest(), + {}, + ], +) +async def test_get_agent_gateway_async(request_type, transport: str = "grpc_asyncio"): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + 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_agent_gateway), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + agent_gateway.AgentGateway( + name="name_value", + description="description_value", + etag="etag_value", + protocols=[agent_gateway.AgentGateway.Protocol.MCP], + registries=["registries_value"], + ) + ) + response = await client.get_agent_gateway(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = agent_gateway.GetAgentGatewayRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, agent_gateway.AgentGateway) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.etag == "etag_value" + assert response.protocols == [agent_gateway.AgentGateway.Protocol.MCP] + assert response.registries == ["registries_value"] - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" - assert "endpointPolicyId" in jsonified_request - assert jsonified_request["endpointPolicyId"] == "endpoint_policy_id_value" +def test_get_agent_gateway_field_headers(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - request = request_type(**request_init) - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "post", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result + # 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 = agent_gateway.GetAgentGatewayRequest() - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) + request.name = "name_value" - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_agent_gateway), "__call__" + ) as call: + call.return_value = agent_gateway.AgentGateway() + client.get_agent_gateway(request) - response = client.create_endpoint_policy(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 - expected_params = [ - ( - "endpointPolicyId", - "", - ), - ("$alt", "json;enum-encoding=int"), - ] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + # 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_create_endpoint_policy_rest_unset_required_fields(): - transport = transports.NetworkServicesRestTransport( - credentials=ga_credentials.AnonymousCredentials +@pytest.mark.asyncio +async def test_get_agent_gateway_field_headers_async(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), ) - unset_fields = transport.create_endpoint_policy._get_unset_required_fields({}) - assert set(unset_fields) == ( - set(("endpointPolicyId",)) - & set( - ( - "parent", - "endpointPolicyId", - "endpointPolicy", - ) + # 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 = agent_gateway.GetAgentGatewayRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_agent_gateway), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + agent_gateway.AgentGateway() ) - ) + await client.get_agent_gateway(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_create_endpoint_policy_rest_flattened(): +def test_get_agent_gateway_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_agent_gateway), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = agent_gateway.AgentGateway() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_agent_gateway( + name="name_value", + ) - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} + # 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 - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", - endpoint_policy=gcn_endpoint_policy.EndpointPolicy(name="name_value"), - endpoint_policy_id="endpoint_policy_id_value", + +def test_get_agent_gateway_flattened_error(): + client = NetworkServicesClient( + 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_agent_gateway( + agent_gateway.GetAgentGatewayRequest(), + name="name_value", ) - mock_args.update(sample_request) - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_endpoint_policy(**mock_args) +@pytest.mark.asyncio +async def test_get_agent_gateway_flattened_async(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_agent_gateway), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = agent_gateway.AgentGateway() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + agent_gateway.AgentGateway() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_agent_gateway( + name="name_value", + ) # Establish that the underlying call was made with the expected # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/endpointPolicies" - % client.transport._host, - args[1], + 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_agent_gateway_flattened_error_async(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_agent_gateway( + agent_gateway.GetAgentGatewayRequest(), + name="name_value", ) -def test_create_endpoint_policy_rest_flattened_error(transport: str = "rest"): +@pytest.mark.parametrize( + "request_type", + [ + gcn_agent_gateway.CreateAgentGatewayRequest(), + {}, + ], +) +def test_create_agent_gateway(request_type, transport: str = "grpc"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.create_endpoint_policy( - gcn_endpoint_policy.CreateEndpointPolicyRequest(), + # 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_agent_gateway), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.create_agent_gateway(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = gcn_agent_gateway.CreateAgentGatewayRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_create_agent_gateway_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = gcn_agent_gateway.CreateAgentGatewayRequest( + parent="parent_value", + agent_gateway_id="agent_gateway_id_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_agent_gateway), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.create_agent_gateway(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_agent_gateway.CreateAgentGatewayRequest( parent="parent_value", - endpoint_policy=gcn_endpoint_policy.EndpointPolicy(name="name_value"), - endpoint_policy_id="endpoint_policy_id_value", + agent_gateway_id="agent_gateway_id_value", ) + assert args[0] == request_msg -def test_update_endpoint_policy_rest_use_cached_wrapped_rpc(): +def test_create_agent_gateway_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) # Should wrap all calls on client creation @@ -24798,8 +25126,7 @@ def test_update_endpoint_policy_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.update_endpoint_policy - in client._transport._wrapped_methods + client._transport.create_agent_gateway in client._transport._wrapped_methods ) # Replace cached wrapped function with mock @@ -24807,359 +25134,378 @@ def test_update_endpoint_policy_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.update_endpoint_policy] = ( + client._transport._wrapped_methods[client._transport.create_agent_gateway] = ( mock_rpc ) - request = {} - client.update_endpoint_policy(request) + client.create_agent_gateway(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper wrapper_fn.reset_mock() - client.update_endpoint_policy(request) + client.create_agent_gateway(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_update_endpoint_policy_rest_required_fields( - request_type=gcn_endpoint_policy.UpdateEndpointPolicyRequest, +@pytest.mark.asyncio +async def test_create_agent_gateway_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", ): - transport_class = transports.NetworkServicesRestTransport + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - request_init = {} - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).update_endpoint_policy._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Ensure method has been cached + assert ( + client._client._transport.create_agent_gateway + in client._client._transport._wrapped_methods + ) - # verify required fields with default values are now present + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.create_agent_gateway + ] = mock_rpc - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).update_endpoint_policy._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("update_mask",)) - jsonified_request.update(unset_fields) + request = {} + await client.create_agent_gateway(request) - # verify required fields with non-default values are left alone + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "patch", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result + await client.create_agent_gateway(request) - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_endpoint_policy(request) +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + gcn_agent_gateway.CreateAgentGatewayRequest(), + {}, + ], +) +async def test_create_agent_gateway_async( + request_type, transport: str = "grpc_asyncio" +): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + # 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_agent_gateway), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + response = await client.create_agent_gateway(request) -def test_update_endpoint_policy_rest_unset_required_fields(): - transport = transports.NetworkServicesRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = gcn_agent_gateway.CreateAgentGatewayRequest() + assert args[0] == request - unset_fields = transport.update_endpoint_policy._get_unset_required_fields({}) - assert set(unset_fields) == (set(("updateMask",)) & set(("endpointPolicy",))) + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) -def test_update_endpoint_policy_rest_flattened(): +def test_create_agent_gateway_field_headers(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # get arguments that satisfy an http rule for this method - sample_request = { - "endpoint_policy": { - "name": "projects/sample1/locations/sample2/endpointPolicies/sample3" - } - } + # 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 = gcn_agent_gateway.CreateAgentGatewayRequest() - # get truthy value for each flattened field - mock_args = dict( - endpoint_policy=gcn_endpoint_policy.EndpointPolicy(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), - ) - mock_args.update(sample_request) + request.parent = "parent_value" - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_agent_gateway), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_agent_gateway(request) - client.update_endpoint_policy(**mock_args) + # 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 underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{endpoint_policy.name=projects/*/locations/*/endpointPolicies/*}" - % client.transport._host, - args[1], - ) + # 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_update_endpoint_policy_rest_flattened_error(transport: str = "rest"): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, +@pytest.mark.asyncio +async def test_create_agent_gateway_field_headers_async(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), ) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.update_endpoint_policy( - gcn_endpoint_policy.UpdateEndpointPolicyRequest(), - endpoint_policy=gcn_endpoint_policy.EndpointPolicy(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), - ) - - -def test_delete_endpoint_policy_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() + # 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 = gcn_agent_gateway.CreateAgentGatewayRequest() - # Ensure method has been cached - assert ( - client._transport.delete_endpoint_policy - in client._transport._wrapped_methods - ) + request.parent = "parent_value" - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[client._transport.delete_endpoint_policy] = ( - mock_rpc + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_agent_gateway), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") ) - - request = {} - client.delete_endpoint_policy(request) + await client.create_agent_gateway(request) # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.delete_endpoint_policy(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 + 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_delete_endpoint_policy_rest_required_fields( - request_type=endpoint_policy.DeleteEndpointPolicyRequest, -): - transport_class = transports.NetworkServicesRestTransport - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) +def test_create_agent_gateway_flattened(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), ) - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).delete_endpoint_policy._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["name"] = "name_value" + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_agent_gateway), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_agent_gateway( + parent="parent_value", + agent_gateway=gcn_agent_gateway.AgentGateway( + google_managed=gcn_agent_gateway.AgentGateway.GoogleManaged( + governed_access_path=gcn_agent_gateway.AgentGateway.GoogleManaged.GovernedAccessPath.AGENT_TO_ANYWHERE + ) + ), + agent_gateway_id="agent_gateway_id_value", + ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).delete_endpoint_policy._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # 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].agent_gateway + mock_val = gcn_agent_gateway.AgentGateway( + google_managed=gcn_agent_gateway.AgentGateway.GoogleManaged( + governed_access_path=gcn_agent_gateway.AgentGateway.GoogleManaged.GovernedAccessPath.AGENT_TO_ANYWHERE + ) + ) + assert arg == mock_val + arg = args[0].agent_gateway_id + mock_val = "agent_gateway_id_value" + assert arg == mock_val - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" +def test_create_agent_gateway_flattened_error(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - request = request_type(**request_init) - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "delete", - "query_params": pb_request, - } - transcode.return_value = transcode_result + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_agent_gateway( + gcn_agent_gateway.CreateAgentGatewayRequest(), + parent="parent_value", + agent_gateway=gcn_agent_gateway.AgentGateway( + google_managed=gcn_agent_gateway.AgentGateway.GoogleManaged( + governed_access_path=gcn_agent_gateway.AgentGateway.GoogleManaged.GovernedAccessPath.AGENT_TO_ANYWHERE + ) + ), + agent_gateway_id="agent_gateway_id_value", + ) - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} +@pytest.mark.asyncio +async def test_create_agent_gateway_flattened_async(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + ) - response = client.delete_endpoint_policy(request) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_agent_gateway), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_agent_gateway( + parent="parent_value", + agent_gateway=gcn_agent_gateway.AgentGateway( + google_managed=gcn_agent_gateway.AgentGateway.GoogleManaged( + governed_access_path=gcn_agent_gateway.AgentGateway.GoogleManaged.GovernedAccessPath.AGENT_TO_ANYWHERE + ) + ), + agent_gateway_id="agent_gateway_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].agent_gateway + mock_val = gcn_agent_gateway.AgentGateway( + google_managed=gcn_agent_gateway.AgentGateway.GoogleManaged( + governed_access_path=gcn_agent_gateway.AgentGateway.GoogleManaged.GovernedAccessPath.AGENT_TO_ANYWHERE + ) + ) + assert arg == mock_val + arg = args[0].agent_gateway_id + mock_val = "agent_gateway_id_value" + assert arg == mock_val -def test_delete_endpoint_policy_rest_unset_required_fields(): - transport = transports.NetworkServicesRestTransport( - credentials=ga_credentials.AnonymousCredentials + +@pytest.mark.asyncio +async def test_create_agent_gateway_flattened_error_async(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), ) - unset_fields = transport.delete_endpoint_policy._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_agent_gateway( + gcn_agent_gateway.CreateAgentGatewayRequest(), + parent="parent_value", + agent_gateway=gcn_agent_gateway.AgentGateway( + google_managed=gcn_agent_gateway.AgentGateway.GoogleManaged( + governed_access_path=gcn_agent_gateway.AgentGateway.GoogleManaged.GovernedAccessPath.AGENT_TO_ANYWHERE + ) + ), + agent_gateway_id="agent_gateway_id_value", + ) -def test_delete_endpoint_policy_rest_flattened(): +@pytest.mark.parametrize( + "request_type", + [ + gcn_agent_gateway.UpdateAgentGatewayRequest(), + {}, + ], +) +def test_update_agent_gateway(request_type, transport: str = "grpc"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport=transport, ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/endpointPolicies/sample3" - } - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) + # 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 - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_agent_gateway), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.update_agent_gateway(request) - client.delete_endpoint_policy(**mock_args) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = gcn_agent_gateway.UpdateAgentGatewayRequest() + assert args[0] == request - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/endpointPolicies/*}" - % client.transport._host, - args[1], - ) + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) -def test_delete_endpoint_policy_rest_flattened_error(transport: str = "rest"): +def test_update_agent_gateway_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport="grpc", ) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.delete_endpoint_policy( - endpoint_policy.DeleteEndpointPolicyRequest(), - name="name_value", + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = gcn_agent_gateway.UpdateAgentGatewayRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_agent_gateway), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. ) + client.update_agent_gateway(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_agent_gateway.UpdateAgentGatewayRequest() + assert args[0] == request_msg -def test_list_wasm_plugin_versions_rest_use_cached_wrapped_rpc(): +def test_update_agent_gateway_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) # Should wrap all calls on client creation @@ -25168,8 +25514,7 @@ def test_list_wasm_plugin_versions_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.list_wasm_plugin_versions - in client._transport._wrapped_methods + client._transport.update_agent_gateway in client._transport._wrapped_methods ) # Replace cached wrapped function with mock @@ -25177,254 +25522,374 @@ def test_list_wasm_plugin_versions_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[ - client._transport.list_wasm_plugin_versions - ] = mock_rpc - + client._transport._wrapped_methods[client._transport.update_agent_gateway] = ( + mock_rpc + ) request = {} - client.list_wasm_plugin_versions(request) + client.update_agent_gateway(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_wasm_plugin_versions(request) + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.update_agent_gateway(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_wasm_plugin_versions_rest_required_fields( - request_type=extensibility.ListWasmPluginVersionsRequest, +@pytest.mark.asyncio +async def test_update_agent_gateway_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", ): - transport_class = transports.NetworkServicesRestTransport + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - request_init = {} - request_init["parent"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # verify fields with default values are dropped + # Ensure method has been cached + assert ( + client._client._transport.update_agent_gateway + in client._client._transport._wrapped_methods + ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_wasm_plugin_versions._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.update_agent_gateway + ] = mock_rpc - # verify required fields with default values are now present + request = {} + await client.update_agent_gateway(request) - jsonified_request["parent"] = "parent_value" + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_wasm_plugin_versions._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "page_size", - "page_token", - ) - ) - jsonified_request.update(unset_fields) + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + await client.update_agent_gateway(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + gcn_agent_gateway.UpdateAgentGatewayRequest(), + {}, + ], +) +async def test_update_agent_gateway_async( + request_type, transport: str = "grpc_asyncio" +): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + 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_agent_gateway), "__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.update_agent_gateway(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = gcn_agent_gateway.UpdateAgentGatewayRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" +def test_update_agent_gateway_field_headers(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - request = request_type(**request_init) - # Designate an appropriate value for the returned response. - return_value = extensibility.ListWasmPluginVersionsResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result + # 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 = gcn_agent_gateway.UpdateAgentGatewayRequest() - response_value = Response() - response_value.status_code = 200 + request.agent_gateway.name = "name_value" - # Convert return value to protobuf type - return_value = extensibility.ListWasmPluginVersionsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_agent_gateway), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.update_agent_gateway(request) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request - response = client.list_wasm_plugin_versions(request) + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "agent_gateway.name=name_value", + ) in kw["metadata"] - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) +@pytest.mark.asyncio +async def test_update_agent_gateway_field_headers_async(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = gcn_agent_gateway.UpdateAgentGatewayRequest() -def test_list_wasm_plugin_versions_rest_unset_required_fields(): - transport = transports.NetworkServicesRestTransport( - credentials=ga_credentials.AnonymousCredentials + request.agent_gateway.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_agent_gateway), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.update_agent_gateway(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", + "agent_gateway.name=name_value", + ) in kw["metadata"] + + +def test_update_agent_gateway_flattened(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), ) - unset_fields = transport.list_wasm_plugin_versions._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "pageSize", - "pageToken", + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_agent_gateway), "__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.update_agent_gateway( + agent_gateway=gcn_agent_gateway.AgentGateway( + google_managed=gcn_agent_gateway.AgentGateway.GoogleManaged( + governed_access_path=gcn_agent_gateway.AgentGateway.GoogleManaged.GovernedAccessPath.AGENT_TO_ANYWHERE + ) + ), + 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].agent_gateway + mock_val = gcn_agent_gateway.AgentGateway( + google_managed=gcn_agent_gateway.AgentGateway.GoogleManaged( + governed_access_path=gcn_agent_gateway.AgentGateway.GoogleManaged.GovernedAccessPath.AGENT_TO_ANYWHERE ) ) - & set(("parent",)) - ) + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val -def test_list_wasm_plugin_versions_rest_flattened(): +def test_update_agent_gateway_flattened_error(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = extensibility.ListWasmPluginVersionsResponse() + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_agent_gateway( + gcn_agent_gateway.UpdateAgentGatewayRequest(), + agent_gateway=gcn_agent_gateway.AgentGateway( + google_managed=gcn_agent_gateway.AgentGateway.GoogleManaged( + governed_access_path=gcn_agent_gateway.AgentGateway.GoogleManaged.GovernedAccessPath.AGENT_TO_ANYWHERE + ) + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) - # get arguments that satisfy an http rule for this method - sample_request = { - "parent": "projects/sample1/locations/sample2/wasmPlugins/sample3" - } - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", - ) - mock_args.update(sample_request) +@pytest.mark.asyncio +async def test_update_agent_gateway_flattened_async(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + ) - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = extensibility.ListWasmPluginVersionsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_agent_gateway), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") - client.list_wasm_plugin_versions(**mock_args) + 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.update_agent_gateway( + agent_gateway=gcn_agent_gateway.AgentGateway( + google_managed=gcn_agent_gateway.AgentGateway.GoogleManaged( + governed_access_path=gcn_agent_gateway.AgentGateway.GoogleManaged.GovernedAccessPath.AGENT_TO_ANYWHERE + ) + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) # Establish that the underlying call was made with the expected # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*/wasmPlugins/*}/versions" - % client.transport._host, - args[1], + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].agent_gateway + mock_val = gcn_agent_gateway.AgentGateway( + google_managed=gcn_agent_gateway.AgentGateway.GoogleManaged( + governed_access_path=gcn_agent_gateway.AgentGateway.GoogleManaged.GovernedAccessPath.AGENT_TO_ANYWHERE + ) ) + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val -def test_list_wasm_plugin_versions_rest_flattened_error(transport: str = "rest"): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, +@pytest.mark.asyncio +async def test_update_agent_gateway_flattened_error_async(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_wasm_plugin_versions( - extensibility.ListWasmPluginVersionsRequest(), - parent="parent_value", + await client.update_agent_gateway( + gcn_agent_gateway.UpdateAgentGatewayRequest(), + agent_gateway=gcn_agent_gateway.AgentGateway( + google_managed=gcn_agent_gateway.AgentGateway.GoogleManaged( + governed_access_path=gcn_agent_gateway.AgentGateway.GoogleManaged.GovernedAccessPath.AGENT_TO_ANYWHERE + ) + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) -def test_list_wasm_plugin_versions_rest_pager(transport: str = "rest"): +@pytest.mark.parametrize( + "request_type", + [ + agent_gateway.DeleteAgentGatewayRequest(), + {}, + ], +) +def test_delete_agent_gateway(request_type, transport: str = "grpc"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - extensibility.ListWasmPluginVersionsResponse( - wasm_plugin_versions=[ - extensibility.WasmPluginVersion(), - extensibility.WasmPluginVersion(), - extensibility.WasmPluginVersion(), - ], - next_page_token="abc", - ), - extensibility.ListWasmPluginVersionsResponse( - wasm_plugin_versions=[], - next_page_token="def", - ), - extensibility.ListWasmPluginVersionsResponse( - wasm_plugin_versions=[ - extensibility.WasmPluginVersion(), - ], - next_page_token="ghi", - ), - extensibility.ListWasmPluginVersionsResponse( - wasm_plugin_versions=[ - extensibility.WasmPluginVersion(), - extensibility.WasmPluginVersion(), - ], - ), - ) - # Two responses for two calls - response = response + response + # 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 - # Wrap the values into proper Response objs - response = tuple( - extensibility.ListWasmPluginVersionsResponse.to_json(x) for x in response - ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_agent_gateway), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.delete_agent_gateway(request) - sample_request = { - "parent": "projects/sample1/locations/sample2/wasmPlugins/sample3" - } + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = agent_gateway.DeleteAgentGatewayRequest() + assert args[0] == request - pager = client.list_wasm_plugin_versions(request=sample_request) + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, extensibility.WasmPluginVersion) for i in results) - pages = list(client.list_wasm_plugin_versions(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token +def test_delete_agent_gateway_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = agent_gateway.DeleteAgentGatewayRequest( + name="name_value", + etag="etag_value", + ) -def test_get_wasm_plugin_version_rest_use_cached_wrapped_rpc(): + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_agent_gateway), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.delete_agent_gateway(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = agent_gateway.DeleteAgentGatewayRequest( + name="name_value", + etag="etag_value", + ) + assert args[0] == request_msg + + +def test_delete_agent_gateway_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) # Should wrap all calls on client creation @@ -25433,8 +25898,7 @@ def test_get_wasm_plugin_version_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.get_wasm_plugin_version - in client._transport._wrapped_methods + client._transport.delete_agent_gateway in client._transport._wrapped_methods ) # Replace cached wrapped function with mock @@ -25442,168 +25906,266 @@ def test_get_wasm_plugin_version_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[ - client._transport.get_wasm_plugin_version - ] = mock_rpc - + client._transport._wrapped_methods[client._transport.delete_agent_gateway] = ( + mock_rpc + ) request = {} - client.get_wasm_plugin_version(request) + client.delete_agent_gateway(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.get_wasm_plugin_version(request) + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_agent_gateway(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_get_wasm_plugin_version_rest_required_fields( - request_type=extensibility.GetWasmPluginVersionRequest, +@pytest.mark.asyncio +async def test_delete_agent_gateway_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", ): - transport_class = transports.NetworkServicesRestTransport - - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_wasm_plugin_version._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - # verify required fields with default values are now present + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - jsonified_request["name"] = "name_value" + # Ensure method has been cached + assert ( + client._client._transport.delete_agent_gateway + in client._client._transport._wrapped_methods + ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_wasm_plugin_version._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.delete_agent_gateway + ] = mock_rpc - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + request = {} + await client.delete_agent_gateway(request) - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - # Designate an appropriate value for the returned response. - return_value = extensibility.WasmPluginVersion() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() - response_value = Response() - response_value.status_code = 200 + await client.delete_agent_gateway(request) - # Convert return value to protobuf type - return_value = extensibility.WasmPluginVersion.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_wasm_plugin_version(request) +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + agent_gateway.DeleteAgentGatewayRequest(), + {}, + ], +) +async def test_delete_agent_gateway_async( + request_type, transport: str = "grpc_asyncio" +): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert sorted(expected_params) == sorted(actual_params) + # 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_agent_gateway), "__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.delete_agent_gateway(request) -def test_get_wasm_plugin_version_rest_unset_required_fields(): - transport = transports.NetworkServicesRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = agent_gateway.DeleteAgentGatewayRequest() + assert args[0] == request - unset_fields = transport.get_wasm_plugin_version._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) -def test_get_wasm_plugin_version_rest_flattened(): +def test_delete_agent_gateway_field_headers(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = extensibility.WasmPluginVersion() - - # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/wasmPlugins/sample3/versions/sample4" - } + # 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 = agent_gateway.DeleteAgentGatewayRequest() - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) + request.name = "name_value" - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = extensibility.WasmPluginVersion.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_agent_gateway), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_agent_gateway(request) - client.get_wasm_plugin_version(**mock_args) + # 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 underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/wasmPlugins/*/versions/*}" - % client.transport._host, - args[1], + # 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_agent_gateway_field_headers_async(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = agent_gateway.DeleteAgentGatewayRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_agent_gateway), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") ) + await client.delete_agent_gateway(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_wasm_plugin_version_rest_flattened_error(transport: str = "rest"): + +def test_delete_agent_gateway_flattened(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_agent_gateway), "__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.delete_agent_gateway( + 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_agent_gateway_flattened_error(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, ) # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.get_wasm_plugin_version( - extensibility.GetWasmPluginVersionRequest(), + client.delete_agent_gateway( + agent_gateway.DeleteAgentGatewayRequest(), name="name_value", ) -def test_create_wasm_plugin_version_rest_use_cached_wrapped_rpc(): +@pytest.mark.asyncio +async def test_delete_agent_gateway_flattened_async(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_agent_gateway), "__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.delete_agent_gateway( + 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_agent_gateway_flattened_error_async(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_agent_gateway( + agent_gateway.DeleteAgentGatewayRequest(), + name="name_value", + ) + + +def test_list_endpoint_policies_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -25618,7 +26180,7 @@ def test_create_wasm_plugin_version_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.create_wasm_plugin_version + client._transport.list_endpoint_policies in client._transport._wrapped_methods ) @@ -25627,35 +26189,30 @@ def test_create_wasm_plugin_version_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[ - client._transport.create_wasm_plugin_version - ] = mock_rpc + client._transport._wrapped_methods[client._transport.list_endpoint_policies] = ( + mock_rpc + ) request = {} - client.create_wasm_plugin_version(request) + client.list_endpoint_policies(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.create_wasm_plugin_version(request) + client.list_endpoint_policies(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_create_wasm_plugin_version_rest_required_fields( - request_type=extensibility.CreateWasmPluginVersionRequest, +def test_list_endpoint_policies_rest_required_fields( + request_type=endpoint_policy.ListEndpointPoliciesRequest, ): transport_class = transports.NetworkServicesRestTransport request_init = {} request_init["parent"] = "" - request_init["wasm_plugin_version_id"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -25663,35 +26220,32 @@ def test_create_wasm_plugin_version_rest_required_fields( ) # verify fields with default values are dropped - assert "wasmPluginVersionId" not in jsonified_request unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_wasm_plugin_version._get_unset_required_fields(jsonified_request) + ).list_endpoint_policies._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - assert "wasmPluginVersionId" in jsonified_request - assert ( - jsonified_request["wasmPluginVersionId"] - == request_init["wasm_plugin_version_id"] - ) jsonified_request["parent"] = "parent_value" - jsonified_request["wasmPluginVersionId"] = "wasm_plugin_version_id_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_wasm_plugin_version._get_unset_required_fields(jsonified_request) + ).list_endpoint_policies._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("wasm_plugin_version_id",)) + assert not set(unset_fields) - set( + ( + "page_size", + "page_token", + "return_partial_success", + ) + ) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone assert "parent" in jsonified_request assert jsonified_request["parent"] == "parent_value" - assert "wasmPluginVersionId" in jsonified_request - assert jsonified_request["wasmPluginVersionId"] == "wasm_plugin_version_id_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -25700,7 +26254,7 @@ def test_create_wasm_plugin_version_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = endpoint_policy.ListEndpointPoliciesResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -25712,52 +26266,48 @@ def test_create_wasm_plugin_version_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "post", + "method": "get", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = endpoint_policy.ListEndpointPoliciesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_wasm_plugin_version(request) + response = client.list_endpoint_policies(request) - expected_params = [ - ( - "wasmPluginVersionId", - "", - ), - ("$alt", "json;enum-encoding=int"), - ] + expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_create_wasm_plugin_version_rest_unset_required_fields(): +def test_list_endpoint_policies_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.create_wasm_plugin_version._get_unset_required_fields({}) + unset_fields = transport.list_endpoint_policies._get_unset_required_fields({}) assert set(unset_fields) == ( - set(("wasmPluginVersionId",)) - & set( + set( ( - "parent", - "wasmPluginVersionId", - "wasmPluginVersion", + "pageSize", + "pageToken", + "returnPartialSuccess", ) ) + & set(("parent",)) ) -def test_create_wasm_plugin_version_rest_flattened(): +def test_list_endpoint_policies_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -25766,45 +26316,41 @@ def test_create_wasm_plugin_version_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = endpoint_policy.ListEndpointPoliciesResponse() # get arguments that satisfy an http rule for this method - sample_request = { - "parent": "projects/sample1/locations/sample2/wasmPlugins/sample3" - } + sample_request = {"parent": "projects/sample1/locations/sample2"} # get truthy value for each flattened field mock_args = dict( parent="parent_value", - wasm_plugin_version=extensibility.WasmPluginVersion( - plugin_config_data=b"plugin_config_data_blob" - ), - wasm_plugin_version_id="wasm_plugin_version_id_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = endpoint_policy.ListEndpointPoliciesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_wasm_plugin_version(**mock_args) + client.list_endpoint_policies(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*/wasmPlugins/*}/versions" + "%s/v1/{parent=projects/*/locations/*}/endpointPolicies" % client.transport._host, args[1], ) -def test_create_wasm_plugin_version_rest_flattened_error(transport: str = "rest"): +def test_list_endpoint_policies_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -25813,17 +26359,76 @@ def test_create_wasm_plugin_version_rest_flattened_error(transport: str = "rest" # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.create_wasm_plugin_version( - extensibility.CreateWasmPluginVersionRequest(), + client.list_endpoint_policies( + endpoint_policy.ListEndpointPoliciesRequest(), parent="parent_value", - wasm_plugin_version=extensibility.WasmPluginVersion( - plugin_config_data=b"plugin_config_data_blob" + ) + + +def test_list_endpoint_policies_rest_pager(transport: str = "rest"): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + endpoint_policy.ListEndpointPoliciesResponse( + endpoint_policies=[ + endpoint_policy.EndpointPolicy(), + endpoint_policy.EndpointPolicy(), + endpoint_policy.EndpointPolicy(), + ], + next_page_token="abc", + ), + endpoint_policy.ListEndpointPoliciesResponse( + endpoint_policies=[], + next_page_token="def", + ), + endpoint_policy.ListEndpointPoliciesResponse( + endpoint_policies=[ + endpoint_policy.EndpointPolicy(), + ], + next_page_token="ghi", + ), + endpoint_policy.ListEndpointPoliciesResponse( + endpoint_policies=[ + endpoint_policy.EndpointPolicy(), + endpoint_policy.EndpointPolicy(), + ], ), - wasm_plugin_version_id="wasm_plugin_version_id_value", ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + endpoint_policy.ListEndpointPoliciesResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + sample_request = {"parent": "projects/sample1/locations/sample2"} -def test_delete_wasm_plugin_version_rest_use_cached_wrapped_rpc(): + pager = client.list_endpoint_policies(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, endpoint_policy.EndpointPolicy) for i in results) + + pages = list(client.list_endpoint_policies(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_get_endpoint_policy_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -25838,8 +26443,7 @@ def test_delete_wasm_plugin_version_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.delete_wasm_plugin_version - in client._transport._wrapped_methods + client._transport.get_endpoint_policy in client._transport._wrapped_methods ) # Replace cached wrapped function with mock @@ -25847,29 +26451,25 @@ def test_delete_wasm_plugin_version_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[ - client._transport.delete_wasm_plugin_version - ] = mock_rpc + client._transport._wrapped_methods[client._transport.get_endpoint_policy] = ( + mock_rpc + ) request = {} - client.delete_wasm_plugin_version(request) + client.get_endpoint_policy(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.delete_wasm_plugin_version(request) + client.get_endpoint_policy(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_delete_wasm_plugin_version_rest_required_fields( - request_type=extensibility.DeleteWasmPluginVersionRequest, +def test_get_endpoint_policy_rest_required_fields( + request_type=endpoint_policy.GetEndpointPolicyRequest, ): transport_class = transports.NetworkServicesRestTransport @@ -25885,7 +26485,7 @@ def test_delete_wasm_plugin_version_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_wasm_plugin_version._get_unset_required_fields(jsonified_request) + ).get_endpoint_policy._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -25894,7 +26494,7 @@ def test_delete_wasm_plugin_version_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_wasm_plugin_version._get_unset_required_fields(jsonified_request) + ).get_endpoint_policy._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -25908,7 +26508,7 @@ def test_delete_wasm_plugin_version_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = endpoint_policy.EndpointPolicy() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -25920,36 +26520,39 @@ def test_delete_wasm_plugin_version_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "delete", + "method": "get", "query_params": pb_request, } transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = endpoint_policy.EndpointPolicy.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_wasm_plugin_version(request) + response = client.get_endpoint_policy(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_delete_wasm_plugin_version_rest_unset_required_fields(): +def test_get_endpoint_policy_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.delete_wasm_plugin_version._get_unset_required_fields({}) + unset_fields = transport.get_endpoint_policy._get_unset_required_fields({}) assert set(unset_fields) == (set(()) & set(("name",))) -def test_delete_wasm_plugin_version_rest_flattened(): +def test_get_endpoint_policy_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -25958,11 +26561,11 @@ def test_delete_wasm_plugin_version_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = endpoint_policy.EndpointPolicy() # get arguments that satisfy an http rule for this method sample_request = { - "name": "projects/sample1/locations/sample2/wasmPlugins/sample3/versions/sample4" + "name": "projects/sample1/locations/sample2/endpointPolicies/sample3" } # get truthy value for each flattened field @@ -25974,25 +26577,27 @@ def test_delete_wasm_plugin_version_rest_flattened(): # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = endpoint_policy.EndpointPolicy.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_wasm_plugin_version(**mock_args) + client.get_endpoint_policy(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/wasmPlugins/*/versions/*}" + "%s/v1/{name=projects/*/locations/*/endpointPolicies/*}" % client.transport._host, args[1], ) -def test_delete_wasm_plugin_version_rest_flattened_error(transport: str = "rest"): +def test_get_endpoint_policy_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -26001,13 +26606,13 @@ def test_delete_wasm_plugin_version_rest_flattened_error(transport: str = "rest" # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.delete_wasm_plugin_version( - extensibility.DeleteWasmPluginVersionRequest(), + client.get_endpoint_policy( + endpoint_policy.GetEndpointPolicyRequest(), name="name_value", ) -def test_list_wasm_plugins_rest_use_cached_wrapped_rpc(): +def test_create_endpoint_policy_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -26021,37 +26626,45 @@ def test_list_wasm_plugins_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.list_wasm_plugins in client._transport._wrapped_methods + assert ( + client._transport.create_endpoint_policy + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.list_wasm_plugins] = ( + client._transport._wrapped_methods[client._transport.create_endpoint_policy] = ( mock_rpc ) request = {} - client.list_wasm_plugins(request) + client.create_endpoint_policy(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_wasm_plugins(request) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.create_endpoint_policy(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_wasm_plugins_rest_required_fields( - request_type=extensibility.ListWasmPluginsRequest, +def test_create_endpoint_policy_rest_required_fields( + request_type=gcn_endpoint_policy.CreateEndpointPolicyRequest, ): transport_class = transports.NetworkServicesRestTransport request_init = {} request_init["parent"] = "" + request_init["endpoint_policy_id"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -26059,31 +26672,32 @@ def test_list_wasm_plugins_rest_required_fields( ) # verify fields with default values are dropped + assert "endpointPolicyId" not in jsonified_request unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_wasm_plugins._get_unset_required_fields(jsonified_request) + ).create_endpoint_policy._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present + assert "endpointPolicyId" in jsonified_request + assert jsonified_request["endpointPolicyId"] == request_init["endpoint_policy_id"] jsonified_request["parent"] = "parent_value" + jsonified_request["endpointPolicyId"] = "endpoint_policy_id_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_wasm_plugins._get_unset_required_fields(jsonified_request) + ).create_endpoint_policy._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "page_size", - "page_token", - ) - ) + assert not set(unset_fields) - set(("endpoint_policy_id",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone assert "parent" in jsonified_request assert jsonified_request["parent"] == "parent_value" + assert "endpointPolicyId" in jsonified_request + assert jsonified_request["endpointPolicyId"] == "endpoint_policy_id_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -26092,7 +26706,7 @@ def test_list_wasm_plugins_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = extensibility.ListWasmPluginsResponse() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -26104,47 +26718,52 @@ def test_list_wasm_plugins_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "post", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = extensibility.ListWasmPluginsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_wasm_plugins(request) + response = client.create_endpoint_policy(request) - expected_params = [("$alt", "json;enum-encoding=int")] + expected_params = [ + ( + "endpointPolicyId", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_list_wasm_plugins_rest_unset_required_fields(): +def test_create_endpoint_policy_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.list_wasm_plugins._get_unset_required_fields({}) + unset_fields = transport.create_endpoint_policy._get_unset_required_fields({}) assert set(unset_fields) == ( - set( + set(("endpointPolicyId",)) + & set( ( - "pageSize", - "pageToken", + "parent", + "endpointPolicyId", + "endpointPolicy", ) ) - & set(("parent",)) ) -def test_list_wasm_plugins_rest_flattened(): +def test_create_endpoint_policy_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -26153,7 +26772,7 @@ def test_list_wasm_plugins_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = extensibility.ListWasmPluginsResponse() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method sample_request = {"parent": "projects/sample1/locations/sample2"} @@ -26161,33 +26780,33 @@ def test_list_wasm_plugins_rest_flattened(): # get truthy value for each flattened field mock_args = dict( parent="parent_value", + endpoint_policy=gcn_endpoint_policy.EndpointPolicy(name="name_value"), + endpoint_policy_id="endpoint_policy_id_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = extensibility.ListWasmPluginsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_wasm_plugins(**mock_args) + client.create_endpoint_policy(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/wasmPlugins" + "%s/v1/{parent=projects/*/locations/*}/endpointPolicies" % client.transport._host, args[1], ) -def test_list_wasm_plugins_rest_flattened_error(transport: str = "rest"): +def test_create_endpoint_policy_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -26196,76 +26815,15 @@ def test_list_wasm_plugins_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_wasm_plugins( - extensibility.ListWasmPluginsRequest(), + client.create_endpoint_policy( + gcn_endpoint_policy.CreateEndpointPolicyRequest(), parent="parent_value", + endpoint_policy=gcn_endpoint_policy.EndpointPolicy(name="name_value"), + endpoint_policy_id="endpoint_policy_id_value", ) -def test_list_wasm_plugins_rest_pager(transport: str = "rest"): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - extensibility.ListWasmPluginsResponse( - wasm_plugins=[ - extensibility.WasmPlugin(), - extensibility.WasmPlugin(), - extensibility.WasmPlugin(), - ], - next_page_token="abc", - ), - extensibility.ListWasmPluginsResponse( - wasm_plugins=[], - next_page_token="def", - ), - extensibility.ListWasmPluginsResponse( - wasm_plugins=[ - extensibility.WasmPlugin(), - ], - next_page_token="ghi", - ), - extensibility.ListWasmPluginsResponse( - wasm_plugins=[ - extensibility.WasmPlugin(), - extensibility.WasmPlugin(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple( - extensibility.ListWasmPluginsResponse.to_json(x) for x in response - ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "projects/sample1/locations/sample2"} - - pager = client.list_wasm_plugins(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, extensibility.WasmPlugin) for i in results) - - pages = list(client.list_wasm_plugins(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token - - -def test_get_wasm_plugin_rest_use_cached_wrapped_rpc(): +def test_update_endpoint_policy_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -26279,35 +26837,43 @@ def test_get_wasm_plugin_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.get_wasm_plugin in client._transport._wrapped_methods + assert ( + client._transport.update_endpoint_policy + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.get_wasm_plugin] = mock_rpc + client._transport._wrapped_methods[client._transport.update_endpoint_policy] = ( + mock_rpc + ) request = {} - client.get_wasm_plugin(request) + client.update_endpoint_policy(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.get_wasm_plugin(request) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.update_endpoint_policy(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_get_wasm_plugin_rest_required_fields( - request_type=extensibility.GetWasmPluginRequest, +def test_update_endpoint_policy_rest_required_fields( + request_type=gcn_endpoint_policy.UpdateEndpointPolicyRequest, ): transport_class = transports.NetworkServicesRestTransport request_init = {} - request_init["name"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -26318,23 +26884,19 @@ def test_get_wasm_plugin_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_wasm_plugin._get_unset_required_fields(jsonified_request) + ).update_endpoint_policy._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["name"] = "name_value" - unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_wasm_plugin._get_unset_required_fields(jsonified_request) + ).update_endpoint_policy._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("view",)) + assert not set(unset_fields) - set(("update_mask",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -26343,7 +26905,7 @@ def test_get_wasm_plugin_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = extensibility.WasmPlugin() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -26355,39 +26917,37 @@ def test_get_wasm_plugin_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "patch", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = extensibility.WasmPlugin.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_wasm_plugin(request) + response = client.update_endpoint_policy(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_get_wasm_plugin_rest_unset_required_fields(): +def test_update_endpoint_policy_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.get_wasm_plugin._get_unset_required_fields({}) - assert set(unset_fields) == (set(("view",)) & set(("name",))) + unset_fields = transport.update_endpoint_policy._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("endpointPolicy",))) -def test_get_wasm_plugin_rest_flattened(): +def test_update_endpoint_policy_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -26396,43 +26956,44 @@ def test_get_wasm_plugin_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = extensibility.WasmPlugin() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method sample_request = { - "name": "projects/sample1/locations/sample2/wasmPlugins/sample3" + "endpoint_policy": { + "name": "projects/sample1/locations/sample2/endpointPolicies/sample3" + } } # get truthy value for each flattened field mock_args = dict( - name="name_value", + endpoint_policy=gcn_endpoint_policy.EndpointPolicy(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = extensibility.WasmPlugin.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_wasm_plugin(**mock_args) + client.update_endpoint_policy(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/wasmPlugins/*}" + "%s/v1/{endpoint_policy.name=projects/*/locations/*/endpointPolicies/*}" % client.transport._host, args[1], ) -def test_get_wasm_plugin_rest_flattened_error(transport: str = "rest"): +def test_update_endpoint_policy_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -26441,13 +27002,14 @@ def test_get_wasm_plugin_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.get_wasm_plugin( - extensibility.GetWasmPluginRequest(), - name="name_value", + client.update_endpoint_policy( + gcn_endpoint_policy.UpdateEndpointPolicyRequest(), + endpoint_policy=gcn_endpoint_policy.EndpointPolicy(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) -def test_create_wasm_plugin_rest_use_cached_wrapped_rpc(): +def test_delete_endpoint_policy_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -26462,7 +27024,8 @@ def test_create_wasm_plugin_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.create_wasm_plugin in client._transport._wrapped_methods + client._transport.delete_endpoint_policy + in client._transport._wrapped_methods ) # Replace cached wrapped function with mock @@ -26470,12 +27033,12 @@ def test_create_wasm_plugin_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.create_wasm_plugin] = ( + client._transport._wrapped_methods[client._transport.delete_endpoint_policy] = ( mock_rpc ) request = {} - client.create_wasm_plugin(request) + client.delete_endpoint_policy(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 @@ -26484,21 +27047,20 @@ def test_create_wasm_plugin_rest_use_cached_wrapped_rpc(): # subsequent calls should use the cached wrapper wrapper_fn.reset_mock() - client.create_wasm_plugin(request) + client.delete_endpoint_policy(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_create_wasm_plugin_rest_required_fields( - request_type=extensibility.CreateWasmPluginRequest, +def test_delete_endpoint_policy_rest_required_fields( + request_type=endpoint_policy.DeleteEndpointPolicyRequest, ): transport_class = transports.NetworkServicesRestTransport request_init = {} - request_init["parent"] = "" - request_init["wasm_plugin_id"] = "" + request_init["name"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -26506,32 +27068,24 @@ def test_create_wasm_plugin_rest_required_fields( ) # verify fields with default values are dropped - assert "wasmPluginId" not in jsonified_request unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_wasm_plugin._get_unset_required_fields(jsonified_request) + ).delete_endpoint_policy._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - assert "wasmPluginId" in jsonified_request - assert jsonified_request["wasmPluginId"] == request_init["wasm_plugin_id"] - jsonified_request["parent"] = "parent_value" - jsonified_request["wasmPluginId"] = "wasm_plugin_id_value" + jsonified_request["name"] = "name_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_wasm_plugin._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("wasm_plugin_id",)) + ).delete_endpoint_policy._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" - assert "wasmPluginId" in jsonified_request - assert jsonified_request["wasmPluginId"] == "wasm_plugin_id_value" + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -26552,10 +27106,9 @@ def test_create_wasm_plugin_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "post", + "method": "delete", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() @@ -26566,38 +27119,23 @@ def test_create_wasm_plugin_rest_required_fields( req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_wasm_plugin(request) + response = client.delete_endpoint_policy(request) - expected_params = [ - ( - "wasmPluginId", - "", - ), - ("$alt", "json;enum-encoding=int"), - ] + expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_create_wasm_plugin_rest_unset_required_fields(): +def test_delete_endpoint_policy_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.create_wasm_plugin._get_unset_required_fields({}) - assert set(unset_fields) == ( - set(("wasmPluginId",)) - & set( - ( - "parent", - "wasmPluginId", - "wasmPlugin", - ) - ) - ) + unset_fields = transport.delete_endpoint_policy._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) -def test_create_wasm_plugin_rest_flattened(): +def test_delete_endpoint_policy_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -26609,13 +27147,13 @@ def test_create_wasm_plugin_rest_flattened(): return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} + sample_request = { + "name": "projects/sample1/locations/sample2/endpointPolicies/sample3" + } # get truthy value for each flattened field mock_args = dict( - parent="parent_value", - wasm_plugin=extensibility.WasmPlugin(name="name_value"), - wasm_plugin_id="wasm_plugin_id_value", + name="name_value", ) mock_args.update(sample_request) @@ -26627,20 +27165,20 @@ def test_create_wasm_plugin_rest_flattened(): req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_wasm_plugin(**mock_args) + client.delete_endpoint_policy(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/wasmPlugins" + "%s/v1/{name=projects/*/locations/*/endpointPolicies/*}" % client.transport._host, args[1], ) -def test_create_wasm_plugin_rest_flattened_error(transport: str = "rest"): +def test_delete_endpoint_policy_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -26649,15 +27187,13 @@ def test_create_wasm_plugin_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.create_wasm_plugin( - extensibility.CreateWasmPluginRequest(), - parent="parent_value", - wasm_plugin=extensibility.WasmPlugin(name="name_value"), - wasm_plugin_id="wasm_plugin_id_value", + client.delete_endpoint_policy( + endpoint_policy.DeleteEndpointPolicyRequest(), + name="name_value", ) -def test_update_wasm_plugin_rest_use_cached_wrapped_rpc(): +def test_list_wasm_plugin_versions_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -26672,7 +27208,8 @@ def test_update_wasm_plugin_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.update_wasm_plugin in client._transport._wrapped_methods + client._transport.list_wasm_plugin_versions + in client._transport._wrapped_methods ) # Replace cached wrapped function with mock @@ -26680,33 +27217,30 @@ def test_update_wasm_plugin_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.update_wasm_plugin] = ( - mock_rpc - ) + client._transport._wrapped_methods[ + client._transport.list_wasm_plugin_versions + ] = mock_rpc request = {} - client.update_wasm_plugin(request) + client.list_wasm_plugin_versions(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.update_wasm_plugin(request) + client.list_wasm_plugin_versions(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_update_wasm_plugin_rest_required_fields( - request_type=extensibility.UpdateWasmPluginRequest, +def test_list_wasm_plugin_versions_rest_required_fields( + request_type=extensibility.ListWasmPluginVersionsRequest, ): transport_class = transports.NetworkServicesRestTransport request_init = {} + request_init["parent"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -26717,19 +27251,28 @@ def test_update_wasm_plugin_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_wasm_plugin._get_unset_required_fields(jsonified_request) + ).list_wasm_plugin_versions._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present + jsonified_request["parent"] = "parent_value" + unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_wasm_plugin._get_unset_required_fields(jsonified_request) + ).list_wasm_plugin_versions._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("update_mask",)) + assert not set(unset_fields) - set( + ( + "page_size", + "page_token", + ) + ) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -26738,7 +27281,7 @@ def test_update_wasm_plugin_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = extensibility.ListWasmPluginVersionsResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -26750,37 +27293,47 @@ def test_update_wasm_plugin_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "patch", + "method": "get", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = extensibility.ListWasmPluginVersionsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_wasm_plugin(request) + response = client.list_wasm_plugin_versions(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_update_wasm_plugin_rest_unset_required_fields(): +def test_list_wasm_plugin_versions_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.update_wasm_plugin._get_unset_required_fields({}) - assert set(unset_fields) == (set(("updateMask",)) & set(("wasmPlugin",))) + unset_fields = transport.list_wasm_plugin_versions._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) -def test_update_wasm_plugin_rest_flattened(): +def test_list_wasm_plugin_versions_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -26789,44 +27342,43 @@ def test_update_wasm_plugin_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = extensibility.ListWasmPluginVersionsResponse() # get arguments that satisfy an http rule for this method sample_request = { - "wasm_plugin": { - "name": "projects/sample1/locations/sample2/wasmPlugins/sample3" - } + "parent": "projects/sample1/locations/sample2/wasmPlugins/sample3" } # get truthy value for each flattened field mock_args = dict( - wasm_plugin=extensibility.WasmPlugin(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + parent="parent_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = extensibility.ListWasmPluginVersionsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_wasm_plugin(**mock_args) + client.list_wasm_plugin_versions(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{wasm_plugin.name=projects/*/locations/*/wasmPlugins/*}" + "%s/v1/{parent=projects/*/locations/*/wasmPlugins/*}/versions" % client.transport._host, args[1], ) -def test_update_wasm_plugin_rest_flattened_error(transport: str = "rest"): +def test_list_wasm_plugin_versions_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -26835,14 +27387,78 @@ def test_update_wasm_plugin_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.update_wasm_plugin( - extensibility.UpdateWasmPluginRequest(), - wasm_plugin=extensibility.WasmPlugin(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + client.list_wasm_plugin_versions( + extensibility.ListWasmPluginVersionsRequest(), + parent="parent_value", ) -def test_delete_wasm_plugin_rest_use_cached_wrapped_rpc(): +def test_list_wasm_plugin_versions_rest_pager(transport: str = "rest"): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + extensibility.ListWasmPluginVersionsResponse( + wasm_plugin_versions=[ + extensibility.WasmPluginVersion(), + extensibility.WasmPluginVersion(), + extensibility.WasmPluginVersion(), + ], + next_page_token="abc", + ), + extensibility.ListWasmPluginVersionsResponse( + wasm_plugin_versions=[], + next_page_token="def", + ), + extensibility.ListWasmPluginVersionsResponse( + wasm_plugin_versions=[ + extensibility.WasmPluginVersion(), + ], + next_page_token="ghi", + ), + extensibility.ListWasmPluginVersionsResponse( + wasm_plugin_versions=[ + extensibility.WasmPluginVersion(), + extensibility.WasmPluginVersion(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + extensibility.ListWasmPluginVersionsResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = { + "parent": "projects/sample1/locations/sample2/wasmPlugins/sample3" + } + + pager = client.list_wasm_plugin_versions(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, extensibility.WasmPluginVersion) for i in results) + + pages = list(client.list_wasm_plugin_versions(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_get_wasm_plugin_version_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -26857,7 +27473,8 @@ def test_delete_wasm_plugin_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.delete_wasm_plugin in client._transport._wrapped_methods + client._transport.get_wasm_plugin_version + in client._transport._wrapped_methods ) # Replace cached wrapped function with mock @@ -26865,29 +27482,25 @@ def test_delete_wasm_plugin_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.delete_wasm_plugin] = ( - mock_rpc - ) + client._transport._wrapped_methods[ + client._transport.get_wasm_plugin_version + ] = mock_rpc request = {} - client.delete_wasm_plugin(request) + client.get_wasm_plugin_version(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.delete_wasm_plugin(request) + client.get_wasm_plugin_version(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_delete_wasm_plugin_rest_required_fields( - request_type=extensibility.DeleteWasmPluginRequest, +def test_get_wasm_plugin_version_rest_required_fields( + request_type=extensibility.GetWasmPluginVersionRequest, ): transport_class = transports.NetworkServicesRestTransport @@ -26903,7 +27516,7 @@ def test_delete_wasm_plugin_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_wasm_plugin._get_unset_required_fields(jsonified_request) + ).get_wasm_plugin_version._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -26912,7 +27525,7 @@ def test_delete_wasm_plugin_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_wasm_plugin._get_unset_required_fields(jsonified_request) + ).get_wasm_plugin_version._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -26926,7 +27539,7 @@ def test_delete_wasm_plugin_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = extensibility.WasmPluginVersion() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -26938,36 +27551,39 @@ def test_delete_wasm_plugin_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "delete", + "method": "get", "query_params": pb_request, } transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = extensibility.WasmPluginVersion.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_wasm_plugin(request) + response = client.get_wasm_plugin_version(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_delete_wasm_plugin_rest_unset_required_fields(): +def test_get_wasm_plugin_version_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.delete_wasm_plugin._get_unset_required_fields({}) + unset_fields = transport.get_wasm_plugin_version._get_unset_required_fields({}) assert set(unset_fields) == (set(()) & set(("name",))) -def test_delete_wasm_plugin_rest_flattened(): +def test_get_wasm_plugin_version_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -26976,11 +27592,11 @@ def test_delete_wasm_plugin_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = extensibility.WasmPluginVersion() # get arguments that satisfy an http rule for this method sample_request = { - "name": "projects/sample1/locations/sample2/wasmPlugins/sample3" + "name": "projects/sample1/locations/sample2/wasmPlugins/sample3/versions/sample4" } # get truthy value for each flattened field @@ -26992,25 +27608,27 @@ def test_delete_wasm_plugin_rest_flattened(): # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = extensibility.WasmPluginVersion.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_wasm_plugin(**mock_args) + client.get_wasm_plugin_version(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/wasmPlugins/*}" + "%s/v1/{name=projects/*/locations/*/wasmPlugins/*/versions/*}" % client.transport._host, args[1], ) -def test_delete_wasm_plugin_rest_flattened_error(transport: str = "rest"): +def test_get_wasm_plugin_version_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -27019,13 +27637,13 @@ def test_delete_wasm_plugin_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.delete_wasm_plugin( - extensibility.DeleteWasmPluginRequest(), + client.get_wasm_plugin_version( + extensibility.GetWasmPluginVersionRequest(), name="name_value", ) -def test_list_gateways_rest_use_cached_wrapped_rpc(): +def test_create_wasm_plugin_version_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -27039,33 +27657,45 @@ def test_list_gateways_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.list_gateways in client._transport._wrapped_methods + assert ( + client._transport.create_wasm_plugin_version + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.list_gateways] = mock_rpc + client._transport._wrapped_methods[ + client._transport.create_wasm_plugin_version + ] = mock_rpc request = {} - client.list_gateways(request) + client.create_wasm_plugin_version(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_gateways(request) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.create_wasm_plugin_version(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_gateways_rest_required_fields(request_type=gateway.ListGatewaysRequest): +def test_create_wasm_plugin_version_rest_required_fields( + request_type=extensibility.CreateWasmPluginVersionRequest, +): transport_class = transports.NetworkServicesRestTransport request_init = {} request_init["parent"] = "" + request_init["wasm_plugin_version_id"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -27073,31 +27703,35 @@ def test_list_gateways_rest_required_fields(request_type=gateway.ListGatewaysReq ) # verify fields with default values are dropped + assert "wasmPluginVersionId" not in jsonified_request unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_gateways._get_unset_required_fields(jsonified_request) + ).create_wasm_plugin_version._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present + assert "wasmPluginVersionId" in jsonified_request + assert ( + jsonified_request["wasmPluginVersionId"] + == request_init["wasm_plugin_version_id"] + ) jsonified_request["parent"] = "parent_value" + jsonified_request["wasmPluginVersionId"] = "wasm_plugin_version_id_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_gateways._get_unset_required_fields(jsonified_request) + ).create_wasm_plugin_version._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "page_size", - "page_token", - ) - ) + assert not set(unset_fields) - set(("wasm_plugin_version_id",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone assert "parent" in jsonified_request assert jsonified_request["parent"] == "parent_value" + assert "wasmPluginVersionId" in jsonified_request + assert jsonified_request["wasmPluginVersionId"] == "wasm_plugin_version_id_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -27106,7 +27740,7 @@ def test_list_gateways_rest_required_fields(request_type=gateway.ListGatewaysReq request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = gateway.ListGatewaysResponse() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -27118,47 +27752,52 @@ def test_list_gateways_rest_required_fields(request_type=gateway.ListGatewaysReq pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "post", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = gateway.ListGatewaysResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_gateways(request) + response = client.create_wasm_plugin_version(request) - expected_params = [("$alt", "json;enum-encoding=int")] + expected_params = [ + ( + "wasmPluginVersionId", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_list_gateways_rest_unset_required_fields(): +def test_create_wasm_plugin_version_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.list_gateways._get_unset_required_fields({}) + unset_fields = transport.create_wasm_plugin_version._get_unset_required_fields({}) assert set(unset_fields) == ( - set( + set(("wasmPluginVersionId",)) + & set( ( - "pageSize", - "pageToken", + "parent", + "wasmPluginVersionId", + "wasmPluginVersion", ) ) - & set(("parent",)) ) -def test_list_gateways_rest_flattened(): +def test_create_wasm_plugin_version_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -27167,40 +27806,45 @@ def test_list_gateways_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = gateway.ListGatewaysResponse() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} + sample_request = { + "parent": "projects/sample1/locations/sample2/wasmPlugins/sample3" + } # get truthy value for each flattened field mock_args = dict( parent="parent_value", + wasm_plugin_version=extensibility.WasmPluginVersion( + plugin_config_data=b"plugin_config_data_blob" + ), + wasm_plugin_version_id="wasm_plugin_version_id_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = gateway.ListGatewaysResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_gateways(**mock_args) + client.create_wasm_plugin_version(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/gateways" % client.transport._host, + "%s/v1/{parent=projects/*/locations/*/wasmPlugins/*}/versions" + % client.transport._host, args[1], ) -def test_list_gateways_rest_flattened_error(transport: str = "rest"): +def test_create_wasm_plugin_version_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -27209,74 +27853,17 @@ def test_list_gateways_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_gateways( - gateway.ListGatewaysRequest(), + client.create_wasm_plugin_version( + extensibility.CreateWasmPluginVersionRequest(), parent="parent_value", - ) - - -def test_list_gateways_rest_pager(transport: str = "rest"): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - gateway.ListGatewaysResponse( - gateways=[ - gateway.Gateway(), - gateway.Gateway(), - gateway.Gateway(), - ], - next_page_token="abc", - ), - gateway.ListGatewaysResponse( - gateways=[], - next_page_token="def", - ), - gateway.ListGatewaysResponse( - gateways=[ - gateway.Gateway(), - ], - next_page_token="ghi", - ), - gateway.ListGatewaysResponse( - gateways=[ - gateway.Gateway(), - gateway.Gateway(), - ], + wasm_plugin_version=extensibility.WasmPluginVersion( + plugin_config_data=b"plugin_config_data_blob" ), + wasm_plugin_version_id="wasm_plugin_version_id_value", ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple(gateway.ListGatewaysResponse.to_json(x) for x in response) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "projects/sample1/locations/sample2"} - - pager = client.list_gateways(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, gateway.Gateway) for i in results) - - pages = list(client.list_gateways(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token -def test_get_gateway_rest_use_cached_wrapped_rpc(): +def test_delete_wasm_plugin_version_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -27290,29 +27877,40 @@ def test_get_gateway_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.get_gateway in client._transport._wrapped_methods + assert ( + client._transport.delete_wasm_plugin_version + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.get_gateway] = mock_rpc + client._transport._wrapped_methods[ + client._transport.delete_wasm_plugin_version + ] = mock_rpc request = {} - client.get_gateway(request) + client.delete_wasm_plugin_version(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.get_gateway(request) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_wasm_plugin_version(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_get_gateway_rest_required_fields(request_type=gateway.GetGatewayRequest): +def test_delete_wasm_plugin_version_rest_required_fields( + request_type=extensibility.DeleteWasmPluginVersionRequest, +): transport_class = transports.NetworkServicesRestTransport request_init = {} @@ -27327,7 +27925,7 @@ def test_get_gateway_rest_required_fields(request_type=gateway.GetGatewayRequest unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_gateway._get_unset_required_fields(jsonified_request) + ).delete_wasm_plugin_version._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -27336,7 +27934,7 @@ def test_get_gateway_rest_required_fields(request_type=gateway.GetGatewayRequest unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_gateway._get_unset_required_fields(jsonified_request) + ).delete_wasm_plugin_version._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -27350,7 +27948,7 @@ def test_get_gateway_rest_required_fields(request_type=gateway.GetGatewayRequest request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = gateway.Gateway() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -27362,39 +27960,36 @@ def test_get_gateway_rest_required_fields(request_type=gateway.GetGatewayRequest pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "delete", "query_params": pb_request, } transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = gateway.Gateway.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_gateway(request) + response = client.delete_wasm_plugin_version(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_get_gateway_rest_unset_required_fields(): +def test_delete_wasm_plugin_version_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.get_gateway._get_unset_required_fields({}) + unset_fields = transport.delete_wasm_plugin_version._get_unset_required_fields({}) assert set(unset_fields) == (set(()) & set(("name",))) -def test_get_gateway_rest_flattened(): +def test_delete_wasm_plugin_version_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -27403,10 +27998,12 @@ def test_get_gateway_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = gateway.Gateway() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = {"name": "projects/sample1/locations/sample2/gateways/sample3"} + sample_request = { + "name": "projects/sample1/locations/sample2/wasmPlugins/sample3/versions/sample4" + } # get truthy value for each flattened field mock_args = dict( @@ -27417,26 +28014,25 @@ def test_get_gateway_rest_flattened(): # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = gateway.Gateway.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_gateway(**mock_args) + client.delete_wasm_plugin_version(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/gateways/*}" % client.transport._host, + "%s/v1/{name=projects/*/locations/*/wasmPlugins/*/versions/*}" + % client.transport._host, args[1], ) -def test_get_gateway_rest_flattened_error(transport: str = "rest"): +def test_delete_wasm_plugin_version_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -27445,13 +28041,13 @@ def test_get_gateway_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.get_gateway( - gateway.GetGatewayRequest(), + client.delete_wasm_plugin_version( + extensibility.DeleteWasmPluginVersionRequest(), name="name_value", ) -def test_create_gateway_rest_use_cached_wrapped_rpc(): +def test_list_wasm_plugins_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -27465,40 +28061,37 @@ def test_create_gateway_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.create_gateway in client._transport._wrapped_methods + assert client._transport.list_wasm_plugins in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.create_gateway] = mock_rpc + client._transport._wrapped_methods[client._transport.list_wasm_plugins] = ( + mock_rpc + ) request = {} - client.create_gateway(request) + client.list_wasm_plugins(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.create_gateway(request) + client.list_wasm_plugins(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_create_gateway_rest_required_fields( - request_type=gcn_gateway.CreateGatewayRequest, +def test_list_wasm_plugins_rest_required_fields( + request_type=extensibility.ListWasmPluginsRequest, ): transport_class = transports.NetworkServicesRestTransport request_init = {} request_init["parent"] = "" - request_init["gateway_id"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -27506,32 +28099,31 @@ def test_create_gateway_rest_required_fields( ) # verify fields with default values are dropped - assert "gatewayId" not in jsonified_request unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_gateway._get_unset_required_fields(jsonified_request) + ).list_wasm_plugins._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - assert "gatewayId" in jsonified_request - assert jsonified_request["gatewayId"] == request_init["gateway_id"] jsonified_request["parent"] = "parent_value" - jsonified_request["gatewayId"] = "gateway_id_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_gateway._get_unset_required_fields(jsonified_request) + ).list_wasm_plugins._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("gateway_id",)) + assert not set(unset_fields) - set( + ( + "page_size", + "page_token", + ) + ) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone assert "parent" in jsonified_request assert jsonified_request["parent"] == "parent_value" - assert "gatewayId" in jsonified_request - assert jsonified_request["gatewayId"] == "gateway_id_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -27540,7 +28132,7 @@ def test_create_gateway_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = extensibility.ListWasmPluginsResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -27552,52 +28144,47 @@ def test_create_gateway_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "post", + "method": "get", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = extensibility.ListWasmPluginsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_gateway(request) + response = client.list_wasm_plugins(request) - expected_params = [ - ( - "gatewayId", - "", - ), - ("$alt", "json;enum-encoding=int"), - ] + expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_create_gateway_rest_unset_required_fields(): +def test_list_wasm_plugins_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.create_gateway._get_unset_required_fields({}) + unset_fields = transport.list_wasm_plugins._get_unset_required_fields({}) assert set(unset_fields) == ( - set(("gatewayId",)) - & set( + set( ( - "parent", - "gatewayId", - "gateway", + "pageSize", + "pageToken", ) ) + & set(("parent",)) ) -def test_create_gateway_rest_flattened(): +def test_list_wasm_plugins_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -27606,7 +28193,7 @@ def test_create_gateway_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = extensibility.ListWasmPluginsResponse() # get arguments that satisfy an http rule for this method sample_request = {"parent": "projects/sample1/locations/sample2"} @@ -27614,32 +28201,33 @@ def test_create_gateway_rest_flattened(): # get truthy value for each flattened field mock_args = dict( parent="parent_value", - gateway=gcn_gateway.Gateway(name="name_value"), - gateway_id="gateway_id_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = extensibility.ListWasmPluginsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_gateway(**mock_args) + client.list_wasm_plugins(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/gateways" % client.transport._host, + "%s/v1/{parent=projects/*/locations/*}/wasmPlugins" + % client.transport._host, args[1], ) -def test_create_gateway_rest_flattened_error(transport: str = "rest"): +def test_list_wasm_plugins_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -27648,15 +28236,76 @@ def test_create_gateway_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.create_gateway( - gcn_gateway.CreateGatewayRequest(), + client.list_wasm_plugins( + extensibility.ListWasmPluginsRequest(), parent="parent_value", - gateway=gcn_gateway.Gateway(name="name_value"), - gateway_id="gateway_id_value", ) -def test_update_gateway_rest_use_cached_wrapped_rpc(): +def test_list_wasm_plugins_rest_pager(transport: str = "rest"): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + extensibility.ListWasmPluginsResponse( + wasm_plugins=[ + extensibility.WasmPlugin(), + extensibility.WasmPlugin(), + extensibility.WasmPlugin(), + ], + next_page_token="abc", + ), + extensibility.ListWasmPluginsResponse( + wasm_plugins=[], + next_page_token="def", + ), + extensibility.ListWasmPluginsResponse( + wasm_plugins=[ + extensibility.WasmPlugin(), + ], + next_page_token="ghi", + ), + extensibility.ListWasmPluginsResponse( + wasm_plugins=[ + extensibility.WasmPlugin(), + extensibility.WasmPlugin(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + extensibility.ListWasmPluginsResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_wasm_plugins(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, extensibility.WasmPlugin) for i in results) + + pages = list(client.list_wasm_plugins(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_get_wasm_plugin_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -27670,38 +28319,35 @@ def test_update_gateway_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.update_gateway in client._transport._wrapped_methods + assert client._transport.get_wasm_plugin in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.update_gateway] = mock_rpc + client._transport._wrapped_methods[client._transport.get_wasm_plugin] = mock_rpc request = {} - client.update_gateway(request) + client.get_wasm_plugin(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.update_gateway(request) + client.get_wasm_plugin(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_update_gateway_rest_required_fields( - request_type=gcn_gateway.UpdateGatewayRequest, +def test_get_wasm_plugin_rest_required_fields( + request_type=extensibility.GetWasmPluginRequest, ): transport_class = transports.NetworkServicesRestTransport request_init = {} + request_init["name"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -27712,19 +28358,23 @@ def test_update_gateway_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_gateway._get_unset_required_fields(jsonified_request) + ).get_wasm_plugin._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present + jsonified_request["name"] = "name_value" + unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_gateway._get_unset_required_fields(jsonified_request) + ).get_wasm_plugin._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("update_mask",)) + assert not set(unset_fields) - set(("view",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -27733,7 +28383,7 @@ def test_update_gateway_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = extensibility.WasmPlugin() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -27745,37 +28395,39 @@ def test_update_gateway_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "patch", + "method": "get", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = extensibility.WasmPlugin.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_gateway(request) + response = client.get_wasm_plugin(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_update_gateway_rest_unset_required_fields(): +def test_get_wasm_plugin_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.update_gateway._get_unset_required_fields({}) - assert set(unset_fields) == (set(("updateMask",)) & set(("gateway",))) + unset_fields = transport.get_wasm_plugin._get_unset_required_fields({}) + assert set(unset_fields) == (set(("view",)) & set(("name",))) -def test_update_gateway_rest_flattened(): +def test_get_wasm_plugin_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -27784,42 +28436,43 @@ def test_update_gateway_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = extensibility.WasmPlugin() # get arguments that satisfy an http rule for this method sample_request = { - "gateway": {"name": "projects/sample1/locations/sample2/gateways/sample3"} + "name": "projects/sample1/locations/sample2/wasmPlugins/sample3" } # get truthy value for each flattened field mock_args = dict( - gateway=gcn_gateway.Gateway(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + name="name_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = extensibility.WasmPlugin.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_gateway(**mock_args) + client.get_wasm_plugin(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{gateway.name=projects/*/locations/*/gateways/*}" + "%s/v1/{name=projects/*/locations/*/wasmPlugins/*}" % client.transport._host, args[1], ) -def test_update_gateway_rest_flattened_error(transport: str = "rest"): +def test_get_wasm_plugin_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -27828,14 +28481,13 @@ def test_update_gateway_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.update_gateway( - gcn_gateway.UpdateGatewayRequest(), - gateway=gcn_gateway.Gateway(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + client.get_wasm_plugin( + extensibility.GetWasmPluginRequest(), + name="name_value", ) -def test_delete_gateway_rest_use_cached_wrapped_rpc(): +def test_create_wasm_plugin_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -27849,17 +28501,21 @@ def test_delete_gateway_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.delete_gateway in client._transport._wrapped_methods + assert ( + client._transport.create_wasm_plugin in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.delete_gateway] = mock_rpc + client._transport._wrapped_methods[client._transport.create_wasm_plugin] = ( + mock_rpc + ) request = {} - client.delete_gateway(request) + client.create_wasm_plugin(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 @@ -27868,18 +28524,21 @@ def test_delete_gateway_rest_use_cached_wrapped_rpc(): # subsequent calls should use the cached wrapper wrapper_fn.reset_mock() - client.delete_gateway(request) + client.create_wasm_plugin(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_delete_gateway_rest_required_fields(request_type=gateway.DeleteGatewayRequest): +def test_create_wasm_plugin_rest_required_fields( + request_type=extensibility.CreateWasmPluginRequest, +): transport_class = transports.NetworkServicesRestTransport request_init = {} - request_init["name"] = "" + request_init["parent"] = "" + request_init["wasm_plugin_id"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -27887,24 +28546,32 @@ def test_delete_gateway_rest_required_fields(request_type=gateway.DeleteGatewayR ) # verify fields with default values are dropped + assert "wasmPluginId" not in jsonified_request unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_gateway._get_unset_required_fields(jsonified_request) + ).create_wasm_plugin._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present + assert "wasmPluginId" in jsonified_request + assert jsonified_request["wasmPluginId"] == request_init["wasm_plugin_id"] - jsonified_request["name"] = "name_value" + jsonified_request["parent"] = "parent_value" + jsonified_request["wasmPluginId"] = "wasm_plugin_id_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_gateway._get_unset_required_fields(jsonified_request) + ).create_wasm_plugin._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("wasm_plugin_id",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "wasmPluginId" in jsonified_request + assert jsonified_request["wasmPluginId"] == "wasm_plugin_id_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -27925,9 +28592,10 @@ def test_delete_gateway_rest_required_fields(request_type=gateway.DeleteGatewayR pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "delete", + "method": "post", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() @@ -27938,23 +28606,38 @@ def test_delete_gateway_rest_required_fields(request_type=gateway.DeleteGatewayR req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_gateway(request) + response = client.create_wasm_plugin(request) - expected_params = [("$alt", "json;enum-encoding=int")] + expected_params = [ + ( + "wasmPluginId", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_delete_gateway_rest_unset_required_fields(): +def test_create_wasm_plugin_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.delete_gateway._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + unset_fields = transport.create_wasm_plugin._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("wasmPluginId",)) + & set( + ( + "parent", + "wasmPluginId", + "wasmPlugin", + ) + ) + ) -def test_delete_gateway_rest_flattened(): +def test_create_wasm_plugin_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -27966,11 +28649,13 @@ def test_delete_gateway_rest_flattened(): return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = {"name": "projects/sample1/locations/sample2/gateways/sample3"} + sample_request = {"parent": "projects/sample1/locations/sample2"} # get truthy value for each flattened field mock_args = dict( - name="name_value", + parent="parent_value", + wasm_plugin=extensibility.WasmPlugin(name="name_value"), + wasm_plugin_id="wasm_plugin_id_value", ) mock_args.update(sample_request) @@ -27982,19 +28667,20 @@ def test_delete_gateway_rest_flattened(): req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_gateway(**mock_args) + client.create_wasm_plugin(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/gateways/*}" % client.transport._host, + "%s/v1/{parent=projects/*/locations/*}/wasmPlugins" + % client.transport._host, args[1], ) -def test_delete_gateway_rest_flattened_error(transport: str = "rest"): +def test_create_wasm_plugin_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -28003,13 +28689,15 @@ def test_delete_gateway_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.delete_gateway( - gateway.DeleteGatewayRequest(), - name="name_value", + client.create_wasm_plugin( + extensibility.CreateWasmPluginRequest(), + parent="parent_value", + wasm_plugin=extensibility.WasmPlugin(name="name_value"), + wasm_plugin_id="wasm_plugin_id_value", ) -def test_list_grpc_routes_rest_use_cached_wrapped_rpc(): +def test_update_wasm_plugin_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -28023,37 +28711,42 @@ def test_list_grpc_routes_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.list_grpc_routes in client._transport._wrapped_methods + assert ( + client._transport.update_wasm_plugin in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.list_grpc_routes] = ( + client._transport._wrapped_methods[client._transport.update_wasm_plugin] = ( mock_rpc ) request = {} - client.list_grpc_routes(request) + client.update_wasm_plugin(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_grpc_routes(request) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.update_wasm_plugin(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_grpc_routes_rest_required_fields( - request_type=grpc_route.ListGrpcRoutesRequest, +def test_update_wasm_plugin_rest_required_fields( + request_type=extensibility.UpdateWasmPluginRequest, ): transport_class = transports.NetworkServicesRestTransport request_init = {} - request_init["parent"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -28064,29 +28757,19 @@ def test_list_grpc_routes_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_grpc_routes._get_unset_required_fields(jsonified_request) + ).update_wasm_plugin._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["parent"] = "parent_value" - unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_grpc_routes._get_unset_required_fields(jsonified_request) + ).update_wasm_plugin._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "page_size", - "page_token", - "return_partial_success", - ) - ) + assert not set(unset_fields) - set(("update_mask",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -28095,7 +28778,7 @@ def test_list_grpc_routes_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = grpc_route.ListGrpcRoutesResponse() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -28107,48 +28790,37 @@ def test_list_grpc_routes_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "patch", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grpc_route.ListGrpcRoutesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_grpc_routes(request) + response = client.update_wasm_plugin(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_list_grpc_routes_rest_unset_required_fields(): +def test_update_wasm_plugin_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.list_grpc_routes._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "pageSize", - "pageToken", - "returnPartialSuccess", - ) - ) - & set(("parent",)) - ) + unset_fields = transport.update_wasm_plugin._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("wasmPlugin",))) -def test_list_grpc_routes_rest_flattened(): +def test_update_wasm_plugin_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -28157,40 +28829,44 @@ def test_list_grpc_routes_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = grpc_route.ListGrpcRoutesResponse() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} + sample_request = { + "wasm_plugin": { + "name": "projects/sample1/locations/sample2/wasmPlugins/sample3" + } + } # get truthy value for each flattened field mock_args = dict( - parent="parent_value", + wasm_plugin=extensibility.WasmPlugin(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = grpc_route.ListGrpcRoutesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_grpc_routes(**mock_args) + client.update_wasm_plugin(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/grpcRoutes" % client.transport._host, + "%s/v1/{wasm_plugin.name=projects/*/locations/*/wasmPlugins/*}" + % client.transport._host, args[1], ) -def test_list_grpc_routes_rest_flattened_error(transport: str = "rest"): +def test_update_wasm_plugin_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -28199,80 +28875,20 @@ def test_list_grpc_routes_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_grpc_routes( - grpc_route.ListGrpcRoutesRequest(), - parent="parent_value", + client.update_wasm_plugin( + extensibility.UpdateWasmPluginRequest(), + wasm_plugin=extensibility.WasmPlugin(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) -def test_list_grpc_routes_rest_pager(transport: str = "rest"): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - grpc_route.ListGrpcRoutesResponse( - grpc_routes=[ - grpc_route.GrpcRoute(), - grpc_route.GrpcRoute(), - grpc_route.GrpcRoute(), - ], - next_page_token="abc", - ), - grpc_route.ListGrpcRoutesResponse( - grpc_routes=[], - next_page_token="def", - ), - grpc_route.ListGrpcRoutesResponse( - grpc_routes=[ - grpc_route.GrpcRoute(), - ], - next_page_token="ghi", - ), - grpc_route.ListGrpcRoutesResponse( - grpc_routes=[ - grpc_route.GrpcRoute(), - grpc_route.GrpcRoute(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple(grpc_route.ListGrpcRoutesResponse.to_json(x) for x in response) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "projects/sample1/locations/sample2"} - - pager = client.list_grpc_routes(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, grpc_route.GrpcRoute) for i in results) - - pages = list(client.list_grpc_routes(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token - - -def test_get_grpc_route_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", +def test_delete_wasm_plugin_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) # Should wrap all calls on client creation @@ -28280,30 +28896,38 @@ def test_get_grpc_route_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.get_grpc_route in client._transport._wrapped_methods + assert ( + client._transport.delete_wasm_plugin in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.get_grpc_route] = mock_rpc + client._transport._wrapped_methods[client._transport.delete_wasm_plugin] = ( + mock_rpc + ) request = {} - client.get_grpc_route(request) + client.delete_wasm_plugin(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.get_grpc_route(request) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_wasm_plugin(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_get_grpc_route_rest_required_fields( - request_type=grpc_route.GetGrpcRouteRequest, +def test_delete_wasm_plugin_rest_required_fields( + request_type=extensibility.DeleteWasmPluginRequest, ): transport_class = transports.NetworkServicesRestTransport @@ -28319,7 +28943,7 @@ def test_get_grpc_route_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_grpc_route._get_unset_required_fields(jsonified_request) + ).delete_wasm_plugin._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -28328,7 +28952,7 @@ def test_get_grpc_route_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_grpc_route._get_unset_required_fields(jsonified_request) + ).delete_wasm_plugin._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -28342,7 +28966,7 @@ def test_get_grpc_route_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = grpc_route.GrpcRoute() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -28354,39 +28978,36 @@ def test_get_grpc_route_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "delete", "query_params": pb_request, } transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grpc_route.GrpcRoute.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_grpc_route(request) + response = client.delete_wasm_plugin(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_get_grpc_route_rest_unset_required_fields(): +def test_delete_wasm_plugin_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.get_grpc_route._get_unset_required_fields({}) + unset_fields = transport.delete_wasm_plugin._get_unset_required_fields({}) assert set(unset_fields) == (set(()) & set(("name",))) -def test_get_grpc_route_rest_flattened(): +def test_delete_wasm_plugin_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -28395,11 +29016,11 @@ def test_get_grpc_route_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = grpc_route.GrpcRoute() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method sample_request = { - "name": "projects/sample1/locations/sample2/grpcRoutes/sample3" + "name": "projects/sample1/locations/sample2/wasmPlugins/sample3" } # get truthy value for each flattened field @@ -28411,26 +29032,25 @@ def test_get_grpc_route_rest_flattened(): # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = grpc_route.GrpcRoute.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_grpc_route(**mock_args) + client.delete_wasm_plugin(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/grpcRoutes/*}" % client.transport._host, + "%s/v1/{name=projects/*/locations/*/wasmPlugins/*}" + % client.transport._host, args[1], ) -def test_get_grpc_route_rest_flattened_error(transport: str = "rest"): +def test_delete_wasm_plugin_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -28439,13 +29059,13 @@ def test_get_grpc_route_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.get_grpc_route( - grpc_route.GetGrpcRouteRequest(), + client.delete_wasm_plugin( + extensibility.DeleteWasmPluginRequest(), name="name_value", ) -def test_create_grpc_route_rest_use_cached_wrapped_rpc(): +def test_list_gateways_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -28459,42 +29079,33 @@ def test_create_grpc_route_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.create_grpc_route in client._transport._wrapped_methods + assert client._transport.list_gateways in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.create_grpc_route] = ( - mock_rpc - ) + client._transport._wrapped_methods[client._transport.list_gateways] = mock_rpc request = {} - client.create_grpc_route(request) + client.list_gateways(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.create_grpc_route(request) + client.list_gateways(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_create_grpc_route_rest_required_fields( - request_type=gcn_grpc_route.CreateGrpcRouteRequest, -): +def test_list_gateways_rest_required_fields(request_type=gateway.ListGatewaysRequest): transport_class = transports.NetworkServicesRestTransport request_init = {} request_init["parent"] = "" - request_init["grpc_route_id"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -28502,32 +29113,31 @@ def test_create_grpc_route_rest_required_fields( ) # verify fields with default values are dropped - assert "grpcRouteId" not in jsonified_request unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_grpc_route._get_unset_required_fields(jsonified_request) + ).list_gateways._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - assert "grpcRouteId" in jsonified_request - assert jsonified_request["grpcRouteId"] == request_init["grpc_route_id"] jsonified_request["parent"] = "parent_value" - jsonified_request["grpcRouteId"] = "grpc_route_id_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_grpc_route._get_unset_required_fields(jsonified_request) + ).list_gateways._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("grpc_route_id",)) + assert not set(unset_fields) - set( + ( + "page_size", + "page_token", + ) + ) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone assert "parent" in jsonified_request assert jsonified_request["parent"] == "parent_value" - assert "grpcRouteId" in jsonified_request - assert jsonified_request["grpcRouteId"] == "grpc_route_id_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -28536,7 +29146,7 @@ def test_create_grpc_route_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = gateway.ListGatewaysResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -28548,52 +29158,47 @@ def test_create_grpc_route_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "post", + "method": "get", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = gateway.ListGatewaysResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_grpc_route(request) + response = client.list_gateways(request) - expected_params = [ - ( - "grpcRouteId", - "", - ), - ("$alt", "json;enum-encoding=int"), - ] + expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_create_grpc_route_rest_unset_required_fields(): +def test_list_gateways_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.create_grpc_route._get_unset_required_fields({}) + unset_fields = transport.list_gateways._get_unset_required_fields({}) assert set(unset_fields) == ( - set(("grpcRouteId",)) - & set( + set( ( - "parent", - "grpcRouteId", - "grpcRoute", + "pageSize", + "pageToken", ) ) + & set(("parent",)) ) -def test_create_grpc_route_rest_flattened(): +def test_list_gateways_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -28602,7 +29207,7 @@ def test_create_grpc_route_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = gateway.ListGatewaysResponse() # get arguments that satisfy an http rule for this method sample_request = {"parent": "projects/sample1/locations/sample2"} @@ -28610,32 +29215,32 @@ def test_create_grpc_route_rest_flattened(): # get truthy value for each flattened field mock_args = dict( parent="parent_value", - grpc_route=gcn_grpc_route.GrpcRoute(name="name_value"), - grpc_route_id="grpc_route_id_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = gateway.ListGatewaysResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_grpc_route(**mock_args) + client.list_gateways(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/grpcRoutes" % client.transport._host, + "%s/v1/{parent=projects/*/locations/*}/gateways" % client.transport._host, args[1], ) -def test_create_grpc_route_rest_flattened_error(transport: str = "rest"): +def test_list_gateways_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -28644,15 +29249,74 @@ def test_create_grpc_route_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.create_grpc_route( - gcn_grpc_route.CreateGrpcRouteRequest(), + client.list_gateways( + gateway.ListGatewaysRequest(), parent="parent_value", - grpc_route=gcn_grpc_route.GrpcRoute(name="name_value"), - grpc_route_id="grpc_route_id_value", ) -def test_update_grpc_route_rest_use_cached_wrapped_rpc(): +def test_list_gateways_rest_pager(transport: str = "rest"): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + gateway.ListGatewaysResponse( + gateways=[ + gateway.Gateway(), + gateway.Gateway(), + gateway.Gateway(), + ], + next_page_token="abc", + ), + gateway.ListGatewaysResponse( + gateways=[], + next_page_token="def", + ), + gateway.ListGatewaysResponse( + gateways=[ + gateway.Gateway(), + ], + next_page_token="ghi", + ), + gateway.ListGatewaysResponse( + gateways=[ + gateway.Gateway(), + gateway.Gateway(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(gateway.ListGatewaysResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_gateways(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, gateway.Gateway) for i in results) + + pages = list(client.list_gateways(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_get_gateway_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -28666,40 +29330,33 @@ def test_update_grpc_route_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.update_grpc_route in client._transport._wrapped_methods + assert client._transport.get_gateway in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.update_grpc_route] = ( - mock_rpc - ) + client._transport._wrapped_methods[client._transport.get_gateway] = mock_rpc request = {} - client.update_grpc_route(request) + client.get_gateway(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.update_grpc_route(request) + client.get_gateway(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_update_grpc_route_rest_required_fields( - request_type=gcn_grpc_route.UpdateGrpcRouteRequest, -): +def test_get_gateway_rest_required_fields(request_type=gateway.GetGatewayRequest): transport_class = transports.NetworkServicesRestTransport request_init = {} + request_init["name"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -28710,19 +29367,21 @@ def test_update_grpc_route_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_grpc_route._get_unset_required_fields(jsonified_request) + ).get_gateway._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present + jsonified_request["name"] = "name_value" + unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_grpc_route._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("update_mask",)) + ).get_gateway._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -28731,7 +29390,7 @@ def test_update_grpc_route_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = gateway.Gateway() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -28743,37 +29402,39 @@ def test_update_grpc_route_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "patch", + "method": "get", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = gateway.Gateway.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_grpc_route(request) + response = client.get_gateway(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_update_grpc_route_rest_unset_required_fields(): +def test_get_gateway_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.update_grpc_route._get_unset_required_fields({}) - assert set(unset_fields) == (set(("updateMask",)) & set(("grpcRoute",))) + unset_fields = transport.get_gateway._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) -def test_update_grpc_route_rest_flattened(): +def test_get_gateway_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -28782,44 +29443,40 @@ def test_update_grpc_route_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = gateway.Gateway() # get arguments that satisfy an http rule for this method - sample_request = { - "grpc_route": { - "name": "projects/sample1/locations/sample2/grpcRoutes/sample3" - } - } + sample_request = {"name": "projects/sample1/locations/sample2/gateways/sample3"} # get truthy value for each flattened field mock_args = dict( - grpc_route=gcn_grpc_route.GrpcRoute(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + name="name_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = gateway.Gateway.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_grpc_route(**mock_args) + client.get_gateway(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{grpc_route.name=projects/*/locations/*/grpcRoutes/*}" - % client.transport._host, + "%s/v1/{name=projects/*/locations/*/gateways/*}" % client.transport._host, args[1], ) -def test_update_grpc_route_rest_flattened_error(transport: str = "rest"): +def test_get_gateway_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -28828,14 +29485,13 @@ def test_update_grpc_route_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.update_grpc_route( - gcn_grpc_route.UpdateGrpcRouteRequest(), - grpc_route=gcn_grpc_route.GrpcRoute(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + client.get_gateway( + gateway.GetGatewayRequest(), + name="name_value", ) -def test_delete_grpc_route_rest_use_cached_wrapped_rpc(): +def test_create_gateway_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -28849,19 +29505,17 @@ def test_delete_grpc_route_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.delete_grpc_route in client._transport._wrapped_methods + assert client._transport.create_gateway in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.delete_grpc_route] = ( - mock_rpc - ) + client._transport._wrapped_methods[client._transport.create_gateway] = mock_rpc request = {} - client.delete_grpc_route(request) + client.create_gateway(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 @@ -28870,20 +29524,21 @@ def test_delete_grpc_route_rest_use_cached_wrapped_rpc(): # subsequent calls should use the cached wrapper wrapper_fn.reset_mock() - client.delete_grpc_route(request) + client.create_gateway(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_delete_grpc_route_rest_required_fields( - request_type=grpc_route.DeleteGrpcRouteRequest, +def test_create_gateway_rest_required_fields( + request_type=gcn_gateway.CreateGatewayRequest, ): transport_class = transports.NetworkServicesRestTransport request_init = {} - request_init["name"] = "" + request_init["parent"] = "" + request_init["gateway_id"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -28891,24 +29546,32 @@ def test_delete_grpc_route_rest_required_fields( ) # verify fields with default values are dropped + assert "gatewayId" not in jsonified_request unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_grpc_route._get_unset_required_fields(jsonified_request) + ).create_gateway._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present + assert "gatewayId" in jsonified_request + assert jsonified_request["gatewayId"] == request_init["gateway_id"] - jsonified_request["name"] = "name_value" + jsonified_request["parent"] = "parent_value" + jsonified_request["gatewayId"] = "gateway_id_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_grpc_route._get_unset_required_fields(jsonified_request) + ).create_gateway._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("gateway_id",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "gatewayId" in jsonified_request + assert jsonified_request["gatewayId"] == "gateway_id_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -28929,9 +29592,10 @@ def test_delete_grpc_route_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "delete", + "method": "post", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() @@ -28942,23 +29606,38 @@ def test_delete_grpc_route_rest_required_fields( req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_grpc_route(request) + response = client.create_gateway(request) - expected_params = [("$alt", "json;enum-encoding=int")] + expected_params = [ + ( + "gatewayId", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_delete_grpc_route_rest_unset_required_fields(): +def test_create_gateway_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.delete_grpc_route._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + unset_fields = transport.create_gateway._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("gatewayId",)) + & set( + ( + "parent", + "gatewayId", + "gateway", + ) + ) + ) -def test_delete_grpc_route_rest_flattened(): +def test_create_gateway_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -28970,13 +29649,13 @@ def test_delete_grpc_route_rest_flattened(): return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/grpcRoutes/sample3" - } + sample_request = {"parent": "projects/sample1/locations/sample2"} # get truthy value for each flattened field mock_args = dict( - name="name_value", + parent="parent_value", + gateway=gcn_gateway.Gateway(name="name_value"), + gateway_id="gateway_id_value", ) mock_args.update(sample_request) @@ -28988,19 +29667,19 @@ def test_delete_grpc_route_rest_flattened(): req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_grpc_route(**mock_args) + client.create_gateway(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/grpcRoutes/*}" % client.transport._host, + "%s/v1/{parent=projects/*/locations/*}/gateways" % client.transport._host, args[1], ) -def test_delete_grpc_route_rest_flattened_error(transport: str = "rest"): +def test_create_gateway_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -29009,13 +29688,15 @@ def test_delete_grpc_route_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.delete_grpc_route( - grpc_route.DeleteGrpcRouteRequest(), - name="name_value", + client.create_gateway( + gcn_gateway.CreateGatewayRequest(), + parent="parent_value", + gateway=gcn_gateway.Gateway(name="name_value"), + gateway_id="gateway_id_value", ) -def test_list_http_routes_rest_use_cached_wrapped_rpc(): +def test_update_gateway_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -29029,37 +29710,38 @@ def test_list_http_routes_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.list_http_routes in client._transport._wrapped_methods + assert client._transport.update_gateway in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.list_http_routes] = ( - mock_rpc - ) + client._transport._wrapped_methods[client._transport.update_gateway] = mock_rpc request = {} - client.list_http_routes(request) + client.update_gateway(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_http_routes(request) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.update_gateway(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_http_routes_rest_required_fields( - request_type=http_route.ListHttpRoutesRequest, +def test_update_gateway_rest_required_fields( + request_type=gcn_gateway.UpdateGatewayRequest, ): transport_class = transports.NetworkServicesRestTransport request_init = {} - request_init["parent"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -29070,29 +29752,19 @@ def test_list_http_routes_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_http_routes._get_unset_required_fields(jsonified_request) + ).update_gateway._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["parent"] = "parent_value" - unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_http_routes._get_unset_required_fields(jsonified_request) + ).update_gateway._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "page_size", - "page_token", - "return_partial_success", - ) - ) + assert not set(unset_fields) - set(("update_mask",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -29101,7 +29773,7 @@ def test_list_http_routes_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = http_route.ListHttpRoutesResponse() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -29113,48 +29785,37 @@ def test_list_http_routes_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "patch", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = http_route.ListHttpRoutesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_http_routes(request) + response = client.update_gateway(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_list_http_routes_rest_unset_required_fields(): +def test_update_gateway_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.list_http_routes._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "pageSize", - "pageToken", - "returnPartialSuccess", - ) - ) - & set(("parent",)) - ) + unset_fields = transport.update_gateway._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("gateway",))) -def test_list_http_routes_rest_flattened(): +def test_update_gateway_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -29163,40 +29824,42 @@ def test_list_http_routes_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = http_route.ListHttpRoutesResponse() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} + sample_request = { + "gateway": {"name": "projects/sample1/locations/sample2/gateways/sample3"} + } # get truthy value for each flattened field mock_args = dict( - parent="parent_value", + gateway=gcn_gateway.Gateway(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = http_route.ListHttpRoutesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_http_routes(**mock_args) + client.update_gateway(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/httpRoutes" % client.transport._host, + "%s/v1/{gateway.name=projects/*/locations/*/gateways/*}" + % client.transport._host, args[1], ) -def test_list_http_routes_rest_flattened_error(transport: str = "rest"): +def test_update_gateway_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -29205,112 +29868,54 @@ def test_list_http_routes_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_http_routes( - http_route.ListHttpRoutesRequest(), - parent="parent_value", + client.update_gateway( + gcn_gateway.UpdateGatewayRequest(), + gateway=gcn_gateway.Gateway(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) -def test_list_http_routes_rest_pager(transport: str = "rest"): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - http_route.ListHttpRoutesResponse( - http_routes=[ - http_route.HttpRoute(), - http_route.HttpRoute(), - http_route.HttpRoute(), - ], - next_page_token="abc", - ), - http_route.ListHttpRoutesResponse( - http_routes=[], - next_page_token="def", - ), - http_route.ListHttpRoutesResponse( - http_routes=[ - http_route.HttpRoute(), - ], - next_page_token="ghi", - ), - http_route.ListHttpRoutesResponse( - http_routes=[ - http_route.HttpRoute(), - http_route.HttpRoute(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple(http_route.ListHttpRoutesResponse.to_json(x) for x in response) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "projects/sample1/locations/sample2"} - - pager = client.list_http_routes(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, http_route.HttpRoute) for i in results) - - pages = list(client.list_http_routes(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token - - -def test_get_http_route_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) +def test_delete_gateway_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) # Should wrap all calls on client creation assert wrapper_fn.call_count > 0 wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.get_http_route in client._transport._wrapped_methods + assert client._transport.delete_gateway in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.get_http_route] = mock_rpc + client._transport._wrapped_methods[client._transport.delete_gateway] = mock_rpc request = {} - client.get_http_route(request) + client.delete_gateway(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.get_http_route(request) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_gateway(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_get_http_route_rest_required_fields( - request_type=http_route.GetHttpRouteRequest, -): +def test_delete_gateway_rest_required_fields(request_type=gateway.DeleteGatewayRequest): transport_class = transports.NetworkServicesRestTransport request_init = {} @@ -29325,7 +29930,7 @@ def test_get_http_route_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_http_route._get_unset_required_fields(jsonified_request) + ).delete_gateway._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -29334,7 +29939,7 @@ def test_get_http_route_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_http_route._get_unset_required_fields(jsonified_request) + ).delete_gateway._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -29348,7 +29953,7 @@ def test_get_http_route_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = http_route.HttpRoute() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -29360,39 +29965,36 @@ def test_get_http_route_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "delete", "query_params": pb_request, } transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = http_route.HttpRoute.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_http_route(request) + response = client.delete_gateway(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_get_http_route_rest_unset_required_fields(): +def test_delete_gateway_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.get_http_route._get_unset_required_fields({}) + unset_fields = transport.delete_gateway._get_unset_required_fields({}) assert set(unset_fields) == (set(()) & set(("name",))) -def test_get_http_route_rest_flattened(): +def test_delete_gateway_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -29401,12 +30003,10 @@ def test_get_http_route_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = http_route.HttpRoute() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/httpRoutes/sample3" - } + sample_request = {"name": "projects/sample1/locations/sample2/gateways/sample3"} # get truthy value for each flattened field mock_args = dict( @@ -29417,26 +30017,24 @@ def test_get_http_route_rest_flattened(): # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = http_route.HttpRoute.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_http_route(**mock_args) + client.delete_gateway(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/httpRoutes/*}" % client.transport._host, + "%s/v1/{name=projects/*/locations/*/gateways/*}" % client.transport._host, args[1], ) -def test_get_http_route_rest_flattened_error(transport: str = "rest"): +def test_delete_gateway_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -29445,13 +30043,13 @@ def test_get_http_route_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.get_http_route( - http_route.GetHttpRouteRequest(), + client.delete_gateway( + gateway.DeleteGatewayRequest(), name="name_value", ) -def test_create_http_route_rest_use_cached_wrapped_rpc(): +def test_list_grpc_routes_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -29465,42 +30063,37 @@ def test_create_http_route_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.create_http_route in client._transport._wrapped_methods + assert client._transport.list_grpc_routes in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.create_http_route] = ( + client._transport._wrapped_methods[client._transport.list_grpc_routes] = ( mock_rpc ) request = {} - client.create_http_route(request) + client.list_grpc_routes(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.create_http_route(request) + client.list_grpc_routes(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_create_http_route_rest_required_fields( - request_type=gcn_http_route.CreateHttpRouteRequest, +def test_list_grpc_routes_rest_required_fields( + request_type=grpc_route.ListGrpcRoutesRequest, ): transport_class = transports.NetworkServicesRestTransport request_init = {} request_init["parent"] = "" - request_init["http_route_id"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -29508,32 +30101,32 @@ def test_create_http_route_rest_required_fields( ) # verify fields with default values are dropped - assert "httpRouteId" not in jsonified_request unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_http_route._get_unset_required_fields(jsonified_request) + ).list_grpc_routes._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - assert "httpRouteId" in jsonified_request - assert jsonified_request["httpRouteId"] == request_init["http_route_id"] jsonified_request["parent"] = "parent_value" - jsonified_request["httpRouteId"] = "http_route_id_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_http_route._get_unset_required_fields(jsonified_request) + ).list_grpc_routes._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("http_route_id",)) + assert not set(unset_fields) - set( + ( + "page_size", + "page_token", + "return_partial_success", + ) + ) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone assert "parent" in jsonified_request assert jsonified_request["parent"] == "parent_value" - assert "httpRouteId" in jsonified_request - assert jsonified_request["httpRouteId"] == "http_route_id_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -29542,7 +30135,7 @@ def test_create_http_route_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = grpc_route.ListGrpcRoutesResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -29554,52 +30147,48 @@ def test_create_http_route_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "post", + "method": "get", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grpc_route.ListGrpcRoutesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_http_route(request) + response = client.list_grpc_routes(request) - expected_params = [ - ( - "httpRouteId", - "", - ), - ("$alt", "json;enum-encoding=int"), - ] + expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_create_http_route_rest_unset_required_fields(): +def test_list_grpc_routes_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.create_http_route._get_unset_required_fields({}) + unset_fields = transport.list_grpc_routes._get_unset_required_fields({}) assert set(unset_fields) == ( - set(("httpRouteId",)) - & set( + set( ( - "parent", - "httpRouteId", - "httpRoute", + "pageSize", + "pageToken", + "returnPartialSuccess", ) ) + & set(("parent",)) ) -def test_create_http_route_rest_flattened(): +def test_list_grpc_routes_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -29608,7 +30197,7 @@ def test_create_http_route_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = grpc_route.ListGrpcRoutesResponse() # get arguments that satisfy an http rule for this method sample_request = {"parent": "projects/sample1/locations/sample2"} @@ -29616,32 +30205,32 @@ def test_create_http_route_rest_flattened(): # get truthy value for each flattened field mock_args = dict( parent="parent_value", - http_route=gcn_http_route.HttpRoute(name="name_value"), - http_route_id="http_route_id_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = grpc_route.ListGrpcRoutesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_http_route(**mock_args) + client.list_grpc_routes(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/httpRoutes" % client.transport._host, + "%s/v1/{parent=projects/*/locations/*}/grpcRoutes" % client.transport._host, args[1], ) -def test_create_http_route_rest_flattened_error(transport: str = "rest"): +def test_list_grpc_routes_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -29650,15 +30239,74 @@ def test_create_http_route_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.create_http_route( - gcn_http_route.CreateHttpRouteRequest(), + client.list_grpc_routes( + grpc_route.ListGrpcRoutesRequest(), parent="parent_value", - http_route=gcn_http_route.HttpRoute(name="name_value"), - http_route_id="http_route_id_value", ) -def test_update_http_route_rest_use_cached_wrapped_rpc(): +def test_list_grpc_routes_rest_pager(transport: str = "rest"): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + grpc_route.ListGrpcRoutesResponse( + grpc_routes=[ + grpc_route.GrpcRoute(), + grpc_route.GrpcRoute(), + grpc_route.GrpcRoute(), + ], + next_page_token="abc", + ), + grpc_route.ListGrpcRoutesResponse( + grpc_routes=[], + next_page_token="def", + ), + grpc_route.ListGrpcRoutesResponse( + grpc_routes=[ + grpc_route.GrpcRoute(), + ], + next_page_token="ghi", + ), + grpc_route.ListGrpcRoutesResponse( + grpc_routes=[ + grpc_route.GrpcRoute(), + grpc_route.GrpcRoute(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(grpc_route.ListGrpcRoutesResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_grpc_routes(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, grpc_route.GrpcRoute) for i in results) + + pages = list(client.list_grpc_routes(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_get_grpc_route_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -29672,40 +30320,35 @@ def test_update_http_route_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.update_http_route in client._transport._wrapped_methods + assert client._transport.get_grpc_route in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.update_http_route] = ( - mock_rpc - ) + client._transport._wrapped_methods[client._transport.get_grpc_route] = mock_rpc request = {} - client.update_http_route(request) + client.get_grpc_route(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.update_http_route(request) + client.get_grpc_route(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_update_http_route_rest_required_fields( - request_type=gcn_http_route.UpdateHttpRouteRequest, +def test_get_grpc_route_rest_required_fields( + request_type=grpc_route.GetGrpcRouteRequest, ): transport_class = transports.NetworkServicesRestTransport request_init = {} + request_init["name"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -29716,19 +30359,21 @@ def test_update_http_route_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_http_route._get_unset_required_fields(jsonified_request) + ).get_grpc_route._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present + jsonified_request["name"] = "name_value" + unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_http_route._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("update_mask",)) + ).get_grpc_route._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -29737,7 +30382,7 @@ def test_update_http_route_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = grpc_route.GrpcRoute() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -29749,37 +30394,39 @@ def test_update_http_route_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "patch", + "method": "get", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grpc_route.GrpcRoute.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_http_route(request) + response = client.get_grpc_route(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_update_http_route_rest_unset_required_fields(): +def test_get_grpc_route_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.update_http_route._get_unset_required_fields({}) - assert set(unset_fields) == (set(("updateMask",)) & set(("httpRoute",))) + unset_fields = transport.get_grpc_route._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) -def test_update_http_route_rest_flattened(): +def test_get_grpc_route_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -29788,44 +30435,42 @@ def test_update_http_route_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = grpc_route.GrpcRoute() # get arguments that satisfy an http rule for this method sample_request = { - "http_route": { - "name": "projects/sample1/locations/sample2/httpRoutes/sample3" - } + "name": "projects/sample1/locations/sample2/grpcRoutes/sample3" } # get truthy value for each flattened field mock_args = dict( - http_route=gcn_http_route.HttpRoute(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + name="name_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = grpc_route.GrpcRoute.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_http_route(**mock_args) + client.get_grpc_route(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{http_route.name=projects/*/locations/*/httpRoutes/*}" - % client.transport._host, + "%s/v1/{name=projects/*/locations/*/grpcRoutes/*}" % client.transport._host, args[1], ) -def test_update_http_route_rest_flattened_error(transport: str = "rest"): +def test_get_grpc_route_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -29834,14 +30479,13 @@ def test_update_http_route_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.update_http_route( - gcn_http_route.UpdateHttpRouteRequest(), - http_route=gcn_http_route.HttpRoute(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + client.get_grpc_route( + grpc_route.GetGrpcRouteRequest(), + name="name_value", ) -def test_delete_http_route_rest_use_cached_wrapped_rpc(): +def test_create_grpc_route_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -29855,19 +30499,19 @@ def test_delete_http_route_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.delete_http_route in client._transport._wrapped_methods + assert client._transport.create_grpc_route in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.delete_http_route] = ( + client._transport._wrapped_methods[client._transport.create_grpc_route] = ( mock_rpc ) request = {} - client.delete_http_route(request) + client.create_grpc_route(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 @@ -29876,20 +30520,21 @@ def test_delete_http_route_rest_use_cached_wrapped_rpc(): # subsequent calls should use the cached wrapper wrapper_fn.reset_mock() - client.delete_http_route(request) + client.create_grpc_route(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_delete_http_route_rest_required_fields( - request_type=http_route.DeleteHttpRouteRequest, +def test_create_grpc_route_rest_required_fields( + request_type=gcn_grpc_route.CreateGrpcRouteRequest, ): transport_class = transports.NetworkServicesRestTransport request_init = {} - request_init["name"] = "" + request_init["parent"] = "" + request_init["grpc_route_id"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -29897,24 +30542,32 @@ def test_delete_http_route_rest_required_fields( ) # verify fields with default values are dropped + assert "grpcRouteId" not in jsonified_request unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_http_route._get_unset_required_fields(jsonified_request) + ).create_grpc_route._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present + assert "grpcRouteId" in jsonified_request + assert jsonified_request["grpcRouteId"] == request_init["grpc_route_id"] - jsonified_request["name"] = "name_value" + jsonified_request["parent"] = "parent_value" + jsonified_request["grpcRouteId"] = "grpc_route_id_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_http_route._get_unset_required_fields(jsonified_request) + ).create_grpc_route._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("grpc_route_id",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "grpcRouteId" in jsonified_request + assert jsonified_request["grpcRouteId"] == "grpc_route_id_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -29935,9 +30588,10 @@ def test_delete_http_route_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "delete", + "method": "post", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() @@ -29948,23 +30602,38 @@ def test_delete_http_route_rest_required_fields( req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_http_route(request) + response = client.create_grpc_route(request) - expected_params = [("$alt", "json;enum-encoding=int")] + expected_params = [ + ( + "grpcRouteId", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_delete_http_route_rest_unset_required_fields(): +def test_create_grpc_route_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.delete_http_route._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + unset_fields = transport.create_grpc_route._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("grpcRouteId",)) + & set( + ( + "parent", + "grpcRouteId", + "grpcRoute", + ) + ) + ) -def test_delete_http_route_rest_flattened(): +def test_create_grpc_route_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -29976,13 +30645,13 @@ def test_delete_http_route_rest_flattened(): return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/httpRoutes/sample3" - } + sample_request = {"parent": "projects/sample1/locations/sample2"} # get truthy value for each flattened field mock_args = dict( - name="name_value", + parent="parent_value", + grpc_route=gcn_grpc_route.GrpcRoute(name="name_value"), + grpc_route_id="grpc_route_id_value", ) mock_args.update(sample_request) @@ -29994,19 +30663,19 @@ def test_delete_http_route_rest_flattened(): req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_http_route(**mock_args) + client.create_grpc_route(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/httpRoutes/*}" % client.transport._host, + "%s/v1/{parent=projects/*/locations/*}/grpcRoutes" % client.transport._host, args[1], ) -def test_delete_http_route_rest_flattened_error(transport: str = "rest"): +def test_create_grpc_route_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -30015,13 +30684,15 @@ def test_delete_http_route_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.delete_http_route( - http_route.DeleteHttpRouteRequest(), - name="name_value", + client.create_grpc_route( + gcn_grpc_route.CreateGrpcRouteRequest(), + parent="parent_value", + grpc_route=gcn_grpc_route.GrpcRoute(name="name_value"), + grpc_route_id="grpc_route_id_value", ) -def test_list_tcp_routes_rest_use_cached_wrapped_rpc(): +def test_update_grpc_route_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -30035,35 +30706,40 @@ def test_list_tcp_routes_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.list_tcp_routes in client._transport._wrapped_methods + assert client._transport.update_grpc_route in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.list_tcp_routes] = mock_rpc + client._transport._wrapped_methods[client._transport.update_grpc_route] = ( + mock_rpc + ) request = {} - client.list_tcp_routes(request) + client.update_grpc_route(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_tcp_routes(request) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.update_grpc_route(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_tcp_routes_rest_required_fields( - request_type=tcp_route.ListTcpRoutesRequest, +def test_update_grpc_route_rest_required_fields( + request_type=gcn_grpc_route.UpdateGrpcRouteRequest, ): transport_class = transports.NetworkServicesRestTransport request_init = {} - request_init["parent"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -30074,29 +30750,19 @@ def test_list_tcp_routes_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_tcp_routes._get_unset_required_fields(jsonified_request) + ).update_grpc_route._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["parent"] = "parent_value" - unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_tcp_routes._get_unset_required_fields(jsonified_request) + ).update_grpc_route._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "page_size", - "page_token", - "return_partial_success", - ) - ) + assert not set(unset_fields) - set(("update_mask",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -30105,7 +30771,7 @@ def test_list_tcp_routes_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = tcp_route.ListTcpRoutesResponse() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -30117,48 +30783,37 @@ def test_list_tcp_routes_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "patch", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = tcp_route.ListTcpRoutesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_tcp_routes(request) + response = client.update_grpc_route(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_list_tcp_routes_rest_unset_required_fields(): +def test_update_grpc_route_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.list_tcp_routes._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "pageSize", - "pageToken", - "returnPartialSuccess", - ) - ) - & set(("parent",)) - ) + unset_fields = transport.update_grpc_route._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("grpcRoute",))) -def test_list_tcp_routes_rest_flattened(): +def test_update_grpc_route_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -30167,40 +30822,44 @@ def test_list_tcp_routes_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = tcp_route.ListTcpRoutesResponse() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} + sample_request = { + "grpc_route": { + "name": "projects/sample1/locations/sample2/grpcRoutes/sample3" + } + } # get truthy value for each flattened field mock_args = dict( - parent="parent_value", + grpc_route=gcn_grpc_route.GrpcRoute(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = tcp_route.ListTcpRoutesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_tcp_routes(**mock_args) + client.update_grpc_route(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/tcpRoutes" % client.transport._host, + "%s/v1/{grpc_route.name=projects/*/locations/*/grpcRoutes/*}" + % client.transport._host, args[1], ) -def test_list_tcp_routes_rest_flattened_error(transport: str = "rest"): +def test_update_grpc_route_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -30209,74 +30868,14 @@ def test_list_tcp_routes_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_tcp_routes( - tcp_route.ListTcpRoutesRequest(), - parent="parent_value", + client.update_grpc_route( + gcn_grpc_route.UpdateGrpcRouteRequest(), + grpc_route=gcn_grpc_route.GrpcRoute(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) -def test_list_tcp_routes_rest_pager(transport: str = "rest"): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - tcp_route.ListTcpRoutesResponse( - tcp_routes=[ - tcp_route.TcpRoute(), - tcp_route.TcpRoute(), - tcp_route.TcpRoute(), - ], - next_page_token="abc", - ), - tcp_route.ListTcpRoutesResponse( - tcp_routes=[], - next_page_token="def", - ), - tcp_route.ListTcpRoutesResponse( - tcp_routes=[ - tcp_route.TcpRoute(), - ], - next_page_token="ghi", - ), - tcp_route.ListTcpRoutesResponse( - tcp_routes=[ - tcp_route.TcpRoute(), - tcp_route.TcpRoute(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple(tcp_route.ListTcpRoutesResponse.to_json(x) for x in response) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "projects/sample1/locations/sample2"} - - pager = client.list_tcp_routes(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, tcp_route.TcpRoute) for i in results) - - pages = list(client.list_tcp_routes(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token - - -def test_get_tcp_route_rest_use_cached_wrapped_rpc(): +def test_delete_grpc_route_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -30290,29 +30889,37 @@ def test_get_tcp_route_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.get_tcp_route in client._transport._wrapped_methods + assert client._transport.delete_grpc_route in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.get_tcp_route] = mock_rpc + client._transport._wrapped_methods[client._transport.delete_grpc_route] = ( + mock_rpc + ) request = {} - client.get_tcp_route(request) + client.delete_grpc_route(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.get_tcp_route(request) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_grpc_route(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_get_tcp_route_rest_required_fields(request_type=tcp_route.GetTcpRouteRequest): +def test_delete_grpc_route_rest_required_fields( + request_type=grpc_route.DeleteGrpcRouteRequest, +): transport_class = transports.NetworkServicesRestTransport request_init = {} @@ -30327,7 +30934,7 @@ def test_get_tcp_route_rest_required_fields(request_type=tcp_route.GetTcpRouteRe unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_tcp_route._get_unset_required_fields(jsonified_request) + ).delete_grpc_route._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -30336,7 +30943,7 @@ def test_get_tcp_route_rest_required_fields(request_type=tcp_route.GetTcpRouteRe unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_tcp_route._get_unset_required_fields(jsonified_request) + ).delete_grpc_route._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -30350,7 +30957,7 @@ def test_get_tcp_route_rest_required_fields(request_type=tcp_route.GetTcpRouteRe request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = tcp_route.TcpRoute() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -30362,39 +30969,36 @@ def test_get_tcp_route_rest_required_fields(request_type=tcp_route.GetTcpRouteRe pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "delete", "query_params": pb_request, } transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = tcp_route.TcpRoute.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_tcp_route(request) + response = client.delete_grpc_route(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_get_tcp_route_rest_unset_required_fields(): +def test_delete_grpc_route_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.get_tcp_route._get_unset_required_fields({}) + unset_fields = transport.delete_grpc_route._get_unset_required_fields({}) assert set(unset_fields) == (set(()) & set(("name",))) -def test_get_tcp_route_rest_flattened(): +def test_delete_grpc_route_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -30403,11 +31007,11 @@ def test_get_tcp_route_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = tcp_route.TcpRoute() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method sample_request = { - "name": "projects/sample1/locations/sample2/tcpRoutes/sample3" + "name": "projects/sample1/locations/sample2/grpcRoutes/sample3" } # get truthy value for each flattened field @@ -30419,26 +31023,24 @@ def test_get_tcp_route_rest_flattened(): # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = tcp_route.TcpRoute.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_tcp_route(**mock_args) + client.delete_grpc_route(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/tcpRoutes/*}" % client.transport._host, + "%s/v1/{name=projects/*/locations/*/grpcRoutes/*}" % client.transport._host, args[1], ) -def test_get_tcp_route_rest_flattened_error(transport: str = "rest"): +def test_delete_grpc_route_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -30447,13 +31049,13 @@ def test_get_tcp_route_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.get_tcp_route( - tcp_route.GetTcpRouteRequest(), + client.delete_grpc_route( + grpc_route.DeleteGrpcRouteRequest(), name="name_value", ) -def test_create_tcp_route_rest_use_cached_wrapped_rpc(): +def test_list_http_routes_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -30467,42 +31069,37 @@ def test_create_tcp_route_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.create_tcp_route in client._transport._wrapped_methods + assert client._transport.list_http_routes in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.create_tcp_route] = ( + client._transport._wrapped_methods[client._transport.list_http_routes] = ( mock_rpc ) request = {} - client.create_tcp_route(request) + client.list_http_routes(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.create_tcp_route(request) + client.list_http_routes(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_create_tcp_route_rest_required_fields( - request_type=gcn_tcp_route.CreateTcpRouteRequest, +def test_list_http_routes_rest_required_fields( + request_type=http_route.ListHttpRoutesRequest, ): transport_class = transports.NetworkServicesRestTransport request_init = {} request_init["parent"] = "" - request_init["tcp_route_id"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -30510,32 +31107,33 @@ def test_create_tcp_route_rest_required_fields( ) # verify fields with default values are dropped - assert "tcpRouteId" not in jsonified_request unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_tcp_route._get_unset_required_fields(jsonified_request) + ).list_http_routes._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - assert "tcpRouteId" in jsonified_request - assert jsonified_request["tcpRouteId"] == request_init["tcp_route_id"] jsonified_request["parent"] = "parent_value" - jsonified_request["tcpRouteId"] = "tcp_route_id_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_tcp_route._get_unset_required_fields(jsonified_request) + ).list_http_routes._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("tcp_route_id",)) + assert not set(unset_fields) - set( + ( + "filter", + "page_size", + "page_token", + "return_partial_success", + ) + ) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone assert "parent" in jsonified_request assert jsonified_request["parent"] == "parent_value" - assert "tcpRouteId" in jsonified_request - assert jsonified_request["tcpRouteId"] == "tcp_route_id_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -30544,7 +31142,7 @@ def test_create_tcp_route_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = http_route.ListHttpRoutesResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -30556,52 +31154,49 @@ def test_create_tcp_route_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "post", + "method": "get", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = http_route.ListHttpRoutesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_tcp_route(request) + response = client.list_http_routes(request) - expected_params = [ - ( - "tcpRouteId", - "", - ), - ("$alt", "json;enum-encoding=int"), - ] + expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_create_tcp_route_rest_unset_required_fields(): +def test_list_http_routes_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.create_tcp_route._get_unset_required_fields({}) + unset_fields = transport.list_http_routes._get_unset_required_fields({}) assert set(unset_fields) == ( - set(("tcpRouteId",)) - & set( + set( ( - "parent", - "tcpRouteId", - "tcpRoute", + "filter", + "pageSize", + "pageToken", + "returnPartialSuccess", ) ) + & set(("parent",)) ) -def test_create_tcp_route_rest_flattened(): +def test_list_http_routes_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -30610,7 +31205,7 @@ def test_create_tcp_route_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = http_route.ListHttpRoutesResponse() # get arguments that satisfy an http rule for this method sample_request = {"parent": "projects/sample1/locations/sample2"} @@ -30618,32 +31213,32 @@ def test_create_tcp_route_rest_flattened(): # get truthy value for each flattened field mock_args = dict( parent="parent_value", - tcp_route=gcn_tcp_route.TcpRoute(name="name_value"), - tcp_route_id="tcp_route_id_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = http_route.ListHttpRoutesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_tcp_route(**mock_args) + client.list_http_routes(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/tcpRoutes" % client.transport._host, + "%s/v1/{parent=projects/*/locations/*}/httpRoutes" % client.transport._host, args[1], ) -def test_create_tcp_route_rest_flattened_error(transport: str = "rest"): +def test_list_http_routes_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -30652,15 +31247,74 @@ def test_create_tcp_route_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.create_tcp_route( - gcn_tcp_route.CreateTcpRouteRequest(), + client.list_http_routes( + http_route.ListHttpRoutesRequest(), parent="parent_value", - tcp_route=gcn_tcp_route.TcpRoute(name="name_value"), - tcp_route_id="tcp_route_id_value", ) -def test_update_tcp_route_rest_use_cached_wrapped_rpc(): +def test_list_http_routes_rest_pager(transport: str = "rest"): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + http_route.ListHttpRoutesResponse( + http_routes=[ + http_route.HttpRoute(), + http_route.HttpRoute(), + http_route.HttpRoute(), + ], + next_page_token="abc", + ), + http_route.ListHttpRoutesResponse( + http_routes=[], + next_page_token="def", + ), + http_route.ListHttpRoutesResponse( + http_routes=[ + http_route.HttpRoute(), + ], + next_page_token="ghi", + ), + http_route.ListHttpRoutesResponse( + http_routes=[ + http_route.HttpRoute(), + http_route.HttpRoute(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(http_route.ListHttpRoutesResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_http_routes(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, http_route.HttpRoute) for i in results) + + pages = list(client.list_http_routes(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_get_http_route_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -30674,40 +31328,35 @@ def test_update_tcp_route_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.update_tcp_route in client._transport._wrapped_methods + assert client._transport.get_http_route in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.update_tcp_route] = ( - mock_rpc - ) + client._transport._wrapped_methods[client._transport.get_http_route] = mock_rpc request = {} - client.update_tcp_route(request) + client.get_http_route(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.update_tcp_route(request) + client.get_http_route(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_update_tcp_route_rest_required_fields( - request_type=gcn_tcp_route.UpdateTcpRouteRequest, +def test_get_http_route_rest_required_fields( + request_type=http_route.GetHttpRouteRequest, ): transport_class = transports.NetworkServicesRestTransport request_init = {} + request_init["name"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -30718,19 +31367,21 @@ def test_update_tcp_route_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_tcp_route._get_unset_required_fields(jsonified_request) + ).get_http_route._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present + jsonified_request["name"] = "name_value" + unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_tcp_route._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("update_mask",)) + ).get_http_route._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -30739,7 +31390,7 @@ def test_update_tcp_route_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = http_route.HttpRoute() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -30751,37 +31402,39 @@ def test_update_tcp_route_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "patch", + "method": "get", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = http_route.HttpRoute.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_tcp_route(request) + response = client.get_http_route(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_update_tcp_route_rest_unset_required_fields(): +def test_get_http_route_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.update_tcp_route._get_unset_required_fields({}) - assert set(unset_fields) == (set(("updateMask",)) & set(("tcpRoute",))) + unset_fields = transport.get_http_route._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) -def test_update_tcp_route_rest_flattened(): +def test_get_http_route_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -30790,44 +31443,42 @@ def test_update_tcp_route_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = http_route.HttpRoute() # get arguments that satisfy an http rule for this method sample_request = { - "tcp_route": { - "name": "projects/sample1/locations/sample2/tcpRoutes/sample3" - } + "name": "projects/sample1/locations/sample2/httpRoutes/sample3" } # get truthy value for each flattened field mock_args = dict( - tcp_route=gcn_tcp_route.TcpRoute(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + name="name_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = http_route.HttpRoute.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_tcp_route(**mock_args) + client.get_http_route(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{tcp_route.name=projects/*/locations/*/tcpRoutes/*}" - % client.transport._host, + "%s/v1/{name=projects/*/locations/*/httpRoutes/*}" % client.transport._host, args[1], ) -def test_update_tcp_route_rest_flattened_error(transport: str = "rest"): +def test_get_http_route_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -30836,14 +31487,13 @@ def test_update_tcp_route_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.update_tcp_route( - gcn_tcp_route.UpdateTcpRouteRequest(), - tcp_route=gcn_tcp_route.TcpRoute(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + client.get_http_route( + http_route.GetHttpRouteRequest(), + name="name_value", ) -def test_delete_tcp_route_rest_use_cached_wrapped_rpc(): +def test_create_http_route_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -30857,19 +31507,19 @@ def test_delete_tcp_route_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.delete_tcp_route in client._transport._wrapped_methods + assert client._transport.create_http_route in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.delete_tcp_route] = ( + client._transport._wrapped_methods[client._transport.create_http_route] = ( mock_rpc ) request = {} - client.delete_tcp_route(request) + client.create_http_route(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 @@ -30878,20 +31528,21 @@ def test_delete_tcp_route_rest_use_cached_wrapped_rpc(): # subsequent calls should use the cached wrapper wrapper_fn.reset_mock() - client.delete_tcp_route(request) + client.create_http_route(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_delete_tcp_route_rest_required_fields( - request_type=tcp_route.DeleteTcpRouteRequest, +def test_create_http_route_rest_required_fields( + request_type=gcn_http_route.CreateHttpRouteRequest, ): transport_class = transports.NetworkServicesRestTransport request_init = {} - request_init["name"] = "" + request_init["parent"] = "" + request_init["http_route_id"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -30899,24 +31550,37 @@ def test_delete_tcp_route_rest_required_fields( ) # verify fields with default values are dropped + assert "httpRouteId" not in jsonified_request unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_tcp_route._get_unset_required_fields(jsonified_request) + ).create_http_route._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present + assert "httpRouteId" in jsonified_request + assert jsonified_request["httpRouteId"] == request_init["http_route_id"] - jsonified_request["name"] = "name_value" + jsonified_request["parent"] = "parent_value" + jsonified_request["httpRouteId"] = "http_route_id_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_tcp_route._get_unset_required_fields(jsonified_request) + ).create_http_route._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "http_route_id", + "request_id", + ) + ) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "httpRouteId" in jsonified_request + assert jsonified_request["httpRouteId"] == "http_route_id_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -30937,9 +31601,10 @@ def test_delete_tcp_route_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "delete", + "method": "post", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() @@ -30950,23 +31615,43 @@ def test_delete_tcp_route_rest_required_fields( req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_tcp_route(request) + response = client.create_http_route(request) - expected_params = [("$alt", "json;enum-encoding=int")] + expected_params = [ + ( + "httpRouteId", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_delete_tcp_route_rest_unset_required_fields(): +def test_create_http_route_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.delete_tcp_route._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + unset_fields = transport.create_http_route._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "httpRouteId", + "requestId", + ) + ) + & set( + ( + "parent", + "httpRouteId", + "httpRoute", + ) + ) + ) -def test_delete_tcp_route_rest_flattened(): +def test_create_http_route_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -30978,13 +31663,13 @@ def test_delete_tcp_route_rest_flattened(): return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/tcpRoutes/sample3" - } + sample_request = {"parent": "projects/sample1/locations/sample2"} # get truthy value for each flattened field mock_args = dict( - name="name_value", + parent="parent_value", + http_route=gcn_http_route.HttpRoute(name="name_value"), + http_route_id="http_route_id_value", ) mock_args.update(sample_request) @@ -30996,19 +31681,19 @@ def test_delete_tcp_route_rest_flattened(): req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_tcp_route(**mock_args) + client.create_http_route(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/tcpRoutes/*}" % client.transport._host, + "%s/v1/{parent=projects/*/locations/*}/httpRoutes" % client.transport._host, args[1], ) -def test_delete_tcp_route_rest_flattened_error(transport: str = "rest"): +def test_create_http_route_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -31017,13 +31702,15 @@ def test_delete_tcp_route_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.delete_tcp_route( - tcp_route.DeleteTcpRouteRequest(), - name="name_value", + client.create_http_route( + gcn_http_route.CreateHttpRouteRequest(), + parent="parent_value", + http_route=gcn_http_route.HttpRoute(name="name_value"), + http_route_id="http_route_id_value", ) -def test_list_tls_routes_rest_use_cached_wrapped_rpc(): +def test_update_http_route_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -31037,35 +31724,40 @@ def test_list_tls_routes_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.list_tls_routes in client._transport._wrapped_methods + assert client._transport.update_http_route in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.list_tls_routes] = mock_rpc + client._transport._wrapped_methods[client._transport.update_http_route] = ( + mock_rpc + ) request = {} - client.list_tls_routes(request) + client.update_http_route(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_tls_routes(request) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.update_http_route(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_tls_routes_rest_required_fields( - request_type=tls_route.ListTlsRoutesRequest, +def test_update_http_route_rest_required_fields( + request_type=gcn_http_route.UpdateHttpRouteRequest, ): transport_class = transports.NetworkServicesRestTransport request_init = {} - request_init["parent"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -31076,29 +31768,19 @@ def test_list_tls_routes_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_tls_routes._get_unset_required_fields(jsonified_request) + ).update_http_route._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["parent"] = "parent_value" - unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_tls_routes._get_unset_required_fields(jsonified_request) + ).update_http_route._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "page_size", - "page_token", - "return_partial_success", - ) - ) + assert not set(unset_fields) - set(("update_mask",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -31107,7 +31789,7 @@ def test_list_tls_routes_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = tls_route.ListTlsRoutesResponse() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -31119,48 +31801,37 @@ def test_list_tls_routes_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "patch", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = tls_route.ListTlsRoutesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_tls_routes(request) + response = client.update_http_route(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_list_tls_routes_rest_unset_required_fields(): +def test_update_http_route_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.list_tls_routes._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "pageSize", - "pageToken", - "returnPartialSuccess", - ) - ) - & set(("parent",)) - ) + unset_fields = transport.update_http_route._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("httpRoute",))) -def test_list_tls_routes_rest_flattened(): +def test_update_http_route_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -31169,40 +31840,44 @@ def test_list_tls_routes_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = tls_route.ListTlsRoutesResponse() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} + sample_request = { + "http_route": { + "name": "projects/sample1/locations/sample2/httpRoutes/sample3" + } + } # get truthy value for each flattened field mock_args = dict( - parent="parent_value", + http_route=gcn_http_route.HttpRoute(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = tls_route.ListTlsRoutesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_tls_routes(**mock_args) + client.update_http_route(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/tlsRoutes" % client.transport._host, + "%s/v1/{http_route.name=projects/*/locations/*/httpRoutes/*}" + % client.transport._host, args[1], ) -def test_list_tls_routes_rest_flattened_error(transport: str = "rest"): +def test_update_http_route_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -31211,74 +31886,14 @@ def test_list_tls_routes_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_tls_routes( - tls_route.ListTlsRoutesRequest(), - parent="parent_value", - ) - - -def test_list_tls_routes_rest_pager(transport: str = "rest"): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - tls_route.ListTlsRoutesResponse( - tls_routes=[ - tls_route.TlsRoute(), - tls_route.TlsRoute(), - tls_route.TlsRoute(), - ], - next_page_token="abc", - ), - tls_route.ListTlsRoutesResponse( - tls_routes=[], - next_page_token="def", - ), - tls_route.ListTlsRoutesResponse( - tls_routes=[ - tls_route.TlsRoute(), - ], - next_page_token="ghi", - ), - tls_route.ListTlsRoutesResponse( - tls_routes=[ - tls_route.TlsRoute(), - tls_route.TlsRoute(), - ], - ), + client.update_http_route( + gcn_http_route.UpdateHttpRouteRequest(), + http_route=gcn_http_route.HttpRoute(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple(tls_route.ListTlsRoutesResponse.to_json(x) for x in response) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "projects/sample1/locations/sample2"} - - pager = client.list_tls_routes(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, tls_route.TlsRoute) for i in results) - - pages = list(client.list_tls_routes(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token -def test_get_tls_route_rest_use_cached_wrapped_rpc(): +def test_delete_http_route_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -31292,29 +31907,37 @@ def test_get_tls_route_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.get_tls_route in client._transport._wrapped_methods + assert client._transport.delete_http_route in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.get_tls_route] = mock_rpc + client._transport._wrapped_methods[client._transport.delete_http_route] = ( + mock_rpc + ) request = {} - client.get_tls_route(request) + client.delete_http_route(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.get_tls_route(request) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_http_route(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_get_tls_route_rest_required_fields(request_type=tls_route.GetTlsRouteRequest): +def test_delete_http_route_rest_required_fields( + request_type=http_route.DeleteHttpRouteRequest, +): transport_class = transports.NetworkServicesRestTransport request_init = {} @@ -31329,7 +31952,7 @@ def test_get_tls_route_rest_required_fields(request_type=tls_route.GetTlsRouteRe unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_tls_route._get_unset_required_fields(jsonified_request) + ).delete_http_route._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -31338,7 +31961,7 @@ def test_get_tls_route_rest_required_fields(request_type=tls_route.GetTlsRouteRe unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_tls_route._get_unset_required_fields(jsonified_request) + ).delete_http_route._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -31352,7 +31975,7 @@ def test_get_tls_route_rest_required_fields(request_type=tls_route.GetTlsRouteRe request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = tls_route.TlsRoute() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -31364,39 +31987,36 @@ def test_get_tls_route_rest_required_fields(request_type=tls_route.GetTlsRouteRe pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "delete", "query_params": pb_request, } transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = tls_route.TlsRoute.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_tls_route(request) + response = client.delete_http_route(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_get_tls_route_rest_unset_required_fields(): +def test_delete_http_route_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.get_tls_route._get_unset_required_fields({}) + unset_fields = transport.delete_http_route._get_unset_required_fields({}) assert set(unset_fields) == (set(()) & set(("name",))) -def test_get_tls_route_rest_flattened(): +def test_delete_http_route_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -31405,11 +32025,11 @@ def test_get_tls_route_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = tls_route.TlsRoute() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method sample_request = { - "name": "projects/sample1/locations/sample2/tlsRoutes/sample3" + "name": "projects/sample1/locations/sample2/httpRoutes/sample3" } # get truthy value for each flattened field @@ -31421,26 +32041,24 @@ def test_get_tls_route_rest_flattened(): # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = tls_route.TlsRoute.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_tls_route(**mock_args) + client.delete_http_route(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/tlsRoutes/*}" % client.transport._host, + "%s/v1/{name=projects/*/locations/*/httpRoutes/*}" % client.transport._host, args[1], ) -def test_get_tls_route_rest_flattened_error(transport: str = "rest"): +def test_delete_http_route_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -31449,13 +32067,13 @@ def test_get_tls_route_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.get_tls_route( - tls_route.GetTlsRouteRequest(), + client.delete_http_route( + http_route.DeleteHttpRouteRequest(), name="name_value", ) -def test_create_tls_route_rest_use_cached_wrapped_rpc(): +def test_list_tcp_routes_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -31469,42 +32087,35 @@ def test_create_tls_route_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.create_tls_route in client._transport._wrapped_methods + assert client._transport.list_tcp_routes in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.create_tls_route] = ( - mock_rpc - ) + client._transport._wrapped_methods[client._transport.list_tcp_routes] = mock_rpc request = {} - client.create_tls_route(request) + client.list_tcp_routes(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.create_tls_route(request) + client.list_tcp_routes(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_create_tls_route_rest_required_fields( - request_type=gcn_tls_route.CreateTlsRouteRequest, +def test_list_tcp_routes_rest_required_fields( + request_type=tcp_route.ListTcpRoutesRequest, ): transport_class = transports.NetworkServicesRestTransport request_init = {} request_init["parent"] = "" - request_init["tls_route_id"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -31512,32 +32123,32 @@ def test_create_tls_route_rest_required_fields( ) # verify fields with default values are dropped - assert "tlsRouteId" not in jsonified_request unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_tls_route._get_unset_required_fields(jsonified_request) + ).list_tcp_routes._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - assert "tlsRouteId" in jsonified_request - assert jsonified_request["tlsRouteId"] == request_init["tls_route_id"] jsonified_request["parent"] = "parent_value" - jsonified_request["tlsRouteId"] = "tls_route_id_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_tls_route._get_unset_required_fields(jsonified_request) + ).list_tcp_routes._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("tls_route_id",)) + assert not set(unset_fields) - set( + ( + "page_size", + "page_token", + "return_partial_success", + ) + ) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone assert "parent" in jsonified_request assert jsonified_request["parent"] == "parent_value" - assert "tlsRouteId" in jsonified_request - assert jsonified_request["tlsRouteId"] == "tls_route_id_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -31546,7 +32157,7 @@ def test_create_tls_route_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = tcp_route.ListTcpRoutesResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -31558,52 +32169,48 @@ def test_create_tls_route_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "post", + "method": "get", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = tcp_route.ListTcpRoutesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_tls_route(request) + response = client.list_tcp_routes(request) - expected_params = [ - ( - "tlsRouteId", - "", - ), - ("$alt", "json;enum-encoding=int"), - ] + expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_create_tls_route_rest_unset_required_fields(): +def test_list_tcp_routes_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.create_tls_route._get_unset_required_fields({}) + unset_fields = transport.list_tcp_routes._get_unset_required_fields({}) assert set(unset_fields) == ( - set(("tlsRouteId",)) - & set( + set( ( - "parent", - "tlsRouteId", - "tlsRoute", + "pageSize", + "pageToken", + "returnPartialSuccess", ) ) + & set(("parent",)) ) -def test_create_tls_route_rest_flattened(): +def test_list_tcp_routes_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -31612,7 +32219,7 @@ def test_create_tls_route_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = tcp_route.ListTcpRoutesResponse() # get arguments that satisfy an http rule for this method sample_request = {"parent": "projects/sample1/locations/sample2"} @@ -31620,32 +32227,32 @@ def test_create_tls_route_rest_flattened(): # get truthy value for each flattened field mock_args = dict( parent="parent_value", - tls_route=gcn_tls_route.TlsRoute(name="name_value"), - tls_route_id="tls_route_id_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = tcp_route.ListTcpRoutesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_tls_route(**mock_args) + client.list_tcp_routes(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/tlsRoutes" % client.transport._host, + "%s/v1/{parent=projects/*/locations/*}/tcpRoutes" % client.transport._host, args[1], ) -def test_create_tls_route_rest_flattened_error(transport: str = "rest"): +def test_list_tcp_routes_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -31654,15 +32261,74 @@ def test_create_tls_route_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.create_tls_route( - gcn_tls_route.CreateTlsRouteRequest(), + client.list_tcp_routes( + tcp_route.ListTcpRoutesRequest(), parent="parent_value", - tls_route=gcn_tls_route.TlsRoute(name="name_value"), - tls_route_id="tls_route_id_value", ) -def test_update_tls_route_rest_use_cached_wrapped_rpc(): +def test_list_tcp_routes_rest_pager(transport: str = "rest"): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + tcp_route.ListTcpRoutesResponse( + tcp_routes=[ + tcp_route.TcpRoute(), + tcp_route.TcpRoute(), + tcp_route.TcpRoute(), + ], + next_page_token="abc", + ), + tcp_route.ListTcpRoutesResponse( + tcp_routes=[], + next_page_token="def", + ), + tcp_route.ListTcpRoutesResponse( + tcp_routes=[ + tcp_route.TcpRoute(), + ], + next_page_token="ghi", + ), + tcp_route.ListTcpRoutesResponse( + tcp_routes=[ + tcp_route.TcpRoute(), + tcp_route.TcpRoute(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(tcp_route.ListTcpRoutesResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_tcp_routes(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, tcp_route.TcpRoute) for i in results) + + pages = list(client.list_tcp_routes(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_get_tcp_route_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -31676,40 +32342,33 @@ def test_update_tls_route_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.update_tls_route in client._transport._wrapped_methods + assert client._transport.get_tcp_route in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.update_tls_route] = ( - mock_rpc - ) + client._transport._wrapped_methods[client._transport.get_tcp_route] = mock_rpc request = {} - client.update_tls_route(request) + client.get_tcp_route(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.update_tls_route(request) + client.get_tcp_route(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_update_tls_route_rest_required_fields( - request_type=gcn_tls_route.UpdateTlsRouteRequest, -): +def test_get_tcp_route_rest_required_fields(request_type=tcp_route.GetTcpRouteRequest): transport_class = transports.NetworkServicesRestTransport request_init = {} + request_init["name"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -31720,19 +32379,21 @@ def test_update_tls_route_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_tls_route._get_unset_required_fields(jsonified_request) + ).get_tcp_route._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present + jsonified_request["name"] = "name_value" + unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_tls_route._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("update_mask",)) + ).get_tcp_route._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -31741,7 +32402,7 @@ def test_update_tls_route_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = tcp_route.TcpRoute() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -31753,37 +32414,39 @@ def test_update_tls_route_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "patch", + "method": "get", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = tcp_route.TcpRoute.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_tls_route(request) + response = client.get_tcp_route(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_update_tls_route_rest_unset_required_fields(): +def test_get_tcp_route_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.update_tls_route._get_unset_required_fields({}) - assert set(unset_fields) == (set(("updateMask",)) & set(("tlsRoute",))) + unset_fields = transport.get_tcp_route._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) -def test_update_tls_route_rest_flattened(): +def test_get_tcp_route_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -31792,44 +32455,42 @@ def test_update_tls_route_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = tcp_route.TcpRoute() # get arguments that satisfy an http rule for this method sample_request = { - "tls_route": { - "name": "projects/sample1/locations/sample2/tlsRoutes/sample3" - } + "name": "projects/sample1/locations/sample2/tcpRoutes/sample3" } # get truthy value for each flattened field mock_args = dict( - tls_route=gcn_tls_route.TlsRoute(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + name="name_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = tcp_route.TcpRoute.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_tls_route(**mock_args) + client.get_tcp_route(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{tls_route.name=projects/*/locations/*/tlsRoutes/*}" - % client.transport._host, + "%s/v1/{name=projects/*/locations/*/tcpRoutes/*}" % client.transport._host, args[1], ) -def test_update_tls_route_rest_flattened_error(transport: str = "rest"): +def test_get_tcp_route_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -31838,14 +32499,13 @@ def test_update_tls_route_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.update_tls_route( - gcn_tls_route.UpdateTlsRouteRequest(), - tls_route=gcn_tls_route.TlsRoute(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + client.get_tcp_route( + tcp_route.GetTcpRouteRequest(), + name="name_value", ) -def test_delete_tls_route_rest_use_cached_wrapped_rpc(): +def test_create_tcp_route_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -31859,19 +32519,19 @@ def test_delete_tls_route_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.delete_tls_route in client._transport._wrapped_methods + assert client._transport.create_tcp_route in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.delete_tls_route] = ( + client._transport._wrapped_methods[client._transport.create_tcp_route] = ( mock_rpc ) request = {} - client.delete_tls_route(request) + client.create_tcp_route(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 @@ -31880,20 +32540,21 @@ def test_delete_tls_route_rest_use_cached_wrapped_rpc(): # subsequent calls should use the cached wrapper wrapper_fn.reset_mock() - client.delete_tls_route(request) + client.create_tcp_route(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_delete_tls_route_rest_required_fields( - request_type=tls_route.DeleteTlsRouteRequest, +def test_create_tcp_route_rest_required_fields( + request_type=gcn_tcp_route.CreateTcpRouteRequest, ): transport_class = transports.NetworkServicesRestTransport request_init = {} - request_init["name"] = "" + request_init["parent"] = "" + request_init["tcp_route_id"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -31901,24 +32562,32 @@ def test_delete_tls_route_rest_required_fields( ) # verify fields with default values are dropped + assert "tcpRouteId" not in jsonified_request unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_tls_route._get_unset_required_fields(jsonified_request) + ).create_tcp_route._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present + assert "tcpRouteId" in jsonified_request + assert jsonified_request["tcpRouteId"] == request_init["tcp_route_id"] - jsonified_request["name"] = "name_value" + jsonified_request["parent"] = "parent_value" + jsonified_request["tcpRouteId"] = "tcp_route_id_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_tls_route._get_unset_required_fields(jsonified_request) + ).create_tcp_route._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("tcp_route_id",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "tcpRouteId" in jsonified_request + assert jsonified_request["tcpRouteId"] == "tcp_route_id_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -31939,9 +32608,10 @@ def test_delete_tls_route_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "delete", + "method": "post", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() @@ -31952,23 +32622,38 @@ def test_delete_tls_route_rest_required_fields( req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_tls_route(request) + response = client.create_tcp_route(request) - expected_params = [("$alt", "json;enum-encoding=int")] + expected_params = [ + ( + "tcpRouteId", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_delete_tls_route_rest_unset_required_fields(): +def test_create_tcp_route_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.delete_tls_route._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + unset_fields = transport.create_tcp_route._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("tcpRouteId",)) + & set( + ( + "parent", + "tcpRouteId", + "tcpRoute", + ) + ) + ) -def test_delete_tls_route_rest_flattened(): +def test_create_tcp_route_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -31980,13 +32665,13 @@ def test_delete_tls_route_rest_flattened(): return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/tlsRoutes/sample3" - } + sample_request = {"parent": "projects/sample1/locations/sample2"} # get truthy value for each flattened field mock_args = dict( - name="name_value", + parent="parent_value", + tcp_route=gcn_tcp_route.TcpRoute(name="name_value"), + tcp_route_id="tcp_route_id_value", ) mock_args.update(sample_request) @@ -31998,19 +32683,19 @@ def test_delete_tls_route_rest_flattened(): req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_tls_route(**mock_args) + client.create_tcp_route(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/tlsRoutes/*}" % client.transport._host, + "%s/v1/{parent=projects/*/locations/*}/tcpRoutes" % client.transport._host, args[1], ) -def test_delete_tls_route_rest_flattened_error(transport: str = "rest"): +def test_create_tcp_route_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -32019,13 +32704,15 @@ def test_delete_tls_route_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.delete_tls_route( - tls_route.DeleteTlsRouteRequest(), - name="name_value", + client.create_tcp_route( + gcn_tcp_route.CreateTcpRouteRequest(), + parent="parent_value", + tcp_route=gcn_tcp_route.TcpRoute(name="name_value"), + tcp_route_id="tcp_route_id_value", ) -def test_list_service_bindings_rest_use_cached_wrapped_rpc(): +def test_update_tcp_route_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -32039,40 +32726,40 @@ def test_list_service_bindings_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert ( - client._transport.list_service_bindings - in client._transport._wrapped_methods - ) + assert client._transport.update_tcp_route in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.list_service_bindings] = ( + client._transport._wrapped_methods[client._transport.update_tcp_route] = ( mock_rpc ) request = {} - client.list_service_bindings(request) + client.update_tcp_route(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_service_bindings(request) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.update_tcp_route(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_service_bindings_rest_required_fields( - request_type=service_binding.ListServiceBindingsRequest, +def test_update_tcp_route_rest_required_fields( + request_type=gcn_tcp_route.UpdateTcpRouteRequest, ): transport_class = transports.NetworkServicesRestTransport request_init = {} - request_init["parent"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -32083,28 +32770,19 @@ def test_list_service_bindings_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_service_bindings._get_unset_required_fields(jsonified_request) + ).update_tcp_route._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["parent"] = "parent_value" - unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_service_bindings._get_unset_required_fields(jsonified_request) + ).update_tcp_route._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "page_size", - "page_token", - ) - ) + assert not set(unset_fields) - set(("update_mask",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -32113,7 +32791,7 @@ def test_list_service_bindings_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = service_binding.ListServiceBindingsResponse() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -32125,47 +32803,37 @@ def test_list_service_bindings_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "patch", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = service_binding.ListServiceBindingsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_service_bindings(request) + response = client.update_tcp_route(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_list_service_bindings_rest_unset_required_fields(): +def test_update_tcp_route_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.list_service_bindings._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "pageSize", - "pageToken", - ) - ) - & set(("parent",)) - ) + unset_fields = transport.update_tcp_route._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("tcpRoute",))) -def test_list_service_bindings_rest_flattened(): +def test_update_tcp_route_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -32174,41 +32842,44 @@ def test_list_service_bindings_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = service_binding.ListServiceBindingsResponse() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} + sample_request = { + "tcp_route": { + "name": "projects/sample1/locations/sample2/tcpRoutes/sample3" + } + } # get truthy value for each flattened field mock_args = dict( - parent="parent_value", + tcp_route=gcn_tcp_route.TcpRoute(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = service_binding.ListServiceBindingsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_service_bindings(**mock_args) + client.update_tcp_route(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/serviceBindings" + "%s/v1/{tcp_route.name=projects/*/locations/*/tcpRoutes/*}" % client.transport._host, args[1], ) -def test_list_service_bindings_rest_flattened_error(transport: str = "rest"): +def test_update_tcp_route_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -32217,76 +32888,14 @@ def test_list_service_bindings_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_service_bindings( - service_binding.ListServiceBindingsRequest(), - parent="parent_value", - ) - - -def test_list_service_bindings_rest_pager(transport: str = "rest"): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - service_binding.ListServiceBindingsResponse( - service_bindings=[ - service_binding.ServiceBinding(), - service_binding.ServiceBinding(), - service_binding.ServiceBinding(), - ], - next_page_token="abc", - ), - service_binding.ListServiceBindingsResponse( - service_bindings=[], - next_page_token="def", - ), - service_binding.ListServiceBindingsResponse( - service_bindings=[ - service_binding.ServiceBinding(), - ], - next_page_token="ghi", - ), - service_binding.ListServiceBindingsResponse( - service_bindings=[ - service_binding.ServiceBinding(), - service_binding.ServiceBinding(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple( - service_binding.ListServiceBindingsResponse.to_json(x) for x in response + client.update_tcp_route( + gcn_tcp_route.UpdateTcpRouteRequest(), + tcp_route=gcn_tcp_route.TcpRoute(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "projects/sample1/locations/sample2"} - - pager = client.list_service_bindings(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, service_binding.ServiceBinding) for i in results) - - pages = list(client.list_service_bindings(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token -def test_get_service_binding_rest_use_cached_wrapped_rpc(): +def test_delete_tcp_route_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -32300,34 +32909,36 @@ def test_get_service_binding_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert ( - client._transport.get_service_binding in client._transport._wrapped_methods - ) + assert client._transport.delete_tcp_route in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.get_service_binding] = ( + client._transport._wrapped_methods[client._transport.delete_tcp_route] = ( mock_rpc ) request = {} - client.get_service_binding(request) + client.delete_tcp_route(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.get_service_binding(request) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_tcp_route(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_get_service_binding_rest_required_fields( - request_type=service_binding.GetServiceBindingRequest, +def test_delete_tcp_route_rest_required_fields( + request_type=tcp_route.DeleteTcpRouteRequest, ): transport_class = transports.NetworkServicesRestTransport @@ -32343,7 +32954,7 @@ def test_get_service_binding_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_service_binding._get_unset_required_fields(jsonified_request) + ).delete_tcp_route._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -32352,7 +32963,7 @@ def test_get_service_binding_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_service_binding._get_unset_required_fields(jsonified_request) + ).delete_tcp_route._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -32366,7 +32977,7 @@ def test_get_service_binding_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = service_binding.ServiceBinding() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -32378,39 +32989,36 @@ def test_get_service_binding_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "delete", "query_params": pb_request, } transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = service_binding.ServiceBinding.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_service_binding(request) + response = client.delete_tcp_route(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_get_service_binding_rest_unset_required_fields(): +def test_delete_tcp_route_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.get_service_binding._get_unset_required_fields({}) + unset_fields = transport.delete_tcp_route._get_unset_required_fields({}) assert set(unset_fields) == (set(()) & set(("name",))) -def test_get_service_binding_rest_flattened(): +def test_delete_tcp_route_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -32419,11 +33027,11 @@ def test_get_service_binding_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = service_binding.ServiceBinding() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method sample_request = { - "name": "projects/sample1/locations/sample2/serviceBindings/sample3" + "name": "projects/sample1/locations/sample2/tcpRoutes/sample3" } # get truthy value for each flattened field @@ -32435,27 +33043,24 @@ def test_get_service_binding_rest_flattened(): # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = service_binding.ServiceBinding.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_service_binding(**mock_args) + client.delete_tcp_route(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/serviceBindings/*}" - % client.transport._host, + "%s/v1/{name=projects/*/locations/*/tcpRoutes/*}" % client.transport._host, args[1], ) -def test_get_service_binding_rest_flattened_error(transport: str = "rest"): +def test_delete_tcp_route_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -32464,13 +33069,13 @@ def test_get_service_binding_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.get_service_binding( - service_binding.GetServiceBindingRequest(), + client.delete_tcp_route( + tcp_route.DeleteTcpRouteRequest(), name="name_value", ) -def test_create_service_binding_rest_use_cached_wrapped_rpc(): +def test_list_tls_routes_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -32484,45 +33089,35 @@ def test_create_service_binding_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert ( - client._transport.create_service_binding - in client._transport._wrapped_methods - ) + assert client._transport.list_tls_routes in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.create_service_binding] = ( - mock_rpc - ) + client._transport._wrapped_methods[client._transport.list_tls_routes] = mock_rpc request = {} - client.create_service_binding(request) + client.list_tls_routes(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.create_service_binding(request) + client.list_tls_routes(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_create_service_binding_rest_required_fields( - request_type=gcn_service_binding.CreateServiceBindingRequest, +def test_list_tls_routes_rest_required_fields( + request_type=tls_route.ListTlsRoutesRequest, ): transport_class = transports.NetworkServicesRestTransport request_init = {} request_init["parent"] = "" - request_init["service_binding_id"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -32530,32 +33125,32 @@ def test_create_service_binding_rest_required_fields( ) # verify fields with default values are dropped - assert "serviceBindingId" not in jsonified_request unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_service_binding._get_unset_required_fields(jsonified_request) + ).list_tls_routes._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - assert "serviceBindingId" in jsonified_request - assert jsonified_request["serviceBindingId"] == request_init["service_binding_id"] jsonified_request["parent"] = "parent_value" - jsonified_request["serviceBindingId"] = "service_binding_id_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_service_binding._get_unset_required_fields(jsonified_request) + ).list_tls_routes._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("service_binding_id",)) + assert not set(unset_fields) - set( + ( + "page_size", + "page_token", + "return_partial_success", + ) + ) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone assert "parent" in jsonified_request assert jsonified_request["parent"] == "parent_value" - assert "serviceBindingId" in jsonified_request - assert jsonified_request["serviceBindingId"] == "service_binding_id_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -32564,7 +33159,7 @@ def test_create_service_binding_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = tls_route.ListTlsRoutesResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -32576,52 +33171,48 @@ def test_create_service_binding_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "post", + "method": "get", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = tls_route.ListTlsRoutesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_service_binding(request) + response = client.list_tls_routes(request) - expected_params = [ - ( - "serviceBindingId", - "", - ), - ("$alt", "json;enum-encoding=int"), - ] + expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_create_service_binding_rest_unset_required_fields(): +def test_list_tls_routes_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.create_service_binding._get_unset_required_fields({}) + unset_fields = transport.list_tls_routes._get_unset_required_fields({}) assert set(unset_fields) == ( - set(("serviceBindingId",)) - & set( + set( ( - "parent", - "serviceBindingId", - "serviceBinding", + "pageSize", + "pageToken", + "returnPartialSuccess", ) ) + & set(("parent",)) ) -def test_create_service_binding_rest_flattened(): +def test_list_tls_routes_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -32630,7 +33221,7 @@ def test_create_service_binding_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = tls_route.ListTlsRoutesResponse() # get arguments that satisfy an http rule for this method sample_request = {"parent": "projects/sample1/locations/sample2"} @@ -32638,33 +33229,32 @@ def test_create_service_binding_rest_flattened(): # get truthy value for each flattened field mock_args = dict( parent="parent_value", - service_binding=gcn_service_binding.ServiceBinding(name="name_value"), - service_binding_id="service_binding_id_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = tls_route.ListTlsRoutesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_service_binding(**mock_args) + client.list_tls_routes(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/serviceBindings" - % client.transport._host, + "%s/v1/{parent=projects/*/locations/*}/tlsRoutes" % client.transport._host, args[1], ) -def test_create_service_binding_rest_flattened_error(transport: str = "rest"): +def test_list_tls_routes_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -32673,15 +33263,74 @@ def test_create_service_binding_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.create_service_binding( - gcn_service_binding.CreateServiceBindingRequest(), + client.list_tls_routes( + tls_route.ListTlsRoutesRequest(), parent="parent_value", - service_binding=gcn_service_binding.ServiceBinding(name="name_value"), - service_binding_id="service_binding_id_value", ) -def test_update_service_binding_rest_use_cached_wrapped_rpc(): +def test_list_tls_routes_rest_pager(transport: str = "rest"): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + tls_route.ListTlsRoutesResponse( + tls_routes=[ + tls_route.TlsRoute(), + tls_route.TlsRoute(), + tls_route.TlsRoute(), + ], + next_page_token="abc", + ), + tls_route.ListTlsRoutesResponse( + tls_routes=[], + next_page_token="def", + ), + tls_route.ListTlsRoutesResponse( + tls_routes=[ + tls_route.TlsRoute(), + ], + next_page_token="ghi", + ), + tls_route.ListTlsRoutesResponse( + tls_routes=[ + tls_route.TlsRoute(), + tls_route.TlsRoute(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(tls_route.ListTlsRoutesResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_tls_routes(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, tls_route.TlsRoute) for i in results) + + pages = list(client.list_tls_routes(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_get_tls_route_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -32695,43 +33344,33 @@ def test_update_service_binding_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert ( - client._transport.update_service_binding - in client._transport._wrapped_methods - ) + assert client._transport.get_tls_route in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.update_service_binding] = ( - mock_rpc - ) + client._transport._wrapped_methods[client._transport.get_tls_route] = mock_rpc request = {} - client.update_service_binding(request) + client.get_tls_route(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.update_service_binding(request) + client.get_tls_route(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_update_service_binding_rest_required_fields( - request_type=gcn_service_binding.UpdateServiceBindingRequest, -): +def test_get_tls_route_rest_required_fields(request_type=tls_route.GetTlsRouteRequest): transport_class = transports.NetworkServicesRestTransport request_init = {} + request_init["name"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -32742,19 +33381,21 @@ def test_update_service_binding_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_service_binding._get_unset_required_fields(jsonified_request) + ).get_tls_route._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present + jsonified_request["name"] = "name_value" + unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_service_binding._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("update_mask",)) + ).get_tls_route._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -32763,7 +33404,7 @@ def test_update_service_binding_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = tls_route.TlsRoute() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -32775,37 +33416,39 @@ def test_update_service_binding_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "patch", + "method": "get", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = tls_route.TlsRoute.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_service_binding(request) + response = client.get_tls_route(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_update_service_binding_rest_unset_required_fields(): +def test_get_tls_route_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.update_service_binding._get_unset_required_fields({}) - assert set(unset_fields) == (set(("updateMask",)) & set(("serviceBinding",))) + unset_fields = transport.get_tls_route._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) -def test_update_service_binding_rest_flattened(): +def test_get_tls_route_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -32814,44 +33457,42 @@ def test_update_service_binding_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = tls_route.TlsRoute() # get arguments that satisfy an http rule for this method sample_request = { - "service_binding": { - "name": "projects/sample1/locations/sample2/serviceBindings/sample3" - } + "name": "projects/sample1/locations/sample2/tlsRoutes/sample3" } # get truthy value for each flattened field mock_args = dict( - service_binding=gcn_service_binding.ServiceBinding(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + name="name_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = tls_route.TlsRoute.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_service_binding(**mock_args) + client.get_tls_route(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{service_binding.name=projects/*/locations/*/serviceBindings/*}" - % client.transport._host, + "%s/v1/{name=projects/*/locations/*/tlsRoutes/*}" % client.transport._host, args[1], ) -def test_update_service_binding_rest_flattened_error(transport: str = "rest"): +def test_get_tls_route_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -32860,14 +33501,13 @@ def test_update_service_binding_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.update_service_binding( - gcn_service_binding.UpdateServiceBindingRequest(), - service_binding=gcn_service_binding.ServiceBinding(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + client.get_tls_route( + tls_route.GetTlsRouteRequest(), + name="name_value", ) -def test_delete_service_binding_rest_use_cached_wrapped_rpc(): +def test_create_tls_route_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -32881,22 +33521,19 @@ def test_delete_service_binding_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert ( - client._transport.delete_service_binding - in client._transport._wrapped_methods - ) + assert client._transport.create_tls_route in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.delete_service_binding] = ( + client._transport._wrapped_methods[client._transport.create_tls_route] = ( mock_rpc ) request = {} - client.delete_service_binding(request) + client.create_tls_route(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 @@ -32905,20 +33542,21 @@ def test_delete_service_binding_rest_use_cached_wrapped_rpc(): # subsequent calls should use the cached wrapper wrapper_fn.reset_mock() - client.delete_service_binding(request) + client.create_tls_route(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_delete_service_binding_rest_required_fields( - request_type=service_binding.DeleteServiceBindingRequest, +def test_create_tls_route_rest_required_fields( + request_type=gcn_tls_route.CreateTlsRouteRequest, ): transport_class = transports.NetworkServicesRestTransport request_init = {} - request_init["name"] = "" + request_init["parent"] = "" + request_init["tls_route_id"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -32926,24 +33564,32 @@ def test_delete_service_binding_rest_required_fields( ) # verify fields with default values are dropped + assert "tlsRouteId" not in jsonified_request unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_service_binding._get_unset_required_fields(jsonified_request) + ).create_tls_route._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present + assert "tlsRouteId" in jsonified_request + assert jsonified_request["tlsRouteId"] == request_init["tls_route_id"] - jsonified_request["name"] = "name_value" + jsonified_request["parent"] = "parent_value" + jsonified_request["tlsRouteId"] = "tls_route_id_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_service_binding._get_unset_required_fields(jsonified_request) + ).create_tls_route._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("tls_route_id",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "tlsRouteId" in jsonified_request + assert jsonified_request["tlsRouteId"] == "tls_route_id_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -32964,9 +33610,10 @@ def test_delete_service_binding_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "delete", + "method": "post", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() @@ -32977,23 +33624,38 @@ def test_delete_service_binding_rest_required_fields( req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_service_binding(request) + response = client.create_tls_route(request) - expected_params = [("$alt", "json;enum-encoding=int")] + expected_params = [ + ( + "tlsRouteId", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_delete_service_binding_rest_unset_required_fields(): +def test_create_tls_route_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.delete_service_binding._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + unset_fields = transport.create_tls_route._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("tlsRouteId",)) + & set( + ( + "parent", + "tlsRouteId", + "tlsRoute", + ) + ) + ) -def test_delete_service_binding_rest_flattened(): +def test_create_tls_route_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -33005,13 +33667,13 @@ def test_delete_service_binding_rest_flattened(): return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/serviceBindings/sample3" - } + sample_request = {"parent": "projects/sample1/locations/sample2"} # get truthy value for each flattened field mock_args = dict( - name="name_value", + parent="parent_value", + tls_route=gcn_tls_route.TlsRoute(name="name_value"), + tls_route_id="tls_route_id_value", ) mock_args.update(sample_request) @@ -33023,20 +33685,19 @@ def test_delete_service_binding_rest_flattened(): req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_service_binding(**mock_args) + client.create_tls_route(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/serviceBindings/*}" - % client.transport._host, + "%s/v1/{parent=projects/*/locations/*}/tlsRoutes" % client.transport._host, args[1], ) -def test_delete_service_binding_rest_flattened_error(transport: str = "rest"): +def test_create_tls_route_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -33045,13 +33706,15 @@ def test_delete_service_binding_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.delete_service_binding( - service_binding.DeleteServiceBindingRequest(), - name="name_value", + client.create_tls_route( + gcn_tls_route.CreateTlsRouteRequest(), + parent="parent_value", + tls_route=gcn_tls_route.TlsRoute(name="name_value"), + tls_route_id="tls_route_id_value", ) -def test_list_meshes_rest_use_cached_wrapped_rpc(): +def test_update_tls_route_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -33065,33 +33728,40 @@ def test_list_meshes_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.list_meshes in client._transport._wrapped_methods + assert client._transport.update_tls_route in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.list_meshes] = mock_rpc + client._transport._wrapped_methods[client._transport.update_tls_route] = ( + mock_rpc + ) request = {} - client.list_meshes(request) + client.update_tls_route(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_meshes(request) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.update_tls_route(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_meshes_rest_required_fields(request_type=mesh.ListMeshesRequest): +def test_update_tls_route_rest_required_fields( + request_type=gcn_tls_route.UpdateTlsRouteRequest, +): transport_class = transports.NetworkServicesRestTransport request_init = {} - request_init["parent"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -33102,29 +33772,19 @@ def test_list_meshes_rest_required_fields(request_type=mesh.ListMeshesRequest): unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_meshes._get_unset_required_fields(jsonified_request) + ).update_tls_route._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["parent"] = "parent_value" - unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_meshes._get_unset_required_fields(jsonified_request) + ).update_tls_route._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "page_size", - "page_token", - "return_partial_success", - ) - ) + assert not set(unset_fields) - set(("update_mask",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -33133,7 +33793,7 @@ def test_list_meshes_rest_required_fields(request_type=mesh.ListMeshesRequest): request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = mesh.ListMeshesResponse() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -33145,48 +33805,37 @@ def test_list_meshes_rest_required_fields(request_type=mesh.ListMeshesRequest): pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "patch", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = mesh.ListMeshesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_meshes(request) + response = client.update_tls_route(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_list_meshes_rest_unset_required_fields(): +def test_update_tls_route_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.list_meshes._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "pageSize", - "pageToken", - "returnPartialSuccess", - ) - ) - & set(("parent",)) - ) + unset_fields = transport.update_tls_route._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("tlsRoute",))) -def test_list_meshes_rest_flattened(): +def test_update_tls_route_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -33195,40 +33844,44 @@ def test_list_meshes_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = mesh.ListMeshesResponse() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} + sample_request = { + "tls_route": { + "name": "projects/sample1/locations/sample2/tlsRoutes/sample3" + } + } # get truthy value for each flattened field mock_args = dict( - parent="parent_value", + tls_route=gcn_tls_route.TlsRoute(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = mesh.ListMeshesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_meshes(**mock_args) + client.update_tls_route(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/meshes" % client.transport._host, + "%s/v1/{tls_route.name=projects/*/locations/*/tlsRoutes/*}" + % client.transport._host, args[1], ) -def test_list_meshes_rest_flattened_error(transport: str = "rest"): +def test_update_tls_route_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -33237,74 +33890,14 @@ def test_list_meshes_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_meshes( - mesh.ListMeshesRequest(), - parent="parent_value", - ) - - -def test_list_meshes_rest_pager(transport: str = "rest"): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - mesh.ListMeshesResponse( - meshes=[ - mesh.Mesh(), - mesh.Mesh(), - mesh.Mesh(), - ], - next_page_token="abc", - ), - mesh.ListMeshesResponse( - meshes=[], - next_page_token="def", - ), - mesh.ListMeshesResponse( - meshes=[ - mesh.Mesh(), - ], - next_page_token="ghi", - ), - mesh.ListMeshesResponse( - meshes=[ - mesh.Mesh(), - mesh.Mesh(), - ], - ), + client.update_tls_route( + gcn_tls_route.UpdateTlsRouteRequest(), + tls_route=gcn_tls_route.TlsRoute(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple(mesh.ListMeshesResponse.to_json(x) for x in response) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "projects/sample1/locations/sample2"} - - pager = client.list_meshes(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, mesh.Mesh) for i in results) - - pages = list(client.list_meshes(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token -def test_get_mesh_rest_use_cached_wrapped_rpc(): +def test_delete_tls_route_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -33318,29 +33911,37 @@ def test_get_mesh_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.get_mesh in client._transport._wrapped_methods + assert client._transport.delete_tls_route in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.get_mesh] = mock_rpc + client._transport._wrapped_methods[client._transport.delete_tls_route] = ( + mock_rpc + ) request = {} - client.get_mesh(request) + client.delete_tls_route(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.get_mesh(request) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_tls_route(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_get_mesh_rest_required_fields(request_type=mesh.GetMeshRequest): +def test_delete_tls_route_rest_required_fields( + request_type=tls_route.DeleteTlsRouteRequest, +): transport_class = transports.NetworkServicesRestTransport request_init = {} @@ -33355,7 +33956,7 @@ def test_get_mesh_rest_required_fields(request_type=mesh.GetMeshRequest): unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_mesh._get_unset_required_fields(jsonified_request) + ).delete_tls_route._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -33364,7 +33965,7 @@ def test_get_mesh_rest_required_fields(request_type=mesh.GetMeshRequest): unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_mesh._get_unset_required_fields(jsonified_request) + ).delete_tls_route._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -33378,7 +33979,7 @@ def test_get_mesh_rest_required_fields(request_type=mesh.GetMeshRequest): request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = mesh.Mesh() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -33390,39 +33991,36 @@ def test_get_mesh_rest_required_fields(request_type=mesh.GetMeshRequest): pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "delete", "query_params": pb_request, } transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = mesh.Mesh.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_mesh(request) + response = client.delete_tls_route(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_get_mesh_rest_unset_required_fields(): +def test_delete_tls_route_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.get_mesh._get_unset_required_fields({}) + unset_fields = transport.delete_tls_route._get_unset_required_fields({}) assert set(unset_fields) == (set(()) & set(("name",))) -def test_get_mesh_rest_flattened(): +def test_delete_tls_route_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -33431,10 +34029,12 @@ def test_get_mesh_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = mesh.Mesh() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = {"name": "projects/sample1/locations/sample2/meshes/sample3"} + sample_request = { + "name": "projects/sample1/locations/sample2/tlsRoutes/sample3" + } # get truthy value for each flattened field mock_args = dict( @@ -33445,26 +34045,24 @@ def test_get_mesh_rest_flattened(): # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = mesh.Mesh.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_mesh(**mock_args) + client.delete_tls_route(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/meshes/*}" % client.transport._host, + "%s/v1/{name=projects/*/locations/*/tlsRoutes/*}" % client.transport._host, args[1], ) -def test_get_mesh_rest_flattened_error(transport: str = "rest"): +def test_delete_tls_route_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -33473,13 +34071,13 @@ def test_get_mesh_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.get_mesh( - mesh.GetMeshRequest(), + client.delete_tls_route( + tls_route.DeleteTlsRouteRequest(), name="name_value", ) -def test_create_mesh_rest_use_cached_wrapped_rpc(): +def test_list_service_bindings_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -33493,38 +34091,40 @@ def test_create_mesh_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.create_mesh in client._transport._wrapped_methods + assert ( + client._transport.list_service_bindings + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.create_mesh] = mock_rpc + client._transport._wrapped_methods[client._transport.list_service_bindings] = ( + mock_rpc + ) request = {} - client.create_mesh(request) + client.list_service_bindings(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.create_mesh(request) + client.list_service_bindings(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_create_mesh_rest_required_fields(request_type=gcn_mesh.CreateMeshRequest): +def test_list_service_bindings_rest_required_fields( + request_type=service_binding.ListServiceBindingsRequest, +): transport_class = transports.NetworkServicesRestTransport request_init = {} request_init["parent"] = "" - request_init["mesh_id"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -33532,32 +34132,31 @@ def test_create_mesh_rest_required_fields(request_type=gcn_mesh.CreateMeshReques ) # verify fields with default values are dropped - assert "meshId" not in jsonified_request unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_mesh._get_unset_required_fields(jsonified_request) + ).list_service_bindings._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - assert "meshId" in jsonified_request - assert jsonified_request["meshId"] == request_init["mesh_id"] jsonified_request["parent"] = "parent_value" - jsonified_request["meshId"] = "mesh_id_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_mesh._get_unset_required_fields(jsonified_request) + ).list_service_bindings._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("mesh_id",)) + assert not set(unset_fields) - set( + ( + "page_size", + "page_token", + ) + ) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone assert "parent" in jsonified_request assert jsonified_request["parent"] == "parent_value" - assert "meshId" in jsonified_request - assert jsonified_request["meshId"] == "mesh_id_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -33566,7 +34165,7 @@ def test_create_mesh_rest_required_fields(request_type=gcn_mesh.CreateMeshReques request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = service_binding.ListServiceBindingsResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -33578,52 +34177,47 @@ def test_create_mesh_rest_required_fields(request_type=gcn_mesh.CreateMeshReques pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "post", + "method": "get", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = service_binding.ListServiceBindingsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_mesh(request) + response = client.list_service_bindings(request) - expected_params = [ - ( - "meshId", - "", - ), - ("$alt", "json;enum-encoding=int"), - ] + expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_create_mesh_rest_unset_required_fields(): +def test_list_service_bindings_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.create_mesh._get_unset_required_fields({}) + unset_fields = transport.list_service_bindings._get_unset_required_fields({}) assert set(unset_fields) == ( - set(("meshId",)) - & set( + set( ( - "parent", - "meshId", - "mesh", + "pageSize", + "pageToken", ) ) + & set(("parent",)) ) -def test_create_mesh_rest_flattened(): +def test_list_service_bindings_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -33632,7 +34226,7 @@ def test_create_mesh_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = service_binding.ListServiceBindingsResponse() # get arguments that satisfy an http rule for this method sample_request = {"parent": "projects/sample1/locations/sample2"} @@ -33640,32 +34234,33 @@ def test_create_mesh_rest_flattened(): # get truthy value for each flattened field mock_args = dict( parent="parent_value", - mesh=gcn_mesh.Mesh(name="name_value"), - mesh_id="mesh_id_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = service_binding.ListServiceBindingsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_mesh(**mock_args) + client.list_service_bindings(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/meshes" % client.transport._host, + "%s/v1/{parent=projects/*/locations/*}/serviceBindings" + % client.transport._host, args[1], ) -def test_create_mesh_rest_flattened_error(transport: str = "rest"): +def test_list_service_bindings_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -33674,15 +34269,76 @@ def test_create_mesh_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.create_mesh( - gcn_mesh.CreateMeshRequest(), + client.list_service_bindings( + service_binding.ListServiceBindingsRequest(), parent="parent_value", - mesh=gcn_mesh.Mesh(name="name_value"), - mesh_id="mesh_id_value", ) -def test_update_mesh_rest_use_cached_wrapped_rpc(): +def test_list_service_bindings_rest_pager(transport: str = "rest"): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + service_binding.ListServiceBindingsResponse( + service_bindings=[ + service_binding.ServiceBinding(), + service_binding.ServiceBinding(), + service_binding.ServiceBinding(), + ], + next_page_token="abc", + ), + service_binding.ListServiceBindingsResponse( + service_bindings=[], + next_page_token="def", + ), + service_binding.ListServiceBindingsResponse( + service_bindings=[ + service_binding.ServiceBinding(), + ], + next_page_token="ghi", + ), + service_binding.ListServiceBindingsResponse( + service_bindings=[ + service_binding.ServiceBinding(), + service_binding.ServiceBinding(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + service_binding.ListServiceBindingsResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_service_bindings(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, service_binding.ServiceBinding) for i in results) + + pages = list(client.list_service_bindings(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_get_service_binding_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -33696,36 +34352,39 @@ def test_update_mesh_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.update_mesh in client._transport._wrapped_methods + assert ( + client._transport.get_service_binding in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.update_mesh] = mock_rpc + client._transport._wrapped_methods[client._transport.get_service_binding] = ( + mock_rpc + ) request = {} - client.update_mesh(request) + client.get_service_binding(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.update_mesh(request) + client.get_service_binding(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_update_mesh_rest_required_fields(request_type=gcn_mesh.UpdateMeshRequest): +def test_get_service_binding_rest_required_fields( + request_type=service_binding.GetServiceBindingRequest, +): transport_class = transports.NetworkServicesRestTransport request_init = {} + request_init["name"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -33736,19 +34395,21 @@ def test_update_mesh_rest_required_fields(request_type=gcn_mesh.UpdateMeshReques unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_mesh._get_unset_required_fields(jsonified_request) + ).get_service_binding._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present + jsonified_request["name"] = "name_value" + unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_mesh._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("update_mask",)) + ).get_service_binding._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -33757,7 +34418,7 @@ def test_update_mesh_rest_required_fields(request_type=gcn_mesh.UpdateMeshReques request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = service_binding.ServiceBinding() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -33769,37 +34430,39 @@ def test_update_mesh_rest_required_fields(request_type=gcn_mesh.UpdateMeshReques pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "patch", + "method": "get", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = service_binding.ServiceBinding.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_mesh(request) + response = client.get_service_binding(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_update_mesh_rest_unset_required_fields(): +def test_get_service_binding_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.update_mesh._get_unset_required_fields({}) - assert set(unset_fields) == (set(("updateMask",)) & set(("mesh",))) + unset_fields = transport.get_service_binding._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) -def test_update_mesh_rest_flattened(): +def test_get_service_binding_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -33808,42 +34471,43 @@ def test_update_mesh_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = service_binding.ServiceBinding() # get arguments that satisfy an http rule for this method sample_request = { - "mesh": {"name": "projects/sample1/locations/sample2/meshes/sample3"} + "name": "projects/sample1/locations/sample2/serviceBindings/sample3" } # get truthy value for each flattened field mock_args = dict( - mesh=gcn_mesh.Mesh(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + name="name_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = service_binding.ServiceBinding.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_mesh(**mock_args) + client.get_service_binding(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{mesh.name=projects/*/locations/*/meshes/*}" + "%s/v1/{name=projects/*/locations/*/serviceBindings/*}" % client.transport._host, args[1], ) -def test_update_mesh_rest_flattened_error(transport: str = "rest"): +def test_get_service_binding_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -33852,14 +34516,13 @@ def test_update_mesh_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.update_mesh( - gcn_mesh.UpdateMeshRequest(), - mesh=gcn_mesh.Mesh(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + client.get_service_binding( + service_binding.GetServiceBindingRequest(), + name="name_value", ) -def test_delete_mesh_rest_use_cached_wrapped_rpc(): +def test_create_service_binding_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -33873,17 +34536,22 @@ def test_delete_mesh_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.delete_mesh in client._transport._wrapped_methods + assert ( + client._transport.create_service_binding + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.delete_mesh] = mock_rpc + client._transport._wrapped_methods[client._transport.create_service_binding] = ( + mock_rpc + ) request = {} - client.delete_mesh(request) + client.create_service_binding(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 @@ -33892,18 +34560,21 @@ def test_delete_mesh_rest_use_cached_wrapped_rpc(): # subsequent calls should use the cached wrapper wrapper_fn.reset_mock() - client.delete_mesh(request) + client.create_service_binding(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_delete_mesh_rest_required_fields(request_type=mesh.DeleteMeshRequest): +def test_create_service_binding_rest_required_fields( + request_type=gcn_service_binding.CreateServiceBindingRequest, +): transport_class = transports.NetworkServicesRestTransport request_init = {} - request_init["name"] = "" + request_init["parent"] = "" + request_init["service_binding_id"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -33911,24 +34582,32 @@ def test_delete_mesh_rest_required_fields(request_type=mesh.DeleteMeshRequest): ) # verify fields with default values are dropped + assert "serviceBindingId" not in jsonified_request unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_mesh._get_unset_required_fields(jsonified_request) + ).create_service_binding._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present + assert "serviceBindingId" in jsonified_request + assert jsonified_request["serviceBindingId"] == request_init["service_binding_id"] - jsonified_request["name"] = "name_value" + jsonified_request["parent"] = "parent_value" + jsonified_request["serviceBindingId"] = "service_binding_id_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_mesh._get_unset_required_fields(jsonified_request) + ).create_service_binding._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("service_binding_id",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "serviceBindingId" in jsonified_request + assert jsonified_request["serviceBindingId"] == "service_binding_id_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -33949,9 +34628,10 @@ def test_delete_mesh_rest_required_fields(request_type=mesh.DeleteMeshRequest): pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "delete", + "method": "post", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() @@ -33962,23 +34642,38 @@ def test_delete_mesh_rest_required_fields(request_type=mesh.DeleteMeshRequest): req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_mesh(request) + response = client.create_service_binding(request) - expected_params = [("$alt", "json;enum-encoding=int")] + expected_params = [ + ( + "serviceBindingId", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_delete_mesh_rest_unset_required_fields(): +def test_create_service_binding_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.delete_mesh._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + unset_fields = transport.create_service_binding._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("serviceBindingId",)) + & set( + ( + "parent", + "serviceBindingId", + "serviceBinding", + ) + ) + ) -def test_delete_mesh_rest_flattened(): +def test_create_service_binding_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -33990,11 +34685,13 @@ def test_delete_mesh_rest_flattened(): return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = {"name": "projects/sample1/locations/sample2/meshes/sample3"} + sample_request = {"parent": "projects/sample1/locations/sample2"} # get truthy value for each flattened field mock_args = dict( - name="name_value", + parent="parent_value", + service_binding=gcn_service_binding.ServiceBinding(name="name_value"), + service_binding_id="service_binding_id_value", ) mock_args.update(sample_request) @@ -34006,19 +34703,20 @@ def test_delete_mesh_rest_flattened(): req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_mesh(**mock_args) + client.create_service_binding(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/meshes/*}" % client.transport._host, + "%s/v1/{parent=projects/*/locations/*}/serviceBindings" + % client.transport._host, args[1], ) -def test_delete_mesh_rest_flattened_error(transport: str = "rest"): +def test_create_service_binding_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -34027,13 +34725,15 @@ def test_delete_mesh_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.delete_mesh( - mesh.DeleteMeshRequest(), - name="name_value", + client.create_service_binding( + gcn_service_binding.CreateServiceBindingRequest(), + parent="parent_value", + service_binding=gcn_service_binding.ServiceBinding(name="name_value"), + service_binding_id="service_binding_id_value", ) -def test_list_service_lb_policies_rest_use_cached_wrapped_rpc(): +def test_update_service_binding_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -34048,7 +34748,7 @@ def test_list_service_lb_policies_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.list_service_lb_policies + client._transport.update_service_binding in client._transport._wrapped_methods ) @@ -34057,30 +34757,33 @@ def test_list_service_lb_policies_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[ - client._transport.list_service_lb_policies - ] = mock_rpc + client._transport._wrapped_methods[client._transport.update_service_binding] = ( + mock_rpc + ) request = {} - client.list_service_lb_policies(request) + client.update_service_binding(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_service_lb_policies(request) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.update_service_binding(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_service_lb_policies_rest_required_fields( - request_type=service_lb_policy.ListServiceLbPoliciesRequest, +def test_update_service_binding_rest_required_fields( + request_type=gcn_service_binding.UpdateServiceBindingRequest, ): transport_class = transports.NetworkServicesRestTransport request_init = {} - request_init["parent"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -34091,28 +34794,19 @@ def test_list_service_lb_policies_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_service_lb_policies._get_unset_required_fields(jsonified_request) + ).update_service_binding._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["parent"] = "parent_value" - unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_service_lb_policies._get_unset_required_fields(jsonified_request) + ).update_service_binding._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "page_size", - "page_token", - ) - ) + assert not set(unset_fields) - set(("update_mask",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -34121,7 +34815,7 @@ def test_list_service_lb_policies_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = service_lb_policy.ListServiceLbPoliciesResponse() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -34133,49 +34827,37 @@ def test_list_service_lb_policies_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "patch", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = service_lb_policy.ListServiceLbPoliciesResponse.pb( - return_value - ) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_service_lb_policies(request) + response = client.update_service_binding(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_list_service_lb_policies_rest_unset_required_fields(): +def test_update_service_binding_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.list_service_lb_policies._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "pageSize", - "pageToken", - ) - ) - & set(("parent",)) - ) + unset_fields = transport.update_service_binding._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("serviceBinding",))) -def test_list_service_lb_policies_rest_flattened(): +def test_update_service_binding_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -34184,41 +34866,44 @@ def test_list_service_lb_policies_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = service_lb_policy.ListServiceLbPoliciesResponse() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} + sample_request = { + "service_binding": { + "name": "projects/sample1/locations/sample2/serviceBindings/sample3" + } + } # get truthy value for each flattened field mock_args = dict( - parent="parent_value", + service_binding=gcn_service_binding.ServiceBinding(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = service_lb_policy.ListServiceLbPoliciesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_service_lb_policies(**mock_args) + client.update_service_binding(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/serviceLbPolicies" + "%s/v1/{service_binding.name=projects/*/locations/*/serviceBindings/*}" % client.transport._host, args[1], ) -def test_list_service_lb_policies_rest_flattened_error(transport: str = "rest"): +def test_update_service_binding_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -34227,76 +34912,14 @@ def test_list_service_lb_policies_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_service_lb_policies( - service_lb_policy.ListServiceLbPoliciesRequest(), - parent="parent_value", - ) - - -def test_list_service_lb_policies_rest_pager(transport: str = "rest"): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - service_lb_policy.ListServiceLbPoliciesResponse( - service_lb_policies=[ - service_lb_policy.ServiceLbPolicy(), - service_lb_policy.ServiceLbPolicy(), - service_lb_policy.ServiceLbPolicy(), - ], - next_page_token="abc", - ), - service_lb_policy.ListServiceLbPoliciesResponse( - service_lb_policies=[], - next_page_token="def", - ), - service_lb_policy.ListServiceLbPoliciesResponse( - service_lb_policies=[ - service_lb_policy.ServiceLbPolicy(), - ], - next_page_token="ghi", - ), - service_lb_policy.ListServiceLbPoliciesResponse( - service_lb_policies=[ - service_lb_policy.ServiceLbPolicy(), - service_lb_policy.ServiceLbPolicy(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple( - service_lb_policy.ListServiceLbPoliciesResponse.to_json(x) for x in response + client.update_service_binding( + gcn_service_binding.UpdateServiceBindingRequest(), + service_binding=gcn_service_binding.ServiceBinding(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "projects/sample1/locations/sample2"} - - pager = client.list_service_lb_policies(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, service_lb_policy.ServiceLbPolicy) for i in results) - - pages = list(client.list_service_lb_policies(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token -def test_get_service_lb_policy_rest_use_cached_wrapped_rpc(): +def test_delete_service_binding_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -34311,7 +34934,7 @@ def test_get_service_lb_policy_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.get_service_lb_policy + client._transport.delete_service_binding in client._transport._wrapped_methods ) @@ -34320,25 +34943,29 @@ def test_get_service_lb_policy_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.get_service_lb_policy] = ( + client._transport._wrapped_methods[client._transport.delete_service_binding] = ( mock_rpc ) request = {} - client.get_service_lb_policy(request) + client.delete_service_binding(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.get_service_lb_policy(request) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_service_binding(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_get_service_lb_policy_rest_required_fields( - request_type=service_lb_policy.GetServiceLbPolicyRequest, +def test_delete_service_binding_rest_required_fields( + request_type=service_binding.DeleteServiceBindingRequest, ): transport_class = transports.NetworkServicesRestTransport @@ -34354,7 +34981,7 @@ def test_get_service_lb_policy_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_service_lb_policy._get_unset_required_fields(jsonified_request) + ).delete_service_binding._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -34363,7 +34990,7 @@ def test_get_service_lb_policy_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_service_lb_policy._get_unset_required_fields(jsonified_request) + ).delete_service_binding._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -34377,7 +35004,7 @@ def test_get_service_lb_policy_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = service_lb_policy.ServiceLbPolicy() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -34389,39 +35016,36 @@ def test_get_service_lb_policy_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "delete", "query_params": pb_request, } transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = service_lb_policy.ServiceLbPolicy.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_service_lb_policy(request) + response = client.delete_service_binding(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_get_service_lb_policy_rest_unset_required_fields(): +def test_delete_service_binding_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.get_service_lb_policy._get_unset_required_fields({}) + unset_fields = transport.delete_service_binding._get_unset_required_fields({}) assert set(unset_fields) == (set(()) & set(("name",))) -def test_get_service_lb_policy_rest_flattened(): +def test_delete_service_binding_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -34430,11 +35054,11 @@ def test_get_service_lb_policy_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = service_lb_policy.ServiceLbPolicy() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method sample_request = { - "name": "projects/sample1/locations/sample2/serviceLbPolicies/sample3" + "name": "projects/sample1/locations/sample2/serviceBindings/sample3" } # get truthy value for each flattened field @@ -34446,27 +35070,25 @@ def test_get_service_lb_policy_rest_flattened(): # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = service_lb_policy.ServiceLbPolicy.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_service_lb_policy(**mock_args) + client.delete_service_binding(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/serviceLbPolicies/*}" + "%s/v1/{name=projects/*/locations/*/serviceBindings/*}" % client.transport._host, args[1], ) -def test_get_service_lb_policy_rest_flattened_error(transport: str = "rest"): +def test_delete_service_binding_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -34475,13 +35097,13 @@ def test_get_service_lb_policy_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.get_service_lb_policy( - service_lb_policy.GetServiceLbPolicyRequest(), + client.delete_service_binding( + service_binding.DeleteServiceBindingRequest(), name="name_value", ) -def test_create_service_lb_policy_rest_use_cached_wrapped_rpc(): +def test_list_meshes_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -34495,45 +35117,33 @@ def test_create_service_lb_policy_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert ( - client._transport.create_service_lb_policy - in client._transport._wrapped_methods - ) + assert client._transport.list_meshes in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[ - client._transport.create_service_lb_policy - ] = mock_rpc + client._transport._wrapped_methods[client._transport.list_meshes] = mock_rpc request = {} - client.create_service_lb_policy(request) + client.list_meshes(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.create_service_lb_policy(request) + client.list_meshes(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_create_service_lb_policy_rest_required_fields( - request_type=gcn_service_lb_policy.CreateServiceLbPolicyRequest, -): +def test_list_meshes_rest_required_fields(request_type=mesh.ListMeshesRequest): transport_class = transports.NetworkServicesRestTransport request_init = {} request_init["parent"] = "" - request_init["service_lb_policy_id"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -34541,34 +35151,32 @@ def test_create_service_lb_policy_rest_required_fields( ) # verify fields with default values are dropped - assert "serviceLbPolicyId" not in jsonified_request unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_service_lb_policy._get_unset_required_fields(jsonified_request) + ).list_meshes._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - assert "serviceLbPolicyId" in jsonified_request - assert ( - jsonified_request["serviceLbPolicyId"] == request_init["service_lb_policy_id"] - ) jsonified_request["parent"] = "parent_value" - jsonified_request["serviceLbPolicyId"] = "service_lb_policy_id_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_service_lb_policy._get_unset_required_fields(jsonified_request) + ).list_meshes._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("service_lb_policy_id",)) + assert not set(unset_fields) - set( + ( + "page_size", + "page_token", + "return_partial_success", + ) + ) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone assert "parent" in jsonified_request assert jsonified_request["parent"] == "parent_value" - assert "serviceLbPolicyId" in jsonified_request - assert jsonified_request["serviceLbPolicyId"] == "service_lb_policy_id_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -34577,7 +35185,7 @@ def test_create_service_lb_policy_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = mesh.ListMeshesResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -34589,52 +35197,48 @@ def test_create_service_lb_policy_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "post", + "method": "get", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = mesh.ListMeshesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_service_lb_policy(request) + response = client.list_meshes(request) - expected_params = [ - ( - "serviceLbPolicyId", - "", - ), - ("$alt", "json;enum-encoding=int"), - ] + expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_create_service_lb_policy_rest_unset_required_fields(): +def test_list_meshes_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.create_service_lb_policy._get_unset_required_fields({}) + unset_fields = transport.list_meshes._get_unset_required_fields({}) assert set(unset_fields) == ( - set(("serviceLbPolicyId",)) - & set( + set( ( - "parent", - "serviceLbPolicyId", - "serviceLbPolicy", + "pageSize", + "pageToken", + "returnPartialSuccess", ) ) + & set(("parent",)) ) -def test_create_service_lb_policy_rest_flattened(): +def test_list_meshes_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -34643,7 +35247,7 @@ def test_create_service_lb_policy_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = mesh.ListMeshesResponse() # get arguments that satisfy an http rule for this method sample_request = {"parent": "projects/sample1/locations/sample2"} @@ -34651,33 +35255,32 @@ def test_create_service_lb_policy_rest_flattened(): # get truthy value for each flattened field mock_args = dict( parent="parent_value", - service_lb_policy=gcn_service_lb_policy.ServiceLbPolicy(name="name_value"), - service_lb_policy_id="service_lb_policy_id_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = mesh.ListMeshesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_service_lb_policy(**mock_args) + client.list_meshes(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*}/serviceLbPolicies" - % client.transport._host, + "%s/v1/{parent=projects/*/locations/*}/meshes" % client.transport._host, args[1], ) -def test_create_service_lb_policy_rest_flattened_error(transport: str = "rest"): +def test_list_meshes_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -34686,15 +35289,74 @@ def test_create_service_lb_policy_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.create_service_lb_policy( - gcn_service_lb_policy.CreateServiceLbPolicyRequest(), + client.list_meshes( + mesh.ListMeshesRequest(), parent="parent_value", - service_lb_policy=gcn_service_lb_policy.ServiceLbPolicy(name="name_value"), - service_lb_policy_id="service_lb_policy_id_value", ) -def test_update_service_lb_policy_rest_use_cached_wrapped_rpc(): +def test_list_meshes_rest_pager(transport: str = "rest"): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + mesh.ListMeshesResponse( + meshes=[ + mesh.Mesh(), + mesh.Mesh(), + mesh.Mesh(), + ], + next_page_token="abc", + ), + mesh.ListMeshesResponse( + meshes=[], + next_page_token="def", + ), + mesh.ListMeshesResponse( + meshes=[ + mesh.Mesh(), + ], + next_page_token="ghi", + ), + mesh.ListMeshesResponse( + meshes=[ + mesh.Mesh(), + mesh.Mesh(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(mesh.ListMeshesResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_meshes(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, mesh.Mesh) for i in results) + + pages = list(client.list_meshes(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_get_mesh_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -34708,43 +35370,33 @@ def test_update_service_lb_policy_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert ( - client._transport.update_service_lb_policy - in client._transport._wrapped_methods - ) + assert client._transport.get_mesh in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[ - client._transport.update_service_lb_policy - ] = mock_rpc + client._transport._wrapped_methods[client._transport.get_mesh] = mock_rpc request = {} - client.update_service_lb_policy(request) + client.get_mesh(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - # Operation methods build a cached wrapper on first rpc call - # subsequent calls should use the cached wrapper - wrapper_fn.reset_mock() - - client.update_service_lb_policy(request) + client.get_mesh(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_update_service_lb_policy_rest_required_fields( - request_type=gcn_service_lb_policy.UpdateServiceLbPolicyRequest, -): +def test_get_mesh_rest_required_fields(request_type=mesh.GetMeshRequest): transport_class = transports.NetworkServicesRestTransport request_init = {} + request_init["name"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -34755,19 +35407,21 @@ def test_update_service_lb_policy_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_service_lb_policy._get_unset_required_fields(jsonified_request) + ).get_mesh._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present + jsonified_request["name"] = "name_value" + unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_service_lb_policy._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("update_mask",)) + ).get_mesh._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -34776,7 +35430,7 @@ def test_update_service_lb_policy_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = mesh.Mesh() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -34788,37 +35442,39 @@ def test_update_service_lb_policy_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "patch", + "method": "get", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = mesh.Mesh.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_service_lb_policy(request) + response = client.get_mesh(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_update_service_lb_policy_rest_unset_required_fields(): +def test_get_mesh_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.update_service_lb_policy._get_unset_required_fields({}) - assert set(unset_fields) == (set(("updateMask",)) & set(("serviceLbPolicy",))) + unset_fields = transport.get_mesh._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) -def test_update_service_lb_policy_rest_flattened(): +def test_get_mesh_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -34827,44 +35483,40 @@ def test_update_service_lb_policy_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = mesh.Mesh() # get arguments that satisfy an http rule for this method - sample_request = { - "service_lb_policy": { - "name": "projects/sample1/locations/sample2/serviceLbPolicies/sample3" - } - } + sample_request = {"name": "projects/sample1/locations/sample2/meshes/sample3"} # get truthy value for each flattened field mock_args = dict( - service_lb_policy=gcn_service_lb_policy.ServiceLbPolicy(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + name="name_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = mesh.Mesh.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_service_lb_policy(**mock_args) + client.get_mesh(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{service_lb_policy.name=projects/*/locations/*/serviceLbPolicies/*}" - % client.transport._host, + "%s/v1/{name=projects/*/locations/*/meshes/*}" % client.transport._host, args[1], ) -def test_update_service_lb_policy_rest_flattened_error(transport: str = "rest"): +def test_get_mesh_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -34873,14 +35525,13 @@ def test_update_service_lb_policy_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.update_service_lb_policy( - gcn_service_lb_policy.UpdateServiceLbPolicyRequest(), - service_lb_policy=gcn_service_lb_policy.ServiceLbPolicy(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + client.get_mesh( + mesh.GetMeshRequest(), + name="name_value", ) -def test_delete_service_lb_policy_rest_use_cached_wrapped_rpc(): +def test_create_mesh_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -34894,22 +35545,17 @@ def test_delete_service_lb_policy_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert ( - client._transport.delete_service_lb_policy - in client._transport._wrapped_methods - ) + assert client._transport.create_mesh in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[ - client._transport.delete_service_lb_policy - ] = mock_rpc + client._transport._wrapped_methods[client._transport.create_mesh] = mock_rpc request = {} - client.delete_service_lb_policy(request) + client.create_mesh(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 @@ -34918,20 +35564,19 @@ def test_delete_service_lb_policy_rest_use_cached_wrapped_rpc(): # subsequent calls should use the cached wrapper wrapper_fn.reset_mock() - client.delete_service_lb_policy(request) + client.create_mesh(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_delete_service_lb_policy_rest_required_fields( - request_type=service_lb_policy.DeleteServiceLbPolicyRequest, -): +def test_create_mesh_rest_required_fields(request_type=gcn_mesh.CreateMeshRequest): transport_class = transports.NetworkServicesRestTransport request_init = {} - request_init["name"] = "" + request_init["parent"] = "" + request_init["mesh_id"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -34939,24 +35584,32 @@ def test_delete_service_lb_policy_rest_required_fields( ) # verify fields with default values are dropped + assert "meshId" not in jsonified_request unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_service_lb_policy._get_unset_required_fields(jsonified_request) + ).create_mesh._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present + assert "meshId" in jsonified_request + assert jsonified_request["meshId"] == request_init["mesh_id"] - jsonified_request["name"] = "name_value" + jsonified_request["parent"] = "parent_value" + jsonified_request["meshId"] = "mesh_id_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_service_lb_policy._get_unset_required_fields(jsonified_request) + ).create_mesh._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("mesh_id",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "meshId" in jsonified_request + assert jsonified_request["meshId"] == "mesh_id_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -34977,9 +35630,10 @@ def test_delete_service_lb_policy_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "delete", + "method": "post", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() @@ -34990,23 +35644,38 @@ def test_delete_service_lb_policy_rest_required_fields( req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_service_lb_policy(request) + response = client.create_mesh(request) - expected_params = [("$alt", "json;enum-encoding=int")] + expected_params = [ + ( + "meshId", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_delete_service_lb_policy_rest_unset_required_fields(): +def test_create_mesh_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.delete_service_lb_policy._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + unset_fields = transport.create_mesh._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("meshId",)) + & set( + ( + "parent", + "meshId", + "mesh", + ) + ) + ) -def test_delete_service_lb_policy_rest_flattened(): +def test_create_mesh_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -35018,13 +35687,13 @@ def test_delete_service_lb_policy_rest_flattened(): return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/serviceLbPolicies/sample3" - } + sample_request = {"parent": "projects/sample1/locations/sample2"} # get truthy value for each flattened field mock_args = dict( - name="name_value", + parent="parent_value", + mesh=gcn_mesh.Mesh(name="name_value"), + mesh_id="mesh_id_value", ) mock_args.update(sample_request) @@ -35036,20 +35705,19 @@ def test_delete_service_lb_policy_rest_flattened(): req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_service_lb_policy(**mock_args) + client.create_mesh(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/serviceLbPolicies/*}" - % client.transport._host, + "%s/v1/{parent=projects/*/locations/*}/meshes" % client.transport._host, args[1], ) -def test_delete_service_lb_policy_rest_flattened_error(transport: str = "rest"): +def test_create_mesh_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -35058,13 +35726,15 @@ def test_delete_service_lb_policy_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.delete_service_lb_policy( - service_lb_policy.DeleteServiceLbPolicyRequest(), - name="name_value", + client.create_mesh( + gcn_mesh.CreateMeshRequest(), + parent="parent_value", + mesh=gcn_mesh.Mesh(name="name_value"), + mesh_id="mesh_id_value", ) -def test_get_gateway_route_view_rest_use_cached_wrapped_rpc(): +def test_update_mesh_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -35078,40 +35748,36 @@ def test_get_gateway_route_view_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert ( - client._transport.get_gateway_route_view - in client._transport._wrapped_methods - ) + assert client._transport.update_mesh in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.get_gateway_route_view] = ( - mock_rpc - ) + client._transport._wrapped_methods[client._transport.update_mesh] = mock_rpc request = {} - client.get_gateway_route_view(request) + client.update_mesh(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.get_gateway_route_view(request) - - # Establish that a new wrapper was not created for this call + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.update_mesh(request) + + # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_get_gateway_route_view_rest_required_fields( - request_type=route_view.GetGatewayRouteViewRequest, -): +def test_update_mesh_rest_required_fields(request_type=gcn_mesh.UpdateMeshRequest): transport_class = transports.NetworkServicesRestTransport request_init = {} - request_init["name"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -35122,21 +35788,19 @@ def test_get_gateway_route_view_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_gateway_route_view._get_unset_required_fields(jsonified_request) + ).update_mesh._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["name"] = "name_value" - unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_gateway_route_view._get_unset_required_fields(jsonified_request) + ).update_mesh._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -35145,7 +35809,7 @@ def test_get_gateway_route_view_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = route_view.GatewayRouteView() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -35157,39 +35821,37 @@ def test_get_gateway_route_view_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "patch", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = route_view.GatewayRouteView.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_gateway_route_view(request) + response = client.update_mesh(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_get_gateway_route_view_rest_unset_required_fields(): +def test_update_mesh_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.get_gateway_route_view._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + unset_fields = transport.update_mesh._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("mesh",))) -def test_get_gateway_route_view_rest_flattened(): +def test_update_mesh_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -35198,43 +35860,42 @@ def test_get_gateway_route_view_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = route_view.GatewayRouteView() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method sample_request = { - "name": "projects/sample1/locations/sample2/gateways/sample3/routeViews/sample4" + "mesh": {"name": "projects/sample1/locations/sample2/meshes/sample3"} } # get truthy value for each flattened field mock_args = dict( - name="name_value", + mesh=gcn_mesh.Mesh(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = route_view.GatewayRouteView.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_gateway_route_view(**mock_args) + client.update_mesh(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/gateways/*/routeViews/*}" + "%s/v1/{mesh.name=projects/*/locations/*/meshes/*}" % client.transport._host, args[1], ) -def test_get_gateway_route_view_rest_flattened_error(transport: str = "rest"): +def test_update_mesh_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -35243,13 +35904,14 @@ def test_get_gateway_route_view_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.get_gateway_route_view( - route_view.GetGatewayRouteViewRequest(), - name="name_value", + client.update_mesh( + gcn_mesh.UpdateMeshRequest(), + mesh=gcn_mesh.Mesh(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) -def test_get_mesh_route_view_rest_use_cached_wrapped_rpc(): +def test_delete_mesh_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -35263,35 +35925,33 @@ def test_get_mesh_route_view_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert ( - client._transport.get_mesh_route_view in client._transport._wrapped_methods - ) + assert client._transport.delete_mesh in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.get_mesh_route_view] = ( - mock_rpc - ) + client._transport._wrapped_methods[client._transport.delete_mesh] = mock_rpc request = {} - client.get_mesh_route_view(request) + client.delete_mesh(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.get_mesh_route_view(request) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_mesh(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_get_mesh_route_view_rest_required_fields( - request_type=route_view.GetMeshRouteViewRequest, -): +def test_delete_mesh_rest_required_fields(request_type=mesh.DeleteMeshRequest): transport_class = transports.NetworkServicesRestTransport request_init = {} @@ -35306,7 +35966,7 @@ def test_get_mesh_route_view_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_mesh_route_view._get_unset_required_fields(jsonified_request) + ).delete_mesh._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -35315,7 +35975,7 @@ def test_get_mesh_route_view_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_mesh_route_view._get_unset_required_fields(jsonified_request) + ).delete_mesh._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -35329,7 +35989,7 @@ def test_get_mesh_route_view_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = route_view.MeshRouteView() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -35341,39 +36001,36 @@ def test_get_mesh_route_view_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "delete", "query_params": pb_request, } transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = route_view.MeshRouteView.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_mesh_route_view(request) + response = client.delete_mesh(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_get_mesh_route_view_rest_unset_required_fields(): +def test_delete_mesh_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.get_mesh_route_view._get_unset_required_fields({}) + unset_fields = transport.delete_mesh._get_unset_required_fields({}) assert set(unset_fields) == (set(()) & set(("name",))) -def test_get_mesh_route_view_rest_flattened(): +def test_delete_mesh_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -35382,12 +36039,10 @@ def test_get_mesh_route_view_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = route_view.MeshRouteView() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/meshes/sample3/routeViews/sample4" - } + sample_request = {"name": "projects/sample1/locations/sample2/meshes/sample3"} # get truthy value for each flattened field mock_args = dict( @@ -35398,27 +36053,24 @@ def test_get_mesh_route_view_rest_flattened(): # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = route_view.MeshRouteView.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_mesh_route_view(**mock_args) + client.delete_mesh(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/meshes/*/routeViews/*}" - % client.transport._host, + "%s/v1/{name=projects/*/locations/*/meshes/*}" % client.transport._host, args[1], ) -def test_get_mesh_route_view_rest_flattened_error(transport: str = "rest"): +def test_delete_mesh_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -35427,13 +36079,13 @@ def test_get_mesh_route_view_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.get_mesh_route_view( - route_view.GetMeshRouteViewRequest(), + client.delete_mesh( + mesh.DeleteMeshRequest(), name="name_value", ) -def test_list_gateway_route_views_rest_use_cached_wrapped_rpc(): +def test_list_service_lb_policies_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -35448,7 +36100,7 @@ def test_list_gateway_route_views_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.list_gateway_route_views + client._transport.list_service_lb_policies in client._transport._wrapped_methods ) @@ -35458,24 +36110,24 @@ def test_list_gateway_route_views_rest_use_cached_wrapped_rpc(): "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ - client._transport.list_gateway_route_views + client._transport.list_service_lb_policies ] = mock_rpc request = {} - client.list_gateway_route_views(request) + client.list_service_lb_policies(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_gateway_route_views(request) + client.list_service_lb_policies(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_gateway_route_views_rest_required_fields( - request_type=route_view.ListGatewayRouteViewsRequest, +def test_list_service_lb_policies_rest_required_fields( + request_type=service_lb_policy.ListServiceLbPoliciesRequest, ): transport_class = transports.NetworkServicesRestTransport @@ -35491,7 +36143,7 @@ def test_list_gateway_route_views_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_gateway_route_views._get_unset_required_fields(jsonified_request) + ).list_service_lb_policies._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -35500,7 +36152,7 @@ def test_list_gateway_route_views_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_gateway_route_views._get_unset_required_fields(jsonified_request) + ).list_service_lb_policies._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. assert not set(unset_fields) - set( ( @@ -35521,7 +36173,7 @@ def test_list_gateway_route_views_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = route_view.ListGatewayRouteViewsResponse() + return_value = service_lb_policy.ListServiceLbPoliciesResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -35542,26 +36194,28 @@ def test_list_gateway_route_views_rest_required_fields( response_value.status_code = 200 # Convert return value to protobuf type - return_value = route_view.ListGatewayRouteViewsResponse.pb(return_value) + return_value = service_lb_policy.ListServiceLbPoliciesResponse.pb( + return_value + ) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_gateway_route_views(request) + response = client.list_service_lb_policies(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_list_gateway_route_views_rest_unset_required_fields(): +def test_list_service_lb_policies_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.list_gateway_route_views._get_unset_required_fields({}) + unset_fields = transport.list_service_lb_policies._get_unset_required_fields({}) assert set(unset_fields) == ( set( ( @@ -35573,7 +36227,7 @@ def test_list_gateway_route_views_rest_unset_required_fields(): ) -def test_list_gateway_route_views_rest_flattened(): +def test_list_service_lb_policies_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -35582,12 +36236,10 @@ def test_list_gateway_route_views_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = route_view.ListGatewayRouteViewsResponse() + return_value = service_lb_policy.ListServiceLbPoliciesResponse() # get arguments that satisfy an http rule for this method - sample_request = { - "parent": "projects/sample1/locations/sample2/gateways/sample3" - } + sample_request = {"parent": "projects/sample1/locations/sample2"} # get truthy value for each flattened field mock_args = dict( @@ -35599,26 +36251,26 @@ def test_list_gateway_route_views_rest_flattened(): response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = route_view.ListGatewayRouteViewsResponse.pb(return_value) + return_value = service_lb_policy.ListServiceLbPoliciesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_gateway_route_views(**mock_args) + client.list_service_lb_policies(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*/gateways/*}/routeViews" + "%s/v1/{parent=projects/*/locations/*}/serviceLbPolicies" % client.transport._host, args[1], ) -def test_list_gateway_route_views_rest_flattened_error(transport: str = "rest"): +def test_list_service_lb_policies_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -35627,13 +36279,13 @@ def test_list_gateway_route_views_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_gateway_route_views( - route_view.ListGatewayRouteViewsRequest(), + client.list_service_lb_policies( + service_lb_policy.ListServiceLbPoliciesRequest(), parent="parent_value", ) -def test_list_gateway_route_views_rest_pager(transport: str = "rest"): +def test_list_service_lb_policies_rest_pager(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -35645,28 +36297,28 @@ def test_list_gateway_route_views_rest_pager(transport: str = "rest"): # with mock.patch.object(path_template, 'transcode') as transcode: # Set the response as a series of pages response = ( - route_view.ListGatewayRouteViewsResponse( - gateway_route_views=[ - route_view.GatewayRouteView(), - route_view.GatewayRouteView(), - route_view.GatewayRouteView(), + service_lb_policy.ListServiceLbPoliciesResponse( + service_lb_policies=[ + service_lb_policy.ServiceLbPolicy(), + service_lb_policy.ServiceLbPolicy(), + service_lb_policy.ServiceLbPolicy(), ], next_page_token="abc", ), - route_view.ListGatewayRouteViewsResponse( - gateway_route_views=[], + service_lb_policy.ListServiceLbPoliciesResponse( + service_lb_policies=[], next_page_token="def", ), - route_view.ListGatewayRouteViewsResponse( - gateway_route_views=[ - route_view.GatewayRouteView(), + service_lb_policy.ListServiceLbPoliciesResponse( + service_lb_policies=[ + service_lb_policy.ServiceLbPolicy(), ], next_page_token="ghi", ), - route_view.ListGatewayRouteViewsResponse( - gateway_route_views=[ - route_view.GatewayRouteView(), - route_view.GatewayRouteView(), + service_lb_policy.ListServiceLbPoliciesResponse( + service_lb_policies=[ + service_lb_policy.ServiceLbPolicy(), + service_lb_policy.ServiceLbPolicy(), ], ), ) @@ -35675,7 +36327,7 @@ def test_list_gateway_route_views_rest_pager(transport: str = "rest"): # Wrap the values into proper Response objs response = tuple( - route_view.ListGatewayRouteViewsResponse.to_json(x) for x in response + service_lb_policy.ListServiceLbPoliciesResponse.to_json(x) for x in response ) return_values = tuple(Response() for i in response) for return_val, response_val in zip(return_values, response): @@ -35683,22 +36335,20 @@ def test_list_gateway_route_views_rest_pager(transport: str = "rest"): return_val.status_code = 200 req.side_effect = return_values - sample_request = { - "parent": "projects/sample1/locations/sample2/gateways/sample3" - } + sample_request = {"parent": "projects/sample1/locations/sample2"} - pager = client.list_gateway_route_views(request=sample_request) + pager = client.list_service_lb_policies(request=sample_request) results = list(pager) assert len(results) == 6 - assert all(isinstance(i, route_view.GatewayRouteView) for i in results) + assert all(isinstance(i, service_lb_policy.ServiceLbPolicy) for i in results) - pages = list(client.list_gateway_route_views(request=sample_request).pages) + pages = list(client.list_service_lb_policies(request=sample_request).pages) for page_, token in zip(pages, ["abc", "def", "ghi", ""]): assert page_.raw_page.next_page_token == token -def test_list_mesh_route_views_rest_use_cached_wrapped_rpc(): +def test_get_service_lb_policy_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -35713,7 +36363,7 @@ def test_list_mesh_route_views_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.list_mesh_route_views + client._transport.get_service_lb_policy in client._transport._wrapped_methods ) @@ -35722,30 +36372,30 @@ def test_list_mesh_route_views_rest_use_cached_wrapped_rpc(): mock_rpc.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client._transport._wrapped_methods[client._transport.list_mesh_route_views] = ( + client._transport._wrapped_methods[client._transport.get_service_lb_policy] = ( mock_rpc ) request = {} - client.list_mesh_route_views(request) + client.get_service_lb_policy(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.list_mesh_route_views(request) + client.get_service_lb_policy(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_list_mesh_route_views_rest_required_fields( - request_type=route_view.ListMeshRouteViewsRequest, +def test_get_service_lb_policy_rest_required_fields( + request_type=service_lb_policy.GetServiceLbPolicyRequest, ): transport_class = transports.NetworkServicesRestTransport request_init = {} - request_init["parent"] = "" + request_init["name"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -35756,28 +36406,21 @@ def test_list_mesh_route_views_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_mesh_route_views._get_unset_required_fields(jsonified_request) + ).get_service_lb_policy._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["parent"] = "parent_value" + jsonified_request["name"] = "name_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_mesh_route_views._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "page_size", - "page_token", - ) - ) + ).get_service_lb_policy._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -35786,7 +36429,7 @@ def test_list_mesh_route_views_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = route_view.ListMeshRouteViewsResponse() + return_value = service_lb_policy.ServiceLbPolicy() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -35807,38 +36450,30 @@ def test_list_mesh_route_views_rest_required_fields( response_value.status_code = 200 # Convert return value to protobuf type - return_value = route_view.ListMeshRouteViewsResponse.pb(return_value) + return_value = service_lb_policy.ServiceLbPolicy.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_mesh_route_views(request) + response = client.get_service_lb_policy(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_list_mesh_route_views_rest_unset_required_fields(): +def test_get_service_lb_policy_rest_unset_required_fields(): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.list_mesh_route_views._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "pageSize", - "pageToken", - ) - ) - & set(("parent",)) - ) + unset_fields = transport.get_service_lb_policy._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) -def test_list_mesh_route_views_rest_flattened(): +def test_get_service_lb_policy_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -35847,14 +36482,16 @@ def test_list_mesh_route_views_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = route_view.ListMeshRouteViewsResponse() + return_value = service_lb_policy.ServiceLbPolicy() # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2/meshes/sample3"} + sample_request = { + "name": "projects/sample1/locations/sample2/serviceLbPolicies/sample3" + } # get truthy value for each flattened field mock_args = dict( - parent="parent_value", + name="name_value", ) mock_args.update(sample_request) @@ -35862,26 +36499,26 @@ def test_list_mesh_route_views_rest_flattened(): response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = route_view.ListMeshRouteViewsResponse.pb(return_value) + return_value = service_lb_policy.ServiceLbPolicy.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_mesh_route_views(**mock_args) + client.get_service_lb_policy(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/locations/*/meshes/*}/routeViews" + "%s/v1/{name=projects/*/locations/*/serviceLbPolicies/*}" % client.transport._host, args[1], ) -def test_list_mesh_route_views_rest_flattened_error(transport: str = "rest"): +def test_get_service_lb_policy_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -35890,3019 +36527,6588 @@ def test_list_mesh_route_views_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_mesh_route_views( - route_view.ListMeshRouteViewsRequest(), - parent="parent_value", - ) - - -def test_list_mesh_route_views_rest_pager(transport: str = "rest"): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - route_view.ListMeshRouteViewsResponse( - mesh_route_views=[ - route_view.MeshRouteView(), - route_view.MeshRouteView(), - route_view.MeshRouteView(), - ], - next_page_token="abc", - ), - route_view.ListMeshRouteViewsResponse( - mesh_route_views=[], - next_page_token="def", - ), - route_view.ListMeshRouteViewsResponse( - mesh_route_views=[ - route_view.MeshRouteView(), - ], - next_page_token="ghi", - ), - route_view.ListMeshRouteViewsResponse( - mesh_route_views=[ - route_view.MeshRouteView(), - route_view.MeshRouteView(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple( - route_view.ListMeshRouteViewsResponse.to_json(x) for x in response + client.get_service_lb_policy( + service_lb_policy.GetServiceLbPolicyRequest(), + name="name_value", ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "projects/sample1/locations/sample2/meshes/sample3"} - - pager = client.list_mesh_route_views(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, route_view.MeshRouteView) for i in results) - - pages = list(client.list_mesh_route_views(request=sample_request).pages) - 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.NetworkServicesGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): +def test_create_service_lb_policy_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport="rest", ) - # It is an error to provide a credentials file and a transport instance. - transport = transports.NetworkServicesGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = NetworkServicesClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # It is an error to provide an api_key and a transport instance. - transport = transports.NetworkServicesGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = NetworkServicesClient( - client_options=options, - transport=transport, + # Ensure method has been cached + assert ( + client._transport.create_service_lb_policy + in client._transport._wrapped_methods ) - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = NetworkServicesClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. ) + client._transport._wrapped_methods[ + client._transport.create_service_lb_policy + ] = mock_rpc - # It is an error to provide scopes and a transport instance. - transport = transports.NetworkServicesGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = NetworkServicesClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) + request = {} + client.create_service_lb_policy(request) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.NetworkServicesGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = NetworkServicesClient(transport=transport) - assert client.transport is transport + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + client.create_service_lb_policy(request) -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.NetworkServicesGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 - transport = transports.NetworkServicesGrpcAsyncIOTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel +def test_create_service_lb_policy_rest_required_fields( + request_type=gcn_service_lb_policy.CreateServiceLbPolicyRequest, +): + transport_class = transports.NetworkServicesRestTransport -@pytest.mark.parametrize( - "transport_class", - [ - transports.NetworkServicesGrpcTransport, - transports.NetworkServicesGrpcAsyncIOTransport, - transports.NetworkServicesRestTransport, - ], -) -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() + request_init = {} + request_init["parent"] = "" + request_init["service_lb_policy_id"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + # verify fields with default values are dropped + assert "serviceLbPolicyId" not in jsonified_request -def test_transport_kind_grpc(): - transport = NetworkServicesClient.get_transport_class("grpc")( + unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() + ).create_service_lb_policy._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "serviceLbPolicyId" in jsonified_request + assert ( + jsonified_request["serviceLbPolicyId"] == request_init["service_lb_policy_id"] ) - assert transport.kind == "grpc" + jsonified_request["parent"] = "parent_value" + jsonified_request["serviceLbPolicyId"] = "service_lb_policy_id_value" -def test_initialize_client_w_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc" - ) - assert client is not None + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_service_lb_policy._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("service_lb_policy_id",)) + jsonified_request.update(unset_fields) + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "serviceLbPolicyId" in jsonified_request + assert jsonified_request["serviceLbPolicyId"] == "service_lb_policy_id_value" -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_endpoint_policies_empty_call_grpc(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport="rest", ) + request = request_type(**request_init) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_endpoint_policies), "__call__" - ) as call: - call.return_value = endpoint_policy.ListEndpointPoliciesResponse() - client.list_endpoint_policies(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = endpoint_policy.ListEndpointPoliciesRequest() - assert args[0] == request_msg + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_endpoint_policy_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_endpoint_policy), "__call__" - ) as call: - call.return_value = endpoint_policy.EndpointPolicy() - client.get_endpoint_policy(request=None) + response = client.create_service_lb_policy(request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = endpoint_policy.GetEndpointPolicyRequest() - assert args[0] == request_msg + expected_params = [ + ( + "serviceLbPolicyId", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_create_endpoint_policy_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", +def test_create_service_lb_policy_rest_unset_required_fields(): + transport = transports.NetworkServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_endpoint_policy), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.create_endpoint_policy(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_endpoint_policy.CreateEndpointPolicyRequest() - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_update_endpoint_policy_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + unset_fields = transport.create_service_lb_policy._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("serviceLbPolicyId",)) + & set( + ( + "parent", + "serviceLbPolicyId", + "serviceLbPolicy", + ) + ) ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.update_endpoint_policy), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.update_endpoint_policy(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_endpoint_policy.UpdateEndpointPolicyRequest() - assert args[0] == request_msg - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_delete_endpoint_policy_empty_call_grpc(): +def test_create_service_lb_policy_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport="rest", ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_endpoint_policy), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.delete_endpoint_policy(request=None) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = endpoint_policy.DeleteEndpointPolicyRequest() - assert args[0] == request_msg + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + service_lb_policy=gcn_service_lb_policy.ServiceLbPolicy(name="name_value"), + service_lb_policy_id="service_lb_policy_id_value", + ) + mock_args.update(sample_request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_wasm_plugin_versions_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_wasm_plugin_versions), "__call__" - ) as call: - call.return_value = extensibility.ListWasmPluginVersionsResponse() - client.list_wasm_plugin_versions(request=None) + client.create_service_lb_policy(**mock_args) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = extensibility.ListWasmPluginVersionsRequest() - assert args[0] == request_msg + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*}/serviceLbPolicies" + % client.transport._host, + args[1], + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_wasm_plugin_version_empty_call_grpc(): +def test_create_service_lb_policy_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport=transport, ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_wasm_plugin_version), "__call__" - ) as call: - call.return_value = extensibility.WasmPluginVersion() - client.get_wasm_plugin_version(request=None) + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_service_lb_policy( + gcn_service_lb_policy.CreateServiceLbPolicyRequest(), + parent="parent_value", + service_lb_policy=gcn_service_lb_policy.ServiceLbPolicy(name="name_value"), + service_lb_policy_id="service_lb_policy_id_value", + ) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = extensibility.GetWasmPluginVersionRequest() - assert args[0] == request_msg +def test_update_service_lb_policy_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_create_wasm_plugin_version_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_wasm_plugin_version), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.create_wasm_plugin_version(request=None) + # Ensure method has been cached + assert ( + client._transport.update_service_lb_policy + in client._transport._wrapped_methods + ) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = extensibility.CreateWasmPluginVersionRequest() - assert args[0] == request_msg + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.update_service_lb_policy + ] = mock_rpc + request = {} + client.update_service_lb_policy(request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_delete_wasm_plugin_version_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_wasm_plugin_version), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.delete_wasm_plugin_version(request=None) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = extensibility.DeleteWasmPluginVersionRequest() - assert args[0] == request_msg + client.update_service_lb_policy(request) + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_wasm_plugins_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_wasm_plugins), "__call__" - ) as call: - call.return_value = extensibility.ListWasmPluginsResponse() - client.list_wasm_plugins(request=None) +def test_update_service_lb_policy_rest_required_fields( + request_type=gcn_service_lb_policy.UpdateServiceLbPolicyRequest, +): + transport_class = transports.NetworkServicesRestTransport - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = extensibility.ListWasmPluginsRequest() - assert args[0] == request_msg + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + # verify fields with default values are dropped -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_wasm_plugin_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_service_lb_policy._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.get_wasm_plugin), "__call__") as call: - call.return_value = extensibility.WasmPlugin() - client.get_wasm_plugin(request=None) + # verify required fields with default values are now present - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = extensibility.GetWasmPluginRequest() - assert args[0] == request_msg + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_service_lb_policy._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) + jsonified_request.update(unset_fields) + # verify required fields with non-default values are left alone -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_create_wasm_plugin_empty_call_grpc(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport="rest", ) + request = request_type(**request_init) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_wasm_plugin), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.create_wasm_plugin(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = extensibility.CreateWasmPluginRequest() - assert args[0] == request_msg + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_update_wasm_plugin_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.update_wasm_plugin), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.update_wasm_plugin(request=None) + response = client.update_service_lb_policy(request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = extensibility.UpdateWasmPluginRequest() - assert args[0] == request_msg + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_delete_wasm_plugin_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", +def test_update_service_lb_policy_rest_unset_required_fields(): + transport = transports.NetworkServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_wasm_plugin), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.delete_wasm_plugin(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = extensibility.DeleteWasmPluginRequest() - assert args[0] == request_msg + unset_fields = transport.update_service_lb_policy._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("serviceLbPolicy",))) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_gateways_empty_call_grpc(): +def test_update_service_lb_policy_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport="rest", ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_gateways), "__call__") as call: - call.return_value = gateway.ListGatewaysResponse() - client.list_gateways(request=None) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gateway.ListGatewaysRequest() - assert args[0] == request_msg + # get arguments that satisfy an http rule for this method + sample_request = { + "service_lb_policy": { + "name": "projects/sample1/locations/sample2/serviceLbPolicies/sample3" + } + } + # get truthy value for each flattened field + mock_args = dict( + service_lb_policy=gcn_service_lb_policy.ServiceLbPolicy(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_gateway_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.get_gateway), "__call__") as call: - call.return_value = gateway.Gateway() - client.get_gateway(request=None) + client.update_service_lb_policy(**mock_args) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gateway.GetGatewayRequest() - assert args[0] == request_msg + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{service_lb_policy.name=projects/*/locations/*/serviceLbPolicies/*}" + % client.transport._host, + args[1], + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_create_gateway_empty_call_grpc(): +def test_update_service_lb_policy_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport=transport, ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.create_gateway), "__call__") as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.create_gateway(request=None) + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_service_lb_policy( + gcn_service_lb_policy.UpdateServiceLbPolicyRequest(), + service_lb_policy=gcn_service_lb_policy.ServiceLbPolicy(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_gateway.CreateGatewayRequest() - assert args[0] == request_msg +def test_delete_service_lb_policy_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_update_gateway_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.update_gateway), "__call__") as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.update_gateway(request=None) + # Ensure method has been cached + assert ( + client._transport.delete_service_lb_policy + in client._transport._wrapped_methods + ) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_gateway.UpdateGatewayRequest() - assert args[0] == request_msg + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.delete_service_lb_policy + ] = mock_rpc + request = {} + client.delete_service_lb_policy(request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_delete_gateway_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.delete_gateway), "__call__") as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.delete_gateway(request=None) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gateway.DeleteGatewayRequest() - assert args[0] == request_msg + client.delete_service_lb_policy(request) + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_grpc_routes_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_grpc_routes), "__call__") as call: - call.return_value = grpc_route.ListGrpcRoutesResponse() - client.list_grpc_routes(request=None) +def test_delete_service_lb_policy_rest_required_fields( + request_type=service_lb_policy.DeleteServiceLbPolicyRequest, +): + transport_class = transports.NetworkServicesRestTransport - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grpc_route.ListGrpcRoutesRequest() - assert args[0] == request_msg + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + # verify fields with default values are dropped -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_grpc_route_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_service_lb_policy._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.get_grpc_route), "__call__") as call: - call.return_value = grpc_route.GrpcRoute() - client.get_grpc_route(request=None) + # verify required fields with default values are now present - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grpc_route.GetGrpcRouteRequest() - assert args[0] == request_msg + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_service_lb_policy._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_create_grpc_route_empty_call_grpc(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport="rest", ) + request = request_type(**request_init) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_grpc_route), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.create_grpc_route(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_grpc_route.CreateGrpcRouteRequest() - assert args[0] == request_msg + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "delete", + "query_params": pb_request, + } + transcode.return_value = transcode_result + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_update_grpc_route_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.update_grpc_route), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.update_grpc_route(request=None) + response = client.delete_service_lb_policy(request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_grpc_route.UpdateGrpcRouteRequest() - assert args[0] == request_msg + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_delete_grpc_route_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", +def test_delete_service_lb_policy_rest_unset_required_fields(): + transport = transports.NetworkServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_grpc_route), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.delete_grpc_route(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grpc_route.DeleteGrpcRouteRequest() - assert args[0] == request_msg + unset_fields = transport.delete_service_lb_policy._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_http_routes_empty_call_grpc(): +def test_delete_service_lb_policy_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport="rest", ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_http_routes), "__call__") as call: - call.return_value = http_route.ListHttpRoutesResponse() - client.list_http_routes(request=None) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = http_route.ListHttpRoutesRequest() - assert args[0] == request_msg + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/serviceLbPolicies/sample3" + } + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_http_route_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.get_http_route), "__call__") as call: - call.return_value = http_route.HttpRoute() - client.get_http_route(request=None) + client.delete_service_lb_policy(**mock_args) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = http_route.GetHttpRouteRequest() - assert args[0] == request_msg + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/serviceLbPolicies/*}" + % client.transport._host, + args[1], + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_create_http_route_empty_call_grpc(): +def test_delete_service_lb_policy_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport=transport, ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_http_route), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.create_http_route(request=None) + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_service_lb_policy( + service_lb_policy.DeleteServiceLbPolicyRequest(), + name="name_value", + ) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_http_route.CreateHttpRouteRequest() - assert args[0] == request_msg +def test_get_gateway_route_view_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_update_http_route_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.update_http_route), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.update_http_route(request=None) + # Ensure method has been cached + assert ( + client._transport.get_gateway_route_view + in client._transport._wrapped_methods + ) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_http_route.UpdateHttpRouteRequest() - assert args[0] == request_msg + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_gateway_route_view] = ( + mock_rpc + ) + request = {} + client.get_gateway_route_view(request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_delete_http_route_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_http_route), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.delete_http_route(request=None) + client.get_gateway_route_view(request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = http_route.DeleteHttpRouteRequest() - assert args[0] == request_msg + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_tcp_routes_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) +def test_get_gateway_route_view_rest_required_fields( + request_type=route_view.GetGatewayRouteViewRequest, +): + transport_class = transports.NetworkServicesRestTransport - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_tcp_routes), "__call__") as call: - call.return_value = tcp_route.ListTcpRoutesResponse() - client.list_tcp_routes(request=None) + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = tcp_route.ListTcpRoutesRequest() - assert args[0] == request_msg + # verify fields with default values are dropped + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_gateway_route_view._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_tcp_route_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # verify required fields with default values are now present - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.get_tcp_route), "__call__") as call: - call.return_value = tcp_route.TcpRoute() - client.get_tcp_route(request=None) + jsonified_request["name"] = "name_value" - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = tcp_route.GetTcpRouteRequest() - assert args[0] == request_msg + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_gateway_route_view._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_create_tcp_route_empty_call_grpc(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport="rest", ) + request = request_type(**request_init) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.create_tcp_route), "__call__") as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.create_tcp_route(request=None) + # Designate an appropriate value for the returned response. + return_value = route_view.GatewayRouteView() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_tcp_route.CreateTcpRouteRequest() - assert args[0] == request_msg + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = route_view.GatewayRouteView.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_update_tcp_route_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.update_tcp_route), "__call__") as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.update_tcp_route(request=None) + response = client.get_gateway_route_view(request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_tcp_route.UpdateTcpRouteRequest() - assert args[0] == request_msg + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_delete_tcp_route_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", +def test_get_gateway_route_view_rest_unset_required_fields(): + transport = transports.NetworkServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.delete_tcp_route), "__call__") as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.delete_tcp_route(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = tcp_route.DeleteTcpRouteRequest() - assert args[0] == request_msg + unset_fields = transport.get_gateway_route_view._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_tls_routes_empty_call_grpc(): +def test_get_gateway_route_view_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport="rest", ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_tls_routes), "__call__") as call: - call.return_value = tls_route.ListTlsRoutesResponse() - client.list_tls_routes(request=None) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = route_view.GatewayRouteView() - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = tls_route.ListTlsRoutesRequest() - assert args[0] == request_msg + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/gateways/sample3/routeViews/sample4" + } + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_tls_route_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = route_view.GatewayRouteView.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.get_tls_route), "__call__") as call: - call.return_value = tls_route.TlsRoute() - client.get_tls_route(request=None) + client.get_gateway_route_view(**mock_args) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = tls_route.GetTlsRouteRequest() - assert args[0] == request_msg + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/gateways/*/routeViews/*}" + % client.transport._host, + args[1], + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_create_tls_route_empty_call_grpc(): +def test_get_gateway_route_view_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport=transport, ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.create_tls_route), "__call__") as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.create_tls_route(request=None) + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_gateway_route_view( + route_view.GetGatewayRouteViewRequest(), + name="name_value", + ) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_tls_route.CreateTlsRouteRequest() - assert args[0] == request_msg +def test_get_mesh_route_view_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_update_tls_route_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.update_tls_route), "__call__") as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.update_tls_route(request=None) + # Ensure method has been cached + assert ( + client._transport.get_mesh_route_view in client._transport._wrapped_methods + ) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_tls_route.UpdateTlsRouteRequest() - assert args[0] == request_msg + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_mesh_route_view] = ( + mock_rpc + ) + request = {} + client.get_mesh_route_view(request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_delete_tls_route_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.delete_tls_route), "__call__") as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.delete_tls_route(request=None) + client.get_mesh_route_view(request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = tls_route.DeleteTlsRouteRequest() - assert args[0] == request_msg + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_service_bindings_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) +def test_get_mesh_route_view_rest_required_fields( + request_type=route_view.GetMeshRouteViewRequest, +): + transport_class = transports.NetworkServicesRestTransport - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_service_bindings), "__call__" - ) as call: - call.return_value = service_binding.ListServiceBindingsResponse() - client.list_service_bindings(request=None) + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = service_binding.ListServiceBindingsRequest() - assert args[0] == request_msg + # verify fields with default values are dropped + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_mesh_route_view._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_service_binding_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # verify required fields with default values are now present - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_service_binding), "__call__" - ) as call: - call.return_value = service_binding.ServiceBinding() - client.get_service_binding(request=None) + jsonified_request["name"] = "name_value" - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = service_binding.GetServiceBindingRequest() - assert args[0] == request_msg + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_mesh_route_view._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_create_service_binding_empty_call_grpc(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport="rest", ) + request = request_type(**request_init) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_service_binding), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.create_service_binding(request=None) + # Designate an appropriate value for the returned response. + return_value = route_view.MeshRouteView() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_service_binding.CreateServiceBindingRequest() - assert args[0] == request_msg + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = route_view.MeshRouteView.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_update_service_binding_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.update_service_binding), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.update_service_binding(request=None) + response = client.get_mesh_route_view(request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_service_binding.UpdateServiceBindingRequest() - assert args[0] == request_msg + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_delete_service_binding_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", +def test_get_mesh_route_view_rest_unset_required_fields(): + transport = transports.NetworkServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_service_binding), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.delete_service_binding(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = service_binding.DeleteServiceBindingRequest() - assert args[0] == request_msg + unset_fields = transport.get_mesh_route_view._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_meshes_empty_call_grpc(): +def test_get_mesh_route_view_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport="rest", ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_meshes), "__call__") as call: - call.return_value = mesh.ListMeshesResponse() - client.list_meshes(request=None) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = route_view.MeshRouteView() - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = mesh.ListMeshesRequest() - assert args[0] == request_msg + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/meshes/sample3/routeViews/sample4" + } + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_mesh_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = route_view.MeshRouteView.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.get_mesh), "__call__") as call: - call.return_value = mesh.Mesh() - client.get_mesh(request=None) + client.get_mesh_route_view(**mock_args) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = mesh.GetMeshRequest() - assert args[0] == request_msg + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/meshes/*/routeViews/*}" + % client.transport._host, + args[1], + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_create_mesh_empty_call_grpc(): +def test_get_mesh_route_view_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport=transport, ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.create_mesh), "__call__") as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.create_mesh(request=None) + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_mesh_route_view( + route_view.GetMeshRouteViewRequest(), + name="name_value", + ) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_mesh.CreateMeshRequest() - assert args[0] == request_msg +def test_list_gateway_route_views_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_update_mesh_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.update_mesh), "__call__") as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.update_mesh(request=None) + # Ensure method has been cached + assert ( + client._transport.list_gateway_route_views + in client._transport._wrapped_methods + ) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_mesh.UpdateMeshRequest() - assert args[0] == request_msg + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_gateway_route_views + ] = mock_rpc + request = {} + client.list_gateway_route_views(request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_delete_mesh_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.delete_mesh), "__call__") as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.delete_mesh(request=None) + client.list_gateway_route_views(request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = mesh.DeleteMeshRequest() - assert args[0] == request_msg + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_service_lb_policies_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) +def test_list_gateway_route_views_rest_required_fields( + request_type=route_view.ListGatewayRouteViewsRequest, +): + transport_class = transports.NetworkServicesRestTransport - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_service_lb_policies), "__call__" - ) as call: - call.return_value = service_lb_policy.ListServiceLbPoliciesResponse() - client.list_service_lb_policies(request=None) + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = service_lb_policy.ListServiceLbPoliciesRequest() - assert args[0] == request_msg + # verify fields with default values are dropped + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_gateway_route_views._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_service_lb_policy_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # verify required fields with default values are now present - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_service_lb_policy), "__call__" - ) as call: - call.return_value = service_lb_policy.ServiceLbPolicy() - client.get_service_lb_policy(request=None) + jsonified_request["parent"] = "parent_value" - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = service_lb_policy.GetServiceLbPolicyRequest() - assert args[0] == request_msg + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_gateway_route_views._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_create_service_lb_policy_empty_call_grpc(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport="rest", ) + request = request_type(**request_init) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_service_lb_policy), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.create_service_lb_policy(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_service_lb_policy.CreateServiceLbPolicyRequest() - assert args[0] == request_msg + # Designate an appropriate value for the returned response. + return_value = route_view.ListGatewayRouteViewsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + response_value = Response() + response_value.status_code = 200 -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_update_service_lb_policy_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Convert return value to protobuf type + return_value = route_view.ListGatewayRouteViewsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.update_service_lb_policy), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.update_service_lb_policy(request=None) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_service_lb_policy.UpdateServiceLbPolicyRequest() - assert args[0] == request_msg + response = client.list_gateway_route_views(request) + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_delete_service_lb_policy_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_service_lb_policy), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.delete_service_lb_policy(request=None) +def test_list_gateway_route_views_rest_unset_required_fields(): + transport = transports.NetworkServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = service_lb_policy.DeleteServiceLbPolicyRequest() - assert args[0] == request_msg + unset_fields = transport.list_gateway_route_views._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_gateway_route_view_empty_call_grpc(): +def test_list_gateway_route_views_rest_flattened(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport="rest", ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_gateway_route_view), "__call__" - ) as call: - call.return_value = route_view.GatewayRouteView() - client.get_gateway_route_view(request=None) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = route_view.ListGatewayRouteViewsResponse() - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = route_view.GetGatewayRouteViewRequest() - assert args[0] == request_msg + # get arguments that satisfy an http rule for this method + sample_request = { + "parent": "projects/sample1/locations/sample2/gateways/sample3" + } + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_mesh_route_view_empty_call_grpc(): - client = NetworkServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = route_view.ListGatewayRouteViewsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_mesh_route_view), "__call__" - ) as call: - call.return_value = route_view.MeshRouteView() - client.get_mesh_route_view(request=None) + client.list_gateway_route_views(**mock_args) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = route_view.GetMeshRouteViewRequest() - assert args[0] == request_msg + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*/gateways/*}/routeViews" + % client.transport._host, + args[1], + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_gateway_route_views_empty_call_grpc(): +def test_list_gateway_route_views_rest_flattened_error(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport=transport, ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_gateway_route_views), "__call__" - ) as call: - call.return_value = route_view.ListGatewayRouteViewsResponse() - client.list_gateway_route_views(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = route_view.ListGatewayRouteViewsRequest() - assert args[0] == request_msg + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_gateway_route_views( + route_view.ListGatewayRouteViewsRequest(), + parent="parent_value", + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_mesh_route_views_empty_call_grpc(): +def test_list_gateway_route_views_rest_pager(transport: str = "rest"): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", + transport=transport, ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_mesh_route_views), "__call__" - ) as call: - call.return_value = route_view.ListMeshRouteViewsResponse() - client.list_mesh_route_views(request=None) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + route_view.ListGatewayRouteViewsResponse( + gateway_route_views=[ + route_view.GatewayRouteView(), + route_view.GatewayRouteView(), + route_view.GatewayRouteView(), + ], + next_page_token="abc", + ), + route_view.ListGatewayRouteViewsResponse( + gateway_route_views=[], + next_page_token="def", + ), + route_view.ListGatewayRouteViewsResponse( + gateway_route_views=[ + route_view.GatewayRouteView(), + ], + next_page_token="ghi", + ), + route_view.ListGatewayRouteViewsResponse( + gateway_route_views=[ + route_view.GatewayRouteView(), + route_view.GatewayRouteView(), + ], + ), + ) + # Two responses for two calls + response = response + response - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = route_view.ListMeshRouteViewsRequest() - assert args[0] == request_msg + # Wrap the values into proper Response objs + response = tuple( + route_view.ListGatewayRouteViewsResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + sample_request = { + "parent": "projects/sample1/locations/sample2/gateways/sample3" + } -def test_transport_kind_grpc_asyncio(): - transport = NetworkServicesAsyncClient.get_transport_class("grpc_asyncio")( - credentials=async_anonymous_credentials() - ) - assert transport.kind == "grpc_asyncio" + pager = client.list_gateway_route_views(request=sample_request) + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, route_view.GatewayRouteView) for i in results) -def test_initialize_client_w_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), transport="grpc_asyncio" - ) - assert client is not None + pages = list(client.list_gateway_route_views(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_endpoint_policies_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) +def test_list_mesh_route_views_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_endpoint_policies), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - endpoint_policy.ListEndpointPoliciesResponse( - next_page_token="next_page_token_value", - unreachable=["unreachable_value"], - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_mesh_route_views + in client._transport._wrapped_methods ) - await client.list_endpoint_policies(request=None) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = endpoint_policy.ListEndpointPoliciesRequest() - assert args[0] == request_msg + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.list_mesh_route_views] = ( + mock_rpc + ) + request = {} + client.list_mesh_route_views(request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_get_endpoint_policy_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_endpoint_policy), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - endpoint_policy.EndpointPolicy( - name="name_value", - type_=endpoint_policy.EndpointPolicy.EndpointPolicyType.SIDECAR_PROXY, - authorization_policy="authorization_policy_value", - description="description_value", - server_tls_policy="server_tls_policy_value", - client_tls_policy="client_tls_policy_value", - ) - ) - await client.get_endpoint_policy(request=None) + client.list_mesh_route_views(request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = endpoint_policy.GetEndpointPolicyRequest() - assert args[0] == request_msg + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_create_endpoint_policy_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +def test_list_mesh_route_views_rest_required_fields( + request_type=route_view.ListMeshRouteViewsRequest, +): + transport_class = transports.NetworkServicesRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_endpoint_policy), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.create_endpoint_policy(request=None) + # verify fields with default values are dropped - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_endpoint_policy.CreateEndpointPolicyRequest() - assert args[0] == request_msg + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_mesh_route_views._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + # verify required fields with default values are now present -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_update_endpoint_policy_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + jsonified_request["parent"] = "parent_value" - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.update_endpoint_policy), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_mesh_route_views._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "page_size", + "page_token", ) - await client.update_endpoint_policy(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_endpoint_policy.UpdateEndpointPolicyRequest() - assert args[0] == request_msg + ) + jsonified_request.update(unset_fields) + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_delete_endpoint_policy_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) + request = request_type(**request_init) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_endpoint_policy), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.delete_endpoint_policy(request=None) + # Designate an appropriate value for the returned response. + return_value = route_view.ListMeshRouteViewsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = endpoint_policy.DeleteEndpointPolicyRequest() - assert args[0] == request_msg + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = route_view.ListMeshRouteViewsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_wasm_plugin_versions_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_mesh_route_views(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_list_mesh_route_views_rest_unset_required_fields(): + transport = transports.NetworkServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_wasm_plugin_versions), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - extensibility.ListWasmPluginVersionsResponse( - next_page_token="next_page_token_value", - unreachable=["unreachable_value"], + unset_fields = transport.list_mesh_route_views._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "pageSize", + "pageToken", ) ) - await client.list_wasm_plugin_versions(request=None) + & set(("parent",)) + ) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = extensibility.ListWasmPluginVersionsRequest() - assert args[0] == request_msg +def test_list_mesh_route_views_rest_flattened(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_get_wasm_plugin_version_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_wasm_plugin_version), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - extensibility.WasmPluginVersion( - name="name_value", - description="description_value", - image_uri="image_uri_value", - image_digest="image_digest_value", - plugin_config_digest="plugin_config_digest_value", - ) - ) - await client.get_wasm_plugin_version(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = extensibility.GetWasmPluginVersionRequest() - assert args[0] == request_msg - + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = route_view.ListMeshRouteViewsResponse() -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_create_wasm_plugin_version_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2/meshes/sample3"} - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_wasm_plugin_version), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", ) - await client.create_wasm_plugin_version(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = extensibility.CreateWasmPluginVersionRequest() - assert args[0] == request_msg + mock_args.update(sample_request) + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = route_view.ListMeshRouteViewsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_delete_wasm_plugin_version_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + client.list_mesh_route_views(**mock_args) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_wasm_plugin_version), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*/meshes/*}/routeViews" + % client.transport._host, + args[1], ) - await client.delete_wasm_plugin_version(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = extensibility.DeleteWasmPluginVersionRequest() - assert args[0] == request_msg -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_wasm_plugins_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +def test_list_mesh_route_views_rest_flattened_error(transport: str = "rest"): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_wasm_plugins), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - extensibility.ListWasmPluginsResponse( - next_page_token="next_page_token_value", - unreachable=["unreachable_value"], - ) + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_mesh_route_views( + route_view.ListMeshRouteViewsRequest(), + parent="parent_value", ) - await client.list_wasm_plugins(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = extensibility.ListWasmPluginsRequest() - assert args[0] == request_msg -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_get_wasm_plugin_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +def test_list_mesh_route_views_rest_pager(transport: str = "rest"): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.get_wasm_plugin), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - extensibility.WasmPlugin( - name="name_value", - description="description_value", - main_version_id="main_version_id_value", - ) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + route_view.ListMeshRouteViewsResponse( + mesh_route_views=[ + route_view.MeshRouteView(), + route_view.MeshRouteView(), + route_view.MeshRouteView(), + ], + next_page_token="abc", + ), + route_view.ListMeshRouteViewsResponse( + mesh_route_views=[], + next_page_token="def", + ), + route_view.ListMeshRouteViewsResponse( + mesh_route_views=[ + route_view.MeshRouteView(), + ], + next_page_token="ghi", + ), + route_view.ListMeshRouteViewsResponse( + mesh_route_views=[ + route_view.MeshRouteView(), + route_view.MeshRouteView(), + ], + ), ) - await client.get_wasm_plugin(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = extensibility.GetWasmPluginRequest() - assert args[0] == request_msg + # Two responses for two calls + response = response + response + # Wrap the values into proper Response objs + response = tuple( + route_view.ListMeshRouteViewsResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_create_wasm_plugin_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + sample_request = {"parent": "projects/sample1/locations/sample2/meshes/sample3"} - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_wasm_plugin), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.create_wasm_plugin(request=None) + pager = client.list_mesh_route_views(request=sample_request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = extensibility.CreateWasmPluginRequest() - assert args[0] == request_msg + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, route_view.MeshRouteView) for i in results) + pages = list(client.list_mesh_route_views(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_update_wasm_plugin_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.update_wasm_plugin), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") +def test_list_agent_gateways_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - await client.update_wasm_plugin(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = extensibility.UpdateWasmPluginRequest() - assert args[0] == request_msg + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_delete_wasm_plugin_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + # Ensure method has been cached + assert ( + client._transport.list_agent_gateways in client._transport._wrapped_methods + ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_wasm_plugin), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.list_agent_gateways] = ( + mock_rpc ) - await client.delete_wasm_plugin(request=None) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = extensibility.DeleteWasmPluginRequest() - assert args[0] == request_msg + request = {} + client.list_agent_gateways(request) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_gateways_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + client.list_agent_gateways(request) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_gateways), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - gateway.ListGatewaysResponse( - next_page_token="next_page_token_value", - unreachable=["unreachable_value"], - ) - ) - await client.list_gateways(request=None) + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gateway.ListGatewaysRequest() - assert args[0] == request_msg +def test_list_agent_gateways_rest_required_fields( + request_type=agent_gateway.ListAgentGatewaysRequest, +): + transport_class = transports.NetworkServicesRestTransport -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_get_gateway_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.get_gateway), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - gateway.Gateway( - name="name_value", - self_link="self_link_value", - description="description_value", - type_=gateway.Gateway.Type.OPEN_MESH, - addresses=["addresses_value"], - ports=[568], - scope="scope_value", - server_tls_policy="server_tls_policy_value", - certificate_urls=["certificate_urls_value"], - gateway_security_policy="gateway_security_policy_value", - network="network_value", - subnetwork="subnetwork_value", - ip_version=gateway.Gateway.IpVersion.IPV4, - envoy_headers=common.EnvoyHeaders.NONE, - routing_mode=gateway.Gateway.RoutingMode.NEXT_HOP_ROUTING_MODE, - ) - ) - await client.get_gateway(request=None) + # verify fields with default values are dropped - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gateway.GetGatewayRequest() - assert args[0] == request_msg + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_agent_gateways._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + # verify required fields with default values are now present -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_create_gateway_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + jsonified_request["parent"] = "parent_value" - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.create_gateway), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_agent_gateways._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "page_size", + "page_token", + "return_partial_success", ) - await client.create_gateway(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_gateway.CreateGatewayRequest() - assert args[0] == request_msg + ) + jsonified_request.update(unset_fields) + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_update_gateway_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) + request = request_type(**request_init) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.update_gateway), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.update_gateway(request=None) + # Designate an appropriate value for the returned response. + return_value = agent_gateway.ListAgentGatewaysResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_gateway.UpdateGatewayRequest() - assert args[0] == request_msg + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = agent_gateway.ListAgentGatewaysResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_delete_gateway_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.delete_gateway), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.delete_gateway(request=None) + response = client.list_agent_gateways(request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gateway.DeleteGatewayRequest() - assert args[0] == request_msg + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_grpc_routes_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +def test_list_agent_gateways_rest_unset_required_fields(): + transport = transports.NetworkServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_grpc_routes), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - grpc_route.ListGrpcRoutesResponse( - next_page_token="next_page_token_value", - unreachable=["unreachable_value"], + unset_fields = transport.list_agent_gateways._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "pageSize", + "pageToken", + "returnPartialSuccess", ) ) - await client.list_grpc_routes(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grpc_route.ListGrpcRoutesRequest() - assert args[0] == request_msg + & set(("parent",)) + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_get_grpc_route_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +def test_list_agent_gateways_rest_flattened(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.get_grpc_route), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - grpc_route.GrpcRoute( - name="name_value", - self_link="self_link_value", - description="description_value", - hostnames=["hostnames_value"], - meshes=["meshes_value"], - gateways=["gateways_value"], - ) - ) - await client.get_grpc_route(request=None) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = agent_gateway.ListAgentGatewaysResponse() - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grpc_route.GetGrpcRouteRequest() - assert args[0] == request_msg + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_create_grpc_route_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = agent_gateway.ListAgentGatewaysResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_grpc_route), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.create_grpc_route(request=None) + client.list_agent_gateways(**mock_args) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_grpc_route.CreateGrpcRouteRequest() - assert args[0] == request_msg + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*}/agentGateways" + % client.transport._host, + args[1], + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_update_grpc_route_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +def test_list_agent_gateways_rest_flattened_error(transport: str = "rest"): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.update_grpc_route), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_agent_gateways( + agent_gateway.ListAgentGatewaysRequest(), + parent="parent_value", ) - await client.update_grpc_route(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_grpc_route.UpdateGrpcRouteRequest() - assert args[0] == request_msg -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_delete_grpc_route_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +def test_list_agent_gateways_rest_pager(transport: str = "rest"): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_grpc_route), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + agent_gateway.ListAgentGatewaysResponse( + agent_gateways=[ + agent_gateway.AgentGateway(), + agent_gateway.AgentGateway(), + agent_gateway.AgentGateway(), + ], + next_page_token="abc", + ), + agent_gateway.ListAgentGatewaysResponse( + agent_gateways=[], + next_page_token="def", + ), + agent_gateway.ListAgentGatewaysResponse( + agent_gateways=[ + agent_gateway.AgentGateway(), + ], + next_page_token="ghi", + ), + agent_gateway.ListAgentGatewaysResponse( + agent_gateways=[ + agent_gateway.AgentGateway(), + agent_gateway.AgentGateway(), + ], + ), ) - await client.delete_grpc_route(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grpc_route.DeleteGrpcRouteRequest() - assert args[0] == request_msg + # Two responses for two calls + response = response + response + # Wrap the values into proper Response objs + response = tuple( + agent_gateway.ListAgentGatewaysResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_http_routes_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + sample_request = {"parent": "projects/sample1/locations/sample2"} - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_http_routes), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - http_route.ListHttpRoutesResponse( - next_page_token="next_page_token_value", - unreachable=["unreachable_value"], - ) - ) - await client.list_http_routes(request=None) + pager = client.list_agent_gateways(request=sample_request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = http_route.ListHttpRoutesRequest() - assert args[0] == request_msg + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, agent_gateway.AgentGateway) for i in results) + pages = list(client.list_agent_gateways(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_get_http_route_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.get_http_route), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - http_route.HttpRoute( - name="name_value", - self_link="self_link_value", - description="description_value", - hostnames=["hostnames_value"], - meshes=["meshes_value"], - gateways=["gateways_value"], - ) +def test_get_agent_gateway_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - await client.get_http_route(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = http_route.GetHttpRouteRequest() - assert args[0] == request_msg + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_create_http_route_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + # Ensure method has been cached + assert client._transport.get_agent_gateway in client._transport._wrapped_methods - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_http_route), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_agent_gateway] = ( + mock_rpc ) - await client.create_http_route(request=None) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_http_route.CreateHttpRouteRequest() - assert args[0] == request_msg + request = {} + client.get_agent_gateway(request) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_update_http_route_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + client.get_agent_gateway(request) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.update_http_route), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.update_http_route(request=None) + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_http_route.UpdateHttpRouteRequest() - assert args[0] == request_msg +def test_get_agent_gateway_rest_required_fields( + request_type=agent_gateway.GetAgentGatewayRequest, +): + transport_class = transports.NetworkServicesRestTransport -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_delete_http_route_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_http_route), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.delete_http_route(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = http_route.DeleteHttpRouteRequest() - assert args[0] == request_msg + # verify fields with default values are dropped + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_agent_gateway._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_tcp_routes_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + # verify required fields with default values are now present - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_tcp_routes), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - tcp_route.ListTcpRoutesResponse( - next_page_token="next_page_token_value", - unreachable=["unreachable_value"], - ) - ) - await client.list_tcp_routes(request=None) + jsonified_request["name"] = "name_value" - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = tcp_route.ListTcpRoutesRequest() - assert args[0] == request_msg + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_agent_gateway._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_get_tcp_route_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) + request = request_type(**request_init) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.get_tcp_route), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - tcp_route.TcpRoute( - name="name_value", - self_link="self_link_value", - description="description_value", - meshes=["meshes_value"], - gateways=["gateways_value"], - ) - ) - await client.get_tcp_route(request=None) + # Designate an appropriate value for the returned response. + return_value = agent_gateway.AgentGateway() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = tcp_route.GetTcpRouteRequest() - assert args[0] == request_msg + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = agent_gateway.AgentGateway.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_create_tcp_route_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.create_tcp_route), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.create_tcp_route(request=None) + response = client.get_agent_gateway(request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_tcp_route.CreateTcpRouteRequest() - assert args[0] == request_msg + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_update_tcp_route_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +def test_get_agent_gateway_rest_unset_required_fields(): + transport = transports.NetworkServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.update_tcp_route), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.update_tcp_route(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_tcp_route.UpdateTcpRouteRequest() - assert args[0] == request_msg + unset_fields = transport.get_agent_gateway._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_delete_tcp_route_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +def test_get_agent_gateway_rest_flattened(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.delete_tcp_route), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.delete_tcp_route(request=None) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = agent_gateway.AgentGateway() - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = tcp_route.DeleteTcpRouteRequest() - assert args[0] == request_msg + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/agentGateways/sample3" + } + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_tls_routes_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = agent_gateway.AgentGateway.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_tls_routes), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - tls_route.ListTlsRoutesResponse( - next_page_token="next_page_token_value", - unreachable=["unreachable_value"], - ) - ) - await client.list_tls_routes(request=None) + client.get_agent_gateway(**mock_args) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = tls_route.ListTlsRoutesRequest() - assert args[0] == request_msg + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/agentGateways/*}" + % client.transport._host, + args[1], + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_get_tls_route_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +def test_get_agent_gateway_rest_flattened_error(transport: str = "rest"): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.get_tls_route), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - tls_route.TlsRoute( - name="name_value", - self_link="self_link_value", - description="description_value", - meshes=["meshes_value"], - gateways=["gateways_value"], - ) + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_agent_gateway( + agent_gateway.GetAgentGatewayRequest(), + name="name_value", ) - await client.get_tls_route(request=None) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = tls_route.GetTlsRouteRequest() - assert args[0] == request_msg +def test_create_agent_gateway_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_create_tls_route_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.create_tls_route), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") + # Ensure method has been cached + assert ( + client._transport.create_agent_gateway in client._transport._wrapped_methods ) - await client.create_tls_route(request=None) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_tls_route.CreateTlsRouteRequest() - assert args[0] == request_msg + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.create_agent_gateway] = ( + mock_rpc + ) + request = {} + client.create_agent_gateway(request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_update_tls_route_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.update_tls_route), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.update_tls_route(request=None) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_tls_route.UpdateTlsRouteRequest() - assert args[0] == request_msg + client.create_agent_gateway(request) + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_delete_tls_route_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.delete_tls_route), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.delete_tls_route(request=None) +def test_create_agent_gateway_rest_required_fields( + request_type=gcn_agent_gateway.CreateAgentGatewayRequest, +): + transport_class = transports.NetworkServicesRestTransport - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = tls_route.DeleteTlsRouteRequest() - assert args[0] == request_msg + request_init = {} + request_init["parent"] = "" + request_init["agent_gateway_id"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + # verify fields with default values are dropped + assert "agentGatewayId" not in jsonified_request -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_service_bindings_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_agent_gateway._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_service_bindings), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - service_binding.ListServiceBindingsResponse( - next_page_token="next_page_token_value", - unreachable=["unreachable_value"], - ) - ) - await client.list_service_bindings(request=None) + # verify required fields with default values are now present + assert "agentGatewayId" in jsonified_request + assert jsonified_request["agentGatewayId"] == request_init["agent_gateway_id"] - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = service_binding.ListServiceBindingsRequest() - assert args[0] == request_msg + jsonified_request["parent"] = "parent_value" + jsonified_request["agentGatewayId"] = "agent_gateway_id_value" + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_agent_gateway._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("agent_gateway_id",)) + jsonified_request.update(unset_fields) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_get_service_binding_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "agentGatewayId" in jsonified_request + assert jsonified_request["agentGatewayId"] == "agent_gateway_id_value" - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_service_binding), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - service_binding.ServiceBinding( - name="name_value", - description="description_value", - service="service_value", - service_id="service_id_value", - ) - ) - await client.get_service_binding(request=None) + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = service_binding.GetServiceBindingRequest() - assert args[0] == request_msg + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_create_service_binding_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_service_binding), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.create_service_binding(request=None) + response = client.create_agent_gateway(request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_service_binding.CreateServiceBindingRequest() - assert args[0] == request_msg + expected_params = [ + ( + "agentGatewayId", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_update_service_binding_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +def test_create_agent_gateway_rest_unset_required_fields(): + transport = transports.NetworkServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.update_service_binding), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") + unset_fields = transport.create_agent_gateway._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("agentGatewayId",)) + & set( + ( + "parent", + "agentGatewayId", + "agentGateway", + ) ) - await client.update_service_binding(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_service_binding.UpdateServiceBindingRequest() - assert args[0] == request_msg + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_delete_service_binding_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +def test_create_agent_gateway_rest_flattened(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_service_binding), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.delete_service_binding(request=None) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = service_binding.DeleteServiceBindingRequest() - assert args[0] == request_msg + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + agent_gateway=gcn_agent_gateway.AgentGateway( + google_managed=gcn_agent_gateway.AgentGateway.GoogleManaged( + governed_access_path=gcn_agent_gateway.AgentGateway.GoogleManaged.GovernedAccessPath.AGENT_TO_ANYWHERE + ) + ), + agent_gateway_id="agent_gateway_id_value", + ) + mock_args.update(sample_request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_meshes_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_meshes), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - mesh.ListMeshesResponse( - next_page_token="next_page_token_value", - unreachable=["unreachable_value"], - ) - ) - await client.list_meshes(request=None) + client.create_agent_gateway(**mock_args) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = mesh.ListMeshesRequest() - assert args[0] == request_msg + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*}/agentGateways" + % client.transport._host, + args[1], + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_get_mesh_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +def test_create_agent_gateway_rest_flattened_error(transport: str = "rest"): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.get_mesh), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - mesh.Mesh( - name="name_value", - self_link="self_link_value", - description="description_value", - interception_port=1848, - envoy_headers=common.EnvoyHeaders.NONE, - ) + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_agent_gateway( + gcn_agent_gateway.CreateAgentGatewayRequest(), + parent="parent_value", + agent_gateway=gcn_agent_gateway.AgentGateway( + google_managed=gcn_agent_gateway.AgentGateway.GoogleManaged( + governed_access_path=gcn_agent_gateway.AgentGateway.GoogleManaged.GovernedAccessPath.AGENT_TO_ANYWHERE + ) + ), + agent_gateway_id="agent_gateway_id_value", ) - await client.get_mesh(request=None) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = mesh.GetMeshRequest() - assert args[0] == request_msg +def test_update_agent_gateway_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_create_mesh_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.create_mesh), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") + # Ensure method has been cached + assert ( + client._transport.update_agent_gateway in client._transport._wrapped_methods ) - await client.create_mesh(request=None) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_mesh.CreateMeshRequest() - assert args[0] == request_msg + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.update_agent_gateway] = ( + mock_rpc + ) + request = {} + client.update_agent_gateway(request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_update_mesh_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.update_mesh), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.update_mesh(request=None) + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_mesh.UpdateMeshRequest() - assert args[0] == request_msg + client.update_agent_gateway(request) + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_delete_mesh_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.delete_mesh), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.delete_mesh(request=None) +def test_update_agent_gateway_rest_required_fields( + request_type=gcn_agent_gateway.UpdateAgentGatewayRequest, +): + transport_class = transports.NetworkServicesRestTransport - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = mesh.DeleteMeshRequest() - assert args[0] == request_msg + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + # verify fields with default values are dropped -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_service_lb_policies_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_agent_gateway._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_service_lb_policies), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - service_lb_policy.ListServiceLbPoliciesResponse( - next_page_token="next_page_token_value", - unreachable=["unreachable_value"], - ) - ) - await client.list_service_lb_policies(request=None) + # verify required fields with default values are now present - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = service_lb_policy.ListServiceLbPoliciesRequest() - assert args[0] == request_msg + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_agent_gateway._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) + jsonified_request.update(unset_fields) + # verify required fields with non-default values are left alone -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_get_service_lb_policy_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.update_agent_gateway(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_update_agent_gateway_rest_unset_required_fields(): + transport = transports.NetworkServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_agent_gateway._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("agentGateway",))) + + +def test_update_agent_gateway_rest_flattened(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = { + "agent_gateway": { + "name": "projects/sample1/locations/sample2/agentGateways/sample3" + } + } + + # get truthy value for each flattened field + mock_args = dict( + agent_gateway=gcn_agent_gateway.AgentGateway( + google_managed=gcn_agent_gateway.AgentGateway.GoogleManaged( + governed_access_path=gcn_agent_gateway.AgentGateway.GoogleManaged.GovernedAccessPath.AGENT_TO_ANYWHERE + ) + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.update_agent_gateway(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{agent_gateway.name=projects/*/locations/*/agentGateways/*}" + % client.transport._host, + args[1], + ) + + +def test_update_agent_gateway_rest_flattened_error(transport: str = "rest"): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_agent_gateway( + gcn_agent_gateway.UpdateAgentGatewayRequest(), + agent_gateway=gcn_agent_gateway.AgentGateway( + google_managed=gcn_agent_gateway.AgentGateway.GoogleManaged( + governed_access_path=gcn_agent_gateway.AgentGateway.GoogleManaged.GovernedAccessPath.AGENT_TO_ANYWHERE + ) + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_delete_agent_gateway_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.delete_agent_gateway in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.delete_agent_gateway] = ( + mock_rpc + ) + + request = {} + client.delete_agent_gateway(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_agent_gateway(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_delete_agent_gateway_rest_required_fields( + request_type=agent_gateway.DeleteAgentGatewayRequest, +): + transport_class = transports.NetworkServicesRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_agent_gateway._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_agent_gateway._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("etag",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "delete", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.delete_agent_gateway(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_delete_agent_gateway_rest_unset_required_fields(): + transport = transports.NetworkServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.delete_agent_gateway._get_unset_required_fields({}) + assert set(unset_fields) == (set(("etag",)) & set(("name",))) + + +def test_delete_agent_gateway_rest_flattened(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/agentGateways/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.delete_agent_gateway(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/agentGateways/*}" + % client.transport._host, + args[1], + ) + + +def test_delete_agent_gateway_rest_flattened_error(transport: str = "rest"): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_agent_gateway( + agent_gateway.DeleteAgentGatewayRequest(), + name="name_value", + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.NetworkServicesGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.NetworkServicesGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = NetworkServicesClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.NetworkServicesGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = NetworkServicesClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = NetworkServicesClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.NetworkServicesGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = NetworkServicesClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.NetworkServicesGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = NetworkServicesClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.NetworkServicesGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.NetworkServicesGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.NetworkServicesGrpcTransport, + transports.NetworkServicesGrpcAsyncIOTransport, + transports.NetworkServicesRestTransport, + ], +) +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_kind_grpc(): + transport = NetworkServicesClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_endpoint_policies_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) # Mock the actual call, and fake the request. with mock.patch.object( - type(client.transport.get_service_lb_policy), "__call__" + type(client.transport.list_endpoint_policies), "__call__" ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - service_lb_policy.ServiceLbPolicy( - name="name_value", - description="description_value", - load_balancing_algorithm=service_lb_policy.ServiceLbPolicy.LoadBalancingAlgorithm.SPRAY_TO_WORLD, - ) - ) - await client.get_service_lb_policy(request=None) + call.return_value = endpoint_policy.ListEndpointPoliciesResponse() + client.list_endpoint_policies(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = endpoint_policy.ListEndpointPoliciesRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_endpoint_policy_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_endpoint_policy), "__call__" + ) as call: + call.return_value = endpoint_policy.EndpointPolicy() + client.get_endpoint_policy(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = endpoint_policy.GetEndpointPolicyRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_endpoint_policy_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_endpoint_policy), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_endpoint_policy(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_endpoint_policy.CreateEndpointPolicyRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_endpoint_policy_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_endpoint_policy), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.update_endpoint_policy(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_endpoint_policy.UpdateEndpointPolicyRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_endpoint_policy_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_endpoint_policy), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_endpoint_policy(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = endpoint_policy.DeleteEndpointPolicyRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_wasm_plugin_versions_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_wasm_plugin_versions), "__call__" + ) as call: + call.return_value = extensibility.ListWasmPluginVersionsResponse() + client.list_wasm_plugin_versions(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = extensibility.ListWasmPluginVersionsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_wasm_plugin_version_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_wasm_plugin_version), "__call__" + ) as call: + call.return_value = extensibility.WasmPluginVersion() + client.get_wasm_plugin_version(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = extensibility.GetWasmPluginVersionRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_wasm_plugin_version_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_wasm_plugin_version), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_wasm_plugin_version(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = extensibility.CreateWasmPluginVersionRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_wasm_plugin_version_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_wasm_plugin_version), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_wasm_plugin_version(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = extensibility.DeleteWasmPluginVersionRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_wasm_plugins_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_wasm_plugins), "__call__" + ) as call: + call.return_value = extensibility.ListWasmPluginsResponse() + client.list_wasm_plugins(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = extensibility.ListWasmPluginsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_wasm_plugin_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_wasm_plugin), "__call__") as call: + call.return_value = extensibility.WasmPlugin() + client.get_wasm_plugin(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = extensibility.GetWasmPluginRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_wasm_plugin_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_wasm_plugin), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_wasm_plugin(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = extensibility.CreateWasmPluginRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_wasm_plugin_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_wasm_plugin), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.update_wasm_plugin(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = extensibility.UpdateWasmPluginRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_wasm_plugin_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_wasm_plugin), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_wasm_plugin(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = extensibility.DeleteWasmPluginRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_gateways_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_gateways), "__call__") as call: + call.return_value = gateway.ListGatewaysResponse() + client.list_gateways(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gateway.ListGatewaysRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_gateway_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_gateway), "__call__") as call: + call.return_value = gateway.Gateway() + client.get_gateway(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gateway.GetGatewayRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_gateway_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_gateway), "__call__") as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_gateway(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_gateway.CreateGatewayRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_gateway_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_gateway), "__call__") as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.update_gateway(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_gateway.UpdateGatewayRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_gateway_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_gateway), "__call__") as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_gateway(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gateway.DeleteGatewayRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_grpc_routes_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_grpc_routes), "__call__") as call: + call.return_value = grpc_route.ListGrpcRoutesResponse() + client.list_grpc_routes(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grpc_route.ListGrpcRoutesRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_grpc_route_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_grpc_route), "__call__") as call: + call.return_value = grpc_route.GrpcRoute() + client.get_grpc_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grpc_route.GetGrpcRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_grpc_route_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_grpc_route), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_grpc_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_grpc_route.CreateGrpcRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_grpc_route_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_grpc_route), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.update_grpc_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_grpc_route.UpdateGrpcRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_grpc_route_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_grpc_route), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_grpc_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grpc_route.DeleteGrpcRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_http_routes_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_http_routes), "__call__") as call: + call.return_value = http_route.ListHttpRoutesResponse() + client.list_http_routes(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = http_route.ListHttpRoutesRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_http_route_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_http_route), "__call__") as call: + call.return_value = http_route.HttpRoute() + client.get_http_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = http_route.GetHttpRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_http_route_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_http_route), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_http_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_http_route.CreateHttpRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_http_route_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_http_route), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.update_http_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_http_route.UpdateHttpRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_http_route_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_http_route), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_http_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = http_route.DeleteHttpRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_tcp_routes_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_tcp_routes), "__call__") as call: + call.return_value = tcp_route.ListTcpRoutesResponse() + client.list_tcp_routes(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = tcp_route.ListTcpRoutesRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_tcp_route_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_tcp_route), "__call__") as call: + call.return_value = tcp_route.TcpRoute() + client.get_tcp_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = tcp_route.GetTcpRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_tcp_route_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_tcp_route), "__call__") as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_tcp_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_tcp_route.CreateTcpRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_tcp_route_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_tcp_route), "__call__") as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.update_tcp_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_tcp_route.UpdateTcpRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_tcp_route_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_tcp_route), "__call__") as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_tcp_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = tcp_route.DeleteTcpRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_tls_routes_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_tls_routes), "__call__") as call: + call.return_value = tls_route.ListTlsRoutesResponse() + client.list_tls_routes(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = tls_route.ListTlsRoutesRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_tls_route_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_tls_route), "__call__") as call: + call.return_value = tls_route.TlsRoute() + client.get_tls_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = tls_route.GetTlsRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_tls_route_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_tls_route), "__call__") as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_tls_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_tls_route.CreateTlsRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_tls_route_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_tls_route), "__call__") as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.update_tls_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_tls_route.UpdateTlsRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_tls_route_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_tls_route), "__call__") as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_tls_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = tls_route.DeleteTlsRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_service_bindings_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_service_bindings), "__call__" + ) as call: + call.return_value = service_binding.ListServiceBindingsResponse() + client.list_service_bindings(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = service_binding.ListServiceBindingsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_service_binding_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_service_binding), "__call__" + ) as call: + call.return_value = service_binding.ServiceBinding() + client.get_service_binding(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = service_binding.GetServiceBindingRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_service_binding_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_service_binding), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_service_binding(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_service_binding.CreateServiceBindingRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_service_binding_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_service_binding), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.update_service_binding(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_service_binding.UpdateServiceBindingRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_service_binding_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_service_binding), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_service_binding(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = service_binding.DeleteServiceBindingRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_meshes_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_meshes), "__call__") as call: + call.return_value = mesh.ListMeshesResponse() + client.list_meshes(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = mesh.ListMeshesRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_mesh_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_mesh), "__call__") as call: + call.return_value = mesh.Mesh() + client.get_mesh(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = mesh.GetMeshRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_mesh_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_mesh), "__call__") as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_mesh(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_mesh.CreateMeshRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_mesh_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_mesh), "__call__") as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.update_mesh(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_mesh.UpdateMeshRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_mesh_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_mesh), "__call__") as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_mesh(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = mesh.DeleteMeshRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_service_lb_policies_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_service_lb_policies), "__call__" + ) as call: + call.return_value = service_lb_policy.ListServiceLbPoliciesResponse() + client.list_service_lb_policies(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = service_lb_policy.ListServiceLbPoliciesRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_service_lb_policy_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_service_lb_policy), "__call__" + ) as call: + call.return_value = service_lb_policy.ServiceLbPolicy() + client.get_service_lb_policy(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = service_lb_policy.GetServiceLbPolicyRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_service_lb_policy_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_service_lb_policy), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_service_lb_policy(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_service_lb_policy.CreateServiceLbPolicyRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_service_lb_policy_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_service_lb_policy), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.update_service_lb_policy(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_service_lb_policy.UpdateServiceLbPolicyRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_service_lb_policy_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_service_lb_policy), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_service_lb_policy(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = service_lb_policy.DeleteServiceLbPolicyRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_gateway_route_view_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_gateway_route_view), "__call__" + ) as call: + call.return_value = route_view.GatewayRouteView() + client.get_gateway_route_view(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = route_view.GetGatewayRouteViewRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_mesh_route_view_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_mesh_route_view), "__call__" + ) as call: + call.return_value = route_view.MeshRouteView() + client.get_mesh_route_view(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = route_view.GetMeshRouteViewRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_gateway_route_views_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_gateway_route_views), "__call__" + ) as call: + call.return_value = route_view.ListGatewayRouteViewsResponse() + client.list_gateway_route_views(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = route_view.ListGatewayRouteViewsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_mesh_route_views_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_mesh_route_views), "__call__" + ) as call: + call.return_value = route_view.ListMeshRouteViewsResponse() + client.list_mesh_route_views(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = route_view.ListMeshRouteViewsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_agent_gateways_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_agent_gateways), "__call__" + ) as call: + call.return_value = agent_gateway.ListAgentGatewaysResponse() + client.list_agent_gateways(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = agent_gateway.ListAgentGatewaysRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_agent_gateway_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_agent_gateway), "__call__" + ) as call: + call.return_value = agent_gateway.AgentGateway() + client.get_agent_gateway(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = agent_gateway.GetAgentGatewayRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_agent_gateway_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_agent_gateway), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_agent_gateway(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_agent_gateway.CreateAgentGatewayRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_agent_gateway_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_agent_gateway), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.update_agent_gateway(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_agent_gateway.UpdateAgentGatewayRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_agent_gateway_empty_call_grpc(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_agent_gateway), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_agent_gateway(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = agent_gateway.DeleteAgentGatewayRequest() + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = NetworkServicesAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_endpoint_policies_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_endpoint_policies), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + endpoint_policy.ListEndpointPoliciesResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + await client.list_endpoint_policies(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = endpoint_policy.ListEndpointPoliciesRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_endpoint_policy_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_endpoint_policy), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + endpoint_policy.EndpointPolicy( + name="name_value", + type_=endpoint_policy.EndpointPolicy.EndpointPolicyType.SIDECAR_PROXY, + authorization_policy="authorization_policy_value", + description="description_value", + server_tls_policy="server_tls_policy_value", + client_tls_policy="client_tls_policy_value", + ) + ) + await client.get_endpoint_policy(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = endpoint_policy.GetEndpointPolicyRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_endpoint_policy_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_endpoint_policy), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.create_endpoint_policy(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_endpoint_policy.CreateEndpointPolicyRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_endpoint_policy_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_endpoint_policy), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.update_endpoint_policy(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_endpoint_policy.UpdateEndpointPolicyRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_endpoint_policy_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_endpoint_policy), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.delete_endpoint_policy(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = endpoint_policy.DeleteEndpointPolicyRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_wasm_plugin_versions_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_wasm_plugin_versions), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + extensibility.ListWasmPluginVersionsResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + await client.list_wasm_plugin_versions(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = extensibility.ListWasmPluginVersionsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_wasm_plugin_version_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_wasm_plugin_version), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + extensibility.WasmPluginVersion( + name="name_value", + description="description_value", + image_uri="image_uri_value", + image_digest="image_digest_value", + plugin_config_digest="plugin_config_digest_value", + ) + ) + await client.get_wasm_plugin_version(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = extensibility.GetWasmPluginVersionRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_wasm_plugin_version_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_wasm_plugin_version), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.create_wasm_plugin_version(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = extensibility.CreateWasmPluginVersionRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_wasm_plugin_version_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_wasm_plugin_version), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.delete_wasm_plugin_version(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = extensibility.DeleteWasmPluginVersionRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_wasm_plugins_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_wasm_plugins), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + extensibility.ListWasmPluginsResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + await client.list_wasm_plugins(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = extensibility.ListWasmPluginsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_wasm_plugin_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_wasm_plugin), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + extensibility.WasmPlugin( + name="name_value", + description="description_value", + main_version_id="main_version_id_value", + ) + ) + await client.get_wasm_plugin(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = extensibility.GetWasmPluginRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_wasm_plugin_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_wasm_plugin), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.create_wasm_plugin(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = extensibility.CreateWasmPluginRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_wasm_plugin_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_wasm_plugin), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.update_wasm_plugin(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = extensibility.UpdateWasmPluginRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_wasm_plugin_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_wasm_plugin), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.delete_wasm_plugin(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = extensibility.DeleteWasmPluginRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_gateways_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_gateways), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gateway.ListGatewaysResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + await client.list_gateways(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gateway.ListGatewaysRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_gateway_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_gateway), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gateway.Gateway( + name="name_value", + self_link="self_link_value", + description="description_value", + type_=gateway.Gateway.Type.OPEN_MESH, + addresses=["addresses_value"], + ports=[568], + all_ports=True, + scope="scope_value", + server_tls_policy="server_tls_policy_value", + certificate_urls=["certificate_urls_value"], + gateway_security_policy="gateway_security_policy_value", + network="network_value", + subnetwork="subnetwork_value", + ip_version=gateway.Gateway.IpVersion.IPV4, + envoy_headers=common.EnvoyHeaders.NONE, + routing_mode=gateway.Gateway.RoutingMode.NEXT_HOP_ROUTING_MODE, + allow_global_access=True, + ) + ) + await client.get_gateway(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gateway.GetGatewayRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_gateway_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_gateway), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.create_gateway(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_gateway.CreateGatewayRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_gateway_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_gateway), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.update_gateway(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_gateway.UpdateGatewayRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_gateway_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_gateway), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.delete_gateway(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gateway.DeleteGatewayRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_grpc_routes_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_grpc_routes), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + grpc_route.ListGrpcRoutesResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + await client.list_grpc_routes(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grpc_route.ListGrpcRoutesRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_grpc_route_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_grpc_route), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + grpc_route.GrpcRoute( + name="name_value", + self_link="self_link_value", + description="description_value", + hostnames=["hostnames_value"], + meshes=["meshes_value"], + gateways=["gateways_value"], + ) + ) + await client.get_grpc_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grpc_route.GetGrpcRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_grpc_route_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_grpc_route), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.create_grpc_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_grpc_route.CreateGrpcRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_grpc_route_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_grpc_route), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.update_grpc_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_grpc_route.UpdateGrpcRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_grpc_route_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_grpc_route), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.delete_grpc_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grpc_route.DeleteGrpcRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_http_routes_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_http_routes), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + http_route.ListHttpRoutesResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + await client.list_http_routes(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = http_route.ListHttpRoutesRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_http_route_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_http_route), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + http_route.HttpRoute( + name="name_value", + self_link="self_link_value", + description="description_value", + hostnames=["hostnames_value"], + meshes=["meshes_value"], + gateways=["gateways_value"], + ) + ) + await client.get_http_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = http_route.GetHttpRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_http_route_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_http_route), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.create_http_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_http_route.CreateHttpRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_http_route_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_http_route), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.update_http_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_http_route.UpdateHttpRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_http_route_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_http_route), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.delete_http_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = http_route.DeleteHttpRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_tcp_routes_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_tcp_routes), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tcp_route.ListTcpRoutesResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + await client.list_tcp_routes(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = tcp_route.ListTcpRoutesRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_tcp_route_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_tcp_route), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tcp_route.TcpRoute( + name="name_value", + self_link="self_link_value", + description="description_value", + meshes=["meshes_value"], + gateways=["gateways_value"], + ) + ) + await client.get_tcp_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = tcp_route.GetTcpRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_tcp_route_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_tcp_route), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.create_tcp_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_tcp_route.CreateTcpRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_tcp_route_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_tcp_route), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.update_tcp_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_tcp_route.UpdateTcpRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_tcp_route_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_tcp_route), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.delete_tcp_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = tcp_route.DeleteTcpRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_tls_routes_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_tls_routes), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tls_route.ListTlsRoutesResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + await client.list_tls_routes(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = tls_route.ListTlsRoutesRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_tls_route_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_tls_route), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tls_route.TlsRoute( + name="name_value", + self_link="self_link_value", + description="description_value", + meshes=["meshes_value"], + gateways=["gateways_value"], + target_proxies=["target_proxies_value"], + ) + ) + await client.get_tls_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = tls_route.GetTlsRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_tls_route_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_tls_route), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.create_tls_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_tls_route.CreateTlsRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_tls_route_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_tls_route), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.update_tls_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_tls_route.UpdateTlsRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_tls_route_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_tls_route), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.delete_tls_route(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = tls_route.DeleteTlsRouteRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_service_bindings_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_service_bindings), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + service_binding.ListServiceBindingsResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + await client.list_service_bindings(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = service_binding.ListServiceBindingsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_service_binding_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_service_binding), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + service_binding.ServiceBinding( + name="name_value", + description="description_value", + service="service_value", + service_id="service_id_value", + ) + ) + await client.get_service_binding(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = service_binding.GetServiceBindingRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_service_binding_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_service_binding), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.create_service_binding(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_service_binding.CreateServiceBindingRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_service_binding_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_service_binding), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.update_service_binding(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_service_binding.UpdateServiceBindingRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_service_binding_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_service_binding), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.delete_service_binding(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = service_binding.DeleteServiceBindingRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_meshes_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_meshes), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + mesh.ListMeshesResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + await client.list_meshes(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = mesh.ListMeshesRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_mesh_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_mesh), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + mesh.Mesh( + name="name_value", + self_link="self_link_value", + description="description_value", + interception_port=1848, + envoy_headers=common.EnvoyHeaders.NONE, + ) + ) + await client.get_mesh(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = mesh.GetMeshRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_mesh_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_mesh), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.create_mesh(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_mesh.CreateMeshRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_mesh_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_mesh), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.update_mesh(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_mesh.UpdateMeshRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_mesh_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_mesh), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.delete_mesh(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = mesh.DeleteMeshRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_service_lb_policies_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_service_lb_policies), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + service_lb_policy.ListServiceLbPoliciesResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + await client.list_service_lb_policies(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = service_lb_policy.ListServiceLbPoliciesRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_service_lb_policy_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_service_lb_policy), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + service_lb_policy.ServiceLbPolicy( + name="name_value", + description="description_value", + load_balancing_algorithm=service_lb_policy.ServiceLbPolicy.LoadBalancingAlgorithm.SPRAY_TO_WORLD, + ) + ) + await client.get_service_lb_policy(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = service_lb_policy.GetServiceLbPolicyRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_service_lb_policy_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_service_lb_policy), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.create_service_lb_policy(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_service_lb_policy.CreateServiceLbPolicyRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_service_lb_policy_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_service_lb_policy), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.update_service_lb_policy(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_service_lb_policy.UpdateServiceLbPolicyRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_service_lb_policy_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_service_lb_policy), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.delete_service_lb_policy(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = service_lb_policy.DeleteServiceLbPolicyRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_gateway_route_view_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_gateway_route_view), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + route_view.GatewayRouteView( + name="name_value", + route_project_number=2157, + route_location="route_location_value", + route_type="route_type_value", + route_id="route_id_value", + ) + ) + await client.get_gateway_route_view(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = route_view.GetGatewayRouteViewRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_mesh_route_view_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_mesh_route_view), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + route_view.MeshRouteView( + name="name_value", + route_project_number=2157, + route_location="route_location_value", + route_type="route_type_value", + route_id="route_id_value", + ) + ) + await client.get_mesh_route_view(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = route_view.GetMeshRouteViewRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_gateway_route_views_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_gateway_route_views), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + route_view.ListGatewayRouteViewsResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + await client.list_gateway_route_views(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = route_view.ListGatewayRouteViewsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_mesh_route_views_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_mesh_route_views), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + route_view.ListMeshRouteViewsResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + await client.list_mesh_route_views(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = route_view.ListMeshRouteViewsRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_agent_gateways_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_agent_gateways), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + agent_gateway.ListAgentGatewaysResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + await client.list_agent_gateways(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = agent_gateway.ListAgentGatewaysRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_agent_gateway_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_agent_gateway), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + agent_gateway.AgentGateway( + name="name_value", + description="description_value", + etag="etag_value", + protocols=[agent_gateway.AgentGateway.Protocol.MCP], + registries=["registries_value"], + ) + ) + await client.get_agent_gateway(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = agent_gateway.GetAgentGatewayRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_agent_gateway_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_agent_gateway), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.create_agent_gateway(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_agent_gateway.CreateAgentGatewayRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_agent_gateway_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_agent_gateway), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.update_agent_gateway(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_agent_gateway.UpdateAgentGatewayRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_agent_gateway_empty_call_grpc_asyncio(): + client = NetworkServicesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_agent_gateway), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.delete_agent_gateway(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = agent_gateway.DeleteAgentGatewayRequest() + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = NetworkServicesClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_list_endpoint_policies_rest_bad_request( + request_type=endpoint_policy.ListEndpointPoliciesRequest, +): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_endpoint_policies(request) + + +@pytest.mark.parametrize( + "request_type", + [ + endpoint_policy.ListEndpointPoliciesRequest, + dict, + ], +) +def test_list_endpoint_policies_rest_call_success(request_type): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = endpoint_policy.ListEndpointPoliciesResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = endpoint_policy.ListEndpointPoliciesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_endpoint_policies(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListEndpointPoliciesPager) + assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_endpoint_policies_rest_interceptors(null_interceptor): + transport = transports.NetworkServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.NetworkServicesRestInterceptor(), + ) + client = NetworkServicesClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.NetworkServicesRestInterceptor, "post_list_endpoint_policies" + ) as post, + mock.patch.object( + transports.NetworkServicesRestInterceptor, + "post_list_endpoint_policies_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.NetworkServicesRestInterceptor, "pre_list_endpoint_policies" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = endpoint_policy.ListEndpointPoliciesRequest.pb( + endpoint_policy.ListEndpointPoliciesRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = endpoint_policy.ListEndpointPoliciesResponse.to_json( + endpoint_policy.ListEndpointPoliciesResponse() + ) + req.return_value.content = return_value + + request = endpoint_policy.ListEndpointPoliciesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = endpoint_policy.ListEndpointPoliciesResponse() + post_with_metadata.return_value = ( + endpoint_policy.ListEndpointPoliciesResponse(), + metadata, + ) + + client.list_endpoint_policies( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_endpoint_policy_rest_bad_request( + request_type=endpoint_policy.GetEndpointPolicyRequest, +): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/endpointPolicies/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_endpoint_policy(request) + + +@pytest.mark.parametrize( + "request_type", + [ + endpoint_policy.GetEndpointPolicyRequest, + dict, + ], +) +def test_get_endpoint_policy_rest_call_success(request_type): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/endpointPolicies/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = endpoint_policy.EndpointPolicy( + name="name_value", + type_=endpoint_policy.EndpointPolicy.EndpointPolicyType.SIDECAR_PROXY, + authorization_policy="authorization_policy_value", + description="description_value", + server_tls_policy="server_tls_policy_value", + client_tls_policy="client_tls_policy_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = endpoint_policy.EndpointPolicy.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_endpoint_policy(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, endpoint_policy.EndpointPolicy) + assert response.name == "name_value" + assert ( + response.type_ + == endpoint_policy.EndpointPolicy.EndpointPolicyType.SIDECAR_PROXY + ) + assert response.authorization_policy == "authorization_policy_value" + assert response.description == "description_value" + assert response.server_tls_policy == "server_tls_policy_value" + assert response.client_tls_policy == "client_tls_policy_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_endpoint_policy_rest_interceptors(null_interceptor): + transport = transports.NetworkServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.NetworkServicesRestInterceptor(), + ) + client = NetworkServicesClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.NetworkServicesRestInterceptor, "post_get_endpoint_policy" + ) as post, + mock.patch.object( + transports.NetworkServicesRestInterceptor, + "post_get_endpoint_policy_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.NetworkServicesRestInterceptor, "pre_get_endpoint_policy" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = endpoint_policy.GetEndpointPolicyRequest.pb( + endpoint_policy.GetEndpointPolicyRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = endpoint_policy.EndpointPolicy.to_json( + endpoint_policy.EndpointPolicy() + ) + req.return_value.content = return_value + + request = endpoint_policy.GetEndpointPolicyRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = endpoint_policy.EndpointPolicy() + post_with_metadata.return_value = endpoint_policy.EndpointPolicy(), metadata + + client.get_endpoint_policy( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_create_endpoint_policy_rest_bad_request( + request_type=gcn_endpoint_policy.CreateEndpointPolicyRequest, +): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.create_endpoint_policy(request) + + +@pytest.mark.parametrize( + "request_type", + [ + gcn_endpoint_policy.CreateEndpointPolicyRequest, + dict, + ], +) +def test_create_endpoint_policy_rest_call_success(request_type): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request_init["endpoint_policy"] = { + "name": "name_value", + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "labels": {}, + "type_": 1, + "authorization_policy": "authorization_policy_value", + "endpoint_matcher": { + "metadata_label_matcher": { + "metadata_label_match_criteria": 1, + "metadata_labels": [ + { + "label_name": "label_name_value", + "label_value": "label_value_value", + } + ], + } + }, + "traffic_port_selector": {"ports": ["ports_value1", "ports_value2"]}, + "description": "description_value", + "server_tls_policy": "server_tls_policy_value", + "client_tls_policy": "client_tls_policy_value", + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = gcn_endpoint_policy.CreateEndpointPolicyRequest.meta.fields[ + "endpoint_policy" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["endpoint_policy"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["endpoint_policy"][field])): + del request_init["endpoint_policy"][field][i][subfield] + else: + del request_init["endpoint_policy"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.create_endpoint_policy(request) + + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_endpoint_policy_rest_interceptors(null_interceptor): + transport = transports.NetworkServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.NetworkServicesRestInterceptor(), + ) + client = NetworkServicesClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), + mock.patch.object( + transports.NetworkServicesRestInterceptor, "post_create_endpoint_policy" + ) as post, + mock.patch.object( + transports.NetworkServicesRestInterceptor, + "post_create_endpoint_policy_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.NetworkServicesRestInterceptor, "pre_create_endpoint_policy" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = gcn_endpoint_policy.CreateEndpointPolicyRequest.pb( + gcn_endpoint_policy.CreateEndpointPolicyRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value + + request = gcn_endpoint_policy.CreateEndpointPolicyRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata + + client.create_endpoint_policy( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_update_endpoint_policy_rest_bad_request( + request_type=gcn_endpoint_policy.UpdateEndpointPolicyRequest, +): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "endpoint_policy": { + "name": "projects/sample1/locations/sample2/endpointPolicies/sample3" + } + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.update_endpoint_policy(request) + + +@pytest.mark.parametrize( + "request_type", + [ + gcn_endpoint_policy.UpdateEndpointPolicyRequest, + dict, + ], +) +def test_update_endpoint_policy_rest_call_success(request_type): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "endpoint_policy": { + "name": "projects/sample1/locations/sample2/endpointPolicies/sample3" + } + } + request_init["endpoint_policy"] = { + "name": "projects/sample1/locations/sample2/endpointPolicies/sample3", + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "labels": {}, + "type_": 1, + "authorization_policy": "authorization_policy_value", + "endpoint_matcher": { + "metadata_label_matcher": { + "metadata_label_match_criteria": 1, + "metadata_labels": [ + { + "label_name": "label_name_value", + "label_value": "label_value_value", + } + ], + } + }, + "traffic_port_selector": {"ports": ["ports_value1", "ports_value2"]}, + "description": "description_value", + "server_tls_policy": "server_tls_policy_value", + "client_tls_policy": "client_tls_policy_value", + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = gcn_endpoint_policy.UpdateEndpointPolicyRequest.meta.fields[ + "endpoint_policy" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = service_lb_policy.GetServiceLbPolicyRequest() - assert args[0] == request_msg + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_create_service_lb_policy_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_service_lb_policy), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.create_service_lb_policy(request=None) + subfields_not_in_runtime = [] - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_service_lb_policy.CreateServiceLbPolicyRequest() - assert args[0] == request_msg + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["endpoint_policy"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["endpoint_policy"][field])): + del request_init["endpoint_policy"][field][i][subfield] + else: + del request_init["endpoint_policy"][field][subfield] + request = request_type(**request_init) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_update_service_lb_policy_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.update_service_lb_policy), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - await client.update_service_lb_policy(request=None) + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.update_endpoint_policy(request) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = gcn_service_lb_policy.UpdateServiceLbPolicyRequest() - assert args[0] == request_msg + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_delete_service_lb_policy_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_endpoint_policy_rest_interceptors(null_interceptor): + transport = transports.NetworkServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.NetworkServicesRestInterceptor(), ) + client = NetworkServicesClient(transport=transport) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_service_lb_policy), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), + mock.patch.object( + transports.NetworkServicesRestInterceptor, "post_update_endpoint_policy" + ) as post, + mock.patch.object( + transports.NetworkServicesRestInterceptor, + "post_update_endpoint_policy_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.NetworkServicesRestInterceptor, "pre_update_endpoint_policy" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = gcn_endpoint_policy.UpdateEndpointPolicyRequest.pb( + gcn_endpoint_policy.UpdateEndpointPolicyRequest() ) - await client.delete_service_lb_policy(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = service_lb_policy.DeleteServiceLbPolicyRequest() - assert args[0] == request_msg + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_get_gateway_route_view_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) + request = gcn_endpoint_policy.UpdateEndpointPolicyRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_gateway_route_view), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - route_view.GatewayRouteView( - name="name_value", - route_project_number=2157, - route_location="route_location_value", - route_type="route_type_value", - route_id="route_id_value", - ) + client.update_endpoint_policy( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], ) - await client.get_gateway_route_view(request=None) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = route_view.GetGatewayRouteViewRequest() - assert args[0] == request_msg + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_get_mesh_route_view_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +def test_delete_endpoint_policy_rest_bad_request( + request_type=endpoint_policy.DeleteEndpointPolicyRequest, +): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/endpointPolicies/sample3" + } + request = request_type(**request_init) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_mesh_route_view), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - route_view.MeshRouteView( - name="name_value", - route_project_number=2157, - route_location="route_location_value", - route_type="route_type_value", - route_id="route_id_value", - ) - ) - await client.get_mesh_route_view(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = route_view.GetMeshRouteViewRequest() - assert args[0] == request_msg + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.delete_endpoint_policy(request) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_gateway_route_views_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +@pytest.mark.parametrize( + "request_type", + [ + endpoint_policy.DeleteEndpointPolicyRequest, + dict, + ], +) +def test_delete_endpoint_policy_rest_call_success(request_type): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_gateway_route_views), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - route_view.ListGatewayRouteViewsResponse( - next_page_token="next_page_token_value", - unreachable=["unreachable_value"], - ) - ) - await client.list_gateway_route_views(request=None) + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/endpointPolicies/sample3" + } + request = request_type(**request_init) - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = route_view.ListGatewayRouteViewsRequest() - assert args[0] == request_msg + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.delete_endpoint_policy(request) + + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_mesh_route_views_empty_call_grpc_asyncio(): - client = NetworkServicesAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_endpoint_policy_rest_interceptors(null_interceptor): + transport = transports.NetworkServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.NetworkServicesRestInterceptor(), ) + client = NetworkServicesClient(transport=transport) - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_mesh_route_views), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - route_view.ListMeshRouteViewsResponse( - next_page_token="next_page_token_value", - unreachable=["unreachable_value"], - ) + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), + mock.patch.object( + transports.NetworkServicesRestInterceptor, "post_delete_endpoint_policy" + ) as post, + mock.patch.object( + transports.NetworkServicesRestInterceptor, + "post_delete_endpoint_policy_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.NetworkServicesRestInterceptor, "pre_delete_endpoint_policy" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = endpoint_policy.DeleteEndpointPolicyRequest.pb( + endpoint_policy.DeleteEndpointPolicyRequest() ) - await client.list_mesh_route_views(request=None) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = route_view.ListMeshRouteViewsRequest() - assert args[0] == request_msg + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value + request = endpoint_policy.DeleteEndpointPolicyRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata -def test_transport_kind_rest(): - transport = NetworkServicesClient.get_transport_class("rest")( - credentials=ga_credentials.AnonymousCredentials() - ) - assert transport.kind == "rest" + client.delete_endpoint_policy( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() -def test_list_endpoint_policies_rest_bad_request( - request_type=endpoint_policy.ListEndpointPoliciesRequest, + +def test_list_wasm_plugin_versions_rest_bad_request( + request_type=extensibility.ListWasmPluginVersionsRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} + request_init = {"parent": "projects/sample1/locations/sample2/wasmPlugins/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -38918,29 +43124,29 @@ def test_list_endpoint_policies_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_endpoint_policies(request) + client.list_wasm_plugin_versions(request) @pytest.mark.parametrize( "request_type", [ - endpoint_policy.ListEndpointPoliciesRequest, + extensibility.ListWasmPluginVersionsRequest, dict, ], ) -def test_list_endpoint_policies_rest_call_success(request_type): +def test_list_wasm_plugin_versions_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} + request_init = {"parent": "projects/sample1/locations/sample2/wasmPlugins/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = endpoint_policy.ListEndpointPoliciesResponse( + return_value = extensibility.ListWasmPluginVersionsResponse( next_page_token="next_page_token_value", unreachable=["unreachable_value"], ) @@ -38950,21 +43156,21 @@ def test_list_endpoint_policies_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = endpoint_policy.ListEndpointPoliciesResponse.pb(return_value) + return_value = extensibility.ListWasmPluginVersionsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_endpoint_policies(request) + response = client.list_wasm_plugin_versions(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListEndpointPoliciesPager) + assert isinstance(response, pagers.ListWasmPluginVersionsPager) assert response.next_page_token == "next_page_token_value" assert response.unreachable == ["unreachable_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_endpoint_policies_rest_interceptors(null_interceptor): +def test_list_wasm_plugin_versions_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -38977,21 +43183,21 @@ def test_list_endpoint_policies_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_list_endpoint_policies" + transports.NetworkServicesRestInterceptor, "post_list_wasm_plugin_versions" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_list_endpoint_policies_with_metadata", + "post_list_wasm_plugin_versions_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_list_endpoint_policies" + transports.NetworkServicesRestInterceptor, "pre_list_wasm_plugin_versions" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = endpoint_policy.ListEndpointPoliciesRequest.pb( - endpoint_policy.ListEndpointPoliciesRequest() + pb_message = extensibility.ListWasmPluginVersionsRequest.pb( + extensibility.ListWasmPluginVersionsRequest() ) transcode.return_value = { "method": "post", @@ -39003,24 +43209,24 @@ def test_list_endpoint_policies_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = endpoint_policy.ListEndpointPoliciesResponse.to_json( - endpoint_policy.ListEndpointPoliciesResponse() + return_value = extensibility.ListWasmPluginVersionsResponse.to_json( + extensibility.ListWasmPluginVersionsResponse() ) req.return_value.content = return_value - request = endpoint_policy.ListEndpointPoliciesRequest() + request = extensibility.ListWasmPluginVersionsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = endpoint_policy.ListEndpointPoliciesResponse() + post.return_value = extensibility.ListWasmPluginVersionsResponse() post_with_metadata.return_value = ( - endpoint_policy.ListEndpointPoliciesResponse(), + extensibility.ListWasmPluginVersionsResponse(), metadata, ) - client.list_endpoint_policies( + client.list_wasm_plugin_versions( request, metadata=[ ("key", "val"), @@ -39033,15 +43239,15 @@ def test_list_endpoint_policies_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_get_endpoint_policy_rest_bad_request( - request_type=endpoint_policy.GetEndpointPolicyRequest, +def test_get_wasm_plugin_version_rest_bad_request( + request_type=extensibility.GetWasmPluginVersionRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/endpointPolicies/sample3" + "name": "projects/sample1/locations/sample2/wasmPlugins/sample3/versions/sample4" } request = request_type(**request_init) @@ -39058,37 +43264,37 @@ def test_get_endpoint_policy_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_endpoint_policy(request) + client.get_wasm_plugin_version(request) @pytest.mark.parametrize( "request_type", [ - endpoint_policy.GetEndpointPolicyRequest, + extensibility.GetWasmPluginVersionRequest, dict, ], ) -def test_get_endpoint_policy_rest_call_success(request_type): +def test_get_wasm_plugin_version_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/endpointPolicies/sample3" + "name": "projects/sample1/locations/sample2/wasmPlugins/sample3/versions/sample4" } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = endpoint_policy.EndpointPolicy( + return_value = extensibility.WasmPluginVersion( name="name_value", - type_=endpoint_policy.EndpointPolicy.EndpointPolicyType.SIDECAR_PROXY, - authorization_policy="authorization_policy_value", description="description_value", - server_tls_policy="server_tls_policy_value", - client_tls_policy="client_tls_policy_value", + image_uri="image_uri_value", + image_digest="image_digest_value", + plugin_config_digest="plugin_config_digest_value", + plugin_config_data=b"plugin_config_data_blob", ) # Wrap the value into a proper Response obj @@ -39096,28 +43302,24 @@ def test_get_endpoint_policy_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = endpoint_policy.EndpointPolicy.pb(return_value) + return_value = extensibility.WasmPluginVersion.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_endpoint_policy(request) + response = client.get_wasm_plugin_version(request) # Establish that the response is the type that we expect. - assert isinstance(response, endpoint_policy.EndpointPolicy) + assert isinstance(response, extensibility.WasmPluginVersion) assert response.name == "name_value" - assert ( - response.type_ - == endpoint_policy.EndpointPolicy.EndpointPolicyType.SIDECAR_PROXY - ) - assert response.authorization_policy == "authorization_policy_value" assert response.description == "description_value" - assert response.server_tls_policy == "server_tls_policy_value" - assert response.client_tls_policy == "client_tls_policy_value" + assert response.image_uri == "image_uri_value" + assert response.image_digest == "image_digest_value" + assert response.plugin_config_digest == "plugin_config_digest_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_endpoint_policy_rest_interceptors(null_interceptor): +def test_get_wasm_plugin_version_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -39130,21 +43332,21 @@ def test_get_endpoint_policy_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_get_endpoint_policy" + transports.NetworkServicesRestInterceptor, "post_get_wasm_plugin_version" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_get_endpoint_policy_with_metadata", + "post_get_wasm_plugin_version_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_get_endpoint_policy" + transports.NetworkServicesRestInterceptor, "pre_get_wasm_plugin_version" ) as pre, ): pre.assert_not_called() post.assert_not_called() - post_with_metadata.assert_not_called() - pb_message = endpoint_policy.GetEndpointPolicyRequest.pb( - endpoint_policy.GetEndpointPolicyRequest() + post_with_metadata.assert_not_called() + pb_message = extensibility.GetWasmPluginVersionRequest.pb( + extensibility.GetWasmPluginVersionRequest() ) transcode.return_value = { "method": "post", @@ -39156,21 +43358,21 @@ def test_get_endpoint_policy_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = endpoint_policy.EndpointPolicy.to_json( - endpoint_policy.EndpointPolicy() + return_value = extensibility.WasmPluginVersion.to_json( + extensibility.WasmPluginVersion() ) req.return_value.content = return_value - request = endpoint_policy.GetEndpointPolicyRequest() + request = extensibility.GetWasmPluginVersionRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = endpoint_policy.EndpointPolicy() - post_with_metadata.return_value = endpoint_policy.EndpointPolicy(), metadata + post.return_value = extensibility.WasmPluginVersion() + post_with_metadata.return_value = extensibility.WasmPluginVersion(), metadata - client.get_endpoint_policy( + client.get_wasm_plugin_version( request, metadata=[ ("key", "val"), @@ -39183,14 +43385,14 @@ def test_get_endpoint_policy_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_create_endpoint_policy_rest_bad_request( - request_type=gcn_endpoint_policy.CreateEndpointPolicyRequest, +def test_create_wasm_plugin_version_rest_bad_request( + request_type=extensibility.CreateWasmPluginVersionRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} + request_init = {"parent": "projects/sample1/locations/sample2/wasmPlugins/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -39206,53 +43408,42 @@ def test_create_endpoint_policy_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_endpoint_policy(request) + client.create_wasm_plugin_version(request) @pytest.mark.parametrize( "request_type", [ - gcn_endpoint_policy.CreateEndpointPolicyRequest, + extensibility.CreateWasmPluginVersionRequest, dict, ], ) -def test_create_endpoint_policy_rest_call_success(request_type): +def test_create_wasm_plugin_version_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} - request_init["endpoint_policy"] = { + request_init = {"parent": "projects/sample1/locations/sample2/wasmPlugins/sample3"} + request_init["wasm_plugin_version"] = { + "plugin_config_data": b"plugin_config_data_blob", + "plugin_config_uri": "plugin_config_uri_value", "name": "name_value", "create_time": {"seconds": 751, "nanos": 543}, "update_time": {}, - "labels": {}, - "type_": 1, - "authorization_policy": "authorization_policy_value", - "endpoint_matcher": { - "metadata_label_matcher": { - "metadata_label_match_criteria": 1, - "metadata_labels": [ - { - "label_name": "label_name_value", - "label_value": "label_value_value", - } - ], - } - }, - "traffic_port_selector": {"ports": ["ports_value1", "ports_value2"]}, "description": "description_value", - "server_tls_policy": "server_tls_policy_value", - "client_tls_policy": "client_tls_policy_value", + "labels": {}, + "image_uri": "image_uri_value", + "image_digest": "image_digest_value", + "plugin_config_digest": "plugin_config_digest_value", } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = gcn_endpoint_policy.CreateEndpointPolicyRequest.meta.fields[ - "endpoint_policy" + test_field = extensibility.CreateWasmPluginVersionRequest.meta.fields[ + "wasm_plugin_version" ] def get_message_fields(field): @@ -39281,7 +43472,7 @@ def get_message_fields(field): # For each item in the sample request, create a list of sub fields which are not present at runtime # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["endpoint_policy"].items(): # pragma: NO COVER + for field, value in request_init["wasm_plugin_version"].items(): # pragma: NO COVER result = None is_repeated = False # For repeated fields @@ -39311,10 +43502,10 @@ def get_message_fields(field): subfield = subfield_to_delete.get("subfield") if subfield: if field_repeated: - for i in range(0, len(request_init["endpoint_policy"][field])): - del request_init["endpoint_policy"][field][i][subfield] + for i in range(0, len(request_init["wasm_plugin_version"][field])): + del request_init["wasm_plugin_version"][field][i][subfield] else: - del request_init["endpoint_policy"][field][subfield] + del request_init["wasm_plugin_version"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -39329,14 +43520,14 @@ def get_message_fields(field): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_endpoint_policy(request) + response = client.create_wasm_plugin_version(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_endpoint_policy_rest_interceptors(null_interceptor): +def test_create_wasm_plugin_version_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -39350,21 +43541,21 @@ def test_create_endpoint_policy_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_create_endpoint_policy" + transports.NetworkServicesRestInterceptor, "post_create_wasm_plugin_version" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_create_endpoint_policy_with_metadata", + "post_create_wasm_plugin_version_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_create_endpoint_policy" + transports.NetworkServicesRestInterceptor, "pre_create_wasm_plugin_version" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = gcn_endpoint_policy.CreateEndpointPolicyRequest.pb( - gcn_endpoint_policy.CreateEndpointPolicyRequest() + pb_message = extensibility.CreateWasmPluginVersionRequest.pb( + extensibility.CreateWasmPluginVersionRequest() ) transcode.return_value = { "method": "post", @@ -39379,7 +43570,7 @@ def test_create_endpoint_policy_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = gcn_endpoint_policy.CreateEndpointPolicyRequest() + request = extensibility.CreateWasmPluginVersionRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -39388,7 +43579,7 @@ def test_create_endpoint_policy_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.create_endpoint_policy( + client.create_wasm_plugin_version( request, metadata=[ ("key", "val"), @@ -39401,17 +43592,15 @@ def test_create_endpoint_policy_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_update_endpoint_policy_rest_bad_request( - request_type=gcn_endpoint_policy.UpdateEndpointPolicyRequest, +def test_delete_wasm_plugin_version_rest_bad_request( + request_type=extensibility.DeleteWasmPluginVersionRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "endpoint_policy": { - "name": "projects/sample1/locations/sample2/endpointPolicies/sample3" - } + "name": "projects/sample1/locations/sample2/wasmPlugins/sample3/versions/sample4" } request = request_type(**request_init) @@ -39428,119 +43617,25 @@ def test_update_endpoint_policy_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_endpoint_policy(request) + client.delete_wasm_plugin_version(request) @pytest.mark.parametrize( "request_type", [ - gcn_endpoint_policy.UpdateEndpointPolicyRequest, + extensibility.DeleteWasmPluginVersionRequest, dict, ], ) -def test_update_endpoint_policy_rest_call_success(request_type): +def test_delete_wasm_plugin_version_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "endpoint_policy": { - "name": "projects/sample1/locations/sample2/endpointPolicies/sample3" - } - } - request_init["endpoint_policy"] = { - "name": "projects/sample1/locations/sample2/endpointPolicies/sample3", - "create_time": {"seconds": 751, "nanos": 543}, - "update_time": {}, - "labels": {}, - "type_": 1, - "authorization_policy": "authorization_policy_value", - "endpoint_matcher": { - "metadata_label_matcher": { - "metadata_label_match_criteria": 1, - "metadata_labels": [ - { - "label_name": "label_name_value", - "label_value": "label_value_value", - } - ], - } - }, - "traffic_port_selector": {"ports": ["ports_value1", "ports_value2"]}, - "description": "description_value", - "server_tls_policy": "server_tls_policy_value", - "client_tls_policy": "client_tls_policy_value", + "name": "projects/sample1/locations/sample2/wasmPlugins/sample3/versions/sample4" } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = gcn_endpoint_policy.UpdateEndpointPolicyRequest.meta.fields[ - "endpoint_policy" - ] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["endpoint_policy"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["endpoint_policy"][field])): - del request_init["endpoint_policy"][field][i][subfield] - else: - del request_init["endpoint_policy"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -39555,14 +43650,14 @@ def get_message_fields(field): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_endpoint_policy(request) + response = client.delete_wasm_plugin_version(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_endpoint_policy_rest_interceptors(null_interceptor): +def test_delete_wasm_plugin_version_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -39576,21 +43671,21 @@ def test_update_endpoint_policy_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_update_endpoint_policy" + transports.NetworkServicesRestInterceptor, "post_delete_wasm_plugin_version" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_update_endpoint_policy_with_metadata", + "post_delete_wasm_plugin_version_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_update_endpoint_policy" + transports.NetworkServicesRestInterceptor, "pre_delete_wasm_plugin_version" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = gcn_endpoint_policy.UpdateEndpointPolicyRequest.pb( - gcn_endpoint_policy.UpdateEndpointPolicyRequest() + pb_message = extensibility.DeleteWasmPluginVersionRequest.pb( + extensibility.DeleteWasmPluginVersionRequest() ) transcode.return_value = { "method": "post", @@ -39605,7 +43700,7 @@ def test_update_endpoint_policy_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = gcn_endpoint_policy.UpdateEndpointPolicyRequest() + request = extensibility.DeleteWasmPluginVersionRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -39614,7 +43709,7 @@ def test_update_endpoint_policy_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.update_endpoint_policy( + client.delete_wasm_plugin_version( request, metadata=[ ("key", "val"), @@ -39627,16 +43722,14 @@ def test_update_endpoint_policy_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_delete_endpoint_policy_rest_bad_request( - request_type=endpoint_policy.DeleteEndpointPolicyRequest, +def test_list_wasm_plugins_rest_bad_request( + request_type=extensibility.ListWasmPluginsRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/endpointPolicies/sample3" - } + request_init = {"parent": "projects/sample1/locations/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -39652,47 +43745,53 @@ def test_delete_endpoint_policy_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_endpoint_policy(request) + client.list_wasm_plugins(request) @pytest.mark.parametrize( "request_type", [ - endpoint_policy.DeleteEndpointPolicyRequest, + extensibility.ListWasmPluginsRequest, dict, ], ) -def test_delete_endpoint_policy_rest_call_success(request_type): +def test_list_wasm_plugins_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/endpointPolicies/sample3" - } + request_init = {"parent": "projects/sample1/locations/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = extensibility.ListWasmPluginsResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = extensibility.ListWasmPluginsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_endpoint_policy(request) + response = client.list_wasm_plugins(request) # Establish that the response is the type that we expect. - json_return_value = json_format.MessageToJson(return_value) + assert isinstance(response, pagers.ListWasmPluginsPager) + assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_endpoint_policy_rest_interceptors(null_interceptor): +def test_list_wasm_plugins_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -39704,23 +43803,22 @@ def test_delete_endpoint_policy_rest_interceptors(null_interceptor): with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, - mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_delete_endpoint_policy" + transports.NetworkServicesRestInterceptor, "post_list_wasm_plugins" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_delete_endpoint_policy_with_metadata", + "post_list_wasm_plugins_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_delete_endpoint_policy" + transports.NetworkServicesRestInterceptor, "pre_list_wasm_plugins" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = endpoint_policy.DeleteEndpointPolicyRequest.pb( - endpoint_policy.DeleteEndpointPolicyRequest() + pb_message = extensibility.ListWasmPluginsRequest.pb( + extensibility.ListWasmPluginsRequest() ) transcode.return_value = { "method": "post", @@ -39732,19 +43830,24 @@ def test_delete_endpoint_policy_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = json_format.MessageToJson(operations_pb2.Operation()) + return_value = extensibility.ListWasmPluginsResponse.to_json( + extensibility.ListWasmPluginsResponse() + ) req.return_value.content = return_value - request = endpoint_policy.DeleteEndpointPolicyRequest() + request = extensibility.ListWasmPluginsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() - post_with_metadata.return_value = operations_pb2.Operation(), metadata + post.return_value = extensibility.ListWasmPluginsResponse() + post_with_metadata.return_value = ( + extensibility.ListWasmPluginsResponse(), + metadata, + ) - client.delete_endpoint_policy( + client.list_wasm_plugins( request, metadata=[ ("key", "val"), @@ -39757,14 +43860,14 @@ def test_delete_endpoint_policy_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_wasm_plugin_versions_rest_bad_request( - request_type=extensibility.ListWasmPluginVersionsRequest, +def test_get_wasm_plugin_rest_bad_request( + request_type=extensibility.GetWasmPluginRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2/wasmPlugins/sample3"} + request_init = {"name": "projects/sample1/locations/sample2/wasmPlugins/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -39780,31 +43883,32 @@ def test_list_wasm_plugin_versions_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_wasm_plugin_versions(request) + client.get_wasm_plugin(request) @pytest.mark.parametrize( "request_type", [ - extensibility.ListWasmPluginVersionsRequest, + extensibility.GetWasmPluginRequest, dict, ], ) -def test_list_wasm_plugin_versions_rest_call_success(request_type): +def test_get_wasm_plugin_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2/wasmPlugins/sample3"} + request_init = {"name": "projects/sample1/locations/sample2/wasmPlugins/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = extensibility.ListWasmPluginVersionsResponse( - next_page_token="next_page_token_value", - unreachable=["unreachable_value"], + return_value = extensibility.WasmPlugin( + name="name_value", + description="description_value", + main_version_id="main_version_id_value", ) # Wrap the value into a proper Response obj @@ -39812,21 +43916,22 @@ def test_list_wasm_plugin_versions_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = extensibility.ListWasmPluginVersionsResponse.pb(return_value) + return_value = extensibility.WasmPlugin.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_wasm_plugin_versions(request) + response = client.get_wasm_plugin(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListWasmPluginVersionsPager) - assert response.next_page_token == "next_page_token_value" - assert response.unreachable == ["unreachable_value"] + assert isinstance(response, extensibility.WasmPlugin) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.main_version_id == "main_version_id_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_wasm_plugin_versions_rest_interceptors(null_interceptor): +def test_get_wasm_plugin_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -39839,21 +43944,21 @@ def test_list_wasm_plugin_versions_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_list_wasm_plugin_versions" + transports.NetworkServicesRestInterceptor, "post_get_wasm_plugin" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_list_wasm_plugin_versions_with_metadata", + "post_get_wasm_plugin_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_list_wasm_plugin_versions" + transports.NetworkServicesRestInterceptor, "pre_get_wasm_plugin" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = extensibility.ListWasmPluginVersionsRequest.pb( - extensibility.ListWasmPluginVersionsRequest() + pb_message = extensibility.GetWasmPluginRequest.pb( + extensibility.GetWasmPluginRequest() ) transcode.return_value = { "method": "post", @@ -39865,24 +43970,19 @@ def test_list_wasm_plugin_versions_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = extensibility.ListWasmPluginVersionsResponse.to_json( - extensibility.ListWasmPluginVersionsResponse() - ) + return_value = extensibility.WasmPlugin.to_json(extensibility.WasmPlugin()) req.return_value.content = return_value - request = extensibility.ListWasmPluginVersionsRequest() + request = extensibility.GetWasmPluginRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = extensibility.ListWasmPluginVersionsResponse() - post_with_metadata.return_value = ( - extensibility.ListWasmPluginVersionsResponse(), - metadata, - ) + post.return_value = extensibility.WasmPlugin() + post_with_metadata.return_value = extensibility.WasmPlugin(), metadata - client.list_wasm_plugin_versions( + client.get_wasm_plugin( request, metadata=[ ("key", "val"), @@ -39895,16 +43995,14 @@ def test_list_wasm_plugin_versions_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_get_wasm_plugin_version_rest_bad_request( - request_type=extensibility.GetWasmPluginVersionRequest, +def test_create_wasm_plugin_rest_bad_request( + request_type=extensibility.CreateWasmPluginRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/wasmPlugins/sample3/versions/sample4" - } + request_init = {"parent": "projects/sample1/locations/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -39920,62 +44018,123 @@ def test_get_wasm_plugin_version_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_wasm_plugin_version(request) + client.create_wasm_plugin(request) @pytest.mark.parametrize( "request_type", [ - extensibility.GetWasmPluginVersionRequest, + extensibility.CreateWasmPluginRequest, dict, ], ) -def test_get_wasm_plugin_version_rest_call_success(request_type): +def test_create_wasm_plugin_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/wasmPlugins/sample3/versions/sample4" + request_init = {"parent": "projects/sample1/locations/sample2"} + request_init["wasm_plugin"] = { + "name": "name_value", + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "description": "description_value", + "labels": {}, + "main_version_id": "main_version_id_value", + "log_config": {"enable": True, "sample_rate": 0.1165, "min_log_level": 1}, + "versions": {}, + "used_by": [{"name": "name_value"}], } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = extensibility.CreateWasmPluginRequest.meta.fields["wasm_plugin"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["wasm_plugin"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["wasm_plugin"][field])): + del request_init["wasm_plugin"][field][i][subfield] + else: + del request_init["wasm_plugin"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = extensibility.WasmPluginVersion( - name="name_value", - description="description_value", - image_uri="image_uri_value", - image_digest="image_digest_value", - plugin_config_digest="plugin_config_digest_value", - plugin_config_data=b"plugin_config_data_blob", - ) + return_value = operations_pb2.Operation(name="operations/spam") # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = extensibility.WasmPluginVersion.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_wasm_plugin_version(request) + response = client.create_wasm_plugin(request) # Establish that the response is the type that we expect. - assert isinstance(response, extensibility.WasmPluginVersion) - assert response.name == "name_value" - assert response.description == "description_value" - assert response.image_uri == "image_uri_value" - assert response.image_digest == "image_digest_value" - assert response.plugin_config_digest == "plugin_config_digest_value" + json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_wasm_plugin_version_rest_interceptors(null_interceptor): +def test_create_wasm_plugin_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -39987,22 +44146,23 @@ def test_get_wasm_plugin_version_rest_interceptors(null_interceptor): with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_get_wasm_plugin_version" + transports.NetworkServicesRestInterceptor, "post_create_wasm_plugin" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_get_wasm_plugin_version_with_metadata", + "post_create_wasm_plugin_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_get_wasm_plugin_version" + transports.NetworkServicesRestInterceptor, "pre_create_wasm_plugin" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = extensibility.GetWasmPluginVersionRequest.pb( - extensibility.GetWasmPluginVersionRequest() + pb_message = extensibility.CreateWasmPluginRequest.pb( + extensibility.CreateWasmPluginRequest() ) transcode.return_value = { "method": "post", @@ -40014,21 +44174,19 @@ def test_get_wasm_plugin_version_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = extensibility.WasmPluginVersion.to_json( - extensibility.WasmPluginVersion() - ) + return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = extensibility.GetWasmPluginVersionRequest() + request = extensibility.CreateWasmPluginRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = extensibility.WasmPluginVersion() - post_with_metadata.return_value = extensibility.WasmPluginVersion(), metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.get_wasm_plugin_version( + client.create_wasm_plugin( request, metadata=[ ("key", "val"), @@ -40041,14 +44199,18 @@ def test_get_wasm_plugin_version_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_create_wasm_plugin_version_rest_bad_request( - request_type=extensibility.CreateWasmPluginVersionRequest, +def test_update_wasm_plugin_rest_bad_request( + request_type=extensibility.UpdateWasmPluginRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2/wasmPlugins/sample3"} + request_init = { + "wasm_plugin": { + "name": "projects/sample1/locations/sample2/wasmPlugins/sample3" + } + } request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -40064,43 +44226,44 @@ def test_create_wasm_plugin_version_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_wasm_plugin_version(request) + client.update_wasm_plugin(request) @pytest.mark.parametrize( "request_type", [ - extensibility.CreateWasmPluginVersionRequest, + extensibility.UpdateWasmPluginRequest, dict, ], ) -def test_create_wasm_plugin_version_rest_call_success(request_type): +def test_update_wasm_plugin_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2/wasmPlugins/sample3"} - request_init["wasm_plugin_version"] = { - "plugin_config_data": b"plugin_config_data_blob", - "plugin_config_uri": "plugin_config_uri_value", - "name": "name_value", + request_init = { + "wasm_plugin": { + "name": "projects/sample1/locations/sample2/wasmPlugins/sample3" + } + } + request_init["wasm_plugin"] = { + "name": "projects/sample1/locations/sample2/wasmPlugins/sample3", "create_time": {"seconds": 751, "nanos": 543}, "update_time": {}, "description": "description_value", "labels": {}, - "image_uri": "image_uri_value", - "image_digest": "image_digest_value", - "plugin_config_digest": "plugin_config_digest_value", + "main_version_id": "main_version_id_value", + "log_config": {"enable": True, "sample_rate": 0.1165, "min_log_level": 1}, + "versions": {}, + "used_by": [{"name": "name_value"}], } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = extensibility.CreateWasmPluginVersionRequest.meta.fields[ - "wasm_plugin_version" - ] + test_field = extensibility.UpdateWasmPluginRequest.meta.fields["wasm_plugin"] def get_message_fields(field): # Given a field which is a message (composite type), return a list with @@ -40128,7 +44291,7 @@ def get_message_fields(field): # For each item in the sample request, create a list of sub fields which are not present at runtime # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["wasm_plugin_version"].items(): # pragma: NO COVER + for field, value in request_init["wasm_plugin"].items(): # pragma: NO COVER result = None is_repeated = False # For repeated fields @@ -40158,10 +44321,10 @@ def get_message_fields(field): subfield = subfield_to_delete.get("subfield") if subfield: if field_repeated: - for i in range(0, len(request_init["wasm_plugin_version"][field])): - del request_init["wasm_plugin_version"][field][i][subfield] + for i in range(0, len(request_init["wasm_plugin"][field])): + del request_init["wasm_plugin"][field][i][subfield] else: - del request_init["wasm_plugin_version"][field][subfield] + del request_init["wasm_plugin"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -40176,14 +44339,14 @@ def get_message_fields(field): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_wasm_plugin_version(request) + response = client.update_wasm_plugin(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_wasm_plugin_version_rest_interceptors(null_interceptor): +def test_update_wasm_plugin_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -40197,21 +44360,21 @@ def test_create_wasm_plugin_version_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_create_wasm_plugin_version" + transports.NetworkServicesRestInterceptor, "post_update_wasm_plugin" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_create_wasm_plugin_version_with_metadata", + "post_update_wasm_plugin_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_create_wasm_plugin_version" + transports.NetworkServicesRestInterceptor, "pre_update_wasm_plugin" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = extensibility.CreateWasmPluginVersionRequest.pb( - extensibility.CreateWasmPluginVersionRequest() + pb_message = extensibility.UpdateWasmPluginRequest.pb( + extensibility.UpdateWasmPluginRequest() ) transcode.return_value = { "method": "post", @@ -40226,7 +44389,7 @@ def test_create_wasm_plugin_version_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = extensibility.CreateWasmPluginVersionRequest() + request = extensibility.UpdateWasmPluginRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -40235,7 +44398,7 @@ def test_create_wasm_plugin_version_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.create_wasm_plugin_version( + client.update_wasm_plugin( request, metadata=[ ("key", "val"), @@ -40248,16 +44411,14 @@ def test_create_wasm_plugin_version_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_delete_wasm_plugin_version_rest_bad_request( - request_type=extensibility.DeleteWasmPluginVersionRequest, +def test_delete_wasm_plugin_rest_bad_request( + request_type=extensibility.DeleteWasmPluginRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/wasmPlugins/sample3/versions/sample4" - } + request_init = {"name": "projects/sample1/locations/sample2/wasmPlugins/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -40273,25 +44434,23 @@ def test_delete_wasm_plugin_version_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_wasm_plugin_version(request) + client.delete_wasm_plugin(request) @pytest.mark.parametrize( "request_type", [ - extensibility.DeleteWasmPluginVersionRequest, + extensibility.DeleteWasmPluginRequest, dict, ], ) -def test_delete_wasm_plugin_version_rest_call_success(request_type): +def test_delete_wasm_plugin_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/wasmPlugins/sample3/versions/sample4" - } + request_init = {"name": "projects/sample1/locations/sample2/wasmPlugins/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -40306,14 +44465,14 @@ def test_delete_wasm_plugin_version_rest_call_success(request_type): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_wasm_plugin_version(request) + response = client.delete_wasm_plugin(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_wasm_plugin_version_rest_interceptors(null_interceptor): +def test_delete_wasm_plugin_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -40327,21 +44486,21 @@ def test_delete_wasm_plugin_version_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_delete_wasm_plugin_version" + transports.NetworkServicesRestInterceptor, "post_delete_wasm_plugin" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_delete_wasm_plugin_version_with_metadata", + "post_delete_wasm_plugin_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_delete_wasm_plugin_version" + transports.NetworkServicesRestInterceptor, "pre_delete_wasm_plugin" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = extensibility.DeleteWasmPluginVersionRequest.pb( - extensibility.DeleteWasmPluginVersionRequest() + pb_message = extensibility.DeleteWasmPluginRequest.pb( + extensibility.DeleteWasmPluginRequest() ) transcode.return_value = { "method": "post", @@ -40356,7 +44515,7 @@ def test_delete_wasm_plugin_version_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = extensibility.DeleteWasmPluginVersionRequest() + request = extensibility.DeleteWasmPluginRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -40365,7 +44524,7 @@ def test_delete_wasm_plugin_version_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.delete_wasm_plugin_version( + client.delete_wasm_plugin( request, metadata=[ ("key", "val"), @@ -40378,9 +44537,7 @@ def test_delete_wasm_plugin_version_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_wasm_plugins_rest_bad_request( - request_type=extensibility.ListWasmPluginsRequest, -): +def test_list_gateways_rest_bad_request(request_type=gateway.ListGatewaysRequest): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -40401,17 +44558,17 @@ def test_list_wasm_plugins_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_wasm_plugins(request) + client.list_gateways(request) @pytest.mark.parametrize( "request_type", [ - extensibility.ListWasmPluginsRequest, + gateway.ListGatewaysRequest, dict, ], ) -def test_list_wasm_plugins_rest_call_success(request_type): +def test_list_gateways_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -40423,7 +44580,7 @@ def test_list_wasm_plugins_rest_call_success(request_type): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = extensibility.ListWasmPluginsResponse( + return_value = gateway.ListGatewaysResponse( next_page_token="next_page_token_value", unreachable=["unreachable_value"], ) @@ -40433,21 +44590,21 @@ def test_list_wasm_plugins_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = extensibility.ListWasmPluginsResponse.pb(return_value) + return_value = gateway.ListGatewaysResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_wasm_plugins(request) + response = client.list_gateways(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListWasmPluginsPager) + assert isinstance(response, pagers.ListGatewaysPager) assert response.next_page_token == "next_page_token_value" assert response.unreachable == ["unreachable_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_wasm_plugins_rest_interceptors(null_interceptor): +def test_list_gateways_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -40460,22 +44617,20 @@ def test_list_wasm_plugins_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_list_wasm_plugins" + transports.NetworkServicesRestInterceptor, "post_list_gateways" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_list_wasm_plugins_with_metadata", + "post_list_gateways_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_list_wasm_plugins" + transports.NetworkServicesRestInterceptor, "pre_list_gateways" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = extensibility.ListWasmPluginsRequest.pb( - extensibility.ListWasmPluginsRequest() - ) + pb_message = gateway.ListGatewaysRequest.pb(gateway.ListGatewaysRequest()) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -40486,24 +44641,21 @@ def test_list_wasm_plugins_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = extensibility.ListWasmPluginsResponse.to_json( - extensibility.ListWasmPluginsResponse() + return_value = gateway.ListGatewaysResponse.to_json( + gateway.ListGatewaysResponse() ) req.return_value.content = return_value - request = extensibility.ListWasmPluginsRequest() + request = gateway.ListGatewaysRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = extensibility.ListWasmPluginsResponse() - post_with_metadata.return_value = ( - extensibility.ListWasmPluginsResponse(), - metadata, - ) + post.return_value = gateway.ListGatewaysResponse() + post_with_metadata.return_value = gateway.ListGatewaysResponse(), metadata - client.list_wasm_plugins( + client.list_gateways( request, metadata=[ ("key", "val"), @@ -40516,14 +44668,12 @@ def test_list_wasm_plugins_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_get_wasm_plugin_rest_bad_request( - request_type=extensibility.GetWasmPluginRequest, -): +def test_get_gateway_rest_bad_request(request_type=gateway.GetGatewayRequest): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/wasmPlugins/sample3"} + request_init = {"name": "projects/sample1/locations/sample2/gateways/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -40539,32 +44689,46 @@ def test_get_wasm_plugin_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_wasm_plugin(request) + client.get_gateway(request) @pytest.mark.parametrize( "request_type", [ - extensibility.GetWasmPluginRequest, + gateway.GetGatewayRequest, dict, ], ) -def test_get_wasm_plugin_rest_call_success(request_type): +def test_get_gateway_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/wasmPlugins/sample3"} + request_init = {"name": "projects/sample1/locations/sample2/gateways/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = extensibility.WasmPlugin( + return_value = gateway.Gateway( name="name_value", + self_link="self_link_value", description="description_value", - main_version_id="main_version_id_value", + type_=gateway.Gateway.Type.OPEN_MESH, + addresses=["addresses_value"], + ports=[568], + all_ports=True, + scope="scope_value", + server_tls_policy="server_tls_policy_value", + certificate_urls=["certificate_urls_value"], + gateway_security_policy="gateway_security_policy_value", + network="network_value", + subnetwork="subnetwork_value", + ip_version=gateway.Gateway.IpVersion.IPV4, + envoy_headers=common.EnvoyHeaders.NONE, + routing_mode=gateway.Gateway.RoutingMode.NEXT_HOP_ROUTING_MODE, + allow_global_access=True, ) # Wrap the value into a proper Response obj @@ -40572,22 +44736,36 @@ def test_get_wasm_plugin_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = extensibility.WasmPlugin.pb(return_value) + return_value = gateway.Gateway.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_wasm_plugin(request) + response = client.get_gateway(request) # Establish that the response is the type that we expect. - assert isinstance(response, extensibility.WasmPlugin) + assert isinstance(response, gateway.Gateway) assert response.name == "name_value" + assert response.self_link == "self_link_value" assert response.description == "description_value" - assert response.main_version_id == "main_version_id_value" + assert response.type_ == gateway.Gateway.Type.OPEN_MESH + assert response.addresses == ["addresses_value"] + assert response.ports == [568] + assert response.all_ports is True + assert response.scope == "scope_value" + assert response.server_tls_policy == "server_tls_policy_value" + assert response.certificate_urls == ["certificate_urls_value"] + assert response.gateway_security_policy == "gateway_security_policy_value" + assert response.network == "network_value" + assert response.subnetwork == "subnetwork_value" + assert response.ip_version == gateway.Gateway.IpVersion.IPV4 + assert response.envoy_headers == common.EnvoyHeaders.NONE + assert response.routing_mode == gateway.Gateway.RoutingMode.NEXT_HOP_ROUTING_MODE + assert response.allow_global_access is True @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_wasm_plugin_rest_interceptors(null_interceptor): +def test_get_gateway_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -40600,22 +44778,19 @@ def test_get_wasm_plugin_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_get_wasm_plugin" + transports.NetworkServicesRestInterceptor, "post_get_gateway" ) as post, mock.patch.object( - transports.NetworkServicesRestInterceptor, - "post_get_wasm_plugin_with_metadata", + transports.NetworkServicesRestInterceptor, "post_get_gateway_with_metadata" ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_get_wasm_plugin" + transports.NetworkServicesRestInterceptor, "pre_get_gateway" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = extensibility.GetWasmPluginRequest.pb( - extensibility.GetWasmPluginRequest() - ) + pb_message = gateway.GetGatewayRequest.pb(gateway.GetGatewayRequest()) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -40626,19 +44801,19 @@ def test_get_wasm_plugin_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = extensibility.WasmPlugin.to_json(extensibility.WasmPlugin()) + return_value = gateway.Gateway.to_json(gateway.Gateway()) req.return_value.content = return_value - request = extensibility.GetWasmPluginRequest() + request = gateway.GetGatewayRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = extensibility.WasmPlugin() - post_with_metadata.return_value = extensibility.WasmPlugin(), metadata + post.return_value = gateway.Gateway() + post_with_metadata.return_value = gateway.Gateway(), metadata - client.get_wasm_plugin( + client.get_gateway( request, metadata=[ ("key", "val"), @@ -40651,9 +44826,7 @@ def test_get_wasm_plugin_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_create_wasm_plugin_rest_bad_request( - request_type=extensibility.CreateWasmPluginRequest, -): +def test_create_gateway_rest_bad_request(request_type=gcn_gateway.CreateGatewayRequest): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -40674,40 +44847,51 @@ def test_create_wasm_plugin_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_wasm_plugin(request) + client.create_gateway(request) @pytest.mark.parametrize( "request_type", [ - extensibility.CreateWasmPluginRequest, + gcn_gateway.CreateGatewayRequest, dict, ], ) -def test_create_wasm_plugin_rest_call_success(request_type): +def test_create_gateway_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = {"parent": "projects/sample1/locations/sample2"} - request_init["wasm_plugin"] = { + request_init["gateway"] = { "name": "name_value", + "self_link": "self_link_value", "create_time": {"seconds": 751, "nanos": 543}, "update_time": {}, - "description": "description_value", "labels": {}, - "main_version_id": "main_version_id_value", - "log_config": {"enable": True, "sample_rate": 0.1165, "min_log_level": 1}, - "versions": {}, - "used_by": [{"name": "name_value"}], + "description": "description_value", + "type_": 1, + "addresses": ["addresses_value1", "addresses_value2"], + "ports": [569, 570], + "all_ports": True, + "scope": "scope_value", + "server_tls_policy": "server_tls_policy_value", + "certificate_urls": ["certificate_urls_value1", "certificate_urls_value2"], + "gateway_security_policy": "gateway_security_policy_value", + "network": "network_value", + "subnetwork": "subnetwork_value", + "ip_version": 1, + "envoy_headers": 1, + "routing_mode": 1, + "allow_global_access": True, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = extensibility.CreateWasmPluginRequest.meta.fields["wasm_plugin"] + test_field = gcn_gateway.CreateGatewayRequest.meta.fields["gateway"] def get_message_fields(field): # Given a field which is a message (composite type), return a list with @@ -40735,7 +44919,7 @@ def get_message_fields(field): # For each item in the sample request, create a list of sub fields which are not present at runtime # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["wasm_plugin"].items(): # pragma: NO COVER + for field, value in request_init["gateway"].items(): # pragma: NO COVER result = None is_repeated = False # For repeated fields @@ -40765,10 +44949,10 @@ def get_message_fields(field): subfield = subfield_to_delete.get("subfield") if subfield: if field_repeated: - for i in range(0, len(request_init["wasm_plugin"][field])): - del request_init["wasm_plugin"][field][i][subfield] + for i in range(0, len(request_init["gateway"][field])): + del request_init["gateway"][field][i][subfield] else: - del request_init["wasm_plugin"][field][subfield] + del request_init["gateway"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -40783,14 +44967,14 @@ def get_message_fields(field): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_wasm_plugin(request) + response = client.create_gateway(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_wasm_plugin_rest_interceptors(null_interceptor): +def test_create_gateway_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -40804,21 +44988,21 @@ def test_create_wasm_plugin_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_create_wasm_plugin" + transports.NetworkServicesRestInterceptor, "post_create_gateway" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_create_wasm_plugin_with_metadata", + "post_create_gateway_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_create_wasm_plugin" + transports.NetworkServicesRestInterceptor, "pre_create_gateway" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = extensibility.CreateWasmPluginRequest.pb( - extensibility.CreateWasmPluginRequest() + pb_message = gcn_gateway.CreateGatewayRequest.pb( + gcn_gateway.CreateGatewayRequest() ) transcode.return_value = { "method": "post", @@ -40833,7 +45017,7 @@ def test_create_wasm_plugin_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = extensibility.CreateWasmPluginRequest() + request = gcn_gateway.CreateGatewayRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -40842,7 +45026,7 @@ def test_create_wasm_plugin_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.create_wasm_plugin( + client.create_gateway( request, metadata=[ ("key", "val"), @@ -40855,17 +45039,13 @@ def test_create_wasm_plugin_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_update_wasm_plugin_rest_bad_request( - request_type=extensibility.UpdateWasmPluginRequest, -): +def test_update_gateway_rest_bad_request(request_type=gcn_gateway.UpdateGatewayRequest): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "wasm_plugin": { - "name": "projects/sample1/locations/sample2/wasmPlugins/sample3" - } + "gateway": {"name": "projects/sample1/locations/sample2/gateways/sample3"} } request = request_type(**request_init) @@ -40882,44 +45062,53 @@ def test_update_wasm_plugin_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_wasm_plugin(request) + client.update_gateway(request) @pytest.mark.parametrize( "request_type", [ - extensibility.UpdateWasmPluginRequest, + gcn_gateway.UpdateGatewayRequest, dict, ], ) -def test_update_wasm_plugin_rest_call_success(request_type): +def test_update_gateway_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "wasm_plugin": { - "name": "projects/sample1/locations/sample2/wasmPlugins/sample3" - } + "gateway": {"name": "projects/sample1/locations/sample2/gateways/sample3"} } - request_init["wasm_plugin"] = { - "name": "projects/sample1/locations/sample2/wasmPlugins/sample3", + request_init["gateway"] = { + "name": "projects/sample1/locations/sample2/gateways/sample3", + "self_link": "self_link_value", "create_time": {"seconds": 751, "nanos": 543}, "update_time": {}, - "description": "description_value", "labels": {}, - "main_version_id": "main_version_id_value", - "log_config": {"enable": True, "sample_rate": 0.1165, "min_log_level": 1}, - "versions": {}, - "used_by": [{"name": "name_value"}], + "description": "description_value", + "type_": 1, + "addresses": ["addresses_value1", "addresses_value2"], + "ports": [569, 570], + "all_ports": True, + "scope": "scope_value", + "server_tls_policy": "server_tls_policy_value", + "certificate_urls": ["certificate_urls_value1", "certificate_urls_value2"], + "gateway_security_policy": "gateway_security_policy_value", + "network": "network_value", + "subnetwork": "subnetwork_value", + "ip_version": 1, + "envoy_headers": 1, + "routing_mode": 1, + "allow_global_access": True, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = extensibility.UpdateWasmPluginRequest.meta.fields["wasm_plugin"] + test_field = gcn_gateway.UpdateGatewayRequest.meta.fields["gateway"] def get_message_fields(field): # Given a field which is a message (composite type), return a list with @@ -40947,7 +45136,7 @@ def get_message_fields(field): # For each item in the sample request, create a list of sub fields which are not present at runtime # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["wasm_plugin"].items(): # pragma: NO COVER + for field, value in request_init["gateway"].items(): # pragma: NO COVER result = None is_repeated = False # For repeated fields @@ -40977,10 +45166,10 @@ def get_message_fields(field): subfield = subfield_to_delete.get("subfield") if subfield: if field_repeated: - for i in range(0, len(request_init["wasm_plugin"][field])): - del request_init["wasm_plugin"][field][i][subfield] + for i in range(0, len(request_init["gateway"][field])): + del request_init["gateway"][field][i][subfield] else: - del request_init["wasm_plugin"][field][subfield] + del request_init["gateway"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -40995,14 +45184,14 @@ def get_message_fields(field): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_wasm_plugin(request) + response = client.update_gateway(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_wasm_plugin_rest_interceptors(null_interceptor): +def test_update_gateway_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -41016,21 +45205,21 @@ def test_update_wasm_plugin_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_update_wasm_plugin" + transports.NetworkServicesRestInterceptor, "post_update_gateway" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_update_wasm_plugin_with_metadata", + "post_update_gateway_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_update_wasm_plugin" + transports.NetworkServicesRestInterceptor, "pre_update_gateway" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = extensibility.UpdateWasmPluginRequest.pb( - extensibility.UpdateWasmPluginRequest() + pb_message = gcn_gateway.UpdateGatewayRequest.pb( + gcn_gateway.UpdateGatewayRequest() ) transcode.return_value = { "method": "post", @@ -41045,7 +45234,7 @@ def test_update_wasm_plugin_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = extensibility.UpdateWasmPluginRequest() + request = gcn_gateway.UpdateGatewayRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -41054,7 +45243,7 @@ def test_update_wasm_plugin_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.update_wasm_plugin( + client.update_gateway( request, metadata=[ ("key", "val"), @@ -41067,14 +45256,12 @@ def test_update_wasm_plugin_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_delete_wasm_plugin_rest_bad_request( - request_type=extensibility.DeleteWasmPluginRequest, -): +def test_delete_gateway_rest_bad_request(request_type=gateway.DeleteGatewayRequest): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/wasmPlugins/sample3"} + request_init = {"name": "projects/sample1/locations/sample2/gateways/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -41090,23 +45277,23 @@ def test_delete_wasm_plugin_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_wasm_plugin(request) + client.delete_gateway(request) @pytest.mark.parametrize( "request_type", [ - extensibility.DeleteWasmPluginRequest, + gateway.DeleteGatewayRequest, dict, ], ) -def test_delete_wasm_plugin_rest_call_success(request_type): +def test_delete_gateway_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/wasmPlugins/sample3"} + request_init = {"name": "projects/sample1/locations/sample2/gateways/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -41121,14 +45308,14 @@ def test_delete_wasm_plugin_rest_call_success(request_type): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_wasm_plugin(request) + response = client.delete_gateway(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_wasm_plugin_rest_interceptors(null_interceptor): +def test_delete_gateway_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -41142,22 +45329,20 @@ def test_delete_wasm_plugin_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_delete_wasm_plugin" + transports.NetworkServicesRestInterceptor, "post_delete_gateway" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_delete_wasm_plugin_with_metadata", + "post_delete_gateway_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_delete_wasm_plugin" + transports.NetworkServicesRestInterceptor, "pre_delete_gateway" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = extensibility.DeleteWasmPluginRequest.pb( - extensibility.DeleteWasmPluginRequest() - ) + pb_message = gateway.DeleteGatewayRequest.pb(gateway.DeleteGatewayRequest()) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -41171,7 +45356,7 @@ def test_delete_wasm_plugin_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = extensibility.DeleteWasmPluginRequest() + request = gateway.DeleteGatewayRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -41180,7 +45365,7 @@ def test_delete_wasm_plugin_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.delete_wasm_plugin( + client.delete_gateway( request, metadata=[ ("key", "val"), @@ -41193,7 +45378,9 @@ def test_delete_wasm_plugin_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_gateways_rest_bad_request(request_type=gateway.ListGatewaysRequest): +def test_list_grpc_routes_rest_bad_request( + request_type=grpc_route.ListGrpcRoutesRequest, +): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -41214,17 +45401,17 @@ def test_list_gateways_rest_bad_request(request_type=gateway.ListGatewaysRequest response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_gateways(request) + client.list_grpc_routes(request) @pytest.mark.parametrize( "request_type", [ - gateway.ListGatewaysRequest, + grpc_route.ListGrpcRoutesRequest, dict, ], ) -def test_list_gateways_rest_call_success(request_type): +def test_list_grpc_routes_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -41236,7 +45423,7 @@ def test_list_gateways_rest_call_success(request_type): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = gateway.ListGatewaysResponse( + return_value = grpc_route.ListGrpcRoutesResponse( next_page_token="next_page_token_value", unreachable=["unreachable_value"], ) @@ -41246,21 +45433,21 @@ def test_list_gateways_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = gateway.ListGatewaysResponse.pb(return_value) + return_value = grpc_route.ListGrpcRoutesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_gateways(request) + response = client.list_grpc_routes(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListGatewaysPager) + assert isinstance(response, pagers.ListGrpcRoutesPager) assert response.next_page_token == "next_page_token_value" assert response.unreachable == ["unreachable_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_gateways_rest_interceptors(null_interceptor): +def test_list_grpc_routes_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -41273,20 +45460,22 @@ def test_list_gateways_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_list_gateways" + transports.NetworkServicesRestInterceptor, "post_list_grpc_routes" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_list_gateways_with_metadata", + "post_list_grpc_routes_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_list_gateways" + transports.NetworkServicesRestInterceptor, "pre_list_grpc_routes" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = gateway.ListGatewaysRequest.pb(gateway.ListGatewaysRequest()) + pb_message = grpc_route.ListGrpcRoutesRequest.pb( + grpc_route.ListGrpcRoutesRequest() + ) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -41297,21 +45486,21 @@ def test_list_gateways_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = gateway.ListGatewaysResponse.to_json( - gateway.ListGatewaysResponse() + return_value = grpc_route.ListGrpcRoutesResponse.to_json( + grpc_route.ListGrpcRoutesResponse() ) req.return_value.content = return_value - request = gateway.ListGatewaysRequest() + request = grpc_route.ListGrpcRoutesRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = gateway.ListGatewaysResponse() - post_with_metadata.return_value = gateway.ListGatewaysResponse(), metadata + post.return_value = grpc_route.ListGrpcRoutesResponse() + post_with_metadata.return_value = grpc_route.ListGrpcRoutesResponse(), metadata - client.list_gateways( + client.list_grpc_routes( request, metadata=[ ("key", "val"), @@ -41324,12 +45513,12 @@ def test_list_gateways_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_get_gateway_rest_bad_request(request_type=gateway.GetGatewayRequest): +def test_get_grpc_route_rest_bad_request(request_type=grpc_route.GetGrpcRouteRequest): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/gateways/sample3"} + request_init = {"name": "projects/sample1/locations/sample2/grpcRoutes/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -41345,44 +45534,35 @@ def test_get_gateway_rest_bad_request(request_type=gateway.GetGatewayRequest): response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_gateway(request) + client.get_grpc_route(request) @pytest.mark.parametrize( "request_type", [ - gateway.GetGatewayRequest, + grpc_route.GetGrpcRouteRequest, dict, ], ) -def test_get_gateway_rest_call_success(request_type): +def test_get_grpc_route_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/gateways/sample3"} + request_init = {"name": "projects/sample1/locations/sample2/grpcRoutes/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = gateway.Gateway( + return_value = grpc_route.GrpcRoute( name="name_value", self_link="self_link_value", description="description_value", - type_=gateway.Gateway.Type.OPEN_MESH, - addresses=["addresses_value"], - ports=[568], - scope="scope_value", - server_tls_policy="server_tls_policy_value", - certificate_urls=["certificate_urls_value"], - gateway_security_policy="gateway_security_policy_value", - network="network_value", - subnetwork="subnetwork_value", - ip_version=gateway.Gateway.IpVersion.IPV4, - envoy_headers=common.EnvoyHeaders.NONE, - routing_mode=gateway.Gateway.RoutingMode.NEXT_HOP_ROUTING_MODE, + hostnames=["hostnames_value"], + meshes=["meshes_value"], + gateways=["gateways_value"], ) # Wrap the value into a proper Response obj @@ -41390,34 +45570,25 @@ def test_get_gateway_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = gateway.Gateway.pb(return_value) + return_value = grpc_route.GrpcRoute.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_gateway(request) + response = client.get_grpc_route(request) # Establish that the response is the type that we expect. - assert isinstance(response, gateway.Gateway) + assert isinstance(response, grpc_route.GrpcRoute) assert response.name == "name_value" assert response.self_link == "self_link_value" assert response.description == "description_value" - assert response.type_ == gateway.Gateway.Type.OPEN_MESH - assert response.addresses == ["addresses_value"] - assert response.ports == [568] - assert response.scope == "scope_value" - assert response.server_tls_policy == "server_tls_policy_value" - assert response.certificate_urls == ["certificate_urls_value"] - assert response.gateway_security_policy == "gateway_security_policy_value" - assert response.network == "network_value" - assert response.subnetwork == "subnetwork_value" - assert response.ip_version == gateway.Gateway.IpVersion.IPV4 - assert response.envoy_headers == common.EnvoyHeaders.NONE - assert response.routing_mode == gateway.Gateway.RoutingMode.NEXT_HOP_ROUTING_MODE + assert response.hostnames == ["hostnames_value"] + assert response.meshes == ["meshes_value"] + assert response.gateways == ["gateways_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_gateway_rest_interceptors(null_interceptor): +def test_get_grpc_route_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -41430,19 +45601,20 @@ def test_get_gateway_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_get_gateway" + transports.NetworkServicesRestInterceptor, "post_get_grpc_route" ) as post, mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_get_gateway_with_metadata" + transports.NetworkServicesRestInterceptor, + "post_get_grpc_route_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_get_gateway" + transports.NetworkServicesRestInterceptor, "pre_get_grpc_route" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = gateway.GetGatewayRequest.pb(gateway.GetGatewayRequest()) + pb_message = grpc_route.GetGrpcRouteRequest.pb(grpc_route.GetGrpcRouteRequest()) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -41453,19 +45625,19 @@ def test_get_gateway_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = gateway.Gateway.to_json(gateway.Gateway()) + return_value = grpc_route.GrpcRoute.to_json(grpc_route.GrpcRoute()) req.return_value.content = return_value - request = gateway.GetGatewayRequest() + request = grpc_route.GetGrpcRouteRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = gateway.Gateway() - post_with_metadata.return_value = gateway.Gateway(), metadata + post.return_value = grpc_route.GrpcRoute() + post_with_metadata.return_value = grpc_route.GrpcRoute(), metadata - client.get_gateway( + client.get_grpc_route( request, metadata=[ ("key", "val"), @@ -41478,7 +45650,9 @@ def test_get_gateway_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_create_gateway_rest_bad_request(request_type=gcn_gateway.CreateGatewayRequest): +def test_create_grpc_route_rest_bad_request( + request_type=gcn_grpc_route.CreateGrpcRouteRequest, +): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -41499,49 +45673,79 @@ def test_create_gateway_rest_bad_request(request_type=gcn_gateway.CreateGatewayR response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_gateway(request) + client.create_grpc_route(request) @pytest.mark.parametrize( "request_type", [ - gcn_gateway.CreateGatewayRequest, + gcn_grpc_route.CreateGrpcRouteRequest, dict, ], ) -def test_create_gateway_rest_call_success(request_type): +def test_create_grpc_route_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = {"parent": "projects/sample1/locations/sample2"} - request_init["gateway"] = { + request_init["grpc_route"] = { "name": "name_value", "self_link": "self_link_value", "create_time": {"seconds": 751, "nanos": 543}, "update_time": {}, "labels": {}, "description": "description_value", - "type_": 1, - "addresses": ["addresses_value1", "addresses_value2"], - "ports": [569, 570], - "scope": "scope_value", - "server_tls_policy": "server_tls_policy_value", - "certificate_urls": ["certificate_urls_value1", "certificate_urls_value2"], - "gateway_security_policy": "gateway_security_policy_value", - "network": "network_value", - "subnetwork": "subnetwork_value", - "ip_version": 1, - "envoy_headers": 1, - "routing_mode": 1, + "hostnames": ["hostnames_value1", "hostnames_value2"], + "meshes": ["meshes_value1", "meshes_value2"], + "gateways": ["gateways_value1", "gateways_value2"], + "rules": [ + { + "matches": [ + { + "method": { + "type_": 1, + "grpc_service": "grpc_service_value", + "grpc_method": "grpc_method_value", + "case_sensitive": True, + }, + "headers": [ + {"type_": 1, "key": "key_value", "value": "value_value"} + ], + } + ], + "action": { + "destinations": [ + {"service_name": "service_name_value", "weight": 648} + ], + "fault_injection_policy": { + "delay": { + "fixed_delay": {"seconds": 751, "nanos": 543}, + "percentage": 1054, + }, + "abort": {"http_status": 1219, "percentage": 1054}, + }, + "timeout": {}, + "retry_policy": { + "retry_conditions": [ + "retry_conditions_value1", + "retry_conditions_value2", + ], + "num_retries": 1197, + }, + "stateful_session_affinity": {"cookie_ttl": {}}, + "idle_timeout": {}, + }, + } + ], } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = gcn_gateway.CreateGatewayRequest.meta.fields["gateway"] + test_field = gcn_grpc_route.CreateGrpcRouteRequest.meta.fields["grpc_route"] def get_message_fields(field): # Given a field which is a message (composite type), return a list with @@ -41569,7 +45773,7 @@ def get_message_fields(field): # For each item in the sample request, create a list of sub fields which are not present at runtime # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["gateway"].items(): # pragma: NO COVER + for field, value in request_init["grpc_route"].items(): # pragma: NO COVER result = None is_repeated = False # For repeated fields @@ -41599,10 +45803,10 @@ def get_message_fields(field): subfield = subfield_to_delete.get("subfield") if subfield: if field_repeated: - for i in range(0, len(request_init["gateway"][field])): - del request_init["gateway"][field][i][subfield] + for i in range(0, len(request_init["grpc_route"][field])): + del request_init["grpc_route"][field][i][subfield] else: - del request_init["gateway"][field][subfield] + del request_init["grpc_route"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -41617,14 +45821,14 @@ def get_message_fields(field): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_gateway(request) + response = client.create_grpc_route(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_gateway_rest_interceptors(null_interceptor): +def test_create_grpc_route_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -41638,21 +45842,21 @@ def test_create_gateway_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_create_gateway" + transports.NetworkServicesRestInterceptor, "post_create_grpc_route" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_create_gateway_with_metadata", + "post_create_grpc_route_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_create_gateway" + transports.NetworkServicesRestInterceptor, "pre_create_grpc_route" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = gcn_gateway.CreateGatewayRequest.pb( - gcn_gateway.CreateGatewayRequest() + pb_message = gcn_grpc_route.CreateGrpcRouteRequest.pb( + gcn_grpc_route.CreateGrpcRouteRequest() ) transcode.return_value = { "method": "post", @@ -41667,7 +45871,7 @@ def test_create_gateway_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = gcn_gateway.CreateGatewayRequest() + request = gcn_grpc_route.CreateGrpcRouteRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -41676,7 +45880,7 @@ def test_create_gateway_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.create_gateway( + client.create_grpc_route( request, metadata=[ ("key", "val"), @@ -41689,13 +45893,15 @@ def test_create_gateway_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_update_gateway_rest_bad_request(request_type=gcn_gateway.UpdateGatewayRequest): +def test_update_grpc_route_rest_bad_request( + request_type=gcn_grpc_route.UpdateGrpcRouteRequest, +): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "gateway": {"name": "projects/sample1/locations/sample2/gateways/sample3"} + "grpc_route": {"name": "projects/sample1/locations/sample2/grpcRoutes/sample3"} } request = request_type(**request_init) @@ -41712,51 +45918,81 @@ def test_update_gateway_rest_bad_request(request_type=gcn_gateway.UpdateGatewayR response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_gateway(request) + client.update_grpc_route(request) @pytest.mark.parametrize( "request_type", [ - gcn_gateway.UpdateGatewayRequest, + gcn_grpc_route.UpdateGrpcRouteRequest, dict, ], ) -def test_update_gateway_rest_call_success(request_type): +def test_update_grpc_route_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "gateway": {"name": "projects/sample1/locations/sample2/gateways/sample3"} + "grpc_route": {"name": "projects/sample1/locations/sample2/grpcRoutes/sample3"} } - request_init["gateway"] = { - "name": "projects/sample1/locations/sample2/gateways/sample3", + request_init["grpc_route"] = { + "name": "projects/sample1/locations/sample2/grpcRoutes/sample3", "self_link": "self_link_value", "create_time": {"seconds": 751, "nanos": 543}, "update_time": {}, "labels": {}, "description": "description_value", - "type_": 1, - "addresses": ["addresses_value1", "addresses_value2"], - "ports": [569, 570], - "scope": "scope_value", - "server_tls_policy": "server_tls_policy_value", - "certificate_urls": ["certificate_urls_value1", "certificate_urls_value2"], - "gateway_security_policy": "gateway_security_policy_value", - "network": "network_value", - "subnetwork": "subnetwork_value", - "ip_version": 1, - "envoy_headers": 1, - "routing_mode": 1, + "hostnames": ["hostnames_value1", "hostnames_value2"], + "meshes": ["meshes_value1", "meshes_value2"], + "gateways": ["gateways_value1", "gateways_value2"], + "rules": [ + { + "matches": [ + { + "method": { + "type_": 1, + "grpc_service": "grpc_service_value", + "grpc_method": "grpc_method_value", + "case_sensitive": True, + }, + "headers": [ + {"type_": 1, "key": "key_value", "value": "value_value"} + ], + } + ], + "action": { + "destinations": [ + {"service_name": "service_name_value", "weight": 648} + ], + "fault_injection_policy": { + "delay": { + "fixed_delay": {"seconds": 751, "nanos": 543}, + "percentage": 1054, + }, + "abort": {"http_status": 1219, "percentage": 1054}, + }, + "timeout": {}, + "retry_policy": { + "retry_conditions": [ + "retry_conditions_value1", + "retry_conditions_value2", + ], + "num_retries": 1197, + }, + "stateful_session_affinity": {"cookie_ttl": {}}, + "idle_timeout": {}, + }, + } + ], } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = gcn_gateway.UpdateGatewayRequest.meta.fields["gateway"] + test_field = gcn_grpc_route.UpdateGrpcRouteRequest.meta.fields["grpc_route"] def get_message_fields(field): # Given a field which is a message (composite type), return a list with @@ -41784,7 +46020,7 @@ def get_message_fields(field): # For each item in the sample request, create a list of sub fields which are not present at runtime # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["gateway"].items(): # pragma: NO COVER + for field, value in request_init["grpc_route"].items(): # pragma: NO COVER result = None is_repeated = False # For repeated fields @@ -41814,10 +46050,10 @@ def get_message_fields(field): subfield = subfield_to_delete.get("subfield") if subfield: if field_repeated: - for i in range(0, len(request_init["gateway"][field])): - del request_init["gateway"][field][i][subfield] + for i in range(0, len(request_init["grpc_route"][field])): + del request_init["grpc_route"][field][i][subfield] else: - del request_init["gateway"][field][subfield] + del request_init["grpc_route"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -41832,14 +46068,14 @@ def get_message_fields(field): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_gateway(request) + response = client.update_grpc_route(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_gateway_rest_interceptors(null_interceptor): +def test_update_grpc_route_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -41853,21 +46089,21 @@ def test_update_gateway_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_update_gateway" + transports.NetworkServicesRestInterceptor, "post_update_grpc_route" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_update_gateway_with_metadata", + "post_update_grpc_route_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_update_gateway" + transports.NetworkServicesRestInterceptor, "pre_update_grpc_route" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = gcn_gateway.UpdateGatewayRequest.pb( - gcn_gateway.UpdateGatewayRequest() + pb_message = gcn_grpc_route.UpdateGrpcRouteRequest.pb( + gcn_grpc_route.UpdateGrpcRouteRequest() ) transcode.return_value = { "method": "post", @@ -41882,7 +46118,7 @@ def test_update_gateway_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = gcn_gateway.UpdateGatewayRequest() + request = gcn_grpc_route.UpdateGrpcRouteRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -41891,7 +46127,7 @@ def test_update_gateway_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.update_gateway( + client.update_grpc_route( request, metadata=[ ("key", "val"), @@ -41904,12 +46140,14 @@ def test_update_gateway_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_delete_gateway_rest_bad_request(request_type=gateway.DeleteGatewayRequest): +def test_delete_grpc_route_rest_bad_request( + request_type=grpc_route.DeleteGrpcRouteRequest, +): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/gateways/sample3"} + request_init = {"name": "projects/sample1/locations/sample2/grpcRoutes/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -41925,23 +46163,23 @@ def test_delete_gateway_rest_bad_request(request_type=gateway.DeleteGatewayReque response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_gateway(request) + client.delete_grpc_route(request) @pytest.mark.parametrize( "request_type", [ - gateway.DeleteGatewayRequest, + grpc_route.DeleteGrpcRouteRequest, dict, ], ) -def test_delete_gateway_rest_call_success(request_type): +def test_delete_grpc_route_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/gateways/sample3"} + request_init = {"name": "projects/sample1/locations/sample2/grpcRoutes/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -41956,14 +46194,14 @@ def test_delete_gateway_rest_call_success(request_type): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_gateway(request) + response = client.delete_grpc_route(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_gateway_rest_interceptors(null_interceptor): +def test_delete_grpc_route_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -41977,20 +46215,22 @@ def test_delete_gateway_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_delete_gateway" + transports.NetworkServicesRestInterceptor, "post_delete_grpc_route" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_delete_gateway_with_metadata", + "post_delete_grpc_route_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_delete_gateway" + transports.NetworkServicesRestInterceptor, "pre_delete_grpc_route" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = gateway.DeleteGatewayRequest.pb(gateway.DeleteGatewayRequest()) + pb_message = grpc_route.DeleteGrpcRouteRequest.pb( + grpc_route.DeleteGrpcRouteRequest() + ) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -42004,7 +46244,7 @@ def test_delete_gateway_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = gateway.DeleteGatewayRequest() + request = grpc_route.DeleteGrpcRouteRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -42013,7 +46253,7 @@ def test_delete_gateway_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.delete_gateway( + client.delete_grpc_route( request, metadata=[ ("key", "val"), @@ -42026,8 +46266,8 @@ def test_delete_gateway_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_grpc_routes_rest_bad_request( - request_type=grpc_route.ListGrpcRoutesRequest, +def test_list_http_routes_rest_bad_request( + request_type=http_route.ListHttpRoutesRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" @@ -42049,17 +46289,17 @@ def test_list_grpc_routes_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_grpc_routes(request) + client.list_http_routes(request) @pytest.mark.parametrize( "request_type", [ - grpc_route.ListGrpcRoutesRequest, + http_route.ListHttpRoutesRequest, dict, ], ) -def test_list_grpc_routes_rest_call_success(request_type): +def test_list_http_routes_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -42071,7 +46311,7 @@ def test_list_grpc_routes_rest_call_success(request_type): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = grpc_route.ListGrpcRoutesResponse( + return_value = http_route.ListHttpRoutesResponse( next_page_token="next_page_token_value", unreachable=["unreachable_value"], ) @@ -42081,21 +46321,21 @@ def test_list_grpc_routes_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = grpc_route.ListGrpcRoutesResponse.pb(return_value) + return_value = http_route.ListHttpRoutesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_grpc_routes(request) + response = client.list_http_routes(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListGrpcRoutesPager) + assert isinstance(response, pagers.ListHttpRoutesPager) assert response.next_page_token == "next_page_token_value" assert response.unreachable == ["unreachable_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_grpc_routes_rest_interceptors(null_interceptor): +def test_list_http_routes_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -42108,21 +46348,21 @@ def test_list_grpc_routes_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_list_grpc_routes" + transports.NetworkServicesRestInterceptor, "post_list_http_routes" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_list_grpc_routes_with_metadata", + "post_list_http_routes_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_list_grpc_routes" + transports.NetworkServicesRestInterceptor, "pre_list_http_routes" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = grpc_route.ListGrpcRoutesRequest.pb( - grpc_route.ListGrpcRoutesRequest() + pb_message = http_route.ListHttpRoutesRequest.pb( + http_route.ListHttpRoutesRequest() ) transcode.return_value = { "method": "post", @@ -42134,21 +46374,21 @@ def test_list_grpc_routes_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = grpc_route.ListGrpcRoutesResponse.to_json( - grpc_route.ListGrpcRoutesResponse() + return_value = http_route.ListHttpRoutesResponse.to_json( + http_route.ListHttpRoutesResponse() ) req.return_value.content = return_value - request = grpc_route.ListGrpcRoutesRequest() + request = http_route.ListHttpRoutesRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = grpc_route.ListGrpcRoutesResponse() - post_with_metadata.return_value = grpc_route.ListGrpcRoutesResponse(), metadata + post.return_value = http_route.ListHttpRoutesResponse() + post_with_metadata.return_value = http_route.ListHttpRoutesResponse(), metadata - client.list_grpc_routes( + client.list_http_routes( request, metadata=[ ("key", "val"), @@ -42161,12 +46401,12 @@ def test_list_grpc_routes_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_get_grpc_route_rest_bad_request(request_type=grpc_route.GetGrpcRouteRequest): +def test_get_http_route_rest_bad_request(request_type=http_route.GetHttpRouteRequest): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/grpcRoutes/sample3"} + request_init = {"name": "projects/sample1/locations/sample2/httpRoutes/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -42182,29 +46422,29 @@ def test_get_grpc_route_rest_bad_request(request_type=grpc_route.GetGrpcRouteReq response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_grpc_route(request) + client.get_http_route(request) @pytest.mark.parametrize( "request_type", [ - grpc_route.GetGrpcRouteRequest, + http_route.GetHttpRouteRequest, dict, ], ) -def test_get_grpc_route_rest_call_success(request_type): +def test_get_http_route_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/grpcRoutes/sample3"} + request_init = {"name": "projects/sample1/locations/sample2/httpRoutes/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = grpc_route.GrpcRoute( + return_value = http_route.HttpRoute( name="name_value", self_link="self_link_value", description="description_value", @@ -42218,15 +46458,15 @@ def test_get_grpc_route_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = grpc_route.GrpcRoute.pb(return_value) + return_value = http_route.HttpRoute.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_grpc_route(request) + response = client.get_http_route(request) # Establish that the response is the type that we expect. - assert isinstance(response, grpc_route.GrpcRoute) + assert isinstance(response, http_route.HttpRoute) assert response.name == "name_value" assert response.self_link == "self_link_value" assert response.description == "description_value" @@ -42236,7 +46476,7 @@ def test_get_grpc_route_rest_call_success(request_type): @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_grpc_route_rest_interceptors(null_interceptor): +def test_get_http_route_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -42249,20 +46489,20 @@ def test_get_grpc_route_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_get_grpc_route" + transports.NetworkServicesRestInterceptor, "post_get_http_route" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_get_grpc_route_with_metadata", + "post_get_http_route_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_get_grpc_route" + transports.NetworkServicesRestInterceptor, "pre_get_http_route" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = grpc_route.GetGrpcRouteRequest.pb(grpc_route.GetGrpcRouteRequest()) + pb_message = http_route.GetHttpRouteRequest.pb(http_route.GetHttpRouteRequest()) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -42273,19 +46513,19 @@ def test_get_grpc_route_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = grpc_route.GrpcRoute.to_json(grpc_route.GrpcRoute()) + return_value = http_route.HttpRoute.to_json(http_route.HttpRoute()) req.return_value.content = return_value - request = grpc_route.GetGrpcRouteRequest() + request = http_route.GetHttpRouteRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = grpc_route.GrpcRoute() - post_with_metadata.return_value = grpc_route.GrpcRoute(), metadata + post.return_value = http_route.HttpRoute() + post_with_metadata.return_value = http_route.HttpRoute(), metadata - client.get_grpc_route( + client.get_http_route( request, metadata=[ ("key", "val"), @@ -42298,8 +46538,8 @@ def test_get_grpc_route_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_create_grpc_route_rest_bad_request( - request_type=gcn_grpc_route.CreateGrpcRouteRequest, +def test_create_http_route_rest_bad_request( + request_type=gcn_http_route.CreateHttpRouteRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" @@ -42321,52 +46561,85 @@ def test_create_grpc_route_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_grpc_route(request) + client.create_http_route(request) @pytest.mark.parametrize( "request_type", [ - gcn_grpc_route.CreateGrpcRouteRequest, + gcn_http_route.CreateHttpRouteRequest, dict, ], ) -def test_create_grpc_route_rest_call_success(request_type): +def test_create_http_route_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = {"parent": "projects/sample1/locations/sample2"} - request_init["grpc_route"] = { + request_init["http_route"] = { "name": "name_value", "self_link": "self_link_value", + "description": "description_value", "create_time": {"seconds": 751, "nanos": 543}, "update_time": {}, - "labels": {}, - "description": "description_value", "hostnames": ["hostnames_value1", "hostnames_value2"], "meshes": ["meshes_value1", "meshes_value2"], "gateways": ["gateways_value1", "gateways_value2"], + "labels": {}, "rules": [ { "matches": [ { - "method": { - "type_": 1, - "grpc_service": "grpc_service_value", - "grpc_method": "grpc_method_value", - "case_sensitive": True, - }, + "full_path_match": "full_path_match_value", + "prefix_match": "prefix_match_value", + "regex_match": "regex_match_value", + "ignore_case": True, "headers": [ - {"type_": 1, "key": "key_value", "value": "value_value"} + { + "exact_match": "exact_match_value", + "regex_match": "regex_match_value", + "prefix_match": "prefix_match_value", + "present_match": True, + "suffix_match": "suffix_match_value", + "range_match": {"start": 558, "end": 311}, + "header": "header_value", + "invert_match": True, + } + ], + "query_parameters": [ + { + "exact_match": "exact_match_value", + "regex_match": "regex_match_value", + "present_match": True, + "query_parameter": "query_parameter_value", + } ], } ], "action": { "destinations": [ - {"service_name": "service_name_value", "weight": 648} + { + "service_name": "service_name_value", + "weight": 648, + "request_header_modifier": { + "set": {}, + "add": {}, + "remove": ["remove_value1", "remove_value2"], + }, + "response_header_modifier": {}, + } ], + "redirect": { + "host_redirect": "host_redirect_value", + "path_redirect": "path_redirect_value", + "prefix_rewrite": "prefix_rewrite_value", + "response_code": 1, + "https_redirect": True, + "strip_query": True, + "port_redirect": 1398, + }, "fault_injection_policy": { "delay": { "fixed_delay": {"seconds": 751, "nanos": 543}, @@ -42374,6 +46647,12 @@ def test_create_grpc_route_rest_call_success(request_type): }, "abort": {"http_status": 1219, "percentage": 1054}, }, + "request_header_modifier": {}, + "response_header_modifier": {}, + "url_rewrite": { + "path_prefix_rewrite": "path_prefix_rewrite_value", + "host_rewrite": "host_rewrite_value", + }, "timeout": {}, "retry_policy": { "retry_conditions": [ @@ -42381,8 +46660,43 @@ def test_create_grpc_route_rest_call_success(request_type): "retry_conditions_value2", ], "num_retries": 1197, + "per_try_timeout": {}, + }, + "request_mirror_policy": { + "destination": {}, + "mirror_percent": 0.1515, + }, + "cors_policy": { + "allow_origins": [ + "allow_origins_value1", + "allow_origins_value2", + ], + "allow_origin_regexes": [ + "allow_origin_regexes_value1", + "allow_origin_regexes_value2", + ], + "allow_methods": [ + "allow_methods_value1", + "allow_methods_value2", + ], + "allow_headers": [ + "allow_headers_value1", + "allow_headers_value2", + ], + "expose_headers": [ + "expose_headers_value1", + "expose_headers_value2", + ], + "max_age": "max_age_value", + "allow_credentials": True, + "disabled": True, }, "stateful_session_affinity": {"cookie_ttl": {}}, + "direct_response": { + "string_body": "string_body_value", + "bytes_body": b"bytes_body_blob", + "status": 676, + }, "idle_timeout": {}, }, } @@ -42393,7 +46707,7 @@ def test_create_grpc_route_rest_call_success(request_type): # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = gcn_grpc_route.CreateGrpcRouteRequest.meta.fields["grpc_route"] + test_field = gcn_http_route.CreateHttpRouteRequest.meta.fields["http_route"] def get_message_fields(field): # Given a field which is a message (composite type), return a list with @@ -42421,7 +46735,7 @@ def get_message_fields(field): # For each item in the sample request, create a list of sub fields which are not present at runtime # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["grpc_route"].items(): # pragma: NO COVER + for field, value in request_init["http_route"].items(): # pragma: NO COVER result = None is_repeated = False # For repeated fields @@ -42451,10 +46765,10 @@ def get_message_fields(field): subfield = subfield_to_delete.get("subfield") if subfield: if field_repeated: - for i in range(0, len(request_init["grpc_route"][field])): - del request_init["grpc_route"][field][i][subfield] + for i in range(0, len(request_init["http_route"][field])): + del request_init["http_route"][field][i][subfield] else: - del request_init["grpc_route"][field][subfield] + del request_init["http_route"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -42469,14 +46783,14 @@ def get_message_fields(field): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_grpc_route(request) + response = client.create_http_route(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_grpc_route_rest_interceptors(null_interceptor): +def test_create_http_route_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -42490,21 +46804,21 @@ def test_create_grpc_route_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_create_grpc_route" + transports.NetworkServicesRestInterceptor, "post_create_http_route" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_create_grpc_route_with_metadata", + "post_create_http_route_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_create_grpc_route" + transports.NetworkServicesRestInterceptor, "pre_create_http_route" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = gcn_grpc_route.CreateGrpcRouteRequest.pb( - gcn_grpc_route.CreateGrpcRouteRequest() + pb_message = gcn_http_route.CreateHttpRouteRequest.pb( + gcn_http_route.CreateHttpRouteRequest() ) transcode.return_value = { "method": "post", @@ -42519,7 +46833,7 @@ def test_create_grpc_route_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = gcn_grpc_route.CreateGrpcRouteRequest() + request = gcn_http_route.CreateHttpRouteRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -42528,7 +46842,7 @@ def test_create_grpc_route_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.create_grpc_route( + client.create_http_route( request, metadata=[ ("key", "val"), @@ -42541,15 +46855,15 @@ def test_create_grpc_route_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_update_grpc_route_rest_bad_request( - request_type=gcn_grpc_route.UpdateGrpcRouteRequest, +def test_update_http_route_rest_bad_request( + request_type=gcn_http_route.UpdateHttpRouteRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "grpc_route": {"name": "projects/sample1/locations/sample2/grpcRoutes/sample3"} + "http_route": {"name": "projects/sample1/locations/sample2/httpRoutes/sample3"} } request = request_type(**request_init) @@ -42566,54 +46880,87 @@ def test_update_grpc_route_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_grpc_route(request) + client.update_http_route(request) @pytest.mark.parametrize( "request_type", [ - gcn_grpc_route.UpdateGrpcRouteRequest, + gcn_http_route.UpdateHttpRouteRequest, dict, ], ) -def test_update_grpc_route_rest_call_success(request_type): +def test_update_http_route_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "grpc_route": {"name": "projects/sample1/locations/sample2/grpcRoutes/sample3"} + "http_route": {"name": "projects/sample1/locations/sample2/httpRoutes/sample3"} } - request_init["grpc_route"] = { - "name": "projects/sample1/locations/sample2/grpcRoutes/sample3", + request_init["http_route"] = { + "name": "projects/sample1/locations/sample2/httpRoutes/sample3", "self_link": "self_link_value", + "description": "description_value", "create_time": {"seconds": 751, "nanos": 543}, "update_time": {}, - "labels": {}, - "description": "description_value", "hostnames": ["hostnames_value1", "hostnames_value2"], "meshes": ["meshes_value1", "meshes_value2"], "gateways": ["gateways_value1", "gateways_value2"], + "labels": {}, "rules": [ { "matches": [ { - "method": { - "type_": 1, - "grpc_service": "grpc_service_value", - "grpc_method": "grpc_method_value", - "case_sensitive": True, - }, + "full_path_match": "full_path_match_value", + "prefix_match": "prefix_match_value", + "regex_match": "regex_match_value", + "ignore_case": True, "headers": [ - {"type_": 1, "key": "key_value", "value": "value_value"} + { + "exact_match": "exact_match_value", + "regex_match": "regex_match_value", + "prefix_match": "prefix_match_value", + "present_match": True, + "suffix_match": "suffix_match_value", + "range_match": {"start": 558, "end": 311}, + "header": "header_value", + "invert_match": True, + } + ], + "query_parameters": [ + { + "exact_match": "exact_match_value", + "regex_match": "regex_match_value", + "present_match": True, + "query_parameter": "query_parameter_value", + } ], } ], "action": { "destinations": [ - {"service_name": "service_name_value", "weight": 648} + { + "service_name": "service_name_value", + "weight": 648, + "request_header_modifier": { + "set": {}, + "add": {}, + "remove": ["remove_value1", "remove_value2"], + }, + "response_header_modifier": {}, + } ], + "redirect": { + "host_redirect": "host_redirect_value", + "path_redirect": "path_redirect_value", + "prefix_rewrite": "prefix_rewrite_value", + "response_code": 1, + "https_redirect": True, + "strip_query": True, + "port_redirect": 1398, + }, "fault_injection_policy": { "delay": { "fixed_delay": {"seconds": 751, "nanos": 543}, @@ -42621,6 +46968,12 @@ def test_update_grpc_route_rest_call_success(request_type): }, "abort": {"http_status": 1219, "percentage": 1054}, }, + "request_header_modifier": {}, + "response_header_modifier": {}, + "url_rewrite": { + "path_prefix_rewrite": "path_prefix_rewrite_value", + "host_rewrite": "host_rewrite_value", + }, "timeout": {}, "retry_policy": { "retry_conditions": [ @@ -42628,8 +46981,43 @@ def test_update_grpc_route_rest_call_success(request_type): "retry_conditions_value2", ], "num_retries": 1197, + "per_try_timeout": {}, + }, + "request_mirror_policy": { + "destination": {}, + "mirror_percent": 0.1515, + }, + "cors_policy": { + "allow_origins": [ + "allow_origins_value1", + "allow_origins_value2", + ], + "allow_origin_regexes": [ + "allow_origin_regexes_value1", + "allow_origin_regexes_value2", + ], + "allow_methods": [ + "allow_methods_value1", + "allow_methods_value2", + ], + "allow_headers": [ + "allow_headers_value1", + "allow_headers_value2", + ], + "expose_headers": [ + "expose_headers_value1", + "expose_headers_value2", + ], + "max_age": "max_age_value", + "allow_credentials": True, + "disabled": True, }, "stateful_session_affinity": {"cookie_ttl": {}}, + "direct_response": { + "string_body": "string_body_value", + "bytes_body": b"bytes_body_blob", + "status": 676, + }, "idle_timeout": {}, }, } @@ -42640,7 +47028,7 @@ def test_update_grpc_route_rest_call_success(request_type): # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = gcn_grpc_route.UpdateGrpcRouteRequest.meta.fields["grpc_route"] + test_field = gcn_http_route.UpdateHttpRouteRequest.meta.fields["http_route"] def get_message_fields(field): # Given a field which is a message (composite type), return a list with @@ -42668,7 +47056,7 @@ def get_message_fields(field): # For each item in the sample request, create a list of sub fields which are not present at runtime # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["grpc_route"].items(): # pragma: NO COVER + for field, value in request_init["http_route"].items(): # pragma: NO COVER result = None is_repeated = False # For repeated fields @@ -42698,10 +47086,10 @@ def get_message_fields(field): subfield = subfield_to_delete.get("subfield") if subfield: if field_repeated: - for i in range(0, len(request_init["grpc_route"][field])): - del request_init["grpc_route"][field][i][subfield] + for i in range(0, len(request_init["http_route"][field])): + del request_init["http_route"][field][i][subfield] else: - del request_init["grpc_route"][field][subfield] + del request_init["http_route"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -42716,14 +47104,14 @@ def get_message_fields(field): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_grpc_route(request) + response = client.update_http_route(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_grpc_route_rest_interceptors(null_interceptor): +def test_update_http_route_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -42737,21 +47125,21 @@ def test_update_grpc_route_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_update_grpc_route" + transports.NetworkServicesRestInterceptor, "post_update_http_route" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_update_grpc_route_with_metadata", + "post_update_http_route_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_update_grpc_route" + transports.NetworkServicesRestInterceptor, "pre_update_http_route" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = gcn_grpc_route.UpdateGrpcRouteRequest.pb( - gcn_grpc_route.UpdateGrpcRouteRequest() + pb_message = gcn_http_route.UpdateHttpRouteRequest.pb( + gcn_http_route.UpdateHttpRouteRequest() ) transcode.return_value = { "method": "post", @@ -42766,7 +47154,7 @@ def test_update_grpc_route_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = gcn_grpc_route.UpdateGrpcRouteRequest() + request = gcn_http_route.UpdateHttpRouteRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -42775,7 +47163,7 @@ def test_update_grpc_route_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.update_grpc_route( + client.update_http_route( request, metadata=[ ("key", "val"), @@ -42788,14 +47176,14 @@ def test_update_grpc_route_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_delete_grpc_route_rest_bad_request( - request_type=grpc_route.DeleteGrpcRouteRequest, +def test_delete_http_route_rest_bad_request( + request_type=http_route.DeleteHttpRouteRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/grpcRoutes/sample3"} + request_init = {"name": "projects/sample1/locations/sample2/httpRoutes/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -42811,23 +47199,23 @@ def test_delete_grpc_route_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_grpc_route(request) + client.delete_http_route(request) @pytest.mark.parametrize( "request_type", [ - grpc_route.DeleteGrpcRouteRequest, + http_route.DeleteHttpRouteRequest, dict, ], ) -def test_delete_grpc_route_rest_call_success(request_type): +def test_delete_http_route_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/grpcRoutes/sample3"} + request_init = {"name": "projects/sample1/locations/sample2/httpRoutes/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -42842,14 +47230,14 @@ def test_delete_grpc_route_rest_call_success(request_type): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_grpc_route(request) + response = client.delete_http_route(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_grpc_route_rest_interceptors(null_interceptor): +def test_delete_http_route_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -42863,21 +47251,21 @@ def test_delete_grpc_route_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_delete_grpc_route" + transports.NetworkServicesRestInterceptor, "post_delete_http_route" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_delete_grpc_route_with_metadata", + "post_delete_http_route_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_delete_grpc_route" + transports.NetworkServicesRestInterceptor, "pre_delete_http_route" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = grpc_route.DeleteGrpcRouteRequest.pb( - grpc_route.DeleteGrpcRouteRequest() + pb_message = http_route.DeleteHttpRouteRequest.pb( + http_route.DeleteHttpRouteRequest() ) transcode.return_value = { "method": "post", @@ -42892,7 +47280,7 @@ def test_delete_grpc_route_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = grpc_route.DeleteGrpcRouteRequest() + request = http_route.DeleteHttpRouteRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -42901,7 +47289,7 @@ def test_delete_grpc_route_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.delete_grpc_route( + client.delete_http_route( request, metadata=[ ("key", "val"), @@ -42914,9 +47302,7 @@ def test_delete_grpc_route_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_http_routes_rest_bad_request( - request_type=http_route.ListHttpRoutesRequest, -): +def test_list_tcp_routes_rest_bad_request(request_type=tcp_route.ListTcpRoutesRequest): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -42937,17 +47323,17 @@ def test_list_http_routes_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_http_routes(request) + client.list_tcp_routes(request) @pytest.mark.parametrize( "request_type", [ - http_route.ListHttpRoutesRequest, + tcp_route.ListTcpRoutesRequest, dict, ], ) -def test_list_http_routes_rest_call_success(request_type): +def test_list_tcp_routes_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -42959,7 +47345,7 @@ def test_list_http_routes_rest_call_success(request_type): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = http_route.ListHttpRoutesResponse( + return_value = tcp_route.ListTcpRoutesResponse( next_page_token="next_page_token_value", unreachable=["unreachable_value"], ) @@ -42969,21 +47355,21 @@ def test_list_http_routes_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = http_route.ListHttpRoutesResponse.pb(return_value) + return_value = tcp_route.ListTcpRoutesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_http_routes(request) + response = client.list_tcp_routes(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListHttpRoutesPager) + assert isinstance(response, pagers.ListTcpRoutesPager) assert response.next_page_token == "next_page_token_value" assert response.unreachable == ["unreachable_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_http_routes_rest_interceptors(null_interceptor): +def test_list_tcp_routes_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -42996,22 +47382,20 @@ def test_list_http_routes_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_list_http_routes" + transports.NetworkServicesRestInterceptor, "post_list_tcp_routes" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_list_http_routes_with_metadata", + "post_list_tcp_routes_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_list_http_routes" + transports.NetworkServicesRestInterceptor, "pre_list_tcp_routes" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = http_route.ListHttpRoutesRequest.pb( - http_route.ListHttpRoutesRequest() - ) + pb_message = tcp_route.ListTcpRoutesRequest.pb(tcp_route.ListTcpRoutesRequest()) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -43022,21 +47406,21 @@ def test_list_http_routes_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = http_route.ListHttpRoutesResponse.to_json( - http_route.ListHttpRoutesResponse() + return_value = tcp_route.ListTcpRoutesResponse.to_json( + tcp_route.ListTcpRoutesResponse() ) req.return_value.content = return_value - request = http_route.ListHttpRoutesRequest() + request = tcp_route.ListTcpRoutesRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = http_route.ListHttpRoutesResponse() - post_with_metadata.return_value = http_route.ListHttpRoutesResponse(), metadata + post.return_value = tcp_route.ListTcpRoutesResponse() + post_with_metadata.return_value = tcp_route.ListTcpRoutesResponse(), metadata - client.list_http_routes( + client.list_tcp_routes( request, metadata=[ ("key", "val"), @@ -43049,12 +47433,12 @@ def test_list_http_routes_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_get_http_route_rest_bad_request(request_type=http_route.GetHttpRouteRequest): +def test_get_tcp_route_rest_bad_request(request_type=tcp_route.GetTcpRouteRequest): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/httpRoutes/sample3"} + request_init = {"name": "projects/sample1/locations/sample2/tcpRoutes/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -43070,33 +47454,32 @@ def test_get_http_route_rest_bad_request(request_type=http_route.GetHttpRouteReq response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_http_route(request) + client.get_tcp_route(request) @pytest.mark.parametrize( "request_type", [ - http_route.GetHttpRouteRequest, + tcp_route.GetTcpRouteRequest, dict, ], ) -def test_get_http_route_rest_call_success(request_type): +def test_get_tcp_route_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/httpRoutes/sample3"} + request_init = {"name": "projects/sample1/locations/sample2/tcpRoutes/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = http_route.HttpRoute( + return_value = tcp_route.TcpRoute( name="name_value", self_link="self_link_value", description="description_value", - hostnames=["hostnames_value"], meshes=["meshes_value"], gateways=["gateways_value"], ) @@ -43106,25 +47489,24 @@ def test_get_http_route_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = http_route.HttpRoute.pb(return_value) + return_value = tcp_route.TcpRoute.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_http_route(request) + response = client.get_tcp_route(request) # Establish that the response is the type that we expect. - assert isinstance(response, http_route.HttpRoute) + assert isinstance(response, tcp_route.TcpRoute) assert response.name == "name_value" assert response.self_link == "self_link_value" assert response.description == "description_value" - assert response.hostnames == ["hostnames_value"] assert response.meshes == ["meshes_value"] assert response.gateways == ["gateways_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_http_route_rest_interceptors(null_interceptor): +def test_get_tcp_route_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -43137,20 +47519,20 @@ def test_get_http_route_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_get_http_route" + transports.NetworkServicesRestInterceptor, "post_get_tcp_route" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_get_http_route_with_metadata", + "post_get_tcp_route_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_get_http_route" + transports.NetworkServicesRestInterceptor, "pre_get_tcp_route" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = http_route.GetHttpRouteRequest.pb(http_route.GetHttpRouteRequest()) + pb_message = tcp_route.GetTcpRouteRequest.pb(tcp_route.GetTcpRouteRequest()) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -43161,19 +47543,19 @@ def test_get_http_route_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = http_route.HttpRoute.to_json(http_route.HttpRoute()) + return_value = tcp_route.TcpRoute.to_json(tcp_route.TcpRoute()) req.return_value.content = return_value - request = http_route.GetHttpRouteRequest() + request = tcp_route.GetTcpRouteRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = http_route.HttpRoute() - post_with_metadata.return_value = http_route.HttpRoute(), metadata + post.return_value = tcp_route.TcpRoute() + post_with_metadata.return_value = tcp_route.TcpRoute(), metadata - client.get_http_route( + client.get_tcp_route( request, metadata=[ ("key", "val"), @@ -43186,8 +47568,8 @@ def test_get_http_route_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_create_http_route_rest_bad_request( - request_type=gcn_http_route.CreateHttpRouteRequest, +def test_create_tcp_route_rest_bad_request( + request_type=gcn_tcp_route.CreateTcpRouteRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" @@ -43209,153 +47591,51 @@ def test_create_http_route_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_http_route(request) + client.create_tcp_route(request) @pytest.mark.parametrize( "request_type", [ - gcn_http_route.CreateHttpRouteRequest, + gcn_tcp_route.CreateTcpRouteRequest, dict, ], ) -def test_create_http_route_rest_call_success(request_type): +def test_create_tcp_route_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = {"parent": "projects/sample1/locations/sample2"} - request_init["http_route"] = { + request_init["tcp_route"] = { "name": "name_value", "self_link": "self_link_value", - "description": "description_value", "create_time": {"seconds": 751, "nanos": 543}, "update_time": {}, - "hostnames": ["hostnames_value1", "hostnames_value2"], - "meshes": ["meshes_value1", "meshes_value2"], - "gateways": ["gateways_value1", "gateways_value2"], - "labels": {}, + "description": "description_value", "rules": [ { - "matches": [ - { - "full_path_match": "full_path_match_value", - "prefix_match": "prefix_match_value", - "regex_match": "regex_match_value", - "ignore_case": True, - "headers": [ - { - "exact_match": "exact_match_value", - "regex_match": "regex_match_value", - "prefix_match": "prefix_match_value", - "present_match": True, - "suffix_match": "suffix_match_value", - "range_match": {"start": 558, "end": 311}, - "header": "header_value", - "invert_match": True, - } - ], - "query_parameters": [ - { - "exact_match": "exact_match_value", - "regex_match": "regex_match_value", - "present_match": True, - "query_parameter": "query_parameter_value", - } - ], - } - ], + "matches": [{"address": "address_value", "port": "port_value"}], "action": { "destinations": [ - { - "service_name": "service_name_value", - "weight": 648, - "request_header_modifier": { - "set": {}, - "add": {}, - "remove": ["remove_value1", "remove_value2"], - }, - "response_header_modifier": {}, - } + {"service_name": "service_name_value", "weight": 648} ], - "redirect": { - "host_redirect": "host_redirect_value", - "path_redirect": "path_redirect_value", - "prefix_rewrite": "prefix_rewrite_value", - "response_code": 1, - "https_redirect": True, - "strip_query": True, - "port_redirect": 1398, - }, - "fault_injection_policy": { - "delay": { - "fixed_delay": {"seconds": 751, "nanos": 543}, - "percentage": 1054, - }, - "abort": {"http_status": 1219, "percentage": 1054}, - }, - "request_header_modifier": {}, - "response_header_modifier": {}, - "url_rewrite": { - "path_prefix_rewrite": "path_prefix_rewrite_value", - "host_rewrite": "host_rewrite_value", - }, - "timeout": {}, - "retry_policy": { - "retry_conditions": [ - "retry_conditions_value1", - "retry_conditions_value2", - ], - "num_retries": 1197, - "per_try_timeout": {}, - }, - "request_mirror_policy": { - "destination": {}, - "mirror_percent": 0.1515, - }, - "cors_policy": { - "allow_origins": [ - "allow_origins_value1", - "allow_origins_value2", - ], - "allow_origin_regexes": [ - "allow_origin_regexes_value1", - "allow_origin_regexes_value2", - ], - "allow_methods": [ - "allow_methods_value1", - "allow_methods_value2", - ], - "allow_headers": [ - "allow_headers_value1", - "allow_headers_value2", - ], - "expose_headers": [ - "expose_headers_value1", - "expose_headers_value2", - ], - "max_age": "max_age_value", - "allow_credentials": True, - "disabled": True, - }, - "stateful_session_affinity": {"cookie_ttl": {}}, - "direct_response": { - "string_body": "string_body_value", - "bytes_body": b"bytes_body_blob", - "status": 676, - }, - "idle_timeout": {}, + "original_destination": True, + "idle_timeout": {"seconds": 751, "nanos": 543}, }, } ], + "meshes": ["meshes_value1", "meshes_value2"], + "gateways": ["gateways_value1", "gateways_value2"], + "labels": {}, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = gcn_http_route.CreateHttpRouteRequest.meta.fields["http_route"] + test_field = gcn_tcp_route.CreateTcpRouteRequest.meta.fields["tcp_route"] def get_message_fields(field): # Given a field which is a message (composite type), return a list with @@ -43383,7 +47663,7 @@ def get_message_fields(field): # For each item in the sample request, create a list of sub fields which are not present at runtime # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["http_route"].items(): # pragma: NO COVER + for field, value in request_init["tcp_route"].items(): # pragma: NO COVER result = None is_repeated = False # For repeated fields @@ -43413,10 +47693,10 @@ def get_message_fields(field): subfield = subfield_to_delete.get("subfield") if subfield: if field_repeated: - for i in range(0, len(request_init["http_route"][field])): - del request_init["http_route"][field][i][subfield] + for i in range(0, len(request_init["tcp_route"][field])): + del request_init["tcp_route"][field][i][subfield] else: - del request_init["http_route"][field][subfield] + del request_init["tcp_route"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -43431,14 +47711,14 @@ def get_message_fields(field): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_http_route(request) + response = client.create_tcp_route(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_http_route_rest_interceptors(null_interceptor): +def test_create_tcp_route_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -43452,21 +47732,21 @@ def test_create_http_route_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_create_http_route" + transports.NetworkServicesRestInterceptor, "post_create_tcp_route" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_create_http_route_with_metadata", + "post_create_tcp_route_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_create_http_route" + transports.NetworkServicesRestInterceptor, "pre_create_tcp_route" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = gcn_http_route.CreateHttpRouteRequest.pb( - gcn_http_route.CreateHttpRouteRequest() + pb_message = gcn_tcp_route.CreateTcpRouteRequest.pb( + gcn_tcp_route.CreateTcpRouteRequest() ) transcode.return_value = { "method": "post", @@ -43481,7 +47761,7 @@ def test_create_http_route_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = gcn_http_route.CreateHttpRouteRequest() + request = gcn_tcp_route.CreateTcpRouteRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -43490,7 +47770,7 @@ def test_create_http_route_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.create_http_route( + client.create_tcp_route( request, metadata=[ ("key", "val"), @@ -43503,15 +47783,15 @@ def test_create_http_route_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_update_http_route_rest_bad_request( - request_type=gcn_http_route.UpdateHttpRouteRequest, +def test_update_tcp_route_rest_bad_request( + request_type=gcn_tcp_route.UpdateTcpRouteRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "http_route": {"name": "projects/sample1/locations/sample2/httpRoutes/sample3"} + "tcp_route": {"name": "projects/sample1/locations/sample2/tcpRoutes/sample3"} } request = request_type(**request_init) @@ -43528,155 +47808,53 @@ def test_update_http_route_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_http_route(request) + client.update_tcp_route(request) @pytest.mark.parametrize( "request_type", [ - gcn_http_route.UpdateHttpRouteRequest, + gcn_tcp_route.UpdateTcpRouteRequest, dict, ], ) -def test_update_http_route_rest_call_success(request_type): +def test_update_tcp_route_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "http_route": {"name": "projects/sample1/locations/sample2/httpRoutes/sample3"} + "tcp_route": {"name": "projects/sample1/locations/sample2/tcpRoutes/sample3"} } - request_init["http_route"] = { - "name": "projects/sample1/locations/sample2/httpRoutes/sample3", + request_init["tcp_route"] = { + "name": "projects/sample1/locations/sample2/tcpRoutes/sample3", "self_link": "self_link_value", - "description": "description_value", "create_time": {"seconds": 751, "nanos": 543}, "update_time": {}, - "hostnames": ["hostnames_value1", "hostnames_value2"], - "meshes": ["meshes_value1", "meshes_value2"], - "gateways": ["gateways_value1", "gateways_value2"], - "labels": {}, + "description": "description_value", "rules": [ { - "matches": [ - { - "full_path_match": "full_path_match_value", - "prefix_match": "prefix_match_value", - "regex_match": "regex_match_value", - "ignore_case": True, - "headers": [ - { - "exact_match": "exact_match_value", - "regex_match": "regex_match_value", - "prefix_match": "prefix_match_value", - "present_match": True, - "suffix_match": "suffix_match_value", - "range_match": {"start": 558, "end": 311}, - "header": "header_value", - "invert_match": True, - } - ], - "query_parameters": [ - { - "exact_match": "exact_match_value", - "regex_match": "regex_match_value", - "present_match": True, - "query_parameter": "query_parameter_value", - } - ], - } - ], + "matches": [{"address": "address_value", "port": "port_value"}], "action": { "destinations": [ - { - "service_name": "service_name_value", - "weight": 648, - "request_header_modifier": { - "set": {}, - "add": {}, - "remove": ["remove_value1", "remove_value2"], - }, - "response_header_modifier": {}, - } + {"service_name": "service_name_value", "weight": 648} ], - "redirect": { - "host_redirect": "host_redirect_value", - "path_redirect": "path_redirect_value", - "prefix_rewrite": "prefix_rewrite_value", - "response_code": 1, - "https_redirect": True, - "strip_query": True, - "port_redirect": 1398, - }, - "fault_injection_policy": { - "delay": { - "fixed_delay": {"seconds": 751, "nanos": 543}, - "percentage": 1054, - }, - "abort": {"http_status": 1219, "percentage": 1054}, - }, - "request_header_modifier": {}, - "response_header_modifier": {}, - "url_rewrite": { - "path_prefix_rewrite": "path_prefix_rewrite_value", - "host_rewrite": "host_rewrite_value", - }, - "timeout": {}, - "retry_policy": { - "retry_conditions": [ - "retry_conditions_value1", - "retry_conditions_value2", - ], - "num_retries": 1197, - "per_try_timeout": {}, - }, - "request_mirror_policy": { - "destination": {}, - "mirror_percent": 0.1515, - }, - "cors_policy": { - "allow_origins": [ - "allow_origins_value1", - "allow_origins_value2", - ], - "allow_origin_regexes": [ - "allow_origin_regexes_value1", - "allow_origin_regexes_value2", - ], - "allow_methods": [ - "allow_methods_value1", - "allow_methods_value2", - ], - "allow_headers": [ - "allow_headers_value1", - "allow_headers_value2", - ], - "expose_headers": [ - "expose_headers_value1", - "expose_headers_value2", - ], - "max_age": "max_age_value", - "allow_credentials": True, - "disabled": True, - }, - "stateful_session_affinity": {"cookie_ttl": {}}, - "direct_response": { - "string_body": "string_body_value", - "bytes_body": b"bytes_body_blob", - "status": 676, - }, - "idle_timeout": {}, + "original_destination": True, + "idle_timeout": {"seconds": 751, "nanos": 543}, }, } ], + "meshes": ["meshes_value1", "meshes_value2"], + "gateways": ["gateways_value1", "gateways_value2"], + "labels": {}, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = gcn_http_route.UpdateHttpRouteRequest.meta.fields["http_route"] + test_field = gcn_tcp_route.UpdateTcpRouteRequest.meta.fields["tcp_route"] def get_message_fields(field): # Given a field which is a message (composite type), return a list with @@ -43704,7 +47882,7 @@ def get_message_fields(field): # For each item in the sample request, create a list of sub fields which are not present at runtime # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["http_route"].items(): # pragma: NO COVER + for field, value in request_init["tcp_route"].items(): # pragma: NO COVER result = None is_repeated = False # For repeated fields @@ -43734,10 +47912,10 @@ def get_message_fields(field): subfield = subfield_to_delete.get("subfield") if subfield: if field_repeated: - for i in range(0, len(request_init["http_route"][field])): - del request_init["http_route"][field][i][subfield] + for i in range(0, len(request_init["tcp_route"][field])): + del request_init["tcp_route"][field][i][subfield] else: - del request_init["http_route"][field][subfield] + del request_init["tcp_route"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -43752,14 +47930,14 @@ def get_message_fields(field): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_http_route(request) + response = client.update_tcp_route(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_http_route_rest_interceptors(null_interceptor): +def test_update_tcp_route_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -43773,21 +47951,21 @@ def test_update_http_route_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_update_http_route" + transports.NetworkServicesRestInterceptor, "post_update_tcp_route" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_update_http_route_with_metadata", + "post_update_tcp_route_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_update_http_route" + transports.NetworkServicesRestInterceptor, "pre_update_tcp_route" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = gcn_http_route.UpdateHttpRouteRequest.pb( - gcn_http_route.UpdateHttpRouteRequest() + pb_message = gcn_tcp_route.UpdateTcpRouteRequest.pb( + gcn_tcp_route.UpdateTcpRouteRequest() ) transcode.return_value = { "method": "post", @@ -43802,7 +47980,7 @@ def test_update_http_route_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = gcn_http_route.UpdateHttpRouteRequest() + request = gcn_tcp_route.UpdateTcpRouteRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -43811,7 +47989,7 @@ def test_update_http_route_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.update_http_route( + client.update_tcp_route( request, metadata=[ ("key", "val"), @@ -43824,14 +48002,14 @@ def test_update_http_route_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_delete_http_route_rest_bad_request( - request_type=http_route.DeleteHttpRouteRequest, +def test_delete_tcp_route_rest_bad_request( + request_type=tcp_route.DeleteTcpRouteRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/httpRoutes/sample3"} + request_init = {"name": "projects/sample1/locations/sample2/tcpRoutes/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -43847,23 +48025,23 @@ def test_delete_http_route_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_http_route(request) + client.delete_tcp_route(request) @pytest.mark.parametrize( "request_type", [ - http_route.DeleteHttpRouteRequest, + tcp_route.DeleteTcpRouteRequest, dict, ], ) -def test_delete_http_route_rest_call_success(request_type): +def test_delete_tcp_route_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/httpRoutes/sample3"} + request_init = {"name": "projects/sample1/locations/sample2/tcpRoutes/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -43878,14 +48056,14 @@ def test_delete_http_route_rest_call_success(request_type): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_http_route(request) + response = client.delete_tcp_route(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_http_route_rest_interceptors(null_interceptor): +def test_delete_tcp_route_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -43899,21 +48077,21 @@ def test_delete_http_route_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_delete_http_route" + transports.NetworkServicesRestInterceptor, "post_delete_tcp_route" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_delete_http_route_with_metadata", + "post_delete_tcp_route_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_delete_http_route" + transports.NetworkServicesRestInterceptor, "pre_delete_tcp_route" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = http_route.DeleteHttpRouteRequest.pb( - http_route.DeleteHttpRouteRequest() + pb_message = tcp_route.DeleteTcpRouteRequest.pb( + tcp_route.DeleteTcpRouteRequest() ) transcode.return_value = { "method": "post", @@ -43928,7 +48106,7 @@ def test_delete_http_route_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = http_route.DeleteHttpRouteRequest() + request = tcp_route.DeleteTcpRouteRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -43937,7 +48115,7 @@ def test_delete_http_route_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.delete_http_route( + client.delete_tcp_route( request, metadata=[ ("key", "val"), @@ -43950,7 +48128,7 @@ def test_delete_http_route_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_tcp_routes_rest_bad_request(request_type=tcp_route.ListTcpRoutesRequest): +def test_list_tls_routes_rest_bad_request(request_type=tls_route.ListTlsRoutesRequest): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -43971,17 +48149,17 @@ def test_list_tcp_routes_rest_bad_request(request_type=tcp_route.ListTcpRoutesRe response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_tcp_routes(request) + client.list_tls_routes(request) @pytest.mark.parametrize( "request_type", [ - tcp_route.ListTcpRoutesRequest, + tls_route.ListTlsRoutesRequest, dict, ], ) -def test_list_tcp_routes_rest_call_success(request_type): +def test_list_tls_routes_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -43993,7 +48171,7 @@ def test_list_tcp_routes_rest_call_success(request_type): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = tcp_route.ListTcpRoutesResponse( + return_value = tls_route.ListTlsRoutesResponse( next_page_token="next_page_token_value", unreachable=["unreachable_value"], ) @@ -44003,21 +48181,21 @@ def test_list_tcp_routes_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = tcp_route.ListTcpRoutesResponse.pb(return_value) + return_value = tls_route.ListTlsRoutesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_tcp_routes(request) + response = client.list_tls_routes(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListTcpRoutesPager) + assert isinstance(response, pagers.ListTlsRoutesPager) assert response.next_page_token == "next_page_token_value" assert response.unreachable == ["unreachable_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_tcp_routes_rest_interceptors(null_interceptor): +def test_list_tls_routes_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -44030,20 +48208,20 @@ def test_list_tcp_routes_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_list_tcp_routes" + transports.NetworkServicesRestInterceptor, "post_list_tls_routes" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_list_tcp_routes_with_metadata", + "post_list_tls_routes_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_list_tcp_routes" + transports.NetworkServicesRestInterceptor, "pre_list_tls_routes" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = tcp_route.ListTcpRoutesRequest.pb(tcp_route.ListTcpRoutesRequest()) + pb_message = tls_route.ListTlsRoutesRequest.pb(tls_route.ListTlsRoutesRequest()) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -44054,21 +48232,21 @@ def test_list_tcp_routes_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = tcp_route.ListTcpRoutesResponse.to_json( - tcp_route.ListTcpRoutesResponse() + return_value = tls_route.ListTlsRoutesResponse.to_json( + tls_route.ListTlsRoutesResponse() ) req.return_value.content = return_value - request = tcp_route.ListTcpRoutesRequest() + request = tls_route.ListTlsRoutesRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = tcp_route.ListTcpRoutesResponse() - post_with_metadata.return_value = tcp_route.ListTcpRoutesResponse(), metadata + post.return_value = tls_route.ListTlsRoutesResponse() + post_with_metadata.return_value = tls_route.ListTlsRoutesResponse(), metadata - client.list_tcp_routes( + client.list_tls_routes( request, metadata=[ ("key", "val"), @@ -44081,12 +48259,12 @@ def test_list_tcp_routes_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_get_tcp_route_rest_bad_request(request_type=tcp_route.GetTcpRouteRequest): +def test_get_tls_route_rest_bad_request(request_type=tls_route.GetTlsRouteRequest): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/tcpRoutes/sample3"} + request_init = {"name": "projects/sample1/locations/sample2/tlsRoutes/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -44102,34 +48280,35 @@ def test_get_tcp_route_rest_bad_request(request_type=tcp_route.GetTcpRouteReques response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_tcp_route(request) + client.get_tls_route(request) @pytest.mark.parametrize( "request_type", [ - tcp_route.GetTcpRouteRequest, + tls_route.GetTlsRouteRequest, dict, ], ) -def test_get_tcp_route_rest_call_success(request_type): +def test_get_tls_route_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/tcpRoutes/sample3"} + request_init = {"name": "projects/sample1/locations/sample2/tlsRoutes/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = tcp_route.TcpRoute( + return_value = tls_route.TlsRoute( name="name_value", self_link="self_link_value", description="description_value", meshes=["meshes_value"], gateways=["gateways_value"], + target_proxies=["target_proxies_value"], ) # Wrap the value into a proper Response obj @@ -44137,24 +48316,25 @@ def test_get_tcp_route_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = tcp_route.TcpRoute.pb(return_value) + return_value = tls_route.TlsRoute.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_tcp_route(request) + response = client.get_tls_route(request) # Establish that the response is the type that we expect. - assert isinstance(response, tcp_route.TcpRoute) + assert isinstance(response, tls_route.TlsRoute) assert response.name == "name_value" assert response.self_link == "self_link_value" assert response.description == "description_value" assert response.meshes == ["meshes_value"] assert response.gateways == ["gateways_value"] + assert response.target_proxies == ["target_proxies_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_tcp_route_rest_interceptors(null_interceptor): +def test_get_tls_route_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -44167,20 +48347,20 @@ def test_get_tcp_route_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_get_tcp_route" + transports.NetworkServicesRestInterceptor, "post_get_tls_route" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_get_tcp_route_with_metadata", + "post_get_tls_route_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_get_tcp_route" + transports.NetworkServicesRestInterceptor, "pre_get_tls_route" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = tcp_route.GetTcpRouteRequest.pb(tcp_route.GetTcpRouteRequest()) + pb_message = tls_route.GetTlsRouteRequest.pb(tls_route.GetTlsRouteRequest()) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -44191,19 +48371,19 @@ def test_get_tcp_route_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = tcp_route.TcpRoute.to_json(tcp_route.TcpRoute()) + return_value = tls_route.TlsRoute.to_json(tls_route.TlsRoute()) req.return_value.content = return_value - request = tcp_route.GetTcpRouteRequest() + request = tls_route.GetTlsRouteRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = tcp_route.TcpRoute() - post_with_metadata.return_value = tcp_route.TcpRoute(), metadata + post.return_value = tls_route.TlsRoute() + post_with_metadata.return_value = tls_route.TlsRoute(), metadata - client.get_tcp_route( + client.get_tls_route( request, metadata=[ ("key", "val"), @@ -44216,8 +48396,8 @@ def test_get_tcp_route_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_create_tcp_route_rest_bad_request( - request_type=gcn_tcp_route.CreateTcpRouteRequest, +def test_create_tls_route_rest_bad_request( + request_type=gcn_tls_route.CreateTlsRouteRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" @@ -44239,24 +48419,24 @@ def test_create_tcp_route_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_tcp_route(request) + client.create_tls_route(request) @pytest.mark.parametrize( "request_type", [ - gcn_tcp_route.CreateTcpRouteRequest, + gcn_tls_route.CreateTlsRouteRequest, dict, ], ) -def test_create_tcp_route_rest_call_success(request_type): +def test_create_tls_route_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = {"parent": "projects/sample1/locations/sample2"} - request_init["tcp_route"] = { + request_init["tls_route"] = { "name": "name_value", "self_link": "self_link_value", "create_time": {"seconds": 751, "nanos": 543}, @@ -44264,18 +48444,23 @@ def test_create_tcp_route_rest_call_success(request_type): "description": "description_value", "rules": [ { - "matches": [{"address": "address_value", "port": "port_value"}], + "matches": [ + { + "sni_host": ["sni_host_value1", "sni_host_value2"], + "alpn": ["alpn_value1", "alpn_value2"], + } + ], "action": { "destinations": [ {"service_name": "service_name_value", "weight": 648} ], - "original_destination": True, "idle_timeout": {"seconds": 751, "nanos": 543}, }, } ], "meshes": ["meshes_value1", "meshes_value2"], "gateways": ["gateways_value1", "gateways_value2"], + "target_proxies": ["target_proxies_value1", "target_proxies_value2"], "labels": {}, } # The version of a generated dependency at test runtime may differ from the version used during generation. @@ -44283,7 +48468,7 @@ def test_create_tcp_route_rest_call_success(request_type): # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = gcn_tcp_route.CreateTcpRouteRequest.meta.fields["tcp_route"] + test_field = gcn_tls_route.CreateTlsRouteRequest.meta.fields["tls_route"] def get_message_fields(field): # Given a field which is a message (composite type), return a list with @@ -44311,7 +48496,7 @@ def get_message_fields(field): # For each item in the sample request, create a list of sub fields which are not present at runtime # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["tcp_route"].items(): # pragma: NO COVER + for field, value in request_init["tls_route"].items(): # pragma: NO COVER result = None is_repeated = False # For repeated fields @@ -44341,10 +48526,10 @@ def get_message_fields(field): subfield = subfield_to_delete.get("subfield") if subfield: if field_repeated: - for i in range(0, len(request_init["tcp_route"][field])): - del request_init["tcp_route"][field][i][subfield] + for i in range(0, len(request_init["tls_route"][field])): + del request_init["tls_route"][field][i][subfield] else: - del request_init["tcp_route"][field][subfield] + del request_init["tls_route"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -44359,14 +48544,14 @@ def get_message_fields(field): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_tcp_route(request) + response = client.create_tls_route(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_tcp_route_rest_interceptors(null_interceptor): +def test_create_tls_route_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -44380,21 +48565,21 @@ def test_create_tcp_route_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_create_tcp_route" + transports.NetworkServicesRestInterceptor, "post_create_tls_route" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_create_tcp_route_with_metadata", + "post_create_tls_route_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_create_tcp_route" + transports.NetworkServicesRestInterceptor, "pre_create_tls_route" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = gcn_tcp_route.CreateTcpRouteRequest.pb( - gcn_tcp_route.CreateTcpRouteRequest() + pb_message = gcn_tls_route.CreateTlsRouteRequest.pb( + gcn_tls_route.CreateTlsRouteRequest() ) transcode.return_value = { "method": "post", @@ -44409,7 +48594,7 @@ def test_create_tcp_route_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = gcn_tcp_route.CreateTcpRouteRequest() + request = gcn_tls_route.CreateTlsRouteRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -44418,7 +48603,7 @@ def test_create_tcp_route_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.create_tcp_route( + client.create_tls_route( request, metadata=[ ("key", "val"), @@ -44431,15 +48616,15 @@ def test_create_tcp_route_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_update_tcp_route_rest_bad_request( - request_type=gcn_tcp_route.UpdateTcpRouteRequest, +def test_update_tls_route_rest_bad_request( + request_type=gcn_tls_route.UpdateTlsRouteRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "tcp_route": {"name": "projects/sample1/locations/sample2/tcpRoutes/sample3"} + "tls_route": {"name": "projects/sample1/locations/sample2/tlsRoutes/sample3"} } request = request_type(**request_init) @@ -44456,45 +48641,50 @@ def test_update_tcp_route_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_tcp_route(request) + client.update_tls_route(request) @pytest.mark.parametrize( "request_type", [ - gcn_tcp_route.UpdateTcpRouteRequest, + gcn_tls_route.UpdateTlsRouteRequest, dict, ], ) -def test_update_tcp_route_rest_call_success(request_type): +def test_update_tls_route_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "tcp_route": {"name": "projects/sample1/locations/sample2/tcpRoutes/sample3"} + "tls_route": {"name": "projects/sample1/locations/sample2/tlsRoutes/sample3"} } - request_init["tcp_route"] = { - "name": "projects/sample1/locations/sample2/tcpRoutes/sample3", + request_init["tls_route"] = { + "name": "projects/sample1/locations/sample2/tlsRoutes/sample3", "self_link": "self_link_value", "create_time": {"seconds": 751, "nanos": 543}, "update_time": {}, "description": "description_value", "rules": [ { - "matches": [{"address": "address_value", "port": "port_value"}], + "matches": [ + { + "sni_host": ["sni_host_value1", "sni_host_value2"], + "alpn": ["alpn_value1", "alpn_value2"], + } + ], "action": { "destinations": [ {"service_name": "service_name_value", "weight": 648} ], - "original_destination": True, "idle_timeout": {"seconds": 751, "nanos": 543}, }, } ], "meshes": ["meshes_value1", "meshes_value2"], "gateways": ["gateways_value1", "gateways_value2"], + "target_proxies": ["target_proxies_value1", "target_proxies_value2"], "labels": {}, } # The version of a generated dependency at test runtime may differ from the version used during generation. @@ -44502,7 +48692,7 @@ def test_update_tcp_route_rest_call_success(request_type): # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = gcn_tcp_route.UpdateTcpRouteRequest.meta.fields["tcp_route"] + test_field = gcn_tls_route.UpdateTlsRouteRequest.meta.fields["tls_route"] def get_message_fields(field): # Given a field which is a message (composite type), return a list with @@ -44530,7 +48720,7 @@ def get_message_fields(field): # For each item in the sample request, create a list of sub fields which are not present at runtime # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["tcp_route"].items(): # pragma: NO COVER + for field, value in request_init["tls_route"].items(): # pragma: NO COVER result = None is_repeated = False # For repeated fields @@ -44560,10 +48750,10 @@ def get_message_fields(field): subfield = subfield_to_delete.get("subfield") if subfield: if field_repeated: - for i in range(0, len(request_init["tcp_route"][field])): - del request_init["tcp_route"][field][i][subfield] + for i in range(0, len(request_init["tls_route"][field])): + del request_init["tls_route"][field][i][subfield] else: - del request_init["tcp_route"][field][subfield] + del request_init["tls_route"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -44578,14 +48768,14 @@ def get_message_fields(field): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_tcp_route(request) + response = client.update_tls_route(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_tcp_route_rest_interceptors(null_interceptor): +def test_update_tls_route_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -44599,21 +48789,21 @@ def test_update_tcp_route_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_update_tcp_route" + transports.NetworkServicesRestInterceptor, "post_update_tls_route" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_update_tcp_route_with_metadata", + "post_update_tls_route_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_update_tcp_route" + transports.NetworkServicesRestInterceptor, "pre_update_tls_route" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = gcn_tcp_route.UpdateTcpRouteRequest.pb( - gcn_tcp_route.UpdateTcpRouteRequest() + pb_message = gcn_tls_route.UpdateTlsRouteRequest.pb( + gcn_tls_route.UpdateTlsRouteRequest() ) transcode.return_value = { "method": "post", @@ -44628,7 +48818,7 @@ def test_update_tcp_route_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = gcn_tcp_route.UpdateTcpRouteRequest() + request = gcn_tls_route.UpdateTlsRouteRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -44637,7 +48827,7 @@ def test_update_tcp_route_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.update_tcp_route( + client.update_tls_route( request, metadata=[ ("key", "val"), @@ -44650,14 +48840,14 @@ def test_update_tcp_route_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_delete_tcp_route_rest_bad_request( - request_type=tcp_route.DeleteTcpRouteRequest, +def test_delete_tls_route_rest_bad_request( + request_type=tls_route.DeleteTlsRouteRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/tcpRoutes/sample3"} + request_init = {"name": "projects/sample1/locations/sample2/tlsRoutes/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -44673,23 +48863,23 @@ def test_delete_tcp_route_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_tcp_route(request) + client.delete_tls_route(request) @pytest.mark.parametrize( "request_type", [ - tcp_route.DeleteTcpRouteRequest, + tls_route.DeleteTlsRouteRequest, dict, ], ) -def test_delete_tcp_route_rest_call_success(request_type): +def test_delete_tls_route_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/tcpRoutes/sample3"} + request_init = {"name": "projects/sample1/locations/sample2/tlsRoutes/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -44704,14 +48894,14 @@ def test_delete_tcp_route_rest_call_success(request_type): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_tcp_route(request) + response = client.delete_tls_route(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_tcp_route_rest_interceptors(null_interceptor): +def test_delete_tls_route_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -44725,21 +48915,21 @@ def test_delete_tcp_route_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_delete_tcp_route" + transports.NetworkServicesRestInterceptor, "post_delete_tls_route" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_delete_tcp_route_with_metadata", + "post_delete_tls_route_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_delete_tcp_route" + transports.NetworkServicesRestInterceptor, "pre_delete_tls_route" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = tcp_route.DeleteTcpRouteRequest.pb( - tcp_route.DeleteTcpRouteRequest() + pb_message = tls_route.DeleteTlsRouteRequest.pb( + tls_route.DeleteTlsRouteRequest() ) transcode.return_value = { "method": "post", @@ -44754,7 +48944,7 @@ def test_delete_tcp_route_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = tcp_route.DeleteTcpRouteRequest() + request = tls_route.DeleteTlsRouteRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -44763,7 +48953,7 @@ def test_delete_tcp_route_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.delete_tcp_route( + client.delete_tls_route( request, metadata=[ ("key", "val"), @@ -44776,7 +48966,9 @@ def test_delete_tcp_route_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_tls_routes_rest_bad_request(request_type=tls_route.ListTlsRoutesRequest): +def test_list_service_bindings_rest_bad_request( + request_type=service_binding.ListServiceBindingsRequest, +): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -44797,17 +48989,17 @@ def test_list_tls_routes_rest_bad_request(request_type=tls_route.ListTlsRoutesRe response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_tls_routes(request) + client.list_service_bindings(request) @pytest.mark.parametrize( "request_type", [ - tls_route.ListTlsRoutesRequest, + service_binding.ListServiceBindingsRequest, dict, ], ) -def test_list_tls_routes_rest_call_success(request_type): +def test_list_service_bindings_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -44819,7 +49011,7 @@ def test_list_tls_routes_rest_call_success(request_type): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = tls_route.ListTlsRoutesResponse( + return_value = service_binding.ListServiceBindingsResponse( next_page_token="next_page_token_value", unreachable=["unreachable_value"], ) @@ -44829,21 +49021,21 @@ def test_list_tls_routes_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = tls_route.ListTlsRoutesResponse.pb(return_value) + return_value = service_binding.ListServiceBindingsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_tls_routes(request) + response = client.list_service_bindings(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListTlsRoutesPager) + assert isinstance(response, pagers.ListServiceBindingsPager) assert response.next_page_token == "next_page_token_value" assert response.unreachable == ["unreachable_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_tls_routes_rest_interceptors(null_interceptor): +def test_list_service_bindings_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -44856,20 +49048,22 @@ def test_list_tls_routes_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_list_tls_routes" + transports.NetworkServicesRestInterceptor, "post_list_service_bindings" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_list_tls_routes_with_metadata", + "post_list_service_bindings_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_list_tls_routes" + transports.NetworkServicesRestInterceptor, "pre_list_service_bindings" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = tls_route.ListTlsRoutesRequest.pb(tls_route.ListTlsRoutesRequest()) + pb_message = service_binding.ListServiceBindingsRequest.pb( + service_binding.ListServiceBindingsRequest() + ) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -44880,21 +49074,24 @@ def test_list_tls_routes_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = tls_route.ListTlsRoutesResponse.to_json( - tls_route.ListTlsRoutesResponse() + return_value = service_binding.ListServiceBindingsResponse.to_json( + service_binding.ListServiceBindingsResponse() ) req.return_value.content = return_value - request = tls_route.ListTlsRoutesRequest() + request = service_binding.ListServiceBindingsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = tls_route.ListTlsRoutesResponse() - post_with_metadata.return_value = tls_route.ListTlsRoutesResponse(), metadata + post.return_value = service_binding.ListServiceBindingsResponse() + post_with_metadata.return_value = ( + service_binding.ListServiceBindingsResponse(), + metadata, + ) - client.list_tls_routes( + client.list_service_bindings( request, metadata=[ ("key", "val"), @@ -44907,12 +49104,16 @@ def test_list_tls_routes_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_get_tls_route_rest_bad_request(request_type=tls_route.GetTlsRouteRequest): +def test_get_service_binding_rest_bad_request( + request_type=service_binding.GetServiceBindingRequest, +): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/tlsRoutes/sample3"} + request_init = { + "name": "projects/sample1/locations/sample2/serviceBindings/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -44928,34 +49129,35 @@ def test_get_tls_route_rest_bad_request(request_type=tls_route.GetTlsRouteReques response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_tls_route(request) + client.get_service_binding(request) @pytest.mark.parametrize( "request_type", [ - tls_route.GetTlsRouteRequest, + service_binding.GetServiceBindingRequest, dict, ], ) -def test_get_tls_route_rest_call_success(request_type): +def test_get_service_binding_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/tlsRoutes/sample3"} + request_init = { + "name": "projects/sample1/locations/sample2/serviceBindings/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = tls_route.TlsRoute( + return_value = service_binding.ServiceBinding( name="name_value", - self_link="self_link_value", description="description_value", - meshes=["meshes_value"], - gateways=["gateways_value"], + service="service_value", + service_id="service_id_value", ) # Wrap the value into a proper Response obj @@ -44963,24 +49165,23 @@ def test_get_tls_route_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = tls_route.TlsRoute.pb(return_value) + return_value = service_binding.ServiceBinding.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_tls_route(request) + response = client.get_service_binding(request) # Establish that the response is the type that we expect. - assert isinstance(response, tls_route.TlsRoute) + assert isinstance(response, service_binding.ServiceBinding) assert response.name == "name_value" - assert response.self_link == "self_link_value" assert response.description == "description_value" - assert response.meshes == ["meshes_value"] - assert response.gateways == ["gateways_value"] + assert response.service == "service_value" + assert response.service_id == "service_id_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_tls_route_rest_interceptors(null_interceptor): +def test_get_service_binding_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -44993,20 +49194,22 @@ def test_get_tls_route_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_get_tls_route" + transports.NetworkServicesRestInterceptor, "post_get_service_binding" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_get_tls_route_with_metadata", + "post_get_service_binding_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_get_tls_route" + transports.NetworkServicesRestInterceptor, "pre_get_service_binding" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = tls_route.GetTlsRouteRequest.pb(tls_route.GetTlsRouteRequest()) + pb_message = service_binding.GetServiceBindingRequest.pb( + service_binding.GetServiceBindingRequest() + ) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -45017,19 +49220,21 @@ def test_get_tls_route_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = tls_route.TlsRoute.to_json(tls_route.TlsRoute()) + return_value = service_binding.ServiceBinding.to_json( + service_binding.ServiceBinding() + ) req.return_value.content = return_value - request = tls_route.GetTlsRouteRequest() + request = service_binding.GetServiceBindingRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = tls_route.TlsRoute() - post_with_metadata.return_value = tls_route.TlsRoute(), metadata + post.return_value = service_binding.ServiceBinding() + post_with_metadata.return_value = service_binding.ServiceBinding(), metadata - client.get_tls_route( + client.get_service_binding( request, metadata=[ ("key", "val"), @@ -45042,8 +49247,8 @@ def test_get_tls_route_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_create_tls_route_rest_bad_request( - request_type=gcn_tls_route.CreateTlsRouteRequest, +def test_create_service_binding_rest_bad_request( + request_type=gcn_service_binding.CreateServiceBindingRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" @@ -45065,47 +49270,30 @@ def test_create_tls_route_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_tls_route(request) + client.create_service_binding(request) @pytest.mark.parametrize( "request_type", [ - gcn_tls_route.CreateTlsRouteRequest, + gcn_service_binding.CreateServiceBindingRequest, dict, ], ) -def test_create_tls_route_rest_call_success(request_type): +def test_create_service_binding_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = {"parent": "projects/sample1/locations/sample2"} - request_init["tls_route"] = { + request_init["service_binding"] = { "name": "name_value", - "self_link": "self_link_value", + "description": "description_value", "create_time": {"seconds": 751, "nanos": 543}, "update_time": {}, - "description": "description_value", - "rules": [ - { - "matches": [ - { - "sni_host": ["sni_host_value1", "sni_host_value2"], - "alpn": ["alpn_value1", "alpn_value2"], - } - ], - "action": { - "destinations": [ - {"service_name": "service_name_value", "weight": 648} - ], - "idle_timeout": {"seconds": 751, "nanos": 543}, - }, - } - ], - "meshes": ["meshes_value1", "meshes_value2"], - "gateways": ["gateways_value1", "gateways_value2"], + "service": "service_value", + "service_id": "service_id_value", "labels": {}, } # The version of a generated dependency at test runtime may differ from the version used during generation. @@ -45113,7 +49301,9 @@ def test_create_tls_route_rest_call_success(request_type): # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = gcn_tls_route.CreateTlsRouteRequest.meta.fields["tls_route"] + test_field = gcn_service_binding.CreateServiceBindingRequest.meta.fields[ + "service_binding" + ] def get_message_fields(field): # Given a field which is a message (composite type), return a list with @@ -45141,7 +49331,7 @@ def get_message_fields(field): # For each item in the sample request, create a list of sub fields which are not present at runtime # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["tls_route"].items(): # pragma: NO COVER + for field, value in request_init["service_binding"].items(): # pragma: NO COVER result = None is_repeated = False # For repeated fields @@ -45171,10 +49361,10 @@ def get_message_fields(field): subfield = subfield_to_delete.get("subfield") if subfield: if field_repeated: - for i in range(0, len(request_init["tls_route"][field])): - del request_init["tls_route"][field][i][subfield] + for i in range(0, len(request_init["service_binding"][field])): + del request_init["service_binding"][field][i][subfield] else: - del request_init["tls_route"][field][subfield] + del request_init["service_binding"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -45189,14 +49379,14 @@ def get_message_fields(field): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_tls_route(request) + response = client.create_service_binding(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_tls_route_rest_interceptors(null_interceptor): +def test_create_service_binding_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -45210,21 +49400,21 @@ def test_create_tls_route_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_create_tls_route" + transports.NetworkServicesRestInterceptor, "post_create_service_binding" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_create_tls_route_with_metadata", + "post_create_service_binding_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_create_tls_route" + transports.NetworkServicesRestInterceptor, "pre_create_service_binding" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = gcn_tls_route.CreateTlsRouteRequest.pb( - gcn_tls_route.CreateTlsRouteRequest() + pb_message = gcn_service_binding.CreateServiceBindingRequest.pb( + gcn_service_binding.CreateServiceBindingRequest() ) transcode.return_value = { "method": "post", @@ -45239,7 +49429,7 @@ def test_create_tls_route_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = gcn_tls_route.CreateTlsRouteRequest() + request = gcn_service_binding.CreateServiceBindingRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -45248,7 +49438,7 @@ def test_create_tls_route_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.create_tls_route( + client.create_service_binding( request, metadata=[ ("key", "val"), @@ -45261,15 +49451,17 @@ def test_create_tls_route_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_update_tls_route_rest_bad_request( - request_type=gcn_tls_route.UpdateTlsRouteRequest, +def test_update_service_binding_rest_bad_request( + request_type=gcn_service_binding.UpdateServiceBindingRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "tls_route": {"name": "projects/sample1/locations/sample2/tlsRoutes/sample3"} + "service_binding": { + "name": "projects/sample1/locations/sample2/serviceBindings/sample3" + } } request = request_type(**request_init) @@ -45286,49 +49478,34 @@ def test_update_tls_route_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_tls_route(request) + client.update_service_binding(request) @pytest.mark.parametrize( "request_type", [ - gcn_tls_route.UpdateTlsRouteRequest, + gcn_service_binding.UpdateServiceBindingRequest, dict, ], ) -def test_update_tls_route_rest_call_success(request_type): +def test_update_service_binding_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "tls_route": {"name": "projects/sample1/locations/sample2/tlsRoutes/sample3"} + "service_binding": { + "name": "projects/sample1/locations/sample2/serviceBindings/sample3" + } } - request_init["tls_route"] = { - "name": "projects/sample1/locations/sample2/tlsRoutes/sample3", - "self_link": "self_link_value", + request_init["service_binding"] = { + "name": "projects/sample1/locations/sample2/serviceBindings/sample3", + "description": "description_value", "create_time": {"seconds": 751, "nanos": 543}, "update_time": {}, - "description": "description_value", - "rules": [ - { - "matches": [ - { - "sni_host": ["sni_host_value1", "sni_host_value2"], - "alpn": ["alpn_value1", "alpn_value2"], - } - ], - "action": { - "destinations": [ - {"service_name": "service_name_value", "weight": 648} - ], - "idle_timeout": {"seconds": 751, "nanos": 543}, - }, - } - ], - "meshes": ["meshes_value1", "meshes_value2"], - "gateways": ["gateways_value1", "gateways_value2"], + "service": "service_value", + "service_id": "service_id_value", "labels": {}, } # The version of a generated dependency at test runtime may differ from the version used during generation. @@ -45336,7 +49513,9 @@ def test_update_tls_route_rest_call_success(request_type): # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = gcn_tls_route.UpdateTlsRouteRequest.meta.fields["tls_route"] + test_field = gcn_service_binding.UpdateServiceBindingRequest.meta.fields[ + "service_binding" + ] def get_message_fields(field): # Given a field which is a message (composite type), return a list with @@ -45364,7 +49543,7 @@ def get_message_fields(field): # For each item in the sample request, create a list of sub fields which are not present at runtime # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["tls_route"].items(): # pragma: NO COVER + for field, value in request_init["service_binding"].items(): # pragma: NO COVER result = None is_repeated = False # For repeated fields @@ -45394,10 +49573,10 @@ def get_message_fields(field): subfield = subfield_to_delete.get("subfield") if subfield: if field_repeated: - for i in range(0, len(request_init["tls_route"][field])): - del request_init["tls_route"][field][i][subfield] + for i in range(0, len(request_init["service_binding"][field])): + del request_init["service_binding"][field][i][subfield] else: - del request_init["tls_route"][field][subfield] + del request_init["service_binding"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -45412,14 +49591,14 @@ def get_message_fields(field): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_tls_route(request) + response = client.update_service_binding(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_tls_route_rest_interceptors(null_interceptor): +def test_update_service_binding_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -45433,21 +49612,21 @@ def test_update_tls_route_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_update_tls_route" + transports.NetworkServicesRestInterceptor, "post_update_service_binding" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_update_tls_route_with_metadata", + "post_update_service_binding_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_update_tls_route" + transports.NetworkServicesRestInterceptor, "pre_update_service_binding" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = gcn_tls_route.UpdateTlsRouteRequest.pb( - gcn_tls_route.UpdateTlsRouteRequest() + pb_message = gcn_service_binding.UpdateServiceBindingRequest.pb( + gcn_service_binding.UpdateServiceBindingRequest() ) transcode.return_value = { "method": "post", @@ -45462,7 +49641,7 @@ def test_update_tls_route_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = gcn_tls_route.UpdateTlsRouteRequest() + request = gcn_service_binding.UpdateServiceBindingRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -45471,7 +49650,7 @@ def test_update_tls_route_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.update_tls_route( + client.update_service_binding( request, metadata=[ ("key", "val"), @@ -45484,14 +49663,16 @@ def test_update_tls_route_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_delete_tls_route_rest_bad_request( - request_type=tls_route.DeleteTlsRouteRequest, +def test_delete_service_binding_rest_bad_request( + request_type=service_binding.DeleteServiceBindingRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/tlsRoutes/sample3"} + request_init = { + "name": "projects/sample1/locations/sample2/serviceBindings/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -45507,23 +49688,25 @@ def test_delete_tls_route_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_tls_route(request) + client.delete_service_binding(request) @pytest.mark.parametrize( "request_type", [ - tls_route.DeleteTlsRouteRequest, + service_binding.DeleteServiceBindingRequest, dict, ], ) -def test_delete_tls_route_rest_call_success(request_type): +def test_delete_service_binding_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/tlsRoutes/sample3"} + request_init = { + "name": "projects/sample1/locations/sample2/serviceBindings/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -45538,14 +49721,14 @@ def test_delete_tls_route_rest_call_success(request_type): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_tls_route(request) + response = client.delete_service_binding(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_tls_route_rest_interceptors(null_interceptor): +def test_delete_service_binding_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -45559,21 +49742,21 @@ def test_delete_tls_route_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_delete_tls_route" + transports.NetworkServicesRestInterceptor, "post_delete_service_binding" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_delete_tls_route_with_metadata", + "post_delete_service_binding_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_delete_tls_route" + transports.NetworkServicesRestInterceptor, "pre_delete_service_binding" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = tls_route.DeleteTlsRouteRequest.pb( - tls_route.DeleteTlsRouteRequest() + pb_message = service_binding.DeleteServiceBindingRequest.pb( + service_binding.DeleteServiceBindingRequest() ) transcode.return_value = { "method": "post", @@ -45588,7 +49771,7 @@ def test_delete_tls_route_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = tls_route.DeleteTlsRouteRequest() + request = service_binding.DeleteServiceBindingRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -45597,7 +49780,7 @@ def test_delete_tls_route_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.delete_tls_route( + client.delete_service_binding( request, metadata=[ ("key", "val"), @@ -45610,9 +49793,7 @@ def test_delete_tls_route_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_service_bindings_rest_bad_request( - request_type=service_binding.ListServiceBindingsRequest, -): +def test_list_meshes_rest_bad_request(request_type=mesh.ListMeshesRequest): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -45633,17 +49814,17 @@ def test_list_service_bindings_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_service_bindings(request) + client.list_meshes(request) @pytest.mark.parametrize( "request_type", [ - service_binding.ListServiceBindingsRequest, + mesh.ListMeshesRequest, dict, ], ) -def test_list_service_bindings_rest_call_success(request_type): +def test_list_meshes_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -45655,7 +49836,7 @@ def test_list_service_bindings_rest_call_success(request_type): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = service_binding.ListServiceBindingsResponse( + return_value = mesh.ListMeshesResponse( next_page_token="next_page_token_value", unreachable=["unreachable_value"], ) @@ -45665,21 +49846,21 @@ def test_list_service_bindings_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = service_binding.ListServiceBindingsResponse.pb(return_value) + return_value = mesh.ListMeshesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_service_bindings(request) + response = client.list_meshes(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListServiceBindingsPager) + assert isinstance(response, pagers.ListMeshesPager) assert response.next_page_token == "next_page_token_value" assert response.unreachable == ["unreachable_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_service_bindings_rest_interceptors(null_interceptor): +def test_list_meshes_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -45692,22 +49873,19 @@ def test_list_service_bindings_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_list_service_bindings" + transports.NetworkServicesRestInterceptor, "post_list_meshes" ) as post, mock.patch.object( - transports.NetworkServicesRestInterceptor, - "post_list_service_bindings_with_metadata", + transports.NetworkServicesRestInterceptor, "post_list_meshes_with_metadata" ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_list_service_bindings" + transports.NetworkServicesRestInterceptor, "pre_list_meshes" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = service_binding.ListServiceBindingsRequest.pb( - service_binding.ListServiceBindingsRequest() - ) + pb_message = mesh.ListMeshesRequest.pb(mesh.ListMeshesRequest()) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -45718,24 +49896,19 @@ def test_list_service_bindings_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = service_binding.ListServiceBindingsResponse.to_json( - service_binding.ListServiceBindingsResponse() - ) + return_value = mesh.ListMeshesResponse.to_json(mesh.ListMeshesResponse()) req.return_value.content = return_value - request = service_binding.ListServiceBindingsRequest() + request = mesh.ListMeshesRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = service_binding.ListServiceBindingsResponse() - post_with_metadata.return_value = ( - service_binding.ListServiceBindingsResponse(), - metadata, - ) + post.return_value = mesh.ListMeshesResponse() + post_with_metadata.return_value = mesh.ListMeshesResponse(), metadata - client.list_service_bindings( + client.list_meshes( request, metadata=[ ("key", "val"), @@ -45748,16 +49921,12 @@ def test_list_service_bindings_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_get_service_binding_rest_bad_request( - request_type=service_binding.GetServiceBindingRequest, -): +def test_get_mesh_rest_bad_request(request_type=mesh.GetMeshRequest): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/serviceBindings/sample3" - } + request_init = {"name": "projects/sample1/locations/sample2/meshes/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -45773,35 +49942,34 @@ def test_get_service_binding_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_service_binding(request) + client.get_mesh(request) @pytest.mark.parametrize( "request_type", [ - service_binding.GetServiceBindingRequest, + mesh.GetMeshRequest, dict, ], ) -def test_get_service_binding_rest_call_success(request_type): +def test_get_mesh_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/serviceBindings/sample3" - } + request_init = {"name": "projects/sample1/locations/sample2/meshes/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = service_binding.ServiceBinding( + return_value = mesh.Mesh( name="name_value", + self_link="self_link_value", description="description_value", - service="service_value", - service_id="service_id_value", + interception_port=1848, + envoy_headers=common.EnvoyHeaders.NONE, ) # Wrap the value into a proper Response obj @@ -45809,23 +49977,24 @@ def test_get_service_binding_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = service_binding.ServiceBinding.pb(return_value) + return_value = mesh.Mesh.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_service_binding(request) + response = client.get_mesh(request) # Establish that the response is the type that we expect. - assert isinstance(response, service_binding.ServiceBinding) + assert isinstance(response, mesh.Mesh) assert response.name == "name_value" + assert response.self_link == "self_link_value" assert response.description == "description_value" - assert response.service == "service_value" - assert response.service_id == "service_id_value" + assert response.interception_port == 1848 + assert response.envoy_headers == common.EnvoyHeaders.NONE @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_service_binding_rest_interceptors(null_interceptor): +def test_get_mesh_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -45838,22 +50007,19 @@ def test_get_service_binding_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_get_service_binding" + transports.NetworkServicesRestInterceptor, "post_get_mesh" ) as post, mock.patch.object( - transports.NetworkServicesRestInterceptor, - "post_get_service_binding_with_metadata", + transports.NetworkServicesRestInterceptor, "post_get_mesh_with_metadata" ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_get_service_binding" + transports.NetworkServicesRestInterceptor, "pre_get_mesh" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = service_binding.GetServiceBindingRequest.pb( - service_binding.GetServiceBindingRequest() - ) + pb_message = mesh.GetMeshRequest.pb(mesh.GetMeshRequest()) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -45864,21 +50030,19 @@ def test_get_service_binding_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = service_binding.ServiceBinding.to_json( - service_binding.ServiceBinding() - ) + return_value = mesh.Mesh.to_json(mesh.Mesh()) req.return_value.content = return_value - request = service_binding.GetServiceBindingRequest() + request = mesh.GetMeshRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = service_binding.ServiceBinding() - post_with_metadata.return_value = service_binding.ServiceBinding(), metadata + post.return_value = mesh.Mesh() + post_with_metadata.return_value = mesh.Mesh(), metadata - client.get_service_binding( + client.get_mesh( request, metadata=[ ("key", "val"), @@ -45891,9 +50055,7 @@ def test_get_service_binding_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_create_service_binding_rest_bad_request( - request_type=gcn_service_binding.CreateServiceBindingRequest, -): +def test_create_mesh_rest_bad_request(request_type=gcn_mesh.CreateMeshRequest): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -45914,40 +50076,39 @@ def test_create_service_binding_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_service_binding(request) + client.create_mesh(request) @pytest.mark.parametrize( "request_type", [ - gcn_service_binding.CreateServiceBindingRequest, + gcn_mesh.CreateMeshRequest, dict, ], ) -def test_create_service_binding_rest_call_success(request_type): +def test_create_mesh_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = {"parent": "projects/sample1/locations/sample2"} - request_init["service_binding"] = { + request_init["mesh"] = { "name": "name_value", - "description": "description_value", + "self_link": "self_link_value", "create_time": {"seconds": 751, "nanos": 543}, "update_time": {}, - "service": "service_value", - "service_id": "service_id_value", "labels": {}, + "description": "description_value", + "interception_port": 1848, + "envoy_headers": 1, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = gcn_service_binding.CreateServiceBindingRequest.meta.fields[ - "service_binding" - ] + test_field = gcn_mesh.CreateMeshRequest.meta.fields["mesh"] def get_message_fields(field): # Given a field which is a message (composite type), return a list with @@ -45975,7 +50136,7 @@ def get_message_fields(field): # For each item in the sample request, create a list of sub fields which are not present at runtime # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["service_binding"].items(): # pragma: NO COVER + for field, value in request_init["mesh"].items(): # pragma: NO COVER result = None is_repeated = False # For repeated fields @@ -46005,10 +50166,10 @@ def get_message_fields(field): subfield = subfield_to_delete.get("subfield") if subfield: if field_repeated: - for i in range(0, len(request_init["service_binding"][field])): - del request_init["service_binding"][field][i][subfield] + for i in range(0, len(request_init["mesh"][field])): + del request_init["mesh"][field][i][subfield] else: - del request_init["service_binding"][field][subfield] + del request_init["mesh"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -46023,14 +50184,14 @@ def get_message_fields(field): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_service_binding(request) + response = client.create_mesh(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_service_binding_rest_interceptors(null_interceptor): +def test_create_mesh_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -46044,22 +50205,19 @@ def test_create_service_binding_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_create_service_binding" + transports.NetworkServicesRestInterceptor, "post_create_mesh" ) as post, mock.patch.object( - transports.NetworkServicesRestInterceptor, - "post_create_service_binding_with_metadata", + transports.NetworkServicesRestInterceptor, "post_create_mesh_with_metadata" ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_create_service_binding" + transports.NetworkServicesRestInterceptor, "pre_create_mesh" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = gcn_service_binding.CreateServiceBindingRequest.pb( - gcn_service_binding.CreateServiceBindingRequest() - ) + pb_message = gcn_mesh.CreateMeshRequest.pb(gcn_mesh.CreateMeshRequest()) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -46073,7 +50231,7 @@ def test_create_service_binding_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = gcn_service_binding.CreateServiceBindingRequest() + request = gcn_mesh.CreateMeshRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -46082,7 +50240,7 @@ def test_create_service_binding_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.create_service_binding( + client.create_mesh( request, metadata=[ ("key", "val"), @@ -46095,17 +50253,13 @@ def test_create_service_binding_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_update_service_binding_rest_bad_request( - request_type=gcn_service_binding.UpdateServiceBindingRequest, -): +def test_update_mesh_rest_bad_request(request_type=gcn_mesh.UpdateMeshRequest): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "service_binding": { - "name": "projects/sample1/locations/sample2/serviceBindings/sample3" - } + "mesh": {"name": "projects/sample1/locations/sample2/meshes/sample3"} } request = request_type(**request_init) @@ -46122,44 +50276,41 @@ def test_update_service_binding_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_service_binding(request) + client.update_mesh(request) @pytest.mark.parametrize( "request_type", [ - gcn_service_binding.UpdateServiceBindingRequest, + gcn_mesh.UpdateMeshRequest, dict, ], ) -def test_update_service_binding_rest_call_success(request_type): +def test_update_mesh_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "service_binding": { - "name": "projects/sample1/locations/sample2/serviceBindings/sample3" - } + "mesh": {"name": "projects/sample1/locations/sample2/meshes/sample3"} } - request_init["service_binding"] = { - "name": "projects/sample1/locations/sample2/serviceBindings/sample3", - "description": "description_value", + request_init["mesh"] = { + "name": "projects/sample1/locations/sample2/meshes/sample3", + "self_link": "self_link_value", "create_time": {"seconds": 751, "nanos": 543}, "update_time": {}, - "service": "service_value", - "service_id": "service_id_value", "labels": {}, + "description": "description_value", + "interception_port": 1848, + "envoy_headers": 1, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = gcn_service_binding.UpdateServiceBindingRequest.meta.fields[ - "service_binding" - ] + test_field = gcn_mesh.UpdateMeshRequest.meta.fields["mesh"] def get_message_fields(field): # Given a field which is a message (composite type), return a list with @@ -46187,7 +50338,7 @@ def get_message_fields(field): # For each item in the sample request, create a list of sub fields which are not present at runtime # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["service_binding"].items(): # pragma: NO COVER + for field, value in request_init["mesh"].items(): # pragma: NO COVER result = None is_repeated = False # For repeated fields @@ -46217,10 +50368,10 @@ def get_message_fields(field): subfield = subfield_to_delete.get("subfield") if subfield: if field_repeated: - for i in range(0, len(request_init["service_binding"][field])): - del request_init["service_binding"][field][i][subfield] + for i in range(0, len(request_init["mesh"][field])): + del request_init["mesh"][field][i][subfield] else: - del request_init["service_binding"][field][subfield] + del request_init["mesh"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -46235,14 +50386,14 @@ def get_message_fields(field): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_service_binding(request) + response = client.update_mesh(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_service_binding_rest_interceptors(null_interceptor): +def test_update_mesh_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -46256,22 +50407,19 @@ def test_update_service_binding_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_update_service_binding" + transports.NetworkServicesRestInterceptor, "post_update_mesh" ) as post, mock.patch.object( - transports.NetworkServicesRestInterceptor, - "post_update_service_binding_with_metadata", + transports.NetworkServicesRestInterceptor, "post_update_mesh_with_metadata" ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_update_service_binding" + transports.NetworkServicesRestInterceptor, "pre_update_mesh" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = gcn_service_binding.UpdateServiceBindingRequest.pb( - gcn_service_binding.UpdateServiceBindingRequest() - ) + pb_message = gcn_mesh.UpdateMeshRequest.pb(gcn_mesh.UpdateMeshRequest()) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -46285,7 +50433,7 @@ def test_update_service_binding_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = gcn_service_binding.UpdateServiceBindingRequest() + request = gcn_mesh.UpdateMeshRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -46294,7 +50442,7 @@ def test_update_service_binding_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.update_service_binding( + client.update_mesh( request, metadata=[ ("key", "val"), @@ -46307,16 +50455,12 @@ def test_update_service_binding_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_delete_service_binding_rest_bad_request( - request_type=service_binding.DeleteServiceBindingRequest, -): +def test_delete_mesh_rest_bad_request(request_type=mesh.DeleteMeshRequest): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/serviceBindings/sample3" - } + request_init = {"name": "projects/sample1/locations/sample2/meshes/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -46332,25 +50476,23 @@ def test_delete_service_binding_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_service_binding(request) + client.delete_mesh(request) @pytest.mark.parametrize( "request_type", [ - service_binding.DeleteServiceBindingRequest, + mesh.DeleteMeshRequest, dict, ], ) -def test_delete_service_binding_rest_call_success(request_type): +def test_delete_mesh_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/serviceBindings/sample3" - } + request_init = {"name": "projects/sample1/locations/sample2/meshes/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -46365,14 +50507,14 @@ def test_delete_service_binding_rest_call_success(request_type): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_service_binding(request) + response = client.delete_mesh(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_service_binding_rest_interceptors(null_interceptor): +def test_delete_mesh_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -46386,22 +50528,19 @@ def test_delete_service_binding_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_delete_service_binding" + transports.NetworkServicesRestInterceptor, "post_delete_mesh" ) as post, mock.patch.object( - transports.NetworkServicesRestInterceptor, - "post_delete_service_binding_with_metadata", + transports.NetworkServicesRestInterceptor, "post_delete_mesh_with_metadata" ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_delete_service_binding" + transports.NetworkServicesRestInterceptor, "pre_delete_mesh" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = service_binding.DeleteServiceBindingRequest.pb( - service_binding.DeleteServiceBindingRequest() - ) + pb_message = mesh.DeleteMeshRequest.pb(mesh.DeleteMeshRequest()) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -46415,7 +50554,7 @@ def test_delete_service_binding_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = service_binding.DeleteServiceBindingRequest() + request = mesh.DeleteMeshRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -46424,7 +50563,7 @@ def test_delete_service_binding_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.delete_service_binding( + client.delete_mesh( request, metadata=[ ("key", "val"), @@ -46437,7 +50576,9 @@ def test_delete_service_binding_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_meshes_rest_bad_request(request_type=mesh.ListMeshesRequest): +def test_list_service_lb_policies_rest_bad_request( + request_type=service_lb_policy.ListServiceLbPoliciesRequest, +): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -46458,17 +50599,17 @@ def test_list_meshes_rest_bad_request(request_type=mesh.ListMeshesRequest): response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_meshes(request) + client.list_service_lb_policies(request) @pytest.mark.parametrize( "request_type", [ - mesh.ListMeshesRequest, + service_lb_policy.ListServiceLbPoliciesRequest, dict, ], ) -def test_list_meshes_rest_call_success(request_type): +def test_list_service_lb_policies_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -46480,7 +50621,7 @@ def test_list_meshes_rest_call_success(request_type): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = mesh.ListMeshesResponse( + return_value = service_lb_policy.ListServiceLbPoliciesResponse( next_page_token="next_page_token_value", unreachable=["unreachable_value"], ) @@ -46490,21 +50631,21 @@ def test_list_meshes_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = mesh.ListMeshesResponse.pb(return_value) + return_value = service_lb_policy.ListServiceLbPoliciesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_meshes(request) + response = client.list_service_lb_policies(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListMeshesPager) + assert isinstance(response, pagers.ListServiceLbPoliciesPager) assert response.next_page_token == "next_page_token_value" assert response.unreachable == ["unreachable_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_meshes_rest_interceptors(null_interceptor): +def test_list_service_lb_policies_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -46517,19 +50658,22 @@ def test_list_meshes_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_list_meshes" + transports.NetworkServicesRestInterceptor, "post_list_service_lb_policies" ) as post, mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_list_meshes_with_metadata" + transports.NetworkServicesRestInterceptor, + "post_list_service_lb_policies_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_list_meshes" + transports.NetworkServicesRestInterceptor, "pre_list_service_lb_policies" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = mesh.ListMeshesRequest.pb(mesh.ListMeshesRequest()) + pb_message = service_lb_policy.ListServiceLbPoliciesRequest.pb( + service_lb_policy.ListServiceLbPoliciesRequest() + ) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -46540,19 +50684,24 @@ def test_list_meshes_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = mesh.ListMeshesResponse.to_json(mesh.ListMeshesResponse()) + return_value = service_lb_policy.ListServiceLbPoliciesResponse.to_json( + service_lb_policy.ListServiceLbPoliciesResponse() + ) req.return_value.content = return_value - request = mesh.ListMeshesRequest() + request = service_lb_policy.ListServiceLbPoliciesRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = mesh.ListMeshesResponse() - post_with_metadata.return_value = mesh.ListMeshesResponse(), metadata + post.return_value = service_lb_policy.ListServiceLbPoliciesResponse() + post_with_metadata.return_value = ( + service_lb_policy.ListServiceLbPoliciesResponse(), + metadata, + ) - client.list_meshes( + client.list_service_lb_policies( request, metadata=[ ("key", "val"), @@ -46565,12 +50714,16 @@ def test_list_meshes_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_get_mesh_rest_bad_request(request_type=mesh.GetMeshRequest): +def test_get_service_lb_policy_rest_bad_request( + request_type=service_lb_policy.GetServiceLbPolicyRequest, +): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/meshes/sample3"} + request_init = { + "name": "projects/sample1/locations/sample2/serviceLbPolicies/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -46586,34 +50739,34 @@ def test_get_mesh_rest_bad_request(request_type=mesh.GetMeshRequest): response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_mesh(request) + client.get_service_lb_policy(request) @pytest.mark.parametrize( "request_type", [ - mesh.GetMeshRequest, + service_lb_policy.GetServiceLbPolicyRequest, dict, ], ) -def test_get_mesh_rest_call_success(request_type): +def test_get_service_lb_policy_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/meshes/sample3"} + request_init = { + "name": "projects/sample1/locations/sample2/serviceLbPolicies/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = mesh.Mesh( + return_value = service_lb_policy.ServiceLbPolicy( name="name_value", - self_link="self_link_value", description="description_value", - interception_port=1848, - envoy_headers=common.EnvoyHeaders.NONE, + load_balancing_algorithm=service_lb_policy.ServiceLbPolicy.LoadBalancingAlgorithm.SPRAY_TO_WORLD, ) # Wrap the value into a proper Response obj @@ -46621,24 +50774,25 @@ def test_get_mesh_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = mesh.Mesh.pb(return_value) + return_value = service_lb_policy.ServiceLbPolicy.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_mesh(request) + response = client.get_service_lb_policy(request) # Establish that the response is the type that we expect. - assert isinstance(response, mesh.Mesh) + assert isinstance(response, service_lb_policy.ServiceLbPolicy) assert response.name == "name_value" - assert response.self_link == "self_link_value" assert response.description == "description_value" - assert response.interception_port == 1848 - assert response.envoy_headers == common.EnvoyHeaders.NONE + assert ( + response.load_balancing_algorithm + == service_lb_policy.ServiceLbPolicy.LoadBalancingAlgorithm.SPRAY_TO_WORLD + ) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_mesh_rest_interceptors(null_interceptor): +def test_get_service_lb_policy_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -46651,19 +50805,22 @@ def test_get_mesh_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_get_mesh" + transports.NetworkServicesRestInterceptor, "post_get_service_lb_policy" ) as post, mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_get_mesh_with_metadata" + transports.NetworkServicesRestInterceptor, + "post_get_service_lb_policy_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_get_mesh" + transports.NetworkServicesRestInterceptor, "pre_get_service_lb_policy" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = mesh.GetMeshRequest.pb(mesh.GetMeshRequest()) + pb_message = service_lb_policy.GetServiceLbPolicyRequest.pb( + service_lb_policy.GetServiceLbPolicyRequest() + ) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -46674,19 +50831,21 @@ def test_get_mesh_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = mesh.Mesh.to_json(mesh.Mesh()) + return_value = service_lb_policy.ServiceLbPolicy.to_json( + service_lb_policy.ServiceLbPolicy() + ) req.return_value.content = return_value - request = mesh.GetMeshRequest() + request = service_lb_policy.GetServiceLbPolicyRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = mesh.Mesh() - post_with_metadata.return_value = mesh.Mesh(), metadata + post.return_value = service_lb_policy.ServiceLbPolicy() + post_with_metadata.return_value = service_lb_policy.ServiceLbPolicy(), metadata - client.get_mesh( + client.get_service_lb_policy( request, metadata=[ ("key", "val"), @@ -46699,7 +50858,9 @@ def test_get_mesh_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_create_mesh_rest_bad_request(request_type=gcn_mesh.CreateMeshRequest): +def test_create_service_lb_policy_rest_bad_request( + request_type=gcn_service_lb_policy.CreateServiceLbPolicyRequest, +): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -46720,39 +50881,42 @@ def test_create_mesh_rest_bad_request(request_type=gcn_mesh.CreateMeshRequest): response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_mesh(request) + client.create_service_lb_policy(request) @pytest.mark.parametrize( "request_type", [ - gcn_mesh.CreateMeshRequest, + gcn_service_lb_policy.CreateServiceLbPolicyRequest, dict, ], ) -def test_create_mesh_rest_call_success(request_type): +def test_create_service_lb_policy_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = {"parent": "projects/sample1/locations/sample2"} - request_init["mesh"] = { + request_init["service_lb_policy"] = { "name": "name_value", - "self_link": "self_link_value", "create_time": {"seconds": 751, "nanos": 543}, "update_time": {}, "labels": {}, "description": "description_value", - "interception_port": 1848, - "envoy_headers": 1, + "load_balancing_algorithm": 3, + "auto_capacity_drain": {"enable": True}, + "failover_config": {"failover_health_threshold": 2649}, + "isolation_config": {"isolation_granularity": 1, "isolation_mode": 1}, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = gcn_mesh.CreateMeshRequest.meta.fields["mesh"] + test_field = gcn_service_lb_policy.CreateServiceLbPolicyRequest.meta.fields[ + "service_lb_policy" + ] def get_message_fields(field): # Given a field which is a message (composite type), return a list with @@ -46780,7 +50944,7 @@ def get_message_fields(field): # For each item in the sample request, create a list of sub fields which are not present at runtime # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["mesh"].items(): # pragma: NO COVER + for field, value in request_init["service_lb_policy"].items(): # pragma: NO COVER result = None is_repeated = False # For repeated fields @@ -46810,10 +50974,10 @@ def get_message_fields(field): subfield = subfield_to_delete.get("subfield") if subfield: if field_repeated: - for i in range(0, len(request_init["mesh"][field])): - del request_init["mesh"][field][i][subfield] + for i in range(0, len(request_init["service_lb_policy"][field])): + del request_init["service_lb_policy"][field][i][subfield] else: - del request_init["mesh"][field][subfield] + del request_init["service_lb_policy"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -46828,14 +50992,14 @@ def get_message_fields(field): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_mesh(request) + response = client.create_service_lb_policy(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_mesh_rest_interceptors(null_interceptor): +def test_create_service_lb_policy_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -46849,19 +51013,22 @@ def test_create_mesh_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_create_mesh" + transports.NetworkServicesRestInterceptor, "post_create_service_lb_policy" ) as post, mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_create_mesh_with_metadata" + transports.NetworkServicesRestInterceptor, + "post_create_service_lb_policy_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_create_mesh" + transports.NetworkServicesRestInterceptor, "pre_create_service_lb_policy" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = gcn_mesh.CreateMeshRequest.pb(gcn_mesh.CreateMeshRequest()) + pb_message = gcn_service_lb_policy.CreateServiceLbPolicyRequest.pb( + gcn_service_lb_policy.CreateServiceLbPolicyRequest() + ) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -46875,7 +51042,7 @@ def test_create_mesh_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = gcn_mesh.CreateMeshRequest() + request = gcn_service_lb_policy.CreateServiceLbPolicyRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -46884,7 +51051,7 @@ def test_create_mesh_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.create_mesh( + client.create_service_lb_policy( request, metadata=[ ("key", "val"), @@ -46897,13 +51064,17 @@ def test_create_mesh_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_update_mesh_rest_bad_request(request_type=gcn_mesh.UpdateMeshRequest): +def test_update_service_lb_policy_rest_bad_request( + request_type=gcn_service_lb_policy.UpdateServiceLbPolicyRequest, +): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "mesh": {"name": "projects/sample1/locations/sample2/meshes/sample3"} + "service_lb_policy": { + "name": "projects/sample1/locations/sample2/serviceLbPolicies/sample3" + } } request = request_type(**request_init) @@ -46920,41 +51091,46 @@ def test_update_mesh_rest_bad_request(request_type=gcn_mesh.UpdateMeshRequest): response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_mesh(request) + client.update_service_lb_policy(request) @pytest.mark.parametrize( "request_type", [ - gcn_mesh.UpdateMeshRequest, + gcn_service_lb_policy.UpdateServiceLbPolicyRequest, dict, ], ) -def test_update_mesh_rest_call_success(request_type): +def test_update_service_lb_policy_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "mesh": {"name": "projects/sample1/locations/sample2/meshes/sample3"} + "service_lb_policy": { + "name": "projects/sample1/locations/sample2/serviceLbPolicies/sample3" + } } - request_init["mesh"] = { - "name": "projects/sample1/locations/sample2/meshes/sample3", - "self_link": "self_link_value", + request_init["service_lb_policy"] = { + "name": "projects/sample1/locations/sample2/serviceLbPolicies/sample3", "create_time": {"seconds": 751, "nanos": 543}, "update_time": {}, "labels": {}, "description": "description_value", - "interception_port": 1848, - "envoy_headers": 1, + "load_balancing_algorithm": 3, + "auto_capacity_drain": {"enable": True}, + "failover_config": {"failover_health_threshold": 2649}, + "isolation_config": {"isolation_granularity": 1, "isolation_mode": 1}, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = gcn_mesh.UpdateMeshRequest.meta.fields["mesh"] + test_field = gcn_service_lb_policy.UpdateServiceLbPolicyRequest.meta.fields[ + "service_lb_policy" + ] def get_message_fields(field): # Given a field which is a message (composite type), return a list with @@ -46982,7 +51158,7 @@ def get_message_fields(field): # For each item in the sample request, create a list of sub fields which are not present at runtime # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["mesh"].items(): # pragma: NO COVER + for field, value in request_init["service_lb_policy"].items(): # pragma: NO COVER result = None is_repeated = False # For repeated fields @@ -47012,10 +51188,10 @@ def get_message_fields(field): subfield = subfield_to_delete.get("subfield") if subfield: if field_repeated: - for i in range(0, len(request_init["mesh"][field])): - del request_init["mesh"][field][i][subfield] + for i in range(0, len(request_init["service_lb_policy"][field])): + del request_init["service_lb_policy"][field][i][subfield] else: - del request_init["mesh"][field][subfield] + del request_init["service_lb_policy"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -47030,14 +51206,14 @@ def get_message_fields(field): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_mesh(request) + response = client.update_service_lb_policy(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_mesh_rest_interceptors(null_interceptor): +def test_update_service_lb_policy_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -47051,19 +51227,22 @@ def test_update_mesh_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_update_mesh" + transports.NetworkServicesRestInterceptor, "post_update_service_lb_policy" ) as post, mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_update_mesh_with_metadata" + transports.NetworkServicesRestInterceptor, + "post_update_service_lb_policy_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_update_mesh" + transports.NetworkServicesRestInterceptor, "pre_update_service_lb_policy" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = gcn_mesh.UpdateMeshRequest.pb(gcn_mesh.UpdateMeshRequest()) + pb_message = gcn_service_lb_policy.UpdateServiceLbPolicyRequest.pb( + gcn_service_lb_policy.UpdateServiceLbPolicyRequest() + ) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -47077,7 +51256,7 @@ def test_update_mesh_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = gcn_mesh.UpdateMeshRequest() + request = gcn_service_lb_policy.UpdateServiceLbPolicyRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -47086,7 +51265,7 @@ def test_update_mesh_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.update_mesh( + client.update_service_lb_policy( request, metadata=[ ("key", "val"), @@ -47099,12 +51278,16 @@ def test_update_mesh_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_delete_mesh_rest_bad_request(request_type=mesh.DeleteMeshRequest): +def test_delete_service_lb_policy_rest_bad_request( + request_type=service_lb_policy.DeleteServiceLbPolicyRequest, +): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/meshes/sample3"} + request_init = { + "name": "projects/sample1/locations/sample2/serviceLbPolicies/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -47120,23 +51303,25 @@ def test_delete_mesh_rest_bad_request(request_type=mesh.DeleteMeshRequest): response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_mesh(request) + client.delete_service_lb_policy(request) @pytest.mark.parametrize( "request_type", [ - mesh.DeleteMeshRequest, + service_lb_policy.DeleteServiceLbPolicyRequest, dict, ], ) -def test_delete_mesh_rest_call_success(request_type): +def test_delete_service_lb_policy_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/meshes/sample3"} + request_init = { + "name": "projects/sample1/locations/sample2/serviceLbPolicies/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -47151,14 +51336,14 @@ def test_delete_mesh_rest_call_success(request_type): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_mesh(request) + response = client.delete_service_lb_policy(request) # Establish that the response is the type that we expect. json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_mesh_rest_interceptors(null_interceptor): +def test_delete_service_lb_policy_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -47172,19 +51357,22 @@ def test_delete_mesh_rest_interceptors(null_interceptor): mock.patch.object(path_template, "transcode") as transcode, mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_delete_mesh" + transports.NetworkServicesRestInterceptor, "post_delete_service_lb_policy" ) as post, mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_delete_mesh_with_metadata" + transports.NetworkServicesRestInterceptor, + "post_delete_service_lb_policy_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_delete_mesh" + transports.NetworkServicesRestInterceptor, "pre_delete_service_lb_policy" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = mesh.DeleteMeshRequest.pb(mesh.DeleteMeshRequest()) + pb_message = service_lb_policy.DeleteServiceLbPolicyRequest.pb( + service_lb_policy.DeleteServiceLbPolicyRequest() + ) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -47198,7 +51386,7 @@ def test_delete_mesh_rest_interceptors(null_interceptor): return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = mesh.DeleteMeshRequest() + request = service_lb_policy.DeleteServiceLbPolicyRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -47207,7 +51395,7 @@ def test_delete_mesh_rest_interceptors(null_interceptor): post.return_value = operations_pb2.Operation() post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.delete_mesh( + client.delete_service_lb_policy( request, metadata=[ ("key", "val"), @@ -47220,14 +51408,16 @@ def test_delete_mesh_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_service_lb_policies_rest_bad_request( - request_type=service_lb_policy.ListServiceLbPoliciesRequest, +def test_get_gateway_route_view_rest_bad_request( + request_type=route_view.GetGatewayRouteViewRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} + request_init = { + "name": "projects/sample1/locations/sample2/gateways/sample3/routeViews/sample4" + } request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -47243,31 +51433,36 @@ def test_list_service_lb_policies_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_service_lb_policies(request) + client.get_gateway_route_view(request) @pytest.mark.parametrize( "request_type", [ - service_lb_policy.ListServiceLbPoliciesRequest, + route_view.GetGatewayRouteViewRequest, dict, ], ) -def test_list_service_lb_policies_rest_call_success(request_type): +def test_get_gateway_route_view_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} + request_init = { + "name": "projects/sample1/locations/sample2/gateways/sample3/routeViews/sample4" + } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = service_lb_policy.ListServiceLbPoliciesResponse( - next_page_token="next_page_token_value", - unreachable=["unreachable_value"], + return_value = route_view.GatewayRouteView( + name="name_value", + route_project_number=2157, + route_location="route_location_value", + route_type="route_type_value", + route_id="route_id_value", ) # Wrap the value into a proper Response obj @@ -47275,21 +51470,24 @@ def test_list_service_lb_policies_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = service_lb_policy.ListServiceLbPoliciesResponse.pb(return_value) + return_value = route_view.GatewayRouteView.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_service_lb_policies(request) + response = client.get_gateway_route_view(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListServiceLbPoliciesPager) - assert response.next_page_token == "next_page_token_value" - assert response.unreachable == ["unreachable_value"] + assert isinstance(response, route_view.GatewayRouteView) + assert response.name == "name_value" + assert response.route_project_number == 2157 + assert response.route_location == "route_location_value" + assert response.route_type == "route_type_value" + assert response.route_id == "route_id_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_service_lb_policies_rest_interceptors(null_interceptor): +def test_get_gateway_route_view_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -47302,21 +51500,21 @@ def test_list_service_lb_policies_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_list_service_lb_policies" + transports.NetworkServicesRestInterceptor, "post_get_gateway_route_view" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_list_service_lb_policies_with_metadata", + "post_get_gateway_route_view_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_list_service_lb_policies" + transports.NetworkServicesRestInterceptor, "pre_get_gateway_route_view" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = service_lb_policy.ListServiceLbPoliciesRequest.pb( - service_lb_policy.ListServiceLbPoliciesRequest() + pb_message = route_view.GetGatewayRouteViewRequest.pb( + route_view.GetGatewayRouteViewRequest() ) transcode.return_value = { "method": "post", @@ -47328,24 +51526,21 @@ def test_list_service_lb_policies_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = service_lb_policy.ListServiceLbPoliciesResponse.to_json( - service_lb_policy.ListServiceLbPoliciesResponse() + return_value = route_view.GatewayRouteView.to_json( + route_view.GatewayRouteView() ) req.return_value.content = return_value - request = service_lb_policy.ListServiceLbPoliciesRequest() + request = route_view.GetGatewayRouteViewRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = service_lb_policy.ListServiceLbPoliciesResponse() - post_with_metadata.return_value = ( - service_lb_policy.ListServiceLbPoliciesResponse(), - metadata, - ) + post.return_value = route_view.GatewayRouteView() + post_with_metadata.return_value = route_view.GatewayRouteView(), metadata - client.list_service_lb_policies( + client.get_gateway_route_view( request, metadata=[ ("key", "val"), @@ -47358,15 +51553,15 @@ def test_list_service_lb_policies_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_get_service_lb_policy_rest_bad_request( - request_type=service_lb_policy.GetServiceLbPolicyRequest, +def test_get_mesh_route_view_rest_bad_request( + request_type=route_view.GetMeshRouteViewRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/serviceLbPolicies/sample3" + "name": "projects/sample1/locations/sample2/meshes/sample3/routeViews/sample4" } request = request_type(**request_init) @@ -47383,34 +51578,36 @@ def test_get_service_lb_policy_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_service_lb_policy(request) + client.get_mesh_route_view(request) @pytest.mark.parametrize( "request_type", [ - service_lb_policy.GetServiceLbPolicyRequest, + route_view.GetMeshRouteViewRequest, dict, ], ) -def test_get_service_lb_policy_rest_call_success(request_type): +def test_get_mesh_route_view_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding request_init = { - "name": "projects/sample1/locations/sample2/serviceLbPolicies/sample3" + "name": "projects/sample1/locations/sample2/meshes/sample3/routeViews/sample4" } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = service_lb_policy.ServiceLbPolicy( + return_value = route_view.MeshRouteView( name="name_value", - description="description_value", - load_balancing_algorithm=service_lb_policy.ServiceLbPolicy.LoadBalancingAlgorithm.SPRAY_TO_WORLD, + route_project_number=2157, + route_location="route_location_value", + route_type="route_type_value", + route_id="route_id_value", ) # Wrap the value into a proper Response obj @@ -47418,25 +51615,24 @@ def test_get_service_lb_policy_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = service_lb_policy.ServiceLbPolicy.pb(return_value) + return_value = route_view.MeshRouteView.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_service_lb_policy(request) + response = client.get_mesh_route_view(request) # Establish that the response is the type that we expect. - assert isinstance(response, service_lb_policy.ServiceLbPolicy) + assert isinstance(response, route_view.MeshRouteView) assert response.name == "name_value" - assert response.description == "description_value" - assert ( - response.load_balancing_algorithm - == service_lb_policy.ServiceLbPolicy.LoadBalancingAlgorithm.SPRAY_TO_WORLD - ) + assert response.route_project_number == 2157 + assert response.route_location == "route_location_value" + assert response.route_type == "route_type_value" + assert response.route_id == "route_id_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_service_lb_policy_rest_interceptors(null_interceptor): +def test_get_mesh_route_view_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -47449,21 +51645,21 @@ def test_get_service_lb_policy_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_get_service_lb_policy" + transports.NetworkServicesRestInterceptor, "post_get_mesh_route_view" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_get_service_lb_policy_with_metadata", + "post_get_mesh_route_view_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_get_service_lb_policy" + transports.NetworkServicesRestInterceptor, "pre_get_mesh_route_view" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = service_lb_policy.GetServiceLbPolicyRequest.pb( - service_lb_policy.GetServiceLbPolicyRequest() + pb_message = route_view.GetMeshRouteViewRequest.pb( + route_view.GetMeshRouteViewRequest() ) transcode.return_value = { "method": "post", @@ -47475,21 +51671,19 @@ def test_get_service_lb_policy_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = service_lb_policy.ServiceLbPolicy.to_json( - service_lb_policy.ServiceLbPolicy() - ) + return_value = route_view.MeshRouteView.to_json(route_view.MeshRouteView()) req.return_value.content = return_value - request = service_lb_policy.GetServiceLbPolicyRequest() + request = route_view.GetMeshRouteViewRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = service_lb_policy.ServiceLbPolicy() - post_with_metadata.return_value = service_lb_policy.ServiceLbPolicy(), metadata + post.return_value = route_view.MeshRouteView() + post_with_metadata.return_value = route_view.MeshRouteView(), metadata - client.get_service_lb_policy( + client.get_mesh_route_view( request, metadata=[ ("key", "val"), @@ -47502,14 +51696,14 @@ def test_get_service_lb_policy_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_create_service_lb_policy_rest_bad_request( - request_type=gcn_service_lb_policy.CreateServiceLbPolicyRequest, +def test_list_gateway_route_views_rest_bad_request( + request_type=route_view.ListGatewayRouteViewsRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} + request_init = {"parent": "projects/sample1/locations/sample2/gateways/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -47525,125 +51719,53 @@ def test_create_service_lb_policy_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.create_service_lb_policy(request) + client.list_gateway_route_views(request) @pytest.mark.parametrize( "request_type", [ - gcn_service_lb_policy.CreateServiceLbPolicyRequest, + route_view.ListGatewayRouteViewsRequest, dict, ], ) -def test_create_service_lb_policy_rest_call_success(request_type): +def test_list_gateway_route_views_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} - request_init["service_lb_policy"] = { - "name": "name_value", - "create_time": {"seconds": 751, "nanos": 543}, - "update_time": {}, - "labels": {}, - "description": "description_value", - "load_balancing_algorithm": 3, - "auto_capacity_drain": {"enable": True}, - "failover_config": {"failover_health_threshold": 2649}, - "isolation_config": {"isolation_granularity": 1, "isolation_mode": 1}, - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = gcn_service_lb_policy.CreateServiceLbPolicyRequest.meta.fields[ - "service_lb_policy" - ] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["service_lb_policy"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["service_lb_policy"][field])): - del request_init["service_lb_policy"][field][i][subfield] - else: - del request_init["service_lb_policy"][field][subfield] + request_init = {"parent": "projects/sample1/locations/sample2/gateways/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = route_view.ListGatewayRouteViewsResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = route_view.ListGatewayRouteViewsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.create_service_lb_policy(request) + response = client.list_gateway_route_views(request) # Establish that the response is the type that we expect. - json_return_value = json_format.MessageToJson(return_value) + assert isinstance(response, pagers.ListGatewayRouteViewsPager) + assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_service_lb_policy_rest_interceptors(null_interceptor): +def test_list_gateway_route_views_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -47655,23 +51777,22 @@ def test_create_service_lb_policy_rest_interceptors(null_interceptor): with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, - mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_create_service_lb_policy" + transports.NetworkServicesRestInterceptor, "post_list_gateway_route_views" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_create_service_lb_policy_with_metadata", + "post_list_gateway_route_views_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_create_service_lb_policy" + transports.NetworkServicesRestInterceptor, "pre_list_gateway_route_views" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = gcn_service_lb_policy.CreateServiceLbPolicyRequest.pb( - gcn_service_lb_policy.CreateServiceLbPolicyRequest() + pb_message = route_view.ListGatewayRouteViewsRequest.pb( + route_view.ListGatewayRouteViewsRequest() ) transcode.return_value = { "method": "post", @@ -47683,19 +51804,24 @@ def test_create_service_lb_policy_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = json_format.MessageToJson(operations_pb2.Operation()) + return_value = route_view.ListGatewayRouteViewsResponse.to_json( + route_view.ListGatewayRouteViewsResponse() + ) req.return_value.content = return_value - request = gcn_service_lb_policy.CreateServiceLbPolicyRequest() + request = route_view.ListGatewayRouteViewsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() - post_with_metadata.return_value = operations_pb2.Operation(), metadata + post.return_value = route_view.ListGatewayRouteViewsResponse() + post_with_metadata.return_value = ( + route_view.ListGatewayRouteViewsResponse(), + metadata, + ) - client.create_service_lb_policy( + client.list_gateway_route_views( request, metadata=[ ("key", "val"), @@ -47708,18 +51834,14 @@ def test_create_service_lb_policy_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_update_service_lb_policy_rest_bad_request( - request_type=gcn_service_lb_policy.UpdateServiceLbPolicyRequest, +def test_list_mesh_route_views_rest_bad_request( + request_type=route_view.ListMeshRouteViewsRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "service_lb_policy": { - "name": "projects/sample1/locations/sample2/serviceLbPolicies/sample3" - } - } + request_init = {"parent": "projects/sample1/locations/sample2/meshes/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -47735,129 +51857,53 @@ def test_update_service_lb_policy_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_service_lb_policy(request) + client.list_mesh_route_views(request) @pytest.mark.parametrize( "request_type", [ - gcn_service_lb_policy.UpdateServiceLbPolicyRequest, + route_view.ListMeshRouteViewsRequest, dict, ], ) -def test_update_service_lb_policy_rest_call_success(request_type): +def test_list_mesh_route_views_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "service_lb_policy": { - "name": "projects/sample1/locations/sample2/serviceLbPolicies/sample3" - } - } - request_init["service_lb_policy"] = { - "name": "projects/sample1/locations/sample2/serviceLbPolicies/sample3", - "create_time": {"seconds": 751, "nanos": 543}, - "update_time": {}, - "labels": {}, - "description": "description_value", - "load_balancing_algorithm": 3, - "auto_capacity_drain": {"enable": True}, - "failover_config": {"failover_health_threshold": 2649}, - "isolation_config": {"isolation_granularity": 1, "isolation_mode": 1}, - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = gcn_service_lb_policy.UpdateServiceLbPolicyRequest.meta.fields[ - "service_lb_policy" - ] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["service_lb_policy"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["service_lb_policy"][field])): - del request_init["service_lb_policy"][field][i][subfield] - else: - del request_init["service_lb_policy"][field][subfield] + request_init = {"parent": "projects/sample1/locations/sample2/meshes/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = route_view.ListMeshRouteViewsResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = route_view.ListMeshRouteViewsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_service_lb_policy(request) + response = client.list_mesh_route_views(request) # Establish that the response is the type that we expect. - json_return_value = json_format.MessageToJson(return_value) + assert isinstance(response, pagers.ListMeshRouteViewsPager) + assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_service_lb_policy_rest_interceptors(null_interceptor): +def test_list_mesh_route_views_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -47869,23 +51915,22 @@ def test_update_service_lb_policy_rest_interceptors(null_interceptor): with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, - mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_update_service_lb_policy" + transports.NetworkServicesRestInterceptor, "post_list_mesh_route_views" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_update_service_lb_policy_with_metadata", + "post_list_mesh_route_views_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_update_service_lb_policy" + transports.NetworkServicesRestInterceptor, "pre_list_mesh_route_views" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = gcn_service_lb_policy.UpdateServiceLbPolicyRequest.pb( - gcn_service_lb_policy.UpdateServiceLbPolicyRequest() + pb_message = route_view.ListMeshRouteViewsRequest.pb( + route_view.ListMeshRouteViewsRequest() ) transcode.return_value = { "method": "post", @@ -47897,19 +51942,24 @@ def test_update_service_lb_policy_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = json_format.MessageToJson(operations_pb2.Operation()) + return_value = route_view.ListMeshRouteViewsResponse.to_json( + route_view.ListMeshRouteViewsResponse() + ) req.return_value.content = return_value - request = gcn_service_lb_policy.UpdateServiceLbPolicyRequest() + request = route_view.ListMeshRouteViewsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() - post_with_metadata.return_value = operations_pb2.Operation(), metadata + post.return_value = route_view.ListMeshRouteViewsResponse() + post_with_metadata.return_value = ( + route_view.ListMeshRouteViewsResponse(), + metadata, + ) - client.update_service_lb_policy( + client.list_mesh_route_views( request, metadata=[ ("key", "val"), @@ -47922,16 +51972,14 @@ def test_update_service_lb_policy_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_delete_service_lb_policy_rest_bad_request( - request_type=service_lb_policy.DeleteServiceLbPolicyRequest, +def test_list_agent_gateways_rest_bad_request( + request_type=agent_gateway.ListAgentGatewaysRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/serviceLbPolicies/sample3" - } + request_init = {"parent": "projects/sample1/locations/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -47947,47 +51995,53 @@ def test_delete_service_lb_policy_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_service_lb_policy(request) + client.list_agent_gateways(request) @pytest.mark.parametrize( "request_type", [ - service_lb_policy.DeleteServiceLbPolicyRequest, + agent_gateway.ListAgentGatewaysRequest, dict, ], ) -def test_delete_service_lb_policy_rest_call_success(request_type): +def test_list_agent_gateways_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/serviceLbPolicies/sample3" - } + request_init = {"parent": "projects/sample1/locations/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = agent_gateway.ListAgentGatewaysResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = agent_gateway.ListAgentGatewaysResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_service_lb_policy(request) + response = client.list_agent_gateways(request) # Establish that the response is the type that we expect. - json_return_value = json_format.MessageToJson(return_value) + assert isinstance(response, pagers.ListAgentGatewaysPager) + assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_service_lb_policy_rest_interceptors(null_interceptor): +def test_list_agent_gateways_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -47999,23 +52053,22 @@ def test_delete_service_lb_policy_rest_interceptors(null_interceptor): with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, - mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_delete_service_lb_policy" + transports.NetworkServicesRestInterceptor, "post_list_agent_gateways" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_delete_service_lb_policy_with_metadata", + "post_list_agent_gateways_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_delete_service_lb_policy" + transports.NetworkServicesRestInterceptor, "pre_list_agent_gateways" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = service_lb_policy.DeleteServiceLbPolicyRequest.pb( - service_lb_policy.DeleteServiceLbPolicyRequest() + pb_message = agent_gateway.ListAgentGatewaysRequest.pb( + agent_gateway.ListAgentGatewaysRequest() ) transcode.return_value = { "method": "post", @@ -48027,19 +52080,24 @@ def test_delete_service_lb_policy_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = json_format.MessageToJson(operations_pb2.Operation()) + return_value = agent_gateway.ListAgentGatewaysResponse.to_json( + agent_gateway.ListAgentGatewaysResponse() + ) req.return_value.content = return_value - request = service_lb_policy.DeleteServiceLbPolicyRequest() + request = agent_gateway.ListAgentGatewaysRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() - post_with_metadata.return_value = operations_pb2.Operation(), metadata + post.return_value = agent_gateway.ListAgentGatewaysResponse() + post_with_metadata.return_value = ( + agent_gateway.ListAgentGatewaysResponse(), + metadata, + ) - client.delete_service_lb_policy( + client.list_agent_gateways( request, metadata=[ ("key", "val"), @@ -48052,16 +52110,14 @@ def test_delete_service_lb_policy_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_get_gateway_route_view_rest_bad_request( - request_type=route_view.GetGatewayRouteViewRequest, +def test_get_agent_gateway_rest_bad_request( + request_type=agent_gateway.GetAgentGatewayRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/gateways/sample3/routeViews/sample4" - } + request_init = {"name": "projects/sample1/locations/sample2/agentGateways/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -48077,36 +52133,34 @@ def test_get_gateway_route_view_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_gateway_route_view(request) + client.get_agent_gateway(request) @pytest.mark.parametrize( "request_type", [ - route_view.GetGatewayRouteViewRequest, + agent_gateway.GetAgentGatewayRequest, dict, ], ) -def test_get_gateway_route_view_rest_call_success(request_type): +def test_get_agent_gateway_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/gateways/sample3/routeViews/sample4" - } + request_init = {"name": "projects/sample1/locations/sample2/agentGateways/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = route_view.GatewayRouteView( + return_value = agent_gateway.AgentGateway( name="name_value", - route_project_number=2157, - route_location="route_location_value", - route_type="route_type_value", - route_id="route_id_value", + description="description_value", + etag="etag_value", + protocols=[agent_gateway.AgentGateway.Protocol.MCP], + registries=["registries_value"], ) # Wrap the value into a proper Response obj @@ -48114,24 +52168,24 @@ def test_get_gateway_route_view_rest_call_success(request_type): response_value.status_code = 200 # Convert return value to protobuf type - return_value = route_view.GatewayRouteView.pb(return_value) + return_value = agent_gateway.AgentGateway.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_gateway_route_view(request) + response = client.get_agent_gateway(request) # Establish that the response is the type that we expect. - assert isinstance(response, route_view.GatewayRouteView) + assert isinstance(response, agent_gateway.AgentGateway) assert response.name == "name_value" - assert response.route_project_number == 2157 - assert response.route_location == "route_location_value" - assert response.route_type == "route_type_value" - assert response.route_id == "route_id_value" + assert response.description == "description_value" + assert response.etag == "etag_value" + assert response.protocols == [agent_gateway.AgentGateway.Protocol.MCP] + assert response.registries == ["registries_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_gateway_route_view_rest_interceptors(null_interceptor): +def test_get_agent_gateway_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -48144,21 +52198,21 @@ def test_get_gateway_route_view_rest_interceptors(null_interceptor): mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_get_gateway_route_view" + transports.NetworkServicesRestInterceptor, "post_get_agent_gateway" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_get_gateway_route_view_with_metadata", + "post_get_agent_gateway_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_get_gateway_route_view" + transports.NetworkServicesRestInterceptor, "pre_get_agent_gateway" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = route_view.GetGatewayRouteViewRequest.pb( - route_view.GetGatewayRouteViewRequest() + pb_message = agent_gateway.GetAgentGatewayRequest.pb( + agent_gateway.GetAgentGatewayRequest() ) transcode.return_value = { "method": "post", @@ -48170,21 +52224,19 @@ def test_get_gateway_route_view_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = route_view.GatewayRouteView.to_json( - route_view.GatewayRouteView() - ) + return_value = agent_gateway.AgentGateway.to_json(agent_gateway.AgentGateway()) req.return_value.content = return_value - request = route_view.GetGatewayRouteViewRequest() + request = agent_gateway.GetAgentGatewayRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = route_view.GatewayRouteView() - post_with_metadata.return_value = route_view.GatewayRouteView(), metadata + post.return_value = agent_gateway.AgentGateway() + post_with_metadata.return_value = agent_gateway.AgentGateway(), metadata - client.get_gateway_route_view( + client.get_agent_gateway( request, metadata=[ ("key", "val"), @@ -48197,16 +52249,14 @@ def test_get_gateway_route_view_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_get_mesh_route_view_rest_bad_request( - request_type=route_view.GetMeshRouteViewRequest, +def test_create_agent_gateway_rest_bad_request( + request_type=gcn_agent_gateway.CreateAgentGatewayRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/meshes/sample3/routeViews/sample4" - } + request_init = {"parent": "projects/sample1/locations/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -48222,61 +52272,150 @@ def test_get_mesh_route_view_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_mesh_route_view(request) + client.create_agent_gateway(request) @pytest.mark.parametrize( "request_type", [ - route_view.GetMeshRouteViewRequest, + gcn_agent_gateway.CreateAgentGatewayRequest, dict, ], ) -def test_get_mesh_route_view_rest_call_success(request_type): +def test_create_agent_gateway_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/meshes/sample3/routeViews/sample4" + request_init = {"parent": "projects/sample1/locations/sample2"} + request_init["agent_gateway"] = { + "google_managed": {"governed_access_path": 1}, + "self_managed": {"resource_uri": "resource_uri_value"}, + "name": "name_value", + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "labels": {}, + "description": "description_value", + "etag": "etag_value", + "protocols": [1], + "registries": ["registries_value1", "registries_value2"], + "network_config": { + "egress": { + "network_attachment": "network_attachment_value", + "trust_config": { + "pem_certificates": [ + "pem_certificates_value1", + "pem_certificates_value2", + ] + }, + }, + "dns_peering_config": { + "domains": ["domains_value1", "domains_value2"], + "target_project": "target_project_value", + "target_network": "target_network_value", + }, + }, + "agent_gateway_card": { + "mtls_endpoint": "mtls_endpoint_value", + "root_certificates": [ + "root_certificates_value1", + "root_certificates_value2", + ], + "service_extensions_service_account": "service_extensions_service_account_value", + }, } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = gcn_agent_gateway.CreateAgentGatewayRequest.meta.fields[ + "agent_gateway" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["agent_gateway"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["agent_gateway"][field])): + del request_init["agent_gateway"][field][i][subfield] + else: + del request_init["agent_gateway"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = route_view.MeshRouteView( - name="name_value", - route_project_number=2157, - route_location="route_location_value", - route_type="route_type_value", - route_id="route_id_value", - ) + return_value = operations_pb2.Operation(name="operations/spam") # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = route_view.MeshRouteView.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_mesh_route_view(request) + response = client.create_agent_gateway(request) # Establish that the response is the type that we expect. - assert isinstance(response, route_view.MeshRouteView) - assert response.name == "name_value" - assert response.route_project_number == 2157 - assert response.route_location == "route_location_value" - assert response.route_type == "route_type_value" - assert response.route_id == "route_id_value" + json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_mesh_route_view_rest_interceptors(null_interceptor): +def test_create_agent_gateway_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -48288,22 +52427,23 @@ def test_get_mesh_route_view_rest_interceptors(null_interceptor): with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_get_mesh_route_view" + transports.NetworkServicesRestInterceptor, "post_create_agent_gateway" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_get_mesh_route_view_with_metadata", + "post_create_agent_gateway_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_get_mesh_route_view" + transports.NetworkServicesRestInterceptor, "pre_create_agent_gateway" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = route_view.GetMeshRouteViewRequest.pb( - route_view.GetMeshRouteViewRequest() + pb_message = gcn_agent_gateway.CreateAgentGatewayRequest.pb( + gcn_agent_gateway.CreateAgentGatewayRequest() ) transcode.return_value = { "method": "post", @@ -48315,19 +52455,19 @@ def test_get_mesh_route_view_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = route_view.MeshRouteView.to_json(route_view.MeshRouteView()) + return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = route_view.GetMeshRouteViewRequest() + request = gcn_agent_gateway.CreateAgentGatewayRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = route_view.MeshRouteView() - post_with_metadata.return_value = route_view.MeshRouteView(), metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.get_mesh_route_view( + client.create_agent_gateway( request, metadata=[ ("key", "val"), @@ -48340,14 +52480,18 @@ def test_get_mesh_route_view_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_gateway_route_views_rest_bad_request( - request_type=route_view.ListGatewayRouteViewsRequest, +def test_update_agent_gateway_rest_bad_request( + request_type=gcn_agent_gateway.UpdateAgentGatewayRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2/gateways/sample3"} + request_init = { + "agent_gateway": { + "name": "projects/sample1/locations/sample2/agentGateways/sample3" + } + } request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -48363,53 +52507,154 @@ def test_list_gateway_route_views_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_gateway_route_views(request) + client.update_agent_gateway(request) @pytest.mark.parametrize( "request_type", [ - route_view.ListGatewayRouteViewsRequest, + gcn_agent_gateway.UpdateAgentGatewayRequest, dict, ], ) -def test_list_gateway_route_views_rest_call_success(request_type): +def test_update_agent_gateway_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2/gateways/sample3"} + request_init = { + "agent_gateway": { + "name": "projects/sample1/locations/sample2/agentGateways/sample3" + } + } + request_init["agent_gateway"] = { + "google_managed": {"governed_access_path": 1}, + "self_managed": {"resource_uri": "resource_uri_value"}, + "name": "projects/sample1/locations/sample2/agentGateways/sample3", + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "labels": {}, + "description": "description_value", + "etag": "etag_value", + "protocols": [1], + "registries": ["registries_value1", "registries_value2"], + "network_config": { + "egress": { + "network_attachment": "network_attachment_value", + "trust_config": { + "pem_certificates": [ + "pem_certificates_value1", + "pem_certificates_value2", + ] + }, + }, + "dns_peering_config": { + "domains": ["domains_value1", "domains_value2"], + "target_project": "target_project_value", + "target_network": "target_network_value", + }, + }, + "agent_gateway_card": { + "mtls_endpoint": "mtls_endpoint_value", + "root_certificates": [ + "root_certificates_value1", + "root_certificates_value2", + ], + "service_extensions_service_account": "service_extensions_service_account_value", + }, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = gcn_agent_gateway.UpdateAgentGatewayRequest.meta.fields[ + "agent_gateway" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["agent_gateway"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["agent_gateway"][field])): + del request_init["agent_gateway"][field][i][subfield] + else: + del request_init["agent_gateway"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = route_view.ListGatewayRouteViewsResponse( - next_page_token="next_page_token_value", - unreachable=["unreachable_value"], - ) + return_value = operations_pb2.Operation(name="operations/spam") # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = route_view.ListGatewayRouteViewsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_gateway_route_views(request) + response = client.update_agent_gateway(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListGatewayRouteViewsPager) - assert response.next_page_token == "next_page_token_value" - assert response.unreachable == ["unreachable_value"] + json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_gateway_route_views_rest_interceptors(null_interceptor): +def test_update_agent_gateway_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -48421,22 +52666,23 @@ def test_list_gateway_route_views_rest_interceptors(null_interceptor): with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_list_gateway_route_views" + transports.NetworkServicesRestInterceptor, "post_update_agent_gateway" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_list_gateway_route_views_with_metadata", + "post_update_agent_gateway_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_list_gateway_route_views" + transports.NetworkServicesRestInterceptor, "pre_update_agent_gateway" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = route_view.ListGatewayRouteViewsRequest.pb( - route_view.ListGatewayRouteViewsRequest() + pb_message = gcn_agent_gateway.UpdateAgentGatewayRequest.pb( + gcn_agent_gateway.UpdateAgentGatewayRequest() ) transcode.return_value = { "method": "post", @@ -48448,24 +52694,19 @@ def test_list_gateway_route_views_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = route_view.ListGatewayRouteViewsResponse.to_json( - route_view.ListGatewayRouteViewsResponse() - ) + return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = route_view.ListGatewayRouteViewsRequest() + request = gcn_agent_gateway.UpdateAgentGatewayRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = route_view.ListGatewayRouteViewsResponse() - post_with_metadata.return_value = ( - route_view.ListGatewayRouteViewsResponse(), - metadata, - ) + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.list_gateway_route_views( + client.update_agent_gateway( request, metadata=[ ("key", "val"), @@ -48478,14 +52719,14 @@ def test_list_gateway_route_views_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_mesh_route_views_rest_bad_request( - request_type=route_view.ListMeshRouteViewsRequest, +def test_delete_agent_gateway_rest_bad_request( + request_type=agent_gateway.DeleteAgentGatewayRequest, ): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2/meshes/sample3"} + request_init = {"name": "projects/sample1/locations/sample2/agentGateways/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -48501,53 +52742,45 @@ def test_list_mesh_route_views_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_mesh_route_views(request) + client.delete_agent_gateway(request) @pytest.mark.parametrize( "request_type", [ - route_view.ListMeshRouteViewsRequest, + agent_gateway.DeleteAgentGatewayRequest, dict, ], ) -def test_list_mesh_route_views_rest_call_success(request_type): +def test_delete_agent_gateway_rest_call_success(request_type): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2/meshes/sample3"} + request_init = {"name": "projects/sample1/locations/sample2/agentGateways/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = route_view.ListMeshRouteViewsResponse( - next_page_token="next_page_token_value", - unreachable=["unreachable_value"], - ) + return_value = operations_pb2.Operation(name="operations/spam") # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = route_view.ListMeshRouteViewsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_mesh_route_views(request) + response = client.delete_agent_gateway(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListMeshRouteViewsPager) - assert response.next_page_token == "next_page_token_value" - assert response.unreachable == ["unreachable_value"] + json_return_value = json_format.MessageToJson(return_value) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_mesh_route_views_rest_interceptors(null_interceptor): +def test_delete_agent_gateway_rest_interceptors(null_interceptor): transport = transports.NetworkServicesRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -48559,22 +52792,23 @@ def test_list_mesh_route_views_rest_interceptors(null_interceptor): with ( mock.patch.object(type(client.transport._session), "request") as req, mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), mock.patch.object( - transports.NetworkServicesRestInterceptor, "post_list_mesh_route_views" + transports.NetworkServicesRestInterceptor, "post_delete_agent_gateway" ) as post, mock.patch.object( transports.NetworkServicesRestInterceptor, - "post_list_mesh_route_views_with_metadata", + "post_delete_agent_gateway_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.NetworkServicesRestInterceptor, "pre_list_mesh_route_views" + transports.NetworkServicesRestInterceptor, "pre_delete_agent_gateway" ) as pre, ): pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = route_view.ListMeshRouteViewsRequest.pb( - route_view.ListMeshRouteViewsRequest() + pb_message = agent_gateway.DeleteAgentGatewayRequest.pb( + agent_gateway.DeleteAgentGatewayRequest() ) transcode.return_value = { "method": "post", @@ -48586,24 +52820,19 @@ def test_list_mesh_route_views_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = route_view.ListMeshRouteViewsResponse.to_json( - route_view.ListMeshRouteViewsResponse() - ) + return_value = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value - request = route_view.ListMeshRouteViewsRequest() + request = agent_gateway.DeleteAgentGatewayRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = route_view.ListMeshRouteViewsResponse() - post_with_metadata.return_value = ( - route_view.ListMeshRouteViewsResponse(), - metadata, - ) + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata - client.list_mesh_route_views( + client.delete_agent_gateway( request, metadata=[ ("key", "val"), @@ -50363,6 +54592,111 @@ def test_list_mesh_route_views_empty_call_rest(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_agent_gateways_empty_call_rest(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_agent_gateways), "__call__" + ) as call: + client.list_agent_gateways(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = agent_gateway.ListAgentGatewaysRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_agent_gateway_empty_call_rest(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_agent_gateway), "__call__" + ) as call: + client.get_agent_gateway(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = agent_gateway.GetAgentGatewayRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_agent_gateway_empty_call_rest(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_agent_gateway), "__call__" + ) as call: + client.create_agent_gateway(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_agent_gateway.CreateAgentGatewayRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_agent_gateway_empty_call_rest(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_agent_gateway), "__call__" + ) as call: + client.update_agent_gateway(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcn_agent_gateway.UpdateAgentGatewayRequest() + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_agent_gateway_empty_call_rest(): + client = NetworkServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_agent_gateway), "__call__" + ) as call: + client.delete_agent_gateway(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = agent_gateway.DeleteAgentGatewayRequest() + assert args[0] == request_msg + + def test_network_services_rest_lro_client(): client = NetworkServicesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -50471,6 +54805,11 @@ def test_network_services_base_transport(): "get_mesh_route_view", "list_gateway_route_views", "list_mesh_route_views", + "list_agent_gateways", + "get_agent_gateway", + "create_agent_gateway", + "update_agent_gateway", + "delete_agent_gateway", "set_iam_policy", "get_iam_policy", "test_iam_permissions", @@ -50924,6 +55263,21 @@ def test_network_services_client_transport_session_collision(transport_name): session1 = client1.transport.list_mesh_route_views._session session2 = client2.transport.list_mesh_route_views._session assert session1 != session2 + session1 = client1.transport.list_agent_gateways._session + session2 = client2.transport.list_agent_gateways._session + assert session1 != session2 + session1 = client1.transport.get_agent_gateway._session + session2 = client2.transport.get_agent_gateway._session + assert session1 != session2 + session1 = client1.transport.create_agent_gateway._session + session2 = client2.transport.create_agent_gateway._session + assert session1 != session2 + session1 = client1.transport.update_agent_gateway._session + session2 = client2.transport.update_agent_gateway._session + assert session1 != session2 + session1 = client1.transport.delete_agent_gateway._session + session2 = client2.transport.delete_agent_gateway._session + assert session1 != session2 def test_network_services_grpc_transport_channel(): @@ -51113,10 +55467,38 @@ def test_parse_address_path(): assert expected == actual -def test_authorization_policy_path(): +def test_agent_gateway_path(): project = "cuttlefish" location = "mussel" - authorization_policy = "winkle" + agent_gateway = "winkle" + expected = ( + "projects/{project}/locations/{location}/agentGateways/{agent_gateway}".format( + project=project, + location=location, + agent_gateway=agent_gateway, + ) + ) + actual = NetworkServicesClient.agent_gateway_path(project, location, agent_gateway) + assert expected == actual + + +def test_parse_agent_gateway_path(): + expected = { + "project": "nautilus", + "location": "scallop", + "agent_gateway": "abalone", + } + path = NetworkServicesClient.agent_gateway_path(**expected) + + # Check that the path construction is reversible. + actual = NetworkServicesClient.parse_agent_gateway_path(path) + assert expected == actual + + +def test_authorization_policy_path(): + project = "squid" + location = "clam" + authorization_policy = "whelk" expected = "projects/{project}/locations/{location}/authorizationPolicies/{authorization_policy}".format( project=project, location=location, @@ -51130,9 +55512,9 @@ def test_authorization_policy_path(): def test_parse_authorization_policy_path(): expected = { - "project": "nautilus", - "location": "scallop", - "authorization_policy": "abalone", + "project": "octopus", + "location": "oyster", + "authorization_policy": "nudibranch", } path = NetworkServicesClient.authorization_policy_path(**expected) @@ -51142,9 +55524,9 @@ def test_parse_authorization_policy_path(): def test_backend_service_path(): - project = "squid" - location = "clam" - backend_service = "whelk" + project = "cuttlefish" + location = "mussel" + backend_service = "winkle" expected = "projects/{project}/locations/{location}/backendServices/{backend_service}".format( project=project, location=location, @@ -51158,9 +55540,9 @@ def test_backend_service_path(): def test_parse_backend_service_path(): expected = { - "project": "octopus", - "location": "oyster", - "backend_service": "nudibranch", + "project": "nautilus", + "location": "scallop", + "backend_service": "abalone", } path = NetworkServicesClient.backend_service_path(**expected) @@ -51170,9 +55552,9 @@ def test_parse_backend_service_path(): def test_certificate_path(): - project = "cuttlefish" - location = "mussel" - certificate = "winkle" + project = "squid" + location = "clam" + certificate = "whelk" expected = ( "projects/{project}/locations/{location}/certificates/{certificate}".format( project=project, @@ -51186,9 +55568,9 @@ def test_certificate_path(): def test_parse_certificate_path(): expected = { - "project": "nautilus", - "location": "scallop", - "certificate": "abalone", + "project": "octopus", + "location": "oyster", + "certificate": "nudibranch", } path = NetworkServicesClient.certificate_path(**expected) @@ -51198,9 +55580,9 @@ def test_parse_certificate_path(): def test_client_tls_policy_path(): - project = "squid" - location = "clam" - client_tls_policy = "whelk" + project = "cuttlefish" + location = "mussel" + client_tls_policy = "winkle" expected = "projects/{project}/locations/{location}/clientTlsPolicies/{client_tls_policy}".format( project=project, location=location, @@ -51214,9 +55596,9 @@ def test_client_tls_policy_path(): def test_parse_client_tls_policy_path(): expected = { - "project": "octopus", - "location": "oyster", - "client_tls_policy": "nudibranch", + "project": "nautilus", + "location": "scallop", + "client_tls_policy": "abalone", } path = NetworkServicesClient.client_tls_policy_path(**expected) @@ -51226,9 +55608,9 @@ def test_parse_client_tls_policy_path(): def test_endpoint_policy_path(): - project = "cuttlefish" - location = "mussel" - endpoint_policy = "winkle" + project = "squid" + location = "clam" + endpoint_policy = "whelk" expected = "projects/{project}/locations/{location}/endpointPolicies/{endpoint_policy}".format( project=project, location=location, @@ -51242,9 +55624,9 @@ def test_endpoint_policy_path(): def test_parse_endpoint_policy_path(): expected = { - "project": "nautilus", - "location": "scallop", - "endpoint_policy": "abalone", + "project": "octopus", + "location": "oyster", + "endpoint_policy": "nudibranch", } path = NetworkServicesClient.endpoint_policy_path(**expected) @@ -51254,9 +55636,9 @@ def test_parse_endpoint_policy_path(): def test_gateway_path(): - project = "squid" - location = "clam" - gateway = "whelk" + project = "cuttlefish" + location = "mussel" + gateway = "winkle" expected = "projects/{project}/locations/{location}/gateways/{gateway}".format( project=project, location=location, @@ -51268,9 +55650,9 @@ def test_gateway_path(): def test_parse_gateway_path(): expected = { - "project": "octopus", - "location": "oyster", - "gateway": "nudibranch", + "project": "nautilus", + "location": "scallop", + "gateway": "abalone", } path = NetworkServicesClient.gateway_path(**expected) @@ -51280,10 +55662,10 @@ def test_parse_gateway_path(): def test_gateway_route_view_path(): - project = "cuttlefish" - location = "mussel" - gateway = "winkle" - route_view = "nautilus" + project = "squid" + location = "clam" + gateway = "whelk" + route_view = "octopus" expected = "projects/{project}/locations/{location}/gateways/{gateway}/routeViews/{route_view}".format( project=project, location=location, @@ -51298,10 +55680,10 @@ def test_gateway_route_view_path(): def test_parse_gateway_route_view_path(): expected = { - "project": "scallop", - "location": "abalone", - "gateway": "squid", - "route_view": "clam", + "project": "oyster", + "location": "nudibranch", + "gateway": "cuttlefish", + "route_view": "mussel", } path = NetworkServicesClient.gateway_route_view_path(**expected) @@ -51311,9 +55693,9 @@ def test_parse_gateway_route_view_path(): def test_gateway_security_policy_path(): - project = "whelk" - location = "octopus" - gateway_security_policy = "oyster" + project = "winkle" + location = "nautilus" + gateway_security_policy = "scallop" expected = "projects/{project}/locations/{location}/gatewaySecurityPolicies/{gateway_security_policy}".format( project=project, location=location, @@ -51327,9 +55709,9 @@ def test_gateway_security_policy_path(): def test_parse_gateway_security_policy_path(): expected = { - "project": "nudibranch", - "location": "cuttlefish", - "gateway_security_policy": "mussel", + "project": "abalone", + "location": "squid", + "gateway_security_policy": "clam", } path = NetworkServicesClient.gateway_security_policy_path(**expected) @@ -51339,9 +55721,9 @@ def test_parse_gateway_security_policy_path(): def test_grpc_route_path(): - project = "winkle" - location = "nautilus" - grpc_route = "scallop" + project = "whelk" + location = "octopus" + grpc_route = "oyster" expected = "projects/{project}/locations/{location}/grpcRoutes/{grpc_route}".format( project=project, location=location, @@ -51353,9 +55735,9 @@ def test_grpc_route_path(): def test_parse_grpc_route_path(): expected = { - "project": "abalone", - "location": "squid", - "grpc_route": "clam", + "project": "nudibranch", + "location": "cuttlefish", + "grpc_route": "mussel", } path = NetworkServicesClient.grpc_route_path(**expected) @@ -51365,9 +55747,9 @@ def test_parse_grpc_route_path(): def test_http_route_path(): - project = "whelk" - location = "octopus" - http_route = "oyster" + project = "winkle" + location = "nautilus" + http_route = "scallop" expected = "projects/{project}/locations/{location}/httpRoutes/{http_route}".format( project=project, location=location, @@ -51379,9 +55761,9 @@ def test_http_route_path(): def test_parse_http_route_path(): expected = { - "project": "nudibranch", - "location": "cuttlefish", - "http_route": "mussel", + "project": "abalone", + "location": "squid", + "http_route": "clam", } path = NetworkServicesClient.http_route_path(**expected) @@ -51391,9 +55773,9 @@ def test_parse_http_route_path(): def test_mesh_path(): - project = "winkle" - location = "nautilus" - mesh = "scallop" + project = "whelk" + location = "octopus" + mesh = "oyster" expected = "projects/{project}/locations/{location}/meshes/{mesh}".format( project=project, location=location, @@ -51405,9 +55787,9 @@ def test_mesh_path(): def test_parse_mesh_path(): expected = { - "project": "abalone", - "location": "squid", - "mesh": "clam", + "project": "nudibranch", + "location": "cuttlefish", + "mesh": "mussel", } path = NetworkServicesClient.mesh_path(**expected) @@ -51417,10 +55799,10 @@ def test_parse_mesh_path(): def test_mesh_route_view_path(): - project = "whelk" - location = "octopus" - mesh = "oyster" - route_view = "nudibranch" + project = "winkle" + location = "nautilus" + mesh = "scallop" + route_view = "abalone" expected = "projects/{project}/locations/{location}/meshes/{mesh}/routeViews/{route_view}".format( project=project, location=location, @@ -51435,10 +55817,10 @@ def test_mesh_route_view_path(): def test_parse_mesh_route_view_path(): expected = { - "project": "cuttlefish", - "location": "mussel", - "mesh": "winkle", - "route_view": "nautilus", + "project": "squid", + "location": "clam", + "mesh": "whelk", + "route_view": "octopus", } path = NetworkServicesClient.mesh_route_view_path(**expected) @@ -51448,8 +55830,8 @@ def test_parse_mesh_route_view_path(): def test_network_path(): - project = "scallop" - network = "abalone" + project = "oyster" + network = "nudibranch" expected = "projects/{project}/global/networks/{network}".format( project=project, network=network, @@ -51460,8 +55842,8 @@ def test_network_path(): def test_parse_network_path(): expected = { - "project": "squid", - "network": "clam", + "project": "cuttlefish", + "network": "mussel", } path = NetworkServicesClient.network_path(**expected) @@ -51471,9 +55853,9 @@ def test_parse_network_path(): def test_server_tls_policy_path(): - project = "whelk" - location = "octopus" - server_tls_policy = "oyster" + project = "winkle" + location = "nautilus" + server_tls_policy = "scallop" expected = "projects/{project}/locations/{location}/serverTlsPolicies/{server_tls_policy}".format( project=project, location=location, @@ -51487,9 +55869,9 @@ def test_server_tls_policy_path(): def test_parse_server_tls_policy_path(): expected = { - "project": "nudibranch", - "location": "cuttlefish", - "server_tls_policy": "mussel", + "project": "abalone", + "location": "squid", + "server_tls_policy": "clam", } path = NetworkServicesClient.server_tls_policy_path(**expected) @@ -51499,10 +55881,10 @@ def test_parse_server_tls_policy_path(): def test_service_path(): - project = "winkle" - location = "nautilus" - namespace = "scallop" - service = "abalone" + project = "whelk" + location = "octopus" + namespace = "oyster" + service = "nudibranch" expected = "projects/{project}/locations/{location}/namespaces/{namespace}/services/{service}".format( project=project, location=location, @@ -51515,10 +55897,10 @@ def test_service_path(): def test_parse_service_path(): expected = { - "project": "squid", - "location": "clam", - "namespace": "whelk", - "service": "octopus", + "project": "cuttlefish", + "location": "mussel", + "namespace": "winkle", + "service": "nautilus", } path = NetworkServicesClient.service_path(**expected) @@ -51528,9 +55910,9 @@ def test_parse_service_path(): def test_service_binding_path(): - project = "oyster" - location = "nudibranch" - service_binding = "cuttlefish" + project = "scallop" + location = "abalone" + service_binding = "squid" expected = "projects/{project}/locations/{location}/serviceBindings/{service_binding}".format( project=project, location=location, @@ -51544,9 +55926,9 @@ def test_service_binding_path(): def test_parse_service_binding_path(): expected = { - "project": "mussel", - "location": "winkle", - "service_binding": "nautilus", + "project": "clam", + "location": "whelk", + "service_binding": "octopus", } path = NetworkServicesClient.service_binding_path(**expected) @@ -51556,9 +55938,9 @@ def test_parse_service_binding_path(): def test_service_lb_policy_path(): - project = "scallop" - location = "abalone" - service_lb_policy = "squid" + project = "oyster" + location = "nudibranch" + service_lb_policy = "cuttlefish" expected = "projects/{project}/locations/{location}/serviceLbPolicies/{service_lb_policy}".format( project=project, location=location, @@ -51572,9 +55954,9 @@ def test_service_lb_policy_path(): def test_parse_service_lb_policy_path(): expected = { - "project": "clam", - "location": "whelk", - "service_lb_policy": "octopus", + "project": "mussel", + "location": "winkle", + "service_lb_policy": "nautilus", } path = NetworkServicesClient.service_lb_policy_path(**expected) @@ -51584,9 +55966,9 @@ def test_parse_service_lb_policy_path(): def test_subnetwork_path(): - project = "oyster" - region = "nudibranch" - subnetwork = "cuttlefish" + project = "scallop" + region = "abalone" + subnetwork = "squid" expected = "projects/{project}/regions/{region}/subnetworks/{subnetwork}".format( project=project, region=region, @@ -51598,9 +55980,9 @@ def test_subnetwork_path(): def test_parse_subnetwork_path(): expected = { - "project": "mussel", - "region": "winkle", - "subnetwork": "nautilus", + "project": "clam", + "region": "whelk", + "subnetwork": "octopus", } path = NetworkServicesClient.subnetwork_path(**expected) @@ -51609,6 +55991,34 @@ def test_parse_subnetwork_path(): assert expected == actual +def test_target_tcp_proxy_path(): + project = "oyster" + location = "nudibranch" + target_tcp_proxy = "cuttlefish" + expected = "projects/{project}/locations/{location}/targetTcpProxies/{target_tcp_proxy}".format( + project=project, + location=location, + target_tcp_proxy=target_tcp_proxy, + ) + actual = NetworkServicesClient.target_tcp_proxy_path( + project, location, target_tcp_proxy + ) + assert expected == actual + + +def test_parse_target_tcp_proxy_path(): + expected = { + "project": "mussel", + "location": "winkle", + "target_tcp_proxy": "nautilus", + } + path = NetworkServicesClient.target_tcp_proxy_path(**expected) + + # Check that the path construction is reversible. + actual = NetworkServicesClient.parse_target_tcp_proxy_path(path) + assert expected == actual + + def test_tcp_route_path(): project = "scallop" location = "abalone" From 654701257c6ed4c329729d32965faba4a79627e1 Mon Sep 17 00:00:00 2001 From: sofisl <55454395+sofisl@users.noreply.github.com> Date: Thu, 11 Jun 2026 13:40:54 -0700 Subject: [PATCH 061/174] chore: librarian release pull request: 20260611T192009Z (#17432) PR created by the Librarian CLI to initialize a release. Merging this PR will auto trigger a release. Librarian Version: v0.19.0 Language Image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:234b9d1f2ddb057ed7ac6a38db0bf8163d839c65c6cf88ade52530cddebce59e
gapic-generator: v1.35.0 ## [v1.35.0](https://github.com/googleapis/google-cloud-python/compare/gapic-generator-v1.34.1...gapic-generator-v1.35.0) (2026-06-11) ### Features * setup.py matches prerelease versions (#17370) ([25b857e1](https://github.com/googleapis/google-cloud-python/commit/25b857e1)) ### Bug Fixes * require protobuf 6.33.5 to address CVE-2026-0994 (#17349) ([66422636](https://github.com/googleapis/google-cloud-python/commit/66422636))
google-auth: v2.54.0 ## [v2.54.0](https://github.com/googleapis/google-cloud-python/compare/google-auth-v2.53.0...google-auth-v2.54.0) (2026-06-11) ### Features * implement regional access boundary support for standalone JWT and async service accounts (#17025) ([35af6168](https://github.com/googleapis/google-cloud-python/commit/35af6168)) ### Bug Fixes * configure mTLS for impersonated credentials (#17404) ([57269d56](https://github.com/googleapis/google-cloud-python/commit/57269d56)) * fail-fast on missing ECP config file to avoid 30s hang (#17377) ([e0961270](https://github.com/googleapis/google-cloud-python/commit/e0961270)) * Rename the 'seed' argument for setting an initial regional access boundary for clarity (#17186) ([e5c8cf92](https://github.com/googleapis/google-cloud-python/commit/e5c8cf92)) * update incorrect urls in setup.py to point at monorepo vs splitrepo (#17237) ([eaed04ba](https://github.com/googleapis/google-cloud-python/commit/eaed04ba))
google-cloud-alloydb: v0.11.0 ## [v0.11.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-alloydb-v0.10.0...google-cloud-alloydb-v0.11.0) (2026-06-11) ### Features * update API sources and regenerate (#17413) ([59fe7cf8](https://github.com/googleapis/google-cloud-python/commit/59fe7cf8))
google-cloud-biglake: v0.5.0 ## [v0.5.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-biglake-v0.4.0...google-cloud-biglake-v0.5.0) (2026-06-11) ### Features * update API sources and regenerate (#17431) ([2e75c78c](https://github.com/googleapis/google-cloud-python/commit/2e75c78c))
google-cloud-ces: v0.7.0 ## [v0.7.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-ces-v0.6.0...google-cloud-ces-v0.7.0) (2026-06-11) ### Features * update API sources and regenerate (#17413) ([59fe7cf8](https://github.com/googleapis/google-cloud-python/commit/59fe7cf8))
google-cloud-confidentialcomputing: v0.11.0 ## [v0.11.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-confidentialcomputing-v0.10.0...google-cloud-confidentialcomputing-v0.11.0) (2026-06-11) ### Features * update API sources and regenerate (#17413) ([59fe7cf8](https://github.com/googleapis/google-cloud-python/commit/59fe7cf8))
google-cloud-modelarmor: v0.7.0 ## [v0.7.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-modelarmor-v0.6.0...google-cloud-modelarmor-v0.7.0) (2026-06-11) ### Features * update API sources and regenerate (#17413) ([59fe7cf8](https://github.com/googleapis/google-cloud-python/commit/59fe7cf8))
google-cloud-network-services: v0.10.0 ## [v0.10.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-network-services-v0.9.0...google-cloud-network-services-v0.10.0) (2026-06-11) ### Features * update API sources and regenerate (#17431) ([2e75c78c](https://github.com/googleapis/google-cloud-python/commit/2e75c78c))
google-cloud-oracledatabase: v0.6.0 ## [v0.6.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-oracledatabase-v0.5.0...google-cloud-oracledatabase-v0.6.0) (2026-06-11) ### Features * update API sources and regenerate (#17413) ([59fe7cf8](https://github.com/googleapis/google-cloud-python/commit/59fe7cf8))
google-cloud-spanner: v3.68.0 ## [v3.68.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-spanner-v3.67.0...google-cloud-spanner-v3.68.0) (2026-06-11) ### Features * add asynchronous code snippets and minor cleanup changes (#17337) ([d6aaf610](https://github.com/googleapis/google-cloud-python/commit/d6aaf610)) ### Performance Improvements * optimize query result decoding (#17375) ([3f70b2ff](https://github.com/googleapis/google-cloud-python/commit/3f70b2ff))
google-cloud-storage: v3.12.0 ## [v3.12.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-storage-v3.11.0...google-cloud-storage-v3.12.0) (2026-06-11) ### Features * full object checksum: implement rolling checksum and verification in reads resumption strategy (#17262) ([2361ba6e](https://github.com/googleapis/google-cloud-python/commit/2361ba6e)) * Enable full object checksum PR 1/3 : parse finalize_time and server crc32c in async object stream (#17261) ([72c7a272](https://github.com/googleapis/google-cloud-python/commit/72c7a272)) * full object checksum: integrate full-object checksum in AsyncMultiRangeDownloader (#17263) ([b6a85e49](https://github.com/googleapis/google-cloud-python/commit/b6a85e49))
google-developer-knowledge: v0.1.0 ## [v0.1.0](https://github.com/googleapis/google-cloud-python/compare/google-developer-knowledge-v0.0.0...google-developer-knowledge-v0.1.0) (2026-06-11) ### Features * add google-developer-knowledge (#17417) ([ca02afce](https://github.com/googleapis/google-cloud-python/commit/ca02afce))
--- .librarian/state.yaml | 24 +++++++++---------- CHANGELOG.md | 10 ++++---- librarian.yaml | 24 +++++++++---------- packages/gapic-generator/CHANGELOG.md | 12 ++++++++++ packages/gapic-generator/setup.py | 2 +- packages/google-auth/CHANGELOG.md | 15 ++++++++++++ packages/google-auth/google/auth/version.py | 2 +- packages/google-cloud-alloydb/CHANGELOG.md | 7 ++++++ .../google/cloud/alloydb/gapic_version.py | 2 +- .../google/cloud/alloydb_v1/gapic_version.py | 2 +- .../cloud/alloydb_v1alpha/gapic_version.py | 2 +- .../cloud/alloydb_v1beta/gapic_version.py | 2 +- ...ppet_metadata_google.cloud.alloydb.v1.json | 2 +- ...metadata_google.cloud.alloydb.v1alpha.json | 2 +- ..._metadata_google.cloud.alloydb.v1beta.json | 2 +- packages/google-cloud-biglake/CHANGELOG.md | 7 ++++++ .../google/cloud/biglake/gapic_version.py | 2 +- .../google/cloud/biglake_v1/gapic_version.py | 2 +- ...ppet_metadata_google.cloud.biglake.v1.json | 2 +- packages/google-cloud-ces/CHANGELOG.md | 7 ++++++ packages/google-cloud-ces/docs/CHANGELOG.md | 7 ++++++ .../google/cloud/ces/gapic_version.py | 2 +- .../google/cloud/ces_v1/gapic_version.py | 2 +- .../google/cloud/ces_v1beta/gapic_version.py | 2 +- .../snippet_metadata_google.cloud.ces.v1.json | 2 +- ...ppet_metadata_google.cloud.ces.v1beta.json | 2 +- .../CHANGELOG.md | 7 ++++++ .../confidentialcomputing/gapic_version.py | 2 +- .../confidentialcomputing_v1/gapic_version.py | 2 +- ...google.cloud.confidentialcomputing.v1.json | 2 +- packages/google-cloud-modelarmor/CHANGELOG.md | 7 ++++++ .../google/cloud/modelarmor/gapic_version.py | 2 +- .../cloud/modelarmor_v1/gapic_version.py | 2 +- .../cloud/modelarmor_v1beta/gapic_version.py | 2 +- ...t_metadata_google.cloud.modelarmor.v1.json | 2 +- ...tadata_google.cloud.modelarmor.v1beta.json | 2 +- .../CHANGELOG.md | 7 ++++++ .../cloud/network_services/gapic_version.py | 2 +- .../network_services_v1/gapic_version.py | 2 +- ...adata_google.cloud.networkservices.v1.json | 2 +- .../google-cloud-oracledatabase/CHANGELOG.md | 7 ++++++ .../cloud/oracledatabase/gapic_version.py | 2 +- .../cloud/oracledatabase_v1/gapic_version.py | 2 +- ...tadata_google.cloud.oracledatabase.v1.json | 2 +- packages/google-cloud-spanner/CHANGELOG.md | 7 ++++++ .../google/cloud/spanner/gapic_version.py | 2 +- .../spanner_admin_database/gapic_version.py | 2 +- .../gapic_version.py | 2 +- .../spanner_admin_instance/gapic_version.py | 2 +- .../gapic_version.py | 2 +- .../google/cloud/spanner_dbapi/version.py | 2 +- .../google/cloud/spanner_v1/gapic_version.py | 2 +- ...data_google.spanner.admin.database.v1.json | 2 +- ...data_google.spanner.admin.instance.v1.json | 2 +- .../snippet_metadata_google.spanner.v1.json | 2 +- packages/google-cloud-storage/CHANGELOG.md | 9 +++++++ .../google/cloud/_storage/gapic_version.py | 2 +- .../google/cloud/_storage_v2/gapic_version.py | 2 +- .../google/cloud/storage/version.py | 2 +- .../snippet_metadata_google.storage.v2.json | 2 +- .../google-developer-knowledge/CHANGELOG.md | 7 ++++++ .../developer_knowledge/gapic_version.py | 2 +- .../developer_knowledge_v1/gapic_version.py | 2 +- ...tadata_google.developers.knowledge.v1.json | 2 +- 64 files changed, 183 insertions(+), 77 deletions(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index d69a10f8d167..3255f442c54d 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -74,7 +74,7 @@ libraries: - packages/django-google-spanner/docs/ tag_format: '{id}-v{version}' - id: gapic-generator - version: 1.34.1 + version: 1.35.0 last_generated_commit: "" apis: [] source_roots: @@ -387,7 +387,7 @@ libraries: - packages/google-area120-tables/docs/ tag_format: '{id}-v{version}' - id: google-auth - version: 2.53.0 + version: 2.54.0 last_generated_commit: "" apis: [] source_roots: @@ -531,7 +531,7 @@ libraries: - packages/google-cloud-agentidentitycredentials/docs/ tag_format: '{id}-v{version}' - id: google-cloud-alloydb - version: 0.10.0 + version: 0.11.0 last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c apis: - path: google/cloud/alloydb/v1beta @@ -1095,7 +1095,7 @@ libraries: - packages/google-cloud-beyondcorp-clientgateways/docs/ tag_format: '{id}-v{version}' - id: google-cloud-biglake - version: 0.4.0 + version: 0.5.0 last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c apis: - path: google/cloud/biglake/v1 @@ -1577,7 +1577,7 @@ libraries: - packages/google-cloud-certificate-manager/docs/ tag_format: '{id}-v{version}' - id: google-cloud-ces - version: 0.6.0 + version: 0.7.0 last_generated_commit: 582172de2d9b6443e1fecf696167867c6d8a5fc4 apis: - path: google/cloud/ces/v1 @@ -1769,7 +1769,7 @@ libraries: - packages/google-cloud-compute-v1beta/docs/ tag_format: '{id}-v{version}' - id: google-cloud-confidentialcomputing - version: 0.10.0 + version: 0.11.0 last_generated_commit: 9eea40c74d97622bb0aa406dd313409a376cc73b apis: - path: google/cloud/confidentialcomputing/v1 @@ -3493,7 +3493,7 @@ libraries: - packages/google-cloud-migrationcenter/docs/ tag_format: '{id}-v{version}' - id: google-cloud-modelarmor - version: 0.6.0 + version: 0.7.0 last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c apis: - path: google/cloud/modelarmor/v1beta @@ -3686,7 +3686,7 @@ libraries: - packages/google-cloud-network-security/docs/ tag_format: '{id}-v{version}' - id: google-cloud-network-services - version: 0.9.0 + version: 0.10.0 last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c apis: - path: google/cloud/networkservices/v1 @@ -3750,7 +3750,7 @@ libraries: - packages/google-cloud-optimization/docs/ tag_format: '{id}-v{version}' - id: google-cloud-oracledatabase - version: 0.5.0 + version: 0.6.0 last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c apis: - path: google/cloud/oracledatabase/v1 @@ -4616,7 +4616,7 @@ libraries: - packages/google-cloud-source-context/docs/ tag_format: '{id}-v{version}' - id: google-cloud-spanner - version: 3.67.0 + version: 3.68.0 last_generated_commit: 3e09ac03bab9dba5b8800248cf10190219938a26 apis: - path: google/spanner/admin/instance/v1 @@ -4734,7 +4734,7 @@ libraries: - packages/google-cloud-speech/docs/ tag_format: '{id}-v{version}' - id: google-cloud-storage - version: 3.11.0 + version: 3.12.0 last_generated_commit: 2233f63baf69c2a481f30180045fcf036242781d apis: - path: google/storage/v2 @@ -5421,7 +5421,7 @@ libraries: - packages/google-crc32c/docs/ tag_format: '{id}-v{version}' - id: google-developer-knowledge - version: 0.0.0 + version: 0.1.0 last_generated_commit: "" apis: - path: google/developers/knowledge/v1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 18e672b864d4..977d55b247b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,7 +17,7 @@ Changelogs - [google-cloud-access-context-manager==0.6.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-access-context-manager/CHANGELOG.md) - [google-cloud-advisorynotifications==0.7.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-advisorynotifications/CHANGELOG.md) - [google-cloud-alloydb-connectors==0.5.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-alloydb-connectors/CHANGELOG.md) -- [google-cloud-alloydb==0.10.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-alloydb/CHANGELOG.md) +- [google-cloud-alloydb==0.11.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-alloydb/CHANGELOG.md) - [google-cloud-api-gateway==1.16.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-api-gateway/CHANGELOG.md) - [google-cloud-api-keys==0.9.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-api-keys/CHANGELOG.md) - [google-cloud-apigee-connect==1.16.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-apigee-connect/CHANGELOG.md) @@ -60,7 +60,7 @@ Changelogs - [google-cloud-common==1.10.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-common/CHANGELOG.md) - [google-cloud-compute-v1beta==0.12.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-compute-v1beta/CHANGELOG.md) - [google-cloud-compute==1.48.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-compute/CHANGELOG.md) -- [google-cloud-confidentialcomputing==0.10.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-confidentialcomputing/CHANGELOG.md) +- [google-cloud-confidentialcomputing==0.11.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-confidentialcomputing/CHANGELOG.md) - [google-cloud-config==0.7.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-config/CHANGELOG.md) - [google-cloud-configdelivery==0.5.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-configdelivery/CHANGELOG.md) - [google-cloud-contact-center-insights==1.27.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-contact-center-insights/CHANGELOG.md) @@ -122,7 +122,7 @@ Changelogs - [google-cloud-memcache==1.15.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-memcache/CHANGELOG.md) - [google-cloud-memorystore==0.5.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-memorystore/CHANGELOG.md) - [google-cloud-migrationcenter==0.4.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-migrationcenter/CHANGELOG.md) -- [google-cloud-modelarmor==0.6.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-modelarmor/CHANGELOG.md) +- [google-cloud-modelarmor==0.7.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-modelarmor/CHANGELOG.md) - [google-cloud-monitoring-dashboards==2.21.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-monitoring-dashboards/CHANGELOG.md) - [google-cloud-monitoring-metrics-scopes==1.12.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-monitoring-metrics-scopes/CHANGELOG.md) - [google-cloud-monitoring==2.31.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-monitoring/CHANGELOG.md) @@ -130,10 +130,10 @@ Changelogs - [google-cloud-network-connectivity==2.15.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-network-connectivity/CHANGELOG.md) - [google-cloud-network-management==1.35.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-network-management/CHANGELOG.md) - [google-cloud-network-security==0.13.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-network-security/CHANGELOG.md) -- [google-cloud-network-services==0.9.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-network-services/CHANGELOG.md) +- [google-cloud-network-services==0.10.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-network-services/CHANGELOG.md) - [google-cloud-notebooks==1.16.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-notebooks/CHANGELOG.md) - [google-cloud-optimization==1.14.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-optimization/CHANGELOG.md) -- [google-cloud-oracledatabase==0.5.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-oracledatabase/CHANGELOG.md) +- [google-cloud-oracledatabase==0.6.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-oracledatabase/CHANGELOG.md) - [google-cloud-orchestration-airflow==1.21.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-orchestration-airflow/CHANGELOG.md) - [google-cloud-org-policy==1.17.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-org-policy/CHANGELOG.md) - [google-cloud-os-config==1.24.0](https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-os-config/CHANGELOG.md) diff --git a/librarian.yaml b/librarian.yaml index 8a14680e872a..a9a31501696a 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -75,7 +75,7 @@ libraries: python: library_type: INTEGRATION - name: gapic-generator - version: 1.34.1 + version: 1.35.0 python: library_type: CORE - name: gcp-sphinx-docfx-yaml @@ -228,7 +228,7 @@ libraries: metadata_name_override: area120tables default_version: v1alpha1 - name: google-auth - version: 2.53.0 + version: 2.54.0 python: library_type: AUTH - name: google-auth-httplib2 @@ -287,7 +287,7 @@ libraries: python: default_version: v1 - name: google-cloud-alloydb - version: 0.10.0 + version: 0.11.0 apis: - path: google/cloud/alloydb/v1 - path: google/cloud/alloydb/v1beta @@ -526,7 +526,7 @@ libraries: metadata_name_override: beyondcorpclientgateways default_version: v1 - name: google-cloud-biglake - version: 0.4.0 + version: 0.5.0 apis: - path: google/cloud/biglake/v1 python: @@ -710,7 +710,7 @@ libraries: metadata_name_override: certificatemanager default_version: v1 - name: google-cloud-ces - version: 0.6.0 + version: 0.7.0 apis: - path: google/cloud/ces/v1 - path: google/cloud/ces/v1beta @@ -774,7 +774,7 @@ libraries: python: default_version: v1beta - name: google-cloud-confidentialcomputing - version: 0.10.0 + version: 0.11.0 apis: - path: google/cloud/confidentialcomputing/v1 python: @@ -1447,7 +1447,7 @@ libraries: metadata_name_override: migrationcenter default_version: v1 - name: google-cloud-modelarmor - version: 0.6.0 + version: 0.7.0 apis: - path: google/cloud/modelarmor/v1 - path: google/cloud/modelarmor/v1beta @@ -1537,7 +1537,7 @@ libraries: metadata_name_override: networksecurity default_version: v1 - name: google-cloud-network-services - version: 0.9.0 + version: 0.10.0 apis: - path: google/cloud/networkservices/v1 python: @@ -1563,7 +1563,7 @@ libraries: metadata_name_override: optimization default_version: v1 - name: google-cloud-oracledatabase - version: 0.5.0 + version: 0.6.0 apis: - path: google/cloud/oracledatabase/v1 python: @@ -1918,7 +1918,7 @@ libraries: metadata_name_override: source default_version: v1 - name: google-cloud-spanner - version: 3.67.0 + version: 3.68.0 apis: - path: google/spanner/v1 - path: google/spanner/admin/instance/v1 @@ -1960,7 +1960,7 @@ libraries: metadata_name_override: speech default_version: v1 - name: google-cloud-storage - version: 3.11.0 + version: 3.12.0 apis: - path: google/storage/v2 python: @@ -2228,7 +2228,7 @@ libraries: python: library_type: OTHER - name: google-developer-knowledge - version: 0.0.0 + version: 0.1.0 apis: - path: google/developers/knowledge/v1 copyright_year: "2026" diff --git a/packages/gapic-generator/CHANGELOG.md b/packages/gapic-generator/CHANGELOG.md index 1566c7ee5297..09dfc588094a 100644 --- a/packages/gapic-generator/CHANGELOG.md +++ b/packages/gapic-generator/CHANGELOG.md @@ -4,6 +4,18 @@ [1]: https://pypi.org/project/gapic-generator/#history +## [1.35.0](https://github.com/googleapis/google-cloud-python/compare/gapic-generator-v1.34.1...gapic-generator-v1.35.0) (2026-06-11) + + +### Features + +* setup.py matches prerelease versions (#17370) ([25b857e1bc196da5b56cf599ec346967c6559922](https://github.com/googleapis/google-cloud-python/commit/25b857e1bc196da5b56cf599ec346967c6559922)) + + +### Bug Fixes + +* require protobuf 6.33.5 to address CVE-2026-0994 (#17349) ([66422636633e980324877f2ff3805a284001ad38](https://github.com/googleapis/google-cloud-python/commit/66422636633e980324877f2ff3805a284001ad38)) + ## [1.34.1](https://github.com/googleapis/google-cloud-python/compare/gapic-generator-v1.34.0...gapic-generator-v1.34.1) (2026-05-27) ## [1.34.0](https://github.com/googleapis/google-cloud-python/compare/gapic-generator-v1.33.0...gapic-generator-v1.34.0) (2026-05-27) diff --git a/packages/gapic-generator/setup.py b/packages/gapic-generator/setup.py index a1646a992684..237281229446 100644 --- a/packages/gapic-generator/setup.py +++ b/packages/gapic-generator/setup.py @@ -22,7 +22,7 @@ name = "gapic-generator" description = "Google API Client Generator for Python" url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/gapic-generator" -version = "1.34.1" +version = "1.35.0" release_status = "Development Status :: 5 - Production/Stable" dependencies = [ # Ensure that the lower bounds of these dependencies match what we have in the diff --git a/packages/google-auth/CHANGELOG.md b/packages/google-auth/CHANGELOG.md index afe30067c3e8..034b15b2c197 100644 --- a/packages/google-auth/CHANGELOG.md +++ b/packages/google-auth/CHANGELOG.md @@ -4,6 +4,21 @@ [1]: https://pypi.org/project/google-auth/#history +## [2.54.0](https://github.com/googleapis/google-cloud-python/compare/google-auth-v2.53.0...google-auth-v2.54.0) (2026-06-11) + + +### Features + +* implement regional access boundary support for standalone JWT and async service accounts (#17025) ([35af6168c19dd6f114dd67a8bfdcd0ff8fe3bdf9](https://github.com/googleapis/google-cloud-python/commit/35af6168c19dd6f114dd67a8bfdcd0ff8fe3bdf9)) + + +### Bug Fixes + +* configure mTLS for impersonated credentials (#17404) ([57269d567227655e16a2c518e29129c31ebe65be](https://github.com/googleapis/google-cloud-python/commit/57269d567227655e16a2c518e29129c31ebe65be)) +* fail-fast on missing ECP config file to avoid 30s hang (#17377) ([e0961270013ceea2c191ec2c6d445c5c5f928ddf](https://github.com/googleapis/google-cloud-python/commit/e0961270013ceea2c191ec2c6d445c5c5f928ddf)) +* update incorrect urls in setup.py to point at monorepo vs splitrepo (#17237) ([eaed04baf3cd356c3811c66e64c277c8841c7563](https://github.com/googleapis/google-cloud-python/commit/eaed04baf3cd356c3811c66e64c277c8841c7563)) +* Rename the 'seed' argument for setting an initial regional access boundary for clarity (#17186) ([e5c8cf92f4e78fe05c8d899e00fb36f29f31d7c4](https://github.com/googleapis/google-cloud-python/commit/e5c8cf92f4e78fe05c8d899e00fb36f29f31d7c4)) + ## [2.53.0](https://github.com/googleapis/google-cloud-python/compare/google-auth-v2.52.0...google-auth-v2.53.0) (2026-05-15) diff --git a/packages/google-auth/google/auth/version.py b/packages/google-auth/google/auth/version.py index 4c624ee15b19..533fd28ff6c1 100644 --- a/packages/google-auth/google/auth/version.py +++ b/packages/google-auth/google/auth/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "2.53.0" +__version__ = "2.54.0" diff --git a/packages/google-cloud-alloydb/CHANGELOG.md b/packages/google-cloud-alloydb/CHANGELOG.md index daeb980cc810..e7508af495b6 100644 --- a/packages/google-cloud-alloydb/CHANGELOG.md +++ b/packages/google-cloud-alloydb/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-alloydb/#history +## [0.11.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-alloydb-v0.10.0...google-cloud-alloydb-v0.11.0) (2026-06-11) + + +### Features + +* update API sources and regenerate (#17413) ([59fe7cf83c123102baf5439af4acd6218d7ce01b](https://github.com/googleapis/google-cloud-python/commit/59fe7cf83c123102baf5439af4acd6218d7ce01b)) + ## [0.10.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-alloydb-v0.9.0...google-cloud-alloydb-v0.10.0) (2026-06-02) diff --git a/packages/google-cloud-alloydb/google/cloud/alloydb/gapic_version.py b/packages/google-cloud-alloydb/google/cloud/alloydb/gapic_version.py index 0a5d17e6c82a..09eb9941e1dd 100644 --- a/packages/google-cloud-alloydb/google/cloud/alloydb/gapic_version.py +++ b/packages/google-cloud-alloydb/google/cloud/alloydb/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.10.0" # {x-release-please-version} +__version__ = "0.11.0" # {x-release-please-version} diff --git a/packages/google-cloud-alloydb/google/cloud/alloydb_v1/gapic_version.py b/packages/google-cloud-alloydb/google/cloud/alloydb_v1/gapic_version.py index 0a5d17e6c82a..09eb9941e1dd 100644 --- a/packages/google-cloud-alloydb/google/cloud/alloydb_v1/gapic_version.py +++ b/packages/google-cloud-alloydb/google/cloud/alloydb_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.10.0" # {x-release-please-version} +__version__ = "0.11.0" # {x-release-please-version} diff --git a/packages/google-cloud-alloydb/google/cloud/alloydb_v1alpha/gapic_version.py b/packages/google-cloud-alloydb/google/cloud/alloydb_v1alpha/gapic_version.py index 0a5d17e6c82a..09eb9941e1dd 100644 --- a/packages/google-cloud-alloydb/google/cloud/alloydb_v1alpha/gapic_version.py +++ b/packages/google-cloud-alloydb/google/cloud/alloydb_v1alpha/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.10.0" # {x-release-please-version} +__version__ = "0.11.0" # {x-release-please-version} diff --git a/packages/google-cloud-alloydb/google/cloud/alloydb_v1beta/gapic_version.py b/packages/google-cloud-alloydb/google/cloud/alloydb_v1beta/gapic_version.py index 0a5d17e6c82a..09eb9941e1dd 100644 --- a/packages/google-cloud-alloydb/google/cloud/alloydb_v1beta/gapic_version.py +++ b/packages/google-cloud-alloydb/google/cloud/alloydb_v1beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.10.0" # {x-release-please-version} +__version__ = "0.11.0" # {x-release-please-version} diff --git a/packages/google-cloud-alloydb/samples/generated_samples/snippet_metadata_google.cloud.alloydb.v1.json b/packages/google-cloud-alloydb/samples/generated_samples/snippet_metadata_google.cloud.alloydb.v1.json index ec9f9bd3bdbd..190edfb94dea 100644 --- a/packages/google-cloud-alloydb/samples/generated_samples/snippet_metadata_google.cloud.alloydb.v1.json +++ b/packages/google-cloud-alloydb/samples/generated_samples/snippet_metadata_google.cloud.alloydb.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-alloydb", - "version": "0.10.0" + "version": "0.11.0" }, "snippets": [ { diff --git a/packages/google-cloud-alloydb/samples/generated_samples/snippet_metadata_google.cloud.alloydb.v1alpha.json b/packages/google-cloud-alloydb/samples/generated_samples/snippet_metadata_google.cloud.alloydb.v1alpha.json index 023698f09577..9608f8071f22 100644 --- a/packages/google-cloud-alloydb/samples/generated_samples/snippet_metadata_google.cloud.alloydb.v1alpha.json +++ b/packages/google-cloud-alloydb/samples/generated_samples/snippet_metadata_google.cloud.alloydb.v1alpha.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-alloydb", - "version": "0.10.0" + "version": "0.11.0" }, "snippets": [ { diff --git a/packages/google-cloud-alloydb/samples/generated_samples/snippet_metadata_google.cloud.alloydb.v1beta.json b/packages/google-cloud-alloydb/samples/generated_samples/snippet_metadata_google.cloud.alloydb.v1beta.json index 50f43b8299cc..c6e230408981 100644 --- a/packages/google-cloud-alloydb/samples/generated_samples/snippet_metadata_google.cloud.alloydb.v1beta.json +++ b/packages/google-cloud-alloydb/samples/generated_samples/snippet_metadata_google.cloud.alloydb.v1beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-alloydb", - "version": "0.10.0" + "version": "0.11.0" }, "snippets": [ { diff --git a/packages/google-cloud-biglake/CHANGELOG.md b/packages/google-cloud-biglake/CHANGELOG.md index b7f116cb94ab..699a4bd5e7d8 100644 --- a/packages/google-cloud-biglake/CHANGELOG.md +++ b/packages/google-cloud-biglake/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-biglake/#history +## [0.5.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-biglake-v0.4.0...google-cloud-biglake-v0.5.0) (2026-06-11) + + +### Features + +* update API sources and regenerate (#17431) ([2e75c78cdd09d4472ed412a2e925196effaea9fd](https://github.com/googleapis/google-cloud-python/commit/2e75c78cdd09d4472ed412a2e925196effaea9fd)) + ## [0.4.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-biglake-v0.3.0...google-cloud-biglake-v0.4.0) (2026-06-02) diff --git a/packages/google-cloud-biglake/google/cloud/biglake/gapic_version.py b/packages/google-cloud-biglake/google/cloud/biglake/gapic_version.py index 7a26901aff5b..7d9863d19611 100644 --- a/packages/google-cloud-biglake/google/cloud/biglake/gapic_version.py +++ b/packages/google-cloud-biglake/google/cloud/biglake/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.5.0" # {x-release-please-version} diff --git a/packages/google-cloud-biglake/google/cloud/biglake_v1/gapic_version.py b/packages/google-cloud-biglake/google/cloud/biglake_v1/gapic_version.py index 7a26901aff5b..7d9863d19611 100644 --- a/packages/google-cloud-biglake/google/cloud/biglake_v1/gapic_version.py +++ b/packages/google-cloud-biglake/google/cloud/biglake_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.5.0" # {x-release-please-version} diff --git a/packages/google-cloud-biglake/samples/generated_samples/snippet_metadata_google.cloud.biglake.v1.json b/packages/google-cloud-biglake/samples/generated_samples/snippet_metadata_google.cloud.biglake.v1.json index df3623823115..8847429f91f3 100644 --- a/packages/google-cloud-biglake/samples/generated_samples/snippet_metadata_google.cloud.biglake.v1.json +++ b/packages/google-cloud-biglake/samples/generated_samples/snippet_metadata_google.cloud.biglake.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-biglake", - "version": "0.4.0" + "version": "0.5.0" }, "snippets": [ { diff --git a/packages/google-cloud-ces/CHANGELOG.md b/packages/google-cloud-ces/CHANGELOG.md index 1f23fc975553..56bcfee20e96 100644 --- a/packages/google-cloud-ces/CHANGELOG.md +++ b/packages/google-cloud-ces/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-ces/#history +## [0.7.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-ces-v0.6.0...google-cloud-ces-v0.7.0) (2026-06-11) + + +### Features + +* update API sources and regenerate (#17413) ([59fe7cf83c123102baf5439af4acd6218d7ce01b](https://github.com/googleapis/google-cloud-python/commit/59fe7cf83c123102baf5439af4acd6218d7ce01b)) + ## [0.6.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-ces-v0.5.0...google-cloud-ces-v0.6.0) (2026-06-02) diff --git a/packages/google-cloud-ces/docs/CHANGELOG.md b/packages/google-cloud-ces/docs/CHANGELOG.md index 1f23fc975553..56bcfee20e96 100644 --- a/packages/google-cloud-ces/docs/CHANGELOG.md +++ b/packages/google-cloud-ces/docs/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-ces/#history +## [0.7.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-ces-v0.6.0...google-cloud-ces-v0.7.0) (2026-06-11) + + +### Features + +* update API sources and regenerate (#17413) ([59fe7cf83c123102baf5439af4acd6218d7ce01b](https://github.com/googleapis/google-cloud-python/commit/59fe7cf83c123102baf5439af4acd6218d7ce01b)) + ## [0.6.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-ces-v0.5.0...google-cloud-ces-v0.6.0) (2026-06-02) diff --git a/packages/google-cloud-ces/google/cloud/ces/gapic_version.py b/packages/google-cloud-ces/google/cloud/ces/gapic_version.py index 916d95dd4eda..ad3e775fa49f 100644 --- a/packages/google-cloud-ces/google/cloud/ces/gapic_version.py +++ b/packages/google-cloud-ces/google/cloud/ces/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.6.0" # {x-release-please-version} +__version__ = "0.7.0" # {x-release-please-version} diff --git a/packages/google-cloud-ces/google/cloud/ces_v1/gapic_version.py b/packages/google-cloud-ces/google/cloud/ces_v1/gapic_version.py index 916d95dd4eda..ad3e775fa49f 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1/gapic_version.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.6.0" # {x-release-please-version} +__version__ = "0.7.0" # {x-release-please-version} diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/gapic_version.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/gapic_version.py index 916d95dd4eda..ad3e775fa49f 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/gapic_version.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.6.0" # {x-release-please-version} +__version__ = "0.7.0" # {x-release-please-version} diff --git a/packages/google-cloud-ces/samples/generated_samples/snippet_metadata_google.cloud.ces.v1.json b/packages/google-cloud-ces/samples/generated_samples/snippet_metadata_google.cloud.ces.v1.json index e3ced8e188a9..540e3a8de1fb 100644 --- a/packages/google-cloud-ces/samples/generated_samples/snippet_metadata_google.cloud.ces.v1.json +++ b/packages/google-cloud-ces/samples/generated_samples/snippet_metadata_google.cloud.ces.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-ces", - "version": "0.6.0" + "version": "0.7.0" }, "snippets": [ { diff --git a/packages/google-cloud-ces/samples/generated_samples/snippet_metadata_google.cloud.ces.v1beta.json b/packages/google-cloud-ces/samples/generated_samples/snippet_metadata_google.cloud.ces.v1beta.json index 0d389ae737b9..36c0a8d304cf 100644 --- a/packages/google-cloud-ces/samples/generated_samples/snippet_metadata_google.cloud.ces.v1beta.json +++ b/packages/google-cloud-ces/samples/generated_samples/snippet_metadata_google.cloud.ces.v1beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-ces", - "version": "0.6.0" + "version": "0.7.0" }, "snippets": [ { diff --git a/packages/google-cloud-confidentialcomputing/CHANGELOG.md b/packages/google-cloud-confidentialcomputing/CHANGELOG.md index 375ce1b16082..614fe59c22ad 100644 --- a/packages/google-cloud-confidentialcomputing/CHANGELOG.md +++ b/packages/google-cloud-confidentialcomputing/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-confidentialcomputing/#history +## [0.11.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-confidentialcomputing-v0.10.0...google-cloud-confidentialcomputing-v0.11.0) (2026-06-11) + + +### Features + +* update API sources and regenerate (#17413) ([59fe7cf83c123102baf5439af4acd6218d7ce01b](https://github.com/googleapis/google-cloud-python/commit/59fe7cf83c123102baf5439af4acd6218d7ce01b)) + ## [0.10.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-confidentialcomputing-v0.9.0...google-cloud-confidentialcomputing-v0.10.0) (2026-06-02) diff --git a/packages/google-cloud-confidentialcomputing/google/cloud/confidentialcomputing/gapic_version.py b/packages/google-cloud-confidentialcomputing/google/cloud/confidentialcomputing/gapic_version.py index 0a5d17e6c82a..09eb9941e1dd 100644 --- a/packages/google-cloud-confidentialcomputing/google/cloud/confidentialcomputing/gapic_version.py +++ b/packages/google-cloud-confidentialcomputing/google/cloud/confidentialcomputing/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.10.0" # {x-release-please-version} +__version__ = "0.11.0" # {x-release-please-version} diff --git a/packages/google-cloud-confidentialcomputing/google/cloud/confidentialcomputing_v1/gapic_version.py b/packages/google-cloud-confidentialcomputing/google/cloud/confidentialcomputing_v1/gapic_version.py index 0a5d17e6c82a..09eb9941e1dd 100644 --- a/packages/google-cloud-confidentialcomputing/google/cloud/confidentialcomputing_v1/gapic_version.py +++ b/packages/google-cloud-confidentialcomputing/google/cloud/confidentialcomputing_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.10.0" # {x-release-please-version} +__version__ = "0.11.0" # {x-release-please-version} diff --git a/packages/google-cloud-confidentialcomputing/samples/generated_samples/snippet_metadata_google.cloud.confidentialcomputing.v1.json b/packages/google-cloud-confidentialcomputing/samples/generated_samples/snippet_metadata_google.cloud.confidentialcomputing.v1.json index f80d0fd19ebb..2ad70524f6cd 100644 --- a/packages/google-cloud-confidentialcomputing/samples/generated_samples/snippet_metadata_google.cloud.confidentialcomputing.v1.json +++ b/packages/google-cloud-confidentialcomputing/samples/generated_samples/snippet_metadata_google.cloud.confidentialcomputing.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-confidentialcomputing", - "version": "0.10.0" + "version": "0.11.0" }, "snippets": [ { diff --git a/packages/google-cloud-modelarmor/CHANGELOG.md b/packages/google-cloud-modelarmor/CHANGELOG.md index 70b9b7bedf8b..1559ca7ffb3b 100644 --- a/packages/google-cloud-modelarmor/CHANGELOG.md +++ b/packages/google-cloud-modelarmor/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-modelarmor/#history +## [0.7.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-modelarmor-v0.6.0...google-cloud-modelarmor-v0.7.0) (2026-06-11) + + +### Features + +* update API sources and regenerate (#17413) ([59fe7cf83c123102baf5439af4acd6218d7ce01b](https://github.com/googleapis/google-cloud-python/commit/59fe7cf83c123102baf5439af4acd6218d7ce01b)) + ## [0.6.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-modelarmor-v0.5.0...google-cloud-modelarmor-v0.6.0) (2026-05-06) ## [0.5.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-modelarmor-v0.4.0...google-cloud-modelarmor-v0.5.0) (2026-03-26) diff --git a/packages/google-cloud-modelarmor/google/cloud/modelarmor/gapic_version.py b/packages/google-cloud-modelarmor/google/cloud/modelarmor/gapic_version.py index 916d95dd4eda..ad3e775fa49f 100644 --- a/packages/google-cloud-modelarmor/google/cloud/modelarmor/gapic_version.py +++ b/packages/google-cloud-modelarmor/google/cloud/modelarmor/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.6.0" # {x-release-please-version} +__version__ = "0.7.0" # {x-release-please-version} diff --git a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/gapic_version.py b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/gapic_version.py index 916d95dd4eda..ad3e775fa49f 100644 --- a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/gapic_version.py +++ b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.6.0" # {x-release-please-version} +__version__ = "0.7.0" # {x-release-please-version} diff --git a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1beta/gapic_version.py b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1beta/gapic_version.py index 916d95dd4eda..ad3e775fa49f 100644 --- a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1beta/gapic_version.py +++ b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.6.0" # {x-release-please-version} +__version__ = "0.7.0" # {x-release-please-version} diff --git a/packages/google-cloud-modelarmor/samples/generated_samples/snippet_metadata_google.cloud.modelarmor.v1.json b/packages/google-cloud-modelarmor/samples/generated_samples/snippet_metadata_google.cloud.modelarmor.v1.json index acc1dee1e100..51ecef114754 100644 --- a/packages/google-cloud-modelarmor/samples/generated_samples/snippet_metadata_google.cloud.modelarmor.v1.json +++ b/packages/google-cloud-modelarmor/samples/generated_samples/snippet_metadata_google.cloud.modelarmor.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-modelarmor", - "version": "0.6.0" + "version": "0.7.0" }, "snippets": [ { diff --git a/packages/google-cloud-modelarmor/samples/generated_samples/snippet_metadata_google.cloud.modelarmor.v1beta.json b/packages/google-cloud-modelarmor/samples/generated_samples/snippet_metadata_google.cloud.modelarmor.v1beta.json index c63688ff0c29..be08a69a8a7c 100644 --- a/packages/google-cloud-modelarmor/samples/generated_samples/snippet_metadata_google.cloud.modelarmor.v1beta.json +++ b/packages/google-cloud-modelarmor/samples/generated_samples/snippet_metadata_google.cloud.modelarmor.v1beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-modelarmor", - "version": "0.6.0" + "version": "0.7.0" }, "snippets": [ { diff --git a/packages/google-cloud-network-services/CHANGELOG.md b/packages/google-cloud-network-services/CHANGELOG.md index 7e663a96828f..ae1276a3e656 100644 --- a/packages/google-cloud-network-services/CHANGELOG.md +++ b/packages/google-cloud-network-services/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-network-services/#history +## [0.10.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-network-services-v0.9.0...google-cloud-network-services-v0.10.0) (2026-06-11) + + +### Features + +* update API sources and regenerate (#17431) ([2e75c78cdd09d4472ed412a2e925196effaea9fd](https://github.com/googleapis/google-cloud-python/commit/2e75c78cdd09d4472ed412a2e925196effaea9fd)) + ## [0.9.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-network-services-v0.8.0...google-cloud-network-services-v0.9.0) (2026-03-26) diff --git a/packages/google-cloud-network-services/google/cloud/network_services/gapic_version.py b/packages/google-cloud-network-services/google/cloud/network_services/gapic_version.py index 1a69f86a509b..0a5d17e6c82a 100644 --- a/packages/google-cloud-network-services/google/cloud/network_services/gapic_version.py +++ b/packages/google-cloud-network-services/google/cloud/network_services/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.9.0" # {x-release-please-version} +__version__ = "0.10.0" # {x-release-please-version} diff --git a/packages/google-cloud-network-services/google/cloud/network_services_v1/gapic_version.py b/packages/google-cloud-network-services/google/cloud/network_services_v1/gapic_version.py index 1a69f86a509b..0a5d17e6c82a 100644 --- a/packages/google-cloud-network-services/google/cloud/network_services_v1/gapic_version.py +++ b/packages/google-cloud-network-services/google/cloud/network_services_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.9.0" # {x-release-please-version} +__version__ = "0.10.0" # {x-release-please-version} diff --git a/packages/google-cloud-network-services/samples/generated_samples/snippet_metadata_google.cloud.networkservices.v1.json b/packages/google-cloud-network-services/samples/generated_samples/snippet_metadata_google.cloud.networkservices.v1.json index f3c4a8668983..7d74c7b62776 100644 --- a/packages/google-cloud-network-services/samples/generated_samples/snippet_metadata_google.cloud.networkservices.v1.json +++ b/packages/google-cloud-network-services/samples/generated_samples/snippet_metadata_google.cloud.networkservices.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-network-services", - "version": "0.9.0" + "version": "0.10.0" }, "snippets": [ { diff --git a/packages/google-cloud-oracledatabase/CHANGELOG.md b/packages/google-cloud-oracledatabase/CHANGELOG.md index 55bff8b24828..f4b4baad9966 100644 --- a/packages/google-cloud-oracledatabase/CHANGELOG.md +++ b/packages/google-cloud-oracledatabase/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-oracledatabase/#history +## [0.6.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-oracledatabase-v0.5.0...google-cloud-oracledatabase-v0.6.0) (2026-06-11) + + +### Features + +* update API sources and regenerate (#17413) ([59fe7cf83c123102baf5439af4acd6218d7ce01b](https://github.com/googleapis/google-cloud-python/commit/59fe7cf83c123102baf5439af4acd6218d7ce01b)) + ## [0.5.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-oracledatabase-v0.4.0...google-cloud-oracledatabase-v0.5.0) (2026-03-26) diff --git a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase/gapic_version.py b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase/gapic_version.py index 7d9863d19611..916d95dd4eda 100644 --- a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase/gapic_version.py +++ b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.5.0" # {x-release-please-version} +__version__ = "0.6.0" # {x-release-please-version} diff --git a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/gapic_version.py b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/gapic_version.py index 7d9863d19611..916d95dd4eda 100644 --- a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/gapic_version.py +++ b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.5.0" # {x-release-please-version} +__version__ = "0.6.0" # {x-release-please-version} diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/snippet_metadata_google.cloud.oracledatabase.v1.json b/packages/google-cloud-oracledatabase/samples/generated_samples/snippet_metadata_google.cloud.oracledatabase.v1.json index 8dbb40f31646..54c833e41b23 100644 --- a/packages/google-cloud-oracledatabase/samples/generated_samples/snippet_metadata_google.cloud.oracledatabase.v1.json +++ b/packages/google-cloud-oracledatabase/samples/generated_samples/snippet_metadata_google.cloud.oracledatabase.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-oracledatabase", - "version": "0.5.0" + "version": "0.6.0" }, "snippets": [ { diff --git a/packages/google-cloud-spanner/CHANGELOG.md b/packages/google-cloud-spanner/CHANGELOG.md index 8e6a53aef3a3..6290f4080ddb 100644 --- a/packages/google-cloud-spanner/CHANGELOG.md +++ b/packages/google-cloud-spanner/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-spanner/#history +## [3.68.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-spanner-v3.67.0...google-cloud-spanner-v3.68.0) (2026-06-11) + + +### Features + +* add asynchronous code snippets and minor cleanup changes (#17337) ([d6aaf610fa97b76077cacade2fca306dbe1e8c80](https://github.com/googleapis/google-cloud-python/commit/d6aaf610fa97b76077cacade2fca306dbe1e8c80)) + ## [3.67.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-spanner-v3.66.0...google-cloud-spanner-v3.67.0) (2026-06-02) diff --git a/packages/google-cloud-spanner/google/cloud/spanner/gapic_version.py b/packages/google-cloud-spanner/google/cloud/spanner/gapic_version.py index 2547dd9c2457..4e96af723141 100644 --- a/packages/google-cloud-spanner/google/cloud/spanner/gapic_version.py +++ b/packages/google-cloud-spanner/google/cloud/spanner/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "3.67.0" # {x-release-please-version} +__version__ = "3.68.0" # {x-release-please-version} diff --git a/packages/google-cloud-spanner/google/cloud/spanner_admin_database/gapic_version.py b/packages/google-cloud-spanner/google/cloud/spanner_admin_database/gapic_version.py index 2547dd9c2457..4e96af723141 100644 --- a/packages/google-cloud-spanner/google/cloud/spanner_admin_database/gapic_version.py +++ b/packages/google-cloud-spanner/google/cloud/spanner_admin_database/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "3.67.0" # {x-release-please-version} +__version__ = "3.68.0" # {x-release-please-version} diff --git a/packages/google-cloud-spanner/google/cloud/spanner_admin_database_v1/gapic_version.py b/packages/google-cloud-spanner/google/cloud/spanner_admin_database_v1/gapic_version.py index 2547dd9c2457..4e96af723141 100644 --- a/packages/google-cloud-spanner/google/cloud/spanner_admin_database_v1/gapic_version.py +++ b/packages/google-cloud-spanner/google/cloud/spanner_admin_database_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "3.67.0" # {x-release-please-version} +__version__ = "3.68.0" # {x-release-please-version} diff --git a/packages/google-cloud-spanner/google/cloud/spanner_admin_instance/gapic_version.py b/packages/google-cloud-spanner/google/cloud/spanner_admin_instance/gapic_version.py index 2547dd9c2457..4e96af723141 100644 --- a/packages/google-cloud-spanner/google/cloud/spanner_admin_instance/gapic_version.py +++ b/packages/google-cloud-spanner/google/cloud/spanner_admin_instance/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "3.67.0" # {x-release-please-version} +__version__ = "3.68.0" # {x-release-please-version} diff --git a/packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/gapic_version.py b/packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/gapic_version.py index 2547dd9c2457..4e96af723141 100644 --- a/packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/gapic_version.py +++ b/packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "3.67.0" # {x-release-please-version} +__version__ = "3.68.0" # {x-release-please-version} diff --git a/packages/google-cloud-spanner/google/cloud/spanner_dbapi/version.py b/packages/google-cloud-spanner/google/cloud/spanner_dbapi/version.py index b8b33b894a35..5b959b60d895 100644 --- a/packages/google-cloud-spanner/google/cloud/spanner_dbapi/version.py +++ b/packages/google-cloud-spanner/google/cloud/spanner_dbapi/version.py @@ -15,6 +15,6 @@ import platform PY_VERSION = platform.python_version() -__version__ = "3.67.0" +__version__ = "3.68.0" VERSION = __version__ DEFAULT_USER_AGENT = "gl-dbapi/" + VERSION diff --git a/packages/google-cloud-spanner/google/cloud/spanner_v1/gapic_version.py b/packages/google-cloud-spanner/google/cloud/spanner_v1/gapic_version.py index 2547dd9c2457..4e96af723141 100644 --- a/packages/google-cloud-spanner/google/cloud/spanner_v1/gapic_version.py +++ b/packages/google-cloud-spanner/google/cloud/spanner_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "3.67.0" # {x-release-please-version} +__version__ = "3.68.0" # {x-release-please-version} diff --git a/packages/google-cloud-spanner/samples/generated_samples/snippet_metadata_google.spanner.admin.database.v1.json b/packages/google-cloud-spanner/samples/generated_samples/snippet_metadata_google.spanner.admin.database.v1.json index 1da357e84ba1..cfb5a5d0a6d4 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/snippet_metadata_google.spanner.admin.database.v1.json +++ b/packages/google-cloud-spanner/samples/generated_samples/snippet_metadata_google.spanner.admin.database.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-spanner", - "version": "3.67.0" + "version": "3.68.0" }, "snippets": [ { diff --git a/packages/google-cloud-spanner/samples/generated_samples/snippet_metadata_google.spanner.admin.instance.v1.json b/packages/google-cloud-spanner/samples/generated_samples/snippet_metadata_google.spanner.admin.instance.v1.json index 360f473adca8..319317bdee70 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/snippet_metadata_google.spanner.admin.instance.v1.json +++ b/packages/google-cloud-spanner/samples/generated_samples/snippet_metadata_google.spanner.admin.instance.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-spanner", - "version": "3.67.0" + "version": "3.68.0" }, "snippets": [ { diff --git a/packages/google-cloud-spanner/samples/generated_samples/snippet_metadata_google.spanner.v1.json b/packages/google-cloud-spanner/samples/generated_samples/snippet_metadata_google.spanner.v1.json index 333740c85c30..3a3d815b6b55 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/snippet_metadata_google.spanner.v1.json +++ b/packages/google-cloud-spanner/samples/generated_samples/snippet_metadata_google.spanner.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-spanner", - "version": "3.67.0" + "version": "3.68.0" }, "snippets": [ { diff --git a/packages/google-cloud-storage/CHANGELOG.md b/packages/google-cloud-storage/CHANGELOG.md index 87aeb611f998..5d8d20c15d3d 100644 --- a/packages/google-cloud-storage/CHANGELOG.md +++ b/packages/google-cloud-storage/CHANGELOG.md @@ -4,6 +4,15 @@ [1]: https://pypi.org/project/google-cloud-storage/#history +## [3.12.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-storage-v3.11.0...google-cloud-storage-v3.12.0) (2026-06-11) + + +### Features + +* full object checksum: integrate full-object checksum in AsyncMultiRangeDownloader (#17263) ([b6a85e49ae3873a853812e46ddf759607a01cf25](https://github.com/googleapis/google-cloud-python/commit/b6a85e49ae3873a853812e46ddf759607a01cf25)) +* full object checksum: implement rolling checksum and verification in reads resumption strategy (#17262) ([2361ba6eeb766722b9460f3eb1dc1286c6fb19f3](https://github.com/googleapis/google-cloud-python/commit/2361ba6eeb766722b9460f3eb1dc1286c6fb19f3)) +* Enable full object checksum PR 1/3 : parse finalize_time and server crc32c in async object stream (#17261) ([72c7a2728bf66d684a12fdaac59c089115a53246](https://github.com/googleapis/google-cloud-python/commit/72c7a2728bf66d684a12fdaac59c089115a53246)) + ## [3.11.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-storage-v3.10.1...google-cloud-storage-v3.11.0) (2026-06-02) diff --git a/packages/google-cloud-storage/google/cloud/_storage/gapic_version.py b/packages/google-cloud-storage/google/cloud/_storage/gapic_version.py index 09a63573578e..a04a11ce2df9 100644 --- a/packages/google-cloud-storage/google/cloud/_storage/gapic_version.py +++ b/packages/google-cloud-storage/google/cloud/_storage/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "3.11.0" # {x-release-please-version} +__version__ = "3.12.0" # {x-release-please-version} diff --git a/packages/google-cloud-storage/google/cloud/_storage_v2/gapic_version.py b/packages/google-cloud-storage/google/cloud/_storage_v2/gapic_version.py index 09a63573578e..a04a11ce2df9 100644 --- a/packages/google-cloud-storage/google/cloud/_storage_v2/gapic_version.py +++ b/packages/google-cloud-storage/google/cloud/_storage_v2/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "3.11.0" # {x-release-please-version} +__version__ = "3.12.0" # {x-release-please-version} diff --git a/packages/google-cloud-storage/google/cloud/storage/version.py b/packages/google-cloud-storage/google/cloud/storage/version.py index 0e93e961e552..ea71d198bdd0 100644 --- a/packages/google-cloud-storage/google/cloud/storage/version.py +++ b/packages/google-cloud-storage/google/cloud/storage/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "3.11.0" +__version__ = "3.12.0" diff --git a/packages/google-cloud-storage/samples/generated_samples/snippet_metadata_google.storage.v2.json b/packages/google-cloud-storage/samples/generated_samples/snippet_metadata_google.storage.v2.json index 1fdc86ae171a..0a0171d423a6 100644 --- a/packages/google-cloud-storage/samples/generated_samples/snippet_metadata_google.storage.v2.json +++ b/packages/google-cloud-storage/samples/generated_samples/snippet_metadata_google.storage.v2.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-storage", - "version": "3.11.0" + "version": "3.12.0" }, "snippets": [ { diff --git a/packages/google-developer-knowledge/CHANGELOG.md b/packages/google-developer-knowledge/CHANGELOG.md index da1b0f4b4eb8..616821a57193 100644 --- a/packages/google-developer-knowledge/CHANGELOG.md +++ b/packages/google-developer-knowledge/CHANGELOG.md @@ -3,3 +3,10 @@ [PyPI History][1] [1]: https://pypi.org/project/google-developer-knowledge/#history + +## [0.1.0](https://github.com/googleapis/google-cloud-python/compare/google-developer-knowledge-v0.0.0...google-developer-knowledge-v0.1.0) (2026-06-11) + + +### Features + +* add google-developer-knowledge (#17417) ([ca02afce77af166d9e69cd65caf94fe5db505b30](https://github.com/googleapis/google-cloud-python/commit/ca02afce77af166d9e69cd65caf94fe5db505b30)) diff --git a/packages/google-developer-knowledge/google/developer_knowledge/gapic_version.py b/packages/google-developer-knowledge/google/developer_knowledge/gapic_version.py index e89a0031d71b..075b8773ece3 100644 --- a/packages/google-developer-knowledge/google/developer_knowledge/gapic_version.py +++ b/packages/google-developer-knowledge/google/developer_knowledge/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.0.0" # {x-release-please-version} +__version__ = "0.1.0" # {x-release-please-version} diff --git a/packages/google-developer-knowledge/google/developer_knowledge_v1/gapic_version.py b/packages/google-developer-knowledge/google/developer_knowledge_v1/gapic_version.py index e89a0031d71b..075b8773ece3 100644 --- a/packages/google-developer-knowledge/google/developer_knowledge_v1/gapic_version.py +++ b/packages/google-developer-knowledge/google/developer_knowledge_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.0.0" # {x-release-please-version} +__version__ = "0.1.0" # {x-release-please-version} diff --git a/packages/google-developer-knowledge/samples/generated_samples/snippet_metadata_google.developers.knowledge.v1.json b/packages/google-developer-knowledge/samples/generated_samples/snippet_metadata_google.developers.knowledge.v1.json index f9250f284097..66b47485c10e 100644 --- a/packages/google-developer-knowledge/samples/generated_samples/snippet_metadata_google.developers.knowledge.v1.json +++ b/packages/google-developer-knowledge/samples/generated_samples/snippet_metadata_google.developers.knowledge.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-developer-knowledge", - "version": "0.0.0" + "version": "0.1.0" }, "snippets": [ { From f0067701fd2cd3b76c2ced2fbd5cb507683c7fdd Mon Sep 17 00:00:00 2001 From: ohmayr Date: Thu, 11 Jun 2026 14:02:41 -0700 Subject: [PATCH 062/174] chore(firestore): optimize system tests runtime (#17418) Optimizes Firestore system tests execution time to 13 minutes (down from ~1 hour) under live GCP environments. **Parallelism:** Added pytest-xdist using all cores (--dist load for maximum load balancing). **Isolation:** Appended os.getpid() to test resource IDs to prevent parallel worker collisions. **Fixture Re-use:** Promoted query setup fixtures to module scope to reduce database setups by ~97%. **Fast Polling:** Reduced hardcoded delays in watch tests from 1.0s to 0.2s with early-exit polling. --- .../firestore-integration.yaml | 52 +++++++++++++++++++ packages/google-cloud-firestore/noxfile.py | 5 ++ .../tests/system/test__helpers.py | 2 +- .../tests/system/test_system.py | 48 +++++++++++------ .../tests/system/test_system_async.py | 6 +-- 5 files changed, 93 insertions(+), 20 deletions(-) diff --git a/.librarian/generator-input/client-post-processing/firestore-integration.yaml b/.librarian/generator-input/client-post-processing/firestore-integration.yaml index 2114dbabca04..fd5fb175852d 100644 --- a/.librarian/generator-input/client-post-processing/firestore-integration.yaml +++ b/.librarian/generator-input/client-post-processing/firestore-integration.yaml @@ -564,6 +564,9 @@ replacements: "freezegun", ] count: 1 + # TODO(https://github.com/googleapis/google-cloud-python/issues/17429): + # Temporary post-processing rule to add pytest-xdist dependency. + # Remove this once gapic-generator includes pytest-xdist by default. - paths: [ packages/google-cloud-firestore/noxfile.py ] @@ -574,6 +577,7 @@ replacements: "pytest-asyncio", "six", "pyyaml", + "pytest-xdist", ] count: 1 - paths: [ @@ -584,6 +588,54 @@ replacements: after: | "pytest-asyncio==0.21.2", count: 2 + # TODO(https://github.com/googleapis/google-cloud-python/issues/17429): + # Temporary post-processing rule to inject `-n auto` for Firestore parallel tests. + # This rule should be removed once the generator template changes are released + # and the generator version is updated in librarian.yaml. + - paths: [ + packages/google-cloud-firestore/noxfile.py + ] + before: | + # Run py.test against the system tests\. + if system_test_exists: + session\.run\( + "py.test", + "--quiet", + f"--junitxml=system_\{session\.python\}_sponge_log\.xml", + system_test_path, + \*session\.posargs, + \) + if system_test_folder_exists: + session\.run\( + "py.test", + "--quiet", + f"--junitxml=system_\{session\.python\}_sponge_log\.xml", + system_test_folder_path, + \*session\.posargs, + \) + after: | + # Run py.test against the system tests. + if system_test_exists: + session.run( + "py.test", + "-n", + "auto", + "--quiet", + f"--junitxml=system_{session.python}_sponge_log.xml", + system_test_path, + *session.posargs, + ) + if system_test_folder_exists: + session.run( + "py.test", + "-n", + "auto", + "--quiet", + f"--junitxml=system_{session.python}_sponge_log.xml", + system_test_folder_path, + *session.posargs, + ) + count: 1 - paths: [ "packages/google-cloud-firestore/docs/conf.py", ] diff --git a/packages/google-cloud-firestore/noxfile.py b/packages/google-cloud-firestore/noxfile.py index ef340c48888a..80fe70fa5798 100644 --- a/packages/google-cloud-firestore/noxfile.py +++ b/packages/google-cloud-firestore/noxfile.py @@ -82,6 +82,7 @@ "pytest-asyncio==0.21.2", "six", "pyyaml", + "pytest-xdist", ] SYSTEM_TEST_LOCAL_DEPENDENCIES: List[str] = [] SYSTEM_TEST_DEPENDENCIES: List[str] = [] @@ -402,6 +403,8 @@ def system(session): if system_test_exists: session.run( "py.test", + "-n", + "auto", "--quiet", f"--junitxml=system_{session.python}_sponge_log.xml", system_test_path, @@ -410,6 +413,8 @@ def system(session): if system_test_folder_exists: session.run( "py.test", + "-n", + "auto", "--quiet", f"--junitxml=system_{session.python}_sponge_log.xml", system_test_folder_path, diff --git a/packages/google-cloud-firestore/tests/system/test__helpers.py b/packages/google-cloud-firestore/tests/system/test__helpers.py index 83dd476602f2..228bd0e4362a 100644 --- a/packages/google-cloud-firestore/tests/system/test__helpers.py +++ b/packages/google-cloud-firestore/tests/system/test__helpers.py @@ -16,7 +16,7 @@ MISSING_DOCUMENT = "No document to update: " DOCUMENT_EXISTS = "Document already exists: " ENTERPRISE_MODE_ERROR = "only allowed on ENTERPRISE mode" -UNIQUE_RESOURCE_ID = unique_resource_id("-") +UNIQUE_RESOURCE_ID = unique_resource_id("-") + "-" + str(os.getpid()) EMULATOR_CREDS = EmulatorCreds() FIRESTORE_EMULATOR = os.environ.get(_FIRESTORE_EMULATOR_HOST) is not None FIRESTORE_OTHER_DB = os.environ.get("SYSTEM_TESTS_DATABASE", "system-tests-named-db") diff --git a/packages/google-cloud-firestore/tests/system/test_system.py b/packages/google-cloud-firestore/tests/system/test_system.py index 0827c372149d..fe475206d37f 100644 --- a/packages/google-cloud-firestore/tests/system/test_system.py +++ b/packages/google-cloud-firestore/tests/system/test_system.py @@ -1268,7 +1268,7 @@ def test_unicode_doc(client, cleanup, database): assert snapshot2.reference.id == explicit_doc_id -@pytest.fixture +@pytest.fixture(scope="module") def query_docs(client, database): collection_id = "qs" + UNIQUE_RESOURCE_ID sub_collection = "child" + UNIQUE_RESOURCE_ID @@ -1297,13 +1297,13 @@ def query_docs(client, database): operation() -@pytest.fixture +@pytest.fixture(scope="module") def collection(query_docs): collection, _, _ = query_docs return collection -@pytest.fixture +@pytest.fixture(scope="module") def query(collection): return collection.where(filter=FieldFilter("a", "==", 1)) @@ -2336,7 +2336,11 @@ def test_watch_document(client, cleanup, database): doc_ref.set({"first": "Jane", "last": "Doe", "born": 1900}) cleanup(doc_ref.delete) - sleep(1) + # TODO(https://github.com/googleapis/google-cloud-python/issues/17428): + # Investigate why these sleep/polling delays are needed for listener tests. + # Having arbitrary delays is fragile and can lead to flakiness. + # Explore event-driven synchronization. + sleep(0.2) # Setup listener def on_snapshot(docs, changes, read_time): @@ -2349,12 +2353,12 @@ def on_snapshot(docs, changes, read_time): # Alter document doc_ref.set({"first": "Ada", "last": "Lovelace", "born": 1815}) - sleep(1) + sleep(0.2) - for _ in range(10): + for _ in range(50): if on_snapshot.called_count > 0: break - sleep(1) + sleep(0.2) if on_snapshot.called_count not in (1, 2): raise AssertionError( @@ -2384,15 +2388,19 @@ def on_snapshot(docs, changes, read_time): collection_ref.on_snapshot(on_snapshot) + # TODO(https://github.com/googleapis/google-cloud-python/issues/17428): + # Investigate why these sleep/polling delays are needed for listener tests. + # Having arbitrary delays is fragile and can lead to flakiness. + # Explore event-driven synchronization. # delay here so initial on_snapshot occurs and isn't combined with set - sleep(1) + sleep(0.2) doc_ref.set({"first": "Ada", "last": "Lovelace", "born": 1815}) - for _ in range(10): + for _ in range(50): if on_snapshot.born == 1815: break - sleep(1) + sleep(0.2) if on_snapshot.born != 1815: raise AssertionError( @@ -2411,7 +2419,11 @@ def test_watch_query(client, cleanup, database): doc_ref.set({"first": "Jane", "last": "Doe", "born": 1900}) cleanup(doc_ref.delete) - sleep(1) + # TODO(https://github.com/googleapis/google-cloud-python/issues/17428): + # Investigate why these sleep/polling delays are needed for listener tests. + # Having arbitrary delays is fragile and can lead to flakiness. + # Explore event-driven synchronization. + sleep(0.2) # Setup listener def on_snapshot(docs, changes, read_time): @@ -2429,10 +2441,10 @@ def on_snapshot(docs, changes, read_time): # Alter document doc_ref.set({"first": "Ada", "last": "Lovelace", "born": 1815}) - for _ in range(10): + for _ in range(50): if on_snapshot.called_count == 1: return - sleep(1) + sleep(0.2) if on_snapshot.called_count != 1: raise AssertionError( @@ -2806,7 +2818,11 @@ def on_snapshot(docs, changes, read_time): on_snapshot.failed = None query_ref.on_snapshot(on_snapshot) - sleep(1) + # TODO(https://github.com/googleapis/google-cloud-python/issues/17428): + # Investigate why these sleep/polling delays are needed for listener tests. + # Having arbitrary delays is fragile and can lead to flakiness. + # Explore event-driven synchronization. + sleep(0.2) doc_ref1.set({"first": "Ada", "last": "Lovelace", "born": 1815}) cleanup(doc_ref1.delete) @@ -2823,10 +2839,10 @@ def on_snapshot(docs, changes, read_time): doc_ref5.set({"first": "Ada", "last": "lovelace", "born": 1815}) cleanup(doc_ref5.delete) - for _ in range(10): + for _ in range(50): if on_snapshot.last_doc_count == 5: break - sleep(1) + sleep(0.2) if on_snapshot.failed: raise on_snapshot.failed diff --git a/packages/google-cloud-firestore/tests/system/test_system_async.py b/packages/google-cloud-firestore/tests/system/test_system_async.py index 34c7eb6d8164..ef8ca5b84d5f 100644 --- a/packages/google-cloud-firestore/tests/system/test_system_async.py +++ b/packages/google-cloud-firestore/tests/system/test_system_async.py @@ -1243,7 +1243,7 @@ async def test_list_collections_with_read_time(client, cleanup, database): } -@pytest_asyncio.fixture +@pytest_asyncio.fixture(scope="module") async def query_docs(client): collection_id = "qs" + UNIQUE_RESOURCE_ID sub_collection = "child" + UNIQUE_RESOURCE_ID @@ -1272,13 +1272,13 @@ async def query_docs(client): await operation() -@pytest_asyncio.fixture +@pytest_asyncio.fixture(scope="module") async def collection(query_docs): collection, _, _ = query_docs yield collection -@pytest_asyncio.fixture +@pytest_asyncio.fixture(scope="module") async def async_query(collection): return collection.where(filter=FieldFilter("a", "==", 1)) From 7f29823fadb3cff42dbe666f8c7aa33bab3c7021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Swe=C3=B1a=20=28Swast=29?= Date: Thu, 11 Jun 2026 16:39:31 -0500 Subject: [PATCH 063/174] feat: add `bigframes.bigquery.bit_count` and conversion scalar function (#17433) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🦕 --- .../bigframes/bigframes/bigquery/__init__.py | 32 +++ .../extensions/core/series_accessor.py | 154 ++++++++++++++ .../googlesql/global_namespace/bit.py | 48 +++++ .../googlesql/global_namespace/conversion.py | 193 ++++++++++++++++++ .../sql-functions/global_namespace/bit.yaml | 26 +++ .../global_namespace/conversion.yaml | 119 +++++++++++ .../scripts/generate_bigframes_bigquery.py | 82 +++++++- .../scripts/templates/test_operation.py.j2 | 2 +- .../generated/global_namespace/test_bit.py | 43 ++++ .../global_namespace/test_conversion.py | 172 ++++++++++++++++ 10 files changed, 868 insertions(+), 3 deletions(-) create mode 100644 packages/bigframes/bigframes/operations/googlesql/global_namespace/bit.py create mode 100644 packages/bigframes/bigframes/operations/googlesql/global_namespace/conversion.py create mode 100644 packages/bigframes/scripts/data/sql-functions/global_namespace/bit.yaml create mode 100644 packages/bigframes/scripts/data/sql-functions/global_namespace/conversion.yaml create mode 100644 packages/bigframes/tests/unit/bigquery/generated/global_namespace/test_bit.py create mode 100644 packages/bigframes/tests/unit/bigquery/generated/global_namespace/test_conversion.py diff --git a/packages/bigframes/bigframes/bigquery/__init__.py b/packages/bigframes/bigframes/bigquery/__init__.py index d3fb8701df20..99a47d218691 100644 --- a/packages/bigframes/bigframes/bigquery/__init__.py +++ b/packages/bigframes/bigframes/bigquery/__init__.py @@ -114,6 +114,18 @@ flatten, generate_array, ) +from bigframes.operations.googlesql.global_namespace.bit import ( + bit_count, +) +from bigframes.operations.googlesql.global_namespace.conversion import ( + bool_, + double, + float64, + int64, + parse_bignumeric, + parse_numeric, + string, +) _functions = [ # approximate aggregate ops @@ -134,6 +146,16 @@ array_to_string, flatten, generate_array, + # bit ops + bit_count, + # conversion ops + bool_, + double, + float64, + int64, + parse_bignumeric, + parse_numeric, + string, # datetime ops unix_micros, unix_millis, @@ -208,6 +230,16 @@ "array_to_string", "flatten", "generate_array", + # bit ops + "bit_count", + # conversion ops + "bool_", + "double", + "float64", + "int64", + "parse_bignumeric", + "parse_numeric", + "string", # datetime ops "unix_micros", "unix_millis", diff --git a/packages/bigframes/bigframes/extensions/core/series_accessor.py b/packages/bigframes/bigframes/extensions/core/series_accessor.py index 4c0f261b83cd..96d0eb8d045e 100644 --- a/packages/bigframes/bigframes/extensions/core/series_accessor.py +++ b/packages/bigframes/bigframes/extensions/core/series_accessor.py @@ -598,6 +598,160 @@ def flatten( ) return self._to_series(cast(series.Series, result)) + def bool_( + self, + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Converts a JSON boolean to a SQL BOOL value.""" + from bigframes.operations.googlesql.global_namespace.conversion import ( + bool_ as bool__impl, + ) + + bf_series = self._bf_from_series(session) + result = bool__impl( + bf_series, + ) + return self._to_series(cast(series.Series, result)) + + def double( + self, + wide_number_mode: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Converts a JSON number to a SQL FLOAT64 value.""" + from bigframes.operations.googlesql.global_namespace.conversion import ( + double as double_impl, + ) + + # Resolve session from other arguments if not passed + if session is None: + import bigframes.core.googlesql as googlesql + + session = googlesql._find_session( + wide_number_mode, + ) + + bf_series = self._bf_from_series(session) + result = double_impl( + bf_series, + wide_number_mode, + ) + return self._to_series(cast(series.Series, result)) + + def float64( + self, + wide_number_mode: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Converts a JSON number to a SQL FLOAT64 value.""" + from bigframes.operations.googlesql.global_namespace.conversion import ( + float64 as float64_impl, + ) + + # Resolve session from other arguments if not passed + if session is None: + import bigframes.core.googlesql as googlesql + + session = googlesql._find_session( + wide_number_mode, + ) + + bf_series = self._bf_from_series(session) + result = float64_impl( + bf_series, + wide_number_mode, + ) + return self._to_series(cast(series.Series, result)) + + def int64( + self, + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Converts a JSON number to a SQL INT64 value.""" + from bigframes.operations.googlesql.global_namespace.conversion import ( + int64 as int64_impl, + ) + + bf_series = self._bf_from_series(session) + result = int64_impl( + bf_series, + ) + return self._to_series(cast(series.Series, result)) + + def parse_bignumeric( + self, + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Converts a STRING to a BIGNUMERIC value.""" + from bigframes.operations.googlesql.global_namespace.conversion import ( + parse_bignumeric as parse_bignumeric_impl, + ) + + bf_series = self._bf_from_series(session) + result = parse_bignumeric_impl( + bf_series, + ) + return self._to_series(cast(series.Series, result)) + + def parse_numeric( + self, + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Converts a STRING to a NUMERIC value.""" + from bigframes.operations.googlesql.global_namespace.conversion import ( + parse_numeric as parse_numeric_impl, + ) + + bf_series = self._bf_from_series(session) + result = parse_numeric_impl( + bf_series, + ) + return self._to_series(cast(series.Series, result)) + + def string( + self, + timezone: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Converts a value to a STRING value.""" + from bigframes.operations.googlesql.global_namespace.conversion import ( + string as string_impl, + ) + + # Resolve session from other arguments if not passed + if session is None: + import bigframes.core.googlesql as googlesql + + session = googlesql._find_session( + timezone, + ) + + bf_series = self._bf_from_series(session) + result = string_impl( + bf_series, + timezone, + ) + return self._to_series(cast(series.Series, result)) + class AeadSeriesAccessor(AbstractBigQuerySeriesAccessor[S]): """Series accessor for BigQuery aead functions.""" diff --git a/packages/bigframes/bigframes/operations/googlesql/global_namespace/bit.py b/packages/bigframes/bigframes/operations/googlesql/global_namespace/bit.py new file mode 100644 index 000000000000..e0c22dfc2990 --- /dev/null +++ b/packages/bigframes/bigframes/operations/googlesql/global_namespace/bit.py @@ -0,0 +1,48 @@ +# Copyright 2026 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. +# +# DO NOT MODIFY THIS FILE DIRECTLY. +# This file was generated from: scripts/data/sql-functions/global_namespace/bit.yaml +# by the script: scripts/generate_bigframes_bigquery.py + +from __future__ import annotations + +from typing import Any, Literal, Union + +import bigframes.core.col +import bigframes.core.googlesql +import bigframes.core.sentinels as sentinels +import bigframes.series as series +from bigframes import dtypes +from bigframes.operations import googlesql + +_BIT_COUNT_OP = googlesql.GoogleSqlScalarOp( + "BIT_COUNT", + args=(googlesql.ArgSpec(),), + signature=lambda *args: dtypes.INT_DTYPE, +) + + +def bit_count( + expression: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Any, Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes, int], + ], +) -> Union[series.Series, bigframes.core.col.Expression]: + """The input, `expression`, must be an integer or `BYTES`. Returns the number of bits that are set in the input expression. For signed integers, this is the number of bits in two's complement form.""" + return bigframes.core.googlesql.apply_googlesql_scalar_op( + _BIT_COUNT_OP, + expression, + ) diff --git a/packages/bigframes/bigframes/operations/googlesql/global_namespace/conversion.py b/packages/bigframes/bigframes/operations/googlesql/global_namespace/conversion.py new file mode 100644 index 000000000000..cea4e45d836b --- /dev/null +++ b/packages/bigframes/bigframes/operations/googlesql/global_namespace/conversion.py @@ -0,0 +1,193 @@ +# Copyright 2026 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. +# +# DO NOT MODIFY THIS FILE DIRECTLY. +# This file was generated from: scripts/data/sql-functions/global_namespace/conversion.yaml +# by the script: scripts/generate_bigframes_bigquery.py + +from __future__ import annotations + +import datetime +from typing import Literal, Union + +import bigframes.core.col +import bigframes.core.googlesql +import bigframes.core.sentinels as sentinels +import bigframes.series as series +from bigframes import dtypes +from bigframes.operations import googlesql + +_BOOL_OP = googlesql.GoogleSqlScalarOp( + "BOOL", + args=(googlesql.ArgSpec(),), + signature=lambda *args: dtypes.BOOL_DTYPE, +) +_DOUBLE_OP = googlesql.GoogleSqlScalarOp( + "DOUBLE", + args=( + googlesql.ArgSpec(), + googlesql.ArgSpec(arg_name="wide_number_mode", optional=True), + ), + signature=lambda *args: dtypes.FLOAT_DTYPE, +) +_FLOAT64_OP = googlesql.GoogleSqlScalarOp( + "FLOAT64", + args=( + googlesql.ArgSpec(), + googlesql.ArgSpec(arg_name="wide_number_mode", optional=True), + ), + signature=lambda *args: dtypes.FLOAT_DTYPE, +) +_INT64_OP = googlesql.GoogleSqlScalarOp( + "INT64", + args=(googlesql.ArgSpec(),), + signature=lambda *args: dtypes.INT_DTYPE, +) +_PARSE_BIGNUMERIC_OP = googlesql.GoogleSqlScalarOp( + "PARSE_BIGNUMERIC", + args=(googlesql.ArgSpec(),), + signature=lambda *args: dtypes.BIGNUMERIC_DTYPE, +) +_PARSE_NUMERIC_OP = googlesql.GoogleSqlScalarOp( + "PARSE_NUMERIC", + args=(googlesql.ArgSpec(),), + signature=lambda *args: dtypes.NUMERIC_DTYPE, +) +_STRING_OP = googlesql.GoogleSqlScalarOp( + "STRING", + args=(googlesql.ArgSpec(), googlesql.ArgSpec(optional=True)), + signature=lambda *args: dtypes.STRING_DTYPE, +) + + +def bool_( + json_string_expression: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ], +) -> Union[series.Series, bigframes.core.col.Expression]: + """Converts a JSON boolean to a SQL BOOL value.""" + return bigframes.core.googlesql.apply_googlesql_scalar_op( + _BOOL_OP, + json_string_expression, + ) + + +def double( + json_string_expression: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ], + wide_number_mode: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, +) -> Union[series.Series, bigframes.core.col.Expression]: + """Converts a JSON number to a SQL FLOAT64 value.""" + return bigframes.core.googlesql.apply_googlesql_scalar_op( + _DOUBLE_OP, + json_string_expression, + wide_number_mode, + ) + + +def float64( + json_string_expression: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ], + wide_number_mode: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, +) -> Union[series.Series, bigframes.core.col.Expression]: + """Converts a JSON number to a SQL FLOAT64 value.""" + return bigframes.core.googlesql.apply_googlesql_scalar_op( + _FLOAT64_OP, + json_string_expression, + wide_number_mode, + ) + + +def int64( + json_string_expression: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ], +) -> Union[series.Series, bigframes.core.col.Expression]: + """Converts a JSON number to a SQL INT64 value.""" + return bigframes.core.googlesql.apply_googlesql_scalar_op( + _INT64_OP, + json_string_expression, + ) + + +def parse_bignumeric( + string_expression: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ], +) -> Union[series.Series, bigframes.core.col.Expression]: + """Converts a STRING to a BIGNUMERIC value.""" + return bigframes.core.googlesql.apply_googlesql_scalar_op( + _PARSE_BIGNUMERIC_OP, + string_expression, + ) + + +def parse_numeric( + string_expression: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ], +) -> Union[series.Series, bigframes.core.col.Expression]: + """Converts a STRING to a NUMERIC value.""" + return bigframes.core.googlesql.apply_googlesql_scalar_op( + _PARSE_NUMERIC_OP, + string_expression, + ) + + +def string( + expression: Union[ + series.Series, + bigframes.core.col.Expression, + Union[ + Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], + datetime.date, + datetime.datetime, + datetime.time, + str, + ], + ], + timezone: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, +) -> Union[series.Series, bigframes.core.col.Expression]: + """Converts a value to a STRING value.""" + return bigframes.core.googlesql.apply_googlesql_scalar_op( + _STRING_OP, + expression, + timezone, + ) diff --git a/packages/bigframes/scripts/data/sql-functions/global_namespace/bit.yaml b/packages/bigframes/scripts/data/sql-functions/global_namespace/bit.yaml new file mode 100644 index 000000000000..3c2953133e49 --- /dev/null +++ b/packages/bigframes/scripts/data/sql-functions/global_namespace/bit.yaml @@ -0,0 +1,26 @@ +urn: extension:google:bq_scalar_functions +scalar_functions: + - name: "bit_count" + description: "The input, `expression`, must be an integer or `BYTES`. Returns the number of bits that are set in the input expression. For signed integers, this is the number of bits in two's complement form." + impls: + # Signature: bit_count:i32 + - args: + - name: "expression" + value: i32 + optional: false + keyword_only: false + return: i64 + # Signature: bit_count:i64 + - args: + - name: "expression" + value: i64 + optional: false + keyword_only: false + return: i64 + # Signature: bit_count:vbin + - args: + - name: "expression" + value: binary + optional: false + keyword_only: false + return: i64 diff --git a/packages/bigframes/scripts/data/sql-functions/global_namespace/conversion.yaml b/packages/bigframes/scripts/data/sql-functions/global_namespace/conversion.yaml new file mode 100644 index 000000000000..c39724427de4 --- /dev/null +++ b/packages/bigframes/scripts/data/sql-functions/global_namespace/conversion.yaml @@ -0,0 +1,119 @@ +urn: extension:google:bq_scalar_functions +scalar_functions: + - name: "bool" + description: "Converts a JSON boolean to a SQL BOOL value." + series_accessor_arg: json_string_expression + impls: + # Signature: bool:str + - args: + - name: "json_string_expression" + value: string + optional: false + keyword_only: false + return: boolean + - name: "double" + description: "Converts a JSON number to a SQL FLOAT64 value." + series_accessor_arg: json_string_expression + impls: + # Signature: double:str_str + - args: + - name: "json_string_expression" + value: string + optional: false + keyword_only: false + - name: "wide_number_mode" + value: string + optional: true + keyword_only: true + return: fp64 + - name: "float64" + description: "Converts a JSON number to a SQL FLOAT64 value." + series_accessor_arg: json_string_expression + impls: + # Signature: float64:str_str + - args: + - name: "json_string_expression" + value: string + optional: false + keyword_only: false + - name: "wide_number_mode" + value: string + optional: true + keyword_only: true + return: fp64 + - name: "int64" + description: "Converts a JSON number to a SQL INT64 value." + series_accessor_arg: json_string_expression + impls: + # Signature: int64:str + - args: + - name: "json_string_expression" + value: string + optional: false + keyword_only: false + return: i64 + - name: "parse_bignumeric" + description: "Converts a STRING to a BIGNUMERIC value." + series_accessor_arg: string_expression + impls: + # Signature: parse_bignumeric:str + - args: + - name: "string_expression" + value: string + optional: false + keyword_only: false + return: decimal<76,38> + - name: "parse_numeric" + description: "Converts a STRING to a NUMERIC value." + series_accessor_arg: string_expression + impls: + # Signature: parse_numeric:str + - args: + - name: "string_expression" + value: string + optional: false + keyword_only: false + return: decimal<38,9> + - name: "string" + description: "Converts a value to a STRING value." + series_accessor_arg: expression + impls: + # Signature: string:pts_str + - args: + - name: "expression" + value: timestamp + optional: false + keyword_only: false + - name: "timezone" + value: string + optional: true + keyword_only: false + return: string + # Signature: string:date + - args: + - name: "expression" + value: date + optional: false + keyword_only: false + return: string + # Signature: string:pt + - args: + - name: "expression" + value: time + optional: false + keyword_only: false + return: string + # Signature: string:pts + - args: + - name: "expression" + value: timestamp + optional: false + keyword_only: false + return: string + # Signature: string:str + - args: + - name: "expression" + value: string + optional: false + keyword_only: false + return: string diff --git a/packages/bigframes/scripts/generate_bigframes_bigquery.py b/packages/bigframes/scripts/generate_bigframes_bigquery.py index 124604354205..bb232a6cdf8c 100755 --- a/packages/bigframes/scripts/generate_bigframes_bigquery.py +++ b/packages/bigframes/scripts/generate_bigframes_bigquery.py @@ -77,6 +77,7 @@ "datetime": "dtypes.DATETIME_DTYPE", "timestamp": "dtypes.TIMESTAMP_DTYPE", "decimal<38,9>": "dtypes.NUMERIC_DTYPE", + "decimal<76,38>": "dtypes.BIGNUMERIC_DTYPE", } PY_TYPE_MAP = { @@ -96,6 +97,7 @@ "timestamp": "datetime.datetime", "struct": "dict", "decimal<38,9>": "decimal.Decimal", + "decimal<76,38>": "decimal.Decimal", } YAML_TYPE_TO_COL = { @@ -113,6 +115,78 @@ "datetime": "datetime_col", "timestamp": "timestamp_col", "decimal<38,9>": "numeric_col", + "decimal<76,38>": "bignumeric_col", +} + +_PYTHON_BUILTINS = { + "abs", + "all", + "any", + "ascii", + "bin", + "bool", + "breakpoint", + "bytearray", + "bytes", + "callable", + "chr", + "classmethod", + "compile", + "complex", + "delattr", + "dict", + "dir", + "divmod", + "enumerate", + "eval", + "exec", + "filter", + "float", + "format", + "frozenset", + "getattr", + "globals", + "hasattr", + "hash", + "help", + "hex", + "id", + "input", + "int", + "isinstance", + "issubclass", + "iter", + "len", + "list", + "locals", + "map", + "max", + "memoryview", + "min", + "next", + "object", + "oct", + "open", + "ord", + "pow", + "print", + "property", + "range", + "repr", + "reversed", + "round", + "set", + "setattr", + "slice", + "sorted", + "staticmethod", + "str", + "sum", + "super", + "tuple", + "type", + "vars", + "zip", } @@ -311,7 +385,11 @@ def parse_scalar_functions(data, module_name, signature_def_template, is_global= if not is_global and python_name.startswith(module_name + "_"): python_name = python_name[len(module_name) + 1 :] - internal_op_name = f"_{python_name.upper()}_OP" + op_base_name = python_name + if python_name in _PYTHON_BUILTINS: + python_name = python_name + "_" + + internal_op_name = f"_{op_base_name.upper()}_OP" # Aggregate args across impls args_by_name, arg_order = _collect_args(func_data["impls"]) @@ -324,7 +402,7 @@ def parse_scalar_functions(data, module_name, signature_def_template, is_global= # Determine return dtype sig_name, sig_def = _generate_signature_def( - python_name, + op_base_name, func_data["impls"], sql_name, signature_def_template, diff --git a/packages/bigframes/scripts/templates/test_operation.py.j2 b/packages/bigframes/scripts/templates/test_operation.py.j2 index 21db9cbfc8ba..6aee365cdedb 100644 --- a/packages/bigframes/scripts/templates/test_operation.py.j2 +++ b/packages/bigframes/scripts/templates/test_operation.py.j2 @@ -31,7 +31,7 @@ def test_{{ func.name }}_expression(): # Verify the internal expression structure expr = result._value assert isinstance(expr, ex.OpExpression) - assert expr.op == {{ short_name }}_op._{{ func.name | upper }}_OP + assert expr.op == {{ short_name }}_op.{{ func.op_name }} # Verify arguments are free variables matching the names assert len(expr.inputs) == {{ func.args | length }} diff --git a/packages/bigframes/tests/unit/bigquery/generated/global_namespace/test_bit.py b/packages/bigframes/tests/unit/bigquery/generated/global_namespace/test_bit.py new file mode 100644 index 000000000000..2cccafc0643d --- /dev/null +++ b/packages/bigframes/tests/unit/bigquery/generated/global_namespace/test_bit.py @@ -0,0 +1,43 @@ +# Copyright 2026 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. +# +# DO NOT MODIFY THIS FILE DIRECTLY. +# This file was generated from: scripts/data/sql-functions/global_namespace/bit.yaml +# by the script: scripts/generate_bigframes_bigquery.py + +import bigframes.bigquery as bbq +import bigframes.core.col +import bigframes.core.expression as ex +import bigframes.operations.googlesql.global_namespace.bit as bit_op +import bigframes.pandas as bpd + + +def test_bit_count_expression(): + # Call the function with col() expressions + result = bbq.bit_count( + bpd.col("expression"), + ) + + # Verify result is a col Expression + assert isinstance(result, bigframes.core.col.Expression) + + # Verify the internal expression structure + expr = result._value + assert isinstance(expr, ex.OpExpression) + assert expr.op == bit_op._BIT_COUNT_OP + + # Verify arguments are free variables matching the names + assert len(expr.inputs) == 1 + assert isinstance(expr.inputs[0], ex.UnboundVariableExpression) + assert expr.inputs[0].id == "expression" diff --git a/packages/bigframes/tests/unit/bigquery/generated/global_namespace/test_conversion.py b/packages/bigframes/tests/unit/bigquery/generated/global_namespace/test_conversion.py new file mode 100644 index 000000000000..84dfc02465cc --- /dev/null +++ b/packages/bigframes/tests/unit/bigquery/generated/global_namespace/test_conversion.py @@ -0,0 +1,172 @@ +# Copyright 2026 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. +# +# DO NOT MODIFY THIS FILE DIRECTLY. +# This file was generated from: scripts/data/sql-functions/global_namespace/conversion.yaml +# by the script: scripts/generate_bigframes_bigquery.py + +import bigframes.bigquery as bbq +import bigframes.core.col +import bigframes.core.expression as ex +import bigframes.operations.googlesql.global_namespace.conversion as conversion_op +import bigframes.pandas as bpd + + +def test_bool__expression(): + # Call the function with col() expressions + result = bbq.bool_( + bpd.col("json_string_expression"), + ) + + # Verify result is a col Expression + assert isinstance(result, bigframes.core.col.Expression) + + # Verify the internal expression structure + expr = result._value + assert isinstance(expr, ex.OpExpression) + assert expr.op == conversion_op._BOOL_OP + + # Verify arguments are free variables matching the names + assert len(expr.inputs) == 1 + assert isinstance(expr.inputs[0], ex.UnboundVariableExpression) + assert expr.inputs[0].id == "json_string_expression" + + +def test_double_expression(): + # Call the function with col() expressions + result = bbq.double( + bpd.col("json_string_expression"), + bpd.col("wide_number_mode"), + ) + + # Verify result is a col Expression + assert isinstance(result, bigframes.core.col.Expression) + + # Verify the internal expression structure + expr = result._value + assert isinstance(expr, ex.OpExpression) + assert expr.op == conversion_op._DOUBLE_OP + + # Verify arguments are free variables matching the names + assert len(expr.inputs) == 2 + assert isinstance(expr.inputs[0], ex.UnboundVariableExpression) + assert expr.inputs[0].id == "json_string_expression" + assert isinstance(expr.inputs[1], ex.UnboundVariableExpression) + assert expr.inputs[1].id == "wide_number_mode" + + +def test_float64_expression(): + # Call the function with col() expressions + result = bbq.float64( + bpd.col("json_string_expression"), + bpd.col("wide_number_mode"), + ) + + # Verify result is a col Expression + assert isinstance(result, bigframes.core.col.Expression) + + # Verify the internal expression structure + expr = result._value + assert isinstance(expr, ex.OpExpression) + assert expr.op == conversion_op._FLOAT64_OP + + # Verify arguments are free variables matching the names + assert len(expr.inputs) == 2 + assert isinstance(expr.inputs[0], ex.UnboundVariableExpression) + assert expr.inputs[0].id == "json_string_expression" + assert isinstance(expr.inputs[1], ex.UnboundVariableExpression) + assert expr.inputs[1].id == "wide_number_mode" + + +def test_int64_expression(): + # Call the function with col() expressions + result = bbq.int64( + bpd.col("json_string_expression"), + ) + + # Verify result is a col Expression + assert isinstance(result, bigframes.core.col.Expression) + + # Verify the internal expression structure + expr = result._value + assert isinstance(expr, ex.OpExpression) + assert expr.op == conversion_op._INT64_OP + + # Verify arguments are free variables matching the names + assert len(expr.inputs) == 1 + assert isinstance(expr.inputs[0], ex.UnboundVariableExpression) + assert expr.inputs[0].id == "json_string_expression" + + +def test_parse_bignumeric_expression(): + # Call the function with col() expressions + result = bbq.parse_bignumeric( + bpd.col("string_expression"), + ) + + # Verify result is a col Expression + assert isinstance(result, bigframes.core.col.Expression) + + # Verify the internal expression structure + expr = result._value + assert isinstance(expr, ex.OpExpression) + assert expr.op == conversion_op._PARSE_BIGNUMERIC_OP + + # Verify arguments are free variables matching the names + assert len(expr.inputs) == 1 + assert isinstance(expr.inputs[0], ex.UnboundVariableExpression) + assert expr.inputs[0].id == "string_expression" + + +def test_parse_numeric_expression(): + # Call the function with col() expressions + result = bbq.parse_numeric( + bpd.col("string_expression"), + ) + + # Verify result is a col Expression + assert isinstance(result, bigframes.core.col.Expression) + + # Verify the internal expression structure + expr = result._value + assert isinstance(expr, ex.OpExpression) + assert expr.op == conversion_op._PARSE_NUMERIC_OP + + # Verify arguments are free variables matching the names + assert len(expr.inputs) == 1 + assert isinstance(expr.inputs[0], ex.UnboundVariableExpression) + assert expr.inputs[0].id == "string_expression" + + +def test_string_expression(): + # Call the function with col() expressions + result = bbq.string( + bpd.col("expression"), + bpd.col("timezone"), + ) + + # Verify result is a col Expression + assert isinstance(result, bigframes.core.col.Expression) + + # Verify the internal expression structure + expr = result._value + assert isinstance(expr, ex.OpExpression) + assert expr.op == conversion_op._STRING_OP + + # Verify arguments are free variables matching the names + assert len(expr.inputs) == 2 + assert isinstance(expr.inputs[0], ex.UnboundVariableExpression) + assert expr.inputs[0].id == "expression" + assert isinstance(expr.inputs[1], ex.UnboundVariableExpression) + assert expr.inputs[1].id == "timezone" From f932bcaaa2663c9d1a6219f5a2e1fe42d391224a Mon Sep 17 00:00:00 2001 From: Tomo Suzuki Date: Thu, 11 Jun 2026 19:23:43 -0400 Subject: [PATCH 064/174] chore(google-cloud-bigquery): unskip release (#17435) --- librarian.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/librarian.yaml b/librarian.yaml index a9a31501696a..25570c818942 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -539,7 +539,6 @@ libraries: default_version: v1beta - name: google-cloud-bigquery version: 3.41.0 - skip_release: true python: library_type: GAPIC_COMBO metadata_name_override: bigquery From ac1f5d55900d4787f2ced6b5350ef530f700794b Mon Sep 17 00:00:00 2001 From: ohmayr Date: Fri, 12 Jun 2026 08:18:29 -0700 Subject: [PATCH 065/174] fix: make test_utils unique_resource_id parallel-safe (#17440) This PR shifts the parallel-safety logic (`os.getpid()`) out of the individual firestore system tests, baking it directly into the shared `test_utils` package. This ensures that all packages in the monorepo using pytest-xdist will automatically generate unique collection/resource names that never collide across parallel workers, rather than requiring each library to manually append PID strings to `unique_resource_id()`. --- .../firestore-integration.yaml | 25 +++++++++++++++++++ packages/google-cloud-firestore/noxfile.py | 3 +-- .../tests/system/test__helpers.py | 2 +- .../test_utils/system.py | 12 +++++++-- 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/.librarian/generator-input/client-post-processing/firestore-integration.yaml b/.librarian/generator-input/client-post-processing/firestore-integration.yaml index fd5fb175852d..6b1c18229ed3 100644 --- a/.librarian/generator-input/client-post-processing/firestore-integration.yaml +++ b/.librarian/generator-input/client-post-processing/firestore-integration.yaml @@ -564,6 +564,31 @@ replacements: "freezegun", ] count: 1 + - paths: [ + packages/google-cloud-firestore/noxfile.py + ] + before: | + SYSTEM_TEST_STANDARD_DEPENDENCIES = \[ + "mock", + "pytest", + "google-cloud-testutils", + \] + after: | + SYSTEM_TEST_STANDARD_DEPENDENCIES = [ + "mock", + "pytest", + ] + count: 1 + - paths: [ + packages/google-cloud-firestore/noxfile.py + ] + before: | + SYSTEM_TEST_LOCAL_DEPENDENCIES: List\[str\] = \[\] + after: | + SYSTEM_TEST_LOCAL_DEPENDENCIES: List[str] = [ + "../google-cloud-testutils" + ] + count: 1 # TODO(https://github.com/googleapis/google-cloud-python/issues/17429): # Temporary post-processing rule to add pytest-xdist dependency. # Remove this once gapic-generator includes pytest-xdist by default. diff --git a/packages/google-cloud-firestore/noxfile.py b/packages/google-cloud-firestore/noxfile.py index 80fe70fa5798..a89acb8a0c38 100644 --- a/packages/google-cloud-firestore/noxfile.py +++ b/packages/google-cloud-firestore/noxfile.py @@ -76,7 +76,6 @@ SYSTEM_TEST_STANDARD_DEPENDENCIES = [ "mock", "pytest", - "google-cloud-testutils", ] SYSTEM_TEST_EXTERNAL_DEPENDENCIES: List[str] = [ "pytest-asyncio==0.21.2", @@ -84,7 +83,7 @@ "pyyaml", "pytest-xdist", ] -SYSTEM_TEST_LOCAL_DEPENDENCIES: List[str] = [] +SYSTEM_TEST_LOCAL_DEPENDENCIES: List[str] = ["../google-cloud-testutils"] SYSTEM_TEST_DEPENDENCIES: List[str] = [] SYSTEM_TEST_EXTRAS: List[str] = [] SYSTEM_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} diff --git a/packages/google-cloud-firestore/tests/system/test__helpers.py b/packages/google-cloud-firestore/tests/system/test__helpers.py index 228bd0e4362a..83dd476602f2 100644 --- a/packages/google-cloud-firestore/tests/system/test__helpers.py +++ b/packages/google-cloud-firestore/tests/system/test__helpers.py @@ -16,7 +16,7 @@ MISSING_DOCUMENT = "No document to update: " DOCUMENT_EXISTS = "Document already exists: " ENTERPRISE_MODE_ERROR = "only allowed on ENTERPRISE mode" -UNIQUE_RESOURCE_ID = unique_resource_id("-") + "-" + str(os.getpid()) +UNIQUE_RESOURCE_ID = unique_resource_id("-") EMULATOR_CREDS = EmulatorCreds() FIRESTORE_EMULATOR = os.environ.get(_FIRESTORE_EMULATOR_HOST) is not None FIRESTORE_OTHER_DB = os.environ.get("SYSTEM_TESTS_DATABASE", "system-tests-named-db") diff --git a/packages/google-cloud-testutils/test_utils/system.py b/packages/google-cloud-testutils/test_utils/system.py index 18a29303c449..ed513be422bd 100644 --- a/packages/google-cloud-testutils/test_utils/system.py +++ b/packages/google-cloud-testutils/test_utils/system.py @@ -74,7 +74,15 @@ def unique_resource_id(delimiter="_"): testing environments and at particular times. """ build_id = os.getenv("CIRCLE_BUILD_NUM", "") + pid = os.getpid() if build_id == "": - return "%s%d" % (delimiter, 1000 * time.time()) + return "%s%d%s%d" % (delimiter, 1000 * time.time(), delimiter, pid) else: - return "%s%s%s%d" % (delimiter, build_id, delimiter, time.time()) + return "%s%s%s%d%s%d" % ( + delimiter, + build_id, + delimiter, + time.time(), + delimiter, + pid, + ) From ab01ffa1c61fa30189fe751133aafba221a08e31 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Fri, 12 Jun 2026 09:43:03 -0700 Subject: [PATCH 066/174] chore(firestore): fix firestore flaky tests (#17439) Fixes: https://github.com/googleapis/google-cloud-python/issues/17428 Additional change: using 10 workers instead of `auto` seems to be a sweet spot. --- .../firestore-integration.yaml | 4 +- packages/google-cloud-firestore/noxfile.py | 4 +- .../tests/system/test_system.py | 121 ++++++------------ .../tests/system/test_system_async.py | 4 +- 4 files changed, 48 insertions(+), 85 deletions(-) diff --git a/.librarian/generator-input/client-post-processing/firestore-integration.yaml b/.librarian/generator-input/client-post-processing/firestore-integration.yaml index 6b1c18229ed3..3fbc8093e139 100644 --- a/.librarian/generator-input/client-post-processing/firestore-integration.yaml +++ b/.librarian/generator-input/client-post-processing/firestore-integration.yaml @@ -644,7 +644,7 @@ replacements: session.run( "py.test", "-n", - "auto", + "10", "--quiet", f"--junitxml=system_{session.python}_sponge_log.xml", system_test_path, @@ -654,7 +654,7 @@ replacements: session.run( "py.test", "-n", - "auto", + "10", "--quiet", f"--junitxml=system_{session.python}_sponge_log.xml", system_test_folder_path, diff --git a/packages/google-cloud-firestore/noxfile.py b/packages/google-cloud-firestore/noxfile.py index a89acb8a0c38..4df37240719c 100644 --- a/packages/google-cloud-firestore/noxfile.py +++ b/packages/google-cloud-firestore/noxfile.py @@ -403,7 +403,7 @@ def system(session): session.run( "py.test", "-n", - "auto", + "10", "--quiet", f"--junitxml=system_{session.python}_sponge_log.xml", system_test_path, @@ -413,7 +413,7 @@ def system(session): session.run( "py.test", "-n", - "auto", + "10", "--quiet", f"--junitxml=system_{session.python}_sponge_log.xml", system_test_folder_path, diff --git a/packages/google-cloud-firestore/tests/system/test_system.py b/packages/google-cloud-firestore/tests/system/test_system.py index fe475206d37f..7d8394ea5673 100644 --- a/packages/google-cloud-firestore/tests/system/test_system.py +++ b/packages/google-cloud-firestore/tests/system/test_system.py @@ -12,11 +12,11 @@ # See the License for the specific language governing permissions and # limitations under the License. +import concurrent.futures import datetime import itertools import math import operator -from time import sleep from typing import Callable, Dict, List, Optional import google.auth @@ -80,8 +80,8 @@ def cleanup(): operations = [] yield operations.append - for operation in operations: - operation() + with concurrent.futures.ThreadPoolExecutor() as executor: + list(executor.map(lambda op: op(), operations)) @pytest.fixture @@ -389,15 +389,18 @@ def test_create_document_w_vector(client, cleanup, database): for v in client.collection(collection_id).order_by("embedding").get() ] == [data3, data1, data2] + vector_query_future = concurrent.futures.Future() + def on_snapshot(docs, changes, read_time): on_snapshot.results += docs + if len(on_snapshot.results) >= 3 and not vector_query_future.done(): + vector_query_future.set_result(True) on_snapshot.results = [] client.collection(collection_id).order_by("embedding").on_snapshot(on_snapshot) - # delay here so initial on_snapshot occurs and isn't combined with set - sleep(1) - assert [v.to_dict() for v in on_snapshot.results] == [data3, data1, data2] + vector_query_future.result(timeout=60.0) + assert [v.to_dict() for v in on_snapshot.results[:3]] == [data3, data1, data2] @pytest.mark.skipif(FIRESTORE_EMULATOR, reason="Require index and seed data") @@ -2336,15 +2339,13 @@ def test_watch_document(client, cleanup, database): doc_ref.set({"first": "Jane", "last": "Doe", "born": 1900}) cleanup(doc_ref.delete) - # TODO(https://github.com/googleapis/google-cloud-python/issues/17428): - # Investigate why these sleep/polling delays are needed for listener tests. - # Having arbitrary delays is fragile and can lead to flakiness. - # Explore event-driven synchronization. - sleep(0.2) - # Setup listener + ada_future = concurrent.futures.Future() + def on_snapshot(docs, changes, read_time): on_snapshot.called_count += 1 + if docs and docs[0].get("first") == "Ada" and not ada_future.done(): + ada_future.set_result(True) on_snapshot.called_count = 0 @@ -2353,12 +2354,8 @@ def on_snapshot(docs, changes, read_time): # Alter document doc_ref.set({"first": "Ada", "last": "Lovelace", "born": 1815}) - sleep(0.2) - - for _ in range(50): - if on_snapshot.called_count > 0: - break - sleep(0.2) + # Wait for the event-driven callback to resolve the future + ada_future.result(timeout=60.0) if on_snapshot.called_count not in (1, 2): raise AssertionError( @@ -2378,34 +2375,18 @@ def test_watch_collection(client, cleanup, database): cleanup(doc_ref.delete) # Setup listener + born_1815_future = concurrent.futures.Future() + def on_snapshot(docs, changes, read_time): - on_snapshot.called_count += 1 for doc in [doc for doc in docs if doc.id == doc_ref.id]: - on_snapshot.born = doc.get("born") - - on_snapshot.called_count = 0 - on_snapshot.born = 0 + if doc.get("born") == 1815 and not born_1815_future.done(): + born_1815_future.set_result(True) collection_ref.on_snapshot(on_snapshot) - # TODO(https://github.com/googleapis/google-cloud-python/issues/17428): - # Investigate why these sleep/polling delays are needed for listener tests. - # Having arbitrary delays is fragile and can lead to flakiness. - # Explore event-driven synchronization. - # delay here so initial on_snapshot occurs and isn't combined with set - sleep(0.2) - doc_ref.set({"first": "Ada", "last": "Lovelace", "born": 1815}) - for _ in range(50): - if on_snapshot.born == 1815: - break - sleep(0.2) - - if on_snapshot.born != 1815: - raise AssertionError( - "Expected the last document update to update born: " + str(on_snapshot.born) - ) + born_1815_future.result(timeout=60.0) @pytest.mark.parametrize("database", TEST_DATABASES, indirect=True) @@ -2419,20 +2400,21 @@ def test_watch_query(client, cleanup, database): doc_ref.set({"first": "Jane", "last": "Doe", "born": 1900}) cleanup(doc_ref.delete) - # TODO(https://github.com/googleapis/google-cloud-python/issues/17428): - # Investigate why these sleep/polling delays are needed for listener tests. - # Having arbitrary delays is fragile and can lead to flakiness. - # Explore event-driven synchronization. - sleep(0.2) - # Setup listener + one_doc_future = concurrent.futures.Future() + def on_snapshot(docs, changes, read_time): on_snapshot.called_count += 1 - # A snapshot should return the same thing as if a query ran now. - query_ran_query = collection_ref.where(filter=FieldFilter("first", "==", "Ada")) - query_ran = query_ran_query.stream() - assert len(docs) == len([i for i in query_ran]) + if docs: + # A snapshot should return the same thing as if a query ran now. + query_ran_query = collection_ref.where( + filter=FieldFilter("first", "==", "Ada") + ) + query_ran = query_ran_query.stream() + assert len(docs) == len([i for i in query_ran]) + if not one_doc_future.done(): + one_doc_future.set_result(True) on_snapshot.called_count = 0 @@ -2441,14 +2423,11 @@ def on_snapshot(docs, changes, read_time): # Alter document doc_ref.set({"first": "Ada", "last": "Lovelace", "born": 1815}) - for _ in range(50): - if on_snapshot.called_count == 1: - return - sleep(0.2) + one_doc_future.result(timeout=60.0) - if on_snapshot.called_count != 1: + if on_snapshot.called_count not in (1, 2): raise AssertionError( - "Failed to get exactly one document change: count: " + "Failed to get expected document change count: " + str(on_snapshot.called_count) ) @@ -2788,6 +2767,8 @@ def test_watch_query_order(client, cleanup, database): ) # Setup listener + five_docs_future = concurrent.futures.Future() + def on_snapshot(docs, changes, read_time): try: docs = [i for i in docs if i.id.endswith(UNIQUE_RESOURCE_ID)] @@ -2808,22 +2789,14 @@ def on_snapshot(docs, changes, read_time): assert snapshot.get("born") == query.get("born"), ( "expect the sort order to match, born" ) - on_snapshot.called_count += 1 - on_snapshot.last_doc_count = len(docs) + if not five_docs_future.done(): + five_docs_future.set_result(True) except Exception as e: - on_snapshot.failed = e + if not five_docs_future.done(): + five_docs_future.set_exception(e) - on_snapshot.called_count = 0 - on_snapshot.last_doc_count = 0 - on_snapshot.failed = None query_ref.on_snapshot(on_snapshot) - # TODO(https://github.com/googleapis/google-cloud-python/issues/17428): - # Investigate why these sleep/polling delays are needed for listener tests. - # Having arbitrary delays is fragile and can lead to flakiness. - # Explore event-driven synchronization. - sleep(0.2) - doc_ref1.set({"first": "Ada", "last": "Lovelace", "born": 1815}) cleanup(doc_ref1.delete) @@ -2839,18 +2812,8 @@ def on_snapshot(docs, changes, read_time): doc_ref5.set({"first": "Ada", "last": "lovelace", "born": 1815}) cleanup(doc_ref5.delete) - for _ in range(50): - if on_snapshot.last_doc_count == 5: - break - sleep(0.2) - - if on_snapshot.failed: - raise on_snapshot.failed - - if on_snapshot.last_doc_count != 5: - raise AssertionError( - "5 docs expected in snapshot method " + str(on_snapshot.last_doc_count) - ) + # Wait for the future to be resolved + five_docs_future.result(timeout=60.0) @pytest.mark.parametrize("database", TEST_DATABASES_W_ENTERPRISE, indirect=True) diff --git a/packages/google-cloud-firestore/tests/system/test_system_async.py b/packages/google-cloud-firestore/tests/system/test_system_async.py index ef8ca5b84d5f..6356f24bea8c 100644 --- a/packages/google-cloud-firestore/tests/system/test_system_async.py +++ b/packages/google-cloud-firestore/tests/system/test_system_async.py @@ -160,8 +160,8 @@ async def cleanup(): operations = [] yield operations.append - for operation in operations: - await operation() + if operations: + await asyncio.gather(*[operation() for operation in operations]) @pytest.fixture From a6970c834c13c3a3c530a4e3bb3ae3b1e31d09db Mon Sep 17 00:00:00 2001 From: ohmayr Date: Fri, 12 Jun 2026 10:09:47 -0700 Subject: [PATCH 067/174] chore(firestore): remove named database duplication in system tests (#17442) This PR reduces system test execution time by removing redundant test sweeps across identical standard databases. --- .../google-cloud-firestore/tests/system/test__helpers.py | 6 ++++-- packages/google-cloud-firestore/tests/system/test_system.py | 5 ++++- .../tests/system/test_system_async.py | 5 ++++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/google-cloud-firestore/tests/system/test__helpers.py b/packages/google-cloud-firestore/tests/system/test__helpers.py index 83dd476602f2..018eea55bfc1 100644 --- a/packages/google-cloud-firestore/tests/system/test__helpers.py +++ b/packages/google-cloud-firestore/tests/system/test__helpers.py @@ -22,8 +22,10 @@ FIRESTORE_OTHER_DB = os.environ.get("SYSTEM_TESTS_DATABASE", "system-tests-named-db") FIRESTORE_ENTERPRISE_DB = os.environ.get("ENTERPRISE_DATABASE", "enterprise-db-native") -# run all tests against default database, and a named database -TEST_DATABASES = [None, FIRESTORE_OTHER_DB] +# To eliminate test duplication, we use the default database for the +# core test suites. The named database is ONLY tested explicitly in dedicated +# routing tests to prove path construction works. +TEST_DATABASES = [None] TEST_DATABASES_W_ENTERPRISE = TEST_DATABASES + [FIRESTORE_ENTERPRISE_DB] diff --git a/packages/google-cloud-firestore/tests/system/test_system.py b/packages/google-cloud-firestore/tests/system/test_system.py index 7d8394ea5673..cd16279fa988 100644 --- a/packages/google-cloud-firestore/tests/system/test_system.py +++ b/packages/google-cloud-firestore/tests/system/test_system.py @@ -36,6 +36,7 @@ FIRESTORE_CREDS, FIRESTORE_EMULATOR, FIRESTORE_ENTERPRISE_DB, + FIRESTORE_OTHER_DB, FIRESTORE_PROJECT, MISSING_DOCUMENT, RANDOM_ID_REGEX, @@ -1067,7 +1068,9 @@ def check_snapshot(snapshot, document, data, write_result): assert snapshot.update_time == write_result.update_time -@pytest.mark.parametrize("database", TEST_DATABASES, indirect=True) +# We explicitly parameterize test_document_get with FIRESTORE_OTHER_DB to test +# named database path routing natively, without inflating the rest of the test suite. +@pytest.mark.parametrize("database", [None, FIRESTORE_OTHER_DB], indirect=True) def test_document_get(client, cleanup, database): now = datetime.datetime.now(tz=datetime.timezone.utc) document_id = "for-get" + UNIQUE_RESOURCE_ID diff --git a/packages/google-cloud-firestore/tests/system/test_system_async.py b/packages/google-cloud-firestore/tests/system/test_system_async.py index 6356f24bea8c..1003f2a5a015 100644 --- a/packages/google-cloud-firestore/tests/system/test_system_async.py +++ b/packages/google-cloud-firestore/tests/system/test_system_async.py @@ -39,6 +39,7 @@ FIRESTORE_CREDS, FIRESTORE_EMULATOR, FIRESTORE_ENTERPRISE_DB, + FIRESTORE_OTHER_DB, FIRESTORE_PROJECT, MISSING_DOCUMENT, RANDOM_ID_REGEX, @@ -1046,7 +1047,9 @@ def check_snapshot(snapshot, document, data, write_result): assert snapshot.update_time == write_result.update_time -@pytest.mark.parametrize("database", TEST_DATABASES, indirect=True) +# We explicitly parameterize test_document_get with FIRESTORE_OTHER_DB to test +# named database path routing natively, without inflating the rest of the test suite. +@pytest.mark.parametrize("database", [None, FIRESTORE_OTHER_DB], indirect=True) async def test_document_get(client, cleanup, database): now = datetime.datetime.now(tz=datetime.timezone.utc) document_id = "for-get" + UNIQUE_RESOURCE_ID From 08cc1f65f4f535d16ab99b435b1bbf9a1edb9cb1 Mon Sep 17 00:00:00 2001 From: Shuowei Li Date: Fri, 12 Jun 2026 17:26:54 +0000 Subject: [PATCH 068/174] chore(bigframes): document release procedure using legacylibrarian (#17436) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #<522923981> 🦕 --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- packages/bigframes/release-procedure.md | 51 +++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 packages/bigframes/release-procedure.md diff --git a/packages/bigframes/release-procedure.md b/packages/bigframes/release-procedure.md new file mode 100644 index 000000000000..aeb87862fe64 --- /dev/null +++ b/packages/bigframes/release-procedure.md @@ -0,0 +1,51 @@ +# BigQuery DataFrames (bigframes) release procedure + +*(Note: bigframes releases are marked with `skip_release: true` in `librarian.yaml` and must be kicked off manually using legacylibrarian.)* + +## Setup (First Time Only) + +* Install `legacylibrarian`: + + go install github.com/googleapis/librarian/cmd/legacylibrarian@latest + +* Authenticate with GitHub CLI: + + gh auth login + +## Release Steps + +* Obtain GitHub token: + + export LIBRARIAN_GITHUB_TOKEN=$(gh auth token) + +* Stash changes (repo must be clean): + + git stash -u + +* Fetch and checkout base: + + git fetch origin main + git fetch origin --tags + git checkout origin/main + +* Check image updates: + + legacylibrarian update-image --push + +* Create release PR: + + # Option A: Push directly + legacylibrarian release stage --repo=https://github.com/googleapis/google-cloud-python --library=bigframes --library-version=X.X.X --push + + # Option B: Manual edit first (omit --push, edit files in /tmp/librarian-*, commit/push from there) + legacylibrarian release stage --repo=https://github.com/googleapis/google-cloud-python --library=bigframes --library-version=X.X.X + # In /tmp repository: + git commit -a -m "chore: create release" --no-verify # keep librarian config pristine + git push origin HEAD + gh pr create --fill --label "release:pending" + +* Post-release restore: + + # Move back any stashed/relocated files (like .vscode) + git checkout main + git stash pop From d7f57fcc576fbf20ff6faeaeb3a59f5dcb41ba2f Mon Sep 17 00:00:00 2001 From: ohmayr Date: Fri, 12 Jun 2026 11:02:49 -0700 Subject: [PATCH 069/174] chore(bigframes): optimize system test teardown (#17443) brings down bigframes system tests from 23 mins to 12 mins i.e. 2x speed up. --- .../bigframes/session/anonymous_dataset.py | 17 ++++++++++++++--- packages/bigframes/noxfile.py | 1 + 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/packages/bigframes/bigframes/session/anonymous_dataset.py b/packages/bigframes/bigframes/session/anonymous_dataset.py index 1a3d43655b79..ed718ff909f0 100644 --- a/packages/bigframes/bigframes/session/anonymous_dataset.py +++ b/packages/bigframes/bigframes/session/anonymous_dataset.py @@ -16,6 +16,7 @@ import threading import uuid import warnings +from concurrent.futures import ThreadPoolExecutor from typing import List, Optional, Sequence import google.cloud.bigquery as bigquery @@ -170,9 +171,19 @@ def _cleanup_old_udfs(self): def close(self): """Delete tables that were created with this session's session_id.""" - for table_ref in self._table_ids: - self.bqclient.delete_table(table_ref, not_found_ok=True) - self._table_ids.clear() + if self._table_ids: + try: + with ThreadPoolExecutor() as executor: + futures = [ + executor.submit( + self.bqclient.delete_table, table_ref, not_found_ok=True + ) + for table_ref in self._table_ids + ] + for future in futures: + future.result() + finally: + self._table_ids.clear() try: # Before closing the session, attempt to clean up any uncollected, diff --git a/packages/bigframes/noxfile.py b/packages/bigframes/noxfile.py index e7c105a552e8..0a33264aa8ea 100644 --- a/packages/bigframes/noxfile.py +++ b/packages/bigframes/noxfile.py @@ -354,6 +354,7 @@ def run_system( "py.test", "-v", f"-n={num_workers}", + "--dist=worksteal", # Any individual test taking longer than 15 mins will be terminated. f"--timeout={timeout_seconds}", # Log 20 slowest tests From 4d3447d567f7e0f6d5793f1dc55da87b437de231 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Fri, 12 Jun 2026 12:34:47 -0700 Subject: [PATCH 070/174] chore: skip sqlalchemy-bigquery test to unblock CI (#17288) skip sqlalchemy-bigquery test to keep builds green. See: https://github.com/googleapis/google-cloud-python/issues/17287. Releases will be blocked for `sqlalchemy-bigquery` until this test is fixed. See https://github.com/googleapis/google-cloud-python/pull/17289 --- packages/sqlalchemy-bigquery/tests/system/test_geography.py | 6 ++++++ packages/sqlalchemy-bigquery/tests/unit/test_geography.py | 2 ++ 2 files changed, 8 insertions(+) diff --git a/packages/sqlalchemy-bigquery/tests/system/test_geography.py b/packages/sqlalchemy-bigquery/tests/system/test_geography.py index 3519c31c6a75..c689642f56be 100644 --- a/packages/sqlalchemy-bigquery/tests/system/test_geography.py +++ b/packages/sqlalchemy-bigquery/tests/system/test_geography.py @@ -22,6 +22,8 @@ geoalchemy2 = pytest.importorskip("geoalchemy2") +# TODO(http://github.com/googleapis/google-cloud-python/issues/17287): Unskip once bug is resolved. +@pytest.mark.skip(reason="Failing in CI with AssertionError.") def test_geoalchemy2_core(bigquery_dataset): """Make sure GeoAlchemy 2 Core Tutorial works as adapted to only having geography @@ -139,6 +141,8 @@ def test_geoalchemy2_core(bigquery_dataset): ) +# TODO(http://github.com/googleapis/google-cloud-python/issues/17287): Unskip once bug is resolved. +@pytest.mark.skip(reason="Failing in CI with AssertionError.") def test_geoalchemy2_orm(bigquery_dataset): """Make sure GeoAlchemy 2 ORM Tutorial works as adapted to only having geometry @@ -254,6 +258,8 @@ class Lake(Base): ] +# TODO(http://github.com/googleapis/google-cloud-python/issues/17287): Unskip once bug is resolved. +@pytest.mark.skip(reason="Failing in CI with AssertionError.") def test_geoalchemy2_orm_w_relationship(bigquery_dataset): from sqlalchemy import create_engine diff --git a/packages/sqlalchemy-bigquery/tests/unit/test_geography.py b/packages/sqlalchemy-bigquery/tests/unit/test_geography.py index 647e1bc36b6c..d03dbf940d93 100644 --- a/packages/sqlalchemy-bigquery/tests/unit/test_geography.py +++ b/packages/sqlalchemy-bigquery/tests/unit/test_geography.py @@ -24,6 +24,8 @@ geoalchemy2 = pytest.importorskip("geoalchemy2") +# TODO(http://github.com/googleapis/google-cloud-python/issues/17287): Unskip once bug is resolved. +@pytest.mark.skip(reason="Failing in CI with AssertionError.") def test_geoalchemy2_core(faux_conn, last_query): """Make sure GeoAlchemy 2 Core Tutorial works as adapted to only having geometry""" conn = faux_conn From dd59d3623c0af8c3ae683b0ea808b1992a917071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Swe=C3=B1a=20=28Swast=29?= Date: Fri, 12 Jun 2026 16:52:59 -0500 Subject: [PATCH 071/174] chore: address pandas 3 failure and remove inherently flaky system test (#17452) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes b/523301714 🦕 --- .../tests/system/test_pandas.py | 2 +- .../tests/system/test_query.py | 38 +++++-------------- 2 files changed, 10 insertions(+), 30 deletions(-) diff --git a/packages/google-cloud-bigquery/tests/system/test_pandas.py b/packages/google-cloud-bigquery/tests/system/test_pandas.py index d1031436ec32..08f20dba71c3 100644 --- a/packages/google-cloud-bigquery/tests/system/test_pandas.py +++ b/packages/google-cloud-bigquery/tests/system/test_pandas.py @@ -1098,7 +1098,7 @@ def test_list_rows_nullable_scalars_dtypes(bigquery_client, scalars_table, max_r # pandas uses Python string and bytes objects. assert df.dtypes["bytes_col"].name == "object" - assert df.dtypes["string_col"].name == "object" + assert df.dtypes["string_col"].name in ("str", "string", "object") @pytest.mark.parametrize( diff --git a/packages/google-cloud-bigquery/tests/system/test_query.py b/packages/google-cloud-bigquery/tests/system/test_query.py index 437c28f73915..69ff08b66073 100644 --- a/packages/google-cloud-bigquery/tests/system/test_query.py +++ b/packages/google-cloud-bigquery/tests/system/test_query.py @@ -12,22 +12,22 @@ # See the License for the specific language governing permissions and # limitations under the License. -import concurrent.futures import datetime import decimal from typing import Tuple -from google.api_core import exceptions import pytest - +from google.api_core import exceptions from google.cloud import bigquery from google.cloud.bigquery import enums -from google.cloud.bigquery.query import ArrayQueryParameter -from google.cloud.bigquery.query import ScalarQueryParameter -from google.cloud.bigquery.query import ScalarQueryParameterType -from google.cloud.bigquery.query import StructQueryParameter -from google.cloud.bigquery.query import StructQueryParameterType -from google.cloud.bigquery.query import RangeQueryParameter +from google.cloud.bigquery.query import ( + ArrayQueryParameter, + RangeQueryParameter, + ScalarQueryParameter, + ScalarQueryParameterType, + StructQueryParameter, + StructQueryParameterType, +) @pytest.fixture(params=["INSERT", "QUERY"]) @@ -79,26 +79,6 @@ def test_query_many_columns( assert row[f"col_{column}"] == rowval * column -def test_query_w_timeout(bigquery_client, query_api_method): - job_config = bigquery.QueryJobConfig() - job_config.use_query_cache = False - - query_job = bigquery_client.query( - "SELECT * FROM `bigquery-public-data.github_repos.commits`;", - location="US", - job_config=job_config, - api_method=query_api_method, - ) - - with pytest.raises(concurrent.futures.TimeoutError): - query_job.result(timeout=1) - - # Even though the query takes >1 second, the call to getQueryResults - # should succeed. - assert not query_job.done(timeout=1) - assert bigquery_client.cancel_job(query_job) is not None - - def test_query_statistics(bigquery_client, query_api_method): """ A system test to exercise some of the extended query statistics. From 145034a345eb3e14ea3f23dfcafa3d2409a09067 Mon Sep 17 00:00:00 2001 From: Shuowei Li Date: Fri, 12 Jun 2026 23:06:10 +0000 Subject: [PATCH 072/174] fix: preserve aliases on cast columns and fix star selection in sqlglot (#17394) (#17455) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ** This branch is under testing, not ready for review ** This PR resolves a regression introduced when switching to the default `sqlglot` compiler, where cast columns lost their aliases during type-coercion and were auto-named by BigQuery as `f0_`, `f1_`, etc. (fixes #17394). Before: screen/7FibgBYoY6EN8hR After: screen/AWsDt8aocqyzjup Fixes #<521420846> 🦕 --- .../bigframes/core/compile/sqlglot/sqlglot_ir.py | 9 +++++---- packages/bigframes/bigframes/core/sql_nodes.py | 9 ++++++++- .../test_datetime_ops/test_to_datetime/out.sql | 6 +++--- .../test_generic_ops/test_astype_float/out.sql | 4 ++-- .../test_generic_ops/test_astype_string/out.sql | 4 ++-- .../compile/sqlglot/expressions/test_datetime_ops.py | 2 +- .../compile/sqlglot/expressions/test_generic_ops.py | 4 ++-- .../test_compile_astype_aliases/out.sql | 5 +++++ .../core/compile/sqlglot/test_compile_readtable.py | 12 ++++++++++++ 9 files changed, 40 insertions(+), 15 deletions(-) create mode 100644 packages/bigframes/tests/unit/core/compile/sqlglot/snapshots/test_compile_readtable/test_compile_astype_aliases/out.sql diff --git a/packages/bigframes/bigframes/core/compile/sqlglot/sqlglot_ir.py b/packages/bigframes/bigframes/core/compile/sqlglot/sqlglot_ir.py index 1e0b561e8c5b..b29a23cd84b8 100644 --- a/packages/bigframes/bigframes/core/compile/sqlglot/sqlglot_ir.py +++ b/packages/bigframes/bigframes/core/compile/sqlglot/sqlglot_ir.py @@ -249,12 +249,13 @@ def select( # TODO: Explicitly insert CTEs into plan if len(selections) > 0: to_select = [ - sge.Alias( - this=expr, + expr + if (isinstance(expr, sge.Alias) and expr.alias == id) + or (isinstance(expr, sge.Column) and expr.name == id) + else sge.Alias( + this=expr.this if isinstance(expr, sge.Alias) else expr, alias=sql.identifier(id), ) - if expr.alias_or_name != id - else expr for id, expr in selections ] new_expr = self.expr.select(*to_select) diff --git a/packages/bigframes/bigframes/core/sql_nodes.py b/packages/bigframes/bigframes/core/sql_nodes.py index 4cb4b02f7b80..c7a05a082f29 100644 --- a/packages/bigframes/bigframes/core/sql_nodes.py +++ b/packages/bigframes/bigframes/core/sql_nodes.py @@ -276,7 +276,14 @@ def _node_expressions(self): @property def is_star_selection(self) -> bool: - return tuple(self.ids) == tuple(self.child.ids) + if tuple(self.ids) != tuple(self.child.ids): + return False + for cdef in self.selections: + if not isinstance(cdef.expression, ex.DerefOp): + return False + if cdef.expression.id != cdef.id: + return False + return True @functools.cache def get_id_mapping(self) -> dict[identifiers.ColumnId, ex.Expression]: diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_datetime_ops/test_to_datetime/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_datetime_ops/test_to_datetime/out.sql index 9a2913e44beb..57ec17bf681a 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_datetime_ops/test_to_datetime/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_datetime_ops/test_to_datetime/out.sql @@ -1,7 +1,7 @@ SELECT CAST(TIMESTAMP_MICROS(CAST(TRUNC(`int64_col` * 0.001) AS INT64)) AS DATETIME) AS `int64_col`, - SAFE_CAST(`string_col` AS DATETIME), + SAFE_CAST(`string_col` AS DATETIME) AS `string_col`, CAST(TIMESTAMP_MICROS(CAST(TRUNC(`float64_col` * 0.001) AS INT64)) AS DATETIME) AS `float64_col`, - SAFE_CAST(`timestamp_col` AS DATETIME), + SAFE_CAST(`timestamp_col` AS DATETIME) AS `timestamp_col`, SAFE_CAST(`string_col` AS DATETIME) AS `string_col_fmt` -FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` AS `bft_0` \ No newline at end of file +FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` AS `bft_0` diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_generic_ops/test_astype_float/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_generic_ops/test_astype_float/out.sql index 3d48001e77ad..7f7bd86084ea 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_generic_ops/test_astype_float/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_generic_ops/test_astype_float/out.sql @@ -1,5 +1,5 @@ SELECT - CAST(CAST(`bool_col` AS INT64) AS FLOAT64), + CAST(CAST(`bool_col` AS INT64) AS FLOAT64) AS `bool_col`, CAST('1.34235e4' AS FLOAT64) AS `str_const`, SAFE_CAST(SAFE_CAST(`bool_col` AS INT64) AS FLOAT64) AS `bool_w_safe` -FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` AS `bft_0` \ No newline at end of file +FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` AS `bft_0` diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_generic_ops/test_astype_string/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_generic_ops/test_astype_string/out.sql index 3ea2299cc4f9..174f18d98233 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_generic_ops/test_astype_string/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_generic_ops/test_astype_string/out.sql @@ -1,5 +1,5 @@ SELECT - CAST(`int64_col` AS STRING), + CAST(`int64_col` AS STRING) AS `int64_col`, INITCAP(CAST(`bool_col` AS STRING)) AS `bool_col`, INITCAP(SAFE_CAST(`bool_col` AS STRING)) AS `bool_w_safe` -FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` AS `bft_0` \ No newline at end of file +FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` AS `bft_0` diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/test_datetime_ops.py b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/test_datetime_ops.py index fd3aacc7e271..e86059b160a8 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/test_datetime_ops.py +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/test_datetime_ops.py @@ -217,7 +217,7 @@ def test_to_datetime(scalar_types_df: bpd.DataFrame, snapshot): ) sql = utils._apply_ops_to_sql(bf_df, list(ops_map.values()), list(ops_map.keys())) - snapshot.assert_match(sql, "out.sql") + snapshot.assert_match(sql + "\n", "out.sql") def test_to_timestamp(scalar_types_df: bpd.DataFrame, snapshot): diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/test_generic_ops.py b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/test_generic_ops.py index fb5a9fd7ce84..185a8df04509 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/test_generic_ops.py +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/test_generic_ops.py @@ -60,7 +60,7 @@ def test_astype_float(scalar_types_df: bpd.DataFrame, snapshot): "bool_w_safe": ops.AsTypeOp(to_type=to_type, safe=True).as_expr("bool_col"), } sql = utils._apply_ops_to_sql(bf_df, list(ops_map.values()), list(ops_map.keys())) - snapshot.assert_match(sql, "out.sql") + snapshot.assert_match(sql + "\n", "out.sql") def test_astype_bool(scalar_types_df: bpd.DataFrame, snapshot): @@ -107,7 +107,7 @@ def test_astype_string(scalar_types_df: bpd.DataFrame, snapshot): "bool_w_safe": ops.AsTypeOp(to_type=to_type, safe=True).as_expr("bool_col"), } sql = utils._apply_ops_to_sql(bf_df, list(ops_map.values()), list(ops_map.keys())) - snapshot.assert_match(sql, "out.sql") + snapshot.assert_match(sql + "\n", "out.sql") def test_astype_json(scalar_types_df: bpd.DataFrame, snapshot): diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/snapshots/test_compile_readtable/test_compile_astype_aliases/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/snapshots/test_compile_readtable/test_compile_astype_aliases/out.sql new file mode 100644 index 000000000000..cd056c650fd3 --- /dev/null +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/snapshots/test_compile_readtable/test_compile_astype_aliases/out.sql @@ -0,0 +1,5 @@ +SELECT + `rowindex`, + CAST(`timestamp_col` AS STRING) AS `timestamp_col`, + CAST(`int64_col` AS FLOAT64) AS `int64_col` +FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` AS `bft_0` diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/test_compile_readtable.py b/packages/bigframes/tests/unit/core/compile/sqlglot/test_compile_readtable.py index ea9875302a93..0f2058f21f68 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/test_compile_readtable.py +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/test_compile_readtable.py @@ -80,3 +80,15 @@ def test_compile_readtable_w_columns_filters(compiler_session, snapshot): filters=filters, ) snapshot.assert_match(bf_df.sql, "out.sql") + + +def test_compile_astype_aliases(scalar_types_df: bpd.DataFrame, snapshot): + # Test case for issue #17394 (CAST columns lose their aliases) + bf_df = scalar_types_df[["timestamp_col", "int64_col"]] + result = bf_df.astype( + { + "timestamp_col": "string[pyarrow]", + "int64_col": "Float64", + } + ) + snapshot.assert_match(result.sql + "\n", "out.sql") From 53bcd6f24a72db75ede33be86a34cc0dc0be57c1 Mon Sep 17 00:00:00 2001 From: Shuowei Li Date: Mon, 15 Jun 2026 15:48:44 +0000 Subject: [PATCH 073/174] chore: unblock release in config.yaml (#17461) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #<523413032> 🦕 --- .librarian/config.yaml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.librarian/config.yaml b/.librarian/config.yaml index af751c2626d9..919289117611 100644 --- a/.librarian/config.yaml +++ b/.librarian/config.yaml @@ -36,10 +36,5 @@ libraries: - id: "sqlalchemy-bigquery" release_blocked: true # TODO(https://github.com/googleapis/google-cloud-python/issues/17327) - - id: "google-cloud-bigquery" - release_blocked: true - # TODO(https://github.com/googleapis/google-cloud-python/issues/17327) - id: "google-cloud-bigtable" release_blocked: true - - From b50cf1aed2d5376a26c8d8e375e414e577fa27f3 Mon Sep 17 00:00:00 2001 From: Chalmer Lowe Date: Mon, 15 Jun 2026 13:16:54 -0400 Subject: [PATCH 074/174] chore(google-auth): drop python 3.7 EOL false positives and refactor metrics telemetry (#17463) This pull request eliminates EOL Python 3.7 false positives from the `google-auth` codebase to ensure a clean signal from version scanner compliance checks. **Why these changes are made:** - **Metrics Telemetry:** Hardcoded Python versions in telemetry headers (like `gl-python/3.7`) have been replaced with abstract version placeholders (``) in comments with formatting examples and in test assertions. This prevents scanner alerts while retaining the ability to verify HTTP client request formatting behavior. - **App Engine Runtime Tests:** GAE standard runtime test cases have been refactored to dynamically construct GAE runtime values from the active Python interpreter at test execution time, avoiding the need for EOL checks and manual updates when Python versions retire. - **Clean Up Transport Properties:** Replaced legacy private `_auto_decompress` internal attribute access in the `aiohttp` transport with the standard public `auto_decompress` property (supported in `aiohttp >= 3.8`), allowing the removal of old TODOs from the source code that referenced 3.7. - **Readme Cleanup**: Removed the manual, out-of-date historical "Unsupported Python Versions" list from the package documentation, relying instead on standard authoritative packaging metadata (`python_requires`) to enforce runtime compatibility. --- Supports resolution of the internal bug: #512225398 --- packages/google-auth/README.rst | 13 --- packages/google-auth/google/auth/metrics.py | 22 ++--- .../auth/transport/_aiohttp_requests.py | 3 +- .../google-auth/google/oauth2/credentials.py | 2 +- .../tests/compute_engine/test__metadata.py | 6 +- .../tests/compute_engine/test_credentials.py | 8 +- .../google-auth/tests/oauth2/test__client.py | 8 +- .../google-auth/tests/oauth2/test_reauth.py | 10 ++- packages/google-auth/tests/test__default.py | 10 ++- packages/google-auth/tests/test_aws.py | 18 ++-- .../tests/test_external_account.py | 38 ++++----- .../google-auth/tests/test_identity_pool.py | 4 +- .../tests/test_impersonated_credentials.py | 8 +- packages/google-auth/tests/test_metrics.py | 84 +++++++++++-------- .../tests_async/test__default_async.py | 10 ++- .../transport/test_aiohttp_requests.py | 11 ++- 16 files changed, 126 insertions(+), 129 deletions(-) diff --git a/packages/google-auth/README.rst b/packages/google-auth/README.rst index f160ef818979..61ea9a2302ac 100644 --- a/packages/google-auth/README.rst +++ b/packages/google-auth/README.rst @@ -37,19 +37,6 @@ Supported Python Versions ^^^^^^^^^^^^^^^^^^^^^^^^^ Python >= 3.10 -Unsupported Python Versions -^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- Python == 2.7: The last version of this library with support for Python 2.7 - was `google.auth == 1.34.0`. - -- Python 3.5: The last version of this library with support for Python 3.5 - was `google.auth == 1.23.0`. - -- Python 3.6: The last version of this library with support for Python 3.6 - was `google.auth == 2.22.0`. - -- Python 3.7: The last version of this library with support for Python 3.7 - was `google.auth == 2.45.0`. Documentation diff --git a/packages/google-auth/google/auth/metrics.py b/packages/google-auth/google/auth/metrics.py index 5511f581f658..89a15d740d7e 100644 --- a/packages/google-auth/google/auth/metrics.py +++ b/packages/google-auth/google/auth/metrics.py @@ -50,7 +50,7 @@ def python_and_auth_lib_version(): # x-goog-api-client header value for access token request via metadata server. -# Example: "gl-python/3.7 auth/1.1 auth-request-type/at cred-type/mds" +# Example: "gl-python/ auth/ auth-request-type/at cred-type/mds" def token_request_access_token_mds(): return "{} {} {}".format( python_and_auth_lib_version(), REQUEST_TYPE_ACCESS_TOKEN, CRED_TYPE_SA_MDS @@ -58,7 +58,7 @@ def token_request_access_token_mds(): # x-goog-api-client header value for ID token request via metadata server. -# Example: "gl-python/3.7 auth/1.1 auth-request-type/it cred-type/mds" +# Example: "gl-python/ auth/ auth-request-type/it cred-type/mds" def token_request_id_token_mds(): return "{} {} {}".format( python_and_auth_lib_version(), REQUEST_TYPE_ID_TOKEN, CRED_TYPE_SA_MDS @@ -66,7 +66,7 @@ def token_request_id_token_mds(): # x-goog-api-client header value for impersonated credentials access token request. -# Example: "gl-python/3.7 auth/1.1 auth-request-type/at cred-type/imp" +# Example: "gl-python/ auth/ auth-request-type/at cred-type/imp" def token_request_access_token_impersonate(): return "{} {} {}".format( python_and_auth_lib_version(), @@ -76,7 +76,7 @@ def token_request_access_token_impersonate(): # x-goog-api-client header value for impersonated credentials ID token request. -# Example: "gl-python/3.7 auth/1.1 auth-request-type/it cred-type/imp" +# Example: "gl-python/ auth/ auth-request-type/it cred-type/imp" def token_request_id_token_impersonate(): return "{} {} {}".format( python_and_auth_lib_version(), REQUEST_TYPE_ID_TOKEN, CRED_TYPE_SA_IMPERSONATE @@ -85,7 +85,7 @@ def token_request_id_token_impersonate(): # x-goog-api-client header value for service account credentials access token # request (assertion flow). -# Example: "gl-python/3.7 auth/1.1 auth-request-type/at cred-type/sa" +# Example: "gl-python/ auth/ auth-request-type/at cred-type/sa" def token_request_access_token_sa_assertion(): return "{} {} {}".format( python_and_auth_lib_version(), REQUEST_TYPE_ACCESS_TOKEN, CRED_TYPE_SA_ASSERTION @@ -94,7 +94,7 @@ def token_request_access_token_sa_assertion(): # x-goog-api-client header value for service account credentials ID token # request (assertion flow). -# Example: "gl-python/3.7 auth/1.1 auth-request-type/it cred-type/sa" +# Example: "gl-python/ auth/ auth-request-type/it cred-type/sa" def token_request_id_token_sa_assertion(): return "{} {} {}".format( python_and_auth_lib_version(), REQUEST_TYPE_ID_TOKEN, CRED_TYPE_SA_ASSERTION @@ -102,7 +102,7 @@ def token_request_id_token_sa_assertion(): # x-goog-api-client header value for user credentials token request. -# Example: "gl-python/3.7 auth/1.1 cred-type/u" +# Example: "gl-python/ auth/ cred-type/u" def token_request_user(): return "{} {}".format(python_and_auth_lib_version(), CRED_TYPE_USER) @@ -111,25 +111,25 @@ def token_request_user(): # x-goog-api-client header value for metadata server ping. -# Example: "gl-python/3.7 auth/1.1 auth-request-type/mds" +# Example: "gl-python/ auth/ auth-request-type/mds" def mds_ping(): return "{} {}".format(python_and_auth_lib_version(), REQUEST_TYPE_MDS_PING) # x-goog-api-client header value for reauth start endpoint calls. -# Example: "gl-python/3.7 auth/1.1 auth-request-type/re-start" +# Example: "gl-python/ auth/ auth-request-type/re-start" def reauth_start(): return "{} {}".format(python_and_auth_lib_version(), REQUEST_TYPE_REAUTH_START) # x-goog-api-client header value for reauth continue endpoint calls. -# Example: "gl-python/3.7 auth/1.1 cred-type/re-cont" +# Example: "gl-python/ auth/ cred-type/re-cont" def reauth_continue(): return "{} {}".format(python_and_auth_lib_version(), REQUEST_TYPE_REAUTH_CONTINUE) # x-goog-api-client header value for BYOID calls to the Security Token Service exchange token endpoint. -# Example: "gl-python/3.7 auth/1.1 google-byoid-sdk source/aws sa-impersonation/true sa-impersonation/true" +# Example: "gl-python/ auth/ google-byoid-sdk source/aws sa-impersonation/true sa-impersonation/true" def byoid_metrics_header(metrics_options): header = "{} {}".format(python_and_auth_lib_version(), BYOID_HEADER_SECTION) for key, value in metrics_options.items(): diff --git a/packages/google-auth/google/auth/transport/_aiohttp_requests.py b/packages/google-auth/google/auth/transport/_aiohttp_requests.py index e8321965e0db..470647b0690a 100644 --- a/packages/google-auth/google/auth/transport/_aiohttp_requests.py +++ b/packages/google-auth/google/auth/transport/_aiohttp_requests.py @@ -143,8 +143,7 @@ class Request(transport.Request): """ def __init__(self, session=None): - # TODO: Use auto_decompress property for aiohttp 3.7+ - if session is not None and session._auto_decompress: + if session is not None and getattr(session, "auto_decompress", None) is True: raise exceptions.InvalidOperation( "Client sessions with auto_decompress=True are not supported." ) diff --git a/packages/google-auth/google/oauth2/credentials.py b/packages/google-auth/google/oauth2/credentials.py index 724cf98bcad2..5edea697bfdc 100644 --- a/packages/google-auth/google/oauth2/credentials.py +++ b/packages/google-auth/google/oauth2/credentials.py @@ -167,7 +167,7 @@ def __init__( def __getstate__(self): """A __getstate__ method must exist for the __setstate__ to be called This is identical to the default implementation. - See https://docs.python.org/3.7/library/pickle.html#object.__setstate__ + See https://docs.python.org/3/library/pickle.html#object.__setstate__ """ state_dict = self.__dict__.copy() # Remove _refresh_handler function as there are limitations pickling and diff --git a/packages/google-auth/tests/compute_engine/test__metadata.py b/packages/google-auth/tests/compute_engine/test__metadata.py index b27e7f7f4fb5..199683f7b8c2 100644 --- a/packages/google-auth/tests/compute_engine/test__metadata.py +++ b/packages/google-auth/tests/compute_engine/test__metadata.py @@ -63,10 +63,10 @@ b"-----END CERTIFICATE-----\n" ) -ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE = ( - "gl-python/3.7 auth/1.1 auth-request-type/at cred-type/mds" +ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE = "gl-python/ auth/ auth-request-type/at cred-type/mds" +MDS_PING_METRICS_HEADER_VALUE = ( + "gl-python/ auth/ auth-request-type/mds" ) -MDS_PING_METRICS_HEADER_VALUE = "gl-python/3.7 auth/1.1 auth-request-type/mds" MDS_PING_REQUEST_HEADER = { "metadata-flavor": "Google", "x-goog-api-client": MDS_PING_METRICS_HEADER_VALUE, diff --git a/packages/google-auth/tests/compute_engine/test_credentials.py b/packages/google-auth/tests/compute_engine/test_credentials.py index 7fb2b8b504fc..de37656dcee3 100644 --- a/packages/google-auth/tests/compute_engine/test_credentials.py +++ b/packages/google-auth/tests/compute_engine/test_credentials.py @@ -43,12 +43,8 @@ b"bsxbLa6Fp0SYeYwO8ifEnkRvasVpc1WTQqfRB2JCj5pTBDzJpIpFCMmnQ" ) -ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE = ( - "gl-python/3.7 auth/1.1 auth-request-type/at cred-type/mds" -) -ID_TOKEN_REQUEST_METRICS_HEADER_VALUE = ( - "gl-python/3.7 auth/1.1 auth-request-type/it cred-type/mds" -) +ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE = "gl-python/ auth/ auth-request-type/at cred-type/mds" +ID_TOKEN_REQUEST_METRICS_HEADER_VALUE = "gl-python/ auth/ auth-request-type/it cred-type/mds" FAKE_SERVICE_ACCOUNT_EMAIL = "foo@bar.com" FAKE_QUOTA_PROJECT_ID = "fake-quota-project" FAKE_SCOPES = ["scope1", "scope2"] diff --git a/packages/google-auth/tests/oauth2/test__client.py b/packages/google-auth/tests/oauth2/test__client.py index b20a8042d5f5..0d17b3317856 100644 --- a/packages/google-auth/tests/oauth2/test__client.py +++ b/packages/google-auth/tests/oauth2/test__client.py @@ -46,12 +46,8 @@ " https://www.googleapis.com/auth/logging.write" ) -ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE = ( - "gl-python/3.7 auth/1.1 auth-request-type/at cred-type/sa" -) -ID_TOKEN_REQUEST_METRICS_HEADER_VALUE = ( - "gl-python/3.7 auth/1.1 auth-request-type/it cred-type/sa" -) +ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE = "gl-python/ auth/ auth-request-type/at cred-type/sa" +ID_TOKEN_REQUEST_METRICS_HEADER_VALUE = "gl-python/ auth/ auth-request-type/it cred-type/sa" @pytest.mark.parametrize("retryable", [True, False]) diff --git a/packages/google-auth/tests/oauth2/test_reauth.py b/packages/google-auth/tests/oauth2/test_reauth.py index ef19e4c8492c..0949def39528 100644 --- a/packages/google-auth/tests/oauth2/test_reauth.py +++ b/packages/google-auth/tests/oauth2/test_reauth.py @@ -40,11 +40,15 @@ "encodedProofOfReauthToken": "new_rapt_token", } -REAUTH_START_METRICS_HEADER_VALUE = "gl-python/3.7 auth/1.1 auth-request-type/re-start" +REAUTH_START_METRICS_HEADER_VALUE = ( + "gl-python/ auth/ auth-request-type/re-start" +) REAUTH_CONTINUE_METRICS_HEADER_VALUE = ( - "gl-python/3.7 auth/1.1 auth-request-type/re-cont" + "gl-python/ auth/ auth-request-type/re-cont" +) +TOKEN_REQUEST_METRICS_HEADER_VALUE = ( + "gl-python/ auth/ cred-type/u" ) -TOKEN_REQUEST_METRICS_HEADER_VALUE = "gl-python/3.7 auth/1.1 cred-type/u" class MockChallenge(object): diff --git a/packages/google-auth/tests/test__default.py b/packages/google-auth/tests/test__default.py index 9690377cc624..fa2de3b9084e 100644 --- a/packages/google-auth/tests/test__default.py +++ b/packages/google-auth/tests/test__default.py @@ -14,6 +14,7 @@ import json import os +import sys from unittest import mock import warnings @@ -773,7 +774,9 @@ def test__get_gae_credentials_gen1(app_identity): @mock.patch.dict(os.environ) def test__get_gae_credentials_gen2(): - os.environ["GAE_RUNTIME"] = "python37" + os.environ[ + "GAE_RUNTIME" + ] = f"python{sys.version_info.major}{sys.version_info.minor}" credentials, project_id = _default._get_gae_credentials() assert credentials is None assert project_id is None @@ -783,8 +786,9 @@ def test__get_gae_credentials_gen2(): def test__get_gae_credentials_gen2_backwards_compat(): # compat helpers may copy GAE_RUNTIME to APPENGINE_RUNTIME # for backwards compatibility with code that relies on it - os.environ[environment_vars.LEGACY_APPENGINE_RUNTIME] = "python37" - os.environ["GAE_RUNTIME"] = "python37" + current_runtime = f"python{sys.version_info.major}{sys.version_info.minor}" + os.environ[environment_vars.LEGACY_APPENGINE_RUNTIME] = current_runtime + os.environ["GAE_RUNTIME"] = current_runtime credentials, project_id = _default._get_gae_credentials() assert credentials is None assert project_id is None diff --git a/packages/google-auth/tests/test_aws.py b/packages/google-auth/tests/test_aws.py index b6b1ca2319ed..ce578af7b871 100644 --- a/packages/google-auth/tests/test_aws.py +++ b/packages/google-auth/tests/test_aws.py @@ -28,11 +28,9 @@ from google.auth import transport from google.auth.credentials import DEFAULT_UNIVERSE_DOMAIN -IMPERSONATE_ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE = ( - "gl-python/3.7 auth/1.1 auth-request-type/at cred-type/imp" -) +IMPERSONATE_ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE = "gl-python/ auth/ auth-request-type/at cred-type/imp" -LANG_LIBRARY_METRICS_HEADER_VALUE = "gl-python/3.7 auth/1.1" +LANG_LIBRARY_METRICS_HEADER_VALUE = "gl-python/ auth/" CLIENT_ID = "username" CLIENT_SECRET = "password" @@ -1913,7 +1911,7 @@ def test_refresh_success_without_impersonation_ignore_default_scopes( token_headers = { "Content-Type": "application/x-www-form-urlencoded", "Authorization": "Basic " + BASIC_AUTH_ENCODING, - "x-goog-api-client": "gl-python/3.7 auth/1.1 google-byoid-sdk sa-impersonation/false config-lifetime/false source/aws", + "x-goog-api-client": "gl-python/ auth/ google-byoid-sdk sa-impersonation/false config-lifetime/false source/aws", } token_request_data = { "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", @@ -1972,7 +1970,7 @@ def test_refresh_success_without_impersonation_use_default_scopes( token_headers = { "Content-Type": "application/x-www-form-urlencoded", "Authorization": "Basic " + BASIC_AUTH_ENCODING, - "x-goog-api-client": "gl-python/3.7 auth/1.1 google-byoid-sdk sa-impersonation/false config-lifetime/false source/aws", + "x-goog-api-client": "gl-python/ auth/ google-byoid-sdk sa-impersonation/false config-lifetime/false source/aws", } token_request_data = { "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", @@ -2038,7 +2036,7 @@ def test_refresh_success_with_impersonation_ignore_default_scopes( token_headers = { "Content-Type": "application/x-www-form-urlencoded", "Authorization": "Basic " + BASIC_AUTH_ENCODING, - "x-goog-api-client": "gl-python/3.7 auth/1.1 google-byoid-sdk sa-impersonation/true config-lifetime/false source/aws", + "x-goog-api-client": "gl-python/ auth/ google-byoid-sdk sa-impersonation/true config-lifetime/false source/aws", } token_request_data = { "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", @@ -2133,7 +2131,7 @@ def test_refresh_success_with_impersonation_use_default_scopes( token_headers = { "Content-Type": "application/x-www-form-urlencoded", "Authorization": "Basic " + BASIC_AUTH_ENCODING, - "x-goog-api-client": "gl-python/3.7 auth/1.1 google-byoid-sdk sa-impersonation/true config-lifetime/false source/aws", + "x-goog-api-client": "gl-python/ auth/ google-byoid-sdk sa-impersonation/true config-lifetime/false source/aws", } token_request_data = { "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", @@ -2328,7 +2326,7 @@ def test_refresh_success_with_supplier_with_impersonation( token_headers = { "Content-Type": "application/x-www-form-urlencoded", "Authorization": "Basic " + BASIC_AUTH_ENCODING, - "x-goog-api-client": "gl-python/3.7 auth/1.1 google-byoid-sdk sa-impersonation/true config-lifetime/false source/programmatic", + "x-goog-api-client": "gl-python/ auth/ google-byoid-sdk sa-impersonation/true config-lifetime/false source/programmatic", } token_request_data = { "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", @@ -2414,7 +2412,7 @@ def test_refresh_success_with_supplier(self, utcnow, mock_auth_lib_value): token_headers = { "Content-Type": "application/x-www-form-urlencoded", "Authorization": "Basic " + BASIC_AUTH_ENCODING, - "x-goog-api-client": "gl-python/3.7 auth/1.1 google-byoid-sdk sa-impersonation/false config-lifetime/false source/programmatic", + "x-goog-api-client": "gl-python/ auth/ google-byoid-sdk sa-impersonation/false config-lifetime/false source/programmatic", } token_request_data = { "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", diff --git a/packages/google-auth/tests/test_external_account.py b/packages/google-auth/tests/test_external_account.py index 870b07d47b6e..77d4ff0b327a 100644 --- a/packages/google-auth/tests/test_external_account.py +++ b/packages/google-auth/tests/test_external_account.py @@ -27,10 +27,8 @@ from google.auth.credentials import DEFAULT_UNIVERSE_DOMAIN from google.auth.credentials import TokenState -IMPERSONATE_ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE = ( - "gl-python/3.7 auth/1.1 auth-request-type/at cred-type/imp" -) -LANG_LIBRARY_METRICS_HEADER_VALUE = "gl-python/3.7 auth/1.1" +IMPERSONATE_ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE = "gl-python/ auth/ auth-request-type/at cred-type/imp" +LANG_LIBRARY_METRICS_HEADER_VALUE = "gl-python/ auth/" CLIENT_ID = "username" CLIENT_SECRET = "password" @@ -686,7 +684,7 @@ def test_refresh_without_client_auth_success( ) headers = { "Content-Type": "application/x-www-form-urlencoded", - "x-goog-api-client": "gl-python/3.7 auth/1.1 google-byoid-sdk sa-impersonation/false config-lifetime/false", + "x-goog-api-client": "gl-python/ auth/ google-byoid-sdk sa-impersonation/false config-lifetime/false", } request_data = { "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", @@ -751,7 +749,7 @@ def test_refresh_with_mtls( ) headers = { "Content-Type": "application/x-www-form-urlencoded", - "x-goog-api-client": "gl-python/3.7 auth/1.1 google-byoid-sdk sa-impersonation/false config-lifetime/false", + "x-goog-api-client": "gl-python/ auth/ google-byoid-sdk sa-impersonation/false config-lifetime/false", } request_data = { "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", @@ -790,7 +788,7 @@ def test_refresh_workforce_without_client_auth_success( ) headers = { "Content-Type": "application/x-www-form-urlencoded", - "x-goog-api-client": "gl-python/3.7 auth/1.1 google-byoid-sdk sa-impersonation/false config-lifetime/false", + "x-goog-api-client": "gl-python/ auth/ google-byoid-sdk sa-impersonation/false config-lifetime/false", } request_data = { "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", @@ -832,7 +830,7 @@ def test_refresh_workforce_with_client_auth_success( headers = { "Content-Type": "application/x-www-form-urlencoded", "Authorization": "Basic {}".format(BASIC_AUTH_ENCODING), - "x-goog-api-client": "gl-python/3.7 auth/1.1 google-byoid-sdk sa-impersonation/false config-lifetime/false", + "x-goog-api-client": "gl-python/ auth/ google-byoid-sdk sa-impersonation/false config-lifetime/false", } request_data = { "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", @@ -874,7 +872,7 @@ def test_refresh_workforce_with_client_auth_and_no_workforce_project_success( headers = { "Content-Type": "application/x-www-form-urlencoded", "Authorization": "Basic {}".format(BASIC_AUTH_ENCODING), - "x-goog-api-client": "gl-python/3.7 auth/1.1 google-byoid-sdk sa-impersonation/false config-lifetime/false", + "x-goog-api-client": "gl-python/ auth/ google-byoid-sdk sa-impersonation/false config-lifetime/false", } request_data = { "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", @@ -919,7 +917,7 @@ def test_refresh_impersonation_without_client_auth_success( token_response = self.SUCCESS_RESPONSE.copy() token_headers = { "Content-Type": "application/x-www-form-urlencoded", - "x-goog-api-client": "gl-python/3.7 auth/1.1 google-byoid-sdk sa-impersonation/true config-lifetime/false", + "x-goog-api-client": "gl-python/ auth/ google-byoid-sdk sa-impersonation/true config-lifetime/false", } token_request_data = { "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", @@ -1059,7 +1057,7 @@ def test_refresh_impersonation_with_mtls_success( token_response = self.SUCCESS_RESPONSE.copy() token_headers = { "Content-Type": "application/x-www-form-urlencoded", - "x-goog-api-client": "gl-python/3.7 auth/1.1 google-byoid-sdk sa-impersonation/true config-lifetime/false", + "x-goog-api-client": "gl-python/ auth/ google-byoid-sdk sa-impersonation/true config-lifetime/false", } token_request_data = { "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", @@ -1142,7 +1140,7 @@ def test_refresh_workforce_impersonation_without_client_auth_success( token_response = self.SUCCESS_RESPONSE.copy() token_headers = { "Content-Type": "application/x-www-form-urlencoded", - "x-goog-api-client": "gl-python/3.7 auth/1.1 google-byoid-sdk sa-impersonation/true config-lifetime/false", + "x-goog-api-client": "gl-python/ auth/ google-byoid-sdk sa-impersonation/true config-lifetime/false", } token_request_data = { "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", @@ -1213,7 +1211,7 @@ def test_refresh_without_client_auth_success_explicit_user_scopes_ignore_default ): headers = { "Content-Type": "application/x-www-form-urlencoded", - "x-goog-api-client": "gl-python/3.7 auth/1.1 google-byoid-sdk sa-impersonation/false config-lifetime/false", + "x-goog-api-client": "gl-python/ auth/ google-byoid-sdk sa-impersonation/false config-lifetime/false", } request_data = { "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", @@ -1250,7 +1248,7 @@ def test_refresh_without_client_auth_success_explicit_default_scopes_only( ): headers = { "Content-Type": "application/x-www-form-urlencoded", - "x-goog-api-client": "gl-python/3.7 auth/1.1 google-byoid-sdk sa-impersonation/false config-lifetime/false", + "x-goog-api-client": "gl-python/ auth/ google-byoid-sdk sa-impersonation/false config-lifetime/false", } request_data = { "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", @@ -1349,7 +1347,7 @@ def test_refresh_with_client_auth_success(self, mock_auth_lib_value): headers = { "Content-Type": "application/x-www-form-urlencoded", "Authorization": "Basic {}".format(BASIC_AUTH_ENCODING), - "x-goog-api-client": "gl-python/3.7 auth/1.1 google-byoid-sdk sa-impersonation/false config-lifetime/false", + "x-goog-api-client": "gl-python/ auth/ google-byoid-sdk sa-impersonation/false config-lifetime/false", } request_data = { "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", @@ -1393,7 +1391,7 @@ def test_refresh_impersonation_with_client_auth_success_ignore_default_scopes( token_headers = { "Content-Type": "application/x-www-form-urlencoded", "Authorization": "Basic {}".format(BASIC_AUTH_ENCODING), - "x-goog-api-client": "gl-python/3.7 auth/1.1 google-byoid-sdk sa-impersonation/true config-lifetime/false", + "x-goog-api-client": "gl-python/ auth/ google-byoid-sdk sa-impersonation/true config-lifetime/false", } token_request_data = { "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", @@ -1476,7 +1474,7 @@ def test_refresh_impersonation_with_client_auth_success_use_default_scopes( token_headers = { "Content-Type": "application/x-www-form-urlencoded", "Authorization": "Basic {}".format(BASIC_AUTH_ENCODING), - "x-goog-api-client": "gl-python/3.7 auth/1.1 google-byoid-sdk sa-impersonation/true config-lifetime/false", + "x-goog-api-client": "gl-python/ auth/ google-byoid-sdk sa-impersonation/true config-lifetime/false", } token_request_data = { "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", @@ -1967,7 +1965,7 @@ def test_get_project_id_cloud_resource_manager_success( token_response = self.SUCCESS_RESPONSE.copy() token_headers = { "Content-Type": "application/x-www-form-urlencoded", - "x-goog-api-client": "gl-python/3.7 auth/1.1 google-byoid-sdk sa-impersonation/true config-lifetime/false", + "x-goog-api-client": "gl-python/ auth/ google-byoid-sdk sa-impersonation/true config-lifetime/false", } token_request_data = { "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", @@ -2064,7 +2062,7 @@ def test_workforce_pool_get_project_id_cloud_resource_manager_success( # STS token exchange request/response. token_headers = { "Content-Type": "application/x-www-form-urlencoded", - "x-goog-api-client": "gl-python/3.7 auth/1.1 google-byoid-sdk sa-impersonation/false config-lifetime/false", + "x-goog-api-client": "gl-python/ auth/ google-byoid-sdk sa-impersonation/false config-lifetime/false", } token_request_data = { "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", @@ -2145,7 +2143,7 @@ def test_refresh_impersonation_with_lifetime( token_response = self.SUCCESS_RESPONSE.copy() token_headers = { "Content-Type": "application/x-www-form-urlencoded", - "x-goog-api-client": "gl-python/3.7 auth/1.1 google-byoid-sdk sa-impersonation/true config-lifetime/true", + "x-goog-api-client": "gl-python/ auth/ google-byoid-sdk sa-impersonation/true config-lifetime/true", } token_request_data = { "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", diff --git a/packages/google-auth/tests/test_identity_pool.py b/packages/google-auth/tests/test_identity_pool.py index c68fac64708d..18e5ca9abd62 100644 --- a/packages/google-auth/tests/test_identity_pool.py +++ b/packages/google-auth/tests/test_identity_pool.py @@ -368,9 +368,7 @@ def assert_underlying_credentials_refresh( json.dumps({"userProject": workforce_pool_user_project}) ) - metrics_header_value = ( - "gl-python/3.7 auth/1.1 auth-request-type/at cred-type/imp" - ) + metrics_header_value = "gl-python/ auth/ auth-request-type/at cred-type/imp" if service_account_impersonation_url: # Service account impersonation request/response. expire_time = ( diff --git a/packages/google-auth/tests/test_impersonated_credentials.py b/packages/google-auth/tests/test_impersonated_credentials.py index f937e871cdf9..1207ed874b31 100644 --- a/packages/google-auth/tests/test_impersonated_credentials.py +++ b/packages/google-auth/tests/test_impersonated_credentials.py @@ -59,12 +59,8 @@ SIGNER = crypt.RSASigner.from_string(PRIVATE_KEY_BYTES, "1") TOKEN_URI = "https://example.com/oauth2/token" -ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE = ( - "gl-python/3.7 auth/1.1 auth-request-type/at cred-type/imp" -) -ID_TOKEN_REQUEST_METRICS_HEADER_VALUE = ( - "gl-python/3.7 auth/1.1 auth-request-type/it cred-type/imp" -) +ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE = "gl-python/ auth/ auth-request-type/at cred-type/imp" +ID_TOKEN_REQUEST_METRICS_HEADER_VALUE = "gl-python/ auth/ auth-request-type/it cred-type/imp" @pytest.fixture diff --git a/packages/google-auth/tests/test_metrics.py b/packages/google-auth/tests/test_metrics.py index c2e4014a06c7..dc8789b2fe34 100644 --- a/packages/google-auth/tests/test_metrics.py +++ b/packages/google-auth/tests/test_metrics.py @@ -15,6 +15,8 @@ import platform from unittest import mock +import pytest + from google.auth import metrics from google.auth import version @@ -33,63 +35,71 @@ def test_add_metric_header(): assert headers == {"x-goog-api-client": "bar"} -@mock.patch.object(platform, "python_version", return_value="3.7") +@mock.patch.object(platform, "python_version", return_value="") def test_versions(mock_python_version): version_save = version.__version__ - version.__version__ = "1.1" - assert metrics.python_and_auth_lib_version() == "gl-python/3.7 auth/1.1" + version.__version__ = "" + assert ( + metrics.python_and_auth_lib_version() + == "gl-python/ auth/" + ) version.__version__ = version_save +@pytest.mark.parametrize( + "func, expected_suffix", + [ + (metrics.token_request_access_token_mds, "auth-request-type/at cred-type/mds"), + (metrics.token_request_id_token_mds, "auth-request-type/it cred-type/mds"), + ( + metrics.token_request_access_token_impersonate, + "auth-request-type/at cred-type/imp", + ), + ( + metrics.token_request_id_token_impersonate, + "auth-request-type/it cred-type/imp", + ), + ( + metrics.token_request_access_token_sa_assertion, + "auth-request-type/at cred-type/sa", + ), + ( + metrics.token_request_id_token_sa_assertion, + "auth-request-type/it cred-type/sa", + ), + (metrics.token_request_user, "cred-type/u"), + (metrics.mds_ping, "auth-request-type/mds"), + (metrics.reauth_start, "auth-request-type/re-start"), + (metrics.reauth_continue, "auth-request-type/re-cont"), + ], +) @mock.patch( "google.auth.metrics.python_and_auth_lib_version", - return_value="gl-python/3.7 auth/1.1", + return_value="gl-python/ auth/", ) -def test_metric_values(mock_python_and_auth_lib_version): - assert ( - metrics.token_request_access_token_mds() - == "gl-python/3.7 auth/1.1 auth-request-type/at cred-type/mds" - ) - assert ( - metrics.token_request_id_token_mds() - == "gl-python/3.7 auth/1.1 auth-request-type/it cred-type/mds" - ) - assert ( - metrics.token_request_access_token_impersonate() - == "gl-python/3.7 auth/1.1 auth-request-type/at cred-type/imp" - ) - assert ( - metrics.token_request_id_token_impersonate() - == "gl-python/3.7 auth/1.1 auth-request-type/it cred-type/imp" - ) - assert ( - metrics.token_request_access_token_sa_assertion() - == "gl-python/3.7 auth/1.1 auth-request-type/at cred-type/sa" - ) - assert ( - metrics.token_request_id_token_sa_assertion() - == "gl-python/3.7 auth/1.1 auth-request-type/it cred-type/sa" - ) - assert metrics.token_request_user() == "gl-python/3.7 auth/1.1 cred-type/u" - assert metrics.mds_ping() == "gl-python/3.7 auth/1.1 auth-request-type/mds" - assert metrics.reauth_start() == "gl-python/3.7 auth/1.1 auth-request-type/re-start" - assert ( - metrics.reauth_continue() == "gl-python/3.7 auth/1.1 auth-request-type/re-cont" +def test_metric_values(mock_python_and_auth_lib_version, func, expected_suffix): + # mock_python_and_auth_lib_version is injected by mock.patch but is not + # explicitly referenced in the test body as the mock behaves as configured. + expected = ( + f"gl-python/ auth/ {expected_suffix}".strip() ) + assert func() == expected @mock.patch( "google.auth.metrics.python_and_auth_lib_version", - return_value="gl-python/3.7 auth/1.1", + return_value="gl-python/ auth/", ) def test_byoid_metric_header(mock_python_and_auth_lib_version): + # mock_python_and_auth_lib_version is injected by mock.patch but is not + # explicitly referenced in the test body as the mock behaves as configured. metrics_options = {} assert ( metrics.byoid_metrics_header(metrics_options) - == "gl-python/3.7 auth/1.1 google-byoid-sdk" + == "gl-python/ auth/ google-byoid-sdk" ) metrics_options["testKey"] = "testValue" assert ( metrics.byoid_metrics_header(metrics_options) - == "gl-python/3.7 auth/1.1 google-byoid-sdk testKey/testValue" + == "gl-python/ auth/ google-byoid-sdk testKey/testValue" ) diff --git a/packages/google-auth/tests_async/test__default_async.py b/packages/google-auth/tests_async/test__default_async.py index a1268bdc05db..ebdd2c1b0184 100644 --- a/packages/google-auth/tests_async/test__default_async.py +++ b/packages/google-auth/tests_async/test__default_async.py @@ -14,6 +14,7 @@ import json import os +import sys from unittest import mock import pytest # type: ignore @@ -306,7 +307,9 @@ def test__get_gae_credentials_gen1(app_identity): @mock.patch.dict(os.environ) def test__get_gae_credentials_gen2(): - os.environ["GAE_RUNTIME"] = "python37" + os.environ[ + "GAE_RUNTIME" + ] = f"python{sys.version_info.major}{sys.version_info.minor}" credentials, project_id = _default._get_gae_credentials() assert credentials is None assert project_id is None @@ -316,8 +319,9 @@ def test__get_gae_credentials_gen2(): def test__get_gae_credentials_gen2_backwards_compat(): # compat helpers may copy GAE_RUNTIME to APPENGINE_RUNTIME # for backwards compatibility with code that relies on it - os.environ[environment_vars.LEGACY_APPENGINE_RUNTIME] = "python37" - os.environ["GAE_RUNTIME"] = "python37" + current_runtime = f"python{sys.version_info.major}{sys.version_info.minor}" + os.environ[environment_vars.LEGACY_APPENGINE_RUNTIME] = current_runtime + os.environ["GAE_RUNTIME"] = current_runtime credentials, project_id = _default._get_gae_credentials() assert credentials is None assert project_id is None diff --git a/packages/google-auth/tests_async/transport/test_aiohttp_requests.py b/packages/google-auth/tests_async/transport/test_aiohttp_requests.py index d6a24da2e302..7d1215ef71ea 100644 --- a/packages/google-auth/tests_async/transport/test_aiohttp_requests.py +++ b/packages/google-auth/tests_async/transport/test_aiohttp_requests.py @@ -121,9 +121,16 @@ async def test_unsupported_session(self): with pytest.raises(ValueError): await aiohttp_requests.Request(http) + def test_mock_session_unspecified_auto_decompress(self): + # A plain mock object (without spec) will return a mock on attribute access. + # Ensure this does not trigger InvalidOperation. + http = mock.Mock() + request = aiohttp_requests.Request(http) + assert request.session == http + def test_timeout(self): http = mock.create_autospec( - aiohttp.ClientSession, instance=True, _auto_decompress=False + aiohttp.ClientSession, instance=True, auto_decompress=False ) request = aiohttp_requests.Request(http) request(url="http://example.com", method="GET", timeout=5) @@ -153,7 +160,7 @@ async def test_constructor(self): @pytest.mark.asyncio async def test_constructor_with_auth_request(self): http = mock.create_autospec( - aiohttp.ClientSession, instance=True, _auto_decompress=False + aiohttp.ClientSession, instance=True, auto_decompress=False ) auth_request = aiohttp_requests.Request(http) From 56cbea8509c66889485b43f2d98d60210eae81bc Mon Sep 17 00:00:00 2001 From: nbayati <99771966+nbayati@users.noreply.github.com> Date: Mon, 15 Jun 2026 11:27:01 -0700 Subject: [PATCH 075/174] fix(rab): run async background boundary refresh on detached session (#17441) When AuthorizedSession.request() makes an API call, it runs inside a temporary aiohttp ClientSession block. If our background Regional Access Boundary (RAB) refresh worker naively shares this exact same session, a fast primary call (like an instant 401/403 or a quick CRM check) will exit its block and close the active socket mid-flight. This causes the background worker to silently fail with "RuntimeError: Session is closed" and forces the RAB manager into a 15-minute cooldown. This commit resolves the race condition and ensures safe connection lifecycle management: - Shifted the cloning block to run synchronously inside start_refresh, capturing a fresh, independent ClientSession before the foreground thread can close the source transport. - Added a _clone() method to async Request adapters (both modern and legacy) to copy proxy settings and trace configurations while enforcing connector limits. - Prevented resource leaks on task creation failures by capturing exceptions in start_refresh and closing the cloned session synchronously. - Refactored the close wrapper to inspect and await generic awaitables (such as asyncio.Future) returned by custom or third-party transports. - Aligned exception behaviors by raising a wrapped TransportError directly when calling a closed instance of the legacy aiohttp_requests adapter. - Ensured the cloned transport is cleanly closed in a finally block after the background lookup settles. --- .../auth/_regional_access_boundary_utils.py | 88 ++++++- .../google/auth/aio/transport/__init__.py | 10 + .../google/auth/aio/transport/aiohttp.py | 82 ++++++- .../auth/transport/_aiohttp_requests.py | 90 +++++++ .../test__regional_access_boundary_utils.py | 170 +++++++++++++ .../tests/transport/aio/test_aiohttp.py | 149 ++++++++++++ .../tests/transport/aio/test_sessions.py | 6 + .../test__regional_access_boundary_utils.py | 224 ++++++++++++++++++ .../transport/test_aiohttp_requests.py | 210 ++++++++++++++++ 9 files changed, 1025 insertions(+), 4 deletions(-) diff --git a/packages/google-auth/google/auth/_regional_access_boundary_utils.py b/packages/google-auth/google/auth/_regional_access_boundary_utils.py index c97bf8f484df..84f891082e48 100644 --- a/packages/google-auth/google/auth/_regional_access_boundary_utils.py +++ b/packages/google-auth/google/auth/_regional_access_boundary_utils.py @@ -27,7 +27,7 @@ from google.auth import _helpers from google.auth import environment_vars -if TYPE_CHECKING: +if TYPE_CHECKING: # pragma: NO COVER import google.auth.credentials import google.auth.transport @@ -455,6 +455,61 @@ def start_refresh(self, credentials, request, rab_manager): self._worker.start() +def _prepare_async_lookup_callable(request): + """Unwraps a request callable, clones the transport, and returns the new callable. + + Args: + request: The original request callable (e.g. functools.partial or raw Request). + + Returns: + Tuple[Callable, Any, bool]: A tuple containing the new lookup callable, the + underlying request object, and a boolean indicating if it was cloned. + """ + is_partial = isinstance(request, functools.partial) + base_callable = request.func if is_partial else request + + if not hasattr(base_callable, "_clone"): + return request, base_callable, False + + cloned_callable = base_callable._clone() + is_cloned = cloned_callable is not base_callable + + if is_partial: + new_request = functools.partial( + cloned_callable, *request.args, **request.keywords + ) + else: + new_request = cloned_callable + + return new_request, cloned_callable, is_cloned + + +async def _close_cloned_request(lookup_request, is_cloned): + """Safely closes the underlying cloned request transport, if applicable. + + Args: + lookup_request (Any): The request object/transport to close. + is_cloned (bool): Whether the request was actually cloned. + """ + if not is_cloned or not hasattr(lookup_request, "close"): + return + + is_async = False + try: + maybe_coro = lookup_request.close() + if is_async := inspect.isawaitable(maybe_coro): + await maybe_coro + except Exception as e: + if _helpers.is_logging_enabled(_LOGGER): + adapter_type = " asynchronous " if is_async else " " + _LOGGER.warning( + "Failed to cleanly close cloned%srequest transport: %s", + adapter_type, + e, + exc_info=True, + ) + + class _AsyncRegionalAccessBoundaryRefreshManager(object): """Manages a task for background refreshing of the Regional Access Boundary in async flows.""" @@ -491,11 +546,28 @@ def start_refresh(self, credentials, request, rab_manager): # A refresh is already in progress. return + try: + ( + lookup_callable, + lookup_request, + is_cloned, + ) = _prepare_async_lookup_callable(request) + except Exception as e: + if _helpers.is_logging_enabled(_LOGGER): + _LOGGER.warning( + "Synchronous cloning of request for Regional Access Boundary lookup failed: %s", + e, + exc_info=True, + ) + rab_manager.process_regional_access_boundary_info(None) + return + async def _worker(): try: - # credentials._lookup_regional_access_boundary should be async in the async creds class regional_access_boundary_info = ( - await credentials._lookup_regional_access_boundary(request) + await credentials._lookup_regional_access_boundary( + lookup_callable + ) ) except Exception as e: if _helpers.is_logging_enabled(_LOGGER): @@ -505,6 +577,8 @@ async def _worker(): exc_info=True, ) regional_access_boundary_info = None + finally: + await _close_cloned_request(lookup_request, is_cloned) rab_manager.process_regional_access_boundary_info( regional_access_boundary_info @@ -514,7 +588,15 @@ async def _worker(): try: self._worker_task = asyncio.create_task(coro) except Exception: + # Clean up cloned request if task creation fails coro.close() + try: + asyncio.get_running_loop().create_task( + _close_cloned_request(lookup_request, is_cloned) + ) + except RuntimeError: + pass + rab_manager.process_regional_access_boundary_info(None) raise diff --git a/packages/google-auth/google/auth/aio/transport/__init__.py b/packages/google-auth/google/auth/aio/transport/__init__.py index 166a3be50914..343711272a95 100644 --- a/packages/google-auth/google/auth/aio/transport/__init__.py +++ b/packages/google-auth/google/auth/aio/transport/__init__.py @@ -142,3 +142,13 @@ async def close(self) -> None: Close the underlying session. """ raise NotImplementedError("close must be implemented.") + + def _clone(self) -> "Request": + """Creates a copy of this request adapter. + + The base implementation returns `self` (an identical shared instance). + Transport adapters that maintain internal connection pools or stateful + sessions must override this method to return an independent, detached + adapter instance. + """ + return self diff --git a/packages/google-auth/google/auth/aio/transport/aiohttp.py b/packages/google-auth/google/auth/aio/transport/aiohttp.py index 642d15927d0f..96e71849fd19 100644 --- a/packages/google-auth/google/auth/aio/transport/aiohttp.py +++ b/packages/google-auth/google/auth/aio/transport/aiohttp.py @@ -36,7 +36,7 @@ else: try: from aiohttp import ClientTimeout - except (ImportError, AttributeError): + except (ImportError, AttributeError): # pragma: NO COVER ClientTimeout = None _LOGGER = logging.getLogger(__name__) @@ -203,3 +203,83 @@ async def close(self) -> None: if not self._closed and self._session: await self._session.close() self._closed = True + + def _clone(self) -> "Request": + """Creates an independent copy of this request adapter. + + Clones the connection settings, trace configurations, and session defaults + (headers, cookies, basic auth, and timeouts). + + Only standard `aiohttp.TCPConnector` and `aiohttp.UnixConnector` connectors + are supported. The DNS resolver is not copied to avoid closing shared resolver + resources. + + Returns: + google.auth.aio.transport.aiohttp.Request: A new request adapter. + + Raises: + google.auth.exceptions.TransportError: If the transport is closed, or if the + session uses an unsupported connector. + """ + if self._closed: + raise exceptions.TransportError("Cannot clone a closed transport.") + + if not self._session: + new_session = aiohttp.ClientSession( + auto_decompress=False, + trust_env=True, + ) + return Request(session=new_session) + + session_kwargs: dict = { + "auto_decompress": False, + "trust_env": getattr(self._session, "_trust_env", True), + } + + # Copy underlying connection pool settings (SSL context, IP bindings, limits). + orig_connector = getattr(self._session, "_connector", None) + if orig_connector and not orig_connector.closed: + if isinstance(orig_connector, aiohttp.TCPConnector): + # We explicitly do not copy the resolver. The connector + # owns the resolver, and closing the cloned session would + # close the shared resolver, breaking the original session. + session_kwargs["connector"] = aiohttp.TCPConnector( + ssl=getattr(orig_connector, "_ssl", None), # type: ignore + limit=getattr(orig_connector, "_limit", 100), + limit_per_host=getattr(orig_connector, "_limit_per_host", 0), + force_close=getattr(orig_connector, "_force_close", False), + local_addr=getattr(orig_connector, "_local_addr", None), + ) + elif getattr(aiohttp, "UnixConnector", None) and isinstance( + orig_connector, getattr(aiohttp, "UnixConnector") + ): + path = getattr(orig_connector, "_path", None) + if path: + session_kwargs["connector"] = aiohttp.UnixConnector( + path=path, + limit=getattr(orig_connector, "_limit", 100), + force_close=getattr(orig_connector, "_force_close", False), + ) + else: + raise exceptions.TransportError( + f"Unsupported connector type for cloning: {type(orig_connector)}" + ) + + # Preserve distributed tracing configurations. + trace_configs = getattr(self._session, "_trace_configs", None) + if trace_configs: + session_kwargs["trace_configs"] = list(trace_configs) + + # Copy session-level defaults (headers, cookies, auth, timeout). + for attr_name, kwarg_name in [ + ("_default_headers", "headers"), + ("_cookie_jar", "cookie_jar"), + ("_default_auth", "auth"), + ("_timeout", "timeout"), + ("_json_serialize", "json_serialize"), + ]: + val = getattr(self._session, attr_name, None) + if val is not None: + session_kwargs[kwarg_name] = val + + return Request(session=aiohttp.ClientSession(**session_kwargs)) # type: ignore diff --git a/packages/google-auth/google/auth/transport/_aiohttp_requests.py b/packages/google-auth/google/auth/transport/_aiohttp_requests.py index 470647b0690a..12a239b7daf7 100644 --- a/packages/google-auth/google/auth/transport/_aiohttp_requests.py +++ b/packages/google-auth/google/auth/transport/_aiohttp_requests.py @@ -148,6 +148,7 @@ def __init__(self, session=None): "Client sessions with auto_decompress=True are not supported." ) self.session = session + self._closed = False async def __call__( self, @@ -183,6 +184,9 @@ async def __call__( """ try: + if getattr(self, "_closed", False): + raise exceptions.TransportError("session is closed.") + if self.session is None: # pragma: NO COVER self.session = aiohttp.ClientSession( auto_decompress=False @@ -202,6 +206,92 @@ async def __call__( new_exc = exceptions.TransportError(caught_exc) raise new_exc from caught_exc + def _clone(self): + """Creates an independent copy of this request adapter. + + Clones the connection settings, trace configurations, and session defaults + (headers, cookies, basic auth, and timeouts). + + Only standard `aiohttp.TCPConnector` and `aiohttp.UnixConnector` connectors + are supported. The DNS resolver is not copied to avoid closing shared resolver + resources. + + Returns: + google.auth.transport._aiohttp_requests.Request: A new request adapter. + + Raises: + google.auth.exceptions.TransportError: If the transport is closed, or if the + session uses an unsupported connector. + """ + if getattr(self, "_closed", False): + raise exceptions.TransportError("Cannot clone a closed transport.") + + if not self.session: + new_session = aiohttp.ClientSession( + auto_decompress=False, + trust_env=True, + ) + return Request(session=new_session) + + session_kwargs: dict = { + "auto_decompress": False, + "trust_env": getattr(self.session, "_trust_env", True), + } + + # Copy underlying connection pool settings (SSL context, IP bindings, limits). + orig_connector = getattr(self.session, "_connector", None) + if orig_connector and not getattr(orig_connector, "closed", True): + if isinstance(orig_connector, aiohttp.TCPConnector): + # We explicitly do not copy the resolver. The connector + # owns the resolver, and closing the cloned session would + # close the shared resolver, breaking the original session. + session_kwargs["connector"] = aiohttp.TCPConnector( + ssl=getattr(orig_connector, "_ssl", None), # type: ignore + limit=getattr(orig_connector, "_limit", 100), + limit_per_host=getattr(orig_connector, "_limit_per_host", 0), + force_close=getattr(orig_connector, "_force_close", False), + local_addr=getattr(orig_connector, "_local_addr", None), + ) + elif getattr(aiohttp, "UnixConnector", None) and isinstance( + orig_connector, getattr(aiohttp, "UnixConnector") + ): + path = getattr(orig_connector, "_path", None) + if path: + session_kwargs["connector"] = aiohttp.UnixConnector( + path=path, + limit=getattr(orig_connector, "_limit", 100), + force_close=getattr(orig_connector, "_force_close", False), + ) + else: + raise exceptions.TransportError( + f"Unsupported connector type for cloning: {type(orig_connector)}" + ) + + # Preserve distributed tracing configurations. + trace_configs = getattr(self.session, "_trace_configs", None) + if trace_configs: + session_kwargs["trace_configs"] = list(trace_configs) + + # Copy session-level defaults (headers, cookies, auth, timeout). + for attr_name, kwarg_name in [ + ("_default_headers", "headers"), + ("_cookie_jar", "cookie_jar"), + ("_default_auth", "auth"), + ("_timeout", "timeout"), + ("_json_serialize", "json_serialize"), + ]: + val = getattr(self.session, attr_name, None) + if val is not None: + session_kwargs[kwarg_name] = val + + return Request(session=aiohttp.ClientSession(**session_kwargs)) # type: ignore + + async def close(self): + """Cleanly release the underlying aiohttp ClientSession resources.""" + if not getattr(self, "_closed", False) and self.session: + await self.session.close() + self._closed = True + class AuthorizedSession(aiohttp.ClientSession): """This is an async implementation of the Authorized Session class. We utilize an diff --git a/packages/google-auth/tests/test__regional_access_boundary_utils.py b/packages/google-auth/tests/test__regional_access_boundary_utils.py index c612b60b8ed2..1983571054ad 100644 --- a/packages/google-auth/tests/test__regional_access_boundary_utils.py +++ b/packages/google-auth/tests/test__regional_access_boundary_utils.py @@ -678,6 +678,7 @@ async def test_async_refresh_manager_session_closed_ignored(self): ) request = mock.Mock() + request._clone.return_value = request rab_manager = mock.Mock() manager = ( @@ -694,6 +695,120 @@ async def test_async_refresh_manager_session_closed_ignored(self): credentials._lookup_regional_access_boundary.assert_called_once_with(request) rab_manager.process_regional_access_boundary_info.assert_called_once_with(None) + @pytest.mark.asyncio + async def test_start_refresh_async_clones_request_and_unwraps_partial(self): + import functools + + credentials = mock.AsyncMock() + credentials._lookup_regional_access_boundary.return_value = { + "encodedLocations": "0xA30" + } + + mock_request = mock.Mock() + mock_cloned_request = mock.Mock() + mock_request._clone.return_value = mock_cloned_request + mock_cloned_request.close = mock.AsyncMock() + + # Wrap in a functools.partial to simulate AuthorizedSession.request() timeouts + partial_request = functools.partial(mock_request, timeout=180) + + rab_manager = mock.Mock() + + manager = ( + _regional_access_boundary_utils._AsyncRegionalAccessBoundaryRefreshManager() + ) + manager.start_refresh(credentials, partial_request, rab_manager) + + await manager._worker_task + + # Verify that actual_request._clone() was called + mock_request._clone.assert_called_once() + + # Verify that the lookup ran on a re-wrapped partial of the cloned request + called_arg = credentials._lookup_regional_access_boundary.call_args[0][0] + assert isinstance(called_arg, functools.partial) + assert called_arg.func is mock_cloned_request + assert called_arg.keywords == {"timeout": 180} + + # Verify that the cloned request was closed cleanly in the finally block + mock_cloned_request.close.assert_awaited_once() + rab_manager.process_regional_access_boundary_info.assert_called_once_with( + {"encodedLocations": "0xA30"} + ) + + @pytest.mark.asyncio + async def test_start_refresh_suppresses_request_clone_exception(self): + from google.auth import exceptions + + credentials = mock.AsyncMock() + + request = mock.Mock() + request._clone.side_effect = exceptions.TransportError( + "Cannot clone a closed transport." + ) + + rab_manager = mock.Mock() + manager = ( + _regional_access_boundary_utils._AsyncRegionalAccessBoundaryRefreshManager() + ) + + manager.start_refresh(credentials, request, rab_manager) + + assert manager._worker_task is None + credentials._lookup_regional_access_boundary.assert_not_called() + rab_manager.process_regional_access_boundary_info.assert_called_once_with(None) + + @pytest.mark.asyncio + async def test_start_refresh_async_mimics_ephemeral_session_closed_bug(self): + # Specifically mimics the real-world race condition where a fast foreground main call + # pulls the rug out from under the background worker when using an un-cloned session. + import asyncio + + manager = ( + _regional_access_boundary_utils._AsyncRegionalAccessBoundaryRefreshManager() + ) + + worker_started_event = asyncio.Event() + foreground_closed_event = asyncio.Event() + + class EphemeralRequest: + def __init__(self): + self.closed = False + + async def __call__(self, *args, **kwargs): + worker_started_event.set() + await foreground_closed_event.wait() + if self.closed: + raise RuntimeError("Session is closed") + return "success" + + ephemeral_req = EphemeralRequest() + + credentials = mock.AsyncMock() + + async def mock_lookup(req): + return await req() + + credentials._lookup_regional_access_boundary.side_effect = mock_lookup + + rab_manager = mock.Mock() + + # Start the background refresh worker + manager.start_refresh(credentials, ephemeral_req, rab_manager) + + # Wait until the background worker has actually started its speculative request + await worker_started_event.wait() + + # Simulate fast foreground primary call closing the session + ephemeral_req.closed = True + foreground_closed_event.set() + + # Await the background worker task to settle + await manager._worker_task + + # Verify that the background worker hit the "Session is closed" error and failed open cleanly + rab_manager.process_regional_access_boundary_info.assert_called_once_with(None) + def test_get_service_account_rab_endpoint(monkeypatch): from google.auth.transport import _mtls_helper @@ -761,3 +876,58 @@ def test_get_workload_identity_pool_rab_endpoint(monkeypatch): url == "https://iamcredentials.mtls.googleapis.com/v1/projects/PROJECT_NUM/locations/global/workloadIdentityPools/POOL_ID/allowedLocations" ) + + +def test_sync_refresh_manager_pickle(): + import pickle + + manager = _regional_access_boundary_utils._RegionalAccessBoundaryRefreshManager() + manager._worker = mock.Mock() + + dumped = pickle.dumps(manager) + loaded = pickle.loads(dumped) + + assert loaded._lock is not None + assert loaded._worker is None + + +def test_manager_eq_different_type(): + manager = _regional_access_boundary_utils._RegionalAccessBoundaryManager() + assert manager != "not a manager" + + +def test_set_initial_regional_access_boundary_empty(): + manager = _regional_access_boundary_utils._RegionalAccessBoundaryManager() + manager.set_initial_regional_access_boundary( + encoded_locations="", expiry=datetime.datetime.now() + ) + assert manager._data.encoded_locations == "" + assert manager._data.expiry is None + + +def test_set_initial_regional_access_boundary_with_value(): + manager = _regional_access_boundary_utils._RegionalAccessBoundaryManager() + expiry = datetime.datetime.now() + manager.set_initial_regional_access_boundary( + encoded_locations="us-east1", expiry=expiry + ) + assert manager._data.encoded_locations == "us-east1" + assert manager._data.expiry == expiry + + +def test_sync_refresh_manager_start_refresh_executes(): + manager = _regional_access_boundary_utils._RegionalAccessBoundaryRefreshManager() + creds = mock.Mock() + request = mock.Mock() + rab_manager = mock.Mock() + + with mock.patch( + "google.auth._regional_access_boundary_utils._RegionalAccessBoundaryRefreshThread" + ) as mock_thread_class: + mock_thread = mock.Mock() + mock_thread_class.return_value = mock_thread + + manager.start_refresh(creds, request, rab_manager) + + mock_thread_class.assert_called_once() + mock_thread.start.assert_called_once() diff --git a/packages/google-auth/tests/transport/aio/test_aiohttp.py b/packages/google-auth/tests/transport/aio/test_aiohttp.py index 553f35775fac..68acac6f7619 100644 --- a/packages/google-auth/tests/transport/aio/test_aiohttp.py +++ b/packages/google-auth/tests/transport/aio/test_aiohttp.py @@ -169,3 +169,152 @@ async def test_request_call_raises_transport_error_for_closed_session( exc.match("session is closed.") aiohttp_request._closed = False + + async def test_request_clone(self): + request = auth_aiohttp.Request() + cloned = request._clone() + assert cloned is not request + assert isinstance(cloned, auth_aiohttp.Request) + assert cloned._session is not request._session + await request.close() + await cloned.close() + + async def test_request_close(self): + request = auth_aiohttp.Request() + assert not getattr(request, "_closed", False) + await request.close() + assert request._closed + # Second call should be idempotent + await request.close() + assert request._closed + + async def test_request_clone_closed_session_raises(self): + request = auth_aiohttp.Request() + await request.close() + with pytest.raises(exceptions.TransportError) as exc: + request._clone() + exc.match("Cannot clone a closed transport.") + + async def test_request_clone_with_active_session(self): + import ssl + from aiohttp import BasicAuth, ClientTimeout, TCPConnector + + custom_ssl = ssl.create_default_context() + custom_connector = TCPConnector( + ssl=custom_ssl, + limit=42, + limit_per_host=12, + force_close=True, + local_addr=("127.0.0.2", 0), + ) + + mock_session = aiohttp.ClientSession( + connector=custom_connector, + headers={"x-corporate-firewall": "open"}, + cookies={"enterprise_session": "active"}, + auth=BasicAuth("admin", "secret"), + timeout=ClientTimeout(total=84.0), + trust_env=True, + trace_configs=[aiohttp.TraceConfig()], + ) + request = auth_aiohttp.Request(session=mock_session) + + cloned = request._clone() + + assert cloned is not request + assert cloned._session is not mock_session + assert cloned._session is not None + + # Verify underlying TCPConnector configuration + cloned_connector = cloned._session._connector + assert isinstance(cloned_connector, TCPConnector) + assert cloned_connector is not custom_connector + assert cloned_connector._resolver is not custom_connector._resolver + assert cloned_connector._ssl is custom_ssl + assert cloned_connector._limit == 42 + assert cloned_connector._limit_per_host == 12 + assert cloned_connector._force_close is True + assert cloned_connector._local_addr == ("127.0.0.2", 0) + + # Verify session-level configuration + assert cloned._session._trust_env is True + assert len(cloned._session._trace_configs) == 1 + assert cloned._session._default_headers == {"x-corporate-firewall": "open"} + assert cloned._session._cookie_jar is mock_session._cookie_jar + assert cloned._session._default_auth == mock_session._default_auth + assert cloned._session._timeout == ClientTimeout(total=84.0) + + await request.close() + await cloned.close() + + async def test_request_clone_unix_socket(self): + try: + from aiohttp import UnixConnector + except ImportError: + return # Windows or environment without Unix Domain Sockets + + connector = UnixConnector(path="/var/run/enterprise.sock", limit=42) + mock_session = aiohttp.ClientSession(connector=connector) + request = auth_aiohttp.Request(session=mock_session) + + cloned = request._clone() + + assert cloned._session is not None + cloned_connector = cloned._session._connector + assert isinstance(cloned_connector, UnixConnector) + assert cloned_connector._path == "/var/run/enterprise.sock" + assert cloned_connector._limit == 42 + + await request.close() + await cloned.close() + + async def test_request_call_raises_timeout_error_int(self, aiohttp_request): + with aioresponses() as m: + m.get("http://example.com", exception=asyncio.TimeoutError) + with pytest.raises(exceptions.TimeoutError) as exc: + await aiohttp_request("http://example.com", timeout=120) + exc.match("Request timed out after 120 seconds.") + + async def test_request_clone_with_closed_connector(self): + session = aiohttp.ClientSession() + request = auth_aiohttp.Request(session=session) + await session.close() + + cloned = request._clone() + assert cloned is not request + assert cloned._session is not None + await request.close() + await cloned.close() + + async def test_request_clone_with_custom_connector(self): + session = aiohttp.ClientSession() + custom_connector = AsyncMock() + custom_connector.closed = False + custom_connector.close = AsyncMock() + session._connector = custom_connector + + request = auth_aiohttp.Request(session=session) + with pytest.raises( + exceptions.TransportError, match="Unsupported connector type for cloning" + ): + request._clone() + await request.close() + + async def test_request_clone_unix_socket_no_path(self): + try: + from aiohttp import UnixConnector + except ImportError: + return + + session = aiohttp.ClientSession() + connector = UnixConnector(path="/tmp/test.sock") + connector._path = None + session._connector = connector + + request = auth_aiohttp.Request(session=session) + cloned = request._clone() + assert cloned is not request + assert cloned._session is not None + assert cloned._session._connector is not connector + await request.close() + await cloned.close() diff --git a/packages/google-auth/tests/transport/aio/test_sessions.py b/packages/google-auth/tests/transport/aio/test_sessions.py index 9780b8e2a1d2..58643c653ca2 100644 --- a/packages/google-auth/tests/transport/aio/test_sessions.py +++ b/packages/google-auth/tests/transport/aio/test_sessions.py @@ -334,3 +334,9 @@ async def test_http_delete_method_success(self): response = await authed_session.delete(self.TEST_URL) assert await response.read() == expected_payload response = await authed_session.close() + + +def test_mock_request_clone(): + request = MockRequest() + cloned = request._clone() + assert cloned is request diff --git a/packages/google-auth/tests_async/test__regional_access_boundary_utils.py b/packages/google-auth/tests_async/test__regional_access_boundary_utils.py index 268ee37261c8..dd8a9eae2d8a 100644 --- a/packages/google-auth/tests_async/test__regional_access_boundary_utils.py +++ b/packages/google-auth/tests_async/test__regional_access_boundary_utils.py @@ -28,6 +28,7 @@ async def test_async_refresh_manager_start_refresh(): } request = mock.Mock() + request._clone.return_value = request rab_manager = mock.Mock() manager = ( @@ -82,3 +83,226 @@ async def controlled_lookup(*args, **kwargs): # Verify that the second refresh request was ignored and only one lookup occurred. assert credentials._lookup_regional_access_boundary.call_count == 1 + + +def test_prepare_async_lookup_callable_no_clone(): + request = mock.Mock(spec=[]) # explicitly no _clone + ( + new_request, + cloned, + is_cloned, + ) = _regional_access_boundary_utils._prepare_async_lookup_callable(request) + assert new_request is request + assert cloned is request + assert is_cloned is False + + +def test_prepare_async_lookup_callable_with_clone(): + request = mock.Mock() + cloned_req = mock.Mock() + request._clone.return_value = cloned_req + + ( + new_request, + cloned, + is_cloned, + ) = _regional_access_boundary_utils._prepare_async_lookup_callable(request) + assert new_request is cloned_req + assert cloned is cloned_req + assert is_cloned is True + + +def test_prepare_async_lookup_callable_partial(): + import functools + + request = mock.Mock() + cloned_req = mock.Mock() + request._clone.return_value = cloned_req + + partial_req = functools.partial(request, 1, a=2) + ( + new_request, + cloned, + is_cloned, + ) = _regional_access_boundary_utils._prepare_async_lookup_callable(partial_req) + + assert isinstance(new_request, functools.partial) + assert new_request.func is cloned_req + assert new_request.args == (1,) + assert new_request.keywords == {"a": 2} + assert cloned is cloned_req + assert is_cloned is True + + +@pytest.mark.asyncio +async def test_close_cloned_request_not_cloned(): + request = mock.Mock() + await _regional_access_boundary_utils._close_cloned_request( + request, is_cloned=False + ) + request.close.assert_not_called() + + +@pytest.mark.asyncio +async def test_close_cloned_request_sync(): + request = mock.Mock() + await _regional_access_boundary_utils._close_cloned_request(request, is_cloned=True) + request.close.assert_called_once() + + +@pytest.mark.asyncio +async def test_close_cloned_request_async(): + request = mock.Mock() + request.close = mock.AsyncMock() + await _regional_access_boundary_utils._close_cloned_request(request, is_cloned=True) + request.close.assert_awaited_once() + + +@pytest.mark.asyncio +async def test_close_cloned_request_future(): + request = mock.Mock() + future = asyncio.Future() + future.set_result(None) + request.close = mock.Mock(return_value=future) + + await _regional_access_boundary_utils._close_cloned_request(request, is_cloned=True) + request.close.assert_called_once() + assert future.done() + + +@pytest.mark.asyncio +async def test_close_cloned_request_async_exception(): + request = mock.Mock() + request.close = mock.AsyncMock(side_effect=Exception("close error")) + # Should swallow the exception and not raise + await _regional_access_boundary_utils._close_cloned_request(request, is_cloned=True) + request.close.assert_awaited_once() + + +def test_async_refresh_manager_pickle(): + import pickle + + manager = ( + _regional_access_boundary_utils._AsyncRegionalAccessBoundaryRefreshManager() + ) + manager._worker_task = mock.Mock() + + dumped = pickle.dumps(manager) + loaded = pickle.loads(dumped) + + assert loaded._lock is not None + assert loaded._worker_task is None + + +@pytest.mark.asyncio +async def test_async_worker_exception_logging_enabled(monkeypatch): + credentials = mock.AsyncMock() + credentials._lookup_regional_access_boundary.side_effect = Exception("lookup fail") + + request = mock.Mock() + request._clone.return_value = request + rab_manager = mock.Mock() + + # Force is_logging_enabled to return True + monkeypatch.setattr( + _regional_access_boundary_utils._helpers, + "is_logging_enabled", + lambda logger: True, + ) + + manager = ( + _regional_access_boundary_utils._AsyncRegionalAccessBoundaryRefreshManager() + ) + + with mock.patch.object( + _regional_access_boundary_utils._LOGGER, "warning" + ) as mock_warning: + manager.start_refresh(credentials, request, rab_manager) + await manager._worker_task + + mock_warning.assert_called_once() + assert "lookup raised an exception" in mock_warning.call_args[0][0] + rab_manager.process_regional_access_boundary_info.assert_called_once_with(None) + + +@pytest.mark.asyncio +async def test_async_worker_exception_logging_disabled(monkeypatch): + credentials = mock.AsyncMock() + credentials._lookup_regional_access_boundary.side_effect = Exception("lookup fail") + + request = mock.Mock() + request._clone.return_value = request + rab_manager = mock.Mock() + + # Force is_logging_enabled to return False + monkeypatch.setattr( + _regional_access_boundary_utils._helpers, + "is_logging_enabled", + lambda logger: False, + ) + + manager = ( + _regional_access_boundary_utils._AsyncRegionalAccessBoundaryRefreshManager() + ) + + with mock.patch.object( + _regional_access_boundary_utils._LOGGER, "warning" + ) as mock_warning: + manager.start_refresh(credentials, request, rab_manager) + await manager._worker_task + + mock_warning.assert_not_called() + rab_manager.process_regional_access_boundary_info.assert_called_once_with(None) + + +@pytest.mark.asyncio +async def test_async_refresh_manager_clone_failure(): + credentials = mock.AsyncMock() + rab_manager = mock.Mock() + + # Configure mock request to raise an exception on clone + request = mock.Mock() + request._clone.side_effect = Exception("mock clone error") + + manager = ( + _regional_access_boundary_utils._AsyncRegionalAccessBoundaryRefreshManager() + ) + + manager.start_refresh(credentials, request, rab_manager) + + # Verify no worker task was created and cooldown was triggered immediately + assert manager._worker_task is None + rab_manager.process_regional_access_boundary_info.assert_called_once_with(None) + + +@pytest.mark.asyncio +async def test_async_refresh_manager_task_creation_failure(monkeypatch): + credentials = mock.AsyncMock() + rab_manager = mock.Mock() + + # Configure a mock request that successfully clones + request = mock.Mock() + cloned_req = mock.Mock() + cloned_req.close = mock.AsyncMock() + request._clone.return_value = cloned_req + + # Force task creation to fail + monkeypatch.setattr( + asyncio, + "create_task", + mock.Mock(side_effect=RuntimeError("loop closed")), + ) + + manager = ( + _regional_access_boundary_utils._AsyncRegionalAccessBoundaryRefreshManager() + ) + + with pytest.raises(RuntimeError, match="loop closed"): + manager.start_refresh(credentials, request, rab_manager) + + # Yield control to the event loop so the scheduled close task can run + await asyncio.sleep(0) + + # Verify the cloned session was closed immediately to prevent socket leaks + cloned_req.close.assert_awaited_once() + rab_manager.process_regional_access_boundary_info.assert_called_once_with(None) diff --git a/packages/google-auth/tests_async/transport/test_aiohttp_requests.py b/packages/google-auth/tests_async/transport/test_aiohttp_requests.py index 7d1215ef71ea..7eab914189f1 100644 --- a/packages/google-auth/tests_async/transport/test_aiohttp_requests.py +++ b/packages/google-auth/tests_async/transport/test_aiohttp_requests.py @@ -135,6 +135,216 @@ def test_timeout(self): request = aiohttp_requests.Request(http) request(url="http://example.com", method="GET", timeout=5) + @pytest.mark.asyncio + async def test__clone(self): + http = mock.create_autospec( + aiohttp.ClientSession, instance=True, _auto_decompress=False + ) + http._connector = mock.Mock(spec=aiohttp.TCPConnector) + http._connector.closed = False + http._connector._ssl = mock.sentinel.ssl + http._connector._limit = 50 + http._connector._limit_per_host = 10 + http._connector._force_close = True + http._connector._resolver = mock.sentinel.resolver + http._connector._local_addr = mock.sentinel.local_addr + + http._trust_env = False + http._trace_configs = [mock.sentinel.trace_config] + http._default_headers = {"test": "header"} + http._cookie_jar = mock.sentinel.cookie_jar + http._default_auth = mock.sentinel.auth + http._timeout = mock.sentinel.timeout + http._json_serialize = mock.sentinel.json_serialize + + request = aiohttp_requests.Request(http) + with mock.patch( + "aiohttp.ClientSession", autospec=True + ) as session_mock, mock.patch.object( + aiohttp.TCPConnector, "__init__", autospec=True, return_value=None + ) as connector_init_mock: + session_mock.return_value._auto_decompress = False + cloned = request._clone() + + assert isinstance(cloned, aiohttp_requests.Request) + assert cloned is not request + + connector_init_mock.assert_called_once_with( + mock.ANY, + ssl=mock.sentinel.ssl, + limit=50, + limit_per_host=10, + force_close=True, + local_addr=mock.sentinel.local_addr, + ) + + session_mock.assert_called_once_with( + connector=mock.ANY, + auto_decompress=False, + trust_env=False, + trace_configs=[mock.sentinel.trace_config], + headers={"test": "header"}, + cookie_jar=mock.sentinel.cookie_jar, + auth=mock.sentinel.auth, + timeout=mock.sentinel.timeout, + json_serialize=mock.sentinel.json_serialize, + ) + assert isinstance(session_mock.call_args[1]["connector"], aiohttp.TCPConnector) + + @pytest.mark.asyncio + async def test__clone_closed(self): + request = aiohttp_requests.Request() + request._closed = True + with pytest.raises( + google.auth.exceptions.TransportError, + match="Cannot clone a closed transport.", + ): + request._clone() + + @pytest.mark.asyncio + async def test__clone_custom_connector(self): + http = mock.create_autospec( + aiohttp.ClientSession, instance=True, _auto_decompress=False + ) + http._connector = mock.Mock() + http._connector.closed = False + request = aiohttp_requests.Request(http) + with pytest.raises( + google.auth.exceptions.TransportError, + match="Unsupported connector type for cloning", + ): + request._clone() + + @pytest.mark.asyncio + async def test_close(self): + http = mock.create_autospec( + aiohttp.ClientSession, instance=True, _auto_decompress=False + ) + http.close = mock.AsyncMock() + request = aiohttp_requests.Request(http) + + await request.close() + assert request._closed is True + http.close.assert_awaited_once() + + # Check idempotency + await request.close() + http.close.assert_awaited_once() # Still only called 1 time + + @pytest.mark.asyncio + async def test_request_call_closed(self): + http = mock.create_autospec( + aiohttp.ClientSession, instance=True, _auto_decompress=False + ) + request = aiohttp_requests.Request(http) + await request.close() + with pytest.raises( + google.auth.exceptions.TransportError, match="session is closed." + ): + await request("http://example.com") + + @pytest.mark.asyncio + async def test__clone_no_session(self): + request = aiohttp_requests.Request() + cloned = request._clone() + assert isinstance(cloned, aiohttp_requests.Request) + assert cloned is not request + assert cloned.session is not None + await cloned.close() + + @pytest.mark.asyncio + async def test__clone_closed_connector(self): + http = mock.create_autospec( + aiohttp.ClientSession, instance=True, _auto_decompress=False + ) + http._connector = mock.Mock() + http._connector.closed = True + http._trust_env = True + http._trace_configs = None + http._default_headers = None + http._cookie_jar = None + http._default_auth = None + http._timeout = None + http._json_serialize = None + + request = aiohttp_requests.Request(http) + with mock.patch("aiohttp.ClientSession", autospec=True) as session_mock: + session_mock.return_value._auto_decompress = False + cloned = request._clone() + + assert isinstance(cloned, aiohttp_requests.Request) + assert cloned is not request + + @pytest.mark.asyncio + async def test__clone_unix_socket_no_path(self): + try: + from aiohttp import UnixConnector + except ImportError: + return + + http = mock.create_autospec( + aiohttp.ClientSession, instance=True, _auto_decompress=False + ) + http._connector = mock.Mock(spec=UnixConnector) + http._connector.closed = False + http._connector._path = None + http._trust_env = True + http._trace_configs = None + http._default_headers = None + http._cookie_jar = None + http._default_auth = None + http._timeout = None + http._json_serialize = None + + request = aiohttp_requests.Request(http) + with mock.patch("aiohttp.ClientSession", autospec=True) as session_mock: + session_mock.return_value._auto_decompress = False + cloned = request._clone() + + assert isinstance(cloned, aiohttp_requests.Request) + assert cloned is not request + + @pytest.mark.asyncio + async def test__clone_unix_socket_with_path(self): + try: + from aiohttp import UnixConnector + except ImportError: + return + + http = mock.create_autospec( + aiohttp.ClientSession, instance=True, _auto_decompress=False + ) + http._connector = mock.Mock(spec=UnixConnector) + http._connector.closed = False + http._connector._path = "/tmp/test.sock" + http._connector._limit = 42 + http._connector._force_close = True + http._trust_env = True + http._trace_configs = None + http._default_headers = None + http._cookie_jar = None + http._default_auth = None + http._timeout = None + http._json_serialize = None + + request = aiohttp_requests.Request(http) + with mock.patch( + "aiohttp.ClientSession", autospec=True + ) as session_mock, mock.patch.object( + UnixConnector, "__init__", autospec=True, return_value=None + ) as connector_init_mock: + session_mock.return_value._auto_decompress = False + cloned = request._clone() + + assert isinstance(cloned, aiohttp_requests.Request) + assert cloned is not request + connector_init_mock.assert_called_once_with( + mock.ANY, + path="/tmp/test.sock", + limit=42, + force_close=True, + ) + class CredentialsStub(google.auth._credentials_async.Credentials): def __init__(self, token="token"): From f4945bd33f385c8ad7fcf71c03e677c28bba2378 Mon Sep 17 00:00:00 2001 From: Anthonios Partheniou Date: Mon, 15 Jun 2026 14:27:55 -0400 Subject: [PATCH 076/174] tests: fix compatibility with pytest 9.1.0 (#17465) This PR fixes a compatibility issue with `pytest==9.1.0`. See https://docs.pytest.org/en/stable/deprecations.html#non-collection-iterables-in-pytest-mark-parametrize See the stack trace below which appears without the fix ``` ________________________________________________________________________________________________________ ERROR collecting tests/unit/test_python_version_support.py ________________________________________________________________________________________________________ .nox/97a4db2a/lib/python3.14/site-packages/pluggy/_hooks.py:512: in __call__ return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .nox/97a4db2a/lib/python3.14/site-packages/pluggy/_manager.py:120: in _hookexec return self._inner_hookexec(hook_name, methods, kwargs, firstresult) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .nox/97a4db2a/lib/python3.14/site-packages/pluggy/_callers.py:53: in run_old_style_hookwrapper return result.get_result() ^^^^^^^^^^^^^^^^^^^ .nox/97a4db2a/lib/python3.14/site-packages/pytest_asyncio/plugin.py:701: in pytest_pycollect_makeitem_convert_async_functions_to_subclass ) = hook_result.get_result() ^^^^^^^^^^^^^^^^^^^^^^^^ .nox/97a4db2a/lib/python3.14/site-packages/pluggy/_callers.py:38: in run_old_style_hookwrapper res = yield ^^^^^ .nox/97a4db2a/lib/python3.14/site-packages/_pytest/python.py:250: in pytest_pycollect_makeitem return list(collector._genfunctions(name, obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .nox/97a4db2a/lib/python3.14/site-packages/_pytest/python.py:476: in _genfunctions self.ihook.pytest_generate_tests.call_extra(methods, dict(metafunc=metafunc)) .nox/97a4db2a/lib/python3.14/site-packages/pluggy/_hooks.py:573: in call_extra return self._hookexec(self.name, hookimpls, kwargs, firstresult) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .nox/97a4db2a/lib/python3.14/site-packages/pluggy/_manager.py:120: in _hookexec return self._inner_hookexec(hook_name, methods, kwargs, firstresult) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .nox/97a4db2a/lib/python3.14/site-packages/_pytest/python.py:124: in pytest_generate_tests metafunc.parametrize(*marker.args, **marker.kwargs, _param_mark=marker) .nox/97a4db2a/lib/python3.14/site-packages/_pytest/python.py:1316: in parametrize argnames, parametersets = ParameterSet._for_parametrize( .nox/97a4db2a/lib/python3.14/site-packages/_pytest/mark/structures.py:203: in _for_parametrize warnings.warn( E pytest.PytestRemovedIn10Warning: Passing a non-Collection iterable to parametrize is deprecated. E Test: tests/unit/test_python_version_support.py::test_all_tracked_versions_and_date_scenarios, argvalues type: generator E Please convert to a list or tuple. E See https://docs.pytest.org/en/stable/deprecations.html#parametrize-iterators ``` --- .../tests/unit/test_python_version_support.py | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/packages/google-api-core/tests/unit/test_python_version_support.py b/packages/google-api-core/tests/unit/test_python_version_support.py index 07620934c93f..e6856c436d62 100644 --- a/packages/google-api-core/tests/unit/test_python_version_support.py +++ b/packages/google-api-core/tests/unit/test_python_version_support.py @@ -12,20 +12,20 @@ # See the License for the specific language governing permissions and # limitations under the License. -import pytest import datetime import textwrap import warnings from collections import namedtuple - from unittest.mock import patch +import pytest + # Code to be tested from google.api_core._python_version_support import ( + PYTHON_VERSION_INFO, + PythonVersionStatus, _flatten_message, check_python_version, - PythonVersionStatus, - PYTHON_VERSION_INFO, ) # Helper object for mocking sys.version_info @@ -65,10 +65,12 @@ def _create_failure_message( ) -def generate_tracked_version_test_cases(): +def get_tracked_version_test_cases(): """ - Yields test parameters for all tracked versions and boundary conditions. + Returns a list of test parameters for all tracked versions and boundary conditions. """ + results = [] + for version_tuple, version_info in PYTHON_VERSION_INFO.items(): py_version_str = f"{version_tuple[0]}.{version_tuple[1]}" gapic_dep = version_info.gapic_deprecation or ( @@ -111,20 +113,23 @@ def generate_tracked_version_test_cases(): } for name, params in test_cases.items(): - yield pytest.param( - version_tuple, - params["date"], - params["expected"], - gapic_dep, - gapic_end, - eol_warning_starts, - id=f"{py_version_str}-{name}", + results.append( + pytest.param( + version_tuple, + params["date"], + params["expected"], + gapic_dep, + gapic_end, + eol_warning_starts, + id=f"{py_version_str}-{name}", + ) ) + return results @pytest.mark.parametrize( "version_tuple, mock_date, expected_status, gapic_dep, gapic_end, eol_warning_starts", - generate_tracked_version_test_cases(), + get_tracked_version_test_cases(), ) def test_all_tracked_versions_and_date_scenarios( version_tuple, mock_date, expected_status, gapic_dep, gapic_end, eol_warning_starts From 00ec9bfd967546809e84114be1c63f9482ad90b2 Mon Sep 17 00:00:00 2001 From: Shuowei Li Date: Mon, 15 Jun 2026 18:29:37 +0000 Subject: [PATCH 077/174] chore: release bigframes v2.43.0 (#17460) PR created by the Librarian CLI to initialize a release. Merging this PR will auto trigger a release. Librarian Version: v0.16.0 Language Image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:234b9d1f2ddb057ed7ac6a38db0bf8163d839c65c6cf88ade52530cddebce59e
bigframes: v2.43.0 ## [v2.43.0](https://github.com/googleapis/google-cloud-python/compare/bigframes-v2.42.0...bigframes-v2.43.0) (2026-06-12) ### Features * add `bigframes.bigquery.bit_count` and conversion scalar function (#17433) ([7f29823f](https://github.com/googleapis/google-cloud-python/commit/7f29823f)) ### Bug Fixes * preserve aliases on cast columns and fix star selection in sqlglot (#17394) (#17455) ([145034a3](https://github.com/googleapis/google-cloud-python/commit/145034a3)) * improve error message when unescaped `{` are found in SQL cells (#17346) ([3a90cc8e](https://github.com/googleapis/google-cloud-python/commit/3a90cc8e)) * bump pyarrow from 15.0.2 to 23.0.1 in /packages/bigframes (#17386) ([f59c2b2a](https://github.com/googleapis/google-cloud-python/commit/f59c2b2a)) ### Documentation * add a notebook explaining bqsql magics cell chaining (#17216) ([1a0de4a7](https://github.com/googleapis/google-cloud-python/commit/1a0de4a7))
--- .librarian/state.yaml | 2 +- librarian.yaml | 2 +- packages/bigframes/CHANGELOG.md | 19 +++++++++++++++++++ packages/bigframes/bigframes/version.py | 4 ++-- .../third_party/bigframes_vendored/version.py | 4 ++-- 5 files changed, 25 insertions(+), 6 deletions(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index 3255f442c54d..55a6a3e77498 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -14,7 +14,7 @@ image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:234b9d1f2ddb057ed7ac6a38db0bf8163d839c65c6cf88ade52530cddebce59e libraries: - id: bigframes - version: 2.42.0 + version: 2.43.0 last_generated_commit: "" apis: [] source_roots: diff --git a/librarian.yaml b/librarian.yaml index 25570c818942..78f128c04026 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -58,7 +58,7 @@ default: library_type: GAPIC_AUTO libraries: - name: bigframes - version: 2.42.0 + version: 2.43.0 skip_release: true python: library_type: INTEGRATION diff --git a/packages/bigframes/CHANGELOG.md b/packages/bigframes/CHANGELOG.md index 1708074a9ae0..5a44900bf1be 100644 --- a/packages/bigframes/CHANGELOG.md +++ b/packages/bigframes/CHANGELOG.md @@ -4,6 +4,25 @@ [1]: https://pypi.org/project/bigframes/#history +## [2.43.0](https://github.com/googleapis/google-cloud-python/compare/bigframes-v2.42.0...bigframes-v2.43.0) (2026-06-12) + + +### Documentation + +* add a notebook explaining bqsql magics cell chaining (#17216) ([1a0de4a7701b7fdf4c2593b1960f1194ebc49793](https://github.com/googleapis/google-cloud-python/commit/1a0de4a7701b7fdf4c2593b1960f1194ebc49793)) + + +### Features + +* add `bigframes.bigquery.bit_count` and conversion scalar function (#17433) ([7f29823fadb3cff42dbe666f8c7aa33bab3c7021](https://github.com/googleapis/google-cloud-python/commit/7f29823fadb3cff42dbe666f8c7aa33bab3c7021)) + + +### Bug Fixes + +* preserve aliases on cast columns and fix star selection in sqlglot (#17394) (#17455) ([145034a345eb3e14ea3f23dfcafa3d2409a09067](https://github.com/googleapis/google-cloud-python/commit/145034a345eb3e14ea3f23dfcafa3d2409a09067)) +* bump pyarrow from 15.0.2 to 23.0.1 in /packages/bigframes (#17386) ([f59c2b2aa61316cf04b650933036ef50f6a1f08c](https://github.com/googleapis/google-cloud-python/commit/f59c2b2aa61316cf04b650933036ef50f6a1f08c)) +* improve error message when unescaped `{` are found in SQL cells (#17346) ([3a90cc8e867c8a2d2f8060858fde9eda94f80a54](https://github.com/googleapis/google-cloud-python/commit/3a90cc8e867c8a2d2f8060858fde9eda94f80a54)) + ## [2.42.0](https://github.com/googleapis/google-cloud-python/compare/bigframes-v2.41.0...bigframes-v2.42.0) (2026-06-08) diff --git a/packages/bigframes/bigframes/version.py b/packages/bigframes/bigframes/version.py index 8982d009e1b8..da85cfd043d2 100644 --- a/packages/bigframes/bigframes/version.py +++ b/packages/bigframes/bigframes/version.py @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "2.42.0" +__version__ = "2.43.0" # {x-release-please-start-date} -__release_date__ = "2026-06-08" +__release_date__ = "2026-06-12" # {x-release-please-end} diff --git a/packages/bigframes/third_party/bigframes_vendored/version.py b/packages/bigframes/third_party/bigframes_vendored/version.py index 8982d009e1b8..da85cfd043d2 100644 --- a/packages/bigframes/third_party/bigframes_vendored/version.py +++ b/packages/bigframes/third_party/bigframes_vendored/version.py @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "2.42.0" +__version__ = "2.43.0" # {x-release-please-start-date} -__release_date__ = "2026-06-08" +__release_date__ = "2026-06-12" # {x-release-please-end} From af193931e4e38c4b59751edb8e915ae3388b8524 Mon Sep 17 00:00:00 2001 From: nbayati <99771966+nbayati@users.noreply.github.com> Date: Mon, 15 Jun 2026 12:03:42 -0700 Subject: [PATCH 078/174] feat(auth): make RAB feature production ready (#17390) This PR resolves issues identified during verification of gcloud Regional Access Boundary (RAB) flows and enables RAB verification by default: * Removes the client-side environment variable feature gate (`GOOGLE_AUTH_TRUST_BOUNDARY_ENABLED`) to execute RAB lookups by default across standard credential classes. * Updates the Python auth SDK to recognize mTLS regional endpoints (`.rep.mtls.googleapis.com`), bypassing redundant RAB lookups on secure transport boundaries. * Defers Service Account impersonation setup until HTTP request execution before_request, propagating active cached tokens downward onto the inner credential to guarantee that access tokens restored across external CLI entrypoints correctly delegate regional access boundary (RAB) lookups to target Service Account endpoints without forcing redundant STS network renewal. --- .../auth/_regional_access_boundary_utils.py | 21 --- packages/google-auth/google/auth/aws.py | 8 +- .../google-auth/google/auth/credentials.py | 17 +- .../google/auth/environment_vars.py | 6 +- .../google/auth/external_account.py | 33 +++- .../google-auth/google/auth/identity_pool.py | 3 +- .../tests/compute_engine/test_credentials.py | 50 ++++-- .../test__regional_access_boundary_utils.py | 154 +++++------------- packages/google-auth/tests/test_aws.py | 15 ++ .../google-auth/tests/test_credentials.py | 57 +++---- .../tests/test_external_account.py | 140 ++++++++++++++++ .../google-auth/tests/test_identity_pool.py | 15 ++ 12 files changed, 318 insertions(+), 201 deletions(-) diff --git a/packages/google-auth/google/auth/_regional_access_boundary_utils.py b/packages/google-auth/google/auth/_regional_access_boundary_utils.py index 84f891082e48..9b055b0dde68 100644 --- a/packages/google-auth/google/auth/_regional_access_boundary_utils.py +++ b/packages/google-auth/google/auth/_regional_access_boundary_utils.py @@ -20,12 +20,10 @@ import functools import inspect import logging -import os import threading from typing import NamedTuple, Optional, TYPE_CHECKING from google.auth import _helpers -from google.auth import environment_vars if TYPE_CHECKING: # pragma: NO COVER import google.auth.credentials @@ -34,25 +32,6 @@ _LOGGER = logging.getLogger(__name__) -@functools.lru_cache() -def is_regional_access_boundary_enabled(): - """Checks if Regional Access Boundary is enabled via environment variable. - - The environment variable is interpreted as a boolean with the following - (case-insensitive) rules: - - "true", "1" are considered true. - - Any other value (or unset) is considered false. - - Returns: - bool: True if Regional Access Boundary is enabled, False otherwise. - """ - value = os.environ.get(environment_vars.GOOGLE_AUTH_TRUST_BOUNDARY_ENABLED) - if value is None: - return False - - return value.lower() in ("true", "1") - - # The default lifetime for a cached Regional Access Boundary. DEFAULT_REGIONAL_ACCESS_BOUNDARY_TTL = datetime.timedelta(hours=6) diff --git a/packages/google-auth/google/auth/aws.py b/packages/google-auth/google/auth/aws.py index c640568b80e9..46c913a7a96f 100644 --- a/packages/google-auth/google/auth/aws.py +++ b/packages/google-auth/google/auth/aws.py @@ -841,11 +841,9 @@ def from_info(cls, info, **kwargs): Raises: ValueError: For invalid parameters. """ - aws_security_credentials_supplier = info.get( - "aws_security_credentials_supplier" - ) - kwargs.update( - {"aws_security_credentials_supplier": aws_security_credentials_supplier} + kwargs.setdefault( + "aws_security_credentials_supplier", + info.get("aws_security_credentials_supplier"), ) return super(Credentials, cls).from_info(info, **kwargs) diff --git a/packages/google-auth/google/auth/credentials.py b/packages/google-auth/google/auth/credentials.py index f0ce4f41e0ac..95aa2cf3503f 100644 --- a/packages/google-auth/google/auth/credentials.py +++ b/packages/google-auth/google/auth/credentials.py @@ -446,9 +446,13 @@ def _is_regional_endpoint(self, url): try: # Do not perform a lookup if the request is for a regional endpoint. hostname = urlparse(url).hostname - if hostname and ( - hostname.endswith(".rep.googleapis.com") - or hostname.endswith(".rep.sandbox.googleapis.com") + if hostname and hostname.endswith( + ( + ".rep.googleapis.com", + ".rep.sandbox.googleapis.com", + ".rep.mtls.googleapis.com", + ".rep.mtls.sandbox.googleapis.com", + ) ): return True except (ValueError, TypeError, AttributeError): @@ -484,16 +488,11 @@ def _maybe_start_regional_access_boundary_refresh(self, request, url): def _is_regional_access_boundary_lookup_required(self): """Checks if a Regional Access Boundary lookup is required. - A lookup is required if the feature is enabled via an environment - variable and the universe domain is supported. + A lookup is required if the universe domain is supported. Returns: bool: True if a Regional Access Boundary lookup is required, False otherwise. """ - # Check if the feature is enabled. - if not _regional_access_boundary_utils.is_regional_access_boundary_enabled(): - return False - # Skip for non-default universe domains. if self.universe_domain != DEFAULT_UNIVERSE_DOMAIN: return False diff --git a/packages/google-auth/google/auth/environment_vars.py b/packages/google-auth/google/auth/environment_vars.py index c7d706467ed4..b7ff66c8b54a 100644 --- a/packages/google-auth/google/auth/environment_vars.py +++ b/packages/google-auth/google/auth/environment_vars.py @@ -105,9 +105,13 @@ AWS_REGION = "AWS_REGION" AWS_DEFAULT_REGION = "AWS_DEFAULT_REGION" + GOOGLE_AUTH_TRUST_BOUNDARY_ENABLED = "GOOGLE_AUTH_TRUST_BOUNDARY_ENABLED" """Environment variable controlling whether to enable trust boundary feature. -The default value is false. Users have to explicitly set this value to true.""" + +.. deprecated:: + This environment variable is deprecated and no longer has any effect. +""" GOOGLE_API_CERTIFICATE_CONFIG = "GOOGLE_API_CERTIFICATE_CONFIG" """Environment variable defining the location of Google API certificate config diff --git a/packages/google-auth/google/auth/external_account.py b/packages/google-auth/google/auth/external_account.py index eee6d1194031..b90fcab4c0ee 100644 --- a/packages/google-auth/google/auth/external_account.py +++ b/packages/google-auth/google/auth/external_account.py @@ -36,6 +36,7 @@ import json import logging import re +import threading from typing import Optional, TYPE_CHECKING @@ -200,6 +201,7 @@ def __init__( self._metrics_options = self._create_default_metrics_options() self._impersonated_credentials = None + self._impersonation_lock = threading.Lock() self._project_id = None self._supplier_context = SupplierContext( self._subject_token_type, self._audience @@ -213,6 +215,15 @@ def __init__( "credentials" ) + def __getstate__(self): + state = self.__dict__.copy() + state.pop("_impersonation_lock", None) + return state + + def __setstate__(self, state): + super().__setstate__(state) + self._impersonation_lock = threading.Lock() + @property def info(self): """Generates the dictionary representation of the current credentials. @@ -444,6 +455,17 @@ def _maybe_start_regional_access_boundary_refresh(self, request, url): HTTP requests. url (str): The URL of the request. """ + if self._should_initialize_impersonated_credentials(): + with self._impersonation_lock: + if self._impersonated_credentials is None: + impersonated = self._initialize_impersonated_credentials() + if getattr(self, "token", None): + impersonated.token = self.token + if getattr(self, "expiry", None): + impersonated.expiry = self.expiry + self._impersonated_credentials = impersonated + self._rab_manager = impersonated._rab_manager + if getattr(self, "_impersonated_credentials", None): self._impersonated_credentials._maybe_start_regional_access_boundary_refresh( request, url @@ -462,7 +484,11 @@ def _perform_refresh_token(self, request, cert_fingerprint=None): ) if self._should_initialize_impersonated_credentials(): - self._impersonated_credentials = self._initialize_impersonated_credentials() + with self._impersonation_lock: + if self._impersonated_credentials is None: + self._impersonated_credentials = ( + self._initialize_impersonated_credentials() + ) if self._impersonated_credentials: self._impersonated_credentials.refresh(request) @@ -581,9 +607,10 @@ def with_universe_domain(self, universe_domain): return cred def _should_initialize_impersonated_credentials(self): + """Determines if the underlying Service Account credential should be initialized.""" return ( - self._service_account_impersonation_url is not None - and self._impersonated_credentials is None + getattr(self, "_service_account_impersonation_url", None) is not None + and getattr(self, "_impersonated_credentials", None) is None ) def _initialize_impersonated_credentials(self): diff --git a/packages/google-auth/google/auth/identity_pool.py b/packages/google-auth/google/auth/identity_pool.py index 30819ef0485a..333f7bdf53ea 100644 --- a/packages/google-auth/google/auth/identity_pool.py +++ b/packages/google-auth/google/auth/identity_pool.py @@ -526,8 +526,7 @@ def from_info(cls, info, **kwargs): Raises: ValueError: For invalid parameters. """ - subject_token_supplier = info.get("subject_token_supplier") - kwargs.update({"subject_token_supplier": subject_token_supplier}) + kwargs.setdefault("subject_token_supplier", info.get("subject_token_supplier")) return super(Credentials, cls).from_info(info, **kwargs) @classmethod diff --git a/packages/google-auth/tests/compute_engine/test_credentials.py b/packages/google-auth/tests/compute_engine/test_credentials.py index de37656dcee3..584d518a9f75 100644 --- a/packages/google-auth/tests/compute_engine/test_credentials.py +++ b/packages/google-auth/tests/compute_engine/test_credentials.py @@ -13,6 +13,7 @@ # limitations under the License. import base64 import datetime +import re from unittest import mock import pytest # type: ignore @@ -202,6 +203,7 @@ def test_before_request_refreshes(self, get): "access_token": "token", "expires_in": 500, }, + "googleapis.com", ] # Credentials should start as invalid @@ -248,7 +250,11 @@ def test_with_universe_domain(self): assert creds.universe_domain == "universe_domain" assert creds._universe_domain_cached - def test_token_usage_metrics(self): + @mock.patch( + "google.auth.compute_engine._metadata.get_universe_domain", + return_value="googleapis.com", + ) + def test_token_usage_metrics(self, mock_get_universe_domain): self.credentials.token = "token" self.credentials.expiry = None @@ -406,11 +412,7 @@ def test_build_regional_access_boundary_lookup_url_no_email( url = creds._build_regional_access_boundary_lookup_url() assert url is None - @mock.patch( - "google.auth._regional_access_boundary_utils.is_regional_access_boundary_enabled", - return_value=True, - ) - def test_is_regional_access_boundary_lookup_required(self, mock_enabled): + def test_is_regional_access_boundary_lookup_required(self): creds = self.credentials creds._universe_domain_cached = True @@ -438,15 +440,11 @@ def test_build_regional_access_boundary_lookup_url_with_invalid_email(self): url = creds._build_regional_access_boundary_lookup_url() assert url is None - @mock.patch( - "google.auth._regional_access_boundary_utils.is_regional_access_boundary_enabled", - return_value=True, - ) @mock.patch( "google.auth.compute_engine._metadata.get_service_account_info", autospec=True ) def test_regional_access_boundary_disabled_state_transitions( - self, mock_get_service_account_info, mock_enabled + self, mock_get_service_account_info ): mock_get_service_account_info.return_value = { "email": "spiffe://trust-domain/ns/ns/sa/sa", @@ -765,6 +763,15 @@ def test_with_target_audience_integration(self): json={}, ) + # mock allowedLocations for Regional Access Boundary + responses.add( + responses.GET, + re.compile(r".*/allowedLocations$"), + status=200, + content_type="application/json", + json={"encodedLocations": "0xABC"}, + ) + # mock token for credentials responses.add( responses.GET, @@ -783,8 +790,10 @@ def test_with_target_audience_integration(self): signature = base64.b64encode(b"some-signature").decode("utf-8") responses.add( responses.POST, - "https://iamcredentials.googleapis.com/v1/projects/-/" - "serviceAccounts/service-account@example.com:signBlob", + re.compile( + r"https://iamcredentials\.(mtls\.)?googleapis\.com/v1/projects/-/" + r"serviceAccounts/service-account@example\.com:signBlob" + ), status=200, content_type="application/json", json={"keyId": "some-key-id", "signedBlob": signature}, @@ -947,12 +956,23 @@ def test_with_quota_project_integration(self): json={}, ) + # mock allowedLocations for Regional Access Boundary + responses.add( + responses.GET, + re.compile(r".*/allowedLocations$"), + status=200, + content_type="application/json", + json={"encodedLocations": "0xABC"}, + ) + # mock sign blob endpoint signature = base64.b64encode(b"some-signature").decode("utf-8") responses.add( responses.POST, - "https://iamcredentials.googleapis.com/v1/projects/-/" - "serviceAccounts/service-account@example.com:signBlob", + re.compile( + r"https://iamcredentials\.(mtls\.)?googleapis\.com/v1/projects/-/" + r"serviceAccounts/service-account@example\.com:signBlob" + ), status=200, content_type="application/json", json={"keyId": "some-key-id", "signedBlob": signature}, diff --git a/packages/google-auth/tests/test__regional_access_boundary_utils.py b/packages/google-auth/tests/test__regional_access_boundary_utils.py index 1983571054ad..6746cf854405 100644 --- a/packages/google-auth/tests/test__regional_access_boundary_utils.py +++ b/packages/google-auth/tests/test__regional_access_boundary_utils.py @@ -13,7 +13,6 @@ # limitations under the License. import datetime -import os from unittest import mock import pytest # type: ignore @@ -22,7 +21,6 @@ from google.auth import _helpers from google.auth import _regional_access_boundary_utils from google.auth import credentials -from google.auth import environment_vars from google.oauth2 import credentials as oauth2_credentials @@ -53,48 +51,7 @@ def _make_copy(self): return new_credentials -@pytest.fixture(autouse=True) -def clear_rab_cache(): - """Clears the Regional Access Boundary enablement cache before every test.""" - _regional_access_boundary_utils.is_regional_access_boundary_enabled.cache_clear() - - class TestCredentialsWithRegionalAccessBoundary(object): - def test_is_regional_access_boundary_enabled_cached(self, monkeypatch): - # Set to true - monkeypatch.setenv(environment_vars.GOOGLE_AUTH_TRUST_BOUNDARY_ENABLED, "true") - assert ( - _regional_access_boundary_utils.is_regional_access_boundary_enabled() - is True - ) - - # Change env var to false, but it should still return True due to caching - monkeypatch.setenv(environment_vars.GOOGLE_AUTH_TRUST_BOUNDARY_ENABLED, "false") - assert ( - _regional_access_boundary_utils.is_regional_access_boundary_enabled() - is True - ) - - # Clear cache and it should now reflect the new value - _regional_access_boundary_utils.is_regional_access_boundary_enabled.cache_clear() - assert ( - _regional_access_boundary_utils.is_regional_access_boundary_enabled() - is False - ) - - @mock.patch( - "google.auth._regional_access_boundary_utils._RegionalAccessBoundaryRefreshManager.start_refresh" - ) - def test_maybe_start_refresh_is_skipped_if_env_var_not_set( - self, mock_start_refresh - ): - creds = CredentialsImpl() - with mock.patch.dict(os.environ, clear=True): - creds._maybe_start_regional_access_boundary_refresh( - mock.Mock(), "http://example.com" - ) - mock_start_refresh.assert_not_called() - @mock.patch( "google.auth._regional_access_boundary_utils._RegionalAccessBoundaryRefreshManager.start_refresh" ) @@ -106,13 +63,9 @@ def test_maybe_start_refresh_is_skipped_if_not_expired(self, mock_start_refresh) cooldown_expiry=None, cooldown_duration=_regional_access_boundary_utils.DEFAULT_REGIONAL_ACCESS_BOUNDARY_COOLDOWN, ) - with mock.patch.dict( - os.environ, - {environment_vars.GOOGLE_AUTH_TRUST_BOUNDARY_ENABLED: "true"}, - ): - creds._maybe_start_regional_access_boundary_refresh( - mock.Mock(), "http://example.com" - ) + creds._maybe_start_regional_access_boundary_refresh( + mock.Mock(), "http://example.com" + ) mock_start_refresh.assert_not_called() @mock.patch( @@ -127,13 +80,9 @@ def test_maybe_start_refresh_triggered_if_soft_expired(self, mock_start_refresh) cooldown_duration=_regional_access_boundary_utils.DEFAULT_REGIONAL_ACCESS_BOUNDARY_COOLDOWN, ) request = mock.Mock() - with mock.patch.dict( - os.environ, - {environment_vars.GOOGLE_AUTH_TRUST_BOUNDARY_ENABLED: "true"}, - ): - creds._maybe_start_regional_access_boundary_refresh( - request, "http://example.com" - ) + creds._maybe_start_regional_access_boundary_refresh( + request, "http://example.com" + ) mock_start_refresh.assert_called_once_with(creds, request, creds._rab_manager) @mock.patch( @@ -149,29 +98,28 @@ def test_maybe_start_refresh_is_skipped_if_cooldown_active( cooldown_expiry=_helpers.utcnow() + datetime.timedelta(minutes=5), cooldown_duration=_regional_access_boundary_utils.DEFAULT_REGIONAL_ACCESS_BOUNDARY_COOLDOWN, ) - with mock.patch.dict( - os.environ, - {environment_vars.GOOGLE_AUTH_TRUST_BOUNDARY_ENABLED: "true"}, - ): - creds._maybe_start_regional_access_boundary_refresh( - mock.Mock(), "http://example.com" - ) + creds._maybe_start_regional_access_boundary_refresh( + mock.Mock(), "http://example.com" + ) mock_start_refresh.assert_not_called() @mock.patch( "google.auth._regional_access_boundary_utils._RegionalAccessBoundaryRefreshManager.start_refresh" ) + @pytest.mark.parametrize( + "url", + [ + "https://my-service.us-east1.rep.googleapis.com", + "https://my-service.us-east1.rep.sandbox.googleapis.com", + "https://my-service.us-east1.rep.mtls.googleapis.com", + "https://my-service.us-east1.rep.mtls.sandbox.googleapis.com", + ], + ) def test_maybe_start_refresh_is_skipped_for_regional_endpoint( - self, mock_start_refresh + self, mock_start_refresh, url ): creds = CredentialsImpl() - with mock.patch.dict( - os.environ, - {environment_vars.GOOGLE_AUTH_TRUST_BOUNDARY_ENABLED: "true"}, - ): - creds._maybe_start_regional_access_boundary_refresh( - mock.Mock(), "https://my-service.us-east1.rep.googleapis.com" - ) + creds._maybe_start_regional_access_boundary_refresh(mock.Mock(), url) mock_start_refresh.assert_not_called() @mock.patch( @@ -180,13 +128,9 @@ def test_maybe_start_refresh_is_skipped_for_regional_endpoint( def test_maybe_start_refresh_is_triggered(self, mock_start_refresh): creds = CredentialsImpl() request = mock.Mock() - with mock.patch.dict( - os.environ, - {environment_vars.GOOGLE_AUTH_TRUST_BOUNDARY_ENABLED: "true"}, - ): - creds._maybe_start_regional_access_boundary_refresh( - request, "http://example.com" - ) + creds._maybe_start_regional_access_boundary_refresh( + request, "http://example.com" + ) mock_start_refresh.assert_called_once_with(creds, request, creds._rab_manager) def test_apply_headers_success(self): @@ -327,13 +271,9 @@ def test_maybe_start_refresh_is_skipped_if_non_default_universe_domain( self, mock_start_refresh ): creds = CredentialsImpl(universe_domain="not.googleapis.com") - with mock.patch.dict( - os.environ, - {environment_vars.GOOGLE_AUTH_TRUST_BOUNDARY_ENABLED: "true"}, - ): - creds._maybe_start_regional_access_boundary_refresh( - mock.Mock(), "http://example.com" - ) + creds._maybe_start_regional_access_boundary_refresh( + mock.Mock(), "http://example.com" + ) mock_start_refresh.assert_not_called() @mock.patch( @@ -346,13 +286,9 @@ def test_maybe_start_refresh_handles_url_parse_errors( mock_urlparse.side_effect = ValueError("Malformed URL") creds = CredentialsImpl() request = mock.Mock() - with mock.patch.dict( - os.environ, - {environment_vars.GOOGLE_AUTH_TRUST_BOUNDARY_ENABLED: "true"}, - ): - creds._maybe_start_regional_access_boundary_refresh( - request, "http://malformed-url" - ) + creds._maybe_start_regional_access_boundary_refresh( + request, "http://malformed-url" + ) mock_start_refresh.assert_called_once_with(creds, request, creds._rab_manager) @mock.patch( @@ -362,13 +298,9 @@ def test_maybe_start_refresh_blocking(self, mock_start_blocking_refresh): creds = CredentialsImpl() creds._rab_manager._use_blocking_regional_access_boundary_lookup = True request = mock.Mock() - with mock.patch.dict( - os.environ, - {environment_vars.GOOGLE_AUTH_TRUST_BOUNDARY_ENABLED: "true"}, - ): - creds._maybe_start_regional_access_boundary_refresh( - request, "http://example.com" - ) + creds._maybe_start_regional_access_boundary_refresh( + request, "http://example.com" + ) mock_start_blocking_refresh.assert_called_once_with(creds, request) def test_start_blocking_refresh_success(self): @@ -622,19 +554,15 @@ async def test_maybe_start_refresh_async_blocking(self): creds._rab_manager._use_blocking_regional_access_boundary_lookup = True request = mock.Mock() - with mock.patch.dict( - os.environ, - {environment_vars.GOOGLE_AUTH_TRUST_BOUNDARY_ENABLED: "true"}, - ): - with mock.patch.object( - creds._rab_manager, - "start_blocking_refresh_async", - new_callable=mock.AsyncMock, - ) as mock_start_blocking: - await creds._maybe_start_regional_access_boundary_refresh_async( - request, "http://example.com" - ) - mock_start_blocking.assert_called_once_with(creds, request) + with mock.patch.object( + creds._rab_manager, + "start_blocking_refresh_async", + new_callable=mock.AsyncMock, + ) as mock_start_blocking: + await creds._maybe_start_regional_access_boundary_refresh_async( + request, "http://example.com" + ) + mock_start_blocking.assert_called_once_with(creds, request) @pytest.mark.asyncio async def test_start_blocking_refresh_async_success(self): diff --git a/packages/google-auth/tests/test_aws.py b/packages/google-auth/tests/test_aws.py index ce578af7b871..8c09c5453f9f 100644 --- a/packages/google-auth/tests/test_aws.py +++ b/packages/google-auth/tests/test_aws.py @@ -1036,6 +1036,21 @@ def test_from_info_supplier(self, mock_init): trust_boundary=None, ) + @mock.patch.object(aws.Credentials, "__init__", return_value=None) + def test_from_info_programmatic_supplier_keyword(self, mock_init): + supplier = TestAwsSecurityCredentialsSupplier() + info = { + "audience": AUDIENCE, + "subject_token_type": SUBJECT_TOKEN_TYPE, + "token_url": TOKEN_URL, + } + credentials = aws.Credentials.from_info( + info, aws_security_credentials_supplier=supplier + ) + + assert isinstance(credentials, aws.Credentials) + assert mock_init.call_args[1]["aws_security_credentials_supplier"] == supplier + @mock.patch.object(aws.Credentials, "__init__", return_value=None) def test_from_file_full_options(self, mock_init, tmpdir): info = { diff --git a/packages/google-auth/tests/test_credentials.py b/packages/google-auth/tests/test_credentials.py index 5c7e39d59e84..24cbb98afd94 100644 --- a/packages/google-auth/tests/test_credentials.py +++ b/packages/google-auth/tests/test_credentials.py @@ -407,38 +407,31 @@ def _build_trust_boundary_lookup_url(self): def test_before_request_triggers_rab_refresh(): - with mock.patch( - "google.auth._regional_access_boundary_utils." - "is_regional_access_boundary_enabled", - return_value=True, - ): - with mock.patch( - "google.oauth2._client._lookup_regional_access_boundary" - ) as lookup: - lookup.return_value = {"encodedLocations": "0xA30"} - - creds = CredentialsImpl() - creds = creds._set_blocking_regional_access_boundary_lookup() - - request = mock.Mock() - headers = {} - - # Initial state: no token - assert creds.token is None - - # before_request should trigger token refresh and THEN RAB refresh. - # We verify this by checking that the RAB lookup was called with - # the URL containing the refreshed token. - creds.before_request(request, "GET", "http://example.com", headers) - - assert creds.token == "refreshed-token" - assert headers["authorization"] == "Bearer refreshed-token" - assert headers["x-allowed-locations"] == "0xA30" - - # Verify lookup was called with the refreshed token's URL - lookup.assert_called_once() - args, kwargs = lookup.call_args - assert args[1] == "http://mock.url/lookup_for_refreshed-token" + with mock.patch("google.oauth2._client._lookup_regional_access_boundary") as lookup: + lookup.return_value = {"encodedLocations": "0xA30"} + + creds = CredentialsImpl() + creds = creds._set_blocking_regional_access_boundary_lookup() + + request = mock.Mock() + headers = {} + + # Initial state: no token + assert creds.token is None + + # before_request should trigger token refresh and THEN RAB refresh. + # We verify this by checking that the RAB lookup was called with + # the URL containing the refreshed token. + creds.before_request(request, "GET", "http://example.com", headers) + + assert creds.token == "refreshed-token" + assert headers["authorization"] == "Bearer refreshed-token" + assert headers["x-allowed-locations"] == "0xA30" + + # Verify lookup was called with the refreshed token's URL + lookup.assert_called_once() + args, kwargs = lookup.call_args + assert args[1] == "http://mock.url/lookup_for_refreshed-token" def test_maybe_start_regional_access_boundary_refresh_invalid_url(): diff --git a/packages/google-auth/tests/test_external_account.py b/packages/google-auth/tests/test_external_account.py index 77d4ff0b327a..0db6fc4cea84 100644 --- a/packages/google-auth/tests/test_external_account.py +++ b/packages/google-auth/tests/test_external_account.py @@ -1026,6 +1026,37 @@ def test_refresh_impersonation_propagates_rab_config( is credentials._impersonated_credentials._rab_manager ) + def test_cached_token_initializes_impersonated_credentials(self): + # Initialize credentials with impersonation. + credentials = self.make_credentials( + service_account_impersonation_url=self.SERVICE_ACCOUNT_IMPERSONATION_URL, + scopes=self.SCOPES, + ) + + assert credentials._impersonated_credentials is None + + # Simulate cached token by setting it directly. + credentials.token = "CACHED_SA_TOKEN" + credentials.expiry = _helpers.utcnow() + datetime.timedelta(seconds=3600) + + assert credentials.token == "CACHED_SA_TOKEN" + + request = self.make_mock_request(status=http_client.OK, data={}) + + # Mock RAB refresh on ImpersonatedCredentials to verify delegation. + with mock.patch( + "google.auth.impersonated_credentials.Credentials._maybe_start_regional_access_boundary_refresh" + ) as mock_rab_refresh: + headers = {} + credentials.before_request(request, "GET", "https://example.com", headers) + + assert credentials._impersonated_credentials is not None + assert credentials._impersonated_credentials.token == "CACHED_SA_TOKEN" + assert credentials._impersonated_credentials.expiry == credentials.expiry + + # Verify delegation occurred. + mock_rab_refresh.assert_called_once_with(request, "https://example.com") + @mock.patch( "google.auth.metrics.token_request_access_token_impersonate", return_value=IMPERSONATE_ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE, @@ -2291,6 +2322,115 @@ def test_get_mtls_cert_and_key_paths(self): with pytest.raises(NotImplementedError): credentials._get_mtls_cert_and_key_paths() + def test_unpickle_legacy_state_preserves_token(self): + from google.auth import identity_pool + + creds = identity_pool.Credentials( + audience=self.AUDIENCE, + subject_token_type=self.SUBJECT_TOKEN_TYPE, + token_url=self.TOKEN_URL, + credential_source=self.CREDENTIAL_SOURCE, + ) + legacy_state = creds.__dict__.copy() + legacy_state["token"] = "LEGACY_PICKLED_TOKEN" + legacy_state["expiry"] = _helpers.utcnow() + datetime.timedelta(seconds=3600) + + unpickled_creds = identity_pool.Credentials.__new__(identity_pool.Credentials) + unpickled_creds.__setstate__(legacy_state) + + assert unpickled_creds.token == "LEGACY_PICKLED_TOKEN" + assert unpickled_creds.expiry == legacy_state["expiry"] + + def test_custom_subclass_instantiation(self): + class CustomExternalCredentials(external_account.Credentials): + def __init__(self, custom_arg, *args, **kwargs): + super().__init__(*args, **kwargs) + self.custom_arg = custom_arg + + def retrieve_subject_token(self, request): + return "CUSTOM_SUBJECT_TOKEN" + + creds = CustomExternalCredentials( + custom_arg="subclass_value", + audience=self.AUDIENCE, + subject_token_type=self.SUBJECT_TOKEN_TYPE, + token_url=self.TOKEN_URL, + credential_source=self.CREDENTIAL_SOURCE, + service_account_impersonation_url=self.SERVICE_ACCOUNT_IMPERSONATION_URL, + ) + assert creds.custom_arg == "subclass_value" + assert creds._impersonated_credentials is None + + def test_invalid_configuration_raises_validation_error(self): + from google.auth import identity_pool + + with pytest.raises(exceptions.InvalidValue) as excinfo: + identity_pool.Credentials( + audience=self.AUDIENCE, + subject_token_type=self.SUBJECT_TOKEN_TYPE, + token_url=self.TOKEN_URL, + credential_source=None, + ) + assert ( + "A valid credential source or a subject token supplier must be provided" + in str(excinfo.value) + ) + + with pytest.raises(exceptions.InvalidValue) as excinfo: + identity_pool.Credentials( + audience=self.AUDIENCE, + subject_token_type=self.SUBJECT_TOKEN_TYPE, + token_url=self.TOKEN_URL, + credential_source=self.CREDENTIAL_SOURCE, + subject_token_supplier=mock.Mock(), + ) + assert ( + "cannot have both a credential source and a subject token supplier" + in str(excinfo.value) + ) + + def test_before_request_multithreaded_lazy_initialization(self): + from google.auth import identity_pool + import threading + import time + + creds = identity_pool.Credentials( + audience=self.AUDIENCE, + subject_token_type=self.SUBJECT_TOKEN_TYPE, + token_url=self.TOKEN_URL, + credential_source=self.CREDENTIAL_SOURCE, + service_account_impersonation_url=self.SERVICE_ACCOUNT_IMPERSONATION_URL, + ) + + init_mock = mock.Mock() + mock_impersonated = mock.Mock() + mock_impersonated._rab_manager = mock.Mock() + mock_impersonated.token = "IMPERSONATED_TOKEN" + mock_impersonated.expiry = None + + def slow_initialize(): + time.sleep(0.01) + return mock_impersonated + + init_mock.side_effect = slow_initialize + creds._initialize_impersonated_credentials = init_mock + + num_threads = 10 + barrier = threading.Barrier(num_threads) + + def worker(): + barrier.wait() + creds.before_request(mock.Mock(), "GET", "https://example.com", {}) + + threads = [threading.Thread(target=worker) for _ in range(num_threads)] + for t in threads: + t.start() + for t in threads: + t.join() + + assert init_mock.call_count == 1 + assert creds._impersonated_credentials == mock_impersonated + def test_supplier_context(): context = external_account.SupplierContext("TestTokenType", "TestAudience") diff --git a/packages/google-auth/tests/test_identity_pool.py b/packages/google-auth/tests/test_identity_pool.py index 18e5ca9abd62..4b3349028b54 100644 --- a/packages/google-auth/tests/test_identity_pool.py +++ b/packages/google-auth/tests/test_identity_pool.py @@ -602,6 +602,21 @@ def test_from_info_workforce_pool(self, mock_init): trust_boundary=None, ) + @mock.patch.object(identity_pool.Credentials, "__init__", return_value=None) + def test_from_info_programmatic_supplier_keyword(self, mock_init): + supplier = TestSubjectTokenSupplier() + info = { + "audience": AUDIENCE, + "subject_token_type": SUBJECT_TOKEN_TYPE, + "token_url": TOKEN_URL, + } + credentials = identity_pool.Credentials.from_info( + info, subject_token_supplier=supplier + ) + + assert isinstance(credentials, identity_pool.Credentials) + assert mock_init.call_args[1]["subject_token_supplier"] == supplier + @mock.patch.object(identity_pool.Credentials, "__init__", return_value=None) def test_from_file_full_options(self, mock_init, tmpdir): info = { From 305f5bdd7e083fef33cb59dca581fbf3b7908a03 Mon Sep 17 00:00:00 2001 From: Wes Tarle Date: Mon, 15 Jun 2026 17:24:55 -0400 Subject: [PATCH 079/174] test(auth): assert quota project header injection in google-auth tests (#17448) Other languages like Rust, .NET, and Swift have tests verifying that the user-project configuration propagates as an HTTP request header (x-goog-user-project). The Python auth tests were only checking that the quota project property was assigned, without asserting the outbound HTTP header payload. --- .../tests/compute_engine/test_credentials.py | 5 +++++ packages/google-auth/tests/oauth2/test_credentials.py | 5 +++-- .../google-auth/tests/oauth2/test_service_account.py | 6 ++++-- packages/google-auth/tests/test_external_account.py | 7 +++++++ .../tests_async/oauth2/test_credentials_async.py | 9 ++++++--- .../tests_async/oauth2/test_service_account_async.py | 11 ++++++++--- 6 files changed, 33 insertions(+), 10 deletions(-) diff --git a/packages/google-auth/tests/compute_engine/test_credentials.py b/packages/google-auth/tests/compute_engine/test_credentials.py index 584d518a9f75..8f8a17e94640 100644 --- a/packages/google-auth/tests/compute_engine/test_credentials.py +++ b/packages/google-auth/tests/compute_engine/test_credentials.py @@ -865,6 +865,11 @@ def test_with_quota_project(self, sign, get, utcnow): # Check that the signer have been initialized with a Request object assert isinstance(self.credentials._signer._request, transport.Request) + headers = {} + self.credentials.token = "fake-token" + self.credentials.before_request(request, "GET", "https://example.com", headers) + assert headers.get("x-goog-user-project") == "project-foo" + @mock.patch( "google.auth._helpers.utcnow", return_value=_helpers.utcfromtimestamp(0), diff --git a/packages/google-auth/tests/oauth2/test_credentials.py b/packages/google-auth/tests/oauth2/test_credentials.py index 5a1ec2f757ad..43df9b3a0cc4 100644 --- a/packages/google-auth/tests/oauth2/test_credentials.py +++ b/packages/google-auth/tests/oauth2/test_credentials.py @@ -844,9 +844,10 @@ def test_with_quota_project(self): new_creds = creds.with_quota_project("new-project-456") assert new_creds.quota_project_id == "new-project-456" + request = mock.create_autospec(transport.Request, instance=True) headers = {} - creds.apply(headers) - assert "x-goog-user-project" in headers + new_creds.before_request(request, "GET", "https://example.com", headers) + assert headers.get("x-goog-user-project") == "new-project-456" def test_with_universe_domain(self): creds = credentials.Credentials(token="token") diff --git a/packages/google-auth/tests/oauth2/test_service_account.py b/packages/google-auth/tests/oauth2/test_service_account.py index 958eace2dd22..1d70543057d7 100644 --- a/packages/google-auth/tests/oauth2/test_service_account.py +++ b/packages/google-auth/tests/oauth2/test_service_account.py @@ -224,9 +224,11 @@ def test_with_quota_project(self): credentials = self.make_credentials() new_credentials = credentials.with_quota_project("new-project-456") assert new_credentials.quota_project_id == "new-project-456" + request = mock.create_autospec(transport.Request, instance=True) hdrs = {} - new_credentials.apply(hdrs, token="tok") - assert "x-goog-user-project" in hdrs + new_credentials.token = "tok" + new_credentials.before_request(request, "GET", "https://example.com", hdrs) + assert hdrs.get("x-goog-user-project") == "new-project-456" def test_copy_regional_access_boundary_manager_state_and_config_with_scopes(self): credentials = self.make_credentials() diff --git a/packages/google-auth/tests/test_external_account.py b/packages/google-auth/tests/test_external_account.py index 0db6fc4cea84..a637a95cf168 100644 --- a/packages/google-auth/tests/test_external_account.py +++ b/packages/google-auth/tests/test_external_account.py @@ -454,6 +454,13 @@ def test_with_quota_project(self): quota_project_creds = credentials.with_quota_project("project-foo") assert quota_project_creds.quota_project_id == "project-foo" + request = mock.create_autospec(transport.Request, instance=True) + headers = {} + quota_project_creds.token = "fake-token" + quota_project_creds.before_request( + request, "GET", "https://example.com", headers + ) + assert headers.get("x-goog-user-project") == "project-foo" def test_with_quota_project_workforce_pool(self): credentials = self.make_workforce_pool_credentials( diff --git a/packages/google-auth/tests_async/oauth2/test_credentials_async.py b/packages/google-auth/tests_async/oauth2/test_credentials_async.py index 0a5d8ab1aaf9..d8bf82a0b59f 100644 --- a/packages/google-auth/tests_async/oauth2/test_credentials_async.py +++ b/packages/google-auth/tests_async/oauth2/test_credentials_async.py @@ -23,6 +23,7 @@ from google.auth import _helpers from google.auth import exceptions +from google.auth import transport from google.oauth2 import _credentials_async as _credentials_async from google.oauth2 import credentials from tests.oauth2 import test_credentials @@ -344,7 +345,8 @@ def test_apply_with_no_quota_project_id(self): creds.apply(headers) assert "x-goog-user-project" not in headers - def test_with_quota_project(self): + @pytest.mark.asyncio + async def test_with_quota_project(self): creds = _credentials_async.Credentials( token="token", refresh_token=self.REFRESH_TOKEN, @@ -356,9 +358,10 @@ def test_with_quota_project(self): new_creds = creds.with_quota_project("new-project-456") assert new_creds.quota_project_id == "new-project-456" + request = mock.create_autospec(transport.Request, instance=True) headers = {} - creds.apply(headers) - assert "x-goog-user-project" in headers + await new_creds.before_request(request, "GET", "https://example.com", headers) + assert headers.get("x-goog-user-project") == "new-project-456" def test_from_authorized_user_info(self): info = test_credentials.AUTH_USER_INFO.copy() diff --git a/packages/google-auth/tests_async/oauth2/test_service_account_async.py b/packages/google-auth/tests_async/oauth2/test_service_account_async.py index e0c2e0d60a60..0539ecc80e13 100644 --- a/packages/google-auth/tests_async/oauth2/test_service_account_async.py +++ b/packages/google-auth/tests_async/oauth2/test_service_account_async.py @@ -139,13 +139,18 @@ def test_with_claims(self): new_credentials = credentials.with_claims({"meep": "moop"}) assert new_credentials._additional_claims == {"meep": "moop"} - def test_with_quota_project(self): + @pytest.mark.asyncio + async def test_with_quota_project(self): credentials = self.make_credentials() new_credentials = credentials.with_quota_project("new-project-456") assert new_credentials.quota_project_id == "new-project-456" + request = mock.create_autospec(transport.Request, instance=True) hdrs = {} - new_credentials.apply(hdrs, token="tok") - assert "x-goog-user-project" in hdrs + new_credentials.token = "tok" + await new_credentials.before_request( + request, "GET", "https://example.com", hdrs + ) + assert hdrs.get("x-goog-user-project") == "new-project-456" def test__make_authorization_grant_assertion(self): credentials = self.make_credentials() From 08a8f9013af8ec0d5e82b7e5d428caded2f41156 Mon Sep 17 00:00:00 2001 From: Min Zhu Date: Mon, 15 Jun 2026 17:46:31 -0400 Subject: [PATCH 080/174] chore: librarian release pull request: 20260615T173024Z (#17468) PR created by the Librarian CLI to initialize a release. Merging this PR will auto trigger a release. Librarian Version: v0.19.0 Language Image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:234b9d1f2ddb057ed7ac6a38db0bf8163d839c65c6cf88ade52530cddebce59e
google-auth: v2.55.0 ## [v2.55.0](https://github.com/googleapis/google-cloud-python/compare/google-auth-v2.54.0...google-auth-v2.55.0) (2026-06-15) ### Features * make RAB feature production ready (#17390) ([af193931](https://github.com/googleapis/google-cloud-python/commit/af193931)) ### Bug Fixes * run async background boundary refresh on detached session (#17441) ([56cbea85](https://github.com/googleapis/google-cloud-python/commit/56cbea85))
--- .librarian/state.yaml | 2 +- librarian.yaml | 2 +- packages/google-auth/CHANGELOG.md | 12 ++++++++++++ packages/google-auth/google/auth/version.py | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index 55a6a3e77498..6eaaa6a34363 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -387,7 +387,7 @@ libraries: - packages/google-area120-tables/docs/ tag_format: '{id}-v{version}' - id: google-auth - version: 2.54.0 + version: 2.55.0 last_generated_commit: "" apis: [] source_roots: diff --git a/librarian.yaml b/librarian.yaml index 78f128c04026..31ab0598c18e 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -228,7 +228,7 @@ libraries: metadata_name_override: area120tables default_version: v1alpha1 - name: google-auth - version: 2.54.0 + version: 2.55.0 python: library_type: AUTH - name: google-auth-httplib2 diff --git a/packages/google-auth/CHANGELOG.md b/packages/google-auth/CHANGELOG.md index 034b15b2c197..15b23d0fab58 100644 --- a/packages/google-auth/CHANGELOG.md +++ b/packages/google-auth/CHANGELOG.md @@ -4,6 +4,18 @@ [1]: https://pypi.org/project/google-auth/#history +## [2.55.0](https://github.com/googleapis/google-cloud-python/compare/google-auth-v2.54.0...google-auth-v2.55.0) (2026-06-15) + + +### Features + +* make RAB feature production ready (#17390) ([af193931e4e38c4b59751edb8e915ae3388b8524](https://github.com/googleapis/google-cloud-python/commit/af193931e4e38c4b59751edb8e915ae3388b8524)) + + +### Bug Fixes + +* run async background boundary refresh on detached session (#17441) ([56cbea8509c66889485b43f2d98d60210eae81bc](https://github.com/googleapis/google-cloud-python/commit/56cbea8509c66889485b43f2d98d60210eae81bc)) + ## [2.54.0](https://github.com/googleapis/google-cloud-python/compare/google-auth-v2.53.0...google-auth-v2.54.0) (2026-06-11) diff --git a/packages/google-auth/google/auth/version.py b/packages/google-auth/google/auth/version.py index 533fd28ff6c1..9df4d8eb58c6 100644 --- a/packages/google-auth/google/auth/version.py +++ b/packages/google-auth/google/auth/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "2.54.0" +__version__ = "2.55.0" From 0aff09d2af5b9b2707ae3e9035e182511927e405 Mon Sep 17 00:00:00 2001 From: sofisl <55454395+sofisl@users.noreply.github.com> Date: Mon, 15 Jun 2026 15:10:57 -0700 Subject: [PATCH 081/174] chore: librarian release pull request: 20260612T171649Z (#17449) PR created by the Librarian CLI to initialize a release. Merging this PR will auto trigger a release. Librarian Version: v0.19.0 Language Image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:234b9d1f2ddb057ed7ac6a38db0bf8163d839c65c6cf88ade52530cddebce59e
google-cloud-bigquery: v3.42.0 ## [v3.42.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-bigquery-v3.41.0...google-cloud-bigquery-v3.42.0) (2026-06-12) ### Features * drop Python 3.7-3.9 support and regenerate (#17187) ([494abcdf](https://github.com/googleapis/google-cloud-python/commit/494abcdf)) ### Bug Fixes * include pyopenssl as a dependency (#17345) ([12817900](https://github.com/googleapis/google-cloud-python/commit/12817900)) * bump requests from 2.21.0 to 2.33.0 in /packages/google-cloud-bigquery (#17192) ([5283c926](https://github.com/googleapis/google-cloud-python/commit/5283c926)) * bump tqdm from 4.23.4 to 4.66.3 in /packages/google-cloud-bigquery (#17194) ([8cda5fe1](https://github.com/googleapis/google-cloud-python/commit/8cda5fe1)) * bump opentelemetry-instrumentation from 0.37b0 to 0.41b0 in /packages/google-cloud-bigquery (#17195) ([f530a2c6](https://github.com/googleapis/google-cloud-python/commit/f530a2c6)) * allow multi-part dataset IDs to support BigLake tables (#17137) ([f93911c0](https://github.com/googleapis/google-cloud-python/commit/f93911c0)) ### Documentation * clarify Quickstart POST example (<a href="https://redirect.github.com/psf/requests/issues/6960">#6960</a>)</li> <li>Additional commits viewable in <a href="https://github.com/psf/requests/compare/v2.21.0...v2.33.0">compare view</a></li> </ul> </details> <br /> ([5283c926](https://github.com/googleapis/google-cloud-python/commit/5283c926)) * fix FAQ grammar in httplib2 example</li> <li><a href="https://github.com/psf/requests/commit/774a0b837a194ee885d4fdd9ca947900cc3daf71"><code>774a0b8</code></a> ([5283c926](https://github.com/googleapis/google-cloud-python/commit/5283c926)) * same block as other sections</li> <li><a href="https://github.com/psf/requests/commit/9c72a41bec8597f948c9d8caa5dc3f12273b3303"><code>9c72a41</code></a> Bump github/codeql-action from 4.33.0 to 4.34.1</li> <li><a href="https://github.com/psf/requests/commit/ebf71906798ec82f34e07d3168f8b8aecaf8a3be"><code>ebf7190</code></a> Bump github/codeql-action from 4.32.0 to 4.33.0</li> <li><a href="https://github.com/psf/requests/commit/0e4ae38f0c93d4f92a96c774bd52c069d12a4798"><code>0e4ae38</code></a> ([5283c926](https://github.com/googleapis/google-cloud-python/commit/5283c926)) * exclude Response.is_permanent_redirect from API docs (<a href="https://redirect.github.com/psf/requests/issues/7244">#7244</a>)</li> <li><a href="https://github.com/psf/requests/commit/d568f47278492e630cc990a259047c67991d007a"><code>d568f47</code></a> ([5283c926](https://github.com/googleapis/google-cloud-python/commit/5283c926))
--- .librarian/state.yaml | 2 +- librarian.yaml | 2 +- packages/google-cloud-bigquery/CHANGELOG.md | 24 +++++++++++++++++++ .../google/cloud/bigquery/version.py | 2 +- 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index 6eaaa6a34363..020ac1dbf812 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -1139,7 +1139,7 @@ libraries: - packages/google-cloud-biglake-hive/docs/ tag_format: '{id}-v{version}' - id: google-cloud-bigquery - version: 3.41.0 + version: 3.42.0 last_generated_commit: "" apis: [] source_roots: diff --git a/librarian.yaml b/librarian.yaml index 31ab0598c18e..34509c96c53d 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -538,7 +538,7 @@ libraries: python: default_version: v1beta - name: google-cloud-bigquery - version: 3.41.0 + version: 3.42.0 python: library_type: GAPIC_COMBO metadata_name_override: bigquery diff --git a/packages/google-cloud-bigquery/CHANGELOG.md b/packages/google-cloud-bigquery/CHANGELOG.md index 0310cc44182f..978555bf3a03 100644 --- a/packages/google-cloud-bigquery/CHANGELOG.md +++ b/packages/google-cloud-bigquery/CHANGELOG.md @@ -4,6 +4,30 @@ [1]: https://pypi.org/project/google-cloud-bigquery/#history +## [3.42.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-bigquery-v3.41.0...google-cloud-bigquery-v3.42.0) (2026-06-12) + + +### Documentation + +* fix FAQ grammar in httplib2 example
  • 774a0b8 ([5283c92639438d9e4dd3519d00a64755e87ea669](https://github.com/googleapis/google-cloud-python/commit/5283c92639438d9e4dd3519d00a64755e87ea669)) +* same block as other sections
  • 9c72a41 Bump github/codeql-action from 4.33.0 to 4.34.1
  • ebf7190 Bump github/codeql-action from 4.32.0 to 4.33.0
  • 0e4ae38 ([5283c92639438d9e4dd3519d00a64755e87ea669](https://github.com/googleapis/google-cloud-python/commit/5283c92639438d9e4dd3519d00a64755e87ea669)) +* exclude Response.is_permanent_redirect from API docs (#7244)
  • d568f47 ([5283c92639438d9e4dd3519d00a64755e87ea669](https://github.com/googleapis/google-cloud-python/commit/5283c92639438d9e4dd3519d00a64755e87ea669)) +* clarify Quickstart POST example (#6960)
  • Additional commits viewable in compare view

  • ([5283c92639438d9e4dd3519d00a64755e87ea669](https://github.com/googleapis/google-cloud-python/commit/5283c92639438d9e4dd3519d00a64755e87ea669)) + + +### Features + +* drop Python 3.7-3.9 support and regenerate (#17187) ([494abcdfc2bc4f28be9477db86fde149a3af6b66](https://github.com/googleapis/google-cloud-python/commit/494abcdfc2bc4f28be9477db86fde149a3af6b66)) + + +### Bug Fixes + +* include pyopenssl as a dependency (#17345) ([12817900fd11e68067a5ce9b4254fa8703e864d8](https://github.com/googleapis/google-cloud-python/commit/12817900fd11e68067a5ce9b4254fa8703e864d8)) +* bump requests from 2.21.0 to 2.33.0 in /packages/google-cloud-bigquery (#17192) ([5283c92639438d9e4dd3519d00a64755e87ea669](https://github.com/googleapis/google-cloud-python/commit/5283c92639438d9e4dd3519d00a64755e87ea669)) +* bump tqdm from 4.23.4 to 4.66.3 in /packages/google-cloud-bigquery (#17194) ([8cda5fe1c6aec69af209851c778183e1bb673f07](https://github.com/googleapis/google-cloud-python/commit/8cda5fe1c6aec69af209851c778183e1bb673f07)) +* bump opentelemetry-instrumentation from 0.37b0 to 0.41b0 in /packages/google-cloud-bigquery (#17195) ([f530a2c64fb468c611cfe23c833efdb0b9ea45e1](https://github.com/googleapis/google-cloud-python/commit/f530a2c64fb468c611cfe23c833efdb0b9ea45e1)) +* allow multi-part dataset IDs to support BigLake tables (#17137) ([f93911c0a7f163a8d0374f96cbb73cce75e8dc42](https://github.com/googleapis/google-cloud-python/commit/f93911c0a7f163a8d0374f96cbb73cce75e8dc42)) + ## [3.41.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-bigquery-v3.40.1...google-cloud-bigquery-v3.41.0) (2026-03-26) diff --git a/packages/google-cloud-bigquery/google/cloud/bigquery/version.py b/packages/google-cloud-bigquery/google/cloud/bigquery/version.py index 7d799125f88a..24c157c62aca 100644 --- a/packages/google-cloud-bigquery/google/cloud/bigquery/version.py +++ b/packages/google-cloud-bigquery/google/cloud/bigquery/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "3.41.0" +__version__ = "3.42.0" From b5e0d4bd72685f0077e028bb5afd68721c84741d Mon Sep 17 00:00:00 2001 From: Daniel Sanche Date: Mon, 15 Jun 2026 18:08:23 -0700 Subject: [PATCH 082/174] chore(tests): re-enable cover tests (#17454) The cover CI test was silently failing open. This PR re-enables it Fixes https://github.com/googleapis/google-cloud-python/issues/17456 --- .github/workflows/unittest.yml | 96 +++++++++++++++++-- .../%name_%version/%sub/test_%service.py.j2 | 6 ++ .../gapic/%name_%version/%sub/test_macros.j2 | 8 ++ .../unit/gapic/asset_v1/test_asset_service.py | 56 +++++++++++ .../unit/gapic/eventarc_v1/test_eventarc.py | 72 ++++++++++++++ .../logging_v2/test_config_service_v2.py | 25 +++++ .../logging_v2/test_logging_service_v2.py | 15 +++ .../logging_v2/test_metrics_service_v2.py | 5 + .../logging_v2/test_config_service_v2.py | 25 +++++ .../logging_v2/test_logging_service_v2.py | 15 +++ .../logging_v2/test_metrics_service_v2.py | 5 + .../unit/gapic/redis_v1/test_cloud_redis.py | 8 ++ .../unit/gapic/redis_v1/test_cloud_redis.py | 8 ++ .../test_storage_batch_operations.py | 16 ++++ packages/gcp-sphinx-docfx-yaml/.coveragerc | 31 ++++++ packages/gcp-sphinx-docfx-yaml/noxfile.py | 13 ++- .../.coveragerc | 34 +++++++ packages/google-cloud-audit-log/.coveragerc | 34 +++++++ .../unit/v1/test_pipeline_expressions.py | 3 +- packages/google-cloud-testutils/.coveragerc | 31 ++++++ packages/googleapis-common-protos/.coveragerc | 34 +++++++ packages/grpc-google-iam-v1/.coveragerc | 34 +++++++ 22 files changed, 562 insertions(+), 12 deletions(-) create mode 100644 packages/gcp-sphinx-docfx-yaml/.coveragerc create mode 100644 packages/google-cloud-access-context-manager/.coveragerc create mode 100644 packages/google-cloud-audit-log/.coveragerc create mode 100644 packages/google-cloud-testutils/.coveragerc create mode 100644 packages/googleapis-common-protos/.coveragerc create mode 100644 packages/grpc-google-iam-v1/.coveragerc diff --git a/.github/workflows/unittest.yml b/.github/workflows/unittest.yml index 83a8280132e9..e231533e0ee1 100644 --- a/.github/workflows/unittest.yml +++ b/.github/workflows/unittest.yml @@ -36,7 +36,7 @@ jobs: python -m pip install nox - name: Run unit tests env: - COVERAGE_FILE: .coverage-${{ matrix.python }} + COVERAGE_FILE: ${{ github.workspace }}/.coverage-${{ matrix.python }} BUILD_TYPE: presubmit TARGET_BRANCH: ${{ github.base_ref || github.event.merge_group.base_ref }} TEST_TYPE: unit @@ -46,8 +46,9 @@ jobs: - name: Upload coverage results uses: actions/upload-artifact@v4 with: - name: coverage-artifact-${{ '{{' }} matrix.python {{ '}}' }} + name: coverage-artifact-${{ matrix.python }} path: .coverage-${{ matrix.python }} + include-hidden-files: true cover: runs-on: ubuntu-latest @@ -67,20 +68,97 @@ jobs: python-version: "3.10" - name: Set number of files changes in packages directory id: packages - run: echo "::set-output name=num_files_changed::$(git diff HEAD~1 -- packages | wc -l)" + run: | + git diff HEAD~1 -- packages > /dev/null + num_files_changed=$(git diff HEAD~1 -- packages | wc -l | tr -d ' ') + echo "num_files_changed=${num_files_changed}" >> "$GITHUB_OUTPUT" - name: Install coverage - if: steps.packages.num_files_changed > 0 + if: ${{ steps.packages.outputs.num_files_changed > 0 }} run: | python -m pip install --upgrade setuptools pip wheel python -m pip install coverage - name: Download coverage results - if: ${{ steps.date.packages.num_files_changed > 0 }} + if: ${{ steps.packages.outputs.num_files_changed > 0 }} uses: actions/download-artifact@v4 with: path: .coverage-results/ - name: Report coverage results - if: ${{ steps.date.packages.num_files_changed > 0 }} + if: ${{ steps.packages.outputs.num_files_changed > 0 }} + env: + # TODO: default to 100% coverage after next gapic-generator release + # https://github.com/googleapis/google-cloud-python/issues/17459 + DEFAULT_FAIL_UNDER: 99 run: | - find .coverage-results -type f -name '*.zip' -exec unzip {} \; - coverage combine .coverage-results/**/.coverage* - coverage report --show-missing --fail-under=100 + if [ -d .coverage-results ]; then + # Unzip any zipped coverage results + find .coverage-results -type f -name '*.zip' -exec unzip -o {} \; + + # Find all coverage files and combine them. + # We find files starting with .coverage (excluding .coveragerc files and templates) + coverage_files=$(find .coverage-results . -type f -name '.coverage*' ! -name '.coveragerc*') + if [ -n "${coverage_files}" ]; then + coverage combine ${coverage_files} + else + echo "Error: No coverage files found to combine." + exit 1 + fi + + # Find all modified packages + modified_packages=$(git diff --name-only HEAD~1 -- packages | cut -d/ -f1,2 | sort -u) + + failed_packages=() + passed_packages=() + + for pkg in ${modified_packages}; do + if [ -d "${pkg}" ]; then + echo "============================================================" + echo "Evaluating coverage for package: ${pkg}" + echo "============================================================" + + set +e + if [ -f "${pkg}/.coveragerc" ]; then + echo "Using package-specific configuration: ${pkg}/.coveragerc" + # If fail_under is specified in the package-specific .coveragerc, coverage report + # will automatically enforce it. Otherwise, we enforce the default. + if grep -q "fail_under" "${pkg}/.coveragerc"; then + coverage report --rcfile="${pkg}/.coveragerc" --include="${pkg}/**" + else + echo "No fail_under specified in ${pkg}/.coveragerc, enforcing default" + coverage report --rcfile="${pkg}/.coveragerc" --include="${pkg}/**" --fail-under="${DEFAULT_FAIL_UNDER}" + fi + else + echo "No .coveragerc found for ${pkg}, enforcing default" + coverage report --include="${pkg}/**" --fail-under="${DEFAULT_FAIL_UNDER}" + fi + status=$? + set -e + + if [ ${status} -ne 0 ]; then + failed_packages+=("${pkg}") + else + passed_packages+=("${pkg}") + fi + fi + done + + echo "============================================================" + echo "Coverage Evaluation Summary" + echo "============================================================" + if [ ${#passed_packages[@]} -gt 0 ]; then + echo "Passed packages:" + for pkg in "${passed_packages[@]}"; do + echo " - ${pkg}" + done + fi + if [ ${#failed_packages[@]} -gt 0 ]; then + echo "Failed packages:" + for pkg in "${failed_packages[@]}"; do + echo " - ${pkg}" + done + exit 1 + fi + else + echo "Error: No coverage results were downloaded from the unit test jobs." + echo "This usually means the unit tests did not run or failed to upload their coverage files." + exit 1 + fi diff --git a/packages/gapic-generator/gapic/ads-templates/tests/unit/gapic/%name_%version/%sub/test_%service.py.j2 b/packages/gapic-generator/gapic/ads-templates/tests/unit/gapic/%name_%version/%sub/test_%service.py.j2 index e8953eb0742e..e6ffe31a47ae 100644 --- a/packages/gapic-generator/gapic/ads-templates/tests/unit/gapic/%name_%version/%sub/test_%service.py.j2 +++ b/packages/gapic-generator/gapic/ads-templates/tests/unit/gapic/%name_%version/%sub/test_%service.py.j2 @@ -965,6 +965,9 @@ def test_{{ method_name }}_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, {{ method.paged_result_field.type.ident }}) @@ -1738,6 +1741,9 @@ def test_{{ method_name }}_rest_pager(transport: str = 'rest'): pager = client.{{ method_name }}(request=sample_request) + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + {% if method.paged_result_field.map %} assert isinstance(pager.get('a'), {{ method.paged_result_field.type.fields.get('value').ident }}) assert pager.get('h') is None diff --git a/packages/gapic-generator/gapic/templates/tests/unit/gapic/%name_%version/%sub/test_macros.j2 b/packages/gapic-generator/gapic/templates/tests/unit/gapic/%name_%version/%sub/test_macros.j2 index a612b9397f65..bccc38afe2a1 100644 --- a/packages/gapic-generator/gapic/templates/tests/unit/gapic/%name_%version/%sub/test_macros.j2 +++ b/packages/gapic-generator/gapic/templates/tests/unit/gapic/%name_%version/%sub/test_macros.j2 @@ -746,6 +746,9 @@ def test_{{ method_name }}_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 {% if method.paged_result_field.type.ident|string == 'struct_pb2.ListValue' %} @@ -902,6 +905,8 @@ async def test_{{ method_name }}_async_pager(): ) async_pager = await client.{{ method_name }}(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -1425,6 +1430,9 @@ def test_{{ method_name }}_rest_pager(transport: str = 'rest'): pager = client.{{ method_name }}(request=sample_request) + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + {% if method.paged_result_field.map %} assert isinstance(pager.get('a'), {{ method.paged_result_field.type.fields.get('value').ident }}) assert pager.get('h') is None diff --git a/packages/gapic-generator/tests/integration/goldens/asset/tests/unit/gapic/asset_v1/test_asset_service.py b/packages/gapic-generator/tests/integration/goldens/asset/tests/unit/gapic/asset_v1/test_asset_service.py index b6bbf1cdc830..ea110a38acc3 100755 --- a/packages/gapic-generator/tests/integration/goldens/asset/tests/unit/gapic/asset_v1/test_asset_service.py +++ b/packages/gapic-generator/tests/integration/goldens/asset/tests/unit/gapic/asset_v1/test_asset_service.py @@ -1577,6 +1577,9 @@ def test_list_assets_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, assets.Asset) @@ -1663,6 +1666,8 @@ async def test_list_assets_async_pager(): ) async_pager = await client.list_assets(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -3912,6 +3917,9 @@ def test_search_all_resources_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, assets.ResourceSearchResult) @@ -3998,6 +4006,8 @@ async def test_search_all_resources_async_pager(): ) async_pager = await client.search_all_resources(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -4431,6 +4441,9 @@ def test_search_all_iam_policies_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, assets.IamPolicySearchResult) @@ -4517,6 +4530,8 @@ async def test_search_all_iam_policies_async_pager(): ) async_pager = await client.search_all_iam_policies(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -6524,6 +6539,9 @@ def test_list_saved_queries_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, asset_service.SavedQuery) @@ -6610,6 +6628,8 @@ async def test_list_saved_queries_async_pager(): ) async_pager = await client.list_saved_queries(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -7908,6 +7928,9 @@ def test_analyze_org_policies_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, asset_service.AnalyzeOrgPoliciesResponse.OrgPolicyResult) @@ -7994,6 +8017,8 @@ async def test_analyze_org_policies_async_pager(): ) async_pager = await client.analyze_org_policies(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -8437,6 +8462,9 @@ def test_analyze_org_policy_governed_containers_pager(transport_name: str = "grp assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, asset_service.AnalyzeOrgPolicyGovernedContainersResponse.GovernedContainer) @@ -8523,6 +8551,8 @@ async def test_analyze_org_policy_governed_containers_async_pager(): ) async_pager = await client.analyze_org_policy_governed_containers(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -8966,6 +8996,9 @@ def test_analyze_org_policy_governed_assets_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, asset_service.AnalyzeOrgPolicyGovernedAssetsResponse.GovernedAsset) @@ -9052,6 +9085,8 @@ async def test_analyze_org_policy_governed_assets_async_pager(): ) async_pager = await client.analyze_org_policy_governed_assets(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -9442,6 +9477,9 @@ def test_list_assets_rest_pager(transport: str = 'rest'): pager = client.list_assets(request=sample_request) + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, assets.Asset) @@ -10616,6 +10654,9 @@ def test_search_all_resources_rest_pager(transport: str = 'rest'): pager = client.search_all_resources(request=sample_request) + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, assets.ResourceSearchResult) @@ -10848,6 +10889,9 @@ def test_search_all_iam_policies_rest_pager(transport: str = 'rest'): pager = client.search_all_iam_policies(request=sample_request) + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, assets.IamPolicySearchResult) @@ -11884,6 +11928,9 @@ def test_list_saved_queries_rest_pager(transport: str = 'rest'): pager = client.list_saved_queries(request=sample_request) + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, asset_service.SavedQuery) @@ -12581,6 +12628,9 @@ def test_analyze_org_policies_rest_pager(transport: str = 'rest'): pager = client.analyze_org_policies(request=sample_request) + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, asset_service.AnalyzeOrgPoliciesResponse.OrgPolicyResult) @@ -12826,6 +12876,9 @@ def test_analyze_org_policy_governed_containers_rest_pager(transport: str = 'res pager = client.analyze_org_policy_governed_containers(request=sample_request) + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, asset_service.AnalyzeOrgPolicyGovernedContainersResponse.GovernedContainer) @@ -13071,6 +13124,9 @@ def test_analyze_org_policy_governed_assets_rest_pager(transport: str = 'rest'): pager = client.analyze_org_policy_governed_assets(request=sample_request) + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, asset_service.AnalyzeOrgPolicyGovernedAssetsResponse.GovernedAsset) diff --git a/packages/gapic-generator/tests/integration/goldens/eventarc/tests/unit/gapic/eventarc_v1/test_eventarc.py b/packages/gapic-generator/tests/integration/goldens/eventarc/tests/unit/gapic/eventarc_v1/test_eventarc.py index 538dd2b2bac4..533e401eb1e7 100755 --- a/packages/gapic-generator/tests/integration/goldens/eventarc/tests/unit/gapic/eventarc_v1/test_eventarc.py +++ b/packages/gapic-generator/tests/integration/goldens/eventarc/tests/unit/gapic/eventarc_v1/test_eventarc.py @@ -1706,6 +1706,9 @@ def test_list_triggers_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, trigger.Trigger) @@ -1792,6 +1795,8 @@ async def test_list_triggers_async_pager(): ) async_pager = await client.list_triggers(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -3554,6 +3559,9 @@ def test_list_channels_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, channel.Channel) @@ -3640,6 +3648,8 @@ async def test_list_channels_async_pager(): ) async_pager = await client.list_channels(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -5361,6 +5371,9 @@ def test_list_providers_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, discovery.Provider) @@ -5447,6 +5460,8 @@ async def test_list_providers_async_pager(): ) async_pager = await client.list_providers(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -6191,6 +6206,9 @@ def test_list_channel_connections_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, channel_connection.ChannelConnection) @@ -6277,6 +6295,8 @@ async def test_list_channel_connections_async_pager(): ) async_pager = await client.list_channel_connections(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -8319,6 +8339,9 @@ def test_list_message_buses_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, message_bus.MessageBus) @@ -8405,6 +8428,8 @@ async def test_list_message_buses_async_pager(): ) async_pager = await client.list_message_buses(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -8832,6 +8857,9 @@ def test_list_message_bus_enrollments_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, str) @@ -8918,6 +8946,8 @@ async def test_list_message_bus_enrollments_async_pager(): ) async_pager = await client.list_message_bus_enrollments(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -10671,6 +10701,9 @@ def test_list_enrollments_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, enrollment.Enrollment) @@ -10757,6 +10790,8 @@ async def test_list_enrollments_async_pager(): ) async_pager = await client.list_enrollments(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -12506,6 +12541,9 @@ def test_list_pipelines_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, pipeline.Pipeline) @@ -12592,6 +12630,8 @@ async def test_list_pipelines_async_pager(): ) async_pager = await client.list_pipelines(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -14341,6 +14381,9 @@ def test_list_google_api_sources_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, google_api_source.GoogleApiSource) @@ -14427,6 +14470,8 @@ async def test_list_google_api_sources_async_pager(): ) async_pager = await client.list_google_api_sources(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -15861,6 +15906,9 @@ def test_list_triggers_rest_pager(transport: str = 'rest'): pager = client.list_triggers(request=sample_request) + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, trigger.Trigger) @@ -16703,6 +16751,9 @@ def test_list_channels_rest_pager(transport: str = 'rest'): pager = client.list_channels(request=sample_request) + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, channel.Channel) @@ -17541,6 +17592,9 @@ def test_list_providers_rest_pager(transport: str = 'rest'): pager = client.list_providers(request=sample_request) + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, discovery.Provider) @@ -17937,6 +17991,9 @@ def test_list_channel_connections_rest_pager(transport: str = 'rest'): pager = client.list_channel_connections(request=sample_request) + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, channel_connection.ChannelConnection) @@ -19013,6 +19070,9 @@ def test_list_message_buses_rest_pager(transport: str = 'rest'): pager = client.list_message_buses(request=sample_request) + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, message_bus.MessageBus) @@ -19243,6 +19303,9 @@ def test_list_message_bus_enrollments_rest_pager(transport: str = 'rest'): pager = client.list_message_bus_enrollments(request=sample_request) + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, str) @@ -20156,6 +20219,9 @@ def test_list_enrollments_rest_pager(transport: str = 'rest'): pager = client.list_enrollments(request=sample_request) + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, enrollment.Enrollment) @@ -21069,6 +21135,9 @@ def test_list_pipelines_rest_pager(transport: str = 'rest'): pager = client.list_pipelines(request=sample_request) + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, pipeline.Pipeline) @@ -21982,6 +22051,9 @@ def test_list_google_api_sources_rest_pager(transport: str = 'rest'): pager = client.list_google_api_sources(request=sample_request) + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, google_api_source.GoogleApiSource) diff --git a/packages/gapic-generator/tests/integration/goldens/logging/tests/unit/gapic/logging_v2/test_config_service_v2.py b/packages/gapic-generator/tests/integration/goldens/logging/tests/unit/gapic/logging_v2/test_config_service_v2.py index 57522704960d..eada5b433c55 100755 --- a/packages/gapic-generator/tests/integration/goldens/logging/tests/unit/gapic/logging_v2/test_config_service_v2.py +++ b/packages/gapic-generator/tests/integration/goldens/logging/tests/unit/gapic/logging_v2/test_config_service_v2.py @@ -1323,6 +1323,9 @@ def test_list_buckets_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, logging_config.LogBucket) @@ -1409,6 +1412,8 @@ async def test_list_buckets_async_pager(): ) async_pager = await client.list_buckets(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -3493,6 +3498,9 @@ def test_list_views_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, logging_config.LogView) @@ -3579,6 +3587,8 @@ async def test_list_views_async_pager(): ) async_pager = await client.list_views(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -4926,6 +4936,9 @@ def test_list_sinks_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, logging_config.LogSink) @@ -5012,6 +5025,8 @@ async def test_list_sinks_async_pager(): ) async_pager = await client.list_sinks(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -7431,6 +7446,9 @@ def test_list_links_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, logging_config.Link) @@ -7517,6 +7535,8 @@ async def test_list_links_async_pager(): ) async_pager = await client.list_links(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -8253,6 +8273,9 @@ def test_list_exclusions_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, logging_config.LogExclusion) @@ -8339,6 +8362,8 @@ async def test_list_exclusions_async_pager(): ) async_pager = await client.list_exclusions(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) diff --git a/packages/gapic-generator/tests/integration/goldens/logging/tests/unit/gapic/logging_v2/test_logging_service_v2.py b/packages/gapic-generator/tests/integration/goldens/logging/tests/unit/gapic/logging_v2/test_logging_service_v2.py index 544b2fd557db..65559a5d1073 100755 --- a/packages/gapic-generator/tests/integration/goldens/logging/tests/unit/gapic/logging_v2/test_logging_service_v2.py +++ b/packages/gapic-generator/tests/integration/goldens/logging/tests/unit/gapic/logging_v2/test_logging_service_v2.py @@ -1856,6 +1856,9 @@ def test_list_log_entries_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, log_entry.LogEntry) @@ -1942,6 +1945,8 @@ async def test_list_log_entries_async_pager(): ) async_pager = await client.list_log_entries(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -2210,6 +2215,9 @@ def test_list_monitored_resource_descriptors_pager(transport_name: str = "grpc") assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, monitored_resource_pb2.MonitoredResourceDescriptor) @@ -2296,6 +2304,8 @@ async def test_list_monitored_resource_descriptors_async_pager(): ) async_pager = await client.list_monitored_resource_descriptors(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -2719,6 +2729,9 @@ def test_list_logs_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, str) @@ -2805,6 +2818,8 @@ async def test_list_logs_async_pager(): ) async_pager = await client.list_logs(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) diff --git a/packages/gapic-generator/tests/integration/goldens/logging/tests/unit/gapic/logging_v2/test_metrics_service_v2.py b/packages/gapic-generator/tests/integration/goldens/logging/tests/unit/gapic/logging_v2/test_metrics_service_v2.py index 9f598dbcf95e..90cdab2be2b2 100755 --- a/packages/gapic-generator/tests/integration/goldens/logging/tests/unit/gapic/logging_v2/test_metrics_service_v2.py +++ b/packages/gapic-generator/tests/integration/goldens/logging/tests/unit/gapic/logging_v2/test_metrics_service_v2.py @@ -1323,6 +1323,9 @@ def test_list_log_metrics_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, logging_metrics.LogMetric) @@ -1409,6 +1412,8 @@ async def test_list_log_metrics_async_pager(): ) async_pager = await client.list_log_metrics(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) diff --git a/packages/gapic-generator/tests/integration/goldens/logging_internal/tests/unit/gapic/logging_v2/test_config_service_v2.py b/packages/gapic-generator/tests/integration/goldens/logging_internal/tests/unit/gapic/logging_v2/test_config_service_v2.py index 9152aa72c6a1..9eec837e6f58 100755 --- a/packages/gapic-generator/tests/integration/goldens/logging_internal/tests/unit/gapic/logging_v2/test_config_service_v2.py +++ b/packages/gapic-generator/tests/integration/goldens/logging_internal/tests/unit/gapic/logging_v2/test_config_service_v2.py @@ -1323,6 +1323,9 @@ def test_list_buckets_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, logging_config.LogBucket) @@ -1409,6 +1412,8 @@ async def test_list_buckets_async_pager(): ) async_pager = await client.list_buckets(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -3493,6 +3498,9 @@ def test__list_views_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, logging_config.LogView) @@ -3579,6 +3587,8 @@ async def test__list_views_async_pager(): ) async_pager = await client._list_views(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -4926,6 +4936,9 @@ def test__list_sinks_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, logging_config.LogSink) @@ -5012,6 +5025,8 @@ async def test__list_sinks_async_pager(): ) async_pager = await client._list_sinks(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -7431,6 +7446,9 @@ def test__list_links_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, logging_config.Link) @@ -7517,6 +7535,8 @@ async def test__list_links_async_pager(): ) async_pager = await client._list_links(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -8253,6 +8273,9 @@ def test__list_exclusions_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, logging_config.LogExclusion) @@ -8339,6 +8362,8 @@ async def test__list_exclusions_async_pager(): ) async_pager = await client._list_exclusions(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) diff --git a/packages/gapic-generator/tests/integration/goldens/logging_internal/tests/unit/gapic/logging_v2/test_logging_service_v2.py b/packages/gapic-generator/tests/integration/goldens/logging_internal/tests/unit/gapic/logging_v2/test_logging_service_v2.py index 544b2fd557db..65559a5d1073 100755 --- a/packages/gapic-generator/tests/integration/goldens/logging_internal/tests/unit/gapic/logging_v2/test_logging_service_v2.py +++ b/packages/gapic-generator/tests/integration/goldens/logging_internal/tests/unit/gapic/logging_v2/test_logging_service_v2.py @@ -1856,6 +1856,9 @@ def test_list_log_entries_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, log_entry.LogEntry) @@ -1942,6 +1945,8 @@ async def test_list_log_entries_async_pager(): ) async_pager = await client.list_log_entries(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -2210,6 +2215,9 @@ def test_list_monitored_resource_descriptors_pager(transport_name: str = "grpc") assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, monitored_resource_pb2.MonitoredResourceDescriptor) @@ -2296,6 +2304,8 @@ async def test_list_monitored_resource_descriptors_async_pager(): ) async_pager = await client.list_monitored_resource_descriptors(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -2719,6 +2729,9 @@ def test_list_logs_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, str) @@ -2805,6 +2818,8 @@ async def test_list_logs_async_pager(): ) async_pager = await client.list_logs(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) diff --git a/packages/gapic-generator/tests/integration/goldens/logging_internal/tests/unit/gapic/logging_v2/test_metrics_service_v2.py b/packages/gapic-generator/tests/integration/goldens/logging_internal/tests/unit/gapic/logging_v2/test_metrics_service_v2.py index 0fc62ce795c0..310677b64bc6 100755 --- a/packages/gapic-generator/tests/integration/goldens/logging_internal/tests/unit/gapic/logging_v2/test_metrics_service_v2.py +++ b/packages/gapic-generator/tests/integration/goldens/logging_internal/tests/unit/gapic/logging_v2/test_metrics_service_v2.py @@ -1323,6 +1323,9 @@ def test__list_log_metrics_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, logging_metrics.LogMetric) @@ -1409,6 +1412,8 @@ async def test__list_log_metrics_async_pager(): ) async_pager = await client._list_log_metrics(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) diff --git a/packages/gapic-generator/tests/integration/goldens/redis/tests/unit/gapic/redis_v1/test_cloud_redis.py b/packages/gapic-generator/tests/integration/goldens/redis/tests/unit/gapic/redis_v1/test_cloud_redis.py index 7d14d15849c9..8ca1fb5194a6 100755 --- a/packages/gapic-generator/tests/integration/goldens/redis/tests/unit/gapic/redis_v1/test_cloud_redis.py +++ b/packages/gapic-generator/tests/integration/goldens/redis/tests/unit/gapic/redis_v1/test_cloud_redis.py @@ -1356,6 +1356,9 @@ def test_list_instances_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, cloud_redis.Instance) @@ -1442,6 +1445,8 @@ async def test_list_instances_async_pager(): ) async_pager = await client.list_instances(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -5063,6 +5068,9 @@ def test_list_instances_rest_pager(transport: str = 'rest'): pager = client.list_instances(request=sample_request) + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, cloud_redis.Instance) diff --git a/packages/gapic-generator/tests/integration/goldens/redis_selective/tests/unit/gapic/redis_v1/test_cloud_redis.py b/packages/gapic-generator/tests/integration/goldens/redis_selective/tests/unit/gapic/redis_v1/test_cloud_redis.py index 1076ace45ba6..3f6b7aa521f3 100755 --- a/packages/gapic-generator/tests/integration/goldens/redis_selective/tests/unit/gapic/redis_v1/test_cloud_redis.py +++ b/packages/gapic-generator/tests/integration/goldens/redis_selective/tests/unit/gapic/redis_v1/test_cloud_redis.py @@ -1356,6 +1356,9 @@ def test_list_instances_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, cloud_redis.Instance) @@ -1442,6 +1445,8 @@ async def test_list_instances_async_pager(): ) async_pager = await client.list_instances(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -3111,6 +3116,9 @@ def test_list_instances_rest_pager(transport: str = 'rest'): pager = client.list_instances(request=sample_request) + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, cloud_redis.Instance) diff --git a/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/tests/unit/gapic/storagebatchoperations_v1/test_storage_batch_operations.py b/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/tests/unit/gapic/storagebatchoperations_v1/test_storage_batch_operations.py index 66367a27be49..5c53e97f8d12 100755 --- a/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/tests/unit/gapic/storagebatchoperations_v1/test_storage_batch_operations.py +++ b/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/tests/unit/gapic/storagebatchoperations_v1/test_storage_batch_operations.py @@ -1428,6 +1428,9 @@ def test_list_jobs_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, storage_batch_operations_types.Job) @@ -1514,6 +1517,8 @@ async def test_list_jobs_async_pager(): ) async_pager = await client.list_jobs(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -3246,6 +3251,9 @@ def test_list_bucket_operations_pager(transport_name: str = "grpc"): assert pager._retry == retry assert pager._timeout == timeout + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, storage_batch_operations_types.BucketOperation) @@ -3332,6 +3340,8 @@ async def test_list_bucket_operations_async_pager(): ) async_pager = await client.list_bucket_operations(request={},) assert async_pager.next_page_token == 'abc' + assert str(async_pager).startswith(f'{async_pager.__class__.__name__}<') + responses = [] async for response in async_pager: # pragma: no branch responses.append(response) @@ -3924,6 +3934,9 @@ def test_list_jobs_rest_pager(transport: str = 'rest'): pager = client.list_jobs(request=sample_request) + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, storage_batch_operations_types.Job) @@ -4866,6 +4879,9 @@ def test_list_bucket_operations_rest_pager(transport: str = 'rest'): pager = client.list_bucket_operations(request=sample_request) + assert pager.next_page_token == 'abc' + assert str(pager).startswith(f'{pager.__class__.__name__}<') + results = list(pager) assert len(results) == 6 assert all(isinstance(i, storage_batch_operations_types.BucketOperation) diff --git a/packages/gcp-sphinx-docfx-yaml/.coveragerc b/packages/gcp-sphinx-docfx-yaml/.coveragerc new file mode 100644 index 000000000000..18b2efb98608 --- /dev/null +++ b/packages/gcp-sphinx-docfx-yaml/.coveragerc @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2026 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 +# +# https://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. + +[run] +branch = True + +[report] +fail_under = 40 +show_missing = True +exclude_lines = + # Re-enable the standard pragma + pragma: NO COVER + # Ignore debug-only repr + def __repr__ + # Ignore abstract methods + raise NotImplementedError +omit = + */site-packages/*.py diff --git a/packages/gcp-sphinx-docfx-yaml/noxfile.py b/packages/gcp-sphinx-docfx-yaml/noxfile.py index 7e17f37c8ffa..ba5658c0e24f 100644 --- a/packages/gcp-sphinx-docfx-yaml/noxfile.py +++ b/packages/gcp-sphinx-docfx-yaml/noxfile.py @@ -140,8 +140,17 @@ def unit(session): # Track 3.14 compatibility as upstream dependencies stabilize. _skip_python_session(session, ["3.7", "3.8", "3.9", "3.11", "3.12", "3.13", "3.14"]) session.install("-r", "requirements.txt") - session.install("pytest") - session.run("pytest", "tests") + session.install("pytest", "pytest-cov") + session.run( + "pytest", + "--cov=docfx_yaml", + "--cov=tests", + "--cov-append", + "--cov-config=.coveragerc", + "--cov-report=", + "--cov-fail-under=0", + "tests", + ) @nox.session(python="3.10") diff --git a/packages/google-cloud-access-context-manager/.coveragerc b/packages/google-cloud-access-context-manager/.coveragerc new file mode 100644 index 000000000000..b609b649b442 --- /dev/null +++ b/packages/google-cloud-access-context-manager/.coveragerc @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2026 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 +# +# https://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. + +[run] +branch = True +omit = + google/__init__.py + +[report] +fail_under = 99 +show_missing = True +exclude_lines = + # Re-enable the standard pragma + pragma: NO COVER + # Ignore debug-only repr + def __repr__ + # Ignore abstract methods + raise NotImplementedError +omit = + */site-packages/*.py + google/__init__.py diff --git a/packages/google-cloud-audit-log/.coveragerc b/packages/google-cloud-audit-log/.coveragerc new file mode 100644 index 000000000000..d012e8e5a905 --- /dev/null +++ b/packages/google-cloud-audit-log/.coveragerc @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2026 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 +# +# https://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. + +[run] +branch = True +omit = + google/__init__.py + +[report] +fail_under = 100 +show_missing = True +exclude_lines = + # Re-enable the standard pragma + pragma: NO COVER + # Ignore debug-only repr + def __repr__ + # Ignore abstract methods + raise NotImplementedError +omit = + */site-packages/*.py + google/__init__.py diff --git a/packages/google-cloud-firestore/tests/unit/v1/test_pipeline_expressions.py b/packages/google-cloud-firestore/tests/unit/v1/test_pipeline_expressions.py index f76016805729..0c0f29df54b3 100644 --- a/packages/google-cloud-firestore/tests/unit/v1/test_pipeline_expressions.py +++ b/packages/google-cloud-firestore/tests/unit/v1/test_pipeline_expressions.py @@ -284,7 +284,8 @@ def test__from_query_filter_pb_composite_filter_or(self, mock_client): """ test composite OR filters - should create an or statement, made up of ands checking of existance of relevant fields + should create an or statement, made up of ands checking of existance + of relevant fields """ filter1_pb = query_pb.StructuredQuery.FieldFilter( field=query_pb.StructuredQuery.FieldReference(field_path="field1"), diff --git a/packages/google-cloud-testutils/.coveragerc b/packages/google-cloud-testutils/.coveragerc new file mode 100644 index 000000000000..c1f05d46e455 --- /dev/null +++ b/packages/google-cloud-testutils/.coveragerc @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2026 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 +# +# https://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. + +[run] +branch = True + +[report] +fail_under = 75 +show_missing = True +exclude_lines = + # Re-enable the standard pragma + pragma: NO COVER + # Ignore debug-only repr + def __repr__ + # Ignore abstract methods + raise NotImplementedError +omit = + */site-packages/*.py diff --git a/packages/googleapis-common-protos/.coveragerc b/packages/googleapis-common-protos/.coveragerc new file mode 100644 index 000000000000..d012e8e5a905 --- /dev/null +++ b/packages/googleapis-common-protos/.coveragerc @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2026 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 +# +# https://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. + +[run] +branch = True +omit = + google/__init__.py + +[report] +fail_under = 100 +show_missing = True +exclude_lines = + # Re-enable the standard pragma + pragma: NO COVER + # Ignore debug-only repr + def __repr__ + # Ignore abstract methods + raise NotImplementedError +omit = + */site-packages/*.py + google/__init__.py diff --git a/packages/grpc-google-iam-v1/.coveragerc b/packages/grpc-google-iam-v1/.coveragerc new file mode 100644 index 000000000000..d012e8e5a905 --- /dev/null +++ b/packages/grpc-google-iam-v1/.coveragerc @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2026 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 +# +# https://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. + +[run] +branch = True +omit = + google/__init__.py + +[report] +fail_under = 100 +show_missing = True +exclude_lines = + # Re-enable the standard pragma + pragma: NO COVER + # Ignore debug-only repr + def __repr__ + # Ignore abstract methods + raise NotImplementedError +omit = + */site-packages/*.py + google/__init__.py From 387abe0ab25f15e8ec8040ce01c279e8ef523878 Mon Sep 17 00:00:00 2001 From: Chalmer Lowe Date: Tue, 16 Jun 2026 04:37:44 -0400 Subject: [PATCH 083/174] chore: Adds version scanner CI/CD upgrades (#17425) ### Summary of Changes This PR contains updates to the automated dependency version scanner tool and its associated CI/CD workflow to support decoupled formatting, clean console logs, and advisory (non-signalling) runs during rollout. #### 1. GitHub Actions (GHA) Workflow Modernization * **Triggers & Scheduling:** * Configured the workflow to run on `main` and any branch matching `'**version-scanner**'` * Set the schedule to run hourly to test how the system behaves if we choose to use it nightly * Added a `workflow_dispatch` button in the GHA tab to simplify ad hoc testing and demos during development. #### 2. Scanner Script Refactoring (Decoupled Formatters) * Decoupled formatting code from reporting code. * Introduced specialized formatters: * `format_for_raw_csv`: Generates clean, unformatted raw data for CSV reporting. * `format_for_spreadsheet`: Wraps matches with Google Sheets formulas (such as `HYPERLINK` and string quotes to prevent float truncation) for Google Sheets upload. * `format_for_console`: Prepares a slim, readable console string for stdout/logs (especially GHA logs). #### 3. Output Simplification * Removed some existing outputs that no longer made sense to to declutter GHA runner logs. * Ensure it prints matches in the clean console format and removed some existing duplicate outputs. #### 4. Advisory Runs (`--soft-fail`) * Added a `--soft-fail` CLI flag to the python script to allow it to exit with code `0` even if version matches are found (allowing the scan to run and report findings in the logs without failing the GHA check and blocking merges during development and prototyping phases). * Integrated `--soft-fail` in the GHA workflow for now to support development. --- .github/workflows/version_scanner.yml | 78 +++++ scripts/version_scanner/regex_config.yaml | 14 +- .../tests/unit/test_version_scanner.py | 294 ++++++++++++++---- scripts/version_scanner/version_scanner.py | 169 ++++++---- 4 files changed, 428 insertions(+), 127 deletions(-) create mode 100644 .github/workflows/version_scanner.yml diff --git a/.github/workflows/version_scanner.yml b/.github/workflows/version_scanner.yml new file mode 100644 index 000000000000..52f813e67995 --- /dev/null +++ b/.github/workflows/version_scanner.yml @@ -0,0 +1,78 @@ +name: Version Scan + +on: + push: + branches: + - main + - '**version-scanner**' + schedule: + - cron: '0 * * * *' # Run hourly at the top of the hour + workflow_dispatch: + +permissions: + contents: read + issues: write + +jobs: + scan: + name: Version Scan + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: '3.14' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install pyyaml + + - name: Run Version Scanner + run: | + # Uses -o to output a detailed, raw CSV to a file + # Uses --stdout to print a slim, easier to parse summary to the GitHub Actions UI + # Uses --soft-fail to temporarily limit causing CI/CD failures during the migration to full operation. + python scripts/version_scanner/version_scanner.py -d python -v 3.7 --stdout -o version_scanner_output.csv --soft-fail + + - name: Upload CSV Results + if: always() + uses: actions/upload-artifact@v7 + with: + name: version-scanner-results + path: version_scanner_output.csv + + - name: Create or update issue on finding + if: failure() + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + TITLE="Version Scanner found deprecated dependencies" + RUN_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" + + # Read the first 50 lines to prevent blowing up the issue body if it's massive + CSV_PREVIEW=$(head -n 50 version_scanner_output.csv) + + BODY="The [Version Scanner]($RUN_URL) found deprecated dependencies in the repository. + + **Matches Found:** + \`\`\`csv + $CSV_PREVIEW + \`\`\` + *(If there are more than 50 matches, see the workflow logs for the full list)*" + + # Mirroring regenerate-all.yml: check if an issue already exists to prevent spam + EXISTING_ISSUE=$(gh issue list --state open --search "in:title \"$TITLE\"" --json number --jq '.[0].number') + + if [ -z "$EXISTING_ISSUE" ]; then + echo "WOULD HAVE CREATED ISSUE:" + echo "gh issue create --title \"$TITLE\" --body \"$BODY\"" + # gh issue create --title "$TITLE" --body "$BODY" + else + echo "Issue #$EXISTING_ISSUE already exists." + echo "WOULD HAVE ADDED COMMENT:" + echo "gh issue comment \"$EXISTING_ISSUE\" --body \"Another scanner run found deprecated dependencies: $RUN_URL\"" + # gh issue comment "$EXISTING_ISSUE" --body "Another scanner run found deprecated dependencies: $RUN_URL" + fi diff --git a/scripts/version_scanner/regex_config.yaml b/scripts/version_scanner/regex_config.yaml index 07196c63edeb..95e62fe002aa 100644 --- a/scripts/version_scanner/regex_config.yaml +++ b/scripts/version_scanner/regex_config.yaml @@ -58,15 +58,15 @@ rules: - | sys\.version_info\s*<\s*\(3,\s*{minor_plus_one}\) - | - sys\.version_info\.minor\s*==\s*{minor} + sys\.version_info\.minor\s*==\s*{minor}(?!\d) - | - sys\.version_info\.minor\s*>=\s*{minor} + sys\.version_info\.minor\s*>=\s*{minor}(?!\d) - | - sys\.version_info\.minor\s*<=\s*{minor} + sys\.version_info\.minor\s*<=\s*{minor}(?!\d) - | - sys\.version_info\.minor\s*>\s*{minor_minus_one} + sys\.version_info\.minor\s*>\s*{minor_minus_one}(?!\d) - | - sys\.version_info\.minor\s*<\s*{minor_plus_one} + sys\.version_info\.minor\s*<\s*{minor_plus_one}(?!\d) - name: python_env_short description: Finds short python environment names often used in tox or nox. @@ -87,7 +87,7 @@ rules: - "Python3.7" rules: - | - python3\.{minor} + python3\.{minor}(?!\d) - name: combined_version_string description: Finds combined version strings often used in class or variable names. @@ -97,6 +97,6 @@ rules: - "Python37DeprecationWarning" rules: - | - Python{major}{minor} + Python{major}{minor}(?!\d) diff --git a/scripts/version_scanner/tests/unit/test_version_scanner.py b/scripts/version_scanner/tests/unit/test_version_scanner.py index f2d6ce66735e..f5a909e849e8 100644 --- a/scripts/version_scanner/tests/unit/test_version_scanner.py +++ b/scripts/version_scanner/tests/unit/test_version_scanner.py @@ -19,7 +19,18 @@ from unittest.mock import patch import pytest import yaml -from version_scanner import ConfigManager, scan_file, write_csv_report +from version_scanner import ( + ConfigManager, + scan_file, + write_csv_report, + _truncate_context, + _wrap_sheet_hyperlink, + _wrap_sheet_string, + _safe_int, + format_for_raw_csv, + format_for_spreadsheet, + format_for_console +) # Test ConfigManager @pytest.mark.parametrize("dependency, version, expected", [ @@ -246,44 +257,8 @@ def test_main_package_file_not_found(capsys): assert excinfo.value.code == 1 captured = capsys.readouterr() assert "Error: Package file not found" in captured.err -def test_format_match_for_csv(): - from version_scanner import format_match_for_csv - match = { - "file_path": "google-cloud-python/main/packages/pkg_a/setup.py", - "repo_path": "packages/pkg_a/setup.py", - "line_number": 123, - "rule_name": "test_rule" - } - - # Test without github_repo - formatted = format_match_for_csv(match) - assert formatted["line_number"] == 123 - - # Test with github_repo - formatted = format_match_for_csv(match, github_repo="https://github.com/user/repo", branch="main") - expected_url = "https://github.com/user/repo/blob/main/packages/pkg_a/setup.py#L123" - assert formatted["line_number"] == f'=HYPERLINK("{expected_url}", "123")' -def test_format_match_for_csv_truncates_long_line(): - from version_scanner import format_match_for_csv - - long_line = "a" * 1000 + "PY37" + "b" * 1000 - match = { - "file_path": "test.py", - "line_number": 1, - "rule_name": "test_rule", - "matched_string": "PY37", - "context_line": long_line - } - - formatted = format_match_for_csv(match) - context = formatted["context_line"] - - assert len(context) <= 600 - assert "PY37" in context - assert "..." in context - def test_get_match_counts(): from version_scanner import get_match_counts @@ -315,30 +290,7 @@ def test_scan_file_removes_newline_from_match(tmp_path): assert "\n" not in results[0]["matched_string"] -def test_write_csv_report_with_links(tmp_path): - output_file = tmp_path / "report.csv" - matches = [ - { - "file_path": "google-cloud-python/main/packages/pkg_a/setup.py", - "repo_path": "packages/pkg_a/setup.py", - "line_number": 1, - "rule_name": "python_requires_check", - "matched_string": "python_requires = '>=3.7'", - "context_line": "python_requires = '>=3.7'" - } - ] - - from version_scanner import write_csv_report - write_csv_report(str(output_file), matches, github_repo="https://github.com/user/repo", branch="main") - - assert output_file.exists() - - with open(output_file, 'r', encoding='utf-8', newline='') as f: - reader = csv.DictReader(f) - rows = list(reader) - - assert len(rows) == 1 - assert "HYPERLINK" in rows[0]["line_number"] + def test_scan_repository_ignores_version_scanner(tmp_path): vs_dir = tmp_path / "version_scanner" vs_dir.mkdir() @@ -376,7 +328,8 @@ def test_main_loads_ignore_from_script_dir(mock_scan, mock_load_ignore): with mock.patch('sys.argv', test_args): from version_scanner import main - main() + with pytest.raises(SystemExit): + main() mock_load_ignore.assert_called_once() args, kwargs = mock_load_ignore.call_args @@ -385,9 +338,17 @@ def test_main_loads_ignore_from_script_dir(mock_scan, mock_load_ignore): assert "scripts/version_scanner" in path +try: + import googleapiclient + HAS_GOOGLE_API = True +except ImportError: + HAS_GOOGLE_API = False + +@pytest.mark.skipif(not HAS_GOOGLE_API, reason="Requires googleapiclient") @mock.patch('googleapiclient.discovery.build') @mock.patch('google.auth.default') def test_upload_to_drive(mock_auth, mock_build): + """Test the ability to upload results to drive for visibility in gSheets.""" from unittest import mock mock_creds = mock.Mock() @@ -479,6 +440,108 @@ def test_regex_examples_from_config(): break assert matched, f"Example '{example}' in group '{name}' did not match any pattern." +def test_main_exit_code_1(): + """Test that main() calls sys.exit(1) when matches are found.""" + # We can mock scan_repository to return a dummy match + test_args = ['version_scanner.py', '-d', 'python', '-v', '3.7'] + with mock.patch('sys.argv', test_args): + from version_scanner import main + with mock.patch('version_scanner.scan_repository', return_value=[{'file_path': 'test', 'line_number': 1, 'matched_string': '3.7', 'rule_name': 'test'}]): + with pytest.raises(SystemExit) as excinfo: + main() + assert excinfo.value.code == 1 + + +def test_main_soft_fail_exit_code_0(): + """Test that main() calls sys.exit(0) when matches are found but --soft-fail is set.""" + test_args = ['version_scanner.py', '-d', 'python', '-v', '3.7', '--soft-fail'] + with mock.patch('sys.argv', test_args): + from version_scanner import main + with mock.patch('version_scanner.scan_repository', return_value=[{'file_path': 'test', 'line_number': 1, 'matched_string': '3.7', 'rule_name': 'test'}]): + with pytest.raises(SystemExit) as excinfo: + main() + assert excinfo.value.code == 0 + + +def test_main_stdout(capsys): + """Test that --stdout prints the CSV output to stdout.""" + test_args = ['version_scanner.py', '-d', 'python', '-v', '3.7', '--stdout'] + with mock.patch('sys.argv', test_args): + from version_scanner import main + with mock.patch('version_scanner.scan_repository', return_value=[{'file_path': 'test.py', 'line_number': 1, 'matched_string': '3.7', 'rule_name': 'test'}]): + with pytest.raises(SystemExit): + main() + + captured = capsys.readouterr() + assert "test.py:1 [test] 3.7" in captured.out + + +def test_main_without_stdout_limits_output(capsys): + """Test that main() without --stdout prints only 10 matches and shows a suffix.""" + test_args = ['version_scanner.py', '-d', 'python', '-v', '3.7'] + matches = [{'file_path': f'test_{i}.py', 'line_number': i, 'matched_string': '3.7', 'rule_name': 'test'} for i in range(15)] + with mock.patch('sys.argv', test_args): + from version_scanner import main + with mock.patch('version_scanner.scan_repository', return_value=matches): + with pytest.raises(SystemExit): + main() + + captured = capsys.readouterr() + # Should only print first 10 matches + for i in range(10): + assert f"test_{i}.py:{i} [test] 3.7" in captured.out + for i in range(10, 15): + assert f"test_{i}.py:{i} [test] 3.7" not in captured.out + assert "... and 5 more matches." in captured.out + + +def test_main_with_stdout_prints_all(capsys): + """Test that main() with --stdout prints all matches without limiting.""" + test_args = ['version_scanner.py', '-d', 'python', '-v', '3.7', '--stdout'] + matches = [{'file_path': f'test_{i}.py', 'line_number': i, 'matched_string': '3.7', 'rule_name': 'test'} for i in range(15)] + with mock.patch('sys.argv', test_args): + from version_scanner import main + with mock.patch('version_scanner.scan_repository', return_value=matches): + with pytest.raises(SystemExit): + main() + + captured = capsys.readouterr() + # Should print all 15 matches + for i in range(15): + assert f"test_{i}.py:{i} [test] 3.7" in captured.out + assert "... and 5 more matches." not in captured.out + + +def test_main_does_not_print_rules(capsys): + """Test that main() does not print the list of loaded rules to stdout.""" + test_args = ['version_scanner.py', '-d', 'python', '-v', '3.7'] + with mock.patch('sys.argv', test_args): + from version_scanner import main + with mock.patch('version_scanner.scan_repository', return_value=[]): + with pytest.raises(SystemExit): + main() + captured = capsys.readouterr() + assert "explicit_version_string" not in captured.out + + +def test_scan_file_truncation_bug(tmp_path): + """Test that searching for 3.1 does NOT match 3.10 (truncation bug).""" + # Create a file with 3.10 + test_file = tmp_path / "test_file.py" + test_file.write_text("python_requires = '>=3.10'\npython3.10\nPython310\n") + + from version_scanner import ConfigManager, scan_file + + # Init config for 3.1 + config_manager = ConfigManager("regex_config.yaml", "python", "3.1") + rules = config_manager.load_config() + import re + compiled_rules = [{"name": r["name"], "pattern": re.compile(r["pattern"], re.IGNORECASE)} for r in rules] + + # It should not match anything because all strings are 3.10, not 3.1 + matches = scan_file(str(test_file), compiled_rules) + assert len(matches) == 0, f"Expected 0 matches for 3.1 in 3.10 content, but got {len(matches)}: {matches}" + def test_scan_repository_layout_agnostic(tmp_path): # Create directories under different roots @@ -525,3 +588,110 @@ def test_scan_repository_package_name_roots(tmp_path): assert len(results) == 1 assert results[0]["package_name"] == "pkg_third" assert "third_party/pkg_third/setup.py" in results[0]["file_path"] + + +# --- Decoupled Formatters Tests (TDD) --- + +def test_truncate_context(): + # Context shorter than 500 characters shouldn't be truncated + assert _truncate_context("short context", "short") == "short context" + + # Context longer than 500 characters should be truncated around the matched string + matched = "TARGET_VERSION" + long_prefix = "a" * 300 + long_suffix = "b" * 300 + long_context = long_prefix + matched + long_suffix + + truncated = _truncate_context(long_context, matched) + assert len(truncated) <= 500 + assert matched in truncated + assert truncated.startswith("...") + assert truncated.endswith("...") + +def test_wrap_sheet_hyperlink(): + assert _wrap_sheet_hyperlink("https://github.com/foo", "12") == '=HYPERLINK("https://github.com/foo", "12")' + +def test_wrap_sheet_string(): + assert _wrap_sheet_string("3.10") == '="3.10"' + assert _wrap_sheet_string('python_requires = ">=3.7"') == '="python_requires = "">=3.7"""' + assert _wrap_sheet_string("") == "" + assert _wrap_sheet_string(None) == "" + +def test_safe_int(): + assert _safe_int("123") == 123 + assert _safe_int("") == 0 + assert _safe_int(None) == 0 + assert _safe_int("abc") == 0 + +def test_format_for_raw_csv_handles_empty_line_number(): + match = { + "file_path": "google-cloud-python/main/packages/pkg_a/setup.py", + "repo_path": "packages/pkg_a/setup.py", + "package_name": "pkg_a", + "rule_name": "python_requires_check", + "line_number": "", + "matched_string": "3.7", + "context_line": "python_requires = '>=3.7'" + } + formatted = format_for_raw_csv(match) + assert formatted["line_number"] == 0 + +def test_format_for_raw_csv(): + match = { + "file_path": "google-cloud-python/main/packages/pkg_a/setup.py", + "repo_path": "packages/pkg_a/setup.py", + "package_name": "pkg_a", + "rule_name": "python_requires_check", + "line_number": "123", + "matched_string": "3.7", + "context_line": "python_requires = '>=3.7'" + } + + formatted = format_for_raw_csv(match) + + assert formatted["file_path"] == "google-cloud-python/main/packages/pkg_a/setup.py" + assert formatted["package_name"] == "pkg_a" + assert formatted["rule_name"] == "python_requires_check" + assert formatted["line_number"] == 123 # Int conversion + assert formatted["matched_string"] == "3.7" # No formula wrapping + assert formatted["context_line"] == "python_requires = '>=3.7'" + +def test_format_for_spreadsheet(): + match = { + "file_path": "google-cloud-python/main/packages/pkg_a/setup.py", + "repo_path": "packages/pkg_a/setup.py", + "package_name": "pkg_a", + "rule_name": "python_requires_check", + "line_number": 123, + "matched_string": "3.7", + "context_line": "python_requires = '>=3.7'" + } + + # Without github_repo + formatted_no_repo = format_for_spreadsheet(match) + assert formatted_no_repo["line_number"] == 123 + assert formatted_no_repo["matched_string"] == '="3.7"' # Decimal protection formula + + # With github_repo + formatted_repo = format_for_spreadsheet(match, github_repo="https://github.com/user/repo", branch="main") + expected_url = "https://github.com/user/repo/blob/main/packages/pkg_a/setup.py#L123" + assert formatted_repo["line_number"] == f'=HYPERLINK("{expected_url}", "123")' + assert formatted_repo["matched_string"] == '="3.7"' + +def test_format_for_console(): + match = { + "file_path": "google-cloud-python/main/packages/pkg_a/setup.py", + "repo_path": "packages/pkg_a/setup.py", + "package_name": "pkg_a", + "rule_name": "python_requires_check", + "line_number": 123, + "matched_string": "3.7", + "context_line": "python_requires = '>=3.7'" + } + + log_str = format_for_console(match) + assert "google-cloud-python/main/packages/pkg_a/setup.py:123" in log_str + assert "[python_requires_check]" in log_str + assert "3.7" in log_str + assert "python_requires = " not in log_str # Slim format doesn't print context line + diff --git a/scripts/version_scanner/version_scanner.py b/scripts/version_scanner/version_scanner.py index 1d24c8fceced..90234a967665 100644 --- a/scripts/version_scanner/version_scanner.py +++ b/scripts/version_scanner/version_scanner.py @@ -23,7 +23,7 @@ import os import re import sys -from typing import Dict, List, Tuple +from typing import Dict, List, Tuple, Any import yaml class ConfigManager: @@ -186,61 +186,100 @@ def scan_file(file_path: str, compiled_rules: List[Dict[str, re.Pattern]]) -> Li return results -def format_match_for_csv( +def _truncate_context(context: str, matched: str) -> str: + """Safely truncates context around the match location to prevent overflow.""" + if len(context) > 500: + match_start = context.find(matched) + if match_start != -1: + start = max(0, match_start - 200) + end = min(len(context), match_start + len(matched) + 200) + prefix = "..." if start > 0 else "" + suffix = "..." if end < len(context) else "" + return prefix + context[start:end] + suffix + else: + return context[:500] + "..." + return context + + +def _wrap_sheet_hyperlink(url: str, label: str) -> str: + """Wraps a URL and label into a Google Sheets HYPERLINK formula. + + This ensures that when output is imported into spreadsheet software, the + resulting cells contain clickable hyperlinks pointing directly to GitHub file + locations and line numbers. + """ + return f'=HYPERLINK("{url}", "{label}")' + + +def _wrap_sheet_string(value: str) -> str: + """Wraps a string value inside a spreadsheet string formula to prevent float parsing. + + This forces spreadsheet software (such as Google Sheets) to treat numeric + string patterns (like python runtime version "3.10") as literal strings, + preventing auto-truncation to floats (which would display "3.1"). Double + quotes inside the value are escaped by doubling them to avoid formula syntax + errors on import. + """ + if value is None: + return "" + escaped_value = value.replace('"', '""') + return f'="{escaped_value}"' if value else "" + + +def _safe_int(value: Any, default: int = 0) -> int: + """Safely converts a value to an integer, falling back to a default value. + + Used primarily during raw data formatting for spreadsheet ingestion. If a + value (like a line number) is missing or contains non-integer text (e.g. empty + strings for filename-only matches), this avoids crashing the scanner. + """ + try: + return int(value) + except (ValueError, TypeError): + return default + + +def format_for_raw_csv(match: Dict[str, str]) -> Dict[str, str]: + """Prepares a full raw dataset (n + x columns) with clean text values.""" + return { + "file_path": match.get("file_path", ""), + "package_name": match.get("package_name", ""), + "rule_name": match.get("rule_name", ""), + "line_number": _safe_int(match.get("line_number")), + "matched_string": match.get("matched_string", ""), + "context_line": _truncate_context(match.get("context_line", ""), match.get("matched_string", "")) + } + + +def format_for_spreadsheet( match: Dict[str, str], github_repo: str = None, branch: str = "main" ) -> Dict[str, str]: - """ - Formats a raw match dictionary for clean CSV presentation and imports. - - Cleans long context lines by truncating them around the match location to prevent - extreme cell overflow in spreadsheets. Optionally transforms line numbers into - clickable `=HYPERLINK(...)` formulas linking directly to the exact file and line - number in GitHub. - - Args: - match: A match dictionary containing 'file_path', 'repo_path', 'rule_name', - 'line_number', 'matched_string', and 'context_line'. - github_repo: Optional GitHub repository base URL (e.g., "https://github.com/user/repo"). - If provided, triggers the hyperlink generation. - branch: Optional branch name to build the GitHub blob URL (defaults to "main"). - - Returns: - A copy of the match dictionary with formatted/truncated values, suitable for CSV writing. - """ - formatted = match.copy() + """Builds on top of raw CSV but applies Sheets-specific formulas.""" + formatted = format_for_raw_csv(match) + # Override fields with spreadsheet formatting if github_repo: - # Use repo_path if available, fallback to file_path file_path = match.get("repo_path", match.get("file_path", "")) line_number = match.get("line_number", "") - - # Construct URL url = f"{github_repo}/blob/{branch}/{file_path}#L{line_number}" + formatted["line_number"] = _wrap_sheet_hyperlink(url, str(line_number)) - # Format as Google Sheets formula - formatted["line_number"] = f'=HYPERLINK("{url}", "{line_number}")' - - context = formatted.get("context_line", "") - matched = formatted.get("matched_string", "") - - if len(context) > 500: - match_start = context.find(matched) - if match_start != -1: - start = max(0, match_start - 200) - end = min(len(context), match_start + len(matched) + 200) - - prefix = "..." if start > 0 else "" - suffix = "..." if end < len(context) else "" - - formatted["context_line"] = prefix + context[start:end] + suffix - else: - formatted["context_line"] = context[:500] + "..." - + formatted["matched_string"] = _wrap_sheet_string(match.get("matched_string", "")) return formatted +def format_for_console(match: Dict[str, str]) -> str: + """Prepares a slim, readable string representation (n columns) for stdout/logs.""" + file_path = match.get("file_path", "") + line_number = match.get("line_number", "") + rule_name = match.get("rule_name", "") + matched_string = match.get("matched_string", "") + return f" {file_path}:{line_number} [{rule_name}] {matched_string}" + + + def get_match_counts(matches: List[Dict[str, str]]) -> Tuple[Dict[str, int], Dict[str, int]]: """ Aggregate matches by rule and by package. @@ -294,9 +333,7 @@ def load_ignore_file(file_path: str) -> List[str]: def write_csv_report( output_path: str, - matches: List[Dict[str, str]], - github_repo: str = None, - branch: str = "main" + matches: List[Dict[str, str]] ) -> None: """ Write the collected matches to a CSV file. @@ -304,8 +341,6 @@ def write_csv_report( Args: output_path: Path to the output CSV file. matches: A list of dictionaries containing match details. - github_repo: Optional GitHub repository URL base. - branch: GitHub branch for links (defaults to main). """ fieldnames = ["file_path", "package_name", "rule_name", "line_number", "matched_string", "context_line"] @@ -315,7 +350,7 @@ def write_csv_report( writer.writeheader() for match in matches: - formatted_match = format_match_for_csv(match, github_repo, branch) + formatted_match = format_for_raw_csv(match) # Ensure only specified fields are written row = {field: formatted_match.get(field, "") for field in fieldnames} writer.writerow(row) @@ -358,7 +393,7 @@ def upload_to_drive(csv_path: str, matches: List[Dict[str, str]], github_repo: s # Prepare data values = [["file_path", "package_name", "rule_name", "line_number", "matched_string", "context_line"]] for m in matches: - formatted_m = format_match_for_csv(m, github_repo=github_repo, branch=branch) + formatted_m = format_for_spreadsheet(m, github_repo=github_repo, branch=branch) values.append([ formatted_m.get("file_path", ""), formatted_m.get("package_name", ""), @@ -601,6 +636,18 @@ def main(): help="Upload results to a Google Sheet in Drive" ) + parser.add_argument( + "--stdout", + action="store_true", + help="Print the full CSV report to stdout instead of/in addition to writing to a file" + ) + + parser.add_argument( + "--soft-fail", + action="store_true", + help="Exit with code 0 even if matches are found (useful during development and testing runs)" + ) + args = parser.parse_args() # Resolve target packages if filtering is requested @@ -628,10 +675,7 @@ def main(): config_manager = ConfigManager(args.config, args.dependency, args.version) rules = config_manager.load_config() - print(f"\nLoaded {len(rules)} rules:") - for rule in rules: - print(f" - {rule['name']}: {rule['pattern']}") - + # Load ignore file from script directory (Option A) @@ -645,10 +689,11 @@ def main(): all_matches = scan_repository(args.path, rules, target_packages, ignore_dirs, version_string=args.version) print(f"\nFound {len(all_matches)} matches.") - for m in all_matches[:10]: # Show first 10 - print(f" {m['file_path']}:{m['line_number']} [{m['rule_name']}] {m['matched_string']}") + display_matches = all_matches if args.stdout else all_matches[:10] + for m in display_matches: + print(format_for_console(m)) - if len(all_matches) > 10: + if not args.stdout and len(all_matches) > 10: print(f" ... and {len(all_matches) - 10} more matches.") # Get and print summary counts @@ -665,10 +710,18 @@ def main(): os.makedirs(results_dir, exist_ok=True) output_path = os.path.join(results_dir, f"{args.dependency}-{args.version}-{timestamp}.csv") - write_csv_report(output_path, all_matches, github_repo=args.github_repo, branch=args.branch) + write_csv_report(output_path, all_matches) if args.upload: upload_to_drive(output_path, all_matches, github_repo=args.github_repo, branch=args.branch) + + + # Distinct exit codes for CI/CD + if all_matches and not args.soft_fail: + sys.exit(1) + else: + sys.exit(0) + if __name__ == "__main__": main() From 32f7d84a3b2db39e31a8eadcc7d6b5a94fd684b0 Mon Sep 17 00:00:00 2001 From: Cody Oss <6331106+codyoss@users.noreply.github.com> Date: Tue, 16 Jun 2026 09:52:26 -0500 Subject: [PATCH 084/174] chore: migrate from legacylibrarian to release-please for releasing (#17474) --- .github/release-please.yml | 17 + .github/workflows/librarian_config_check.yml | 43 - .librarian/config.yaml | 40 - .librarian/state.yaml | 6218 ------------------ .release-please-bulk-manifest.json | 276 + .release-please-individual-manifest.json | 8 + release-please-bulk-config.json | 3828 +++++++++++ release-please-individual-config.json | 53 + 8 files changed, 4182 insertions(+), 6301 deletions(-) create mode 100644 .github/release-please.yml delete mode 100644 .github/workflows/librarian_config_check.yml delete mode 100644 .librarian/config.yaml delete mode 100644 .librarian/state.yaml create mode 100644 .release-please-bulk-manifest.json create mode 100644 .release-please-individual-manifest.json create mode 100644 release-please-bulk-config.json create mode 100644 release-please-individual-config.json diff --git a/.github/release-please.yml b/.github/release-please.yml new file mode 100644 index 000000000000..2505abb289e8 --- /dev/null +++ b/.github/release-please.yml @@ -0,0 +1,17 @@ +handleGHRelease: true +manifest: true +tagPullRequestNumber: true + +branches: + - branch: main + handleGHRelease: true + tagPullRequestNumber: true + manifest: true + manifestFile: .release-please-bulk-manifest.json + manifestConfig: release-please-bulk-config.json + - branch: main + handleGHRelease: true + tagPullRequestNumber: true + manifest: true + manifestFile: .release-please-individual-manifest.json + manifestConfig: release-please-individual-config.json diff --git a/.github/workflows/librarian_config_check.yml b/.github/workflows/librarian_config_check.yml deleted file mode 100644 index 3e06702a98fb..000000000000 --- a/.github/workflows/librarian_config_check.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: check that Librarian and legacylibrarian configs are consistent -on: - pull_request: - push: - branches: - - main -permissions: - contents: read -jobs: - config-check: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - # Use this action, rather than a file filter so that we can make this - # mandatory. - # See https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#example-including-branches - # for more details. - - uses: dorny/paths-filter@v4 - id: filter - with: - filters: | - librarian: - - 'librarian.yaml' - - '.librarian/config.yaml' - - '.librarian/state.yaml' - - name: Config check - id: config-check - if: steps.filter.outputs.librarian == 'true' - run: | - V=$(go run github.com/googleapis/librarian/cmd/librarian@latest config get version) - go run "github.com/googleapis/librarian/tool/cmd/configcheck@${V}" . - - name: Report any failures - if: failure() && steps.config-check.outcome == 'failure' - run: | - echo "Library configuration is different between state.yaml and librarian.yaml. - Update library configuration in the configs according to the error message and - regenerate libraries using: - - V=\$(go run github.com/googleapis/librarian/cmd/librarian@latest config get version) - go run github.com/googleapis/librarian/cmd/librarian@\${V} generate --all - " - # Make sure this step fails too, so that it's highlighted in the action logs. - exit 1 diff --git a/.librarian/config.yaml b/.librarian/config.yaml deleted file mode 100644 index 919289117611..000000000000 --- a/.librarian/config.yaml +++ /dev/null @@ -1,40 +0,0 @@ -# This file is now handwritten again, post-migration from legacylibrarian to -# librarian (for generation purposes). - -# Release-only mode prevents legacylibrarian from generating any packages. -# legacylibrarian is only used for releasing; librarian is used for generation. -release_only_mode: true - -global_files_allowlist: - # Allow the container to read and write the root `CHANGELOG.md` - # file during the `release` step to update the latest client library - # versions which are hardcoded in the file. - - path: "CHANGELOG.md" - permissions: "read-write" - -libraries: - # libraries have "release_blocked: true" so that releases are - # explicitly initiated. - # TODO(https://github.com/googleapis/google-cloud-python/issues/16489): - # Allow releases for bigframes once the bug above is fixed. - - id: "bigframes" - release_blocked: true - # TODO(https://github.com/googleapis/google-cloud-python/issues/16520): - # Allow release for google-crc32c once this bug is fixed. - - id: "google-crc32c" - release_blocked: true - # TODO(https://github.com/googleapis/google-cloud-python/issues/16962): - # Disable automatic releases until tests stabilize. - - id: "pandas-gbq" - release_blocked: true - # TODO(https://github.com/googleapis/google-cloud-python/issues/16970): - # Disable automatic releases until system tests are sped up or reorganized. - - id: "google-cloud-firestore" - release_blocked: true - # TODO(https://github.com/googleapis/google-cloud-python/issues/17287): - # Allow releases for sqlalchemy-bigquery once the bug above is fixed. - - id: "sqlalchemy-bigquery" - release_blocked: true - # TODO(https://github.com/googleapis/google-cloud-python/issues/17327) - - id: "google-cloud-bigtable" - release_blocked: true diff --git a/.librarian/state.yaml b/.librarian/state.yaml deleted file mode 100644 index 020ac1dbf812..000000000000 --- a/.librarian/state.yaml +++ /dev/null @@ -1,6218 +0,0 @@ -# Copyright 2026 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 -# -# https://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. -image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:234b9d1f2ddb057ed7ac6a38db0bf8163d839c65c6cf88ade52530cddebce59e -libraries: - - id: bigframes - version: 2.43.0 - last_generated_commit: "" - apis: [] - source_roots: - - packages/bigframes - preserve_regex: [] - remove_regex: [] - release_exclude_paths: - - packages/bigframes/.repo-metadata.json - - packages/bigframes/noxfile.py - - packages/bigframes/tests/ - - packages/bigframes/README.rst - - packages/bigframes/docs/ - tag_format: '{id}-v{version}' - - id: bigquery-magics - version: 0.15.0 - last_generated_commit: "" - apis: [] - source_roots: - - packages/bigquery-magics - preserve_regex: [] - remove_regex: [] - release_exclude_paths: - - packages/bigquery-magics/.repo-metadata.json - - packages/bigquery-magics/noxfile.py - - packages/bigquery-magics/tests/ - - packages/bigquery-magics/README.rst - - packages/bigquery-magics/docs/ - tag_format: '{id}-v{version}' - - id: db-dtypes - version: 1.7.0 - last_generated_commit: "" - apis: [] - source_roots: - - packages/db-dtypes - preserve_regex: [] - remove_regex: [] - release_exclude_paths: - - packages/db-dtypes/.repo-metadata.json - - packages/db-dtypes/noxfile.py - - packages/db-dtypes/tests/ - - packages/db-dtypes/README.rst - - packages/db-dtypes/docs/ - tag_format: '{id}-v{version}' - - id: django-google-spanner - version: 5.0.0 - last_generated_commit: "" - apis: [] - source_roots: - - packages/django-google-spanner - preserve_regex: [] - remove_regex: [] - release_exclude_paths: - - packages/django-google-spanner/.repo-metadata.json - - packages/django-google-spanner/noxfile.py - - packages/django-google-spanner/tests/ - - packages/django-google-spanner/README.rst - - packages/django-google-spanner/docs/ - tag_format: '{id}-v{version}' - - id: gapic-generator - version: 1.35.0 - last_generated_commit: "" - apis: [] - source_roots: - - packages/gapic-generator - preserve_regex: [] - remove_regex: [] - release_exclude_paths: - - packages/gapic-generator/.repo-metadata.json - - packages/gapic-generator/noxfile.py - - packages/gapic-generator/tests/ - - packages/gapic-generator/README.rst - - packages/gapic-generator/docs/ - tag_format: '{id}-v{version}' - - id: gcp-sphinx-docfx-yaml - version: 3.3.0 - last_generated_commit: "" - apis: [] - source_roots: - - packages/gcp-sphinx-docfx-yaml - preserve_regex: [] - remove_regex: [] - release_exclude_paths: - - packages/gcp-sphinx-docfx-yaml/.repo-metadata.json - - packages/gcp-sphinx-docfx-yaml/noxfile.py - - packages/gcp-sphinx-docfx-yaml/tests/ - - packages/gcp-sphinx-docfx-yaml/README.rst - - packages/gcp-sphinx-docfx-yaml/docs/ - tag_format: '{id}-v{version}' - - id: google-ads-admanager - version: 0.10.0 - last_generated_commit: effe5c4fa816021e724ca856d5640f2e55b14a8b - apis: - - path: google/ads/admanager/v1 - service_config: admanager_v1.yaml - source_roots: - - packages/google-ads-admanager - preserve_regex: - - packages/google-ads-admanager/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-ads-admanager/ - release_exclude_paths: - - packages/google-ads-admanager/.repo-metadata.json - - packages/google-ads-admanager/noxfile.py - - packages/google-ads-admanager/tests/ - - packages/google-ads-admanager/README.rst - - packages/google-ads-admanager/docs/ - tag_format: '{id}-v{version}' - - id: google-ads-datamanager - version: 0.9.0 - last_generated_commit: 582172de2d9b6443e1fecf696167867c6d8a5fc4 - apis: - - path: google/ads/datamanager/v1 - service_config: datamanager_v1.yaml - source_roots: - - packages/google-ads-datamanager - preserve_regex: - - packages/google-ads-datamanager/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-ads-datamanager - release_exclude_paths: - - packages/google-ads-datamanager/.repo-metadata.json - - packages/google-ads-datamanager/noxfile.py - - packages/google-ads-datamanager/tests/ - - packages/google-ads-datamanager/README.rst - - packages/google-ads-datamanager/docs/ - tag_format: '{id}-v{version}' - - id: google-ads-marketingplatform-admin - version: 0.6.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/marketingplatform/admin/v1alpha - service_config: marketingplatformadmin_v1alpha.yaml - source_roots: - - packages/google-ads-marketingplatform-admin - preserve_regex: - - packages/google-ads-marketingplatform-admin/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-ads-marketingplatform-admin/ - release_exclude_paths: - - packages/google-ads-marketingplatform-admin/.repo-metadata.json - - packages/google-ads-marketingplatform-admin/noxfile.py - - packages/google-ads-marketingplatform-admin/tests/ - - packages/google-ads-marketingplatform-admin/README.rst - - packages/google-ads-marketingplatform-admin/docs/ - tag_format: '{id}-v{version}' - - id: google-ai-generativelanguage - version: 0.12.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/ai/generativelanguage/v1 - service_config: generativelanguage_v1.yaml - - path: google/ai/generativelanguage/v1beta - service_config: generativelanguage_v1beta.yaml - - path: google/ai/generativelanguage/v1beta3 - service_config: generativelanguage_v1beta3.yaml - - path: google/ai/generativelanguage/v1beta2 - service_config: generativelanguage_v1beta2.yaml - - path: google/ai/generativelanguage/v1alpha - service_config: generativelanguage_v1alpha.yaml - source_roots: - - packages/google-ai-generativelanguage - preserve_regex: - - packages/google-ai-generativelanguage/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-ai-generativelanguage/ - release_exclude_paths: - - packages/google-ai-generativelanguage/.repo-metadata.json - - packages/google-ai-generativelanguage/noxfile.py - - packages/google-ai-generativelanguage/tests/ - - packages/google-ai-generativelanguage/README.rst - - packages/google-ai-generativelanguage/docs/ - tag_format: '{id}-v{version}' - - id: google-analytics-admin - version: 0.30.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/analytics/admin/v1beta - service_config: analyticsadmin_v1beta.yaml - - path: google/analytics/admin/v1alpha - service_config: analyticsadmin_v1alpha.yaml - source_roots: - - packages/google-analytics-admin - preserve_regex: - - packages/google-analytics-admin/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-analytics-admin/ - release_exclude_paths: - - packages/google-analytics-admin/.repo-metadata.json - - packages/google-analytics-admin/noxfile.py - - packages/google-analytics-admin/tests/ - - packages/google-analytics-admin/README.rst - - packages/google-analytics-admin/docs/ - tag_format: '{id}-v{version}' - - id: google-analytics-data - version: 0.23.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/analytics/data/v1alpha - service_config: analyticsdata_v1alpha.yaml - - path: google/analytics/data/v1beta - service_config: analyticsdata_v1beta.yaml - source_roots: - - packages/google-analytics-data - preserve_regex: - - packages/google-analytics-data/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-analytics-data/ - release_exclude_paths: - - packages/google-analytics-data/.repo-metadata.json - - packages/google-analytics-data/noxfile.py - - packages/google-analytics-data/tests/ - - packages/google-analytics-data/README.rst - - packages/google-analytics-data/docs/ - tag_format: '{id}-v{version}' - - id: google-api-core - version: 2.31.0 - last_generated_commit: "" - apis: [] - source_roots: - - packages/google-api-core - preserve_regex: [] - remove_regex: [] - release_exclude_paths: - - packages/google-api-core/.repo-metadata.json - - packages/google-api-core/noxfile.py - - packages/google-api-core/tests/ - - packages/google-api-core/README.rst - - packages/google-api-core/docs/ - tag_format: '{id}-v{version}' - - id: google-apps-card - version: 0.7.0 - last_generated_commit: 7a5706618f42f482acf583febcc7b977b66c25b2 - apis: - - path: google/apps/card/v1 - source_roots: - - packages/google-apps-card - preserve_regex: - - packages/google-apps-card/CHANGELOG.md - - docs/CHANGELOG.md - - tests/unit/gapic/card_v1/test_card.py - remove_regex: - - packages/google-apps-card/ - release_exclude_paths: - - packages/google-apps-card/.repo-metadata.json - - packages/google-apps-card/noxfile.py - - packages/google-apps-card/tests/ - - packages/google-apps-card/README.rst - - packages/google-apps-card/docs/ - tag_format: '{id}-v{version}' - - id: google-apps-chat - version: 0.10.0 - last_generated_commit: 2233f63baf69c2a481f30180045fcf036242781d - apis: - - path: google/chat/v1 - service_config: chat_v1.yaml - source_roots: - - packages/google-apps-chat - preserve_regex: - - packages/google-apps-chat/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-apps-chat/ - release_exclude_paths: - - packages/google-apps-chat/.repo-metadata.json - - packages/google-apps-chat/noxfile.py - - packages/google-apps-chat/tests/ - - packages/google-apps-chat/README.rst - - packages/google-apps-chat/docs/ - tag_format: '{id}-v{version}' - - id: google-apps-events-subscriptions - version: 0.6.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/apps/events/subscriptions/v1 - service_config: workspaceevents_v1.yaml - - path: google/apps/events/subscriptions/v1beta - service_config: workspaceevents_v1beta.yaml - source_roots: - - packages/google-apps-events-subscriptions - preserve_regex: - - packages/google-apps-events-subscriptions/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-apps-events-subscriptions/ - release_exclude_paths: - - packages/google-apps-events-subscriptions/.repo-metadata.json - - packages/google-apps-events-subscriptions/noxfile.py - - packages/google-apps-events-subscriptions/tests/ - - packages/google-apps-events-subscriptions/README.rst - - packages/google-apps-events-subscriptions/docs/ - tag_format: '{id}-v{version}' - - id: google-apps-meet - version: 0.5.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/apps/meet/v2beta - service_config: meet_v2beta.yaml - - path: google/apps/meet/v2 - service_config: meet_v2.yaml - source_roots: - - packages/google-apps-meet - preserve_regex: - - packages/google-apps-meet/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-apps-meet/ - release_exclude_paths: - - packages/google-apps-meet/.repo-metadata.json - - packages/google-apps-meet/noxfile.py - - packages/google-apps-meet/tests/ - - packages/google-apps-meet/README.rst - - packages/google-apps-meet/docs/ - tag_format: '{id}-v{version}' - - id: google-apps-script-type - version: 0.8.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/apps/script/type - - path: google/apps/script/type/gmail - - path: google/apps/script/type/docs - - path: google/apps/script/type/drive - - path: google/apps/script/type/sheets - - path: google/apps/script/type/calendar - - path: google/apps/script/type/slides - source_roots: - - packages/google-apps-script-type - preserve_regex: - - packages/google-apps-script-type/CHANGELOG.md - - docs/CHANGELOG.md - - tests/unit/gapic/calendar/test_calendar.py - - tests/unit/gapic/docs/test_docs.py - - tests/unit/gapic/drive/test_drive.py - - tests/unit/gapic/gmail/test_gmail.py - - tests/unit/gapic/sheets/test_sheets.py - - tests/unit/gapic/slides/test_slides.py - - tests/unit/gapic/type/test_type.py - remove_regex: - - packages/google-apps-script-type - release_exclude_paths: - - packages/google-apps-script-type/.repo-metadata.json - - packages/google-apps-script-type/noxfile.py - - packages/google-apps-script-type/tests/ - - packages/google-apps-script-type/README.rst - - packages/google-apps-script-type/docs/ - tag_format: '{id}-v{version}' - - id: google-area120-tables - version: 0.15.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/area120/tables/v1alpha1 - service_config: area120tables_v1alpha1.yaml - source_roots: - - packages/google-area120-tables - preserve_regex: - - packages/google-area120-tables/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-area120-tables/ - release_exclude_paths: - - packages/google-area120-tables/.repo-metadata.json - - packages/google-area120-tables/noxfile.py - - packages/google-area120-tables/tests/ - - packages/google-area120-tables/README.rst - - packages/google-area120-tables/docs/ - tag_format: '{id}-v{version}' - - id: google-auth - version: 2.55.0 - last_generated_commit: "" - apis: [] - source_roots: - - packages/google-auth - preserve_regex: [] - remove_regex: [] - release_exclude_paths: - - packages/google-auth/.repo-metadata.json - - packages/google-auth/noxfile.py - - packages/google-auth/tests/ - - packages/google-auth/README.rst - - packages/google-auth/docs/ - tag_format: '{id}-v{version}' - - id: google-auth-httplib2 - version: 0.4.0 - last_generated_commit: "" - apis: [] - source_roots: - - packages/google-auth-httplib2 - preserve_regex: [] - remove_regex: [] - release_exclude_paths: - - packages/google-auth-httplib2/.repo-metadata.json - - packages/google-auth-httplib2/noxfile.py - - packages/google-auth-httplib2/tests/ - - packages/google-auth-httplib2/README.rst - - packages/google-auth-httplib2/docs/ - tag_format: '{id}-v{version}' - - id: google-auth-oauthlib - version: 1.4.0 - last_generated_commit: "" - apis: [] - source_roots: - - packages/google-auth-oauthlib - preserve_regex: [] - remove_regex: [] - release_exclude_paths: - - packages/google-auth-oauthlib/.repo-metadata.json - - packages/google-auth-oauthlib/noxfile.py - - packages/google-auth-oauthlib/tests/ - - packages/google-auth-oauthlib/README.rst - - packages/google-auth-oauthlib/docs/ - tag_format: '{id}-v{version}' - - id: google-backstory - version: 0.1.0 - last_generated_commit: "" - apis: - - path: backstory - source_roots: - - packages/google-backstory - preserve_regex: - - tests/unit/test_backstory.py - - tests/unit/test_packaging.py - remove_regex: [] - release_exclude_paths: - - packages/google-backstory/.repo-metadata.json - - packages/google-backstory/noxfile.py - - packages/google-backstory/tests/ - - packages/google-backstory/README.rst - - packages/google-backstory/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-access-approval - version: 1.20.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/accessapproval/v1 - service_config: accessapproval_v1.yaml - source_roots: - - packages/google-cloud-access-approval - preserve_regex: - - packages/google-cloud-access-approval/CHANGELOG.md - - docs/CHANGELOG.md - - tests/system - remove_regex: - - packages/google-cloud-access-approval/ - release_exclude_paths: - - packages/google-cloud-access-approval/.repo-metadata.json - - packages/google-cloud-access-approval/noxfile.py - - packages/google-cloud-access-approval/tests/ - - packages/google-cloud-access-approval/README.rst - - packages/google-cloud-access-approval/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-access-context-manager - version: 0.6.0 - last_generated_commit: e8365a7f88fabe8717cb8322b8ce784b03b6daea - apis: - - path: google/identity/accesscontextmanager/v1 - service_config: accesscontextmanager_v1.yaml - - path: google/identity/accesscontextmanager/type - source_roots: - - packages/google-cloud-access-context-manager - preserve_regex: [] - remove_regex: - - ^packages/google-cloud-access-context-manager/google/.*/.*(?:\.proto|_pb2\.(?:py|pyi))$ - - .repo-metadata.json - - noxfile.py - - tests/ - - README.rst - - docs/summary_overview.md - release_exclude_paths: - - packages/google-cloud-access-context-manager/.repo-metadata.json - - packages/google-cloud-access-context-manager/noxfile.py - - packages/google-cloud-access-context-manager/tests/ - - packages/google-cloud-access-context-manager/README.rst - - packages/google-cloud-access-context-manager/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-advisorynotifications - version: 0.7.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/advisorynotifications/v1 - service_config: advisorynotifications_v1.yaml - source_roots: - - packages/google-cloud-advisorynotifications - preserve_regex: - - packages/google-cloud-advisorynotifications/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-advisorynotifications/ - release_exclude_paths: - - packages/google-cloud-advisorynotifications/.repo-metadata.json - - packages/google-cloud-advisorynotifications/noxfile.py - - packages/google-cloud-advisorynotifications/tests/ - - packages/google-cloud-advisorynotifications/README.rst - - packages/google-cloud-advisorynotifications/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-agentidentitycredentials - version: 0.1.0 - last_generated_commit: "" - apis: - - path: google/cloud/agentidentitycredentials/v1 - source_roots: - - packages/google-cloud-agentidentitycredentials - preserve_regex: [] - remove_regex: [] - release_exclude_paths: - - packages/google-cloud-agentidentitycredentials/.repo-metadata.json - - packages/google-cloud-agentidentitycredentials/noxfile.py - - packages/google-cloud-agentidentitycredentials/tests/ - - packages/google-cloud-agentidentitycredentials/README.rst - - packages/google-cloud-agentidentitycredentials/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-alloydb - version: 0.11.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/alloydb/v1beta - service_config: alloydb_v1beta.yaml - - path: google/cloud/alloydb/v1 - service_config: alloydb_v1.yaml - - path: google/cloud/alloydb/v1alpha - service_config: alloydb_v1alpha.yaml - source_roots: - - packages/google-cloud-alloydb - preserve_regex: - - packages/google-cloud-alloydb/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-alloydb/ - release_exclude_paths: - - packages/google-cloud-alloydb/.repo-metadata.json - - packages/google-cloud-alloydb/noxfile.py - - packages/google-cloud-alloydb/tests/ - - packages/google-cloud-alloydb/README.rst - - packages/google-cloud-alloydb/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-alloydb-connectors - version: 0.5.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/alloydb/connectors/v1 - service_config: connectors_v1.yaml - - path: google/cloud/alloydb/connectors/v1alpha - service_config: connectors_v1alpha.yaml - - path: google/cloud/alloydb/connectors/v1beta - service_config: connectors_v1beta.yaml - source_roots: - - packages/google-cloud-alloydb-connectors - preserve_regex: - - packages/google-cloud-alloydb-connectors/CHANGELOG.md - - docs/CHANGELOG.md - - tests/unit/gapic/connectors_v1/test_connectors.py - remove_regex: - - packages/google-cloud-alloydb-connectors/ - release_exclude_paths: - - packages/google-cloud-alloydb-connectors/.repo-metadata.json - - packages/google-cloud-alloydb-connectors/noxfile.py - - packages/google-cloud-alloydb-connectors/tests/ - - packages/google-cloud-alloydb-connectors/README.rst - - packages/google-cloud-alloydb-connectors/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-api-gateway - version: 1.16.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/apigateway/v1 - service_config: apigateway_v1.yaml - source_roots: - - packages/google-cloud-api-gateway - preserve_regex: - - packages/google-cloud-api-gateway/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-api-gateway/ - release_exclude_paths: - - packages/google-cloud-api-gateway/.repo-metadata.json - - packages/google-cloud-api-gateway/noxfile.py - - packages/google-cloud-api-gateway/tests/ - - packages/google-cloud-api-gateway/README.rst - - packages/google-cloud-api-gateway/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-api-keys - version: 0.9.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/api/apikeys/v2 - service_config: apikeys_v2.yaml - source_roots: - - packages/google-cloud-api-keys - preserve_regex: - - packages/google-cloud-api-keys/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-api-keys/ - release_exclude_paths: - - packages/google-cloud-api-keys/.repo-metadata.json - - packages/google-cloud-api-keys/noxfile.py - - packages/google-cloud-api-keys/tests/ - - packages/google-cloud-api-keys/README.rst - - packages/google-cloud-api-keys/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-apigee-connect - version: 1.16.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/apigeeconnect/v1 - service_config: apigeeconnect_v1.yaml - source_roots: - - packages/google-cloud-apigee-connect - preserve_regex: - - packages/google-cloud-apigee-connect/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-apigee-connect/ - release_exclude_paths: - - packages/google-cloud-apigee-connect/.repo-metadata.json - - packages/google-cloud-apigee-connect/noxfile.py - - packages/google-cloud-apigee-connect/tests/ - - packages/google-cloud-apigee-connect/README.rst - - packages/google-cloud-apigee-connect/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-apigee-registry - version: 0.10.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/apigeeregistry/v1 - service_config: apigeeregistry_v1.yaml - source_roots: - - packages/google-cloud-apigee-registry - preserve_regex: - - packages/google-cloud-apigee-registry/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-apigee-registry/ - release_exclude_paths: - - packages/google-cloud-apigee-registry/.repo-metadata.json - - packages/google-cloud-apigee-registry/noxfile.py - - packages/google-cloud-apigee-registry/tests/ - - packages/google-cloud-apigee-registry/README.rst - - packages/google-cloud-apigee-registry/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-apihub - version: 0.7.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/apihub/v1 - service_config: apihub_v1.yaml - source_roots: - - packages/google-cloud-apihub - preserve_regex: - - packages/google-cloud-apihub/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-apihub/ - release_exclude_paths: - - packages/google-cloud-apihub/.repo-metadata.json - - packages/google-cloud-apihub/noxfile.py - - packages/google-cloud-apihub/tests/ - - packages/google-cloud-apihub/README.rst - - packages/google-cloud-apihub/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-apiregistry - version: 0.3.0 - last_generated_commit: d077e5979c3e99b53fe43d606f553bba96b744d6 - apis: - - path: google/cloud/apiregistry/v1beta - service_config: cloudapiregistry_v1beta.yaml - source_roots: - - packages/google-cloud-apiregistry - preserve_regex: - - packages/google-cloud-apiregistry/CHANGELOG.md - - docs/CHANGELOG.md - - samples/README.txt - - scripts/client-post-processing - - samples/snippets/README.rst - - tests/system - remove_regex: - - packages/google-cloud-apiregistry - release_exclude_paths: - - packages/google-cloud-apiregistry/.repo-metadata.json - - packages/google-cloud-apiregistry/noxfile.py - - packages/google-cloud-apiregistry/tests/ - - packages/google-cloud-apiregistry/README.rst - - packages/google-cloud-apiregistry/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-appengine-admin - version: 1.18.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/appengine/v1 - service_config: appengine_v1.yaml - source_roots: - - packages/google-cloud-appengine-admin - preserve_regex: - - packages/google-cloud-appengine-admin/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-appengine-admin/ - release_exclude_paths: - - packages/google-cloud-appengine-admin/.repo-metadata.json - - packages/google-cloud-appengine-admin/noxfile.py - - packages/google-cloud-appengine-admin/tests/ - - packages/google-cloud-appengine-admin/README.rst - - packages/google-cloud-appengine-admin/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-appengine-logging - version: 1.10.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/appengine/logging/v1 - source_roots: - - packages/google-cloud-appengine-logging - preserve_regex: - - packages/google-cloud-appengine-logging/CHANGELOG.md - - docs/CHANGELOG.md - - tests/unit/gapic/appengine_logging_v1/test_appengine_logging_v1.py - remove_regex: - - packages/google-cloud-appengine-logging/ - release_exclude_paths: - - packages/google-cloud-appengine-logging/.repo-metadata.json - - packages/google-cloud-appengine-logging/noxfile.py - - packages/google-cloud-appengine-logging/tests/ - - packages/google-cloud-appengine-logging/README.rst - - packages/google-cloud-appengine-logging/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-apphub - version: 0.5.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/apphub/v1 - service_config: apphub_v1.yaml - source_roots: - - packages/google-cloud-apphub - preserve_regex: - - packages/google-cloud-apphub/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-apphub/ - release_exclude_paths: - - packages/google-cloud-apphub/.repo-metadata.json - - packages/google-cloud-apphub/noxfile.py - - packages/google-cloud-apphub/tests/ - - packages/google-cloud-apphub/README.rst - - packages/google-cloud-apphub/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-appoptimize - version: 0.2.0 - last_generated_commit: cd090841ab172574e740c214c99df00aef9c0dee - apis: - - path: google/cloud/appoptimize/v1beta - service_config: appoptimize_v1beta.yaml - source_roots: - - packages/google-cloud-appoptimize - preserve_regex: - - packages/google-cloud-appoptimize/CHANGELOG.md - - docs/CHANGELOG.md - - samples/README.txt - - scripts/client-post-processing - - samples/snippets/README.rst - - tests/system - remove_regex: - - packages/google-cloud-appoptimize - release_exclude_paths: - - packages/google-cloud-appoptimize/.repo-metadata.json - - packages/google-cloud-appoptimize/noxfile.py - - packages/google-cloud-appoptimize/tests/ - - packages/google-cloud-appoptimize/README.rst - - packages/google-cloud-appoptimize/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-artifact-registry - version: 1.22.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/devtools/artifactregistry/v1 - service_config: artifactregistry_v1.yaml - - path: google/devtools/artifactregistry/v1beta2 - service_config: artifactregistry_v1beta2.yaml - source_roots: - - packages/google-cloud-artifact-registry - preserve_regex: - - packages/google-cloud-artifact-registry/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-artifact-registry/ - release_exclude_paths: - - packages/google-cloud-artifact-registry/.repo-metadata.json - - packages/google-cloud-artifact-registry/noxfile.py - - packages/google-cloud-artifact-registry/tests/ - - packages/google-cloud-artifact-registry/README.rst - - packages/google-cloud-artifact-registry/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-asset - version: 4.4.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/asset/v1p5beta1 - service_config: cloudasset_v1p5beta1.yaml - - path: google/cloud/asset/v1 - service_config: cloudasset_v1.yaml - - path: google/cloud/asset/v1p1beta1 - service_config: cloudasset_v1p1beta1.yaml - - path: google/cloud/asset/v1p2beta1 - service_config: cloudasset_v1p2beta1.yaml - source_roots: - - packages/google-cloud-asset - preserve_regex: - - packages/google-cloud-asset/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-asset/ - release_exclude_paths: - - packages/google-cloud-asset/.repo-metadata.json - - packages/google-cloud-asset/noxfile.py - - packages/google-cloud-asset/tests/ - - packages/google-cloud-asset/README.rst - - packages/google-cloud-asset/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-assured-workloads - version: 2.4.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/assuredworkloads/v1 - service_config: assuredworkloads_v1.yaml - - path: google/cloud/assuredworkloads/v1beta1 - service_config: assuredworkloads_v1beta1.yaml - source_roots: - - packages/google-cloud-assured-workloads - preserve_regex: - - packages/google-cloud-assured-workloads/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-assured-workloads/ - release_exclude_paths: - - packages/google-cloud-assured-workloads/.repo-metadata.json - - packages/google-cloud-assured-workloads/noxfile.py - - packages/google-cloud-assured-workloads/tests/ - - packages/google-cloud-assured-workloads/README.rst - - packages/google-cloud-assured-workloads/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-audit-log - version: 0.6.0 - last_generated_commit: e8365a7f88fabe8717cb8322b8ce784b03b6daea - apis: - - path: google/cloud/audit - service_config: cloudaudit.yaml - source_roots: - - packages/google-cloud-audit-log - preserve_regex: [] - remove_regex: - - ^packages/google-cloud-audit-log/google/.*/.*(?:\.proto|_pb2\.(?:py|pyi))$ - - .repo-metadata.json - - noxfile.py - - tests/ - - README.rst - - docs/summary_overview.md - release_exclude_paths: - - packages/google-cloud-audit-log/.repo-metadata.json - - packages/google-cloud-audit-log/noxfile.py - - packages/google-cloud-audit-log/tests/ - - packages/google-cloud-audit-log/README.rst - - packages/google-cloud-audit-log/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-auditmanager - version: 0.3.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/auditmanager/v1 - service_config: auditmanager_v1.yaml - source_roots: - - packages/google-cloud-auditmanager - preserve_regex: - - packages/google-cloud-auditmanager/CHANGELOG.md - - docs/CHANGELOG.md - - samples/README.txt - - scripts/client-post-processing - - samples/snippets/README.rst - - tests/system - remove_regex: - - packages/google-cloud-auditmanager - release_exclude_paths: - - packages/google-cloud-auditmanager/.repo-metadata.json - - packages/google-cloud-auditmanager/noxfile.py - - packages/google-cloud-auditmanager/tests/ - - packages/google-cloud-auditmanager/README.rst - - packages/google-cloud-auditmanager/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-automl - version: 2.20.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/automl/v1beta1 - service_config: automl_v1beta1.yaml - - path: google/cloud/automl/v1 - service_config: automl_v1.yaml - source_roots: - - packages/google-cloud-automl - preserve_regex: - - packages/google-cloud-automl/CHANGELOG.md - - docs/CHANGELOG.md - - docs/automl_v1beta1/tables.rst - - google/cloud/automl_v1beta1/services/tables - - samples/README - - tests/system - - tests/unit/test_gcs_client_v1beta1.py - - tests/unit/test_tables_client_v1beta1.py - remove_regex: - - packages/google-cloud-automl/ - release_exclude_paths: - - packages/google-cloud-automl/.repo-metadata.json - - packages/google-cloud-automl/noxfile.py - - packages/google-cloud-automl/tests/ - - packages/google-cloud-automl/README.rst - - packages/google-cloud-automl/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-backupdr - version: 0.10.0 - last_generated_commit: 59d5f2b46924714af627ac29ea6de78641a00835 - apis: - - path: google/cloud/backupdr/v1 - service_config: backupdr_v1.yaml - source_roots: - - packages/google-cloud-backupdr - preserve_regex: - - packages/google-cloud-backupdr/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-backupdr/ - release_exclude_paths: - - packages/google-cloud-backupdr/.repo-metadata.json - - packages/google-cloud-backupdr/noxfile.py - - packages/google-cloud-backupdr/tests/ - - packages/google-cloud-backupdr/README.rst - - packages/google-cloud-backupdr/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-bare-metal-solution - version: 1.14.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/baremetalsolution/v2 - service_config: baremetalsolution_v2.yaml - source_roots: - - packages/google-cloud-bare-metal-solution - preserve_regex: - - packages/google-cloud-bare-metal-solution/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-bare-metal-solution/ - release_exclude_paths: - - packages/google-cloud-bare-metal-solution/.repo-metadata.json - - packages/google-cloud-bare-metal-solution/noxfile.py - - packages/google-cloud-bare-metal-solution/tests/ - - packages/google-cloud-bare-metal-solution/README.rst - - packages/google-cloud-bare-metal-solution/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-batch - version: 0.22.0 - last_generated_commit: a17b84add8318f780fcc8a027815d5fee644b9f7 - apis: - - path: google/cloud/batch/v1alpha - service_config: batch_v1alpha.yaml - - path: google/cloud/batch/v1 - service_config: batch_v1.yaml - source_roots: - - packages/google-cloud-batch - preserve_regex: - - packages/google-cloud-batch/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-batch/ - release_exclude_paths: - - packages/google-cloud-batch/.repo-metadata.json - - packages/google-cloud-batch/noxfile.py - - packages/google-cloud-batch/tests/ - - packages/google-cloud-batch/README.rst - - packages/google-cloud-batch/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-beyondcorp-appconnections - version: 0.8.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/beyondcorp/appconnections/v1 - service_config: beyondcorp_v1.yaml - source_roots: - - packages/google-cloud-beyondcorp-appconnections - preserve_regex: - - packages/google-cloud-beyondcorp-appconnections/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-beyondcorp-appconnections/ - release_exclude_paths: - - packages/google-cloud-beyondcorp-appconnections/.repo-metadata.json - - packages/google-cloud-beyondcorp-appconnections/noxfile.py - - packages/google-cloud-beyondcorp-appconnections/tests/ - - packages/google-cloud-beyondcorp-appconnections/README.rst - - packages/google-cloud-beyondcorp-appconnections/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-beyondcorp-appconnectors - version: 0.8.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/beyondcorp/appconnectors/v1 - service_config: beyondcorp_v1.yaml - source_roots: - - packages/google-cloud-beyondcorp-appconnectors - preserve_regex: - - packages/google-cloud-beyondcorp-appconnectors/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-beyondcorp-appconnectors/ - release_exclude_paths: - - packages/google-cloud-beyondcorp-appconnectors/.repo-metadata.json - - packages/google-cloud-beyondcorp-appconnectors/noxfile.py - - packages/google-cloud-beyondcorp-appconnectors/tests/ - - packages/google-cloud-beyondcorp-appconnectors/README.rst - - packages/google-cloud-beyondcorp-appconnectors/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-beyondcorp-appgateways - version: 0.8.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/beyondcorp/appgateways/v1 - service_config: beyondcorp_v1.yaml - source_roots: - - packages/google-cloud-beyondcorp-appgateways - preserve_regex: - - packages/google-cloud-beyondcorp-appgateways/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-beyondcorp-appgateways/ - release_exclude_paths: - - packages/google-cloud-beyondcorp-appgateways/.repo-metadata.json - - packages/google-cloud-beyondcorp-appgateways/noxfile.py - - packages/google-cloud-beyondcorp-appgateways/tests/ - - packages/google-cloud-beyondcorp-appgateways/README.rst - - packages/google-cloud-beyondcorp-appgateways/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-beyondcorp-clientconnectorservices - version: 0.8.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/beyondcorp/clientconnectorservices/v1 - service_config: beyondcorp_v1.yaml - source_roots: - - packages/google-cloud-beyondcorp-clientconnectorservices - preserve_regex: - - packages/google-cloud-beyondcorp-clientconnectorservices/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-beyondcorp-clientconnectorservices/ - release_exclude_paths: - - packages/google-cloud-beyondcorp-clientconnectorservices/.repo-metadata.json - - packages/google-cloud-beyondcorp-clientconnectorservices/noxfile.py - - packages/google-cloud-beyondcorp-clientconnectorservices/tests/ - - packages/google-cloud-beyondcorp-clientconnectorservices/README.rst - - packages/google-cloud-beyondcorp-clientconnectorservices/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-beyondcorp-clientgateways - version: 0.8.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/beyondcorp/clientgateways/v1 - service_config: beyondcorp_v1.yaml - source_roots: - - packages/google-cloud-beyondcorp-clientgateways - preserve_regex: - - packages/google-cloud-beyondcorp-clientgateways/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-beyondcorp-clientgateways/ - release_exclude_paths: - - packages/google-cloud-beyondcorp-clientgateways/.repo-metadata.json - - packages/google-cloud-beyondcorp-clientgateways/noxfile.py - - packages/google-cloud-beyondcorp-clientgateways/tests/ - - packages/google-cloud-beyondcorp-clientgateways/README.rst - - packages/google-cloud-beyondcorp-clientgateways/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-biglake - version: 0.5.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/biglake/v1 - service_config: biglake_v1.yaml - source_roots: - - packages/google-cloud-biglake - preserve_regex: - - packages/google-cloud-biglake/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-biglake - release_exclude_paths: - - packages/google-cloud-biglake/.repo-metadata.json - - packages/google-cloud-biglake/noxfile.py - - packages/google-cloud-biglake/tests/ - - packages/google-cloud-biglake/README.rst - - packages/google-cloud-biglake/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-biglake-hive - version: 0.3.0 - last_generated_commit: 6649b7fea255d74c5bdd027a19ed444d0121f946 - apis: - - path: google/cloud/biglake/hive/v1beta - service_config: biglake_v1beta.yaml - source_roots: - - packages/google-cloud-biglake-hive - preserve_regex: - - packages/google-cloud-biglake-hive/CHANGELOG.md - - docs/CHANGELOG.md - - samples/README.txt - - scripts/client-post-processing - - samples/snippets/README.rst - - tests/system - remove_regex: - - packages/google-cloud-biglake-hive - release_exclude_paths: - - packages/google-cloud-biglake-hive/.repo-metadata.json - - packages/google-cloud-biglake-hive/noxfile.py - - packages/google-cloud-biglake-hive/tests/ - - packages/google-cloud-biglake-hive/README.rst - - packages/google-cloud-biglake-hive/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-bigquery - version: 3.42.0 - last_generated_commit: "" - apis: [] - source_roots: - - packages/google-cloud-bigquery - preserve_regex: [] - remove_regex: [] - release_exclude_paths: - - packages/google-cloud-bigquery/.repo-metadata.json - - packages/google-cloud-bigquery/noxfile.py - - packages/google-cloud-bigquery/tests/ - - packages/google-cloud-bigquery/README.rst - - packages/google-cloud-bigquery/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-bigquery-analyticshub - version: 0.9.0 - last_generated_commit: 53f97391f3451398f7b53c7f86dabd325d205677 - apis: - - path: google/cloud/bigquery/analyticshub/v1 - service_config: analyticshub_v1.yaml - source_roots: - - packages/google-cloud-bigquery-analyticshub - preserve_regex: - - packages/google-cloud-bigquery-analyticshub/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-bigquery-analyticshub/ - release_exclude_paths: - - packages/google-cloud-bigquery-analyticshub/.repo-metadata.json - - packages/google-cloud-bigquery-analyticshub/noxfile.py - - packages/google-cloud-bigquery-analyticshub/tests/ - - packages/google-cloud-bigquery-analyticshub/README.rst - - packages/google-cloud-bigquery-analyticshub/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-bigquery-biglake - version: 0.8.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/bigquery/biglake/v1alpha1 - service_config: biglake_v1alpha1.yaml - - path: google/cloud/bigquery/biglake/v1 - service_config: biglake_v1.yaml - source_roots: - - packages/google-cloud-bigquery-biglake - preserve_regex: - - packages/google-cloud-bigquery-biglake/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-bigquery-biglake/ - release_exclude_paths: - - packages/google-cloud-bigquery-biglake/.repo-metadata.json - - packages/google-cloud-bigquery-biglake/noxfile.py - - packages/google-cloud-bigquery-biglake/tests/ - - packages/google-cloud-bigquery-biglake/README.rst - - packages/google-cloud-bigquery-biglake/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-bigquery-connection - version: 1.22.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/bigquery/connection/v1 - service_config: bigqueryconnection_v1.yaml - source_roots: - - packages/google-cloud-bigquery-connection - preserve_regex: - - packages/google-cloud-bigquery-connection/CHANGELOG.md - - docs/CHANGELOG.md - - tests/system - remove_regex: - - packages/google-cloud-bigquery-connection/ - release_exclude_paths: - - packages/google-cloud-bigquery-connection/.repo-metadata.json - - packages/google-cloud-bigquery-connection/noxfile.py - - packages/google-cloud-bigquery-connection/tests/ - - packages/google-cloud-bigquery-connection/README.rst - - packages/google-cloud-bigquery-connection/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-bigquery-data-exchange - version: 0.9.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/bigquery/dataexchange/v1beta1 - service_config: analyticshub_v1beta1.yaml - source_roots: - - packages/google-cloud-bigquery-data-exchange - preserve_regex: - - packages/google-cloud-bigquery-data-exchange/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-bigquery-data-exchange/ - release_exclude_paths: - - packages/google-cloud-bigquery-data-exchange/.repo-metadata.json - - packages/google-cloud-bigquery-data-exchange/noxfile.py - - packages/google-cloud-bigquery-data-exchange/tests/ - - packages/google-cloud-bigquery-data-exchange/README.rst - - packages/google-cloud-bigquery-data-exchange/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-bigquery-datapolicies - version: 0.10.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/bigquery/datapolicies/v2beta1 - service_config: bigquerydatapolicy_v2beta1.yaml - - path: google/cloud/bigquery/datapolicies/v2 - service_config: bigquerydatapolicy_v2.yaml - - path: google/cloud/bigquery/datapolicies/v1beta1 - service_config: bigquerydatapolicy_v1beta1.yaml - - path: google/cloud/bigquery/datapolicies/v1 - service_config: bigquerydatapolicy_v1.yaml - source_roots: - - packages/google-cloud-bigquery-datapolicies - preserve_regex: - - packages/google-cloud-bigquery-datapolicies/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-bigquery-datapolicies/ - release_exclude_paths: - - packages/google-cloud-bigquery-datapolicies/.repo-metadata.json - - packages/google-cloud-bigquery-datapolicies/noxfile.py - - packages/google-cloud-bigquery-datapolicies/tests/ - - packages/google-cloud-bigquery-datapolicies/README.rst - - packages/google-cloud-bigquery-datapolicies/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-bigquery-datatransfer - version: 3.23.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/bigquery/datatransfer/v1 - service_config: bigquerydatatransfer_v1.yaml - source_roots: - - packages/google-cloud-bigquery-datatransfer - preserve_regex: - - packages/google-cloud-bigquery-datatransfer/CHANGELOG.md - - docs/CHANGELOG.md - - tests/system - remove_regex: - - packages/google-cloud-bigquery-datatransfer/ - release_exclude_paths: - - packages/google-cloud-bigquery-datatransfer/.repo-metadata.json - - packages/google-cloud-bigquery-datatransfer/noxfile.py - - packages/google-cloud-bigquery-datatransfer/tests/ - - packages/google-cloud-bigquery-datatransfer/README.rst - - packages/google-cloud-bigquery-datatransfer/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-bigquery-logging - version: 1.10.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/bigquery/logging/v1 - source_roots: - - packages/google-cloud-bigquery-logging - preserve_regex: - - packages/google-cloud-bigquery-logging/CHANGELOG.md - - docs/CHANGELOG.md - - tests/unit/gapic/bigquery_logging_v1/test_bigquery_logging_v1.py - remove_regex: - - packages/google-cloud-bigquery-logging/ - release_exclude_paths: - - packages/google-cloud-bigquery-logging/.repo-metadata.json - - packages/google-cloud-bigquery-logging/noxfile.py - - packages/google-cloud-bigquery-logging/tests/ - - packages/google-cloud-bigquery-logging/README.rst - - packages/google-cloud-bigquery-logging/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-bigquery-migration - version: 0.15.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/bigquery/migration/v2alpha - service_config: bigquerymigration_v2alpha.yaml - - path: google/cloud/bigquery/migration/v2 - service_config: bigquerymigration_v2.yaml - source_roots: - - packages/google-cloud-bigquery-migration - preserve_regex: - - packages/google-cloud-bigquery-migration/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-bigquery-migration/ - release_exclude_paths: - - packages/google-cloud-bigquery-migration/.repo-metadata.json - - packages/google-cloud-bigquery-migration/noxfile.py - - packages/google-cloud-bigquery-migration/tests/ - - packages/google-cloud-bigquery-migration/README.rst - - packages/google-cloud-bigquery-migration/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-bigquery-reservation - version: 1.25.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/bigquery/reservation/v1 - service_config: bigqueryreservation_v1.yaml - source_roots: - - packages/google-cloud-bigquery-reservation - preserve_regex: - - packages/google-cloud-bigquery-reservation/CHANGELOG.md - - docs/CHANGELOG.md - - tests/system - remove_regex: - - packages/google-cloud-bigquery-reservation/ - release_exclude_paths: - - packages/google-cloud-bigquery-reservation/.repo-metadata.json - - packages/google-cloud-bigquery-reservation/noxfile.py - - packages/google-cloud-bigquery-reservation/tests/ - - packages/google-cloud-bigquery-reservation/README.rst - - packages/google-cloud-bigquery-reservation/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-bigquery-storage - version: 2.39.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/bigquery/storage/v1beta2 - service_config: bigquerystorage_v1beta2.yaml - - path: google/cloud/bigquery/storage/v1alpha - service_config: bigquerystorage_v1alpha.yaml - - path: google/cloud/bigquery/storage/v1beta - service_config: bigquerystorage_v1beta.yaml - - path: google/cloud/bigquery/storage/v1 - service_config: bigquerystorage_v1.yaml - source_roots: - - packages/google-cloud-bigquery-storage - preserve_regex: - - docs/.*/library.rst - - docs/samples - - docs/CHANGELOG.md - - google/cloud/bigquery_storage_v1/client.py - - google/cloud/bigquery_storage_v1/exceptions.py - - google/cloud/bigquery_storage_v1/gapic_types.py - - google/cloud/bigquery_storage_v1/reader.py - - google/cloud/bigquery_storage_v1/writer.py - - google/cloud/bigquery_storage_v1beta2/client.py - - google/cloud/bigquery_storage_v1beta2/exceptions.py - - google/cloud/bigquery_storage_v1beta2/writer.py - - packages/google-cloud-bigquery-storage/CHANGELOG.md - - packages/google-cloud-bigquery-storage/CONTRIBUTING - - samples/__init__.py - - samples/conftest.py - - samples/pyarrow - - samples/quickstart - - samples/snippets - - samples/to_dataframe - - scripts/readme-gen - - testing/.gitignore - - tests/system - - tests/unit/helpers.py - - tests/unit/test_.*.py - remove_regex: - - packages/google-cloud-bigquery-storage - release_exclude_paths: - - packages/google-cloud-bigquery-storage/.repo-metadata.json - - packages/google-cloud-bigquery-storage/noxfile.py - - packages/google-cloud-bigquery-storage/tests/ - - packages/google-cloud-bigquery-storage/README.rst - - packages/google-cloud-bigquery-storage/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-bigtable - version: 2.38.0 - last_generated_commit: a6cbf809c4c165e618ee23a059442af90a80a0f5 - apis: - - path: google/bigtable/admin/v2 - service_config: bigtableadmin_v2.yaml - - path: google/bigtable/v2 - service_config: bigtable_v2.yaml - source_roots: - - packages/google-cloud-bigtable - preserve_regex: - - packages/google-cloud-bigtable/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - ^packages/google-cloud-bigtable/.coveragerc - - ^packages/google-cloud-bigtable/.flake8 - - ^packages/google-cloud-bigtable/.repo-metadata.json - - ^packages/google-cloud-bigtable/noxfile.py - - ^packages/google-cloud-bigtable/tests/ - - ^packages/google-cloud-bigtable/LICENSE - - ^packages/google-cloud-bigtable/MANIFEST.in - - ^packages/google-cloud-bigtable/README.rst - - ^packages/google-cloud-bigtable/mypy.ini - - ^packages/google-cloud-bigtable/noxfile.py - - ^packages/google-cloud-bigtable/setup.py - - ^packages/google-cloud-bigtable/docs/conf.py - - ^packages/google-cloud-bigtable/docs/index.rst - - ^packages/google-cloud-bigtable/docs/multiprocessing.rst - - ^packages/google-cloud-bigtable/docs/summary_overview.md - - ^packages/google-cloud-bigtable/README.rst - - ^packages/google-cloud-bigtable/docs/ - - ^packages/google-cloud-bigtable/docs/_static/custom.css - - ^packages/google-cloud-bigtable/docs/_templates - - ^packages/google-cloud-bigtable/docs/bigtable - - ^packages/google-cloud-bigtable/google/cloud/bigtable/__init__.py - - ^packages/google-cloud-bigtable/google/cloud/bigtable/gapic_version.py - - ^packages/google-cloud-bigtable/google/cloud/bigtable/py.typed - - ^packages/google-cloud-bigtable/google/cloud/bigtable_v2 - - ^packages/google-cloud-bigtable/google/cloud/bigtable_admin/ - - ^packages/google-cloud-bigtable/google/cloud/bigtable_admin_v2/services - - ^packages/google-cloud-bigtable/google/cloud/bigtable_admin_v2/types - - ^packages/google-cloud-bigtable/google/cloud/bigtable_admin_v2/__init__.py - - ^packages/google-cloud-bigtable/google/cloud/bigtable_admin_v2/gapic - - ^packages/google-cloud-bigtable/google/cloud/bigtable_admin_v2/py.typed - - ^packages/google-cloud-bigtable/samples/generated_samples - - ^packages/google-cloud-bigtable/testing - - ^packages/google-cloud-bigtable/tests/__init__.py - - ^packages/google-cloud-bigtable/tests/unit/__init__.py - - ^packages/google-cloud-bigtable/tests/unit/gapic - release_exclude_paths: - - packages/google-cloud-bigtable/.repo-metadata.json - - packages/google-cloud-bigtable/noxfile.py - - packages/google-cloud-bigtable/tests/ - - packages/google-cloud-bigtable/README.rst - - packages/google-cloud-bigtable/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-billing - version: 1.20.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/billing/v1 - service_config: cloudbilling_v1.yaml - source_roots: - - packages/google-cloud-billing - preserve_regex: - - packages/google-cloud-billing/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-billing/ - release_exclude_paths: - - packages/google-cloud-billing/.repo-metadata.json - - packages/google-cloud-billing/noxfile.py - - packages/google-cloud-billing/tests/ - - packages/google-cloud-billing/README.rst - - packages/google-cloud-billing/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-billing-budgets - version: 1.21.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/billing/budgets/v1 - service_config: billingbudgets.yaml - - path: google/cloud/billing/budgets/v1beta1 - service_config: billingbudgets.yaml - source_roots: - - packages/google-cloud-billing-budgets - preserve_regex: - - packages/google-cloud-billing-budgets/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-billing-budgets/ - release_exclude_paths: - - packages/google-cloud-billing-budgets/.repo-metadata.json - - packages/google-cloud-billing-budgets/noxfile.py - - packages/google-cloud-billing-budgets/tests/ - - packages/google-cloud-billing-budgets/README.rst - - packages/google-cloud-billing-budgets/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-binary-authorization - version: 1.17.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/binaryauthorization/v1 - service_config: binaryauthorization_v1.yaml - - path: google/cloud/binaryauthorization/v1beta1 - service_config: binaryauthorization_v1beta1.yaml - source_roots: - - packages/google-cloud-binary-authorization - preserve_regex: - - packages/google-cloud-binary-authorization/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-binary-authorization/ - release_exclude_paths: - - packages/google-cloud-binary-authorization/.repo-metadata.json - - packages/google-cloud-binary-authorization/noxfile.py - - packages/google-cloud-binary-authorization/tests/ - - packages/google-cloud-binary-authorization/README.rst - - packages/google-cloud-binary-authorization/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-build - version: 3.37.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/devtools/cloudbuild/v1 - service_config: cloudbuild_v1.yaml - - path: google/devtools/cloudbuild/v2 - service_config: cloudbuild_v2.yaml - source_roots: - - packages/google-cloud-build - preserve_regex: - - packages/google-cloud-build/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-build/ - release_exclude_paths: - - packages/google-cloud-build/.repo-metadata.json - - packages/google-cloud-build/noxfile.py - - packages/google-cloud-build/tests/ - - packages/google-cloud-build/README.rst - - packages/google-cloud-build/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-capacityplanner - version: 0.5.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/capacityplanner/v1beta - service_config: capacityplanner_v1beta.yaml - source_roots: - - packages/google-cloud-capacityplanner - preserve_regex: - - packages/google-cloud-capacityplanner/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-capacityplanner/ - release_exclude_paths: - - packages/google-cloud-capacityplanner/.repo-metadata.json - - packages/google-cloud-capacityplanner/noxfile.py - - packages/google-cloud-capacityplanner/tests/ - - packages/google-cloud-capacityplanner/README.rst - - packages/google-cloud-capacityplanner/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-certificate-manager - version: 1.14.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/certificatemanager/v1 - service_config: certificatemanager_v1.yaml - source_roots: - - packages/google-cloud-certificate-manager - preserve_regex: - - packages/google-cloud-certificate-manager/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-certificate-manager/ - release_exclude_paths: - - packages/google-cloud-certificate-manager/.repo-metadata.json - - packages/google-cloud-certificate-manager/noxfile.py - - packages/google-cloud-certificate-manager/tests/ - - packages/google-cloud-certificate-manager/README.rst - - packages/google-cloud-certificate-manager/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-ces - version: 0.7.0 - last_generated_commit: 582172de2d9b6443e1fecf696167867c6d8a5fc4 - apis: - - path: google/cloud/ces/v1 - service_config: ces_v1.yaml - - path: google/cloud/ces/v1beta - service_config: ces_v1beta.yaml - source_roots: - - packages/google-cloud-ces - preserve_regex: - - packages/google-cloud-ces/CHANGELOG.md - - docs/CHANGELOG.md - - samples/README.txt - - scripts/client-post-processing - - samples/snippets/README.rst - - tests/system - remove_regex: - - packages/google-cloud-ces - release_exclude_paths: - - packages/google-cloud-ces/.repo-metadata.json - - packages/google-cloud-ces/noxfile.py - - packages/google-cloud-ces/tests/ - - packages/google-cloud-ces/README.rst - - packages/google-cloud-ces/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-channel - version: 1.28.0 - last_generated_commit: 535d161c24965e9ed1a0b27032cc1c8b4beab818 - apis: - - path: google/cloud/channel/v1 - service_config: cloudchannel_v1.yaml - source_roots: - - packages/google-cloud-channel - preserve_regex: - - packages/google-cloud-channel/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-channel/ - release_exclude_paths: - - packages/google-cloud-channel/.repo-metadata.json - - packages/google-cloud-channel/noxfile.py - - packages/google-cloud-channel/tests/ - - packages/google-cloud-channel/README.rst - - packages/google-cloud-channel/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-chronicle - version: 0.6.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/chronicle/v1 - service_config: chronicle_v1.yaml - source_roots: - - packages/google-cloud-chronicle - preserve_regex: - - packages/google-cloud-chronicle/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-chronicle/ - release_exclude_paths: - - packages/google-cloud-chronicle/.repo-metadata.json - - packages/google-cloud-chronicle/noxfile.py - - packages/google-cloud-chronicle/tests/ - - packages/google-cloud-chronicle/README.rst - - packages/google-cloud-chronicle/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-cloudcontrolspartner - version: 0.6.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/cloudcontrolspartner/v1beta - service_config: cloudcontrolspartner_v1beta.yaml - - path: google/cloud/cloudcontrolspartner/v1 - service_config: cloudcontrolspartner_v1.yaml - source_roots: - - packages/google-cloud-cloudcontrolspartner - preserve_regex: - - packages/google-cloud-cloudcontrolspartner/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-cloudcontrolspartner/ - release_exclude_paths: - - packages/google-cloud-cloudcontrolspartner/.repo-metadata.json - - packages/google-cloud-cloudcontrolspartner/noxfile.py - - packages/google-cloud-cloudcontrolspartner/tests/ - - packages/google-cloud-cloudcontrolspartner/README.rst - - packages/google-cloud-cloudcontrolspartner/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-cloudsecuritycompliance - version: 0.8.0 - last_generated_commit: 53f97391f3451398f7b53c7f86dabd325d205677 - apis: - - path: google/cloud/cloudsecuritycompliance/v1 - service_config: cloudsecuritycompliance_v1.yaml - source_roots: - - packages/google-cloud-cloudsecuritycompliance - preserve_regex: - - packages/google-cloud-cloudsecuritycompliance/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-cloudsecuritycompliance/ - release_exclude_paths: - - packages/google-cloud-cloudsecuritycompliance/.repo-metadata.json - - packages/google-cloud-cloudsecuritycompliance/noxfile.py - - packages/google-cloud-cloudsecuritycompliance/tests/ - - packages/google-cloud-cloudsecuritycompliance/README.rst - - packages/google-cloud-cloudsecuritycompliance/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-commerce-consumer-procurement - version: 0.6.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/commerce/consumer/procurement/v1 - service_config: cloudcommerceconsumerprocurement_v1.yaml - - path: google/cloud/commerce/consumer/procurement/v1alpha1 - service_config: cloudcommerceconsumerprocurement_v1alpha1.yaml - source_roots: - - packages/google-cloud-commerce-consumer-procurement - preserve_regex: - - packages/google-cloud-commerce-consumer-procurement/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-commerce-consumer-procurement/ - release_exclude_paths: - - packages/google-cloud-commerce-consumer-procurement/.repo-metadata.json - - packages/google-cloud-commerce-consumer-procurement/noxfile.py - - packages/google-cloud-commerce-consumer-procurement/tests/ - - packages/google-cloud-commerce-consumer-procurement/README.rst - - packages/google-cloud-commerce-consumer-procurement/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-common - version: 1.10.0 - last_generated_commit: e8365a7f88fabe8717cb8322b8ce784b03b6daea - apis: - - path: google/cloud/common - service_config: common.yaml - source_roots: - - packages/google-cloud-common - preserve_regex: - - packages/google-cloud-common/CHANGELOG.md - - docs/CHANGELOG.md - - tests/unit/gapic/common/test_common.py - remove_regex: - - packages/google-cloud-common/ - release_exclude_paths: - - packages/google-cloud-common/.repo-metadata.json - - packages/google-cloud-common/noxfile.py - - packages/google-cloud-common/tests/ - - packages/google-cloud-common/README.rst - - packages/google-cloud-common/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-compute - version: 1.48.0 - last_generated_commit: 256b575f6915282b20795c13414b21f2c0af65db - apis: - - path: google/cloud/compute/v1 - service_config: compute_v1.yaml - source_roots: - - packages/google-cloud-compute - preserve_regex: - - packages/google-cloud-compute/CHANGELOG.md - - docs/CHANGELOG.md - - tests/system - remove_regex: - - packages/google-cloud-compute/ - release_exclude_paths: - - packages/google-cloud-compute/.repo-metadata.json - - packages/google-cloud-compute/noxfile.py - - packages/google-cloud-compute/tests/ - - packages/google-cloud-compute/README.rst - - packages/google-cloud-compute/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-compute-v1beta - version: 0.12.0 - last_generated_commit: 256b575f6915282b20795c13414b21f2c0af65db - apis: - - path: google/cloud/compute/v1beta - service_config: compute_v1beta.yaml - source_roots: - - packages/google-cloud-compute-v1beta - preserve_regex: - - packages/google-cloud-compute-v1beta/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-compute-v1beta/ - release_exclude_paths: - - packages/google-cloud-compute-v1beta/.repo-metadata.json - - packages/google-cloud-compute-v1beta/noxfile.py - - packages/google-cloud-compute-v1beta/tests/ - - packages/google-cloud-compute-v1beta/README.rst - - packages/google-cloud-compute-v1beta/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-confidentialcomputing - version: 0.11.0 - last_generated_commit: 9eea40c74d97622bb0aa406dd313409a376cc73b - apis: - - path: google/cloud/confidentialcomputing/v1 - service_config: confidentialcomputing_v1.yaml - source_roots: - - packages/google-cloud-confidentialcomputing - preserve_regex: - - packages/google-cloud-confidentialcomputing/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-confidentialcomputing/ - release_exclude_paths: - - packages/google-cloud-confidentialcomputing/.repo-metadata.json - - packages/google-cloud-confidentialcomputing/noxfile.py - - packages/google-cloud-confidentialcomputing/tests/ - - packages/google-cloud-confidentialcomputing/README.rst - - packages/google-cloud-confidentialcomputing/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-config - version: 0.7.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/config/v1 - service_config: config_v1.yaml - source_roots: - - packages/google-cloud-config - preserve_regex: - - packages/google-cloud-config/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-config/ - release_exclude_paths: - - packages/google-cloud-config/.repo-metadata.json - - packages/google-cloud-config/noxfile.py - - packages/google-cloud-config/tests/ - - packages/google-cloud-config/README.rst - - packages/google-cloud-config/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-configdelivery - version: 0.5.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/configdelivery/v1beta - service_config: configdelivery_v1beta.yaml - - path: google/cloud/configdelivery/v1alpha - service_config: configdelivery_v1alpha.yaml - - path: google/cloud/configdelivery/v1 - service_config: configdelivery_v1.yaml - source_roots: - - packages/google-cloud-configdelivery - preserve_regex: - - packages/google-cloud-configdelivery/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-configdelivery/ - release_exclude_paths: - - packages/google-cloud-configdelivery/.repo-metadata.json - - packages/google-cloud-configdelivery/noxfile.py - - packages/google-cloud-configdelivery/tests/ - - packages/google-cloud-configdelivery/README.rst - - packages/google-cloud-configdelivery/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-contact-center-insights - version: 1.27.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/contactcenterinsights/v1 - service_config: contactcenterinsights_v1.yaml - source_roots: - - packages/google-cloud-contact-center-insights - preserve_regex: - - packages/google-cloud-contact-center-insights/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-contact-center-insights/ - release_exclude_paths: - - packages/google-cloud-contact-center-insights/.repo-metadata.json - - packages/google-cloud-contact-center-insights/noxfile.py - - packages/google-cloud-contact-center-insights/tests/ - - packages/google-cloud-contact-center-insights/README.rst - - packages/google-cloud-contact-center-insights/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-container - version: 2.65.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/container/v1 - service_config: container_v1.yaml - - path: google/container/v1beta1 - service_config: container_v1beta1.yaml - source_roots: - - packages/google-cloud-container - preserve_regex: - - packages/google-cloud-container/CHANGELOG.md - - docs/CHANGELOG.md - - tests/system - remove_regex: - - packages/google-cloud-container/ - release_exclude_paths: - - packages/google-cloud-container/.repo-metadata.json - - packages/google-cloud-container/noxfile.py - - packages/google-cloud-container/tests/ - - packages/google-cloud-container/README.rst - - packages/google-cloud-container/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-containeranalysis - version: 2.22.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/devtools/containeranalysis/v1 - service_config: containeranalysis_v1.yaml - source_roots: - - packages/google-cloud-containeranalysis - preserve_regex: - - packages/google-cloud-containeranalysis/CHANGELOG.md - - docs/CHANGELOG.md - - tests/unit/test_get_grafeas_client.py - remove_regex: - - packages/google-cloud-containeranalysis/ - release_exclude_paths: - - packages/google-cloud-containeranalysis/.repo-metadata.json - - packages/google-cloud-containeranalysis/noxfile.py - - packages/google-cloud-containeranalysis/tests/ - - packages/google-cloud-containeranalysis/README.rst - - packages/google-cloud-containeranalysis/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-contentwarehouse - version: 0.11.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/contentwarehouse/v1 - service_config: contentwarehouse_v1.yaml - source_roots: - - packages/google-cloud-contentwarehouse - preserve_regex: - - packages/google-cloud-contentwarehouse/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-contentwarehouse/ - release_exclude_paths: - - packages/google-cloud-contentwarehouse/.repo-metadata.json - - packages/google-cloud-contentwarehouse/noxfile.py - - packages/google-cloud-contentwarehouse/tests/ - - packages/google-cloud-contentwarehouse/README.rst - - packages/google-cloud-contentwarehouse/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-core - version: 2.6.0 - last_generated_commit: "" - apis: [] - source_roots: - - packages/google-cloud-core - preserve_regex: [] - remove_regex: [] - release_exclude_paths: - - packages/google-cloud-core/.repo-metadata.json - - packages/google-cloud-core/noxfile.py - - packages/google-cloud-core/tests/ - - packages/google-cloud-core/README.rst - - packages/google-cloud-core/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-data-fusion - version: 1.17.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/datafusion/v1 - service_config: datafusion_v1.yaml - source_roots: - - packages/google-cloud-data-fusion - preserve_regex: - - packages/google-cloud-data-fusion/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-data-fusion/ - release_exclude_paths: - - packages/google-cloud-data-fusion/.repo-metadata.json - - packages/google-cloud-data-fusion/noxfile.py - - packages/google-cloud-data-fusion/tests/ - - packages/google-cloud-data-fusion/README.rst - - packages/google-cloud-data-fusion/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-data-qna - version: 0.14.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/dataqna/v1alpha - service_config: dataqna_v1alpha.yaml - source_roots: - - packages/google-cloud-data-qna - preserve_regex: - - packages/google-cloud-data-qna/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-data-qna/ - release_exclude_paths: - - packages/google-cloud-data-qna/.repo-metadata.json - - packages/google-cloud-data-qna/noxfile.py - - packages/google-cloud-data-qna/tests/ - - packages/google-cloud-data-qna/README.rst - - packages/google-cloud-data-qna/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-databasecenter - version: 0.9.0 - last_generated_commit: 59d5f2b46924714af627ac29ea6de78641a00835 - apis: - - path: google/cloud/databasecenter/v1beta - service_config: databasecenter_v1beta.yaml - source_roots: - - packages/google-cloud-databasecenter - preserve_regex: - - packages/google-cloud-databasecenter/CHANGELOG.md - - docs/CHANGELOG.md - - scripts/client-post-processing - remove_regex: - - packages/google-cloud-databasecenter - release_exclude_paths: - - packages/google-cloud-databasecenter/.repo-metadata.json - - packages/google-cloud-databasecenter/noxfile.py - - packages/google-cloud-databasecenter/tests/ - - packages/google-cloud-databasecenter/README.rst - - packages/google-cloud-databasecenter/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-datacatalog - version: 3.31.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/datacatalog/v1 - service_config: datacatalog_v1.yaml - - path: google/cloud/datacatalog/v1beta1 - service_config: datacatalog_v1beta1.yaml - source_roots: - - packages/google-cloud-datacatalog - preserve_regex: - - packages/google-cloud-datacatalog/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-datacatalog/ - release_exclude_paths: - - packages/google-cloud-datacatalog/.repo-metadata.json - - packages/google-cloud-datacatalog/noxfile.py - - packages/google-cloud-datacatalog/tests/ - - packages/google-cloud-datacatalog/README.rst - - packages/google-cloud-datacatalog/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-datacatalog-lineage - version: 0.7.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/datacatalog/lineage/v1 - service_config: datalineage_v1.yaml - source_roots: - - packages/google-cloud-datacatalog-lineage - preserve_regex: - - packages/google-cloud-datacatalog-lineage/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-datacatalog-lineage/ - release_exclude_paths: - - packages/google-cloud-datacatalog-lineage/.repo-metadata.json - - packages/google-cloud-datacatalog-lineage/noxfile.py - - packages/google-cloud-datacatalog-lineage/tests/ - - packages/google-cloud-datacatalog-lineage/README.rst - - packages/google-cloud-datacatalog-lineage/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-datacatalog-lineage-configmanagement - version: 0.3.0 - last_generated_commit: 0b3dec847f1045e47991c1539d4c69d8b025cfe8 - apis: - - path: google/cloud/datacatalog/lineage/configmanagement/v1 - service_config: datalineage_v1.yaml - source_roots: - - packages/google-cloud-datacatalog-lineage-configmanagement - preserve_regex: - - packages/google-cloud-datacatalog-lineage-configmanagement/CHANGELOG.md - - docs/CHANGELOG.md - - samples/README.txt - - scripts/client-post-processing - - samples/snippets/README.rst - - tests/system - remove_regex: - - packages/google-cloud-datacatalog-lineage-configmanagement - release_exclude_paths: - - packages/google-cloud-datacatalog-lineage-configmanagement/.repo-metadata.json - - packages/google-cloud-datacatalog-lineage-configmanagement/noxfile.py - - packages/google-cloud-datacatalog-lineage-configmanagement/tests/ - - packages/google-cloud-datacatalog-lineage-configmanagement/README.rst - - packages/google-cloud-datacatalog-lineage-configmanagement/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-dataflow-client - version: 0.14.0 - last_generated_commit: 582172de2d9b6443e1fecf696167867c6d8a5fc4 - apis: - - path: google/dataflow/v1beta3 - service_config: dataflow_v1beta3.yaml - source_roots: - - packages/google-cloud-dataflow-client - preserve_regex: - - packages/google-cloud-dataflow-client/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-dataflow-client/ - release_exclude_paths: - - packages/google-cloud-dataflow-client/.repo-metadata.json - - packages/google-cloud-dataflow-client/noxfile.py - - packages/google-cloud-dataflow-client/tests/ - - packages/google-cloud-dataflow-client/README.rst - - packages/google-cloud-dataflow-client/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-dataform - version: 0.11.0 - last_generated_commit: 59d5f2b46924714af627ac29ea6de78641a00835 - apis: - - path: google/cloud/dataform/v1beta1 - service_config: dataform_v1beta1.yaml - - path: google/cloud/dataform/v1 - service_config: dataform_v1.yaml - source_roots: - - packages/google-cloud-dataform - preserve_regex: - - packages/google-cloud-dataform/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-dataform/ - release_exclude_paths: - - packages/google-cloud-dataform/.repo-metadata.json - - packages/google-cloud-dataform/noxfile.py - - packages/google-cloud-dataform/tests/ - - packages/google-cloud-dataform/README.rst - - packages/google-cloud-dataform/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-datalabeling - version: 1.17.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/datalabeling/v1beta1 - service_config: datalabeling_v1beta1.yaml - source_roots: - - packages/google-cloud-datalabeling - preserve_regex: - - packages/google-cloud-datalabeling/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-datalabeling/ - release_exclude_paths: - - packages/google-cloud-datalabeling/.repo-metadata.json - - packages/google-cloud-datalabeling/noxfile.py - - packages/google-cloud-datalabeling/tests/ - - packages/google-cloud-datalabeling/README.rst - - packages/google-cloud-datalabeling/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-dataplex - version: 2.20.0 - last_generated_commit: 59d5f2b46924714af627ac29ea6de78641a00835 - apis: - - path: google/cloud/dataplex/v1 - service_config: dataplex_v1.yaml - source_roots: - - packages/google-cloud-dataplex - preserve_regex: - - packages/google-cloud-dataplex/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-dataplex/ - release_exclude_paths: - - packages/google-cloud-dataplex/.repo-metadata.json - - packages/google-cloud-dataplex/noxfile.py - - packages/google-cloud-dataplex/tests/ - - packages/google-cloud-dataplex/README.rst - - packages/google-cloud-dataplex/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-dataproc - version: 5.28.0 - last_generated_commit: 38ed7d6ba66a774924722146f054d12b4487a89f - apis: - - path: google/cloud/dataproc/v1 - service_config: dataproc_v1.yaml - source_roots: - - packages/google-cloud-dataproc - preserve_regex: - - packages/google-cloud-dataproc/CHANGELOG.md - - docs/CHANGELOG.md - - tests/system - remove_regex: - - packages/google-cloud-dataproc/ - release_exclude_paths: - - packages/google-cloud-dataproc/.repo-metadata.json - - packages/google-cloud-dataproc/noxfile.py - - packages/google-cloud-dataproc/tests/ - - packages/google-cloud-dataproc/README.rst - - packages/google-cloud-dataproc/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-dataproc-metastore - version: 1.23.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/metastore/v1alpha - service_config: metastore_v1alpha.yaml - - path: google/cloud/metastore/v1beta - service_config: metastore_v1beta.yaml - - path: google/cloud/metastore/v1 - service_config: metastore_v1.yaml - source_roots: - - packages/google-cloud-dataproc-metastore - preserve_regex: - - packages/google-cloud-dataproc-metastore/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-dataproc-metastore/ - release_exclude_paths: - - packages/google-cloud-dataproc-metastore/.repo-metadata.json - - packages/google-cloud-dataproc-metastore/noxfile.py - - packages/google-cloud-dataproc-metastore/tests/ - - packages/google-cloud-dataproc-metastore/README.rst - - packages/google-cloud-dataproc-metastore/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-datastore - version: 2.25.0 - last_generated_commit: ce8678a96c8e1fc0d870d80fcf062e5be2b12877 - apis: - - path: google/datastore/admin/v1 - service_config: datastore_v1.yaml - - path: google/datastore/v1 - service_config: datastore_v1.yaml - source_roots: - - packages/google-cloud-datastore - preserve_regex: - - packages/google-cloud-datastore/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - ^packages/google-cloud-datastore/.coveragerc - - ^packages/google-cloud-datastore/.flake8 - - ^packages/google-cloud-datastore/.repo-metadata.json - - ^packages/google-cloud-datastore/noxfile.py - - ^packages/google-cloud-datastore/tests/ - - ^packages/google-cloud-datastore/LICENSE - - ^packages/google-cloud-datastore/MANIFEST.in - - ^packages/google-cloud-datastore/README.rst - - ^packages/google-cloud-datastore/mypy.ini - - ^packages/google-cloud-datastore/noxfile.py - - ^packages/google-cloud-datastore/setup.py - - ^packages/google-cloud-datastore/docs/conf.py - - ^packages/google-cloud-datastore/docs/index.rst - - ^packages/google-cloud-datastore/docs/summary_overview.md - - ^packages/google-cloud-datastore/README.rst - - ^packages/google-cloud-datastore/docs/ - - ^packages/google-cloud-datastore/docs/_static/custom.css - - ^packages/google-cloud-datastore/docs/datastore_admin_v1/datastore_admin.rst - - ^packages/google-cloud-datastore/docs/datastore_admin_v1/services_.rst - - ^packages/google-cloud-datastore/docs/datastore_admin_v1/types_.rst - - ^packages/google-cloud-datastore/docs/datastore_v1/datastore.rst - - ^packages/google-cloud-datastore/docs/datastore_v1/services_.rst - - ^packages/google-cloud-datastore/docs/datastore_v1/types_.rst - - ^packages/google-cloud-datastore/docs/multiprocessing.rst - - ^packages/google-cloud-datastore/docs/_templates/datastore_admin.rst - - ^packages/google-cloud-datastore/docs/_templates/layout.html - - ^packages/google-cloud-datastore/google/cloud/datastore_admin_v1/__init__.py - - ^packages/google-cloud-datastore/google/cloud/datastore_admin_v1/gapic_metadata.json - - ^packages/google-cloud-datastore/google/cloud/datastore_admin_v1/gapic_version.py - - ^packages/google-cloud-datastore/google/cloud/datastore_admin_v1/py.typed - - ^packages/google-cloud-datastore/google/cloud/datastore_admin_v1/services - - ^packages/google-cloud-datastore/google/cloud/datastore_admin_v1/types - - ^packages/google-cloud-datastore/google/cloud/datastore_v1/__init__.py - - ^packages/google-cloud-datastore/google/cloud/datastore_v1/gapic_metadata.json - - ^packages/google-cloud-datastore/google/cloud/datastore_v1/gapic_version.py - - ^packages/google-cloud-datastore/google/cloud/datastore_v1/py.typed - - ^packages/google-cloud-datastore/google/cloud/datastore_v1/services - - ^packages/google-cloud-datastore/google/cloud/datastore_v1/types - - ^packages/google-cloud-datastore/google/cloud/datastore/__init__.py - - ^packages/google-cloud-datastore/google/cloud/datastore/gapic_version.py - - ^packages/google-cloud-datastore/google/cloud/datastore/py.typed - - ^packages/google-cloud-datastore/google/cloud/datastore_admin/__init__.py - - ^packages/google-cloud-datastore/google/cloud/datastore_admin/gapic_version.py - - ^packages/google-cloud-datastore/google/cloud/datastore_admin/py.typed - - ^packages/google-cloud-datastore/testing - - ^packages/google-cloud-datastore/tests/__init__.py - - ^packages/google-cloud-datastore/tests/unit/__init__.py - - ^packages/google-cloud-datastore/tests/unit/gapic - - ^packages/google-cloud-datastore/samples/generated_samples - release_exclude_paths: - - packages/google-cloud-datastore/.repo-metadata.json - - packages/google-cloud-datastore/noxfile.py - - packages/google-cloud-datastore/tests/ - - packages/google-cloud-datastore/README.rst - - packages/google-cloud-datastore/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-datastream - version: 1.19.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/datastream/v1 - service_config: datastream_v1.yaml - - path: google/cloud/datastream/v1alpha1 - service_config: datastream_v1alpha1.yaml - source_roots: - - packages/google-cloud-datastream - preserve_regex: - - packages/google-cloud-datastream/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-datastream/ - release_exclude_paths: - - packages/google-cloud-datastream/.repo-metadata.json - - packages/google-cloud-datastream/noxfile.py - - packages/google-cloud-datastream/tests/ - - packages/google-cloud-datastream/README.rst - - packages/google-cloud-datastream/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-deploy - version: 2.11.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/deploy/v1 - service_config: clouddeploy_v1.yaml - source_roots: - - packages/google-cloud-deploy - preserve_regex: - - packages/google-cloud-deploy/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-deploy/ - release_exclude_paths: - - packages/google-cloud-deploy/.repo-metadata.json - - packages/google-cloud-deploy/noxfile.py - - packages/google-cloud-deploy/tests/ - - packages/google-cloud-deploy/README.rst - - packages/google-cloud-deploy/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-developerconnect - version: 0.6.0 - last_generated_commit: c662840a94dbdf708caa44893a2d49119cdd391c - apis: - - path: google/cloud/developerconnect/v1 - service_config: developerconnect_v1.yaml - source_roots: - - packages/google-cloud-developerconnect - preserve_regex: - - packages/google-cloud-developerconnect/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-developerconnect/ - release_exclude_paths: - - packages/google-cloud-developerconnect/.repo-metadata.json - - packages/google-cloud-developerconnect/noxfile.py - - packages/google-cloud-developerconnect/tests/ - - packages/google-cloud-developerconnect/README.rst - - packages/google-cloud-developerconnect/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-devicestreaming - version: 0.5.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/devicestreaming/v1 - service_config: devicestreaming_v1.yaml - source_roots: - - packages/google-cloud-devicestreaming - preserve_regex: - - packages/google-cloud-devicestreaming/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-devicestreaming/ - release_exclude_paths: - - packages/google-cloud-devicestreaming/.repo-metadata.json - - packages/google-cloud-devicestreaming/noxfile.py - - packages/google-cloud-devicestreaming/tests/ - - packages/google-cloud-devicestreaming/README.rst - - packages/google-cloud-devicestreaming/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-dialogflow - version: 2.48.0 - last_generated_commit: 256b575f6915282b20795c13414b21f2c0af65db - apis: - - path: google/cloud/dialogflow/v2beta1 - service_config: dialogflow_v2beta1.yaml - - path: google/cloud/dialogflow/v2 - service_config: dialogflow_v2.yaml - source_roots: - - packages/google-cloud-dialogflow - preserve_regex: - - packages/google-cloud-dialogflow/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-dialogflow/ - release_exclude_paths: - - packages/google-cloud-dialogflow/.repo-metadata.json - - packages/google-cloud-dialogflow/noxfile.py - - packages/google-cloud-dialogflow/tests/ - - packages/google-cloud-dialogflow/README.rst - - packages/google-cloud-dialogflow/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-dialogflow-cx - version: 2.6.0 - last_generated_commit: 59d5f2b46924714af627ac29ea6de78641a00835 - apis: - - path: google/cloud/dialogflow/cx/v3 - service_config: dialogflow_v3.yaml - - path: google/cloud/dialogflow/cx/v3beta1 - service_config: dialogflow_v3beta1.yaml - source_roots: - - packages/google-cloud-dialogflow-cx - preserve_regex: - - packages/google-cloud-dialogflow-cx/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-dialogflow-cx - release_exclude_paths: - - packages/google-cloud-dialogflow-cx/.repo-metadata.json - - packages/google-cloud-dialogflow-cx/noxfile.py - - packages/google-cloud-dialogflow-cx/tests/ - - packages/google-cloud-dialogflow-cx/README.rst - - packages/google-cloud-dialogflow-cx/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-discoveryengine - version: 0.20.0 - last_generated_commit: 59d5f2b46924714af627ac29ea6de78641a00835 - apis: - - path: google/cloud/discoveryengine/v1 - service_config: discoveryengine_v1.yaml - - path: google/cloud/discoveryengine/v1beta - service_config: discoveryengine_v1beta.yaml - - path: google/cloud/discoveryengine/v1alpha - service_config: discoveryengine_v1alpha.yaml - source_roots: - - packages/google-cloud-discoveryengine - preserve_regex: - - packages/google-cloud-discoveryengine/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-discoveryengine/ - release_exclude_paths: - - packages/google-cloud-discoveryengine/.repo-metadata.json - - packages/google-cloud-discoveryengine/noxfile.py - - packages/google-cloud-discoveryengine/tests/ - - packages/google-cloud-discoveryengine/README.rst - - packages/google-cloud-discoveryengine/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-dlp - version: 3.37.0 - last_generated_commit: 2233f63baf69c2a481f30180045fcf036242781d - apis: - - path: google/privacy/dlp/v2 - service_config: dlp_v2.yaml - source_roots: - - packages/google-cloud-dlp - preserve_regex: - - packages/google-cloud-dlp/CHANGELOG.md - - docs/CHANGELOG.md - - tests/system - remove_regex: - - packages/google-cloud-dlp/ - release_exclude_paths: - - packages/google-cloud-dlp/.repo-metadata.json - - packages/google-cloud-dlp/noxfile.py - - packages/google-cloud-dlp/tests/ - - packages/google-cloud-dlp/README.rst - - packages/google-cloud-dlp/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-dms - version: 1.16.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/clouddms/v1 - service_config: datamigration_v1.yaml - source_roots: - - packages/google-cloud-dms - preserve_regex: - - packages/google-cloud-dms/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-dms/ - release_exclude_paths: - - packages/google-cloud-dms/.repo-metadata.json - - packages/google-cloud-dms/noxfile.py - - packages/google-cloud-dms/tests/ - - packages/google-cloud-dms/README.rst - - packages/google-cloud-dms/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-dns - version: 0.37.0 - last_generated_commit: "" - apis: [] - source_roots: - - packages/google-cloud-dns - preserve_regex: [] - remove_regex: [] - release_exclude_paths: - - packages/google-cloud-dns/.repo-metadata.json - - packages/google-cloud-dns/noxfile.py - - packages/google-cloud-dns/tests/ - - packages/google-cloud-dns/README.rst - - packages/google-cloud-dns/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-documentai - version: 3.15.0 - last_generated_commit: 582172de2d9b6443e1fecf696167867c6d8a5fc4 - apis: - - path: google/cloud/documentai/v1beta3 - service_config: documentai_v1beta3.yaml - - path: google/cloud/documentai/v1 - service_config: documentai_v1.yaml - source_roots: - - packages/google-cloud-documentai - preserve_regex: - - packages/google-cloud-documentai/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-documentai/ - release_exclude_paths: - - packages/google-cloud-documentai/.repo-metadata.json - - packages/google-cloud-documentai/noxfile.py - - packages/google-cloud-documentai/tests/ - - packages/google-cloud-documentai/README.rst - - packages/google-cloud-documentai/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-documentai-toolbox - version: 0.17.0 - last_generated_commit: "" - apis: [] - source_roots: - - packages/google-cloud-documentai-toolbox - preserve_regex: [] - remove_regex: [] - release_exclude_paths: - - packages/google-cloud-documentai-toolbox/.repo-metadata.json - - packages/google-cloud-documentai-toolbox/noxfile.py - - packages/google-cloud-documentai-toolbox/tests/ - - packages/google-cloud-documentai-toolbox/README.rst - - packages/google-cloud-documentai-toolbox/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-domains - version: 1.14.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/domains/v1beta1 - service_config: domains_v1beta1.yaml - - path: google/cloud/domains/v1 - service_config: domains_v1.yaml - source_roots: - - packages/google-cloud-domains - preserve_regex: - - packages/google-cloud-domains/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-domains/ - release_exclude_paths: - - packages/google-cloud-domains/.repo-metadata.json - - packages/google-cloud-domains/noxfile.py - - packages/google-cloud-domains/tests/ - - packages/google-cloud-domains/README.rst - - packages/google-cloud-domains/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-edgecontainer - version: 0.8.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/edgecontainer/v1 - service_config: edgecontainer_v1.yaml - source_roots: - - packages/google-cloud-edgecontainer - preserve_regex: - - packages/google-cloud-edgecontainer/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-edgecontainer/ - release_exclude_paths: - - packages/google-cloud-edgecontainer/.repo-metadata.json - - packages/google-cloud-edgecontainer/noxfile.py - - packages/google-cloud-edgecontainer/tests/ - - packages/google-cloud-edgecontainer/README.rst - - packages/google-cloud-edgecontainer/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-edgenetwork - version: 0.5.0 - last_generated_commit: b1a9eefc2e1021fb9465bdac5e2984499451ae34 - apis: - - path: google/cloud/edgenetwork/v1 - service_config: edgenetwork_v1.yaml - source_roots: - - packages/google-cloud-edgenetwork - preserve_regex: - - packages/google-cloud-edgenetwork/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-edgenetwork/ - release_exclude_paths: - - packages/google-cloud-edgenetwork/.repo-metadata.json - - packages/google-cloud-edgenetwork/noxfile.py - - packages/google-cloud-edgenetwork/tests/ - - packages/google-cloud-edgenetwork/README.rst - - packages/google-cloud-edgenetwork/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-enterpriseknowledgegraph - version: 0.6.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/enterpriseknowledgegraph/v1 - service_config: enterpriseknowledgegraph_v1.yaml - source_roots: - - packages/google-cloud-enterpriseknowledgegraph - preserve_regex: - - packages/google-cloud-enterpriseknowledgegraph/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-enterpriseknowledgegraph/ - release_exclude_paths: - - packages/google-cloud-enterpriseknowledgegraph/.repo-metadata.json - - packages/google-cloud-enterpriseknowledgegraph/noxfile.py - - packages/google-cloud-enterpriseknowledgegraph/tests/ - - packages/google-cloud-enterpriseknowledgegraph/README.rst - - packages/google-cloud-enterpriseknowledgegraph/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-error-reporting - version: 1.15.0 - last_generated_commit: 59d5f2b46924714af627ac29ea6de78641a00835 - apis: - - path: google/devtools/clouderrorreporting/v1beta1 - service_config: clouderrorreporting_v1beta1.yaml - source_roots: - - packages/google-cloud-error-reporting - preserve_regex: - - packages/google-cloud-error-reporting/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - ^packages/google-cloud-error-reporting/google/cloud/errorreporting - - ^packages/google-cloud-error-reporting/docs/_static - - ^packages/google-cloud-error-reporting/docs/_templates - - ^packages/google-cloud-error-reporting/docs/errorreporting_v1beta1 - - ^packages/google-cloud-error-reporting/docs/multiprocessing.rst - - ^packages/google-cloud-error-reporting/docs/conf.py - - ^packages/google-cloud-error-reporting/docs/index.rst - - ^packages/google-cloud-error-reporting/README.rst - - ^packages/google-cloud-error-reporting/docs/ - - ^packages/google-cloud-error-reporting/docs/summary_overview.md - - ^packages/google-cloud-error-reporting/tests/unit/gapic - - ^packages/google-cloud-error-reporting/tests/__init__.py - - ^packages/google-cloud-error-reporting/tests/unit/__init__.py - - ^packages/google-cloud-error-reporting/.coveragerc - - ^packages/google-cloud-error-reporting/.flake8 - - ^packages/google-cloud-error-reporting/.repo-metadata.json - - ^packages/google-cloud-error-reporting/noxfile.py - - ^packages/google-cloud-error-reporting/tests/ - - ^packages/google-cloud-error-reporting/.trampolinerc - - ^packages/google-cloud-error-reporting/LICENSE - - ^packages/google-cloud-error-reporting/MANIFEST.in - - ^packages/google-cloud-error-reporting/README.rst - - ^packages/google-cloud-error-reporting/mypy.ini - - ^packages/google-cloud-error-reporting/noxfile.py - - ^packages/google-cloud-error-reporting/samples/generated_samples - - ^packages/google-cloud-error-reporting/setup.py - - ^packages/google-cloud-error-reporting/testing - release_exclude_paths: - - packages/google-cloud-error-reporting/.repo-metadata.json - - packages/google-cloud-error-reporting/noxfile.py - - packages/google-cloud-error-reporting/tests/ - - packages/google-cloud-error-reporting/README.rst - - packages/google-cloud-error-reporting/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-essential-contacts - version: 1.13.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/essentialcontacts/v1 - service_config: essentialcontacts_v1.yaml - source_roots: - - packages/google-cloud-essential-contacts - preserve_regex: - - packages/google-cloud-essential-contacts/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-essential-contacts/ - release_exclude_paths: - - packages/google-cloud-essential-contacts/.repo-metadata.json - - packages/google-cloud-essential-contacts/noxfile.py - - packages/google-cloud-essential-contacts/tests/ - - packages/google-cloud-essential-contacts/README.rst - - packages/google-cloud-essential-contacts/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-eventarc - version: 1.20.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/eventarc/v1 - service_config: eventarc_v1.yaml - source_roots: - - packages/google-cloud-eventarc - preserve_regex: - - packages/google-cloud-eventarc/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-eventarc/ - release_exclude_paths: - - packages/google-cloud-eventarc/.repo-metadata.json - - packages/google-cloud-eventarc/noxfile.py - - packages/google-cloud-eventarc/tests/ - - packages/google-cloud-eventarc/README.rst - - packages/google-cloud-eventarc/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-eventarc-publishing - version: 0.10.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/eventarc/publishing/v1 - service_config: eventarcpublishing_v1.yaml - source_roots: - - packages/google-cloud-eventarc-publishing - preserve_regex: - - packages/google-cloud-eventarc-publishing/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-eventarc-publishing/ - release_exclude_paths: - - packages/google-cloud-eventarc-publishing/.repo-metadata.json - - packages/google-cloud-eventarc-publishing/noxfile.py - - packages/google-cloud-eventarc-publishing/tests/ - - packages/google-cloud-eventarc-publishing/README.rst - - packages/google-cloud-eventarc-publishing/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-filestore - version: 1.16.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/filestore/v1 - service_config: file_v1.yaml - source_roots: - - packages/google-cloud-filestore - preserve_regex: - - packages/google-cloud-filestore/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-filestore/ - release_exclude_paths: - - packages/google-cloud-filestore/.repo-metadata.json - - packages/google-cloud-filestore/noxfile.py - - packages/google-cloud-filestore/tests/ - - packages/google-cloud-filestore/README.rst - - packages/google-cloud-filestore/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-financialservices - version: 0.4.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/financialservices/v1 - service_config: financialservices_v1.yaml - source_roots: - - packages/google-cloud-financialservices - preserve_regex: - - packages/google-cloud-financialservices/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-financialservices/ - release_exclude_paths: - - packages/google-cloud-financialservices/.repo-metadata.json - - packages/google-cloud-financialservices/noxfile.py - - packages/google-cloud-financialservices/tests/ - - packages/google-cloud-financialservices/README.rst - - packages/google-cloud-financialservices/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-firestore - version: 2.27.0 - last_generated_commit: a78b5838b801428bfe5b85758727a46d830b7f39 - apis: - - path: google/firestore/admin/v1 - service_config: firestore_v1.yaml - - path: google/firestore/bundle - - path: google/firestore/v1 - service_config: firestore_v1.yaml - source_roots: - - packages/google-cloud-firestore - preserve_regex: - - ^packages/google-cloud-firestore/CHANGELOG.md - - ^packages/google-cloud-firestore/docs/CHANGELOG.md - remove_regex: - - ^packages/google-cloud-firestore/google/cloud/firestore/__init__.py - - ^packages/google-cloud-firestore/google/cloud/firestore/gapic - - ^packages/google-cloud-firestore/google/cloud/firestore/py.typed - - ^packages/google-cloud-firestore/google/cloud/firestore_v1/__init__.py - - ^packages/google-cloud-firestore/google/cloud/firestore_v1/services - - ^packages/google-cloud-firestore/google/cloud/firestore_v1/types - - ^packages/google-cloud-firestore/google/cloud/firestore_v1/gapic - - ^packages/google-cloud-firestore/google/cloud/firestore_v1/py.typed - - ^packages/google-cloud-firestore/google/cloud/firestore_admin/ - - ^packages/google-cloud-firestore/google/cloud/firestore_admin_v1/__init__.py - - ^packages/google-cloud-firestore/google/cloud/firestore_admin_v1/services - - ^packages/google-cloud-firestore/google/cloud/firestore_admin_v1/types - - ^packages/google-cloud-firestore/google/cloud/firestore_admin_v1/gapic - - ^packages/google-cloud-firestore/google/cloud/firestore_admin_v1/py.typed - - ^packages/google-cloud-firestore/google/cloud/firestore_bundle/__init__.py - - ^packages/google-cloud-firestore/google/cloud/firestore_bundle/services - - ^packages/google-cloud-firestore/google/cloud/firestore_bundle/types - - ^packages/google-cloud-firestore/google/cloud/firestore_bundle/__init__.py - - ^packages/google-cloud-firestore/google/cloud/firestore_bundle/gapic - - ^packages/google-cloud-firestore/google/cloud/firestore_bundle/py.typed - - ^packages/google-cloud-firestore/testing - - ^packages/google-cloud-firestore/tests/unit/gapic - - ^packages/google-cloud-firestore/tests/__init__.py - - ^packages/google-cloud-firestore/tests/unit/__init__.py - - ^packages/google-cloud-firestore/.flake8 - - ^packages/google-cloud-firestore/.repo-metadata.json - - ^packages/google-cloud-firestore/noxfile.py - - ^packages/google-cloud-firestore/tests/ - - ^packages/google-cloud-firestore/.coveragerc - - ^packages/google-cloud-firestore/mypy.ini - - ^packages/google-cloud-firestore/LICENSE - - ^packages/google-cloud-firestore/MANIFEST.in - - ^packages/google-cloud-firestore/noxfile.py - - ^packages/google-cloud-firestore/samples/generated_samples - - ^packages/google-cloud-firestore/setup.py - - ^packages/google-cloud-firestore/README.rst - - ^packages/google-cloud-firestore/docs/_static - - ^packages/google-cloud-firestore/docs/_templates - - ^packages/google-cloud-firestore/docs/firestore_v1/firestore.rst - - ^packages/google-cloud-firestore/docs/firestore_admin_v1/firestore_admin.rst - - ^packages/google-cloud-firestore/docs/firestore_.*/services_.rst - - ^packages/google-cloud-firestore/docs/firestore_.*/types_.rst - - ^packages/google-cloud-firestore/docs/multiprocessing.rst - - ^packages/google-cloud-firestore/docs/conf.py - - ^packages/google-cloud-firestore/docs/index.rst - - ^packages/google-cloud-firestore/README.rst - - ^packages/google-cloud-firestore/docs/ - - ^packages/google-cloud-firestore/docs/summary_overview.md - release_exclude_paths: - - packages/google-cloud-firestore/.repo-metadata.json - - packages/google-cloud-firestore/noxfile.py - - packages/google-cloud-firestore/tests/ - - packages/google-cloud-firestore/README.rst - - packages/google-cloud-firestore/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-functions - version: 1.23.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/functions/v2 - service_config: cloudfunctions_v2.yaml - - path: google/cloud/functions/v1 - service_config: cloudfunctions_v1.yaml - source_roots: - - packages/google-cloud-functions - preserve_regex: - - packages/google-cloud-functions/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-functions/ - release_exclude_paths: - - packages/google-cloud-functions/.repo-metadata.json - - packages/google-cloud-functions/noxfile.py - - packages/google-cloud-functions/tests/ - - packages/google-cloud-functions/README.rst - - packages/google-cloud-functions/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-gdchardwaremanagement - version: 0.5.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/gdchardwaremanagement/v1alpha - service_config: gdchardwaremanagement_v1alpha.yaml - source_roots: - - packages/google-cloud-gdchardwaremanagement - preserve_regex: - - packages/google-cloud-gdchardwaremanagement/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-gdchardwaremanagement/ - release_exclude_paths: - - packages/google-cloud-gdchardwaremanagement/.repo-metadata.json - - packages/google-cloud-gdchardwaremanagement/noxfile.py - - packages/google-cloud-gdchardwaremanagement/tests/ - - packages/google-cloud-gdchardwaremanagement/README.rst - - packages/google-cloud-gdchardwaremanagement/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-geminidataanalytics - version: 0.13.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/geminidataanalytics/v1beta - service_config: geminidataanalytics_v1beta.yaml - - path: google/cloud/geminidataanalytics/v1alpha - service_config: geminidataanalytics_v1alpha.yaml - - path: google/cloud/geminidataanalytics/v1 - source_roots: - - packages/google-cloud-geminidataanalytics - preserve_regex: - - packages/google-cloud-geminidataanalytics/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-geminidataanalytics/ - release_exclude_paths: - - packages/google-cloud-geminidataanalytics/.repo-metadata.json - - packages/google-cloud-geminidataanalytics/noxfile.py - - packages/google-cloud-geminidataanalytics/tests/ - - packages/google-cloud-geminidataanalytics/README.rst - - packages/google-cloud-geminidataanalytics/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-gke-backup - version: 0.8.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/gkebackup/v1 - service_config: gkebackup_v1.yaml - source_roots: - - packages/google-cloud-gke-backup - preserve_regex: - - packages/google-cloud-gke-backup/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-gke-backup/ - release_exclude_paths: - - packages/google-cloud-gke-backup/.repo-metadata.json - - packages/google-cloud-gke-backup/noxfile.py - - packages/google-cloud-gke-backup/tests/ - - packages/google-cloud-gke-backup/README.rst - - packages/google-cloud-gke-backup/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-gke-connect-gateway - version: 0.13.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/gkeconnect/gateway/v1beta1 - service_config: connectgateway_v1beta1.yaml - - path: google/cloud/gkeconnect/gateway/v1 - service_config: connectgateway_v1.yaml - source_roots: - - packages/google-cloud-gke-connect-gateway - preserve_regex: - - packages/google-cloud-gke-connect-gateway/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-gke-connect-gateway/ - release_exclude_paths: - - packages/google-cloud-gke-connect-gateway/.repo-metadata.json - - packages/google-cloud-gke-connect-gateway/noxfile.py - - packages/google-cloud-gke-connect-gateway/tests/ - - packages/google-cloud-gke-connect-gateway/README.rst - - packages/google-cloud-gke-connect-gateway/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-gke-hub - version: 1.24.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/gkehub/v1 - service_config: gkehub_v1.yaml - - path: google/cloud/gkehub/v1beta1 - service_config: gkehub_v1beta1.yaml - source_roots: - - packages/google-cloud-gke-hub - preserve_regex: - - packages/google-cloud-gke-hub/CHANGELOG.md - - docs/CHANGELOG.md - - docs/gkehub_v1/configmanagement_v1 - - docs/gkehub_v1/multiclusteringress_v1 - - docs/gkehub_v1/rbacrolebindingactuation_v1 - - google/cloud/gkehub_v1/configmanagement_v1 - - google/cloud/gkehub_v1/multiclusteringress_v1 - - google/cloud/gkehub_v1/rbacrolebindingactuation_v1 - remove_regex: - - packages/google-cloud-gke-hub - release_exclude_paths: - - packages/google-cloud-gke-hub/.repo-metadata.json - - packages/google-cloud-gke-hub/noxfile.py - - packages/google-cloud-gke-hub/tests/ - - packages/google-cloud-gke-hub/README.rst - - packages/google-cloud-gke-hub/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-gke-multicloud - version: 0.9.0 - last_generated_commit: 535d161c24965e9ed1a0b27032cc1c8b4beab818 - apis: - - path: google/cloud/gkemulticloud/v1 - service_config: gkemulticloud_v1.yaml - source_roots: - - packages/google-cloud-gke-multicloud - preserve_regex: - - packages/google-cloud-gke-multicloud/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-gke-multicloud - release_exclude_paths: - - packages/google-cloud-gke-multicloud/.repo-metadata.json - - packages/google-cloud-gke-multicloud/noxfile.py - - packages/google-cloud-gke-multicloud/tests/ - - packages/google-cloud-gke-multicloud/README.rst - - packages/google-cloud-gke-multicloud/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-gkerecommender - version: 0.3.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/gkerecommender/v1 - service_config: gkerecommender_v1.yaml - source_roots: - - packages/google-cloud-gkerecommender - preserve_regex: - - packages/google-cloud-gkerecommender/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-gkerecommender - release_exclude_paths: - - packages/google-cloud-gkerecommender/.repo-metadata.json - - packages/google-cloud-gkerecommender/noxfile.py - - packages/google-cloud-gkerecommender/tests/ - - packages/google-cloud-gkerecommender/README.rst - - packages/google-cloud-gkerecommender/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-gsuiteaddons - version: 0.5.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/gsuiteaddons/v1 - service_config: gsuiteaddons_v1.yaml - source_roots: - - packages/google-cloud-gsuiteaddons - preserve_regex: - - packages/google-cloud-gsuiteaddons/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-gsuiteaddons - release_exclude_paths: - - packages/google-cloud-gsuiteaddons/.repo-metadata.json - - packages/google-cloud-gsuiteaddons/noxfile.py - - packages/google-cloud-gsuiteaddons/tests/ - - packages/google-cloud-gsuiteaddons/README.rst - - packages/google-cloud-gsuiteaddons/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-hypercomputecluster - version: 0.4.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/hypercomputecluster/v1beta - service_config: hypercomputecluster_v1beta.yaml - - path: google/cloud/hypercomputecluster/v1 - service_config: hypercomputecluster_v1.yaml - source_roots: - - packages/google-cloud-hypercomputecluster - preserve_regex: - - packages/google-cloud-hypercomputecluster/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-hypercomputecluster - release_exclude_paths: - - packages/google-cloud-hypercomputecluster/.repo-metadata.json - - packages/google-cloud-hypercomputecluster/noxfile.py - - packages/google-cloud-hypercomputecluster/tests/ - - packages/google-cloud-hypercomputecluster/README.rst - - packages/google-cloud-hypercomputecluster/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-iam - version: 2.23.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/iam/v3 - service_config: iam_v3.yaml - - path: google/iam/v3beta - service_config: iam_v3beta.yaml - - path: google/iam/admin/v1 - service_config: iam.yaml - - path: google/iam/v2 - service_config: iam_v2.yaml - - path: google/iam/credentials/v1 - service_config: iamcredentials_v1.yaml - - path: google/iam/v2beta - service_config: iam_v2beta.yaml - source_roots: - - packages/google-cloud-iam - preserve_regex: - - packages/google-cloud-iam/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-iam - release_exclude_paths: - - packages/google-cloud-iam/.repo-metadata.json - - packages/google-cloud-iam/noxfile.py - - packages/google-cloud-iam/tests/ - - packages/google-cloud-iam/README.rst - - packages/google-cloud-iam/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-iam-logging - version: 1.7.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/iam/v1/logging - source_roots: - - packages/google-cloud-iam-logging - preserve_regex: - - packages/google-cloud-iam-logging/CHANGELOG.md - - docs/CHANGELOG.md - - tests/unit/gapic/iam_logging_v1/test_iam_logging.py - remove_regex: - - packages/google-cloud-iam-logging/ - release_exclude_paths: - - packages/google-cloud-iam-logging/.repo-metadata.json - - packages/google-cloud-iam-logging/noxfile.py - - packages/google-cloud-iam-logging/tests/ - - packages/google-cloud-iam-logging/README.rst - - packages/google-cloud-iam-logging/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-iamconnectorcredentials - version: 0.1.0 - last_generated_commit: 13b86d1d083c314bf51e42c19f9f6ed941e0553b - apis: - - path: google/cloud/iamconnectorcredentials/v1alpha - service_config: iamconnectorcredentials_v1alpha.yaml - source_roots: - - packages/google-cloud-iamconnectorcredentials - preserve_regex: - - packages/google-cloud-iamconnectorcredentials/CHANGELOG.md - - docs/CHANGELOG.md - - samples/README.txt - - scripts/client-post-processing - - samples/snippets/README.rst - - tests/system - remove_regex: - - packages/google-cloud-iamconnectorcredentials - release_exclude_paths: - - packages/google-cloud-iamconnectorcredentials/.repo-metadata.json - - packages/google-cloud-iamconnectorcredentials/noxfile.py - - packages/google-cloud-iamconnectorcredentials/tests/ - - packages/google-cloud-iamconnectorcredentials/README.rst - - packages/google-cloud-iamconnectorcredentials/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-iap - version: 1.21.0 - last_generated_commit: ebfdba37e54d9cd3e78380d226c2c4ab5a5f7fd4 - apis: - - path: google/cloud/iap/v1 - service_config: iap_v1.yaml - source_roots: - - packages/google-cloud-iap - preserve_regex: - - packages/google-cloud-iap/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-iap/ - release_exclude_paths: - - packages/google-cloud-iap/.repo-metadata.json - - packages/google-cloud-iap/noxfile.py - - packages/google-cloud-iap/tests/ - - packages/google-cloud-iap/README.rst - - packages/google-cloud-iap/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-ids - version: 1.13.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/ids/v1 - service_config: ids_v1.yaml - source_roots: - - packages/google-cloud-ids - preserve_regex: - - packages/google-cloud-ids/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-ids/ - release_exclude_paths: - - packages/google-cloud-ids/.repo-metadata.json - - packages/google-cloud-ids/noxfile.py - - packages/google-cloud-ids/tests/ - - packages/google-cloud-ids/README.rst - - packages/google-cloud-ids/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-kms - version: 3.13.0 - last_generated_commit: 1133adb136f742df62864f1d9d307df25d451880 - apis: - - path: google/cloud/kms/v1 - service_config: cloudkms_v1.yaml - source_roots: - - packages/google-cloud-kms - preserve_regex: - - packages/google-cloud-kms/CHANGELOG.md - - docs/CHANGELOG.md - - tests/system - remove_regex: - - packages/google-cloud-kms/ - release_exclude_paths: - - packages/google-cloud-kms/.repo-metadata.json - - packages/google-cloud-kms/noxfile.py - - packages/google-cloud-kms/tests/ - - packages/google-cloud-kms/README.rst - - packages/google-cloud-kms/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-kms-inventory - version: 0.6.0 - last_generated_commit: 1133adb136f742df62864f1d9d307df25d451880 - apis: - - path: google/cloud/kms/inventory/v1 - service_config: kmsinventory_v1.yaml - source_roots: - - packages/google-cloud-kms-inventory - preserve_regex: - - packages/google-cloud-kms-inventory/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-kms-inventory/ - release_exclude_paths: - - packages/google-cloud-kms-inventory/.repo-metadata.json - - packages/google-cloud-kms-inventory/noxfile.py - - packages/google-cloud-kms-inventory/tests/ - - packages/google-cloud-kms-inventory/README.rst - - packages/google-cloud-kms-inventory/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-language - version: 2.20.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/language/v1 - service_config: language_v1.yaml - - path: google/cloud/language/v1beta2 - service_config: language_v1beta2.yaml - - path: google/cloud/language/v2 - service_config: language_v2.yaml - source_roots: - - packages/google-cloud-language - preserve_regex: - - packages/google-cloud-language/CHANGELOG.md - - docs/CHANGELOG.md - - samples/README.txt - remove_regex: - - packages/google-cloud-language/ - release_exclude_paths: - - packages/google-cloud-language/.repo-metadata.json - - packages/google-cloud-language/noxfile.py - - packages/google-cloud-language/tests/ - - packages/google-cloud-language/README.rst - - packages/google-cloud-language/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-licensemanager - version: 0.4.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/licensemanager/v1 - service_config: licensemanager_v1.yaml - source_roots: - - packages/google-cloud-licensemanager - preserve_regex: - - packages/google-cloud-licensemanager/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-licensemanager/ - release_exclude_paths: - - packages/google-cloud-licensemanager/.repo-metadata.json - - packages/google-cloud-licensemanager/noxfile.py - - packages/google-cloud-licensemanager/tests/ - - packages/google-cloud-licensemanager/README.rst - - packages/google-cloud-licensemanager/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-life-sciences - version: 0.12.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/lifesciences/v2beta - service_config: lifesciences_v2beta.yaml - source_roots: - - packages/google-cloud-life-sciences - preserve_regex: - - packages/google-cloud-life-sciences/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-life-sciences/ - release_exclude_paths: - - packages/google-cloud-life-sciences/.repo-metadata.json - - packages/google-cloud-life-sciences/noxfile.py - - packages/google-cloud-life-sciences/tests/ - - packages/google-cloud-life-sciences/README.rst - - packages/google-cloud-life-sciences/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-locationfinder - version: 0.4.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/locationfinder/v1 - service_config: cloudlocationfinder_v1.yaml - source_roots: - - packages/google-cloud-locationfinder - preserve_regex: - - packages/google-cloud-locationfinder/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-locationfinder/ - release_exclude_paths: - - packages/google-cloud-locationfinder/.repo-metadata.json - - packages/google-cloud-locationfinder/noxfile.py - - packages/google-cloud-locationfinder/tests/ - - packages/google-cloud-locationfinder/README.rst - - packages/google-cloud-locationfinder/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-logging - version: 3.16.0 - last_generated_commit: 59d5f2b46924714af627ac29ea6de78641a00835 - apis: - - path: google/logging/v2 - service_config: logging_v2.yaml - source_roots: - - packages/google-cloud-logging - preserve_regex: - - packages/google-cloud-logging/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - ^packages/google-cloud-logging/.coveragerc - - ^packages/google-cloud-logging/.flake8 - - ^packages/google-cloud-logging/.repo-metadata.json - - ^packages/google-cloud-logging/noxfile.py - - ^packages/google-cloud-logging/tests/ - - ^packages/google-cloud-logging/LICENSE - - ^packages/google-cloud-logging/MANIFEST.in - - ^packages/google-cloud-logging/README.rst - - ^packages/google-cloud-logging/mypy.ini - - ^packages/google-cloud-logging/noxfile.py - - ^packages/google-cloud-logging/setup.py - - ^packages/google-cloud-logging/docs/conf.py - - ^packages/google-cloud-logging/docs/index.rst - - ^packages/google-cloud-logging/docs/multiprocessing.rst - - ^packages/google-cloud-logging/docs/summary_overview.md - - ^packages/google-cloud-logging/README.rst - - ^packages/google-cloud-logging/docs/ - - ^packages/google-cloud-logging/docs/_static/custom.css - - ^packages/google-cloud-logging/docs/_templates - - ^packages/google-cloud-logging/docs/logging_v2 - - ^packages/google-cloud-logging/google/cloud/logging_v2/__init__.py - - ^packages/google-cloud-logging/google/cloud/logging_v2/services - - ^packages/google-cloud-logging/google/cloud/logging_v2/types - - ^packages/google-cloud-logging/google/cloud/logging_v2/gapic_version.py - - ^packages/google-cloud-logging/google/cloud/logging_v2/gapic_metadata.json - - ^packages/google-cloud-logging/google/cloud/logging_v2/py.typed - - ^packages/google-cloud-logging/google/cloud/logging/__init__.py - - ^packages/google-cloud-logging/google/cloud/logging/gapic_version.py - - ^packages/google-cloud-logging/google/cloud/logging/py.typed - - ^packages/google-cloud-logging/samples/generated_samples - - ^packages/google-cloud-logging/testing - - ^packages/google-cloud-logging/tests/__init__.py - - ^packages/google-cloud-logging/tests/unit/__init__.py - - ^packages/google-cloud-logging/tests/unit/gapic - release_exclude_paths: - - packages/google-cloud-logging/.repo-metadata.json - - packages/google-cloud-logging/noxfile.py - - packages/google-cloud-logging/tests/ - - packages/google-cloud-logging/README.rst - - packages/google-cloud-logging/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-lustre - version: 0.4.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/lustre/v1 - service_config: lustre_v1.yaml - source_roots: - - packages/google-cloud-lustre - preserve_regex: - - packages/google-cloud-lustre/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-lustre/ - release_exclude_paths: - - packages/google-cloud-lustre/.repo-metadata.json - - packages/google-cloud-lustre/noxfile.py - - packages/google-cloud-lustre/tests/ - - packages/google-cloud-lustre/README.rst - - packages/google-cloud-lustre/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-maintenance-api - version: 0.4.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/maintenance/api/v1beta - service_config: maintenance_v1beta.yaml - - path: google/cloud/maintenance/api/v1 - service_config: maintenance_v1.yaml - source_roots: - - packages/google-cloud-maintenance-api - preserve_regex: - - packages/google-cloud-maintenance-api/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-maintenance-api/ - release_exclude_paths: - - packages/google-cloud-maintenance-api/.repo-metadata.json - - packages/google-cloud-maintenance-api/noxfile.py - - packages/google-cloud-maintenance-api/tests/ - - packages/google-cloud-maintenance-api/README.rst - - packages/google-cloud-maintenance-api/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-managed-identities - version: 1.15.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/managedidentities/v1 - service_config: managedidentities_v1.yaml - source_roots: - - packages/google-cloud-managed-identities - preserve_regex: - - packages/google-cloud-managed-identities/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-managed-identities/ - release_exclude_paths: - - packages/google-cloud-managed-identities/.repo-metadata.json - - packages/google-cloud-managed-identities/noxfile.py - - packages/google-cloud-managed-identities/tests/ - - packages/google-cloud-managed-identities/README.rst - - packages/google-cloud-managed-identities/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-managedkafka - version: 0.4.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/managedkafka/v1 - service_config: managedkafka_v1.yaml - source_roots: - - packages/google-cloud-managedkafka - preserve_regex: - - packages/google-cloud-managedkafka/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-managedkafka/ - release_exclude_paths: - - packages/google-cloud-managedkafka/.repo-metadata.json - - packages/google-cloud-managedkafka/noxfile.py - - packages/google-cloud-managedkafka/tests/ - - packages/google-cloud-managedkafka/README.rst - - packages/google-cloud-managedkafka/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-managedkafka-schemaregistry - version: 0.4.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/managedkafka/schemaregistry/v1 - service_config: managedkafka_v1.yaml - source_roots: - - packages/google-cloud-managedkafka-schemaregistry - preserve_regex: - - packages/google-cloud-managedkafka-schemaregistry/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-managedkafka-schemaregistry/ - release_exclude_paths: - - packages/google-cloud-managedkafka-schemaregistry/.repo-metadata.json - - packages/google-cloud-managedkafka-schemaregistry/noxfile.py - - packages/google-cloud-managedkafka-schemaregistry/tests/ - - packages/google-cloud-managedkafka-schemaregistry/README.rst - - packages/google-cloud-managedkafka-schemaregistry/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-media-translation - version: 0.14.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/mediatranslation/v1beta1 - service_config: mediatranslation_v1beta1.yaml - source_roots: - - packages/google-cloud-media-translation - preserve_regex: - - packages/google-cloud-media-translation/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-media-translation/ - release_exclude_paths: - - packages/google-cloud-media-translation/.repo-metadata.json - - packages/google-cloud-media-translation/noxfile.py - - packages/google-cloud-media-translation/tests/ - - packages/google-cloud-media-translation/README.rst - - packages/google-cloud-media-translation/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-memcache - version: 1.15.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/memcache/v1 - service_config: memcache_v1.yaml - - path: google/cloud/memcache/v1beta2 - service_config: memcache_v1beta2.yaml - source_roots: - - packages/google-cloud-memcache - preserve_regex: - - packages/google-cloud-memcache/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-memcache/ - release_exclude_paths: - - packages/google-cloud-memcache/.repo-metadata.json - - packages/google-cloud-memcache/noxfile.py - - packages/google-cloud-memcache/tests/ - - packages/google-cloud-memcache/README.rst - - packages/google-cloud-memcache/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-memorystore - version: 0.5.0 - last_generated_commit: 2233f63baf69c2a481f30180045fcf036242781d - apis: - - path: google/cloud/memorystore/v1beta - service_config: memorystore_v1beta.yaml - - path: google/cloud/memorystore/v1 - service_config: memorystore_v1.yaml - source_roots: - - packages/google-cloud-memorystore - preserve_regex: - - packages/google-cloud-memorystore/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-memorystore/ - release_exclude_paths: - - packages/google-cloud-memorystore/.repo-metadata.json - - packages/google-cloud-memorystore/noxfile.py - - packages/google-cloud-memorystore/tests/ - - packages/google-cloud-memorystore/README.rst - - packages/google-cloud-memorystore/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-migrationcenter - version: 0.4.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/migrationcenter/v1 - service_config: migrationcenter_v1.yaml - source_roots: - - packages/google-cloud-migrationcenter - preserve_regex: - - packages/google-cloud-migrationcenter/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-migrationcenter/ - release_exclude_paths: - - packages/google-cloud-migrationcenter/.repo-metadata.json - - packages/google-cloud-migrationcenter/noxfile.py - - packages/google-cloud-migrationcenter/tests/ - - packages/google-cloud-migrationcenter/README.rst - - packages/google-cloud-migrationcenter/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-modelarmor - version: 0.7.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/modelarmor/v1beta - service_config: modelarmor_v1beta.yaml - - path: google/cloud/modelarmor/v1 - service_config: modelarmor_v1.yaml - source_roots: - - packages/google-cloud-modelarmor - preserve_regex: - - packages/google-cloud-modelarmor/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-modelarmor/ - release_exclude_paths: - - packages/google-cloud-modelarmor/.repo-metadata.json - - packages/google-cloud-modelarmor/noxfile.py - - packages/google-cloud-modelarmor/tests/ - - packages/google-cloud-modelarmor/README.rst - - packages/google-cloud-modelarmor/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-monitoring - version: 2.31.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/monitoring/v3 - service_config: monitoring.yaml - source_roots: - - packages/google-cloud-monitoring - preserve_regex: - - packages/google-cloud-monitoring/CHANGELOG.md - - docs/CHANGELOG.md - - docs/query.rst - - packages/google-cloud-monitoring/google/cloud/monitoring_v3/_dataframe.py - - packages/google-cloud-monitoring/google/cloud/monitoring_v3/query.py - - tests/system - - tests/unit/test__dataframe.py - - tests/unit/test_query.py - remove_regex: - - packages/google-cloud-monitoring - release_exclude_paths: - - packages/google-cloud-monitoring/.repo-metadata.json - - packages/google-cloud-monitoring/noxfile.py - - packages/google-cloud-monitoring/tests/ - - packages/google-cloud-monitoring/README.rst - - packages/google-cloud-monitoring/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-monitoring-dashboards - version: 2.21.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/monitoring/dashboard/v1 - service_config: monitoring.yaml - source_roots: - - packages/google-cloud-monitoring-dashboards - preserve_regex: - - packages/google-cloud-monitoring-dashboards/CHANGELOG.md - - docs/CHANGELOG.md - - packages/google-cloud-monitoring-dashboards/google/monitoring - - tests/unit/gapic/dashboard_v1 - remove_regex: - - packages/google-cloud-monitoring-dashboards - release_exclude_paths: - - packages/google-cloud-monitoring-dashboards/.repo-metadata.json - - packages/google-cloud-monitoring-dashboards/noxfile.py - - packages/google-cloud-monitoring-dashboards/tests/ - - packages/google-cloud-monitoring-dashboards/README.rst - - packages/google-cloud-monitoring-dashboards/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-monitoring-metrics-scopes - version: 1.12.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/monitoring/metricsscope/v1 - service_config: monitoring.yaml - source_roots: - - packages/google-cloud-monitoring-metrics-scopes - preserve_regex: - - packages/google-cloud-monitoring-metrics-scopes/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-monitoring-metrics-scopes/ - release_exclude_paths: - - packages/google-cloud-monitoring-metrics-scopes/.repo-metadata.json - - packages/google-cloud-monitoring-metrics-scopes/noxfile.py - - packages/google-cloud-monitoring-metrics-scopes/tests/ - - packages/google-cloud-monitoring-metrics-scopes/README.rst - - packages/google-cloud-monitoring-metrics-scopes/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-ndb - version: 2.5.0 - last_generated_commit: "" - apis: [] - source_roots: - - packages/google-cloud-ndb - preserve_regex: [] - remove_regex: [] - release_exclude_paths: - - packages/google-cloud-ndb/.repo-metadata.json - - packages/google-cloud-ndb/noxfile.py - - packages/google-cloud-ndb/tests/ - - packages/google-cloud-ndb/README.rst - - packages/google-cloud-ndb/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-netapp - version: 0.10.0 - last_generated_commit: 582172de2d9b6443e1fecf696167867c6d8a5fc4 - apis: - - path: google/cloud/netapp/v1 - service_config: netapp_v1.yaml - source_roots: - - packages/google-cloud-netapp - preserve_regex: - - packages/google-cloud-netapp/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-netapp/ - release_exclude_paths: - - packages/google-cloud-netapp/.repo-metadata.json - - packages/google-cloud-netapp/noxfile.py - - packages/google-cloud-netapp/tests/ - - packages/google-cloud-netapp/README.rst - - packages/google-cloud-netapp/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-network-connectivity - version: 2.15.0 - last_generated_commit: 77291a3c21b89ebfab5a473a5cbf0eb6eec22a30 - apis: - - path: google/cloud/networkconnectivity/v1 - service_config: networkconnectivity_v1.yaml - - path: google/cloud/networkconnectivity/v1alpha1 - service_config: networkconnectivity_v1alpha1.yaml - - path: google/cloud/networkconnectivity/v1beta - service_config: networkconnectivity_v1beta.yaml - source_roots: - - packages/google-cloud-network-connectivity - preserve_regex: - - packages/google-cloud-network-connectivity/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-network-connectivity/ - release_exclude_paths: - - packages/google-cloud-network-connectivity/.repo-metadata.json - - packages/google-cloud-network-connectivity/noxfile.py - - packages/google-cloud-network-connectivity/tests/ - - packages/google-cloud-network-connectivity/README.rst - - packages/google-cloud-network-connectivity/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-network-management - version: 1.35.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/networkmanagement/v1 - service_config: networkmanagement_v1.yaml - source_roots: - - packages/google-cloud-network-management - preserve_regex: - - packages/google-cloud-network-management/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-network-management/ - release_exclude_paths: - - packages/google-cloud-network-management/.repo-metadata.json - - packages/google-cloud-network-management/noxfile.py - - packages/google-cloud-network-management/tests/ - - packages/google-cloud-network-management/README.rst - - packages/google-cloud-network-management/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-network-security - version: 0.13.0 - last_generated_commit: 582172de2d9b6443e1fecf696167867c6d8a5fc4 - apis: - - path: google/cloud/networksecurity/v1alpha1 - service_config: networksecurity_v1alpha1.yaml - - path: google/cloud/networksecurity/v1beta1 - service_config: networksecurity_v1beta1.yaml - - path: google/cloud/networksecurity/v1 - service_config: networksecurity_v1.yaml - source_roots: - - packages/google-cloud-network-security - preserve_regex: - - packages/google-cloud-network-security/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-network-security - release_exclude_paths: - - packages/google-cloud-network-security/.repo-metadata.json - - packages/google-cloud-network-security/noxfile.py - - packages/google-cloud-network-security/tests/ - - packages/google-cloud-network-security/README.rst - - packages/google-cloud-network-security/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-network-services - version: 0.10.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/networkservices/v1 - service_config: networkservices_v1.yaml - source_roots: - - packages/google-cloud-network-services - preserve_regex: - - packages/google-cloud-network-services/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-network-services/ - release_exclude_paths: - - packages/google-cloud-network-services/.repo-metadata.json - - packages/google-cloud-network-services/noxfile.py - - packages/google-cloud-network-services/tests/ - - packages/google-cloud-network-services/README.rst - - packages/google-cloud-network-services/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-notebooks - version: 1.16.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/notebooks/v1beta1 - service_config: notebooks_v1beta1.yaml - - path: google/cloud/notebooks/v1 - service_config: notebooks_v1.yaml - - path: google/cloud/notebooks/v2 - service_config: notebooks_v2.yaml - source_roots: - - packages/google-cloud-notebooks - preserve_regex: - - packages/google-cloud-notebooks/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-notebooks/ - release_exclude_paths: - - packages/google-cloud-notebooks/.repo-metadata.json - - packages/google-cloud-notebooks/noxfile.py - - packages/google-cloud-notebooks/tests/ - - packages/google-cloud-notebooks/README.rst - - packages/google-cloud-notebooks/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-optimization - version: 1.14.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/optimization/v1 - service_config: cloudoptimization_v1.yaml - source_roots: - - packages/google-cloud-optimization - preserve_regex: - - packages/google-cloud-optimization/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-optimization/ - release_exclude_paths: - - packages/google-cloud-optimization/.repo-metadata.json - - packages/google-cloud-optimization/noxfile.py - - packages/google-cloud-optimization/tests/ - - packages/google-cloud-optimization/README.rst - - packages/google-cloud-optimization/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-oracledatabase - version: 0.6.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/oracledatabase/v1 - service_config: oracledatabase_v1.yaml - source_roots: - - packages/google-cloud-oracledatabase - preserve_regex: - - packages/google-cloud-oracledatabase/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-oracledatabase/ - release_exclude_paths: - - packages/google-cloud-oracledatabase/.repo-metadata.json - - packages/google-cloud-oracledatabase/noxfile.py - - packages/google-cloud-oracledatabase/tests/ - - packages/google-cloud-oracledatabase/README.rst - - packages/google-cloud-oracledatabase/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-orchestration-airflow - version: 1.21.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/orchestration/airflow/service/v1 - service_config: composer_v1.yaml - - path: google/cloud/orchestration/airflow/service/v1beta1 - service_config: composer_v1beta1.yaml - source_roots: - - packages/google-cloud-orchestration-airflow - preserve_regex: - - packages/google-cloud-orchestration-airflow/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-orchestration-airflow/ - release_exclude_paths: - - packages/google-cloud-orchestration-airflow/.repo-metadata.json - - packages/google-cloud-orchestration-airflow/noxfile.py - - packages/google-cloud-orchestration-airflow/tests/ - - packages/google-cloud-orchestration-airflow/README.rst - - packages/google-cloud-orchestration-airflow/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-org-policy - version: 1.17.0 - last_generated_commit: 55319b058f8a0e46bbeeff30e374e4b1f081f494 - apis: - - path: google/cloud/orgpolicy/v1 - - path: google/cloud/orgpolicy/v2 - service_config: orgpolicy_v2.yaml - source_roots: - - packages/google-cloud-org-policy - preserve_regex: - - packages/google-cloud-org-policy/pytest.ini - - packages/google-cloud-org-policy/CHANGELOG.md - - google/cloud/orgpolicy/v1/__init__.py - - docs/CHANGELOG.md - - tests/unit/test_packaging.py - remove_regex: - - packages/google-cloud-org-policy - release_exclude_paths: - - packages/google-cloud-org-policy/.repo-metadata.json - - packages/google-cloud-org-policy/noxfile.py - - packages/google-cloud-org-policy/tests/ - - packages/google-cloud-org-policy/README.rst - - packages/google-cloud-org-policy/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-os-config - version: 1.24.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/osconfig/v1alpha - service_config: osconfig_v1alpha.yaml - - path: google/cloud/osconfig/v1 - service_config: osconfig_v1.yaml - source_roots: - - packages/google-cloud-os-config - preserve_regex: - - packages/google-cloud-os-config/CHANGELOG.md - - docs/CHANGELOG.md - - tests/system - remove_regex: - - packages/google-cloud-os-config/ - release_exclude_paths: - - packages/google-cloud-os-config/.repo-metadata.json - - packages/google-cloud-os-config/noxfile.py - - packages/google-cloud-os-config/tests/ - - packages/google-cloud-os-config/README.rst - - packages/google-cloud-os-config/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-os-login - version: 2.21.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/oslogin/v1 - service_config: oslogin_v1.yaml - source_roots: - - packages/google-cloud-os-login - preserve_regex: - - packages/google-cloud-os-login/CHANGELOG.md - - docs/CHANGELOG.md - - google/cloud/oslogin_v1/common - - docs/oslogin_v1/common/types.rst - remove_regex: - - packages/google-cloud-os-login - release_exclude_paths: - - packages/google-cloud-os-login/.repo-metadata.json - - packages/google-cloud-os-login/noxfile.py - - packages/google-cloud-os-login/tests/ - - packages/google-cloud-os-login/README.rst - - packages/google-cloud-os-login/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-parallelstore - version: 0.6.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/parallelstore/v1 - service_config: parallelstore_v1.yaml - - path: google/cloud/parallelstore/v1beta - service_config: parallelstore_v1beta.yaml - source_roots: - - packages/google-cloud-parallelstore - preserve_regex: - - packages/google-cloud-parallelstore/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-parallelstore/ - release_exclude_paths: - - packages/google-cloud-parallelstore/.repo-metadata.json - - packages/google-cloud-parallelstore/noxfile.py - - packages/google-cloud-parallelstore/tests/ - - packages/google-cloud-parallelstore/README.rst - - packages/google-cloud-parallelstore/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-parametermanager - version: 0.4.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/parametermanager/v1 - service_config: parametermanager_v1.yaml - source_roots: - - packages/google-cloud-parametermanager - preserve_regex: - - packages/google-cloud-parametermanager/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-parametermanager/ - release_exclude_paths: - - packages/google-cloud-parametermanager/.repo-metadata.json - - packages/google-cloud-parametermanager/noxfile.py - - packages/google-cloud-parametermanager/tests/ - - packages/google-cloud-parametermanager/README.rst - - packages/google-cloud-parametermanager/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-phishing-protection - version: 1.17.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/phishingprotection/v1beta1 - service_config: phishingprotection_v1beta1.yaml - source_roots: - - packages/google-cloud-phishing-protection - preserve_regex: - - packages/google-cloud-phishing-protection/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-phishing-protection/ - release_exclude_paths: - - packages/google-cloud-phishing-protection/.repo-metadata.json - - packages/google-cloud-phishing-protection/noxfile.py - - packages/google-cloud-phishing-protection/tests/ - - packages/google-cloud-phishing-protection/README.rst - - packages/google-cloud-phishing-protection/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-policy-troubleshooter - version: 1.16.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/policytroubleshooter/v1 - service_config: policytroubleshooter_v1.yaml - source_roots: - - packages/google-cloud-policy-troubleshooter - preserve_regex: - - packages/google-cloud-policy-troubleshooter/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-policy-troubleshooter/ - release_exclude_paths: - - packages/google-cloud-policy-troubleshooter/.repo-metadata.json - - packages/google-cloud-policy-troubleshooter/noxfile.py - - packages/google-cloud-policy-troubleshooter/tests/ - - packages/google-cloud-policy-troubleshooter/README.rst - - packages/google-cloud-policy-troubleshooter/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-policysimulator - version: 0.4.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/policysimulator/v1 - service_config: policysimulator_v1.yaml - source_roots: - - packages/google-cloud-policysimulator - preserve_regex: - - packages/google-cloud-policysimulator/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-policysimulator/ - release_exclude_paths: - - packages/google-cloud-policysimulator/.repo-metadata.json - - packages/google-cloud-policysimulator/noxfile.py - - packages/google-cloud-policysimulator/tests/ - - packages/google-cloud-policysimulator/README.rst - - packages/google-cloud-policysimulator/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-policytroubleshooter-iam - version: 0.5.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/policytroubleshooter/iam/v3 - service_config: policytroubleshooter_v3.yaml - source_roots: - - packages/google-cloud-policytroubleshooter-iam - preserve_regex: - - packages/google-cloud-policytroubleshooter-iam/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-policytroubleshooter-iam/ - release_exclude_paths: - - packages/google-cloud-policytroubleshooter-iam/.repo-metadata.json - - packages/google-cloud-policytroubleshooter-iam/noxfile.py - - packages/google-cloud-policytroubleshooter-iam/tests/ - - packages/google-cloud-policytroubleshooter-iam/README.rst - - packages/google-cloud-policytroubleshooter-iam/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-private-ca - version: 1.18.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/security/privateca/v1 - service_config: privateca_v1.yaml - - path: google/cloud/security/privateca/v1beta1 - service_config: privateca_v1beta1.yaml - source_roots: - - packages/google-cloud-private-ca - preserve_regex: - - packages/google-cloud-private-ca/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-private-ca/ - release_exclude_paths: - - packages/google-cloud-private-ca/.repo-metadata.json - - packages/google-cloud-private-ca/noxfile.py - - packages/google-cloud-private-ca/tests/ - - packages/google-cloud-private-ca/README.rst - - packages/google-cloud-private-ca/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-private-catalog - version: 0.12.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/privatecatalog/v1beta1 - service_config: cloudprivatecatalog_v1beta1.yaml - source_roots: - - packages/google-cloud-private-catalog - preserve_regex: - - packages/google-cloud-private-catalog/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-private-catalog/ - release_exclude_paths: - - packages/google-cloud-private-catalog/.repo-metadata.json - - packages/google-cloud-private-catalog/noxfile.py - - packages/google-cloud-private-catalog/tests/ - - packages/google-cloud-private-catalog/README.rst - - packages/google-cloud-private-catalog/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-privilegedaccessmanager - version: 0.4.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/privilegedaccessmanager/v1 - service_config: privilegedaccessmanager_v1.yaml - source_roots: - - packages/google-cloud-privilegedaccessmanager - preserve_regex: - - packages/google-cloud-privilegedaccessmanager/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-privilegedaccessmanager/ - release_exclude_paths: - - packages/google-cloud-privilegedaccessmanager/.repo-metadata.json - - packages/google-cloud-privilegedaccessmanager/noxfile.py - - packages/google-cloud-privilegedaccessmanager/tests/ - - packages/google-cloud-privilegedaccessmanager/README.rst - - packages/google-cloud-privilegedaccessmanager/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-pubsub - version: 2.39.0 - last_generated_commit: 2233f63baf69c2a481f30180045fcf036242781d - apis: - - path: google/pubsub/v1 - service_config: pubsub_v1.yaml - source_roots: - - packages/google-cloud-pubsub - preserve_regex: - - packages/google-cloud-pubsub/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - ^packages/google-cloud-pubsub/.coveragerc - - ^packages/google-cloud-pubsub/.flake8 - - ^packages/google-cloud-pubsub/.repo-metadata.json - - ^packages/google-cloud-pubsub/noxfile.py - - ^packages/google-cloud-pubsub/tests/ - - ^packages/google-cloud-pubsub/LICENSE - - ^packages/google-cloud-pubsub/MANIFEST.in - - ^packages/google-cloud-pubsub/README.rst - - ^packages/google-cloud-pubsub/mypy.ini - - ^packages/google-cloud-pubsub/noxfile.py - - ^packages/google-cloud-pubsub/setup.py - - ^packages/google-cloud-pubsub/docs/conf.py - - ^packages/google-cloud-pubsub/docs/index.rst - - ^packages/google-cloud-pubsub/README.rst - - ^packages/google-cloud-pubsub/docs/ - - ^packages/google-cloud-pubsub/docs/_static - - ^packages/google-cloud-pubsub/docs/_templates - - ^packages/google-cloud-pubsub/docs/multiprocessing.rst - - ^packages/google-cloud-pubsub/google/pubsub - - ^packages/google-cloud-pubsub/google/pubsub_v1 - - ^packages/google-cloud-pubsub/testing - - ^packages/google-cloud-pubsub/tests/__init__.py - - ^packages/google-cloud-pubsub/tests/unit/__init__.py - - ^packages/google-cloud-pubsub/tests/unit/gapic - - ^packages/google-cloud-pubsub/samples/generated_samples - - ^packages/google-cloud-pubsub/docs/pubsub_v1 - release_exclude_paths: - - packages/google-cloud-pubsub/.repo-metadata.json - - packages/google-cloud-pubsub/noxfile.py - - packages/google-cloud-pubsub/tests/ - - packages/google-cloud-pubsub/README.rst - - packages/google-cloud-pubsub/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-quotas - version: 0.6.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/api/cloudquotas/v1 - service_config: cloudquotas_v1.yaml - - path: google/api/cloudquotas/v1beta - service_config: cloudquotas_v1beta.yaml - source_roots: - - packages/google-cloud-quotas - preserve_regex: - - packages/google-cloud-quotas/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-quotas/ - release_exclude_paths: - - packages/google-cloud-quotas/.repo-metadata.json - - packages/google-cloud-quotas/noxfile.py - - packages/google-cloud-quotas/tests/ - - packages/google-cloud-quotas/README.rst - - packages/google-cloud-quotas/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-rapidmigrationassessment - version: 0.4.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/rapidmigrationassessment/v1 - service_config: rapidmigrationassessment_v1.yaml - source_roots: - - packages/google-cloud-rapidmigrationassessment - preserve_regex: - - packages/google-cloud-rapidmigrationassessment/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-rapidmigrationassessment/ - release_exclude_paths: - - packages/google-cloud-rapidmigrationassessment/.repo-metadata.json - - packages/google-cloud-rapidmigrationassessment/noxfile.py - - packages/google-cloud-rapidmigrationassessment/tests/ - - packages/google-cloud-rapidmigrationassessment/README.rst - - packages/google-cloud-rapidmigrationassessment/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-recaptcha-enterprise - version: 1.31.0 - last_generated_commit: 9a477cd3c26a704130e2a2fb44a40281d9312e4c - apis: - - path: google/cloud/recaptchaenterprise/v1 - service_config: recaptchaenterprise_v1.yaml - source_roots: - - packages/google-cloud-recaptcha-enterprise - preserve_regex: - - packages/google-cloud-recaptcha-enterprise/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-recaptcha-enterprise/ - release_exclude_paths: - - packages/google-cloud-recaptcha-enterprise/.repo-metadata.json - - packages/google-cloud-recaptcha-enterprise/noxfile.py - - packages/google-cloud-recaptcha-enterprise/tests/ - - packages/google-cloud-recaptcha-enterprise/README.rst - - packages/google-cloud-recaptcha-enterprise/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-recommendations-ai - version: 0.13.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/recommendationengine/v1beta1 - service_config: recommendationengine_v1beta1.yaml - source_roots: - - packages/google-cloud-recommendations-ai - preserve_regex: - - packages/google-cloud-recommendations-ai/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-recommendations-ai/ - release_exclude_paths: - - packages/google-cloud-recommendations-ai/.repo-metadata.json - - packages/google-cloud-recommendations-ai/noxfile.py - - packages/google-cloud-recommendations-ai/tests/ - - packages/google-cloud-recommendations-ai/README.rst - - packages/google-cloud-recommendations-ai/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-recommender - version: 2.21.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/recommender/v1beta1 - service_config: recommender_v1beta1.yaml - - path: google/cloud/recommender/v1 - service_config: recommender_v1.yaml - source_roots: - - packages/google-cloud-recommender - preserve_regex: - - packages/google-cloud-recommender/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-recommender/ - release_exclude_paths: - - packages/google-cloud-recommender/.repo-metadata.json - - packages/google-cloud-recommender/noxfile.py - - packages/google-cloud-recommender/tests/ - - packages/google-cloud-recommender/README.rst - - packages/google-cloud-recommender/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-redis - version: 2.21.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/redis/v1 - service_config: redis_v1.yaml - - path: google/cloud/redis/v1beta1 - service_config: redis_v1beta1.yaml - source_roots: - - packages/google-cloud-redis - preserve_regex: - - packages/google-cloud-redis/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-redis/ - release_exclude_paths: - - packages/google-cloud-redis/.repo-metadata.json - - packages/google-cloud-redis/noxfile.py - - packages/google-cloud-redis/tests/ - - packages/google-cloud-redis/README.rst - - packages/google-cloud-redis/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-redis-cluster - version: 0.5.0 - last_generated_commit: 582172de2d9b6443e1fecf696167867c6d8a5fc4 - apis: - - path: google/cloud/redis/cluster/v1 - service_config: redis_v1.yaml - - path: google/cloud/redis/cluster/v1beta1 - service_config: redis_v1beta1.yaml - source_roots: - - packages/google-cloud-redis-cluster - preserve_regex: - - packages/google-cloud-redis-cluster/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-redis-cluster/ - release_exclude_paths: - - packages/google-cloud-redis-cluster/.repo-metadata.json - - packages/google-cloud-redis-cluster/noxfile.py - - packages/google-cloud-redis-cluster/tests/ - - packages/google-cloud-redis-cluster/README.rst - - packages/google-cloud-redis-cluster/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-resource-manager - version: 1.17.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/resourcemanager/v3 - service_config: cloudresourcemanager_v3.yaml - source_roots: - - packages/google-cloud-resource-manager - preserve_regex: - - packages/google-cloud-resource-manager/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-resource-manager/ - release_exclude_paths: - - packages/google-cloud-resource-manager/.repo-metadata.json - - packages/google-cloud-resource-manager/noxfile.py - - packages/google-cloud-resource-manager/tests/ - - packages/google-cloud-resource-manager/README.rst - - packages/google-cloud-resource-manager/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-retail - version: 2.10.0 - last_generated_commit: 256b575f6915282b20795c13414b21f2c0af65db - apis: - - path: google/cloud/retail/v2 - service_config: retail_v2.yaml - - path: google/cloud/retail/v2alpha - service_config: retail_v2alpha.yaml - - path: google/cloud/retail/v2beta - service_config: retail_v2beta.yaml - source_roots: - - packages/google-cloud-retail - preserve_regex: - - packages/google-cloud-retail/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-retail/ - release_exclude_paths: - - packages/google-cloud-retail/.repo-metadata.json - - packages/google-cloud-retail/noxfile.py - - packages/google-cloud-retail/tests/ - - packages/google-cloud-retail/README.rst - - packages/google-cloud-retail/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-run - version: 0.16.0 - last_generated_commit: 59d5f2b46924714af627ac29ea6de78641a00835 - apis: - - path: google/cloud/run/v2 - service_config: run_v2.yaml - source_roots: - - packages/google-cloud-run - preserve_regex: - - packages/google-cloud-run/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-run/ - release_exclude_paths: - - packages/google-cloud-run/.repo-metadata.json - - packages/google-cloud-run/noxfile.py - - packages/google-cloud-run/tests/ - - packages/google-cloud-run/README.rst - - packages/google-cloud-run/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-runtimeconfig - version: 0.37.0 - last_generated_commit: "" - apis: [] - source_roots: - - packages/google-cloud-runtimeconfig - preserve_regex: [] - remove_regex: [] - release_exclude_paths: - - packages/google-cloud-runtimeconfig/.repo-metadata.json - - packages/google-cloud-runtimeconfig/noxfile.py - - packages/google-cloud-runtimeconfig/tests/ - - packages/google-cloud-runtimeconfig/README.rst - - packages/google-cloud-runtimeconfig/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-saasplatform-saasservicemgmt - version: 0.7.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/saasplatform/saasservicemgmt/v1beta1 - service_config: saasservicemgmt_v1beta1.yaml - source_roots: - - packages/google-cloud-saasplatform-saasservicemgmt - preserve_regex: - - packages/google-cloud-saasplatform-saasservicemgmt/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-saasplatform-saasservicemgmt/ - release_exclude_paths: - - packages/google-cloud-saasplatform-saasservicemgmt/.repo-metadata.json - - packages/google-cloud-saasplatform-saasservicemgmt/noxfile.py - - packages/google-cloud-saasplatform-saasservicemgmt/tests/ - - packages/google-cloud-saasplatform-saasservicemgmt/README.rst - - packages/google-cloud-saasplatform-saasservicemgmt/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-scheduler - version: 2.20.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/scheduler/v1 - service_config: cloudscheduler_v1.yaml - - path: google/cloud/scheduler/v1beta1 - service_config: cloudscheduler_v1beta1.yaml - source_roots: - - packages/google-cloud-scheduler - preserve_regex: - - packages/google-cloud-scheduler/CHANGELOG.md - - docs/CHANGELOG.md - - tests/system - remove_regex: - - packages/google-cloud-scheduler/ - release_exclude_paths: - - packages/google-cloud-scheduler/.repo-metadata.json - - packages/google-cloud-scheduler/noxfile.py - - packages/google-cloud-scheduler/tests/ - - packages/google-cloud-scheduler/README.rst - - packages/google-cloud-scheduler/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-secret-manager - version: 2.29.0 - last_generated_commit: ebfdba37e54d9cd3e78380d226c2c4ab5a5f7fd4 - apis: - - path: google/cloud/secretmanager/v1 - service_config: secretmanager_v1.yaml - - path: google/cloud/secretmanager/v1beta2 - service_config: secretmanager_v1beta2.yaml - - path: google/cloud/secrets/v1beta1 - service_config: secretmanager_v1beta1.yaml - source_roots: - - packages/google-cloud-secret-manager - preserve_regex: - - packages/google-cloud-secret-manager/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-secret-manager - release_exclude_paths: - - packages/google-cloud-secret-manager/.repo-metadata.json - - packages/google-cloud-secret-manager/noxfile.py - - packages/google-cloud-secret-manager/tests/ - - packages/google-cloud-secret-manager/README.rst - - packages/google-cloud-secret-manager/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-securesourcemanager - version: 0.6.0 - last_generated_commit: 582172de2d9b6443e1fecf696167867c6d8a5fc4 - apis: - - path: google/cloud/securesourcemanager/v1 - service_config: securesourcemanager_v1.yaml - source_roots: - - packages/google-cloud-securesourcemanager - preserve_regex: - - packages/google-cloud-securesourcemanager/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-securesourcemanager/ - release_exclude_paths: - - packages/google-cloud-securesourcemanager/.repo-metadata.json - - packages/google-cloud-securesourcemanager/noxfile.py - - packages/google-cloud-securesourcemanager/tests/ - - packages/google-cloud-securesourcemanager/README.rst - - packages/google-cloud-securesourcemanager/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-security-publicca - version: 0.7.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/security/publicca/v1 - service_config: publicca_v1.yaml - - path: google/cloud/security/publicca/v1beta1 - service_config: publicca_v1beta1.yaml - source_roots: - - packages/google-cloud-security-publicca - preserve_regex: - - packages/google-cloud-security-publicca/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-security-publicca/ - release_exclude_paths: - - packages/google-cloud-security-publicca/.repo-metadata.json - - packages/google-cloud-security-publicca/noxfile.py - - packages/google-cloud-security-publicca/tests/ - - packages/google-cloud-security-publicca/README.rst - - packages/google-cloud-security-publicca/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-securitycenter - version: 1.45.0 - last_generated_commit: ebfdba37e54d9cd3e78380d226c2c4ab5a5f7fd4 - apis: - - path: google/cloud/securitycenter/v2 - service_config: securitycenter_v2.yaml - - path: google/cloud/securitycenter/v1p1beta1 - service_config: securitycenter_v1p1beta1.yaml - - path: google/cloud/securitycenter/v1beta1 - service_config: securitycenter_v1beta1.yaml - - path: google/cloud/securitycenter/v1 - service_config: securitycenter_v1.yaml - source_roots: - - packages/google-cloud-securitycenter - preserve_regex: - - packages/google-cloud-securitycenter/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-securitycenter/ - release_exclude_paths: - - packages/google-cloud-securitycenter/.repo-metadata.json - - packages/google-cloud-securitycenter/noxfile.py - - packages/google-cloud-securitycenter/tests/ - - packages/google-cloud-securitycenter/README.rst - - packages/google-cloud-securitycenter/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-securitycentermanagement - version: 0.5.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/securitycentermanagement/v1 - service_config: securitycentermanagement_v1.yaml - source_roots: - - packages/google-cloud-securitycentermanagement - preserve_regex: - - packages/google-cloud-securitycentermanagement/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-securitycentermanagement/ - release_exclude_paths: - - packages/google-cloud-securitycentermanagement/.repo-metadata.json - - packages/google-cloud-securitycentermanagement/noxfile.py - - packages/google-cloud-securitycentermanagement/tests/ - - packages/google-cloud-securitycentermanagement/README.rst - - packages/google-cloud-securitycentermanagement/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-service-control - version: 1.20.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/api/servicecontrol/v2 - service_config: servicecontrol.yaml - - path: google/api/servicecontrol/v1 - service_config: servicecontrol.yaml - source_roots: - - packages/google-cloud-service-control - preserve_regex: - - packages/google-cloud-service-control/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-service-control/ - release_exclude_paths: - - packages/google-cloud-service-control/.repo-metadata.json - - packages/google-cloud-service-control/noxfile.py - - packages/google-cloud-service-control/tests/ - - packages/google-cloud-service-control/README.rst - - packages/google-cloud-service-control/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-service-directory - version: 1.18.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/servicedirectory/v1 - service_config: servicedirectory_v1.yaml - - path: google/cloud/servicedirectory/v1beta1 - service_config: servicedirectory_v1beta1.yaml - source_roots: - - packages/google-cloud-service-directory - preserve_regex: - - packages/google-cloud-service-directory/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-service-directory/ - release_exclude_paths: - - packages/google-cloud-service-directory/.repo-metadata.json - - packages/google-cloud-service-directory/noxfile.py - - packages/google-cloud-service-directory/tests/ - - packages/google-cloud-service-directory/README.rst - - packages/google-cloud-service-directory/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-service-management - version: 1.17.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/api/servicemanagement/v1 - service_config: servicemanagement_v1.yaml - source_roots: - - packages/google-cloud-service-management - preserve_regex: - - packages/google-cloud-service-management/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-service-management/ - release_exclude_paths: - - packages/google-cloud-service-management/.repo-metadata.json - - packages/google-cloud-service-management/noxfile.py - - packages/google-cloud-service-management/tests/ - - packages/google-cloud-service-management/README.rst - - packages/google-cloud-service-management/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-service-usage - version: 1.17.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/api/serviceusage/v1 - service_config: serviceusage_v1.yaml - source_roots: - - packages/google-cloud-service-usage - preserve_regex: - - packages/google-cloud-service-usage/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-service-usage/ - release_exclude_paths: - - packages/google-cloud-service-usage/.repo-metadata.json - - packages/google-cloud-service-usage/noxfile.py - - packages/google-cloud-service-usage/tests/ - - packages/google-cloud-service-usage/README.rst - - packages/google-cloud-service-usage/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-servicehealth - version: 0.5.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/servicehealth/v1 - service_config: servicehealth_v1.yaml - source_roots: - - packages/google-cloud-servicehealth - preserve_regex: - - packages/google-cloud-servicehealth/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-servicehealth/ - release_exclude_paths: - - packages/google-cloud-servicehealth/.repo-metadata.json - - packages/google-cloud-servicehealth/noxfile.py - - packages/google-cloud-servicehealth/tests/ - - packages/google-cloud-servicehealth/README.rst - - packages/google-cloud-servicehealth/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-shell - version: 1.16.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/shell/v1 - service_config: cloudshell_v1.yaml - source_roots: - - packages/google-cloud-shell - preserve_regex: - - packages/google-cloud-shell/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-shell/ - release_exclude_paths: - - packages/google-cloud-shell/.repo-metadata.json - - packages/google-cloud-shell/noxfile.py - - packages/google-cloud-shell/tests/ - - packages/google-cloud-shell/README.rst - - packages/google-cloud-shell/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-source-context - version: 1.11.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/devtools/source/v1 - source_roots: - - packages/google-cloud-source-context - preserve_regex: - - packages/google-cloud-source-context/CHANGELOG.md - - docs/CHANGELOG.md - - tests/unit/gapic/source_context_v1/test_source_context_v1.py - remove_regex: - - packages/google-cloud-source-context/ - release_exclude_paths: - - packages/google-cloud-source-context/.repo-metadata.json - - packages/google-cloud-source-context/noxfile.py - - packages/google-cloud-source-context/tests/ - - packages/google-cloud-source-context/README.rst - - packages/google-cloud-source-context/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-spanner - version: 3.68.0 - last_generated_commit: 3e09ac03bab9dba5b8800248cf10190219938a26 - apis: - - path: google/spanner/admin/instance/v1 - service_config: spanner.yaml - - path: google/spanner/admin/database/v1 - service_config: spanner.yaml - - path: google/spanner/v1 - service_config: spanner.yaml - source_roots: - - packages/google-cloud-spanner - preserve_regex: - - packages/google-cloud-spanner/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - ^packages/google-cloud-spanner/.coveragerc - - ^packages/google-cloud-spanner/.flake8 - - ^packages/google-cloud-spanner/.repo-metadata.json - - ^packages/google-cloud-spanner/noxfile.py - - ^packages/google-cloud-spanner/tests/ - - ^packages/google-cloud-spanner/LICENSE - - ^packages/google-cloud-spanner/MANIFEST.in - - ^packages/google-cloud-spanner/README.rst - - ^packages/google-cloud-spanner/mypy.ini - - ^packages/google-cloud-spanner/noxfile.py - - ^packages/google-cloud-spanner/setup.py - - ^packages/google-cloud-spanner/docs/conf.py - - ^packages/google-cloud-spanner/docs/index.rst - - ^packages/google-cloud-spanner/docs/summary_overview.md - - ^packages/google-cloud-spanner/README.rst - - ^packages/google-cloud-spanner/docs/ - - ^packages/google-cloud-spanner/docs/_static - - ^packages/google-cloud-spanner/docs/_templates - - ^packages/google-cloud-spanner/docs/multiprocessing.rst - - ^packages/google-cloud-spanner/docs/spanner_v1/spanner.rst - - ^packages/google-cloud-spanner/docs/spanner_v1/services_.rst - - ^packages/google-cloud-spanner/docs/spanner_v1/types_.rst - - ^packages/google-cloud-spanner/docs/spanner_admin_database_v1/database_admin.rst - - ^packages/google-cloud-spanner/docs/spanner_admin_database_v1/spanner_admin_database.rst - - ^packages/google-cloud-spanner/docs/spanner_admin_database_v1/services_.rst - - ^packages/google-cloud-spanner/docs/spanner_admin_database_v1/types_.rst - - ^packages/google-cloud-spanner/docs/spanner_admin_instance_v1/instance_admin.rst - - ^packages/google-cloud-spanner/docs/spanner_admin_instance_v1/spanner_admin_instance.rst - - ^packages/google-cloud-spanner/docs/spanner_admin_instance_v1/services_.rst - - ^packages/google-cloud-spanner/docs/spanner_admin_instance_v1/types_.rst - - ^packages/google-cloud-spanner/google/cloud/spanner/__init__.py - - ^packages/google-cloud-spanner/google/cloud/spanner/gapic_version.py - - ^packages/google-cloud-spanner/google/cloud/spanner/py.typed - - ^packages/google-cloud-spanner/google/cloud/spanner_v1/__init__.py - - ^packages/google-cloud-spanner/google/cloud/spanner_v1/gapic_metadata.json - - ^packages/google-cloud-spanner/google/cloud/spanner_v1/gapic_version.py - - ^packages/google-cloud-spanner/google/cloud/spanner_v1/py.typed - - ^packages/google-cloud-spanner/google/cloud/spanner_v1/services - - ^packages/google-cloud-spanner/google/cloud/spanner_v1/types - - ^packages/google-cloud-spanner/google/cloud/spanner_admin_database_v1/__init__.py - - ^packages/google-cloud-spanner/google/cloud/spanner_admin_database_v1/gapic_metadata.json - - ^packages/google-cloud-spanner/google/cloud/spanner_admin_database_v1/gapic_version.py - - ^packages/google-cloud-spanner/google/cloud/spanner_admin_database_v1/py.typed - - ^packages/google-cloud-spanner/google/cloud/spanner_admin_database_v1/services - - ^packages/google-cloud-spanner/google/cloud/spanner_admin_database_v1/types - - ^packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/__init__.py - - ^packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/gapic_metadata.json - - ^packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/gapic_version.py - - ^packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/py.typed - - ^packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/services - - ^packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/types - - ^packages/google-cloud-spanner/google/cloud/spanner_admin_database/__init__.py - - ^packages/google-cloud-spanner/google/cloud/spanner_admin_database/gapic_version.py - - ^packages/google-cloud-spanner/google/cloud/spanner_admin_database/py.typed - - ^packages/google-cloud-spanner/google/cloud/spanner_admin_instance/__init__.py - - ^packages/google-cloud-spanner/google/cloud/spanner_admin_instance/gapic_version.py - - ^packages/google-cloud-spanner/google/cloud/spanner_admin_instance/py.typed - - ^packages/google-cloud-spanner/google/cloud/spanner/__init__.py - - ^packages/google-cloud-spanner/google/cloud/spanner/gapic_version.py - - ^packages/google-cloud-spanner/google/cloud/spanner/py.typed - - ^packages/google-cloud-spanner/testing - - ^packages/google-cloud-spanner/tests/__init__.py - - ^packages/google-cloud-spanner/tests/unit/__init__.py - - ^packages/google-cloud-spanner/tests/unit/gapic/spanner_admin_database_v1 - - ^packages/google-cloud-spanner/tests/unit/gapic/spanner_admin_instance_v1 - - ^packages/google-cloud-spanner/tests/unit/gapic/spanner_v1 - - ^packages/google-cloud-spanner/tests/unit/gapic/__init__.py - - ^packages/google-cloud-spanner/samples/generated_samples - release_exclude_paths: - - packages/google-cloud-spanner/.repo-metadata.json - - packages/google-cloud-spanner/noxfile.py - - packages/google-cloud-spanner/tests/ - - packages/google-cloud-spanner/README.rst - - packages/google-cloud-spanner/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-speech - version: 2.40.0 - last_generated_commit: c662840a94dbdf708caa44893a2d49119cdd391c - apis: - - path: google/cloud/speech/v1 - service_config: speech_v1.yaml - - path: google/cloud/speech/v2 - service_config: speech_v2.yaml - - path: google/cloud/speech/v1p1beta1 - service_config: speech_v1p1beta1.yaml - source_roots: - - packages/google-cloud-speech - preserve_regex: - - packages/google-cloud-speech/CHANGELOG.md - - docs/CHANGELOG.md - - google/cloud/speech_v1/helpers.py - - tests/system - - tests/unit/test_helpers.py - remove_regex: - - packages/google-cloud-speech/ - release_exclude_paths: - - packages/google-cloud-speech/.repo-metadata.json - - packages/google-cloud-speech/noxfile.py - - packages/google-cloud-speech/tests/ - - packages/google-cloud-speech/README.rst - - packages/google-cloud-speech/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-storage - version: 3.12.0 - last_generated_commit: 2233f63baf69c2a481f30180045fcf036242781d - apis: - - path: google/storage/v2 - service_config: storage_v2.yaml - source_roots: - - packages/google-cloud-storage - preserve_regex: - - packages/google-cloud-storage/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - ^packages/google-cloud-storage/.coveragerc - - ^packages/google-cloud-storage/.flake8 - - ^packages/google-cloud-storage/.repo-metadata.json - - ^packages/google-cloud-storage/noxfile.py - - ^packages/google-cloud-storage/tests/ - - ^packages/google-cloud-storage/LICENSE - - ^packages/google-cloud-storage/MANIFEST.in - - ^packages/google-cloud-storage/README.rst - - ^packages/google-cloud-storage/mypy.ini - - ^packages/google-cloud-storage/noxfile.py - - ^packages/google-cloud-storage/setup.py - - ^packages/google-cloud-storage/google/cloud/_storage - - ^packages/google-cloud-storage/samples/generated_samples - - ^packages/google-cloud-storage/testing - - ^packages/google-cloud-storage/tests/__init__.py - - ^packages/google-cloud-storage/tests/unit/__init__.py - - ^packages/google-cloud-storage/tests/unit/gapic - - ^packages/google-cloud-storage/docs/conf.py - - ^packages/google-cloud-storage/docs/index.rst - - ^packages/google-cloud-storage/README.rst - - ^packages/google-cloud-storage/docs/ - - ^packages/google-cloud-storage/docs/_static - - ^packages/google-cloud-storage/docs/_templates - - ^packages/google-cloud-storage/docs/_storage - - ^packages/google-cloud-storage/docs/summary_overview.md - - ^packages/google-cloud-storage/docs/multiprocessing.rst - release_exclude_paths: - - packages/google-cloud-storage/.repo-metadata.json - - packages/google-cloud-storage/noxfile.py - - packages/google-cloud-storage/tests/ - - packages/google-cloud-storage/README.rst - - packages/google-cloud-storage/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-storage-control - version: 1.12.0 - last_generated_commit: 9eea40c74d97622bb0aa406dd313409a376cc73b - apis: - - path: google/storage/control/v2 - service_config: storage_v2.yaml - source_roots: - - packages/google-cloud-storage-control - preserve_regex: - - packages/google-cloud-storage-control/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-storage-control/ - release_exclude_paths: - - packages/google-cloud-storage-control/.repo-metadata.json - - packages/google-cloud-storage-control/noxfile.py - - packages/google-cloud-storage-control/tests/ - - packages/google-cloud-storage-control/README.rst - - packages/google-cloud-storage-control/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-storage-transfer - version: 1.21.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/storagetransfer/v1 - service_config: storagetransfer_v1.yaml - source_roots: - - packages/google-cloud-storage-transfer - preserve_regex: - - packages/google-cloud-storage-transfer/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-storage-transfer/ - release_exclude_paths: - - packages/google-cloud-storage-transfer/.repo-metadata.json - - packages/google-cloud-storage-transfer/noxfile.py - - packages/google-cloud-storage-transfer/tests/ - - packages/google-cloud-storage-transfer/README.rst - - packages/google-cloud-storage-transfer/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-storagebatchoperations - version: 0.8.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/storagebatchoperations/v1 - service_config: storagebatchoperations_v1.yaml - source_roots: - - packages/google-cloud-storagebatchoperations - preserve_regex: - - packages/google-cloud-storagebatchoperations/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-storagebatchoperations/ - release_exclude_paths: - - packages/google-cloud-storagebatchoperations/.repo-metadata.json - - packages/google-cloud-storagebatchoperations/noxfile.py - - packages/google-cloud-storagebatchoperations/tests/ - - packages/google-cloud-storagebatchoperations/README.rst - - packages/google-cloud-storagebatchoperations/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-storageinsights - version: 0.5.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/storageinsights/v1 - service_config: storageinsights_v1.yaml - source_roots: - - packages/google-cloud-storageinsights - preserve_regex: - - packages/google-cloud-storageinsights/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-storageinsights/ - release_exclude_paths: - - packages/google-cloud-storageinsights/.repo-metadata.json - - packages/google-cloud-storageinsights/noxfile.py - - packages/google-cloud-storageinsights/tests/ - - packages/google-cloud-storageinsights/README.rst - - packages/google-cloud-storageinsights/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-support - version: 0.5.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/support/v2beta - service_config: cloudsupport_v2beta.yaml - - path: google/cloud/support/v2 - service_config: cloudsupport_v2.yaml - source_roots: - - packages/google-cloud-support - preserve_regex: - - packages/google-cloud-support/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-support/ - release_exclude_paths: - - packages/google-cloud-support/.repo-metadata.json - - packages/google-cloud-support/noxfile.py - - packages/google-cloud-support/tests/ - - packages/google-cloud-support/README.rst - - packages/google-cloud-support/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-talent - version: 2.20.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/talent/v4beta1 - service_config: jobs_v4beta1.yaml - - path: google/cloud/talent/v4 - service_config: jobs_v4.yaml - source_roots: - - packages/google-cloud-talent - preserve_regex: - - packages/google-cloud-talent/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-talent/ - release_exclude_paths: - - packages/google-cloud-talent/.repo-metadata.json - - packages/google-cloud-talent/noxfile.py - - packages/google-cloud-talent/tests/ - - packages/google-cloud-talent/README.rst - - packages/google-cloud-talent/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-tasks - version: 2.22.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/tasks/v2beta2 - service_config: cloudtasks_v2beta2.yaml - - path: google/cloud/tasks/v2beta3 - service_config: cloudtasks_v2beta3.yaml - - path: google/cloud/tasks/v2 - service_config: cloudtasks_v2.yaml - source_roots: - - packages/google-cloud-tasks - preserve_regex: - - packages/google-cloud-tasks/CHANGELOG.md - - docs/CHANGELOG.md - - snippets/README.md - - tests/system - remove_regex: - - packages/google-cloud-tasks/ - release_exclude_paths: - - packages/google-cloud-tasks/.repo-metadata.json - - packages/google-cloud-tasks/noxfile.py - - packages/google-cloud-tasks/tests/ - - packages/google-cloud-tasks/README.rst - - packages/google-cloud-tasks/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-telcoautomation - version: 0.5.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/telcoautomation/v1 - service_config: telcoautomation_v1.yaml - - path: google/cloud/telcoautomation/v1alpha1 - service_config: telcoautomation_v1alpha1.yaml - source_roots: - - packages/google-cloud-telcoautomation - preserve_regex: - - packages/google-cloud-telcoautomation/CHANGELOG.md - - docs/CHANGELOG.md - - snippets/README.md - remove_regex: - - packages/google-cloud-telcoautomation/ - release_exclude_paths: - - packages/google-cloud-telcoautomation/.repo-metadata.json - - packages/google-cloud-telcoautomation/noxfile.py - - packages/google-cloud-telcoautomation/tests/ - - packages/google-cloud-telcoautomation/README.rst - - packages/google-cloud-telcoautomation/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-testutils - version: 1.9.0 - last_generated_commit: "" - apis: [] - source_roots: - - packages/google-cloud-testutils - preserve_regex: [] - remove_regex: [] - release_exclude_paths: - - packages/google-cloud-testutils/.repo-metadata.json - - packages/google-cloud-testutils/noxfile.py - - packages/google-cloud-testutils/tests/ - - packages/google-cloud-testutils/README.rst - - packages/google-cloud-testutils/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-texttospeech - version: 2.36.0 - last_generated_commit: 582172de2d9b6443e1fecf696167867c6d8a5fc4 - apis: - - path: google/cloud/texttospeech/v1 - service_config: texttospeech_v1.yaml - - path: google/cloud/texttospeech/v1beta1 - service_config: texttospeech_v1beta1.yaml - source_roots: - - packages/google-cloud-texttospeech - preserve_regex: - - packages/google-cloud-texttospeech/CHANGELOG.md - - docs/CHANGELOG.md - - tests/system - remove_regex: - - packages/google-cloud-texttospeech/ - release_exclude_paths: - - packages/google-cloud-texttospeech/.repo-metadata.json - - packages/google-cloud-texttospeech/noxfile.py - - packages/google-cloud-texttospeech/tests/ - - packages/google-cloud-texttospeech/README.rst - - packages/google-cloud-texttospeech/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-tpu - version: 1.26.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/tpu/v2alpha1 - service_config: tpu_v2alpha1.yaml - - path: google/cloud/tpu/v2 - service_config: tpu_v2.yaml - - path: google/cloud/tpu/v1 - service_config: tpu_v1.yaml - source_roots: - - packages/google-cloud-tpu - preserve_regex: - - packages/google-cloud-tpu/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-tpu/ - release_exclude_paths: - - packages/google-cloud-tpu/.repo-metadata.json - - packages/google-cloud-tpu/noxfile.py - - packages/google-cloud-tpu/tests/ - - packages/google-cloud-tpu/README.rst - - packages/google-cloud-tpu/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-trace - version: 1.19.0 - last_generated_commit: 59d5f2b46924714af627ac29ea6de78641a00835 - apis: - - path: google/devtools/cloudtrace/v2 - service_config: cloudtrace_v2.yaml - - path: google/devtools/cloudtrace/v1 - service_config: cloudtrace_v1.yaml - source_roots: - - packages/google-cloud-trace - preserve_regex: - - packages/google-cloud-trace/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-trace/ - release_exclude_paths: - - packages/google-cloud-trace/.repo-metadata.json - - packages/google-cloud-trace/noxfile.py - - packages/google-cloud-trace/tests/ - - packages/google-cloud-trace/README.rst - - packages/google-cloud-trace/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-translate - version: 3.26.0 - last_generated_commit: 2233f63baf69c2a481f30180045fcf036242781d - apis: - - path: google/cloud/translate/v3beta1 - service_config: translate_v3beta1.yaml - - path: google/cloud/translate/v3 - service_config: translate_v3.yaml - source_roots: - - packages/google-cloud-translate - preserve_regex: - - packages/google-cloud-translate/CHANGELOG.md - - docs/CHANGELOG.md - - docs/client.rst - - docs/v2.rst - - google/cloud/translate_v2 - - tests/system - - tests/unit/v2 - remove_regex: - - packages/google-cloud-translate/ - release_exclude_paths: - - packages/google-cloud-translate/.repo-metadata.json - - packages/google-cloud-translate/noxfile.py - - packages/google-cloud-translate/tests/ - - packages/google-cloud-translate/README.rst - - packages/google-cloud-translate/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-vectorsearch - version: 0.11.0 - last_generated_commit: 38ed7d6ba66a774924722146f054d12b4487a89f - apis: - - path: google/cloud/vectorsearch/v1beta - service_config: vectorsearch_v1beta.yaml - - path: google/cloud/vectorsearch/v1 - service_config: vectorsearch_v1.yaml - source_roots: - - packages/google-cloud-vectorsearch - preserve_regex: - - packages/google-cloud-vectorsearch/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-vectorsearch - release_exclude_paths: - - packages/google-cloud-vectorsearch/.repo-metadata.json - - packages/google-cloud-vectorsearch/noxfile.py - - packages/google-cloud-vectorsearch/tests/ - - packages/google-cloud-vectorsearch/README.rst - - packages/google-cloud-vectorsearch/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-video-live-stream - version: 1.16.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/video/livestream/v1 - service_config: livestream_v1.yaml - source_roots: - - packages/google-cloud-video-live-stream - preserve_regex: - - packages/google-cloud-video-live-stream/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-video-live-stream/ - release_exclude_paths: - - packages/google-cloud-video-live-stream/.repo-metadata.json - - packages/google-cloud-video-live-stream/noxfile.py - - packages/google-cloud-video-live-stream/tests/ - - packages/google-cloud-video-live-stream/README.rst - - packages/google-cloud-video-live-stream/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-video-stitcher - version: 0.11.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/video/stitcher/v1 - service_config: videostitcher_v1.yaml - source_roots: - - packages/google-cloud-video-stitcher - preserve_regex: - - packages/google-cloud-video-stitcher/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-video-stitcher/ - release_exclude_paths: - - packages/google-cloud-video-stitcher/.repo-metadata.json - - packages/google-cloud-video-stitcher/noxfile.py - - packages/google-cloud-video-stitcher/tests/ - - packages/google-cloud-video-stitcher/README.rst - - packages/google-cloud-video-stitcher/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-video-transcoder - version: 1.20.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/video/transcoder/v1 - service_config: transcoder_v1.yaml - source_roots: - - packages/google-cloud-video-transcoder - preserve_regex: - - packages/google-cloud-video-transcoder/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-video-transcoder/ - release_exclude_paths: - - packages/google-cloud-video-transcoder/.repo-metadata.json - - packages/google-cloud-video-transcoder/noxfile.py - - packages/google-cloud-video-transcoder/tests/ - - packages/google-cloud-video-transcoder/README.rst - - packages/google-cloud-video-transcoder/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-videointelligence - version: 2.19.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/videointelligence/v1p3beta1 - service_config: videointelligence_v1p3beta1.yaml - - path: google/cloud/videointelligence/v1 - service_config: videointelligence_v1.yaml - - path: google/cloud/videointelligence/v1p2beta1 - service_config: videointelligence_v1p2beta1.yaml - - path: google/cloud/videointelligence/v1p1beta1 - service_config: videointelligence_v1p1beta1.yaml - - path: google/cloud/videointelligence/v1beta2 - service_config: videointelligence_v1beta2.yaml - source_roots: - - packages/google-cloud-videointelligence - preserve_regex: - - packages/google-cloud-videointelligence/CHANGELOG.md - - docs/CHANGELOG.md - - tests/system - remove_regex: - - packages/google-cloud-videointelligence/ - release_exclude_paths: - - packages/google-cloud-videointelligence/.repo-metadata.json - - packages/google-cloud-videointelligence/noxfile.py - - packages/google-cloud-videointelligence/tests/ - - packages/google-cloud-videointelligence/README.rst - - packages/google-cloud-videointelligence/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-vision - version: 3.14.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/vision/v1p3beta1 - service_config: vision_v1p3beta1.yaml - - path: google/cloud/vision/v1 - service_config: vision_v1.yaml - - path: google/cloud/vision/v1p1beta1 - service_config: vision_v1p1beta1.yaml - - path: google/cloud/vision/v1p2beta1 - service_config: vision_v1p2beta1.yaml - - path: google/cloud/vision/v1p4beta1 - service_config: vision_v1p4beta1.yaml - source_roots: - - packages/google-cloud-vision - preserve_regex: - - packages/google-cloud-vision/CHANGELOG.md - - docs/CHANGELOG.md - - google/cloud/vision_helpers - - tests/system - - tests/unit/test_decorators.py - - tests/unit/test_helpers.py - remove_regex: - - packages/google-cloud-vision/ - release_exclude_paths: - - packages/google-cloud-vision/.repo-metadata.json - - packages/google-cloud-vision/noxfile.py - - packages/google-cloud-vision/tests/ - - packages/google-cloud-vision/README.rst - - packages/google-cloud-vision/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-visionai - version: 0.5.0 - last_generated_commit: 59d5f2b46924714af627ac29ea6de78641a00835 - apis: - - path: google/cloud/visionai/v1alpha1 - service_config: visionai_v1alpha1.yaml - - path: google/cloud/visionai/v1 - service_config: visionai_v1.yaml - source_roots: - - packages/google-cloud-visionai - preserve_regex: - - packages/google-cloud-visionai/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-visionai/ - release_exclude_paths: - - packages/google-cloud-visionai/.repo-metadata.json - - packages/google-cloud-visionai/noxfile.py - - packages/google-cloud-visionai/tests/ - - packages/google-cloud-visionai/README.rst - - packages/google-cloud-visionai/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-vm-migration - version: 1.16.0 - last_generated_commit: a17b84add8318f780fcc8a027815d5fee644b9f7 - apis: - - path: google/cloud/vmmigration/v1 - service_config: vmmigration_v1.yaml - source_roots: - - packages/google-cloud-vm-migration - preserve_regex: - - packages/google-cloud-vm-migration/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-vm-migration/ - release_exclude_paths: - - packages/google-cloud-vm-migration/.repo-metadata.json - - packages/google-cloud-vm-migration/noxfile.py - - packages/google-cloud-vm-migration/tests/ - - packages/google-cloud-vm-migration/README.rst - - packages/google-cloud-vm-migration/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-vmwareengine - version: 1.11.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/vmwareengine/v1 - service_config: vmwareengine_v1.yaml - source_roots: - - packages/google-cloud-vmwareengine - preserve_regex: - - packages/google-cloud-vmwareengine/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-vmwareengine/ - release_exclude_paths: - - packages/google-cloud-vmwareengine/.repo-metadata.json - - packages/google-cloud-vmwareengine/noxfile.py - - packages/google-cloud-vmwareengine/tests/ - - packages/google-cloud-vmwareengine/README.rst - - packages/google-cloud-vmwareengine/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-vpc-access - version: 1.16.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/vpcaccess/v1 - service_config: vpcaccess_v1.yaml - source_roots: - - packages/google-cloud-vpc-access - preserve_regex: - - packages/google-cloud-vpc-access/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-vpc-access/ - release_exclude_paths: - - packages/google-cloud-vpc-access/.repo-metadata.json - - packages/google-cloud-vpc-access/noxfile.py - - packages/google-cloud-vpc-access/tests/ - - packages/google-cloud-vpc-access/README.rst - - packages/google-cloud-vpc-access/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-webrisk - version: 1.21.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/webrisk/v1beta1 - service_config: webrisk_v1beta1.yaml - - path: google/cloud/webrisk/v1 - service_config: webrisk_v1.yaml - source_roots: - - packages/google-cloud-webrisk - preserve_regex: - - packages/google-cloud-webrisk/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-webrisk/ - release_exclude_paths: - - packages/google-cloud-webrisk/.repo-metadata.json - - packages/google-cloud-webrisk/noxfile.py - - packages/google-cloud-webrisk/tests/ - - packages/google-cloud-webrisk/README.rst - - packages/google-cloud-webrisk/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-websecurityscanner - version: 1.20.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/websecurityscanner/v1alpha - service_config: websecurityscanner_v1alpha.yaml - - path: google/cloud/websecurityscanner/v1beta - service_config: websecurityscanner_v1beta.yaml - - path: google/cloud/websecurityscanner/v1 - service_config: websecurityscanner_v1.yaml - source_roots: - - packages/google-cloud-websecurityscanner - preserve_regex: - - packages/google-cloud-websecurityscanner/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-websecurityscanner/ - release_exclude_paths: - - packages/google-cloud-websecurityscanner/.repo-metadata.json - - packages/google-cloud-websecurityscanner/noxfile.py - - packages/google-cloud-websecurityscanner/tests/ - - packages/google-cloud-websecurityscanner/README.rst - - packages/google-cloud-websecurityscanner/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-workflows - version: 1.22.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/workflows/executions/v1 - service_config: workflowexecutions_v1.yaml - - path: google/cloud/workflows/executions/v1beta - service_config: workflowexecutions_v1beta.yaml - - path: google/cloud/workflows/v1 - service_config: workflows_v1.yaml - - path: google/cloud/workflows/v1beta - service_config: workflows_v1beta.yaml - source_roots: - - packages/google-cloud-workflows - preserve_regex: - - packages/google-cloud-workflows/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-workflows/ - release_exclude_paths: - - packages/google-cloud-workflows/.repo-metadata.json - - packages/google-cloud-workflows/noxfile.py - - packages/google-cloud-workflows/tests/ - - packages/google-cloud-workflows/README.rst - - packages/google-cloud-workflows/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-workloadmanager - version: 0.2.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/cloud/workloadmanager/v1 - service_config: workloadmanager_v1.yaml - source_roots: - - packages/google-cloud-workloadmanager - preserve_regex: - - packages/google-cloud-workloadmanager/CHANGELOG.md - - docs/CHANGELOG.md - - samples/README.txt - - scripts/client-post-processing - - samples/snippets/README.rst - - tests/system - remove_regex: - - packages/google-cloud-workloadmanager - release_exclude_paths: - - packages/google-cloud-workloadmanager/.repo-metadata.json - - packages/google-cloud-workloadmanager/noxfile.py - - packages/google-cloud-workloadmanager/tests/ - - packages/google-cloud-workloadmanager/README.rst - - packages/google-cloud-workloadmanager/docs/ - tag_format: '{id}-v{version}' - - id: google-cloud-workstations - version: 0.8.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/cloud/workstations/v1beta - service_config: workstations_v1beta.yaml - - path: google/cloud/workstations/v1 - service_config: workstations_v1.yaml - source_roots: - - packages/google-cloud-workstations - preserve_regex: - - packages/google-cloud-workstations/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-cloud-workstations/ - release_exclude_paths: - - packages/google-cloud-workstations/.repo-metadata.json - - packages/google-cloud-workstations/noxfile.py - - packages/google-cloud-workstations/tests/ - - packages/google-cloud-workstations/README.rst - - packages/google-cloud-workstations/docs/ - tag_format: '{id}-v{version}' - - id: google-crc32c - version: 1.8.0 - last_generated_commit: "" - apis: [] - source_roots: - - packages/google-crc32c - preserve_regex: [] - remove_regex: [] - release_exclude_paths: - - packages/google-crc32c/.repo-metadata.json - - packages/google-crc32c/noxfile.py - - packages/google-crc32c/tests/ - - packages/google-crc32c/README.rst - - packages/google-crc32c/docs/ - tag_format: '{id}-v{version}' - - id: google-developer-knowledge - version: 0.1.0 - last_generated_commit: "" - apis: - - path: google/developers/knowledge/v1 - source_roots: - - packages/google-developer-knowledge - preserve_regex: [] - remove_regex: [] - release_exclude_paths: - - packages/google-developer-knowledge/.repo-metadata.json - - packages/google-developer-knowledge/noxfile.py - - packages/google-developer-knowledge/tests/ - - packages/google-developer-knowledge/README.rst - - packages/google-developer-knowledge/docs/ - tag_format: '{id}-v{version}' - - id: google-devicesandservices-health - version: 0.1.0 - last_generated_commit: "" - apis: - - path: google/devicesandservices/health/v4 - source_roots: - - packages/google-devicesandservices-health - preserve_regex: [] - remove_regex: [] - release_exclude_paths: - - packages/google-devicesandservices-health/.repo-metadata.json - - packages/google-devicesandservices-health/noxfile.py - - packages/google-devicesandservices-health/tests/ - - packages/google-devicesandservices-health/README.rst - - packages/google-devicesandservices-health/docs/ - tag_format: '{id}-v{version}' - - id: google-geo-type - version: 0.7.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/geo/type - service_config: type_geo.yaml - source_roots: - - packages/google-geo-type - preserve_regex: - - packages/google-geo-type/CHANGELOG.md - - docs/CHANGELOG.md - - tests/unit/gapic/type/test_type.py - remove_regex: - - packages/google-geo-type - release_exclude_paths: - - packages/google-geo-type/.repo-metadata.json - - packages/google-geo-type/noxfile.py - - packages/google-geo-type/tests/ - - packages/google-geo-type/README.rst - - packages/google-geo-type/docs/ - tag_format: '{id}-v{version}' - - id: google-maps-addressvalidation - version: 0.7.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/maps/addressvalidation/v1 - service_config: addressvalidation_v1.yaml - source_roots: - - packages/google-maps-addressvalidation - preserve_regex: - - packages/google-maps-addressvalidation/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-maps-addressvalidation - release_exclude_paths: - - packages/google-maps-addressvalidation/.repo-metadata.json - - packages/google-maps-addressvalidation/noxfile.py - - packages/google-maps-addressvalidation/tests/ - - packages/google-maps-addressvalidation/README.rst - - packages/google-maps-addressvalidation/docs/ - tag_format: '{id}-v{version}' - - id: google-maps-areainsights - version: 0.5.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/maps/areainsights/v1 - service_config: areainsights_v1.yaml - source_roots: - - packages/google-maps-areainsights - preserve_regex: - - packages/google-maps-areainsights/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-maps-areainsights - release_exclude_paths: - - packages/google-maps-areainsights/.repo-metadata.json - - packages/google-maps-areainsights/noxfile.py - - packages/google-maps-areainsights/tests/ - - packages/google-maps-areainsights/README.rst - - packages/google-maps-areainsights/docs/ - tag_format: '{id}-v{version}' - - id: google-maps-fleetengine - version: 0.6.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/maps/fleetengine/v1 - service_config: fleetengine_v1.yaml - source_roots: - - packages/google-maps-fleetengine - preserve_regex: - - packages/google-maps-fleetengine/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-maps-fleetengine - release_exclude_paths: - - packages/google-maps-fleetengine/.repo-metadata.json - - packages/google-maps-fleetengine/noxfile.py - - packages/google-maps-fleetengine/tests/ - - packages/google-maps-fleetengine/README.rst - - packages/google-maps-fleetengine/docs/ - tag_format: '{id}-v{version}' - - id: google-maps-fleetengine-delivery - version: 0.6.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/maps/fleetengine/delivery/v1 - service_config: fleetengine_v1.yaml - source_roots: - - packages/google-maps-fleetengine-delivery - preserve_regex: - - packages/google-maps-fleetengine-delivery/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-maps-fleetengine-delivery - release_exclude_paths: - - packages/google-maps-fleetengine-delivery/.repo-metadata.json - - packages/google-maps-fleetengine-delivery/noxfile.py - - packages/google-maps-fleetengine-delivery/tests/ - - packages/google-maps-fleetengine-delivery/README.rst - - packages/google-maps-fleetengine-delivery/docs/ - tag_format: '{id}-v{version}' - - id: google-maps-geocode - version: 0.3.0 - last_generated_commit: 582172de2d9b6443e1fecf696167867c6d8a5fc4 - apis: - - path: google/maps/geocode/v4 - service_config: geocoding_backend_v4.yaml - source_roots: - - packages/google-maps-geocode - preserve_regex: - - packages/google-maps-geocode/CHANGELOG.md - - docs/CHANGELOG.md - - samples/README.txt - - scripts/client-post-processing - - samples/snippets/README.rst - - tests/system - remove_regex: - - packages/google-maps-geocode - release_exclude_paths: - - packages/google-maps-geocode/.repo-metadata.json - - packages/google-maps-geocode/noxfile.py - - packages/google-maps-geocode/tests/ - - packages/google-maps-geocode/README.rst - - packages/google-maps-geocode/docs/ - tag_format: '{id}-v{version}' - - id: google-maps-mapmanagement - version: 0.1.0 - last_generated_commit: "" - apis: - - path: google/maps/mapmanagement/v2beta - source_roots: - - packages/google-maps-mapmanagement - preserve_regex: [] - remove_regex: [] - release_exclude_paths: - - packages/google-maps-mapmanagement/.repo-metadata.json - - packages/google-maps-mapmanagement/noxfile.py - - packages/google-maps-mapmanagement/tests/ - - packages/google-maps-mapmanagement/README.rst - - packages/google-maps-mapmanagement/docs/ - tag_format: '{id}-v{version}' - - id: google-maps-mapsplatformdatasets - version: 0.8.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/maps/mapsplatformdatasets/v1 - service_config: mapsplatformdatasets_v1.yaml - source_roots: - - packages/google-maps-mapsplatformdatasets - preserve_regex: - - packages/google-maps-mapsplatformdatasets/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-maps-mapsplatformdatasets - release_exclude_paths: - - packages/google-maps-mapsplatformdatasets/.repo-metadata.json - - packages/google-maps-mapsplatformdatasets/noxfile.py - - packages/google-maps-mapsplatformdatasets/tests/ - - packages/google-maps-mapsplatformdatasets/README.rst - - packages/google-maps-mapsplatformdatasets/docs/ - tag_format: '{id}-v{version}' - - id: google-maps-navconnect - version: 0.2.0 - last_generated_commit: dfcbe6807e8c0bb8d5abb2b5e875a2a03af8d874 - apis: - - path: google/maps/navconnect/v1 - service_config: navigationconnect_v1.yaml - source_roots: - - packages/google-maps-navconnect - preserve_regex: - - packages/google-maps-navconnect/CHANGELOG.md - - docs/CHANGELOG.md - - samples/README.txt - - scripts/client-post-processing - - samples/snippets/README.rst - - tests/system - remove_regex: - - packages/google-maps-navconnect - release_exclude_paths: - - packages/google-maps-navconnect/.repo-metadata.json - - packages/google-maps-navconnect/noxfile.py - - packages/google-maps-navconnect/tests/ - - packages/google-maps-navconnect/README.rst - - packages/google-maps-navconnect/docs/ - tag_format: '{id}-v{version}' - - id: google-maps-places - version: 0.9.0 - last_generated_commit: 59d5f2b46924714af627ac29ea6de78641a00835 - apis: - - path: google/maps/places/v1 - service_config: places_v1.yaml - source_roots: - - packages/google-maps-places - preserve_regex: - - packages/google-maps-places/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-maps-places - release_exclude_paths: - - packages/google-maps-places/.repo-metadata.json - - packages/google-maps-places/noxfile.py - - packages/google-maps-places/tests/ - - packages/google-maps-places/README.rst - - packages/google-maps-places/docs/ - tag_format: '{id}-v{version}' - - id: google-maps-routeoptimization - version: 0.5.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/maps/routeoptimization/v1 - service_config: routeoptimization_v1.yaml - source_roots: - - packages/google-maps-routeoptimization - preserve_regex: - - packages/google-maps-routeoptimization/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-maps-routeoptimization - release_exclude_paths: - - packages/google-maps-routeoptimization/.repo-metadata.json - - packages/google-maps-routeoptimization/noxfile.py - - packages/google-maps-routeoptimization/tests/ - - packages/google-maps-routeoptimization/README.rst - - packages/google-maps-routeoptimization/docs/ - tag_format: '{id}-v{version}' - - id: google-maps-routing - version: 0.11.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/maps/routing/v2 - service_config: routes_v2.yaml - source_roots: - - packages/google-maps-routing - preserve_regex: - - packages/google-maps-routing/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-maps-routing - release_exclude_paths: - - packages/google-maps-routing/.repo-metadata.json - - packages/google-maps-routing/noxfile.py - - packages/google-maps-routing/tests/ - - packages/google-maps-routing/README.rst - - packages/google-maps-routing/docs/ - tag_format: '{id}-v{version}' - - id: google-maps-solar - version: 0.6.0 - last_generated_commit: 9eea40c74d97622bb0aa406dd313409a376cc73b - apis: - - path: google/maps/solar/v1 - service_config: solar_v1.yaml - source_roots: - - packages/google-maps-solar - preserve_regex: - - packages/google-maps-solar/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-maps-solar - release_exclude_paths: - - packages/google-maps-solar/.repo-metadata.json - - packages/google-maps-solar/noxfile.py - - packages/google-maps-solar/tests/ - - packages/google-maps-solar/README.rst - - packages/google-maps-solar/docs/ - tag_format: '{id}-v{version}' - - id: google-resumable-media - version: 2.10.0 - last_generated_commit: "" - apis: [] - source_roots: - - packages/google-resumable-media - preserve_regex: [] - remove_regex: [] - release_exclude_paths: - - packages/google-resumable-media/.repo-metadata.json - - packages/google-resumable-media/noxfile.py - - packages/google-resumable-media/tests/ - - packages/google-resumable-media/README.rst - - packages/google-resumable-media/docs/ - tag_format: '{id}-v{version}' - - id: google-shopping-css - version: 0.6.0 - last_generated_commit: ebfdba37e54d9cd3e78380d226c2c4ab5a5f7fd4 - apis: - - path: google/shopping/css/v1 - service_config: css_v1.yaml - source_roots: - - packages/google-shopping-css - preserve_regex: - - packages/google-shopping-css/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-shopping-css/ - release_exclude_paths: - - packages/google-shopping-css/.repo-metadata.json - - packages/google-shopping-css/noxfile.py - - packages/google-shopping-css/tests/ - - packages/google-shopping-css/README.rst - - packages/google-shopping-css/docs/ - tag_format: '{id}-v{version}' - - id: google-shopping-merchant-accounts - version: 1.6.0 - last_generated_commit: ffe6fc5c48419866f525b463f20400d65c0e6312 - apis: - - path: google/shopping/merchant/accounts/v1 - service_config: merchantapi_v1.yaml - - path: google/shopping/merchant/accounts/v1beta - service_config: merchantapi_v1beta.yaml - source_roots: - - packages/google-shopping-merchant-accounts - preserve_regex: - - packages/google-shopping-merchant-accounts/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-shopping-merchant-accounts/ - release_exclude_paths: - - packages/google-shopping-merchant-accounts/.repo-metadata.json - - packages/google-shopping-merchant-accounts/noxfile.py - - packages/google-shopping-merchant-accounts/tests/ - - packages/google-shopping-merchant-accounts/README.rst - - packages/google-shopping-merchant-accounts/docs/ - tag_format: '{id}-v{version}' - - id: google-shopping-merchant-conversions - version: 1.4.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/shopping/merchant/conversions/v1 - service_config: merchantapi_v1.yaml - - path: google/shopping/merchant/conversions/v1beta - service_config: merchantapi_v1beta.yaml - source_roots: - - packages/google-shopping-merchant-conversions - preserve_regex: - - packages/google-shopping-merchant-conversions/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-shopping-merchant-conversions/ - release_exclude_paths: - - packages/google-shopping-merchant-conversions/.repo-metadata.json - - packages/google-shopping-merchant-conversions/noxfile.py - - packages/google-shopping-merchant-conversions/tests/ - - packages/google-shopping-merchant-conversions/README.rst - - packages/google-shopping-merchant-conversions/docs/ - tag_format: '{id}-v{version}' - - id: google-shopping-merchant-datasources - version: 1.5.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/shopping/merchant/datasources/v1 - service_config: merchantapi_v1.yaml - - path: google/shopping/merchant/datasources/v1beta - service_config: merchantapi_v1beta.yaml - source_roots: - - packages/google-shopping-merchant-datasources - preserve_regex: - - packages/google-shopping-merchant-datasources/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-shopping-merchant-datasources/ - release_exclude_paths: - - packages/google-shopping-merchant-datasources/.repo-metadata.json - - packages/google-shopping-merchant-datasources/noxfile.py - - packages/google-shopping-merchant-datasources/tests/ - - packages/google-shopping-merchant-datasources/README.rst - - packages/google-shopping-merchant-datasources/docs/ - tag_format: '{id}-v{version}' - - id: google-shopping-merchant-inventories - version: 1.5.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/shopping/merchant/inventories/v1beta - service_config: merchantapi_v1beta.yaml - - path: google/shopping/merchant/inventories/v1 - service_config: merchantapi_v1.yaml - source_roots: - - packages/google-shopping-merchant-inventories - preserve_regex: - - packages/google-shopping-merchant-inventories/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-shopping-merchant-inventories/ - release_exclude_paths: - - packages/google-shopping-merchant-inventories/.repo-metadata.json - - packages/google-shopping-merchant-inventories/noxfile.py - - packages/google-shopping-merchant-inventories/tests/ - - packages/google-shopping-merchant-inventories/README.rst - - packages/google-shopping-merchant-inventories/docs/ - tag_format: '{id}-v{version}' - - id: google-shopping-merchant-issueresolution - version: 1.4.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/shopping/merchant/issueresolution/v1 - service_config: merchantapi_v1.yaml - - path: google/shopping/merchant/issueresolution/v1beta - service_config: merchantapi_v1beta.yaml - source_roots: - - packages/google-shopping-merchant-issueresolution - preserve_regex: - - packages/google-shopping-merchant-issueresolution/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-shopping-merchant-issueresolution/ - release_exclude_paths: - - packages/google-shopping-merchant-issueresolution/.repo-metadata.json - - packages/google-shopping-merchant-issueresolution/noxfile.py - - packages/google-shopping-merchant-issueresolution/tests/ - - packages/google-shopping-merchant-issueresolution/README.rst - - packages/google-shopping-merchant-issueresolution/docs/ - tag_format: '{id}-v{version}' - - id: google-shopping-merchant-lfp - version: 1.4.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/shopping/merchant/lfp/v1beta - service_config: merchantapi_v1beta.yaml - - path: google/shopping/merchant/lfp/v1 - service_config: merchantapi_v1.yaml - source_roots: - - packages/google-shopping-merchant-lfp - preserve_regex: - - packages/google-shopping-merchant-lfp/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-shopping-merchant-lfp/ - release_exclude_paths: - - packages/google-shopping-merchant-lfp/.repo-metadata.json - - packages/google-shopping-merchant-lfp/noxfile.py - - packages/google-shopping-merchant-lfp/tests/ - - packages/google-shopping-merchant-lfp/README.rst - - packages/google-shopping-merchant-lfp/docs/ - tag_format: '{id}-v{version}' - - id: google-shopping-merchant-notifications - version: 1.4.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/shopping/merchant/notifications/v1 - service_config: merchantapi_v1.yaml - - path: google/shopping/merchant/notifications/v1beta - service_config: merchantapi_v1beta.yaml - source_roots: - - packages/google-shopping-merchant-notifications - preserve_regex: - - packages/google-shopping-merchant-notifications/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-shopping-merchant-notifications/ - release_exclude_paths: - - packages/google-shopping-merchant-notifications/.repo-metadata.json - - packages/google-shopping-merchant-notifications/noxfile.py - - packages/google-shopping-merchant-notifications/tests/ - - packages/google-shopping-merchant-notifications/README.rst - - packages/google-shopping-merchant-notifications/docs/ - tag_format: '{id}-v{version}' - - id: google-shopping-merchant-ordertracking - version: 1.4.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/shopping/merchant/ordertracking/v1 - service_config: merchantapi_v1.yaml - - path: google/shopping/merchant/ordertracking/v1beta - service_config: merchantapi_v1beta.yaml - source_roots: - - packages/google-shopping-merchant-ordertracking - preserve_regex: - - packages/google-shopping-merchant-ordertracking/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-shopping-merchant-ordertracking/ - release_exclude_paths: - - packages/google-shopping-merchant-ordertracking/.repo-metadata.json - - packages/google-shopping-merchant-ordertracking/noxfile.py - - packages/google-shopping-merchant-ordertracking/tests/ - - packages/google-shopping-merchant-ordertracking/README.rst - - packages/google-shopping-merchant-ordertracking/docs/ - tag_format: '{id}-v{version}' - - id: google-shopping-merchant-products - version: 1.7.0 - last_generated_commit: ebfdba37e54d9cd3e78380d226c2c4ab5a5f7fd4 - apis: - - path: google/shopping/merchant/products/v1 - service_config: merchantapi_v1.yaml - - path: google/shopping/merchant/products/v1beta - service_config: merchantapi_v1beta.yaml - source_roots: - - packages/google-shopping-merchant-products - preserve_regex: - - packages/google-shopping-merchant-products/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-shopping-merchant-products/ - release_exclude_paths: - - packages/google-shopping-merchant-products/.repo-metadata.json - - packages/google-shopping-merchant-products/noxfile.py - - packages/google-shopping-merchant-products/tests/ - - packages/google-shopping-merchant-products/README.rst - - packages/google-shopping-merchant-products/docs/ - tag_format: '{id}-v{version}' - - id: google-shopping-merchant-productstudio - version: 0.5.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd - apis: - - path: google/shopping/merchant/productstudio/v1alpha - service_config: merchantapi_v1alpha.yaml - source_roots: - - packages/google-shopping-merchant-productstudio - preserve_regex: - - packages/google-shopping-merchant-productstudio/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-shopping-merchant-productstudio/ - release_exclude_paths: - - packages/google-shopping-merchant-productstudio/.repo-metadata.json - - packages/google-shopping-merchant-productstudio/noxfile.py - - packages/google-shopping-merchant-productstudio/tests/ - - packages/google-shopping-merchant-productstudio/README.rst - - packages/google-shopping-merchant-productstudio/docs/ - tag_format: '{id}-v{version}' - - id: google-shopping-merchant-promotions - version: 1.4.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/shopping/merchant/promotions/v1 - service_config: merchantapi_v1.yaml - - path: google/shopping/merchant/promotions/v1beta - service_config: merchantapi_v1beta.yaml - source_roots: - - packages/google-shopping-merchant-promotions - preserve_regex: - - packages/google-shopping-merchant-promotions/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-shopping-merchant-promotions/ - release_exclude_paths: - - packages/google-shopping-merchant-promotions/.repo-metadata.json - - packages/google-shopping-merchant-promotions/noxfile.py - - packages/google-shopping-merchant-promotions/tests/ - - packages/google-shopping-merchant-promotions/README.rst - - packages/google-shopping-merchant-promotions/docs/ - tag_format: '{id}-v{version}' - - id: google-shopping-merchant-quota - version: 1.5.0 - last_generated_commit: c2db528a3e4d12b95666c719ee0db30a3d4c78ad - apis: - - path: google/shopping/merchant/quota/v1beta - service_config: merchantapi_v1beta.yaml - - path: google/shopping/merchant/quota/v1 - service_config: merchantapi_v1.yaml - source_roots: - - packages/google-shopping-merchant-quota - preserve_regex: - - packages/google-shopping-merchant-quota/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-shopping-merchant-quota/ - release_exclude_paths: - - packages/google-shopping-merchant-quota/.repo-metadata.json - - packages/google-shopping-merchant-quota/noxfile.py - - packages/google-shopping-merchant-quota/tests/ - - packages/google-shopping-merchant-quota/README.rst - - packages/google-shopping-merchant-quota/docs/ - tag_format: '{id}-v{version}' - - id: google-shopping-merchant-reports - version: 1.5.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/shopping/merchant/reports/v1beta - service_config: merchantapi_v1beta.yaml - - path: google/shopping/merchant/reports/v1 - service_config: merchantapi_v1.yaml - - path: google/shopping/merchant/reports/v1alpha - service_config: merchantapi_v1alpha.yaml - source_roots: - - packages/google-shopping-merchant-reports - preserve_regex: - - packages/google-shopping-merchant-reports/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-shopping-merchant-reports/ - release_exclude_paths: - - packages/google-shopping-merchant-reports/.repo-metadata.json - - packages/google-shopping-merchant-reports/noxfile.py - - packages/google-shopping-merchant-reports/tests/ - - packages/google-shopping-merchant-reports/README.rst - - packages/google-shopping-merchant-reports/docs/ - tag_format: '{id}-v{version}' - - id: google-shopping-merchant-reviews - version: 0.6.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/shopping/merchant/reviews/v1beta - service_config: merchantapi_v1beta.yaml - source_roots: - - packages/google-shopping-merchant-reviews - preserve_regex: - - packages/google-shopping-merchant-reviews/CHANGELOG.md - - docs/CHANGELOG.md - remove_regex: - - packages/google-shopping-merchant-reviews/ - release_exclude_paths: - - packages/google-shopping-merchant-reviews/.repo-metadata.json - - packages/google-shopping-merchant-reviews/noxfile.py - - packages/google-shopping-merchant-reviews/tests/ - - packages/google-shopping-merchant-reviews/README.rst - - packages/google-shopping-merchant-reviews/docs/ - tag_format: '{id}-v{version}' - - id: google-shopping-type - version: 1.5.0 - last_generated_commit: 6df3ecf4fd43b64826de6a477d1a535ec18b0d7c - apis: - - path: google/shopping/type - source_roots: - - packages/google-shopping-type - preserve_regex: - - packages/google-shopping-type/CHANGELOG.md - - docs/CHANGELOG.md - - tests/unit/gapic/type/test_type.py - remove_regex: - - packages/google-shopping-type/ - release_exclude_paths: - - packages/google-shopping-type/.repo-metadata.json - - packages/google-shopping-type/noxfile.py - - packages/google-shopping-type/tests/ - - packages/google-shopping-type/README.rst - - packages/google-shopping-type/docs/ - tag_format: '{id}-v{version}' - - id: googleapis-common-protos - version: 1.75.0 - last_generated_commit: 2233f63baf69c2a481f30180045fcf036242781d - apis: - - path: google/api - service_config: serviceconfig.yaml - - path: google/cloud - - path: google/cloud/location - service_config: cloud.yaml - - path: google/logging/type - - path: google/rpc - service_config: rpc_publish.yaml - - path: google/rpc/context - - path: google/type - service_config: type.yaml - source_roots: - - packages/googleapis-common-protos - preserve_regex: [] - remove_regex: - - ^packages/googleapis-common-protos/google/(?:api|cloud|logging|rpc|type)/.*(?:\.proto|_pb2\.(?:py|pyi))$ - - .repo-metadata.json - - noxfile.py - - tests/ - - README.rst - - docs/summary_overview.md - release_exclude_paths: - - packages/googleapis-common-protos/.repo-metadata.json - - packages/googleapis-common-protos/noxfile.py - - packages/googleapis-common-protos/tests/ - - packages/googleapis-common-protos/README.rst - - packages/googleapis-common-protos/docs/ - tag_format: '{id}-v{version}' - - id: grafeas - version: 1.23.0 - last_generated_commit: ebfdba37e54d9cd3e78380d226c2c4ab5a5f7fd4 - apis: - - path: grafeas/v1 - service_config: grafeas_v1.yaml - source_roots: - - packages/grafeas - preserve_regex: - - packages/grafeas/CHANGELOG.md - - docs/CHANGELOG.md - - grafeas/grafeas\.py - - ^packages/grafeas/grafeas/__init__.py - - grafeas/grafeas/grafeas_v1/types.py - remove_regex: - - packages/grafeas - release_exclude_paths: - - packages/grafeas/.repo-metadata.json - - packages/grafeas/noxfile.py - - packages/grafeas/tests/ - - packages/grafeas/README.rst - - packages/grafeas/docs/ - tag_format: '{id}-v{version}' - - id: grpc-google-iam-v1 - version: 0.14.4 - last_generated_commit: e8365a7f88fabe8717cb8322b8ce784b03b6daea - apis: - - path: google/iam/v1 - service_config: iam_meta_api.yaml - source_roots: - - packages/grpc-google-iam-v1/ - preserve_regex: [] - remove_regex: - - ^packages/grpc-google-iam-v1/google/iam/v1/[^/]*(?:\.proto|_pb2\.(?:py|pyi))$ - - .repo-metadata.json - - noxfile.py - - tests/ - - README.rst - - docs/summary_overview.md - release_exclude_paths: - - packages/grpc-google-iam-v1/.repo-metadata.json - - packages/grpc-google-iam-v1/noxfile.py - - packages/grpc-google-iam-v1/tests/ - - packages/grpc-google-iam-v1/README.rst - - packages/grpc-google-iam-v1/docs/ - tag_format: '{id}-v{version}' - - id: pandas-gbq - version: 0.35.0 - last_generated_commit: "" - apis: [] - source_roots: - - packages/pandas-gbq - preserve_regex: [] - remove_regex: [] - release_exclude_paths: - - packages/pandas-gbq/.repo-metadata.json - - packages/pandas-gbq/noxfile.py - - packages/pandas-gbq/tests/ - - packages/pandas-gbq/README.rst - - packages/pandas-gbq/docs/ - tag_format: '{id}-v{version}' - - id: proto-plus - version: 1.28.0 - last_generated_commit: "" - apis: [] - source_roots: - - packages/proto-plus - preserve_regex: [] - remove_regex: [] - release_exclude_paths: - - packages/proto-plus/.repo-metadata.json - - packages/proto-plus/noxfile.py - - packages/proto-plus/tests/ - - packages/proto-plus/README.rst - - packages/proto-plus/docs/ - tag_format: '{id}-v{version}' - - id: sqlalchemy-bigquery - version: 1.17.0 - last_generated_commit: "" - apis: [] - source_roots: - - packages/sqlalchemy-bigquery - preserve_regex: [] - remove_regex: [] - release_exclude_paths: - - packages/sqlalchemy-bigquery/.repo-metadata.json - - packages/sqlalchemy-bigquery/noxfile.py - - packages/sqlalchemy-bigquery/tests/ - - packages/sqlalchemy-bigquery/README.rst - - packages/sqlalchemy-bigquery/docs/ - tag_format: '{id}-v{version}' - - id: sqlalchemy-spanner - version: 1.19.0 - last_generated_commit: "" - apis: [] - source_roots: - - packages/sqlalchemy-spanner - preserve_regex: [] - remove_regex: [] - release_exclude_paths: - - packages/sqlalchemy-spanner/.repo-metadata.json - - packages/sqlalchemy-spanner/noxfile.py - - packages/sqlalchemy-spanner/tests/ - - packages/sqlalchemy-spanner/README.rst - - packages/sqlalchemy-spanner/docs/ - tag_format: '{id}-v{version}' diff --git a/.release-please-bulk-manifest.json b/.release-please-bulk-manifest.json new file mode 100644 index 000000000000..3612728ebad7 --- /dev/null +++ b/.release-please-bulk-manifest.json @@ -0,0 +1,276 @@ +{ + "packages/bigquery-magics": "0.15.0", + "packages/db-dtypes": "1.7.0", + "packages/django-google-spanner": "5.0.0", + "packages/gapic-generator": "1.35.0", + "packages/gcp-sphinx-docfx-yaml": "3.3.0", + "packages/google-ads-admanager": "0.10.0", + "packages/google-ads-datamanager": "0.9.0", + "packages/google-ads-marketingplatform-admin": "0.6.0", + "packages/google-ai-generativelanguage": "0.12.0", + "packages/google-analytics-admin": "0.30.0", + "packages/google-analytics-data": "0.23.0", + "packages/google-api-core": "2.31.0", + "packages/google-apps-card": "0.7.0", + "packages/google-apps-chat": "0.10.0", + "packages/google-apps-events-subscriptions": "0.6.0", + "packages/google-apps-meet": "0.5.0", + "packages/google-apps-script-type": "0.8.0", + "packages/google-area120-tables": "0.15.0", + "packages/google-auth": "2.55.0", + "packages/google-auth-httplib2": "0.4.0", + "packages/google-auth-oauthlib": "1.4.0", + "packages/google-backstory": "0.1.0", + "packages/google-cloud-access-approval": "1.20.0", + "packages/google-cloud-access-context-manager": "0.6.0", + "packages/google-cloud-advisorynotifications": "0.7.0", + "packages/google-cloud-agentidentitycredentials": "0.1.0", + "packages/google-cloud-alloydb": "0.11.0", + "packages/google-cloud-alloydb-connectors": "0.5.0", + "packages/google-cloud-api-gateway": "1.16.0", + "packages/google-cloud-api-keys": "0.9.0", + "packages/google-cloud-apigee-connect": "1.16.0", + "packages/google-cloud-apigee-registry": "0.10.0", + "packages/google-cloud-apihub": "0.7.0", + "packages/google-cloud-apiregistry": "0.3.0", + "packages/google-cloud-appengine-admin": "1.18.0", + "packages/google-cloud-appengine-logging": "1.10.0", + "packages/google-cloud-apphub": "0.5.0", + "packages/google-cloud-appoptimize": "0.2.0", + "packages/google-cloud-artifact-registry": "1.22.0", + "packages/google-cloud-asset": "4.4.0", + "packages/google-cloud-assured-workloads": "2.4.0", + "packages/google-cloud-audit-log": "0.6.0", + "packages/google-cloud-auditmanager": "0.3.0", + "packages/google-cloud-automl": "2.20.0", + "packages/google-cloud-backupdr": "0.10.0", + "packages/google-cloud-bare-metal-solution": "1.14.0", + "packages/google-cloud-batch": "0.22.0", + "packages/google-cloud-beyondcorp-appconnections": "0.8.0", + "packages/google-cloud-beyondcorp-appconnectors": "0.8.0", + "packages/google-cloud-beyondcorp-appgateways": "0.8.0", + "packages/google-cloud-beyondcorp-clientconnectorservices": "0.8.0", + "packages/google-cloud-beyondcorp-clientgateways": "0.8.0", + "packages/google-cloud-biglake": "0.5.0", + "packages/google-cloud-biglake-hive": "0.3.0", + "packages/google-cloud-bigquery": "3.42.0", + "packages/google-cloud-bigquery-analyticshub": "0.9.0", + "packages/google-cloud-bigquery-biglake": "0.8.0", + "packages/google-cloud-bigquery-connection": "1.22.0", + "packages/google-cloud-bigquery-data-exchange": "0.9.0", + "packages/google-cloud-bigquery-datapolicies": "0.10.0", + "packages/google-cloud-bigquery-datatransfer": "3.23.0", + "packages/google-cloud-bigquery-logging": "1.10.0", + "packages/google-cloud-bigquery-migration": "0.15.0", + "packages/google-cloud-bigquery-reservation": "1.25.0", + "packages/google-cloud-bigquery-storage": "2.39.0", + "packages/google-cloud-billing": "1.20.0", + "packages/google-cloud-billing-budgets": "1.21.0", + "packages/google-cloud-binary-authorization": "1.17.0", + "packages/google-cloud-build": "3.37.0", + "packages/google-cloud-capacityplanner": "0.5.0", + "packages/google-cloud-certificate-manager": "1.14.0", + "packages/google-cloud-ces": "0.7.0", + "packages/google-cloud-channel": "1.28.0", + "packages/google-cloud-chronicle": "0.6.0", + "packages/google-cloud-cloudcontrolspartner": "0.6.0", + "packages/google-cloud-cloudsecuritycompliance": "0.8.0", + "packages/google-cloud-commerce-consumer-procurement": "0.6.0", + "packages/google-cloud-common": "1.10.0", + "packages/google-cloud-compute": "1.48.0", + "packages/google-cloud-compute-v1beta": "0.12.0", + "packages/google-cloud-confidentialcomputing": "0.11.0", + "packages/google-cloud-config": "0.7.0", + "packages/google-cloud-configdelivery": "0.5.0", + "packages/google-cloud-contact-center-insights": "1.27.0", + "packages/google-cloud-container": "2.65.0", + "packages/google-cloud-containeranalysis": "2.22.0", + "packages/google-cloud-contentwarehouse": "0.11.0", + "packages/google-cloud-core": "2.6.0", + "packages/google-cloud-data-fusion": "1.17.0", + "packages/google-cloud-data-qna": "0.14.0", + "packages/google-cloud-databasecenter": "0.9.0", + "packages/google-cloud-datacatalog": "3.31.0", + "packages/google-cloud-datacatalog-lineage": "0.7.0", + "packages/google-cloud-datacatalog-lineage-configmanagement": "0.3.0", + "packages/google-cloud-dataflow-client": "0.14.0", + "packages/google-cloud-dataform": "0.11.0", + "packages/google-cloud-datalabeling": "1.17.0", + "packages/google-cloud-dataplex": "2.20.0", + "packages/google-cloud-dataproc": "5.28.0", + "packages/google-cloud-dataproc-metastore": "1.23.0", + "packages/google-cloud-datastore": "2.25.0", + "packages/google-cloud-datastream": "1.19.0", + "packages/google-cloud-deploy": "2.11.0", + "packages/google-cloud-developerconnect": "0.6.0", + "packages/google-cloud-devicestreaming": "0.5.0", + "packages/google-cloud-dialogflow": "2.48.0", + "packages/google-cloud-dialogflow-cx": "2.6.0", + "packages/google-cloud-discoveryengine": "0.20.0", + "packages/google-cloud-dlp": "3.37.0", + "packages/google-cloud-dms": "1.16.0", + "packages/google-cloud-dns": "0.37.0", + "packages/google-cloud-documentai": "3.15.0", + "packages/google-cloud-documentai-toolbox": "0.17.0", + "packages/google-cloud-domains": "1.14.0", + "packages/google-cloud-edgecontainer": "0.8.0", + "packages/google-cloud-edgenetwork": "0.5.0", + "packages/google-cloud-enterpriseknowledgegraph": "0.6.0", + "packages/google-cloud-error-reporting": "1.15.0", + "packages/google-cloud-essential-contacts": "1.13.0", + "packages/google-cloud-eventarc": "1.20.0", + "packages/google-cloud-eventarc-publishing": "0.10.0", + "packages/google-cloud-filestore": "1.16.0", + "packages/google-cloud-financialservices": "0.4.0", + "packages/google-cloud-functions": "1.23.0", + "packages/google-cloud-gdchardwaremanagement": "0.5.0", + "packages/google-cloud-geminidataanalytics": "0.13.0", + "packages/google-cloud-gke-backup": "0.8.0", + "packages/google-cloud-gke-connect-gateway": "0.13.0", + "packages/google-cloud-gke-hub": "1.24.0", + "packages/google-cloud-gke-multicloud": "0.9.0", + "packages/google-cloud-gkerecommender": "0.3.0", + "packages/google-cloud-gsuiteaddons": "0.5.0", + "packages/google-cloud-hypercomputecluster": "0.4.0", + "packages/google-cloud-iam": "2.23.0", + "packages/google-cloud-iam-logging": "1.7.0", + "packages/google-cloud-iamconnectorcredentials": "0.1.0", + "packages/google-cloud-iap": "1.21.0", + "packages/google-cloud-ids": "1.13.0", + "packages/google-cloud-kms": "3.13.0", + "packages/google-cloud-kms-inventory": "0.6.0", + "packages/google-cloud-language": "2.20.0", + "packages/google-cloud-licensemanager": "0.4.0", + "packages/google-cloud-life-sciences": "0.12.0", + "packages/google-cloud-locationfinder": "0.4.0", + "packages/google-cloud-logging": "3.16.0", + "packages/google-cloud-lustre": "0.4.0", + "packages/google-cloud-maintenance-api": "0.4.0", + "packages/google-cloud-managed-identities": "1.15.0", + "packages/google-cloud-managedkafka": "0.4.0", + "packages/google-cloud-managedkafka-schemaregistry": "0.4.0", + "packages/google-cloud-media-translation": "0.14.0", + "packages/google-cloud-memcache": "1.15.0", + "packages/google-cloud-memorystore": "0.5.0", + "packages/google-cloud-migrationcenter": "0.4.0", + "packages/google-cloud-modelarmor": "0.7.0", + "packages/google-cloud-monitoring": "2.31.0", + "packages/google-cloud-monitoring-dashboards": "2.21.0", + "packages/google-cloud-monitoring-metrics-scopes": "1.12.0", + "packages/google-cloud-ndb": "2.5.0", + "packages/google-cloud-netapp": "0.10.0", + "packages/google-cloud-network-connectivity": "2.15.0", + "packages/google-cloud-network-management": "1.35.0", + "packages/google-cloud-network-security": "0.13.0", + "packages/google-cloud-network-services": "0.10.0", + "packages/google-cloud-notebooks": "1.16.0", + "packages/google-cloud-optimization": "1.14.0", + "packages/google-cloud-oracledatabase": "0.6.0", + "packages/google-cloud-orchestration-airflow": "1.21.0", + "packages/google-cloud-org-policy": "1.17.0", + "packages/google-cloud-os-config": "1.24.0", + "packages/google-cloud-os-login": "2.21.0", + "packages/google-cloud-parallelstore": "0.6.0", + "packages/google-cloud-parametermanager": "0.4.0", + "packages/google-cloud-phishing-protection": "1.17.0", + "packages/google-cloud-policy-troubleshooter": "1.16.0", + "packages/google-cloud-policysimulator": "0.4.0", + "packages/google-cloud-policytroubleshooter-iam": "0.5.0", + "packages/google-cloud-private-ca": "1.18.0", + "packages/google-cloud-private-catalog": "0.12.0", + "packages/google-cloud-privilegedaccessmanager": "0.4.0", + "packages/google-cloud-pubsub": "2.39.0", + "packages/google-cloud-quotas": "0.6.0", + "packages/google-cloud-rapidmigrationassessment": "0.4.0", + "packages/google-cloud-recaptcha-enterprise": "1.31.0", + "packages/google-cloud-recommendations-ai": "0.13.0", + "packages/google-cloud-recommender": "2.21.0", + "packages/google-cloud-redis": "2.21.0", + "packages/google-cloud-redis-cluster": "0.5.0", + "packages/google-cloud-resource-manager": "1.17.0", + "packages/google-cloud-retail": "2.10.0", + "packages/google-cloud-run": "0.16.0", + "packages/google-cloud-runtimeconfig": "0.37.0", + "packages/google-cloud-saasplatform-saasservicemgmt": "0.7.0", + "packages/google-cloud-scheduler": "2.20.0", + "packages/google-cloud-secret-manager": "2.29.0", + "packages/google-cloud-securesourcemanager": "0.6.0", + "packages/google-cloud-security-publicca": "0.7.0", + "packages/google-cloud-securitycenter": "1.45.0", + "packages/google-cloud-securitycentermanagement": "0.5.0", + "packages/google-cloud-service-control": "1.20.0", + "packages/google-cloud-service-directory": "1.18.0", + "packages/google-cloud-service-management": "1.17.0", + "packages/google-cloud-service-usage": "1.17.0", + "packages/google-cloud-servicehealth": "0.5.0", + "packages/google-cloud-shell": "1.16.0", + "packages/google-cloud-source-context": "1.11.0", + "packages/google-cloud-spanner": "3.68.0", + "packages/google-cloud-speech": "2.40.0", + "packages/google-cloud-storage": "3.12.0", + "packages/google-cloud-storage-control": "1.12.0", + "packages/google-cloud-storage-transfer": "1.21.0", + "packages/google-cloud-storagebatchoperations": "0.8.0", + "packages/google-cloud-storageinsights": "0.5.0", + "packages/google-cloud-support": "0.5.0", + "packages/google-cloud-talent": "2.20.0", + "packages/google-cloud-tasks": "2.22.0", + "packages/google-cloud-telcoautomation": "0.5.0", + "packages/google-cloud-testutils": "1.9.0", + "packages/google-cloud-texttospeech": "2.36.0", + "packages/google-cloud-tpu": "1.26.0", + "packages/google-cloud-trace": "1.19.0", + "packages/google-cloud-translate": "3.26.0", + "packages/google-cloud-vectorsearch": "0.11.0", + "packages/google-cloud-video-live-stream": "1.16.0", + "packages/google-cloud-video-stitcher": "0.11.0", + "packages/google-cloud-video-transcoder": "1.20.0", + "packages/google-cloud-videointelligence": "2.19.0", + "packages/google-cloud-vision": "3.14.0", + "packages/google-cloud-visionai": "0.5.0", + "packages/google-cloud-vm-migration": "1.16.0", + "packages/google-cloud-vmwareengine": "1.11.0", + "packages/google-cloud-vpc-access": "1.16.0", + "packages/google-cloud-webrisk": "1.21.0", + "packages/google-cloud-websecurityscanner": "1.20.0", + "packages/google-cloud-workflows": "1.22.0", + "packages/google-cloud-workloadmanager": "0.2.0", + "packages/google-cloud-workstations": "0.8.0", + "packages/google-developer-knowledge": "0.1.0", + "packages/google-devicesandservices-health": "0.1.0", + "packages/google-geo-type": "0.7.0", + "packages/google-maps-addressvalidation": "0.7.0", + "packages/google-maps-areainsights": "0.5.0", + "packages/google-maps-fleetengine": "0.6.0", + "packages/google-maps-fleetengine-delivery": "0.6.0", + "packages/google-maps-geocode": "0.3.0", + "packages/google-maps-mapmanagement": "0.1.0", + "packages/google-maps-mapsplatformdatasets": "0.8.0", + "packages/google-maps-navconnect": "0.2.0", + "packages/google-maps-places": "0.9.0", + "packages/google-maps-routeoptimization": "0.5.0", + "packages/google-maps-routing": "0.11.0", + "packages/google-maps-solar": "0.6.0", + "packages/google-resumable-media": "2.10.0", + "packages/google-shopping-css": "0.6.0", + "packages/google-shopping-merchant-accounts": "1.6.0", + "packages/google-shopping-merchant-conversions": "1.4.0", + "packages/google-shopping-merchant-datasources": "1.5.0", + "packages/google-shopping-merchant-inventories": "1.5.0", + "packages/google-shopping-merchant-issueresolution": "1.4.0", + "packages/google-shopping-merchant-lfp": "1.4.0", + "packages/google-shopping-merchant-notifications": "1.4.0", + "packages/google-shopping-merchant-ordertracking": "1.4.0", + "packages/google-shopping-merchant-products": "1.7.0", + "packages/google-shopping-merchant-productstudio": "0.5.0", + "packages/google-shopping-merchant-promotions": "1.4.0", + "packages/google-shopping-merchant-quota": "1.5.0", + "packages/google-shopping-merchant-reports": "1.5.0", + "packages/google-shopping-merchant-reviews": "0.6.0", + "packages/google-shopping-type": "1.5.0", + "packages/googleapis-common-protos": "1.75.0", + "packages/grafeas": "1.23.0", + "packages/grpc-google-iam-v1": "0.14.4", + "packages/proto-plus": "1.28.0", + "packages/sqlalchemy-spanner": "1.19.0" +} diff --git a/.release-please-individual-manifest.json b/.release-please-individual-manifest.json new file mode 100644 index 000000000000..1bdea73da032 --- /dev/null +++ b/.release-please-individual-manifest.json @@ -0,0 +1,8 @@ +{ + "packages/bigframes": "2.43.0", + "packages/google-cloud-bigtable": "2.38.0", + "packages/google-cloud-firestore": "2.27.0", + "packages/google-crc32c": "1.8.0", + "packages/pandas-gbq": "0.35.0", + "packages/sqlalchemy-bigquery": "1.17.0" +} \ No newline at end of file diff --git a/release-please-bulk-config.json b/release-please-bulk-config.json new file mode 100644 index 000000000000..eddb861e6b11 --- /dev/null +++ b/release-please-bulk-config.json @@ -0,0 +1,3828 @@ +{ + "bump-minor-pre-major": true, + "bump-patch-for-minor-pre-major": true, + "packages": { + "packages/bigquery-magics": { + "component": "bigquery-magics" + }, + "packages/db-dtypes": { + "component": "db-dtypes" + }, + "packages/django-google-spanner": { + "component": "django-google-spanner" + }, + "packages/gapic-generator": { + "component": "gapic-generator" + }, + "packages/gcp-sphinx-docfx-yaml": { + "component": "gcp-sphinx-docfx-yaml" + }, + "packages/google-ads-admanager": { + "component": "google-ads-admanager", + "extra-files": [ + "google/ads/admanager/gapic_version.py", + "google/ads/admanager_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.ads.admanager.v1.json", + "type": "json" + } + ] + }, + "packages/google-ads-datamanager": { + "component": "google-ads-datamanager", + "extra-files": [ + "google/ads/datamanager/gapic_version.py", + "google/ads/datamanager_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.ads.datamanager.v1.json", + "type": "json" + } + ] + }, + "packages/google-ads-marketingplatform-admin": { + "component": "google-ads-marketingplatform-admin", + "extra-files": [ + "google/ads/marketingplatform_admin/gapic_version.py", + "google/ads/marketingplatform_admin_v1alpha/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.marketingplatform.admin.v1alpha.json", + "type": "json" + } + ] + }, + "packages/google-ai-generativelanguage": { + "component": "google-ai-generativelanguage", + "extra-files": [ + "google/ai/generativelanguage/gapic_version.py", + "google/ai/generativelanguage_v1/gapic_version.py", + "google/ai/generativelanguage_v1alpha/gapic_version.py", + "google/ai/generativelanguage_v1beta/gapic_version.py", + "google/ai/generativelanguage_v1beta2/gapic_version.py", + "google/ai/generativelanguage_v1beta3/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.ai.generativelanguage.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.ai.generativelanguage.v1alpha.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.ai.generativelanguage.v1beta.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.ai.generativelanguage.v1beta2.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.ai.generativelanguage.v1beta3.json", + "type": "json" + } + ] + }, + "packages/google-analytics-admin": { + "component": "google-analytics-admin", + "extra-files": [ + "google/analytics/admin/gapic_version.py", + "google/analytics/admin_v1alpha/gapic_version.py", + "google/analytics/admin_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.analytics.admin.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-analytics-data": { + "component": "google-analytics-data", + "extra-files": [ + "google/analytics/data/gapic_version.py", + "google/analytics/data_v1alpha/gapic_version.py", + "google/analytics/data_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.analytics.data.v1alpha.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.analytics.data.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-api-core": { + "component": "google-api-core" + }, + "packages/google-apps-card": { + "component": "google-apps-card", + "extra-files": [ + "google/apps/card/gapic_version.py", + "google/apps/card_v1/gapic_version.py" + ] + }, + "packages/google-apps-chat": { + "component": "google-apps-chat", + "extra-files": [ + "google/apps/chat/gapic_version.py", + "google/apps/chat_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.chat.v1.json", + "type": "json" + } + ] + }, + "packages/google-apps-events-subscriptions": { + "component": "google-apps-events-subscriptions", + "extra-files": [ + "google/apps/events_subscriptions/gapic_version.py", + "google/apps/events_subscriptions_v1/gapic_version.py", + "google/apps/events_subscriptions_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.apps.events.subscriptions.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.apps.events.subscriptions.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-apps-meet": { + "component": "google-apps-meet", + "extra-files": [ + "google/apps/meet/gapic_version.py", + "google/apps/meet_v2/gapic_version.py", + "google/apps/meet_v2beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.apps.meet.v2.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.apps.meet.v2beta.json", + "type": "json" + } + ] + }, + "packages/google-apps-script-type": { + "component": "google-apps-script-type", + "extra-files": [ + "google/apps/script/type/calendar/gapic_version.py", + "google/apps/script/type/docs/gapic_version.py", + "google/apps/script/type/drive/gapic_version.py", + "google/apps/script/type/gapic_version.py", + "google/apps/script/type/gmail/gapic_version.py", + "google/apps/script/type/sheets/gapic_version.py", + "google/apps/script/type/slides/gapic_version.py" + ] + }, + "packages/google-area120-tables": { + "component": "google-area120-tables", + "extra-files": [ + "google/area120/tables/gapic_version.py", + "google/area120/tables_v1alpha1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.area120.tables.v1alpha1.json", + "type": "json" + } + ] + }, + "packages/google-auth": { + "component": "google-auth" + }, + "packages/google-auth-httplib2": { + "component": "google-auth-httplib2" + }, + "packages/google-auth-oauthlib": { + "component": "google-auth-oauthlib" + }, + "packages/google-backstory": { + "component": "google-backstory", + "extra-files": [ + "google/backstory/gapic_version.py" + ] + }, + "packages/google-cloud-access-approval": { + "component": "google-cloud-access-approval", + "extra-files": [ + "google/cloud/accessapproval/gapic_version.py", + "google/cloud/accessapproval_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.accessapproval.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-access-context-manager": { + "component": "google-cloud-access-context-manager" + }, + "packages/google-cloud-advisorynotifications": { + "component": "google-cloud-advisorynotifications", + "extra-files": [ + "google/cloud/advisorynotifications/gapic_version.py", + "google/cloud/advisorynotifications_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.advisorynotifications.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-agentidentitycredentials": { + "component": "google-cloud-agentidentitycredentials", + "extra-files": [ + "google/cloud/agentidentitycredentials/gapic_version.py", + "google/cloud/agentidentitycredentials_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.agentidentitycredentials.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-alloydb": { + "component": "google-cloud-alloydb", + "extra-files": [ + "google/cloud/alloydb/gapic_version.py", + "google/cloud/alloydb_v1/gapic_version.py", + "google/cloud/alloydb_v1alpha/gapic_version.py", + "google/cloud/alloydb_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.alloydb.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.alloydb.v1alpha.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.alloydb.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-cloud-alloydb-connectors": { + "component": "google-cloud-alloydb-connectors", + "extra-files": [ + "google/cloud/alloydb/connectors/gapic_version.py", + "google/cloud/alloydb/connectors_v1/gapic_version.py", + "google/cloud/alloydb/connectors_v1alpha/gapic_version.py", + "google/cloud/alloydb/connectors_v1beta/gapic_version.py" + ] + }, + "packages/google-cloud-api-gateway": { + "component": "google-cloud-api-gateway", + "extra-files": [ + "google/cloud/apigateway/gapic_version.py", + "google/cloud/apigateway_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.apigateway.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-api-keys": { + "component": "google-cloud-api-keys", + "extra-files": [ + "google/cloud/api_keys/gapic_version.py", + "google/cloud/api_keys_v2/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.api.apikeys.v2.json", + "type": "json" + } + ] + }, + "packages/google-cloud-apigee-connect": { + "component": "google-cloud-apigee-connect", + "extra-files": [ + "google/cloud/apigeeconnect/gapic_version.py", + "google/cloud/apigeeconnect_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.apigeeconnect.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-apigee-registry": { + "component": "google-cloud-apigee-registry", + "extra-files": [ + "google/cloud/apigee_registry/gapic_version.py", + "google/cloud/apigee_registry_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.apigeeregistry.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-apihub": { + "component": "google-cloud-apihub", + "extra-files": [ + "google/cloud/apihub/gapic_version.py", + "google/cloud/apihub_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.apihub.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-apiregistry": { + "component": "google-cloud-apiregistry", + "extra-files": [ + "google/cloud/apiregistry/gapic_version.py", + "google/cloud/apiregistry_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.apiregistry.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-cloud-appengine-admin": { + "component": "google-cloud-appengine-admin", + "extra-files": [ + "google/cloud/appengine_admin/gapic_version.py", + "google/cloud/appengine_admin_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.appengine.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-appengine-logging": { + "component": "google-cloud-appengine-logging", + "extra-files": [ + "google/cloud/appengine_logging/gapic_version.py", + "google/cloud/appengine_logging_v1/gapic_version.py" + ] + }, + "packages/google-cloud-apphub": { + "component": "google-cloud-apphub", + "extra-files": [ + "google/cloud/apphub/gapic_version.py", + "google/cloud/apphub_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.apphub.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-appoptimize": { + "component": "google-cloud-appoptimize", + "extra-files": [ + "google/cloud/appoptimize/gapic_version.py", + "google/cloud/appoptimize_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.appoptimize.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-cloud-artifact-registry": { + "component": "google-cloud-artifact-registry", + "extra-files": [ + "google/cloud/artifactregistry/gapic_version.py", + "google/cloud/artifactregistry_v1/gapic_version.py", + "google/cloud/artifactregistry_v1beta2/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.devtools.artifactregistry.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.devtools.artifactregistry.v1beta2.json", + "type": "json" + } + ] + }, + "packages/google-cloud-asset": { + "component": "google-cloud-asset", + "extra-files": [ + "google/cloud/asset/gapic_version.py", + "google/cloud/asset_v1/gapic_version.py", + "google/cloud/asset_v1p1beta1/gapic_version.py", + "google/cloud/asset_v1p2beta1/gapic_version.py", + "google/cloud/asset_v1p5beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.asset.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.asset.v1p1beta1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.asset.v1p2beta1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.asset.v1p5beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-assured-workloads": { + "component": "google-cloud-assured-workloads", + "extra-files": [ + "google/cloud/assuredworkloads/gapic_version.py", + "google/cloud/assuredworkloads_v1/gapic_version.py", + "google/cloud/assuredworkloads_v1beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.assuredworkloads.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.assuredworkloads.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-audit-log": { + "component": "google-cloud-audit-log" + }, + "packages/google-cloud-auditmanager": { + "component": "google-cloud-auditmanager", + "extra-files": [ + "google/cloud/auditmanager/gapic_version.py", + "google/cloud/auditmanager_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.auditmanager.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-automl": { + "component": "google-cloud-automl", + "extra-files": [ + "google/cloud/automl/gapic_version.py", + "google/cloud/automl_v1/gapic_version.py", + "google/cloud/automl_v1beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.automl.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.automl.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-backupdr": { + "component": "google-cloud-backupdr", + "extra-files": [ + "google/cloud/backupdr/gapic_version.py", + "google/cloud/backupdr_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.backupdr.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-bare-metal-solution": { + "component": "google-cloud-bare-metal-solution", + "extra-files": [ + "google/cloud/bare_metal_solution/gapic_version.py", + "google/cloud/bare_metal_solution_v2/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.baremetalsolution.v2.json", + "type": "json" + } + ] + }, + "packages/google-cloud-batch": { + "component": "google-cloud-batch", + "extra-files": [ + "google/cloud/batch/gapic_version.py", + "google/cloud/batch_v1/gapic_version.py", + "google/cloud/batch_v1alpha/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.batch.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.batch.v1alpha.json", + "type": "json" + } + ] + }, + "packages/google-cloud-beyondcorp-appconnections": { + "component": "google-cloud-beyondcorp-appconnections", + "extra-files": [ + "google/cloud/beyondcorp_appconnections/gapic_version.py", + "google/cloud/beyondcorp_appconnections_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.beyondcorp.appconnections.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-beyondcorp-appconnectors": { + "component": "google-cloud-beyondcorp-appconnectors", + "extra-files": [ + "google/cloud/beyondcorp_appconnectors/gapic_version.py", + "google/cloud/beyondcorp_appconnectors_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.beyondcorp.appconnectors.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-beyondcorp-appgateways": { + "component": "google-cloud-beyondcorp-appgateways", + "extra-files": [ + "google/cloud/beyondcorp_appgateways/gapic_version.py", + "google/cloud/beyondcorp_appgateways_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.beyondcorp.appgateways.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-beyondcorp-clientconnectorservices": { + "component": "google-cloud-beyondcorp-clientconnectorservices", + "extra-files": [ + "google/cloud/beyondcorp_clientconnectorservices/gapic_version.py", + "google/cloud/beyondcorp_clientconnectorservices_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.beyondcorp.clientconnectorservices.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-beyondcorp-clientgateways": { + "component": "google-cloud-beyondcorp-clientgateways", + "extra-files": [ + "google/cloud/beyondcorp_clientgateways/gapic_version.py", + "google/cloud/beyondcorp_clientgateways_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.beyondcorp.clientgateways.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-biglake": { + "component": "google-cloud-biglake", + "extra-files": [ + "google/cloud/biglake/gapic_version.py", + "google/cloud/biglake_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.biglake.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-biglake-hive": { + "component": "google-cloud-biglake-hive", + "extra-files": [ + "google/cloud/biglake_hive/gapic_version.py", + "google/cloud/biglake_hive_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.biglake.hive.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-cloud-bigquery": { + "component": "google-cloud-bigquery" + }, + "packages/google-cloud-bigquery-analyticshub": { + "component": "google-cloud-bigquery-analyticshub", + "extra-files": [ + "google/cloud/bigquery_analyticshub/gapic_version.py", + "google/cloud/bigquery_analyticshub_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.bigquery.analyticshub.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-bigquery-biglake": { + "component": "google-cloud-bigquery-biglake", + "extra-files": [ + "google/cloud/bigquery_biglake/gapic_version.py", + "google/cloud/bigquery_biglake_v1/gapic_version.py", + "google/cloud/bigquery_biglake_v1alpha1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.bigquery.biglake.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.bigquery.biglake.v1alpha1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-bigquery-connection": { + "component": "google-cloud-bigquery-connection", + "extra-files": [ + "google/cloud/bigquery_connection/gapic_version.py", + "google/cloud/bigquery_connection_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.bigquery.connection.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-bigquery-data-exchange": { + "component": "google-cloud-bigquery-data-exchange", + "extra-files": [ + "google/cloud/bigquery_data_exchange/gapic_version.py", + "google/cloud/bigquery_data_exchange_v1beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.bigquery.dataexchange.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-bigquery-datapolicies": { + "component": "google-cloud-bigquery-datapolicies", + "extra-files": [ + "google/cloud/bigquery_datapolicies/gapic_version.py", + "google/cloud/bigquery_datapolicies_v1/gapic_version.py", + "google/cloud/bigquery_datapolicies_v1beta1/gapic_version.py", + "google/cloud/bigquery_datapolicies_v2/gapic_version.py", + "google/cloud/bigquery_datapolicies_v2beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.bigquery.datapolicies.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.bigquery.datapolicies.v1beta1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.bigquery.datapolicies.v2.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.bigquery.datapolicies.v2beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-bigquery-datatransfer": { + "component": "google-cloud-bigquery-datatransfer", + "extra-files": [ + "google/cloud/bigquery_datatransfer/gapic_version.py", + "google/cloud/bigquery_datatransfer_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.bigquery.datatransfer.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-bigquery-logging": { + "component": "google-cloud-bigquery-logging", + "extra-files": [ + "google/cloud/bigquery_logging/gapic_version.py", + "google/cloud/bigquery_logging_v1/gapic_version.py" + ] + }, + "packages/google-cloud-bigquery-migration": { + "component": "google-cloud-bigquery-migration", + "extra-files": [ + "google/cloud/bigquery_migration/gapic_version.py", + "google/cloud/bigquery_migration_v2/gapic_version.py", + "google/cloud/bigquery_migration_v2alpha/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.bigquery.migration.v2.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.bigquery.migration.v2alpha.json", + "type": "json" + } + ] + }, + "packages/google-cloud-bigquery-reservation": { + "component": "google-cloud-bigquery-reservation", + "extra-files": [ + "google/cloud/bigquery_reservation/gapic_version.py", + "google/cloud/bigquery_reservation_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.bigquery.reservation.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-bigquery-storage": { + "component": "google-cloud-bigquery-storage", + "extra-files": [ + "google/cloud/bigquery_storage/gapic_version.py", + "google/cloud/bigquery_storage_v1/gapic_version.py", + "google/cloud/bigquery_storage_v1alpha/gapic_version.py", + "google/cloud/bigquery_storage_v1beta/gapic_version.py", + "google/cloud/bigquery_storage_v1beta2/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.bigquery.storage.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.bigquery.storage.v1alpha.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.bigquery.storage.v1beta.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.bigquery.storage.v1beta2.json", + "type": "json" + } + ] + }, + "packages/google-cloud-billing": { + "component": "google-cloud-billing", + "extra-files": [ + "google/cloud/billing/gapic_version.py", + "google/cloud/billing_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.billing.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-billing-budgets": { + "component": "google-cloud-billing-budgets", + "extra-files": [ + "google/cloud/billing/budgets/gapic_version.py", + "google/cloud/billing/budgets_v1/gapic_version.py", + "google/cloud/billing/budgets_v1beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.billing.budgets.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.billing.budgets.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-binary-authorization": { + "component": "google-cloud-binary-authorization", + "extra-files": [ + "google/cloud/binaryauthorization/gapic_version.py", + "google/cloud/binaryauthorization_v1/gapic_version.py", + "google/cloud/binaryauthorization_v1beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.binaryauthorization.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.binaryauthorization.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-build": { + "component": "google-cloud-build", + "extra-files": [ + "google/cloud/devtools/cloudbuild/gapic_version.py", + "google/cloud/devtools/cloudbuild_v1/gapic_version.py", + "google/cloud/devtools/cloudbuild_v2/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.devtools.cloudbuild.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.devtools.cloudbuild.v2.json", + "type": "json" + } + ] + }, + "packages/google-cloud-capacityplanner": { + "component": "google-cloud-capacityplanner", + "extra-files": [ + "google/cloud/capacityplanner/gapic_version.py", + "google/cloud/capacityplanner_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.capacityplanner.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-cloud-certificate-manager": { + "component": "google-cloud-certificate-manager", + "extra-files": [ + "google/cloud/certificate_manager/gapic_version.py", + "google/cloud/certificate_manager_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.certificatemanager.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-ces": { + "component": "google-cloud-ces", + "extra-files": [ + "google/cloud/ces/gapic_version.py", + "google/cloud/ces_v1/gapic_version.py", + "google/cloud/ces_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.ces.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.ces.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-cloud-channel": { + "component": "google-cloud-channel", + "extra-files": [ + "google/cloud/channel/gapic_version.py", + "google/cloud/channel_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.channel.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-chronicle": { + "component": "google-cloud-chronicle", + "extra-files": [ + "google/cloud/chronicle/gapic_version.py", + "google/cloud/chronicle_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.chronicle.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-cloudcontrolspartner": { + "component": "google-cloud-cloudcontrolspartner", + "extra-files": [ + "google/cloud/cloudcontrolspartner/gapic_version.py", + "google/cloud/cloudcontrolspartner_v1/gapic_version.py", + "google/cloud/cloudcontrolspartner_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.cloudcontrolspartner.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.cloudcontrolspartner.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-cloud-cloudsecuritycompliance": { + "component": "google-cloud-cloudsecuritycompliance", + "extra-files": [ + "google/cloud/cloudsecuritycompliance/gapic_version.py", + "google/cloud/cloudsecuritycompliance_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.cloudsecuritycompliance.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-commerce-consumer-procurement": { + "component": "google-cloud-commerce-consumer-procurement", + "extra-files": [ + "google/cloud/commerce_consumer_procurement/gapic_version.py", + "google/cloud/commerce_consumer_procurement_v1/gapic_version.py", + "google/cloud/commerce_consumer_procurement_v1alpha1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.commerce.consumer.procurement.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.commerce.consumer.procurement.v1alpha1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-common": { + "component": "google-cloud-common", + "extra-files": [ + "google/cloud/common/gapic_version.py" + ] + }, + "packages/google-cloud-compute": { + "component": "google-cloud-compute", + "extra-files": [ + "google/cloud/compute/gapic_version.py", + "google/cloud/compute_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.compute.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-compute-v1beta": { + "component": "google-cloud-compute-v1beta", + "extra-files": [ + "google/cloud/compute_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.compute.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-cloud-confidentialcomputing": { + "component": "google-cloud-confidentialcomputing", + "extra-files": [ + "google/cloud/confidentialcomputing/gapic_version.py", + "google/cloud/confidentialcomputing_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.confidentialcomputing.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-config": { + "component": "google-cloud-config", + "extra-files": [ + "google/cloud/config/gapic_version.py", + "google/cloud/config_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.config.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-configdelivery": { + "component": "google-cloud-configdelivery", + "extra-files": [ + "google/cloud/configdelivery/gapic_version.py", + "google/cloud/configdelivery_v1/gapic_version.py", + "google/cloud/configdelivery_v1alpha/gapic_version.py", + "google/cloud/configdelivery_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.configdelivery.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.configdelivery.v1alpha.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.configdelivery.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-cloud-contact-center-insights": { + "component": "google-cloud-contact-center-insights", + "extra-files": [ + "google/cloud/contact_center_insights/gapic_version.py", + "google/cloud/contact_center_insights_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.contactcenterinsights.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-container": { + "component": "google-cloud-container", + "extra-files": [ + "google/cloud/container/gapic_version.py", + "google/cloud/container_v1/gapic_version.py", + "google/cloud/container_v1beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.container.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.container.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-containeranalysis": { + "component": "google-cloud-containeranalysis", + "extra-files": [ + "google/cloud/devtools/containeranalysis/gapic_version.py", + "google/cloud/devtools/containeranalysis_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.devtools.containeranalysis.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-contentwarehouse": { + "component": "google-cloud-contentwarehouse", + "extra-files": [ + "google/cloud/contentwarehouse/gapic_version.py", + "google/cloud/contentwarehouse_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.contentwarehouse.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-core": { + "component": "google-cloud-core" + }, + "packages/google-cloud-data-fusion": { + "component": "google-cloud-data-fusion", + "extra-files": [ + "google/cloud/data_fusion/gapic_version.py", + "google/cloud/data_fusion_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.datafusion.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-data-qna": { + "component": "google-cloud-data-qna", + "extra-files": [ + "google/cloud/dataqna/gapic_version.py", + "google/cloud/dataqna_v1alpha/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.dataqna.v1alpha.json", + "type": "json" + } + ] + }, + "packages/google-cloud-databasecenter": { + "component": "google-cloud-databasecenter", + "extra-files": [ + "google/cloud/databasecenter/gapic_version.py", + "google/cloud/databasecenter_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.databasecenter.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-cloud-datacatalog": { + "component": "google-cloud-datacatalog", + "extra-files": [ + "google/cloud/datacatalog/gapic_version.py", + "google/cloud/datacatalog_v1/gapic_version.py", + "google/cloud/datacatalog_v1beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.datacatalog.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.datacatalog.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-datacatalog-lineage": { + "component": "google-cloud-datacatalog-lineage", + "extra-files": [ + "google/cloud/datacatalog_lineage/gapic_version.py", + "google/cloud/datacatalog_lineage_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.datacatalog.lineage.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-datacatalog-lineage-configmanagement": { + "component": "google-cloud-datacatalog-lineage-configmanagement", + "extra-files": [ + "google/cloud/datacatalog_lineage_configmanagement/gapic_version.py", + "google/cloud/datacatalog_lineage_configmanagement_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.datacatalog.lineage.configmanagement.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-dataflow-client": { + "component": "google-cloud-dataflow-client", + "extra-files": [ + "google/cloud/dataflow/gapic_version.py", + "google/cloud/dataflow_v1beta3/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.dataflow.v1beta3.json", + "type": "json" + } + ] + }, + "packages/google-cloud-dataform": { + "component": "google-cloud-dataform", + "extra-files": [ + "google/cloud/dataform/gapic_version.py", + "google/cloud/dataform_v1/gapic_version.py", + "google/cloud/dataform_v1beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.dataform.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.dataform.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-datalabeling": { + "component": "google-cloud-datalabeling", + "extra-files": [ + "google/cloud/datalabeling/gapic_version.py", + "google/cloud/datalabeling_v1beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.datalabeling.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-dataplex": { + "component": "google-cloud-dataplex", + "extra-files": [ + "google/cloud/dataplex/gapic_version.py", + "google/cloud/dataplex_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.dataplex.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-dataproc": { + "component": "google-cloud-dataproc", + "extra-files": [ + "google/cloud/dataproc/gapic_version.py", + "google/cloud/dataproc_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.dataproc.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-dataproc-metastore": { + "component": "google-cloud-dataproc-metastore", + "extra-files": [ + "google/cloud/metastore/gapic_version.py", + "google/cloud/metastore_v1/gapic_version.py", + "google/cloud/metastore_v1alpha/gapic_version.py", + "google/cloud/metastore_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.metastore.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.metastore.v1alpha.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.metastore.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-cloud-datastore": { + "component": "google-cloud-datastore", + "extra-files": [ + "google/cloud/datastore/gapic_version.py", + "google/cloud/datastore_admin/gapic_version.py", + "google/cloud/datastore_admin_v1/gapic_version.py", + "google/cloud/datastore_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.datastore.admin.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.datastore.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-datastream": { + "component": "google-cloud-datastream", + "extra-files": [ + "google/cloud/datastream/gapic_version.py", + "google/cloud/datastream_v1/gapic_version.py", + "google/cloud/datastream_v1alpha1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.datastream.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.datastream.v1alpha1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-deploy": { + "component": "google-cloud-deploy", + "extra-files": [ + "google/cloud/deploy/gapic_version.py", + "google/cloud/deploy_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.deploy.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-developerconnect": { + "component": "google-cloud-developerconnect", + "extra-files": [ + "google/cloud/developerconnect/gapic_version.py", + "google/cloud/developerconnect_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.developerconnect.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-devicestreaming": { + "component": "google-cloud-devicestreaming", + "extra-files": [ + "google/cloud/devicestreaming/gapic_version.py", + "google/cloud/devicestreaming_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.devicestreaming.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-dialogflow": { + "component": "google-cloud-dialogflow", + "extra-files": [ + "google/cloud/dialogflow/gapic_version.py", + "google/cloud/dialogflow_v2/gapic_version.py", + "google/cloud/dialogflow_v2beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.dialogflow.v2.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.dialogflow.v2beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-dialogflow-cx": { + "component": "google-cloud-dialogflow-cx", + "extra-files": [ + "google/cloud/dialogflowcx/gapic_version.py", + "google/cloud/dialogflowcx_v3/gapic_version.py", + "google/cloud/dialogflowcx_v3beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.dialogflow.cx.v3.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.dialogflow.cx.v3beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-discoveryengine": { + "component": "google-cloud-discoveryengine", + "extra-files": [ + "google/cloud/discoveryengine/gapic_version.py", + "google/cloud/discoveryengine_v1/gapic_version.py", + "google/cloud/discoveryengine_v1alpha/gapic_version.py", + "google/cloud/discoveryengine_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.discoveryengine.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.discoveryengine.v1alpha.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.discoveryengine.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-cloud-dlp": { + "component": "google-cloud-dlp", + "extra-files": [ + "google/cloud/dlp/gapic_version.py", + "google/cloud/dlp_v2/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.privacy.dlp.v2.json", + "type": "json" + } + ] + }, + "packages/google-cloud-dms": { + "component": "google-cloud-dms", + "extra-files": [ + "google/cloud/clouddms/gapic_version.py", + "google/cloud/clouddms_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.clouddms.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-dns": { + "component": "google-cloud-dns" + }, + "packages/google-cloud-documentai": { + "component": "google-cloud-documentai", + "extra-files": [ + "google/cloud/documentai/gapic_version.py", + "google/cloud/documentai_v1/gapic_version.py", + "google/cloud/documentai_v1beta3/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.documentai.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.documentai.v1beta3.json", + "type": "json" + } + ] + }, + "packages/google-cloud-documentai-toolbox": { + "component": "google-cloud-documentai-toolbox" + }, + "packages/google-cloud-domains": { + "component": "google-cloud-domains", + "extra-files": [ + "google/cloud/domains/gapic_version.py", + "google/cloud/domains_v1/gapic_version.py", + "google/cloud/domains_v1beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.domains.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.domains.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-edgecontainer": { + "component": "google-cloud-edgecontainer", + "extra-files": [ + "google/cloud/edgecontainer/gapic_version.py", + "google/cloud/edgecontainer_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.edgecontainer.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-edgenetwork": { + "component": "google-cloud-edgenetwork", + "extra-files": [ + "google/cloud/edgenetwork/gapic_version.py", + "google/cloud/edgenetwork_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.edgenetwork.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-enterpriseknowledgegraph": { + "component": "google-cloud-enterpriseknowledgegraph", + "extra-files": [ + "google/cloud/enterpriseknowledgegraph/gapic_version.py", + "google/cloud/enterpriseknowledgegraph_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.enterpriseknowledgegraph.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-error-reporting": { + "component": "google-cloud-error-reporting", + "extra-files": [ + "google/cloud/error_reporting/gapic_version.py", + "google/cloud/errorreporting/gapic_version.py", + "google/cloud/errorreporting_v1beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.devtools.clouderrorreporting.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-essential-contacts": { + "component": "google-cloud-essential-contacts", + "extra-files": [ + "google/cloud/essential_contacts/gapic_version.py", + "google/cloud/essential_contacts_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.essentialcontacts.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-eventarc": { + "component": "google-cloud-eventarc", + "extra-files": [ + "google/cloud/eventarc/gapic_version.py", + "google/cloud/eventarc_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.eventarc.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-eventarc-publishing": { + "component": "google-cloud-eventarc-publishing", + "extra-files": [ + "google/cloud/eventarc_publishing/gapic_version.py", + "google/cloud/eventarc_publishing_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.eventarc.publishing.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-filestore": { + "component": "google-cloud-filestore", + "extra-files": [ + "google/cloud/filestore/gapic_version.py", + "google/cloud/filestore_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.filestore.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-financialservices": { + "component": "google-cloud-financialservices", + "extra-files": [ + "google/cloud/financialservices/gapic_version.py", + "google/cloud/financialservices_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.financialservices.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-functions": { + "component": "google-cloud-functions", + "extra-files": [ + "google/cloud/functions/gapic_version.py", + "google/cloud/functions_v1/gapic_version.py", + "google/cloud/functions_v2/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.functions.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.functions.v2.json", + "type": "json" + } + ] + }, + "packages/google-cloud-gdchardwaremanagement": { + "component": "google-cloud-gdchardwaremanagement", + "extra-files": [ + "google/cloud/gdchardwaremanagement/gapic_version.py", + "google/cloud/gdchardwaremanagement_v1alpha/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.gdchardwaremanagement.v1alpha.json", + "type": "json" + } + ] + }, + "packages/google-cloud-geminidataanalytics": { + "component": "google-cloud-geminidataanalytics", + "extra-files": [ + "google/cloud/geminidataanalytics/gapic_version.py", + "google/cloud/geminidataanalytics_v1/gapic_version.py", + "google/cloud/geminidataanalytics_v1alpha/gapic_version.py", + "google/cloud/geminidataanalytics_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.geminidataanalytics.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.geminidataanalytics.v1alpha.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.geminidataanalytics.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-cloud-gke-backup": { + "component": "google-cloud-gke-backup", + "extra-files": [ + "google/cloud/gke_backup/gapic_version.py", + "google/cloud/gke_backup_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.gkebackup.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-gke-connect-gateway": { + "component": "google-cloud-gke-connect-gateway", + "extra-files": [ + "google/cloud/gkeconnect/gateway/gapic_version.py", + "google/cloud/gkeconnect/gateway_v1/gapic_version.py", + "google/cloud/gkeconnect/gateway_v1beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.gkeconnect.gateway.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.gkeconnect.gateway.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-gke-hub": { + "component": "google-cloud-gke-hub", + "extra-files": [ + "google/cloud/gkehub/gapic_version.py", + "google/cloud/gkehub_v1/configmanagement_v1/gapic_version.py", + "google/cloud/gkehub_v1/gapic_version.py", + "google/cloud/gkehub_v1/multiclusteringress_v1/gapic_version.py", + "google/cloud/gkehub_v1/rbacrolebindingactuation_v1/gapic_version.py", + "google/cloud/gkehub_v1beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.gkehub.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.gkehub.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-gke-multicloud": { + "component": "google-cloud-gke-multicloud", + "extra-files": [ + "google/cloud/gke_multicloud/gapic_version.py", + "google/cloud/gke_multicloud_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.gkemulticloud.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-gkerecommender": { + "component": "google-cloud-gkerecommender", + "extra-files": [ + "google/cloud/gkerecommender/gapic_version.py", + "google/cloud/gkerecommender_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.gkerecommender.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-gsuiteaddons": { + "component": "google-cloud-gsuiteaddons", + "extra-files": [ + "google/cloud/gsuiteaddons/gapic_version.py", + "google/cloud/gsuiteaddons_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.gsuiteaddons.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-hypercomputecluster": { + "component": "google-cloud-hypercomputecluster", + "extra-files": [ + "google/cloud/hypercomputecluster/gapic_version.py", + "google/cloud/hypercomputecluster_v1/gapic_version.py", + "google/cloud/hypercomputecluster_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.hypercomputecluster.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.hypercomputecluster.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-cloud-iam": { + "component": "google-cloud-iam", + "extra-files": [ + "google/cloud/iam/gapic_version.py", + "google/cloud/iam_admin/gapic_version.py", + "google/cloud/iam_admin_v1/gapic_version.py", + "google/cloud/iam_credentials/gapic_version.py", + "google/cloud/iam_credentials_v1/gapic_version.py", + "google/cloud/iam_v2/gapic_version.py", + "google/cloud/iam_v2beta/gapic_version.py", + "google/cloud/iam_v3/gapic_version.py", + "google/cloud/iam_v3beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.iam.admin.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.iam.credentials.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.iam.v2.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.iam.v2beta.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.iam.v3.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.iam.v3beta.json", + "type": "json" + } + ] + }, + "packages/google-cloud-iam-logging": { + "component": "google-cloud-iam-logging", + "extra-files": [ + "google/cloud/iam_logging/gapic_version.py", + "google/cloud/iam_logging_v1/gapic_version.py" + ] + }, + "packages/google-cloud-iamconnectorcredentials": { + "component": "google-cloud-iamconnectorcredentials", + "extra-files": [ + "google/cloud/iamconnectorcredentials/gapic_version.py", + "google/cloud/iamconnectorcredentials_v1alpha/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.iamconnectorcredentials.v1alpha.json", + "type": "json" + } + ] + }, + "packages/google-cloud-iap": { + "component": "google-cloud-iap", + "extra-files": [ + "google/cloud/iap/gapic_version.py", + "google/cloud/iap_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.iap.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-ids": { + "component": "google-cloud-ids", + "extra-files": [ + "google/cloud/ids/gapic_version.py", + "google/cloud/ids_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.ids.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-kms": { + "component": "google-cloud-kms", + "extra-files": [ + "google/cloud/kms/gapic_version.py", + "google/cloud/kms_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.kms.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-kms-inventory": { + "component": "google-cloud-kms-inventory", + "extra-files": [ + "google/cloud/kms_inventory/gapic_version.py", + "google/cloud/kms_inventory_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.kms.inventory.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-language": { + "component": "google-cloud-language", + "extra-files": [ + "google/cloud/language/gapic_version.py", + "google/cloud/language_v1/gapic_version.py", + "google/cloud/language_v1beta2/gapic_version.py", + "google/cloud/language_v2/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.language.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.language.v1beta2.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.language.v2.json", + "type": "json" + } + ] + }, + "packages/google-cloud-licensemanager": { + "component": "google-cloud-licensemanager", + "extra-files": [ + "google/cloud/licensemanager/gapic_version.py", + "google/cloud/licensemanager_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.licensemanager.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-life-sciences": { + "component": "google-cloud-life-sciences", + "extra-files": [ + "google/cloud/lifesciences/gapic_version.py", + "google/cloud/lifesciences_v2beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.lifesciences.v2beta.json", + "type": "json" + } + ] + }, + "packages/google-cloud-locationfinder": { + "component": "google-cloud-locationfinder", + "extra-files": [ + "google/cloud/locationfinder/gapic_version.py", + "google/cloud/locationfinder_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.locationfinder.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-logging": { + "component": "google-cloud-logging", + "extra-files": [ + "google/cloud/logging/gapic_version.py", + "google/cloud/logging_v2/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.logging.v2.json", + "type": "json" + } + ] + }, + "packages/google-cloud-lustre": { + "component": "google-cloud-lustre", + "extra-files": [ + "google/cloud/lustre/gapic_version.py", + "google/cloud/lustre_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.lustre.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-maintenance-api": { + "component": "google-cloud-maintenance-api", + "extra-files": [ + "google/cloud/maintenance_api/gapic_version.py", + "google/cloud/maintenance_api_v1/gapic_version.py", + "google/cloud/maintenance_api_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.maintenance.api.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.maintenance.api.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-cloud-managed-identities": { + "component": "google-cloud-managed-identities", + "extra-files": [ + "google/cloud/managedidentities/gapic_version.py", + "google/cloud/managedidentities_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.managedidentities.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-managedkafka": { + "component": "google-cloud-managedkafka", + "extra-files": [ + "google/cloud/managedkafka/gapic_version.py", + "google/cloud/managedkafka_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.managedkafka.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-managedkafka-schemaregistry": { + "component": "google-cloud-managedkafka-schemaregistry", + "extra-files": [ + "google/cloud/managedkafka_schemaregistry/gapic_version.py", + "google/cloud/managedkafka_schemaregistry_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.managedkafka.schemaregistry.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-media-translation": { + "component": "google-cloud-media-translation", + "extra-files": [ + "google/cloud/mediatranslation/gapic_version.py", + "google/cloud/mediatranslation_v1beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.mediatranslation.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-memcache": { + "component": "google-cloud-memcache", + "extra-files": [ + "google/cloud/memcache/gapic_version.py", + "google/cloud/memcache_v1/gapic_version.py", + "google/cloud/memcache_v1beta2/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.memcache.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.memcache.v1beta2.json", + "type": "json" + } + ] + }, + "packages/google-cloud-memorystore": { + "component": "google-cloud-memorystore", + "extra-files": [ + "google/cloud/memorystore/gapic_version.py", + "google/cloud/memorystore_v1/gapic_version.py", + "google/cloud/memorystore_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.memorystore.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.memorystore.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-cloud-migrationcenter": { + "component": "google-cloud-migrationcenter", + "extra-files": [ + "google/cloud/migrationcenter/gapic_version.py", + "google/cloud/migrationcenter_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.migrationcenter.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-modelarmor": { + "component": "google-cloud-modelarmor", + "extra-files": [ + "google/cloud/modelarmor/gapic_version.py", + "google/cloud/modelarmor_v1/gapic_version.py", + "google/cloud/modelarmor_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.modelarmor.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.modelarmor.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-cloud-monitoring": { + "component": "google-cloud-monitoring", + "extra-files": [ + "google/cloud/monitoring/gapic_version.py", + "google/cloud/monitoring_v3/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.monitoring.v3.json", + "type": "json" + } + ] + }, + "packages/google-cloud-monitoring-dashboards": { + "component": "google-cloud-monitoring-dashboards", + "extra-files": [ + "google/cloud/monitoring_dashboard/gapic_version.py", + "google/cloud/monitoring_dashboard_v1/gapic_version.py", + "google/monitoring/dashboard_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.monitoring.dashboard.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-monitoring-metrics-scopes": { + "component": "google-cloud-monitoring-metrics-scopes", + "extra-files": [ + "google/cloud/monitoring_metrics_scope/gapic_version.py", + "google/cloud/monitoring_metrics_scope_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.monitoring.metricsscope.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-ndb": { + "component": "google-cloud-ndb" + }, + "packages/google-cloud-netapp": { + "component": "google-cloud-netapp", + "extra-files": [ + "google/cloud/netapp/gapic_version.py", + "google/cloud/netapp_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.netapp.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-network-connectivity": { + "component": "google-cloud-network-connectivity", + "extra-files": [ + "google/cloud/networkconnectivity/gapic_version.py", + "google/cloud/networkconnectivity_v1/gapic_version.py", + "google/cloud/networkconnectivity_v1alpha1/gapic_version.py", + "google/cloud/networkconnectivity_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.networkconnectivity.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.networkconnectivity.v1alpha1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.networkconnectivity.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-cloud-network-management": { + "component": "google-cloud-network-management", + "extra-files": [ + "google/cloud/network_management/gapic_version.py", + "google/cloud/network_management_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.networkmanagement.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-network-security": { + "component": "google-cloud-network-security", + "extra-files": [ + "google/cloud/network_security/gapic_version.py", + "google/cloud/network_security_v1/gapic_version.py", + "google/cloud/network_security_v1alpha1/gapic_version.py", + "google/cloud/network_security_v1beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.networksecurity.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.networksecurity.v1alpha1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.networksecurity.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-network-services": { + "component": "google-cloud-network-services", + "extra-files": [ + "google/cloud/network_services/gapic_version.py", + "google/cloud/network_services_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.networkservices.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-notebooks": { + "component": "google-cloud-notebooks", + "extra-files": [ + "google/cloud/notebooks/gapic_version.py", + "google/cloud/notebooks_v1/gapic_version.py", + "google/cloud/notebooks_v1beta1/gapic_version.py", + "google/cloud/notebooks_v2/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.notebooks.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.notebooks.v1beta1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.notebooks.v2.json", + "type": "json" + } + ] + }, + "packages/google-cloud-optimization": { + "component": "google-cloud-optimization", + "extra-files": [ + "google/cloud/optimization/gapic_version.py", + "google/cloud/optimization_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.optimization.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-oracledatabase": { + "component": "google-cloud-oracledatabase", + "extra-files": [ + "google/cloud/oracledatabase/gapic_version.py", + "google/cloud/oracledatabase_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.oracledatabase.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-orchestration-airflow": { + "component": "google-cloud-orchestration-airflow", + "extra-files": [ + "google/cloud/orchestration/airflow/service/gapic_version.py", + "google/cloud/orchestration/airflow/service_v1/gapic_version.py", + "google/cloud/orchestration/airflow/service_v1beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.orchestration.airflow.service.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.orchestration.airflow.service.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-org-policy": { + "component": "google-cloud-org-policy", + "extra-files": [ + "google/cloud/orgpolicy/gapic_version.py", + "google/cloud/orgpolicy_v2/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.orgpolicy.v2.json", + "type": "json" + } + ] + }, + "packages/google-cloud-os-config": { + "component": "google-cloud-os-config", + "extra-files": [ + "google/cloud/osconfig/gapic_version.py", + "google/cloud/osconfig_v1/gapic_version.py", + "google/cloud/osconfig_v1alpha/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.osconfig.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.osconfig.v1alpha.json", + "type": "json" + } + ] + }, + "packages/google-cloud-os-login": { + "component": "google-cloud-os-login", + "extra-files": [ + "google/cloud/oslogin/gapic_version.py", + "google/cloud/oslogin_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.oslogin.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-parallelstore": { + "component": "google-cloud-parallelstore", + "extra-files": [ + "google/cloud/parallelstore/gapic_version.py", + "google/cloud/parallelstore_v1/gapic_version.py", + "google/cloud/parallelstore_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.parallelstore.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.parallelstore.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-cloud-parametermanager": { + "component": "google-cloud-parametermanager", + "extra-files": [ + "google/cloud/parametermanager/gapic_version.py", + "google/cloud/parametermanager_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.parametermanager.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-phishing-protection": { + "component": "google-cloud-phishing-protection", + "extra-files": [ + "google/cloud/phishingprotection/gapic_version.py", + "google/cloud/phishingprotection_v1beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.phishingprotection.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-policy-troubleshooter": { + "component": "google-cloud-policy-troubleshooter", + "extra-files": [ + "google/cloud/policytroubleshooter/gapic_version.py", + "google/cloud/policytroubleshooter_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.policytroubleshooter.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-policysimulator": { + "component": "google-cloud-policysimulator", + "extra-files": [ + "google/cloud/policysimulator/gapic_version.py", + "google/cloud/policysimulator_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.policysimulator.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-policytroubleshooter-iam": { + "component": "google-cloud-policytroubleshooter-iam", + "extra-files": [ + "google/cloud/policytroubleshooter_iam/gapic_version.py", + "google/cloud/policytroubleshooter_iam_v3/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.policytroubleshooter.iam.v3.json", + "type": "json" + } + ] + }, + "packages/google-cloud-private-ca": { + "component": "google-cloud-private-ca", + "extra-files": [ + "google/cloud/security/privateca/gapic_version.py", + "google/cloud/security/privateca_v1/gapic_version.py", + "google/cloud/security/privateca_v1beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.security.privateca.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.security.privateca.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-private-catalog": { + "component": "google-cloud-private-catalog", + "extra-files": [ + "google/cloud/privatecatalog/gapic_version.py", + "google/cloud/privatecatalog_v1beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.privatecatalog.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-privilegedaccessmanager": { + "component": "google-cloud-privilegedaccessmanager", + "extra-files": [ + "google/cloud/privilegedaccessmanager/gapic_version.py", + "google/cloud/privilegedaccessmanager_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.privilegedaccessmanager.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-pubsub": { + "component": "google-cloud-pubsub", + "extra-files": [ + "google/pubsub/gapic_version.py", + "google/pubsub_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.pubsub.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-quotas": { + "component": "google-cloud-quotas", + "extra-files": [ + "google/cloud/cloudquotas/gapic_version.py", + "google/cloud/cloudquotas_v1/gapic_version.py", + "google/cloud/cloudquotas_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.api.cloudquotas.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.api.cloudquotas.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-cloud-rapidmigrationassessment": { + "component": "google-cloud-rapidmigrationassessment", + "extra-files": [ + "google/cloud/rapidmigrationassessment/gapic_version.py", + "google/cloud/rapidmigrationassessment_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.rapidmigrationassessment.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-recaptcha-enterprise": { + "component": "google-cloud-recaptcha-enterprise", + "extra-files": [ + "google/cloud/recaptchaenterprise/gapic_version.py", + "google/cloud/recaptchaenterprise_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.recaptchaenterprise.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-recommendations-ai": { + "component": "google-cloud-recommendations-ai", + "extra-files": [ + "google/cloud/recommendationengine/gapic_version.py", + "google/cloud/recommendationengine_v1beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.recommendationengine.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-recommender": { + "component": "google-cloud-recommender", + "extra-files": [ + "google/cloud/recommender/gapic_version.py", + "google/cloud/recommender_v1/gapic_version.py", + "google/cloud/recommender_v1beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.recommender.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.recommender.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-redis": { + "component": "google-cloud-redis", + "extra-files": [ + "google/cloud/redis/gapic_version.py", + "google/cloud/redis_v1/gapic_version.py", + "google/cloud/redis_v1beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.redis.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.redis.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-redis-cluster": { + "component": "google-cloud-redis-cluster", + "extra-files": [ + "google/cloud/redis_cluster/gapic_version.py", + "google/cloud/redis_cluster_v1/gapic_version.py", + "google/cloud/redis_cluster_v1beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.redis.cluster.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.redis.cluster.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-resource-manager": { + "component": "google-cloud-resource-manager", + "extra-files": [ + "google/cloud/resourcemanager/gapic_version.py", + "google/cloud/resourcemanager_v3/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.resourcemanager.v3.json", + "type": "json" + } + ] + }, + "packages/google-cloud-retail": { + "component": "google-cloud-retail", + "extra-files": [ + "google/cloud/retail/gapic_version.py", + "google/cloud/retail_v2/gapic_version.py", + "google/cloud/retail_v2alpha/gapic_version.py", + "google/cloud/retail_v2beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.retail.v2.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.retail.v2alpha.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.retail.v2beta.json", + "type": "json" + } + ] + }, + "packages/google-cloud-run": { + "component": "google-cloud-run", + "extra-files": [ + "google/cloud/run/gapic_version.py", + "google/cloud/run_v2/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.run.v2.json", + "type": "json" + } + ] + }, + "packages/google-cloud-runtimeconfig": { + "component": "google-cloud-runtimeconfig" + }, + "packages/google-cloud-saasplatform-saasservicemgmt": { + "component": "google-cloud-saasplatform-saasservicemgmt", + "extra-files": [ + "google/cloud/saasplatform_saasservicemgmt/gapic_version.py", + "google/cloud/saasplatform_saasservicemgmt_v1beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.saasplatform.saasservicemgmt.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-scheduler": { + "component": "google-cloud-scheduler", + "extra-files": [ + "google/cloud/scheduler/gapic_version.py", + "google/cloud/scheduler_v1/gapic_version.py", + "google/cloud/scheduler_v1beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.scheduler.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.scheduler.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-secret-manager": { + "component": "google-cloud-secret-manager", + "extra-files": [ + "google/cloud/secretmanager/gapic_version.py", + "google/cloud/secretmanager_v1/gapic_version.py", + "google/cloud/secretmanager_v1beta1/gapic_version.py", + "google/cloud/secretmanager_v1beta2/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.secretmanager.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.secretmanager.v1beta2.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.secrets.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-securesourcemanager": { + "component": "google-cloud-securesourcemanager", + "extra-files": [ + "google/cloud/securesourcemanager/gapic_version.py", + "google/cloud/securesourcemanager_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.securesourcemanager.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-security-publicca": { + "component": "google-cloud-security-publicca", + "extra-files": [ + "google/cloud/security/publicca/gapic_version.py", + "google/cloud/security/publicca_v1/gapic_version.py", + "google/cloud/security/publicca_v1beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.security.publicca.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.security.publicca.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-securitycenter": { + "component": "google-cloud-securitycenter", + "extra-files": [ + "google/cloud/securitycenter/gapic_version.py", + "google/cloud/securitycenter_v1/gapic_version.py", + "google/cloud/securitycenter_v1beta1/gapic_version.py", + "google/cloud/securitycenter_v1p1beta1/gapic_version.py", + "google/cloud/securitycenter_v2/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v1beta1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v1p1beta1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v2.json", + "type": "json" + } + ] + }, + "packages/google-cloud-securitycentermanagement": { + "component": "google-cloud-securitycentermanagement", + "extra-files": [ + "google/cloud/securitycentermanagement/gapic_version.py", + "google/cloud/securitycentermanagement_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.securitycentermanagement.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-service-control": { + "component": "google-cloud-service-control", + "extra-files": [ + "google/cloud/servicecontrol/gapic_version.py", + "google/cloud/servicecontrol_v1/gapic_version.py", + "google/cloud/servicecontrol_v2/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.api.servicecontrol.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.api.servicecontrol.v2.json", + "type": "json" + } + ] + }, + "packages/google-cloud-service-directory": { + "component": "google-cloud-service-directory", + "extra-files": [ + "google/cloud/servicedirectory/gapic_version.py", + "google/cloud/servicedirectory_v1/gapic_version.py", + "google/cloud/servicedirectory_v1beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.servicedirectory.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.servicedirectory.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-service-management": { + "component": "google-cloud-service-management", + "extra-files": [ + "google/cloud/servicemanagement/gapic_version.py", + "google/cloud/servicemanagement_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.api.servicemanagement.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-service-usage": { + "component": "google-cloud-service-usage", + "extra-files": [ + "google/cloud/service_usage/gapic_version.py", + "google/cloud/service_usage_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.api.serviceusage.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-servicehealth": { + "component": "google-cloud-servicehealth", + "extra-files": [ + "google/cloud/servicehealth/gapic_version.py", + "google/cloud/servicehealth_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.servicehealth.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-shell": { + "component": "google-cloud-shell", + "extra-files": [ + "google/cloud/shell/gapic_version.py", + "google/cloud/shell_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.shell.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-source-context": { + "component": "google-cloud-source-context", + "extra-files": [ + "google/cloud/source_context/gapic_version.py", + "google/cloud/source_context_v1/gapic_version.py" + ] + }, + "packages/google-cloud-spanner": { + "component": "google-cloud-spanner", + "extra-files": [ + "google/cloud/spanner/gapic_version.py", + "google/cloud/spanner_admin_database/gapic_version.py", + "google/cloud/spanner_admin_database_v1/gapic_version.py", + "google/cloud/spanner_admin_instance/gapic_version.py", + "google/cloud/spanner_admin_instance_v1/gapic_version.py", + "google/cloud/spanner_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.spanner.admin.database.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.spanner.admin.instance.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.spanner.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-speech": { + "component": "google-cloud-speech", + "extra-files": [ + "google/cloud/speech/gapic_version.py", + "google/cloud/speech_v1/gapic_version.py", + "google/cloud/speech_v1p1beta1/gapic_version.py", + "google/cloud/speech_v2/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.speech.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.speech.v1p1beta1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.speech.v2.json", + "type": "json" + } + ] + }, + "packages/google-cloud-storage": { + "component": "google-cloud-storage", + "extra-files": [ + "google/cloud/_storage/gapic_version.py", + "google/cloud/_storage_v2/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.storage.v2.json", + "type": "json" + } + ] + }, + "packages/google-cloud-storage-control": { + "component": "google-cloud-storage-control", + "extra-files": [ + "google/cloud/storage_control/gapic_version.py", + "google/cloud/storage_control_v2/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.storage.control.v2.json", + "type": "json" + } + ] + }, + "packages/google-cloud-storage-transfer": { + "component": "google-cloud-storage-transfer", + "extra-files": [ + "google/cloud/storage_transfer/gapic_version.py", + "google/cloud/storage_transfer_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.storagetransfer.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-storagebatchoperations": { + "component": "google-cloud-storagebatchoperations", + "extra-files": [ + "google/cloud/storagebatchoperations/gapic_version.py", + "google/cloud/storagebatchoperations_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.storagebatchoperations.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-storageinsights": { + "component": "google-cloud-storageinsights", + "extra-files": [ + "google/cloud/storageinsights/gapic_version.py", + "google/cloud/storageinsights_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.storageinsights.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-support": { + "component": "google-cloud-support", + "extra-files": [ + "google/cloud/support/gapic_version.py", + "google/cloud/support_v2/gapic_version.py", + "google/cloud/support_v2beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.support.v2.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.support.v2beta.json", + "type": "json" + } + ] + }, + "packages/google-cloud-talent": { + "component": "google-cloud-talent", + "extra-files": [ + "google/cloud/talent/gapic_version.py", + "google/cloud/talent_v4/gapic_version.py", + "google/cloud/talent_v4beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.talent.v4.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.talent.v4beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-tasks": { + "component": "google-cloud-tasks", + "extra-files": [ + "google/cloud/tasks/gapic_version.py", + "google/cloud/tasks_v2/gapic_version.py", + "google/cloud/tasks_v2beta2/gapic_version.py", + "google/cloud/tasks_v2beta3/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.tasks.v2.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.tasks.v2beta2.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.tasks.v2beta3.json", + "type": "json" + } + ] + }, + "packages/google-cloud-telcoautomation": { + "component": "google-cloud-telcoautomation", + "extra-files": [ + "google/cloud/telcoautomation/gapic_version.py", + "google/cloud/telcoautomation_v1/gapic_version.py", + "google/cloud/telcoautomation_v1alpha1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.telcoautomation.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.telcoautomation.v1alpha1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-testutils": { + "component": "google-cloud-testutils" + }, + "packages/google-cloud-texttospeech": { + "component": "google-cloud-texttospeech", + "extra-files": [ + "google/cloud/texttospeech/gapic_version.py", + "google/cloud/texttospeech_v1/gapic_version.py", + "google/cloud/texttospeech_v1beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.texttospeech.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.texttospeech.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-tpu": { + "component": "google-cloud-tpu", + "extra-files": [ + "google/cloud/tpu/gapic_version.py", + "google/cloud/tpu_v1/gapic_version.py", + "google/cloud/tpu_v2/gapic_version.py", + "google/cloud/tpu_v2alpha1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.tpu.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.tpu.v2.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.tpu.v2alpha1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-trace": { + "component": "google-cloud-trace", + "extra-files": [ + "google/cloud/trace/gapic_version.py", + "google/cloud/trace_v1/gapic_version.py", + "google/cloud/trace_v2/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.devtools.cloudtrace.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.devtools.cloudtrace.v2.json", + "type": "json" + } + ] + }, + "packages/google-cloud-translate": { + "component": "google-cloud-translate", + "extra-files": [ + "google/cloud/translate/gapic_version.py", + "google/cloud/translate_v3/gapic_version.py", + "google/cloud/translate_v3beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.translation.v3.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.translation.v3beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-vectorsearch": { + "component": "google-cloud-vectorsearch", + "extra-files": [ + "google/cloud/vectorsearch/gapic_version.py", + "google/cloud/vectorsearch_v1/gapic_version.py", + "google/cloud/vectorsearch_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.vectorsearch.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.vectorsearch.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-cloud-video-live-stream": { + "component": "google-cloud-video-live-stream", + "extra-files": [ + "google/cloud/video/live_stream/gapic_version.py", + "google/cloud/video/live_stream_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.video.livestream.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-video-stitcher": { + "component": "google-cloud-video-stitcher", + "extra-files": [ + "google/cloud/video/stitcher/gapic_version.py", + "google/cloud/video/stitcher_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.video.stitcher.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-video-transcoder": { + "component": "google-cloud-video-transcoder", + "extra-files": [ + "google/cloud/video/transcoder/gapic_version.py", + "google/cloud/video/transcoder_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.video.transcoder.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-videointelligence": { + "component": "google-cloud-videointelligence", + "extra-files": [ + "google/cloud/videointelligence/gapic_version.py", + "google/cloud/videointelligence_v1/gapic_version.py", + "google/cloud/videointelligence_v1beta2/gapic_version.py", + "google/cloud/videointelligence_v1p1beta1/gapic_version.py", + "google/cloud/videointelligence_v1p2beta1/gapic_version.py", + "google/cloud/videointelligence_v1p3beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.videointelligence.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.videointelligence.v1beta2.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.videointelligence.v1p1beta1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.videointelligence.v1p2beta1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.videointelligence.v1p3beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-vision": { + "component": "google-cloud-vision", + "extra-files": [ + "google/cloud/vision/gapic_version.py", + "google/cloud/vision_v1/gapic_version.py", + "google/cloud/vision_v1p1beta1/gapic_version.py", + "google/cloud/vision_v1p2beta1/gapic_version.py", + "google/cloud/vision_v1p3beta1/gapic_version.py", + "google/cloud/vision_v1p4beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.vision.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.vision.v1p1beta1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.vision.v1p2beta1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.vision.v1p3beta1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.vision.v1p4beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-visionai": { + "component": "google-cloud-visionai", + "extra-files": [ + "google/cloud/visionai/gapic_version.py", + "google/cloud/visionai_v1/gapic_version.py", + "google/cloud/visionai_v1alpha1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.visionai.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.visionai.v1alpha1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-vm-migration": { + "component": "google-cloud-vm-migration", + "extra-files": [ + "google/cloud/vmmigration/gapic_version.py", + "google/cloud/vmmigration_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.vmmigration.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-vmwareengine": { + "component": "google-cloud-vmwareengine", + "extra-files": [ + "google/cloud/vmwareengine/gapic_version.py", + "google/cloud/vmwareengine_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.vmwareengine.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-vpc-access": { + "component": "google-cloud-vpc-access", + "extra-files": [ + "google/cloud/vpcaccess/gapic_version.py", + "google/cloud/vpcaccess_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.vpcaccess.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-webrisk": { + "component": "google-cloud-webrisk", + "extra-files": [ + "google/cloud/webrisk/gapic_version.py", + "google/cloud/webrisk_v1/gapic_version.py", + "google/cloud/webrisk_v1beta1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.webrisk.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.webrisk.v1beta1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-websecurityscanner": { + "component": "google-cloud-websecurityscanner", + "extra-files": [ + "google/cloud/websecurityscanner/gapic_version.py", + "google/cloud/websecurityscanner_v1/gapic_version.py", + "google/cloud/websecurityscanner_v1alpha/gapic_version.py", + "google/cloud/websecurityscanner_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.websecurityscanner.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.websecurityscanner.v1alpha.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.websecurityscanner.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-cloud-workflows": { + "component": "google-cloud-workflows", + "extra-files": [ + "google/cloud/workflows/executions/gapic_version.py", + "google/cloud/workflows/executions_v1/gapic_version.py", + "google/cloud/workflows/executions_v1beta/gapic_version.py", + "google/cloud/workflows/gapic_version.py", + "google/cloud/workflows_v1/gapic_version.py", + "google/cloud/workflows_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.workflows.executions.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.workflows.executions.v1beta.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.workflows.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.workflows.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-cloud-workloadmanager": { + "component": "google-cloud-workloadmanager", + "extra-files": [ + "google/cloud/workloadmanager/gapic_version.py", + "google/cloud/workloadmanager_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.workloadmanager.v1.json", + "type": "json" + } + ] + }, + "packages/google-cloud-workstations": { + "component": "google-cloud-workstations", + "extra-files": [ + "google/cloud/workstations/gapic_version.py", + "google/cloud/workstations_v1/gapic_version.py", + "google/cloud/workstations_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.workstations.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.workstations.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-developer-knowledge": { + "component": "google-developer-knowledge", + "extra-files": [ + "google/developer_knowledge/gapic_version.py", + "google/developer_knowledge_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.developers.knowledge.v1.json", + "type": "json" + } + ] + }, + "packages/google-devicesandservices-health": { + "component": "google-devicesandservices-health", + "extra-files": [ + "google/devicesandservices/health/gapic_version.py", + "google/devicesandservices/health_v4/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.devicesandservices.health.v4.json", + "type": "json" + } + ] + }, + "packages/google-geo-type": { + "component": "google-geo-type", + "extra-files": [ + "google/geo/type/gapic_version.py" + ] + }, + "packages/google-maps-addressvalidation": { + "component": "google-maps-addressvalidation", + "extra-files": [ + "google/maps/addressvalidation/gapic_version.py", + "google/maps/addressvalidation_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.maps.addressvalidation.v1.json", + "type": "json" + } + ] + }, + "packages/google-maps-areainsights": { + "component": "google-maps-areainsights", + "extra-files": [ + "google/maps/areainsights/gapic_version.py", + "google/maps/areainsights_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.maps.areainsights.v1.json", + "type": "json" + } + ] + }, + "packages/google-maps-fleetengine": { + "component": "google-maps-fleetengine", + "extra-files": [ + "google/maps/fleetengine/gapic_version.py", + "google/maps/fleetengine_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_maps.fleetengine.v1.json", + "type": "json" + } + ] + }, + "packages/google-maps-fleetengine-delivery": { + "component": "google-maps-fleetengine-delivery", + "extra-files": [ + "google/maps/fleetengine_delivery/gapic_version.py", + "google/maps/fleetengine_delivery_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_maps.fleetengine.delivery.v1.json", + "type": "json" + } + ] + }, + "packages/google-maps-geocode": { + "component": "google-maps-geocode", + "extra-files": [ + "google/maps/geocode/gapic_version.py", + "google/maps/geocode_v4/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.maps.geocode.v4.json", + "type": "json" + } + ] + }, + "packages/google-maps-mapmanagement": { + "component": "google-maps-mapmanagement", + "extra-files": [ + "google/maps/mapmanagement/gapic_version.py", + "google/maps/mapmanagement_v2beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.maps.mapmanagement.v2beta.json", + "type": "json" + } + ] + }, + "packages/google-maps-mapsplatformdatasets": { + "component": "google-maps-mapsplatformdatasets", + "extra-files": [ + "google/maps/mapsplatformdatasets/gapic_version.py", + "google/maps/mapsplatformdatasets_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.maps.mapsplatformdatasets.v1.json", + "type": "json" + } + ] + }, + "packages/google-maps-navconnect": { + "component": "google-maps-navconnect", + "extra-files": [ + "google/maps/navconnect/gapic_version.py", + "google/maps/navconnect_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.maps.navconnect.v1.json", + "type": "json" + } + ] + }, + "packages/google-maps-places": { + "component": "google-maps-places", + "extra-files": [ + "google/maps/places/gapic_version.py", + "google/maps/places_v1/gapic_version.py" + ] + }, + "packages/google-maps-routeoptimization": { + "component": "google-maps-routeoptimization", + "extra-files": [ + "google/maps/routeoptimization/gapic_version.py", + "google/maps/routeoptimization_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.maps.routeoptimization.v1.json", + "type": "json" + } + ] + }, + "packages/google-maps-routing": { + "component": "google-maps-routing", + "extra-files": [ + "google/maps/routing/gapic_version.py", + "google/maps/routing_v2/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.maps.routing.v2.json", + "type": "json" + } + ] + }, + "packages/google-maps-solar": { + "component": "google-maps-solar", + "extra-files": [ + "google/maps/solar/gapic_version.py", + "google/maps/solar_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.maps.solar.v1.json", + "type": "json" + } + ] + }, + "packages/google-resumable-media": { + "component": "google-resumable-media" + }, + "packages/google-shopping-css": { + "component": "google-shopping-css", + "extra-files": [ + "google/shopping/css/gapic_version.py", + "google/shopping/css_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.shopping.css.v1.json", + "type": "json" + } + ] + }, + "packages/google-shopping-merchant-accounts": { + "component": "google-shopping-merchant-accounts", + "extra-files": [ + "google/shopping/merchant_accounts/gapic_version.py", + "google/shopping/merchant_accounts_v1/gapic_version.py", + "google/shopping/merchant_accounts_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.shopping.merchant.accounts.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.shopping.merchant.accounts.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-shopping-merchant-conversions": { + "component": "google-shopping-merchant-conversions", + "extra-files": [ + "google/shopping/merchant_conversions/gapic_version.py", + "google/shopping/merchant_conversions_v1/gapic_version.py", + "google/shopping/merchant_conversions_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.shopping.merchant.conversions.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.shopping.merchant.conversions.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-shopping-merchant-datasources": { + "component": "google-shopping-merchant-datasources", + "extra-files": [ + "google/shopping/merchant_datasources/gapic_version.py", + "google/shopping/merchant_datasources_v1/gapic_version.py", + "google/shopping/merchant_datasources_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.shopping.merchant.datasources.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.shopping.merchant.datasources.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-shopping-merchant-inventories": { + "component": "google-shopping-merchant-inventories", + "extra-files": [ + "google/shopping/merchant_inventories/gapic_version.py", + "google/shopping/merchant_inventories_v1/gapic_version.py", + "google/shopping/merchant_inventories_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.shopping.merchant.inventories.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.shopping.merchant.inventories.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-shopping-merchant-issueresolution": { + "component": "google-shopping-merchant-issueresolution", + "extra-files": [ + "google/shopping/merchant_issueresolution/gapic_version.py", + "google/shopping/merchant_issueresolution_v1/gapic_version.py", + "google/shopping/merchant_issueresolution_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.shopping.merchant.issueresolution.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.shopping.merchant.issueresolution.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-shopping-merchant-lfp": { + "component": "google-shopping-merchant-lfp", + "extra-files": [ + "google/shopping/merchant_lfp/gapic_version.py", + "google/shopping/merchant_lfp_v1/gapic_version.py", + "google/shopping/merchant_lfp_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.shopping.merchant.lfp.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.shopping.merchant.lfp.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-shopping-merchant-notifications": { + "component": "google-shopping-merchant-notifications", + "extra-files": [ + "google/shopping/merchant_notifications/gapic_version.py", + "google/shopping/merchant_notifications_v1/gapic_version.py", + "google/shopping/merchant_notifications_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.shopping.merchant.notifications.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.shopping.merchant.notifications.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-shopping-merchant-ordertracking": { + "component": "google-shopping-merchant-ordertracking", + "extra-files": [ + "google/shopping/merchant_ordertracking/gapic_version.py", + "google/shopping/merchant_ordertracking_v1/gapic_version.py", + "google/shopping/merchant_ordertracking_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.shopping.merchant.ordertracking.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.shopping.merchant.ordertracking.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-shopping-merchant-products": { + "component": "google-shopping-merchant-products", + "extra-files": [ + "google/shopping/merchant_products/gapic_version.py", + "google/shopping/merchant_products_v1/gapic_version.py", + "google/shopping/merchant_products_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.shopping.merchant.products.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.shopping.merchant.products.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-shopping-merchant-productstudio": { + "component": "google-shopping-merchant-productstudio", + "extra-files": [ + "google/shopping/merchant_productstudio/gapic_version.py", + "google/shopping/merchant_productstudio_v1alpha/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.shopping.merchant.productstudio.v1alpha.json", + "type": "json" + } + ] + }, + "packages/google-shopping-merchant-promotions": { + "component": "google-shopping-merchant-promotions", + "extra-files": [ + "google/shopping/merchant_promotions/gapic_version.py", + "google/shopping/merchant_promotions_v1/gapic_version.py", + "google/shopping/merchant_promotions_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.shopping.merchant.promotions.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.shopping.merchant.promotions.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-shopping-merchant-quota": { + "component": "google-shopping-merchant-quota", + "extra-files": [ + "google/shopping/merchant_quota/gapic_version.py", + "google/shopping/merchant_quota_v1/gapic_version.py", + "google/shopping/merchant_quota_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.shopping.merchant.quota.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.shopping.merchant.quota.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-shopping-merchant-reports": { + "component": "google-shopping-merchant-reports", + "extra-files": [ + "google/shopping/merchant_reports/gapic_version.py", + "google/shopping/merchant_reports_v1/gapic_version.py", + "google/shopping/merchant_reports_v1alpha/gapic_version.py", + "google/shopping/merchant_reports_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.shopping.merchant.reports.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.shopping.merchant.reports.v1alpha.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.shopping.merchant.reports.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-shopping-merchant-reviews": { + "component": "google-shopping-merchant-reviews", + "extra-files": [ + "google/shopping/merchant_reviews/gapic_version.py", + "google/shopping/merchant_reviews_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.shopping.merchant.reviews.v1beta.json", + "type": "json" + } + ] + }, + "packages/google-shopping-type": { + "component": "google-shopping-type", + "extra-files": [ + "google/shopping/type/gapic_version.py" + ] + }, + "packages/googleapis-common-protos": { + "component": "googleapis-common-protos" + }, + "packages/grafeas": { + "component": "grafeas", + "extra-files": [ + "grafeas/grafeas/gapic_version.py", + "grafeas/grafeas_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_grafeas.v1.json", + "type": "json" + } + ] + }, + "packages/grpc-google-iam-v1": { + "component": "grpc-google-iam-v1" + }, + "packages/proto-plus": { + "component": "proto-plus" + }, + "packages/sqlalchemy-spanner": { + "component": "sqlalchemy-spanner" + } + }, + "release-type": "python-librarian" +} diff --git a/release-please-individual-config.json b/release-please-individual-config.json new file mode 100644 index 000000000000..f61d64328f0c --- /dev/null +++ b/release-please-individual-config.json @@ -0,0 +1,53 @@ +{ + "bump-minor-pre-major": true, + "bump-patch-for-minor-pre-major": true, + "packages": { + "packages/bigframes": { + "component": "bigframes" + }, + "packages/google-cloud-bigtable": { + "component": "google-cloud-bigtable", + "extra-files": [ + "google/cloud/bigtable/gapic_version.py", + "google/cloud/bigtable_admin/gapic_version.py", + "google/cloud/bigtable_admin_v2/gapic_version.py", + "google/cloud/bigtable_v2/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.bigtable.admin.v2.json", + "type": "json" + } + ] + }, + "packages/google-cloud-firestore": { + "component": "google-cloud-firestore", + "extra-files": [ + "google/cloud/firestore/gapic_version.py", + "google/cloud/firestore_admin/gapic_version.py", + "google/cloud/firestore_admin_v1/gapic_version.py", + "google/cloud/firestore_bundle/gapic_version.py", + "google/cloud/firestore_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.firestore.admin.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.firestore.v1.json", + "type": "json" + } + ] + }, + "packages/google-crc32c": { + "component": "google-crc32c" + }, + "packages/pandas-gbq": { + "component": "pandas-gbq" + }, + "packages/sqlalchemy-bigquery": { + "component": "sqlalchemy-bigquery" + } + }, + "release-type": "python-librarian" +} \ No newline at end of file From d3dd06619f8c6a22ef82003c24579b274bba01c1 Mon Sep 17 00:00:00 2001 From: Chalmer Lowe Date: Tue, 16 Jun 2026 11:17:59 -0400 Subject: [PATCH 085/174] chore(version-scanner): split file path in output and format reporting columns (#17476) This pull request polishes the output format of the version_scanner. It splits the scanned file's path into directory and filename columns, and places the dependency and target version columns upfront to help reviewers quickly scan the findings. Key changes: - Adds `file_name`, `dependency`, and `version` columns to the report formats. - Re-orders output columns in CSV and Google Sheets uploads. - Updates unit tests to verify the new column ordering. --- .../tests/unit/test_version_scanner.py | 47 +++++++++++++++---- scripts/version_scanner/version_scanner.py | 37 +++++++++------ 2 files changed, 62 insertions(+), 22 deletions(-) diff --git a/scripts/version_scanner/tests/unit/test_version_scanner.py b/scripts/version_scanner/tests/unit/test_version_scanner.py index f5a909e849e8..f887dfc12fd4 100644 --- a/scripts/version_scanner/tests/unit/test_version_scanner.py +++ b/scripts/version_scanner/tests/unit/test_version_scanner.py @@ -151,7 +151,9 @@ def test_write_csv_report(tmp_path): "rule_name": "python_requires_check", "line_number": 1, "matched_string": "python_requires = '>=3.7'", - "context_line": "python_requires = '>=3.7'" + "context_line": "python_requires = '>=3.7'", + "dependency": "python", + "version": "3.7" } ] @@ -164,11 +166,14 @@ def test_write_csv_report(tmp_path): rows = list(reader) assert len(rows) == 1 + assert rows[0]["file_name"] == "setup.py" assert rows[0]["file_path"] == "./setup.py" assert rows[0]["rule_name"] == "python_requires_check" assert rows[0]["line_number"] == "1" assert rows[0]["matched_string"] == "python_requires = '>=3.7'" assert rows[0]["context_line"] == "python_requires = '>=3.7'" + assert rows[0]["dependency"] == "python" + assert rows[0]["version"] == "3.7" def test_load_config(tmp_path): @@ -227,7 +232,6 @@ def test_main_package_file_permission_error(tmp_path, capsys): package_file = tmp_path / "packages.txt" package_file.write_text("packages/pkg_a") - import sys test_args = ["version_scanner.py", "-d", "python", "-v", "3.7", "--package-file", str(package_file)] real_open = open @@ -246,7 +250,6 @@ def side_effect(file, *args, **kwargs): captured = capsys.readouterr() assert "Error: Permission denied reading package file" in captured.err def test_main_package_file_not_found(capsys): - import sys test_args = ["version_scanner.py", "-d", "python", "-v", "3.7", "--package-file", "non_existent_file.txt"] with patch("sys.argv", test_args): @@ -323,7 +326,6 @@ def test_main_loads_ignore_from_script_dir(mock_scan, mock_load_ignore): mock_load_ignore.return_value = [] mock_scan.return_value = [] - import sys test_args = ["version_scanner.py", "-d", "python", "-v", "3.7"] with mock.patch('sys.argv', test_args): @@ -339,7 +341,8 @@ def test_main_loads_ignore_from_script_dir(mock_scan, mock_load_ignore): try: - import googleapiclient + # Ruff linter F401: Imported solely to detect Google API Client library presence for test skipping + import googleapiclient # noqa: F401 HAS_GOOGLE_API = True except ImportError: HAS_GOOGLE_API = False @@ -392,7 +395,7 @@ def test_upload_to_drive(mock_auth, mock_build): body = kwargs.get('body', {}) values = body.get('values', []) assert len(values) > 1 - assert "HYPERLINK" in values[1][3] # line_number is at index 3 + assert "HYPERLINK" in values[1][6] # line_number is at index 6 def test_regex_examples_from_config(): @@ -638,39 +641,67 @@ def test_format_for_raw_csv_handles_empty_line_number(): def test_format_for_raw_csv(): match = { + "file_name": "setup.py", "file_path": "google-cloud-python/main/packages/pkg_a/setup.py", "repo_path": "packages/pkg_a/setup.py", "package_name": "pkg_a", "rule_name": "python_requires_check", "line_number": "123", "matched_string": "3.7", - "context_line": "python_requires = '>=3.7'" + "context_line": "python_requires = '>=3.7'", + "dependency": "python", + "version": "3.7" } formatted = format_for_raw_csv(match) + assert formatted["file_name"] == "setup.py" assert formatted["file_path"] == "google-cloud-python/main/packages/pkg_a/setup.py" assert formatted["package_name"] == "pkg_a" assert formatted["rule_name"] == "python_requires_check" assert formatted["line_number"] == 123 # Int conversion assert formatted["matched_string"] == "3.7" # No formula wrapping assert formatted["context_line"] == "python_requires = '>=3.7'" + assert formatted["dependency"] == "python" + assert formatted["version"] == "3.7" + +def test_format_for_raw_csv_fallback_filename(): + match = { + "file_path": "google-cloud-python/main/packages/pkg_a/setup.py", + "repo_path": "packages/pkg_a/setup.py", + "package_name": "pkg_a", + "rule_name": "python_requires_check", + "line_number": "123", + "matched_string": "3.7", + "context_line": "python_requires = '>=3.7'", + "dependency": "python", + "version": "3.7" + } + + formatted = format_for_raw_csv(match) + assert formatted["file_name"] == "setup.py" def test_format_for_spreadsheet(): match = { + "file_name": "setup.py", "file_path": "google-cloud-python/main/packages/pkg_a/setup.py", "repo_path": "packages/pkg_a/setup.py", "package_name": "pkg_a", "rule_name": "python_requires_check", "line_number": 123, "matched_string": "3.7", - "context_line": "python_requires = '>=3.7'" + "context_line": "python_requires = '>=3.7'", + "dependency": "python", + "version": "3.7" } # Without github_repo formatted_no_repo = format_for_spreadsheet(match) + assert formatted_no_repo["file_name"] == "setup.py" assert formatted_no_repo["line_number"] == 123 assert formatted_no_repo["matched_string"] == '="3.7"' # Decimal protection formula + assert formatted_no_repo["dependency"] == "python" + assert formatted_no_repo["version"] == "3.7" # With github_repo formatted_repo = format_for_spreadsheet(match, github_repo="https://github.com/user/repo", branch="main") diff --git a/scripts/version_scanner/version_scanner.py b/scripts/version_scanner/version_scanner.py index 90234a967665..484a6eacacae 100644 --- a/scripts/version_scanner/version_scanner.py +++ b/scripts/version_scanner/version_scanner.py @@ -146,7 +146,7 @@ def load_config(self) -> List[Dict[str, str]]: return resolved_rules -def scan_file(file_path: str, compiled_rules: List[Dict[str, re.Pattern]]) -> List[Dict[str, str]]: +def scan_file(file_path: str, compiled_rules: List[Dict[str, re.Pattern]]) -> List[Dict[str, Any]]: """ Scan a single file for matching patterns. @@ -239,23 +239,29 @@ def _safe_int(value: Any, default: int = 0) -> int: return default -def format_for_raw_csv(match: Dict[str, str]) -> Dict[str, str]: +def format_for_raw_csv(match: Dict[str, Any]) -> Dict[str, Any]: """Prepares a full raw dataset (n + x columns) with clean text values.""" + file_name = match.get("file_name") + if not file_name and match.get("file_path"): + file_name = os.path.basename(match.get("file_path")) return { + "file_name": file_name or "", "file_path": match.get("file_path", ""), "package_name": match.get("package_name", ""), "rule_name": match.get("rule_name", ""), "line_number": _safe_int(match.get("line_number")), "matched_string": match.get("matched_string", ""), - "context_line": _truncate_context(match.get("context_line", ""), match.get("matched_string", "")) + "context_line": _truncate_context(match.get("context_line", ""), match.get("matched_string", "")), + "dependency": match.get("dependency", ""), + "version": match.get("version", "") } def format_for_spreadsheet( - match: Dict[str, str], + match: Dict[str, Any], github_repo: str = None, branch: str = "main" -) -> Dict[str, str]: +) -> Dict[str, Any]: """Builds on top of raw CSV but applies Sheets-specific formulas.""" formatted = format_for_raw_csv(match) @@ -270,7 +276,7 @@ def format_for_spreadsheet( return formatted -def format_for_console(match: Dict[str, str]) -> str: +def format_for_console(match: Dict[str, Any]) -> str: """Prepares a slim, readable string representation (n columns) for stdout/logs.""" file_path = match.get("file_path", "") line_number = match.get("line_number", "") @@ -280,7 +286,7 @@ def format_for_console(match: Dict[str, str]) -> str: -def get_match_counts(matches: List[Dict[str, str]]) -> Tuple[Dict[str, int], Dict[str, int]]: +def get_match_counts(matches: List[Dict[str, Any]]) -> Tuple[Dict[str, int], Dict[str, int]]: """ Aggregate matches by rule and by package. """ @@ -333,7 +339,7 @@ def load_ignore_file(file_path: str) -> List[str]: def write_csv_report( output_path: str, - matches: List[Dict[str, str]] + matches: List[Dict[str, Any]] ) -> None: """ Write the collected matches to a CSV file. @@ -342,7 +348,7 @@ def write_csv_report( output_path: Path to the output CSV file. matches: A list of dictionaries containing match details. """ - fieldnames = ["file_path", "package_name", "rule_name", "line_number", "matched_string", "context_line"] + fieldnames = ["file_name", "file_path", "package_name", "rule_name", "dependency", "version", "line_number", "matched_string", "context_line"] try: with open(output_path, 'w', encoding='utf-8', newline='') as f: @@ -360,7 +366,7 @@ def write_csv_report( print(f"Error writing CSV report: {e}", file=sys.stderr) -def upload_to_drive(csv_path: str, matches: List[Dict[str, str]], github_repo: str = None, branch: str = "main") -> str: +def upload_to_drive(csv_path: str, matches: List[Dict[str, Any]], github_repo: str = None, branch: str = "main") -> str: """ Upload matches to a Google Sheet in Drive. """ @@ -391,13 +397,16 @@ def upload_to_drive(csv_path: str, matches: List[Dict[str, str]], github_repo: s spreadsheet_id = spreadsheet.get('spreadsheetId') # Prepare data - values = [["file_path", "package_name", "rule_name", "line_number", "matched_string", "context_line"]] + values = [["file_name", "file_path", "package_name", "rule_name", "dependency", "version", "line_number", "matched_string", "context_line"]] for m in matches: formatted_m = format_for_spreadsheet(m, github_repo=github_repo, branch=branch) values.append([ + formatted_m.get("file_name", ""), formatted_m.get("file_path", ""), formatted_m.get("package_name", ""), formatted_m.get("rule_name", ""), + formatted_m.get("dependency", ""), + formatted_m.get("version", ""), str(formatted_m.get("line_number", "")), formatted_m.get("matched_string", ""), formatted_m.get("context_line", "") @@ -460,7 +469,7 @@ def scan_repository( target_packages: List[str] = None, ignore_dirs: List[str] = None, version_string: str = None -) -> List[Dict[str, str]]: +) -> List[Dict[str, Any]]: """ Scans the repository directory tree applying resolved regex patterns to files. @@ -510,7 +519,6 @@ def scan_repository( files = [f for f in files if f.lower() not in ignore_lower] rel_root = os.path.relpath(root, root_path) - parts = rel_root.split(os.sep) # Layout-agnostic generic subdirectory filtering if target_packages: @@ -559,6 +567,7 @@ def scan_repository( display_path = rel_file_path for m in matches: + m["file_name"] = file m["file_path"] = display_path m["repo_path"] = rel_file_path m["package_name"] = package_name @@ -663,7 +672,7 @@ def main(): print(f"Starting scan for dependency: {args.dependency} version: {args.version}") print(f"Root path: {args.path}") - print(f"Targets to scan:") + print("Targets to scan:") if target_packages: for pkg in target_packages: print(f" - {os.path.join(args.path, pkg)}") From 8ea802da4a721c7a4a9b5729028bd6f299203970 Mon Sep 17 00:00:00 2001 From: Chalmer Lowe Date: Tue, 16 Jun 2026 13:04:14 -0400 Subject: [PATCH 086/174] chore(generator): centralize mypy configuration and regenerate google-cloud-datastore POC (#17408) > [!note] > This is step one of a multi-step process. The work done here is outlined below. Additional steps (to be completed in other PRs) include: > * generate the remaining **generated packages** > * generate and/or post process **hybrid packages** This work: * Adds a centralized `mypy.ini` file at the root of the repository. * Updates GAPIC generator templates to omit local `mypy.ini` and dynamically resolve the root config via a `MYPY_CONFIG_FILE` constant. * Removes `mypy.ini` replacements from `datastore-integration.yaml` post-processing. * Regenerates `google-cloud-datastore` using the updated generator configurations to serve as a proof of concept. > [!note] > Work on strictly handwritten libraries is outside the scope of this PR and can be found here: https://github.com/googleapis/google-cloud-python/pull/17409 --- .../datastore-integration.yaml | 36 ------ mypy.ini | 110 ++++++++++++++++++ .../gapic/ads-templates/mypy.ini.j2 | 3 - .../gapic/ads-templates/noxfile.py.j2 | 7 ++ .../gapic/templates/mypy.ini.j2 | 15 --- .../gapic/templates/noxfile.py.j2 | 3 + .../tests/integration/goldens/asset/mypy.ini | 15 --- .../integration/goldens/asset/noxfile.py | 3 + .../integration/goldens/credentials/mypy.ini | 15 --- .../goldens/credentials/noxfile.py | 3 + .../integration/goldens/eventarc/mypy.ini | 15 --- .../integration/goldens/eventarc/noxfile.py | 3 + .../integration/goldens/logging/mypy.ini | 15 --- .../integration/goldens/logging/noxfile.py | 3 + .../goldens/logging_internal/mypy.ini | 15 --- .../goldens/logging_internal/noxfile.py | 3 + .../tests/integration/goldens/redis/mypy.ini | 15 --- .../integration/goldens/redis/noxfile.py | 3 + .../goldens/redis_selective/mypy.ini | 15 --- .../goldens/redis_selective/noxfile.py | 3 + .../goldens/storagebatchoperations/mypy.ini | 15 --- .../goldens/storagebatchoperations/noxfile.py | 3 + .../cloud/datastore_admin_v1/__init__.py | 8 +- .../google/cloud/datastore_v1/__init__.py | 8 +- packages/google-cloud-datastore/mypy.ini | 23 ---- packages/google-cloud-datastore/noxfile.py | 3 + packages/google-cloud-datastore/setup.py | 12 +- .../testing/constraints-3.10.txt | 6 +- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- 30 files changed, 167 insertions(+), 215 deletions(-) create mode 100644 mypy.ini delete mode 100644 packages/gapic-generator/gapic/ads-templates/mypy.ini.j2 delete mode 100644 packages/gapic-generator/gapic/templates/mypy.ini.j2 delete mode 100755 packages/gapic-generator/tests/integration/goldens/asset/mypy.ini delete mode 100755 packages/gapic-generator/tests/integration/goldens/credentials/mypy.ini delete mode 100755 packages/gapic-generator/tests/integration/goldens/eventarc/mypy.ini delete mode 100755 packages/gapic-generator/tests/integration/goldens/logging/mypy.ini delete mode 100755 packages/gapic-generator/tests/integration/goldens/logging_internal/mypy.ini delete mode 100755 packages/gapic-generator/tests/integration/goldens/redis/mypy.ini delete mode 100755 packages/gapic-generator/tests/integration/goldens/redis_selective/mypy.ini delete mode 100755 packages/gapic-generator/tests/integration/goldens/storagebatchoperations/mypy.ini delete mode 100644 packages/google-cloud-datastore/mypy.ini diff --git a/.librarian/generator-input/client-post-processing/datastore-integration.yaml b/.librarian/generator-input/client-post-processing/datastore-integration.yaml index 7d81275e77c0..aca5e5845036 100644 --- a/.librarian/generator-input/client-post-processing/datastore-integration.yaml +++ b/.librarian/generator-input/client-post-processing/datastore-integration.yaml @@ -39,42 +39,6 @@ replacements: "google-cloud-core >= 2.0.0, <3.0.0", "grpcio >= 1.59.0, < 2.0.0", count: 1 - - paths: [ - "packages/google-cloud-datastore/mypy.ini", - ] - before: |- - # Performance: reuse results from previous runs to speed up 'nox' - incremental = True - after: |- - # Performance: reuse results from previous runs to speed up "nox" - incremental = True - - [mypy-google.cloud.datastore._app_engine_key_pb2] - ignore_errors = True - - # TODO(https://github.com/googleapis/gapic-generator-python/issues/2410): - # Remove once this generator bug is fixed - [mypy-google.cloud.datastore_v1.services.datastore.async_client] - ignore_errors = True - - # TODO(https://github.com/googleapis/gapic-generator-python/issues/2410): - # Remove once this generator bug is fixed - [mypy-google.cloud.datastore_v1.services.datastore.client] - ignore_errors = True - count: 1 - - paths: [ - "packages/google-cloud-datastore/mypy.ini", - ] - before: | - ignore_missing_imports = False - - # TODO\(https://github.com/googleapis/gapic-generator-python/issues/2563\): - # Dependencies that historically lacks py.typed markers - \[mypy-google\.iam\.\*\] - ignore_missing_imports = True - after: | - ignore_missing_imports = True - count: 1 - paths: [ "packages/google-cloud-datastore/docs/index.rst", ] diff --git a/mypy.ini b/mypy.ini new file mode 100644 index 000000000000..9c9bb9d52935 --- /dev/null +++ b/mypy.ini @@ -0,0 +1,110 @@ +[mypy] +namespace_packages = True +ignore_missing_imports = False + +# Helps mypy navigate the "google" namespace more reliably in 3.10+ +explicit_package_bases = True + +# Performance: reuse results from previous runs to speed up "nox" +incremental = True + +exclude = (?x)( + (^|/)third_party/ + | (^|/)tests/unit/resources/ + | (^|/)tests/unit/gapic/ + ) + + +# ============================================================================== +# GLOBAL THIRD-PARTY & SHARED LIBRARY IGNORES +# ============================================================================== + +[mypy-anywidget] +ignore_missing_imports = True + +[mypy-cloudpickle.*] +ignore_missing_imports = True + +[mypy-flask] +ignore_missing_imports = True + +[mypy-google.auth.*] +ignore_missing_imports = True + +[mypy-google.cloud.bigtable] +ignore_missing_imports = True + +[mypy-google.cloud.pubsub] +ignore_missing_imports = True + +[mypy-google.colab] +ignore_missing_imports = True + +[mypy-google.iam.*] +ignore_missing_imports = True + +[mypy-google.longrunning.*] +ignore_missing_imports = True + +[mypy-google.oauth2.*] +ignore_missing_imports = True + +[mypy-google.protobuf.*] +ignore_missing_imports = True + +[mypy-google.rpc.*] +ignore_missing_imports = True + +[mypy-google.type.*] +ignore_missing_imports = True + +[mypy-grpc.*] +ignore_missing_imports = True + +[mypy-ibis.*] +ignore_missing_imports = True + +[mypy-ipywidgets] +ignore_missing_imports = True + +[mypy-proto.*] +ignore_missing_imports = True + +[mypy-pyarrow.*] +ignore_missing_imports = True + +[mypy-pydata_google_auth] +ignore_missing_imports = True + +[mypy-pytest] +ignore_missing_imports = True + +[mypy-pytz] +ignore_missing_imports = True + + +# ============================================================================== +# PACKAGE-SPECIFIC OVERRIDES & EXCEPTIONS +# ============================================================================== + +# --- google-cloud-bigtable --- +[mypy-google.cloud.bigtable.*] +ignore_errors = True + +[mypy-google.cloud.bigtable.data.*] +check_untyped_defs = True +warn_unreachable = True +disallow_any_generics = True +ignore_errors = False + +# --- google-cloud-datastore --- +[mypy-google.cloud.datastore._app_engine_key_pb2] +ignore_errors = True + +# TODO(https://github.com/googleapis/gapic-generator-python/issues/2410): +# Remove once this generator bug is fixed +[mypy-google.cloud.datastore_v1.services.datastore.async_client] +ignore_errors = True + +[mypy-google.cloud.datastore_v1.services.datastore.client] +ignore_errors = True diff --git a/packages/gapic-generator/gapic/ads-templates/mypy.ini.j2 b/packages/gapic-generator/gapic/ads-templates/mypy.ini.j2 deleted file mode 100644 index cb397f571128..000000000000 --- a/packages/gapic-generator/gapic/ads-templates/mypy.ini.j2 +++ /dev/null @@ -1,3 +0,0 @@ -[mypy] -python_version = 3.10 -namespace_packages = True diff --git a/packages/gapic-generator/gapic/ads-templates/noxfile.py.j2 b/packages/gapic-generator/gapic/ads-templates/noxfile.py.j2 index 0a42cd6e4fa0..13b37159d38a 100644 --- a/packages/gapic-generator/gapic/ads-templates/noxfile.py.j2 +++ b/packages/gapic-generator/gapic/ads-templates/noxfile.py.j2 @@ -3,10 +3,16 @@ {% block content %} import os +import pathlib import nox # type: ignore +CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() +# Path to the centralized mypy configuration file at the repository root. +MYPY_CONFIG_FILE = str(CURRENT_DIRECTORY.parent.parent / "mypy.ini") + + # TODO(https://github.com/googleapis/gapic-generator-python/issues/2450): # Add tests for Python 3.15 alpha1 # https://peps.python.org/pep-0790/ @@ -44,6 +50,7 @@ def mypy(session): session.install('.') session.run( 'mypy', + f"--config-file={MYPY_CONFIG_FILE}", {% if api.naming.module_namespace %} '{{ api.naming.module_namespace[0] }}', {% else %} diff --git a/packages/gapic-generator/gapic/templates/mypy.ini.j2 b/packages/gapic-generator/gapic/templates/mypy.ini.j2 deleted file mode 100644 index defc5b1ed854..000000000000 --- a/packages/gapic-generator/gapic/templates/mypy.ini.j2 +++ /dev/null @@ -1,15 +0,0 @@ -[mypy] -python_version = 3.14 -namespace_packages = True -ignore_missing_imports = False - -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): -# Dependencies that historically lacks py.typed markers -[mypy-google.iam.*] -ignore_missing_imports = True - -# Helps mypy navigate the 'google' namespace more reliably in 3.10+ -explicit_package_bases = True - -# Performance: reuse results from previous runs to speed up 'nox' -incremental = True \ No newline at end of file diff --git a/packages/gapic-generator/gapic/templates/noxfile.py.j2 b/packages/gapic-generator/gapic/templates/noxfile.py.j2 index c240871b994e..a11b38f658eb 100644 --- a/packages/gapic-generator/gapic/templates/noxfile.py.j2 +++ b/packages/gapic-generator/gapic/templates/noxfile.py.j2 @@ -40,6 +40,8 @@ DEFAULT_PYTHON_VERSION = "3.14" PREVIEW_PYTHON_VERSION = "3.14" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() +# Path to the centralized mypy configuration file at the repository root. +MYPY_CONFIG_FILE = str(CURRENT_DIRECTORY.parent.parent / "mypy.ini") if (CURRENT_DIRECTORY / "testing").exists(): LOWER_BOUND_CONSTRAINTS_FILE = ( @@ -101,6 +103,7 @@ def mypy(session): session.install(".") session.run( "mypy", + f"--config-file={MYPY_CONFIG_FILE}", "-p", {% if api.naming.module_namespace %} "{{ api.naming.module_namespace[0] }}", diff --git a/packages/gapic-generator/tests/integration/goldens/asset/mypy.ini b/packages/gapic-generator/tests/integration/goldens/asset/mypy.ini deleted file mode 100755 index e0e0da2e9e40..000000000000 --- a/packages/gapic-generator/tests/integration/goldens/asset/mypy.ini +++ /dev/null @@ -1,15 +0,0 @@ -[mypy] -python_version = 3.14 -namespace_packages = True -ignore_missing_imports = False - -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): -# Dependencies that historically lacks py.typed markers -[mypy-google.iam.*] -ignore_missing_imports = True - -# Helps mypy navigate the 'google' namespace more reliably in 3.10+ -explicit_package_bases = True - -# Performance: reuse results from previous runs to speed up 'nox' -incremental = True diff --git a/packages/gapic-generator/tests/integration/goldens/asset/noxfile.py b/packages/gapic-generator/tests/integration/goldens/asset/noxfile.py index 93e185b59d11..bdbc94d16aad 100755 --- a/packages/gapic-generator/tests/integration/goldens/asset/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/asset/noxfile.py @@ -47,6 +47,8 @@ PREVIEW_PYTHON_VERSION = "3.14" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() +# Path to the centralized mypy configuration file at the repository root. +MYPY_CONFIG_FILE = str(CURRENT_DIRECTORY.parent.parent / "mypy.ini") if (CURRENT_DIRECTORY / "testing").exists(): LOWER_BOUND_CONSTRAINTS_FILE = ( @@ -108,6 +110,7 @@ def mypy(session): session.install(".") session.run( "mypy", + f"--config-file={MYPY_CONFIG_FILE}", "-p", "google", "--check-untyped-defs", diff --git a/packages/gapic-generator/tests/integration/goldens/credentials/mypy.ini b/packages/gapic-generator/tests/integration/goldens/credentials/mypy.ini deleted file mode 100755 index e0e0da2e9e40..000000000000 --- a/packages/gapic-generator/tests/integration/goldens/credentials/mypy.ini +++ /dev/null @@ -1,15 +0,0 @@ -[mypy] -python_version = 3.14 -namespace_packages = True -ignore_missing_imports = False - -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): -# Dependencies that historically lacks py.typed markers -[mypy-google.iam.*] -ignore_missing_imports = True - -# Helps mypy navigate the 'google' namespace more reliably in 3.10+ -explicit_package_bases = True - -# Performance: reuse results from previous runs to speed up 'nox' -incremental = True diff --git a/packages/gapic-generator/tests/integration/goldens/credentials/noxfile.py b/packages/gapic-generator/tests/integration/goldens/credentials/noxfile.py index c991842b24ca..dacd23460373 100755 --- a/packages/gapic-generator/tests/integration/goldens/credentials/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/credentials/noxfile.py @@ -47,6 +47,8 @@ PREVIEW_PYTHON_VERSION = "3.14" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() +# Path to the centralized mypy configuration file at the repository root. +MYPY_CONFIG_FILE = str(CURRENT_DIRECTORY.parent.parent / "mypy.ini") if (CURRENT_DIRECTORY / "testing").exists(): LOWER_BOUND_CONSTRAINTS_FILE = ( @@ -108,6 +110,7 @@ def mypy(session): session.install(".") session.run( "mypy", + f"--config-file={MYPY_CONFIG_FILE}", "-p", "google", "--check-untyped-defs", diff --git a/packages/gapic-generator/tests/integration/goldens/eventarc/mypy.ini b/packages/gapic-generator/tests/integration/goldens/eventarc/mypy.ini deleted file mode 100755 index e0e0da2e9e40..000000000000 --- a/packages/gapic-generator/tests/integration/goldens/eventarc/mypy.ini +++ /dev/null @@ -1,15 +0,0 @@ -[mypy] -python_version = 3.14 -namespace_packages = True -ignore_missing_imports = False - -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): -# Dependencies that historically lacks py.typed markers -[mypy-google.iam.*] -ignore_missing_imports = True - -# Helps mypy navigate the 'google' namespace more reliably in 3.10+ -explicit_package_bases = True - -# Performance: reuse results from previous runs to speed up 'nox' -incremental = True diff --git a/packages/gapic-generator/tests/integration/goldens/eventarc/noxfile.py b/packages/gapic-generator/tests/integration/goldens/eventarc/noxfile.py index 1ec5368a9dd4..d950dd9d285b 100755 --- a/packages/gapic-generator/tests/integration/goldens/eventarc/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/eventarc/noxfile.py @@ -47,6 +47,8 @@ PREVIEW_PYTHON_VERSION = "3.14" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() +# Path to the centralized mypy configuration file at the repository root. +MYPY_CONFIG_FILE = str(CURRENT_DIRECTORY.parent.parent / "mypy.ini") if (CURRENT_DIRECTORY / "testing").exists(): LOWER_BOUND_CONSTRAINTS_FILE = ( @@ -108,6 +110,7 @@ def mypy(session): session.install(".") session.run( "mypy", + f"--config-file={MYPY_CONFIG_FILE}", "-p", "google", "--check-untyped-defs", diff --git a/packages/gapic-generator/tests/integration/goldens/logging/mypy.ini b/packages/gapic-generator/tests/integration/goldens/logging/mypy.ini deleted file mode 100755 index e0e0da2e9e40..000000000000 --- a/packages/gapic-generator/tests/integration/goldens/logging/mypy.ini +++ /dev/null @@ -1,15 +0,0 @@ -[mypy] -python_version = 3.14 -namespace_packages = True -ignore_missing_imports = False - -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): -# Dependencies that historically lacks py.typed markers -[mypy-google.iam.*] -ignore_missing_imports = True - -# Helps mypy navigate the 'google' namespace more reliably in 3.10+ -explicit_package_bases = True - -# Performance: reuse results from previous runs to speed up 'nox' -incremental = True diff --git a/packages/gapic-generator/tests/integration/goldens/logging/noxfile.py b/packages/gapic-generator/tests/integration/goldens/logging/noxfile.py index 448aec3ef2b0..7296b5795a8b 100755 --- a/packages/gapic-generator/tests/integration/goldens/logging/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/logging/noxfile.py @@ -47,6 +47,8 @@ PREVIEW_PYTHON_VERSION = "3.14" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() +# Path to the centralized mypy configuration file at the repository root. +MYPY_CONFIG_FILE = str(CURRENT_DIRECTORY.parent.parent / "mypy.ini") if (CURRENT_DIRECTORY / "testing").exists(): LOWER_BOUND_CONSTRAINTS_FILE = ( @@ -108,6 +110,7 @@ def mypy(session): session.install(".") session.run( "mypy", + f"--config-file={MYPY_CONFIG_FILE}", "-p", "google", "--check-untyped-defs", diff --git a/packages/gapic-generator/tests/integration/goldens/logging_internal/mypy.ini b/packages/gapic-generator/tests/integration/goldens/logging_internal/mypy.ini deleted file mode 100755 index e0e0da2e9e40..000000000000 --- a/packages/gapic-generator/tests/integration/goldens/logging_internal/mypy.ini +++ /dev/null @@ -1,15 +0,0 @@ -[mypy] -python_version = 3.14 -namespace_packages = True -ignore_missing_imports = False - -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): -# Dependencies that historically lacks py.typed markers -[mypy-google.iam.*] -ignore_missing_imports = True - -# Helps mypy navigate the 'google' namespace more reliably in 3.10+ -explicit_package_bases = True - -# Performance: reuse results from previous runs to speed up 'nox' -incremental = True diff --git a/packages/gapic-generator/tests/integration/goldens/logging_internal/noxfile.py b/packages/gapic-generator/tests/integration/goldens/logging_internal/noxfile.py index 448aec3ef2b0..7296b5795a8b 100755 --- a/packages/gapic-generator/tests/integration/goldens/logging_internal/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/logging_internal/noxfile.py @@ -47,6 +47,8 @@ PREVIEW_PYTHON_VERSION = "3.14" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() +# Path to the centralized mypy configuration file at the repository root. +MYPY_CONFIG_FILE = str(CURRENT_DIRECTORY.parent.parent / "mypy.ini") if (CURRENT_DIRECTORY / "testing").exists(): LOWER_BOUND_CONSTRAINTS_FILE = ( @@ -108,6 +110,7 @@ def mypy(session): session.install(".") session.run( "mypy", + f"--config-file={MYPY_CONFIG_FILE}", "-p", "google", "--check-untyped-defs", diff --git a/packages/gapic-generator/tests/integration/goldens/redis/mypy.ini b/packages/gapic-generator/tests/integration/goldens/redis/mypy.ini deleted file mode 100755 index e0e0da2e9e40..000000000000 --- a/packages/gapic-generator/tests/integration/goldens/redis/mypy.ini +++ /dev/null @@ -1,15 +0,0 @@ -[mypy] -python_version = 3.14 -namespace_packages = True -ignore_missing_imports = False - -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): -# Dependencies that historically lacks py.typed markers -[mypy-google.iam.*] -ignore_missing_imports = True - -# Helps mypy navigate the 'google' namespace more reliably in 3.10+ -explicit_package_bases = True - -# Performance: reuse results from previous runs to speed up 'nox' -incremental = True diff --git a/packages/gapic-generator/tests/integration/goldens/redis/noxfile.py b/packages/gapic-generator/tests/integration/goldens/redis/noxfile.py index d860093c9653..ca0b6b791d68 100755 --- a/packages/gapic-generator/tests/integration/goldens/redis/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/redis/noxfile.py @@ -47,6 +47,8 @@ PREVIEW_PYTHON_VERSION = "3.14" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() +# Path to the centralized mypy configuration file at the repository root. +MYPY_CONFIG_FILE = str(CURRENT_DIRECTORY.parent.parent / "mypy.ini") if (CURRENT_DIRECTORY / "testing").exists(): LOWER_BOUND_CONSTRAINTS_FILE = ( @@ -108,6 +110,7 @@ def mypy(session): session.install(".") session.run( "mypy", + f"--config-file={MYPY_CONFIG_FILE}", "-p", "google", "--check-untyped-defs", diff --git a/packages/gapic-generator/tests/integration/goldens/redis_selective/mypy.ini b/packages/gapic-generator/tests/integration/goldens/redis_selective/mypy.ini deleted file mode 100755 index e0e0da2e9e40..000000000000 --- a/packages/gapic-generator/tests/integration/goldens/redis_selective/mypy.ini +++ /dev/null @@ -1,15 +0,0 @@ -[mypy] -python_version = 3.14 -namespace_packages = True -ignore_missing_imports = False - -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): -# Dependencies that historically lacks py.typed markers -[mypy-google.iam.*] -ignore_missing_imports = True - -# Helps mypy navigate the 'google' namespace more reliably in 3.10+ -explicit_package_bases = True - -# Performance: reuse results from previous runs to speed up 'nox' -incremental = True diff --git a/packages/gapic-generator/tests/integration/goldens/redis_selective/noxfile.py b/packages/gapic-generator/tests/integration/goldens/redis_selective/noxfile.py index d860093c9653..ca0b6b791d68 100755 --- a/packages/gapic-generator/tests/integration/goldens/redis_selective/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/redis_selective/noxfile.py @@ -47,6 +47,8 @@ PREVIEW_PYTHON_VERSION = "3.14" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() +# Path to the centralized mypy configuration file at the repository root. +MYPY_CONFIG_FILE = str(CURRENT_DIRECTORY.parent.parent / "mypy.ini") if (CURRENT_DIRECTORY / "testing").exists(): LOWER_BOUND_CONSTRAINTS_FILE = ( @@ -108,6 +110,7 @@ def mypy(session): session.install(".") session.run( "mypy", + f"--config-file={MYPY_CONFIG_FILE}", "-p", "google", "--check-untyped-defs", diff --git a/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/mypy.ini b/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/mypy.ini deleted file mode 100755 index e0e0da2e9e40..000000000000 --- a/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/mypy.ini +++ /dev/null @@ -1,15 +0,0 @@ -[mypy] -python_version = 3.14 -namespace_packages = True -ignore_missing_imports = False - -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): -# Dependencies that historically lacks py.typed markers -[mypy-google.iam.*] -ignore_missing_imports = True - -# Helps mypy navigate the 'google' namespace more reliably in 3.10+ -explicit_package_bases = True - -# Performance: reuse results from previous runs to speed up 'nox' -incremental = True diff --git a/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/noxfile.py b/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/noxfile.py index 9afec5aeae68..141088cbacc3 100755 --- a/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/noxfile.py @@ -47,6 +47,8 @@ PREVIEW_PYTHON_VERSION = "3.14" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() +# Path to the centralized mypy configuration file at the repository root. +MYPY_CONFIG_FILE = str(CURRENT_DIRECTORY.parent.parent / "mypy.ini") if (CURRENT_DIRECTORY / "testing").exists(): LOWER_BOUND_CONSTRAINTS_FILE = ( @@ -108,6 +110,7 @@ def mypy(session): session.install(".") session.run( "mypy", + f"--config-file={MYPY_CONFIG_FILE}", "-p", "google", "--check-untyped-defs", diff --git a/packages/google-cloud-datastore/google/cloud/datastore_admin_v1/__init__.py b/packages/google-cloud-datastore/google/cloud/datastore_admin_v1/__init__.py index ab92fd717567..e6209583615b 100644 --- a/packages/google-cloud-datastore/google/cloud/datastore_admin_v1/__init__.py +++ b/packages/google-cloud-datastore/google/cloud/datastore_admin_v1/__init__.py @@ -75,7 +75,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -104,9 +104,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-datastore/google/cloud/datastore_v1/__init__.py b/packages/google-cloud-datastore/google/cloud/datastore_v1/__init__.py index 7e8f2602291d..7017a18c095c 100644 --- a/packages/google-cloud-datastore/google/cloud/datastore_v1/__init__.py +++ b/packages/google-cloud-datastore/google/cloud/datastore_v1/__init__.py @@ -98,7 +98,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -127,9 +127,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-datastore/mypy.ini b/packages/google-cloud-datastore/mypy.ini deleted file mode 100644 index 2d553926db9d..000000000000 --- a/packages/google-cloud-datastore/mypy.ini +++ /dev/null @@ -1,23 +0,0 @@ -[mypy] -python_version = 3.14 -namespace_packages = True -ignore_missing_imports = True - -# Helps mypy navigate the 'google' namespace more reliably in 3.10+ -explicit_package_bases = True - -# Performance: reuse results from previous runs to speed up "nox" -incremental = True - -[mypy-google.cloud.datastore._app_engine_key_pb2] -ignore_errors = True - -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2410): -# Remove once this generator bug is fixed -[mypy-google.cloud.datastore_v1.services.datastore.async_client] -ignore_errors = True - -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2410): -# Remove once this generator bug is fixed -[mypy-google.cloud.datastore_v1.services.datastore.client] -ignore_errors = True diff --git a/packages/google-cloud-datastore/noxfile.py b/packages/google-cloud-datastore/noxfile.py index af42d740478e..9e9c06b33b12 100644 --- a/packages/google-cloud-datastore/noxfile.py +++ b/packages/google-cloud-datastore/noxfile.py @@ -46,6 +46,8 @@ PREVIEW_PYTHON_VERSION = "3.14" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() +# Path to the centralized mypy configuration file at the repository root. +MYPY_CONFIG_FILE = str(CURRENT_DIRECTORY.parent.parent / "mypy.ini") if (CURRENT_DIRECTORY / "testing").exists(): LOWER_BOUND_CONSTRAINTS_FILE = ( @@ -107,6 +109,7 @@ def mypy(session): session.install(".") session.run( "mypy", + f"--config-file={MYPY_CONFIG_FILE}", "-p", "google", # TODO(https://github.com/googleapis/google-cloud-python/issues/16083) diff --git a/packages/google-cloud-datastore/setup.py b/packages/google-cloud-datastore/setup.py index b0cac8c0ec50..26f21974303e 100644 --- a/packages/google-cloud-datastore/setup.py +++ b/packages/google-cloud-datastore/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/datastore/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "google-cloud-core >= 2.0.0, <3.0.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-datastore" diff --git a/packages/google-cloud-datastore/testing/constraints-3.10.txt b/packages/google-cloud-datastore/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-datastore/testing/constraints-3.10.txt +++ b/packages/google-cloud-datastore/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-datastore/testing/constraints-3.13.txt b/packages/google-cloud-datastore/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-datastore/testing/constraints-3.13.txt +++ b/packages/google-cloud-datastore/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-datastore/testing/constraints-3.14.txt b/packages/google-cloud-datastore/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-datastore/testing/constraints-3.14.txt +++ b/packages/google-cloud-datastore/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 From b254faf69fe826c8debd20c5401b072c370c6489 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Tue, 16 Jun 2026 10:08:51 -0700 Subject: [PATCH 087/174] chore(generator): add pyenv3wrapper script (#17483) This file is needed by the bazel build rules. --- packages/gapic-generator/pyenv3wrapper.sh | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 packages/gapic-generator/pyenv3wrapper.sh diff --git a/packages/gapic-generator/pyenv3wrapper.sh b/packages/gapic-generator/pyenv3wrapper.sh new file mode 100644 index 000000000000..54176219f731 --- /dev/null +++ b/packages/gapic-generator/pyenv3wrapper.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +HOME_DIR=$(getent passwd "$(whoami)" | cut -d: -f6) +exec "$HOME_DIR/.pyenv/shims/python3" "$@" From 734302a14fc223e35a709c5003cc12f9458ec8ca Mon Sep 17 00:00:00 2001 From: Shuowei Li Date: Tue, 16 Jun 2026 17:18:56 +0000 Subject: [PATCH 088/174] refactor: rewrite interactive table widget in Angular (#17416) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR rewrites the frontend implementation of the interactive `TableWidget` in Angular, replacing the legacy vanilla JS version (`table_widget.js`). This enables more structured state management and paves the way for future UI improvements. ### Key Changes: 1. **Angular Frontend Rewrite**: - Created a new Angular application workspace under `bigframes/display/table_widget_angular`. - Introduced `WidgetStateService` to manage the widget's internal state (pages, sorting, column visibility) and synchronize updates with the Python `anywidget` model. - Rewrote the template, CSS variables (including VS Code dark mode support), pagination controls, and column sorting handlers as Angular components. - Compiled and bundled the Angular workspace into the single distribution file `table_widget_angular.js`, which is now loaded by the Python class. 2. **Backend Refactoring**: - Renamed `DataFrame._get_display_df` to `_process_display_df` and refactored it to return both the processed display DataFrame and its metadata. - Updated `html.py` to standardize representation rendering pipelines, enabling native rendering support for both `DataFrame` and `Series` objects. 3. **Robust Multi-Instance Bootstrapping**: - Configured the Angular bootstrap sequence to use `createApplication()` and manually attach each component instance to its local widget container (`el`). This prevents rendering conflicts and state bleeding when rendering multiple widgets on the same notebook page. 4. **Testing**: - Added a frontend test suite (`tests/js/table_widget_angular.test.js`) to assert that multiple Angular widgets can bootstrap and render distinct model configurations concurrently. - Updated Python backend unit tests under `tests/unit/display/` to conform to the new `_process_display_df` interface. Verified at: go/scrcast/NTkzNjEzNzYyNDM1NDgxNnw4NTI0NjA5My1iMA screen/4NJKSkYEjoYjpxA Fixes #<505414691> 🦕 --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- packages/bigframes/bigframes/dataframe.py | 2 +- .../bigframes/bigframes/display/anywidget.py | 4 +- packages/bigframes/bigframes/display/html.py | 26 +- .../bigframes/display/table_widget_angular.js | 6201 +++++++++++------ .../display/table_widget_angular/README.md | 66 +- .../table_widget_angular/src/app/app.spec.ts | 4 +- .../table_widget_angular/src/app/app.ts | 527 +- .../src/app/widget-state.service.spec.ts | 128 + .../src/app/widget-state.service.ts | 123 + .../display/table_widget_angular/src/main.ts | 10 +- packages/bigframes/bigframes/series.py | 4 +- .../notebooks/dataframes/anywidget_mode.ipynb | 213 +- .../tests/js/table_widget_angular.test.js | 96 + .../tests/unit/display/test_anywidget.py | 4 +- .../bigframes/tests/unit/display/test_html.py | 4 +- 15 files changed, 4922 insertions(+), 2490 deletions(-) create mode 100644 packages/bigframes/bigframes/display/table_widget_angular/src/app/widget-state.service.spec.ts create mode 100644 packages/bigframes/bigframes/display/table_widget_angular/src/app/widget-state.service.ts create mode 100644 packages/bigframes/tests/js/table_widget_angular.test.js diff --git a/packages/bigframes/bigframes/dataframe.py b/packages/bigframes/bigframes/dataframe.py index 6b7922fe9753..f5fc7bdfc6b1 100644 --- a/packages/bigframes/bigframes/dataframe.py +++ b/packages/bigframes/bigframes/dataframe.py @@ -819,7 +819,7 @@ def __repr__(self) -> str: column_count=len(self.columns), ) - def _get_display_df(self) -> DataFrame: + def _prepare_display_df(self) -> DataFrame: """Process ObjectRef and JSON/nested JSON columns for display.""" df = self # Arrow/Pandas to_pandas_batches does not support raw JSON/nested JSON diff --git a/packages/bigframes/bigframes/display/anywidget.py b/packages/bigframes/bigframes/display/anywidget.py index 08b19d820173..9d547baff842 100644 --- a/packages/bigframes/bigframes/display/anywidget.py +++ b/packages/bigframes/bigframes/display/anywidget.py @@ -175,8 +175,8 @@ def _on_initial_load_complete(self, change: dict[str, Any]): @functools.cached_property def _esm(self): - """Load JavaScript code from external file.""" - return resources.read_text(bigframes.display, "table_widget.js") + """Load JavaScript code from the compiled Angular hybrid bundle.""" + return resources.read_text(bigframes.display, "table_widget_angular.js") @functools.cached_property def _css(self): diff --git a/packages/bigframes/bigframes/display/html.py b/packages/bigframes/bigframes/display/html.py index 56c070d58a4a..c46613d1a84d 100644 --- a/packages/bigframes/bigframes/display/html.py +++ b/packages/bigframes/bigframes/display/html.py @@ -30,7 +30,6 @@ import bigframes.formatting_helpers as formatter from bigframes._config import display_options, options from bigframes.display import plaintext -from bigframes.series import Series if typing.TYPE_CHECKING: import bigframes.dataframe @@ -192,9 +191,11 @@ def create_html_representation( total_columns: int, ) -> str: """Create an HTML representation of the DataFrame or Series.""" + import bigframes.series + opts = options.display with display_options.pandas_repr(opts): - if isinstance(obj, Series): + if isinstance(obj, bigframes.series.Series): pd_series = pandas_df.iloc[:, 0] try: html_string = pd_series._repr_html_() @@ -216,7 +217,9 @@ def create_html_representation( def _get_obj_metadata( obj: Union[bigframes.dataframe.DataFrame, bigframes.series.Series], ) -> tuple[bool, bool]: - is_series = isinstance(obj, Series) + import bigframes.series + + is_series = isinstance(obj, bigframes.series.Series) if is_series: has_index = len(obj._block.index_columns) > 0 else: @@ -233,9 +236,15 @@ def get_anywidget_bundle( Helper method to create and return the anywidget mimebundle. This function encapsulates the logic for anywidget display. """ + import bigframes.series from bigframes import display - df = obj._get_display_df() + if isinstance(obj, bigframes.series.Series): + df = obj.to_frame() + else: + df = obj + + df = df._prepare_display_df() widget = display.TableWidget(df) widget_repr_result = widget._repr_mimebundle_(include=include, exclude=exclude) @@ -283,8 +292,15 @@ def repr_mimebundle_deferred( def repr_mimebundle_head( obj: Union[bigframes.dataframe.DataFrame, bigframes.series.Series], ) -> dict[str, str]: + import bigframes.series + opts = options.display - df = obj._get_display_df() + if isinstance(obj, bigframes.series.Series): + df = obj.to_frame() + else: + df = obj + + df = df._prepare_display_df() pandas_df, row_count, query_job = df._block.retrieve_repr_request_results( opts.max_rows ) diff --git a/packages/bigframes/bigframes/display/table_widget_angular.js b/packages/bigframes/bigframes/display/table_widget_angular.js index 31aaee6ab228..69d2df7eaab1 100644 --- a/packages/bigframes/bigframes/display/table_widget_angular.js +++ b/packages/bigframes/bigframes/display/table_widget_angular.js @@ -16,158 +16,158 @@ // dist/table-widget-angular/browser/main.js -var tl = Object.defineProperty; -var nl = Object.defineProperties; -var rl = Object.getOwnPropertyDescriptors; -var ki = Object.getOwnPropertySymbols; -var ol = Object.prototype.hasOwnProperty; -var il = Object.prototype.propertyIsEnumerable; -var Oi = (e6, t, n) => t in e6 ? tl(e6, t, { enumerable: true, configurable: true, writable: true, value: n }) : e6[t] = n; -var A = (e6, t) => { +var od = Object.defineProperty; +var id = Object.defineProperties; +var sd = Object.getOwnPropertyDescriptors; +var Da = Object.getOwnPropertySymbols; +var ad = Object.prototype.hasOwnProperty; +var cd = Object.prototype.propertyIsEnumerable; +var wa = (e12, t, n) => t in e12 ? od(e12, t, { enumerable: true, configurable: true, writable: true, value: n }) : e12[t] = n; +var N = (e12, t) => { for (var n in t ||= {}) - ol.call(t, n) && Oi(e6, n, t[n]); - if (ki) - for (var n of ki(t)) - il.call(t, n) && Oi(e6, n, t[n]); - return e6; + ad.call(t, n) && wa(e12, n, t[n]); + if (Da) + for (var n of Da(t)) + cd.call(t, n) && wa(e12, n, t[n]); + return e12; }; -var V = (e6, t) => nl(e6, rl(t)); -var b = null; -var zt = false; -var cr = 1; -var sl = null; -var W = Symbol("SIGNAL"); -function v(e6) { - let t = b; - return b = e6, t; -} -function Wt() { - return b; -} -var Gt = { version: 0, lastCleanEpoch: 0, dirty: false, producers: void 0, producersTail: void 0, consumers: void 0, consumersTail: void 0, recomputing: false, consumerAllowSignalWrites: false, consumerIsAlwaysLive: false, kind: "unknown", producerMustRecompute: () => false, producerRecomputeValue: () => { +var A = (e12, t) => id(e12, sd(t)); +var L = null; +var Sn = false; +var yo = 1; +var ld = null; +var Z = Symbol("SIGNAL"); +function g(e12) { + let t = L; + return L = e12, t; +} +function xn() { + return L; +} +var ut = { version: 0, lastCleanEpoch: 0, dirty: false, producers: void 0, producersTail: void 0, consumers: void 0, consumersTail: void 0, recomputing: false, consumerAllowSignalWrites: false, consumerIsAlwaysLive: false, kind: "unknown", producerMustRecompute: () => false, producerRecomputeValue: () => { }, consumerMarkedDirty: () => { }, consumerOnSignalRead: () => { } }; -function Li(e6) { - if (zt) +function vo(e12) { + if (Sn) throw new Error(""); - if (b === null) + if (L === null) return; - b.consumerOnSignalRead(e6); - let t = b.producersTail; - if (t !== void 0 && t.producer === e6) + L.consumerOnSignalRead(e12); + let t = L.producersTail; + if (t !== void 0 && t.producer === e12) return; - let n, r = b.recomputing; - if (r && (n = t !== void 0 ? t.nextProducer : b.producers, n !== void 0 && n.producer === e6)) { - b.producersTail = n, n.lastReadVersion = e6.version; + let n, r = L.recomputing; + if (r && (n = t !== void 0 ? t.nextProducer : L.producers, n !== void 0 && n.producer === e12)) { + L.producersTail = n, n.lastReadVersion = e12.version; return; } - let o = e6.consumersTail; - if (o !== void 0 && o.consumer === b && (!r || cl(o, b))) + let o = e12.consumersTail; + if (o !== void 0 && o.consumer === L && (!r || dd(o, L))) return; - let i = Le(b), s = { producer: e6, consumer: b, nextProducer: n, prevConsumer: o, lastReadVersion: e6.version, nextConsumer: void 0 }; - b.producersTail = s, t !== void 0 ? t.nextProducer = s : b.producers = s, i && Bi(e6, s); + let i = ft(L), s = { producer: e12, consumer: L, nextProducer: n, prevConsumer: o, lastReadVersion: e12.version, nextConsumer: void 0 }; + L.producersTail = s, t !== void 0 ? t.nextProducer = s : L.producers = s, i && Ma(e12, s); } -function Pi() { - cr++; +function Ca() { + yo++; } -function Fi(e6) { - if (!(Le(e6) && !e6.dirty) && !(!e6.dirty && e6.lastCleanEpoch === cr)) { - if (!e6.producerMustRecompute(e6) && !fr(e6)) { - ar(e6); +function Eo(e12) { + if (!(ft(e12) && !e12.dirty) && !(!e12.dirty && e12.lastCleanEpoch === yo)) { + if (!e12.producerMustRecompute(e12) && !Rn(e12)) { + mo(e12); return; } - e6.producerRecomputeValue(e6), ar(e6); + e12.producerRecomputeValue(e12), mo(e12); } } -function lr(e6) { - if (e6.consumers === void 0) +function Io(e12) { + if (e12.consumers === void 0) return; - let t = zt; - zt = true; + let t = Sn; + Sn = true; try { - for (let n = e6.consumers; n !== void 0; n = n.nextConsumer) { + for (let n = e12.consumers; n !== void 0; n = n.nextConsumer) { let r = n.consumer; - r.dirty || al(r); + r.dirty || ud(r); } } finally { - zt = t; + Sn = t; } } -function ur() { - return b?.consumerAllowSignalWrites !== false; +function Do() { + return L?.consumerAllowSignalWrites !== false; } -function al(e6) { - e6.dirty = true, lr(e6), e6.consumerMarkedDirty?.(e6); +function ud(e12) { + e12.dirty = true, Io(e12), e12.consumerMarkedDirty?.(e12); } -function ar(e6) { - e6.dirty = false, e6.lastCleanEpoch = cr; +function mo(e12) { + e12.dirty = false, e12.lastCleanEpoch = yo; } -function dr(e6) { - return e6 && ji(e6), v(e6); +function Bt(e12) { + return e12 && ba(e12), g(e12); } -function ji(e6) { - e6.producersTail = void 0, e6.recomputing = true; +function ba(e12) { + e12.producersTail = void 0, e12.recomputing = true; } -function Hi(e6, t) { - v(t), e6 && Vi(e6); +function An(e12, t) { + g(t), e12 && Ta(e12); } -function Vi(e6) { - e6.recomputing = false; - let t = e6.producersTail, n = t !== void 0 ? t.nextProducer : e6.producers; +function Ta(e12) { + e12.recomputing = false; + let t = e12.producersTail, n = t !== void 0 ? t.nextProducer : e12.producers; if (n !== void 0) { - if (Le(e6)) + if (ft(e12)) do - n = pr(n); + n = wo(n); while (n !== void 0); - t !== void 0 ? t.nextProducer = void 0 : e6.producers = void 0; + t !== void 0 ? t.nextProducer = void 0 : e12.producers = void 0; } } -function fr(e6) { - for (let t = e6.producers; t !== void 0; t = t.nextProducer) { +function Rn(e12) { + for (let t = e12.producers; t !== void 0; t = t.nextProducer) { let n = t.producer, r = t.lastReadVersion; - if (r !== n.version || (Fi(n), r !== n.version)) + if (r !== n.version || (Eo(n), r !== n.version)) return true; } return false; } -function qt(e6) { - if (Le(e6)) { - let t = e6.producers; +function dt(e12) { + if (ft(e12)) { + let t = e12.producers; for (; t !== void 0; ) - t = pr(t); + t = wo(t); } - e6.producers = void 0, e6.producersTail = void 0, e6.consumers = void 0, e6.consumersTail = void 0; + e12.producers = void 0, e12.producersTail = void 0, e12.consumers = void 0, e12.consumersTail = void 0; } -function Bi(e6, t) { - let n = e6.consumersTail, r = Le(e6); - if (n !== void 0 ? (t.nextConsumer = n.nextConsumer, n.nextConsumer = t) : (t.nextConsumer = void 0, e6.consumers = t), t.prevConsumer = n, e6.consumersTail = t, !r) - for (let o = e6.producers; o !== void 0; o = o.nextProducer) - Bi(o.producer, o); +function Ma(e12, t) { + let n = e12.consumersTail, r = ft(e12); + if (n !== void 0 ? (t.nextConsumer = n.nextConsumer, n.nextConsumer = t) : (t.nextConsumer = void 0, e12.consumers = t), t.prevConsumer = n, e12.consumersTail = t, !r) + for (let o = e12.producers; o !== void 0; o = o.nextProducer) + Ma(o.producer, o); } -function pr(e6) { - let t = e6.producer, n = e6.nextProducer, r = e6.nextConsumer, o = e6.prevConsumer; - if (e6.nextConsumer = void 0, e6.prevConsumer = void 0, r !== void 0 ? r.prevConsumer = o : t.consumersTail = o, o !== void 0) +function wo(e12) { + let t = e12.producer, n = e12.nextProducer, r = e12.nextConsumer, o = e12.prevConsumer; + if (e12.nextConsumer = void 0, e12.prevConsumer = void 0, r !== void 0 ? r.prevConsumer = o : t.consumersTail = o, o !== void 0) o.nextConsumer = r; - else if (t.consumers = r, !Le(t)) { + else if (t.consumers = r, !ft(t)) { let i = t.producers; for (; i !== void 0; ) - i = pr(i); + i = wo(i); } return n; } -function Le(e6) { - return e6.consumerIsAlwaysLive || e6.consumers !== void 0; +function ft(e12) { + return e12.consumerIsAlwaysLive || e12.consumers !== void 0; } -function $i(e6) { - sl?.(e6); +function Co(e12) { + ld?.(e12); } -function cl(e6, t) { +function dd(e12, t) { let n = t.producersTail; if (n !== void 0) { let r = t.producers; do { - if (r === e6) + if (r === e12) return true; if (r === n) break; @@ -176,60 +176,106 @@ function cl(e6, t) { } return false; } -function Ui(e6, t) { - return Object.is(e6, t); +function bo(e12, t) { + return Object.is(e12, t); } -function ll() { +function On(e12, t) { + let n = Object.create(fd); + n.computation = e12, t !== void 0 && (n.equal = t); + let r = () => { + if (Eo(n), vo(n), n.value === Nn) + throw n.error; + return n.value; + }; + return r[Z] = n, Co(n), r; +} +var ho = Symbol("UNSET"); +var go = Symbol("COMPUTING"); +var Nn = Symbol("ERRORED"); +var fd = A(N({}, ut), { value: ho, dirty: true, error: null, equal: bo, kind: "computed", producerMustRecompute(e12) { + return e12.value === ho || e12.value === go; +}, producerRecomputeValue(e12) { + if (e12.value === go) + throw new Error(""); + let t = e12.value; + e12.value = go; + let n = Bt(e12), r, o = false; + try { + r = e12.computation(), g(null), o = t !== ho && t !== Nn && r !== Nn && e12.equal(t, r); + } catch (i) { + r = Nn, e12.error = i; + } finally { + An(e12, n); + } + if (o) { + e12.value = t; + return; + } + e12.value = r, e12.version++; +} }); +function pd() { throw new Error(); } -var zi = ll; -function Wi(e6) { - zi(e6); +var _a = pd; +function Sa(e12) { + _a(e12); +} +function To(e12) { + _a = e12; } -function hr(e6) { - zi = e6; +var hd = null; +function Mo(e12, t) { + let n = Object.create(Aa); + n.value = e12, t !== void 0 && (n.equal = t); + let r = () => Na(n); + return r[Z] = n, Co(n), [r, (s) => _o(n, s), (s) => xa(n, s)]; } -var ul = null; -function gr(e6, t) { - let n = Object.create(Zi); - n.value = e6, t !== void 0 && (n.equal = t); - let r = () => Gi(n); - return r[W] = n, $i(n), [r, (s) => mr(n, s), (s) => qi(n, s)]; +function Na(e12) { + return vo(e12), e12.value; } -function Gi(e6) { - return Li(e6), e6.value; +function _o(e12, t) { + Do() || Sa(e12), e12.equal(e12.value, t) || (e12.value = t, gd(e12)); } -function mr(e6, t) { - ur() || Wi(e6), e6.equal(e6.value, t) || (e6.value = t, dl(e6)); +function xa(e12, t) { + Do() || Sa(e12), _o(e12, t(e12.value)); } -function qi(e6, t) { - ur() || Wi(e6), mr(e6, t(e6.value)); +var Aa = A(N({}, ut), { equal: bo, value: void 0, kind: "signal" }); +function gd(e12) { + e12.version++, Ca(), Io(e12), hd?.(e12); } -var Zi = V(A({}, Gt), { equal: Ui, value: void 0, kind: "signal" }); -function dl(e6) { - e6.version++, Pi(), lr(e6), ul?.(e6); +var So = A(N({}, ut), { consumerIsAlwaysLive: true, consumerAllowSignalWrites: true, dirty: true, kind: "effect" }); +function No(e12) { + if (e12.dirty = false, e12.version > 0 && !Rn(e12)) + return; + e12.version++; + let t = Bt(e12); + try { + e12.cleanup(), e12.fn(); + } finally { + An(e12, t); + } } -function N(e6) { - return typeof e6 == "function"; +function $(e12) { + return typeof e12 == "function"; } -function Zt(e6) { - let n = e6((r) => { +function kn(e12) { + let n = e12((r) => { Error.call(r), r.stack = new Error().stack; }); return n.prototype = Object.create(Error.prototype), n.prototype.constructor = n, n; } -var Qt = Zt((e6) => function(n) { - e6(this), this.message = n ? `${n.length} errors occurred during unsubscription: +var Pn = kn((e12) => function(n) { + e12(this), this.message = n ? `${n.length} errors occurred during unsubscription: ${n.map((r, o) => `${o + 1}) ${r.toString()}`).join(` `)}` : "", this.name = "UnsubscriptionError", this.errors = n; }); -function ot(e6, t) { - if (e6) { - let n = e6.indexOf(t); - 0 <= n && e6.splice(n, 1); +function $t(e12, t) { + if (e12) { + let n = e12.indexOf(t); + 0 <= n && e12.splice(n, 1); } } -var _ = class e { +var H = class e { constructor(t) { this.initialTeardown = t, this.closed = false, this._parentage = null, this._finalizers = null; } @@ -245,31 +291,31 @@ var _ = class e { else n.remove(this); let { initialTeardown: r } = this; - if (N(r)) + if ($(r)) try { r(); } catch (i) { - t = i instanceof Qt ? i.errors : [i]; + t = i instanceof Pn ? i.errors : [i]; } let { _finalizers: o } = this; if (o) { this._finalizers = null; for (let i of o) try { - Qi(i); + Ra(i); } catch (s) { - t = t ?? [], s instanceof Qt ? t = [...t, ...s.errors] : t.push(s); + t = t ?? [], s instanceof Pn ? t = [...t, ...s.errors] : t.push(s); } } if (t) - throw new Qt(t); + throw new Pn(t); } } add(t) { var n; if (t && t !== this) if (this.closed) - Qi(t); + Ra(t); else { if (t instanceof e) { if (t.closed || t._hasParent(this)) @@ -289,83 +335,83 @@ var _ = class e { } _removeParent(t) { let { _parentage: n } = this; - n === t ? this._parentage = null : Array.isArray(n) && ot(n, t); + n === t ? this._parentage = null : Array.isArray(n) && $t(n, t); } remove(t) { let { _finalizers: n } = this; - n && ot(n, t), t instanceof e && t._removeParent(this); + n && $t(n, t), t instanceof e && t._removeParent(this); } }; -_.EMPTY = (() => { - let e6 = new _(); - return e6.closed = true, e6; +H.EMPTY = (() => { + let e12 = new H(); + return e12.closed = true, e12; })(); -var yr = _.EMPTY; -function Yt(e6) { - return e6 instanceof _ || e6 && "closed" in e6 && N(e6.remove) && N(e6.add) && N(e6.unsubscribe); -} -function Qi(e6) { - N(e6) ? e6() : e6.unsubscribe(); -} -var B = { onUnhandledError: null, onStoppedNotification: null, Promise: void 0, useDeprecatedSynchronousErrorHandling: false, useDeprecatedNextContext: false }; -var Pe = { setTimeout(e6, t, ...n) { - let { delegate: r } = Pe; - return r?.setTimeout ? r.setTimeout(e6, t, ...n) : setTimeout(e6, t, ...n); -}, clearTimeout(e6) { - let { delegate: t } = Pe; - return (t?.clearTimeout || clearTimeout)(e6); +var xo = H.EMPTY; +function Ln(e12) { + return e12 instanceof H || e12 && "closed" in e12 && $(e12.remove) && $(e12.add) && $(e12.unsubscribe); +} +function Ra(e12) { + $(e12) ? e12() : e12.unsubscribe(); +} +var te = { onUnhandledError: null, onStoppedNotification: null, Promise: void 0, useDeprecatedSynchronousErrorHandling: false, useDeprecatedNextContext: false }; +var pt = { setTimeout(e12, t, ...n) { + let { delegate: r } = pt; + return r?.setTimeout ? r.setTimeout(e12, t, ...n) : setTimeout(e12, t, ...n); +}, clearTimeout(e12) { + let { delegate: t } = pt; + return (t?.clearTimeout || clearTimeout)(e12); }, delegate: void 0 }; -function Yi(e6) { - Pe.setTimeout(() => { - let { onUnhandledError: t } = B; +function Oa(e12) { + pt.setTimeout(() => { + let { onUnhandledError: t } = te; if (t) - t(e6); + t(e12); else - throw e6; + throw e12; }); } -function vr() { +function Ao() { } -var Ki = Er("C", void 0, void 0); -function Ji(e6) { - return Er("E", void 0, e6); +var ka = Ro("C", void 0, void 0); +function Pa(e12) { + return Ro("E", void 0, e12); } -function Xi(e6) { - return Er("N", e6, void 0); +function La(e12) { + return Ro("N", e12, void 0); } -function Er(e6, t, n) { - return { kind: e6, value: t, error: n }; +function Ro(e12, t, n) { + return { kind: e12, value: t, error: n }; } -var ve = null; -function Fe(e6) { - if (B.useDeprecatedSynchronousErrorHandling) { - let t = !ve; - if (t && (ve = { errorThrown: false, error: null }), e6(), t) { - let { errorThrown: n, error: r } = ve; - if (ve = null, n) +var Ue = null; +function ht(e12) { + if (te.useDeprecatedSynchronousErrorHandling) { + let t = !Ue; + if (t && (Ue = { errorThrown: false, error: null }), e12(), t) { + let { errorThrown: n, error: r } = Ue; + if (Ue = null, n) throw r; } } else - e6(); + e12(); } -function es(e6) { - B.useDeprecatedSynchronousErrorHandling && ve && (ve.errorThrown = true, ve.error = e6); +function Fa(e12) { + te.useDeprecatedSynchronousErrorHandling && Ue && (Ue.errorThrown = true, Ue.error = e12); } -var Ee = class extends _ { +var ze = class extends H { constructor(t) { - super(), this.isStopped = false, t ? (this.destination = t, Yt(t) && t.add(this)) : this.destination = hl; + super(), this.isStopped = false, t ? (this.destination = t, Ln(t) && t.add(this)) : this.destination = vd; } static create(t, n, r) { - return new je(t, n, r); + return new gt(t, n, r); } next(t) { - this.isStopped ? Dr(Xi(t), this) : this._next(t); + this.isStopped ? ko(La(t), this) : this._next(t); } error(t) { - this.isStopped ? Dr(Ji(t), this) : (this.isStopped = true, this._error(t)); + this.isStopped ? ko(Pa(t), this) : (this.isStopped = true, this._error(t)); } complete() { - this.isStopped ? Dr(Ki, this) : (this.isStopped = true, this._complete()); + this.isStopped ? ko(ka, this) : (this.isStopped = true, this._complete()); } unsubscribe() { this.closed || (this.isStopped = true, super.unsubscribe(), this.destination = null); @@ -388,11 +434,11 @@ var Ee = class extends _ { } } }; -var fl = Function.prototype.bind; -function Ir(e6, t) { - return fl.call(e6, t); +var md = Function.prototype.bind; +function Oo(e12, t) { + return md.call(e12, t); } -var wr = class { +var Po = class { constructor(t) { this.partialObserver = t; } @@ -402,7 +448,7 @@ var wr = class { try { n.next(t); } catch (r) { - Kt(r); + Fn(r); } } error(t) { @@ -411,10 +457,10 @@ var wr = class { try { n.error(t); } catch (r) { - Kt(r); + Fn(r); } else - Kt(t); + Fn(t); } complete() { let { partialObserver: t } = this; @@ -422,55 +468,55 @@ var wr = class { try { t.complete(); } catch (n) { - Kt(n); + Fn(n); } } }; -var je = class extends Ee { +var gt = class extends ze { constructor(t, n, r) { super(); let o; - if (N(t) || !t) + if ($(t) || !t) o = { next: t ?? void 0, error: n ?? void 0, complete: r ?? void 0 }; else { let i; - this && B.useDeprecatedNextContext ? (i = Object.create(t), i.unsubscribe = () => this.unsubscribe(), o = { next: t.next && Ir(t.next, i), error: t.error && Ir(t.error, i), complete: t.complete && Ir(t.complete, i) }) : o = t; + this && te.useDeprecatedNextContext ? (i = Object.create(t), i.unsubscribe = () => this.unsubscribe(), o = { next: t.next && Oo(t.next, i), error: t.error && Oo(t.error, i), complete: t.complete && Oo(t.complete, i) }) : o = t; } - this.destination = new wr(o); + this.destination = new Po(o); } }; -function Kt(e6) { - B.useDeprecatedSynchronousErrorHandling ? es(e6) : Yi(e6); +function Fn(e12) { + te.useDeprecatedSynchronousErrorHandling ? Fa(e12) : Oa(e12); } -function pl(e6) { - throw e6; +function yd(e12) { + throw e12; } -function Dr(e6, t) { - let { onStoppedNotification: n } = B; - n && Pe.setTimeout(() => n(e6, t)); +function ko(e12, t) { + let { onStoppedNotification: n } = te; + n && pt.setTimeout(() => n(e12, t)); } -var hl = { closed: true, next: vr, error: pl, complete: vr }; -var ts = typeof Symbol == "function" && Symbol.observable || "@@observable"; -function ns(e6) { - return e6; +var vd = { closed: true, next: Ao, error: yd, complete: Ao }; +var ja = typeof Symbol == "function" && Symbol.observable || "@@observable"; +function Ha(e12) { + return e12; } -function rs(e6) { - return e6.length === 0 ? ns : e6.length === 1 ? e6[0] : function(n) { - return e6.reduce((r, o) => o(r), n); +function Va(e12) { + return e12.length === 0 ? Ha : e12.length === 1 ? e12[0] : function(n) { + return e12.reduce((r, o) => o(r), n); }; } -var He = (() => { - class e6 { +var mt = (() => { + class e12 { constructor(n) { n && (this._subscribe = n); } lift(n) { - let r = new e6(); + let r = new e12(); return r.source = this, r.operator = n, r; } subscribe(n, r, o) { - let i = ml(n) ? n : new je(n, r, o); - return Fe(() => { + let i = Id(n) ? n : new gt(n, r, o); + return ht(() => { let { operator: s, source: a } = this; i.add(s ? s.call(i, a) : a ? this._subscribe(i) : this._trySubscribe(i)); }), i; @@ -483,8 +529,8 @@ var He = (() => { } } forEach(n, r) { - return r = os(r), new r((o, i) => { - let s = new je({ next: (a) => { + return r = Ba(r), new r((o, i) => { + let s = new gt({ next: (a) => { try { n(a); } catch (c) { @@ -498,40 +544,40 @@ var He = (() => { var r; return (r = this.source) === null || r === void 0 ? void 0 : r.subscribe(n); } - [ts]() { + [ja]() { return this; } pipe(...n) { - return rs(n)(this); + return Va(n)(this); } toPromise(n) { - return n = os(n), new n((r, o) => { + return n = Ba(n), new n((r, o) => { let i; this.subscribe((s) => i = s, (s) => o(s), () => r(i)); }); } } - return e6.create = (t) => new e6(t), e6; + return e12.create = (t) => new e12(t), e12; })(); -function os(e6) { +function Ba(e12) { var t; - return (t = e6 ?? B.Promise) !== null && t !== void 0 ? t : Promise; + return (t = e12 ?? te.Promise) !== null && t !== void 0 ? t : Promise; } -function gl(e6) { - return e6 && N(e6.next) && N(e6.error) && N(e6.complete); +function Ed(e12) { + return e12 && $(e12.next) && $(e12.error) && $(e12.complete); } -function ml(e6) { - return e6 && e6 instanceof Ee || gl(e6) && Yt(e6); +function Id(e12) { + return e12 && e12 instanceof ze || Ed(e12) && Ln(e12); } -function yl(e6) { - return N(e6?.lift); +function Dd(e12) { + return $(e12?.lift); } -function is(e6) { +function $a(e12) { return (t) => { - if (yl(t)) + if (Dd(t)) return t.lift(function(n) { try { - return e6(n, this); + return e12(n, this); } catch (r) { this.error(r); } @@ -539,10 +585,10 @@ function is(e6) { throw new TypeError("Unable to lift unknown Observable type"); }; } -function ss(e6, t, n, r, o) { - return new Cr(e6, t, n, r, o); +function Ua(e12, t, n, r, o) { + return new Lo(e12, t, n, r, o); } -var Cr = class extends Ee { +var Lo = class extends ze { constructor(t, n, r, o, i, s) { super(t), this.onFinalize = i, this.shouldUnsubscribe = s, this._next = n ? function(a) { try { @@ -576,24 +622,24 @@ var Cr = class extends Ee { } } }; -var as = Zt((e6) => function() { - e6(this), this.name = "ObjectUnsubscribedError", this.message = "object unsubscribed"; +var za = kn((e12) => function() { + e12(this), this.name = "ObjectUnsubscribedError", this.message = "object unsubscribed"; }); -var ae = (() => { - class e6 extends He { +var ye = (() => { + class e12 extends mt { constructor() { super(), this.closed = false, this.currentObservers = null, this.observers = [], this.isStopped = false, this.hasError = false, this.thrownError = null; } lift(n) { - let r = new Jt(this, this); + let r = new jn(this, this); return r.operator = n, r; } _throwIfClosed() { if (this.closed) - throw new as(); + throw new za(); } next(n) { - Fe(() => { + ht(() => { if (this._throwIfClosed(), !this.isStopped) { this.currentObservers || (this.currentObservers = Array.from(this.observers)); for (let r of this.currentObservers) @@ -602,7 +648,7 @@ var ae = (() => { }); } error(n) { - Fe(() => { + ht(() => { if (this._throwIfClosed(), !this.isStopped) { this.hasError = this.isStopped = true, this.thrownError = n; let { observers: r } = this; @@ -612,7 +658,7 @@ var ae = (() => { }); } complete() { - Fe(() => { + ht(() => { if (this._throwIfClosed(), !this.isStopped) { this.isStopped = true; let { observers: n } = this; @@ -636,8 +682,8 @@ var ae = (() => { } _innerSubscribe(n) { let { hasError: r, isStopped: o, observers: i } = this; - return r || o ? yr : (this.currentObservers = null, i.push(n), new _(() => { - this.currentObservers = null, ot(i, n); + return r || o ? xo : (this.currentObservers = null, i.push(n), new H(() => { + this.currentObservers = null, $t(i, n); })); } _checkFinalizedStatuses(n) { @@ -645,13 +691,13 @@ var ae = (() => { r ? n.error(o) : i && n.complete(); } asObservable() { - let n = new He(); + let n = new mt(); return n.source = this, n; } } - return e6.create = (t, n) => new Jt(t, n), e6; + return e12.create = (t, n) => new jn(t, n), e12; })(); -var Jt = class extends ae { +var jn = class extends ye { constructor(t, n) { super(), this.destination = t, this.source = n; } @@ -669,10 +715,10 @@ var Jt = class extends ae { } _subscribe(t) { var n, r; - return (r = (n = this.source) === null || n === void 0 ? void 0 : n.subscribe(t)) !== null && r !== void 0 ? r : yr; + return (r = (n = this.source) === null || n === void 0 ? void 0 : n.subscribe(t)) !== null && r !== void 0 ? r : xo; } }; -var it = class extends ae { +var Ut = class extends ye { constructor(t) { super(), this._value = t; } @@ -693,83 +739,100 @@ var it = class extends ae { super.next(this._value = t); } }; -function Tr(e6, t) { - return is((n, r) => { +function Fo(e12, t) { + return $a((n, r) => { let o = 0; - n.subscribe(ss(r, (i) => { - r.next(e6.call(t, i, o++)); + n.subscribe(Ua(r, (i) => { + r.next(e12.call(t, i, o++)); })); }); } -var Mr; -function Xt() { - return Mr; +var jo; +function Hn() { + return jo; } -function G(e6) { - let t = Mr; - return Mr = e6, t; +function ae(e12) { + let t = jo; + return jo = e12, t; } -var cs = Symbol("NotFound"); -function Ve(e6) { - return e6 === cs || e6?.name === "\u0275NotFound"; +var Wa = Symbol("NotFound"); +function yt(e12) { + return e12 === Wa || e12?.name === "\u0275NotFound"; } -var sn = "https://angular.dev/best-practices/security#preventing-cross-site-scripting-xss"; -var g = class extends Error { +var qn = "https://angular.dev/best-practices/security#preventing-cross-site-scripting-xss"; +var v = class extends Error { code; constructor(t, n) { - super(an(t, n)), this.code = t; + super(Zn(t, n)), this.code = t; } }; -function Dl(e6) { - return `NG0${Math.abs(e6)}`; +function wd(e12) { + return `NG0${Math.abs(e12)}`; } -function an(e6, t) { - return `${Dl(e6)}${t ? ": " + t : ""}`; +function Zn(e12, t) { + return `${wd(e12)}${t ? ": " + t : ""}`; } -var ce = globalThis; -function C(e6) { - for (let t in e6) - if (e6[t] === C) +var Re = globalThis; +function b(e12) { + for (let t in e12) + if (e12[t] === b) return t; throw Error(""); } -function Br(e6, t) { - return e6 ? t ? `${e6} ${t}` : e6 : t || ""; -} -var wl = C({ __forward_ref__: C }); -function cn(e6) { - return e6.__forward_ref__ = cn, e6; -} -function k(e6) { - return ps(e6) ? e6() : e6; -} -function ps(e6) { - return typeof e6 == "function" && e6.hasOwnProperty(wl) && e6.__forward_ref__ === cn; -} -function S(e6) { - return { token: e6.token, providedIn: e6.providedIn || null, factory: e6.factory, value: void 0 }; -} -function ln(e6) { - return Cl(e6, un); -} -function Cl(e6, t) { - return e6.hasOwnProperty(t) && e6[t] || null; -} -function Tl(e6) { - let t = e6?.[un] ?? null; +function Qn(e12) { + if (typeof e12 == "string") + return e12; + if (Array.isArray(e12)) + return `[${e12.map(Qn).join(", ")}]`; + if (e12 == null) + return "" + e12; + let t = e12.overriddenName || e12.name; + if (t) + return `${t}`; + let n = e12.toString(); + if (n == null) + return "" + n; + let r = n.indexOf(` +`); + return r >= 0 ? n.slice(0, r) : n; +} +function Jo(e12, t) { + return e12 ? t ? `${e12} ${t}` : e12 : t || ""; +} +var Cd = b({ __forward_ref__: b }); +function Yn(e12) { + return e12.__forward_ref__ = Yn, e12; +} +function W(e12) { + return Ya(e12) ? e12() : e12; +} +function Ya(e12) { + return typeof e12 == "function" && e12.hasOwnProperty(Cd) && e12.__forward_ref__ === Yn; +} +function _(e12) { + return { token: e12.token, providedIn: e12.providedIn || null, factory: e12.factory, value: void 0 }; +} +function Kn(e12) { + return bd(e12, Jn); +} +function bd(e12, t) { + return e12.hasOwnProperty(t) && e12[t] || null; +} +function Td(e12) { + let t = e12?.[Jn] ?? null; return t || null; } -function br(e6) { - return e6 && e6.hasOwnProperty(tn) ? e6[tn] : null; +function Vo(e12) { + return e12 && e12.hasOwnProperty(Bn) ? e12[Bn] : null; } -var un = C({ \u0275prov: C }); -var tn = C({ \u0275inj: C }); -var m = class { +var Jn = b({ \u0275prov: b }); +var Bn = b({ \u0275inj: b }); +var D = class { _desc; ngMetadataName = "InjectionToken"; \u0275prov; constructor(t, n) { - this._desc = t, this.\u0275prov = void 0, typeof n == "number" ? this.__NG_ELEMENT_ID__ = n : n !== void 0 && (this.\u0275prov = S({ token: this, providedIn: n.providedIn || "root", factory: n.factory })); + this._desc = t, this.\u0275prov = void 0, typeof n == "number" ? this.__NG_ELEMENT_ID__ = n : n !== void 0 && (this.\u0275prov = _({ token: this, providedIn: n.providedIn || "root", factory: n.factory })); } get multi() { return this; @@ -778,93 +841,93 @@ var m = class { return `InjectionToken ${this._desc}`; } }; -function $r(e6) { - return e6 && !!e6.\u0275providers; +function Xo(e12) { + return e12 && !!e12.\u0275providers; } -var Ur = C({ \u0275cmp: C }); -var zr = C({ \u0275dir: C }); -var Wr = C({ \u0275pipe: C }); -var _r = C({ \u0275fac: C }); -var Me = C({ __NG_ELEMENT_ID__: C }); -var ls = C({ __NG_ENV_ID__: C }); -function ut(e6) { - return qr(e6, "@Component"), e6[Ur] || null; +var ei = b({ \u0275cmp: b }); +var ti = b({ \u0275dir: b }); +var ni = b({ \u0275pipe: b }); +var Bo = b({ \u0275fac: b }); +var Qe = b({ __NG_ELEMENT_ID__: b }); +var Ga = b({ __NG_ENV_ID__: b }); +function Ye(e12) { + return oi(e12, "@Component"), e12[ei] || null; } -function Gr(e6) { - return qr(e6, "@Directive"), e6[zr] || null; +function ri(e12) { + return oi(e12, "@Directive"), e12[ti] || null; } -function hs(e6) { - return qr(e6, "@Pipe"), e6[Wr] || null; +function Ka(e12) { + return oi(e12, "@Pipe"), e12[ni] || null; } -function qr(e6, t) { - if (e6 == null) - throw new g(-919, false); +function oi(e12, t) { + if (e12 == null) + throw new v(-919, false); } -function Zr(e6) { - return typeof e6 == "string" ? e6 : e6 == null ? "" : String(e6); +function ii(e12) { + return typeof e12 == "string" ? e12 : e12 == null ? "" : String(e12); } -var gs = C({ ngErrorCode: C }); -var Ml = C({ ngErrorMessage: C }); -var Sl = C({ ngTokenPath: C }); -function Qr(e6, t) { - return ms("", -200, t); +var Ja = b({ ngErrorCode: b }); +var Md = b({ ngErrorMessage: b }); +var _d = b({ ngTokenPath: b }); +function si(e12, t) { + return Xa("", -200, t); } -function dn(e6, t) { - throw new g(-201, false); +function Xn(e12, t) { + throw new v(-201, false); } -function ms(e6, t, n) { - let r = new g(t, e6); - return r[gs] = t, r[Ml] = e6, n && (r[Sl] = n), r; +function Xa(e12, t, n) { + let r = new v(t, e12); + return r[Ja] = t, r[Md] = e12, n && (r[_d] = n), r; } -function bl(e6) { - return e6[gs]; +function Sd(e12) { + return e12[Ja]; } -var Nr; -function ys() { - return Nr; +var $o; +function ec() { + return $o; } -function R(e6) { - let t = Nr; - return Nr = e6, t; +function z(e12) { + let t = $o; + return $o = e12, t; } -function Yr(e6, t, n) { - let r = ln(e6); +function ai(e12, t, n) { + let r = Kn(e12); if (r && r.providedIn == "root") return r.value === void 0 ? r.value = r.factory() : r.value; if (n & 8) return null; if (t !== void 0) return t; - dn(e6, ""); + Xn(e12, ""); } -var _l = {}; -var Ie = _l; -var Nl = "__NG_DI_FLAG__"; -var xr = class { +var Nd = {}; +var We = Nd; +var xd = "__NG_DI_FLAG__"; +var Uo = class { injector; constructor(t) { this.injector = t; } retrieve(t, n) { - let r = De(n) || 0; + let r = Ge(n) || 0; try { - return this.injector.get(t, r & 8 ? null : Ie, r); + return this.injector.get(t, r & 8 ? null : We, r); } catch (o) { - if (Ve(o)) + if (yt(o)) return o; throw o; } } }; -function xl(e6, t = 0) { - let n = Xt(); +function Ad(e12, t = 0) { + let n = Hn(); if (n === void 0) - throw new g(-203, false); + throw new v(-203, false); if (n === null) - return Yr(e6, void 0, t); + return ai(e12, void 0, t); { - let r = Al(t), o = n.retrieve(e6, r); - if (Ve(o)) { + let r = Rd(t), o = n.retrieve(e12, r); + if (yt(o)) { if (r.optional) return null; throw o; @@ -872,103 +935,155 @@ function xl(e6, t = 0) { return o; } } -function I(e6, t = 0) { - return (ys() || xl)(k(e6), t); +function w(e12, t = 0) { + return (ec() || Ad)(W(e12), t); } -function E(e6, t) { - return I(e6, De(t)); +function E(e12, t) { + return w(e12, Ge(t)); } -function De(e6) { - return typeof e6 > "u" || typeof e6 == "number" ? e6 : 0 | (e6.optional && 8) | (e6.host && 1) | (e6.self && 2) | (e6.skipSelf && 4); +function Ge(e12) { + return typeof e12 > "u" || typeof e12 == "number" ? e12 : 0 | (e12.optional && 8) | (e12.host && 1) | (e12.self && 2) | (e12.skipSelf && 4); } -function Al(e6) { - return { optional: !!(e6 & 8), host: !!(e6 & 1), self: !!(e6 & 2), skipSelf: !!(e6 & 4) }; +function Rd(e12) { + return { optional: !!(e12 & 8), host: !!(e12 & 1), self: !!(e12 & 2), skipSelf: !!(e12 & 4) }; } -function Ar(e6) { +function zo(e12) { let t = []; - for (let n = 0; n < e6.length; n++) { - let r = k(e6[n]); + for (let n = 0; n < e12.length; n++) { + let r = W(e12[n]); if (Array.isArray(r)) { if (r.length === 0) - throw new g(900, false); + throw new v(900, false); let o, i = 0; for (let s = 0; s < r.length; s++) { - let a = r[s], c = Rl(a); + let a = r[s], c = Od(a); typeof c == "number" ? c === -1 ? o = a.token : i |= c : o = a; } - t.push(I(o, i)); + t.push(w(o, i)); } else - t.push(I(r)); + t.push(w(r)); } return t; } -function Rl(e6) { - return e6[Nl]; +function Od(e12) { + return e12[xd]; } -function $e(e6, t) { - let n = e6.hasOwnProperty(_r); - return n ? e6[_r] : null; +function Et(e12, t) { + let n = e12.hasOwnProperty(Bo); + return n ? e12[Bo] : null; } -function fn(e6, t) { - e6.forEach((n) => Array.isArray(n) ? fn(n, t) : t(n)); +function tc(e12, t, n) { + if (e12.length !== t.length) + return false; + for (let r = 0; r < e12.length; r++) { + let o = e12[r], i = t[r]; + if (n && (o = n(o), i = n(i)), i !== o) + return false; + } + return true; } -function Kr(e6, t) { - return t >= e6.length - 1 ? e6.pop() : e6.splice(t, 1)[0]; +function nc(e12) { + return e12.flat(Number.POSITIVE_INFINITY); } -var Se = {}; -var we = []; -var be = new m(""); -var Jr = new m("", -1); -var Xr = new m(""); -var at = class { - get(t, n = Ie) { - if (n === Ie) { - let o = ms("", -201); +function er(e12, t) { + e12.forEach((n) => Array.isArray(n) ? er(n, t) : t(n)); +} +function ci(e12, t, n) { + t >= e12.length ? e12.push(n) : e12.splice(t, 0, n); +} +function Qt(e12, t) { + return t >= e12.length - 1 ? e12.pop() : e12.splice(t, 1)[0]; +} +function rc(e12, t, n, r) { + let o = e12.length; + if (o == t) + e12.push(n, r); + else if (o === 1) + e12.push(r, e12[0]), e12[0] = n; + else { + for (o--, e12.push(e12[o - 1], e12[o]); o > t; ) { + let i = o - 2; + e12[o] = e12[i], o--; + } + e12[t] = n, e12[t + 1] = r; + } +} +function oc(e12, t, n) { + let r = It(e12, t); + return r >= 0 ? e12[r | 1] = n : (r = ~r, rc(e12, r, t, n)), r; +} +function tr(e12, t) { + let n = It(e12, t); + if (n >= 0) + return e12[n | 1]; +} +function It(e12, t) { + return kd(e12, t, 1); +} +function kd(e12, t, n) { + let r = 0, o = e12.length >> n; + for (; o !== r; ) { + let i = r + (o - r >> 1), s = e12[i << n]; + if (t === s) + return i << n; + s > t ? o = i : r = i + 1; + } + return ~(o << n); +} +var Ke = {}; +var Ne = []; +var Je = new D(""); +var li = new D("", -1); +var ui = new D(""); +var Wt = class { + get(t, n = We) { + if (n === We) { + let o = Xa("", -201); throw o.name = "\u0275NotFound", o; } return n; } }; -function dt(e6) { - return { \u0275providers: e6 }; +function Dt(e12) { + return { \u0275providers: e12 }; } -function vs(e6) { - return dt([{ provide: be, multi: true, useValue: e6 }]); +function ic(e12) { + return Dt([{ provide: Je, multi: true, useValue: e12 }]); } -function Es(...e6) { - return { \u0275providers: eo(true, e6), \u0275fromNgModule: true }; +function sc(...e12) { + return { \u0275providers: di(true, e12), \u0275fromNgModule: true }; } -function eo(e6, ...t) { +function di(e12, ...t) { let n = [], r = /* @__PURE__ */ new Set(), o, i = (s) => { n.push(s); }; - return fn(t, (s) => { + return er(t, (s) => { let a = s; - nn(a, i, [], r) && (o ||= [], o.push(a)); - }), o !== void 0 && Is(o, i), n; + $n(a, i, [], r) && (o ||= [], o.push(a)); + }), o !== void 0 && ac(o, i), n; } -function Is(e6, t) { - for (let n = 0; n < e6.length; n++) { - let { ngModule: r, providers: o } = e6[n]; - to(o, (i) => { +function ac(e12, t) { + for (let n = 0; n < e12.length; n++) { + let { ngModule: r, providers: o } = e12[n]; + fi(o, (i) => { t(i, r); }); } } -function nn(e6, t, n, r) { - if (e6 = k(e6), !e6) +function $n(e12, t, n, r) { + if (e12 = W(e12), !e12) return false; - let o = null, i = br(e6), s = !i && ut(e6); + let o = null, i = Vo(e12), s = !i && Ye(e12); if (!i && !s) { - let c = e6.ngModule; - if (i = br(c), i) + let c = e12.ngModule; + if (i = Vo(c), i) o = c; else return false; } else { if (s && !s.standalone) return false; - o = e6; + o = e12; } let a = r.has(o); if (s) { @@ -977,58 +1092,58 @@ function nn(e6, t, n, r) { if (r.add(o), s.dependencies) { let c = typeof s.dependencies == "function" ? s.dependencies() : s.dependencies; for (let l of c) - nn(l, t, n, r); + $n(l, t, n, r); } } else if (i) { if (i.imports != null && !a) { r.add(o); let l; - fn(i.imports, (u) => { - nn(u, t, n, r) && (l ||= [], l.push(u)); - }), l !== void 0 && Is(l, t); + er(i.imports, (u) => { + $n(u, t, n, r) && (l ||= [], l.push(u)); + }), l !== void 0 && ac(l, t); } if (!a) { - let l = $e(o) || (() => new o()); - t({ provide: o, useFactory: l, deps: we }, o), t({ provide: Xr, useValue: o, multi: true }, o), t({ provide: be, useValue: () => I(o), multi: true }, o); + let l = Et(o) || (() => new o()); + t({ provide: o, useFactory: l, deps: Ne }, o), t({ provide: ui, useValue: o, multi: true }, o), t({ provide: Je, useValue: () => w(o), multi: true }, o); } let c = i.providers; if (c != null && !a) { - let l = e6; - to(c, (u) => { + let l = e12; + fi(c, (u) => { t(u, l); }); } } else return false; - return o !== e6 && e6.providers !== void 0; + return o !== e12 && e12.providers !== void 0; } -function to(e6, t) { - for (let n of e6) - $r(n) && (n = n.\u0275providers), Array.isArray(n) ? to(n, t) : t(n); +function fi(e12, t) { + for (let n of e12) + Xo(n) && (n = n.\u0275providers), Array.isArray(n) ? fi(n, t) : t(n); } -var kl = C({ provide: String, useValue: C }); -function Ds(e6) { - return e6 !== null && typeof e6 == "object" && kl in e6; +var Pd = b({ provide: String, useValue: b }); +function cc(e12) { + return e12 !== null && typeof e12 == "object" && Pd in e12; } -function Ol(e6) { - return !!(e6 && e6.useExisting); +function Ld(e12) { + return !!(e12 && e12.useExisting); } -function Ll(e6) { - return !!(e6 && e6.useFactory); +function Fd(e12) { + return !!(e12 && e12.useFactory); } -function rn(e6) { - return typeof e6 == "function"; +function Un(e12) { + return typeof e12 == "function"; } -var ft = new m(""); -var en = {}; -var us = {}; -var Sr; -function pt() { - return Sr === void 0 && (Sr = new at()), Sr; +var Yt = new D(""); +var Vn = {}; +var qa = {}; +var Ho; +function Kt() { + return Ho === void 0 && (Ho = new Wt()), Ho; } -var $ = class { +var Q = class { }; -var Ce = class extends $ { +var qe = class extends Q { parent; source; scopes; @@ -1041,23 +1156,23 @@ var Ce = class extends $ { _destroyed = false; injectorDefTypes; constructor(t, n, r, o) { - super(), this.parent = n, this.source = r, this.scopes = o, kr(t, (s) => this.processProvider(s)), this.records.set(Jr, Be(void 0, this)), o.has("environment") && this.records.set($, Be(void 0, this)); - let i = this.records.get(ft); - i != null && typeof i.value == "string" && this.scopes.add(i.value), this.injectorDefTypes = new Set(this.get(Xr, we, { self: true })); + super(), this.parent = n, this.source = r, this.scopes = o, Go(t, (s) => this.processProvider(s)), this.records.set(li, vt(void 0, this)), o.has("environment") && this.records.set(Q, vt(void 0, this)); + let i = this.records.get(Yt); + i != null && typeof i.value == "string" && this.scopes.add(i.value), this.injectorDefTypes = new Set(this.get(ui, Ne, { self: true })); } retrieve(t, n) { - let r = De(n) || 0; + let r = Ge(n) || 0; try { - return this.get(t, Ie, r); + return this.get(t, We, r); } catch (o) { - if (Ve(o)) + if (yt(o)) return o; throw o; } } destroy() { - st(this), this._destroyed = true; - let t = v(null); + zt(this), this._destroyed = true; + let t = g(null); try { for (let r of this._ngOnDestroyHooks) r.ngOnDestroy(); @@ -1066,80 +1181,80 @@ var Ce = class extends $ { for (let r of n) r(); } finally { - this.records.clear(), this._ngOnDestroyHooks.clear(), this.injectorDefTypes.clear(), v(t); + this.records.clear(), this._ngOnDestroyHooks.clear(), this.injectorDefTypes.clear(), g(t); } } onDestroy(t) { - return st(this), this._onDestroyHooks.push(t), () => this.removeOnDestroy(t); + return zt(this), this._onDestroyHooks.push(t), () => this.removeOnDestroy(t); } runInContext(t) { - st(this); - let n = G(this), r = R(void 0), o; + zt(this); + let n = ae(this), r = z(void 0), o; try { return t(); } finally { - G(n), R(r); + ae(n), z(r); } } - get(t, n = Ie, r) { - if (st(this), t.hasOwnProperty(ls)) - return t[ls](this); - let o = De(r), i, s = G(this), a = R(void 0); + get(t, n = We, r) { + if (zt(this), t.hasOwnProperty(Ga)) + return t[Ga](this); + let o = Ge(r), i, s = ae(this), a = z(void 0); try { if (!(o & 4)) { let l = this.records.get(t); if (l === void 0) { - let u = Vl(t) && ln(t); - u && this.injectableDefInScope(u) ? l = Be(Rr(t), en) : l = null, this.records.set(t, l); + let u = $d(t) && Kn(t); + u && this.injectableDefInScope(u) ? l = vt(Wo(t), Vn) : l = null, this.records.set(t, l); } if (l != null) return this.hydrate(t, l, o); } - let c = o & 2 ? pt() : this.parent; - return n = o & 8 && n === Ie ? null : n, c.get(t, n); + let c = o & 2 ? Kt() : this.parent; + return n = o & 8 && n === We ? null : n, c.get(t, n); } catch (c) { - let l = bl(c); - throw l === -200 || l === -201 ? new g(l, null) : c; + let l = Sd(c); + throw l === -200 || l === -201 ? new v(l, null) : c; } finally { - R(a), G(s); + z(a), ae(s); } } resolveInjectorInitializers() { - let t = v(null), n = G(this), r = R(void 0), o; + let t = g(null), n = ae(this), r = z(void 0), o; try { - let i = this.get(be, we, { self: true }); + let i = this.get(Je, Ne, { self: true }); for (let s of i) s(); } finally { - G(n), R(r), v(t); + ae(n), z(r), g(t); } } toString() { return "R3Injector[...]"; } processProvider(t) { - t = k(t); - let n = rn(t) ? t : k(t && t.provide), r = Fl(t); - if (!rn(t) && t.multi === true) { + t = W(t); + let n = Un(t) ? t : W(t && t.provide), r = Hd(t); + if (!Un(t) && t.multi === true) { let o = this.records.get(n); - o || (o = Be(void 0, en, true), o.factory = () => Ar(o.multi), this.records.set(n, o)), n = t, o.multi.push(t); + o || (o = vt(void 0, Vn, true), o.factory = () => zo(o.multi), this.records.set(n, o)), n = t, o.multi.push(t); } this.records.set(n, r); } hydrate(t, n, r) { - let o = v(null); + let o = g(null); try { - if (n.value === us) - throw Qr(""); - return n.value === en && (n.value = us, n.value = n.factory(void 0, r)), typeof n.value == "object" && n.value && Hl(n.value) && this._ngOnDestroyHooks.add(n.value), n.value; + if (n.value === qa) + throw si(""); + return n.value === Vn && (n.value = qa, n.value = n.factory(void 0, r)), typeof n.value == "object" && n.value && Bd(n.value) && this._ngOnDestroyHooks.add(n.value), n.value; } finally { - v(o); + g(o); } } injectableDefInScope(t) { if (!t.providedIn) return false; - let n = k(t.providedIn); + let n = W(t.providedIn); return typeof n == "string" ? n === "any" || this.scopes.has(n) : this.injectorDefTypes.has(n); } removeOnDestroy(t) { @@ -1147,395 +1262,431 @@ var Ce = class extends $ { n !== -1 && this._onDestroyHooks.splice(n, 1); } }; -function Rr(e6) { - let t = ln(e6), n = t !== null ? t.factory : $e(e6); +function Wo(e12) { + let t = Kn(e12), n = t !== null ? t.factory : Et(e12); if (n !== null) return n; - if (e6 instanceof m) - throw new g(-204, false); - if (e6 instanceof Function) - return Pl(e6); - throw new g(-204, false); -} -function Pl(e6) { - if (e6.length > 0) - throw new g(-204, false); - let n = Tl(e6); - return n !== null ? () => n.factory(e6) : () => new e6(); -} -function Fl(e6) { - if (Ds(e6)) - return Be(void 0, e6.useValue); + if (e12 instanceof D) + throw new v(-204, false); + if (e12 instanceof Function) + return jd(e12); + throw new v(-204, false); +} +function jd(e12) { + if (e12.length > 0) + throw new v(-204, false); + let n = Td(e12); + return n !== null ? () => n.factory(e12) : () => new e12(); +} +function Hd(e12) { + if (cc(e12)) + return vt(void 0, e12.useValue); { - let t = ws(e6); - return Be(t, en); + let t = lc(e12); + return vt(t, Vn); } } -function ws(e6, t, n) { +function lc(e12, t, n) { let r; - if (rn(e6)) { - let o = k(e6); - return $e(o) || Rr(o); - } else if (Ds(e6)) - r = () => k(e6.useValue); - else if (Ll(e6)) - r = () => e6.useFactory(...Ar(e6.deps || [])); - else if (Ol(e6)) - r = (o, i) => I(k(e6.useExisting), i !== void 0 && i & 8 ? 8 : void 0); + if (Un(e12)) { + let o = W(e12); + return Et(o) || Wo(o); + } else if (cc(e12)) + r = () => W(e12.useValue); + else if (Fd(e12)) + r = () => e12.useFactory(...zo(e12.deps || [])); + else if (Ld(e12)) + r = (o, i) => w(W(e12.useExisting), i !== void 0 && i & 8 ? 8 : void 0); else { - let o = k(e6 && (e6.useClass || e6.provide)); - if (jl(e6)) - r = () => new o(...Ar(e6.deps)); + let o = W(e12 && (e12.useClass || e12.provide)); + if (Vd(e12)) + r = () => new o(...zo(e12.deps)); else - return $e(o) || Rr(o); + return Et(o) || Wo(o); } return r; } -function st(e6) { - if (e6.destroyed) - throw new g(-205, false); +function zt(e12) { + if (e12.destroyed) + throw new v(-205, false); } -function Be(e6, t, n = false) { - return { factory: e6, value: t, multi: n ? [] : void 0 }; +function vt(e12, t, n = false) { + return { factory: e12, value: t, multi: n ? [] : void 0 }; } -function jl(e6) { - return !!e6.deps; +function Vd(e12) { + return !!e12.deps; } -function Hl(e6) { - return e6 !== null && typeof e6 == "object" && typeof e6.ngOnDestroy == "function"; +function Bd(e12) { + return e12 !== null && typeof e12 == "object" && typeof e12.ngOnDestroy == "function"; } -function Vl(e6) { - return typeof e6 == "function" || typeof e6 == "object" && e6.ngMetadataName === "InjectionToken"; +function $d(e12) { + return typeof e12 == "function" || typeof e12 == "object" && e12.ngMetadataName === "InjectionToken"; } -function kr(e6, t) { - for (let n of e6) - Array.isArray(n) ? kr(n, t) : n && $r(n) ? kr(n.\u0275providers, t) : t(n); +function Go(e12, t) { + for (let n of e12) + Array.isArray(n) ? Go(n, t) : n && Xo(n) ? Go(n.\u0275providers, t) : t(n); } -function pn(e6, t) { +function nr(e12, t) { let n; - e6 instanceof Ce ? (st(e6), n = e6) : n = new xr(e6); - let r, o = G(n), i = R(void 0); + e12 instanceof qe ? (zt(e12), n = e12) : n = new Uo(e12); + let r, o = ae(n), i = z(void 0); try { return t(); } finally { - G(o), R(i); - } -} -function Cs() { - return ys() !== void 0 || Xt() != null; -} -var q = 0; -var y = 1; -var h = 2; -var O = 3; -var ne = 4; -var re = 5; -var hn = 6; -var gn = 7; -var L = 8; -var _e = 9; -var Z = 10; -var P = 11; -var ze = 12; -var no = 13; -var We = 14; -var Q = 15; -var ht = 16; -var Ne = 17; -var mn = 18; -var le = 19; -var ro = 20; -var X = 21; -var yn = 22; -var gt = 23; -var F = 24; -var vn = 25; -var Ge = 26; -var U = 27; -var Ts = 1; -var En = 7; -var Ms = 8; -var mt = 9; -var oe = 10; -function ue(e6) { - return Array.isArray(e6) && typeof e6[Ts] == "object"; -} -function de(e6) { - return Array.isArray(e6) && e6[Ts] === true; -} -function oo(e6) { - return (e6.flags & 4) !== 0; -} -function yt(e6) { - return e6.componentOffset > -1; -} -function Ss(e6) { - return (e6.flags & 1) === 1; -} -function qe(e6) { - return !!e6.template; -} -function Ze(e6) { - return (e6[h] & 512) !== 0; -} -function xe(e6) { - return (e6[h] & 256) === 256; -} -var bs = "svg"; -var _s = "math"; -function fe(e6) { - for (; Array.isArray(e6); ) - e6 = e6[q]; - return e6; -} -function Ns(e6, t) { - return fe(t[e6]); -} -function Ae(e6, t) { - return fe(t[e6.index]); -} -function io(e6, t) { - return e6.data[t]; -} -function pe(e6, t) { - let n = t[e6]; - return ue(n) ? n : n[q]; -} -function In(e6) { - return (e6[h] & 128) === 128; -} -function vt(e6, t) { - return t == null ? null : e6[t]; -} -function so(e6) { - e6[Ne] = 0; -} -function ao(e6) { - e6[h] & 1024 || (e6[h] |= 1024, In(e6) && It(e6)); -} -function Et(e6) { - return !!(e6[h] & 9216 || e6[F]?.dirty); -} -function co(e6) { - e6[Z].changeDetectionScheduler?.notify(8), e6[h] & 64 && (e6[h] |= 1024), Et(e6) && It(e6); -} -function It(e6) { - e6[Z].changeDetectionScheduler?.notify(0); - let t = Te(e6); - for (; t !== null && !(t[h] & 8192 || (t[h] |= 8192, !In(t))); ) - t = Te(t); -} -function lo(e6, t) { - if (xe(e6)) - throw new g(911, false); - e6[X] === null && (e6[X] = []), e6[X].push(t); -} -function xs(e6, t) { - if (e6[X] === null) + ae(o), z(i); + } +} +function uc() { + return ec() !== void 0 || Hn() != null; +} +var ne = 0; +var m = 1; +var y = 2; +var R = 3; +var K = 4; +var J = 5; +var wt = 6; +var Ct = 7; +var x = 8; +var De = 9; +var le = 10; +var O = 11; +var bt = 12; +var pi = 13; +var Xe = 14; +var X = 15; +var Oe = 16; +var et = 17; +var ue = 18; +var we = 19; +var hi = 20; +var Ee = 21; +var rr = 22; +var xe = 23; +var G = 24; +var or = 25; +var ke = 26; +var F = 27; +var dc = 1; +var gi = 6; +var Pe = 7; +var Jt = 8; +var tt = 9; +var S = 10; +function Le(e12) { + return Array.isArray(e12) && typeof e12[dc] == "object"; +} +function re(e12) { + return Array.isArray(e12) && e12[dc] === true; +} +function mi(e12) { + return (e12.flags & 4) !== 0; +} +function Tt(e12) { + return e12.componentOffset > -1; +} +function yi(e12) { + return (e12.flags & 1) === 1; +} +function Mt(e12) { + return !!e12.template; +} +function _t(e12) { + return (e12[y] & 512) !== 0; +} +function nt(e12) { + return (e12[y] & 256) === 256; +} +var fc = "svg"; +var pc = "math"; +function ee(e12) { + for (; Array.isArray(e12); ) + e12 = e12[ne]; + return e12; +} +function vi(e12, t) { + return ee(t[e12]); +} +function de(e12, t) { + return ee(t[e12.index]); +} +function ir(e12, t) { + return e12.data[t]; +} +function Ce(e12, t) { + let n = t[e12]; + return Le(n) ? n : n[ne]; +} +function hc(e12) { + return (e12[y] & 4) === 4; +} +function sr(e12) { + return (e12[y] & 128) === 128; +} +function gc(e12) { + return re(e12[R]); +} +function fe(e12, t) { + return t == null ? null : e12[t]; +} +function Ei(e12) { + e12[et] = 0; +} +function Ii(e12) { + e12[y] & 1024 || (e12[y] |= 1024, sr(e12) && St(e12)); +} +function mc(e12, t) { + for (; e12 > 0; ) + t = t[Xe], e12--; + return t; +} +function Xt(e12) { + return !!(e12[y] & 9216 || e12[G]?.dirty); +} +function ar(e12) { + e12[le].changeDetectionScheduler?.notify(8), e12[y] & 64 && (e12[y] |= 1024), Xt(e12) && St(e12); +} +function St(e12) { + e12[le].changeDetectionScheduler?.notify(0); + let t = Ae(e12); + for (; t !== null && !(t[y] & 8192 || (t[y] |= 8192, !sr(t))); ) + t = Ae(t); +} +function Di(e12, t) { + if (nt(e12)) + throw new v(911, false); + e12[Ee] === null && (e12[Ee] = []), e12[Ee].push(t); +} +function yc(e12, t) { + if (e12[Ee] === null) return; - let n = e6[X].indexOf(t); - n !== -1 && e6[X].splice(n, 1); + let n = e12[Ee].indexOf(t); + n !== -1 && e12[Ee].splice(n, 1); +} +function Ae(e12) { + let t = e12[R]; + return re(t) ? t[R] : t; +} +function wi(e12) { + return e12[Ct] ??= []; +} +function Ci(e12) { + return e12.cleanup ??= []; +} +function vc(e12, t, n, r) { + let o = wi(t); + o.push(n), e12.firstCreatePass && Ci(e12).push(r, o.length - 1); +} +var I = { lFrame: kc(null), bindingsEnabled: true, skipHydrationRootTNode: null }; +var qo = false; +function Ec() { + return I.lFrame.elementDepthCount; } -function Te(e6) { - let t = e6[O]; - return de(t) ? t[O] : t; +function Ic() { + I.lFrame.elementDepthCount++; } -var D = { lFrame: zs(null), bindingsEnabled: true, skipHydrationRootTNode: null }; -var Or = false; -function As() { - return D.lFrame.elementDepthCount; +function Dc() { + I.lFrame.elementDepthCount--; } -function Rs() { - D.lFrame.elementDepthCount++; +function wc() { + return I.skipHydrationRootTNode !== null; } -function ks() { - D.lFrame.elementDepthCount--; +function Cc(e12) { + return I.skipHydrationRootTNode === e12; } -function Os() { - return D.skipHydrationRootTNode !== null; +function bc() { + I.skipHydrationRootTNode = null; } -function Ls(e6) { - return D.skipHydrationRootTNode === e6; +function M() { + return I.lFrame.lView; } -function Ps() { - D.skipHydrationRootTNode = null; +function oe() { + return I.lFrame.tView; } -function H() { - return D.lFrame.lView; +function pe() { + let e12 = bi(); + for (; e12 !== null && e12.type === 64; ) + e12 = e12.parent; + return e12; } -function Dn() { - return D.lFrame.tView; +function bi() { + return I.lFrame.currentTNode; } -function Qe() { - let e6 = uo(); - for (; e6 !== null && e6.type === 64; ) - e6 = e6.parent; - return e6; +function Tc() { + let e12 = I.lFrame, t = e12.currentTNode; + return e12.isParent ? t : t.parent; } -function uo() { - return D.lFrame.currentTNode; +function Nt(e12, t) { + let n = I.lFrame; + n.currentTNode = e12, n.isParent = t; } -function Fs() { - let e6 = D.lFrame, t = e6.currentTNode; - return e6.isParent ? t : t.parent; +function Ti() { + return I.lFrame.isParent; } -function Dt(e6, t) { - let n = D.lFrame; - n.currentTNode = e6, n.isParent = t; +function Mc() { + I.lFrame.isParent = false; } -function fo() { - return D.lFrame.isParent; +function Mi() { + return qo; } -function js() { - D.lFrame.isParent = false; +function Gt(e12) { + let t = qo; + return qo = e12, t; } -function po() { - return Or; +function _c(e12) { + return I.lFrame.bindingIndex = e12; } -function ho(e6) { - let t = Or; - return Or = e6, t; +function en() { + return I.lFrame.bindingIndex++; } -function Hs(e6) { - return D.lFrame.bindingIndex = e6; +function Sc(e12) { + let t = I.lFrame, n = t.bindingIndex; + return t.bindingIndex = t.bindingIndex + e12, n; } -function go() { - return D.lFrame.bindingIndex++; +function Nc() { + return I.lFrame.inI18n; } -function Vs() { - return D.lFrame.inI18n; +function xc(e12, t) { + let n = I.lFrame; + n.bindingIndex = n.bindingRootIndex = e12, cr(t); } -function Bs(e6, t) { - let n = D.lFrame; - n.bindingIndex = n.bindingRootIndex = e6, wn(t); +function Ac() { + return I.lFrame.currentDirectiveIndex; } -function $s() { - return D.lFrame.currentDirectiveIndex; +function cr(e12) { + I.lFrame.currentDirectiveIndex = e12; } -function wn(e6) { - D.lFrame.currentDirectiveIndex = e6; +function Rc(e12) { + let t = I.lFrame.currentDirectiveIndex; + return t === -1 ? null : e12[t]; } -function mo(e6) { - D.lFrame.currentQueryIndex = e6; +function _i() { + return I.lFrame.currentQueryIndex; } -function Bl(e6) { - let t = e6[y]; - return t.type === 2 ? t.declTNode : t.type === 1 ? e6[re] : null; +function lr(e12) { + I.lFrame.currentQueryIndex = e12; } -function yo(e6, t, n) { +function Ud(e12) { + let t = e12[m]; + return t.type === 2 ? t.declTNode : t.type === 1 ? e12[J] : null; +} +function Si(e12, t, n) { if (n & 4) { - let o = t, i = e6; + let o = t, i = e12; for (; o = o.parent, o === null && !(n & 1); ) - if (o = Bl(i), o === null || (i = i[We], o.type & 10)) + if (o = Ud(i), o === null || (i = i[Xe], o.type & 10)) break; if (o === null) return false; - t = o, e6 = i; + t = o, e12 = i; } - let r = D.lFrame = Us(); - return r.currentTNode = t, r.lView = e6, true; + let r = I.lFrame = Oc(); + return r.currentTNode = t, r.lView = e12, true; +} +function ur(e12) { + let t = Oc(), n = e12[m]; + I.lFrame = t, t.currentTNode = n.firstChild, t.lView = e12, t.tView = n, t.contextLView = e12, t.bindingIndex = n.bindingStartIndex, t.inI18n = false; } -function Cn(e6) { - let t = Us(), n = e6[y]; - D.lFrame = t, t.currentTNode = n.firstChild, t.lView = e6, t.tView = n, t.contextLView = e6, t.bindingIndex = n.bindingStartIndex, t.inI18n = false; +function Oc() { + let e12 = I.lFrame, t = e12 === null ? null : e12.child; + return t === null ? kc(e12) : t; } -function Us() { - let e6 = D.lFrame, t = e6 === null ? null : e6.child; - return t === null ? zs(e6) : t; +function kc(e12) { + let t = { currentTNode: null, isParent: true, lView: null, tView: null, selectedIndex: -1, contextLView: null, elementDepthCount: 0, currentNamespace: null, currentDirectiveIndex: -1, bindingRootIndex: -1, bindingIndex: -1, currentQueryIndex: 0, parent: e12, child: null, inI18n: false }; + return e12 !== null && (e12.child = t), t; } -function zs(e6) { - let t = { currentTNode: null, isParent: true, lView: null, tView: null, selectedIndex: -1, contextLView: null, elementDepthCount: 0, currentNamespace: null, currentDirectiveIndex: -1, bindingRootIndex: -1, bindingIndex: -1, currentQueryIndex: 0, parent: e6, child: null, inI18n: false }; - return e6 !== null && (e6.child = t), t; +function Pc() { + let e12 = I.lFrame; + return I.lFrame = e12.parent, e12.currentTNode = null, e12.lView = null, e12; } -function Ws() { - let e6 = D.lFrame; - return D.lFrame = e6.parent, e6.currentTNode = null, e6.lView = null, e6; +var Ni = Pc; +function dr() { + let e12 = Pc(); + e12.isParent = true, e12.tView = null, e12.selectedIndex = -1, e12.contextLView = null, e12.elementDepthCount = 0, e12.currentDirectiveIndex = -1, e12.currentNamespace = null, e12.bindingRootIndex = -1, e12.bindingIndex = -1, e12.currentQueryIndex = 0; } -var vo = Ws; -function Tn() { - let e6 = Ws(); - e6.isParent = true, e6.tView = null, e6.selectedIndex = -1, e6.contextLView = null, e6.elementDepthCount = 0, e6.currentDirectiveIndex = -1, e6.currentNamespace = null, e6.bindingRootIndex = -1, e6.bindingIndex = -1, e6.currentQueryIndex = 0; +function Lc(e12) { + return (I.lFrame.contextLView = mc(e12, I.lFrame.contextLView))[x]; } -function Mn() { - return D.lFrame.selectedIndex; +function Fe() { + return I.lFrame.selectedIndex; } -function he(e6) { - D.lFrame.selectedIndex = e6; +function je(e12) { + I.lFrame.selectedIndex = e12; } -function Gs() { - let e6 = D.lFrame; - return io(e6.tView, e6.selectedIndex); +function Fc() { + let e12 = I.lFrame; + return ir(e12.tView, e12.selectedIndex); } -function qs() { - return D.lFrame.currentNamespace; +function jc() { + return I.lFrame.currentNamespace; } -var Zs = true; -function Eo() { - return Zs; +var Hc = true; +function fr() { + return Hc; } -function Io(e6) { - Zs = e6; +function pr(e12) { + Hc = e12; } -function Lr(e6, t = null, n = null, r) { - let o = Qs(e6, t, n, r); +function Zo(e12, t = null, n = null, r) { + let o = Vc(e12, t, n, r); return o.resolveInjectorInitializers(), o; } -function Qs(e6, t = null, n = null, r, o = /* @__PURE__ */ new Set()) { - let i = [n || we, Es(e6)], s; - return new Ce(i, t || pt(), s || null, o); +function Vc(e12, t = null, n = null, r, o = /* @__PURE__ */ new Set()) { + let i = [n || Ne, sc(e12)], s; + return new qe(i, t || Kt(), s || null, o); } -var ee = class e2 { - static THROW_IF_NOT_FOUND = Ie; - static NULL = new at(); +var ce = class e2 { + static THROW_IF_NOT_FOUND = We; + static NULL = new Wt(); static create(t, n) { if (Array.isArray(t)) - return Lr({ name: "" }, n, t, ""); + return Zo({ name: "" }, n, t, ""); { let r = t.name ?? ""; - return Lr({ name: r }, t.parent, t.providers, r); + return Zo({ name: r }, t.parent, t.providers, r); } } - static \u0275prov = S({ token: e2, providedIn: "any", factory: () => I(Jr) }); + static \u0275prov = _({ token: e2, providedIn: "any", factory: () => w(li) }); static __NG_ELEMENT_ID__ = -1; }; -var x = new m(""); -var wt = /* @__PURE__ */ (() => { - class e6 { - static __NG_ELEMENT_ID__ = $l; +var U = new D(""); +var xt = /* @__PURE__ */ (() => { + class e12 { + static __NG_ELEMENT_ID__ = zd; static __NG_ENV_ID__ = (n) => n; } - return e6; + return e12; })(); -var Pr = class extends wt { +var zn = class extends xt { _lView; constructor(t) { super(), this._lView = t; } get destroyed() { - return xe(this._lView); + return nt(this._lView); } onDestroy(t) { let n = this._lView; - return lo(n, t), () => xs(n, t); + return Di(n, t), () => yc(n, t); } }; -function $l() { - return new Pr(H()); +function zd() { + return new zn(M()); } -var Ys = false; -var Ks = new m(""); -var Ye = (() => { - class e6 { +var Bc = false; +var $c = new D(""); +var At = (() => { + class e12 { taskId = 0; pendingTasks = /* @__PURE__ */ new Set(); destroyed = false; - pendingTask = new it(false); - debugTaskTracker = E(Ks, { optional: true }); + pendingTask = new Ut(false); + debugTaskTracker = E($c, { optional: true }); get hasPendingTasks() { return this.destroyed ? false : this.pendingTask.value; } get hasPendingTasksObservable() { - return this.destroyed ? new He((n) => { + return this.destroyed ? new mt((n) => { n.next(false), n.complete(); }) : this.pendingTask; } @@ -1553,23 +1704,23 @@ var Ye = (() => { ngOnDestroy() { this.pendingTasks.clear(), this.hasPendingTasks && this.pendingTask.next(false), this.destroyed = true, this.pendingTask.unsubscribe(); } - static \u0275prov = S({ token: e6, providedIn: "root", factory: () => new e6() }); + static \u0275prov = _({ token: e12, providedIn: "root", factory: () => new e12() }); } - return e6; + return e12; })(); -var Fr = class extends ae { +var Qo = class extends ye { __isAsync; destroyRef = void 0; pendingTasks = void 0; constructor(t = false) { - super(), this.__isAsync = t, Cs() && (this.destroyRef = E(wt, { optional: true }) ?? void 0, this.pendingTasks = E(Ye, { optional: true }) ?? void 0); + super(), this.__isAsync = t, uc() && (this.destroyRef = E(xt, { optional: true }) ?? void 0, this.pendingTasks = E(At, { optional: true }) ?? void 0); } emit(t) { - let n = v(null); + let n = g(null); try { super.next(t); } finally { - v(n); + g(n); } } subscribe(t, n, r) { @@ -1580,7 +1731,7 @@ var Fr = class extends ae { } this.__isAsync && (i = this.wrapInTimeout(i), o && (o = this.wrapInTimeout(o)), s && (s = this.wrapInTimeout(s))); let a = super.subscribe({ next: o, error: i, complete: s }); - return t instanceof _ && t.add(a), a; + return t instanceof H && t.add(a), a; } wrapInTimeout(t) { return (n) => { @@ -1595,64 +1746,64 @@ var Fr = class extends ae { }; } }; -var J = Fr; -function on(...e6) { +var ve = Qo; +function Wn(...e12) { } -function Do(e6) { +function xi(e12) { let t, n; function r() { - e6 = on; + e12 = Wn; try { n !== void 0 && typeof cancelAnimationFrame == "function" && cancelAnimationFrame(n), t !== void 0 && clearTimeout(t); } catch { } } return t = setTimeout(() => { - e6(), r(); + e12(), r(); }), typeof requestAnimationFrame == "function" && (n = requestAnimationFrame(() => { - e6(), r(); + e12(), r(); })), () => r(); } -function Js(e6) { - return queueMicrotask(() => e6()), () => { - e6 = on; +function Uc(e12) { + return queueMicrotask(() => e12()), () => { + e12 = Wn; }; } -var wo = "isAngularZone"; -var ct = wo + "_ID"; -var Ul = 0; -var j = class e3 { +var Ai = "isAngularZone"; +var qt = Ai + "_ID"; +var Wd = 0; +var Y = class e3 { hasPendingMacrotasks = false; hasPendingMicrotasks = false; isStable = true; - onUnstable = new J(false); - onMicrotaskEmpty = new J(false); - onStable = new J(false); - onError = new J(false); + onUnstable = new ve(false); + onMicrotaskEmpty = new ve(false); + onStable = new ve(false); + onError = new ve(false); constructor(t) { - let { enableLongStackTrace: n = false, shouldCoalesceEventChangeDetection: r = false, shouldCoalesceRunChangeDetection: o = false, scheduleInRootZone: i = Ys } = t; + let { enableLongStackTrace: n = false, shouldCoalesceEventChangeDetection: r = false, shouldCoalesceRunChangeDetection: o = false, scheduleInRootZone: i = Bc } = t; if (typeof Zone > "u") - throw new g(908, false); + throw new v(908, false); Zone.assertZonePatched(); let s = this; - s._nesting = 0, s._outer = s._inner = Zone.current, Zone.TaskTrackingZoneSpec && (s._inner = s._inner.fork(new Zone.TaskTrackingZoneSpec())), n && Zone.longStackTraceZoneSpec && (s._inner = s._inner.fork(Zone.longStackTraceZoneSpec)), s.shouldCoalesceEventChangeDetection = !o && r, s.shouldCoalesceRunChangeDetection = o, s.callbackScheduled = false, s.scheduleInRootZone = i, Gl(s); + s._nesting = 0, s._outer = s._inner = Zone.current, Zone.TaskTrackingZoneSpec && (s._inner = s._inner.fork(new Zone.TaskTrackingZoneSpec())), n && Zone.longStackTraceZoneSpec && (s._inner = s._inner.fork(Zone.longStackTraceZoneSpec)), s.shouldCoalesceEventChangeDetection = !o && r, s.shouldCoalesceRunChangeDetection = o, s.callbackScheduled = false, s.scheduleInRootZone = i, Zd(s); } static isInAngularZone() { - return typeof Zone < "u" && Zone.current.get(wo) === true; + return typeof Zone < "u" && Zone.current.get(Ai) === true; } static assertInAngularZone() { if (!e3.isInAngularZone()) - throw new g(909, false); + throw new v(909, false); } static assertNotInAngularZone() { if (e3.isInAngularZone()) - throw new g(909, false); + throw new v(909, false); } run(t, n, r) { return this._inner.run(t, n, r); } runTask(t, n, r, o) { - let i = this._inner, s = i.scheduleEventTask("NgZoneEvent: " + o, t, zl, on, on); + let i = this._inner, s = i.scheduleEventTask("NgZoneEvent: " + o, t, Gd, Wn, Wn); try { return i.runTask(s, n, r); } finally { @@ -1666,74 +1817,74 @@ var j = class e3 { return this._outer.run(t); } }; -var zl = {}; -function Co(e6) { - if (e6._nesting == 0 && !e6.hasPendingMicrotasks && !e6.isStable) +var Gd = {}; +function Ri(e12) { + if (e12._nesting == 0 && !e12.hasPendingMicrotasks && !e12.isStable) try { - e6._nesting++, e6.onMicrotaskEmpty.emit(null); + e12._nesting++, e12.onMicrotaskEmpty.emit(null); } finally { - if (e6._nesting--, !e6.hasPendingMicrotasks) + if (e12._nesting--, !e12.hasPendingMicrotasks) try { - e6.runOutsideAngular(() => e6.onStable.emit(null)); + e12.runOutsideAngular(() => e12.onStable.emit(null)); } finally { - e6.isStable = true; + e12.isStable = true; } } } -function Wl(e6) { - if (e6.isCheckStableRunning || e6.callbackScheduled) +function qd(e12) { + if (e12.isCheckStableRunning || e12.callbackScheduled) return; - e6.callbackScheduled = true; + e12.callbackScheduled = true; function t() { - Do(() => { - e6.callbackScheduled = false, jr(e6), e6.isCheckStableRunning = true, Co(e6), e6.isCheckStableRunning = false; + xi(() => { + e12.callbackScheduled = false, Yo(e12), e12.isCheckStableRunning = true, Ri(e12), e12.isCheckStableRunning = false; }); } - e6.scheduleInRootZone ? Zone.root.run(() => { + e12.scheduleInRootZone ? Zone.root.run(() => { t(); - }) : e6._outer.run(() => { + }) : e12._outer.run(() => { t(); - }), jr(e6); + }), Yo(e12); } -function Gl(e6) { +function Zd(e12) { let t = () => { - Wl(e6); - }, n = Ul++; - e6._inner = e6._inner.fork({ name: "angular", properties: { [wo]: true, [ct]: n, [ct + n]: true }, onInvokeTask: (r, o, i, s, a, c) => { - if (ql(c)) + qd(e12); + }, n = Wd++; + e12._inner = e12._inner.fork({ name: "angular", properties: { [Ai]: true, [qt]: n, [qt + n]: true }, onInvokeTask: (r, o, i, s, a, c) => { + if (Qd(c)) return r.invokeTask(i, s, a, c); try { - return ds(e6), r.invokeTask(i, s, a, c); + return Za(e12), r.invokeTask(i, s, a, c); } finally { - (e6.shouldCoalesceEventChangeDetection && s.type === "eventTask" || e6.shouldCoalesceRunChangeDetection) && t(), fs(e6); + (e12.shouldCoalesceEventChangeDetection && s.type === "eventTask" || e12.shouldCoalesceRunChangeDetection) && t(), Qa(e12); } }, onInvoke: (r, o, i, s, a, c, l) => { try { - return ds(e6), r.invoke(i, s, a, c, l); + return Za(e12), r.invoke(i, s, a, c, l); } finally { - e6.shouldCoalesceRunChangeDetection && !e6.callbackScheduled && !Zl(c) && t(), fs(e6); + e12.shouldCoalesceRunChangeDetection && !e12.callbackScheduled && !Yd(c) && t(), Qa(e12); } }, onHasTask: (r, o, i, s) => { - r.hasTask(i, s), o === i && (s.change == "microTask" ? (e6._hasPendingMicrotasks = s.microTask, jr(e6), Co(e6)) : s.change == "macroTask" && (e6.hasPendingMacrotasks = s.macroTask)); - }, onHandleError: (r, o, i, s) => (r.handleError(i, s), e6.runOutsideAngular(() => e6.onError.emit(s)), false) }); + r.hasTask(i, s), o === i && (s.change == "microTask" ? (e12._hasPendingMicrotasks = s.microTask, Yo(e12), Ri(e12)) : s.change == "macroTask" && (e12.hasPendingMacrotasks = s.macroTask)); + }, onHandleError: (r, o, i, s) => (r.handleError(i, s), e12.runOutsideAngular(() => e12.onError.emit(s)), false) }); } -function jr(e6) { - e6._hasPendingMicrotasks || (e6.shouldCoalesceEventChangeDetection || e6.shouldCoalesceRunChangeDetection) && e6.callbackScheduled === true ? e6.hasPendingMicrotasks = true : e6.hasPendingMicrotasks = false; +function Yo(e12) { + e12._hasPendingMicrotasks || (e12.shouldCoalesceEventChangeDetection || e12.shouldCoalesceRunChangeDetection) && e12.callbackScheduled === true ? e12.hasPendingMicrotasks = true : e12.hasPendingMicrotasks = false; } -function ds(e6) { - e6._nesting++, e6.isStable && (e6.isStable = false, e6.onUnstable.emit(null)); +function Za(e12) { + e12._nesting++, e12.isStable && (e12.isStable = false, e12.onUnstable.emit(null)); } -function fs(e6) { - e6._nesting--, Co(e6); +function Qa(e12) { + e12._nesting--, Ri(e12); } -var lt = class { +var Zt = class { hasPendingMicrotasks = false; hasPendingMacrotasks = false; isStable = true; - onUnstable = new J(); - onMicrotaskEmpty = new J(); - onStable = new J(); - onError = new J(); + onUnstable = new ve(); + onMicrotaskEmpty = new ve(); + onStable = new ve(); + onError = new ve(); run(t, n, r) { return t.apply(n, r); } @@ -1747,77 +1898,91 @@ var lt = class { return t.apply(n, r); } }; -function ql(e6) { - return Xs(e6, "__ignore_ng_zone__"); +function Qd(e12) { + return zc(e12, "__ignore_ng_zone__"); } -function Zl(e6) { - return Xs(e6, "__scheduler_tick__"); +function Yd(e12) { + return zc(e12, "__scheduler_tick__"); } -function Xs(e6, t) { - return !Array.isArray(e6) || e6.length !== 1 ? false : e6[0]?.data?.[t] === true; +function zc(e12, t) { + return !Array.isArray(e12) || e12.length !== 1 ? false : e12[0]?.data?.[t] === true; } -var te = class { +var Ie = class { _console = console; handleError(t) { this._console.error("ERROR", t); } }; -var Ke = new m("", { factory: () => { - let e6 = E(j), t = E($), n; +var rt = new D("", { factory: () => { + let e12 = E(Y), t = E(Q), n; return (r) => { - e6.runOutsideAngular(() => { + e12.runOutsideAngular(() => { t.destroyed && !n ? setTimeout(() => { throw r; - }) : (n ??= t.get(te), n.handleError(r)); + }) : (n ??= t.get(Ie), n.handleError(r)); }); }; } }); -var ea = { provide: be, useValue: () => { - let e6 = E(te, { optional: true }); +var Wc = { provide: Je, useValue: () => { + let e12 = E(Ie, { optional: true }); }, multi: true }; -var Ql = new m("", { factory: () => { - let e6 = E(x).defaultView; - if (!e6) +var Kd = new D("", { factory: () => { + let e12 = E(U).defaultView; + if (!e12) return; - let t = E(Ke), n = (i) => { + let t = E(rt), n = (i) => { t(i.reason), i.preventDefault(); }, r = (i) => { i.error ? t(i.error) : t(new Error(i.message, { cause: i })), i.preventDefault(); }, o = () => { - e6.addEventListener("unhandledrejection", n), e6.addEventListener("error", r); + e12.addEventListener("unhandledrejection", n), e12.addEventListener("error", r); }; - typeof Zone < "u" ? Zone.root.run(o) : o(), E(wt).onDestroy(() => { - e6.removeEventListener("error", r), e6.removeEventListener("unhandledrejection", n); + typeof Zone < "u" ? Zone.root.run(o) : o(), E(xt).onDestroy(() => { + e12.removeEventListener("error", r), e12.removeEventListener("unhandledrejection", n); }); } }); -function To() { - return dt([vs(() => { - E(Ql); +function Oi() { + return Dt([ic(() => { + E(Kd); })]); } -function Ct(e6, t) { - let [n, r, o] = gr(e6, t?.equal), i = n, s = i[W]; - return i.set = r, i.update = o, i.asReadonly = ta.bind(i), i; +function q(e12, t) { + let [n, r, o] = Mo(e12, t?.equal), i = n, s = i[Z]; + return i.set = r, i.update = o, i.asReadonly = Gc.bind(i), i; } -function ta() { - let e6 = this[W]; - if (e6.readonlyFn === void 0) { +function Gc() { + let e12 = this[Z]; + if (e12.readonlyFn === void 0) { let t = () => this(); - t[W] = e6, e6.readonlyFn = t; + t[Z] = e12, e12.readonlyFn = t; + } + return e12.readonlyFn; +} +var hr = /* @__PURE__ */ (() => { + class e12 { + view; + node; + constructor(n, r) { + this.view = n, this.node = r; + } + static __NG_ELEMENT_ID__ = Jd; } - return e6.readonlyFn; + return e12; +})(); +function Jd() { + return new hr(M(), pe()); } -var Ue = class { +var Ze = class { }; -var Tt = new m("", { factory: () => true }); -var Mo = new m(""); -var So = (() => { - class e6 { - static \u0275prov = S({ token: e6, providedIn: "root", factory: () => new Hr() }); +var tn = new D("", { factory: () => true }); +var ki = new D(""); +var gr = (() => { + class e12 { + static \u0275prov = _({ token: e12, providedIn: "root", factory: () => new Ko() }); } - return e6; + return e12; })(); -var Hr = class { +var Ko = class { dirtyEffectCount = 0; queues = /* @__PURE__ */ new Map(); add(t) { @@ -1851,22 +2016,76 @@ var Hr = class { return n; } }; -var Vr = class { - [W]; +var Gn = class { + [Z]; constructor(t) { - this[W] = t; + this[Z] = t; } destroy() { - this[W].destroy(); + this[Z].destroy(); } }; -function Ma(e6) { - return { toString: e6 }.toString(); +function Pi(e12, t) { + let n = t?.injector ?? E(ce), r = t?.manualCleanup !== true ? n.get(xt) : null, o, i = n.get(hr, null, { optional: true }), s = n.get(Ze); + return i !== null ? (o = tf(i.view, s, e12), r instanceof zn && r._lView === i.view && (r = null)) : o = nf(e12, n.get(gr), s), o.injector = n, r !== null && (o.onDestroyFns = [r.onDestroy(() => o.destroy())]), new Gn(o); +} +var qc = A(N({}, So), { cleanupFns: void 0, zone: null, onDestroyFns: null, run() { + let e12 = Gt(false); + try { + No(this); + } finally { + Gt(e12); + } +}, cleanup() { + if (!this.cleanupFns?.length) + return; + let e12 = g(null); + try { + for (; this.cleanupFns.length; ) + this.cleanupFns.pop()(); + } finally { + this.cleanupFns = [], g(e12); + } +} }); +var Xd = A(N({}, qc), { consumerMarkedDirty() { + this.scheduler.schedule(this), this.notifier.notify(12); +}, destroy() { + if (dt(this), this.onDestroyFns !== null) + for (let e12 of this.onDestroyFns) + e12(); + this.cleanup(), this.scheduler.remove(this); +} }); +var ef = A(N({}, qc), { consumerMarkedDirty() { + this.view[y] |= 8192, St(this.view), this.notifier.notify(13); +}, destroy() { + if (dt(this), this.onDestroyFns !== null) + for (let e12 of this.onDestroyFns) + e12(); + this.cleanup(), this.view[xe]?.delete(this); +} }); +function tf(e12, t, n) { + let r = Object.create(ef); + return r.view = e12, r.zone = typeof Zone < "u" ? Zone.current : null, r.notifier = t, r.fn = Zc(r, n), e12[xe] ??= /* @__PURE__ */ new Set(), e12[xe].add(r), r.consumerMarkedDirty(r), r; +} +function nf(e12, t, n) { + let r = Object.create(Xd); + return r.fn = Zc(r, e12), r.scheduler = t, r.notifier = n, r.zone = typeof Zone < "u" ? Zone.current : null, r.scheduler.add(r), r.notifier.notify(12), r; } -function Sa(e6, t, n, r) { - t !== null ? t.applyValueToInputSignal(t, r) : e6[n] = r; +function Zc(e12, t) { + return () => { + t((n) => (e12.cleanupFns ??= []).push(n)); + }; +} +function Tl(e12) { + return { toString: e12 }.toString(); +} +function vf(e12) { + return typeof e12 == "function"; +} +function Ml(e12, t, n, r) { + t !== null ? t.applyValueToInputSignal(t, r) : e12[n] = r; } -var Rn = class { +var br = class { previousValue; currentValue; firstChange; @@ -1877,90 +2096,90 @@ var Rn = class { return this.firstChange; } }; -function fu(e6) { - return e6.type.prototype.ngOnChanges && (e6.setInput = hu), pu; +function Ef(e12) { + return e12.type.prototype.ngOnChanges && (e12.setInput = Df), If; } -function pu() { - let e6 = _a(this), t = e6?.current; +function If() { + let e12 = Sl(this), t = e12?.current; if (t) { - let n = e6.previous; - if (n === Se) - e6.previous = t; + let n = e12.previous; + if (n === Ke) + e12.previous = t; else for (let r in t) n[r] = t[r]; - e6.current = null, this.ngOnChanges(t); + e12.current = null, this.ngOnChanges(t); } } -function hu(e6, t, n, r, o) { - let i = this.declaredInputs[r], s = _a(e6) || gu(e6, { previous: Se, current: null }), a = s.current || (s.current = {}), c = s.previous, l = c[i]; - a[i] = new Rn(l && l.currentValue, n, c === Se), Sa(e6, t, o, n); +function Df(e12, t, n, r, o) { + let i = this.declaredInputs[r], s = Sl(e12) || wf(e12, { previous: Ke, current: null }), a = s.current || (s.current = {}), c = s.previous, l = c[i]; + a[i] = new br(l && l.currentValue, n, c === Ke), Ml(e12, t, o, n); } -var ba = "__ngSimpleChanges__"; -function _a(e6) { - return e6[ba] || null; +var _l = "__ngSimpleChanges__"; +function Sl(e12) { + return e12[_l] || null; } -function gu(e6, t) { - return e6[ba] = t; +function wf(e12, t) { + return e12[_l] = t; } -var na = []; -var M = function(e6, t = null, n) { - for (let r = 0; r < na.length; r++) { - let o = na[r]; - o(e6, t, n); +var Qc = []; +var T = function(e12, t = null, n) { + for (let r = 0; r < Qc.length; r++) { + let o = Qc[r]; + o(e12, t, n); } }; -var w = function(e6) { - return e6[e6.TemplateCreateStart = 0] = "TemplateCreateStart", e6[e6.TemplateCreateEnd = 1] = "TemplateCreateEnd", e6[e6.TemplateUpdateStart = 2] = "TemplateUpdateStart", e6[e6.TemplateUpdateEnd = 3] = "TemplateUpdateEnd", e6[e6.LifecycleHookStart = 4] = "LifecycleHookStart", e6[e6.LifecycleHookEnd = 5] = "LifecycleHookEnd", e6[e6.OutputStart = 6] = "OutputStart", e6[e6.OutputEnd = 7] = "OutputEnd", e6[e6.BootstrapApplicationStart = 8] = "BootstrapApplicationStart", e6[e6.BootstrapApplicationEnd = 9] = "BootstrapApplicationEnd", e6[e6.BootstrapComponentStart = 10] = "BootstrapComponentStart", e6[e6.BootstrapComponentEnd = 11] = "BootstrapComponentEnd", e6[e6.ChangeDetectionStart = 12] = "ChangeDetectionStart", e6[e6.ChangeDetectionEnd = 13] = "ChangeDetectionEnd", e6[e6.ChangeDetectionSyncStart = 14] = "ChangeDetectionSyncStart", e6[e6.ChangeDetectionSyncEnd = 15] = "ChangeDetectionSyncEnd", e6[e6.AfterRenderHooksStart = 16] = "AfterRenderHooksStart", e6[e6.AfterRenderHooksEnd = 17] = "AfterRenderHooksEnd", e6[e6.ComponentStart = 18] = "ComponentStart", e6[e6.ComponentEnd = 19] = "ComponentEnd", e6[e6.DeferBlockStateStart = 20] = "DeferBlockStateStart", e6[e6.DeferBlockStateEnd = 21] = "DeferBlockStateEnd", e6[e6.DynamicComponentStart = 22] = "DynamicComponentStart", e6[e6.DynamicComponentEnd = 23] = "DynamicComponentEnd", e6[e6.HostBindingsUpdateStart = 24] = "HostBindingsUpdateStart", e6[e6.HostBindingsUpdateEnd = 25] = "HostBindingsUpdateEnd", e6; -}(w || {}); -function mu(e6, t, n) { +var C = function(e12) { + return e12[e12.TemplateCreateStart = 0] = "TemplateCreateStart", e12[e12.TemplateCreateEnd = 1] = "TemplateCreateEnd", e12[e12.TemplateUpdateStart = 2] = "TemplateUpdateStart", e12[e12.TemplateUpdateEnd = 3] = "TemplateUpdateEnd", e12[e12.LifecycleHookStart = 4] = "LifecycleHookStart", e12[e12.LifecycleHookEnd = 5] = "LifecycleHookEnd", e12[e12.OutputStart = 6] = "OutputStart", e12[e12.OutputEnd = 7] = "OutputEnd", e12[e12.BootstrapApplicationStart = 8] = "BootstrapApplicationStart", e12[e12.BootstrapApplicationEnd = 9] = "BootstrapApplicationEnd", e12[e12.BootstrapComponentStart = 10] = "BootstrapComponentStart", e12[e12.BootstrapComponentEnd = 11] = "BootstrapComponentEnd", e12[e12.ChangeDetectionStart = 12] = "ChangeDetectionStart", e12[e12.ChangeDetectionEnd = 13] = "ChangeDetectionEnd", e12[e12.ChangeDetectionSyncStart = 14] = "ChangeDetectionSyncStart", e12[e12.ChangeDetectionSyncEnd = 15] = "ChangeDetectionSyncEnd", e12[e12.AfterRenderHooksStart = 16] = "AfterRenderHooksStart", e12[e12.AfterRenderHooksEnd = 17] = "AfterRenderHooksEnd", e12[e12.ComponentStart = 18] = "ComponentStart", e12[e12.ComponentEnd = 19] = "ComponentEnd", e12[e12.DeferBlockStateStart = 20] = "DeferBlockStateStart", e12[e12.DeferBlockStateEnd = 21] = "DeferBlockStateEnd", e12[e12.DynamicComponentStart = 22] = "DynamicComponentStart", e12[e12.DynamicComponentEnd = 23] = "DynamicComponentEnd", e12[e12.HostBindingsUpdateStart = 24] = "HostBindingsUpdateStart", e12[e12.HostBindingsUpdateEnd = 25] = "HostBindingsUpdateEnd", e12; +}(C || {}); +function Cf(e12, t, n) { let { ngOnChanges: r, ngOnInit: o, ngDoCheck: i } = t.type.prototype; if (r) { - let s = fu(t); - (n.preOrderHooks ??= []).push(e6, s), (n.preOrderCheckHooks ??= []).push(e6, s); + let s = Ef(t); + (n.preOrderHooks ??= []).push(e12, s), (n.preOrderCheckHooks ??= []).push(e12, s); } - o && (n.preOrderHooks ??= []).push(0 - e6, o), i && ((n.preOrderHooks ??= []).push(e6, i), (n.preOrderCheckHooks ??= []).push(e6, i)); + o && (n.preOrderHooks ??= []).push(0 - e12, o), i && ((n.preOrderHooks ??= []).push(e12, i), (n.preOrderCheckHooks ??= []).push(e12, i)); } -function yu(e6, t) { +function bf(e12, t) { for (let n = t.directiveStart, r = t.directiveEnd; n < r; n++) { - let i = e6.data[n].type.prototype, { ngAfterContentInit: s, ngAfterContentChecked: a, ngAfterViewInit: c, ngAfterViewChecked: l, ngOnDestroy: u } = i; - s && (e6.contentHooks ??= []).push(-n, s), a && ((e6.contentHooks ??= []).push(n, a), (e6.contentCheckHooks ??= []).push(n, a)), c && (e6.viewHooks ??= []).push(-n, c), l && ((e6.viewHooks ??= []).push(n, l), (e6.viewCheckHooks ??= []).push(n, l)), u != null && (e6.destroyHooks ??= []).push(n, u); + let i = e12.data[n].type.prototype, { ngAfterContentInit: s, ngAfterContentChecked: a, ngAfterViewInit: c, ngAfterViewChecked: l, ngOnDestroy: u } = i; + s && (e12.contentHooks ??= []).push(-n, s), a && ((e12.contentHooks ??= []).push(n, a), (e12.contentCheckHooks ??= []).push(n, a)), c && (e12.viewHooks ??= []).push(-n, c), l && ((e12.viewHooks ??= []).push(n, l), (e12.viewCheckHooks ??= []).push(n, l)), u != null && (e12.destroyHooks ??= []).push(n, u); } } -function Nn(e6, t, n) { - Na(e6, t, 3, n); +function Ir(e12, t, n) { + Nl(e12, t, 3, n); } -function xn(e6, t, n, r) { - (e6[h] & 3) === n && Na(e6, t, n, r); +function Dr(e12, t, n, r) { + (e12[y] & 3) === n && Nl(e12, t, n, r); } -function bo(e6, t) { - let n = e6[h]; - (n & 3) === t && (n &= 16383, n += 1, e6[h] = n); +function Li(e12, t) { + let n = e12[y]; + (n & 3) === t && (n &= 16383, n += 1, e12[y] = n); } -function Na(e6, t, n, r) { - let o = r !== void 0 ? e6[Ne] & 65535 : 0, i = r ?? -1, s = t.length - 1, a = 0; +function Nl(e12, t, n, r) { + let o = r !== void 0 ? e12[et] & 65535 : 0, i = r ?? -1, s = t.length - 1, a = 0; for (let c = o; c < s; c++) if (typeof t[c + 1] == "number") { if (a = t[c], r != null && a >= r) break; } else - t[c] < 0 && (e6[Ne] += 65536), (a < i || i == -1) && (vu(e6, n, t, c), e6[Ne] = (e6[Ne] & 4294901760) + c + 2), c++; + t[c] < 0 && (e12[et] += 65536), (a < i || i == -1) && (Tf(e12, n, t, c), e12[et] = (e12[et] & 4294901760) + c + 2), c++; } -function ra(e6, t) { - M(w.LifecycleHookStart, e6, t); - let n = v(null); +function Yc(e12, t) { + T(C.LifecycleHookStart, e12, t); + let n = g(null); try { - t.call(e6); + t.call(e12); } finally { - v(n), M(w.LifecycleHookEnd, e6, t); + g(n), T(C.LifecycleHookEnd, e12, t); } } -function vu(e6, t, n, r) { - let o = n[r] < 0, i = n[r + 1], s = o ? -n[r] : n[r], a = e6[s]; - o ? e6[h] >> 14 < e6[Ne] >> 16 && (e6[h] & 3) === t && (e6[h] += 16384, ra(a, i)) : ra(a, i); +function Tf(e12, t, n, r) { + let o = n[r] < 0, i = n[r + 1], s = o ? -n[r] : n[r], a = e12[s]; + o ? e12[y] >> 14 < e12[et] >> 16 && (e12[y] & 3) === t && (e12[y] += 16384, Yc(a, i)) : Yc(a, i); } -var Xe = -1; -var bt = class { +var Ot = -1; +var sn = class { factory; name; injectImpl; @@ -1974,7 +2193,7 @@ var bt = class { this.factory = t, this.name = o, this.canSeeViewProviders = n, this.injectImpl = r; } }; -function Eu(e6, t, n) { +function Mf(e12, t, n) { let r = 0; for (; r < n.length; ) { let o = n[r]; @@ -1983,37 +2202,37 @@ function Eu(e6, t, n) { break; r++; let i = n[r++], s = n[r++], a = n[r++]; - e6.setAttribute(t, s, a, i); + e12.setAttribute(t, s, a, i); } else { let i = o, s = n[++r]; - Iu(i) ? e6.setProperty(t, i, s) : e6.setAttribute(t, i, s), r++; + _f(i) ? e12.setProperty(t, i, s) : e12.setAttribute(t, i, s), r++; } } return r; } -function Iu(e6) { - return e6.charCodeAt(0) === 64; +function _f(e12) { + return e12.charCodeAt(0) === 64; } -function ti(e6, t) { +function Fr(e12, t) { if (!(t === null || t.length === 0)) - if (e6 === null || e6.length === 0) - e6 = t.slice(); + if (e12 === null || e12.length === 0) + e12 = t.slice(); else { let n = -1; for (let r = 0; r < t.length; r++) { let o = t[r]; - typeof o == "number" ? n = o : n === 0 || (n === -1 || n === 2 ? oa(e6, n, o, null, t[++r]) : oa(e6, n, o, null, null)); + typeof o == "number" ? n = o : n === 0 || (n === -1 || n === 2 ? Kc(e12, n, o, null, t[++r]) : Kc(e12, n, o, null, null)); } } - return e6; + return e12; } -function oa(e6, t, n, r, o) { - let i = 0, s = e6.length; +function Kc(e12, t, n, r, o) { + let i = 0, s = e12.length; if (t === -1) s = -1; else - for (; i < e6.length; ) { - let a = e6[i++]; + for (; i < e12.length; ) { + let a = e12[i++]; if (typeof a == "number") { if (a === t) { s = -1; @@ -2024,438 +2243,520 @@ function oa(e6, t, n, r, o) { } } } - for (; i < e6.length; ) { - let a = e6[i]; + for (; i < e12.length; ) { + let a = e12[i]; if (typeof a == "number") break; if (a === n) { - o !== null && (e6[i + 1] = o); + o !== null && (e12[i + 1] = o); return; } i++, o !== null && i++; } - s !== -1 && (e6.splice(s, 0, t), i = s + 1), e6.splice(i++, 0, n), o !== null && e6.splice(i++, 0, o); + s !== -1 && (e12.splice(s, 0, t), i = s + 1), e12.splice(i++, 0, n), o !== null && e12.splice(i++, 0, o); } -function Du(e6) { - return e6 !== Xe; +function xl(e12) { + return e12 !== Ot; } -function xo(e6) { - return e6 & 32767; +function Tr(e12) { + return e12 & 32767; } -function wu(e6) { - return e6 >> 16; +function Sf(e12) { + return e12 >> 16; } -function Ao(e6, t) { - let n = wu(e6), r = t; +function Mr(e12, t) { + let n = Sf(e12), r = t; for (; n > 0; ) - r = r[We], n--; + r = r[Xe], n--; return r; } -var Ro = true; -function ia(e6) { - let t = Ro; - return Ro = e6, t; -} -var Cu = 256; -var xa = Cu - 1; -var Aa = 5; -var Tu = 0; -var Y = {}; -function Mu(e6, t, n) { +var Ui = true; +function Jc(e12) { + let t = Ui; + return Ui = e12, t; +} +var Nf = 256; +var Al = Nf - 1; +var Rl = 5; +var xf = 0; +var he = {}; +function Af(e12, t, n) { let r; - typeof n == "string" ? r = n.charCodeAt(0) || 0 : n.hasOwnProperty(Me) && (r = n[Me]), r == null && (r = n[Me] = Tu++); - let o = r & xa, i = 1 << o; - t.data[e6 + (o >> Aa)] |= i; + typeof n == "string" ? r = n.charCodeAt(0) || 0 : n.hasOwnProperty(Qe) && (r = n[Qe]), r == null && (r = n[Qe] = xf++); + let o = r & Al, i = 1 << o; + t.data[e12 + (o >> Rl)] |= i; } -function Ra(e6, t) { - let n = ka(e6, t); +function Ol(e12, t) { + let n = kl(e12, t); if (n !== -1) return n; - let r = t[y]; - r.firstCreatePass && (e6.injectorIndex = t.length, _o(r.data, e6), _o(t, null), _o(r.blueprint, null)); - let o = Oa(e6, t), i = e6.injectorIndex; - if (Du(o)) { - let s = xo(o), a = Ao(o, t), c = a[y].data; + let r = t[m]; + r.firstCreatePass && (e12.injectorIndex = t.length, Fi(r.data, e12), Fi(t, null), Fi(r.blueprint, null)); + let o = _s(e12, t), i = e12.injectorIndex; + if (xl(o)) { + let s = Tr(o), a = Mr(o, t), c = a[m].data; for (let l = 0; l < 8; l++) t[i + l] = a[s + l] | c[s + l]; } return t[i + 8] = o, i; } -function _o(e6, t) { - e6.push(0, 0, 0, 0, 0, 0, 0, 0, t); +function Fi(e12, t) { + e12.push(0, 0, 0, 0, 0, 0, 0, 0, t); } -function ka(e6, t) { - return e6.injectorIndex === -1 || e6.parent && e6.parent.injectorIndex === e6.injectorIndex || t[e6.injectorIndex + 8] === null ? -1 : e6.injectorIndex; +function kl(e12, t) { + return e12.injectorIndex === -1 || e12.parent && e12.parent.injectorIndex === e12.injectorIndex || t[e12.injectorIndex + 8] === null ? -1 : e12.injectorIndex; } -function Oa(e6, t) { - if (e6.parent && e6.parent.injectorIndex !== -1) - return e6.parent.injectorIndex; +function _s(e12, t) { + if (e12.parent && e12.parent.injectorIndex !== -1) + return e12.parent.injectorIndex; let n = 0, r = null, o = t; for (; o !== null; ) { - if (r = Ha(o), r === null) - return Xe; - if (n++, o = o[We], r.injectorIndex !== -1) + if (r = Hl(o), r === null) + return Ot; + if (n++, o = o[Xe], r.injectorIndex !== -1) return r.injectorIndex | n << 16; } - return Xe; + return Ot; } -function Su(e6, t, n) { - Mu(e6, t, n); +function Rf(e12, t, n) { + Af(e12, t, n); } -function La(e6, t, n) { - if (n & 8 || e6 !== void 0) - return e6; - dn(t, "NodeInjector"); +function Pl(e12, t, n) { + if (n & 8 || e12 !== void 0) + return e12; + Xn(t, "NodeInjector"); } -function Pa(e6, t, n, r) { +function Ll(e12, t, n, r) { if (n & 8 && r === void 0 && (r = null), (n & 3) === 0) { - let o = e6[_e], i = R(void 0); + let o = e12[De], i = z(void 0); try { - return o ? o.get(t, r, n & 8) : Yr(t, r, n & 8); + return o ? o.get(t, r, n & 8) : ai(t, r, n & 8); } finally { - R(i); + z(i); } } - return La(r, t, n); + return Pl(r, t, n); } -function Fa(e6, t, n, r = 0, o) { - if (e6 !== null) { - if (t[h] & 2048 && !(r & 2)) { - let s = Au(e6, t, n, r, Y); - if (s !== Y) +function Fl(e12, t, n, r = 0, o) { + if (e12 !== null) { + if (t[y] & 2048 && !(r & 2)) { + let s = Lf(e12, t, n, r, he); + if (s !== he) return s; } - let i = ja(e6, t, n, r, Y); - if (i !== Y) + let i = jl(e12, t, n, r, he); + if (i !== he) return i; } - return Pa(t, n, r, o); + return Ll(t, n, r, o); } -function ja(e6, t, n, r, o) { - let i = Nu(n); +function jl(e12, t, n, r, o) { + let i = kf(n); if (typeof i == "function") { - if (!yo(t, e6, r)) - return r & 1 ? La(o, n, r) : Pa(t, n, r, o); + if (!Si(t, e12, r)) + return r & 1 ? Pl(o, n, r) : Ll(t, n, r, o); try { let s; if (s = i(r), s == null && !(r & 8)) - dn(n); + Xn(n); else return s; } finally { - vo(); + Ni(); } } else if (typeof i == "number") { - let s = null, a = ka(e6, t), c = Xe, l = r & 1 ? t[Q][re] : null; - for ((a === -1 || r & 4) && (c = a === -1 ? Oa(e6, t) : t[a + 8], c === Xe || !aa(r, false) ? a = -1 : (s = t[y], a = xo(c), t = Ao(c, t))); a !== -1; ) { - let u = t[y]; - if (sa(i, a, u.data)) { - let d = bu(a, t, n, s, r, l); - if (d !== Y) + let s = null, a = kl(e12, t), c = Ot, l = r & 1 ? t[X][J] : null; + for ((a === -1 || r & 4) && (c = a === -1 ? _s(e12, t) : t[a + 8], c === Ot || !el(r, false) ? a = -1 : (s = t[m], a = Tr(c), t = Mr(c, t))); a !== -1; ) { + let u = t[m]; + if (Xc(i, a, u.data)) { + let d = Of(a, t, n, s, r, l); + if (d !== he) return d; } - c = t[a + 8], c !== Xe && aa(r, t[y].data[a + 8] === l) && sa(i, a, t) ? (s = u, a = xo(c), t = Ao(c, t)) : a = -1; + c = t[a + 8], c !== Ot && el(r, t[m].data[a + 8] === l) && Xc(i, a, t) ? (s = u, a = Tr(c), t = Mr(c, t)) : a = -1; } } return o; } -function bu(e6, t, n, r, o, i) { - let s = t[y], a = s.data[e6 + 8], c = r == null ? yt(a) && Ro : r != s && (a.type & 3) !== 0, l = o & 1 && i === a, u = _u(a, s, n, c, l); - return u !== null ? ko(t, s, u, a, o) : Y; +function Of(e12, t, n, r, o, i) { + let s = t[m], a = s.data[e12 + 8], c = r == null ? Tt(a) && Ui : r != s && (a.type & 3) !== 0, l = o & 1 && i === a, u = wr(a, s, n, c, l); + return u !== null ? _r(t, s, u, a, o) : he; } -function _u(e6, t, n, r, o) { - let i = e6.providerIndexes, s = t.data, a = i & 1048575, c = e6.directiveStart, l = e6.directiveEnd, u = i >> 20, d = r ? a : a + u, p = o ? a + u : l; - for (let f = d; f < p; f++) { - let T = s[f]; - if (f < c && n === T || f >= c && T.type === n) - return f; +function wr(e12, t, n, r, o) { + let i = e12.providerIndexes, s = t.data, a = i & 1048575, c = e12.directiveStart, l = e12.directiveEnd, u = i >> 20, d = r ? a : a + u, f = o ? a + u : l; + for (let p = d; p < f; p++) { + let h = s[p]; + if (p < c && n === h || p >= c && h.type === n) + return p; } if (o) { - let f = s[c]; - if (f && qe(f) && f.type === n) + let p = s[c]; + if (p && Mt(p) && p.type === n) return c; } return null; } -function ko(e6, t, n, r, o) { - let i = e6[n], s = t.data; - if (i instanceof bt) { +function _r(e12, t, n, r, o) { + let i = e12[n], s = t.data; + if (i instanceof sn) { let a = i; if (a.resolving) - throw Qr(""); - let c = ia(a.canSeeViewProviders); + throw si(""); + let c = Jc(a.canSeeViewProviders); a.resolving = true; - let l = s[n].type || s[n], u, d = a.injectImpl ? R(a.injectImpl) : null, p = yo(e6, r, 0); + let l = s[n].type || s[n], u, d = a.injectImpl ? z(a.injectImpl) : null, f = Si(e12, r, 0); try { - i = e6[n] = a.factory(void 0, o, s, e6, r), t.firstCreatePass && n >= r.directiveStart && mu(n, s[n], t); + i = e12[n] = a.factory(void 0, o, s, e12, r), t.firstCreatePass && n >= r.directiveStart && Cf(n, s[n], t); } finally { - d !== null && R(d), ia(c), a.resolving = false, vo(); + d !== null && z(d), Jc(c), a.resolving = false, Ni(); } } return i; } -function Nu(e6) { - if (typeof e6 == "string") - return e6.charCodeAt(0) || 0; - let t = e6.hasOwnProperty(Me) ? e6[Me] : void 0; - return typeof t == "number" ? t >= 0 ? t & xa : xu : t; +function kf(e12) { + if (typeof e12 == "string") + return e12.charCodeAt(0) || 0; + let t = e12.hasOwnProperty(Qe) ? e12[Qe] : void 0; + return typeof t == "number" ? t >= 0 ? t & Al : Pf : t; } -function sa(e6, t, n) { - let r = 1 << e6; - return !!(n[t + (e6 >> Aa)] & r); +function Xc(e12, t, n) { + let r = 1 << e12; + return !!(n[t + (e12 >> Rl)] & r); } -function aa(e6, t) { - return !(e6 & 2) && !(e6 & 1 && t); +function el(e12, t) { + return !(e12 & 2) && !(e12 & 1 && t); } -var kn = class { +var ot = class { _tNode; _lView; constructor(t, n) { this._tNode = t, this._lView = n; } get(t, n, r) { - return Fa(this._tNode, this._lView, t, De(r), n); + return Fl(this._tNode, this._lView, t, Ge(r), n); } }; -function xu() { - return new kn(Qe(), H()); -} -function Au(e6, t, n, r, o) { - let i = e6, s = t; - for (; i !== null && s !== null && s[h] & 2048 && !Ze(s); ) { - let a = ja(i, s, n, r | 2, Y); - if (a !== Y) +function Pf() { + return new ot(pe(), M()); +} +function Lf(e12, t, n, r, o) { + let i = e12, s = t; + for (; i !== null && s !== null && s[y] & 2048 && !_t(s); ) { + let a = jl(i, s, n, r | 2, he); + if (a !== he) return a; let c = i.parent; if (!c) { - let l = s[ro]; + let l = s[hi]; if (l) { - let u = l.get(n, Y, r & -5); - if (u !== Y) + let u = l.get(n, he, r & -5); + if (u !== he) return u; } - c = Ha(s), s = s[We]; + c = Hl(s), s = s[Xe]; } i = c; } return o; } -function Ha(e6) { - let t = e6[y], n = t.type; - return n === 2 ? t.declTNode : n === 1 ? e6[re] : null; +function Hl(e12) { + let t = e12[m], n = t.type; + return n === 2 ? t.declTNode : n === 1 ? e12[J] : null; } -function Ru() { - return Va(Qe(), H()); +function Ff() { + return Ft(pe(), M()); } -function Va(e6, t) { - return new Ba(Ae(e6, t)); +function Ft(e12, t) { + return new hn(de(e12, t)); } -var Ba = /* @__PURE__ */ (() => { - class e6 { +var hn = /* @__PURE__ */ (() => { + class e12 { nativeElement; constructor(n) { this.nativeElement = n; } - static __NG_ELEMENT_ID__ = Ru; + static __NG_ELEMENT_ID__ = Ff; } - return e6; + return e12; })(); -function ku(e6) { - return (e6.flags & 128) === 128; +function jf(e12) { + return e12 instanceof hn ? e12.nativeElement : e12; +} +function Hf() { + return this._results[Symbol.iterator](); +} +var Sr = class { + _emitDistinctChangesOnly; + dirty = true; + _onDirty = void 0; + _results = []; + _changesDetected = false; + _changes = void 0; + length = 0; + first = void 0; + last = void 0; + get changes() { + return this._changes ??= new ye(); + } + constructor(t = false) { + this._emitDistinctChangesOnly = t; + } + get(t) { + return this._results[t]; + } + map(t) { + return this._results.map(t); + } + filter(t) { + return this._results.filter(t); + } + find(t) { + return this._results.find(t); + } + reduce(t, n) { + return this._results.reduce(t, n); + } + forEach(t) { + this._results.forEach(t); + } + some(t) { + return this._results.some(t); + } + toArray() { + return this._results.slice(); + } + toString() { + return this._results.toString(); + } + reset(t, n) { + this.dirty = false; + let r = nc(t); + (this._changesDetected = !tc(this._results, r, n)) && (this._results = r, this.length = r.length, this.last = r[this.length - 1], this.first = r[0]); + } + notifyOnChanges() { + this._changes !== void 0 && (this._changesDetected || !this._emitDistinctChangesOnly) && this._changes.next(this); + } + onDirty(t) { + this._onDirty = t; + } + setDirty() { + this.dirty = true, this._onDirty?.(); + } + destroy() { + this._changes !== void 0 && (this._changes.complete(), this._changes.unsubscribe()); + } + [Symbol.iterator] = Hf; +}; +function Vl(e12) { + return (e12.flags & 128) === 128; } -var ni = function(e6) { - return e6[e6.OnPush = 0] = "OnPush", e6[e6.Eager = 1] = "Eager", e6[e6.Default = 1] = "Default", e6; -}(ni || {}); -var $a = /* @__PURE__ */ new Map(); -var Ou = 0; -function Lu() { - return Ou++; +var Ss = function(e12) { + return e12[e12.OnPush = 0] = "OnPush", e12[e12.Eager = 1] = "Eager", e12[e12.Default = 1] = "Default", e12; +}(Ss || {}); +var Bl = /* @__PURE__ */ new Map(); +var Vf = 0; +function Bf() { + return Vf++; } -function Pu(e6) { - $a.set(e6[le], e6); +function $f(e12) { + Bl.set(e12[we], e12); } -function Oo(e6) { - $a.delete(e6[le]); +function zi(e12) { + Bl.delete(e12[we]); } -var ca = "__ngContext__"; -function _t(e6, t) { - ue(t) ? (e6[ca] = t[le], Pu(t)) : e6[ca] = t; +var tl = "__ngContext__"; +function kt(e12, t) { + Le(t) ? (e12[tl] = t[we], $f(t)) : e12[tl] = t; } -function Ua(e6) { - return Wa(e6[ze]); +function $l(e12) { + return zl(e12[bt]); } -function za(e6) { - return Wa(e6[ne]); +function Ul(e12) { + return zl(e12[K]); } -function Wa(e6) { - for (; e6 !== null && !de(e6); ) - e6 = e6[ne]; - return e6; +function zl(e12) { + for (; e12 !== null && !re(e12); ) + e12 = e12[K]; + return e12; } -var Lo; -function ri(e6) { - Lo = e6; +var Wi; +function Ns(e12) { + Wi = e12; } -function Ga() { - if (Lo !== void 0) - return Lo; +function Wl() { + if (Wi !== void 0) + return Wi; if (typeof document < "u") return document; - throw new g(210, false); -} -var Hn = new m("", { factory: () => Fu }); -var Fu = "ng"; -var Vn = new m(""); -var At = new m("", { providedIn: "platform", factory: () => "unknown" }); -var Bn = new m("", { factory: () => E(x).body?.querySelector("[ngCspNonce]")?.getAttribute("ngCspNonce") || null }); -var qa = false; -var Za = new m("", { factory: () => qa }); -function oi(e6) { - return (e6.flags & 32) === 32; -} -var ju = () => null; -function Qa(e6, t, n = false) { - return ju(e6, t, n); -} -function Ya(e6, t) { - let n = e6.contentQueries; + throw new v(210, false); +} +var jr = new D("", { factory: () => Uf }); +var Uf = "ng"; +var Hr = new D(""); +var gn = new D("", { providedIn: "platform", factory: () => "unknown" }); +var Vr = new D("", { factory: () => E(U).body?.querySelector("[ngCspNonce]")?.getAttribute("ngCspNonce") || null }); +var Gl = "r"; +var ql = "di"; +var Zl = false; +var Ql = new D("", { factory: () => Zl }); +var nl = /* @__PURE__ */ new WeakMap(); +function zf(e12, t) { + if (e12 == null || typeof e12 != "object") + return; + let n = nl.get(e12); + n || (n = /* @__PURE__ */ new WeakSet(), nl.set(e12, n)), n.add(t); +} +var Wf = (e12, t, n, r) => { +}; +function Gf(e12, t, n, r) { + Wf(e12, t, n, r); +} +function xs(e12) { + return (e12.flags & 32) === 32; +} +var qf = () => null; +function Yl(e12, t, n = false) { + return qf(e12, t, n); +} +function Kl(e12, t) { + let n = e12.contentQueries; if (n !== null) { - let r = v(null); + let r = g(null); try { for (let o = 0; o < n.length; o += 2) { let i = n[o], s = n[o + 1]; if (s !== -1) { - let a = e6.data[s]; - mo(i), a.contentQueries(2, t[s], s); + let a = e12.data[s]; + lr(i), a.contentQueries(2, t[s], s); } } } finally { - v(r); + g(r); } } } -function Po(e6, t, n) { - mo(0); - let r = v(null); +function Gi(e12, t, n) { + lr(0); + let r = g(null); try { - t(e6, n); + t(e12, n); } finally { - v(r); + g(r); } } -function Hu(e6, t, n) { - if (oo(t)) { - let r = v(null); +function Zf(e12, t, n) { + if (mi(t)) { + let r = g(null); try { let o = t.directiveStart, i = t.directiveEnd; for (let s = o; s < i; s++) { - let a = e6.data[s]; + let a = e12.data[s]; if (a.contentQueries) { let c = n[s]; a.contentQueries(1, c, s); } } } finally { - v(r); + g(r); } } } -var z = function(e6) { - return e6[e6.Emulated = 0] = "Emulated", e6[e6.None = 2] = "None", e6[e6.ShadowDom = 3] = "ShadowDom", e6[e6.ExperimentalIsolatedShadowDom = 4] = "ExperimentalIsolatedShadowDom", e6; -}(z || {}); -var Sn; -function Vu() { - if (Sn === void 0 && (Sn = null, ce.trustedTypes)) +var ie = function(e12) { + return e12[e12.Emulated = 0] = "Emulated", e12[e12.None = 2] = "None", e12[e12.ShadowDom = 3] = "ShadowDom", e12[e12.ExperimentalIsolatedShadowDom = 4] = "ExperimentalIsolatedShadowDom", e12; +}(ie || {}); +var mr; +function Qf() { + if (mr === void 0 && (mr = null, Re.trustedTypes)) try { - Sn = ce.trustedTypes.createPolicy("angular", { createHTML: (e6) => e6, createScript: (e6) => e6, createScriptURL: (e6) => e6 }); + mr = Re.trustedTypes.createPolicy("angular", { createHTML: (e12) => e12, createScript: (e12) => e12, createScriptURL: (e12) => e12 }); } catch { } - return Sn; + return mr; } -function $n(e6) { - return Vu()?.createHTML(e6) || e6; +function Br(e12) { + return Qf()?.createHTML(e12) || e12; } -var bn; -function Bu() { - if (bn === void 0 && (bn = null, ce.trustedTypes)) +var yr; +function Yf() { + if (yr === void 0 && (yr = null, Re.trustedTypes)) try { - bn = ce.trustedTypes.createPolicy("angular#unsafe-bypass", { createHTML: (e6) => e6, createScript: (e6) => e6, createScriptURL: (e6) => e6 }); + yr = Re.trustedTypes.createPolicy("angular#unsafe-bypass", { createHTML: (e12) => e12, createScript: (e12) => e12, createScriptURL: (e12) => e12 }); } catch { } - return bn; + return yr; } -function la(e6) { - return Bu()?.createHTML(e6) || e6; +function rl(e12) { + return Yf()?.createHTML(e12) || e12; } -var ie = class { +var be = class { changingThisBreaksApplicationSecurity; constructor(t) { this.changingThisBreaksApplicationSecurity = t; } toString() { - return `SafeValue must use [property]=binding: ${this.changingThisBreaksApplicationSecurity} (see ${sn})`; + return `SafeValue must use [property]=binding: ${this.changingThisBreaksApplicationSecurity} (see ${qn})`; } }; -var Fo = class extends ie { +var qi = class extends be { getTypeName() { return "HTML"; } }; -var jo = class extends ie { +var Zi = class extends be { getTypeName() { return "Style"; } }; -var Ho = class extends ie { +var Qi = class extends be { getTypeName() { return "Script"; } }; -var Vo = class extends ie { +var Yi = class extends be { getTypeName() { return "URL"; } }; -var Bo = class extends ie { +var Ki = class extends be { getTypeName() { return "ResourceURL"; } }; -function ge(e6) { - return e6 instanceof ie ? e6.changingThisBreaksApplicationSecurity : e6; +function Me(e12) { + return e12 instanceof be ? e12.changingThisBreaksApplicationSecurity : e12; } -function me(e6, t) { - let n = Ka(e6); +function He(e12, t) { + let n = Jl(e12); if (n != null && n !== t) { if (n === "ResourceURL" && t === "URL") return true; - throw new Error(`Required a safe ${t}, got a ${n} (see ${sn})`); + throw new Error(`Required a safe ${t}, got a ${n} (see ${qn})`); } return n === t; } -function Ka(e6) { - return e6 instanceof ie && e6.getTypeName() || null; +function Jl(e12) { + return e12 instanceof be && e12.getTypeName() || null; } -function ii(e6) { - return new Fo(e6); +function As(e12) { + return new qi(e12); } -function si(e6) { - return new jo(e6); +function Rs(e12) { + return new Zi(e12); } -function ai(e6) { - return new Ho(e6); +function Os(e12) { + return new Qi(e12); } -function ci(e6) { - return new Vo(e6); +function ks(e12) { + return new Yi(e12); } -function li(e6) { - return new Bo(e6); +function Ps(e12) { + return new Ki(e12); } -function $u(e6) { - let t = new Uo(e6); - return Uu() ? new $o(t) : t; +function Kf(e12) { + let t = new Xi(e12); + return Jf() ? new Ji(t) : t; } -var $o = class { +var Ji = class { inertDocumentHelper; constructor(t) { this.inertDocumentHelper = t; @@ -2463,14 +2764,14 @@ var $o = class { getInertBodyElement(t) { t = "" + t; try { - let n = new window.DOMParser().parseFromString($n(t), "text/html").body; + let n = new window.DOMParser().parseFromString(Br(t), "text/html").body; return n === null ? this.inertDocumentHelper.getInertBodyElement(t) : (n.firstChild?.remove(), n); } catch { return null; } } }; -var Uo = class { +var Xi = class { defaultDoc; inertDocument; constructor(t) { @@ -2478,58 +2779,58 @@ var Uo = class { } getInertBodyElement(t) { let n = this.inertDocument.createElement("template"); - return n.innerHTML = $n(t), n; + return n.innerHTML = Br(t), n; } }; -function Uu() { +function Jf() { try { - return !!new window.DOMParser().parseFromString($n(""), "text/html"); + return !!new window.DOMParser().parseFromString(Br(""), "text/html"); } catch { return false; } } -var zu = /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:\/?#]*(?:[\/?#]|$))/i; -function Un(e6) { - return e6 = String(e6), e6.match(zu) ? e6 : "unsafe:" + e6; +var Xf = /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:\/?#]*(?:[\/?#]|$))/i; +function $r(e12) { + return e12 = String(e12), e12.match(Xf) ? e12 : "unsafe:" + e12; } -function se(e6) { +function _e(e12) { let t = {}; - for (let n of e6.split(",")) + for (let n of e12.split(",")) t[n] = true; return t; } -function Rt(...e6) { +function mn(...e12) { let t = {}; - for (let n of e6) + for (let n of e12) for (let r in n) n.hasOwnProperty(r) && (t[r] = true); return t; } -var Ja = se("area,br,col,hr,img,wbr"); -var Xa = se("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr"); -var ec = se("rp,rt"); -var Wu = Rt(ec, Xa); -var Gu = Rt(Xa, se("address,article,aside,blockquote,caption,center,del,details,dialog,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,h6,header,hgroup,hr,ins,main,map,menu,nav,ol,pre,section,summary,table,ul")); -var qu = Rt(ec, se("a,abbr,acronym,audio,b,bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,picture,q,ruby,rp,rt,s,samp,small,source,span,strike,strong,sub,sup,time,track,tt,u,var,video")); -var ua = Rt(Ja, Gu, qu, Wu); -var tc = se("background,cite,href,itemtype,longdesc,poster,src,xlink:href"); -var Zu = se("abbr,accesskey,align,alt,autoplay,axis,bgcolor,border,cellpadding,cellspacing,class,clear,color,cols,colspan,compact,controls,coords,datetime,default,dir,download,face,headers,height,hidden,hreflang,hspace,ismap,itemscope,itemprop,kind,label,lang,language,loop,media,muted,nohref,nowrap,open,preload,rel,rev,role,rows,rowspan,rules,scope,scrolling,shape,size,sizes,span,srclang,srcset,start,summary,tabindex,target,title,translate,type,usemap,valign,value,vspace,width"); -var Qu = se("aria-activedescendant,aria-atomic,aria-autocomplete,aria-busy,aria-checked,aria-colcount,aria-colindex,aria-colspan,aria-controls,aria-current,aria-describedby,aria-details,aria-disabled,aria-dropeffect,aria-errormessage,aria-expanded,aria-flowto,aria-grabbed,aria-haspopup,aria-hidden,aria-invalid,aria-keyshortcuts,aria-label,aria-labelledby,aria-level,aria-live,aria-modal,aria-multiline,aria-multiselectable,aria-orientation,aria-owns,aria-placeholder,aria-posinset,aria-pressed,aria-readonly,aria-relevant,aria-required,aria-roledescription,aria-rowcount,aria-rowindex,aria-rowspan,aria-selected,aria-setsize,aria-sort,aria-valuemax,aria-valuemin,aria-valuenow,aria-valuetext"); -var Yu = Rt(tc, Zu, Qu); -var Ku = se("script,style,template"); -var zo = class { +var Xl = _e("area,br,col,hr,img,wbr"); +var eu = _e("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr"); +var tu = _e("rp,rt"); +var ep = mn(tu, eu); +var tp = mn(eu, _e("address,article,aside,blockquote,caption,center,del,details,dialog,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,h6,header,hgroup,hr,ins,main,map,menu,nav,ol,pre,section,summary,table,ul")); +var np = mn(tu, _e("a,abbr,acronym,audio,b,bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,picture,q,ruby,rp,rt,s,samp,small,source,span,strike,strong,sub,sup,time,track,tt,u,var,video")); +var ol = mn(Xl, tp, np, ep); +var nu = _e("background,cite,href,itemtype,longdesc,poster,src,xlink:href"); +var rp = _e("abbr,accesskey,align,alt,autoplay,axis,bgcolor,border,cellpadding,cellspacing,class,clear,color,cols,colspan,compact,controls,coords,datetime,default,dir,download,face,headers,height,hidden,hreflang,hspace,ismap,itemscope,itemprop,kind,label,lang,language,loop,media,muted,nohref,nowrap,open,preload,rel,rev,role,rows,rowspan,rules,scope,scrolling,shape,size,sizes,span,srclang,srcset,start,summary,tabindex,target,title,translate,type,usemap,valign,value,vspace,width"); +var op = _e("aria-activedescendant,aria-atomic,aria-autocomplete,aria-busy,aria-checked,aria-colcount,aria-colindex,aria-colspan,aria-controls,aria-current,aria-describedby,aria-details,aria-disabled,aria-dropeffect,aria-errormessage,aria-expanded,aria-flowto,aria-grabbed,aria-haspopup,aria-hidden,aria-invalid,aria-keyshortcuts,aria-label,aria-labelledby,aria-level,aria-live,aria-modal,aria-multiline,aria-multiselectable,aria-orientation,aria-owns,aria-placeholder,aria-posinset,aria-pressed,aria-readonly,aria-relevant,aria-required,aria-roledescription,aria-rowcount,aria-rowindex,aria-rowspan,aria-selected,aria-setsize,aria-sort,aria-valuemax,aria-valuemin,aria-valuenow,aria-valuetext"); +var ip = mn(nu, rp, op); +var sp = _e("script,style,template"); +var es = class { sanitizedSomething = false; buf = []; sanitizeChildren(t) { let n = t.firstChild, r = true, o = []; for (; n; ) { if (n.nodeType === Node.ELEMENT_NODE ? r = this.startElement(n) : n.nodeType === Node.TEXT_NODE ? this.chars(n.nodeValue) : this.sanitizedSomething = true, r && n.firstChild) { - o.push(n), n = ed(n); + o.push(n), n = lp(n); continue; } for (; n; ) { n.nodeType === Node.ELEMENT_NODE && this.endElement(n); - let i = Xu(n); + let i = cp(n); if (i) { n = i; break; @@ -2540,170 +2841,170 @@ var zo = class { return this.buf.join(""); } startElement(t) { - let n = da(t).toLowerCase(); - if (!ua.hasOwnProperty(n)) - return this.sanitizedSomething = true, !Ku.hasOwnProperty(n); + let n = il(t).toLowerCase(); + if (!ol.hasOwnProperty(n)) + return this.sanitizedSomething = true, !sp.hasOwnProperty(n); this.buf.push("<"), this.buf.push(n); let r = t.attributes; for (let o = 0; o < r.length; o++) { let i = r.item(o), s = i.name, a = s.toLowerCase(); - if (!Yu.hasOwnProperty(a)) { + if (!ip.hasOwnProperty(a)) { this.sanitizedSomething = true; continue; } let c = i.value; - tc[a] && (c = Un(c)), this.buf.push(" ", s, '="', fa(c), '"'); + nu[a] && (c = $r(c)), this.buf.push(" ", s, '="', sl(c), '"'); } return this.buf.push(">"), true; } endElement(t) { - let n = da(t).toLowerCase(); - ua.hasOwnProperty(n) && !Ja.hasOwnProperty(n) && (this.buf.push("")); + let n = il(t).toLowerCase(); + ol.hasOwnProperty(n) && !Xl.hasOwnProperty(n) && (this.buf.push("")); } chars(t) { - this.buf.push(fa(t)); + this.buf.push(sl(t)); } }; -function Ju(e6, t) { - return (e6.compareDocumentPosition(t) & Node.DOCUMENT_POSITION_CONTAINED_BY) !== Node.DOCUMENT_POSITION_CONTAINED_BY; +function ap(e12, t) { + return (e12.compareDocumentPosition(t) & Node.DOCUMENT_POSITION_CONTAINED_BY) !== Node.DOCUMENT_POSITION_CONTAINED_BY; } -function Xu(e6) { - let t = e6.nextSibling; - if (t && e6 !== t.previousSibling) - throw nc(t); +function cp(e12) { + let t = e12.nextSibling; + if (t && e12 !== t.previousSibling) + throw ru(t); return t; } -function ed(e6) { - let t = e6.firstChild; - if (t && Ju(e6, t)) - throw nc(t); +function lp(e12) { + let t = e12.firstChild; + if (t && ap(e12, t)) + throw ru(t); return t; } -function da(e6) { - let t = e6.nodeName; +function il(e12) { + let t = e12.nodeName; return typeof t == "string" ? t : "FORM"; } -function nc(e6) { - return new Error(`Failed to sanitize html because the element is clobbered: ${e6.outerHTML}`); +function ru(e12) { + return new Error(`Failed to sanitize html because the element is clobbered: ${e12.outerHTML}`); } -var td = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g; -var nd = /([^\#-~ |!])/g; -function fa(e6) { - return e6.replace(/&/g, "&").replace(td, function(t) { +var up = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g; +var dp = /([^\#-~ |!])/g; +function sl(e12) { + return e12.replace(/&/g, "&").replace(up, function(t) { let n = t.charCodeAt(0), r = t.charCodeAt(1); return "&#" + ((n - 55296) * 1024 + (r - 56320) + 65536) + ";"; - }).replace(nd, function(t) { + }).replace(dp, function(t) { return "&#" + t.charCodeAt(0) + ";"; }).replace(//g, ">"); } -var _n; -function zn(e6, t) { +var vr; +function Ur(e12, t) { let n = null; try { - _n = _n || $u(e6); + vr = vr || Kf(e12); let r = t ? String(t) : ""; - n = _n.getInertBodyElement(r); + n = vr.getInertBodyElement(r); let o = 5, i = r; do { if (o === 0) throw new Error("Failed to sanitize html because the input is unstable"); - o--, r = i, i = n.innerHTML, n = _n.getInertBodyElement(r); + o--, r = i, i = n.innerHTML, n = vr.getInertBodyElement(r); } while (r !== i); - let a = new zo().sanitizeChildren(pa(n) || n); - return $n(a); + let a = new es().sanitizeChildren(al(n) || n); + return Br(a); } finally { if (n) { - let r = pa(n) || n; + let r = al(n) || n; for (; r.firstChild; ) r.firstChild.remove(); } } } -function pa(e6) { - return "content" in e6 && rd(e6) ? e6.content : null; +function al(e12) { + return "content" in e12 && fp(e12) ? e12.content : null; } -function rd(e6) { - return e6.nodeType === Node.ELEMENT_NODE && e6.nodeName === "TEMPLATE"; +function fp(e12) { + return e12.nodeType === Node.ELEMENT_NODE && e12.nodeName === "TEMPLATE"; } -function od(e6, t) { - return e6.createText(t); +function pp(e12, t) { + return e12.createText(t); } -function id(e6, t, n) { - e6.setValue(t, n); +function hp(e12, t, n) { + e12.setValue(t, n); } -function rc(e6, t, n) { - return e6.createElement(t, n); +function ou(e12, t, n) { + return e12.createElement(t, n); } -function Wo(e6, t, n, r, o) { - e6.insertBefore(t, n, r, o); +function Nr(e12, t, n, r, o) { + e12.insertBefore(t, n, r, o); } -function oc(e6, t, n) { - e6.appendChild(t, n); +function iu(e12, t, n) { + e12.appendChild(t, n); } -function ha(e6, t, n, r, o) { - r !== null ? Wo(e6, t, n, r, o) : oc(e6, t, n); +function cl(e12, t, n, r, o) { + r !== null ? Nr(e12, t, n, r, o) : iu(e12, t, n); } -function sd(e6, t, n, r) { - e6.removeChild(null, t, n, r); +function su(e12, t, n, r) { + e12.removeChild(null, t, n, r); } -function ad(e6, t, n) { - e6.setAttribute(t, "style", n); +function gp(e12, t, n) { + e12.setAttribute(t, "style", n); } -function cd(e6, t, n) { - n === "" ? e6.removeAttribute(t, "class") : e6.setAttribute(t, "class", n); +function mp(e12, t, n) { + n === "" ? e12.removeAttribute(t, "class") : e12.setAttribute(t, "class", n); } -function ic(e6, t, n) { +function au(e12, t, n) { let { mergedAttrs: r, classes: o, styles: i } = n; - r !== null && Eu(e6, t, r), o !== null && cd(e6, t, o), i !== null && ad(e6, t, i); + r !== null && Mf(e12, t, r), o !== null && mp(e12, t, o), i !== null && gp(e12, t, i); } -var K = function(e6) { - return e6[e6.NONE = 0] = "NONE", e6[e6.HTML = 1] = "HTML", e6[e6.STYLE = 2] = "STYLE", e6[e6.SCRIPT = 3] = "SCRIPT", e6[e6.URL = 4] = "URL", e6[e6.RESOURCE_URL = 5] = "RESOURCE_URL", e6; -}(K || {}); -function ui(e6) { - let t = ld(); - return t ? la(t.sanitize(K.HTML, e6) || "") : me(e6, "HTML") ? la(ge(e6)) : zn(Ga(), Zr(e6)); +var ge = function(e12) { + return e12[e12.NONE = 0] = "NONE", e12[e12.HTML = 1] = "HTML", e12[e12.STYLE = 2] = "STYLE", e12[e12.SCRIPT = 3] = "SCRIPT", e12[e12.URL = 4] = "URL", e12[e12.RESOURCE_URL = 5] = "RESOURCE_URL", e12; +}(ge || {}); +function Ls(e12) { + let t = yp(); + return t ? rl(t.sanitize(ge.HTML, e12) || "") : He(e12, "HTML") ? rl(Me(e12)) : Ur(Wl(), ii(e12)); } -function ld() { - let e6 = H(); - return e6 && e6[Z].sanitizer; +function yp() { + let e12 = M(); + return e12 && e12[le].sanitizer; } -var ud = "ng-template"; -function dd(e6) { - return e6.type === 4 && e6.value !== ud; +var vp = "ng-template"; +function Ep(e12) { + return e12.type === 4 && e12.value !== vp; } -function Go(e6) { - return (e6 & 1) === 0; +function ts(e12) { + return (e12 & 1) === 0; } -function ga(e6, t) { - return e6 ? ":not(" + t.trim() + ")" : t; +function ll(e12, t) { + return e12 ? ":not(" + t.trim() + ")" : t; } -function fd(e6) { - let t = e6[0], n = 1, r = 2, o = "", i = false; - for (; n < e6.length; ) { - let s = e6[n]; +function Ip(e12) { + let t = e12[0], n = 1, r = 2, o = "", i = false; + for (; n < e12.length; ) { + let s = e12[n]; if (typeof s == "string") if (r & 2) { - let a = e6[++n]; + let a = e12[++n]; o += "[" + s + (a.length > 0 ? '="' + a + '"' : "") + "]"; } else r & 8 ? o += "." + s : r & 4 && (o += " " + s); else - o !== "" && !Go(s) && (t += ga(i, o), o = ""), r = s, i = i || !Go(r); + o !== "" && !ts(s) && (t += ll(i, o), o = ""), r = s, i = i || !ts(r); n++; } - return o !== "" && (t += ga(i, o)), t; + return o !== "" && (t += ll(i, o)), t; } -function pd(e6) { - return e6.map(fd).join(","); +function Dp(e12) { + return e12.map(Ip).join(","); } -function hd(e6) { +function wp(e12) { let t = [], n = [], r = 1, o = 2; - for (; r < e6.length; ) { - let i = e6[r]; + for (; r < e12.length; ) { + let i = e12[r]; if (typeof i == "string") - o === 2 ? i !== "" && t.push(i, e6[++r]) : o === 8 && n.push(i); + o === 2 ? i !== "" && t.push(i, e12[++r]) : o === 8 && n.push(i); else { - if (!Go(o)) + if (!ts(o)) break; o = i; } @@ -2711,205 +3012,216 @@ function hd(e6) { } return n.length && t.push(1, ...n), t; } -var tt = {}; -function sc(e6, t, n, r, o, i, s, a, c, l, u) { - let d = U + r, p = d + o, f = gd(d, p), T = typeof l == "function" ? l() : l; - return f[y] = { type: e6, blueprint: f, template: n, queries: null, viewQuery: a, declTNode: t, data: f.slice().fill(null, d), bindingStartIndex: d, expandoStartIndex: p, hostBindingOpCodes: null, firstCreatePass: true, firstUpdatePass: true, staticViewQueries: false, staticContentQueries: false, preOrderHooks: null, preOrderCheckHooks: null, contentHooks: null, contentCheckHooks: null, viewHooks: null, viewCheckHooks: null, destroyHooks: null, cleanup: null, contentQueries: null, components: null, directiveRegistry: typeof i == "function" ? i() : i, pipeRegistry: typeof s == "function" ? s() : s, firstChild: null, schemas: c, consts: T, incompleteFirstPass: false, ssrId: u }; +var Se = {}; +function Fs(e12, t, n, r, o, i, s, a, c, l, u) { + let d = F + r, f = d + o, p = Cp(d, f), h = typeof l == "function" ? l() : l; + return p[m] = { type: e12, blueprint: p, template: n, queries: null, viewQuery: a, declTNode: t, data: p.slice().fill(null, d), bindingStartIndex: d, expandoStartIndex: f, hostBindingOpCodes: null, firstCreatePass: true, firstUpdatePass: true, staticViewQueries: false, staticContentQueries: false, preOrderHooks: null, preOrderCheckHooks: null, contentHooks: null, contentCheckHooks: null, viewHooks: null, viewCheckHooks: null, destroyHooks: null, cleanup: null, contentQueries: null, components: null, directiveRegistry: typeof i == "function" ? i() : i, pipeRegistry: typeof s == "function" ? s() : s, firstChild: null, schemas: c, consts: h, incompleteFirstPass: false, ssrId: u }; } -function gd(e6, t) { +function Cp(e12, t) { let n = []; for (let r = 0; r < t; r++) - n.push(r < e6 ? null : tt); + n.push(r < e12 ? null : Se); return n; } -function md(e6) { - let t = e6.tView; - return t === null || t.incompleteFirstPass ? e6.tView = sc(1, null, e6.template, e6.decls, e6.vars, e6.directiveDefs, e6.pipeDefs, e6.viewQuery, e6.schemas, e6.consts, e6.id) : t; +function bp(e12) { + let t = e12.tView; + return t === null || t.incompleteFirstPass ? e12.tView = Fs(1, null, e12.template, e12.decls, e12.vars, e12.directiveDefs, e12.pipeDefs, e12.viewQuery, e12.schemas, e12.consts, e12.id) : t; } -function ac(e6, t, n, r, o, i, s, a, c, l, u) { +function js(e12, t, n, r, o, i, s, a, c, l, u) { let d = t.blueprint.slice(); - return d[q] = o, d[h] = r | 4 | 128 | 8 | 64 | 1024, (l !== null || e6 && e6[h] & 2048) && (d[h] |= 2048), so(d), d[O] = d[We] = e6, d[L] = n, d[Z] = s || e6 && e6[Z], d[P] = a || e6 && e6[P], d[_e] = c || e6 && e6[_e] || null, d[re] = i, d[le] = Lu(), d[hn] = u, d[ro] = l, d[Q] = t.type == 2 ? e6[Q] : d, d; + return d[ne] = o, d[y] = r | 4 | 128 | 8 | 64 | 1024, (l !== null || e12 && e12[y] & 2048) && (d[y] |= 2048), Ei(d), d[R] = d[Xe] = e12, d[x] = n, d[le] = s || e12 && e12[le], d[O] = a || e12 && e12[O], d[De] = c || e12 && e12[De] || null, d[J] = i, d[we] = Bf(), d[wt] = u, d[hi] = l, d[X] = t.type == 2 ? e12[X] : d, d; } -function yd(e6, t, n) { - let r = Ae(t, e6), o = md(n), i = e6[Z].rendererFactory, s = vd(e6, ac(e6, o, null, cc(n), r, t, null, i.createRenderer(r, n), null, null, null)); - return e6[t.index] = s; +function Tp(e12, t, n) { + let r = de(t, e12), o = bp(n), i = e12[le].rendererFactory, s = Hs(e12, js(e12, o, null, cu(n), r, t, null, i.createRenderer(r, n), null, null, null)); + return e12[t.index] = s; } -function cc(e6) { +function cu(e12) { let t = 16; - return e6.signals ? t = 4096 : e6.onPush && (t = 64), t; + return e12.signals ? t = 4096 : e12.onPush && (t = 64), t; } -function lc(e6, t, n, r) { +function lu(e12, t, n, r) { if (n === 0) return -1; let o = t.length; for (let i = 0; i < n; i++) - t.push(r), e6.blueprint.push(r), e6.data.push(null); + t.push(r), e12.blueprint.push(r), e12.data.push(null); return o; } -function vd(e6, t) { - return e6[ze] ? e6[no][ne] = t : e6[ze] = t, e6[no] = t, t; +function Hs(e12, t) { + return e12[bt] ? e12[pi][K] = t : e12[bt] = t, e12[pi] = t, t; } -function Wn(e6 = 1) { - uc(Dn(), H(), Mn() + e6, false); +function V(e12 = 1) { + uu(oe(), M(), Fe() + e12, false); } -function uc(e6, t, n, r) { +function uu(e12, t, n, r) { if (!r) - if ((t[h] & 3) === 3) { - let i = e6.preOrderCheckHooks; - i !== null && Nn(t, i, n); + if ((t[y] & 3) === 3) { + let i = e12.preOrderCheckHooks; + i !== null && Ir(t, i, n); } else { - let i = e6.preOrderHooks; - i !== null && xn(t, i, 0, n); + let i = e12.preOrderHooks; + i !== null && Dr(t, i, 0, n); } - he(n); + je(n); } -var Gn = function(e6) { - return e6[e6.None = 0] = "None", e6[e6.SignalBased = 1] = "SignalBased", e6[e6.HasDecoratorInputTransform = 2] = "HasDecoratorInputTransform", e6; -}(Gn || {}); -function qo(e6, t, n, r) { - let o = v(null); +var zr = function(e12) { + return e12[e12.None = 0] = "None", e12[e12.SignalBased = 1] = "SignalBased", e12[e12.HasDecoratorInputTransform = 2] = "HasDecoratorInputTransform", e12; +}(zr || {}); +function ns(e12, t, n, r) { + let o = g(null); try { - let [i, s, a] = e6.inputs[n], c = null; - (s & Gn.SignalBased) !== 0 && (c = t[i][W]), c !== null && c.transformFn !== void 0 ? r = c.transformFn(r) : a !== null && (r = a.call(t, r)), e6.setInput !== null ? e6.setInput(t, c, r, n, i) : Sa(t, c, i, r); + let [i, s, a] = e12.inputs[n], c = null; + (s & zr.SignalBased) !== 0 && (c = t[i][Z]), c !== null && c.transformFn !== void 0 ? r = c.transformFn(r) : a !== null && (r = a.call(t, r)), e12.setInput !== null ? e12.setInput(t, c, r, n, i) : Ml(t, c, i, r); } finally { - v(o); + g(o); } } -var ke = function(e6) { - return e6[e6.Important = 1] = "Important", e6[e6.DashCase = 2] = "DashCase", e6; -}(ke || {}); -var Ed; -function dc(e6, t) { - return Ed(e6, t); +var Te = function(e12) { + return e12[e12.Important = 1] = "Important", e12[e12.DashCase = 2] = "DashCase", e12; +}(Te || {}); +var Mp; +function Vs(e12, t) { + return Mp(e12, t); } -var ny = typeof document < "u" && typeof document?.documentElement?.getAnimations == "function"; -var Zo = /* @__PURE__ */ new WeakMap(); -var Mt = /* @__PURE__ */ new WeakSet(); -function Id(e6, t) { - let n = Zo.get(e6); +var UE = typeof document < "u" && typeof document?.documentElement?.getAnimations == "function"; +var rs = /* @__PURE__ */ new WeakMap(); +var nn = /* @__PURE__ */ new WeakSet(); +function _p(e12, t) { + let n = rs.get(e12); if (!n || n.length === 0) return; let r = t.parentNode, o = t.previousSibling; for (let i = n.length - 1; i >= 0; i--) { let s = n[i], a = s.parentNode; - s === t ? (n.splice(i, 1), Mt.add(s), s.dispatchEvent(new CustomEvent("animationend", { detail: { cancel: true } }))) : (o && s === o || a && r && a !== r) && (n.splice(i, 1), s.dispatchEvent(new CustomEvent("animationend", { detail: { cancel: true } })), s.parentNode?.removeChild(s)); + s === t ? (n.splice(i, 1), nn.add(s), s.dispatchEvent(new CustomEvent("animationend", { detail: { cancel: true } }))) : (o && s === o || a && r && a !== r) && (n.splice(i, 1), s.dispatchEvent(new CustomEvent("animationend", { detail: { cancel: true } })), s.parentNode?.removeChild(s)); } } -function Dd(e6, t) { - let n = Zo.get(e6); - n ? n.includes(t) || n.push(t) : Zo.set(e6, [t]); +function Sp(e12, t) { + let n = rs.get(e12); + n ? n.includes(t) || n.push(t) : rs.set(e12, [t]); } -var et = /* @__PURE__ */ new Set(); -var di = function(e6) { - return e6[e6.CHANGE_DETECTION = 0] = "CHANGE_DETECTION", e6[e6.AFTER_NEXT_RENDER = 1] = "AFTER_NEXT_RENDER", e6; -}(di || {}); -var nt = new m(""); -var ma = /* @__PURE__ */ new Set(); -function fc(e6) { - ma.has(e6) || (ma.add(e6), performance?.mark?.("mark_feature_usage", { detail: { feature: e6 } })); +var it = /* @__PURE__ */ new Set(); +var Bs = function(e12) { + return e12[e12.CHANGE_DETECTION = 0] = "CHANGE_DETECTION", e12[e12.AFTER_NEXT_RENDER = 1] = "AFTER_NEXT_RENDER", e12; +}(Bs || {}); +var jt = new D(""); +var ul = /* @__PURE__ */ new Set(); +function ct(e12) { + ul.has(e12) || (ul.add(e12), performance?.mark?.("mark_feature_usage", { detail: { feature: e12 } })); } -var pc = (() => { - class e6 { +var du = (() => { + class e12 { impl = null; execute() { this.impl?.execute(); } - static \u0275prov = S({ token: e6, providedIn: "root", factory: () => new e6() }); + static \u0275prov = _({ token: e12, providedIn: "root", factory: () => new e12() }); } - return e6; + return e12; })(); -var wd = new m("", { factory: () => ({ queue: /* @__PURE__ */ new Set(), isScheduled: false, scheduler: null, injector: E($) }) }); -function hc(e6, t, n) { - let r = e6.get(wd); +var fu = new D("", { factory: () => ({ queue: /* @__PURE__ */ new Set(), isScheduled: false, scheduler: null, injector: E(Q) }) }); +function pu(e12, t, n) { + let r = e12.get(fu); if (Array.isArray(t)) for (let o of t) r.queue.add(o), n?.detachedLeaveAnimationFns?.push(o); else r.queue.add(t), n?.detachedLeaveAnimationFns?.push(t); - r.scheduler && r.scheduler(e6); + r.scheduler && r.scheduler(e12); +} +function Np(e12, t) { + let n = e12.get(fu); + if (t.detachedLeaveAnimationFns) { + for (let r of t.detachedLeaveAnimationFns) + n.queue.delete(r); + t.detachedLeaveAnimationFns = void 0; + } } -function Cd(e6, t) { +function xp(e12, t) { for (let [n, r] of t) - hc(e6, r.animateFns); + pu(e12, r.animateFns); } -function ya(e6, t, n, r) { - let o = e6?.[Ge]?.enter; - t !== null && o && o.has(n.index) && Cd(r, o); +function dl(e12, t, n, r) { + let o = e12?.[ke]?.enter; + t !== null && o && o.has(n.index) && xp(r, o); } -function Je(e6, t, n, r, o, i, s, a) { +function Rt(e12, t, n, r, o, i, s, a) { if (o != null) { let c, l = false; - de(o) ? c = o : ue(o) && (l = true, o = o[q]); - let u = fe(o); - e6 === 0 && r !== null ? (ya(a, r, i, n), s == null ? oc(t, r, u) : Wo(t, r, u, s || null, true)) : e6 === 1 && r !== null ? (ya(a, r, i, n), Wo(t, r, u, s || null, true), Id(i, u)) : e6 === 2 ? (a?.[Ge]?.leave?.has(i.index) && Dd(i, u), Mt.delete(u), va(a, i, n, (d) => { - if (Mt.has(u)) { - Mt.delete(u); + re(o) ? c = o : Le(o) && (l = true, o = o[ne]); + let u = ee(o); + e12 === 0 && r !== null ? (dl(a, r, i, n), s == null ? iu(t, r, u) : Nr(t, r, u, s || null, true)) : e12 === 1 && r !== null ? (dl(a, r, i, n), Nr(t, r, u, s || null, true), _p(i, u)) : e12 === 2 ? (a?.[ke]?.leave?.has(i.index) && Sp(i, u), nn.delete(u), fl(a, i, n, (d) => { + if (nn.has(u)) { + nn.delete(u); return; } - sd(t, u, l, d); - })) : e6 === 3 && (Mt.delete(u), va(a, i, n, () => { + su(t, u, l, d); + })) : e12 === 3 && (nn.delete(u), fl(a, i, n, () => { t.destroyNode(u); - })), c != null && Fd(t, e6, n, c, i, r, s); + })), c != null && Up(t, e12, n, c, i, r, s); } } -function Td(e6, t) { - gc(e6, t), t[q] = null, t[re] = null; +function Ap(e12, t) { + hu(e12, t), t[ne] = null, t[J] = null; } -function gc(e6, t) { - t[Z].changeDetectionScheduler?.notify(9), hi(e6, t, t[P], 2, null, null); +function Rp(e12, t, n, r, o, i) { + r[ne] = o, r[J] = t, Gr(e12, r, n, 1, o, i); } -function Md(e6) { - let t = e6[ze]; +function hu(e12, t) { + t[le].changeDetectionScheduler?.notify(9), Gr(e12, t, t[O], 2, null, null); +} +function Op(e12) { + let t = e12[bt]; if (!t) - return No(e6[y], e6); + return ji(e12[m], e12); for (; t; ) { let n = null; - if (ue(t)) - n = t[ze]; + if (Le(t)) + n = t[bt]; else { - let r = t[oe]; + let r = t[S]; r && (n = r); } if (!n) { - for (; t && !t[ne] && t !== e6; ) - ue(t) && No(t[y], t), t = t[O]; - t === null && (t = e6), ue(t) && No(t[y], t), n = t && t[ne]; + for (; t && !t[K] && t !== e12; ) + Le(t) && ji(t[m], t), t = t[R]; + t === null && (t = e12), Le(t) && ji(t[m], t), n = t && t[K]; } t = n; } } -function fi(e6, t) { - let n = e6[mt], r = n.indexOf(t); +function $s(e12, t) { + let n = e12[tt], r = n.indexOf(t); n.splice(r, 1); } -function Sd(e6, t) { - if (xe(t)) +function Wr(e12, t) { + if (nt(t)) return; - let n = t[P]; - n.destroyNode && hi(e6, t, n, 3, null, null), Md(t); + let n = t[O]; + n.destroyNode && Gr(e12, t, n, 3, null, null), Op(t); } -function No(e6, t) { - if (xe(t)) +function ji(e12, t) { + if (nt(t)) return; - let n = v(null); + let n = g(null); try { - t[h] &= -129, t[h] |= 256, t[F] && qt(t[F]), Nd(e6, t), _d(e6, t), t[y].type === 1 && t[P].destroy(); - let r = t[ht]; - if (r !== null && de(t[O])) { - r !== t[O] && fi(r, t); - let o = t[mn]; - o !== null && o.detachView(e6); - } - Oo(t); + t[y] &= -129, t[y] |= 256, t[G] && dt(t[G]), Lp(e12, t), Pp(e12, t), t[m].type === 1 && t[O].destroy(); + let r = t[Oe]; + if (r !== null && re(t[R])) { + r !== t[R] && $s(r, t); + let o = t[ue]; + o !== null && o.detachView(e12); + } + zi(t); } finally { - v(n); + g(n); } } -function va(e6, t, n, r) { - let o = e6?.[Ge]; +function fl(e12, t, n, r) { + let o = e12?.[ke]; if (o == null || o.leave == null || !o.leave.has(t.index)) return r(false); - e6 && et.add(e6[le]), hc(n, () => { + e12 && it.add(e12[we]), pu(n, () => { if (o.leave && o.leave.has(t.index)) { let s = o.leave.get(t.index), a = []; if (s) { @@ -2919,23 +3231,23 @@ function va(e6, t, n, r) { } o.detachedLeaveAnimationFns = void 0; } - o.running = Promise.allSettled(a), bd(e6, r); + o.running = Promise.allSettled(a), kp(e12, r); } else - e6 && et.delete(e6[le]), r(false); + e12 && it.delete(e12[we]), r(false); }, o); } -function bd(e6, t) { - let n = e6[Ge]?.running; +function kp(e12, t) { + let n = e12[ke]?.running; if (n) { n.then(() => { - e6[Ge].running = void 0, et.delete(e6[le]), t(true); + e12[ke].running = void 0, it.delete(e12[we]), t(true); }); return; } t(false); } -function _d(e6, t) { - let n = e6.cleanup, r = t[gn]; +function Pp(e12, t) { + let n = e12.cleanup, r = t[Ct]; if (n !== null) for (let s = 0; s < n.length - 1; s += 2) if (typeof n[s] == "string") { @@ -2945,683 +3257,841 @@ function _d(e6, t) { let a = r[n[s + 1]]; n[s].call(a); } - r !== null && (t[gn] = null); - let o = t[X]; + r !== null && (t[Ct] = null); + let o = t[Ee]; if (o !== null) { - t[X] = null; + t[Ee] = null; for (let s = 0; s < o.length; s++) { let a = o[s]; a(); } } - let i = t[gt]; + let i = t[xe]; if (i !== null) { - t[gt] = null; + t[xe] = null; for (let s of i) s.destroy(); } } -function Nd(e6, t) { +function Lp(e12, t) { let n; - if (e6 != null && (n = e6.destroyHooks) != null) + if (e12 != null && (n = e12.destroyHooks) != null) for (let r = 0; r < n.length; r += 2) { let o = t[n[r]]; - if (!(o instanceof bt)) { + if (!(o instanceof sn)) { let i = n[r + 1]; if (Array.isArray(i)) for (let s = 0; s < i.length; s += 2) { let a = o[i[s]], c = i[s + 1]; - M(w.LifecycleHookStart, a, c); + T(C.LifecycleHookStart, a, c); try { c.call(a); } finally { - M(w.LifecycleHookEnd, a, c); + T(C.LifecycleHookEnd, a, c); } } else { - M(w.LifecycleHookStart, o, i); + T(C.LifecycleHookStart, o, i); try { i.call(o); } finally { - M(w.LifecycleHookEnd, o, i); + T(C.LifecycleHookEnd, o, i); } } } } } -function xd(e6, t, n) { - return Ad(e6, t.parent, n); +function Fp(e12, t, n) { + return jp(e12, t.parent, n); } -function Ad(e6, t, n) { +function jp(e12, t, n) { let r = t; for (; r !== null && r.type & 168; ) t = r, r = t.parent; if (r === null) - return n[q]; - if (yt(r)) { - let { encapsulation: o } = e6.data[r.directiveStart + r.componentOffset]; - if (o === z.None || o === z.Emulated) + return n[ne]; + if (Tt(r)) { + let { encapsulation: o } = e12.data[r.directiveStart + r.componentOffset]; + if (o === ie.None || o === ie.Emulated) return null; } - return Ae(r, n); + return de(r, n); } -function Rd(e6, t, n) { - return Od(e6, t, n); +function Hp(e12, t, n) { + return Bp(e12, t, n); } -function kd(e6, t, n) { - return e6.type & 40 ? Ae(e6, n) : null; +function Vp(e12, t, n) { + return e12.type & 40 ? de(e12, n) : null; } -var Od = kd; -var Ea; -function mc(e6, t, n, r) { - let o = xd(e6, r, t), i = t[P], s = r.parent || t[re], a = Rd(s, r, t); +var Bp = Vp; +var pl; +function Us(e12, t, n, r) { + let o = Fp(e12, r, t), i = t[O], s = r.parent || t[J], a = Hp(s, r, t); if (o != null) if (Array.isArray(n)) for (let c = 0; c < n.length; c++) - ha(i, o, n[c], a, false); + cl(i, o, n[c], a, false); else - ha(i, o, n, a, false); - Ea !== void 0 && Ea(i, r, t, n, o); + cl(i, o, n, a, false); + pl !== void 0 && pl(i, r, t, n, o); +} +function rn(e12, t) { + if (t !== null) { + let n = t.type; + if (n & 3) + return de(t, e12); + if (n & 4) + return os(-1, e12[t.index]); + if (n & 8) { + let r = t.child; + if (r !== null) + return rn(e12, r); + { + let o = e12[t.index]; + return re(o) ? os(-1, o) : ee(o); + } + } else { + if (n & 128) + return rn(e12, t.next); + if (n & 32) + return Vs(t, e12)() || ee(e12[t.index]); + { + let r = gu(e12, t); + if (r !== null) { + if (Array.isArray(r)) + return r[0]; + let o = Ae(e12[X]); + return rn(o, r); + } else + return rn(e12, t.next); + } + } + } + return null; } -function Ld(e6, t) { +function gu(e12, t) { if (t !== null) { - let r = e6[Q][re], o = t.projection; + let r = e12[X][J], o = t.projection; return r.projection[o]; } return null; } -function pi(e6, t, n, r, o, i, s) { +function os(e12, t) { + let n = S + e12 + 1; + if (n < t.length) { + let r = t[n], o = r[m].firstChild; + if (o !== null) + return rn(r, o); + } + return t[Pe]; +} +function zs(e12, t, n, r, o, i, s) { for (; n != null; ) { - let a = r[_e]; + let a = r[De]; if (n.type === 128) { n = n.next; continue; } let c = r[n.index], l = n.type; - if (s && t === 0 && (c && _t(fe(c), r), n.flags |= 2), !oi(n)) + if (s && t === 0 && (c && kt(ee(c), r), n.flags |= 2), !xs(n)) if (l & 8) - pi(e6, t, n.child, r, o, i, false), Je(t, e6, a, o, c, n, i, r); + zs(e12, t, n.child, r, o, i, false), Rt(t, e12, a, o, c, n, i, r); else if (l & 32) { - let u = dc(n, r), d; + let u = Vs(n, r), d; for (; d = u(); ) - Je(t, e6, a, o, d, n, i, r); - Je(t, e6, a, o, c, n, i, r); + Rt(t, e12, a, o, d, n, i, r); + Rt(t, e12, a, o, c, n, i, r); } else - l & 16 ? Pd(e6, t, r, n, o, i) : Je(t, e6, a, o, c, n, i, r); + l & 16 ? $p(e12, t, r, n, o, i) : Rt(t, e12, a, o, c, n, i, r); n = s ? n.projectionNext : n.next; } } -function hi(e6, t, n, r, o, i) { - pi(n, r, e6.firstChild, t, o, i, false); +function Gr(e12, t, n, r, o, i) { + zs(n, r, e12.firstChild, t, o, i, false); } -function Pd(e6, t, n, r, o, i) { - let s = n[Q], c = s[re].projection[r.projection]; +function $p(e12, t, n, r, o, i) { + let s = n[X], c = s[J].projection[r.projection]; if (Array.isArray(c)) for (let l = 0; l < c.length; l++) { let u = c[l]; - Je(t, e6, n[_e], o, u, r, i, n); + Rt(t, e12, n[De], o, u, r, i, n); } else { - let l = c, u = s[O]; - ku(r) && (l.flags |= 128), pi(e6, t, l, u, o, i, true); + let l = c, u = s[R]; + Vl(r) && (l.flags |= 128), zs(e12, t, l, u, o, i, true); } } -function Fd(e6, t, n, r, o, i, s) { - let a = r[En], c = fe(r); - a !== c && Je(t, e6, n, i, a, o, s); - for (let l = oe; l < r.length; l++) { +function Up(e12, t, n, r, o, i, s) { + let a = r[Pe], c = ee(r); + a !== c && Rt(t, e12, n, i, a, o, s); + for (let l = S; l < r.length; l++) { let u = r[l]; - hi(u[y], u, e6, t, i, a); + Gr(u[m], u, e12, t, i, a); + } +} +function zp(e12, t, n, r, o) { + if (t) + o ? e12.addClass(n, r) : e12.removeClass(n, r); + else { + let i = r.indexOf("-") === -1 ? void 0 : Te.DashCase; + o == null ? e12.removeStyle(n, r, i) : (typeof o == "string" && o.endsWith("!important") && (o = o.slice(0, -10), i |= Te.Important), e12.setStyle(n, r, o, i)); } } -function yc(e6, t, n, r, o) { - let i = Mn(), s = r & 2; +function mu(e12, t, n, r, o) { + let i = Fe(), s = r & 2; try { - he(-1), s && t.length > U && uc(e6, t, U, false); - let a = s ? w.TemplateUpdateStart : w.TemplateCreateStart; - M(a, o, n), n(r, o); + je(-1), s && t.length > F && uu(e12, t, F, false); + let a = s ? C.TemplateUpdateStart : C.TemplateCreateStart; + T(a, o, n), n(r, o); } finally { - he(i); - let a = s ? w.TemplateUpdateEnd : w.TemplateCreateEnd; - M(a, o, n); + je(i); + let a = s ? C.TemplateUpdateEnd : C.TemplateCreateEnd; + T(a, o, n); } } -function jd(e6, t, n) { - zd(e6, t, n), (n.flags & 64) === 64 && Wd(e6, t, n); +function Wp(e12, t, n) { + Yp(e12, t, n), (n.flags & 64) === 64 && Kp(e12, t, n); } -function Hd(e6, t, n = Ae) { +function yu(e12, t, n = de) { let r = t.localNames; if (r !== null) { let o = t.index + 1; for (let i = 0; i < r.length; i += 2) { - let s = r[i + 1], a = s === -1 ? n(t, e6) : e6[s]; - e6[o++] = a; + let s = r[i + 1], a = s === -1 ? n(t, e12) : e12[s]; + e12[o++] = a; } } } -function Vd(e6, t, n, r) { - let i = r.get(Za, qa) || n === z.ShadowDom || n === z.ExperimentalIsolatedShadowDom, s = e6.selectRootElement(t, i); - return Bd(s), s; +function Gp(e12, t, n, r) { + let i = r.get(Ql, Zl) || n === ie.ShadowDom || n === ie.ExperimentalIsolatedShadowDom, s = e12.selectRootElement(t, i); + return qp(s), s; } -function Bd(e6) { - $d(e6); +function qp(e12) { + Zp(e12); } -var $d = () => null; -function Ud(e6, t, n, r, o, i) { - if (e6.type & 3) { - let s = Ae(e6, t); - r = i != null ? i(r, e6.value || "", n) : r, o.setProperty(s, n, r); +var Zp = () => null; +function Qp(e12, t, n, r, o, i) { + if (e12.type & 3) { + let s = de(e12, t); + r = i != null ? i(r, e12.value || "", n) : r, o.setProperty(s, n, r); } else - e6.type & 12; + e12.type & 12; } -function zd(e6, t, n) { +function Yp(e12, t, n) { let r = n.directiveStart, o = n.directiveEnd; - yt(n) && yd(t, n, e6.data[r + n.componentOffset]), e6.firstCreatePass || Ra(n, t); + Tt(n) && Tp(t, n, e12.data[r + n.componentOffset]), e12.firstCreatePass || Ol(n, t); let i = n.initialInputs; for (let s = r; s < o; s++) { - let a = e6.data[s], c = ko(t, e6, s, n); - if (_t(c, t), i !== null && qd(t, s - r, c, a, n, i), qe(a)) { - let l = pe(n.index, t); - l[L] = ko(t, e6, s, n); + let a = e12.data[s], c = _r(t, e12, s, n); + if (kt(c, t), i !== null && Xp(t, s - r, c, a, n, i), Mt(a)) { + let l = Ce(n.index, t); + l[x] = _r(t, e12, s, n); } } } -function Wd(e6, t, n) { - let r = n.directiveStart, o = n.directiveEnd, i = n.index, s = $s(); +function Kp(e12, t, n) { + let r = n.directiveStart, o = n.directiveEnd, i = n.index, s = Ac(); try { - he(i); + je(i); for (let a = r; a < o; a++) { - let c = e6.data[a], l = t[a]; - wn(a), (c.hostBindings !== null || c.hostVars !== 0 || c.hostAttrs !== null) && Gd(c, l); + let c = e12.data[a], l = t[a]; + cr(a), (c.hostBindings !== null || c.hostVars !== 0 || c.hostAttrs !== null) && Jp(c, l); } } finally { - he(-1), wn(s); + je(-1), cr(s); } } -function Gd(e6, t) { - e6.hostBindings !== null && e6.hostBindings(1, t); +function Jp(e12, t) { + e12.hostBindings !== null && e12.hostBindings(1, t); } -function qd(e6, t, n, r, o, i) { +function Xp(e12, t, n, r, o, i) { let s = i[t]; if (s !== null) for (let a = 0; a < s.length; a += 2) { let c = s[a], l = s[a + 1]; - qo(r, n, c, l); + ns(r, n, c, l); } } -function Zd(e6, t, n, r, o) { - let i = U + n, s = t[y], a = o(s, t, e6, r, n); - t[i] = a, Dt(e6, true); - let c = e6.type === 2; - return c ? (ic(t[P], a, e6), (As() === 0 || Ss(e6)) && _t(a, t), Rs()) : _t(a, t), Eo() && (!c || !oi(e6)) && mc(s, t, a, e6), e6; +function eh(e12, t, n, r, o) { + let i = F + n, s = t[m], a = o(s, t, e12, r, n); + t[i] = a, Nt(e12, true); + let c = e12.type === 2; + return c ? (au(t[O], a, e12), (Ec() === 0 || yi(e12)) && kt(a, t), Ic()) : kt(a, t), fr() && (!c || !xs(e12)) && Us(s, t, a, e12), e12; +} +function th(e12) { + let t = e12; + return Ti() ? Mc() : (t = t.parent, Nt(t, false)), t; } -function Qd(e6) { - let t = e6; - return fo() ? js() : (t = t.parent, Dt(t, false)), t; +function nh(e12, t) { + let n = e12[De]; + if (!n) + return; + let r; + try { + r = n.get(rt, null); + } catch { + r = null; + } + r?.(t); } -function Yd(e6, t, n, r, o) { - let i = e6.inputs?.[r], s = e6.hostDirectiveInputs?.[r], a = false; +function rh(e12, t, n, r, o) { + let i = e12.inputs?.[r], s = e12.hostDirectiveInputs?.[r], a = false; if (s) for (let c = 0; c < s.length; c += 2) { let l = s[c], u = s[c + 1], d = t.data[l]; - qo(d, n[l], u, o), a = true; + ns(d, n[l], u, o), a = true; } if (i) for (let c of i) { let l = n[c], u = t.data[c]; - qo(u, l, r, o), a = true; + ns(u, l, r, o), a = true; } return a; } -function Kd(e6, t) { - let n = pe(t, e6), r = n[y]; - Jd(r, n); - let o = n[q]; - o !== null && n[hn] === null && (n[hn] = Qa(o, n[_e])), M(w.ComponentStart); +function oh(e12, t) { + let n = Ce(t, e12), r = n[m]; + ih(r, n); + let o = n[ne]; + o !== null && n[wt] === null && (n[wt] = Yl(o, n[De])), T(C.ComponentStart); try { - vc(r, n, n[L]); + Ws(r, n, n[x]); } finally { - M(w.ComponentEnd, n[L]); + T(C.ComponentEnd, n[x]); } } -function Jd(e6, t) { - for (let n = t.length; n < e6.blueprint.length; n++) - t.push(e6.blueprint[n]); +function ih(e12, t) { + for (let n = t.length; n < e12.blueprint.length; n++) + t.push(e12.blueprint[n]); } -function vc(e6, t, n) { - Cn(t); +function Ws(e12, t, n) { + ur(t); try { - let r = e6.viewQuery; - r !== null && Po(1, r, n); - let o = e6.template; - o !== null && yc(e6, t, o, 1, n), e6.firstCreatePass && (e6.firstCreatePass = false), t[mn]?.finishViewCreation(e6), e6.staticContentQueries && Ya(e6, t), e6.staticViewQueries && Po(2, e6.viewQuery, n); - let i = e6.components; - i !== null && Xd(t, i); + let r = e12.viewQuery; + r !== null && Gi(1, r, n); + let o = e12.template; + o !== null && mu(e12, t, o, 1, n), e12.firstCreatePass && (e12.firstCreatePass = false), t[ue]?.finishViewCreation(e12), e12.staticContentQueries && Kl(e12, t), e12.staticViewQueries && Gi(2, e12.viewQuery, n); + let i = e12.components; + i !== null && sh(t, i); } catch (r) { - throw e6.firstCreatePass && (e6.incompleteFirstPass = true, e6.firstCreatePass = false), r; + throw e12.firstCreatePass && (e12.incompleteFirstPass = true, e12.firstCreatePass = false), r; } finally { - t[h] &= -5, Tn(); + t[y] &= -5, dr(); } } -function Xd(e6, t) { +function sh(e12, t) { for (let n = 0; n < t.length; n++) - Kd(e6, t[n]); + oh(e12, t[n]); } -function Nt(e6, t, n, r, o = false) { +function qr(e12, t, n, r) { + let o = g(null); + try { + let i = t.tView, a = e12[y] & 4096 ? 4096 : 16, c = js(e12, i, n, a, null, t, null, null, r?.injector ?? null, r?.embeddedViewInjector ?? null, r?.dehydratedView ?? null), l = e12[t.index]; + c[Oe] = l; + let u = e12[ue]; + return u !== null && (c[ue] = u.createEmbeddedView(i)), Ws(i, c, n), c; + } finally { + g(o); + } +} +function an(e12, t) { + return !t || t.firstChild === null || Vl(e12); +} +function cn(e12, t, n, r, o = false) { for (; n !== null; ) { if (n.type === 128) { n = o ? n.projectionNext : n.next; continue; } let i = t[n.index]; - i !== null && r.push(fe(i)), de(i) && Ec(i, r); + i !== null && r.push(ee(i)), re(i) && vu(i, r); let s = n.type; if (s & 8) - Nt(e6, t, n.child, r); + cn(e12, t, n.child, r); else if (s & 32) { - let a = dc(n, t), c; + let a = Vs(n, t), c; for (; c = a(); ) r.push(c); } else if (s & 16) { - let a = Ld(t, n); + let a = gu(t, n); if (Array.isArray(a)) r.push(...a); else { - let c = Te(t[Q]); - Nt(c[y], c, a, r, true); + let c = Ae(t[X]); + cn(c[m], c, a, r, true); } } n = o ? n.projectionNext : n.next; } return r; } -function Ec(e6, t) { - for (let n = oe; n < e6.length; n++) { - let r = e6[n], o = r[y].firstChild; - o !== null && Nt(r[y], r, o, t); +function vu(e12, t) { + for (let n = S; n < e12.length; n++) { + let r = e12[n], o = r[m].firstChild; + o !== null && cn(r[m], r, o, t); } - e6[En] !== e6[q] && t.push(e6[En]); + e12[Pe] !== e12[ne] && t.push(e12[Pe]); } -function Ic(e6) { - if (e6[vn] !== null) { - for (let t of e6[vn]) +function Eu(e12) { + if (e12[or] !== null) { + for (let t of e12[or]) t.impl.addSequence(t); - e6[vn].length = 0; + e12[or].length = 0; } } -var Dc = []; -function ef(e6) { - return e6[F] ?? tf(e6); +var Iu = []; +function ah(e12) { + return e12[G] ?? ch(e12); } -function tf(e6) { - let t = Dc.pop() ?? Object.create(rf); - return t.lView = e6, t; +function ch(e12) { + let t = Iu.pop() ?? Object.create(uh); + return t.lView = e12, t; } -function nf(e6) { - e6.lView[F] !== e6 && (e6.lView = null, Dc.push(e6)); +function lh(e12) { + e12.lView[G] !== e12 && (e12.lView = null, Iu.push(e12)); } -var rf = V(A({}, Gt), { consumerIsAlwaysLive: true, kind: "template", consumerMarkedDirty: (e6) => { - It(e6.lView); +var uh = A(N({}, ut), { consumerIsAlwaysLive: true, kind: "template", consumerMarkedDirty: (e12) => { + St(e12.lView); }, consumerOnSignalRead() { - this.lView[F] = this; + this.lView[G] = this; } }); -function of(e6) { - let t = e6[F] ?? Object.create(sf); - return t.lView = e6, t; -} -var sf = V(A({}, Gt), { consumerIsAlwaysLive: true, kind: "template", consumerMarkedDirty: (e6) => { - let t = Te(e6.lView); - for (; t && !wc(t[y]); ) - t = Te(t); - t && ao(t); +function dh(e12) { + let t = e12[G] ?? Object.create(fh); + return t.lView = e12, t; +} +var fh = A(N({}, ut), { consumerIsAlwaysLive: true, kind: "template", consumerMarkedDirty: (e12) => { + let t = Ae(e12.lView); + for (; t && !Du(t[m]); ) + t = Ae(t); + t && Ii(t); }, consumerOnSignalRead() { - this.lView[F] = this; + this.lView[G] = this; } }); -function wc(e6) { - return e6.type !== 2; +function Du(e12) { + return e12.type !== 2; } -function Cc(e6) { - if (e6[gt] === null) +function wu(e12) { + if (e12[xe] === null) return; let t = true; for (; t; ) { let n = false; - for (let r of e6[gt]) + for (let r of e12[xe]) r.dirty && (n = true, r.zone === null || Zone.current === r.zone ? r.run() : r.zone.run(() => r.run())); - t = n && !!(e6[h] & 8192); + t = n && !!(e12[y] & 8192); } } -var af = 100; -function Tc(e6, t = 0) { - let r = e6[Z].rendererFactory, o = false; +var ph = 100; +function Cu(e12, t = 0) { + let r = e12[le].rendererFactory, o = false; o || r.begin?.(); try { - cf(e6, t); + hh(e12, t); } finally { o || r.end?.(); } } -function cf(e6, t) { - let n = po(); +function hh(e12, t) { + let n = Mi(); try { - ho(true), Qo(e6, t); + Gt(true), is(e12, t); let r = 0; - for (; Et(e6); ) { - if (r === af) - throw new g(103, false); - r++, Qo(e6, 1); + for (; Xt(e12); ) { + if (r === ph) + throw new v(103, false); + r++, is(e12, 1); } } finally { - ho(n); + Gt(n); } } -function lf(e6, t, n, r) { - if (xe(t)) +function gh(e12, t, n, r) { + if (nt(t)) return; - let o = t[h], i = false, s = false; - Cn(t); + let o = t[y], i = false, s = false; + ur(t); let a = true, c = null, l = null; - i || (wc(e6) ? (l = ef(t), c = dr(l)) : Wt() === null ? (a = false, l = of(t), c = dr(l)) : t[F] && (qt(t[F]), t[F] = null)); + i || (Du(e12) ? (l = ah(t), c = Bt(l)) : xn() === null ? (a = false, l = dh(t), c = Bt(l)) : t[G] && (dt(t[G]), t[G] = null)); try { - so(t), Hs(e6.bindingStartIndex), n !== null && yc(e6, t, n, 2, r); + Ei(t), _c(e12.bindingStartIndex), n !== null && mu(e12, t, n, 2, r); let u = (o & 3) === 3; if (!i) if (u) { - let f = e6.preOrderCheckHooks; - f !== null && Nn(t, f, null); + let p = e12.preOrderCheckHooks; + p !== null && Ir(t, p, null); } else { - let f = e6.preOrderHooks; - f !== null && xn(t, f, 0, null), bo(t, 0); + let p = e12.preOrderHooks; + p !== null && Dr(t, p, 0, null), Li(t, 0); } - if (s || uf(t), Cc(t), Mc(t, 0), e6.contentQueries !== null && Ya(e6, t), !i) + if (s || mh(t), wu(t), bu(t, 0), e12.contentQueries !== null && Kl(e12, t), !i) if (u) { - let f = e6.contentCheckHooks; - f !== null && Nn(t, f); + let p = e12.contentCheckHooks; + p !== null && Ir(t, p); } else { - let f = e6.contentHooks; - f !== null && xn(t, f, 1), bo(t, 1); + let p = e12.contentHooks; + p !== null && Dr(t, p, 1), Li(t, 1); } - ff(e6, t); - let d = e6.components; - d !== null && bc(t, d, 0); - let p = e6.viewQuery; - if (p !== null && Po(2, p, r), !i) + vh(e12, t); + let d = e12.components; + d !== null && Mu(t, d, 0); + let f = e12.viewQuery; + if (f !== null && Gi(2, f, r), !i) if (u) { - let f = e6.viewCheckHooks; - f !== null && Nn(t, f); + let p = e12.viewCheckHooks; + p !== null && Ir(t, p); } else { - let f = e6.viewHooks; - f !== null && xn(t, f, 2), bo(t, 2); + let p = e12.viewHooks; + p !== null && Dr(t, p, 2), Li(t, 2); } - if (e6.firstUpdatePass === true && (e6.firstUpdatePass = false), t[yn]) { - for (let f of t[yn]) - f(); - t[yn] = null; + if (e12.firstUpdatePass === true && (e12.firstUpdatePass = false), t[rr]) { + for (let p of t[rr]) + p(); + t[rr] = null; } - i || (Ic(t), t[h] &= -73); + i || (Eu(t), t[y] &= -73); } catch (u) { - throw i || It(t), u; + throw i || St(t), u; } finally { - l !== null && (Hi(l, c), a && nf(l)), Tn(); + l !== null && (An(l, c), a && lh(l)), dr(); } } -function Mc(e6, t) { - for (let n = Ua(e6); n !== null; n = za(n)) - for (let r = oe; r < n.length; r++) { +function bu(e12, t) { + for (let n = $l(e12); n !== null; n = Ul(n)) + for (let r = S; r < n.length; r++) { let o = n[r]; - Sc(o, t); + Tu(o, t); } } -function uf(e6) { - for (let t = Ua(e6); t !== null; t = za(t)) { - if (!(t[h] & 2)) +function mh(e12) { + for (let t = $l(e12); t !== null; t = Ul(t)) { + if (!(t[y] & 2)) continue; - let n = t[mt]; + let n = t[tt]; for (let r = 0; r < n.length; r++) { let o = n[r]; - ao(o); + Ii(o); } } } -function df(e6, t, n) { - M(w.ComponentStart); - let r = pe(t, e6); +function yh(e12, t, n) { + T(C.ComponentStart); + let r = Ce(t, e12); try { - Sc(r, n); + Tu(r, n); } finally { - M(w.ComponentEnd, r[L]); + T(C.ComponentEnd, r[x]); } } -function Sc(e6, t) { - In(e6) && Qo(e6, t); +function Tu(e12, t) { + sr(e12) && is(e12, t); } -function Qo(e6, t) { - let r = e6[y], o = e6[h], i = e6[F], s = !!(t === 0 && o & 16); - if (s ||= !!(o & 64 && t === 0), s ||= !!(o & 1024), s ||= !!(i?.dirty && fr(i)), s ||= false, i && (i.dirty = false), e6[h] &= -9217, s) - lf(r, e6, r.template, e6[L]); +function is(e12, t) { + let r = e12[m], o = e12[y], i = e12[G], s = !!(t === 0 && o & 16); + if (s ||= !!(o & 64 && t === 0), s ||= !!(o & 1024), s ||= !!(i?.dirty && Rn(i)), s ||= false, i && (i.dirty = false), e12[y] &= -9217, s) + gh(r, e12, r.template, e12[x]); else if (o & 8192) { - let a = v(null); + let a = g(null); try { - Cc(e6), Mc(e6, 1); + wu(e12), bu(e12, 1); let c = r.components; - c !== null && bc(e6, c, 1), Ic(e6); + c !== null && Mu(e12, c, 1), Eu(e12); } finally { - v(a); + g(a); } } } -function bc(e6, t, n) { +function Mu(e12, t, n) { for (let r = 0; r < t.length; r++) - df(e6, t[r], n); + yh(e12, t[r], n); } -function ff(e6, t) { - let n = e6.hostBindingOpCodes; +function vh(e12, t) { + let n = e12.hostBindingOpCodes; if (n !== null) try { for (let r = 0; r < n.length; r++) { let o = n[r]; if (o < 0) - he(~o); + je(~o); else { let i = o, s = n[++r], a = n[++r]; - Bs(s, i); + xc(s, i); let c = t[i]; - M(w.HostBindingsUpdateStart, c); + T(C.HostBindingsUpdateStart, c); try { a(2, c); } finally { - M(w.HostBindingsUpdateEnd, c); + T(C.HostBindingsUpdateEnd, c); } } } } finally { - he(-1); + je(-1); } } -function _c(e6, t) { - let n = po() ? 64 : 1088; - for (e6[Z].changeDetectionScheduler?.notify(t); e6; ) { - e6[h] |= n; - let r = Te(e6); - if (Ze(e6) && !r) - return e6; - e6 = r; +function Gs(e12, t) { + let n = Mi() ? 64 : 1088; + for (e12[le].changeDetectionScheduler?.notify(t); e12; ) { + e12[y] |= n; + let r = Ae(e12); + if (_t(e12) && !r) + return e12; + e12 = r; } return null; } -function pf(e6, t) { - if (e6.length <= oe) +function _u(e12, t, n, r) { + return [e12, true, 0, t, null, r, null, n, null, null]; +} +function Su(e12, t) { + let n = S + t; + if (n < e12.length) + return e12[n]; +} +function Zr(e12, t, n, r = true) { + let o = t[m]; + if (Eh(o, t, e12, n), r) { + let s = os(n, e12), a = t[O], c = a.parentNode(e12[Pe]); + c !== null && Rp(o, e12[J], a, t, c, s); + } + let i = t[wt]; + i !== null && i.firstChild !== null && (i.firstChild = null); +} +function Nu(e12, t) { + let n = ln(e12, t); + return n !== void 0 && Wr(n[m], n), n; +} +function ln(e12, t) { + if (e12.length <= S) return; - let n = oe + t, r = e6[n]; + let n = S + t, r = e12[n]; if (r) { - let o = r[ht]; - o !== null && o !== e6 && fi(o, r), t > 0 && (e6[n - 1][ne] = r[ne]); - let i = Kr(e6, oe + t); - Td(r[y], r); - let s = i[mn]; - s !== null && s.detachView(i[y]), r[O] = null, r[ne] = null, r[h] &= -129; + let o = r[Oe]; + o !== null && o !== e12 && $s(o, r), t > 0 && (e12[n - 1][K] = r[K]); + let i = Qt(e12, S + t); + Ap(r[m], r); + let s = i[ue]; + s !== null && s.detachView(i[m]), r[R] = null, r[K] = null, r[y] &= -129; } return r; } -function hf(e6, t) { - let n = e6[mt], r = t[O]; - if (ue(r)) - e6[h] |= 2; +function Eh(e12, t, n, r) { + let o = S + r, i = n.length; + r > 0 && (n[o - 1][K] = t), r < i - S ? (t[K] = n[o], ci(n, S + r, t)) : (n.push(t), t[K] = null), t[R] = n; + let s = t[Oe]; + s !== null && n !== s && xu(s, t); + let a = t[ue]; + a !== null && a.insertView(e12), ar(t), t[y] |= 128; +} +function xu(e12, t) { + let n = e12[tt], r = t[R]; + if (Le(r)) + e12[y] |= 2; else { - let o = r[O][Q]; - t[Q] !== o && (e6[h] |= 2); + let o = r[R][X]; + t[X] !== o && (e12[y] |= 2); } - n === null ? e6[mt] = [t] : n.push(t); + n === null ? e12[tt] = [t] : n.push(t); } -var On = class { +var Pt = class { _lView; _cdRefInjectingView; _appRef = null; _attachedToViewContainer = false; exhaustive; get rootNodes() { - let t = this._lView, n = t[y]; - return Nt(n, t, n.firstChild, []); + let t = this._lView, n = t[m]; + return cn(n, t, n.firstChild, []); } constructor(t, n) { this._lView = t, this._cdRefInjectingView = n; } get context() { - return this._lView[L]; + return this._lView[x]; } set context(t) { - this._lView[L] = t; + this._lView[x] = t; } get destroyed() { - return xe(this._lView); + return nt(this._lView); } destroy() { if (this._appRef) this._appRef.detachView(this); else if (this._attachedToViewContainer) { - let t = this._lView[O]; - if (de(t)) { - let n = t[Ms], r = n ? n.indexOf(this) : -1; - r > -1 && (pf(t, r), Kr(n, r)); + let t = this._lView[R]; + if (re(t)) { + let n = t[Jt], r = n ? n.indexOf(this) : -1; + r > -1 && (ln(t, r), Qt(n, r)); } this._attachedToViewContainer = false; } - Sd(this._lView[y], this._lView); + Wr(this._lView[m], this._lView); } onDestroy(t) { - lo(this._lView, t); + Di(this._lView, t); } markForCheck() { - _c(this._cdRefInjectingView || this._lView, 4); + Gs(this._cdRefInjectingView || this._lView, 4); } detach() { - this._lView[h] &= -129; + this._lView[y] &= -129; } reattach() { - co(this._lView), this._lView[h] |= 128; + ar(this._lView), this._lView[y] |= 128; } detectChanges() { - this._lView[h] |= 1024, Tc(this._lView); + this._lView[y] |= 1024, Cu(this._lView); } checkNoChanges() { } attachToViewContainerRef() { if (this._appRef) - throw new g(902, false); + throw new v(902, false); this._attachedToViewContainer = true; } detachFromAppRef() { this._appRef = null; - let t = Ze(this._lView), n = this._lView[ht]; - n !== null && !t && fi(n, this._lView), gc(this._lView[y], this._lView); + let t = _t(this._lView), n = this._lView[Oe]; + n !== null && !t && $s(n, this._lView), hu(this._lView[m], this._lView); } attachToAppRef(t) { if (this._attachedToViewContainer) - throw new g(902, false); + throw new v(902, false); this._appRef = t; - let n = Ze(this._lView), r = this._lView[ht]; - r !== null && !n && hf(r, this._lView), co(this._lView); + let n = _t(this._lView), r = this._lView[Oe]; + r !== null && !n && xu(r, this._lView), ar(this._lView); } }; -function gi(e6, t, n, r, o) { - let i = e6.data[t]; +var un = /* @__PURE__ */ (() => { + class e12 { + _declarationLView; + _declarationTContainer; + elementRef; + static __NG_ELEMENT_ID__ = Ih; + constructor(n, r, o) { + this._declarationLView = n, this._declarationTContainer = r, this.elementRef = o; + } + get ssrId() { + return this._declarationTContainer.tView?.ssrId || null; + } + createEmbeddedView(n, r) { + return this.createEmbeddedViewImpl(n, r); + } + createEmbeddedViewImpl(n, r, o) { + let i = qr(this._declarationLView, this._declarationTContainer, n, { embeddedViewInjector: r, dehydratedView: o }); + return new Pt(i); + } + } + return e12; +})(); +function Ih() { + return qs(pe(), M()); +} +function qs(e12, t) { + return e12.type & 4 ? new un(t, e12, Ft(e12, t)) : null; +} +function Qr(e12, t, n, r, o) { + let i = e12.data[t]; if (i === null) - i = gf(e6, t, n, r, o), Vs() && (i.flags |= 32); + i = Dh(e12, t, n, r, o), Nc() && (i.flags |= 32); else if (i.type & 64) { i.type = n, i.value = r, i.attrs = o; - let s = Fs(); + let s = Tc(); i.injectorIndex = s === null ? -1 : s.injectorIndex; } - return Dt(i, true), i; + return Nt(i, true), i; } -function gf(e6, t, n, r, o) { - let i = uo(), s = fo(), a = s ? i : i && i.parent, c = e6.data[t] = yf(e6, a, n, t, r, o); - return mf(e6, c, i, s), c; +function Dh(e12, t, n, r, o) { + let i = bi(), s = Ti(), a = s ? i : i && i.parent, c = e12.data[t] = Ch(e12, a, n, t, r, o); + return wh(e12, c, i, s), c; } -function mf(e6, t, n, r) { - e6.firstChild === null && (e6.firstChild = t), n !== null && (r ? n.child == null && t.parent !== null && (n.child = t) : n.next === null && (n.next = t, t.prev = n)); +function wh(e12, t, n, r) { + e12.firstChild === null && (e12.firstChild = t), n !== null && (r ? n.child == null && t.parent !== null && (n.child = t) : n.next === null && (n.next = t, t.prev = n)); } -function yf(e6, t, n, r, o, i) { +function Ch(e12, t, n, r, o, i) { let s = t ? t.injectorIndex : -1, a = 0; - return Os() && (a |= 128), { type: n, index: r, insertBeforeIndex: null, injectorIndex: s, directiveStart: -1, directiveEnd: -1, directiveStylingLast: -1, componentOffset: -1, controlDirectiveIndex: -1, customControlIndex: -1, propertyBindings: null, flags: a, providerIndexes: 0, value: o, attrs: i, mergedAttrs: null, localNames: null, initialInputs: null, inputs: null, hostDirectiveInputs: null, outputs: null, hostDirectiveOutputs: null, directiveToIndex: null, tView: null, next: null, prev: null, projectionNext: null, child: null, parent: t, projection: null, styles: null, stylesWithoutHost: null, residualStyles: void 0, classes: null, classesWithoutHost: null, residualClasses: void 0, classBindings: 0, styleBindings: 0 }; + return wc() && (a |= 128), { type: n, index: r, insertBeforeIndex: null, injectorIndex: s, directiveStart: -1, directiveEnd: -1, directiveStylingLast: -1, componentOffset: -1, controlDirectiveIndex: -1, customControlIndex: -1, propertyBindings: null, flags: a, providerIndexes: 0, value: o, attrs: i, mergedAttrs: null, localNames: null, initialInputs: null, inputs: null, hostDirectiveInputs: null, outputs: null, hostDirectiveOutputs: null, directiveToIndex: null, tView: null, next: null, prev: null, projectionNext: null, child: null, parent: t, projection: null, styles: null, stylesWithoutHost: null, residualStyles: void 0, classes: null, classesWithoutHost: null, residualClasses: void 0, classBindings: 0, styleBindings: 0 }; +} +function bh(e12) { + let t = e12[gi] ?? [], r = e12[R][O], o = []; + for (let i of t) + i.data[ql] !== void 0 ? o.push(i) : Th(i, r); + e12[gi] = o; +} +function Th(e12, t) { + let n = 0, r = e12.firstChild; + if (r) { + let o = e12.data[Gl]; + for (; n < o; ) { + let i = r.nextSibling; + su(t, r, false), r = i, n++; + } + } +} +var Mh = () => null; +var _h = () => null; +function ss(e12, t) { + return Mh(e12, t); +} +function Au(e12, t, n) { + return _h(e12, t, n); } -var Nc = class { +var Ru = class { }; -var qn = class { +var Yr = class { }; -var Yo = class { +var as = class { resolveComponentFactory(t) { - throw new g(917, false); + throw new v(917, false); } }; -var Zn = class { - static NULL = new Yo(); +var Kr = class { + static NULL = new as(); }; -var Re = class { +var st = class { }; -var xc = (() => { - class e6 { - static \u0275prov = S({ token: e6, providedIn: "root", factory: () => null }); +var Ou = (() => { + class e12 { + static \u0275prov = _({ token: e12, providedIn: "root", factory: () => null }); } - return e6; + return e12; })(); -var An = {}; -var Ko = class { +var Cr = {}; +var cs = class { injector; parentInjector; constructor(t, n) { this.injector = t, this.parentInjector = n; } get(t, n, r) { - let o = this.injector.get(t, An, r); - return o !== An || n === An ? o : this.parentInjector.get(t, n, r); + let o = this.injector.get(t, Cr, r); + return o !== Cr || n === Cr ? o : this.parentInjector.get(t, n, r); } }; -function Ln(e6, t, n) { - let r = n ? e6.styles : null, o = n ? e6.classes : null, i = 0; +function xr(e12, t, n) { + let r = n ? e12.styles : null, o = n ? e12.classes : null, i = 0; if (t !== null) for (let s = 0; s < t.length; s++) { let a = t[s]; if (typeof a == "number") i = a; else if (i == 1) - o = Br(o, a); + o = Jo(o, a); else if (i == 2) { let c = a, l = t[++s]; - r = Br(r, c + ": " + l + ";"); + r = Jo(r, c + ": " + l + ";"); } } - n ? e6.styles = r : e6.stylesWithoutHost = r, n ? e6.classes = o : e6.classesWithoutHost = o; + n ? e12.styles = r : e12.stylesWithoutHost = r, n ? e12.classes = o : e12.classesWithoutHost = o; } -function kt(e6, t = 0) { - let n = H(); +function ku(e12, t = 0) { + let n = M(); if (n === null) - return I(e6, t); - let r = Qe(); - return Fa(r, n, k(e6), t); + return w(e12, t); + let r = pe(); + return Fl(r, n, W(e12), t); } -function vf(e6, t, n, r, o) { - let i = r === null ? null : { "": -1 }, s = o(e6, n); +function Sh(e12, t, n, r, o) { + let i = r === null ? null : { "": -1 }, s = o(e12, n); if (s !== null) { let a = s, c = null, l = null; for (let u of s) @@ -3629,82 +4099,82 @@ function vf(e6, t, n, r, o) { [a, c, l] = u.resolveHostDirectives(s); break; } - Df(e6, t, n, a, i, c, l); + Ah(e12, t, n, a, i, c, l); } - i !== null && r !== null && Ef(n, r, i); + i !== null && r !== null && Nh(n, r, i); } -function Ef(e6, t, n) { - let r = e6.localNames = []; +function Nh(e12, t, n) { + let r = e12.localNames = []; for (let o = 0; o < t.length; o += 2) { let i = n[t[o + 1]]; if (i == null) - throw new g(-301, false); + throw new v(-301, false); r.push(t[o], i); } } -function If(e6, t, n) { - t.componentOffset = n, (e6.components ??= []).push(t.index); +function xh(e12, t, n) { + t.componentOffset = n, (e12.components ??= []).push(t.index); } -function Df(e6, t, n, r, o, i, s) { +function Ah(e12, t, n, r, o, i, s) { let a = r.length, c = null; - for (let p = 0; p < a; p++) { - let f = r[p]; - c === null && qe(f) && (c = f, If(e6, n, p)), Su(Ra(n, t), e6, f.type); + for (let f = 0; f < a; f++) { + let p = r[f]; + c === null && Mt(p) && (c = p, xh(e12, n, f)), Rf(Ol(n, t), e12, p.type); } - bf(n, e6.data.length, a), c?.viewProvidersResolver && c.viewProvidersResolver(c); - for (let p = 0; p < a; p++) { - let f = r[p]; - f.providersResolver && f.providersResolver(f); + Fh(n, e12.data.length, a), c?.viewProvidersResolver && c.viewProvidersResolver(c); + for (let f = 0; f < a; f++) { + let p = r[f]; + p.providersResolver && p.providersResolver(p); } - let l = false, u = false, d = lc(e6, t, a, null); + let l = false, u = false, d = lu(e12, t, a, null); a > 0 && (n.directiveToIndex = /* @__PURE__ */ new Map()); - for (let p = 0; p < a; p++) { - let f = r[p]; - if (n.mergedAttrs = ti(n.mergedAttrs, f.hostAttrs), Cf(e6, n, t, d, f), Sf(d, f, o), s !== null && s.has(f)) { - let [sr, el] = s.get(f); - n.directiveToIndex.set(f.type, [d, sr + n.directiveStart, el + n.directiveStart]); + for (let f = 0; f < a; f++) { + let p = r[f]; + if (n.mergedAttrs = Fr(n.mergedAttrs, p.hostAttrs), Oh(e12, n, t, d, p), Lh(d, p, o), s !== null && s.has(p)) { + let [k, P] = s.get(p); + n.directiveToIndex.set(p.type, [d, k + n.directiveStart, P + n.directiveStart]); } else - (i === null || !i.has(f)) && n.directiveToIndex.set(f.type, d); - f.contentQueries !== null && (n.flags |= 4), (f.hostBindings !== null || f.hostAttrs !== null || f.hostVars !== 0) && (n.flags |= 64); - let T = f.type.prototype; - !l && (T.ngOnChanges || T.ngOnInit || T.ngDoCheck) && ((e6.preOrderHooks ??= []).push(n.index), l = true), !u && (T.ngOnChanges || T.ngDoCheck) && ((e6.preOrderCheckHooks ??= []).push(n.index), u = true), d++; + (i === null || !i.has(p)) && n.directiveToIndex.set(p.type, d); + p.contentQueries !== null && (n.flags |= 4), (p.hostBindings !== null || p.hostAttrs !== null || p.hostVars !== 0) && (n.flags |= 64); + let h = p.type.prototype; + !l && (h.ngOnChanges || h.ngOnInit || h.ngDoCheck) && ((e12.preOrderHooks ??= []).push(n.index), l = true), !u && (h.ngOnChanges || h.ngDoCheck) && ((e12.preOrderCheckHooks ??= []).push(n.index), u = true), d++; } - wf(e6, n, i); + Rh(e12, n, i); } -function wf(e6, t, n) { +function Rh(e12, t, n) { for (let r = t.directiveStart; r < t.directiveEnd; r++) { - let o = e6.data[r]; + let o = e12.data[r]; if (n === null || !n.has(o)) - Ia(0, t, o, r), Ia(1, t, o, r), wa(t, r, false); + hl(0, t, o, r), hl(1, t, o, r), ml(t, r, false); else { let i = n.get(o); - Da(0, t, i, r), Da(1, t, i, r), wa(t, r, true); + gl(0, t, i, r), gl(1, t, i, r), ml(t, r, true); } } } -function Ia(e6, t, n, r) { - let o = e6 === 0 ? n.inputs : n.outputs; +function hl(e12, t, n, r) { + let o = e12 === 0 ? n.inputs : n.outputs; for (let i in o) if (o.hasOwnProperty(i)) { let s; - e6 === 0 ? s = t.inputs ??= {} : s = t.outputs ??= {}, s[i] ??= [], s[i].push(r), Ac(t, i); + e12 === 0 ? s = t.inputs ??= {} : s = t.outputs ??= {}, s[i] ??= [], s[i].push(r), Pu(t, i); } } -function Da(e6, t, n, r) { - let o = e6 === 0 ? n.inputs : n.outputs; +function gl(e12, t, n, r) { + let o = e12 === 0 ? n.inputs : n.outputs; for (let i in o) if (o.hasOwnProperty(i)) { let s = o[i], a; - e6 === 0 ? a = t.hostDirectiveInputs ??= {} : a = t.hostDirectiveOutputs ??= {}, a[s] ??= [], a[s].push(r, i), Ac(t, s); + e12 === 0 ? a = t.hostDirectiveInputs ??= {} : a = t.hostDirectiveOutputs ??= {}, a[s] ??= [], a[s].push(r, i), Pu(t, s); } } -function Ac(e6, t) { - t === "class" ? e6.flags |= 8 : t === "style" && (e6.flags |= 16); +function Pu(e12, t) { + t === "class" ? e12.flags |= 8 : t === "style" && (e12.flags |= 16); } -function wa(e6, t, n) { - let { attrs: r, inputs: o, hostDirectiveInputs: i } = e6; - if (r === null || !n && o === null || n && i === null || dd(e6)) { - e6.initialInputs ??= [], e6.initialInputs.push(null); +function ml(e12, t, n) { + let { attrs: r, inputs: o, hostDirectiveInputs: i } = e12; + if (r === null || !n && o === null || n && i === null || Ep(e12)) { + e12.initialInputs ??= [], e12.initialInputs.push(null); return; } let s = null, a = 0; @@ -3735,107 +4205,165 @@ function wa(e6, t, n) { } a += 2; } - e6.initialInputs ??= [], e6.initialInputs.push(s); + e12.initialInputs ??= [], e12.initialInputs.push(s); } -function Cf(e6, t, n, r, o) { - e6.data[r] = o; - let i = o.factory || (o.factory = $e(o.type, true)), s = new bt(i, qe(o), kt, null); - e6.blueprint[r] = s, n[r] = s, Tf(e6, t, r, lc(e6, n, o.hostVars, tt), o); +function Oh(e12, t, n, r, o) { + e12.data[r] = o; + let i = o.factory || (o.factory = Et(o.type, true)), s = new sn(i, Mt(o), ku, null); + e12.blueprint[r] = s, n[r] = s, kh(e12, t, r, lu(e12, n, o.hostVars, Se), o); } -function Tf(e6, t, n, r, o) { +function kh(e12, t, n, r, o) { let i = o.hostBindings; if (i) { - let s = e6.hostBindingOpCodes; - s === null && (s = e6.hostBindingOpCodes = []); + let s = e12.hostBindingOpCodes; + s === null && (s = e12.hostBindingOpCodes = []); let a = ~t.index; - Mf(s) != a && s.push(a), s.push(n, r, i); + Ph(s) != a && s.push(a), s.push(n, r, i); } } -function Mf(e6) { - let t = e6.length; +function Ph(e12) { + let t = e12.length; for (; t > 0; ) { - let n = e6[--t]; + let n = e12[--t]; if (typeof n == "number" && n < 0) return n; } return 0; } -function Sf(e6, t, n) { +function Lh(e12, t, n) { if (n) { if (t.exportAs) for (let r = 0; r < t.exportAs.length; r++) - n[t.exportAs[r]] = e6; - qe(t) && (n[""] = e6); + n[t.exportAs[r]] = e12; + Mt(t) && (n[""] = e12); } } -function bf(e6, t, n) { - e6.flags |= 1, e6.directiveStart = t, e6.directiveEnd = t + n, e6.providerIndexes = t; +function Fh(e12, t, n) { + e12.flags |= 1, e12.directiveStart = t, e12.directiveEnd = t + n, e12.providerIndexes = t; } -function _f(e6, t, n, r, o, i, s, a) { - let c = t[y], l = c.consts, u = vt(l, s), d = gi(c, e6, n, r, u); - return i && vf(c, t, d, vt(l, a), o), d.mergedAttrs = ti(d.mergedAttrs, d.attrs), d.attrs !== null && Ln(d, d.attrs, false), d.mergedAttrs !== null && Ln(d, d.mergedAttrs, true), c.queries !== null && c.queries.elementStart(c, d), d; +function jh(e12, t, n, r, o, i, s, a) { + let c = t[m], l = c.consts, u = fe(l, s), d = Qr(c, e12, n, r, u); + return i && Sh(c, t, d, fe(l, a), o), d.mergedAttrs = Fr(d.mergedAttrs, d.attrs), d.attrs !== null && xr(d, d.attrs, false), d.mergedAttrs !== null && xr(d, d.mergedAttrs, true), c.queries !== null && c.queries.elementStart(c, d), d; } -function Nf(e6, t) { - yu(e6, t), oo(t) && e6.queries.elementEnd(t); +function Hh(e12, t) { + bf(e12, t), mi(t) && e12.queries.elementEnd(t); } -function xf(e6, t, n, r, o, i) { - let s = t.consts, a = vt(s, o), c = gi(t, e6, n, r, a); - if (c.mergedAttrs = ti(c.mergedAttrs, c.attrs), i != null) { - let l = vt(s, i); +function Vh(e12, t, n, r, o, i) { + let s = t.consts, a = fe(s, o), c = Qr(t, e12, n, r, a); + if (c.mergedAttrs = Fr(c.mergedAttrs, c.attrs), i != null) { + let l = fe(s, i); c.localNames = []; for (let u = 0; u < l.length; u += 2) c.localNames.push(l[u], -1); } - return c.attrs !== null && Ln(c, c.attrs, false), c.mergedAttrs !== null && Ln(c, c.mergedAttrs, true), t.queries !== null && t.queries.elementStart(t, c), c; + return c.attrs !== null && xr(c, c.attrs, false), c.mergedAttrs !== null && xr(c, c.mergedAttrs, true), t.queries !== null && t.queries.elementStart(t, c), c; } -function Rc(e6, t, n) { - if (n === tt) +function yn(e12, t, n) { + if (n === Se) return false; - let r = e6[t]; - return Object.is(r, n) ? false : (e6[t] = n, true); + let r = e12[t]; + return Object.is(r, n) ? false : (e12[t] = n, true); +} +function Bh(e12, t, n) { + return function r(o) { + let i = r.__ngNativeEl__; + i !== void 0 && zf(o, i); + let s = Tt(e12) ? Ce(e12.index, t) : t; + Gs(s, 5); + let a = t[x], c = yl(t, a, n, o), l = r.__ngNextListenerFn__; + for (; l; ) + c = yl(t, a, l, o) && c, l = l.__ngNextListenerFn__; + return c; + }; +} +function yl(e12, t, n, r) { + let o = g(null); + try { + return T(C.OutputStart, t, n), n(r) !== false; + } catch (i) { + return nh(e12, i), false; + } finally { + T(C.OutputEnd, t, n), g(o); + } +} +function $h(e12, t, n, r, o, i, s, a) { + let c = yi(e12), l = false, u = null; + if (!r && c && (u = zh(t, n, i, e12.index)), u !== null) { + let d = u.__ngLastListenerFn__ || u; + d.__ngNextListenerFn__ = s, u.__ngLastListenerFn__ = s, l = true; + } else { + let d = de(e12, n), f = r ? r(d) : d; + Gf(n, f, i, a), r || (a.__ngNativeEl__ = d); + let p = o.listen(f, i, a); + if (!Uh(i)) { + let h = r ? (k) => r(ee(k[e12.index])) : e12.index; + Wh(h, t, n, i, a, p, false); + } + } + return l; +} +function Uh(e12) { + return e12.startsWith("animation") || e12.startsWith("transition"); +} +function zh(e12, t, n, r) { + let o = e12.cleanup; + if (o != null) + for (let i = 0; i < o.length - 1; i += 2) { + let s = o[i]; + if (s === n && o[i + 1] === r) { + let a = t[Ct], c = o[i + 2]; + return a && a.length > c ? a[c] : null; + } + typeof s == "string" && (i += 2); + } + return null; } -var Jo = Symbol("BINDING"); -function Af(e6) { - return e6.debugInfo?.className || e6.type.name || null; +function Wh(e12, t, n, r, o, i, s) { + let a = t.firstCreatePass ? Ci(t) : null, c = wi(n), l = c.length; + c.push(o, i), a && a.push(r, e12, l, (l + 1) * (s ? -1 : 1)); } -var Xo = class extends Zn { +var ls = Symbol("BINDING"); +function Gh(e12) { + return e12.debugInfo?.className || e12.type.name || null; +} +var us = class extends Kr { ngModule; constructor(t) { super(), this.ngModule = t; } resolveComponentFactory(t) { - let n = ut(t); - return new Pn(n, this.ngModule); + let n = Ye(t); + return new dn(n, this.ngModule); } }; -function Rf(e6) { - return Object.keys(e6).map((t) => { - let [n, r, o] = e6[t], i = { propName: n, templateName: t, isSignal: (r & Gn.SignalBased) !== 0 }; +function qh(e12) { + return Object.keys(e12).map((t) => { + let [n, r, o] = e12[t], i = { propName: n, templateName: t, isSignal: (r & zr.SignalBased) !== 0 }; return o && (i.transform = o), i; }); } -function kf(e6) { - return Object.keys(e6).map((t) => ({ propName: e6[t], templateName: t })); +function Zh(e12) { + return Object.keys(e12).map((t) => ({ propName: e12[t], templateName: t })); } -function Of(e6, t, n) { - let r = t instanceof $ ? t : t?.injector; - return r && e6.getStandaloneInjector !== null && (r = e6.getStandaloneInjector(r) || r), r ? new Ko(n, r) : n; +function Qh(e12, t, n) { + let r = t instanceof Q ? t : t?.injector; + return r && e12.getStandaloneInjector !== null && (r = e12.getStandaloneInjector(r) || r), r ? new cs(n, r) : n; } -function Lf(e6) { - let t = e6.get(Re, null); +function Yh(e12) { + let t = e12.get(st, null); if (t === null) - throw new g(407, false); - let n = e6.get(xc, null), r = e6.get(Ue, null), o = e6.get(nt, null, { optional: true }); + throw new v(407, false); + let n = e12.get(Ou, null), r = e12.get(Ze, null), o = e12.get(jt, null, { optional: true }); return { rendererFactory: t, sanitizer: n, changeDetectionScheduler: r, ngReflect: false, tracingService: o }; } -function Pf(e6, t) { - let n = kc(e6); - return rc(t, n, n === "svg" ? bs : n === "math" ? _s : null); +function Kh(e12, t) { + let n = Lu(e12); + return ou(t, n, n === "svg" ? fc : n === "math" ? pc : null); } -function kc(e6) { - return (e6.selectors[0][0] || "div").toLowerCase(); +function Lu(e12) { + return (e12.selectors[0][0] || "div").toLowerCase(); } -var Pn = class extends qn { +var dn = class extends Yr { componentDef; ngModule; selector; @@ -3845,77 +4373,77 @@ var Pn = class extends qn { cachedInputs = null; cachedOutputs = null; get inputs() { - return this.cachedInputs ??= Rf(this.componentDef.inputs), this.cachedInputs; + return this.cachedInputs ??= qh(this.componentDef.inputs), this.cachedInputs; } get outputs() { - return this.cachedOutputs ??= kf(this.componentDef.outputs), this.cachedOutputs; + return this.cachedOutputs ??= Zh(this.componentDef.outputs), this.cachedOutputs; } constructor(t, n) { - super(), this.componentDef = t, this.ngModule = n, this.componentType = t.type, this.selector = pd(t.selectors), this.ngContentSelectors = t.ngContentSelectors ?? [], this.isBoundToModule = !!n; + super(), this.componentDef = t, this.ngModule = n, this.componentType = t.type, this.selector = Dp(t.selectors), this.ngContentSelectors = t.ngContentSelectors ?? [], this.isBoundToModule = !!n; } create(t, n, r, o, i, s) { - M(w.DynamicComponentStart); - let a = v(null); + T(C.DynamicComponentStart); + let a = g(null); try { - let c = this.componentDef, l = Of(c, o || this.ngModule, t), u = Lf(l), d = u.tracingService; - return d && d.componentCreate ? d.componentCreate(Af(c), () => this.createComponentRef(u, l, n, r, i, s)) : this.createComponentRef(u, l, n, r, i, s); + let c = this.componentDef, l = Qh(c, o || this.ngModule, t), u = Yh(l), d = u.tracingService; + return d && d.componentCreate ? d.componentCreate(Gh(c), () => this.createComponentRef(u, l, n, r, i, s)) : this.createComponentRef(u, l, n, r, i, s); } finally { - v(a); + g(a); } } createComponentRef(t, n, r, o, i, s) { - let a = this.componentDef, c = Ff(o, a, s, i), l = t.rendererFactory.createRenderer(null, a), u = o ? Vd(l, o, a.encapsulation, n) : Pf(a, l), d = s?.some(Ca) || i?.some((T) => typeof T != "function" && T.bindings.some(Ca)), p = ac(null, c, null, 512 | cc(a), null, null, t, l, n, null, Qa(u, n, true)); - p[U] = u, Cn(p); - let f = null; + let a = this.componentDef, c = Jh(o, a, s, i), l = t.rendererFactory.createRenderer(null, a), u = o ? Gp(l, o, a.encapsulation, n) : Kh(a, l), d = s?.some(vl) || i?.some((h) => typeof h != "function" && h.bindings.some(vl)), f = js(null, c, null, 512 | cu(a), null, null, t, l, n, null, Yl(u, n, true)); + f[F] = u, ur(f); + let p = null; try { - let T = _f(U, p, 2, "#host", () => c.directiveRegistry, true, 0); - ic(l, u, T), _t(u, p), jd(c, p, T), Hu(c, T, p), Nf(c, T), r !== void 0 && Hf(T, this.ngContentSelectors, r), f = pe(T.index, p), p[L] = f[L], vc(c, p, null); - } catch (T) { - throw f !== null && Oo(f), Oo(p), T; + let h = jh(F, f, 2, "#host", () => c.directiveRegistry, true, 0); + au(l, u, h), kt(u, f), Wp(c, f, h), Zf(c, h, f), Hh(c, h), r !== void 0 && eg(h, this.ngContentSelectors, r), p = Ce(h.index, f), f[x] = p[x], Ws(c, f, null); + } catch (h) { + throw p !== null && zi(p), zi(f), h; } finally { - M(w.DynamicComponentEnd), Tn(); + T(C.DynamicComponentEnd), dr(); } - return new Fn(this.componentType, p, !!d); + return new Ar(this.componentType, f, !!d); } }; -function Ff(e6, t, n, r) { - let o = e6 ? ["ng-version", "21.2.11"] : hd(t.selectors[0]), i = null, s = null, a = 0; +function Jh(e12, t, n, r) { + let o = e12 ? ["ng-version", "21.2.11"] : wp(t.selectors[0]), i = null, s = null, a = 0; if (n) for (let u of n) - a += u[Jo].requiredVars, u.create && (u.targetIdx = 0, (i ??= []).push(u)), u.update && (u.targetIdx = 0, (s ??= []).push(u)); + a += u[ls].requiredVars, u.create && (u.targetIdx = 0, (i ??= []).push(u)), u.update && (u.targetIdx = 0, (s ??= []).push(u)); if (r) for (let u = 0; u < r.length; u++) { let d = r[u]; if (typeof d != "function") - for (let p of d.bindings) { - a += p[Jo].requiredVars; - let f = u + 1; - p.create && (p.targetIdx = f, (i ??= []).push(p)), p.update && (p.targetIdx = f, (s ??= []).push(p)); + for (let f of d.bindings) { + a += f[ls].requiredVars; + let p = u + 1; + f.create && (f.targetIdx = p, (i ??= []).push(f)), f.update && (f.targetIdx = p, (s ??= []).push(f)); } } let c = [t]; if (r) for (let u of r) { - let d = typeof u == "function" ? u : u.type, p = Gr(d); - c.push(p); + let d = typeof u == "function" ? u : u.type, f = ri(d); + c.push(f); } - return sc(0, null, jf(i, s), 1, a, c, null, null, null, [o], null); + return Fs(0, null, Xh(i, s), 1, a, c, null, null, null, [o], null); } -function jf(e6, t) { - return !e6 && !t ? null : (n) => { - if (n & 1 && e6) - for (let r of e6) +function Xh(e12, t) { + return !e12 && !t ? null : (n) => { + if (n & 1 && e12) + for (let r of e12) r.create(); if (n & 2 && t) for (let r of t) r.update(); }; } -function Ca(e6) { - let t = e6[Jo].kind; +function vl(e12) { + let t = e12[ls].kind; return t === "input" || t === "twoWay"; } -var Fn = class extends Nc { +var Ar = class extends Ru { _rootLView; _hasInputBindings; instance; @@ -3926,20 +4454,20 @@ var Fn = class extends Nc { previousInputValues = null; _tNode; constructor(t, n, r) { - super(), this._rootLView = n, this._hasInputBindings = r, this._tNode = io(n[y], U), this.location = Va(this._tNode, n), this.instance = pe(this._tNode.index, n)[L], this.hostView = this.changeDetectorRef = new On(n, void 0), this.componentType = t; + super(), this._rootLView = n, this._hasInputBindings = r, this._tNode = ir(n[m], F), this.location = Ft(this._tNode, n), this.instance = Ce(this._tNode.index, n)[x], this.hostView = this.changeDetectorRef = new Pt(n, void 0), this.componentType = t; } setInput(t, n) { this._hasInputBindings; let r = this._tNode; if (this.previousInputValues ??= /* @__PURE__ */ new Map(), this.previousInputValues.has(t) && Object.is(this.previousInputValues.get(t), n)) return; - let o = this._rootLView, i = Yd(r, o[y], o, t, n); + let o = this._rootLView, i = rh(r, o[m], o, t, n); this.previousInputValues.set(t, n); - let s = pe(r.index, o); - _c(s, 1); + let s = Ce(r.index, o); + Gs(s, 1); } get injector() { - return new kn(this._tNode, this._rootLView); + return new ot(this._tNode, this._rootLView); } destroy() { this.hostView.destroy(); @@ -3948,22 +4476,383 @@ var Fn = class extends Nc { this.hostView.onDestroy(t); } }; -function Hf(e6, t, n) { - let r = e6.projection = []; +function eg(e12, t, n) { + let r = e12.projection = []; for (let o = 0; o < t.length; o++) { let i = n[o]; r.push(i != null && i.length ? Array.from(i) : null); } } -var jn = class { +var Jr = /* @__PURE__ */ (() => { + class e12 { + static __NG_ELEMENT_ID__ = tg; + } + return e12; +})(); +function tg() { + let e12 = pe(); + return Fu(e12, M()); +} +var ds = class e4 extends Jr { + _lContainer; + _hostTNode; + _hostLView; + constructor(t, n, r) { + super(), this._lContainer = t, this._hostTNode = n, this._hostLView = r; + } + get element() { + return Ft(this._hostTNode, this._hostLView); + } + get injector() { + return new ot(this._hostTNode, this._hostLView); + } + get parentInjector() { + let t = _s(this._hostTNode, this._hostLView); + if (xl(t)) { + let n = Mr(t, this._hostLView), r = Tr(t), o = n[m].data[r + 8]; + return new ot(o, n); + } else + return new ot(null, this._hostLView); + } + clear() { + for (; this.length > 0; ) + this.remove(this.length - 1); + } + get(t) { + let n = El(this._lContainer); + return n !== null && n[t] || null; + } + get length() { + return this._lContainer.length - S; + } + createEmbeddedView(t, n, r) { + let o, i; + typeof r == "number" ? o = r : r != null && (o = r.index, i = r.injector); + let s = ss(this._lContainer, t.ssrId), a = t.createEmbeddedViewImpl(n || {}, i, s); + return this.insertImpl(a, o, an(this._hostTNode, s)), a; + } + createComponent(t, n, r, o, i, s, a) { + let c = t && !vf(t), l; + if (c) + l = n; + else { + let P = n || {}; + l = P.index, r = P.injector, o = P.projectableNodes, i = P.environmentInjector || P.ngModuleRef, s = P.directives, a = P.bindings; + } + let u = c ? t : new dn(Ye(t)), d = r || this.parentInjector; + if (!i && u.ngModule == null) { + let lt = (c ? d : this.parentInjector).get(Q, null); + lt && (i = lt); + } + let f = Ye(u.componentType ?? {}), p = ss(this._lContainer, f?.id ?? null), h = p?.firstChild ?? null, k = u.create(d, o, h, i, s, a); + return this.insertImpl(k.hostView, l, an(this._hostTNode, p)), k; + } + insert(t, n) { + return this.insertImpl(t, n, true); + } + insertImpl(t, n, r) { + let o = t._lView; + if (gc(o)) { + let a = this.indexOf(t); + if (a !== -1) + this.detach(a); + else { + let c = o[R], l = new e4(c, c[J], c[R]); + l.detach(l.indexOf(t)); + } + } + let i = this._adjustIndex(n), s = this._lContainer; + return Zr(s, o, i, r), t.attachToViewContainerRef(), ci(Hi(s), i, t), t; + } + move(t, n) { + return this.insert(t, n); + } + indexOf(t) { + let n = El(this._lContainer); + return n !== null ? n.indexOf(t) : -1; + } + remove(t) { + let n = this._adjustIndex(t, -1), r = ln(this._lContainer, n); + r && (Qt(Hi(this._lContainer), n), Wr(r[m], r)); + } + detach(t) { + let n = this._adjustIndex(t, -1), r = ln(this._lContainer, n); + return r && Qt(Hi(this._lContainer), n) != null ? new Pt(r) : null; + } + _adjustIndex(t, n = 0) { + return t ?? this.length + n; + } +}; +function El(e12) { + return e12[Jt]; +} +function Hi(e12) { + return e12[Jt] || (e12[Jt] = []); +} +function Fu(e12, t) { + let n, r = t[e12.index]; + return re(r) ? n = r : (n = _u(r, t, null, e12), t[e12.index] = n, Hs(t, n)), rg(n, t, e12, r), new ds(n, e12, t); +} +function ng(e12, t) { + let n = e12[O], r = n.createComment(""), o = de(t, e12), i = n.parentNode(o); + return Nr(n, i, r, n.nextSibling(o), false), r; +} +var rg = sg; +var og = () => false; +function ig(e12, t, n) { + return og(e12, t, n); +} +function sg(e12, t, n, r) { + if (e12[Pe]) + return; + let o; + n.type & 8 ? o = ee(r) : o = ng(t, n), e12[Pe] = o; +} +var fs = class e5 { + queryList; + matches = null; + constructor(t) { + this.queryList = t; + } + clone() { + return new e5(this.queryList); + } + setDirty() { + this.queryList.setDirty(); + } +}; +var ps = class e6 { + queries; + constructor(t = []) { + this.queries = t; + } + createEmbeddedView(t) { + let n = t.queries; + if (n !== null) { + let r = t.contentQueries !== null ? t.contentQueries[0] : n.length, o = []; + for (let i = 0; i < r; i++) { + let s = n.getByIndex(i), a = this.queries[s.indexInDeclarationView]; + o.push(a.clone()); + } + return new e6(o); + } + return null; + } + insertView(t) { + this.dirtyQueriesWithMatches(t); + } + detachView(t) { + this.dirtyQueriesWithMatches(t); + } + finishViewCreation(t) { + this.dirtyQueriesWithMatches(t); + } + dirtyQueriesWithMatches(t) { + for (let n = 0; n < this.queries.length; n++) + Zs(t, n).matches !== null && this.queries[n].setDirty(); + } +}; +var hs = class { + flags; + read; + predicate; + constructor(t, n, r = null) { + this.flags = n, this.read = r, typeof t == "string" ? this.predicate = hg(t) : this.predicate = t; + } +}; +var gs = class e7 { + queries; + constructor(t = []) { + this.queries = t; + } + elementStart(t, n) { + for (let r = 0; r < this.queries.length; r++) + this.queries[r].elementStart(t, n); + } + elementEnd(t) { + for (let n = 0; n < this.queries.length; n++) + this.queries[n].elementEnd(t); + } + embeddedTView(t) { + let n = null; + for (let r = 0; r < this.length; r++) { + let o = n !== null ? n.length : 0, i = this.getByIndex(r).embeddedTView(t, o); + i && (i.indexInDeclarationView = r, n !== null ? n.push(i) : n = [i]); + } + return n !== null ? new e7(n) : null; + } + template(t, n) { + for (let r = 0; r < this.queries.length; r++) + this.queries[r].template(t, n); + } + getByIndex(t) { + return this.queries[t]; + } + get length() { + return this.queries.length; + } + track(t) { + this.queries.push(t); + } }; -var xt = class extends jn { +var ms = class e8 { + metadata; + matches = null; + indexInDeclarationView = -1; + crossesNgTemplate = false; + _declarationNodeIndex; + _appliesToNextNode = true; + constructor(t, n = -1) { + this.metadata = t, this._declarationNodeIndex = n; + } + elementStart(t, n) { + this.isApplyingToNode(n) && this.matchTNode(t, n); + } + elementEnd(t) { + this._declarationNodeIndex === t.index && (this._appliesToNextNode = false); + } + template(t, n) { + this.elementStart(t, n); + } + embeddedTView(t, n) { + return this.isApplyingToNode(t) ? (this.crossesNgTemplate = true, this.addMatch(-t.index, n), new e8(this.metadata)) : null; + } + isApplyingToNode(t) { + if (this._appliesToNextNode && (this.metadata.flags & 1) !== 1) { + let n = this._declarationNodeIndex, r = t.parent; + for (; r !== null && r.type & 8 && r.index !== n; ) + r = r.parent; + return n === (r !== null ? r.index : -1); + } + return this._appliesToNextNode; + } + matchTNode(t, n) { + let r = this.metadata.predicate; + if (Array.isArray(r)) + for (let o = 0; o < r.length; o++) { + let i = r[o]; + this.matchTNodeWithReadOption(t, n, ag(n, i)), this.matchTNodeWithReadOption(t, n, wr(n, t, i, false, false)); + } + else + r === un ? n.type & 4 && this.matchTNodeWithReadOption(t, n, -1) : this.matchTNodeWithReadOption(t, n, wr(n, t, r, false, false)); + } + matchTNodeWithReadOption(t, n, r) { + if (r !== null) { + let o = this.metadata.read; + if (o !== null) + if (o === hn || o === Jr || o === un && n.type & 4) + this.addMatch(n.index, -2); + else { + let i = wr(n, t, o, false, false); + i !== null && this.addMatch(n.index, i); + } + else + this.addMatch(n.index, r); + } + } + addMatch(t, n) { + this.matches === null ? this.matches = [t, n] : this.matches.push(t, n); + } +}; +function ag(e12, t) { + let n = e12.localNames; + if (n !== null) { + for (let r = 0; r < n.length; r += 2) + if (n[r] === t) + return n[r + 1]; + } + return null; +} +function cg(e12, t) { + return e12.type & 11 ? Ft(e12, t) : e12.type & 4 ? qs(e12, t) : null; +} +function lg(e12, t, n, r) { + return n === -1 ? cg(t, e12) : n === -2 ? ug(e12, t, r) : _r(e12, e12[m], n, t); +} +function ug(e12, t, n) { + if (n === hn) + return Ft(t, e12); + if (n === un) + return qs(t, e12); + if (n === Jr) + return Fu(t, e12); +} +function ju(e12, t, n, r) { + let o = t[ue].queries[r]; + if (o.matches === null) { + let i = e12.data, s = n.matches, a = []; + for (let c = 0; s !== null && c < s.length; c += 2) { + let l = s[c]; + if (l < 0) + a.push(null); + else { + let u = i[l]; + a.push(lg(t, u, s[c + 1], n.metadata.read)); + } + } + o.matches = a; + } + return o.matches; +} +function ys(e12, t, n, r) { + let o = e12.queries.getByIndex(n), i = o.matches; + if (i !== null) { + let s = ju(e12, t, o, n); + for (let a = 0; a < i.length; a += 2) { + let c = i[a]; + if (c > 0) + r.push(s[a / 2]); + else { + let l = i[a + 1], u = t[-c]; + for (let d = S; d < u.length; d++) { + let f = u[d]; + f[Oe] === f[R] && ys(f[m], f, l, r); + } + if (u[tt] !== null) { + let d = u[tt]; + for (let f = 0; f < d.length; f++) { + let p = d[f]; + ys(p[m], p, l, r); + } + } + } + } + } + return r; +} +function dg(e12, t) { + return e12[ue].queries[t].queryList; +} +function fg(e12, t, n) { + let r = new Sr((n & 4) === 4); + return vc(e12, t, r, r.destroy), (t[ue] ??= new ps()).queries.push(new fs(r)) - 1; +} +function pg(e12, t, n) { + let r = oe(); + return r.firstCreatePass && (gg(r, new hs(e12, t, n), -1), (t & 2) === 2 && (r.staticViewQueries = true)), fg(r, M(), t); +} +function hg(e12) { + return e12.split(",").map((t) => t.trim()); +} +function gg(e12, t, n) { + e12.queries === null && (e12.queries = new gs()), e12.queries.track(new ms(t, n)); +} +function Zs(e12, t) { + return e12.queries.getByIndex(t); +} +function mg(e12, t) { + let n = e12[m], r = Zs(n, t); + return r.crossesNgTemplate ? ys(n, e12, t, []) : ju(n, e12, r, t); +} +var Rr = class { +}; +var fn = class extends Rr { injector; - componentFactoryResolver = new Xo(this); + componentFactoryResolver = new us(this); instance = null; constructor(t) { super(); - let n = new Ce([...t.providers, { provide: jn, useValue: this }, { provide: Zn, useValue: this.componentFactoryResolver }], t.parent || pt(), t.debugName, /* @__PURE__ */ new Set(["environment"])); + let n = new qe([...t.providers, { provide: Rr, useValue: this }, { provide: Kr, useValue: this.componentFactoryResolver }], t.parent || Kt(), t.debugName, /* @__PURE__ */ new Set(["environment"])); this.injector = n, t.runEnvironmentInitializers && n.resolveInjectorInitializers(); } destroy() { @@ -3973,11 +4862,11 @@ var xt = class extends jn { this.injector.onDestroy(t); } }; -function Oc(e6, t, n = null) { - return new xt({ providers: e6, parent: t, debugName: n, runEnvironmentInitializers: true }).injector; +function Hu(e12, t, n = null) { + return new fn({ providers: e12, parent: t, debugName: n, runEnvironmentInitializers: true }).injector; } -var Vf = (() => { - class e6 { +var yg = (() => { + class e12 { _injector; cachedInjectors = /* @__PURE__ */ new Map(); constructor(n) { @@ -3987,7 +4876,7 @@ var Vf = (() => { if (!n.standalone) return null; if (!this.cachedInjectors.has(n)) { - let r = eo(false, n.type), o = r.length > 0 ? Oc([r], this._injector, "") : null; + let r = di(false, n.type), o = r.length > 0 ? Hu([r], this._injector, "") : null; this.cachedInjectors.set(n, o); } return this.cachedInjectors.get(n); @@ -4000,50 +4889,50 @@ var Vf = (() => { this.cachedInjectors.clear(); } } - static \u0275prov = S({ token: e6, providedIn: "environment", factory: () => new e6(I($)) }); + static \u0275prov = _({ token: e12, providedIn: "environment", factory: () => new e12(w(Q)) }); } - return e6; + return e12; })(); -function mi(e6) { - return Ma(() => { - let t = zf(e6), n = V(A({}, t), { decls: e6.decls, vars: e6.vars, template: e6.template, consts: e6.consts || null, ngContentSelectors: e6.ngContentSelectors, onPush: e6.changeDetection === ni.OnPush, directiveDefs: null, pipeDefs: null, dependencies: t.standalone && e6.dependencies || null, getStandaloneInjector: t.standalone ? (o) => o.get(Vf).getOrCreateStandaloneInjector(n) : null, getExternalStyles: null, signals: e6.signals ?? false, data: e6.data || {}, encapsulation: e6.encapsulation || z.Emulated, styles: e6.styles || we, _: null, schemas: e6.schemas || null, tView: null, id: "" }); - t.standalone && fc("NgStandalone"), Wf(n); - let r = e6.dependencies; - return n.directiveDefs = Ta(r, Bf), n.pipeDefs = Ta(r, hs), n.id = Gf(n), n; +function Qs(e12) { + return Tl(() => { + let t = Dg(e12), n = A(N({}, t), { decls: e12.decls, vars: e12.vars, template: e12.template, consts: e12.consts || null, ngContentSelectors: e12.ngContentSelectors, onPush: e12.changeDetection === Ss.OnPush, directiveDefs: null, pipeDefs: null, dependencies: t.standalone && e12.dependencies || null, getStandaloneInjector: t.standalone ? (o) => o.get(yg).getOrCreateStandaloneInjector(n) : null, getExternalStyles: null, signals: e12.signals ?? false, data: e12.data || {}, encapsulation: e12.encapsulation || ie.Emulated, styles: e12.styles || Ne, _: null, schemas: e12.schemas || null, tView: null, id: "" }); + t.standalone && ct("NgStandalone"), wg(n); + let r = e12.dependencies; + return n.directiveDefs = Il(r, vg), n.pipeDefs = Il(r, Ka), n.id = Cg(n), n; }); } -function Bf(e6) { - return ut(e6) || Gr(e6); +function vg(e12) { + return Ye(e12) || ri(e12); } -function $f(e6, t) { - if (e6 == null) - return Se; +function Eg(e12, t) { + if (e12 == null) + return Ke; let n = {}; - for (let r in e6) - if (e6.hasOwnProperty(r)) { - let o = e6[r], i, s, a, c; - Array.isArray(o) ? (a = o[0], i = o[1], s = o[2] ?? i, c = o[3] || null) : (i = o, s = o, a = Gn.None, c = null), n[i] = [r, a, c], t[i] = s; + for (let r in e12) + if (e12.hasOwnProperty(r)) { + let o = e12[r], i, s, a, c; + Array.isArray(o) ? (a = o[0], i = o[1], s = o[2] ?? i, c = o[3] || null) : (i = o, s = o, a = zr.None, c = null), n[i] = [r, a, c], t[i] = s; } return n; } -function Uf(e6) { - if (e6 == null) - return Se; +function Ig(e12) { + if (e12 == null) + return Ke; let t = {}; - for (let n in e6) - e6.hasOwnProperty(n) && (t[e6[n]] = n); + for (let n in e12) + e12.hasOwnProperty(n) && (t[e12[n]] = n); return t; } -function zf(e6) { +function Dg(e12) { let t = {}; - return { type: e6.type, providersResolver: null, viewProvidersResolver: null, factory: null, hostBindings: e6.hostBindings || null, hostVars: e6.hostVars || 0, hostAttrs: e6.hostAttrs || null, contentQueries: e6.contentQueries || null, declaredInputs: t, inputConfig: e6.inputs || Se, exportAs: e6.exportAs || null, standalone: e6.standalone ?? true, signals: e6.signals === true, selectors: e6.selectors || we, viewQuery: e6.viewQuery || null, features: e6.features || null, setInput: null, resolveHostDirectives: null, hostDirectives: null, controlDef: null, inputs: $f(e6.inputs, t), outputs: Uf(e6.outputs), debugInfo: null }; + return { type: e12.type, providersResolver: null, viewProvidersResolver: null, factory: null, hostBindings: e12.hostBindings || null, hostVars: e12.hostVars || 0, hostAttrs: e12.hostAttrs || null, contentQueries: e12.contentQueries || null, declaredInputs: t, inputConfig: e12.inputs || Ke, exportAs: e12.exportAs || null, standalone: e12.standalone ?? true, signals: e12.signals === true, selectors: e12.selectors || Ne, viewQuery: e12.viewQuery || null, features: e12.features || null, setInput: null, resolveHostDirectives: null, hostDirectives: null, controlDef: null, inputs: Eg(e12.inputs, t), outputs: Ig(e12.outputs), debugInfo: null }; } -function Wf(e6) { - e6.features?.forEach((t) => t(e6)); +function wg(e12) { + e12.features?.forEach((t) => t(e12)); } -function Ta(e6, t) { - return e6 ? () => { - let n = typeof e6 == "function" ? e6() : e6, r = []; +function Il(e12, t) { + return e12 ? () => { + let n = typeof e12 == "function" ? e12() : e12, r = []; for (let o of n) { let i = t(o); i !== null && r.push(i); @@ -4051,22 +4940,51 @@ function Ta(e6, t) { return r; } : null; } -function Gf(e6) { - let t = 0, n = typeof e6.consts == "function" ? "" : e6.consts, r = [e6.selectors, e6.ngContentSelectors, e6.hostVars, e6.hostAttrs, n, e6.vars, e6.decls, e6.encapsulation, e6.standalone, e6.signals, e6.exportAs, JSON.stringify(e6.inputs), JSON.stringify(e6.outputs), Object.getOwnPropertyNames(e6.type.prototype), !!e6.contentQueries, !!e6.viewQuery]; +function Cg(e12) { + let t = 0, n = typeof e12.consts == "function" ? "" : e12.consts, r = [e12.selectors, e12.ngContentSelectors, e12.hostVars, e12.hostAttrs, n, e12.vars, e12.decls, e12.encapsulation, e12.standalone, e12.signals, e12.exportAs, JSON.stringify(e12.inputs), JSON.stringify(e12.outputs), Object.getOwnPropertyNames(e12.type.prototype), !!e12.contentQueries, !!e12.viewQuery]; for (let i of r.join("|")) t = Math.imul(31, t) + i.charCodeAt(0) << 0; return t += 2147483648, "c" + t; } -var yi = new m(""); -function vi(e6) { - return !!e6 && typeof e6.then == "function"; +function bg(e12, t, n, r, o, i, s, a) { + if (n.firstCreatePass) { + e12.mergedAttrs = Fr(e12.mergedAttrs, e12.attrs); + let u = e12.tView = Fs(2, e12, o, i, s, n.directiveRegistry, n.pipeRegistry, null, n.schemas, n.consts, null); + n.queries !== null && (n.queries.template(n, e12), u.queries = n.queries.embeddedTView(e12)); + } + a && (e12.flags |= a), Nt(e12, false); + let c = Tg(n, t, e12, r); + fr() && Us(n, t, c, e12), kt(c, t); + let l = _u(c, t, c, e12); + t[r + F] = l, Hs(t, l), ig(l, e12, t); +} +function Or(e12, t, n, r, o, i, s, a, c, l, u) { + let d = n + F, f; + if (t.firstCreatePass) { + if (f = Qr(t, d, 4, s || null, a || null), l != null) { + let p = fe(t.consts, l); + f.localNames = []; + for (let h = 0; h < p.length; h += 2) + f.localNames.push(p[h], -1); + } + } else + f = t.data[d]; + return bg(f, e12, t, n, r, o, i, c), l != null && yu(e12, f, u), f; +} +var Tg = Mg; +function Mg(e12, t, n, r) { + return pr(true), t[O].createComment(""); } -function Lc(e6) { - return !!e6 && typeof e6.subscribe == "function"; +var Ys = new D(""); +function Ks(e12) { + return !!e12 && typeof e12.then == "function"; } -var Pc = new m(""); -var Ei = (() => { - class e6 { +function Vu(e12) { + return !!e12 && typeof e12.subscribe == "function"; +} +var Bu = new D(""); +var Js = (() => { + class e12 { resolve; reject; initialized = false; @@ -4074,8 +4992,8 @@ var Ei = (() => { donePromise = new Promise((n, r) => { this.resolve = n, this.reject = r; }); - appInits = E(Pc, { optional: true }) ?? []; - injector = E(ee); + appInits = E(Bu, { optional: true }) ?? []; + injector = E(ce); constructor() { } runInitializers() { @@ -4083,10 +5001,10 @@ var Ei = (() => { return; let n = []; for (let o of this.appInits) { - let i = pn(this.injector, o); - if (vi(i)) + let i = nr(this.injector, o); + if (Ks(i)) n.push(i); - else if (Lc(i)) { + else if (Vu(i)) { let s = new Promise((a, c) => { i.subscribe({ complete: a, error: c }); }); @@ -4103,39 +5021,39 @@ var Ei = (() => { }), n.length === 0 && r(), this.initialized = true; } static \u0275fac = function(r) { - return new (r || e6)(); + return new (r || e12)(); }; - static \u0275prov = S({ token: e6, factory: e6.\u0275fac, providedIn: "root" }); + static \u0275prov = _({ token: e12, factory: e12.\u0275fac, providedIn: "root" }); } - return e6; + return e12; })(); -var Fc = new m(""); -function jc() { - hr(() => { - let e6 = ""; - throw new g(600, e6); +var $u = new D(""); +function Uu() { + To(() => { + let e12 = ""; + throw new v(600, e12); }); } -function Hc(e6) { - return e6.isBoundToModule; +function zu(e12) { + return e12.isBoundToModule; } -var qf = 10; -var Ot = (() => { - class e6 { +var _g = 10; +var vn = (() => { + class e12 { _runningTick = false; _destroyed = false; _destroyListeners = []; _views = []; - internalErrorHandler = E(Ke); - afterRenderManager = E(pc); - zonelessEnabled = E(Tt); - rootEffectScheduler = E(So); + internalErrorHandler = E(rt); + afterRenderManager = E(du); + zonelessEnabled = E(tn); + rootEffectScheduler = E(gr); dirtyFlags = 0; tracingSnapshot = null; allTestViews = /* @__PURE__ */ new Set(); autoDetectTestViews = /* @__PURE__ */ new Set(); includeAllTestViews = false; - afterTick = new ae(); + afterTick = new ye(); get allViews() { return [...(this.includeAllTestViews ? this.allTestViews : this.autoDetectTestViews).keys(), ...this._views]; } @@ -4144,12 +5062,12 @@ var Ot = (() => { } componentTypes = []; components = []; - internalPendingTask = E(Ye); + internalPendingTask = E(At); get isStable() { - return this.internalPendingTask.hasPendingTasksObservable.pipe(Tr((n) => !n)); + return this.internalPendingTask.hasPendingTasksObservable.pipe(Fo((n) => !n)); } constructor() { - E(nt, { optional: true }); + E(jt, { optional: true }); } whenStable() { let n; @@ -4161,7 +5079,7 @@ var Ot = (() => { n.unsubscribe(); }); } - _injector = E($); + _injector = E(Q); _rendererFactory = null; get injector() { return this._injector; @@ -4169,47 +5087,47 @@ var Ot = (() => { bootstrap(n, r) { return this.bootstrapImpl(n, r); } - bootstrapImpl(n, r, o = ee.NULL) { - return this._injector.get(j).run(() => { - M(w.BootstrapComponentStart); - let s = n instanceof qn; - if (!this._injector.get(Ei).done) { - let T = ""; - throw new g(405, T); + bootstrapImpl(n, r, o = ce.NULL) { + return this._injector.get(Y).run(() => { + T(C.BootstrapComponentStart); + let s = n instanceof Yr; + if (!this._injector.get(Js).done) { + let h = ""; + throw new v(405, h); } let c; - s ? c = n : c = this._injector.get(Zn).resolveComponentFactory(n), this.componentTypes.push(c.componentType); - let l = Hc(c) ? void 0 : this._injector.get(jn), u = r || c.selector, d = c.create(o, [], u, l), p = d.location.nativeElement, f = d.injector.get(yi, null); - return f?.registerApplication(p), d.onDestroy(() => { - this.detachView(d.hostView), St(this.components, d), f?.unregisterApplication(p); - }), this._loadComponent(d), M(w.BootstrapComponentEnd, d), d; + s ? c = n : c = this._injector.get(Kr).resolveComponentFactory(n), this.componentTypes.push(c.componentType); + let l = zu(c) ? void 0 : this._injector.get(Rr), u = r || c.selector, d = c.create(o, [], u, l), f = d.location.nativeElement, p = d.injector.get(Ys, null); + return p?.registerApplication(f), d.onDestroy(() => { + this.detachView(d.hostView), on(this.components, d), p?.unregisterApplication(f); + }), this._loadComponent(d), T(C.BootstrapComponentEnd, d), d; }); } tick() { this.zonelessEnabled || (this.dirtyFlags |= 1), this._tick(); } _tick() { - M(w.ChangeDetectionStart), this.tracingSnapshot !== null ? this.tracingSnapshot.run(di.CHANGE_DETECTION, this.tickImpl) : this.tickImpl(); + T(C.ChangeDetectionStart), this.tracingSnapshot !== null ? this.tracingSnapshot.run(Bs.CHANGE_DETECTION, this.tickImpl) : this.tickImpl(); } tickImpl = () => { if (this._runningTick) - throw M(w.ChangeDetectionEnd), new g(101, false); - let n = v(null); + throw T(C.ChangeDetectionEnd), new v(101, false); + let n = g(null); try { this._runningTick = true, this.synchronize(); } finally { - this._runningTick = false, this.tracingSnapshot?.dispose(), this.tracingSnapshot = null, v(n), this.afterTick.next(), M(w.ChangeDetectionEnd); + this._runningTick = false, this.tracingSnapshot?.dispose(), this.tracingSnapshot = null, g(n), this.afterTick.next(), T(C.ChangeDetectionEnd); } }; synchronize() { - this._rendererFactory === null && !this._injector.destroyed && (this._rendererFactory = this._injector.get(Re, null, { optional: true })); + this._rendererFactory === null && !this._injector.destroyed && (this._rendererFactory = this._injector.get(st, null, { optional: true })); let n = 0; - for (; this.dirtyFlags !== 0 && n++ < qf; ) { - M(w.ChangeDetectionSyncStart); + for (; this.dirtyFlags !== 0 && n++ < _g; ) { + T(C.ChangeDetectionSyncStart); try { this.synchronizeOnce(); } finally { - M(w.ChangeDetectionSyncEnd); + T(C.ChangeDetectionSyncEnd); } } } @@ -4220,10 +5138,10 @@ var Ot = (() => { let r = !!(this.dirtyFlags & 1); this.dirtyFlags &= -8, this.dirtyFlags |= 8; for (let { _lView: o } of this.allViews) { - if (!r && !Et(o)) + if (!r && !Xt(o)) continue; let i = r && !this.zonelessEnabled ? 0 : 1; - Tc(o, i), n = true; + Cu(o, i), n = true; } if (this.dirtyFlags &= -5, this.syncDirtyFlagsWithViews(), this.dirtyFlags & 23) return; @@ -4231,7 +5149,7 @@ var Ot = (() => { n || (this._rendererFactory?.begin?.(), this._rendererFactory?.end?.()), this.dirtyFlags & 8 && (this.dirtyFlags &= -9, this.afterRenderManager.execute()), this.syncDirtyFlagsWithViews(); } syncDirtyFlagsWithViews() { - if (this.allViews.some(({ _lView: n }) => Et(n))) { + if (this.allViews.some(({ _lView: n }) => Xt(n))) { this.dirtyFlags |= 2; return; } else @@ -4243,7 +5161,7 @@ var Ot = (() => { } detachView(n) { let r = n; - St(this._views, r), r.detachFromAppRef(); + on(this._views, r), r.detachFromAppRef(); } _loadComponent(n) { this.attachView(n.hostView); @@ -4252,7 +5170,7 @@ var Ot = (() => { } catch (o) { this.internalErrorHandler(o); } - this.components.push(n), this._injector.get(Fc, []).forEach((o) => o(n)); + this.components.push(n), this._injector.get($u, []).forEach((o) => o(n)); } ngOnDestroy() { if (!this._destroyed) @@ -4263,11 +5181,11 @@ var Ot = (() => { } } onDestroy(n) { - return this._destroyListeners.push(n), () => St(this._destroyListeners, n); + return this._destroyListeners.push(n), () => on(this._destroyListeners, n); } destroy() { if (this._destroyed) - throw new g(406, false); + throw new v(406, false); let n = this._injector; n.destroy && !n.destroyed && n.destroy(); } @@ -4275,70 +5193,549 @@ var Ot = (() => { return this._views.length; } static \u0275fac = function(r) { - return new (r || e6)(); + return new (r || e12)(); }; - static \u0275prov = S({ token: e6, factory: e6.\u0275fac, providedIn: "root" }); + static \u0275prov = _({ token: e12, factory: e12.\u0275fac, providedIn: "root" }); } - return e6; + return e12; })(); -function St(e6, t) { - let n = e6.indexOf(t); - n > -1 && e6.splice(n, 1); -} -function Oe(e6, t, n, r) { - let o = H(), i = o[y], s = e6 + U, a = i.firstCreatePass ? xf(s, i, 2, t, n, r) : i.data[s]; - return Zd(a, o, e6, t, Zf), r != null && Hd(o, a), Oe; -} -function ye() { - let e6 = Qe(), t = Qd(e6); - return Ls(t) && Ps(), ks(), ye; -} -function Qn(e6, t, n, r) { - return Oe(e6, t, n, r), ye(), Qn; -} -var Zf = (e6, t, n, r, o) => (Io(true), rc(t[P], r, qs())); -function Yn(e6, t, n) { - let r = H(), o = go(); - if (Rc(r, o, t)) { - let i = Dn(), s = Gs(); - Ud(s, r, e6, t, r[P], n); - } - return Yn; -} -var Lt = "en-US"; -var Qf = Lt; -function Vc(e6) { - typeof e6 == "string" && (Qf = e6.toLowerCase().replace(/_/g, "-")); -} -function Pt(e6, t = "") { - let n = H(), r = Dn(), o = e6 + U, i = r.firstCreatePass ? gi(r, o, 1, t, null) : r.data[o], s = Yf(r, n, i, t); - n[o] = s, Eo() && mc(r, n, s, i), Dt(i, false); -} -var Yf = (e6, t, n, r) => (Io(true), od(t[P], r)); -function Kf(e6, t, n, r = "") { - return Rc(e6, go(), n) ? t + Zr(n) + r : tt; -} -function Kn(e6, t, n) { - let r = H(), o = Kf(r, e6, t, n); - return o !== tt && Jf(r, Mn(), o), Kn; -} -function Jf(e6, t, n) { - let r = Ns(t, e6); - id(e6[P], r, n); -} -var Bc = (() => { - class e6 { - applicationErrorHandler = E(Ke); - appRef = E(Ot); - taskService = E(Ye); - ngZone = E(j); - zonelessEnabled = E(Tt); - tracing = E(nt, { optional: true }); +function on(e12, t) { + let n = e12.indexOf(t); + n > -1 && e12.splice(n, 1); +} +var vs = class { + destroy(t) { + } + updateValue(t, n) { + } + swap(t, n) { + let r = Math.min(t, n), o = Math.max(t, n), i = this.detach(o); + if (o - r > 1) { + let s = this.detach(r); + this.attach(r, i), this.attach(o, s); + } else + this.attach(r, i); + } + move(t, n) { + this.attach(n, this.detach(t)); + } +}; +function Vi(e12, t, n, r, o) { + return e12 === n && Object.is(t, r) ? 1 : Object.is(o(e12, t), o(n, r)) ? -1 : 0; +} +function Sg(e12, t, n, r) { + let o, i, s = 0, a = e12.length - 1, c = void 0; + if (Array.isArray(t)) { + g(r); + let l = t.length - 1; + for (g(null); s <= a && s <= l; ) { + let u = e12.at(s), d = t[s], f = Vi(s, u, s, d, n); + if (f !== 0) { + f < 0 && e12.updateValue(s, d), s++; + continue; + } + let p = e12.at(a), h = t[l], k = Vi(a, p, l, h, n); + if (k !== 0) { + k < 0 && e12.updateValue(a, h), a--, l--; + continue; + } + let P = n(s, u), lt = n(a, p), Vt = n(s, d); + if (Object.is(Vt, lt)) { + let po = n(l, h); + Object.is(po, P) ? (e12.swap(s, a), e12.updateValue(a, h), l--, a--) : e12.move(a, s), e12.updateValue(s, d), s++; + continue; + } + if (o ??= new kr(), i ??= wl(e12, s, a, n), Es(e12, o, s, Vt)) + e12.updateValue(s, d), s++, a++; + else if (i.has(Vt)) + o.set(P, e12.detach(s)), a--; + else { + let po = e12.create(s, t[s]); + e12.attach(s, po), s++, a++; + } + } + for (; s <= l; ) + Dl(e12, o, n, s, t[s]), s++; + } else if (t != null) { + g(r); + let l = t[Symbol.iterator](); + g(null); + let u = l.next(); + for (; !u.done && s <= a; ) { + let d = e12.at(s), f = u.value, p = Vi(s, d, s, f, n); + if (p !== 0) + p < 0 && e12.updateValue(s, f), s++, u = l.next(); + else { + o ??= new kr(), i ??= wl(e12, s, a, n); + let h = n(s, f); + if (Es(e12, o, s, h)) + e12.updateValue(s, f), s++, a++, u = l.next(); + else if (!i.has(h)) + e12.attach(s, e12.create(s, f)), s++, a++, u = l.next(); + else { + let k = n(s, d); + o.set(k, e12.detach(s)), a--; + } + } + } + for (; !u.done; ) + Dl(e12, o, n, e12.length, u.value), u = l.next(); + } + for (; s <= a; ) + e12.destroy(e12.detach(a--)); + o?.forEach((l) => { + e12.destroy(l); + }); +} +function Es(e12, t, n, r) { + return t !== void 0 && t.has(r) ? (e12.attach(n, t.get(r)), t.delete(r), true) : false; +} +function Dl(e12, t, n, r, o) { + if (Es(e12, t, r, n(r, o))) + e12.updateValue(r, o); + else { + let i = e12.create(r, o); + e12.attach(r, i); + } +} +function wl(e12, t, n, r) { + let o = /* @__PURE__ */ new Set(); + for (let i = t; i <= n; i++) + o.add(r(i, e12.at(i))); + return o; +} +var kr = class { + kvMap = /* @__PURE__ */ new Map(); + _vMap = void 0; + has(t) { + return this.kvMap.has(t); + } + delete(t) { + if (!this.has(t)) + return false; + let n = this.kvMap.get(t); + return this._vMap !== void 0 && this._vMap.has(n) ? (this.kvMap.set(t, this._vMap.get(n)), this._vMap.delete(n)) : this.kvMap.delete(t), true; + } + get(t) { + return this.kvMap.get(t); + } + set(t, n) { + if (this.kvMap.has(t)) { + let r = this.kvMap.get(t); + this._vMap === void 0 && (this._vMap = /* @__PURE__ */ new Map()); + let o = this._vMap; + for (; o.has(r); ) + r = o.get(r); + o.set(r, n); + } else + this.kvMap.set(t, n); + } + forEach(t) { + for (let [n, r] of this.kvMap) + if (t(r, n), this._vMap !== void 0) { + let o = this._vMap; + for (; o.has(r); ) + r = o.get(r), t(r, n); + } + } +}; +function Xs(e12, t, n, r, o, i, s, a) { + ct("NgControlFlow"); + let c = M(), l = oe(), u = fe(l.consts, i); + return Or(c, l, e12, t, n, r, o, u, 256, s, a), ea; +} +function ea(e12, t, n, r, o, i, s, a) { + ct("NgControlFlow"); + let c = M(), l = oe(), u = fe(l.consts, i); + return Or(c, l, e12, t, n, r, o, u, 512, s, a), ea; +} +function ta(e12, t) { + ct("NgControlFlow"); + let n = M(), r = en(), o = n[r] !== Se ? n[r] : -1, i = o !== -1 ? Pr(n, F + o) : void 0, s = 0; + if (yn(n, r, e12)) { + let a = g(null); + try { + if (i !== void 0 && Nu(i, s), e12 !== -1) { + let c = F + e12, l = Pr(n, c), u = Cs(n[m], c), d = Au(l, u, n), f = qr(n, u, t, { dehydratedView: d }); + Zr(l, f, s, an(u, d)); + } + } finally { + g(a); + } + } else if (i !== void 0) { + let a = Su(i, s); + a !== void 0 && (a[x] = t); + } +} +var Is = class { + lContainer; + $implicit; + $index; + constructor(t, n, r) { + this.lContainer = t, this.$implicit = n, this.$index = r; + } + get $count() { + return this.lContainer.length - S; + } +}; +function Xr(e12, t) { + return t; +} +var Ds = class { + hasEmptyBlock; + trackByFn; + liveCollection; + constructor(t, n, r) { + this.hasEmptyBlock = t, this.trackByFn = n, this.liveCollection = r; + } +}; +function eo(e12, t, n, r, o, i, s, a, c, l, u, d, f) { + ct("NgControlFlow"); + let p = M(), h = oe(), k = c !== void 0, P = M(), lt = a ? s.bind(P[X][x]) : s, Vt = new Ds(k, lt); + P[F + e12] = Vt, Or(p, h, e12 + 1, t, n, r, o, fe(h.consts, i), 256), k && Or(p, h, e12 + 2, c, l, u, d, fe(h.consts, f), 512); +} +var ws = class extends vs { + lContainer; + hostLView; + templateTNode; + operationsCounter = void 0; + needsIndexUpdate = false; + constructor(t, n, r) { + super(), this.lContainer = t, this.hostLView = n, this.templateTNode = r; + } + get length() { + return this.lContainer.length - S; + } + at(t) { + return this.getLView(t)[x].$implicit; + } + attach(t, n) { + let r = n[wt]; + this.needsIndexUpdate ||= t !== this.length, Zr(this.lContainer, n, t, an(this.templateTNode, r)), Ng(this.lContainer, t); + } + detach(t) { + return this.needsIndexUpdate ||= t !== this.length - 1, xg(this.lContainer, t), Ag(this.lContainer, t); + } + create(t, n) { + let r = ss(this.lContainer, this.templateTNode.tView.ssrId); + return qr(this.hostLView, this.templateTNode, new Is(this.lContainer, n, t), { dehydratedView: r }); + } + destroy(t) { + Wr(t[m], t); + } + updateValue(t, n) { + this.getLView(t)[x].$implicit = n; + } + reset() { + this.needsIndexUpdate = false; + } + updateIndexes() { + if (this.needsIndexUpdate) + for (let t = 0; t < this.length; t++) + this.getLView(t)[x].$index = t; + } + getLView(t) { + return Rg(this.lContainer, t); + } +}; +function to(e12) { + let t = g(null), n = Fe(); + try { + let r = M(), o = r[m], i = r[n], s = n + 1, a = Pr(r, s); + if (i.liveCollection === void 0) { + let l = Cs(o, s); + i.liveCollection = new ws(a, r, l); + } else + i.liveCollection.reset(); + let c = i.liveCollection; + if (Sg(c, e12, i.trackByFn, t), c.updateIndexes(), i.hasEmptyBlock) { + let l = en(), u = c.length === 0; + if (yn(r, l, u)) { + let d = n + 2, f = Pr(r, d); + if (u) { + let p = Cs(o, d), h = Au(f, p, r), k = qr(r, p, void 0, { dehydratedView: h }); + Zr(f, k, 0, an(p, h)); + } else + o.firstUpdatePass && bh(f), Nu(f, 0); + } + } + } finally { + g(t); + } +} +function Pr(e12, t) { + return e12[t]; +} +function Ng(e12, t) { + if (e12.length <= S) + return; + let n = S + t, r = e12[n], o = r ? r[ke] : void 0; + if (r && o && o.detachedLeaveAnimationFns && o.detachedLeaveAnimationFns.length > 0) { + let i = r[De]; + Np(i, o), it.delete(r[we]), o.detachedLeaveAnimationFns = void 0; + } +} +function xg(e12, t) { + if (e12.length <= S) + return; + let n = S + t, r = e12[n], o = r ? r[ke] : void 0; + o && o.leave && o.leave.size > 0 && (o.detachedLeaveAnimationFns = []); +} +function Ag(e12, t) { + return ln(e12, t); +} +function Rg(e12, t) { + return Su(e12, t); +} +function Cs(e12, t) { + return ir(e12, t); +} +function j(e12, t, n, r) { + let o = M(), i = o[m], s = e12 + F, a = i.firstCreatePass ? Vh(s, i, 2, t, n, r) : i.data[s]; + return eh(a, o, e12, t, Og), r != null && yu(o, a), j; +} +function B() { + let e12 = pe(), t = th(e12); + return Cc(t) && bc(), Dc(), B; +} +var Og = (e12, t, n, r, o) => (pr(true), ou(t[O], r, jc())); +function me(e12, t, n) { + let r = M(), o = en(); + if (yn(r, o, t)) { + let i = oe(), s = Fc(); + Qp(s, r, e12, t, r[O], n); + } + return me; +} +var En = "en-US"; +var kg = En; +function Wu(e12) { + typeof e12 == "string" && (kg = e12.toLowerCase().replace(/_/g, "-")); +} +function Ve(e12, t, n) { + let r = M(), o = oe(), i = pe(); + return (i.type & 3 || n) && $h(i, o, r, n, r[O], e12, t, Bh(i, r, t)), Ve; +} +function na(e12 = 1) { + return Lc(e12); +} +function no(e12, t, n) { + return pg(e12, t, n), no; +} +function ra(e12) { + let t = M(), n = oe(), r = _i(); + lr(r + 1); + let o = Zs(n, r); + if (e12.dirty && hc(t) === ((o.metadata.flags & 2) === 2)) { + if (o.matches === null) + e12.reset([]); + else { + let i = mg(t, r); + e12.reset(i, jf), e12.notifyOnChanges(); + } + return true; + } + return false; +} +function oa() { + return dg(M(), _i()); +} +function Er(e12, t) { + return e12 << 17 | t << 2; +} +function at(e12) { + return e12 >> 17 & 32767; +} +function Pg(e12) { + return (e12 & 2) == 2; +} +function Lg(e12, t) { + return e12 & 131071 | t << 17; +} +function bs(e12) { + return e12 | 2; +} +function Lt(e12) { + return (e12 & 131068) >> 2; +} +function Bi(e12, t) { + return e12 & -131069 | t << 2; +} +function Fg(e12) { + return (e12 & 1) === 1; +} +function Ts(e12) { + return e12 | 1; +} +function jg(e12, t, n, r, o, i) { + let s = i ? t.classBindings : t.styleBindings, a = at(s), c = Lt(s); + e12[r] = n; + let l = false, u; + if (Array.isArray(n)) { + let d = n; + u = d[1], (u === null || It(d, u) > 0) && (l = true); + } else + u = n; + if (o) + if (c !== 0) { + let f = at(e12[a + 1]); + e12[r + 1] = Er(f, a), f !== 0 && (e12[f + 1] = Bi(e12[f + 1], r)), e12[a + 1] = Lg(e12[a + 1], r); + } else + e12[r + 1] = Er(a, 0), a !== 0 && (e12[a + 1] = Bi(e12[a + 1], r)), a = r; + else + e12[r + 1] = Er(c, 0), a === 0 ? a = r : e12[c + 1] = Bi(e12[c + 1], r), c = r; + l && (e12[r + 1] = bs(e12[r + 1])), Cl(e12, u, r, true), Cl(e12, u, r, false), Hg(t, u, e12, r, i), s = Er(a, c), i ? t.classBindings = s : t.styleBindings = s; +} +function Hg(e12, t, n, r, o) { + let i = o ? e12.residualClasses : e12.residualStyles; + i != null && typeof t == "string" && It(i, t) >= 0 && (n[r + 1] = Ts(n[r + 1])); +} +function Cl(e12, t, n, r) { + let o = e12[n + 1], i = t === null, s = r ? at(o) : Lt(o), a = false; + for (; s !== 0 && (a === false || i); ) { + let c = e12[s], l = e12[s + 1]; + Vg(c, t) && (a = true, e12[s + 1] = r ? Ts(l) : bs(l)), s = r ? at(l) : Lt(l); + } + a && (e12[n + 1] = r ? bs(o) : Ts(o)); +} +function Vg(e12, t) { + return e12 === null || t == null || (Array.isArray(e12) ? e12[1] : e12) === t ? true : Array.isArray(e12) && typeof t == "string" ? It(e12, t) >= 0 : false; +} +function ro(e12, t) { + return Bg(e12, t, null, true), ro; +} +function Bg(e12, t, n, r) { + let o = M(), i = oe(), s = Sc(2); + if (i.firstUpdatePass && Ug(i, e12, s, r), t !== Se && yn(o, s, t)) { + let a = i.data[Fe()]; + Zg(i, a, o, o[O], e12, o[s + 1] = Qg(t, n), r, s); + } +} +function $g(e12, t) { + return t >= e12.expandoStartIndex; +} +function Ug(e12, t, n, r) { + let o = e12.data; + if (o[n + 1] === null) { + let i = o[Fe()], s = $g(e12, n); + Yg(i, r) && t === null && !s && (t = false), t = zg(o, i, t, r), jg(o, i, t, n, s, r); + } +} +function zg(e12, t, n, r) { + let o = Rc(e12), i = r ? t.residualClasses : t.residualStyles; + if (o === null) + (r ? t.classBindings : t.styleBindings) === 0 && (n = $i(null, e12, t, n, r), n = pn(n, t.attrs, r), i = null); + else { + let s = t.directiveStylingLast; + if (s === -1 || e12[s] !== o) + if (n = $i(o, e12, t, n, r), i === null) { + let c = Wg(e12, t, r); + c !== void 0 && Array.isArray(c) && (c = $i(null, e12, t, c[1], r), c = pn(c, t.attrs, r), Gg(e12, t, r, c)); + } else + i = qg(e12, t, r); + } + return i !== void 0 && (r ? t.residualClasses = i : t.residualStyles = i), n; +} +function Wg(e12, t, n) { + let r = n ? t.classBindings : t.styleBindings; + if (Lt(r) !== 0) + return e12[at(r)]; +} +function Gg(e12, t, n, r) { + let o = n ? t.classBindings : t.styleBindings; + e12[at(o)] = r; +} +function qg(e12, t, n) { + let r, o = t.directiveEnd; + for (let i = 1 + t.directiveStylingLast; i < o; i++) { + let s = e12[i].hostAttrs; + r = pn(r, s, n); + } + return pn(r, t.attrs, n); +} +function $i(e12, t, n, r, o) { + let i = null, s = n.directiveEnd, a = n.directiveStylingLast; + for (a === -1 ? a = n.directiveStart : a++; a < s && (i = t[a], r = pn(r, i.hostAttrs, o), i !== e12); ) + a++; + return e12 !== null && (n.directiveStylingLast = a), r; +} +function pn(e12, t, n) { + let r = n ? 1 : 2, o = -1; + if (t !== null) + for (let i = 0; i < t.length; i++) { + let s = t[i]; + typeof s == "number" ? o = s : o === r && (Array.isArray(e12) || (e12 = e12 === void 0 ? [] : ["", e12]), oc(e12, s, n ? true : t[++i])); + } + return e12 === void 0 ? null : e12; +} +function Zg(e12, t, n, r, o, i, s, a) { + if (!(t.type & 3)) + return; + let c = e12.data, l = c[a + 1], u = Fg(l) ? bl(c, t, n, o, Lt(l), s) : void 0; + if (!Lr(u)) { + Lr(i) || Pg(l) && (i = bl(c, null, n, o, a, s)); + let d = vi(Fe(), n); + zp(r, s, d, o, i); + } +} +function bl(e12, t, n, r, o, i) { + let s = t === null, a; + for (; o > 0; ) { + let c = e12[o], l = Array.isArray(c), u = l ? c[1] : c, d = u === null, f = n[o + 1]; + f === Se && (f = d ? Ne : void 0); + let p = d ? tr(f, r) : u === r ? f : void 0; + if (l && !Lr(p) && (p = tr(c, r)), Lr(p) && (a = p, s)) + return a; + let h = e12[o + 1]; + o = s ? at(h) : Lt(h); + } + if (t !== null) { + let c = i ? t.residualClasses : t.residualStyles; + c != null && (a = tr(c, r)); + } + return a; +} +function Lr(e12) { + return e12 !== void 0; +} +function Qg(e12, t) { + return e12 == null || e12 === "" || (typeof t == "string" ? e12 = e12 + t : typeof e12 == "object" && (e12 = Qn(Me(e12)))), e12; +} +function Yg(e12, t) { + return (e12.flags & (t ? 8 : 16)) !== 0; +} +function se(e12, t = "") { + let n = M(), r = oe(), o = e12 + F, i = r.firstCreatePass ? Qr(r, o, 1, t, null) : r.data[o], s = Kg(r, n, i, t); + n[o] = s, fr() && Us(r, n, s, i), Nt(i, false); +} +var Kg = (e12, t, n, r) => (pr(true), pp(t[O], r)); +function Jg(e12, t, n, r = "") { + return yn(e12, en(), n) ? t + ii(n) + r : Se; +} +function Be(e12) { + return ia("", e12), Be; +} +function ia(e12, t, n) { + let r = M(), o = Jg(r, e12, t, n); + return o !== Se && Xg(r, Fe(), o), ia; +} +function Xg(e12, t, n) { + let r = vi(t, e12); + hp(e12[O], r, n); +} +var Gu = (() => { + class e12 { + applicationErrorHandler = E(rt); + appRef = E(vn); + taskService = E(At); + ngZone = E(Y); + zonelessEnabled = E(tn); + tracing = E(jt, { optional: true }); zoneIsDefined = typeof Zone < "u" && !!Zone.root.run; schedulerTickApplyArgs = [{ data: { __scheduler_tick__: true } }]; - subscriptions = new _(); - angularZoneId = this.zoneIsDefined ? this.ngZone._inner?.get(ct) : null; - scheduleInRootZone = !this.zonelessEnabled && this.zoneIsDefined && (E(Mo, { optional: true }) ?? false); + subscriptions = new H(); + angularZoneId = this.zoneIsDefined ? this.ngZone._inner?.get(qt) : null; + scheduleInRootZone = !this.zonelessEnabled && this.zoneIsDefined && (E(ki, { optional: true }) ?? false); cancelScheduledCallback = null; useMicrotaskScheduler = false; runningTick = false; @@ -4398,11 +5795,11 @@ var Bc = (() => { } if (this.appRef.tracingSnapshot = this.tracing?.snapshot(this.appRef.tracingSnapshot) ?? null, !this.shouldScheduleTick()) return; - let r = this.useMicrotaskScheduler ? Js : Do; + let r = this.useMicrotaskScheduler ? Uc : xi; this.pendingRenderTaskId = this.taskService.add(), this.scheduleInRootZone ? this.cancelScheduledCallback = Zone.root.run(() => r(() => this.tick())) : this.cancelScheduledCallback = this.ngZone.runOutsideAngular(() => r(() => this.tick())); } shouldScheduleTick() { - return !(this.appRef.destroyed || this.pendingRenderTaskId !== null || this.runningTick || this.appRef._runningTick || !this.zonelessEnabled && this.zoneIsDefined && Zone.current.get(ct + this.angularZoneId)); + return !(this.appRef.destroyed || this.pendingRenderTaskId !== null || this.runningTick || this.appRef._runningTick || !this.zonelessEnabled && this.zoneIsDefined && Zone.current.get(qt + this.angularZoneId)); } tick() { if (this.runningTick || this.appRef.destroyed) @@ -4433,130 +5830,136 @@ var Bc = (() => { } } static \u0275fac = function(r) { - return new (r || e6)(); + return new (r || e12)(); }; - static \u0275prov = S({ token: e6, factory: e6.\u0275fac, providedIn: "root" }); + static \u0275prov = _({ token: e12, factory: e12.\u0275fac, providedIn: "root" }); } - return e6; + return e12; })(); -function $c() { - return [{ provide: Ue, useExisting: Bc }, { provide: j, useClass: lt }, { provide: Tt, useValue: true }]; +function sa() { + return ct("NgZoneless"), Dt([...aa(), []]); +} +function aa() { + return [{ provide: Ze, useExisting: Gu }, { provide: Y, useClass: Zt }, { provide: tn, useValue: true }]; +} +function em() { + return typeof $localize < "u" && $localize.locale || En; } -function Xf() { - return typeof $localize < "u" && $localize.locale || Lt; +var ca = new D("", { factory: () => E(ca, { optional: true, skipSelf: true }) || em() }); +function $e(e12, t) { + return On(e12, t?.equal); } -var Ii = new m("", { factory: () => E(Ii, { optional: true, skipSelf: true }) || Xf() }); -var Di = new m(""); -var lp = new m(""); -function Ft(e6) { - return !e6.moduleRef; +var la = new D(""); +var um = new D(""); +function In(e12) { + return !e12.moduleRef; } -function up(e6) { - let t = Ft(e6) ? e6.r3Injector : e6.moduleRef.injector, n = t.get(j); +function dm(e12) { + let t = In(e12) ? e12.r3Injector : e12.moduleRef.injector, n = t.get(Y); return n.run(() => { - Ft(e6) ? e6.r3Injector.resolveInjectorInitializers() : e6.moduleRef.resolveInjectorInitializers(); - let r = t.get(Ke), o; + In(e12) ? e12.r3Injector.resolveInjectorInitializers() : e12.moduleRef.resolveInjectorInitializers(); + let r = t.get(rt), o; if (n.runOutsideAngular(() => { o = n.onError.subscribe({ next: r }); - }), Ft(e6)) { - let i = () => t.destroy(), s = e6.platformInjector.get(Di); + }), In(e12)) { + let i = () => t.destroy(), s = e12.platformInjector.get(la); s.add(i), t.onDestroy(() => { o.unsubscribe(), s.delete(i); }); } else { - let i = () => e6.moduleRef.destroy(), s = e6.platformInjector.get(Di); - s.add(i), e6.moduleRef.onDestroy(() => { - St(e6.allPlatformModules, e6.moduleRef), o.unsubscribe(), s.delete(i); + let i = () => e12.moduleRef.destroy(), s = e12.platformInjector.get(la); + s.add(i), e12.moduleRef.onDestroy(() => { + on(e12.allPlatformModules, e12.moduleRef), o.unsubscribe(), s.delete(i); }); } - return fp(r, n, () => { - let i = t.get(Ye), s = i.add(), a = t.get(Ei); + return pm(r, n, () => { + let i = t.get(At), s = i.add(), a = t.get(Js); return a.runInitializers(), a.donePromise.then(() => { - let c = t.get(Ii, Lt); - if (Vc(c || Lt), !t.get(lp, true)) - return Ft(e6) ? t.get(Ot) : (e6.allPlatformModules.push(e6.moduleRef), e6.moduleRef); - if (Ft(e6)) { - let u = t.get(Ot); - return e6.rootComponent !== void 0 && u.bootstrap(e6.rootComponent), u; + let c = t.get(ca, En); + if (Wu(c || En), !t.get(um, true)) + return In(e12) ? t.get(vn) : (e12.allPlatformModules.push(e12.moduleRef), e12.moduleRef); + if (In(e12)) { + let u = t.get(vn); + return e12.rootComponent !== void 0 && u.bootstrap(e12.rootComponent), u; } else - return dp?.(e6.moduleRef, e6.allPlatformModules), e6.moduleRef; + return fm?.(e12.moduleRef, e12.allPlatformModules), e12.moduleRef; }).finally(() => { i.remove(s); }); }); }); } -var dp; -function fp(e6, t, n) { +var fm; +function pm(e12, t, n) { try { let r = n(); - return vi(r) ? r.catch((o) => { - throw t.runOutsideAngular(() => e6(o)), o; + return Ks(r) ? r.catch((o) => { + throw t.runOutsideAngular(() => e12(o)), o; }) : r; } catch (r) { - throw t.runOutsideAngular(() => e6(r)), r; + throw t.runOutsideAngular(() => e12(r)), r; } } -var Jn = null; -function pp(e6 = [], t) { - return ee.create({ name: t, providers: [{ provide: ft, useValue: "platform" }, { provide: Di, useValue: /* @__PURE__ */ new Set([() => Jn = null]) }, ...e6] }); +var oo = null; +function hm(e12 = [], t) { + return ce.create({ name: t, providers: [{ provide: Yt, useValue: "platform" }, { provide: la, useValue: /* @__PURE__ */ new Set([() => oo = null]) }, ...e12] }); } -function hp(e6 = []) { - if (Jn) - return Jn; - let t = pp(e6); - return Jn = t, jc(), gp(t), t; +function gm(e12 = []) { + if (oo) + return oo; + let t = hm(e12); + return oo = t, Uu(), mm(t), t; } -function gp(e6) { - let t = e6.get(Vn, null); - pn(e6, () => { +function mm(e12) { + let t = e12.get(Hr, null); + nr(e12, () => { t?.forEach((n) => n()); }); } -var mp = 1e4; -var pT = mp - 1e3; -function zc(e6) { - let { rootComponent: t, appProviders: n, platformProviders: r, platformRef: o } = e6; - M(w.BootstrapApplicationStart); +var ym = 1e4; +var VM = ym - 1e3; +function Zu(e12) { + let { rootComponent: t, appProviders: n, platformProviders: r, platformRef: o } = e12; + T(C.BootstrapApplicationStart); try { - let i = o?.injector ?? hp(r), s = [$c(), ea, ...n || []], a = new xt({ providers: s, parent: i, debugName: "", runEnvironmentInitializers: false }); - return up({ r3Injector: a.injector, platformInjector: i, rootComponent: t }); + let i = o?.injector ?? gm(r), s = [aa(), Wc, ...n || []], a = new fn({ providers: s, parent: i, debugName: "", runEnvironmentInitializers: false }); + return dm({ r3Injector: a.injector, platformInjector: i, rootComponent: t }); } catch (i) { return Promise.reject(i); } finally { - M(w.BootstrapApplicationEnd); + T(C.BootstrapApplicationEnd); } } -var Wc = null; -function rt() { - return Wc; +var Qu = null; +function Ht() { + return Qu; } -function wi(e6) { - Wc ??= e6; +function ua(e12) { + Qu ??= e12; } -var jt = class { +var wn = class { }; -function Ci(e6, t) { +function da(e12, t) { t = encodeURIComponent(t); - for (let n of e6.split(";")) { + for (let n of e12.split(";")) { let r = n.indexOf("="), [o, i] = r == -1 ? [n, ""] : [n.slice(0, r), n.slice(r + 1)]; if (o.trim() === t) return decodeURIComponent(i); } return null; } -var Ht = class { +var Cn = class { }; -var Gc = "browser"; -var Vt = class { +var Yu = "browser"; +var bn = class { _doc; constructor(t) { this._doc = t; } manager; }; -var er = (() => { - class e6 extends Vt { +var io = (() => { + class e12 extends bn { constructor(n) { super(n); } @@ -4570,15 +5973,15 @@ var er = (() => { return n.removeEventListener(r, o, i); } static \u0275fac = function(r) { - return new (r || e6)(I(x)); + return new (r || e12)(w(U)); }; - static \u0275prov = S({ token: e6, factory: e6.\u0275fac }); + static \u0275prov = _({ token: e12, factory: e12.\u0275fac }); } - return e6; + return e12; })(); -var rr = new m(""); -var bi = (() => { - class e6 { +var co = new D(""); +var ga = (() => { + class e12 { _zone; _plugins; _eventNameToPlugin = /* @__PURE__ */ new Map(); @@ -4586,9 +5989,9 @@ var bi = (() => { this._zone = r, n.forEach((s) => { s.manager = this; }); - let o = n.filter((s) => !(s instanceof er)); + let o = n.filter((s) => !(s instanceof io)); this._plugins = o.slice().reverse(); - let i = n.find((s) => s instanceof er); + let i = n.find((s) => s instanceof io); i && this._plugins.push(i); } addEventListener(n, r, o, i) { @@ -4602,37 +6005,37 @@ var bi = (() => { if (r) return r; if (r = this._plugins.find((i) => i.supports(n)), !r) - throw new g(5101, false); + throw new v(5101, false); return this._eventNameToPlugin.set(n, r), r; } static \u0275fac = function(r) { - return new (r || e6)(I(rr), I(j)); + return new (r || e12)(w(co), w(Y)); }; - static \u0275prov = S({ token: e6, factory: e6.\u0275fac }); + static \u0275prov = _({ token: e12, factory: e12.\u0275fac }); } - return e6; + return e12; })(); -var Ti = "ng-app-id"; -function qc(e6) { - for (let t of e6) +var fa = "ng-app-id"; +function Ku(e12) { + for (let t of e12) t.remove(); } -function Zc(e6, t) { +function Ju(e12, t) { let n = t.createElement("style"); - return n.textContent = e6, n; + return n.textContent = e12, n; } -function yp(e6, t, n, r) { - let o = e6.head?.querySelectorAll(`style[${Ti}="${t}"],link[${Ti}="${t}"]`); +function vm(e12, t, n, r) { + let o = e12.head?.querySelectorAll(`style[${fa}="${t}"],link[${fa}="${t}"]`); if (o) for (let i of o) - i.removeAttribute(Ti), i instanceof HTMLLinkElement ? r.set(i.href.slice(i.href.lastIndexOf("/") + 1), { usage: 0, elements: [i] }) : i.textContent && n.set(i.textContent, { usage: 0, elements: [i] }); + i.removeAttribute(fa), i instanceof HTMLLinkElement ? r.set(i.href.slice(i.href.lastIndexOf("/") + 1), { usage: 0, elements: [i] }) : i.textContent && n.set(i.textContent, { usage: 0, elements: [i] }); } -function Si(e6, t) { +function ha(e12, t) { let n = t.createElement("link"); - return n.setAttribute("rel", "stylesheet"), n.setAttribute("href", e6), n; + return n.setAttribute("rel", "stylesheet"), n.setAttribute("href", e12), n; } -var _i = (() => { - class e6 { +var ma = (() => { + class e12 { doc; appId; nonce; @@ -4640,12 +6043,12 @@ var _i = (() => { external = /* @__PURE__ */ new Map(); hosts = /* @__PURE__ */ new Set(); constructor(n, r, o, i = {}) { - this.doc = n, this.appId = r, this.nonce = o, yp(n, r, this.inline, this.external), this.hosts.add(n.head); + this.doc = n, this.appId = r, this.nonce = o, vm(n, r, this.inline, this.external), this.hosts.add(n.head); } addStyles(n, r) { for (let o of n) - this.addUsage(o, this.inline, Zc); - r?.forEach((o) => this.addUsage(o, this.external, Si)); + this.addUsage(o, this.inline, Ju); + r?.forEach((o) => this.addUsage(o, this.external, ha)); } removeStyles(n, r) { for (let o of n) @@ -4658,19 +6061,19 @@ var _i = (() => { } removeUsage(n, r) { let o = r.get(n); - o && (o.usage--, o.usage <= 0 && (qc(o.elements), r.delete(n))); + o && (o.usage--, o.usage <= 0 && (Ku(o.elements), r.delete(n))); } ngOnDestroy() { for (let [, { elements: n }] of [...this.inline, ...this.external]) - qc(n); + Ku(n); this.hosts.clear(); } addHost(n) { this.hosts.add(n); for (let [r, { elements: o }] of this.inline) - o.push(this.addElement(n, Zc(r, this.doc))); + o.push(this.addElement(n, Ju(r, this.doc))); for (let [r, { elements: o }] of this.external) - o.push(this.addElement(n, Si(r, this.doc))); + o.push(this.addElement(n, ha(r, this.doc))); } removeHost(n) { this.hosts.delete(n); @@ -4679,30 +6082,30 @@ var _i = (() => { return this.nonce && r.setAttribute("nonce", this.nonce), n.appendChild(r); } static \u0275fac = function(r) { - return new (r || e6)(I(x), I(Hn), I(Bn, 8), I(At)); + return new (r || e12)(w(U), w(jr), w(Vr, 8), w(gn)); }; - static \u0275prov = S({ token: e6, factory: e6.\u0275fac }); + static \u0275prov = _({ token: e12, factory: e12.\u0275fac }); } - return e6; + return e12; })(); -var Mi = { svg: "http://www.w3.org/2000/svg", xhtml: "http://www.w3.org/1999/xhtml", xlink: "http://www.w3.org/1999/xlink", xml: "http://www.w3.org/XML/1998/namespace", xmlns: "http://www.w3.org/2000/xmlns/", math: "http://www.w3.org/1998/Math/MathML" }; -var Ni = /%COMP%/g; -var Yc = "%COMP%"; -var vp = `_nghost-${Yc}`; -var Ep = `_ngcontent-${Yc}`; -var Ip = true; -var Dp = new m("", { factory: () => Ip }); -function wp(e6) { - return Ep.replace(Ni, e6); -} -function Cp(e6) { - return vp.replace(Ni, e6); -} -function Kc(e6, t) { - return t.map((n) => n.replace(Ni, e6)); -} -var xi = (() => { - class e6 { +var pa = { svg: "http://www.w3.org/2000/svg", xhtml: "http://www.w3.org/1999/xhtml", xlink: "http://www.w3.org/1999/xlink", xml: "http://www.w3.org/XML/1998/namespace", xmlns: "http://www.w3.org/2000/xmlns/", math: "http://www.w3.org/1998/Math/MathML" }; +var ya = /%COMP%/g; +var ed = "%COMP%"; +var Em = `_nghost-${ed}`; +var Im = `_ngcontent-${ed}`; +var Dm = true; +var wm = new D("", { factory: () => Dm }); +function Cm(e12) { + return Im.replace(ya, e12); +} +function bm(e12) { + return Em.replace(ya, e12); +} +function td(e12, t) { + return t.map((n) => n.replace(ya, e12)); +} +var va = (() => { + class e12 { eventManager; sharedStylesHost; appId; @@ -4714,28 +6117,28 @@ var xi = (() => { rendererByCompId = /* @__PURE__ */ new Map(); defaultRenderer; constructor(n, r, o, i, s, a, c = null, l = null) { - this.eventManager = n, this.sharedStylesHost = r, this.appId = o, this.removeStylesOnCompDestroy = i, this.doc = s, this.ngZone = a, this.nonce = c, this.tracingService = l, this.defaultRenderer = new Bt(n, s, a, this.tracingService); + this.eventManager = n, this.sharedStylesHost = r, this.appId = o, this.removeStylesOnCompDestroy = i, this.doc = s, this.ngZone = a, this.nonce = c, this.tracingService = l, this.defaultRenderer = new Tn(n, s, a, this.tracingService); } createRenderer(n, r) { if (!n || !r) return this.defaultRenderer; let o = this.getOrCreateRenderer(n, r); - return o instanceof nr ? o.applyToHost(n) : o instanceof $t && o.applyStyles(), o; + return o instanceof ao ? o.applyToHost(n) : o instanceof Mn && o.applyStyles(), o; } getOrCreateRenderer(n, r) { let o = this.rendererByCompId, i = o.get(r.id); if (!i) { let s = this.doc, a = this.ngZone, c = this.eventManager, l = this.sharedStylesHost, u = this.removeStylesOnCompDestroy, d = this.tracingService; switch (r.encapsulation) { - case z.Emulated: - i = new nr(c, l, r, this.appId, u, s, a, d); + case ie.Emulated: + i = new ao(c, l, r, this.appId, u, s, a, d); break; - case z.ShadowDom: - return new tr(c, n, r, s, a, this.nonce, d, l); - case z.ExperimentalIsolatedShadowDom: - return new tr(c, n, r, s, a, this.nonce, d); + case ie.ShadowDom: + return new so(c, n, r, s, a, this.nonce, d, l); + case ie.ExperimentalIsolatedShadowDom: + return new so(c, n, r, s, a, this.nonce, d); default: - i = new $t(c, l, r, u, s, a, d); + i = new Mn(c, l, r, u, s, a, d); break; } o.set(r.id, i); @@ -4749,13 +6152,13 @@ var xi = (() => { this.rendererByCompId.delete(n); } static \u0275fac = function(r) { - return new (r || e6)(I(bi), I(_i), I(Hn), I(Dp), I(x), I(j), I(Bn), I(nt, 8)); + return new (r || e12)(w(ga), w(ma), w(jr), w(wm), w(U), w(Y), w(Vr), w(jt, 8)); }; - static \u0275prov = S({ token: e6, factory: e6.\u0275fac }); + static \u0275prov = _({ token: e12, factory: e12.\u0275fac }); } - return e6; + return e12; })(); -var Bt = class { +var Tn = class { eventManager; doc; ngZone; @@ -4769,7 +6172,7 @@ var Bt = class { } destroyNode = null; createElement(t, n) { - return n ? this.doc.createElementNS(Mi[n] || n, t) : this.doc.createElement(t); + return n ? this.doc.createElementNS(pa[n] || n, t) : this.doc.createElement(t); } createComment(t) { return this.doc.createComment(t); @@ -4778,10 +6181,10 @@ var Bt = class { return this.doc.createTextNode(t); } appendChild(t, n) { - (Qc(t) ? t.content : t).appendChild(n); + (Xu(t) ? t.content : t).appendChild(n); } insertBefore(t, n, r) { - t && (Qc(t) ? t.content : t).insertBefore(n, r); + t && (Xu(t) ? t.content : t).insertBefore(n, r); } removeChild(t, n) { n.remove(); @@ -4789,7 +6192,7 @@ var Bt = class { selectRootElement(t, n) { let r = typeof t == "string" ? this.doc.querySelector(t) : t; if (!r) - throw new g(-5104, false); + throw new v(-5104, false); return n || (r.textContent = ""), r; } parentNode(t) { @@ -4801,14 +6204,14 @@ var Bt = class { setAttribute(t, n, r, o) { if (o) { n = o + ":" + n; - let i = Mi[o]; + let i = pa[o]; i ? t.setAttributeNS(i, n, r) : t.setAttribute(n, r); } else t.setAttribute(n, r); } removeAttribute(t, n, r) { if (r) { - let o = Mi[r]; + let o = pa[r]; o ? t.removeAttributeNS(o, n) : t.removeAttribute(`${r}:${n}`); } else t.removeAttribute(n); @@ -4820,10 +6223,10 @@ var Bt = class { t.classList.remove(n); } setStyle(t, n, r, o) { - o & (ke.DashCase | ke.Important) ? t.style.setProperty(n, r, o & ke.Important ? "important" : "") : t.style[n] = r; + o & (Te.DashCase | Te.Important) ? t.style.setProperty(n, r, o & Te.Important ? "important" : "") : t.style[n] = r; } removeStyle(t, n, r) { - r & ke.DashCase ? t.style.removeProperty(n) : t.style[n] = ""; + r & Te.DashCase ? t.style.removeProperty(n) : t.style[n] = ""; } setProperty(t, n, r) { t != null && (t[n] = r); @@ -4832,8 +6235,8 @@ var Bt = class { t.nodeValue = n; } listen(t, n, r, o) { - if (typeof t == "string" && (t = rt().getGlobalEventTarget(this.doc, t), !t)) - throw new g(5102, false); + if (typeof t == "string" && (t = Ht().getGlobalEventTarget(this.doc, t), !t)) + throw new v(5102, false); let i = this.decoratePreventDefault(r); return this.tracingService?.wrapEventListener && (i = this.tracingService.wrapEventListener(t, n, i)), this.eventManager.addEventListener(t, n, i, o); } @@ -4845,26 +6248,26 @@ var Bt = class { }; } }; -function Qc(e6) { - return e6.tagName === "TEMPLATE" && e6.content !== void 0; +function Xu(e12) { + return e12.tagName === "TEMPLATE" && e12.content !== void 0; } -var tr = class extends Bt { +var so = class extends Tn { hostEl; sharedStylesHost; shadowRoot; constructor(t, n, r, o, i, s, a, c) { super(t, o, i, a), this.hostEl = n, this.sharedStylesHost = c, this.shadowRoot = n.attachShadow({ mode: "open" }), this.sharedStylesHost && this.sharedStylesHost.addHost(this.shadowRoot); let l = r.styles; - l = Kc(r.id, l); + l = td(r.id, l); for (let d of l) { - let p = document.createElement("style"); - s && p.setAttribute("nonce", s), p.textContent = d, this.shadowRoot.appendChild(p); + let f = document.createElement("style"); + s && f.setAttribute("nonce", s), f.textContent = d, this.shadowRoot.appendChild(f); } let u = r.getExternalStyles?.(); if (u) for (let d of u) { - let p = Si(d, o); - s && p.setAttribute("nonce", s), this.shadowRoot.appendChild(p); + let f = ha(d, o); + s && f.setAttribute("nonce", s), this.shadowRoot.appendChild(f); } } nodeOrShadowRoot(t) { @@ -4886,7 +6289,7 @@ var tr = class extends Bt { this.sharedStylesHost && this.sharedStylesHost.removeHost(this.shadowRoot); } }; -var $t = class extends Bt { +var Mn = class extends Tn { sharedStylesHost; removeStylesOnCompDestroy; styles; @@ -4894,21 +6297,21 @@ var $t = class extends Bt { constructor(t, n, r, o, i, s, a, c) { super(t, i, s, a), this.sharedStylesHost = n, this.removeStylesOnCompDestroy = o; let l = r.styles; - this.styles = c ? Kc(c, l) : l, this.styleUrls = r.getExternalStyles?.(c); + this.styles = c ? td(c, l) : l, this.styleUrls = r.getExternalStyles?.(c); } applyStyles() { this.sharedStylesHost.addStyles(this.styles, this.styleUrls); } destroy() { - this.removeStylesOnCompDestroy && et.size === 0 && this.sharedStylesHost.removeStyles(this.styles, this.styleUrls); + this.removeStylesOnCompDestroy && it.size === 0 && this.sharedStylesHost.removeStyles(this.styles, this.styleUrls); } }; -var nr = class extends $t { +var ao = class extends Mn { contentAttr; hostAttr; constructor(t, n, r, o, i, s, a, c) { let l = o + "-" + r.id; - super(t, n, r, i, s, a, c, l), this.contentAttr = wp(l), this.hostAttr = Cp(l); + super(t, n, r, i, s, a, c, l), this.contentAttr = Cm(l), this.hostAttr = bm(l); } applyToHost(t) { this.applyStyles(), this.setAttribute(t, this.hostAttr, ""); @@ -4918,10 +6321,10 @@ var nr = class extends $t { return super.setAttribute(r, this.contentAttr, ""), r; } }; -var or = class e4 extends jt { +var lo = class e9 extends wn { supportsDOMEvents = true; static makeCurrent() { - wi(new e4()); + ua(new e9()); } onAndCancel(t, n, r, o) { return t.addEventListener(n, r, o), () => { @@ -4953,59 +6356,59 @@ var or = class e4 extends jt { return n === "window" ? window : n === "document" ? t : n === "body" ? t.body : null; } getBaseHref(t) { - let n = Tp(); - return n == null ? null : Mp(n); + let n = Tm(); + return n == null ? null : Mm(n); } resetBaseElement() { - Ut = null; + _n = null; } getUserAgent() { return window.navigator.userAgent; } getCookie(t) { - return Ci(document.cookie, t); + return da(document.cookie, t); } }; -var Ut = null; -function Tp() { - return Ut = Ut || document.head.querySelector("base"), Ut ? Ut.getAttribute("href") : null; +var _n = null; +function Tm() { + return _n = _n || document.head.querySelector("base"), _n ? _n.getAttribute("href") : null; } -function Mp(e6) { - return new URL(e6, document.baseURI).pathname; +function Mm(e12) { + return new URL(e12, document.baseURI).pathname; } -var Sp = (() => { - class e6 { +var _m = (() => { + class e12 { build() { return new XMLHttpRequest(); } static \u0275fac = function(r) { - return new (r || e6)(); + return new (r || e12)(); }; - static \u0275prov = S({ token: e6, factory: e6.\u0275fac }); + static \u0275prov = _({ token: e12, factory: e12.\u0275fac }); } - return e6; + return e12; })(); -var Jc = ["alt", "control", "meta", "shift"]; -var bp = { "\b": "Backspace", " ": "Tab", "\x7F": "Delete", "\x1B": "Escape", Del: "Delete", Esc: "Escape", Left: "ArrowLeft", Right: "ArrowRight", Up: "ArrowUp", Down: "ArrowDown", Menu: "ContextMenu", Scroll: "ScrollLock", Win: "OS" }; -var _p = { alt: (e6) => e6.altKey, control: (e6) => e6.ctrlKey, meta: (e6) => e6.metaKey, shift: (e6) => e6.shiftKey }; -var Xc = (() => { - class e6 extends Vt { +var nd = ["alt", "control", "meta", "shift"]; +var Sm = { "\b": "Backspace", " ": "Tab", "\x7F": "Delete", "\x1B": "Escape", Del: "Delete", Esc: "Escape", Left: "ArrowLeft", Right: "ArrowRight", Up: "ArrowUp", Down: "ArrowDown", Menu: "ContextMenu", Scroll: "ScrollLock", Win: "OS" }; +var Nm = { alt: (e12) => e12.altKey, control: (e12) => e12.ctrlKey, meta: (e12) => e12.metaKey, shift: (e12) => e12.shiftKey }; +var rd = (() => { + class e12 extends bn { constructor(n) { super(n); } supports(n) { - return e6.parseEventName(n) != null; + return e12.parseEventName(n) != null; } addEventListener(n, r, o, i) { - let s = e6.parseEventName(r), a = e6.eventCallback(s.fullKey, o, this.manager.getZone()); - return this.manager.getZone().runOutsideAngular(() => rt().onAndCancel(n, s.domEventName, a, i)); + let s = e12.parseEventName(r), a = e12.eventCallback(s.fullKey, o, this.manager.getZone()); + return this.manager.getZone().runOutsideAngular(() => Ht().onAndCancel(n, s.domEventName, a, i)); } static parseEventName(n) { let r = n.toLowerCase().split("."), o = r.shift(); if (r.length === 0 || !(o === "keydown" || o === "keyup")) return null; - let i = e6._normalizeKey(r.pop()), s = "", a = r.indexOf("code"); - if (a > -1 && (r.splice(a, 1), s = "code."), Jc.forEach((l) => { + let i = e12._normalizeKey(r.pop()), s = "", a = r.indexOf("code"); + if (a > -1 && (r.splice(a, 1), s = "code."), nd.forEach((l) => { let u = r.indexOf(l); u > -1 && (r.splice(u, 1), s += l + "."); }), s += i, r.length != 0 || i.length === 0) @@ -5014,61 +6417,60 @@ var Xc = (() => { return c.domEventName = o, c.fullKey = s, c; } static matchEventFullKeyCode(n, r) { - let o = bp[n.key] || n.key, i = ""; - return r.indexOf("code.") > -1 && (o = n.code, i = "code."), o == null || !o ? false : (o = o.toLowerCase(), o === " " ? o = "space" : o === "." && (o = "dot"), Jc.forEach((s) => { + let o = Sm[n.key] || n.key, i = ""; + return r.indexOf("code.") > -1 && (o = n.code, i = "code."), o == null || !o ? false : (o = o.toLowerCase(), o === " " ? o = "space" : o === "." && (o = "dot"), nd.forEach((s) => { if (s !== o) { - let a = _p[s]; + let a = Nm[s]; a(n) && (i += s + "."); } }), i += o, i === r); } static eventCallback(n, r, o) { return (i) => { - e6.matchEventFullKeyCode(i, n) && o.runGuarded(() => r(i)); + e12.matchEventFullKeyCode(i, n) && o.runGuarded(() => r(i)); }; } static _normalizeKey(n) { return n === "esc" ? "escape" : n; } static \u0275fac = function(r) { - return new (r || e6)(I(x)); + return new (r || e12)(w(U)); }; - static \u0275prov = S({ token: e6, factory: e6.\u0275fac }); + static \u0275prov = _({ token: e12, factory: e12.\u0275fac }); } - return e6; + return e12; })(); -async function Ai(e6, t, n) { - let r = A({ rootComponent: e6 }, Np(t, n)); - return zc(r); +async function Ea(e12, t) { + return Zu(xm(e12, t)); } -function Np(e6, t) { - return { platformRef: t?.platformRef, appProviders: [...Op, ...e6?.providers ?? []], platformProviders: kp }; +function xm(e12, t) { + return { platformRef: t?.platformRef, appProviders: [...Pm, ...e12?.providers ?? []], platformProviders: km }; } -function xp() { - or.makeCurrent(); +function Am() { + lo.makeCurrent(); } -function Ap() { - return new te(); +function Rm() { + return new Ie(); } -function Rp() { - return ri(document), document; +function Om() { + return Ns(document), document; } -var kp = [{ provide: At, useValue: Gc }, { provide: Vn, useValue: xp, multi: true }, { provide: x, useFactory: Rp }]; -var Op = [{ provide: ft, useValue: "root" }, { provide: te, useFactory: Ap }, { provide: rr, useClass: er, multi: true }, { provide: rr, useClass: Xc, multi: true }, xi, _i, bi, { provide: Re, useExisting: xi }, { provide: Ht, useClass: Sp }, []]; -var Ri = (() => { - class e6 { +var km = [{ provide: gn, useValue: Yu }, { provide: Hr, useValue: Am, multi: true }, { provide: U, useFactory: Om }]; +var Pm = [{ provide: Yt, useValue: "root" }, { provide: Ie, useFactory: Rm }, { provide: co, useClass: io, multi: true }, { provide: co, useClass: rd, multi: true }, va, ma, ga, { provide: st, useExisting: va }, { provide: Cn, useClass: _m }, []]; +var Ia = (() => { + class e12 { static \u0275fac = function(r) { - return new (r || e6)(); + return new (r || e12)(); }; - static \u0275prov = S({ token: e6, factory: function(r) { + static \u0275prov = _({ token: e12, factory: function(r) { let o = null; - return r ? o = new (r || e6)() : o = I(Lp), o; + return r ? o = new (r || e12)() : o = w(Lm), o; }, providedIn: "root" }); } - return e6; + return e12; })(); -var Lp = (() => { - class e6 extends Ri { +var Lm = (() => { + class e12 extends Ia { _doc; constructor(n) { super(), this._doc = n; @@ -5077,79 +6479,256 @@ var Lp = (() => { if (r == null) return null; switch (n) { - case K.NONE: + case ge.NONE: return r; - case K.HTML: - return me(r, "HTML") ? ge(r) : zn(this._doc, String(r)).toString(); - case K.STYLE: - return me(r, "Style") ? ge(r) : r; - case K.SCRIPT: - if (me(r, "Script")) - return ge(r); - throw new g(5200, false); - case K.URL: - return me(r, "URL") ? ge(r) : Un(String(r)); - case K.RESOURCE_URL: - if (me(r, "ResourceURL")) - return ge(r); - throw new g(5201, false); + case ge.HTML: + return He(r, "HTML") ? Me(r) : Ur(this._doc, String(r)).toString(); + case ge.STYLE: + return He(r, "Style") ? Me(r) : r; + case ge.SCRIPT: + if (He(r, "Script")) + return Me(r); + throw new v(5200, false); + case ge.URL: + return He(r, "URL") ? Me(r) : $r(String(r)); + case ge.RESOURCE_URL: + if (He(r, "ResourceURL")) + return Me(r); + throw new v(5201, false); default: - throw new g(5202, false); + throw new v(5202, false); } } bypassSecurityTrustHtml(n) { - return ii(n); + return As(n); } bypassSecurityTrustStyle(n) { - return si(n); + return Rs(n); } bypassSecurityTrustScript(n) { - return ai(n); + return Os(n); } bypassSecurityTrustUrl(n) { - return ci(n); + return ks(n); } bypassSecurityTrustResourceUrl(n) { - return li(n); + return Ps(n); } static \u0275fac = function(r) { - return new (r || e6)(I(x)); + return new (r || e12)(w(U)); }; - static \u0275prov = S({ token: e6, factory: e6.\u0275fac, providedIn: "root" }); + static \u0275prov = _({ token: e12, factory: e12.\u0275fac, providedIn: "root" }); } - return e6; + return e12; })(); -var ir = class e5 { - constructor(t, n) { +var uo = class e10 { + constructor(t) { this.model = t; - this.sanitizer = n; if (t) { - this.message.set(t.get("message") || "Model loaded, no message."); - let r = t.get("table_html") || "

    No table HTML yet.

    "; - this.sanitizedHtml.set(this.sanitizer.bypassSecurityTrustHtml(r)), t.on("change:message", () => { - this.message.set(t.get("message")); + this.page.set(t.get("page") ?? 0), this.pageSize.set(t.get("page_size") ?? 10), this.maxColumns.set(t.get("max_columns") ?? 0), this.rowCount.set(t.get("row_count") ?? null), this.tableHtml.set(t.get("table_html") ?? ""), this.sortContext.set(t.get("sort_context") ?? []), this.orderableColumns.set(t.get("orderable_columns") ?? []); + let n = t.get("error_message") ?? t.get("_error_message") ?? null; + this.errorMessage.set(n), t.on("change:page", () => { + this.page.set(t.get("page")); + }), t.on("change:page_size", () => { + this.pageSize.set(t.get("page_size")); + }), t.on("change:max_columns", () => { + this.maxColumns.set(t.get("max_columns")); + }), t.on("change:row_count", () => { + this.rowCount.set(t.get("row_count")); }), t.on("change:table_html", () => { - let o = t.get("table_html"); - this.sanitizedHtml.set(this.sanitizer.bypassSecurityTrustHtml(o)); + this.tableHtml.set(t.get("table_html")); + }), t.on("change:sort_context", () => { + this.sortContext.set(t.get("sort_context")); + }), t.on("change:orderable_columns", () => { + this.orderableColumns.set(t.get("orderable_columns")); }); + let r = () => { + let o = t.get("error_message") ?? t.get("_error_message") ?? null; + this.errorMessage.set(o); + }; + t.on("change:error_message", r), t.on("change:_error_message", r); } } - message = Ct("Waiting for model..."); - sanitizedHtml = Ct(""); + page = q(0); + pageSize = q(10); + maxColumns = q(0); + rowCount = q(null); + tableHtml = q(""); + sortContext = q([]); + orderableColumns = q([]); + errorMessage = q(null); + setPage(t) { + this.page.set(t), this.model && (this.model.set("page", t), this.model.save_changes()); + } + setPageSize(t) { + this.pageSize.set(t), this.page.set(0), this.model && (this.model.set("page_size", t), this.model.set("page", 0), this.model.save_changes()); + } + setMaxColumns(t) { + this.maxColumns.set(t), this.model && (this.model.set("max_columns", t), this.model.save_changes()); + } + setSortContext(t) { + this.sortContext.set(t), this.model && (this.model.set("sort_context", t), this.model.save_changes()); + } + static \u0275fac = function(n) { + return new (n || e10)(w("ANYWIDGET_MODEL")); + }; + static \u0275prov = _({ token: e10, factory: e10.\u0275fac, providedIn: "root" }); +}; +var Fm = ["tableContainer"]; +function jm(e12, t) { + if (e12 & 1 && (j(0, "div", 2), se(1), B()), e12 & 2) { + let n = na(); + V(), Be(n.errorMessage()); + } +} +function Hm(e12, t) { + if (e12 & 1 && (j(0, "option", 13), se(1), B()), e12 & 2) { + let n = t.$implicit; + me("value", n), V(), Be(n === 0 ? "All" : n); + } +} +function Vm(e12, t) { + if (e12 & 1 && (j(0, "option", 13), se(1), B()), e12 & 2) { + let n = t.$implicit; + me("value", n), V(), Be(n); + } +} +var fo = class e11 { + state = E(uo); + sanitizer = E(Ia); + maxColumnOptions = [5, 10, 15, 20, 0]; + pageSizeOptions = [10, 25, 50, 100]; + errorMessage = this.state.errorMessage; + maxColumns = this.state.maxColumns; + pageSize = this.state.pageSize; + page = this.state.page; + rowCount = this.state.rowCount; + sanitizedHtml = $e(() => this.sanitizer.bypassSecurityTrustHtml(this.state.tableHtml())); + totalPages = $e(() => { + let t = this.rowCount(), n = this.pageSize(); + return t !== null && n > 0 ? Math.ceil(t / n) : null; + }); + pageIndicatorText = $e(() => { + let t = this.page(), n = this.rowCount(), r = this.totalPages(), o = (t + 1).toLocaleString(), i = (r ?? 1).toLocaleString(); + return `Page ${o} of ${i}`; + }); + rowCountText = $e(() => { + let t = this.rowCount(); + return t === null ? "Total rows unknown" : t === 0 ? "0 total rows" : `${t.toLocaleString()} total rows`; + }); + prevPageDisabled = $e(() => this.page() === 0); + nextPageDisabled = $e(() => { + let t = this.page(), n = this.rowCount(), r = this.totalPages(); + return n === null ? false : n === 0 ? true : r !== null && t >= r - 1; + }); + isDarkMode = q(false); + themeObserver = null; + tableContainerRef; + constructor() { + Pi(() => { + let t = this.state.tableHtml(), n = this.state.sortContext(), r = this.state.orderableColumns(); + setTimeout(() => { + this.applySortIndicators(); + }, 0); + }); + } + ngOnInit() { + this.initThemeDetection(); + } + ngOnDestroy() { + this.themeObserver?.disconnect(); + } + handlePageChange(t) { + let n = this.page() + t; + this.state.setPage(n); + } + handlePageSizeChange(t) { + let n = t.target, r = Number(n.value); + r && this.state.setPageSize(r); + } + handleMaxColumnsChange(t) { + let n = t.target, r = Number(n.value); + this.state.setMaxColumns(r); + } + handleTableClick(t) { + let r = t.target.closest("th"); + if (!r) + return; + let o = r.querySelector("div.bf-header-content"); + if (!o) + return; + let i = this.getColumnName(o), s = this.state.orderableColumns(); + if (!i || !s.includes(i)) + return; + let a = [...this.state.sortContext()], c = a.findIndex((u) => u.column === i), l = [...a]; + t.shiftKey ? c !== -1 ? l[c].ascending ? l[c] = A(N({}, l[c]), { ascending: false }) : l.splice(c, 1) : l.push({ column: i, ascending: true }) : c !== -1 && l.length === 1 ? l[c].ascending ? l[c] = A(N({}, l[c]), { ascending: false }) : l = [] : l = [{ column: i, ascending: true }], this.state.setSortContext(l); + } + getColumnName(t) { + let n = t.cloneNode(true); + return n.querySelector(".sort-indicator")?.remove(), n.textContent?.trim() || ""; + } + applySortIndicators() { + let t = this.tableContainerRef?.nativeElement; + if (!t) + return; + let n = this.state.orderableColumns(), r = this.state.sortContext() || [], o = (s) => r.findIndex((a) => a.column === s); + t.querySelectorAll("th").forEach((s) => { + let a = s.querySelector("div.bf-header-content"); + if (!a) + return; + let c = this.getColumnName(a); + if (c && n.includes(c)) { + let l = a.querySelector(".sort-indicator"); + l || (l = document.createElement("span"), l.classList.add("sort-indicator"), l.style.paddingLeft = "5px", a.appendChild(l)); + let u = o(c); + if (u !== -1) { + let d = r[u].ascending; + l.textContent = d ? "\u25B2" : "\u25BC", l.style.visibility = "visible"; + } else + l.textContent = "\u25CF", l.style.visibility = "hidden"; + } + }); + } + initThemeDetection() { + this.updateTheme(); + let t = new MutationObserver(() => this.updateTheme()); + t.observe(document.body, { attributes: true, attributeFilter: ["class", "data-theme", "data-vscode-theme-kind"] }), this.themeObserver = t; + } + updateTheme() { + let t = document.body, n = t.classList.contains("vscode-dark") || t.classList.contains("theme-dark") || t.dataset.theme === "dark" || t.getAttribute("data-vscode-theme-kind") === "vscode-dark"; + this.isDarkMode.set(n); + } static \u0275fac = function(n) { - return new (n || e5)(kt("ANYWIDGET_MODEL"), kt(Ri)); + return new (n || e11)(); }; - static \u0275cmp = mi({ type: e5, selectors: [["app-root"]], decls: 8, vars: 2, consts: [[1, "angular-widget"], [3, "innerHTML"]], template: function(n, r) { - n & 1 && (Oe(0, "div", 0)(1, "h3"), Pt(2, "Angular Hybrid Widget"), ye(), Oe(3, "p"), Pt(4, "Status: Infrastructure Loaded"), ye(), Oe(5, "p"), Pt(6), ye(), Qn(7, "div", 1), ye()), n & 2 && (Wn(6), Kn("Message from Python: ", r.message()), Wn(), Yn("innerHTML", r.sanitizedHtml(), ui)); - }, styles: [".angular-widget[_ngcontent-%COMP%]{background-color:#f9f9f9;border:1px solid #ccc;border-radius:4px;padding:10px}"] }); + static \u0275cmp = Qs({ type: e11, selectors: [["app-root"]], viewQuery: function(n, r) { + if (n & 1 && no(Fm, 7), n & 2) { + let o; + ra(o = oa()) && (r.tableContainerRef = o.first); + } + }, decls: 27, vars: 10, consts: [["tableContainer", ""], [1, "bigframes-widget"], [1, "bigframes-error-message"], [1, "table-container", 3, "click", "innerHTML"], [1, "footer"], [1, "row-count"], [1, "pagination"], [3, "click", "disabled"], [1, "page-indicator"], [1, "settings"], [1, "max-columns"], ["for", "max-cols-select"], ["id", "max-cols-select", 3, "change", "value"], [3, "value"], [1, "page-size"], ["for", "page-size-select"], ["id", "page-size-select", 3, "change", "value"]], template: function(n, r) { + n & 1 && (j(0, "div", 1), Xs(1, jm, 2, 1, "div", 2), j(2, "div", 3, 0), Ve("click", function(i) { + return r.handleTableClick(i); + }), B(), j(4, "footer", 4)(5, "span", 5), se(6), B(), j(7, "div", 6)(8, "button", 7), Ve("click", function() { + return r.handlePageChange(-1); + }), se(9, "<"), B(), j(10, "span", 8), se(11), B(), j(12, "button", 7), Ve("click", function() { + return r.handlePageChange(1); + }), se(13, ">"), B()(), j(14, "div", 9)(15, "div", 10)(16, "label", 11), se(17, "Max columns:"), B(), j(18, "select", 12), Ve("change", function(i) { + return r.handleMaxColumnsChange(i); + }), eo(19, Hm, 2, 2, "option", 13, Xr), B()(), j(21, "div", 14)(22, "label", 15), se(23, "Page size:"), B(), j(24, "select", 16), Ve("change", function(i) { + return r.handlePageSizeChange(i); + }), eo(25, Vm, 2, 2, "option", 13, Xr), B()()()()()), n & 2 && (ro("bigframes-dark-mode", r.isDarkMode()), V(), ta(r.errorMessage() ? 1 : -1), V(), me("innerHTML", r.sanitizedHtml(), Ls), V(4), Be(r.rowCountText()), V(2), me("disabled", r.prevPageDisabled()), V(3), Be(r.pageIndicatorText()), V(), me("disabled", r.nextPageDisabled()), V(6), me("value", r.maxColumns()), V(), to(r.maxColumnOptions), V(5), me("value", r.pageSize()), V(), to(r.pageSizeOptions)); + }, styles: [".bigframes-widget.bigframes-widget[_ngcontent-%COMP%]{--bf-bg: white;--bf-border-color: #ccc;--bf-error-bg: #fbe;--bf-error-border: red;--bf-error-fg: black;--bf-fg: black;--bf-header-bg: #f5f5f5;--bf-null-fg: gray;--bf-row-even-bg: #f5f5f5;--bf-row-odd-bg: white;background-color:var(--bf-bg);box-sizing:border-box;color:var(--bf-fg);display:flex;flex-direction:column;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;margin:0;padding:0}.bigframes-widget[_ngcontent-%COMP%] *[_ngcontent-%COMP%]{box-sizing:border-box}@media(prefers-color-scheme:dark){.bigframes-widget.bigframes-widget[_ngcontent-%COMP%]{--bf-bg: var(--vscode-editor-background, #202124);--bf-border-color: #444;--bf-error-bg: #511;--bf-error-border: #f88;--bf-error-fg: #fcc;--bf-fg: white;--bf-header-bg: var(--vscode-editor-background, black);--bf-null-fg: #aaa;--bf-row-even-bg: #202124;--bf-row-odd-bg: #383838}}.bigframes-widget.bigframes-dark-mode.bigframes-dark-mode[_ngcontent-%COMP%]{--bf-bg: var(--vscode-editor-background, #202124);--bf-border-color: #444;--bf-error-bg: #511;--bf-error-border: #f88;--bf-error-fg: #fcc;--bf-fg: white;--bf-header-bg: var(--vscode-editor-background, black);--bf-null-fg: #aaa;--bf-row-even-bg: #202124;--bf-row-odd-bg: #383838}.bigframes-widget[_ngcontent-%COMP%] .table-container[_ngcontent-%COMP%]{background-color:var(--bf-bg);margin:0;max-height:620px;overflow:auto;padding:0}.bigframes-widget[_ngcontent-%COMP%] .footer[_ngcontent-%COMP%]{align-items:center;background-color:var(--bf-bg);color:var(--bf-fg);display:flex;font-size:.8rem;justify-content:space-between;padding:8px}.bigframes-widget[_ngcontent-%COMP%] .footer[_ngcontent-%COMP%] > *[_ngcontent-%COMP%]{flex:1}.bigframes-widget[_ngcontent-%COMP%] .pagination[_ngcontent-%COMP%]{align-items:center;display:flex;flex-direction:row;gap:4px;justify-content:center;padding:4px}.bigframes-widget[_ngcontent-%COMP%] .page-indicator[_ngcontent-%COMP%], .bigframes-widget[_ngcontent-%COMP%] .row-count[_ngcontent-%COMP%]{margin:0 8px}.bigframes-widget[_ngcontent-%COMP%] .settings[_ngcontent-%COMP%]{align-items:center;display:flex;flex-direction:row;gap:16px;justify-content:end}.bigframes-widget[_ngcontent-%COMP%] .page-size[_ngcontent-%COMP%], .bigframes-widget[_ngcontent-%COMP%] .max-columns[_ngcontent-%COMP%]{align-items:center;display:flex;flex-direction:row;gap:4px}.bigframes-widget[_ngcontent-%COMP%] .page-size[_ngcontent-%COMP%] label[_ngcontent-%COMP%], .bigframes-widget[_ngcontent-%COMP%] .max-columns[_ngcontent-%COMP%] label[_ngcontent-%COMP%]{margin-right:8px}.bigframes-widget[_ngcontent-%COMP%] table.bigframes-widget-table, .bigframes-widget[_ngcontent-%COMP%] table.dataframe{background-color:var(--bf-bg);border:1px solid var(--bf-border-color);border-collapse:collapse;border-spacing:0;box-shadow:none;color:var(--bf-fg);margin:0;outline:none;text-align:left;width:auto}.bigframes-widget[_ngcontent-%COMP%] tr{border:none}.bigframes-widget[_ngcontent-%COMP%] th{background-color:var(--bf-header-bg);border:1px solid var(--bf-border-color);color:var(--bf-fg);padding:0;position:sticky;text-align:left;top:0;z-index:1}.bigframes-widget[_ngcontent-%COMP%] td{border:1px solid var(--bf-border-color);color:var(--bf-fg);padding:.5em}.bigframes-widget[_ngcontent-%COMP%] table tbody tr:nth-child(odd), .bigframes-widget[_ngcontent-%COMP%] table tbody tr:nth-child(odd) td{background-color:var(--bf-row-odd-bg)}.bigframes-widget[_ngcontent-%COMP%] table tbody tr:nth-child(2n), .bigframes-widget[_ngcontent-%COMP%] table tbody tr:nth-child(2n) td{background-color:var(--bf-row-even-bg)}.bigframes-widget[_ngcontent-%COMP%] .bf-header-content{box-sizing:border-box;height:100%;overflow:auto;padding:.5em;resize:horizontal;width:100%}.bigframes-widget[_ngcontent-%COMP%] th .sort-indicator{padding-left:4px;visibility:hidden}.bigframes-widget[_ngcontent-%COMP%] th:hover .sort-indicator{visibility:visible}.bigframes-widget[_ngcontent-%COMP%] button[_ngcontent-%COMP%]{background-color:transparent;border:1px solid currentColor;border-radius:4px;color:inherit;cursor:pointer;display:inline-block;padding:2px 8px;text-align:center;text-decoration:none;-webkit-user-select:none;user-select:none;vertical-align:middle}.bigframes-widget[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:disabled{opacity:.65;pointer-events:none}.bigframes-widget[_ngcontent-%COMP%] .bigframes-error-message[_ngcontent-%COMP%]{background-color:var(--bf-error-bg);border:1px solid var(--bf-error-border);border-radius:4px;color:var(--bf-error-fg);font-size:14px;margin-bottom:8px;padding:8px}.bigframes-widget[_ngcontent-%COMP%] .cell-align-right{text-align:right}.bigframes-widget[_ngcontent-%COMP%] .cell-align-left{text-align:left}.bigframes-widget[_ngcontent-%COMP%] .null-value{color:var(--bf-null-fg)}.bigframes-widget[_ngcontent-%COMP%] .debug-info{border-top:1px solid var(--bf-border-color)}"] }); }; -function Fp({ model: e6, el: t }) { +function Bm({ model: e12, el: t }) { let n = document.createElement("app-root"); t.appendChild(n); - let r = { providers: [To(), { provide: "ANYWIDGET_MODEL", useValue: e6 }] }; - Ai(ir, r).catch((o) => console.error(o)); + let r = { providers: [Oi(), sa(), { provide: "ANYWIDGET_MODEL", useValue: e12 }] }; + Ea(r).then((o) => { + o.bootstrap(fo, n); + }).catch((o) => console.error(o)); } -var EM = { render: Fp }; +var tS = { render: Bm }; export { - EM as default + tS as default }; diff --git a/packages/bigframes/bigframes/display/table_widget_angular/README.md b/packages/bigframes/bigframes/display/table_widget_angular/README.md index 6ac5408cb0a4..80af11fd0954 100644 --- a/packages/bigframes/bigframes/display/table_widget_angular/README.md +++ b/packages/bigframes/bigframes/display/table_widget_angular/README.md @@ -1,41 +1,65 @@ # TableWidgetAngular -This project is the Angular-based interactive Table Widget frontend for BigQuery DataFrames (``bigframes``). It is integrated into the Python backend using ``anywidget``. +This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 21.2.9. -## Getting Started +## Development server -Ensure you have [Node.js](https://nodejs.org/) installed. +To start a local development server, run: -1. Install dependencies: - ```bash - npm install - ``` +```bash +npm start +# or +npx ng serve +``` + +Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files. -2. Start the local development server: - ```bash - npm run start - ``` - Navigate to `http://localhost:4200/`. The application will automatically reload when you modify the source files under `src/`. +## Code scaffolding -## Development & Code Scaffolding +Angular CLI includes powerful code scaffolding tools. To generate a new component, run: -This project was generated using [Angular CLI](https://github.com/angular/angular-cli). To generate a new component, directive, or service: ```bash -ng generate component component-name +npx ng generate component component-name ``` -## Running Tests +For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run: + +```bash +npx ng generate --help +``` + +## Building + +To build the project run: + +```bash +npm run build +# or +npx ng build +``` + +This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed. + +## Running unit tests + +To execute unit tests with the [Vitest](https://vitest.dev/) test runner, use the following command: -To execute unit tests: ```bash npm run test +# or +npx ng test ``` -## Packaging for Python +## Running end-to-end tests + +For end-to-end (e2e) testing, run: -Before testing the widget inside a Jupyter notebook or committing changes, compile the Angular app and bundle it so that the Python backend can load it: ```bash -npm run build:widget +npx ng e2e ``` -This command compiles the project in production mode and then triggers `bundle.js` (via `esbuild`) to bundle the browser artifacts into a single unified ES module file at `../table_widget_angular.js`. +Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs. + +## Additional Resources + +For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page. diff --git a/packages/bigframes/bigframes/display/table_widget_angular/src/app/app.spec.ts b/packages/bigframes/bigframes/display/table_widget_angular/src/app/app.spec.ts index 0c5453db626a..75ccf03e436c 100644 --- a/packages/bigframes/bigframes/display/table_widget_angular/src/app/app.spec.ts +++ b/packages/bigframes/bigframes/display/table_widget_angular/src/app/app.spec.ts @@ -31,10 +31,10 @@ describe('App', () => { expect(app).toBeTruthy(); }); - it('should render title', async () => { + it('should render the table container', async () => { const fixture = TestBed.createComponent(App); fixture.detectChanges(); const compiled = fixture.nativeElement as HTMLElement; - expect(compiled.querySelector('h3')?.textContent).toContain('Angular Hybrid Widget'); + expect(compiled.querySelector('.table-container')).toBeTruthy(); }); }); diff --git a/packages/bigframes/bigframes/display/table_widget_angular/src/app/app.ts b/packages/bigframes/bigframes/display/table_widget_angular/src/app/app.ts index 995c0f64b59f..343be0074708 100644 --- a/packages/bigframes/bigframes/display/table_widget_angular/src/app/app.ts +++ b/packages/bigframes/bigframes/display/table_widget_angular/src/app/app.ts @@ -14,53 +14,514 @@ * limitations under the License. */ -import { Component, Inject, signal } from '@angular/core'; -import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; +import { Component, ElementRef, ViewChild, computed, effect, inject, signal } from '@angular/core'; +import { DomSanitizer } from '@angular/platform-browser'; +import { WidgetStateService } from './widget-state.service'; @Component({ selector: 'app-root', standalone: true, imports: [], template: ` -
    -

    Angular Hybrid Widget

    -

    Status: Infrastructure Loaded

    -

    Message from Python: {{ message() }}

    -
    +
    + @if (errorMessage()) { +
    {{ errorMessage() }}
    + } + +
    +
    + +
    + {{ rowCountText() }} + + + +
    +
    + + +
    + +
    + + +
    +
    +
    `, styles: [` - .angular-widget { - background-color: #f9f9f9; - border: 1px solid #ccc; + /* Increase specificity to override framework styles without !important */ + .bigframes-widget.bigframes-widget { + /* Default Light Mode Variables */ + --bf-bg: white; + --bf-border-color: #ccc; + --bf-error-bg: #fbe; + --bf-error-border: red; + --bf-error-fg: black; + --bf-fg: black; + --bf-header-bg: #f5f5f5; + --bf-null-fg: gray; + --bf-row-even-bg: #f5f5f5; + --bf-row-odd-bg: white; + + background-color: var(--bf-bg); + box-sizing: border-box; + color: var(--bf-fg); + display: flex; + flex-direction: column; + font-family: + '-apple-system', 'BlinkMacSystemFont', 'Segoe UI', 'Roboto', sans-serif; + margin: 0; + padding: 0; + } + + .bigframes-widget * { + box-sizing: border-box; + } + + /* Dark Mode Overrides */ + @media (prefers-color-scheme: dark) { + .bigframes-widget.bigframes-widget { + --bf-bg: var(--vscode-editor-background, #202124); + --bf-border-color: #444; + --bf-error-bg: #511; + --bf-error-border: #f88; + --bf-error-fg: #fcc; + --bf-fg: white; + --bf-header-bg: var(--vscode-editor-background, black); + --bf-null-fg: #aaa; + --bf-row-even-bg: #202124; + --bf-row-odd-bg: #383838; + } + } + + .bigframes-widget.bigframes-dark-mode.bigframes-dark-mode { + --bf-bg: var(--vscode-editor-background, #202124); + --bf-border-color: #444; + --bf-error-bg: #511; + --bf-error-border: #f88; + --bf-error-fg: #fcc; + --bf-fg: white; + --bf-header-bg: var(--vscode-editor-background, black); + --bf-null-fg: #aaa; + --bf-row-even-bg: #202124; + --bf-row-odd-bg: #383838; + } + + .bigframes-widget .table-container { + background-color: var(--bf-bg); + margin: 0; + max-height: 620px; + overflow: auto; + padding: 0; + } + + .bigframes-widget .footer { + align-items: center; + background-color: var(--bf-bg); + color: var(--bf-fg); + display: flex; + font-size: 0.8rem; + justify-content: space-between; + padding: 8px; + } + + .bigframes-widget .footer > * { + flex: 1; + } + + .bigframes-widget .pagination { + align-items: center; + display: flex; + flex-direction: row; + gap: 4px; + justify-content: center; + padding: 4px; + } + + .bigframes-widget .page-indicator { + margin: 0 8px; + } + + .bigframes-widget .row-count { + margin: 0 8px; + } + + .bigframes-widget .settings { + align-items: center; + display: flex; + flex-direction: row; + gap: 16px; + justify-content: end; + } + + .bigframes-widget .page-size, + .bigframes-widget .max-columns { + align-items: center; + display: flex; + flex-direction: row; + gap: 4px; + } + + .bigframes-widget .page-size label, + .bigframes-widget .max-columns label { + margin-right: 8px; + } + + /* Dynamic internal elements styles */ + .bigframes-widget ::ng-deep table.bigframes-widget-table, + .bigframes-widget ::ng-deep table.dataframe { + background-color: var(--bf-bg); + border: 1px solid var(--bf-border-color); + border-collapse: collapse; + border-spacing: 0; + box-shadow: none; + color: var(--bf-fg); + margin: 0; + outline: none; + text-align: left; + width: auto; + } + + .bigframes-widget ::ng-deep tr { + border: none; + } + + .bigframes-widget ::ng-deep th { + background-color: var(--bf-header-bg); + border: 1px solid var(--bf-border-color); + color: var(--bf-fg); + padding: 0; + position: sticky; + text-align: left; + top: 0; + z-index: 1; + } + + .bigframes-widget ::ng-deep td { + border: 1px solid var(--bf-border-color); + color: var(--bf-fg); + padding: 0.5em; + } + + .bigframes-widget ::ng-deep table tbody tr:nth-child(odd), + .bigframes-widget ::ng-deep table tbody tr:nth-child(odd) td { + background-color: var(--bf-row-odd-bg); + } + + .bigframes-widget ::ng-deep table tbody tr:nth-child(even), + .bigframes-widget ::ng-deep table tbody tr:nth-child(even) td { + background-color: var(--bf-row-even-bg); + } + + .bigframes-widget ::ng-deep .bf-header-content { + box-sizing: border-box; + height: 100%; + overflow: auto; + padding: 0.5em; + resize: horizontal; + width: 100%; + } + + .bigframes-widget ::ng-deep th .sort-indicator { + padding-left: 4px; + visibility: hidden; + } + + .bigframes-widget ::ng-deep th:hover .sort-indicator { + visibility: visible; + } + + .bigframes-widget button { + background-color: transparent; + border: 1px solid currentColor; border-radius: 4px; - padding: 10px; + color: inherit; + cursor: pointer; + display: inline-block; + padding: 2px 8px; + text-align: center; + text-decoration: none; + user-select: none; + vertical-align: middle; + } + + .bigframes-widget button:disabled { + opacity: 0.65; + pointer-events: none; + } + + .bigframes-widget .bigframes-error-message { + background-color: var(--bf-error-bg); + border: 1px solid var(--bf-error-border); + border-radius: 4px; + color: var(--bf-error-fg); + font-size: 14px; + margin-bottom: 8px; + padding: 8px; + } + + .bigframes-widget ::ng-deep .cell-align-right { + text-align: right; + } + + .bigframes-widget ::ng-deep .cell-align-left { + text-align: left; + } + + .bigframes-widget ::ng-deep .null-value { + color: var(--bf-null-fg); + } + + .bigframes-widget ::ng-deep .debug-info { + border-top: 1px solid var(--bf-border-color); } `] }) -// Dummy comment to test pre-commit hook export class App { - protected readonly message = signal('Waiting for model...'); - protected readonly sanitizedHtml = signal(''); - - constructor( - @Inject('ANYWIDGET_MODEL') public model: any, - private sanitizer: DomSanitizer - ) { - if (model) { - this.message.set(model.get('message') || 'Model loaded, no message.'); - - const rawHtml = model.get('table_html') || '

    No table HTML yet.

    '; - this.sanitizedHtml.set(this.sanitizer.bypassSecurityTrustHtml(rawHtml)); - - // Listen for changes - model.on('change:message', () => { - this.message.set(model.get('message')); - }); - model.on('change:table_html', () => { - const html = model.get('table_html'); - this.sanitizedHtml.set(this.sanitizer.bypassSecurityTrustHtml(html)); - }); + protected readonly state = inject(WidgetStateService); + private readonly sanitizer = inject(DomSanitizer); + + protected readonly maxColumnOptions = [5, 10, 15, 20, 0]; + protected readonly pageSizeOptions = [10, 25, 50, 100]; + + // State signals + protected readonly errorMessage = this.state.errorMessage; + protected readonly maxColumns = this.state.maxColumns; + protected readonly pageSize = this.state.pageSize; + protected readonly page = this.state.page; + protected readonly rowCount = this.state.rowCount; + + // Computed properties for formatting and display states + protected readonly sanitizedHtml = computed(() => + this.sanitizer.bypassSecurityTrustHtml(this.state.tableHtml()) + ); + + protected readonly totalPages = computed(() => { + const count = this.rowCount(); + const size = this.pageSize(); + return count !== null && size > 0 ? Math.ceil(count / size) : null; + }); + + protected readonly pageIndicatorText = computed(() => { + const currentPage = this.page(); + const count = this.rowCount(); + const total = this.totalPages(); + const currentStr = (currentPage + 1).toLocaleString(); + const totalStr = (total ?? 1).toLocaleString(); + return `Page ${currentStr} of ${totalStr}`; + }); + + protected readonly rowCountText = computed(() => { + const count = this.rowCount(); + if (count === null) { + return 'Total rows unknown'; + } + if (count === 0) { + return '0 total rows'; + } + return `${count.toLocaleString()} total rows`; + }); + + protected readonly prevPageDisabled = computed(() => this.page() === 0); + + protected readonly nextPageDisabled = computed(() => { + const currentPage = this.page(); + const count = this.rowCount(); + const total = this.totalPages(); + if (count === null) { + return false; + } + if (count === 0) { + return true; + } + return total !== null && currentPage >= total - 1; + }); + + protected readonly isDarkMode = signal(false); + private themeObserver: MutationObserver | null = null; + + @ViewChild('tableContainer', { static: true }) + tableContainerRef!: ElementRef; + + constructor() { + effect(() => { + // Setup dependencies for reactive effect + const _html = this.state.tableHtml(); + const _sort = this.state.sortContext(); + const _orderable = this.state.orderableColumns(); + + // Schedule DOM post-processing once the innerHTML render completes + setTimeout(() => { + this.applySortIndicators(); + }, 0); + }); + } + + ngOnInit() { + this.initThemeDetection(); + } + + ngOnDestroy() { + this.themeObserver?.disconnect(); + } + + protected handlePageChange(direction: number) { + const nextPage = this.page() + direction; + this.state.setPage(nextPage); + } + + protected handlePageSizeChange(event: Event) { + const select = event.target as HTMLSelectElement; + const newSize = Number(select.value); + if (newSize) { + this.state.setPageSize(newSize); + } + } + + protected handleMaxColumnsChange(event: Event) { + const select = event.target as HTMLSelectElement; + const maxCols = Number(select.value); + this.state.setMaxColumns(maxCols); + } + + protected handleTableClick(event: MouseEvent) { + const target = event.target as HTMLElement; + const header = target.closest('th'); + if (!header) return; + + const headerDiv = header.querySelector( + 'div.bf-header-content' + ) as HTMLElement | null; + if (!headerDiv) return; + + const columnName = this.getColumnName(headerDiv); + const sortableColumns = this.state.orderableColumns(); + if (!columnName || !sortableColumns.includes(columnName)) return; + + const currentSortContext = [...this.state.sortContext()]; + const sortIndex = currentSortContext.findIndex( + (item) => item.column === columnName + ); + let newContext = [...currentSortContext]; + + if (event.shiftKey) { + if (sortIndex !== -1) { + // Toggle: Asc -> Desc -> Unsorted + if (newContext[sortIndex].ascending) { + newContext[sortIndex] = { + ...newContext[sortIndex], + ascending: false + }; + } else { + newContext.splice(sortIndex, 1); + } + } else { + newContext.push({ column: columnName, ascending: true }); + } + } else { + // Single column sort mode + if (sortIndex !== -1 && newContext.length === 1) { + // Toggle: Asc -> Desc -> Unsorted + if (newContext[sortIndex].ascending) { + newContext[sortIndex] = { + ...newContext[sortIndex], + ascending: false + }; + } else { + newContext = []; + } + } else { + newContext = [{ column: columnName, ascending: true }]; + } } + + this.state.setSortContext(newContext); + } + + private getColumnName(headerDiv: HTMLElement): string { + const clone = headerDiv.cloneNode(true) as HTMLElement; + clone.querySelector('.sort-indicator')?.remove(); + return clone.textContent?.trim() || ''; + } + + private applySortIndicators() { + const container = this.tableContainerRef?.nativeElement; + if (!container) return; + + const sortableColumns = this.state.orderableColumns(); + const currentSortContext = this.state.sortContext() || []; + + const getSortIndex = (colName: string) => + currentSortContext.findIndex((item) => item.column === colName); + + const headers = container.querySelectorAll('th'); + headers.forEach((header: HTMLElement) => { + const headerDiv = header.querySelector( + 'div.bf-header-content' + ) as HTMLElement | null; + if (!headerDiv) return; + + const columnName = this.getColumnName(headerDiv); + if (columnName && sortableColumns.includes(columnName)) { + + let indicatorSpan = headerDiv.querySelector( + '.sort-indicator' + ) as HTMLElement; + if (!indicatorSpan) { + indicatorSpan = document.createElement('span'); + indicatorSpan.classList.add('sort-indicator'); + indicatorSpan.style.paddingLeft = '5px'; + headerDiv.appendChild(indicatorSpan); + } + + const sortIndex = getSortIndex(columnName); + if (sortIndex !== -1) { + const isAscending = currentSortContext[sortIndex].ascending; + indicatorSpan.textContent = isAscending ? '▲' : '▼'; + indicatorSpan.style.visibility = 'visible'; + } else { + indicatorSpan.textContent = '●'; + indicatorSpan.style.visibility = 'hidden'; + } + } + }); + } + + + private initThemeDetection() { + this.updateTheme(); + const observer = new MutationObserver(() => this.updateTheme()); + observer.observe(document.body, { + attributes: true, + attributeFilter: ['class', 'data-theme', 'data-vscode-theme-kind'], + }); + this.themeObserver = observer; + } + + private updateTheme() { + const body = document.body; + const isDark = + body.classList.contains('vscode-dark') || + body.classList.contains('theme-dark') || + body.dataset['theme'] === 'dark' || + body.getAttribute('data-vscode-theme-kind') === 'vscode-dark'; + this.isDarkMode.set(isDark); } } diff --git a/packages/bigframes/bigframes/display/table_widget_angular/src/app/widget-state.service.spec.ts b/packages/bigframes/bigframes/display/table_widget_angular/src/app/widget-state.service.spec.ts new file mode 100644 index 000000000000..3ad922c91048 --- /dev/null +++ b/packages/bigframes/bigframes/display/table_widget_angular/src/app/widget-state.service.spec.ts @@ -0,0 +1,128 @@ +/* + * Copyright 2026 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 { TestBed } from '@angular/core/testing'; +import { vi } from 'vitest'; +import { WidgetStateService } from './widget-state.service'; + +describe('WidgetStateService', () => { + let service: WidgetStateService; + let mockModel: any; + let mockListeners: { [key: string]: Function }; + + beforeEach(() => { + mockListeners = {}; + mockModel = { + get: vi.fn().mockImplementation((prop: string) => { + if (prop === 'page') return 2; + if (prop === 'page_size') return 25; + if (prop === 'max_columns') return 10; + if (prop === 'row_count') return 150; + if (prop === 'table_html') return '
    '; + if (prop === 'sort_context') { + return [{ column: 'col1', ascending: true }]; + } + if (prop === 'orderable_columns') { + return ['col1', 'col2']; + } + if (prop === 'error_message') return 'initial error'; + return null; + }), + set: vi.fn(), + save_changes: vi.fn(), + on: vi.fn().mockImplementation( + (event: string, callback: Function) => { + mockListeners[event] = callback; + } + ) + }; + + TestBed.configureTestingModule({ + providers: [ + { provide: 'ANYWIDGET_MODEL', useValue: mockModel } + ] + }); + service = TestBed.inject(WidgetStateService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); + + it('should initialize signals from model values', () => { + expect(service.page()).toBe(2); + expect(service.pageSize()).toBe(25); + expect(service.maxColumns()).toBe(10); + expect(service.rowCount()).toBe(150); + expect(service.tableHtml()).toBe('
    '); + expect(service.sortContext()).toEqual([ + { column: 'col1', ascending: true } + ]); + expect(service.orderableColumns()).toEqual(['col1', 'col2']); + expect(service.errorMessage()).toBe('initial error'); + }); + + it('should update signals when model triggers change events', () => { + mockModel.get.mockImplementation((prop: string) => { + if (prop === 'page') return 5; + if (prop === 'page_size') return 50; + return null; + }); + + mockListeners['change:page'](); + mockListeners['change:page_size'](); + + expect(service.page()).toBe(5); + expect(service.pageSize()).toBe(50); + }); + + it('should support dual-listen pattern for error messages', () => { + // 1. Check error_message change + mockModel.get.mockImplementation((prop: string) => { + if (prop === 'error_message') return 'new error'; + return null; + }); + mockListeners['change:error_message'](); + expect(service.errorMessage()).toBe('new error'); + + // 2. Check _error_message change + mockModel.get.mockImplementation((prop: string) => { + if (prop === '_error_message') return 'new private error'; + return null; + }); + mockListeners['change:_error_message'](); + expect(service.errorMessage()).toBe('new private error'); + }); + + it('should write updates back to model on setter methods', () => { + service.setPage(4); + expect(mockModel.set).toHaveBeenCalledWith('page', 4); + expect(mockModel.save_changes).toHaveBeenCalled(); + + service.setPageSize(100); + expect(mockModel.set).toHaveBeenCalledWith('page_size', 100); + expect(mockModel.set).toHaveBeenCalledWith('page', 0); + + service.setMaxColumns(15); + expect(mockModel.set).toHaveBeenCalledWith('max_columns', 15); + + service.setSortContext([{ column: 'col2', ascending: false }]); + expect(mockModel.set).toHaveBeenCalledWith( + 'sort_context', + [{ column: 'col2', ascending: false }] + ); + }); +}); diff --git a/packages/bigframes/bigframes/display/table_widget_angular/src/app/widget-state.service.ts b/packages/bigframes/bigframes/display/table_widget_angular/src/app/widget-state.service.ts new file mode 100644 index 000000000000..3ab51e1bdf54 --- /dev/null +++ b/packages/bigframes/bigframes/display/table_widget_angular/src/app/widget-state.service.ts @@ -0,0 +1,123 @@ +/* + * Copyright 2026 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 { Injectable, Inject, signal } from '@angular/core'; + +export interface SortItem { + column: string; + ascending: boolean; +} + +@Injectable({ + providedIn: 'root' +}) +export class WidgetStateService { + readonly page = signal(0); + readonly pageSize = signal(10); + readonly maxColumns = signal(0); + readonly rowCount = signal(null); + readonly tableHtml = signal(''); + readonly sortContext = signal([]); + readonly orderableColumns = signal([]); + readonly errorMessage = signal(null); + + constructor(@Inject('ANYWIDGET_MODEL') private model: any) { + if (model) { + // Initialize from the model + this.page.set(model.get('page') ?? 0); + this.pageSize.set(model.get('page_size') ?? 10); + this.maxColumns.set(model.get('max_columns') ?? 0); + this.rowCount.set(model.get('row_count') ?? null); + this.tableHtml.set(model.get('table_html') ?? ''); + this.sortContext.set(model.get('sort_context') ?? []); + this.orderableColumns.set(model.get('orderable_columns') ?? []); + const initialError = + model.get('error_message') ?? + model.get('_error_message') ?? + null; + this.errorMessage.set(initialError); + + // Register event listeners for anywidget updates + model.on('change:page', () => { + this.page.set(model.get('page')); + }); + model.on('change:page_size', () => { + this.pageSize.set(model.get('page_size')); + }); + model.on('change:max_columns', () => { + this.maxColumns.set(model.get('max_columns')); + }); + model.on('change:row_count', () => { + this.rowCount.set(model.get('row_count')); + }); + model.on('change:table_html', () => { + this.tableHtml.set(model.get('table_html')); + }); + model.on('change:sort_context', () => { + this.sortContext.set(model.get('sort_context')); + }); + model.on('change:orderable_columns', () => { + this.orderableColumns.set(model.get('orderable_columns')); + }); + + // Robust dual-listen pattern for error messages (with/without underscore) + const handleErrorChange = () => { + const err = + model.get('error_message') ?? + model.get('_error_message') ?? + null; + this.errorMessage.set(err); + }; + model.on('change:error_message', handleErrorChange); + model.on('change:_error_message', handleErrorChange); + } + } + + setPage(page: number) { + this.page.set(page); + if (this.model) { + this.model.set('page', page); + this.model.save_changes(); + } + } + + setPageSize(pageSize: number) { + this.pageSize.set(pageSize); + this.page.set(0); + if (this.model) { + this.model.set('page_size', pageSize); + // Reset to page 0 on page size change + this.model.set('page', 0); + this.model.save_changes(); + } + } + + setMaxColumns(maxColumns: number) { + this.maxColumns.set(maxColumns); + if (this.model) { + this.model.set('max_columns', maxColumns); + this.model.save_changes(); + } + } + + setSortContext(context: SortItem[]) { + this.sortContext.set(context); + if (this.model) { + this.model.set('sort_context', context); + this.model.save_changes(); + } + } +} diff --git a/packages/bigframes/bigframes/display/table_widget_angular/src/main.ts b/packages/bigframes/bigframes/display/table_widget_angular/src/main.ts index 42ffdbf0a394..32e4ea202bf2 100644 --- a/packages/bigframes/bigframes/display/table_widget_angular/src/main.ts +++ b/packages/bigframes/bigframes/display/table_widget_angular/src/main.ts @@ -14,9 +14,9 @@ * limitations under the License. */ -import { bootstrapApplication } from '@angular/platform-browser'; +import { createApplication } from '@angular/platform-browser'; import { App } from './app/app'; -import { ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/core'; +import { ApplicationConfig, provideBrowserGlobalErrorListeners, provideZonelessChangeDetection } from '@angular/core'; function render({ model, el }: { model: any, el: HTMLElement }) { // Create a container for the Angular app @@ -26,11 +26,15 @@ function render({ model, el }: { model: any, el: HTMLElement }) { const appConfig: ApplicationConfig = { providers: [ provideBrowserGlobalErrorListeners(), + provideZonelessChangeDetection(), { provide: 'ANYWIDGET_MODEL', useValue: model } ] }; - bootstrapApplication(App, appConfig) + createApplication(appConfig) + .then((appRef) => { + appRef.bootstrap(App, appRoot); + }) .catch((err) => console.error(err)); } diff --git a/packages/bigframes/bigframes/series.py b/packages/bigframes/bigframes/series.py index 181bc4f63b2f..262e1859ab92 100644 --- a/packages/bigframes/bigframes/series.py +++ b/packages/bigframes/bigframes/series.py @@ -595,8 +595,8 @@ def reset_index( block = block.assign_label(self._value_column, name) return bigframes.dataframe.DataFrame(block) - def _get_display_df(self) -> bigframes.dataframe.DataFrame: - return self.to_frame()._get_display_df() + def _prepare_display_df(self) -> bigframes.dataframe.DataFrame: + return self.to_frame()._prepare_display_df() def _repr_mimebundle_(self, include=None, exclude=None): """ diff --git a/packages/bigframes/notebooks/dataframes/anywidget_mode.ipynb b/packages/bigframes/notebooks/dataframes/anywidget_mode.ipynb index 43a57a661063..9cae55b26dc7 100644 --- a/packages/bigframes/notebooks/dataframes/anywidget_mode.ipynb +++ b/packages/bigframes/notebooks/dataframes/anywidget_mode.ipynb @@ -93,7 +93,7 @@ "data": { "text/html": [ "\n", - " Query processed 171.4 MB in 19 seconds of slot time. [Job bigframes-dev:US.04d2a871-4479-4f86-9f9f-48fdd989443c details]\n", + " Query processed 171.4 MB in 19 seconds of slot time. [Job bigframes-dev:US.50efe672-74c6-4292-98d9-520cba9ca516 details]\n", " " ], "text/plain": [ @@ -108,16 +108,16 @@ "output_type": "stream", "text": [ "state gender year name number\n", - " AL F 1910 Vera 71\n", - " AR F 1910 Viola 37\n", - " AR F 1910 Alice 57\n", - " AR F 1910 Edna 95\n", - " AR F 1910 Ollie 40\n", - " CA F 1910 Beatrice 37\n", - " CT F 1910 Marion 36\n", - " CT F 1910 Marie 36\n", - " FL F 1910 Alice 53\n", - " GA F 1910 Thelma 133\n", + " AL F 1910 Annie 482\n", + " AL F 1910 Myrtle 104\n", + " AR F 1910 Lillian 56\n", + " CT F 1910 Anne 38\n", + " CT F 1910 Frances 45\n", + " FL F 1910 Margaret 53\n", + " GA F 1910 Mae 73\n", + " GA F 1910 Beatrice 96\n", + " GA F 1910 Lola 47\n", + " IA F 1910 Viola 49\n", "...\n", "\n", "[5552452 rows x 5 columns]\n" @@ -138,7 +138,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "655a6fe111344246b5996034cf5022f9", + "model_id": "b1080dddbe4140d2b88ef85566e52955", "version_major": 2, "version_minor": 1 }, @@ -174,80 +174,80 @@ " AL\n", " F\n", " 1910\n", - " Hazel\n", - " 51\n", + " Lillian\n", + " 99\n", " \n", " \n", " 1\n", " AL\n", " F\n", " 1910\n", - " Lucy\n", - " 76\n", + " Ruby\n", + " 204\n", " \n", " \n", " 2\n", - " AR\n", + " AL\n", " F\n", " 1910\n", - " Nellie\n", - " 39\n", + " Helen\n", + " 76\n", " \n", " \n", " 3\n", - " AR\n", + " AL\n", " F\n", " 1910\n", - " Lena\n", - " 40\n", + " Eunice\n", + " 41\n", " \n", " \n", " 4\n", - " CO\n", + " AR\n", " F\n", " 1910\n", - " Thelma\n", - " 36\n", + " Dora\n", + " 42\n", " \n", " \n", " 5\n", - " CO\n", + " CA\n", " F\n", " 1910\n", - " Ruth\n", - " 68\n", + " Edna\n", + " 62\n", " \n", " \n", " 6\n", - " CT\n", + " CA\n", " F\n", " 1910\n", - " Elizabeth\n", - " 86\n", + " Helen\n", + " 239\n", " \n", " \n", " 7\n", - " DC\n", + " CO\n", " F\n", " 1910\n", - " Mary\n", - " 80\n", + " Alice\n", + " 46\n", " \n", " \n", " 8\n", " FL\n", " F\n", " 1910\n", - " Annie\n", - " 101\n", + " Willie\n", + " 71\n", " \n", " \n", " 9\n", " FL\n", " F\n", " 1910\n", - " Alma\n", - " 39\n", + " Thelma\n", + " 65\n", " \n", " \n", "\n", @@ -255,17 +255,17 @@ "
    [5552452 rows x 5 columns in total]" ], "text/plain": [ - "state gender year name number\n", - " AL F 1910 Hazel 51\n", - " AL F 1910 Lucy 76\n", - " AR F 1910 Nellie 39\n", - " AR F 1910 Lena 40\n", - " CO F 1910 Thelma 36\n", - " CO F 1910 Ruth 68\n", - " CT F 1910 Elizabeth 86\n", - " DC F 1910 Mary 80\n", - " FL F 1910 Annie 101\n", - " FL F 1910 Alma 39\n", + "state gender year name number\n", + " AL F 1910 Lillian 99\n", + " AL F 1910 Ruby 204\n", + " AL F 1910 Helen 76\n", + " AL F 1910 Eunice 41\n", + " AR F 1910 Dora 42\n", + " CA F 1910 Edna 62\n", + " CA F 1910 Helen 239\n", + " CO F 1910 Alice 46\n", + " FL F 1910 Willie 71\n", + " FL F 1910 Thelma 65\n", "...\n", "\n", "[5552452 rows x 5 columns]" @@ -313,16 +313,16 @@ "name": "stdout", "output_type": "stream", "text": [ - "2009\n", - "2006\n", - "1996\n", - "1970\n", "1967\n", "1981\n", - "2002\n", - "2000\n", - "1997\n", - "1987\n", + "2009\n", + "1956\n", + "1960\n", + "2001\n", + "2009\n", + "2003\n", + "1985\n", + "1993\n", "Name: year, dtype: Int64\n", "...\n", "\n", @@ -353,33 +353,33 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "30da7d0885a6484dae0ae55a6c7d50fd", + "model_id": "46e836f10d9e47afb4d82b5c7da69660", "version_major": 2, "version_minor": 1 }, "text/html": [ - "
    0    1912\n",
    +       "
    0    1910\n",
            "1    1912\n",
    -       "2    1911\n",
    -       "3    1913\n",
    -       "4    1910\n",
    -       "5    1911\n",
    -       "6    1911\n",
    -       "7    1913\n",
    -       "8    1910\n",
    -       "9    1911

    [5552452 rows]

    " + "2 1912\n", + "3 1911\n", + "4 1912\n", + "5 1910\n", + "6 1913\n", + "7 1912\n", + "8 1913\n", + "9 1913

    [5552452 rows]

    " ], "text/plain": [ + "1910\n", "1912\n", "1912\n", "1911\n", - "1913\n", + "1912\n", "1910\n", - "1911\n", - "1911\n", "1913\n", - "1910\n", - "1911\n", + "1912\n", + "1913\n", + "1913\n", "Name: year, dtype: Int64\n", "...\n", "\n", @@ -461,12 +461,12 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "80709d6d43b64d04b598295f36b167fd", + "model_id": "6e5f603b56fb408bb1ea41519ea8702e", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "execution_count": 8, @@ -475,9 +475,10 @@ } ], "source": [ - "from bigframes.display.anywidget import TableWidget\n", "import math\n", - " \n", + "\n", + "from bigframes.display.anywidget import TableWidget\n", + "\n", "# Create widget programmatically \n", "widget = TableWidget(df)\n", "print(f\"Total pages: {math.ceil(widget.row_count / widget.page_size)}\")\n", @@ -548,12 +549,12 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "651ca38349134d84995c062419c79c0c", + "model_id": "20c94621c4ae4eb5a94fd3596ae8c236", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "execution_count": 10, @@ -597,7 +598,7 @@ "data": { "text/html": [ "\n", - " Query processed 85.9 kB in 34 seconds of slot time. [Job bigframes-dev:US.job_jR3UJwXJNbBAasEynvKKzuHxU684 details]\n", + " Query processed 0 Bytes in a moment of slot time. [Job bigframes-dev:US.job_cpfa9oehjApkQgrbTrKRxTpEtuQX details]\n", " " ], "text/plain": [ @@ -610,7 +611,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "e58b6bbb7c034c11bf4dc602bb080551", + "model_id": "d5bf0a9438954c6890b5d8cd16bff7cd", "version_major": 2, "version_minor": 1 }, @@ -653,6 +654,24 @@ " \n", " \n", " 0\n", + " {\"application_number\":\"18157874.1\",\"class_inte...\n", + " gs://gcs-public-data--labeled-patents/espacene...\n", + " EU\n", + " DE\n", + " 29.08.018\n", + " E04H 6/12\n", + " <NA>\n", + " 18157874.1\n", + " 21.02.2018\n", + " 22.02.2017\n", + " Liedtke & Partner Patentanwälte\n", + " SHB Hebezeugbau GmbH\n", + " VOLGER, Alexander\n", + " STEUERUNGSSYSTEM FÜR AUTOMATISCHE PARKHÄUSER\n", + " EP 3 366 869 A1\n", + " \n", + " \n", + " 1\n", " {\"application_number\":\"18165514.3\",\"class_inte...\n", " gs://gcs-public-data--labeled-patents/espacene...\n", " EU\n", @@ -670,7 +689,7 @@ " EP 3 383 141 A2\n", " \n", " \n", - " 1\n", + " 2\n", " {\"application_number\":\"18157347.8\",\"class_inte...\n", " gs://gcs-public-data--labeled-patents/espacene...\n", " EU\n", @@ -688,7 +707,7 @@ " EP 3 382 553 A1\n", " \n", " \n", - " 2\n", + " 3\n", " {\"application_number\":\"18166536.5\",\"class_inte...\n", " gs://gcs-public-data--labeled-patents/espacene...\n", " EU\n", @@ -706,7 +725,7 @@ " EP 3 382 744 A1\n", " \n", " \n", - " 3\n", + " 4\n", " {\"application_number\":\"18171005.4\",\"class_inte...\n", " gs://gcs-public-data--labeled-patents/espacene...\n", " EU\n", @@ -723,24 +742,6 @@ " MASTHÄHNCHENCONTAINER ALS BESTANDTEIL EINER E...\n", " EP 3 381 276 A1\n", " \n", - " \n", - " 4\n", - " {\"application_number\":\"18157874.1\",\"class_inte...\n", - " gs://gcs-public-data--labeled-patents/espacene...\n", - " EU\n", - " DE\n", - " 29.08.018\n", - " E04H 6/12\n", - " <NA>\n", - " 18157874.1\n", - " 21.02.2018\n", - " 22.02.2017\n", - " Liedtke & Partner Patentanwälte\n", - " SHB Hebezeugbau GmbH\n", - " VOLGER, Alexander\n", - " STEUERUNGSSYSTEM FÜR AUTOMATISCHE PARKHÄUSER\n", - " EP 3 366 869 A1\n", - " \n", " \n", "\n", "

    5 rows × 15 columns

    \n", @@ -748,11 +749,11 @@ ], "text/plain": [ " result \\\n", + "{\"application_number\":\"18157874.1\",\"class_inter... \n", "{\"application_number\":\"18165514.3\",\"class_inter... \n", "{\"application_number\":\"18157347.8\",\"class_inter... \n", "{\"application_number\":\"18166536.5\",\"class_inter... \n", "{\"application_number\":\"18171005.4\",\"class_inter... \n", - "{\"application_number\":\"18157874.1\",\"class_inter... \n", "\n", " gcs_path issuer language \\\n", "gs://gcs-public-data--labeled-patents/espacenet... EU DE \n", @@ -762,32 +763,32 @@ "gs://gcs-public-data--labeled-patents/espacenet... EU DE \n", "\n", "publication_date class_international class_us application_number filing_date \\\n", + " 29.08.018 E04H 6/12 18157874.1 21.02.2018 \n", " 03.10.2018 H05B 6/12 18165514.3 03.04.2018 \n", " 03.10.2018 G06F 11/30 18157347.8 19.02.2018 \n", " 03.10.2018 H01L 21/20 18166536.5 16.02.2016 \n", " 03.10.2018 A01K 31/00 18171005.4 05.02.2015 \n", - " 29.08.018 E04H 6/12 18157874.1 21.02.2018 \n", "\n", "priority_date_eu representative_line_1_eu applicant_line_1 \\\n", + " 22.02.2017 Liedtke & Partner Patentanwälte SHB Hebezeugbau GmbH \n", " 30.03.2017 BSH Hausgeräte GmbH \n", " 31.03.2017 Hoffmann Eitle FUJITSU LIMITED \n", " Scheider, Sascha et al EV Group E. Thallner GmbH \n", " 05.02.2014 Stork Bamberger Patentanwälte Linco Food Systems A/S \n", - " 22.02.2017 Liedtke & Partner Patentanwälte SHB Hebezeugbau GmbH \n", "\n", " inventor_line_1 title_line_1 \\\n", + " VOLGER, Alexander STEUERUNGSSYSTEM FÜR AUTOMATISCHE PARKHÄUSER \n", "Acero Acero, Jesus VORRICHTUNG ZUR INDUKTIVEN ENERGIEÜBERTRAGUNG \n", " Kukihara, Kensuke METHOD EXECUTED BY A COMPUTER, INFORMATION PROC... \n", " Kurz, Florian VORRICHTUNG ZUM BONDEN VON SUBSTRATEN \n", " Thrane, Uffe MASTHÄHNCHENCONTAINER ALS BESTANDTEIL EINER EI... \n", - " VOLGER, Alexander STEUERUNGSSYSTEM FÜR AUTOMATISCHE PARKHÄUSER \n", "\n", " number \n", + "EP 3 366 869 A1 \n", "EP 3 383 141 A2 \n", "EP 3 382 553 A1 \n", "EP 3 382 744 A1 \n", "EP 3 381 276 A1 \n", - "EP 3 366 869 A1 \n", "\n", "[5 rows x 15 columns]" ] diff --git a/packages/bigframes/tests/js/table_widget_angular.test.js b/packages/bigframes/tests/js/table_widget_angular.test.js new file mode 100644 index 000000000000..62af3cb26dc6 --- /dev/null +++ b/packages/bigframes/tests/js/table_widget_angular.test.js @@ -0,0 +1,96 @@ +/* + * Copyright 2026 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 { jest } from '@jest/globals'; + +describe('TableWidgetAngular', () => { + let render; + + beforeEach(async () => { + jest.resetModules(); + const tableWidgetAngular = ( + await import('../../bigframes/display/table_widget_angular.js') + ).default; + render = tableWidgetAngular.render; + }); + + it('should have a render function', () => { + expect(render).toBeDefined(); + }); + + it( + 'should bootstrap multiple widgets independently on their respective elements', + async () => { + const el1 = document.createElement('div'); + document.body.appendChild(el1); + + const model1 = { + get: jest.fn((prop) => { + if (prop === 'table_html') { + return '
    Widget 1 Content
    '; + } + if (prop === 'page_size') return 10; + if (prop === 'page') return 0; + if (prop === 'row_count') return 100; + if (prop === 'max_columns') return 20; + return null; + }), + set: jest.fn(), + save_changes: jest.fn(), + on: jest.fn(), + }; + + const el2 = document.createElement('div'); + document.body.appendChild(el2); + + const model2 = { + get: jest.fn((prop) => { + if (prop === 'table_html') { + return '
    Widget 2 Content
    '; + } + if (prop === 'page_size') return 25; + if (prop === 'page') return 0; + if (prop === 'row_count') return 200; + if (prop === 'max_columns') return 20; + return null; + }), + set: jest.fn(), + save_changes: jest.fn(), + on: jest.fn(), + }; + + render({ model: model1, el: el1 }); + render({ model: model2, el: el2 }); + + // Wait for async angular bootstrap to complete + await new Promise((resolve) => setTimeout(resolve, 200)); + + const appRoot1 = el1.querySelector('app-root'); + expect(appRoot1).not.toBeNull(); + expect(el1.textContent).toContain('Widget 1 Content'); + expect(el1.textContent).toContain('100 total rows'); + expect(el1.textContent).toContain('Page 1 of 10'); + + const appRoot2 = el2.querySelector('app-root'); + expect(appRoot2).not.toBeNull(); + expect(el2.textContent).toContain('Widget 2 Content'); + expect(el2.textContent).toContain('200 total rows'); + expect(el2.textContent).toContain('Page 1 of 8'); + + document.body.removeChild(el1); + document.body.removeChild(el2); + }); +}); diff --git a/packages/bigframes/tests/unit/display/test_anywidget.py b/packages/bigframes/tests/unit/display/test_anywidget.py index 0b9afb5645f2..acdbf182b133 100644 --- a/packages/bigframes/tests/unit/display/test_anywidget.py +++ b/packages/bigframes/tests/unit/display/test_anywidget.py @@ -206,7 +206,7 @@ def test_json_column_converted_to_string_for_display(): with mock.patch.object(DataFrame, "__getitem__", return_value=mock_series): with mock.patch.object(DataFrame, "assign") as mock_assign: - df._get_display_df() + df._prepare_display_df() mock_assign.assert_called_once() _, kwargs = mock_assign.call_args @@ -236,7 +236,7 @@ def test_struct_column_with_nested_json_converted_to_string_for_display(): with mock.patch.object(DataFrame, "__getitem__", return_value=mock_series): with mock.patch.object(DataFrame, "assign") as mock_assign: - df._get_display_df() + df._prepare_display_df() mock_assign.assert_called_once() _, kwargs = mock_assign.call_args diff --git a/packages/bigframes/tests/unit/display/test_html.py b/packages/bigframes/tests/unit/display/test_html.py index 97aead4c82db..9386dad8b1ff 100644 --- a/packages/bigframes/tests/unit/display/test_html.py +++ b/packages/bigframes/tests/unit/display/test_html.py @@ -192,7 +192,7 @@ def test_repr_mimebundle_head(): mock_df = Mock() mock_df.columns = ["col1"] - mock_df._get_display_df.return_value = mock_df + mock_df._prepare_display_df.return_value = mock_df # Mock the call to retrieve_repr_request_results pandas_df = pd.DataFrame({"col1": [1, 2, 3]}) @@ -215,7 +215,7 @@ def test_repr_mimebundle_head(): bundle = bf_html.repr_mimebundle_head(mock_df) assert bundle == {"text/html": "", "text/plain": "text"} - mock_df._get_display_df.assert_called_once() + mock_df._prepare_display_df.assert_called_once() mock_df._block.retrieve_repr_request_results.assert_called_once() mock_create_html.assert_called_once() mock_create_text.assert_called_once() From 0d2d40ddd3f2a60dc37717a77469b4a562c04df5 Mon Sep 17 00:00:00 2001 From: Chalmer Lowe Date: Tue, 16 Jun 2026 20:45:09 -0400 Subject: [PATCH 089/174] feat(version-scanner): refine python version checks and document boundary logic (#17477) This pull request refines the regex rules configuration used by the dependency version scanner. It improves Python runtime version boundary checking and documents the intent behind boundary offsets. Key changes: - Refines `python_requires` checks to support optional patch versions (e.g., matching `>=3.7.0`). - Adds subscript-based minor version checks (e.g., `sys.version_info[1] >= 7`). - Adds inline YAML comments to document the `+1` and `-1` offset logic for external reviewers and auditors. --- scripts/version_scanner/regex_config.yaml | 46 ++++++++++++-- .../tests/unit/test_version_scanner.py | 60 ++++++++++++++++++- 2 files changed, 99 insertions(+), 7 deletions(-) diff --git a/scripts/version_scanner/regex_config.yaml b/scripts/version_scanner/regex_config.yaml index 95e62fe002aa..c88696016bfc 100644 --- a/scripts/version_scanner/regex_config.yaml +++ b/scripts/version_scanner/regex_config.yaml @@ -17,20 +17,23 @@ rules: examples: - "python_requires = '==3.7'" - "python_requires = '>=3.7'" + - "python_requires = '>=3.7.0'" - "python_requires = '<=3.7'" - "python_requires = '>3.6'" - "python_requires = '<3.8'" rules: - | - python_requires\s*=\s*['"]==3\.{minor}['"] + python_requires\s*=\s*['"]==3\.{minor}(?:\.\d+)?['"] - | - python_requires\s*=\s*['"]>=3\.{minor}['"] + python_requires\s*=\s*['"]>=3\.{minor}(?:\.0)?['"] - | - python_requires\s*=\s*['"]<=3\.{minor}['"] + python_requires\s*=\s*['"]<=3\.{minor}(?:\.0)?['"] + # Matches >3.6 (equivalent to >=3.7) - | - python_requires\s*=\s*['"]>3\.{minor_minus_one}['"] + python_requires\s*=\s*['"]>3\.{minor_minus_one}(?:\.0)?['"] + # Matches <3.8 (equivalent to <=3.7) - | - python_requires\s*=\s*['"]<3\.{minor_plus_one}['"] + python_requires\s*=\s*['"]<3\.{minor_plus_one}(?:\.0)?['"] - name: sys_version_info description: Finds sys.version_info checks in code. @@ -46,6 +49,11 @@ rules: - "sys.version_info.minor <= 7" - "sys.version_info.minor > 6" - "sys.version_info.minor < 8" + - "sys.version_info[1] == 7" + - "sys.version_info[1] >= 7" + - "sys.version_info[1] <= 7" + - "sys.version_info[1] > 6" + - "sys.version_info[1] < 8" rules: - | sys\.version_info\s*==\s*\(3,\s*{minor}\) @@ -53,8 +61,10 @@ rules: sys\.version_info\s*>=\s*\(3,\s*{minor}\) - | sys\.version_info\s*<=\s*\(3,\s*{minor}\) + # Matches sys.version_info > (3, 6) (equivalent to >=3.7) - | sys\.version_info\s*>\s*\(3,\s*{minor_minus_one}\) + # Matches sys.version_info < (3, 8) (equivalent to <=3.7) - | sys\.version_info\s*<\s*\(3,\s*{minor_plus_one}\) - | @@ -63,10 +73,24 @@ rules: sys\.version_info\.minor\s*>=\s*{minor}(?!\d) - | sys\.version_info\.minor\s*<=\s*{minor}(?!\d) + # Matches sys.version_info.minor > 6 (equivalent to >=7) - | sys\.version_info\.minor\s*>\s*{minor_minus_one}(?!\d) + # Matches sys.version_info.minor < 8 (equivalent to <=7) - | sys\.version_info\.minor\s*<\s*{minor_plus_one}(?!\d) + - | + sys\.version_info\[\s*1\s*\]\s*==\s*{minor}(?!\d) + - | + sys\.version_info\[\s*1\s*\]\s*>=\s*{minor}(?!\d) + - | + sys\.version_info\[\s*1\s*\]\s*<=\s*{minor}(?!\d) + # Matches sys.version_info[1] > 6 (equivalent to >=7) + - | + sys\.version_info\[\s*1\s*\]\s*>\s*{minor_minus_one}(?!\d) + # Matches sys.version_info[1] < 8 (equivalent to <=7) + - | + sys\.version_info\[\s*1\s*\]\s*<\s*{minor_plus_one}(?!\d) - name: python_env_short description: Finds short python environment names often used in tox or nox. @@ -99,4 +123,16 @@ rules: - | Python{major}{minor}(?!\d) + - name: dependency_requirement + description: Finds standard dependency requirement formats (e.g., protobuf==3.7). + examples: + - "protobuf==3.7" + - "protobuf>=3.7" + - "protobuf<=3.7" + - "protobuf~=3.7" + - "protobuf!=3.7" + rules: + - | + {name}\s*(?:==|>=|<=|~=|!=)\s*{version}(?!\d) + diff --git a/scripts/version_scanner/tests/unit/test_version_scanner.py b/scripts/version_scanner/tests/unit/test_version_scanner.py index f887dfc12fd4..f76b66d4d55d 100644 --- a/scripts/version_scanner/tests/unit/test_version_scanner.py +++ b/scripts/version_scanner/tests/unit/test_version_scanner.py @@ -410,8 +410,8 @@ def test_regex_examples_from_config(): rules_list = config.get("rules", []) - # Variables for interpolation (simulate Python 3.7) - vars = { + # Base variables for interpolation (simulate target version 3.7) + base_vars = { "major": "3", "minor": "7", "version": "3.7", @@ -427,6 +427,11 @@ def test_regex_examples_from_config(): if not examples or not templates: continue + # Resolve target dependency name based on applies_to metadata, falling back to protobuf + applies_to = rule_group.get("applies_to", []) + dep_name = applies_to[0] if applies_to else "protobuf" + vars = {**base_vars, "name": dep_name} + compiled_patterns = [] for template in templates: try: @@ -443,6 +448,57 @@ def test_regex_examples_from_config(): break assert matched, f"Example '{example}' in group '{name}' did not match any pattern." + +def test_regex_negative_cases(): + """Verify regex patterns prevent false positives (lookaheads, patch bounds) and support whitespace.""" + config_path = "regex_config.yaml" + with open(config_path, 'r') as f: + config = yaml.safe_load(f) + + rules_list = config.get("rules", []) + + # Target version 3.7 + vars = { + "name": "protobuf", + "major": "3", + "minor": "7", + "version": "3.7", + "minor_plus_one": "8", + "minor_minus_one": "6" + } + + # Find specific rule groups + dep_req_group = next(r for r in rules_list if r["name"] == "dependency_requirement") + python_cmd_group = next(r for r in rules_list if r["name"] == "explicit_python_command") + python_req_group = next(r for r in rules_list if r["name"] == "python_requires") + sys_info_group = next(r for r in rules_list if r["name"] == "sys_version_info") + + # 1. Verify dependency_requirement looks ahead correctly (no partial match) + dep_pattern = re.compile(dep_req_group["rules"][0].strip().format(**vars), re.IGNORECASE) + assert dep_pattern.search("protobuf==3.7") + assert not dep_pattern.search("protobuf==3.72") + + # 2. Verify explicit_python_command negative lookahead + cmd_pattern = re.compile(python_cmd_group["rules"][0].strip().format(**vars), re.IGNORECASE) + assert cmd_pattern.search("python3.7") + assert not cmd_pattern.search("python3.72") + + # 3. Verify python_requires optional patch limits boundary rules to .0 + # Boundary rule 1: >=3.7 (python_requires = '>=3.7.0' is OK, but >=3.7.1 is not equivalent and should be skipped) + req_ge_pattern = re.compile(python_req_group["rules"][1].strip().format(**vars), re.IGNORECASE) + assert req_ge_pattern.search("python_requires = '>=3.7'") + assert req_ge_pattern.search("python_requires = '>=3.7.0'") + assert not req_ge_pattern.search("python_requires = '>=3.7.1'") + + # 4. Verify sys_version_info[1] allows optional whitespace + # Matches sys.version_info[ 1 ] + sys_sub_pattern = re.compile(sys_info_group["rules"][10].strip().format(**vars), re.IGNORECASE) # sys.version_info[1] == 7 + assert sys_sub_pattern.search("sys.version_info[1] == 7") + assert sys_sub_pattern.search("sys.version_info[ 1 ] == 7") + assert sys_sub_pattern.search("sys.version_info[1 ] == 7") + assert sys_sub_pattern.search("sys.version_info[ 1] == 7") + + def test_main_exit_code_1(): """Test that main() calls sys.exit(1) when matches are found.""" # We can mock scan_repository to return a dummy match From f119dc29348a71372c582e7b6ff84c3a478adf8d Mon Sep 17 00:00:00 2001 From: Chalmer Lowe Date: Wed, 17 Jun 2026 12:08:35 -0400 Subject: [PATCH 090/174] refactor(pubsub): remove EOL Python 3.7/3.8/3.9 false positives and compatibility checks (#17485) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since `google-cloud-pubsub` requires Python >= 3.10, this PR cleans up obsolete compatibility checks, warnings, and pytest skip conditions targeting Python 3.7, 3.8, and 3.9. Why this is needed: * Simplifies the codebase by removing dead compatibility blocks and checks that are always true under Python >= 3.10. * Cleans up EOL warnings and deprecated import workarounds that are no longer relevant to current runtimes. * Cleans up unit test decorators to run all OpenTelemetry tests unconditionally. * Supports clean up efforts to eliminate false positives as found by the version_scanner. 🦕 --- packages/google-cloud-pubsub/CONTRIBUTING.rst | 16 +--- packages/google-cloud-pubsub/README.rst | 4 - .../cloud/pubsub_v1/publisher/client.py | 13 ---- .../pubsub_v1/subscriber/_protocol/leaser.py | 8 +- .../cloud/pubsub_v1/subscriber/client.py | 13 ---- .../cloud/pubsub_v1/subscriber/scheduler.py | 5 -- packages/google-cloud-pubsub/pytest.ini | 2 - packages/google-cloud-pubsub/tests/system.py | 21 +++++- .../tests/unit/pubsub_v1/conftest.py | 18 ++++- .../pubsub_v1/publisher/batch/test_thread.py | 13 ---- .../publisher/test_publisher_client.py | 74 +++++++------------ .../pubsub_v1/subscriber/test_dispatcher.py | 17 ----- .../subscriber/test_streaming_pull_manager.py | 9 --- .../subscriber/test_subscriber_client.py | 16 +--- .../tests/unit/pubsub_v1/test_futures.py | 9 --- 15 files changed, 69 insertions(+), 169 deletions(-) diff --git a/packages/google-cloud-pubsub/CONTRIBUTING.rst b/packages/google-cloud-pubsub/CONTRIBUTING.rst index 4e926536bf26..3aff2258e23c 100644 --- a/packages/google-cloud-pubsub/CONTRIBUTING.rst +++ b/packages/google-cloud-pubsub/CONTRIBUTING.rst @@ -22,7 +22,7 @@ In order to add a feature: documentation. - The feature must work fully on the following CPython versions: - 3.9, 3.10, 3.11, 3.12, 3.13 and 3.14 on both UNIX and Windows. + 3.10, 3.11, 3.12, 3.13 and 3.14 on both UNIX and Windows. - The feature must not add unnecessary dependencies (where "unnecessary" is of course subjective, but new dependencies should @@ -221,14 +221,12 @@ Supported Python Versions We support: -- `Python 3.9`_ - `Python 3.10`_ - `Python 3.11`_ - `Python 3.12`_ - `Python 3.13`_ - `Python 3.14`_ -.. _Python 3.9: https://docs.python.org/3.9/ .. _Python 3.10: https://docs.python.org/3.10/ .. _Python 3.11: https://docs.python.org/3.11/ .. _Python 3.12: https://docs.python.org/3.12/ @@ -241,18 +239,6 @@ Supported versions can be found in our ``noxfile.py`` `config`_. .. _config: https://github.com/googleapis/python-pubsub/blob/main/noxfile.py -We also explicitly decided to support Python 3 beginning with version 3.7. -Reasons for this include: - -- Encouraging use of newest versions of Python 3 -- Taking the lead of `prominent`_ open-source `projects`_ -- `Unicode literal support`_ which allows for a cleaner codebase that - works in both Python 2 and Python 3 - -.. _prominent: https://docs.djangoproject.com/en/1.9/faq/install/#what-python-version-can-i-use-with-django -.. _projects: http://flask.pocoo.org/docs/0.10/python3/ -.. _Unicode literal support: https://www.python.org/dev/peps/pep-0414/ - ********** Versioning ********** diff --git a/packages/google-cloud-pubsub/README.rst b/packages/google-cloud-pubsub/README.rst index 7717a22044c4..3fe8a71491f0 100644 --- a/packages/google-cloud-pubsub/README.rst +++ b/packages/google-cloud-pubsub/README.rst @@ -67,10 +67,6 @@ Python >= 3.10, including 3.14 .. _active: https://devguide.python.org/devcycle/#in-development-main-branch .. _maintenance: https://devguide.python.org/devcycle/#maintenance-branches -Unsupported Python Versions -^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Python <= 3.9 - If you are using an `end-of-life`_ version of Python, we recommend that you update as soon as possible to an actively supported version. diff --git a/packages/google-cloud-pubsub/google/cloud/pubsub_v1/publisher/client.py b/packages/google-cloud-pubsub/google/cloud/pubsub_v1/publisher/client.py index eb7cb6511638..d821b7e5c524 100644 --- a/packages/google-cloud-pubsub/google/cloud/pubsub_v1/publisher/client.py +++ b/packages/google-cloud-pubsub/google/cloud/pubsub_v1/publisher/client.py @@ -17,7 +17,6 @@ import copy import logging import os -import sys import threading import time import typing @@ -165,18 +164,6 @@ def __init__( self._open_telemetry_enabled = ( self.publisher_options.enable_open_telemetry_tracing ) - # OpenTelemetry features used by the library are not supported in Python versions <= 3.7. - # Refer https://github.com/open-telemetry/opentelemetry-python/issues/3993#issuecomment-2211976389 - if ( - self.publisher_options.enable_open_telemetry_tracing - and sys.version_info.major == 3 - and sys.version_info.minor < 8 - ): - warnings.warn( - message="Open Telemetry for Python version 3.7 or lower is not supported. Disabling Open Telemetry tracing.", - category=RuntimeWarning, - ) - self._open_telemetry_enabled = False @classmethod def from_service_account_file( # type: ignore[override] diff --git a/packages/google-cloud-pubsub/google/cloud/pubsub_v1/subscriber/_protocol/leaser.py b/packages/google-cloud-pubsub/google/cloud/pubsub_v1/subscriber/_protocol/leaser.py index 879dcc4faef3..1e241d21d81d 100644 --- a/packages/google-cloud-pubsub/google/cloud/pubsub_v1/subscriber/_protocol/leaser.py +++ b/packages/google-cloud-pubsub/google/cloud/pubsub_v1/subscriber/_protocol/leaser.py @@ -27,13 +27,7 @@ ) from google.cloud.pubsub_v1.subscriber._protocol.dispatcher import _MAX_BATCH_LATENCY -try: - from collections.abc import KeysView - - KeysView[None] # KeysView is only subscriptable in Python 3.9+ -except TypeError: - # Deprecated since Python 3.9, thus only use as a fallback in older Python versions - from typing import KeysView +from collections.abc import KeysView from google.cloud.pubsub_v1.subscriber._protocol import requests diff --git a/packages/google-cloud-pubsub/google/cloud/pubsub_v1/subscriber/client.py b/packages/google-cloud-pubsub/google/cloud/pubsub_v1/subscriber/client.py index 3131a09c4744..7591af028403 100644 --- a/packages/google-cloud-pubsub/google/cloud/pubsub_v1/subscriber/client.py +++ b/packages/google-cloud-pubsub/google/cloud/pubsub_v1/subscriber/client.py @@ -15,7 +15,6 @@ from __future__ import absolute_import import os -import sys import typing import warnings from typing import Any, Callable, Optional, Sequence, Union, cast @@ -102,18 +101,6 @@ def __init__( self._open_telemetry_enabled = ( self.subscriber_options.enable_open_telemetry_tracing ) - # OpenTelemetry features used by the library are not supported in Python versions <= 3.7. - # Refer https://github.com/open-telemetry/opentelemetry-python/issues/3993#issuecomment-2211976389 - if ( - self.subscriber_options.enable_open_telemetry_tracing - and sys.version_info.major == 3 - and sys.version_info.minor < 8 - ): - warnings.warn( - message="Open Telemetry for Python version 3.7 or lower is not supported. Disabling Open Telemetry tracing.", - category=RuntimeWarning, - ) - self._open_telemetry_enabled = False @property def open_telemetry_enabled(self) -> bool: diff --git a/packages/google-cloud-pubsub/google/cloud/pubsub_v1/subscriber/scheduler.py b/packages/google-cloud-pubsub/google/cloud/pubsub_v1/subscriber/scheduler.py index 269027cfbc82..80aea1dcdf41 100644 --- a/packages/google-cloud-pubsub/google/cloud/pubsub_v1/subscriber/scheduler.py +++ b/packages/google-cloud-pubsub/google/cloud/pubsub_v1/subscriber/scheduler.py @@ -153,11 +153,6 @@ def shutdown( """ dropped_messages = [] - # Drop all pending item from the executor. Without this, the executor will also - # try to process any pending work items before termination, which is undesirable. - # - # TODO: Replace the logic below by passing `cancel_futures=True` to shutdown() - # once we only need to support Python 3.9+. try: while True: work_item = self._executor._work_queue.get(block=False) diff --git a/packages/google-cloud-pubsub/pytest.ini b/packages/google-cloud-pubsub/pytest.ini index af45389fdac8..571c4709ea25 100644 --- a/packages/google-cloud-pubsub/pytest.ini +++ b/packages/google-cloud-pubsub/pytest.ini @@ -16,8 +16,6 @@ filterwarnings = # Remove once the minimum supported version of googleapis-common-protos is 1.62.0 ignore:.*pkg_resources.declare_namespace:DeprecationWarning ignore:.*pkg_resources is deprecated as an API:DeprecationWarning - # Remove once https://github.com/googleapis/gapic-generator-python/issues/2303 is fixed - ignore:The python-bigquery library will stop supporting Python 3.7:PendingDeprecationWarning # Remove once we move off credential files https://github.com/googleapis/google-auth-library-python/pull/1812 # Note that these are used in tests only ignore:Your config file at [/home/kbuilder/.docker/config.json] contains these credential helper entries:DeprecationWarning diff --git a/packages/google-cloud-pubsub/tests/system.py b/packages/google-cloud-pubsub/tests/system.py index 1a57b3aa7439..cfbc71202e7f 100644 --- a/packages/google-cloud-pubsub/tests/system.py +++ b/packages/google-cloud-pubsub/tests/system.py @@ -447,11 +447,19 @@ def test_subscriber_not_leaking_open_sockets( subscriber = pubsub_v1.SubscriberClient(transport="grpc") subscriber_2 = pubsub_v1.SubscriberClient(transport="grpc") + # Construct a secondary publisher client to clean up the topic, + # so we can safely close the main publisher client inside the test. + if "Rest" in type(publisher._transport).__name__: + publisher_2 = pubsub_v1.PublisherClient(transport="rest") + else: + publisher_2 = pubsub_v1.PublisherClient(transport="grpc") + cleanup.append( (subscriber_2.delete_subscription, (), {"subscription": subscription_path}) ) cleanup.append((subscriber_2.close, (), {})) - cleanup.append((publisher.delete_topic, (), {"topic": topic_path})) + cleanup.append((publisher_2.delete_topic, (), {"topic": topic_path})) + cleanup.append((publisher_2._transport.close, (), {})) # Create topic before starting to track connection count (any sockets opened # by the publisher client are not counted by this test). @@ -477,7 +485,16 @@ def test_subscriber_not_leaking_open_sockets( response = subscriber.pull(subscription=subscription_path, max_messages=3) assert len(response.received_messages) == 3 - conn_count_end = len(current_process.net_connections()) + # Close the publisher client's transport used in the test to ensure all its socket connections + # (including any opened asynchronously on the background publisher threads) are closed. + publisher._transport.close() + + # Wait a bit for the asynchronous channel teardown to complete and the socket to be closed. + for _ in range(30): + conn_count_end = len(current_process.net_connections()) + if conn_count_end <= conn_count_start: + break + time.sleep(0.1) # To avoid flakiness, use <= in the assertion, since on rare occasions additional # sockets are closed, causing the == assertion to fail. diff --git a/packages/google-cloud-pubsub/tests/unit/pubsub_v1/conftest.py b/packages/google-cloud-pubsub/tests/unit/pubsub_v1/conftest.py index 3c72d293da4b..3bc2420583ff 100644 --- a/packages/google-cloud-pubsub/tests/unit/pubsub_v1/conftest.py +++ b/packages/google-cloud-pubsub/tests/unit/pubsub_v1/conftest.py @@ -39,11 +39,27 @@ def set_trace_provider(): @pytest.fixture(scope="function") def span_exporter(): + """Provides an InMemorySpanExporter for testing OpenTelemetry traces. + + Registers a SimpleSpanProcessor with the global TracerProvider at start, + and removes it during teardown to prevent trace/span processor accumulation + and test pollution across tests. + """ exporter = InMemorySpanExporter() processor = SimpleSpanProcessor(exporter) provider = trace.get_tracer_provider() provider.add_span_processor(processor) - yield exporter + try: + yield exporter + finally: + if hasattr(provider, "_active_span_processor") and hasattr( + provider._active_span_processor, "_span_processors" + ): + processors = provider._active_span_processor._span_processors + if isinstance(processors, tuple): + provider._active_span_processor._span_processors = tuple( + p for p in processors if p is not processor + ) @pytest.fixture() diff --git a/packages/google-cloud-pubsub/tests/unit/pubsub_v1/publisher/batch/test_thread.py b/packages/google-cloud-pubsub/tests/unit/pubsub_v1/publisher/batch/test_thread.py index 25d5ae6fc9b7..72b30a9ad139 100644 --- a/packages/google-cloud-pubsub/tests/unit/pubsub_v1/publisher/batch/test_thread.py +++ b/packages/google-cloud-pubsub/tests/unit/pubsub_v1/publisher/batch/test_thread.py @@ -13,7 +13,6 @@ # limitations under the License. import datetime -import sys import threading import time from unittest import mock @@ -723,9 +722,6 @@ def test_batch_done_callback_called_on_publish_response_invalid(): # Refer https://opentelemetry.io/docs/languages/python/#version-support -@pytest.mark.skipif( - sys.version_info < (3, 8), reason="Open Telemetry requires python3.8 or higher" -) def test_open_telemetry_commit_publish_rpc_span_none(span_exporter): """ Test scenario where OpenTelemetry is enabled, publish RPC @@ -771,9 +767,6 @@ def test_open_telemetry_commit_publish_rpc_span_none(span_exporter): # Refer https://opentelemetry.io/docs/languages/python/#version-support -@pytest.mark.skipif( - sys.version_info < (3, 8), reason="Open Telemetry requires python3.8 or higher" -) def test_open_telemetry_commit_publish_rpc_exception(span_exporter): TOPIC = "projects/projectID/topics/topicID" batch = create_batch(topic=TOPIC, enable_open_telemetry=True) @@ -819,9 +812,6 @@ def test_open_telemetry_commit_publish_rpc_exception(span_exporter): # Refer https://opentelemetry.io/docs/languages/python/#version-support -@pytest.mark.skipif( - sys.version_info < (3, 8), reason="Open Telemetry requires python3.8 or higher" -) def test_opentelemetry_commit_sampling(span_exporter): TOPIC = "projects/projectID/topics/topic" batch = create_batch( @@ -886,9 +876,6 @@ def test_opentelemetry_commit_sampling(span_exporter): assert span.events[1].name == "publish end" -@pytest.mark.skipif( - sys.version_info < (3, 8), reason="Open Telemetry requires python3.8 or higher" -) def test_opentelemetry_commit(span_exporter): TOPIC = "projects/projectID/topics/topic" batch = create_batch( diff --git a/packages/google-cloud-pubsub/tests/unit/pubsub_v1/publisher/test_publisher_client.py b/packages/google-cloud-pubsub/tests/unit/pubsub_v1/publisher/test_publisher_client.py index cdba7654d2bb..cd20d49d9443 100644 --- a/packages/google-cloud-pubsub/tests/unit/pubsub_v1/publisher/test_publisher_client.py +++ b/packages/google-cloud-pubsub/tests/unit/pubsub_v1/publisher/test_publisher_client.py @@ -16,7 +16,6 @@ import inspect import math -import sys import time from typing import Any, Callable, TypeVar, cast from unittest import mock @@ -154,28 +153,13 @@ def test_init_w_custom_transport(creds): ) @typed_flaky def test_open_telemetry_publisher_options(creds, enable_open_telemetry): - if sys.version_info >= (3, 8) or enable_open_telemetry is False: - client = publisher.Client( - publisher_options=types.PublisherOptions( - enable_open_telemetry_tracing=enable_open_telemetry - ), - credentials=creds, - ) - assert client._open_telemetry_enabled == enable_open_telemetry - else: - # Open Telemetry is not supported and hence disabled for Python - # versions 3.7 or below - with pytest.warns( - RuntimeWarning, - match="Open Telemetry for Python version 3.7 or lower is not supported. Disabling Open Telemetry tracing.", - ): - client = publisher.Client( - publisher_options=types.PublisherOptions( - enable_open_telemetry_tracing=enable_open_telemetry - ), - credentials=creds, - ) - assert client._open_telemetry_enabled is False + client = publisher.Client( + publisher_options=types.PublisherOptions( + enable_open_telemetry_tracing=enable_open_telemetry + ), + credentials=creds, + ) + assert client._open_telemetry_enabled == enable_open_telemetry def test_opentelemetry_context_setter(): @@ -185,10 +169,6 @@ def test_opentelemetry_context_setter(): assert "googclient_key" in msg.attributes.keys() -@pytest.mark.skipif( - sys.version_info < (3, 8), - reason="Open Telemetry not supported below Python version 3.8", -) def test_opentelemetry_context_propagation(creds, span_exporter): TOPIC = "projects/projectID/topics/topicID" client = publisher.Client( @@ -208,10 +188,6 @@ def test_opentelemetry_context_propagation(creds, span_exporter): assert "googclient_traceparent" in args[0].attributes -@pytest.mark.skipif( - sys.version_info < (3, 8), - reason="Open Telemetry not supported below Python version 3.8", -) @pytest.mark.parametrize( "enable_open_telemetry", [ @@ -271,10 +247,6 @@ def test_opentelemetry_publisher_batching_exception( assert len(spans) == 0 -@pytest.mark.skipif( - sys.version_info < (3, 8), - reason="Open Telemetry not supported below Python version 3.8", -) def test_opentelemetry_flow_control_exception(creds, span_exporter): publisher_options = types.PublisherOptions( flow_control=types.PublishFlowControl( @@ -299,16 +271,30 @@ def test_opentelemetry_flow_control_exception(creds, span_exporter): spans = span_exporter.get_finished_spans() - # Find the spans related to the second, failing publish call - failed_create_span = None + # Find the spans related to the second, failing publish call. + # We first find the failed flow control span. failed_fc_span = None for span in spans: - if span.name == "topicID create": - if span.status.status_code == trace.StatusCode.ERROR: + if ( + span.name == "publisher flow control" + and span.status.status_code == trace.StatusCode.ERROR + ): + failed_fc_span = span + break + + # Next, we find the corresponding 'create' span. + # Crucially, to prevent matching late-arriving or concurrent publish spans from other tests + # (e.g. background batch/sequencer threads from previous tests executing late), + # we filter for the 'topicID create' span that shares the EXACT same trace ID. + failed_create_span = None + if failed_fc_span: + for span in spans: + if ( + span.name == "topicID create" + and span.context.trace_id == failed_fc_span.context.trace_id + ): failed_create_span = span - elif span.name == "publisher flow control": - if span.status.status_code == trace.StatusCode.ERROR: - failed_fc_span = span + break assert failed_create_span is not None, "Failed 'topicID create' span not found" assert failed_fc_span is not None, "Failed 'publisher flow control' span not found" @@ -332,10 +318,6 @@ def test_opentelemetry_flow_control_exception(creds, span_exporter): assert has_exception_event, "Exception event not found in failed create span" -@pytest.mark.skipif( - sys.version_info < (3, 8), - reason="Open Telemetry not supported below Python version 3.8", -) def test_opentelemetry_publish(creds, span_exporter): TOPIC = "projects/projectID/topics/topicID" client = publisher.Client( diff --git a/packages/google-cloud-pubsub/tests/unit/pubsub_v1/subscriber/test_dispatcher.py b/packages/google-cloud-pubsub/tests/unit/pubsub_v1/subscriber/test_dispatcher.py index 2ebd37318717..749b7495c3b1 100644 --- a/packages/google-cloud-pubsub/tests/unit/pubsub_v1/subscriber/test_dispatcher.py +++ b/packages/google-cloud-pubsub/tests/unit/pubsub_v1/subscriber/test_dispatcher.py @@ -14,7 +14,6 @@ import collections import queue -import sys import threading from unittest import mock @@ -403,10 +402,6 @@ def test_opentelemetry_modify_ack_deadline(span_exporter): assert subscribe_span.events[1].name == "modack end" -@pytest.mark.skipif( - sys.version_info < (3, 8), - reason="Open Telemetry not supported below Python version 3.8", -) def test_opentelemetry_ack(span_exporter): manager = mock.create_autospec( streaming_pull_manager.StreamingPullManager, instance=True @@ -602,10 +597,6 @@ def test_retry_acks_in_new_thread(): assert ctor_call.kwargs["daemon"] -@pytest.mark.skipif( - sys.version_info < (3, 8), - reason="Open Telemetry not supported below Python version 3.8", -) def test_opentelemetry_retry_acks(span_exporter): manager = mock.create_autospec( streaming_pull_manager.StreamingPullManager, instance=True @@ -789,10 +780,6 @@ def test_opentelemetry_retry_modacks(span_exporter): assert subscribe_span.events[0].name == "modack end" -@pytest.mark.skipif( - sys.version_info < (3, 8), - reason="Open Telemetry not supported below Python version 3.8", -) def test_opentelemetry_retry_nacks(span_exporter): manager = mock.create_autospec( streaming_pull_manager.StreamingPullManager, instance=True @@ -959,10 +946,6 @@ def test_drop_ordered_messages(): manager.maybe_resume_consumer.assert_called_once() -@pytest.mark.skipif( - sys.version_info < (3, 8), - reason="Open Telemetry not supported below Python version 3.8", -) def test_opentelemetry_nack(span_exporter): manager = mock.create_autospec( streaming_pull_manager.StreamingPullManager, instance=True diff --git a/packages/google-cloud-pubsub/tests/unit/pubsub_v1/subscriber/test_streaming_pull_manager.py b/packages/google-cloud-pubsub/tests/unit/pubsub_v1/subscriber/test_streaming_pull_manager.py index 5279591377a1..aa5d0d30cee9 100644 --- a/packages/google-cloud-pubsub/tests/unit/pubsub_v1/subscriber/test_streaming_pull_manager.py +++ b/packages/google-cloud-pubsub/tests/unit/pubsub_v1/subscriber/test_streaming_pull_manager.py @@ -16,7 +16,6 @@ import logging import math import queue -import sys import threading import time import types as stdlib_types @@ -629,10 +628,6 @@ def test__maybe_release_messages_negative_on_hold_bytes_warning( assert manager._on_hold_bytes == 0 # should be auto-corrected -@pytest.mark.skipif( - sys.version_info < (3, 8), - reason="Open Telemetry not supported below Python version 3.8", -) @pytest.mark.parametrize( "receipt_modack", [ @@ -2823,10 +2818,6 @@ def test_process_requests_mixed_success_and_failure_modacks(): assert future3.result() == subscriber_exceptions.AcknowledgeStatus.SUCCESS -@pytest.mark.skipif( - sys.version_info < (3, 8), - reason="Open Telemetry not supported below Python version 3.8", -) def test_opentelemetry__on_response_subscribe_span_create(span_exporter): manager, _, _, leaser, _, _ = make_running_manager( enable_open_telemetry=True, diff --git a/packages/google-cloud-pubsub/tests/unit/pubsub_v1/subscriber/test_subscriber_client.py b/packages/google-cloud-pubsub/tests/unit/pubsub_v1/subscriber/test_subscriber_client.py index 9e488c84b86b..2b3045b8d547 100644 --- a/packages/google-cloud-pubsub/tests/unit/pubsub_v1/subscriber/test_subscriber_client.py +++ b/packages/google-cloud-pubsub/tests/unit/pubsub_v1/subscriber/test_subscriber_client.py @@ -11,8 +11,6 @@ # 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 sys from unittest import mock import grpc @@ -345,17 +343,9 @@ def test_opentelemetry_subscriber_setting(creds, enable_open_telemetry): options = types.SubscriberOptions( enable_open_telemetry_tracing=enable_open_telemetry, ) - if sys.version_info >= (3, 8) or enable_open_telemetry is False: - client = subscriber.Client(credentials=creds, subscriber_options=options) - assert client.subscriber_options == options - assert client._open_telemetry_enabled == enable_open_telemetry - else: - with pytest.warns( - RuntimeWarning, - match="Open Telemetry for Python version 3.7 or lower is not supported. Disabling Open Telemetry tracing.", - ): - client = subscriber.Client(credentials=creds, subscriber_options=options) - assert client._open_telemetry_enabled is False + client = subscriber.Client(credentials=creds, subscriber_options=options) + assert client.subscriber_options == options + assert client._open_telemetry_enabled == enable_open_telemetry def test_opentelemetry_propagator_get(): diff --git a/packages/google-cloud-pubsub/tests/unit/pubsub_v1/test_futures.py b/packages/google-cloud-pubsub/tests/unit/pubsub_v1/test_futures.py index 7c724ad047f1..cf18f1b795ac 100644 --- a/packages/google-cloud-pubsub/tests/unit/pubsub_v1/test_futures.py +++ b/packages/google-cloud-pubsub/tests/unit/pubsub_v1/test_futures.py @@ -13,7 +13,6 @@ # limitations under the License. import concurrent.futures -import sys import threading import time from unittest import mock @@ -117,10 +116,6 @@ def test_set_running_or_notify_cancel_not_implemented_error(): assert "concurrent.futures" in error_msg -@pytest.mark.skipif( - sys.version_info < (3, 8), - reason="InvalidStateError is only available in Python 3.8+", -) def test_set_result_once_only(): future = _future() future.set_result("12345") @@ -128,10 +123,6 @@ def test_set_result_once_only(): future.set_result("67890") -@pytest.mark.skipif( - sys.version_info < (3, 8), - reason="InvalidStateError is only available in Python 3.8+", -) def test_set_exception_once_only(): future = _future() future.set_exception(ValueError("wah wah")) From 3d8d582a8606395e36ebcd2d1697931558a96621 Mon Sep 17 00:00:00 2001 From: Chalmer Lowe Date: Wed, 17 Jun 2026 12:08:52 -0400 Subject: [PATCH 091/174] feat(version-scanner): support target list inputs via --targets (#17478) This pull request adds support for scanning multiple target dependencies and versions concurrently via a YAML file containing targets, while consolidating file handling and error logging. Key changes: - **YAML Targets File Support:** Adds a `--targets-file` CLI argument to read and resolve multiple target dependency-version tuples from a configuration file. - **Consolidated File Handling:** Centralizes file reading and error logging across the codebase under a single helper (`_safe_read_file`) with uniform stderr printing and exit codes. - **Expanded Test Coverage:** Adds parametrized unit tests validating targets file parsing errors (missing files, bad format, null values) and the core file helper error branches, and updates integration tests to utilize soft-fail flags. --- .../integration/test_scanner_integration.py | 3 +- .../tests/unit/test_version_scanner.py | 222 +++++++++++------ scripts/version_scanner/version_scanner.py | 226 ++++++++++++++---- 3 files changed, 329 insertions(+), 122 deletions(-) diff --git a/scripts/version_scanner/tests/integration/test_scanner_integration.py b/scripts/version_scanner/tests/integration/test_scanner_integration.py index 36eff2402d38..3ce6d2cd3ab1 100644 --- a/scripts/version_scanner/tests/integration/test_scanner_integration.py +++ b/scripts/version_scanner/tests/integration/test_scanner_integration.py @@ -32,7 +32,8 @@ def test_integration_scan(tmp_path): "-v", "3.7", "-p", data_dir, "--config", config_path, - "-o", "scanner_report.csv" + "-o", "scanner_report.csv", + "--soft-fail" ] result = subprocess.run(cmd, cwd=tmp_path, capture_output=True, text=True, check=True) diff --git a/scripts/version_scanner/tests/unit/test_version_scanner.py b/scripts/version_scanner/tests/unit/test_version_scanner.py index f76b66d4d55d..054df22421bc 100644 --- a/scripts/version_scanner/tests/unit/test_version_scanner.py +++ b/scripts/version_scanner/tests/unit/test_version_scanner.py @@ -32,6 +32,60 @@ format_for_console ) +@pytest.fixture +def sample_match(): + return { + "file_name": "setup.py", + "file_path": "google-cloud-python/main/packages/pkg_a/setup.py", + "repo_path": "packages/pkg_a/setup.py", + "package_name": "pkg_a", + "rule_name": "python_requires_check", + "line_number": "123", + "matched_string": "3.7", + "context_line": "python_requires = '>=3.7'", + "dependency": "python", + "version": "3.7" + } + + +@pytest.mark.parametrize( + "exception_to_raise, required, silent_missing, expected_exit, expected_output, expected_return", + [ + (None, True, False, False, None, "file content"), # Success + (FileNotFoundError(), True, True, False, None, None), # Silent missing FileNotFoundError + (FileNotFoundError(), True, False, True, "Error: Test_desc not found", None), # Required FileNotFoundError + (FileNotFoundError(), False, False, False, "Warning: Test_desc not found", None), # Optional FileNotFoundError + (PermissionError(), True, False, True, "Error: Permission denied reading test_desc", None), # Required PermissionError + (PermissionError(), False, False, False, "Warning: Permission denied reading test_desc", None), # Optional PermissionError + (IOError("disk full"), True, False, True, "Error reading test_desc", None), # Required IOError + (IOError("disk full"), False, False, False, "Warning: Error reading test_desc", None), # Optional IOError + ] +) +def test_safe_read_file_scenarios( + capsys, exception_to_raise, required, silent_missing, expected_exit, expected_output, expected_return +): + from version_scanner import _safe_read_file + + if exception_to_raise: + mock_open = mock.mock_open() + mock_open.side_effect = exception_to_raise + else: + mock_open = mock.mock_open(read_data="file content") + + with patch("builtins.open", mock_open): + if expected_exit: + with pytest.raises(SystemExit) as excinfo: + _safe_read_file("dummy.txt", required=required, description="test_desc", silent_missing=silent_missing) + assert excinfo.value.code == 1 + else: + res = _safe_read_file("dummy.txt", required=required, description="test_desc", silent_missing=silent_missing) + assert res == expected_return + + if expected_output: + captured = capsys.readouterr() + assert expected_output in captured.err + + # Test ConfigManager @pytest.mark.parametrize("dependency, version, expected", [ ( @@ -682,34 +736,13 @@ def test_safe_int(): assert _safe_int(None) == 0 assert _safe_int("abc") == 0 -def test_format_for_raw_csv_handles_empty_line_number(): - match = { - "file_path": "google-cloud-python/main/packages/pkg_a/setup.py", - "repo_path": "packages/pkg_a/setup.py", - "package_name": "pkg_a", - "rule_name": "python_requires_check", - "line_number": "", - "matched_string": "3.7", - "context_line": "python_requires = '>=3.7'" - } - formatted = format_for_raw_csv(match) +def test_format_for_raw_csv_handles_empty_line_number(sample_match): + sample_match["line_number"] = "" + formatted = format_for_raw_csv(sample_match) assert formatted["line_number"] == 0 -def test_format_for_raw_csv(): - match = { - "file_name": "setup.py", - "file_path": "google-cloud-python/main/packages/pkg_a/setup.py", - "repo_path": "packages/pkg_a/setup.py", - "package_name": "pkg_a", - "rule_name": "python_requires_check", - "line_number": "123", - "matched_string": "3.7", - "context_line": "python_requires = '>=3.7'", - "dependency": "python", - "version": "3.7" - } - - formatted = format_for_raw_csv(match) +def test_format_for_raw_csv(sample_match): + formatted = format_for_raw_csv(sample_match) assert formatted["file_name"] == "setup.py" assert formatted["file_path"] == "google-cloud-python/main/packages/pkg_a/setup.py" @@ -721,38 +754,14 @@ def test_format_for_raw_csv(): assert formatted["dependency"] == "python" assert formatted["version"] == "3.7" -def test_format_for_raw_csv_fallback_filename(): - match = { - "file_path": "google-cloud-python/main/packages/pkg_a/setup.py", - "repo_path": "packages/pkg_a/setup.py", - "package_name": "pkg_a", - "rule_name": "python_requires_check", - "line_number": "123", - "matched_string": "3.7", - "context_line": "python_requires = '>=3.7'", - "dependency": "python", - "version": "3.7" - } - - formatted = format_for_raw_csv(match) +def test_format_for_raw_csv_fallback_filename(sample_match): + del sample_match["file_name"] + formatted = format_for_raw_csv(sample_match) assert formatted["file_name"] == "setup.py" -def test_format_for_spreadsheet(): - match = { - "file_name": "setup.py", - "file_path": "google-cloud-python/main/packages/pkg_a/setup.py", - "repo_path": "packages/pkg_a/setup.py", - "package_name": "pkg_a", - "rule_name": "python_requires_check", - "line_number": 123, - "matched_string": "3.7", - "context_line": "python_requires = '>=3.7'", - "dependency": "python", - "version": "3.7" - } - +def test_format_for_spreadsheet(sample_match): # Without github_repo - formatted_no_repo = format_for_spreadsheet(match) + formatted_no_repo = format_for_spreadsheet(sample_match) assert formatted_no_repo["file_name"] == "setup.py" assert formatted_no_repo["line_number"] == 123 assert formatted_no_repo["matched_string"] == '="3.7"' # Decimal protection formula @@ -760,25 +769,102 @@ def test_format_for_spreadsheet(): assert formatted_no_repo["version"] == "3.7" # With github_repo - formatted_repo = format_for_spreadsheet(match, github_repo="https://github.com/user/repo", branch="main") + formatted_repo = format_for_spreadsheet(sample_match, github_repo="https://github.com/user/repo", branch="main") expected_url = "https://github.com/user/repo/blob/main/packages/pkg_a/setup.py#L123" assert formatted_repo["line_number"] == f'=HYPERLINK("{expected_url}", "123")' assert formatted_repo["matched_string"] == '="3.7"' -def test_format_for_console(): - match = { - "file_path": "google-cloud-python/main/packages/pkg_a/setup.py", - "repo_path": "packages/pkg_a/setup.py", - "package_name": "pkg_a", - "rule_name": "python_requires_check", - "line_number": 123, - "matched_string": "3.7", - "context_line": "python_requires = '>=3.7'" - } - - log_str = format_for_console(match) +def test_format_for_console(sample_match): + log_str = format_for_console(sample_match) assert "google-cloud-python/main/packages/pkg_a/setup.py:123" in log_str assert "[python_requires_check]" in log_str assert "3.7" in log_str assert "python_requires = " not in log_str # Slim format doesn't print context line + +def test_parse_targets_file(tmp_path): + from version_scanner import parse_targets_file + yaml_file = tmp_path / "targets.yaml" + yaml_file.write_text(""" +python: + - "3.7" + - "3.8" +protobuf: "4.25.8" +""") + targets = parse_targets_file(str(yaml_file)) + assert targets == [("python", "3.7"), ("python", "3.8"), ("protobuf", "4.25.8")] + +@pytest.mark.parametrize( + "file_content, file_exists", + [ + (None, False), # File not found + ("invalid: {", True), # Invalid YAML + ("- not_a_mapping", True), # Invalid structure (list instead of map) + ("python:\n - null", True), # Invalid version type (null/None value) + ] +) +def test_parse_targets_file_failures(tmp_path, file_content, file_exists): + from version_scanner import parse_targets_file + + if file_exists: + yaml_file = tmp_path / "targets_failures.yaml" + yaml_file.write_text(file_content) + path = str(yaml_file) + else: + path = "nonexistent_file.yaml" + + with pytest.raises(SystemExit) as excinfo: + parse_targets_file(path) + assert excinfo.value.code == 1 + +def test_scan_repository_multi_targets(tmp_path): + # Setup files in tmp repository + file1 = tmp_path / "packages" / "pkg1" / "setup.py" + file1.parent.mkdir(parents=True) + file1.write_text("python_requires = '>=3.7'\n") + + file2 = tmp_path / "packages" / "pkg2" / "requirements.txt" + file2.parent.mkdir(parents=True) + file2.write_text("protobuf==4.25.8\n") + + # Let's mock a config file with rules for both python and protobuf + config_file = tmp_path / "regex_config.yaml" + config_file.write_text(""" +rules: + - name: python_requires_check + applies_to: + - python + rules: + - python_requires\\s*=\\s*['\"]>={version}['\"] + - name: protobuf_check + applies_to: + - protobuf + rules: + - protobuf=={version} +""") + + from version_scanner import ConfigManager, scan_repository + + targets = [("python", "3.7"), ("protobuf", "4.25.8")] + rules = [] + for dep, ver in targets: + cm = ConfigManager(str(config_file), dep, ver) + rules.extend(cm.load_config()) + + results = scan_repository(str(tmp_path), rules, targets=targets) + + # We should have 2 matches + assert len(results) == 2 + + # Match for python + python_match = [r for r in results if r["dependency"] == "python"] + assert len(python_match) == 1 + assert python_match[0]["version"] == "3.7" + assert python_match[0]["rule_name"] == "python_requires_check" + + # Match for protobuf + protobuf_match = [r for r in results if r["dependency"] == "protobuf"] + assert len(protobuf_match) == 1 + assert protobuf_match[0]["version"] == "4.25.8" + assert protobuf_match[0]["rule_name"] == "protobuf_check" + diff --git a/scripts/version_scanner/version_scanner.py b/scripts/version_scanner/version_scanner.py index 484a6eacacae..6205e8effadd 100644 --- a/scripts/version_scanner/version_scanner.py +++ b/scripts/version_scanner/version_scanner.py @@ -23,9 +23,57 @@ import os import re import sys -from typing import Dict, List, Tuple, Any +from typing import Dict, List, Tuple, Any, Optional import yaml + +def _safe_read_file( + file_path: str, + required: bool = True, + description: str = "file", + silent_missing: bool = False +) -> Optional[str]: + """ + Safely reads file content and handles common file errors. + + Args: + file_path: Path to the file. + required: If True, exits the program with code 1 on read failure. + If False, prints a warning (or ignores) and returns None. + description: Description of the file type for error logging. + silent_missing: If True, silently ignores FileNotFoundError (returns None). + + Returns: + The file content string, or None if reading failed/was ignored. + """ + try: + with open(file_path, 'r', encoding='utf-8') as f: + return f.read() + except FileNotFoundError: + if silent_missing: + return None + if required: + print(f"Error: {description.capitalize()} not found: {file_path}", file=sys.stderr) + sys.exit(1) + else: + print(f"Warning: {description.capitalize()} not found: {file_path}", file=sys.stderr) + return None + except PermissionError: + if required: + print(f"Error: Permission denied reading {description}: {file_path}", file=sys.stderr) + sys.exit(1) + else: + print(f"Warning: Permission denied reading {description}: {file_path}", file=sys.stderr) + return None + except IOError as e: + if required: + print(f"Error reading {description} {file_path}: {e}", file=sys.stderr) + sys.exit(1) + else: + print(f"Warning: Error reading {description} {file_path}: {e}", file=sys.stderr) + return None + + class ConfigManager: """ Handles loading, validation, and interpolation of the regex configuration rules. @@ -106,15 +154,9 @@ def _compute_variables(self) -> Dict[str, str]: def load_config(self) -> List[Dict[str, str]]: """Load and resolve rules from config.""" + content = _safe_read_file(self.config_path, required=True, description="config file") try: - with open(self.config_path, 'r', encoding='utf-8') as f: - config = yaml.safe_load(f) - except FileNotFoundError: - print(f"Error: Config file not found: {self.config_path}", file=sys.stderr) - sys.exit(1) - except PermissionError: - print(f"Error: Permission denied reading config file: {self.config_path}", file=sys.stderr) - sys.exit(1) + config = yaml.safe_load(content) except yaml.YAMLError as e: print(f"Error parsing config file: {e}", file=sys.stderr) sys.exit(1) @@ -137,7 +179,9 @@ def load_config(self) -> List[Dict[str, str]]: resolved_pattern = template.strip().format(**self.variables) resolved_rules.append({ "name": name, - "pattern": resolved_pattern + "pattern": resolved_pattern, + "dependency": self.dependency, + "version": self.version }) except KeyError as e: print(f"Warning: Missing variable for interpolation in rule {name}: {e}", file=sys.stderr) @@ -178,7 +222,9 @@ def scan_file(file_path: str, compiled_rules: List[Dict[str, re.Pattern]]) -> Li "rule_name": rule["name"], "line_number": line_num, "matched_string": match.group(0).strip(), - "context_line": line.strip() + "context_line": line.strip(), + "dependency": rule.get("dependency", ""), + "version": rule.get("version", "") }) except IOError as e: print(f"Warning: Could not read file {file_path}: {e}", file=sys.stderr) @@ -326,14 +372,12 @@ def load_ignore_file(file_path: str) -> List[str]: Read ignore paths from a file. """ ignore_dirs = [] - try: - with open(file_path, 'r', encoding='utf-8') as f: - for line in f: - line = line.strip() - if line and not line.startswith('#'): - ignore_dirs.append(line) - except FileNotFoundError: - pass + content = _safe_read_file(file_path, required=False, silent_missing=True) + if content: + for line in content.splitlines(): + line = line.strip() + if line and not line.startswith('#'): + ignore_dirs.append(line) return ignore_dirs @@ -445,30 +489,22 @@ def read_package_file(file_path: str) -> List[str]: A list of package paths. """ packages = [] - try: - with open(file_path, 'r', encoding='utf-8') as f: - for line in f: - line = line.strip() - if line and not line.startswith('#'): - packages.append(line) - except FileNotFoundError: - print(f"Error: Package file not found: {file_path}", file=sys.stderr) - sys.exit(1) - except PermissionError: - print(f"Error: Permission denied reading package file: {file_path}", file=sys.stderr) - sys.exit(1) - except IOError as e: - print(f"Error reading package file: {e}", file=sys.stderr) - sys.exit(1) + content = _safe_read_file(file_path, required=True, description="package file") + if content: + for line in content.splitlines(): + line = line.strip() + if line and not line.startswith('#'): + packages.append(line) return packages def scan_repository( root_path: str, - rules: List[Dict[str, str]], + rules: List[Dict[str, Any]], target_packages: List[str] = None, ignore_dirs: List[str] = None, - version_string: str = None + version_string: str = None, + targets: List[Tuple[str, str]] = None ) -> List[Dict[str, Any]]: """ Scans the repository directory tree applying resolved regex patterns to files. @@ -487,21 +523,30 @@ def scan_repository( performs a full recursive scan of the repository. ignore_dirs: Optional list of directory names or glob-like files to ignore (case-insensitive). version_string: Optional target version string (e.g. "3.7") to scan for in filenames. + targets: Optional list of (dependency, version) tuples. Returns: - A list of dictionaries detailing each match: 'file_path', 'repo_path', - 'package_name', 'rule_name', 'line_number', 'matched_string', 'context_line'. + A list of dictionaries detailing each match. """ ignore_lower = {i.lower() for i in ignore_dirs} if ignore_dirs else set() results = [] + filename_targets = [] + if targets: + filename_targets = targets + elif version_string: + dep = rules[0].get("dependency") if rules else None + filename_targets = [(dep, version_string)] + # Compile patterns once here compiled_rules = [] for rule in rules: try: compiled_rules.append({ "name": rule["name"], - "pattern": re.compile(rule["pattern"], re.IGNORECASE) + "pattern": re.compile(rule["pattern"], re.IGNORECASE), + "dependency": rule.get("dependency", ""), + "version": rule.get("version", "") }) except re.error as e: print(f"Error compiling regex for rule {rule['name']}: {e}", file=sys.stderr) @@ -541,13 +586,16 @@ def scan_repository( matches = scan_file(file_path, compiled_rules) # Add filename match if applicable - if version_string and version_string in file: - matches.append({ - "rule_name": "filename_match", - "line_number": 0, - "matched_string": version_string, - "context_line": f"Filename contains {version_string}" - }) + for dep, ver in filename_targets: + if ver and ver in file: + matches.append({ + "rule_name": "filename_match", + "line_number": 0, + "matched_string": ver, + "context_line": f"Filename contains {ver}", + "dependency": dep or "", + "version": ver + }) # Compute display path and package name rel_file_path = os.path.relpath(file_path, root_path) @@ -576,6 +624,38 @@ def scan_repository( return results +def parse_targets_file(file_path: str) -> List[Tuple[str, str]]: + """ + Parses a YAML targets file into a list of (dependency, version) tuples. + """ + content = _safe_read_file(file_path, required=True, description="targets file") + try: + raw_targets = yaml.safe_load(content) + except Exception as e: + print(f"Error parsing targets YAML mapping: {e}", file=sys.stderr) + sys.exit(1) + + if not isinstance(raw_targets, dict): + print("Error: Targets file content must resolve to a YAML mapping", file=sys.stderr) + sys.exit(1) + + targets = [] + for dep, versions in raw_targets.items(): + if isinstance(versions, list): + for v in versions: + if v is None or isinstance(v, (dict, list)): + print(f"Error: Invalid version '{v}' for dependency '{dep}'", file=sys.stderr) + sys.exit(1) + targets.append((str(dep), str(v))) + elif versions is not None and not isinstance(versions, dict): + targets.append((str(dep), str(versions))) + else: + print(f"Error: Invalid version '{versions}' for dependency '{dep}'", file=sys.stderr) + sys.exit(1) + + return targets + + def main(): script_dir = os.path.dirname(os.path.abspath(__file__)) default_config = os.path.join(script_dir, "regex_config.yaml") @@ -586,16 +666,19 @@ def main(): parser.add_argument( "-d", "--dependency", - required=True, help="Name of the dependency (e.g., python, protobuf)" ) parser.add_argument( "-v", "--version", - required=True, help="Specific version to search for (e.g., 3.7, 4.25.8)" ) + parser.add_argument( + "--targets-file", + help="Path to a YAML file containing target dependencies and versions." + ) + parser.add_argument( "-p", "--path", default=".", @@ -659,6 +742,25 @@ def main(): args = parser.parse_args() + # Validation of required inputs + has_single_target = bool(args.dependency and args.version) + has_targets_file = bool(args.targets_file) + + if not (has_single_target or has_targets_file): + parser.error("Must specify either (-d/--dependency AND -v/--version) OR (--targets-file)") + if has_single_target and has_targets_file: + parser.error("Cannot specify both single target (-d/-v) and targets file (--targets-file)") + + targets = [] + if has_targets_file: + targets = parse_targets_file(args.targets_file) + else: + targets = [(args.dependency, args.version)] + + if not targets: + print("Error: No targets resolved to scan.", file=sys.stderr) + sys.exit(1) + # Resolve target packages if filtering is requested target_packages = [] if args.package: @@ -670,7 +772,12 @@ def main(): elif args.package_file: target_packages = read_package_file(args.package_file) - print(f"Starting scan for dependency: {args.dependency} version: {args.version}") + if has_targets_file: + print("Starting scan for multiple targets:") + for dep, ver in targets: + print(f" - {dep}: {ver}") + else: + print(f"Starting scan for dependency: {args.dependency} version: {args.version}") print(f"Root path: {args.path}") print("Targets to scan:") if target_packages: @@ -681,8 +788,10 @@ def main(): print(f"Using config: {args.config}") # Load and resolve rules - config_manager = ConfigManager(args.config, args.dependency, args.version) - rules = config_manager.load_config() + rules = [] + for dep, ver in targets: + config_manager = ConfigManager(args.config, dep, ver) + rules.extend(config_manager.load_config()) @@ -695,7 +804,14 @@ def main(): print(f"Loaded {len(ignore_dirs)} ignore patterns from {ignore_file_path}") # Scan repository - all_matches = scan_repository(args.path, rules, target_packages, ignore_dirs, version_string=args.version) + all_matches = scan_repository( + args.path, + rules, + target_packages, + ignore_dirs, + version_string=(None if has_targets_file else args.version), + targets=targets + ) print(f"\nFound {len(all_matches)} matches.") display_matches = all_matches if args.stdout else all_matches[:10] @@ -717,7 +833,11 @@ def main(): script_dir = os.path.dirname(os.path.abspath(__file__)) results_dir = os.path.join(script_dir, "results") os.makedirs(results_dir, exist_ok=True) - output_path = os.path.join(results_dir, f"{args.dependency}-{args.version}-{timestamp}.csv") + if has_targets_file: + base_name = os.path.splitext(os.path.basename(args.targets_file))[0] + output_path = os.path.join(results_dir, f"{base_name}-{timestamp}.csv") + else: + output_path = os.path.join(results_dir, f"{args.dependency}-{args.version}-{timestamp}.csv") write_csv_report(output_path, all_matches) From 27d999d3036991e377b916c36b74e9aa97fcc0c2 Mon Sep 17 00:00:00 2001 From: Daniel Sanche Date: Wed, 17 Jun 2026 09:10:35 -0700 Subject: [PATCH 092/174] chore: update action versions for node24 (#17462) Addressing warning in recent CI runs: >Warning: Node.js 20 actions are deprecated. The following actions are running on Node.js 20 and may not work as expected: actions/checkout@v4, actions/download-artifact@v4, actions/setup-python@v5. Actions will be forced to run with Node.js 24 by default starting June 16th, 2026. Node.js 20 will be removed from the runner on September 16th, 2026. Please check if updated versions of these actions are available that support Node.js 24. To opt into Node.js 24 now, set the FORCE_JAVASCRIPT_ACTIONS_TO_NODE24=true environment variable on the runner or in your workflow file. Once Node.js 24 becomes the default, you can temporarily opt out by setting ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true. For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/ --- .github/workflows/django-spanner-django5.2_tests.yml | 6 +++--- .github/workflows/unittest.yml | 6 +++--- .../tests/unit/v1/test_query_profile.py | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/django-spanner-django5.2_tests.yml b/.github/workflows/django-spanner-django5.2_tests.yml index 63b8f52d1839..be4ccc1b3350 100644 --- a/.github/workflows/django-spanner-django5.2_tests.yml +++ b/.github/workflows/django-spanner-django5.2_tests.yml @@ -21,7 +21,7 @@ jobs: outputs: run_django_spanner: ${{ steps.filter.outputs.django_spanner }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: dorny/paths-filter@v3 id: filter with: @@ -68,9 +68,9 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: "3.10" - name: Run Django tests diff --git a/.github/workflows/unittest.yml b/.github/workflows/unittest.yml index e231533e0ee1..6cd22f7ba742 100644 --- a/.github/workflows/unittest.yml +++ b/.github/workflows/unittest.yml @@ -20,14 +20,14 @@ jobs: python: ['3.9', '3.10', "3.11", "3.12", "3.13", "3.14"] steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 # Use a fetch-depth of 2 to avoid error `fatal: origin/main...HEAD: no merge base` # See https://github.com/googleapis/google-cloud-python/issues/12013 # and https://github.com/actions/checkout#checkout-head. with: fetch-depth: 2 - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.python }} - name: Install nox @@ -79,7 +79,7 @@ jobs: python -m pip install coverage - name: Download coverage results if: ${{ steps.packages.outputs.num_files_changed > 0 }} - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v5 with: path: .coverage-results/ - name: Report coverage results diff --git a/packages/google-cloud-firestore/tests/unit/v1/test_query_profile.py b/packages/google-cloud-firestore/tests/unit/v1/test_query_profile.py index b86c8fc1154e..fa9e231d6839 100644 --- a/packages/google-cloud-firestore/tests/unit/v1/test_query_profile.py +++ b/packages/google-cloud-firestore/tests/unit/v1/test_query_profile.py @@ -96,8 +96,8 @@ def test_explain_metrics__from_pb_empty(): def test_explain_metrics_execution_stats(): """ - Standard ExplainMetrics class should raise exception when execution_stats is accessed. - _ExplainAnalyzeMetrics should include the field + Standard ExplainMetrics class should raise exception when execution_stats + is accessed. _ExplainAnalyzeMetrics should include the field """ from google.cloud.firestore_v1.query_profile import ( ExplainMetrics, From a734cfc6aceaf6721fd9813bdf75bfd568bac4c0 Mon Sep 17 00:00:00 2001 From: Min Zhu Date: Wed, 17 Jun 2026 13:28:23 -0400 Subject: [PATCH 093/174] Revert "chore(generator): centralize mypy configuration and regenerate google-cloud-datastore POC" (#17493) Reverts googleapis/google-cloud-python#17408 --- .../datastore-integration.yaml | 36 ++++++ mypy.ini | 110 ------------------ .../gapic/ads-templates/mypy.ini.j2 | 3 + .../gapic/ads-templates/noxfile.py.j2 | 7 -- .../gapic/templates/mypy.ini.j2 | 15 +++ .../gapic/templates/noxfile.py.j2 | 3 - .../tests/integration/goldens/asset/mypy.ini | 15 +++ .../integration/goldens/asset/noxfile.py | 3 - .../integration/goldens/credentials/mypy.ini | 15 +++ .../goldens/credentials/noxfile.py | 3 - .../integration/goldens/eventarc/mypy.ini | 15 +++ .../integration/goldens/eventarc/noxfile.py | 3 - .../integration/goldens/logging/mypy.ini | 15 +++ .../integration/goldens/logging/noxfile.py | 3 - .../goldens/logging_internal/mypy.ini | 15 +++ .../goldens/logging_internal/noxfile.py | 3 - .../tests/integration/goldens/redis/mypy.ini | 15 +++ .../integration/goldens/redis/noxfile.py | 3 - .../goldens/redis_selective/mypy.ini | 15 +++ .../goldens/redis_selective/noxfile.py | 3 - .../goldens/storagebatchoperations/mypy.ini | 15 +++ .../goldens/storagebatchoperations/noxfile.py | 3 - .../cloud/datastore_admin_v1/__init__.py | 8 +- .../google/cloud/datastore_v1/__init__.py | 8 +- packages/google-cloud-datastore/mypy.ini | 23 ++++ packages/google-cloud-datastore/noxfile.py | 3 - packages/google-cloud-datastore/setup.py | 12 +- .../testing/constraints-3.10.txt | 6 +- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- 30 files changed, 215 insertions(+), 167 deletions(-) delete mode 100644 mypy.ini create mode 100644 packages/gapic-generator/gapic/ads-templates/mypy.ini.j2 create mode 100644 packages/gapic-generator/gapic/templates/mypy.ini.j2 create mode 100755 packages/gapic-generator/tests/integration/goldens/asset/mypy.ini create mode 100755 packages/gapic-generator/tests/integration/goldens/credentials/mypy.ini create mode 100755 packages/gapic-generator/tests/integration/goldens/eventarc/mypy.ini create mode 100755 packages/gapic-generator/tests/integration/goldens/logging/mypy.ini create mode 100755 packages/gapic-generator/tests/integration/goldens/logging_internal/mypy.ini create mode 100755 packages/gapic-generator/tests/integration/goldens/redis/mypy.ini create mode 100755 packages/gapic-generator/tests/integration/goldens/redis_selective/mypy.ini create mode 100755 packages/gapic-generator/tests/integration/goldens/storagebatchoperations/mypy.ini create mode 100644 packages/google-cloud-datastore/mypy.ini diff --git a/.librarian/generator-input/client-post-processing/datastore-integration.yaml b/.librarian/generator-input/client-post-processing/datastore-integration.yaml index aca5e5845036..7d81275e77c0 100644 --- a/.librarian/generator-input/client-post-processing/datastore-integration.yaml +++ b/.librarian/generator-input/client-post-processing/datastore-integration.yaml @@ -39,6 +39,42 @@ replacements: "google-cloud-core >= 2.0.0, <3.0.0", "grpcio >= 1.59.0, < 2.0.0", count: 1 + - paths: [ + "packages/google-cloud-datastore/mypy.ini", + ] + before: |- + # Performance: reuse results from previous runs to speed up 'nox' + incremental = True + after: |- + # Performance: reuse results from previous runs to speed up "nox" + incremental = True + + [mypy-google.cloud.datastore._app_engine_key_pb2] + ignore_errors = True + + # TODO(https://github.com/googleapis/gapic-generator-python/issues/2410): + # Remove once this generator bug is fixed + [mypy-google.cloud.datastore_v1.services.datastore.async_client] + ignore_errors = True + + # TODO(https://github.com/googleapis/gapic-generator-python/issues/2410): + # Remove once this generator bug is fixed + [mypy-google.cloud.datastore_v1.services.datastore.client] + ignore_errors = True + count: 1 + - paths: [ + "packages/google-cloud-datastore/mypy.ini", + ] + before: | + ignore_missing_imports = False + + # TODO\(https://github.com/googleapis/gapic-generator-python/issues/2563\): + # Dependencies that historically lacks py.typed markers + \[mypy-google\.iam\.\*\] + ignore_missing_imports = True + after: | + ignore_missing_imports = True + count: 1 - paths: [ "packages/google-cloud-datastore/docs/index.rst", ] diff --git a/mypy.ini b/mypy.ini deleted file mode 100644 index 9c9bb9d52935..000000000000 --- a/mypy.ini +++ /dev/null @@ -1,110 +0,0 @@ -[mypy] -namespace_packages = True -ignore_missing_imports = False - -# Helps mypy navigate the "google" namespace more reliably in 3.10+ -explicit_package_bases = True - -# Performance: reuse results from previous runs to speed up "nox" -incremental = True - -exclude = (?x)( - (^|/)third_party/ - | (^|/)tests/unit/resources/ - | (^|/)tests/unit/gapic/ - ) - - -# ============================================================================== -# GLOBAL THIRD-PARTY & SHARED LIBRARY IGNORES -# ============================================================================== - -[mypy-anywidget] -ignore_missing_imports = True - -[mypy-cloudpickle.*] -ignore_missing_imports = True - -[mypy-flask] -ignore_missing_imports = True - -[mypy-google.auth.*] -ignore_missing_imports = True - -[mypy-google.cloud.bigtable] -ignore_missing_imports = True - -[mypy-google.cloud.pubsub] -ignore_missing_imports = True - -[mypy-google.colab] -ignore_missing_imports = True - -[mypy-google.iam.*] -ignore_missing_imports = True - -[mypy-google.longrunning.*] -ignore_missing_imports = True - -[mypy-google.oauth2.*] -ignore_missing_imports = True - -[mypy-google.protobuf.*] -ignore_missing_imports = True - -[mypy-google.rpc.*] -ignore_missing_imports = True - -[mypy-google.type.*] -ignore_missing_imports = True - -[mypy-grpc.*] -ignore_missing_imports = True - -[mypy-ibis.*] -ignore_missing_imports = True - -[mypy-ipywidgets] -ignore_missing_imports = True - -[mypy-proto.*] -ignore_missing_imports = True - -[mypy-pyarrow.*] -ignore_missing_imports = True - -[mypy-pydata_google_auth] -ignore_missing_imports = True - -[mypy-pytest] -ignore_missing_imports = True - -[mypy-pytz] -ignore_missing_imports = True - - -# ============================================================================== -# PACKAGE-SPECIFIC OVERRIDES & EXCEPTIONS -# ============================================================================== - -# --- google-cloud-bigtable --- -[mypy-google.cloud.bigtable.*] -ignore_errors = True - -[mypy-google.cloud.bigtable.data.*] -check_untyped_defs = True -warn_unreachable = True -disallow_any_generics = True -ignore_errors = False - -# --- google-cloud-datastore --- -[mypy-google.cloud.datastore._app_engine_key_pb2] -ignore_errors = True - -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2410): -# Remove once this generator bug is fixed -[mypy-google.cloud.datastore_v1.services.datastore.async_client] -ignore_errors = True - -[mypy-google.cloud.datastore_v1.services.datastore.client] -ignore_errors = True diff --git a/packages/gapic-generator/gapic/ads-templates/mypy.ini.j2 b/packages/gapic-generator/gapic/ads-templates/mypy.ini.j2 new file mode 100644 index 000000000000..cb397f571128 --- /dev/null +++ b/packages/gapic-generator/gapic/ads-templates/mypy.ini.j2 @@ -0,0 +1,3 @@ +[mypy] +python_version = 3.10 +namespace_packages = True diff --git a/packages/gapic-generator/gapic/ads-templates/noxfile.py.j2 b/packages/gapic-generator/gapic/ads-templates/noxfile.py.j2 index 13b37159d38a..0a42cd6e4fa0 100644 --- a/packages/gapic-generator/gapic/ads-templates/noxfile.py.j2 +++ b/packages/gapic-generator/gapic/ads-templates/noxfile.py.j2 @@ -3,16 +3,10 @@ {% block content %} import os -import pathlib import nox # type: ignore -CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() -# Path to the centralized mypy configuration file at the repository root. -MYPY_CONFIG_FILE = str(CURRENT_DIRECTORY.parent.parent / "mypy.ini") - - # TODO(https://github.com/googleapis/gapic-generator-python/issues/2450): # Add tests for Python 3.15 alpha1 # https://peps.python.org/pep-0790/ @@ -50,7 +44,6 @@ def mypy(session): session.install('.') session.run( 'mypy', - f"--config-file={MYPY_CONFIG_FILE}", {% if api.naming.module_namespace %} '{{ api.naming.module_namespace[0] }}', {% else %} diff --git a/packages/gapic-generator/gapic/templates/mypy.ini.j2 b/packages/gapic-generator/gapic/templates/mypy.ini.j2 new file mode 100644 index 000000000000..defc5b1ed854 --- /dev/null +++ b/packages/gapic-generator/gapic/templates/mypy.ini.j2 @@ -0,0 +1,15 @@ +[mypy] +python_version = 3.14 +namespace_packages = True +ignore_missing_imports = False + +# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): +# Dependencies that historically lacks py.typed markers +[mypy-google.iam.*] +ignore_missing_imports = True + +# Helps mypy navigate the 'google' namespace more reliably in 3.10+ +explicit_package_bases = True + +# Performance: reuse results from previous runs to speed up 'nox' +incremental = True \ No newline at end of file diff --git a/packages/gapic-generator/gapic/templates/noxfile.py.j2 b/packages/gapic-generator/gapic/templates/noxfile.py.j2 index a11b38f658eb..c240871b994e 100644 --- a/packages/gapic-generator/gapic/templates/noxfile.py.j2 +++ b/packages/gapic-generator/gapic/templates/noxfile.py.j2 @@ -40,8 +40,6 @@ DEFAULT_PYTHON_VERSION = "3.14" PREVIEW_PYTHON_VERSION = "3.14" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() -# Path to the centralized mypy configuration file at the repository root. -MYPY_CONFIG_FILE = str(CURRENT_DIRECTORY.parent.parent / "mypy.ini") if (CURRENT_DIRECTORY / "testing").exists(): LOWER_BOUND_CONSTRAINTS_FILE = ( @@ -103,7 +101,6 @@ def mypy(session): session.install(".") session.run( "mypy", - f"--config-file={MYPY_CONFIG_FILE}", "-p", {% if api.naming.module_namespace %} "{{ api.naming.module_namespace[0] }}", diff --git a/packages/gapic-generator/tests/integration/goldens/asset/mypy.ini b/packages/gapic-generator/tests/integration/goldens/asset/mypy.ini new file mode 100755 index 000000000000..e0e0da2e9e40 --- /dev/null +++ b/packages/gapic-generator/tests/integration/goldens/asset/mypy.ini @@ -0,0 +1,15 @@ +[mypy] +python_version = 3.14 +namespace_packages = True +ignore_missing_imports = False + +# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): +# Dependencies that historically lacks py.typed markers +[mypy-google.iam.*] +ignore_missing_imports = True + +# Helps mypy navigate the 'google' namespace more reliably in 3.10+ +explicit_package_bases = True + +# Performance: reuse results from previous runs to speed up 'nox' +incremental = True diff --git a/packages/gapic-generator/tests/integration/goldens/asset/noxfile.py b/packages/gapic-generator/tests/integration/goldens/asset/noxfile.py index bdbc94d16aad..93e185b59d11 100755 --- a/packages/gapic-generator/tests/integration/goldens/asset/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/asset/noxfile.py @@ -47,8 +47,6 @@ PREVIEW_PYTHON_VERSION = "3.14" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() -# Path to the centralized mypy configuration file at the repository root. -MYPY_CONFIG_FILE = str(CURRENT_DIRECTORY.parent.parent / "mypy.ini") if (CURRENT_DIRECTORY / "testing").exists(): LOWER_BOUND_CONSTRAINTS_FILE = ( @@ -110,7 +108,6 @@ def mypy(session): session.install(".") session.run( "mypy", - f"--config-file={MYPY_CONFIG_FILE}", "-p", "google", "--check-untyped-defs", diff --git a/packages/gapic-generator/tests/integration/goldens/credentials/mypy.ini b/packages/gapic-generator/tests/integration/goldens/credentials/mypy.ini new file mode 100755 index 000000000000..e0e0da2e9e40 --- /dev/null +++ b/packages/gapic-generator/tests/integration/goldens/credentials/mypy.ini @@ -0,0 +1,15 @@ +[mypy] +python_version = 3.14 +namespace_packages = True +ignore_missing_imports = False + +# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): +# Dependencies that historically lacks py.typed markers +[mypy-google.iam.*] +ignore_missing_imports = True + +# Helps mypy navigate the 'google' namespace more reliably in 3.10+ +explicit_package_bases = True + +# Performance: reuse results from previous runs to speed up 'nox' +incremental = True diff --git a/packages/gapic-generator/tests/integration/goldens/credentials/noxfile.py b/packages/gapic-generator/tests/integration/goldens/credentials/noxfile.py index dacd23460373..c991842b24ca 100755 --- a/packages/gapic-generator/tests/integration/goldens/credentials/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/credentials/noxfile.py @@ -47,8 +47,6 @@ PREVIEW_PYTHON_VERSION = "3.14" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() -# Path to the centralized mypy configuration file at the repository root. -MYPY_CONFIG_FILE = str(CURRENT_DIRECTORY.parent.parent / "mypy.ini") if (CURRENT_DIRECTORY / "testing").exists(): LOWER_BOUND_CONSTRAINTS_FILE = ( @@ -110,7 +108,6 @@ def mypy(session): session.install(".") session.run( "mypy", - f"--config-file={MYPY_CONFIG_FILE}", "-p", "google", "--check-untyped-defs", diff --git a/packages/gapic-generator/tests/integration/goldens/eventarc/mypy.ini b/packages/gapic-generator/tests/integration/goldens/eventarc/mypy.ini new file mode 100755 index 000000000000..e0e0da2e9e40 --- /dev/null +++ b/packages/gapic-generator/tests/integration/goldens/eventarc/mypy.ini @@ -0,0 +1,15 @@ +[mypy] +python_version = 3.14 +namespace_packages = True +ignore_missing_imports = False + +# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): +# Dependencies that historically lacks py.typed markers +[mypy-google.iam.*] +ignore_missing_imports = True + +# Helps mypy navigate the 'google' namespace more reliably in 3.10+ +explicit_package_bases = True + +# Performance: reuse results from previous runs to speed up 'nox' +incremental = True diff --git a/packages/gapic-generator/tests/integration/goldens/eventarc/noxfile.py b/packages/gapic-generator/tests/integration/goldens/eventarc/noxfile.py index d950dd9d285b..1ec5368a9dd4 100755 --- a/packages/gapic-generator/tests/integration/goldens/eventarc/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/eventarc/noxfile.py @@ -47,8 +47,6 @@ PREVIEW_PYTHON_VERSION = "3.14" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() -# Path to the centralized mypy configuration file at the repository root. -MYPY_CONFIG_FILE = str(CURRENT_DIRECTORY.parent.parent / "mypy.ini") if (CURRENT_DIRECTORY / "testing").exists(): LOWER_BOUND_CONSTRAINTS_FILE = ( @@ -110,7 +108,6 @@ def mypy(session): session.install(".") session.run( "mypy", - f"--config-file={MYPY_CONFIG_FILE}", "-p", "google", "--check-untyped-defs", diff --git a/packages/gapic-generator/tests/integration/goldens/logging/mypy.ini b/packages/gapic-generator/tests/integration/goldens/logging/mypy.ini new file mode 100755 index 000000000000..e0e0da2e9e40 --- /dev/null +++ b/packages/gapic-generator/tests/integration/goldens/logging/mypy.ini @@ -0,0 +1,15 @@ +[mypy] +python_version = 3.14 +namespace_packages = True +ignore_missing_imports = False + +# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): +# Dependencies that historically lacks py.typed markers +[mypy-google.iam.*] +ignore_missing_imports = True + +# Helps mypy navigate the 'google' namespace more reliably in 3.10+ +explicit_package_bases = True + +# Performance: reuse results from previous runs to speed up 'nox' +incremental = True diff --git a/packages/gapic-generator/tests/integration/goldens/logging/noxfile.py b/packages/gapic-generator/tests/integration/goldens/logging/noxfile.py index 7296b5795a8b..448aec3ef2b0 100755 --- a/packages/gapic-generator/tests/integration/goldens/logging/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/logging/noxfile.py @@ -47,8 +47,6 @@ PREVIEW_PYTHON_VERSION = "3.14" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() -# Path to the centralized mypy configuration file at the repository root. -MYPY_CONFIG_FILE = str(CURRENT_DIRECTORY.parent.parent / "mypy.ini") if (CURRENT_DIRECTORY / "testing").exists(): LOWER_BOUND_CONSTRAINTS_FILE = ( @@ -110,7 +108,6 @@ def mypy(session): session.install(".") session.run( "mypy", - f"--config-file={MYPY_CONFIG_FILE}", "-p", "google", "--check-untyped-defs", diff --git a/packages/gapic-generator/tests/integration/goldens/logging_internal/mypy.ini b/packages/gapic-generator/tests/integration/goldens/logging_internal/mypy.ini new file mode 100755 index 000000000000..e0e0da2e9e40 --- /dev/null +++ b/packages/gapic-generator/tests/integration/goldens/logging_internal/mypy.ini @@ -0,0 +1,15 @@ +[mypy] +python_version = 3.14 +namespace_packages = True +ignore_missing_imports = False + +# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): +# Dependencies that historically lacks py.typed markers +[mypy-google.iam.*] +ignore_missing_imports = True + +# Helps mypy navigate the 'google' namespace more reliably in 3.10+ +explicit_package_bases = True + +# Performance: reuse results from previous runs to speed up 'nox' +incremental = True diff --git a/packages/gapic-generator/tests/integration/goldens/logging_internal/noxfile.py b/packages/gapic-generator/tests/integration/goldens/logging_internal/noxfile.py index 7296b5795a8b..448aec3ef2b0 100755 --- a/packages/gapic-generator/tests/integration/goldens/logging_internal/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/logging_internal/noxfile.py @@ -47,8 +47,6 @@ PREVIEW_PYTHON_VERSION = "3.14" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() -# Path to the centralized mypy configuration file at the repository root. -MYPY_CONFIG_FILE = str(CURRENT_DIRECTORY.parent.parent / "mypy.ini") if (CURRENT_DIRECTORY / "testing").exists(): LOWER_BOUND_CONSTRAINTS_FILE = ( @@ -110,7 +108,6 @@ def mypy(session): session.install(".") session.run( "mypy", - f"--config-file={MYPY_CONFIG_FILE}", "-p", "google", "--check-untyped-defs", diff --git a/packages/gapic-generator/tests/integration/goldens/redis/mypy.ini b/packages/gapic-generator/tests/integration/goldens/redis/mypy.ini new file mode 100755 index 000000000000..e0e0da2e9e40 --- /dev/null +++ b/packages/gapic-generator/tests/integration/goldens/redis/mypy.ini @@ -0,0 +1,15 @@ +[mypy] +python_version = 3.14 +namespace_packages = True +ignore_missing_imports = False + +# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): +# Dependencies that historically lacks py.typed markers +[mypy-google.iam.*] +ignore_missing_imports = True + +# Helps mypy navigate the 'google' namespace more reliably in 3.10+ +explicit_package_bases = True + +# Performance: reuse results from previous runs to speed up 'nox' +incremental = True diff --git a/packages/gapic-generator/tests/integration/goldens/redis/noxfile.py b/packages/gapic-generator/tests/integration/goldens/redis/noxfile.py index ca0b6b791d68..d860093c9653 100755 --- a/packages/gapic-generator/tests/integration/goldens/redis/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/redis/noxfile.py @@ -47,8 +47,6 @@ PREVIEW_PYTHON_VERSION = "3.14" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() -# Path to the centralized mypy configuration file at the repository root. -MYPY_CONFIG_FILE = str(CURRENT_DIRECTORY.parent.parent / "mypy.ini") if (CURRENT_DIRECTORY / "testing").exists(): LOWER_BOUND_CONSTRAINTS_FILE = ( @@ -110,7 +108,6 @@ def mypy(session): session.install(".") session.run( "mypy", - f"--config-file={MYPY_CONFIG_FILE}", "-p", "google", "--check-untyped-defs", diff --git a/packages/gapic-generator/tests/integration/goldens/redis_selective/mypy.ini b/packages/gapic-generator/tests/integration/goldens/redis_selective/mypy.ini new file mode 100755 index 000000000000..e0e0da2e9e40 --- /dev/null +++ b/packages/gapic-generator/tests/integration/goldens/redis_selective/mypy.ini @@ -0,0 +1,15 @@ +[mypy] +python_version = 3.14 +namespace_packages = True +ignore_missing_imports = False + +# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): +# Dependencies that historically lacks py.typed markers +[mypy-google.iam.*] +ignore_missing_imports = True + +# Helps mypy navigate the 'google' namespace more reliably in 3.10+ +explicit_package_bases = True + +# Performance: reuse results from previous runs to speed up 'nox' +incremental = True diff --git a/packages/gapic-generator/tests/integration/goldens/redis_selective/noxfile.py b/packages/gapic-generator/tests/integration/goldens/redis_selective/noxfile.py index ca0b6b791d68..d860093c9653 100755 --- a/packages/gapic-generator/tests/integration/goldens/redis_selective/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/redis_selective/noxfile.py @@ -47,8 +47,6 @@ PREVIEW_PYTHON_VERSION = "3.14" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() -# Path to the centralized mypy configuration file at the repository root. -MYPY_CONFIG_FILE = str(CURRENT_DIRECTORY.parent.parent / "mypy.ini") if (CURRENT_DIRECTORY / "testing").exists(): LOWER_BOUND_CONSTRAINTS_FILE = ( @@ -110,7 +108,6 @@ def mypy(session): session.install(".") session.run( "mypy", - f"--config-file={MYPY_CONFIG_FILE}", "-p", "google", "--check-untyped-defs", diff --git a/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/mypy.ini b/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/mypy.ini new file mode 100755 index 000000000000..e0e0da2e9e40 --- /dev/null +++ b/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/mypy.ini @@ -0,0 +1,15 @@ +[mypy] +python_version = 3.14 +namespace_packages = True +ignore_missing_imports = False + +# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): +# Dependencies that historically lacks py.typed markers +[mypy-google.iam.*] +ignore_missing_imports = True + +# Helps mypy navigate the 'google' namespace more reliably in 3.10+ +explicit_package_bases = True + +# Performance: reuse results from previous runs to speed up 'nox' +incremental = True diff --git a/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/noxfile.py b/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/noxfile.py index 141088cbacc3..9afec5aeae68 100755 --- a/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/noxfile.py @@ -47,8 +47,6 @@ PREVIEW_PYTHON_VERSION = "3.14" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() -# Path to the centralized mypy configuration file at the repository root. -MYPY_CONFIG_FILE = str(CURRENT_DIRECTORY.parent.parent / "mypy.ini") if (CURRENT_DIRECTORY / "testing").exists(): LOWER_BOUND_CONSTRAINTS_FILE = ( @@ -110,7 +108,6 @@ def mypy(session): session.install(".") session.run( "mypy", - f"--config-file={MYPY_CONFIG_FILE}", "-p", "google", "--check-untyped-defs", diff --git a/packages/google-cloud-datastore/google/cloud/datastore_admin_v1/__init__.py b/packages/google-cloud-datastore/google/cloud/datastore_admin_v1/__init__.py index e6209583615b..ab92fd717567 100644 --- a/packages/google-cloud-datastore/google/cloud/datastore_admin_v1/__init__.py +++ b/packages/google-cloud-datastore/google/cloud/datastore_admin_v1/__init__.py @@ -75,7 +75,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "6.33.5" -> (6, 33, 5) + Example: "4.25.8" -> (4, 25, 8) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -104,9 +104,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "6.33.5" - _next_supported_version_tuple = (6, 33, 5) - _recommendation = " (we recommend 7.x)" + _next_supported_version = "4.25.8" + _next_supported_version_tuple = (4, 25, 8) + _recommendation = " (we recommend 6.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-datastore/google/cloud/datastore_v1/__init__.py b/packages/google-cloud-datastore/google/cloud/datastore_v1/__init__.py index 7017a18c095c..7e8f2602291d 100644 --- a/packages/google-cloud-datastore/google/cloud/datastore_v1/__init__.py +++ b/packages/google-cloud-datastore/google/cloud/datastore_v1/__init__.py @@ -98,7 +98,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "6.33.5" -> (6, 33, 5) + Example: "4.25.8" -> (4, 25, 8) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -127,9 +127,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "6.33.5" - _next_supported_version_tuple = (6, 33, 5) - _recommendation = " (we recommend 7.x)" + _next_supported_version = "4.25.8" + _next_supported_version_tuple = (4, 25, 8) + _recommendation = " (we recommend 6.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-datastore/mypy.ini b/packages/google-cloud-datastore/mypy.ini new file mode 100644 index 000000000000..2d553926db9d --- /dev/null +++ b/packages/google-cloud-datastore/mypy.ini @@ -0,0 +1,23 @@ +[mypy] +python_version = 3.14 +namespace_packages = True +ignore_missing_imports = True + +# Helps mypy navigate the 'google' namespace more reliably in 3.10+ +explicit_package_bases = True + +# Performance: reuse results from previous runs to speed up "nox" +incremental = True + +[mypy-google.cloud.datastore._app_engine_key_pb2] +ignore_errors = True + +# TODO(https://github.com/googleapis/gapic-generator-python/issues/2410): +# Remove once this generator bug is fixed +[mypy-google.cloud.datastore_v1.services.datastore.async_client] +ignore_errors = True + +# TODO(https://github.com/googleapis/gapic-generator-python/issues/2410): +# Remove once this generator bug is fixed +[mypy-google.cloud.datastore_v1.services.datastore.client] +ignore_errors = True diff --git a/packages/google-cloud-datastore/noxfile.py b/packages/google-cloud-datastore/noxfile.py index 9e9c06b33b12..af42d740478e 100644 --- a/packages/google-cloud-datastore/noxfile.py +++ b/packages/google-cloud-datastore/noxfile.py @@ -46,8 +46,6 @@ PREVIEW_PYTHON_VERSION = "3.14" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() -# Path to the centralized mypy configuration file at the repository root. -MYPY_CONFIG_FILE = str(CURRENT_DIRECTORY.parent.parent / "mypy.ini") if (CURRENT_DIRECTORY / "testing").exists(): LOWER_BOUND_CONSTRAINTS_FILE = ( @@ -109,7 +107,6 @@ def mypy(session): session.install(".") session.run( "mypy", - f"--config-file={MYPY_CONFIG_FILE}", "-p", "google", # TODO(https://github.com/googleapis/google-cloud-python/issues/16083) diff --git a/packages/google-cloud-datastore/setup.py b/packages/google-cloud-datastore/setup.py index 26f21974303e..b0cac8c0ec50 100644 --- a/packages/google-cloud-datastore/setup.py +++ b/packages/google-cloud-datastore/setup.py @@ -29,10 +29,7 @@ version = None with open(os.path.join(package_root, "google/cloud/datastore/gapic_version.py")) as fp: - version_candidates = re.findall( - r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", - fp.read(), - ) + version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) assert len(version_candidates) == 1 version = version_candidates[0] @@ -42,15 +39,16 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.24.2, <3.0.0", + "google-api-core[grpc] >= 2.17.1, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "google-cloud-core >= 2.0.0, <3.0.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.26.1, <2.0.0", - "protobuf >= 6.33.5, < 8.0.0", + "proto-plus >= 1.22.3, <2.0.0", + "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", + "protobuf >= 4.25.8, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-datastore" diff --git a/packages/google-cloud-datastore/testing/constraints-3.10.txt b/packages/google-cloud-datastore/testing/constraints-3.10.txt index 81605a716d32..7be9c36933fc 100644 --- a/packages/google-cloud-datastore/testing/constraints-3.10.txt +++ b/packages/google-cloud-datastore/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.24.2 +google-api-core==2.17.1 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.26.1 -protobuf==6.33.5 +proto-plus==1.22.3 +protobuf==4.25.8 diff --git a/packages/google-cloud-datastore/testing/constraints-3.13.txt b/packages/google-cloud-datastore/testing/constraints-3.13.txt index 6bd7e1f5b03d..1e93c60e50aa 100644 --- a/packages/google-cloud-datastore/testing/constraints-3.13.txt +++ b/packages/google-cloud-datastore/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=7 +protobuf>=6 diff --git a/packages/google-cloud-datastore/testing/constraints-3.14.txt b/packages/google-cloud-datastore/testing/constraints-3.14.txt index 6bd7e1f5b03d..1e93c60e50aa 100644 --- a/packages/google-cloud-datastore/testing/constraints-3.14.txt +++ b/packages/google-cloud-datastore/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=7 +protobuf>=6 From 6f99e230fc523ae15068d172e31c956e4c1894e4 Mon Sep 17 00:00:00 2001 From: Cody Oss <6331106+codyoss@users.noreply.github.com> Date: Wed, 17 Jun 2026 13:29:59 -0500 Subject: [PATCH 094/174] chore: separate release-please prs for individual config (#17491) --- release-please-individual-config.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/release-please-individual-config.json b/release-please-individual-config.json index f61d64328f0c..793e723414a4 100644 --- a/release-please-individual-config.json +++ b/release-please-individual-config.json @@ -49,5 +49,6 @@ "component": "sqlalchemy-bigquery" } }, - "release-type": "python-librarian" -} \ No newline at end of file + "release-type": "python-librarian", + "separate-pull-requests": true +} From 4f5593a520b5afdeb02cc28f19a9596dbc35a90f Mon Sep 17 00:00:00 2001 From: Shuowei Li Date: Thu, 18 Jun 2026 01:05:09 +0000 Subject: [PATCH 095/174] fix: handle empty endpoints during cloud function reuse (#17501) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes an issue where reusing recently created Cloud Functions during Remote Function creation would sometimes result in an empty endpoint (`endpoint=""`). When a Cloud Function has been recently provisioned, its endpoint URI (`response.service_config.uri`) may occasionally be returned as an empty string if URL propagation is still pending. The remote function decorator previously only checked for `None`, proceeding to create the BigQuery Remote Function with `OPTIONS(endpoint='')`, which leads to validation failures when queries invoke the function. This PR changes the check to `if not cf_endpoint:` to handle both `None` and empty strings. If the endpoint is empty, it will route to `create_cloud_function`, which catches the `AlreadyExists` exception and safely retries/waits for the endpoint URI propagation to complete. Fixes #<525124882> 🦕 --- packages/bigframes/bigframes/functions/_function_session.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/bigframes/bigframes/functions/_function_session.py b/packages/bigframes/bigframes/functions/_function_session.py index e369b0b39bfd..213ac6638490 100644 --- a/packages/bigframes/bigframes/functions/_function_session.py +++ b/packages/bigframes/bigframes/functions/_function_session.py @@ -592,7 +592,9 @@ def wrapper(func): if reuse is not None: cf_endpoint = self._function_client.get_cloud_function_endpoint(cf_name) - if cf_endpoint is None: + # If the endpoint is empty, the function might exist but the URL propagation is pending. + # Running create_cloud_function will handle AlreadyExists and retry endpoint fetching. + if not cf_endpoint: cf_endpoint = self._function_client.create_cloud_function( cf_name, cloud_func_spec ) From 3b79caa8f40f61ccd7c655542e9f242f34e068e2 Mon Sep 17 00:00:00 2001 From: Shuowei Li Date: Thu, 18 Jun 2026 01:25:46 +0000 Subject: [PATCH 096/174] fix: avoid invalid CAST(NULL AS NULL) in SQLGlot compiler (#17487) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR resolves a compilation crash caused by the SQLGlot compiler attempting to generate an invalid CAST(NULL AS NULL) statement in BigQuery, which triggers a syntax/validation error (e.g., Unexpected keyword NULL). Fixes #<524701452> 🦕 --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- .../bigframes/core/compile/sqlglot/sql/base.py | 2 ++ .../tests/unit/core/compile/sqlglot/sql/test_base.py | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/packages/bigframes/bigframes/core/compile/sqlglot/sql/base.py b/packages/bigframes/bigframes/core/compile/sqlglot/sql/base.py index 8b5eb748f575..f77dcbee4d93 100644 --- a/packages/bigframes/bigframes/core/compile/sqlglot/sql/base.py +++ b/packages/bigframes/bigframes/core/compile/sqlglot/sql/base.py @@ -69,6 +69,8 @@ def literal(value: typing.Any, dtype: dtypes.Dtype | None = None) -> sge.Express return sge.Null() if value is None: + if str(sqlglot_type).upper() == "NULL": + return sge.Null() return cast(sge.Null(), sqlglot_type) if dtypes.is_struct_like(dtype): items = [ diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/sql/test_base.py b/packages/bigframes/tests/unit/core/compile/sqlglot/sql/test_base.py index 5ba77d925d0f..617f3636d403 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/sql/test_base.py +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/sql/test_base.py @@ -159,3 +159,15 @@ def test_literal_explicit_dtype(value, dtype, expected): def test_literal_for_list(value: list, expected: str): got = sql.to_sql(sql.literal(value)) assert got == expected + + +def test_literal_null_type(): + import unittest.mock as mock + + mock_dtype = mock.Mock() + with mock.patch( + "bigframes.core.compile.sqlglot.sql.base.sgt.from_bigframes_dtype", + return_value="NULL", + ): + got = sql.to_sql(sql.literal(None, dtype=mock_dtype)) + assert got == "NULL" From 1890637d24280c7fe26747bcfaa557b529d85467 Mon Sep 17 00:00:00 2001 From: Min Zhu Date: Thu, 18 Jun 2026 10:27:02 -0400 Subject: [PATCH 097/174] chore: re-generate all (#17505) Re-generate all in attempt to restore repo to "clean" state where config in librarian.yaml and generated code matches. Run below commands. ``` V=$(go run github.com/googleapis/librarian/cmd/librarian@latest config get version) go run github.com/googleapis/librarian/tool/cmd/builddockerimages@latest --language python --version=${V} docker run -u $(id -u):$(id -g) -v .:/repo -v ~/.cache:/.cache -w /repo docker.io/library/librarian-python:${V} generate -v --all ``` Fixes https://github.com/googleapis/google-cloud-python/issues/17426, https://github.com/googleapis/google-cloud-python/issues/17427 --- packages/google-cloud-pubsub/README.rst | 4 ++++ .../google/cloud/pubsub_v1/subscriber/_protocol/leaser.py | 6 ++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/google-cloud-pubsub/README.rst b/packages/google-cloud-pubsub/README.rst index 3fe8a71491f0..7717a22044c4 100644 --- a/packages/google-cloud-pubsub/README.rst +++ b/packages/google-cloud-pubsub/README.rst @@ -67,6 +67,10 @@ Python >= 3.10, including 3.14 .. _active: https://devguide.python.org/devcycle/#in-development-main-branch .. _maintenance: https://devguide.python.org/devcycle/#maintenance-branches +Unsupported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Python <= 3.9 + If you are using an `end-of-life`_ version of Python, we recommend that you update as soon as possible to an actively supported version. diff --git a/packages/google-cloud-pubsub/google/cloud/pubsub_v1/subscriber/_protocol/leaser.py b/packages/google-cloud-pubsub/google/cloud/pubsub_v1/subscriber/_protocol/leaser.py index 1e241d21d81d..2f9a8ac20d02 100644 --- a/packages/google-cloud-pubsub/google/cloud/pubsub_v1/subscriber/_protocol/leaser.py +++ b/packages/google-cloud-pubsub/google/cloud/pubsub_v1/subscriber/_protocol/leaser.py @@ -20,16 +20,14 @@ import threading import time import typing +from collections.abc import KeysView from typing import Dict, Iterable, Optional, Union from google.cloud.pubsub_v1.open_telemetry.subscribe_opentelemetry import ( SubscribeOpenTelemetry, ) -from google.cloud.pubsub_v1.subscriber._protocol.dispatcher import _MAX_BATCH_LATENCY - -from collections.abc import KeysView - from google.cloud.pubsub_v1.subscriber._protocol import requests +from google.cloud.pubsub_v1.subscriber._protocol.dispatcher import _MAX_BATCH_LATENCY if typing.TYPE_CHECKING: # pragma: NO COVER from google.cloud.pubsub_v1.subscriber._protocol.streaming_pull_manager import ( From 690c15d26f78f3c8e221da355c0836399db887b8 Mon Sep 17 00:00:00 2001 From: TrevorBergeron Date: Thu, 18 Jun 2026 11:08:05 -0700 Subject: [PATCH 098/174] refactor(bigframes): Extract json conversions to distinct ops (#17473) --- .../ibis_compiler/scalar_op_registry.py | 53 ++++++++----------- .../bigframes/core/compile/polars/compiler.py | 32 ++++++++--- .../bigframes/core/compile/polars/lowering.py | 4 -- .../sqlglot/expressions/generic_ops.py | 35 ------------ .../compile/sqlglot/expressions/json_ops.py | 37 +++++++++++-- packages/bigframes/bigframes/dataframe.py | 38 ++++++++++--- packages/bigframes/bigframes/dtypes.py | 24 ++++++++- .../bigframes/operations/__init__.py | 2 + .../bigframes/operations/generic_ops.py | 33 ------------ .../bigframes/operations/json_ops.py | 11 +++- packages/bigframes/bigframes/series.py | 14 +++-- .../tests/system/small/bigquery/test_json.py | 2 +- .../system/small/engines/test_generic_ops.py | 20 +++---- .../tests/system/small/test_series.py | 13 +++-- .../test_astype_from_json/out.sql | 8 +-- .../test_generic_ops/test_to_json/out.sql | 8 +++ .../test_json_ops/test_to_json/out.sql | 2 +- .../sqlglot/expressions/test_generic_ops.py | 42 ++++++--------- 18 files changed, 204 insertions(+), 174 deletions(-) create mode 100644 packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_generic_ops/test_to_json/out.sql diff --git a/packages/bigframes/bigframes/core/compile/ibis_compiler/scalar_op_registry.py b/packages/bigframes/bigframes/core/compile/ibis_compiler/scalar_op_registry.py index 5172d1e7c602..3f9fcb5b75df 100644 --- a/packages/bigframes/bigframes/core/compile/ibis_compiler/scalar_op_registry.py +++ b/packages/bigframes/bigframes/core/compile/ibis_compiler/scalar_op_registry.py @@ -922,35 +922,6 @@ def astype_op_impl(x: ibis_types.Value, op: ops.AsTypeOp): elif to_type == ibis_dtypes.time: return x_converted.time() - if to_type == ibis_dtypes.json: - if x.type() == ibis_dtypes.string: - return parse_json_in_safe(x) if op.safe else parse_json(x) - if x.type() == ibis_dtypes.bool: - x_bool = typing.cast( - ibis_types.StringValue, - bigframes.core.compile.ibis_types.cast_ibis_value( - x, ibis_dtypes.string, safe=op.safe - ), - ).lower() - return parse_json_in_safe(x_bool) if op.safe else parse_json(x_bool) - if x.type() in (ibis_dtypes.int64, ibis_dtypes.float64): - x_str = bigframes.core.compile.ibis_types.cast_ibis_value( - x, ibis_dtypes.string, safe=op.safe - ) - return parse_json_in_safe(x_str) if op.safe else parse_json(x_str) - - if x.type() == ibis_dtypes.json: - if to_type == ibis_dtypes.int64: - return cast_json_to_int64_in_safe(x) if op.safe else cast_json_to_int64(x) - if to_type == ibis_dtypes.float64: - return ( - cast_json_to_float64_in_safe(x) if op.safe else cast_json_to_float64(x) - ) - if to_type == ibis_dtypes.bool: - return cast_json_to_bool_in_safe(x) if op.safe else cast_json_to_bool(x) - if to_type == ibis_dtypes.string: - return cast_json_to_string_in_safe(x) if op.safe else cast_json_to_string(x) - # TODO: either inline this function, or push rest of this op into the function return bigframes.core.compile.ibis_types.cast_ibis_value(x, to_type, safe=op.safe) @@ -1193,9 +1164,27 @@ def parse_json_op_impl(x: ibis_types.Value, op: ops.ParseJSON): return parse_json(json_str=x) -@scalar_op_compiler.register_unary_op(ops.ToJSON) -def to_json_op_impl(json_obj: ibis_types.Value): - return to_json(json_obj=json_obj) +@scalar_op_compiler.register_unary_op(ops.ToJSON, pass_op=True) +def to_json_op_impl(x: ibis_types.Value, op: ops.ToJSON): + if x.type() == ibis_dtypes.string: + return parse_json_in_safe(x) if op.safe else parse_json(x) + return x.isnull().ifelse(ibis.null().cast(ibis_dtypes.json), to_json(x)) + + +@scalar_op_compiler.register_unary_op(ops.JSONDecode, pass_op=True) +def json_decode_op_impl(x: ibis_types.Value, op: ops.JSONDecode): + to_type = bigframes.core.compile.ibis_types.bigframes_dtype_to_ibis_dtype( + op.to_type + ) + if to_type == ibis_dtypes.int64: + return cast_json_to_int64_in_safe(x) if op.safe else cast_json_to_int64(x) + if to_type == ibis_dtypes.float64: + return cast_json_to_float64_in_safe(x) if op.safe else cast_json_to_float64(x) + if to_type == ibis_dtypes.bool: + return cast_json_to_bool_in_safe(x) if op.safe else cast_json_to_bool(x) + if to_type == ibis_dtypes.string: + return cast_json_to_string_in_safe(x) if op.safe else cast_json_to_string(x) + raise TypeError(f"Cannot cast from JSON to type {to_type}") @scalar_op_compiler.register_unary_op(ops.ToJSONString) diff --git a/packages/bigframes/bigframes/core/compile/polars/compiler.py b/packages/bigframes/bigframes/core/compile/polars/compiler.py index 6f24929eeb4e..2477f27b6432 100644 --- a/packages/bigframes/bigframes/core/compile/polars/compiler.py +++ b/packages/bigframes/bigframes/core/compile/polars/compiler.py @@ -138,11 +138,20 @@ class PolarsExpressionCompiler: Should be extended to dispatch based on bigframes schema types. """ - @functools.singledispatchmethod + _expr_types: dict[int, bigframes.dtypes.ExpressionType] = dataclasses.field( + default_factory=dict, init=False, compare=False + ) + def compile_expression(self, expression: ex.Expression) -> pl.Expr: + res = self._compile_expression(expression) + self._expr_types[id(res)] = expression.output_type + return res + + @functools.singledispatchmethod + def _compile_expression(self, expression: ex.Expression) -> pl.Expr: raise NotImplementedError(f"Cannot compile expression: {expression}") - @compile_expression.register + @_compile_expression.register def _( self, expression: ex.ScalarConstantExpression, @@ -159,21 +168,21 @@ def _( return pl.lit(value, _bigframes_dtype_to_polars_dtype(expression.dtype)) - @compile_expression.register + @_compile_expression.register def _( self, expression: ex.DerefOp, ) -> pl.Expr: return pl.col(expression.id.sql) - @compile_expression.register + @_compile_expression.register def _( self, expression: ex.ResolvedDerefOp, ) -> pl.Expr: return pl.col(expression.id.sql) - @compile_expression.register + @_compile_expression.register def _( self, expression: ex.OpExpression, @@ -478,10 +487,21 @@ def _(self, op: ops.ScalarOp, input: pl.Expr) -> pl.Expr: ) @compile_op.register(json_ops.JSONDecode) - def _(self, op: ops.ScalarOp, input: pl.Expr) -> pl.Expr: + def _(self, op: json_ops.JSONDecode, input: pl.Expr) -> pl.Expr: assert isinstance(op, json_ops.JSONDecode) return input.str.json_decode(_DTYPE_MAPPING[op.to_type]) + @compile_op.register(json_ops.ToJSON) + def _(self, op: json_ops.ToJSON, input: pl.Expr) -> pl.Expr: + from_type = self._expr_types.get(id(input)) + if from_type in ( + bigframes.dtypes.STRING_DTYPE, + bigframes.dtypes.JSON_DTYPE, + ): + return input + else: + return input.cast(pl.String()) + @compile_op.register(arr_ops.ToArrayOp) def _(self, op: ops.ToArrayOp, *inputs: pl.Expr) -> pl.Expr: return pl.concat_list(*inputs) diff --git a/packages/bigframes/bigframes/core/compile/polars/lowering.py b/packages/bigframes/bigframes/core/compile/polars/lowering.py index 7416ebc963b4..5b3d9154b731 100644 --- a/packages/bigframes/bigframes/core/compile/polars/lowering.py +++ b/packages/bigframes/bigframes/core/compile/polars/lowering.py @@ -26,7 +26,6 @@ comparison_ops, datetime_ops, generic_ops, - json_ops, numeric_ops, string_ops, ) @@ -412,9 +411,6 @@ def _coerce_comparables( def _lower_cast(cast_op: ops.AsTypeOp, arg: expression.Expression): if arg.output_type == cast_op.to_type: return arg - - if arg.output_type == dtypes.JSON_DTYPE: - return json_ops.JSONDecode(cast_op.to_type).as_expr(arg) if ( arg.output_type == dtypes.STRING_DTYPE and cast_op.to_type == dtypes.DATETIME_DTYPE diff --git a/packages/bigframes/bigframes/core/compile/sqlglot/expressions/generic_ops.py b/packages/bigframes/bigframes/core/compile/sqlglot/expressions/generic_ops.py index 22dcd8bf51ac..2cc27cb8e5a2 100644 --- a/packages/bigframes/bigframes/core/compile/sqlglot/expressions/generic_ops.py +++ b/packages/bigframes/bigframes/core/compile/sqlglot/expressions/generic_ops.py @@ -36,12 +36,6 @@ def _(expr: TypedExpr, op: ops.AsTypeOp) -> sge.Expression: sg_to_type = sqlglot_types.from_bigframes_dtype(to_type) sg_expr = expr.expr - if to_type == dtypes.JSON_DTYPE: - return _cast_to_json(expr, op) - - if from_type == dtypes.JSON_DTYPE: - return _cast_from_json(expr, op) - if to_type == dtypes.INT_DTYPE: result = _cast_to_int(expr, op) if result is not None: @@ -251,35 +245,6 @@ def _(*values: TypedExpr) -> sge.Expression: # Helper functions -def _cast_to_json(expr: TypedExpr, op: ops.AsTypeOp) -> sge.Expression: - from_type = expr.dtype - sg_expr = expr.expr - - if from_type == dtypes.STRING_DTYPE: - func_name = "SAFE.PARSE_JSON" if op.safe else "PARSE_JSON" - return sge.func(func_name, sg_expr) - if from_type in (dtypes.INT_DTYPE, dtypes.BOOL_DTYPE, dtypes.FLOAT_DTYPE): - sg_expr = sge.Cast(this=sg_expr, to="STRING") - return sge.func("PARSE_JSON", sg_expr) - raise TypeError(f"Cannot cast from {from_type} to {dtypes.JSON_DTYPE}") - - -def _cast_from_json(expr: TypedExpr, op: ops.AsTypeOp) -> sge.Expression: - to_type = op.to_type - sg_expr = expr.expr - func_name = "" - if to_type == dtypes.INT_DTYPE: - func_name = "INT64" - elif to_type == dtypes.FLOAT_DTYPE: - func_name = "FLOAT64" - elif to_type == dtypes.BOOL_DTYPE: - func_name = "BOOL" - elif to_type == dtypes.STRING_DTYPE: - func_name = "STRING" - if func_name: - func_name = "SAFE." + func_name if op.safe else func_name - return sge.func(func_name, sg_expr) - raise TypeError(f"Cannot cast from {dtypes.JSON_DTYPE} to {to_type}") def _cast_to_int(expr: TypedExpr, op: ops.AsTypeOp) -> sge.Expression | None: diff --git a/packages/bigframes/bigframes/core/compile/sqlglot/expressions/json_ops.py b/packages/bigframes/bigframes/core/compile/sqlglot/expressions/json_ops.py index f27b1f138d70..f9a92d3d7a6d 100644 --- a/packages/bigframes/bigframes/core/compile/sqlglot/expressions/json_ops.py +++ b/packages/bigframes/bigframes/core/compile/sqlglot/expressions/json_ops.py @@ -17,6 +17,7 @@ import bigframes_vendored.sqlglot.expressions as sge import bigframes.core.compile.sqlglot.expression_compiler as expression_compiler +from bigframes import dtypes from bigframes import operations as ops from bigframes.core.compile.sqlglot.expressions.typed_expr import TypedExpr @@ -69,9 +70,39 @@ def _(expr: TypedExpr) -> sge.Expression: return sge.func("PARSE_JSON", expr.expr) -@register_unary_op(ops.ToJSON) -def _(expr: TypedExpr) -> sge.Expression: - return sge.func("TO_JSON", expr.expr) +@register_unary_op(ops.ToJSON, pass_op=True) +def _(expr: TypedExpr, op: ops.ToJSON) -> sge.Expression: + from_type = expr.dtype + sg_expr = expr.expr + + # Parsing really should be a distinct operation from serialization, but + # this was the way things were intially launched. + if from_type == dtypes.STRING_DTYPE: + func_name = "SAFE.PARSE_JSON" if op.safe else "PARSE_JSON" + return sge.func(func_name, sg_expr) + else: + return sge.func( + "IF", sg_expr.is_(sge.Null()), sge.Null(), sge.func("TO_JSON", sg_expr) + ) + + +@register_unary_op(ops.JSONDecode, pass_op=True) +def _(expr: TypedExpr, op: ops.JSONDecode) -> sge.Expression: + to_type = op.to_type + sg_expr = expr.expr + func_name = "" + if to_type == dtypes.INT_DTYPE: + func_name = "INT64" + elif to_type == dtypes.FLOAT_DTYPE: + func_name = "FLOAT64" + elif to_type == dtypes.BOOL_DTYPE: + func_name = "BOOL" + elif to_type == dtypes.STRING_DTYPE: + func_name = "STRING" + if func_name: + func_name = "SAFE." + func_name if op.safe else func_name + return sge.func(func_name, sg_expr) + raise TypeError(f"Cannot cast from {dtypes.JSON_DTYPE} to {to_type}") @register_unary_op(ops.ToJSONString) diff --git a/packages/bigframes/bigframes/dataframe.py b/packages/bigframes/bigframes/dataframe.py index f5fc7bdfc6b1..e64e640287f2 100644 --- a/packages/bigframes/bigframes/dataframe.py +++ b/packages/bigframes/bigframes/dataframe.py @@ -442,17 +442,41 @@ def astype( if errors not in ["raise", "null"]: raise ValueError("Arg 'error' must be one of 'raise' or 'null'") + if isinstance(dtype, dict): + for col in dtype: + if col not in self.columns: + raise KeyError( + f"Only Column Names are allowed in dtypes dict. '{col}' is not in the columns." + ) + safe_cast = errors == "null" - if isinstance(dtype, dict): - result = self.copy() - for col, to_type in dtype.items(): - result[col] = result[col].astype(to_type) - return result + exprs: list[ex.Expression] = [] + for col_id, col_label in zip( + self._block.value_columns, self._block.column_labels + ): + from_type = self._block._column_type(col_id) - dtype = bigframes.dtypes.bigframes_type(dtype) + if isinstance(dtype, dict): + if col_label not in dtype: + exprs.append(ex.deref(col_id)) + continue + to_type = bigframes.dtypes.bigframes_type(dtype[col_label]) + else: + to_type = bigframes.dtypes.bigframes_type(dtype) + + op: ops.UnaryOp + if to_type == bigframes.dtypes.JSON_DTYPE: + op = ops.ToJSON(safe=safe_cast) + elif from_type == bigframes.dtypes.JSON_DTYPE: + op = ops.JSONDecode(to_type=to_type, safe=safe_cast) + else: + op = ops.AsTypeOp(to_type=to_type, safe=safe_cast) - return self._apply_unary_op(ops.AsTypeOp(dtype, safe_cast)) + exprs.append(op.as_expr(ex.deref(col_id))) + + block = self._block.project_exprs(exprs, labels=self.columns, drop=True) + return DataFrame(block) def _should_sql_have_index(self) -> bool: """Should the SQL we pass to BQML and other I/O include the index?""" diff --git a/packages/bigframes/bigframes/dtypes.py b/packages/bigframes/bigframes/dtypes.py index e7539c59c7d7..51ee96432390 100644 --- a/packages/bigframes/bigframes/dtypes.py +++ b/packages/bigframes/bigframes/dtypes.py @@ -364,10 +364,30 @@ def is_json_like(type_: ExpressionType) -> bool: return type_ == JSON_DTYPE or type_ == STRING_DTYPE # Including JSON string -def is_json_encoding_type(type_: ExpressionType) -> bool: +def is_json_encoding_type(type_: ExpressionType, strict: bool = False) -> bool: # Types can be converted into JSON. # https://cloud.google.com/bigquery/docs/reference/standard-sql/json_functions#json_encodings - return type_ != GEO_DTYPE + if is_array_like(type_): + return is_json_encoding_type(get_array_inner_type(type_), strict=strict) + if is_struct_like(type_): + return all( + is_json_encoding_type(field_type, strict=strict) + for field_type in get_struct_fields(type_).values() + ) + + if strict: + # Strict are the types (mostly) defined by json spec, with no/minimal + # encoding/decoding involved. So no temporal types. + return type_ in ( + INT_DTYPE, + FLOAT_DTYPE, + BOOL_DTYPE, + STRING_DTYPE, + JSON_DTYPE, + ) + else: + # GoogleSQL implementation handles anything but GEO + return type_ != GEO_DTYPE def is_numeric(type_: ExpressionType, include_bool: bool = True) -> bool: diff --git a/packages/bigframes/bigframes/operations/__init__.py b/packages/bigframes/bigframes/operations/__init__.py index b8d860029a0f..a493e7a755bf 100644 --- a/packages/bigframes/bigframes/operations/__init__.py +++ b/packages/bigframes/bigframes/operations/__init__.py @@ -128,6 +128,7 @@ ) from bigframes.operations.googlesql import GoogleSqlScalarOp from bigframes.operations.json_ops import ( + JSONDecode, JSONExtract, JSONExtractArray, JSONExtractStringArray, @@ -382,6 +383,7 @@ "FloorDtOp", "IntegerLabelToDatetimeOp", # JSON ops + "JSONDecode", "JSONExtract", "JSONExtractArray", "JSONExtractStringArray", diff --git a/packages/bigframes/bigframes/operations/generic_ops.py b/packages/bigframes/bigframes/operations/generic_ops.py index 9a58f4b8ef33..99cda5fc095f 100644 --- a/packages/bigframes/bigframes/operations/generic_ops.py +++ b/packages/bigframes/bigframes/operations/generic_ops.py @@ -93,10 +93,6 @@ dtypes.STRING_DTYPE, dtypes.INT_DTYPE, ), - ( - dtypes.JSON_DTYPE, - dtypes.INT_DTYPE, - ), # Float casts ( dtypes.BOOL_DTYPE, @@ -118,10 +114,6 @@ dtypes.STRING_DTYPE, dtypes.FLOAT_DTYPE, ), - ( - dtypes.JSON_DTYPE, - dtypes.FLOAT_DTYPE, - ), # Bool casts ( dtypes.INT_DTYPE, @@ -131,10 +123,6 @@ dtypes.FLOAT_DTYPE, dtypes.BOOL_DTYPE, ), - ( - dtypes.JSON_DTYPE, - dtypes.BOOL_DTYPE, - ), # String casts ( dtypes.BYTES_DTYPE, @@ -168,10 +156,6 @@ dtypes.DATE_DTYPE, dtypes.STRING_DTYPE, ), - ( - dtypes.JSON_DTYPE, - dtypes.STRING_DTYPE, - ), # bytes casts ( dtypes.STRING_DTYPE, @@ -276,23 +260,6 @@ dtypes.INT_DTYPE, dtypes.TIMEDELTA_DTYPE, ), - # json casts - ( - dtypes.BOOL_DTYPE, - dtypes.JSON_DTYPE, - ), - ( - dtypes.FLOAT_DTYPE, - dtypes.JSON_DTYPE, - ), - ( - dtypes.STRING_DTYPE, - dtypes.JSON_DTYPE, - ), - ( - dtypes.INT_DTYPE, - dtypes.JSON_DTYPE, - ), ) ) diff --git a/packages/bigframes/bigframes/operations/json_ops.py b/packages/bigframes/bigframes/operations/json_ops.py index 7260a7922305..c9b5849f9ed1 100644 --- a/packages/bigframes/bigframes/operations/json_ops.py +++ b/packages/bigframes/bigframes/operations/json_ops.py @@ -105,10 +105,11 @@ def output_type(self, *input_types): @dataclasses.dataclass(frozen=True) class ToJSON(base_ops.UnaryOp): name: typing.ClassVar[str] = "to_json" + safe: bool = True def output_type(self, *input_types): input_type = input_types[0] - if not dtypes.is_json_encoding_type(input_type): + if not dtypes.is_json_encoding_type(input_type, strict=True): raise TypeError( "The value to be assigned must be a type that can be encoded as JSON." + f"Received type: {input_type}" @@ -220,6 +221,7 @@ def output_type(self, *input_types): class JSONDecode(base_ops.UnaryOp): name: typing.ClassVar[str] = "json_decode" to_type: dtypes.Dtype + safe: bool = True def output_type(self, *input_types): input_type = input_types[0] @@ -228,4 +230,11 @@ def output_type(self, *input_types): "Input type must be a valid JSON object or JSON-formatted string type." + f" Received type: {input_type}" ) + if self.to_type not in ( + dtypes.INT_DTYPE, + dtypes.FLOAT_DTYPE, + dtypes.BOOL_DTYPE, + dtypes.STRING_DTYPE, + ): + raise TypeError(f"Cannot cast from {dtypes.JSON_DTYPE} to {self.to_type}") return self.to_type diff --git a/packages/bigframes/bigframes/series.py b/packages/bigframes/bigframes/series.py index 262e1859ab92..57f74136548c 100644 --- a/packages/bigframes/bigframes/series.py +++ b/packages/bigframes/bigframes/series.py @@ -646,9 +646,17 @@ def astype( if errors not in ["raise", "null"]: raise ValueError("Argument 'errors' must be one of 'raise' or 'null'") dtype = bigframes.dtypes.bigframes_type(dtype) - return self._apply_unary_op( - bigframes.operations.AsTypeOp(to_type=dtype, safe=(errors == "null")) - ) + safe = errors == "null" + if dtype == bigframes.dtypes.JSON_DTYPE: + return self._apply_unary_op(bigframes.operations.ToJSON(safe=safe)) + elif self.dtype == bigframes.dtypes.JSON_DTYPE: + return self._apply_unary_op( + bigframes.operations.JSONDecode(to_type=dtype, safe=safe) + ) + else: + return self._apply_unary_op( + bigframes.operations.AsTypeOp(to_type=dtype, safe=safe) + ) def to_pandas( self, diff --git a/packages/bigframes/tests/system/small/bigquery/test_json.py b/packages/bigframes/tests/system/small/bigquery/test_json.py index 4fc4d2283ece..2d97172e7b5c 100644 --- a/packages/bigframes/tests/system/small/bigquery/test_json.py +++ b/packages/bigframes/tests/system/small/bigquery/test_json.py @@ -390,7 +390,7 @@ def test_parse_json_w_invalid_series_type(): def test_to_json_from_int(): s = bpd.Series([1, 2, None, 3]) actual = bbq.to_json(s) - expected = bpd.Series(["1.0", "2.0", "null", "3.0"], dtype=dtypes.JSON_DTYPE) + expected = bpd.Series(["1.0", "2.0", None, "3.0"], dtype=dtypes.JSON_DTYPE) pd.testing.assert_series_equal(actual.to_pandas(), expected.to_pandas()) diff --git a/packages/bigframes/tests/system/small/engines/test_generic_ops.py b/packages/bigframes/tests/system/small/engines/test_generic_ops.py index 22ad1bfefa4e..05739a1c1b63 100644 --- a/packages/bigframes/tests/system/small/engines/test_generic_ops.py +++ b/packages/bigframes/tests/system/small/engines/test_generic_ops.py @@ -263,16 +263,16 @@ def test_engines_astype_time(scalars_array_value: array_value.ArrayValue, engine @pytest.mark.parametrize("engine", ["polars", "bq", "bq-sqlglot"], indirect=True) def test_engines_astype_from_json(scalars_array_value: array_value.ArrayValue, engine): exprs = [ - ops.AsTypeOp(to_type=bigframes.dtypes.INT_DTYPE).as_expr( + ops.JSONDecode(to_type=bigframes.dtypes.INT_DTYPE).as_expr( expression.const("5", bigframes.dtypes.JSON_DTYPE) ), - ops.AsTypeOp(to_type=bigframes.dtypes.FLOAT_DTYPE).as_expr( + ops.JSONDecode(to_type=bigframes.dtypes.FLOAT_DTYPE).as_expr( expression.const("5", bigframes.dtypes.JSON_DTYPE) ), - ops.AsTypeOp(to_type=bigframes.dtypes.BOOL_DTYPE).as_expr( + ops.JSONDecode(to_type=bigframes.dtypes.BOOL_DTYPE).as_expr( expression.const("true", bigframes.dtypes.JSON_DTYPE) ), - ops.AsTypeOp(to_type=bigframes.dtypes.STRING_DTYPE).as_expr( + ops.JSONDecode(to_type=bigframes.dtypes.STRING_DTYPE).as_expr( expression.const('"hello world"', bigframes.dtypes.JSON_DTYPE) ), ] @@ -284,17 +284,13 @@ def test_engines_astype_from_json(scalars_array_value: array_value.ArrayValue, e @pytest.mark.parametrize("engine", ["polars", "bq", "bq-sqlglot"], indirect=True) def test_engines_astype_to_json(scalars_array_value: array_value.ArrayValue, engine): exprs = [ - ops.AsTypeOp(to_type=bigframes.dtypes.JSON_DTYPE).as_expr( - expression.deref("int64_col") - ), - ops.AsTypeOp(to_type=bigframes.dtypes.JSON_DTYPE).as_expr( + ops.ToJSON().as_expr(expression.deref("int64_col")), + ops.ToJSON().as_expr( # Use a const since float to json has precision issues expression.const(5.2, bigframes.dtypes.FLOAT_DTYPE) ), - ops.AsTypeOp(to_type=bigframes.dtypes.JSON_DTYPE).as_expr( - expression.deref("bool_col") - ), - ops.AsTypeOp(to_type=bigframes.dtypes.JSON_DTYPE).as_expr( + ops.ToJSON().as_expr(expression.deref("bool_col")), + ops.ToJSON().as_expr( # Use a const since "str_col" has special chars. expression.const('"hello world"', bigframes.dtypes.STRING_DTYPE) ), diff --git a/packages/bigframes/tests/system/small/test_series.py b/packages/bigframes/tests/system/small/test_series.py index 5df88e930432..2e80b75c0b41 100644 --- a/packages/bigframes/tests/system/small/test_series.py +++ b/packages/bigframes/tests/system/small/test_series.py @@ -4019,25 +4019,28 @@ def test_timestamp_astype_string(session): @pytest.mark.parametrize("errors", ["raise", "null"]) def test_float_astype_json(errors, session): - data = ["1.25", "2500000000", None, "-12323.24"] + data = ["1.25", "2500000000.1", None, "-12323.24"] bf_series = series.Series(data, dtype=dtypes.FLOAT_DTYPE, session=session) bf_result = bf_series.astype(dtypes.JSON_DTYPE, errors=errors) assert bf_result.dtype == dtypes.JSON_DTYPE + bf_result_pandas = bf_result.to_pandas() - expected_result = pd.Series(data, dtype=dtypes.JSON_DTYPE) + expected_data = [float(x) if x is not None else None for x in data] + expected_result = pd.Series(expected_data, dtype=dtypes.JSON_DTYPE) expected_result.index = expected_result.index.astype("Int64") - bigframes.testing.utils.assert_series_equal(bf_result.to_pandas(), expected_result) + bigframes.testing.utils.assert_series_equal(bf_result_pandas, expected_result) def test_float_astype_json_str(session): - data = ["1.25", "2500000000", None, "-12323.24"] + data = ["1.25", "2500000000.1", None, "-12323.24"] bf_series = series.Series(data, dtype=dtypes.FLOAT_DTYPE, session=session) bf_result = bf_series.astype("json") assert bf_result.dtype == dtypes.JSON_DTYPE - expected_result = pd.Series(data, dtype=dtypes.JSON_DTYPE) + expected_data = [float(x) if x is not None else None for x in data] + expected_result = pd.Series(expected_data, dtype=dtypes.JSON_DTYPE) expected_result.index = expected_result.index.astype("Int64") bigframes.testing.utils.assert_series_equal(bf_result.to_pandas(), expected_result) diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_generic_ops/test_astype_from_json/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_generic_ops/test_astype_from_json/out.sql index 4603f503b5e0..c9450a928003 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_generic_ops/test_astype_from_json/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_generic_ops/test_astype_from_json/out.sql @@ -1,7 +1,7 @@ SELECT - INT64(`json_col`) AS `int64_col`, - FLOAT64(`json_col`) AS `float64_col`, - BOOL(`json_col`) AS `bool_col`, - STRING(`json_col`) AS `string_col`, + SAFE.INT64(`json_col`) AS `int64_col`, + SAFE.FLOAT64(`json_col`) AS `float64_col`, + SAFE.BOOL(`json_col`) AS `bool_col`, + SAFE.STRING(`json_col`) AS `string_col`, SAFE.INT64(`json_col`) AS `int64_w_safe` FROM `bigframes-dev`.`sqlglot_test`.`json_types` AS `bft_0` \ No newline at end of file diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_generic_ops/test_to_json/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_generic_ops/test_to_json/out.sql new file mode 100644 index 000000000000..86d6f0e9fbb4 --- /dev/null +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_generic_ops/test_to_json/out.sql @@ -0,0 +1,8 @@ +SELECT + IF(`int64_col` IS NULL, NULL, TO_JSON(`int64_col`)) AS `int64_col`, + IF(`float64_col` IS NULL, NULL, TO_JSON(`float64_col`)) AS `float64_col`, + IF(`bool_col` IS NULL, NULL, TO_JSON(`bool_col`)) AS `bool_col`, + SAFE.PARSE_JSON(`string_col`) AS `string_col`, + IF(`bool_col` IS NULL, NULL, TO_JSON(`bool_col`)) AS `bool_w_safe`, + SAFE.PARSE_JSON(`string_col`) AS `string_w_safe` +FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` AS `bft_0` \ No newline at end of file diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_json_ops/test_to_json/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_json_ops/test_to_json/out.sql index ef89efa653b1..0545577e27f3 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_json_ops/test_to_json/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_json_ops/test_to_json/out.sql @@ -1,3 +1,3 @@ SELECT - TO_JSON(`string_col`) AS `string_col` + SAFE.PARSE_JSON(`string_col`) AS `string_col` FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` AS `bft_0` \ No newline at end of file diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/test_generic_ops.py b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/test_generic_ops.py index 185a8df04509..e3669e1b0edc 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/test_generic_ops.py +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/test_generic_ops.py @@ -110,20 +110,16 @@ def test_astype_string(scalar_types_df: bpd.DataFrame, snapshot): snapshot.assert_match(sql + "\n", "out.sql") -def test_astype_json(scalar_types_df: bpd.DataFrame, snapshot): +def test_to_json(scalar_types_df: bpd.DataFrame, snapshot): bf_df = scalar_types_df ops_map = { - "int64_col": ops.AsTypeOp(to_type=dtypes.JSON_DTYPE).as_expr("int64_col"), - "float64_col": ops.AsTypeOp(to_type=dtypes.JSON_DTYPE).as_expr("float64_col"), - "bool_col": ops.AsTypeOp(to_type=dtypes.JSON_DTYPE).as_expr("bool_col"), - "string_col": ops.AsTypeOp(to_type=dtypes.JSON_DTYPE).as_expr("string_col"), - "bool_w_safe": ops.AsTypeOp(to_type=dtypes.JSON_DTYPE, safe=True).as_expr( - "bool_col" - ), - "string_w_safe": ops.AsTypeOp(to_type=dtypes.JSON_DTYPE, safe=True).as_expr( - "string_col" - ), + "int64_col": ops.ToJSON().as_expr("int64_col"), + "float64_col": ops.ToJSON().as_expr("float64_col"), + "bool_col": ops.ToJSON().as_expr("bool_col"), + "string_col": ops.ToJSON().as_expr("string_col"), + "bool_w_safe": ops.ToJSON(safe=True).as_expr("bool_col"), + "string_w_safe": ops.ToJSON(safe=True).as_expr("string_col"), } sql = utils._apply_ops_to_sql(bf_df, list(ops_map.values()), list(ops_map.keys())) snapshot.assert_match(sql, "out.sql") @@ -133,11 +129,11 @@ def test_astype_from_json(json_types_df: bpd.DataFrame, snapshot): bf_df = json_types_df ops_map = { - "int64_col": ops.AsTypeOp(to_type=dtypes.INT_DTYPE).as_expr("json_col"), - "float64_col": ops.AsTypeOp(to_type=dtypes.FLOAT_DTYPE).as_expr("json_col"), - "bool_col": ops.AsTypeOp(to_type=dtypes.BOOL_DTYPE).as_expr("json_col"), - "string_col": ops.AsTypeOp(to_type=dtypes.STRING_DTYPE).as_expr("json_col"), - "int64_w_safe": ops.AsTypeOp(to_type=dtypes.INT_DTYPE, safe=True).as_expr( + "int64_col": ops.JSONDecode(to_type=dtypes.INT_DTYPE).as_expr("json_col"), + "float64_col": ops.JSONDecode(to_type=dtypes.FLOAT_DTYPE).as_expr("json_col"), + "bool_col": ops.JSONDecode(to_type=dtypes.BOOL_DTYPE).as_expr("json_col"), + "string_col": ops.JSONDecode(to_type=dtypes.STRING_DTYPE).as_expr("json_col"), + "int64_w_safe": ops.JSONDecode(to_type=dtypes.INT_DTYPE, safe=True).as_expr( "json_col" ), } @@ -145,24 +141,20 @@ def test_astype_from_json(json_types_df: bpd.DataFrame, snapshot): snapshot.assert_match(sql, "out.sql") -def test_astype_json_invalid( - scalar_types_df: bpd.DataFrame, json_types_df: bpd.DataFrame -): +def test_tojson_invalid(scalar_types_df: bpd.DataFrame, json_types_df: bpd.DataFrame): # Test invalid cast to JSON - with pytest.raises(TypeError, match="Cannot cast timestamp.* to .*json.*"): + with pytest.raises(TypeError): ops_map_to = { - "datetime_to_json": ops.AsTypeOp(to_type=dtypes.JSON_DTYPE).as_expr( - "datetime_col" - ), + "datetime_to_json": ops.ToJSON().as_expr("datetime_col"), } utils._apply_ops_to_sql( scalar_types_df, list(ops_map_to.values()), list(ops_map_to.keys()) ) # Test invalid cast from JSON - with pytest.raises(TypeError, match="Cannot cast .*json.* to timestamp.*"): + with pytest.raises(TypeError): ops_map_from = { - "json_to_datetime": ops.AsTypeOp(to_type=dtypes.DATETIME_DTYPE).as_expr( + "json_to_datetime": ops.JSONDecode(to_type=dtypes.DATETIME_DTYPE).as_expr( "json_col" ), } From 141ad0ef584f4b5ca4086bb46fc03187949454fc Mon Sep 17 00:00:00 2001 From: Daniel Sanche Date: Thu, 18 Jun 2026 22:06:23 -0700 Subject: [PATCH 099/174] chore(firestore): improve typing for collection (#16999) Previously, `CollectionReference` didn't define `.document()`, so it inherited the typing of `BaseCollectionReference`. This PR adds an override to ensure that documents are annotated as returning `DocumentReference` types --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- .../google/cloud/firestore_v1/collection.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/packages/google-cloud-firestore/google/cloud/firestore_v1/collection.py b/packages/google-cloud-firestore/google/cloud/firestore_v1/collection.py index 19b86ae6559a..fb7aebda0d31 100644 --- a/packages/google-cloud-firestore/google/cloud/firestore_v1/collection.py +++ b/packages/google-cloud-firestore/google/cloud/firestore_v1/collection.py @@ -16,7 +16,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, Callable, Generator, Optional, Tuple, Union +from typing import TYPE_CHECKING, Any, Callable, Generator, Optional, Tuple, Union, cast from google.api_core import gapic_v1 from google.api_core import retry as retries @@ -34,6 +34,7 @@ import datetime from google.cloud.firestore_v1.base_document import DocumentSnapshot + from google.cloud.firestore_v1.document import DocumentReference from google.cloud.firestore_v1.query_profile import ExplainOptions from google.cloud.firestore_v1.stream_generator import StreamGenerator @@ -134,6 +135,22 @@ def add( write_result = document_ref.create(document_data, **kwargs) return write_result.update_time, document_ref + def document(self, document_id: Union[str, None] = None) -> "DocumentReference": + """Create a sub-document underneath the current collection. + + Args: + document_id (Optional[str]): The document identifier + within the current collection. If not provided, will default + to a random 20 character string composed of digits, + uppercase and lowercase and letters. + + Returns: + :class:~google.cloud.firestore_v1.document.DocumentReference: + The child document. + """ + doc = super().document(document_id) + return cast("DocumentReference", doc) + def list_documents( self, page_size: Union[int, None] = None, From 025840544f5d4ab6a429d1cd9bdbb256c981aa0d Mon Sep 17 00:00:00 2001 From: Chalmer Lowe Date: Fri, 19 Jun 2026 06:53:19 -0400 Subject: [PATCH 100/174] fix(bigquery): close GAPIC storage transport and auth sessions to prevent socket leaks (#17508) This PR resolves resource leaks (specifically open sockets left in the `ESTABLISHED` state) that occur during client lifecycle operations and credential refreshing in system/unit tests. ### The Problem 1. **Transport Lifecycle:** When closing the BigQuery Storage client, calling `_transport.grpc_channel.close()` was insufficient for releasing all network resources. The full `_transport.close()` method needs to be invoked to tear down the underlying transport channel correctly. 2. **Dynamic Auth Sessions:** Under certain authentication environments (like Workload Identity/GCE Metadata server inside Kokoro CI), the `google-auth` library dynamically instantiates helper HTTP sessions to fetch access tokens. These sessions are not owned by the BigQuery client and are not closed automatically, leading to leaked sockets. 3. **Flaky Test Assertions:** Socket count assertions in system tests were flaky because Python's garbage collection is non-deterministic, meaning sockets remained open in the operating system even after client close calls until a garbage collection cycle swept them. ### Changes * **Client & Transport Lifecycle:** * Updated [connection.py](file:///usr/local/google/home/chalmerlowe/titan-src/projects/google-cloud-python/main/packages/google-cloud-bigquery/google/cloud/bigquery/dbapi/connection.py), [magics.py](file:///usr/local/google/home/chalmerlowe/titan-src/projects/google-cloud-python/main/packages/google-cloud-bigquery/google/cloud/bigquery/magics/magics.py), and [table.py](file:///usr/local/google/home/chalmerlowe/titan-src/projects/google-cloud-python/main/packages/google-cloud-bigquery/google/cloud/bigquery/table.py) to close the BigQuery Storage transport using `_transport.close()` instead of `_transport.grpc_channel.close()`. * **Testing Improvements:** * Added `patch_tracked_requests` interceptor to system/unit tests to track and explicitly close all dynamically spawned credential-refreshing HTTP sessions when the test context exits. * Added explicit `gc.collect()` calls to socket leak verification tests to force synchronous sweeping of unreferenced socket objects before asserting final socket counts. * **Code Coverage:** * Appended `# pragma: NO COVER` to Python version checks in [`__init__.py`](file:///usr/local/google/home/chalmerlowe/titan-src/projects/google-cloud-python/main/packages/google-cloud-bigquery/google/cloud/bigquery/__init__.py) for code paths that render a deprecation warning code if attempted to run on Python runtimes <3.10 test matrix (these paths do not run in our CI/CD since we never execute code with the older runtimes). --- .../google/cloud/bigquery/__init__.py | 2 +- .../google/cloud/bigquery/dbapi/connection.py | 2 +- .../google/cloud/bigquery/magics/magics.py | 2 +- .../google/cloud/bigquery/table.py | 4 +- .../tests/system/helpers.py | 28 +++++- .../tests/system/test_client.py | 75 +++++++++------- .../tests/system/test_magics.py | 46 +++++----- .../tests/unit/test_dbapi_connection.py | 6 +- .../tests/unit/test_magics.py | 7 +- .../tests/unit/test_table.py | 90 +++++++++++++++++-- 10 files changed, 189 insertions(+), 73 deletions(-) diff --git a/packages/google-cloud-bigquery/google/cloud/bigquery/__init__.py b/packages/google-cloud-bigquery/google/cloud/bigquery/__init__.py index d20e288f6ac3..fa03156e2e26 100644 --- a/packages/google-cloud-bigquery/google/cloud/bigquery/__init__.py +++ b/packages/google-cloud-bigquery/google/cloud/bigquery/__init__.py @@ -123,7 +123,7 @@ except ImportError: bigquery_magics = None -if sys.version_info < (3, 10): +if sys.version_info < (3, 10): # pragma: NO COVER warnings.warn( "The python-bigquery library no longer supports Python <= 3.9. " f"Your Python version is {sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}. We " diff --git a/packages/google-cloud-bigquery/google/cloud/bigquery/dbapi/connection.py b/packages/google-cloud-bigquery/google/cloud/bigquery/dbapi/connection.py index a1a69b8fec90..b0d7ef895141 100644 --- a/packages/google-cloud-bigquery/google/cloud/bigquery/dbapi/connection.py +++ b/packages/google-cloud-bigquery/google/cloud/bigquery/dbapi/connection.py @@ -84,7 +84,7 @@ def close(self): if self._owns_bqstorage_client: # There is no close() on the BQ Storage client itself. - self._bqstorage_client._transport.grpc_channel.close() + self._bqstorage_client._transport.close() for cursor_ in self._cursors_created: if not cursor_._closed: diff --git a/packages/google-cloud-bigquery/google/cloud/bigquery/magics/magics.py b/packages/google-cloud-bigquery/google/cloud/bigquery/magics/magics.py index 1f892b595222..30bc9d27a8b6 100644 --- a/packages/google-cloud-bigquery/google/cloud/bigquery/magics/magics.py +++ b/packages/google-cloud-bigquery/google/cloud/bigquery/magics/magics.py @@ -773,4 +773,4 @@ def _close_transports(client, bqstorage_client): """ client.close() if bqstorage_client is not None: - bqstorage_client._transport.grpc_channel.close() + bqstorage_client._transport.close() diff --git a/packages/google-cloud-bigquery/google/cloud/bigquery/table.py b/packages/google-cloud-bigquery/google/cloud/bigquery/table.py index b58499343b8a..870cdcc5d2ab 100644 --- a/packages/google-cloud-bigquery/google/cloud/bigquery/table.py +++ b/packages/google-cloud-bigquery/google/cloud/bigquery/table.py @@ -2353,7 +2353,9 @@ def to_arrow( progress_bar.close() finally: if owns_bqstorage_client: - bqstorage_client._transport.grpc_channel.close() # type: ignore + # mypy: bqstorage_client is guaranteed to be not None when owns_bqstorage_client is True, + # but mypy cannot infer this correlation. We ignore the union-attr error here. + bqstorage_client._transport.close() # type: ignore[union-attr] if record_batches and bqstorage_client is not None: return pyarrow.Table.from_batches(record_batches) diff --git a/packages/google-cloud-bigquery/tests/system/helpers.py b/packages/google-cloud-bigquery/tests/system/helpers.py index 7fd344eeb071..6a8e142c2a50 100644 --- a/packages/google-cloud-bigquery/tests/system/helpers.py +++ b/packages/google-cloud-bigquery/tests/system/helpers.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import contextlib import datetime import decimal import uuid @@ -21,7 +22,6 @@ from google.cloud._helpers import UTC - _naive = datetime.datetime(2016, 12, 5, 12, 41, 9) _naive_microseconds = datetime.datetime(2016, 12, 5, 12, 41, 9, 250000) _stamp = "%s %s" % (_naive.date().isoformat(), _naive.time().isoformat()) @@ -104,3 +104,29 @@ def _rate_limit_exceeded(forbidden): google.api_core.exceptions.Forbidden, error_predicate=_rate_limit_exceeded, ) + + +@contextlib.contextmanager +def patch_tracked_requests(): + """Context manager to patch google-auth requests and track/close their HTTP sessions. + + This prevents socket leaks in system tests that use Workload Identity or metadata server auth. + """ + import google.auth.transport.requests + + original_init = google.auth.transport.requests.Request.__init__ + tracked_requests = [] + + def patched_init(self, session=None): + original_init(self, session=session) + if session is None: + tracked_requests.append(self) + + google.auth.transport.requests.Request.__init__ = patched_init + try: + yield tracked_requests + finally: + google.auth.transport.requests.Request.__init__ = original_init + for req in tracked_requests: + if hasattr(req, "session") and req.session is not None: + req.session.close() diff --git a/packages/google-cloud-bigquery/tests/system/test_client.py b/packages/google-cloud-bigquery/tests/system/test_client.py index b6da77c04bdb..d5ec07b5a557 100644 --- a/packages/google-cloud-bigquery/tests/system/test_client.py +++ b/packages/google-cloud-bigquery/tests/system/test_client.py @@ -58,7 +58,6 @@ from . import helpers - JOB_TIMEOUT = 120 # 2 minutes DATA_PATH = pathlib.Path(__file__).parent.parent / "data" @@ -234,23 +233,29 @@ def _create_bucket(self, bucket_name, location=None): def test_close_releases_open_sockets(self): current_process = psutil.Process() - conn_count_start = len(current_process.net_connections()) + conn_start = current_process.net_connections() + conn_count_start = len(conn_start) + + with helpers.patch_tracked_requests(): + client = Config.CLIENT + client.query( + """ + SELECT + source_year AS year, COUNT(is_male) AS birth_count + FROM `bigquery-public-data.samples.natality` + GROUP BY year + ORDER BY year DESC + LIMIT 15 + """ + ) - client = Config.CLIENT - client.query( - """ - SELECT - source_year AS year, COUNT(is_male) AS birth_count - FROM `bigquery-public-data.samples.natality` - GROUP BY year - ORDER BY year DESC - LIMIT 15 - """ - ) + client.close() - client.close() + import gc - conn_count_end = len(current_process.net_connections()) + gc.collect() + conn_end = current_process.net_connections() + conn_count_end = len(conn_end) self.assertLessEqual(conn_count_end, conn_count_start) def test_create_dataset(self): @@ -2174,25 +2179,31 @@ def test_dbapi_dry_run_query(self): def test_dbapi_connection_does_not_leak_sockets(self): pytest.importorskip("google.cloud.bigquery_storage") current_process = psutil.Process() - conn_count_start = len(current_process.net_connections()) - - # Provide no explicit clients, so that the connection will create and own them. - connection = dbapi.connect() - cursor = connection.cursor() - - cursor.execute( + conn_start = current_process.net_connections() + conn_count_start = len(conn_start) + + with helpers.patch_tracked_requests(): + # Provide no explicit clients, so that the connection will create and own them. + connection = dbapi.connect() + cursor = connection.cursor() + + cursor.execute( + """ + SELECT id, `by`, timestamp + FROM `bigquery-public-data.hacker_news.full` + ORDER BY `id` ASC + LIMIT 100000 """ - SELECT id, `by`, timestamp - FROM `bigquery-public-data.hacker_news.full` - ORDER BY `id` ASC - LIMIT 100000 - """ - ) - rows = cursor.fetchall() - self.assertEqual(len(rows), 100000) + ) + rows = cursor.fetchall() + self.assertEqual(len(rows), 100000) + + connection.close() + import gc - connection.close() - conn_count_end = len(current_process.net_connections()) + gc.collect() + conn_end = current_process.net_connections() + conn_count_end = len(conn_end) self.assertLessEqual(conn_count_end, conn_count_start) def _load_table_for_dml(self, rows, dataset_id, table_id): diff --git a/packages/google-cloud-bigquery/tests/system/test_magics.py b/packages/google-cloud-bigquery/tests/system/test_magics.py index d40b18663ef2..31fd4543eed5 100644 --- a/packages/google-cloud-bigquery/tests/system/test_magics.py +++ b/packages/google-cloud-bigquery/tests/system/test_magics.py @@ -19,6 +19,7 @@ import pytest import psutil +from . import helpers IPython = pytest.importorskip("IPython") io = pytest.importorskip("IPython.utils.io") @@ -48,27 +49,30 @@ def ipython_interactive(ipython): def test_bigquery_magic(ipython_interactive): ip = IPython.get_ipython() current_process = psutil.Process() - conn_count_start = len(current_process.net_connections()) - - # Deprecated, but should still work in google-cloud-bigquery 3.x. - with pytest.warns(FutureWarning, match="bigquery_magics"): - ip.extension_manager.load_extension("google.cloud.bigquery") - - sql = """ - SELECT - CONCAT( - 'https://stackoverflow.com/questions/', - CAST(id as STRING)) as url, - view_count - FROM `bigquery-public-data.stackoverflow.posts_questions` - WHERE tags like '%google-bigquery%' - ORDER BY view_count DESC - LIMIT 10 - """ - with io.capture_output() as captured: - result = ip.run_cell_magic("bigquery", "--use_rest_api", sql) - - conn_count_end = len(current_process.net_connections()) + conn_start = current_process.net_connections() + conn_count_start = len(conn_start) + + with helpers.patch_tracked_requests(): + # Deprecated, but should still work in google-cloud-bigquery 3.x. + with pytest.warns(FutureWarning, match="bigquery_magics"): + ip.extension_manager.load_extension("google.cloud.bigquery") + + sql = """ + SELECT + CONCAT( + 'https://stackoverflow.com/questions/', + CAST(id as STRING)) as url, + view_count + FROM `bigquery-public-data.stackoverflow.posts_questions` + WHERE tags like '%google-bigquery%' + ORDER BY view_count DESC + LIMIT 10 + """ + with io.capture_output() as captured: + result = ip.run_cell_magic("bigquery", "--use_rest_api", sql) + + conn_end = current_process.net_connections() + conn_count_end = len(conn_end) lines = re.split("\n|\r", captured.stdout) # Removes blanks & terminal code (result of display clearing) diff --git a/packages/google-cloud-bigquery/tests/unit/test_dbapi_connection.py b/packages/google-cloud-bigquery/tests/unit/test_dbapi_connection.py index f5c77c448eee..8047462243dd 100644 --- a/packages/google-cloud-bigquery/tests/unit/test_dbapi_connection.py +++ b/packages/google-cloud-bigquery/tests/unit/test_dbapi_connection.py @@ -40,7 +40,7 @@ def _mock_bqstorage_client(self): from google.cloud import bigquery_storage mock_client = mock.create_autospec(bigquery_storage.BigQueryReadClient) - mock_client._transport = mock.Mock(spec=["channel"]) + mock_client._transport = mock.Mock(spec=["channel", "close"]) mock_client._transport.grpc_channel = mock.Mock(spec=["close"]) return mock_client @@ -176,7 +176,7 @@ def test_close_closes_all_created_bigquery_clients(self): connection.close() self.assertTrue(client.close.called) - self.assertTrue(bqstorage_client._transport.grpc_channel.close.called) + self.assertTrue(bqstorage_client._transport.close.called) def test_close_does_not_close_bigquery_clients_passed_to_it(self): pytest.importorskip("google.cloud.bigquery_storage") @@ -187,7 +187,7 @@ def test_close_does_not_close_bigquery_clients_passed_to_it(self): connection.close() self.assertFalse(client.close.called) - self.assertFalse(bqstorage_client._transport.grpc_channel.close.called) + self.assertFalse(bqstorage_client._transport.close.called) def test_close_closes_all_created_cursors(self): connection = self._make_one(client=self._mock_client()) diff --git a/packages/google-cloud-bigquery/tests/unit/test_magics.py b/packages/google-cloud-bigquery/tests/unit/test_magics.py index f679d2806bc1..74b8265b3c56 100644 --- a/packages/google-cloud-bigquery/tests/unit/test_magics.py +++ b/packages/google-cloud-bigquery/tests/unit/test_magics.py @@ -45,7 +45,7 @@ @pytest.fixture() def use_local_magics_context(monkeypatch): - if magics is not None: + if magics is not None: # pragma: NO COVER local_context = magics.Context() local_context._project = "unit-test-project" mock_credentials = mock.create_autospec( @@ -2195,13 +2195,10 @@ def test_bigquery_magic_create_dataset_fails(monkeypatch): @pytest.mark.usefixtures("ipython_interactive") -def test_bigquery_magic_with_location(monkeypatch): +def test_bigquery_magic_with_location(monkeypatch, use_local_magics_context): ip = IPython.get_ipython() monkeypatch.setattr(bigquery, "bigquery_magics", None) bigquery.load_ipython_extension(ip) - magics.context.credentials = mock.create_autospec( - google.auth.credentials.Credentials, instance=True - ) run_query_patch = mock.patch( "google.cloud.bigquery.magics.magics._run_query", autospec=True diff --git a/packages/google-cloud-bigquery/tests/unit/test_table.py b/packages/google-cloud-bigquery/tests/unit/test_table.py index 0297156aef95..5701143a62d4 100644 --- a/packages/google-cloud-bigquery/tests/unit/test_table.py +++ b/packages/google-cloud-bigquery/tests/unit/test_table.py @@ -79,6 +79,82 @@ def test_ctor_with_key(self): self.assertEqual(encryption_config.kms_key_name, self.KMS_KEY_NAME) +class TestPropertyGraphReference(unittest.TestCase): + PROJECT = "my-project" + DATASET_ID = "my_dataset" + PROPERTY_GRAPH_ID = "my_pg" + + def _get_target_class(self): + from google.cloud.bigquery.table import PropertyGraphReference + + return PropertyGraphReference + + def _make_one(self, *args, **kw): + return self._get_target_class()(*args, **kw) + + def test_ctor(self): + dataset_ref = DatasetReference(self.PROJECT, self.DATASET_ID) + ref = self._make_one(dataset_ref, self.PROPERTY_GRAPH_ID) + self.assertEqual(ref.project, self.PROJECT) + self.assertEqual(ref.dataset_id, self.DATASET_ID) + self.assertEqual(ref.property_graph_id, self.PROPERTY_GRAPH_ID) + + def test_from_api_repr(self): + resource = { + "projectId": self.PROJECT, + "datasetId": self.DATASET_ID, + "propertyGraphId": self.PROPERTY_GRAPH_ID, + } + ref = self._get_target_class().from_api_repr(resource) + self.assertEqual(ref.project, self.PROJECT) + self.assertEqual(ref.dataset_id, self.DATASET_ID) + self.assertEqual(ref.property_graph_id, self.PROPERTY_GRAPH_ID) + + def test_to_api_repr(self): + dataset_ref = DatasetReference(self.PROJECT, self.DATASET_ID) + ref = self._make_one(dataset_ref, self.PROPERTY_GRAPH_ID) + resource = ref.to_api_repr() + expected = { + "projectId": self.PROJECT, + "datasetId": self.DATASET_ID, + "propertyGraphId": self.PROPERTY_GRAPH_ID, + } + self.assertEqual(resource, expected) + + def test___str__(self): + dataset_ref = DatasetReference(self.PROJECT, self.DATASET_ID) + ref = self._make_one(dataset_ref, self.PROPERTY_GRAPH_ID) + self.assertEqual( + str(ref), f"{self.PROJECT}.{self.DATASET_ID}.{self.PROPERTY_GRAPH_ID}" + ) + + def test___repr__(self): + dataset_ref = DatasetReference(self.PROJECT, self.DATASET_ID) + ref = self._make_one(dataset_ref, self.PROPERTY_GRAPH_ID) + expected = ( + f"PropertyGraphReference({dataset_ref!r}, '{self.PROPERTY_GRAPH_ID}')" + ) + self.assertEqual(repr(ref), expected) + + def test___eq__(self): + dataset_ref1 = DatasetReference(self.PROJECT, self.DATASET_ID) + ref1 = self._make_one(dataset_ref1, self.PROPERTY_GRAPH_ID) + dataset_ref2 = DatasetReference(self.PROJECT, self.DATASET_ID) + ref2 = self._make_one(dataset_ref2, self.PROPERTY_GRAPH_ID) + self.assertEqual(ref1, ref2) + + ref3 = self._make_one(dataset_ref1, "other_pg") + self.assertNotEqual(ref1, ref3) + self.assertNotEqual(ref1, object()) + + def test___hash__(self): + dataset_ref1 = DatasetReference(self.PROJECT, self.DATASET_ID) + ref1 = self._make_one(dataset_ref1, self.PROPERTY_GRAPH_ID) + dataset_ref2 = DatasetReference(self.PROJECT, self.DATASET_ID) + ref2 = self._make_one(dataset_ref2, self.PROPERTY_GRAPH_ID) + self.assertEqual(hash(ref1), hash(ref2)) + + class TestTableBase: @staticmethod def _get_target_class(): @@ -3048,7 +3124,7 @@ def test_to_arrow_iterable_w_bqstorage(self): self.assertEqual(record_batch, expected_record_batch) # Don't close the client if it was passed in. - bqstorage_client._transport.grpc_channel.close.assert_not_called() + bqstorage_client._transport.close.assert_not_called() def test_to_arrow(self): pytest.importorskip("numpy") @@ -3424,7 +3500,7 @@ def test_to_arrow_w_bqstorage(self): self.assertEqual(actual_tbl.num_rows, total_rows) # Don't close the client if it was passed in. - bqstorage_client._transport.grpc_channel.close.assert_not_called() + bqstorage_client._transport.close.assert_not_called() def test_to_arrow_w_bqstorage_creates_client(self): pytest.importorskip("numpy") @@ -3458,7 +3534,7 @@ def test_to_arrow_w_bqstorage_creates_client(self): ) row_iterator.to_arrow(create_bqstorage_client=True) mock_client._ensure_bqstorage_client.assert_called_once() - bqstorage_client._transport.grpc_channel.close.assert_called_once() + bqstorage_client._transport.close.assert_called_once() def test_to_arrow_ensure_bqstorage_client_wo_bqstorage(self): pytest.importorskip("numpy") @@ -3741,7 +3817,7 @@ def test_to_dataframe_iterable_w_bqstorage(self): self.assertEqual(len(got), total_pages) # Don't close the client if it was passed in. - bqstorage_client._transport.grpc_channel.close.assert_not_called() + bqstorage_client._transport.close.assert_not_called() def test_to_dataframe_iterable_w_bqstorage_max_results_warning(self): pytest.importorskip("numpy") @@ -4807,7 +4883,7 @@ def test_to_dataframe_w_bqstorage_creates_client(self): ) row_iterator.to_dataframe(create_bqstorage_client=True) mock_client._ensure_bqstorage_client.assert_called_once() - bqstorage_client._transport.grpc_channel.close.assert_called_once() + bqstorage_client._transport.close.assert_called_once() def test_to_dataframe_w_bqstorage_no_streams(self): pytest.importorskip("numpy") @@ -4999,7 +5075,7 @@ def test_to_dataframe_w_bqstorage_nonempty(self): self.assertEqual(len(got.index), total_rows) # Don't close the client if it was passed in. - bqstorage_client._transport.grpc_channel.close.assert_not_called() + bqstorage_client._transport.close.assert_not_called() def test_to_dataframe_w_bqstorage_multiple_streams_return_unique_index(self): pytest.importorskip("numpy") @@ -5421,7 +5497,7 @@ def test_to_dataframe_concat_categorical_dtype_w_pyarrow(self): ) # Don't close the client if it was passed in. - bqstorage_client._transport.grpc_channel.close.assert_not_called() + bqstorage_client._transport.close.assert_not_called() def test_to_dataframe_geography_as_object(self): pandas = pytest.importorskip("pandas") From 11de93965831311445abacaec2d7baeef21f837d Mon Sep 17 00:00:00 2001 From: Anthonios Partheniou Date: Mon, 22 Jun 2026 11:03:14 -0400 Subject: [PATCH 101/174] tests: add Python 3.15 pre-release testing (#17517) Towards b/525422520 Fixes https://github.com/googleapis/google-cloud-python/issues/16215 --- .github/workflows/gapic-generator-tests.yml | 35 ++++++++++++++++--- .../gapic/templates/noxfile.py.j2 | 8 ++--- .../templates/testing/constraints-3.15.txt.j2 | 21 +++++++++++ packages/gapic-generator/noxfile.py | 3 +- .../integration/goldens/asset/noxfile.py | 8 ++--- .../asset/testing/constraints-3.15.txt | 15 ++++++++ .../goldens/credentials/noxfile.py | 8 ++--- .../credentials/testing/constraints-3.15.txt | 12 +++++++ .../integration/goldens/eventarc/noxfile.py | 8 ++--- .../eventarc/testing/constraints-3.15.txt | 13 +++++++ .../integration/goldens/logging/noxfile.py | 8 ++--- .../logging/testing/constraints-3.15.txt | 12 +++++++ .../goldens/logging_internal/noxfile.py | 8 ++--- .../testing/constraints-3.15.txt | 12 +++++++ .../integration/goldens/redis/noxfile.py | 8 ++--- .../redis/testing/constraints-3.15.txt | 12 +++++++ .../goldens/redis_selective/noxfile.py | 8 ++--- .../testing/constraints-3.15.txt | 12 +++++++ .../goldens/storagebatchoperations/noxfile.py | 8 ++--- .../testing/constraints-3.15.txt | 12 +++++++ 20 files changed, 180 insertions(+), 51 deletions(-) create mode 100644 packages/gapic-generator/gapic/templates/testing/constraints-3.15.txt.j2 create mode 100755 packages/gapic-generator/tests/integration/goldens/asset/testing/constraints-3.15.txt create mode 100755 packages/gapic-generator/tests/integration/goldens/credentials/testing/constraints-3.15.txt create mode 100755 packages/gapic-generator/tests/integration/goldens/eventarc/testing/constraints-3.15.txt create mode 100755 packages/gapic-generator/tests/integration/goldens/logging/testing/constraints-3.15.txt create mode 100755 packages/gapic-generator/tests/integration/goldens/logging_internal/testing/constraints-3.15.txt create mode 100755 packages/gapic-generator/tests/integration/goldens/redis/testing/constraints-3.15.txt create mode 100755 packages/gapic-generator/tests/integration/goldens/redis_selective/testing/constraints-3.15.txt create mode 100755 packages/gapic-generator/tests/integration/goldens/storagebatchoperations/testing/constraints-3.15.txt diff --git a/.github/workflows/gapic-generator-tests.yml b/.github/workflows/gapic-generator-tests.yml index b557a331cf6b..f6a47939fc64 100644 --- a/.github/workflows/gapic-generator-tests.yml +++ b/.github/workflows/gapic-generator-tests.yml @@ -18,7 +18,13 @@ env: SHOWCASE_VERSION: 0.35.0 PROTOC_VERSION: 3.20.2 LATEST_STABLE_PYTHON: 3.14 - ALL_PYTHON: "['3.10', '3.11', '3.12', '3.13', '3.14']" + PRERELEASE_PYTHON: 3.15 + ALL_PYTHON: "['3.10', '3.11', '3.12', '3.13', '3.14', '3.15']" + TRIMMED_PYTHON: "['3.10', '3.14', '3.15']" + # Workaround: Allows libcst to compile on Python 3.15+ while PyO3 catches up + # Can be removed once libcst releases a version with native Python 3.15 wheels + # Follow https://github.com/Instagram/LibCST/issues/1445 for updates. + PYO3_USE_ABI3_FORWARD_COMPATIBILITY: "1" jobs: check_changes: @@ -47,6 +53,8 @@ jobs: outputs: all_python: ${{ env.ALL_PYTHON }} latest_stable_python: ${{ env.LATEST_STABLE_PYTHON }} + prerelease_python: ${{ env.PRERELEASE_PYTHON }} + trimmed_python: $${{ env.TRIMMED_PYTHON }} steps: - run: echo "Initializing config for gapic-generator" @@ -65,6 +73,12 @@ jobs: uses: actions/setup-python@v6 with: python-version: "${{ matrix.python }}" + allow-prereleases: true + # Caches compiled wheels locally to prevent building heavy libraries + # such as grpcio, which we build from scratch on every run for Python 3.15+. + # Follow https://github.com/grpc/grpc/issues/41010 for updates. + cache: 'pip' + cache-dependency-path: '**/requirements*.txt' - name: Install System Deps & Protoc run: | sudo apt-get update && sudo apt-get install -y curl pandoc unzip @@ -132,10 +146,16 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - - name: Set up Python + - name: Set up Python ${{ needs.python_config.outputs.prerelease_python }} uses: actions/setup-python@v6 with: - python-version: ${{ needs.python_config.outputs.latest_stable_python }} + python-version: ${{ needs.python_config.outputs.prerelease_python }} + allow-prereleases: true + # Caches compiled wheels locally to prevent building heavy libraries + # such as grpcio, which we build from scratch on every run for Python 3.15+. + # Follow https://github.com/grpc/grpc/issues/41010 for updates. + cache: 'pip' + cache-dependency-path: '**/requirements*.txt' - name: Install System Deps run: sudo apt-get update && sudo apt-get install -y pandoc - name: Run Goldens (Prerelease) @@ -150,7 +170,7 @@ jobs: needs: python_config strategy: matrix: - python: ["3.10", "3.14"] + python: ${{ fromJSON(needs.python_config.outputs.trimmed_python) }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 @@ -158,7 +178,12 @@ jobs: uses: actions/setup-python@v6 with: python-version: ${{ matrix.python }} - # This fixes the Pandoc error + allow-prereleases: true + # Caches compiled wheels locally to prevent building heavy libraries + # such as grpcio, which we build from scratch on every run for Python 3.15+. + # Follow https://github.com/grpc/grpc/issues/41010 for updates. + cache: 'pip' + cache-dependency-path: '**/requirements*.txt' - name: Install System Deps & Protoc run: | sudo apt-get update && sudo apt-get install -y curl pandoc unzip diff --git a/packages/gapic-generator/gapic/templates/noxfile.py.j2 b/packages/gapic-generator/gapic/templates/noxfile.py.j2 index c240871b994e..a59d98087467 100644 --- a/packages/gapic-generator/gapic/templates/noxfile.py.j2 +++ b/packages/gapic-generator/gapic/templates/noxfile.py.j2 @@ -30,14 +30,12 @@ ALL_PYTHON = [ "3.12", "3.13", "3.14", + "3.15", ] DEFAULT_PYTHON_VERSION = "3.14" -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2450): -# Switch this to Python 3.15 alpha1 -# https://peps.python.org/pep-0790/ -PREVIEW_PYTHON_VERSION = "3.14" +PREVIEW_PYTHON_VERSION = "3.15" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() @@ -567,7 +565,7 @@ def prerelease_deps(session, protobuf_implementation): ) -@nox.session(python=DEFAULT_PYTHON_VERSION) +@nox.session(python=PREVIEW_PYTHON_VERSION) @nox.parametrize( "protobuf_implementation", ["python", "upb"], diff --git a/packages/gapic-generator/gapic/templates/testing/constraints-3.15.txt.j2 b/packages/gapic-generator/gapic/templates/testing/constraints-3.15.txt.j2 new file mode 100644 index 000000000000..a2e0a3f4cb1e --- /dev/null +++ b/packages/gapic-generator/gapic/templates/testing/constraints-3.15.txt.j2 @@ -0,0 +1,21 @@ +{% from '_pypi_packages.j2' import pypi_packages %} +# We use the constraints file for the latest Python version +# (currently this file) to check that the latest +# major versions of dependencies are supported in setup.py. +# List all library dependencies and extras in this file. +# Require the latest major version be installed for each dependency. +# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", +# Then this file should have google-cloud-foo>=1 +google-api-core>=2 +google-auth>=2 +grpcio>=1 +proto-plus>=1 +protobuf>=7 +{% for package_tuple, package_info in pypi_packages.items() %} +{# Quick check to make sure `package_info.package_name` is not the package being generated so we don't circularly include this package in its own constraints file. #} +{% if api.naming.warehouse_package_name != package_info.package_name %} +{% if api.requires_package(package_tuple) %} +{{ package_info.package_name }}>={{ (package_info.upper_bound.split(".")[0] | int) - 1 }} +{% endif %} +{% endif %} +{% endfor %} diff --git a/packages/gapic-generator/noxfile.py b/packages/gapic-generator/noxfile.py index 8ef965740c2b..84d273023968 100644 --- a/packages/gapic-generator/noxfile.py +++ b/packages/gapic-generator/noxfile.py @@ -50,9 +50,10 @@ "3.12", "3.13", "3.14", + "3.15", ) -NEWEST_PYTHON = ALL_PYTHON[-1] +NEWEST_PYTHON = ALL_PYTHON[-2] @nox.session(python=ALL_PYTHON) diff --git a/packages/gapic-generator/tests/integration/goldens/asset/noxfile.py b/packages/gapic-generator/tests/integration/goldens/asset/noxfile.py index 93e185b59d11..58ded83c89ac 100755 --- a/packages/gapic-generator/tests/integration/goldens/asset/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/asset/noxfile.py @@ -37,14 +37,12 @@ "3.12", "3.13", "3.14", + "3.15", ] DEFAULT_PYTHON_VERSION = "3.14" -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2450): -# Switch this to Python 3.15 alpha1 -# https://peps.python.org/pep-0790/ -PREVIEW_PYTHON_VERSION = "3.14" +PREVIEW_PYTHON_VERSION = "3.15" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() @@ -559,7 +557,7 @@ def prerelease_deps(session, protobuf_implementation): ) -@nox.session(python=DEFAULT_PYTHON_VERSION) +@nox.session(python=PREVIEW_PYTHON_VERSION) @nox.parametrize( "protobuf_implementation", ["python", "upb"], diff --git a/packages/gapic-generator/tests/integration/goldens/asset/testing/constraints-3.15.txt b/packages/gapic-generator/tests/integration/goldens/asset/testing/constraints-3.15.txt new file mode 100755 index 000000000000..f63842dab6f9 --- /dev/null +++ b/packages/gapic-generator/tests/integration/goldens/asset/testing/constraints-3.15.txt @@ -0,0 +1,15 @@ +# We use the constraints file for the latest Python version +# (currently this file) to check that the latest +# major versions of dependencies are supported in setup.py. +# List all library dependencies and extras in this file. +# Require the latest major version be installed for each dependency. +# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", +# Then this file should have google-cloud-foo>=1 +google-api-core>=2 +google-auth>=2 +grpcio>=1 +proto-plus>=1 +protobuf>=7 +google-cloud-access-context-manager>=0 +google-cloud-os-config>=1 +grpc-google-iam-v1>=0 diff --git a/packages/gapic-generator/tests/integration/goldens/credentials/noxfile.py b/packages/gapic-generator/tests/integration/goldens/credentials/noxfile.py index c991842b24ca..af6482e5ff68 100755 --- a/packages/gapic-generator/tests/integration/goldens/credentials/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/credentials/noxfile.py @@ -37,14 +37,12 @@ "3.12", "3.13", "3.14", + "3.15", ] DEFAULT_PYTHON_VERSION = "3.14" -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2450): -# Switch this to Python 3.15 alpha1 -# https://peps.python.org/pep-0790/ -PREVIEW_PYTHON_VERSION = "3.14" +PREVIEW_PYTHON_VERSION = "3.15" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() @@ -559,7 +557,7 @@ def prerelease_deps(session, protobuf_implementation): ) -@nox.session(python=DEFAULT_PYTHON_VERSION) +@nox.session(python=PREVIEW_PYTHON_VERSION) @nox.parametrize( "protobuf_implementation", ["python", "upb"], diff --git a/packages/gapic-generator/tests/integration/goldens/credentials/testing/constraints-3.15.txt b/packages/gapic-generator/tests/integration/goldens/credentials/testing/constraints-3.15.txt new file mode 100755 index 000000000000..6bd7e1f5b03d --- /dev/null +++ b/packages/gapic-generator/tests/integration/goldens/credentials/testing/constraints-3.15.txt @@ -0,0 +1,12 @@ +# We use the constraints file for the latest Python version +# (currently this file) to check that the latest +# major versions of dependencies are supported in setup.py. +# List all library dependencies and extras in this file. +# Require the latest major version be installed for each dependency. +# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", +# Then this file should have google-cloud-foo>=1 +google-api-core>=2 +google-auth>=2 +grpcio>=1 +proto-plus>=1 +protobuf>=7 diff --git a/packages/gapic-generator/tests/integration/goldens/eventarc/noxfile.py b/packages/gapic-generator/tests/integration/goldens/eventarc/noxfile.py index 1ec5368a9dd4..9f89e95f5237 100755 --- a/packages/gapic-generator/tests/integration/goldens/eventarc/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/eventarc/noxfile.py @@ -37,14 +37,12 @@ "3.12", "3.13", "3.14", + "3.15", ] DEFAULT_PYTHON_VERSION = "3.14" -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2450): -# Switch this to Python 3.15 alpha1 -# https://peps.python.org/pep-0790/ -PREVIEW_PYTHON_VERSION = "3.14" +PREVIEW_PYTHON_VERSION = "3.15" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() @@ -559,7 +557,7 @@ def prerelease_deps(session, protobuf_implementation): ) -@nox.session(python=DEFAULT_PYTHON_VERSION) +@nox.session(python=PREVIEW_PYTHON_VERSION) @nox.parametrize( "protobuf_implementation", ["python", "upb"], diff --git a/packages/gapic-generator/tests/integration/goldens/eventarc/testing/constraints-3.15.txt b/packages/gapic-generator/tests/integration/goldens/eventarc/testing/constraints-3.15.txt new file mode 100755 index 000000000000..f85022a2fb62 --- /dev/null +++ b/packages/gapic-generator/tests/integration/goldens/eventarc/testing/constraints-3.15.txt @@ -0,0 +1,13 @@ +# We use the constraints file for the latest Python version +# (currently this file) to check that the latest +# major versions of dependencies are supported in setup.py. +# List all library dependencies and extras in this file. +# Require the latest major version be installed for each dependency. +# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", +# Then this file should have google-cloud-foo>=1 +google-api-core>=2 +google-auth>=2 +grpcio>=1 +proto-plus>=1 +protobuf>=7 +grpc-google-iam-v1>=0 diff --git a/packages/gapic-generator/tests/integration/goldens/logging/noxfile.py b/packages/gapic-generator/tests/integration/goldens/logging/noxfile.py index 448aec3ef2b0..dfe763b3d029 100755 --- a/packages/gapic-generator/tests/integration/goldens/logging/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/logging/noxfile.py @@ -37,14 +37,12 @@ "3.12", "3.13", "3.14", + "3.15", ] DEFAULT_PYTHON_VERSION = "3.14" -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2450): -# Switch this to Python 3.15 alpha1 -# https://peps.python.org/pep-0790/ -PREVIEW_PYTHON_VERSION = "3.14" +PREVIEW_PYTHON_VERSION = "3.15" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() @@ -559,7 +557,7 @@ def prerelease_deps(session, protobuf_implementation): ) -@nox.session(python=DEFAULT_PYTHON_VERSION) +@nox.session(python=PREVIEW_PYTHON_VERSION) @nox.parametrize( "protobuf_implementation", ["python", "upb"], diff --git a/packages/gapic-generator/tests/integration/goldens/logging/testing/constraints-3.15.txt b/packages/gapic-generator/tests/integration/goldens/logging/testing/constraints-3.15.txt new file mode 100755 index 000000000000..6bd7e1f5b03d --- /dev/null +++ b/packages/gapic-generator/tests/integration/goldens/logging/testing/constraints-3.15.txt @@ -0,0 +1,12 @@ +# We use the constraints file for the latest Python version +# (currently this file) to check that the latest +# major versions of dependencies are supported in setup.py. +# List all library dependencies and extras in this file. +# Require the latest major version be installed for each dependency. +# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", +# Then this file should have google-cloud-foo>=1 +google-api-core>=2 +google-auth>=2 +grpcio>=1 +proto-plus>=1 +protobuf>=7 diff --git a/packages/gapic-generator/tests/integration/goldens/logging_internal/noxfile.py b/packages/gapic-generator/tests/integration/goldens/logging_internal/noxfile.py index 448aec3ef2b0..dfe763b3d029 100755 --- a/packages/gapic-generator/tests/integration/goldens/logging_internal/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/logging_internal/noxfile.py @@ -37,14 +37,12 @@ "3.12", "3.13", "3.14", + "3.15", ] DEFAULT_PYTHON_VERSION = "3.14" -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2450): -# Switch this to Python 3.15 alpha1 -# https://peps.python.org/pep-0790/ -PREVIEW_PYTHON_VERSION = "3.14" +PREVIEW_PYTHON_VERSION = "3.15" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() @@ -559,7 +557,7 @@ def prerelease_deps(session, protobuf_implementation): ) -@nox.session(python=DEFAULT_PYTHON_VERSION) +@nox.session(python=PREVIEW_PYTHON_VERSION) @nox.parametrize( "protobuf_implementation", ["python", "upb"], diff --git a/packages/gapic-generator/tests/integration/goldens/logging_internal/testing/constraints-3.15.txt b/packages/gapic-generator/tests/integration/goldens/logging_internal/testing/constraints-3.15.txt new file mode 100755 index 000000000000..6bd7e1f5b03d --- /dev/null +++ b/packages/gapic-generator/tests/integration/goldens/logging_internal/testing/constraints-3.15.txt @@ -0,0 +1,12 @@ +# We use the constraints file for the latest Python version +# (currently this file) to check that the latest +# major versions of dependencies are supported in setup.py. +# List all library dependencies and extras in this file. +# Require the latest major version be installed for each dependency. +# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", +# Then this file should have google-cloud-foo>=1 +google-api-core>=2 +google-auth>=2 +grpcio>=1 +proto-plus>=1 +protobuf>=7 diff --git a/packages/gapic-generator/tests/integration/goldens/redis/noxfile.py b/packages/gapic-generator/tests/integration/goldens/redis/noxfile.py index d860093c9653..deedbe421748 100755 --- a/packages/gapic-generator/tests/integration/goldens/redis/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/redis/noxfile.py @@ -37,14 +37,12 @@ "3.12", "3.13", "3.14", + "3.15", ] DEFAULT_PYTHON_VERSION = "3.14" -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2450): -# Switch this to Python 3.15 alpha1 -# https://peps.python.org/pep-0790/ -PREVIEW_PYTHON_VERSION = "3.14" +PREVIEW_PYTHON_VERSION = "3.15" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() @@ -559,7 +557,7 @@ def prerelease_deps(session, protobuf_implementation): ) -@nox.session(python=DEFAULT_PYTHON_VERSION) +@nox.session(python=PREVIEW_PYTHON_VERSION) @nox.parametrize( "protobuf_implementation", ["python", "upb"], diff --git a/packages/gapic-generator/tests/integration/goldens/redis/testing/constraints-3.15.txt b/packages/gapic-generator/tests/integration/goldens/redis/testing/constraints-3.15.txt new file mode 100755 index 000000000000..6bd7e1f5b03d --- /dev/null +++ b/packages/gapic-generator/tests/integration/goldens/redis/testing/constraints-3.15.txt @@ -0,0 +1,12 @@ +# We use the constraints file for the latest Python version +# (currently this file) to check that the latest +# major versions of dependencies are supported in setup.py. +# List all library dependencies and extras in this file. +# Require the latest major version be installed for each dependency. +# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", +# Then this file should have google-cloud-foo>=1 +google-api-core>=2 +google-auth>=2 +grpcio>=1 +proto-plus>=1 +protobuf>=7 diff --git a/packages/gapic-generator/tests/integration/goldens/redis_selective/noxfile.py b/packages/gapic-generator/tests/integration/goldens/redis_selective/noxfile.py index d860093c9653..deedbe421748 100755 --- a/packages/gapic-generator/tests/integration/goldens/redis_selective/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/redis_selective/noxfile.py @@ -37,14 +37,12 @@ "3.12", "3.13", "3.14", + "3.15", ] DEFAULT_PYTHON_VERSION = "3.14" -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2450): -# Switch this to Python 3.15 alpha1 -# https://peps.python.org/pep-0790/ -PREVIEW_PYTHON_VERSION = "3.14" +PREVIEW_PYTHON_VERSION = "3.15" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() @@ -559,7 +557,7 @@ def prerelease_deps(session, protobuf_implementation): ) -@nox.session(python=DEFAULT_PYTHON_VERSION) +@nox.session(python=PREVIEW_PYTHON_VERSION) @nox.parametrize( "protobuf_implementation", ["python", "upb"], diff --git a/packages/gapic-generator/tests/integration/goldens/redis_selective/testing/constraints-3.15.txt b/packages/gapic-generator/tests/integration/goldens/redis_selective/testing/constraints-3.15.txt new file mode 100755 index 000000000000..6bd7e1f5b03d --- /dev/null +++ b/packages/gapic-generator/tests/integration/goldens/redis_selective/testing/constraints-3.15.txt @@ -0,0 +1,12 @@ +# We use the constraints file for the latest Python version +# (currently this file) to check that the latest +# major versions of dependencies are supported in setup.py. +# List all library dependencies and extras in this file. +# Require the latest major version be installed for each dependency. +# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", +# Then this file should have google-cloud-foo>=1 +google-api-core>=2 +google-auth>=2 +grpcio>=1 +proto-plus>=1 +protobuf>=7 diff --git a/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/noxfile.py b/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/noxfile.py index 9afec5aeae68..ea0dffab5b4c 100755 --- a/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/noxfile.py @@ -37,14 +37,12 @@ "3.12", "3.13", "3.14", + "3.15", ] DEFAULT_PYTHON_VERSION = "3.14" -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2450): -# Switch this to Python 3.15 alpha1 -# https://peps.python.org/pep-0790/ -PREVIEW_PYTHON_VERSION = "3.14" +PREVIEW_PYTHON_VERSION = "3.15" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() @@ -559,7 +557,7 @@ def prerelease_deps(session, protobuf_implementation): ) -@nox.session(python=DEFAULT_PYTHON_VERSION) +@nox.session(python=PREVIEW_PYTHON_VERSION) @nox.parametrize( "protobuf_implementation", ["python", "upb"], diff --git a/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/testing/constraints-3.15.txt b/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/testing/constraints-3.15.txt new file mode 100755 index 000000000000..6bd7e1f5b03d --- /dev/null +++ b/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/testing/constraints-3.15.txt @@ -0,0 +1,12 @@ +# We use the constraints file for the latest Python version +# (currently this file) to check that the latest +# major versions of dependencies are supported in setup.py. +# List all library dependencies and extras in this file. +# Require the latest major version be installed for each dependency. +# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", +# Then this file should have google-cloud-foo>=1 +google-api-core>=2 +google-auth>=2 +grpcio>=1 +proto-plus>=1 +protobuf>=7 From 36b5b7ebb01030a2d0f10d49fe4827ddc79dde9a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jun 2026 11:22:12 -0400 Subject: [PATCH 102/174] fix: bump msgpack from 1.1.1 to 1.2.1 in /packages/bigframes (#17520) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [msgpack](https://github.com/msgpack/msgpack-python) from 1.1.1 to 1.2.1.
    Release notes

    Sourced from msgpack's releases.

    v1.2.1

    What's Changed

    Full Changelog: https://github.com/msgpack/msgpack-python/compare/v1.2.0...v1.2.1

    v1.2.0

    What's Changed

    New Contributors

    ... (truncated)

    Changelog

    Sourced from msgpack's changelog.

    1.2.1

    Release Date: 2026-06-19

    Fix a segfault when calling Unpacker.unpack() or Unpacker.skip() after an unpacking failure. But note that reusing the same Unpacker instance after an unpacking failure is not supported. Please create a new Unpacker instance instead. GHSA-6v7p-g79w-8964

    1.2.0

    Release Date: 2026-06-11

    • Support free threaded Python. #654, #686
    • Dropped support for Python 3.9. #656
    • Fix missing error checks in C code. #665, #666, #667, #672
    • Fix strict_map_key option didn't work for object_pairs_hook. #673
    • Increase DEFAULT_RECURSE_LIMIT of Unpacker to 1024. #676
    • Fix memory leak when Unpacker returns error for invalid input. #671
    • Fix Packer.pack_ext_type() ignored autoreset option. #663
    • Fix Timestamp.from_datetime() returning wrong value for pre-epoch datetimes. #662
    • Fix use-after-free in unpackb() and Unpacker.unpack() for non-contiguous input. #677
    • Fix possible memory leak when calling Unpacker.__init__() several times. #687

    1.1.2

    Release Date: 2025-10-08

    This release does not change source code. It updates only building wheels:

    • Update Cython to v3.1.4
    • Update cibuildwheel to v3.2.0
    • Drop Python 3.8
    • Add Python 3.14
    • Add windows-arm
    Commits
    • 448d43f release v1.2.1 (#698)
    • 2c56ddb Merge commit from fork
    • 0f4f350 Bump pypa/cibuildwheel from 4.0.0 to 4.1.0 in the all-dependencies group (#694)
    • 11ed0a5 release v1.2.0 (#692)
    • c410a38 Bump pypa/cibuildwheel from 3.4.1 to 4.0.0 (#691)
    • 97ba6ca skip ci: remove unneeded CIBW_SKIP option
    • cdde1b0 Wheels CI hangs for MacOS Intel (#689)
    • 5eb57e1 release v1.2.0rc1 (#681)
    • 77395c1 Harden Unpacker.__init__ re-entry cleanup to prevent buffer/context leaks (...
    • 7df7136 Guard Packer buffer protocol hooks with Cython critical sections (#686)
    • Additional commits viewable in compare view

    [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=msgpack&package-manager=pip&previous-version=1.1.1&new-version=1.2.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
    Dependabot commands and options
    You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/googleapis/google-cloud-python/network/alerts).
    Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- packages/bigframes/testing/constraints-3.11.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bigframes/testing/constraints-3.11.txt b/packages/bigframes/testing/constraints-3.11.txt index 7bb201d16fcd..56456c226a69 100644 --- a/packages/bigframes/testing/constraints-3.11.txt +++ b/packages/bigframes/testing/constraints-3.11.txt @@ -311,7 +311,7 @@ mlxtend==0.23.4 more-itertools==10.7.0 moviepy==1.0.3 mpmath==1.3.0 -msgpack==1.1.1 +msgpack==1.2.1 multidict==6.6.3 multipledispatch==1.0.0 multiprocess==0.70.16 From 6fc45e3790c5a248dcec4b74799834c7b9219ef0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jun 2026 11:23:00 -0400 Subject: [PATCH 103/174] fix: bump undici and @angular/build in /packages/bigframes/bigframes/display/table_widget_angular (#17519) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [undici](https://github.com/nodejs/undici) to 6.27.0 and updates ancestor dependencies [undici](https://github.com/nodejs/undici) and [@angular/build](https://github.com/angular/angular-cli). These dependencies need to be updated together. Updates `undici` from 6.25.0 to 6.27.0
    Release notes

    Sourced from undici's releases.

    v6.27.0

    ⚠️ Security Release

    This release line addresses 4 security advisories.

    Action required: Upgrade to undici 6.27.0 or later.

    npm install undici@^6.27.0
    

    Note on patched version: the v6 fixes shipped in v6.27.0, not 6.26.0v6.26.0 contains only the chunked-EOF fix (#5308) and the version bump, none of the security fixes below.

    The v6 line is not affected by the SOCKS5 advisories (GHSA-vmh5-mc38-953g, GHSA-hm92-r4w5-c3mj), the shared-cache disclosure (GHSA-pr7r-676h-xcf6), or the 8.x-only WebSocket regression (GHSA-38rv-x7px-6hhq).

    Summary

    Advisory CVE Severity (CVSS) Fixed in Fix commit
    GHSA-vxpw-j846-p89q CVE-2026-12151 High (7.5) 6.27.0 b7f252e7
    GHSA-p88m-4jfj-68fv CVE-2026-9679 Moderate (5.9) 6.27.0 25efa447
    GHSA-g8m3-5g58-fq7m CVE-2026-11525 Low (3.7) 6.27.0 25efa447
    GHSA-35p6-xmwp-9g52 CVE-2026-6733 Low (3.7) 6.27.0 f4c31d60

    High severity

    WebSocket DoS via fragment count bypass — CVE-2026-12151

    GHSA-vxpw-j846-p89q · CWE-400, CWE-770 Fix: b7f252e7 Backport WebSocket maxPayloadSize fixes (#5423, backported to v6 in #5428)

    A malicious WebSocket server can stream a large number of small or empty continuation frames. Undici enforced a limit on cumulative payload size but did not limit the number of fragments per message, leading to unbounded memory growth and denial of service. All releases from 6.17.0 onward are affected.

    • Affected: applications using new WebSocket(...) or WebSocketStream against untrusted endpoints.
    • Workaround: none — upgrade is required.

    Moderate severity

    HTTP header injection via Set-Cookie percent-decoding — CVE-2026-9679

    ... (truncated)

    Commits

    Updates `undici` from 7.24.4 to 7.28.0
    Release notes

    Sourced from undici's releases.

    v6.27.0

    ⚠️ Security Release

    This release line addresses 4 security advisories.

    Action required: Upgrade to undici 6.27.0 or later.

    npm install undici@^6.27.0
    

    Note on patched version: the v6 fixes shipped in v6.27.0, not 6.26.0v6.26.0 contains only the chunked-EOF fix (#5308) and the version bump, none of the security fixes below.

    The v6 line is not affected by the SOCKS5 advisories (GHSA-vmh5-mc38-953g, GHSA-hm92-r4w5-c3mj), the shared-cache disclosure (GHSA-pr7r-676h-xcf6), or the 8.x-only WebSocket regression (GHSA-38rv-x7px-6hhq).

    Summary

    Advisory CVE Severity (CVSS) Fixed in Fix commit
    GHSA-vxpw-j846-p89q CVE-2026-12151 High (7.5) 6.27.0 b7f252e7
    GHSA-p88m-4jfj-68fv CVE-2026-9679 Moderate (5.9) 6.27.0 25efa447
    GHSA-g8m3-5g58-fq7m CVE-2026-11525 Low (3.7) 6.27.0 25efa447
    GHSA-35p6-xmwp-9g52 CVE-2026-6733 Low (3.7) 6.27.0 f4c31d60

    High severity

    WebSocket DoS via fragment count bypass — CVE-2026-12151

    GHSA-vxpw-j846-p89q · CWE-400, CWE-770 Fix: b7f252e7 Backport WebSocket maxPayloadSize fixes (#5423, backported to v6 in #5428)

    A malicious WebSocket server can stream a large number of small or empty continuation frames. Undici enforced a limit on cumulative payload size but did not limit the number of fragments per message, leading to unbounded memory growth and denial of service. All releases from 6.17.0 onward are affected.

    • Affected: applications using new WebSocket(...) or WebSocketStream against untrusted endpoints.
    • Workaround: none — upgrade is required.

    Moderate severity

    HTTP header injection via Set-Cookie percent-decoding — CVE-2026-9679

    ... (truncated)

    Commits

    Updates `@angular/build` from 21.2.9 to 22.0.3
    Release notes

    Sourced from @​angular/build's releases.

    22.0.3

    @​schematics/angular

    Commit Description
    fix -
0eddea898 remove default workspace vscode mcp.json configuration

    22.0.2

    @​angular/cli

    Commit Description
    fix -
136fc2714 support registry metadata fetching under bun package manager
    perf -
2653dd5c7 implement semaphore backpressure throttling in PackageManager

    @​angular/build

    Commit Description
    perf -
0b4a48add implement semaphore backpressure throttling in JavaScriptTransformer

    @​angular/ssr

    Commit Description
    fix -
d996a27e9 avoid caching non-SSG page lookups
    fix -
285a34e42 correct grammar in console warning for redirected location headers
    fix -
c8088a536 prioritize options over environment variables in AngularNodeAppEngine

    22.0.1

    @​schematics/angular

    Commit Description
    fix -
c80012294 fix browserMode option mapping in refactor-jasmine-vitest
    fix -
a9b6bd904 safely comment out multiline statements in refactor-jasmine-vitest
    fix -
12199df00 use null objects and callbacks in karma-to-vitest migration

    @​angular/cli

    Commit Description
    fix -
b54e9a549 do not sort migrations of the same version alphabetically
    fix -
d33311612 fallback to local package.json for schematic detection on first run
    fix -
918102a93 isolate temporary package installation from parent pnpm workspace
    fix -
b048b5f4a remove forceAuth and unscoped credential parsing
    fix -
277934035 validate registry option is a valid URL in ng add
    perf -
4510dae02 optimize update schematic registry query counts by fetching package metadata lazily

    @​angular/build

    Commit Description
    fix -
89d1be979 allow disabling Vitest isolation from builder
    fix -
d45b84be9 exclude JSON imports from Vite dependency optimization
    fix -
e3cab4ddd prevent concurrent stylesheet bundling esbuild context leaks
    fix -
bd413b0eb restrict application builder output paths to output directory

    22.0.0

    @​schematics/angular

    | Commit | Description |

    ... (truncated)

    Changelog

    Sourced from @​angular/build's changelog.

    22.0.3 (2026-06-18)

    @​schematics/angular

    Commit Type Description
    0eddea898 fix remove default workspace vscode mcp.json configuration

    21.2.16 (2026-06-17)

    @​angular/cli

    Commit Type Description
    77c9047ac fix update pacote to 21.5.1

    @​angular/ssr

    Commit Type Description
    d052e97da fix prioritize options over environment variables in AngularNodeAppEngine

    20.3.29 (2026-06-17)

    @​angular/cli

    Commit Type Description
    5f7c0328c fix update pacote to 21.5.1

    @​angular/ssr

    Commit Type Description
    a75d78e68 fix prioritize options over environment variables in AngularNodeAppEngine

    22.0.2 (2026-06-17)

    ... (truncated)

    Commits
    • b30b9d3 release: cut the v22.0.3 release
    • bc97bb3 build: update dependency vite to v7.3.5
    • 0eddea8 fix(@​schematics/angular): remove default workspace vscode mcp.json configuration
    • 08f9959 refactor(@​angular/cli): promote experimental MCP tools to stable
    • aab6c10 release: cut the v22.0.2 release
    • 376e4dc build: update cross-repo angular dependencies
    • d996a27 fix(@​angular/ssr): avoid caching non-SSG page lookups
    • 5714bfc build: update pnpm to v10.34.3
    • f26011a build: lock file maintenance
    • 2879ed9 build: update bazel dependencies
    • Additional commits viewable in compare view

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
    Dependabot commands and options
    You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/googleapis/google-cloud-python/network/alerts).
    Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../table_widget_angular/package-lock.json | 1492 ++++++++++------- .../display/table_widget_angular/package.json | 2 +- 2 files changed, 896 insertions(+), 598 deletions(-) diff --git a/packages/bigframes/bigframes/display/table_widget_angular/package-lock.json b/packages/bigframes/bigframes/display/table_widget_angular/package-lock.json index 80a7030ce3ac..cea8490526c6 100644 --- a/packages/bigframes/bigframes/display/table_widget_angular/package-lock.json +++ b/packages/bigframes/bigframes/display/table_widget_angular/package-lock.json @@ -18,7 +18,7 @@ "tslib": "^2.3.0" }, "devDependencies": { - "@angular/build": "^21.2.9", + "@angular/build": "^22.0.3", "@angular/cli": "^21.2.9", "@angular/compiler-cli": "^21.2.0", "esbuild": "^0.20.0", @@ -325,64 +325,63 @@ } }, "node_modules/@angular/build": { - "version": "21.2.9", - "resolved": "https://registry.npmjs.org/@angular/build/-/build-21.2.9.tgz", - "integrity": "sha512-XYP5ALB56NWvcQisznmvQdVU6WJdUCAuCAEN2eDZNVd9X1IqRNfewQfFH6FyHo7SrK4GHDReqm6xWW6rs0+weQ==", + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-22.0.3.tgz", + "integrity": "sha512-pwFDRCp+r8JK+fCtScPldizcS75wSpn3u/4goDf2FRa4Y9wzTvq6T0XpFHqdpgq6HcIlIZWwAqqW6XqEM9/pKQ==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.2102.9", + "@angular-devkit/architect": "0.2200.3", "@babel/core": "7.29.0", "@babel/helper-annotate-as-pure": "7.27.3", "@babel/helper-split-export-declaration": "7.24.7", - "@inquirer/confirm": "5.1.21", - "@vitejs/plugin-basic-ssl": "2.1.4", - "beasties": "0.4.1", + "@inquirer/confirm": "6.0.12", + "@vitejs/plugin-basic-ssl": "2.3.0", + "beasties": "0.4.2", "browserslist": "^4.26.0", - "esbuild": "0.27.3", - "https-proxy-agent": "7.0.6", - "istanbul-lib-instrument": "6.0.3", + "esbuild": "0.28.1", + "https-proxy-agent": "9.0.0", "jsonc-parser": "3.3.1", - "listr2": "9.0.5", + "listr2": "10.2.1", "magic-string": "0.30.21", "mrmime": "2.0.1", - "parse5-html-rewriting-stream": "8.0.0", + "parse5-html-rewriting-stream": "8.0.1", "picomatch": "4.0.4", "piscina": "5.1.4", - "rolldown": "1.0.0-rc.4", - "sass": "1.97.3", + "rollup": "4.60.2", + "sass": "1.99.0", "semver": "7.7.4", "source-map-support": "0.5.21", - "tinyglobby": "0.2.15", - "undici": "7.24.4", - "vite": "7.3.2", + "tinyglobby": "0.2.16", + "vite": "7.3.5", "watchpack": "2.5.1" }, "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "node": "^22.22.3 || ^24.15.0 || >=26.0.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" }, "optionalDependencies": { - "lmdb": "3.5.1" + "lmdb": "3.5.4" }, "peerDependencies": { - "@angular/compiler": "^21.0.0", - "@angular/compiler-cli": "^21.0.0", - "@angular/core": "^21.0.0", - "@angular/localize": "^21.0.0", - "@angular/platform-browser": "^21.0.0", - "@angular/platform-server": "^21.0.0", - "@angular/service-worker": "^21.0.0", - "@angular/ssr": "^21.2.9", + "@angular/compiler": "^22.0.0", + "@angular/compiler-cli": "^22.0.0", + "@angular/core": "^22.0.0", + "@angular/localize": "^22.0.0", + "@angular/platform-browser": "^22.0.0", + "@angular/platform-server": "^22.0.0", + "@angular/service-worker": "^22.0.0", + "@angular/ssr": "^22.0.3", + "istanbul-lib-instrument": "^6.0.0", "karma": "^6.4.0", "less": "^4.2.0", - "ng-packagr": "^21.0.0", + "ng-packagr": "^22.0.0", "postcss": "^8.4.0", "tailwindcss": "^2.0.0 || ^3.0.0 || ^4.0.0", "tslib": "^2.3.0", - "typescript": ">=5.9 <6.0", + "typescript": ">=6.0 <6.1", "vitest": "^4.0.8" }, "peerDependenciesMeta": { @@ -404,6 +403,9 @@ "@angular/ssr": { "optional": true }, + "istanbul-lib-instrument": { + "optional": true + }, "karma": { "optional": true }, @@ -424,10 +426,57 @@ } } }, + "node_modules/@angular/build/node_modules/@angular-devkit/architect": { + "version": "0.2200.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.2200.3.tgz", + "integrity": "sha512-Ru+ucNkTZr98gmeaBYjq3zZwh32yGofAeB8+GJL/ZNy0x+7NzK6b+OatdzwT4l7mCWFC5vL8iYu0B4++M66Jpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "22.0.3", + "rxjs": "7.8.2" + }, + "bin": { + "architect": "bin/cli.js" + }, + "engines": { + "node": "^22.22.3 || ^24.15.0 || >=26.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular/build/node_modules/@angular-devkit/core": { + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-22.0.3.tgz", + "integrity": "sha512-pBjo1JKwI8GbNdTo/Z0g+ZekqlTBCJWmzIC5fgGW9q5eRjl1y+5N5jlX8UAyyMCeUTTwsfpQdkAM2jyi/jcvjA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "8.20.0", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.4", + "rxjs": "7.8.2", + "source-map": "0.7.6" + }, + "engines": { + "node": "^22.22.3 || ^24.15.0 || >=26.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^5.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, "node_modules/@angular/build/node_modules/@esbuild/aix-ppc64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", - "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", + "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", "cpu": [ "ppc64" ], @@ -442,9 +491,9 @@ } }, "node_modules/@angular/build/node_modules/@esbuild/android-arm": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", - "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", + "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", "cpu": [ "arm" ], @@ -459,9 +508,9 @@ } }, "node_modules/@angular/build/node_modules/@esbuild/android-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", - "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", + "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", "cpu": [ "arm64" ], @@ -476,9 +525,9 @@ } }, "node_modules/@angular/build/node_modules/@esbuild/android-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", - "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", + "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", "cpu": [ "x64" ], @@ -493,9 +542,9 @@ } }, "node_modules/@angular/build/node_modules/@esbuild/darwin-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", - "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", + "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", "cpu": [ "arm64" ], @@ -510,9 +559,9 @@ } }, "node_modules/@angular/build/node_modules/@esbuild/darwin-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", - "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", + "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", "cpu": [ "x64" ], @@ -527,9 +576,9 @@ } }, "node_modules/@angular/build/node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", - "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", + "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", "cpu": [ "arm64" ], @@ -544,9 +593,9 @@ } }, "node_modules/@angular/build/node_modules/@esbuild/freebsd-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", - "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", + "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", "cpu": [ "x64" ], @@ -561,9 +610,9 @@ } }, "node_modules/@angular/build/node_modules/@esbuild/linux-arm": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", - "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", + "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", "cpu": [ "arm" ], @@ -578,9 +627,9 @@ } }, "node_modules/@angular/build/node_modules/@esbuild/linux-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", - "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", + "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", "cpu": [ "arm64" ], @@ -595,9 +644,9 @@ } }, "node_modules/@angular/build/node_modules/@esbuild/linux-ia32": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", - "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", + "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", "cpu": [ "ia32" ], @@ -612,9 +661,9 @@ } }, "node_modules/@angular/build/node_modules/@esbuild/linux-loong64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", - "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", + "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", "cpu": [ "loong64" ], @@ -629,9 +678,9 @@ } }, "node_modules/@angular/build/node_modules/@esbuild/linux-mips64el": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", - "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", + "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", "cpu": [ "mips64el" ], @@ -646,9 +695,9 @@ } }, "node_modules/@angular/build/node_modules/@esbuild/linux-ppc64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", - "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", + "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", "cpu": [ "ppc64" ], @@ -663,9 +712,9 @@ } }, "node_modules/@angular/build/node_modules/@esbuild/linux-riscv64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", - "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", + "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", "cpu": [ "riscv64" ], @@ -680,9 +729,9 @@ } }, "node_modules/@angular/build/node_modules/@esbuild/linux-s390x": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", - "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", + "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", "cpu": [ "s390x" ], @@ -697,9 +746,9 @@ } }, "node_modules/@angular/build/node_modules/@esbuild/linux-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", - "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", + "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", "cpu": [ "x64" ], @@ -714,9 +763,9 @@ } }, "node_modules/@angular/build/node_modules/@esbuild/netbsd-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", - "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", + "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", "cpu": [ "x64" ], @@ -731,9 +780,9 @@ } }, "node_modules/@angular/build/node_modules/@esbuild/openbsd-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", - "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", + "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", "cpu": [ "x64" ], @@ -748,9 +797,9 @@ } }, "node_modules/@angular/build/node_modules/@esbuild/sunos-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", - "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", + "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", "cpu": [ "x64" ], @@ -765,9 +814,9 @@ } }, "node_modules/@angular/build/node_modules/@esbuild/win32-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", - "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", + "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", "cpu": [ "arm64" ], @@ -782,9 +831,9 @@ } }, "node_modules/@angular/build/node_modules/@esbuild/win32-ia32": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", - "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", + "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", "cpu": [ "ia32" ], @@ -799,9 +848,9 @@ } }, "node_modules/@angular/build/node_modules/@esbuild/win32-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", - "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", + "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", "cpu": [ "x64" ], @@ -815,10 +864,487 @@ "node": ">=18" } }, + "node_modules/@angular/build/node_modules/@inquirer/ansi": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-2.0.7.tgz", + "integrity": "sha512-3eTuUO1vH2cZm2ZKHeQxnOqlTi9EfZDGgIe3BL3I4u+rJHocr9Fz86M4fjYABPvFnQG/gGK551HqDiIcETwU6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" + } + }, + "node_modules/@angular/build/node_modules/@inquirer/confirm": { + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-6.0.12.tgz", + "integrity": "sha512-h9FgGun3QwVYNj5TWIZZ+slii73bMoBFjPfVIGtnFuL4t8gBiNDV9PcSfIzkuxvgquJKt9nr1QzszpBzTbH8Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.1.9", + "@inquirer/type": "^4.0.5" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@angular/build/node_modules/@inquirer/core": { + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-11.2.1.tgz", + "integrity": "sha512-Qd6GJT1yVyrZZCfN8W2qKF5ApmqryXRhRKCuip8h01x2w/esJQ2XIYc6f9abMIHgKQdBfFTSOdbHRLAhuM09UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^2.0.7", + "@inquirer/figures": "^2.0.7", + "@inquirer/type": "^4.0.7", + "cli-width": "^4.1.0", + "fast-wrap-ansi": "^0.2.0", + "mute-stream": "^3.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@angular/build/node_modules/@inquirer/figures": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-2.0.7.tgz", + "integrity": "sha512-aJ8TBPOGB6f/2qziPfElISTCEd5XOYTFckA2SGjhNmiKzfK/u4ot3v0DUzGVdUnKjN10EqnnEPck36BkyfLnJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" + } + }, + "node_modules/@angular/build/node_modules/@inquirer/type": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-4.0.7.tgz", + "integrity": "sha512-t28inv14nMQ1PhKpsJPY+kEs/c00qzeCOS2gTNRyTjG5d6qsVA2fItxW4hkvGZ5lvanGLdtCzVIx5dwdRpN1+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.2.tgz", + "integrity": "sha512-dnlp69efPPg6Uaw2dVqzWRfAWRnYVb1XJ8CyyhIbZeaq4CA5/mLeZ1IEt9QqQxmbdvagjLIm2ZL8BxXv5lH4Yw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-android-arm64": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.2.tgz", + "integrity": "sha512-OqZTwDRDchGRHHm/hwLOL7uVPB9aUvI0am/eQuWMNyFHf5PSEQmyEeYYheA0EPPKUO/l0uigCp+iaTjoLjVoHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.2.tgz", + "integrity": "sha512-UwRE7CGpvSVEQS8gUMBe1uADWjNnVgP3Iusyda1nSRwNDCsRjnGc7w6El6WLQsXmZTbLZx9cecegumcitNfpmA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-darwin-x64": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.2.tgz", + "integrity": "sha512-gjEtURKLCC5VXm1I+2i1u9OhxFsKAQJKTVB8WvDAHF+oZlq0GTVFOlTlO1q3AlCTE/DF32c16ESvfgqR7343/g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.2.tgz", + "integrity": "sha512-Bcl6CYDeAgE70cqZaMojOi/eK63h5Me97ZqAQoh77VPjMysA/4ORQBRGo3rRy45x4MzVlU9uZxs8Uwy7ZaKnBw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.2.tgz", + "integrity": "sha512-LU+TPda3mAE2QB0/Hp5VyeKJivpC6+tlOXd1VMoXV/YFMvk/MNk5iXeBfB4MQGRWyOYVJ01625vjkr0Az98OJQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.2.tgz", + "integrity": "sha512-2QxQrM+KQ7DAW4o22j+XZ6RKdxjLD7BOWTP0Bv0tmjdyhXSsr2Ul1oJDQqh9Zf5qOwTuTc7Ek83mOFaKnodPjg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.2.tgz", + "integrity": "sha512-TbziEu2DVsTEOPif2mKWkMeDMLoYjx95oESa9fkQQK7r/Orta0gnkcDpzwufEcAO2BLBsD7mZkXGFqEdMRRwfw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.2.tgz", + "integrity": "sha512-bO/rVDiDUuM2YfuCUwZ1t1cP+/yqjqz+Xf2VtkdppefuOFS2OSeAfgafaHNkFn0t02hEyXngZkxtGqXcXwO8Rg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.2.tgz", + "integrity": "sha512-hr26p7e93Rl0Za+JwW7EAnwAvKkehh12BU1Llm9Ykiibg4uIr2rbpxG9WCf56GuvidlTG9KiiQT/TXT1yAWxTA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.2.tgz", + "integrity": "sha512-pOjB/uSIyDt+ow3k/RcLvUAOGpysT2phDn7TTUB3n75SlIgZzM6NKAqlErPhoFU+npgY3/n+2HYIQVbF70P9/A==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.2.tgz", + "integrity": "sha512-2/w+q8jszv9Ww1c+6uJT3OwqhdmGP2/4T17cu8WuwyUuuaCDDJ2ojdyYwZzCxx0GcsZBhzi3HmH+J5pZNXnd+Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.2.tgz", + "integrity": "sha512-11+aL5vKheYgczxtPVVRhdptAM2H7fcDR5Gw4/bTcteuZBlH4oP9f5s9zYO9aGZvoGeBpqXI/9TZZihZ609wKw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.2.tgz", + "integrity": "sha512-i16fokAGK46IVZuV8LIIwMdtqhin9hfYkCh8pf8iC3QU3LpwL+1FSFGej+O7l3E/AoknL6Dclh2oTdnRMpTzFQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.2.tgz", + "integrity": "sha512-49FkKS6RGQoriDSK/6E2GkAsAuU5kETFCh7pG4yD/ylj9rKhTmO3elsnmBvRD4PgJPds5W2PkhC82aVwmUcJ7A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.2.tgz", + "integrity": "sha512-mjYNkHPfGpUR00DuM1ZZIgs64Hpf4bWcz9Z41+4Q+pgDx73UwWdAYyf6EG/lRFldmdHHzgrYyge5akFUW0D3mQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.2.tgz", + "integrity": "sha512-ALyvJz965BQk8E9Al/JDKKDLH2kfKFLTGMlgkAbbYtZuJt9LU8DW3ZoDMCtQpXAltZxwBHevXz5u+gf0yA0YoA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.2.tgz", + "integrity": "sha512-UQjrkIdWrKI626Du8lCQ6MJp/6V1LAo2bOK9OTu4mSn8GGXIkPXk/Vsp4bLHCd9Z9Iz2OTEaokUE90VweJgIYQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.2.tgz", + "integrity": "sha512-bTsRGj6VlSdn/XD4CGyzMnzaBs9bsRxy79eTqTCBsA8TMIEky7qg48aPkvJvFe1HyzQ5oMZdg7AnVlWQSKLTnw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.2.tgz", + "integrity": "sha512-6d4Z3534xitaA1FcMWP7mQPq5zGwBmGbhphh2DwaA1aNIXUu3KTOfwrWpbwI4/Gr0uANo7NTtaykFyO2hPuFLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.2.tgz", + "integrity": "sha512-NetAg5iO2uN7eB8zE5qrZ3CSil+7IJt4WDFLcC75Ymywq1VZVD6qJ6EvNLjZ3rEm6gB7XW5JdT60c6MN35Z85Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.2.tgz", + "integrity": "sha512-NCYhOotpgWZ5kdxCZsv6Iudx0wX8980Q/oW4pNFNihpBKsDbEA1zpkfxJGC0yugsUuyDZ7gL37dbzwhR0VI7pQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.2.tgz", + "integrity": "sha512-RXsaOqXxfoUBQoOgvmmijVxJnW2IGB0eoMO7F8FAjaj0UTywUO/luSqimWBJn04WNgUkeNhh7fs7pESXajWmkg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.2.tgz", + "integrity": "sha512-qdAzEULD+/hzObedtmV6iBpdL5TIbKVztGiK7O3/KYSf+HIzU257+MX1EXJcyIiDbMAqmbwaufcYPvyRryeZtA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.2.tgz", + "integrity": "sha512-Nd/SgG27WoA9e+/TdK74KnHz852TLa94ovOYySo/yMPuTmpckK/jIF2jSwS3g7ELSKXK13/cVdmg1Z/DaCWKxA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@angular/build/node_modules/agent-base": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-9.0.0.tgz", + "integrity": "sha512-TQf59BsZnytt8GdJKLPfUZ54g/iaUL2OWDSFCCvMOhsHduDQxO8xC4PNeyIkVcA5KwL2phPSv0douC0fgWzmnA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/@angular/build/node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@angular/build/node_modules/entities": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-8.0.0.tgz", + "integrity": "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/@angular/build/node_modules/esbuild": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", - "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", + "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -829,32 +1355,151 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.3", - "@esbuild/android-arm": "0.27.3", - "@esbuild/android-arm64": "0.27.3", - "@esbuild/android-x64": "0.27.3", - "@esbuild/darwin-arm64": "0.27.3", - "@esbuild/darwin-x64": "0.27.3", - "@esbuild/freebsd-arm64": "0.27.3", - "@esbuild/freebsd-x64": "0.27.3", - "@esbuild/linux-arm": "0.27.3", - "@esbuild/linux-arm64": "0.27.3", - "@esbuild/linux-ia32": "0.27.3", - "@esbuild/linux-loong64": "0.27.3", - "@esbuild/linux-mips64el": "0.27.3", - "@esbuild/linux-ppc64": "0.27.3", - "@esbuild/linux-riscv64": "0.27.3", - "@esbuild/linux-s390x": "0.27.3", - "@esbuild/linux-x64": "0.27.3", - "@esbuild/netbsd-arm64": "0.27.3", - "@esbuild/netbsd-x64": "0.27.3", - "@esbuild/openbsd-arm64": "0.27.3", - "@esbuild/openbsd-x64": "0.27.3", - "@esbuild/openharmony-arm64": "0.27.3", - "@esbuild/sunos-x64": "0.27.3", - "@esbuild/win32-arm64": "0.27.3", - "@esbuild/win32-ia32": "0.27.3", - "@esbuild/win32-x64": "0.27.3" + "@esbuild/aix-ppc64": "0.28.1", + "@esbuild/android-arm": "0.28.1", + "@esbuild/android-arm64": "0.28.1", + "@esbuild/android-x64": "0.28.1", + "@esbuild/darwin-arm64": "0.28.1", + "@esbuild/darwin-x64": "0.28.1", + "@esbuild/freebsd-arm64": "0.28.1", + "@esbuild/freebsd-x64": "0.28.1", + "@esbuild/linux-arm": "0.28.1", + "@esbuild/linux-arm64": "0.28.1", + "@esbuild/linux-ia32": "0.28.1", + "@esbuild/linux-loong64": "0.28.1", + "@esbuild/linux-mips64el": "0.28.1", + "@esbuild/linux-ppc64": "0.28.1", + "@esbuild/linux-riscv64": "0.28.1", + "@esbuild/linux-s390x": "0.28.1", + "@esbuild/linux-x64": "0.28.1", + "@esbuild/netbsd-arm64": "0.28.1", + "@esbuild/netbsd-x64": "0.28.1", + "@esbuild/openbsd-arm64": "0.28.1", + "@esbuild/openbsd-x64": "0.28.1", + "@esbuild/openharmony-arm64": "0.28.1", + "@esbuild/sunos-x64": "0.28.1", + "@esbuild/win32-arm64": "0.28.1", + "@esbuild/win32-ia32": "0.28.1", + "@esbuild/win32-x64": "0.28.1" + } + }, + "node_modules/@angular/build/node_modules/https-proxy-agent": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-9.0.0.tgz", + "integrity": "sha512-/MVmHp58WkOypgFhCLk4fzpPcFQvTJ/e6LBI7irpIO2HfxUbpmYoHF+KzipzJpxxzJu7aJNWQ0xojJ/dzV2G5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "9.0.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@angular/build/node_modules/listr2": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-10.2.1.tgz", + "integrity": "sha512-7I5knELsJKTUjXG+A6BkKAiGkW1i25fNa/xlUl9hFtk15WbE9jndA89xu5FzQKrY5llajE1hfZZFMILXkDHk/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "cli-truncate": "^5.2.0", + "eventemitter3": "^5.0.4", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^10.0.0" + }, + "engines": { + "node": ">=22.13.0" + } + }, + "node_modules/@angular/build/node_modules/mute-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-3.0.0.tgz", + "integrity": "sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@angular/build/node_modules/parse5-html-rewriting-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-8.0.1.tgz", + "integrity": "sha512-NaRku2aMpUN1Sh1Gyk1KWUh2A7EJx2c6qYzvwsPtqhoHoaURshdrceYK3LunVCm3WHhm6FS7Vcczbvdh3/UIVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^8.0.0", + "parse5": "^8.0.0", + "parse5-sax-parser": "^8.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/@angular/build/node_modules/rollup": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.2.tgz", + "integrity": "sha512-J9qZyW++QK/09NyN/zeO0dG/1GdGfyp9lV8ajHnRVLfo/uFsbji5mHnDgn/qYdUHyCkM2N+8VyspgZclfAh0eQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.60.2", + "@rollup/rollup-android-arm64": "4.60.2", + "@rollup/rollup-darwin-arm64": "4.60.2", + "@rollup/rollup-darwin-x64": "4.60.2", + "@rollup/rollup-freebsd-arm64": "4.60.2", + "@rollup/rollup-freebsd-x64": "4.60.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.60.2", + "@rollup/rollup-linux-arm-musleabihf": "4.60.2", + "@rollup/rollup-linux-arm64-gnu": "4.60.2", + "@rollup/rollup-linux-arm64-musl": "4.60.2", + "@rollup/rollup-linux-loong64-gnu": "4.60.2", + "@rollup/rollup-linux-loong64-musl": "4.60.2", + "@rollup/rollup-linux-ppc64-gnu": "4.60.2", + "@rollup/rollup-linux-ppc64-musl": "4.60.2", + "@rollup/rollup-linux-riscv64-gnu": "4.60.2", + "@rollup/rollup-linux-riscv64-musl": "4.60.2", + "@rollup/rollup-linux-s390x-gnu": "4.60.2", + "@rollup/rollup-linux-x64-gnu": "4.60.2", + "@rollup/rollup-linux-x64-musl": "4.60.2", + "@rollup/rollup-openbsd-x64": "4.60.2", + "@rollup/rollup-openharmony-arm64": "4.60.2", + "@rollup/rollup-win32-arm64-msvc": "4.60.2", + "@rollup/rollup-win32-ia32-msvc": "4.60.2", + "@rollup/rollup-win32-x64-gnu": "4.60.2", + "@rollup/rollup-win32-x64-msvc": "4.60.2", + "fsevents": "~2.3.2" + } + }, + "node_modules/@angular/build/node_modules/wrap-ansi": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-10.0.0.tgz", + "integrity": "sha512-SGcvg80f0wUy2/fXES19feHMz8E0JoXv2uNgHOu4Dgi2OrCy1lqwFYEJz1BLbDI0exjPMe/ZdzZ/YpGECBG/aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.3", + "string-width": "^8.2.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/@angular/cli": { @@ -1538,44 +2183,7 @@ ], "license": "MIT", "engines": { - "node": ">=20.19.0" - } - }, - "node_modules/@emnapi/core": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", - "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@emnapi/wasi-threads": "1.2.1", - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/runtime": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", - "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", - "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "tslib": "^2.4.0" + "node": ">=20.19.0" } }, "node_modules/@esbuild/aix-ppc64": { @@ -1868,9 +2476,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", - "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", + "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", "cpu": [ "arm64" ], @@ -1902,9 +2510,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", - "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", + "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", "cpu": [ "arm64" ], @@ -1936,9 +2544,9 @@ } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", - "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", + "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", "cpu": [ "arm64" ], @@ -2432,16 +3040,6 @@ "node": ">=18.0.0" } }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz", - "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -2510,9 +3108,9 @@ } }, "node_modules/@lmdb/lmdb-darwin-arm64": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.5.1.tgz", - "integrity": "sha512-tpfN4kKrrMpQ+If1l8bhmoNkECJi0iOu6AEdrTJvWVC+32sLxTARX5Rsu579mPImRP9YFWfWgeRQ5oav7zApQQ==", + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.5.4.tgz", + "integrity": "sha512-Kk4Kz3iyu1QiLsLZBS9Af1eSKUC8VR2T+/jyE2iAyuGw2VwK08pp5iTbZnXn6sWu0LogO/RFktMxOjiDA2sS3w==", "cpu": [ "arm64" ], @@ -2524,9 +3122,9 @@ ] }, "node_modules/@lmdb/lmdb-darwin-x64": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.5.1.tgz", - "integrity": "sha512-+a2tTfc3rmWhLAolFUWRgJtpSuu+Fw/yjn4rF406NMxhfjbMuiOUTDRvRlMFV+DzyjkwnokisskHbCWkS3Ly5w==", + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.5.4.tgz", + "integrity": "sha512-BEe5Rp3trn26oxoXOVL5HVDoiYmjUDwr8NRPkBOdUdCSBEorKI+7JrZLRKAdxO+G6cGQLgseXk0gR7qIQa7aGw==", "cpu": [ "x64" ], @@ -2538,9 +3136,9 @@ ] }, "node_modules/@lmdb/lmdb-linux-arm": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.5.1.tgz", - "integrity": "sha512-0EgcE6reYr8InjD7V37EgXcYrloqpxVPINy3ig1MwDSbl6LF/vXTYRH9OE1Ti1D8YZnB35ZH9aTcdfSb5lql2A==", + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.5.4.tgz", + "integrity": "sha512-SGbFR7816uBcTHc2ZY4S6WyOkl9bICnzqTQd2Mv4V/j24cfds88xx2nC6cm/y8zGQL7Ds31YF/5NGxjgcdM5Hw==", "cpu": [ "arm" ], @@ -2552,9 +3150,9 @@ ] }, "node_modules/@lmdb/lmdb-linux-arm64": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.5.1.tgz", - "integrity": "sha512-aoERa5B6ywXdyFeYGQ1gbQpkMkDbEo45qVoXE5QpIRavqjnyPwjOulMkmkypkmsbJ5z4Wi0TBztON8agCTG0Vg==", + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.5.4.tgz", + "integrity": "sha512-cUXEengO8o60v1SWerJTH4/RH4U3+9jC0/4njp2Z9NdmvaGzhKsbRM2wpXuRYrN8tytsoJCg0SvWEWwHAwLbCA==", "cpu": [ "arm64" ], @@ -2566,9 +3164,9 @@ ] }, "node_modules/@lmdb/lmdb-linux-x64": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.5.1.tgz", - "integrity": "sha512-SqNDY1+vpji7bh0sFH5wlWyFTOzjbDOl0/kB5RLLYDAFyd/uw3n7wyrmas3rYPpAW7z18lMOi1yKlTPv967E3g==", + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.5.4.tgz", + "integrity": "sha512-Gxq8jpgOWXwd0PUR+c9R2Ik1/uBnGd5GMIIzRRDqABCkvmjtC3KWcyhesV9jSPCz759isl0NlbsstZ2oyvk8lA==", "cpu": [ "x64" ], @@ -2580,9 +3178,9 @@ ] }, "node_modules/@lmdb/lmdb-win32-arm64": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-arm64/-/lmdb-win32-arm64-3.5.1.tgz", - "integrity": "sha512-50v0O1Lt37cwrmR9vWZK5hRW0Aw+KEmxJJ75fge/zIYdvNKB/0bSMSVR5Uc2OV9JhosIUyklOmrEvavwNJ8D6w==", + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-arm64/-/lmdb-win32-arm64-3.5.4.tgz", + "integrity": "sha512-pKv1DJ1bPZAaHkdFsSz5IDfUG8x9vntgquXF9/Dm2xuupcIe/EkLzylpoBxppFVK5vzbV561Dq26jNY2fIMA7g==", "cpu": [ "arm64" ], @@ -2594,9 +3192,9 @@ ] }, "node_modules/@lmdb/lmdb-win32-x64": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.5.1.tgz", - "integrity": "sha512-qwosvPyl+zpUlp3gRb7UcJ3H8S28XHCzkv0Y0EgQToXjQP91ZD67EHSCDmaLjtKhe+GVIW5om1KUpzVLA0l6pg==", + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.5.4.tgz", + "integrity": "sha512-JF1BmLCm9kGEVZgYmJq43zeQVdHVgAJnTi/NURWEsy6L1ZrrlSmdltS+D17QN4LODwf+1LMXAA9auIZVXtWwzw==", "cpu": [ "x64" ], @@ -2649,9 +3247,9 @@ } }, "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", - "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.4.tgz", + "integrity": "sha512-LCkGo6JDfaBhgST7UpPWgNgLINpcpabaHfyz5OBx75nUYxBsaEPxjnyNjWpeb/xBup/682QnBfRBy2/LvPutZQ==", "cpu": [ "arm64" ], @@ -2663,9 +3261,9 @@ ] }, "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", - "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.4.tgz", + "integrity": "sha512-zExlW9zUJKZH/tOtVMttwjKa4Xm/3KcNjnE3dPN92uCktwavMxpgCA3MoJK/DOnTWsQgo224OaST27/mPNAf+w==", "cpu": [ "x64" ], @@ -2677,9 +3275,9 @@ ] }, "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", - "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.4.tgz", + "integrity": "sha512-Tg3yX65f5GbtXLkrYEHE5oibZG9epyYWas7FogTTEJeDEF9JlXJzKgXaNhT3UXlTOeA+AfZpYZYZ0uPj7Cfquw==", "cpu": [ "arm" ], @@ -2691,9 +3289,9 @@ ] }, "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", - "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.4.tgz", + "integrity": "sha512-dgX0P/9wGPJeHFBG+ZmhgE6bmtMt7NP5CRBGyyktpopdk/mW4POnrpQsSLtKI1dwpc+pPLuXHDh6vvskyQE/sw==", "cpu": [ "arm64" ], @@ -2705,9 +3303,9 @@ ] }, "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", - "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.4.tgz", + "integrity": "sha512-8TNXMEjJc3QEy7R/x1INhgiU+XakDAFUzBhaz7+Rbrs8NH5UQeHQxxmzsSBJGyV6I1jW79undiQm8tOI+D+8FQ==", "cpu": [ "x64" ], @@ -2719,9 +3317,9 @@ ] }, "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", - "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.4.tgz", + "integrity": "sha512-CmCXPQrkbwExx3j946/PtHWHbYJiCRBRDl4BlkRQcJB/YOwQxJRTpoo7aTsortjgoJ1x7opzTSxn7C+ASSLVjQ==", "cpu": [ "x64" ], @@ -3055,25 +3653,6 @@ "node": ">= 10" } }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", - "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@tybys/wasm-util": "^0.10.1" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" - }, - "peerDependencies": { - "@emnapi/core": "^1.7.1", - "@emnapi/runtime": "^1.7.1" - } - }, "node_modules/@npmcli/agent": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-4.0.0.tgz", @@ -3282,16 +3861,6 @@ "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/@oxc-project/types": { - "version": "0.113.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.113.0.tgz", - "integrity": "sha512-Tp3XmgxwNQ9pEN9vxgJBAqdRamHibi76iowQ38O2I4PMpcvNRQNVsU2n1x1nv9yh0XoTrGFzf7cZSGxmixxrhA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/Boshen" - } - }, "node_modules/@parcel/watcher": { "version": "2.5.6", "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz", @@ -3610,234 +4179,6 @@ "license": "MIT", "optional": true }, - "node_modules/@rolldown/binding-android-arm64": { - "version": "1.0.0-rc.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.4.tgz", - "integrity": "sha512-vRq9f4NzvbdZavhQbjkJBx7rRebDKYR9zHfO/Wg486+I7bSecdUapzCm5cyXoK+LHokTxgSq7A5baAXUZkIz0w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.0.0-rc.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.4.tgz", - "integrity": "sha512-kFgEvkWLqt3YCgKB5re9RlIrx9bRsvyVUnaTakEpOPuLGzLpLapYxE9BufJNvPg8GjT6mB1alN4yN1NjzoeM8Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.0.0-rc.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.4.tgz", - "integrity": "sha512-JXmaOJGsL/+rsmMfutcDjxWM2fTaVgCHGoXS7nE8Z3c9NAYjGqHvXrAhMUZvMpHS/k7Mg+X7n/MVKb7NYWKKww==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.0.0-rc.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.4.tgz", - "integrity": "sha512-ep3Catd6sPnHTM0P4hNEvIv5arnDvk01PfyJIJ+J3wVCG1eEaPo09tvFqdtcaTrkwQy0VWR24uz+cb4IsK53Qw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.0.0-rc.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.4.tgz", - "integrity": "sha512-LwA5ayKIpnsgXJEwWc3h8wPiS33NMIHd9BhsV92T8VetVAbGe2qXlJwNVDGHN5cOQ22R9uYvbrQir2AB+ntT2w==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.0.0-rc.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.4.tgz", - "integrity": "sha512-AC1WsGdlV1MtGay/OQ4J9T7GRadVnpYRzTcygV1hKnypbYN20Yh4t6O1Sa2qRBMqv1etulUknqXjc3CTIsBu6A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.0.0-rc.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.4.tgz", - "integrity": "sha512-lU+6rgXXViO61B4EudxtVMXSOfiZONR29Sys5VGSetUY7X8mg9FCKIIjcPPj8xNDeYzKl+H8F/qSKOBVFJChCQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.0.0-rc.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.4.tgz", - "integrity": "sha512-DZaN1f0PGp/bSvKhtw50pPsnln4T13ycDq1FrDWRiHmWt1JeW+UtYg9touPFf8yt993p8tS2QjybpzKNTxYEwg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.0.0-rc.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.4.tgz", - "integrity": "sha512-RnGxwZLN7fhMMAItnD6dZ7lvy+TI7ba+2V54UF4dhaWa/p8I/ys1E73KO6HmPmgz92ZkfD8TXS1IMV8+uhbR9g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.0.0-rc.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.4.tgz", - "integrity": "sha512-6lcI79+X8klGiGd8yHuTgQRjuuJYNggmEml+RsyN596P23l/zf9FVmJ7K0KVKkFAeYEdg0iMUKyIxiV5vebDNQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-wasm32-wasi": { - "version": "1.0.0-rc.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.4.tgz", - "integrity": "sha512-wz7ohsKCAIWy91blZ/1FlpPdqrsm1xpcEOQVveWoL6+aSPKL4VUcoYmmzuLTssyZxRpEwzuIxL/GDsvpjaBtOw==", - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@napi-rs/wasm-runtime": "^1.1.1" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.0.0-rc.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.4.tgz", - "integrity": "sha512-cfiMrfuWCIgsFmcVG0IPuO6qTRHvF7NuG3wngX1RZzc6dU8FuBFb+J3MIR5WrdTNozlumfgL4cvz+R4ozBCvsQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.0.0-rc.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.4.tgz", - "integrity": "sha512-p6UeR9y7ht82AH57qwGuFYn69S6CZ7LLKdCKy/8T3zS9VTrJei2/CGsTUV45Da4Z9Rbhc7G4gyWQ/Ioamqn09g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-rc.4", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.4.tgz", - "integrity": "sha512-1BrrmTu0TWfOP1riA8uakjFc9bpIUGzVKETsOtzY39pPga8zELGDl8eu1Dx7/gjM5CAz14UknsUMpBO8L+YntQ==", - "dev": true, - "license": "MIT" - }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.60.3", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.3.tgz", @@ -4315,17 +4656,6 @@ "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/@tybys/wasm-util": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", - "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@types/chai": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", @@ -4352,16 +4682,16 @@ "license": "MIT" }, "node_modules/@vitejs/plugin-basic-ssl": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-2.1.4.tgz", - "integrity": "sha512-HXciTXN/sDBYWgeAD4V4s0DN0g72x5mlxQhHxtYu3Tt8BLa6MzcJZUyDVFCdtjNs3bfENVHVzOsmooTVuNgAAw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-2.3.0.tgz", + "integrity": "sha512-bdyo8rB3NnQbikdMpHaML9Z1OZPBu6fFOBo+OtxsBlvMJtysWskmBcnbIDhUqgC8tcxNv/a+BcV5U+2nQMm1OQ==", "dev": true, "license": "MIT", "engines": { "node": "^18.0.0 || ^20.0.0 || >=22.0.0" }, "peerDependencies": { - "vite": "^6.0.0 || ^7.0.0" + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/@vitest/expect": { @@ -4662,9 +4992,9 @@ } }, "node_modules/beasties": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/beasties/-/beasties-0.4.1.tgz", - "integrity": "sha512-2Imdcw3LznDuxAbJM26RHniOLAzE6WgrK8OuvVXCQtNBS8rsnD9zsSEa3fHl4hHpUY7BYTlrpvtPVbvu9G6neg==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/beasties/-/beasties-0.4.2.tgz", + "integrity": "sha512-NvcGjG/7AVUAfRbvrJmHunDQS9uHnE6Q/7AkaPr8oKE8HjOlpjRG5075z/th2Tmlezk3VlaaS8+X9I1RwHJMQw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -5657,6 +5987,23 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-string-truncated-width": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-string-truncated-width/-/fast-string-truncated-width-3.0.3.tgz", + "integrity": "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-string-width": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fast-string-width/-/fast-string-width-3.0.2.tgz", + "integrity": "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-string-truncated-width": "^3.0.2" + } + }, "node_modules/fast-uri": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.1.tgz", @@ -5674,6 +6021,16 @@ ], "license": "BSD-3-Clause" }, + "node_modules/fast-wrap-ansi": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/fast-wrap-ansi/-/fast-wrap-ansi-0.2.2.tgz", + "integrity": "sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-string-width": "^3.0.2" + } + }, "node_modules/fdir": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", @@ -6212,33 +6569,6 @@ "dev": true, "license": "ISC" }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", - "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/core": "^7.23.9", - "@babel/parser": "^7.23.9", - "@istanbuljs/schema": "^0.1.3", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/jose": { "version": "6.2.3", "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.3.tgz", @@ -6419,9 +6749,9 @@ } }, "node_modules/lmdb": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-3.5.1.tgz", - "integrity": "sha512-NYHA0MRPjvNX+vSw8Xxg6FLKxzAG+e7Pt8RqAQA/EehzHVXq9SxDqJIN3JL1hK0dweb884y8kIh6rkWvPyg9Wg==", + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-3.5.4.tgz", + "integrity": "sha512-9FKQA6G1MMtqNxfxvSBNXD/axeG2QRjYbNh0/ykRL5xYcRbCm2vXq7B9bhc7nSuKdHzr8/BHIwfPuYYH1UsXXw==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -6438,13 +6768,13 @@ "download-lmdb-prebuilds": "bin/download-prebuilds.js" }, "optionalDependencies": { - "@lmdb/lmdb-darwin-arm64": "3.5.1", - "@lmdb/lmdb-darwin-x64": "3.5.1", - "@lmdb/lmdb-linux-arm": "3.5.1", - "@lmdb/lmdb-linux-arm64": "3.5.1", - "@lmdb/lmdb-linux-x64": "3.5.1", - "@lmdb/lmdb-win32-arm64": "3.5.1", - "@lmdb/lmdb-win32-x64": "3.5.1" + "@lmdb/lmdb-darwin-arm64": "3.5.4", + "@lmdb/lmdb-darwin-x64": "3.5.4", + "@lmdb/lmdb-linux-arm": "3.5.4", + "@lmdb/lmdb-linux-arm64": "3.5.4", + "@lmdb/lmdb-linux-x64": "3.5.4", + "@lmdb/lmdb-win32-arm64": "3.5.4", + "@lmdb/lmdb-win32-x64": "3.5.4" } }, "node_modules/log-symbols": { @@ -6828,9 +7158,9 @@ "license": "MIT" }, "node_modules/msgpackr": { - "version": "1.11.12", - "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.12.tgz", - "integrity": "sha512-RBdJ1Un7yGlXWajrkxcSa93nvQ0w4zBf60c0yYv7YtBelP8H2FA7XsfBbMHtXKXUMUxH7zV3Zuozh+kUQWhHvg==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.12.1.tgz", + "integrity": "sha512-4EUH9tQHnMmEgzW/MdAP0KIfa1T9AF+htl0ffe2n5vb2EKn9y2co8ccpgWko6S52Jy1PQZKwRnx5/KkYjtd9MQ==", "dev": true, "license": "MIT", "optional": true, @@ -6839,9 +7169,9 @@ } }, "node_modules/msgpackr-extract": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", - "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.4.tgz", + "integrity": "sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -6853,12 +7183,12 @@ "download-msgpackr-prebuilds": "bin/download-prebuilds.js" }, "optionalDependencies": { - "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", - "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.4" } }, "node_modules/mute-stream": { @@ -6960,9 +7290,9 @@ } }, "node_modules/node-gyp/node_modules/undici": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.25.0.tgz", - "integrity": "sha512-ZgpWDC5gmNiuY9CnLVXEH8rl50xhRCuLNA97fAUnKi8RRuV4E6KG31pDTsLVUKnohJE0I3XDrTeEydAXRw47xg==", + "version": "6.27.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.27.0.tgz", + "integrity": "sha512-YmfV3YnEDzXRC5lZ2jWtWWHKGUm1zIt8AhesR1tens+HTNv+YZlN/dp6G727LOvMJ8xjP9Be7Y2Sdr96LDm+pg==", "dev": true, "license": "MIT", "engines": { @@ -7681,38 +8011,6 @@ "dev": true, "license": "MIT" }, - "node_modules/rolldown": { - "version": "1.0.0-rc.4", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.4.tgz", - "integrity": "sha512-V2tPDUrY3WSevrvU2E41ijZlpF+5PbZu4giH+VpNraaadsJGHa4fR6IFwsocVwEXDoAdIv5qgPPxgrvKAOIPtA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@oxc-project/types": "=0.113.0", - "@rolldown/pluginutils": "1.0.0-rc.4" - }, - "bin": { - "rolldown": "bin/cli.mjs" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "optionalDependencies": { - "@rolldown/binding-android-arm64": "1.0.0-rc.4", - "@rolldown/binding-darwin-arm64": "1.0.0-rc.4", - "@rolldown/binding-darwin-x64": "1.0.0-rc.4", - "@rolldown/binding-freebsd-x64": "1.0.0-rc.4", - "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.4", - "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.4", - "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.4", - "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.4", - "@rolldown/binding-linux-x64-musl": "1.0.0-rc.4", - "@rolldown/binding-openharmony-arm64": "1.0.0-rc.4", - "@rolldown/binding-wasm32-wasi": "1.0.0-rc.4", - "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.4", - "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.4" - } - }, "node_modules/rollup": { "version": "4.60.3", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.3.tgz", @@ -7792,14 +8090,14 @@ "license": "MIT" }, "node_modules/sass": { - "version": "1.97.3", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.97.3.tgz", - "integrity": "sha512-fDz1zJpd5GycprAbu4Q2PV/RprsRtKC/0z82z0JLgdytmcq0+ujJbJ/09bPGDxCLkKY3Np5cRAOcWiVkLXJURg==", + "version": "1.99.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.99.0.tgz", + "integrity": "sha512-kgW13M54DUB7IsIRM5LvJkNlpH+WhMpooUcaWGFARkF1Tc82v9mIWkCbCYf+MBvpIUBSeSOTilpZjEPr2VYE6Q==", "dev": true, "license": "MIT", "dependencies": { "chokidar": "^4.0.0", - "immutable": "^5.0.2", + "immutable": "^5.1.5", "source-map-js": ">=0.6.2 <2.0.0" }, "bin": { @@ -8328,14 +8626,14 @@ } }, "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", "dev": true, "license": "MIT", "dependencies": { "fdir": "^6.5.0", - "picomatch": "^4.0.3" + "picomatch": "^4.0.4" }, "engines": { "node": ">=12.0.0" @@ -8461,9 +8759,9 @@ } }, "node_modules/undici": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.4.tgz", - "integrity": "sha512-BM/JzwwaRXxrLdElV2Uo6cTLEjhSb3WXboncJamZ15NgUURmvlXvxa6xkwIOILIjPNo9i8ku136ZvWV0Uly8+w==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.28.0.tgz", + "integrity": "sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==", "dev": true, "license": "MIT", "engines": { @@ -8532,9 +8830,9 @@ } }, "node_modules/vite": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.2.tgz", - "integrity": "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.5.tgz", + "integrity": "sha512-KuOaNhcnGFN2zIPGA7wRmzF+lJA1sea7rHq17aiJ++9lzY1WWG6Jpwqwe1KNbRVPIqHmr8GLYx7jbrQcN/7/ww==", "dev": true, "license": "MIT", "dependencies": { diff --git a/packages/bigframes/bigframes/display/table_widget_angular/package.json b/packages/bigframes/bigframes/display/table_widget_angular/package.json index 80d2ebe916bc..85641cf47535 100644 --- a/packages/bigframes/bigframes/display/table_widget_angular/package.json +++ b/packages/bigframes/bigframes/display/table_widget_angular/package.json @@ -22,7 +22,7 @@ "tslib": "^2.3.0" }, "devDependencies": { - "@angular/build": "^21.2.9", + "@angular/build": "^22.0.3", "@angular/cli": "^21.2.9", "@angular/compiler-cli": "^21.2.0", "jsdom": "^28.0.0", From f23063f9182cdec868c16afb80304892850fbe88 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jun 2026 11:24:10 -0400 Subject: [PATCH 104/174] fix: bump langsmith from 0.8.0 to 0.8.18 in /packages/bigframes (#17518) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [langsmith](https://github.com/langchain-ai/langsmith-sdk) from 0.8.0 to 0.8.18.
    Release notes

    Sourced from langsmith's releases.

    v0.8.18

    What's Changed

    Full Changelog: https://github.com/langchain-ai/langsmith-sdk/compare/v0.8.17...v0.8.18

    v0.8.17

    What's Changed

    New Contributors

    Full Changelog: https://github.com/langchain-ai/langsmith-sdk/compare/v0.8.16...v0.8.17

    v0.8.16

    What's Changed

    ... (truncated)

    Commits
    • 31c2bf6 release(py): 0.8.18 (#3063)
    • 8955b68 chore: reconcile bumpversion config and mandate release process for agents (#...
    • 411401f test(python): fix integration assertions for updated attachment error message...
    • 9c55156 Merge commit from fork
    • 5b2bd8d chore(deps): bump the npm_and_yarn group across 2 directories with 2 updates ...
    • d8642f9 chore(deps): bump the npm_and_yarn group across 4 directories with 4 updates ...
    • 953c2e5 chore(deps-dev): bump langchain-anthropic from 1.4.4 to 1.4.6 in /python (#3044)
    • 5513699 chore(deps): bump starlette from 1.0.1 to 1.3.1 in /python (#3039)
    • 8becdef chore(deps): bump cryptography from 46.0.7 to 48.0.1 in /python (#3038)
    • 1a9c522 chore(deps): bump aiohttp from 3.14.0 to 3.14.1 in /python (#3037)
    • Additional commits viewable in compare view

    [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=langsmith&package-manager=pip&previous-version=0.8.0&new-version=0.8.18)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
    Dependabot commands and options
    You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/googleapis/google-cloud-python/network/alerts).
    Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- packages/bigframes/testing/constraints-3.11.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bigframes/testing/constraints-3.11.txt b/packages/bigframes/testing/constraints-3.11.txt index 56456c226a69..1f569a4f244c 100644 --- a/packages/bigframes/testing/constraints-3.11.txt +++ b/packages/bigframes/testing/constraints-3.11.txt @@ -269,7 +269,7 @@ langchain==0.3.27 langchain-core==0.3.72 langchain-text-splitters==0.3.9 langcodes==3.5.0 -langsmith==0.8.0 +langsmith==0.8.18 language_data==1.3.0 launchpadlib==1.10.16 lazr.restfulclient==0.14.4 From 2f893b1b53e7394655fd204d1f8a138212ad8227 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jun 2026 13:12:06 -0400 Subject: [PATCH 105/174] fix: bump @angular/common, @angular/forms, @angular/platform-browser and @angular/router in /packages/bigframes/bigframes/display/table_widget_angular (#17525) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [@angular/common](https://github.com/angular/angular/tree/HEAD/packages/common), [@angular/forms](https://github.com/angular/angular/tree/HEAD/packages/forms), [@angular/platform-browser](https://github.com/angular/angular/tree/HEAD/packages/platform-browser) and [@angular/router](https://github.com/angular/angular/tree/HEAD/packages/router). These dependencies needed to be updated together. Updates `@angular/common` from 21.2.11 to 22.0.2
    Release notes

    Sourced from @​angular/common's releases.

    22.0.2

    common

    Commit Description
    fix -
94ea403563 escape anchor fragment in shadow DOM name selector
    fix -
6c1f3e9d49 skip transfer cache for uncacheable HTTP traffic (#69316)

    compiler

    Commit Description
    fix -
6f1171991a restrict possible event handler check to property names longer than 2 characters

    core

    Commit Description
    fix -
528a34f766 avoid caching missing locale data
    fix -
e17e8d5422 escape overlapping comment delimiters in escapeCommentText
    fix -
59dea13f80 guard against DOM clobbering in declareExperimentalWebMcpTool
    fix -
3a48abc15c preserve leave animation for sibling instances sharing a TNode
    fix -
93d0a5f95c prevent unsubscribe during emit from throwing off other listeners
    fix -
b32ee7ceb3 treat iframe credentialless as security-sensitive
    perf -
f902d1d35e detect existing signal dependency without checking all producer links

    http

    Commit Description
    fix -
6867f77ec7 distinguish repeated transfer cache params
    fix -
7ef1399068 skip transfer cache for fetch credentialed requests (#69316)

    migrations

    Commit Description
    fix -
15314c1736 migration skip any target are not build or test

    22.0.1

    common

    Commit Description
    fix -
c4b5fa3c92 escape CSS string-terminating characters in escapeCssUrl
    fix -
dfff57ede9 Limits date format string length
    fix -
3c2892c8df prevent prototype pollution in formatDateTime
    fix -
1d87c49f6e use cryptographically secure SHA-256 for transfer cache key generation

    compiler

    Commit Description
    fix -
1ee224ca30 disallow i18n event attributes
    fix -
a56f1cdf8f more robust logic to check if regex can be optimized
    fix -
5946c18275 sanitize href/xlink:href attributes of any element of the MathML namespace
    fix -
393b84caf8 sanitize two-way properties

    compiler-cli

    Commit Description
    fix -
3d9ca2f173 bind switch exhaustive check expressions

    core

    ... (truncated)

    Changelog

    Sourced from @​angular/common's changelog.

    22.0.2 (2026-06-17)

    common

    Commit Type Description
    94ea403563 fix escape anchor fragment in shadow DOM name selector
    6c1f3e9d49 fix skip transfer cache for uncacheable HTTP traffic (#69316)

    compiler

    Commit Type Description
    6f1171991a fix restrict possible event handler check to property names longer than 2 characters

    core

    Commit Type Description
    528a34f766 fix avoid caching missing locale data
    e17e8d5422 fix escape overlapping comment delimiters in escapeCommentText
    59dea13f80 fix guard against DOM clobbering in declareExperimentalWebMcpTool
    3a48abc15c fix preserve leave animation for sibling instances sharing a TNode
    93d0a5f95c fix prevent unsubscribe during emit from throwing off other listeners
    b32ee7ceb3 fix treat iframe credentialless as security-sensitive
    f902d1d35e perf detect existing signal dependency without checking all producer links

    http

    Commit Type Description
    6867f77ec7 fix distinguish repeated transfer cache params
    7ef1399068 fix skip transfer cache for fetch credentialed requests (#69316)

    migrations

    Commit Type Description
    15314c1736 fix migration skip any target are not build or test

    22.1.0-next.0 (2026-06-10)

    Deprecations

    http

    • HttpClient.jsonp, HttpClientJsonpModule, and related JSONP classes/functions are deprecated. Use standard HTTP requests instead.

    common

    Commit Type Description
    1ad6824d0d fix skip transfer cache for uncacheable HTTP traffic (#69017)

    compiler

    Commit Type Description
    25c744c4d0 fix support foreign components defined outside top-level scope

    compiler-cli

    Commit Type Description
    aeb55c8bc1 fix allow passing uninvoked signals as foreign component props
    7c60a98b3c fix support import aliases in foreignImports (#68674)

    ... (truncated)

    Commits
    • 6867f77 fix(http): distinguish repeated transfer cache params
    • 6c1f3e9 fix(common): skip transfer cache for uncacheable HTTP traffic (#69316)
    • 7ef1399 fix(http): skip transfer cache for fetch credentialed requests (#69316)
    • 94ea403 fix(common): escape anchor fragment in shadow DOM name selector
    • 2dd65d2 fix(http): pass down the reportUploadProgress and reportDownloadProgress ...
    • 1bd5a56 docs: deprecate XHR support for server-side rendering in HTTP docs and recomm...
    • 3c2892c fix(common): prevent prototype pollution in formatDateTime
    • c4b5fa3 fix(common): escape CSS string-terminating characters in escapeCssUrl
    • 4254eb4 fix(http): preserve empty referrer option in HttpRequest
    • 167bd4c fix(http): Rejects non-HTTP(S) URLs in JSONP requests
    • Additional commits viewable in compare view

    Updates `@angular/forms` from 21.2.11 to 22.0.2
    Release notes

    Sourced from @​angular/forms's releases.

    22.0.2

    common

    Commit Description
    fix -
94ea403563 escape anchor fragment in shadow DOM name selector
    fix -
6c1f3e9d49 skip transfer cache for uncacheable HTTP traffic (#69316)

    compiler

    Commit Description
    fix -
6f1171991a restrict possible event handler check to property names longer than 2 characters

    core

    Commit Description
    fix -
528a34f766 avoid caching missing locale data
    fix -
e17e8d5422 escape overlapping comment delimiters in escapeCommentText
    fix -
59dea13f80 guard against DOM clobbering in declareExperimentalWebMcpTool
    fix -
3a48abc15c preserve leave animation for sibling instances sharing a TNode
    fix -
93d0a5f95c prevent unsubscribe during emit from throwing off other listeners
    fix -
b32ee7ceb3 treat iframe credentialless as security-sensitive
    perf -
f902d1d35e detect existing signal dependency without checking all producer links

    http

    Commit Description
    fix -
6867f77ec7 distinguish repeated transfer cache params
    fix -
7ef1399068 skip transfer cache for fetch credentialed requests (#69316)

    migrations

    Commit Description
    fix -
15314c1736 migration skip any target are not build or test

    22.0.1

    common

    Commit Description
    fix -
c4b5fa3c92 escape CSS string-terminating characters in escapeCssUrl
    fix -
dfff57ede9 Limits date format string length
    fix -
3c2892c8df prevent prototype pollution in formatDateTime
    fix -
1d87c49f6e use cryptographically secure SHA-256 for transfer cache key generation

    compiler

    Commit Description
    fix -
1ee224ca30 disallow i18n event attributes
    fix -
a56f1cdf8f more robust logic to check if regex can be optimized
    fix -
5946c18275 sanitize href/xlink:href attributes of any element of the MathML namespace
    fix -
393b84caf8 sanitize two-way properties

    compiler-cli

    Commit Description
    fix -
3d9ca2f173 bind switch exhaustive check expressions

    core

    ... (truncated)

    Changelog

    Sourced from @​angular/forms's changelog.

    22.0.2 (2026-06-17)

    common

    Commit Type Description
    94ea403563 fix escape anchor fragment in shadow DOM name selector
    6c1f3e9d49 fix skip transfer cache for uncacheable HTTP traffic (#69316)

    compiler

    Commit Type Description
    6f1171991a fix restrict possible event handler check to property names longer than 2 characters

    core

    Commit Type Description
    528a34f766 fix avoid caching missing locale data
    e17e8d5422 fix escape overlapping comment delimiters in escapeCommentText
    59dea13f80 fix guard against DOM clobbering in declareExperimentalWebMcpTool
    3a48abc15c fix preserve leave animation for sibling instances sharing a TNode
    93d0a5f95c fix prevent unsubscribe during emit from throwing off other listeners
    b32ee7ceb3 fix treat iframe credentialless as security-sensitive
    f902d1d35e perf detect existing signal dependency without checking all producer links

    http

    Commit Type Description
    6867f77ec7 fix distinguish repeated transfer cache params
    7ef1399068 fix skip transfer cache for fetch credentialed requests (#69316)

    migrations

    Commit Type Description
    15314c1736 fix migration skip any target are not build or test

    22.1.0-next.0 (2026-06-10)

    Deprecations

    http

    • HttpClient.jsonp, HttpClientJsonpModule, and related JSONP classes/functions are deprecated. Use standard HTTP requests instead.

    common

    Commit Type Description
    1ad6824d0d fix skip transfer cache for uncacheable HTTP traffic (#69017)

    compiler

    Commit Type Description
    25c744c4d0 fix support foreign components defined outside top-level scope

    compiler-cli

    Commit Type Description
    aeb55c8bc1 fix allow passing uninvoked signals as foreign component props
    7c60a98b3c fix support import aliases in foreignImports (#68674)

    ... (truncated)

    Commits
    • 3f05543 refactor(forms): fix initWebMcpForm description to be required
    • 11836a6 fix(forms): delay mcp reading the form model by a tick
    • e51ad37 fix(forms): remove animationstart listener on component destroy to prevent me...
    • 85d2d10 fix(forms): harden FormGroup control lookups against prototype shadowing
    • cdcea80 fix(core): require WebMCP tool descriptions
    • 55b7b5a fix(forms): set additionalProperties: false on generated WebMCP form
    • e81c7e8 refactor(forms): type built-in getError results
    • eb600aa refactor(forms): mark date and limit signal forms APIs public
    • a97d5ec build: update minimum supported Node.js versions
    • 3b4ef1e perf(forms): avoid redundant invalidations in parser errors signal
    • Additional commits viewable in compare view

    Updates `@angular/platform-browser` from 21.2.11 to 22.0.2
    Release notes

    Sourced from @​angular/platform-browser's releases.

    22.0.2

    common

    Commit Description
    fix -
94ea403563 escape anchor fragment in shadow DOM name selector
    fix -
6c1f3e9d49 skip transfer cache for uncacheable HTTP traffic (#69316)

    compiler

    Commit Description
    fix -
6f1171991a restrict possible event handler check to property names longer than 2 characters

    core

    Commit Description
    fix -
528a34f766 avoid caching missing locale data
    fix -
e17e8d5422 escape overlapping comment delimiters in escapeCommentText
    fix -
59dea13f80 guard against DOM clobbering in declareExperimentalWebMcpTool
    fix -
3a48abc15c preserve leave animation for sibling instances sharing a TNode
    fix -
93d0a5f95c prevent unsubscribe during emit from throwing off other listeners
    fix -
b32ee7ceb3 treat iframe credentialless as security-sensitive
    perf -
f902d1d35e detect existing signal dependency without checking all producer links

    http

    Commit Description
    fix -
6867f77ec7 distinguish repeated transfer cache params
    fix -
7ef1399068 skip transfer cache for fetch credentialed requests (#69316)

    migrations

    Commit Description
    fix -
15314c1736 migration skip any target are not build or test

    22.0.1

    common

    Commit Description
    fix -
c4b5fa3c92 escape CSS string-terminating characters in escapeCssUrl
    fix -
dfff57ede9 Limits date format string length
    fix -
3c2892c8df prevent prototype pollution in formatDateTime
    fix -
1d87c49f6e use cryptographically secure SHA-256 for transfer cache key generation

    compiler

    Commit Description
    fix -
1ee224ca30 disallow i18n event attributes
    fix -
a56f1cdf8f more robust logic to check if regex can be optimized
    fix -
5946c18275 sanitize href/xlink:href attributes of any element of the MathML namespace
    fix -
393b84caf8 sanitize two-way properties

    compiler-cli

    Commit Description
    fix -
3d9ca2f173 bind switch exhaustive check expressions

    core

    ... (truncated)

    Changelog

    Sourced from @​angular/platform-browser's changelog.

    22.0.2 (2026-06-17)

    common

    Commit Type Description
    94ea403563 fix escape anchor fragment in shadow DOM name selector
    6c1f3e9d49 fix skip transfer cache for uncacheable HTTP traffic (#69316)

    compiler

    Commit Type Description
    6f1171991a fix restrict possible event handler check to property names longer than 2 characters

    core

    Commit Type Description
    528a34f766 fix avoid caching missing locale data
    e17e8d5422 fix escape overlapping comment delimiters in escapeCommentText
    59dea13f80 fix guard against DOM clobbering in declareExperimentalWebMcpTool
    3a48abc15c fix preserve leave animation for sibling instances sharing a TNode
    93d0a5f95c fix prevent unsubscribe during emit from throwing off other listeners
    b32ee7ceb3 fix treat iframe credentialless as security-sensitive
    f902d1d35e perf detect existing signal dependency without checking all producer links

    http

    Commit Type Description
    6867f77ec7 fix distinguish repeated transfer cache params
    7ef1399068 fix skip transfer cache for fetch credentialed requests (#69316)

    migrations

    Commit Type Description
    15314c1736 fix migration skip any target are not build or test

    22.1.0-next.0 (2026-06-10)

    Deprecations

    http

    • HttpClient.jsonp, HttpClientJsonpModule, and related JSONP classes/functions are deprecated. Use standard HTTP requests instead.

    common

    Commit Type Description
    1ad6824d0d fix skip transfer cache for uncacheable HTTP traffic (#69017)

    compiler

    Commit Type Description
    25c744c4d0 fix support foreign components defined outside top-level scope

    compiler-cli

    Commit Type Description
    aeb55c8bc1 fix allow passing uninvoked signals as foreign component props
    7c60a98b3c fix support import aliases in foreignImports (#68674)

    ... (truncated)

    Commits
    • d9c38e5 docs: fix typos in source code comments
    • a97d5ec build: update minimum supported Node.js versions
    • 0d9a245 fix(core): sanitize meta selectors
    • ad717df refactor(core): use the @Service decorator where possible.
    • 5a7c1e6 feat(core): add ability to cache resources for SSR
    • b8d3f36 feat(compiler-cli): add support for Node.js 26.0.0
    • 4ad3a1f refactor(core): Don't throw when there are not async metadata
    • 7f3f3d7 ci: remove remainings of saucelabs tests
    • 9f479ae feat(core): Update Testability to use PendingTasks for stability indicator
    • 0454d4c refactor(core): deprecate withIncrementalHydration
    • Additional commits viewable in compare view

    Updates `@angular/router` from 21.2.11 to 22.0.2
    Release notes

    Sourced from @​angular/router's releases.

    22.0.2

    common

    Commit Description
    fix -
94ea403563 escape anchor fragment in shadow DOM name selector
    fix -
6c1f3e9d49 skip transfer cache for uncacheable HTTP traffic (#69316)

    compiler

    Commit Description
    fix -
6f1171991a restrict possible event handler check to property names longer than 2 characters

    core

    Commit Description
    fix -
528a34f766 avoid caching missing locale data
    fix -
e17e8d5422 escape overlapping comment delimiters in escapeCommentText
    fix -
59dea13f80 guard against DOM clobbering in declareExperimentalWebMcpTool
    fix -
3a48abc15c preserve leave animation for sibling instances sharing a TNode
    fix -
93d0a5f95c prevent unsubscribe during emit from throwing off other listeners
    fix -
b32ee7ceb3 treat iframe credentialless as security-sensitive
    perf -
f902d1d35e detect existing signal dependency without checking all producer links

    http

    Commit Description
    fix -
6867f77ec7 distinguish repeated transfer cache params
    fix -
7ef1399068 skip transfer cache for fetch credentialed requests (#69316)

    migrations

    Commit Description
    fix -
15314c1736 migration skip any target are not build or test

    22.0.1

    common

    Commit Description
    fix -
c4b5fa3c92 escape CSS string-terminating characters in escapeCssUrl
    fix -
dfff57ede9 Limits date format string length
    fix -
3c2892c8df prevent prototype pollution in formatDateTime
    fix -
1d87c49f6e use cryptographically secure SHA-256 for transfer cache key generation

    compiler

    Commit Description
    fix -
1ee224ca30 disallow i18n event attributes
    fix -
a56f1cdf8f more robust logic to check if regex can be optimized
    fix -
5946c18275 sanitize href/xlink:href attributes of any element of the MathML namespace
    fix -
393b84caf8 sanitize two-way properties

    compiler-cli

    Commit Description
    fix -
3d9ca2f173 bind switch exhaustive check expressions

    core

    ... (truncated)

    Changelog

    Sourced from @​angular/router's changelog.

    22.0.2 (2026-06-17)

    common

    Commit Type Description
    94ea403563 fix escape anchor fragment in shadow DOM name selector
    6c1f3e9d49 fix skip transfer cache for uncacheable HTTP traffic (#69316)

    compiler

    Commit Type Description
    6f1171991a fix restrict possible event handler check to property names longer than 2 characters

    core

    Commit Type Description
    528a34f766 fix avoid caching missing locale data
    e17e8d5422 fix escape overlapping comment delimiters in escapeCommentText
    59dea13f80 fix guard against DOM clobbering in declareExperimentalWebMcpTool
    3a48abc15c fix preserve leave animation for sibling instances sharing a TNode
    93d0a5f95c fix prevent unsubscribe during emit from throwing off other listeners
    b32ee7ceb3 fix treat iframe credentialless as security-sensitive
    f902d1d35e perf detect existing signal dependency without checking all producer links

    http

    Commit Type Description
    6867f77ec7 fix distinguish repeated transfer cache params
    7ef1399068 fix skip transfer cache for fetch credentialed requests (#69316)

    migrations

    Commit Type Description
    15314c1736 fix migration skip any target are not build or test

    22.1.0-next.0 (2026-06-10)

    Deprecations

    http

    • HttpClient.jsonp, HttpClientJsonpModule, and related JSONP classes/functions are deprecated. Use standard HTTP requests instead.

    common

    Commit Type Description
    1ad6824d0d fix skip transfer cache for uncacheable HTTP traffic (#69017)

    compiler

    Commit Type Description
    25c744c4d0 fix support foreign components defined outside top-level scope

    compiler-cli

    Commit Type Description
    aeb55c8bc1 fix allow passing uninvoked signals as foreign component props
    7c60a98b3c fix support import aliases in foreignImports (#68674)

    ... (truncated)

    Commits
    • 81cb457 refactor(router): Add handling for ActivatedRoute-scoped injector
    • 43edc84 fix(router): use native URL object for navigation boundary and comparison
    • 76a8c87 refactor(core): Split the ng global into internal and external objects
    • a97d5ec build: update minimum supported Node.js versions
    • 3e5ab7b fix(router): skip scroll-to-top on initial navigation when hydrating
    • 3e7117d fix(router): Add strict typing on 'getResolvedTitleForRoute'
    • e9d1c7e refactor(router): Move target RouterState creation before 'blocking' stage
    • ad717df refactor(core): use the @Service decorator where possible.
    • b8d3f36 feat(compiler-cli): add support for Node.js 26.0.0
    • 8a7f955 docs: correct "Angular JS" to "AngularJS"
    • Additional commits viewable in compare view

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
    Dependabot commands and options
    You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/googleapis/google-cloud-python/network/alerts).
    Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../table_widget_angular/package-lock.json | 64 +++++++++---------- .../display/table_widget_angular/package.json | 8 +-- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/packages/bigframes/bigframes/display/table_widget_angular/package-lock.json b/packages/bigframes/bigframes/display/table_widget_angular/package-lock.json index cea8490526c6..bcca8b065f22 100644 --- a/packages/bigframes/bigframes/display/table_widget_angular/package-lock.json +++ b/packages/bigframes/bigframes/display/table_widget_angular/package-lock.json @@ -8,12 +8,12 @@ "name": "table-widget-angular", "version": "0.0.0", "dependencies": { - "@angular/common": "^21.2.0", + "@angular/common": "^22.0.2", "@angular/compiler": "^21.2.0", "@angular/core": "^21.2.0", - "@angular/forms": "^21.2.0", - "@angular/platform-browser": "^21.2.0", - "@angular/router": "^21.2.0", + "@angular/forms": "^22.0.2", + "@angular/platform-browser": "^22.0.2", + "@angular/router": "^22.0.2", "rxjs": "~7.8.0", "tslib": "^2.3.0" }, @@ -1538,18 +1538,18 @@ } }, "node_modules/@angular/common": { - "version": "21.2.11", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-21.2.11.tgz", - "integrity": "sha512-3Z3SABXpzM6fkX21WCRP6IwrjxNQVHM/3Fk2OXScExOAzpaOpS2bDgS4NB6rtCbmzKL/NFSp7ZPIZigfdqnWGw==", + "version": "22.0.2", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-22.0.2.tgz", + "integrity": "sha512-XSkHYRwrM54v4GZ+fg9KU1KbSIE/iQF33VXKo5zqVNKO11MnAbJ59qzyqX/5EzSeogHyBoHApprFKACsCAKm/Q==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + "node": "^22.22.3 || ^24.15.0 || >=26.0.0" }, "peerDependencies": { - "@angular/core": "21.2.11", + "@angular/core": "22.0.2", "rxjs": "^6.5.3 || ^7.4.0" } }, @@ -1624,39 +1624,40 @@ } }, "node_modules/@angular/forms": { - "version": "21.2.11", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-21.2.11.tgz", - "integrity": "sha512-F67V612wHxPXHrbp825VirYfGPKBUM8PvL9atN2Ku1fsdGSFPU3hTxu1HU8fKYLLBpKYVVuqFqzaU/qIpTXGYA==", + "version": "22.0.2", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-22.0.2.tgz", + "integrity": "sha512-k2WhkE8Of8/JRYEojSgfygiXbP6I7f/yZ/jgJzFGRC1FlF5w5erQMFx8KPg1J5CRE8kYPzW8rM4tSVCq7AaDUg==", "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.0.0", - "tslib": "^2.3.0" + "tslib": "^2.3.0", + "zod": "^4.0.10" }, "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + "node": "^22.22.3 || ^24.15.0 || >=26.0.0" }, "peerDependencies": { - "@angular/common": "21.2.11", - "@angular/core": "21.2.11", - "@angular/platform-browser": "21.2.11", + "@angular/common": "22.0.2", + "@angular/core": "22.0.2", + "@angular/platform-browser": "22.0.2", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/platform-browser": { - "version": "21.2.11", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-21.2.11.tgz", - "integrity": "sha512-Uz/KwGjSEvbE8J9kNSSetzxhBWjCXv9OuxH1w2WkW6jLNU3vgvzuKX7SXDyUys6KJv5TqkClJ9BLeU11QbmJdw==", + "version": "22.0.2", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-22.0.2.tgz", + "integrity": "sha512-xUkpJo/Jwa7rgpoSnZs5TeuOD3SDQL+CPJrMGjHivsqWMcAqzSNnIOcbNDJRSxAYkZ9zlJ1+h39JWSUk99rRBw==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + "node": "^22.22.3 || ^24.15.0 || >=26.0.0" }, "peerDependencies": { - "@angular/animations": "21.2.11", - "@angular/common": "21.2.11", - "@angular/core": "21.2.11" + "@angular/animations": "22.0.2", + "@angular/common": "22.0.2", + "@angular/core": "22.0.2" }, "peerDependenciesMeta": { "@angular/animations": { @@ -1665,20 +1666,20 @@ } }, "node_modules/@angular/router": { - "version": "21.2.11", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-21.2.11.tgz", - "integrity": "sha512-IB7/KuRDsxAjCOxYNccq2LdCTKuu59cx5MmOhrt+TarvkNE/xdlFkP7vtrCl44DJt0q7/tveWvsn5oqTw7rN7A==", + "version": "22.0.2", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-22.0.2.tgz", + "integrity": "sha512-uiYlcbOyBliFq1v7O3nMyZtM8scDBurjk4AU2wEPWxSVAXuEjyfnAvowyPzVzGYAEKrsYtcg2TWSsQraqHUbnA==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + "node": "^22.22.3 || ^24.15.0 || >=26.0.0" }, "peerDependencies": { - "@angular/common": "21.2.11", - "@angular/core": "21.2.11", - "@angular/platform-browser": "21.2.11", + "@angular/common": "22.0.2", + "@angular/core": "22.0.2", + "@angular/platform-browser": "22.0.2", "rxjs": "^6.5.3 || ^7.4.0" } }, @@ -9784,7 +9785,6 @@ "version": "4.3.6", "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" diff --git a/packages/bigframes/bigframes/display/table_widget_angular/package.json b/packages/bigframes/bigframes/display/table_widget_angular/package.json index 85641cf47535..c72168675b20 100644 --- a/packages/bigframes/bigframes/display/table_widget_angular/package.json +++ b/packages/bigframes/bigframes/display/table_widget_angular/package.json @@ -12,12 +12,12 @@ "private": true, "packageManager": "npm@11.7.0", "dependencies": { - "@angular/common": "^21.2.0", + "@angular/common": "^22.0.2", "@angular/compiler": "^21.2.0", "@angular/core": "^21.2.0", - "@angular/forms": "^21.2.0", - "@angular/platform-browser": "^21.2.0", - "@angular/router": "^21.2.0", + "@angular/forms": "^22.0.2", + "@angular/platform-browser": "^22.0.2", + "@angular/router": "^22.0.2", "rxjs": "~7.8.0", "tslib": "^2.3.0" }, From e7268785c6736c10c1337160b4d8606975062637 Mon Sep 17 00:00:00 2001 From: sadd amr3e Date: Mon, 22 Jun 2026 23:28:42 +0530 Subject: [PATCH 106/174] fix(bigframes): world-readable temp zip in create_cloud_function (#17522) Repro against the unpatched `create_cloud_function` archive step: archive_path : /tmp/tmpXXXX.zip # sibling of the 0700 TemporaryDirectory dir removed : True zip remains : True # survives TemporaryDirectory cleanup zip perms : 0o644 world-readable: True `shutil.make_archive(directory, "zip", directory)` appends `.zip` to `base_name`, so the archive lands at `.zip`, a sibling of the temp dir rather than inside it. That copy of the generated cloud function source (which embeds the cloudpickled UDF) is created mode 0644 in the shared system temp directory and is not removed when the `TemporaryDirectory` is cleaned up, so any other local user can read it. Fix keeps the sources in a subdirectory and writes the archive inside the 0700 `TemporaryDirectory`, so it inherits the restrictive permissions and is cleaned up with the rest of the scratch space. - [x] Ensure the tests and linter pass - [x] Code coverage does not decrease (if any source code was changed) - [ ] Appropriate docs were updated (if necessary) --- .../bigframes/functions/_function_client.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/bigframes/bigframes/functions/_function_client.py b/packages/bigframes/bigframes/functions/_function_client.py index 81c0c089a4c8..69f99b50276f 100644 --- a/packages/bigframes/bigframes/functions/_function_client.py +++ b/packages/bigframes/bigframes/functions/_function_client.py @@ -358,13 +358,22 @@ def create_cloud_function( config = func_def # Build and deploy folder structure containing cloud function - with tempfile.TemporaryDirectory() as directory: + with tempfile.TemporaryDirectory() as scratch_dir: + # Keep the generated sources in a subdirectory so the archive can be + # written inside the 0700 TemporaryDirectory. shutil.make_archive + # appends ".zip" to base_name, so archiving `directory` into itself + # would leave a world-readable copy of the (pickled) user code as a + # sibling of the temp dir that also survives the cleanup. + directory = os.path.join(scratch_dir, "src") + os.mkdir(directory) entry_point = self._generate_cloud_function_code( config.code, directory, udf_signature=config.signature, ) - archive_path = shutil.make_archive(directory, "zip", directory) + archive_path = shutil.make_archive( + os.path.join(scratch_dir, "source"), "zip", directory + ) # We are creating cloud function source code from the currently running # python version. Use the same version to deploy. This is necessary From 746474f78fd29f70b592ff0ebacf7e19ce6122d5 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Mon, 22 Jun 2026 11:18:06 -0700 Subject: [PATCH 107/174] ci(kokoro): fix `core_deps_from_source` for `google-auth` (#17526) Fixes: https://github.com/googleapis/google-cloud-python/issues/17527 See logs: https://fusion2.corp.google.com/ci;prev=s/kokoro/prod:cloud-devrel%2Fclient-libraries%2Fpython%2Fgoogleapis%2Fgoogle-cloud-python%2Fpresubmit%2Fsystem/activity/53fd6866-f69c-4bad-922e-f806b3833299/log?q=google-cloud-python&s=p --- .kokoro/system.sh | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.kokoro/system.sh b/.kokoro/system.sh index 469d0e81c7fa..e0c7e71c1ad7 100755 --- a/.kokoro/system.sh +++ b/.kokoro/system.sh @@ -60,8 +60,15 @@ run_package_test() { PROJECT_ID=$(cat "${KOKORO_GFILE_DIR}/google-auth-project-id.json") GOOGLE_APPLICATION_CREDENTIALS="${KOKORO_GFILE_DIR}/google-auth-service-account.json" - NOX_FILE="system_tests/noxfile.py" - NOX_SESSION="" + # Note: system.sh is also reused for monorepo-wide continuous unit test jobs + # like `core_deps_from_source` and `prerelease_deps`. For google-auth, we only + # want to override NOX_FILE to system_tests/noxfile.py when running actual system tests. + if [[ -z "${NOX_SESSION}" || "${NOX_SESSION}" == "system-"* ]]; then + NOX_FILE="system_tests/noxfile.py" + NOX_SESSION="" + else + NOX_FILE="noxfile.py" + fi ;; *) PROJECT_ID=$(cat "${KOKORO_GFILE_DIR}/project-id.json") From 172302b809b0ff13267f18b5e7dd24be0dce2f70 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Mon, 22 Jun 2026 13:50:50 -0700 Subject: [PATCH 108/174] ci(bigquery-storage): fix `core_deps_from_source` and `prerelease_deps` by installing extras (#17529) fixes: https://github.com/googleapis/google-cloud-python/issues/17530 Log: https://btx.cloud.google.com/invocations/bf99245e-a50a-4863-941e-a29163224a9d/targets/cloud-devrel%2Fclient-libraries%2Fpython%2Fgoogleapis%2Fgoogle-cloud-python%2Fpresubmit%2Fsystem/log --- .../bigquery-storage-integration.yaml | 9 +++++++++ packages/google-cloud-bigquery-storage/noxfile.py | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.librarian/generator-input/client-post-processing/bigquery-storage-integration.yaml b/.librarian/generator-input/client-post-processing/bigquery-storage-integration.yaml index 0a495b68d521..6449c88e1791 100644 --- a/.librarian/generator-input/client-post-processing/bigquery-storage-integration.yaml +++ b/.librarian/generator-input/client-post-processing/bigquery-storage-integration.yaml @@ -28,6 +28,15 @@ replacements: "pyarrow", ] count: 1 + - paths: [ + packages/google-cloud-bigquery-storage/noxfile.py, + ] + before: | + \ # Install all dependencies\n session.install\("-e", "\."\) + after: | + # Install all dependencies + session.install("-e", f".[{','.join(UNIT_TEST_EXTRAS)}]") + count: 2 - paths: [ packages/google-cloud-bigquery-storage/noxfile.py, ] diff --git a/packages/google-cloud-bigquery-storage/noxfile.py b/packages/google-cloud-bigquery-storage/noxfile.py index e7c22b165e90..4ec53338e333 100644 --- a/packages/google-cloud-bigquery-storage/noxfile.py +++ b/packages/google-cloud-bigquery-storage/noxfile.py @@ -507,7 +507,7 @@ def prerelease_deps(session, protobuf_implementation): """ # Install all dependencies - session.install("-e", ".") + session.install("-e", f".[{','.join(UNIT_TEST_EXTRAS)}]") # Install dependencies for the unit test environment unit_deps_all = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_EXTERNAL_DEPENDENCIES @@ -618,7 +618,7 @@ def core_deps_from_source(session, protobuf_implementation): """ # Install all dependencies - session.install("-e", ".") + session.install("-e", f".[{','.join(UNIT_TEST_EXTRAS)}]") # Install dependencies for the unit test environment unit_deps_all = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_EXTERNAL_DEPENDENCIES From f6937b33e31a4c3e884165b582442274a366a995 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Mon, 22 Jun 2026 17:06:23 -0400 Subject: [PATCH 109/174] chore(main): release google-cloud-bigtable 2.39.0 (#17497) :robot: I have created a release *beep* *boop* --- ## [2.39.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-bigtable-v2.38.0...google-cloud-bigtable-v2.39.0) (2026-06-22) ### Features * added client side metric instrumentation to read_rows and mutate_rows ([#16758](https://github.com/googleapis/google-cloud-python/issues/16758)) ([4005e66](https://github.com/googleapis/google-cloud-python/commit/4005e660a38fd770f8754af1cd07d6d8aa9ed60e)) * **bigtable:** add client side metric instrumentation to basic rpcs ([#16712](https://github.com/googleapis/google-cloud-python/issues/16712)) ([636af26](https://github.com/googleapis/google-cloud-python/commit/636af26677af5be906220ad39d670e74daca58e0)) * **bigtable:** add view_parameters support to execute_query ([#17382](https://github.com/googleapis/google-cloud-python/issues/17382)) ([2695aad](https://github.com/googleapis/google-cloud-python/commit/2695aad5c2949e20e77ae9dd432c6fc8ef787952)) * support row_range in sample_row_keys method ([#17330](https://github.com/googleapis/google-cloud-python/issues/17330)) ([384724c](https://github.com/googleapis/google-cloud-python/commit/384724c2d4c955e15274e9824bcdb93c685b79f6)), closes [#17329](https://github.com/googleapis/google-cloud-python/issues/17329) * update API sources and regenerate ([#17431](https://github.com/googleapis/google-cloud-python/issues/17431)) ([2e75c78](https://github.com/googleapis/google-cloud-python/commit/2e75c78cdd09d4472ed412a2e925196effaea9fd)) * update googleapis and regenerate ([33ba3af](https://github.com/googleapis/google-cloud-python/commit/33ba3afe520e2f64ac7464f1b4ee31c0624a65ac)) ### Bug Fixes * **bigtable:** ensure deadline is respected for read_rows_sharded ([#17352](https://github.com/googleapis/google-cloud-python/issues/17352)) ([6cc890b](https://github.com/googleapis/google-cloud-python/commit/6cc890b5b9088e19afc7dd3dfbb64c72309feb80)) * require Python 3.10+ ([#17245](https://github.com/googleapis/google-cloud-python/issues/17245)) ([200b0d3](https://github.com/googleapis/google-cloud-python/commit/200b0d324df924c69c358203350fb01a08e41ad9)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- .release-please-individual-manifest.json | 2 +- librarian.yaml | 2 +- packages/google-cloud-bigtable/CHANGELOG.md | 18 ++++++++++++++++++ .../google/cloud/bigtable/gapic_version.py | 2 +- .../cloud/bigtable_admin/gapic_version.py | 2 +- .../cloud/bigtable_admin_v2/gapic_version.py | 2 +- .../google/cloud/bigtable_v2/gapic_version.py | 2 +- ...ppet_metadata_google.bigtable.admin.v2.json | 2 +- 8 files changed, 25 insertions(+), 7 deletions(-) diff --git a/.release-please-individual-manifest.json b/.release-please-individual-manifest.json index 1bdea73da032..5b5b19f6b235 100644 --- a/.release-please-individual-manifest.json +++ b/.release-please-individual-manifest.json @@ -1,6 +1,6 @@ { "packages/bigframes": "2.43.0", - "packages/google-cloud-bigtable": "2.38.0", + "packages/google-cloud-bigtable": "2.39.0", "packages/google-cloud-firestore": "2.27.0", "packages/google-crc32c": "1.8.0", "packages/pandas-gbq": "0.35.0", diff --git a/librarian.yaml b/librarian.yaml index 34509c96c53d..60abb1403b4a 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -632,7 +632,7 @@ libraries: metadata_name_override: bigquerystorage default_version: v1 - name: google-cloud-bigtable - version: 2.38.0 + version: 2.39.0 apis: - path: google/bigtable/v2 - path: google/bigtable/admin/v2 diff --git a/packages/google-cloud-bigtable/CHANGELOG.md b/packages/google-cloud-bigtable/CHANGELOG.md index ab6d09424d80..08dea6a665cd 100644 --- a/packages/google-cloud-bigtable/CHANGELOG.md +++ b/packages/google-cloud-bigtable/CHANGELOG.md @@ -4,6 +4,24 @@ [1]: https://pypi.org/project/google-cloud-bigtable/#history +## [2.39.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-bigtable-v2.38.0...google-cloud-bigtable-v2.39.0) (2026-06-22) + + +### Features + +* added client side metric instrumentation to read_rows and mutate_rows ([#16758](https://github.com/googleapis/google-cloud-python/issues/16758)) ([4005e66](https://github.com/googleapis/google-cloud-python/commit/4005e660a38fd770f8754af1cd07d6d8aa9ed60e)) +* **bigtable:** add client side metric instrumentation to basic rpcs ([#16712](https://github.com/googleapis/google-cloud-python/issues/16712)) ([636af26](https://github.com/googleapis/google-cloud-python/commit/636af26677af5be906220ad39d670e74daca58e0)) +* **bigtable:** add view_parameters support to execute_query ([#17382](https://github.com/googleapis/google-cloud-python/issues/17382)) ([2695aad](https://github.com/googleapis/google-cloud-python/commit/2695aad5c2949e20e77ae9dd432c6fc8ef787952)) +* support row_range in sample_row_keys method ([#17330](https://github.com/googleapis/google-cloud-python/issues/17330)) ([384724c](https://github.com/googleapis/google-cloud-python/commit/384724c2d4c955e15274e9824bcdb93c685b79f6)), closes [#17329](https://github.com/googleapis/google-cloud-python/issues/17329) +* update API sources and regenerate ([#17431](https://github.com/googleapis/google-cloud-python/issues/17431)) ([2e75c78](https://github.com/googleapis/google-cloud-python/commit/2e75c78cdd09d4472ed412a2e925196effaea9fd)) +* update googleapis and regenerate ([33ba3af](https://github.com/googleapis/google-cloud-python/commit/33ba3afe520e2f64ac7464f1b4ee31c0624a65ac)) + + +### Bug Fixes + +* **bigtable:** ensure deadline is respected for read_rows_sharded ([#17352](https://github.com/googleapis/google-cloud-python/issues/17352)) ([6cc890b](https://github.com/googleapis/google-cloud-python/commit/6cc890b5b9088e19afc7dd3dfbb64c72309feb80)) +* require Python 3.10+ ([#17245](https://github.com/googleapis/google-cloud-python/issues/17245)) ([200b0d3](https://github.com/googleapis/google-cloud-python/commit/200b0d324df924c69c358203350fb01a08e41ad9)) + ## [2.38.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-bigtable-v2.37.0...google-cloud-bigtable-v2.38.0) (2026-05-07) diff --git a/packages/google-cloud-bigtable/google/cloud/bigtable/gapic_version.py b/packages/google-cloud-bigtable/google/cloud/bigtable/gapic_version.py index c1c4fe87cbdf..5672701b443d 100644 --- a/packages/google-cloud-bigtable/google/cloud/bigtable/gapic_version.py +++ b/packages/google-cloud-bigtable/google/cloud/bigtable/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.38.0" # {x-release-please-version} +__version__ = "2.39.0" # {x-release-please-version} diff --git a/packages/google-cloud-bigtable/google/cloud/bigtable_admin/gapic_version.py b/packages/google-cloud-bigtable/google/cloud/bigtable_admin/gapic_version.py index c1c4fe87cbdf..5672701b443d 100644 --- a/packages/google-cloud-bigtable/google/cloud/bigtable_admin/gapic_version.py +++ b/packages/google-cloud-bigtable/google/cloud/bigtable_admin/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.38.0" # {x-release-please-version} +__version__ = "2.39.0" # {x-release-please-version} diff --git a/packages/google-cloud-bigtable/google/cloud/bigtable_admin_v2/gapic_version.py b/packages/google-cloud-bigtable/google/cloud/bigtable_admin_v2/gapic_version.py index c1c4fe87cbdf..5672701b443d 100644 --- a/packages/google-cloud-bigtable/google/cloud/bigtable_admin_v2/gapic_version.py +++ b/packages/google-cloud-bigtable/google/cloud/bigtable_admin_v2/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.38.0" # {x-release-please-version} +__version__ = "2.39.0" # {x-release-please-version} diff --git a/packages/google-cloud-bigtable/google/cloud/bigtable_v2/gapic_version.py b/packages/google-cloud-bigtable/google/cloud/bigtable_v2/gapic_version.py index c1c4fe87cbdf..5672701b443d 100644 --- a/packages/google-cloud-bigtable/google/cloud/bigtable_v2/gapic_version.py +++ b/packages/google-cloud-bigtable/google/cloud/bigtable_v2/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.38.0" # {x-release-please-version} +__version__ = "2.39.0" # {x-release-please-version} diff --git a/packages/google-cloud-bigtable/samples/generated_samples/snippet_metadata_google.bigtable.admin.v2.json b/packages/google-cloud-bigtable/samples/generated_samples/snippet_metadata_google.bigtable.admin.v2.json index d87ee31e38c1..4fd5aa07b680 100644 --- a/packages/google-cloud-bigtable/samples/generated_samples/snippet_metadata_google.bigtable.admin.v2.json +++ b/packages/google-cloud-bigtable/samples/generated_samples/snippet_metadata_google.bigtable.admin.v2.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-bigtable", - "version": "2.38.0" + "version": "2.39.0" }, "snippets": [ { From 9c596b7a0a52daa7671a09665ae04e7ca22b6be5 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Mon, 22 Jun 2026 14:45:05 -0700 Subject: [PATCH 110/174] chore(bigquery-storage): fix post processing script (#17535) fix post processing script --- .../client-post-processing/bigquery-storage-integration.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.librarian/generator-input/client-post-processing/bigquery-storage-integration.yaml b/.librarian/generator-input/client-post-processing/bigquery-storage-integration.yaml index 6449c88e1791..aeb6240d30f5 100644 --- a/.librarian/generator-input/client-post-processing/bigquery-storage-integration.yaml +++ b/.librarian/generator-input/client-post-processing/bigquery-storage-integration.yaml @@ -33,7 +33,7 @@ replacements: ] before: | \ # Install all dependencies\n session.install\("-e", "\."\) - after: | + after: |2 # Install all dependencies session.install("-e", f".[{','.join(UNIT_TEST_EXTRAS)}]") count: 2 From a5ad18cbad0577b79917dfad2242a57dc21432e1 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Mon, 22 Jun 2026 22:01:09 +0000 Subject: [PATCH 111/174] chore: release main (#17482) :robot: I have created a release *beep* *boop* ---
    google-cloud-bigquery: 3.42.1 ## [3.42.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-bigquery-v3.42.0...google-cloud-bigquery-v3.42.1) (2026-06-22) ### Bug Fixes * **bigquery:** close GAPIC storage transport and auth sessions to prevent socket leaks ([#17508](https://github.com/googleapis/google-cloud-python/issues/17508)) ([0258405](https://github.com/googleapis/google-cloud-python/commit/025840544f5d4ab6a429d1cd9bdbb256c981aa0d))
    google-cloud-dlp: 3.38.0 ## [3.38.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-dlp-v3.37.0...google-cloud-dlp-v3.38.0) (2026-06-22) ### Features * update googleapis and regenerate ([33ba3af](https://github.com/googleapis/google-cloud-python/commit/33ba3afe520e2f64ac7464f1b4ee31c0624a65ac))
    google-cloud-edgecontainer: 0.8.1 ## [0.8.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-edgecontainer-v0.8.0...google-cloud-edgecontainer-v0.8.1) (2026-06-22) ### Features * regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d))
    google-cloud-edgenetwork: 0.5.1 ## [0.5.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-edgenetwork-v0.5.0...google-cloud-edgenetwork-v0.5.1) (2026-06-22) ### Features * regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d))
    google-cloud-enterpriseknowledgegraph: 0.6.1 ## [0.6.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-enterpriseknowledgegraph-v0.6.0...google-cloud-enterpriseknowledgegraph-v0.6.1) (2026-06-22) ### Features * regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d))
    google-cloud-error-reporting: 1.16.0 ## [1.16.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-error-reporting-v1.15.0...google-cloud-error-reporting-v1.16.0) (2026-06-22) ### Features * regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d))
    google-cloud-essential-contacts: 1.14.0 ## [1.14.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-essential-contacts-v1.13.0...google-cloud-essential-contacts-v1.14.0) (2026-06-22) ### Features * regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d))
    google-cloud-eventarc: 1.21.0 ## [1.21.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-eventarc-v1.20.0...google-cloud-eventarc-v1.21.0) (2026-06-22) ### Features * regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d))
    google-cloud-eventarc-publishing: 0.10.1 ## [0.10.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-eventarc-publishing-v0.10.0...google-cloud-eventarc-publishing-v0.10.1) (2026-06-22) ### Features * regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d))
    google-cloud-filestore: 1.17.0 ## [1.17.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-filestore-v1.16.0...google-cloud-filestore-v1.17.0) (2026-06-22) ### Features * regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d))
    google-cloud-financialservices: 0.4.1 ## [0.4.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-financialservices-v0.4.0...google-cloud-financialservices-v0.4.1) (2026-06-22) ### Features * regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d))
    google-cloud-functions: 1.24.0 ## [1.24.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-functions-v1.23.0...google-cloud-functions-v1.24.0) (2026-06-22) ### Features * regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d))
    google-cloud-gdchardwaremanagement: 0.5.1 ## [0.5.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-gdchardwaremanagement-v0.5.0...google-cloud-gdchardwaremanagement-v0.5.1) (2026-06-22) ### Features * regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d))
    google-cloud-geminidataanalytics: 0.13.1 ## [0.13.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-geminidataanalytics-v0.13.0...google-cloud-geminidataanalytics-v0.13.1) (2026-06-22) ### Features * update googleapis and regenerate ([33ba3af](https://github.com/googleapis/google-cloud-python/commit/33ba3afe520e2f64ac7464f1b4ee31c0624a65ac))
    google-cloud-gke-backup: 0.8.1 ## [0.8.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-gke-backup-v0.8.0...google-cloud-gke-backup-v0.8.1) (2026-06-22) ### Features * regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d))
    google-cloud-gke-connect-gateway: 0.13.1 ## [0.13.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-gke-connect-gateway-v0.13.0...google-cloud-gke-connect-gateway-v0.13.1) (2026-06-22) ### Features * regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d))
    google-cloud-gke-hub: 1.25.0 ## [1.25.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-gke-hub-v1.24.0...google-cloud-gke-hub-v1.25.0) (2026-06-22) ### Features * regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d))
    google-cloud-gke-multicloud: 0.9.1 ## [0.9.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-gke-multicloud-v0.9.0...google-cloud-gke-multicloud-v0.9.1) (2026-06-22) ### Features * regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d))
    google-cloud-gkerecommender: 0.3.1 ## [0.3.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-gkerecommender-v0.3.0...google-cloud-gkerecommender-v0.3.1) (2026-06-22) ### Features * regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d))
    google-cloud-gsuiteaddons: 0.5.1 ## [0.5.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-gsuiteaddons-v0.5.0...google-cloud-gsuiteaddons-v0.5.1) (2026-06-22) ### Features * regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d))
    google-cloud-hypercomputecluster: 0.4.1 ## [0.4.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-hypercomputecluster-v0.4.0...google-cloud-hypercomputecluster-v0.4.1) (2026-06-22) ### Features * regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d))
    google-cloud-iam: 2.24.0 ## [2.24.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-iam-v2.23.0...google-cloud-iam-v2.24.0) (2026-06-22) ### Features * regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d))
    google-cloud-iam-logging: 1.8.0 ## [1.8.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-iam-logging-v1.7.0...google-cloud-iam-logging-v1.8.0) (2026-06-22) ### Features * regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d))
    google-cloud-iamconnectorcredentials: 0.1.1 ## [0.1.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-iamconnectorcredentials-v0.1.0...google-cloud-iamconnectorcredentials-v0.1.1) (2026-06-22) ### Features * regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d))
    google-cloud-iap: 1.22.0 ## [1.22.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-iap-v1.21.0...google-cloud-iap-v1.22.0) (2026-06-22) ### Features * regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d))
    google-cloud-ids: 1.14.0 ## [1.14.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-ids-v1.13.0...google-cloud-ids-v1.14.0) (2026-06-22) ### Features * regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d))
    google-cloud-kms: 3.14.0 ## [3.14.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-kms-v3.13.0...google-cloud-kms-v3.14.0) (2026-06-22) ### Features * regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85))
    google-cloud-kms-inventory: 0.6.1 ## [0.6.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-kms-inventory-v0.6.0...google-cloud-kms-inventory-v0.6.1) (2026-06-22) ### Features * regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85))
    google-cloud-language: 2.21.0 ## [2.21.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-language-v2.20.0...google-cloud-language-v2.21.0) (2026-06-22) ### Features * regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85))
    google-cloud-licensemanager: 0.4.1 ## [0.4.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-licensemanager-v0.4.0...google-cloud-licensemanager-v0.4.1) (2026-06-22) ### Features * regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85))
    google-cloud-life-sciences: 0.12.1 ## [0.12.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-life-sciences-v0.12.0...google-cloud-life-sciences-v0.12.1) (2026-06-22) ### Features * regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85))
    google-cloud-locationfinder: 0.4.1 ## [0.4.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-locationfinder-v0.4.0...google-cloud-locationfinder-v0.4.1) (2026-06-22) ### Features * regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85))
    google-cloud-lustre: 0.4.1 ## [0.4.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-lustre-v0.4.0...google-cloud-lustre-v0.4.1) (2026-06-22) ### Features * regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85))
    google-cloud-maintenance-api: 0.4.1 ## [0.4.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-maintenance-api-v0.4.0...google-cloud-maintenance-api-v0.4.1) (2026-06-22) ### Features * regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85))
    google-cloud-managed-identities: 1.16.0 ## [1.16.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-managed-identities-v1.15.0...google-cloud-managed-identities-v1.16.0) (2026-06-22) ### Features * regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85))
    google-cloud-managedkafka: 0.4.1 ## [0.4.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-managedkafka-v0.4.0...google-cloud-managedkafka-v0.4.1) (2026-06-22) ### Features * regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85))
    google-cloud-managedkafka-schemaregistry: 0.4.1 ## [0.4.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-managedkafka-schemaregistry-v0.4.0...google-cloud-managedkafka-schemaregistry-v0.4.1) (2026-06-22) ### Features * regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85))
    google-cloud-media-translation: 0.14.1 ## [0.14.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-media-translation-v0.14.0...google-cloud-media-translation-v0.14.1) (2026-06-22) ### Features * regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85))
    google-cloud-memcache: 1.16.0 ## [1.16.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-memcache-v1.15.0...google-cloud-memcache-v1.16.0) (2026-06-22) ### Features * regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85))
    google-cloud-memorystore: 0.5.1 ## [0.5.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-memorystore-v0.5.0...google-cloud-memorystore-v0.5.1) (2026-06-22) ### Features * regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85))
    google-cloud-migrationcenter: 0.4.1 ## [0.4.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-migrationcenter-v0.4.0...google-cloud-migrationcenter-v0.4.1) (2026-06-22) ### Features * regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85))
    google-cloud-monitoring-dashboards: 2.22.0 ## [2.22.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-monitoring-dashboards-v2.21.0...google-cloud-monitoring-dashboards-v2.22.0) (2026-06-22) ### Features * regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85))
    google-cloud-monitoring-metrics-scopes: 1.13.0 ## [1.13.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-monitoring-metrics-scopes-v1.12.0...google-cloud-monitoring-metrics-scopes-v1.13.0) (2026-06-22) ### Features * regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85))
    google-cloud-netapp: 0.10.1 ## [0.10.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-netapp-v0.10.0...google-cloud-netapp-v0.10.1) (2026-06-22) ### Features * regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85))
    google-cloud-network-connectivity: 2.16.0 ## [2.16.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-network-connectivity-v2.15.0...google-cloud-network-connectivity-v2.16.0) (2026-06-22) ### Features * regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85))
    google-cloud-network-management: 1.36.0 ## [1.36.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-network-management-v1.35.0...google-cloud-network-management-v1.36.0) (2026-06-22) ### Features * regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85))
    google-cloud-network-security: 0.13.1 ## [0.13.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-network-security-v0.13.0...google-cloud-network-security-v0.13.1) (2026-06-22) ### Features * regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85))
    google-cloud-notebooks: 1.17.0 ## [1.17.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-notebooks-v1.16.0...google-cloud-notebooks-v1.17.0) (2026-06-22) ### Features * regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85))
    google-cloud-optimization: 1.15.0 ## [1.15.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-optimization-v1.14.0...google-cloud-optimization-v1.15.0) (2026-06-22) ### Features * regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051))
    google-cloud-orchestration-airflow: 1.22.0 ## [1.22.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-orchestration-airflow-v1.21.0...google-cloud-orchestration-airflow-v1.22.0) (2026-06-22) ### Features * regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051))
    google-cloud-org-policy: 1.18.0 ## [1.18.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-org-policy-v1.17.0...google-cloud-org-policy-v1.18.0) (2026-06-22) ### Features * regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051))
    google-cloud-os-config: 1.25.0 ## [1.25.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-os-config-v1.24.0...google-cloud-os-config-v1.25.0) (2026-06-22) ### Features * regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051))
    google-cloud-os-login: 2.22.0 ## [2.22.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-os-login-v2.21.0...google-cloud-os-login-v2.22.0) (2026-06-22) ### Features * regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051))
    google-cloud-parallelstore: 0.6.1 ## [0.6.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-parallelstore-v0.6.0...google-cloud-parallelstore-v0.6.1) (2026-06-22) ### Features * regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051))
    google-cloud-parametermanager: 0.4.1 ## [0.4.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-parametermanager-v0.4.0...google-cloud-parametermanager-v0.4.1) (2026-06-22) ### Features * regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051))
    google-cloud-phishing-protection: 1.18.0 ## [1.18.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-phishing-protection-v1.17.0...google-cloud-phishing-protection-v1.18.0) (2026-06-22) ### Features * regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051))
    google-cloud-policy-troubleshooter: 1.17.0 ## [1.17.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-policy-troubleshooter-v1.16.0...google-cloud-policy-troubleshooter-v1.17.0) (2026-06-22) ### Features * regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051))
    google-cloud-policysimulator: 0.4.1 ## [0.4.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-policysimulator-v0.4.0...google-cloud-policysimulator-v0.4.1) (2026-06-22) ### Features * regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051))
    google-cloud-policytroubleshooter-iam: 0.5.1 ## [0.5.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-policytroubleshooter-iam-v0.5.0...google-cloud-policytroubleshooter-iam-v0.5.1) (2026-06-22) ### Features * regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051))
    google-cloud-private-ca: 1.19.0 ## [1.19.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-private-ca-v1.18.0...google-cloud-private-ca-v1.19.0) (2026-06-22) ### Features * regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051))
    google-cloud-private-catalog: 0.12.1 ## [0.12.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-private-catalog-v0.12.0...google-cloud-private-catalog-v0.12.1) (2026-06-22) ### Features * regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051))
    google-cloud-privilegedaccessmanager: 0.4.1 ## [0.4.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-privilegedaccessmanager-v0.4.0...google-cloud-privilegedaccessmanager-v0.4.1) (2026-06-22) ### Features * regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051))
    google-cloud-quotas: 0.6.1 ## [0.6.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-quotas-v0.6.0...google-cloud-quotas-v0.6.1) (2026-06-22) ### Features * regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051))
    google-cloud-rapidmigrationassessment: 0.4.1 ## [0.4.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-rapidmigrationassessment-v0.4.0...google-cloud-rapidmigrationassessment-v0.4.1) (2026-06-22) ### Features * regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051))
    google-cloud-recaptcha-enterprise: 1.32.0 ## [1.32.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-recaptcha-enterprise-v1.31.0...google-cloud-recaptcha-enterprise-v1.32.0) (2026-06-22) ### Features * regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051))
    google-cloud-recommendations-ai: 0.13.1 ## [0.13.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-recommendations-ai-v0.13.0...google-cloud-recommendations-ai-v0.13.1) (2026-06-22) ### Features * regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051))
    google-cloud-recommender: 2.22.0 ## [2.22.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-recommender-v2.21.0...google-cloud-recommender-v2.22.0) (2026-06-22) ### Features * regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051))
    google-cloud-redis: 2.22.0 ## [2.22.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-redis-v2.21.0...google-cloud-redis-v2.22.0) (2026-06-22) ### Features * regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051))
    google-cloud-redis-cluster: 0.5.1 ## [0.5.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-redis-cluster-v0.5.0...google-cloud-redis-cluster-v0.5.1) (2026-06-22) ### Features * regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051))
    google-cloud-resource-manager: 1.18.0 ## [1.18.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-resource-manager-v1.17.0...google-cloud-resource-manager-v1.18.0) (2026-06-22) ### Features * regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051))
    google-cloud-retail: 2.11.0 ## [2.11.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-retail-v2.10.0...google-cloud-retail-v2.11.0) (2026-06-22) ### Features * regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051))
    google-cloud-run: 0.16.1 ## [0.16.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-run-v0.16.0...google-cloud-run-v0.16.1) (2026-06-22) ### Features * regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051))
    google-cloud-talent: 2.21.0 ## [2.21.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-talent-v2.20.0...google-cloud-talent-v2.21.0) (2026-06-22) ### Features * regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8))
    google-cloud-tasks: 2.23.0 ## [2.23.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-tasks-v2.22.0...google-cloud-tasks-v2.23.0) (2026-06-22) ### Features * regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8))
    google-cloud-telcoautomation: 0.5.1 ## [0.5.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-telcoautomation-v0.5.0...google-cloud-telcoautomation-v0.5.1) (2026-06-22) ### Features * regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8))
    google-cloud-testutils: 1.9.1 ## [1.9.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-testutils-v1.9.0...google-cloud-testutils-v1.9.1) (2026-06-22) ### Bug Fixes * make test_utils unique_resource_id parallel-safe ([#17440](https://github.com/googleapis/google-cloud-python/issues/17440)) ([ac1f5d5](https://github.com/googleapis/google-cloud-python/commit/ac1f5d55900d4787f2ced6b5350ef530f700794b))
    google-cloud-texttospeech: 2.37.0 ## [2.37.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-texttospeech-v2.36.0...google-cloud-texttospeech-v2.37.0) (2026-06-22) ### Features * regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8))
    google-cloud-tpu: 1.27.0 ## [1.27.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-tpu-v1.26.0...google-cloud-tpu-v1.27.0) (2026-06-22) ### Features * regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8))
    google-cloud-trace: 1.20.0 ## [1.20.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-trace-v1.19.0...google-cloud-trace-v1.20.0) (2026-06-22) ### Features * regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8))
    google-cloud-translate: 3.27.0 ## [3.27.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-translate-v3.26.0...google-cloud-translate-v3.27.0) (2026-06-22) ### Features * regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8))
    google-cloud-video-live-stream: 1.17.0 ## [1.17.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-video-live-stream-v1.16.0...google-cloud-video-live-stream-v1.17.0) (2026-06-22) ### Features * regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8))
    google-cloud-video-stitcher: 0.11.1 ## [0.11.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-video-stitcher-v0.11.0...google-cloud-video-stitcher-v0.11.1) (2026-06-22) ### Features * regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8))
    google-cloud-video-transcoder: 1.21.0 ## [1.21.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-video-transcoder-v1.20.0...google-cloud-video-transcoder-v1.21.0) (2026-06-22) ### Features * regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8))
    google-cloud-videointelligence: 2.20.0 ## [2.20.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-videointelligence-v2.19.0...google-cloud-videointelligence-v2.20.0) (2026-06-22) ### Features * regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8))
    google-cloud-vision: 3.15.0 ## [3.15.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-vision-v3.14.0...google-cloud-vision-v3.15.0) (2026-06-22) ### Features * regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8))
    google-cloud-visionai: 0.5.1 ## [0.5.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-visionai-v0.5.0...google-cloud-visionai-v0.5.1) (2026-06-22) ### Features * regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8))
    google-cloud-vm-migration: 1.17.0 ## [1.17.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-vm-migration-v1.16.0...google-cloud-vm-migration-v1.17.0) (2026-06-22) ### Features * regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8))
    google-cloud-vmwareengine: 1.12.0 ## [1.12.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-vmwareengine-v1.11.0...google-cloud-vmwareengine-v1.12.0) (2026-06-22) ### Features * regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8))
    google-cloud-vpc-access: 1.17.0 ## [1.17.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-vpc-access-v1.16.0...google-cloud-vpc-access-v1.17.0) (2026-06-22) ### Features * regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8))
    google-cloud-webrisk: 1.22.0 ## [1.22.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-webrisk-v1.21.0...google-cloud-webrisk-v1.22.0) (2026-06-22) ### Features * regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8))
    google-cloud-websecurityscanner: 1.21.0 ## [1.21.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-websecurityscanner-v1.20.0...google-cloud-websecurityscanner-v1.21.0) (2026-06-22) ### Features * regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8))
    google-cloud-workflows: 1.23.0 ## [1.23.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-workflows-v1.22.0...google-cloud-workflows-v1.23.0) (2026-06-22) ### Features * regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8))
    google-cloud-workloadmanager: 0.2.1 ## [0.2.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-workloadmanager-v0.2.0...google-cloud-workloadmanager-v0.2.1) (2026-06-22) ### Features * regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8))
    google-cloud-workstations: 0.8.1 ## [0.8.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-workstations-v0.8.0...google-cloud-workstations-v0.8.1) (2026-06-22) ### Features * regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8)) * update googleapis and regenerate ([33ba3af](https://github.com/googleapis/google-cloud-python/commit/33ba3afe520e2f64ac7464f1b4ee31c0624a65ac))
    --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --------- Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- .release-please-bulk-manifest.json | 188 +++++++++--------- librarian.yaml | 188 +++++++++--------- packages/google-cloud-bigquery/CHANGELOG.md | 7 + .../google/cloud/bigquery/version.py | 2 +- packages/google-cloud-dlp/CHANGELOG.md | 7 + .../google/cloud/dlp/gapic_version.py | 2 +- .../google/cloud/dlp_v2/gapic_version.py | 2 +- ...nippet_metadata_google.privacy.dlp.v2.json | 2 +- .../google-cloud-edgecontainer/CHANGELOG.md | 7 + .../cloud/edgecontainer/gapic_version.py | 2 +- .../cloud/edgecontainer_v1/gapic_version.py | 2 +- ...etadata_google.cloud.edgecontainer.v1.json | 2 +- .../google-cloud-edgenetwork/CHANGELOG.md | 7 + .../google/cloud/edgenetwork/gapic_version.py | 2 +- .../cloud/edgenetwork_v1/gapic_version.py | 2 +- ..._metadata_google.cloud.edgenetwork.v1.json | 2 +- .../CHANGELOG.md | 7 + .../enterpriseknowledgegraph/gapic_version.py | 2 +- .../gapic_version.py | 2 +- ...gle.cloud.enterpriseknowledgegraph.v1.json | 2 +- .../google-cloud-error-reporting/CHANGELOG.md | 7 + .../cloud/error_reporting/gapic_version.py | 2 +- .../cloud/errorreporting/gapic_version.py | 2 +- .../errorreporting_v1beta1/gapic_version.py | 2 +- ....devtools.clouderrorreporting.v1beta1.json | 2 +- .../CHANGELOG.md | 7 + .../cloud/essential_contacts/gapic_version.py | 2 +- .../essential_contacts_v1/gapic_version.py | 2 +- ...ata_google.cloud.essentialcontacts.v1.json | 2 +- .../CHANGELOG.md | 7 + .../eventarc_publishing/gapic_version.py | 2 +- .../eventarc_publishing_v1/gapic_version.py | 2 +- ...a_google.cloud.eventarc.publishing.v1.json | 2 +- packages/google-cloud-eventarc/CHANGELOG.md | 7 + .../google/cloud/eventarc/gapic_version.py | 2 +- .../google/cloud/eventarc_v1/gapic_version.py | 2 +- ...pet_metadata_google.cloud.eventarc.v1.json | 2 +- packages/google-cloud-filestore/CHANGELOG.md | 7 + .../google/cloud/filestore/gapic_version.py | 2 +- .../cloud/filestore_v1/gapic_version.py | 2 +- ...et_metadata_google.cloud.filestore.v1.json | 2 +- .../CHANGELOG.md | 7 + .../cloud/financialservices/gapic_version.py | 2 +- .../financialservices_v1/gapic_version.py | 2 +- ...ata_google.cloud.financialservices.v1.json | 2 +- packages/google-cloud-functions/CHANGELOG.md | 7 + .../google/cloud/functions/gapic_version.py | 2 +- .../cloud/functions_v1/gapic_version.py | 2 +- .../cloud/functions_v2/gapic_version.py | 2 +- ...et_metadata_google.cloud.functions.v1.json | 2 +- ...et_metadata_google.cloud.functions.v2.json | 2 +- .../CHANGELOG.md | 7 + .../gdchardwaremanagement/gapic_version.py | 2 +- .../gapic_version.py | 2 +- ...e.cloud.gdchardwaremanagement.v1alpha.json | 2 +- .../CHANGELOG.md | 7 + .../geminidataanalytics/gapic_version.py | 2 +- .../geminidataanalytics_v1/gapic_version.py | 2 +- .../gapic_version.py | 2 +- .../gapic_version.py | 2 +- ...a_google.cloud.geminidataanalytics.v1.json | 2 +- ...gle.cloud.geminidataanalytics.v1alpha.json | 2 +- ...ogle.cloud.geminidataanalytics.v1beta.json | 2 +- packages/google-cloud-gke-backup/CHANGELOG.md | 7 + .../google/cloud/gke_backup/gapic_version.py | 2 +- .../cloud/gke_backup_v1/gapic_version.py | 2 +- ...et_metadata_google.cloud.gkebackup.v1.json | 2 +- .../CHANGELOG.md | 7 + .../cloud/gkeconnect/gateway/gapic_version.py | 2 +- .../gkeconnect/gateway_v1/gapic_version.py | 2 +- .../gateway_v1beta1/gapic_version.py | 2 +- ...ta_google.cloud.gkeconnect.gateway.v1.json | 2 +- ...ogle.cloud.gkeconnect.gateway.v1beta1.json | 2 +- packages/google-cloud-gke-hub/CHANGELOG.md | 7 + .../google/cloud/gkehub/gapic_version.py | 2 +- .../configmanagement_v1/gapic_version.py | 2 +- .../google/cloud/gkehub_v1/gapic_version.py | 2 +- .../multiclusteringress_v1/gapic_version.py | 2 +- .../gapic_version.py | 2 +- .../cloud/gkehub_v1beta1/gapic_version.py | 2 +- ...ippet_metadata_google.cloud.gkehub.v1.json | 2 +- ..._metadata_google.cloud.gkehub.v1beta1.json | 2 +- .../google-cloud-gke-multicloud/CHANGELOG.md | 7 + .../cloud/gke_multicloud/gapic_version.py | 2 +- .../cloud/gke_multicloud_v1/gapic_version.py | 2 +- ...etadata_google.cloud.gkemulticloud.v1.json | 2 +- .../google-cloud-gkerecommender/CHANGELOG.md | 7 + .../cloud/gkerecommender/gapic_version.py | 2 +- .../cloud/gkerecommender_v1/gapic_version.py | 2 +- ...tadata_google.cloud.gkerecommender.v1.json | 2 +- .../google-cloud-gsuiteaddons/CHANGELOG.md | 7 + .../cloud/gsuiteaddons/gapic_version.py | 2 +- .../cloud/gsuiteaddons_v1/gapic_version.py | 2 +- ...metadata_google.cloud.gsuiteaddons.v1.json | 2 +- .../CHANGELOG.md | 7 + .../hypercomputecluster/gapic_version.py | 2 +- .../hypercomputecluster_v1/gapic_version.py | 2 +- .../gapic_version.py | 2 +- ...a_google.cloud.hypercomputecluster.v1.json | 2 +- ...ogle.cloud.hypercomputecluster.v1beta.json | 2 +- .../google-cloud-iam-logging/CHANGELOG.md | 7 + .../google/cloud/iam_logging/gapic_version.py | 2 +- .../cloud/iam_logging_v1/gapic_version.py | 2 +- packages/google-cloud-iam/CHANGELOG.md | 7 + .../google/cloud/iam/gapic_version.py | 2 +- .../google/cloud/iam_admin/gapic_version.py | 2 +- .../cloud/iam_admin_v1/gapic_version.py | 2 +- .../cloud/iam_credentials/gapic_version.py | 2 +- .../cloud/iam_credentials_v1/gapic_version.py | 2 +- .../google/cloud/iam_v2/gapic_version.py | 2 +- .../google/cloud/iam_v2beta/gapic_version.py | 2 +- .../google/cloud/iam_v3/gapic_version.py | 2 +- .../google/cloud/iam_v3beta/gapic_version.py | 2 +- .../snippet_metadata_google.iam.admin.v1.json | 2 +- ...et_metadata_google.iam.credentials.v1.json | 2 +- .../snippet_metadata_google.iam.v2.json | 2 +- .../snippet_metadata_google.iam.v2beta.json | 2 +- .../snippet_metadata_google.iam.v3.json | 2 +- .../snippet_metadata_google.iam.v3beta.json | 2 +- .../CHANGELOG.md | 7 + .../iamconnectorcredentials/gapic_version.py | 2 +- .../gapic_version.py | 2 +- ...cloud.iamconnectorcredentials.v1alpha.json | 2 +- packages/google-cloud-iap/CHANGELOG.md | 7 + .../google/cloud/iap/gapic_version.py | 2 +- .../google/cloud/iap_v1/gapic_version.py | 2 +- .../snippet_metadata_google.cloud.iap.v1.json | 2 +- packages/google-cloud-ids/CHANGELOG.md | 7 + .../google/cloud/ids/gapic_version.py | 2 +- .../google/cloud/ids_v1/gapic_version.py | 2 +- .../snippet_metadata_google.cloud.ids.v1.json | 2 +- .../google-cloud-kms-inventory/CHANGELOG.md | 7 + .../cloud/kms_inventory/gapic_version.py | 2 +- .../cloud/kms_inventory_v1/gapic_version.py | 2 +- ...etadata_google.cloud.kms.inventory.v1.json | 2 +- packages/google-cloud-kms/CHANGELOG.md | 7 + .../google/cloud/kms/gapic_version.py | 2 +- .../google/cloud/kms_v1/gapic_version.py | 2 +- .../snippet_metadata_google.cloud.kms.v1.json | 2 +- packages/google-cloud-language/CHANGELOG.md | 7 + .../google/cloud/language/gapic_version.py | 2 +- .../google/cloud/language_v1/gapic_version.py | 2 +- .../cloud/language_v1beta2/gapic_version.py | 2 +- .../google/cloud/language_v2/gapic_version.py | 2 +- ...pet_metadata_google.cloud.language.v1.json | 2 +- ...etadata_google.cloud.language.v1beta2.json | 2 +- ...pet_metadata_google.cloud.language.v2.json | 2 +- .../google-cloud-licensemanager/CHANGELOG.md | 7 + .../cloud/licensemanager/gapic_version.py | 2 +- .../cloud/licensemanager_v1/gapic_version.py | 2 +- ...tadata_google.cloud.licensemanager.v1.json | 2 +- .../google-cloud-life-sciences/CHANGELOG.md | 7 + .../cloud/lifesciences/gapic_version.py | 2 +- .../lifesciences_v2beta/gapic_version.py | 2 +- ...data_google.cloud.lifesciences.v2beta.json | 2 +- .../google-cloud-locationfinder/CHANGELOG.md | 7 + .../cloud/locationfinder/gapic_version.py | 2 +- .../cloud/locationfinder_v1/gapic_version.py | 2 +- ...tadata_google.cloud.locationfinder.v1.json | 2 +- packages/google-cloud-lustre/CHANGELOG.md | 7 + .../google/cloud/lustre/gapic_version.py | 2 +- .../google/cloud/lustre_v1/gapic_version.py | 2 +- ...ippet_metadata_google.cloud.lustre.v1.json | 2 +- .../google-cloud-maintenance-api/CHANGELOG.md | 7 + .../cloud/maintenance_api/gapic_version.py | 2 +- .../cloud/maintenance_api_v1/gapic_version.py | 2 +- .../maintenance_api_v1beta/gapic_version.py | 2 +- ...adata_google.cloud.maintenance.api.v1.json | 2 +- ...a_google.cloud.maintenance.api.v1beta.json | 2 +- .../CHANGELOG.md | 7 + .../cloud/managedidentities/gapic_version.py | 2 +- .../managedidentities_v1/gapic_version.py | 2 +- ...ata_google.cloud.managedidentities.v1.json | 2 +- .../CHANGELOG.md | 7 + .../gapic_version.py | 2 +- .../gapic_version.py | 2 +- ....cloud.managedkafka.schemaregistry.v1.json | 2 +- .../google-cloud-managedkafka/CHANGELOG.md | 7 + .../cloud/managedkafka/gapic_version.py | 2 +- .../cloud/managedkafka_v1/gapic_version.py | 2 +- ...metadata_google.cloud.managedkafka.v1.json | 2 +- .../CHANGELOG.md | 7 + .../cloud/mediatranslation/gapic_version.py | 2 +- .../mediatranslation_v1beta1/gapic_version.py | 2 +- ...google.cloud.mediatranslation.v1beta1.json | 2 +- packages/google-cloud-memcache/CHANGELOG.md | 7 + .../google/cloud/memcache/gapic_version.py | 2 +- .../google/cloud/memcache_v1/gapic_version.py | 2 +- .../cloud/memcache_v1beta2/gapic_version.py | 2 +- ...pet_metadata_google.cloud.memcache.v1.json | 2 +- ...etadata_google.cloud.memcache.v1beta2.json | 2 +- .../google-cloud-memorystore/CHANGELOG.md | 7 + .../google/cloud/memorystore/gapic_version.py | 2 +- .../cloud/memorystore_v1/gapic_version.py | 2 +- .../cloud/memorystore_v1beta/gapic_version.py | 2 +- ..._metadata_google.cloud.memorystore.v1.json | 2 +- ...adata_google.cloud.memorystore.v1beta.json | 2 +- .../google-cloud-migrationcenter/CHANGELOG.md | 7 + .../cloud/migrationcenter/gapic_version.py | 2 +- .../cloud/migrationcenter_v1/gapic_version.py | 2 +- ...adata_google.cloud.migrationcenter.v1.json | 2 +- .../CHANGELOG.md | 7 + .../monitoring_dashboard/gapic_version.py | 2 +- .../monitoring_dashboard_v1/gapic_version.py | 2 +- .../monitoring/dashboard_v1/gapic_version.py | 2 +- ...tadata_google.monitoring.dashboard.v1.json | 2 +- .../CHANGELOG.md | 7 + .../monitoring_metrics_scope/gapic_version.py | 2 +- .../gapic_version.py | 2 +- ...ata_google.monitoring.metricsscope.v1.json | 2 +- packages/google-cloud-netapp/CHANGELOG.md | 7 + .../google/cloud/netapp/gapic_version.py | 2 +- .../google/cloud/netapp_v1/gapic_version.py | 2 +- ...ippet_metadata_google.cloud.netapp.v1.json | 2 +- .../CHANGELOG.md | 7 + .../networkconnectivity/gapic_version.py | 2 +- .../networkconnectivity_v1/gapic_version.py | 2 +- .../gapic_version.py | 2 +- .../gapic_version.py | 2 +- ...a_google.cloud.networkconnectivity.v1.json | 2 +- ...le.cloud.networkconnectivity.v1alpha1.json | 2 +- ...ogle.cloud.networkconnectivity.v1beta.json | 2 +- .../CHANGELOG.md | 7 + .../cloud/network_management/gapic_version.py | 2 +- .../network_management_v1/gapic_version.py | 2 +- ...ata_google.cloud.networkmanagement.v1.json | 2 +- .../CHANGELOG.md | 7 + .../cloud/network_security/gapic_version.py | 2 +- .../network_security_v1/gapic_version.py | 2 +- .../gapic_version.py | 2 +- .../network_security_v1beta1/gapic_version.py | 2 +- ...adata_google.cloud.networksecurity.v1.json | 2 +- ...google.cloud.networksecurity.v1alpha1.json | 2 +- ..._google.cloud.networksecurity.v1beta1.json | 2 +- packages/google-cloud-notebooks/CHANGELOG.md | 7 + .../google/cloud/notebooks/gapic_version.py | 2 +- .../cloud/notebooks_v1/gapic_version.py | 2 +- .../cloud/notebooks_v1beta1/gapic_version.py | 2 +- .../cloud/notebooks_v2/gapic_version.py | 2 +- ...et_metadata_google.cloud.notebooks.v1.json | 2 +- ...tadata_google.cloud.notebooks.v1beta1.json | 2 +- ...et_metadata_google.cloud.notebooks.v2.json | 2 +- .../google-cloud-optimization/CHANGELOG.md | 7 + .../cloud/optimization/gapic_version.py | 2 +- .../cloud/optimization_v1/gapic_version.py | 2 +- ...metadata_google.cloud.optimization.v1.json | 2 +- .../CHANGELOG.md | 7 + .../airflow/service/gapic_version.py | 2 +- .../airflow/service_v1/gapic_version.py | 2 +- .../airflow/service_v1beta1/gapic_version.py | 2 +- ...loud.orchestration.airflow.service.v1.json | 2 +- ...orchestration.airflow.service.v1beta1.json | 2 +- packages/google-cloud-org-policy/CHANGELOG.md | 7 + .../google/cloud/orgpolicy/gapic_version.py | 2 +- .../cloud/orgpolicy_v2/gapic_version.py | 2 +- ...et_metadata_google.cloud.orgpolicy.v2.json | 2 +- packages/google-cloud-os-config/CHANGELOG.md | 7 + .../google/cloud/osconfig/gapic_version.py | 2 +- .../google/cloud/osconfig_v1/gapic_version.py | 2 +- .../cloud/osconfig_v1alpha/gapic_version.py | 2 +- ...pet_metadata_google.cloud.osconfig.v1.json | 2 +- ...etadata_google.cloud.osconfig.v1alpha.json | 2 +- packages/google-cloud-os-login/CHANGELOG.md | 7 + .../google/cloud/oslogin/gapic_version.py | 2 +- .../google/cloud/oslogin_v1/gapic_version.py | 2 +- ...ppet_metadata_google.cloud.oslogin.v1.json | 2 +- .../google-cloud-parallelstore/CHANGELOG.md | 7 + .../cloud/parallelstore/gapic_version.py | 2 +- .../cloud/parallelstore_v1/gapic_version.py | 2 +- .../parallelstore_v1beta/gapic_version.py | 2 +- ...etadata_google.cloud.parallelstore.v1.json | 2 +- ...ata_google.cloud.parallelstore.v1beta.json | 2 +- .../CHANGELOG.md | 7 + .../cloud/parametermanager/gapic_version.py | 2 +- .../parametermanager_v1/gapic_version.py | 2 +- ...data_google.cloud.parametermanager.v1.json | 2 +- .../CHANGELOG.md | 7 + .../cloud/phishingprotection/gapic_version.py | 2 +- .../gapic_version.py | 2 +- ...ogle.cloud.phishingprotection.v1beta1.json | 2 +- .../CHANGELOG.md | 7 + .../policytroubleshooter/gapic_version.py | 2 +- .../policytroubleshooter_v1/gapic_version.py | 2 +- ..._google.cloud.policytroubleshooter.v1.json | 2 +- .../google-cloud-policysimulator/CHANGELOG.md | 7 + .../cloud/policysimulator/gapic_version.py | 2 +- .../cloud/policysimulator_v1/gapic_version.py | 2 +- ...adata_google.cloud.policysimulator.v1.json | 2 +- .../CHANGELOG.md | 7 + .../policytroubleshooter_iam/gapic_version.py | 2 +- .../gapic_version.py | 2 +- ...gle.cloud.policytroubleshooter.iam.v3.json | 2 +- packages/google-cloud-private-ca/CHANGELOG.md | 7 + .../cloud/security/privateca/gapic_version.py | 2 +- .../security/privateca_v1/gapic_version.py | 2 +- .../privateca_v1beta1/gapic_version.py | 2 +- ...ta_google.cloud.security.privateca.v1.json | 2 +- ...ogle.cloud.security.privateca.v1beta1.json | 2 +- .../google-cloud-private-catalog/CHANGELOG.md | 7 + .../cloud/privatecatalog/gapic_version.py | 2 +- .../privatecatalog_v1beta1/gapic_version.py | 2 +- ...a_google.cloud.privatecatalog.v1beta1.json | 2 +- .../CHANGELOG.md | 7 + .../privilegedaccessmanager/gapic_version.py | 2 +- .../gapic_version.py | 2 +- ...ogle.cloud.privilegedaccessmanager.v1.json | 2 +- packages/google-cloud-quotas/CHANGELOG.md | 7 + .../google/cloud/cloudquotas/gapic_version.py | 2 +- .../cloud/cloudquotas_v1/gapic_version.py | 2 +- .../cloud/cloudquotas_v1beta/gapic_version.py | 2 +- ...et_metadata_google.api.cloudquotas.v1.json | 2 +- ...etadata_google.api.cloudquotas.v1beta.json | 2 +- .../CHANGELOG.md | 7 + .../rapidmigrationassessment/gapic_version.py | 2 +- .../gapic_version.py | 2 +- ...gle.cloud.rapidmigrationassessment.v1.json | 2 +- .../CHANGELOG.md | 7 + .../recaptchaenterprise/gapic_version.py | 2 +- .../recaptchaenterprise_v1/gapic_version.py | 2 +- ...a_google.cloud.recaptchaenterprise.v1.json | 2 +- .../CHANGELOG.md | 7 + .../recommendationengine/gapic_version.py | 2 +- .../gapic_version.py | 2 +- ...le.cloud.recommendationengine.v1beta1.json | 2 +- .../google-cloud-recommender/CHANGELOG.md | 7 + .../google/cloud/recommender/gapic_version.py | 2 +- .../cloud/recommender_v1/gapic_version.py | 2 +- .../recommender_v1beta1/gapic_version.py | 2 +- ..._metadata_google.cloud.recommender.v1.json | 2 +- ...data_google.cloud.recommender.v1beta1.json | 2 +- .../google-cloud-redis-cluster/CHANGELOG.md | 7 + .../cloud/redis_cluster/gapic_version.py | 2 +- .../cloud/redis_cluster_v1/gapic_version.py | 2 +- .../redis_cluster_v1beta1/gapic_version.py | 2 +- ...etadata_google.cloud.redis.cluster.v1.json | 2 +- ...ta_google.cloud.redis.cluster.v1beta1.json | 2 +- packages/google-cloud-redis/CHANGELOG.md | 7 + .../google/cloud/redis/gapic_version.py | 2 +- .../google/cloud/redis_v1/gapic_version.py | 2 +- .../cloud/redis_v1beta1/gapic_version.py | 2 +- ...nippet_metadata_google.cloud.redis.v1.json | 2 +- ...t_metadata_google.cloud.redis.v1beta1.json | 2 +- .../CHANGELOG.md | 7 + .../cloud/resourcemanager/gapic_version.py | 2 +- .../cloud/resourcemanager_v3/gapic_version.py | 2 +- ...adata_google.cloud.resourcemanager.v3.json | 2 +- packages/google-cloud-retail/CHANGELOG.md | 7 + .../google/cloud/retail/gapic_version.py | 2 +- .../google/cloud/retail_v2/gapic_version.py | 2 +- .../cloud/retail_v2alpha/gapic_version.py | 2 +- .../cloud/retail_v2beta/gapic_version.py | 2 +- ...ippet_metadata_google.cloud.retail.v2.json | 2 +- ..._metadata_google.cloud.retail.v2alpha.json | 2 +- ...t_metadata_google.cloud.retail.v2beta.json | 2 +- packages/google-cloud-run/CHANGELOG.md | 7 + .../google/cloud/run/gapic_version.py | 2 +- .../google/cloud/run_v2/gapic_version.py | 2 +- .../snippet_metadata_google.cloud.run.v2.json | 2 +- packages/google-cloud-talent/CHANGELOG.md | 7 + .../google/cloud/talent/gapic_version.py | 2 +- .../google/cloud/talent_v4/gapic_version.py | 2 +- .../cloud/talent_v4beta1/gapic_version.py | 2 +- ...ippet_metadata_google.cloud.talent.v4.json | 2 +- ..._metadata_google.cloud.talent.v4beta1.json | 2 +- packages/google-cloud-tasks/CHANGELOG.md | 7 + .../google/cloud/tasks/gapic_version.py | 2 +- .../google/cloud/tasks_v2/gapic_version.py | 2 +- .../cloud/tasks_v2beta2/gapic_version.py | 2 +- .../cloud/tasks_v2beta3/gapic_version.py | 2 +- ...nippet_metadata_google.cloud.tasks.v2.json | 2 +- ...t_metadata_google.cloud.tasks.v2beta2.json | 2 +- ...t_metadata_google.cloud.tasks.v2beta3.json | 2 +- .../google-cloud-telcoautomation/CHANGELOG.md | 7 + .../cloud/telcoautomation/gapic_version.py | 2 +- .../cloud/telcoautomation_v1/gapic_version.py | 2 +- .../telcoautomation_v1alpha1/gapic_version.py | 2 +- ...adata_google.cloud.telcoautomation.v1.json | 2 +- ...google.cloud.telcoautomation.v1alpha1.json | 2 +- packages/google-cloud-testutils/CHANGELOG.md | 7 + .../test_utils/version.py | 2 +- .../google-cloud-texttospeech/CHANGELOG.md | 7 + .../cloud/texttospeech/gapic_version.py | 2 +- .../cloud/texttospeech_v1/gapic_version.py | 2 +- .../texttospeech_v1beta1/gapic_version.py | 2 +- ...metadata_google.cloud.texttospeech.v1.json | 2 +- ...ata_google.cloud.texttospeech.v1beta1.json | 2 +- packages/google-cloud-tpu/CHANGELOG.md | 7 + .../google/cloud/tpu/gapic_version.py | 2 +- .../google/cloud/tpu_v1/gapic_version.py | 2 +- .../google/cloud/tpu_v2/gapic_version.py | 2 +- .../cloud/tpu_v2alpha1/gapic_version.py | 2 +- .../snippet_metadata_google.cloud.tpu.v1.json | 2 +- .../snippet_metadata_google.cloud.tpu.v2.json | 2 +- ...et_metadata_google.cloud.tpu.v2alpha1.json | 2 +- packages/google-cloud-trace/CHANGELOG.md | 7 + .../google/cloud/trace/gapic_version.py | 2 +- .../google/cloud/trace_v1/gapic_version.py | 2 +- .../google/cloud/trace_v2/gapic_version.py | 2 +- ...etadata_google.devtools.cloudtrace.v1.json | 2 +- ...etadata_google.devtools.cloudtrace.v2.json | 2 +- packages/google-cloud-translate/CHANGELOG.md | 7 + .../google/cloud/translate/gapic_version.py | 2 +- .../cloud/translate_v3/gapic_version.py | 2 +- .../cloud/translate_v3beta1/gapic_version.py | 2 +- ..._metadata_google.cloud.translation.v3.json | 2 +- ...data_google.cloud.translation.v3beta1.json | 2 +- .../CHANGELOG.md | 7 + .../cloud/video/live_stream/gapic_version.py | 2 +- .../video/live_stream_v1/gapic_version.py | 2 +- ...data_google.cloud.video.livestream.v1.json | 2 +- .../google-cloud-video-stitcher/CHANGELOG.md | 7 + .../cloud/video/stitcher/gapic_version.py | 2 +- .../cloud/video/stitcher_v1/gapic_version.py | 2 +- ...tadata_google.cloud.video.stitcher.v1.json | 2 +- .../CHANGELOG.md | 7 + .../cloud/video/transcoder/gapic_version.py | 2 +- .../video/transcoder_v1/gapic_version.py | 2 +- ...data_google.cloud.video.transcoder.v1.json | 2 +- .../CHANGELOG.md | 7 + .../cloud/videointelligence/gapic_version.py | 2 +- .../videointelligence_v1/gapic_version.py | 2 +- .../gapic_version.py | 2 +- .../gapic_version.py | 2 +- .../gapic_version.py | 2 +- .../gapic_version.py | 2 +- ...ata_google.cloud.videointelligence.v1.json | 2 +- ...oogle.cloud.videointelligence.v1beta2.json | 2 +- ...gle.cloud.videointelligence.v1p1beta1.json | 2 +- ...gle.cloud.videointelligence.v1p2beta1.json | 2 +- ...gle.cloud.videointelligence.v1p3beta1.json | 2 +- packages/google-cloud-vision/CHANGELOG.md | 7 + .../google/cloud/vision/gapic_version.py | 2 +- .../google/cloud/vision_v1/gapic_version.py | 2 +- .../cloud/vision_v1p1beta1/gapic_version.py | 2 +- .../cloud/vision_v1p2beta1/gapic_version.py | 2 +- .../cloud/vision_v1p3beta1/gapic_version.py | 2 +- .../cloud/vision_v1p4beta1/gapic_version.py | 2 +- ...ippet_metadata_google.cloud.vision.v1.json | 2 +- ...etadata_google.cloud.vision.v1p1beta1.json | 2 +- ...etadata_google.cloud.vision.v1p2beta1.json | 2 +- ...etadata_google.cloud.vision.v1p3beta1.json | 2 +- ...etadata_google.cloud.vision.v1p4beta1.json | 2 +- packages/google-cloud-visionai/CHANGELOG.md | 7 + .../google/cloud/visionai/gapic_version.py | 2 +- .../google/cloud/visionai_v1/gapic_version.py | 2 +- .../cloud/visionai_v1alpha1/gapic_version.py | 2 +- ...pet_metadata_google.cloud.visionai.v1.json | 2 +- ...tadata_google.cloud.visionai.v1alpha1.json | 2 +- .../google-cloud-vm-migration/CHANGELOG.md | 7 + .../google/cloud/vmmigration/gapic_version.py | 2 +- .../cloud/vmmigration_v1/gapic_version.py | 2 +- ..._metadata_google.cloud.vmmigration.v1.json | 2 +- .../google-cloud-vmwareengine/CHANGELOG.md | 7 + .../cloud/vmwareengine/gapic_version.py | 2 +- .../cloud/vmwareengine_v1/gapic_version.py | 2 +- ...metadata_google.cloud.vmwareengine.v1.json | 2 +- packages/google-cloud-vpc-access/CHANGELOG.md | 7 + .../google/cloud/vpcaccess/gapic_version.py | 2 +- .../cloud/vpcaccess_v1/gapic_version.py | 2 +- ...et_metadata_google.cloud.vpcaccess.v1.json | 2 +- packages/google-cloud-webrisk/CHANGELOG.md | 7 + .../google/cloud/webrisk/gapic_version.py | 2 +- .../google/cloud/webrisk_v1/gapic_version.py | 2 +- .../cloud/webrisk_v1beta1/gapic_version.py | 2 +- ...ppet_metadata_google.cloud.webrisk.v1.json | 2 +- ...metadata_google.cloud.webrisk.v1beta1.json | 2 +- .../CHANGELOG.md | 7 + .../cloud/websecurityscanner/gapic_version.py | 2 +- .../websecurityscanner_v1/gapic_version.py | 2 +- .../gapic_version.py | 2 +- .../gapic_version.py | 2 +- ...ta_google.cloud.websecurityscanner.v1.json | 2 +- ...ogle.cloud.websecurityscanner.v1alpha.json | 2 +- ...oogle.cloud.websecurityscanner.v1beta.json | 2 +- packages/google-cloud-workflows/CHANGELOG.md | 7 + .../workflows/executions/gapic_version.py | 2 +- .../workflows/executions_v1/gapic_version.py | 2 +- .../executions_v1beta/gapic_version.py | 2 +- .../google/cloud/workflows/gapic_version.py | 2 +- .../cloud/workflows_v1/gapic_version.py | 2 +- .../cloud/workflows_v1beta/gapic_version.py | 2 +- ..._google.cloud.workflows.executions.v1.json | 2 +- ...gle.cloud.workflows.executions.v1beta.json | 2 +- ...et_metadata_google.cloud.workflows.v1.json | 2 +- ...etadata_google.cloud.workflows.v1beta.json | 2 +- .../google-cloud-workloadmanager/CHANGELOG.md | 7 + .../cloud/workloadmanager/gapic_version.py | 2 +- .../cloud/workloadmanager_v1/gapic_version.py | 2 +- ...adata_google.cloud.workloadmanager.v1.json | 2 +- .../google-cloud-workstations/CHANGELOG.md | 8 + .../cloud/workstations/gapic_version.py | 2 +- .../cloud/workstations_v1/gapic_version.py | 2 +- .../workstations_v1beta/gapic_version.py | 2 +- ...metadata_google.cloud.workstations.v1.json | 2 +- ...data_google.cloud.workstations.v1beta.json | 2 +- 495 files changed, 1246 insertions(+), 587 deletions(-) diff --git a/.release-please-bulk-manifest.json b/.release-please-bulk-manifest.json index 3612728ebad7..7f62552607b8 100644 --- a/.release-please-bulk-manifest.json +++ b/.release-please-bulk-manifest.json @@ -53,7 +53,7 @@ "packages/google-cloud-beyondcorp-clientgateways": "0.8.0", "packages/google-cloud-biglake": "0.5.0", "packages/google-cloud-biglake-hive": "0.3.0", - "packages/google-cloud-bigquery": "3.42.0", + "packages/google-cloud-bigquery": "3.42.1", "packages/google-cloud-bigquery-analyticshub": "0.9.0", "packages/google-cloud-bigquery-biglake": "0.8.0", "packages/google-cloud-bigquery-connection": "1.22.0", @@ -107,89 +107,89 @@ "packages/google-cloud-dialogflow": "2.48.0", "packages/google-cloud-dialogflow-cx": "2.6.0", "packages/google-cloud-discoveryengine": "0.20.0", - "packages/google-cloud-dlp": "3.37.0", + "packages/google-cloud-dlp": "3.38.0", "packages/google-cloud-dms": "1.16.0", "packages/google-cloud-dns": "0.37.0", "packages/google-cloud-documentai": "3.15.0", "packages/google-cloud-documentai-toolbox": "0.17.0", "packages/google-cloud-domains": "1.14.0", - "packages/google-cloud-edgecontainer": "0.8.0", - "packages/google-cloud-edgenetwork": "0.5.0", - "packages/google-cloud-enterpriseknowledgegraph": "0.6.0", - "packages/google-cloud-error-reporting": "1.15.0", - "packages/google-cloud-essential-contacts": "1.13.0", - "packages/google-cloud-eventarc": "1.20.0", - "packages/google-cloud-eventarc-publishing": "0.10.0", - "packages/google-cloud-filestore": "1.16.0", - "packages/google-cloud-financialservices": "0.4.0", - "packages/google-cloud-functions": "1.23.0", - "packages/google-cloud-gdchardwaremanagement": "0.5.0", - "packages/google-cloud-geminidataanalytics": "0.13.0", - "packages/google-cloud-gke-backup": "0.8.0", - "packages/google-cloud-gke-connect-gateway": "0.13.0", - "packages/google-cloud-gke-hub": "1.24.0", - "packages/google-cloud-gke-multicloud": "0.9.0", - "packages/google-cloud-gkerecommender": "0.3.0", - "packages/google-cloud-gsuiteaddons": "0.5.0", - "packages/google-cloud-hypercomputecluster": "0.4.0", - "packages/google-cloud-iam": "2.23.0", - "packages/google-cloud-iam-logging": "1.7.0", - "packages/google-cloud-iamconnectorcredentials": "0.1.0", - "packages/google-cloud-iap": "1.21.0", - "packages/google-cloud-ids": "1.13.0", - "packages/google-cloud-kms": "3.13.0", - "packages/google-cloud-kms-inventory": "0.6.0", - "packages/google-cloud-language": "2.20.0", - "packages/google-cloud-licensemanager": "0.4.0", - "packages/google-cloud-life-sciences": "0.12.0", - "packages/google-cloud-locationfinder": "0.4.0", + "packages/google-cloud-edgecontainer": "0.8.1", + "packages/google-cloud-edgenetwork": "0.5.1", + "packages/google-cloud-enterpriseknowledgegraph": "0.6.1", + "packages/google-cloud-error-reporting": "1.16.0", + "packages/google-cloud-essential-contacts": "1.14.0", + "packages/google-cloud-eventarc": "1.21.0", + "packages/google-cloud-eventarc-publishing": "0.10.1", + "packages/google-cloud-filestore": "1.17.0", + "packages/google-cloud-financialservices": "0.4.1", + "packages/google-cloud-functions": "1.24.0", + "packages/google-cloud-gdchardwaremanagement": "0.5.1", + "packages/google-cloud-geminidataanalytics": "0.13.1", + "packages/google-cloud-gke-backup": "0.8.1", + "packages/google-cloud-gke-connect-gateway": "0.13.1", + "packages/google-cloud-gke-hub": "1.25.0", + "packages/google-cloud-gke-multicloud": "0.9.1", + "packages/google-cloud-gkerecommender": "0.3.1", + "packages/google-cloud-gsuiteaddons": "0.5.1", + "packages/google-cloud-hypercomputecluster": "0.4.1", + "packages/google-cloud-iam": "2.24.0", + "packages/google-cloud-iam-logging": "1.8.0", + "packages/google-cloud-iamconnectorcredentials": "0.1.1", + "packages/google-cloud-iap": "1.22.0", + "packages/google-cloud-ids": "1.14.0", + "packages/google-cloud-kms": "3.14.0", + "packages/google-cloud-kms-inventory": "0.6.1", + "packages/google-cloud-language": "2.21.0", + "packages/google-cloud-licensemanager": "0.4.1", + "packages/google-cloud-life-sciences": "0.12.1", + "packages/google-cloud-locationfinder": "0.4.1", "packages/google-cloud-logging": "3.16.0", - "packages/google-cloud-lustre": "0.4.0", - "packages/google-cloud-maintenance-api": "0.4.0", - "packages/google-cloud-managed-identities": "1.15.0", - "packages/google-cloud-managedkafka": "0.4.0", - "packages/google-cloud-managedkafka-schemaregistry": "0.4.0", - "packages/google-cloud-media-translation": "0.14.0", - "packages/google-cloud-memcache": "1.15.0", - "packages/google-cloud-memorystore": "0.5.0", - "packages/google-cloud-migrationcenter": "0.4.0", + "packages/google-cloud-lustre": "0.4.1", + "packages/google-cloud-maintenance-api": "0.4.1", + "packages/google-cloud-managed-identities": "1.16.0", + "packages/google-cloud-managedkafka": "0.4.1", + "packages/google-cloud-managedkafka-schemaregistry": "0.4.1", + "packages/google-cloud-media-translation": "0.14.1", + "packages/google-cloud-memcache": "1.16.0", + "packages/google-cloud-memorystore": "0.5.1", + "packages/google-cloud-migrationcenter": "0.4.1", "packages/google-cloud-modelarmor": "0.7.0", "packages/google-cloud-monitoring": "2.31.0", - "packages/google-cloud-monitoring-dashboards": "2.21.0", - "packages/google-cloud-monitoring-metrics-scopes": "1.12.0", + "packages/google-cloud-monitoring-dashboards": "2.22.0", + "packages/google-cloud-monitoring-metrics-scopes": "1.13.0", "packages/google-cloud-ndb": "2.5.0", - "packages/google-cloud-netapp": "0.10.0", - "packages/google-cloud-network-connectivity": "2.15.0", - "packages/google-cloud-network-management": "1.35.0", - "packages/google-cloud-network-security": "0.13.0", + "packages/google-cloud-netapp": "0.10.1", + "packages/google-cloud-network-connectivity": "2.16.0", + "packages/google-cloud-network-management": "1.36.0", + "packages/google-cloud-network-security": "0.13.1", "packages/google-cloud-network-services": "0.10.0", - "packages/google-cloud-notebooks": "1.16.0", - "packages/google-cloud-optimization": "1.14.0", + "packages/google-cloud-notebooks": "1.17.0", + "packages/google-cloud-optimization": "1.15.0", "packages/google-cloud-oracledatabase": "0.6.0", - "packages/google-cloud-orchestration-airflow": "1.21.0", - "packages/google-cloud-org-policy": "1.17.0", - "packages/google-cloud-os-config": "1.24.0", - "packages/google-cloud-os-login": "2.21.0", - "packages/google-cloud-parallelstore": "0.6.0", - "packages/google-cloud-parametermanager": "0.4.0", - "packages/google-cloud-phishing-protection": "1.17.0", - "packages/google-cloud-policy-troubleshooter": "1.16.0", - "packages/google-cloud-policysimulator": "0.4.0", - "packages/google-cloud-policytroubleshooter-iam": "0.5.0", - "packages/google-cloud-private-ca": "1.18.0", - "packages/google-cloud-private-catalog": "0.12.0", - "packages/google-cloud-privilegedaccessmanager": "0.4.0", + "packages/google-cloud-orchestration-airflow": "1.22.0", + "packages/google-cloud-org-policy": "1.18.0", + "packages/google-cloud-os-config": "1.25.0", + "packages/google-cloud-os-login": "2.22.0", + "packages/google-cloud-parallelstore": "0.6.1", + "packages/google-cloud-parametermanager": "0.4.1", + "packages/google-cloud-phishing-protection": "1.18.0", + "packages/google-cloud-policy-troubleshooter": "1.17.0", + "packages/google-cloud-policysimulator": "0.4.1", + "packages/google-cloud-policytroubleshooter-iam": "0.5.1", + "packages/google-cloud-private-ca": "1.19.0", + "packages/google-cloud-private-catalog": "0.12.1", + "packages/google-cloud-privilegedaccessmanager": "0.4.1", "packages/google-cloud-pubsub": "2.39.0", - "packages/google-cloud-quotas": "0.6.0", - "packages/google-cloud-rapidmigrationassessment": "0.4.0", - "packages/google-cloud-recaptcha-enterprise": "1.31.0", - "packages/google-cloud-recommendations-ai": "0.13.0", - "packages/google-cloud-recommender": "2.21.0", - "packages/google-cloud-redis": "2.21.0", - "packages/google-cloud-redis-cluster": "0.5.0", - "packages/google-cloud-resource-manager": "1.17.0", - "packages/google-cloud-retail": "2.10.0", - "packages/google-cloud-run": "0.16.0", + "packages/google-cloud-quotas": "0.6.1", + "packages/google-cloud-rapidmigrationassessment": "0.4.1", + "packages/google-cloud-recaptcha-enterprise": "1.32.0", + "packages/google-cloud-recommendations-ai": "0.13.1", + "packages/google-cloud-recommender": "2.22.0", + "packages/google-cloud-redis": "2.22.0", + "packages/google-cloud-redis-cluster": "0.5.1", + "packages/google-cloud-resource-manager": "1.18.0", + "packages/google-cloud-retail": "2.11.0", + "packages/google-cloud-run": "0.16.1", "packages/google-cloud-runtimeconfig": "0.37.0", "packages/google-cloud-saasplatform-saasservicemgmt": "0.7.0", "packages/google-cloud-scheduler": "2.20.0", @@ -213,29 +213,29 @@ "packages/google-cloud-storagebatchoperations": "0.8.0", "packages/google-cloud-storageinsights": "0.5.0", "packages/google-cloud-support": "0.5.0", - "packages/google-cloud-talent": "2.20.0", - "packages/google-cloud-tasks": "2.22.0", - "packages/google-cloud-telcoautomation": "0.5.0", - "packages/google-cloud-testutils": "1.9.0", - "packages/google-cloud-texttospeech": "2.36.0", - "packages/google-cloud-tpu": "1.26.0", - "packages/google-cloud-trace": "1.19.0", - "packages/google-cloud-translate": "3.26.0", + "packages/google-cloud-talent": "2.21.0", + "packages/google-cloud-tasks": "2.23.0", + "packages/google-cloud-telcoautomation": "0.5.1", + "packages/google-cloud-testutils": "1.9.1", + "packages/google-cloud-texttospeech": "2.37.0", + "packages/google-cloud-tpu": "1.27.0", + "packages/google-cloud-trace": "1.20.0", + "packages/google-cloud-translate": "3.27.0", "packages/google-cloud-vectorsearch": "0.11.0", - "packages/google-cloud-video-live-stream": "1.16.0", - "packages/google-cloud-video-stitcher": "0.11.0", - "packages/google-cloud-video-transcoder": "1.20.0", - "packages/google-cloud-videointelligence": "2.19.0", - "packages/google-cloud-vision": "3.14.0", - "packages/google-cloud-visionai": "0.5.0", - "packages/google-cloud-vm-migration": "1.16.0", - "packages/google-cloud-vmwareengine": "1.11.0", - "packages/google-cloud-vpc-access": "1.16.0", - "packages/google-cloud-webrisk": "1.21.0", - "packages/google-cloud-websecurityscanner": "1.20.0", - "packages/google-cloud-workflows": "1.22.0", - "packages/google-cloud-workloadmanager": "0.2.0", - "packages/google-cloud-workstations": "0.8.0", + "packages/google-cloud-video-live-stream": "1.17.0", + "packages/google-cloud-video-stitcher": "0.11.1", + "packages/google-cloud-video-transcoder": "1.21.0", + "packages/google-cloud-videointelligence": "2.20.0", + "packages/google-cloud-vision": "3.15.0", + "packages/google-cloud-visionai": "0.5.1", + "packages/google-cloud-vm-migration": "1.17.0", + "packages/google-cloud-vmwareengine": "1.12.0", + "packages/google-cloud-vpc-access": "1.17.0", + "packages/google-cloud-webrisk": "1.22.0", + "packages/google-cloud-websecurityscanner": "1.21.0", + "packages/google-cloud-workflows": "1.23.0", + "packages/google-cloud-workloadmanager": "0.2.1", + "packages/google-cloud-workstations": "0.8.1", "packages/google-developer-knowledge": "0.1.0", "packages/google-devicesandservices-health": "0.1.0", "packages/google-geo-type": "0.7.0", diff --git a/librarian.yaml b/librarian.yaml index 60abb1403b4a..61c8bfff2c48 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -538,7 +538,7 @@ libraries: python: default_version: v1beta - name: google-cloud-bigquery - version: 3.42.0 + version: 3.42.1 python: library_type: GAPIC_COMBO metadata_name_override: bigquery @@ -1015,7 +1015,7 @@ libraries: metadata_name_override: discoveryengine default_version: v1beta - name: google-cloud-dlp - version: 3.37.0 + version: 3.38.0 apis: - path: google/privacy/dlp/v2 python: @@ -1060,27 +1060,27 @@ libraries: metadata_name_override: domains default_version: v1 - name: google-cloud-edgecontainer - version: 0.8.0 + version: 0.8.1 apis: - path: google/cloud/edgecontainer/v1 python: metadata_name_override: edgecontainer default_version: v1 - name: google-cloud-edgenetwork - version: 0.5.0 + version: 0.5.1 apis: - path: google/cloud/edgenetwork/v1 python: default_version: v1 - name: google-cloud-enterpriseknowledgegraph - version: 0.6.0 + version: 0.6.1 apis: - path: google/cloud/enterpriseknowledgegraph/v1 python: metadata_name_override: enterpriseknowledgegraph default_version: v1 - name: google-cloud-error-reporting - version: 1.15.0 + version: 1.16.0 apis: - path: google/devtools/clouderrorreporting/v1beta1 python: @@ -1092,7 +1092,7 @@ libraries: metadata_name_override: clouderrorreporting default_version: v1beta1 - name: google-cloud-essential-contacts - version: 1.13.0 + version: 1.14.0 apis: - path: google/cloud/essentialcontacts/v1 python: @@ -1102,21 +1102,21 @@ libraries: metadata_name_override: essentialcontacts default_version: v1 - name: google-cloud-eventarc - version: 1.20.0 + version: 1.21.0 apis: - path: google/cloud/eventarc/v1 python: metadata_name_override: eventarc default_version: v1 - name: google-cloud-eventarc-publishing - version: 0.10.0 + version: 0.10.1 apis: - path: google/cloud/eventarc/publishing/v1 python: metadata_name_override: eventarcpublishing default_version: v1 - name: google-cloud-filestore - version: 1.16.0 + version: 1.17.0 apis: - path: google/cloud/filestore/v1 python: @@ -1126,7 +1126,7 @@ libraries: metadata_name_override: file default_version: v1 - name: google-cloud-financialservices - version: 0.4.0 + version: 0.4.1 apis: - path: google/cloud/financialservices/v1 python: @@ -1167,7 +1167,7 @@ libraries: metadata_name_override: firestore default_version: v1 - name: google-cloud-functions - version: 1.23.0 + version: 1.24.0 apis: - path: google/cloud/functions/v2 - path: google/cloud/functions/v1 @@ -1175,13 +1175,13 @@ libraries: metadata_name_override: cloudfunctions default_version: v1 - name: google-cloud-gdchardwaremanagement - version: 0.5.0 + version: 0.5.1 apis: - path: google/cloud/gdchardwaremanagement/v1alpha python: default_version: v1alpha - name: google-cloud-geminidataanalytics - version: 0.13.0 + version: 0.13.1 apis: - path: google/cloud/geminidataanalytics/v1 - path: google/cloud/geminidataanalytics/v1beta @@ -1189,7 +1189,7 @@ libraries: python: default_version: v1 - name: google-cloud-gke-backup - version: 0.8.0 + version: 0.8.1 apis: - path: google/cloud/gkebackup/v1 python: @@ -1199,7 +1199,7 @@ libraries: metadata_name_override: gkebackup default_version: v1 - name: google-cloud-gke-connect-gateway - version: 0.13.0 + version: 0.13.1 apis: - path: google/cloud/gkeconnect/gateway/v1 - path: google/cloud/gkeconnect/gateway/v1beta1 @@ -1214,7 +1214,7 @@ libraries: metadata_name_override: connectgateway default_version: v1 - name: google-cloud-gke-hub - version: 1.24.0 + version: 1.25.0 apis: - path: google/cloud/gkehub/v1 - path: google/cloud/gkehub/v1beta1 @@ -1230,7 +1230,7 @@ libraries: metadata_name_override: gkehub default_version: v1 - name: google-cloud-gke-multicloud - version: 0.9.0 + version: 0.9.1 apis: - path: google/cloud/gkemulticloud/v1 python: @@ -1240,13 +1240,13 @@ libraries: metadata_name_override: gkemulticloud default_version: v1 - name: google-cloud-gkerecommender - version: 0.3.0 + version: 0.3.1 apis: - path: google/cloud/gkerecommender/v1 python: default_version: v1 - name: google-cloud-gsuiteaddons - version: 0.5.0 + version: 0.5.1 apis: - path: google/cloud/gsuiteaddons/v1 python: @@ -1256,14 +1256,14 @@ libraries: metadata_name_override: gsuiteaddons default_version: v1 - name: google-cloud-hypercomputecluster - version: 0.4.0 + version: 0.4.1 apis: - path: google/cloud/hypercomputecluster/v1 - path: google/cloud/hypercomputecluster/v1beta python: default_version: v1 - name: google-cloud-iam - version: 2.23.0 + version: 2.24.0 apis: - path: google/iam/v3 - path: google/iam/v2 @@ -1294,7 +1294,7 @@ libraries: metadata_name_override: iam default_version: v2 - name: google-cloud-iam-logging - version: 1.7.0 + version: 1.8.0 apis: - path: google/iam/v1/logging keep: @@ -1308,34 +1308,34 @@ libraries: metadata_name_override: iamlogging default_version: v1 - name: google-cloud-iamconnectorcredentials - version: 0.1.0 + version: 0.1.1 apis: - path: google/cloud/iamconnectorcredentials/v1alpha python: default_version: v1alpha - name: google-cloud-iap - version: 1.21.0 + version: 1.22.0 apis: - path: google/cloud/iap/v1 python: metadata_name_override: iap default_version: v1 - name: google-cloud-ids - version: 1.13.0 + version: 1.14.0 apis: - path: google/cloud/ids/v1 python: metadata_name_override: ids default_version: v1 - name: google-cloud-kms - version: 3.13.0 + version: 3.14.0 apis: - path: google/cloud/kms/v1 python: metadata_name_override: cloudkms default_version: v1 - name: google-cloud-kms-inventory - version: 0.6.0 + version: 0.6.1 apis: - path: google/cloud/kms/inventory/v1 python: @@ -1345,7 +1345,7 @@ libraries: metadata_name_override: inventory default_version: v1 - name: google-cloud-language - version: 2.20.0 + version: 2.21.0 apis: - path: google/cloud/language/v2 - path: google/cloud/language/v1 @@ -1354,20 +1354,20 @@ libraries: metadata_name_override: language default_version: v1 - name: google-cloud-licensemanager - version: 0.4.0 + version: 0.4.1 apis: - path: google/cloud/licensemanager/v1 python: default_version: v1 - name: google-cloud-life-sciences - version: 0.12.0 + version: 0.12.1 apis: - path: google/cloud/lifesciences/v2beta python: metadata_name_override: lifesciences default_version: v2beta - name: google-cloud-locationfinder - version: 0.4.0 + version: 0.4.1 apis: - path: google/cloud/locationfinder/v1 python: @@ -1385,46 +1385,46 @@ libraries: metadata_name_override: logging default_version: v2 - name: google-cloud-lustre - version: 0.4.0 + version: 0.4.1 apis: - path: google/cloud/lustre/v1 python: default_version: v1 - name: google-cloud-maintenance-api - version: 0.4.0 + version: 0.4.1 apis: - path: google/cloud/maintenance/api/v1 - path: google/cloud/maintenance/api/v1beta python: default_version: v1 - name: google-cloud-managed-identities - version: 1.15.0 + version: 1.16.0 apis: - path: google/cloud/managedidentities/v1 python: metadata_name_override: managedidentities default_version: v1 - name: google-cloud-managedkafka - version: 0.4.0 + version: 0.4.1 apis: - path: google/cloud/managedkafka/v1 python: default_version: v1 - name: google-cloud-managedkafka-schemaregistry - version: 0.4.0 + version: 0.4.1 apis: - path: google/cloud/managedkafka/schemaregistry/v1 python: default_version: v1 - name: google-cloud-media-translation - version: 0.14.0 + version: 0.14.1 apis: - path: google/cloud/mediatranslation/v1beta1 python: metadata_name_override: mediatranslation default_version: v1beta1 - name: google-cloud-memcache - version: 1.15.0 + version: 1.16.0 apis: - path: google/cloud/memcache/v1 - path: google/cloud/memcache/v1beta2 @@ -1432,14 +1432,14 @@ libraries: metadata_name_override: memcache default_version: v1 - name: google-cloud-memorystore - version: 0.5.0 + version: 0.5.1 apis: - path: google/cloud/memorystore/v1 - path: google/cloud/memorystore/v1beta python: default_version: v1 - name: google-cloud-migrationcenter - version: 0.4.0 + version: 0.4.1 apis: - path: google/cloud/migrationcenter/v1 python: @@ -1465,7 +1465,7 @@ libraries: metadata_name_override: monitoring default_version: v3 - name: google-cloud-monitoring-dashboards - version: 2.21.0 + version: 2.22.0 apis: - path: google/monitoring/dashboard/v1 keep: @@ -1479,7 +1479,7 @@ libraries: metadata_name_override: monitoring-dashboards default_version: v1 - name: google-cloud-monitoring-metrics-scopes - version: 1.12.0 + version: 1.13.0 apis: - path: google/monitoring/metricsscope/v1 python: @@ -1494,14 +1494,14 @@ libraries: library_type: GAPIC_MANUAL metadata_name_override: python-ndb - name: google-cloud-netapp - version: 0.10.0 + version: 0.10.1 apis: - path: google/cloud/netapp/v1 python: metadata_name_override: netapp default_version: v1 - name: google-cloud-network-connectivity - version: 2.15.0 + version: 2.16.0 apis: - path: google/cloud/networkconnectivity/v1 - path: google/cloud/networkconnectivity/v1beta @@ -1510,7 +1510,7 @@ libraries: metadata_name_override: networkconnectivity default_version: v1 - name: google-cloud-network-management - version: 1.35.0 + version: 1.36.0 apis: - path: google/cloud/networkmanagement/v1 python: @@ -1520,7 +1520,7 @@ libraries: metadata_name_override: networkmanagement default_version: v1 - name: google-cloud-network-security - version: 0.13.0 + version: 0.13.1 apis: - path: google/cloud/networksecurity/v1 - path: google/cloud/networksecurity/v1beta1 @@ -1546,7 +1546,7 @@ libraries: metadata_name_override: networkservices default_version: v1 - name: google-cloud-notebooks - version: 1.16.0 + version: 1.17.0 apis: - path: google/cloud/notebooks/v2 - path: google/cloud/notebooks/v1 @@ -1555,7 +1555,7 @@ libraries: metadata_name_override: notebooks default_version: v1 - name: google-cloud-optimization - version: 1.14.0 + version: 1.15.0 apis: - path: google/cloud/optimization/v1 python: @@ -1568,7 +1568,7 @@ libraries: python: default_version: v1 - name: google-cloud-orchestration-airflow - version: 1.21.0 + version: 1.22.0 apis: - path: google/cloud/orchestration/airflow/service/v1 - path: google/cloud/orchestration/airflow/service/v1beta1 @@ -1583,7 +1583,7 @@ libraries: metadata_name_override: composer default_version: v1 - name: google-cloud-org-policy - version: 1.17.0 + version: 1.18.0 apis: - path: google/cloud/orgpolicy/v2 - path: google/cloud/orgpolicy/v1 @@ -1593,7 +1593,7 @@ libraries: metadata_name_override: orgpolicy default_version: v2 - name: google-cloud-os-config - version: 1.24.0 + version: 1.25.0 apis: - path: google/cloud/osconfig/v1 - path: google/cloud/osconfig/v1alpha @@ -1601,7 +1601,7 @@ libraries: metadata_name_override: osconfig default_version: v1 - name: google-cloud-os-login - version: 2.21.0 + version: 2.22.0 apis: - path: google/cloud/oslogin/v1 keep: @@ -1613,34 +1613,34 @@ libraries: metadata_name_override: oslogin default_version: v1 - name: google-cloud-parallelstore - version: 0.6.0 + version: 0.6.1 apis: - path: google/cloud/parallelstore/v1 - path: google/cloud/parallelstore/v1beta python: default_version: v1beta - name: google-cloud-parametermanager - version: 0.4.0 + version: 0.4.1 apis: - path: google/cloud/parametermanager/v1 python: default_version: v1 - name: google-cloud-phishing-protection - version: 1.17.0 + version: 1.18.0 apis: - path: google/cloud/phishingprotection/v1beta1 python: metadata_name_override: phishingprotection default_version: v1beta1 - name: google-cloud-policy-troubleshooter - version: 1.16.0 + version: 1.17.0 apis: - path: google/cloud/policytroubleshooter/v1 python: metadata_name_override: policytroubleshooter default_version: v1 - name: google-cloud-policysimulator - version: 0.4.0 + version: 0.4.1 apis: - path: google/cloud/policysimulator/v1 python: @@ -1650,14 +1650,14 @@ libraries: metadata_name_override: policysimulator default_version: v1 - name: google-cloud-policytroubleshooter-iam - version: 0.5.0 + version: 0.5.1 apis: - path: google/cloud/policytroubleshooter/iam/v3 python: metadata_name_override: policytroubleshooter-iam default_version: v3 - name: google-cloud-private-ca - version: 1.18.0 + version: 1.19.0 apis: - path: google/cloud/security/privateca/v1 - path: google/cloud/security/privateca/v1beta1 @@ -1672,14 +1672,14 @@ libraries: metadata_name_override: privateca default_version: v1 - name: google-cloud-private-catalog - version: 0.12.0 + version: 0.12.1 apis: - path: google/cloud/privatecatalog/v1beta1 python: metadata_name_override: cloudprivatecatalog default_version: v1beta1 - name: google-cloud-privilegedaccessmanager - version: 0.4.0 + version: 0.4.1 apis: - path: google/cloud/privilegedaccessmanager/v1 python: @@ -1697,7 +1697,7 @@ libraries: metadata_name_override: pubsub default_version: v1 - name: google-cloud-quotas - version: 0.6.0 + version: 0.6.1 apis: - path: google/api/cloudquotas/v1 - path: google/api/cloudquotas/v1beta @@ -1710,28 +1710,28 @@ libraries: metadata_name_override: google-cloud-cloudquotas default_version: v1 - name: google-cloud-rapidmigrationassessment - version: 0.4.0 + version: 0.4.1 apis: - path: google/cloud/rapidmigrationassessment/v1 python: metadata_name_override: rapidmigrationassessment default_version: v1 - name: google-cloud-recaptcha-enterprise - version: 1.31.0 + version: 1.32.0 apis: - path: google/cloud/recaptchaenterprise/v1 python: metadata_name_override: recaptchaenterprise default_version: v1 - name: google-cloud-recommendations-ai - version: 0.13.0 + version: 0.13.1 apis: - path: google/cloud/recommendationengine/v1beta1 python: metadata_name_override: recommendationengine default_version: v1beta1 - name: google-cloud-recommender - version: 2.21.0 + version: 2.22.0 apis: - path: google/cloud/recommender/v1 - path: google/cloud/recommender/v1beta1 @@ -1739,7 +1739,7 @@ libraries: metadata_name_override: recommender default_version: v1 - name: google-cloud-redis - version: 2.21.0 + version: 2.22.0 apis: - path: google/cloud/redis/v1 - path: google/cloud/redis/v1beta1 @@ -1747,21 +1747,21 @@ libraries: metadata_name_override: redis default_version: v1 - name: google-cloud-redis-cluster - version: 0.5.0 + version: 0.5.1 apis: - path: google/cloud/redis/cluster/v1 - path: google/cloud/redis/cluster/v1beta1 python: default_version: v1 - name: google-cloud-resource-manager - version: 1.17.0 + version: 1.18.0 apis: - path: google/cloud/resourcemanager/v3 python: metadata_name_override: cloudresourcemanager default_version: v3 - name: google-cloud-retail - version: 2.10.0 + version: 2.11.0 apis: - path: google/cloud/retail/v2 - path: google/cloud/retail/v2beta @@ -1770,7 +1770,7 @@ libraries: metadata_name_override: retail default_version: v2 - name: google-cloud-run - version: 0.16.0 + version: 0.16.1 apis: - path: google/cloud/run/v2 python: @@ -2013,7 +2013,7 @@ libraries: metadata_name_override: support default_version: v2 - name: google-cloud-talent - version: 2.20.0 + version: 2.21.0 apis: - path: google/cloud/talent/v4 - path: google/cloud/talent/v4beta1 @@ -2021,7 +2021,7 @@ libraries: metadata_name_override: talent default_version: v4 - name: google-cloud-tasks - version: 2.22.0 + version: 2.23.0 apis: - path: google/cloud/tasks/v2 - path: google/cloud/tasks/v2beta3 @@ -2030,19 +2030,19 @@ libraries: metadata_name_override: cloudtasks default_version: v2 - name: google-cloud-telcoautomation - version: 0.5.0 + version: 0.5.1 apis: - path: google/cloud/telcoautomation/v1 - path: google/cloud/telcoautomation/v1alpha1 python: default_version: v1 - name: google-cloud-testutils - version: 1.9.0 + version: 1.9.1 python: library_type: OTHER metadata_name_override: google-cloud-test-utils - name: google-cloud-texttospeech - version: 2.36.0 + version: 2.37.0 apis: - path: google/cloud/texttospeech/v1 - path: google/cloud/texttospeech/v1beta1 @@ -2050,7 +2050,7 @@ libraries: metadata_name_override: texttospeech default_version: v1 - name: google-cloud-tpu - version: 1.26.0 + version: 1.27.0 apis: - path: google/cloud/tpu/v2 - path: google/cloud/tpu/v1 @@ -2059,7 +2059,7 @@ libraries: metadata_name_override: tpu default_version: v1 - name: google-cloud-trace - version: 1.19.0 + version: 1.20.0 apis: - path: google/devtools/cloudtrace/v2 - path: google/devtools/cloudtrace/v1 @@ -2074,7 +2074,7 @@ libraries: metadata_name_override: cloudtrace default_version: v2 - name: google-cloud-translate - version: 3.26.0 + version: 3.27.0 apis: - path: google/cloud/translate/v3 - path: google/cloud/translate/v3beta1 @@ -2090,7 +2090,7 @@ libraries: python: default_version: v1 - name: google-cloud-video-live-stream - version: 1.16.0 + version: 1.17.0 apis: - path: google/cloud/video/livestream/v1 python: @@ -2101,7 +2101,7 @@ libraries: metadata_name_override: livestream default_version: v1 - name: google-cloud-video-stitcher - version: 0.11.0 + version: 0.11.1 apis: - path: google/cloud/video/stitcher/v1 python: @@ -2112,7 +2112,7 @@ libraries: metadata_name_override: videostitcher default_version: v1 - name: google-cloud-video-transcoder - version: 1.20.0 + version: 1.21.0 apis: - path: google/cloud/video/transcoder/v1 python: @@ -2123,7 +2123,7 @@ libraries: metadata_name_override: transcoder default_version: v1 - name: google-cloud-videointelligence - version: 2.19.0 + version: 2.20.0 apis: - path: google/cloud/videointelligence/v1 - path: google/cloud/videointelligence/v1p3beta1 @@ -2134,7 +2134,7 @@ libraries: metadata_name_override: videointelligence default_version: v1 - name: google-cloud-vision - version: 3.14.0 + version: 3.15.0 apis: - path: google/cloud/vision/v1 - path: google/cloud/vision/v1p4beta1 @@ -2146,35 +2146,35 @@ libraries: metadata_name_override: vision default_version: v1 - name: google-cloud-visionai - version: 0.5.0 + version: 0.5.1 apis: - path: google/cloud/visionai/v1 - path: google/cloud/visionai/v1alpha1 python: default_version: v1 - name: google-cloud-vm-migration - version: 1.16.0 + version: 1.17.0 apis: - path: google/cloud/vmmigration/v1 python: metadata_name_override: vmmigration default_version: v1 - name: google-cloud-vmwareengine - version: 1.11.0 + version: 1.12.0 apis: - path: google/cloud/vmwareengine/v1 python: metadata_name_override: vmwareengine default_version: v1 - name: google-cloud-vpc-access - version: 1.16.0 + version: 1.17.0 apis: - path: google/cloud/vpcaccess/v1 python: metadata_name_override: vpcaccess default_version: v1 - name: google-cloud-webrisk - version: 1.21.0 + version: 1.22.0 apis: - path: google/cloud/webrisk/v1 - path: google/cloud/webrisk/v1beta1 @@ -2182,7 +2182,7 @@ libraries: metadata_name_override: webrisk default_version: v1 - name: google-cloud-websecurityscanner - version: 1.20.0 + version: 1.21.0 apis: - path: google/cloud/websecurityscanner/v1 - path: google/cloud/websecurityscanner/v1beta @@ -2191,7 +2191,7 @@ libraries: metadata_name_override: websecurityscanner default_version: v1 - name: google-cloud-workflows - version: 1.22.0 + version: 1.23.0 apis: - path: google/cloud/workflows/v1 - path: google/cloud/workflows/executions/v1 @@ -2208,13 +2208,13 @@ libraries: metadata_name_override: workflows default_version: v1 - name: google-cloud-workloadmanager - version: 0.2.0 + version: 0.2.1 apis: - path: google/cloud/workloadmanager/v1 python: default_version: v1 - name: google-cloud-workstations - version: 0.8.0 + version: 0.8.1 apis: - path: google/cloud/workstations/v1 - path: google/cloud/workstations/v1beta diff --git a/packages/google-cloud-bigquery/CHANGELOG.md b/packages/google-cloud-bigquery/CHANGELOG.md index 978555bf3a03..f74fb6e7ea1b 100644 --- a/packages/google-cloud-bigquery/CHANGELOG.md +++ b/packages/google-cloud-bigquery/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-bigquery/#history +## [3.42.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-bigquery-v3.42.0...google-cloud-bigquery-v3.42.1) (2026-06-22) + + +### Bug Fixes + +* **bigquery:** close GAPIC storage transport and auth sessions to prevent socket leaks ([#17508](https://github.com/googleapis/google-cloud-python/issues/17508)) ([0258405](https://github.com/googleapis/google-cloud-python/commit/025840544f5d4ab6a429d1cd9bdbb256c981aa0d)) + ## [3.42.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-bigquery-v3.41.0...google-cloud-bigquery-v3.42.0) (2026-06-12) diff --git a/packages/google-cloud-bigquery/google/cloud/bigquery/version.py b/packages/google-cloud-bigquery/google/cloud/bigquery/version.py index 24c157c62aca..537da2ae7f2b 100644 --- a/packages/google-cloud-bigquery/google/cloud/bigquery/version.py +++ b/packages/google-cloud-bigquery/google/cloud/bigquery/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "3.42.0" +__version__ = "3.42.1" diff --git a/packages/google-cloud-dlp/CHANGELOG.md b/packages/google-cloud-dlp/CHANGELOG.md index 600f60875072..dc4fc8f2c7a6 100644 --- a/packages/google-cloud-dlp/CHANGELOG.md +++ b/packages/google-cloud-dlp/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-dlp/#history +## [3.38.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-dlp-v3.37.0...google-cloud-dlp-v3.38.0) (2026-06-22) + + +### Features + +* update googleapis and regenerate ([33ba3af](https://github.com/googleapis/google-cloud-python/commit/33ba3afe520e2f64ac7464f1b4ee31c0624a65ac)) + ## [3.37.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-dlp-v3.36.0...google-cloud-dlp-v3.37.0) (2026-06-02) diff --git a/packages/google-cloud-dlp/google/cloud/dlp/gapic_version.py b/packages/google-cloud-dlp/google/cloud/dlp/gapic_version.py index 603af12f2f5d..a1d6a371b75f 100644 --- a/packages/google-cloud-dlp/google/cloud/dlp/gapic_version.py +++ b/packages/google-cloud-dlp/google/cloud/dlp/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "3.37.0" # {x-release-please-version} +__version__ = "3.38.0" # {x-release-please-version} diff --git a/packages/google-cloud-dlp/google/cloud/dlp_v2/gapic_version.py b/packages/google-cloud-dlp/google/cloud/dlp_v2/gapic_version.py index 603af12f2f5d..a1d6a371b75f 100644 --- a/packages/google-cloud-dlp/google/cloud/dlp_v2/gapic_version.py +++ b/packages/google-cloud-dlp/google/cloud/dlp_v2/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "3.37.0" # {x-release-please-version} +__version__ = "3.38.0" # {x-release-please-version} diff --git a/packages/google-cloud-dlp/samples/generated_samples/snippet_metadata_google.privacy.dlp.v2.json b/packages/google-cloud-dlp/samples/generated_samples/snippet_metadata_google.privacy.dlp.v2.json index 8837a366e7a9..f0512c6f4197 100644 --- a/packages/google-cloud-dlp/samples/generated_samples/snippet_metadata_google.privacy.dlp.v2.json +++ b/packages/google-cloud-dlp/samples/generated_samples/snippet_metadata_google.privacy.dlp.v2.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-dlp", - "version": "3.37.0" + "version": "3.38.0" }, "snippets": [ { diff --git a/packages/google-cloud-edgecontainer/CHANGELOG.md b/packages/google-cloud-edgecontainer/CHANGELOG.md index 0fa9d0a200d8..092a6825d501 100644 --- a/packages/google-cloud-edgecontainer/CHANGELOG.md +++ b/packages/google-cloud-edgecontainer/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-edgecontainer/#history +## [0.8.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-edgecontainer-v0.8.0...google-cloud-edgecontainer-v0.8.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d)) + ## [0.8.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-edgecontainer-v0.7.0...google-cloud-edgecontainer-v0.8.0) (2026-03-26) diff --git a/packages/google-cloud-edgecontainer/google/cloud/edgecontainer/gapic_version.py b/packages/google-cloud-edgecontainer/google/cloud/edgecontainer/gapic_version.py index ed31d4798409..af283a821985 100644 --- a/packages/google-cloud-edgecontainer/google/cloud/edgecontainer/gapic_version.py +++ b/packages/google-cloud-edgecontainer/google/cloud/edgecontainer/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.8.0" # {x-release-please-version} +__version__ = "0.8.1" # {x-release-please-version} diff --git a/packages/google-cloud-edgecontainer/google/cloud/edgecontainer_v1/gapic_version.py b/packages/google-cloud-edgecontainer/google/cloud/edgecontainer_v1/gapic_version.py index ed31d4798409..af283a821985 100644 --- a/packages/google-cloud-edgecontainer/google/cloud/edgecontainer_v1/gapic_version.py +++ b/packages/google-cloud-edgecontainer/google/cloud/edgecontainer_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.8.0" # {x-release-please-version} +__version__ = "0.8.1" # {x-release-please-version} diff --git a/packages/google-cloud-edgecontainer/samples/generated_samples/snippet_metadata_google.cloud.edgecontainer.v1.json b/packages/google-cloud-edgecontainer/samples/generated_samples/snippet_metadata_google.cloud.edgecontainer.v1.json index a0c2118070bc..4dbaf65f33f2 100644 --- a/packages/google-cloud-edgecontainer/samples/generated_samples/snippet_metadata_google.cloud.edgecontainer.v1.json +++ b/packages/google-cloud-edgecontainer/samples/generated_samples/snippet_metadata_google.cloud.edgecontainer.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-edgecontainer", - "version": "0.8.0" + "version": "0.8.1" }, "snippets": [ { diff --git a/packages/google-cloud-edgenetwork/CHANGELOG.md b/packages/google-cloud-edgenetwork/CHANGELOG.md index 9cd2d38bb47f..eb252680e2cc 100644 --- a/packages/google-cloud-edgenetwork/CHANGELOG.md +++ b/packages/google-cloud-edgenetwork/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-edgenetwork/#history +## [0.5.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-edgenetwork-v0.5.0...google-cloud-edgenetwork-v0.5.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d)) + ## [0.5.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-edgenetwork-v0.4.0...google-cloud-edgenetwork-v0.5.0) (2026-03-26) diff --git a/packages/google-cloud-edgenetwork/google/cloud/edgenetwork/gapic_version.py b/packages/google-cloud-edgenetwork/google/cloud/edgenetwork/gapic_version.py index 7d9863d19611..acc458e7fa6f 100644 --- a/packages/google-cloud-edgenetwork/google/cloud/edgenetwork/gapic_version.py +++ b/packages/google-cloud-edgenetwork/google/cloud/edgenetwork/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.5.0" # {x-release-please-version} +__version__ = "0.5.1" # {x-release-please-version} diff --git a/packages/google-cloud-edgenetwork/google/cloud/edgenetwork_v1/gapic_version.py b/packages/google-cloud-edgenetwork/google/cloud/edgenetwork_v1/gapic_version.py index 7d9863d19611..acc458e7fa6f 100644 --- a/packages/google-cloud-edgenetwork/google/cloud/edgenetwork_v1/gapic_version.py +++ b/packages/google-cloud-edgenetwork/google/cloud/edgenetwork_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.5.0" # {x-release-please-version} +__version__ = "0.5.1" # {x-release-please-version} diff --git a/packages/google-cloud-edgenetwork/samples/generated_samples/snippet_metadata_google.cloud.edgenetwork.v1.json b/packages/google-cloud-edgenetwork/samples/generated_samples/snippet_metadata_google.cloud.edgenetwork.v1.json index dbc5eec5711f..d76249928507 100644 --- a/packages/google-cloud-edgenetwork/samples/generated_samples/snippet_metadata_google.cloud.edgenetwork.v1.json +++ b/packages/google-cloud-edgenetwork/samples/generated_samples/snippet_metadata_google.cloud.edgenetwork.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-edgenetwork", - "version": "0.5.0" + "version": "0.5.1" }, "snippets": [ { diff --git a/packages/google-cloud-enterpriseknowledgegraph/CHANGELOG.md b/packages/google-cloud-enterpriseknowledgegraph/CHANGELOG.md index 79337c58765a..1f7a38273990 100644 --- a/packages/google-cloud-enterpriseknowledgegraph/CHANGELOG.md +++ b/packages/google-cloud-enterpriseknowledgegraph/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-enterpriseknowledgegraph/#history +## [0.6.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-enterpriseknowledgegraph-v0.6.0...google-cloud-enterpriseknowledgegraph-v0.6.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d)) + ## [0.6.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-enterpriseknowledgegraph-v0.5.0...google-cloud-enterpriseknowledgegraph-v0.6.0) (2026-03-26) diff --git a/packages/google-cloud-enterpriseknowledgegraph/google/cloud/enterpriseknowledgegraph/gapic_version.py b/packages/google-cloud-enterpriseknowledgegraph/google/cloud/enterpriseknowledgegraph/gapic_version.py index 916d95dd4eda..4c89af3224e4 100644 --- a/packages/google-cloud-enterpriseknowledgegraph/google/cloud/enterpriseknowledgegraph/gapic_version.py +++ b/packages/google-cloud-enterpriseknowledgegraph/google/cloud/enterpriseknowledgegraph/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.6.0" # {x-release-please-version} +__version__ = "0.6.1" # {x-release-please-version} diff --git a/packages/google-cloud-enterpriseknowledgegraph/google/cloud/enterpriseknowledgegraph_v1/gapic_version.py b/packages/google-cloud-enterpriseknowledgegraph/google/cloud/enterpriseknowledgegraph_v1/gapic_version.py index 916d95dd4eda..4c89af3224e4 100644 --- a/packages/google-cloud-enterpriseknowledgegraph/google/cloud/enterpriseknowledgegraph_v1/gapic_version.py +++ b/packages/google-cloud-enterpriseknowledgegraph/google/cloud/enterpriseknowledgegraph_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.6.0" # {x-release-please-version} +__version__ = "0.6.1" # {x-release-please-version} diff --git a/packages/google-cloud-enterpriseknowledgegraph/samples/generated_samples/snippet_metadata_google.cloud.enterpriseknowledgegraph.v1.json b/packages/google-cloud-enterpriseknowledgegraph/samples/generated_samples/snippet_metadata_google.cloud.enterpriseknowledgegraph.v1.json index 0f5938d1bebc..a3f14a9e185a 100644 --- a/packages/google-cloud-enterpriseknowledgegraph/samples/generated_samples/snippet_metadata_google.cloud.enterpriseknowledgegraph.v1.json +++ b/packages/google-cloud-enterpriseknowledgegraph/samples/generated_samples/snippet_metadata_google.cloud.enterpriseknowledgegraph.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-enterpriseknowledgegraph", - "version": "0.6.0" + "version": "0.6.1" }, "snippets": [ { diff --git a/packages/google-cloud-error-reporting/CHANGELOG.md b/packages/google-cloud-error-reporting/CHANGELOG.md index 1b9e415145c6..7aa4c7c198c2 100644 --- a/packages/google-cloud-error-reporting/CHANGELOG.md +++ b/packages/google-cloud-error-reporting/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-error-reporting/#history +## [1.16.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-error-reporting-v1.15.0...google-cloud-error-reporting-v1.16.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d)) + ## [1.15.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-error-reporting-v1.14.0...google-cloud-error-reporting-v1.15.0) (2026-03-26) diff --git a/packages/google-cloud-error-reporting/google/cloud/error_reporting/gapic_version.py b/packages/google-cloud-error-reporting/google/cloud/error_reporting/gapic_version.py index 7e4ae77c649b..da7f5dbf530e 100644 --- a/packages/google-cloud-error-reporting/google/cloud/error_reporting/gapic_version.py +++ b/packages/google-cloud-error-reporting/google/cloud/error_reporting/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.15.0" # {x-release-please-version} +__version__ = "1.16.0" # {x-release-please-version} diff --git a/packages/google-cloud-error-reporting/google/cloud/errorreporting/gapic_version.py b/packages/google-cloud-error-reporting/google/cloud/errorreporting/gapic_version.py index 6c6a19c3c497..14edf824ad86 100644 --- a/packages/google-cloud-error-reporting/google/cloud/errorreporting/gapic_version.py +++ b/packages/google-cloud-error-reporting/google/cloud/errorreporting/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.15.0" # {x-release-please-version} +__version__ = "1.16.0" # {x-release-please-version} diff --git a/packages/google-cloud-error-reporting/google/cloud/errorreporting_v1beta1/gapic_version.py b/packages/google-cloud-error-reporting/google/cloud/errorreporting_v1beta1/gapic_version.py index 6c6a19c3c497..14edf824ad86 100644 --- a/packages/google-cloud-error-reporting/google/cloud/errorreporting_v1beta1/gapic_version.py +++ b/packages/google-cloud-error-reporting/google/cloud/errorreporting_v1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.15.0" # {x-release-please-version} +__version__ = "1.16.0" # {x-release-please-version} diff --git a/packages/google-cloud-error-reporting/samples/generated_samples/snippet_metadata_google.devtools.clouderrorreporting.v1beta1.json b/packages/google-cloud-error-reporting/samples/generated_samples/snippet_metadata_google.devtools.clouderrorreporting.v1beta1.json index c615c1f327cb..0fa51dc4c19e 100644 --- a/packages/google-cloud-error-reporting/samples/generated_samples/snippet_metadata_google.devtools.clouderrorreporting.v1beta1.json +++ b/packages/google-cloud-error-reporting/samples/generated_samples/snippet_metadata_google.devtools.clouderrorreporting.v1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-error-reporting", - "version": "1.15.0" + "version": "1.16.0" }, "snippets": [ { diff --git a/packages/google-cloud-essential-contacts/CHANGELOG.md b/packages/google-cloud-essential-contacts/CHANGELOG.md index 3bea95df1a71..2d05e57e9bb4 100644 --- a/packages/google-cloud-essential-contacts/CHANGELOG.md +++ b/packages/google-cloud-essential-contacts/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-essential-contacts/#history +## [1.14.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-essential-contacts-v1.13.0...google-cloud-essential-contacts-v1.14.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d)) + ## [1.13.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-essential-contacts-v1.12.0...google-cloud-essential-contacts-v1.13.0) (2026-03-26) diff --git a/packages/google-cloud-essential-contacts/google/cloud/essential_contacts/gapic_version.py b/packages/google-cloud-essential-contacts/google/cloud/essential_contacts/gapic_version.py index 66da8b1d1133..da4b0a9cf041 100644 --- a/packages/google-cloud-essential-contacts/google/cloud/essential_contacts/gapic_version.py +++ b/packages/google-cloud-essential-contacts/google/cloud/essential_contacts/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.13.0" # {x-release-please-version} +__version__ = "1.14.0" # {x-release-please-version} diff --git a/packages/google-cloud-essential-contacts/google/cloud/essential_contacts_v1/gapic_version.py b/packages/google-cloud-essential-contacts/google/cloud/essential_contacts_v1/gapic_version.py index 66da8b1d1133..da4b0a9cf041 100644 --- a/packages/google-cloud-essential-contacts/google/cloud/essential_contacts_v1/gapic_version.py +++ b/packages/google-cloud-essential-contacts/google/cloud/essential_contacts_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.13.0" # {x-release-please-version} +__version__ = "1.14.0" # {x-release-please-version} diff --git a/packages/google-cloud-essential-contacts/samples/generated_samples/snippet_metadata_google.cloud.essentialcontacts.v1.json b/packages/google-cloud-essential-contacts/samples/generated_samples/snippet_metadata_google.cloud.essentialcontacts.v1.json index f9a6c3b62210..06bfeb14539c 100644 --- a/packages/google-cloud-essential-contacts/samples/generated_samples/snippet_metadata_google.cloud.essentialcontacts.v1.json +++ b/packages/google-cloud-essential-contacts/samples/generated_samples/snippet_metadata_google.cloud.essentialcontacts.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-essential-contacts", - "version": "1.13.0" + "version": "1.14.0" }, "snippets": [ { diff --git a/packages/google-cloud-eventarc-publishing/CHANGELOG.md b/packages/google-cloud-eventarc-publishing/CHANGELOG.md index 601fb33bee4a..304632eb48ce 100644 --- a/packages/google-cloud-eventarc-publishing/CHANGELOG.md +++ b/packages/google-cloud-eventarc-publishing/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-eventarc-publishing/#history +## [0.10.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-eventarc-publishing-v0.10.0...google-cloud-eventarc-publishing-v0.10.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d)) + ## [0.10.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-eventarc-publishing-v0.9.0...google-cloud-eventarc-publishing-v0.10.0) (2026-03-26) diff --git a/packages/google-cloud-eventarc-publishing/google/cloud/eventarc_publishing/gapic_version.py b/packages/google-cloud-eventarc-publishing/google/cloud/eventarc_publishing/gapic_version.py index 0a5d17e6c82a..e946c8a43986 100644 --- a/packages/google-cloud-eventarc-publishing/google/cloud/eventarc_publishing/gapic_version.py +++ b/packages/google-cloud-eventarc-publishing/google/cloud/eventarc_publishing/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.10.0" # {x-release-please-version} +__version__ = "0.10.1" # {x-release-please-version} diff --git a/packages/google-cloud-eventarc-publishing/google/cloud/eventarc_publishing_v1/gapic_version.py b/packages/google-cloud-eventarc-publishing/google/cloud/eventarc_publishing_v1/gapic_version.py index 0a5d17e6c82a..e946c8a43986 100644 --- a/packages/google-cloud-eventarc-publishing/google/cloud/eventarc_publishing_v1/gapic_version.py +++ b/packages/google-cloud-eventarc-publishing/google/cloud/eventarc_publishing_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.10.0" # {x-release-please-version} +__version__ = "0.10.1" # {x-release-please-version} diff --git a/packages/google-cloud-eventarc-publishing/samples/generated_samples/snippet_metadata_google.cloud.eventarc.publishing.v1.json b/packages/google-cloud-eventarc-publishing/samples/generated_samples/snippet_metadata_google.cloud.eventarc.publishing.v1.json index a4fff63aad96..bddc79615870 100644 --- a/packages/google-cloud-eventarc-publishing/samples/generated_samples/snippet_metadata_google.cloud.eventarc.publishing.v1.json +++ b/packages/google-cloud-eventarc-publishing/samples/generated_samples/snippet_metadata_google.cloud.eventarc.publishing.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-eventarc-publishing", - "version": "0.10.0" + "version": "0.10.1" }, "snippets": [ { diff --git a/packages/google-cloud-eventarc/CHANGELOG.md b/packages/google-cloud-eventarc/CHANGELOG.md index f84eb6c6892c..337ab5e63d47 100644 --- a/packages/google-cloud-eventarc/CHANGELOG.md +++ b/packages/google-cloud-eventarc/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-eventarc/#history +## [1.21.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-eventarc-v1.20.0...google-cloud-eventarc-v1.21.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d)) + ## [1.20.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-eventarc-v1.19.0...google-cloud-eventarc-v1.20.0) (2026-03-26) diff --git a/packages/google-cloud-eventarc/google/cloud/eventarc/gapic_version.py b/packages/google-cloud-eventarc/google/cloud/eventarc/gapic_version.py index c0c0d110e496..95884592d2da 100644 --- a/packages/google-cloud-eventarc/google/cloud/eventarc/gapic_version.py +++ b/packages/google-cloud-eventarc/google/cloud/eventarc/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.20.0" # {x-release-please-version} +__version__ = "1.21.0" # {x-release-please-version} diff --git a/packages/google-cloud-eventarc/google/cloud/eventarc_v1/gapic_version.py b/packages/google-cloud-eventarc/google/cloud/eventarc_v1/gapic_version.py index c0c0d110e496..95884592d2da 100644 --- a/packages/google-cloud-eventarc/google/cloud/eventarc_v1/gapic_version.py +++ b/packages/google-cloud-eventarc/google/cloud/eventarc_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.20.0" # {x-release-please-version} +__version__ = "1.21.0" # {x-release-please-version} diff --git a/packages/google-cloud-eventarc/samples/generated_samples/snippet_metadata_google.cloud.eventarc.v1.json b/packages/google-cloud-eventarc/samples/generated_samples/snippet_metadata_google.cloud.eventarc.v1.json index 3fe087e7bda9..3337f352475a 100644 --- a/packages/google-cloud-eventarc/samples/generated_samples/snippet_metadata_google.cloud.eventarc.v1.json +++ b/packages/google-cloud-eventarc/samples/generated_samples/snippet_metadata_google.cloud.eventarc.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-eventarc", - "version": "1.20.0" + "version": "1.21.0" }, "snippets": [ { diff --git a/packages/google-cloud-filestore/CHANGELOG.md b/packages/google-cloud-filestore/CHANGELOG.md index 5f0dad169c51..645f9a5fcb11 100644 --- a/packages/google-cloud-filestore/CHANGELOG.md +++ b/packages/google-cloud-filestore/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-filestore/#history +## [1.17.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-filestore-v1.16.0...google-cloud-filestore-v1.17.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d)) + ## [1.16.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-filestore-v1.15.0...google-cloud-filestore-v1.16.0) (2026-03-26) diff --git a/packages/google-cloud-filestore/google/cloud/filestore/gapic_version.py b/packages/google-cloud-filestore/google/cloud/filestore/gapic_version.py index 14edf824ad86..2095da2522f4 100644 --- a/packages/google-cloud-filestore/google/cloud/filestore/gapic_version.py +++ b/packages/google-cloud-filestore/google/cloud/filestore/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.16.0" # {x-release-please-version} +__version__ = "1.17.0" # {x-release-please-version} diff --git a/packages/google-cloud-filestore/google/cloud/filestore_v1/gapic_version.py b/packages/google-cloud-filestore/google/cloud/filestore_v1/gapic_version.py index 14edf824ad86..2095da2522f4 100644 --- a/packages/google-cloud-filestore/google/cloud/filestore_v1/gapic_version.py +++ b/packages/google-cloud-filestore/google/cloud/filestore_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.16.0" # {x-release-please-version} +__version__ = "1.17.0" # {x-release-please-version} diff --git a/packages/google-cloud-filestore/samples/generated_samples/snippet_metadata_google.cloud.filestore.v1.json b/packages/google-cloud-filestore/samples/generated_samples/snippet_metadata_google.cloud.filestore.v1.json index 3304301e3cbc..e9b174d39a73 100644 --- a/packages/google-cloud-filestore/samples/generated_samples/snippet_metadata_google.cloud.filestore.v1.json +++ b/packages/google-cloud-filestore/samples/generated_samples/snippet_metadata_google.cloud.filestore.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-filestore", - "version": "1.16.0" + "version": "1.17.0" }, "snippets": [ { diff --git a/packages/google-cloud-financialservices/CHANGELOG.md b/packages/google-cloud-financialservices/CHANGELOG.md index 491df28d4949..24bdd6eeb57c 100644 --- a/packages/google-cloud-financialservices/CHANGELOG.md +++ b/packages/google-cloud-financialservices/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-financialservices/#history +## [0.4.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-financialservices-v0.4.0...google-cloud-financialservices-v0.4.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d)) + ## [0.4.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-financialservices-v0.3.0...google-cloud-financialservices-v0.4.0) (2026-03-26) diff --git a/packages/google-cloud-financialservices/google/cloud/financialservices/gapic_version.py b/packages/google-cloud-financialservices/google/cloud/financialservices/gapic_version.py index 7a26901aff5b..7de1cf9e096e 100644 --- a/packages/google-cloud-financialservices/google/cloud/financialservices/gapic_version.py +++ b/packages/google-cloud-financialservices/google/cloud/financialservices/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.4.1" # {x-release-please-version} diff --git a/packages/google-cloud-financialservices/google/cloud/financialservices_v1/gapic_version.py b/packages/google-cloud-financialservices/google/cloud/financialservices_v1/gapic_version.py index 7a26901aff5b..7de1cf9e096e 100644 --- a/packages/google-cloud-financialservices/google/cloud/financialservices_v1/gapic_version.py +++ b/packages/google-cloud-financialservices/google/cloud/financialservices_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.4.1" # {x-release-please-version} diff --git a/packages/google-cloud-financialservices/samples/generated_samples/snippet_metadata_google.cloud.financialservices.v1.json b/packages/google-cloud-financialservices/samples/generated_samples/snippet_metadata_google.cloud.financialservices.v1.json index bee521b3e7b8..d2627b724cdf 100644 --- a/packages/google-cloud-financialservices/samples/generated_samples/snippet_metadata_google.cloud.financialservices.v1.json +++ b/packages/google-cloud-financialservices/samples/generated_samples/snippet_metadata_google.cloud.financialservices.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-financialservices", - "version": "0.4.0" + "version": "0.4.1" }, "snippets": [ { diff --git a/packages/google-cloud-functions/CHANGELOG.md b/packages/google-cloud-functions/CHANGELOG.md index f2d95d3ee9be..cfd10e96d70f 100644 --- a/packages/google-cloud-functions/CHANGELOG.md +++ b/packages/google-cloud-functions/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-functions/#history +## [1.24.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-functions-v1.23.0...google-cloud-functions-v1.24.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d)) + ## [1.23.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-functions-v1.22.0...google-cloud-functions-v1.23.0) (2026-03-26) diff --git a/packages/google-cloud-functions/google/cloud/functions/gapic_version.py b/packages/google-cloud-functions/google/cloud/functions/gapic_version.py index 7fc0c295471b..c8ec013ce4bb 100644 --- a/packages/google-cloud-functions/google/cloud/functions/gapic_version.py +++ b/packages/google-cloud-functions/google/cloud/functions/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.23.0" # {x-release-please-version} +__version__ = "1.24.0" # {x-release-please-version} diff --git a/packages/google-cloud-functions/google/cloud/functions_v1/gapic_version.py b/packages/google-cloud-functions/google/cloud/functions_v1/gapic_version.py index 7fc0c295471b..c8ec013ce4bb 100644 --- a/packages/google-cloud-functions/google/cloud/functions_v1/gapic_version.py +++ b/packages/google-cloud-functions/google/cloud/functions_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.23.0" # {x-release-please-version} +__version__ = "1.24.0" # {x-release-please-version} diff --git a/packages/google-cloud-functions/google/cloud/functions_v2/gapic_version.py b/packages/google-cloud-functions/google/cloud/functions_v2/gapic_version.py index 7fc0c295471b..c8ec013ce4bb 100644 --- a/packages/google-cloud-functions/google/cloud/functions_v2/gapic_version.py +++ b/packages/google-cloud-functions/google/cloud/functions_v2/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.23.0" # {x-release-please-version} +__version__ = "1.24.0" # {x-release-please-version} diff --git a/packages/google-cloud-functions/samples/generated_samples/snippet_metadata_google.cloud.functions.v1.json b/packages/google-cloud-functions/samples/generated_samples/snippet_metadata_google.cloud.functions.v1.json index 7ce3b71bd21a..77e8365ebb2c 100644 --- a/packages/google-cloud-functions/samples/generated_samples/snippet_metadata_google.cloud.functions.v1.json +++ b/packages/google-cloud-functions/samples/generated_samples/snippet_metadata_google.cloud.functions.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-functions", - "version": "1.23.0" + "version": "1.24.0" }, "snippets": [ { diff --git a/packages/google-cloud-functions/samples/generated_samples/snippet_metadata_google.cloud.functions.v2.json b/packages/google-cloud-functions/samples/generated_samples/snippet_metadata_google.cloud.functions.v2.json index d01164eaf86c..d496edb789d1 100644 --- a/packages/google-cloud-functions/samples/generated_samples/snippet_metadata_google.cloud.functions.v2.json +++ b/packages/google-cloud-functions/samples/generated_samples/snippet_metadata_google.cloud.functions.v2.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-functions", - "version": "1.23.0" + "version": "1.24.0" }, "snippets": [ { diff --git a/packages/google-cloud-gdchardwaremanagement/CHANGELOG.md b/packages/google-cloud-gdchardwaremanagement/CHANGELOG.md index 55126d39dc1b..23e1d8ffb327 100644 --- a/packages/google-cloud-gdchardwaremanagement/CHANGELOG.md +++ b/packages/google-cloud-gdchardwaremanagement/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-gdchardwaremanagement/#history +## [0.5.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-gdchardwaremanagement-v0.5.0...google-cloud-gdchardwaremanagement-v0.5.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d)) + ## [0.5.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-gdchardwaremanagement-v0.4.0...google-cloud-gdchardwaremanagement-v0.5.0) (2026-03-26) diff --git a/packages/google-cloud-gdchardwaremanagement/google/cloud/gdchardwaremanagement/gapic_version.py b/packages/google-cloud-gdchardwaremanagement/google/cloud/gdchardwaremanagement/gapic_version.py index 7d9863d19611..acc458e7fa6f 100644 --- a/packages/google-cloud-gdchardwaremanagement/google/cloud/gdchardwaremanagement/gapic_version.py +++ b/packages/google-cloud-gdchardwaremanagement/google/cloud/gdchardwaremanagement/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.5.0" # {x-release-please-version} +__version__ = "0.5.1" # {x-release-please-version} diff --git a/packages/google-cloud-gdchardwaremanagement/google/cloud/gdchardwaremanagement_v1alpha/gapic_version.py b/packages/google-cloud-gdchardwaremanagement/google/cloud/gdchardwaremanagement_v1alpha/gapic_version.py index 7d9863d19611..acc458e7fa6f 100644 --- a/packages/google-cloud-gdchardwaremanagement/google/cloud/gdchardwaremanagement_v1alpha/gapic_version.py +++ b/packages/google-cloud-gdchardwaremanagement/google/cloud/gdchardwaremanagement_v1alpha/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.5.0" # {x-release-please-version} +__version__ = "0.5.1" # {x-release-please-version} diff --git a/packages/google-cloud-gdchardwaremanagement/samples/generated_samples/snippet_metadata_google.cloud.gdchardwaremanagement.v1alpha.json b/packages/google-cloud-gdchardwaremanagement/samples/generated_samples/snippet_metadata_google.cloud.gdchardwaremanagement.v1alpha.json index 5237e59c7d10..2872ebb9202a 100644 --- a/packages/google-cloud-gdchardwaremanagement/samples/generated_samples/snippet_metadata_google.cloud.gdchardwaremanagement.v1alpha.json +++ b/packages/google-cloud-gdchardwaremanagement/samples/generated_samples/snippet_metadata_google.cloud.gdchardwaremanagement.v1alpha.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-gdchardwaremanagement", - "version": "0.5.0" + "version": "0.5.1" }, "snippets": [ { diff --git a/packages/google-cloud-geminidataanalytics/CHANGELOG.md b/packages/google-cloud-geminidataanalytics/CHANGELOG.md index eeab302dba36..232fdbbcf761 100644 --- a/packages/google-cloud-geminidataanalytics/CHANGELOG.md +++ b/packages/google-cloud-geminidataanalytics/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-geminidataanalytics/#history +## [0.13.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-geminidataanalytics-v0.13.0...google-cloud-geminidataanalytics-v0.13.1) (2026-06-22) + + +### Features + +* update googleapis and regenerate ([33ba3af](https://github.com/googleapis/google-cloud-python/commit/33ba3afe520e2f64ac7464f1b4ee31c0624a65ac)) + ## [0.13.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-geminidataanalytics-v0.12.0...google-cloud-geminidataanalytics-v0.13.0) (2026-05-28) diff --git a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics/gapic_version.py b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics/gapic_version.py index dcda7097daa0..9847b33bcb50 100644 --- a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics/gapic_version.py +++ b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.13.0" # {x-release-please-version} +__version__ = "0.13.1" # {x-release-please-version} diff --git a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1/gapic_version.py b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1/gapic_version.py index dcda7097daa0..9847b33bcb50 100644 --- a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1/gapic_version.py +++ b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.13.0" # {x-release-please-version} +__version__ = "0.13.1" # {x-release-please-version} diff --git a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1alpha/gapic_version.py b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1alpha/gapic_version.py index dcda7097daa0..9847b33bcb50 100644 --- a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1alpha/gapic_version.py +++ b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1alpha/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.13.0" # {x-release-please-version} +__version__ = "0.13.1" # {x-release-please-version} diff --git a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/gapic_version.py b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/gapic_version.py index dcda7097daa0..9847b33bcb50 100644 --- a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/gapic_version.py +++ b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.13.0" # {x-release-please-version} +__version__ = "0.13.1" # {x-release-please-version} diff --git a/packages/google-cloud-geminidataanalytics/samples/generated_samples/snippet_metadata_google.cloud.geminidataanalytics.v1.json b/packages/google-cloud-geminidataanalytics/samples/generated_samples/snippet_metadata_google.cloud.geminidataanalytics.v1.json index 8496bc8b0794..91ef8e4d8512 100644 --- a/packages/google-cloud-geminidataanalytics/samples/generated_samples/snippet_metadata_google.cloud.geminidataanalytics.v1.json +++ b/packages/google-cloud-geminidataanalytics/samples/generated_samples/snippet_metadata_google.cloud.geminidataanalytics.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-geminidataanalytics", - "version": "0.13.0" + "version": "0.13.1" }, "snippets": [ { diff --git a/packages/google-cloud-geminidataanalytics/samples/generated_samples/snippet_metadata_google.cloud.geminidataanalytics.v1alpha.json b/packages/google-cloud-geminidataanalytics/samples/generated_samples/snippet_metadata_google.cloud.geminidataanalytics.v1alpha.json index be6e91358920..c958cd16d92c 100644 --- a/packages/google-cloud-geminidataanalytics/samples/generated_samples/snippet_metadata_google.cloud.geminidataanalytics.v1alpha.json +++ b/packages/google-cloud-geminidataanalytics/samples/generated_samples/snippet_metadata_google.cloud.geminidataanalytics.v1alpha.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-geminidataanalytics", - "version": "0.13.0" + "version": "0.13.1" }, "snippets": [ { diff --git a/packages/google-cloud-geminidataanalytics/samples/generated_samples/snippet_metadata_google.cloud.geminidataanalytics.v1beta.json b/packages/google-cloud-geminidataanalytics/samples/generated_samples/snippet_metadata_google.cloud.geminidataanalytics.v1beta.json index 281c2ae9da22..ec6db044ef0a 100644 --- a/packages/google-cloud-geminidataanalytics/samples/generated_samples/snippet_metadata_google.cloud.geminidataanalytics.v1beta.json +++ b/packages/google-cloud-geminidataanalytics/samples/generated_samples/snippet_metadata_google.cloud.geminidataanalytics.v1beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-geminidataanalytics", - "version": "0.13.0" + "version": "0.13.1" }, "snippets": [ { diff --git a/packages/google-cloud-gke-backup/CHANGELOG.md b/packages/google-cloud-gke-backup/CHANGELOG.md index 2daf58c26439..b738ca2c4229 100644 --- a/packages/google-cloud-gke-backup/CHANGELOG.md +++ b/packages/google-cloud-gke-backup/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-gke-backup/#history +## [0.8.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-gke-backup-v0.8.0...google-cloud-gke-backup-v0.8.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d)) + ## [0.8.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-gke-backup-v0.7.0...google-cloud-gke-backup-v0.8.0) (2026-03-26) diff --git a/packages/google-cloud-gke-backup/google/cloud/gke_backup/gapic_version.py b/packages/google-cloud-gke-backup/google/cloud/gke_backup/gapic_version.py index ed31d4798409..af283a821985 100644 --- a/packages/google-cloud-gke-backup/google/cloud/gke_backup/gapic_version.py +++ b/packages/google-cloud-gke-backup/google/cloud/gke_backup/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.8.0" # {x-release-please-version} +__version__ = "0.8.1" # {x-release-please-version} diff --git a/packages/google-cloud-gke-backup/google/cloud/gke_backup_v1/gapic_version.py b/packages/google-cloud-gke-backup/google/cloud/gke_backup_v1/gapic_version.py index ed31d4798409..af283a821985 100644 --- a/packages/google-cloud-gke-backup/google/cloud/gke_backup_v1/gapic_version.py +++ b/packages/google-cloud-gke-backup/google/cloud/gke_backup_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.8.0" # {x-release-please-version} +__version__ = "0.8.1" # {x-release-please-version} diff --git a/packages/google-cloud-gke-backup/samples/generated_samples/snippet_metadata_google.cloud.gkebackup.v1.json b/packages/google-cloud-gke-backup/samples/generated_samples/snippet_metadata_google.cloud.gkebackup.v1.json index 0a1c5e130956..515e4aa03f20 100644 --- a/packages/google-cloud-gke-backup/samples/generated_samples/snippet_metadata_google.cloud.gkebackup.v1.json +++ b/packages/google-cloud-gke-backup/samples/generated_samples/snippet_metadata_google.cloud.gkebackup.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-gke-backup", - "version": "0.8.0" + "version": "0.8.1" }, "snippets": [ { diff --git a/packages/google-cloud-gke-connect-gateway/CHANGELOG.md b/packages/google-cloud-gke-connect-gateway/CHANGELOG.md index 89d3c69319f4..f6774e018b86 100644 --- a/packages/google-cloud-gke-connect-gateway/CHANGELOG.md +++ b/packages/google-cloud-gke-connect-gateway/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-gke-connect-gateway/#history +## [0.13.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-gke-connect-gateway-v0.13.0...google-cloud-gke-connect-gateway-v0.13.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d)) + ## [0.13.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-gke-connect-gateway-v0.12.0...google-cloud-gke-connect-gateway-v0.13.0) (2026-03-26) diff --git a/packages/google-cloud-gke-connect-gateway/google/cloud/gkeconnect/gateway/gapic_version.py b/packages/google-cloud-gke-connect-gateway/google/cloud/gkeconnect/gateway/gapic_version.py index dcda7097daa0..9847b33bcb50 100644 --- a/packages/google-cloud-gke-connect-gateway/google/cloud/gkeconnect/gateway/gapic_version.py +++ b/packages/google-cloud-gke-connect-gateway/google/cloud/gkeconnect/gateway/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.13.0" # {x-release-please-version} +__version__ = "0.13.1" # {x-release-please-version} diff --git a/packages/google-cloud-gke-connect-gateway/google/cloud/gkeconnect/gateway_v1/gapic_version.py b/packages/google-cloud-gke-connect-gateway/google/cloud/gkeconnect/gateway_v1/gapic_version.py index dcda7097daa0..9847b33bcb50 100644 --- a/packages/google-cloud-gke-connect-gateway/google/cloud/gkeconnect/gateway_v1/gapic_version.py +++ b/packages/google-cloud-gke-connect-gateway/google/cloud/gkeconnect/gateway_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.13.0" # {x-release-please-version} +__version__ = "0.13.1" # {x-release-please-version} diff --git a/packages/google-cloud-gke-connect-gateway/google/cloud/gkeconnect/gateway_v1beta1/gapic_version.py b/packages/google-cloud-gke-connect-gateway/google/cloud/gkeconnect/gateway_v1beta1/gapic_version.py index dcda7097daa0..9847b33bcb50 100644 --- a/packages/google-cloud-gke-connect-gateway/google/cloud/gkeconnect/gateway_v1beta1/gapic_version.py +++ b/packages/google-cloud-gke-connect-gateway/google/cloud/gkeconnect/gateway_v1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.13.0" # {x-release-please-version} +__version__ = "0.13.1" # {x-release-please-version} diff --git a/packages/google-cloud-gke-connect-gateway/samples/generated_samples/snippet_metadata_google.cloud.gkeconnect.gateway.v1.json b/packages/google-cloud-gke-connect-gateway/samples/generated_samples/snippet_metadata_google.cloud.gkeconnect.gateway.v1.json index 3cf29f0acb34..9c1ec612c20a 100644 --- a/packages/google-cloud-gke-connect-gateway/samples/generated_samples/snippet_metadata_google.cloud.gkeconnect.gateway.v1.json +++ b/packages/google-cloud-gke-connect-gateway/samples/generated_samples/snippet_metadata_google.cloud.gkeconnect.gateway.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-gke-connect-gateway", - "version": "0.13.0" + "version": "0.13.1" }, "snippets": [ { diff --git a/packages/google-cloud-gke-connect-gateway/samples/generated_samples/snippet_metadata_google.cloud.gkeconnect.gateway.v1beta1.json b/packages/google-cloud-gke-connect-gateway/samples/generated_samples/snippet_metadata_google.cloud.gkeconnect.gateway.v1beta1.json index 3303118729dd..d7a060f6570a 100644 --- a/packages/google-cloud-gke-connect-gateway/samples/generated_samples/snippet_metadata_google.cloud.gkeconnect.gateway.v1beta1.json +++ b/packages/google-cloud-gke-connect-gateway/samples/generated_samples/snippet_metadata_google.cloud.gkeconnect.gateway.v1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-gke-connect-gateway", - "version": "0.13.0" + "version": "0.13.1" }, "snippets": [ { diff --git a/packages/google-cloud-gke-hub/CHANGELOG.md b/packages/google-cloud-gke-hub/CHANGELOG.md index e45a17e4b916..d604205f62a3 100644 --- a/packages/google-cloud-gke-hub/CHANGELOG.md +++ b/packages/google-cloud-gke-hub/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-gke-hub/#history +## [1.25.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-gke-hub-v1.24.0...google-cloud-gke-hub-v1.25.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d)) + ## [1.24.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-gke-hub-v1.23.0...google-cloud-gke-hub-v1.24.0) (2026-05-06) ## [1.23.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-gke-hub-v1.22.0...google-cloud-gke-hub-v1.23.0) (2026-03-26) diff --git a/packages/google-cloud-gke-hub/google/cloud/gkehub/gapic_version.py b/packages/google-cloud-gke-hub/google/cloud/gkehub/gapic_version.py index c8ec013ce4bb..9d830c39e17b 100644 --- a/packages/google-cloud-gke-hub/google/cloud/gkehub/gapic_version.py +++ b/packages/google-cloud-gke-hub/google/cloud/gkehub/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.24.0" # {x-release-please-version} +__version__ = "1.25.0" # {x-release-please-version} diff --git a/packages/google-cloud-gke-hub/google/cloud/gkehub_v1/configmanagement_v1/gapic_version.py b/packages/google-cloud-gke-hub/google/cloud/gkehub_v1/configmanagement_v1/gapic_version.py index aeb4f7e443b2..74be05febb8c 100644 --- a/packages/google-cloud-gke-hub/google/cloud/gkehub_v1/configmanagement_v1/gapic_version.py +++ b/packages/google-cloud-gke-hub/google/cloud/gkehub_v1/configmanagement_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.24.0" # {x-release-please-version} +__version__ = "1.25.0" # {x-release-please-version} diff --git a/packages/google-cloud-gke-hub/google/cloud/gkehub_v1/gapic_version.py b/packages/google-cloud-gke-hub/google/cloud/gkehub_v1/gapic_version.py index c8ec013ce4bb..9d830c39e17b 100644 --- a/packages/google-cloud-gke-hub/google/cloud/gkehub_v1/gapic_version.py +++ b/packages/google-cloud-gke-hub/google/cloud/gkehub_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.24.0" # {x-release-please-version} +__version__ = "1.25.0" # {x-release-please-version} diff --git a/packages/google-cloud-gke-hub/google/cloud/gkehub_v1/multiclusteringress_v1/gapic_version.py b/packages/google-cloud-gke-hub/google/cloud/gkehub_v1/multiclusteringress_v1/gapic_version.py index aeb4f7e443b2..74be05febb8c 100644 --- a/packages/google-cloud-gke-hub/google/cloud/gkehub_v1/multiclusteringress_v1/gapic_version.py +++ b/packages/google-cloud-gke-hub/google/cloud/gkehub_v1/multiclusteringress_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.24.0" # {x-release-please-version} +__version__ = "1.25.0" # {x-release-please-version} diff --git a/packages/google-cloud-gke-hub/google/cloud/gkehub_v1/rbacrolebindingactuation_v1/gapic_version.py b/packages/google-cloud-gke-hub/google/cloud/gkehub_v1/rbacrolebindingactuation_v1/gapic_version.py index aeb4f7e443b2..74be05febb8c 100644 --- a/packages/google-cloud-gke-hub/google/cloud/gkehub_v1/rbacrolebindingactuation_v1/gapic_version.py +++ b/packages/google-cloud-gke-hub/google/cloud/gkehub_v1/rbacrolebindingactuation_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.24.0" # {x-release-please-version} +__version__ = "1.25.0" # {x-release-please-version} diff --git a/packages/google-cloud-gke-hub/google/cloud/gkehub_v1beta1/gapic_version.py b/packages/google-cloud-gke-hub/google/cloud/gkehub_v1beta1/gapic_version.py index c8ec013ce4bb..9d830c39e17b 100644 --- a/packages/google-cloud-gke-hub/google/cloud/gkehub_v1beta1/gapic_version.py +++ b/packages/google-cloud-gke-hub/google/cloud/gkehub_v1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.24.0" # {x-release-please-version} +__version__ = "1.25.0" # {x-release-please-version} diff --git a/packages/google-cloud-gke-hub/samples/generated_samples/snippet_metadata_google.cloud.gkehub.v1.json b/packages/google-cloud-gke-hub/samples/generated_samples/snippet_metadata_google.cloud.gkehub.v1.json index ae7730e43a12..a88f95297a5e 100644 --- a/packages/google-cloud-gke-hub/samples/generated_samples/snippet_metadata_google.cloud.gkehub.v1.json +++ b/packages/google-cloud-gke-hub/samples/generated_samples/snippet_metadata_google.cloud.gkehub.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-gke-hub", - "version": "1.24.0" + "version": "1.25.0" }, "snippets": [ { diff --git a/packages/google-cloud-gke-hub/samples/generated_samples/snippet_metadata_google.cloud.gkehub.v1beta1.json b/packages/google-cloud-gke-hub/samples/generated_samples/snippet_metadata_google.cloud.gkehub.v1beta1.json index 103be13af9d0..6daf31d16340 100644 --- a/packages/google-cloud-gke-hub/samples/generated_samples/snippet_metadata_google.cloud.gkehub.v1beta1.json +++ b/packages/google-cloud-gke-hub/samples/generated_samples/snippet_metadata_google.cloud.gkehub.v1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-gke-hub", - "version": "1.24.0" + "version": "1.25.0" }, "snippets": [ { diff --git a/packages/google-cloud-gke-multicloud/CHANGELOG.md b/packages/google-cloud-gke-multicloud/CHANGELOG.md index 947b86c47863..a3875fe6a600 100644 --- a/packages/google-cloud-gke-multicloud/CHANGELOG.md +++ b/packages/google-cloud-gke-multicloud/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-gke-multicloud/#history +## [0.9.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-gke-multicloud-v0.9.0...google-cloud-gke-multicloud-v0.9.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d)) + ## [0.9.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-gke-multicloud-v0.8.0...google-cloud-gke-multicloud-v0.9.0) (2026-03-26) diff --git a/packages/google-cloud-gke-multicloud/google/cloud/gke_multicloud/gapic_version.py b/packages/google-cloud-gke-multicloud/google/cloud/gke_multicloud/gapic_version.py index 1a69f86a509b..cb1b694572dc 100644 --- a/packages/google-cloud-gke-multicloud/google/cloud/gke_multicloud/gapic_version.py +++ b/packages/google-cloud-gke-multicloud/google/cloud/gke_multicloud/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.9.0" # {x-release-please-version} +__version__ = "0.9.1" # {x-release-please-version} diff --git a/packages/google-cloud-gke-multicloud/google/cloud/gke_multicloud_v1/gapic_version.py b/packages/google-cloud-gke-multicloud/google/cloud/gke_multicloud_v1/gapic_version.py index 1a69f86a509b..cb1b694572dc 100644 --- a/packages/google-cloud-gke-multicloud/google/cloud/gke_multicloud_v1/gapic_version.py +++ b/packages/google-cloud-gke-multicloud/google/cloud/gke_multicloud_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.9.0" # {x-release-please-version} +__version__ = "0.9.1" # {x-release-please-version} diff --git a/packages/google-cloud-gke-multicloud/samples/generated_samples/snippet_metadata_google.cloud.gkemulticloud.v1.json b/packages/google-cloud-gke-multicloud/samples/generated_samples/snippet_metadata_google.cloud.gkemulticloud.v1.json index bed920fd73f6..a8eb6f9762cb 100644 --- a/packages/google-cloud-gke-multicloud/samples/generated_samples/snippet_metadata_google.cloud.gkemulticloud.v1.json +++ b/packages/google-cloud-gke-multicloud/samples/generated_samples/snippet_metadata_google.cloud.gkemulticloud.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-gke-multicloud", - "version": "0.9.0" + "version": "0.9.1" }, "snippets": [ { diff --git a/packages/google-cloud-gkerecommender/CHANGELOG.md b/packages/google-cloud-gkerecommender/CHANGELOG.md index 97fee638ca76..145cd88cb44d 100644 --- a/packages/google-cloud-gkerecommender/CHANGELOG.md +++ b/packages/google-cloud-gkerecommender/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-gkerecommender/#history +## [0.3.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-gkerecommender-v0.3.0...google-cloud-gkerecommender-v0.3.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d)) + ## [0.3.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-gkerecommender-v0.2.0...google-cloud-gkerecommender-v0.3.0) (2026-03-26) diff --git a/packages/google-cloud-gkerecommender/google/cloud/gkerecommender/gapic_version.py b/packages/google-cloud-gkerecommender/google/cloud/gkerecommender/gapic_version.py index fba6783b6045..d88d0511755e 100644 --- a/packages/google-cloud-gkerecommender/google/cloud/gkerecommender/gapic_version.py +++ b/packages/google-cloud-gkerecommender/google/cloud/gkerecommender/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.3.0" # {x-release-please-version} +__version__ = "0.3.1" # {x-release-please-version} diff --git a/packages/google-cloud-gkerecommender/google/cloud/gkerecommender_v1/gapic_version.py b/packages/google-cloud-gkerecommender/google/cloud/gkerecommender_v1/gapic_version.py index fba6783b6045..d88d0511755e 100644 --- a/packages/google-cloud-gkerecommender/google/cloud/gkerecommender_v1/gapic_version.py +++ b/packages/google-cloud-gkerecommender/google/cloud/gkerecommender_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.3.0" # {x-release-please-version} +__version__ = "0.3.1" # {x-release-please-version} diff --git a/packages/google-cloud-gkerecommender/samples/generated_samples/snippet_metadata_google.cloud.gkerecommender.v1.json b/packages/google-cloud-gkerecommender/samples/generated_samples/snippet_metadata_google.cloud.gkerecommender.v1.json index c128178778fe..90682db51690 100644 --- a/packages/google-cloud-gkerecommender/samples/generated_samples/snippet_metadata_google.cloud.gkerecommender.v1.json +++ b/packages/google-cloud-gkerecommender/samples/generated_samples/snippet_metadata_google.cloud.gkerecommender.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-gkerecommender", - "version": "0.3.0" + "version": "0.3.1" }, "snippets": [ { diff --git a/packages/google-cloud-gsuiteaddons/CHANGELOG.md b/packages/google-cloud-gsuiteaddons/CHANGELOG.md index c942695479b7..bf36cde5cc0a 100644 --- a/packages/google-cloud-gsuiteaddons/CHANGELOG.md +++ b/packages/google-cloud-gsuiteaddons/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-gsuiteaddons/#history +## [0.5.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-gsuiteaddons-v0.5.0...google-cloud-gsuiteaddons-v0.5.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d)) + ## [0.5.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-gsuiteaddons-v0.4.0...google-cloud-gsuiteaddons-v0.5.0) (2026-03-26) diff --git a/packages/google-cloud-gsuiteaddons/google/cloud/gsuiteaddons/gapic_version.py b/packages/google-cloud-gsuiteaddons/google/cloud/gsuiteaddons/gapic_version.py index 7d9863d19611..acc458e7fa6f 100644 --- a/packages/google-cloud-gsuiteaddons/google/cloud/gsuiteaddons/gapic_version.py +++ b/packages/google-cloud-gsuiteaddons/google/cloud/gsuiteaddons/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.5.0" # {x-release-please-version} +__version__ = "0.5.1" # {x-release-please-version} diff --git a/packages/google-cloud-gsuiteaddons/google/cloud/gsuiteaddons_v1/gapic_version.py b/packages/google-cloud-gsuiteaddons/google/cloud/gsuiteaddons_v1/gapic_version.py index 7d9863d19611..acc458e7fa6f 100644 --- a/packages/google-cloud-gsuiteaddons/google/cloud/gsuiteaddons_v1/gapic_version.py +++ b/packages/google-cloud-gsuiteaddons/google/cloud/gsuiteaddons_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.5.0" # {x-release-please-version} +__version__ = "0.5.1" # {x-release-please-version} diff --git a/packages/google-cloud-gsuiteaddons/samples/generated_samples/snippet_metadata_google.cloud.gsuiteaddons.v1.json b/packages/google-cloud-gsuiteaddons/samples/generated_samples/snippet_metadata_google.cloud.gsuiteaddons.v1.json index 929d54cfd3ca..77927f127d78 100644 --- a/packages/google-cloud-gsuiteaddons/samples/generated_samples/snippet_metadata_google.cloud.gsuiteaddons.v1.json +++ b/packages/google-cloud-gsuiteaddons/samples/generated_samples/snippet_metadata_google.cloud.gsuiteaddons.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-gsuiteaddons", - "version": "0.5.0" + "version": "0.5.1" }, "snippets": [ { diff --git a/packages/google-cloud-hypercomputecluster/CHANGELOG.md b/packages/google-cloud-hypercomputecluster/CHANGELOG.md index 7abc23d04c4d..16f990705b06 100644 --- a/packages/google-cloud-hypercomputecluster/CHANGELOG.md +++ b/packages/google-cloud-hypercomputecluster/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-hypercomputecluster/#history +## [0.4.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-hypercomputecluster-v0.4.0...google-cloud-hypercomputecluster-v0.4.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d)) + ## [0.4.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-hypercomputecluster-v0.3.0...google-cloud-hypercomputecluster-v0.4.0) (2026-03-26) diff --git a/packages/google-cloud-hypercomputecluster/google/cloud/hypercomputecluster/gapic_version.py b/packages/google-cloud-hypercomputecluster/google/cloud/hypercomputecluster/gapic_version.py index 7a26901aff5b..7de1cf9e096e 100644 --- a/packages/google-cloud-hypercomputecluster/google/cloud/hypercomputecluster/gapic_version.py +++ b/packages/google-cloud-hypercomputecluster/google/cloud/hypercomputecluster/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.4.1" # {x-release-please-version} diff --git a/packages/google-cloud-hypercomputecluster/google/cloud/hypercomputecluster_v1/gapic_version.py b/packages/google-cloud-hypercomputecluster/google/cloud/hypercomputecluster_v1/gapic_version.py index 7a26901aff5b..7de1cf9e096e 100644 --- a/packages/google-cloud-hypercomputecluster/google/cloud/hypercomputecluster_v1/gapic_version.py +++ b/packages/google-cloud-hypercomputecluster/google/cloud/hypercomputecluster_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.4.1" # {x-release-please-version} diff --git a/packages/google-cloud-hypercomputecluster/google/cloud/hypercomputecluster_v1beta/gapic_version.py b/packages/google-cloud-hypercomputecluster/google/cloud/hypercomputecluster_v1beta/gapic_version.py index 7a26901aff5b..7de1cf9e096e 100644 --- a/packages/google-cloud-hypercomputecluster/google/cloud/hypercomputecluster_v1beta/gapic_version.py +++ b/packages/google-cloud-hypercomputecluster/google/cloud/hypercomputecluster_v1beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.4.1" # {x-release-please-version} diff --git a/packages/google-cloud-hypercomputecluster/samples/generated_samples/snippet_metadata_google.cloud.hypercomputecluster.v1.json b/packages/google-cloud-hypercomputecluster/samples/generated_samples/snippet_metadata_google.cloud.hypercomputecluster.v1.json index 4fb27b511bd9..7288d3303722 100644 --- a/packages/google-cloud-hypercomputecluster/samples/generated_samples/snippet_metadata_google.cloud.hypercomputecluster.v1.json +++ b/packages/google-cloud-hypercomputecluster/samples/generated_samples/snippet_metadata_google.cloud.hypercomputecluster.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-hypercomputecluster", - "version": "0.4.0" + "version": "0.4.1" }, "snippets": [ { diff --git a/packages/google-cloud-hypercomputecluster/samples/generated_samples/snippet_metadata_google.cloud.hypercomputecluster.v1beta.json b/packages/google-cloud-hypercomputecluster/samples/generated_samples/snippet_metadata_google.cloud.hypercomputecluster.v1beta.json index 514cbacd683b..d46355b5bf42 100644 --- a/packages/google-cloud-hypercomputecluster/samples/generated_samples/snippet_metadata_google.cloud.hypercomputecluster.v1beta.json +++ b/packages/google-cloud-hypercomputecluster/samples/generated_samples/snippet_metadata_google.cloud.hypercomputecluster.v1beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-hypercomputecluster", - "version": "0.4.0" + "version": "0.4.1" }, "snippets": [ { diff --git a/packages/google-cloud-iam-logging/CHANGELOG.md b/packages/google-cloud-iam-logging/CHANGELOG.md index 2ef0a9e55644..35d1c15dd7de 100644 --- a/packages/google-cloud-iam-logging/CHANGELOG.md +++ b/packages/google-cloud-iam-logging/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-iam-logging/#history +## [1.8.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-iam-logging-v1.7.0...google-cloud-iam-logging-v1.8.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d)) + ## [1.7.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-iam-logging-v1.6.0...google-cloud-iam-logging-v1.7.0) (2026-03-26) diff --git a/packages/google-cloud-iam-logging/google/cloud/iam_logging/gapic_version.py b/packages/google-cloud-iam-logging/google/cloud/iam_logging/gapic_version.py index 644ae49cc207..8ea33c949199 100644 --- a/packages/google-cloud-iam-logging/google/cloud/iam_logging/gapic_version.py +++ b/packages/google-cloud-iam-logging/google/cloud/iam_logging/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.7.0" # {x-release-please-version} +__version__ = "1.8.0" # {x-release-please-version} diff --git a/packages/google-cloud-iam-logging/google/cloud/iam_logging_v1/gapic_version.py b/packages/google-cloud-iam-logging/google/cloud/iam_logging_v1/gapic_version.py index 644ae49cc207..8ea33c949199 100644 --- a/packages/google-cloud-iam-logging/google/cloud/iam_logging_v1/gapic_version.py +++ b/packages/google-cloud-iam-logging/google/cloud/iam_logging_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.7.0" # {x-release-please-version} +__version__ = "1.8.0" # {x-release-please-version} diff --git a/packages/google-cloud-iam/CHANGELOG.md b/packages/google-cloud-iam/CHANGELOG.md index e381fcc770c3..4ae57bc6b9cd 100644 --- a/packages/google-cloud-iam/CHANGELOG.md +++ b/packages/google-cloud-iam/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-iam/#history +## [2.24.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-iam-v2.23.0...google-cloud-iam-v2.24.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d)) + ## [2.23.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-iam-v2.22.0...google-cloud-iam-v2.23.0) (2026-05-06) ## [2.22.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-iam-v2.21.0...google-cloud-iam-v2.22.0) (2026-03-26) diff --git a/packages/google-cloud-iam/google/cloud/iam/gapic_version.py b/packages/google-cloud-iam/google/cloud/iam/gapic_version.py index d01518ddd752..dc3478371d83 100644 --- a/packages/google-cloud-iam/google/cloud/iam/gapic_version.py +++ b/packages/google-cloud-iam/google/cloud/iam/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.23.0" # {x-release-please-version} +__version__ = "2.24.0" # {x-release-please-version} diff --git a/packages/google-cloud-iam/google/cloud/iam_admin/gapic_version.py b/packages/google-cloud-iam/google/cloud/iam_admin/gapic_version.py index d01518ddd752..dc3478371d83 100644 --- a/packages/google-cloud-iam/google/cloud/iam_admin/gapic_version.py +++ b/packages/google-cloud-iam/google/cloud/iam_admin/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.23.0" # {x-release-please-version} +__version__ = "2.24.0" # {x-release-please-version} diff --git a/packages/google-cloud-iam/google/cloud/iam_admin_v1/gapic_version.py b/packages/google-cloud-iam/google/cloud/iam_admin_v1/gapic_version.py index d01518ddd752..dc3478371d83 100644 --- a/packages/google-cloud-iam/google/cloud/iam_admin_v1/gapic_version.py +++ b/packages/google-cloud-iam/google/cloud/iam_admin_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.23.0" # {x-release-please-version} +__version__ = "2.24.0" # {x-release-please-version} diff --git a/packages/google-cloud-iam/google/cloud/iam_credentials/gapic_version.py b/packages/google-cloud-iam/google/cloud/iam_credentials/gapic_version.py index d01518ddd752..dc3478371d83 100644 --- a/packages/google-cloud-iam/google/cloud/iam_credentials/gapic_version.py +++ b/packages/google-cloud-iam/google/cloud/iam_credentials/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.23.0" # {x-release-please-version} +__version__ = "2.24.0" # {x-release-please-version} diff --git a/packages/google-cloud-iam/google/cloud/iam_credentials_v1/gapic_version.py b/packages/google-cloud-iam/google/cloud/iam_credentials_v1/gapic_version.py index d01518ddd752..dc3478371d83 100644 --- a/packages/google-cloud-iam/google/cloud/iam_credentials_v1/gapic_version.py +++ b/packages/google-cloud-iam/google/cloud/iam_credentials_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.23.0" # {x-release-please-version} +__version__ = "2.24.0" # {x-release-please-version} diff --git a/packages/google-cloud-iam/google/cloud/iam_v2/gapic_version.py b/packages/google-cloud-iam/google/cloud/iam_v2/gapic_version.py index d01518ddd752..dc3478371d83 100644 --- a/packages/google-cloud-iam/google/cloud/iam_v2/gapic_version.py +++ b/packages/google-cloud-iam/google/cloud/iam_v2/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.23.0" # {x-release-please-version} +__version__ = "2.24.0" # {x-release-please-version} diff --git a/packages/google-cloud-iam/google/cloud/iam_v2beta/gapic_version.py b/packages/google-cloud-iam/google/cloud/iam_v2beta/gapic_version.py index d01518ddd752..dc3478371d83 100644 --- a/packages/google-cloud-iam/google/cloud/iam_v2beta/gapic_version.py +++ b/packages/google-cloud-iam/google/cloud/iam_v2beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.23.0" # {x-release-please-version} +__version__ = "2.24.0" # {x-release-please-version} diff --git a/packages/google-cloud-iam/google/cloud/iam_v3/gapic_version.py b/packages/google-cloud-iam/google/cloud/iam_v3/gapic_version.py index d01518ddd752..dc3478371d83 100644 --- a/packages/google-cloud-iam/google/cloud/iam_v3/gapic_version.py +++ b/packages/google-cloud-iam/google/cloud/iam_v3/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.23.0" # {x-release-please-version} +__version__ = "2.24.0" # {x-release-please-version} diff --git a/packages/google-cloud-iam/google/cloud/iam_v3beta/gapic_version.py b/packages/google-cloud-iam/google/cloud/iam_v3beta/gapic_version.py index d01518ddd752..dc3478371d83 100644 --- a/packages/google-cloud-iam/google/cloud/iam_v3beta/gapic_version.py +++ b/packages/google-cloud-iam/google/cloud/iam_v3beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.23.0" # {x-release-please-version} +__version__ = "2.24.0" # {x-release-please-version} diff --git a/packages/google-cloud-iam/samples/generated_samples/snippet_metadata_google.iam.admin.v1.json b/packages/google-cloud-iam/samples/generated_samples/snippet_metadata_google.iam.admin.v1.json index 331633bf42d4..3f4490d8ad56 100644 --- a/packages/google-cloud-iam/samples/generated_samples/snippet_metadata_google.iam.admin.v1.json +++ b/packages/google-cloud-iam/samples/generated_samples/snippet_metadata_google.iam.admin.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-iam", - "version": "2.23.0" + "version": "2.24.0" }, "snippets": [ { diff --git a/packages/google-cloud-iam/samples/generated_samples/snippet_metadata_google.iam.credentials.v1.json b/packages/google-cloud-iam/samples/generated_samples/snippet_metadata_google.iam.credentials.v1.json index 568d62db5115..163becf96a9a 100644 --- a/packages/google-cloud-iam/samples/generated_samples/snippet_metadata_google.iam.credentials.v1.json +++ b/packages/google-cloud-iam/samples/generated_samples/snippet_metadata_google.iam.credentials.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-iam", - "version": "2.23.0" + "version": "2.24.0" }, "snippets": [ { diff --git a/packages/google-cloud-iam/samples/generated_samples/snippet_metadata_google.iam.v2.json b/packages/google-cloud-iam/samples/generated_samples/snippet_metadata_google.iam.v2.json index b44756253071..1f3eb42f6ddd 100644 --- a/packages/google-cloud-iam/samples/generated_samples/snippet_metadata_google.iam.v2.json +++ b/packages/google-cloud-iam/samples/generated_samples/snippet_metadata_google.iam.v2.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-iam", - "version": "2.23.0" + "version": "2.24.0" }, "snippets": [ { diff --git a/packages/google-cloud-iam/samples/generated_samples/snippet_metadata_google.iam.v2beta.json b/packages/google-cloud-iam/samples/generated_samples/snippet_metadata_google.iam.v2beta.json index 782dbb1cb8ba..7e06bb5e884c 100644 --- a/packages/google-cloud-iam/samples/generated_samples/snippet_metadata_google.iam.v2beta.json +++ b/packages/google-cloud-iam/samples/generated_samples/snippet_metadata_google.iam.v2beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-iam", - "version": "2.23.0" + "version": "2.24.0" }, "snippets": [ { diff --git a/packages/google-cloud-iam/samples/generated_samples/snippet_metadata_google.iam.v3.json b/packages/google-cloud-iam/samples/generated_samples/snippet_metadata_google.iam.v3.json index 3f09a044d7dd..1a2245b7c05a 100644 --- a/packages/google-cloud-iam/samples/generated_samples/snippet_metadata_google.iam.v3.json +++ b/packages/google-cloud-iam/samples/generated_samples/snippet_metadata_google.iam.v3.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-iam", - "version": "2.23.0" + "version": "2.24.0" }, "snippets": [ { diff --git a/packages/google-cloud-iam/samples/generated_samples/snippet_metadata_google.iam.v3beta.json b/packages/google-cloud-iam/samples/generated_samples/snippet_metadata_google.iam.v3beta.json index e0e2f676d4ea..09eb0445a715 100644 --- a/packages/google-cloud-iam/samples/generated_samples/snippet_metadata_google.iam.v3beta.json +++ b/packages/google-cloud-iam/samples/generated_samples/snippet_metadata_google.iam.v3beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-iam", - "version": "2.23.0" + "version": "2.24.0" }, "snippets": [ { diff --git a/packages/google-cloud-iamconnectorcredentials/CHANGELOG.md b/packages/google-cloud-iamconnectorcredentials/CHANGELOG.md index 1000e2dbcd71..fac1bcde4b5e 100644 --- a/packages/google-cloud-iamconnectorcredentials/CHANGELOG.md +++ b/packages/google-cloud-iamconnectorcredentials/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-iamconnectorcredentials/#history +## [0.1.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-iamconnectorcredentials-v0.1.0...google-cloud-iamconnectorcredentials-v0.1.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d)) + ## [0.1.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-iamconnectorcredentials-v0.0.0...google-cloud-iamconnectorcredentials-v0.1.0) (2026-04-09) diff --git a/packages/google-cloud-iamconnectorcredentials/google/cloud/iamconnectorcredentials/gapic_version.py b/packages/google-cloud-iamconnectorcredentials/google/cloud/iamconnectorcredentials/gapic_version.py index 075b8773ece3..af1f9abf2bb8 100644 --- a/packages/google-cloud-iamconnectorcredentials/google/cloud/iamconnectorcredentials/gapic_version.py +++ b/packages/google-cloud-iamconnectorcredentials/google/cloud/iamconnectorcredentials/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.0" # {x-release-please-version} +__version__ = "0.1.1" # {x-release-please-version} diff --git a/packages/google-cloud-iamconnectorcredentials/google/cloud/iamconnectorcredentials_v1alpha/gapic_version.py b/packages/google-cloud-iamconnectorcredentials/google/cloud/iamconnectorcredentials_v1alpha/gapic_version.py index 075b8773ece3..af1f9abf2bb8 100644 --- a/packages/google-cloud-iamconnectorcredentials/google/cloud/iamconnectorcredentials_v1alpha/gapic_version.py +++ b/packages/google-cloud-iamconnectorcredentials/google/cloud/iamconnectorcredentials_v1alpha/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.0" # {x-release-please-version} +__version__ = "0.1.1" # {x-release-please-version} diff --git a/packages/google-cloud-iamconnectorcredentials/samples/generated_samples/snippet_metadata_google.cloud.iamconnectorcredentials.v1alpha.json b/packages/google-cloud-iamconnectorcredentials/samples/generated_samples/snippet_metadata_google.cloud.iamconnectorcredentials.v1alpha.json index a5b2fe7dcc6f..f7de29844475 100644 --- a/packages/google-cloud-iamconnectorcredentials/samples/generated_samples/snippet_metadata_google.cloud.iamconnectorcredentials.v1alpha.json +++ b/packages/google-cloud-iamconnectorcredentials/samples/generated_samples/snippet_metadata_google.cloud.iamconnectorcredentials.v1alpha.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-iamconnectorcredentials", - "version": "0.1.0" + "version": "0.1.1" }, "snippets": [ { diff --git a/packages/google-cloud-iap/CHANGELOG.md b/packages/google-cloud-iap/CHANGELOG.md index a28b4db86a8f..21c6c6e266af 100644 --- a/packages/google-cloud-iap/CHANGELOG.md +++ b/packages/google-cloud-iap/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-iap/#history +## [1.22.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-iap-v1.21.0...google-cloud-iap-v1.22.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d)) + ## [1.21.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-iap-v1.20.0...google-cloud-iap-v1.21.0) (2026-03-26) diff --git a/packages/google-cloud-iap/google/cloud/iap/gapic_version.py b/packages/google-cloud-iap/google/cloud/iap/gapic_version.py index 95884592d2da..a2e7c5e892a1 100644 --- a/packages/google-cloud-iap/google/cloud/iap/gapic_version.py +++ b/packages/google-cloud-iap/google/cloud/iap/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.21.0" # {x-release-please-version} +__version__ = "1.22.0" # {x-release-please-version} diff --git a/packages/google-cloud-iap/google/cloud/iap_v1/gapic_version.py b/packages/google-cloud-iap/google/cloud/iap_v1/gapic_version.py index 95884592d2da..a2e7c5e892a1 100644 --- a/packages/google-cloud-iap/google/cloud/iap_v1/gapic_version.py +++ b/packages/google-cloud-iap/google/cloud/iap_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.21.0" # {x-release-please-version} +__version__ = "1.22.0" # {x-release-please-version} diff --git a/packages/google-cloud-iap/samples/generated_samples/snippet_metadata_google.cloud.iap.v1.json b/packages/google-cloud-iap/samples/generated_samples/snippet_metadata_google.cloud.iap.v1.json index 2a79f96da8c3..7dcb89f4529b 100644 --- a/packages/google-cloud-iap/samples/generated_samples/snippet_metadata_google.cloud.iap.v1.json +++ b/packages/google-cloud-iap/samples/generated_samples/snippet_metadata_google.cloud.iap.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-iap", - "version": "1.21.0" + "version": "1.22.0" }, "snippets": [ { diff --git a/packages/google-cloud-ids/CHANGELOG.md b/packages/google-cloud-ids/CHANGELOG.md index 3e627b9a49fe..2a67983e1b1f 100644 --- a/packages/google-cloud-ids/CHANGELOG.md +++ b/packages/google-cloud-ids/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-ids/#history +## [1.14.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-ids-v1.13.0...google-cloud-ids-v1.14.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[e-i] packages ([#17079](https://github.com/googleapis/google-cloud-python/issues/17079)) ([5239b18](https://github.com/googleapis/google-cloud-python/commit/5239b1814f216676bf02dea08726313ad355439d)) + ## [1.13.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-ids-v1.12.0...google-cloud-ids-v1.13.0) (2026-03-26) diff --git a/packages/google-cloud-ids/google/cloud/ids/gapic_version.py b/packages/google-cloud-ids/google/cloud/ids/gapic_version.py index 66da8b1d1133..da4b0a9cf041 100644 --- a/packages/google-cloud-ids/google/cloud/ids/gapic_version.py +++ b/packages/google-cloud-ids/google/cloud/ids/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.13.0" # {x-release-please-version} +__version__ = "1.14.0" # {x-release-please-version} diff --git a/packages/google-cloud-ids/google/cloud/ids_v1/gapic_version.py b/packages/google-cloud-ids/google/cloud/ids_v1/gapic_version.py index 66da8b1d1133..da4b0a9cf041 100644 --- a/packages/google-cloud-ids/google/cloud/ids_v1/gapic_version.py +++ b/packages/google-cloud-ids/google/cloud/ids_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.13.0" # {x-release-please-version} +__version__ = "1.14.0" # {x-release-please-version} diff --git a/packages/google-cloud-ids/samples/generated_samples/snippet_metadata_google.cloud.ids.v1.json b/packages/google-cloud-ids/samples/generated_samples/snippet_metadata_google.cloud.ids.v1.json index e115a7a0f4a0..968ead94444e 100644 --- a/packages/google-cloud-ids/samples/generated_samples/snippet_metadata_google.cloud.ids.v1.json +++ b/packages/google-cloud-ids/samples/generated_samples/snippet_metadata_google.cloud.ids.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-ids", - "version": "1.13.0" + "version": "1.14.0" }, "snippets": [ { diff --git a/packages/google-cloud-kms-inventory/CHANGELOG.md b/packages/google-cloud-kms-inventory/CHANGELOG.md index 90fad72784f3..8bf5932868d0 100644 --- a/packages/google-cloud-kms-inventory/CHANGELOG.md +++ b/packages/google-cloud-kms-inventory/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-kms-inventory/#history +## [0.6.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-kms-inventory-v0.6.0...google-cloud-kms-inventory-v0.6.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85)) + ## [0.6.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-kms-inventory-v0.5.0...google-cloud-kms-inventory-v0.6.0) (2026-03-26) diff --git a/packages/google-cloud-kms-inventory/google/cloud/kms_inventory/gapic_version.py b/packages/google-cloud-kms-inventory/google/cloud/kms_inventory/gapic_version.py index 916d95dd4eda..4c89af3224e4 100644 --- a/packages/google-cloud-kms-inventory/google/cloud/kms_inventory/gapic_version.py +++ b/packages/google-cloud-kms-inventory/google/cloud/kms_inventory/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.6.0" # {x-release-please-version} +__version__ = "0.6.1" # {x-release-please-version} diff --git a/packages/google-cloud-kms-inventory/google/cloud/kms_inventory_v1/gapic_version.py b/packages/google-cloud-kms-inventory/google/cloud/kms_inventory_v1/gapic_version.py index 916d95dd4eda..4c89af3224e4 100644 --- a/packages/google-cloud-kms-inventory/google/cloud/kms_inventory_v1/gapic_version.py +++ b/packages/google-cloud-kms-inventory/google/cloud/kms_inventory_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.6.0" # {x-release-please-version} +__version__ = "0.6.1" # {x-release-please-version} diff --git a/packages/google-cloud-kms-inventory/samples/generated_samples/snippet_metadata_google.cloud.kms.inventory.v1.json b/packages/google-cloud-kms-inventory/samples/generated_samples/snippet_metadata_google.cloud.kms.inventory.v1.json index 7d630eda52ea..d0e8234553b4 100644 --- a/packages/google-cloud-kms-inventory/samples/generated_samples/snippet_metadata_google.cloud.kms.inventory.v1.json +++ b/packages/google-cloud-kms-inventory/samples/generated_samples/snippet_metadata_google.cloud.kms.inventory.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-kms-inventory", - "version": "0.6.0" + "version": "0.6.1" }, "snippets": [ { diff --git a/packages/google-cloud-kms/CHANGELOG.md b/packages/google-cloud-kms/CHANGELOG.md index 8b6803084975..5e1033c3421b 100644 --- a/packages/google-cloud-kms/CHANGELOG.md +++ b/packages/google-cloud-kms/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-kms/#history +## [3.14.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-kms-v3.13.0...google-cloud-kms-v3.14.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85)) + ## [3.13.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-kms-v3.12.0...google-cloud-kms-v3.13.0) (2026-05-06) ## [3.12.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-kms-v3.11.0...google-cloud-kms-v3.12.0) (2026-03-26) diff --git a/packages/google-cloud-kms/google/cloud/kms/gapic_version.py b/packages/google-cloud-kms/google/cloud/kms/gapic_version.py index 6a1c6c0bc4c3..51dd69ed928b 100644 --- a/packages/google-cloud-kms/google/cloud/kms/gapic_version.py +++ b/packages/google-cloud-kms/google/cloud/kms/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "3.13.0" # {x-release-please-version} +__version__ = "3.14.0" # {x-release-please-version} diff --git a/packages/google-cloud-kms/google/cloud/kms_v1/gapic_version.py b/packages/google-cloud-kms/google/cloud/kms_v1/gapic_version.py index 6a1c6c0bc4c3..51dd69ed928b 100644 --- a/packages/google-cloud-kms/google/cloud/kms_v1/gapic_version.py +++ b/packages/google-cloud-kms/google/cloud/kms_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "3.13.0" # {x-release-please-version} +__version__ = "3.14.0" # {x-release-please-version} diff --git a/packages/google-cloud-kms/samples/generated_samples/snippet_metadata_google.cloud.kms.v1.json b/packages/google-cloud-kms/samples/generated_samples/snippet_metadata_google.cloud.kms.v1.json index f5f8ffb5b41a..45bc2f16c0a2 100644 --- a/packages/google-cloud-kms/samples/generated_samples/snippet_metadata_google.cloud.kms.v1.json +++ b/packages/google-cloud-kms/samples/generated_samples/snippet_metadata_google.cloud.kms.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-kms", - "version": "3.13.0" + "version": "3.14.0" }, "snippets": [ { diff --git a/packages/google-cloud-language/CHANGELOG.md b/packages/google-cloud-language/CHANGELOG.md index fa640c0f26fa..7acc81e008fd 100644 --- a/packages/google-cloud-language/CHANGELOG.md +++ b/packages/google-cloud-language/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-language/#history +## [2.21.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-language-v2.20.0...google-cloud-language-v2.21.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85)) + ## [2.20.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-language-v2.19.0...google-cloud-language-v2.20.0) (2026-03-26) diff --git a/packages/google-cloud-language/google/cloud/language/gapic_version.py b/packages/google-cloud-language/google/cloud/language/gapic_version.py index 9bf1072a8834..1a040a7123e2 100644 --- a/packages/google-cloud-language/google/cloud/language/gapic_version.py +++ b/packages/google-cloud-language/google/cloud/language/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.20.0" # {x-release-please-version} +__version__ = "2.21.0" # {x-release-please-version} diff --git a/packages/google-cloud-language/google/cloud/language_v1/gapic_version.py b/packages/google-cloud-language/google/cloud/language_v1/gapic_version.py index 9bf1072a8834..1a040a7123e2 100644 --- a/packages/google-cloud-language/google/cloud/language_v1/gapic_version.py +++ b/packages/google-cloud-language/google/cloud/language_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.20.0" # {x-release-please-version} +__version__ = "2.21.0" # {x-release-please-version} diff --git a/packages/google-cloud-language/google/cloud/language_v1beta2/gapic_version.py b/packages/google-cloud-language/google/cloud/language_v1beta2/gapic_version.py index 9bf1072a8834..1a040a7123e2 100644 --- a/packages/google-cloud-language/google/cloud/language_v1beta2/gapic_version.py +++ b/packages/google-cloud-language/google/cloud/language_v1beta2/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.20.0" # {x-release-please-version} +__version__ = "2.21.0" # {x-release-please-version} diff --git a/packages/google-cloud-language/google/cloud/language_v2/gapic_version.py b/packages/google-cloud-language/google/cloud/language_v2/gapic_version.py index 9bf1072a8834..1a040a7123e2 100644 --- a/packages/google-cloud-language/google/cloud/language_v2/gapic_version.py +++ b/packages/google-cloud-language/google/cloud/language_v2/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.20.0" # {x-release-please-version} +__version__ = "2.21.0" # {x-release-please-version} diff --git a/packages/google-cloud-language/samples/generated_samples/snippet_metadata_google.cloud.language.v1.json b/packages/google-cloud-language/samples/generated_samples/snippet_metadata_google.cloud.language.v1.json index fa71c4e63870..59270cd9b1ef 100644 --- a/packages/google-cloud-language/samples/generated_samples/snippet_metadata_google.cloud.language.v1.json +++ b/packages/google-cloud-language/samples/generated_samples/snippet_metadata_google.cloud.language.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-language", - "version": "2.20.0" + "version": "2.21.0" }, "snippets": [ { diff --git a/packages/google-cloud-language/samples/generated_samples/snippet_metadata_google.cloud.language.v1beta2.json b/packages/google-cloud-language/samples/generated_samples/snippet_metadata_google.cloud.language.v1beta2.json index 08757b21c805..bc5a11714478 100644 --- a/packages/google-cloud-language/samples/generated_samples/snippet_metadata_google.cloud.language.v1beta2.json +++ b/packages/google-cloud-language/samples/generated_samples/snippet_metadata_google.cloud.language.v1beta2.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-language", - "version": "2.20.0" + "version": "2.21.0" }, "snippets": [ { diff --git a/packages/google-cloud-language/samples/generated_samples/snippet_metadata_google.cloud.language.v2.json b/packages/google-cloud-language/samples/generated_samples/snippet_metadata_google.cloud.language.v2.json index adc26b470890..e49f8c9702a4 100644 --- a/packages/google-cloud-language/samples/generated_samples/snippet_metadata_google.cloud.language.v2.json +++ b/packages/google-cloud-language/samples/generated_samples/snippet_metadata_google.cloud.language.v2.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-language", - "version": "2.20.0" + "version": "2.21.0" }, "snippets": [ { diff --git a/packages/google-cloud-licensemanager/CHANGELOG.md b/packages/google-cloud-licensemanager/CHANGELOG.md index 7be060a2a9f7..cbcd90f73e91 100644 --- a/packages/google-cloud-licensemanager/CHANGELOG.md +++ b/packages/google-cloud-licensemanager/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-licensemanager/#history +## [0.4.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-licensemanager-v0.4.0...google-cloud-licensemanager-v0.4.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85)) + ## [0.4.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-licensemanager-v0.3.0...google-cloud-licensemanager-v0.4.0) (2026-03-26) diff --git a/packages/google-cloud-licensemanager/google/cloud/licensemanager/gapic_version.py b/packages/google-cloud-licensemanager/google/cloud/licensemanager/gapic_version.py index 7a26901aff5b..7de1cf9e096e 100644 --- a/packages/google-cloud-licensemanager/google/cloud/licensemanager/gapic_version.py +++ b/packages/google-cloud-licensemanager/google/cloud/licensemanager/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.4.1" # {x-release-please-version} diff --git a/packages/google-cloud-licensemanager/google/cloud/licensemanager_v1/gapic_version.py b/packages/google-cloud-licensemanager/google/cloud/licensemanager_v1/gapic_version.py index 7a26901aff5b..7de1cf9e096e 100644 --- a/packages/google-cloud-licensemanager/google/cloud/licensemanager_v1/gapic_version.py +++ b/packages/google-cloud-licensemanager/google/cloud/licensemanager_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.4.1" # {x-release-please-version} diff --git a/packages/google-cloud-licensemanager/samples/generated_samples/snippet_metadata_google.cloud.licensemanager.v1.json b/packages/google-cloud-licensemanager/samples/generated_samples/snippet_metadata_google.cloud.licensemanager.v1.json index 8fe90a63a988..a54054029ba8 100644 --- a/packages/google-cloud-licensemanager/samples/generated_samples/snippet_metadata_google.cloud.licensemanager.v1.json +++ b/packages/google-cloud-licensemanager/samples/generated_samples/snippet_metadata_google.cloud.licensemanager.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-licensemanager", - "version": "0.4.0" + "version": "0.4.1" }, "snippets": [ { diff --git a/packages/google-cloud-life-sciences/CHANGELOG.md b/packages/google-cloud-life-sciences/CHANGELOG.md index a323b7eba826..a879c8cc5e6d 100644 --- a/packages/google-cloud-life-sciences/CHANGELOG.md +++ b/packages/google-cloud-life-sciences/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-life-sciences/#history +## [0.12.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-life-sciences-v0.12.0...google-cloud-life-sciences-v0.12.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85)) + ## [0.12.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-life-sciences-v0.11.0...google-cloud-life-sciences-v0.12.0) (2026-03-26) diff --git a/packages/google-cloud-life-sciences/google/cloud/lifesciences/gapic_version.py b/packages/google-cloud-life-sciences/google/cloud/lifesciences/gapic_version.py index e2fe575ca8e7..6883e8a21b96 100644 --- a/packages/google-cloud-life-sciences/google/cloud/lifesciences/gapic_version.py +++ b/packages/google-cloud-life-sciences/google/cloud/lifesciences/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.12.0" # {x-release-please-version} +__version__ = "0.12.1" # {x-release-please-version} diff --git a/packages/google-cloud-life-sciences/google/cloud/lifesciences_v2beta/gapic_version.py b/packages/google-cloud-life-sciences/google/cloud/lifesciences_v2beta/gapic_version.py index e2fe575ca8e7..6883e8a21b96 100644 --- a/packages/google-cloud-life-sciences/google/cloud/lifesciences_v2beta/gapic_version.py +++ b/packages/google-cloud-life-sciences/google/cloud/lifesciences_v2beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.12.0" # {x-release-please-version} +__version__ = "0.12.1" # {x-release-please-version} diff --git a/packages/google-cloud-life-sciences/samples/generated_samples/snippet_metadata_google.cloud.lifesciences.v2beta.json b/packages/google-cloud-life-sciences/samples/generated_samples/snippet_metadata_google.cloud.lifesciences.v2beta.json index bc4884f1e63d..bfd8095ea2f6 100644 --- a/packages/google-cloud-life-sciences/samples/generated_samples/snippet_metadata_google.cloud.lifesciences.v2beta.json +++ b/packages/google-cloud-life-sciences/samples/generated_samples/snippet_metadata_google.cloud.lifesciences.v2beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-life-sciences", - "version": "0.12.0" + "version": "0.12.1" }, "snippets": [ { diff --git a/packages/google-cloud-locationfinder/CHANGELOG.md b/packages/google-cloud-locationfinder/CHANGELOG.md index d7a852391d67..fc775b55573d 100644 --- a/packages/google-cloud-locationfinder/CHANGELOG.md +++ b/packages/google-cloud-locationfinder/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-locationfinder/#history +## [0.4.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-locationfinder-v0.4.0...google-cloud-locationfinder-v0.4.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85)) + ## [0.4.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-locationfinder-v0.3.0...google-cloud-locationfinder-v0.4.0) (2026-03-26) diff --git a/packages/google-cloud-locationfinder/google/cloud/locationfinder/gapic_version.py b/packages/google-cloud-locationfinder/google/cloud/locationfinder/gapic_version.py index 7a26901aff5b..7de1cf9e096e 100644 --- a/packages/google-cloud-locationfinder/google/cloud/locationfinder/gapic_version.py +++ b/packages/google-cloud-locationfinder/google/cloud/locationfinder/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.4.1" # {x-release-please-version} diff --git a/packages/google-cloud-locationfinder/google/cloud/locationfinder_v1/gapic_version.py b/packages/google-cloud-locationfinder/google/cloud/locationfinder_v1/gapic_version.py index 7a26901aff5b..7de1cf9e096e 100644 --- a/packages/google-cloud-locationfinder/google/cloud/locationfinder_v1/gapic_version.py +++ b/packages/google-cloud-locationfinder/google/cloud/locationfinder_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.4.1" # {x-release-please-version} diff --git a/packages/google-cloud-locationfinder/samples/generated_samples/snippet_metadata_google.cloud.locationfinder.v1.json b/packages/google-cloud-locationfinder/samples/generated_samples/snippet_metadata_google.cloud.locationfinder.v1.json index 489074507c84..3d26e8e2e314 100644 --- a/packages/google-cloud-locationfinder/samples/generated_samples/snippet_metadata_google.cloud.locationfinder.v1.json +++ b/packages/google-cloud-locationfinder/samples/generated_samples/snippet_metadata_google.cloud.locationfinder.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-locationfinder", - "version": "0.4.0" + "version": "0.4.1" }, "snippets": [ { diff --git a/packages/google-cloud-lustre/CHANGELOG.md b/packages/google-cloud-lustre/CHANGELOG.md index 8817c2870f80..8c67c6704889 100644 --- a/packages/google-cloud-lustre/CHANGELOG.md +++ b/packages/google-cloud-lustre/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-lustre/#history +## [0.4.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-lustre-v0.4.0...google-cloud-lustre-v0.4.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85)) + ## [0.4.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-lustre-v0.3.0...google-cloud-lustre-v0.4.0) (2026-03-26) diff --git a/packages/google-cloud-lustre/google/cloud/lustre/gapic_version.py b/packages/google-cloud-lustre/google/cloud/lustre/gapic_version.py index 7a26901aff5b..7de1cf9e096e 100644 --- a/packages/google-cloud-lustre/google/cloud/lustre/gapic_version.py +++ b/packages/google-cloud-lustre/google/cloud/lustre/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.4.1" # {x-release-please-version} diff --git a/packages/google-cloud-lustre/google/cloud/lustre_v1/gapic_version.py b/packages/google-cloud-lustre/google/cloud/lustre_v1/gapic_version.py index 7a26901aff5b..7de1cf9e096e 100644 --- a/packages/google-cloud-lustre/google/cloud/lustre_v1/gapic_version.py +++ b/packages/google-cloud-lustre/google/cloud/lustre_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.4.1" # {x-release-please-version} diff --git a/packages/google-cloud-lustre/samples/generated_samples/snippet_metadata_google.cloud.lustre.v1.json b/packages/google-cloud-lustre/samples/generated_samples/snippet_metadata_google.cloud.lustre.v1.json index 39fe37970163..4360bc6428bd 100644 --- a/packages/google-cloud-lustre/samples/generated_samples/snippet_metadata_google.cloud.lustre.v1.json +++ b/packages/google-cloud-lustre/samples/generated_samples/snippet_metadata_google.cloud.lustre.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-lustre", - "version": "0.4.0" + "version": "0.4.1" }, "snippets": [ { diff --git a/packages/google-cloud-maintenance-api/CHANGELOG.md b/packages/google-cloud-maintenance-api/CHANGELOG.md index 6f9bb22af014..45ddd8a4ef13 100644 --- a/packages/google-cloud-maintenance-api/CHANGELOG.md +++ b/packages/google-cloud-maintenance-api/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-maintenance-api/#history +## [0.4.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-maintenance-api-v0.4.0...google-cloud-maintenance-api-v0.4.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85)) + ## [0.4.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-maintenance-api-v0.3.0...google-cloud-maintenance-api-v0.4.0) (2026-03-26) diff --git a/packages/google-cloud-maintenance-api/google/cloud/maintenance_api/gapic_version.py b/packages/google-cloud-maintenance-api/google/cloud/maintenance_api/gapic_version.py index 7a26901aff5b..7de1cf9e096e 100644 --- a/packages/google-cloud-maintenance-api/google/cloud/maintenance_api/gapic_version.py +++ b/packages/google-cloud-maintenance-api/google/cloud/maintenance_api/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.4.1" # {x-release-please-version} diff --git a/packages/google-cloud-maintenance-api/google/cloud/maintenance_api_v1/gapic_version.py b/packages/google-cloud-maintenance-api/google/cloud/maintenance_api_v1/gapic_version.py index 7a26901aff5b..7de1cf9e096e 100644 --- a/packages/google-cloud-maintenance-api/google/cloud/maintenance_api_v1/gapic_version.py +++ b/packages/google-cloud-maintenance-api/google/cloud/maintenance_api_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.4.1" # {x-release-please-version} diff --git a/packages/google-cloud-maintenance-api/google/cloud/maintenance_api_v1beta/gapic_version.py b/packages/google-cloud-maintenance-api/google/cloud/maintenance_api_v1beta/gapic_version.py index 7a26901aff5b..7de1cf9e096e 100644 --- a/packages/google-cloud-maintenance-api/google/cloud/maintenance_api_v1beta/gapic_version.py +++ b/packages/google-cloud-maintenance-api/google/cloud/maintenance_api_v1beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.4.1" # {x-release-please-version} diff --git a/packages/google-cloud-maintenance-api/samples/generated_samples/snippet_metadata_google.cloud.maintenance.api.v1.json b/packages/google-cloud-maintenance-api/samples/generated_samples/snippet_metadata_google.cloud.maintenance.api.v1.json index 5a53cab55343..93a9024b1620 100644 --- a/packages/google-cloud-maintenance-api/samples/generated_samples/snippet_metadata_google.cloud.maintenance.api.v1.json +++ b/packages/google-cloud-maintenance-api/samples/generated_samples/snippet_metadata_google.cloud.maintenance.api.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-maintenance-api", - "version": "0.4.0" + "version": "0.4.1" }, "snippets": [ { diff --git a/packages/google-cloud-maintenance-api/samples/generated_samples/snippet_metadata_google.cloud.maintenance.api.v1beta.json b/packages/google-cloud-maintenance-api/samples/generated_samples/snippet_metadata_google.cloud.maintenance.api.v1beta.json index 80c4cb829a6d..cb22f6f32941 100644 --- a/packages/google-cloud-maintenance-api/samples/generated_samples/snippet_metadata_google.cloud.maintenance.api.v1beta.json +++ b/packages/google-cloud-maintenance-api/samples/generated_samples/snippet_metadata_google.cloud.maintenance.api.v1beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-maintenance-api", - "version": "0.4.0" + "version": "0.4.1" }, "snippets": [ { diff --git a/packages/google-cloud-managed-identities/CHANGELOG.md b/packages/google-cloud-managed-identities/CHANGELOG.md index e927571eb6d7..1e94322c573f 100644 --- a/packages/google-cloud-managed-identities/CHANGELOG.md +++ b/packages/google-cloud-managed-identities/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-managed-identities/#history +## [1.16.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-managed-identities-v1.15.0...google-cloud-managed-identities-v1.16.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85)) + ## [1.15.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-managed-identities-v1.14.0...google-cloud-managed-identities-v1.15.0) (2026-03-26) diff --git a/packages/google-cloud-managed-identities/google/cloud/managedidentities/gapic_version.py b/packages/google-cloud-managed-identities/google/cloud/managedidentities/gapic_version.py index 6c6a19c3c497..14edf824ad86 100644 --- a/packages/google-cloud-managed-identities/google/cloud/managedidentities/gapic_version.py +++ b/packages/google-cloud-managed-identities/google/cloud/managedidentities/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.15.0" # {x-release-please-version} +__version__ = "1.16.0" # {x-release-please-version} diff --git a/packages/google-cloud-managed-identities/google/cloud/managedidentities_v1/gapic_version.py b/packages/google-cloud-managed-identities/google/cloud/managedidentities_v1/gapic_version.py index 6c6a19c3c497..14edf824ad86 100644 --- a/packages/google-cloud-managed-identities/google/cloud/managedidentities_v1/gapic_version.py +++ b/packages/google-cloud-managed-identities/google/cloud/managedidentities_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.15.0" # {x-release-please-version} +__version__ = "1.16.0" # {x-release-please-version} diff --git a/packages/google-cloud-managed-identities/samples/generated_samples/snippet_metadata_google.cloud.managedidentities.v1.json b/packages/google-cloud-managed-identities/samples/generated_samples/snippet_metadata_google.cloud.managedidentities.v1.json index c7ab46667592..b8f90aa1f714 100644 --- a/packages/google-cloud-managed-identities/samples/generated_samples/snippet_metadata_google.cloud.managedidentities.v1.json +++ b/packages/google-cloud-managed-identities/samples/generated_samples/snippet_metadata_google.cloud.managedidentities.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-managed-identities", - "version": "1.15.0" + "version": "1.16.0" }, "snippets": [ { diff --git a/packages/google-cloud-managedkafka-schemaregistry/CHANGELOG.md b/packages/google-cloud-managedkafka-schemaregistry/CHANGELOG.md index a97f658edddf..d0fb86092c7e 100644 --- a/packages/google-cloud-managedkafka-schemaregistry/CHANGELOG.md +++ b/packages/google-cloud-managedkafka-schemaregistry/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-managedkafka-schemaregistry/#history +## [0.4.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-managedkafka-schemaregistry-v0.4.0...google-cloud-managedkafka-schemaregistry-v0.4.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85)) + ## [0.4.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-managedkafka-schemaregistry-v0.3.0...google-cloud-managedkafka-schemaregistry-v0.4.0) (2026-03-26) diff --git a/packages/google-cloud-managedkafka-schemaregistry/google/cloud/managedkafka_schemaregistry/gapic_version.py b/packages/google-cloud-managedkafka-schemaregistry/google/cloud/managedkafka_schemaregistry/gapic_version.py index 7a26901aff5b..7de1cf9e096e 100644 --- a/packages/google-cloud-managedkafka-schemaregistry/google/cloud/managedkafka_schemaregistry/gapic_version.py +++ b/packages/google-cloud-managedkafka-schemaregistry/google/cloud/managedkafka_schemaregistry/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.4.1" # {x-release-please-version} diff --git a/packages/google-cloud-managedkafka-schemaregistry/google/cloud/managedkafka_schemaregistry_v1/gapic_version.py b/packages/google-cloud-managedkafka-schemaregistry/google/cloud/managedkafka_schemaregistry_v1/gapic_version.py index 7a26901aff5b..7de1cf9e096e 100644 --- a/packages/google-cloud-managedkafka-schemaregistry/google/cloud/managedkafka_schemaregistry_v1/gapic_version.py +++ b/packages/google-cloud-managedkafka-schemaregistry/google/cloud/managedkafka_schemaregistry_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.4.1" # {x-release-please-version} diff --git a/packages/google-cloud-managedkafka-schemaregistry/samples/generated_samples/snippet_metadata_google.cloud.managedkafka.schemaregistry.v1.json b/packages/google-cloud-managedkafka-schemaregistry/samples/generated_samples/snippet_metadata_google.cloud.managedkafka.schemaregistry.v1.json index de57f21d27a2..c89f01d6e14c 100644 --- a/packages/google-cloud-managedkafka-schemaregistry/samples/generated_samples/snippet_metadata_google.cloud.managedkafka.schemaregistry.v1.json +++ b/packages/google-cloud-managedkafka-schemaregistry/samples/generated_samples/snippet_metadata_google.cloud.managedkafka.schemaregistry.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-managedkafka-schemaregistry", - "version": "0.4.0" + "version": "0.4.1" }, "snippets": [ { diff --git a/packages/google-cloud-managedkafka/CHANGELOG.md b/packages/google-cloud-managedkafka/CHANGELOG.md index 3b972c90e5ae..e413444820bf 100644 --- a/packages/google-cloud-managedkafka/CHANGELOG.md +++ b/packages/google-cloud-managedkafka/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-managedkafka/#history +## [0.4.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-managedkafka-v0.4.0...google-cloud-managedkafka-v0.4.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85)) + ## [0.4.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-managedkafka-v0.3.0...google-cloud-managedkafka-v0.4.0) (2026-03-26) diff --git a/packages/google-cloud-managedkafka/google/cloud/managedkafka/gapic_version.py b/packages/google-cloud-managedkafka/google/cloud/managedkafka/gapic_version.py index 7a26901aff5b..7de1cf9e096e 100644 --- a/packages/google-cloud-managedkafka/google/cloud/managedkafka/gapic_version.py +++ b/packages/google-cloud-managedkafka/google/cloud/managedkafka/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.4.1" # {x-release-please-version} diff --git a/packages/google-cloud-managedkafka/google/cloud/managedkafka_v1/gapic_version.py b/packages/google-cloud-managedkafka/google/cloud/managedkafka_v1/gapic_version.py index 7a26901aff5b..7de1cf9e096e 100644 --- a/packages/google-cloud-managedkafka/google/cloud/managedkafka_v1/gapic_version.py +++ b/packages/google-cloud-managedkafka/google/cloud/managedkafka_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.4.1" # {x-release-please-version} diff --git a/packages/google-cloud-managedkafka/samples/generated_samples/snippet_metadata_google.cloud.managedkafka.v1.json b/packages/google-cloud-managedkafka/samples/generated_samples/snippet_metadata_google.cloud.managedkafka.v1.json index 41c895539b3f..8dfa04c23894 100644 --- a/packages/google-cloud-managedkafka/samples/generated_samples/snippet_metadata_google.cloud.managedkafka.v1.json +++ b/packages/google-cloud-managedkafka/samples/generated_samples/snippet_metadata_google.cloud.managedkafka.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-managedkafka", - "version": "0.4.0" + "version": "0.4.1" }, "snippets": [ { diff --git a/packages/google-cloud-media-translation/CHANGELOG.md b/packages/google-cloud-media-translation/CHANGELOG.md index 8a3c83fa4a2d..e4c9564a6b0d 100644 --- a/packages/google-cloud-media-translation/CHANGELOG.md +++ b/packages/google-cloud-media-translation/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-media-translation/#history +## [0.14.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-media-translation-v0.14.0...google-cloud-media-translation-v0.14.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85)) + ## [0.14.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-media-translation-v0.13.0...google-cloud-media-translation-v0.14.0) (2026-03-26) diff --git a/packages/google-cloud-media-translation/google/cloud/mediatranslation/gapic_version.py b/packages/google-cloud-media-translation/google/cloud/mediatranslation/gapic_version.py index 83bfffcc3650..b7352296d6bc 100644 --- a/packages/google-cloud-media-translation/google/cloud/mediatranslation/gapic_version.py +++ b/packages/google-cloud-media-translation/google/cloud/mediatranslation/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.14.0" # {x-release-please-version} +__version__ = "0.14.1" # {x-release-please-version} diff --git a/packages/google-cloud-media-translation/google/cloud/mediatranslation_v1beta1/gapic_version.py b/packages/google-cloud-media-translation/google/cloud/mediatranslation_v1beta1/gapic_version.py index 83bfffcc3650..b7352296d6bc 100644 --- a/packages/google-cloud-media-translation/google/cloud/mediatranslation_v1beta1/gapic_version.py +++ b/packages/google-cloud-media-translation/google/cloud/mediatranslation_v1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.14.0" # {x-release-please-version} +__version__ = "0.14.1" # {x-release-please-version} diff --git a/packages/google-cloud-media-translation/samples/generated_samples/snippet_metadata_google.cloud.mediatranslation.v1beta1.json b/packages/google-cloud-media-translation/samples/generated_samples/snippet_metadata_google.cloud.mediatranslation.v1beta1.json index 5142fde99295..c2f0315122b5 100644 --- a/packages/google-cloud-media-translation/samples/generated_samples/snippet_metadata_google.cloud.mediatranslation.v1beta1.json +++ b/packages/google-cloud-media-translation/samples/generated_samples/snippet_metadata_google.cloud.mediatranslation.v1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-media-translation", - "version": "0.14.0" + "version": "0.14.1" }, "snippets": [ { diff --git a/packages/google-cloud-memcache/CHANGELOG.md b/packages/google-cloud-memcache/CHANGELOG.md index 37a02202a786..8dd506b578b6 100644 --- a/packages/google-cloud-memcache/CHANGELOG.md +++ b/packages/google-cloud-memcache/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-memcache/#history +## [1.16.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-memcache-v1.15.0...google-cloud-memcache-v1.16.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85)) + ## [1.15.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-memcache-v1.14.0...google-cloud-memcache-v1.15.0) (2026-03-26) diff --git a/packages/google-cloud-memcache/google/cloud/memcache/gapic_version.py b/packages/google-cloud-memcache/google/cloud/memcache/gapic_version.py index 6c6a19c3c497..14edf824ad86 100644 --- a/packages/google-cloud-memcache/google/cloud/memcache/gapic_version.py +++ b/packages/google-cloud-memcache/google/cloud/memcache/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.15.0" # {x-release-please-version} +__version__ = "1.16.0" # {x-release-please-version} diff --git a/packages/google-cloud-memcache/google/cloud/memcache_v1/gapic_version.py b/packages/google-cloud-memcache/google/cloud/memcache_v1/gapic_version.py index 6c6a19c3c497..14edf824ad86 100644 --- a/packages/google-cloud-memcache/google/cloud/memcache_v1/gapic_version.py +++ b/packages/google-cloud-memcache/google/cloud/memcache_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.15.0" # {x-release-please-version} +__version__ = "1.16.0" # {x-release-please-version} diff --git a/packages/google-cloud-memcache/google/cloud/memcache_v1beta2/gapic_version.py b/packages/google-cloud-memcache/google/cloud/memcache_v1beta2/gapic_version.py index 6c6a19c3c497..14edf824ad86 100644 --- a/packages/google-cloud-memcache/google/cloud/memcache_v1beta2/gapic_version.py +++ b/packages/google-cloud-memcache/google/cloud/memcache_v1beta2/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.15.0" # {x-release-please-version} +__version__ = "1.16.0" # {x-release-please-version} diff --git a/packages/google-cloud-memcache/samples/generated_samples/snippet_metadata_google.cloud.memcache.v1.json b/packages/google-cloud-memcache/samples/generated_samples/snippet_metadata_google.cloud.memcache.v1.json index 0b859df871bd..6aca0d3e7709 100644 --- a/packages/google-cloud-memcache/samples/generated_samples/snippet_metadata_google.cloud.memcache.v1.json +++ b/packages/google-cloud-memcache/samples/generated_samples/snippet_metadata_google.cloud.memcache.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-memcache", - "version": "1.15.0" + "version": "1.16.0" }, "snippets": [ { diff --git a/packages/google-cloud-memcache/samples/generated_samples/snippet_metadata_google.cloud.memcache.v1beta2.json b/packages/google-cloud-memcache/samples/generated_samples/snippet_metadata_google.cloud.memcache.v1beta2.json index 3cf3e8344520..320d585fefc4 100644 --- a/packages/google-cloud-memcache/samples/generated_samples/snippet_metadata_google.cloud.memcache.v1beta2.json +++ b/packages/google-cloud-memcache/samples/generated_samples/snippet_metadata_google.cloud.memcache.v1beta2.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-memcache", - "version": "1.15.0" + "version": "1.16.0" }, "snippets": [ { diff --git a/packages/google-cloud-memorystore/CHANGELOG.md b/packages/google-cloud-memorystore/CHANGELOG.md index 9642887de8a4..0625e8a4ab96 100644 --- a/packages/google-cloud-memorystore/CHANGELOG.md +++ b/packages/google-cloud-memorystore/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-memorystore/#history +## [0.5.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-memorystore-v0.5.0...google-cloud-memorystore-v0.5.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85)) + ## [0.5.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-memorystore-v0.4.0...google-cloud-memorystore-v0.5.0) (2026-05-06) diff --git a/packages/google-cloud-memorystore/google/cloud/memorystore/gapic_version.py b/packages/google-cloud-memorystore/google/cloud/memorystore/gapic_version.py index 7d9863d19611..acc458e7fa6f 100644 --- a/packages/google-cloud-memorystore/google/cloud/memorystore/gapic_version.py +++ b/packages/google-cloud-memorystore/google/cloud/memorystore/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.5.0" # {x-release-please-version} +__version__ = "0.5.1" # {x-release-please-version} diff --git a/packages/google-cloud-memorystore/google/cloud/memorystore_v1/gapic_version.py b/packages/google-cloud-memorystore/google/cloud/memorystore_v1/gapic_version.py index 7d9863d19611..acc458e7fa6f 100644 --- a/packages/google-cloud-memorystore/google/cloud/memorystore_v1/gapic_version.py +++ b/packages/google-cloud-memorystore/google/cloud/memorystore_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.5.0" # {x-release-please-version} +__version__ = "0.5.1" # {x-release-please-version} diff --git a/packages/google-cloud-memorystore/google/cloud/memorystore_v1beta/gapic_version.py b/packages/google-cloud-memorystore/google/cloud/memorystore_v1beta/gapic_version.py index 7d9863d19611..acc458e7fa6f 100644 --- a/packages/google-cloud-memorystore/google/cloud/memorystore_v1beta/gapic_version.py +++ b/packages/google-cloud-memorystore/google/cloud/memorystore_v1beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.5.0" # {x-release-please-version} +__version__ = "0.5.1" # {x-release-please-version} diff --git a/packages/google-cloud-memorystore/samples/generated_samples/snippet_metadata_google.cloud.memorystore.v1.json b/packages/google-cloud-memorystore/samples/generated_samples/snippet_metadata_google.cloud.memorystore.v1.json index ff8269af9dde..f8fa12a1ea5b 100644 --- a/packages/google-cloud-memorystore/samples/generated_samples/snippet_metadata_google.cloud.memorystore.v1.json +++ b/packages/google-cloud-memorystore/samples/generated_samples/snippet_metadata_google.cloud.memorystore.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-memorystore", - "version": "0.5.0" + "version": "0.5.1" }, "snippets": [ { diff --git a/packages/google-cloud-memorystore/samples/generated_samples/snippet_metadata_google.cloud.memorystore.v1beta.json b/packages/google-cloud-memorystore/samples/generated_samples/snippet_metadata_google.cloud.memorystore.v1beta.json index 3b52ff623f2d..8cec683c5a60 100644 --- a/packages/google-cloud-memorystore/samples/generated_samples/snippet_metadata_google.cloud.memorystore.v1beta.json +++ b/packages/google-cloud-memorystore/samples/generated_samples/snippet_metadata_google.cloud.memorystore.v1beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-memorystore", - "version": "0.5.0" + "version": "0.5.1" }, "snippets": [ { diff --git a/packages/google-cloud-migrationcenter/CHANGELOG.md b/packages/google-cloud-migrationcenter/CHANGELOG.md index ead5452ba2a5..e1c759d1bf3c 100644 --- a/packages/google-cloud-migrationcenter/CHANGELOG.md +++ b/packages/google-cloud-migrationcenter/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-migrationcenter/#history +## [0.4.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-migrationcenter-v0.4.0...google-cloud-migrationcenter-v0.4.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85)) + ## [0.4.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-migrationcenter-v0.3.0...google-cloud-migrationcenter-v0.4.0) (2026-03-26) diff --git a/packages/google-cloud-migrationcenter/google/cloud/migrationcenter/gapic_version.py b/packages/google-cloud-migrationcenter/google/cloud/migrationcenter/gapic_version.py index 7a26901aff5b..7de1cf9e096e 100644 --- a/packages/google-cloud-migrationcenter/google/cloud/migrationcenter/gapic_version.py +++ b/packages/google-cloud-migrationcenter/google/cloud/migrationcenter/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.4.1" # {x-release-please-version} diff --git a/packages/google-cloud-migrationcenter/google/cloud/migrationcenter_v1/gapic_version.py b/packages/google-cloud-migrationcenter/google/cloud/migrationcenter_v1/gapic_version.py index 7a26901aff5b..7de1cf9e096e 100644 --- a/packages/google-cloud-migrationcenter/google/cloud/migrationcenter_v1/gapic_version.py +++ b/packages/google-cloud-migrationcenter/google/cloud/migrationcenter_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.4.1" # {x-release-please-version} diff --git a/packages/google-cloud-migrationcenter/samples/generated_samples/snippet_metadata_google.cloud.migrationcenter.v1.json b/packages/google-cloud-migrationcenter/samples/generated_samples/snippet_metadata_google.cloud.migrationcenter.v1.json index 5a8bd8c00a10..1d7fcd589ff7 100644 --- a/packages/google-cloud-migrationcenter/samples/generated_samples/snippet_metadata_google.cloud.migrationcenter.v1.json +++ b/packages/google-cloud-migrationcenter/samples/generated_samples/snippet_metadata_google.cloud.migrationcenter.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-migrationcenter", - "version": "0.4.0" + "version": "0.4.1" }, "snippets": [ { diff --git a/packages/google-cloud-monitoring-dashboards/CHANGELOG.md b/packages/google-cloud-monitoring-dashboards/CHANGELOG.md index 8e5f39e32c51..10b838a8e3c5 100644 --- a/packages/google-cloud-monitoring-dashboards/CHANGELOG.md +++ b/packages/google-cloud-monitoring-dashboards/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-monitoring-dashboards/#history +## [2.22.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-monitoring-dashboards-v2.21.0...google-cloud-monitoring-dashboards-v2.22.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85)) + ## [2.21.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-monitoring-dashboards-v2.20.1...google-cloud-monitoring-dashboards-v2.21.0) (2026-03-26) diff --git a/packages/google-cloud-monitoring-dashboards/google/cloud/monitoring_dashboard/gapic_version.py b/packages/google-cloud-monitoring-dashboards/google/cloud/monitoring_dashboard/gapic_version.py index 1a040a7123e2..f1b13cc4143a 100644 --- a/packages/google-cloud-monitoring-dashboards/google/cloud/monitoring_dashboard/gapic_version.py +++ b/packages/google-cloud-monitoring-dashboards/google/cloud/monitoring_dashboard/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.21.0" # {x-release-please-version} +__version__ = "2.22.0" # {x-release-please-version} diff --git a/packages/google-cloud-monitoring-dashboards/google/cloud/monitoring_dashboard_v1/gapic_version.py b/packages/google-cloud-monitoring-dashboards/google/cloud/monitoring_dashboard_v1/gapic_version.py index 1a040a7123e2..f1b13cc4143a 100644 --- a/packages/google-cloud-monitoring-dashboards/google/cloud/monitoring_dashboard_v1/gapic_version.py +++ b/packages/google-cloud-monitoring-dashboards/google/cloud/monitoring_dashboard_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.21.0" # {x-release-please-version} +__version__ = "2.22.0" # {x-release-please-version} diff --git a/packages/google-cloud-monitoring-dashboards/google/monitoring/dashboard_v1/gapic_version.py b/packages/google-cloud-monitoring-dashboards/google/monitoring/dashboard_v1/gapic_version.py index 91772ebd624b..bdd58a16cd39 100644 --- a/packages/google-cloud-monitoring-dashboards/google/monitoring/dashboard_v1/gapic_version.py +++ b/packages/google-cloud-monitoring-dashboards/google/monitoring/dashboard_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.21.0" # {x-release-please-version} +__version__ = "2.22.0" # {x-release-please-version} diff --git a/packages/google-cloud-monitoring-dashboards/samples/generated_samples/snippet_metadata_google.monitoring.dashboard.v1.json b/packages/google-cloud-monitoring-dashboards/samples/generated_samples/snippet_metadata_google.monitoring.dashboard.v1.json index 25f28ca1d6d2..41c49301f224 100644 --- a/packages/google-cloud-monitoring-dashboards/samples/generated_samples/snippet_metadata_google.monitoring.dashboard.v1.json +++ b/packages/google-cloud-monitoring-dashboards/samples/generated_samples/snippet_metadata_google.monitoring.dashboard.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-monitoring-dashboards", - "version": "2.21.0" + "version": "2.22.0" }, "snippets": [ { diff --git a/packages/google-cloud-monitoring-metrics-scopes/CHANGELOG.md b/packages/google-cloud-monitoring-metrics-scopes/CHANGELOG.md index 5b81977da5d1..47a814c62fd0 100644 --- a/packages/google-cloud-monitoring-metrics-scopes/CHANGELOG.md +++ b/packages/google-cloud-monitoring-metrics-scopes/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-monitoring-metrics-scopes/#history +## [1.13.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-monitoring-metrics-scopes-v1.12.0...google-cloud-monitoring-metrics-scopes-v1.13.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85)) + ## [1.12.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-monitoring-metrics-scopes-v1.11.0...google-cloud-monitoring-metrics-scopes-v1.12.0) (2026-03-26) diff --git a/packages/google-cloud-monitoring-metrics-scopes/google/cloud/monitoring_metrics_scope/gapic_version.py b/packages/google-cloud-monitoring-metrics-scopes/google/cloud/monitoring_metrics_scope/gapic_version.py index 6b2f9ca0653a..66da8b1d1133 100644 --- a/packages/google-cloud-monitoring-metrics-scopes/google/cloud/monitoring_metrics_scope/gapic_version.py +++ b/packages/google-cloud-monitoring-metrics-scopes/google/cloud/monitoring_metrics_scope/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.12.0" # {x-release-please-version} +__version__ = "1.13.0" # {x-release-please-version} diff --git a/packages/google-cloud-monitoring-metrics-scopes/google/cloud/monitoring_metrics_scope_v1/gapic_version.py b/packages/google-cloud-monitoring-metrics-scopes/google/cloud/monitoring_metrics_scope_v1/gapic_version.py index 6b2f9ca0653a..66da8b1d1133 100644 --- a/packages/google-cloud-monitoring-metrics-scopes/google/cloud/monitoring_metrics_scope_v1/gapic_version.py +++ b/packages/google-cloud-monitoring-metrics-scopes/google/cloud/monitoring_metrics_scope_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.12.0" # {x-release-please-version} +__version__ = "1.13.0" # {x-release-please-version} diff --git a/packages/google-cloud-monitoring-metrics-scopes/samples/generated_samples/snippet_metadata_google.monitoring.metricsscope.v1.json b/packages/google-cloud-monitoring-metrics-scopes/samples/generated_samples/snippet_metadata_google.monitoring.metricsscope.v1.json index 24d6969c5fb2..fa1cf7b4140e 100644 --- a/packages/google-cloud-monitoring-metrics-scopes/samples/generated_samples/snippet_metadata_google.monitoring.metricsscope.v1.json +++ b/packages/google-cloud-monitoring-metrics-scopes/samples/generated_samples/snippet_metadata_google.monitoring.metricsscope.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-monitoring-metrics-scopes", - "version": "1.12.0" + "version": "1.13.0" }, "snippets": [ { diff --git a/packages/google-cloud-netapp/CHANGELOG.md b/packages/google-cloud-netapp/CHANGELOG.md index 5e6db22a49af..61dca181a293 100644 --- a/packages/google-cloud-netapp/CHANGELOG.md +++ b/packages/google-cloud-netapp/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-netapp/#history +## [0.10.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-netapp-v0.10.0...google-cloud-netapp-v0.10.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85)) + ## [0.10.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-netapp-v0.9.0...google-cloud-netapp-v0.10.0) (2026-05-06) ## [0.9.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-netapp-v0.8.0...google-cloud-netapp-v0.9.0) (2026-04-02) diff --git a/packages/google-cloud-netapp/google/cloud/netapp/gapic_version.py b/packages/google-cloud-netapp/google/cloud/netapp/gapic_version.py index 0a5d17e6c82a..e946c8a43986 100644 --- a/packages/google-cloud-netapp/google/cloud/netapp/gapic_version.py +++ b/packages/google-cloud-netapp/google/cloud/netapp/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.10.0" # {x-release-please-version} +__version__ = "0.10.1" # {x-release-please-version} diff --git a/packages/google-cloud-netapp/google/cloud/netapp_v1/gapic_version.py b/packages/google-cloud-netapp/google/cloud/netapp_v1/gapic_version.py index 0a5d17e6c82a..e946c8a43986 100644 --- a/packages/google-cloud-netapp/google/cloud/netapp_v1/gapic_version.py +++ b/packages/google-cloud-netapp/google/cloud/netapp_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.10.0" # {x-release-please-version} +__version__ = "0.10.1" # {x-release-please-version} diff --git a/packages/google-cloud-netapp/samples/generated_samples/snippet_metadata_google.cloud.netapp.v1.json b/packages/google-cloud-netapp/samples/generated_samples/snippet_metadata_google.cloud.netapp.v1.json index d0368f6d8c66..9a9115fd73aa 100644 --- a/packages/google-cloud-netapp/samples/generated_samples/snippet_metadata_google.cloud.netapp.v1.json +++ b/packages/google-cloud-netapp/samples/generated_samples/snippet_metadata_google.cloud.netapp.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-netapp", - "version": "0.10.0" + "version": "0.10.1" }, "snippets": [ { diff --git a/packages/google-cloud-network-connectivity/CHANGELOG.md b/packages/google-cloud-network-connectivity/CHANGELOG.md index 2faf4782880b..71f3a877e1d7 100644 --- a/packages/google-cloud-network-connectivity/CHANGELOG.md +++ b/packages/google-cloud-network-connectivity/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-network-connectivity/#history +## [2.16.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-network-connectivity-v2.15.0...google-cloud-network-connectivity-v2.16.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85)) + ## [2.15.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-network-connectivity-v2.14.0...google-cloud-network-connectivity-v2.15.0) (2026-03-26) diff --git a/packages/google-cloud-network-connectivity/google/cloud/networkconnectivity/gapic_version.py b/packages/google-cloud-network-connectivity/google/cloud/networkconnectivity/gapic_version.py index e8543ea688be..fe32844a85a8 100644 --- a/packages/google-cloud-network-connectivity/google/cloud/networkconnectivity/gapic_version.py +++ b/packages/google-cloud-network-connectivity/google/cloud/networkconnectivity/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.15.0" # {x-release-please-version} +__version__ = "2.16.0" # {x-release-please-version} diff --git a/packages/google-cloud-network-connectivity/google/cloud/networkconnectivity_v1/gapic_version.py b/packages/google-cloud-network-connectivity/google/cloud/networkconnectivity_v1/gapic_version.py index e8543ea688be..fe32844a85a8 100644 --- a/packages/google-cloud-network-connectivity/google/cloud/networkconnectivity_v1/gapic_version.py +++ b/packages/google-cloud-network-connectivity/google/cloud/networkconnectivity_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.15.0" # {x-release-please-version} +__version__ = "2.16.0" # {x-release-please-version} diff --git a/packages/google-cloud-network-connectivity/google/cloud/networkconnectivity_v1alpha1/gapic_version.py b/packages/google-cloud-network-connectivity/google/cloud/networkconnectivity_v1alpha1/gapic_version.py index e8543ea688be..fe32844a85a8 100644 --- a/packages/google-cloud-network-connectivity/google/cloud/networkconnectivity_v1alpha1/gapic_version.py +++ b/packages/google-cloud-network-connectivity/google/cloud/networkconnectivity_v1alpha1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.15.0" # {x-release-please-version} +__version__ = "2.16.0" # {x-release-please-version} diff --git a/packages/google-cloud-network-connectivity/google/cloud/networkconnectivity_v1beta/gapic_version.py b/packages/google-cloud-network-connectivity/google/cloud/networkconnectivity_v1beta/gapic_version.py index e8543ea688be..fe32844a85a8 100644 --- a/packages/google-cloud-network-connectivity/google/cloud/networkconnectivity_v1beta/gapic_version.py +++ b/packages/google-cloud-network-connectivity/google/cloud/networkconnectivity_v1beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.15.0" # {x-release-please-version} +__version__ = "2.16.0" # {x-release-please-version} diff --git a/packages/google-cloud-network-connectivity/samples/generated_samples/snippet_metadata_google.cloud.networkconnectivity.v1.json b/packages/google-cloud-network-connectivity/samples/generated_samples/snippet_metadata_google.cloud.networkconnectivity.v1.json index 6d128f294d17..abead568c702 100644 --- a/packages/google-cloud-network-connectivity/samples/generated_samples/snippet_metadata_google.cloud.networkconnectivity.v1.json +++ b/packages/google-cloud-network-connectivity/samples/generated_samples/snippet_metadata_google.cloud.networkconnectivity.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-network-connectivity", - "version": "2.15.0" + "version": "2.16.0" }, "snippets": [ { diff --git a/packages/google-cloud-network-connectivity/samples/generated_samples/snippet_metadata_google.cloud.networkconnectivity.v1alpha1.json b/packages/google-cloud-network-connectivity/samples/generated_samples/snippet_metadata_google.cloud.networkconnectivity.v1alpha1.json index ea6539a046c3..180b7bb8f839 100644 --- a/packages/google-cloud-network-connectivity/samples/generated_samples/snippet_metadata_google.cloud.networkconnectivity.v1alpha1.json +++ b/packages/google-cloud-network-connectivity/samples/generated_samples/snippet_metadata_google.cloud.networkconnectivity.v1alpha1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-network-connectivity", - "version": "2.15.0" + "version": "2.16.0" }, "snippets": [ { diff --git a/packages/google-cloud-network-connectivity/samples/generated_samples/snippet_metadata_google.cloud.networkconnectivity.v1beta.json b/packages/google-cloud-network-connectivity/samples/generated_samples/snippet_metadata_google.cloud.networkconnectivity.v1beta.json index 82d83d14bbe2..71e402e801bd 100644 --- a/packages/google-cloud-network-connectivity/samples/generated_samples/snippet_metadata_google.cloud.networkconnectivity.v1beta.json +++ b/packages/google-cloud-network-connectivity/samples/generated_samples/snippet_metadata_google.cloud.networkconnectivity.v1beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-network-connectivity", - "version": "2.15.0" + "version": "2.16.0" }, "snippets": [ { diff --git a/packages/google-cloud-network-management/CHANGELOG.md b/packages/google-cloud-network-management/CHANGELOG.md index e3f4fa99aaef..38723b16e6d9 100644 --- a/packages/google-cloud-network-management/CHANGELOG.md +++ b/packages/google-cloud-network-management/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-network-management/#history +## [1.36.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-network-management-v1.35.0...google-cloud-network-management-v1.36.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85)) + ## [1.35.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-network-management-v1.34.0...google-cloud-network-management-v1.35.0) (2026-05-06) ## [1.34.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-network-management-v1.33.0...google-cloud-network-management-v1.34.0) (2026-03-26) diff --git a/packages/google-cloud-network-management/google/cloud/network_management/gapic_version.py b/packages/google-cloud-network-management/google/cloud/network_management/gapic_version.py index c7dba89492dd..ef2fc5aa959f 100644 --- a/packages/google-cloud-network-management/google/cloud/network_management/gapic_version.py +++ b/packages/google-cloud-network-management/google/cloud/network_management/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.35.0" # {x-release-please-version} +__version__ = "1.36.0" # {x-release-please-version} diff --git a/packages/google-cloud-network-management/google/cloud/network_management_v1/gapic_version.py b/packages/google-cloud-network-management/google/cloud/network_management_v1/gapic_version.py index c7dba89492dd..ef2fc5aa959f 100644 --- a/packages/google-cloud-network-management/google/cloud/network_management_v1/gapic_version.py +++ b/packages/google-cloud-network-management/google/cloud/network_management_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.35.0" # {x-release-please-version} +__version__ = "1.36.0" # {x-release-please-version} diff --git a/packages/google-cloud-network-management/samples/generated_samples/snippet_metadata_google.cloud.networkmanagement.v1.json b/packages/google-cloud-network-management/samples/generated_samples/snippet_metadata_google.cloud.networkmanagement.v1.json index 8115109a2b17..f9a4aae4ebed 100644 --- a/packages/google-cloud-network-management/samples/generated_samples/snippet_metadata_google.cloud.networkmanagement.v1.json +++ b/packages/google-cloud-network-management/samples/generated_samples/snippet_metadata_google.cloud.networkmanagement.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-network-management", - "version": "1.35.0" + "version": "1.36.0" }, "snippets": [ { diff --git a/packages/google-cloud-network-security/CHANGELOG.md b/packages/google-cloud-network-security/CHANGELOG.md index 5a4fa4d1a06d..82523a1a4640 100644 --- a/packages/google-cloud-network-security/CHANGELOG.md +++ b/packages/google-cloud-network-security/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-network-security/#history +## [0.13.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-network-security-v0.13.0...google-cloud-network-security-v0.13.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85)) + ## [0.13.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-network-security-v0.12.0...google-cloud-network-security-v0.13.0) (2026-04-02) diff --git a/packages/google-cloud-network-security/google/cloud/network_security/gapic_version.py b/packages/google-cloud-network-security/google/cloud/network_security/gapic_version.py index dcda7097daa0..9847b33bcb50 100644 --- a/packages/google-cloud-network-security/google/cloud/network_security/gapic_version.py +++ b/packages/google-cloud-network-security/google/cloud/network_security/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.13.0" # {x-release-please-version} +__version__ = "0.13.1" # {x-release-please-version} diff --git a/packages/google-cloud-network-security/google/cloud/network_security_v1/gapic_version.py b/packages/google-cloud-network-security/google/cloud/network_security_v1/gapic_version.py index dcda7097daa0..9847b33bcb50 100644 --- a/packages/google-cloud-network-security/google/cloud/network_security_v1/gapic_version.py +++ b/packages/google-cloud-network-security/google/cloud/network_security_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.13.0" # {x-release-please-version} +__version__ = "0.13.1" # {x-release-please-version} diff --git a/packages/google-cloud-network-security/google/cloud/network_security_v1alpha1/gapic_version.py b/packages/google-cloud-network-security/google/cloud/network_security_v1alpha1/gapic_version.py index dcda7097daa0..9847b33bcb50 100644 --- a/packages/google-cloud-network-security/google/cloud/network_security_v1alpha1/gapic_version.py +++ b/packages/google-cloud-network-security/google/cloud/network_security_v1alpha1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.13.0" # {x-release-please-version} +__version__ = "0.13.1" # {x-release-please-version} diff --git a/packages/google-cloud-network-security/google/cloud/network_security_v1beta1/gapic_version.py b/packages/google-cloud-network-security/google/cloud/network_security_v1beta1/gapic_version.py index dcda7097daa0..9847b33bcb50 100644 --- a/packages/google-cloud-network-security/google/cloud/network_security_v1beta1/gapic_version.py +++ b/packages/google-cloud-network-security/google/cloud/network_security_v1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.13.0" # {x-release-please-version} +__version__ = "0.13.1" # {x-release-please-version} diff --git a/packages/google-cloud-network-security/samples/generated_samples/snippet_metadata_google.cloud.networksecurity.v1.json b/packages/google-cloud-network-security/samples/generated_samples/snippet_metadata_google.cloud.networksecurity.v1.json index f5bccf332a53..0bf10ecb0c30 100644 --- a/packages/google-cloud-network-security/samples/generated_samples/snippet_metadata_google.cloud.networksecurity.v1.json +++ b/packages/google-cloud-network-security/samples/generated_samples/snippet_metadata_google.cloud.networksecurity.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-network-security", - "version": "0.13.0" + "version": "0.13.1" }, "snippets": [ { diff --git a/packages/google-cloud-network-security/samples/generated_samples/snippet_metadata_google.cloud.networksecurity.v1alpha1.json b/packages/google-cloud-network-security/samples/generated_samples/snippet_metadata_google.cloud.networksecurity.v1alpha1.json index d6d3b00d0dcd..9d6dc07ca5ec 100644 --- a/packages/google-cloud-network-security/samples/generated_samples/snippet_metadata_google.cloud.networksecurity.v1alpha1.json +++ b/packages/google-cloud-network-security/samples/generated_samples/snippet_metadata_google.cloud.networksecurity.v1alpha1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-network-security", - "version": "0.13.0" + "version": "0.13.1" }, "snippets": [ { diff --git a/packages/google-cloud-network-security/samples/generated_samples/snippet_metadata_google.cloud.networksecurity.v1beta1.json b/packages/google-cloud-network-security/samples/generated_samples/snippet_metadata_google.cloud.networksecurity.v1beta1.json index 660547de6cff..a33a1ed68af7 100644 --- a/packages/google-cloud-network-security/samples/generated_samples/snippet_metadata_google.cloud.networksecurity.v1beta1.json +++ b/packages/google-cloud-network-security/samples/generated_samples/snippet_metadata_google.cloud.networksecurity.v1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-network-security", - "version": "0.13.0" + "version": "0.13.1" }, "snippets": [ { diff --git a/packages/google-cloud-notebooks/CHANGELOG.md b/packages/google-cloud-notebooks/CHANGELOG.md index 4aca508ba1a8..120a055f7996 100644 --- a/packages/google-cloud-notebooks/CHANGELOG.md +++ b/packages/google-cloud-notebooks/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-notebooks/#history +## [1.17.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-notebooks-v1.16.0...google-cloud-notebooks-v1.17.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[k-n] packages ([#17074](https://github.com/googleapis/google-cloud-python/issues/17074)) ([ec54f78](https://github.com/googleapis/google-cloud-python/commit/ec54f78e37bb3b48e0794d544784b99fa13d6f85)) + ## [1.16.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-notebooks-v1.15.0...google-cloud-notebooks-v1.16.0) (2026-03-26) diff --git a/packages/google-cloud-notebooks/google/cloud/notebooks/gapic_version.py b/packages/google-cloud-notebooks/google/cloud/notebooks/gapic_version.py index 14edf824ad86..2095da2522f4 100644 --- a/packages/google-cloud-notebooks/google/cloud/notebooks/gapic_version.py +++ b/packages/google-cloud-notebooks/google/cloud/notebooks/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.16.0" # {x-release-please-version} +__version__ = "1.17.0" # {x-release-please-version} diff --git a/packages/google-cloud-notebooks/google/cloud/notebooks_v1/gapic_version.py b/packages/google-cloud-notebooks/google/cloud/notebooks_v1/gapic_version.py index 14edf824ad86..2095da2522f4 100644 --- a/packages/google-cloud-notebooks/google/cloud/notebooks_v1/gapic_version.py +++ b/packages/google-cloud-notebooks/google/cloud/notebooks_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.16.0" # {x-release-please-version} +__version__ = "1.17.0" # {x-release-please-version} diff --git a/packages/google-cloud-notebooks/google/cloud/notebooks_v1beta1/gapic_version.py b/packages/google-cloud-notebooks/google/cloud/notebooks_v1beta1/gapic_version.py index 14edf824ad86..2095da2522f4 100644 --- a/packages/google-cloud-notebooks/google/cloud/notebooks_v1beta1/gapic_version.py +++ b/packages/google-cloud-notebooks/google/cloud/notebooks_v1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.16.0" # {x-release-please-version} +__version__ = "1.17.0" # {x-release-please-version} diff --git a/packages/google-cloud-notebooks/google/cloud/notebooks_v2/gapic_version.py b/packages/google-cloud-notebooks/google/cloud/notebooks_v2/gapic_version.py index 14edf824ad86..2095da2522f4 100644 --- a/packages/google-cloud-notebooks/google/cloud/notebooks_v2/gapic_version.py +++ b/packages/google-cloud-notebooks/google/cloud/notebooks_v2/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.16.0" # {x-release-please-version} +__version__ = "1.17.0" # {x-release-please-version} diff --git a/packages/google-cloud-notebooks/samples/generated_samples/snippet_metadata_google.cloud.notebooks.v1.json b/packages/google-cloud-notebooks/samples/generated_samples/snippet_metadata_google.cloud.notebooks.v1.json index bffd0a8addb6..1dd127ff2afb 100644 --- a/packages/google-cloud-notebooks/samples/generated_samples/snippet_metadata_google.cloud.notebooks.v1.json +++ b/packages/google-cloud-notebooks/samples/generated_samples/snippet_metadata_google.cloud.notebooks.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-notebooks", - "version": "1.16.0" + "version": "1.17.0" }, "snippets": [ { diff --git a/packages/google-cloud-notebooks/samples/generated_samples/snippet_metadata_google.cloud.notebooks.v1beta1.json b/packages/google-cloud-notebooks/samples/generated_samples/snippet_metadata_google.cloud.notebooks.v1beta1.json index d79693c23497..b13735220e74 100644 --- a/packages/google-cloud-notebooks/samples/generated_samples/snippet_metadata_google.cloud.notebooks.v1beta1.json +++ b/packages/google-cloud-notebooks/samples/generated_samples/snippet_metadata_google.cloud.notebooks.v1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-notebooks", - "version": "1.16.0" + "version": "1.17.0" }, "snippets": [ { diff --git a/packages/google-cloud-notebooks/samples/generated_samples/snippet_metadata_google.cloud.notebooks.v2.json b/packages/google-cloud-notebooks/samples/generated_samples/snippet_metadata_google.cloud.notebooks.v2.json index 231c4e31ca1b..d98a9869e0cd 100644 --- a/packages/google-cloud-notebooks/samples/generated_samples/snippet_metadata_google.cloud.notebooks.v2.json +++ b/packages/google-cloud-notebooks/samples/generated_samples/snippet_metadata_google.cloud.notebooks.v2.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-notebooks", - "version": "1.16.0" + "version": "1.17.0" }, "snippets": [ { diff --git a/packages/google-cloud-optimization/CHANGELOG.md b/packages/google-cloud-optimization/CHANGELOG.md index 7786ba9fb6de..097555a7c7b1 100644 --- a/packages/google-cloud-optimization/CHANGELOG.md +++ b/packages/google-cloud-optimization/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-optimization/#history +## [1.15.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-optimization-v1.14.0...google-cloud-optimization-v1.15.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051)) + ## [1.14.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-optimization-v1.13.0...google-cloud-optimization-v1.14.0) (2026-03-26) diff --git a/packages/google-cloud-optimization/google/cloud/optimization/gapic_version.py b/packages/google-cloud-optimization/google/cloud/optimization/gapic_version.py index da4b0a9cf041..6c6a19c3c497 100644 --- a/packages/google-cloud-optimization/google/cloud/optimization/gapic_version.py +++ b/packages/google-cloud-optimization/google/cloud/optimization/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.14.0" # {x-release-please-version} +__version__ = "1.15.0" # {x-release-please-version} diff --git a/packages/google-cloud-optimization/google/cloud/optimization_v1/gapic_version.py b/packages/google-cloud-optimization/google/cloud/optimization_v1/gapic_version.py index da4b0a9cf041..6c6a19c3c497 100644 --- a/packages/google-cloud-optimization/google/cloud/optimization_v1/gapic_version.py +++ b/packages/google-cloud-optimization/google/cloud/optimization_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.14.0" # {x-release-please-version} +__version__ = "1.15.0" # {x-release-please-version} diff --git a/packages/google-cloud-optimization/samples/generated_samples/snippet_metadata_google.cloud.optimization.v1.json b/packages/google-cloud-optimization/samples/generated_samples/snippet_metadata_google.cloud.optimization.v1.json index 42a30b8f7601..6e3ab7dd7814 100644 --- a/packages/google-cloud-optimization/samples/generated_samples/snippet_metadata_google.cloud.optimization.v1.json +++ b/packages/google-cloud-optimization/samples/generated_samples/snippet_metadata_google.cloud.optimization.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-optimization", - "version": "1.14.0" + "version": "1.15.0" }, "snippets": [ { diff --git a/packages/google-cloud-orchestration-airflow/CHANGELOG.md b/packages/google-cloud-orchestration-airflow/CHANGELOG.md index c1f5d7457798..d935ba63ec79 100644 --- a/packages/google-cloud-orchestration-airflow/CHANGELOG.md +++ b/packages/google-cloud-orchestration-airflow/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-orchestration-airflow/#history +## [1.22.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-orchestration-airflow-v1.21.0...google-cloud-orchestration-airflow-v1.22.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051)) + ## [1.21.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-orchestration-airflow-v1.20.0...google-cloud-orchestration-airflow-v1.21.0) (2026-05-06) ## [1.20.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-orchestration-airflow-v1.19.0...google-cloud-orchestration-airflow-v1.20.0) (2026-03-26) diff --git a/packages/google-cloud-orchestration-airflow/google/cloud/orchestration/airflow/service/gapic_version.py b/packages/google-cloud-orchestration-airflow/google/cloud/orchestration/airflow/service/gapic_version.py index 95884592d2da..a2e7c5e892a1 100644 --- a/packages/google-cloud-orchestration-airflow/google/cloud/orchestration/airflow/service/gapic_version.py +++ b/packages/google-cloud-orchestration-airflow/google/cloud/orchestration/airflow/service/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.21.0" # {x-release-please-version} +__version__ = "1.22.0" # {x-release-please-version} diff --git a/packages/google-cloud-orchestration-airflow/google/cloud/orchestration/airflow/service_v1/gapic_version.py b/packages/google-cloud-orchestration-airflow/google/cloud/orchestration/airflow/service_v1/gapic_version.py index 95884592d2da..a2e7c5e892a1 100644 --- a/packages/google-cloud-orchestration-airflow/google/cloud/orchestration/airflow/service_v1/gapic_version.py +++ b/packages/google-cloud-orchestration-airflow/google/cloud/orchestration/airflow/service_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.21.0" # {x-release-please-version} +__version__ = "1.22.0" # {x-release-please-version} diff --git a/packages/google-cloud-orchestration-airflow/google/cloud/orchestration/airflow/service_v1beta1/gapic_version.py b/packages/google-cloud-orchestration-airflow/google/cloud/orchestration/airflow/service_v1beta1/gapic_version.py index 95884592d2da..a2e7c5e892a1 100644 --- a/packages/google-cloud-orchestration-airflow/google/cloud/orchestration/airflow/service_v1beta1/gapic_version.py +++ b/packages/google-cloud-orchestration-airflow/google/cloud/orchestration/airflow/service_v1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.21.0" # {x-release-please-version} +__version__ = "1.22.0" # {x-release-please-version} diff --git a/packages/google-cloud-orchestration-airflow/samples/generated_samples/snippet_metadata_google.cloud.orchestration.airflow.service.v1.json b/packages/google-cloud-orchestration-airflow/samples/generated_samples/snippet_metadata_google.cloud.orchestration.airflow.service.v1.json index 8aa5b52ae41c..df4fa4187b73 100644 --- a/packages/google-cloud-orchestration-airflow/samples/generated_samples/snippet_metadata_google.cloud.orchestration.airflow.service.v1.json +++ b/packages/google-cloud-orchestration-airflow/samples/generated_samples/snippet_metadata_google.cloud.orchestration.airflow.service.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-orchestration-airflow", - "version": "1.21.0" + "version": "1.22.0" }, "snippets": [ { diff --git a/packages/google-cloud-orchestration-airflow/samples/generated_samples/snippet_metadata_google.cloud.orchestration.airflow.service.v1beta1.json b/packages/google-cloud-orchestration-airflow/samples/generated_samples/snippet_metadata_google.cloud.orchestration.airflow.service.v1beta1.json index 94c6788cb2ef..9b474889bf51 100644 --- a/packages/google-cloud-orchestration-airflow/samples/generated_samples/snippet_metadata_google.cloud.orchestration.airflow.service.v1beta1.json +++ b/packages/google-cloud-orchestration-airflow/samples/generated_samples/snippet_metadata_google.cloud.orchestration.airflow.service.v1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-orchestration-airflow", - "version": "1.21.0" + "version": "1.22.0" }, "snippets": [ { diff --git a/packages/google-cloud-org-policy/CHANGELOG.md b/packages/google-cloud-org-policy/CHANGELOG.md index 239687a634dc..d8832527b9e5 100644 --- a/packages/google-cloud-org-policy/CHANGELOG.md +++ b/packages/google-cloud-org-policy/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-org-policy/#history +## [1.18.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-org-policy-v1.17.0...google-cloud-org-policy-v1.18.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051)) + ## [1.17.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-org-policy-v1.16.1...google-cloud-org-policy-v1.17.0) (2026-03-26) diff --git a/packages/google-cloud-org-policy/google/cloud/orgpolicy/gapic_version.py b/packages/google-cloud-org-policy/google/cloud/orgpolicy/gapic_version.py index 2095da2522f4..30056a620e87 100644 --- a/packages/google-cloud-org-policy/google/cloud/orgpolicy/gapic_version.py +++ b/packages/google-cloud-org-policy/google/cloud/orgpolicy/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.17.0" # {x-release-please-version} +__version__ = "1.18.0" # {x-release-please-version} diff --git a/packages/google-cloud-org-policy/google/cloud/orgpolicy_v2/gapic_version.py b/packages/google-cloud-org-policy/google/cloud/orgpolicy_v2/gapic_version.py index 2095da2522f4..30056a620e87 100644 --- a/packages/google-cloud-org-policy/google/cloud/orgpolicy_v2/gapic_version.py +++ b/packages/google-cloud-org-policy/google/cloud/orgpolicy_v2/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.17.0" # {x-release-please-version} +__version__ = "1.18.0" # {x-release-please-version} diff --git a/packages/google-cloud-org-policy/samples/generated_samples/snippet_metadata_google.cloud.orgpolicy.v2.json b/packages/google-cloud-org-policy/samples/generated_samples/snippet_metadata_google.cloud.orgpolicy.v2.json index 05bf8654e5fe..9fefdb122aed 100644 --- a/packages/google-cloud-org-policy/samples/generated_samples/snippet_metadata_google.cloud.orgpolicy.v2.json +++ b/packages/google-cloud-org-policy/samples/generated_samples/snippet_metadata_google.cloud.orgpolicy.v2.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-org-policy", - "version": "1.17.0" + "version": "1.18.0" }, "snippets": [ { diff --git a/packages/google-cloud-os-config/CHANGELOG.md b/packages/google-cloud-os-config/CHANGELOG.md index dfaf5e015c70..cddf3e057d3b 100644 --- a/packages/google-cloud-os-config/CHANGELOG.md +++ b/packages/google-cloud-os-config/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-os-config/#history +## [1.25.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-os-config-v1.24.0...google-cloud-os-config-v1.25.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051)) + ## [1.24.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-os-config-v1.23.0...google-cloud-os-config-v1.24.0) (2026-03-26) diff --git a/packages/google-cloud-os-config/google/cloud/osconfig/gapic_version.py b/packages/google-cloud-os-config/google/cloud/osconfig/gapic_version.py index c8ec013ce4bb..9d830c39e17b 100644 --- a/packages/google-cloud-os-config/google/cloud/osconfig/gapic_version.py +++ b/packages/google-cloud-os-config/google/cloud/osconfig/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.24.0" # {x-release-please-version} +__version__ = "1.25.0" # {x-release-please-version} diff --git a/packages/google-cloud-os-config/google/cloud/osconfig_v1/gapic_version.py b/packages/google-cloud-os-config/google/cloud/osconfig_v1/gapic_version.py index c8ec013ce4bb..9d830c39e17b 100644 --- a/packages/google-cloud-os-config/google/cloud/osconfig_v1/gapic_version.py +++ b/packages/google-cloud-os-config/google/cloud/osconfig_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.24.0" # {x-release-please-version} +__version__ = "1.25.0" # {x-release-please-version} diff --git a/packages/google-cloud-os-config/google/cloud/osconfig_v1alpha/gapic_version.py b/packages/google-cloud-os-config/google/cloud/osconfig_v1alpha/gapic_version.py index c8ec013ce4bb..9d830c39e17b 100644 --- a/packages/google-cloud-os-config/google/cloud/osconfig_v1alpha/gapic_version.py +++ b/packages/google-cloud-os-config/google/cloud/osconfig_v1alpha/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.24.0" # {x-release-please-version} +__version__ = "1.25.0" # {x-release-please-version} diff --git a/packages/google-cloud-os-config/samples/generated_samples/snippet_metadata_google.cloud.osconfig.v1.json b/packages/google-cloud-os-config/samples/generated_samples/snippet_metadata_google.cloud.osconfig.v1.json index a76e5d0e846f..6bde943c4697 100644 --- a/packages/google-cloud-os-config/samples/generated_samples/snippet_metadata_google.cloud.osconfig.v1.json +++ b/packages/google-cloud-os-config/samples/generated_samples/snippet_metadata_google.cloud.osconfig.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-os-config", - "version": "1.24.0" + "version": "1.25.0" }, "snippets": [ { diff --git a/packages/google-cloud-os-config/samples/generated_samples/snippet_metadata_google.cloud.osconfig.v1alpha.json b/packages/google-cloud-os-config/samples/generated_samples/snippet_metadata_google.cloud.osconfig.v1alpha.json index fe548abc70e4..3d126ea2e901 100644 --- a/packages/google-cloud-os-config/samples/generated_samples/snippet_metadata_google.cloud.osconfig.v1alpha.json +++ b/packages/google-cloud-os-config/samples/generated_samples/snippet_metadata_google.cloud.osconfig.v1alpha.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-os-config", - "version": "1.24.0" + "version": "1.25.0" }, "snippets": [ { diff --git a/packages/google-cloud-os-login/CHANGELOG.md b/packages/google-cloud-os-login/CHANGELOG.md index e5cd4cbb57d4..e16f9afe97c3 100644 --- a/packages/google-cloud-os-login/CHANGELOG.md +++ b/packages/google-cloud-os-login/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-os-login/#history +## [2.22.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-os-login-v2.21.0...google-cloud-os-login-v2.22.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051)) + ## [2.21.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-os-login-v2.20.0...google-cloud-os-login-v2.21.0) (2026-05-06) ## [2.20.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-os-login-v2.19.0...google-cloud-os-login-v2.20.0) (2026-03-26) diff --git a/packages/google-cloud-os-login/google/cloud/oslogin/gapic_version.py b/packages/google-cloud-os-login/google/cloud/oslogin/gapic_version.py index 1a040a7123e2..f1b13cc4143a 100644 --- a/packages/google-cloud-os-login/google/cloud/oslogin/gapic_version.py +++ b/packages/google-cloud-os-login/google/cloud/oslogin/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.21.0" # {x-release-please-version} +__version__ = "2.22.0" # {x-release-please-version} diff --git a/packages/google-cloud-os-login/google/cloud/oslogin_v1/gapic_version.py b/packages/google-cloud-os-login/google/cloud/oslogin_v1/gapic_version.py index 1a040a7123e2..f1b13cc4143a 100644 --- a/packages/google-cloud-os-login/google/cloud/oslogin_v1/gapic_version.py +++ b/packages/google-cloud-os-login/google/cloud/oslogin_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.21.0" # {x-release-please-version} +__version__ = "2.22.0" # {x-release-please-version} diff --git a/packages/google-cloud-os-login/samples/generated_samples/snippet_metadata_google.cloud.oslogin.v1.json b/packages/google-cloud-os-login/samples/generated_samples/snippet_metadata_google.cloud.oslogin.v1.json index b22b994d8279..cac97dc9905c 100644 --- a/packages/google-cloud-os-login/samples/generated_samples/snippet_metadata_google.cloud.oslogin.v1.json +++ b/packages/google-cloud-os-login/samples/generated_samples/snippet_metadata_google.cloud.oslogin.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-os-login", - "version": "2.21.0" + "version": "2.22.0" }, "snippets": [ { diff --git a/packages/google-cloud-parallelstore/CHANGELOG.md b/packages/google-cloud-parallelstore/CHANGELOG.md index 4b90a8d4828a..c40cdeac63b3 100644 --- a/packages/google-cloud-parallelstore/CHANGELOG.md +++ b/packages/google-cloud-parallelstore/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-parallelstore/#history +## [0.6.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-parallelstore-v0.6.0...google-cloud-parallelstore-v0.6.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051)) + ## [0.6.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-parallelstore-v0.5.0...google-cloud-parallelstore-v0.6.0) (2026-03-26) diff --git a/packages/google-cloud-parallelstore/google/cloud/parallelstore/gapic_version.py b/packages/google-cloud-parallelstore/google/cloud/parallelstore/gapic_version.py index 916d95dd4eda..4c89af3224e4 100644 --- a/packages/google-cloud-parallelstore/google/cloud/parallelstore/gapic_version.py +++ b/packages/google-cloud-parallelstore/google/cloud/parallelstore/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.6.0" # {x-release-please-version} +__version__ = "0.6.1" # {x-release-please-version} diff --git a/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1/gapic_version.py b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1/gapic_version.py index 916d95dd4eda..4c89af3224e4 100644 --- a/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1/gapic_version.py +++ b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.6.0" # {x-release-please-version} +__version__ = "0.6.1" # {x-release-please-version} diff --git a/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/gapic_version.py b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/gapic_version.py index 916d95dd4eda..4c89af3224e4 100644 --- a/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/gapic_version.py +++ b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.6.0" # {x-release-please-version} +__version__ = "0.6.1" # {x-release-please-version} diff --git a/packages/google-cloud-parallelstore/samples/generated_samples/snippet_metadata_google.cloud.parallelstore.v1.json b/packages/google-cloud-parallelstore/samples/generated_samples/snippet_metadata_google.cloud.parallelstore.v1.json index 057831921a2a..d58f6f85a75c 100644 --- a/packages/google-cloud-parallelstore/samples/generated_samples/snippet_metadata_google.cloud.parallelstore.v1.json +++ b/packages/google-cloud-parallelstore/samples/generated_samples/snippet_metadata_google.cloud.parallelstore.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-parallelstore", - "version": "0.6.0" + "version": "0.6.1" }, "snippets": [ { diff --git a/packages/google-cloud-parallelstore/samples/generated_samples/snippet_metadata_google.cloud.parallelstore.v1beta.json b/packages/google-cloud-parallelstore/samples/generated_samples/snippet_metadata_google.cloud.parallelstore.v1beta.json index 65b57083810a..c2a6a9795a7c 100644 --- a/packages/google-cloud-parallelstore/samples/generated_samples/snippet_metadata_google.cloud.parallelstore.v1beta.json +++ b/packages/google-cloud-parallelstore/samples/generated_samples/snippet_metadata_google.cloud.parallelstore.v1beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-parallelstore", - "version": "0.6.0" + "version": "0.6.1" }, "snippets": [ { diff --git a/packages/google-cloud-parametermanager/CHANGELOG.md b/packages/google-cloud-parametermanager/CHANGELOG.md index 7034b09aaa7d..8b72827739a8 100644 --- a/packages/google-cloud-parametermanager/CHANGELOG.md +++ b/packages/google-cloud-parametermanager/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-parametermanager/#history +## [0.4.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-parametermanager-v0.4.0...google-cloud-parametermanager-v0.4.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051)) + ## [0.4.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-parametermanager-v0.3.0...google-cloud-parametermanager-v0.4.0) (2026-03-26) diff --git a/packages/google-cloud-parametermanager/google/cloud/parametermanager/gapic_version.py b/packages/google-cloud-parametermanager/google/cloud/parametermanager/gapic_version.py index 7a26901aff5b..7de1cf9e096e 100644 --- a/packages/google-cloud-parametermanager/google/cloud/parametermanager/gapic_version.py +++ b/packages/google-cloud-parametermanager/google/cloud/parametermanager/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.4.1" # {x-release-please-version} diff --git a/packages/google-cloud-parametermanager/google/cloud/parametermanager_v1/gapic_version.py b/packages/google-cloud-parametermanager/google/cloud/parametermanager_v1/gapic_version.py index 7a26901aff5b..7de1cf9e096e 100644 --- a/packages/google-cloud-parametermanager/google/cloud/parametermanager_v1/gapic_version.py +++ b/packages/google-cloud-parametermanager/google/cloud/parametermanager_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.4.1" # {x-release-please-version} diff --git a/packages/google-cloud-parametermanager/samples/generated_samples/snippet_metadata_google.cloud.parametermanager.v1.json b/packages/google-cloud-parametermanager/samples/generated_samples/snippet_metadata_google.cloud.parametermanager.v1.json index d57afea14335..dccff397a999 100644 --- a/packages/google-cloud-parametermanager/samples/generated_samples/snippet_metadata_google.cloud.parametermanager.v1.json +++ b/packages/google-cloud-parametermanager/samples/generated_samples/snippet_metadata_google.cloud.parametermanager.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-parametermanager", - "version": "0.4.0" + "version": "0.4.1" }, "snippets": [ { diff --git a/packages/google-cloud-phishing-protection/CHANGELOG.md b/packages/google-cloud-phishing-protection/CHANGELOG.md index 3f5caaf3b4d3..69d03f4c7550 100644 --- a/packages/google-cloud-phishing-protection/CHANGELOG.md +++ b/packages/google-cloud-phishing-protection/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-phishing-protection/#history +## [1.18.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-phishing-protection-v1.17.0...google-cloud-phishing-protection-v1.18.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051)) + ## [1.17.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-phishing-protection-v1.16.0...google-cloud-phishing-protection-v1.17.0) (2026-03-26) diff --git a/packages/google-cloud-phishing-protection/google/cloud/phishingprotection/gapic_version.py b/packages/google-cloud-phishing-protection/google/cloud/phishingprotection/gapic_version.py index 2095da2522f4..30056a620e87 100644 --- a/packages/google-cloud-phishing-protection/google/cloud/phishingprotection/gapic_version.py +++ b/packages/google-cloud-phishing-protection/google/cloud/phishingprotection/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.17.0" # {x-release-please-version} +__version__ = "1.18.0" # {x-release-please-version} diff --git a/packages/google-cloud-phishing-protection/google/cloud/phishingprotection_v1beta1/gapic_version.py b/packages/google-cloud-phishing-protection/google/cloud/phishingprotection_v1beta1/gapic_version.py index 2095da2522f4..30056a620e87 100644 --- a/packages/google-cloud-phishing-protection/google/cloud/phishingprotection_v1beta1/gapic_version.py +++ b/packages/google-cloud-phishing-protection/google/cloud/phishingprotection_v1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.17.0" # {x-release-please-version} +__version__ = "1.18.0" # {x-release-please-version} diff --git a/packages/google-cloud-phishing-protection/samples/generated_samples/snippet_metadata_google.cloud.phishingprotection.v1beta1.json b/packages/google-cloud-phishing-protection/samples/generated_samples/snippet_metadata_google.cloud.phishingprotection.v1beta1.json index 928768a4014e..791751be9bd3 100644 --- a/packages/google-cloud-phishing-protection/samples/generated_samples/snippet_metadata_google.cloud.phishingprotection.v1beta1.json +++ b/packages/google-cloud-phishing-protection/samples/generated_samples/snippet_metadata_google.cloud.phishingprotection.v1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-phishing-protection", - "version": "1.17.0" + "version": "1.18.0" }, "snippets": [ { diff --git a/packages/google-cloud-policy-troubleshooter/CHANGELOG.md b/packages/google-cloud-policy-troubleshooter/CHANGELOG.md index b5c94743e7c4..174b55b9a41b 100644 --- a/packages/google-cloud-policy-troubleshooter/CHANGELOG.md +++ b/packages/google-cloud-policy-troubleshooter/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-policy-troubleshooter/#history +## [1.17.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-policy-troubleshooter-v1.16.0...google-cloud-policy-troubleshooter-v1.17.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051)) + ## [1.16.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-policy-troubleshooter-v1.15.0...google-cloud-policy-troubleshooter-v1.16.0) (2026-03-26) diff --git a/packages/google-cloud-policy-troubleshooter/google/cloud/policytroubleshooter/gapic_version.py b/packages/google-cloud-policy-troubleshooter/google/cloud/policytroubleshooter/gapic_version.py index 14edf824ad86..2095da2522f4 100644 --- a/packages/google-cloud-policy-troubleshooter/google/cloud/policytroubleshooter/gapic_version.py +++ b/packages/google-cloud-policy-troubleshooter/google/cloud/policytroubleshooter/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.16.0" # {x-release-please-version} +__version__ = "1.17.0" # {x-release-please-version} diff --git a/packages/google-cloud-policy-troubleshooter/google/cloud/policytroubleshooter_v1/gapic_version.py b/packages/google-cloud-policy-troubleshooter/google/cloud/policytroubleshooter_v1/gapic_version.py index 14edf824ad86..2095da2522f4 100644 --- a/packages/google-cloud-policy-troubleshooter/google/cloud/policytroubleshooter_v1/gapic_version.py +++ b/packages/google-cloud-policy-troubleshooter/google/cloud/policytroubleshooter_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.16.0" # {x-release-please-version} +__version__ = "1.17.0" # {x-release-please-version} diff --git a/packages/google-cloud-policy-troubleshooter/samples/generated_samples/snippet_metadata_google.cloud.policytroubleshooter.v1.json b/packages/google-cloud-policy-troubleshooter/samples/generated_samples/snippet_metadata_google.cloud.policytroubleshooter.v1.json index ab1732a977ff..1bcc2c7d3fdf 100644 --- a/packages/google-cloud-policy-troubleshooter/samples/generated_samples/snippet_metadata_google.cloud.policytroubleshooter.v1.json +++ b/packages/google-cloud-policy-troubleshooter/samples/generated_samples/snippet_metadata_google.cloud.policytroubleshooter.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-policy-troubleshooter", - "version": "1.16.0" + "version": "1.17.0" }, "snippets": [ { diff --git a/packages/google-cloud-policysimulator/CHANGELOG.md b/packages/google-cloud-policysimulator/CHANGELOG.md index 7cbdcbf6b514..9ee80a8238c1 100644 --- a/packages/google-cloud-policysimulator/CHANGELOG.md +++ b/packages/google-cloud-policysimulator/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-policysimulator/#history +## [0.4.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-policysimulator-v0.4.0...google-cloud-policysimulator-v0.4.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051)) + ## [0.4.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-policysimulator-v0.3.0...google-cloud-policysimulator-v0.4.0) (2026-03-26) diff --git a/packages/google-cloud-policysimulator/google/cloud/policysimulator/gapic_version.py b/packages/google-cloud-policysimulator/google/cloud/policysimulator/gapic_version.py index 7a26901aff5b..7de1cf9e096e 100644 --- a/packages/google-cloud-policysimulator/google/cloud/policysimulator/gapic_version.py +++ b/packages/google-cloud-policysimulator/google/cloud/policysimulator/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.4.1" # {x-release-please-version} diff --git a/packages/google-cloud-policysimulator/google/cloud/policysimulator_v1/gapic_version.py b/packages/google-cloud-policysimulator/google/cloud/policysimulator_v1/gapic_version.py index 7a26901aff5b..7de1cf9e096e 100644 --- a/packages/google-cloud-policysimulator/google/cloud/policysimulator_v1/gapic_version.py +++ b/packages/google-cloud-policysimulator/google/cloud/policysimulator_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.4.1" # {x-release-please-version} diff --git a/packages/google-cloud-policysimulator/samples/generated_samples/snippet_metadata_google.cloud.policysimulator.v1.json b/packages/google-cloud-policysimulator/samples/generated_samples/snippet_metadata_google.cloud.policysimulator.v1.json index ac69f43eabb5..d812d40d9308 100644 --- a/packages/google-cloud-policysimulator/samples/generated_samples/snippet_metadata_google.cloud.policysimulator.v1.json +++ b/packages/google-cloud-policysimulator/samples/generated_samples/snippet_metadata_google.cloud.policysimulator.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-policysimulator", - "version": "0.4.0" + "version": "0.4.1" }, "snippets": [ { diff --git a/packages/google-cloud-policytroubleshooter-iam/CHANGELOG.md b/packages/google-cloud-policytroubleshooter-iam/CHANGELOG.md index 3c06d4da6755..ea81972649f3 100644 --- a/packages/google-cloud-policytroubleshooter-iam/CHANGELOG.md +++ b/packages/google-cloud-policytroubleshooter-iam/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-policytroubleshooter-iam/#history +## [0.5.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-policytroubleshooter-iam-v0.5.0...google-cloud-policytroubleshooter-iam-v0.5.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051)) + ## [0.5.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-policytroubleshooter-iam-v0.4.0...google-cloud-policytroubleshooter-iam-v0.5.0) (2026-05-06) ## [0.4.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-policytroubleshooter-iam-v0.3.0...google-cloud-policytroubleshooter-iam-v0.4.0) (2026-03-26) diff --git a/packages/google-cloud-policytroubleshooter-iam/google/cloud/policytroubleshooter_iam/gapic_version.py b/packages/google-cloud-policytroubleshooter-iam/google/cloud/policytroubleshooter_iam/gapic_version.py index 7d9863d19611..acc458e7fa6f 100644 --- a/packages/google-cloud-policytroubleshooter-iam/google/cloud/policytroubleshooter_iam/gapic_version.py +++ b/packages/google-cloud-policytroubleshooter-iam/google/cloud/policytroubleshooter_iam/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.5.0" # {x-release-please-version} +__version__ = "0.5.1" # {x-release-please-version} diff --git a/packages/google-cloud-policytroubleshooter-iam/google/cloud/policytroubleshooter_iam_v3/gapic_version.py b/packages/google-cloud-policytroubleshooter-iam/google/cloud/policytroubleshooter_iam_v3/gapic_version.py index 7d9863d19611..acc458e7fa6f 100644 --- a/packages/google-cloud-policytroubleshooter-iam/google/cloud/policytroubleshooter_iam_v3/gapic_version.py +++ b/packages/google-cloud-policytroubleshooter-iam/google/cloud/policytroubleshooter_iam_v3/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.5.0" # {x-release-please-version} +__version__ = "0.5.1" # {x-release-please-version} diff --git a/packages/google-cloud-policytroubleshooter-iam/samples/generated_samples/snippet_metadata_google.cloud.policytroubleshooter.iam.v3.json b/packages/google-cloud-policytroubleshooter-iam/samples/generated_samples/snippet_metadata_google.cloud.policytroubleshooter.iam.v3.json index 9a5ef112f0e6..4e8889133c42 100644 --- a/packages/google-cloud-policytroubleshooter-iam/samples/generated_samples/snippet_metadata_google.cloud.policytroubleshooter.iam.v3.json +++ b/packages/google-cloud-policytroubleshooter-iam/samples/generated_samples/snippet_metadata_google.cloud.policytroubleshooter.iam.v3.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-policytroubleshooter-iam", - "version": "0.5.0" + "version": "0.5.1" }, "snippets": [ { diff --git a/packages/google-cloud-private-ca/CHANGELOG.md b/packages/google-cloud-private-ca/CHANGELOG.md index be7167951568..b54e325cba5e 100644 --- a/packages/google-cloud-private-ca/CHANGELOG.md +++ b/packages/google-cloud-private-ca/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-private-ca/#history +## [1.19.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-private-ca-v1.18.0...google-cloud-private-ca-v1.19.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051)) + ## [1.18.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-private-ca-v1.17.0...google-cloud-private-ca-v1.18.0) (2026-03-26) diff --git a/packages/google-cloud-private-ca/google/cloud/security/privateca/gapic_version.py b/packages/google-cloud-private-ca/google/cloud/security/privateca/gapic_version.py index 30056a620e87..a8d1ae7b82b1 100644 --- a/packages/google-cloud-private-ca/google/cloud/security/privateca/gapic_version.py +++ b/packages/google-cloud-private-ca/google/cloud/security/privateca/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.18.0" # {x-release-please-version} +__version__ = "1.19.0" # {x-release-please-version} diff --git a/packages/google-cloud-private-ca/google/cloud/security/privateca_v1/gapic_version.py b/packages/google-cloud-private-ca/google/cloud/security/privateca_v1/gapic_version.py index 30056a620e87..a8d1ae7b82b1 100644 --- a/packages/google-cloud-private-ca/google/cloud/security/privateca_v1/gapic_version.py +++ b/packages/google-cloud-private-ca/google/cloud/security/privateca_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.18.0" # {x-release-please-version} +__version__ = "1.19.0" # {x-release-please-version} diff --git a/packages/google-cloud-private-ca/google/cloud/security/privateca_v1beta1/gapic_version.py b/packages/google-cloud-private-ca/google/cloud/security/privateca_v1beta1/gapic_version.py index 30056a620e87..a8d1ae7b82b1 100644 --- a/packages/google-cloud-private-ca/google/cloud/security/privateca_v1beta1/gapic_version.py +++ b/packages/google-cloud-private-ca/google/cloud/security/privateca_v1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.18.0" # {x-release-please-version} +__version__ = "1.19.0" # {x-release-please-version} diff --git a/packages/google-cloud-private-ca/samples/generated_samples/snippet_metadata_google.cloud.security.privateca.v1.json b/packages/google-cloud-private-ca/samples/generated_samples/snippet_metadata_google.cloud.security.privateca.v1.json index e2aef3153ad4..2e0f6163341f 100644 --- a/packages/google-cloud-private-ca/samples/generated_samples/snippet_metadata_google.cloud.security.privateca.v1.json +++ b/packages/google-cloud-private-ca/samples/generated_samples/snippet_metadata_google.cloud.security.privateca.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-private-ca", - "version": "1.18.0" + "version": "1.19.0" }, "snippets": [ { diff --git a/packages/google-cloud-private-ca/samples/generated_samples/snippet_metadata_google.cloud.security.privateca.v1beta1.json b/packages/google-cloud-private-ca/samples/generated_samples/snippet_metadata_google.cloud.security.privateca.v1beta1.json index 2b117147699c..46f968576a59 100644 --- a/packages/google-cloud-private-ca/samples/generated_samples/snippet_metadata_google.cloud.security.privateca.v1beta1.json +++ b/packages/google-cloud-private-ca/samples/generated_samples/snippet_metadata_google.cloud.security.privateca.v1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-private-ca", - "version": "1.18.0" + "version": "1.19.0" }, "snippets": [ { diff --git a/packages/google-cloud-private-catalog/CHANGELOG.md b/packages/google-cloud-private-catalog/CHANGELOG.md index d6a9f9544351..29623b3cfb95 100644 --- a/packages/google-cloud-private-catalog/CHANGELOG.md +++ b/packages/google-cloud-private-catalog/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-private-catalog/#history +## [0.12.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-private-catalog-v0.12.0...google-cloud-private-catalog-v0.12.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051)) + ## [0.12.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-private-catalog-v0.11.0...google-cloud-private-catalog-v0.12.0) (2026-03-26) diff --git a/packages/google-cloud-private-catalog/google/cloud/privatecatalog/gapic_version.py b/packages/google-cloud-private-catalog/google/cloud/privatecatalog/gapic_version.py index e2fe575ca8e7..6883e8a21b96 100644 --- a/packages/google-cloud-private-catalog/google/cloud/privatecatalog/gapic_version.py +++ b/packages/google-cloud-private-catalog/google/cloud/privatecatalog/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.12.0" # {x-release-please-version} +__version__ = "0.12.1" # {x-release-please-version} diff --git a/packages/google-cloud-private-catalog/google/cloud/privatecatalog_v1beta1/gapic_version.py b/packages/google-cloud-private-catalog/google/cloud/privatecatalog_v1beta1/gapic_version.py index e2fe575ca8e7..6883e8a21b96 100644 --- a/packages/google-cloud-private-catalog/google/cloud/privatecatalog_v1beta1/gapic_version.py +++ b/packages/google-cloud-private-catalog/google/cloud/privatecatalog_v1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.12.0" # {x-release-please-version} +__version__ = "0.12.1" # {x-release-please-version} diff --git a/packages/google-cloud-private-catalog/samples/generated_samples/snippet_metadata_google.cloud.privatecatalog.v1beta1.json b/packages/google-cloud-private-catalog/samples/generated_samples/snippet_metadata_google.cloud.privatecatalog.v1beta1.json index df49d4bea167..ffb8b81ba4f2 100644 --- a/packages/google-cloud-private-catalog/samples/generated_samples/snippet_metadata_google.cloud.privatecatalog.v1beta1.json +++ b/packages/google-cloud-private-catalog/samples/generated_samples/snippet_metadata_google.cloud.privatecatalog.v1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-private-catalog", - "version": "0.12.0" + "version": "0.12.1" }, "snippets": [ { diff --git a/packages/google-cloud-privilegedaccessmanager/CHANGELOG.md b/packages/google-cloud-privilegedaccessmanager/CHANGELOG.md index 92e16a52010c..36ccd179298a 100644 --- a/packages/google-cloud-privilegedaccessmanager/CHANGELOG.md +++ b/packages/google-cloud-privilegedaccessmanager/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-privilegedaccessmanager/#history +## [0.4.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-privilegedaccessmanager-v0.4.0...google-cloud-privilegedaccessmanager-v0.4.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051)) + ## [0.4.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-privilegedaccessmanager-v0.3.0...google-cloud-privilegedaccessmanager-v0.4.0) (2026-03-26) diff --git a/packages/google-cloud-privilegedaccessmanager/google/cloud/privilegedaccessmanager/gapic_version.py b/packages/google-cloud-privilegedaccessmanager/google/cloud/privilegedaccessmanager/gapic_version.py index 7a26901aff5b..7de1cf9e096e 100644 --- a/packages/google-cloud-privilegedaccessmanager/google/cloud/privilegedaccessmanager/gapic_version.py +++ b/packages/google-cloud-privilegedaccessmanager/google/cloud/privilegedaccessmanager/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.4.1" # {x-release-please-version} diff --git a/packages/google-cloud-privilegedaccessmanager/google/cloud/privilegedaccessmanager_v1/gapic_version.py b/packages/google-cloud-privilegedaccessmanager/google/cloud/privilegedaccessmanager_v1/gapic_version.py index 7a26901aff5b..7de1cf9e096e 100644 --- a/packages/google-cloud-privilegedaccessmanager/google/cloud/privilegedaccessmanager_v1/gapic_version.py +++ b/packages/google-cloud-privilegedaccessmanager/google/cloud/privilegedaccessmanager_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.4.1" # {x-release-please-version} diff --git a/packages/google-cloud-privilegedaccessmanager/samples/generated_samples/snippet_metadata_google.cloud.privilegedaccessmanager.v1.json b/packages/google-cloud-privilegedaccessmanager/samples/generated_samples/snippet_metadata_google.cloud.privilegedaccessmanager.v1.json index d1f6b5efb7a2..7d0a16538069 100644 --- a/packages/google-cloud-privilegedaccessmanager/samples/generated_samples/snippet_metadata_google.cloud.privilegedaccessmanager.v1.json +++ b/packages/google-cloud-privilegedaccessmanager/samples/generated_samples/snippet_metadata_google.cloud.privilegedaccessmanager.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-privilegedaccessmanager", - "version": "0.4.0" + "version": "0.4.1" }, "snippets": [ { diff --git a/packages/google-cloud-quotas/CHANGELOG.md b/packages/google-cloud-quotas/CHANGELOG.md index eb439d05e800..b4804461ccc5 100644 --- a/packages/google-cloud-quotas/CHANGELOG.md +++ b/packages/google-cloud-quotas/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-quotas/#history +## [0.6.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-quotas-v0.6.0...google-cloud-quotas-v0.6.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051)) + ## [0.6.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-quotas-v0.5.0...google-cloud-quotas-v0.6.0) (2026-03-26) diff --git a/packages/google-cloud-quotas/google/cloud/cloudquotas/gapic_version.py b/packages/google-cloud-quotas/google/cloud/cloudquotas/gapic_version.py index 916d95dd4eda..4c89af3224e4 100644 --- a/packages/google-cloud-quotas/google/cloud/cloudquotas/gapic_version.py +++ b/packages/google-cloud-quotas/google/cloud/cloudquotas/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.6.0" # {x-release-please-version} +__version__ = "0.6.1" # {x-release-please-version} diff --git a/packages/google-cloud-quotas/google/cloud/cloudquotas_v1/gapic_version.py b/packages/google-cloud-quotas/google/cloud/cloudquotas_v1/gapic_version.py index 916d95dd4eda..4c89af3224e4 100644 --- a/packages/google-cloud-quotas/google/cloud/cloudquotas_v1/gapic_version.py +++ b/packages/google-cloud-quotas/google/cloud/cloudquotas_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.6.0" # {x-release-please-version} +__version__ = "0.6.1" # {x-release-please-version} diff --git a/packages/google-cloud-quotas/google/cloud/cloudquotas_v1beta/gapic_version.py b/packages/google-cloud-quotas/google/cloud/cloudquotas_v1beta/gapic_version.py index 916d95dd4eda..4c89af3224e4 100644 --- a/packages/google-cloud-quotas/google/cloud/cloudquotas_v1beta/gapic_version.py +++ b/packages/google-cloud-quotas/google/cloud/cloudquotas_v1beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.6.0" # {x-release-please-version} +__version__ = "0.6.1" # {x-release-please-version} diff --git a/packages/google-cloud-quotas/samples/generated_samples/snippet_metadata_google.api.cloudquotas.v1.json b/packages/google-cloud-quotas/samples/generated_samples/snippet_metadata_google.api.cloudquotas.v1.json index 795087fa2672..d5561261b8db 100644 --- a/packages/google-cloud-quotas/samples/generated_samples/snippet_metadata_google.api.cloudquotas.v1.json +++ b/packages/google-cloud-quotas/samples/generated_samples/snippet_metadata_google.api.cloudquotas.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-quotas", - "version": "0.6.0" + "version": "0.6.1" }, "snippets": [ { diff --git a/packages/google-cloud-quotas/samples/generated_samples/snippet_metadata_google.api.cloudquotas.v1beta.json b/packages/google-cloud-quotas/samples/generated_samples/snippet_metadata_google.api.cloudquotas.v1beta.json index 6bd889b63bdd..ad4f96290d9a 100644 --- a/packages/google-cloud-quotas/samples/generated_samples/snippet_metadata_google.api.cloudquotas.v1beta.json +++ b/packages/google-cloud-quotas/samples/generated_samples/snippet_metadata_google.api.cloudquotas.v1beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-quotas", - "version": "0.6.0" + "version": "0.6.1" }, "snippets": [ { diff --git a/packages/google-cloud-rapidmigrationassessment/CHANGELOG.md b/packages/google-cloud-rapidmigrationassessment/CHANGELOG.md index ec3f603d1d1f..d01e10849eb4 100644 --- a/packages/google-cloud-rapidmigrationassessment/CHANGELOG.md +++ b/packages/google-cloud-rapidmigrationassessment/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-rapidmigrationassessment/#history +## [0.4.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-rapidmigrationassessment-v0.4.0...google-cloud-rapidmigrationassessment-v0.4.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051)) + ## [0.4.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-rapidmigrationassessment-v0.3.0...google-cloud-rapidmigrationassessment-v0.4.0) (2026-03-26) diff --git a/packages/google-cloud-rapidmigrationassessment/google/cloud/rapidmigrationassessment/gapic_version.py b/packages/google-cloud-rapidmigrationassessment/google/cloud/rapidmigrationassessment/gapic_version.py index 7a26901aff5b..7de1cf9e096e 100644 --- a/packages/google-cloud-rapidmigrationassessment/google/cloud/rapidmigrationassessment/gapic_version.py +++ b/packages/google-cloud-rapidmigrationassessment/google/cloud/rapidmigrationassessment/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.4.1" # {x-release-please-version} diff --git a/packages/google-cloud-rapidmigrationassessment/google/cloud/rapidmigrationassessment_v1/gapic_version.py b/packages/google-cloud-rapidmigrationassessment/google/cloud/rapidmigrationassessment_v1/gapic_version.py index 7a26901aff5b..7de1cf9e096e 100644 --- a/packages/google-cloud-rapidmigrationassessment/google/cloud/rapidmigrationassessment_v1/gapic_version.py +++ b/packages/google-cloud-rapidmigrationassessment/google/cloud/rapidmigrationassessment_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.0" # {x-release-please-version} +__version__ = "0.4.1" # {x-release-please-version} diff --git a/packages/google-cloud-rapidmigrationassessment/samples/generated_samples/snippet_metadata_google.cloud.rapidmigrationassessment.v1.json b/packages/google-cloud-rapidmigrationassessment/samples/generated_samples/snippet_metadata_google.cloud.rapidmigrationassessment.v1.json index 117a17a2b85f..48e7be021b33 100644 --- a/packages/google-cloud-rapidmigrationassessment/samples/generated_samples/snippet_metadata_google.cloud.rapidmigrationassessment.v1.json +++ b/packages/google-cloud-rapidmigrationassessment/samples/generated_samples/snippet_metadata_google.cloud.rapidmigrationassessment.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-rapidmigrationassessment", - "version": "0.4.0" + "version": "0.4.1" }, "snippets": [ { diff --git a/packages/google-cloud-recaptcha-enterprise/CHANGELOG.md b/packages/google-cloud-recaptcha-enterprise/CHANGELOG.md index 432dea1c185d..1a9cbb118e41 100644 --- a/packages/google-cloud-recaptcha-enterprise/CHANGELOG.md +++ b/packages/google-cloud-recaptcha-enterprise/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-recaptcha-enterprise/#history +## [1.32.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-recaptcha-enterprise-v1.31.0...google-cloud-recaptcha-enterprise-v1.32.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051)) + ## [1.31.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-recaptcha-enterprise-v1.30.0...google-cloud-recaptcha-enterprise-v1.31.0) (2026-03-26) diff --git a/packages/google-cloud-recaptcha-enterprise/google/cloud/recaptchaenterprise/gapic_version.py b/packages/google-cloud-recaptcha-enterprise/google/cloud/recaptchaenterprise/gapic_version.py index 88a3bff5c6e1..c19281007f0b 100644 --- a/packages/google-cloud-recaptcha-enterprise/google/cloud/recaptchaenterprise/gapic_version.py +++ b/packages/google-cloud-recaptcha-enterprise/google/cloud/recaptchaenterprise/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.31.0" # {x-release-please-version} +__version__ = "1.32.0" # {x-release-please-version} diff --git a/packages/google-cloud-recaptcha-enterprise/google/cloud/recaptchaenterprise_v1/gapic_version.py b/packages/google-cloud-recaptcha-enterprise/google/cloud/recaptchaenterprise_v1/gapic_version.py index 88a3bff5c6e1..c19281007f0b 100644 --- a/packages/google-cloud-recaptcha-enterprise/google/cloud/recaptchaenterprise_v1/gapic_version.py +++ b/packages/google-cloud-recaptcha-enterprise/google/cloud/recaptchaenterprise_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.31.0" # {x-release-please-version} +__version__ = "1.32.0" # {x-release-please-version} diff --git a/packages/google-cloud-recaptcha-enterprise/samples/generated_samples/snippet_metadata_google.cloud.recaptchaenterprise.v1.json b/packages/google-cloud-recaptcha-enterprise/samples/generated_samples/snippet_metadata_google.cloud.recaptchaenterprise.v1.json index a56dbaf9796d..4b62f4928c6a 100644 --- a/packages/google-cloud-recaptcha-enterprise/samples/generated_samples/snippet_metadata_google.cloud.recaptchaenterprise.v1.json +++ b/packages/google-cloud-recaptcha-enterprise/samples/generated_samples/snippet_metadata_google.cloud.recaptchaenterprise.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-recaptcha-enterprise", - "version": "1.31.0" + "version": "1.32.0" }, "snippets": [ { diff --git a/packages/google-cloud-recommendations-ai/CHANGELOG.md b/packages/google-cloud-recommendations-ai/CHANGELOG.md index 899035c2e7eb..fc1bc77bbbb5 100644 --- a/packages/google-cloud-recommendations-ai/CHANGELOG.md +++ b/packages/google-cloud-recommendations-ai/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-recommendations-ai/#history +## [0.13.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-recommendations-ai-v0.13.0...google-cloud-recommendations-ai-v0.13.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051)) + ## [0.13.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-recommendations-ai-v0.12.0...google-cloud-recommendations-ai-v0.13.0) (2026-03-26) diff --git a/packages/google-cloud-recommendations-ai/google/cloud/recommendationengine/gapic_version.py b/packages/google-cloud-recommendations-ai/google/cloud/recommendationengine/gapic_version.py index dcda7097daa0..9847b33bcb50 100644 --- a/packages/google-cloud-recommendations-ai/google/cloud/recommendationengine/gapic_version.py +++ b/packages/google-cloud-recommendations-ai/google/cloud/recommendationengine/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.13.0" # {x-release-please-version} +__version__ = "0.13.1" # {x-release-please-version} diff --git a/packages/google-cloud-recommendations-ai/google/cloud/recommendationengine_v1beta1/gapic_version.py b/packages/google-cloud-recommendations-ai/google/cloud/recommendationengine_v1beta1/gapic_version.py index dcda7097daa0..9847b33bcb50 100644 --- a/packages/google-cloud-recommendations-ai/google/cloud/recommendationengine_v1beta1/gapic_version.py +++ b/packages/google-cloud-recommendations-ai/google/cloud/recommendationengine_v1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.13.0" # {x-release-please-version} +__version__ = "0.13.1" # {x-release-please-version} diff --git a/packages/google-cloud-recommendations-ai/samples/generated_samples/snippet_metadata_google.cloud.recommendationengine.v1beta1.json b/packages/google-cloud-recommendations-ai/samples/generated_samples/snippet_metadata_google.cloud.recommendationengine.v1beta1.json index e6b91b6d2c45..8dd3380aa250 100644 --- a/packages/google-cloud-recommendations-ai/samples/generated_samples/snippet_metadata_google.cloud.recommendationengine.v1beta1.json +++ b/packages/google-cloud-recommendations-ai/samples/generated_samples/snippet_metadata_google.cloud.recommendationengine.v1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-recommendations-ai", - "version": "0.13.0" + "version": "0.13.1" }, "snippets": [ { diff --git a/packages/google-cloud-recommender/CHANGELOG.md b/packages/google-cloud-recommender/CHANGELOG.md index 6ba8e7bbf0e2..9e25cbb7a07b 100644 --- a/packages/google-cloud-recommender/CHANGELOG.md +++ b/packages/google-cloud-recommender/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-recommender/#history +## [2.22.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-recommender-v2.21.0...google-cloud-recommender-v2.22.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051)) + ## [2.21.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-recommender-v2.20.0...google-cloud-recommender-v2.21.0) (2026-03-26) diff --git a/packages/google-cloud-recommender/google/cloud/recommender/gapic_version.py b/packages/google-cloud-recommender/google/cloud/recommender/gapic_version.py index 1a040a7123e2..f1b13cc4143a 100644 --- a/packages/google-cloud-recommender/google/cloud/recommender/gapic_version.py +++ b/packages/google-cloud-recommender/google/cloud/recommender/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.21.0" # {x-release-please-version} +__version__ = "2.22.0" # {x-release-please-version} diff --git a/packages/google-cloud-recommender/google/cloud/recommender_v1/gapic_version.py b/packages/google-cloud-recommender/google/cloud/recommender_v1/gapic_version.py index 1a040a7123e2..f1b13cc4143a 100644 --- a/packages/google-cloud-recommender/google/cloud/recommender_v1/gapic_version.py +++ b/packages/google-cloud-recommender/google/cloud/recommender_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.21.0" # {x-release-please-version} +__version__ = "2.22.0" # {x-release-please-version} diff --git a/packages/google-cloud-recommender/google/cloud/recommender_v1beta1/gapic_version.py b/packages/google-cloud-recommender/google/cloud/recommender_v1beta1/gapic_version.py index 1a040a7123e2..f1b13cc4143a 100644 --- a/packages/google-cloud-recommender/google/cloud/recommender_v1beta1/gapic_version.py +++ b/packages/google-cloud-recommender/google/cloud/recommender_v1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.21.0" # {x-release-please-version} +__version__ = "2.22.0" # {x-release-please-version} diff --git a/packages/google-cloud-recommender/samples/generated_samples/snippet_metadata_google.cloud.recommender.v1.json b/packages/google-cloud-recommender/samples/generated_samples/snippet_metadata_google.cloud.recommender.v1.json index de05dec986f8..56be7ef0198b 100644 --- a/packages/google-cloud-recommender/samples/generated_samples/snippet_metadata_google.cloud.recommender.v1.json +++ b/packages/google-cloud-recommender/samples/generated_samples/snippet_metadata_google.cloud.recommender.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-recommender", - "version": "2.21.0" + "version": "2.22.0" }, "snippets": [ { diff --git a/packages/google-cloud-recommender/samples/generated_samples/snippet_metadata_google.cloud.recommender.v1beta1.json b/packages/google-cloud-recommender/samples/generated_samples/snippet_metadata_google.cloud.recommender.v1beta1.json index 0ee07e757a13..2ef478b831c2 100644 --- a/packages/google-cloud-recommender/samples/generated_samples/snippet_metadata_google.cloud.recommender.v1beta1.json +++ b/packages/google-cloud-recommender/samples/generated_samples/snippet_metadata_google.cloud.recommender.v1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-recommender", - "version": "2.21.0" + "version": "2.22.0" }, "snippets": [ { diff --git a/packages/google-cloud-redis-cluster/CHANGELOG.md b/packages/google-cloud-redis-cluster/CHANGELOG.md index e70a4c000ccf..3bef763bff2f 100644 --- a/packages/google-cloud-redis-cluster/CHANGELOG.md +++ b/packages/google-cloud-redis-cluster/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-redis-cluster/#history +## [0.5.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-redis-cluster-v0.5.0...google-cloud-redis-cluster-v0.5.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051)) + ## [0.5.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-redis-cluster-v0.4.0...google-cloud-redis-cluster-v0.5.0) (2026-05-06) ## [0.4.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-redis-cluster-v0.3.0...google-cloud-redis-cluster-v0.4.0) (2026-03-26) diff --git a/packages/google-cloud-redis-cluster/google/cloud/redis_cluster/gapic_version.py b/packages/google-cloud-redis-cluster/google/cloud/redis_cluster/gapic_version.py index 7d9863d19611..acc458e7fa6f 100644 --- a/packages/google-cloud-redis-cluster/google/cloud/redis_cluster/gapic_version.py +++ b/packages/google-cloud-redis-cluster/google/cloud/redis_cluster/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.5.0" # {x-release-please-version} +__version__ = "0.5.1" # {x-release-please-version} diff --git a/packages/google-cloud-redis-cluster/google/cloud/redis_cluster_v1/gapic_version.py b/packages/google-cloud-redis-cluster/google/cloud/redis_cluster_v1/gapic_version.py index 7d9863d19611..acc458e7fa6f 100644 --- a/packages/google-cloud-redis-cluster/google/cloud/redis_cluster_v1/gapic_version.py +++ b/packages/google-cloud-redis-cluster/google/cloud/redis_cluster_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.5.0" # {x-release-please-version} +__version__ = "0.5.1" # {x-release-please-version} diff --git a/packages/google-cloud-redis-cluster/google/cloud/redis_cluster_v1beta1/gapic_version.py b/packages/google-cloud-redis-cluster/google/cloud/redis_cluster_v1beta1/gapic_version.py index 7d9863d19611..acc458e7fa6f 100644 --- a/packages/google-cloud-redis-cluster/google/cloud/redis_cluster_v1beta1/gapic_version.py +++ b/packages/google-cloud-redis-cluster/google/cloud/redis_cluster_v1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.5.0" # {x-release-please-version} +__version__ = "0.5.1" # {x-release-please-version} diff --git a/packages/google-cloud-redis-cluster/samples/generated_samples/snippet_metadata_google.cloud.redis.cluster.v1.json b/packages/google-cloud-redis-cluster/samples/generated_samples/snippet_metadata_google.cloud.redis.cluster.v1.json index 329c0617c639..db3a73f598b0 100644 --- a/packages/google-cloud-redis-cluster/samples/generated_samples/snippet_metadata_google.cloud.redis.cluster.v1.json +++ b/packages/google-cloud-redis-cluster/samples/generated_samples/snippet_metadata_google.cloud.redis.cluster.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-redis-cluster", - "version": "0.5.0" + "version": "0.5.1" }, "snippets": [ { diff --git a/packages/google-cloud-redis-cluster/samples/generated_samples/snippet_metadata_google.cloud.redis.cluster.v1beta1.json b/packages/google-cloud-redis-cluster/samples/generated_samples/snippet_metadata_google.cloud.redis.cluster.v1beta1.json index ce3c6fa7c166..2e04889aec02 100644 --- a/packages/google-cloud-redis-cluster/samples/generated_samples/snippet_metadata_google.cloud.redis.cluster.v1beta1.json +++ b/packages/google-cloud-redis-cluster/samples/generated_samples/snippet_metadata_google.cloud.redis.cluster.v1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-redis-cluster", - "version": "0.5.0" + "version": "0.5.1" }, "snippets": [ { diff --git a/packages/google-cloud-redis/CHANGELOG.md b/packages/google-cloud-redis/CHANGELOG.md index 1d6b73ee3e91..1016a3349e45 100644 --- a/packages/google-cloud-redis/CHANGELOG.md +++ b/packages/google-cloud-redis/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-redis/#history +## [2.22.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-redis-v2.21.0...google-cloud-redis-v2.22.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051)) + ## [2.21.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-redis-v2.20.0...google-cloud-redis-v2.21.0) (2026-03-26) diff --git a/packages/google-cloud-redis/google/cloud/redis/gapic_version.py b/packages/google-cloud-redis/google/cloud/redis/gapic_version.py index 1a040a7123e2..f1b13cc4143a 100644 --- a/packages/google-cloud-redis/google/cloud/redis/gapic_version.py +++ b/packages/google-cloud-redis/google/cloud/redis/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.21.0" # {x-release-please-version} +__version__ = "2.22.0" # {x-release-please-version} diff --git a/packages/google-cloud-redis/google/cloud/redis_v1/gapic_version.py b/packages/google-cloud-redis/google/cloud/redis_v1/gapic_version.py index 1a040a7123e2..f1b13cc4143a 100644 --- a/packages/google-cloud-redis/google/cloud/redis_v1/gapic_version.py +++ b/packages/google-cloud-redis/google/cloud/redis_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.21.0" # {x-release-please-version} +__version__ = "2.22.0" # {x-release-please-version} diff --git a/packages/google-cloud-redis/google/cloud/redis_v1beta1/gapic_version.py b/packages/google-cloud-redis/google/cloud/redis_v1beta1/gapic_version.py index 1a040a7123e2..f1b13cc4143a 100644 --- a/packages/google-cloud-redis/google/cloud/redis_v1beta1/gapic_version.py +++ b/packages/google-cloud-redis/google/cloud/redis_v1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.21.0" # {x-release-please-version} +__version__ = "2.22.0" # {x-release-please-version} diff --git a/packages/google-cloud-redis/samples/generated_samples/snippet_metadata_google.cloud.redis.v1.json b/packages/google-cloud-redis/samples/generated_samples/snippet_metadata_google.cloud.redis.v1.json index a690816845ee..1ee0a1416489 100644 --- a/packages/google-cloud-redis/samples/generated_samples/snippet_metadata_google.cloud.redis.v1.json +++ b/packages/google-cloud-redis/samples/generated_samples/snippet_metadata_google.cloud.redis.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-redis", - "version": "2.21.0" + "version": "2.22.0" }, "snippets": [ { diff --git a/packages/google-cloud-redis/samples/generated_samples/snippet_metadata_google.cloud.redis.v1beta1.json b/packages/google-cloud-redis/samples/generated_samples/snippet_metadata_google.cloud.redis.v1beta1.json index 629bfe082b7f..243fabd3091b 100644 --- a/packages/google-cloud-redis/samples/generated_samples/snippet_metadata_google.cloud.redis.v1beta1.json +++ b/packages/google-cloud-redis/samples/generated_samples/snippet_metadata_google.cloud.redis.v1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-redis", - "version": "2.21.0" + "version": "2.22.0" }, "snippets": [ { diff --git a/packages/google-cloud-resource-manager/CHANGELOG.md b/packages/google-cloud-resource-manager/CHANGELOG.md index a7656f023014..c8aacd2b2de6 100644 --- a/packages/google-cloud-resource-manager/CHANGELOG.md +++ b/packages/google-cloud-resource-manager/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-resource-manager/#history +## [1.18.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-resource-manager-v1.17.0...google-cloud-resource-manager-v1.18.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051)) + ## [1.17.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-resource-manager-v1.16.0...google-cloud-resource-manager-v1.17.0) (2026-03-26) diff --git a/packages/google-cloud-resource-manager/google/cloud/resourcemanager/gapic_version.py b/packages/google-cloud-resource-manager/google/cloud/resourcemanager/gapic_version.py index 2095da2522f4..30056a620e87 100644 --- a/packages/google-cloud-resource-manager/google/cloud/resourcemanager/gapic_version.py +++ b/packages/google-cloud-resource-manager/google/cloud/resourcemanager/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.17.0" # {x-release-please-version} +__version__ = "1.18.0" # {x-release-please-version} diff --git a/packages/google-cloud-resource-manager/google/cloud/resourcemanager_v3/gapic_version.py b/packages/google-cloud-resource-manager/google/cloud/resourcemanager_v3/gapic_version.py index 2095da2522f4..30056a620e87 100644 --- a/packages/google-cloud-resource-manager/google/cloud/resourcemanager_v3/gapic_version.py +++ b/packages/google-cloud-resource-manager/google/cloud/resourcemanager_v3/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.17.0" # {x-release-please-version} +__version__ = "1.18.0" # {x-release-please-version} diff --git a/packages/google-cloud-resource-manager/samples/generated_samples/snippet_metadata_google.cloud.resourcemanager.v3.json b/packages/google-cloud-resource-manager/samples/generated_samples/snippet_metadata_google.cloud.resourcemanager.v3.json index 39dbaf6183a6..c1a0124739c8 100644 --- a/packages/google-cloud-resource-manager/samples/generated_samples/snippet_metadata_google.cloud.resourcemanager.v3.json +++ b/packages/google-cloud-resource-manager/samples/generated_samples/snippet_metadata_google.cloud.resourcemanager.v3.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-resource-manager", - "version": "1.17.0" + "version": "1.18.0" }, "snippets": [ { diff --git a/packages/google-cloud-retail/CHANGELOG.md b/packages/google-cloud-retail/CHANGELOG.md index 1caf48265c46..86e2f1d2bfa2 100644 --- a/packages/google-cloud-retail/CHANGELOG.md +++ b/packages/google-cloud-retail/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-retail/#history +## [2.11.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-retail-v2.10.0...google-cloud-retail-v2.11.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051)) + ## [2.10.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-retail-v2.9.0...google-cloud-retail-v2.10.0) (2026-03-26) diff --git a/packages/google-cloud-retail/google/cloud/retail/gapic_version.py b/packages/google-cloud-retail/google/cloud/retail/gapic_version.py index b525e6b63b92..b914fef5f079 100644 --- a/packages/google-cloud-retail/google/cloud/retail/gapic_version.py +++ b/packages/google-cloud-retail/google/cloud/retail/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.10.0" # {x-release-please-version} +__version__ = "2.11.0" # {x-release-please-version} diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/gapic_version.py b/packages/google-cloud-retail/google/cloud/retail_v2/gapic_version.py index b525e6b63b92..b914fef5f079 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2/gapic_version.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.10.0" # {x-release-please-version} +__version__ = "2.11.0" # {x-release-please-version} diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/gapic_version.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/gapic_version.py index b525e6b63b92..b914fef5f079 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/gapic_version.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.10.0" # {x-release-please-version} +__version__ = "2.11.0" # {x-release-please-version} diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/gapic_version.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/gapic_version.py index b525e6b63b92..b914fef5f079 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/gapic_version.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.10.0" # {x-release-please-version} +__version__ = "2.11.0" # {x-release-please-version} diff --git a/packages/google-cloud-retail/samples/generated_samples/snippet_metadata_google.cloud.retail.v2.json b/packages/google-cloud-retail/samples/generated_samples/snippet_metadata_google.cloud.retail.v2.json index 33494f418069..08d690bb628b 100644 --- a/packages/google-cloud-retail/samples/generated_samples/snippet_metadata_google.cloud.retail.v2.json +++ b/packages/google-cloud-retail/samples/generated_samples/snippet_metadata_google.cloud.retail.v2.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-retail", - "version": "2.10.0" + "version": "2.11.0" }, "snippets": [ { diff --git a/packages/google-cloud-retail/samples/generated_samples/snippet_metadata_google.cloud.retail.v2alpha.json b/packages/google-cloud-retail/samples/generated_samples/snippet_metadata_google.cloud.retail.v2alpha.json index a54b19adad48..d3db880629d8 100644 --- a/packages/google-cloud-retail/samples/generated_samples/snippet_metadata_google.cloud.retail.v2alpha.json +++ b/packages/google-cloud-retail/samples/generated_samples/snippet_metadata_google.cloud.retail.v2alpha.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-retail", - "version": "2.10.0" + "version": "2.11.0" }, "snippets": [ { diff --git a/packages/google-cloud-retail/samples/generated_samples/snippet_metadata_google.cloud.retail.v2beta.json b/packages/google-cloud-retail/samples/generated_samples/snippet_metadata_google.cloud.retail.v2beta.json index 297ec739cbed..4c30af8ddd5f 100644 --- a/packages/google-cloud-retail/samples/generated_samples/snippet_metadata_google.cloud.retail.v2beta.json +++ b/packages/google-cloud-retail/samples/generated_samples/snippet_metadata_google.cloud.retail.v2beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-retail", - "version": "2.10.0" + "version": "2.11.0" }, "snippets": [ { diff --git a/packages/google-cloud-run/CHANGELOG.md b/packages/google-cloud-run/CHANGELOG.md index e78024df646c..4afa8f195fbd 100644 --- a/packages/google-cloud-run/CHANGELOG.md +++ b/packages/google-cloud-run/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-run/#history +## [0.16.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-run-v0.16.0...google-cloud-run-v0.16.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[o-r] packages ([#17075](https://github.com/googleapis/google-cloud-python/issues/17075)) ([f4bd018](https://github.com/googleapis/google-cloud-python/commit/f4bd0182d808ae73c3c6981e6ce3d565f78a6051)) + ## [0.16.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-run-v0.15.0...google-cloud-run-v0.16.0) (2026-03-26) diff --git a/packages/google-cloud-run/google/cloud/run/gapic_version.py b/packages/google-cloud-run/google/cloud/run/gapic_version.py index bb638cb9896c..71ad58d79b27 100644 --- a/packages/google-cloud-run/google/cloud/run/gapic_version.py +++ b/packages/google-cloud-run/google/cloud/run/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.16.0" # {x-release-please-version} +__version__ = "0.16.1" # {x-release-please-version} diff --git a/packages/google-cloud-run/google/cloud/run_v2/gapic_version.py b/packages/google-cloud-run/google/cloud/run_v2/gapic_version.py index bb638cb9896c..71ad58d79b27 100644 --- a/packages/google-cloud-run/google/cloud/run_v2/gapic_version.py +++ b/packages/google-cloud-run/google/cloud/run_v2/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.16.0" # {x-release-please-version} +__version__ = "0.16.1" # {x-release-please-version} diff --git a/packages/google-cloud-run/samples/generated_samples/snippet_metadata_google.cloud.run.v2.json b/packages/google-cloud-run/samples/generated_samples/snippet_metadata_google.cloud.run.v2.json index 7affb4f0f941..1c293bd7666b 100644 --- a/packages/google-cloud-run/samples/generated_samples/snippet_metadata_google.cloud.run.v2.json +++ b/packages/google-cloud-run/samples/generated_samples/snippet_metadata_google.cloud.run.v2.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-run", - "version": "0.16.0" + "version": "0.16.1" }, "snippets": [ { diff --git a/packages/google-cloud-talent/CHANGELOG.md b/packages/google-cloud-talent/CHANGELOG.md index 275981605ffb..ab23925f5e19 100644 --- a/packages/google-cloud-talent/CHANGELOG.md +++ b/packages/google-cloud-talent/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-talent/#history +## [2.21.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-talent-v2.20.0...google-cloud-talent-v2.21.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8)) + ## [2.20.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-talent-v2.19.0...google-cloud-talent-v2.20.0) (2026-03-26) diff --git a/packages/google-cloud-talent/google/cloud/talent/gapic_version.py b/packages/google-cloud-talent/google/cloud/talent/gapic_version.py index 9bf1072a8834..1a040a7123e2 100644 --- a/packages/google-cloud-talent/google/cloud/talent/gapic_version.py +++ b/packages/google-cloud-talent/google/cloud/talent/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.20.0" # {x-release-please-version} +__version__ = "2.21.0" # {x-release-please-version} diff --git a/packages/google-cloud-talent/google/cloud/talent_v4/gapic_version.py b/packages/google-cloud-talent/google/cloud/talent_v4/gapic_version.py index 9bf1072a8834..1a040a7123e2 100644 --- a/packages/google-cloud-talent/google/cloud/talent_v4/gapic_version.py +++ b/packages/google-cloud-talent/google/cloud/talent_v4/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.20.0" # {x-release-please-version} +__version__ = "2.21.0" # {x-release-please-version} diff --git a/packages/google-cloud-talent/google/cloud/talent_v4beta1/gapic_version.py b/packages/google-cloud-talent/google/cloud/talent_v4beta1/gapic_version.py index 9bf1072a8834..1a040a7123e2 100644 --- a/packages/google-cloud-talent/google/cloud/talent_v4beta1/gapic_version.py +++ b/packages/google-cloud-talent/google/cloud/talent_v4beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.20.0" # {x-release-please-version} +__version__ = "2.21.0" # {x-release-please-version} diff --git a/packages/google-cloud-talent/samples/generated_samples/snippet_metadata_google.cloud.talent.v4.json b/packages/google-cloud-talent/samples/generated_samples/snippet_metadata_google.cloud.talent.v4.json index a7dca2fdcaba..1bf186a7f8b1 100644 --- a/packages/google-cloud-talent/samples/generated_samples/snippet_metadata_google.cloud.talent.v4.json +++ b/packages/google-cloud-talent/samples/generated_samples/snippet_metadata_google.cloud.talent.v4.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-talent", - "version": "2.20.0" + "version": "2.21.0" }, "snippets": [ { diff --git a/packages/google-cloud-talent/samples/generated_samples/snippet_metadata_google.cloud.talent.v4beta1.json b/packages/google-cloud-talent/samples/generated_samples/snippet_metadata_google.cloud.talent.v4beta1.json index 7cd002ccec33..07e81c4c8dd8 100644 --- a/packages/google-cloud-talent/samples/generated_samples/snippet_metadata_google.cloud.talent.v4beta1.json +++ b/packages/google-cloud-talent/samples/generated_samples/snippet_metadata_google.cloud.talent.v4beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-talent", - "version": "2.20.0" + "version": "2.21.0" }, "snippets": [ { diff --git a/packages/google-cloud-tasks/CHANGELOG.md b/packages/google-cloud-tasks/CHANGELOG.md index 8c4b799cbef6..70a467d1cd4d 100644 --- a/packages/google-cloud-tasks/CHANGELOG.md +++ b/packages/google-cloud-tasks/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-tasks/#history +## [2.23.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-tasks-v2.22.0...google-cloud-tasks-v2.23.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8)) + ## [2.22.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-tasks-v2.21.0...google-cloud-tasks-v2.22.0) (2026-03-26) diff --git a/packages/google-cloud-tasks/google/cloud/tasks/gapic_version.py b/packages/google-cloud-tasks/google/cloud/tasks/gapic_version.py index f1b13cc4143a..d01518ddd752 100644 --- a/packages/google-cloud-tasks/google/cloud/tasks/gapic_version.py +++ b/packages/google-cloud-tasks/google/cloud/tasks/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.22.0" # {x-release-please-version} +__version__ = "2.23.0" # {x-release-please-version} diff --git a/packages/google-cloud-tasks/google/cloud/tasks_v2/gapic_version.py b/packages/google-cloud-tasks/google/cloud/tasks_v2/gapic_version.py index f1b13cc4143a..d01518ddd752 100644 --- a/packages/google-cloud-tasks/google/cloud/tasks_v2/gapic_version.py +++ b/packages/google-cloud-tasks/google/cloud/tasks_v2/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.22.0" # {x-release-please-version} +__version__ = "2.23.0" # {x-release-please-version} diff --git a/packages/google-cloud-tasks/google/cloud/tasks_v2beta2/gapic_version.py b/packages/google-cloud-tasks/google/cloud/tasks_v2beta2/gapic_version.py index f1b13cc4143a..d01518ddd752 100644 --- a/packages/google-cloud-tasks/google/cloud/tasks_v2beta2/gapic_version.py +++ b/packages/google-cloud-tasks/google/cloud/tasks_v2beta2/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.22.0" # {x-release-please-version} +__version__ = "2.23.0" # {x-release-please-version} diff --git a/packages/google-cloud-tasks/google/cloud/tasks_v2beta3/gapic_version.py b/packages/google-cloud-tasks/google/cloud/tasks_v2beta3/gapic_version.py index f1b13cc4143a..d01518ddd752 100644 --- a/packages/google-cloud-tasks/google/cloud/tasks_v2beta3/gapic_version.py +++ b/packages/google-cloud-tasks/google/cloud/tasks_v2beta3/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.22.0" # {x-release-please-version} +__version__ = "2.23.0" # {x-release-please-version} diff --git a/packages/google-cloud-tasks/samples/generated_samples/snippet_metadata_google.cloud.tasks.v2.json b/packages/google-cloud-tasks/samples/generated_samples/snippet_metadata_google.cloud.tasks.v2.json index b8e1bf6fd44c..decfdb68f6cc 100644 --- a/packages/google-cloud-tasks/samples/generated_samples/snippet_metadata_google.cloud.tasks.v2.json +++ b/packages/google-cloud-tasks/samples/generated_samples/snippet_metadata_google.cloud.tasks.v2.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-tasks", - "version": "2.22.0" + "version": "2.23.0" }, "snippets": [ { diff --git a/packages/google-cloud-tasks/samples/generated_samples/snippet_metadata_google.cloud.tasks.v2beta2.json b/packages/google-cloud-tasks/samples/generated_samples/snippet_metadata_google.cloud.tasks.v2beta2.json index ffda10d52bfd..eb3034c315d5 100644 --- a/packages/google-cloud-tasks/samples/generated_samples/snippet_metadata_google.cloud.tasks.v2beta2.json +++ b/packages/google-cloud-tasks/samples/generated_samples/snippet_metadata_google.cloud.tasks.v2beta2.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-tasks", - "version": "2.22.0" + "version": "2.23.0" }, "snippets": [ { diff --git a/packages/google-cloud-tasks/samples/generated_samples/snippet_metadata_google.cloud.tasks.v2beta3.json b/packages/google-cloud-tasks/samples/generated_samples/snippet_metadata_google.cloud.tasks.v2beta3.json index b8300a24ad50..5cf3ff30b3d5 100644 --- a/packages/google-cloud-tasks/samples/generated_samples/snippet_metadata_google.cloud.tasks.v2beta3.json +++ b/packages/google-cloud-tasks/samples/generated_samples/snippet_metadata_google.cloud.tasks.v2beta3.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-tasks", - "version": "2.22.0" + "version": "2.23.0" }, "snippets": [ { diff --git a/packages/google-cloud-telcoautomation/CHANGELOG.md b/packages/google-cloud-telcoautomation/CHANGELOG.md index a5838bd410af..a30eaf301502 100644 --- a/packages/google-cloud-telcoautomation/CHANGELOG.md +++ b/packages/google-cloud-telcoautomation/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-telcoautomation/#history +## [0.5.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-telcoautomation-v0.5.0...google-cloud-telcoautomation-v0.5.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8)) + ## [0.5.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-telcoautomation-v0.4.0...google-cloud-telcoautomation-v0.5.0) (2026-03-26) diff --git a/packages/google-cloud-telcoautomation/google/cloud/telcoautomation/gapic_version.py b/packages/google-cloud-telcoautomation/google/cloud/telcoautomation/gapic_version.py index 7d9863d19611..acc458e7fa6f 100644 --- a/packages/google-cloud-telcoautomation/google/cloud/telcoautomation/gapic_version.py +++ b/packages/google-cloud-telcoautomation/google/cloud/telcoautomation/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.5.0" # {x-release-please-version} +__version__ = "0.5.1" # {x-release-please-version} diff --git a/packages/google-cloud-telcoautomation/google/cloud/telcoautomation_v1/gapic_version.py b/packages/google-cloud-telcoautomation/google/cloud/telcoautomation_v1/gapic_version.py index 7d9863d19611..acc458e7fa6f 100644 --- a/packages/google-cloud-telcoautomation/google/cloud/telcoautomation_v1/gapic_version.py +++ b/packages/google-cloud-telcoautomation/google/cloud/telcoautomation_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.5.0" # {x-release-please-version} +__version__ = "0.5.1" # {x-release-please-version} diff --git a/packages/google-cloud-telcoautomation/google/cloud/telcoautomation_v1alpha1/gapic_version.py b/packages/google-cloud-telcoautomation/google/cloud/telcoautomation_v1alpha1/gapic_version.py index 7d9863d19611..acc458e7fa6f 100644 --- a/packages/google-cloud-telcoautomation/google/cloud/telcoautomation_v1alpha1/gapic_version.py +++ b/packages/google-cloud-telcoautomation/google/cloud/telcoautomation_v1alpha1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.5.0" # {x-release-please-version} +__version__ = "0.5.1" # {x-release-please-version} diff --git a/packages/google-cloud-telcoautomation/samples/generated_samples/snippet_metadata_google.cloud.telcoautomation.v1.json b/packages/google-cloud-telcoautomation/samples/generated_samples/snippet_metadata_google.cloud.telcoautomation.v1.json index 856a6aee53bd..0aca7e832b20 100644 --- a/packages/google-cloud-telcoautomation/samples/generated_samples/snippet_metadata_google.cloud.telcoautomation.v1.json +++ b/packages/google-cloud-telcoautomation/samples/generated_samples/snippet_metadata_google.cloud.telcoautomation.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-telcoautomation", - "version": "0.5.0" + "version": "0.5.1" }, "snippets": [ { diff --git a/packages/google-cloud-telcoautomation/samples/generated_samples/snippet_metadata_google.cloud.telcoautomation.v1alpha1.json b/packages/google-cloud-telcoautomation/samples/generated_samples/snippet_metadata_google.cloud.telcoautomation.v1alpha1.json index 79ea06c8065c..f0422ba7e992 100644 --- a/packages/google-cloud-telcoautomation/samples/generated_samples/snippet_metadata_google.cloud.telcoautomation.v1alpha1.json +++ b/packages/google-cloud-telcoautomation/samples/generated_samples/snippet_metadata_google.cloud.telcoautomation.v1alpha1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-telcoautomation", - "version": "0.5.0" + "version": "0.5.1" }, "snippets": [ { diff --git a/packages/google-cloud-testutils/CHANGELOG.md b/packages/google-cloud-testutils/CHANGELOG.md index 34f4163d36a1..6f47745228bf 100644 --- a/packages/google-cloud-testutils/CHANGELOG.md +++ b/packages/google-cloud-testutils/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-testutils/#history +## [1.9.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-testutils-v1.9.0...google-cloud-testutils-v1.9.1) (2026-06-22) + + +### Bug Fixes + +* make test_utils unique_resource_id parallel-safe ([#17440](https://github.com/googleapis/google-cloud-python/issues/17440)) ([ac1f5d5](https://github.com/googleapis/google-cloud-python/commit/ac1f5d55900d4787f2ced6b5350ef530f700794b)) + ## [1.9.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-testutils-v1.8.0...google-cloud-testutils-v1.9.0) (2026-06-02) diff --git a/packages/google-cloud-testutils/test_utils/version.py b/packages/google-cloud-testutils/test_utils/version.py index ea38ecfc5597..16c74ccd69af 100644 --- a/packages/google-cloud-testutils/test_utils/version.py +++ b/packages/google-cloud-testutils/test_utils/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.9.0" +__version__ = "1.9.1" diff --git a/packages/google-cloud-texttospeech/CHANGELOG.md b/packages/google-cloud-texttospeech/CHANGELOG.md index 537118d54375..d2b2fbb06fc8 100644 --- a/packages/google-cloud-texttospeech/CHANGELOG.md +++ b/packages/google-cloud-texttospeech/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-texttospeech/#history +## [2.37.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-texttospeech-v2.36.0...google-cloud-texttospeech-v2.37.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8)) + ## [2.36.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-texttospeech-v2.35.0...google-cloud-texttospeech-v2.36.0) (2026-04-02) diff --git a/packages/google-cloud-texttospeech/google/cloud/texttospeech/gapic_version.py b/packages/google-cloud-texttospeech/google/cloud/texttospeech/gapic_version.py index 4768ac4d710c..8feae1655bd2 100644 --- a/packages/google-cloud-texttospeech/google/cloud/texttospeech/gapic_version.py +++ b/packages/google-cloud-texttospeech/google/cloud/texttospeech/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.36.0" # {x-release-please-version} +__version__ = "2.37.0" # {x-release-please-version} diff --git a/packages/google-cloud-texttospeech/google/cloud/texttospeech_v1/gapic_version.py b/packages/google-cloud-texttospeech/google/cloud/texttospeech_v1/gapic_version.py index 4768ac4d710c..8feae1655bd2 100644 --- a/packages/google-cloud-texttospeech/google/cloud/texttospeech_v1/gapic_version.py +++ b/packages/google-cloud-texttospeech/google/cloud/texttospeech_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.36.0" # {x-release-please-version} +__version__ = "2.37.0" # {x-release-please-version} diff --git a/packages/google-cloud-texttospeech/google/cloud/texttospeech_v1beta1/gapic_version.py b/packages/google-cloud-texttospeech/google/cloud/texttospeech_v1beta1/gapic_version.py index 4768ac4d710c..8feae1655bd2 100644 --- a/packages/google-cloud-texttospeech/google/cloud/texttospeech_v1beta1/gapic_version.py +++ b/packages/google-cloud-texttospeech/google/cloud/texttospeech_v1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.36.0" # {x-release-please-version} +__version__ = "2.37.0" # {x-release-please-version} diff --git a/packages/google-cloud-texttospeech/samples/generated_samples/snippet_metadata_google.cloud.texttospeech.v1.json b/packages/google-cloud-texttospeech/samples/generated_samples/snippet_metadata_google.cloud.texttospeech.v1.json index f3c6092069ee..9aa7be661d94 100644 --- a/packages/google-cloud-texttospeech/samples/generated_samples/snippet_metadata_google.cloud.texttospeech.v1.json +++ b/packages/google-cloud-texttospeech/samples/generated_samples/snippet_metadata_google.cloud.texttospeech.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-texttospeech", - "version": "2.36.0" + "version": "2.37.0" }, "snippets": [ { diff --git a/packages/google-cloud-texttospeech/samples/generated_samples/snippet_metadata_google.cloud.texttospeech.v1beta1.json b/packages/google-cloud-texttospeech/samples/generated_samples/snippet_metadata_google.cloud.texttospeech.v1beta1.json index 1a206b2537a5..a846356ce36e 100644 --- a/packages/google-cloud-texttospeech/samples/generated_samples/snippet_metadata_google.cloud.texttospeech.v1beta1.json +++ b/packages/google-cloud-texttospeech/samples/generated_samples/snippet_metadata_google.cloud.texttospeech.v1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-texttospeech", - "version": "2.36.0" + "version": "2.37.0" }, "snippets": [ { diff --git a/packages/google-cloud-tpu/CHANGELOG.md b/packages/google-cloud-tpu/CHANGELOG.md index 46ab2ac537c5..6cb685e7903e 100644 --- a/packages/google-cloud-tpu/CHANGELOG.md +++ b/packages/google-cloud-tpu/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-tpu/#history +## [1.27.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-tpu-v1.26.0...google-cloud-tpu-v1.27.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8)) + ## [1.26.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-tpu-v1.25.0...google-cloud-tpu-v1.26.0) (2026-03-26) diff --git a/packages/google-cloud-tpu/google/cloud/tpu/gapic_version.py b/packages/google-cloud-tpu/google/cloud/tpu/gapic_version.py index d598e3d58488..7bcab5a1ba7a 100644 --- a/packages/google-cloud-tpu/google/cloud/tpu/gapic_version.py +++ b/packages/google-cloud-tpu/google/cloud/tpu/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.26.0" # {x-release-please-version} +__version__ = "1.27.0" # {x-release-please-version} diff --git a/packages/google-cloud-tpu/google/cloud/tpu_v1/gapic_version.py b/packages/google-cloud-tpu/google/cloud/tpu_v1/gapic_version.py index d598e3d58488..7bcab5a1ba7a 100644 --- a/packages/google-cloud-tpu/google/cloud/tpu_v1/gapic_version.py +++ b/packages/google-cloud-tpu/google/cloud/tpu_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.26.0" # {x-release-please-version} +__version__ = "1.27.0" # {x-release-please-version} diff --git a/packages/google-cloud-tpu/google/cloud/tpu_v2/gapic_version.py b/packages/google-cloud-tpu/google/cloud/tpu_v2/gapic_version.py index d598e3d58488..7bcab5a1ba7a 100644 --- a/packages/google-cloud-tpu/google/cloud/tpu_v2/gapic_version.py +++ b/packages/google-cloud-tpu/google/cloud/tpu_v2/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.26.0" # {x-release-please-version} +__version__ = "1.27.0" # {x-release-please-version} diff --git a/packages/google-cloud-tpu/google/cloud/tpu_v2alpha1/gapic_version.py b/packages/google-cloud-tpu/google/cloud/tpu_v2alpha1/gapic_version.py index d598e3d58488..7bcab5a1ba7a 100644 --- a/packages/google-cloud-tpu/google/cloud/tpu_v2alpha1/gapic_version.py +++ b/packages/google-cloud-tpu/google/cloud/tpu_v2alpha1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.26.0" # {x-release-please-version} +__version__ = "1.27.0" # {x-release-please-version} diff --git a/packages/google-cloud-tpu/samples/generated_samples/snippet_metadata_google.cloud.tpu.v1.json b/packages/google-cloud-tpu/samples/generated_samples/snippet_metadata_google.cloud.tpu.v1.json index 2dad58e83685..79418502df58 100644 --- a/packages/google-cloud-tpu/samples/generated_samples/snippet_metadata_google.cloud.tpu.v1.json +++ b/packages/google-cloud-tpu/samples/generated_samples/snippet_metadata_google.cloud.tpu.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-tpu", - "version": "1.26.0" + "version": "1.27.0" }, "snippets": [ { diff --git a/packages/google-cloud-tpu/samples/generated_samples/snippet_metadata_google.cloud.tpu.v2.json b/packages/google-cloud-tpu/samples/generated_samples/snippet_metadata_google.cloud.tpu.v2.json index a67727e6e199..be02f53dfb82 100644 --- a/packages/google-cloud-tpu/samples/generated_samples/snippet_metadata_google.cloud.tpu.v2.json +++ b/packages/google-cloud-tpu/samples/generated_samples/snippet_metadata_google.cloud.tpu.v2.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-tpu", - "version": "1.26.0" + "version": "1.27.0" }, "snippets": [ { diff --git a/packages/google-cloud-tpu/samples/generated_samples/snippet_metadata_google.cloud.tpu.v2alpha1.json b/packages/google-cloud-tpu/samples/generated_samples/snippet_metadata_google.cloud.tpu.v2alpha1.json index e880c1ea8bcf..261270d0c542 100644 --- a/packages/google-cloud-tpu/samples/generated_samples/snippet_metadata_google.cloud.tpu.v2alpha1.json +++ b/packages/google-cloud-tpu/samples/generated_samples/snippet_metadata_google.cloud.tpu.v2alpha1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-tpu", - "version": "1.26.0" + "version": "1.27.0" }, "snippets": [ { diff --git a/packages/google-cloud-trace/CHANGELOG.md b/packages/google-cloud-trace/CHANGELOG.md index eac060650aa5..dc05e05d43c4 100644 --- a/packages/google-cloud-trace/CHANGELOG.md +++ b/packages/google-cloud-trace/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-trace/#history +## [1.20.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-trace-v1.19.0...google-cloud-trace-v1.20.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8)) + ## [1.19.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-trace-v1.18.0...google-cloud-trace-v1.19.0) (2026-03-26) diff --git a/packages/google-cloud-trace/google/cloud/trace/gapic_version.py b/packages/google-cloud-trace/google/cloud/trace/gapic_version.py index a8d1ae7b82b1..c0c0d110e496 100644 --- a/packages/google-cloud-trace/google/cloud/trace/gapic_version.py +++ b/packages/google-cloud-trace/google/cloud/trace/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.19.0" # {x-release-please-version} +__version__ = "1.20.0" # {x-release-please-version} diff --git a/packages/google-cloud-trace/google/cloud/trace_v1/gapic_version.py b/packages/google-cloud-trace/google/cloud/trace_v1/gapic_version.py index a8d1ae7b82b1..c0c0d110e496 100644 --- a/packages/google-cloud-trace/google/cloud/trace_v1/gapic_version.py +++ b/packages/google-cloud-trace/google/cloud/trace_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.19.0" # {x-release-please-version} +__version__ = "1.20.0" # {x-release-please-version} diff --git a/packages/google-cloud-trace/google/cloud/trace_v2/gapic_version.py b/packages/google-cloud-trace/google/cloud/trace_v2/gapic_version.py index a8d1ae7b82b1..c0c0d110e496 100644 --- a/packages/google-cloud-trace/google/cloud/trace_v2/gapic_version.py +++ b/packages/google-cloud-trace/google/cloud/trace_v2/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.19.0" # {x-release-please-version} +__version__ = "1.20.0" # {x-release-please-version} diff --git a/packages/google-cloud-trace/samples/generated_samples/snippet_metadata_google.devtools.cloudtrace.v1.json b/packages/google-cloud-trace/samples/generated_samples/snippet_metadata_google.devtools.cloudtrace.v1.json index 5b73ecee2588..6595a49cce18 100644 --- a/packages/google-cloud-trace/samples/generated_samples/snippet_metadata_google.devtools.cloudtrace.v1.json +++ b/packages/google-cloud-trace/samples/generated_samples/snippet_metadata_google.devtools.cloudtrace.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-trace", - "version": "1.19.0" + "version": "1.20.0" }, "snippets": [ { diff --git a/packages/google-cloud-trace/samples/generated_samples/snippet_metadata_google.devtools.cloudtrace.v2.json b/packages/google-cloud-trace/samples/generated_samples/snippet_metadata_google.devtools.cloudtrace.v2.json index 75a4a0cc457a..f6ddefe861ba 100644 --- a/packages/google-cloud-trace/samples/generated_samples/snippet_metadata_google.devtools.cloudtrace.v2.json +++ b/packages/google-cloud-trace/samples/generated_samples/snippet_metadata_google.devtools.cloudtrace.v2.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-trace", - "version": "1.19.0" + "version": "1.20.0" }, "snippets": [ { diff --git a/packages/google-cloud-translate/CHANGELOG.md b/packages/google-cloud-translate/CHANGELOG.md index 4c479c31db23..bf6c38e56d36 100644 --- a/packages/google-cloud-translate/CHANGELOG.md +++ b/packages/google-cloud-translate/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-translate/#history +## [3.27.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-translate-v3.26.0...google-cloud-translate-v3.27.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8)) + ## [3.26.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-translate-v3.25.0...google-cloud-translate-v3.26.0) (2026-04-09) diff --git a/packages/google-cloud-translate/google/cloud/translate/gapic_version.py b/packages/google-cloud-translate/google/cloud/translate/gapic_version.py index 945b3bfd6809..3c7f35435385 100644 --- a/packages/google-cloud-translate/google/cloud/translate/gapic_version.py +++ b/packages/google-cloud-translate/google/cloud/translate/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "3.26.0" # {x-release-please-version} +__version__ = "3.27.0" # {x-release-please-version} diff --git a/packages/google-cloud-translate/google/cloud/translate_v3/gapic_version.py b/packages/google-cloud-translate/google/cloud/translate_v3/gapic_version.py index 945b3bfd6809..3c7f35435385 100644 --- a/packages/google-cloud-translate/google/cloud/translate_v3/gapic_version.py +++ b/packages/google-cloud-translate/google/cloud/translate_v3/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "3.26.0" # {x-release-please-version} +__version__ = "3.27.0" # {x-release-please-version} diff --git a/packages/google-cloud-translate/google/cloud/translate_v3beta1/gapic_version.py b/packages/google-cloud-translate/google/cloud/translate_v3beta1/gapic_version.py index 945b3bfd6809..3c7f35435385 100644 --- a/packages/google-cloud-translate/google/cloud/translate_v3beta1/gapic_version.py +++ b/packages/google-cloud-translate/google/cloud/translate_v3beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "3.26.0" # {x-release-please-version} +__version__ = "3.27.0" # {x-release-please-version} diff --git a/packages/google-cloud-translate/samples/generated_samples/snippet_metadata_google.cloud.translation.v3.json b/packages/google-cloud-translate/samples/generated_samples/snippet_metadata_google.cloud.translation.v3.json index 164c96f09b5d..0c695e6d7f92 100644 --- a/packages/google-cloud-translate/samples/generated_samples/snippet_metadata_google.cloud.translation.v3.json +++ b/packages/google-cloud-translate/samples/generated_samples/snippet_metadata_google.cloud.translation.v3.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-translate", - "version": "3.26.0" + "version": "3.27.0" }, "snippets": [ { diff --git a/packages/google-cloud-translate/samples/generated_samples/snippet_metadata_google.cloud.translation.v3beta1.json b/packages/google-cloud-translate/samples/generated_samples/snippet_metadata_google.cloud.translation.v3beta1.json index e5176c2a8d8e..b06f36437ab8 100644 --- a/packages/google-cloud-translate/samples/generated_samples/snippet_metadata_google.cloud.translation.v3beta1.json +++ b/packages/google-cloud-translate/samples/generated_samples/snippet_metadata_google.cloud.translation.v3beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-translate", - "version": "3.26.0" + "version": "3.27.0" }, "snippets": [ { diff --git a/packages/google-cloud-video-live-stream/CHANGELOG.md b/packages/google-cloud-video-live-stream/CHANGELOG.md index 513185ce6093..b51e0567a7c4 100644 --- a/packages/google-cloud-video-live-stream/CHANGELOG.md +++ b/packages/google-cloud-video-live-stream/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-video-live-stream/#history +## [1.17.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-video-live-stream-v1.16.0...google-cloud-video-live-stream-v1.17.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8)) + ## [1.16.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-video-live-stream-v1.15.0...google-cloud-video-live-stream-v1.16.0) (2026-03-26) diff --git a/packages/google-cloud-video-live-stream/google/cloud/video/live_stream/gapic_version.py b/packages/google-cloud-video-live-stream/google/cloud/video/live_stream/gapic_version.py index 14edf824ad86..2095da2522f4 100644 --- a/packages/google-cloud-video-live-stream/google/cloud/video/live_stream/gapic_version.py +++ b/packages/google-cloud-video-live-stream/google/cloud/video/live_stream/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.16.0" # {x-release-please-version} +__version__ = "1.17.0" # {x-release-please-version} diff --git a/packages/google-cloud-video-live-stream/google/cloud/video/live_stream_v1/gapic_version.py b/packages/google-cloud-video-live-stream/google/cloud/video/live_stream_v1/gapic_version.py index 14edf824ad86..2095da2522f4 100644 --- a/packages/google-cloud-video-live-stream/google/cloud/video/live_stream_v1/gapic_version.py +++ b/packages/google-cloud-video-live-stream/google/cloud/video/live_stream_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.16.0" # {x-release-please-version} +__version__ = "1.17.0" # {x-release-please-version} diff --git a/packages/google-cloud-video-live-stream/samples/generated_samples/snippet_metadata_google.cloud.video.livestream.v1.json b/packages/google-cloud-video-live-stream/samples/generated_samples/snippet_metadata_google.cloud.video.livestream.v1.json index ea9fa01613d9..9ede3d5f4266 100644 --- a/packages/google-cloud-video-live-stream/samples/generated_samples/snippet_metadata_google.cloud.video.livestream.v1.json +++ b/packages/google-cloud-video-live-stream/samples/generated_samples/snippet_metadata_google.cloud.video.livestream.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-video-live-stream", - "version": "1.16.0" + "version": "1.17.0" }, "snippets": [ { diff --git a/packages/google-cloud-video-stitcher/CHANGELOG.md b/packages/google-cloud-video-stitcher/CHANGELOG.md index 79d95cb203bb..4559b8ccf82a 100644 --- a/packages/google-cloud-video-stitcher/CHANGELOG.md +++ b/packages/google-cloud-video-stitcher/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-video-stitcher/#history +## [0.11.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-video-stitcher-v0.11.0...google-cloud-video-stitcher-v0.11.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8)) + ## [0.11.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-video-stitcher-v0.10.0...google-cloud-video-stitcher-v0.11.0) (2026-03-26) diff --git a/packages/google-cloud-video-stitcher/google/cloud/video/stitcher/gapic_version.py b/packages/google-cloud-video-stitcher/google/cloud/video/stitcher/gapic_version.py index 09eb9941e1dd..13e3f7a016da 100644 --- a/packages/google-cloud-video-stitcher/google/cloud/video/stitcher/gapic_version.py +++ b/packages/google-cloud-video-stitcher/google/cloud/video/stitcher/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.11.0" # {x-release-please-version} +__version__ = "0.11.1" # {x-release-please-version} diff --git a/packages/google-cloud-video-stitcher/google/cloud/video/stitcher_v1/gapic_version.py b/packages/google-cloud-video-stitcher/google/cloud/video/stitcher_v1/gapic_version.py index 09eb9941e1dd..13e3f7a016da 100644 --- a/packages/google-cloud-video-stitcher/google/cloud/video/stitcher_v1/gapic_version.py +++ b/packages/google-cloud-video-stitcher/google/cloud/video/stitcher_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.11.0" # {x-release-please-version} +__version__ = "0.11.1" # {x-release-please-version} diff --git a/packages/google-cloud-video-stitcher/samples/generated_samples/snippet_metadata_google.cloud.video.stitcher.v1.json b/packages/google-cloud-video-stitcher/samples/generated_samples/snippet_metadata_google.cloud.video.stitcher.v1.json index ae12e39dacb8..1d3ef9690a30 100644 --- a/packages/google-cloud-video-stitcher/samples/generated_samples/snippet_metadata_google.cloud.video.stitcher.v1.json +++ b/packages/google-cloud-video-stitcher/samples/generated_samples/snippet_metadata_google.cloud.video.stitcher.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-video-stitcher", - "version": "0.11.0" + "version": "0.11.1" }, "snippets": [ { diff --git a/packages/google-cloud-video-transcoder/CHANGELOG.md b/packages/google-cloud-video-transcoder/CHANGELOG.md index 3fca678c39ba..f09e81b37dd6 100644 --- a/packages/google-cloud-video-transcoder/CHANGELOG.md +++ b/packages/google-cloud-video-transcoder/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-video-transcoder/#history +## [1.21.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-video-transcoder-v1.20.0...google-cloud-video-transcoder-v1.21.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8)) + ## [1.20.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-video-transcoder-v1.19.0...google-cloud-video-transcoder-v1.20.0) (2026-03-26) diff --git a/packages/google-cloud-video-transcoder/google/cloud/video/transcoder/gapic_version.py b/packages/google-cloud-video-transcoder/google/cloud/video/transcoder/gapic_version.py index c0c0d110e496..95884592d2da 100644 --- a/packages/google-cloud-video-transcoder/google/cloud/video/transcoder/gapic_version.py +++ b/packages/google-cloud-video-transcoder/google/cloud/video/transcoder/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.20.0" # {x-release-please-version} +__version__ = "1.21.0" # {x-release-please-version} diff --git a/packages/google-cloud-video-transcoder/google/cloud/video/transcoder_v1/gapic_version.py b/packages/google-cloud-video-transcoder/google/cloud/video/transcoder_v1/gapic_version.py index c0c0d110e496..95884592d2da 100644 --- a/packages/google-cloud-video-transcoder/google/cloud/video/transcoder_v1/gapic_version.py +++ b/packages/google-cloud-video-transcoder/google/cloud/video/transcoder_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.20.0" # {x-release-please-version} +__version__ = "1.21.0" # {x-release-please-version} diff --git a/packages/google-cloud-video-transcoder/samples/generated_samples/snippet_metadata_google.cloud.video.transcoder.v1.json b/packages/google-cloud-video-transcoder/samples/generated_samples/snippet_metadata_google.cloud.video.transcoder.v1.json index 6ef806e58892..00c215d35e55 100644 --- a/packages/google-cloud-video-transcoder/samples/generated_samples/snippet_metadata_google.cloud.video.transcoder.v1.json +++ b/packages/google-cloud-video-transcoder/samples/generated_samples/snippet_metadata_google.cloud.video.transcoder.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-video-transcoder", - "version": "1.20.0" + "version": "1.21.0" }, "snippets": [ { diff --git a/packages/google-cloud-videointelligence/CHANGELOG.md b/packages/google-cloud-videointelligence/CHANGELOG.md index e0c06c1055a4..b61657a11015 100644 --- a/packages/google-cloud-videointelligence/CHANGELOG.md +++ b/packages/google-cloud-videointelligence/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-videointelligence/#history +## [2.20.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-videointelligence-v2.19.0...google-cloud-videointelligence-v2.20.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8)) + ## [2.19.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-videointelligence-v2.18.0...google-cloud-videointelligence-v2.19.0) (2026-03-26) diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence/gapic_version.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence/gapic_version.py index 72d244c8d156..9bf1072a8834 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence/gapic_version.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.19.0" # {x-release-please-version} +__version__ = "2.20.0" # {x-release-please-version} diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/gapic_version.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/gapic_version.py index 72d244c8d156..9bf1072a8834 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/gapic_version.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.19.0" # {x-release-please-version} +__version__ = "2.20.0" # {x-release-please-version} diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/gapic_version.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/gapic_version.py index 72d244c8d156..9bf1072a8834 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/gapic_version.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.19.0" # {x-release-please-version} +__version__ = "2.20.0" # {x-release-please-version} diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/gapic_version.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/gapic_version.py index 72d244c8d156..9bf1072a8834 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/gapic_version.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.19.0" # {x-release-please-version} +__version__ = "2.20.0" # {x-release-please-version} diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/gapic_version.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/gapic_version.py index 72d244c8d156..9bf1072a8834 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/gapic_version.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.19.0" # {x-release-please-version} +__version__ = "2.20.0" # {x-release-please-version} diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/gapic_version.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/gapic_version.py index 72d244c8d156..9bf1072a8834 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/gapic_version.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.19.0" # {x-release-please-version} +__version__ = "2.20.0" # {x-release-please-version} diff --git a/packages/google-cloud-videointelligence/samples/generated_samples/snippet_metadata_google.cloud.videointelligence.v1.json b/packages/google-cloud-videointelligence/samples/generated_samples/snippet_metadata_google.cloud.videointelligence.v1.json index 1b0a4961fe43..5c3a27f60425 100644 --- a/packages/google-cloud-videointelligence/samples/generated_samples/snippet_metadata_google.cloud.videointelligence.v1.json +++ b/packages/google-cloud-videointelligence/samples/generated_samples/snippet_metadata_google.cloud.videointelligence.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-videointelligence", - "version": "2.19.0" + "version": "2.20.0" }, "snippets": [ { diff --git a/packages/google-cloud-videointelligence/samples/generated_samples/snippet_metadata_google.cloud.videointelligence.v1beta2.json b/packages/google-cloud-videointelligence/samples/generated_samples/snippet_metadata_google.cloud.videointelligence.v1beta2.json index c35d6c7bba67..fb310582d8a0 100644 --- a/packages/google-cloud-videointelligence/samples/generated_samples/snippet_metadata_google.cloud.videointelligence.v1beta2.json +++ b/packages/google-cloud-videointelligence/samples/generated_samples/snippet_metadata_google.cloud.videointelligence.v1beta2.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-videointelligence", - "version": "2.19.0" + "version": "2.20.0" }, "snippets": [ { diff --git a/packages/google-cloud-videointelligence/samples/generated_samples/snippet_metadata_google.cloud.videointelligence.v1p1beta1.json b/packages/google-cloud-videointelligence/samples/generated_samples/snippet_metadata_google.cloud.videointelligence.v1p1beta1.json index 2cd99e5be26c..d6612dd52609 100644 --- a/packages/google-cloud-videointelligence/samples/generated_samples/snippet_metadata_google.cloud.videointelligence.v1p1beta1.json +++ b/packages/google-cloud-videointelligence/samples/generated_samples/snippet_metadata_google.cloud.videointelligence.v1p1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-videointelligence", - "version": "2.19.0" + "version": "2.20.0" }, "snippets": [ { diff --git a/packages/google-cloud-videointelligence/samples/generated_samples/snippet_metadata_google.cloud.videointelligence.v1p2beta1.json b/packages/google-cloud-videointelligence/samples/generated_samples/snippet_metadata_google.cloud.videointelligence.v1p2beta1.json index 9f8969becc56..c861d93037a4 100644 --- a/packages/google-cloud-videointelligence/samples/generated_samples/snippet_metadata_google.cloud.videointelligence.v1p2beta1.json +++ b/packages/google-cloud-videointelligence/samples/generated_samples/snippet_metadata_google.cloud.videointelligence.v1p2beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-videointelligence", - "version": "2.19.0" + "version": "2.20.0" }, "snippets": [ { diff --git a/packages/google-cloud-videointelligence/samples/generated_samples/snippet_metadata_google.cloud.videointelligence.v1p3beta1.json b/packages/google-cloud-videointelligence/samples/generated_samples/snippet_metadata_google.cloud.videointelligence.v1p3beta1.json index 572ad7fb5bf5..926a69c50f00 100644 --- a/packages/google-cloud-videointelligence/samples/generated_samples/snippet_metadata_google.cloud.videointelligence.v1p3beta1.json +++ b/packages/google-cloud-videointelligence/samples/generated_samples/snippet_metadata_google.cloud.videointelligence.v1p3beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-videointelligence", - "version": "2.19.0" + "version": "2.20.0" }, "snippets": [ { diff --git a/packages/google-cloud-vision/CHANGELOG.md b/packages/google-cloud-vision/CHANGELOG.md index 5068ced1e13d..cb4234a502b9 100644 --- a/packages/google-cloud-vision/CHANGELOG.md +++ b/packages/google-cloud-vision/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-vision/#history +## [3.15.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-vision-v3.14.0...google-cloud-vision-v3.15.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8)) + ## [3.14.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-vision-v3.13.0...google-cloud-vision-v3.14.0) (2026-05-06) ## [3.13.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-vision-v3.12.1...google-cloud-vision-v3.13.0) (2026-03-26) diff --git a/packages/google-cloud-vision/google/cloud/vision/gapic_version.py b/packages/google-cloud-vision/google/cloud/vision/gapic_version.py index 51dd69ed928b..34cc96494eaf 100644 --- a/packages/google-cloud-vision/google/cloud/vision/gapic_version.py +++ b/packages/google-cloud-vision/google/cloud/vision/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "3.14.0" # {x-release-please-version} +__version__ = "3.15.0" # {x-release-please-version} diff --git a/packages/google-cloud-vision/google/cloud/vision_v1/gapic_version.py b/packages/google-cloud-vision/google/cloud/vision_v1/gapic_version.py index 51dd69ed928b..34cc96494eaf 100644 --- a/packages/google-cloud-vision/google/cloud/vision_v1/gapic_version.py +++ b/packages/google-cloud-vision/google/cloud/vision_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "3.14.0" # {x-release-please-version} +__version__ = "3.15.0" # {x-release-please-version} diff --git a/packages/google-cloud-vision/google/cloud/vision_v1p1beta1/gapic_version.py b/packages/google-cloud-vision/google/cloud/vision_v1p1beta1/gapic_version.py index 51dd69ed928b..34cc96494eaf 100644 --- a/packages/google-cloud-vision/google/cloud/vision_v1p1beta1/gapic_version.py +++ b/packages/google-cloud-vision/google/cloud/vision_v1p1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "3.14.0" # {x-release-please-version} +__version__ = "3.15.0" # {x-release-please-version} diff --git a/packages/google-cloud-vision/google/cloud/vision_v1p2beta1/gapic_version.py b/packages/google-cloud-vision/google/cloud/vision_v1p2beta1/gapic_version.py index 51dd69ed928b..34cc96494eaf 100644 --- a/packages/google-cloud-vision/google/cloud/vision_v1p2beta1/gapic_version.py +++ b/packages/google-cloud-vision/google/cloud/vision_v1p2beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "3.14.0" # {x-release-please-version} +__version__ = "3.15.0" # {x-release-please-version} diff --git a/packages/google-cloud-vision/google/cloud/vision_v1p3beta1/gapic_version.py b/packages/google-cloud-vision/google/cloud/vision_v1p3beta1/gapic_version.py index 51dd69ed928b..34cc96494eaf 100644 --- a/packages/google-cloud-vision/google/cloud/vision_v1p3beta1/gapic_version.py +++ b/packages/google-cloud-vision/google/cloud/vision_v1p3beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "3.14.0" # {x-release-please-version} +__version__ = "3.15.0" # {x-release-please-version} diff --git a/packages/google-cloud-vision/google/cloud/vision_v1p4beta1/gapic_version.py b/packages/google-cloud-vision/google/cloud/vision_v1p4beta1/gapic_version.py index 51dd69ed928b..34cc96494eaf 100644 --- a/packages/google-cloud-vision/google/cloud/vision_v1p4beta1/gapic_version.py +++ b/packages/google-cloud-vision/google/cloud/vision_v1p4beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "3.14.0" # {x-release-please-version} +__version__ = "3.15.0" # {x-release-please-version} diff --git a/packages/google-cloud-vision/samples/generated_samples/snippet_metadata_google.cloud.vision.v1.json b/packages/google-cloud-vision/samples/generated_samples/snippet_metadata_google.cloud.vision.v1.json index 287dca8b21d9..720e2a4d577d 100644 --- a/packages/google-cloud-vision/samples/generated_samples/snippet_metadata_google.cloud.vision.v1.json +++ b/packages/google-cloud-vision/samples/generated_samples/snippet_metadata_google.cloud.vision.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-vision", - "version": "3.14.0" + "version": "3.15.0" }, "snippets": [ { diff --git a/packages/google-cloud-vision/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p1beta1.json b/packages/google-cloud-vision/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p1beta1.json index de1ba035b173..4a33e4264b60 100644 --- a/packages/google-cloud-vision/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p1beta1.json +++ b/packages/google-cloud-vision/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-vision", - "version": "3.14.0" + "version": "3.15.0" }, "snippets": [ { diff --git a/packages/google-cloud-vision/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p2beta1.json b/packages/google-cloud-vision/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p2beta1.json index 49efb3ba26b1..2fe0af083b92 100644 --- a/packages/google-cloud-vision/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p2beta1.json +++ b/packages/google-cloud-vision/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p2beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-vision", - "version": "3.14.0" + "version": "3.15.0" }, "snippets": [ { diff --git a/packages/google-cloud-vision/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p3beta1.json b/packages/google-cloud-vision/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p3beta1.json index fb43710c1e36..75b9139094f7 100644 --- a/packages/google-cloud-vision/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p3beta1.json +++ b/packages/google-cloud-vision/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p3beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-vision", - "version": "3.14.0" + "version": "3.15.0" }, "snippets": [ { diff --git a/packages/google-cloud-vision/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p4beta1.json b/packages/google-cloud-vision/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p4beta1.json index 99ad698444b0..4f6c6588db3a 100644 --- a/packages/google-cloud-vision/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p4beta1.json +++ b/packages/google-cloud-vision/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p4beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-vision", - "version": "3.14.0" + "version": "3.15.0" }, "snippets": [ { diff --git a/packages/google-cloud-visionai/CHANGELOG.md b/packages/google-cloud-visionai/CHANGELOG.md index 3a13350ea1a6..bb4823c42aa5 100644 --- a/packages/google-cloud-visionai/CHANGELOG.md +++ b/packages/google-cloud-visionai/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-visionai/#history +## [0.5.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-visionai-v0.5.0...google-cloud-visionai-v0.5.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8)) + ## [0.5.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-visionai-v0.4.0...google-cloud-visionai-v0.5.0) (2026-03-26) diff --git a/packages/google-cloud-visionai/google/cloud/visionai/gapic_version.py b/packages/google-cloud-visionai/google/cloud/visionai/gapic_version.py index 7d9863d19611..acc458e7fa6f 100644 --- a/packages/google-cloud-visionai/google/cloud/visionai/gapic_version.py +++ b/packages/google-cloud-visionai/google/cloud/visionai/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.5.0" # {x-release-please-version} +__version__ = "0.5.1" # {x-release-please-version} diff --git a/packages/google-cloud-visionai/google/cloud/visionai_v1/gapic_version.py b/packages/google-cloud-visionai/google/cloud/visionai_v1/gapic_version.py index 7d9863d19611..acc458e7fa6f 100644 --- a/packages/google-cloud-visionai/google/cloud/visionai_v1/gapic_version.py +++ b/packages/google-cloud-visionai/google/cloud/visionai_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.5.0" # {x-release-please-version} +__version__ = "0.5.1" # {x-release-please-version} diff --git a/packages/google-cloud-visionai/google/cloud/visionai_v1alpha1/gapic_version.py b/packages/google-cloud-visionai/google/cloud/visionai_v1alpha1/gapic_version.py index 7d9863d19611..acc458e7fa6f 100644 --- a/packages/google-cloud-visionai/google/cloud/visionai_v1alpha1/gapic_version.py +++ b/packages/google-cloud-visionai/google/cloud/visionai_v1alpha1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.5.0" # {x-release-please-version} +__version__ = "0.5.1" # {x-release-please-version} diff --git a/packages/google-cloud-visionai/samples/generated_samples/snippet_metadata_google.cloud.visionai.v1.json b/packages/google-cloud-visionai/samples/generated_samples/snippet_metadata_google.cloud.visionai.v1.json index 68ae1a3e592f..47efac5a3354 100644 --- a/packages/google-cloud-visionai/samples/generated_samples/snippet_metadata_google.cloud.visionai.v1.json +++ b/packages/google-cloud-visionai/samples/generated_samples/snippet_metadata_google.cloud.visionai.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-visionai", - "version": "0.5.0" + "version": "0.5.1" }, "snippets": [ { diff --git a/packages/google-cloud-visionai/samples/generated_samples/snippet_metadata_google.cloud.visionai.v1alpha1.json b/packages/google-cloud-visionai/samples/generated_samples/snippet_metadata_google.cloud.visionai.v1alpha1.json index 965e0a197601..110418946eac 100644 --- a/packages/google-cloud-visionai/samples/generated_samples/snippet_metadata_google.cloud.visionai.v1alpha1.json +++ b/packages/google-cloud-visionai/samples/generated_samples/snippet_metadata_google.cloud.visionai.v1alpha1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-visionai", - "version": "0.5.0" + "version": "0.5.1" }, "snippets": [ { diff --git a/packages/google-cloud-vm-migration/CHANGELOG.md b/packages/google-cloud-vm-migration/CHANGELOG.md index 60d37241c4c9..76ae431c535f 100644 --- a/packages/google-cloud-vm-migration/CHANGELOG.md +++ b/packages/google-cloud-vm-migration/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-vm-migration/#history +## [1.17.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-vm-migration-v1.16.0...google-cloud-vm-migration-v1.17.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8)) + ## [1.16.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-vm-migration-v1.15.0...google-cloud-vm-migration-v1.16.0) (2026-03-26) diff --git a/packages/google-cloud-vm-migration/google/cloud/vmmigration/gapic_version.py b/packages/google-cloud-vm-migration/google/cloud/vmmigration/gapic_version.py index 14edf824ad86..2095da2522f4 100644 --- a/packages/google-cloud-vm-migration/google/cloud/vmmigration/gapic_version.py +++ b/packages/google-cloud-vm-migration/google/cloud/vmmigration/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.16.0" # {x-release-please-version} +__version__ = "1.17.0" # {x-release-please-version} diff --git a/packages/google-cloud-vm-migration/google/cloud/vmmigration_v1/gapic_version.py b/packages/google-cloud-vm-migration/google/cloud/vmmigration_v1/gapic_version.py index 14edf824ad86..2095da2522f4 100644 --- a/packages/google-cloud-vm-migration/google/cloud/vmmigration_v1/gapic_version.py +++ b/packages/google-cloud-vm-migration/google/cloud/vmmigration_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.16.0" # {x-release-please-version} +__version__ = "1.17.0" # {x-release-please-version} diff --git a/packages/google-cloud-vm-migration/samples/generated_samples/snippet_metadata_google.cloud.vmmigration.v1.json b/packages/google-cloud-vm-migration/samples/generated_samples/snippet_metadata_google.cloud.vmmigration.v1.json index 69d2492fc1af..63c7d1890c2b 100644 --- a/packages/google-cloud-vm-migration/samples/generated_samples/snippet_metadata_google.cloud.vmmigration.v1.json +++ b/packages/google-cloud-vm-migration/samples/generated_samples/snippet_metadata_google.cloud.vmmigration.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-vm-migration", - "version": "1.16.0" + "version": "1.17.0" }, "snippets": [ { diff --git a/packages/google-cloud-vmwareengine/CHANGELOG.md b/packages/google-cloud-vmwareengine/CHANGELOG.md index 5bd000500535..e2421eda1e7b 100644 --- a/packages/google-cloud-vmwareengine/CHANGELOG.md +++ b/packages/google-cloud-vmwareengine/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-vmwareengine/#history +## [1.12.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-vmwareengine-v1.11.0...google-cloud-vmwareengine-v1.12.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8)) + ## [1.11.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-vmwareengine-v1.10.0...google-cloud-vmwareengine-v1.11.0) (2026-03-26) diff --git a/packages/google-cloud-vmwareengine/google/cloud/vmwareengine/gapic_version.py b/packages/google-cloud-vmwareengine/google/cloud/vmwareengine/gapic_version.py index e456ff485676..6b2f9ca0653a 100644 --- a/packages/google-cloud-vmwareengine/google/cloud/vmwareengine/gapic_version.py +++ b/packages/google-cloud-vmwareengine/google/cloud/vmwareengine/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.11.0" # {x-release-please-version} +__version__ = "1.12.0" # {x-release-please-version} diff --git a/packages/google-cloud-vmwareengine/google/cloud/vmwareengine_v1/gapic_version.py b/packages/google-cloud-vmwareengine/google/cloud/vmwareengine_v1/gapic_version.py index e456ff485676..6b2f9ca0653a 100644 --- a/packages/google-cloud-vmwareengine/google/cloud/vmwareengine_v1/gapic_version.py +++ b/packages/google-cloud-vmwareengine/google/cloud/vmwareengine_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.11.0" # {x-release-please-version} +__version__ = "1.12.0" # {x-release-please-version} diff --git a/packages/google-cloud-vmwareengine/samples/generated_samples/snippet_metadata_google.cloud.vmwareengine.v1.json b/packages/google-cloud-vmwareengine/samples/generated_samples/snippet_metadata_google.cloud.vmwareengine.v1.json index f5e4ce2ac7b5..1a5ca2ad5938 100644 --- a/packages/google-cloud-vmwareengine/samples/generated_samples/snippet_metadata_google.cloud.vmwareengine.v1.json +++ b/packages/google-cloud-vmwareengine/samples/generated_samples/snippet_metadata_google.cloud.vmwareengine.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-vmwareengine", - "version": "1.11.0" + "version": "1.12.0" }, "snippets": [ { diff --git a/packages/google-cloud-vpc-access/CHANGELOG.md b/packages/google-cloud-vpc-access/CHANGELOG.md index e672aef2d0b6..29f00c378dc9 100644 --- a/packages/google-cloud-vpc-access/CHANGELOG.md +++ b/packages/google-cloud-vpc-access/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-vpc-access/#history +## [1.17.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-vpc-access-v1.16.0...google-cloud-vpc-access-v1.17.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8)) + ## [1.16.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-vpc-access-v1.15.0...google-cloud-vpc-access-v1.16.0) (2026-03-26) diff --git a/packages/google-cloud-vpc-access/google/cloud/vpcaccess/gapic_version.py b/packages/google-cloud-vpc-access/google/cloud/vpcaccess/gapic_version.py index 14edf824ad86..2095da2522f4 100644 --- a/packages/google-cloud-vpc-access/google/cloud/vpcaccess/gapic_version.py +++ b/packages/google-cloud-vpc-access/google/cloud/vpcaccess/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.16.0" # {x-release-please-version} +__version__ = "1.17.0" # {x-release-please-version} diff --git a/packages/google-cloud-vpc-access/google/cloud/vpcaccess_v1/gapic_version.py b/packages/google-cloud-vpc-access/google/cloud/vpcaccess_v1/gapic_version.py index 14edf824ad86..2095da2522f4 100644 --- a/packages/google-cloud-vpc-access/google/cloud/vpcaccess_v1/gapic_version.py +++ b/packages/google-cloud-vpc-access/google/cloud/vpcaccess_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.16.0" # {x-release-please-version} +__version__ = "1.17.0" # {x-release-please-version} diff --git a/packages/google-cloud-vpc-access/samples/generated_samples/snippet_metadata_google.cloud.vpcaccess.v1.json b/packages/google-cloud-vpc-access/samples/generated_samples/snippet_metadata_google.cloud.vpcaccess.v1.json index ec60a049ed8c..f17bf2e87466 100644 --- a/packages/google-cloud-vpc-access/samples/generated_samples/snippet_metadata_google.cloud.vpcaccess.v1.json +++ b/packages/google-cloud-vpc-access/samples/generated_samples/snippet_metadata_google.cloud.vpcaccess.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-vpc-access", - "version": "1.16.0" + "version": "1.17.0" }, "snippets": [ { diff --git a/packages/google-cloud-webrisk/CHANGELOG.md b/packages/google-cloud-webrisk/CHANGELOG.md index af4637505d6b..86d9f92d46b6 100644 --- a/packages/google-cloud-webrisk/CHANGELOG.md +++ b/packages/google-cloud-webrisk/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-webrisk/#history +## [1.22.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-webrisk-v1.21.0...google-cloud-webrisk-v1.22.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8)) + ## [1.21.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-webrisk-v1.20.0...google-cloud-webrisk-v1.21.0) (2026-03-26) diff --git a/packages/google-cloud-webrisk/google/cloud/webrisk/gapic_version.py b/packages/google-cloud-webrisk/google/cloud/webrisk/gapic_version.py index 95884592d2da..a2e7c5e892a1 100644 --- a/packages/google-cloud-webrisk/google/cloud/webrisk/gapic_version.py +++ b/packages/google-cloud-webrisk/google/cloud/webrisk/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.21.0" # {x-release-please-version} +__version__ = "1.22.0" # {x-release-please-version} diff --git a/packages/google-cloud-webrisk/google/cloud/webrisk_v1/gapic_version.py b/packages/google-cloud-webrisk/google/cloud/webrisk_v1/gapic_version.py index 95884592d2da..a2e7c5e892a1 100644 --- a/packages/google-cloud-webrisk/google/cloud/webrisk_v1/gapic_version.py +++ b/packages/google-cloud-webrisk/google/cloud/webrisk_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.21.0" # {x-release-please-version} +__version__ = "1.22.0" # {x-release-please-version} diff --git a/packages/google-cloud-webrisk/google/cloud/webrisk_v1beta1/gapic_version.py b/packages/google-cloud-webrisk/google/cloud/webrisk_v1beta1/gapic_version.py index 95884592d2da..a2e7c5e892a1 100644 --- a/packages/google-cloud-webrisk/google/cloud/webrisk_v1beta1/gapic_version.py +++ b/packages/google-cloud-webrisk/google/cloud/webrisk_v1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.21.0" # {x-release-please-version} +__version__ = "1.22.0" # {x-release-please-version} diff --git a/packages/google-cloud-webrisk/samples/generated_samples/snippet_metadata_google.cloud.webrisk.v1.json b/packages/google-cloud-webrisk/samples/generated_samples/snippet_metadata_google.cloud.webrisk.v1.json index 8b6309a5aa73..1a1140b0a36d 100644 --- a/packages/google-cloud-webrisk/samples/generated_samples/snippet_metadata_google.cloud.webrisk.v1.json +++ b/packages/google-cloud-webrisk/samples/generated_samples/snippet_metadata_google.cloud.webrisk.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-webrisk", - "version": "1.21.0" + "version": "1.22.0" }, "snippets": [ { diff --git a/packages/google-cloud-webrisk/samples/generated_samples/snippet_metadata_google.cloud.webrisk.v1beta1.json b/packages/google-cloud-webrisk/samples/generated_samples/snippet_metadata_google.cloud.webrisk.v1beta1.json index 9a533ff61137..8b1f037a2e7e 100644 --- a/packages/google-cloud-webrisk/samples/generated_samples/snippet_metadata_google.cloud.webrisk.v1beta1.json +++ b/packages/google-cloud-webrisk/samples/generated_samples/snippet_metadata_google.cloud.webrisk.v1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-webrisk", - "version": "1.21.0" + "version": "1.22.0" }, "snippets": [ { diff --git a/packages/google-cloud-websecurityscanner/CHANGELOG.md b/packages/google-cloud-websecurityscanner/CHANGELOG.md index 54198fe1efba..b7822cd1f0e5 100644 --- a/packages/google-cloud-websecurityscanner/CHANGELOG.md +++ b/packages/google-cloud-websecurityscanner/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-websecurityscanner/#history +## [1.21.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-websecurityscanner-v1.20.0...google-cloud-websecurityscanner-v1.21.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8)) + ## [1.20.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-websecurityscanner-v1.19.0...google-cloud-websecurityscanner-v1.20.0) (2026-03-26) diff --git a/packages/google-cloud-websecurityscanner/google/cloud/websecurityscanner/gapic_version.py b/packages/google-cloud-websecurityscanner/google/cloud/websecurityscanner/gapic_version.py index c0c0d110e496..95884592d2da 100644 --- a/packages/google-cloud-websecurityscanner/google/cloud/websecurityscanner/gapic_version.py +++ b/packages/google-cloud-websecurityscanner/google/cloud/websecurityscanner/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.20.0" # {x-release-please-version} +__version__ = "1.21.0" # {x-release-please-version} diff --git a/packages/google-cloud-websecurityscanner/google/cloud/websecurityscanner_v1/gapic_version.py b/packages/google-cloud-websecurityscanner/google/cloud/websecurityscanner_v1/gapic_version.py index c0c0d110e496..95884592d2da 100644 --- a/packages/google-cloud-websecurityscanner/google/cloud/websecurityscanner_v1/gapic_version.py +++ b/packages/google-cloud-websecurityscanner/google/cloud/websecurityscanner_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.20.0" # {x-release-please-version} +__version__ = "1.21.0" # {x-release-please-version} diff --git a/packages/google-cloud-websecurityscanner/google/cloud/websecurityscanner_v1alpha/gapic_version.py b/packages/google-cloud-websecurityscanner/google/cloud/websecurityscanner_v1alpha/gapic_version.py index c0c0d110e496..95884592d2da 100644 --- a/packages/google-cloud-websecurityscanner/google/cloud/websecurityscanner_v1alpha/gapic_version.py +++ b/packages/google-cloud-websecurityscanner/google/cloud/websecurityscanner_v1alpha/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.20.0" # {x-release-please-version} +__version__ = "1.21.0" # {x-release-please-version} diff --git a/packages/google-cloud-websecurityscanner/google/cloud/websecurityscanner_v1beta/gapic_version.py b/packages/google-cloud-websecurityscanner/google/cloud/websecurityscanner_v1beta/gapic_version.py index c0c0d110e496..95884592d2da 100644 --- a/packages/google-cloud-websecurityscanner/google/cloud/websecurityscanner_v1beta/gapic_version.py +++ b/packages/google-cloud-websecurityscanner/google/cloud/websecurityscanner_v1beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.20.0" # {x-release-please-version} +__version__ = "1.21.0" # {x-release-please-version} diff --git a/packages/google-cloud-websecurityscanner/samples/generated_samples/snippet_metadata_google.cloud.websecurityscanner.v1.json b/packages/google-cloud-websecurityscanner/samples/generated_samples/snippet_metadata_google.cloud.websecurityscanner.v1.json index 9b377655ea0f..56c86d31f747 100644 --- a/packages/google-cloud-websecurityscanner/samples/generated_samples/snippet_metadata_google.cloud.websecurityscanner.v1.json +++ b/packages/google-cloud-websecurityscanner/samples/generated_samples/snippet_metadata_google.cloud.websecurityscanner.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-websecurityscanner", - "version": "1.20.0" + "version": "1.21.0" }, "snippets": [ { diff --git a/packages/google-cloud-websecurityscanner/samples/generated_samples/snippet_metadata_google.cloud.websecurityscanner.v1alpha.json b/packages/google-cloud-websecurityscanner/samples/generated_samples/snippet_metadata_google.cloud.websecurityscanner.v1alpha.json index 29c219592e96..1a575cf0d91a 100644 --- a/packages/google-cloud-websecurityscanner/samples/generated_samples/snippet_metadata_google.cloud.websecurityscanner.v1alpha.json +++ b/packages/google-cloud-websecurityscanner/samples/generated_samples/snippet_metadata_google.cloud.websecurityscanner.v1alpha.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-websecurityscanner", - "version": "1.20.0" + "version": "1.21.0" }, "snippets": [ { diff --git a/packages/google-cloud-websecurityscanner/samples/generated_samples/snippet_metadata_google.cloud.websecurityscanner.v1beta.json b/packages/google-cloud-websecurityscanner/samples/generated_samples/snippet_metadata_google.cloud.websecurityscanner.v1beta.json index c49bd35b5c22..fc791d0e2fb4 100644 --- a/packages/google-cloud-websecurityscanner/samples/generated_samples/snippet_metadata_google.cloud.websecurityscanner.v1beta.json +++ b/packages/google-cloud-websecurityscanner/samples/generated_samples/snippet_metadata_google.cloud.websecurityscanner.v1beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-websecurityscanner", - "version": "1.20.0" + "version": "1.21.0" }, "snippets": [ { diff --git a/packages/google-cloud-workflows/CHANGELOG.md b/packages/google-cloud-workflows/CHANGELOG.md index 54b5336a5c8c..c1202daa1ef4 100644 --- a/packages/google-cloud-workflows/CHANGELOG.md +++ b/packages/google-cloud-workflows/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-workflows/#history +## [1.23.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-workflows-v1.22.0...google-cloud-workflows-v1.23.0) (2026-06-22) + + +### Features + +* regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8)) + ## [1.22.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-workflows-v1.21.0...google-cloud-workflows-v1.22.0) (2026-05-06) ## [1.21.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-workflows-v1.20.0...google-cloud-workflows-v1.21.0) (2026-03-26) diff --git a/packages/google-cloud-workflows/google/cloud/workflows/executions/gapic_version.py b/packages/google-cloud-workflows/google/cloud/workflows/executions/gapic_version.py index a2e7c5e892a1..7fc0c295471b 100644 --- a/packages/google-cloud-workflows/google/cloud/workflows/executions/gapic_version.py +++ b/packages/google-cloud-workflows/google/cloud/workflows/executions/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.22.0" # {x-release-please-version} +__version__ = "1.23.0" # {x-release-please-version} diff --git a/packages/google-cloud-workflows/google/cloud/workflows/executions_v1/gapic_version.py b/packages/google-cloud-workflows/google/cloud/workflows/executions_v1/gapic_version.py index a2e7c5e892a1..7fc0c295471b 100644 --- a/packages/google-cloud-workflows/google/cloud/workflows/executions_v1/gapic_version.py +++ b/packages/google-cloud-workflows/google/cloud/workflows/executions_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.22.0" # {x-release-please-version} +__version__ = "1.23.0" # {x-release-please-version} diff --git a/packages/google-cloud-workflows/google/cloud/workflows/executions_v1beta/gapic_version.py b/packages/google-cloud-workflows/google/cloud/workflows/executions_v1beta/gapic_version.py index a2e7c5e892a1..7fc0c295471b 100644 --- a/packages/google-cloud-workflows/google/cloud/workflows/executions_v1beta/gapic_version.py +++ b/packages/google-cloud-workflows/google/cloud/workflows/executions_v1beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.22.0" # {x-release-please-version} +__version__ = "1.23.0" # {x-release-please-version} diff --git a/packages/google-cloud-workflows/google/cloud/workflows/gapic_version.py b/packages/google-cloud-workflows/google/cloud/workflows/gapic_version.py index a2e7c5e892a1..7fc0c295471b 100644 --- a/packages/google-cloud-workflows/google/cloud/workflows/gapic_version.py +++ b/packages/google-cloud-workflows/google/cloud/workflows/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.22.0" # {x-release-please-version} +__version__ = "1.23.0" # {x-release-please-version} diff --git a/packages/google-cloud-workflows/google/cloud/workflows_v1/gapic_version.py b/packages/google-cloud-workflows/google/cloud/workflows_v1/gapic_version.py index a2e7c5e892a1..7fc0c295471b 100644 --- a/packages/google-cloud-workflows/google/cloud/workflows_v1/gapic_version.py +++ b/packages/google-cloud-workflows/google/cloud/workflows_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.22.0" # {x-release-please-version} +__version__ = "1.23.0" # {x-release-please-version} diff --git a/packages/google-cloud-workflows/google/cloud/workflows_v1beta/gapic_version.py b/packages/google-cloud-workflows/google/cloud/workflows_v1beta/gapic_version.py index a2e7c5e892a1..7fc0c295471b 100644 --- a/packages/google-cloud-workflows/google/cloud/workflows_v1beta/gapic_version.py +++ b/packages/google-cloud-workflows/google/cloud/workflows_v1beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.22.0" # {x-release-please-version} +__version__ = "1.23.0" # {x-release-please-version} diff --git a/packages/google-cloud-workflows/samples/generated_samples/snippet_metadata_google.cloud.workflows.executions.v1.json b/packages/google-cloud-workflows/samples/generated_samples/snippet_metadata_google.cloud.workflows.executions.v1.json index 13d1c8f16487..fb19fb0572c3 100644 --- a/packages/google-cloud-workflows/samples/generated_samples/snippet_metadata_google.cloud.workflows.executions.v1.json +++ b/packages/google-cloud-workflows/samples/generated_samples/snippet_metadata_google.cloud.workflows.executions.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-workflows", - "version": "1.22.0" + "version": "1.23.0" }, "snippets": [ { diff --git a/packages/google-cloud-workflows/samples/generated_samples/snippet_metadata_google.cloud.workflows.executions.v1beta.json b/packages/google-cloud-workflows/samples/generated_samples/snippet_metadata_google.cloud.workflows.executions.v1beta.json index 8a3a26edc0ba..0b2f2bde2a06 100644 --- a/packages/google-cloud-workflows/samples/generated_samples/snippet_metadata_google.cloud.workflows.executions.v1beta.json +++ b/packages/google-cloud-workflows/samples/generated_samples/snippet_metadata_google.cloud.workflows.executions.v1beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-workflows", - "version": "1.22.0" + "version": "1.23.0" }, "snippets": [ { diff --git a/packages/google-cloud-workflows/samples/generated_samples/snippet_metadata_google.cloud.workflows.v1.json b/packages/google-cloud-workflows/samples/generated_samples/snippet_metadata_google.cloud.workflows.v1.json index eb63d4939813..19f2ec149fe0 100644 --- a/packages/google-cloud-workflows/samples/generated_samples/snippet_metadata_google.cloud.workflows.v1.json +++ b/packages/google-cloud-workflows/samples/generated_samples/snippet_metadata_google.cloud.workflows.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-workflows", - "version": "1.22.0" + "version": "1.23.0" }, "snippets": [ { diff --git a/packages/google-cloud-workflows/samples/generated_samples/snippet_metadata_google.cloud.workflows.v1beta.json b/packages/google-cloud-workflows/samples/generated_samples/snippet_metadata_google.cloud.workflows.v1beta.json index 68c7a1d44a66..b0f6ba07ba99 100644 --- a/packages/google-cloud-workflows/samples/generated_samples/snippet_metadata_google.cloud.workflows.v1beta.json +++ b/packages/google-cloud-workflows/samples/generated_samples/snippet_metadata_google.cloud.workflows.v1beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-workflows", - "version": "1.22.0" + "version": "1.23.0" }, "snippets": [ { diff --git a/packages/google-cloud-workloadmanager/CHANGELOG.md b/packages/google-cloud-workloadmanager/CHANGELOG.md index 6436ee1a2466..4baf849375e9 100644 --- a/packages/google-cloud-workloadmanager/CHANGELOG.md +++ b/packages/google-cloud-workloadmanager/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-workloadmanager/#history +## [0.2.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-workloadmanager-v0.2.0...google-cloud-workloadmanager-v0.2.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8)) + ## [0.2.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-workloadmanager-v0.1.0...google-cloud-workloadmanager-v0.2.0) (2026-03-26) diff --git a/packages/google-cloud-workloadmanager/google/cloud/workloadmanager/gapic_version.py b/packages/google-cloud-workloadmanager/google/cloud/workloadmanager/gapic_version.py index 93d81c18b4c8..f6285c6fae9e 100644 --- a/packages/google-cloud-workloadmanager/google/cloud/workloadmanager/gapic_version.py +++ b/packages/google-cloud-workloadmanager/google/cloud/workloadmanager/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.2.0" # {x-release-please-version} +__version__ = "0.2.1" # {x-release-please-version} diff --git a/packages/google-cloud-workloadmanager/google/cloud/workloadmanager_v1/gapic_version.py b/packages/google-cloud-workloadmanager/google/cloud/workloadmanager_v1/gapic_version.py index 93d81c18b4c8..f6285c6fae9e 100644 --- a/packages/google-cloud-workloadmanager/google/cloud/workloadmanager_v1/gapic_version.py +++ b/packages/google-cloud-workloadmanager/google/cloud/workloadmanager_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.2.0" # {x-release-please-version} +__version__ = "0.2.1" # {x-release-please-version} diff --git a/packages/google-cloud-workloadmanager/samples/generated_samples/snippet_metadata_google.cloud.workloadmanager.v1.json b/packages/google-cloud-workloadmanager/samples/generated_samples/snippet_metadata_google.cloud.workloadmanager.v1.json index 9d8237e14eb6..b92ba15d34a8 100644 --- a/packages/google-cloud-workloadmanager/samples/generated_samples/snippet_metadata_google.cloud.workloadmanager.v1.json +++ b/packages/google-cloud-workloadmanager/samples/generated_samples/snippet_metadata_google.cloud.workloadmanager.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-workloadmanager", - "version": "0.2.0" + "version": "0.2.1" }, "snippets": [ { diff --git a/packages/google-cloud-workstations/CHANGELOG.md b/packages/google-cloud-workstations/CHANGELOG.md index 3b033628fc99..283b0bf865be 100644 --- a/packages/google-cloud-workstations/CHANGELOG.md +++ b/packages/google-cloud-workstations/CHANGELOG.md @@ -4,6 +4,14 @@ [1]: https://pypi.org/project/google-cloud-workstations/#history +## [0.8.1](https://github.com/googleapis/google-cloud-python/compare/google-cloud-workstations-v0.8.0...google-cloud-workstations-v0.8.1) (2026-06-22) + + +### Features + +* regenerate google-cloud-[t-w] packages ([#17076](https://github.com/googleapis/google-cloud-python/issues/17076)) ([928a03c](https://github.com/googleapis/google-cloud-python/commit/928a03ce41fbcb82398636e89f840c00c7749cf8)) +* update googleapis and regenerate ([33ba3af](https://github.com/googleapis/google-cloud-python/commit/33ba3afe520e2f64ac7464f1b4ee31c0624a65ac)) + ## [0.8.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-workstations-v0.7.0...google-cloud-workstations-v0.8.0) (2026-03-26) diff --git a/packages/google-cloud-workstations/google/cloud/workstations/gapic_version.py b/packages/google-cloud-workstations/google/cloud/workstations/gapic_version.py index ed31d4798409..af283a821985 100644 --- a/packages/google-cloud-workstations/google/cloud/workstations/gapic_version.py +++ b/packages/google-cloud-workstations/google/cloud/workstations/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.8.0" # {x-release-please-version} +__version__ = "0.8.1" # {x-release-please-version} diff --git a/packages/google-cloud-workstations/google/cloud/workstations_v1/gapic_version.py b/packages/google-cloud-workstations/google/cloud/workstations_v1/gapic_version.py index ed31d4798409..af283a821985 100644 --- a/packages/google-cloud-workstations/google/cloud/workstations_v1/gapic_version.py +++ b/packages/google-cloud-workstations/google/cloud/workstations_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.8.0" # {x-release-please-version} +__version__ = "0.8.1" # {x-release-please-version} diff --git a/packages/google-cloud-workstations/google/cloud/workstations_v1beta/gapic_version.py b/packages/google-cloud-workstations/google/cloud/workstations_v1beta/gapic_version.py index ed31d4798409..af283a821985 100644 --- a/packages/google-cloud-workstations/google/cloud/workstations_v1beta/gapic_version.py +++ b/packages/google-cloud-workstations/google/cloud/workstations_v1beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.8.0" # {x-release-please-version} +__version__ = "0.8.1" # {x-release-please-version} diff --git a/packages/google-cloud-workstations/samples/generated_samples/snippet_metadata_google.cloud.workstations.v1.json b/packages/google-cloud-workstations/samples/generated_samples/snippet_metadata_google.cloud.workstations.v1.json index 6692e9a17f09..e75573328e9c 100644 --- a/packages/google-cloud-workstations/samples/generated_samples/snippet_metadata_google.cloud.workstations.v1.json +++ b/packages/google-cloud-workstations/samples/generated_samples/snippet_metadata_google.cloud.workstations.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-workstations", - "version": "0.8.0" + "version": "0.8.1" }, "snippets": [ { diff --git a/packages/google-cloud-workstations/samples/generated_samples/snippet_metadata_google.cloud.workstations.v1beta.json b/packages/google-cloud-workstations/samples/generated_samples/snippet_metadata_google.cloud.workstations.v1beta.json index 39c427311dce..55f1321ec4d7 100644 --- a/packages/google-cloud-workstations/samples/generated_samples/snippet_metadata_google.cloud.workstations.v1beta.json +++ b/packages/google-cloud-workstations/samples/generated_samples/snippet_metadata_google.cloud.workstations.v1beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-workstations", - "version": "0.8.0" + "version": "0.8.1" }, "snippets": [ { From 204667b1ee39241111c4bf2ea9bc016ae86bc754 Mon Sep 17 00:00:00 2001 From: Chalmer Lowe Date: Tue, 23 Jun 2026 12:23:24 -0400 Subject: [PATCH 112/174] chore(version-scanner): configure GHA to use targets file for multi-version scanning (#17538) This PR configures the Automated Dependency Version Scanner GHA workflow to use a YAML targets file instead of hardcoded dependency/version parameters, and limits scanning to the 31 handwritten and hybrid packages for speed. --- .github/workflows/version_scanner.yml | 2 +- .../example-list-non-generated-packages.txt | 31 ++++++++++ scripts/version_scanner/matrix.yaml | 4 ++ .../version_scanner/small_package_list.txt | 6 -- .../tests/unit/test_version_scanner.py | 43 +++++++++++--- scripts/version_scanner/version_scanner.py | 57 ++++++++++--------- 6 files changed, 101 insertions(+), 42 deletions(-) create mode 100644 scripts/version_scanner/example-list-non-generated-packages.txt create mode 100644 scripts/version_scanner/matrix.yaml delete mode 100644 scripts/version_scanner/small_package_list.txt diff --git a/.github/workflows/version_scanner.yml b/.github/workflows/version_scanner.yml index 52f813e67995..078e4259e491 100644 --- a/.github/workflows/version_scanner.yml +++ b/.github/workflows/version_scanner.yml @@ -35,7 +35,7 @@ jobs: # Uses -o to output a detailed, raw CSV to a file # Uses --stdout to print a slim, easier to parse summary to the GitHub Actions UI # Uses --soft-fail to temporarily limit causing CI/CD failures during the migration to full operation. - python scripts/version_scanner/version_scanner.py -d python -v 3.7 --stdout -o version_scanner_output.csv --soft-fail + python scripts/version_scanner/version_scanner.py --matrix-file scripts/version_scanner/matrix.yaml --package-file scripts/version_scanner/example-list-non-generated-packages.txt --stdout -o version_scanner_output.csv --soft-fail - name: Upload CSV Results if: always() diff --git a/scripts/version_scanner/example-list-non-generated-packages.txt b/scripts/version_scanner/example-list-non-generated-packages.txt new file mode 100644 index 000000000000..bfc1e3fe8658 --- /dev/null +++ b/scripts/version_scanner/example-list-non-generated-packages.txt @@ -0,0 +1,31 @@ +packages/bigframes +packages/bigquery-magics +packages/db-dtypes +packages/django-google-spanner +packages/gapic-generator +packages/google-api-core +# packages/google-api-python-client # non-monorepo, ignore for now. +packages/google-auth +packages/google-auth-httplib2 +packages/google-auth-oauthlib +packages/google-cloud-bigquery +packages/pandas-gbq +packages/google-cloud-bigtable +packages/google-cloud-core +packages/google-crc32c +packages/google-cloud-datastore +packages/google-cloud-dns +packages/google-cloud-documentai-toolbox +packages/google-cloud-error-reporting +packages/google-cloud-firestore +packages/google-cloud-logging +packages/google-cloud-ndb +packages/google-cloud-pubsub +packages/google-cloud-runtimeconfig +packages/google-cloud-spanner +packages/google-cloud-storage +packages/google-cloud-testutils +packages/google-resumable-media +packages/proto-plus +packages/sqlalchemy-bigquery +packages/sqlalchemy-spanner diff --git a/scripts/version_scanner/matrix.yaml b/scripts/version_scanner/matrix.yaml new file mode 100644 index 000000000000..0f50b31fd48f --- /dev/null +++ b/scripts/version_scanner/matrix.yaml @@ -0,0 +1,4 @@ +python: + - "3.7" + - "3.8" + - "3.9" diff --git a/scripts/version_scanner/small_package_list.txt b/scripts/version_scanner/small_package_list.txt deleted file mode 100644 index 8c9a4f39e879..000000000000 --- a/scripts/version_scanner/small_package_list.txt +++ /dev/null @@ -1,6 +0,0 @@ -# Example package list for filtering scanning targets via the --package-file option. -packages/google-cloud-access-context-manager -packages/google-cloud-bigtable -packages/google-cloud-biglake-hive -packages/google-cloud-documentai-toolbox -packages/google-cloud-core diff --git a/scripts/version_scanner/tests/unit/test_version_scanner.py b/scripts/version_scanner/tests/unit/test_version_scanner.py index 054df22421bc..a151c1c55e11 100644 --- a/scripts/version_scanner/tests/unit/test_version_scanner.py +++ b/scripts/version_scanner/tests/unit/test_version_scanner.py @@ -59,6 +59,8 @@ def sample_match(): (PermissionError(), False, False, False, "Warning: Permission denied reading test_desc", None), # Optional PermissionError (IOError("disk full"), True, False, True, "Error reading test_desc", None), # Required IOError (IOError("disk full"), False, False, False, "Warning: Error reading test_desc", None), # Optional IOError + (ValueError("invalid bytes"), True, False, True, "Error reading test_desc", None), # Required ValueError + (ValueError("invalid bytes"), False, False, False, "Warning: Error reading test_desc", None), # Optional ValueError ] ) def test_safe_read_file_scenarios( @@ -782,16 +784,16 @@ def test_format_for_console(sample_match): assert "python_requires = " not in log_str # Slim format doesn't print context line -def test_parse_targets_file(tmp_path): - from version_scanner import parse_targets_file - yaml_file = tmp_path / "targets.yaml" +def test_parse_matrix_file(tmp_path): + from version_scanner import parse_matrix_file + yaml_file = tmp_path / "matrix.yaml" yaml_file.write_text(""" python: - "3.7" - "3.8" protobuf: "4.25.8" """) - targets = parse_targets_file(str(yaml_file)) + targets = parse_matrix_file(str(yaml_file)) assert targets == [("python", "3.7"), ("python", "3.8"), ("protobuf", "4.25.8")] @pytest.mark.parametrize( @@ -801,20 +803,22 @@ def test_parse_targets_file(tmp_path): ("invalid: {", True), # Invalid YAML ("- not_a_mapping", True), # Invalid structure (list instead of map) ("python:\n - null", True), # Invalid version type (null/None value) + ("python:\n - 3.10", True), # Invalid version type (float instead of string in list) + ("python: 3.10", True), # Invalid version type (float instead of string) ] ) -def test_parse_targets_file_failures(tmp_path, file_content, file_exists): - from version_scanner import parse_targets_file +def test_parse_matrix_file_failures(tmp_path, file_content, file_exists): + from version_scanner import parse_matrix_file if file_exists: - yaml_file = tmp_path / "targets_failures.yaml" + yaml_file = tmp_path / "matrix_failures.yaml" yaml_file.write_text(file_content) path = str(yaml_file) else: path = "nonexistent_file.yaml" with pytest.raises(SystemExit) as excinfo: - parse_targets_file(path) + parse_matrix_file(path) assert excinfo.value.code == 1 def test_scan_repository_multi_targets(tmp_path): @@ -868,3 +872,26 @@ def test_scan_repository_multi_targets(tmp_path): assert protobuf_match[0]["version"] == "4.25.8" assert protobuf_match[0]["rule_name"] == "protobuf_check" + +@pytest.mark.parametrize( + "args, expected_error_msg", + [ + # Mixing -m/--matrix-file with -d or -v + (['version_scanner.py', '-m', 'matrix.yaml', '-d', 'python'], "Cannot specify -d/--dependency or -v/--version when using -m/--matrix-file"), + (['version_scanner.py', '-m', 'matrix.yaml', '-v', '3.7'], "Cannot specify -d/--dependency or -v/--version when using -m/--matrix-file"), + (['version_scanner.py', '-m', 'matrix.yaml', '-d', 'python', '-v', '3.7'], "Cannot specify -d/--dependency or -v/--version when using -m/--matrix-file"), + # Missing either -d or -v when not using -m + (['version_scanner.py', '-d', 'python'], "Must specify both -d/--dependency and -v/--version when not using -m/--matrix-file"), + (['version_scanner.py', '-v', '3.7'], "Must specify both -d/--dependency and -v/--version when not using -m/--matrix-file"), + (['version_scanner.py'], "Must specify both -d/--dependency and -v/--version when not using -m/--matrix-file"), + ] +) +def test_main_cli_validation(capsys, args, expected_error_msg): + from version_scanner import main + with mock.patch('sys.argv', args): + with pytest.raises(SystemExit) as excinfo: + main() + assert excinfo.value.code == 2 + captured = capsys.readouterr() + assert expected_error_msg in captured.err + diff --git a/scripts/version_scanner/version_scanner.py b/scripts/version_scanner/version_scanner.py index 6205e8effadd..fcd45ed63b54 100644 --- a/scripts/version_scanner/version_scanner.py +++ b/scripts/version_scanner/version_scanner.py @@ -65,7 +65,7 @@ def _safe_read_file( else: print(f"Warning: Permission denied reading {description}: {file_path}", file=sys.stderr) return None - except IOError as e: + except (IOError, ValueError) as e: if required: print(f"Error reading {description} {file_path}: {e}", file=sys.stderr) sys.exit(1) @@ -624,33 +624,36 @@ def scan_repository( return results -def parse_targets_file(file_path: str) -> List[Tuple[str, str]]: +def parse_matrix_file(file_path: str) -> List[Tuple[str, str]]: """ - Parses a YAML targets file into a list of (dependency, version) tuples. + Parses a YAML matrix file into a list of (dependency, version) tuples. """ - content = _safe_read_file(file_path, required=True, description="targets file") + content = _safe_read_file(file_path, required=True, description="matrix file") try: - raw_targets = yaml.safe_load(content) + raw_matrix = yaml.safe_load(content) except Exception as e: - print(f"Error parsing targets YAML mapping: {e}", file=sys.stderr) + print(f"Error parsing matrix YAML mapping: {e}", file=sys.stderr) sys.exit(1) - if not isinstance(raw_targets, dict): - print("Error: Targets file content must resolve to a YAML mapping", file=sys.stderr) + if not isinstance(raw_matrix, dict): + print("Error: Matrix file content must resolve to a YAML mapping", file=sys.stderr) sys.exit(1) targets = [] - for dep, versions in raw_targets.items(): + for dep, versions in raw_matrix.items(): if isinstance(versions, list): for v in versions: if v is None or isinstance(v, (dict, list)): print(f"Error: Invalid version '{v}' for dependency '{dep}'", file=sys.stderr) sys.exit(1) - targets.append((str(dep), str(v))) - elif versions is not None and not isinstance(versions, dict): - targets.append((str(dep), str(versions))) + if not isinstance(v, str): + print(f"Error: Version '{v}' for dependency '{dep}' must be specified as a quoted string to prevent YAML parsing issues (e.g., 3.10 parsed as 3.1).", file=sys.stderr) + sys.exit(1) + targets.append((str(dep), v)) + elif isinstance(versions, str): + targets.append((str(dep), versions)) else: - print(f"Error: Invalid version '{versions}' for dependency '{dep}'", file=sys.stderr) + print(f"Error: Invalid version '{versions}' for dependency '{dep}'. Versions must be specified as quoted strings.", file=sys.stderr) sys.exit(1) return targets @@ -675,7 +678,7 @@ def main(): ) parser.add_argument( - "--targets-file", + "-m", "--matrix-file", help="Path to a YAML file containing target dependencies and versions." ) @@ -743,17 +746,17 @@ def main(): args = parser.parse_args() # Validation of required inputs - has_single_target = bool(args.dependency and args.version) - has_targets_file = bool(args.targets_file) - - if not (has_single_target or has_targets_file): - parser.error("Must specify either (-d/--dependency AND -v/--version) OR (--targets-file)") - if has_single_target and has_targets_file: - parser.error("Cannot specify both single target (-d/-v) and targets file (--targets-file)") + has_matrix_file = bool(args.matrix_file) + if has_matrix_file: + if args.dependency or args.version: + parser.error("Cannot specify -d/--dependency or -v/--version when using -m/--matrix-file") + else: + if not (args.dependency and args.version): + parser.error("Must specify both -d/--dependency and -v/--version when not using -m/--matrix-file") targets = [] - if has_targets_file: - targets = parse_targets_file(args.targets_file) + if has_matrix_file: + targets = parse_matrix_file(args.matrix_file) else: targets = [(args.dependency, args.version)] @@ -772,7 +775,7 @@ def main(): elif args.package_file: target_packages = read_package_file(args.package_file) - if has_targets_file: + if has_matrix_file: print("Starting scan for multiple targets:") for dep, ver in targets: print(f" - {dep}: {ver}") @@ -809,7 +812,7 @@ def main(): rules, target_packages, ignore_dirs, - version_string=(None if has_targets_file else args.version), + version_string=(None if has_matrix_file else args.version), targets=targets ) @@ -833,8 +836,8 @@ def main(): script_dir = os.path.dirname(os.path.abspath(__file__)) results_dir = os.path.join(script_dir, "results") os.makedirs(results_dir, exist_ok=True) - if has_targets_file: - base_name = os.path.splitext(os.path.basename(args.targets_file))[0] + if has_matrix_file: + base_name = os.path.splitext(os.path.basename(args.matrix_file))[0] output_path = os.path.join(results_dir, f"{base_name}-{timestamp}.csv") else: output_path = os.path.join(results_dir, f"{args.dependency}-{args.version}-{timestamp}.csv") From 6febabf795106a0c336dc905fc23da88d8cc94a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Swe=C3=B1a=20=28Swast=29?= Date: Tue, 23 Jun 2026 12:35:14 -0500 Subject: [PATCH 113/174] docs: ensure that PlotAccessor is included in the API reference (#17513) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, [this page](https://dataframes.bigquery.dev/reference/api/bigframes.pandas.DataFrame.plot.html#bigframes.pandas.DataFrame.plot) is blank. image After this change: image 🦕 --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- packages/bigframes/bigframes/_tools/docs.py | 14 ++++++++++++++ packages/bigframes/bigframes/pandas/api/typing.py | 2 ++ packages/bigframes/docs/templates/toc.yml | 4 ++-- .../bigframes_vendored/pandas/core/frame.py | 2 +- .../bigframes_vendored/pandas/core/series.py | 2 +- 5 files changed, 20 insertions(+), 4 deletions(-) diff --git a/packages/bigframes/bigframes/_tools/docs.py b/packages/bigframes/bigframes/_tools/docs.py index 1b4b329a9454..9ecfd61b3c96 100644 --- a/packages/bigframes/bigframes/_tools/docs.py +++ b/packages/bigframes/bigframes/_tools/docs.py @@ -34,6 +34,20 @@ def decorator(target_class): except AttributeError: pass + underlying = None + if isinstance(target_item, property): + underlying = target_item.fget + elif hasattr(target_item, "__func__"): + underlying = target_item.__func__ + elif hasattr(target_item, "func"): + underlying = getattr(target_item, "func", None) + + if underlying is not None: + try: + underlying.__doc__ = source_item.__doc__ + except AttributeError: + pass + return target_class return decorator diff --git a/packages/bigframes/bigframes/pandas/api/typing.py b/packages/bigframes/bigframes/pandas/api/typing.py index e21216bb6857..8d8d65eddece 100644 --- a/packages/bigframes/bigframes/pandas/api/typing.py +++ b/packages/bigframes/bigframes/pandas/api/typing.py @@ -21,12 +21,14 @@ from bigframes.core.groupby.series_group_by import SeriesGroupBy from bigframes.core.window import Window from bigframes.operations.datetimes import DatetimeMethods +from bigframes.operations.plotting import PlotAccessor from bigframes.operations.strings import StringMethods from bigframes.operations.structs import StructAccessor, StructFrameAccessor __all__ = [ "DataFrameGroupBy", "DatetimeMethods", + "PlotAccessor", "SeriesGroupBy", "StringMethods", "StructAccessor", diff --git a/packages/bigframes/docs/templates/toc.yml b/packages/bigframes/docs/templates/toc.yml index 562b857fee5c..394f2a7d3cc1 100644 --- a/packages/bigframes/docs/templates/toc.yml +++ b/packages/bigframes/docs/templates/toc.yml @@ -42,7 +42,7 @@ - name: DataFrame uid: bigframes.dataframe.DataFrame - name: PlotAccessor - uid: bigframes.operations.plotting.PlotAccessor + uid: bigframes.pandas.api.typing.PlotAccessor - name: StructAccessor uid: bigframes.operations.structs.StructFrameAccessor name: DataFrame @@ -86,7 +86,7 @@ - name: ListAccessor uid: bigframes.operations.lists.ListAccessor - name: PlotAccessor - uid: bigframes.operations.plotting.PlotAccessor + uid: bigframes.pandas.api.typing.PlotAccessor name: Series - name: Window uid: bigframes.core.window.Window diff --git a/packages/bigframes/third_party/bigframes_vendored/pandas/core/frame.py b/packages/bigframes/third_party/bigframes_vendored/pandas/core/frame.py index f016cab47ae3..b13b4a6d14eb 100644 --- a/packages/bigframes/third_party/bigframes_vendored/pandas/core/frame.py +++ b/packages/bigframes/third_party/bigframes_vendored/pandas/core/frame.py @@ -7335,7 +7335,7 @@ def plot(self): Make plots of Dataframes. Returns: - bigframes.operations.plotting.PlotAccessor: + bigframes.pandas.api.typing.PlotAccessor: An accessor making plots. """ raise NotImplementedError(constants.ABSTRACT_METHOD_ERROR_MESSAGE) diff --git a/packages/bigframes/third_party/bigframes_vendored/pandas/core/series.py b/packages/bigframes/third_party/bigframes_vendored/pandas/core/series.py index c116ed640122..42c543018c64 100644 --- a/packages/bigframes/third_party/bigframes_vendored/pandas/core/series.py +++ b/packages/bigframes/third_party/bigframes_vendored/pandas/core/series.py @@ -5450,7 +5450,7 @@ def plot(self): Returns: - bigframes.operations.plotting.PlotAccessor: + bigframes.pandas.api.typing.PlotAccessor: An accessor making plots. """ raise NotImplementedError(constants.ABSTRACT_METHOD_ERROR_MESSAGE) From 8826494779ba3cbf899cc957c6c8e9d98708ece8 Mon Sep 17 00:00:00 2001 From: Chalmer Lowe Date: Tue, 23 Jun 2026 13:37:30 -0400 Subject: [PATCH 114/174] chore(bigquery): add dynamic logging banner to nox mypy session (#17492) This PR adds a dynamic logging banner `Finished session for ` to nox `mypy` sessions in `bigquery` to simplify troubleshooting. Currently when a nox session runs, there may be many lines of text between a reference to which package is being tested and the result summary line. This can make it more difficult to determine which package is affected without a lot of manual scrolling (every time you need to trouble shoot an issue). This is especially true if you use `Ctrl+F` to zoom over to summaries with words like `failed`. ``` change detected in packages/bigframes/ [many lines of text...] 2547 passed, 157 skipped, 9 xfailed, 1 xpassed, 586 warnings in 136.68s (0:02:16) nox > Session unit-3.11(test_extra=True) failed in 3 minutes. ``` The PR adds a banner line right before the nox result summary: ``` change detected in packages/bigframes/ [many lines of text...] 2547 passed, 157 skipped, 9 xfailed, 1 xpassed, 586 warnings in 136.68s (0:02:16) nox > Finished session for bigframes # NEW LINE, right before the summary line nox > Session unit-3.11(test_extra=True) failed in 3 minutes. ``` > [!note] > There is no convenient way to inject a log line into the nox session and have it print **exactly** where you want. Also, because the long term intent is to add this to all nox sessions I included an easy to apply `contextmanager` to ensure the correct placement of the new logging banner. > [!note] > This PR only adds this capability to a single nox session (`mypy`) and a single handwritten package (`bigquery`). I did not want to invest a lot of time unless the team feels it is beneficial. In which case, we can add a task the next sprint to make this a global change. --- packages/google-cloud-bigquery/noxfile.py | 24 ++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/packages/google-cloud-bigquery/noxfile.py b/packages/google-cloud-bigquery/noxfile.py index c576870f9be9..cfe3b60e0c51 100644 --- a/packages/google-cloud-bigquery/noxfile.py +++ b/packages/google-cloud-bigquery/noxfile.py @@ -14,9 +14,11 @@ from __future__ import absolute_import +import contextlib from functools import wraps import os import pathlib +from typing import Generator import re import shutil import time @@ -80,6 +82,25 @@ def wrapper(*args, **kwargs): ] +@contextlib.contextmanager +def log_package_context(session: nox.Session) -> Generator[None, None, None]: + """Logs a highly visible package context banner right before a session exits. + + Ensures metadata is printed adjacent to Nox's final status log, + even if the session fails or raises an exception. + """ + # Dynamically extract current folder name (e.g., 'google-cloud-bigquery') + package_name = CURRENT_DIRECTORY.name + + try: + # Hands control back to the session code block + yield + finally: + # This executes AFTER test output finishes, immediately above Nox's summary line + banner_text = f"Finished session for {package_name.lower()}" + session.log(banner_text) + + def default(session, install_extras=True): """Default unit test session. @@ -193,7 +214,8 @@ def mypy(session): "types-setuptools", ) session.run("python", "-m", "pip", "freeze") - session.run("mypy", "-p", "google", "--show-traceback") + with log_package_context(session): + session.run("mypy", "-p", "google", "--show-traceback") @nox.session(python=SYSTEM_TEST_PYTHON_VERSIONS) From ea9aad9a43c306ab109054183b257e6c41a1b2e6 Mon Sep 17 00:00:00 2001 From: TrevorBergeron Date: Tue, 23 Jun 2026 10:42:36 -0700 Subject: [PATCH 115/174] feat: Experimental transpilation of unannotated python callables (#17419) --- .../bigframes/_config/experiment_options.py | 15 ++ .../bigframes/core/block_transforms.py | 40 ++- packages/bigframes/bigframes/core/bytecode.py | 7 +- .../bigframes/core/py_expressions.py | 20 +- packages/bigframes/bigframes/dataframe.py | 36 ++- packages/bigframes/bigframes/exceptions.py | 8 + .../bigframes/operations/__init__.py | 4 +- .../bigframes/bigframes/operations/to_op.py | 182 ++++++++++++- packages/bigframes/bigframes/series.py | 90 +++++-- packages/bigframes/conftest.py | 2 +- .../tests/unit/core/test_bytecode.py | 49 ++-- packages/bigframes/tests/unit/test_py_udf.py | 243 ++++++++++++++++++ .../bigframes_vendored/pandas/core/frame.py | 25 ++ .../bigframes_vendored/pandas/core/series.py | 11 + 14 files changed, 646 insertions(+), 86 deletions(-) create mode 100644 packages/bigframes/tests/unit/test_py_udf.py diff --git a/packages/bigframes/bigframes/_config/experiment_options.py b/packages/bigframes/bigframes/_config/experiment_options.py index e8183d2b2228..202b47b738c1 100644 --- a/packages/bigframes/bigframes/_config/experiment_options.py +++ b/packages/bigframes/bigframes/_config/experiment_options.py @@ -28,6 +28,7 @@ def __init__(self): self._semantic_operators: bool = False self._ai_operators: bool = False self._sql_compiler: Literal["legacy", "stable", "experimental"] = "stable" + self._enable_python_transpiler: bool = False @property def semantic_operators(self) -> bool: @@ -166,3 +167,17 @@ def blob_display_height(self, value: Optional[int]): warnings.warn(msg, category=bfe.ApiDeprecationWarning) bigframes.options.display.blob_display_height = value + + @property + def enable_python_transpiler(self) -> bool: + return self._enable_python_transpiler + + @enable_python_transpiler.setter + def enable_python_transpiler(self, value: bool): + if value: + msg = bfe.format_message( + "Python transpiler is an unstable, experimental feature, and not yet fully " + "validated, use at your own risk." + ) + warnings.warn(msg, category=bfe.PythonTranspilerPreviewWarning) + self._enable_python_transpiler = value diff --git a/packages/bigframes/bigframes/core/block_transforms.py b/packages/bigframes/bigframes/core/block_transforms.py index cea59c028b83..10bd2a736412 100644 --- a/packages/bigframes/bigframes/core/block_transforms.py +++ b/packages/bigframes/bigframes/core/block_transforms.py @@ -14,8 +14,9 @@ from __future__ import annotations import functools +import inspect import typing -from typing import Optional, Sequence +from typing import Callable, Hashable, Optional, Sequence import bigframes_vendored.constants as constants import pandas as pd @@ -23,13 +24,48 @@ import bigframes.constants import bigframes.core as core import bigframes.core.blocks as blocks +import bigframes.core.bytecode as bytecode import bigframes.core.expression as ex import bigframes.core.ordering as ordering import bigframes.core.window_spec as windows import bigframes.dtypes as dtypes import bigframes.operations as ops import bigframes.operations.aggregations as agg_ops -from bigframes.core import agg_expressions +from bigframes.core import agg_expressions, py_expressions + + +def apply_to_block_rows( + func: Callable, block: blocks.Block, *args, **kwargs +) -> blocks.Block: + """ + Apply the given function to each row of the block. + + The function is applied to each row of the block, and the result is returned + as a new block with the same index. + """ + expr = bytecode._compile_bytecode_to_py_expr(func) + sig = inspect.signature(func) + + bindings: dict[Hashable, ex.Expression] = {} + + bound_args = sig.bind(*(None, *args), **kwargs) + bound_args.apply_defaults() + bound_params = bound_args.arguments + for name, value in bound_params.items(): + bindings[name] = ex.const(value) + + expr = py_expressions.resolve_py_exprs( + expr, + series_arg=next(iter(sig.parameters.keys())), + series_attrs={ + label: col_id + for label in block.column_labels + if (col_id := block.resolve_label_exact(label)) is not None + }, + ) + expr = expr.bind_variables(bindings) + + return block.project_exprs([expr], labels=[None], drop=True) def equals(block1: blocks.Block, block2: blocks.Block) -> bool: diff --git a/packages/bigframes/bigframes/core/bytecode.py b/packages/bigframes/bigframes/core/bytecode.py index 5887254eb4de..fb4d3eabd8b7 100644 --- a/packages/bigframes/bigframes/core/bytecode.py +++ b/packages/bigframes/bigframes/core/bytecode.py @@ -249,15 +249,12 @@ def _compile_bytecode_to_py_expr(func: Callable) -> expression.Expression: raise ValueError("No return value found") -def dis_to_expr(func: Callable, unpack_mode: bool = False) -> expression.Expression: +def py_to_expression(func: Callable) -> expression.Expression: """ Try to convert a python function to a BigQuery expression. - Unpack mode is whether SQL columns are addressed as attributes of a single - python argument (e.g. row.col1), or as separate arguments (e.g. col1). - This is "best effort" - if the function contains operations that cannot be converted to BigQuery expressions, it will raise an Exception. """ py_expr = _compile_bytecode_to_py_expr(func) - return py_exprs.resolve_py_exprs(py_expr, unpack_mode=unpack_mode) + return py_exprs.resolve_py_exprs(py_expr) diff --git a/packages/bigframes/bigframes/core/py_expressions.py b/packages/bigframes/bigframes/core/py_expressions.py index f29a35b0d161..e1885e13afea 100644 --- a/packages/bigframes/bigframes/core/py_expressions.py +++ b/packages/bigframes/bigframes/core/py_expressions.py @@ -17,7 +17,7 @@ import dataclasses import itertools from types import ModuleType -from typing import Callable, Hashable, Mapping, Tuple +from typing import Callable, Hashable, Mapping, Optional, Tuple import bigframes.operations.python_op_maps as python_op_maps from bigframes import dtypes @@ -27,6 +27,7 @@ OpExpression, UnboundVariableExpression, const, + deref, ) from bigframes.operations import NUMPY_TO_BINOP, NUMPY_TO_OP, generic_ops, numeric_ops @@ -310,7 +311,11 @@ def bind_refs( # TODO: Mode that resolves free variable attrs as columns -def resolve_py_exprs(expression: Expression, unpack_mode: bool = False) -> Expression: +def resolve_py_exprs( + expression: Expression, + series_arg: Optional[str] = None, + series_attrs: Mapping[Hashable, str] | None = None, +) -> Expression: """Replace all PyObject, attribute, call expressions. Bottom-up.""" def resolve_expr_if_call(expression: Expression) -> Expression: @@ -325,10 +330,15 @@ def resolve_attrs(expression: Expression) -> Expression: if isinstance(expression.input, Module): # resolves things like Math.pi return PyObject(getattr(expression.input.module, expression.attr)) - if not unpack_mode and isinstance( - expression.input, UnboundVariableExpression + # TODO: Resolve some series methods + if ( + series_arg is not None + and series_attrs is not None + and isinstance(expression.input, UnboundVariableExpression) + and expression.input.id == series_arg + and expression.attr in series_attrs ): - return UnboundVariableExpression(expression.attr) + return deref(series_attrs[expression.attr]) return expression def resolve_pyobjs(expression: Expression) -> Expression: diff --git a/packages/bigframes/bigframes/dataframe.py b/packages/bigframes/bigframes/dataframe.py index e64e640287f2..51c4decd5ebd 100644 --- a/packages/bigframes/bigframes/dataframe.py +++ b/packages/bigframes/bigframes/dataframe.py @@ -4716,13 +4716,17 @@ def _prepare_export( return array_value, id_overrides def map(self, func, na_action: Optional[str] = None) -> DataFrame: - if not isinstance(func, bigframes.functions.Udf): + from bigframes._config import options + + if not isinstance(func, bigframes.functions.Udf) and not ( + options.experiments.enable_python_transpiler and callable(func) + ): raise TypeError("the first argument must be callable") if na_action not in {None, "ignore"}: raise ValueError(f"na_action={na_action} not supported") - expr = ops.func_to_op(func).as_expr(ex.free_var("input")) + expr = ops.func_to_expr(func).apply(ex.free_var("input")) if na_action == "ignore": # True case, predicate, False case expr = ops.where_op.as_expr( @@ -4742,11 +4746,25 @@ def apply(self, func, *, axis=0, args: typing.Tuple = (), **kwargs): ) warnings.warn(msg, category=bfe.FunctionAxisOnePreviewWarning) - if not isinstance(func, bigframes.functions.Udf): + from bigframes._config import options + + if not isinstance(func, bigframes.functions.Udf) and not ( + options.experiments.enable_python_transpiler and callable(func) + ): raise ValueError( "For axis=1 a BigFrames BigQuery function must be used." ) + if ( + not isinstance(func, bigframes.functions.Udf) + and options.experiments.enable_python_transpiler + and callable(func) + ): + result_block = block_ops.apply_to_block_rows( + func, self._block, *args, **kwargs + ) + return bigframes.series.Series(result_block) + if func.udf_def.signature.is_row_processor: # Early check whether the dataframe dtypes are currently supported # in the bigquery function @@ -4800,8 +4818,14 @@ def apply(self, func, *, axis=0, args: typing.Tuple = (), **kwargs): ) # Apply the function + expr = ops.func_to_expr(func).expr + if not ( + isinstance(expr, ex.OpExpression) + and isinstance(expr.op, ops.NaryOp) + ): + raise TypeError(f"Expected OpExpression with NaryOp, got {expr}") result_series = rows_as_json_series._apply_nary_op( - ops.func_to_op(func), + expr.op, list(args), ) @@ -4861,8 +4885,8 @@ def apply(self, func, *, axis=0, args: typing.Tuple = (), **kwargs): series_list = [self[col] for col in self.columns] op_list = series_list[1:] + list(args) - result_series = series_list[0]._apply_nary_op( - ops.func_to_op(func), op_list + result_series = series_list[0]._apply_callable_expr( + ops.func_to_expr(func), op_list ) result_series.name = None diff --git a/packages/bigframes/bigframes/exceptions.py b/packages/bigframes/bigframes/exceptions.py index 9facb40e8eac..dea8a55f9b55 100644 --- a/packages/bigframes/bigframes/exceptions.py +++ b/packages/bigframes/bigframes/exceptions.py @@ -75,6 +75,10 @@ class MaximumResultRowsExceeded(RuntimeError): """Maximum number of rows in the result was exceeded.""" +class TranspilationError(RuntimeError): + """Failed to transpile a Python function to BigFrames Expression.""" + + class TimeTravelDisabledWarning(Warning): """A query was reattempted without time travel.""" @@ -126,6 +130,10 @@ class FunctionPackageVersionWarning(PreviewWarning): """ +class PythonTranspilerPreviewWarning(PreviewWarning): + """Python Transpiler is a preview feature.""" + + def format_message(message: str, fill: bool = True): """[Private] Formats a warning message. diff --git a/packages/bigframes/bigframes/operations/__init__.py b/packages/bigframes/bigframes/operations/__init__.py index a493e7a755bf..b63a150afaea 100644 --- a/packages/bigframes/bigframes/operations/__init__.py +++ b/packages/bigframes/bigframes/operations/__init__.py @@ -230,7 +230,7 @@ timestamp_add_op, timestamp_sub_op, ) -from bigframes.operations.to_op import func_to_op +from bigframes.operations.to_op import func_to_expr __all__ = [ # Base ops @@ -439,7 +439,7 @@ "AIScore", "AISimilarity", # Helper functions - "func_to_op", + "func_to_expr", # Numpy ops mapping "NUMPY_TO_BINOP", "NUMPY_TO_OP", diff --git a/packages/bigframes/bigframes/operations/to_op.py b/packages/bigframes/bigframes/operations/to_op.py index 7fd44d957e40..4f97a61e3c0b 100644 --- a/packages/bigframes/bigframes/operations/to_op.py +++ b/packages/bigframes/bigframes/operations/to_op.py @@ -11,31 +11,191 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import annotations +import dataclasses +import inspect +import typing + +import bigframes.core.expression as ex +from bigframes._config import options +from bigframes.exceptions import TranspilationError from bigframes.functions import Udf from bigframes.functions.udf_def import BigqueryUdf, PythonUdf from bigframes.operations import base_ops, remote_function_ops +ArgKind = typing.Literal[ + "positional_only", + "positional_or_keyword", + "keyword_only", + "var_positional", + "var_keyword", +] + +_ARGKIND_MAP: dict[inspect._ParameterKind, ArgKind] = { + inspect.Parameter.POSITIONAL_ONLY: "positional_only", + inspect.Parameter.POSITIONAL_OR_KEYWORD: "positional_or_keyword", + inspect.Parameter.VAR_POSITIONAL: "var_positional", + inspect.Parameter.KEYWORD_ONLY: "keyword_only", + inspect.Parameter.VAR_KEYWORD: "var_keyword", +} -def func_to_op(op) -> base_ops.NaryOp: + +@dataclasses.dataclass(frozen=True) +class ArgumentSpec: + """ + Information about a single argument to a function """ - Convert various bigframes, python functions into bigframes operations. - This should handle anything that might be passed to eg map, combine, other pandas methods that take a function. + name: str + default_value: typing.Any + argkind: ArgKind + + @property + def is_positional(self) -> bool: + return self.argkind in ["positional_only", "positional_or_keyword"] + + @property + def is_keyword(self) -> bool: + return self.argkind in ["keyword_only", "positional_or_keyword"] + + @property + def is_var_positional(self) -> bool: + return self.argkind == "var_positional" + + @property + def is_var_keyword(self) -> bool: + return self.argkind == "var_keyword" + + @property + def is_varargs(self) -> bool: + return self.is_var_positional + + +@dataclasses.dataclass(frozen=True) +class CallableExpression: + """ + Encodes a calling convention and an expression to bind arguments to. + """ + + expr: ex.Expression + arg_specs: typing.Sequence[ArgumentSpec] + + @classmethod + def from_callable(cls, func: typing.Callable) -> CallableExpression: + sig = inspect.signature(func) + arg_specs = [] + for name, param in sig.parameters.items(): + arg_specs.append( + ArgumentSpec( + name=name, + default_value=param.default, + argkind=_ARGKIND_MAP[param.kind], + ) + ) - It should raise a TypeError if the object is not a supported type. + from bigframes.core.bytecode import py_to_expression - Args: - op: The object to convert. + try: + expr = py_to_expression(func) + except Exception as ex: + raise TranspilationError(f"Failed to transpile function {func}") from ex + return cls(expr=expr, arg_specs=arg_specs) - Returns: - A bigframes operations. + def apply(self, *args, **kwargs) -> ex.Expression: + """ + Apply the arguments to the expression. + + All args are expected to be column references, or scalars. + """ + return self.bind_partial(*args, _offset=0, **kwargs).expr + + def bind_partial( + self, + *args, + _offset: int = 0, + **kwargs, + ) -> CallableExpression: + """ + Bind a subset of arguments and return a new CallableExpression with the remaining unbound arguments. + """ + bindings: dict[typing.Hashable, ex.Expression] = {} + pos_idx = 0 + allowed_params = self.arg_specs[_offset:] + allowed_names = {spec.name for spec in allowed_params} + + # Validate unexpected keyword arguments + for key in kwargs: + if key not in allowed_names: + raise TypeError(f"got an unexpected keyword argument '{key}'") + + def to_expr(val): + if isinstance(val, ex.Expression): + return val + return ex.const(val) + + for spec in allowed_params: + if spec.is_varargs: + raise NotImplementedError( + "varargs in compiled python functions is not supported" + ) + + if pos_idx < len(args): + if spec.name in kwargs: + raise TypeError( + f"got multiple values for keyword argument '{spec.name}'" + ) + bindings[spec.name] = to_expr(args[pos_idx]) + pos_idx += 1 + elif spec.name in kwargs: + bindings[spec.name] = to_expr(kwargs[spec.name]) + elif spec.default_value is not inspect.Parameter.empty: + bindings[spec.name] = to_expr(spec.default_value) + else: + raise TypeError(f"missing required argument: '{spec.name}'") + + if pos_idx < len(args): + raise TypeError( + f"too many positional arguments: expected {len(allowed_params)}, got {len(args)}" + ) + + new_expr = self.expr.bind_variables(bindings, allow_partial_bindings=True) + remaining_specs = list(self.arg_specs[:_offset]) + return CallableExpression(expr=new_expr, arg_specs=remaining_specs) + + +def func_to_expr(op) -> CallableExpression: + """ + Convert various bigframes, python functions into bigframes CallableExpression. """ - # TODO(b/517578802): Handle numpy ufuncs, builtin functions, etc. if isinstance(op, Udf): + bq_op: base_ops.NaryOp if isinstance(op.udf_def, BigqueryUdf): - return remote_function_ops.RemoteFunctionOp(function_def=op.udf_def) + bq_op = remote_function_ops.RemoteFunctionOp(function_def=op.udf_def) elif isinstance(op.udf_def, PythonUdf): - return remote_function_ops.PythonUdfOp(function_def=op.udf_def) + bq_op = remote_function_ops.PythonUdfOp(function_def=op.udf_def) + else: + raise TypeError(f"Unsupported UDF definition: {op.udf_def}") + + inputs_expr = tuple( + ex.free_var(arg.name) for arg in op.udf_def.signature.inputs + ) + expr = ex.OpExpression(bq_op, inputs_expr) + + arg_specs = [ + ArgumentSpec( + name=arg.name, + default_value=inspect.Parameter.empty, + # Udf specs don't have concept of positional only or keyword only yet, + # so default to positional_or_keyword. + argkind="positional_or_keyword", + ) + for arg in op.udf_def.signature.inputs + ] + return CallableExpression(expr=expr, arg_specs=arg_specs) + + elif options.experiments.enable_python_transpiler and callable(op): + return CallableExpression.from_callable(op) + else: raise TypeError(f"Unsupported function type: {op}") diff --git a/packages/bigframes/bigframes/series.py b/packages/bigframes/bigframes/series.py index 57f74136548c..b7f52970f55e 100644 --- a/packages/bigframes/bigframes/series.py +++ b/packages/bigframes/bigframes/series.py @@ -2073,25 +2073,48 @@ def apply( " are supported." ) - if isinstance(func, bigframes.functions.Udf): - # We are working with bigquery function at this point - result_series = self._apply_nary_op(ops.func_to_op(func), args) - # TODO(jialuo): Investigate why `_apply_nary_op` drops the series - # `name`. Manually reassigning it here as a temporary fix. - result_series.name = self.name - - return result_series - + # Highest priority: try to map directly to an operator, for eg numpy + # ufuncs, or simple arithmetic/logic operators. bf_op = python_ops.python_callable_to_op(func) if bf_op and isinstance(bf_op, ops.UnaryOp): return self._apply_unary_op(bf_op) - # It is neither a remote function nor a managed function. - # Then it must be a vectorized function that applies to the Series - # as a whole. if by_row: + from bigframes._config import options + + enable_transpile = options.experiments.enable_python_transpiler + return self._apply_by_row( + func, args=args, transpile_enabled=enable_transpile + ) + try: + return func(self) # type: ignore + except Exception as ex: + # This could happen if any of the operators in func is not + # supported on a Series. Let's guide the customer to use a + # bigquery function instead + if hasattr(ex, "message"): + ex.message += f"\n{_bigquery_function_recommendation_message}" + raise + + def _apply_by_row( + self, + func: typing.Callable, + args: typing.Tuple = (), + transpile_enabled: bool = False, + ) -> Series: + """ + Apply callable or deployed udf row-wise on the series. + """ + if not callable(func): + raise ValueError( + "Expected a callable function. If you meant to use a BigQuery function, please wrap it with bigframes.pandas.udf(...)" + ) + try: + expr = ops.func_to_expr(func) + # We get this message even if transpiler could have in theory translated it. + except Exception: raise ValueError( - "You have passed a function as-is. If your intention is to " + "You have passed a functi1on as-is. If your intention is to " "apply this function in a vectorized way (i.e. to the " "entire Series as a whole, and you are sure that it " "performs only the operations that are implemented for a " @@ -2105,15 +2128,12 @@ def apply( "or `bigframes.pandas.remote_function` before passing." ) - try: - return func(self) # type: ignore - except Exception as ex: - # This could happen if any of the operators in func is not - # supported on a Series. Let's guide the customer to use a - # bigquery function instead - if hasattr(ex, "message"): - ex.message += f"\n{_bigquery_function_recommendation_message}" - raise + result_series = self._apply_callable_expr(expr, args) + # TODO(jialuo): Investigate why `_apply_nary_op` drops the series + # `name`. Manually reassigning it here as a temporary fix. + result_series.name = self.name + + return result_series def combine( self, @@ -2127,8 +2147,12 @@ def combine( " are supported." ) - if isinstance(func, bigframes.functions.Udf): - result_series = self._apply_nary_op(ops.func_to_op(func), (other,)) + from bigframes._config import options + + if isinstance(func, bigframes.functions.Udf) or ( + options.experiments.enable_python_transpiler and callable(func) + ): + result_series = self._apply_callable_expr(ops.func_to_expr(func), (other,)) if hasattr(other, "name") and other.name != self._name: # type: ignore result_series.name = None else: @@ -2498,7 +2522,10 @@ def map( map_df = map_df.set_index("keys") elif callable(arg): # This is for remote function and managed funtion. - return self.apply(arg) + from bigframes._config import options + + enable_transpile = options.experiments.enable_python_transpiler + return self._apply_by_row(arg, transpile_enabled=enable_transpile) else: # Mirroring pandas, call the uncallable object arg() # throws TypeError: object is not callable @@ -2735,6 +2762,19 @@ def _apply_nary_op( block, result_id = block.project_expr(op.as_expr(*values)) return Series(block.select_column(result_id).with_column_labels([None])) + def _apply_callable_expr( + self, + callable_expr: bigframes.operations.to_op.CallableExpression, + others: Sequence[typing.Union[Series, scalars.Scalar]], + ignore_self=False, + ): + """Applies a CallableExpression to the series and others.""" + values, block = self._align_n( + others, ignore_self=ignore_self, cast_scalars=False + ) + block, result_id = block.project_expr(callable_expr.apply(*values)) + return Series(block.select_column(result_id).with_column_labels([None])) + def _apply_binary_aggregation( self, other: Series, stat: agg_ops.BinaryAggregateOp ) -> float: diff --git a/packages/bigframes/conftest.py b/packages/bigframes/conftest.py index e0f059fa4322..5d3f116b521c 100644 --- a/packages/bigframes/conftest.py +++ b/packages/bigframes/conftest.py @@ -29,7 +29,7 @@ warnings.simplefilter("ignore", pd.errors.SettingWithCopyWarning) -@pytest.fixture(scope="session") +@pytest.fixture() def polars_session_or_bpd(): # Since the doctest imports fixture is autouse=True, don't skip if polars # isn't available. diff --git a/packages/bigframes/tests/unit/core/test_bytecode.py b/packages/bigframes/tests/unit/core/test_bytecode.py index e718d252c601..036e3f00e8fa 100644 --- a/packages/bigframes/tests/unit/core/test_bytecode.py +++ b/packages/bigframes/tests/unit/core/test_bytecode.py @@ -18,73 +18,64 @@ import bigframes.core.expression as ex import bigframes.operations as ops -from bigframes.core.bytecode import dis_to_expr +from bigframes.core.bytecode import py_to_expression -def test_dis_to_expr_simple_arithmetic(): - func = lambda row: row.x + 1 - expr = dis_to_expr(func, unpack_mode=False) +def test_py_to_expression_simple_arithmetic(): + func = lambda x: x + 1 + expr = py_to_expression(func) assert expr is not None expected = ops.add_op.as_expr(ex.free_var("x"), ex.const(1)) assert expr == expected -def test_dis_to_expr_unpack_mode(): - func = lambda col1, col2: col1 * col2 - expr = dis_to_expr(func, unpack_mode=True) - assert expr is not None - - expected = ops.mul_op.as_expr(ex.free_var("col1"), ex.free_var("col2")) - assert expr == expected - - -def test_dis_to_expr_math_function(): - func = lambda row: math.sin(row.x) - expr = dis_to_expr(func, unpack_mode=False) +def test_py_to_expression_math_function(): + func = lambda x: math.sin(x) + expr = py_to_expression(func) assert expr is not None expected = ops.numeric_ops.sin_op.as_expr(ex.free_var("x")) assert expr == expected -def test_dis_to_expr_negation(): - func = lambda row: -row.x - expr = dis_to_expr(func, unpack_mode=False) +def test_py_to_expression_negation(): + func = lambda x: -x + expr = py_to_expression(func) assert expr is not None expected = ops.numeric_ops.neg_op.as_expr(ex.free_var("x")) assert expr == expected -def test_dis_to_expr_comparison(): - func = lambda row: row.x == row.y - expr = dis_to_expr(func, unpack_mode=False) +def test_py_to_expression_comparison(): + func = lambda x, y: x == y + expr = py_to_expression(func) assert expr is not None expected = ops.comparison_ops.eq_op.as_expr(ex.free_var("x"), ex.free_var("y")) assert expr == expected -def test_dis_to_expr_unsupported(): +def test_py_to_expression_unsupported(): # Control flow or unsupported structures should return None - def func_with_loop(row): + def func_with_loop(x): res = 0 - for val in range(int(row.x)): + for val in range(int(x)): res += val return res with pytest.raises(ValueError): - dis_to_expr(func_with_loop, unpack_mode=False) + py_to_expression(func_with_loop) global_none_val = None -def test_dis_to_expr_global_none(): +def test_py_to_expression_global_none(): # Test resolving a global variable explicitly set to None - func = lambda row: row.x == global_none_val - expr = dis_to_expr(func, unpack_mode=False) + func = lambda x: x == global_none_val + expr = py_to_expression(func) assert expr is not None expected = ops.comparison_ops.eq_op.as_expr(ex.free_var("x"), ex.const(None)) diff --git a/packages/bigframes/tests/unit/test_py_udf.py b/packages/bigframes/tests/unit/test_py_udf.py new file mode 100644 index 000000000000..ad491f6a7393 --- /dev/null +++ b/packages/bigframes/tests/unit/test_py_udf.py @@ -0,0 +1,243 @@ +# Copyright 2023 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 pathlib +from typing import Generator + +import pandas as pd +import pandas.testing +import pytest + +import bigframes +import bigframes.pandas as bpd +from bigframes.testing.utils import ( + assert_frame_equal, + assert_series_equal, + convert_pandas_dtypes, +) + +pytest.importorskip("polars") +pytest.importorskip("pandas", minversion="2.0.0") + +CURRENT_DIR = pathlib.Path(__file__).parent +DATA_DIR = CURRENT_DIR.parent / "data" + + +@pytest.fixture(scope="module", autouse=True) +def session() -> Generator[bigframes.Session, None, None]: + import bigframes.core.global_session + from bigframes.testing import polars_session + + with bpd.option_context("experiments.enable_python_transpiler", True): + session = polars_session.TestSession() + with bigframes.core.global_session._GlobalSessionContext(session): + yield session + + +@pytest.fixture(scope="module") +def scalars_pandas_df_index() -> pd.DataFrame: + """pd.DataFrame pointing at test data.""" + + df = pd.read_json( + DATA_DIR / "scalars.jsonl", + lines=True, + ) + convert_pandas_dtypes(df, bytes_col=True) + + df = df.set_index("rowindex", drop=False) + df.index.name = None + return df.set_index("rowindex").sort_index() + + +@pytest.fixture(scope="module") +def scalars_df_index( + session: bigframes.Session, scalars_pandas_df_index +) -> bpd.DataFrame: + return session.read_pandas(scalars_pandas_df_index) + + +@pytest.fixture(scope="module") +def scalars_dfs( + scalars_df_index, + scalars_pandas_df_index, +): + return scalars_df_index, scalars_pandas_df_index + + +def test_dataframe_map_transpile( + scalars_df_index, + scalars_pandas_df_index, +): + columns = ["int64_too", "int64_col"] + + def foo(input): + return input * 3 + 12 + + bf_result = scalars_df_index[columns].map(foo, na_action="ignore").to_pandas() + + pd_result = ( + scalars_pandas_df_index[columns].map(foo, na_action="ignore").astype("Int64") + ) + + assert_frame_equal(bf_result, pd_result) + + +def test_dataframe_apply_axis_1_transpile( + scalars_df_index, + scalars_pandas_df_index, +): + columns = ["int64_too", "int64_col"] + + def foo(input): + return input.int64_too + input.int64_col + + bf_result = scalars_df_index[columns].apply(foo, axis=1).to_pandas() + + pd_result = scalars_pandas_df_index[columns].apply(foo, axis=1).astype("Int64") + + assert_series_equal(bf_result, pd_result) + + +def test_series_combine_transpile( + scalars_df_index, + scalars_pandas_df_index, +): + def which_smaller(left, right): + return (left * right) + 3 + + bf_result = ( + scalars_df_index["int64_too"] + .combine(scalars_df_index["int64_col"], which_smaller) + .to_pandas() + ) + + pd_result = scalars_pandas_df_index["int64_too"].combine( + scalars_pandas_df_index["int64_col"], which_smaller + ) + + assert_series_equal(bf_result, pd_result) + + +def test_dataframe_apply_axis_1_transpile_with_defaults( + scalars_df_index, + scalars_pandas_df_index, +): + columns = ["int64_too", "int64_col"] + + def foo(input, x=10, y=5): + return input.int64_too + input.int64_col + x + y + + bf_result = scalars_df_index[columns].apply(foo, axis=1).to_pandas() + pd_result = scalars_pandas_df_index[columns].apply(foo, axis=1).astype("Int64") + + assert_series_equal(bf_result, pd_result) + + +def test_dataframe_apply_axis_1_transpile_with_args( + scalars_df_index, + scalars_pandas_df_index, +): + columns = ["int64_too", "int64_col"] + + def foo(input, x, y=5): + return input.int64_too + input.int64_col + x + y + + bf_result = ( + scalars_df_index[columns].apply(foo, axis=1, args=(12,), y=20).to_pandas() + ) + pd_result = ( + scalars_pandas_df_index[columns] + .apply(foo, axis=1, args=(12,), y=20) + .astype("Int64") + ) + + assert_series_equal(bf_result, pd_result) + + +def test_dataframe_apply_axis_1_transpile_invalid_bindings( + scalars_df_index, +): + columns = ["int64_too", "int64_col"] + + def foo(input, x, y=5): + return input.int64_too + input.int64_col + x + y + + # 1. Unexpected keyword argument + with pytest.raises(TypeError, match="unexpected keyword argument 'z'"): + scalars_df_index[columns].apply(foo, axis=1, args=(10,), z=20) + + # 2. Multiple values for keyword argument 'x' + with pytest.raises(TypeError, match="multiple values for argument 'x'"): + scalars_df_index[columns].apply(foo, axis=1, args=(10,), x=20) + + # 3. Too many positional arguments + with pytest.raises(TypeError, match="too many positional arguments"): + scalars_df_index[columns].apply(foo, axis=1, args=(10, 20, 30)) + + # 4. Missing required argument 'x' + with pytest.raises(TypeError, match="missing a required argument: 'x'"): + scalars_df_index[columns].apply(foo, axis=1) + + +def test_series_apply_transpile( + scalars_df_index, + scalars_pandas_df_index, +): + def foo(x, y=10): + return x * 2 + y + + bf_result = scalars_df_index["int64_col"].apply(foo, args=(5,)).to_pandas() + pd_result = ( + scalars_pandas_df_index["int64_col"].apply(foo, args=(5,)).astype("Int64") + ) + + assert_series_equal(bf_result, pd_result) + + +def test_series_apply_transpile_invalid_bindings( + scalars_df_index, +): + def foo(x, y): + return x + y + + # Too many positional args: foo takes 2 args (x, y), we pass self and 2 more args (total 3 positional) + with pytest.raises( + TypeError, match="too many positional arguments: expected 2, got 3" + ): + scalars_df_index["int64_col"].apply(foo, args=(10, 20)) + + # Missing required argument: foo takes 2 args, we only pass self (so y is missing) + with pytest.raises(TypeError, match="missing required argument: 'y'"): + scalars_df_index["int64_col"].apply(foo) + + +def test_transpilation_unsupported_ops_raise( + scalars_df_index, +): + def foo_with_if(x): + if x > 0: + return x + return -x + + with pytest.raises(ValueError): + scalars_df_index["int64_col"].apply(foo_with_if) + + def foo_with_loop(x): + total = 0 + for i in range(x): + total += i + return total + + with pytest.raises(ValueError): + scalars_df_index["int64_col"].apply(foo_with_loop) diff --git a/packages/bigframes/third_party/bigframes_vendored/pandas/core/frame.py b/packages/bigframes/third_party/bigframes_vendored/pandas/core/frame.py index b13b4a6d14eb..e84f46861d9f 100644 --- a/packages/bigframes/third_party/bigframes_vendored/pandas/core/frame.py +++ b/packages/bigframes/third_party/bigframes_vendored/pandas/core/frame.py @@ -4470,6 +4470,22 @@ def map(self, func, na_action: Optional[str] = None) -> DataFrame: [7 rows x 2 columns] + With experimental Python Transpiler enabled, you can use some lambda functions without + deploying them as remote functions. + + >>> bpd.options.experiments.enable_python_transpiler = True + >>> df_minutes.map(lambda hours: hours / 60) + system_minutes user_minutes + 0 0.0 0.0 + 1 0.5 0.25 + 2 1.0 1.25 + 3 1.5 + 4 1.5 0.1 + 5 2.0 + 6 + + [7 rows x 2 columns] + Args: func (function): Python function wrapped by ``remote_function`` decorator, @@ -5053,6 +5069,15 @@ def apply(self, func, *, axis=0, args=(), **kwargs): 1 3.8 dtype: Float64 + With experimental Python Transpiler enabled, you can use some lambda functions without + deploying them as remote functions: + + >>> bpd.options.experiments.enable_python_transpiler = True + >>> df.apply(lambda row: 1 + row.col1 + row.col2/row.col3, axis=1) + 0 2.6 + 1 3.8 + dtype: Float64 + Args: func (function): Function to apply to each column or row. To apply to each row diff --git a/packages/bigframes/third_party/bigframes_vendored/pandas/core/series.py b/packages/bigframes/third_party/bigframes_vendored/pandas/core/series.py index 42c543018c64..183f36ef5a49 100644 --- a/packages/bigframes/third_party/bigframes_vendored/pandas/core/series.py +++ b/packages/bigframes/third_party/bigframes_vendored/pandas/core/series.py @@ -5631,6 +5631,17 @@ def map( 3 rAbbIt dtype: string + With experimental Python Transpiler enabled, you can use some lambda functions without + deploying them as remote functions: + + >>> bpd.options.experiments.enable_python_transpiler = True + >>> s.map(lambda val: val + "fish") + 0 catfish + 1 dogfish + 2 + 3 rabbitfish + dtype: string + Args: arg (function, Mapping, Series): remote function, collections.abc.Mapping subclass or Series From 3a67b7f05f0e24d2e3fb826e79a5ed69257a49cd Mon Sep 17 00:00:00 2001 From: Chalmer Lowe Date: Tue, 23 Jun 2026 14:01:43 -0400 Subject: [PATCH 116/174] feat(mypy): centralize mypy.ini and update templates (#17523) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit > [!note] > This is step one of a multi-step process. The work done here is outlined below. Additional steps (to be completed in other PRs) include: > * generate the **generated packages** > * generate and/or post process **hybrid packages** This work: * Adds a centralized `mypy.ini` file at the root of the repository. * Updates GAPIC generator templates to omit local `mypy.ini` and dynamically resolve the root config via a `MYPY_CONFIG_FILE` constant. > [!note] > Work on strictly handwritten libraries is outside the scope of this PR and can be found here: https://github.com/googleapis/google-cloud-python/pull/17409 Partially resolves: #17322 🦕 --- mypy.ini | 100 ++++++++++++++++++ .../gapic/ads-templates/mypy.ini.j2 | 3 - .../gapic/ads-templates/noxfile.py.j2 | 9 ++ .../gapic/templates/mypy.ini.j2 | 15 --- .../gapic/templates/noxfile.py.j2 | 7 ++ .../test/integration_test.bzl | 1 + .../tests/integration/goldens/asset/mypy.ini | 15 --- .../integration/goldens/asset/noxfile.py | 7 ++ .../integration/goldens/credentials/mypy.ini | 15 --- .../goldens/credentials/noxfile.py | 7 ++ .../integration/goldens/eventarc/mypy.ini | 15 --- .../integration/goldens/eventarc/noxfile.py | 7 ++ .../integration/goldens/logging/mypy.ini | 15 --- .../integration/goldens/logging/noxfile.py | 7 ++ .../goldens/logging_internal/mypy.ini | 15 --- .../goldens/logging_internal/noxfile.py | 7 ++ .../tests/integration/goldens/redis/mypy.ini | 15 --- .../integration/goldens/redis/noxfile.py | 7 ++ .../goldens/redis_selective/mypy.ini | 15 --- .../goldens/redis_selective/noxfile.py | 7 ++ .../goldens/storagebatchoperations/mypy.ini | 15 --- .../goldens/storagebatchoperations/noxfile.py | 7 ++ 22 files changed, 173 insertions(+), 138 deletions(-) create mode 100644 mypy.ini delete mode 100644 packages/gapic-generator/gapic/ads-templates/mypy.ini.j2 delete mode 100644 packages/gapic-generator/gapic/templates/mypy.ini.j2 delete mode 100755 packages/gapic-generator/tests/integration/goldens/asset/mypy.ini delete mode 100755 packages/gapic-generator/tests/integration/goldens/credentials/mypy.ini delete mode 100755 packages/gapic-generator/tests/integration/goldens/eventarc/mypy.ini delete mode 100755 packages/gapic-generator/tests/integration/goldens/logging/mypy.ini delete mode 100755 packages/gapic-generator/tests/integration/goldens/logging_internal/mypy.ini delete mode 100755 packages/gapic-generator/tests/integration/goldens/redis/mypy.ini delete mode 100755 packages/gapic-generator/tests/integration/goldens/redis_selective/mypy.ini delete mode 100755 packages/gapic-generator/tests/integration/goldens/storagebatchoperations/mypy.ini diff --git a/mypy.ini b/mypy.ini new file mode 100644 index 000000000000..e36c23ebbc8a --- /dev/null +++ b/mypy.ini @@ -0,0 +1,100 @@ +[mypy] +namespace_packages = True +ignore_missing_imports = False + +# Helps mypy navigate the "google" namespace more reliably in 3.10+ +explicit_package_bases = True + +# Performance: reuse results from previous runs to speed up "nox" +incremental = True + +exclude = (?x)( + (^|/)third_party/ + | (^|/)tests/unit/resources/ + | (^|/)tests/unit/gapic/ + ) + + +# ============================================================================== +# GLOBAL THIRD-PARTY & SHARED LIBRARY IGNORES +# ============================================================================== + +[mypy-anywidget] +ignore_missing_imports = True + +[mypy-cloudpickle.*] +ignore_missing_imports = True + +[mypy-flask] +ignore_missing_imports = True + +[mypy-google.auth.*] +ignore_missing_imports = True + +[mypy-google.cloud.bigtable] +ignore_missing_imports = True + +[mypy-google.cloud.pubsub] +ignore_missing_imports = True + +[mypy-google.colab] +ignore_missing_imports = True + +[mypy-google.iam.*] +ignore_missing_imports = True + +[mypy-google.longrunning.*] +ignore_missing_imports = True + +[mypy-google.oauth2.*] +ignore_missing_imports = True + +[mypy-google.protobuf.*] +ignore_missing_imports = True + +[mypy-google.rpc.*] +ignore_missing_imports = True + +[mypy-google.type.*] +ignore_missing_imports = True + +[mypy-grpc.*] +ignore_missing_imports = True + +[mypy-ibis.*] +ignore_missing_imports = True + +[mypy-ipywidgets] +ignore_missing_imports = True + +[mypy-proto.*] +ignore_missing_imports = True + +[mypy-pyarrow.*] +ignore_missing_imports = True + +[mypy-pydata_google_auth] +ignore_missing_imports = True + +[mypy-pytest] +ignore_missing_imports = True + +[mypy-pytz] +ignore_missing_imports = True + + +# ============================================================================== +# PACKAGE-SPECIFIC OVERRIDES & EXCEPTIONS +# ============================================================================== + +# --- google-cloud-bigtable --- +[mypy-google.cloud.bigtable.*] +ignore_errors = True + +[mypy-google.cloud.bigtable.data.*] +check_untyped_defs = True +warn_unreachable = True +disallow_any_generics = True +ignore_errors = False + + diff --git a/packages/gapic-generator/gapic/ads-templates/mypy.ini.j2 b/packages/gapic-generator/gapic/ads-templates/mypy.ini.j2 deleted file mode 100644 index cb397f571128..000000000000 --- a/packages/gapic-generator/gapic/ads-templates/mypy.ini.j2 +++ /dev/null @@ -1,3 +0,0 @@ -[mypy] -python_version = 3.10 -namespace_packages = True diff --git a/packages/gapic-generator/gapic/ads-templates/noxfile.py.j2 b/packages/gapic-generator/gapic/ads-templates/noxfile.py.j2 index 0a42cd6e4fa0..ecc8da38f38b 100644 --- a/packages/gapic-generator/gapic/ads-templates/noxfile.py.j2 +++ b/packages/gapic-generator/gapic/ads-templates/noxfile.py.j2 @@ -3,9 +3,17 @@ {% block content %} import os +import pathlib import nox # type: ignore +CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() +# Search upwards to support running nox from both monorepo packages and integration test goldens. +MYPY_CONFIG_FILE = next( + (str(p / "mypy.ini") for p in CURRENT_DIRECTORY.parents if (p / "mypy.ini").exists()), + str(CURRENT_DIRECTORY.parent.parent / "mypy.ini"), +) + # TODO(https://github.com/googleapis/gapic-generator-python/issues/2450): # Add tests for Python 3.15 alpha1 @@ -44,6 +52,7 @@ def mypy(session): session.install('.') session.run( 'mypy', + f"--config-file={MYPY_CONFIG_FILE}", {% if api.naming.module_namespace %} '{{ api.naming.module_namespace[0] }}', {% else %} diff --git a/packages/gapic-generator/gapic/templates/mypy.ini.j2 b/packages/gapic-generator/gapic/templates/mypy.ini.j2 deleted file mode 100644 index defc5b1ed854..000000000000 --- a/packages/gapic-generator/gapic/templates/mypy.ini.j2 +++ /dev/null @@ -1,15 +0,0 @@ -[mypy] -python_version = 3.14 -namespace_packages = True -ignore_missing_imports = False - -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): -# Dependencies that historically lacks py.typed markers -[mypy-google.iam.*] -ignore_missing_imports = True - -# Helps mypy navigate the 'google' namespace more reliably in 3.10+ -explicit_package_bases = True - -# Performance: reuse results from previous runs to speed up 'nox' -incremental = True \ No newline at end of file diff --git a/packages/gapic-generator/gapic/templates/noxfile.py.j2 b/packages/gapic-generator/gapic/templates/noxfile.py.j2 index a59d98087467..8db595319396 100644 --- a/packages/gapic-generator/gapic/templates/noxfile.py.j2 +++ b/packages/gapic-generator/gapic/templates/noxfile.py.j2 @@ -38,6 +38,12 @@ DEFAULT_PYTHON_VERSION = "3.14" PREVIEW_PYTHON_VERSION = "3.15" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() +# Path to the centralized mypy configuration file at the repository root. +# Search upwards to support running nox from both monorepo packages and integration test goldens. +MYPY_CONFIG_FILE = next( + (str(p / "mypy.ini") for p in CURRENT_DIRECTORY.parents if (p / "mypy.ini").exists()), + str(CURRENT_DIRECTORY.parent.parent / "mypy.ini"), +) if (CURRENT_DIRECTORY / "testing").exists(): LOWER_BOUND_CONSTRAINTS_FILE = ( @@ -99,6 +105,7 @@ def mypy(session): session.install(".") session.run( "mypy", + f"--config-file={MYPY_CONFIG_FILE}", "-p", {% if api.naming.module_namespace %} "{{ api.naming.module_namespace[0] }}", diff --git a/packages/gapic-generator/rules_python_gapic/test/integration_test.bzl b/packages/gapic-generator/rules_python_gapic/test/integration_test.bzl index 7aaea5ab267c..6a1107609c7e 100644 --- a/packages/gapic-generator/rules_python_gapic/test/integration_test.bzl +++ b/packages/gapic-generator/rules_python_gapic/test/integration_test.bzl @@ -116,6 +116,7 @@ def _overwrite_golden_impl(ctx): # Filename pattern-based removal is needed to preserve the BUILD.bazel file. find tests/integration/goldens/{api_name}/ -name \\*.py -type f -delete find tests/integration/goldens/{api_name}/ -name \\*.json -type f -delete + find tests/integration/goldens/{api_name}/ -name \\*.ini -type f -delete unzip -ao {goldens_output_zip} -d tests/integration/goldens/{api_name} """.format( goldens_output_zip = goldens_output_zip.path, diff --git a/packages/gapic-generator/tests/integration/goldens/asset/mypy.ini b/packages/gapic-generator/tests/integration/goldens/asset/mypy.ini deleted file mode 100755 index e0e0da2e9e40..000000000000 --- a/packages/gapic-generator/tests/integration/goldens/asset/mypy.ini +++ /dev/null @@ -1,15 +0,0 @@ -[mypy] -python_version = 3.14 -namespace_packages = True -ignore_missing_imports = False - -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): -# Dependencies that historically lacks py.typed markers -[mypy-google.iam.*] -ignore_missing_imports = True - -# Helps mypy navigate the 'google' namespace more reliably in 3.10+ -explicit_package_bases = True - -# Performance: reuse results from previous runs to speed up 'nox' -incremental = True diff --git a/packages/gapic-generator/tests/integration/goldens/asset/noxfile.py b/packages/gapic-generator/tests/integration/goldens/asset/noxfile.py index 58ded83c89ac..09d28712c73c 100755 --- a/packages/gapic-generator/tests/integration/goldens/asset/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/asset/noxfile.py @@ -45,6 +45,12 @@ PREVIEW_PYTHON_VERSION = "3.15" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() +# Path to the centralized mypy configuration file at the repository root. +# Search upwards to support running nox from both monorepo packages and integration test goldens. +MYPY_CONFIG_FILE = next( + (str(p / "mypy.ini") for p in CURRENT_DIRECTORY.parents if (p / "mypy.ini").exists()), + str(CURRENT_DIRECTORY.parent.parent / "mypy.ini"), +) if (CURRENT_DIRECTORY / "testing").exists(): LOWER_BOUND_CONSTRAINTS_FILE = ( @@ -106,6 +112,7 @@ def mypy(session): session.install(".") session.run( "mypy", + f"--config-file={MYPY_CONFIG_FILE}", "-p", "google", "--check-untyped-defs", diff --git a/packages/gapic-generator/tests/integration/goldens/credentials/mypy.ini b/packages/gapic-generator/tests/integration/goldens/credentials/mypy.ini deleted file mode 100755 index e0e0da2e9e40..000000000000 --- a/packages/gapic-generator/tests/integration/goldens/credentials/mypy.ini +++ /dev/null @@ -1,15 +0,0 @@ -[mypy] -python_version = 3.14 -namespace_packages = True -ignore_missing_imports = False - -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): -# Dependencies that historically lacks py.typed markers -[mypy-google.iam.*] -ignore_missing_imports = True - -# Helps mypy navigate the 'google' namespace more reliably in 3.10+ -explicit_package_bases = True - -# Performance: reuse results from previous runs to speed up 'nox' -incremental = True diff --git a/packages/gapic-generator/tests/integration/goldens/credentials/noxfile.py b/packages/gapic-generator/tests/integration/goldens/credentials/noxfile.py index af6482e5ff68..65e26efe21d3 100755 --- a/packages/gapic-generator/tests/integration/goldens/credentials/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/credentials/noxfile.py @@ -45,6 +45,12 @@ PREVIEW_PYTHON_VERSION = "3.15" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() +# Path to the centralized mypy configuration file at the repository root. +# Search upwards to support running nox from both monorepo packages and integration test goldens. +MYPY_CONFIG_FILE = next( + (str(p / "mypy.ini") for p in CURRENT_DIRECTORY.parents if (p / "mypy.ini").exists()), + str(CURRENT_DIRECTORY.parent.parent / "mypy.ini"), +) if (CURRENT_DIRECTORY / "testing").exists(): LOWER_BOUND_CONSTRAINTS_FILE = ( @@ -106,6 +112,7 @@ def mypy(session): session.install(".") session.run( "mypy", + f"--config-file={MYPY_CONFIG_FILE}", "-p", "google", "--check-untyped-defs", diff --git a/packages/gapic-generator/tests/integration/goldens/eventarc/mypy.ini b/packages/gapic-generator/tests/integration/goldens/eventarc/mypy.ini deleted file mode 100755 index e0e0da2e9e40..000000000000 --- a/packages/gapic-generator/tests/integration/goldens/eventarc/mypy.ini +++ /dev/null @@ -1,15 +0,0 @@ -[mypy] -python_version = 3.14 -namespace_packages = True -ignore_missing_imports = False - -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): -# Dependencies that historically lacks py.typed markers -[mypy-google.iam.*] -ignore_missing_imports = True - -# Helps mypy navigate the 'google' namespace more reliably in 3.10+ -explicit_package_bases = True - -# Performance: reuse results from previous runs to speed up 'nox' -incremental = True diff --git a/packages/gapic-generator/tests/integration/goldens/eventarc/noxfile.py b/packages/gapic-generator/tests/integration/goldens/eventarc/noxfile.py index 9f89e95f5237..42b2349e2cc1 100755 --- a/packages/gapic-generator/tests/integration/goldens/eventarc/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/eventarc/noxfile.py @@ -45,6 +45,12 @@ PREVIEW_PYTHON_VERSION = "3.15" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() +# Path to the centralized mypy configuration file at the repository root. +# Search upwards to support running nox from both monorepo packages and integration test goldens. +MYPY_CONFIG_FILE = next( + (str(p / "mypy.ini") for p in CURRENT_DIRECTORY.parents if (p / "mypy.ini").exists()), + str(CURRENT_DIRECTORY.parent.parent / "mypy.ini"), +) if (CURRENT_DIRECTORY / "testing").exists(): LOWER_BOUND_CONSTRAINTS_FILE = ( @@ -106,6 +112,7 @@ def mypy(session): session.install(".") session.run( "mypy", + f"--config-file={MYPY_CONFIG_FILE}", "-p", "google", "--check-untyped-defs", diff --git a/packages/gapic-generator/tests/integration/goldens/logging/mypy.ini b/packages/gapic-generator/tests/integration/goldens/logging/mypy.ini deleted file mode 100755 index e0e0da2e9e40..000000000000 --- a/packages/gapic-generator/tests/integration/goldens/logging/mypy.ini +++ /dev/null @@ -1,15 +0,0 @@ -[mypy] -python_version = 3.14 -namespace_packages = True -ignore_missing_imports = False - -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): -# Dependencies that historically lacks py.typed markers -[mypy-google.iam.*] -ignore_missing_imports = True - -# Helps mypy navigate the 'google' namespace more reliably in 3.10+ -explicit_package_bases = True - -# Performance: reuse results from previous runs to speed up 'nox' -incremental = True diff --git a/packages/gapic-generator/tests/integration/goldens/logging/noxfile.py b/packages/gapic-generator/tests/integration/goldens/logging/noxfile.py index dfe763b3d029..09e4b345592a 100755 --- a/packages/gapic-generator/tests/integration/goldens/logging/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/logging/noxfile.py @@ -45,6 +45,12 @@ PREVIEW_PYTHON_VERSION = "3.15" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() +# Path to the centralized mypy configuration file at the repository root. +# Search upwards to support running nox from both monorepo packages and integration test goldens. +MYPY_CONFIG_FILE = next( + (str(p / "mypy.ini") for p in CURRENT_DIRECTORY.parents if (p / "mypy.ini").exists()), + str(CURRENT_DIRECTORY.parent.parent / "mypy.ini"), +) if (CURRENT_DIRECTORY / "testing").exists(): LOWER_BOUND_CONSTRAINTS_FILE = ( @@ -106,6 +112,7 @@ def mypy(session): session.install(".") session.run( "mypy", + f"--config-file={MYPY_CONFIG_FILE}", "-p", "google", "--check-untyped-defs", diff --git a/packages/gapic-generator/tests/integration/goldens/logging_internal/mypy.ini b/packages/gapic-generator/tests/integration/goldens/logging_internal/mypy.ini deleted file mode 100755 index e0e0da2e9e40..000000000000 --- a/packages/gapic-generator/tests/integration/goldens/logging_internal/mypy.ini +++ /dev/null @@ -1,15 +0,0 @@ -[mypy] -python_version = 3.14 -namespace_packages = True -ignore_missing_imports = False - -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): -# Dependencies that historically lacks py.typed markers -[mypy-google.iam.*] -ignore_missing_imports = True - -# Helps mypy navigate the 'google' namespace more reliably in 3.10+ -explicit_package_bases = True - -# Performance: reuse results from previous runs to speed up 'nox' -incremental = True diff --git a/packages/gapic-generator/tests/integration/goldens/logging_internal/noxfile.py b/packages/gapic-generator/tests/integration/goldens/logging_internal/noxfile.py index dfe763b3d029..09e4b345592a 100755 --- a/packages/gapic-generator/tests/integration/goldens/logging_internal/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/logging_internal/noxfile.py @@ -45,6 +45,12 @@ PREVIEW_PYTHON_VERSION = "3.15" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() +# Path to the centralized mypy configuration file at the repository root. +# Search upwards to support running nox from both monorepo packages and integration test goldens. +MYPY_CONFIG_FILE = next( + (str(p / "mypy.ini") for p in CURRENT_DIRECTORY.parents if (p / "mypy.ini").exists()), + str(CURRENT_DIRECTORY.parent.parent / "mypy.ini"), +) if (CURRENT_DIRECTORY / "testing").exists(): LOWER_BOUND_CONSTRAINTS_FILE = ( @@ -106,6 +112,7 @@ def mypy(session): session.install(".") session.run( "mypy", + f"--config-file={MYPY_CONFIG_FILE}", "-p", "google", "--check-untyped-defs", diff --git a/packages/gapic-generator/tests/integration/goldens/redis/mypy.ini b/packages/gapic-generator/tests/integration/goldens/redis/mypy.ini deleted file mode 100755 index e0e0da2e9e40..000000000000 --- a/packages/gapic-generator/tests/integration/goldens/redis/mypy.ini +++ /dev/null @@ -1,15 +0,0 @@ -[mypy] -python_version = 3.14 -namespace_packages = True -ignore_missing_imports = False - -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): -# Dependencies that historically lacks py.typed markers -[mypy-google.iam.*] -ignore_missing_imports = True - -# Helps mypy navigate the 'google' namespace more reliably in 3.10+ -explicit_package_bases = True - -# Performance: reuse results from previous runs to speed up 'nox' -incremental = True diff --git a/packages/gapic-generator/tests/integration/goldens/redis/noxfile.py b/packages/gapic-generator/tests/integration/goldens/redis/noxfile.py index deedbe421748..9b3356dd1272 100755 --- a/packages/gapic-generator/tests/integration/goldens/redis/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/redis/noxfile.py @@ -45,6 +45,12 @@ PREVIEW_PYTHON_VERSION = "3.15" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() +# Path to the centralized mypy configuration file at the repository root. +# Search upwards to support running nox from both monorepo packages and integration test goldens. +MYPY_CONFIG_FILE = next( + (str(p / "mypy.ini") for p in CURRENT_DIRECTORY.parents if (p / "mypy.ini").exists()), + str(CURRENT_DIRECTORY.parent.parent / "mypy.ini"), +) if (CURRENT_DIRECTORY / "testing").exists(): LOWER_BOUND_CONSTRAINTS_FILE = ( @@ -106,6 +112,7 @@ def mypy(session): session.install(".") session.run( "mypy", + f"--config-file={MYPY_CONFIG_FILE}", "-p", "google", "--check-untyped-defs", diff --git a/packages/gapic-generator/tests/integration/goldens/redis_selective/mypy.ini b/packages/gapic-generator/tests/integration/goldens/redis_selective/mypy.ini deleted file mode 100755 index e0e0da2e9e40..000000000000 --- a/packages/gapic-generator/tests/integration/goldens/redis_selective/mypy.ini +++ /dev/null @@ -1,15 +0,0 @@ -[mypy] -python_version = 3.14 -namespace_packages = True -ignore_missing_imports = False - -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): -# Dependencies that historically lacks py.typed markers -[mypy-google.iam.*] -ignore_missing_imports = True - -# Helps mypy navigate the 'google' namespace more reliably in 3.10+ -explicit_package_bases = True - -# Performance: reuse results from previous runs to speed up 'nox' -incremental = True diff --git a/packages/gapic-generator/tests/integration/goldens/redis_selective/noxfile.py b/packages/gapic-generator/tests/integration/goldens/redis_selective/noxfile.py index deedbe421748..9b3356dd1272 100755 --- a/packages/gapic-generator/tests/integration/goldens/redis_selective/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/redis_selective/noxfile.py @@ -45,6 +45,12 @@ PREVIEW_PYTHON_VERSION = "3.15" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() +# Path to the centralized mypy configuration file at the repository root. +# Search upwards to support running nox from both monorepo packages and integration test goldens. +MYPY_CONFIG_FILE = next( + (str(p / "mypy.ini") for p in CURRENT_DIRECTORY.parents if (p / "mypy.ini").exists()), + str(CURRENT_DIRECTORY.parent.parent / "mypy.ini"), +) if (CURRENT_DIRECTORY / "testing").exists(): LOWER_BOUND_CONSTRAINTS_FILE = ( @@ -106,6 +112,7 @@ def mypy(session): session.install(".") session.run( "mypy", + f"--config-file={MYPY_CONFIG_FILE}", "-p", "google", "--check-untyped-defs", diff --git a/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/mypy.ini b/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/mypy.ini deleted file mode 100755 index e0e0da2e9e40..000000000000 --- a/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/mypy.ini +++ /dev/null @@ -1,15 +0,0 @@ -[mypy] -python_version = 3.14 -namespace_packages = True -ignore_missing_imports = False - -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): -# Dependencies that historically lacks py.typed markers -[mypy-google.iam.*] -ignore_missing_imports = True - -# Helps mypy navigate the 'google' namespace more reliably in 3.10+ -explicit_package_bases = True - -# Performance: reuse results from previous runs to speed up 'nox' -incremental = True diff --git a/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/noxfile.py b/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/noxfile.py index ea0dffab5b4c..db370dd3dd0f 100755 --- a/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/noxfile.py +++ b/packages/gapic-generator/tests/integration/goldens/storagebatchoperations/noxfile.py @@ -45,6 +45,12 @@ PREVIEW_PYTHON_VERSION = "3.15" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() +# Path to the centralized mypy configuration file at the repository root. +# Search upwards to support running nox from both monorepo packages and integration test goldens. +MYPY_CONFIG_FILE = next( + (str(p / "mypy.ini") for p in CURRENT_DIRECTORY.parents if (p / "mypy.ini").exists()), + str(CURRENT_DIRECTORY.parent.parent / "mypy.ini"), +) if (CURRENT_DIRECTORY / "testing").exists(): LOWER_BOUND_CONSTRAINTS_FILE = ( @@ -106,6 +112,7 @@ def mypy(session): session.install(".") session.run( "mypy", + f"--config-file={MYPY_CONFIG_FILE}", "-p", "google", "--check-untyped-defs", From ee74e3140a2e11936c36714a27393c3072bed6c7 Mon Sep 17 00:00:00 2001 From: Shenyang Cai Date: Tue, 23 Jun 2026 12:10:47 -0700 Subject: [PATCH 117/174] feat(bigframes): add AI TVFs to the pandas bq accessor (#17402) Also updated the tests to fully utilize the mocking framework. internal issue: b/517233441 --- .../extensions/bigframes/series_accessor.py | 53 +++- .../core/abstract_series_accessor.py | 50 ++++ .../extensions/core/series_accessor.py | 175 ++++++----- .../extensions/core/series_tvf_mixins.py | 129 ++++++++ .../extensions/pandas/series_accessor.py | 59 +++- .../scripts/data/sql-functions/ai.yaml | 1 + .../scripts/generate_bigframes_bigquery.py | 10 +- .../templates/bigframes_series_accessor.py.j2 | 21 +- .../templates/core_series_accessor.py.j2 | 40 +-- .../templates/pandas_series_accessor.py.j2 | 23 +- .../core/test_dataframe_accessor.py | 276 +++++++++++------- .../extensions/core/test_series_tvf_mixins.py | 248 ++++++++++++++++ 12 files changed, 812 insertions(+), 273 deletions(-) create mode 100644 packages/bigframes/bigframes/extensions/core/abstract_series_accessor.py create mode 100644 packages/bigframes/bigframes/extensions/core/series_tvf_mixins.py create mode 100644 packages/bigframes/scripts/data/sql-functions/ai.yaml create mode 100644 packages/bigframes/tests/unit/extensions/core/test_series_tvf_mixins.py diff --git a/packages/bigframes/bigframes/extensions/bigframes/series_accessor.py b/packages/bigframes/bigframes/extensions/bigframes/series_accessor.py index b67d007b88e7..8379e6a145a0 100644 --- a/packages/bigframes/bigframes/extensions/bigframes/series_accessor.py +++ b/packages/bigframes/bigframes/extensions/bigframes/series_accessor.py @@ -20,41 +20,68 @@ from typing import Optional, TypeVar, cast -import bigframes.extensions.core.series_accessor as core_accessor -import bigframes.series -import bigframes.session +from bigframes import dataframe, series, session from bigframes.core.logging import log_adapter +from bigframes.extensions.core import series_accessor as core_accessor -S = TypeVar("S", bound="bigframes.series.Series") +T = TypeVar("T", bound="dataframe.DataFrame") +S = TypeVar("S", bound="series.Series") @log_adapter.class_logger -class BigframesBigQuerySeriesAccessor(core_accessor.BigQuerySeriesAccessor[S]): +class BigframesBigQuerySeriesAccessor(core_accessor.BigQuerySeriesAccessor[T, S]): def __init__(self, bf_obj: S): super().__init__(bf_obj) def _bf_from_series( - self, session: Optional[bigframes.session.Session] = None - ) -> bigframes.series.Series: + self, session: Optional[session.Session] = None + ) -> series.Series: return self._obj - def _to_series(self, bf_series: bigframes.series.Series) -> S: + def _to_dataframe(self, bf_df: dataframe.DataFrame) -> T: + return cast(T, bf_df) + + def _to_series(self, bf_series: series.Series) -> S: return cast(S, bf_series) @property - def aead(self) -> BigframesAeadSeriesAccessor[S]: + def ai(self) -> BigframesAiSeriesAccessor[T, S]: + return BigframesAiSeriesAccessor(self._obj) + + @property + def aead(self) -> BigframesAeadSeriesAccessor[T, S]: return BigframesAeadSeriesAccessor(self._obj) @log_adapter.class_logger -class BigframesAeadSeriesAccessor(core_accessor.AeadSeriesAccessor[S]): +class BigframesAiSeriesAccessor(core_accessor.AiSeriesAccessor[T, S]): def __init__(self, bf_obj: S): super().__init__(bf_obj) def _bf_from_series( - self, session: Optional[bigframes.session.Session] = None - ) -> bigframes.series.Series: + self, session: Optional[session.Session] = None + ) -> series.Series: return self._obj - def _to_series(self, bf_series: bigframes.series.Series) -> S: + def _to_dataframe(self, bf_df: dataframe.DataFrame) -> T: + return cast(T, bf_df) + + def _to_series(self, bf_series: series.Series) -> S: + return cast(S, bf_series) + + +@log_adapter.class_logger +class BigframesAeadSeriesAccessor(core_accessor.AeadSeriesAccessor[T, S]): + def __init__(self, bf_obj: S): + super().__init__(bf_obj) + + def _bf_from_series( + self, session: Optional[session.Session] = None + ) -> series.Series: + return self._obj + + def _to_dataframe(self, bf_df: dataframe.DataFrame) -> T: + return cast(T, bf_df) + + def _to_series(self, bf_series: series.Series) -> S: return cast(S, bf_series) diff --git a/packages/bigframes/bigframes/extensions/core/abstract_series_accessor.py b/packages/bigframes/bigframes/extensions/core/abstract_series_accessor.py new file mode 100644 index 000000000000..22d098618770 --- /dev/null +++ b/packages/bigframes/bigframes/extensions/core/abstract_series_accessor.py @@ -0,0 +1,50 @@ +# Copyright 2026 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. +# +# DO NOT MODIFY THIS FILE DIRECTLY. +# This file was generated by the script: scripts/generate_bigframes_bigquery.py +# + +from __future__ import annotations + +import abc +from typing import ( + Generic, + Optional, + TypeVar, +) + +from bigframes import dataframe, series, session + +T = TypeVar("T") +S = TypeVar("S") + + +class AbstractBigQuerySeriesAccessor(abc.ABC, Generic[T, S]): + def __init__(self, obj: S): + self._obj = obj + + @abc.abstractmethod + def _bf_from_series( + self, session: Optional[session.Session] = None + ) -> series.Series: + """Convert the accessor's object to a BigFrames Series.""" + + @abc.abstractmethod + def _to_dataframe(self, bf_df: dataframe.DataFrame) -> T: + """Convert a BigFrames DataFrame to the accessor's object type.""" + + @abc.abstractmethod + def _to_series(self, bf_series: series.Series) -> S: + """Convert a BigFrames Series to the accessor's object type.""" diff --git a/packages/bigframes/bigframes/extensions/core/series_accessor.py b/packages/bigframes/bigframes/extensions/core/series_accessor.py index 96d0eb8d045e..86f34e9ab603 100644 --- a/packages/bigframes/bigframes/extensions/core/series_accessor.py +++ b/packages/bigframes/bigframes/extensions/core/series_accessor.py @@ -21,7 +21,6 @@ import abc from typing import ( Any, - Generic, Literal, Optional, TypeVar, @@ -29,51 +28,43 @@ cast, ) -import bigframes.core.col -import bigframes.core.sentinels as sentinels -import bigframes.series as series -import bigframes.session +from bigframes import series, session +from bigframes.core import col, sentinels +from bigframes.extensions.core import abstract_series_accessor, series_tvf_mixins +T = TypeVar("T") S = TypeVar("S") -class AbstractBigQuerySeriesAccessor(abc.ABC, Generic[S]): - def __init__(self, obj: S): - self._obj = obj - - @abc.abstractmethod - def _bf_from_series( - self, session: Optional[bigframes.session.Session] = None - ) -> series.Series: - """Convert the accessor's object to a BigFrames Series.""" +class BigQuerySeriesAccessor( + abstract_series_accessor.AbstractBigQuerySeriesAccessor[T, S] +): + """Series accessor for BigQuery functions.""" + @property @abc.abstractmethod - def _to_series(self, bf_series: series.Series) -> S: - """Convert a BigFrames Series to the accessor's object type.""" - - -class BigQuerySeriesAccessor(AbstractBigQuerySeriesAccessor[S]): - """Series accessor for BigQuery functions.""" + def ai(self) -> AiSeriesAccessor[T, S]: + """Accessor for BigQuery ai functions.""" @property @abc.abstractmethod - def aead(self) -> AeadSeriesAccessor[S]: + def aead(self) -> AeadSeriesAccessor[T, S]: """Accessor for BigQuery aead functions.""" def deterministic_decrypt_bytes( self, ciphertext: Union[ series.Series, - bigframes.core.col.Expression, + col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes], ], additional_data: Union[ series.Series, - bigframes.core.col.Expression, + col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes], ], *, - session: Optional[bigframes.session.Session] = None, + session: Optional[session.Session] = None, ) -> S: """Uses the matching key from `keyset` to decrypt `ciphertext` and verifies the integrity of the data using `additional_data`. Returns an error if decryption fails.""" from bigframes.operations.googlesql.global_namespace.aead_encryption import ( @@ -82,7 +73,7 @@ def deterministic_decrypt_bytes( # Resolve session from other arguments if not passed if session is None: - import bigframes.core.googlesql as googlesql + from bigframes.core import googlesql session = googlesql._find_session( ciphertext, @@ -101,16 +92,16 @@ def deterministic_decrypt_string( self, ciphertext: Union[ series.Series, - bigframes.core.col.Expression, + col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes], ], additional_data: Union[ series.Series, - bigframes.core.col.Expression, + col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], ], *, - session: Optional[bigframes.session.Session] = None, + session: Optional[session.Session] = None, ) -> S: """Like `DETERMINISTIC_DECRYPT_BYTES`, but where plaintext is of type STRING.""" from bigframes.operations.googlesql.global_namespace.aead_encryption import ( @@ -119,7 +110,7 @@ def deterministic_decrypt_string( # Resolve session from other arguments if not passed if session is None: - import bigframes.core.googlesql as googlesql + from bigframes.core import googlesql session = googlesql._find_session( ciphertext, @@ -138,16 +129,16 @@ def deterministic_encrypt( self, plaintext: Union[ series.Series, - bigframes.core.col.Expression, + col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes, str], ], additional_data: Union[ series.Series, - bigframes.core.col.Expression, + col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes, str], ], *, - session: Optional[bigframes.session.Session] = None, + session: Optional[session.Session] = None, ) -> S: """Encrypts `plaintext` using the primary cryptographic key in `keyset` using deterministic AEAD. The algorithm of the primary key must be `DETERMINISTIC_AEAD_AES_SIV_CMAC_256`. Binds the ciphertext to the context defined by `additional_data`. Returns `NULL` if any input is `NULL`.""" from bigframes.operations.googlesql.global_namespace.aead_encryption import ( @@ -156,7 +147,7 @@ def deterministic_encrypt( # Resolve session from other arguments if not passed if session is None: - import bigframes.core.googlesql as googlesql + from bigframes.core import googlesql session = googlesql._find_session( plaintext, @@ -175,11 +166,11 @@ def array_concat( self, array_expression_2: Union[ series.Series, - bigframes.core.col.Expression, + col.Expression, Union[Any, Literal[sentinels.Sentinel.ARGUMENT_DEFAULT]], ], *, - session: Optional[bigframes.session.Session] = None, + session: Optional[session.Session] = None, ) -> S: """Concatenates one or more arrays with the same element type into a single array.""" from bigframes.operations.googlesql.global_namespace.array import ( @@ -188,7 +179,7 @@ def array_concat( # Resolve session from other arguments if not passed if session is None: - import bigframes.core.googlesql as googlesql + from bigframes.core import googlesql session = googlesql._find_session( array_expression_2, @@ -204,7 +195,7 @@ def array_concat( def array_first( self, *, - session: Optional[bigframes.session.Session] = None, + session: Optional[session.Session] = None, ) -> S: """Takes an array and returns the first element in the array.""" from bigframes.operations.googlesql.global_namespace.array import ( @@ -221,11 +212,11 @@ def array_first_n( self, n: Union[ series.Series, - bigframes.core.col.Expression, + col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], int], ], *, - session: Optional[bigframes.session.Session] = None, + session: Optional[session.Session] = None, ) -> S: """Returns a prefix of `input_array` consisting of the first `n` elements.""" from bigframes.operations.googlesql.global_namespace.array import ( @@ -234,7 +225,7 @@ def array_first_n( # Resolve session from other arguments if not passed if session is None: - import bigframes.core.googlesql as googlesql + from bigframes.core import googlesql session = googlesql._find_session( n, @@ -251,11 +242,11 @@ def array_includes( self, search_value: Union[ series.Series, - bigframes.core.col.Expression, + col.Expression, Union[Any, Literal[sentinels.Sentinel.ARGUMENT_DEFAULT]], ], *, - session: Optional[bigframes.session.Session] = None, + session: Optional[session.Session] = None, ) -> S: """Takes an array and returns `TRUE` if there is an element in the array that is equal to the search_value.""" from bigframes.operations.googlesql.global_namespace.array import ( @@ -264,7 +255,7 @@ def array_includes( # Resolve session from other arguments if not passed if session is None: - import bigframes.core.googlesql as googlesql + from bigframes.core import googlesql session = googlesql._find_session( search_value, @@ -281,11 +272,11 @@ def array_includes_all( self, search_values: Union[ series.Series, - bigframes.core.col.Expression, + col.Expression, Union[Any, Literal[sentinels.Sentinel.ARGUMENT_DEFAULT]], ], *, - session: Optional[bigframes.session.Session] = None, + session: Optional[session.Session] = None, ) -> S: """Takes an array to search and an array of search values. Returns `TRUE` if all search values are in the array to search, otherwise returns `FALSE`.""" from bigframes.operations.googlesql.global_namespace.array import ( @@ -294,7 +285,7 @@ def array_includes_all( # Resolve session from other arguments if not passed if session is None: - import bigframes.core.googlesql as googlesql + from bigframes.core import googlesql session = googlesql._find_session( search_values, @@ -311,11 +302,11 @@ def array_includes_any( self, search_values: Union[ series.Series, - bigframes.core.col.Expression, + col.Expression, Union[Any, Literal[sentinels.Sentinel.ARGUMENT_DEFAULT]], ], *, - session: Optional[bigframes.session.Session] = None, + session: Optional[session.Session] = None, ) -> S: """Takes an array to search and an array of search values. Returns `TRUE` if any search values are in the array to search, otherwise returns `FALSE`.""" from bigframes.operations.googlesql.global_namespace.array import ( @@ -324,7 +315,7 @@ def array_includes_any( # Resolve session from other arguments if not passed if session is None: - import bigframes.core.googlesql as googlesql + from bigframes.core import googlesql session = googlesql._find_session( search_values, @@ -340,7 +331,7 @@ def array_includes_any( def array_is_distinct( self, *, - session: Optional[bigframes.session.Session] = None, + session: Optional[session.Session] = None, ) -> S: """Returns `TRUE` if the array contains no repeated elements, using the same equality comparison logic as `SELECT DISTINCT`.""" from bigframes.operations.googlesql.global_namespace.array import ( @@ -356,7 +347,7 @@ def array_is_distinct( def array_last( self, *, - session: Optional[bigframes.session.Session] = None, + session: Optional[session.Session] = None, ) -> S: """Takes an array and returns the last element in the array.""" from bigframes.operations.googlesql.global_namespace.array import ( @@ -372,7 +363,7 @@ def array_last( def array_length( self, *, - session: Optional[bigframes.session.Session] = None, + session: Optional[session.Session] = None, ) -> S: """Compute the length of each array element in the Series. @@ -435,7 +426,7 @@ def array_length( def array_reverse( self, *, - session: Optional[bigframes.session.Session] = None, + session: Optional[session.Session] = None, ) -> S: """Returns the input `ARRAY` with elements in reverse order.""" from bigframes.operations.googlesql.global_namespace.array import ( @@ -452,16 +443,16 @@ def array_slice( self, start_offset: Union[ series.Series, - bigframes.core.col.Expression, + col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], int], ], end_offset: Union[ series.Series, - bigframes.core.col.Expression, + col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], int], ], *, - session: Optional[bigframes.session.Session] = None, + session: Optional[session.Session] = None, ) -> S: """Returns an array containing zero or more consecutive elements from the input array.""" from bigframes.operations.googlesql.global_namespace.array import ( @@ -470,7 +461,7 @@ def array_slice( # Resolve session from other arguments if not passed if session is None: - import bigframes.core.googlesql as googlesql + from bigframes.core import googlesql session = googlesql._find_session( start_offset, @@ -489,16 +480,16 @@ def array_to_string( self, delimiter: Union[ series.Series, - bigframes.core.col.Expression, + col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes, str], ], null_text: Union[ series.Series, - bigframes.core.col.Expression, + col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes, str], ] = sentinels.Sentinel.ARGUMENT_DEFAULT, *, - session: Optional[bigframes.session.Session] = None, + session: Optional[session.Session] = None, ) -> S: """Converts array elements within a Series into delimited strings. @@ -553,7 +544,7 @@ def array_to_string( # Resolve session from other arguments if not passed if session is None: - import bigframes.core.googlesql as googlesql + from bigframes.core import googlesql session = googlesql._find_session( delimiter, @@ -572,11 +563,11 @@ def flatten( self, depth: Union[ series.Series, - bigframes.core.col.Expression, + col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], int], ] = sentinels.Sentinel.ARGUMENT_DEFAULT, *, - session: Optional[bigframes.session.Session] = None, + session: Optional[session.Session] = None, ) -> S: """Takes an array of nested data and flattens a specific part of it into a single, flat array with the [array elements field access operator][array-el-field-operator]. Returns `NULL` if the input value is `NULL`.""" from bigframes.operations.googlesql.global_namespace.array import ( @@ -585,7 +576,7 @@ def flatten( # Resolve session from other arguments if not passed if session is None: - import bigframes.core.googlesql as googlesql + from bigframes.core import googlesql session = googlesql._find_session( depth, @@ -601,7 +592,7 @@ def flatten( def bool_( self, *, - session: Optional[bigframes.session.Session] = None, + session: Optional[session.Session] = None, ) -> S: """Converts a JSON boolean to a SQL BOOL value.""" from bigframes.operations.googlesql.global_namespace.conversion import ( @@ -618,11 +609,11 @@ def double( self, wide_number_mode: Union[ series.Series, - bigframes.core.col.Expression, + col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], ] = sentinels.Sentinel.ARGUMENT_DEFAULT, *, - session: Optional[bigframes.session.Session] = None, + session: Optional[session.Session] = None, ) -> S: """Converts a JSON number to a SQL FLOAT64 value.""" from bigframes.operations.googlesql.global_namespace.conversion import ( @@ -631,7 +622,7 @@ def double( # Resolve session from other arguments if not passed if session is None: - import bigframes.core.googlesql as googlesql + from bigframes.core import googlesql session = googlesql._find_session( wide_number_mode, @@ -648,11 +639,11 @@ def float64( self, wide_number_mode: Union[ series.Series, - bigframes.core.col.Expression, + col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], ] = sentinels.Sentinel.ARGUMENT_DEFAULT, *, - session: Optional[bigframes.session.Session] = None, + session: Optional[session.Session] = None, ) -> S: """Converts a JSON number to a SQL FLOAT64 value.""" from bigframes.operations.googlesql.global_namespace.conversion import ( @@ -661,7 +652,7 @@ def float64( # Resolve session from other arguments if not passed if session is None: - import bigframes.core.googlesql as googlesql + from bigframes.core import googlesql session = googlesql._find_session( wide_number_mode, @@ -677,7 +668,7 @@ def float64( def int64( self, *, - session: Optional[bigframes.session.Session] = None, + session: Optional[session.Session] = None, ) -> S: """Converts a JSON number to a SQL INT64 value.""" from bigframes.operations.googlesql.global_namespace.conversion import ( @@ -693,7 +684,7 @@ def int64( def parse_bignumeric( self, *, - session: Optional[bigframes.session.Session] = None, + session: Optional[session.Session] = None, ) -> S: """Converts a STRING to a BIGNUMERIC value.""" from bigframes.operations.googlesql.global_namespace.conversion import ( @@ -709,7 +700,7 @@ def parse_bignumeric( def parse_numeric( self, *, - session: Optional[bigframes.session.Session] = None, + session: Optional[session.Session] = None, ) -> S: """Converts a STRING to a NUMERIC value.""" from bigframes.operations.googlesql.global_namespace.conversion import ( @@ -726,11 +717,11 @@ def string( self, timezone: Union[ series.Series, - bigframes.core.col.Expression, + col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], ] = sentinels.Sentinel.ARGUMENT_DEFAULT, *, - session: Optional[bigframes.session.Session] = None, + session: Optional[session.Session] = None, ) -> S: """Converts a value to a STRING value.""" from bigframes.operations.googlesql.global_namespace.conversion import ( @@ -739,7 +730,7 @@ def string( # Resolve session from other arguments if not passed if session is None: - import bigframes.core.googlesql as googlesql + from bigframes.core import googlesql session = googlesql._find_session( timezone, @@ -753,23 +744,27 @@ def string( return self._to_series(cast(series.Series, result)) -class AeadSeriesAccessor(AbstractBigQuerySeriesAccessor[S]): +class AiSeriesAccessor(series_tvf_mixins.AITVFMixin[T, S]): + """Series accessor for BigQuery ai functions.""" + + +class AeadSeriesAccessor(abstract_series_accessor.AbstractBigQuerySeriesAccessor[T, S]): """Series accessor for BigQuery aead functions.""" def decrypt_bytes( self, ciphertext: Union[ series.Series, - bigframes.core.col.Expression, + col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes], ], additional_data: Union[ series.Series, - bigframes.core.col.Expression, + col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes], ], *, - session: Optional[bigframes.session.Session] = None, + session: Optional[session.Session] = None, ) -> S: """Uses the matching key from keyset to decrypt ciphertext and verifies the integrity of the data using additional_data. Returns an error if decryption or verification fails.""" from bigframes.operations.googlesql.aead import ( @@ -778,7 +773,7 @@ def decrypt_bytes( # Resolve session from other arguments if not passed if session is None: - import bigframes.core.googlesql as googlesql + from bigframes.core import googlesql session = googlesql._find_session( ciphertext, @@ -797,16 +792,16 @@ def decrypt_string( self, ciphertext: Union[ series.Series, - bigframes.core.col.Expression, + col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes], ], additional_data: Union[ series.Series, - bigframes.core.col.Expression, + col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], ], *, - session: Optional[bigframes.session.Session] = None, + session: Optional[session.Session] = None, ) -> S: """Like AEAD.DECRYPT_BYTES, but where additional_data is of type STRING.""" from bigframes.operations.googlesql.aead import ( @@ -815,7 +810,7 @@ def decrypt_string( # Resolve session from other arguments if not passed if session is None: - import bigframes.core.googlesql as googlesql + from bigframes.core import googlesql session = googlesql._find_session( ciphertext, @@ -834,23 +829,23 @@ def encrypt( self, plaintext: Union[ series.Series, - bigframes.core.col.Expression, + col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes, str], ], additional_data: Union[ series.Series, - bigframes.core.col.Expression, + col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes, str], ], *, - session: Optional[bigframes.session.Session] = None, + session: Optional[session.Session] = None, ) -> S: """Encrypts plaintext using the primary cryptographic key in keyset. The algorithm of the primary key must be AEAD_AES_GCM_256. Binds the ciphertext to the context defined by additional_data. Returns NULL if any input is NULL.""" from bigframes.operations.googlesql.aead import encrypt as encrypt_impl # Resolve session from other arguments if not passed if session is None: - import bigframes.core.googlesql as googlesql + from bigframes.core import googlesql session = googlesql._find_session( plaintext, diff --git a/packages/bigframes/bigframes/extensions/core/series_tvf_mixins.py b/packages/bigframes/bigframes/extensions/core/series_tvf_mixins.py new file mode 100644 index 000000000000..673978bbe46c --- /dev/null +++ b/packages/bigframes/bigframes/extensions/core/series_tvf_mixins.py @@ -0,0 +1,129 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import annotations + +from typing import List, Mapping, TypeVar + +import pandas as pd + +from bigframes import session +from bigframes.extensions.core import abstract_series_accessor +from bigframes.ml import base as ml_base + +T = TypeVar("T") +S = TypeVar("S") + + +class AITVFMixin(abstract_series_accessor.AbstractBigQuerySeriesAccessor[T, S]): + def generate_embedding( + self, + model: ml_base.BaseEstimator | str | pd.Series, + *, + output_dimensionality: int | None = None, + task_type: str | None = None, + start_second: float | None = None, + end_second: float | None = None, + interval_seconds: float | None = None, + trial_id: int | None = None, + session: session.Session | None = None, + ) -> T: + """ + Creates embeddings that describe an entity — for example, a piece of text or an image. + + This is an accessor for :func:`bigframes.bigquery.ai.generate_embedding`. See that + function's documentation for detailed parameter descriptions and examples. + """ + import bigframes.bigquery.ai + + bf_series = self._bf_from_series(session) + result = bigframes.bigquery.ai.generate_embedding( + model, + bf_series, + output_dimensionality=output_dimensionality, + task_type=task_type, + start_second=start_second, + end_second=end_second, + interval_seconds=interval_seconds, + trial_id=trial_id, + ) + return self._to_dataframe(result) + + def generate_text( + self, + model: ml_base.BaseEstimator | str | pd.Series, + *, + temperature: float | None = None, + max_output_tokens: int | None = None, + top_k: int | None = None, + top_p: float | None = None, + stop_sequences: List[str] | None = None, + ground_with_google_search: bool | None = None, + request_type: str | None = None, + session: session.Session | None = None, + ) -> T: + """ + Generates text using a BigQuery ML model. + + This is an accessor for :func:`bigframes.bigquery.ai.generate_text`. See that + function's documentation for detailed parameter descriptions and examples. + """ + import bigframes.bigquery.ai + + bf_series = self._bf_from_series(session) + result = bigframes.bigquery.ai.generate_text( + model, + bf_series, + temperature=temperature, + max_output_tokens=max_output_tokens, + top_k=top_k, + top_p=top_p, + stop_sequences=stop_sequences, + ground_with_google_search=ground_with_google_search, + request_type=request_type, + ) + return self._to_dataframe(result) + + def generate_table( + self, + model: ml_base.BaseEstimator | str | pd.Series, + *, + output_schema: str | Mapping[str, str], + temperature: float | None = None, + top_p: float | None = None, + max_output_tokens: int | None = None, + stop_sequences: List[str] | None = None, + request_type: str | None = None, + session: session.Session | None = None, + ) -> T: + """ + Generates a table using a BigQuery ML model. + + This is an accessor for :func:`bigframes.bigquery.ai.generate_table`. See that + function's documentation for detailed parameter descriptions and examples. + """ + import bigframes.bigquery.ai + + bf_series = self._bf_from_series(session) + result = bigframes.bigquery.ai.generate_table( + model, + bf_series, + output_schema=output_schema, + temperature=temperature, + top_p=top_p, + max_output_tokens=max_output_tokens, + stop_sequences=stop_sequences, + request_type=request_type, + ) + return self._to_dataframe(result) diff --git a/packages/bigframes/bigframes/extensions/pandas/series_accessor.py b/packages/bigframes/bigframes/extensions/pandas/series_accessor.py index 837664c6e1f5..204f1e0d2cf3 100644 --- a/packages/bigframes/bigframes/extensions/pandas/series_accessor.py +++ b/packages/bigframes/bigframes/extensions/pandas/series_accessor.py @@ -23,47 +23,76 @@ import pandas import pandas.api.extensions -import bigframes.core.global_session as bf_session -import bigframes.extensions.core.series_accessor as core_accessor -import bigframes.series -import bigframes.session +from bigframes import dataframe, series, session +from bigframes.core import global_session as bf_session from bigframes.core.logging import log_adapter +from bigframes.extensions.core import series_accessor as core_accessor +T = TypeVar("T", bound="pandas.DataFrame") S = TypeVar("S", bound="pandas.Series") @pandas.api.extensions.register_series_accessor("bigquery") @log_adapter.class_logger -class PandasBigQuerySeriesAccessor(core_accessor.BigQuerySeriesAccessor[S]): +class PandasBigQuerySeriesAccessor(core_accessor.BigQuerySeriesAccessor[T, S]): def __init__(self, pandas_obj: S): super().__init__(pandas_obj) def _bf_from_series( - self, session: Optional[bigframes.session.Session] = None - ) -> bigframes.series.Series: + self, session: Optional[session.Session] = None + ) -> series.Series: if session is None: session = bf_session.get_global_session() - return cast(bigframes.series.Series, session.read_pandas(self._obj)) + return cast(series.Series, session.read_pandas(self._obj)) - def _to_series(self, bf_series: bigframes.series.Series) -> S: + def _to_dataframe(self, bf_df: dataframe.DataFrame) -> T: + return cast(T, bf_df.to_pandas(ordered=True)) + + def _to_series(self, bf_series: series.Series) -> S: return cast(S, bf_series.to_pandas(ordered=True)) @property - def aead(self) -> PandasAeadSeriesAccessor[S]: + def ai(self) -> PandasAiSeriesAccessor[T, S]: + return PandasAiSeriesAccessor(self._obj) + + @property + def aead(self) -> PandasAeadSeriesAccessor[T, S]: return PandasAeadSeriesAccessor(self._obj) @log_adapter.class_logger -class PandasAeadSeriesAccessor(core_accessor.AeadSeriesAccessor[S]): +class PandasAiSeriesAccessor(core_accessor.AiSeriesAccessor[T, S]): + def __init__(self, pandas_obj: S): + super().__init__(pandas_obj) + + def _bf_from_series( + self, session: Optional[session.Session] = None + ) -> series.Series: + if session is None: + session = bf_session.get_global_session() + return cast(series.Series, session.read_pandas(self._obj)) + + def _to_dataframe(self, bf_df: dataframe.DataFrame) -> T: + return cast(T, bf_df.to_pandas(ordered=True)) + + def _to_series(self, bf_series: series.Series) -> S: + return cast(S, bf_series.to_pandas(ordered=True)) + + +@log_adapter.class_logger +class PandasAeadSeriesAccessor(core_accessor.AeadSeriesAccessor[T, S]): def __init__(self, pandas_obj: S): super().__init__(pandas_obj) def _bf_from_series( - self, session: Optional[bigframes.session.Session] = None - ) -> bigframes.series.Series: + self, session: Optional[session.Session] = None + ) -> series.Series: if session is None: session = bf_session.get_global_session() - return cast(bigframes.series.Series, session.read_pandas(self._obj)) + return cast(series.Series, session.read_pandas(self._obj)) + + def _to_dataframe(self, bf_df: dataframe.DataFrame) -> T: + return cast(T, bf_df.to_pandas(ordered=True)) - def _to_series(self, bf_series: bigframes.series.Series) -> S: + def _to_series(self, bf_series: series.Series) -> S: return cast(S, bf_series.to_pandas(ordered=True)) diff --git a/packages/bigframes/scripts/data/sql-functions/ai.yaml b/packages/bigframes/scripts/data/sql-functions/ai.yaml new file mode 100644 index 000000000000..f3238c8178b7 --- /dev/null +++ b/packages/bigframes/scripts/data/sql-functions/ai.yaml @@ -0,0 +1 @@ +urn: extension:google:bq_scalar_functions diff --git a/packages/bigframes/scripts/generate_bigframes_bigquery.py b/packages/bigframes/scripts/generate_bigframes_bigquery.py index bb232a6cdf8c..999f17b10215 100755 --- a/packages/bigframes/scripts/generate_bigframes_bigquery.py +++ b/packages/bigframes/scripts/generate_bigframes_bigquery.py @@ -489,6 +489,11 @@ def process_yaml_file(yaml_file, templates): is_global = "global_namespace" in module_path.parts namespace = get_namespace(yaml_file) + + if not data or not isinstance(data, dict) or "scalar_functions" not in data: + # If the file is empty or has no functions, just create the namespace. + return [{"namespace": namespace}] + ops_list, functions_list = parse_scalar_functions( data, module_name, @@ -611,8 +616,9 @@ def generate_series_accessors(functions: list[dict], templates: dict): # Populate functions for func in functions: - ns = func["namespace"] or () - ns_by_tuple[ns]["functions"].append(func) + if "name" in func: + ns = func["namespace"] or () + ns_by_tuple[ns]["functions"].append(func) # Populate children properties for ns in sorted_namespaces: diff --git a/packages/bigframes/scripts/templates/bigframes_series_accessor.py.j2 b/packages/bigframes/scripts/templates/bigframes_series_accessor.py.j2 index f5ed3d045485..8ce37d67321b 100644 --- a/packages/bigframes/scripts/templates/bigframes_series_accessor.py.j2 +++ b/packages/bigframes/scripts/templates/bigframes_series_accessor.py.j2 @@ -10,30 +10,33 @@ from __future__ import annotations from typing import cast, Optional, TypeVar from bigframes.core.logging import log_adapter -import bigframes.extensions.core.series_accessor as core_accessor -import bigframes.series -import bigframes.session +from bigframes.extensions.core import series_accessor as core_accessor +from bigframes import series, dataframe, session -S = TypeVar("S", bound="bigframes.series.Series") +T = TypeVar("T", bound="dataframe.DataFrame") +S = TypeVar("S", bound="series.Series") {% for ns in namespaces %} @log_adapter.class_logger -class {{ ns.bigframes_class_name }}(core_accessor.{{ ns.class_name }}[S]): +class {{ ns.bigframes_class_name }}(core_accessor.{{ ns.class_name }}[T, S]): def __init__(self, bf_obj: S): super().__init__(bf_obj) def _bf_from_series( - self, session: Optional[bigframes.session.Session] = None - ) -> bigframes.series.Series: + self, session: Optional[session.Session] = None + ) -> series.Series: return self._obj - def _to_series(self, bf_series: bigframes.series.Series) -> S: + def _to_dataframe(self, bf_df: dataframe.DataFrame) -> T: + return cast(T, bf_df) + + def _to_series(self, bf_series: series.Series) -> S: return cast(S, bf_series) {% for child in ns.children %} @property - def {{ child.prop_name }}(self) -> {{ child.bigframes_class_name }}[S]: + def {{ child.prop_name }}(self) -> {{ child.bigframes_class_name }}[T, S]: return {{ child.bigframes_class_name }}(self._obj) {% endfor %} diff --git a/packages/bigframes/scripts/templates/core_series_accessor.py.j2 b/packages/bigframes/scripts/templates/core_series_accessor.py.j2 index 5881fe6963b9..5a64b7590398 100644 --- a/packages/bigframes/scripts/templates/core_series_accessor.py.j2 +++ b/packages/bigframes/scripts/templates/core_series_accessor.py.j2 @@ -10,45 +10,33 @@ from __future__ import annotations import abc from typing import ( Any, - cast, - Generic, Literal, Optional, TypeVar, Union, + cast, ) -from bigframes import dtypes -import bigframes.core.col -import bigframes.core.sentinels as sentinels -import bigframes.series as series -import bigframes.session +from bigframes import series, session +from bigframes.core import col, sentinels +from bigframes.extensions.core import abstract_series_accessor, series_tvf_mixins +T = TypeVar("T") S = TypeVar("S") -class AbstractBigQuerySeriesAccessor(abc.ABC, Generic[S]): - def __init__(self, obj: S): - self._obj = obj - - @abc.abstractmethod - def _bf_from_series( - self, session: Optional[bigframes.session.Session] = None - ) -> series.Series: - """Convert the accessor's object to a BigFrames Series.""" - - @abc.abstractmethod - def _to_series(self, bf_series: series.Series) -> S: - """Convert a BigFrames Series to the accessor's object type.""" - {% for ns in namespaces %} -class {{ ns.class_name }}(AbstractBigQuerySeriesAccessor[S]): +{% if ns.class_name == "AiSeriesAccessor" %} +class {{ ns.class_name }}(series_tvf_mixins.AITVFMixin[T, S]): +{% else %} +class {{ ns.class_name }}(abstract_series_accessor.AbstractBigQuerySeriesAccessor[T, S]): +{% endif %} """{{ ns.description }}""" {% for child in ns.children %} @property @abc.abstractmethod - def {{ child.prop_name }}(self) -> {{ child.class_name }}[S]: + def {{ child.prop_name }}(self) -> {{ child.class_name }}[T, S]: """Accessor for BigQuery {{ child.prop_name }} functions.""" {% endfor %} @@ -56,10 +44,10 @@ class {{ ns.class_name }}(AbstractBigQuerySeriesAccessor[S]): def {{ func.name }}( self, {% for arg in func.args if arg.name != func.series_accessor_arg %} - {{ arg.name }}: Union[series.Series, bigframes.core.col.Expression, {{ arg.type_hint }}]{% if arg.default %} = {{ arg.default }}{% endif %}, + {{ arg.name }}: Union[series.Series, col.Expression, {{ arg.type_hint }}]{% if arg.default %} = {{ arg.default }}{% endif %}, {% endfor %} *, - session: Optional[bigframes.session.Session] = None, + session: Optional[session.Session] = None, ) -> S: """{{ func.description | indent(8) }}""" from {{ func.import_module }} import {{ func.name }} as {{ func.name }}_impl @@ -67,7 +55,7 @@ class {{ ns.class_name }}(AbstractBigQuerySeriesAccessor[S]): # Resolve session from other arguments if not passed if session is None: - import bigframes.core.googlesql as googlesql + from bigframes.core import googlesql session = googlesql._find_session( {% for arg in func.args if arg.name != func.series_accessor_arg %} {{ arg.name }}, diff --git a/packages/bigframes/scripts/templates/pandas_series_accessor.py.j2 b/packages/bigframes/scripts/templates/pandas_series_accessor.py.j2 index 76f3d4797531..150546655613 100644 --- a/packages/bigframes/scripts/templates/pandas_series_accessor.py.j2 +++ b/packages/bigframes/scripts/templates/pandas_series_accessor.py.j2 @@ -12,12 +12,12 @@ from typing import cast, Optional, TypeVar import pandas import pandas.api.extensions -import bigframes.core.global_session as bf_session +from bigframes import dataframe, series, session +from bigframes.core import global_session as bf_session from bigframes.core.logging import log_adapter -import bigframes.extensions.core.series_accessor as core_accessor -import bigframes.series -import bigframes.session +from bigframes.extensions.core import series_accessor as core_accessor +T = TypeVar("T", bound="pandas.DataFrame") S = TypeVar("S", bound="pandas.Series") @@ -26,23 +26,26 @@ S = TypeVar("S", bound="pandas.Series") @pandas.api.extensions.register_series_accessor("bigquery") {% endif %} @log_adapter.class_logger -class {{ ns.pandas_class_name }}(core_accessor.{{ ns.class_name }}[S]): +class {{ ns.pandas_class_name }}(core_accessor.{{ ns.class_name }}[T, S]): def __init__(self, pandas_obj: S): super().__init__(pandas_obj) def _bf_from_series( - self, session: Optional[bigframes.session.Session] = None - ) -> bigframes.series.Series: + self, session: Optional[session.Session] = None + ) -> series.Series: if session is None: session = bf_session.get_global_session() - return cast(bigframes.series.Series, session.read_pandas(self._obj)) + return cast(series.Series, session.read_pandas(self._obj)) - def _to_series(self, bf_series: bigframes.series.Series) -> S: + def _to_dataframe(self, bf_df: dataframe.DataFrame) -> T: + return cast(T, bf_df.to_pandas(ordered=True)) + + def _to_series(self, bf_series: series.Series) -> S: return cast(S, bf_series.to_pandas(ordered=True)) {% for child in ns.children %} @property - def {{ child.prop_name }}(self) -> {{ child.pandas_class_name }}[S]: + def {{ child.prop_name }}(self) -> {{ child.pandas_class_name }}[T, S]: return {{ child.pandas_class_name }}(self._obj) {% endfor %} diff --git a/packages/bigframes/tests/unit/extensions/core/test_dataframe_accessor.py b/packages/bigframes/tests/unit/extensions/core/test_dataframe_accessor.py index 7ab4f5176980..2f3352116aff 100644 --- a/packages/bigframes/tests/unit/extensions/core/test_dataframe_accessor.py +++ b/packages/bigframes/tests/unit/extensions/core/test_dataframe_accessor.py @@ -26,16 +26,16 @@ def test_ai_forecast(monkeypatch): bf_df = mock.create_autospec(bpd.DataFrame) session.read_pandas.return_value = bf_df - def mock_ai_forecast(df, **kwargs): - assert df is bf_df - result_df = mock.create_autospec(bpd.DataFrame) - result_df.to_pandas.return_value = kwargs - return result_df + mock_forecast = mock.MagicMock() + forecast_result_df = mock.create_autospec(bpd.DataFrame) + mock_forecast.return_value = forecast_result_df + expected_result = mock.create_autospec(pd.DataFrame) + forecast_result_df.to_pandas.return_value = expected_result - monkeypatch.setattr(bigframes.bigquery.ai, "forecast", mock_ai_forecast) + monkeypatch.setattr(bigframes.bigquery.ai, "forecast", mock_forecast) df = pd.DataFrame({"date": ["2020-01-01"], "value": [1.0]}) - result = df.bigquery.ai.forecast( + actual_result = df.bigquery.ai.forecast( timestamp_col="date", data_col="value", horizon=5, @@ -43,30 +43,31 @@ def mock_ai_forecast(df, **kwargs): ) session.read_pandas.assert_called_once() - assert result == { - "timestamp_col": "date", - "data_col": "value", - "model": "TimesFM 2.0", - "id_cols": None, - "horizon": 5, - "confidence_level": 0.95, - "context_window": None, - "output_historical_time_series": False, - } + mock_forecast.assert_called_once_with( + bf_df, + timestamp_col="date", + data_col="value", + model="TimesFM 2.0", + id_cols=None, + horizon=5, + confidence_level=0.95, + context_window=None, + output_historical_time_series=False, + ) + forecast_result_df.to_pandas.assert_called_once() + assert actual_result is expected_result -def test_bigframes_ai_forecast(monkeypatch): - session = mock.create_autospec(bigframes.session.Session) - bf_df = mock.create_autospec(bpd.DataFrame) - def mock_ai_forecast(df, **kwargs): - assert df is bf_df - result_df = mock.create_autospec(bpd.DataFrame) - return result_df +def test_bigframes_ai_forecast(scalar_types_df: bpd.DataFrame, monkeypatch): + session = mock.create_autospec(bigframes.session.Session) + forecast_result = mock.create_autospec(bpd.DataFrame) + mock_forecast = mock.MagicMock() + mock_forecast.return_value = forecast_result - monkeypatch.setattr(bigframes.bigquery.ai, "forecast", mock_ai_forecast) + monkeypatch.setattr(bigframes.bigquery.ai, "forecast", mock_forecast) - result = bf_df.bigquery.ai.forecast( + actual_result = scalar_types_df.bigquery.ai.forecast( timestamp_col="date", data_col="value", horizon=5, @@ -74,21 +75,37 @@ def mock_ai_forecast(df, **kwargs): ) session.read_pandas.assert_not_called() + mock_forecast.assert_called_once() + args, kwargs = mock_forecast.call_args + assert args[0] is scalar_types_df + assert kwargs == { + "timestamp_col": "date", + "data_col": "value", + "model": "TimesFM 2.0", + "id_cols": None, + "horizon": 5, + "confidence_level": 0.95, + "context_window": None, + "output_historical_time_series": False, + } # BigFrames accessor returns the bf_df directly without calling to_pandas - assert result is not None + forecast_result.to_pandas.assert_not_called() + assert actual_result is forecast_result def test_ai_generate(monkeypatch): - def mock_generate(prompt, **kwargs): - result_series = mock.create_autospec(bpd.Series) - result_series.to_pandas.return_value = (prompt, kwargs) - return result_series + mock_generate = mock.MagicMock() + result_series = mock.create_autospec(bpd.Series) + mock_generate.return_value = result_series + expected_result = mock.create_autospec(pd.Series) + result_series.to_pandas.return_value = expected_result monkeypatch.setattr(bigframes.bigquery.ai, "generate", mock_generate) + prompt = mock.create_autospec(pd.Series) df = pd.DataFrame({"text_input": ["Is this a positive review?"]}) - result = df.bigquery.ai.generate( - df["text_input"], + actual_result = df.bigquery.ai.generate( + prompt, connection_id="conn", endpoint="endpoint", request_type="dedicated", @@ -96,29 +113,28 @@ def mock_generate(prompt, **kwargs): output_schema={"res": "STRING"}, ) - assert isinstance(result, tuple) - assert len(result) == 2 - pd.testing.assert_series_equal(result[0], df["text_input"]) - assert result[1] == { - "connection_id": "conn", - "endpoint": "endpoint", - "request_type": "dedicated", - "model_params": {"temp": 0.5}, - "output_schema": {"res": "STRING"}, - } + mock_generate.assert_called_once_with( + prompt, + connection_id="conn", + endpoint="endpoint", + request_type="dedicated", + model_params={"temp": 0.5}, + output_schema={"res": "STRING"}, + ) + result_series.to_pandas.assert_called_once() + assert actual_result is expected_result def test_bigframes_ai_generate(scalar_types_df: bpd.DataFrame, monkeypatch): bf_series = mock.create_autospec(bpd.Series) result_series = mock.create_autospec(bpd.Series) - def mock_generate(prompt, **kwargs): - assert prompt is bf_series - return result_series + mock_generate = mock.MagicMock() + mock_generate.return_value = result_series monkeypatch.setattr(bigframes.bigquery.ai, "generate", mock_generate) - result = scalar_types_df.bigquery.ai.generate( + actual_result = scalar_types_df.bigquery.ai.generate( bf_series, connection_id="conn", endpoint="endpoint", @@ -127,48 +143,60 @@ def mock_generate(prompt, **kwargs): output_schema={"res": "STRING"}, ) - assert result is result_series + mock_generate.assert_called_once() + args, kwargs = mock_generate.call_args + assert args[0] is bf_series + assert kwargs == { + "connection_id": "conn", + "endpoint": "endpoint", + "request_type": "dedicated", + "model_params": {"temp": 0.5}, + "output_schema": {"res": "STRING"}, + } + result_series.to_pandas.assert_not_called() + assert actual_result is result_series def test_ai_generate_bool(monkeypatch): - def mock_generate_bool(prompt, **kwargs): - result_series = mock.create_autospec(bpd.Series) - result_series.to_pandas.return_value = (prompt, kwargs) - return result_series + mock_generate_bool = mock.MagicMock() + result_series = mock.create_autospec(bpd.Series) + mock_generate_bool.return_value = result_series + expected_result = mock.create_autospec(pd.Series) + result_series.to_pandas.return_value = expected_result monkeypatch.setattr(bigframes.bigquery.ai, "generate_bool", mock_generate_bool) + prompt = mock.create_autospec(pd.Series) df = pd.DataFrame({"text_input": ["Is this a positive review?"]}) - result = df.bigquery.ai.generate_bool( - df["text_input"], + actual_result = df.bigquery.ai.generate_bool( + prompt, connection_id="conn", endpoint="endpoint", request_type="dedicated", model_params={"temp": 0.5}, ) - assert isinstance(result, tuple) - assert len(result) == 2 - pd.testing.assert_series_equal(result[0], df["text_input"]) - assert result[1] == { - "connection_id": "conn", - "endpoint": "endpoint", - "request_type": "dedicated", - "model_params": {"temp": 0.5}, - } + mock_generate_bool.assert_called_once_with( + prompt, + connection_id="conn", + endpoint="endpoint", + request_type="dedicated", + model_params={"temp": 0.5}, + ) + result_series.to_pandas.assert_called_once() + assert actual_result is expected_result def test_bigframes_ai_generate_bool(scalar_types_df: bpd.DataFrame, monkeypatch): bf_series = mock.create_autospec(bpd.Series) result_series = mock.create_autospec(bpd.Series) - def mock_generate_bool(prompt, **kwargs): - assert prompt is bf_series - return result_series + mock_generate_bool = mock.MagicMock() + mock_generate_bool.return_value = result_series monkeypatch.setattr(bigframes.bigquery.ai, "generate_bool", mock_generate_bool) - result = scalar_types_df.bigquery.ai.generate_bool( + actual_result = scalar_types_df.bigquery.ai.generate_bool( bf_series, connection_id="conn", endpoint="endpoint", @@ -176,48 +204,59 @@ def mock_generate_bool(prompt, **kwargs): model_params={"temp": 0.5}, ) - assert result is result_series + mock_generate_bool.assert_called_once() + args, kwargs = mock_generate_bool.call_args + assert args[0] is bf_series + assert kwargs == { + "connection_id": "conn", + "endpoint": "endpoint", + "request_type": "dedicated", + "model_params": {"temp": 0.5}, + } + result_series.to_pandas.assert_not_called() + assert actual_result is result_series def test_ai_generate_int(monkeypatch): - def mock_generate_int(prompt, **kwargs): - result_series = mock.create_autospec(bpd.Series) - result_series.to_pandas.return_value = (prompt, kwargs) - return result_series + mock_generate_int = mock.MagicMock() + result_series = mock.create_autospec(bpd.Series) + mock_generate_int.return_value = result_series + expected_result = mock.create_autospec(pd.Series) + result_series.to_pandas.return_value = expected_result monkeypatch.setattr(bigframes.bigquery.ai, "generate_int", mock_generate_int) + prompt = mock.create_autospec(pd.Series) df = pd.DataFrame({"text_input": ["How many legs?"]}) - result = df.bigquery.ai.generate_int( - df["text_input"], + actual_result = df.bigquery.ai.generate_int( + prompt, connection_id="conn", endpoint="endpoint", request_type="dedicated", model_params={"temp": 0.5}, ) - assert isinstance(result, tuple) - assert len(result) == 2 - pd.testing.assert_series_equal(result[0], df["text_input"]) - assert result[1] == { - "connection_id": "conn", - "endpoint": "endpoint", - "request_type": "dedicated", - "model_params": {"temp": 0.5}, - } + mock_generate_int.assert_called_once_with( + prompt, + connection_id="conn", + endpoint="endpoint", + request_type="dedicated", + model_params={"temp": 0.5}, + ) + result_series.to_pandas.assert_called_once() + assert actual_result is expected_result def test_bigframes_ai_generate_int(scalar_types_df: bpd.DataFrame, monkeypatch): bf_series = mock.create_autospec(bpd.Series) result_series = mock.create_autospec(bpd.Series) - def mock_generate_int(prompt, **kwargs): - assert prompt is bf_series - return result_series + mock_generate_int = mock.MagicMock() + mock_generate_int.return_value = result_series monkeypatch.setattr(bigframes.bigquery.ai, "generate_int", mock_generate_int) - result = scalar_types_df.bigquery.ai.generate_int( + actual_result = scalar_types_df.bigquery.ai.generate_int( bf_series, connection_id="conn", endpoint="endpoint", @@ -225,48 +264,59 @@ def mock_generate_int(prompt, **kwargs): model_params={"temp": 0.5}, ) - assert result is result_series + mock_generate_int.assert_called_once() + args, kwargs = mock_generate_int.call_args + assert args[0] is bf_series + assert kwargs == { + "connection_id": "conn", + "endpoint": "endpoint", + "request_type": "dedicated", + "model_params": {"temp": 0.5}, + } + result_series.to_pandas.assert_not_called() + assert actual_result is result_series def test_ai_generate_double(monkeypatch): - def mock_generate_double(prompt, **kwargs): - result_series = mock.create_autospec(bpd.Series) - result_series.to_pandas.return_value = (prompt, kwargs) - return result_series + mock_generate_double = mock.MagicMock() + result_series = mock.create_autospec(bpd.Series) + mock_generate_double.return_value = result_series + expected_result = mock.create_autospec(pd.Series) + result_series.to_pandas.return_value = expected_result monkeypatch.setattr(bigframes.bigquery.ai, "generate_double", mock_generate_double) + prompt = mock.create_autospec(pd.Series) df = pd.DataFrame({"text_input": ["How tall?"]}) - result = df.bigquery.ai.generate_double( - df["text_input"], + actual_result = df.bigquery.ai.generate_double( + prompt, connection_id="conn", endpoint="endpoint", request_type="dedicated", model_params={"temp": 0.5}, ) - assert isinstance(result, tuple) - assert len(result) == 2 - pd.testing.assert_series_equal(result[0], df["text_input"]) - assert result[1] == { - "connection_id": "conn", - "endpoint": "endpoint", - "request_type": "dedicated", - "model_params": {"temp": 0.5}, - } + mock_generate_double.assert_called_once_with( + prompt, + connection_id="conn", + endpoint="endpoint", + request_type="dedicated", + model_params={"temp": 0.5}, + ) + result_series.to_pandas.assert_called_once() + assert actual_result is expected_result def test_bigframes_ai_generate_double(scalar_types_df: bpd.DataFrame, monkeypatch): bf_series = mock.create_autospec(bpd.Series) result_series = mock.create_autospec(bpd.Series) - def mock_generate_double(prompt, **kwargs): - assert prompt is bf_series - return result_series + mock_generate_double = mock.MagicMock() + mock_generate_double.return_value = result_series monkeypatch.setattr(bigframes.bigquery.ai, "generate_double", mock_generate_double) - result = scalar_types_df.bigquery.ai.generate_double( + actual_result = scalar_types_df.bigquery.ai.generate_double( bf_series, connection_id="conn", endpoint="endpoint", @@ -274,4 +324,14 @@ def mock_generate_double(prompt, **kwargs): model_params={"temp": 0.5}, ) - assert result is result_series + mock_generate_double.assert_called_once() + args, kwargs = mock_generate_double.call_args + assert args[0] is bf_series + assert kwargs == { + "connection_id": "conn", + "endpoint": "endpoint", + "request_type": "dedicated", + "model_params": {"temp": 0.5}, + } + result_series.to_pandas.assert_not_called() + assert actual_result is result_series diff --git a/packages/bigframes/tests/unit/extensions/core/test_series_tvf_mixins.py b/packages/bigframes/tests/unit/extensions/core/test_series_tvf_mixins.py new file mode 100644 index 000000000000..9d5a24d2db93 --- /dev/null +++ b/packages/bigframes/tests/unit/extensions/core/test_series_tvf_mixins.py @@ -0,0 +1,248 @@ +# Copyright 2026 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 unittest.mock as mock + +import pandas as pd + +import bigframes.bigquery.ai +import bigframes.pandas as bpd +import bigframes.session + + +def test_ai_generate_embedding(monkeypatch): + session = mock.create_autospec(bigframes.session.Session) + bf_series = mock.create_autospec(bpd.Series) + session.read_pandas.return_value = bf_series + + mock_generate_embedding = mock.MagicMock() + result_df = mock.create_autospec(bpd.DataFrame) + mock_generate_embedding.return_value = result_df + expected_result = mock.create_autospec(pd.DataFrame) + result_df.to_pandas.return_value = expected_result + + monkeypatch.setattr( + bigframes.bigquery.ai, "generate_embedding", mock_generate_embedding + ) + + series = pd.Series(["apple"], name="content") + actual_result = series.bigquery.ai.generate_embedding( # type: ignore + model="my_model", + output_dimensionality=256, + task_type="retrieval_document", + start_second=1.0, + end_second=2.0, + interval_seconds=3.0, + trial_id=4, + session=session, + ) + + session.read_pandas.assert_called_once() + mock_generate_embedding.assert_called_once_with( + "my_model", + bf_series, + output_dimensionality=256, + task_type="retrieval_document", + start_second=1.0, + end_second=2.0, + interval_seconds=3.0, + trial_id=4, + ) + result_df.to_pandas.assert_called_once() + assert actual_result is expected_result + + +def test_bigframes_ai_generate_embedding(scalar_types_df: bpd.DataFrame, monkeypatch): + session = mock.create_autospec(bigframes.session.Session) + result_df = mock.create_autospec(bpd.DataFrame) + + mock_generate_embedding = mock.MagicMock() + mock_generate_embedding.return_value = result_df + + monkeypatch.setattr( + bigframes.bigquery.ai, "generate_embedding", mock_generate_embedding + ) + + scalar_types_series = scalar_types_df["string_col"] + actual_result = scalar_types_series.bigquery.ai.generate_embedding( + model="my_model", + output_dimensionality=256, + session=session, + ) + + session.read_pandas.assert_not_called() + mock_generate_embedding.assert_called_once() + args, kwargs = mock_generate_embedding.call_args + assert args[0] == "my_model" + assert args[1] is scalar_types_series + assert kwargs == { + "output_dimensionality": 256, + "task_type": None, + "start_second": None, + "end_second": None, + "interval_seconds": None, + "trial_id": None, + } + result_df.to_pandas.assert_not_called() + assert actual_result is result_df + + +def test_ai_generate_text(monkeypatch): + session = mock.create_autospec(bigframes.session.Session) + bf_series = mock.create_autospec(bpd.Series) + session.read_pandas.return_value = bf_series + + mock_generate_text = mock.MagicMock() + result_df = mock.create_autospec(bpd.DataFrame) + mock_generate_text.return_value = result_df + expected_result = mock.create_autospec(pd.DataFrame) + result_df.to_pandas.return_value = expected_result + + monkeypatch.setattr(bigframes.bigquery.ai, "generate_text", mock_generate_text) + + series = pd.Series(["write a poem"], name="prompt") + actual_result = series.bigquery.ai.generate_text( # type: ignore + model="my_model", + temperature=0.7, + max_output_tokens=100, + top_k=50, + top_p=0.9, + stop_sequences=["\n"], + ground_with_google_search=True, + request_type="dedicated", + session=session, + ) + + session.read_pandas.assert_called_once() + mock_generate_text.assert_called_once_with( + "my_model", + bf_series, + temperature=0.7, + max_output_tokens=100, + top_k=50, + top_p=0.9, + stop_sequences=["\n"], + ground_with_google_search=True, + request_type="dedicated", + ) + result_df.to_pandas.assert_called_once() + assert actual_result is expected_result + + +def test_bigframes_ai_generate_text(scalar_types_df: bpd.DataFrame, monkeypatch): + session = mock.create_autospec(bigframes.session.Session) + result_df = mock.create_autospec(bpd.DataFrame) + + mock_generate_text = mock.MagicMock() + mock_generate_text.return_value = result_df + + monkeypatch.setattr(bigframes.bigquery.ai, "generate_text", mock_generate_text) + + scalar_types_series = scalar_types_df["string_col"] + actual_result = scalar_types_series.bigquery.ai.generate_text( + model="my_model", + temperature=0.7, + session=session, + ) + + session.read_pandas.assert_not_called() + mock_generate_text.assert_called_once() + args, kwargs = mock_generate_text.call_args + assert args[0] == "my_model" + assert args[1] is scalar_types_series + assert kwargs == { + "temperature": 0.7, + "max_output_tokens": None, + "top_k": None, + "top_p": None, + "stop_sequences": None, + "ground_with_google_search": None, + "request_type": None, + } + result_df.to_pandas.assert_not_called() + assert actual_result is result_df + + +def test_ai_generate_table(monkeypatch): + session = mock.create_autospec(bigframes.session.Session) + bf_series = mock.create_autospec(bpd.Series) + session.read_pandas.return_value = bf_series + + mock_generate_table = mock.MagicMock() + result_df = mock.create_autospec(bpd.DataFrame) + mock_generate_table.return_value = result_df + expected_result = mock.create_autospec(pd.DataFrame) + result_df.to_pandas.return_value = expected_result + + monkeypatch.setattr(bigframes.bigquery.ai, "generate_table", mock_generate_table) + + series = pd.Series(["generate something"], name="prompt") + actual_result = series.bigquery.ai.generate_table( # type: ignore + model="my_model", + output_schema="category STRING", + temperature=0.7, + top_p=0.9, + max_output_tokens=100, + stop_sequences=["\n"], + request_type="dedicated", + session=session, + ) + + session.read_pandas.assert_called_once() + mock_generate_table.assert_called_once_with( + "my_model", + bf_series, + output_schema="category STRING", + temperature=0.7, + top_p=0.9, + max_output_tokens=100, + stop_sequences=["\n"], + request_type="dedicated", + ) + result_df.to_pandas.assert_called_once() + assert actual_result is expected_result + + +def test_bigframes_ai_generate_table(scalar_types_df: bpd.DataFrame, monkeypatch): + session = mock.create_autospec(bigframes.session.Session) + result_df = mock.create_autospec(bpd.DataFrame) + + mock_generate_table = mock.MagicMock() + mock_generate_table.return_value = result_df + + monkeypatch.setattr(bigframes.bigquery.ai, "generate_table", mock_generate_table) + + scalar_types_series = scalar_types_df["string_col"] + actual_result = scalar_types_series.bigquery.ai.generate_table( + model="my_model", + output_schema="category STRING", + temperature=0.7, + session=session, + ) + + session.read_pandas.assert_not_called() + mock_generate_table.assert_called_once() + args, kwargs = mock_generate_table.call_args + assert args[0] == "my_model" + assert args[1] is scalar_types_series + assert kwargs == { + "output_schema": "category STRING", + "temperature": 0.7, + "top_p": None, + "max_output_tokens": None, + "stop_sequences": None, + "request_type": None, + } + result_df.to_pandas.assert_not_called() + assert actual_result is result_df From 234c7c5e593aa78215dece5cc8699aa4c66a8543 Mon Sep 17 00:00:00 2001 From: Min Zhu Date: Tue, 23 Jun 2026 16:12:16 -0400 Subject: [PATCH 118/174] chore: update librarian to v0.21.0 (#17488) Weekly update to librarian version and re-generate. This update includes a generator upgrade, see https://github.com/googleapis/librarian/releases/tag/v0.21.0. **Manually changes** applied changes to postprocess config files due to generation failure after upgrade. [46dfa75](https://github.com/googleapis/google-cloud-python/pull/17488/commits/46dfa753c76ae082131a3527107c0c70d68819eb) commands run: ``` go run github.com/googleapis/librarian/cmd/librarian@latest update version V=$(go run github.com/googleapis/librarian/cmd/librarian@latest config get version) go run github.com/googleapis/librarian/cmd/librarian@${V} tidy # Build a new Docker image go run github.com/googleapis/librarian/tool/cmd/builddockerimages@latest --language python --version=${V} # Regenerate all libraries in Docker. Around 2 minutes. docker run -u $(id -u):$(id -g) -v .:/repo -v ~/.cache:/.cache -w /repo docker.io/library/librarian-python:${V} generate -v --all ``` For the sake of easier review, separated 3 commits: - librarian version update [f60299a](https://github.com/googleapis/google-cloud-python/pull/17488/commits/f60299a3ffecf07c75980e1f72f123e3399b63fe) - Manual changes to config to make fix generation error: [46dfa75](https://github.com/googleapis/google-cloud-python/pull/17488/commits/46dfa753c76ae082131a3527107c0c70d68819eb) - Generated code changes: [b8f2240](https://github.com/googleapis/google-cloud-python/pull/17488/commits/b8f224089ee57e3eb43bbad1561cb744e403f23f) Fixes https://github.com/googleapis/librarian/issues/6450 --------- Co-authored-by: Anthonios Partheniou --- .github/workflows/unittest.yml | 1 + .../add-dependency-google-cloud-common.yaml | 4 +- ...-dependencies-to-setup-py-constraints.yaml | 26 ++++++------- .../asset-integration.yaml | 12 +++--- ...containeranalysis-grafeas-integration.yaml | 4 +- .../integrate-isolated-handwritten-code.yaml | 16 ++++---- .../logging-integration.yaml | 8 ++-- .../pubsub-integration.yaml | 4 +- .../storage-integration.yaml | 8 ++-- librarian.yaml | 7 +++- .../google/ads/admanager_v1/__init__.py | 8 ++-- packages/google-ads-admanager/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/ads/datamanager_v1/__init__.py | 8 ++-- packages/google-ads-datamanager/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../ai/generativelanguage_v1/__init__.py | 8 ++-- .../ai/generativelanguage_v1alpha/__init__.py | 8 ++-- .../ai/generativelanguage_v1beta/__init__.py | 8 ++-- .../ai/generativelanguage_v1beta2/__init__.py | 8 ++-- .../ai/generativelanguage_v1beta3/__init__.py | 8 ++-- .../google-ai-generativelanguage/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../analytics/admin_v1alpha/__init__.py | 8 ++-- .../google/analytics/admin_v1beta/__init__.py | 8 ++-- packages/google-analytics-admin/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/analytics/data_v1alpha/__init__.py | 8 ++-- .../google/analytics/data_v1beta/__init__.py | 8 ++-- packages/google-analytics-data/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/apps/card_v1/__init__.py | 8 ++-- packages/google-apps-card/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/apps/chat_v1/__init__.py | 8 ++-- packages/google-apps-chat/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../apps/events_subscriptions_v1/__init__.py | 8 ++-- .../events_subscriptions_v1beta/__init__.py | 8 ++-- .../google-apps-events-subscriptions/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/apps/meet_v2/__init__.py | 8 ++-- .../google/apps/meet_v2beta/__init__.py | 8 ++-- packages/google-apps-meet/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/apps/script/type/__init__.py | 8 ++-- .../apps/script/type/calendar/__init__.py | 8 ++-- .../google/apps/script/type/docs/__init__.py | 8 ++-- .../google/apps/script/type/drive/__init__.py | 8 ++-- .../google/apps/script/type/gmail/__init__.py | 8 ++-- .../apps/script/type/sheets/__init__.py | 8 ++-- .../apps/script/type/slides/__init__.py | 8 ++-- packages/google-apps-script-type/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../area120/tables_v1alpha1/__init__.py | 8 ++-- packages/google-area120-tables/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/backstory/__init__.py | 8 ++-- packages/google-backstory/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/accessapproval_v1/__init__.py | 8 ++-- .../google-cloud-access-approval/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../advisorynotifications_v1/__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../agentidentitycredentials_v1/__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/alloydb/connectors_v1/__init__.py | 8 ++-- .../alloydb/connectors_v1alpha/__init__.py | 8 ++-- .../alloydb/connectors_v1beta/__init__.py | 8 ++-- .../google-cloud-alloydb-connectors/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/alloydb_v1/__init__.py | 8 ++-- .../google/cloud/alloydb_v1alpha/__init__.py | 8 ++-- .../google/cloud/alloydb_v1beta/__init__.py | 8 ++-- packages/google-cloud-alloydb/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/apigateway_v1/__init__.py | 8 ++-- packages/google-cloud-api-gateway/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/api_keys_v2/__init__.py | 8 ++-- packages/google-cloud-api-keys/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/apigeeconnect_v1/__init__.py | 8 ++-- packages/google-cloud-apigee-connect/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/apigee_registry_v1/__init__.py | 8 ++-- .../google-cloud-apigee-registry/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/apihub_v1/__init__.py | 8 ++-- packages/google-cloud-apihub/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/apiregistry_v1beta/__init__.py | 8 ++-- packages/google-cloud-apiregistry/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/appengine_admin_v1/__init__.py | 8 ++-- .../google-cloud-appengine-admin/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/appengine_logging_v1/__init__.py | 8 ++-- .../google-cloud-appengine-logging/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/apphub_v1/__init__.py | 8 ++-- packages/google-cloud-apphub/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/appoptimize_v1beta/__init__.py | 8 ++-- packages/google-cloud-appoptimize/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/artifactregistry_v1/__init__.py | 8 ++-- .../artifactregistry_v1beta2/__init__.py | 8 ++-- .../google-cloud-artifact-registry/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/asset_v1/__init__.py | 8 ++-- .../google/cloud/asset_v1p1beta1/__init__.py | 8 ++-- .../google/cloud/asset_v1p2beta1/__init__.py | 8 ++-- .../google/cloud/asset_v1p5beta1/__init__.py | 8 ++-- packages/google-cloud-asset/setup.py | 20 +++++----- .../testing/constraints-3.10.txt | 14 +++---- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/assuredworkloads_v1/__init__.py | 8 ++-- .../assuredworkloads_v1beta1/__init__.py | 8 ++-- .../google-cloud-assured-workloads/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/auditmanager_v1/__init__.py | 8 ++-- packages/google-cloud-auditmanager/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/automl_v1/__init__.py | 8 ++-- .../google/cloud/automl_v1beta1/__init__.py | 8 ++-- packages/google-cloud-automl/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/backupdr_v1/__init__.py | 8 ++-- packages/google-cloud-backupdr/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/bare_metal_solution_v2/__init__.py | 8 ++-- .../google-cloud-bare-metal-solution/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/batch_v1/__init__.py | 8 ++-- .../google/cloud/batch_v1alpha/__init__.py | 8 ++-- packages/google-cloud-batch/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../beyondcorp_appconnections_v1/__init__.py | 8 ++-- .../setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../beyondcorp_appconnectors_v1/__init__.py | 8 ++-- .../setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../beyondcorp_appgateways_v1/__init__.py | 8 ++-- .../setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../__init__.py | 8 ++-- .../setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../beyondcorp_clientgateways_v1/__init__.py | 8 ++-- .../setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/biglake_hive_v1beta/__init__.py | 8 ++-- packages/google-cloud-biglake-hive/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/biglake_v1/__init__.py | 8 ++-- packages/google-cloud-biglake/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../bigquery_analyticshub_v1/__init__.py | 8 ++-- .../setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/bigquery_biglake_v1/__init__.py | 8 ++-- .../bigquery_biglake_v1alpha1/__init__.py | 8 ++-- .../google-cloud-bigquery-biglake/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/bigquery_connection_v1/__init__.py | 8 ++-- .../google-cloud-bigquery-connection/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../__init__.py | 8 ++-- .../setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../bigquery_datapolicies_v1/__init__.py | 8 ++-- .../bigquery_datapolicies_v1beta1/__init__.py | 8 ++-- .../bigquery_datapolicies_v2/__init__.py | 8 ++-- .../bigquery_datapolicies_v2beta1/__init__.py | 8 ++-- .../setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../bigquery_datatransfer_v1/__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/bigquery_logging_v1/__init__.py | 8 ++-- .../google-cloud-bigquery-logging/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/bigquery_migration_v2/__init__.py | 8 ++-- .../bigquery_migration_v2alpha/__init__.py | 8 ++-- .../google-cloud-bigquery-migration/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/bigquery_reservation_v1/__init__.py | 8 ++-- .../setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/bigquery_storage_v1/__init__.py | 8 ++-- .../bigquery_storage_v1alpha/__init__.py | 8 ++-- .../cloud/bigquery_storage_v1beta/__init__.py | 8 ++-- .../bigquery_storage_v1beta2/__init__.py | 8 ++-- .../google-cloud-bigquery-storage/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/billing/budgets_v1/__init__.py | 8 ++-- .../cloud/billing/budgets_v1beta1/__init__.py | 8 ++-- .../google-cloud-billing-budgets/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/billing_v1/__init__.py | 8 ++-- packages/google-cloud-billing/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/binaryauthorization_v1/__init__.py | 8 ++-- .../binaryauthorization_v1beta1/__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/devtools/cloudbuild_v1/__init__.py | 8 ++-- .../cloud/devtools/cloudbuild_v2/__init__.py | 8 ++-- packages/google-cloud-build/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/capacityplanner_v1beta/__init__.py | 8 ++-- .../google-cloud-capacityplanner/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/certificate_manager_v1/__init__.py | 8 ++-- .../google-cloud-certificate-manager/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/ces_v1/__init__.py | 8 ++-- .../google/cloud/ces_v1beta/__init__.py | 8 ++-- packages/google-cloud-ces/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/channel_v1/__init__.py | 8 ++-- packages/google-cloud-channel/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/chronicle_v1/__init__.py | 8 ++-- packages/google-cloud-chronicle/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/cloudcontrolspartner_v1/__init__.py | 8 ++-- .../cloudcontrolspartner_v1beta/__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloudsecuritycompliance_v1/__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../__init__.py | 8 ++-- .../__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/common/__init__.py | 8 ++-- packages/google-cloud-common/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/compute_v1beta/__init__.py | 8 ++-- packages/google-cloud-compute-v1beta/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../confidentialcomputing_v1/__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/config_v1/__init__.py | 8 ++-- packages/google-cloud-config/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/configdelivery_v1/__init__.py | 8 ++-- .../cloud/configdelivery_v1alpha/__init__.py | 8 ++-- .../cloud/configdelivery_v1beta/__init__.py | 8 ++-- packages/google-cloud-configdelivery/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../contact_center_insights_v1/__init__.py | 8 ++-- .../setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/container_v1/__init__.py | 8 ++-- .../cloud/container_v1beta1/__init__.py | 8 ++-- packages/google-cloud-container/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../devtools/containeranalysis_v1/__init__.py | 8 ++-- .../google-cloud-containeranalysis/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/contentwarehouse_v1/__init__.py | 8 ++-- .../google-cloud-contentwarehouse/setup.py | 16 ++++---- .../testing/constraints-3.10.txt | 10 ++--- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/data_fusion_v1/__init__.py | 8 ++-- packages/google-cloud-data-fusion/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/dataqna_v1alpha/__init__.py | 8 ++-- packages/google-cloud-data-qna/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/databasecenter_v1beta/__init__.py | 8 ++-- packages/google-cloud-databasecenter/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/datacatalog_lineage_v1/__init__.py | 8 ++-- .../google-cloud-datacatalog-lineage/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/datacatalog_v1/__init__.py | 8 ++-- .../cloud/datacatalog_v1beta1/__init__.py | 8 ++-- packages/google-cloud-datacatalog/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/dataflow_v1beta3/__init__.py | 8 ++-- .../google-cloud-dataflow-client/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/dataform_v1/__init__.py | 8 ++-- .../google/cloud/dataform_v1beta1/__init__.py | 8 ++-- packages/google-cloud-dataform/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/datalabeling_v1beta1/__init__.py | 8 ++-- packages/google-cloud-datalabeling/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/dataplex_v1/__init__.py | 8 ++-- packages/google-cloud-dataplex/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/metastore_v1/__init__.py | 8 ++-- .../cloud/metastore_v1alpha/__init__.py | 8 ++-- .../google/cloud/metastore_v1beta/__init__.py | 8 ++-- .../google-cloud-dataproc-metastore/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/dataproc_v1/__init__.py | 8 ++-- packages/google-cloud-dataproc/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/datastore_admin_v1/__init__.py | 8 ++-- .../google/cloud/datastore_v1/__init__.py | 8 ++-- packages/google-cloud-datastore/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/datastream_v1/__init__.py | 8 ++-- .../cloud/datastream_v1alpha1/__init__.py | 8 ++-- packages/google-cloud-datastream/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/deploy_v1/__init__.py | 8 ++-- packages/google-cloud-deploy/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/developerconnect_v1/__init__.py | 8 ++-- .../google-cloud-developerconnect/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/devicestreaming_v1/__init__.py | 8 ++-- .../google-cloud-devicestreaming/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/dialogflowcx_v3/__init__.py | 8 ++-- .../cloud/dialogflowcx_v3beta1/__init__.py | 8 ++-- packages/google-cloud-dialogflow-cx/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/dialogflow_v2/__init__.py | 8 ++-- .../cloud/dialogflow_v2beta1/__init__.py | 8 ++-- packages/google-cloud-dialogflow/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/discoveryengine_v1/__init__.py | 8 ++-- .../cloud/discoveryengine_v1alpha/__init__.py | 8 ++-- .../cloud/discoveryengine_v1beta/__init__.py | 8 ++-- .../google-cloud-discoveryengine/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/dlp_v2/__init__.py | 8 ++-- packages/google-cloud-dlp/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/clouddms_v1/__init__.py | 8 ++-- packages/google-cloud-dms/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/documentai_v1/__init__.py | 8 ++-- .../cloud/documentai_v1beta3/__init__.py | 8 ++-- packages/google-cloud-documentai/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/domains_v1/__init__.py | 8 ++-- .../google/cloud/domains_v1beta1/__init__.py | 8 ++-- packages/google-cloud-domains/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/edgecontainer_v1/__init__.py | 8 ++-- packages/google-cloud-edgecontainer/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/edgenetwork_v1/__init__.py | 8 ++-- packages/google-cloud-edgenetwork/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../enterpriseknowledgegraph_v1/__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/errorreporting_v1beta1/__init__.py | 8 ++-- .../google-cloud-error-reporting/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/essential_contacts_v1/__init__.py | 8 ++-- .../google-cloud-essential-contacts/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/eventarc_publishing_v1/__init__.py | 8 ++-- .../google-cloud-eventarc-publishing/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/eventarc_v1/__init__.py | 8 ++-- packages/google-cloud-eventarc/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/filestore_v1/__init__.py | 8 ++-- packages/google-cloud-filestore/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/financialservices_v1/__init__.py | 8 ++-- .../google-cloud-financialservices/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/functions_v1/__init__.py | 8 ++-- .../google/cloud/functions_v2/__init__.py | 8 ++-- packages/google-cloud-functions/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../gdchardwaremanagement_v1alpha/__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/geminidataanalytics_v1/__init__.py | 8 ++-- .../geminidataanalytics_v1alpha/__init__.py | 8 ++-- .../geminidataanalytics_v1beta/__init__.py | 8 ++-- .../google-cloud-geminidataanalytics/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/gke_backup_v1/__init__.py | 8 ++-- packages/google-cloud-gke-backup/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/gkeconnect/gateway_v1/__init__.py | 8 ++-- .../gkeconnect/gateway_v1beta1/__init__.py | 8 ++-- .../google-cloud-gke-connect-gateway/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/gkehub_v1/__init__.py | 8 ++-- .../google/cloud/gkehub_v1beta1/__init__.py | 8 ++-- packages/google-cloud-gke-hub/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/gke_multicloud_v1/__init__.py | 8 ++-- packages/google-cloud-gke-multicloud/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/gkerecommender_v1/__init__.py | 8 ++-- packages/google-cloud-gkerecommender/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/gsuiteaddons_v1/__init__.py | 8 ++-- packages/google-cloud-gsuiteaddons/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/hypercomputecluster_v1/__init__.py | 8 ++-- .../hypercomputecluster_v1beta/__init__.py | 8 ++-- .../google-cloud-hypercomputecluster/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/iam_logging_v1/__init__.py | 8 ++-- packages/google-cloud-iam-logging/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/iam_admin_v1/__init__.py | 8 ++-- .../cloud/iam_credentials_v1/__init__.py | 8 ++-- .../google/cloud/iam_v2/__init__.py | 8 ++-- .../google/cloud/iam_v2beta/__init__.py | 8 ++-- .../google/cloud/iam_v3/__init__.py | 8 ++-- .../google/cloud/iam_v3beta/__init__.py | 8 ++-- packages/google-cloud-iam/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/iap_v1/__init__.py | 8 ++-- packages/google-cloud-iap/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/ids_v1/__init__.py | 8 ++-- packages/google-cloud-ids/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/kms_inventory_v1/__init__.py | 8 ++-- packages/google-cloud-kms-inventory/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/kms_v1/__init__.py | 8 ++-- packages/google-cloud-kms/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/language_v1/__init__.py | 8 ++-- .../google/cloud/language_v1beta2/__init__.py | 8 ++-- .../google/cloud/language_v2/__init__.py | 8 ++-- packages/google-cloud-language/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/licensemanager_v1/__init__.py | 8 ++-- packages/google-cloud-licensemanager/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/lifesciences_v2beta/__init__.py | 8 ++-- packages/google-cloud-life-sciences/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/locationfinder_v1/__init__.py | 8 ++-- packages/google-cloud-locationfinder/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- packages/google-cloud-logging/setup.py | 16 ++++---- .../testing/constraints-3.10.txt | 10 ++--- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/lustre_v1/__init__.py | 8 ++-- packages/google-cloud-lustre/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/maintenance_api_v1/__init__.py | 8 ++-- .../cloud/maintenance_api_v1beta/__init__.py | 8 ++-- .../google-cloud-maintenance-api/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/managedidentities_v1/__init__.py | 8 ++-- .../google-cloud-managed-identities/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/managedkafka_v1/__init__.py | 8 ++-- packages/google-cloud-managedkafka/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../mediatranslation_v1beta1/__init__.py | 8 ++-- .../google-cloud-media-translation/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/memcache_v1/__init__.py | 8 ++-- .../google/cloud/memcache_v1beta2/__init__.py | 8 ++-- packages/google-cloud-memcache/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/memorystore_v1/__init__.py | 8 ++-- .../cloud/memorystore_v1beta/__init__.py | 8 ++-- packages/google-cloud-memorystore/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/migrationcenter_v1/__init__.py | 8 ++-- .../google-cloud-migrationcenter/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/modelarmor_v1/__init__.py | 8 ++-- .../cloud/modelarmor_v1beta/__init__.py | 8 ++-- packages/google-cloud-modelarmor/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/monitoring_dashboard_v1/__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../monitoring_metrics_scope_v1/__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/monitoring_v3/__init__.py | 8 ++-- packages/google-cloud-monitoring/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/netapp_v1/__init__.py | 8 ++-- packages/google-cloud-netapp/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/networkconnectivity_v1/__init__.py | 8 ++-- .../networkconnectivity_v1alpha1/__init__.py | 8 ++-- .../networkconnectivity_v1beta/__init__.py | 8 ++-- .../setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/network_management_v1/__init__.py | 8 ++-- .../google-cloud-network-management/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/network_security_v1/__init__.py | 8 ++-- .../network_security_v1alpha1/__init__.py | 8 ++-- .../network_security_v1beta1/__init__.py | 8 ++-- .../google-cloud-network-security/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/network_services_v1/__init__.py | 8 ++-- .../google-cloud-network-services/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/notebooks_v1/__init__.py | 8 ++-- .../cloud/notebooks_v1beta1/__init__.py | 8 ++-- .../google/cloud/notebooks_v2/__init__.py | 8 ++-- packages/google-cloud-notebooks/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/optimization_v1/__init__.py | 8 ++-- packages/google-cloud-optimization/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/oracledatabase_v1/__init__.py | 8 ++-- packages/google-cloud-oracledatabase/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../airflow/service_v1/__init__.py | 8 ++-- .../airflow/service_v1beta1/__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/orgpolicy_v2/__init__.py | 8 ++-- packages/google-cloud-org-policy/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/osconfig_v1/__init__.py | 8 ++-- .../google/cloud/osconfig_v1alpha/__init__.py | 8 ++-- packages/google-cloud-os-config/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/oslogin_v1/__init__.py | 8 ++-- packages/google-cloud-os-login/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/parallelstore_v1/__init__.py | 8 ++-- .../cloud/parallelstore_v1beta/__init__.py | 8 ++-- packages/google-cloud-parallelstore/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/parametermanager_v1/__init__.py | 8 ++-- .../google-cloud-parametermanager/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../phishingprotection_v1beta1/__init__.py | 8 ++-- .../google-cloud-phishing-protection/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/policytroubleshooter_v1/__init__.py | 8 ++-- .../setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/policysimulator_v1/__init__.py | 8 ++-- .../google-cloud-policysimulator/setup.py | 16 ++++---- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../policytroubleshooter_iam_v3/__init__.py | 8 ++-- .../setup.py | 16 ++++---- .../testing/constraints-3.10.txt | 10 ++--- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/security/privateca_v1/__init__.py | 8 ++-- .../security/privateca_v1beta1/__init__.py | 8 ++-- packages/google-cloud-private-ca/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/privatecatalog_v1beta1/__init__.py | 8 ++-- .../google-cloud-private-catalog/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../privilegedaccessmanager_v1/__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/pubsub_v1/__init__.py | 8 ++-- packages/google-cloud-pubsub/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/cloudquotas_v1/__init__.py | 8 ++-- .../cloud/cloudquotas_v1beta/__init__.py | 8 ++-- packages/google-cloud-quotas/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../rapidmigrationassessment_v1/__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/recaptchaenterprise_v1/__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../recommendationengine_v1beta1/__init__.py | 8 ++-- .../google-cloud-recommendations-ai/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/recommender_v1/__init__.py | 8 ++-- .../cloud/recommender_v1beta1/__init__.py | 8 ++-- packages/google-cloud-recommender/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/redis_cluster_v1/__init__.py | 8 ++-- .../cloud/redis_cluster_v1beta1/__init__.py | 8 ++-- packages/google-cloud-redis-cluster/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/redis_v1/__init__.py | 8 ++-- .../google/cloud/redis_v1beta1/__init__.py | 8 ++-- packages/google-cloud-redis/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/resourcemanager_v3/__init__.py | 8 ++-- .../google-cloud-resource-manager/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/retail_v2/__init__.py | 8 ++-- .../google/cloud/retail_v2alpha/__init__.py | 8 ++-- .../google/cloud/retail_v2beta/__init__.py | 8 ++-- packages/google-cloud-retail/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/run_v2/__init__.py | 8 ++-- packages/google-cloud-run/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/scheduler_v1/__init__.py | 8 ++-- .../cloud/scheduler_v1beta1/__init__.py | 8 ++-- packages/google-cloud-scheduler/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/secretmanager_v1/__init__.py | 8 ++-- .../cloud/secretmanager_v1beta1/__init__.py | 8 ++-- .../cloud/secretmanager_v1beta2/__init__.py | 8 ++-- packages/google-cloud-secret-manager/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/securesourcemanager_v1/__init__.py | 8 ++-- .../google-cloud-securesourcemanager/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/security/publicca_v1/__init__.py | 8 ++-- .../security/publicca_v1beta1/__init__.py | 8 ++-- .../google-cloud-security-publicca/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/securitycenter_v1/__init__.py | 8 ++-- .../cloud/securitycenter_v1beta1/__init__.py | 8 ++-- .../securitycenter_v1p1beta1/__init__.py | 8 ++-- .../cloud/securitycenter_v2/__init__.py | 8 ++-- packages/google-cloud-securitycenter/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../securitycentermanagement_v1/__init__.py | 8 ++-- .../setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/servicecontrol_v1/__init__.py | 8 ++-- .../cloud/servicecontrol_v2/__init__.py | 8 ++-- .../google-cloud-service-control/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/servicedirectory_v1/__init__.py | 8 ++-- .../servicedirectory_v1beta1/__init__.py | 8 ++-- .../google-cloud-service-directory/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/servicemanagement_v1/__init__.py | 8 ++-- .../google-cloud-service-management/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/service_usage_v1/__init__.py | 8 ++-- packages/google-cloud-service-usage/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/servicehealth_v1/__init__.py | 8 ++-- packages/google-cloud-servicehealth/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/shell_v1/__init__.py | 8 ++-- packages/google-cloud-shell/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/source_context_v1/__init__.py | 8 ++-- packages/google-cloud-source-context/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/speech_v1/__init__.py | 8 ++-- .../google/cloud/speech_v1p1beta1/__init__.py | 8 ++-- .../google/cloud/speech_v2/__init__.py | 8 ++-- packages/google-cloud-speech/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/storage_control_v2/__init__.py | 8 ++-- .../google-cloud-storage-control/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/storage_transfer_v1/__init__.py | 8 ++-- .../google-cloud-storage-transfer/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/_storage_v2/__init__.py | 8 ++-- packages/google-cloud-storage/setup.py | 5 ++- .../storagebatchoperations_v1/__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/storageinsights_v1/__init__.py | 8 ++-- .../google-cloud-storageinsights/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/support_v2/__init__.py | 8 ++-- .../google/cloud/support_v2beta/__init__.py | 8 ++-- packages/google-cloud-support/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/talent_v4/__init__.py | 8 ++-- .../google/cloud/talent_v4beta1/__init__.py | 8 ++-- packages/google-cloud-talent/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/tasks_v2/__init__.py | 8 ++-- .../google/cloud/tasks_v2beta2/__init__.py | 8 ++-- .../google/cloud/tasks_v2beta3/__init__.py | 8 ++-- packages/google-cloud-tasks/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/telcoautomation_v1/__init__.py | 8 ++-- .../telcoautomation_v1alpha1/__init__.py | 8 ++-- .../google-cloud-telcoautomation/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/texttospeech_v1/__init__.py | 8 ++-- .../cloud/texttospeech_v1beta1/__init__.py | 8 ++-- packages/google-cloud-texttospeech/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/tpu_v1/__init__.py | 8 ++-- .../google/cloud/tpu_v2/__init__.py | 8 ++-- .../google/cloud/tpu_v2alpha1/__init__.py | 8 ++-- packages/google-cloud-tpu/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/trace_v1/__init__.py | 8 ++-- .../google/cloud/trace_v2/__init__.py | 8 ++-- packages/google-cloud-trace/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/translate_v3/__init__.py | 8 ++-- .../cloud/translate_v3beta1/__init__.py | 8 ++-- packages/google-cloud-translate/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/vectorsearch_v1/__init__.py | 8 ++-- .../cloud/vectorsearch_v1beta/__init__.py | 8 ++-- packages/google-cloud-vectorsearch/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/video/live_stream_v1/__init__.py | 8 ++-- .../google-cloud-video-live-stream/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/video/stitcher_v1/__init__.py | 8 ++-- packages/google-cloud-video-stitcher/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/video/transcoder_v1/__init__.py | 8 ++-- .../google-cloud-video-transcoder/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/videointelligence_v1/__init__.py | 8 ++-- .../videointelligence_v1beta2/__init__.py | 8 ++-- .../videointelligence_v1p1beta1/__init__.py | 8 ++-- .../videointelligence_v1p2beta1/__init__.py | 8 ++-- .../videointelligence_v1p3beta1/__init__.py | 8 ++-- .../google-cloud-videointelligence/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/vision_v1/__init__.py | 8 ++-- .../google/cloud/vision_v1p1beta1/__init__.py | 8 ++-- .../google/cloud/vision_v1p2beta1/__init__.py | 8 ++-- .../google/cloud/vision_v1p3beta1/__init__.py | 8 ++-- .../google/cloud/vision_v1p4beta1/__init__.py | 8 ++-- packages/google-cloud-vision/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/visionai_v1/__init__.py | 8 ++-- .../cloud/visionai_v1alpha1/__init__.py | 8 ++-- packages/google-cloud-visionai/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/vmmigration_v1/__init__.py | 8 ++-- packages/google-cloud-vm-migration/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/vmwareengine_v1/__init__.py | 8 ++-- packages/google-cloud-vmwareengine/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/vpcaccess_v1/__init__.py | 8 ++-- packages/google-cloud-vpc-access/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/webrisk_v1/__init__.py | 8 ++-- .../google/cloud/webrisk_v1beta1/__init__.py | 8 ++-- packages/google-cloud-webrisk/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/websecurityscanner_v1/__init__.py | 8 ++-- .../websecurityscanner_v1alpha/__init__.py | 8 ++-- .../websecurityscanner_v1beta/__init__.py | 8 ++-- .../google-cloud-websecurityscanner/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/workflows/executions_v1/__init__.py | 8 ++-- .../workflows/executions_v1beta/__init__.py | 8 ++-- .../google/cloud/workflows_v1/__init__.py | 8 ++-- .../google/cloud/workflows_v1beta/__init__.py | 8 ++-- packages/google-cloud-workflows/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../cloud/workloadmanager_v1/__init__.py | 8 ++-- .../google-cloud-workloadmanager/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/cloud/workstations_v1/__init__.py | 8 ++-- .../cloud/workstations_v1beta/__init__.py | 8 ++-- packages/google-cloud-workstations/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/developer_knowledge_v1/__init__.py | 8 ++-- packages/google-developer-knowledge/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../devicesandservices/health_v4/__init__.py | 8 ++-- .../google-devicesandservices-health/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/geo/type/__init__.py | 8 ++-- packages/google-geo-type/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../maps/addressvalidation_v1/__init__.py | 8 ++-- .../google-maps-addressvalidation/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/maps/areainsights_v1/__init__.py | 8 ++-- packages/google-maps-areainsights/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../maps/fleetengine_delivery_v1/__init__.py | 8 ++-- .../google-maps-fleetengine-delivery/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/maps/fleetengine_v1/__init__.py | 8 ++-- packages/google-maps-fleetengine/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/maps/geocode_v4/__init__.py | 8 ++-- packages/google-maps-geocode/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../maps/mapmanagement_v2beta/__init__.py | 8 ++-- packages/google-maps-mapmanagement/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../maps/mapsplatformdatasets_v1/__init__.py | 8 ++-- .../google-maps-mapsplatformdatasets/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/maps/navconnect_v1/__init__.py | 8 ++-- packages/google-maps-navconnect/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/maps/places_v1/__init__.py | 8 ++-- packages/google-maps-places/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../maps/routeoptimization_v1/__init__.py | 8 ++-- .../google-maps-routeoptimization/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/maps/routing_v2/__init__.py | 8 ++-- packages/google-maps-routing/setup.py | 14 ++++--- .../testing/constraints-3.10.txt | 8 ++-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/maps/solar_v1/__init__.py | 8 ++-- packages/google-maps-solar/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/shopping/css_v1/__init__.py | 8 ++-- packages/google-shopping-css/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../shopping/merchant_accounts_v1/__init__.py | 8 ++-- .../merchant_accounts_v1beta/__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../merchant_conversions_v1/__init__.py | 8 ++-- .../merchant_conversions_v1beta/__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../merchant_datasources_v1/__init__.py | 8 ++-- .../merchant_datasources_v1beta/__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../merchant_inventories_v1/__init__.py | 8 ++-- .../merchant_inventories_v1beta/__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../merchant_issueresolution_v1/__init__.py | 8 ++-- .../__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../shopping/merchant_lfp_v1/__init__.py | 8 ++-- .../shopping/merchant_lfp_v1beta/__init__.py | 8 ++-- .../google-shopping-merchant-lfp/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../merchant_notifications_v1/__init__.py | 8 ++-- .../merchant_notifications_v1beta/__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../merchant_ordertracking_v1/__init__.py | 8 ++-- .../merchant_ordertracking_v1beta/__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../shopping/merchant_products_v1/__init__.py | 8 ++-- .../merchant_products_v1beta/__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../merchant_promotions_v1/__init__.py | 8 ++-- .../merchant_promotions_v1beta/__init__.py | 8 ++-- .../setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../shopping/merchant_quota_v1/__init__.py | 8 ++-- .../merchant_quota_v1beta/__init__.py | 8 ++-- .../google-shopping-merchant-quota/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../shopping/merchant_reports_v1/__init__.py | 8 ++-- .../merchant_reports_v1alpha/__init__.py | 8 ++-- .../merchant_reports_v1beta/__init__.py | 8 ++-- .../google-shopping-merchant-reports/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../merchant_reviews_v1beta/__init__.py | 8 ++-- .../google-shopping-merchant-reviews/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../google/shopping/type/__init__.py | 8 ++-- packages/google-shopping-type/setup.py | 12 +++--- .../testing/constraints-3.10.txt | 6 +-- .../testing/constraints-3.13.txt | 2 +- .../testing/constraints-3.14.txt | 2 +- .../grafeas/grafeas/grafeas_v1/__init__.py | 8 ++-- packages/grafeas/setup.py | 12 +++--- packages/grafeas/testing/constraints-3.10.txt | 6 +-- packages/grafeas/testing/constraints-3.13.txt | 2 +- packages/grafeas/testing/constraints-3.14.txt | 2 +- release-please-bulk-config.json | 38 ------------------- release-please-individual-config.json | 38 +++++++++++++++++++ 1391 files changed, 4769 insertions(+), 4264 deletions(-) diff --git a/.github/workflows/unittest.yml b/.github/workflows/unittest.yml index 6cd22f7ba742..ded62f7ddf67 100644 --- a/.github/workflows/unittest.yml +++ b/.github/workflows/unittest.yml @@ -16,6 +16,7 @@ jobs: unit: runs-on: ubuntu-22.04 strategy: + fail-fast: true matrix: python: ['3.9', '3.10', "3.11", "3.12", "3.13", "3.14"] steps: diff --git a/.librarian/generator-input/client-post-processing/add-dependency-google-cloud-common.yaml b/.librarian/generator-input/client-post-processing/add-dependency-google-cloud-common.yaml index 289ca7c7712d..c01f2e3ec861 100644 --- a/.librarian/generator-input/client-post-processing/add-dependency-google-cloud-common.yaml +++ b/.librarian/generator-input/client-post-processing/add-dependency-google-cloud-common.yaml @@ -19,14 +19,14 @@ replacements: ] before: | dependencies = \[ - "google-api-core\[grpc\] >= 2.17.1, <3.0.0", + "google-api-core\[grpc\] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", after: | dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", diff --git a/.librarian/generator-input/client-post-processing/add-missing-dependencies-to-setup-py-constraints.yaml b/.librarian/generator-input/client-post-processing/add-missing-dependencies-to-setup-py-constraints.yaml index 1f8c7353df3a..5c80b764aa9b 100644 --- a/.librarian/generator-input/client-post-processing/add-missing-dependencies-to-setup-py-constraints.yaml +++ b/.librarian/generator-input/client-post-processing/add-missing-dependencies-to-setup-py-constraints.yaml @@ -19,14 +19,14 @@ replacements: ] before: | dependencies = \[ - "google-api-core\[grpc\] >= 2.17.1, <3.0.0", + "google-api-core\[grpc\] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", after: | dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", @@ -38,14 +38,14 @@ replacements: ] before: | dependencies = \[ - "google-api-core\[grpc\] >= 2.17.1, <3.0.0", + "google-api-core\[grpc\] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", after: | dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", @@ -57,14 +57,14 @@ replacements: ] before: | dependencies = \[ - "google-api-core\[grpc\] >= 2.17.1, <3.0.0", + "google-api-core\[grpc\] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", after: | dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", @@ -76,14 +76,14 @@ replacements: ] before: | dependencies = \[ - "google-api-core\[grpc\] >= 2.17.1, <3.0.0", + "google-api-core\[grpc\] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", after: | dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", @@ -95,18 +95,18 @@ replacements: ] before: | dependencies = \[ - "google-api-core\[grpc\] >= 2.17.1, <3.0.0", + "google-api-core\[grpc\] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", after: | dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", - "google-cloud-org-policy >= 1.11.1, <2.0.0", + "google-cloud-org-policy >= 1.13.1, <2.0.0", "grpcio >= 1.59.0, < 2.0.0", count: 1 - paths: [ @@ -114,14 +114,14 @@ replacements: ] before: | dependencies = \[ - "google-api-core\[grpc\] >= 2.17.1, <3.0.0", + "google-api-core\[grpc\] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", after: | dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", diff --git a/.librarian/generator-input/client-post-processing/asset-integration.yaml b/.librarian/generator-input/client-post-processing/asset-integration.yaml index 8246cb16f7a8..5a6eb97a18c4 100644 --- a/.librarian/generator-input/client-post-processing/asset-integration.yaml +++ b/.librarian/generator-input/client-post-processing/asset-integration.yaml @@ -19,18 +19,18 @@ replacements: ] before: | dependencies = \[ - "google-api-core\[grpc\] >= 2.17.1, <3.0.0", + "google-api-core\[grpc\] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", after: | dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", - "google-cloud-org-policy >= 1.11.1, <2.0.0", + "google-cloud-org-policy >= 1.13.1, <2.0.0", "grpcio >= 1.59.0, < 2.0.0", count: 1 @@ -38,10 +38,10 @@ replacements: packages/google-cloud-asset/testing/constraints-3.10.txt ] before: | - google-api-core==2.17.1 + google-api-core==2.24.2 google-auth==2.14.1 after: | - google-api-core==2.17.1 - google-cloud-org-policy==1.11.1 + google-api-core==2.24.2 + google-cloud-org-policy==1.13.1 google-auth==2.14.1 count: 1 diff --git a/.librarian/generator-input/client-post-processing/containeranalysis-grafeas-integration.yaml b/.librarian/generator-input/client-post-processing/containeranalysis-grafeas-integration.yaml index 65602c6d2286..6f8fe28e7966 100644 --- a/.librarian/generator-input/client-post-processing/containeranalysis-grafeas-integration.yaml +++ b/.librarian/generator-input/client-post-processing/containeranalysis-grafeas-integration.yaml @@ -19,14 +19,14 @@ replacements: ] before: | dependencies = \[ - "google-api-core\[grpc\] >= 2.17.1, <3.0.0", + "google-api-core\[grpc\] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", after: | dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", diff --git a/.librarian/generator-input/client-post-processing/integrate-isolated-handwritten-code.yaml b/.librarian/generator-input/client-post-processing/integrate-isolated-handwritten-code.yaml index d7a85d8e40a8..fb4b1af44058 100644 --- a/.librarian/generator-input/client-post-processing/integrate-isolated-handwritten-code.yaml +++ b/.librarian/generator-input/client-post-processing/integrate-isolated-handwritten-code.yaml @@ -60,14 +60,14 @@ replacements: ] before: | dependencies = \[ - "google-api-core\[grpc\] >= 2.17.1, <3.0.0", + "google-api-core\[grpc\] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", after: | dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", @@ -210,10 +210,10 @@ replacements: packages/google-cloud-automl/testing/constraints-3.10.txt, ] before: | - google-api-core==2.17.1 + google-api-core==2.24.2 google-auth==2.14.1 after: | - google-api-core==2.17.1 + google-api-core==2.24.2 google-cloud-storage==2.14.0 libcst==0.2.5 pandas==1.3.4 @@ -331,7 +331,7 @@ replacements: "grpcio >= 1.59.0, < 2.0.0", after: | "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", - "google-cloud-logging>=3.9.0, <4.0.0", + "google-cloud-logging>=3.12.0, <4.0.0", "grpcio >= 1.59.0, < 2.0.0", count: 1 - paths: [ @@ -424,10 +424,10 @@ replacements: "packages/google-cloud-monitoring/testing/constraints-3.10.txt", ] before: | - google-api-core==2.17.1 + google-api-core==2.24.2 google-auth==2.14.1 after: | - google-api-core==2.17.1 + google-api-core==2.24.2 pandas==1.3.4 numpy==1.21.3 google-auth==2.14.1 @@ -440,7 +440,7 @@ replacements: grpcio==1.59.0 after: | google-auth==2.14.1 - google-cloud-logging==3.9.0 + google-cloud-logging==3.12.0 grpcio==1.59.0 count: 1 - paths: [ diff --git a/.librarian/generator-input/client-post-processing/logging-integration.yaml b/.librarian/generator-input/client-post-processing/logging-integration.yaml index 543f261c0738..f5ff09d4d7d5 100644 --- a/.librarian/generator-input/client-post-processing/logging-integration.yaml +++ b/.librarian/generator-input/client-post-processing/logging-integration.yaml @@ -42,9 +42,9 @@ replacements: after: | "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "google-cloud-appengine-logging>=0.1.3, <2.0.0", - "google-cloud-audit-log >= 0.3.1, < 1.0.0", + "google-cloud-audit-log >= 0.3.2, < 1.0.0", "google-cloud-core >= 2.0.0, <3.0.0", - "grpc-google-iam-v1 >=0.12.4, <1.0.0", + "grpc-google-iam-v1 >=0.14.2, <1.0.0", "opentelemetry-api >= 1.16.0", "grpcio >= 1.59.0, < 2.0.0", count: 1 @@ -57,9 +57,9 @@ replacements: after: | google-auth==2.14.1 google-cloud-appengine-logging==0.1.3 - google-cloud-audit-log==0.3.1 + google-cloud-audit-log==0.3.2 google-cloud-core==2.0.0 - grpc-google-iam-v1==0.12.4 + grpc-google-iam-v1==0.14.2 opentelemetry-api==1.16.0 grpcio==1.59.0 count: 1 diff --git a/.librarian/generator-input/client-post-processing/pubsub-integration.yaml b/.librarian/generator-input/client-post-processing/pubsub-integration.yaml index 97e87b026ae5..d90529897d1c 100644 --- a/.librarian/generator-input/client-post-processing/pubsub-integration.yaml +++ b/.librarian/generator-input/client-post-processing/pubsub-integration.yaml @@ -506,9 +506,9 @@ replacements: - paths: - "packages/google-cloud-pubsub/testing/constraints-3.10.txt" - before: 'grpc-google-iam-v1==0\.14\.0\n(?!grpcio-status)' + before: 'grpc-google-iam-v1==0\.14\.2\n(?!grpcio-status)' after: |- - grpc-google-iam-v1==0.14.0 + grpc-google-iam-v1==0.14.2 grpcio-status==1.51.3 opentelemetry-api==1.27.0 opentelemetry-sdk==1.27.0 diff --git a/.librarian/generator-input/client-post-processing/storage-integration.yaml b/.librarian/generator-input/client-post-processing/storage-integration.yaml index 55a062f43071..eb1fc8547227 100644 --- a/.librarian/generator-input/client-post-processing/storage-integration.yaml +++ b/.librarian/generator-input/client-post-processing/storage-integration.yaml @@ -640,12 +640,12 @@ replacements: packages/google-cloud-storage/testing/constraints-3.10.txt ] before: | - google-api-core==2.17.1 + google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 - proto-plus==1.22.3 - protobuf==4.25.8 - grpc-google-iam-v1==0.14.0 + proto-plus==1.26.1 + protobuf==6.33.5 + grpc-google-iam-v1==0.14.2 after: | google-auth==2.26.1 # cryptography is a direct dependency of google-auth diff --git a/librarian.yaml b/librarian.yaml index 61c8bfff2c48..e8cc16d4b7bc 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. language: python -version: v0.19.0 +version: v0.21.0 repo: googleapis/google-cloud-python sources: googleapis: @@ -636,6 +636,7 @@ libraries: apis: - path: google/bigtable/v2 - path: google/bigtable/admin/v2 + skip_generate: true skip_release: true python: library_type: GAPIC_COMBO @@ -763,6 +764,8 @@ libraries: version: 1.48.0 apis: - path: google/cloud/compute/v1 + skip_generate: true + skip_release: true python: metadata_name_override: compute default_version: v1 @@ -1934,6 +1937,8 @@ libraries: - docs/spanner_v1/table.rst - docs/spanner_v1/transaction.rst - tests/unit/gapic/conftest.py + skip_generate: true + skip_release: true python: library_type: GAPIC_COMBO opt_args_by_api: diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/__init__.py index 8b39194d132b..c0b4c9857aa5 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/__init__.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/__init__.py @@ -582,7 +582,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -611,9 +611,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-ads-admanager/setup.py b/packages/google-ads-admanager/setup.py index 58ac519a48ab..cf1356d9e3d7 100644 --- a/packages/google-ads-admanager/setup.py +++ b/packages/google-ads-admanager/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/ads/admanager/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-ads-admanager" diff --git a/packages/google-ads-admanager/testing/constraints-3.10.txt b/packages/google-ads-admanager/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-ads-admanager/testing/constraints-3.10.txt +++ b/packages/google-ads-admanager/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-ads-admanager/testing/constraints-3.13.txt b/packages/google-ads-admanager/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-ads-admanager/testing/constraints-3.13.txt +++ b/packages/google-ads-admanager/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-ads-admanager/testing/constraints-3.14.txt b/packages/google-ads-admanager/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-ads-admanager/testing/constraints-3.14.txt +++ b/packages/google-ads-admanager/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-ads-datamanager/google/ads/datamanager_v1/__init__.py b/packages/google-ads-datamanager/google/ads/datamanager_v1/__init__.py index ada6908ff2af..090ecb7224b2 100644 --- a/packages/google-ads-datamanager/google/ads/datamanager_v1/__init__.py +++ b/packages/google-ads-datamanager/google/ads/datamanager_v1/__init__.py @@ -191,7 +191,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -220,9 +220,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-ads-datamanager/setup.py b/packages/google-ads-datamanager/setup.py index 46fabd9b7fcf..4ac14d2a8cf3 100644 --- a/packages/google-ads-datamanager/setup.py +++ b/packages/google-ads-datamanager/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/ads/datamanager/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-ads-datamanager" diff --git a/packages/google-ads-datamanager/testing/constraints-3.10.txt b/packages/google-ads-datamanager/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-ads-datamanager/testing/constraints-3.10.txt +++ b/packages/google-ads-datamanager/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-ads-datamanager/testing/constraints-3.13.txt b/packages/google-ads-datamanager/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-ads-datamanager/testing/constraints-3.13.txt +++ b/packages/google-ads-datamanager/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-ads-datamanager/testing/constraints-3.14.txt b/packages/google-ads-datamanager/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-ads-datamanager/testing/constraints-3.14.txt +++ b/packages/google-ads-datamanager/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-ads-marketingplatform-admin/google/ads/marketingplatform_admin_v1alpha/__init__.py b/packages/google-ads-marketingplatform-admin/google/ads/marketingplatform_admin_v1alpha/__init__.py index 04eadd2381ff..fce2c804bf34 100644 --- a/packages/google-ads-marketingplatform-admin/google/ads/marketingplatform_admin_v1alpha/__init__.py +++ b/packages/google-ads-marketingplatform-admin/google/ads/marketingplatform_admin_v1alpha/__init__.py @@ -75,7 +75,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -104,9 +104,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-ads-marketingplatform-admin/setup.py b/packages/google-ads-marketingplatform-admin/setup.py index b4e9ddafeb60..f965e024ed18 100644 --- a/packages/google-ads-marketingplatform-admin/setup.py +++ b/packages/google-ads-marketingplatform-admin/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/ads/marketingplatform_admin/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-ads-marketingplatform-admin" diff --git a/packages/google-ads-marketingplatform-admin/testing/constraints-3.10.txt b/packages/google-ads-marketingplatform-admin/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-ads-marketingplatform-admin/testing/constraints-3.10.txt +++ b/packages/google-ads-marketingplatform-admin/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-ads-marketingplatform-admin/testing/constraints-3.13.txt b/packages/google-ads-marketingplatform-admin/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-ads-marketingplatform-admin/testing/constraints-3.13.txt +++ b/packages/google-ads-marketingplatform-admin/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-ads-marketingplatform-admin/testing/constraints-3.14.txt b/packages/google-ads-marketingplatform-admin/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-ads-marketingplatform-admin/testing/constraints-3.14.txt +++ b/packages/google-ads-marketingplatform-admin/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-ai-generativelanguage/google/ai/generativelanguage_v1/__init__.py b/packages/google-ai-generativelanguage/google/ai/generativelanguage_v1/__init__.py index 4457758668f1..294e4da544c1 100644 --- a/packages/google-ai-generativelanguage/google/ai/generativelanguage_v1/__init__.py +++ b/packages/google-ai-generativelanguage/google/ai/generativelanguage_v1/__init__.py @@ -89,7 +89,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -118,9 +118,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-ai-generativelanguage/google/ai/generativelanguage_v1alpha/__init__.py b/packages/google-ai-generativelanguage/google/ai/generativelanguage_v1alpha/__init__.py index 891df6525c05..a6e7f1e556c1 100644 --- a/packages/google-ai-generativelanguage/google/ai/generativelanguage_v1alpha/__init__.py +++ b/packages/google-ai-generativelanguage/google/ai/generativelanguage_v1alpha/__init__.py @@ -256,7 +256,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -285,9 +285,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-ai-generativelanguage/google/ai/generativelanguage_v1beta/__init__.py b/packages/google-ai-generativelanguage/google/ai/generativelanguage_v1beta/__init__.py index 93eea1a9c84a..58c0e656ac41 100644 --- a/packages/google-ai-generativelanguage/google/ai/generativelanguage_v1beta/__init__.py +++ b/packages/google-ai-generativelanguage/google/ai/generativelanguage_v1beta/__init__.py @@ -287,7 +287,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -316,9 +316,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-ai-generativelanguage/google/ai/generativelanguage_v1beta2/__init__.py b/packages/google-ai-generativelanguage/google/ai/generativelanguage_v1beta2/__init__.py index c1dd2005fc76..c1713865fa8d 100644 --- a/packages/google-ai-generativelanguage/google/ai/generativelanguage_v1beta2/__init__.py +++ b/packages/google-ai-generativelanguage/google/ai/generativelanguage_v1beta2/__init__.py @@ -80,7 +80,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -109,9 +109,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-ai-generativelanguage/google/ai/generativelanguage_v1beta3/__init__.py b/packages/google-ai-generativelanguage/google/ai/generativelanguage_v1beta3/__init__.py index 8eaeca833014..f87f1d11c52a 100644 --- a/packages/google-ai-generativelanguage/google/ai/generativelanguage_v1beta3/__init__.py +++ b/packages/google-ai-generativelanguage/google/ai/generativelanguage_v1beta3/__init__.py @@ -120,7 +120,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -149,9 +149,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-ai-generativelanguage/setup.py b/packages/google-ai-generativelanguage/setup.py index 26599479f3c7..e42402798b73 100644 --- a/packages/google-ai-generativelanguage/setup.py +++ b/packages/google-ai-generativelanguage/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/ai/generativelanguage/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-ai-generativelanguage" diff --git a/packages/google-ai-generativelanguage/testing/constraints-3.10.txt b/packages/google-ai-generativelanguage/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-ai-generativelanguage/testing/constraints-3.10.txt +++ b/packages/google-ai-generativelanguage/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-ai-generativelanguage/testing/constraints-3.13.txt b/packages/google-ai-generativelanguage/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-ai-generativelanguage/testing/constraints-3.13.txt +++ b/packages/google-ai-generativelanguage/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-ai-generativelanguage/testing/constraints-3.14.txt b/packages/google-ai-generativelanguage/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-ai-generativelanguage/testing/constraints-3.14.txt +++ b/packages/google-ai-generativelanguage/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-analytics-admin/google/analytics/admin_v1alpha/__init__.py b/packages/google-analytics-admin/google/analytics/admin_v1alpha/__init__.py index d41121620ee6..d5044effcba8 100644 --- a/packages/google-analytics-admin/google/analytics/admin_v1alpha/__init__.py +++ b/packages/google-analytics-admin/google/analytics/admin_v1alpha/__init__.py @@ -359,7 +359,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -388,9 +388,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-analytics-admin/google/analytics/admin_v1beta/__init__.py b/packages/google-analytics-admin/google/analytics/admin_v1beta/__init__.py index 3b9b525df797..4c5e04368ced 100644 --- a/packages/google-analytics-admin/google/analytics/admin_v1beta/__init__.py +++ b/packages/google-analytics-admin/google/analytics/admin_v1beta/__init__.py @@ -169,7 +169,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -198,9 +198,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-analytics-admin/setup.py b/packages/google-analytics-admin/setup.py index 5bf56c657b44..2566dfedcc5e 100644 --- a/packages/google-analytics-admin/setup.py +++ b/packages/google-analytics-admin/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/analytics/admin/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-analytics-admin" diff --git a/packages/google-analytics-admin/testing/constraints-3.10.txt b/packages/google-analytics-admin/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-analytics-admin/testing/constraints-3.10.txt +++ b/packages/google-analytics-admin/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-analytics-admin/testing/constraints-3.13.txt b/packages/google-analytics-admin/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-analytics-admin/testing/constraints-3.13.txt +++ b/packages/google-analytics-admin/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-analytics-admin/testing/constraints-3.14.txt b/packages/google-analytics-admin/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-analytics-admin/testing/constraints-3.14.txt +++ b/packages/google-analytics-admin/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-analytics-data/google/analytics/data_v1alpha/__init__.py b/packages/google-analytics-data/google/analytics/data_v1alpha/__init__.py index 03764340690c..75bf16a771fe 100644 --- a/packages/google-analytics-data/google/analytics/data_v1alpha/__init__.py +++ b/packages/google-analytics-data/google/analytics/data_v1alpha/__init__.py @@ -171,7 +171,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -200,9 +200,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-analytics-data/google/analytics/data_v1beta/__init__.py b/packages/google-analytics-data/google/analytics/data_v1beta/__init__.py index 41d22479e94f..2a7dcb2cb486 100644 --- a/packages/google-analytics-data/google/analytics/data_v1beta/__init__.py +++ b/packages/google-analytics-data/google/analytics/data_v1beta/__init__.py @@ -118,7 +118,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -147,9 +147,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-analytics-data/setup.py b/packages/google-analytics-data/setup.py index 2587aad63f16..f65b9a764f3c 100644 --- a/packages/google-analytics-data/setup.py +++ b/packages/google-analytics-data/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/analytics/data/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-analytics-data" diff --git a/packages/google-analytics-data/testing/constraints-3.10.txt b/packages/google-analytics-data/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-analytics-data/testing/constraints-3.10.txt +++ b/packages/google-analytics-data/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-analytics-data/testing/constraints-3.13.txt b/packages/google-analytics-data/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-analytics-data/testing/constraints-3.13.txt +++ b/packages/google-analytics-data/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-analytics-data/testing/constraints-3.14.txt b/packages/google-analytics-data/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-analytics-data/testing/constraints-3.14.txt +++ b/packages/google-analytics-data/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-apps-card/google/apps/card_v1/__init__.py b/packages/google-apps-card/google/apps/card_v1/__init__.py index c096c576359d..313419bb4c4b 100644 --- a/packages/google-apps-card/google/apps/card_v1/__init__.py +++ b/packages/google-apps-card/google/apps/card_v1/__init__.py @@ -79,7 +79,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -108,9 +108,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-apps-card/setup.py b/packages/google-apps-card/setup.py index 318cd93ce4d4..161175be73be 100644 --- a/packages/google-apps-card/setup.py +++ b/packages/google-apps-card/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/apps/card/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-apps-card" diff --git a/packages/google-apps-card/testing/constraints-3.10.txt b/packages/google-apps-card/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-apps-card/testing/constraints-3.10.txt +++ b/packages/google-apps-card/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-apps-card/testing/constraints-3.13.txt b/packages/google-apps-card/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-apps-card/testing/constraints-3.13.txt +++ b/packages/google-apps-card/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-apps-card/testing/constraints-3.14.txt b/packages/google-apps-card/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-apps-card/testing/constraints-3.14.txt +++ b/packages/google-apps-card/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-apps-chat/google/apps/chat_v1/__init__.py b/packages/google-apps-chat/google/apps/chat_v1/__init__.py index 52f15f6f26c2..630ee3de1917 100644 --- a/packages/google-apps-chat/google/apps/chat_v1/__init__.py +++ b/packages/google-apps-chat/google/apps/chat_v1/__init__.py @@ -193,7 +193,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -222,9 +222,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-apps-chat/setup.py b/packages/google-apps-chat/setup.py index 2c5c14bd9670..4b1e23dc5449 100644 --- a/packages/google-apps-chat/setup.py +++ b/packages/google-apps-chat/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/apps/chat/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", "google-apps-card >= 0.3.0, <1.0.0", ] extras = {} diff --git a/packages/google-apps-chat/testing/constraints-3.10.txt b/packages/google-apps-chat/testing/constraints-3.10.txt index 3af90f8e61b8..1e4d176ff35e 100644 --- a/packages/google-apps-chat/testing/constraints-3.10.txt +++ b/packages/google-apps-chat/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 google-apps-card==0.3.0 diff --git a/packages/google-apps-chat/testing/constraints-3.13.txt b/packages/google-apps-chat/testing/constraints-3.13.txt index 6cffc701cac5..dfbecf969055 100644 --- a/packages/google-apps-chat/testing/constraints-3.13.txt +++ b/packages/google-apps-chat/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-apps-card>=0 diff --git a/packages/google-apps-chat/testing/constraints-3.14.txt b/packages/google-apps-chat/testing/constraints-3.14.txt index 6cffc701cac5..dfbecf969055 100644 --- a/packages/google-apps-chat/testing/constraints-3.14.txt +++ b/packages/google-apps-chat/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-apps-card>=0 diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/__init__.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/__init__.py index 14e026c429e0..cb688f7b8572 100644 --- a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/__init__.py +++ b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/__init__.py @@ -71,7 +71,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -100,9 +100,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1beta/__init__.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1beta/__init__.py index 3663cdeae9ad..ffc141d511d5 100644 --- a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1beta/__init__.py +++ b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1beta/__init__.py @@ -71,7 +71,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -100,9 +100,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-apps-events-subscriptions/setup.py b/packages/google-apps-events-subscriptions/setup.py index 639938a7908d..b5b08e9309ca 100644 --- a/packages/google-apps-events-subscriptions/setup.py +++ b/packages/google-apps-events-subscriptions/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/apps/events_subscriptions/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-apps-events-subscriptions" diff --git a/packages/google-apps-events-subscriptions/testing/constraints-3.10.txt b/packages/google-apps-events-subscriptions/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-apps-events-subscriptions/testing/constraints-3.10.txt +++ b/packages/google-apps-events-subscriptions/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-apps-events-subscriptions/testing/constraints-3.13.txt b/packages/google-apps-events-subscriptions/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-apps-events-subscriptions/testing/constraints-3.13.txt +++ b/packages/google-apps-events-subscriptions/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-apps-events-subscriptions/testing/constraints-3.14.txt b/packages/google-apps-events-subscriptions/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-apps-events-subscriptions/testing/constraints-3.14.txt +++ b/packages/google-apps-events-subscriptions/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-apps-meet/google/apps/meet_v2/__init__.py b/packages/google-apps-meet/google/apps/meet_v2/__init__.py index 11df27e80829..0c41eb5e68c8 100644 --- a/packages/google-apps-meet/google/apps/meet_v2/__init__.py +++ b/packages/google-apps-meet/google/apps/meet_v2/__init__.py @@ -94,7 +94,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -123,9 +123,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-apps-meet/google/apps/meet_v2beta/__init__.py b/packages/google-apps-meet/google/apps/meet_v2beta/__init__.py index e0b7b696428d..cbb111edec93 100644 --- a/packages/google-apps-meet/google/apps/meet_v2beta/__init__.py +++ b/packages/google-apps-meet/google/apps/meet_v2beta/__init__.py @@ -102,7 +102,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -131,9 +131,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-apps-meet/setup.py b/packages/google-apps-meet/setup.py index e6790d3df309..76e2a406cb6c 100644 --- a/packages/google-apps-meet/setup.py +++ b/packages/google-apps-meet/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/apps/meet/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-apps-meet" diff --git a/packages/google-apps-meet/testing/constraints-3.10.txt b/packages/google-apps-meet/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-apps-meet/testing/constraints-3.10.txt +++ b/packages/google-apps-meet/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-apps-meet/testing/constraints-3.13.txt b/packages/google-apps-meet/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-apps-meet/testing/constraints-3.13.txt +++ b/packages/google-apps-meet/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-apps-meet/testing/constraints-3.14.txt b/packages/google-apps-meet/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-apps-meet/testing/constraints-3.14.txt +++ b/packages/google-apps-meet/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-apps-script-type/google/apps/script/type/__init__.py b/packages/google-apps-script-type/google/apps/script/type/__init__.py index 3092b9f884ba..07fa33487f10 100644 --- a/packages/google-apps-script-type/google/apps/script/type/__init__.py +++ b/packages/google-apps-script-type/google/apps/script/type/__init__.py @@ -61,7 +61,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -90,9 +90,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-apps-script-type/google/apps/script/type/calendar/__init__.py b/packages/google-apps-script-type/google/apps/script/type/calendar/__init__.py index 5ce17f903e0d..751d9070fcac 100644 --- a/packages/google-apps-script-type/google/apps/script/type/calendar/__init__.py +++ b/packages/google-apps-script-type/google/apps/script/type/calendar/__init__.py @@ -54,7 +54,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -83,9 +83,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-apps-script-type/google/apps/script/type/docs/__init__.py b/packages/google-apps-script-type/google/apps/script/type/docs/__init__.py index fc22178650d9..c61b1a0a687d 100644 --- a/packages/google-apps-script-type/google/apps/script/type/docs/__init__.py +++ b/packages/google-apps-script-type/google/apps/script/type/docs/__init__.py @@ -50,7 +50,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -79,9 +79,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-apps-script-type/google/apps/script/type/drive/__init__.py b/packages/google-apps-script-type/google/apps/script/type/drive/__init__.py index 1a88a001d639..2c4e0113d725 100644 --- a/packages/google-apps-script-type/google/apps/script/type/drive/__init__.py +++ b/packages/google-apps-script-type/google/apps/script/type/drive/__init__.py @@ -50,7 +50,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -79,9 +79,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-apps-script-type/google/apps/script/type/gmail/__init__.py b/packages/google-apps-script-type/google/apps/script/type/gmail/__init__.py index ee1f432bb819..15b7ab7cfee6 100644 --- a/packages/google-apps-script-type/google/apps/script/type/gmail/__init__.py +++ b/packages/google-apps-script-type/google/apps/script/type/gmail/__init__.py @@ -56,7 +56,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -85,9 +85,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-apps-script-type/google/apps/script/type/sheets/__init__.py b/packages/google-apps-script-type/google/apps/script/type/sheets/__init__.py index aeedd177542d..6eb865763637 100644 --- a/packages/google-apps-script-type/google/apps/script/type/sheets/__init__.py +++ b/packages/google-apps-script-type/google/apps/script/type/sheets/__init__.py @@ -50,7 +50,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -79,9 +79,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-apps-script-type/google/apps/script/type/slides/__init__.py b/packages/google-apps-script-type/google/apps/script/type/slides/__init__.py index 8c9e5517ee6a..2cb67b5f5a8b 100644 --- a/packages/google-apps-script-type/google/apps/script/type/slides/__init__.py +++ b/packages/google-apps-script-type/google/apps/script/type/slides/__init__.py @@ -50,7 +50,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -79,9 +79,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-apps-script-type/setup.py b/packages/google-apps-script-type/setup.py index 7a4b08ab118e..6b6ef8d5f37e 100644 --- a/packages/google-apps-script-type/setup.py +++ b/packages/google-apps-script-type/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/apps/script/type/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-apps-script-type" diff --git a/packages/google-apps-script-type/testing/constraints-3.10.txt b/packages/google-apps-script-type/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-apps-script-type/testing/constraints-3.10.txt +++ b/packages/google-apps-script-type/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-apps-script-type/testing/constraints-3.13.txt b/packages/google-apps-script-type/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-apps-script-type/testing/constraints-3.13.txt +++ b/packages/google-apps-script-type/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-apps-script-type/testing/constraints-3.14.txt b/packages/google-apps-script-type/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-apps-script-type/testing/constraints-3.14.txt +++ b/packages/google-apps-script-type/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-area120-tables/google/area120/tables_v1alpha1/__init__.py b/packages/google-area120-tables/google/area120/tables_v1alpha1/__init__.py index 616b3ca2f849..fb36c8448d4b 100644 --- a/packages/google-area120-tables/google/area120/tables_v1alpha1/__init__.py +++ b/packages/google-area120-tables/google/area120/tables_v1alpha1/__init__.py @@ -77,7 +77,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -106,9 +106,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-area120-tables/setup.py b/packages/google-area120-tables/setup.py index 033db87198aa..0bd6b1303c90 100644 --- a/packages/google-area120-tables/setup.py +++ b/packages/google-area120-tables/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/area120/tables/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-area120-tables" diff --git a/packages/google-area120-tables/testing/constraints-3.10.txt b/packages/google-area120-tables/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-area120-tables/testing/constraints-3.10.txt +++ b/packages/google-area120-tables/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-area120-tables/testing/constraints-3.13.txt b/packages/google-area120-tables/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-area120-tables/testing/constraints-3.13.txt +++ b/packages/google-area120-tables/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-area120-tables/testing/constraints-3.14.txt b/packages/google-area120-tables/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-area120-tables/testing/constraints-3.14.txt +++ b/packages/google-area120-tables/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-backstory/google/backstory/__init__.py b/packages/google-backstory/google/backstory/__init__.py index bdb09ee6600d..95cf541e8151 100644 --- a/packages/google-backstory/google/backstory/__init__.py +++ b/packages/google-backstory/google/backstory/__init__.py @@ -162,7 +162,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -191,9 +191,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-backstory/setup.py b/packages/google-backstory/setup.py index 0bc1a58702fc..91d7cdddecd6 100644 --- a/packages/google-backstory/setup.py +++ b/packages/google-backstory/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/backstory/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-backstory" diff --git a/packages/google-backstory/testing/constraints-3.10.txt b/packages/google-backstory/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-backstory/testing/constraints-3.10.txt +++ b/packages/google-backstory/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-backstory/testing/constraints-3.13.txt b/packages/google-backstory/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-backstory/testing/constraints-3.13.txt +++ b/packages/google-backstory/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-backstory/testing/constraints-3.14.txt b/packages/google-backstory/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-backstory/testing/constraints-3.14.txt +++ b/packages/google-backstory/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-access-approval/google/cloud/accessapproval_v1/__init__.py b/packages/google-cloud-access-approval/google/cloud/accessapproval_v1/__init__.py index abffedbe7fe8..c6a648dccb13 100644 --- a/packages/google-cloud-access-approval/google/cloud/accessapproval_v1/__init__.py +++ b/packages/google-cloud-access-approval/google/cloud/accessapproval_v1/__init__.py @@ -73,7 +73,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -102,9 +102,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-access-approval/setup.py b/packages/google-cloud-access-approval/setup.py index 7da5c9780181..dcc6f6cfbf13 100644 --- a/packages/google-cloud-access-approval/setup.py +++ b/packages/google-cloud-access-approval/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/accessapproval/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-access-approval" diff --git a/packages/google-cloud-access-approval/testing/constraints-3.10.txt b/packages/google-cloud-access-approval/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-access-approval/testing/constraints-3.10.txt +++ b/packages/google-cloud-access-approval/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-access-approval/testing/constraints-3.13.txt b/packages/google-cloud-access-approval/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-access-approval/testing/constraints-3.13.txt +++ b/packages/google-cloud-access-approval/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-access-approval/testing/constraints-3.14.txt b/packages/google-cloud-access-approval/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-access-approval/testing/constraints-3.14.txt +++ b/packages/google-cloud-access-approval/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-advisorynotifications/google/cloud/advisorynotifications_v1/__init__.py b/packages/google-cloud-advisorynotifications/google/cloud/advisorynotifications_v1/__init__.py index 0c721afc0fc0..a1970d649ca3 100644 --- a/packages/google-cloud-advisorynotifications/google/cloud/advisorynotifications_v1/__init__.py +++ b/packages/google-cloud-advisorynotifications/google/cloud/advisorynotifications_v1/__init__.py @@ -71,7 +71,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -100,9 +100,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-advisorynotifications/setup.py b/packages/google-cloud-advisorynotifications/setup.py index 8d0ca3914c4b..c52060f36d3e 100644 --- a/packages/google-cloud-advisorynotifications/setup.py +++ b/packages/google-cloud-advisorynotifications/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/advisorynotifications/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-advisorynotifications" diff --git a/packages/google-cloud-advisorynotifications/testing/constraints-3.10.txt b/packages/google-cloud-advisorynotifications/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-advisorynotifications/testing/constraints-3.10.txt +++ b/packages/google-cloud-advisorynotifications/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-advisorynotifications/testing/constraints-3.13.txt b/packages/google-cloud-advisorynotifications/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-advisorynotifications/testing/constraints-3.13.txt +++ b/packages/google-cloud-advisorynotifications/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-advisorynotifications/testing/constraints-3.14.txt b/packages/google-cloud-advisorynotifications/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-advisorynotifications/testing/constraints-3.14.txt +++ b/packages/google-cloud-advisorynotifications/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/__init__.py b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/__init__.py index aa5fecf0e405..bf30d3d6f734 100644 --- a/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/__init__.py +++ b/packages/google-cloud-agentidentitycredentials/google/cloud/agentidentitycredentials_v1/__init__.py @@ -59,7 +59,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -88,9 +88,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-agentidentitycredentials/setup.py b/packages/google-cloud-agentidentitycredentials/setup.py index d664811f1e93..8f0e6f4c9798 100644 --- a/packages/google-cloud-agentidentitycredentials/setup.py +++ b/packages/google-cloud-agentidentitycredentials/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/agentidentitycredentials/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-agentidentitycredentials" diff --git a/packages/google-cloud-agentidentitycredentials/testing/constraints-3.10.txt b/packages/google-cloud-agentidentitycredentials/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-agentidentitycredentials/testing/constraints-3.10.txt +++ b/packages/google-cloud-agentidentitycredentials/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-agentidentitycredentials/testing/constraints-3.13.txt b/packages/google-cloud-agentidentitycredentials/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-agentidentitycredentials/testing/constraints-3.13.txt +++ b/packages/google-cloud-agentidentitycredentials/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-agentidentitycredentials/testing/constraints-3.14.txt b/packages/google-cloud-agentidentitycredentials/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-agentidentitycredentials/testing/constraints-3.14.txt +++ b/packages/google-cloud-agentidentitycredentials/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-alloydb-connectors/google/cloud/alloydb/connectors_v1/__init__.py b/packages/google-cloud-alloydb-connectors/google/cloud/alloydb/connectors_v1/__init__.py index 31debc4106be..34f50e5adfcf 100644 --- a/packages/google-cloud-alloydb-connectors/google/cloud/alloydb/connectors_v1/__init__.py +++ b/packages/google-cloud-alloydb-connectors/google/cloud/alloydb/connectors_v1/__init__.py @@ -50,7 +50,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -79,9 +79,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-alloydb-connectors/google/cloud/alloydb/connectors_v1alpha/__init__.py b/packages/google-cloud-alloydb-connectors/google/cloud/alloydb/connectors_v1alpha/__init__.py index a98244871cda..656daf15acd2 100644 --- a/packages/google-cloud-alloydb-connectors/google/cloud/alloydb/connectors_v1alpha/__init__.py +++ b/packages/google-cloud-alloydb-connectors/google/cloud/alloydb/connectors_v1alpha/__init__.py @@ -50,7 +50,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -79,9 +79,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-alloydb-connectors/google/cloud/alloydb/connectors_v1beta/__init__.py b/packages/google-cloud-alloydb-connectors/google/cloud/alloydb/connectors_v1beta/__init__.py index 66c5491aeda7..ab60f0ecc6e2 100644 --- a/packages/google-cloud-alloydb-connectors/google/cloud/alloydb/connectors_v1beta/__init__.py +++ b/packages/google-cloud-alloydb-connectors/google/cloud/alloydb/connectors_v1beta/__init__.py @@ -50,7 +50,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -79,9 +79,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-alloydb-connectors/setup.py b/packages/google-cloud-alloydb-connectors/setup.py index 47dc6f396d48..5270893f7303 100644 --- a/packages/google-cloud-alloydb-connectors/setup.py +++ b/packages/google-cloud-alloydb-connectors/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/alloydb/connectors/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-alloydb-connectors" diff --git a/packages/google-cloud-alloydb-connectors/testing/constraints-3.10.txt b/packages/google-cloud-alloydb-connectors/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-alloydb-connectors/testing/constraints-3.10.txt +++ b/packages/google-cloud-alloydb-connectors/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-alloydb-connectors/testing/constraints-3.13.txt b/packages/google-cloud-alloydb-connectors/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-alloydb-connectors/testing/constraints-3.13.txt +++ b/packages/google-cloud-alloydb-connectors/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-alloydb-connectors/testing/constraints-3.14.txt b/packages/google-cloud-alloydb-connectors/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-alloydb-connectors/testing/constraints-3.14.txt +++ b/packages/google-cloud-alloydb-connectors/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-alloydb/google/cloud/alloydb_v1/__init__.py b/packages/google-cloud-alloydb/google/cloud/alloydb_v1/__init__.py index 5b2a718d48ac..d420ba1bc373 100644 --- a/packages/google-cloud-alloydb/google/cloud/alloydb_v1/__init__.py +++ b/packages/google-cloud-alloydb/google/cloud/alloydb_v1/__init__.py @@ -140,7 +140,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -169,9 +169,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-alloydb/google/cloud/alloydb_v1alpha/__init__.py b/packages/google-cloud-alloydb/google/cloud/alloydb_v1alpha/__init__.py index 2745dc6bc514..ff2b3915e356 100644 --- a/packages/google-cloud-alloydb/google/cloud/alloydb_v1alpha/__init__.py +++ b/packages/google-cloud-alloydb/google/cloud/alloydb_v1alpha/__init__.py @@ -148,7 +148,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -177,9 +177,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-alloydb/google/cloud/alloydb_v1beta/__init__.py b/packages/google-cloud-alloydb/google/cloud/alloydb_v1beta/__init__.py index 5fe84055a0e0..aa18b69d95d6 100644 --- a/packages/google-cloud-alloydb/google/cloud/alloydb_v1beta/__init__.py +++ b/packages/google-cloud-alloydb/google/cloud/alloydb_v1beta/__init__.py @@ -148,7 +148,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -177,9 +177,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-alloydb/setup.py b/packages/google-cloud-alloydb/setup.py index 87face2890a5..f9c7c1bdd5ca 100644 --- a/packages/google-cloud-alloydb/setup.py +++ b/packages/google-cloud-alloydb/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/alloydb/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-alloydb" diff --git a/packages/google-cloud-alloydb/testing/constraints-3.10.txt b/packages/google-cloud-alloydb/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-alloydb/testing/constraints-3.10.txt +++ b/packages/google-cloud-alloydb/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-alloydb/testing/constraints-3.13.txt b/packages/google-cloud-alloydb/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-alloydb/testing/constraints-3.13.txt +++ b/packages/google-cloud-alloydb/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-alloydb/testing/constraints-3.14.txt b/packages/google-cloud-alloydb/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-alloydb/testing/constraints-3.14.txt +++ b/packages/google-cloud-alloydb/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-api-gateway/google/cloud/apigateway_v1/__init__.py b/packages/google-cloud-api-gateway/google/cloud/apigateway_v1/__init__.py index a7a79f57bb81..b74a9fa26c8c 100644 --- a/packages/google-cloud-api-gateway/google/cloud/apigateway_v1/__init__.py +++ b/packages/google-cloud-api-gateway/google/cloud/apigateway_v1/__init__.py @@ -77,7 +77,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -106,9 +106,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-api-gateway/setup.py b/packages/google-cloud-api-gateway/setup.py index 9c62ef5a32e9..af69e4d1519a 100644 --- a/packages/google-cloud-api-gateway/setup.py +++ b/packages/google-cloud-api-gateway/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/apigateway/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-api-gateway" diff --git a/packages/google-cloud-api-gateway/testing/constraints-3.10.txt b/packages/google-cloud-api-gateway/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-api-gateway/testing/constraints-3.10.txt +++ b/packages/google-cloud-api-gateway/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-api-gateway/testing/constraints-3.13.txt b/packages/google-cloud-api-gateway/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-api-gateway/testing/constraints-3.13.txt +++ b/packages/google-cloud-api-gateway/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-api-gateway/testing/constraints-3.14.txt b/packages/google-cloud-api-gateway/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-api-gateway/testing/constraints-3.14.txt +++ b/packages/google-cloud-api-gateway/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-api-keys/google/cloud/api_keys_v2/__init__.py b/packages/google-cloud-api-keys/google/cloud/api_keys_v2/__init__.py index 13b0a41f7116..f738f1cddb71 100644 --- a/packages/google-cloud-api-keys/google/cloud/api_keys_v2/__init__.py +++ b/packages/google-cloud-api-keys/google/cloud/api_keys_v2/__init__.py @@ -73,7 +73,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -102,9 +102,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-api-keys/setup.py b/packages/google-cloud-api-keys/setup.py index 1a6adc159e8e..d207a495b289 100644 --- a/packages/google-cloud-api-keys/setup.py +++ b/packages/google-cloud-api-keys/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/api_keys/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-api-keys" diff --git a/packages/google-cloud-api-keys/testing/constraints-3.10.txt b/packages/google-cloud-api-keys/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-api-keys/testing/constraints-3.10.txt +++ b/packages/google-cloud-api-keys/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-api-keys/testing/constraints-3.13.txt b/packages/google-cloud-api-keys/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-api-keys/testing/constraints-3.13.txt +++ b/packages/google-cloud-api-keys/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-api-keys/testing/constraints-3.14.txt b/packages/google-cloud-api-keys/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-api-keys/testing/constraints-3.14.txt +++ b/packages/google-cloud-api-keys/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-apigee-connect/google/cloud/apigeeconnect_v1/__init__.py b/packages/google-cloud-apigee-connect/google/cloud/apigeeconnect_v1/__init__.py index 7dd770701659..c8d0eda85b7f 100644 --- a/packages/google-cloud-apigee-connect/google/cloud/apigeeconnect_v1/__init__.py +++ b/packages/google-cloud-apigee-connect/google/cloud/apigeeconnect_v1/__init__.py @@ -73,7 +73,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -102,9 +102,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-apigee-connect/setup.py b/packages/google-cloud-apigee-connect/setup.py index 99b0c60e3202..112f0ccbe8a6 100644 --- a/packages/google-cloud-apigee-connect/setup.py +++ b/packages/google-cloud-apigee-connect/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/apigeeconnect/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-apigee-connect" diff --git a/packages/google-cloud-apigee-connect/testing/constraints-3.10.txt b/packages/google-cloud-apigee-connect/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-apigee-connect/testing/constraints-3.10.txt +++ b/packages/google-cloud-apigee-connect/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-apigee-connect/testing/constraints-3.13.txt b/packages/google-cloud-apigee-connect/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-apigee-connect/testing/constraints-3.13.txt +++ b/packages/google-cloud-apigee-connect/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-apigee-connect/testing/constraints-3.14.txt b/packages/google-cloud-apigee-connect/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-apigee-connect/testing/constraints-3.14.txt +++ b/packages/google-cloud-apigee-connect/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-apigee-registry/google/cloud/apigee_registry_v1/__init__.py b/packages/google-cloud-apigee-registry/google/cloud/apigee_registry_v1/__init__.py index 6ccbe4508678..3695d603ebf6 100644 --- a/packages/google-cloud-apigee-registry/google/cloud/apigee_registry_v1/__init__.py +++ b/packages/google-cloud-apigee-registry/google/cloud/apigee_registry_v1/__init__.py @@ -103,7 +103,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -132,9 +132,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-apigee-registry/setup.py b/packages/google-cloud-apigee-registry/setup.py index fc332bd518ed..a29d8f16ed7a 100644 --- a/packages/google-cloud-apigee-registry/setup.py +++ b/packages/google-cloud-apigee-registry/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/apigee_registry/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-apigee-registry" diff --git a/packages/google-cloud-apigee-registry/testing/constraints-3.10.txt b/packages/google-cloud-apigee-registry/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-apigee-registry/testing/constraints-3.10.txt +++ b/packages/google-cloud-apigee-registry/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-apigee-registry/testing/constraints-3.13.txt b/packages/google-cloud-apigee-registry/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-apigee-registry/testing/constraints-3.13.txt +++ b/packages/google-cloud-apigee-registry/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-apigee-registry/testing/constraints-3.14.txt b/packages/google-cloud-apigee-registry/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-apigee-registry/testing/constraints-3.14.txt +++ b/packages/google-cloud-apigee-registry/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-apihub/google/cloud/apihub_v1/__init__.py b/packages/google-cloud-apihub/google/cloud/apihub_v1/__init__.py index 46f8f03fa5c0..f04e150bc40e 100644 --- a/packages/google-cloud-apihub/google/cloud/apihub_v1/__init__.py +++ b/packages/google-cloud-apihub/google/cloud/apihub_v1/__init__.py @@ -264,7 +264,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -293,9 +293,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-apihub/setup.py b/packages/google-cloud-apihub/setup.py index ac4c98f6d437..1a2517509dda 100644 --- a/packages/google-cloud-apihub/setup.py +++ b/packages/google-cloud-apihub/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/apihub/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-apihub" diff --git a/packages/google-cloud-apihub/testing/constraints-3.10.txt b/packages/google-cloud-apihub/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-apihub/testing/constraints-3.10.txt +++ b/packages/google-cloud-apihub/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-apihub/testing/constraints-3.13.txt b/packages/google-cloud-apihub/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-apihub/testing/constraints-3.13.txt +++ b/packages/google-cloud-apihub/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-apihub/testing/constraints-3.14.txt b/packages/google-cloud-apihub/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-apihub/testing/constraints-3.14.txt +++ b/packages/google-cloud-apihub/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-apiregistry/google/cloud/apiregistry_v1beta/__init__.py b/packages/google-cloud-apiregistry/google/cloud/apiregistry_v1beta/__init__.py index 3501061a0239..d71fce5b3e1a 100644 --- a/packages/google-cloud-apiregistry/google/cloud/apiregistry_v1beta/__init__.py +++ b/packages/google-cloud-apiregistry/google/cloud/apiregistry_v1beta/__init__.py @@ -63,7 +63,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -92,9 +92,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-apiregistry/setup.py b/packages/google-cloud-apiregistry/setup.py index 5c9a2841ab1c..c5864e119c12 100644 --- a/packages/google-cloud-apiregistry/setup.py +++ b/packages/google-cloud-apiregistry/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/apiregistry/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-apiregistry" diff --git a/packages/google-cloud-apiregistry/testing/constraints-3.10.txt b/packages/google-cloud-apiregistry/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-apiregistry/testing/constraints-3.10.txt +++ b/packages/google-cloud-apiregistry/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-apiregistry/testing/constraints-3.13.txt b/packages/google-cloud-apiregistry/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-apiregistry/testing/constraints-3.13.txt +++ b/packages/google-cloud-apiregistry/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-apiregistry/testing/constraints-3.14.txt b/packages/google-cloud-apiregistry/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-apiregistry/testing/constraints-3.14.txt +++ b/packages/google-cloud-apiregistry/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-appengine-admin/google/cloud/appengine_admin_v1/__init__.py b/packages/google-cloud-appengine-admin/google/cloud/appengine_admin_v1/__init__.py index 9e31c27ba93c..058686a141fa 100644 --- a/packages/google-cloud-appengine-admin/google/cloud/appengine_admin_v1/__init__.py +++ b/packages/google-cloud-appengine-admin/google/cloud/appengine_admin_v1/__init__.py @@ -167,7 +167,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -196,9 +196,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-appengine-admin/setup.py b/packages/google-cloud-appengine-admin/setup.py index 14d844e106b8..a8a3e2904a77 100644 --- a/packages/google-cloud-appengine-admin/setup.py +++ b/packages/google-cloud-appengine-admin/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/appengine_admin/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-appengine-admin" diff --git a/packages/google-cloud-appengine-admin/testing/constraints-3.10.txt b/packages/google-cloud-appengine-admin/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-appengine-admin/testing/constraints-3.10.txt +++ b/packages/google-cloud-appengine-admin/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-appengine-admin/testing/constraints-3.13.txt b/packages/google-cloud-appengine-admin/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-appengine-admin/testing/constraints-3.13.txt +++ b/packages/google-cloud-appengine-admin/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-appengine-admin/testing/constraints-3.14.txt b/packages/google-cloud-appengine-admin/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-appengine-admin/testing/constraints-3.14.txt +++ b/packages/google-cloud-appengine-admin/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-appengine-logging/google/cloud/appengine_logging_v1/__init__.py b/packages/google-cloud-appengine-logging/google/cloud/appengine_logging_v1/__init__.py index c46ad467ef94..3c3a3310b970 100644 --- a/packages/google-cloud-appengine-logging/google/cloud/appengine_logging_v1/__init__.py +++ b/packages/google-cloud-appengine-logging/google/cloud/appengine_logging_v1/__init__.py @@ -50,7 +50,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -79,9 +79,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-appengine-logging/setup.py b/packages/google-cloud-appengine-logging/setup.py index 422fb283d3e9..33e6e627889d 100644 --- a/packages/google-cloud-appengine-logging/setup.py +++ b/packages/google-cloud-appengine-logging/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/appengine_logging/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-appengine-logging" diff --git a/packages/google-cloud-appengine-logging/testing/constraints-3.10.txt b/packages/google-cloud-appengine-logging/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-appengine-logging/testing/constraints-3.10.txt +++ b/packages/google-cloud-appengine-logging/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-appengine-logging/testing/constraints-3.13.txt b/packages/google-cloud-appengine-logging/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-appengine-logging/testing/constraints-3.13.txt +++ b/packages/google-cloud-appengine-logging/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-appengine-logging/testing/constraints-3.14.txt b/packages/google-cloud-appengine-logging/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-appengine-logging/testing/constraints-3.14.txt +++ b/packages/google-cloud-appengine-logging/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-apphub/google/cloud/apphub_v1/__init__.py b/packages/google-cloud-apphub/google/cloud/apphub_v1/__init__.py index 08aa2bba560d..63922ed6fc67 100644 --- a/packages/google-cloud-apphub/google/cloud/apphub_v1/__init__.py +++ b/packages/google-cloud-apphub/google/cloud/apphub_v1/__init__.py @@ -105,7 +105,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -134,9 +134,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-apphub/setup.py b/packages/google-cloud-apphub/setup.py index 64006dd5326b..ebd87f8a63c8 100644 --- a/packages/google-cloud-apphub/setup.py +++ b/packages/google-cloud-apphub/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/apphub/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-apphub" diff --git a/packages/google-cloud-apphub/testing/constraints-3.10.txt b/packages/google-cloud-apphub/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-apphub/testing/constraints-3.10.txt +++ b/packages/google-cloud-apphub/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-apphub/testing/constraints-3.13.txt b/packages/google-cloud-apphub/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-apphub/testing/constraints-3.13.txt +++ b/packages/google-cloud-apphub/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-apphub/testing/constraints-3.14.txt b/packages/google-cloud-apphub/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-apphub/testing/constraints-3.14.txt +++ b/packages/google-cloud-apphub/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-appoptimize/google/cloud/appoptimize_v1beta/__init__.py b/packages/google-cloud-appoptimize/google/cloud/appoptimize_v1beta/__init__.py index 19657159864e..d6ac1a0cf62a 100644 --- a/packages/google-cloud-appoptimize/google/cloud/appoptimize_v1beta/__init__.py +++ b/packages/google-cloud-appoptimize/google/cloud/appoptimize_v1beta/__init__.py @@ -63,7 +63,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -92,9 +92,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-appoptimize/setup.py b/packages/google-cloud-appoptimize/setup.py index be384ed6d500..76f2f022a3ff 100644 --- a/packages/google-cloud-appoptimize/setup.py +++ b/packages/google-cloud-appoptimize/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/appoptimize/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-appoptimize" diff --git a/packages/google-cloud-appoptimize/testing/constraints-3.10.txt b/packages/google-cloud-appoptimize/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-appoptimize/testing/constraints-3.10.txt +++ b/packages/google-cloud-appoptimize/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-appoptimize/testing/constraints-3.13.txt b/packages/google-cloud-appoptimize/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-appoptimize/testing/constraints-3.13.txt +++ b/packages/google-cloud-appoptimize/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-appoptimize/testing/constraints-3.14.txt b/packages/google-cloud-appoptimize/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-appoptimize/testing/constraints-3.14.txt +++ b/packages/google-cloud-appoptimize/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-artifact-registry/google/cloud/artifactregistry_v1/__init__.py b/packages/google-cloud-artifact-registry/google/cloud/artifactregistry_v1/__init__.py index 016b58fb7874..a96e1e87ccbc 100644 --- a/packages/google-cloud-artifact-registry/google/cloud/artifactregistry_v1/__init__.py +++ b/packages/google-cloud-artifact-registry/google/cloud/artifactregistry_v1/__init__.py @@ -176,7 +176,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -205,9 +205,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-artifact-registry/google/cloud/artifactregistry_v1beta2/__init__.py b/packages/google-cloud-artifact-registry/google/cloud/artifactregistry_v1beta2/__init__.py index 1c908cb04de7..dde84b7d9368 100644 --- a/packages/google-cloud-artifact-registry/google/cloud/artifactregistry_v1beta2/__init__.py +++ b/packages/google-cloud-artifact-registry/google/cloud/artifactregistry_v1beta2/__init__.py @@ -109,7 +109,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -138,9 +138,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-artifact-registry/setup.py b/packages/google-cloud-artifact-registry/setup.py index ed26efd33d9f..192863a30dce 100644 --- a/packages/google-cloud-artifact-registry/setup.py +++ b/packages/google-cloud-artifact-registry/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/artifactregistry/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-artifact-registry" diff --git a/packages/google-cloud-artifact-registry/testing/constraints-3.10.txt b/packages/google-cloud-artifact-registry/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-artifact-registry/testing/constraints-3.10.txt +++ b/packages/google-cloud-artifact-registry/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-artifact-registry/testing/constraints-3.13.txt b/packages/google-cloud-artifact-registry/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-artifact-registry/testing/constraints-3.13.txt +++ b/packages/google-cloud-artifact-registry/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-artifact-registry/testing/constraints-3.14.txt b/packages/google-cloud-artifact-registry/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-artifact-registry/testing/constraints-3.14.txt +++ b/packages/google-cloud-artifact-registry/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-asset/google/cloud/asset_v1/__init__.py b/packages/google-cloud-asset/google/cloud/asset_v1/__init__.py index 9d80550b47d0..bb9de558b7ed 100644 --- a/packages/google-cloud-asset/google/cloud/asset_v1/__init__.py +++ b/packages/google-cloud-asset/google/cloud/asset_v1/__init__.py @@ -135,7 +135,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -164,9 +164,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-asset/google/cloud/asset_v1p1beta1/__init__.py b/packages/google-cloud-asset/google/cloud/asset_v1p1beta1/__init__.py index d3091091d399..2e8f02021f6c 100644 --- a/packages/google-cloud-asset/google/cloud/asset_v1p1beta1/__init__.py +++ b/packages/google-cloud-asset/google/cloud/asset_v1p1beta1/__init__.py @@ -57,7 +57,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -86,9 +86,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-asset/google/cloud/asset_v1p2beta1/__init__.py b/packages/google-cloud-asset/google/cloud/asset_v1p2beta1/__init__.py index d1ce85f9cf46..0810de2ae7dc 100644 --- a/packages/google-cloud-asset/google/cloud/asset_v1p2beta1/__init__.py +++ b/packages/google-cloud-asset/google/cloud/asset_v1p2beta1/__init__.py @@ -67,7 +67,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -96,9 +96,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-asset/google/cloud/asset_v1p5beta1/__init__.py b/packages/google-cloud-asset/google/cloud/asset_v1p5beta1/__init__.py index 1769e4ec28d0..59e25df37eb5 100644 --- a/packages/google-cloud-asset/google/cloud/asset_v1p5beta1/__init__.py +++ b/packages/google-cloud-asset/google/cloud/asset_v1p5beta1/__init__.py @@ -52,7 +52,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -81,9 +81,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-asset/setup.py b/packages/google-cloud-asset/setup.py index cec358ae0145..26f33d34e8c5 100644 --- a/packages/google-cloud-asset/setup.py +++ b/packages/google-cloud-asset/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/asset/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,19 +42,18 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", - "google-cloud-org-policy >= 1.11.1, <2.0.0", + "google-cloud-org-policy >= 1.13.1, <2.0.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "google-cloud-access-context-manager >= 0.2.0, <1.0.0", - "google-cloud-os-config >= 1.13.0, <2.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "google-cloud-access-context-manager >= 0.2.2, <1.0.0", + "google-cloud-os-config >= 1.20.1, <2.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-asset" diff --git a/packages/google-cloud-asset/testing/constraints-3.10.txt b/packages/google-cloud-asset/testing/constraints-3.10.txt index 7d034c762509..83807339d4fb 100644 --- a/packages/google-cloud-asset/testing/constraints-3.10.txt +++ b/packages/google-cloud-asset/testing/constraints-3.10.txt @@ -4,12 +4,12 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 -google-cloud-org-policy==1.11.1 +google-api-core==2.24.2 +google-cloud-org-policy==1.13.1 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -google-cloud-access-context-manager==0.2.0 -google-cloud-os-config==1.13.0 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +google-cloud-access-context-manager==0.2.2 +google-cloud-os-config==1.20.1 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-asset/testing/constraints-3.13.txt b/packages/google-cloud-asset/testing/constraints-3.13.txt index c3db09a0c746..f63842dab6f9 100644 --- a/packages/google-cloud-asset/testing/constraints-3.13.txt +++ b/packages/google-cloud-asset/testing/constraints-3.13.txt @@ -9,7 +9,7 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-cloud-access-context-manager>=0 google-cloud-os-config>=1 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-asset/testing/constraints-3.14.txt b/packages/google-cloud-asset/testing/constraints-3.14.txt index c3db09a0c746..f63842dab6f9 100644 --- a/packages/google-cloud-asset/testing/constraints-3.14.txt +++ b/packages/google-cloud-asset/testing/constraints-3.14.txt @@ -9,7 +9,7 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-cloud-access-context-manager>=0 google-cloud-os-config>=1 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-assured-workloads/google/cloud/assuredworkloads_v1/__init__.py b/packages/google-cloud-assured-workloads/google/cloud/assuredworkloads_v1/__init__.py index e64f9d9e2750..4adbfd534c49 100644 --- a/packages/google-cloud-assured-workloads/google/cloud/assuredworkloads_v1/__init__.py +++ b/packages/google-cloud-assured-workloads/google/cloud/assuredworkloads_v1/__init__.py @@ -72,7 +72,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -101,9 +101,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-assured-workloads/google/cloud/assuredworkloads_v1beta1/__init__.py b/packages/google-cloud-assured-workloads/google/cloud/assuredworkloads_v1beta1/__init__.py index 8d348ad3bc8b..8e903cbe1d56 100644 --- a/packages/google-cloud-assured-workloads/google/cloud/assuredworkloads_v1beta1/__init__.py +++ b/packages/google-cloud-assured-workloads/google/cloud/assuredworkloads_v1beta1/__init__.py @@ -67,7 +67,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -96,9 +96,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-assured-workloads/setup.py b/packages/google-cloud-assured-workloads/setup.py index f5ee5362e2de..72e54799d8ad 100644 --- a/packages/google-cloud-assured-workloads/setup.py +++ b/packages/google-cloud-assured-workloads/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/assuredworkloads/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-assured-workloads" diff --git a/packages/google-cloud-assured-workloads/testing/constraints-3.10.txt b/packages/google-cloud-assured-workloads/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-assured-workloads/testing/constraints-3.10.txt +++ b/packages/google-cloud-assured-workloads/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-assured-workloads/testing/constraints-3.13.txt b/packages/google-cloud-assured-workloads/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-assured-workloads/testing/constraints-3.13.txt +++ b/packages/google-cloud-assured-workloads/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-assured-workloads/testing/constraints-3.14.txt b/packages/google-cloud-assured-workloads/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-assured-workloads/testing/constraints-3.14.txt +++ b/packages/google-cloud-assured-workloads/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-auditmanager/google/cloud/auditmanager_v1/__init__.py b/packages/google-cloud-auditmanager/google/cloud/auditmanager_v1/__init__.py index 666540e33d2d..0f2b2f3c7eff 100644 --- a/packages/google-cloud-auditmanager/google/cloud/auditmanager_v1/__init__.py +++ b/packages/google-cloud-auditmanager/google/cloud/auditmanager_v1/__init__.py @@ -76,7 +76,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -105,9 +105,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-auditmanager/setup.py b/packages/google-cloud-auditmanager/setup.py index ce758e6b51b6..6a1b623e55ed 100644 --- a/packages/google-cloud-auditmanager/setup.py +++ b/packages/google-cloud-auditmanager/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/auditmanager/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-auditmanager" diff --git a/packages/google-cloud-auditmanager/testing/constraints-3.10.txt b/packages/google-cloud-auditmanager/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-auditmanager/testing/constraints-3.10.txt +++ b/packages/google-cloud-auditmanager/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-auditmanager/testing/constraints-3.13.txt b/packages/google-cloud-auditmanager/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-auditmanager/testing/constraints-3.13.txt +++ b/packages/google-cloud-auditmanager/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-auditmanager/testing/constraints-3.14.txt b/packages/google-cloud-auditmanager/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-auditmanager/testing/constraints-3.14.txt +++ b/packages/google-cloud-auditmanager/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-automl/google/cloud/automl_v1/__init__.py b/packages/google-cloud-automl/google/cloud/automl_v1/__init__.py index 60d64076048b..9bd10ba234fd 100644 --- a/packages/google-cloud-automl/google/cloud/automl_v1/__init__.py +++ b/packages/google-cloud-automl/google/cloud/automl_v1/__init__.py @@ -159,7 +159,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -188,9 +188,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-automl/google/cloud/automl_v1beta1/__init__.py b/packages/google-cloud-automl/google/cloud/automl_v1beta1/__init__.py index 07baf5afcb7c..0d0a6e9a7000 100644 --- a/packages/google-cloud-automl/google/cloud/automl_v1beta1/__init__.py +++ b/packages/google-cloud-automl/google/cloud/automl_v1beta1/__init__.py @@ -205,7 +205,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -234,9 +234,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-automl/setup.py b/packages/google-cloud-automl/setup.py index fc5d8bfa6429..787260e821b9 100644 --- a/packages/google-cloud-automl/setup.py +++ b/packages/google-cloud-automl/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/automl/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = { "libcst": "libcst >= 0.2.5", diff --git a/packages/google-cloud-automl/testing/constraints-3.10.txt b/packages/google-cloud-automl/testing/constraints-3.10.txt index 81484ad92a64..ffcaae697c9b 100644 --- a/packages/google-cloud-automl/testing/constraints-3.10.txt +++ b/packages/google-cloud-automl/testing/constraints-3.10.txt @@ -4,7 +4,7 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-cloud-storage==2.14.0 libcst==0.2.5 pandas==1.3.4 @@ -12,5 +12,5 @@ pandas==1.3.4 numpy==1.21.3 google-auth==2.23.3 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-automl/testing/constraints-3.13.txt b/packages/google-cloud-automl/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-automl/testing/constraints-3.13.txt +++ b/packages/google-cloud-automl/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-automl/testing/constraints-3.14.txt b/packages/google-cloud-automl/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-automl/testing/constraints-3.14.txt +++ b/packages/google-cloud-automl/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-backupdr/google/cloud/backupdr_v1/__init__.py b/packages/google-cloud-backupdr/google/cloud/backupdr_v1/__init__.py index f8ffecfa2df7..5631aec5a891 100644 --- a/packages/google-cloud-backupdr/google/cloud/backupdr_v1/__init__.py +++ b/packages/google-cloud-backupdr/google/cloud/backupdr_v1/__init__.py @@ -206,7 +206,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -235,9 +235,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-backupdr/setup.py b/packages/google-cloud-backupdr/setup.py index bba6f7d0675e..73280f359103 100644 --- a/packages/google-cloud-backupdr/setup.py +++ b/packages/google-cloud-backupdr/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/backupdr/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-backupdr" diff --git a/packages/google-cloud-backupdr/testing/constraints-3.10.txt b/packages/google-cloud-backupdr/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-backupdr/testing/constraints-3.10.txt +++ b/packages/google-cloud-backupdr/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-backupdr/testing/constraints-3.13.txt b/packages/google-cloud-backupdr/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-backupdr/testing/constraints-3.13.txt +++ b/packages/google-cloud-backupdr/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-backupdr/testing/constraints-3.14.txt b/packages/google-cloud-backupdr/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-backupdr/testing/constraints-3.14.txt +++ b/packages/google-cloud-backupdr/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-bare-metal-solution/google/cloud/bare_metal_solution_v2/__init__.py b/packages/google-cloud-bare-metal-solution/google/cloud/bare_metal_solution_v2/__init__.py index 49106f94510b..cf3ff8755a58 100644 --- a/packages/google-cloud-bare-metal-solution/google/cloud/bare_metal_solution_v2/__init__.py +++ b/packages/google-cloud-bare-metal-solution/google/cloud/bare_metal_solution_v2/__init__.py @@ -148,7 +148,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -177,9 +177,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-bare-metal-solution/setup.py b/packages/google-cloud-bare-metal-solution/setup.py index 06ba1790302e..983d14e9488b 100644 --- a/packages/google-cloud-bare-metal-solution/setup.py +++ b/packages/google-cloud-bare-metal-solution/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/bare_metal_solution/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-bare-metal-solution" diff --git a/packages/google-cloud-bare-metal-solution/testing/constraints-3.10.txt b/packages/google-cloud-bare-metal-solution/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-bare-metal-solution/testing/constraints-3.10.txt +++ b/packages/google-cloud-bare-metal-solution/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-bare-metal-solution/testing/constraints-3.13.txt b/packages/google-cloud-bare-metal-solution/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-bare-metal-solution/testing/constraints-3.13.txt +++ b/packages/google-cloud-bare-metal-solution/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-bare-metal-solution/testing/constraints-3.14.txt b/packages/google-cloud-bare-metal-solution/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-bare-metal-solution/testing/constraints-3.14.txt +++ b/packages/google-cloud-bare-metal-solution/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-batch/google/cloud/batch_v1/__init__.py b/packages/google-cloud-batch/google/cloud/batch_v1/__init__.py index 223bc938260d..80afe12bf729 100644 --- a/packages/google-cloud-batch/google/cloud/batch_v1/__init__.py +++ b/packages/google-cloud-batch/google/cloud/batch_v1/__init__.py @@ -84,7 +84,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -113,9 +113,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-batch/google/cloud/batch_v1alpha/__init__.py b/packages/google-cloud-batch/google/cloud/batch_v1alpha/__init__.py index f0f5ad9b9cdf..cc7c32de6060 100644 --- a/packages/google-cloud-batch/google/cloud/batch_v1alpha/__init__.py +++ b/packages/google-cloud-batch/google/cloud/batch_v1alpha/__init__.py @@ -103,7 +103,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -132,9 +132,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-batch/setup.py b/packages/google-cloud-batch/setup.py index e87950027e82..79cb501263f1 100644 --- a/packages/google-cloud-batch/setup.py +++ b/packages/google-cloud-batch/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/batch/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-batch" diff --git a/packages/google-cloud-batch/testing/constraints-3.10.txt b/packages/google-cloud-batch/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-batch/testing/constraints-3.10.txt +++ b/packages/google-cloud-batch/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-batch/testing/constraints-3.13.txt b/packages/google-cloud-batch/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-batch/testing/constraints-3.13.txt +++ b/packages/google-cloud-batch/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-batch/testing/constraints-3.14.txt b/packages/google-cloud-batch/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-batch/testing/constraints-3.14.txt +++ b/packages/google-cloud-batch/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-beyondcorp-appconnections/google/cloud/beyondcorp_appconnections_v1/__init__.py b/packages/google-cloud-beyondcorp-appconnections/google/cloud/beyondcorp_appconnections_v1/__init__.py index 629262b6deba..2dd0b1f2e9ec 100644 --- a/packages/google-cloud-beyondcorp-appconnections/google/cloud/beyondcorp_appconnections_v1/__init__.py +++ b/packages/google-cloud-beyondcorp-appconnections/google/cloud/beyondcorp_appconnections_v1/__init__.py @@ -65,7 +65,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -94,9 +94,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-beyondcorp-appconnections/setup.py b/packages/google-cloud-beyondcorp-appconnections/setup.py index 9689016c75a5..9b5cfbb2d49e 100644 --- a/packages/google-cloud-beyondcorp-appconnections/setup.py +++ b/packages/google-cloud-beyondcorp-appconnections/setup.py @@ -33,7 +33,10 @@ package_root, "google/cloud/beyondcorp_appconnections/gapic_version.py" ) ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -43,16 +46,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-beyondcorp-appconnections" diff --git a/packages/google-cloud-beyondcorp-appconnections/testing/constraints-3.10.txt b/packages/google-cloud-beyondcorp-appconnections/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-beyondcorp-appconnections/testing/constraints-3.10.txt +++ b/packages/google-cloud-beyondcorp-appconnections/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-beyondcorp-appconnections/testing/constraints-3.13.txt b/packages/google-cloud-beyondcorp-appconnections/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-beyondcorp-appconnections/testing/constraints-3.13.txt +++ b/packages/google-cloud-beyondcorp-appconnections/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-beyondcorp-appconnections/testing/constraints-3.14.txt b/packages/google-cloud-beyondcorp-appconnections/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-beyondcorp-appconnections/testing/constraints-3.14.txt +++ b/packages/google-cloud-beyondcorp-appconnections/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-beyondcorp-appconnectors/google/cloud/beyondcorp_appconnectors_v1/__init__.py b/packages/google-cloud-beyondcorp-appconnectors/google/cloud/beyondcorp_appconnectors_v1/__init__.py index 96cbf5fca0e4..c199a7dbc8a9 100644 --- a/packages/google-cloud-beyondcorp-appconnectors/google/cloud/beyondcorp_appconnectors_v1/__init__.py +++ b/packages/google-cloud-beyondcorp-appconnectors/google/cloud/beyondcorp_appconnectors_v1/__init__.py @@ -70,7 +70,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -99,9 +99,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-beyondcorp-appconnectors/setup.py b/packages/google-cloud-beyondcorp-appconnectors/setup.py index aa8f8581926a..b5bf867d74f5 100644 --- a/packages/google-cloud-beyondcorp-appconnectors/setup.py +++ b/packages/google-cloud-beyondcorp-appconnectors/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/beyondcorp_appconnectors/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-beyondcorp-appconnectors" diff --git a/packages/google-cloud-beyondcorp-appconnectors/testing/constraints-3.10.txt b/packages/google-cloud-beyondcorp-appconnectors/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-beyondcorp-appconnectors/testing/constraints-3.10.txt +++ b/packages/google-cloud-beyondcorp-appconnectors/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-beyondcorp-appconnectors/testing/constraints-3.13.txt b/packages/google-cloud-beyondcorp-appconnectors/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-beyondcorp-appconnectors/testing/constraints-3.13.txt +++ b/packages/google-cloud-beyondcorp-appconnectors/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-beyondcorp-appconnectors/testing/constraints-3.14.txt b/packages/google-cloud-beyondcorp-appconnectors/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-beyondcorp-appconnectors/testing/constraints-3.14.txt +++ b/packages/google-cloud-beyondcorp-appconnectors/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-beyondcorp-appgateways/google/cloud/beyondcorp_appgateways_v1/__init__.py b/packages/google-cloud-beyondcorp-appgateways/google/cloud/beyondcorp_appgateways_v1/__init__.py index 86d0be0285ab..6d3f2b8b5c29 100644 --- a/packages/google-cloud-beyondcorp-appgateways/google/cloud/beyondcorp_appgateways_v1/__init__.py +++ b/packages/google-cloud-beyondcorp-appgateways/google/cloud/beyondcorp_appgateways_v1/__init__.py @@ -62,7 +62,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -91,9 +91,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-beyondcorp-appgateways/setup.py b/packages/google-cloud-beyondcorp-appgateways/setup.py index 3c11fb6f7788..990893ae46e3 100644 --- a/packages/google-cloud-beyondcorp-appgateways/setup.py +++ b/packages/google-cloud-beyondcorp-appgateways/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/beyondcorp_appgateways/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-beyondcorp-appgateways" diff --git a/packages/google-cloud-beyondcorp-appgateways/testing/constraints-3.10.txt b/packages/google-cloud-beyondcorp-appgateways/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-beyondcorp-appgateways/testing/constraints-3.10.txt +++ b/packages/google-cloud-beyondcorp-appgateways/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-beyondcorp-appgateways/testing/constraints-3.13.txt b/packages/google-cloud-beyondcorp-appgateways/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-beyondcorp-appgateways/testing/constraints-3.13.txt +++ b/packages/google-cloud-beyondcorp-appgateways/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-beyondcorp-appgateways/testing/constraints-3.14.txt b/packages/google-cloud-beyondcorp-appgateways/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-beyondcorp-appgateways/testing/constraints-3.14.txt +++ b/packages/google-cloud-beyondcorp-appgateways/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-beyondcorp-clientconnectorservices/google/cloud/beyondcorp_clientconnectorservices_v1/__init__.py b/packages/google-cloud-beyondcorp-clientconnectorservices/google/cloud/beyondcorp_clientconnectorservices_v1/__init__.py index 0662358cd914..3230fcd5aa83 100644 --- a/packages/google-cloud-beyondcorp-clientconnectorservices/google/cloud/beyondcorp_clientconnectorservices_v1/__init__.py +++ b/packages/google-cloud-beyondcorp-clientconnectorservices/google/cloud/beyondcorp_clientconnectorservices_v1/__init__.py @@ -67,7 +67,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -96,9 +96,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-beyondcorp-clientconnectorservices/setup.py b/packages/google-cloud-beyondcorp-clientconnectorservices/setup.py index 8a24bca5f233..343e0184ce38 100644 --- a/packages/google-cloud-beyondcorp-clientconnectorservices/setup.py +++ b/packages/google-cloud-beyondcorp-clientconnectorservices/setup.py @@ -33,7 +33,10 @@ package_root, "google/cloud/beyondcorp_clientconnectorservices/gapic_version.py" ) ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -43,16 +46,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-beyondcorp-clientconnectorservices" diff --git a/packages/google-cloud-beyondcorp-clientconnectorservices/testing/constraints-3.10.txt b/packages/google-cloud-beyondcorp-clientconnectorservices/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-beyondcorp-clientconnectorservices/testing/constraints-3.10.txt +++ b/packages/google-cloud-beyondcorp-clientconnectorservices/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-beyondcorp-clientconnectorservices/testing/constraints-3.13.txt b/packages/google-cloud-beyondcorp-clientconnectorservices/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-beyondcorp-clientconnectorservices/testing/constraints-3.13.txt +++ b/packages/google-cloud-beyondcorp-clientconnectorservices/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-beyondcorp-clientconnectorservices/testing/constraints-3.14.txt b/packages/google-cloud-beyondcorp-clientconnectorservices/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-beyondcorp-clientconnectorservices/testing/constraints-3.14.txt +++ b/packages/google-cloud-beyondcorp-clientconnectorservices/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-beyondcorp-clientgateways/google/cloud/beyondcorp_clientgateways_v1/__init__.py b/packages/google-cloud-beyondcorp-clientgateways/google/cloud/beyondcorp_clientgateways_v1/__init__.py index 43b74bf2a747..2faf507370e0 100644 --- a/packages/google-cloud-beyondcorp-clientgateways/google/cloud/beyondcorp_clientgateways_v1/__init__.py +++ b/packages/google-cloud-beyondcorp-clientgateways/google/cloud/beyondcorp_clientgateways_v1/__init__.py @@ -62,7 +62,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -91,9 +91,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-beyondcorp-clientgateways/setup.py b/packages/google-cloud-beyondcorp-clientgateways/setup.py index 29b091e58ee1..d04f040e7cc4 100644 --- a/packages/google-cloud-beyondcorp-clientgateways/setup.py +++ b/packages/google-cloud-beyondcorp-clientgateways/setup.py @@ -33,7 +33,10 @@ package_root, "google/cloud/beyondcorp_clientgateways/gapic_version.py" ) ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -43,16 +46,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-beyondcorp-clientgateways" diff --git a/packages/google-cloud-beyondcorp-clientgateways/testing/constraints-3.10.txt b/packages/google-cloud-beyondcorp-clientgateways/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-beyondcorp-clientgateways/testing/constraints-3.10.txt +++ b/packages/google-cloud-beyondcorp-clientgateways/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-beyondcorp-clientgateways/testing/constraints-3.13.txt b/packages/google-cloud-beyondcorp-clientgateways/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-beyondcorp-clientgateways/testing/constraints-3.13.txt +++ b/packages/google-cloud-beyondcorp-clientgateways/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-beyondcorp-clientgateways/testing/constraints-3.14.txt b/packages/google-cloud-beyondcorp-clientgateways/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-beyondcorp-clientgateways/testing/constraints-3.14.txt +++ b/packages/google-cloud-beyondcorp-clientgateways/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-biglake-hive/google/cloud/biglake_hive_v1beta/__init__.py b/packages/google-cloud-biglake-hive/google/cloud/biglake_hive_v1beta/__init__.py index 2174fa25184e..1f59c805e65c 100644 --- a/packages/google-cloud-biglake-hive/google/cloud/biglake_hive_v1beta/__init__.py +++ b/packages/google-cloud-biglake-hive/google/cloud/biglake_hive_v1beta/__init__.py @@ -90,7 +90,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -119,9 +119,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-biglake-hive/setup.py b/packages/google-cloud-biglake-hive/setup.py index 552430cb475c..2e3676303c3e 100644 --- a/packages/google-cloud-biglake-hive/setup.py +++ b/packages/google-cloud-biglake-hive/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/biglake_hive/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-biglake-hive" diff --git a/packages/google-cloud-biglake-hive/testing/constraints-3.10.txt b/packages/google-cloud-biglake-hive/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-biglake-hive/testing/constraints-3.10.txt +++ b/packages/google-cloud-biglake-hive/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-biglake-hive/testing/constraints-3.13.txt b/packages/google-cloud-biglake-hive/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-biglake-hive/testing/constraints-3.13.txt +++ b/packages/google-cloud-biglake-hive/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-biglake-hive/testing/constraints-3.14.txt b/packages/google-cloud-biglake-hive/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-biglake-hive/testing/constraints-3.14.txt +++ b/packages/google-cloud-biglake-hive/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-biglake/google/cloud/biglake_v1/__init__.py b/packages/google-cloud-biglake/google/cloud/biglake_v1/__init__.py index fcda198246b7..68d8d4bd3cb7 100644 --- a/packages/google-cloud-biglake/google/cloud/biglake_v1/__init__.py +++ b/packages/google-cloud-biglake/google/cloud/biglake_v1/__init__.py @@ -66,7 +66,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -95,9 +95,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-biglake/setup.py b/packages/google-cloud-biglake/setup.py index c1b3bb4bb6ba..07531e23c47f 100644 --- a/packages/google-cloud-biglake/setup.py +++ b/packages/google-cloud-biglake/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/biglake/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-biglake" diff --git a/packages/google-cloud-biglake/testing/constraints-3.10.txt b/packages/google-cloud-biglake/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-biglake/testing/constraints-3.10.txt +++ b/packages/google-cloud-biglake/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-biglake/testing/constraints-3.13.txt b/packages/google-cloud-biglake/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-biglake/testing/constraints-3.13.txt +++ b/packages/google-cloud-biglake/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-biglake/testing/constraints-3.14.txt b/packages/google-cloud-biglake/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-biglake/testing/constraints-3.14.txt +++ b/packages/google-cloud-biglake/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-bigquery-analyticshub/google/cloud/bigquery_analyticshub_v1/__init__.py b/packages/google-cloud-bigquery-analyticshub/google/cloud/bigquery_analyticshub_v1/__init__.py index 22d699f00625..104a4c928263 100644 --- a/packages/google-cloud-bigquery-analyticshub/google/cloud/bigquery_analyticshub_v1/__init__.py +++ b/packages/google-cloud-bigquery-analyticshub/google/cloud/bigquery_analyticshub_v1/__init__.py @@ -117,7 +117,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -146,9 +146,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-bigquery-analyticshub/setup.py b/packages/google-cloud-bigquery-analyticshub/setup.py index c97c4f9bb548..2c2506ab9dbc 100644 --- a/packages/google-cloud-bigquery-analyticshub/setup.py +++ b/packages/google-cloud-bigquery-analyticshub/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/bigquery_analyticshub/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-bigquery-analyticshub" diff --git a/packages/google-cloud-bigquery-analyticshub/testing/constraints-3.10.txt b/packages/google-cloud-bigquery-analyticshub/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-bigquery-analyticshub/testing/constraints-3.10.txt +++ b/packages/google-cloud-bigquery-analyticshub/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-bigquery-analyticshub/testing/constraints-3.13.txt b/packages/google-cloud-bigquery-analyticshub/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-bigquery-analyticshub/testing/constraints-3.13.txt +++ b/packages/google-cloud-bigquery-analyticshub/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-bigquery-analyticshub/testing/constraints-3.14.txt b/packages/google-cloud-bigquery-analyticshub/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-bigquery-analyticshub/testing/constraints-3.14.txt +++ b/packages/google-cloud-bigquery-analyticshub/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-bigquery-biglake/google/cloud/bigquery_biglake_v1/__init__.py b/packages/google-cloud-bigquery-biglake/google/cloud/bigquery_biglake_v1/__init__.py index 868e17a3ddbc..06279a89a7a8 100644 --- a/packages/google-cloud-bigquery-biglake/google/cloud/bigquery_biglake_v1/__init__.py +++ b/packages/google-cloud-bigquery-biglake/google/cloud/bigquery_biglake_v1/__init__.py @@ -79,7 +79,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -108,9 +108,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-bigquery-biglake/google/cloud/bigquery_biglake_v1alpha1/__init__.py b/packages/google-cloud-bigquery-biglake/google/cloud/bigquery_biglake_v1alpha1/__init__.py index fe7277897a92..e290bcabc1d7 100644 --- a/packages/google-cloud-bigquery-biglake/google/cloud/bigquery_biglake_v1alpha1/__init__.py +++ b/packages/google-cloud-bigquery-biglake/google/cloud/bigquery_biglake_v1alpha1/__init__.py @@ -85,7 +85,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -114,9 +114,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-bigquery-biglake/setup.py b/packages/google-cloud-bigquery-biglake/setup.py index 7d62c606c564..533cf287e093 100644 --- a/packages/google-cloud-bigquery-biglake/setup.py +++ b/packages/google-cloud-bigquery-biglake/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/bigquery_biglake/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-bigquery-biglake" diff --git a/packages/google-cloud-bigquery-biglake/testing/constraints-3.10.txt b/packages/google-cloud-bigquery-biglake/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-bigquery-biglake/testing/constraints-3.10.txt +++ b/packages/google-cloud-bigquery-biglake/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-bigquery-biglake/testing/constraints-3.13.txt b/packages/google-cloud-bigquery-biglake/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-bigquery-biglake/testing/constraints-3.13.txt +++ b/packages/google-cloud-bigquery-biglake/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-bigquery-biglake/testing/constraints-3.14.txt b/packages/google-cloud-bigquery-biglake/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-bigquery-biglake/testing/constraints-3.14.txt +++ b/packages/google-cloud-bigquery-biglake/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-bigquery-connection/google/cloud/bigquery_connection_v1/__init__.py b/packages/google-cloud-bigquery-connection/google/cloud/bigquery_connection_v1/__init__.py index 76600994b646..73bcafc38912 100644 --- a/packages/google-cloud-bigquery-connection/google/cloud/bigquery_connection_v1/__init__.py +++ b/packages/google-cloud-bigquery-connection/google/cloud/bigquery_connection_v1/__init__.py @@ -74,7 +74,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -103,9 +103,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-bigquery-connection/setup.py b/packages/google-cloud-bigquery-connection/setup.py index 9515d7a90b2e..fb0b40ee9d77 100644 --- a/packages/google-cloud-bigquery-connection/setup.py +++ b/packages/google-cloud-bigquery-connection/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/bigquery_connection/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-bigquery-connection" diff --git a/packages/google-cloud-bigquery-connection/testing/constraints-3.10.txt b/packages/google-cloud-bigquery-connection/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-bigquery-connection/testing/constraints-3.10.txt +++ b/packages/google-cloud-bigquery-connection/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-bigquery-connection/testing/constraints-3.13.txt b/packages/google-cloud-bigquery-connection/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-bigquery-connection/testing/constraints-3.13.txt +++ b/packages/google-cloud-bigquery-connection/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-bigquery-connection/testing/constraints-3.14.txt b/packages/google-cloud-bigquery-connection/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-bigquery-connection/testing/constraints-3.14.txt +++ b/packages/google-cloud-bigquery-connection/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-bigquery-data-exchange/google/cloud/bigquery_data_exchange_v1beta1/__init__.py b/packages/google-cloud-bigquery-data-exchange/google/cloud/bigquery_data_exchange_v1beta1/__init__.py index 319a13eba22b..194e49cf0eae 100644 --- a/packages/google-cloud-bigquery-data-exchange/google/cloud/bigquery_data_exchange_v1beta1/__init__.py +++ b/packages/google-cloud-bigquery-data-exchange/google/cloud/bigquery_data_exchange_v1beta1/__init__.py @@ -77,7 +77,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -106,9 +106,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-bigquery-data-exchange/setup.py b/packages/google-cloud-bigquery-data-exchange/setup.py index 709a469cfe64..3b7259d55234 100644 --- a/packages/google-cloud-bigquery-data-exchange/setup.py +++ b/packages/google-cloud-bigquery-data-exchange/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/bigquery_data_exchange/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-bigquery-data-exchange" diff --git a/packages/google-cloud-bigquery-data-exchange/testing/constraints-3.10.txt b/packages/google-cloud-bigquery-data-exchange/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-bigquery-data-exchange/testing/constraints-3.10.txt +++ b/packages/google-cloud-bigquery-data-exchange/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-bigquery-data-exchange/testing/constraints-3.13.txt b/packages/google-cloud-bigquery-data-exchange/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-bigquery-data-exchange/testing/constraints-3.13.txt +++ b/packages/google-cloud-bigquery-data-exchange/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-bigquery-data-exchange/testing/constraints-3.14.txt b/packages/google-cloud-bigquery-data-exchange/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-bigquery-data-exchange/testing/constraints-3.14.txt +++ b/packages/google-cloud-bigquery-data-exchange/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-bigquery-datapolicies/google/cloud/bigquery_datapolicies_v1/__init__.py b/packages/google-cloud-bigquery-datapolicies/google/cloud/bigquery_datapolicies_v1/__init__.py index 0e075f23a66c..1d64d26cd017 100644 --- a/packages/google-cloud-bigquery-datapolicies/google/cloud/bigquery_datapolicies_v1/__init__.py +++ b/packages/google-cloud-bigquery-datapolicies/google/cloud/bigquery_datapolicies_v1/__init__.py @@ -64,7 +64,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -93,9 +93,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-bigquery-datapolicies/google/cloud/bigquery_datapolicies_v1beta1/__init__.py b/packages/google-cloud-bigquery-datapolicies/google/cloud/bigquery_datapolicies_v1beta1/__init__.py index 82c1e6a21a95..ebbef5466a5d 100644 --- a/packages/google-cloud-bigquery-datapolicies/google/cloud/bigquery_datapolicies_v1beta1/__init__.py +++ b/packages/google-cloud-bigquery-datapolicies/google/cloud/bigquery_datapolicies_v1beta1/__init__.py @@ -63,7 +63,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -92,9 +92,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-bigquery-datapolicies/google/cloud/bigquery_datapolicies_v2/__init__.py b/packages/google-cloud-bigquery-datapolicies/google/cloud/bigquery_datapolicies_v2/__init__.py index 91f8a486274b..c3c1ffc649de 100644 --- a/packages/google-cloud-bigquery-datapolicies/google/cloud/bigquery_datapolicies_v2/__init__.py +++ b/packages/google-cloud-bigquery-datapolicies/google/cloud/bigquery_datapolicies_v2/__init__.py @@ -65,7 +65,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -94,9 +94,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-bigquery-datapolicies/google/cloud/bigquery_datapolicies_v2beta1/__init__.py b/packages/google-cloud-bigquery-datapolicies/google/cloud/bigquery_datapolicies_v2beta1/__init__.py index 76a08102cb7d..c1bf00714422 100644 --- a/packages/google-cloud-bigquery-datapolicies/google/cloud/bigquery_datapolicies_v2beta1/__init__.py +++ b/packages/google-cloud-bigquery-datapolicies/google/cloud/bigquery_datapolicies_v2beta1/__init__.py @@ -65,7 +65,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -94,9 +94,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-bigquery-datapolicies/setup.py b/packages/google-cloud-bigquery-datapolicies/setup.py index 6e5251e5523c..aafbb6248fcb 100644 --- a/packages/google-cloud-bigquery-datapolicies/setup.py +++ b/packages/google-cloud-bigquery-datapolicies/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/bigquery_datapolicies/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-bigquery-datapolicies" diff --git a/packages/google-cloud-bigquery-datapolicies/testing/constraints-3.10.txt b/packages/google-cloud-bigquery-datapolicies/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-bigquery-datapolicies/testing/constraints-3.10.txt +++ b/packages/google-cloud-bigquery-datapolicies/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-bigquery-datapolicies/testing/constraints-3.13.txt b/packages/google-cloud-bigquery-datapolicies/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-bigquery-datapolicies/testing/constraints-3.13.txt +++ b/packages/google-cloud-bigquery-datapolicies/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-bigquery-datapolicies/testing/constraints-3.14.txt b/packages/google-cloud-bigquery-datapolicies/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-bigquery-datapolicies/testing/constraints-3.14.txt +++ b/packages/google-cloud-bigquery-datapolicies/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-bigquery-datatransfer/google/cloud/bigquery_datatransfer_v1/__init__.py b/packages/google-cloud-bigquery-datatransfer/google/cloud/bigquery_datatransfer_v1/__init__.py index 028ec25eba72..b95aed28cf35 100644 --- a/packages/google-cloud-bigquery-datatransfer/google/cloud/bigquery_datatransfer_v1/__init__.py +++ b/packages/google-cloud-bigquery-datatransfer/google/cloud/bigquery_datatransfer_v1/__init__.py @@ -95,7 +95,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -124,9 +124,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-bigquery-datatransfer/setup.py b/packages/google-cloud-bigquery-datatransfer/setup.py index afeab9dee42b..55f1c624bd1f 100644 --- a/packages/google-cloud-bigquery-datatransfer/setup.py +++ b/packages/google-cloud-bigquery-datatransfer/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/bigquery_datatransfer/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-bigquery-datatransfer" diff --git a/packages/google-cloud-bigquery-datatransfer/testing/constraints-3.10.txt b/packages/google-cloud-bigquery-datatransfer/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-bigquery-datatransfer/testing/constraints-3.10.txt +++ b/packages/google-cloud-bigquery-datatransfer/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-bigquery-datatransfer/testing/constraints-3.13.txt b/packages/google-cloud-bigquery-datatransfer/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-bigquery-datatransfer/testing/constraints-3.13.txt +++ b/packages/google-cloud-bigquery-datatransfer/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-bigquery-datatransfer/testing/constraints-3.14.txt b/packages/google-cloud-bigquery-datatransfer/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-bigquery-datatransfer/testing/constraints-3.14.txt +++ b/packages/google-cloud-bigquery-datatransfer/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-bigquery-logging/google/cloud/bigquery_logging_v1/__init__.py b/packages/google-cloud-bigquery-logging/google/cloud/bigquery_logging_v1/__init__.py index adc721a8f93f..99908d1b8e90 100644 --- a/packages/google-cloud-bigquery-logging/google/cloud/bigquery_logging_v1/__init__.py +++ b/packages/google-cloud-bigquery-logging/google/cloud/bigquery_logging_v1/__init__.py @@ -86,7 +86,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -115,9 +115,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-bigquery-logging/setup.py b/packages/google-cloud-bigquery-logging/setup.py index ff79919fb839..7f3894065115 100644 --- a/packages/google-cloud-bigquery-logging/setup.py +++ b/packages/google-cloud-bigquery-logging/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/bigquery_logging/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-bigquery-logging" diff --git a/packages/google-cloud-bigquery-logging/testing/constraints-3.10.txt b/packages/google-cloud-bigquery-logging/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-bigquery-logging/testing/constraints-3.10.txt +++ b/packages/google-cloud-bigquery-logging/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-bigquery-logging/testing/constraints-3.13.txt b/packages/google-cloud-bigquery-logging/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-bigquery-logging/testing/constraints-3.13.txt +++ b/packages/google-cloud-bigquery-logging/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-bigquery-logging/testing/constraints-3.14.txt b/packages/google-cloud-bigquery-logging/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-bigquery-logging/testing/constraints-3.14.txt +++ b/packages/google-cloud-bigquery-logging/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-bigquery-migration/google/cloud/bigquery_migration_v2/__init__.py b/packages/google-cloud-bigquery-migration/google/cloud/bigquery_migration_v2/__init__.py index e634458e23ef..bb2ead57e0c9 100644 --- a/packages/google-cloud-bigquery-migration/google/cloud/bigquery_migration_v2/__init__.py +++ b/packages/google-cloud-bigquery-migration/google/cloud/bigquery_migration_v2/__init__.py @@ -116,7 +116,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -145,9 +145,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-bigquery-migration/google/cloud/bigquery_migration_v2alpha/__init__.py b/packages/google-cloud-bigquery-migration/google/cloud/bigquery_migration_v2alpha/__init__.py index 916f7fc5cb34..c2625d45a95a 100644 --- a/packages/google-cloud-bigquery-migration/google/cloud/bigquery_migration_v2alpha/__init__.py +++ b/packages/google-cloud-bigquery-migration/google/cloud/bigquery_migration_v2alpha/__init__.py @@ -100,7 +100,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -129,9 +129,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-bigquery-migration/setup.py b/packages/google-cloud-bigquery-migration/setup.py index 0ff1ca1557b4..ae821f3100c2 100644 --- a/packages/google-cloud-bigquery-migration/setup.py +++ b/packages/google-cloud-bigquery-migration/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/bigquery_migration/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-bigquery-migration" diff --git a/packages/google-cloud-bigquery-migration/testing/constraints-3.10.txt b/packages/google-cloud-bigquery-migration/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-bigquery-migration/testing/constraints-3.10.txt +++ b/packages/google-cloud-bigquery-migration/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-bigquery-migration/testing/constraints-3.13.txt b/packages/google-cloud-bigquery-migration/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-bigquery-migration/testing/constraints-3.13.txt +++ b/packages/google-cloud-bigquery-migration/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-bigquery-migration/testing/constraints-3.14.txt b/packages/google-cloud-bigquery-migration/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-bigquery-migration/testing/constraints-3.14.txt +++ b/packages/google-cloud-bigquery-migration/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-bigquery-reservation/google/cloud/bigquery_reservation_v1/__init__.py b/packages/google-cloud-bigquery-reservation/google/cloud/bigquery_reservation_v1/__init__.py index b10ed1d34990..da3978b93cb8 100644 --- a/packages/google-cloud-bigquery-reservation/google/cloud/bigquery_reservation_v1/__init__.py +++ b/packages/google-cloud-bigquery-reservation/google/cloud/bigquery_reservation_v1/__init__.py @@ -97,7 +97,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -126,9 +126,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-bigquery-reservation/setup.py b/packages/google-cloud-bigquery-reservation/setup.py index 07e6eba134b7..aca1403c128b 100644 --- a/packages/google-cloud-bigquery-reservation/setup.py +++ b/packages/google-cloud-bigquery-reservation/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/bigquery_reservation/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-bigquery-reservation" diff --git a/packages/google-cloud-bigquery-reservation/testing/constraints-3.10.txt b/packages/google-cloud-bigquery-reservation/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-bigquery-reservation/testing/constraints-3.10.txt +++ b/packages/google-cloud-bigquery-reservation/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-bigquery-reservation/testing/constraints-3.13.txt b/packages/google-cloud-bigquery-reservation/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-bigquery-reservation/testing/constraints-3.13.txt +++ b/packages/google-cloud-bigquery-reservation/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-bigquery-reservation/testing/constraints-3.14.txt b/packages/google-cloud-bigquery-reservation/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-bigquery-reservation/testing/constraints-3.14.txt +++ b/packages/google-cloud-bigquery-reservation/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-bigquery-storage/google/cloud/bigquery_storage_v1/__init__.py b/packages/google-cloud-bigquery-storage/google/cloud/bigquery_storage_v1/__init__.py index fd0d8451304d..2ab62f3a4b43 100644 --- a/packages/google-cloud-bigquery-storage/google/cloud/bigquery_storage_v1/__init__.py +++ b/packages/google-cloud-bigquery-storage/google/cloud/bigquery_storage_v1/__init__.py @@ -59,7 +59,7 @@ class BigQueryWriteClient(client.BigQueryWriteClient): def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -88,9 +88,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-bigquery-storage/google/cloud/bigquery_storage_v1alpha/__init__.py b/packages/google-cloud-bigquery-storage/google/cloud/bigquery_storage_v1alpha/__init__.py index 5177548b5b5d..cf2821bc5802 100644 --- a/packages/google-cloud-bigquery-storage/google/cloud/bigquery_storage_v1alpha/__init__.py +++ b/packages/google-cloud-bigquery-storage/google/cloud/bigquery_storage_v1alpha/__init__.py @@ -48,7 +48,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -77,9 +77,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-bigquery-storage/google/cloud/bigquery_storage_v1beta/__init__.py b/packages/google-cloud-bigquery-storage/google/cloud/bigquery_storage_v1beta/__init__.py index 091cf62a94b8..4e21546e3ef0 100644 --- a/packages/google-cloud-bigquery-storage/google/cloud/bigquery_storage_v1beta/__init__.py +++ b/packages/google-cloud-bigquery-storage/google/cloud/bigquery_storage_v1beta/__init__.py @@ -48,7 +48,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -77,9 +77,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-bigquery-storage/google/cloud/bigquery_storage_v1beta2/__init__.py b/packages/google-cloud-bigquery-storage/google/cloud/bigquery_storage_v1beta2/__init__.py index 3494348486a5..3c664286d38e 100644 --- a/packages/google-cloud-bigquery-storage/google/cloud/bigquery_storage_v1beta2/__init__.py +++ b/packages/google-cloud-bigquery-storage/google/cloud/bigquery_storage_v1beta2/__init__.py @@ -59,7 +59,7 @@ class BigQueryWriteClient(client.BigQueryWriteClient): def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -88,9 +88,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-bigquery-storage/setup.py b/packages/google-cloud-bigquery-storage/setup.py index d3a6bc437845..3d2404674227 100644 --- a/packages/google-cloud-bigquery-storage/setup.py +++ b/packages/google-cloud-bigquery-storage/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/bigquery_storage/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = { "pandas": ["pandas>=1.1.3"], diff --git a/packages/google-cloud-bigquery-storage/testing/constraints-3.10.txt b/packages/google-cloud-bigquery-storage/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-bigquery-storage/testing/constraints-3.10.txt +++ b/packages/google-cloud-bigquery-storage/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-bigquery-storage/testing/constraints-3.13.txt b/packages/google-cloud-bigquery-storage/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-bigquery-storage/testing/constraints-3.13.txt +++ b/packages/google-cloud-bigquery-storage/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-bigquery-storage/testing/constraints-3.14.txt b/packages/google-cloud-bigquery-storage/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-bigquery-storage/testing/constraints-3.14.txt +++ b/packages/google-cloud-bigquery-storage/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-billing-budgets/google/cloud/billing/budgets_v1/__init__.py b/packages/google-cloud-billing-budgets/google/cloud/billing/budgets_v1/__init__.py index f9ab3b68b711..471698a911a6 100644 --- a/packages/google-cloud-billing-budgets/google/cloud/billing/budgets_v1/__init__.py +++ b/packages/google-cloud-billing-budgets/google/cloud/billing/budgets_v1/__init__.py @@ -68,7 +68,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -97,9 +97,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-billing-budgets/google/cloud/billing/budgets_v1beta1/__init__.py b/packages/google-cloud-billing-budgets/google/cloud/billing/budgets_v1beta1/__init__.py index 21ded9065bf7..ac885e34439d 100644 --- a/packages/google-cloud-billing-budgets/google/cloud/billing/budgets_v1beta1/__init__.py +++ b/packages/google-cloud-billing-budgets/google/cloud/billing/budgets_v1beta1/__init__.py @@ -68,7 +68,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -97,9 +97,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-billing-budgets/setup.py b/packages/google-cloud-billing-budgets/setup.py index eda177d690aa..0ecb58ba1c54 100644 --- a/packages/google-cloud-billing-budgets/setup.py +++ b/packages/google-cloud-billing-budgets/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/billing/budgets/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-billing-budgets" diff --git a/packages/google-cloud-billing-budgets/testing/constraints-3.10.txt b/packages/google-cloud-billing-budgets/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-billing-budgets/testing/constraints-3.10.txt +++ b/packages/google-cloud-billing-budgets/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-billing-budgets/testing/constraints-3.13.txt b/packages/google-cloud-billing-budgets/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-billing-budgets/testing/constraints-3.13.txt +++ b/packages/google-cloud-billing-budgets/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-billing-budgets/testing/constraints-3.14.txt b/packages/google-cloud-billing-budgets/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-billing-budgets/testing/constraints-3.14.txt +++ b/packages/google-cloud-billing-budgets/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-billing/google/cloud/billing_v1/__init__.py b/packages/google-cloud-billing/google/cloud/billing_v1/__init__.py index c3d2c0430d10..17e1f4a99e55 100644 --- a/packages/google-cloud-billing/google/cloud/billing_v1/__init__.py +++ b/packages/google-cloud-billing/google/cloud/billing_v1/__init__.py @@ -78,7 +78,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -107,9 +107,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-billing/setup.py b/packages/google-cloud-billing/setup.py index d09922705fe2..f0e2f3767a48 100644 --- a/packages/google-cloud-billing/setup.py +++ b/packages/google-cloud-billing/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/billing/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-billing" diff --git a/packages/google-cloud-billing/testing/constraints-3.10.txt b/packages/google-cloud-billing/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-billing/testing/constraints-3.10.txt +++ b/packages/google-cloud-billing/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-billing/testing/constraints-3.13.txt b/packages/google-cloud-billing/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-billing/testing/constraints-3.13.txt +++ b/packages/google-cloud-billing/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-billing/testing/constraints-3.14.txt b/packages/google-cloud-billing/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-billing/testing/constraints-3.14.txt +++ b/packages/google-cloud-billing/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-binary-authorization/google/cloud/binaryauthorization_v1/__init__.py b/packages/google-cloud-binary-authorization/google/cloud/binaryauthorization_v1/__init__.py index 6b920a1440de..0ac101a280a7 100644 --- a/packages/google-cloud-binary-authorization/google/cloud/binaryauthorization_v1/__init__.py +++ b/packages/google-cloud-binary-authorization/google/cloud/binaryauthorization_v1/__init__.py @@ -80,7 +80,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -109,9 +109,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-binary-authorization/google/cloud/binaryauthorization_v1beta1/__init__.py b/packages/google-cloud-binary-authorization/google/cloud/binaryauthorization_v1beta1/__init__.py index 9bcc90d114ab..d3218378af6a 100644 --- a/packages/google-cloud-binary-authorization/google/cloud/binaryauthorization_v1beta1/__init__.py +++ b/packages/google-cloud-binary-authorization/google/cloud/binaryauthorization_v1beta1/__init__.py @@ -78,7 +78,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -107,9 +107,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-binary-authorization/setup.py b/packages/google-cloud-binary-authorization/setup.py index 801bbc527e32..32fab06a13ff 100644 --- a/packages/google-cloud-binary-authorization/setup.py +++ b/packages/google-cloud-binary-authorization/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/binaryauthorization/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grafeas >= 1.7.0, <2.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-binary-authorization" diff --git a/packages/google-cloud-binary-authorization/testing/constraints-3.10.txt b/packages/google-cloud-binary-authorization/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-binary-authorization/testing/constraints-3.10.txt +++ b/packages/google-cloud-binary-authorization/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-binary-authorization/testing/constraints-3.13.txt b/packages/google-cloud-binary-authorization/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-binary-authorization/testing/constraints-3.13.txt +++ b/packages/google-cloud-binary-authorization/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-binary-authorization/testing/constraints-3.14.txt b/packages/google-cloud-binary-authorization/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-binary-authorization/testing/constraints-3.14.txt +++ b/packages/google-cloud-binary-authorization/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-build/google/cloud/devtools/cloudbuild_v1/__init__.py b/packages/google-cloud-build/google/cloud/devtools/cloudbuild_v1/__init__.py index 901fe97b93bd..93671c66be5a 100644 --- a/packages/google-cloud-build/google/cloud/devtools/cloudbuild_v1/__init__.py +++ b/packages/google-cloud-build/google/cloud/devtools/cloudbuild_v1/__init__.py @@ -124,7 +124,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -153,9 +153,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-build/google/cloud/devtools/cloudbuild_v2/__init__.py b/packages/google-cloud-build/google/cloud/devtools/cloudbuild_v2/__init__.py index 3433054f6bb0..44784edba1b8 100644 --- a/packages/google-cloud-build/google/cloud/devtools/cloudbuild_v2/__init__.py +++ b/packages/google-cloud-build/google/cloud/devtools/cloudbuild_v2/__init__.py @@ -89,7 +89,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -118,9 +118,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-build/setup.py b/packages/google-cloud-build/setup.py index 103e6bbcc6f5..2bffbea45a43 100644 --- a/packages/google-cloud-build/setup.py +++ b/packages/google-cloud-build/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/devtools/cloudbuild/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpc-google-iam-v1 >=0.12.4, <1.0.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-build" diff --git a/packages/google-cloud-build/testing/constraints-3.10.txt b/packages/google-cloud-build/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-build/testing/constraints-3.10.txt +++ b/packages/google-cloud-build/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-build/testing/constraints-3.13.txt b/packages/google-cloud-build/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-build/testing/constraints-3.13.txt +++ b/packages/google-cloud-build/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-build/testing/constraints-3.14.txt b/packages/google-cloud-build/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-build/testing/constraints-3.14.txt +++ b/packages/google-cloud-build/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-capacityplanner/google/cloud/capacityplanner_v1beta/__init__.py b/packages/google-cloud-capacityplanner/google/cloud/capacityplanner_v1beta/__init__.py index d3efe8335f9f..c11e99fb4a28 100644 --- a/packages/google-cloud-capacityplanner/google/cloud/capacityplanner_v1beta/__init__.py +++ b/packages/google-cloud-capacityplanner/google/cloud/capacityplanner_v1beta/__init__.py @@ -86,7 +86,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -115,9 +115,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-capacityplanner/setup.py b/packages/google-cloud-capacityplanner/setup.py index cf377b7839a8..0ff374547dd4 100644 --- a/packages/google-cloud-capacityplanner/setup.py +++ b/packages/google-cloud-capacityplanner/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/capacityplanner/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-capacityplanner" diff --git a/packages/google-cloud-capacityplanner/testing/constraints-3.10.txt b/packages/google-cloud-capacityplanner/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-capacityplanner/testing/constraints-3.10.txt +++ b/packages/google-cloud-capacityplanner/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-capacityplanner/testing/constraints-3.13.txt b/packages/google-cloud-capacityplanner/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-capacityplanner/testing/constraints-3.13.txt +++ b/packages/google-cloud-capacityplanner/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-capacityplanner/testing/constraints-3.14.txt b/packages/google-cloud-capacityplanner/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-capacityplanner/testing/constraints-3.14.txt +++ b/packages/google-cloud-capacityplanner/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-certificate-manager/google/cloud/certificate_manager_v1/__init__.py b/packages/google-cloud-certificate-manager/google/cloud/certificate_manager_v1/__init__.py index a278a76c1c7e..70491d02d234 100644 --- a/packages/google-cloud-certificate-manager/google/cloud/certificate_manager_v1/__init__.py +++ b/packages/google-cloud-certificate-manager/google/cloud/certificate_manager_v1/__init__.py @@ -102,7 +102,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -131,9 +131,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-certificate-manager/setup.py b/packages/google-cloud-certificate-manager/setup.py index e3e6d2d628db..17f20bf48168 100644 --- a/packages/google-cloud-certificate-manager/setup.py +++ b/packages/google-cloud-certificate-manager/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/certificate_manager/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-certificate-manager" diff --git a/packages/google-cloud-certificate-manager/testing/constraints-3.10.txt b/packages/google-cloud-certificate-manager/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-certificate-manager/testing/constraints-3.10.txt +++ b/packages/google-cloud-certificate-manager/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-certificate-manager/testing/constraints-3.13.txt b/packages/google-cloud-certificate-manager/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-certificate-manager/testing/constraints-3.13.txt +++ b/packages/google-cloud-certificate-manager/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-certificate-manager/testing/constraints-3.14.txt b/packages/google-cloud-certificate-manager/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-certificate-manager/testing/constraints-3.14.txt +++ b/packages/google-cloud-certificate-manager/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-ces/google/cloud/ces_v1/__init__.py b/packages/google-cloud-ces/google/cloud/ces_v1/__init__.py index eaf1b8b99f6b..0cf94f276d46 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1/__init__.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1/__init__.py @@ -231,7 +231,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -260,9 +260,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/__init__.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/__init__.py index 481866dfbb65..a1e1f7c5b676 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/__init__.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/__init__.py @@ -323,7 +323,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -352,9 +352,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-ces/setup.py b/packages/google-cloud-ces/setup.py index c0021061dc76..ae05fd05f157 100644 --- a/packages/google-cloud-ces/setup.py +++ b/packages/google-cloud-ces/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/ces/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-ces" diff --git a/packages/google-cloud-ces/testing/constraints-3.10.txt b/packages/google-cloud-ces/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-ces/testing/constraints-3.10.txt +++ b/packages/google-cloud-ces/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-ces/testing/constraints-3.13.txt b/packages/google-cloud-ces/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-ces/testing/constraints-3.13.txt +++ b/packages/google-cloud-ces/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-ces/testing/constraints-3.14.txt b/packages/google-cloud-ces/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-ces/testing/constraints-3.14.txt +++ b/packages/google-cloud-ces/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-channel/google/cloud/channel_v1/__init__.py b/packages/google-cloud-channel/google/cloud/channel_v1/__init__.py index ce16ca721c7b..2e4febbe9be0 100644 --- a/packages/google-cloud-channel/google/cloud/channel_v1/__init__.py +++ b/packages/google-cloud-channel/google/cloud/channel_v1/__init__.py @@ -206,7 +206,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -235,9 +235,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-channel/setup.py b/packages/google-cloud-channel/setup.py index 9e84aea01f00..1afbcbfe20c7 100644 --- a/packages/google-cloud-channel/setup.py +++ b/packages/google-cloud-channel/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/channel/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-channel" diff --git a/packages/google-cloud-channel/testing/constraints-3.10.txt b/packages/google-cloud-channel/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-channel/testing/constraints-3.10.txt +++ b/packages/google-cloud-channel/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-channel/testing/constraints-3.13.txt b/packages/google-cloud-channel/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-channel/testing/constraints-3.13.txt +++ b/packages/google-cloud-channel/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-channel/testing/constraints-3.14.txt b/packages/google-cloud-channel/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-channel/testing/constraints-3.14.txt +++ b/packages/google-cloud-channel/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/__init__.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/__init__.py index 8071d407990a..8f93142f2184 100644 --- a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/__init__.py +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/__init__.py @@ -272,7 +272,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -301,9 +301,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-chronicle/setup.py b/packages/google-cloud-chronicle/setup.py index 238ccb8ccf34..3f2b220e1ab8 100644 --- a/packages/google-cloud-chronicle/setup.py +++ b/packages/google-cloud-chronicle/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/chronicle/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-chronicle" diff --git a/packages/google-cloud-chronicle/testing/constraints-3.10.txt b/packages/google-cloud-chronicle/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-chronicle/testing/constraints-3.10.txt +++ b/packages/google-cloud-chronicle/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-chronicle/testing/constraints-3.13.txt b/packages/google-cloud-chronicle/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-chronicle/testing/constraints-3.13.txt +++ b/packages/google-cloud-chronicle/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-chronicle/testing/constraints-3.14.txt b/packages/google-cloud-chronicle/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-chronicle/testing/constraints-3.14.txt +++ b/packages/google-cloud-chronicle/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-cloudcontrolspartner/google/cloud/cloudcontrolspartner_v1/__init__.py b/packages/google-cloud-cloudcontrolspartner/google/cloud/cloudcontrolspartner_v1/__init__.py index 4e6790a72b2b..c74ef86bb85b 100644 --- a/packages/google-cloud-cloudcontrolspartner/google/cloud/cloudcontrolspartner_v1/__init__.py +++ b/packages/google-cloud-cloudcontrolspartner/google/cloud/cloudcontrolspartner_v1/__init__.py @@ -97,7 +97,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -126,9 +126,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-cloudcontrolspartner/google/cloud/cloudcontrolspartner_v1beta/__init__.py b/packages/google-cloud-cloudcontrolspartner/google/cloud/cloudcontrolspartner_v1beta/__init__.py index 8590404f6d30..d6d3909103ab 100644 --- a/packages/google-cloud-cloudcontrolspartner/google/cloud/cloudcontrolspartner_v1beta/__init__.py +++ b/packages/google-cloud-cloudcontrolspartner/google/cloud/cloudcontrolspartner_v1beta/__init__.py @@ -97,7 +97,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -126,9 +126,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-cloudcontrolspartner/setup.py b/packages/google-cloud-cloudcontrolspartner/setup.py index 72d0d864e14f..9392a65c36b8 100644 --- a/packages/google-cloud-cloudcontrolspartner/setup.py +++ b/packages/google-cloud-cloudcontrolspartner/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/cloudcontrolspartner/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-cloudcontrolspartner" diff --git a/packages/google-cloud-cloudcontrolspartner/testing/constraints-3.10.txt b/packages/google-cloud-cloudcontrolspartner/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-cloudcontrolspartner/testing/constraints-3.10.txt +++ b/packages/google-cloud-cloudcontrolspartner/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-cloudcontrolspartner/testing/constraints-3.13.txt b/packages/google-cloud-cloudcontrolspartner/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-cloudcontrolspartner/testing/constraints-3.13.txt +++ b/packages/google-cloud-cloudcontrolspartner/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-cloudcontrolspartner/testing/constraints-3.14.txt b/packages/google-cloud-cloudcontrolspartner/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-cloudcontrolspartner/testing/constraints-3.14.txt +++ b/packages/google-cloud-cloudcontrolspartner/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/__init__.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/__init__.py index c465e2600544..22965128f440 100644 --- a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/__init__.py +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/__init__.py @@ -172,7 +172,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -201,9 +201,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-cloudsecuritycompliance/setup.py b/packages/google-cloud-cloudsecuritycompliance/setup.py index 4ed3b0065cf7..89a604ff4594 100644 --- a/packages/google-cloud-cloudsecuritycompliance/setup.py +++ b/packages/google-cloud-cloudsecuritycompliance/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/cloudsecuritycompliance/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-cloudsecuritycompliance" diff --git a/packages/google-cloud-cloudsecuritycompliance/testing/constraints-3.10.txt b/packages/google-cloud-cloudsecuritycompliance/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-cloudsecuritycompliance/testing/constraints-3.10.txt +++ b/packages/google-cloud-cloudsecuritycompliance/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-cloudsecuritycompliance/testing/constraints-3.13.txt b/packages/google-cloud-cloudsecuritycompliance/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-cloudsecuritycompliance/testing/constraints-3.13.txt +++ b/packages/google-cloud-cloudsecuritycompliance/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-cloudsecuritycompliance/testing/constraints-3.14.txt b/packages/google-cloud-cloudsecuritycompliance/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-cloudsecuritycompliance/testing/constraints-3.14.txt +++ b/packages/google-cloud-cloudsecuritycompliance/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-commerce-consumer-procurement/google/cloud/commerce_consumer_procurement_v1/__init__.py b/packages/google-cloud-commerce-consumer-procurement/google/cloud/commerce_consumer_procurement_v1/__init__.py index 8c4c417007ba..d2481ac5e736 100644 --- a/packages/google-cloud-commerce-consumer-procurement/google/cloud/commerce_consumer_procurement_v1/__init__.py +++ b/packages/google-cloud-commerce-consumer-procurement/google/cloud/commerce_consumer_procurement_v1/__init__.py @@ -95,7 +95,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -124,9 +124,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-commerce-consumer-procurement/google/cloud/commerce_consumer_procurement_v1alpha1/__init__.py b/packages/google-cloud-commerce-consumer-procurement/google/cloud/commerce_consumer_procurement_v1alpha1/__init__.py index 6b270a80f0cb..6803c631478d 100644 --- a/packages/google-cloud-commerce-consumer-procurement/google/cloud/commerce_consumer_procurement_v1alpha1/__init__.py +++ b/packages/google-cloud-commerce-consumer-procurement/google/cloud/commerce_consumer_procurement_v1alpha1/__init__.py @@ -75,7 +75,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -104,9 +104,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-commerce-consumer-procurement/setup.py b/packages/google-cloud-commerce-consumer-procurement/setup.py index c4dca6e9f508..56051acd776b 100644 --- a/packages/google-cloud-commerce-consumer-procurement/setup.py +++ b/packages/google-cloud-commerce-consumer-procurement/setup.py @@ -33,7 +33,10 @@ package_root, "google/cloud/commerce_consumer_procurement/gapic_version.py" ) ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -43,15 +46,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-commerce-consumer-procurement" diff --git a/packages/google-cloud-commerce-consumer-procurement/testing/constraints-3.10.txt b/packages/google-cloud-commerce-consumer-procurement/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-commerce-consumer-procurement/testing/constraints-3.10.txt +++ b/packages/google-cloud-commerce-consumer-procurement/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-commerce-consumer-procurement/testing/constraints-3.13.txt b/packages/google-cloud-commerce-consumer-procurement/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-commerce-consumer-procurement/testing/constraints-3.13.txt +++ b/packages/google-cloud-commerce-consumer-procurement/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-commerce-consumer-procurement/testing/constraints-3.14.txt b/packages/google-cloud-commerce-consumer-procurement/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-commerce-consumer-procurement/testing/constraints-3.14.txt +++ b/packages/google-cloud-commerce-consumer-procurement/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-common/google/cloud/common/__init__.py b/packages/google-cloud-common/google/cloud/common/__init__.py index 8d1f2e3a214b..fa4cf61f8479 100644 --- a/packages/google-cloud-common/google/cloud/common/__init__.py +++ b/packages/google-cloud-common/google/cloud/common/__init__.py @@ -50,7 +50,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -79,9 +79,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-common/setup.py b/packages/google-cloud-common/setup.py index 1e5cbf370808..9572242780c0 100644 --- a/packages/google-cloud-common/setup.py +++ b/packages/google-cloud-common/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/common/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-common" diff --git a/packages/google-cloud-common/testing/constraints-3.10.txt b/packages/google-cloud-common/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-common/testing/constraints-3.10.txt +++ b/packages/google-cloud-common/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-common/testing/constraints-3.13.txt b/packages/google-cloud-common/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-common/testing/constraints-3.13.txt +++ b/packages/google-cloud-common/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-common/testing/constraints-3.14.txt b/packages/google-cloud-common/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-common/testing/constraints-3.14.txt +++ b/packages/google-cloud-common/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-compute-v1beta/google/cloud/compute_v1beta/__init__.py b/packages/google-cloud-compute-v1beta/google/cloud/compute_v1beta/__init__.py index 0ed7374600c0..6d9e0eafb450 100644 --- a/packages/google-cloud-compute-v1beta/google/cloud/compute_v1beta/__init__.py +++ b/packages/google-cloud-compute-v1beta/google/cloud/compute_v1beta/__init__.py @@ -2369,7 +2369,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -2398,9 +2398,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-compute-v1beta/setup.py b/packages/google-cloud-compute-v1beta/setup.py index 36f6a285726e..9aa231a17583 100644 --- a/packages/google-cloud-compute-v1beta/setup.py +++ b/packages/google-cloud-compute-v1beta/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/compute_v1beta/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-compute-v1beta" diff --git a/packages/google-cloud-compute-v1beta/testing/constraints-3.10.txt b/packages/google-cloud-compute-v1beta/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-compute-v1beta/testing/constraints-3.10.txt +++ b/packages/google-cloud-compute-v1beta/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-compute-v1beta/testing/constraints-3.13.txt b/packages/google-cloud-compute-v1beta/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-compute-v1beta/testing/constraints-3.13.txt +++ b/packages/google-cloud-compute-v1beta/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-compute-v1beta/testing/constraints-3.14.txt b/packages/google-cloud-compute-v1beta/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-compute-v1beta/testing/constraints-3.14.txt +++ b/packages/google-cloud-compute-v1beta/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-confidentialcomputing/google/cloud/confidentialcomputing_v1/__init__.py b/packages/google-cloud-confidentialcomputing/google/cloud/confidentialcomputing_v1/__init__.py index f4e46fd93655..82c322de5274 100644 --- a/packages/google-cloud-confidentialcomputing/google/cloud/confidentialcomputing_v1/__init__.py +++ b/packages/google-cloud-confidentialcomputing/google/cloud/confidentialcomputing_v1/__init__.py @@ -78,7 +78,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -107,9 +107,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-confidentialcomputing/setup.py b/packages/google-cloud-confidentialcomputing/setup.py index f91a86958f03..d1ce807c115e 100644 --- a/packages/google-cloud-confidentialcomputing/setup.py +++ b/packages/google-cloud-confidentialcomputing/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/confidentialcomputing/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-confidentialcomputing" diff --git a/packages/google-cloud-confidentialcomputing/testing/constraints-3.10.txt b/packages/google-cloud-confidentialcomputing/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-confidentialcomputing/testing/constraints-3.10.txt +++ b/packages/google-cloud-confidentialcomputing/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-confidentialcomputing/testing/constraints-3.13.txt b/packages/google-cloud-confidentialcomputing/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-confidentialcomputing/testing/constraints-3.13.txt +++ b/packages/google-cloud-confidentialcomputing/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-confidentialcomputing/testing/constraints-3.14.txt b/packages/google-cloud-confidentialcomputing/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-confidentialcomputing/testing/constraints-3.14.txt +++ b/packages/google-cloud-confidentialcomputing/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-config/google/cloud/config_v1/__init__.py b/packages/google-cloud-config/google/cloud/config_v1/__init__.py index c95023ad8a58..7632712ba10d 100644 --- a/packages/google-cloud-config/google/cloud/config_v1/__init__.py +++ b/packages/google-cloud-config/google/cloud/config_v1/__init__.py @@ -138,7 +138,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -167,9 +167,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-config/setup.py b/packages/google-cloud-config/setup.py index 0fe433100501..9ee4a6723db2 100644 --- a/packages/google-cloud-config/setup.py +++ b/packages/google-cloud-config/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/config/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-config" diff --git a/packages/google-cloud-config/testing/constraints-3.10.txt b/packages/google-cloud-config/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-config/testing/constraints-3.10.txt +++ b/packages/google-cloud-config/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-config/testing/constraints-3.13.txt b/packages/google-cloud-config/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-config/testing/constraints-3.13.txt +++ b/packages/google-cloud-config/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-config/testing/constraints-3.14.txt b/packages/google-cloud-config/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-config/testing/constraints-3.14.txt +++ b/packages/google-cloud-config/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-configdelivery/google/cloud/configdelivery_v1/__init__.py b/packages/google-cloud-configdelivery/google/cloud/configdelivery_v1/__init__.py index 61603789d0e2..7200700d54f5 100644 --- a/packages/google-cloud-configdelivery/google/cloud/configdelivery_v1/__init__.py +++ b/packages/google-cloud-configdelivery/google/cloud/configdelivery_v1/__init__.py @@ -102,7 +102,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -131,9 +131,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-configdelivery/google/cloud/configdelivery_v1alpha/__init__.py b/packages/google-cloud-configdelivery/google/cloud/configdelivery_v1alpha/__init__.py index f83b190b41e7..4b367f4b7ea1 100644 --- a/packages/google-cloud-configdelivery/google/cloud/configdelivery_v1alpha/__init__.py +++ b/packages/google-cloud-configdelivery/google/cloud/configdelivery_v1alpha/__init__.py @@ -102,7 +102,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -131,9 +131,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-configdelivery/google/cloud/configdelivery_v1beta/__init__.py b/packages/google-cloud-configdelivery/google/cloud/configdelivery_v1beta/__init__.py index 7571ad9598a6..909ff28b09be 100644 --- a/packages/google-cloud-configdelivery/google/cloud/configdelivery_v1beta/__init__.py +++ b/packages/google-cloud-configdelivery/google/cloud/configdelivery_v1beta/__init__.py @@ -102,7 +102,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -131,9 +131,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-configdelivery/setup.py b/packages/google-cloud-configdelivery/setup.py index 61419b531d46..626e8eec7d17 100644 --- a/packages/google-cloud-configdelivery/setup.py +++ b/packages/google-cloud-configdelivery/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/configdelivery/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-configdelivery" diff --git a/packages/google-cloud-configdelivery/testing/constraints-3.10.txt b/packages/google-cloud-configdelivery/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-configdelivery/testing/constraints-3.10.txt +++ b/packages/google-cloud-configdelivery/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-configdelivery/testing/constraints-3.13.txt b/packages/google-cloud-configdelivery/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-configdelivery/testing/constraints-3.13.txt +++ b/packages/google-cloud-configdelivery/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-configdelivery/testing/constraints-3.14.txt b/packages/google-cloud-configdelivery/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-configdelivery/testing/constraints-3.14.txt +++ b/packages/google-cloud-configdelivery/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-contact-center-insights/google/cloud/contact_center_insights_v1/__init__.py b/packages/google-cloud-contact-center-insights/google/cloud/contact_center_insights_v1/__init__.py index 98fc38e51452..d9ce6c12e7c1 100644 --- a/packages/google-cloud-contact-center-insights/google/cloud/contact_center_insights_v1/__init__.py +++ b/packages/google-cloud-contact-center-insights/google/cloud/contact_center_insights_v1/__init__.py @@ -231,7 +231,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -260,9 +260,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-contact-center-insights/setup.py b/packages/google-cloud-contact-center-insights/setup.py index f9d7d118c5e5..fae0aaf7f5a3 100644 --- a/packages/google-cloud-contact-center-insights/setup.py +++ b/packages/google-cloud-contact-center-insights/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/contact_center_insights/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-contact-center-insights" diff --git a/packages/google-cloud-contact-center-insights/testing/constraints-3.10.txt b/packages/google-cloud-contact-center-insights/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-contact-center-insights/testing/constraints-3.10.txt +++ b/packages/google-cloud-contact-center-insights/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-contact-center-insights/testing/constraints-3.13.txt b/packages/google-cloud-contact-center-insights/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-contact-center-insights/testing/constraints-3.13.txt +++ b/packages/google-cloud-contact-center-insights/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-contact-center-insights/testing/constraints-3.14.txt b/packages/google-cloud-contact-center-insights/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-contact-center-insights/testing/constraints-3.14.txt +++ b/packages/google-cloud-contact-center-insights/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-container/google/cloud/container_v1/__init__.py b/packages/google-cloud-container/google/cloud/container_v1/__init__.py index b5f5f5dc023c..462aa79c68e6 100644 --- a/packages/google-cloud-container/google/cloud/container_v1/__init__.py +++ b/packages/google-cloud-container/google/cloud/container_v1/__init__.py @@ -274,7 +274,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -303,9 +303,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-container/google/cloud/container_v1beta1/__init__.py b/packages/google-cloud-container/google/cloud/container_v1beta1/__init__.py index 8f909159b0b6..6ff7ecec793f 100644 --- a/packages/google-cloud-container/google/cloud/container_v1beta1/__init__.py +++ b/packages/google-cloud-container/google/cloud/container_v1beta1/__init__.py @@ -295,7 +295,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -324,9 +324,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-container/setup.py b/packages/google-cloud-container/setup.py index afad62d98b9c..507acea00403 100644 --- a/packages/google-cloud-container/setup.py +++ b/packages/google-cloud-container/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/container/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-container" diff --git a/packages/google-cloud-container/testing/constraints-3.10.txt b/packages/google-cloud-container/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-container/testing/constraints-3.10.txt +++ b/packages/google-cloud-container/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-container/testing/constraints-3.13.txt b/packages/google-cloud-container/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-container/testing/constraints-3.13.txt +++ b/packages/google-cloud-container/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-container/testing/constraints-3.14.txt b/packages/google-cloud-container/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-container/testing/constraints-3.14.txt +++ b/packages/google-cloud-container/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-containeranalysis/google/cloud/devtools/containeranalysis_v1/__init__.py b/packages/google-cloud-containeranalysis/google/cloud/devtools/containeranalysis_v1/__init__.py index ef77b86ef531..145d9c9b86d3 100644 --- a/packages/google-cloud-containeranalysis/google/cloud/devtools/containeranalysis_v1/__init__.py +++ b/packages/google-cloud-containeranalysis/google/cloud/devtools/containeranalysis_v1/__init__.py @@ -59,7 +59,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -88,9 +88,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-containeranalysis/setup.py b/packages/google-cloud-containeranalysis/setup.py index 7c49cf1731a0..2402207f279b 100644 --- a/packages/google-cloud-containeranalysis/setup.py +++ b/packages/google-cloud-containeranalysis/setup.py @@ -33,7 +33,10 @@ package_root, "google/cloud/devtools/containeranalysis/gapic_version.py" ) ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -43,17 +46,16 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grafeas >=1.7.0, <2.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-containeranalysis" diff --git a/packages/google-cloud-containeranalysis/testing/constraints-3.10.txt b/packages/google-cloud-containeranalysis/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-containeranalysis/testing/constraints-3.10.txt +++ b/packages/google-cloud-containeranalysis/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-containeranalysis/testing/constraints-3.13.txt b/packages/google-cloud-containeranalysis/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-containeranalysis/testing/constraints-3.13.txt +++ b/packages/google-cloud-containeranalysis/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-containeranalysis/testing/constraints-3.14.txt b/packages/google-cloud-containeranalysis/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-containeranalysis/testing/constraints-3.14.txt +++ b/packages/google-cloud-containeranalysis/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-contentwarehouse/google/cloud/contentwarehouse_v1/__init__.py b/packages/google-cloud-contentwarehouse/google/cloud/contentwarehouse_v1/__init__.py index 33a650da1a10..7297cb7b399c 100644 --- a/packages/google-cloud-contentwarehouse/google/cloud/contentwarehouse_v1/__init__.py +++ b/packages/google-cloud-contentwarehouse/google/cloud/contentwarehouse_v1/__init__.py @@ -204,7 +204,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -233,9 +233,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-contentwarehouse/setup.py b/packages/google-cloud-contentwarehouse/setup.py index 2dfccc30ac23..a3fc187795e1 100644 --- a/packages/google-cloud-contentwarehouse/setup.py +++ b/packages/google-cloud-contentwarehouse/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/contentwarehouse/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,17 +44,16 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "google-cloud-documentai >= 2.4.1, <4.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "google-cloud-documentai >= 3.2.1, <4.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-contentwarehouse" diff --git a/packages/google-cloud-contentwarehouse/testing/constraints-3.10.txt b/packages/google-cloud-contentwarehouse/testing/constraints-3.10.txt index 8b0bfae23e7f..ea87757c3942 100644 --- a/packages/google-cloud-contentwarehouse/testing/constraints-3.10.txt +++ b/packages/google-cloud-contentwarehouse/testing/constraints-3.10.txt @@ -4,10 +4,10 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -google-cloud-documentai==2.4.1 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +google-cloud-documentai==3.2.1 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-contentwarehouse/testing/constraints-3.13.txt b/packages/google-cloud-contentwarehouse/testing/constraints-3.13.txt index fc148ee44beb..daf20eb644e0 100644 --- a/packages/google-cloud-contentwarehouse/testing/constraints-3.13.txt +++ b/packages/google-cloud-contentwarehouse/testing/constraints-3.13.txt @@ -9,6 +9,6 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-cloud-documentai>=3 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-contentwarehouse/testing/constraints-3.14.txt b/packages/google-cloud-contentwarehouse/testing/constraints-3.14.txt index fc148ee44beb..daf20eb644e0 100644 --- a/packages/google-cloud-contentwarehouse/testing/constraints-3.14.txt +++ b/packages/google-cloud-contentwarehouse/testing/constraints-3.14.txt @@ -9,6 +9,6 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-cloud-documentai>=3 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-data-fusion/google/cloud/data_fusion_v1/__init__.py b/packages/google-cloud-data-fusion/google/cloud/data_fusion_v1/__init__.py index 78328c8d509b..c78083bfbc09 100644 --- a/packages/google-cloud-data-fusion/google/cloud/data_fusion_v1/__init__.py +++ b/packages/google-cloud-data-fusion/google/cloud/data_fusion_v1/__init__.py @@ -67,7 +67,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -96,9 +96,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-data-fusion/setup.py b/packages/google-cloud-data-fusion/setup.py index e885b43b28a4..9a4d5c6a0ec8 100644 --- a/packages/google-cloud-data-fusion/setup.py +++ b/packages/google-cloud-data-fusion/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/data_fusion/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-data-fusion" diff --git a/packages/google-cloud-data-fusion/testing/constraints-3.10.txt b/packages/google-cloud-data-fusion/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-data-fusion/testing/constraints-3.10.txt +++ b/packages/google-cloud-data-fusion/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-data-fusion/testing/constraints-3.13.txt b/packages/google-cloud-data-fusion/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-data-fusion/testing/constraints-3.13.txt +++ b/packages/google-cloud-data-fusion/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-data-fusion/testing/constraints-3.14.txt b/packages/google-cloud-data-fusion/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-data-fusion/testing/constraints-3.14.txt +++ b/packages/google-cloud-data-fusion/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-data-qna/google/cloud/dataqna_v1alpha/__init__.py b/packages/google-cloud-data-qna/google/cloud/dataqna_v1alpha/__init__.py index bfb33f772ea1..a9900d44e191 100644 --- a/packages/google-cloud-data-qna/google/cloud/dataqna_v1alpha/__init__.py +++ b/packages/google-cloud-data-qna/google/cloud/dataqna_v1alpha/__init__.py @@ -82,7 +82,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -111,9 +111,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-data-qna/setup.py b/packages/google-cloud-data-qna/setup.py index 680a0e811f7e..61963741f6c3 100644 --- a/packages/google-cloud-data-qna/setup.py +++ b/packages/google-cloud-data-qna/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/dataqna/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-data-qna" diff --git a/packages/google-cloud-data-qna/testing/constraints-3.10.txt b/packages/google-cloud-data-qna/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-data-qna/testing/constraints-3.10.txt +++ b/packages/google-cloud-data-qna/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-data-qna/testing/constraints-3.13.txt b/packages/google-cloud-data-qna/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-data-qna/testing/constraints-3.13.txt +++ b/packages/google-cloud-data-qna/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-data-qna/testing/constraints-3.14.txt b/packages/google-cloud-data-qna/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-data-qna/testing/constraints-3.14.txt +++ b/packages/google-cloud-data-qna/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-databasecenter/google/cloud/databasecenter_v1beta/__init__.py b/packages/google-cloud-databasecenter/google/cloud/databasecenter_v1beta/__init__.py index 85d7aa68fe13..3cb441b01ec6 100644 --- a/packages/google-cloud-databasecenter/google/cloud/databasecenter_v1beta/__init__.py +++ b/packages/google-cloud-databasecenter/google/cloud/databasecenter_v1beta/__init__.py @@ -124,7 +124,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -153,9 +153,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-databasecenter/setup.py b/packages/google-cloud-databasecenter/setup.py index 1dd5154980d1..935696dce31e 100644 --- a/packages/google-cloud-databasecenter/setup.py +++ b/packages/google-cloud-databasecenter/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/databasecenter/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-databasecenter" diff --git a/packages/google-cloud-databasecenter/testing/constraints-3.10.txt b/packages/google-cloud-databasecenter/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-databasecenter/testing/constraints-3.10.txt +++ b/packages/google-cloud-databasecenter/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-databasecenter/testing/constraints-3.13.txt b/packages/google-cloud-databasecenter/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-databasecenter/testing/constraints-3.13.txt +++ b/packages/google-cloud-databasecenter/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-databasecenter/testing/constraints-3.14.txt b/packages/google-cloud-databasecenter/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-databasecenter/testing/constraints-3.14.txt +++ b/packages/google-cloud-databasecenter/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-datacatalog-lineage-configmanagement/google/cloud/datacatalog_lineage_configmanagement_v1/__init__.py b/packages/google-cloud-datacatalog-lineage-configmanagement/google/cloud/datacatalog_lineage_configmanagement_v1/__init__.py index 45e0f1ba4a1d..548a0083e0ef 100644 --- a/packages/google-cloud-datacatalog-lineage-configmanagement/google/cloud/datacatalog_lineage_configmanagement_v1/__init__.py +++ b/packages/google-cloud-datacatalog-lineage-configmanagement/google/cloud/datacatalog_lineage_configmanagement_v1/__init__.py @@ -60,7 +60,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -89,9 +89,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-datacatalog-lineage-configmanagement/setup.py b/packages/google-cloud-datacatalog-lineage-configmanagement/setup.py index 383994524bfc..f0c08ce28e78 100644 --- a/packages/google-cloud-datacatalog-lineage-configmanagement/setup.py +++ b/packages/google-cloud-datacatalog-lineage-configmanagement/setup.py @@ -34,7 +34,10 @@ "google/cloud/datacatalog_lineage_configmanagement/gapic_version.py", ) ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -44,15 +47,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-datacatalog-lineage-configmanagement" diff --git a/packages/google-cloud-datacatalog-lineage-configmanagement/testing/constraints-3.10.txt b/packages/google-cloud-datacatalog-lineage-configmanagement/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-datacatalog-lineage-configmanagement/testing/constraints-3.10.txt +++ b/packages/google-cloud-datacatalog-lineage-configmanagement/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-datacatalog-lineage-configmanagement/testing/constraints-3.13.txt b/packages/google-cloud-datacatalog-lineage-configmanagement/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-datacatalog-lineage-configmanagement/testing/constraints-3.13.txt +++ b/packages/google-cloud-datacatalog-lineage-configmanagement/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-datacatalog-lineage-configmanagement/testing/constraints-3.14.txt b/packages/google-cloud-datacatalog-lineage-configmanagement/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-datacatalog-lineage-configmanagement/testing/constraints-3.14.txt +++ b/packages/google-cloud-datacatalog-lineage-configmanagement/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/__init__.py b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/__init__.py index a3c913d09c18..8d46559e3ecb 100644 --- a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/__init__.py +++ b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/__init__.py @@ -91,7 +91,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -120,9 +120,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-datacatalog-lineage/setup.py b/packages/google-cloud-datacatalog-lineage/setup.py index d2326fe061e9..02c5bd3d9593 100644 --- a/packages/google-cloud-datacatalog-lineage/setup.py +++ b/packages/google-cloud-datacatalog-lineage/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/datacatalog_lineage/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-datacatalog-lineage" diff --git a/packages/google-cloud-datacatalog-lineage/testing/constraints-3.10.txt b/packages/google-cloud-datacatalog-lineage/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-datacatalog-lineage/testing/constraints-3.10.txt +++ b/packages/google-cloud-datacatalog-lineage/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-datacatalog-lineage/testing/constraints-3.13.txt b/packages/google-cloud-datacatalog-lineage/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-datacatalog-lineage/testing/constraints-3.13.txt +++ b/packages/google-cloud-datacatalog-lineage/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-datacatalog-lineage/testing/constraints-3.14.txt b/packages/google-cloud-datacatalog-lineage/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-datacatalog-lineage/testing/constraints-3.14.txt +++ b/packages/google-cloud-datacatalog-lineage/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1/__init__.py b/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1/__init__.py index b43453e73c88..750234275869 100644 --- a/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1/__init__.py +++ b/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1/__init__.py @@ -184,7 +184,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -213,9 +213,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1beta1/__init__.py b/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1beta1/__init__.py index 30a0de4cabb0..5636d837da3e 100644 --- a/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1beta1/__init__.py +++ b/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1beta1/__init__.py @@ -131,7 +131,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -160,9 +160,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-datacatalog/setup.py b/packages/google-cloud-datacatalog/setup.py index 199f4daffb54..1550b4895931 100644 --- a/packages/google-cloud-datacatalog/setup.py +++ b/packages/google-cloud-datacatalog/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/datacatalog/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-datacatalog" diff --git a/packages/google-cloud-datacatalog/testing/constraints-3.10.txt b/packages/google-cloud-datacatalog/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-datacatalog/testing/constraints-3.10.txt +++ b/packages/google-cloud-datacatalog/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-datacatalog/testing/constraints-3.13.txt b/packages/google-cloud-datacatalog/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-datacatalog/testing/constraints-3.13.txt +++ b/packages/google-cloud-datacatalog/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-datacatalog/testing/constraints-3.14.txt b/packages/google-cloud-datacatalog/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-datacatalog/testing/constraints-3.14.txt +++ b/packages/google-cloud-datacatalog/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/__init__.py b/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/__init__.py index 58baf9846f36..8942e1d18466 100644 --- a/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/__init__.py +++ b/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/__init__.py @@ -197,7 +197,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -226,9 +226,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-dataflow-client/setup.py b/packages/google-cloud-dataflow-client/setup.py index f64881ee3409..e2e70a586f98 100644 --- a/packages/google-cloud-dataflow-client/setup.py +++ b/packages/google-cloud-dataflow-client/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/dataflow/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-dataflow-client" diff --git a/packages/google-cloud-dataflow-client/testing/constraints-3.10.txt b/packages/google-cloud-dataflow-client/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-dataflow-client/testing/constraints-3.10.txt +++ b/packages/google-cloud-dataflow-client/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-dataflow-client/testing/constraints-3.13.txt b/packages/google-cloud-dataflow-client/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-dataflow-client/testing/constraints-3.13.txt +++ b/packages/google-cloud-dataflow-client/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-dataflow-client/testing/constraints-3.14.txt b/packages/google-cloud-dataflow-client/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-dataflow-client/testing/constraints-3.14.txt +++ b/packages/google-cloud-dataflow-client/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-dataform/google/cloud/dataform_v1/__init__.py b/packages/google-cloud-dataform/google/cloud/dataform_v1/__init__.py index 268b5c5ba09d..c8e83474dacb 100644 --- a/packages/google-cloud-dataform/google/cloud/dataform_v1/__init__.py +++ b/packages/google-cloud-dataform/google/cloud/dataform_v1/__init__.py @@ -188,7 +188,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -217,9 +217,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/__init__.py b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/__init__.py index d83bf644c121..097c288f8006 100644 --- a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/__init__.py +++ b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/__init__.py @@ -183,7 +183,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -212,9 +212,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-dataform/setup.py b/packages/google-cloud-dataform/setup.py index 3b2562f571fd..3f18e5c500f6 100644 --- a/packages/google-cloud-dataform/setup.py +++ b/packages/google-cloud-dataform/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/dataform/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-dataform" diff --git a/packages/google-cloud-dataform/testing/constraints-3.10.txt b/packages/google-cloud-dataform/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-dataform/testing/constraints-3.10.txt +++ b/packages/google-cloud-dataform/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-dataform/testing/constraints-3.13.txt b/packages/google-cloud-dataform/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-dataform/testing/constraints-3.13.txt +++ b/packages/google-cloud-dataform/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-dataform/testing/constraints-3.14.txt b/packages/google-cloud-dataform/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-dataform/testing/constraints-3.14.txt +++ b/packages/google-cloud-dataform/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-datalabeling/google/cloud/datalabeling_v1beta1/__init__.py b/packages/google-cloud-datalabeling/google/cloud/datalabeling_v1beta1/__init__.py index 4983f7dc0c2a..15b203a438af 100644 --- a/packages/google-cloud-datalabeling/google/cloud/datalabeling_v1beta1/__init__.py +++ b/packages/google-cloud-datalabeling/google/cloud/datalabeling_v1beta1/__init__.py @@ -196,7 +196,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -225,9 +225,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-datalabeling/setup.py b/packages/google-cloud-datalabeling/setup.py index e32ddc444741..c9b782264427 100644 --- a/packages/google-cloud-datalabeling/setup.py +++ b/packages/google-cloud-datalabeling/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/datalabeling/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-datalabeling" diff --git a/packages/google-cloud-datalabeling/testing/constraints-3.10.txt b/packages/google-cloud-datalabeling/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-datalabeling/testing/constraints-3.10.txt +++ b/packages/google-cloud-datalabeling/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-datalabeling/testing/constraints-3.13.txt b/packages/google-cloud-datalabeling/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-datalabeling/testing/constraints-3.13.txt +++ b/packages/google-cloud-datalabeling/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-datalabeling/testing/constraints-3.14.txt b/packages/google-cloud-datalabeling/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-datalabeling/testing/constraints-3.14.txt +++ b/packages/google-cloud-datalabeling/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/__init__.py b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/__init__.py index f57d85ad0fe3..bade5997771d 100644 --- a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/__init__.py +++ b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/__init__.py @@ -313,7 +313,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -342,9 +342,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-dataplex/setup.py b/packages/google-cloud-dataplex/setup.py index db1491be3ac3..71aaae470977 100644 --- a/packages/google-cloud-dataplex/setup.py +++ b/packages/google-cloud-dataplex/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/dataplex/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-dataplex" diff --git a/packages/google-cloud-dataplex/testing/constraints-3.10.txt b/packages/google-cloud-dataplex/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-dataplex/testing/constraints-3.10.txt +++ b/packages/google-cloud-dataplex/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-dataplex/testing/constraints-3.13.txt b/packages/google-cloud-dataplex/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-dataplex/testing/constraints-3.13.txt +++ b/packages/google-cloud-dataplex/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-dataplex/testing/constraints-3.14.txt b/packages/google-cloud-dataplex/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-dataplex/testing/constraints-3.14.txt +++ b/packages/google-cloud-dataplex/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1/__init__.py b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1/__init__.py index 17d0509ed010..80b613cf788b 100644 --- a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1/__init__.py +++ b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1/__init__.py @@ -112,7 +112,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -141,9 +141,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1alpha/__init__.py b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1alpha/__init__.py index 72bbff3c4dff..b33d86e0f9d7 100644 --- a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1alpha/__init__.py +++ b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1alpha/__init__.py @@ -118,7 +118,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -147,9 +147,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1beta/__init__.py b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1beta/__init__.py index f031c60faa7c..9e6521efc5b7 100644 --- a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1beta/__init__.py +++ b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1beta/__init__.py @@ -118,7 +118,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -147,9 +147,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-dataproc-metastore/setup.py b/packages/google-cloud-dataproc-metastore/setup.py index b773b5a98b0d..9d60d24667eb 100644 --- a/packages/google-cloud-dataproc-metastore/setup.py +++ b/packages/google-cloud-dataproc-metastore/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/metastore/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-dataproc-metastore" diff --git a/packages/google-cloud-dataproc-metastore/testing/constraints-3.10.txt b/packages/google-cloud-dataproc-metastore/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-dataproc-metastore/testing/constraints-3.10.txt +++ b/packages/google-cloud-dataproc-metastore/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-dataproc-metastore/testing/constraints-3.13.txt b/packages/google-cloud-dataproc-metastore/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-dataproc-metastore/testing/constraints-3.13.txt +++ b/packages/google-cloud-dataproc-metastore/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-dataproc-metastore/testing/constraints-3.14.txt b/packages/google-cloud-dataproc-metastore/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-dataproc-metastore/testing/constraints-3.14.txt +++ b/packages/google-cloud-dataproc-metastore/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/__init__.py b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/__init__.py index 6b88a77379fa..0743d394c587 100644 --- a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/__init__.py +++ b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/__init__.py @@ -248,7 +248,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -277,9 +277,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-dataproc/setup.py b/packages/google-cloud-dataproc/setup.py index 24eddbb83a43..76dd34fc8b49 100644 --- a/packages/google-cloud-dataproc/setup.py +++ b/packages/google-cloud-dataproc/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/dataproc/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-dataproc" diff --git a/packages/google-cloud-dataproc/testing/constraints-3.10.txt b/packages/google-cloud-dataproc/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-dataproc/testing/constraints-3.10.txt +++ b/packages/google-cloud-dataproc/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-dataproc/testing/constraints-3.13.txt b/packages/google-cloud-dataproc/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-dataproc/testing/constraints-3.13.txt +++ b/packages/google-cloud-dataproc/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-dataproc/testing/constraints-3.14.txt b/packages/google-cloud-dataproc/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-dataproc/testing/constraints-3.14.txt +++ b/packages/google-cloud-dataproc/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-datastore/google/cloud/datastore_admin_v1/__init__.py b/packages/google-cloud-datastore/google/cloud/datastore_admin_v1/__init__.py index ab92fd717567..e6209583615b 100644 --- a/packages/google-cloud-datastore/google/cloud/datastore_admin_v1/__init__.py +++ b/packages/google-cloud-datastore/google/cloud/datastore_admin_v1/__init__.py @@ -75,7 +75,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -104,9 +104,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-datastore/google/cloud/datastore_v1/__init__.py b/packages/google-cloud-datastore/google/cloud/datastore_v1/__init__.py index 7e8f2602291d..7017a18c095c 100644 --- a/packages/google-cloud-datastore/google/cloud/datastore_v1/__init__.py +++ b/packages/google-cloud-datastore/google/cloud/datastore_v1/__init__.py @@ -98,7 +98,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -127,9 +127,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-datastore/setup.py b/packages/google-cloud-datastore/setup.py index b0cac8c0ec50..26f21974303e 100644 --- a/packages/google-cloud-datastore/setup.py +++ b/packages/google-cloud-datastore/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/datastore/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "google-cloud-core >= 2.0.0, <3.0.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-datastore" diff --git a/packages/google-cloud-datastore/testing/constraints-3.10.txt b/packages/google-cloud-datastore/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-datastore/testing/constraints-3.10.txt +++ b/packages/google-cloud-datastore/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-datastore/testing/constraints-3.13.txt b/packages/google-cloud-datastore/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-datastore/testing/constraints-3.13.txt +++ b/packages/google-cloud-datastore/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-datastore/testing/constraints-3.14.txt b/packages/google-cloud-datastore/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-datastore/testing/constraints-3.14.txt +++ b/packages/google-cloud-datastore/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-datastream/google/cloud/datastream_v1/__init__.py b/packages/google-cloud-datastream/google/cloud/datastream_v1/__init__.py index 999476c4a595..1afa6550835e 100644 --- a/packages/google-cloud-datastream/google/cloud/datastream_v1/__init__.py +++ b/packages/google-cloud-datastream/google/cloud/datastream_v1/__init__.py @@ -164,7 +164,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -193,9 +193,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-datastream/google/cloud/datastream_v1alpha1/__init__.py b/packages/google-cloud-datastream/google/cloud/datastream_v1alpha1/__init__.py index 7f645fd02506..ed581a7caeb2 100644 --- a/packages/google-cloud-datastream/google/cloud/datastream_v1alpha1/__init__.py +++ b/packages/google-cloud-datastream/google/cloud/datastream_v1alpha1/__init__.py @@ -117,7 +117,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -146,9 +146,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-datastream/setup.py b/packages/google-cloud-datastream/setup.py index 215e519dc6c5..141a08c88cee 100644 --- a/packages/google-cloud-datastream/setup.py +++ b/packages/google-cloud-datastream/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/datastream/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-datastream" diff --git a/packages/google-cloud-datastream/testing/constraints-3.10.txt b/packages/google-cloud-datastream/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-datastream/testing/constraints-3.10.txt +++ b/packages/google-cloud-datastream/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-datastream/testing/constraints-3.13.txt b/packages/google-cloud-datastream/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-datastream/testing/constraints-3.13.txt +++ b/packages/google-cloud-datastream/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-datastream/testing/constraints-3.14.txt b/packages/google-cloud-datastream/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-datastream/testing/constraints-3.14.txt +++ b/packages/google-cloud-datastream/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-deploy/google/cloud/deploy_v1/__init__.py b/packages/google-cloud-deploy/google/cloud/deploy_v1/__init__.py index ecf53db6404a..ae086dd3f447 100644 --- a/packages/google-cloud-deploy/google/cloud/deploy_v1/__init__.py +++ b/packages/google-cloud-deploy/google/cloud/deploy_v1/__init__.py @@ -232,7 +232,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -261,9 +261,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-deploy/setup.py b/packages/google-cloud-deploy/setup.py index 7637cd7081bf..e1a1fa50536c 100644 --- a/packages/google-cloud-deploy/setup.py +++ b/packages/google-cloud-deploy/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/deploy/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-deploy" diff --git a/packages/google-cloud-deploy/testing/constraints-3.10.txt b/packages/google-cloud-deploy/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-deploy/testing/constraints-3.10.txt +++ b/packages/google-cloud-deploy/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-deploy/testing/constraints-3.13.txt b/packages/google-cloud-deploy/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-deploy/testing/constraints-3.13.txt +++ b/packages/google-cloud-deploy/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-deploy/testing/constraints-3.14.txt b/packages/google-cloud-deploy/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-deploy/testing/constraints-3.14.txt +++ b/packages/google-cloud-deploy/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-developerconnect/google/cloud/developerconnect_v1/__init__.py b/packages/google-cloud-developerconnect/google/cloud/developerconnect_v1/__init__.py index 8e4b1016b04e..a5e7b35a4347 100644 --- a/packages/google-cloud-developerconnect/google/cloud/developerconnect_v1/__init__.py +++ b/packages/google-cloud-developerconnect/google/cloud/developerconnect_v1/__init__.py @@ -143,7 +143,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -172,9 +172,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-developerconnect/setup.py b/packages/google-cloud-developerconnect/setup.py index aa6aca1f649f..2c50b79d2675 100644 --- a/packages/google-cloud-developerconnect/setup.py +++ b/packages/google-cloud-developerconnect/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/developerconnect/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-developerconnect" diff --git a/packages/google-cloud-developerconnect/testing/constraints-3.10.txt b/packages/google-cloud-developerconnect/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-developerconnect/testing/constraints-3.10.txt +++ b/packages/google-cloud-developerconnect/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-developerconnect/testing/constraints-3.13.txt b/packages/google-cloud-developerconnect/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-developerconnect/testing/constraints-3.13.txt +++ b/packages/google-cloud-developerconnect/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-developerconnect/testing/constraints-3.14.txt b/packages/google-cloud-developerconnect/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-developerconnect/testing/constraints-3.14.txt +++ b/packages/google-cloud-developerconnect/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-devicestreaming/google/cloud/devicestreaming_v1/__init__.py b/packages/google-cloud-devicestreaming/google/cloud/devicestreaming_v1/__init__.py index 14f3494e0ae1..fafed132819d 100644 --- a/packages/google-cloud-devicestreaming/google/cloud/devicestreaming_v1/__init__.py +++ b/packages/google-cloud-devicestreaming/google/cloud/devicestreaming_v1/__init__.py @@ -74,7 +74,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -103,9 +103,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-devicestreaming/setup.py b/packages/google-cloud-devicestreaming/setup.py index ab00aacd2212..24f407ca6a62 100644 --- a/packages/google-cloud-devicestreaming/setup.py +++ b/packages/google-cloud-devicestreaming/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/devicestreaming/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-devicestreaming" diff --git a/packages/google-cloud-devicestreaming/testing/constraints-3.10.txt b/packages/google-cloud-devicestreaming/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-devicestreaming/testing/constraints-3.10.txt +++ b/packages/google-cloud-devicestreaming/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-devicestreaming/testing/constraints-3.13.txt b/packages/google-cloud-devicestreaming/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-devicestreaming/testing/constraints-3.13.txt +++ b/packages/google-cloud-devicestreaming/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-devicestreaming/testing/constraints-3.14.txt b/packages/google-cloud-devicestreaming/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-devicestreaming/testing/constraints-3.14.txt +++ b/packages/google-cloud-devicestreaming/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/__init__.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/__init__.py index 076e0643ba58..812b93f2d657 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/__init__.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/__init__.py @@ -437,7 +437,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -466,9 +466,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/__init__.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/__init__.py index cfac0ff2ec78..6f05a16ae2fe 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/__init__.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/__init__.py @@ -460,7 +460,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -489,9 +489,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-dialogflow-cx/setup.py b/packages/google-cloud-dialogflow-cx/setup.py index 5e7bec4a5b56..eb20ac067d53 100644 --- a/packages/google-cloud-dialogflow-cx/setup.py +++ b/packages/google-cloud-dialogflow-cx/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/dialogflowcx/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-dialogflow-cx" diff --git a/packages/google-cloud-dialogflow-cx/testing/constraints-3.10.txt b/packages/google-cloud-dialogflow-cx/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-dialogflow-cx/testing/constraints-3.10.txt +++ b/packages/google-cloud-dialogflow-cx/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-dialogflow-cx/testing/constraints-3.13.txt b/packages/google-cloud-dialogflow-cx/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-dialogflow-cx/testing/constraints-3.13.txt +++ b/packages/google-cloud-dialogflow-cx/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-dialogflow-cx/testing/constraints-3.14.txt b/packages/google-cloud-dialogflow-cx/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-dialogflow-cx/testing/constraints-3.14.txt +++ b/packages/google-cloud-dialogflow-cx/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/__init__.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/__init__.py index f980335cf78f..87ed765ed6cc 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/__init__.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/__init__.py @@ -442,7 +442,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -471,9 +471,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/__init__.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/__init__.py index cb2fcfce4c59..348927177b65 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/__init__.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/__init__.py @@ -419,7 +419,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -448,9 +448,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-dialogflow/setup.py b/packages/google-cloud-dialogflow/setup.py index 2dc803c41467..e531168dd1f2 100644 --- a/packages/google-cloud-dialogflow/setup.py +++ b/packages/google-cloud-dialogflow/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/dialogflow/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-dialogflow" diff --git a/packages/google-cloud-dialogflow/testing/constraints-3.10.txt b/packages/google-cloud-dialogflow/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-dialogflow/testing/constraints-3.10.txt +++ b/packages/google-cloud-dialogflow/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-dialogflow/testing/constraints-3.13.txt b/packages/google-cloud-dialogflow/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-dialogflow/testing/constraints-3.13.txt +++ b/packages/google-cloud-dialogflow/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-dialogflow/testing/constraints-3.14.txt b/packages/google-cloud-dialogflow/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-dialogflow/testing/constraints-3.14.txt +++ b/packages/google-cloud-dialogflow/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/__init__.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/__init__.py index c295e14246ed..08805283ccff 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/__init__.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/__init__.py @@ -375,7 +375,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -404,9 +404,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/__init__.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/__init__.py index 206ae0c2aa16..1b27234603fa 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/__init__.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/__init__.py @@ -390,7 +390,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -419,9 +419,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/__init__.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/__init__.py index f27dbbca2178..33ec2f3deebb 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/__init__.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/__init__.py @@ -369,7 +369,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -398,9 +398,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-discoveryengine/setup.py b/packages/google-cloud-discoveryengine/setup.py index d63cebc67086..7e75b11cd6fb 100644 --- a/packages/google-cloud-discoveryengine/setup.py +++ b/packages/google-cloud-discoveryengine/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/discoveryengine/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-discoveryengine" diff --git a/packages/google-cloud-discoveryengine/testing/constraints-3.10.txt b/packages/google-cloud-discoveryengine/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-discoveryengine/testing/constraints-3.10.txt +++ b/packages/google-cloud-discoveryengine/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-discoveryengine/testing/constraints-3.13.txt b/packages/google-cloud-discoveryengine/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-discoveryengine/testing/constraints-3.13.txt +++ b/packages/google-cloud-discoveryengine/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-discoveryengine/testing/constraints-3.14.txt b/packages/google-cloud-discoveryengine/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-discoveryengine/testing/constraints-3.14.txt +++ b/packages/google-cloud-discoveryengine/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-dlp/google/cloud/dlp_v2/__init__.py b/packages/google-cloud-dlp/google/cloud/dlp_v2/__init__.py index 350174be60ef..6b080ecb958d 100644 --- a/packages/google-cloud-dlp/google/cloud/dlp_v2/__init__.py +++ b/packages/google-cloud-dlp/google/cloud/dlp_v2/__init__.py @@ -378,7 +378,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -407,9 +407,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-dlp/setup.py b/packages/google-cloud-dlp/setup.py index 7f7d1bd82cad..1fb2a2bb04f0 100644 --- a/packages/google-cloud-dlp/setup.py +++ b/packages/google-cloud-dlp/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/dlp/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-dlp" diff --git a/packages/google-cloud-dlp/testing/constraints-3.10.txt b/packages/google-cloud-dlp/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-dlp/testing/constraints-3.10.txt +++ b/packages/google-cloud-dlp/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-dlp/testing/constraints-3.13.txt b/packages/google-cloud-dlp/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-dlp/testing/constraints-3.13.txt +++ b/packages/google-cloud-dlp/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-dlp/testing/constraints-3.14.txt b/packages/google-cloud-dlp/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-dlp/testing/constraints-3.14.txt +++ b/packages/google-cloud-dlp/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-dms/google/cloud/clouddms_v1/__init__.py b/packages/google-cloud-dms/google/cloud/clouddms_v1/__init__.py index 9a4605d42457..d964d849f547 100644 --- a/packages/google-cloud-dms/google/cloud/clouddms_v1/__init__.py +++ b/packages/google-cloud-dms/google/cloud/clouddms_v1/__init__.py @@ -194,7 +194,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -223,9 +223,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-dms/setup.py b/packages/google-cloud-dms/setup.py index a6792bcd5ca5..2f7c0c6c32fa 100644 --- a/packages/google-cloud-dms/setup.py +++ b/packages/google-cloud-dms/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/clouddms/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-dms" diff --git a/packages/google-cloud-dms/testing/constraints-3.10.txt b/packages/google-cloud-dms/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-dms/testing/constraints-3.10.txt +++ b/packages/google-cloud-dms/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-dms/testing/constraints-3.13.txt b/packages/google-cloud-dms/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-dms/testing/constraints-3.13.txt +++ b/packages/google-cloud-dms/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-dms/testing/constraints-3.14.txt b/packages/google-cloud-dms/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-dms/testing/constraints-3.14.txt +++ b/packages/google-cloud-dms/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-documentai/google/cloud/documentai_v1/__init__.py b/packages/google-cloud-documentai/google/cloud/documentai_v1/__init__.py index 2fab63e832c3..bfd3283f728a 100644 --- a/packages/google-cloud-documentai/google/cloud/documentai_v1/__init__.py +++ b/packages/google-cloud-documentai/google/cloud/documentai_v1/__init__.py @@ -122,7 +122,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -151,9 +151,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-documentai/google/cloud/documentai_v1beta3/__init__.py b/packages/google-cloud-documentai/google/cloud/documentai_v1beta3/__init__.py index 8f5bb7f97b2b..fc13acd350f7 100644 --- a/packages/google-cloud-documentai/google/cloud/documentai_v1beta3/__init__.py +++ b/packages/google-cloud-documentai/google/cloud/documentai_v1beta3/__init__.py @@ -156,7 +156,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -185,9 +185,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-documentai/setup.py b/packages/google-cloud-documentai/setup.py index acb38ef0ea31..1386c7beb099 100644 --- a/packages/google-cloud-documentai/setup.py +++ b/packages/google-cloud-documentai/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/documentai/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-documentai" diff --git a/packages/google-cloud-documentai/testing/constraints-3.10.txt b/packages/google-cloud-documentai/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-documentai/testing/constraints-3.10.txt +++ b/packages/google-cloud-documentai/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-documentai/testing/constraints-3.13.txt b/packages/google-cloud-documentai/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-documentai/testing/constraints-3.13.txt +++ b/packages/google-cloud-documentai/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-documentai/testing/constraints-3.14.txt b/packages/google-cloud-documentai/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-documentai/testing/constraints-3.14.txt +++ b/packages/google-cloud-documentai/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-domains/google/cloud/domains_v1/__init__.py b/packages/google-cloud-domains/google/cloud/domains_v1/__init__.py index 586b59820078..4435eacb6994 100644 --- a/packages/google-cloud-domains/google/cloud/domains_v1/__init__.py +++ b/packages/google-cloud-domains/google/cloud/domains_v1/__init__.py @@ -83,7 +83,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -112,9 +112,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-domains/google/cloud/domains_v1beta1/__init__.py b/packages/google-cloud-domains/google/cloud/domains_v1beta1/__init__.py index 9606c3ebb01f..1864df637864 100644 --- a/packages/google-cloud-domains/google/cloud/domains_v1beta1/__init__.py +++ b/packages/google-cloud-domains/google/cloud/domains_v1beta1/__init__.py @@ -83,7 +83,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -112,9 +112,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-domains/setup.py b/packages/google-cloud-domains/setup.py index 897e10ebaedb..9b88f3c3879b 100644 --- a/packages/google-cloud-domains/setup.py +++ b/packages/google-cloud-domains/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/domains/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-domains" diff --git a/packages/google-cloud-domains/testing/constraints-3.10.txt b/packages/google-cloud-domains/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-domains/testing/constraints-3.10.txt +++ b/packages/google-cloud-domains/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-domains/testing/constraints-3.13.txt b/packages/google-cloud-domains/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-domains/testing/constraints-3.13.txt +++ b/packages/google-cloud-domains/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-domains/testing/constraints-3.14.txt b/packages/google-cloud-domains/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-domains/testing/constraints-3.14.txt +++ b/packages/google-cloud-domains/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-edgecontainer/google/cloud/edgecontainer_v1/__init__.py b/packages/google-cloud-edgecontainer/google/cloud/edgecontainer_v1/__init__.py index 49ba75ed766e..da72e2163411 100644 --- a/packages/google-cloud-edgecontainer/google/cloud/edgecontainer_v1/__init__.py +++ b/packages/google-cloud-edgecontainer/google/cloud/edgecontainer_v1/__init__.py @@ -103,7 +103,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -132,9 +132,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-edgecontainer/setup.py b/packages/google-cloud-edgecontainer/setup.py index cb72ce7e68de..d628c5485443 100644 --- a/packages/google-cloud-edgecontainer/setup.py +++ b/packages/google-cloud-edgecontainer/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/edgecontainer/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-edgecontainer" diff --git a/packages/google-cloud-edgecontainer/testing/constraints-3.10.txt b/packages/google-cloud-edgecontainer/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-edgecontainer/testing/constraints-3.10.txt +++ b/packages/google-cloud-edgecontainer/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-edgecontainer/testing/constraints-3.13.txt b/packages/google-cloud-edgecontainer/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-edgecontainer/testing/constraints-3.13.txt +++ b/packages/google-cloud-edgecontainer/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-edgecontainer/testing/constraints-3.14.txt b/packages/google-cloud-edgecontainer/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-edgecontainer/testing/constraints-3.14.txt +++ b/packages/google-cloud-edgecontainer/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-edgenetwork/google/cloud/edgenetwork_v1/__init__.py b/packages/google-cloud-edgenetwork/google/cloud/edgenetwork_v1/__init__.py index 315857c34d38..e5c511eeb3b6 100644 --- a/packages/google-cloud-edgenetwork/google/cloud/edgenetwork_v1/__init__.py +++ b/packages/google-cloud-edgenetwork/google/cloud/edgenetwork_v1/__init__.py @@ -103,7 +103,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -132,9 +132,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-edgenetwork/setup.py b/packages/google-cloud-edgenetwork/setup.py index 85e448469a8c..6f58d945b83a 100644 --- a/packages/google-cloud-edgenetwork/setup.py +++ b/packages/google-cloud-edgenetwork/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/edgenetwork/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-edgenetwork" diff --git a/packages/google-cloud-edgenetwork/testing/constraints-3.10.txt b/packages/google-cloud-edgenetwork/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-edgenetwork/testing/constraints-3.10.txt +++ b/packages/google-cloud-edgenetwork/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-edgenetwork/testing/constraints-3.13.txt b/packages/google-cloud-edgenetwork/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-edgenetwork/testing/constraints-3.13.txt +++ b/packages/google-cloud-edgenetwork/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-edgenetwork/testing/constraints-3.14.txt b/packages/google-cloud-edgenetwork/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-edgenetwork/testing/constraints-3.14.txt +++ b/packages/google-cloud-edgenetwork/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-enterpriseknowledgegraph/google/cloud/enterpriseknowledgegraph_v1/__init__.py b/packages/google-cloud-enterpriseknowledgegraph/google/cloud/enterpriseknowledgegraph_v1/__init__.py index 3c70c813e8a3..2deabc420657 100644 --- a/packages/google-cloud-enterpriseknowledgegraph/google/cloud/enterpriseknowledgegraph_v1/__init__.py +++ b/packages/google-cloud-enterpriseknowledgegraph/google/cloud/enterpriseknowledgegraph_v1/__init__.py @@ -79,7 +79,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -108,9 +108,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-enterpriseknowledgegraph/setup.py b/packages/google-cloud-enterpriseknowledgegraph/setup.py index fff6bc032467..efa8f398627e 100644 --- a/packages/google-cloud-enterpriseknowledgegraph/setup.py +++ b/packages/google-cloud-enterpriseknowledgegraph/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/enterpriseknowledgegraph/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-enterpriseknowledgegraph" diff --git a/packages/google-cloud-enterpriseknowledgegraph/testing/constraints-3.10.txt b/packages/google-cloud-enterpriseknowledgegraph/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-enterpriseknowledgegraph/testing/constraints-3.10.txt +++ b/packages/google-cloud-enterpriseknowledgegraph/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-enterpriseknowledgegraph/testing/constraints-3.13.txt b/packages/google-cloud-enterpriseknowledgegraph/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-enterpriseknowledgegraph/testing/constraints-3.13.txt +++ b/packages/google-cloud-enterpriseknowledgegraph/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-enterpriseknowledgegraph/testing/constraints-3.14.txt b/packages/google-cloud-enterpriseknowledgegraph/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-enterpriseknowledgegraph/testing/constraints-3.14.txt +++ b/packages/google-cloud-enterpriseknowledgegraph/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-error-reporting/google/cloud/errorreporting_v1beta1/__init__.py b/packages/google-cloud-error-reporting/google/cloud/errorreporting_v1beta1/__init__.py index 5f955693de7c..3d3ae8d23715 100644 --- a/packages/google-cloud-error-reporting/google/cloud/errorreporting_v1beta1/__init__.py +++ b/packages/google-cloud-error-reporting/google/cloud/errorreporting_v1beta1/__init__.py @@ -91,7 +91,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -120,9 +120,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-error-reporting/setup.py b/packages/google-cloud-error-reporting/setup.py index 58594b2a336c..42eeba4d2451 100644 --- a/packages/google-cloud-error-reporting/setup.py +++ b/packages/google-cloud-error-reporting/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/errorreporting/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", - "google-cloud-logging>=3.9.0, <4.0.0", + "google-cloud-logging>=3.12.0, <4.0.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-error-reporting" diff --git a/packages/google-cloud-error-reporting/testing/constraints-3.10.txt b/packages/google-cloud-error-reporting/testing/constraints-3.10.txt index 76cd237011f5..34448f9970b8 100644 --- a/packages/google-cloud-error-reporting/testing/constraints-3.10.txt +++ b/packages/google-cloud-error-reporting/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 -google-cloud-logging==3.9.0 +google-cloud-logging==3.12.0 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-error-reporting/testing/constraints-3.13.txt b/packages/google-cloud-error-reporting/testing/constraints-3.13.txt index a16f760afe46..ccb38bfd45df 100644 --- a/packages/google-cloud-error-reporting/testing/constraints-3.13.txt +++ b/packages/google-cloud-error-reporting/testing/constraints-3.13.txt @@ -10,4 +10,4 @@ google-auth>=2 google-cloud-logging>=3 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-error-reporting/testing/constraints-3.14.txt b/packages/google-cloud-error-reporting/testing/constraints-3.14.txt index a16f760afe46..ccb38bfd45df 100644 --- a/packages/google-cloud-error-reporting/testing/constraints-3.14.txt +++ b/packages/google-cloud-error-reporting/testing/constraints-3.14.txt @@ -10,4 +10,4 @@ google-auth>=2 google-cloud-logging>=3 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-essential-contacts/google/cloud/essential_contacts_v1/__init__.py b/packages/google-cloud-essential-contacts/google/cloud/essential_contacts_v1/__init__.py index 1478133cb01c..a01991f83306 100644 --- a/packages/google-cloud-essential-contacts/google/cloud/essential_contacts_v1/__init__.py +++ b/packages/google-cloud-essential-contacts/google/cloud/essential_contacts_v1/__init__.py @@ -66,7 +66,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -95,9 +95,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-essential-contacts/setup.py b/packages/google-cloud-essential-contacts/setup.py index 731fc7517951..8d37a95bd0c3 100644 --- a/packages/google-cloud-essential-contacts/setup.py +++ b/packages/google-cloud-essential-contacts/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/essential_contacts/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-essential-contacts" diff --git a/packages/google-cloud-essential-contacts/testing/constraints-3.10.txt b/packages/google-cloud-essential-contacts/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-essential-contacts/testing/constraints-3.10.txt +++ b/packages/google-cloud-essential-contacts/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-essential-contacts/testing/constraints-3.13.txt b/packages/google-cloud-essential-contacts/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-essential-contacts/testing/constraints-3.13.txt +++ b/packages/google-cloud-essential-contacts/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-essential-contacts/testing/constraints-3.14.txt b/packages/google-cloud-essential-contacts/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-essential-contacts/testing/constraints-3.14.txt +++ b/packages/google-cloud-essential-contacts/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-eventarc-publishing/google/cloud/eventarc_publishing_v1/__init__.py b/packages/google-cloud-eventarc-publishing/google/cloud/eventarc_publishing_v1/__init__.py index c294d86fde47..b8c9b2e30dbd 100644 --- a/packages/google-cloud-eventarc-publishing/google/cloud/eventarc_publishing_v1/__init__.py +++ b/packages/google-cloud-eventarc-publishing/google/cloud/eventarc_publishing_v1/__init__.py @@ -59,7 +59,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -88,9 +88,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-eventarc-publishing/setup.py b/packages/google-cloud-eventarc-publishing/setup.py index c99abf91b14d..e09c5416c1bf 100644 --- a/packages/google-cloud-eventarc-publishing/setup.py +++ b/packages/google-cloud-eventarc-publishing/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/eventarc_publishing/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-eventarc-publishing" diff --git a/packages/google-cloud-eventarc-publishing/testing/constraints-3.10.txt b/packages/google-cloud-eventarc-publishing/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-eventarc-publishing/testing/constraints-3.10.txt +++ b/packages/google-cloud-eventarc-publishing/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-eventarc-publishing/testing/constraints-3.13.txt b/packages/google-cloud-eventarc-publishing/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-eventarc-publishing/testing/constraints-3.13.txt +++ b/packages/google-cloud-eventarc-publishing/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-eventarc-publishing/testing/constraints-3.14.txt b/packages/google-cloud-eventarc-publishing/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-eventarc-publishing/testing/constraints-3.14.txt +++ b/packages/google-cloud-eventarc-publishing/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-eventarc/google/cloud/eventarc_v1/__init__.py b/packages/google-cloud-eventarc/google/cloud/eventarc_v1/__init__.py index d201f36ee0e7..0cd8d61edca5 100644 --- a/packages/google-cloud-eventarc/google/cloud/eventarc_v1/__init__.py +++ b/packages/google-cloud-eventarc/google/cloud/eventarc_v1/__init__.py @@ -122,7 +122,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -151,9 +151,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-eventarc/setup.py b/packages/google-cloud-eventarc/setup.py index 9c47a7ec37ff..ee3a7ae26e20 100644 --- a/packages/google-cloud-eventarc/setup.py +++ b/packages/google-cloud-eventarc/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/eventarc/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-eventarc" diff --git a/packages/google-cloud-eventarc/testing/constraints-3.10.txt b/packages/google-cloud-eventarc/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-eventarc/testing/constraints-3.10.txt +++ b/packages/google-cloud-eventarc/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-eventarc/testing/constraints-3.13.txt b/packages/google-cloud-eventarc/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-eventarc/testing/constraints-3.13.txt +++ b/packages/google-cloud-eventarc/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-eventarc/testing/constraints-3.14.txt b/packages/google-cloud-eventarc/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-eventarc/testing/constraints-3.14.txt +++ b/packages/google-cloud-eventarc/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-filestore/google/cloud/filestore_v1/__init__.py b/packages/google-cloud-filestore/google/cloud/filestore_v1/__init__.py index a6c56bc8612a..0a4d44d65ed4 100644 --- a/packages/google-cloud-filestore/google/cloud/filestore_v1/__init__.py +++ b/packages/google-cloud-filestore/google/cloud/filestore_v1/__init__.py @@ -84,7 +84,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -113,9 +113,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-filestore/setup.py b/packages/google-cloud-filestore/setup.py index 37dc387b12a4..55b1b9fa1d89 100644 --- a/packages/google-cloud-filestore/setup.py +++ b/packages/google-cloud-filestore/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/filestore/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "google-cloud-common >= 1.0.0, <2.0.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-filestore" diff --git a/packages/google-cloud-filestore/testing/constraints-3.10.txt b/packages/google-cloud-filestore/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-filestore/testing/constraints-3.10.txt +++ b/packages/google-cloud-filestore/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-filestore/testing/constraints-3.13.txt b/packages/google-cloud-filestore/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-filestore/testing/constraints-3.13.txt +++ b/packages/google-cloud-filestore/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-filestore/testing/constraints-3.14.txt b/packages/google-cloud-filestore/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-filestore/testing/constraints-3.14.txt +++ b/packages/google-cloud-filestore/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-financialservices/google/cloud/financialservices_v1/__init__.py b/packages/google-cloud-financialservices/google/cloud/financialservices_v1/__init__.py index 986dfd5f4f49..be0caee9ca28 100644 --- a/packages/google-cloud-financialservices/google/cloud/financialservices_v1/__init__.py +++ b/packages/google-cloud-financialservices/google/cloud/financialservices_v1/__init__.py @@ -125,7 +125,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -154,9 +154,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-financialservices/setup.py b/packages/google-cloud-financialservices/setup.py index a487f81da4e8..008e7a178a2a 100644 --- a/packages/google-cloud-financialservices/setup.py +++ b/packages/google-cloud-financialservices/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/financialservices/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-financialservices" diff --git a/packages/google-cloud-financialservices/testing/constraints-3.10.txt b/packages/google-cloud-financialservices/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-financialservices/testing/constraints-3.10.txt +++ b/packages/google-cloud-financialservices/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-financialservices/testing/constraints-3.13.txt b/packages/google-cloud-financialservices/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-financialservices/testing/constraints-3.13.txt +++ b/packages/google-cloud-financialservices/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-financialservices/testing/constraints-3.14.txt b/packages/google-cloud-financialservices/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-financialservices/testing/constraints-3.14.txt +++ b/packages/google-cloud-financialservices/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-functions/google/cloud/functions_v1/__init__.py b/packages/google-cloud-functions/google/cloud/functions_v1/__init__.py index 893977f8f305..1d830eecceab 100644 --- a/packages/google-cloud-functions/google/cloud/functions_v1/__init__.py +++ b/packages/google-cloud-functions/google/cloud/functions_v1/__init__.py @@ -76,7 +76,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -105,9 +105,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-functions/google/cloud/functions_v2/__init__.py b/packages/google-cloud-functions/google/cloud/functions_v2/__init__.py index 716df5469dd7..aff47bb1edcc 100644 --- a/packages/google-cloud-functions/google/cloud/functions_v2/__init__.py +++ b/packages/google-cloud-functions/google/cloud/functions_v2/__init__.py @@ -83,7 +83,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -112,9 +112,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-functions/setup.py b/packages/google-cloud-functions/setup.py index 10c335da2fca..4f9b20f341b5 100644 --- a/packages/google-cloud-functions/setup.py +++ b/packages/google-cloud-functions/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/functions/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-functions" diff --git a/packages/google-cloud-functions/testing/constraints-3.10.txt b/packages/google-cloud-functions/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-functions/testing/constraints-3.10.txt +++ b/packages/google-cloud-functions/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-functions/testing/constraints-3.13.txt b/packages/google-cloud-functions/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-functions/testing/constraints-3.13.txt +++ b/packages/google-cloud-functions/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-functions/testing/constraints-3.14.txt b/packages/google-cloud-functions/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-functions/testing/constraints-3.14.txt +++ b/packages/google-cloud-functions/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-gdchardwaremanagement/google/cloud/gdchardwaremanagement_v1alpha/__init__.py b/packages/google-cloud-gdchardwaremanagement/google/cloud/gdchardwaremanagement_v1alpha/__init__.py index ea810cfbb178..2ca2bc0ac2ae 100644 --- a/packages/google-cloud-gdchardwaremanagement/google/cloud/gdchardwaremanagement_v1alpha/__init__.py +++ b/packages/google-cloud-gdchardwaremanagement/google/cloud/gdchardwaremanagement_v1alpha/__init__.py @@ -127,7 +127,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -156,9 +156,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-gdchardwaremanagement/setup.py b/packages/google-cloud-gdchardwaremanagement/setup.py index 22c537fdf4cc..ce8aa43cbe25 100644 --- a/packages/google-cloud-gdchardwaremanagement/setup.py +++ b/packages/google-cloud-gdchardwaremanagement/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/gdchardwaremanagement/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-gdchardwaremanagement" diff --git a/packages/google-cloud-gdchardwaremanagement/testing/constraints-3.10.txt b/packages/google-cloud-gdchardwaremanagement/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-gdchardwaremanagement/testing/constraints-3.10.txt +++ b/packages/google-cloud-gdchardwaremanagement/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-gdchardwaremanagement/testing/constraints-3.13.txt b/packages/google-cloud-gdchardwaremanagement/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-gdchardwaremanagement/testing/constraints-3.13.txt +++ b/packages/google-cloud-gdchardwaremanagement/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-gdchardwaremanagement/testing/constraints-3.14.txt b/packages/google-cloud-gdchardwaremanagement/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-gdchardwaremanagement/testing/constraints-3.14.txt +++ b/packages/google-cloud-gdchardwaremanagement/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1/__init__.py b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1/__init__.py index 0f4040145eb1..a2c89951668a 100644 --- a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1/__init__.py +++ b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1/__init__.py @@ -144,7 +144,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -173,9 +173,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1alpha/__init__.py b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1alpha/__init__.py index f8d496d36869..fae0dc1ca676 100644 --- a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1alpha/__init__.py +++ b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1alpha/__init__.py @@ -149,7 +149,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -178,9 +178,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/__init__.py b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/__init__.py index db78fe9542c2..5c98a2e1694d 100644 --- a/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/__init__.py +++ b/packages/google-cloud-geminidataanalytics/google/cloud/geminidataanalytics_v1beta/__init__.py @@ -161,7 +161,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -190,9 +190,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-geminidataanalytics/setup.py b/packages/google-cloud-geminidataanalytics/setup.py index cb8dfd005a02..1face59793e2 100644 --- a/packages/google-cloud-geminidataanalytics/setup.py +++ b/packages/google-cloud-geminidataanalytics/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/geminidataanalytics/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-geminidataanalytics" diff --git a/packages/google-cloud-geminidataanalytics/testing/constraints-3.10.txt b/packages/google-cloud-geminidataanalytics/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-geminidataanalytics/testing/constraints-3.10.txt +++ b/packages/google-cloud-geminidataanalytics/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-geminidataanalytics/testing/constraints-3.13.txt b/packages/google-cloud-geminidataanalytics/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-geminidataanalytics/testing/constraints-3.13.txt +++ b/packages/google-cloud-geminidataanalytics/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-geminidataanalytics/testing/constraints-3.14.txt b/packages/google-cloud-geminidataanalytics/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-geminidataanalytics/testing/constraints-3.14.txt +++ b/packages/google-cloud-geminidataanalytics/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-gke-backup/google/cloud/gke_backup_v1/__init__.py b/packages/google-cloud-gke-backup/google/cloud/gke_backup_v1/__init__.py index 0cab7fc74563..4c800a10e5ea 100644 --- a/packages/google-cloud-gke-backup/google/cloud/gke_backup_v1/__init__.py +++ b/packages/google-cloud-gke-backup/google/cloud/gke_backup_v1/__init__.py @@ -124,7 +124,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -153,9 +153,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-gke-backup/setup.py b/packages/google-cloud-gke-backup/setup.py index 7257d38c1fc7..0956ed99ec2e 100644 --- a/packages/google-cloud-gke-backup/setup.py +++ b/packages/google-cloud-gke-backup/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/gke_backup/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-gke-backup" diff --git a/packages/google-cloud-gke-backup/testing/constraints-3.10.txt b/packages/google-cloud-gke-backup/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-gke-backup/testing/constraints-3.10.txt +++ b/packages/google-cloud-gke-backup/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-gke-backup/testing/constraints-3.13.txt b/packages/google-cloud-gke-backup/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-gke-backup/testing/constraints-3.13.txt +++ b/packages/google-cloud-gke-backup/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-gke-backup/testing/constraints-3.14.txt b/packages/google-cloud-gke-backup/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-gke-backup/testing/constraints-3.14.txt +++ b/packages/google-cloud-gke-backup/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-gke-connect-gateway/google/cloud/gkeconnect/gateway_v1/__init__.py b/packages/google-cloud-gke-connect-gateway/google/cloud/gkeconnect/gateway_v1/__init__.py index a2c882215730..a95668837fc8 100644 --- a/packages/google-cloud-gke-connect-gateway/google/cloud/gkeconnect/gateway_v1/__init__.py +++ b/packages/google-cloud-gke-connect-gateway/google/cloud/gkeconnect/gateway_v1/__init__.py @@ -51,7 +51,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -80,9 +80,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-gke-connect-gateway/google/cloud/gkeconnect/gateway_v1beta1/__init__.py b/packages/google-cloud-gke-connect-gateway/google/cloud/gkeconnect/gateway_v1beta1/__init__.py index 376eb83aeb6b..a691f751aaae 100644 --- a/packages/google-cloud-gke-connect-gateway/google/cloud/gkeconnect/gateway_v1beta1/__init__.py +++ b/packages/google-cloud-gke-connect-gateway/google/cloud/gkeconnect/gateway_v1beta1/__init__.py @@ -51,7 +51,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -80,9 +80,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-gke-connect-gateway/setup.py b/packages/google-cloud-gke-connect-gateway/setup.py index 95296f191dc0..2cfe3b1ab8b0 100644 --- a/packages/google-cloud-gke-connect-gateway/setup.py +++ b/packages/google-cloud-gke-connect-gateway/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/gkeconnect/gateway/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-gke-connect-gateway" diff --git a/packages/google-cloud-gke-connect-gateway/testing/constraints-3.10.txt b/packages/google-cloud-gke-connect-gateway/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-gke-connect-gateway/testing/constraints-3.10.txt +++ b/packages/google-cloud-gke-connect-gateway/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-gke-connect-gateway/testing/constraints-3.13.txt b/packages/google-cloud-gke-connect-gateway/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-gke-connect-gateway/testing/constraints-3.13.txt +++ b/packages/google-cloud-gke-connect-gateway/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-gke-connect-gateway/testing/constraints-3.14.txt b/packages/google-cloud-gke-connect-gateway/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-gke-connect-gateway/testing/constraints-3.14.txt +++ b/packages/google-cloud-gke-connect-gateway/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-gke-hub/google/cloud/gkehub_v1/__init__.py b/packages/google-cloud-gke-hub/google/cloud/gkehub_v1/__init__.py index 74e2a7e10d9f..c30bdf8ef380 100644 --- a/packages/google-cloud-gke-hub/google/cloud/gkehub_v1/__init__.py +++ b/packages/google-cloud-gke-hub/google/cloud/gkehub_v1/__init__.py @@ -150,7 +150,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -179,9 +179,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-gke-hub/google/cloud/gkehub_v1beta1/__init__.py b/packages/google-cloud-gke-hub/google/cloud/gkehub_v1beta1/__init__.py index 1089fbd9be79..eaa69c0a8b3b 100644 --- a/packages/google-cloud-gke-hub/google/cloud/gkehub_v1beta1/__init__.py +++ b/packages/google-cloud-gke-hub/google/cloud/gkehub_v1beta1/__init__.py @@ -85,7 +85,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -114,9 +114,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-gke-hub/setup.py b/packages/google-cloud-gke-hub/setup.py index e5a9ecc0bec0..c65cb02dd063 100644 --- a/packages/google-cloud-gke-hub/setup.py +++ b/packages/google-cloud-gke-hub/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/gkehub/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpc-google-iam-v1 >=0.12.4, <1.0.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-gke-hub" diff --git a/packages/google-cloud-gke-hub/testing/constraints-3.10.txt b/packages/google-cloud-gke-hub/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-gke-hub/testing/constraints-3.10.txt +++ b/packages/google-cloud-gke-hub/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-gke-hub/testing/constraints-3.13.txt b/packages/google-cloud-gke-hub/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-gke-hub/testing/constraints-3.13.txt +++ b/packages/google-cloud-gke-hub/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-gke-hub/testing/constraints-3.14.txt b/packages/google-cloud-gke-hub/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-gke-hub/testing/constraints-3.14.txt +++ b/packages/google-cloud-gke-hub/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-gke-multicloud/google/cloud/gke_multicloud_v1/__init__.py b/packages/google-cloud-gke-multicloud/google/cloud/gke_multicloud_v1/__init__.py index 4e08b4266842..8b894a676a8d 100644 --- a/packages/google-cloud-gke-multicloud/google/cloud/gke_multicloud_v1/__init__.py +++ b/packages/google-cloud-gke-multicloud/google/cloud/gke_multicloud_v1/__init__.py @@ -204,7 +204,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -233,9 +233,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-gke-multicloud/setup.py b/packages/google-cloud-gke-multicloud/setup.py index 248c51dc4af8..01e4337de097 100644 --- a/packages/google-cloud-gke-multicloud/setup.py +++ b/packages/google-cloud-gke-multicloud/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/gke_multicloud/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-gke-multicloud" diff --git a/packages/google-cloud-gke-multicloud/testing/constraints-3.10.txt b/packages/google-cloud-gke-multicloud/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-gke-multicloud/testing/constraints-3.10.txt +++ b/packages/google-cloud-gke-multicloud/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-gke-multicloud/testing/constraints-3.13.txt b/packages/google-cloud-gke-multicloud/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-gke-multicloud/testing/constraints-3.13.txt +++ b/packages/google-cloud-gke-multicloud/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-gke-multicloud/testing/constraints-3.14.txt b/packages/google-cloud-gke-multicloud/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-gke-multicloud/testing/constraints-3.14.txt +++ b/packages/google-cloud-gke-multicloud/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-gkerecommender/google/cloud/gkerecommender_v1/__init__.py b/packages/google-cloud-gkerecommender/google/cloud/gkerecommender_v1/__init__.py index f65b5153e1ba..76070ed5a4c4 100644 --- a/packages/google-cloud-gkerecommender/google/cloud/gkerecommender_v1/__init__.py +++ b/packages/google-cloud-gkerecommender/google/cloud/gkerecommender_v1/__init__.py @@ -79,7 +79,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -108,9 +108,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-gkerecommender/setup.py b/packages/google-cloud-gkerecommender/setup.py index cac4e5c4b9c5..106af27bef79 100644 --- a/packages/google-cloud-gkerecommender/setup.py +++ b/packages/google-cloud-gkerecommender/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/gkerecommender/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-gkerecommender" diff --git a/packages/google-cloud-gkerecommender/testing/constraints-3.10.txt b/packages/google-cloud-gkerecommender/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-gkerecommender/testing/constraints-3.10.txt +++ b/packages/google-cloud-gkerecommender/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-gkerecommender/testing/constraints-3.13.txt b/packages/google-cloud-gkerecommender/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-gkerecommender/testing/constraints-3.13.txt +++ b/packages/google-cloud-gkerecommender/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-gkerecommender/testing/constraints-3.14.txt b/packages/google-cloud-gkerecommender/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-gkerecommender/testing/constraints-3.14.txt +++ b/packages/google-cloud-gkerecommender/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-gsuiteaddons/google/cloud/gsuiteaddons_v1/__init__.py b/packages/google-cloud-gsuiteaddons/google/cloud/gsuiteaddons_v1/__init__.py index 423ed12593a9..d9e146ab0e75 100644 --- a/packages/google-cloud-gsuiteaddons/google/cloud/gsuiteaddons_v1/__init__.py +++ b/packages/google-cloud-gsuiteaddons/google/cloud/gsuiteaddons_v1/__init__.py @@ -66,7 +66,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -95,9 +95,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-gsuiteaddons/setup.py b/packages/google-cloud-gsuiteaddons/setup.py index a2d572a5e832..b1a86f9ee763 100644 --- a/packages/google-cloud-gsuiteaddons/setup.py +++ b/packages/google-cloud-gsuiteaddons/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/gsuiteaddons/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "google-apps-script-type >= 0.2.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "google-apps-script-type >= 0.3.14, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-gsuiteaddons" diff --git a/packages/google-cloud-gsuiteaddons/testing/constraints-3.10.txt b/packages/google-cloud-gsuiteaddons/testing/constraints-3.10.txt index 287fc3345b5d..c066e0be98f6 100644 --- a/packages/google-cloud-gsuiteaddons/testing/constraints-3.10.txt +++ b/packages/google-cloud-gsuiteaddons/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -google-apps-script-type==0.2.0 +proto-plus==1.26.1 +protobuf==6.33.5 +google-apps-script-type==0.3.14 diff --git a/packages/google-cloud-gsuiteaddons/testing/constraints-3.13.txt b/packages/google-cloud-gsuiteaddons/testing/constraints-3.13.txt index 0d0de33f3329..04f0ffb57ea2 100644 --- a/packages/google-cloud-gsuiteaddons/testing/constraints-3.13.txt +++ b/packages/google-cloud-gsuiteaddons/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-apps-script-type>=0 diff --git a/packages/google-cloud-gsuiteaddons/testing/constraints-3.14.txt b/packages/google-cloud-gsuiteaddons/testing/constraints-3.14.txt index 0d0de33f3329..04f0ffb57ea2 100644 --- a/packages/google-cloud-gsuiteaddons/testing/constraints-3.14.txt +++ b/packages/google-cloud-gsuiteaddons/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-apps-script-type>=0 diff --git a/packages/google-cloud-hypercomputecluster/google/cloud/hypercomputecluster_v1/__init__.py b/packages/google-cloud-hypercomputecluster/google/cloud/hypercomputecluster_v1/__init__.py index 74df1d167008..55c9949707bc 100644 --- a/packages/google-cloud-hypercomputecluster/google/cloud/hypercomputecluster_v1/__init__.py +++ b/packages/google-cloud-hypercomputecluster/google/cloud/hypercomputecluster_v1/__init__.py @@ -124,7 +124,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -153,9 +153,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-hypercomputecluster/google/cloud/hypercomputecluster_v1beta/__init__.py b/packages/google-cloud-hypercomputecluster/google/cloud/hypercomputecluster_v1beta/__init__.py index 8c063839fb57..c5d5c86e2005 100644 --- a/packages/google-cloud-hypercomputecluster/google/cloud/hypercomputecluster_v1beta/__init__.py +++ b/packages/google-cloud-hypercomputecluster/google/cloud/hypercomputecluster_v1beta/__init__.py @@ -97,7 +97,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -126,9 +126,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-hypercomputecluster/setup.py b/packages/google-cloud-hypercomputecluster/setup.py index 30775e33ba78..509bc3c7c319 100644 --- a/packages/google-cloud-hypercomputecluster/setup.py +++ b/packages/google-cloud-hypercomputecluster/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/hypercomputecluster/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-hypercomputecluster" diff --git a/packages/google-cloud-hypercomputecluster/testing/constraints-3.10.txt b/packages/google-cloud-hypercomputecluster/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-hypercomputecluster/testing/constraints-3.10.txt +++ b/packages/google-cloud-hypercomputecluster/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-hypercomputecluster/testing/constraints-3.13.txt b/packages/google-cloud-hypercomputecluster/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-hypercomputecluster/testing/constraints-3.13.txt +++ b/packages/google-cloud-hypercomputecluster/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-hypercomputecluster/testing/constraints-3.14.txt b/packages/google-cloud-hypercomputecluster/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-hypercomputecluster/testing/constraints-3.14.txt +++ b/packages/google-cloud-hypercomputecluster/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-iam-logging/google/cloud/iam_logging_v1/__init__.py b/packages/google-cloud-iam-logging/google/cloud/iam_logging_v1/__init__.py index a80d18dda2d8..e6147d2f88a8 100644 --- a/packages/google-cloud-iam-logging/google/cloud/iam_logging_v1/__init__.py +++ b/packages/google-cloud-iam-logging/google/cloud/iam_logging_v1/__init__.py @@ -50,7 +50,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -79,9 +79,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-iam-logging/setup.py b/packages/google-cloud-iam-logging/setup.py index 910ca3483003..88b3288d40c2 100644 --- a/packages/google-cloud-iam-logging/setup.py +++ b/packages/google-cloud-iam-logging/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/iam_logging/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-iam-logging" diff --git a/packages/google-cloud-iam-logging/testing/constraints-3.10.txt b/packages/google-cloud-iam-logging/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-iam-logging/testing/constraints-3.10.txt +++ b/packages/google-cloud-iam-logging/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-iam-logging/testing/constraints-3.13.txt b/packages/google-cloud-iam-logging/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-iam-logging/testing/constraints-3.13.txt +++ b/packages/google-cloud-iam-logging/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-iam-logging/testing/constraints-3.14.txt b/packages/google-cloud-iam-logging/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-iam-logging/testing/constraints-3.14.txt +++ b/packages/google-cloud-iam-logging/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-iam/google/cloud/iam_admin_v1/__init__.py b/packages/google-cloud-iam/google/cloud/iam_admin_v1/__init__.py index 9673af81a7dc..cdf1b55d313f 100644 --- a/packages/google-cloud-iam/google/cloud/iam_admin_v1/__init__.py +++ b/packages/google-cloud-iam/google/cloud/iam_admin_v1/__init__.py @@ -100,7 +100,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -129,9 +129,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-iam/google/cloud/iam_credentials_v1/__init__.py b/packages/google-cloud-iam/google/cloud/iam_credentials_v1/__init__.py index 5e89b36bdeeb..d2db0912b63e 100644 --- a/packages/google-cloud-iam/google/cloud/iam_credentials_v1/__init__.py +++ b/packages/google-cloud-iam/google/cloud/iam_credentials_v1/__init__.py @@ -60,7 +60,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -89,9 +89,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-iam/google/cloud/iam_v2/__init__.py b/packages/google-cloud-iam/google/cloud/iam_v2/__init__.py index 5ca508743313..1d138b8b035d 100644 --- a/packages/google-cloud-iam/google/cloud/iam_v2/__init__.py +++ b/packages/google-cloud-iam/google/cloud/iam_v2/__init__.py @@ -62,7 +62,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -91,9 +91,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-iam/google/cloud/iam_v2beta/__init__.py b/packages/google-cloud-iam/google/cloud/iam_v2beta/__init__.py index 58dad9e825e2..56b7def8936d 100644 --- a/packages/google-cloud-iam/google/cloud/iam_v2beta/__init__.py +++ b/packages/google-cloud-iam/google/cloud/iam_v2beta/__init__.py @@ -62,7 +62,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -91,9 +91,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-iam/google/cloud/iam_v3/__init__.py b/packages/google-cloud-iam/google/cloud/iam_v3/__init__.py index ded72677d01f..6fe5d43a5f6a 100644 --- a/packages/google-cloud-iam/google/cloud/iam_v3/__init__.py +++ b/packages/google-cloud-iam/google/cloud/iam_v3/__init__.py @@ -81,7 +81,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -110,9 +110,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-iam/google/cloud/iam_v3beta/__init__.py b/packages/google-cloud-iam/google/cloud/iam_v3beta/__init__.py index af90e3210d00..f4ef2ec89dc3 100644 --- a/packages/google-cloud-iam/google/cloud/iam_v3beta/__init__.py +++ b/packages/google-cloud-iam/google/cloud/iam_v3beta/__init__.py @@ -97,7 +97,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -126,9 +126,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-iam/setup.py b/packages/google-cloud-iam/setup.py index daf8695c129d..a4f98034677d 100644 --- a/packages/google-cloud-iam/setup.py +++ b/packages/google-cloud-iam/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/iam/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpc-google-iam-v1 >=0.12.4, <1.0.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-iam" diff --git a/packages/google-cloud-iam/testing/constraints-3.10.txt b/packages/google-cloud-iam/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-iam/testing/constraints-3.10.txt +++ b/packages/google-cloud-iam/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-iam/testing/constraints-3.13.txt b/packages/google-cloud-iam/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-iam/testing/constraints-3.13.txt +++ b/packages/google-cloud-iam/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-iam/testing/constraints-3.14.txt b/packages/google-cloud-iam/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-iam/testing/constraints-3.14.txt +++ b/packages/google-cloud-iam/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-iamconnectorcredentials/google/cloud/iamconnectorcredentials_v1alpha/__init__.py b/packages/google-cloud-iamconnectorcredentials/google/cloud/iamconnectorcredentials_v1alpha/__init__.py index 9b4a28bc115d..8eb2f7402346 100644 --- a/packages/google-cloud-iamconnectorcredentials/google/cloud/iamconnectorcredentials_v1alpha/__init__.py +++ b/packages/google-cloud-iamconnectorcredentials/google/cloud/iamconnectorcredentials_v1alpha/__init__.py @@ -62,7 +62,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -91,9 +91,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-iamconnectorcredentials/setup.py b/packages/google-cloud-iamconnectorcredentials/setup.py index db191dee7c5b..5d435da7c318 100644 --- a/packages/google-cloud-iamconnectorcredentials/setup.py +++ b/packages/google-cloud-iamconnectorcredentials/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/iamconnectorcredentials/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-iamconnectorcredentials" diff --git a/packages/google-cloud-iamconnectorcredentials/testing/constraints-3.10.txt b/packages/google-cloud-iamconnectorcredentials/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-iamconnectorcredentials/testing/constraints-3.10.txt +++ b/packages/google-cloud-iamconnectorcredentials/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-iamconnectorcredentials/testing/constraints-3.13.txt b/packages/google-cloud-iamconnectorcredentials/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-iamconnectorcredentials/testing/constraints-3.13.txt +++ b/packages/google-cloud-iamconnectorcredentials/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-iamconnectorcredentials/testing/constraints-3.14.txt b/packages/google-cloud-iamconnectorcredentials/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-iamconnectorcredentials/testing/constraints-3.14.txt +++ b/packages/google-cloud-iamconnectorcredentials/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-iap/google/cloud/iap_v1/__init__.py b/packages/google-cloud-iap/google/cloud/iap_v1/__init__.py index 86b512280851..4ce251b0b98f 100644 --- a/packages/google-cloud-iap/google/cloud/iap_v1/__init__.py +++ b/packages/google-cloud-iap/google/cloud/iap_v1/__init__.py @@ -95,7 +95,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -124,9 +124,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-iap/setup.py b/packages/google-cloud-iap/setup.py index 4bf15966b7bd..5212cc518e8f 100644 --- a/packages/google-cloud-iap/setup.py +++ b/packages/google-cloud-iap/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/iap/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-iap" diff --git a/packages/google-cloud-iap/testing/constraints-3.10.txt b/packages/google-cloud-iap/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-iap/testing/constraints-3.10.txt +++ b/packages/google-cloud-iap/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-iap/testing/constraints-3.13.txt b/packages/google-cloud-iap/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-iap/testing/constraints-3.13.txt +++ b/packages/google-cloud-iap/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-iap/testing/constraints-3.14.txt b/packages/google-cloud-iap/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-iap/testing/constraints-3.14.txt +++ b/packages/google-cloud-iap/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-ids/google/cloud/ids_v1/__init__.py b/packages/google-cloud-ids/google/cloud/ids_v1/__init__.py index 318d9606e30b..598e4ca18f93 100644 --- a/packages/google-cloud-ids/google/cloud/ids_v1/__init__.py +++ b/packages/google-cloud-ids/google/cloud/ids_v1/__init__.py @@ -59,7 +59,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -88,9 +88,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-ids/setup.py b/packages/google-cloud-ids/setup.py index 83d09ccc178f..aeaa641dfbed 100644 --- a/packages/google-cloud-ids/setup.py +++ b/packages/google-cloud-ids/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/ids/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-ids" diff --git a/packages/google-cloud-ids/testing/constraints-3.10.txt b/packages/google-cloud-ids/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-ids/testing/constraints-3.10.txt +++ b/packages/google-cloud-ids/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-ids/testing/constraints-3.13.txt b/packages/google-cloud-ids/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-ids/testing/constraints-3.13.txt +++ b/packages/google-cloud-ids/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-ids/testing/constraints-3.14.txt b/packages/google-cloud-ids/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-ids/testing/constraints-3.14.txt +++ b/packages/google-cloud-ids/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-kms-inventory/google/cloud/kms_inventory_v1/__init__.py b/packages/google-cloud-kms-inventory/google/cloud/kms_inventory_v1/__init__.py index 36256352e82c..a2b9d1840e6c 100644 --- a/packages/google-cloud-kms-inventory/google/cloud/kms_inventory_v1/__init__.py +++ b/packages/google-cloud-kms-inventory/google/cloud/kms_inventory_v1/__init__.py @@ -67,7 +67,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -96,9 +96,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-kms-inventory/setup.py b/packages/google-cloud-kms-inventory/setup.py index 8ee40e58be3d..af10201eddf1 100644 --- a/packages/google-cloud-kms-inventory/setup.py +++ b/packages/google-cloud-kms-inventory/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/kms_inventory/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "google-cloud-kms >= 2.13.0, <4.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "google-cloud-kms >= 3.4.1, <4.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-kms-inventory" diff --git a/packages/google-cloud-kms-inventory/testing/constraints-3.10.txt b/packages/google-cloud-kms-inventory/testing/constraints-3.10.txt index c7005b0b2be5..2793afc2cd1c 100644 --- a/packages/google-cloud-kms-inventory/testing/constraints-3.10.txt +++ b/packages/google-cloud-kms-inventory/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -google-cloud-kms==2.13.0 +proto-plus==1.26.1 +protobuf==6.33.5 +google-cloud-kms==3.4.1 diff --git a/packages/google-cloud-kms-inventory/testing/constraints-3.13.txt b/packages/google-cloud-kms-inventory/testing/constraints-3.13.txt index d5a2c60c2972..8573f096b0fa 100644 --- a/packages/google-cloud-kms-inventory/testing/constraints-3.13.txt +++ b/packages/google-cloud-kms-inventory/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-cloud-kms>=3 diff --git a/packages/google-cloud-kms-inventory/testing/constraints-3.14.txt b/packages/google-cloud-kms-inventory/testing/constraints-3.14.txt index d5a2c60c2972..8573f096b0fa 100644 --- a/packages/google-cloud-kms-inventory/testing/constraints-3.14.txt +++ b/packages/google-cloud-kms-inventory/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-cloud-kms>=3 diff --git a/packages/google-cloud-kms/google/cloud/kms_v1/__init__.py b/packages/google-cloud-kms/google/cloud/kms_v1/__init__.py index d56fee18f02b..13dc1bc42ae5 100644 --- a/packages/google-cloud-kms/google/cloud/kms_v1/__init__.py +++ b/packages/google-cloud-kms/google/cloud/kms_v1/__init__.py @@ -177,7 +177,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -206,9 +206,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-kms/setup.py b/packages/google-cloud-kms/setup.py index 91013ea6d3b3..27d191e70382 100644 --- a/packages/google-cloud-kms/setup.py +++ b/packages/google-cloud-kms/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/kms/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-kms" diff --git a/packages/google-cloud-kms/testing/constraints-3.10.txt b/packages/google-cloud-kms/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-kms/testing/constraints-3.10.txt +++ b/packages/google-cloud-kms/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-kms/testing/constraints-3.13.txt b/packages/google-cloud-kms/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-kms/testing/constraints-3.13.txt +++ b/packages/google-cloud-kms/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-kms/testing/constraints-3.14.txt b/packages/google-cloud-kms/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-kms/testing/constraints-3.14.txt +++ b/packages/google-cloud-kms/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-language/google/cloud/language_v1/__init__.py b/packages/google-cloud-language/google/cloud/language_v1/__init__.py index 697de8232046..d8cacd6bbcfd 100644 --- a/packages/google-cloud-language/google/cloud/language_v1/__init__.py +++ b/packages/google-cloud-language/google/cloud/language_v1/__init__.py @@ -78,7 +78,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -107,9 +107,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-language/google/cloud/language_v1beta2/__init__.py b/packages/google-cloud-language/google/cloud/language_v1beta2/__init__.py index a2523883aaf2..a2246a7f2db3 100644 --- a/packages/google-cloud-language/google/cloud/language_v1beta2/__init__.py +++ b/packages/google-cloud-language/google/cloud/language_v1beta2/__init__.py @@ -78,7 +78,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -107,9 +107,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-language/google/cloud/language_v2/__init__.py b/packages/google-cloud-language/google/cloud/language_v2/__init__.py index 12680d0d3483..538ae8f15044 100644 --- a/packages/google-cloud-language/google/cloud/language_v2/__init__.py +++ b/packages/google-cloud-language/google/cloud/language_v2/__init__.py @@ -70,7 +70,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -99,9 +99,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-language/setup.py b/packages/google-cloud-language/setup.py index 422879cbb6fa..fcb9cefd238e 100644 --- a/packages/google-cloud-language/setup.py +++ b/packages/google-cloud-language/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/language/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-language" diff --git a/packages/google-cloud-language/testing/constraints-3.10.txt b/packages/google-cloud-language/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-language/testing/constraints-3.10.txt +++ b/packages/google-cloud-language/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-language/testing/constraints-3.13.txt b/packages/google-cloud-language/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-language/testing/constraints-3.13.txt +++ b/packages/google-cloud-language/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-language/testing/constraints-3.14.txt b/packages/google-cloud-language/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-language/testing/constraints-3.14.txt +++ b/packages/google-cloud-language/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-licensemanager/google/cloud/licensemanager_v1/__init__.py b/packages/google-cloud-licensemanager/google/cloud/licensemanager_v1/__init__.py index ef8e5a477c03..b1fcba013d0d 100644 --- a/packages/google-cloud-licensemanager/google/cloud/licensemanager_v1/__init__.py +++ b/packages/google-cloud-licensemanager/google/cloud/licensemanager_v1/__init__.py @@ -82,7 +82,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -111,9 +111,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-licensemanager/setup.py b/packages/google-cloud-licensemanager/setup.py index e6ae92e3cc25..344bc7e965f1 100644 --- a/packages/google-cloud-licensemanager/setup.py +++ b/packages/google-cloud-licensemanager/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/licensemanager/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-licensemanager" diff --git a/packages/google-cloud-licensemanager/testing/constraints-3.10.txt b/packages/google-cloud-licensemanager/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-licensemanager/testing/constraints-3.10.txt +++ b/packages/google-cloud-licensemanager/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-licensemanager/testing/constraints-3.13.txt b/packages/google-cloud-licensemanager/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-licensemanager/testing/constraints-3.13.txt +++ b/packages/google-cloud-licensemanager/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-licensemanager/testing/constraints-3.14.txt b/packages/google-cloud-licensemanager/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-licensemanager/testing/constraints-3.14.txt +++ b/packages/google-cloud-licensemanager/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-life-sciences/google/cloud/lifesciences_v2beta/__init__.py b/packages/google-cloud-life-sciences/google/cloud/lifesciences_v2beta/__init__.py index cc2e76ddeafb..624a50735ea2 100644 --- a/packages/google-cloud-life-sciences/google/cloud/lifesciences_v2beta/__init__.py +++ b/packages/google-cloud-life-sciences/google/cloud/lifesciences_v2beta/__init__.py @@ -83,7 +83,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -112,9 +112,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-life-sciences/setup.py b/packages/google-cloud-life-sciences/setup.py index c8809c0aaaed..31b60e1195cf 100644 --- a/packages/google-cloud-life-sciences/setup.py +++ b/packages/google-cloud-life-sciences/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/lifesciences/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-life-sciences" diff --git a/packages/google-cloud-life-sciences/testing/constraints-3.10.txt b/packages/google-cloud-life-sciences/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-life-sciences/testing/constraints-3.10.txt +++ b/packages/google-cloud-life-sciences/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-life-sciences/testing/constraints-3.13.txt b/packages/google-cloud-life-sciences/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-life-sciences/testing/constraints-3.13.txt +++ b/packages/google-cloud-life-sciences/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-life-sciences/testing/constraints-3.14.txt b/packages/google-cloud-life-sciences/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-life-sciences/testing/constraints-3.14.txt +++ b/packages/google-cloud-life-sciences/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-locationfinder/google/cloud/locationfinder_v1/__init__.py b/packages/google-cloud-locationfinder/google/cloud/locationfinder_v1/__init__.py index 2fdff819e6d6..ce76365ea1c2 100644 --- a/packages/google-cloud-locationfinder/google/cloud/locationfinder_v1/__init__.py +++ b/packages/google-cloud-locationfinder/google/cloud/locationfinder_v1/__init__.py @@ -61,7 +61,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -90,9 +90,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-locationfinder/setup.py b/packages/google-cloud-locationfinder/setup.py index db61f4b9fc5b..fa31eb157ebe 100644 --- a/packages/google-cloud-locationfinder/setup.py +++ b/packages/google-cloud-locationfinder/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/locationfinder/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-locationfinder" diff --git a/packages/google-cloud-locationfinder/testing/constraints-3.10.txt b/packages/google-cloud-locationfinder/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-locationfinder/testing/constraints-3.10.txt +++ b/packages/google-cloud-locationfinder/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-locationfinder/testing/constraints-3.13.txt b/packages/google-cloud-locationfinder/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-locationfinder/testing/constraints-3.13.txt +++ b/packages/google-cloud-locationfinder/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-locationfinder/testing/constraints-3.14.txt b/packages/google-cloud-locationfinder/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-locationfinder/testing/constraints-3.14.txt +++ b/packages/google-cloud-locationfinder/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-logging/setup.py b/packages/google-cloud-logging/setup.py index 97568c52429b..390fb322c872 100644 --- a/packages/google-cloud-logging/setup.py +++ b/packages/google-cloud-logging/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/logging/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,20 +42,19 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "google-cloud-appengine-logging>=0.1.3, <2.0.0", - "google-cloud-audit-log >= 0.3.1, < 1.0.0", + "google-cloud-audit-log >= 0.3.2, < 1.0.0", "google-cloud-core >= 2.0.0, <3.0.0", - "grpc-google-iam-v1 >=0.12.4, <1.0.0", + "grpc-google-iam-v1 >=0.14.2, <1.0.0", "opentelemetry-api >= 1.16.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-logging" diff --git a/packages/google-cloud-logging/testing/constraints-3.10.txt b/packages/google-cloud-logging/testing/constraints-3.10.txt index 3ff5c516b82a..d3324144e20d 100644 --- a/packages/google-cloud-logging/testing/constraints-3.10.txt +++ b/packages/google-cloud-logging/testing/constraints-3.10.txt @@ -4,13 +4,13 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 google-cloud-appengine-logging==0.1.3 -google-cloud-audit-log==0.3.1 +google-cloud-audit-log==0.3.2 google-cloud-core==2.0.0 -grpc-google-iam-v1==0.12.4 +grpc-google-iam-v1==0.14.2 opentelemetry-api==1.16.0 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-logging/testing/constraints-3.13.txt b/packages/google-cloud-logging/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-logging/testing/constraints-3.13.txt +++ b/packages/google-cloud-logging/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-logging/testing/constraints-3.14.txt b/packages/google-cloud-logging/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-logging/testing/constraints-3.14.txt +++ b/packages/google-cloud-logging/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-lustre/google/cloud/lustre_v1/__init__.py b/packages/google-cloud-lustre/google/cloud/lustre_v1/__init__.py index 4067f922809a..ff29229acbe0 100644 --- a/packages/google-cloud-lustre/google/cloud/lustre_v1/__init__.py +++ b/packages/google-cloud-lustre/google/cloud/lustre_v1/__init__.py @@ -75,7 +75,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -104,9 +104,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-lustre/setup.py b/packages/google-cloud-lustre/setup.py index 79ffe101e41f..7bfcba2bfa1b 100644 --- a/packages/google-cloud-lustre/setup.py +++ b/packages/google-cloud-lustre/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/lustre/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-lustre" diff --git a/packages/google-cloud-lustre/testing/constraints-3.10.txt b/packages/google-cloud-lustre/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-lustre/testing/constraints-3.10.txt +++ b/packages/google-cloud-lustre/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-lustre/testing/constraints-3.13.txt b/packages/google-cloud-lustre/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-lustre/testing/constraints-3.13.txt +++ b/packages/google-cloud-lustre/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-lustre/testing/constraints-3.14.txt b/packages/google-cloud-lustre/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-lustre/testing/constraints-3.14.txt +++ b/packages/google-cloud-lustre/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-maintenance-api/google/cloud/maintenance_api_v1/__init__.py b/packages/google-cloud-maintenance-api/google/cloud/maintenance_api_v1/__init__.py index fa6863381d74..967f784e0519 100644 --- a/packages/google-cloud-maintenance-api/google/cloud/maintenance_api_v1/__init__.py +++ b/packages/google-cloud-maintenance-api/google/cloud/maintenance_api_v1/__init__.py @@ -61,7 +61,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -90,9 +90,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-maintenance-api/google/cloud/maintenance_api_v1beta/__init__.py b/packages/google-cloud-maintenance-api/google/cloud/maintenance_api_v1beta/__init__.py index f0a652bc6a57..9663c2f55e52 100644 --- a/packages/google-cloud-maintenance-api/google/cloud/maintenance_api_v1beta/__init__.py +++ b/packages/google-cloud-maintenance-api/google/cloud/maintenance_api_v1beta/__init__.py @@ -61,7 +61,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -90,9 +90,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-maintenance-api/setup.py b/packages/google-cloud-maintenance-api/setup.py index b6c5444d0ce4..703795455eff 100644 --- a/packages/google-cloud-maintenance-api/setup.py +++ b/packages/google-cloud-maintenance-api/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/maintenance_api/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-maintenance-api" diff --git a/packages/google-cloud-maintenance-api/testing/constraints-3.10.txt b/packages/google-cloud-maintenance-api/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-maintenance-api/testing/constraints-3.10.txt +++ b/packages/google-cloud-maintenance-api/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-maintenance-api/testing/constraints-3.13.txt b/packages/google-cloud-maintenance-api/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-maintenance-api/testing/constraints-3.13.txt +++ b/packages/google-cloud-maintenance-api/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-maintenance-api/testing/constraints-3.14.txt b/packages/google-cloud-maintenance-api/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-maintenance-api/testing/constraints-3.14.txt +++ b/packages/google-cloud-maintenance-api/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-managed-identities/google/cloud/managedidentities_v1/__init__.py b/packages/google-cloud-managed-identities/google/cloud/managedidentities_v1/__init__.py index 325bde76d519..8d09f98f9358 100644 --- a/packages/google-cloud-managed-identities/google/cloud/managedidentities_v1/__init__.py +++ b/packages/google-cloud-managed-identities/google/cloud/managedidentities_v1/__init__.py @@ -69,7 +69,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -98,9 +98,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-managed-identities/setup.py b/packages/google-cloud-managed-identities/setup.py index 6b43890953d3..c5071c973582 100644 --- a/packages/google-cloud-managed-identities/setup.py +++ b/packages/google-cloud-managed-identities/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/managedidentities/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-managed-identities" diff --git a/packages/google-cloud-managed-identities/testing/constraints-3.10.txt b/packages/google-cloud-managed-identities/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-managed-identities/testing/constraints-3.10.txt +++ b/packages/google-cloud-managed-identities/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-managed-identities/testing/constraints-3.13.txt b/packages/google-cloud-managed-identities/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-managed-identities/testing/constraints-3.13.txt +++ b/packages/google-cloud-managed-identities/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-managed-identities/testing/constraints-3.14.txt b/packages/google-cloud-managed-identities/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-managed-identities/testing/constraints-3.14.txt +++ b/packages/google-cloud-managed-identities/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-managedkafka-schemaregistry/google/cloud/managedkafka_schemaregistry_v1/__init__.py b/packages/google-cloud-managedkafka-schemaregistry/google/cloud/managedkafka_schemaregistry_v1/__init__.py index e0f3ef69420a..95421fa41155 100644 --- a/packages/google-cloud-managedkafka-schemaregistry/google/cloud/managedkafka_schemaregistry_v1/__init__.py +++ b/packages/google-cloud-managedkafka-schemaregistry/google/cloud/managedkafka_schemaregistry_v1/__init__.py @@ -92,7 +92,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -121,9 +121,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-managedkafka-schemaregistry/setup.py b/packages/google-cloud-managedkafka-schemaregistry/setup.py index 9416c56d5a36..fe7ec9207344 100644 --- a/packages/google-cloud-managedkafka-schemaregistry/setup.py +++ b/packages/google-cloud-managedkafka-schemaregistry/setup.py @@ -33,7 +33,10 @@ package_root, "google/cloud/managedkafka_schemaregistry/gapic_version.py" ) ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -43,15 +46,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-managedkafka-schemaregistry" diff --git a/packages/google-cloud-managedkafka-schemaregistry/testing/constraints-3.10.txt b/packages/google-cloud-managedkafka-schemaregistry/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-managedkafka-schemaregistry/testing/constraints-3.10.txt +++ b/packages/google-cloud-managedkafka-schemaregistry/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-managedkafka-schemaregistry/testing/constraints-3.13.txt b/packages/google-cloud-managedkafka-schemaregistry/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-managedkafka-schemaregistry/testing/constraints-3.13.txt +++ b/packages/google-cloud-managedkafka-schemaregistry/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-managedkafka-schemaregistry/testing/constraints-3.14.txt b/packages/google-cloud-managedkafka-schemaregistry/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-managedkafka-schemaregistry/testing/constraints-3.14.txt +++ b/packages/google-cloud-managedkafka-schemaregistry/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-managedkafka/google/cloud/managedkafka_v1/__init__.py b/packages/google-cloud-managedkafka/google/cloud/managedkafka_v1/__init__.py index 972633cef999..782f8c772354 100644 --- a/packages/google-cloud-managedkafka/google/cloud/managedkafka_v1/__init__.py +++ b/packages/google-cloud-managedkafka/google/cloud/managedkafka_v1/__init__.py @@ -128,7 +128,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -157,9 +157,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-managedkafka/setup.py b/packages/google-cloud-managedkafka/setup.py index d9ea063674ea..09e86f8d94da 100644 --- a/packages/google-cloud-managedkafka/setup.py +++ b/packages/google-cloud-managedkafka/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/managedkafka/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-managedkafka" diff --git a/packages/google-cloud-managedkafka/testing/constraints-3.10.txt b/packages/google-cloud-managedkafka/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-managedkafka/testing/constraints-3.10.txt +++ b/packages/google-cloud-managedkafka/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-managedkafka/testing/constraints-3.13.txt b/packages/google-cloud-managedkafka/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-managedkafka/testing/constraints-3.13.txt +++ b/packages/google-cloud-managedkafka/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-managedkafka/testing/constraints-3.14.txt b/packages/google-cloud-managedkafka/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-managedkafka/testing/constraints-3.14.txt +++ b/packages/google-cloud-managedkafka/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-media-translation/google/cloud/mediatranslation_v1beta1/__init__.py b/packages/google-cloud-media-translation/google/cloud/mediatranslation_v1beta1/__init__.py index 7a72cefff50e..e4eae055056a 100644 --- a/packages/google-cloud-media-translation/google/cloud/mediatranslation_v1beta1/__init__.py +++ b/packages/google-cloud-media-translation/google/cloud/mediatranslation_v1beta1/__init__.py @@ -60,7 +60,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -89,9 +89,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-media-translation/setup.py b/packages/google-cloud-media-translation/setup.py index 44edff2adc76..6180f605c0c7 100644 --- a/packages/google-cloud-media-translation/setup.py +++ b/packages/google-cloud-media-translation/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/mediatranslation/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-media-translation" diff --git a/packages/google-cloud-media-translation/testing/constraints-3.10.txt b/packages/google-cloud-media-translation/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-media-translation/testing/constraints-3.10.txt +++ b/packages/google-cloud-media-translation/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-media-translation/testing/constraints-3.13.txt b/packages/google-cloud-media-translation/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-media-translation/testing/constraints-3.13.txt +++ b/packages/google-cloud-media-translation/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-media-translation/testing/constraints-3.14.txt b/packages/google-cloud-media-translation/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-media-translation/testing/constraints-3.14.txt +++ b/packages/google-cloud-media-translation/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-memcache/google/cloud/memcache_v1/__init__.py b/packages/google-cloud-memcache/google/cloud/memcache_v1/__init__.py index 10d3f88e69f5..4cbab1dd69bc 100644 --- a/packages/google-cloud-memcache/google/cloud/memcache_v1/__init__.py +++ b/packages/google-cloud-memcache/google/cloud/memcache_v1/__init__.py @@ -70,7 +70,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -99,9 +99,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-memcache/google/cloud/memcache_v1beta2/__init__.py b/packages/google-cloud-memcache/google/cloud/memcache_v1beta2/__init__.py index b568dee8aedf..39a008463637 100644 --- a/packages/google-cloud-memcache/google/cloud/memcache_v1beta2/__init__.py +++ b/packages/google-cloud-memcache/google/cloud/memcache_v1beta2/__init__.py @@ -71,7 +71,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -100,9 +100,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-memcache/setup.py b/packages/google-cloud-memcache/setup.py index 79d8a055aabe..541bb28df4d1 100644 --- a/packages/google-cloud-memcache/setup.py +++ b/packages/google-cloud-memcache/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/memcache/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-memcache" diff --git a/packages/google-cloud-memcache/testing/constraints-3.10.txt b/packages/google-cloud-memcache/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-memcache/testing/constraints-3.10.txt +++ b/packages/google-cloud-memcache/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-memcache/testing/constraints-3.13.txt b/packages/google-cloud-memcache/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-memcache/testing/constraints-3.13.txt +++ b/packages/google-cloud-memcache/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-memcache/testing/constraints-3.14.txt b/packages/google-cloud-memcache/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-memcache/testing/constraints-3.14.txt +++ b/packages/google-cloud-memcache/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-memorystore/google/cloud/memorystore_v1/__init__.py b/packages/google-cloud-memorystore/google/cloud/memorystore_v1/__init__.py index 826ae3aa5fa4..fd0f4561b3f1 100644 --- a/packages/google-cloud-memorystore/google/cloud/memorystore_v1/__init__.py +++ b/packages/google-cloud-memorystore/google/cloud/memorystore_v1/__init__.py @@ -92,7 +92,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -121,9 +121,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-memorystore/google/cloud/memorystore_v1beta/__init__.py b/packages/google-cloud-memorystore/google/cloud/memorystore_v1beta/__init__.py index 36cf30060c9d..b299b61b2bcb 100644 --- a/packages/google-cloud-memorystore/google/cloud/memorystore_v1beta/__init__.py +++ b/packages/google-cloud-memorystore/google/cloud/memorystore_v1beta/__init__.py @@ -72,7 +72,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -101,9 +101,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-memorystore/setup.py b/packages/google-cloud-memorystore/setup.py index 208691caab56..bad2fb388ea9 100644 --- a/packages/google-cloud-memorystore/setup.py +++ b/packages/google-cloud-memorystore/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/memorystore/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-memorystore" diff --git a/packages/google-cloud-memorystore/testing/constraints-3.10.txt b/packages/google-cloud-memorystore/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-memorystore/testing/constraints-3.10.txt +++ b/packages/google-cloud-memorystore/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-memorystore/testing/constraints-3.13.txt b/packages/google-cloud-memorystore/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-memorystore/testing/constraints-3.13.txt +++ b/packages/google-cloud-memorystore/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-memorystore/testing/constraints-3.14.txt b/packages/google-cloud-memorystore/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-memorystore/testing/constraints-3.14.txt +++ b/packages/google-cloud-memorystore/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-migrationcenter/google/cloud/migrationcenter_v1/__init__.py b/packages/google-cloud-migrationcenter/google/cloud/migrationcenter_v1/__init__.py index 1890ed202e21..c88508f2a229 100644 --- a/packages/google-cloud-migrationcenter/google/cloud/migrationcenter_v1/__init__.py +++ b/packages/google-cloud-migrationcenter/google/cloud/migrationcenter_v1/__init__.py @@ -210,7 +210,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -239,9 +239,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-migrationcenter/setup.py b/packages/google-cloud-migrationcenter/setup.py index e86879e9c131..7b5139ef8f60 100644 --- a/packages/google-cloud-migrationcenter/setup.py +++ b/packages/google-cloud-migrationcenter/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/migrationcenter/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-migrationcenter" diff --git a/packages/google-cloud-migrationcenter/testing/constraints-3.10.txt b/packages/google-cloud-migrationcenter/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-migrationcenter/testing/constraints-3.10.txt +++ b/packages/google-cloud-migrationcenter/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-migrationcenter/testing/constraints-3.13.txt b/packages/google-cloud-migrationcenter/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-migrationcenter/testing/constraints-3.13.txt +++ b/packages/google-cloud-migrationcenter/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-migrationcenter/testing/constraints-3.14.txt b/packages/google-cloud-migrationcenter/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-migrationcenter/testing/constraints-3.14.txt +++ b/packages/google-cloud-migrationcenter/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/__init__.py b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/__init__.py index c93c523b3f4a..89d2dcbb660f 100644 --- a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/__init__.py +++ b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1/__init__.py @@ -98,7 +98,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -127,9 +127,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1beta/__init__.py b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1beta/__init__.py index 98c3d030ab6d..6d9803207727 100644 --- a/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1beta/__init__.py +++ b/packages/google-cloud-modelarmor/google/cloud/modelarmor_v1beta/__init__.py @@ -99,7 +99,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -128,9 +128,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-modelarmor/setup.py b/packages/google-cloud-modelarmor/setup.py index 8506f9fb203b..cb1761764ec2 100644 --- a/packages/google-cloud-modelarmor/setup.py +++ b/packages/google-cloud-modelarmor/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/modelarmor/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-modelarmor" diff --git a/packages/google-cloud-modelarmor/testing/constraints-3.10.txt b/packages/google-cloud-modelarmor/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-modelarmor/testing/constraints-3.10.txt +++ b/packages/google-cloud-modelarmor/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-modelarmor/testing/constraints-3.13.txt b/packages/google-cloud-modelarmor/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-modelarmor/testing/constraints-3.13.txt +++ b/packages/google-cloud-modelarmor/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-modelarmor/testing/constraints-3.14.txt b/packages/google-cloud-modelarmor/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-modelarmor/testing/constraints-3.14.txt +++ b/packages/google-cloud-modelarmor/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-monitoring-dashboards/google/cloud/monitoring_dashboard_v1/__init__.py b/packages/google-cloud-monitoring-dashboards/google/cloud/monitoring_dashboard_v1/__init__.py index 84f96411042b..879516cbe56d 100644 --- a/packages/google-cloud-monitoring-dashboards/google/cloud/monitoring_dashboard_v1/__init__.py +++ b/packages/google-cloud-monitoring-dashboards/google/cloud/monitoring_dashboard_v1/__init__.py @@ -86,7 +86,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -115,9 +115,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-monitoring-dashboards/setup.py b/packages/google-cloud-monitoring-dashboards/setup.py index 95971113f4db..d4e6dd1a5eaf 100644 --- a/packages/google-cloud-monitoring-dashboards/setup.py +++ b/packages/google-cloud-monitoring-dashboards/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/monitoring_dashboard/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-monitoring-dashboards" diff --git a/packages/google-cloud-monitoring-dashboards/testing/constraints-3.10.txt b/packages/google-cloud-monitoring-dashboards/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-monitoring-dashboards/testing/constraints-3.10.txt +++ b/packages/google-cloud-monitoring-dashboards/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-monitoring-dashboards/testing/constraints-3.13.txt b/packages/google-cloud-monitoring-dashboards/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-monitoring-dashboards/testing/constraints-3.13.txt +++ b/packages/google-cloud-monitoring-dashboards/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-monitoring-dashboards/testing/constraints-3.14.txt b/packages/google-cloud-monitoring-dashboards/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-monitoring-dashboards/testing/constraints-3.14.txt +++ b/packages/google-cloud-monitoring-dashboards/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-monitoring-metrics-scopes/google/cloud/monitoring_metrics_scope_v1/__init__.py b/packages/google-cloud-monitoring-metrics-scopes/google/cloud/monitoring_metrics_scope_v1/__init__.py index 1e13c92aea6d..e520b377c8b4 100644 --- a/packages/google-cloud-monitoring-metrics-scopes/google/cloud/monitoring_metrics_scope_v1/__init__.py +++ b/packages/google-cloud-monitoring-metrics-scopes/google/cloud/monitoring_metrics_scope_v1/__init__.py @@ -59,7 +59,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -88,9 +88,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-monitoring-metrics-scopes/setup.py b/packages/google-cloud-monitoring-metrics-scopes/setup.py index 00bd7975c4cb..9445363dc558 100644 --- a/packages/google-cloud-monitoring-metrics-scopes/setup.py +++ b/packages/google-cloud-monitoring-metrics-scopes/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/monitoring_metrics_scope/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-monitoring-metrics-scopes" diff --git a/packages/google-cloud-monitoring-metrics-scopes/testing/constraints-3.10.txt b/packages/google-cloud-monitoring-metrics-scopes/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-monitoring-metrics-scopes/testing/constraints-3.10.txt +++ b/packages/google-cloud-monitoring-metrics-scopes/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-monitoring-metrics-scopes/testing/constraints-3.13.txt b/packages/google-cloud-monitoring-metrics-scopes/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-monitoring-metrics-scopes/testing/constraints-3.13.txt +++ b/packages/google-cloud-monitoring-metrics-scopes/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-monitoring-metrics-scopes/testing/constraints-3.14.txt b/packages/google-cloud-monitoring-metrics-scopes/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-monitoring-metrics-scopes/testing/constraints-3.14.txt +++ b/packages/google-cloud-monitoring-metrics-scopes/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-monitoring/google/cloud/monitoring_v3/__init__.py b/packages/google-cloud-monitoring/google/cloud/monitoring_v3/__init__.py index 0d3318ec2d4b..344bd1ab6b6b 100644 --- a/packages/google-cloud-monitoring/google/cloud/monitoring_v3/__init__.py +++ b/packages/google-cloud-monitoring/google/cloud/monitoring_v3/__init__.py @@ -193,7 +193,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -222,9 +222,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-monitoring/setup.py b/packages/google-cloud-monitoring/setup.py index e549aed6fc15..2eb2a37ed01b 100644 --- a/packages/google-cloud-monitoring/setup.py +++ b/packages/google-cloud-monitoring/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/monitoring/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {"pandas": "pandas >= 1.3.4"} diff --git a/packages/google-cloud-monitoring/testing/constraints-3.10.txt b/packages/google-cloud-monitoring/testing/constraints-3.10.txt index d335f6419cf8..53e51cd75bb0 100644 --- a/packages/google-cloud-monitoring/testing/constraints-3.10.txt +++ b/packages/google-cloud-monitoring/testing/constraints-3.10.txt @@ -4,10 +4,10 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 pandas==1.3.4 numpy==1.21.3 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-monitoring/testing/constraints-3.13.txt b/packages/google-cloud-monitoring/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-monitoring/testing/constraints-3.13.txt +++ b/packages/google-cloud-monitoring/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-monitoring/testing/constraints-3.14.txt b/packages/google-cloud-monitoring/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-monitoring/testing/constraints-3.14.txt +++ b/packages/google-cloud-monitoring/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-netapp/google/cloud/netapp_v1/__init__.py b/packages/google-cloud-netapp/google/cloud/netapp_v1/__init__.py index f0716178a060..3944cb800dcd 100644 --- a/packages/google-cloud-netapp/google/cloud/netapp_v1/__init__.py +++ b/packages/google-cloud-netapp/google/cloud/netapp_v1/__init__.py @@ -213,7 +213,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -242,9 +242,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-netapp/setup.py b/packages/google-cloud-netapp/setup.py index f7360b1daeb6..b421fbec29d5 100644 --- a/packages/google-cloud-netapp/setup.py +++ b/packages/google-cloud-netapp/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/netapp/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-netapp" diff --git a/packages/google-cloud-netapp/testing/constraints-3.10.txt b/packages/google-cloud-netapp/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-netapp/testing/constraints-3.10.txt +++ b/packages/google-cloud-netapp/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-netapp/testing/constraints-3.13.txt b/packages/google-cloud-netapp/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-netapp/testing/constraints-3.13.txt +++ b/packages/google-cloud-netapp/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-netapp/testing/constraints-3.14.txt b/packages/google-cloud-netapp/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-netapp/testing/constraints-3.14.txt +++ b/packages/google-cloud-netapp/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-network-connectivity/google/cloud/networkconnectivity_v1/__init__.py b/packages/google-cloud-network-connectivity/google/cloud/networkconnectivity_v1/__init__.py index 981e0ecc117f..721e5394aa69 100644 --- a/packages/google-cloud-network-connectivity/google/cloud/networkconnectivity_v1/__init__.py +++ b/packages/google-cloud-network-connectivity/google/cloud/networkconnectivity_v1/__init__.py @@ -200,7 +200,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -229,9 +229,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-network-connectivity/google/cloud/networkconnectivity_v1alpha1/__init__.py b/packages/google-cloud-network-connectivity/google/cloud/networkconnectivity_v1alpha1/__init__.py index e57ea4a58693..a69b4193269d 100644 --- a/packages/google-cloud-network-connectivity/google/cloud/networkconnectivity_v1alpha1/__init__.py +++ b/packages/google-cloud-network-connectivity/google/cloud/networkconnectivity_v1alpha1/__init__.py @@ -69,7 +69,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -98,9 +98,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-network-connectivity/google/cloud/networkconnectivity_v1beta/__init__.py b/packages/google-cloud-network-connectivity/google/cloud/networkconnectivity_v1beta/__init__.py index 92ac5dcf3760..01f50021c944 100644 --- a/packages/google-cloud-network-connectivity/google/cloud/networkconnectivity_v1beta/__init__.py +++ b/packages/google-cloud-network-connectivity/google/cloud/networkconnectivity_v1beta/__init__.py @@ -180,7 +180,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -209,9 +209,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-network-connectivity/setup.py b/packages/google-cloud-network-connectivity/setup.py index de8d11e404f4..775af2c3ba2b 100644 --- a/packages/google-cloud-network-connectivity/setup.py +++ b/packages/google-cloud-network-connectivity/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/networkconnectivity/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-network-connectivity" diff --git a/packages/google-cloud-network-connectivity/testing/constraints-3.10.txt b/packages/google-cloud-network-connectivity/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-network-connectivity/testing/constraints-3.10.txt +++ b/packages/google-cloud-network-connectivity/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-network-connectivity/testing/constraints-3.13.txt b/packages/google-cloud-network-connectivity/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-network-connectivity/testing/constraints-3.13.txt +++ b/packages/google-cloud-network-connectivity/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-network-connectivity/testing/constraints-3.14.txt b/packages/google-cloud-network-connectivity/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-network-connectivity/testing/constraints-3.14.txt +++ b/packages/google-cloud-network-connectivity/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-network-management/google/cloud/network_management_v1/__init__.py b/packages/google-cloud-network-management/google/cloud/network_management_v1/__init__.py index cb7447d8e3b3..eecf50e9cdd5 100644 --- a/packages/google-cloud-network-management/google/cloud/network_management_v1/__init__.py +++ b/packages/google-cloud-network-management/google/cloud/network_management_v1/__init__.py @@ -134,7 +134,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -163,9 +163,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-network-management/setup.py b/packages/google-cloud-network-management/setup.py index 8af6d1192eee..992aefaafe8b 100644 --- a/packages/google-cloud-network-management/setup.py +++ b/packages/google-cloud-network-management/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/network_management/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-network-management" diff --git a/packages/google-cloud-network-management/testing/constraints-3.10.txt b/packages/google-cloud-network-management/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-network-management/testing/constraints-3.10.txt +++ b/packages/google-cloud-network-management/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-network-management/testing/constraints-3.13.txt b/packages/google-cloud-network-management/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-network-management/testing/constraints-3.13.txt +++ b/packages/google-cloud-network-management/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-network-management/testing/constraints-3.14.txt b/packages/google-cloud-network-management/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-network-management/testing/constraints-3.14.txt +++ b/packages/google-cloud-network-management/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-network-security/google/cloud/network_security_v1/__init__.py b/packages/google-cloud-network-security/google/cloud/network_security_v1/__init__.py index 962e4da8b6ad..0e6d79c26858 100644 --- a/packages/google-cloud-network-security/google/cloud/network_security_v1/__init__.py +++ b/packages/google-cloud-network-security/google/cloud/network_security_v1/__init__.py @@ -311,7 +311,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -340,9 +340,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-network-security/google/cloud/network_security_v1alpha1/__init__.py b/packages/google-cloud-network-security/google/cloud/network_security_v1alpha1/__init__.py index e7dc75a22db1..0157cdac082b 100644 --- a/packages/google-cloud-network-security/google/cloud/network_security_v1alpha1/__init__.py +++ b/packages/google-cloud-network-security/google/cloud/network_security_v1alpha1/__init__.py @@ -308,7 +308,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -337,9 +337,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-network-security/google/cloud/network_security_v1beta1/__init__.py b/packages/google-cloud-network-security/google/cloud/network_security_v1beta1/__init__.py index 4969f11a1ee9..e97b8c25195a 100644 --- a/packages/google-cloud-network-security/google/cloud/network_security_v1beta1/__init__.py +++ b/packages/google-cloud-network-security/google/cloud/network_security_v1beta1/__init__.py @@ -97,7 +97,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -126,9 +126,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-network-security/setup.py b/packages/google-cloud-network-security/setup.py index 0c5a80731f77..a7e51d60dfdb 100644 --- a/packages/google-cloud-network-security/setup.py +++ b/packages/google-cloud-network-security/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/network_security/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-network-security" diff --git a/packages/google-cloud-network-security/testing/constraints-3.10.txt b/packages/google-cloud-network-security/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-network-security/testing/constraints-3.10.txt +++ b/packages/google-cloud-network-security/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-network-security/testing/constraints-3.13.txt b/packages/google-cloud-network-security/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-network-security/testing/constraints-3.13.txt +++ b/packages/google-cloud-network-security/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-network-security/testing/constraints-3.14.txt b/packages/google-cloud-network-security/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-network-security/testing/constraints-3.14.txt +++ b/packages/google-cloud-network-security/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-network-services/google/cloud/network_services_v1/__init__.py b/packages/google-cloud-network-services/google/cloud/network_services_v1/__init__.py index ae423bbb90b7..1a36dfb8920e 100644 --- a/packages/google-cloud-network-services/google/cloud/network_services_v1/__init__.py +++ b/packages/google-cloud-network-services/google/cloud/network_services_v1/__init__.py @@ -208,7 +208,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -237,9 +237,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-network-services/setup.py b/packages/google-cloud-network-services/setup.py index 8a72208f46e3..6823cf82dba1 100644 --- a/packages/google-cloud-network-services/setup.py +++ b/packages/google-cloud-network-services/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/network_services/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-network-services" diff --git a/packages/google-cloud-network-services/testing/constraints-3.10.txt b/packages/google-cloud-network-services/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-network-services/testing/constraints-3.10.txt +++ b/packages/google-cloud-network-services/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-network-services/testing/constraints-3.13.txt b/packages/google-cloud-network-services/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-network-services/testing/constraints-3.13.txt +++ b/packages/google-cloud-network-services/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-network-services/testing/constraints-3.14.txt b/packages/google-cloud-network-services/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-network-services/testing/constraints-3.14.txt +++ b/packages/google-cloud-network-services/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-notebooks/google/cloud/notebooks_v1/__init__.py b/packages/google-cloud-notebooks/google/cloud/notebooks_v1/__init__.py index f0a864e3a305..e7f13c9c2ba9 100644 --- a/packages/google-cloud-notebooks/google/cloud/notebooks_v1/__init__.py +++ b/packages/google-cloud-notebooks/google/cloud/notebooks_v1/__init__.py @@ -136,7 +136,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -165,9 +165,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-notebooks/google/cloud/notebooks_v1beta1/__init__.py b/packages/google-cloud-notebooks/google/cloud/notebooks_v1beta1/__init__.py index e2dd11997cba..15da11447402 100644 --- a/packages/google-cloud-notebooks/google/cloud/notebooks_v1beta1/__init__.py +++ b/packages/google-cloud-notebooks/google/cloud/notebooks_v1beta1/__init__.py @@ -77,7 +77,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -106,9 +106,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-notebooks/google/cloud/notebooks_v2/__init__.py b/packages/google-cloud-notebooks/google/cloud/notebooks_v2/__init__.py index 963fa2bd93cc..32134fac90b9 100644 --- a/packages/google-cloud-notebooks/google/cloud/notebooks_v2/__init__.py +++ b/packages/google-cloud-notebooks/google/cloud/notebooks_v2/__init__.py @@ -84,7 +84,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -113,9 +113,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-notebooks/setup.py b/packages/google-cloud-notebooks/setup.py index 1d4d559b4a37..cd13f812512b 100644 --- a/packages/google-cloud-notebooks/setup.py +++ b/packages/google-cloud-notebooks/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/notebooks/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-notebooks" diff --git a/packages/google-cloud-notebooks/testing/constraints-3.10.txt b/packages/google-cloud-notebooks/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-notebooks/testing/constraints-3.10.txt +++ b/packages/google-cloud-notebooks/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-notebooks/testing/constraints-3.13.txt b/packages/google-cloud-notebooks/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-notebooks/testing/constraints-3.13.txt +++ b/packages/google-cloud-notebooks/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-notebooks/testing/constraints-3.14.txt b/packages/google-cloud-notebooks/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-notebooks/testing/constraints-3.14.txt +++ b/packages/google-cloud-notebooks/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-optimization/google/cloud/optimization_v1/__init__.py b/packages/google-cloud-optimization/google/cloud/optimization_v1/__init__.py index 3af18a4c0156..fa7ded4432c7 100644 --- a/packages/google-cloud-optimization/google/cloud/optimization_v1/__init__.py +++ b/packages/google-cloud-optimization/google/cloud/optimization_v1/__init__.py @@ -83,7 +83,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -112,9 +112,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-optimization/setup.py b/packages/google-cloud-optimization/setup.py index c29d9b8b6cd2..4d97583945bb 100644 --- a/packages/google-cloud-optimization/setup.py +++ b/packages/google-cloud-optimization/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/optimization/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-optimization" diff --git a/packages/google-cloud-optimization/testing/constraints-3.10.txt b/packages/google-cloud-optimization/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-optimization/testing/constraints-3.10.txt +++ b/packages/google-cloud-optimization/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-optimization/testing/constraints-3.13.txt b/packages/google-cloud-optimization/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-optimization/testing/constraints-3.13.txt +++ b/packages/google-cloud-optimization/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-optimization/testing/constraints-3.14.txt b/packages/google-cloud-optimization/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-optimization/testing/constraints-3.14.txt +++ b/packages/google-cloud-optimization/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/__init__.py b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/__init__.py index 9ba5e09b5c0f..cc926ee58385 100644 --- a/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/__init__.py +++ b/packages/google-cloud-oracledatabase/google/cloud/oracledatabase_v1/__init__.py @@ -336,7 +336,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -365,9 +365,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-oracledatabase/setup.py b/packages/google-cloud-oracledatabase/setup.py index 46d329fbff77..01f7265aa733 100644 --- a/packages/google-cloud-oracledatabase/setup.py +++ b/packages/google-cloud-oracledatabase/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/oracledatabase/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-oracledatabase" diff --git a/packages/google-cloud-oracledatabase/testing/constraints-3.10.txt b/packages/google-cloud-oracledatabase/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-oracledatabase/testing/constraints-3.10.txt +++ b/packages/google-cloud-oracledatabase/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-oracledatabase/testing/constraints-3.13.txt b/packages/google-cloud-oracledatabase/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-oracledatabase/testing/constraints-3.13.txt +++ b/packages/google-cloud-oracledatabase/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-oracledatabase/testing/constraints-3.14.txt b/packages/google-cloud-oracledatabase/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-oracledatabase/testing/constraints-3.14.txt +++ b/packages/google-cloud-oracledatabase/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-orchestration-airflow/google/cloud/orchestration/airflow/service_v1/__init__.py b/packages/google-cloud-orchestration-airflow/google/cloud/orchestration/airflow/service_v1/__init__.py index 3ab93ea509a1..ce2f826871d3 100644 --- a/packages/google-cloud-orchestration-airflow/google/cloud/orchestration/airflow/service_v1/__init__.py +++ b/packages/google-cloud-orchestration-airflow/google/cloud/orchestration/airflow/service_v1/__init__.py @@ -121,7 +121,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -150,9 +150,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-orchestration-airflow/google/cloud/orchestration/airflow/service_v1beta1/__init__.py b/packages/google-cloud-orchestration-airflow/google/cloud/orchestration/airflow/service_v1beta1/__init__.py index c9c12c473dc2..09190ab22bd3 100644 --- a/packages/google-cloud-orchestration-airflow/google/cloud/orchestration/airflow/service_v1beta1/__init__.py +++ b/packages/google-cloud-orchestration-airflow/google/cloud/orchestration/airflow/service_v1beta1/__init__.py @@ -124,7 +124,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -153,9 +153,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-orchestration-airflow/setup.py b/packages/google-cloud-orchestration-airflow/setup.py index d695956c7ffe..1948b7c3af0a 100644 --- a/packages/google-cloud-orchestration-airflow/setup.py +++ b/packages/google-cloud-orchestration-airflow/setup.py @@ -33,7 +33,10 @@ package_root, "google/cloud/orchestration/airflow/service/gapic_version.py" ) ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -43,15 +46,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-orchestration-airflow" diff --git a/packages/google-cloud-orchestration-airflow/testing/constraints-3.10.txt b/packages/google-cloud-orchestration-airflow/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-orchestration-airflow/testing/constraints-3.10.txt +++ b/packages/google-cloud-orchestration-airflow/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-orchestration-airflow/testing/constraints-3.13.txt b/packages/google-cloud-orchestration-airflow/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-orchestration-airflow/testing/constraints-3.13.txt +++ b/packages/google-cloud-orchestration-airflow/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-orchestration-airflow/testing/constraints-3.14.txt b/packages/google-cloud-orchestration-airflow/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-orchestration-airflow/testing/constraints-3.14.txt +++ b/packages/google-cloud-orchestration-airflow/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-org-policy/google/cloud/orgpolicy_v2/__init__.py b/packages/google-cloud-org-policy/google/cloud/orgpolicy_v2/__init__.py index ee3ed8b4ed24..abb179a2e16e 100644 --- a/packages/google-cloud-org-policy/google/cloud/orgpolicy_v2/__init__.py +++ b/packages/google-cloud-org-policy/google/cloud/orgpolicy_v2/__init__.py @@ -71,7 +71,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -100,9 +100,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-org-policy/setup.py b/packages/google-cloud-org-policy/setup.py index eeeb8c23b623..cce90859b4a7 100644 --- a/packages/google-cloud-org-policy/setup.py +++ b/packages/google-cloud-org-policy/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/orgpolicy/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-org-policy" diff --git a/packages/google-cloud-org-policy/testing/constraints-3.10.txt b/packages/google-cloud-org-policy/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-org-policy/testing/constraints-3.10.txt +++ b/packages/google-cloud-org-policy/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-org-policy/testing/constraints-3.13.txt b/packages/google-cloud-org-policy/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-org-policy/testing/constraints-3.13.txt +++ b/packages/google-cloud-org-policy/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-org-policy/testing/constraints-3.14.txt b/packages/google-cloud-org-policy/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-org-policy/testing/constraints-3.14.txt +++ b/packages/google-cloud-org-policy/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-os-config/google/cloud/osconfig_v1/__init__.py b/packages/google-cloud-os-config/google/cloud/osconfig_v1/__init__.py index f424f56097a1..16589199972e 100644 --- a/packages/google-cloud-os-config/google/cloud/osconfig_v1/__init__.py +++ b/packages/google-cloud-os-config/google/cloud/osconfig_v1/__init__.py @@ -130,7 +130,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -159,9 +159,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-os-config/google/cloud/osconfig_v1alpha/__init__.py b/packages/google-cloud-os-config/google/cloud/osconfig_v1alpha/__init__.py index a3fb0b49b4a6..c3e71dbb6f58 100644 --- a/packages/google-cloud-os-config/google/cloud/osconfig_v1alpha/__init__.py +++ b/packages/google-cloud-os-config/google/cloud/osconfig_v1alpha/__init__.py @@ -98,7 +98,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -127,9 +127,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-os-config/setup.py b/packages/google-cloud-os-config/setup.py index 8e3a7eabbf6e..e9dc57fa548c 100644 --- a/packages/google-cloud-os-config/setup.py +++ b/packages/google-cloud-os-config/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/osconfig/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-os-config" diff --git a/packages/google-cloud-os-config/testing/constraints-3.10.txt b/packages/google-cloud-os-config/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-os-config/testing/constraints-3.10.txt +++ b/packages/google-cloud-os-config/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-os-config/testing/constraints-3.13.txt b/packages/google-cloud-os-config/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-os-config/testing/constraints-3.13.txt +++ b/packages/google-cloud-os-config/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-os-config/testing/constraints-3.14.txt b/packages/google-cloud-os-config/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-os-config/testing/constraints-3.14.txt +++ b/packages/google-cloud-os-config/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-os-login/google/cloud/oslogin_v1/__init__.py b/packages/google-cloud-os-login/google/cloud/oslogin_v1/__init__.py index 5d0a9a28e8a3..de46c4aa1787 100644 --- a/packages/google-cloud-os-login/google/cloud/oslogin_v1/__init__.py +++ b/packages/google-cloud-os-login/google/cloud/oslogin_v1/__init__.py @@ -61,7 +61,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -90,9 +90,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-os-login/setup.py b/packages/google-cloud-os-login/setup.py index fc9fcd2ffe66..1f4dc68bd225 100644 --- a/packages/google-cloud-os-login/setup.py +++ b/packages/google-cloud-os-login/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/oslogin/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-os-login" diff --git a/packages/google-cloud-os-login/testing/constraints-3.10.txt b/packages/google-cloud-os-login/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-os-login/testing/constraints-3.10.txt +++ b/packages/google-cloud-os-login/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-os-login/testing/constraints-3.13.txt b/packages/google-cloud-os-login/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-os-login/testing/constraints-3.13.txt +++ b/packages/google-cloud-os-login/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-os-login/testing/constraints-3.14.txt b/packages/google-cloud-os-login/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-os-login/testing/constraints-3.14.txt +++ b/packages/google-cloud-os-login/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1/__init__.py b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1/__init__.py index 48484f52d23a..d4ae70c5e1ec 100644 --- a/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1/__init__.py +++ b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1/__init__.py @@ -79,7 +79,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -108,9 +108,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/__init__.py b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/__init__.py index b3ecc0ef887e..28d74e1809fe 100644 --- a/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/__init__.py +++ b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/__init__.py @@ -79,7 +79,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -108,9 +108,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-parallelstore/setup.py b/packages/google-cloud-parallelstore/setup.py index 6ef4df5c52ac..a944c6a662e6 100644 --- a/packages/google-cloud-parallelstore/setup.py +++ b/packages/google-cloud-parallelstore/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/parallelstore/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-parallelstore" diff --git a/packages/google-cloud-parallelstore/testing/constraints-3.10.txt b/packages/google-cloud-parallelstore/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-parallelstore/testing/constraints-3.10.txt +++ b/packages/google-cloud-parallelstore/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-parallelstore/testing/constraints-3.13.txt b/packages/google-cloud-parallelstore/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-parallelstore/testing/constraints-3.13.txt +++ b/packages/google-cloud-parallelstore/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-parallelstore/testing/constraints-3.14.txt b/packages/google-cloud-parallelstore/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-parallelstore/testing/constraints-3.14.txt +++ b/packages/google-cloud-parallelstore/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-parametermanager/google/cloud/parametermanager_v1/__init__.py b/packages/google-cloud-parametermanager/google/cloud/parametermanager_v1/__init__.py index 0b52a17d3b34..6fed83bdb57c 100644 --- a/packages/google-cloud-parametermanager/google/cloud/parametermanager_v1/__init__.py +++ b/packages/google-cloud-parametermanager/google/cloud/parametermanager_v1/__init__.py @@ -74,7 +74,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -103,9 +103,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-parametermanager/setup.py b/packages/google-cloud-parametermanager/setup.py index 96a75cc8f4ca..6bf84a9e0129 100644 --- a/packages/google-cloud-parametermanager/setup.py +++ b/packages/google-cloud-parametermanager/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/parametermanager/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-parametermanager" diff --git a/packages/google-cloud-parametermanager/testing/constraints-3.10.txt b/packages/google-cloud-parametermanager/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-parametermanager/testing/constraints-3.10.txt +++ b/packages/google-cloud-parametermanager/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-parametermanager/testing/constraints-3.13.txt b/packages/google-cloud-parametermanager/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-parametermanager/testing/constraints-3.13.txt +++ b/packages/google-cloud-parametermanager/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-parametermanager/testing/constraints-3.14.txt b/packages/google-cloud-parametermanager/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-parametermanager/testing/constraints-3.14.txt +++ b/packages/google-cloud-parametermanager/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-phishing-protection/google/cloud/phishingprotection_v1beta1/__init__.py b/packages/google-cloud-phishing-protection/google/cloud/phishingprotection_v1beta1/__init__.py index 1a57f91a69b1..2e871b0961ae 100644 --- a/packages/google-cloud-phishing-protection/google/cloud/phishingprotection_v1beta1/__init__.py +++ b/packages/google-cloud-phishing-protection/google/cloud/phishingprotection_v1beta1/__init__.py @@ -54,7 +54,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -83,9 +83,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-phishing-protection/setup.py b/packages/google-cloud-phishing-protection/setup.py index 5f84e31c66e3..af18d8b4c6ae 100644 --- a/packages/google-cloud-phishing-protection/setup.py +++ b/packages/google-cloud-phishing-protection/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/phishingprotection/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-phishing-protection" diff --git a/packages/google-cloud-phishing-protection/testing/constraints-3.10.txt b/packages/google-cloud-phishing-protection/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-phishing-protection/testing/constraints-3.10.txt +++ b/packages/google-cloud-phishing-protection/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-phishing-protection/testing/constraints-3.13.txt b/packages/google-cloud-phishing-protection/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-phishing-protection/testing/constraints-3.13.txt +++ b/packages/google-cloud-phishing-protection/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-phishing-protection/testing/constraints-3.14.txt b/packages/google-cloud-phishing-protection/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-phishing-protection/testing/constraints-3.14.txt +++ b/packages/google-cloud-phishing-protection/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-policy-troubleshooter/google/cloud/policytroubleshooter_v1/__init__.py b/packages/google-cloud-policy-troubleshooter/google/cloud/policytroubleshooter_v1/__init__.py index 3470b5141817..19686075b803 100644 --- a/packages/google-cloud-policy-troubleshooter/google/cloud/policytroubleshooter_v1/__init__.py +++ b/packages/google-cloud-policy-troubleshooter/google/cloud/policytroubleshooter_v1/__init__.py @@ -58,7 +58,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -87,9 +87,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-policy-troubleshooter/setup.py b/packages/google-cloud-policy-troubleshooter/setup.py index 4b0add742904..c821e7ea1b09 100644 --- a/packages/google-cloud-policy-troubleshooter/setup.py +++ b/packages/google-cloud-policy-troubleshooter/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/policytroubleshooter/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-policy-troubleshooter" diff --git a/packages/google-cloud-policy-troubleshooter/testing/constraints-3.10.txt b/packages/google-cloud-policy-troubleshooter/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-policy-troubleshooter/testing/constraints-3.10.txt +++ b/packages/google-cloud-policy-troubleshooter/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-policy-troubleshooter/testing/constraints-3.13.txt b/packages/google-cloud-policy-troubleshooter/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-policy-troubleshooter/testing/constraints-3.13.txt +++ b/packages/google-cloud-policy-troubleshooter/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-policy-troubleshooter/testing/constraints-3.14.txt b/packages/google-cloud-policy-troubleshooter/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-policy-troubleshooter/testing/constraints-3.14.txt +++ b/packages/google-cloud-policy-troubleshooter/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-policysimulator/google/cloud/policysimulator_v1/__init__.py b/packages/google-cloud-policysimulator/google/cloud/policysimulator_v1/__init__.py index ecd207b296a7..00ff3e27fc2d 100644 --- a/packages/google-cloud-policysimulator/google/cloud/policysimulator_v1/__init__.py +++ b/packages/google-cloud-policysimulator/google/cloud/policysimulator_v1/__init__.py @@ -88,7 +88,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -117,9 +117,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-policysimulator/setup.py b/packages/google-cloud-policysimulator/setup.py index 2fcef358e8bc..2fdd697bbed5 100644 --- a/packages/google-cloud-policysimulator/setup.py +++ b/packages/google-cloud-policysimulator/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/policysimulator/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,17 +44,16 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", - "google-cloud-org-policy >= 1.11.1, <2.0.0", + "google-cloud-org-policy >= 1.13.1, <2.0.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-policysimulator" diff --git a/packages/google-cloud-policysimulator/testing/constraints-3.10.txt b/packages/google-cloud-policysimulator/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-policysimulator/testing/constraints-3.10.txt +++ b/packages/google-cloud-policysimulator/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-policysimulator/testing/constraints-3.13.txt b/packages/google-cloud-policysimulator/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-policysimulator/testing/constraints-3.13.txt +++ b/packages/google-cloud-policysimulator/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-policysimulator/testing/constraints-3.14.txt b/packages/google-cloud-policysimulator/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-policysimulator/testing/constraints-3.14.txt +++ b/packages/google-cloud-policysimulator/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-policytroubleshooter-iam/google/cloud/policytroubleshooter_iam_v3/__init__.py b/packages/google-cloud-policytroubleshooter-iam/google/cloud/policytroubleshooter_iam_v3/__init__.py index 0fe6b843e149..7f13b2532597 100644 --- a/packages/google-cloud-policytroubleshooter-iam/google/cloud/policytroubleshooter_iam_v3/__init__.py +++ b/packages/google-cloud-policytroubleshooter-iam/google/cloud/policytroubleshooter_iam_v3/__init__.py @@ -73,7 +73,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -102,9 +102,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-policytroubleshooter-iam/setup.py b/packages/google-cloud-policytroubleshooter-iam/setup.py index 304049104b14..4e55b87b9009 100644 --- a/packages/google-cloud-policytroubleshooter-iam/setup.py +++ b/packages/google-cloud-policytroubleshooter-iam/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/policytroubleshooter_iam/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,17 +44,16 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", - "google-cloud-iam >= 2.12.2, <3.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", + "google-cloud-iam >= 2.18.2, <3.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-policytroubleshooter-iam" diff --git a/packages/google-cloud-policytroubleshooter-iam/testing/constraints-3.10.txt b/packages/google-cloud-policytroubleshooter-iam/testing/constraints-3.10.txt index 674a39705cb1..bbd3b5241b82 100644 --- a/packages/google-cloud-policytroubleshooter-iam/testing/constraints-3.10.txt +++ b/packages/google-cloud-policytroubleshooter-iam/testing/constraints-3.10.txt @@ -4,10 +4,10 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 -google-cloud-iam==2.12.2 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 +google-cloud-iam==2.18.2 diff --git a/packages/google-cloud-policytroubleshooter-iam/testing/constraints-3.13.txt b/packages/google-cloud-policytroubleshooter-iam/testing/constraints-3.13.txt index 1eb835cabc37..d72c71aba784 100644 --- a/packages/google-cloud-policytroubleshooter-iam/testing/constraints-3.13.txt +++ b/packages/google-cloud-policytroubleshooter-iam/testing/constraints-3.13.txt @@ -9,6 +9,6 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 google-cloud-iam>=2 diff --git a/packages/google-cloud-policytroubleshooter-iam/testing/constraints-3.14.txt b/packages/google-cloud-policytroubleshooter-iam/testing/constraints-3.14.txt index 1eb835cabc37..d72c71aba784 100644 --- a/packages/google-cloud-policytroubleshooter-iam/testing/constraints-3.14.txt +++ b/packages/google-cloud-policytroubleshooter-iam/testing/constraints-3.14.txt @@ -9,6 +9,6 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 google-cloud-iam>=2 diff --git a/packages/google-cloud-private-ca/google/cloud/security/privateca_v1/__init__.py b/packages/google-cloud-private-ca/google/cloud/security/privateca_v1/__init__.py index 16edba16d777..466fd02d220d 100644 --- a/packages/google-cloud-private-ca/google/cloud/security/privateca_v1/__init__.py +++ b/packages/google-cloud-private-ca/google/cloud/security/privateca_v1/__init__.py @@ -117,7 +117,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -146,9 +146,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-private-ca/google/cloud/security/privateca_v1beta1/__init__.py b/packages/google-cloud-private-ca/google/cloud/security/privateca_v1beta1/__init__.py index daf7edfa9e4f..577d072ca6fd 100644 --- a/packages/google-cloud-private-ca/google/cloud/security/privateca_v1beta1/__init__.py +++ b/packages/google-cloud-private-ca/google/cloud/security/privateca_v1beta1/__init__.py @@ -99,7 +99,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -128,9 +128,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-private-ca/setup.py b/packages/google-cloud-private-ca/setup.py index c11f2d1df881..7571cbd46c83 100644 --- a/packages/google-cloud-private-ca/setup.py +++ b/packages/google-cloud-private-ca/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/security/privateca/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-private-ca" diff --git a/packages/google-cloud-private-ca/testing/constraints-3.10.txt b/packages/google-cloud-private-ca/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-private-ca/testing/constraints-3.10.txt +++ b/packages/google-cloud-private-ca/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-private-ca/testing/constraints-3.13.txt b/packages/google-cloud-private-ca/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-private-ca/testing/constraints-3.13.txt +++ b/packages/google-cloud-private-ca/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-private-ca/testing/constraints-3.14.txt b/packages/google-cloud-private-ca/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-private-ca/testing/constraints-3.14.txt +++ b/packages/google-cloud-private-ca/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-private-catalog/google/cloud/privatecatalog_v1beta1/__init__.py b/packages/google-cloud-private-catalog/google/cloud/privatecatalog_v1beta1/__init__.py index 4b7dfeb6b305..2378ebb5c3c5 100644 --- a/packages/google-cloud-private-catalog/google/cloud/privatecatalog_v1beta1/__init__.py +++ b/packages/google-cloud-private-catalog/google/cloud/privatecatalog_v1beta1/__init__.py @@ -65,7 +65,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -94,9 +94,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-private-catalog/setup.py b/packages/google-cloud-private-catalog/setup.py index 37ec2442c612..0be5fa792fa6 100644 --- a/packages/google-cloud-private-catalog/setup.py +++ b/packages/google-cloud-private-catalog/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/privatecatalog/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-private-catalog" diff --git a/packages/google-cloud-private-catalog/testing/constraints-3.10.txt b/packages/google-cloud-private-catalog/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-private-catalog/testing/constraints-3.10.txt +++ b/packages/google-cloud-private-catalog/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-private-catalog/testing/constraints-3.13.txt b/packages/google-cloud-private-catalog/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-private-catalog/testing/constraints-3.13.txt +++ b/packages/google-cloud-private-catalog/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-private-catalog/testing/constraints-3.14.txt b/packages/google-cloud-private-catalog/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-private-catalog/testing/constraints-3.14.txt +++ b/packages/google-cloud-private-catalog/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-privilegedaccessmanager/google/cloud/privilegedaccessmanager_v1/__init__.py b/packages/google-cloud-privilegedaccessmanager/google/cloud/privilegedaccessmanager_v1/__init__.py index d276cb37b00b..0cf880476781 100644 --- a/packages/google-cloud-privilegedaccessmanager/google/cloud/privilegedaccessmanager_v1/__init__.py +++ b/packages/google-cloud-privilegedaccessmanager/google/cloud/privilegedaccessmanager_v1/__init__.py @@ -82,7 +82,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -111,9 +111,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-privilegedaccessmanager/setup.py b/packages/google-cloud-privilegedaccessmanager/setup.py index e2bbe8c24c01..5bf5a8122e8d 100644 --- a/packages/google-cloud-privilegedaccessmanager/setup.py +++ b/packages/google-cloud-privilegedaccessmanager/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/privilegedaccessmanager/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-privilegedaccessmanager" diff --git a/packages/google-cloud-privilegedaccessmanager/testing/constraints-3.10.txt b/packages/google-cloud-privilegedaccessmanager/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-privilegedaccessmanager/testing/constraints-3.10.txt +++ b/packages/google-cloud-privilegedaccessmanager/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-privilegedaccessmanager/testing/constraints-3.13.txt b/packages/google-cloud-privilegedaccessmanager/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-privilegedaccessmanager/testing/constraints-3.13.txt +++ b/packages/google-cloud-privilegedaccessmanager/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-privilegedaccessmanager/testing/constraints-3.14.txt b/packages/google-cloud-privilegedaccessmanager/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-privilegedaccessmanager/testing/constraints-3.14.txt +++ b/packages/google-cloud-privilegedaccessmanager/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-pubsub/google/pubsub_v1/__init__.py b/packages/google-cloud-pubsub/google/pubsub_v1/__init__.py index b766bd04eff7..9393ffac76e6 100644 --- a/packages/google-cloud-pubsub/google/pubsub_v1/__init__.py +++ b/packages/google-cloud-pubsub/google/pubsub_v1/__init__.py @@ -126,7 +126,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -155,9 +155,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-pubsub/setup.py b/packages/google-cloud-pubsub/setup.py index 96a086c5c694..66c9606ffc26 100644 --- a/packages/google-cloud-pubsub/setup.py +++ b/packages/google-cloud-pubsub/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/pubsub/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.51.3, < 2.0.0; python_version < '3.14'", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", "grpcio-status >= 1.51.3", "opentelemetry-api >= 1.27.0", "opentelemetry-sdk >= 1.27.0", diff --git a/packages/google-cloud-pubsub/testing/constraints-3.10.txt b/packages/google-cloud-pubsub/testing/constraints-3.10.txt index aa2a4f1e90a4..00a8388e941c 100644 --- a/packages/google-cloud-pubsub/testing/constraints-3.10.txt +++ b/packages/google-cloud-pubsub/testing/constraints-3.10.txt @@ -4,12 +4,12 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.51.3 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 grpcio-status==1.51.3 opentelemetry-api==1.27.0 opentelemetry-sdk==1.27.0 \ No newline at end of file diff --git a/packages/google-cloud-pubsub/testing/constraints-3.13.txt b/packages/google-cloud-pubsub/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-pubsub/testing/constraints-3.13.txt +++ b/packages/google-cloud-pubsub/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-pubsub/testing/constraints-3.14.txt b/packages/google-cloud-pubsub/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-pubsub/testing/constraints-3.14.txt +++ b/packages/google-cloud-pubsub/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-quotas/google/cloud/cloudquotas_v1/__init__.py b/packages/google-cloud-quotas/google/cloud/cloudquotas_v1/__init__.py index 1e3583052da8..e345603d7297 100644 --- a/packages/google-cloud-quotas/google/cloud/cloudquotas_v1/__init__.py +++ b/packages/google-cloud-quotas/google/cloud/cloudquotas_v1/__init__.py @@ -70,7 +70,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -99,9 +99,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-quotas/google/cloud/cloudquotas_v1beta/__init__.py b/packages/google-cloud-quotas/google/cloud/cloudquotas_v1beta/__init__.py index 437e33d5dbd5..ad81101c823e 100644 --- a/packages/google-cloud-quotas/google/cloud/cloudquotas_v1beta/__init__.py +++ b/packages/google-cloud-quotas/google/cloud/cloudquotas_v1beta/__init__.py @@ -79,7 +79,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -108,9 +108,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-quotas/setup.py b/packages/google-cloud-quotas/setup.py index 511993a5d9e8..d9112924a284 100644 --- a/packages/google-cloud-quotas/setup.py +++ b/packages/google-cloud-quotas/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/cloudquotas/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-quotas" diff --git a/packages/google-cloud-quotas/testing/constraints-3.10.txt b/packages/google-cloud-quotas/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-quotas/testing/constraints-3.10.txt +++ b/packages/google-cloud-quotas/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-quotas/testing/constraints-3.13.txt b/packages/google-cloud-quotas/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-quotas/testing/constraints-3.13.txt +++ b/packages/google-cloud-quotas/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-quotas/testing/constraints-3.14.txt b/packages/google-cloud-quotas/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-quotas/testing/constraints-3.14.txt +++ b/packages/google-cloud-quotas/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-rapidmigrationassessment/google/cloud/rapidmigrationassessment_v1/__init__.py b/packages/google-cloud-rapidmigrationassessment/google/cloud/rapidmigrationassessment_v1/__init__.py index 8f8092abba4d..a94b6c386ecb 100644 --- a/packages/google-cloud-rapidmigrationassessment/google/cloud/rapidmigrationassessment_v1/__init__.py +++ b/packages/google-cloud-rapidmigrationassessment/google/cloud/rapidmigrationassessment_v1/__init__.py @@ -68,7 +68,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -97,9 +97,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-rapidmigrationassessment/setup.py b/packages/google-cloud-rapidmigrationassessment/setup.py index eaac50568810..4fe64eb850fc 100644 --- a/packages/google-cloud-rapidmigrationassessment/setup.py +++ b/packages/google-cloud-rapidmigrationassessment/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/rapidmigrationassessment/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-rapidmigrationassessment" diff --git a/packages/google-cloud-rapidmigrationassessment/testing/constraints-3.10.txt b/packages/google-cloud-rapidmigrationassessment/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-rapidmigrationassessment/testing/constraints-3.10.txt +++ b/packages/google-cloud-rapidmigrationassessment/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-rapidmigrationassessment/testing/constraints-3.13.txt b/packages/google-cloud-rapidmigrationassessment/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-rapidmigrationassessment/testing/constraints-3.13.txt +++ b/packages/google-cloud-rapidmigrationassessment/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-rapidmigrationassessment/testing/constraints-3.14.txt b/packages/google-cloud-rapidmigrationassessment/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-rapidmigrationassessment/testing/constraints-3.14.txt +++ b/packages/google-cloud-rapidmigrationassessment/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-recaptcha-enterprise/google/cloud/recaptchaenterprise_v1/__init__.py b/packages/google-cloud-recaptcha-enterprise/google/cloud/recaptchaenterprise_v1/__init__.py index 1aeb6a567ca1..a2fe88ed6d13 100644 --- a/packages/google-cloud-recaptcha-enterprise/google/cloud/recaptchaenterprise_v1/__init__.py +++ b/packages/google-cloud-recaptcha-enterprise/google/cloud/recaptchaenterprise_v1/__init__.py @@ -125,7 +125,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -154,9 +154,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-recaptcha-enterprise/setup.py b/packages/google-cloud-recaptcha-enterprise/setup.py index 8c7c85c164f7..543d463a08a8 100644 --- a/packages/google-cloud-recaptcha-enterprise/setup.py +++ b/packages/google-cloud-recaptcha-enterprise/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/recaptchaenterprise/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-recaptcha-enterprise" diff --git a/packages/google-cloud-recaptcha-enterprise/testing/constraints-3.10.txt b/packages/google-cloud-recaptcha-enterprise/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-recaptcha-enterprise/testing/constraints-3.10.txt +++ b/packages/google-cloud-recaptcha-enterprise/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-recaptcha-enterprise/testing/constraints-3.13.txt b/packages/google-cloud-recaptcha-enterprise/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-recaptcha-enterprise/testing/constraints-3.13.txt +++ b/packages/google-cloud-recaptcha-enterprise/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-recaptcha-enterprise/testing/constraints-3.14.txt b/packages/google-cloud-recaptcha-enterprise/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-recaptcha-enterprise/testing/constraints-3.14.txt +++ b/packages/google-cloud-recaptcha-enterprise/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-recommendations-ai/google/cloud/recommendationengine_v1beta1/__init__.py b/packages/google-cloud-recommendations-ai/google/cloud/recommendationengine_v1beta1/__init__.py index d71aa9f4180c..ae967c987aff 100644 --- a/packages/google-cloud-recommendations-ai/google/cloud/recommendationengine_v1beta1/__init__.py +++ b/packages/google-cloud-recommendations-ai/google/cloud/recommendationengine_v1beta1/__init__.py @@ -110,7 +110,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -139,9 +139,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-recommendations-ai/setup.py b/packages/google-cloud-recommendations-ai/setup.py index 6a3d2c00be48..8593f40466cf 100644 --- a/packages/google-cloud-recommendations-ai/setup.py +++ b/packages/google-cloud-recommendations-ai/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/recommendationengine/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-recommendations-ai" diff --git a/packages/google-cloud-recommendations-ai/testing/constraints-3.10.txt b/packages/google-cloud-recommendations-ai/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-recommendations-ai/testing/constraints-3.10.txt +++ b/packages/google-cloud-recommendations-ai/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-recommendations-ai/testing/constraints-3.13.txt b/packages/google-cloud-recommendations-ai/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-recommendations-ai/testing/constraints-3.13.txt +++ b/packages/google-cloud-recommendations-ai/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-recommendations-ai/testing/constraints-3.14.txt b/packages/google-cloud-recommendations-ai/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-recommendations-ai/testing/constraints-3.14.txt +++ b/packages/google-cloud-recommendations-ai/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-recommender/google/cloud/recommender_v1/__init__.py b/packages/google-cloud-recommender/google/cloud/recommender_v1/__init__.py index 944d0e34daba..756ce83af459 100644 --- a/packages/google-cloud-recommender/google/cloud/recommender_v1/__init__.py +++ b/packages/google-cloud-recommender/google/cloud/recommender_v1/__init__.py @@ -83,7 +83,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -112,9 +112,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-recommender/google/cloud/recommender_v1beta1/__init__.py b/packages/google-cloud-recommender/google/cloud/recommender_v1beta1/__init__.py index 2b8c92a4c1e5..713fd5826372 100644 --- a/packages/google-cloud-recommender/google/cloud/recommender_v1beta1/__init__.py +++ b/packages/google-cloud-recommender/google/cloud/recommender_v1beta1/__init__.py @@ -86,7 +86,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -115,9 +115,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-recommender/setup.py b/packages/google-cloud-recommender/setup.py index 54e16ef9de61..8bf364d2e206 100644 --- a/packages/google-cloud-recommender/setup.py +++ b/packages/google-cloud-recommender/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/recommender/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-recommender" diff --git a/packages/google-cloud-recommender/testing/constraints-3.10.txt b/packages/google-cloud-recommender/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-recommender/testing/constraints-3.10.txt +++ b/packages/google-cloud-recommender/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-recommender/testing/constraints-3.13.txt b/packages/google-cloud-recommender/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-recommender/testing/constraints-3.13.txt +++ b/packages/google-cloud-recommender/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-recommender/testing/constraints-3.14.txt b/packages/google-cloud-recommender/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-recommender/testing/constraints-3.14.txt +++ b/packages/google-cloud-recommender/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-redis-cluster/google/cloud/redis_cluster_v1/__init__.py b/packages/google-cloud-redis-cluster/google/cloud/redis_cluster_v1/__init__.py index a466f04b66df..180568fddcaf 100644 --- a/packages/google-cloud-redis-cluster/google/cloud/redis_cluster_v1/__init__.py +++ b/packages/google-cloud-redis-cluster/google/cloud/redis_cluster_v1/__init__.py @@ -101,7 +101,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -130,9 +130,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-redis-cluster/google/cloud/redis_cluster_v1beta1/__init__.py b/packages/google-cloud-redis-cluster/google/cloud/redis_cluster_v1beta1/__init__.py index 5f39b56f7410..5c1181837ba2 100644 --- a/packages/google-cloud-redis-cluster/google/cloud/redis_cluster_v1beta1/__init__.py +++ b/packages/google-cloud-redis-cluster/google/cloud/redis_cluster_v1beta1/__init__.py @@ -101,7 +101,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -130,9 +130,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-redis-cluster/setup.py b/packages/google-cloud-redis-cluster/setup.py index 9c6a891cd9fb..932a4d9c1485 100644 --- a/packages/google-cloud-redis-cluster/setup.py +++ b/packages/google-cloud-redis-cluster/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/redis_cluster/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-redis-cluster" diff --git a/packages/google-cloud-redis-cluster/testing/constraints-3.10.txt b/packages/google-cloud-redis-cluster/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-redis-cluster/testing/constraints-3.10.txt +++ b/packages/google-cloud-redis-cluster/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-redis-cluster/testing/constraints-3.13.txt b/packages/google-cloud-redis-cluster/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-redis-cluster/testing/constraints-3.13.txt +++ b/packages/google-cloud-redis-cluster/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-redis-cluster/testing/constraints-3.14.txt b/packages/google-cloud-redis-cluster/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-redis-cluster/testing/constraints-3.14.txt +++ b/packages/google-cloud-redis-cluster/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-redis/google/cloud/redis_v1/__init__.py b/packages/google-cloud-redis/google/cloud/redis_v1/__init__.py index dc3033429796..7f67c87bda33 100644 --- a/packages/google-cloud-redis/google/cloud/redis_v1/__init__.py +++ b/packages/google-cloud-redis/google/cloud/redis_v1/__init__.py @@ -79,7 +79,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -108,9 +108,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-redis/google/cloud/redis_v1beta1/__init__.py b/packages/google-cloud-redis/google/cloud/redis_v1beta1/__init__.py index f35f33fda484..889192b5eb99 100644 --- a/packages/google-cloud-redis/google/cloud/redis_v1beta1/__init__.py +++ b/packages/google-cloud-redis/google/cloud/redis_v1beta1/__init__.py @@ -78,7 +78,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -107,9 +107,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-redis/setup.py b/packages/google-cloud-redis/setup.py index 85c6bfd22bd7..cbdddc70227f 100644 --- a/packages/google-cloud-redis/setup.py +++ b/packages/google-cloud-redis/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/redis/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-redis" diff --git a/packages/google-cloud-redis/testing/constraints-3.10.txt b/packages/google-cloud-redis/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-redis/testing/constraints-3.10.txt +++ b/packages/google-cloud-redis/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-redis/testing/constraints-3.13.txt b/packages/google-cloud-redis/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-redis/testing/constraints-3.13.txt +++ b/packages/google-cloud-redis/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-redis/testing/constraints-3.14.txt b/packages/google-cloud-redis/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-redis/testing/constraints-3.14.txt +++ b/packages/google-cloud-redis/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-resource-manager/google/cloud/resourcemanager_v3/__init__.py b/packages/google-cloud-resource-manager/google/cloud/resourcemanager_v3/__init__.py index 4fdd145f90f8..5f146121796c 100644 --- a/packages/google-cloud-resource-manager/google/cloud/resourcemanager_v3/__init__.py +++ b/packages/google-cloud-resource-manager/google/cloud/resourcemanager_v3/__init__.py @@ -148,7 +148,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -177,9 +177,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-resource-manager/setup.py b/packages/google-cloud-resource-manager/setup.py index 7e406112d4c0..1815015501be 100644 --- a/packages/google-cloud-resource-manager/setup.py +++ b/packages/google-cloud-resource-manager/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/resourcemanager/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-resource-manager" diff --git a/packages/google-cloud-resource-manager/testing/constraints-3.10.txt b/packages/google-cloud-resource-manager/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-resource-manager/testing/constraints-3.10.txt +++ b/packages/google-cloud-resource-manager/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-resource-manager/testing/constraints-3.13.txt b/packages/google-cloud-resource-manager/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-resource-manager/testing/constraints-3.13.txt +++ b/packages/google-cloud-resource-manager/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-resource-manager/testing/constraints-3.14.txt b/packages/google-cloud-resource-manager/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-resource-manager/testing/constraints-3.14.txt +++ b/packages/google-cloud-resource-manager/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/__init__.py b/packages/google-cloud-retail/google/cloud/retail_v2/__init__.py index 963a4610b622..125136f55792 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2/__init__.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2/__init__.py @@ -262,7 +262,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -291,9 +291,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/__init__.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/__init__.py index e3981c3e52bb..784ae53a93a6 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/__init__.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/__init__.py @@ -308,7 +308,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -337,9 +337,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/__init__.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/__init__.py index 40b56c721de0..2b39193f0ec4 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/__init__.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/__init__.py @@ -274,7 +274,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -303,9 +303,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-retail/setup.py b/packages/google-cloud-retail/setup.py index d630659866d7..ebb74b63e02d 100644 --- a/packages/google-cloud-retail/setup.py +++ b/packages/google-cloud-retail/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/retail/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-retail" diff --git a/packages/google-cloud-retail/testing/constraints-3.10.txt b/packages/google-cloud-retail/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-retail/testing/constraints-3.10.txt +++ b/packages/google-cloud-retail/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-retail/testing/constraints-3.13.txt b/packages/google-cloud-retail/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-retail/testing/constraints-3.13.txt +++ b/packages/google-cloud-retail/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-retail/testing/constraints-3.14.txt b/packages/google-cloud-retail/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-retail/testing/constraints-3.14.txt +++ b/packages/google-cloud-retail/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-run/google/cloud/run_v2/__init__.py b/packages/google-cloud-run/google/cloud/run_v2/__init__.py index 243d5084cf9a..df742f00336a 100644 --- a/packages/google-cloud-run/google/cloud/run_v2/__init__.py +++ b/packages/google-cloud-run/google/cloud/run_v2/__init__.py @@ -172,7 +172,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -201,9 +201,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-run/setup.py b/packages/google-cloud-run/setup.py index ff8b20df8c5d..0620a6b2ed39 100644 --- a/packages/google-cloud-run/setup.py +++ b/packages/google-cloud-run/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/run/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-run" diff --git a/packages/google-cloud-run/testing/constraints-3.10.txt b/packages/google-cloud-run/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-run/testing/constraints-3.10.txt +++ b/packages/google-cloud-run/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-run/testing/constraints-3.13.txt b/packages/google-cloud-run/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-run/testing/constraints-3.13.txt +++ b/packages/google-cloud-run/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-run/testing/constraints-3.14.txt b/packages/google-cloud-run/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-run/testing/constraints-3.14.txt +++ b/packages/google-cloud-run/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-saasplatform-saasservicemgmt/google/cloud/saasplatform_saasservicemgmt_v1beta1/__init__.py b/packages/google-cloud-saasplatform-saasservicemgmt/google/cloud/saasplatform_saasservicemgmt_v1beta1/__init__.py index 8eaafcd4bde3..983862c7c71e 100644 --- a/packages/google-cloud-saasplatform-saasservicemgmt/google/cloud/saasplatform_saasservicemgmt_v1beta1/__init__.py +++ b/packages/google-cloud-saasplatform-saasservicemgmt/google/cloud/saasplatform_saasservicemgmt_v1beta1/__init__.py @@ -145,7 +145,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -174,9 +174,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-saasplatform-saasservicemgmt/setup.py b/packages/google-cloud-saasplatform-saasservicemgmt/setup.py index a5201c621115..1ec1808f63c9 100644 --- a/packages/google-cloud-saasplatform-saasservicemgmt/setup.py +++ b/packages/google-cloud-saasplatform-saasservicemgmt/setup.py @@ -33,7 +33,10 @@ package_root, "google/cloud/saasplatform_saasservicemgmt/gapic_version.py" ) ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -43,15 +46,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-saasplatform-saasservicemgmt" diff --git a/packages/google-cloud-saasplatform-saasservicemgmt/testing/constraints-3.10.txt b/packages/google-cloud-saasplatform-saasservicemgmt/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-saasplatform-saasservicemgmt/testing/constraints-3.10.txt +++ b/packages/google-cloud-saasplatform-saasservicemgmt/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-saasplatform-saasservicemgmt/testing/constraints-3.13.txt b/packages/google-cloud-saasplatform-saasservicemgmt/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-saasplatform-saasservicemgmt/testing/constraints-3.13.txt +++ b/packages/google-cloud-saasplatform-saasservicemgmt/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-saasplatform-saasservicemgmt/testing/constraints-3.14.txt b/packages/google-cloud-saasplatform-saasservicemgmt/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-saasplatform-saasservicemgmt/testing/constraints-3.14.txt +++ b/packages/google-cloud-saasplatform-saasservicemgmt/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-scheduler/google/cloud/scheduler_v1/__init__.py b/packages/google-cloud-scheduler/google/cloud/scheduler_v1/__init__.py index 028e06eda7c8..e4ea86b0647e 100644 --- a/packages/google-cloud-scheduler/google/cloud/scheduler_v1/__init__.py +++ b/packages/google-cloud-scheduler/google/cloud/scheduler_v1/__init__.py @@ -71,7 +71,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -100,9 +100,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-scheduler/google/cloud/scheduler_v1beta1/__init__.py b/packages/google-cloud-scheduler/google/cloud/scheduler_v1beta1/__init__.py index d4b0d0c35e50..233e33cc9568 100644 --- a/packages/google-cloud-scheduler/google/cloud/scheduler_v1beta1/__init__.py +++ b/packages/google-cloud-scheduler/google/cloud/scheduler_v1beta1/__init__.py @@ -71,7 +71,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -100,9 +100,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-scheduler/setup.py b/packages/google-cloud-scheduler/setup.py index 7209982c00b6..dee4047082b4 100644 --- a/packages/google-cloud-scheduler/setup.py +++ b/packages/google-cloud-scheduler/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/scheduler/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-scheduler" diff --git a/packages/google-cloud-scheduler/testing/constraints-3.10.txt b/packages/google-cloud-scheduler/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-scheduler/testing/constraints-3.10.txt +++ b/packages/google-cloud-scheduler/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-scheduler/testing/constraints-3.13.txt b/packages/google-cloud-scheduler/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-scheduler/testing/constraints-3.13.txt +++ b/packages/google-cloud-scheduler/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-scheduler/testing/constraints-3.14.txt b/packages/google-cloud-scheduler/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-scheduler/testing/constraints-3.14.txt +++ b/packages/google-cloud-scheduler/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-secret-manager/google/cloud/secretmanager_v1/__init__.py b/packages/google-cloud-secret-manager/google/cloud/secretmanager_v1/__init__.py index a47740a66d05..5370bcfc99d2 100644 --- a/packages/google-cloud-secret-manager/google/cloud/secretmanager_v1/__init__.py +++ b/packages/google-cloud-secret-manager/google/cloud/secretmanager_v1/__init__.py @@ -81,7 +81,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -110,9 +110,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-secret-manager/google/cloud/secretmanager_v1beta1/__init__.py b/packages/google-cloud-secret-manager/google/cloud/secretmanager_v1beta1/__init__.py index e03614eebc26..aeba7b920f51 100644 --- a/packages/google-cloud-secret-manager/google/cloud/secretmanager_v1beta1/__init__.py +++ b/packages/google-cloud-secret-manager/google/cloud/secretmanager_v1beta1/__init__.py @@ -71,7 +71,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -100,9 +100,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-secret-manager/google/cloud/secretmanager_v1beta2/__init__.py b/packages/google-cloud-secret-manager/google/cloud/secretmanager_v1beta2/__init__.py index a95c6472a078..505e054be690 100644 --- a/packages/google-cloud-secret-manager/google/cloud/secretmanager_v1beta2/__init__.py +++ b/packages/google-cloud-secret-manager/google/cloud/secretmanager_v1beta2/__init__.py @@ -81,7 +81,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -110,9 +110,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-secret-manager/setup.py b/packages/google-cloud-secret-manager/setup.py index fe1c04e8b58d..f6cd66555e9c 100644 --- a/packages/google-cloud-secret-manager/setup.py +++ b/packages/google-cloud-secret-manager/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/secretmanager/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-secret-manager" diff --git a/packages/google-cloud-secret-manager/testing/constraints-3.10.txt b/packages/google-cloud-secret-manager/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-secret-manager/testing/constraints-3.10.txt +++ b/packages/google-cloud-secret-manager/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-secret-manager/testing/constraints-3.13.txt b/packages/google-cloud-secret-manager/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-secret-manager/testing/constraints-3.13.txt +++ b/packages/google-cloud-secret-manager/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-secret-manager/testing/constraints-3.14.txt b/packages/google-cloud-secret-manager/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-secret-manager/testing/constraints-3.14.txt +++ b/packages/google-cloud-secret-manager/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-securesourcemanager/google/cloud/securesourcemanager_v1/__init__.py b/packages/google-cloud-securesourcemanager/google/cloud/securesourcemanager_v1/__init__.py index 1e6831f3aadf..cc27b9f9eb5f 100644 --- a/packages/google-cloud-securesourcemanager/google/cloud/securesourcemanager_v1/__init__.py +++ b/packages/google-cloud-securesourcemanager/google/cloud/securesourcemanager_v1/__init__.py @@ -129,7 +129,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -158,9 +158,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-securesourcemanager/setup.py b/packages/google-cloud-securesourcemanager/setup.py index 8531b16d46ab..a915aca135dc 100644 --- a/packages/google-cloud-securesourcemanager/setup.py +++ b/packages/google-cloud-securesourcemanager/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/securesourcemanager/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-securesourcemanager" diff --git a/packages/google-cloud-securesourcemanager/testing/constraints-3.10.txt b/packages/google-cloud-securesourcemanager/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-securesourcemanager/testing/constraints-3.10.txt +++ b/packages/google-cloud-securesourcemanager/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-securesourcemanager/testing/constraints-3.13.txt b/packages/google-cloud-securesourcemanager/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-securesourcemanager/testing/constraints-3.13.txt +++ b/packages/google-cloud-securesourcemanager/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-securesourcemanager/testing/constraints-3.14.txt b/packages/google-cloud-securesourcemanager/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-securesourcemanager/testing/constraints-3.14.txt +++ b/packages/google-cloud-securesourcemanager/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-security-publicca/google/cloud/security/publicca_v1/__init__.py b/packages/google-cloud-security-publicca/google/cloud/security/publicca_v1/__init__.py index 8bc792bef3e5..d88cb949c0f0 100644 --- a/packages/google-cloud-security-publicca/google/cloud/security/publicca_v1/__init__.py +++ b/packages/google-cloud-security-publicca/google/cloud/security/publicca_v1/__init__.py @@ -55,7 +55,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -84,9 +84,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-security-publicca/google/cloud/security/publicca_v1beta1/__init__.py b/packages/google-cloud-security-publicca/google/cloud/security/publicca_v1beta1/__init__.py index 58fc718f2bce..cd62bbbd8bc0 100644 --- a/packages/google-cloud-security-publicca/google/cloud/security/publicca_v1beta1/__init__.py +++ b/packages/google-cloud-security-publicca/google/cloud/security/publicca_v1beta1/__init__.py @@ -55,7 +55,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -84,9 +84,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-security-publicca/setup.py b/packages/google-cloud-security-publicca/setup.py index 432b05c125f6..05e59d0b1807 100644 --- a/packages/google-cloud-security-publicca/setup.py +++ b/packages/google-cloud-security-publicca/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/security/publicca/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-security-publicca" diff --git a/packages/google-cloud-security-publicca/testing/constraints-3.10.txt b/packages/google-cloud-security-publicca/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-security-publicca/testing/constraints-3.10.txt +++ b/packages/google-cloud-security-publicca/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-security-publicca/testing/constraints-3.13.txt b/packages/google-cloud-security-publicca/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-security-publicca/testing/constraints-3.13.txt +++ b/packages/google-cloud-security-publicca/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-security-publicca/testing/constraints-3.14.txt b/packages/google-cloud-security-publicca/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-security-publicca/testing/constraints-3.14.txt +++ b/packages/google-cloud-security-publicca/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/__init__.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/__init__.py index 0fde9ea125d7..7e6f19b8c06b 100644 --- a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/__init__.py +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/__init__.py @@ -222,7 +222,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -251,9 +251,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1beta1/__init__.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1beta1/__init__.py index 8994a8f4c737..0c0a02fc6e85 100644 --- a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1beta1/__init__.py +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1beta1/__init__.py @@ -79,7 +79,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -108,9 +108,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1p1beta1/__init__.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1p1beta1/__init__.py index e645271bf148..e93cc808c238 100644 --- a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1p1beta1/__init__.py +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1p1beta1/__init__.py @@ -89,7 +89,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -118,9 +118,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/__init__.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/__init__.py index 10586934426e..20f87f2e97b3 100644 --- a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/__init__.py +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/__init__.py @@ -180,7 +180,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -209,9 +209,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-securitycenter/setup.py b/packages/google-cloud-securitycenter/setup.py index 8bf26ebefc2a..fc4777070a7c 100644 --- a/packages/google-cloud-securitycenter/setup.py +++ b/packages/google-cloud-securitycenter/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/securitycenter/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-securitycenter" diff --git a/packages/google-cloud-securitycenter/testing/constraints-3.10.txt b/packages/google-cloud-securitycenter/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-securitycenter/testing/constraints-3.10.txt +++ b/packages/google-cloud-securitycenter/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-securitycenter/testing/constraints-3.13.txt b/packages/google-cloud-securitycenter/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-securitycenter/testing/constraints-3.13.txt +++ b/packages/google-cloud-securitycenter/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-securitycenter/testing/constraints-3.14.txt b/packages/google-cloud-securitycenter/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-securitycenter/testing/constraints-3.14.txt +++ b/packages/google-cloud-securitycenter/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-securitycentermanagement/google/cloud/securitycentermanagement_v1/__init__.py b/packages/google-cloud-securitycentermanagement/google/cloud/securitycentermanagement_v1/__init__.py index 7489e577f8e2..6fbda4426174 100644 --- a/packages/google-cloud-securitycentermanagement/google/cloud/securitycentermanagement_v1/__init__.py +++ b/packages/google-cloud-securitycentermanagement/google/cloud/securitycentermanagement_v1/__init__.py @@ -92,7 +92,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -121,9 +121,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-securitycentermanagement/setup.py b/packages/google-cloud-securitycentermanagement/setup.py index 84e2f6c02601..b80b2fd16450 100644 --- a/packages/google-cloud-securitycentermanagement/setup.py +++ b/packages/google-cloud-securitycentermanagement/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/securitycentermanagement/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-securitycentermanagement" diff --git a/packages/google-cloud-securitycentermanagement/testing/constraints-3.10.txt b/packages/google-cloud-securitycentermanagement/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-securitycentermanagement/testing/constraints-3.10.txt +++ b/packages/google-cloud-securitycentermanagement/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-securitycentermanagement/testing/constraints-3.13.txt b/packages/google-cloud-securitycentermanagement/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-securitycentermanagement/testing/constraints-3.13.txt +++ b/packages/google-cloud-securitycentermanagement/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-securitycentermanagement/testing/constraints-3.14.txt b/packages/google-cloud-securitycentermanagement/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-securitycentermanagement/testing/constraints-3.14.txt +++ b/packages/google-cloud-securitycentermanagement/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-service-control/google/cloud/servicecontrol_v1/__init__.py b/packages/google-cloud-service-control/google/cloud/servicecontrol_v1/__init__.py index dfc7ca5ea5d4..415681b343c3 100644 --- a/packages/google-cloud-service-control/google/cloud/servicecontrol_v1/__init__.py +++ b/packages/google-cloud-service-control/google/cloud/servicecontrol_v1/__init__.py @@ -72,7 +72,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -101,9 +101,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-service-control/google/cloud/servicecontrol_v2/__init__.py b/packages/google-cloud-service-control/google/cloud/servicecontrol_v2/__init__.py index 0db18863cdd3..0e067f14eff7 100644 --- a/packages/google-cloud-service-control/google/cloud/servicecontrol_v2/__init__.py +++ b/packages/google-cloud-service-control/google/cloud/servicecontrol_v2/__init__.py @@ -61,7 +61,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -90,9 +90,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-service-control/setup.py b/packages/google-cloud-service-control/setup.py index 805a88f437ca..de8e556f8f74 100644 --- a/packages/google-cloud-service-control/setup.py +++ b/packages/google-cloud-service-control/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/servicecontrol/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-service-control" diff --git a/packages/google-cloud-service-control/testing/constraints-3.10.txt b/packages/google-cloud-service-control/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-service-control/testing/constraints-3.10.txt +++ b/packages/google-cloud-service-control/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-service-control/testing/constraints-3.13.txt b/packages/google-cloud-service-control/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-service-control/testing/constraints-3.13.txt +++ b/packages/google-cloud-service-control/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-service-control/testing/constraints-3.14.txt b/packages/google-cloud-service-control/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-service-control/testing/constraints-3.14.txt +++ b/packages/google-cloud-service-control/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-service-directory/google/cloud/servicedirectory_v1/__init__.py b/packages/google-cloud-service-directory/google/cloud/servicedirectory_v1/__init__.py index 996ff19fd8e6..63d8a0699faa 100644 --- a/packages/google-cloud-service-directory/google/cloud/servicedirectory_v1/__init__.py +++ b/packages/google-cloud-service-directory/google/cloud/servicedirectory_v1/__init__.py @@ -78,7 +78,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -107,9 +107,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-service-directory/google/cloud/servicedirectory_v1beta1/__init__.py b/packages/google-cloud-service-directory/google/cloud/servicedirectory_v1beta1/__init__.py index 8cae386c0582..1d69856679c4 100644 --- a/packages/google-cloud-service-directory/google/cloud/servicedirectory_v1beta1/__init__.py +++ b/packages/google-cloud-service-directory/google/cloud/servicedirectory_v1beta1/__init__.py @@ -78,7 +78,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -107,9 +107,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-service-directory/setup.py b/packages/google-cloud-service-directory/setup.py index a77b67882b1a..bd10ddf46ea9 100644 --- a/packages/google-cloud-service-directory/setup.py +++ b/packages/google-cloud-service-directory/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/servicedirectory/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-service-directory" diff --git a/packages/google-cloud-service-directory/testing/constraints-3.10.txt b/packages/google-cloud-service-directory/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-service-directory/testing/constraints-3.10.txt +++ b/packages/google-cloud-service-directory/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-service-directory/testing/constraints-3.13.txt b/packages/google-cloud-service-directory/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-service-directory/testing/constraints-3.13.txt +++ b/packages/google-cloud-service-directory/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-service-directory/testing/constraints-3.14.txt b/packages/google-cloud-service-directory/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-service-directory/testing/constraints-3.14.txt +++ b/packages/google-cloud-service-directory/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-service-management/google/cloud/servicemanagement_v1/__init__.py b/packages/google-cloud-service-management/google/cloud/servicemanagement_v1/__init__.py index 4f8e943f2fee..b038ac3bed4f 100644 --- a/packages/google-cloud-service-management/google/cloud/servicemanagement_v1/__init__.py +++ b/packages/google-cloud-service-management/google/cloud/servicemanagement_v1/__init__.py @@ -82,7 +82,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -111,9 +111,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-service-management/setup.py b/packages/google-cloud-service-management/setup.py index 779085f98aa9..f13f9a998e1a 100644 --- a/packages/google-cloud-service-management/setup.py +++ b/packages/google-cloud-service-management/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/servicemanagement/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-service-management" diff --git a/packages/google-cloud-service-management/testing/constraints-3.10.txt b/packages/google-cloud-service-management/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-service-management/testing/constraints-3.10.txt +++ b/packages/google-cloud-service-management/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-service-management/testing/constraints-3.13.txt b/packages/google-cloud-service-management/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-service-management/testing/constraints-3.13.txt +++ b/packages/google-cloud-service-management/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-service-management/testing/constraints-3.14.txt b/packages/google-cloud-service-management/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-service-management/testing/constraints-3.14.txt +++ b/packages/google-cloud-service-management/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-service-usage/google/cloud/service_usage_v1/__init__.py b/packages/google-cloud-service-usage/google/cloud/service_usage_v1/__init__.py index dfcdd744118a..f434353a0ba6 100644 --- a/packages/google-cloud-service-usage/google/cloud/service_usage_v1/__init__.py +++ b/packages/google-cloud-service-usage/google/cloud/service_usage_v1/__init__.py @@ -64,7 +64,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -93,9 +93,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-service-usage/setup.py b/packages/google-cloud-service-usage/setup.py index 81e525f5379e..a60b2167cc88 100644 --- a/packages/google-cloud-service-usage/setup.py +++ b/packages/google-cloud-service-usage/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/service_usage/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-service-usage" diff --git a/packages/google-cloud-service-usage/testing/constraints-3.10.txt b/packages/google-cloud-service-usage/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-service-usage/testing/constraints-3.10.txt +++ b/packages/google-cloud-service-usage/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-service-usage/testing/constraints-3.13.txt b/packages/google-cloud-service-usage/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-service-usage/testing/constraints-3.13.txt +++ b/packages/google-cloud-service-usage/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-service-usage/testing/constraints-3.14.txt b/packages/google-cloud-service-usage/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-service-usage/testing/constraints-3.14.txt +++ b/packages/google-cloud-service-usage/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-servicehealth/google/cloud/servicehealth_v1/__init__.py b/packages/google-cloud-servicehealth/google/cloud/servicehealth_v1/__init__.py index 116f632bee7d..ab979bfceb78 100644 --- a/packages/google-cloud-servicehealth/google/cloud/servicehealth_v1/__init__.py +++ b/packages/google-cloud-servicehealth/google/cloud/servicehealth_v1/__init__.py @@ -71,7 +71,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -100,9 +100,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-servicehealth/setup.py b/packages/google-cloud-servicehealth/setup.py index 48fb14123db0..83300905b6a5 100644 --- a/packages/google-cloud-servicehealth/setup.py +++ b/packages/google-cloud-servicehealth/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/servicehealth/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-servicehealth" diff --git a/packages/google-cloud-servicehealth/testing/constraints-3.10.txt b/packages/google-cloud-servicehealth/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-servicehealth/testing/constraints-3.10.txt +++ b/packages/google-cloud-servicehealth/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-servicehealth/testing/constraints-3.13.txt b/packages/google-cloud-servicehealth/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-servicehealth/testing/constraints-3.13.txt +++ b/packages/google-cloud-servicehealth/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-servicehealth/testing/constraints-3.14.txt b/packages/google-cloud-servicehealth/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-servicehealth/testing/constraints-3.14.txt +++ b/packages/google-cloud-servicehealth/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-shell/google/cloud/shell_v1/__init__.py b/packages/google-cloud-shell/google/cloud/shell_v1/__init__.py index 39be64494a5c..649097214d1b 100644 --- a/packages/google-cloud-shell/google/cloud/shell_v1/__init__.py +++ b/packages/google-cloud-shell/google/cloud/shell_v1/__init__.py @@ -72,7 +72,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -101,9 +101,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-shell/setup.py b/packages/google-cloud-shell/setup.py index 268f5e47af1f..35c3015f17dc 100644 --- a/packages/google-cloud-shell/setup.py +++ b/packages/google-cloud-shell/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/shell/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-shell" diff --git a/packages/google-cloud-shell/testing/constraints-3.10.txt b/packages/google-cloud-shell/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-shell/testing/constraints-3.10.txt +++ b/packages/google-cloud-shell/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-shell/testing/constraints-3.13.txt b/packages/google-cloud-shell/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-shell/testing/constraints-3.13.txt +++ b/packages/google-cloud-shell/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-shell/testing/constraints-3.14.txt b/packages/google-cloud-shell/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-shell/testing/constraints-3.14.txt +++ b/packages/google-cloud-shell/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-source-context/google/cloud/source_context_v1/__init__.py b/packages/google-cloud-source-context/google/cloud/source_context_v1/__init__.py index 0c47b446db02..b685c50e6c43 100644 --- a/packages/google-cloud-source-context/google/cloud/source_context_v1/__init__.py +++ b/packages/google-cloud-source-context/google/cloud/source_context_v1/__init__.py @@ -61,7 +61,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -90,9 +90,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-source-context/setup.py b/packages/google-cloud-source-context/setup.py index dac66291ccbe..2fb7c986b6f5 100644 --- a/packages/google-cloud-source-context/setup.py +++ b/packages/google-cloud-source-context/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/source_context/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-source-context" diff --git a/packages/google-cloud-source-context/testing/constraints-3.10.txt b/packages/google-cloud-source-context/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-source-context/testing/constraints-3.10.txt +++ b/packages/google-cloud-source-context/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-source-context/testing/constraints-3.13.txt b/packages/google-cloud-source-context/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-source-context/testing/constraints-3.13.txt +++ b/packages/google-cloud-source-context/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-source-context/testing/constraints-3.14.txt b/packages/google-cloud-source-context/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-source-context/testing/constraints-3.14.txt +++ b/packages/google-cloud-source-context/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-speech/google/cloud/speech_v1/__init__.py b/packages/google-cloud-speech/google/cloud/speech_v1/__init__.py index e73b4e5104f0..130b6ccaa930 100644 --- a/packages/google-cloud-speech/google/cloud/speech_v1/__init__.py +++ b/packages/google-cloud-speech/google/cloud/speech_v1/__init__.py @@ -92,7 +92,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -121,9 +121,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-speech/google/cloud/speech_v1p1beta1/__init__.py b/packages/google-cloud-speech/google/cloud/speech_v1p1beta1/__init__.py index 34836f8aeab2..d7e51e833f15 100644 --- a/packages/google-cloud-speech/google/cloud/speech_v1p1beta1/__init__.py +++ b/packages/google-cloud-speech/google/cloud/speech_v1p1beta1/__init__.py @@ -92,7 +92,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -121,9 +121,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-speech/google/cloud/speech_v2/__init__.py b/packages/google-cloud-speech/google/cloud/speech_v2/__init__.py index 0423a3f26fb1..eb13ed51e30c 100644 --- a/packages/google-cloud-speech/google/cloud/speech_v2/__init__.py +++ b/packages/google-cloud-speech/google/cloud/speech_v2/__init__.py @@ -125,7 +125,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -154,9 +154,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-speech/setup.py b/packages/google-cloud-speech/setup.py index 46a8b8bc8298..772736540ae7 100644 --- a/packages/google-cloud-speech/setup.py +++ b/packages/google-cloud-speech/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/speech/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-speech" diff --git a/packages/google-cloud-speech/testing/constraints-3.10.txt b/packages/google-cloud-speech/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-speech/testing/constraints-3.10.txt +++ b/packages/google-cloud-speech/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-speech/testing/constraints-3.13.txt b/packages/google-cloud-speech/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-speech/testing/constraints-3.13.txt +++ b/packages/google-cloud-speech/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-speech/testing/constraints-3.14.txt b/packages/google-cloud-speech/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-speech/testing/constraints-3.14.txt +++ b/packages/google-cloud-speech/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-storage-control/google/cloud/storage_control_v2/__init__.py b/packages/google-cloud-storage-control/google/cloud/storage_control_v2/__init__.py index 3b297eafced5..c6bffc6da1da 100644 --- a/packages/google-cloud-storage-control/google/cloud/storage_control_v2/__init__.py +++ b/packages/google-cloud-storage-control/google/cloud/storage_control_v2/__init__.py @@ -104,7 +104,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -133,9 +133,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-storage-control/setup.py b/packages/google-cloud-storage-control/setup.py index 462cddfbec14..ac5d24ba2cff 100644 --- a/packages/google-cloud-storage-control/setup.py +++ b/packages/google-cloud-storage-control/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/storage_control/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-storage-control" diff --git a/packages/google-cloud-storage-control/testing/constraints-3.10.txt b/packages/google-cloud-storage-control/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-storage-control/testing/constraints-3.10.txt +++ b/packages/google-cloud-storage-control/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-storage-control/testing/constraints-3.13.txt b/packages/google-cloud-storage-control/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-storage-control/testing/constraints-3.13.txt +++ b/packages/google-cloud-storage-control/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-storage-control/testing/constraints-3.14.txt b/packages/google-cloud-storage-control/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-storage-control/testing/constraints-3.14.txt +++ b/packages/google-cloud-storage-control/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-storage-transfer/google/cloud/storage_transfer_v1/__init__.py b/packages/google-cloud-storage-transfer/google/cloud/storage_transfer_v1/__init__.py index e8a4639ea8e3..7dfeb7645faf 100644 --- a/packages/google-cloud-storage-transfer/google/cloud/storage_transfer_v1/__init__.py +++ b/packages/google-cloud-storage-transfer/google/cloud/storage_transfer_v1/__init__.py @@ -100,7 +100,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -129,9 +129,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-storage-transfer/setup.py b/packages/google-cloud-storage-transfer/setup.py index 36982fbbe3df..dbafea2eca36 100644 --- a/packages/google-cloud-storage-transfer/setup.py +++ b/packages/google-cloud-storage-transfer/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/storage_transfer/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-storage-transfer" diff --git a/packages/google-cloud-storage-transfer/testing/constraints-3.10.txt b/packages/google-cloud-storage-transfer/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-storage-transfer/testing/constraints-3.10.txt +++ b/packages/google-cloud-storage-transfer/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-storage-transfer/testing/constraints-3.13.txt b/packages/google-cloud-storage-transfer/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-storage-transfer/testing/constraints-3.13.txt +++ b/packages/google-cloud-storage-transfer/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-storage-transfer/testing/constraints-3.14.txt b/packages/google-cloud-storage-transfer/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-storage-transfer/testing/constraints-3.14.txt +++ b/packages/google-cloud-storage-transfer/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-storage/google/cloud/_storage_v2/__init__.py b/packages/google-cloud-storage/google/cloud/_storage_v2/__init__.py index cc6a108f30b2..44f646ecdf5a 100644 --- a/packages/google-cloud-storage/google/cloud/_storage_v2/__init__.py +++ b/packages/google-cloud-storage/google/cloud/_storage_v2/__init__.py @@ -108,7 +108,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -137,9 +137,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-storage/setup.py b/packages/google-cloud-storage/setup.py index 0f339a119486..b872eff7dbd8 100644 --- a/packages/google-cloud-storage/setup.py +++ b/packages/google-cloud-storage/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/_storage/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] diff --git a/packages/google-cloud-storagebatchoperations/google/cloud/storagebatchoperations_v1/__init__.py b/packages/google-cloud-storagebatchoperations/google/cloud/storagebatchoperations_v1/__init__.py index 282008b8c8bc..1cbeffeea172 100644 --- a/packages/google-cloud-storagebatchoperations/google/cloud/storagebatchoperations_v1/__init__.py +++ b/packages/google-cloud-storagebatchoperations/google/cloud/storagebatchoperations_v1/__init__.py @@ -85,7 +85,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -114,9 +114,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-storagebatchoperations/setup.py b/packages/google-cloud-storagebatchoperations/setup.py index a56b82d620e2..f053549ad73e 100644 --- a/packages/google-cloud-storagebatchoperations/setup.py +++ b/packages/google-cloud-storagebatchoperations/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/storagebatchoperations/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-storagebatchoperations" diff --git a/packages/google-cloud-storagebatchoperations/testing/constraints-3.10.txt b/packages/google-cloud-storagebatchoperations/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-storagebatchoperations/testing/constraints-3.10.txt +++ b/packages/google-cloud-storagebatchoperations/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-storagebatchoperations/testing/constraints-3.13.txt b/packages/google-cloud-storagebatchoperations/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-storagebatchoperations/testing/constraints-3.13.txt +++ b/packages/google-cloud-storagebatchoperations/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-storagebatchoperations/testing/constraints-3.14.txt b/packages/google-cloud-storagebatchoperations/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-storagebatchoperations/testing/constraints-3.14.txt +++ b/packages/google-cloud-storagebatchoperations/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-storageinsights/google/cloud/storageinsights_v1/__init__.py b/packages/google-cloud-storageinsights/google/cloud/storageinsights_v1/__init__.py index d9c422e41f25..5edeb233767b 100644 --- a/packages/google-cloud-storageinsights/google/cloud/storageinsights_v1/__init__.py +++ b/packages/google-cloud-storageinsights/google/cloud/storageinsights_v1/__init__.py @@ -82,7 +82,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -111,9 +111,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-storageinsights/setup.py b/packages/google-cloud-storageinsights/setup.py index 875651f634a5..df724f39c7ae 100644 --- a/packages/google-cloud-storageinsights/setup.py +++ b/packages/google-cloud-storageinsights/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/storageinsights/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-storageinsights" diff --git a/packages/google-cloud-storageinsights/testing/constraints-3.10.txt b/packages/google-cloud-storageinsights/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-storageinsights/testing/constraints-3.10.txt +++ b/packages/google-cloud-storageinsights/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-storageinsights/testing/constraints-3.13.txt b/packages/google-cloud-storageinsights/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-storageinsights/testing/constraints-3.13.txt +++ b/packages/google-cloud-storageinsights/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-storageinsights/testing/constraints-3.14.txt b/packages/google-cloud-storageinsights/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-storageinsights/testing/constraints-3.14.txt +++ b/packages/google-cloud-storageinsights/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-support/google/cloud/support_v2/__init__.py b/packages/google-cloud-support/google/cloud/support_v2/__init__.py index 9649728d5e9c..5c1776102997 100644 --- a/packages/google-cloud-support/google/cloud/support_v2/__init__.py +++ b/packages/google-cloud-support/google/cloud/support_v2/__init__.py @@ -84,7 +84,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -113,9 +113,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-support/google/cloud/support_v2beta/__init__.py b/packages/google-cloud-support/google/cloud/support_v2beta/__init__.py index b21dd23db19c..23e7f9d851f1 100644 --- a/packages/google-cloud-support/google/cloud/support_v2beta/__init__.py +++ b/packages/google-cloud-support/google/cloud/support_v2beta/__init__.py @@ -89,7 +89,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -118,9 +118,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-support/setup.py b/packages/google-cloud-support/setup.py index 85dacdc67f2b..1cd2cf3222cc 100644 --- a/packages/google-cloud-support/setup.py +++ b/packages/google-cloud-support/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/support/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-support" diff --git a/packages/google-cloud-support/testing/constraints-3.10.txt b/packages/google-cloud-support/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-support/testing/constraints-3.10.txt +++ b/packages/google-cloud-support/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-support/testing/constraints-3.13.txt b/packages/google-cloud-support/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-support/testing/constraints-3.13.txt +++ b/packages/google-cloud-support/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-support/testing/constraints-3.14.txt b/packages/google-cloud-support/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-support/testing/constraints-3.14.txt +++ b/packages/google-cloud-support/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-talent/google/cloud/talent_v4/__init__.py b/packages/google-cloud-talent/google/cloud/talent_v4/__init__.py index 0f2b7ee0a32b..63bc3f5def6f 100644 --- a/packages/google-cloud-talent/google/cloud/talent_v4/__init__.py +++ b/packages/google-cloud-talent/google/cloud/talent_v4/__init__.py @@ -117,7 +117,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -146,9 +146,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-talent/google/cloud/talent_v4beta1/__init__.py b/packages/google-cloud-talent/google/cloud/talent_v4beta1/__init__.py index 34cf5dd14249..189251e36f11 100644 --- a/packages/google-cloud-talent/google/cloud/talent_v4beta1/__init__.py +++ b/packages/google-cloud-talent/google/cloud/talent_v4beta1/__init__.py @@ -114,7 +114,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -143,9 +143,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-talent/setup.py b/packages/google-cloud-talent/setup.py index 82577fd8b8b8..f59aced32002 100644 --- a/packages/google-cloud-talent/setup.py +++ b/packages/google-cloud-talent/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/talent/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-talent" diff --git a/packages/google-cloud-talent/testing/constraints-3.10.txt b/packages/google-cloud-talent/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-talent/testing/constraints-3.10.txt +++ b/packages/google-cloud-talent/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-talent/testing/constraints-3.13.txt b/packages/google-cloud-talent/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-talent/testing/constraints-3.13.txt +++ b/packages/google-cloud-talent/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-talent/testing/constraints-3.14.txt b/packages/google-cloud-talent/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-talent/testing/constraints-3.14.txt +++ b/packages/google-cloud-talent/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-tasks/google/cloud/tasks_v2/__init__.py b/packages/google-cloud-tasks/google/cloud/tasks_v2/__init__.py index e2e6c2d5b104..4d5431a036c5 100644 --- a/packages/google-cloud-tasks/google/cloud/tasks_v2/__init__.py +++ b/packages/google-cloud-tasks/google/cloud/tasks_v2/__init__.py @@ -77,7 +77,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -106,9 +106,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-tasks/google/cloud/tasks_v2beta2/__init__.py b/packages/google-cloud-tasks/google/cloud/tasks_v2beta2/__init__.py index 8212d629baf4..da9fe6287eac 100644 --- a/packages/google-cloud-tasks/google/cloud/tasks_v2beta2/__init__.py +++ b/packages/google-cloud-tasks/google/cloud/tasks_v2beta2/__init__.py @@ -90,7 +90,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -119,9 +119,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-tasks/google/cloud/tasks_v2beta3/__init__.py b/packages/google-cloud-tasks/google/cloud/tasks_v2beta3/__init__.py index 69f0155ffa89..e7900a1d6b5e 100644 --- a/packages/google-cloud-tasks/google/cloud/tasks_v2beta3/__init__.py +++ b/packages/google-cloud-tasks/google/cloud/tasks_v2beta3/__init__.py @@ -89,7 +89,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -118,9 +118,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-tasks/setup.py b/packages/google-cloud-tasks/setup.py index 36fb9a623d04..23480d4779df 100644 --- a/packages/google-cloud-tasks/setup.py +++ b/packages/google-cloud-tasks/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/tasks/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-tasks" diff --git a/packages/google-cloud-tasks/testing/constraints-3.10.txt b/packages/google-cloud-tasks/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-tasks/testing/constraints-3.10.txt +++ b/packages/google-cloud-tasks/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-tasks/testing/constraints-3.13.txt b/packages/google-cloud-tasks/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-tasks/testing/constraints-3.13.txt +++ b/packages/google-cloud-tasks/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-tasks/testing/constraints-3.14.txt b/packages/google-cloud-tasks/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-tasks/testing/constraints-3.14.txt +++ b/packages/google-cloud-tasks/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-telcoautomation/google/cloud/telcoautomation_v1/__init__.py b/packages/google-cloud-telcoautomation/google/cloud/telcoautomation_v1/__init__.py index b3563c10f192..6d31533986a3 100644 --- a/packages/google-cloud-telcoautomation/google/cloud/telcoautomation_v1/__init__.py +++ b/packages/google-cloud-telcoautomation/google/cloud/telcoautomation_v1/__init__.py @@ -124,7 +124,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -153,9 +153,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-telcoautomation/google/cloud/telcoautomation_v1alpha1/__init__.py b/packages/google-cloud-telcoautomation/google/cloud/telcoautomation_v1alpha1/__init__.py index 91ee97c852b9..bd41994daae6 100644 --- a/packages/google-cloud-telcoautomation/google/cloud/telcoautomation_v1alpha1/__init__.py +++ b/packages/google-cloud-telcoautomation/google/cloud/telcoautomation_v1alpha1/__init__.py @@ -124,7 +124,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -153,9 +153,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-telcoautomation/setup.py b/packages/google-cloud-telcoautomation/setup.py index c92bf913c9e8..3b03f181a224 100644 --- a/packages/google-cloud-telcoautomation/setup.py +++ b/packages/google-cloud-telcoautomation/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/telcoautomation/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-telcoautomation" diff --git a/packages/google-cloud-telcoautomation/testing/constraints-3.10.txt b/packages/google-cloud-telcoautomation/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-telcoautomation/testing/constraints-3.10.txt +++ b/packages/google-cloud-telcoautomation/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-telcoautomation/testing/constraints-3.13.txt b/packages/google-cloud-telcoautomation/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-telcoautomation/testing/constraints-3.13.txt +++ b/packages/google-cloud-telcoautomation/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-telcoautomation/testing/constraints-3.14.txt b/packages/google-cloud-telcoautomation/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-telcoautomation/testing/constraints-3.14.txt +++ b/packages/google-cloud-telcoautomation/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-texttospeech/google/cloud/texttospeech_v1/__init__.py b/packages/google-cloud-texttospeech/google/cloud/texttospeech_v1/__init__.py index 93755da86ee2..2583f8c94a57 100644 --- a/packages/google-cloud-texttospeech/google/cloud/texttospeech_v1/__init__.py +++ b/packages/google-cloud-texttospeech/google/cloud/texttospeech_v1/__init__.py @@ -84,7 +84,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -113,9 +113,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-texttospeech/google/cloud/texttospeech_v1beta1/__init__.py b/packages/google-cloud-texttospeech/google/cloud/texttospeech_v1beta1/__init__.py index 0ac7c07db17e..777a5830fcd0 100644 --- a/packages/google-cloud-texttospeech/google/cloud/texttospeech_v1beta1/__init__.py +++ b/packages/google-cloud-texttospeech/google/cloud/texttospeech_v1beta1/__init__.py @@ -85,7 +85,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -114,9 +114,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-texttospeech/setup.py b/packages/google-cloud-texttospeech/setup.py index 6787142e1078..7bbe6fbed848 100644 --- a/packages/google-cloud-texttospeech/setup.py +++ b/packages/google-cloud-texttospeech/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/texttospeech/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-texttospeech" diff --git a/packages/google-cloud-texttospeech/testing/constraints-3.10.txt b/packages/google-cloud-texttospeech/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-texttospeech/testing/constraints-3.10.txt +++ b/packages/google-cloud-texttospeech/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-texttospeech/testing/constraints-3.13.txt b/packages/google-cloud-texttospeech/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-texttospeech/testing/constraints-3.13.txt +++ b/packages/google-cloud-texttospeech/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-texttospeech/testing/constraints-3.14.txt b/packages/google-cloud-texttospeech/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-texttospeech/testing/constraints-3.14.txt +++ b/packages/google-cloud-texttospeech/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-tpu/google/cloud/tpu_v1/__init__.py b/packages/google-cloud-tpu/google/cloud/tpu_v1/__init__.py index 2a61f42cd6be..7ca9bcb83552 100644 --- a/packages/google-cloud-tpu/google/cloud/tpu_v1/__init__.py +++ b/packages/google-cloud-tpu/google/cloud/tpu_v1/__init__.py @@ -73,7 +73,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -102,9 +102,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-tpu/google/cloud/tpu_v2/__init__.py b/packages/google-cloud-tpu/google/cloud/tpu_v2/__init__.py index c69b2ad5605d..3e907805e968 100644 --- a/packages/google-cloud-tpu/google/cloud/tpu_v2/__init__.py +++ b/packages/google-cloud-tpu/google/cloud/tpu_v2/__init__.py @@ -95,7 +95,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -124,9 +124,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-tpu/google/cloud/tpu_v2alpha1/__init__.py b/packages/google-cloud-tpu/google/cloud/tpu_v2alpha1/__init__.py index cd780ec23b07..a67c0bf953ca 100644 --- a/packages/google-cloud-tpu/google/cloud/tpu_v2alpha1/__init__.py +++ b/packages/google-cloud-tpu/google/cloud/tpu_v2alpha1/__init__.py @@ -104,7 +104,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -133,9 +133,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-tpu/setup.py b/packages/google-cloud-tpu/setup.py index ebf078b4b589..91c1e16a3b39 100644 --- a/packages/google-cloud-tpu/setup.py +++ b/packages/google-cloud-tpu/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/tpu/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-tpu" diff --git a/packages/google-cloud-tpu/testing/constraints-3.10.txt b/packages/google-cloud-tpu/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-tpu/testing/constraints-3.10.txt +++ b/packages/google-cloud-tpu/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-tpu/testing/constraints-3.13.txt b/packages/google-cloud-tpu/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-tpu/testing/constraints-3.13.txt +++ b/packages/google-cloud-tpu/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-tpu/testing/constraints-3.14.txt b/packages/google-cloud-tpu/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-tpu/testing/constraints-3.14.txt +++ b/packages/google-cloud-tpu/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-trace/google/cloud/trace_v1/__init__.py b/packages/google-cloud-trace/google/cloud/trace_v1/__init__.py index 61679a3445c2..44351fa12de9 100644 --- a/packages/google-cloud-trace/google/cloud/trace_v1/__init__.py +++ b/packages/google-cloud-trace/google/cloud/trace_v1/__init__.py @@ -59,7 +59,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -88,9 +88,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-trace/google/cloud/trace_v2/__init__.py b/packages/google-cloud-trace/google/cloud/trace_v2/__init__.py index 4b3f460d1ac4..6dae62900491 100644 --- a/packages/google-cloud-trace/google/cloud/trace_v2/__init__.py +++ b/packages/google-cloud-trace/google/cloud/trace_v2/__init__.py @@ -52,7 +52,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -81,9 +81,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-trace/setup.py b/packages/google-cloud-trace/setup.py index 4b8ded729adf..550f4d30d4c0 100644 --- a/packages/google-cloud-trace/setup.py +++ b/packages/google-cloud-trace/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/trace/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-trace" diff --git a/packages/google-cloud-trace/testing/constraints-3.10.txt b/packages/google-cloud-trace/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-trace/testing/constraints-3.10.txt +++ b/packages/google-cloud-trace/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-trace/testing/constraints-3.13.txt b/packages/google-cloud-trace/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-trace/testing/constraints-3.13.txt +++ b/packages/google-cloud-trace/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-trace/testing/constraints-3.14.txt b/packages/google-cloud-trace/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-trace/testing/constraints-3.14.txt +++ b/packages/google-cloud-trace/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-translate/google/cloud/translate_v3/__init__.py b/packages/google-cloud-translate/google/cloud/translate_v3/__init__.py index 5d37c2dd5d73..06fdb44d9e8f 100644 --- a/packages/google-cloud-translate/google/cloud/translate_v3/__init__.py +++ b/packages/google-cloud-translate/google/cloud/translate_v3/__init__.py @@ -161,7 +161,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -190,9 +190,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-translate/google/cloud/translate_v3beta1/__init__.py b/packages/google-cloud-translate/google/cloud/translate_v3beta1/__init__.py index 1983fb0586dc..10492b805c39 100644 --- a/packages/google-cloud-translate/google/cloud/translate_v3beta1/__init__.py +++ b/packages/google-cloud-translate/google/cloud/translate_v3beta1/__init__.py @@ -95,7 +95,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -124,9 +124,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-translate/setup.py b/packages/google-cloud-translate/setup.py index c79b32162195..b32c7f6572ea 100644 --- a/packages/google-cloud-translate/setup.py +++ b/packages/google-cloud-translate/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/translate/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,17 +42,16 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "google-cloud-core >= 2.0.0, <3.0.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-translate" diff --git a/packages/google-cloud-translate/testing/constraints-3.10.txt b/packages/google-cloud-translate/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-translate/testing/constraints-3.10.txt +++ b/packages/google-cloud-translate/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-translate/testing/constraints-3.13.txt b/packages/google-cloud-translate/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-translate/testing/constraints-3.13.txt +++ b/packages/google-cloud-translate/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-translate/testing/constraints-3.14.txt b/packages/google-cloud-translate/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-translate/testing/constraints-3.14.txt +++ b/packages/google-cloud-translate/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-vectorsearch/google/cloud/vectorsearch_v1/__init__.py b/packages/google-cloud-vectorsearch/google/cloud/vectorsearch_v1/__init__.py index 5e1efa6bdf92..6113a04a7798 100644 --- a/packages/google-cloud-vectorsearch/google/cloud/vectorsearch_v1/__init__.py +++ b/packages/google-cloud-vectorsearch/google/cloud/vectorsearch_v1/__init__.py @@ -124,7 +124,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -153,9 +153,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-vectorsearch/google/cloud/vectorsearch_v1beta/__init__.py b/packages/google-cloud-vectorsearch/google/cloud/vectorsearch_v1beta/__init__.py index 7ccbf95e312d..1710753bcc45 100644 --- a/packages/google-cloud-vectorsearch/google/cloud/vectorsearch_v1beta/__init__.py +++ b/packages/google-cloud-vectorsearch/google/cloud/vectorsearch_v1beta/__init__.py @@ -126,7 +126,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -155,9 +155,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-vectorsearch/setup.py b/packages/google-cloud-vectorsearch/setup.py index d1b95b1755fa..0da7fb2df079 100644 --- a/packages/google-cloud-vectorsearch/setup.py +++ b/packages/google-cloud-vectorsearch/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/vectorsearch/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-vectorsearch" diff --git a/packages/google-cloud-vectorsearch/testing/constraints-3.10.txt b/packages/google-cloud-vectorsearch/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-vectorsearch/testing/constraints-3.10.txt +++ b/packages/google-cloud-vectorsearch/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-vectorsearch/testing/constraints-3.13.txt b/packages/google-cloud-vectorsearch/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-vectorsearch/testing/constraints-3.13.txt +++ b/packages/google-cloud-vectorsearch/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-vectorsearch/testing/constraints-3.14.txt b/packages/google-cloud-vectorsearch/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-vectorsearch/testing/constraints-3.14.txt +++ b/packages/google-cloud-vectorsearch/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-video-live-stream/google/cloud/video/live_stream_v1/__init__.py b/packages/google-cloud-video-live-stream/google/cloud/video/live_stream_v1/__init__.py index 2f13f62540b1..9047532fff1f 100644 --- a/packages/google-cloud-video-live-stream/google/cloud/video/live_stream_v1/__init__.py +++ b/packages/google-cloud-video-live-stream/google/cloud/video/live_stream_v1/__init__.py @@ -139,7 +139,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -168,9 +168,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-video-live-stream/setup.py b/packages/google-cloud-video-live-stream/setup.py index 7377ca4fc650..05f2a253529a 100644 --- a/packages/google-cloud-video-live-stream/setup.py +++ b/packages/google-cloud-video-live-stream/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/video/live_stream/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-video-live-stream" diff --git a/packages/google-cloud-video-live-stream/testing/constraints-3.10.txt b/packages/google-cloud-video-live-stream/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-video-live-stream/testing/constraints-3.10.txt +++ b/packages/google-cloud-video-live-stream/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-video-live-stream/testing/constraints-3.13.txt b/packages/google-cloud-video-live-stream/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-video-live-stream/testing/constraints-3.13.txt +++ b/packages/google-cloud-video-live-stream/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-video-live-stream/testing/constraints-3.14.txt b/packages/google-cloud-video-live-stream/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-video-live-stream/testing/constraints-3.14.txt +++ b/packages/google-cloud-video-live-stream/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-video-stitcher/google/cloud/video/stitcher_v1/__init__.py b/packages/google-cloud-video-stitcher/google/cloud/video/stitcher_v1/__init__.py index 9a643521e403..fada95aa2269 100644 --- a/packages/google-cloud-video-stitcher/google/cloud/video/stitcher_v1/__init__.py +++ b/packages/google-cloud-video-stitcher/google/cloud/video/stitcher_v1/__init__.py @@ -124,7 +124,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -153,9 +153,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-video-stitcher/setup.py b/packages/google-cloud-video-stitcher/setup.py index 57fcc6a1b62d..f65ee6ba9e2c 100644 --- a/packages/google-cloud-video-stitcher/setup.py +++ b/packages/google-cloud-video-stitcher/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/video/stitcher/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-video-stitcher" diff --git a/packages/google-cloud-video-stitcher/testing/constraints-3.10.txt b/packages/google-cloud-video-stitcher/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-video-stitcher/testing/constraints-3.10.txt +++ b/packages/google-cloud-video-stitcher/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-video-stitcher/testing/constraints-3.13.txt b/packages/google-cloud-video-stitcher/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-video-stitcher/testing/constraints-3.13.txt +++ b/packages/google-cloud-video-stitcher/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-video-stitcher/testing/constraints-3.14.txt b/packages/google-cloud-video-stitcher/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-video-stitcher/testing/constraints-3.14.txt +++ b/packages/google-cloud-video-stitcher/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-video-transcoder/google/cloud/video/transcoder_v1/__init__.py b/packages/google-cloud-video-transcoder/google/cloud/video/transcoder_v1/__init__.py index 010bea2804c5..24393a0fc125 100644 --- a/packages/google-cloud-video-transcoder/google/cloud/video/transcoder_v1/__init__.py +++ b/packages/google-cloud-video-transcoder/google/cloud/video/transcoder_v1/__init__.py @@ -88,7 +88,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -117,9 +117,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-video-transcoder/setup.py b/packages/google-cloud-video-transcoder/setup.py index add5a553a150..cfd187ced81b 100644 --- a/packages/google-cloud-video-transcoder/setup.py +++ b/packages/google-cloud-video-transcoder/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/video/transcoder/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-video-transcoder" diff --git a/packages/google-cloud-video-transcoder/testing/constraints-3.10.txt b/packages/google-cloud-video-transcoder/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-video-transcoder/testing/constraints-3.10.txt +++ b/packages/google-cloud-video-transcoder/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-video-transcoder/testing/constraints-3.13.txt b/packages/google-cloud-video-transcoder/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-video-transcoder/testing/constraints-3.13.txt +++ b/packages/google-cloud-video-transcoder/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-video-transcoder/testing/constraints-3.14.txt b/packages/google-cloud-video-transcoder/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-video-transcoder/testing/constraints-3.14.txt +++ b/packages/google-cloud-video-transcoder/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/__init__.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/__init__.py index e9e9ee740f5f..9690037e2693 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/__init__.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/__init__.py @@ -101,7 +101,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -130,9 +130,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/__init__.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/__init__.py index 1d37f3041354..88f8c2be2d08 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/__init__.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/__init__.py @@ -79,7 +79,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -108,9 +108,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/__init__.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/__init__.py index e26b9cdf6a01..7bf3f10906be 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/__init__.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/__init__.py @@ -79,7 +79,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -108,9 +108,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/__init__.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/__init__.py index 20a3ba3c4724..c01580d89eed 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/__init__.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/__init__.py @@ -83,7 +83,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -112,9 +112,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/__init__.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/__init__.py index 77686a4543a0..2d0d035a3b64 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/__init__.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/__init__.py @@ -118,7 +118,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -147,9 +147,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-videointelligence/setup.py b/packages/google-cloud-videointelligence/setup.py index 3573c98f7480..f026a3b3c878 100644 --- a/packages/google-cloud-videointelligence/setup.py +++ b/packages/google-cloud-videointelligence/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/videointelligence/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-videointelligence" diff --git a/packages/google-cloud-videointelligence/testing/constraints-3.10.txt b/packages/google-cloud-videointelligence/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-videointelligence/testing/constraints-3.10.txt +++ b/packages/google-cloud-videointelligence/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-videointelligence/testing/constraints-3.13.txt b/packages/google-cloud-videointelligence/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-videointelligence/testing/constraints-3.13.txt +++ b/packages/google-cloud-videointelligence/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-videointelligence/testing/constraints-3.14.txt b/packages/google-cloud-videointelligence/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-videointelligence/testing/constraints-3.14.txt +++ b/packages/google-cloud-videointelligence/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-vision/google/cloud/vision_v1/__init__.py b/packages/google-cloud-vision/google/cloud/vision_v1/__init__.py index ad4531c6cea7..e37a4e8188c0 100644 --- a/packages/google-cloud-vision/google/cloud/vision_v1/__init__.py +++ b/packages/google-cloud-vision/google/cloud/vision_v1/__init__.py @@ -134,7 +134,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -163,9 +163,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-vision/google/cloud/vision_v1p1beta1/__init__.py b/packages/google-cloud-vision/google/cloud/vision_v1p1beta1/__init__.py index 63385ec4b144..32fddf6282cd 100644 --- a/packages/google-cloud-vision/google/cloud/vision_v1p1beta1/__init__.py +++ b/packages/google-cloud-vision/google/cloud/vision_v1p1beta1/__init__.py @@ -82,7 +82,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -111,9 +111,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-vision/google/cloud/vision_v1p2beta1/__init__.py b/packages/google-cloud-vision/google/cloud/vision_v1p2beta1/__init__.py index 6c9a922ae9be..156cfcbfdaf3 100644 --- a/packages/google-cloud-vision/google/cloud/vision_v1p2beta1/__init__.py +++ b/packages/google-cloud-vision/google/cloud/vision_v1p2beta1/__init__.py @@ -93,7 +93,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -122,9 +122,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-vision/google/cloud/vision_v1p3beta1/__init__.py b/packages/google-cloud-vision/google/cloud/vision_v1p3beta1/__init__.py index 5f68e4357fe4..c3a0ca19dfeb 100644 --- a/packages/google-cloud-vision/google/cloud/vision_v1p3beta1/__init__.py +++ b/packages/google-cloud-vision/google/cloud/vision_v1p3beta1/__init__.py @@ -127,7 +127,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -156,9 +156,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-vision/google/cloud/vision_v1p4beta1/__init__.py b/packages/google-cloud-vision/google/cloud/vision_v1p4beta1/__init__.py index 415eedaa8838..99039b68dcfa 100644 --- a/packages/google-cloud-vision/google/cloud/vision_v1p4beta1/__init__.py +++ b/packages/google-cloud-vision/google/cloud/vision_v1p4beta1/__init__.py @@ -135,7 +135,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -164,9 +164,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-vision/setup.py b/packages/google-cloud-vision/setup.py index c3b44abecd05..1d9adf89627c 100644 --- a/packages/google-cloud-vision/setup.py +++ b/packages/google-cloud-vision/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/vision/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-vision" diff --git a/packages/google-cloud-vision/testing/constraints-3.10.txt b/packages/google-cloud-vision/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-vision/testing/constraints-3.10.txt +++ b/packages/google-cloud-vision/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-vision/testing/constraints-3.13.txt b/packages/google-cloud-vision/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-vision/testing/constraints-3.13.txt +++ b/packages/google-cloud-vision/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-vision/testing/constraints-3.14.txt b/packages/google-cloud-vision/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-vision/testing/constraints-3.14.txt +++ b/packages/google-cloud-vision/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-visionai/google/cloud/visionai_v1/__init__.py b/packages/google-cloud-visionai/google/cloud/visionai_v1/__init__.py index be5b2569f01d..14462be39420 100644 --- a/packages/google-cloud-visionai/google/cloud/visionai_v1/__init__.py +++ b/packages/google-cloud-visionai/google/cloud/visionai_v1/__init__.py @@ -421,7 +421,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -450,9 +450,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-visionai/google/cloud/visionai_v1alpha1/__init__.py b/packages/google-cloud-visionai/google/cloud/visionai_v1alpha1/__init__.py index 911275f59ea5..fe1456cef925 100644 --- a/packages/google-cloud-visionai/google/cloud/visionai_v1alpha1/__init__.py +++ b/packages/google-cloud-visionai/google/cloud/visionai_v1alpha1/__init__.py @@ -296,7 +296,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -325,9 +325,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-visionai/setup.py b/packages/google-cloud-visionai/setup.py index b3c81042e3e9..368bc1872711 100644 --- a/packages/google-cloud-visionai/setup.py +++ b/packages/google-cloud-visionai/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/visionai/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-visionai" diff --git a/packages/google-cloud-visionai/testing/constraints-3.10.txt b/packages/google-cloud-visionai/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-visionai/testing/constraints-3.10.txt +++ b/packages/google-cloud-visionai/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-visionai/testing/constraints-3.13.txt b/packages/google-cloud-visionai/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-visionai/testing/constraints-3.13.txt +++ b/packages/google-cloud-visionai/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-visionai/testing/constraints-3.14.txt b/packages/google-cloud-visionai/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-visionai/testing/constraints-3.14.txt +++ b/packages/google-cloud-visionai/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-vm-migration/google/cloud/vmmigration_v1/__init__.py b/packages/google-cloud-vm-migration/google/cloud/vmmigration_v1/__init__.py index 2c93ea92ac72..841e632a4408 100644 --- a/packages/google-cloud-vm-migration/google/cloud/vmmigration_v1/__init__.py +++ b/packages/google-cloud-vm-migration/google/cloud/vmmigration_v1/__init__.py @@ -235,7 +235,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -264,9 +264,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-vm-migration/setup.py b/packages/google-cloud-vm-migration/setup.py index d3acee99be47..dc2266d98558 100644 --- a/packages/google-cloud-vm-migration/setup.py +++ b/packages/google-cloud-vm-migration/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/vmmigration/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-vm-migration" diff --git a/packages/google-cloud-vm-migration/testing/constraints-3.10.txt b/packages/google-cloud-vm-migration/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-vm-migration/testing/constraints-3.10.txt +++ b/packages/google-cloud-vm-migration/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-vm-migration/testing/constraints-3.13.txt b/packages/google-cloud-vm-migration/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-vm-migration/testing/constraints-3.13.txt +++ b/packages/google-cloud-vm-migration/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-vm-migration/testing/constraints-3.14.txt b/packages/google-cloud-vm-migration/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-vm-migration/testing/constraints-3.14.txt +++ b/packages/google-cloud-vm-migration/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-vmwareengine/google/cloud/vmwareengine_v1/__init__.py b/packages/google-cloud-vmwareengine/google/cloud/vmwareengine_v1/__init__.py index 72640fb1d286..34f4ec5d5c30 100644 --- a/packages/google-cloud-vmwareengine/google/cloud/vmwareengine_v1/__init__.py +++ b/packages/google-cloud-vmwareengine/google/cloud/vmwareengine_v1/__init__.py @@ -173,7 +173,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -202,9 +202,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-vmwareengine/setup.py b/packages/google-cloud-vmwareengine/setup.py index 53d0bd968b92..79b66e1bc1d8 100644 --- a/packages/google-cloud-vmwareengine/setup.py +++ b/packages/google-cloud-vmwareengine/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/vmwareengine/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-vmwareengine" diff --git a/packages/google-cloud-vmwareengine/testing/constraints-3.10.txt b/packages/google-cloud-vmwareengine/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-vmwareengine/testing/constraints-3.10.txt +++ b/packages/google-cloud-vmwareengine/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-vmwareengine/testing/constraints-3.13.txt b/packages/google-cloud-vmwareengine/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-vmwareengine/testing/constraints-3.13.txt +++ b/packages/google-cloud-vmwareengine/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-vmwareengine/testing/constraints-3.14.txt b/packages/google-cloud-vmwareengine/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-vmwareengine/testing/constraints-3.14.txt +++ b/packages/google-cloud-vmwareengine/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-vpc-access/google/cloud/vpcaccess_v1/__init__.py b/packages/google-cloud-vpc-access/google/cloud/vpcaccess_v1/__init__.py index e85a2c101470..bc21f07c112a 100644 --- a/packages/google-cloud-vpc-access/google/cloud/vpcaccess_v1/__init__.py +++ b/packages/google-cloud-vpc-access/google/cloud/vpcaccess_v1/__init__.py @@ -62,7 +62,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -91,9 +91,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-vpc-access/setup.py b/packages/google-cloud-vpc-access/setup.py index d8665c6bd1c4..674ed837bbf8 100644 --- a/packages/google-cloud-vpc-access/setup.py +++ b/packages/google-cloud-vpc-access/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/vpcaccess/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-vpc-access" diff --git a/packages/google-cloud-vpc-access/testing/constraints-3.10.txt b/packages/google-cloud-vpc-access/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-vpc-access/testing/constraints-3.10.txt +++ b/packages/google-cloud-vpc-access/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-vpc-access/testing/constraints-3.13.txt b/packages/google-cloud-vpc-access/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-vpc-access/testing/constraints-3.13.txt +++ b/packages/google-cloud-vpc-access/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-vpc-access/testing/constraints-3.14.txt b/packages/google-cloud-vpc-access/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-vpc-access/testing/constraints-3.14.txt +++ b/packages/google-cloud-vpc-access/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-webrisk/google/cloud/webrisk_v1/__init__.py b/packages/google-cloud-webrisk/google/cloud/webrisk_v1/__init__.py index 389b932e51ca..2d29bdb83e89 100644 --- a/packages/google-cloud-webrisk/google/cloud/webrisk_v1/__init__.py +++ b/packages/google-cloud-webrisk/google/cloud/webrisk_v1/__init__.py @@ -71,7 +71,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -100,9 +100,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-webrisk/google/cloud/webrisk_v1beta1/__init__.py b/packages/google-cloud-webrisk/google/cloud/webrisk_v1beta1/__init__.py index 2f2e2656a942..52af7aac3686 100644 --- a/packages/google-cloud-webrisk/google/cloud/webrisk_v1beta1/__init__.py +++ b/packages/google-cloud-webrisk/google/cloud/webrisk_v1beta1/__init__.py @@ -68,7 +68,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -97,9 +97,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-webrisk/setup.py b/packages/google-cloud-webrisk/setup.py index 993bdd3378ba..f7ecf8ce0623 100644 --- a/packages/google-cloud-webrisk/setup.py +++ b/packages/google-cloud-webrisk/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/webrisk/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-webrisk" diff --git a/packages/google-cloud-webrisk/testing/constraints-3.10.txt b/packages/google-cloud-webrisk/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-webrisk/testing/constraints-3.10.txt +++ b/packages/google-cloud-webrisk/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-webrisk/testing/constraints-3.13.txt b/packages/google-cloud-webrisk/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-webrisk/testing/constraints-3.13.txt +++ b/packages/google-cloud-webrisk/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-webrisk/testing/constraints-3.14.txt b/packages/google-cloud-webrisk/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-webrisk/testing/constraints-3.14.txt +++ b/packages/google-cloud-webrisk/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-websecurityscanner/google/cloud/websecurityscanner_v1/__init__.py b/packages/google-cloud-websecurityscanner/google/cloud/websecurityscanner_v1/__init__.py index 3f09af7f9c4b..3f51dc4ec113 100644 --- a/packages/google-cloud-websecurityscanner/google/cloud/websecurityscanner_v1/__init__.py +++ b/packages/google-cloud-websecurityscanner/google/cloud/websecurityscanner_v1/__init__.py @@ -91,7 +91,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -120,9 +120,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-websecurityscanner/google/cloud/websecurityscanner_v1alpha/__init__.py b/packages/google-cloud-websecurityscanner/google/cloud/websecurityscanner_v1alpha/__init__.py index cbbd5ed1895a..c3d50586fb61 100644 --- a/packages/google-cloud-websecurityscanner/google/cloud/websecurityscanner_v1alpha/__init__.py +++ b/packages/google-cloud-websecurityscanner/google/cloud/websecurityscanner_v1alpha/__init__.py @@ -85,7 +85,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -114,9 +114,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-websecurityscanner/google/cloud/websecurityscanner_v1beta/__init__.py b/packages/google-cloud-websecurityscanner/google/cloud/websecurityscanner_v1beta/__init__.py index a205a1727d67..b0a6ed45e031 100644 --- a/packages/google-cloud-websecurityscanner/google/cloud/websecurityscanner_v1beta/__init__.py +++ b/packages/google-cloud-websecurityscanner/google/cloud/websecurityscanner_v1beta/__init__.py @@ -89,7 +89,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -118,9 +118,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-websecurityscanner/setup.py b/packages/google-cloud-websecurityscanner/setup.py index 57f3e54bd80d..eba5f3bc1840 100644 --- a/packages/google-cloud-websecurityscanner/setup.py +++ b/packages/google-cloud-websecurityscanner/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/websecurityscanner/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-websecurityscanner" diff --git a/packages/google-cloud-websecurityscanner/testing/constraints-3.10.txt b/packages/google-cloud-websecurityscanner/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-websecurityscanner/testing/constraints-3.10.txt +++ b/packages/google-cloud-websecurityscanner/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-websecurityscanner/testing/constraints-3.13.txt b/packages/google-cloud-websecurityscanner/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-websecurityscanner/testing/constraints-3.13.txt +++ b/packages/google-cloud-websecurityscanner/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-websecurityscanner/testing/constraints-3.14.txt b/packages/google-cloud-websecurityscanner/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-websecurityscanner/testing/constraints-3.14.txt +++ b/packages/google-cloud-websecurityscanner/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-workflows/google/cloud/workflows/executions_v1/__init__.py b/packages/google-cloud-workflows/google/cloud/workflows/executions_v1/__init__.py index 378371c379a0..42bdf27d9121 100644 --- a/packages/google-cloud-workflows/google/cloud/workflows/executions_v1/__init__.py +++ b/packages/google-cloud-workflows/google/cloud/workflows/executions_v1/__init__.py @@ -59,7 +59,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -88,9 +88,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-workflows/google/cloud/workflows/executions_v1beta/__init__.py b/packages/google-cloud-workflows/google/cloud/workflows/executions_v1beta/__init__.py index 33352d0d3b15..0edd35c8aef6 100644 --- a/packages/google-cloud-workflows/google/cloud/workflows/executions_v1beta/__init__.py +++ b/packages/google-cloud-workflows/google/cloud/workflows/executions_v1beta/__init__.py @@ -59,7 +59,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -88,9 +88,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-workflows/google/cloud/workflows_v1/__init__.py b/packages/google-cloud-workflows/google/cloud/workflows_v1/__init__.py index 76f0ccfb42b4..854f1d40757e 100644 --- a/packages/google-cloud-workflows/google/cloud/workflows_v1/__init__.py +++ b/packages/google-cloud-workflows/google/cloud/workflows_v1/__init__.py @@ -63,7 +63,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -92,9 +92,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-workflows/google/cloud/workflows_v1beta/__init__.py b/packages/google-cloud-workflows/google/cloud/workflows_v1beta/__init__.py index b9da95f8c9fa..10e355bde3b4 100644 --- a/packages/google-cloud-workflows/google/cloud/workflows_v1beta/__init__.py +++ b/packages/google-cloud-workflows/google/cloud/workflows_v1beta/__init__.py @@ -60,7 +60,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -89,9 +89,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-workflows/setup.py b/packages/google-cloud-workflows/setup.py index fddb078de9fb..5e02c2029645 100644 --- a/packages/google-cloud-workflows/setup.py +++ b/packages/google-cloud-workflows/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/cloud/workflows/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-workflows" diff --git a/packages/google-cloud-workflows/testing/constraints-3.10.txt b/packages/google-cloud-workflows/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-workflows/testing/constraints-3.10.txt +++ b/packages/google-cloud-workflows/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-workflows/testing/constraints-3.13.txt b/packages/google-cloud-workflows/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-workflows/testing/constraints-3.13.txt +++ b/packages/google-cloud-workflows/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-workflows/testing/constraints-3.14.txt b/packages/google-cloud-workflows/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-workflows/testing/constraints-3.14.txt +++ b/packages/google-cloud-workflows/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-workloadmanager/google/cloud/workloadmanager_v1/__init__.py b/packages/google-cloud-workloadmanager/google/cloud/workloadmanager_v1/__init__.py index 5a8e6ed77d10..0cca8a0318d4 100644 --- a/packages/google-cloud-workloadmanager/google/cloud/workloadmanager_v1/__init__.py +++ b/packages/google-cloud-workloadmanager/google/cloud/workloadmanager_v1/__init__.py @@ -86,7 +86,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -115,9 +115,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-workloadmanager/setup.py b/packages/google-cloud-workloadmanager/setup.py index 4746534cd2e1..f5bd88b3b67f 100644 --- a/packages/google-cloud-workloadmanager/setup.py +++ b/packages/google-cloud-workloadmanager/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/workloadmanager/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-workloadmanager" diff --git a/packages/google-cloud-workloadmanager/testing/constraints-3.10.txt b/packages/google-cloud-workloadmanager/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-cloud-workloadmanager/testing/constraints-3.10.txt +++ b/packages/google-cloud-workloadmanager/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-workloadmanager/testing/constraints-3.13.txt b/packages/google-cloud-workloadmanager/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-workloadmanager/testing/constraints-3.13.txt +++ b/packages/google-cloud-workloadmanager/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-workloadmanager/testing/constraints-3.14.txt b/packages/google-cloud-workloadmanager/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-cloud-workloadmanager/testing/constraints-3.14.txt +++ b/packages/google-cloud-workloadmanager/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-cloud-workstations/google/cloud/workstations_v1/__init__.py b/packages/google-cloud-workstations/google/cloud/workstations_v1/__init__.py index 324dff0b595b..d0e618414dca 100644 --- a/packages/google-cloud-workstations/google/cloud/workstations_v1/__init__.py +++ b/packages/google-cloud-workstations/google/cloud/workstations_v1/__init__.py @@ -82,7 +82,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -111,9 +111,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-workstations/google/cloud/workstations_v1beta/__init__.py b/packages/google-cloud-workstations/google/cloud/workstations_v1beta/__init__.py index 1a0ed5c51123..2d41ff26af33 100644 --- a/packages/google-cloud-workstations/google/cloud/workstations_v1beta/__init__.py +++ b/packages/google-cloud-workstations/google/cloud/workstations_v1beta/__init__.py @@ -84,7 +84,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -113,9 +113,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-cloud-workstations/setup.py b/packages/google-cloud-workstations/setup.py index 2f2874b979a1..312cf8146d5c 100644 --- a/packages/google-cloud-workstations/setup.py +++ b/packages/google-cloud-workstations/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/cloud/workstations/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "grpc-google-iam-v1 >= 0.14.2, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-workstations" diff --git a/packages/google-cloud-workstations/testing/constraints-3.10.txt b/packages/google-cloud-workstations/testing/constraints-3.10.txt index b39cd54634f9..3a84666fb90e 100644 --- a/packages/google-cloud-workstations/testing/constraints-3.10.txt +++ b/packages/google-cloud-workstations/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -grpc-google-iam-v1==0.14.0 +proto-plus==1.26.1 +protobuf==6.33.5 +grpc-google-iam-v1==0.14.2 diff --git a/packages/google-cloud-workstations/testing/constraints-3.13.txt b/packages/google-cloud-workstations/testing/constraints-3.13.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-workstations/testing/constraints-3.13.txt +++ b/packages/google-cloud-workstations/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-cloud-workstations/testing/constraints-3.14.txt b/packages/google-cloud-workstations/testing/constraints-3.14.txt index 2ae5a677e852..f85022a2fb62 100644 --- a/packages/google-cloud-workstations/testing/constraints-3.14.txt +++ b/packages/google-cloud-workstations/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 grpc-google-iam-v1>=0 diff --git a/packages/google-developer-knowledge/google/developer_knowledge_v1/__init__.py b/packages/google-developer-knowledge/google/developer_knowledge_v1/__init__.py index 7ea2fc16961e..075278bba7e4 100644 --- a/packages/google-developer-knowledge/google/developer_knowledge_v1/__init__.py +++ b/packages/google-developer-knowledge/google/developer_knowledge_v1/__init__.py @@ -63,7 +63,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -92,9 +92,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-developer-knowledge/setup.py b/packages/google-developer-knowledge/setup.py index 7feece0e9cd6..c3942c02af48 100644 --- a/packages/google-developer-knowledge/setup.py +++ b/packages/google-developer-knowledge/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/developer_knowledge/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-developer-knowledge" diff --git a/packages/google-developer-knowledge/testing/constraints-3.10.txt b/packages/google-developer-knowledge/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-developer-knowledge/testing/constraints-3.10.txt +++ b/packages/google-developer-knowledge/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-developer-knowledge/testing/constraints-3.13.txt b/packages/google-developer-knowledge/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-developer-knowledge/testing/constraints-3.13.txt +++ b/packages/google-developer-knowledge/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-developer-knowledge/testing/constraints-3.14.txt b/packages/google-developer-knowledge/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-developer-knowledge/testing/constraints-3.14.txt +++ b/packages/google-developer-knowledge/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/__init__.py b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/__init__.py index c6014be40728..3929447111d5 100644 --- a/packages/google-devicesandservices-health/google/devicesandservices/health_v4/__init__.py +++ b/packages/google-devicesandservices-health/google/devicesandservices/health_v4/__init__.py @@ -209,7 +209,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -238,9 +238,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-devicesandservices-health/setup.py b/packages/google-devicesandservices-health/setup.py index b87889d68543..5c592f85c234 100644 --- a/packages/google-devicesandservices-health/setup.py +++ b/packages/google-devicesandservices-health/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/devicesandservices/health/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-devicesandservices-health" diff --git a/packages/google-devicesandservices-health/testing/constraints-3.10.txt b/packages/google-devicesandservices-health/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-devicesandservices-health/testing/constraints-3.10.txt +++ b/packages/google-devicesandservices-health/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-devicesandservices-health/testing/constraints-3.13.txt b/packages/google-devicesandservices-health/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-devicesandservices-health/testing/constraints-3.13.txt +++ b/packages/google-devicesandservices-health/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-devicesandservices-health/testing/constraints-3.14.txt b/packages/google-devicesandservices-health/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-devicesandservices-health/testing/constraints-3.14.txt +++ b/packages/google-devicesandservices-health/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-geo-type/google/geo/type/__init__.py b/packages/google-geo-type/google/geo/type/__init__.py index e69ed30b7b6d..e88eaba90537 100644 --- a/packages/google-geo-type/google/geo/type/__init__.py +++ b/packages/google-geo-type/google/geo/type/__init__.py @@ -50,7 +50,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -79,9 +79,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-geo-type/setup.py b/packages/google-geo-type/setup.py index ead51acc329a..1deaa98f0943 100644 --- a/packages/google-geo-type/setup.py +++ b/packages/google-geo-type/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/geo/type/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-geo-type" diff --git a/packages/google-geo-type/testing/constraints-3.10.txt b/packages/google-geo-type/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-geo-type/testing/constraints-3.10.txt +++ b/packages/google-geo-type/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-geo-type/testing/constraints-3.13.txt b/packages/google-geo-type/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-geo-type/testing/constraints-3.13.txt +++ b/packages/google-geo-type/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-geo-type/testing/constraints-3.14.txt b/packages/google-geo-type/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-geo-type/testing/constraints-3.14.txt +++ b/packages/google-geo-type/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-maps-addressvalidation/google/maps/addressvalidation_v1/__init__.py b/packages/google-maps-addressvalidation/google/maps/addressvalidation_v1/__init__.py index fe473316a703..2e2577e17a3f 100644 --- a/packages/google-maps-addressvalidation/google/maps/addressvalidation_v1/__init__.py +++ b/packages/google-maps-addressvalidation/google/maps/addressvalidation_v1/__init__.py @@ -65,7 +65,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -94,9 +94,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-maps-addressvalidation/setup.py b/packages/google-maps-addressvalidation/setup.py index bd661bcc6605..f941d7de681e 100644 --- a/packages/google-maps-addressvalidation/setup.py +++ b/packages/google-maps-addressvalidation/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/maps/addressvalidation/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "google-geo-type >= 0.1.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "google-geo-type >= 0.3.12, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-maps-addressvalidation" diff --git a/packages/google-maps-addressvalidation/testing/constraints-3.10.txt b/packages/google-maps-addressvalidation/testing/constraints-3.10.txt index ea5951376612..ee60d295a792 100644 --- a/packages/google-maps-addressvalidation/testing/constraints-3.10.txt +++ b/packages/google-maps-addressvalidation/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -google-geo-type==0.1.0 +proto-plus==1.26.1 +protobuf==6.33.5 +google-geo-type==0.3.12 diff --git a/packages/google-maps-addressvalidation/testing/constraints-3.13.txt b/packages/google-maps-addressvalidation/testing/constraints-3.13.txt index c6b6ca67e783..5c8b50a29836 100644 --- a/packages/google-maps-addressvalidation/testing/constraints-3.13.txt +++ b/packages/google-maps-addressvalidation/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-geo-type>=0 diff --git a/packages/google-maps-addressvalidation/testing/constraints-3.14.txt b/packages/google-maps-addressvalidation/testing/constraints-3.14.txt index c6b6ca67e783..5c8b50a29836 100644 --- a/packages/google-maps-addressvalidation/testing/constraints-3.14.txt +++ b/packages/google-maps-addressvalidation/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-geo-type>=0 diff --git a/packages/google-maps-areainsights/google/maps/areainsights_v1/__init__.py b/packages/google-maps-areainsights/google/maps/areainsights_v1/__init__.py index e790d5492c98..7eb80ddb96c4 100644 --- a/packages/google-maps-areainsights/google/maps/areainsights_v1/__init__.py +++ b/packages/google-maps-areainsights/google/maps/areainsights_v1/__init__.py @@ -62,7 +62,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -91,9 +91,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-maps-areainsights/setup.py b/packages/google-maps-areainsights/setup.py index 9f670777e6fe..86bfa4c4e78d 100644 --- a/packages/google-maps-areainsights/setup.py +++ b/packages/google-maps-areainsights/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/maps/areainsights/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-maps-areainsights" diff --git a/packages/google-maps-areainsights/testing/constraints-3.10.txt b/packages/google-maps-areainsights/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-maps-areainsights/testing/constraints-3.10.txt +++ b/packages/google-maps-areainsights/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-maps-areainsights/testing/constraints-3.13.txt b/packages/google-maps-areainsights/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-maps-areainsights/testing/constraints-3.13.txt +++ b/packages/google-maps-areainsights/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-maps-areainsights/testing/constraints-3.14.txt b/packages/google-maps-areainsights/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-maps-areainsights/testing/constraints-3.14.txt +++ b/packages/google-maps-areainsights/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery_v1/__init__.py b/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery_v1/__init__.py index 9318f00aee7e..07a9e17aefee 100644 --- a/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery_v1/__init__.py +++ b/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery_v1/__init__.py @@ -84,7 +84,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -113,9 +113,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-maps-fleetengine-delivery/setup.py b/packages/google-maps-fleetengine-delivery/setup.py index 8b10fafb1c3d..a7135a9da67a 100644 --- a/packages/google-maps-fleetengine-delivery/setup.py +++ b/packages/google-maps-fleetengine-delivery/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/maps/fleetengine_delivery/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,16 +44,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "google-geo-type >= 0.1.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "google-geo-type >= 0.3.12, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-maps-fleetengine-delivery" diff --git a/packages/google-maps-fleetengine-delivery/testing/constraints-3.10.txt b/packages/google-maps-fleetengine-delivery/testing/constraints-3.10.txt index ea5951376612..ee60d295a792 100644 --- a/packages/google-maps-fleetengine-delivery/testing/constraints-3.10.txt +++ b/packages/google-maps-fleetengine-delivery/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -google-geo-type==0.1.0 +proto-plus==1.26.1 +protobuf==6.33.5 +google-geo-type==0.3.12 diff --git a/packages/google-maps-fleetengine-delivery/testing/constraints-3.13.txt b/packages/google-maps-fleetengine-delivery/testing/constraints-3.13.txt index c6b6ca67e783..5c8b50a29836 100644 --- a/packages/google-maps-fleetengine-delivery/testing/constraints-3.13.txt +++ b/packages/google-maps-fleetengine-delivery/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-geo-type>=0 diff --git a/packages/google-maps-fleetengine-delivery/testing/constraints-3.14.txt b/packages/google-maps-fleetengine-delivery/testing/constraints-3.14.txt index c6b6ca67e783..5c8b50a29836 100644 --- a/packages/google-maps-fleetengine-delivery/testing/constraints-3.14.txt +++ b/packages/google-maps-fleetengine-delivery/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-geo-type>=0 diff --git a/packages/google-maps-fleetengine/google/maps/fleetengine_v1/__init__.py b/packages/google-maps-fleetengine/google/maps/fleetengine_v1/__init__.py index 0e88fc3d2140..7d78781219e4 100644 --- a/packages/google-maps-fleetengine/google/maps/fleetengine_v1/__init__.py +++ b/packages/google-maps-fleetengine/google/maps/fleetengine_v1/__init__.py @@ -109,7 +109,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -138,9 +138,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-maps-fleetengine/setup.py b/packages/google-maps-fleetengine/setup.py index a19334f38827..3a600cdfa4f8 100644 --- a/packages/google-maps-fleetengine/setup.py +++ b/packages/google-maps-fleetengine/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/maps/fleetengine/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "google-geo-type >= 0.1.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "google-geo-type >= 0.3.12, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-maps-fleetengine" diff --git a/packages/google-maps-fleetengine/testing/constraints-3.10.txt b/packages/google-maps-fleetengine/testing/constraints-3.10.txt index ea5951376612..ee60d295a792 100644 --- a/packages/google-maps-fleetengine/testing/constraints-3.10.txt +++ b/packages/google-maps-fleetengine/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -google-geo-type==0.1.0 +proto-plus==1.26.1 +protobuf==6.33.5 +google-geo-type==0.3.12 diff --git a/packages/google-maps-fleetengine/testing/constraints-3.13.txt b/packages/google-maps-fleetengine/testing/constraints-3.13.txt index c6b6ca67e783..5c8b50a29836 100644 --- a/packages/google-maps-fleetengine/testing/constraints-3.13.txt +++ b/packages/google-maps-fleetengine/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-geo-type>=0 diff --git a/packages/google-maps-fleetengine/testing/constraints-3.14.txt b/packages/google-maps-fleetengine/testing/constraints-3.14.txt index c6b6ca67e783..5c8b50a29836 100644 --- a/packages/google-maps-fleetengine/testing/constraints-3.14.txt +++ b/packages/google-maps-fleetengine/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-geo-type>=0 diff --git a/packages/google-maps-geocode/google/maps/geocode_v4/__init__.py b/packages/google-maps-geocode/google/maps/geocode_v4/__init__.py index 5ea4476eba29..4c5f8360118a 100644 --- a/packages/google-maps-geocode/google/maps/geocode_v4/__init__.py +++ b/packages/google-maps-geocode/google/maps/geocode_v4/__init__.py @@ -72,7 +72,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -101,9 +101,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-maps-geocode/setup.py b/packages/google-maps-geocode/setup.py index e6e2810f399d..c5f5a0e20cb0 100644 --- a/packages/google-maps-geocode/setup.py +++ b/packages/google-maps-geocode/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/maps/geocode/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "google-geo-type >= 0.1.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "google-geo-type >= 0.3.12, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-maps-geocode" diff --git a/packages/google-maps-geocode/testing/constraints-3.10.txt b/packages/google-maps-geocode/testing/constraints-3.10.txt index ea5951376612..ee60d295a792 100644 --- a/packages/google-maps-geocode/testing/constraints-3.10.txt +++ b/packages/google-maps-geocode/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -google-geo-type==0.1.0 +proto-plus==1.26.1 +protobuf==6.33.5 +google-geo-type==0.3.12 diff --git a/packages/google-maps-geocode/testing/constraints-3.13.txt b/packages/google-maps-geocode/testing/constraints-3.13.txt index c6b6ca67e783..5c8b50a29836 100644 --- a/packages/google-maps-geocode/testing/constraints-3.13.txt +++ b/packages/google-maps-geocode/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-geo-type>=0 diff --git a/packages/google-maps-geocode/testing/constraints-3.14.txt b/packages/google-maps-geocode/testing/constraints-3.14.txt index c6b6ca67e783..5c8b50a29836 100644 --- a/packages/google-maps-geocode/testing/constraints-3.14.txt +++ b/packages/google-maps-geocode/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-geo-type>=0 diff --git a/packages/google-maps-mapmanagement/google/maps/mapmanagement_v2beta/__init__.py b/packages/google-maps-mapmanagement/google/maps/mapmanagement_v2beta/__init__.py index 6f5b09169301..517fd5374323 100644 --- a/packages/google-maps-mapmanagement/google/maps/mapmanagement_v2beta/__init__.py +++ b/packages/google-maps-mapmanagement/google/maps/mapmanagement_v2beta/__init__.py @@ -76,7 +76,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -105,9 +105,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-maps-mapmanagement/setup.py b/packages/google-maps-mapmanagement/setup.py index 17039bfee030..001c091ff153 100644 --- a/packages/google-maps-mapmanagement/setup.py +++ b/packages/google-maps-mapmanagement/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/maps/mapmanagement/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-maps-mapmanagement" diff --git a/packages/google-maps-mapmanagement/testing/constraints-3.10.txt b/packages/google-maps-mapmanagement/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-maps-mapmanagement/testing/constraints-3.10.txt +++ b/packages/google-maps-mapmanagement/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-maps-mapmanagement/testing/constraints-3.13.txt b/packages/google-maps-mapmanagement/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-maps-mapmanagement/testing/constraints-3.13.txt +++ b/packages/google-maps-mapmanagement/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-maps-mapmanagement/testing/constraints-3.14.txt b/packages/google-maps-mapmanagement/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-maps-mapmanagement/testing/constraints-3.14.txt +++ b/packages/google-maps-mapmanagement/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/__init__.py b/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/__init__.py index 4cb327465e1b..a3e24597be2b 100644 --- a/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/__init__.py +++ b/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/__init__.py @@ -65,7 +65,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -94,9 +94,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-maps-mapsplatformdatasets/setup.py b/packages/google-maps-mapsplatformdatasets/setup.py index 31f32789eaee..6acadb1485cd 100644 --- a/packages/google-maps-mapsplatformdatasets/setup.py +++ b/packages/google-maps-mapsplatformdatasets/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/maps/mapsplatformdatasets/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-maps-mapsplatformdatasets" diff --git a/packages/google-maps-mapsplatformdatasets/testing/constraints-3.10.txt b/packages/google-maps-mapsplatformdatasets/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-maps-mapsplatformdatasets/testing/constraints-3.10.txt +++ b/packages/google-maps-mapsplatformdatasets/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-maps-mapsplatformdatasets/testing/constraints-3.13.txt b/packages/google-maps-mapsplatformdatasets/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-maps-mapsplatformdatasets/testing/constraints-3.13.txt +++ b/packages/google-maps-mapsplatformdatasets/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-maps-mapsplatformdatasets/testing/constraints-3.14.txt b/packages/google-maps-mapsplatformdatasets/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-maps-mapsplatformdatasets/testing/constraints-3.14.txt +++ b/packages/google-maps-mapsplatformdatasets/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-maps-navconnect/google/maps/navconnect_v1/__init__.py b/packages/google-maps-navconnect/google/maps/navconnect_v1/__init__.py index ae649f3cb2bf..f3993622e2aa 100644 --- a/packages/google-maps-navconnect/google/maps/navconnect_v1/__init__.py +++ b/packages/google-maps-navconnect/google/maps/navconnect_v1/__init__.py @@ -63,7 +63,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -92,9 +92,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-maps-navconnect/setup.py b/packages/google-maps-navconnect/setup.py index c4634db58cad..b6f9e9bcc32b 100644 --- a/packages/google-maps-navconnect/setup.py +++ b/packages/google-maps-navconnect/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/maps/navconnect/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-maps-navconnect" diff --git a/packages/google-maps-navconnect/testing/constraints-3.10.txt b/packages/google-maps-navconnect/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-maps-navconnect/testing/constraints-3.10.txt +++ b/packages/google-maps-navconnect/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-maps-navconnect/testing/constraints-3.13.txt b/packages/google-maps-navconnect/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-maps-navconnect/testing/constraints-3.13.txt +++ b/packages/google-maps-navconnect/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-maps-navconnect/testing/constraints-3.14.txt b/packages/google-maps-navconnect/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-maps-navconnect/testing/constraints-3.14.txt +++ b/packages/google-maps-navconnect/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-maps-places/google/maps/places_v1/__init__.py b/packages/google-maps-places/google/maps/places_v1/__init__.py index 21cb42522c09..64b3b4ccdf62 100644 --- a/packages/google-maps-places/google/maps/places_v1/__init__.py +++ b/packages/google-maps-places/google/maps/places_v1/__init__.py @@ -86,7 +86,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -115,9 +115,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-maps-places/setup.py b/packages/google-maps-places/setup.py index a625b8be55dd..072ad51a8604 100644 --- a/packages/google-maps-places/setup.py +++ b/packages/google-maps-places/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/maps/places/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "google-geo-type >= 0.1.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "google-geo-type >= 0.3.12, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-maps-places" diff --git a/packages/google-maps-places/testing/constraints-3.10.txt b/packages/google-maps-places/testing/constraints-3.10.txt index ea5951376612..ee60d295a792 100644 --- a/packages/google-maps-places/testing/constraints-3.10.txt +++ b/packages/google-maps-places/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -google-geo-type==0.1.0 +proto-plus==1.26.1 +protobuf==6.33.5 +google-geo-type==0.3.12 diff --git a/packages/google-maps-places/testing/constraints-3.13.txt b/packages/google-maps-places/testing/constraints-3.13.txt index c6b6ca67e783..5c8b50a29836 100644 --- a/packages/google-maps-places/testing/constraints-3.13.txt +++ b/packages/google-maps-places/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-geo-type>=0 diff --git a/packages/google-maps-places/testing/constraints-3.14.txt b/packages/google-maps-places/testing/constraints-3.14.txt index c6b6ca67e783..5c8b50a29836 100644 --- a/packages/google-maps-places/testing/constraints-3.14.txt +++ b/packages/google-maps-places/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-geo-type>=0 diff --git a/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/__init__.py b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/__init__.py index 9ca378fec5d9..c626d4eb195e 100644 --- a/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/__init__.py +++ b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/__init__.py @@ -88,7 +88,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -117,9 +117,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-maps-routeoptimization/setup.py b/packages/google-maps-routeoptimization/setup.py index e8c88c8a570a..834a721a442d 100644 --- a/packages/google-maps-routeoptimization/setup.py +++ b/packages/google-maps-routeoptimization/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/maps/routeoptimization/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-maps-routeoptimization" diff --git a/packages/google-maps-routeoptimization/testing/constraints-3.10.txt b/packages/google-maps-routeoptimization/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-maps-routeoptimization/testing/constraints-3.10.txt +++ b/packages/google-maps-routeoptimization/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-maps-routeoptimization/testing/constraints-3.13.txt b/packages/google-maps-routeoptimization/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-maps-routeoptimization/testing/constraints-3.13.txt +++ b/packages/google-maps-routeoptimization/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-maps-routeoptimization/testing/constraints-3.14.txt b/packages/google-maps-routeoptimization/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-maps-routeoptimization/testing/constraints-3.14.txt +++ b/packages/google-maps-routeoptimization/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-maps-routing/google/maps/routing_v2/__init__.py b/packages/google-maps-routing/google/maps/routing_v2/__init__.py index af21c2e4599a..f6e540e3c3bf 100644 --- a/packages/google-maps-routing/google/maps/routing_v2/__init__.py +++ b/packages/google-maps-routing/google/maps/routing_v2/__init__.py @@ -90,7 +90,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -119,9 +119,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-maps-routing/setup.py b/packages/google-maps-routing/setup.py index 72db4db4484d..8cecb1bd365d 100644 --- a/packages/google-maps-routing/setup.py +++ b/packages/google-maps-routing/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/maps/routing/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,16 +42,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", - "google-geo-type >= 0.1.0, <1.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", + "google-geo-type >= 0.3.12, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-maps-routing" diff --git a/packages/google-maps-routing/testing/constraints-3.10.txt b/packages/google-maps-routing/testing/constraints-3.10.txt index ea5951376612..ee60d295a792 100644 --- a/packages/google-maps-routing/testing/constraints-3.10.txt +++ b/packages/google-maps-routing/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 -google-geo-type==0.1.0 +proto-plus==1.26.1 +protobuf==6.33.5 +google-geo-type==0.3.12 diff --git a/packages/google-maps-routing/testing/constraints-3.13.txt b/packages/google-maps-routing/testing/constraints-3.13.txt index c6b6ca67e783..5c8b50a29836 100644 --- a/packages/google-maps-routing/testing/constraints-3.13.txt +++ b/packages/google-maps-routing/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-geo-type>=0 diff --git a/packages/google-maps-routing/testing/constraints-3.14.txt b/packages/google-maps-routing/testing/constraints-3.14.txt index c6b6ca67e783..5c8b50a29836 100644 --- a/packages/google-maps-routing/testing/constraints-3.14.txt +++ b/packages/google-maps-routing/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-geo-type>=0 diff --git a/packages/google-maps-solar/google/maps/solar_v1/__init__.py b/packages/google-maps-solar/google/maps/solar_v1/__init__.py index 56b2e45ca05f..cde0a0d4519c 100644 --- a/packages/google-maps-solar/google/maps/solar_v1/__init__.py +++ b/packages/google-maps-solar/google/maps/solar_v1/__init__.py @@ -74,7 +74,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -103,9 +103,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-maps-solar/setup.py b/packages/google-maps-solar/setup.py index f435db555b02..e5cfaaa5fe98 100644 --- a/packages/google-maps-solar/setup.py +++ b/packages/google-maps-solar/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/maps/solar/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-maps-solar" diff --git a/packages/google-maps-solar/testing/constraints-3.10.txt b/packages/google-maps-solar/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-maps-solar/testing/constraints-3.10.txt +++ b/packages/google-maps-solar/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-maps-solar/testing/constraints-3.13.txt b/packages/google-maps-solar/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-maps-solar/testing/constraints-3.13.txt +++ b/packages/google-maps-solar/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-maps-solar/testing/constraints-3.14.txt b/packages/google-maps-solar/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-maps-solar/testing/constraints-3.14.txt +++ b/packages/google-maps-solar/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-shopping-css/google/shopping/css_v1/__init__.py b/packages/google-shopping-css/google/shopping/css_v1/__init__.py index bc342edcdfb3..172094bc5973 100644 --- a/packages/google-shopping-css/google/shopping/css_v1/__init__.py +++ b/packages/google-shopping-css/google/shopping/css_v1/__init__.py @@ -107,7 +107,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -136,9 +136,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-shopping-css/setup.py b/packages/google-shopping-css/setup.py index 42a8a1c8dea4..36d97fc87922 100644 --- a/packages/google-shopping-css/setup.py +++ b/packages/google-shopping-css/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/shopping/css/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", "google-shopping-type >= 1.0.0, <2.0.0", ] extras = {} diff --git a/packages/google-shopping-css/testing/constraints-3.10.txt b/packages/google-shopping-css/testing/constraints-3.10.txt index b408428a99a2..250670a79385 100644 --- a/packages/google-shopping-css/testing/constraints-3.10.txt +++ b/packages/google-shopping-css/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 google-shopping-type==1.0.0 diff --git a/packages/google-shopping-css/testing/constraints-3.13.txt b/packages/google-shopping-css/testing/constraints-3.13.txt index d17e4ad50309..72a0563100f5 100644 --- a/packages/google-shopping-css/testing/constraints-3.13.txt +++ b/packages/google-shopping-css/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-shopping-type>=1 diff --git a/packages/google-shopping-css/testing/constraints-3.14.txt b/packages/google-shopping-css/testing/constraints-3.14.txt index d17e4ad50309..72a0563100f5 100644 --- a/packages/google-shopping-css/testing/constraints-3.14.txt +++ b/packages/google-shopping-css/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-shopping-type>=1 diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1/__init__.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1/__init__.py index c7feb410a5db..9a88e23c0974 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1/__init__.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1/__init__.py @@ -325,7 +325,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -354,9 +354,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/__init__.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/__init__.py index 0fcb5989577c..ffbeb99b523f 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/__init__.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/__init__.py @@ -289,7 +289,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -318,9 +318,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-shopping-merchant-accounts/setup.py b/packages/google-shopping-merchant-accounts/setup.py index 3f5197604129..82427c44f8e5 100644 --- a/packages/google-shopping-merchant-accounts/setup.py +++ b/packages/google-shopping-merchant-accounts/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/shopping/merchant_accounts/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", "google-shopping-type >= 1.0.0, <2.0.0", ] extras = {} diff --git a/packages/google-shopping-merchant-accounts/testing/constraints-3.10.txt b/packages/google-shopping-merchant-accounts/testing/constraints-3.10.txt index b408428a99a2..250670a79385 100644 --- a/packages/google-shopping-merchant-accounts/testing/constraints-3.10.txt +++ b/packages/google-shopping-merchant-accounts/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 google-shopping-type==1.0.0 diff --git a/packages/google-shopping-merchant-accounts/testing/constraints-3.13.txt b/packages/google-shopping-merchant-accounts/testing/constraints-3.13.txt index d17e4ad50309..72a0563100f5 100644 --- a/packages/google-shopping-merchant-accounts/testing/constraints-3.13.txt +++ b/packages/google-shopping-merchant-accounts/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-shopping-type>=1 diff --git a/packages/google-shopping-merchant-accounts/testing/constraints-3.14.txt b/packages/google-shopping-merchant-accounts/testing/constraints-3.14.txt index d17e4ad50309..72a0563100f5 100644 --- a/packages/google-shopping-merchant-accounts/testing/constraints-3.14.txt +++ b/packages/google-shopping-merchant-accounts/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-shopping-type>=1 diff --git a/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1/__init__.py b/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1/__init__.py index 962b1086f963..16954200b036 100644 --- a/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1/__init__.py +++ b/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1/__init__.py @@ -66,7 +66,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -95,9 +95,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/__init__.py b/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/__init__.py index 85edf806e2fb..86471764ff6a 100644 --- a/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/__init__.py +++ b/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/__init__.py @@ -66,7 +66,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -95,9 +95,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-shopping-merchant-conversions/setup.py b/packages/google-shopping-merchant-conversions/setup.py index b9738abb789e..17cb6dce825a 100644 --- a/packages/google-shopping-merchant-conversions/setup.py +++ b/packages/google-shopping-merchant-conversions/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/shopping/merchant_conversions/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-shopping-merchant-conversions" diff --git a/packages/google-shopping-merchant-conversions/testing/constraints-3.10.txt b/packages/google-shopping-merchant-conversions/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-shopping-merchant-conversions/testing/constraints-3.10.txt +++ b/packages/google-shopping-merchant-conversions/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-shopping-merchant-conversions/testing/constraints-3.13.txt b/packages/google-shopping-merchant-conversions/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-shopping-merchant-conversions/testing/constraints-3.13.txt +++ b/packages/google-shopping-merchant-conversions/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-shopping-merchant-conversions/testing/constraints-3.14.txt b/packages/google-shopping-merchant-conversions/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-shopping-merchant-conversions/testing/constraints-3.14.txt +++ b/packages/google-shopping-merchant-conversions/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1/__init__.py b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1/__init__.py index 3c92be291518..5b6466d6e240 100644 --- a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1/__init__.py +++ b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1/__init__.py @@ -79,7 +79,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -108,9 +108,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/__init__.py b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/__init__.py index 0869dbcde175..ffaef646d739 100644 --- a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/__init__.py +++ b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/__init__.py @@ -79,7 +79,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -108,9 +108,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-shopping-merchant-datasources/setup.py b/packages/google-shopping-merchant-datasources/setup.py index 326a0b6fe7f3..25bac4046235 100644 --- a/packages/google-shopping-merchant-datasources/setup.py +++ b/packages/google-shopping-merchant-datasources/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/shopping/merchant_datasources/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", "google-shopping-type >= 1.0.0, <2.0.0", ] extras = {} diff --git a/packages/google-shopping-merchant-datasources/testing/constraints-3.10.txt b/packages/google-shopping-merchant-datasources/testing/constraints-3.10.txt index b408428a99a2..250670a79385 100644 --- a/packages/google-shopping-merchant-datasources/testing/constraints-3.10.txt +++ b/packages/google-shopping-merchant-datasources/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 google-shopping-type==1.0.0 diff --git a/packages/google-shopping-merchant-datasources/testing/constraints-3.13.txt b/packages/google-shopping-merchant-datasources/testing/constraints-3.13.txt index d17e4ad50309..72a0563100f5 100644 --- a/packages/google-shopping-merchant-datasources/testing/constraints-3.13.txt +++ b/packages/google-shopping-merchant-datasources/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-shopping-type>=1 diff --git a/packages/google-shopping-merchant-datasources/testing/constraints-3.14.txt b/packages/google-shopping-merchant-datasources/testing/constraints-3.14.txt index d17e4ad50309..72a0563100f5 100644 --- a/packages/google-shopping-merchant-datasources/testing/constraints-3.14.txt +++ b/packages/google-shopping-merchant-datasources/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-shopping-type>=1 diff --git a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1/__init__.py b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1/__init__.py index 195445ad187f..5bb720f1f344 100644 --- a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1/__init__.py +++ b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1/__init__.py @@ -76,7 +76,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -105,9 +105,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/__init__.py b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/__init__.py index 43a87ad51963..ccecae9f0d54 100644 --- a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/__init__.py +++ b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/__init__.py @@ -71,7 +71,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -100,9 +100,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-shopping-merchant-inventories/setup.py b/packages/google-shopping-merchant-inventories/setup.py index 275ba33e8c0c..b84ec4335dfe 100644 --- a/packages/google-shopping-merchant-inventories/setup.py +++ b/packages/google-shopping-merchant-inventories/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/shopping/merchant_inventories/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", "google-shopping-type >= 1.0.0, <2.0.0", ] extras = {} diff --git a/packages/google-shopping-merchant-inventories/testing/constraints-3.10.txt b/packages/google-shopping-merchant-inventories/testing/constraints-3.10.txt index b408428a99a2..250670a79385 100644 --- a/packages/google-shopping-merchant-inventories/testing/constraints-3.10.txt +++ b/packages/google-shopping-merchant-inventories/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 google-shopping-type==1.0.0 diff --git a/packages/google-shopping-merchant-inventories/testing/constraints-3.13.txt b/packages/google-shopping-merchant-inventories/testing/constraints-3.13.txt index d17e4ad50309..72a0563100f5 100644 --- a/packages/google-shopping-merchant-inventories/testing/constraints-3.13.txt +++ b/packages/google-shopping-merchant-inventories/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-shopping-type>=1 diff --git a/packages/google-shopping-merchant-inventories/testing/constraints-3.14.txt b/packages/google-shopping-merchant-inventories/testing/constraints-3.14.txt index d17e4ad50309..72a0563100f5 100644 --- a/packages/google-shopping-merchant-inventories/testing/constraints-3.14.txt +++ b/packages/google-shopping-merchant-inventories/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-shopping-type>=1 diff --git a/packages/google-shopping-merchant-issueresolution/google/shopping/merchant_issueresolution_v1/__init__.py b/packages/google-shopping-merchant-issueresolution/google/shopping/merchant_issueresolution_v1/__init__.py index 3727846e1bea..38921d274e71 100644 --- a/packages/google-shopping-merchant-issueresolution/google/shopping/merchant_issueresolution_v1/__init__.py +++ b/packages/google-shopping-merchant-issueresolution/google/shopping/merchant_issueresolution_v1/__init__.py @@ -88,7 +88,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -117,9 +117,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-shopping-merchant-issueresolution/google/shopping/merchant_issueresolution_v1beta/__init__.py b/packages/google-shopping-merchant-issueresolution/google/shopping/merchant_issueresolution_v1beta/__init__.py index e92747550669..92862bf2f966 100644 --- a/packages/google-shopping-merchant-issueresolution/google/shopping/merchant_issueresolution_v1beta/__init__.py +++ b/packages/google-shopping-merchant-issueresolution/google/shopping/merchant_issueresolution_v1beta/__init__.py @@ -92,7 +92,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -121,9 +121,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-shopping-merchant-issueresolution/setup.py b/packages/google-shopping-merchant-issueresolution/setup.py index ab2d9ffc5a01..1e6c065eedfb 100644 --- a/packages/google-shopping-merchant-issueresolution/setup.py +++ b/packages/google-shopping-merchant-issueresolution/setup.py @@ -33,7 +33,10 @@ package_root, "google/shopping/merchant_issueresolution/gapic_version.py" ) ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -43,15 +46,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", "google-shopping-type >= 1.0.0, <2.0.0", ] extras = {} diff --git a/packages/google-shopping-merchant-issueresolution/testing/constraints-3.10.txt b/packages/google-shopping-merchant-issueresolution/testing/constraints-3.10.txt index b408428a99a2..250670a79385 100644 --- a/packages/google-shopping-merchant-issueresolution/testing/constraints-3.10.txt +++ b/packages/google-shopping-merchant-issueresolution/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 google-shopping-type==1.0.0 diff --git a/packages/google-shopping-merchant-issueresolution/testing/constraints-3.13.txt b/packages/google-shopping-merchant-issueresolution/testing/constraints-3.13.txt index d17e4ad50309..72a0563100f5 100644 --- a/packages/google-shopping-merchant-issueresolution/testing/constraints-3.13.txt +++ b/packages/google-shopping-merchant-issueresolution/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-shopping-type>=1 diff --git a/packages/google-shopping-merchant-issueresolution/testing/constraints-3.14.txt b/packages/google-shopping-merchant-issueresolution/testing/constraints-3.14.txt index d17e4ad50309..72a0563100f5 100644 --- a/packages/google-shopping-merchant-issueresolution/testing/constraints-3.14.txt +++ b/packages/google-shopping-merchant-issueresolution/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-shopping-type>=1 diff --git a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1/__init__.py b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1/__init__.py index 5d4b6f8c7aec..62b4a3d38f51 100644 --- a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1/__init__.py +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1/__init__.py @@ -73,7 +73,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -102,9 +102,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/__init__.py b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/__init__.py index da94e4483bb0..b502a464f20f 100644 --- a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/__init__.py +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/__init__.py @@ -73,7 +73,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -102,9 +102,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-shopping-merchant-lfp/setup.py b/packages/google-shopping-merchant-lfp/setup.py index e8228bbd3130..3de53ddb5a6f 100644 --- a/packages/google-shopping-merchant-lfp/setup.py +++ b/packages/google-shopping-merchant-lfp/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/shopping/merchant_lfp/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", "google-shopping-type >= 1.0.0, <2.0.0", ] extras = {} diff --git a/packages/google-shopping-merchant-lfp/testing/constraints-3.10.txt b/packages/google-shopping-merchant-lfp/testing/constraints-3.10.txt index b408428a99a2..250670a79385 100644 --- a/packages/google-shopping-merchant-lfp/testing/constraints-3.10.txt +++ b/packages/google-shopping-merchant-lfp/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 google-shopping-type==1.0.0 diff --git a/packages/google-shopping-merchant-lfp/testing/constraints-3.13.txt b/packages/google-shopping-merchant-lfp/testing/constraints-3.13.txt index d17e4ad50309..72a0563100f5 100644 --- a/packages/google-shopping-merchant-lfp/testing/constraints-3.13.txt +++ b/packages/google-shopping-merchant-lfp/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-shopping-type>=1 diff --git a/packages/google-shopping-merchant-lfp/testing/constraints-3.14.txt b/packages/google-shopping-merchant-lfp/testing/constraints-3.14.txt index d17e4ad50309..72a0563100f5 100644 --- a/packages/google-shopping-merchant-lfp/testing/constraints-3.14.txt +++ b/packages/google-shopping-merchant-lfp/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-shopping-type>=1 diff --git a/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1/__init__.py b/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1/__init__.py index 9075296a39c7..663d47edf843 100644 --- a/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1/__init__.py +++ b/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1/__init__.py @@ -64,7 +64,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -93,9 +93,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/__init__.py b/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/__init__.py index 6d9228e02862..91596a101bb6 100644 --- a/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/__init__.py +++ b/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/__init__.py @@ -68,7 +68,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -97,9 +97,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-shopping-merchant-notifications/setup.py b/packages/google-shopping-merchant-notifications/setup.py index 77399923b484..f94604f15d22 100644 --- a/packages/google-shopping-merchant-notifications/setup.py +++ b/packages/google-shopping-merchant-notifications/setup.py @@ -33,7 +33,10 @@ package_root, "google/shopping/merchant_notifications/gapic_version.py" ) ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -43,16 +46,15 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "google-shopping-type >= 1.0.0, <2.0.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-shopping-merchant-notifications" diff --git a/packages/google-shopping-merchant-notifications/testing/constraints-3.10.txt b/packages/google-shopping-merchant-notifications/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-shopping-merchant-notifications/testing/constraints-3.10.txt +++ b/packages/google-shopping-merchant-notifications/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-shopping-merchant-notifications/testing/constraints-3.13.txt b/packages/google-shopping-merchant-notifications/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-shopping-merchant-notifications/testing/constraints-3.13.txt +++ b/packages/google-shopping-merchant-notifications/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-shopping-merchant-notifications/testing/constraints-3.14.txt b/packages/google-shopping-merchant-notifications/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-shopping-merchant-notifications/testing/constraints-3.14.txt +++ b/packages/google-shopping-merchant-notifications/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-shopping-merchant-ordertracking/google/shopping/merchant_ordertracking_v1/__init__.py b/packages/google-shopping-merchant-ordertracking/google/shopping/merchant_ordertracking_v1/__init__.py index 22c2b5383959..374230334be2 100644 --- a/packages/google-shopping-merchant-ordertracking/google/shopping/merchant_ordertracking_v1/__init__.py +++ b/packages/google-shopping-merchant-ordertracking/google/shopping/merchant_ordertracking_v1/__init__.py @@ -57,7 +57,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -86,9 +86,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-shopping-merchant-ordertracking/google/shopping/merchant_ordertracking_v1beta/__init__.py b/packages/google-shopping-merchant-ordertracking/google/shopping/merchant_ordertracking_v1beta/__init__.py index 089330b7af8c..c77d1dc6d2f3 100644 --- a/packages/google-shopping-merchant-ordertracking/google/shopping/merchant_ordertracking_v1beta/__init__.py +++ b/packages/google-shopping-merchant-ordertracking/google/shopping/merchant_ordertracking_v1beta/__init__.py @@ -59,7 +59,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -88,9 +88,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-shopping-merchant-ordertracking/setup.py b/packages/google-shopping-merchant-ordertracking/setup.py index 2ea862f833bf..e70f7a811aa7 100644 --- a/packages/google-shopping-merchant-ordertracking/setup.py +++ b/packages/google-shopping-merchant-ordertracking/setup.py @@ -33,7 +33,10 @@ package_root, "google/shopping/merchant_ordertracking/gapic_version.py" ) ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -43,15 +46,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", "google-shopping-type >= 1.0.0, <2.0.0", ] extras = {} diff --git a/packages/google-shopping-merchant-ordertracking/testing/constraints-3.10.txt b/packages/google-shopping-merchant-ordertracking/testing/constraints-3.10.txt index b408428a99a2..250670a79385 100644 --- a/packages/google-shopping-merchant-ordertracking/testing/constraints-3.10.txt +++ b/packages/google-shopping-merchant-ordertracking/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 google-shopping-type==1.0.0 diff --git a/packages/google-shopping-merchant-ordertracking/testing/constraints-3.13.txt b/packages/google-shopping-merchant-ordertracking/testing/constraints-3.13.txt index d17e4ad50309..72a0563100f5 100644 --- a/packages/google-shopping-merchant-ordertracking/testing/constraints-3.13.txt +++ b/packages/google-shopping-merchant-ordertracking/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-shopping-type>=1 diff --git a/packages/google-shopping-merchant-ordertracking/testing/constraints-3.14.txt b/packages/google-shopping-merchant-ordertracking/testing/constraints-3.14.txt index d17e4ad50309..72a0563100f5 100644 --- a/packages/google-shopping-merchant-ordertracking/testing/constraints-3.14.txt +++ b/packages/google-shopping-merchant-ordertracking/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-shopping-type>=1 diff --git a/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1/__init__.py b/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1/__init__.py index a37adcba5d38..f853e9116a2d 100644 --- a/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1/__init__.py +++ b/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1/__init__.py @@ -106,7 +106,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -135,9 +135,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/__init__.py b/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/__init__.py index 82686a6930f2..50cbfd949ef1 100644 --- a/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/__init__.py +++ b/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/__init__.py @@ -91,7 +91,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -120,9 +120,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-shopping-merchant-products/setup.py b/packages/google-shopping-merchant-products/setup.py index 03638308dec1..bb370a8911ce 100644 --- a/packages/google-shopping-merchant-products/setup.py +++ b/packages/google-shopping-merchant-products/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/shopping/merchant_products/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", "google-shopping-type >= 1.0.0, <2.0.0", ] extras = {} diff --git a/packages/google-shopping-merchant-products/testing/constraints-3.10.txt b/packages/google-shopping-merchant-products/testing/constraints-3.10.txt index b408428a99a2..250670a79385 100644 --- a/packages/google-shopping-merchant-products/testing/constraints-3.10.txt +++ b/packages/google-shopping-merchant-products/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 google-shopping-type==1.0.0 diff --git a/packages/google-shopping-merchant-products/testing/constraints-3.13.txt b/packages/google-shopping-merchant-products/testing/constraints-3.13.txt index d17e4ad50309..72a0563100f5 100644 --- a/packages/google-shopping-merchant-products/testing/constraints-3.13.txt +++ b/packages/google-shopping-merchant-products/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-shopping-type>=1 diff --git a/packages/google-shopping-merchant-products/testing/constraints-3.14.txt b/packages/google-shopping-merchant-products/testing/constraints-3.14.txt index d17e4ad50309..72a0563100f5 100644 --- a/packages/google-shopping-merchant-products/testing/constraints-3.14.txt +++ b/packages/google-shopping-merchant-products/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-shopping-type>=1 diff --git a/packages/google-shopping-merchant-productstudio/google/shopping/merchant_productstudio_v1alpha/__init__.py b/packages/google-shopping-merchant-productstudio/google/shopping/merchant_productstudio_v1alpha/__init__.py index f40f3fbf5062..a22b918fc048 100644 --- a/packages/google-shopping-merchant-productstudio/google/shopping/merchant_productstudio_v1alpha/__init__.py +++ b/packages/google-shopping-merchant-productstudio/google/shopping/merchant_productstudio_v1alpha/__init__.py @@ -80,7 +80,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -109,9 +109,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-shopping-merchant-productstudio/setup.py b/packages/google-shopping-merchant-productstudio/setup.py index 20e11ca62385..e38d58e0eea9 100644 --- a/packages/google-shopping-merchant-productstudio/setup.py +++ b/packages/google-shopping-merchant-productstudio/setup.py @@ -33,7 +33,10 @@ package_root, "google/shopping/merchant_productstudio/gapic_version.py" ) ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -43,15 +46,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-shopping-merchant-productstudio" diff --git a/packages/google-shopping-merchant-productstudio/testing/constraints-3.10.txt b/packages/google-shopping-merchant-productstudio/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-shopping-merchant-productstudio/testing/constraints-3.10.txt +++ b/packages/google-shopping-merchant-productstudio/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-shopping-merchant-productstudio/testing/constraints-3.13.txt b/packages/google-shopping-merchant-productstudio/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-shopping-merchant-productstudio/testing/constraints-3.13.txt +++ b/packages/google-shopping-merchant-productstudio/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-shopping-merchant-productstudio/testing/constraints-3.14.txt b/packages/google-shopping-merchant-productstudio/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-shopping-merchant-productstudio/testing/constraints-3.14.txt +++ b/packages/google-shopping-merchant-productstudio/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1/__init__.py b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1/__init__.py index 85ef7209ede0..5bc481062af2 100644 --- a/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1/__init__.py +++ b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1/__init__.py @@ -69,7 +69,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -98,9 +98,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/__init__.py b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/__init__.py index a7322b6f3381..43a34ec35edb 100644 --- a/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/__init__.py +++ b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/__init__.py @@ -69,7 +69,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -98,9 +98,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-shopping-merchant-promotions/setup.py b/packages/google-shopping-merchant-promotions/setup.py index 69f37d950a6e..5bc3db2108ae 100644 --- a/packages/google-shopping-merchant-promotions/setup.py +++ b/packages/google-shopping-merchant-promotions/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/shopping/merchant_promotions/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", "google-shopping-type >= 1.0.0, <2.0.0", ] extras = {} diff --git a/packages/google-shopping-merchant-promotions/testing/constraints-3.10.txt b/packages/google-shopping-merchant-promotions/testing/constraints-3.10.txt index b408428a99a2..250670a79385 100644 --- a/packages/google-shopping-merchant-promotions/testing/constraints-3.10.txt +++ b/packages/google-shopping-merchant-promotions/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 google-shopping-type==1.0.0 diff --git a/packages/google-shopping-merchant-promotions/testing/constraints-3.13.txt b/packages/google-shopping-merchant-promotions/testing/constraints-3.13.txt index d17e4ad50309..72a0563100f5 100644 --- a/packages/google-shopping-merchant-promotions/testing/constraints-3.13.txt +++ b/packages/google-shopping-merchant-promotions/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-shopping-type>=1 diff --git a/packages/google-shopping-merchant-promotions/testing/constraints-3.14.txt b/packages/google-shopping-merchant-promotions/testing/constraints-3.14.txt index d17e4ad50309..72a0563100f5 100644 --- a/packages/google-shopping-merchant-promotions/testing/constraints-3.14.txt +++ b/packages/google-shopping-merchant-promotions/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-shopping-type>=1 diff --git a/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1/__init__.py b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1/__init__.py index 27eaa7673d11..1f71f5b3dbab 100644 --- a/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1/__init__.py +++ b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1/__init__.py @@ -67,7 +67,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -96,9 +96,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/__init__.py b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/__init__.py index 9c67d36d6091..445ccce5d33a 100644 --- a/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/__init__.py +++ b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/__init__.py @@ -56,7 +56,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -85,9 +85,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-shopping-merchant-quota/setup.py b/packages/google-shopping-merchant-quota/setup.py index 382890aaea9e..ce7f014db2b2 100644 --- a/packages/google-shopping-merchant-quota/setup.py +++ b/packages/google-shopping-merchant-quota/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/shopping/merchant_quota/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-shopping-merchant-quota" diff --git a/packages/google-shopping-merchant-quota/testing/constraints-3.10.txt b/packages/google-shopping-merchant-quota/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-shopping-merchant-quota/testing/constraints-3.10.txt +++ b/packages/google-shopping-merchant-quota/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-shopping-merchant-quota/testing/constraints-3.13.txt b/packages/google-shopping-merchant-quota/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-shopping-merchant-quota/testing/constraints-3.13.txt +++ b/packages/google-shopping-merchant-quota/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-shopping-merchant-quota/testing/constraints-3.14.txt b/packages/google-shopping-merchant-quota/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-shopping-merchant-quota/testing/constraints-3.14.txt +++ b/packages/google-shopping-merchant-quota/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1/__init__.py b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1/__init__.py index 4d5677c5ce78..4a1f4a2dcc91 100644 --- a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1/__init__.py +++ b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1/__init__.py @@ -71,7 +71,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -100,9 +100,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1alpha/__init__.py b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1alpha/__init__.py index d6e7cb1cc7c8..f73a3fc23c8a 100644 --- a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1alpha/__init__.py +++ b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1alpha/__init__.py @@ -73,7 +73,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -102,9 +102,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/__init__.py b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/__init__.py index 543e0f0a68e2..286c425e7b12 100644 --- a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/__init__.py +++ b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/__init__.py @@ -70,7 +70,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -99,9 +99,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-shopping-merchant-reports/setup.py b/packages/google-shopping-merchant-reports/setup.py index 52bc61fba399..0b271803015a 100644 --- a/packages/google-shopping-merchant-reports/setup.py +++ b/packages/google-shopping-merchant-reports/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/shopping/merchant_reports/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", "google-shopping-type >= 1.0.0, <2.0.0", ] extras = {} diff --git a/packages/google-shopping-merchant-reports/testing/constraints-3.10.txt b/packages/google-shopping-merchant-reports/testing/constraints-3.10.txt index b408428a99a2..250670a79385 100644 --- a/packages/google-shopping-merchant-reports/testing/constraints-3.10.txt +++ b/packages/google-shopping-merchant-reports/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 google-shopping-type==1.0.0 diff --git a/packages/google-shopping-merchant-reports/testing/constraints-3.13.txt b/packages/google-shopping-merchant-reports/testing/constraints-3.13.txt index d17e4ad50309..72a0563100f5 100644 --- a/packages/google-shopping-merchant-reports/testing/constraints-3.13.txt +++ b/packages/google-shopping-merchant-reports/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-shopping-type>=1 diff --git a/packages/google-shopping-merchant-reports/testing/constraints-3.14.txt b/packages/google-shopping-merchant-reports/testing/constraints-3.14.txt index d17e4ad50309..72a0563100f5 100644 --- a/packages/google-shopping-merchant-reports/testing/constraints-3.14.txt +++ b/packages/google-shopping-merchant-reports/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-shopping-type>=1 diff --git a/packages/google-shopping-merchant-reviews/google/shopping/merchant_reviews_v1beta/__init__.py b/packages/google-shopping-merchant-reviews/google/shopping/merchant_reviews_v1beta/__init__.py index ed24b9773df9..9799b4b88335 100644 --- a/packages/google-shopping-merchant-reviews/google/shopping/merchant_reviews_v1beta/__init__.py +++ b/packages/google-shopping-merchant-reviews/google/shopping/merchant_reviews_v1beta/__init__.py @@ -75,7 +75,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -104,9 +104,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-shopping-merchant-reviews/setup.py b/packages/google-shopping-merchant-reviews/setup.py index e93978164816..17a6a4f6a260 100644 --- a/packages/google-shopping-merchant-reviews/setup.py +++ b/packages/google-shopping-merchant-reviews/setup.py @@ -31,7 +31,10 @@ with open( os.path.join(package_root, "google/shopping/merchant_reviews/gapic_version.py") ) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -41,15 +44,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", "google-shopping-type >= 1.0.0, <2.0.0", ] extras = {} diff --git a/packages/google-shopping-merchant-reviews/testing/constraints-3.10.txt b/packages/google-shopping-merchant-reviews/testing/constraints-3.10.txt index b408428a99a2..250670a79385 100644 --- a/packages/google-shopping-merchant-reviews/testing/constraints-3.10.txt +++ b/packages/google-shopping-merchant-reviews/testing/constraints-3.10.txt @@ -4,9 +4,9 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 google-shopping-type==1.0.0 diff --git a/packages/google-shopping-merchant-reviews/testing/constraints-3.13.txt b/packages/google-shopping-merchant-reviews/testing/constraints-3.13.txt index d17e4ad50309..72a0563100f5 100644 --- a/packages/google-shopping-merchant-reviews/testing/constraints-3.13.txt +++ b/packages/google-shopping-merchant-reviews/testing/constraints-3.13.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-shopping-type>=1 diff --git a/packages/google-shopping-merchant-reviews/testing/constraints-3.14.txt b/packages/google-shopping-merchant-reviews/testing/constraints-3.14.txt index d17e4ad50309..72a0563100f5 100644 --- a/packages/google-shopping-merchant-reviews/testing/constraints-3.14.txt +++ b/packages/google-shopping-merchant-reviews/testing/constraints-3.14.txt @@ -9,5 +9,5 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 google-shopping-type>=1 diff --git a/packages/google-shopping-type/google/shopping/type/__init__.py b/packages/google-shopping-type/google/shopping/type/__init__.py index 71dfc5ab3857..c71475aec70a 100644 --- a/packages/google-shopping-type/google/shopping/type/__init__.py +++ b/packages/google-shopping-type/google/shopping/type/__init__.py @@ -57,7 +57,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -86,9 +86,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/google-shopping-type/setup.py b/packages/google-shopping-type/setup.py index fdd70a0e1433..f22eed3eb758 100644 --- a/packages/google-shopping-type/setup.py +++ b/packages/google-shopping-type/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "google/shopping/type/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-shopping-type" diff --git a/packages/google-shopping-type/testing/constraints-3.10.txt b/packages/google-shopping-type/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/google-shopping-type/testing/constraints-3.10.txt +++ b/packages/google-shopping-type/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-shopping-type/testing/constraints-3.13.txt b/packages/google-shopping-type/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-shopping-type/testing/constraints-3.13.txt +++ b/packages/google-shopping-type/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/google-shopping-type/testing/constraints-3.14.txt b/packages/google-shopping-type/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/google-shopping-type/testing/constraints-3.14.txt +++ b/packages/google-shopping-type/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/grafeas/grafeas/grafeas_v1/__init__.py b/packages/grafeas/grafeas/grafeas_v1/__init__.py index 76db9067f15e..4277fcf561bb 100644 --- a/packages/grafeas/grafeas/grafeas_v1/__init__.py +++ b/packages/grafeas/grafeas/grafeas_v1/__init__.py @@ -158,7 +158,7 @@ def parse_version_to_tuple(version_string: str): """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) + Example: "6.33.5" -> (6, 33, 5) Ignores non-numeric parts and handles common version formats. Args: version_string: Version string in the format "x.y.z" or "x.y.z" @@ -187,9 +187,9 @@ def _get_version(dependency_name): return (None, "--") _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" + _next_supported_version = "6.33.5" + _next_supported_version_tuple = (6, 33, 5) + _recommendation = " (we recommend 7.x)" (_version_used, _version_used_string) = _get_version(_dependency_package) if _version_used and _version_used < _next_supported_version_tuple: warnings.warn( diff --git a/packages/grafeas/setup.py b/packages/grafeas/setup.py index 42618c18ebff..5a2fa1fb7d4b 100644 --- a/packages/grafeas/setup.py +++ b/packages/grafeas/setup.py @@ -29,7 +29,10 @@ version = None with open(os.path.join(package_root, "grafeas/grafeas/gapic_version.py")) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + version_candidates = re.findall( + r"(?<=\")\d+\.\d+\.\d+[^\"\s]*(?=\")", + fp.read(), + ) assert len(version_candidates) == 1 version = version_candidates[0] @@ -39,15 +42,14 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.17.1, <3.0.0", + "google-api-core[grpc] >= 2.24.2, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.59.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.3, <2.0.0", - "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", - "protobuf >= 4.25.8, < 8.0.0", + "proto-plus >= 1.26.1, <2.0.0", + "protobuf >= 6.33.5, < 8.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/grafeas" diff --git a/packages/grafeas/testing/constraints-3.10.txt b/packages/grafeas/testing/constraints-3.10.txt index 7be9c36933fc..81605a716d32 100644 --- a/packages/grafeas/testing/constraints-3.10.txt +++ b/packages/grafeas/testing/constraints-3.10.txt @@ -4,8 +4,8 @@ # pinning their versions to their lower bounds. # For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", # then this file should have google-cloud-foo==1.14.0 -google-api-core==2.17.1 +google-api-core==2.24.2 google-auth==2.14.1 grpcio==1.59.0 -proto-plus==1.22.3 -protobuf==4.25.8 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/grafeas/testing/constraints-3.13.txt b/packages/grafeas/testing/constraints-3.13.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/grafeas/testing/constraints-3.13.txt +++ b/packages/grafeas/testing/constraints-3.13.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/packages/grafeas/testing/constraints-3.14.txt b/packages/grafeas/testing/constraints-3.14.txt index 1e93c60e50aa..6bd7e1f5b03d 100644 --- a/packages/grafeas/testing/constraints-3.14.txt +++ b/packages/grafeas/testing/constraints-3.14.txt @@ -9,4 +9,4 @@ google-api-core>=2 google-auth>=2 grpcio>=1 proto-plus>=1 -protobuf>=6 +protobuf>=7 diff --git a/release-please-bulk-config.json b/release-please-bulk-config.json index eddb861e6b11..c8e66cb251b1 100644 --- a/release-please-bulk-config.json +++ b/release-please-bulk-config.json @@ -981,18 +981,6 @@ "google/cloud/common/gapic_version.py" ] }, - "packages/google-cloud-compute": { - "component": "google-cloud-compute", - "extra-files": [ - "google/cloud/compute/gapic_version.py", - "google/cloud/compute_v1/gapic_version.py", - { - "jsonpath": "$.clientLibrary.version", - "path": "samples/generated_samples/snippet_metadata_google.cloud.compute.v1.json", - "type": "json" - } - ] - }, "packages/google-cloud-compute-v1beta": { "component": "google-cloud-compute-v1beta", "extra-files": [ @@ -2811,32 +2799,6 @@ "google/cloud/source_context_v1/gapic_version.py" ] }, - "packages/google-cloud-spanner": { - "component": "google-cloud-spanner", - "extra-files": [ - "google/cloud/spanner/gapic_version.py", - "google/cloud/spanner_admin_database/gapic_version.py", - "google/cloud/spanner_admin_database_v1/gapic_version.py", - "google/cloud/spanner_admin_instance/gapic_version.py", - "google/cloud/spanner_admin_instance_v1/gapic_version.py", - "google/cloud/spanner_v1/gapic_version.py", - { - "jsonpath": "$.clientLibrary.version", - "path": "samples/generated_samples/snippet_metadata_google.spanner.admin.database.v1.json", - "type": "json" - }, - { - "jsonpath": "$.clientLibrary.version", - "path": "samples/generated_samples/snippet_metadata_google.spanner.admin.instance.v1.json", - "type": "json" - }, - { - "jsonpath": "$.clientLibrary.version", - "path": "samples/generated_samples/snippet_metadata_google.spanner.v1.json", - "type": "json" - } - ] - }, "packages/google-cloud-speech": { "component": "google-cloud-speech", "extra-files": [ diff --git a/release-please-individual-config.json b/release-please-individual-config.json index 793e723414a4..2d6e68f7402a 100644 --- a/release-please-individual-config.json +++ b/release-please-individual-config.json @@ -19,6 +19,18 @@ } ] }, + "packages/google-cloud-compute": { + "component": "google-cloud-compute", + "extra-files": [ + "google/cloud/compute/gapic_version.py", + "google/cloud/compute_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.compute.v1.json", + "type": "json" + } + ] + }, "packages/google-cloud-firestore": { "component": "google-cloud-firestore", "extra-files": [ @@ -39,6 +51,32 @@ } ] }, + "packages/google-cloud-spanner": { + "component": "google-cloud-spanner", + "extra-files": [ + "google/cloud/spanner/gapic_version.py", + "google/cloud/spanner_admin_database/gapic_version.py", + "google/cloud/spanner_admin_database_v1/gapic_version.py", + "google/cloud/spanner_admin_instance/gapic_version.py", + "google/cloud/spanner_admin_instance_v1/gapic_version.py", + "google/cloud/spanner_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.spanner.admin.database.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.spanner.admin.instance.v1.json", + "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.spanner.v1.json", + "type": "json" + } + ] + }, "packages/google-crc32c": { "component": "google-crc32c" }, From 586c7f76c5f03bb15bb04b8d18d9f4efee86f515 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Tue, 23 Jun 2026 13:20:44 -0700 Subject: [PATCH 119/174] chore(bigtable): fix flaky batcher flush interval test (#17545) **Flaky test**: - The unit test `test_mutations_batcher_flush_interval` was flaky under load because it relied on real wall-clock sleep durations (`time.sleep(0.4)` and `time.sleep(0.1)`). On busy VM executors, minor CPU scheduling delays caused the test thread to wake up out of sync with the background `threading.Timer` execution thread, triggering sporadic test failures. **Solution**: - Refactored the test to completely mock `threading.Timer` instead of relying on real-time sleeps: a. Verifies that `MutationsBatcher` instantiates the background timer with the correct `flush_interval` and starts it. b. Manually triggers the timer's callback function to verify it calls `flush()` synchronously. This makes the unit test 100% deterministic, immune to VM executor load, and significantly faster. --- .../tests/unit/v2_client/test_batcher.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/packages/google-cloud-bigtable/tests/unit/v2_client/test_batcher.py b/packages/google-cloud-bigtable/tests/unit/v2_client/test_batcher.py index 4090c3c81cea..847e769bf08c 100644 --- a/packages/google-cloud-bigtable/tests/unit/v2_client/test_batcher.py +++ b/packages/google-cloud-bigtable/tests/unit/v2_client/test_batcher.py @@ -13,8 +13,6 @@ # limitations under the License. -import time - import mock import pytest @@ -175,23 +173,22 @@ def test_mutations_batcher_context_manager_flushed_when_closed(): assert table.mutation_calls == 1 +@mock.patch("google.cloud.bigtable.batcher.threading.Timer") @mock.patch("google.cloud.bigtable.batcher.MutationsBatcher.flush") -def test_mutations_batcher_flush_interval(mocked_flush): +def test_mutations_batcher_flush_interval(mocked_flush, mocked_timer): table = _Table(TABLE_NAME) flush_interval = 0.5 mutation_batcher = MutationsBatcher(table=table, flush_interval=flush_interval) - assert mutation_batcher._timer.interval == flush_interval - mocked_flush.assert_not_called() - - time.sleep(0.4) + mocked_timer.assert_called_once_with(flush_interval, mutation_batcher.flush) + mocked_timer.return_value.start.assert_called_once_with() mocked_flush.assert_not_called() - time.sleep(0.1) + # Manually invoke the timer callback to verify it calls flush + timer_callback = mocked_timer.call_args[0][1] + timer_callback() mocked_flush.assert_called_once_with() - mutation_batcher.close() - def test_mutations_batcher_response_with_error_codes(): from google.rpc.status_pb2 import Status From 147908ec17c86ae92b5653d1d62d8d7fcdec6476 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Tue, 23 Jun 2026 13:21:26 -0700 Subject: [PATCH 120/174] chore(bigtable): fix flaky sharded query concurrency limit test by relaxing eps (#17541) **Flaky tests**: - The test `test_read_rows_sharded_concurrency_limit` was flaky under VM execution load because it checked if all of the first 10 concurrent requests were dispatched within `eps = 0.01` seconds (10 milliseconds) of the operation's start. Due to CPU scheduling and thread context switching overhead on virtualized CI hosts (like Kokoro), dispatching 10 concurrent threads/tasks can occasionally take slightly longer than 10ms, triggering random `AssertionError` failures. **Solution**: - Relaxed the threshold `eps` from `0.01` to `0.2` seconds (200 milliseconds) in: - The async source test file: [tests/unit/data/_async/test_client.py](file:///usr/local/google/home/omairn/git/googleapis/google-cloud-python/packages/google-cloud-bigtable/tests/unit/data/_async/test_client.py) - The sync auto-generated test file: [tests/unit/data/_sync_autogen/test_client.py](file:///usr/local/google/home/omairn/git/googleapis/google-cloud-python/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_client.py) This allows enough scheduling margin for virtualized CI runners to pass successfully while still validating that the first 10 queries are fired concurrently without delay compared to the queued queries. --- .../google-cloud-bigtable/tests/unit/data/_async/test_client.py | 2 +- .../tests/unit/data/_sync_autogen/test_client.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/google-cloud-bigtable/tests/unit/data/_async/test_client.py b/packages/google-cloud-bigtable/tests/unit/data/_async/test_client.py index 8d2aa9872d01..534b5e61132b 100644 --- a/packages/google-cloud-bigtable/tests/unit/data/_async/test_client.py +++ b/packages/google-cloud-bigtable/tests/unit/data/_async/test_client.py @@ -2328,7 +2328,7 @@ async def mock_call(*args, **kwargs): starting_timeout - kwargs["operation_timeout"] for _, kwargs in read_rows.call_args_list ] - eps = 0.01 + eps = 0.2 # first 10 should start immediately assert all( rpc_start_list[i] < eps for i in range(_CONCURRENCY_LIMIT) diff --git a/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_client.py b/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_client.py index ca5158381774..2336f41117ab 100644 --- a/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_client.py +++ b/packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_client.py @@ -1926,7 +1926,7 @@ def mock_call(*args, **kwargs): starting_timeout - kwargs["operation_timeout"] for _, kwargs in read_rows.call_args_list ] - eps = 0.01 + eps = 0.2 assert all( (rpc_start_list[i] < eps for i in range(_CONCURRENCY_LIMIT)) ) From e97590cfcb8f177cfaa7ee755fc0a1bd985aa81c Mon Sep 17 00:00:00 2001 From: Anthonios Partheniou Date: Tue, 23 Jun 2026 16:46:01 -0400 Subject: [PATCH 121/174] chore: migrate packages to release please individual manifest (#17552) Closes https://github.com/googleapis/google-cloud-python/pull/17551 Closes https://github.com/googleapis/google-cloud-python/pull/17550 --- .release-please-bulk-manifest.json | 2 -- .release-please-individual-manifest.json | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.release-please-bulk-manifest.json b/.release-please-bulk-manifest.json index 7f62552607b8..fabe44cb47af 100644 --- a/.release-please-bulk-manifest.json +++ b/.release-please-bulk-manifest.json @@ -77,7 +77,6 @@ "packages/google-cloud-cloudsecuritycompliance": "0.8.0", "packages/google-cloud-commerce-consumer-procurement": "0.6.0", "packages/google-cloud-common": "1.10.0", - "packages/google-cloud-compute": "1.48.0", "packages/google-cloud-compute-v1beta": "0.12.0", "packages/google-cloud-confidentialcomputing": "0.11.0", "packages/google-cloud-config": "0.7.0", @@ -205,7 +204,6 @@ "packages/google-cloud-servicehealth": "0.5.0", "packages/google-cloud-shell": "1.16.0", "packages/google-cloud-source-context": "1.11.0", - "packages/google-cloud-spanner": "3.68.0", "packages/google-cloud-speech": "2.40.0", "packages/google-cloud-storage": "3.12.0", "packages/google-cloud-storage-control": "1.12.0", diff --git a/.release-please-individual-manifest.json b/.release-please-individual-manifest.json index 5b5b19f6b235..0f5ab7b0ed7e 100644 --- a/.release-please-individual-manifest.json +++ b/.release-please-individual-manifest.json @@ -1,7 +1,9 @@ { "packages/bigframes": "2.43.0", "packages/google-cloud-bigtable": "2.39.0", + "packages/google-cloud-compute": "1.48.0", "packages/google-cloud-firestore": "2.27.0", + "packages/google-cloud-spanner": "3.68.0", "packages/google-crc32c": "1.8.0", "packages/pandas-gbq": "0.35.0", "packages/sqlalchemy-bigquery": "1.17.0" From 8d66c089da74b9ae6cd73c04200cc7da6cdcfb8a Mon Sep 17 00:00:00 2001 From: Joe Wang <106995533+JoeWang1127@users.noreply.github.com> Date: Tue, 23 Jun 2026 21:12:03 +0000 Subject: [PATCH 122/174] chore: update librarian to v0.22.0 (#17553) --- librarian.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librarian.yaml b/librarian.yaml index e8cc16d4b7bc..2f3a4a2cc90a 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. language: python -version: v0.21.0 +version: v0.22.0 repo: googleapis/google-cloud-python sources: googleapis: From e5d2e35db94373ca395976fd755c2bc7e0a060bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Swe=C3=B1a=20=28Swast=29?= Date: Tue, 23 Jun 2026 16:32:40 -0500 Subject: [PATCH 123/174] feat: add date functions to `bigframes.bigquery` module (#17514) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Used the following prompt: > Update the descriptions and argument names in scripts/data/sql-functions/global-namespace/date.yaml according to the following SQL documentation: > > (Paste from https://docs.cloud.google.com/bigquery/docs/reference/standard-sql/date_functions) > > Also, if there is a natural argument to use for `series_accessor_arg` in this yaml or others, add it. Towards BigQuery SQL API coverage. 🦕 --- .../bigframes/bigframes/bigquery/__init__.py | 43 ++ .../extensions/core/series_accessor.py | 368 ++++++++++++++++ .../googlesql/global_namespace/date.py | 412 ++++++++++++++++++ .../sql-functions/global_namespace/bit.yaml | 1 + .../sql-functions/global_namespace/date.yaml | 277 ++++++++++++ .../scripts/generate_bigframes_bigquery.py | 20 + .../templates/core_series_accessor.py.j2 | 1 + .../generated/global_namespace/test_date.py | 340 +++++++++++++++ 8 files changed, 1462 insertions(+) create mode 100644 packages/bigframes/bigframes/operations/googlesql/global_namespace/date.py create mode 100644 packages/bigframes/scripts/data/sql-functions/global_namespace/date.yaml create mode 100644 packages/bigframes/tests/unit/bigquery/generated/global_namespace/test_date.py diff --git a/packages/bigframes/bigframes/bigquery/__init__.py b/packages/bigframes/bigframes/bigquery/__init__.py index 99a47d218691..ade7535c32bd 100644 --- a/packages/bigframes/bigframes/bigquery/__init__.py +++ b/packages/bigframes/bigframes/bigquery/__init__.py @@ -126,6 +126,21 @@ parse_numeric, string, ) +from bigframes.operations.googlesql.global_namespace.date import ( + current_date, + date, + date_add, + date_diff, + date_from_unix_date, + date_sub, + date_trunc, + extract, + format_date, + generate_date_array, + last_day, + parse_date, + unix_date, +) _functions = [ # approximate aggregate ops @@ -156,6 +171,20 @@ parse_bignumeric, parse_numeric, string, + # date ops + current_date, + date, + date_add, + date_diff, + date_from_unix_date, + date_sub, + date_trunc, + extract, + format_date, + generate_date_array, + last_day, + parse_date, + unix_date, # datetime ops unix_micros, unix_millis, @@ -240,6 +269,20 @@ "parse_bignumeric", "parse_numeric", "string", + # date ops + "current_date", + "date", + "date_add", + "date_diff", + "date_from_unix_date", + "date_sub", + "date_trunc", + "extract", + "format_date", + "generate_date_array", + "last_day", + "parse_date", + "unix_date", # datetime ops "unix_micros", "unix_millis", diff --git a/packages/bigframes/bigframes/extensions/core/series_accessor.py b/packages/bigframes/bigframes/extensions/core/series_accessor.py index 86f34e9ab603..440e6731aba2 100644 --- a/packages/bigframes/bigframes/extensions/core/series_accessor.py +++ b/packages/bigframes/bigframes/extensions/core/series_accessor.py @@ -19,6 +19,7 @@ from __future__ import annotations import abc +import datetime from typing import ( Any, Literal, @@ -589,6 +590,22 @@ def flatten( ) return self._to_series(cast(series.Series, result)) + def bit_count( + self, + *, + session: Optional[session.Session] = None, + ) -> S: + """The input, `expression`, must be an integer or `BYTES`. Returns the number of bits that are set in the input expression. For signed integers, this is the number of bits in two's complement form.""" + from bigframes.operations.googlesql.global_namespace.bit import ( + bit_count as bit_count_impl, + ) + + bf_series = self._bf_from_series(session) + result = bit_count_impl( + bf_series, + ) + return self._to_series(cast(series.Series, result)) + def bool_( self, *, @@ -743,6 +760,357 @@ def string( ) return self._to_series(cast(series.Series, result)) + def date( + self, + time_zone_expression: Union[ + series.Series, + col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, + year: Union[ + series.Series, + col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], int], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, + month: Union[ + series.Series, + col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], int], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, + day: Union[ + series.Series, + col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], int], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, + *, + session: Optional[session.Session] = None, + ) -> S: + """Constructs or extracts a date.""" + from bigframes.operations.googlesql.global_namespace.date import ( + date as date_impl, + ) + + # Resolve session from other arguments if not passed + if session is None: + from bigframes.core import googlesql + + session = googlesql._find_session( + time_zone_expression, + year, + month, + day, + ) + + bf_series = self._bf_from_series(session) + result = date_impl( + bf_series, + time_zone_expression, + year, + month, + day, + ) + return self._to_series(cast(series.Series, result)) + + def date_add( + self, + int64_expression: Union[ + series.Series, + col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], int], + ], + date_part: Union[ + series.Series, + col.Expression, + Union[Any, Literal[sentinels.Sentinel.ARGUMENT_DEFAULT]], + ], + *, + session: Optional[session.Session] = None, + ) -> S: + """Adds a specified time interval to a DATE.""" + from bigframes.operations.googlesql.global_namespace.date import ( + date_add as date_add_impl, + ) + + # Resolve session from other arguments if not passed + if session is None: + from bigframes.core import googlesql + + session = googlesql._find_session( + int64_expression, + date_part, + ) + + bf_series = self._bf_from_series(session) + result = date_add_impl( + bf_series, + int64_expression, + date_part, + ) + return self._to_series(cast(series.Series, result)) + + def date_diff( + self, + start_date: Union[ + series.Series, + col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], datetime.date], + ], + granularity: Union[ + series.Series, + col.Expression, + Union[Any, Literal[sentinels.Sentinel.ARGUMENT_DEFAULT]], + ], + *, + session: Optional[session.Session] = None, + ) -> S: + """Gets the number of unit boundaries between two DATE values (end_date - start_date) at a particular time granularity.""" + from bigframes.operations.googlesql.global_namespace.date import ( + date_diff as date_diff_impl, + ) + + # Resolve session from other arguments if not passed + if session is None: + from bigframes.core import googlesql + + session = googlesql._find_session( + start_date, + granularity, + ) + + bf_series = self._bf_from_series(session) + result = date_diff_impl( + bf_series, + start_date, + granularity, + ) + return self._to_series(cast(series.Series, result)) + + def date_from_unix_date( + self, + *, + session: Optional[session.Session] = None, + ) -> S: + """Interprets an INT64 expression as the number of days since 1970-01-01.""" + from bigframes.operations.googlesql.global_namespace.date import ( + date_from_unix_date as date_from_unix_date_impl, + ) + + bf_series = self._bf_from_series(session) + result = date_from_unix_date_impl( + bf_series, + ) + return self._to_series(cast(series.Series, result)) + + def date_sub( + self, + int64_expression: Union[ + series.Series, + col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], int], + ], + date_part: Union[ + series.Series, + col.Expression, + Union[Any, Literal[sentinels.Sentinel.ARGUMENT_DEFAULT]], + ], + *, + session: Optional[session.Session] = None, + ) -> S: + """Subtracts a specified time interval from a DATE.""" + from bigframes.operations.googlesql.global_namespace.date import ( + date_sub as date_sub_impl, + ) + + # Resolve session from other arguments if not passed + if session is None: + from bigframes.core import googlesql + + session = googlesql._find_session( + int64_expression, + date_part, + ) + + bf_series = self._bf_from_series(session) + result = date_sub_impl( + bf_series, + int64_expression, + date_part, + ) + return self._to_series(cast(series.Series, result)) + + def date_trunc( + self, + granularity: Union[ + series.Series, + col.Expression, + Union[Any, Literal[sentinels.Sentinel.ARGUMENT_DEFAULT]], + ], + *, + session: Optional[session.Session] = None, + ) -> S: + """Truncates a DATE, DATETIME, or TIMESTAMP value at a particular granularity.""" + from bigframes.operations.googlesql.global_namespace.date import ( + date_trunc as date_trunc_impl, + ) + + # Resolve session from other arguments if not passed + if session is None: + from bigframes.core import googlesql + + session = googlesql._find_session( + granularity, + ) + + bf_series = self._bf_from_series(session) + result = date_trunc_impl( + bf_series, + granularity, + ) + return self._to_series(cast(series.Series, result)) + + def extract( + self, + part: Union[ + series.Series, + col.Expression, + Union[Any, Literal[sentinels.Sentinel.ARGUMENT_DEFAULT]], + ], + time_zone: Union[ + series.Series, + col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, + *, + session: Optional[session.Session] = None, + ) -> S: + """Returns the value corresponding to the specified date part.""" + from bigframes.operations.googlesql.global_namespace.date import ( + extract as extract_impl, + ) + + # Resolve session from other arguments if not passed + if session is None: + from bigframes.core import googlesql + + session = googlesql._find_session( + part, + time_zone, + ) + + bf_series = self._bf_from_series(session) + result = extract_impl( + bf_series, + part, + time_zone, + ) + return self._to_series(cast(series.Series, result)) + + def format_date( + self, + format_string: Union[ + series.Series, + col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ], + *, + session: Optional[session.Session] = None, + ) -> S: + """Formats a DATE value according to a specified format string.""" + from bigframes.operations.googlesql.global_namespace.date import ( + format_date as format_date_impl, + ) + + # Resolve session from other arguments if not passed + if session is None: + from bigframes.core import googlesql + + session = googlesql._find_session( + format_string, + ) + + bf_series = self._bf_from_series(session) + result = format_date_impl( + format_string, + bf_series, + ) + return self._to_series(cast(series.Series, result)) + + def last_day( + self, + date_part: Union[ + series.Series, + col.Expression, + Union[Any, Literal[sentinels.Sentinel.ARGUMENT_DEFAULT]], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, + *, + session: Optional[session.Session] = None, + ) -> S: + """Returns the last day from a date expression. This is commonly used to return the last day of the month.""" + from bigframes.operations.googlesql.global_namespace.date import ( + last_day as last_day_impl, + ) + + # Resolve session from other arguments if not passed + if session is None: + from bigframes.core import googlesql + + session = googlesql._find_session( + date_part, + ) + + bf_series = self._bf_from_series(session) + result = last_day_impl( + bf_series, + date_part, + ) + return self._to_series(cast(series.Series, result)) + + def parse_date( + self, + format_string: Union[ + series.Series, + col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ], + *, + session: Optional[session.Session] = None, + ) -> S: + """Converts a STRING value to a DATE value.""" + from bigframes.operations.googlesql.global_namespace.date import ( + parse_date as parse_date_impl, + ) + + # Resolve session from other arguments if not passed + if session is None: + from bigframes.core import googlesql + + session = googlesql._find_session( + format_string, + ) + + bf_series = self._bf_from_series(session) + result = parse_date_impl( + format_string, + bf_series, + ) + return self._to_series(cast(series.Series, result)) + + def unix_date( + self, + *, + session: Optional[session.Session] = None, + ) -> S: + """Returns the number of days since 1970-01-01.""" + from bigframes.operations.googlesql.global_namespace.date import ( + unix_date as unix_date_impl, + ) + + bf_series = self._bf_from_series(session) + result = unix_date_impl( + bf_series, + ) + return self._to_series(cast(series.Series, result)) + class AiSeriesAccessor(series_tvf_mixins.AITVFMixin[T, S]): """Series accessor for BigQuery ai functions.""" diff --git a/packages/bigframes/bigframes/operations/googlesql/global_namespace/date.py b/packages/bigframes/bigframes/operations/googlesql/global_namespace/date.py new file mode 100644 index 000000000000..b6cfc9722b52 --- /dev/null +++ b/packages/bigframes/bigframes/operations/googlesql/global_namespace/date.py @@ -0,0 +1,412 @@ +# Copyright 2026 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. +# +# DO NOT MODIFY THIS FILE DIRECTLY. +# This file was generated from: scripts/data/sql-functions/global_namespace/date.yaml +# by the script: scripts/generate_bigframes_bigquery.py + +from __future__ import annotations + +import datetime +from typing import Any, Literal, Union + +import bigframes.core.col +import bigframes.core.googlesql +import bigframes.core.sentinels as sentinels +import bigframes.series as series +from bigframes import dtypes +from bigframes.operations import googlesql + +_CURRENT_DATE_OP = googlesql.GoogleSqlScalarOp( + "CURRENT_DATE", + args=(googlesql.ArgSpec(optional=True),), + signature=lambda *args: dtypes.DATE_DTYPE, +) +_DATE_OP = googlesql.GoogleSqlScalarOp( + "DATE", + args=( + googlesql.ArgSpec(optional=True), + googlesql.ArgSpec(optional=True), + googlesql.ArgSpec(optional=True), + googlesql.ArgSpec(optional=True), + googlesql.ArgSpec(optional=True), + ), + signature=lambda *args: dtypes.DATE_DTYPE, +) +_DATE_ADD_OP = googlesql.GoogleSqlScalarOp( + "DATE_ADD", + args=(googlesql.ArgSpec(), googlesql.ArgSpec(), googlesql.ArgSpec()), + signature=lambda *args: dtypes.DATE_DTYPE, +) +_DATE_DIFF_OP = googlesql.GoogleSqlScalarOp( + "DATE_DIFF", + args=(googlesql.ArgSpec(), googlesql.ArgSpec(), googlesql.ArgSpec()), + signature=lambda *args: dtypes.INT_DTYPE, +) +_DATE_FROM_UNIX_DATE_OP = googlesql.GoogleSqlScalarOp( + "DATE_FROM_UNIX_DATE", + args=(googlesql.ArgSpec(),), + signature=lambda *args: dtypes.DATE_DTYPE, +) +_DATE_SUB_OP = googlesql.GoogleSqlScalarOp( + "DATE_SUB", + args=(googlesql.ArgSpec(), googlesql.ArgSpec(), googlesql.ArgSpec()), + signature=lambda *args: dtypes.DATE_DTYPE, +) +_DATE_TRUNC_OP = googlesql.GoogleSqlScalarOp( + "DATE_TRUNC", + args=(googlesql.ArgSpec(), googlesql.ArgSpec()), + signature=lambda *args: dtypes.DATE_DTYPE, +) +_EXTRACT_OP = googlesql.GoogleSqlScalarOp( + "EXTRACT", + args=(googlesql.ArgSpec(), googlesql.ArgSpec(), googlesql.ArgSpec(optional=True)), + signature=lambda *args: dtypes.INT_DTYPE, +) +_FORMAT_DATE_OP = googlesql.GoogleSqlScalarOp( + "FORMAT_DATE", + args=(googlesql.ArgSpec(), googlesql.ArgSpec()), + signature=lambda *args: dtypes.STRING_DTYPE, +) +_GENERATE_DATE_ARRAY_OP = googlesql.GoogleSqlScalarOp( + "GENERATE_DATE_ARRAY", + args=( + googlesql.ArgSpec(), + googlesql.ArgSpec(), + googlesql.ArgSpec(optional=True), + googlesql.ArgSpec(optional=True), + ), + signature=lambda *args: dtypes.list_type(dtypes.DATE_DTYPE), +) +_LAST_DAY_OP = googlesql.GoogleSqlScalarOp( + "LAST_DAY", + args=(googlesql.ArgSpec(), googlesql.ArgSpec(optional=True)), + signature=lambda *args: dtypes.DATE_DTYPE, +) +_PARSE_DATE_OP = googlesql.GoogleSqlScalarOp( + "PARSE_DATE", + args=(googlesql.ArgSpec(), googlesql.ArgSpec()), + signature=lambda *args: dtypes.DATE_DTYPE, +) +_UNIX_DATE_OP = googlesql.GoogleSqlScalarOp( + "UNIX_DATE", + args=(googlesql.ArgSpec(),), + signature=lambda *args: dtypes.INT_DTYPE, +) + + +def current_date( + time_zone_expression: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, +) -> Union[series.Series, bigframes.core.col.Expression]: + """Returns the current date as a DATE object. Parentheses are optional when called with no arguments.""" + return bigframes.core.googlesql.apply_googlesql_scalar_op( + _CURRENT_DATE_OP, + time_zone_expression, + ) + + +def date( + expression: Union[ + series.Series, + bigframes.core.col.Expression, + Union[ + Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], + datetime.date, + datetime.datetime, + str, + ], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, + time_zone_expression: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, + year: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], int], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, + month: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], int], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, + day: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], int], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, +) -> Union[series.Series, bigframes.core.col.Expression]: + """Constructs or extracts a date.""" + return bigframes.core.googlesql.apply_googlesql_scalar_op( + _DATE_OP, + expression, + time_zone_expression, + year, + month, + day, + ) + + +def date_add( + date_expression: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], datetime.date], + ], + int64_expression: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], int], + ], + date_part: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Any, Literal[sentinels.Sentinel.ARGUMENT_DEFAULT]], + ], +) -> Union[series.Series, bigframes.core.col.Expression]: + """Adds a specified time interval to a DATE.""" + return bigframes.core.googlesql.apply_googlesql_scalar_op( + _DATE_ADD_OP, + date_expression, + int64_expression, + date_part, + ) + + +def date_diff( + end_date: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], datetime.date], + ], + start_date: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], datetime.date], + ], + granularity: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Any, Literal[sentinels.Sentinel.ARGUMENT_DEFAULT]], + ], +) -> Union[series.Series, bigframes.core.col.Expression]: + """Gets the number of unit boundaries between two DATE values (end_date - start_date) at a particular time granularity.""" + return bigframes.core.googlesql.apply_googlesql_scalar_op( + _DATE_DIFF_OP, + end_date, + start_date, + granularity, + ) + + +def date_from_unix_date( + int64_expression: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], int], + ], +) -> Union[series.Series, bigframes.core.col.Expression]: + """Interprets an INT64 expression as the number of days since 1970-01-01.""" + return bigframes.core.googlesql.apply_googlesql_scalar_op( + _DATE_FROM_UNIX_DATE_OP, + int64_expression, + ) + + +def date_sub( + date_expression: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], datetime.date], + ], + int64_expression: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], int], + ], + date_part: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Any, Literal[sentinels.Sentinel.ARGUMENT_DEFAULT]], + ], +) -> Union[series.Series, bigframes.core.col.Expression]: + """Subtracts a specified time interval from a DATE.""" + return bigframes.core.googlesql.apply_googlesql_scalar_op( + _DATE_SUB_OP, + date_expression, + int64_expression, + date_part, + ) + + +def date_trunc( + date_value: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], datetime.date], + ], + granularity: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Any, Literal[sentinels.Sentinel.ARGUMENT_DEFAULT]], + ], +) -> Union[series.Series, bigframes.core.col.Expression]: + """Truncates a DATE, DATETIME, or TIMESTAMP value at a particular granularity.""" + return bigframes.core.googlesql.apply_googlesql_scalar_op( + _DATE_TRUNC_OP, + date_value, + granularity, + ) + + +def extract( + date_expression: Union[ + series.Series, + bigframes.core.col.Expression, + Union[ + Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], + datetime.date, + datetime.datetime, + datetime.time, + ], + ], + part: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Any, Literal[sentinels.Sentinel.ARGUMENT_DEFAULT]], + ], + time_zone: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, +) -> Union[series.Series, bigframes.core.col.Expression]: + """Returns the value corresponding to the specified date part.""" + return bigframes.core.googlesql.apply_googlesql_scalar_op( + _EXTRACT_OP, + date_expression, + part, + time_zone, + ) + + +def format_date( + format_string: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ], + date_expr: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], datetime.date], + ], +) -> Union[series.Series, bigframes.core.col.Expression]: + """Formats a DATE value according to a specified format string.""" + return bigframes.core.googlesql.apply_googlesql_scalar_op( + _FORMAT_DATE_OP, + format_string, + date_expr, + ) + + +def generate_date_array( + start_date: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], datetime.date], + ], + end_date: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], datetime.date], + ], + int64_expression: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], int], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, + date_part: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Any, Literal[sentinels.Sentinel.ARGUMENT_DEFAULT]], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, +) -> Union[series.Series, bigframes.core.col.Expression]: + """Generates an array of dates in a range.""" + return bigframes.core.googlesql.apply_googlesql_scalar_op( + _GENERATE_DATE_ARRAY_OP, + start_date, + end_date, + int64_expression, + date_part, + ) + + +def last_day( + date_expression: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], datetime.date], + ], + date_part: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Any, Literal[sentinels.Sentinel.ARGUMENT_DEFAULT]], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, +) -> Union[series.Series, bigframes.core.col.Expression]: + """Returns the last day from a date expression. This is commonly used to return the last day of the month.""" + return bigframes.core.googlesql.apply_googlesql_scalar_op( + _LAST_DAY_OP, + date_expression, + date_part, + ) + + +def parse_date( + format_string: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ], + date_string: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ], +) -> Union[series.Series, bigframes.core.col.Expression]: + """Converts a STRING value to a DATE value.""" + return bigframes.core.googlesql.apply_googlesql_scalar_op( + _PARSE_DATE_OP, + format_string, + date_string, + ) + + +def unix_date( + date_expression: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], datetime.date], + ], +) -> Union[series.Series, bigframes.core.col.Expression]: + """Returns the number of days since 1970-01-01.""" + return bigframes.core.googlesql.apply_googlesql_scalar_op( + _UNIX_DATE_OP, + date_expression, + ) diff --git a/packages/bigframes/scripts/data/sql-functions/global_namespace/bit.yaml b/packages/bigframes/scripts/data/sql-functions/global_namespace/bit.yaml index 3c2953133e49..fe14eae7b649 100644 --- a/packages/bigframes/scripts/data/sql-functions/global_namespace/bit.yaml +++ b/packages/bigframes/scripts/data/sql-functions/global_namespace/bit.yaml @@ -2,6 +2,7 @@ urn: extension:google:bq_scalar_functions scalar_functions: - name: "bit_count" description: "The input, `expression`, must be an integer or `BYTES`. Returns the number of bits that are set in the input expression. For signed integers, this is the number of bits in two's complement form." + series_accessor_arg: expression impls: # Signature: bit_count:i32 - args: diff --git a/packages/bigframes/scripts/data/sql-functions/global_namespace/date.yaml b/packages/bigframes/scripts/data/sql-functions/global_namespace/date.yaml new file mode 100644 index 000000000000..8d1dfc952840 --- /dev/null +++ b/packages/bigframes/scripts/data/sql-functions/global_namespace/date.yaml @@ -0,0 +1,277 @@ +urn: extension:google:bq_scalar_functions +scalar_functions: + - name: "current_date" + description: "Returns the current date as a DATE object. Parentheses are optional when called with no arguments." + impls: + # Signature: current_date:str + - args: + - name: "time_zone_expression" + value: string + optional: true + keyword_only: false + return: date + - name: "date" + description: "Constructs or extracts a date." + series_accessor_arg: expression + impls: + # Signature: date:pts_str + - args: + - name: "expression" + value: timestamp + optional: false + keyword_only: false + - name: "time_zone_expression" + value: string + optional: true + keyword_only: false + return: date + # Signature: date:pts + - args: + - name: "expression" + value: timestamp + optional: false + keyword_only: false + return: date + # Signature: date:i64_i64_i64 + - args: + - name: "year" + value: i64 + optional: false + keyword_only: false + - name: "month" + value: i64 + optional: false + keyword_only: false + - name: "day" + value: i64 + optional: false + keyword_only: false + return: date + # Signature: date:date + - args: + - name: "expression" + value: date + optional: false + keyword_only: false + return: date + # Signature: date:str + - args: + - name: "expression" + value: string + optional: false + keyword_only: false + return: date + - name: "date_add" + description: "Adds a specified time interval to a DATE." + series_accessor_arg: date_expression + impls: + # Signature: date_add:date_i64_any + - args: + - name: "date_expression" + value: date + optional: false + keyword_only: false + - name: "int64_expression" + value: i64 + optional: false + keyword_only: false + - name: "date_part" + value: any1 + optional: false + keyword_only: false + return: date + # TODO(b/527093666): add support for date_bucket when we add an INTERVAL dtype + - name: "date_diff" + description: "Gets the number of unit boundaries between two DATE values (end_date - start_date) at a particular time granularity." + series_accessor_arg: end_date + impls: + # Signature: date_diff:date_date_any + - args: + - name: "end_date" + value: date + optional: false + keyword_only: false + - name: "start_date" + value: date + optional: false + keyword_only: false + - name: "granularity" + value: any1 + optional: false + keyword_only: false + return: i64 + - name: "date_from_unix_date" + description: "Interprets an INT64 expression as the number of days since 1970-01-01." + series_accessor_arg: int64_expression + impls: + # Signature: date_from_unix_date:i64 + - args: + - name: "int64_expression" + value: i64 + optional: false + keyword_only: false + return: date + - name: "date_sub" + description: "Subtracts a specified time interval from a DATE." + series_accessor_arg: date_expression + impls: + # Signature: date_sub:date_i64_any + - args: + - name: "date_expression" + value: date + optional: false + keyword_only: false + - name: "int64_expression" + value: i64 + optional: false + keyword_only: false + - name: "date_part" + value: any1 + optional: false + keyword_only: false + return: date + - name: "date_trunc" + description: "Truncates a DATE, DATETIME, or TIMESTAMP value at a particular granularity." + series_accessor_arg: date_value + impls: + # Signature: date_trunc:date_any + - args: + - name: "date_value" + value: date + optional: false + keyword_only: false + - name: "granularity" + value: any1 + optional: false + keyword_only: false + return: date + - name: "extract" + description: "Returns the value corresponding to the specified date part." + series_accessor_arg: date_expression + impls: + # Signature: extract:date_any + - args: + - name: "date_expression" + value: date + optional: false + keyword_only: false + - name: "part" + value: any1 + optional: false + keyword_only: false + return: i64 + # Signature: extract:pts_any_str + - args: + - name: "date_expression" + value: timestamp + optional: false + keyword_only: false + - name: "part" + value: any1 + optional: false + keyword_only: false + - name: "time_zone" + value: string + optional: true + keyword_only: false + return: i64 + # Signature: extract:pts_any + - args: + - name: "date_expression" + value: timestamp + optional: false + keyword_only: false + - name: "part" + value: any1 + optional: false + keyword_only: false + return: i64 + # Signature: extract:pt_any + - args: + - name: "date_expression" + value: time + optional: false + keyword_only: false + - name: "part" + value: any1 + optional: false + keyword_only: false + return: i64 + - name: "format_date" + description: "Formats a DATE value according to a specified format string." + series_accessor_arg: date_expr + impls: + # Signature: format_date:str_date + - args: + - name: "format_string" + value: string + optional: false + keyword_only: false + - name: "date_expr" + value: date + optional: false + keyword_only: false + return: string + - name: "generate_date_array" + description: "Generates an array of dates in a range." + impls: + # Signature: generate_date_array:date_date_i64_any + - args: + - name: "start_date" + value: date + optional: false + keyword_only: false + - name: "end_date" + value: date + optional: false + keyword_only: false + - name: "int64_expression" + value: i64 + optional: true + keyword_only: false + - name: "date_part" + value: any1 + optional: true + keyword_only: false + return: list + - name: "last_day" + description: "Returns the last day from a date expression. This is commonly used to return the last day of the month." + series_accessor_arg: date_expression + impls: + # Signature: last_day:date_any + - args: + - name: "date_expression" + value: date + optional: false + keyword_only: false + - name: "date_part" + value: any1 + optional: true + keyword_only: false + return: date + - name: "parse_date" + description: "Converts a STRING value to a DATE value." + series_accessor_arg: date_string + impls: + # Signature: parse_date:str_str + - args: + - name: "format_string" + value: string + optional: false + keyword_only: false + - name: "date_string" + value: string + optional: false + keyword_only: false + return: date + - name: "unix_date" + description: "Returns the number of days since 1970-01-01." + series_accessor_arg: date_expression + impls: + # Signature: unix_date:date + - args: + - name: "date_expression" + value: date + optional: false + keyword_only: false + return: i64 diff --git a/packages/bigframes/scripts/generate_bigframes_bigquery.py b/packages/bigframes/scripts/generate_bigframes_bigquery.py index 999f17b10215..0381d168329f 100755 --- a/packages/bigframes/scripts/generate_bigframes_bigquery.py +++ b/packages/bigframes/scripts/generate_bigframes_bigquery.py @@ -98,6 +98,7 @@ "struct": "dict", "decimal<38,9>": "decimal.Decimal", "decimal<76,38>": "decimal.Decimal", + "interval_day": "datetime.timedelta", } YAML_TYPE_TO_COL = { @@ -222,9 +223,12 @@ def load_templates(): def _collect_args(impls): args_by_name = {} arg_order = [] + arg_appearances = {} for impl in impls: + seen_in_impl = set() for arg in impl["args"]: name = arg["name"] + seen_in_impl.add(name) if name not in args_by_name: args_by_name[name] = { "types": set(), @@ -232,7 +236,23 @@ def _collect_args(impls): "keyword_only": arg["keyword_only"], } arg_order.append(name) + else: + # If it was marked optional or keyword_only in any previous impl, keep it. + # Or if this impl marks it as optional/keyword_only, update it. + if arg["optional"]: + args_by_name[name]["optional"] = True + if arg["keyword_only"]: + args_by_name[name]["keyword_only"] = True args_by_name[name]["types"].add(arg["value"]) + for name in seen_in_impl: + arg_appearances[name] = arg_appearances.get(name, 0) + 1 + + # If an argument is not in all impls, it must be optional overall + num_impls = len(impls) + for name, count in arg_appearances.items(): + if count < num_impls: + args_by_name[name]["optional"] = True + return args_by_name, arg_order diff --git a/packages/bigframes/scripts/templates/core_series_accessor.py.j2 b/packages/bigframes/scripts/templates/core_series_accessor.py.j2 index 5a64b7590398..ef35d6570cc5 100644 --- a/packages/bigframes/scripts/templates/core_series_accessor.py.j2 +++ b/packages/bigframes/scripts/templates/core_series_accessor.py.j2 @@ -8,6 +8,7 @@ from __future__ import annotations import abc +import datetime from typing import ( Any, Literal, diff --git a/packages/bigframes/tests/unit/bigquery/generated/global_namespace/test_date.py b/packages/bigframes/tests/unit/bigquery/generated/global_namespace/test_date.py new file mode 100644 index 000000000000..6484208584f9 --- /dev/null +++ b/packages/bigframes/tests/unit/bigquery/generated/global_namespace/test_date.py @@ -0,0 +1,340 @@ +# Copyright 2026 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. +# +# DO NOT MODIFY THIS FILE DIRECTLY. +# This file was generated from: scripts/data/sql-functions/global_namespace/date.yaml +# by the script: scripts/generate_bigframes_bigquery.py + +import bigframes.bigquery as bbq +import bigframes.core.col +import bigframes.core.expression as ex +import bigframes.operations.googlesql.global_namespace.date as date_op +import bigframes.pandas as bpd + + +def test_current_date_expression(): + # Call the function with col() expressions + result = bbq.current_date( + bpd.col("time_zone_expression"), + ) + + # Verify result is a col Expression + assert isinstance(result, bigframes.core.col.Expression) + + # Verify the internal expression structure + expr = result._value + assert isinstance(expr, ex.OpExpression) + assert expr.op == date_op._CURRENT_DATE_OP + + # Verify arguments are free variables matching the names + assert len(expr.inputs) == 1 + assert isinstance(expr.inputs[0], ex.UnboundVariableExpression) + assert expr.inputs[0].id == "time_zone_expression" + + +def test_date_expression(): + # Call the function with col() expressions + result = bbq.date( + bpd.col("expression"), + bpd.col("time_zone_expression"), + bpd.col("year"), + bpd.col("month"), + bpd.col("day"), + ) + + # Verify result is a col Expression + assert isinstance(result, bigframes.core.col.Expression) + + # Verify the internal expression structure + expr = result._value + assert isinstance(expr, ex.OpExpression) + assert expr.op == date_op._DATE_OP + + # Verify arguments are free variables matching the names + assert len(expr.inputs) == 5 + assert isinstance(expr.inputs[0], ex.UnboundVariableExpression) + assert expr.inputs[0].id == "expression" + assert isinstance(expr.inputs[1], ex.UnboundVariableExpression) + assert expr.inputs[1].id == "time_zone_expression" + assert isinstance(expr.inputs[2], ex.UnboundVariableExpression) + assert expr.inputs[2].id == "year" + assert isinstance(expr.inputs[3], ex.UnboundVariableExpression) + assert expr.inputs[3].id == "month" + assert isinstance(expr.inputs[4], ex.UnboundVariableExpression) + assert expr.inputs[4].id == "day" + + +def test_date_add_expression(): + # Call the function with col() expressions + result = bbq.date_add( + bpd.col("date_expression"), + bpd.col("int64_expression"), + bpd.col("date_part"), + ) + + # Verify result is a col Expression + assert isinstance(result, bigframes.core.col.Expression) + + # Verify the internal expression structure + expr = result._value + assert isinstance(expr, ex.OpExpression) + assert expr.op == date_op._DATE_ADD_OP + + # Verify arguments are free variables matching the names + assert len(expr.inputs) == 3 + assert isinstance(expr.inputs[0], ex.UnboundVariableExpression) + assert expr.inputs[0].id == "date_expression" + assert isinstance(expr.inputs[1], ex.UnboundVariableExpression) + assert expr.inputs[1].id == "int64_expression" + assert isinstance(expr.inputs[2], ex.UnboundVariableExpression) + assert expr.inputs[2].id == "date_part" + + +def test_date_diff_expression(): + # Call the function with col() expressions + result = bbq.date_diff( + bpd.col("end_date"), + bpd.col("start_date"), + bpd.col("granularity"), + ) + + # Verify result is a col Expression + assert isinstance(result, bigframes.core.col.Expression) + + # Verify the internal expression structure + expr = result._value + assert isinstance(expr, ex.OpExpression) + assert expr.op == date_op._DATE_DIFF_OP + + # Verify arguments are free variables matching the names + assert len(expr.inputs) == 3 + assert isinstance(expr.inputs[0], ex.UnboundVariableExpression) + assert expr.inputs[0].id == "end_date" + assert isinstance(expr.inputs[1], ex.UnboundVariableExpression) + assert expr.inputs[1].id == "start_date" + assert isinstance(expr.inputs[2], ex.UnboundVariableExpression) + assert expr.inputs[2].id == "granularity" + + +def test_date_from_unix_date_expression(): + # Call the function with col() expressions + result = bbq.date_from_unix_date( + bpd.col("int64_expression"), + ) + + # Verify result is a col Expression + assert isinstance(result, bigframes.core.col.Expression) + + # Verify the internal expression structure + expr = result._value + assert isinstance(expr, ex.OpExpression) + assert expr.op == date_op._DATE_FROM_UNIX_DATE_OP + + # Verify arguments are free variables matching the names + assert len(expr.inputs) == 1 + assert isinstance(expr.inputs[0], ex.UnboundVariableExpression) + assert expr.inputs[0].id == "int64_expression" + + +def test_date_sub_expression(): + # Call the function with col() expressions + result = bbq.date_sub( + bpd.col("date_expression"), + bpd.col("int64_expression"), + bpd.col("date_part"), + ) + + # Verify result is a col Expression + assert isinstance(result, bigframes.core.col.Expression) + + # Verify the internal expression structure + expr = result._value + assert isinstance(expr, ex.OpExpression) + assert expr.op == date_op._DATE_SUB_OP + + # Verify arguments are free variables matching the names + assert len(expr.inputs) == 3 + assert isinstance(expr.inputs[0], ex.UnboundVariableExpression) + assert expr.inputs[0].id == "date_expression" + assert isinstance(expr.inputs[1], ex.UnboundVariableExpression) + assert expr.inputs[1].id == "int64_expression" + assert isinstance(expr.inputs[2], ex.UnboundVariableExpression) + assert expr.inputs[2].id == "date_part" + + +def test_date_trunc_expression(): + # Call the function with col() expressions + result = bbq.date_trunc( + bpd.col("date_value"), + bpd.col("granularity"), + ) + + # Verify result is a col Expression + assert isinstance(result, bigframes.core.col.Expression) + + # Verify the internal expression structure + expr = result._value + assert isinstance(expr, ex.OpExpression) + assert expr.op == date_op._DATE_TRUNC_OP + + # Verify arguments are free variables matching the names + assert len(expr.inputs) == 2 + assert isinstance(expr.inputs[0], ex.UnboundVariableExpression) + assert expr.inputs[0].id == "date_value" + assert isinstance(expr.inputs[1], ex.UnboundVariableExpression) + assert expr.inputs[1].id == "granularity" + + +def test_extract_expression(): + # Call the function with col() expressions + result = bbq.extract( + bpd.col("date_expression"), + bpd.col("part"), + bpd.col("time_zone"), + ) + + # Verify result is a col Expression + assert isinstance(result, bigframes.core.col.Expression) + + # Verify the internal expression structure + expr = result._value + assert isinstance(expr, ex.OpExpression) + assert expr.op == date_op._EXTRACT_OP + + # Verify arguments are free variables matching the names + assert len(expr.inputs) == 3 + assert isinstance(expr.inputs[0], ex.UnboundVariableExpression) + assert expr.inputs[0].id == "date_expression" + assert isinstance(expr.inputs[1], ex.UnboundVariableExpression) + assert expr.inputs[1].id == "part" + assert isinstance(expr.inputs[2], ex.UnboundVariableExpression) + assert expr.inputs[2].id == "time_zone" + + +def test_format_date_expression(): + # Call the function with col() expressions + result = bbq.format_date( + bpd.col("format_string"), + bpd.col("date_expr"), + ) + + # Verify result is a col Expression + assert isinstance(result, bigframes.core.col.Expression) + + # Verify the internal expression structure + expr = result._value + assert isinstance(expr, ex.OpExpression) + assert expr.op == date_op._FORMAT_DATE_OP + + # Verify arguments are free variables matching the names + assert len(expr.inputs) == 2 + assert isinstance(expr.inputs[0], ex.UnboundVariableExpression) + assert expr.inputs[0].id == "format_string" + assert isinstance(expr.inputs[1], ex.UnboundVariableExpression) + assert expr.inputs[1].id == "date_expr" + + +def test_generate_date_array_expression(): + # Call the function with col() expressions + result = bbq.generate_date_array( + bpd.col("start_date"), + bpd.col("end_date"), + bpd.col("int64_expression"), + bpd.col("date_part"), + ) + + # Verify result is a col Expression + assert isinstance(result, bigframes.core.col.Expression) + + # Verify the internal expression structure + expr = result._value + assert isinstance(expr, ex.OpExpression) + assert expr.op == date_op._GENERATE_DATE_ARRAY_OP + + # Verify arguments are free variables matching the names + assert len(expr.inputs) == 4 + assert isinstance(expr.inputs[0], ex.UnboundVariableExpression) + assert expr.inputs[0].id == "start_date" + assert isinstance(expr.inputs[1], ex.UnboundVariableExpression) + assert expr.inputs[1].id == "end_date" + assert isinstance(expr.inputs[2], ex.UnboundVariableExpression) + assert expr.inputs[2].id == "int64_expression" + assert isinstance(expr.inputs[3], ex.UnboundVariableExpression) + assert expr.inputs[3].id == "date_part" + + +def test_last_day_expression(): + # Call the function with col() expressions + result = bbq.last_day( + bpd.col("date_expression"), + bpd.col("date_part"), + ) + + # Verify result is a col Expression + assert isinstance(result, bigframes.core.col.Expression) + + # Verify the internal expression structure + expr = result._value + assert isinstance(expr, ex.OpExpression) + assert expr.op == date_op._LAST_DAY_OP + + # Verify arguments are free variables matching the names + assert len(expr.inputs) == 2 + assert isinstance(expr.inputs[0], ex.UnboundVariableExpression) + assert expr.inputs[0].id == "date_expression" + assert isinstance(expr.inputs[1], ex.UnboundVariableExpression) + assert expr.inputs[1].id == "date_part" + + +def test_parse_date_expression(): + # Call the function with col() expressions + result = bbq.parse_date( + bpd.col("format_string"), + bpd.col("date_string"), + ) + + # Verify result is a col Expression + assert isinstance(result, bigframes.core.col.Expression) + + # Verify the internal expression structure + expr = result._value + assert isinstance(expr, ex.OpExpression) + assert expr.op == date_op._PARSE_DATE_OP + + # Verify arguments are free variables matching the names + assert len(expr.inputs) == 2 + assert isinstance(expr.inputs[0], ex.UnboundVariableExpression) + assert expr.inputs[0].id == "format_string" + assert isinstance(expr.inputs[1], ex.UnboundVariableExpression) + assert expr.inputs[1].id == "date_string" + + +def test_unix_date_expression(): + # Call the function with col() expressions + result = bbq.unix_date( + bpd.col("date_expression"), + ) + + # Verify result is a col Expression + assert isinstance(result, bigframes.core.col.Expression) + + # Verify the internal expression structure + expr = result._value + assert isinstance(expr, ex.OpExpression) + assert expr.op == date_op._UNIX_DATE_OP + + # Verify arguments are free variables matching the names + assert len(expr.inputs) == 1 + assert isinstance(expr.inputs[0], ex.UnboundVariableExpression) + assert expr.inputs[0].id == "date_expression" From 03d0574da8485e918f16e90666928f5c7b7f1c92 Mon Sep 17 00:00:00 2001 From: Joe Wang <106995533+JoeWang1127@users.noreply.github.com> Date: Tue, 23 Jun 2026 22:15:39 +0000 Subject: [PATCH 124/174] feat: update googleapis and regenerate (#17554) Update googleapis to the latest commit and regenerate all client libraries. --- librarian.yaml | 4 +- .../google/ads/datamanager/__init__.py | 38 + .../google/ads/datamanager_v1/__init__.py | 40 +- .../ads/datamanager_v1/gapic_metadata.json | 15 + .../ingestion_service/async_client.py | 102 + .../services/ingestion_service/client.py | 100 + .../ingestion_service/transports/base.py | 17 + .../ingestion_service/transports/grpc.py | 32 + .../transports/grpc_asyncio.py | 37 + .../ingestion_service/transports/rest.py | 224 + .../ingestion_service/transports/rest_base.py | 57 + .../partner_link_service/async_client.py | 2 + .../services/partner_link_service/client.py | 2 + .../ads/datamanager_v1/types/__init__.py | 38 + .../ads/datamanager_v1/types/ad_event.py | 613 + .../ads/datamanager_v1/types/destination.py | 2 +- .../datamanager_v1/types/encryption_info.py | 33 + .../google/ads/datamanager_v1/types/error.py | 4 +- .../datamanager_v1/types/ingestion_service.py | 39 +- .../types/partner_link_service.py | 97 + .../datamanager_v1/types/viewability_info.py | 145 + ...ngestion_service_ingest_ad_events_async.py | 70 + ...ingestion_service_ingest_ad_events_sync.py | 70 + ...n_service_ingest_audience_members_async.py | 1 + ...on_service_ingest_audience_members_sync.py | 1 + ...d_ingestion_service_ingest_events_async.py | 1 + ...ed_ingestion_service_ingest_events_sync.py | 1 + ...n_service_remove_audience_members_async.py | 1 + ...on_service_remove_audience_members_sync.py | 1 + ..._link_service_create_partner_link_async.py | 2 + ...r_link_service_create_partner_link_sync.py | 2 + ...et_metadata_google.ads.datamanager.v1.json | 265 +- .../datamanager_v1/test_ingestion_service.py | 494 + .../test_partner_link_service.py | 23 + .../google/analytics/admin/__init__.py | 2 + .../analytics/admin_v1alpha/__init__.py | 2 + .../admin_v1alpha/gapic_metadata.json | 15 + .../analytics_admin_service/async_client.py | 115 + .../analytics_admin_service/client.py | 114 + .../transports/base.py | 17 + .../transports/grpc.py | 33 + .../transports/grpc_asyncio.py | 38 + .../transports/rest.py | 235 + .../transports/rest_base.py | 59 + .../analytics/admin_v1alpha/types/__init__.py | 2 + .../admin_v1alpha/types/analytics_admin.py | 29 + .../admin_v1alpha/types/resources.py | 7 + .../admin_v1beta/types/analytics_admin.py | 116 +- .../analytics/admin_v1beta/types/resources.py | 80 +- .../test_analytics_admin_service.py | 870 + .../google/apps/chat_v1/types/message.py | 13 +- .../cloudbuild_v1/types/cloudbuild.py | 3 + .../cloud/ces_v1beta/types/agent_tool.py | 9 - .../gapic/ces_v1beta/test_agent_service.py | 3 - .../rule_execution_error_service.rst | 10 + .../docs/chronicle_v1/services_.rst | 1 + .../google/cloud/chronicle/__init__.py | 26 + .../google/cloud/chronicle_v1/__init__.py | 24 + .../cloud/chronicle_v1/gapic_metadata.json | 64 + .../reference_list_service/async_client.py | 93 + .../services/reference_list_service/client.py | 111 + .../reference_list_service/transports/base.py | 32 +- .../reference_list_service/transports/grpc.py | 30 + .../transports/grpc_asyncio.py | 44 + .../reference_list_service/transports/rest.py | 226 + .../transports/rest_base.py | 57 + .../rule_execution_error_service/__init__.py | 22 + .../async_client.py | 708 + .../rule_execution_error_service/client.py | 1188 ++ .../rule_execution_error_service/pagers.py | 201 + .../transports/README.rst | 10 + .../transports/__init__.py | 39 + .../transports/base.py | 251 + .../transports/grpc.py | 439 + .../transports/grpc_asyncio.py | 491 + .../transports/rest.py | 1029 ++ .../transports/rest_base.py | 245 + .../services/rule_service/async_client.py | 125 + .../services/rule_service/client.py | 142 + .../services/rule_service/transports/base.py | 29 +- .../services/rule_service/transports/grpc.py | 26 + .../rule_service/transports/grpc_asyncio.py | 40 + .../services/rule_service/transports/rest.py | 217 + .../rule_service/transports/rest_base.py | 57 + .../cloud/chronicle_v1/types/__init__.py | 18 + .../chronicle_v1/types/reference_list.py | 78 + .../google/cloud/chronicle_v1/types/rule.py | 51 + .../types/rule_execution_error.py | 192 + ...ist_service_verify_reference_list_async.py | 58 + ...list_service_verify_reference_list_sync.py | 58 + ...ervice_list_rule_execution_errors_async.py | 54 + ...service_list_rule_execution_errors_sync.py | 54 + ...ted_rule_service_verify_rule_text_async.py | 54 + ...ated_rule_service_verify_rule_text_sync.py | 54 + ...et_metadata_google.cloud.chronicle.v1.json | 483 + .../test_reference_list_service.py | 753 +- .../test_rule_execution_error_service.py | 4317 +++++ .../gapic/chronicle_v1/test_rule_service.py | 914 +- .../google/cloud/dataform/__init__.py | 16 + .../google/cloud/dataform_v1beta1/__init__.py | 16 + .../dataform_v1beta1/gapic_metadata.json | 45 + .../services/dataform/async_client.py | 463 +- .../services/dataform/client.py | 476 +- .../services/dataform/transports/base.py | 42 + .../services/dataform/transports/grpc.py | 86 + .../dataform/transports/grpc_asyncio.py | 106 + .../services/dataform/transports/rest.py | 883 +- .../services/dataform/transports/rest_base.py | 171 + .../cloud/dataform_v1beta1/types/__init__.py | 16 + .../cloud/dataform_v1beta1/types/dataform.py | 392 +- ...ated_dataform_delete_folder_tree_async.py} | 22 +- ...rated_dataform_delete_folder_tree_sync.py} | 22 +- ...rm_delete_repository_long_running_async.py | 57 + ...orm_delete_repository_long_running_sync.py | 57 + ..._dataform_delete_team_folder_tree_async.py | 57 + ...d_dataform_delete_team_folder_tree_sync.py | 57 + ...etadata_google.cloud.dataform.v1beta1.json | 507 + .../gapic/dataform_v1beta1/test_dataform.py | 2395 ++- .../cloud/dataproc_v1/types/clusters.py | 52 +- .../dataproc_v1/test_cluster_controller.py | 12 +- .../test_workflow_template_service.py | 12 +- .../dialogflowcx_v3/types/audio_config.py | 2 +- .../cloud/dialogflowcx_v3/types/session.py | 8 + .../types/audio_config.py | 2 +- .../dialogflowcx_v3beta1/types/session.py | 6 + .../google/cloud/dialogflow/__init__.py | 2 + .../google/cloud/dialogflow_v2/__init__.py | 2 + .../services/participants/async_client.py | 10 +- .../services/participants/client.py | 10 +- .../cloud/dialogflow_v2/types/__init__.py | 2 + .../cloud/dialogflow_v2/types/audio_config.py | 2 +- .../cloud/dialogflow_v2/types/ces_app.py | 26 + .../cloud/dialogflow_v2/types/conversation.py | 6 + .../types/conversation_profile.py | 92 + .../cloud/dialogflow_v2/types/participant.py | 173 +- .../cloud/dialogflow_v2/types/session.py | 25 +- .../cloud/dialogflow_v2beta1/__init__.py | 2 + .../conversation_profiles/async_client.py | 6 - .../services/conversation_profiles/client.py | 22 - .../services/conversations/async_client.py | 4 - .../services/conversations/client.py | 22 - .../services/participants/async_client.py | 10 +- .../services/participants/client.py | 10 +- .../dialogflow_v2beta1/types/__init__.py | 2 + .../dialogflow_v2beta1/types/audio_config.py | 2 +- .../cloud/dialogflow_v2beta1/types/ces_app.py | 26 + .../dialogflow_v2beta1/types/conversation.py | 6 + .../types/conversation_profile.py | 136 +- .../dialogflow_v2beta1/types/participant.py | 278 +- .../cloud/dialogflow_v2beta1/types/session.py | 25 +- .../test_conversation_profiles.py | 28 + .../gapic/dialogflow_v2/test_conversations.py | 14 + .../test_generator_evaluations.py | 7 +- .../gapic/dialogflow_v2/test_generators.py | 18 +- .../test_conversation_profiles.py | 152 +- .../dialogflow_v2beta1/test_conversations.py | 190 +- .../test_generator_evaluations.py | 7 +- .../dialogflow_v2beta1/test_generators.py | 18 +- .../acl_config_service.rst | 6 + .../assistant_service.rst | 10 + .../cmek_config_service.rst | 6 + .../identity_mapping_store_service.rst | 10 + .../license_config_service.rst | 10 + .../docs/discoveryengine_v1beta/services_.rst | 7 + .../user_license_service.rst | 10 + .../user_store_service.rst | 6 + .../google/cloud/discoveryengine/__init__.py | 241 +- .../cloud/discoveryengine_v1beta/__init__.py | 210 +- .../gapic_metadata.json | 673 + .../services/acl_config_service/__init__.py | 22 + .../acl_config_service/async_client.py | 702 + .../services/acl_config_service/client.py | 1143 ++ .../acl_config_service/transports/README.rst | 10 + .../acl_config_service/transports/__init__.py | 36 + .../acl_config_service/transports/base.py | 240 + .../acl_config_service/transports/grpc.py | 447 + .../transports/grpc_asyncio.py | 494 + .../acl_config_service/transports/rest.py | 1081 ++ .../transports/rest_base.py | 407 + .../services/assistant_service/__init__.py | 22 + .../assistant_service/async_client.py | 1194 ++ .../services/assistant_service/client.py | 1762 ++ .../services/assistant_service/pagers.py | 197 + .../assistant_service/transports/README.rst | 10 + .../assistant_service/transports/__init__.py | 36 + .../assistant_service/transports/base.py | 314 + .../assistant_service/transports/grpc.py | 561 + .../transports/grpc_asyncio.py | 642 + .../assistant_service/transports/rest.py | 1875 ++ .../assistant_service/transports/rest_base.py | 619 + .../services/cmek_config_service/__init__.py | 22 + .../cmek_config_service/async_client.py | 1028 ++ .../services/cmek_config_service/client.py | 1515 ++ .../cmek_config_service/transports/README.rst | 10 + .../transports/__init__.py | 36 + .../cmek_config_service/transports/base.py | 278 + .../cmek_config_service/transports/grpc.py | 528 + .../transports/grpc_asyncio.py | 584 + .../cmek_config_service/transports/rest.py | 1702 ++ .../transports/rest_base.py | 510 + .../completion_service/async_client.py | 98 + .../services/completion_service/client.py | 96 + .../completion_service/transports/base.py | 25 +- .../completion_service/transports/grpc.py | 33 + .../transports/grpc_asyncio.py | 38 + .../completion_service/transports/rest.py | 241 + .../transports/rest_base.py | 69 + .../services/control_service/async_client.py | 10 +- .../services/control_service/client.py | 34 +- .../control_service/transports/base.py | 6 +- .../control_service/transports/rest_base.py | 12 + .../async_client.py | 112 + .../conversational_search_service/client.py | 131 + .../transports/base.py | 23 +- .../transports/grpc.py | 35 + .../transports/grpc_asyncio.py | 40 + .../transports/rest.py | 221 + .../transports/rest_base.py | 79 + .../data_store_service/async_client.py | 18 + .../services/data_store_service/client.py | 93 + .../data_store_service/transports/base.py | 6 +- .../data_store_service/transports/rest.py | 12 + .../transports/rest_base.py | 12 + .../services/document_service/async_client.py | 2 +- .../services/document_service/client.py | 2 +- .../document_service/transports/base.py | 6 +- .../document_service/transports/rest.py | 12 + .../document_service/transports/rest_base.py | 12 + .../services/engine_service/async_client.py | 339 +- .../services/engine_service/client.py | 418 +- .../engine_service/transports/base.py | 36 +- .../engine_service/transports/grpc.py | 88 +- .../engine_service/transports/grpc_asyncio.py | 98 +- .../engine_service/transports/rest.py | 582 + .../engine_service/transports/rest_base.py | 118 + .../evaluation_service/async_client.py | 8 +- .../services/evaluation_service/client.py | 8 +- .../evaluation_service/transports/base.py | 7 +- .../evaluation_service/transports/rest.py | 12 + .../transports/rest_base.py | 12 + .../transports/base.py | 6 +- .../transports/rest_base.py | 12 + .../__init__.py | 22 + .../async_client.py | 1418 ++ .../identity_mapping_store_service/client.py | 1917 ++ .../identity_mapping_store_service/pagers.py | 383 + .../transports/README.rst | 10 + .../transports/__init__.py | 39 + .../transports/base.py | 333 + .../transports/grpc.py | 627 + .../transports/grpc_asyncio.py | 697 + .../transports/rest.py | 2431 +++ .../transports/rest_base.py | 694 + .../license_config_service/__init__.py | 22 + .../license_config_service/async_client.py | 1405 ++ .../services/license_config_service/client.py | 1863 ++ .../services/license_config_service/pagers.py | 204 + .../transports/README.rst | 10 + .../transports/__init__.py | 36 + .../license_config_service/transports/base.py | 317 + .../license_config_service/transports/grpc.py | 582 + .../transports/grpc_asyncio.py | 646 + .../license_config_service/transports/rest.py | 2024 +++ .../transports/rest_base.py | 633 + .../services/project_service/async_client.py | 6 + .../services/project_service/client.py | 44 + .../project_service/transports/base.py | 6 +- .../project_service/transports/rest.py | 12 + .../project_service/transports/rest_base.py | 12 + .../services/rank_service/transports/base.py | 6 +- .../rank_service/transports/rest_base.py | 12 + .../recommendation_service/transports/base.py | 6 +- .../transports/rest_base.py | 12 + .../sample_query_service/transports/base.py | 6 +- .../sample_query_service/transports/rest.py | 12 + .../transports/rest_base.py | 12 + .../transports/base.py | 6 +- .../transports/rest_base.py | 12 + .../schema_service/transports/base.py | 6 +- .../schema_service/transports/rest.py | 12 + .../schema_service/transports/rest_base.py | 12 + .../search_service/transports/base.py | 7 +- .../search_service/transports/rest_base.py | 12 + .../search_tuning_service/transports/base.py | 6 +- .../search_tuning_service/transports/rest.py | 12 + .../transports/rest_base.py | 12 + .../serving_config_service/async_client.py | 264 +- .../services/serving_config_service/client.py | 258 +- .../serving_config_service/transports/base.py | 38 +- .../serving_config_service/transports/grpc.py | 68 + .../transports/grpc_asyncio.py | 80 + .../serving_config_service/transports/rest.py | 370 + .../transports/rest_base.py | 137 + .../services/session_service/async_client.py | 4 + .../services/session_service/client.py | 28 + .../session_service/transports/base.py | 7 +- .../session_service/transports/rest_base.py | 12 + .../transports/base.py | 6 +- .../transports/rest.py | 12 + .../transports/rest_base.py | 16 + .../user_event_service/async_client.py | 1 + .../services/user_event_service/client.py | 1 + .../user_event_service/transports/base.py | 7 +- .../user_event_service/transports/rest.py | 12 + .../transports/rest_base.py | 17 + .../services/user_license_service/__init__.py | 22 + .../user_license_service/async_client.py | 862 + .../services/user_license_service/client.py | 1323 ++ .../services/user_license_service/pagers.py | 199 + .../transports/README.rst | 10 + .../transports/__init__.py | 36 + .../user_license_service/transports/base.py | 265 + .../user_license_service/transports/grpc.py | 503 + .../transports/grpc_asyncio.py | 552 + .../user_license_service/transports/rest.py | 1507 ++ .../transports/rest_base.py | 456 + .../services/user_store_service/__init__.py | 22 + .../user_store_service/async_client.py | 734 + .../services/user_store_service/client.py | 1195 ++ .../user_store_service/transports/README.rst | 10 + .../user_store_service/transports/__init__.py | 36 + .../user_store_service/transports/base.py | 241 + .../user_store_service/transports/grpc.py | 446 + .../transports/grpc_asyncio.py | 491 + .../user_store_service/transports/rest.py | 1089 ++ .../transports/rest_base.py | 408 + .../discoveryengine_v1beta/types/__init__.py | 196 + .../types/acl_config.py | 58 + .../types/acl_config_service.py | 69 + .../types/agent_gateway_setting.py | 67 + .../discoveryengine_v1beta/types/answer.py | 207 +- .../types/assist_answer.py | 730 + .../discoveryengine_v1beta/types/assistant.py | 391 + .../types/assistant_service.py | 563 + .../discoveryengine_v1beta/types/chunk.py | 99 +- .../types/cmek_config_service.py | 344 + .../discoveryengine_v1beta/types/common.py | 348 + .../types/completion_service.py | 216 +- .../discoveryengine_v1beta/types/control.py | 193 +- .../types/conversational_search_service.py | 291 +- .../types/data_store.py | 387 +- .../types/data_store_service.py | 29 + .../discoveryengine_v1beta/types/document.py | 115 +- .../types/document_processing_config.py | 65 +- .../types/document_service.py | 2 +- .../discoveryengine_v1beta/types/engine.py | 570 +- .../types/evaluation.py | 4 +- .../types/evaluation_service.py | 25 +- .../discoveryengine_v1beta/types/feedback.py | 227 + .../types/grounded_generation_service.py | 350 +- .../discoveryengine_v1beta/types/grounding.py | 18 + .../types/identity_mapping_store.py | 128 + .../types/identity_mapping_store_service.py | 488 + .../types/import_config.py | 40 +- .../types/license_config.py | 166 + .../types/license_config_service.py | 348 + .../discoveryengine_v1beta/types/logging.py | 53 + .../discoveryengine_v1beta/types/project.py | 350 + .../types/project_service.py | 30 + .../types/purge_config.py | 13 +- .../types/rank_service.py | 10 +- .../types/recommendation_service.py | 4 +- .../discoveryengine_v1beta/types/safety.py | 152 + .../types/search_service.py | 782 +- .../types/serving_config.py | 101 +- .../types/serving_config_service.py | 51 + .../discoveryengine_v1beta/types/session.py | 36 + .../types/site_search_engine.py | 9 +- .../types/site_search_engine_service.py | 19 +- .../types/user_event.py | 65 +- .../types/user_event_service.py | 17 +- .../types/user_license.py | 152 + .../types/user_license_service.py | 329 + .../types/user_store.py | 94 + .../types/user_store_service.py | 75 + ...cl_config_service_get_acl_config_async.py} | 18 +- ..._acl_config_service_get_acl_config_sync.py | 53 + ..._config_service_update_acl_config_async.py | 51 + ...l_config_service_update_acl_config_sync.py | 51 + ...ssistant_service_create_assistant_async.py | 58 + ...assistant_service_create_assistant_sync.py | 58 + ...ssistant_service_delete_assistant_async.py | 50 + ...assistant_service_delete_assistant_sync.py | 50 + ...d_assistant_service_get_assistant_async.py | 53 + ...ed_assistant_service_get_assistant_sync.py | 53 + ...assistant_service_list_assistants_async.py | 54 + ..._assistant_service_list_assistants_sync.py | 54 + ...d_assistant_service_stream_assist_async.py | 54 + ...ed_assistant_service_stream_assist_sync.py | 54 + ...ssistant_service_update_assistant_async.py | 56 + ...assistant_service_update_assistant_sync.py | 56 + ...onfig_service_delete_cmek_config_async.py} | 22 +- ...config_service_delete_cmek_config_sync.py} | 22 +- ...ek_config_service_get_cmek_config_async.py | 53 + ...mek_config_service_get_cmek_config_sync.py | 53 + ..._config_service_list_cmek_configs_async.py | 53 + ...k_config_service_list_cmek_configs_sync.py | 53 + ...config_service_update_cmek_config_async.py | 61 + ..._config_service_update_cmek_config_sync.py | 61 + ...pletion_service_remove_suggestion_async.py | 55 + ...mpletion_service_remove_suggestion_sync.py | 55 + ...ed_control_service_create_control_async.py | 4 +- ...ted_control_service_create_control_sync.py | 4 +- ...ed_control_service_update_control_async.py | 4 +- ...ted_control_service_update_control_sync.py | 4 +- ...earch_service_stream_answer_query_async.py | 58 + ...search_service_stream_answer_query_sync.py | 58 + ...a_store_service_create_data_store_async.py | 1 + ...ta_store_service_create_data_store_sync.py | 1 + ...ated_engine_service_create_engine_async.py | 2 +- ...rated_engine_service_create_engine_sync.py | 2 +- ...ted_engine_service_get_iam_policy_async.py | 55 + ...ated_engine_service_get_iam_policy_sync.py | 55 + ...ted_engine_service_set_iam_policy_async.py | 55 + ...ated_engine_service_set_iam_policy_sync.py | 55 + ...ated_engine_service_update_engine_async.py | 2 +- ...rated_engine_service_update_engine_sync.py | 2 +- ...luation_service_create_evaluation_async.py | 3 - ...aluation_service_create_evaluation_sync.py | 3 - ...ice_create_identity_mapping_store_async.py | 55 + ...vice_create_identity_mapping_store_sync.py | 55 + ...ice_delete_identity_mapping_store_async.py | 57 + ...vice_delete_identity_mapping_store_sync.py | 57 + ...ervice_get_identity_mapping_store_async.py | 53 + ...service_get_identity_mapping_store_sync.py | 53 + ..._service_import_identity_mappings_async.py | 57 + ...e_service_import_identity_mappings_sync.py | 57 + ...vice_list_identity_mapping_stores_async.py | 54 + ...vice_list_identity_mapping_stores_sync.py} | 23 +- ...re_service_list_identity_mappings_async.py | 54 + ...ore_service_list_identity_mappings_sync.py | 54 + ...e_service_purge_identity_mappings_async.py | 57 + ...re_service_purge_identity_mappings_sync.py | 57 + ...fig_service_create_license_config_async.py | 59 + ...nfig_service_create_license_config_sync.py | 59 + ...service_distribute_license_config_async.py | 56 + ..._service_distribute_license_config_sync.py | 56 + ...config_service_get_license_config_async.py | 53 + ..._config_service_get_license_config_sync.py | 53 + ...nfig_service_list_license_configs_async.py | 54 + ...onfig_service_list_license_configs_sync.py | 54 + ...ig_service_retract_license_config_async.py | 54 + ...fig_service_retract_license_config_sync.py | 54 + ...fig_service_update_license_config_async.py | 58 + ...nfig_service_update_license_config_sync.py | 58 + ...fig_service_create_serving_config_async.py | 60 + ...nfig_service_create_serving_config_sync.py | 60 + ...fig_service_delete_serving_config_async.py | 50 + ...nfig_service_delete_serving_config_sync.py | 50 + ...fig_service_update_serving_config_async.py | 2 +- ...nfig_service_update_serving_config_sync.py | 2 +- ...ervice_batch_update_user_licenses_async.py | 61 + ...service_batch_update_user_licenses_sync.py | 61 + ..._list_license_configs_usage_stats_async.py | 53 + ...e_list_license_configs_usage_stats_sync.py | 53 + ...icense_service_list_user_licenses_async.py | 54 + ...license_service_list_user_licenses_sync.py | 54 + ...user_store_service_get_user_store_async.py | 53 + ..._user_store_service_get_user_store_sync.py | 53 + ...r_store_service_update_user_store_async.py | 51 + ...er_store_service_update_user_store_sync.py | 51 + ...a_google.cloud.discoveryengine.v1beta.json | 14440 ++++++++++----- .../google-cloud-discoveryengine/setup.py | 1 + .../testing/constraints-3.10.txt | 1 + .../testing/constraints-3.11.txt | 1 + .../testing/constraints-3.12.txt | 1 + .../testing/constraints-3.13.txt | 1 + .../testing/constraints-3.14.txt | 1 + .../test_acl_config_service.py | 4265 +++++ .../test_assistant_service.py | 7679 ++++++++ .../test_cmek_config_service.py | 6071 +++++++ .../test_completion_service.py | 640 +- .../test_control_service.py | 160 +- .../test_conversational_search_service.py | 1099 +- .../test_data_store_service.py | 453 +- .../test_document_service.py | 61 +- .../test_engine_service.py | 4375 +++-- .../test_evaluation_service.py | 77 +- .../test_grounded_generation_service.py | 30 +- .../test_identity_mapping_store_service.py | 8759 +++++++++ .../test_license_config_service.py | 8290 +++++++++ .../test_project_service.py | 88 +- .../test_rank_service.py | 30 +- .../test_recommendation_service.py | 33 +- .../test_sample_query_service.py | 30 +- .../test_sample_query_set_service.py | 30 +- .../test_schema_service.py | 30 +- .../test_search_service.py | 80 +- .../test_search_tuning_service.py | 30 +- .../test_serving_config_service.py | 3990 +++-- .../test_session_service.py | 433 +- .../test_site_search_engine_service.py | 30 +- .../test_user_event_service.py | 81 +- .../test_user_license_service.py | 5384 ++++++ .../test_user_store_service.py | 4514 +++++ .../cloud/network_management/__init__.py | 4 + .../cloud/network_management_v1/__init__.py | 4 + .../network_management_v1/types/__init__.py | 4 + .../types/connectivity_test.py | 18 + .../network_management_v1/types/trace.py | 94 + .../test_reachability_service.py | 16 + .../types/security_profile_group.py | 3 +- .../types/agent_gateway.py | 2 +- .../google/cloud/oracledatabase/__init__.py | 12 +- .../cloud/oracledatabase_v1/__init__.py | 12 +- .../oracledatabase_v1/gapic_metadata.json | 75 +- .../services/oracle_database/async_client.py | 804 +- .../services/oracle_database/client.py | 799 +- .../oracle_database/transports/base.py | 84 +- .../oracle_database/transports/grpc.py | 160 +- .../transports/grpc_asyncio.py | 185 +- .../oracle_database/transports/rest.py | 1519 +- .../oracle_database/transports/rest_base.py | 263 +- .../cloud/oracledatabase_v1/types/__init__.py | 12 +- .../oracledatabase_v1/types/exadata_infra.py | 63 + .../types/exascale_db_storage_vault.py | 9 + .../types/goldengate_connection_type.py | 16 - .../goldengate_deployment_environment.py | 16 - .../types/goldengate_deployment_type.py | 17 - .../types/goldengate_deployment_version.py | 17 - .../oracledatabase_v1/types/vm_cluster.py | 32 + ...ale_cloud_exadata_infrastructure_async.py} | 19 +- ...cale_cloud_exadata_infrastructure_sync.py} | 17 +- ...tadata_google.cloud.oracledatabase.v1.json | 839 +- .../oracledatabase_v1/test_oracle_database.py | 14764 +++++++--------- .../types/data_object_search_service.py | 7 +- .../types/vectorsearch_service.py | 79 + .../types/data_object_search_service.py | 7 +- .../types/vectorsearch_service.py | 79 + .../test_vector_search_service.py | 17 +- .../test_vector_search_service.py | 17 +- 531 files changed, 159517 insertions(+), 20194 deletions(-) create mode 100644 packages/google-ads-datamanager/google/ads/datamanager_v1/types/ad_event.py create mode 100644 packages/google-ads-datamanager/google/ads/datamanager_v1/types/viewability_info.py create mode 100644 packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_ingest_ad_events_async.py create mode 100644 packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_ingest_ad_events_sync.py create mode 100644 packages/google-cloud-chronicle/docs/chronicle_v1/rule_execution_error_service.rst create mode 100644 packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/__init__.py create mode 100644 packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/async_client.py create mode 100644 packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/client.py create mode 100644 packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/pagers.py create mode 100644 packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/transports/README.rst create mode 100644 packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/transports/__init__.py create mode 100644 packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/transports/base.py create mode 100644 packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/transports/grpc.py create mode 100644 packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/transports/grpc_asyncio.py create mode 100644 packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/transports/rest.py create mode 100644 packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/transports/rest_base.py create mode 100644 packages/google-cloud-chronicle/google/cloud/chronicle_v1/types/rule_execution_error.py create mode 100644 packages/google-cloud-chronicle/samples/generated_samples/chronicle_v1_generated_reference_list_service_verify_reference_list_async.py create mode 100644 packages/google-cloud-chronicle/samples/generated_samples/chronicle_v1_generated_reference_list_service_verify_reference_list_sync.py create mode 100644 packages/google-cloud-chronicle/samples/generated_samples/chronicle_v1_generated_rule_execution_error_service_list_rule_execution_errors_async.py create mode 100644 packages/google-cloud-chronicle/samples/generated_samples/chronicle_v1_generated_rule_execution_error_service_list_rule_execution_errors_sync.py create mode 100644 packages/google-cloud-chronicle/samples/generated_samples/chronicle_v1_generated_rule_service_verify_rule_text_async.py create mode 100644 packages/google-cloud-chronicle/samples/generated_samples/chronicle_v1_generated_rule_service_verify_rule_text_sync.py create mode 100644 packages/google-cloud-chronicle/tests/unit/gapic/chronicle_v1/test_rule_execution_error_service.py rename packages/{google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_type_async.py => google-cloud-dataform/samples/generated_samples/dataform_v1beta1_generated_dataform_delete_folder_tree_async.py} (71%) rename packages/{google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_connection_type_sync.py => google-cloud-dataform/samples/generated_samples/dataform_v1beta1_generated_dataform_delete_folder_tree_sync.py} (72%) create mode 100644 packages/google-cloud-dataform/samples/generated_samples/dataform_v1beta1_generated_dataform_delete_repository_long_running_async.py create mode 100644 packages/google-cloud-dataform/samples/generated_samples/dataform_v1beta1_generated_dataform_delete_repository_long_running_sync.py create mode 100644 packages/google-cloud-dataform/samples/generated_samples/dataform_v1beta1_generated_dataform_delete_team_folder_tree_async.py create mode 100644 packages/google-cloud-dataform/samples/generated_samples/dataform_v1beta1_generated_dataform_delete_team_folder_tree_sync.py create mode 100644 packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/acl_config_service.rst create mode 100644 packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/assistant_service.rst create mode 100644 packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/cmek_config_service.rst create mode 100644 packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/identity_mapping_store_service.rst create mode 100644 packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/license_config_service.rst create mode 100644 packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/user_license_service.rst create mode 100644 packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/user_store_service.rst create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/__init__.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/async_client.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/client.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/transports/README.rst create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/transports/__init__.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/transports/base.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/transports/grpc.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/transports/grpc_asyncio.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/transports/rest.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/transports/rest_base.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/assistant_service/__init__.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/assistant_service/async_client.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/assistant_service/client.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/assistant_service/pagers.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/assistant_service/transports/README.rst create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/assistant_service/transports/__init__.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/assistant_service/transports/base.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/assistant_service/transports/grpc.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/assistant_service/transports/grpc_asyncio.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/assistant_service/transports/rest.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/assistant_service/transports/rest_base.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/cmek_config_service/__init__.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/cmek_config_service/async_client.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/cmek_config_service/client.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/cmek_config_service/transports/README.rst create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/cmek_config_service/transports/__init__.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/cmek_config_service/transports/base.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/cmek_config_service/transports/grpc.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/cmek_config_service/transports/grpc_asyncio.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/cmek_config_service/transports/rest.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/cmek_config_service/transports/rest_base.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/identity_mapping_store_service/__init__.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/identity_mapping_store_service/async_client.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/identity_mapping_store_service/client.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/identity_mapping_store_service/pagers.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/identity_mapping_store_service/transports/README.rst create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/identity_mapping_store_service/transports/__init__.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/identity_mapping_store_service/transports/base.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/identity_mapping_store_service/transports/grpc.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/identity_mapping_store_service/transports/grpc_asyncio.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/identity_mapping_store_service/transports/rest.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/identity_mapping_store_service/transports/rest_base.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/license_config_service/__init__.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/license_config_service/async_client.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/license_config_service/client.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/license_config_service/pagers.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/license_config_service/transports/README.rst create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/license_config_service/transports/__init__.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/license_config_service/transports/base.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/license_config_service/transports/grpc.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/license_config_service/transports/grpc_asyncio.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/license_config_service/transports/rest.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/license_config_service/transports/rest_base.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/user_license_service/__init__.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/user_license_service/async_client.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/user_license_service/client.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/user_license_service/pagers.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/user_license_service/transports/README.rst create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/user_license_service/transports/__init__.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/user_license_service/transports/base.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/user_license_service/transports/grpc.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/user_license_service/transports/grpc_asyncio.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/user_license_service/transports/rest.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/user_license_service/transports/rest_base.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/user_store_service/__init__.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/user_store_service/async_client.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/user_store_service/client.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/user_store_service/transports/README.rst create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/user_store_service/transports/__init__.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/user_store_service/transports/base.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/user_store_service/transports/grpc.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/user_store_service/transports/grpc_asyncio.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/user_store_service/transports/rest.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/user_store_service/transports/rest_base.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/types/acl_config.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/types/acl_config_service.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/types/agent_gateway_setting.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/types/assist_answer.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/types/assistant.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/types/assistant_service.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/types/cmek_config_service.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/types/feedback.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/types/identity_mapping_store.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/types/identity_mapping_store_service.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/types/license_config.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/types/license_config_service.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/types/logging.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/types/safety.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/types/user_license.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/types/user_license_service.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/types/user_store.py create mode 100644 packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/types/user_store_service.py rename packages/{google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_type_sync.py => google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_acl_config_service_get_acl_config_async.py} (72%) create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_acl_config_service_get_acl_config_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_acl_config_service_update_acl_config_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_acl_config_service_update_acl_config_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_assistant_service_create_assistant_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_assistant_service_create_assistant_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_assistant_service_delete_assistant_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_assistant_service_delete_assistant_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_assistant_service_get_assistant_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_assistant_service_get_assistant_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_assistant_service_list_assistants_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_assistant_service_list_assistants_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_assistant_service_stream_assist_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_assistant_service_stream_assist_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_assistant_service_update_assistant_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_assistant_service_update_assistant_sync.py rename packages/{google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_environment_async.py => google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_cmek_config_service_delete_cmek_config_async.py} (69%) rename packages/{google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_environment_sync.py => google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_cmek_config_service_delete_cmek_config_sync.py} (70%) create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_cmek_config_service_get_cmek_config_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_cmek_config_service_get_cmek_config_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_cmek_config_service_list_cmek_configs_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_cmek_config_service_list_cmek_configs_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_cmek_config_service_update_cmek_config_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_cmek_config_service_update_cmek_config_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_completion_service_remove_suggestion_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_completion_service_remove_suggestion_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_conversational_search_service_stream_answer_query_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_conversational_search_service_stream_answer_query_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_engine_service_get_iam_policy_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_engine_service_get_iam_policy_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_engine_service_set_iam_policy_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_engine_service_set_iam_policy_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_identity_mapping_store_service_create_identity_mapping_store_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_identity_mapping_store_service_create_identity_mapping_store_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_identity_mapping_store_service_delete_identity_mapping_store_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_identity_mapping_store_service_delete_identity_mapping_store_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_identity_mapping_store_service_get_identity_mapping_store_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_identity_mapping_store_service_get_identity_mapping_store_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_identity_mapping_store_service_import_identity_mappings_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_identity_mapping_store_service_import_identity_mappings_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_identity_mapping_store_service_list_identity_mapping_stores_async.py rename packages/{google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_version_async.py => google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_identity_mapping_store_service_list_identity_mapping_stores_sync.py} (66%) create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_identity_mapping_store_service_list_identity_mappings_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_identity_mapping_store_service_list_identity_mappings_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_identity_mapping_store_service_purge_identity_mappings_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_identity_mapping_store_service_purge_identity_mappings_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_license_config_service_create_license_config_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_license_config_service_create_license_config_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_license_config_service_distribute_license_config_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_license_config_service_distribute_license_config_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_license_config_service_get_license_config_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_license_config_service_get_license_config_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_license_config_service_list_license_configs_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_license_config_service_list_license_configs_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_license_config_service_retract_license_config_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_license_config_service_retract_license_config_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_license_config_service_update_license_config_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_license_config_service_update_license_config_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_serving_config_service_create_serving_config_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_serving_config_service_create_serving_config_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_serving_config_service_delete_serving_config_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_serving_config_service_delete_serving_config_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_user_license_service_batch_update_user_licenses_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_user_license_service_batch_update_user_licenses_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_user_license_service_list_license_configs_usage_stats_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_user_license_service_list_license_configs_usage_stats_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_user_license_service_list_user_licenses_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_user_license_service_list_user_licenses_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_user_store_service_get_user_store_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_user_store_service_get_user_store_sync.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_user_store_service_update_user_store_async.py create mode 100644 packages/google-cloud-discoveryengine/samples/generated_samples/discoveryengine_v1beta_generated_user_store_service_update_user_store_sync.py create mode 100644 packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_acl_config_service.py create mode 100644 packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_assistant_service.py create mode 100644 packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_cmek_config_service.py create mode 100644 packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_identity_mapping_store_service.py create mode 100644 packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_license_config_service.py create mode 100644 packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_user_license_service.py create mode 100644 packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_user_store_service.py rename packages/google-cloud-oracledatabase/samples/generated_samples/{oracledatabase_v1_generated_oracle_database_get_goldengate_connection_type_async.py => oracledatabase_v1_generated_oracle_database_configure_exascale_cloud_exadata_infrastructure_async.py} (70%) rename packages/google-cloud-oracledatabase/samples/generated_samples/{oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_version_sync.py => oracledatabase_v1_generated_oracle_database_configure_exascale_cloud_exadata_infrastructure_sync.py} (71%) diff --git a/librarian.yaml b/librarian.yaml index 2f3a4a2cc90a..eb38359a0aa8 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -16,8 +16,8 @@ version: v0.22.0 repo: googleapis/google-cloud-python sources: googleapis: - commit: f93e046328794785ad89869f00c0358dfcff2c35 - sha256: 415249f584d57e5a2298c36ae9ff71563403112dee04ac961023a1b0098404d2 + commit: e57bae6efbd075a925978a79bb9b997beb4ecc19 + sha256: 762523e55a4cd9f57c7e5a952dd76ca6041c0e1dd405c14b1d6cfb165e4730b1 default: output: packages tag_format: '{name}-v{version}' diff --git a/packages/google-ads-datamanager/google/ads/datamanager/__init__.py b/packages/google-ads-datamanager/google/ads/datamanager/__init__.py index 4c2ea0af79c2..a88f6c4f0ad2 100644 --- a/packages/google-ads-datamanager/google/ads/datamanager/__init__.py +++ b/packages/google-ads-datamanager/google/ads/datamanager/__init__.py @@ -54,6 +54,16 @@ from google.ads.datamanager_v1.services.user_list_service.client import ( UserListServiceClient, ) +from google.ads.datamanager_v1.types.ad_event import ( + AdEvent, + AdFormat, + AdPlacement, + AdType, + AttributionHint, + Platform, + PlatformType, + TargetingType, +) from google.ads.datamanager_v1.types.age_range import AgeRange from google.ads.datamanager_v1.types.audience import ( AudienceMember, @@ -75,6 +85,7 @@ from google.ads.datamanager_v1.types.encrypted_user_id import EncryptedUserId from google.ads.datamanager_v1.types.encryption_info import ( AwsWrappedKeyInfo, + CoordinatorKeyInfo, EncryptionInfo, GcpWrappedKeyInfo, ) @@ -91,6 +102,8 @@ from google.ads.datamanager_v1.types.gender import Gender from google.ads.datamanager_v1.types.ingestion_service import ( Encoding, + IngestAdEventsRequest, + IngestAdEventsResponse, IngestAudienceMembersRequest, IngestAudienceMembersResponse, IngestEventsRequest, @@ -110,7 +123,10 @@ from google.ads.datamanager_v1.types.partner_link_service import ( CreatePartnerLinkRequest, DeletePartnerLinkRequest, + FeatureSet, + PartnerCustomerAccount, PartnerLink, + PartnerLinkMetadata, SearchPartnerLinksRequest, SearchPartnerLinksResponse, ) @@ -199,6 +215,11 @@ UserProperties, UserProperty, ) +from google.ads.datamanager_v1.types.viewability_info import ( + MediaQuartile, + ViewabilityInfo, + ViewType, +) __all__ = ( "IngestionServiceClient", @@ -213,6 +234,14 @@ "UserListGlobalLicenseServiceAsyncClient", "UserListServiceClient", "UserListServiceAsyncClient", + "AdEvent", + "AdFormat", + "AdPlacement", + "AdType", + "AttributionHint", + "Platform", + "PlatformType", + "TargetingType", "AgeRange", "AudienceMember", "CompositeData", @@ -232,6 +261,7 @@ "DeviceInfo", "EncryptedUserId", "AwsWrappedKeyInfo", + "CoordinatorKeyInfo", "EncryptionInfo", "GcpWrappedKeyInfo", "ErrorReason", @@ -243,6 +273,8 @@ "EventSource", "ExperimentalField", "Gender", + "IngestAdEventsRequest", + "IngestAdEventsResponse", "IngestAudienceMembersRequest", "IngestAudienceMembersResponse", "IngestEventsRequest", @@ -259,9 +291,12 @@ "MatchRateRange", "CreatePartnerLinkRequest", "DeletePartnerLinkRequest", + "PartnerCustomerAccount", "PartnerLink", + "PartnerLinkMetadata", "SearchPartnerLinksRequest", "SearchPartnerLinksResponse", + "FeatureSet", "ErrorCount", "ErrorInfo", "WarningCount", @@ -315,4 +350,7 @@ "UserProperty", "CustomerType", "CustomerValueBucket", + "ViewabilityInfo", + "MediaQuartile", + "ViewType", ) diff --git a/packages/google-ads-datamanager/google/ads/datamanager_v1/__init__.py b/packages/google-ads-datamanager/google/ads/datamanager_v1/__init__.py index 090ecb7224b2..f09a49051ab0 100644 --- a/packages/google-ads-datamanager/google/ads/datamanager_v1/__init__.py +++ b/packages/google-ads-datamanager/google/ads/datamanager_v1/__init__.py @@ -47,6 +47,16 @@ UserListServiceAsyncClient, UserListServiceClient, ) +from .types.ad_event import ( + AdEvent, + AdFormat, + AdPlacement, + AdType, + AttributionHint, + Platform, + PlatformType, + TargetingType, +) from .types.age_range import AgeRange from .types.audience import ( AudienceMember, @@ -62,7 +72,12 @@ from .types.destination import Destination, Product, ProductAccount from .types.device_info import DeviceInfo from .types.encrypted_user_id import EncryptedUserId -from .types.encryption_info import AwsWrappedKeyInfo, EncryptionInfo, GcpWrappedKeyInfo +from .types.encryption_info import ( + AwsWrappedKeyInfo, + CoordinatorKeyInfo, + EncryptionInfo, + GcpWrappedKeyInfo, +) from .types.error import ErrorReason from .types.event import ( AdIdentifiers, @@ -76,6 +91,8 @@ from .types.gender import Gender from .types.ingestion_service import ( Encoding, + IngestAdEventsRequest, + IngestAdEventsResponse, IngestAudienceMembersRequest, IngestAudienceMembersResponse, IngestEventsRequest, @@ -95,7 +112,10 @@ from .types.partner_link_service import ( CreatePartnerLinkRequest, DeletePartnerLinkRequest, + FeatureSet, + PartnerCustomerAccount, PartnerLink, + PartnerLinkMetadata, SearchPartnerLinksRequest, SearchPartnerLinksResponse, ) @@ -165,6 +185,7 @@ UserProperties, UserProperty, ) +from .types.viewability_info import MediaQuartile, ViewabilityInfo, ViewType if hasattr(api_core, "check_python_version") and hasattr( api_core, "check_dependency_versions" @@ -256,9 +277,14 @@ def _get_version(dependency_name): "UserListDirectLicenseServiceAsyncClient", "UserListGlobalLicenseServiceAsyncClient", "UserListServiceAsyncClient", + "AdEvent", + "AdFormat", "AdIdentifiers", + "AdPlacement", + "AdType", "AddressInfo", "AgeRange", + "AttributionHint", "AudienceMember", "AwsWrappedKeyInfo", "Baseline", @@ -267,6 +293,7 @@ def _get_version(dependency_name): "Consent", "ConsentStatus", "ContactIdInfo", + "CoordinatorKeyInfo", "CreatePartnerLinkRequest", "CreateUserListDirectLicenseRequest", "CreateUserListGlobalLicenseRequest", @@ -290,11 +317,14 @@ def _get_version(dependency_name): "EventParameter", "EventSource", "ExperimentalField", + "FeatureSet", "GcpWrappedKeyInfo", "Gender", "GetUserListDirectLicenseRequest", "GetUserListGlobalLicenseRequest", "GetUserListRequest", + "IngestAdEventsRequest", + "IngestAdEventsResponse", "IngestAudienceMembersRequest", "IngestAudienceMembersResponse", "IngestEventsRequest", @@ -315,13 +345,18 @@ def _get_version(dependency_name): "ListUserListsResponse", "MarketingDataInsightsServiceClient", "MatchRateRange", + "MediaQuartile", "MobileData", "MobileIdInfo", "PairData", "PairIdInfo", "PartnerAudienceInfo", + "PartnerCustomerAccount", "PartnerLink", + "PartnerLinkMetadata", "PartnerLinkServiceClient", + "Platform", + "PlatformType", "PpidData", "ProcessingErrorReason", "ProcessingWarningReason", @@ -339,6 +374,7 @@ def _get_version(dependency_name): "SearchPartnerLinksResponse", "SizeInfo", "TargetNetworkInfo", + "TargetingType", "TermsOfService", "TermsOfServiceStatus", "UpdateUserListDirectLicenseRequest", @@ -362,6 +398,8 @@ def _get_version(dependency_name): "UserListServiceClient", "UserProperties", "UserProperty", + "ViewType", + "ViewabilityInfo", "WarningCount", "WarningInfo", ) diff --git a/packages/google-ads-datamanager/google/ads/datamanager_v1/gapic_metadata.json b/packages/google-ads-datamanager/google/ads/datamanager_v1/gapic_metadata.json index e14891c3ab94..60250ca08a2d 100644 --- a/packages/google-ads-datamanager/google/ads/datamanager_v1/gapic_metadata.json +++ b/packages/google-ads-datamanager/google/ads/datamanager_v1/gapic_metadata.json @@ -10,6 +10,11 @@ "grpc": { "libraryClient": "IngestionServiceClient", "rpcs": { + "IngestAdEvents": { + "methods": [ + "ingest_ad_events" + ] + }, "IngestAudienceMembers": { "methods": [ "ingest_audience_members" @@ -35,6 +40,11 @@ "grpc-async": { "libraryClient": "IngestionServiceAsyncClient", "rpcs": { + "IngestAdEvents": { + "methods": [ + "ingest_ad_events" + ] + }, "IngestAudienceMembers": { "methods": [ "ingest_audience_members" @@ -60,6 +70,11 @@ "rest": { "libraryClient": "IngestionServiceClient", "rpcs": { + "IngestAdEvents": { + "methods": [ + "ingest_ad_events" + ] + }, "IngestAudienceMembers": { "methods": [ "ingest_audience_members" diff --git a/packages/google-ads-datamanager/google/ads/datamanager_v1/services/ingestion_service/async_client.py b/packages/google-ads-datamanager/google/ads/datamanager_v1/services/ingestion_service/async_client.py index 607803113699..8da6f7e26092 100644 --- a/packages/google-ads-datamanager/google/ads/datamanager_v1/services/ingestion_service/async_client.py +++ b/packages/google-ads-datamanager/google/ads/datamanager_v1/services/ingestion_service/async_client.py @@ -328,6 +328,7 @@ async def sample_ingest_audience_members(): # Initialize request argument(s) destinations = datamanager_v1.Destination() destinations.operating_account.account_id = "account_id_value" + destinations.operating_account.account_type = "FLOODLIGHT_CONFIG" destinations.product_destination_id = "product_destination_id_value" audience_members = datamanager_v1.AudienceMember() @@ -422,6 +423,7 @@ async def sample_remove_audience_members(): # Initialize request argument(s) destinations = datamanager_v1.Destination() destinations.operating_account.account_id = "account_id_value" + destinations.operating_account.account_type = "FLOODLIGHT_CONFIG" destinations.product_destination_id = "product_destination_id_value" audience_members = datamanager_v1.AudienceMember() @@ -513,6 +515,7 @@ async def sample_ingest_events(): # Initialize request argument(s) destinations = datamanager_v1.Destination() destinations.operating_account.account_id = "account_id_value" + destinations.operating_account.account_type = "FLOODLIGHT_CONFIG" destinations.product_destination_id = "product_destination_id_value" request = datamanager_v1.IngestEventsRequest( @@ -570,6 +573,105 @@ async def sample_ingest_events(): # Done; return the response. return response + async def ingest_ad_events( + self, + request: Optional[Union[ingestion_service.IngestAdEventsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ingestion_service.IngestAdEventsResponse: + r"""Uploads a list of [AdEvent][google.ads.datamanager.v1.AdEvent] + resources to Google Analytics. + + This feature is only available to accounts on an allowlist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import datamanager_v1 + + async def sample_ingest_ad_events(): + # Create a client + client = datamanager_v1.IngestionServiceAsyncClient() + + # Initialize request argument(s) + ad_events = datamanager_v1.AdEvent() + ad_events.event_subtype = "EVENT_SUBTYPE_OUTBOUND_CLICK" + ad_events.ad_type = "AD_TYPE_VIDEO" + ad_events.ad_format = "AD_FORMAT_VIDEO" + ad_events.ad_placement = "AD_PLACEMENT_STORY" + ad_events.targeting_type = "TARGETING_TYPE_REMARKETING" + ad_events.platform_type = "PLATFORM_TYPE_TABLET" + ad_events.platform = "PLATFORM_WEB" + ad_events.advertiser_id = "advertiser_id_value" + ad_events.event_type = "EVENT_TYPE_CLICK" + ad_events.campaign_id = "campaign_id_value" + ad_events.campaign_name = "campaign_name_value" + ad_events.region_code = "region_code_value" + ad_events.source = "source_value" + ad_events.medium = "medium_value" + ad_events.viewability_info.view_type = "VIEW_TYPE_MRC_RENDERED" + + request = datamanager_v1.IngestAdEventsRequest( + ad_events=ad_events, + ) + + # Make the request + response = await client.ingest_ad_events(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.ads.datamanager_v1.types.IngestAdEventsRequest, dict]]): + The request object. Request to upload ad events. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.datamanager_v1.types.IngestAdEventsResponse: + Response from an ad event ingestion + operation. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, ingestion_service.IngestAdEventsRequest): + request = ingestion_service.IngestAdEventsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.ingest_ad_events + ] + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + async def retrieve_request_status( self, request: Optional[ diff --git a/packages/google-ads-datamanager/google/ads/datamanager_v1/services/ingestion_service/client.py b/packages/google-ads-datamanager/google/ads/datamanager_v1/services/ingestion_service/client.py index 0282585b8fe0..0dae3f323e08 100644 --- a/packages/google-ads-datamanager/google/ads/datamanager_v1/services/ingestion_service/client.py +++ b/packages/google-ads-datamanager/google/ads/datamanager_v1/services/ingestion_service/client.py @@ -743,6 +743,7 @@ def sample_ingest_audience_members(): # Initialize request argument(s) destinations = datamanager_v1.Destination() destinations.operating_account.account_id = "account_id_value" + destinations.operating_account.account_type = "FLOODLIGHT_CONFIG" destinations.product_destination_id = "product_destination_id_value" audience_members = datamanager_v1.AudienceMember() @@ -835,6 +836,7 @@ def sample_remove_audience_members(): # Initialize request argument(s) destinations = datamanager_v1.Destination() destinations.operating_account.account_id = "account_id_value" + destinations.operating_account.account_type = "FLOODLIGHT_CONFIG" destinations.product_destination_id = "product_destination_id_value" audience_members = datamanager_v1.AudienceMember() @@ -924,6 +926,7 @@ def sample_ingest_events(): # Initialize request argument(s) destinations = datamanager_v1.Destination() destinations.operating_account.account_id = "account_id_value" + destinations.operating_account.account_type = "FLOODLIGHT_CONFIG" destinations.product_destination_id = "product_destination_id_value" request = datamanager_v1.IngestEventsRequest( @@ -979,6 +982,103 @@ def sample_ingest_events(): # Done; return the response. return response + def ingest_ad_events( + self, + request: Optional[Union[ingestion_service.IngestAdEventsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ingestion_service.IngestAdEventsResponse: + r"""Uploads a list of [AdEvent][google.ads.datamanager.v1.AdEvent] + resources to Google Analytics. + + This feature is only available to accounts on an allowlist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import datamanager_v1 + + def sample_ingest_ad_events(): + # Create a client + client = datamanager_v1.IngestionServiceClient() + + # Initialize request argument(s) + ad_events = datamanager_v1.AdEvent() + ad_events.event_subtype = "EVENT_SUBTYPE_OUTBOUND_CLICK" + ad_events.ad_type = "AD_TYPE_VIDEO" + ad_events.ad_format = "AD_FORMAT_VIDEO" + ad_events.ad_placement = "AD_PLACEMENT_STORY" + ad_events.targeting_type = "TARGETING_TYPE_REMARKETING" + ad_events.platform_type = "PLATFORM_TYPE_TABLET" + ad_events.platform = "PLATFORM_WEB" + ad_events.advertiser_id = "advertiser_id_value" + ad_events.event_type = "EVENT_TYPE_CLICK" + ad_events.campaign_id = "campaign_id_value" + ad_events.campaign_name = "campaign_name_value" + ad_events.region_code = "region_code_value" + ad_events.source = "source_value" + ad_events.medium = "medium_value" + ad_events.viewability_info.view_type = "VIEW_TYPE_MRC_RENDERED" + + request = datamanager_v1.IngestAdEventsRequest( + ad_events=ad_events, + ) + + # Make the request + response = client.ingest_ad_events(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.datamanager_v1.types.IngestAdEventsRequest, dict]): + The request object. Request to upload ad events. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.datamanager_v1.types.IngestAdEventsResponse: + Response from an ad event ingestion + operation. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, ingestion_service.IngestAdEventsRequest): + request = ingestion_service.IngestAdEventsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.ingest_ad_events] + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + def retrieve_request_status( self, request: Optional[ diff --git a/packages/google-ads-datamanager/google/ads/datamanager_v1/services/ingestion_service/transports/base.py b/packages/google-ads-datamanager/google/ads/datamanager_v1/services/ingestion_service/transports/base.py index c65424017d17..966fbe06b59e 100644 --- a/packages/google-ads-datamanager/google/ads/datamanager_v1/services/ingestion_service/transports/base.py +++ b/packages/google-ads-datamanager/google/ads/datamanager_v1/services/ingestion_service/transports/base.py @@ -157,6 +157,11 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.ingest_ad_events: gapic_v1.method.wrap_method( + self.ingest_ad_events, + default_timeout=None, + client_info=client_info, + ), self.retrieve_request_status: gapic_v1.method.wrap_method( self.retrieve_request_status, default_timeout=None, @@ -209,6 +214,18 @@ def ingest_events( ]: raise NotImplementedError() + @property + def ingest_ad_events( + self, + ) -> Callable[ + [ingestion_service.IngestAdEventsRequest], + Union[ + ingestion_service.IngestAdEventsResponse, + Awaitable[ingestion_service.IngestAdEventsResponse], + ], + ]: + raise NotImplementedError() + @property def retrieve_request_status( self, diff --git a/packages/google-ads-datamanager/google/ads/datamanager_v1/services/ingestion_service/transports/grpc.py b/packages/google-ads-datamanager/google/ads/datamanager_v1/services/ingestion_service/transports/grpc.py index ef983168edea..7a1ae1b62abf 100644 --- a/packages/google-ads-datamanager/google/ads/datamanager_v1/services/ingestion_service/transports/grpc.py +++ b/packages/google-ads-datamanager/google/ads/datamanager_v1/services/ingestion_service/transports/grpc.py @@ -419,6 +419,38 @@ def ingest_events( ) return self._stubs["ingest_events"] + @property + def ingest_ad_events( + self, + ) -> Callable[ + [ingestion_service.IngestAdEventsRequest], + ingestion_service.IngestAdEventsResponse, + ]: + r"""Return a callable for the ingest ad events method over gRPC. + + Uploads a list of [AdEvent][google.ads.datamanager.v1.AdEvent] + resources to Google Analytics. + + This feature is only available to accounts on an allowlist. + + Returns: + Callable[[~.IngestAdEventsRequest], + ~.IngestAdEventsResponse]: + 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 "ingest_ad_events" not in self._stubs: + self._stubs["ingest_ad_events"] = self._logged_channel.unary_unary( + "/google.ads.datamanager.v1.IngestionService/IngestAdEvents", + request_serializer=ingestion_service.IngestAdEventsRequest.serialize, + response_deserializer=ingestion_service.IngestAdEventsResponse.deserialize, + ) + return self._stubs["ingest_ad_events"] + @property def retrieve_request_status( self, diff --git a/packages/google-ads-datamanager/google/ads/datamanager_v1/services/ingestion_service/transports/grpc_asyncio.py b/packages/google-ads-datamanager/google/ads/datamanager_v1/services/ingestion_service/transports/grpc_asyncio.py index 4a6846d5dd7b..3d0d2d9c0d78 100644 --- a/packages/google-ads-datamanager/google/ads/datamanager_v1/services/ingestion_service/transports/grpc_asyncio.py +++ b/packages/google-ads-datamanager/google/ads/datamanager_v1/services/ingestion_service/transports/grpc_asyncio.py @@ -428,6 +428,38 @@ def ingest_events( ) return self._stubs["ingest_events"] + @property + def ingest_ad_events( + self, + ) -> Callable[ + [ingestion_service.IngestAdEventsRequest], + Awaitable[ingestion_service.IngestAdEventsResponse], + ]: + r"""Return a callable for the ingest ad events method over gRPC. + + Uploads a list of [AdEvent][google.ads.datamanager.v1.AdEvent] + resources to Google Analytics. + + This feature is only available to accounts on an allowlist. + + Returns: + Callable[[~.IngestAdEventsRequest], + Awaitable[~.IngestAdEventsResponse]]: + 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 "ingest_ad_events" not in self._stubs: + self._stubs["ingest_ad_events"] = self._logged_channel.unary_unary( + "/google.ads.datamanager.v1.IngestionService/IngestAdEvents", + request_serializer=ingestion_service.IngestAdEventsRequest.serialize, + response_deserializer=ingestion_service.IngestAdEventsResponse.deserialize, + ) + return self._stubs["ingest_ad_events"] + @property def retrieve_request_status( self, @@ -475,6 +507,11 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.ingest_ad_events: self._wrap_method( + self.ingest_ad_events, + default_timeout=None, + client_info=client_info, + ), self.retrieve_request_status: self._wrap_method( self.retrieve_request_status, default_timeout=None, diff --git a/packages/google-ads-datamanager/google/ads/datamanager_v1/services/ingestion_service/transports/rest.py b/packages/google-ads-datamanager/google/ads/datamanager_v1/services/ingestion_service/transports/rest.py index 69b7f894b963..2c48d2e16e20 100644 --- a/packages/google-ads-datamanager/google/ads/datamanager_v1/services/ingestion_service/transports/rest.py +++ b/packages/google-ads-datamanager/google/ads/datamanager_v1/services/ingestion_service/transports/rest.py @@ -72,6 +72,14 @@ class IngestionServiceRestInterceptor: .. code-block:: python class MyCustomIngestionServiceInterceptor(IngestionServiceRestInterceptor): + def pre_ingest_ad_events(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_ingest_ad_events(self, response): + logging.log(f"Received response: {response}") + return response + def pre_ingest_audience_members(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -110,6 +118,57 @@ def post_retrieve_request_status(self, response): """ + def pre_ingest_ad_events( + self, + request: ingestion_service.IngestAdEventsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + ingestion_service.IngestAdEventsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for ingest_ad_events + + Override in a subclass to manipulate the request or metadata + before they are sent to the IngestionService server. + """ + return request, metadata + + def post_ingest_ad_events( + self, response: ingestion_service.IngestAdEventsResponse + ) -> ingestion_service.IngestAdEventsResponse: + """Post-rpc interceptor for ingest_ad_events + + DEPRECATED. Please use the `post_ingest_ad_events_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the IngestionService server but before + it is returned to user code. This `post_ingest_ad_events` interceptor runs + before the `post_ingest_ad_events_with_metadata` interceptor. + """ + return response + + def post_ingest_ad_events_with_metadata( + self, + response: ingestion_service.IngestAdEventsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + ingestion_service.IngestAdEventsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for ingest_ad_events + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the IngestionService server but before it is returned to user code. + + We recommend only using this `post_ingest_ad_events_with_metadata` + interceptor in new development instead of the `post_ingest_ad_events` interceptor. + When both interceptors are used, this `post_ingest_ad_events_with_metadata` interceptor runs after the + `post_ingest_ad_events` interceptor. The (possibly modified) response returned by + `post_ingest_ad_events` will be passed to + `post_ingest_ad_events_with_metadata`. + """ + return response, metadata + def pre_ingest_audience_members( self, request: ingestion_service.IngestAudienceMembersRequest, @@ -410,6 +469,160 @@ def __init__( self._interceptor = interceptor or IngestionServiceRestInterceptor() self._prep_wrapped_messages(client_info) + class _IngestAdEvents( + _BaseIngestionServiceRestTransport._BaseIngestAdEvents, IngestionServiceRestStub + ): + def __hash__(self): + return hash("IngestionServiceRestTransport.IngestAdEvents") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: ingestion_service.IngestAdEventsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ingestion_service.IngestAdEventsResponse: + r"""Call the ingest ad events method over HTTP. + + Args: + request (~.ingestion_service.IngestAdEventsRequest): + The request object. Request to upload ad events. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.ingestion_service.IngestAdEventsResponse: + Response from an ad event ingestion + operation. + + """ + + http_options = _BaseIngestionServiceRestTransport._BaseIngestAdEvents._get_http_options() + + request, metadata = self._interceptor.pre_ingest_ad_events( + request, metadata + ) + transcoded_request = _BaseIngestionServiceRestTransport._BaseIngestAdEvents._get_transcoded_request( + http_options, request + ) + + body = _BaseIngestionServiceRestTransport._BaseIngestAdEvents._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseIngestionServiceRestTransport._BaseIngestAdEvents._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.datamanager_v1.IngestionServiceClient.IngestAdEvents", + extra={ + "serviceName": "google.ads.datamanager.v1.IngestionService", + "rpcName": "IngestAdEvents", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = IngestionServiceRestTransport._IngestAdEvents._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = ingestion_service.IngestAdEventsResponse() + pb_resp = ingestion_service.IngestAdEventsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_ingest_ad_events(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_ingest_ad_events_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ingestion_service.IngestAdEventsResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.datamanager_v1.IngestionServiceClient.ingest_ad_events", + extra={ + "serviceName": "google.ads.datamanager.v1.IngestionService", + "rpcName": "IngestAdEvents", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + class _IngestAudienceMembers( _BaseIngestionServiceRestTransport._BaseIngestAudienceMembers, IngestionServiceRestStub, @@ -1043,6 +1256,17 @@ def __call__( ) return resp + @property + def ingest_ad_events( + self, + ) -> Callable[ + [ingestion_service.IngestAdEventsRequest], + ingestion_service.IngestAdEventsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._IngestAdEvents(self._session, self._host, self._interceptor) # type: ignore + @property def ingest_audience_members( self, diff --git a/packages/google-ads-datamanager/google/ads/datamanager_v1/services/ingestion_service/transports/rest_base.py b/packages/google-ads-datamanager/google/ads/datamanager_v1/services/ingestion_service/transports/rest_base.py index f0b2dc696816..b4c248b12689 100644 --- a/packages/google-ads-datamanager/google/ads/datamanager_v1/services/ingestion_service/transports/rest_base.py +++ b/packages/google-ads-datamanager/google/ads/datamanager_v1/services/ingestion_service/transports/rest_base.py @@ -87,6 +87,63 @@ def __init__( api_audience=api_audience, ) + class _BaseIngestAdEvents: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/adEvents:ingest", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = ingestion_service.IngestAdEventsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseIngestionServiceRestTransport._BaseIngestAdEvents._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + class _BaseIngestAudienceMembers: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") diff --git a/packages/google-ads-datamanager/google/ads/datamanager_v1/services/partner_link_service/async_client.py b/packages/google-ads-datamanager/google/ads/datamanager_v1/services/partner_link_service/async_client.py index 26d9e63c41f5..33bc47086e21 100644 --- a/packages/google-ads-datamanager/google/ads/datamanager_v1/services/partner_link_service/async_client.py +++ b/packages/google-ads-datamanager/google/ads/datamanager_v1/services/partner_link_service/async_client.py @@ -343,7 +343,9 @@ async def sample_create_partner_link(): # Initialize request argument(s) partner_link = datamanager_v1.PartnerLink() partner_link.owning_account.account_id = "account_id_value" + partner_link.owning_account.account_type = "FLOODLIGHT_CONFIG" partner_link.partner_account.account_id = "account_id_value" + partner_link.partner_account.account_type = "FLOODLIGHT_CONFIG" request = datamanager_v1.CreatePartnerLinkRequest( parent="parent_value", diff --git a/packages/google-ads-datamanager/google/ads/datamanager_v1/services/partner_link_service/client.py b/packages/google-ads-datamanager/google/ads/datamanager_v1/services/partner_link_service/client.py index 71235b65c66d..ff2192e695da 100644 --- a/packages/google-ads-datamanager/google/ads/datamanager_v1/services/partner_link_service/client.py +++ b/packages/google-ads-datamanager/google/ads/datamanager_v1/services/partner_link_service/client.py @@ -774,7 +774,9 @@ def sample_create_partner_link(): # Initialize request argument(s) partner_link = datamanager_v1.PartnerLink() partner_link.owning_account.account_id = "account_id_value" + partner_link.owning_account.account_type = "FLOODLIGHT_CONFIG" partner_link.partner_account.account_id = "account_id_value" + partner_link.partner_account.account_type = "FLOODLIGHT_CONFIG" request = datamanager_v1.CreatePartnerLinkRequest( parent="parent_value", diff --git a/packages/google-ads-datamanager/google/ads/datamanager_v1/types/__init__.py b/packages/google-ads-datamanager/google/ads/datamanager_v1/types/__init__.py index 2dfc20157877..ac3a1418bd4b 100644 --- a/packages/google-ads-datamanager/google/ads/datamanager_v1/types/__init__.py +++ b/packages/google-ads-datamanager/google/ads/datamanager_v1/types/__init__.py @@ -13,6 +13,16 @@ # See the License for the specific language governing permissions and # limitations under the License. # +from .ad_event import ( + AdEvent, + AdFormat, + AdPlacement, + AdType, + AttributionHint, + Platform, + PlatformType, + TargetingType, +) from .age_range import ( AgeRange, ) @@ -47,6 +57,7 @@ ) from .encryption_info import ( AwsWrappedKeyInfo, + CoordinatorKeyInfo, EncryptionInfo, GcpWrappedKeyInfo, ) @@ -69,6 +80,8 @@ ) from .ingestion_service import ( Encoding, + IngestAdEventsRequest, + IngestAdEventsResponse, IngestAudienceMembersRequest, IngestAudienceMembersResponse, IngestEventsRequest, @@ -92,7 +105,10 @@ from .partner_link_service import ( CreatePartnerLinkRequest, DeletePartnerLinkRequest, + FeatureSet, + PartnerCustomerAccount, PartnerLink, + PartnerLinkMetadata, SearchPartnerLinksRequest, SearchPartnerLinksResponse, ) @@ -181,8 +197,21 @@ UserProperties, UserProperty, ) +from .viewability_info import ( + MediaQuartile, + ViewabilityInfo, + ViewType, +) __all__ = ( + "AdEvent", + "AdFormat", + "AdPlacement", + "AdType", + "AttributionHint", + "Platform", + "PlatformType", + "TargetingType", "AgeRange", "AudienceMember", "CompositeData", @@ -202,6 +231,7 @@ "DeviceInfo", "EncryptedUserId", "AwsWrappedKeyInfo", + "CoordinatorKeyInfo", "EncryptionInfo", "GcpWrappedKeyInfo", "ErrorReason", @@ -213,6 +243,8 @@ "EventSource", "ExperimentalField", "Gender", + "IngestAdEventsRequest", + "IngestAdEventsResponse", "IngestAudienceMembersRequest", "IngestAudienceMembersResponse", "IngestEventsRequest", @@ -229,9 +261,12 @@ "MatchRateRange", "CreatePartnerLinkRequest", "DeletePartnerLinkRequest", + "PartnerCustomerAccount", "PartnerLink", + "PartnerLinkMetadata", "SearchPartnerLinksRequest", "SearchPartnerLinksResponse", + "FeatureSet", "ErrorCount", "ErrorInfo", "WarningCount", @@ -285,4 +320,7 @@ "UserProperty", "CustomerType", "CustomerValueBucket", + "ViewabilityInfo", + "MediaQuartile", + "ViewType", ) diff --git a/packages/google-ads-datamanager/google/ads/datamanager_v1/types/ad_event.py b/packages/google-ads-datamanager/google/ads/datamanager_v1/types/ad_event.py new file mode 100644 index 000000000000..f169f6038810 --- /dev/null +++ b/packages/google-ads-datamanager/google/ads/datamanager_v1/types/ad_event.py @@ -0,0 +1,613 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore +import proto # type: ignore + +from google.ads.datamanager_v1.types import device_info as gad_device_info +from google.ads.datamanager_v1.types import user_data as gad_user_data +from google.ads.datamanager_v1.types import viewability_info as gad_viewability_info + +__protobuf__ = proto.module( + package="google.ads.datamanager.v1", + manifest={ + "AdType", + "AdFormat", + "AdPlacement", + "TargetingType", + "PlatformType", + "Platform", + "AttributionHint", + "AdEvent", + }, +) + + +class AdType(proto.Enum): + r"""The type of the ad served. + + Values: + AD_TYPE_UNSPECIFIED (0): + Unspecified ad type. + AD_TYPE_DISPLAY (1): + Display ad. + AD_TYPE_TEXT (2): + Text ad. + AD_TYPE_IMAGE (3): + Image ad. + AD_TYPE_RICH_MEDIA (4): + Rich media ad. + AD_TYPE_HTML (5): + HTML ad. + AD_TYPE_AUDIO (6): + Audio ad. + AD_TYPE_VIDEO (7): + Video ad. + """ + + AD_TYPE_UNSPECIFIED = 0 + AD_TYPE_DISPLAY = 1 + AD_TYPE_TEXT = 2 + AD_TYPE_IMAGE = 3 + AD_TYPE_RICH_MEDIA = 4 + AD_TYPE_HTML = 5 + AD_TYPE_AUDIO = 6 + AD_TYPE_VIDEO = 7 + + +class AdFormat(proto.Enum): + r"""The format of the ad served. + + Values: + AD_FORMAT_UNSPECIFIED (0): + Unspecified ad format. + AD_FORMAT_AR (1): + AR ad. + AD_FORMAT_AUDIO (2): + Audio ad. + AD_FORMAT_BANNER (3): + Banner ad. + AD_FORMAT_BUMPER (4): + Bumper ad. + AD_FORMAT_CAROUSEL (5): + Carousel ad. + AD_FORMAT_COLLECTION (6): + Collection ad. + AD_FORMAT_IMAGE (7): + Image ad. + AD_FORMAT_INTERACTIVE (8): + Interactive ad. + AD_FORMAT_INTERSTITIAL (9): + Interstitial ad. + AD_FORMAT_IN_FEED (10): + In-feed ad. + AD_FORMAT_IN_STREAM (11): + In-stream ad. + AD_FORMAT_IN_STREAM_SKIPPABLE (12): + In-stream skippable ad. + AD_FORMAT_IN_STREAM_NON_SKIPPABLE (13): + In-stream non-skippable ad. + AD_FORMAT_NATIVE (14): + Native ad. + AD_FORMAT_SHORTS (15): + Shorts ad. + AD_FORMAT_STORY (16): + Story ad. + AD_FORMAT_SPONSORED (17): + Sponsored ad. + AD_FORMAT_VIDEO (18): + Video ad. + """ + + AD_FORMAT_UNSPECIFIED = 0 + AD_FORMAT_AR = 1 + AD_FORMAT_AUDIO = 2 + AD_FORMAT_BANNER = 3 + AD_FORMAT_BUMPER = 4 + AD_FORMAT_CAROUSEL = 5 + AD_FORMAT_COLLECTION = 6 + AD_FORMAT_IMAGE = 7 + AD_FORMAT_INTERACTIVE = 8 + AD_FORMAT_INTERSTITIAL = 9 + AD_FORMAT_IN_FEED = 10 + AD_FORMAT_IN_STREAM = 11 + AD_FORMAT_IN_STREAM_SKIPPABLE = 12 + AD_FORMAT_IN_STREAM_NON_SKIPPABLE = 13 + AD_FORMAT_NATIVE = 14 + AD_FORMAT_SHORTS = 15 + AD_FORMAT_STORY = 16 + AD_FORMAT_SPONSORED = 17 + AD_FORMAT_VIDEO = 18 + + +class AdPlacement(proto.Enum): + r"""The placement of the ad served. + + Values: + AD_PLACEMENT_UNSPECIFIED (0): + Unspecified ad placement. + AD_PLACEMENT_DISCOVER (1): + Discover placement. + AD_PLACEMENT_FEED (2): + Feed placement. + AD_PLACEMENT_FOOTER (3): + Footer placement. + AD_PLACEMENT_HEADER (4): + Header placement. + AD_PLACEMENT_HOME (5): + Home placement. + AD_PLACEMENT_IN_CONTENT (6): + In-content placement. + AD_PLACEMENT_PROMOTED (7): + Promoted placement. + AD_PLACEMENT_SEARCH (8): + Search placement. + AD_PLACEMENT_STORY (9): + Story placement. + """ + + AD_PLACEMENT_UNSPECIFIED = 0 + AD_PLACEMENT_DISCOVER = 1 + AD_PLACEMENT_FEED = 2 + AD_PLACEMENT_FOOTER = 3 + AD_PLACEMENT_HEADER = 4 + AD_PLACEMENT_HOME = 5 + AD_PLACEMENT_IN_CONTENT = 6 + AD_PLACEMENT_PROMOTED = 7 + AD_PLACEMENT_SEARCH = 8 + AD_PLACEMENT_STORY = 9 + + +class TargetingType(proto.Enum): + r"""The type of targeting used to serve the ad. + + Values: + TARGETING_TYPE_UNSPECIFIED (0): + Unspecified targeting type. + TARGETING_TYPE_AUDIENCE (1): + Audience targeting. + TARGETING_TYPE_CONTEXTUAL (2): + Contextual targeting. + TARGETING_TYPE_DEMOGRAPHIC (3): + Demographic targeting. + TARGETING_TYPE_DEVICE (4): + Device targeting. + TARGETING_TYPE_GEO (5): + Geo targeting. + TARGETING_TYPE_INTEREST (6): + Interest targeting. + TARGETING_TYPE_PURCHASE_INTENT (7): + Purchase intent targeting. + TARGETING_TYPE_REMARKETING (8): + Remarketing targeting. + """ + + TARGETING_TYPE_UNSPECIFIED = 0 + TARGETING_TYPE_AUDIENCE = 1 + TARGETING_TYPE_CONTEXTUAL = 2 + TARGETING_TYPE_DEMOGRAPHIC = 3 + TARGETING_TYPE_DEVICE = 4 + TARGETING_TYPE_GEO = 5 + TARGETING_TYPE_INTEREST = 6 + TARGETING_TYPE_PURCHASE_INTENT = 7 + TARGETING_TYPE_REMARKETING = 8 + + +class PlatformType(proto.Enum): + r"""The type of the platform on which the ad was served. + + Values: + PLATFORM_TYPE_UNSPECIFIED (0): + Unspecified platform type. + PLATFORM_TYPE_MOBILE (1): + Mobile platform. + PLATFORM_TYPE_DESKTOP (2): + Desktop platform. + PLATFORM_TYPE_CTV (3): + CTV platform. + PLATFORM_TYPE_PHONE (4): + Phone platform. + PLATFORM_TYPE_TABLET (5): + Tablet platform. + """ + + PLATFORM_TYPE_UNSPECIFIED = 0 + PLATFORM_TYPE_MOBILE = 1 + PLATFORM_TYPE_DESKTOP = 2 + PLATFORM_TYPE_CTV = 3 + PLATFORM_TYPE_PHONE = 4 + PLATFORM_TYPE_TABLET = 5 + + +class Platform(proto.Enum): + r"""Further detail of the platform on which the ad was served. + + Values: + PLATFORM_UNSPECIFIED (0): + Unspecified platform. + PLATFORM_IOS (1): + iOS platform. + PLATFORM_ANDROID (2): + Android platform. + PLATFORM_WEB (3): + Web platform. + """ + + PLATFORM_UNSPECIFIED = 0 + PLATFORM_IOS = 1 + PLATFORM_ANDROID = 2 + PLATFORM_WEB = 3 + + +class AttributionHint(proto.Enum): + r"""The partner-assumed attribution status for this ad event. + + Values: + ATTRIBUTION_HINT_UNSPECIFIED (0): + Unknown attribution status. + ATTRIBUTION_HINT_CONVERTED (1): + Converted status. + ATTRIBUTION_HINT_NOT_CONVERTED (2): + Not converted status. + """ + + ATTRIBUTION_HINT_UNSPECIFIED = 0 + ATTRIBUTION_HINT_CONVERTED = 1 + ATTRIBUTION_HINT_NOT_CONVERTED = 2 + + +class AdEvent(proto.Message): + r"""An ad event. + + 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: + advertiser_id (str): + Required. The ID of the advertiser for the ad + event. + This must match the ID sent in the linking flow. + event_type (google.ads.datamanager_v1.types.AdEvent.EventType): + Required. The type of the event. + event_subtype (google.ads.datamanager_v1.types.AdEvent.EventSubtype): + Enum value for event subtype. + + This field is a member of `oneof`_ ``event_subtype_oneof``. + event_subtype_string (str): + String value for event subtype. + + This field is a member of `oneof`_ ``event_subtype_oneof``. + timestamp (google.protobuf.timestamp_pb2.Timestamp): + Required. The time the event occurred. + event_id (str): + Optional. An ID created and managed by the + caller that uniquely identifies this event. + + Required if you want to deduplicate ad events + that are included in multiple requests. + Otherwise, this field is optional. + user_data (google.ads.datamanager_v1.types.UserData): + Optional. Multiple pieces of user-provided + data, representing the user the event is + associated with. + + It is possible to provide multiple instances of + the same type of data (e.g. email address). The + more data provided, the more likely a match will + be found. + device_info (google.ads.datamanager_v1.types.DeviceInfo): + Optional. Information gathered about the + device being used when the ad event happened. + mobile_device_id (str): + Optional. The device ID of the device that + the ad was served to. + campaign_id (str): + Required. The ID of the associated campaign. + campaign_name (str): + Required. The name of the associated + campaign. + ad_group_id (str): + Optional. The ID of the associated ad group. + ad_id (str): + Optional. The ID of the associated ad within + the group. + ad_type (google.ads.datamanager_v1.types.AdType): + Enum value for ad type. + + This field is a member of `oneof`_ ``ad_type_oneof``. + ad_type_string (str): + String value for ad type. + + This field is a member of `oneof`_ ``ad_type_oneof``. + ad_format (google.ads.datamanager_v1.types.AdFormat): + Enum value for ad format. + + This field is a member of `oneof`_ ``ad_format_oneof``. + ad_format_string (str): + String value for ad format. + + This field is a member of `oneof`_ ``ad_format_oneof``. + ad_placement (google.ads.datamanager_v1.types.AdPlacement): + Enum value for ad placement. + + This field is a member of `oneof`_ ``ad_placement_oneof``. + ad_placement_string (str): + String value for ad placement. + + This field is a member of `oneof`_ ``ad_placement_oneof``. + ad_height (int): + Optional. The height of the ad in pixels. + ad_width (int): + Optional. The width of the ad in pixels. + region_code (str): + Required. The ISO 3166-2 country plus + subdivision. + source (str): + Required. The platform source of the ad, akin + to the Google Analytics source. + medium (str): + Required. The medium of the ad, akin to the + Google Analytics medium. + targeting_type (google.ads.datamanager_v1.types.TargetingType): + Enum value for targeting type. + + This field is a member of `oneof`_ ``targeting_type_oneof``. + targeting_type_string (str): + String value for targeting type. + + This field is a member of `oneof`_ ``targeting_type_oneof``. + platform_type (google.ads.datamanager_v1.types.PlatformType): + Enum value for platform type. + + This field is a member of `oneof`_ ``platform_type_oneof``. + platform_type_string (str): + String value for platform type. + + This field is a member of `oneof`_ ``platform_type_oneof``. + platform (google.ads.datamanager_v1.types.Platform): + Enum value for platform. + + This field is a member of `oneof`_ ``platform_oneof``. + platform_string (str): + String value for platform. + + This field is a member of `oneof`_ ``platform_oneof``. + attribution_hint (google.ads.datamanager_v1.types.AttributionHint): + Optional. The partner-assumed attribution + status for this ad event. + This acts only as a signal for how the partner + assumed attribution played out, and does not + force an end result in final reports. + viewability_info (google.ads.datamanager_v1.types.ViewabilityInfo): + Required. Details of the viewability of the + ad served. + measurement_allowed (bool): + Optional. Represents if the row is allowed to + be used for measurement purposes, as governed by + applicable privacy laws within regional + jurisdiction. + + This field is a member of `oneof`_ ``_measurement_allowed``. + """ + + class EventType(proto.Enum): + r"""The type of the event. + + Values: + EVENT_TYPE_UNSPECIFIED (0): + Unspecified event type. + EVENT_TYPE_VIEW (1): + View event. + EVENT_TYPE_CLICK (2): + Click event. + """ + + EVENT_TYPE_UNSPECIFIED = 0 + EVENT_TYPE_VIEW = 1 + EVENT_TYPE_CLICK = 2 + + class EventSubtype(proto.Enum): + r"""Additional classification about the type of ad event. + + Values: + EVENT_SUBTYPE_UNSPECIFIED (0): + Unspecified event subtype. + EVENT_SUBTYPE_IMPRESSION (1): + Impression event. + EVENT_SUBTYPE_ENGAGED_VIEW (2): + Engaged view event. + EVENT_SUBTYPE_ONSITE_CLICK (3): + Onsite click event. + EVENT_SUBTYPE_OUTBOUND_CLICK (4): + Outbound click event. + """ + + EVENT_SUBTYPE_UNSPECIFIED = 0 + EVENT_SUBTYPE_IMPRESSION = 1 + EVENT_SUBTYPE_ENGAGED_VIEW = 2 + EVENT_SUBTYPE_ONSITE_CLICK = 3 + EVENT_SUBTYPE_OUTBOUND_CLICK = 4 + + advertiser_id: str = proto.Field( + proto.STRING, + number=1, + ) + event_type: EventType = proto.Field( + proto.ENUM, + number=2, + enum=EventType, + ) + event_subtype: EventSubtype = proto.Field( + proto.ENUM, + number=3, + oneof="event_subtype_oneof", + enum=EventSubtype, + ) + event_subtype_string: str = proto.Field( + proto.STRING, + number=4, + oneof="event_subtype_oneof", + ) + timestamp: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + event_id: str = proto.Field( + proto.STRING, + number=6, + ) + user_data: gad_user_data.UserData = proto.Field( + proto.MESSAGE, + number=7, + message=gad_user_data.UserData, + ) + device_info: gad_device_info.DeviceInfo = proto.Field( + proto.MESSAGE, + number=8, + message=gad_device_info.DeviceInfo, + ) + mobile_device_id: str = proto.Field( + proto.STRING, + number=9, + ) + campaign_id: str = proto.Field( + proto.STRING, + number=10, + ) + campaign_name: str = proto.Field( + proto.STRING, + number=11, + ) + ad_group_id: str = proto.Field( + proto.STRING, + number=12, + ) + ad_id: str = proto.Field( + proto.STRING, + number=13, + ) + ad_type: "AdType" = proto.Field( + proto.ENUM, + number=14, + oneof="ad_type_oneof", + enum="AdType", + ) + ad_type_string: str = proto.Field( + proto.STRING, + number=15, + oneof="ad_type_oneof", + ) + ad_format: "AdFormat" = proto.Field( + proto.ENUM, + number=16, + oneof="ad_format_oneof", + enum="AdFormat", + ) + ad_format_string: str = proto.Field( + proto.STRING, + number=17, + oneof="ad_format_oneof", + ) + ad_placement: "AdPlacement" = proto.Field( + proto.ENUM, + number=18, + oneof="ad_placement_oneof", + enum="AdPlacement", + ) + ad_placement_string: str = proto.Field( + proto.STRING, + number=19, + oneof="ad_placement_oneof", + ) + ad_height: int = proto.Field( + proto.INT32, + number=20, + ) + ad_width: int = proto.Field( + proto.INT32, + number=21, + ) + region_code: str = proto.Field( + proto.STRING, + number=22, + ) + source: str = proto.Field( + proto.STRING, + number=23, + ) + medium: str = proto.Field( + proto.STRING, + number=24, + ) + targeting_type: "TargetingType" = proto.Field( + proto.ENUM, + number=25, + oneof="targeting_type_oneof", + enum="TargetingType", + ) + targeting_type_string: str = proto.Field( + proto.STRING, + number=26, + oneof="targeting_type_oneof", + ) + platform_type: "PlatformType" = proto.Field( + proto.ENUM, + number=27, + oneof="platform_type_oneof", + enum="PlatformType", + ) + platform_type_string: str = proto.Field( + proto.STRING, + number=28, + oneof="platform_type_oneof", + ) + platform: "Platform" = proto.Field( + proto.ENUM, + number=29, + oneof="platform_oneof", + enum="Platform", + ) + platform_string: str = proto.Field( + proto.STRING, + number=30, + oneof="platform_oneof", + ) + attribution_hint: "AttributionHint" = proto.Field( + proto.ENUM, + number=31, + enum="AttributionHint", + ) + viewability_info: gad_viewability_info.ViewabilityInfo = proto.Field( + proto.MESSAGE, + number=32, + message=gad_viewability_info.ViewabilityInfo, + ) + measurement_allowed: bool = proto.Field( + proto.BOOL, + number=33, + optional=True, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-datamanager/google/ads/datamanager_v1/types/destination.py b/packages/google-ads-datamanager/google/ads/datamanager_v1/types/destination.py index 7c9767b41b3a..a09a0b7e100c 100644 --- a/packages/google-ads-datamanager/google/ads/datamanager_v1/types/destination.py +++ b/packages/google-ads-datamanager/google/ads/datamanager_v1/types/destination.py @@ -131,7 +131,7 @@ class ProductAccount(proto.Message): Required. The ID of the account. For example, your Google Ads account ID. account_type (google.ads.datamanager_v1.types.ProductAccount.AccountType): - Optional. The type of the account. For example, + Required. The type of the account. For example, ``GOOGLE_ADS``. Either ``account_type`` or the deprecated ``product`` is required. If both are set, the values must match. diff --git a/packages/google-ads-datamanager/google/ads/datamanager_v1/types/encryption_info.py b/packages/google-ads-datamanager/google/ads/datamanager_v1/types/encryption_info.py index 83529a224cf4..3d1b83d3103c 100644 --- a/packages/google-ads-datamanager/google/ads/datamanager_v1/types/encryption_info.py +++ b/packages/google-ads-datamanager/google/ads/datamanager_v1/types/encryption_info.py @@ -25,6 +25,7 @@ "EncryptionInfo", "GcpWrappedKeyInfo", "AwsWrappedKeyInfo", + "CoordinatorKeyInfo", }, ) @@ -48,6 +49,17 @@ class EncryptionInfo(proto.Message): aws_wrapped_key_info (google.ads.datamanager_v1.types.AwsWrappedKeyInfo): Amazon Web Services wrapped key information. + This field is a member of `oneof`_ ``wrapped_key``. + coordinator_key_info (google.ads.datamanager_v1.types.CoordinatorKeyInfo): + Key information for the chosen coordinator key. + + This is not supported for the + [IngestEvents][google.ads.datamanager.v1.IngestionService.IngestEvents], + [IngestAudienceMembers][google.ads.datamanager.v1.IngestionService.IngestAudienceMembers], + and + [RemoveAudienceMembers][google.ads.datamanager.v1.IngestionService.RemoveAudienceMembers] + methods. + This field is a member of `oneof`_ ``wrapped_key``. """ @@ -63,6 +75,12 @@ class EncryptionInfo(proto.Message): oneof="wrapped_key", message="AwsWrappedKeyInfo", ) + coordinator_key_info: "CoordinatorKeyInfo" = proto.Field( + proto.MESSAGE, + number=3, + oneof="wrapped_key", + message="CoordinatorKeyInfo", + ) class GcpWrappedKeyInfo(proto.Message): @@ -176,4 +194,19 @@ class KeyType(proto.Enum): ) +class CoordinatorKeyInfo(proto.Message): + r"""Information about the coordinator key. + + Attributes: + key_id (str): + Required. The ID of the chosen coordinator + key. + """ + + key_id: str = proto.Field( + proto.STRING, + number=1, + ) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-datamanager/google/ads/datamanager_v1/types/error.py b/packages/google-ads-datamanager/google/ads/datamanager_v1/types/error.py index 3a80492b6c88..3e2c9f4ded5a 100644 --- a/packages/google-ads-datamanager/google/ads/datamanager_v1/types/error.py +++ b/packages/google-ads-datamanager/google/ads/datamanager_v1/types/error.py @@ -133,7 +133,9 @@ class ErrorReason(proto.Enum): authorization. NO_IDENTIFIERS_PROVIDED (39): Events data contains no user identifiers or - ad identifiers. + ad identifiers. For Floodlight Event ingestion + this error indicates requests contains no ad + identifiers. INVALID_PROPERTY_TYPE (40): The property type is not supported. INVALID_STREAM_TYPE (41): diff --git a/packages/google-ads-datamanager/google/ads/datamanager_v1/types/ingestion_service.py b/packages/google-ads-datamanager/google/ads/datamanager_v1/types/ingestion_service.py index a11e26292e31..6083231519fd 100644 --- a/packages/google-ads-datamanager/google/ads/datamanager_v1/types/ingestion_service.py +++ b/packages/google-ads-datamanager/google/ads/datamanager_v1/types/ingestion_service.py @@ -19,7 +19,7 @@ import proto # type: ignore -from google.ads.datamanager_v1.types import audience, destination, event +from google.ads.datamanager_v1.types import ad_event, audience, destination, event from google.ads.datamanager_v1.types import consent as gad_consent from google.ads.datamanager_v1.types import encryption_info as gad_encryption_info from google.ads.datamanager_v1.types import ( @@ -37,6 +37,8 @@ "RemoveAudienceMembersResponse", "IngestEventsRequest", "IngestEventsResponse", + "IngestAdEventsRequest", + "IngestAdEventsResponse", "RetrieveRequestStatusRequest", "RetrieveRequestStatusResponse", }, @@ -313,6 +315,41 @@ class IngestEventsResponse(proto.Message): ) +class IngestAdEventsRequest(proto.Message): + r"""Request to upload ad events. + + Attributes: + ad_events (MutableSequence[google.ads.datamanager_v1.types.AdEvent]): + Required. Required (at least 1). A list of ad + events. + encryption_info (google.ads.datamanager_v1.types.EncryptionInfo): + Optional. Information about encryption keys + which are used to encrypt the data. + validate_only (bool): + Optional. If true, the request is validated, + but not executed. + """ + + ad_events: MutableSequence[ad_event.AdEvent] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=ad_event.AdEvent, + ) + encryption_info: gad_encryption_info.EncryptionInfo = proto.Field( + proto.MESSAGE, + number=2, + message=gad_encryption_info.EncryptionInfo, + ) + validate_only: bool = proto.Field( + proto.BOOL, + number=3, + ) + + +class IngestAdEventsResponse(proto.Message): + r"""Response from an ad event ingestion operation.""" + + class RetrieveRequestStatusRequest(proto.Message): r"""Request to get the status of request made to the DM API for a given request ID. Returns a diff --git a/packages/google-ads-datamanager/google/ads/datamanager_v1/types/partner_link_service.py b/packages/google-ads-datamanager/google/ads/datamanager_v1/types/partner_link_service.py index 727880115aa4..0f8360d9c779 100644 --- a/packages/google-ads-datamanager/google/ads/datamanager_v1/types/partner_link_service.py +++ b/packages/google-ads-datamanager/google/ads/datamanager_v1/types/partner_link_service.py @@ -24,15 +24,39 @@ __protobuf__ = proto.module( package="google.ads.datamanager.v1", manifest={ + "FeatureSet", "CreatePartnerLinkRequest", "DeletePartnerLinkRequest", "SearchPartnerLinksRequest", "SearchPartnerLinksResponse", "PartnerLink", + "PartnerCustomerAccount", + "PartnerLinkMetadata", }, ) +class FeatureSet(proto.Enum): + r"""The set of supported features for a partner link. + + Values: + FEATURE_SET_UNSPECIFIED (0): + Unspecified feature set. If unspecified, the system behavior + defaults to + [FEATURE_SET_AUDIENCE_AND_EVENT_MANAGEMENT][google.ads.datamanager.v1.FeatureSet.FEATURE_SET_AUDIENCE_AND_EVENT_MANAGEMENT]. + FEATURE_SET_AUDIENCE_AND_EVENT_MANAGEMENT (1): + Indicates a link used for audience and event + management. + FEATURE_SET_AD_EVENT_MANAGEMENT (2): + Indicates a link used for ad event + management. + """ + + FEATURE_SET_UNSPECIFIED = 0 + FEATURE_SET_AUDIENCE_AND_EVENT_MANAGEMENT = 1 + FEATURE_SET_AD_EVENT_MANAGEMENT = 2 + + class CreatePartnerLinkRequest(proto.Message): r"""Request to create a [PartnerLink][google.ads.datamanager.v1.PartnerLink] resource. @@ -193,6 +217,20 @@ class PartnerLink(proto.Message): partner_account (google.ads.datamanager_v1.types.ProductAccount): Required. The partner account granted access by the owning account. + feature_set (google.ads.datamanager_v1.types.FeatureSet): + Optional. Immutable. The set of features supported for the + partner link. If not specified, the system behavior defaults + to + [FEATURE_SET_AUDIENCE_AND_EVENT_MANAGEMENT][google.ads.datamanager.v1.FeatureSet.FEATURE_SET_AUDIENCE_AND_EVENT_MANAGEMENT]. + partner_customer_account (google.ads.datamanager_v1.types.PartnerCustomerAccount): + Optional. The customer account in the partner system. This + is required for partner links with the + [FEATURE_SET_AD_EVENT_MANAGEMENT][google.ads.datamanager.v1.FeatureSet.FEATURE_SET_AD_EVENT_MANAGEMENT] + feature set. + partner_link_metadata (google.ads.datamanager_v1.types.PartnerLinkMetadata): + Optional. Metadata associated with the partner link. This is + optional and only accepted for partner links with the + [FEATURE_SET_AD_EVENT_MANAGEMENT][google.ads.datamanager.v1.FeatureSet.FEATURE_SET_AD_EVENT_MANAGEMENT]. """ name: str = proto.Field( @@ -213,6 +251,65 @@ class PartnerLink(proto.Message): number=4, message=destination.ProductAccount, ) + feature_set: "FeatureSet" = proto.Field( + proto.ENUM, + number=5, + enum="FeatureSet", + ) + partner_customer_account: "PartnerCustomerAccount" = proto.Field( + proto.MESSAGE, + number=6, + message="PartnerCustomerAccount", + ) + partner_link_metadata: "PartnerLinkMetadata" = proto.Field( + proto.MESSAGE, + number=7, + message="PartnerLinkMetadata", + ) + + +class PartnerCustomerAccount(proto.Message): + r"""Represents a customer account in the partner's system. + + Attributes: + account_id (str): + Required. The identifier of the customer + account in the partner's ID space. + account_name (str): + Optional. The name of the account. + account_type (str): + Optional. The type of the account. Can be + used to distinguish between advertiser accounts + and business level accounts, for example. + """ + + account_id: str = proto.Field( + proto.STRING, + number=1, + ) + account_name: str = proto.Field( + proto.STRING, + number=2, + ) + account_type: str = proto.Field( + proto.STRING, + number=3, + ) + + +class PartnerLinkMetadata(proto.Message): + r"""Represents metadata associated with a partner link. + + Attributes: + implicit_accounts (MutableSequence[google.ads.datamanager_v1.types.PartnerCustomerAccount]): + Optional. The list of implicit accounts. + """ + + implicit_accounts: MutableSequence["PartnerCustomerAccount"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="PartnerCustomerAccount", + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-datamanager/google/ads/datamanager_v1/types/viewability_info.py b/packages/google-ads-datamanager/google/ads/datamanager_v1/types/viewability_info.py new file mode 100644 index 000000000000..2c5cb59d5b7b --- /dev/null +++ b/packages/google-ads-datamanager/google/ads/datamanager_v1/types/viewability_info.py @@ -0,0 +1,145 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import google.protobuf.duration_pb2 as duration_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.ads.datamanager.v1", + manifest={ + "ViewType", + "MediaQuartile", + "ViewabilityInfo", + }, +) + + +class ViewType(proto.Enum): + r"""The type of the event. + + Values: + VIEW_TYPE_UNSPECIFIED (0): + Unspecified view type. + VIEW_TYPE_MRC_VIEWED (1): + MRC viewed. + VIEW_TYPE_MRC_RENDERED (2): + MRC rendered. + """ + + VIEW_TYPE_UNSPECIFIED = 0 + VIEW_TYPE_MRC_VIEWED = 1 + VIEW_TYPE_MRC_RENDERED = 2 + + +class MediaQuartile(proto.Enum): + r"""The amount of the media that was played as discrete + quartiles. + + Values: + MEDIA_QUARTILE_UNSPECIFIED (0): + Unspecified media quartile. + MEDIA_QUARTILE_START (1): + Start. + MEDIA_QUARTILE_FIRST_QUARTILE (2): + First quartile. + MEDIA_QUARTILE_MIDPOINT (3): + Midpoint. + MEDIA_QUARTILE_THIRD_QUARTILE (4): + Third quartile. + MEDIA_QUARTILE_COMPLETE (5): + Complete. + """ + + MEDIA_QUARTILE_UNSPECIFIED = 0 + MEDIA_QUARTILE_START = 1 + MEDIA_QUARTILE_FIRST_QUARTILE = 2 + MEDIA_QUARTILE_MIDPOINT = 3 + MEDIA_QUARTILE_THIRD_QUARTILE = 4 + MEDIA_QUARTILE_COMPLETE = 5 + + +class ViewabilityInfo(proto.Message): + r"""Details of the viewability of the ad served. + + Attributes: + view_type (google.ads.datamanager_v1.types.ViewType): + Required. The type of the event. + viewable_percent (int): + Optional. The numerical percent (0-100) of + the pixels that were viewable. + viewable_duration (google.protobuf.duration_pb2.Duration): + Optional. The amount of time the ad was + viewable for. + media_skippable (bool): + Optional. Whether the ad media was skippable + or not. + media_quartile (google.ads.datamanager_v1.types.MediaQuartile): + Optional. The amount of the media that was + played as discrete quartiles. + media_duration (google.protobuf.duration_pb2.Duration): + Optional. The duration of the ad media. + media_volume_percent (int): + Optional. The numerical percent (0-100) of + the volume of the media playback. + playback_duration (google.protobuf.duration_pb2.Duration): + Optional. The duration of playback of the ad + media, regardless of whether it was viewable or + not. + """ + + view_type: "ViewType" = proto.Field( + proto.ENUM, + number=1, + enum="ViewType", + ) + viewable_percent: int = proto.Field( + proto.INT32, + number=2, + ) + viewable_duration: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=3, + message=duration_pb2.Duration, + ) + media_skippable: bool = proto.Field( + proto.BOOL, + number=4, + ) + media_quartile: "MediaQuartile" = proto.Field( + proto.ENUM, + number=5, + enum="MediaQuartile", + ) + media_duration: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=6, + message=duration_pb2.Duration, + ) + media_volume_percent: int = proto.Field( + proto.INT32, + number=7, + ) + playback_duration: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=8, + message=duration_pb2.Duration, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_ingest_ad_events_async.py b/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_ingest_ad_events_async.py new file mode 100644 index 000000000000..46c9a73da5c6 --- /dev/null +++ b/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_ingest_ad_events_async.py @@ -0,0 +1,70 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for IngestAdEvents +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-datamanager + + +# [START datamanager_v1_generated_IngestionService_IngestAdEvents_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import datamanager_v1 + + +async def sample_ingest_ad_events(): + # Create a client + client = datamanager_v1.IngestionServiceAsyncClient() + + # Initialize request argument(s) + ad_events = datamanager_v1.AdEvent() + ad_events.event_subtype = "EVENT_SUBTYPE_OUTBOUND_CLICK" + ad_events.ad_type = "AD_TYPE_VIDEO" + ad_events.ad_format = "AD_FORMAT_VIDEO" + ad_events.ad_placement = "AD_PLACEMENT_STORY" + ad_events.targeting_type = "TARGETING_TYPE_REMARKETING" + ad_events.platform_type = "PLATFORM_TYPE_TABLET" + ad_events.platform = "PLATFORM_WEB" + ad_events.advertiser_id = "advertiser_id_value" + ad_events.event_type = "EVENT_TYPE_CLICK" + ad_events.campaign_id = "campaign_id_value" + ad_events.campaign_name = "campaign_name_value" + ad_events.region_code = "region_code_value" + ad_events.source = "source_value" + ad_events.medium = "medium_value" + ad_events.viewability_info.view_type = "VIEW_TYPE_MRC_RENDERED" + + request = datamanager_v1.IngestAdEventsRequest( + ad_events=ad_events, + ) + + # Make the request + response = await client.ingest_ad_events(request=request) + + # Handle the response + print(response) + + +# [END datamanager_v1_generated_IngestionService_IngestAdEvents_async] diff --git a/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_ingest_ad_events_sync.py b/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_ingest_ad_events_sync.py new file mode 100644 index 000000000000..4ed2a906cec8 --- /dev/null +++ b/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_ingest_ad_events_sync.py @@ -0,0 +1,70 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for IngestAdEvents +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-datamanager + + +# [START datamanager_v1_generated_IngestionService_IngestAdEvents_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import datamanager_v1 + + +def sample_ingest_ad_events(): + # Create a client + client = datamanager_v1.IngestionServiceClient() + + # Initialize request argument(s) + ad_events = datamanager_v1.AdEvent() + ad_events.event_subtype = "EVENT_SUBTYPE_OUTBOUND_CLICK" + ad_events.ad_type = "AD_TYPE_VIDEO" + ad_events.ad_format = "AD_FORMAT_VIDEO" + ad_events.ad_placement = "AD_PLACEMENT_STORY" + ad_events.targeting_type = "TARGETING_TYPE_REMARKETING" + ad_events.platform_type = "PLATFORM_TYPE_TABLET" + ad_events.platform = "PLATFORM_WEB" + ad_events.advertiser_id = "advertiser_id_value" + ad_events.event_type = "EVENT_TYPE_CLICK" + ad_events.campaign_id = "campaign_id_value" + ad_events.campaign_name = "campaign_name_value" + ad_events.region_code = "region_code_value" + ad_events.source = "source_value" + ad_events.medium = "medium_value" + ad_events.viewability_info.view_type = "VIEW_TYPE_MRC_RENDERED" + + request = datamanager_v1.IngestAdEventsRequest( + ad_events=ad_events, + ) + + # Make the request + response = client.ingest_ad_events(request=request) + + # Handle the response + print(response) + + +# [END datamanager_v1_generated_IngestionService_IngestAdEvents_sync] diff --git a/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_ingest_audience_members_async.py b/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_ingest_audience_members_async.py index d3d68a8377ca..d3ca2dce6215 100644 --- a/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_ingest_audience_members_async.py +++ b/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_ingest_audience_members_async.py @@ -41,6 +41,7 @@ async def sample_ingest_audience_members(): # Initialize request argument(s) destinations = datamanager_v1.Destination() destinations.operating_account.account_id = "account_id_value" + destinations.operating_account.account_type = "FLOODLIGHT_CONFIG" destinations.product_destination_id = "product_destination_id_value" audience_members = datamanager_v1.AudienceMember() diff --git a/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_ingest_audience_members_sync.py b/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_ingest_audience_members_sync.py index 7de1d5b46040..2250290d10b4 100644 --- a/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_ingest_audience_members_sync.py +++ b/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_ingest_audience_members_sync.py @@ -41,6 +41,7 @@ def sample_ingest_audience_members(): # Initialize request argument(s) destinations = datamanager_v1.Destination() destinations.operating_account.account_id = "account_id_value" + destinations.operating_account.account_type = "FLOODLIGHT_CONFIG" destinations.product_destination_id = "product_destination_id_value" audience_members = datamanager_v1.AudienceMember() diff --git a/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_ingest_events_async.py b/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_ingest_events_async.py index 207690c0aeac..f85295c2ba13 100644 --- a/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_ingest_events_async.py +++ b/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_ingest_events_async.py @@ -41,6 +41,7 @@ async def sample_ingest_events(): # Initialize request argument(s) destinations = datamanager_v1.Destination() destinations.operating_account.account_id = "account_id_value" + destinations.operating_account.account_type = "FLOODLIGHT_CONFIG" destinations.product_destination_id = "product_destination_id_value" request = datamanager_v1.IngestEventsRequest( diff --git a/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_ingest_events_sync.py b/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_ingest_events_sync.py index fe1ce62c6d29..855ecf9cff19 100644 --- a/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_ingest_events_sync.py +++ b/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_ingest_events_sync.py @@ -41,6 +41,7 @@ def sample_ingest_events(): # Initialize request argument(s) destinations = datamanager_v1.Destination() destinations.operating_account.account_id = "account_id_value" + destinations.operating_account.account_type = "FLOODLIGHT_CONFIG" destinations.product_destination_id = "product_destination_id_value" request = datamanager_v1.IngestEventsRequest( diff --git a/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_remove_audience_members_async.py b/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_remove_audience_members_async.py index fcb903557616..1fb0bf52b857 100644 --- a/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_remove_audience_members_async.py +++ b/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_remove_audience_members_async.py @@ -41,6 +41,7 @@ async def sample_remove_audience_members(): # Initialize request argument(s) destinations = datamanager_v1.Destination() destinations.operating_account.account_id = "account_id_value" + destinations.operating_account.account_type = "FLOODLIGHT_CONFIG" destinations.product_destination_id = "product_destination_id_value" audience_members = datamanager_v1.AudienceMember() diff --git a/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_remove_audience_members_sync.py b/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_remove_audience_members_sync.py index 0256f6628c54..b90028e39d52 100644 --- a/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_remove_audience_members_sync.py +++ b/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_ingestion_service_remove_audience_members_sync.py @@ -41,6 +41,7 @@ def sample_remove_audience_members(): # Initialize request argument(s) destinations = datamanager_v1.Destination() destinations.operating_account.account_id = "account_id_value" + destinations.operating_account.account_type = "FLOODLIGHT_CONFIG" destinations.product_destination_id = "product_destination_id_value" audience_members = datamanager_v1.AudienceMember() diff --git a/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_partner_link_service_create_partner_link_async.py b/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_partner_link_service_create_partner_link_async.py index 340fd349b76e..f1f85560d7ef 100644 --- a/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_partner_link_service_create_partner_link_async.py +++ b/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_partner_link_service_create_partner_link_async.py @@ -41,7 +41,9 @@ async def sample_create_partner_link(): # Initialize request argument(s) partner_link = datamanager_v1.PartnerLink() partner_link.owning_account.account_id = "account_id_value" + partner_link.owning_account.account_type = "FLOODLIGHT_CONFIG" partner_link.partner_account.account_id = "account_id_value" + partner_link.partner_account.account_type = "FLOODLIGHT_CONFIG" request = datamanager_v1.CreatePartnerLinkRequest( parent="parent_value", diff --git a/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_partner_link_service_create_partner_link_sync.py b/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_partner_link_service_create_partner_link_sync.py index 4e48718c3aa9..623f21b963cf 100644 --- a/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_partner_link_service_create_partner_link_sync.py +++ b/packages/google-ads-datamanager/samples/generated_samples/datamanager_v1_generated_partner_link_service_create_partner_link_sync.py @@ -41,7 +41,9 @@ def sample_create_partner_link(): # Initialize request argument(s) partner_link = datamanager_v1.PartnerLink() partner_link.owning_account.account_id = "account_id_value" + partner_link.owning_account.account_type = "FLOODLIGHT_CONFIG" partner_link.partner_account.account_id = "account_id_value" + partner_link.partner_account.account_type = "FLOODLIGHT_CONFIG" request = datamanager_v1.CreatePartnerLinkRequest( parent="parent_value", diff --git a/packages/google-ads-datamanager/samples/generated_samples/snippet_metadata_google.ads.datamanager.v1.json b/packages/google-ads-datamanager/samples/generated_samples/snippet_metadata_google.ads.datamanager.v1.json index edbf7d3b3841..747067e4d585 100644 --- a/packages/google-ads-datamanager/samples/generated_samples/snippet_metadata_google.ads.datamanager.v1.json +++ b/packages/google-ads-datamanager/samples/generated_samples/snippet_metadata_google.ads.datamanager.v1.json @@ -11,6 +11,159 @@ "version": "0.9.0" }, "snippets": [ + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.ads.datamanager_v1.IngestionServiceAsyncClient", + "shortName": "IngestionServiceAsyncClient" + }, + "fullName": "google.ads.datamanager_v1.IngestionServiceAsyncClient.ingest_ad_events", + "method": { + "fullName": "google.ads.datamanager.v1.IngestionService.IngestAdEvents", + "service": { + "fullName": "google.ads.datamanager.v1.IngestionService", + "shortName": "IngestionService" + }, + "shortName": "IngestAdEvents" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.datamanager_v1.types.IngestAdEventsRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.datamanager_v1.types.IngestAdEventsResponse", + "shortName": "ingest_ad_events" + }, + "description": "Sample for IngestAdEvents", + "file": "datamanager_v1_generated_ingestion_service_ingest_ad_events_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "datamanager_v1_generated_IngestionService_IngestAdEvents_async", + "segments": [ + { + "end": 68, + "start": 27, + "type": "FULL" + }, + { + "end": 68, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 62, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 65, + "start": 63, + "type": "REQUEST_EXECUTION" + }, + { + "end": 69, + "start": 66, + "type": "RESPONSE_HANDLING" + } + ], + "title": "datamanager_v1_generated_ingestion_service_ingest_ad_events_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.datamanager_v1.IngestionServiceClient", + "shortName": "IngestionServiceClient" + }, + "fullName": "google.ads.datamanager_v1.IngestionServiceClient.ingest_ad_events", + "method": { + "fullName": "google.ads.datamanager.v1.IngestionService.IngestAdEvents", + "service": { + "fullName": "google.ads.datamanager.v1.IngestionService", + "shortName": "IngestionService" + }, + "shortName": "IngestAdEvents" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.datamanager_v1.types.IngestAdEventsRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.datamanager_v1.types.IngestAdEventsResponse", + "shortName": "ingest_ad_events" + }, + "description": "Sample for IngestAdEvents", + "file": "datamanager_v1_generated_ingestion_service_ingest_ad_events_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "datamanager_v1_generated_IngestionService_IngestAdEvents_sync", + "segments": [ + { + "end": 68, + "start": 27, + "type": "FULL" + }, + { + "end": 68, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 62, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 65, + "start": 63, + "type": "REQUEST_EXECUTION" + }, + { + "end": 69, + "start": 66, + "type": "RESPONSE_HANDLING" + } + ], + "title": "datamanager_v1_generated_ingestion_service_ingest_ad_events_sync.py" + }, { "canonical": true, "clientMethod": { @@ -56,12 +209,12 @@ "regionTag": "datamanager_v1_generated_IngestionService_IngestAudienceMembers_async", "segments": [ { - "end": 59, + "end": 60, "start": 27, "type": "FULL" }, { - "end": 59, + "end": 60, "start": 27, "type": "SHORT" }, @@ -71,18 +224,18 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 53, + "end": 54, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 56, - "start": 54, + "end": 57, + "start": 55, "type": "REQUEST_EXECUTION" }, { - "end": 60, - "start": 57, + "end": 61, + "start": 58, "type": "RESPONSE_HANDLING" } ], @@ -132,12 +285,12 @@ "regionTag": "datamanager_v1_generated_IngestionService_IngestAudienceMembers_sync", "segments": [ { - "end": 59, + "end": 60, "start": 27, "type": "FULL" }, { - "end": 59, + "end": 60, "start": 27, "type": "SHORT" }, @@ -147,18 +300,18 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 53, + "end": 54, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 56, - "start": 54, + "end": 57, + "start": 55, "type": "REQUEST_EXECUTION" }, { - "end": 60, - "start": 57, + "end": 61, + "start": 58, "type": "RESPONSE_HANDLING" } ], @@ -209,12 +362,12 @@ "regionTag": "datamanager_v1_generated_IngestionService_IngestEvents_async", "segments": [ { - "end": 55, + "end": 56, "start": 27, "type": "FULL" }, { - "end": 55, + "end": 56, "start": 27, "type": "SHORT" }, @@ -224,18 +377,18 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 49, + "end": 50, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 52, - "start": 50, + "end": 53, + "start": 51, "type": "REQUEST_EXECUTION" }, { - "end": 56, - "start": 53, + "end": 57, + "start": 54, "type": "RESPONSE_HANDLING" } ], @@ -285,12 +438,12 @@ "regionTag": "datamanager_v1_generated_IngestionService_IngestEvents_sync", "segments": [ { - "end": 55, + "end": 56, "start": 27, "type": "FULL" }, { - "end": 55, + "end": 56, "start": 27, "type": "SHORT" }, @@ -300,18 +453,18 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 49, + "end": 50, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 52, - "start": 50, + "end": 53, + "start": 51, "type": "REQUEST_EXECUTION" }, { - "end": 56, - "start": 53, + "end": 57, + "start": 54, "type": "RESPONSE_HANDLING" } ], @@ -362,12 +515,12 @@ "regionTag": "datamanager_v1_generated_IngestionService_RemoveAudienceMembers_async", "segments": [ { - "end": 59, + "end": 60, "start": 27, "type": "FULL" }, { - "end": 59, + "end": 60, "start": 27, "type": "SHORT" }, @@ -377,18 +530,18 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 53, + "end": 54, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 56, - "start": 54, + "end": 57, + "start": 55, "type": "REQUEST_EXECUTION" }, { - "end": 60, - "start": 57, + "end": 61, + "start": 58, "type": "RESPONSE_HANDLING" } ], @@ -438,12 +591,12 @@ "regionTag": "datamanager_v1_generated_IngestionService_RemoveAudienceMembers_sync", "segments": [ { - "end": 59, + "end": 60, "start": 27, "type": "FULL" }, { - "end": 59, + "end": 60, "start": 27, "type": "SHORT" }, @@ -453,18 +606,18 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 53, + "end": 54, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 56, - "start": 54, + "end": 57, + "start": 55, "type": "REQUEST_EXECUTION" }, { - "end": 60, - "start": 57, + "end": 61, + "start": 58, "type": "RESPONSE_HANDLING" } ], @@ -829,12 +982,12 @@ "regionTag": "datamanager_v1_generated_PartnerLinkService_CreatePartnerLink_async", "segments": [ { - "end": 56, + "end": 58, "start": 27, "type": "FULL" }, { - "end": 56, + "end": 58, "start": 27, "type": "SHORT" }, @@ -844,18 +997,18 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 50, + "end": 52, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 53, - "start": 51, + "end": 55, + "start": 53, "type": "REQUEST_EXECUTION" }, { - "end": 57, - "start": 54, + "end": 59, + "start": 56, "type": "RESPONSE_HANDLING" } ], @@ -913,12 +1066,12 @@ "regionTag": "datamanager_v1_generated_PartnerLinkService_CreatePartnerLink_sync", "segments": [ { - "end": 56, + "end": 58, "start": 27, "type": "FULL" }, { - "end": 56, + "end": 58, "start": 27, "type": "SHORT" }, @@ -928,18 +1081,18 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 50, + "end": 52, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 53, - "start": 51, + "end": 55, + "start": 53, "type": "REQUEST_EXECUTION" }, { - "end": 57, - "start": 54, + "end": 59, + "start": 56, "type": "RESPONSE_HANDLING" } ], diff --git a/packages/google-ads-datamanager/tests/unit/gapic/datamanager_v1/test_ingestion_service.py b/packages/google-ads-datamanager/tests/unit/gapic/datamanager_v1/test_ingestion_service.py index dcd7752d8bd6..4c240410032b 100644 --- a/packages/google-ads-datamanager/tests/unit/gapic/datamanager_v1/test_ingestion_service.py +++ b/packages/google-ads-datamanager/tests/unit/gapic/datamanager_v1/test_ingestion_service.py @@ -39,6 +39,7 @@ HAS_GOOGLE_AUTH_AIO = False import google.auth +import google.protobuf.duration_pb2 as duration_pb2 # type: ignore import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore from google.api_core import ( client_options, @@ -59,6 +60,7 @@ transports, ) from google.ads.datamanager_v1.types import ( + ad_event, audience, cart_data, consent, @@ -74,6 +76,7 @@ terms_of_service, user_data, user_properties, + viewability_info, ) CRED_INFO_JSON = { @@ -1926,6 +1929,179 @@ async def test_ingest_events_async(request_type, transport: str = "grpc_asyncio" assert response.request_id == "request_id_value" +@pytest.mark.parametrize( + "request_type", + [ + ingestion_service.IngestAdEventsRequest(), + {}, + ], +) +def test_ingest_ad_events(request_type, transport: str = "grpc"): + client = IngestionServiceClient( + 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.ingest_ad_events), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = ingestion_service.IngestAdEventsResponse() + response = client.ingest_ad_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = ingestion_service.IngestAdEventsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, ingestion_service.IngestAdEventsResponse) + + +def test_ingest_ad_events_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = IngestionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = ingestion_service.IngestAdEventsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.ingest_ad_events), "__call__") as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.ingest_ad_events(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ingestion_service.IngestAdEventsRequest() + assert args[0] == request_msg + + +def test_ingest_ad_events_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = IngestionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.ingest_ad_events in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.ingest_ad_events] = ( + mock_rpc + ) + request = {} + client.ingest_ad_events(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.ingest_ad_events(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_ingest_ad_events_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = IngestionServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.ingest_ad_events + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.ingest_ad_events + ] = mock_rpc + + request = {} + await client.ingest_ad_events(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.ingest_ad_events(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + ingestion_service.IngestAdEventsRequest(), + {}, + ], +) +async def test_ingest_ad_events_async(request_type, transport: str = "grpc_asyncio"): + client = IngestionServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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.ingest_ad_events), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + ingestion_service.IngestAdEventsResponse() + ) + response = await client.ingest_ad_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = ingestion_service.IngestAdEventsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, ingestion_service.IngestAdEventsResponse) + + @pytest.mark.parametrize( "request_type", [ @@ -2500,6 +2676,124 @@ def test_ingest_events_rest_unset_required_fields(): ) +def test_ingest_ad_events_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = IngestionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.ingest_ad_events in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.ingest_ad_events] = ( + mock_rpc + ) + + request = {} + client.ingest_ad_events(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.ingest_ad_events(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_ingest_ad_events_rest_required_fields( + request_type=ingestion_service.IngestAdEventsRequest, +): + transport_class = transports.IngestionServiceRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).ingest_ad_events._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).ingest_ad_events._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = IngestionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = ingestion_service.IngestAdEventsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = ingestion_service.IngestAdEventsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.ingest_ad_events(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_ingest_ad_events_rest_unset_required_fields(): + transport = transports.IngestionServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.ingest_ad_events._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("adEvents",))) + + def test_retrieve_request_status_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -2808,6 +3102,26 @@ def test_ingest_events_empty_call_grpc(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_ingest_ad_events_empty_call_grpc(): + client = IngestionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.ingest_ad_events), "__call__") as call: + call.return_value = ingestion_service.IngestAdEventsResponse() + client.ingest_ad_events(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ingestion_service.IngestAdEventsRequest() + assert args[0] == request_msg + + # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. def test_retrieve_request_status_empty_call_grpc(): @@ -2926,6 +3240,30 @@ async def test_ingest_events_empty_call_grpc_asyncio(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_ingest_ad_events_empty_call_grpc_asyncio(): + client = IngestionServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.ingest_ad_events), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + ingestion_service.IngestAdEventsResponse() + ) + await client.ingest_ad_events(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ingestion_service.IngestAdEventsRequest() + assert args[0] == request_msg + + # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @pytest.mark.asyncio @@ -3367,6 +3705,139 @@ def test_ingest_events_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() +def test_ingest_ad_events_rest_bad_request( + request_type=ingestion_service.IngestAdEventsRequest, +): + client = IngestionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.ingest_ad_events(request) + + +@pytest.mark.parametrize( + "request_type", + [ + ingestion_service.IngestAdEventsRequest, + dict, + ], +) +def test_ingest_ad_events_rest_call_success(request_type): + client = IngestionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = ingestion_service.IngestAdEventsResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = ingestion_service.IngestAdEventsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.ingest_ad_events(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, ingestion_service.IngestAdEventsResponse) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_ingest_ad_events_rest_interceptors(null_interceptor): + transport = transports.IngestionServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.IngestionServiceRestInterceptor(), + ) + client = IngestionServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.IngestionServiceRestInterceptor, "post_ingest_ad_events" + ) as post, + mock.patch.object( + transports.IngestionServiceRestInterceptor, + "post_ingest_ad_events_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.IngestionServiceRestInterceptor, "pre_ingest_ad_events" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = ingestion_service.IngestAdEventsRequest.pb( + ingestion_service.IngestAdEventsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = ingestion_service.IngestAdEventsResponse.to_json( + ingestion_service.IngestAdEventsResponse() + ) + req.return_value.content = return_value + + request = ingestion_service.IngestAdEventsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = ingestion_service.IngestAdEventsResponse() + post_with_metadata.return_value = ( + ingestion_service.IngestAdEventsResponse(), + metadata, + ) + + client.ingest_ad_events( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + def test_retrieve_request_status_rest_bad_request( request_type=ingestion_service.RetrieveRequestStatusRequest, ): @@ -3568,6 +4039,25 @@ def test_ingest_events_empty_call_rest(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_ingest_ad_events_empty_call_rest(): + client = IngestionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.ingest_ad_events), "__call__") as call: + client.ingest_ad_events(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ingestion_service.IngestAdEventsRequest() + assert args[0] == request_msg + + # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. def test_retrieve_request_status_empty_call_rest(): @@ -3625,6 +4115,7 @@ def test_ingestion_service_base_transport(): "ingest_audience_members", "remove_audience_members", "ingest_events", + "ingest_ad_events", "retrieve_request_status", ) for method in methods: @@ -3900,6 +4391,9 @@ def test_ingestion_service_client_transport_session_collision(transport_name): session1 = client1.transport.ingest_events._session session2 = client2.transport.ingest_events._session assert session1 != session2 + session1 = client1.transport.ingest_ad_events._session + session2 = client2.transport.ingest_ad_events._session + assert session1 != session2 session1 = client1.transport.retrieve_request_status._session session2 = client2.transport.retrieve_request_status._session assert session1 != session2 diff --git a/packages/google-ads-datamanager/tests/unit/gapic/datamanager_v1/test_partner_link_service.py b/packages/google-ads-datamanager/tests/unit/gapic/datamanager_v1/test_partner_link_service.py index 16822b897a91..aae69c55e38b 100644 --- a/packages/google-ads-datamanager/tests/unit/gapic/datamanager_v1/test_partner_link_service.py +++ b/packages/google-ads-datamanager/tests/unit/gapic/datamanager_v1/test_partner_link_service.py @@ -1393,6 +1393,7 @@ def test_create_partner_link(request_type, transport: str = "grpc"): call.return_value = partner_link_service.PartnerLink( name="name_value", partner_link_id="partner_link_id_value", + feature_set=partner_link_service.FeatureSet.FEATURE_SET_AUDIENCE_AND_EVENT_MANAGEMENT, ) response = client.create_partner_link(request) @@ -1406,6 +1407,10 @@ def test_create_partner_link(request_type, transport: str = "grpc"): assert isinstance(response, partner_link_service.PartnerLink) assert response.name == "name_value" assert response.partner_link_id == "partner_link_id_value" + assert ( + response.feature_set + == partner_link_service.FeatureSet.FEATURE_SET_AUDIENCE_AND_EVENT_MANAGEMENT + ) def test_create_partner_link_non_empty_request_with_auto_populated_field(): @@ -1547,6 +1552,7 @@ async def test_create_partner_link_async(request_type, transport: str = "grpc_as partner_link_service.PartnerLink( name="name_value", partner_link_id="partner_link_id_value", + feature_set=partner_link_service.FeatureSet.FEATURE_SET_AUDIENCE_AND_EVENT_MANAGEMENT, ) ) response = await client.create_partner_link(request) @@ -1561,6 +1567,10 @@ async def test_create_partner_link_async(request_type, transport: str = "grpc_as assert isinstance(response, partner_link_service.PartnerLink) assert response.name == "name_value" assert response.partner_link_id == "partner_link_id_value" + assert ( + response.feature_set + == partner_link_service.FeatureSet.FEATURE_SET_AUDIENCE_AND_EVENT_MANAGEMENT + ) def test_create_partner_link_field_headers(): @@ -3440,6 +3450,7 @@ async def test_create_partner_link_empty_call_grpc_asyncio(): partner_link_service.PartnerLink( name="name_value", partner_link_id="partner_link_id_value", + feature_set=partner_link_service.FeatureSet.FEATURE_SET_AUDIENCE_AND_EVENT_MANAGEMENT, ) ) await client.create_partner_link(request=None) @@ -3559,6 +3570,13 @@ def test_create_partner_link_rest_call_success(request_type): "account_type": 1, }, "partner_account": {}, + "feature_set": 1, + "partner_customer_account": { + "account_id": "account_id_value", + "account_name": "account_name_value", + "account_type": "account_type_value", + }, + "partner_link_metadata": {"implicit_accounts": {}}, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -3637,6 +3655,7 @@ def get_message_fields(field): return_value = partner_link_service.PartnerLink( name="name_value", partner_link_id="partner_link_id_value", + feature_set=partner_link_service.FeatureSet.FEATURE_SET_AUDIENCE_AND_EVENT_MANAGEMENT, ) # Wrap the value into a proper Response obj @@ -3655,6 +3674,10 @@ def get_message_fields(field): assert isinstance(response, partner_link_service.PartnerLink) assert response.name == "name_value" assert response.partner_link_id == "partner_link_id_value" + assert ( + response.feature_set + == partner_link_service.FeatureSet.FEATURE_SET_AUDIENCE_AND_EVENT_MANAGEMENT + ) @pytest.mark.parametrize("null_interceptor", [True, False]) diff --git a/packages/google-analytics-admin/google/analytics/admin/__init__.py b/packages/google-analytics-admin/google/analytics/admin/__init__.py index de58c7221942..53ca940df65d 100644 --- a/packages/google-analytics-admin/google/analytics/admin/__init__.py +++ b/packages/google-analytics-admin/google/analytics/admin/__init__.py @@ -236,6 +236,7 @@ UpdateMeasurementProtocolSecretRequest, UpdatePropertyRequest, UpdateReportingDataAnnotationRequest, + UpdateReportingIdentitySettingsRequest, UpdateSearchAds360LinkRequest, UpdateSKAdNetworkConversionValueSchemaRequest, UpdateSubpropertyEventFilterRequest, @@ -543,6 +544,7 @@ "UpdateMeasurementProtocolSecretRequest", "UpdatePropertyRequest", "UpdateReportingDataAnnotationRequest", + "UpdateReportingIdentitySettingsRequest", "UpdateSearchAds360LinkRequest", "UpdateSKAdNetworkConversionValueSchemaRequest", "UpdateSubpropertyEventFilterRequest", diff --git a/packages/google-analytics-admin/google/analytics/admin_v1alpha/__init__.py b/packages/google-analytics-admin/google/analytics/admin_v1alpha/__init__.py index d5044effcba8..c3bb19a1a3c0 100644 --- a/packages/google-analytics-admin/google/analytics/admin_v1alpha/__init__.py +++ b/packages/google-analytics-admin/google/analytics/admin_v1alpha/__init__.py @@ -239,6 +239,7 @@ UpdateMeasurementProtocolSecretRequest, UpdatePropertyRequest, UpdateReportingDataAnnotationRequest, + UpdateReportingIdentitySettingsRequest, UpdateSearchAds360LinkRequest, UpdateSKAdNetworkConversionValueSchemaRequest, UpdateSubpropertyEventFilterRequest, @@ -705,6 +706,7 @@ def _get_version(dependency_name): "UpdateMeasurementProtocolSecretRequest", "UpdatePropertyRequest", "UpdateReportingDataAnnotationRequest", + "UpdateReportingIdentitySettingsRequest", "UpdateSKAdNetworkConversionValueSchemaRequest", "UpdateSearchAds360LinkRequest", "UpdateSubpropertyEventFilterRequest", diff --git a/packages/google-analytics-admin/google/analytics/admin_v1alpha/gapic_metadata.json b/packages/google-analytics-admin/google/analytics/admin_v1alpha/gapic_metadata.json index 85e5a17017d0..5a249f54d896 100644 --- a/packages/google-analytics-admin/google/analytics/admin_v1alpha/gapic_metadata.json +++ b/packages/google-analytics-admin/google/analytics/admin_v1alpha/gapic_metadata.json @@ -765,6 +765,11 @@ "update_reporting_data_annotation" ] }, + "UpdateReportingIdentitySettings": { + "methods": [ + "update_reporting_identity_settings" + ] + }, "UpdateSKAdNetworkConversionValueSchema": { "methods": [ "update_sk_ad_network_conversion_value_schema" @@ -1545,6 +1550,11 @@ "update_reporting_data_annotation" ] }, + "UpdateReportingIdentitySettings": { + "methods": [ + "update_reporting_identity_settings" + ] + }, "UpdateSKAdNetworkConversionValueSchema": { "methods": [ "update_sk_ad_network_conversion_value_schema" @@ -2325,6 +2335,11 @@ "update_reporting_data_annotation" ] }, + "UpdateReportingIdentitySettings": { + "methods": [ + "update_reporting_identity_settings" + ] + }, "UpdateSKAdNetworkConversionValueSchema": { "methods": [ "update_sk_ad_network_conversion_value_schema" diff --git a/packages/google-analytics-admin/google/analytics/admin_v1alpha/services/analytics_admin_service/async_client.py b/packages/google-analytics-admin/google/analytics/admin_v1alpha/services/analytics_admin_service/async_client.py index 8fbc539b8990..a8bdb143f9e4 100644 --- a/packages/google-analytics-admin/google/analytics/admin_v1alpha/services/analytics_admin_service/async_client.py +++ b/packages/google-analytics-admin/google/analytics/admin_v1alpha/services/analytics_admin_service/async_client.py @@ -14759,6 +14759,121 @@ async def get_reporting_identity_settings( # Done; return the response. return response + async def update_reporting_identity_settings( + self, + request: Optional[ + Union[analytics_admin.UpdateReportingIdentitySettingsRequest, dict] + ] = None, + *, + reporting_identity_settings: Optional[ + resources.ReportingIdentitySettings + ] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> resources.ReportingIdentitySettings: + r"""Updates the reporting identity settings for this + property. + + Args: + request (Optional[Union[google.analytics.admin_v1alpha.types.UpdateReportingIdentitySettingsRequest, dict]]): + The request object. Request message for + UpdateReportingIdentitySettings RPC. + reporting_identity_settings (:class:`google.analytics.admin_v1alpha.types.ReportingIdentitySettings`): + Required. The reporting identity settings to update. The + settings' ``name`` field is used to identify the + settings. + + This corresponds to the ``reporting_identity_settings`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Optional. The list of fields to be updated. Field names + must be in snake case (for example, "field_to_update"). + Omitted fields will not be updated. To replace the + entire entity, use one path with the string "\*" to + match all fields. If omitted, the service will treat it + as an implied field mask equivalent to all fields that + are populated. + + 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_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.analytics.admin_v1alpha.types.ReportingIdentitySettings: + A resource containing settings + related to reporting identity. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [reporting_identity_settings, update_mask] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, analytics_admin.UpdateReportingIdentitySettingsRequest + ): + request = analytics_admin.UpdateReportingIdentitySettingsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if reporting_identity_settings is not None: + request.reporting_identity_settings = reporting_identity_settings + 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._client._transport._wrapped_methods[ + self._client._transport.update_reporting_identity_settings + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + ( + ( + "reporting_identity_settings.name", + request.reporting_identity_settings.name, + ), + ) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + async def get_user_provided_data_settings( self, request: Optional[ diff --git a/packages/google-analytics-admin/google/analytics/admin_v1alpha/services/analytics_admin_service/client.py b/packages/google-analytics-admin/google/analytics/admin_v1alpha/services/analytics_admin_service/client.py index a9f002a47a4c..27b9051f4a8c 100644 --- a/packages/google-analytics-admin/google/analytics/admin_v1alpha/services/analytics_admin_service/client.py +++ b/packages/google-analytics-admin/google/analytics/admin_v1alpha/services/analytics_admin_service/client.py @@ -15355,6 +15355,120 @@ def get_reporting_identity_settings( # Done; return the response. return response + def update_reporting_identity_settings( + self, + request: Optional[ + Union[analytics_admin.UpdateReportingIdentitySettingsRequest, dict] + ] = None, + *, + reporting_identity_settings: Optional[ + resources.ReportingIdentitySettings + ] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> resources.ReportingIdentitySettings: + r"""Updates the reporting identity settings for this + property. + + Args: + request (Union[google.analytics.admin_v1alpha.types.UpdateReportingIdentitySettingsRequest, dict]): + The request object. Request message for + UpdateReportingIdentitySettings RPC. + reporting_identity_settings (google.analytics.admin_v1alpha.types.ReportingIdentitySettings): + Required. The reporting identity settings to update. The + settings' ``name`` field is used to identify the + settings. + + This corresponds to the ``reporting_identity_settings`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Optional. The list of fields to be updated. Field names + must be in snake case (for example, "field_to_update"). + Omitted fields will not be updated. To replace the + entire entity, use one path with the string "\*" to + match all fields. If omitted, the service will treat it + as an implied field mask equivalent to all fields that + are populated. + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.analytics.admin_v1alpha.types.ReportingIdentitySettings: + A resource containing settings + related to reporting identity. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [reporting_identity_settings, update_mask] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, analytics_admin.UpdateReportingIdentitySettingsRequest + ): + request = analytics_admin.UpdateReportingIdentitySettingsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if reporting_identity_settings is not None: + request.reporting_identity_settings = reporting_identity_settings + 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_reporting_identity_settings + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + ( + ( + "reporting_identity_settings.name", + request.reporting_identity_settings.name, + ), + ) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + def get_user_provided_data_settings( self, request: Optional[ diff --git a/packages/google-analytics-admin/google/analytics/admin_v1alpha/services/analytics_admin_service/transports/base.py b/packages/google-analytics-admin/google/analytics/admin_v1alpha/services/analytics_admin_service/transports/base.py index a17b0d30eb32..cc36ef0d8f6b 100644 --- a/packages/google-analytics-admin/google/analytics/admin_v1alpha/services/analytics_admin_service/transports/base.py +++ b/packages/google-analytics-admin/google/analytics/admin_v1alpha/services/analytics_admin_service/transports/base.py @@ -934,6 +934,11 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.update_reporting_identity_settings: gapic_v1.method.wrap_method( + self.update_reporting_identity_settings, + default_timeout=None, + client_info=client_info, + ), self.get_user_provided_data_settings: gapic_v1.method.wrap_method( self.get_user_provided_data_settings, default_timeout=None, @@ -2573,6 +2578,18 @@ def get_reporting_identity_settings( ]: raise NotImplementedError() + @property + def update_reporting_identity_settings( + self, + ) -> Callable[ + [analytics_admin.UpdateReportingIdentitySettingsRequest], + Union[ + resources.ReportingIdentitySettings, + Awaitable[resources.ReportingIdentitySettings], + ], + ]: + raise NotImplementedError() + @property def get_user_provided_data_settings( self, diff --git a/packages/google-analytics-admin/google/analytics/admin_v1alpha/services/analytics_admin_service/transports/grpc.py b/packages/google-analytics-admin/google/analytics/admin_v1alpha/services/analytics_admin_service/transports/grpc.py index 3a7d2c6180b6..6c1dc0abdda4 100644 --- a/packages/google-analytics-admin/google/analytics/admin_v1alpha/services/analytics_admin_service/transports/grpc.py +++ b/packages/google-analytics-admin/google/analytics/admin_v1alpha/services/analytics_admin_service/transports/grpc.py @@ -4913,6 +4913,39 @@ def get_reporting_identity_settings( ) return self._stubs["get_reporting_identity_settings"] + @property + def update_reporting_identity_settings( + self, + ) -> Callable[ + [analytics_admin.UpdateReportingIdentitySettingsRequest], + resources.ReportingIdentitySettings, + ]: + r"""Return a callable for the update reporting identity + settings method over gRPC. + + Updates the reporting identity settings for this + property. + + Returns: + Callable[[~.UpdateReportingIdentitySettingsRequest], + ~.ReportingIdentitySettings]: + 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_reporting_identity_settings" not in self._stubs: + self._stubs["update_reporting_identity_settings"] = ( + self._logged_channel.unary_unary( + "/google.analytics.admin.v1alpha.AnalyticsAdminService/UpdateReportingIdentitySettings", + request_serializer=analytics_admin.UpdateReportingIdentitySettingsRequest.serialize, + response_deserializer=resources.ReportingIdentitySettings.deserialize, + ) + ) + return self._stubs["update_reporting_identity_settings"] + @property def get_user_provided_data_settings( self, diff --git a/packages/google-analytics-admin/google/analytics/admin_v1alpha/services/analytics_admin_service/transports/grpc_asyncio.py b/packages/google-analytics-admin/google/analytics/admin_v1alpha/services/analytics_admin_service/transports/grpc_asyncio.py index 55e85f98924f..e656c23c87c8 100644 --- a/packages/google-analytics-admin/google/analytics/admin_v1alpha/services/analytics_admin_service/transports/grpc_asyncio.py +++ b/packages/google-analytics-admin/google/analytics/admin_v1alpha/services/analytics_admin_service/transports/grpc_asyncio.py @@ -5027,6 +5027,39 @@ def get_reporting_identity_settings( ) return self._stubs["get_reporting_identity_settings"] + @property + def update_reporting_identity_settings( + self, + ) -> Callable[ + [analytics_admin.UpdateReportingIdentitySettingsRequest], + Awaitable[resources.ReportingIdentitySettings], + ]: + r"""Return a callable for the update reporting identity + settings method over gRPC. + + Updates the reporting identity settings for this + property. + + Returns: + Callable[[~.UpdateReportingIdentitySettingsRequest], + Awaitable[~.ReportingIdentitySettings]]: + 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_reporting_identity_settings" not in self._stubs: + self._stubs["update_reporting_identity_settings"] = ( + self._logged_channel.unary_unary( + "/google.analytics.admin.v1alpha.AnalyticsAdminService/UpdateReportingIdentitySettings", + request_serializer=analytics_admin.UpdateReportingIdentitySettingsRequest.serialize, + response_deserializer=resources.ReportingIdentitySettings.deserialize, + ) + ) + return self._stubs["update_reporting_identity_settings"] + @property def get_user_provided_data_settings( self, @@ -5833,6 +5866,11 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.update_reporting_identity_settings: self._wrap_method( + self.update_reporting_identity_settings, + default_timeout=None, + client_info=client_info, + ), self.get_user_provided_data_settings: self._wrap_method( self.get_user_provided_data_settings, default_timeout=None, diff --git a/packages/google-analytics-admin/google/analytics/admin_v1alpha/services/analytics_admin_service/transports/rest.py b/packages/google-analytics-admin/google/analytics/admin_v1alpha/services/analytics_admin_service/transports/rest.py index c6724e97dd84..1d62fd255029 100644 --- a/packages/google-analytics-admin/google/analytics/admin_v1alpha/services/analytics_admin_service/transports/rest.py +++ b/packages/google-analytics-admin/google/analytics/admin_v1alpha/services/analytics_admin_service/transports/rest.py @@ -1189,6 +1189,14 @@ def post_update_reporting_data_annotation(self, response): logging.log(f"Received response: {response}") return response + def pre_update_reporting_identity_settings(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_reporting_identity_settings(self, response): + logging.log(f"Received response: {response}") + return response + def pre_update_search_ads360_link(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -7851,6 +7859,57 @@ def post_update_reporting_data_annotation_with_metadata( """ return response, metadata + def pre_update_reporting_identity_settings( + self, + request: analytics_admin.UpdateReportingIdentitySettingsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + analytics_admin.UpdateReportingIdentitySettingsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for update_reporting_identity_settings + + Override in a subclass to manipulate the request or metadata + before they are sent to the AnalyticsAdminService server. + """ + return request, metadata + + def post_update_reporting_identity_settings( + self, response: resources.ReportingIdentitySettings + ) -> resources.ReportingIdentitySettings: + """Post-rpc interceptor for update_reporting_identity_settings + + DEPRECATED. Please use the `post_update_reporting_identity_settings_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the AnalyticsAdminService server but before + it is returned to user code. This `post_update_reporting_identity_settings` interceptor runs + before the `post_update_reporting_identity_settings_with_metadata` interceptor. + """ + return response + + def post_update_reporting_identity_settings_with_metadata( + self, + response: resources.ReportingIdentitySettings, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + resources.ReportingIdentitySettings, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for update_reporting_identity_settings + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the AnalyticsAdminService server but before it is returned to user code. + + We recommend only using this `post_update_reporting_identity_settings_with_metadata` + interceptor in new development instead of the `post_update_reporting_identity_settings` interceptor. + When both interceptors are used, this `post_update_reporting_identity_settings_with_metadata` interceptor runs after the + `post_update_reporting_identity_settings` interceptor. The (possibly modified) response returned by + `post_update_reporting_identity_settings` will be passed to + `post_update_reporting_identity_settings_with_metadata`. + """ + return response, metadata + def pre_update_search_ads360_link( self, request: analytics_admin.UpdateSearchAds360LinkRequest, @@ -30462,6 +30521,169 @@ def __call__( ) return resp + class _UpdateReportingIdentitySettings( + _BaseAnalyticsAdminServiceRestTransport._BaseUpdateReportingIdentitySettings, + AnalyticsAdminServiceRestStub, + ): + def __hash__(self): + return hash( + "AnalyticsAdminServiceRestTransport.UpdateReportingIdentitySettings" + ) + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: analytics_admin.UpdateReportingIdentitySettingsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> resources.ReportingIdentitySettings: + r"""Call the update reporting identity + settings method over HTTP. + + Args: + request (~.analytics_admin.UpdateReportingIdentitySettingsRequest): + The request object. Request message for + UpdateReportingIdentitySettings RPC. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.resources.ReportingIdentitySettings: + A resource containing settings + related to reporting identity. + + """ + + http_options = _BaseAnalyticsAdminServiceRestTransport._BaseUpdateReportingIdentitySettings._get_http_options() + + request, metadata = ( + self._interceptor.pre_update_reporting_identity_settings( + request, metadata + ) + ) + transcoded_request = _BaseAnalyticsAdminServiceRestTransport._BaseUpdateReportingIdentitySettings._get_transcoded_request( + http_options, request + ) + + body = _BaseAnalyticsAdminServiceRestTransport._BaseUpdateReportingIdentitySettings._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseAnalyticsAdminServiceRestTransport._BaseUpdateReportingIdentitySettings._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.analytics.admin_v1alpha.AnalyticsAdminServiceClient.UpdateReportingIdentitySettings", + extra={ + "serviceName": "google.analytics.admin.v1alpha.AnalyticsAdminService", + "rpcName": "UpdateReportingIdentitySettings", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = AnalyticsAdminServiceRestTransport._UpdateReportingIdentitySettings._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = resources.ReportingIdentitySettings() + pb_resp = resources.ReportingIdentitySettings.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_update_reporting_identity_settings(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = ( + self._interceptor.post_update_reporting_identity_settings_with_metadata( + resp, response_metadata + ) + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = resources.ReportingIdentitySettings.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.analytics.admin_v1alpha.AnalyticsAdminServiceClient.update_reporting_identity_settings", + extra={ + "serviceName": "google.analytics.admin.v1alpha.AnalyticsAdminService", + "rpcName": "UpdateReportingIdentitySettings", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + class _UpdateSearchAds360Link( _BaseAnalyticsAdminServiceRestTransport._BaseUpdateSearchAds360Link, AnalyticsAdminServiceRestStub, @@ -32720,6 +32942,19 @@ def update_reporting_data_annotation( self._session, self._host, self._interceptor ) # type: ignore + @property + def update_reporting_identity_settings( + self, + ) -> Callable[ + [analytics_admin.UpdateReportingIdentitySettingsRequest], + resources.ReportingIdentitySettings, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateReportingIdentitySettings( + self._session, self._host, self._interceptor + ) # type: ignore + @property def update_search_ads360_link( self, diff --git a/packages/google-analytics-admin/google/analytics/admin_v1alpha/services/analytics_admin_service/transports/rest_base.py b/packages/google-analytics-admin/google/analytics/admin_v1alpha/services/analytics_admin_service/transports/rest_base.py index 5b9a0ac7f71d..999cb5db9778 100644 --- a/packages/google-analytics-admin/google/analytics/admin_v1alpha/services/analytics_admin_service/transports/rest_base.py +++ b/packages/google-analytics-admin/google/analytics/admin_v1alpha/services/analytics_admin_service/transports/rest_base.py @@ -7959,6 +7959,65 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params + class _BaseUpdateReportingIdentitySettings: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v1alpha/{reporting_identity_settings.name=properties/*/reportingIdentitySettings}", + "body": "reporting_identity_settings", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = analytics_admin.UpdateReportingIdentitySettingsRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAnalyticsAdminServiceRestTransport._BaseUpdateReportingIdentitySettings._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + class _BaseUpdateSearchAds360Link: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") diff --git a/packages/google-analytics-admin/google/analytics/admin_v1alpha/types/__init__.py b/packages/google-analytics-admin/google/analytics/admin_v1alpha/types/__init__.py index 1681a970339f..825af3013797 100644 --- a/packages/google-analytics-admin/google/analytics/admin_v1alpha/types/__init__.py +++ b/packages/google-analytics-admin/google/analytics/admin_v1alpha/types/__init__.py @@ -225,6 +225,7 @@ UpdateMeasurementProtocolSecretRequest, UpdatePropertyRequest, UpdateReportingDataAnnotationRequest, + UpdateReportingIdentitySettingsRequest, UpdateSearchAds360LinkRequest, UpdateSKAdNetworkConversionValueSchemaRequest, UpdateSubpropertyEventFilterRequest, @@ -530,6 +531,7 @@ "UpdateMeasurementProtocolSecretRequest", "UpdatePropertyRequest", "UpdateReportingDataAnnotationRequest", + "UpdateReportingIdentitySettingsRequest", "UpdateSearchAds360LinkRequest", "UpdateSKAdNetworkConversionValueSchemaRequest", "UpdateSubpropertyEventFilterRequest", diff --git a/packages/google-analytics-admin/google/analytics/admin_v1alpha/types/analytics_admin.py b/packages/google-analytics-admin/google/analytics/admin_v1alpha/types/analytics_admin.py index 5ae43add0792..cf6b1913fdde 100644 --- a/packages/google-analytics-admin/google/analytics/admin_v1alpha/types/analytics_admin.py +++ b/packages/google-analytics-admin/google/analytics/admin_v1alpha/types/analytics_admin.py @@ -231,6 +231,7 @@ "ListSubpropertySyncConfigsResponse", "UpdateSubpropertySyncConfigRequest", "GetReportingIdentitySettingsRequest", + "UpdateReportingIdentitySettingsRequest", "GetUserProvidedDataSettingsRequest", }, ) @@ -5235,6 +5236,34 @@ class GetReportingIdentitySettingsRequest(proto.Message): ) +class UpdateReportingIdentitySettingsRequest(proto.Message): + r"""Request message for UpdateReportingIdentitySettings RPC. + + Attributes: + reporting_identity_settings (google.analytics.admin_v1alpha.types.ReportingIdentitySettings): + Required. The reporting identity settings to update. The + settings' ``name`` field is used to identify the settings. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Optional. The list of fields to be updated. Field names must + be in snake case (for example, "field_to_update"). Omitted + fields will not be updated. To replace the entire entity, + use one path with the string "\*" to match all fields. If + omitted, the service will treat it as an implied field mask + equivalent to all fields that are populated. + """ + + reporting_identity_settings: resources.ReportingIdentitySettings = proto.Field( + proto.MESSAGE, + number=1, + message=resources.ReportingIdentitySettings, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + class GetUserProvidedDataSettingsRequest(proto.Message): r"""Request message for GetUserProvidedDataSettings RPC diff --git a/packages/google-analytics-admin/google/analytics/admin_v1alpha/types/resources.py b/packages/google-analytics-admin/google/analytics/admin_v1alpha/types/resources.py index f32b4ab50f10..3a53e79b8ad6 100644 --- a/packages/google-analytics-admin/google/analytics/admin_v1alpha/types/resources.py +++ b/packages/google-analytics-admin/google/analytics/admin_v1alpha/types/resources.py @@ -1135,6 +1135,9 @@ class PropertySummary(proto.Message): change the parent. Format: accounts/{account}, properties/{property} Example: "accounts/100", "properties/200". + can_edit (bool): + If true, then the user has a Google Analytics + role that permits them to edit the property. """ property: str = proto.Field( @@ -1154,6 +1157,10 @@ class PropertySummary(proto.Message): proto.STRING, number=4, ) + can_edit: bool = proto.Field( + proto.BOOL, + number=5, + ) class MeasurementProtocolSecret(proto.Message): diff --git a/packages/google-analytics-admin/google/analytics/admin_v1beta/types/analytics_admin.py b/packages/google-analytics-admin/google/analytics/admin_v1beta/types/analytics_admin.py index 65e1f577b905..e8098788e9e7 100644 --- a/packages/google-analytics-admin/google/analytics/admin_v1beta/types/analytics_admin.py +++ b/packages/google-analytics-admin/google/analytics/admin_v1beta/types/analytics_admin.py @@ -347,18 +347,18 @@ class ListAccountsRequest(proto.Message): Attributes: page_size (int): - The maximum number of resources to return. - The service may return fewer than this value, - even if there are additional pages. If + Optional. The maximum number of resources to + return. The service may return fewer than this + value, even if there are additional pages. If unspecified, at most 50 resources will be returned. The maximum value is 200; (higher values will be coerced to the maximum) page_token (str): - A page token, received from a previous ``ListAccounts`` - call. Provide this to retrieve the subsequent page. When - paginating, all other parameters provided to - ``ListAccounts`` must match the call that provided the page - token. + Optional. A page token, received from a previous + ``ListAccounts`` call. Provide this to retrieve the + subsequent page. When paginating, all other parameters + provided to ``ListAccounts`` must match the call that + provided the page token. show_deleted (bool): Whether to include soft-deleted (ie: "trashed") Accounts in the results. Accounts can @@ -524,18 +524,18 @@ class ListPropertiesRequest(proto.Message): | firebase_project:project-id | The firebase project with id: project-id. | | firebase_project:123 | The firebase project with number: 123. | page_size (int): - The maximum number of resources to return. - The service may return fewer than this value, - even if there are additional pages. If + Optional. The maximum number of resources to + return. The service may return fewer than this + value, even if there are additional pages. If unspecified, at most 50 resources will be returned. The maximum value is 200; (higher values will be coerced to the maximum) page_token (str): - A page token, received from a previous ``ListProperties`` - call. Provide this to retrieve the subsequent page. When - paginating, all other parameters provided to - ``ListProperties`` must match the call that provided the - page token. + Optional. A page token, received from a previous + ``ListProperties`` call. Provide this to retrieve the + subsequent page. When paginating, all other parameters + provided to ``ListProperties`` must match the call that + provided the page token. show_deleted (bool): Whether to include soft-deleted (ie: "trashed") Properties in the results. Properties @@ -696,18 +696,18 @@ class ListFirebaseLinksRequest(proto.Message): Example: ``properties/1234`` page_size (int): - The maximum number of resources to return. - The service may return fewer than this value, - even if there are additional pages. If + Optional. The maximum number of resources to + return. The service may return fewer than this + value, even if there are additional pages. If unspecified, at most 50 resources will be returned. The maximum value is 200; (higher values will be coerced to the maximum) page_token (str): - A page token, received from a previous ``ListFirebaseLinks`` - call. Provide this to retrieve the subsequent page. When - paginating, all other parameters provided to - ``ListFirebaseLinks`` must match the call that provided the - page token. + Optional. A page token, received from a previous + ``ListFirebaseLinks`` call. Provide this to retrieve the + subsequent page. When paginating, all other parameters + provided to ``ListFirebaseLinks`` must match the call that + provided the page token. """ parent: str = proto.Field( @@ -821,12 +821,12 @@ class ListGoogleAdsLinksRequest(proto.Message): parent (str): Required. Example format: properties/1234 page_size (int): - The maximum number of resources to return. - If unspecified, at most 50 resources will be - returned. The maximum value is 200 (higher - values will be coerced to the maximum). + Optional. The maximum number of resources to + return. If unspecified, at most 50 resources + will be returned. The maximum value is 200 + (higher values will be coerced to the maximum). page_token (str): - A page token, received from a previous + Optional. A page token, received from a previous ``ListGoogleAdsLinks`` call. Provide this to retrieve the subsequent page. @@ -898,15 +898,15 @@ class ListAccountSummariesRequest(proto.Message): Attributes: page_size (int): - The maximum number of AccountSummary - resources to return. The service may return - fewer than this value, even if there are - additional pages. If unspecified, at most 50 + Optional. The maximum number of + AccountSummary resources to return. The service + may return fewer than this value, even if there + are additional pages. If unspecified, at most 50 resources will be returned. The maximum value is 200; (higher values will be coerced to the maximum) page_token (str): - A page token, received from a previous + Optional. A page token, received from a previous ``ListAccountSummaries`` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to ``ListAccountSummaries`` must match the call @@ -1203,12 +1203,12 @@ class ListMeasurementProtocolSecretsRequest(proto.Message): properties/{property}/dataStreams/{dataStream}/measurementProtocolSecrets page_size (int): - The maximum number of resources to return. - If unspecified, at most 10 resources will be - returned. The maximum value is 10. Higher values - will be coerced to the maximum. + Optional. The maximum number of resources to + return. If unspecified, at most 10 resources + will be returned. The maximum value is 10. + Higher values will be coerced to the maximum. page_token (str): - A page token, received from a previous + Optional. A page token, received from a previous ``ListMeasurementProtocolSecrets`` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to ``ListMeasurementProtocolSecrets`` @@ -1350,12 +1350,12 @@ class ListConversionEventsRequest(proto.Message): Required. The resource name of the parent property. Example: 'properties/123' page_size (int): - The maximum number of resources to return. - If unspecified, at most 50 resources will be - returned. The maximum value is 200; (higher - values will be coerced to the maximum) + Optional. The maximum number of resources to + return. If unspecified, at most 50 resources + will be returned. The maximum value is 200; + (higher values will be coerced to the maximum) page_token (str): - A page token, received from a previous + Optional. A page token, received from a previous ``ListConversionEvents`` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to ``ListConversionEvents`` must match the call @@ -1492,16 +1492,16 @@ class ListKeyEventsRequest(proto.Message): Required. The resource name of the parent property. Example: 'properties/123' page_size (int): - The maximum number of resources to return. - If unspecified, at most 50 resources will be - returned. The maximum value is 200; (higher - values will be coerced to the maximum) + Optional. The maximum number of resources to + return. If unspecified, at most 50 resources + will be returned. The maximum value is 200; + (higher values will be coerced to the maximum) page_token (str): - A page token, received from a previous ``ListKeyEvents`` - call. Provide this to retrieve the subsequent page. When - paginating, all other parameters provided to - ``ListKeyEvents`` must match the call that provided the page - token. + Optional. A page token, received from a previous + ``ListKeyEvents`` call. Provide this to retrieve the + subsequent page. When paginating, all other parameters + provided to ``ListKeyEvents`` must match the call that + provided the page token. """ parent: str = proto.Field( @@ -1597,12 +1597,12 @@ class ListCustomDimensionsRequest(proto.Message): parent (str): Required. Example format: properties/1234 page_size (int): - The maximum number of resources to return. - If unspecified, at most 50 resources will be - returned. The maximum value is 200 (higher - values will be coerced to the maximum). + Optional. The maximum number of resources to + return. If unspecified, at most 50 resources + will be returned. The maximum value is 200 + (higher values will be coerced to the maximum). page_token (str): - A page token, received from a previous + Optional. A page token, received from a previous ``ListCustomDimensions`` call. Provide this to retrieve the subsequent page. diff --git a/packages/google-analytics-admin/google/analytics/admin_v1beta/types/resources.py b/packages/google-analytics-admin/google/analytics/admin_v1beta/types/resources.py index bdc45acd752f..ab758a47989a 100644 --- a/packages/google-analytics-admin/google/analytics/admin_v1beta/types/resources.py +++ b/packages/google-analytics-admin/google/analytics/admin_v1beta/types/resources.py @@ -280,7 +280,7 @@ class Account(proto.Message): Attributes: name (str): - Output only. Resource name of this account. + Identifier. Resource name of this account. Format: accounts/{account} Example: "accounts/100". create_time (google.protobuf.timestamp_pb2.Timestamp): @@ -344,7 +344,7 @@ class Property(proto.Message): Attributes: name (str): - Output only. Resource name of this property. Format: + Identifier. Resource name of this property. Format: properties/{property_id} Example: "properties/1000". property_type (google.analytics.admin_v1beta.types.PropertyType): Immutable. The property type for this Property resource. @@ -493,7 +493,7 @@ class DataStream(proto.Message): This field is a member of `oneof`_ ``stream_data``. name (str): - Output only. Resource name of this Data Stream. Format: + Identifier. Resource name of this Data Stream. Format: properties/{property_id}/dataStreams/{stream_id} Example: "properties/1000/dataStreams/2000". type_ (google.analytics.admin_v1beta.types.DataStream.DataStreamType): @@ -658,7 +658,7 @@ class FirebaseLink(proto.Message): Attributes: name (str): - Output only. Example format: + Identifier. Example format: properties/1234/firebaseLinks/5678 project (str): Immutable. Firebase project resource name. When creating a @@ -694,7 +694,7 @@ class GoogleAdsLink(proto.Message): Attributes: name (str): - Output only. Format: + Identifier. Format: properties/{propertyId}/googleAdsLinks/{googleAdsLinkId} @@ -765,28 +765,53 @@ class DataSharingSettings(proto.Message): Attributes: name (str): - Output only. Resource name. + Identifier. Resource name. Format: accounts/{account}/dataSharingSettings Example: "accounts/1000/dataSharingSettings". sharing_with_google_support_enabled (bool): - Allows Google support to access the data in - order to help troubleshoot issues. + Allows Google technical support + representatives access to your Google Analytics + data and account when necessary to provide + service and find solutions to technical issues. + + This field maps to the "Technical support" field + in the Google Analytics Admin UI. sharing_with_google_assigned_sales_enabled (bool): - Allows Google sales teams that are assigned - to the customer to access the data in order to - suggest configuration changes to improve - results. Sales team restrictions still apply - when enabled. + Allows Google access to your Google Analytics + account data, including account usage and + configuration data, product spending, and users + associated with your Google Analytics account, + so that Google can help you make the most of + Google products, providing you with insights, + offers, recommendations, and optimization tips + across Google Analytics and other Google + products for business. + + This field maps to the "Recommendations for your + business" field in the Google Analytics Admin + UI. sharing_with_google_any_sales_enabled (bool): - Allows any of Google sales to access the data - in order to suggest configuration changes to - improve results. + Deprecated. This field is no longer used and + always returns false. sharing_with_google_products_enabled (bool): Allows Google to use the data to improve other Google products or services. + This fields maps to the "Google products & + services" field in the Google Analytics Admin + UI. sharing_with_others_enabled (bool): - Allows Google to share the data anonymously - in aggregate form with others. + Enable features like predictions, modeled + data, and benchmarking that can provide you with + richer business insights when you contribute + aggregated measurement data. The data you share + (including information about the property from + which it is shared) is aggregated and + de-identified before being used to generate + business insights. + + This field maps to the "Modeling contributions & + business insights" field in the Google Analytics + Admin UI. """ name: str = proto.Field( @@ -821,7 +846,7 @@ class AccountSummary(proto.Message): Attributes: name (str): - Resource name for this account summary. Format: + Identifier. Resource name for this account summary. Format: accountSummaries/{account_id} Example: "accountSummaries/1000". account (str): @@ -875,6 +900,9 @@ class PropertySummary(proto.Message): change the parent. Format: accounts/{account}, properties/{property} Example: "accounts/100", "properties/200". + can_edit (bool): + If true, then the user has a Google Analytics + role that permits them to edit the property. """ property: str = proto.Field( @@ -894,6 +922,10 @@ class PropertySummary(proto.Message): proto.STRING, number=4, ) + can_edit: bool = proto.Field( + proto.BOOL, + number=5, + ) class MeasurementProtocolSecret(proto.Message): @@ -901,7 +933,7 @@ class MeasurementProtocolSecret(proto.Message): Attributes: name (str): - Output only. Resource name of this secret. + Identifier. Resource name of this secret. This secret may be a child of any type of stream. Format: @@ -1142,7 +1174,7 @@ class ConversionEvent(proto.Message): Attributes: name (str): - Output only. Resource name of this conversion event. Format: + Identifier. Resource name of this conversion event. Format: properties/{property}/conversionEvents/{conversion_event} event_name (str): Immutable. The event name for this conversion @@ -1381,7 +1413,7 @@ class CustomDimension(proto.Message): Attributes: name (str): - Output only. Resource name for this + Identifier. Resource name for this CustomDimension resource. Format: properties/{property}/customDimensions/{customDimension} parameter_name (str): @@ -1473,7 +1505,7 @@ class CustomMetric(proto.Message): Attributes: name (str): - Output only. Resource name for this + Identifier. Resource name for this CustomMetric resource. Format: properties/{property}/customMetrics/{customMetric} parameter_name (str): @@ -1621,7 +1653,7 @@ class DataRetentionSettings(proto.Message): Attributes: name (str): - Output only. Resource name for this + Identifier. Resource name for this DataRetentionSetting resource. Format: properties/{property}/dataRetentionSettings event_data_retention (google.analytics.admin_v1beta.types.DataRetentionSettings.RetentionDuration): diff --git a/packages/google-analytics-admin/tests/unit/gapic/admin_v1alpha/test_analytics_admin_service.py b/packages/google-analytics-admin/tests/unit/gapic/admin_v1alpha/test_analytics_admin_service.py index 45ff53758cf3..d2e8861de9b1 100644 --- a/packages/google-analytics-admin/tests/unit/gapic/admin_v1alpha/test_analytics_admin_service.py +++ b/packages/google-analytics-admin/tests/unit/gapic/admin_v1alpha/test_analytics_admin_service.py @@ -59714,6 +59714,375 @@ async def test_get_reporting_identity_settings_flattened_error_async(): ) +@pytest.mark.parametrize( + "request_type", + [ + analytics_admin.UpdateReportingIdentitySettingsRequest(), + {}, + ], +) +def test_update_reporting_identity_settings(request_type, transport: str = "grpc"): + client = AnalyticsAdminServiceClient( + 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_reporting_identity_settings), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = resources.ReportingIdentitySettings( + name="name_value", + reporting_identity=resources.ReportingIdentitySettings.ReportingIdentity.BLENDED, + ) + response = client.update_reporting_identity_settings(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = analytics_admin.UpdateReportingIdentitySettingsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, resources.ReportingIdentitySettings) + assert response.name == "name_value" + assert ( + response.reporting_identity + == resources.ReportingIdentitySettings.ReportingIdentity.BLENDED + ) + + +def test_update_reporting_identity_settings_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = AnalyticsAdminServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = analytics_admin.UpdateReportingIdentitySettingsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_reporting_identity_settings), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.update_reporting_identity_settings(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = analytics_admin.UpdateReportingIdentitySettingsRequest() + assert args[0] == request_msg + + +def test_update_reporting_identity_settings_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = AnalyticsAdminServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.update_reporting_identity_settings + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.update_reporting_identity_settings + ] = mock_rpc + request = {} + client.update_reporting_identity_settings(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.update_reporting_identity_settings(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_update_reporting_identity_settings_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = AnalyticsAdminServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.update_reporting_identity_settings + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.update_reporting_identity_settings + ] = mock_rpc + + request = {} + await client.update_reporting_identity_settings(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.update_reporting_identity_settings(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + analytics_admin.UpdateReportingIdentitySettingsRequest(), + {}, + ], +) +async def test_update_reporting_identity_settings_async( + request_type, transport: str = "grpc_asyncio" +): + client = AnalyticsAdminServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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_reporting_identity_settings), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + resources.ReportingIdentitySettings( + name="name_value", + reporting_identity=resources.ReportingIdentitySettings.ReportingIdentity.BLENDED, + ) + ) + response = await client.update_reporting_identity_settings(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = analytics_admin.UpdateReportingIdentitySettingsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, resources.ReportingIdentitySettings) + assert response.name == "name_value" + assert ( + response.reporting_identity + == resources.ReportingIdentitySettings.ReportingIdentity.BLENDED + ) + + +def test_update_reporting_identity_settings_field_headers(): + client = AnalyticsAdminServiceClient( + 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 = analytics_admin.UpdateReportingIdentitySettingsRequest() + + request.reporting_identity_settings.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_reporting_identity_settings), "__call__" + ) as call: + call.return_value = resources.ReportingIdentitySettings() + client.update_reporting_identity_settings(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", + "reporting_identity_settings.name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_update_reporting_identity_settings_field_headers_async(): + client = AnalyticsAdminServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = analytics_admin.UpdateReportingIdentitySettingsRequest() + + request.reporting_identity_settings.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_reporting_identity_settings), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + resources.ReportingIdentitySettings() + ) + await client.update_reporting_identity_settings(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", + "reporting_identity_settings.name=name_value", + ) in kw["metadata"] + + +def test_update_reporting_identity_settings_flattened(): + client = AnalyticsAdminServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_reporting_identity_settings), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = resources.ReportingIdentitySettings() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_reporting_identity_settings( + reporting_identity_settings=resources.ReportingIdentitySettings( + 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].reporting_identity_settings + mock_val = resources.ReportingIdentitySettings(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_reporting_identity_settings_flattened_error(): + client = AnalyticsAdminServiceClient( + 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_reporting_identity_settings( + analytics_admin.UpdateReportingIdentitySettingsRequest(), + reporting_identity_settings=resources.ReportingIdentitySettings( + name="name_value" + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.asyncio +async def test_update_reporting_identity_settings_flattened_async(): + client = AnalyticsAdminServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_reporting_identity_settings), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = resources.ReportingIdentitySettings() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + resources.ReportingIdentitySettings() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_reporting_identity_settings( + reporting_identity_settings=resources.ReportingIdentitySettings( + 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].reporting_identity_settings + mock_val = resources.ReportingIdentitySettings(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_reporting_identity_settings_flattened_error_async(): + client = AnalyticsAdminServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_reporting_identity_settings( + analytics_admin.UpdateReportingIdentitySettingsRequest(), + reporting_identity_settings=resources.ReportingIdentitySettings( + name="name_value" + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + @pytest.mark.parametrize( "request_type", [ @@ -89851,6 +90220,203 @@ def test_get_reporting_identity_settings_rest_flattened_error(transport: str = " ) +def test_update_reporting_identity_settings_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = AnalyticsAdminServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.update_reporting_identity_settings + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.update_reporting_identity_settings + ] = mock_rpc + + request = {} + client.update_reporting_identity_settings(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.update_reporting_identity_settings(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_update_reporting_identity_settings_rest_required_fields( + request_type=analytics_admin.UpdateReportingIdentitySettingsRequest, +): + transport_class = transports.AnalyticsAdminServiceRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_reporting_identity_settings._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_reporting_identity_settings._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = AnalyticsAdminServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = resources.ReportingIdentitySettings() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = resources.ReportingIdentitySettings.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.update_reporting_identity_settings(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_update_reporting_identity_settings_rest_unset_required_fields(): + transport = transports.AnalyticsAdminServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = ( + transport.update_reporting_identity_settings._get_unset_required_fields({}) + ) + assert set(unset_fields) == ( + set(("updateMask",)) & set(("reportingIdentitySettings",)) + ) + + +def test_update_reporting_identity_settings_rest_flattened(): + client = AnalyticsAdminServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = resources.ReportingIdentitySettings() + + # get arguments that satisfy an http rule for this method + sample_request = { + "reporting_identity_settings": { + "name": "properties/sample1/reportingIdentitySettings" + } + } + + # get truthy value for each flattened field + mock_args = dict( + reporting_identity_settings=resources.ReportingIdentitySettings( + name="name_value" + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = resources.ReportingIdentitySettings.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.update_reporting_identity_settings(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1alpha/{reporting_identity_settings.name=properties/*/reportingIdentitySettings}" + % client.transport._host, + args[1], + ) + + +def test_update_reporting_identity_settings_rest_flattened_error( + transport: str = "rest", +): + client = AnalyticsAdminServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_reporting_identity_settings( + analytics_admin.UpdateReportingIdentitySettingsRequest(), + reporting_identity_settings=resources.ReportingIdentitySettings( + name="name_value" + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + def test_get_user_provided_data_settings_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -93511,6 +94077,28 @@ def test_get_reporting_identity_settings_empty_call_grpc(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_reporting_identity_settings_empty_call_grpc(): + client = AnalyticsAdminServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_reporting_identity_settings), "__call__" + ) as call: + call.return_value = resources.ReportingIdentitySettings() + client.update_reporting_identity_settings(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = analytics_admin.UpdateReportingIdentitySettingsRequest() + assert args[0] == request_msg + + # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. def test_get_user_provided_data_settings_empty_call_grpc(): @@ -98035,6 +98623,35 @@ async def test_get_reporting_identity_settings_empty_call_grpc_asyncio(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_reporting_identity_settings_empty_call_grpc_asyncio(): + client = AnalyticsAdminServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_reporting_identity_settings), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + resources.ReportingIdentitySettings( + name="name_value", + reporting_identity=resources.ReportingIdentitySettings.ReportingIdentity.BLENDED, + ) + ) + await client.update_reporting_identity_settings(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = analytics_admin.UpdateReportingIdentitySettingsRequest() + assert args[0] == request_msg + + # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @pytest.mark.asyncio @@ -123640,6 +124257,234 @@ def test_get_reporting_identity_settings_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() +def test_update_reporting_identity_settings_rest_bad_request( + request_type=analytics_admin.UpdateReportingIdentitySettingsRequest, +): + client = AnalyticsAdminServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "reporting_identity_settings": { + "name": "properties/sample1/reportingIdentitySettings" + } + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.update_reporting_identity_settings(request) + + +@pytest.mark.parametrize( + "request_type", + [ + analytics_admin.UpdateReportingIdentitySettingsRequest, + dict, + ], +) +def test_update_reporting_identity_settings_rest_call_success(request_type): + client = AnalyticsAdminServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "reporting_identity_settings": { + "name": "properties/sample1/reportingIdentitySettings" + } + } + request_init["reporting_identity_settings"] = { + "name": "properties/sample1/reportingIdentitySettings", + "reporting_identity": 1, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = analytics_admin.UpdateReportingIdentitySettingsRequest.meta.fields[ + "reporting_identity_settings" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init[ + "reporting_identity_settings" + ].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range( + 0, len(request_init["reporting_identity_settings"][field]) + ): + del request_init["reporting_identity_settings"][field][i][subfield] + else: + del request_init["reporting_identity_settings"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = resources.ReportingIdentitySettings( + name="name_value", + reporting_identity=resources.ReportingIdentitySettings.ReportingIdentity.BLENDED, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = resources.ReportingIdentitySettings.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.update_reporting_identity_settings(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, resources.ReportingIdentitySettings) + assert response.name == "name_value" + assert ( + response.reporting_identity + == resources.ReportingIdentitySettings.ReportingIdentity.BLENDED + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_reporting_identity_settings_rest_interceptors(null_interceptor): + transport = transports.AnalyticsAdminServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.AnalyticsAdminServiceRestInterceptor(), + ) + client = AnalyticsAdminServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.AnalyticsAdminServiceRestInterceptor, + "post_update_reporting_identity_settings", + ) as post, + mock.patch.object( + transports.AnalyticsAdminServiceRestInterceptor, + "post_update_reporting_identity_settings_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.AnalyticsAdminServiceRestInterceptor, + "pre_update_reporting_identity_settings", + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = analytics_admin.UpdateReportingIdentitySettingsRequest.pb( + analytics_admin.UpdateReportingIdentitySettingsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = resources.ReportingIdentitySettings.to_json( + resources.ReportingIdentitySettings() + ) + req.return_value.content = return_value + + request = analytics_admin.UpdateReportingIdentitySettingsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = resources.ReportingIdentitySettings() + post_with_metadata.return_value = ( + resources.ReportingIdentitySettings(), + metadata, + ) + + client.update_reporting_identity_settings( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + def test_get_user_provided_data_settings_rest_bad_request( request_type=analytics_admin.GetUserProvidedDataSettingsRequest, ): @@ -126995,6 +127840,27 @@ def test_get_reporting_identity_settings_empty_call_rest(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_reporting_identity_settings_empty_call_rest(): + client = AnalyticsAdminServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_reporting_identity_settings), "__call__" + ) as call: + client.update_reporting_identity_settings(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = analytics_admin.UpdateReportingIdentitySettingsRequest() + assert args[0] == request_msg + + # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. def test_get_user_provided_data_settings_empty_call_rest(): @@ -127203,6 +128069,7 @@ def test_analytics_admin_service_base_transport(): "update_subproperty_sync_config", "get_subproperty_sync_config", "get_reporting_identity_settings", + "update_reporting_identity_settings", "get_user_provided_data_settings", ) for method in methods: @@ -127975,6 +128842,9 @@ def test_analytics_admin_service_client_transport_session_collision(transport_na session1 = client1.transport.get_reporting_identity_settings._session session2 = client2.transport.get_reporting_identity_settings._session assert session1 != session2 + session1 = client1.transport.update_reporting_identity_settings._session + session2 = client2.transport.update_reporting_identity_settings._session + assert session1 != session2 session1 = client1.transport.get_user_provided_data_settings._session session2 = client2.transport.get_user_provided_data_settings._session assert session1 != session2 diff --git a/packages/google-apps-chat/google/apps/chat_v1/types/message.py b/packages/google-apps-chat/google/apps/chat_v1/types/message.py index d85925d9b891..cb3cf60c0bf7 100644 --- a/packages/google-apps-chat/google/apps/chat_v1/types/message.py +++ b/packages/google-apps-chat/google/apps/chat_v1/types/message.py @@ -417,10 +417,6 @@ class AttachedGif(proto.Message): class QuotedMessageMetadata(proto.Message): r"""Information about a message that another message quotes. - When you create a message, you can quote messages within the same - thread, or quote a root message to create a new root message. - However, you can't quote a message reply from a different thread. - When you update a message, you can't add or replace the ``quotedMessageMetadata`` field, but you can remove it. @@ -462,19 +458,24 @@ class QuoteType(proto.Enum): QUOTE_TYPE_UNSPECIFIED (0): Reserved. This value is unused. REPLY (1): - If quote_type is ``REPLY``, you can do the following: + When ``quote_type`` is ``REPLY``, you can do the following: - If you're replying in a thread, you can quote another message in that thread. - If you're creating a root message, you can quote another root message in that space. + FORWARD (2): + When ``quote_type`` is ``FORWARD``, you can quote a: + + - Message from a different space. - You can't quote a message reply from a different thread. + - Message reply from a different thread in the same space. """ QUOTE_TYPE_UNSPECIFIED = 0 REPLY = 1 + FORWARD = 2 name: str = proto.Field( proto.STRING, diff --git a/packages/google-cloud-build/google/cloud/devtools/cloudbuild_v1/types/cloudbuild.py b/packages/google-cloud-build/google/cloud/devtools/cloudbuild_v1/types/cloudbuild.py index d662fee0ff8e..4b699b419808 100644 --- a/packages/google-cloud-build/google/cloud/devtools/cloudbuild_v1/types/cloudbuild.py +++ b/packages/google-cloud-build/google/cloud/devtools/cloudbuild_v1/types/cloudbuild.py @@ -3684,6 +3684,8 @@ class MachineType(proto.Enum): Highcpu e2 machine with 32 CPUs. E2_MEDIUM (7): E2 machine with 1 CPU. + E2_STANDARD_2 (11): + E2 machine with 2 CPUs. """ UNSPECIFIED = 0 @@ -3692,6 +3694,7 @@ class MachineType(proto.Enum): E2_HIGHCPU_8 = 5 E2_HIGHCPU_32 = 6 E2_MEDIUM = 7 + E2_STANDARD_2 = 11 class SubstitutionOption(proto.Enum): r"""Specifies the behavior when there is an error in the diff --git a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/agent_tool.py b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/agent_tool.py index 762037cf0381..c5efc6f507ad 100644 --- a/packages/google-cloud-ces/google/cloud/ces_v1beta/types/agent_tool.py +++ b/packages/google-cloud-ces/google/cloud/ces_v1beta/types/agent_tool.py @@ -36,11 +36,6 @@ class AgentTool(proto.Message): Required. The name of the agent tool. description (str): Optional. Description of the tool's purpose. - root_agent (str): - Optional. Deprecated: Use ``agent`` instead. The resource - name of the root agent that is the entry point of the tool. - Format: - ``projects/{project}/locations/{location}/agents/{agent}`` agent (str): Optional. The resource name of the agent that is the entry point of the tool. Format: @@ -55,10 +50,6 @@ class AgentTool(proto.Message): proto.STRING, number=2, ) - root_agent: str = proto.Field( - proto.STRING, - number=3, - ) agent: str = proto.Field( proto.STRING, number=4, diff --git a/packages/google-cloud-ces/tests/unit/gapic/ces_v1beta/test_agent_service.py b/packages/google-cloud-ces/tests/unit/gapic/ces_v1beta/test_agent_service.py index 8c34161fe618..501b21ad1dbf 100644 --- a/packages/google-cloud-ces/tests/unit/gapic/ces_v1beta/test_agent_service.py +++ b/packages/google-cloud-ces/tests/unit/gapic/ces_v1beta/test_agent_service.py @@ -38341,7 +38341,6 @@ def test_create_tool_rest_call_success(request_type): "agent_tool": { "name": "name_value", "description": "description_value", - "root_agent": "root_agent_value", "agent": "agent_value", }, "widget_tool": { @@ -38817,7 +38816,6 @@ def test_update_tool_rest_call_success(request_type): "agent_tool": { "name": "name_value", "description": "description_value", - "root_agent": "root_agent_value", "agent": "agent_value", }, "widget_tool": { @@ -42782,7 +42780,6 @@ def test_create_app_version_rest_call_success(request_type): "agent_tool": { "name": "name_value", "description": "description_value", - "root_agent": "root_agent_value", "agent": "agent_value", }, "widget_tool": { diff --git a/packages/google-cloud-chronicle/docs/chronicle_v1/rule_execution_error_service.rst b/packages/google-cloud-chronicle/docs/chronicle_v1/rule_execution_error_service.rst new file mode 100644 index 000000000000..e95d79bd0784 --- /dev/null +++ b/packages/google-cloud-chronicle/docs/chronicle_v1/rule_execution_error_service.rst @@ -0,0 +1,10 @@ +RuleExecutionErrorService +------------------------------------------- + +.. automodule:: google.cloud.chronicle_v1.services.rule_execution_error_service + :members: + :inherited-members: + +.. automodule:: google.cloud.chronicle_v1.services.rule_execution_error_service.pagers + :members: + :inherited-members: diff --git a/packages/google-cloud-chronicle/docs/chronicle_v1/services_.rst b/packages/google-cloud-chronicle/docs/chronicle_v1/services_.rst index e0ae32d4d4f2..1cde737362f4 100644 --- a/packages/google-cloud-chronicle/docs/chronicle_v1/services_.rst +++ b/packages/google-cloud-chronicle/docs/chronicle_v1/services_.rst @@ -13,4 +13,5 @@ Services for Google Cloud Chronicle v1 API instance_service native_dashboard_service reference_list_service + rule_execution_error_service rule_service diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle/__init__.py b/packages/google-cloud-chronicle/google/cloud/chronicle/__init__.py index 35c56ef21f6d..8be7d23a51d0 100644 --- a/packages/google-cloud-chronicle/google/cloud/chronicle/__init__.py +++ b/packages/google-cloud-chronicle/google/cloud/chronicle/__init__.py @@ -76,6 +76,12 @@ from google.cloud.chronicle_v1.services.reference_list_service.client import ( ReferenceListServiceClient, ) +from google.cloud.chronicle_v1.services.rule_execution_error_service.async_client import ( + RuleExecutionErrorServiceAsyncClient, +) +from google.cloud.chronicle_v1.services.rule_execution_error_service.client import ( + RuleExecutionErrorServiceClient, +) from google.cloud.chronicle_v1.services.rule_service.async_client import ( RuleServiceAsyncClient, ) @@ -235,11 +241,14 @@ ListReferenceListsResponse, ReferenceList, ReferenceListEntry, + ReferenceListError, ReferenceListScope, ReferenceListSyntaxType, ReferenceListView, ScopeInfo, UpdateReferenceListRequest, + VerifyReferenceListRequest, + VerifyReferenceListResponse, ) from google.cloud.chronicle_v1.types.rule import ( CompilationDiagnostic, @@ -269,6 +278,13 @@ Severity, UpdateRuleDeploymentRequest, UpdateRuleRequest, + VerifyRuleTextRequest, + VerifyRuleTextResponse, +) +from google.cloud.chronicle_v1.types.rule_execution_error import ( + ListRuleExecutionErrorsRequest, + ListRuleExecutionErrorsResponse, + RuleExecutionError, ) __all__ = ( @@ -292,6 +308,8 @@ "NativeDashboardServiceAsyncClient", "ReferenceListServiceClient", "ReferenceListServiceAsyncClient", + "RuleExecutionErrorServiceClient", + "RuleExecutionErrorServiceAsyncClient", "RuleServiceClient", "RuleServiceAsyncClient", "BigQueryExport", @@ -431,9 +449,12 @@ "ListReferenceListsResponse", "ReferenceList", "ReferenceListEntry", + "ReferenceListError", "ReferenceListScope", "ScopeInfo", "UpdateReferenceListRequest", + "VerifyReferenceListRequest", + "VerifyReferenceListResponse", "ReferenceListSyntaxType", "ReferenceListView", "CompilationDiagnostic", @@ -460,7 +481,12 @@ "Severity", "UpdateRuleDeploymentRequest", "UpdateRuleRequest", + "VerifyRuleTextRequest", + "VerifyRuleTextResponse", "RuleType", "RuleView", "RunFrequency", + "ListRuleExecutionErrorsRequest", + "ListRuleExecutionErrorsResponse", + "RuleExecutionError", ) diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/__init__.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/__init__.py index 8f93142f2184..3f77c05f421f 100644 --- a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/__init__.py +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/__init__.py @@ -57,6 +57,10 @@ ReferenceListServiceAsyncClient, ReferenceListServiceClient, ) +from .services.rule_execution_error_service import ( + RuleExecutionErrorServiceAsyncClient, + RuleExecutionErrorServiceClient, +) from .services.rule_service import RuleServiceAsyncClient, RuleServiceClient from .types.big_query_export import ( BigQueryExport, @@ -211,11 +215,14 @@ ListReferenceListsResponse, ReferenceList, ReferenceListEntry, + ReferenceListError, ReferenceListScope, ReferenceListSyntaxType, ReferenceListView, ScopeInfo, UpdateReferenceListRequest, + VerifyReferenceListRequest, + VerifyReferenceListResponse, ) from .types.rule import ( CompilationDiagnostic, @@ -245,6 +252,13 @@ Severity, UpdateRuleDeploymentRequest, UpdateRuleRequest, + VerifyRuleTextRequest, + VerifyRuleTextResponse, +) +from .types.rule_execution_error import ( + ListRuleExecutionErrorsRequest, + ListRuleExecutionErrorsResponse, + RuleExecutionError, ) if hasattr(api_core, "check_python_version") and hasattr( @@ -341,6 +355,7 @@ def _get_version(dependency_name): "InstanceServiceAsyncClient", "NativeDashboardServiceAsyncClient", "ReferenceListServiceAsyncClient", + "RuleExecutionErrorServiceAsyncClient", "RuleServiceAsyncClient", "AddChartRequest", "AddChartResponse", @@ -467,6 +482,8 @@ def _get_version(dependency_name): "ListRetrohuntsResponse", "ListRuleDeploymentsRequest", "ListRuleDeploymentsResponse", + "ListRuleExecutionErrorsRequest", + "ListRuleExecutionErrorsResponse", "ListRuleRevisionsRequest", "ListRuleRevisionsResponse", "ListRulesRequest", @@ -487,6 +504,7 @@ def _get_version(dependency_name): "QueryRuntimeError", "ReferenceList", "ReferenceListEntry", + "ReferenceListError", "ReferenceListScope", "ReferenceListServiceClient", "ReferenceListSyntaxType", @@ -497,6 +515,8 @@ def _get_version(dependency_name): "RetrohuntMetadata", "Rule", "RuleDeployment", + "RuleExecutionError", + "RuleExecutionErrorServiceClient", "RuleServiceClient", "RuleType", "RuleView", @@ -519,6 +539,10 @@ def _get_version(dependency_name): "UpdateRuleDeploymentRequest", "UpdateRuleRequest", "UpdateWatchlistRequest", + "VerifyReferenceListRequest", + "VerifyReferenceListResponse", + "VerifyRuleTextRequest", + "VerifyRuleTextResponse", "VisualMapType", "Watchlist", "WatchlistUserPreferences", diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/gapic_metadata.json b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/gapic_metadata.json index b5400b21a874..511d879a4faa 100644 --- a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/gapic_metadata.json +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/gapic_metadata.json @@ -995,6 +995,11 @@ "methods": [ "update_reference_list" ] + }, + "VerifyReferenceList": { + "methods": [ + "verify_reference_list" + ] } } }, @@ -1020,6 +1025,11 @@ "methods": [ "update_reference_list" ] + }, + "VerifyReferenceList": { + "methods": [ + "verify_reference_list" + ] } } }, @@ -1045,6 +1055,45 @@ "methods": [ "update_reference_list" ] + }, + "VerifyReferenceList": { + "methods": [ + "verify_reference_list" + ] + } + } + } + } + }, + "RuleExecutionErrorService": { + "clients": { + "grpc": { + "libraryClient": "RuleExecutionErrorServiceClient", + "rpcs": { + "ListRuleExecutionErrors": { + "methods": [ + "list_rule_execution_errors" + ] + } + } + }, + "grpc-async": { + "libraryClient": "RuleExecutionErrorServiceAsyncClient", + "rpcs": { + "ListRuleExecutionErrors": { + "methods": [ + "list_rule_execution_errors" + ] + } + } + }, + "rest": { + "libraryClient": "RuleExecutionErrorServiceClient", + "rpcs": { + "ListRuleExecutionErrors": { + "methods": [ + "list_rule_execution_errors" + ] } } } @@ -1114,6 +1163,11 @@ "methods": [ "update_rule_deployment" ] + }, + "VerifyRuleText": { + "methods": [ + "verify_rule_text" + ] } } }, @@ -1179,6 +1233,11 @@ "methods": [ "update_rule_deployment" ] + }, + "VerifyRuleText": { + "methods": [ + "verify_rule_text" + ] } } }, @@ -1244,6 +1303,11 @@ "methods": [ "update_rule_deployment" ] + }, + "VerifyRuleText": { + "methods": [ + "verify_rule_text" + ] } } } diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/reference_list_service/async_client.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/reference_list_service/async_client.py index 43e1bcda8eee..931452f93c3f 100644 --- a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/reference_list_service/async_client.py +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/reference_list_service/async_client.py @@ -80,6 +80,8 @@ class ReferenceListServiceAsyncClient: _DEFAULT_ENDPOINT_TEMPLATE = ReferenceListServiceClient._DEFAULT_ENDPOINT_TEMPLATE _DEFAULT_UNIVERSE = ReferenceListServiceClient._DEFAULT_UNIVERSE + instance_path = staticmethod(ReferenceListServiceClient.instance_path) + parse_instance_path = staticmethod(ReferenceListServiceClient.parse_instance_path) reference_list_path = staticmethod(ReferenceListServiceClient.reference_list_path) parse_reference_list_path = staticmethod( ReferenceListServiceClient.parse_reference_list_path @@ -835,6 +837,97 @@ async def sample_update_reference_list(): # Done; return the response. return response + async def verify_reference_list( + self, + request: Optional[ + Union[reference_list.VerifyReferenceListRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> reference_list.VerifyReferenceListResponse: + r"""VerifyReferenceList validates list content and + returns line errors, if any. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import chronicle_v1 + + async def sample_verify_reference_list(): + # Create a client + client = chronicle_v1.ReferenceListServiceAsyncClient() + + # Initialize request argument(s) + entries = chronicle_v1.ReferenceListEntry() + entries.value = "value_value" + + request = chronicle_v1.VerifyReferenceListRequest( + instance="instance_value", + syntax_type="REFERENCE_LIST_SYNTAX_TYPE_CIDR", + entries=entries, + ) + + # Make the request + response = await client.verify_reference_list(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.chronicle_v1.types.VerifyReferenceListRequest, dict]]): + The request object. VerifyReferenceList request message. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.chronicle_v1.types.VerifyReferenceListResponse: + VerifyListResponse response message. + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, reference_list.VerifyReferenceListRequest): + request = reference_list.VerifyReferenceListRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.verify_reference_list + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("instance", request.instance),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + async def list_operations( self, request: Optional[Union[operations_pb2.ListOperationsRequest, dict]] = None, diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/reference_list_service/client.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/reference_list_service/client.py index d7ad5e67e3ab..50f3d80bfecf 100644 --- a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/reference_list_service/client.py +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/reference_list_service/client.py @@ -233,6 +233,28 @@ def transport(self) -> ReferenceListServiceTransport: """ return self._transport + @staticmethod + def instance_path( + project: str, + location: str, + instance: str, + ) -> str: + """Returns a fully-qualified instance string.""" + return "projects/{project}/locations/{location}/instances/{instance}".format( + project=project, + location=location, + instance=instance, + ) + + @staticmethod + def parse_instance_path(path: str) -> Dict[str, str]: + """Parses a instance path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/instances/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def reference_list_path( project: str, @@ -1256,6 +1278,95 @@ def sample_update_reference_list(): # Done; return the response. return response + def verify_reference_list( + self, + request: Optional[ + Union[reference_list.VerifyReferenceListRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> reference_list.VerifyReferenceListResponse: + r"""VerifyReferenceList validates list content and + returns line errors, if any. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import chronicle_v1 + + def sample_verify_reference_list(): + # Create a client + client = chronicle_v1.ReferenceListServiceClient() + + # Initialize request argument(s) + entries = chronicle_v1.ReferenceListEntry() + entries.value = "value_value" + + request = chronicle_v1.VerifyReferenceListRequest( + instance="instance_value", + syntax_type="REFERENCE_LIST_SYNTAX_TYPE_CIDR", + entries=entries, + ) + + # Make the request + response = client.verify_reference_list(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.chronicle_v1.types.VerifyReferenceListRequest, dict]): + The request object. VerifyReferenceList request message. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.chronicle_v1.types.VerifyReferenceListResponse: + VerifyListResponse response message. + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, reference_list.VerifyReferenceListRequest): + request = reference_list.VerifyReferenceListRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.verify_reference_list] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("instance", request.instance),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + def __enter__(self) -> "ReferenceListServiceClient": return self diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/reference_list_service/transports/base.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/reference_list_service/transports/base.py index 5a54cf899042..db80f452fae1 100644 --- a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/reference_list_service/transports/base.py +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/reference_list_service/transports/base.py @@ -41,7 +41,11 @@ class ReferenceListServiceTransport(abc.ABC): """Abstract transport class for ReferenceListService.""" - AUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) + AUTH_SCOPES = ( + "https://www.googleapis.com/auth/chronicle", + "https://www.googleapis.com/auth/chronicle.readonly", + "https://www.googleapis.com/auth/cloud-platform", + ) DEFAULT_HOST: str = "chronicle.googleapis.com" @@ -182,6 +186,20 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), + self.verify_reference_list: gapic_v1.method.wrap_method( + self.verify_reference_list, + default_retry=retries.Retry( + initial=1.0, + maximum=60.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), self.cancel_operation: gapic_v1.method.wrap_method( self.cancel_operation, default_timeout=None, @@ -258,6 +276,18 @@ def update_reference_list( ]: raise NotImplementedError() + @property + def verify_reference_list( + self, + ) -> Callable[ + [reference_list.VerifyReferenceListRequest], + Union[ + reference_list.VerifyReferenceListResponse, + Awaitable[reference_list.VerifyReferenceListResponse], + ], + ]: + raise NotImplementedError() + @property def list_operations( self, diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/reference_list_service/transports/grpc.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/reference_list_service/transports/grpc.py index afb29f951599..02290a95738a 100644 --- a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/reference_list_service/transports/grpc.py +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/reference_list_service/transports/grpc.py @@ -443,6 +443,36 @@ def update_reference_list( ) return self._stubs["update_reference_list"] + @property + def verify_reference_list( + self, + ) -> Callable[ + [reference_list.VerifyReferenceListRequest], + reference_list.VerifyReferenceListResponse, + ]: + r"""Return a callable for the verify reference list method over gRPC. + + VerifyReferenceList validates list content and + returns line errors, if any. + + Returns: + Callable[[~.VerifyReferenceListRequest], + ~.VerifyReferenceListResponse]: + 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 "verify_reference_list" not in self._stubs: + self._stubs["verify_reference_list"] = self._logged_channel.unary_unary( + "/google.cloud.chronicle.v1.ReferenceListService/VerifyReferenceList", + request_serializer=reference_list.VerifyReferenceListRequest.serialize, + response_deserializer=reference_list.VerifyReferenceListResponse.deserialize, + ) + return self._stubs["verify_reference_list"] + def close(self): self._logged_channel.close() diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/reference_list_service/transports/grpc_asyncio.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/reference_list_service/transports/grpc_asyncio.py index 185593e53a91..81b94111dcfd 100644 --- a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/reference_list_service/transports/grpc_asyncio.py +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/reference_list_service/transports/grpc_asyncio.py @@ -452,6 +452,36 @@ def update_reference_list( ) return self._stubs["update_reference_list"] + @property + def verify_reference_list( + self, + ) -> Callable[ + [reference_list.VerifyReferenceListRequest], + Awaitable[reference_list.VerifyReferenceListResponse], + ]: + r"""Return a callable for the verify reference list method over gRPC. + + VerifyReferenceList validates list content and + returns line errors, if any. + + Returns: + Callable[[~.VerifyReferenceListRequest], + Awaitable[~.VerifyReferenceListResponse]]: + 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 "verify_reference_list" not in self._stubs: + self._stubs["verify_reference_list"] = self._logged_channel.unary_unary( + "/google.cloud.chronicle.v1.ReferenceListService/VerifyReferenceList", + request_serializer=reference_list.VerifyReferenceListRequest.serialize, + response_deserializer=reference_list.VerifyReferenceListResponse.deserialize, + ) + return self._stubs["verify_reference_list"] + def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { @@ -493,6 +523,20 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), + self.verify_reference_list: self._wrap_method( + self.verify_reference_list, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=60.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), self.cancel_operation: self._wrap_method( self.cancel_operation, default_timeout=None, diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/reference_list_service/transports/rest.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/reference_list_service/transports/rest.py index de4f4cef98f1..edf00c108178 100644 --- a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/reference_list_service/transports/rest.py +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/reference_list_service/transports/rest.py @@ -106,6 +106,14 @@ def post_update_reference_list(self, response): logging.log(f"Received response: {response}") return response + def pre_verify_reference_list(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_verify_reference_list(self, response): + logging.log(f"Received response: {response}") + return response + transport = ReferenceListServiceRestTransport(interceptor=MyCustomReferenceListServiceInterceptor()) client = ReferenceListServiceClient(transport=transport) @@ -314,6 +322,58 @@ def post_update_reference_list_with_metadata( """ return response, metadata + def pre_verify_reference_list( + self, + request: reference_list.VerifyReferenceListRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + reference_list.VerifyReferenceListRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for verify_reference_list + + Override in a subclass to manipulate the request or metadata + before they are sent to the ReferenceListService server. + """ + return request, metadata + + def post_verify_reference_list( + self, response: reference_list.VerifyReferenceListResponse + ) -> reference_list.VerifyReferenceListResponse: + """Post-rpc interceptor for verify_reference_list + + DEPRECATED. Please use the `post_verify_reference_list_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the ReferenceListService server but before + it is returned to user code. This `post_verify_reference_list` interceptor runs + before the `post_verify_reference_list_with_metadata` interceptor. + """ + return response + + def post_verify_reference_list_with_metadata( + self, + response: reference_list.VerifyReferenceListResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + reference_list.VerifyReferenceListResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for verify_reference_list + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ReferenceListService server but before it is returned to user code. + + We recommend only using this `post_verify_reference_list_with_metadata` + interceptor in new development instead of the `post_verify_reference_list` interceptor. + When both interceptors are used, this `post_verify_reference_list_with_metadata` interceptor runs after the + `post_verify_reference_list` interceptor. The (possibly modified) response returned by + `post_verify_reference_list` will be passed to + `post_verify_reference_list_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -1127,6 +1187,161 @@ def __call__( ) return resp + class _VerifyReferenceList( + _BaseReferenceListServiceRestTransport._BaseVerifyReferenceList, + ReferenceListServiceRestStub, + ): + def __hash__(self): + return hash("ReferenceListServiceRestTransport.VerifyReferenceList") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: reference_list.VerifyReferenceListRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> reference_list.VerifyReferenceListResponse: + r"""Call the verify reference list method over HTTP. + + Args: + request (~.reference_list.VerifyReferenceListRequest): + The request object. VerifyReferenceList request message. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.reference_list.VerifyReferenceListResponse: + VerifyListResponse response message. + """ + + http_options = _BaseReferenceListServiceRestTransport._BaseVerifyReferenceList._get_http_options() + + request, metadata = self._interceptor.pre_verify_reference_list( + request, metadata + ) + transcoded_request = _BaseReferenceListServiceRestTransport._BaseVerifyReferenceList._get_transcoded_request( + http_options, request + ) + + body = _BaseReferenceListServiceRestTransport._BaseVerifyReferenceList._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseReferenceListServiceRestTransport._BaseVerifyReferenceList._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.chronicle_v1.ReferenceListServiceClient.VerifyReferenceList", + extra={ + "serviceName": "google.cloud.chronicle.v1.ReferenceListService", + "rpcName": "VerifyReferenceList", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + ReferenceListServiceRestTransport._VerifyReferenceList._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = reference_list.VerifyReferenceListResponse() + pb_resp = reference_list.VerifyReferenceListResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_verify_reference_list(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_verify_reference_list_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + reference_list.VerifyReferenceListResponse.to_json(response) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.chronicle_v1.ReferenceListServiceClient.verify_reference_list", + extra={ + "serviceName": "google.cloud.chronicle.v1.ReferenceListService", + "rpcName": "VerifyReferenceList", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + @property def create_reference_list( self, @@ -1170,6 +1385,17 @@ def update_reference_list( # In C++ this would require a dynamic_cast return self._UpdateReferenceList(self._session, self._host, self._interceptor) # type: ignore + @property + def verify_reference_list( + self, + ) -> Callable[ + [reference_list.VerifyReferenceListRequest], + reference_list.VerifyReferenceListResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._VerifyReferenceList(self._session, self._host, self._interceptor) # type: ignore + @property def cancel_operation(self): return self._CancelOperation(self._session, self._host, self._interceptor) # type: ignore diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/reference_list_service/transports/rest_base.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/reference_list_service/transports/rest_base.py index 3a964df8c43b..c1d673052a92 100644 --- a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/reference_list_service/transports/rest_base.py +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/reference_list_service/transports/rest_base.py @@ -299,6 +299,63 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params + class _BaseVerifyReferenceList: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{instance=projects/*/locations/*/instances/*}:verifyReferenceList", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = reference_list.VerifyReferenceListRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseReferenceListServiceRestTransport._BaseVerifyReferenceList._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + class _BaseCancelOperation: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/__init__.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/__init__.py new file mode 100644 index 000000000000..19e2479d30d5 --- /dev/null +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .async_client import RuleExecutionErrorServiceAsyncClient +from .client import RuleExecutionErrorServiceClient + +__all__ = ( + "RuleExecutionErrorServiceClient", + "RuleExecutionErrorServiceAsyncClient", +) diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/async_client.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/async_client.py new file mode 100644 index 000000000000..ac0db34ff1f4 --- /dev/null +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/async_client.py @@ -0,0 +1,708 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 logging as std_logging +import re +from collections import OrderedDict +from typing import ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, +) + +import google.protobuf +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.api_core.client_options import ClientOptions +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.chronicle_v1 import gapic_version as package_version + +try: + OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.longrunning import operations_pb2 # type: ignore + +from google.cloud.chronicle_v1.services.rule_execution_error_service import pagers +from google.cloud.chronicle_v1.types import rule_execution_error + +from .client import RuleExecutionErrorServiceClient +from .transports.base import DEFAULT_CLIENT_INFO, RuleExecutionErrorServiceTransport +from .transports.grpc_asyncio import RuleExecutionErrorServiceGrpcAsyncIOTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class RuleExecutionErrorServiceAsyncClient: + """RuleExecutionErrorService contains endpoints related to rule + execution errors. + """ + + _client: RuleExecutionErrorServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = RuleExecutionErrorServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = RuleExecutionErrorServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + RuleExecutionErrorServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = RuleExecutionErrorServiceClient._DEFAULT_UNIVERSE + + curated_rule_path = staticmethod(RuleExecutionErrorServiceClient.curated_rule_path) + parse_curated_rule_path = staticmethod( + RuleExecutionErrorServiceClient.parse_curated_rule_path + ) + rule_path = staticmethod(RuleExecutionErrorServiceClient.rule_path) + parse_rule_path = staticmethod(RuleExecutionErrorServiceClient.parse_rule_path) + rule_execution_error_path = staticmethod( + RuleExecutionErrorServiceClient.rule_execution_error_path + ) + parse_rule_execution_error_path = staticmethod( + RuleExecutionErrorServiceClient.parse_rule_execution_error_path + ) + common_billing_account_path = staticmethod( + RuleExecutionErrorServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + RuleExecutionErrorServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + RuleExecutionErrorServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + RuleExecutionErrorServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + RuleExecutionErrorServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + RuleExecutionErrorServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + RuleExecutionErrorServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + RuleExecutionErrorServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + RuleExecutionErrorServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + RuleExecutionErrorServiceClient.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: + RuleExecutionErrorServiceAsyncClient: The constructed client. + """ + sa_info_func = ( + RuleExecutionErrorServiceClient.from_service_account_info.__func__ # type: ignore + ) + return sa_info_func(RuleExecutionErrorServiceAsyncClient, info, *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: + RuleExecutionErrorServiceAsyncClient: The constructed client. + """ + sa_file_func = ( + RuleExecutionErrorServiceClient.from_service_account_file.__func__ # type: ignore + ) + return sa_file_func( + RuleExecutionErrorServiceAsyncClient, filename, *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 variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return RuleExecutionErrorServiceClient.get_mtls_endpoint_and_cert_source( + client_options + ) # type: ignore + + @property + def transport(self) -> RuleExecutionErrorServiceTransport: + """Returns the transport used by the client instance. + + Returns: + RuleExecutionErrorServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self) -> str: + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = RuleExecutionErrorServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + RuleExecutionErrorServiceTransport, + Callable[..., RuleExecutionErrorServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the rule execution error service async 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 (Optional[Union[str,RuleExecutionErrorServiceTransport,Callable[..., RuleExecutionErrorServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the RuleExecutionErrorServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "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). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS 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. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + 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. + """ + self._client = RuleExecutionErrorServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.cloud.chronicle_v1.RuleExecutionErrorServiceAsyncClient`.", + extra={ + "serviceName": "google.cloud.chronicle.v1.RuleExecutionErrorService", + "universeDomain": getattr( + self._client._transport._credentials, "universe_domain", "" + ), + "credentialsType": f"{type(self._client._transport._credentials).__module__}.{type(self._client._transport._credentials).__qualname__}", + "credentialsInfo": getattr( + self.transport._credentials, "get_cred_info", lambda: None + )(), + } + if hasattr(self._client._transport, "_credentials") + else { + "serviceName": "google.cloud.chronicle.v1.RuleExecutionErrorService", + "credentialsType": None, + }, + ) + + async def list_rule_execution_errors( + self, + request: Optional[ + Union[rule_execution_error.ListRuleExecutionErrorsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListRuleExecutionErrorsAsyncPager: + r"""Lists rule execution errors. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import chronicle_v1 + + async def sample_list_rule_execution_errors(): + # Create a client + client = chronicle_v1.RuleExecutionErrorServiceAsyncClient() + + # Initialize request argument(s) + request = chronicle_v1.ListRuleExecutionErrorsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_rule_execution_errors(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.chronicle_v1.types.ListRuleExecutionErrorsRequest, dict]]): + The request object. Request message for + ListRuleExecutionErrors. + parent (:class:`str`): + Required. The instance to list rule + execution errors from. Format: + + projects/{project}/locations/{location}/instances/{instance} + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.chronicle_v1.services.rule_execution_error_service.pagers.ListRuleExecutionErrorsAsyncPager: + Response message for + ListRuleExecutionErrors. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, rule_execution_error.ListRuleExecutionErrorsRequest): + request = rule_execution_error.ListRuleExecutionErrorsRequest(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._client._transport._wrapped_methods[ + self._client._transport.list_rule_execution_errors + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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.ListRuleExecutionErrorsAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[Union[operations_pb2.ListOperationsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if request is None: + request_pb = operations_pb2.ListOperationsRequest() + elif isinstance(request, dict): + request_pb = operations_pb2.ListOperationsRequest(**request) + else: + request_pb = request + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.list_operations] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request_pb.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request_pb, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[Union[operations_pb2.GetOperationRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if request is None: + request_pb = operations_pb2.GetOperationRequest() + elif isinstance(request, dict): + request_pb = operations_pb2.GetOperationRequest(**request) + else: + request_pb = request + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request_pb.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request_pb, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_operation( + self, + request: Optional[Union[operations_pb2.DeleteOperationRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Deletes a long-running operation. + + This method indicates that the client is no longer interested + in the operation result. It does not cancel the operation. + If the server doesn't support this method, it returns + `google.rpc.Code.UNIMPLEMENTED`. + + Args: + request (:class:`~.operations_pb2.DeleteOperationRequest`): + The request object. Request message for + `DeleteOperation` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + None + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if request is None: + request_pb = operations_pb2.DeleteOperationRequest() + elif isinstance(request, dict): + request_pb = operations_pb2.DeleteOperationRequest(**request) + else: + request_pb = request + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.delete_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request_pb.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request_pb, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def cancel_operation( + self, + request: Optional[Union[operations_pb2.CancelOperationRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Starts asynchronous cancellation on a long-running operation. + + The server makes a best effort to cancel the operation, but success + is not guaranteed. If the server doesn't support this method, it returns + `google.rpc.Code.UNIMPLEMENTED`. + + Args: + request (:class:`~.operations_pb2.CancelOperationRequest`): + The request object. Request message for + `CancelOperation` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + None + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if request is None: + request_pb = operations_pb2.CancelOperationRequest() + elif isinstance(request, dict): + request_pb = operations_pb2.CancelOperationRequest(**request) + else: + request_pb = request + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.cancel_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request_pb.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request_pb, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def __aenter__(self) -> "RuleExecutionErrorServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("RuleExecutionErrorServiceAsyncClient",) diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/client.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/client.py new file mode 100644 index 000000000000..776dc45f3acf --- /dev/null +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/client.py @@ -0,0 +1,1188 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 json +import logging as std_logging +import os +import re +import warnings +from collections import OrderedDict +from http import HTTPStatus +from typing import ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) + +import google.protobuf +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.chronicle_v1 import gapic_version as package_version + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + +from google.longrunning import operations_pb2 # type: ignore + +from google.cloud.chronicle_v1.services.rule_execution_error_service import pagers +from google.cloud.chronicle_v1.types import rule_execution_error + +from .transports.base import DEFAULT_CLIENT_INFO, RuleExecutionErrorServiceTransport +from .transports.grpc import RuleExecutionErrorServiceGrpcTransport +from .transports.grpc_asyncio import RuleExecutionErrorServiceGrpcAsyncIOTransport +from .transports.rest import RuleExecutionErrorServiceRestTransport + + +class RuleExecutionErrorServiceClientMeta(type): + """Metaclass for the RuleExecutionErrorService 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[RuleExecutionErrorServiceTransport]] + _transport_registry["grpc"] = RuleExecutionErrorServiceGrpcTransport + _transport_registry["grpc_asyncio"] = RuleExecutionErrorServiceGrpcAsyncIOTransport + _transport_registry["rest"] = RuleExecutionErrorServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[RuleExecutionErrorServiceTransport]: + """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 RuleExecutionErrorServiceClient(metaclass=RuleExecutionErrorServiceClientMeta): + """RuleExecutionErrorService contains endpoints related to rule + execution errors. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint) -> Optional[str]: + """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: + Optional[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) + if m is None: + # Could not parse api_endpoint; return as-is. + return 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") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "chronicle.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "chronicle.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @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: + RuleExecutionErrorServiceClient: 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: + RuleExecutionErrorServiceClient: 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) -> RuleExecutionErrorServiceTransport: + """Returns the transport used by the client instance. + + Returns: + RuleExecutionErrorServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def curated_rule_path( + project: str, + location: str, + instance: str, + curatedRule: str, + ) -> str: + """Returns a fully-qualified curated_rule string.""" + return "projects/{project}/locations/{location}/instances/{instance}/curatedRules/{curatedRule}".format( + project=project, + location=location, + instance=instance, + curatedRule=curatedRule, + ) + + @staticmethod + def parse_curated_rule_path(path: str) -> Dict[str, str]: + """Parses a curated_rule path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/instances/(?P.+?)/curatedRules/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def rule_path( + project: str, + location: str, + instance: str, + rule: str, + ) -> str: + """Returns a fully-qualified rule string.""" + return "projects/{project}/locations/{location}/instances/{instance}/rules/{rule}".format( + project=project, + location=location, + instance=instance, + rule=rule, + ) + + @staticmethod + def parse_rule_path(path: str) -> Dict[str, str]: + """Parses a rule path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/instances/(?P.+?)/rules/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def rule_execution_error_path( + project: str, + location: str, + instance: str, + rule_execution_error: str, + ) -> str: + """Returns a fully-qualified rule_execution_error string.""" + return "projects/{project}/locations/{location}/instances/{instance}/ruleExecutionErrors/{rule_execution_error}".format( + project=project, + location=location, + instance=instance, + rule_execution_error=rule_execution_error, + ) + + @staticmethod + def parse_rule_execution_error_path(path: str) -> Dict[str, str]: + """Parses a rule_execution_error path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/instances/(?P.+?)/ruleExecutionErrors/(?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 + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = RuleExecutionErrorServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + 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: + 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 + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = RuleExecutionErrorServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ) -> str: + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = RuleExecutionErrorServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = RuleExecutionErrorServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + RuleExecutionErrorServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], universe_domain_env: Optional[str] + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = RuleExecutionErrorServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self) -> str: + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + RuleExecutionErrorServiceTransport, + Callable[..., RuleExecutionErrorServiceTransport], + ] + ] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the rule execution error 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 (Optional[Union[str,RuleExecutionErrorServiceTransport,Callable[..., RuleExecutionErrorServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the RuleExecutionErrorServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "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). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS 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. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + 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. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict(self._client_options) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr(self._client_options, "universe_domain", None) + + self._use_client_cert, self._use_mtls_endpoint, self._universe_domain_env = ( + RuleExecutionErrorServiceClient._read_environment_variables() + ) + self._client_cert_source = ( + RuleExecutionErrorServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = RuleExecutionErrorServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint: str = "" # updated below, depending on `transport` + + # Initialize the universe domain validation. + self._is_universe_domain_valid = False + + if CLIENT_LOGGING_SUPPORTED: # pragma: NO COVER + # Setup logging. + client_logging.initialize_logging() + + api_key_value = getattr(self._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. + transport_provided = isinstance(transport, RuleExecutionErrorServiceTransport) + if transport_provided: + # transport is a RuleExecutionErrorServiceTransport instance. + if credentials or self._client_options.credentials_file or api_key_value: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes directly." + ) + self._transport = cast(RuleExecutionErrorServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or RuleExecutionErrorServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + 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_init: Union[ + Type[RuleExecutionErrorServiceTransport], + Callable[..., RuleExecutionErrorServiceTransport], + ] = ( + RuleExecutionErrorServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., RuleExecutionErrorServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + api_audience=self._client_options.api_audience, + ) + + if "async" not in str(self._transport): + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.cloud.chronicle_v1.RuleExecutionErrorServiceClient`.", + extra={ + "serviceName": "google.cloud.chronicle.v1.RuleExecutionErrorService", + "universeDomain": getattr( + self._transport._credentials, "universe_domain", "" + ), + "credentialsType": f"{type(self._transport._credentials).__module__}.{type(self._transport._credentials).__qualname__}", + "credentialsInfo": getattr( + self.transport._credentials, "get_cred_info", lambda: None + )(), + } + if hasattr(self._transport, "_credentials") + else { + "serviceName": "google.cloud.chronicle.v1.RuleExecutionErrorService", + "credentialsType": None, + }, + ) + + def list_rule_execution_errors( + self, + request: Optional[ + Union[rule_execution_error.ListRuleExecutionErrorsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListRuleExecutionErrorsPager: + r"""Lists rule execution errors. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import chronicle_v1 + + def sample_list_rule_execution_errors(): + # Create a client + client = chronicle_v1.RuleExecutionErrorServiceClient() + + # Initialize request argument(s) + request = chronicle_v1.ListRuleExecutionErrorsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_rule_execution_errors(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.chronicle_v1.types.ListRuleExecutionErrorsRequest, dict]): + The request object. Request message for + ListRuleExecutionErrors. + parent (str): + Required. The instance to list rule + execution errors from. Format: + + projects/{project}/locations/{location}/instances/{instance} + + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.chronicle_v1.services.rule_execution_error_service.pagers.ListRuleExecutionErrorsPager: + Response message for + ListRuleExecutionErrors. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, rule_execution_error.ListRuleExecutionErrorsRequest): + request = rule_execution_error.ListRuleExecutionErrorsRequest(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_rule_execution_errors + ] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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.ListRuleExecutionErrorsPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "RuleExecutionErrorServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + def list_operations( + self, + request: Optional[Union[operations_pb2.ListOperationsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if request is None: + request_pb = operations_pb2.ListOperationsRequest() + elif isinstance(request, dict): + request_pb = operations_pb2.ListOperationsRequest(**request) + else: + request_pb = request + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_operations] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request_pb.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request_pb, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + def get_operation( + self, + request: Optional[Union[operations_pb2.GetOperationRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if request is None: + request_pb = operations_pb2.GetOperationRequest() + elif isinstance(request, dict): + request_pb = operations_pb2.GetOperationRequest(**request) + else: + request_pb = request + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request_pb.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request_pb, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + def delete_operation( + self, + request: Optional[Union[operations_pb2.DeleteOperationRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Deletes a long-running operation. + + This method indicates that the client is no longer interested + in the operation result. It does not cancel the operation. + If the server doesn't support this method, it returns + `google.rpc.Code.UNIMPLEMENTED`. + + Args: + request (:class:`~.operations_pb2.DeleteOperationRequest`): + The request object. Request message for + `DeleteOperation` 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + None + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if request is None: + request_pb = operations_pb2.DeleteOperationRequest() + elif isinstance(request, dict): + request_pb = operations_pb2.DeleteOperationRequest(**request) + else: + request_pb = request + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.delete_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request_pb.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + rpc( + request_pb, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def cancel_operation( + self, + request: Optional[Union[operations_pb2.CancelOperationRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Starts asynchronous cancellation on a long-running operation. + + The server makes a best effort to cancel the operation, but success + is not guaranteed. If the server doesn't support this method, it returns + `google.rpc.Code.UNIMPLEMENTED`. + + Args: + request (:class:`~.operations_pb2.CancelOperationRequest`): + The request object. Request message for + `CancelOperation` 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + None + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if request is None: + request_pb = operations_pb2.CancelOperationRequest() + elif isinstance(request, dict): + request_pb = operations_pb2.CancelOperationRequest(**request) + else: + request_pb = request + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.cancel_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request_pb.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + rpc( + request_pb, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("RuleExecutionErrorServiceClient",) diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/pagers.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/pagers.py new file mode 100644 index 000000000000..d3c8caec0a00 --- /dev/null +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/pagers.py @@ -0,0 +1,201 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, + Union, +) + +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import retry_async as retries_async + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] + OptionalAsyncRetry = Union[ + retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore + +from google.cloud.chronicle_v1.types import rule_execution_error + + +class ListRuleExecutionErrorsPager: + """A pager for iterating through ``list_rule_execution_errors`` requests. + + This class thinly wraps an initial + :class:`google.cloud.chronicle_v1.types.ListRuleExecutionErrorsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``rule_execution_errors`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListRuleExecutionErrors`` requests and continue to iterate + through the ``rule_execution_errors`` field on the + corresponding responses. + + All the usual :class:`google.cloud.chronicle_v1.types.ListRuleExecutionErrorsResponse` + 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[..., rule_execution_error.ListRuleExecutionErrorsResponse], + request: rule_execution_error.ListRuleExecutionErrorsRequest, + response: rule_execution_error.ListRuleExecutionErrorsResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.chronicle_v1.types.ListRuleExecutionErrorsRequest): + The initial request object. + response (google.cloud.chronicle_v1.types.ListRuleExecutionErrorsResponse): + The initial response object. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = rule_execution_error.ListRuleExecutionErrorsRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[rule_execution_error.ListRuleExecutionErrorsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __iter__(self) -> Iterator[rule_execution_error.RuleExecutionError]: + for page in self.pages: + yield from page.rule_execution_errors + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListRuleExecutionErrorsAsyncPager: + """A pager for iterating through ``list_rule_execution_errors`` requests. + + This class thinly wraps an initial + :class:`google.cloud.chronicle_v1.types.ListRuleExecutionErrorsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``rule_execution_errors`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListRuleExecutionErrors`` requests and continue to iterate + through the ``rule_execution_errors`` field on the + corresponding responses. + + All the usual :class:`google.cloud.chronicle_v1.types.ListRuleExecutionErrorsResponse` + 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[rule_execution_error.ListRuleExecutionErrorsResponse] + ], + request: rule_execution_error.ListRuleExecutionErrorsRequest, + response: rule_execution_error.ListRuleExecutionErrorsResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.chronicle_v1.types.ListRuleExecutionErrorsRequest): + The initial request object. + response (google.cloud.chronicle_v1.types.ListRuleExecutionErrorsResponse): + The initial response object. + retry (google.api_core.retry.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = rule_execution_error.ListRuleExecutionErrorsRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[rule_execution_error.ListRuleExecutionErrorsResponse]: + 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, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __aiter__(self) -> AsyncIterator[rule_execution_error.RuleExecutionError]: + async def async_generator(): + async for page in self.pages: + for response in page.rule_execution_errors: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/transports/README.rst b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/transports/README.rst new file mode 100644 index 000000000000..3fbe22612bd7 --- /dev/null +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/transports/README.rst @@ -0,0 +1,10 @@ + +transport inheritance structure +_______________________________ + +``RuleExecutionErrorServiceTransport`` is the ABC for all transports. + +- public child ``RuleExecutionErrorServiceGrpcTransport`` for sync gRPC transport (defined in ``grpc.py``). +- public child ``RuleExecutionErrorServiceGrpcAsyncIOTransport`` for async gRPC transport (defined in ``grpc_asyncio.py``). +- private child ``_BaseRuleExecutionErrorServiceRestTransport`` for base REST transport with inner classes ``_BaseMETHOD`` (defined in ``rest_base.py``). +- public child ``RuleExecutionErrorServiceRestTransport`` for sync REST transport with inner classes ``METHOD`` derived from the parent's corresponding ``_BaseMETHOD`` classes (defined in ``rest.py``). diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/transports/__init__.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/transports/__init__.py new file mode 100644 index 000000000000..79b16393ae0e --- /dev/null +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/transports/__init__.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 RuleExecutionErrorServiceTransport +from .grpc import RuleExecutionErrorServiceGrpcTransport +from .grpc_asyncio import RuleExecutionErrorServiceGrpcAsyncIOTransport +from .rest import ( + RuleExecutionErrorServiceRestInterceptor, + RuleExecutionErrorServiceRestTransport, +) + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[RuleExecutionErrorServiceTransport]] +_transport_registry["grpc"] = RuleExecutionErrorServiceGrpcTransport +_transport_registry["grpc_asyncio"] = RuleExecutionErrorServiceGrpcAsyncIOTransport +_transport_registry["rest"] = RuleExecutionErrorServiceRestTransport + +__all__ = ( + "RuleExecutionErrorServiceTransport", + "RuleExecutionErrorServiceGrpcTransport", + "RuleExecutionErrorServiceGrpcAsyncIOTransport", + "RuleExecutionErrorServiceRestTransport", + "RuleExecutionErrorServiceRestInterceptor", +) diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/transports/base.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/transports/base.py new file mode 100644 index 000000000000..c69c33dbe21f --- /dev/null +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/transports/base.py @@ -0,0 +1,251 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union + +import google.api_core +import google.auth # type: ignore +import google.protobuf +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.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.chronicle_v1 import gapic_version as package_version +from google.cloud.chronicle_v1.types import rule_execution_error + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class RuleExecutionErrorServiceTransport(abc.ABC): + """Abstract transport class for RuleExecutionErrorService.""" + + AUTH_SCOPES = ( + "https://www.googleapis.com/auth/chronicle", + "https://www.googleapis.com/auth/chronicle.readonly", + "https://www.googleapis.com/auth/cloud-platform", + ) + + DEFAULT_HOST: str = "chronicle.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'chronicle.googleapis.com'). + 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]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + 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. + api_audience (Optional[str]): The intended audience for the API calls + to the service that will be set when using certain 3rd party + authentication flows. Audience is typically a resource identifier. + If not set, the host value will be used as a default. + """ + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # 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=scopes, + quota_project_id=quota_project_id, + default_scopes=self.AUTH_SCOPES, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + scopes=scopes, + quota_project_id=quota_project_id, + default_scopes=self.AUTH_SCOPES, + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr(service_account.Credentials, "with_always_use_jwt_access") + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + self._wrapped_methods: Dict[Callable, Callable] = {} + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.list_rule_execution_errors: gapic_v1.method.wrap_method( + self.list_rule_execution_errors, + default_retry=retries.Retry( + initial=1.0, + maximum=600.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.cancel_operation: gapic_v1.method.wrap_method( + self.cancel_operation, + default_timeout=None, + client_info=client_info, + ), + self.delete_operation: gapic_v1.method.wrap_method( + self.delete_operation, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: gapic_v1.method.wrap_method( + self.get_operation, + default_timeout=None, + client_info=client_info, + ), + self.list_operations: gapic_v1.method.wrap_method( + self.list_operations, + 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_rule_execution_errors( + self, + ) -> Callable[ + [rule_execution_error.ListRuleExecutionErrorsRequest], + Union[ + rule_execution_error.ListRuleExecutionErrorsResponse, + Awaitable[rule_execution_error.ListRuleExecutionErrorsResponse], + ], + ]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[ + operations_pb2.ListOperationsResponse, + Awaitable[operations_pb2.ListOperationsResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def cancel_operation( + self, + ) -> Callable[ + [operations_pb2.CancelOperationRequest], + None, + ]: + raise NotImplementedError() + + @property + def delete_operation( + self, + ) -> Callable[ + [operations_pb2.DeleteOperationRequest], + None, + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("RuleExecutionErrorServiceTransport",) diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/transports/grpc.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/transports/grpc.py new file mode 100644 index 000000000000..042756eb18da --- /dev/null +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/transports/grpc.py @@ -0,0 +1,439 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 json +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +import google.auth # type: ignore +import google.protobuf.message +import grpc # type: ignore +import proto # type: ignore +from google.api_core import gapic_v1, grpc_helpers +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson + +from google.cloud.chronicle_v1.types import rule_execution_error + +from .base import DEFAULT_CLIENT_INFO, RuleExecutionErrorServiceTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor(grpc.UnaryUnaryClientInterceptor): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = f"{type(request).__name__}: {pickle.dumps(request)!r}" + + request_metadata = { + key: value.decode("utf-8") if isinstance(value, bytes) else value + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.cloud.chronicle.v1.RuleExecutionErrorService", + "rpcName": str(client_call_details.method), + "request": grpc_request, + "metadata": grpc_request["metadata"], + }, + ) + response = continuation(client_call_details, request) + if logging_enabled: # pragma: NO COVER + response_metadata = response.trailing_metadata() + # Convert gRPC metadata `` to list of tuples + metadata = ( + dict([(k, str(v)) for k, v in response_metadata]) + if response_metadata + else None + ) + result = response.result() + if isinstance(result, proto.Message): + response_payload = type(result).to_json(result) + elif isinstance(result, google.protobuf.message.Message): + response_payload = MessageToJson(result) + else: + response_payload = f"{type(result).__name__}: {pickle.dumps(result)!r}" + grpc_response = { + "payload": response_payload, + "metadata": metadata, + "status": "OK", + } + _LOGGER.debug( + f"Received response for {client_call_details.method}.", + extra={ + "serviceName": "google.cloud.chronicle.v1.RuleExecutionErrorService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class RuleExecutionErrorServiceGrpcTransport(RuleExecutionErrorServiceTransport): + """gRPC backend transport for RuleExecutionErrorService. + + RuleExecutionErrorService contains endpoints related to rule + execution errors. + + 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 = "chronicle.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'chronicle.googleapis.com'). + 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 a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + 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 a ``channel`` instance 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 a ``channel`` instance 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. + api_audience (Optional[str]): The intended audience for the API calls + to the service that will be set when using certain 3rd party + authentication flows. Audience is typically a resource identifier. + If not set, the host value will be used as a default. + + 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 isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + self._interceptor = _LoggingClientInterceptor() + self._logged_channel = grpc.intercept_channel( + self._grpc_channel, self._interceptor + ) + + # Wrap messages. This must be done after self._logged_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "chronicle.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + 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_rule_execution_errors( + self, + ) -> Callable[ + [rule_execution_error.ListRuleExecutionErrorsRequest], + rule_execution_error.ListRuleExecutionErrorsResponse, + ]: + r"""Return a callable for the list rule execution errors method over gRPC. + + Lists rule execution errors. + + Returns: + Callable[[~.ListRuleExecutionErrorsRequest], + ~.ListRuleExecutionErrorsResponse]: + 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_rule_execution_errors" not in self._stubs: + self._stubs["list_rule_execution_errors"] = ( + self._logged_channel.unary_unary( + "/google.cloud.chronicle.v1.RuleExecutionErrorService/ListRuleExecutionErrors", + request_serializer=rule_execution_error.ListRuleExecutionErrorsRequest.serialize, + response_deserializer=rule_execution_error.ListRuleExecutionErrorsResponse.deserialize, + ) + ) + return self._stubs["list_rule_execution_errors"] + + def close(self): + self._logged_channel.close() + + @property + def delete_operation( + self, + ) -> Callable[[operations_pb2.DeleteOperationRequest], None]: + r"""Return a callable for the delete_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_operation" not in self._stubs: + self._stubs["delete_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/DeleteOperation", + request_serializer=operations_pb2.DeleteOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["delete_operation"] + + @property + def cancel_operation( + self, + ) -> Callable[[operations_pb2.CancelOperationRequest], None]: + r"""Return a callable for the cancel_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "cancel_operation" not in self._stubs: + self._stubs["cancel_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/CancelOperation", + request_serializer=operations_pb2.CancelOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["cancel_operation"] + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_operation" not in self._stubs: + self._stubs["get_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse + ]: + r"""Return a callable for the list_operations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_operations" not in self._stubs: + self._stubs["list_operations"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("RuleExecutionErrorServiceGrpcTransport",) diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/transports/grpc_asyncio.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/transports/grpc_asyncio.py new file mode 100644 index 000000000000..1768420165a4 --- /dev/null +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/transports/grpc_asyncio.py @@ -0,0 +1,491 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 inspect +import json +import logging as std_logging +import pickle +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +import google.protobuf.message +import grpc # type: ignore +import proto # type: ignore +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, grpc_helpers_async +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +from grpc.experimental import aio # type: ignore + +from google.cloud.chronicle_v1.types import rule_execution_error + +from .base import DEFAULT_CLIENT_INFO, RuleExecutionErrorServiceTransport +from .grpc import RuleExecutionErrorServiceGrpcTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientAIOInterceptor( + grpc.aio.UnaryUnaryClientInterceptor +): # pragma: NO COVER + async def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = f"{type(request).__name__}: {pickle.dumps(request)!r}" + + request_metadata = { + key: value.decode("utf-8") if isinstance(value, bytes) else value + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.cloud.chronicle.v1.RuleExecutionErrorService", + "rpcName": str(client_call_details.method), + "request": grpc_request, + "metadata": grpc_request["metadata"], + }, + ) + response = await continuation(client_call_details, request) + if logging_enabled: # pragma: NO COVER + response_metadata = await response.trailing_metadata() + # Convert gRPC metadata `` to list of tuples + metadata = ( + dict([(k, str(v)) for k, v in response_metadata]) + if response_metadata + else None + ) + result = await response + if isinstance(result, proto.Message): + response_payload = type(result).to_json(result) + elif isinstance(result, google.protobuf.message.Message): + response_payload = MessageToJson(result) + else: + response_payload = f"{type(result).__name__}: {pickle.dumps(result)!r}" + grpc_response = { + "payload": response_payload, + "metadata": metadata, + "status": "OK", + } + _LOGGER.debug( + f"Received response to rpc {client_call_details.method}.", + extra={ + "serviceName": "google.cloud.chronicle.v1.RuleExecutionErrorService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class RuleExecutionErrorServiceGrpcAsyncIOTransport(RuleExecutionErrorServiceTransport): + """gRPC AsyncIO backend transport for RuleExecutionErrorService. + + RuleExecutionErrorService contains endpoints related to rule + execution errors. + + 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 = "chronicle.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + 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 = "chronicle.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[Union[aio.Channel, Callable[..., aio.Channel]]] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'chronicle.googleapis.com'). + 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 a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + 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[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + 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 a ``channel`` instance 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 a ``channel`` instance 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. + api_audience (Optional[str]): The intended audience for the API calls + to the service that will be set when using certain 3rd party + authentication flows. Audience is typically a resource identifier. + If not set, the host value will be used as a default. + + 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 isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + self._interceptor = _LoggingClientAIOInterceptor() + self._grpc_channel._unary_unary_interceptors.append(self._interceptor) + self._logged_channel = self._grpc_channel + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) + # Wrap messages. This must be done after self._logged_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_rule_execution_errors( + self, + ) -> Callable[ + [rule_execution_error.ListRuleExecutionErrorsRequest], + Awaitable[rule_execution_error.ListRuleExecutionErrorsResponse], + ]: + r"""Return a callable for the list rule execution errors method over gRPC. + + Lists rule execution errors. + + Returns: + Callable[[~.ListRuleExecutionErrorsRequest], + Awaitable[~.ListRuleExecutionErrorsResponse]]: + 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_rule_execution_errors" not in self._stubs: + self._stubs["list_rule_execution_errors"] = ( + self._logged_channel.unary_unary( + "/google.cloud.chronicle.v1.RuleExecutionErrorService/ListRuleExecutionErrors", + request_serializer=rule_execution_error.ListRuleExecutionErrorsRequest.serialize, + response_deserializer=rule_execution_error.ListRuleExecutionErrorsResponse.deserialize, + ) + ) + return self._stubs["list_rule_execution_errors"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.list_rule_execution_errors: self._wrap_method( + self.list_rule_execution_errors, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=600.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.cancel_operation: self._wrap_method( + self.cancel_operation, + default_timeout=None, + client_info=client_info, + ), + self.delete_operation: self._wrap_method( + self.delete_operation, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: self._wrap_method( + self.get_operation, + default_timeout=None, + client_info=client_info, + ), + self.list_operations: self._wrap_method( + self.list_operations, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + @property + def delete_operation( + self, + ) -> Callable[[operations_pb2.DeleteOperationRequest], None]: + r"""Return a callable for the delete_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_operation" not in self._stubs: + self._stubs["delete_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/DeleteOperation", + request_serializer=operations_pb2.DeleteOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["delete_operation"] + + @property + def cancel_operation( + self, + ) -> Callable[[operations_pb2.CancelOperationRequest], None]: + r"""Return a callable for the cancel_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "cancel_operation" not in self._stubs: + self._stubs["cancel_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/CancelOperation", + request_serializer=operations_pb2.CancelOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["cancel_operation"] + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_operation" not in self._stubs: + self._stubs["get_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse + ]: + r"""Return a callable for the list_operations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_operations" not in self._stubs: + self._stubs["list_operations"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ("RuleExecutionErrorServiceGrpcAsyncIOTransport",) diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/transports/rest.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/transports/rest.py new file mode 100644 index 000000000000..bf91cfbaf6c3 --- /dev/null +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/transports/rest.py @@ -0,0 +1,1029 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +import warnings +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +import google.protobuf +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.cloud.chronicle_v1.types import rule_execution_error + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseRuleExecutionErrorServiceRestTransport + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class RuleExecutionErrorServiceRestInterceptor: + """Interceptor for RuleExecutionErrorService. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the RuleExecutionErrorServiceRestTransport. + + .. code-block:: python + class MyCustomRuleExecutionErrorServiceInterceptor(RuleExecutionErrorServiceRestInterceptor): + def pre_list_rule_execution_errors(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_rule_execution_errors(self, response): + logging.log(f"Received response: {response}") + return response + + transport = RuleExecutionErrorServiceRestTransport(interceptor=MyCustomRuleExecutionErrorServiceInterceptor()) + client = RuleExecutionErrorServiceClient(transport=transport) + + + """ + + def pre_list_rule_execution_errors( + self, + request: rule_execution_error.ListRuleExecutionErrorsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + rule_execution_error.ListRuleExecutionErrorsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for list_rule_execution_errors + + Override in a subclass to manipulate the request or metadata + before they are sent to the RuleExecutionErrorService server. + """ + return request, metadata + + def post_list_rule_execution_errors( + self, response: rule_execution_error.ListRuleExecutionErrorsResponse + ) -> rule_execution_error.ListRuleExecutionErrorsResponse: + """Post-rpc interceptor for list_rule_execution_errors + + DEPRECATED. Please use the `post_list_rule_execution_errors_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the RuleExecutionErrorService server but before + it is returned to user code. This `post_list_rule_execution_errors` interceptor runs + before the `post_list_rule_execution_errors_with_metadata` interceptor. + """ + return response + + def post_list_rule_execution_errors_with_metadata( + self, + response: rule_execution_error.ListRuleExecutionErrorsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + rule_execution_error.ListRuleExecutionErrorsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_rule_execution_errors + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the RuleExecutionErrorService server but before it is returned to user code. + + We recommend only using this `post_list_rule_execution_errors_with_metadata` + interceptor in new development instead of the `post_list_rule_execution_errors` interceptor. + When both interceptors are used, this `post_list_rule_execution_errors_with_metadata` interceptor runs after the + `post_list_rule_execution_errors` interceptor. The (possibly modified) response returned by + `post_list_rule_execution_errors` will be passed to + `post_list_rule_execution_errors_with_metadata`. + """ + return response, metadata + + def pre_cancel_operation( + self, + request: operations_pb2.CancelOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.CancelOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for cancel_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the RuleExecutionErrorService server. + """ + return request, metadata + + def post_cancel_operation(self, response: None) -> None: + """Post-rpc interceptor for cancel_operation + + Override in a subclass to manipulate the response + after it is returned by the RuleExecutionErrorService server but before + it is returned to user code. + """ + return response + + def pre_delete_operation( + self, + request: operations_pb2.DeleteOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.DeleteOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for delete_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the RuleExecutionErrorService server. + """ + return request, metadata + + def post_delete_operation(self, response: None) -> None: + """Post-rpc interceptor for delete_operation + + Override in a subclass to manipulate the response + after it is returned by the RuleExecutionErrorService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the RuleExecutionErrorService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the RuleExecutionErrorService server but before + it is returned to user code. + """ + return response + + def pre_list_operations( + self, + request: operations_pb2.ListOperationsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.ListOperationsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the RuleExecutionErrorService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the RuleExecutionErrorService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class RuleExecutionErrorServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: RuleExecutionErrorServiceRestInterceptor + + +class RuleExecutionErrorServiceRestTransport( + _BaseRuleExecutionErrorServiceRestTransport +): + """REST backend synchronous transport for RuleExecutionErrorService. + + RuleExecutionErrorService contains endpoints related to rule + execution errors. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "chronicle.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[RuleExecutionErrorServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'chronicle.googleapis.com'). + 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]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. This argument will be + removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + interceptor (Optional[RuleExecutionErrorServiceRestInterceptor]): Interceptor used + to manipulate requests, request metadata, and responses. + api_audience (Optional[str]): The intended audience for the API calls + to the service that will be set when using certain 3rd party + authentication flows. Audience is typically a resource identifier. + If not set, the host value will be used as a default. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or RuleExecutionErrorServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _ListRuleExecutionErrors( + _BaseRuleExecutionErrorServiceRestTransport._BaseListRuleExecutionErrors, + RuleExecutionErrorServiceRestStub, + ): + def __hash__(self): + return hash( + "RuleExecutionErrorServiceRestTransport.ListRuleExecutionErrors" + ) + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: rule_execution_error.ListRuleExecutionErrorsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> rule_execution_error.ListRuleExecutionErrorsResponse: + r"""Call the list rule execution + errors method over HTTP. + + Args: + request (~.rule_execution_error.ListRuleExecutionErrorsRequest): + The request object. Request message for + ListRuleExecutionErrors. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.rule_execution_error.ListRuleExecutionErrorsResponse: + Response message for + ListRuleExecutionErrors. + + """ + + http_options = _BaseRuleExecutionErrorServiceRestTransport._BaseListRuleExecutionErrors._get_http_options() + + request, metadata = self._interceptor.pre_list_rule_execution_errors( + request, metadata + ) + transcoded_request = _BaseRuleExecutionErrorServiceRestTransport._BaseListRuleExecutionErrors._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseRuleExecutionErrorServiceRestTransport._BaseListRuleExecutionErrors._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.chronicle_v1.RuleExecutionErrorServiceClient.ListRuleExecutionErrors", + extra={ + "serviceName": "google.cloud.chronicle.v1.RuleExecutionErrorService", + "rpcName": "ListRuleExecutionErrors", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = RuleExecutionErrorServiceRestTransport._ListRuleExecutionErrors._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = rule_execution_error.ListRuleExecutionErrorsResponse() + pb_resp = rule_execution_error.ListRuleExecutionErrorsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_list_rule_execution_errors(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_rule_execution_errors_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + rule_execution_error.ListRuleExecutionErrorsResponse.to_json( + response + ) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.chronicle_v1.RuleExecutionErrorServiceClient.list_rule_execution_errors", + extra={ + "serviceName": "google.cloud.chronicle.v1.RuleExecutionErrorService", + "rpcName": "ListRuleExecutionErrors", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def list_rule_execution_errors( + self, + ) -> Callable[ + [rule_execution_error.ListRuleExecutionErrorsRequest], + rule_execution_error.ListRuleExecutionErrorsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListRuleExecutionErrors( + self._session, self._host, self._interceptor + ) # type: ignore + + @property + def cancel_operation(self): + return self._CancelOperation(self._session, self._host, self._interceptor) # type: ignore + + class _CancelOperation( + _BaseRuleExecutionErrorServiceRestTransport._BaseCancelOperation, + RuleExecutionErrorServiceRestStub, + ): + def __hash__(self): + return hash("RuleExecutionErrorServiceRestTransport.CancelOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: operations_pb2.CancelOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Call the cancel operation method over HTTP. + + Args: + request (operations_pb2.CancelOperationRequest): + The request object for CancelOperation 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + + http_options = _BaseRuleExecutionErrorServiceRestTransport._BaseCancelOperation._get_http_options() + + request, metadata = self._interceptor.pre_cancel_operation( + request, metadata + ) + transcoded_request = _BaseRuleExecutionErrorServiceRestTransport._BaseCancelOperation._get_transcoded_request( + http_options, request + ) + + body = _BaseRuleExecutionErrorServiceRestTransport._BaseCancelOperation._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseRuleExecutionErrorServiceRestTransport._BaseCancelOperation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.chronicle_v1.RuleExecutionErrorServiceClient.CancelOperation", + extra={ + "serviceName": "google.cloud.chronicle.v1.RuleExecutionErrorService", + "rpcName": "CancelOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + RuleExecutionErrorServiceRestTransport._CancelOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + return self._interceptor.post_cancel_operation(None) + + @property + def delete_operation(self): + return self._DeleteOperation(self._session, self._host, self._interceptor) # type: ignore + + class _DeleteOperation( + _BaseRuleExecutionErrorServiceRestTransport._BaseDeleteOperation, + RuleExecutionErrorServiceRestStub, + ): + def __hash__(self): + return hash("RuleExecutionErrorServiceRestTransport.DeleteOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.DeleteOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Call the delete operation method over HTTP. + + Args: + request (operations_pb2.DeleteOperationRequest): + The request object for DeleteOperation 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + + http_options = _BaseRuleExecutionErrorServiceRestTransport._BaseDeleteOperation._get_http_options() + + request, metadata = self._interceptor.pre_delete_operation( + request, metadata + ) + transcoded_request = _BaseRuleExecutionErrorServiceRestTransport._BaseDeleteOperation._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseRuleExecutionErrorServiceRestTransport._BaseDeleteOperation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.chronicle_v1.RuleExecutionErrorServiceClient.DeleteOperation", + extra={ + "serviceName": "google.cloud.chronicle.v1.RuleExecutionErrorService", + "rpcName": "DeleteOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + RuleExecutionErrorServiceRestTransport._DeleteOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + return self._interceptor.post_delete_operation(None) + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation( + _BaseRuleExecutionErrorServiceRestTransport._BaseGetOperation, + RuleExecutionErrorServiceRestStub, + ): + def __hash__(self): + return hash("RuleExecutionErrorServiceRestTransport.GetOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options = _BaseRuleExecutionErrorServiceRestTransport._BaseGetOperation._get_http_options() + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + transcoded_request = _BaseRuleExecutionErrorServiceRestTransport._BaseGetOperation._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseRuleExecutionErrorServiceRestTransport._BaseGetOperation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.chronicle_v1.RuleExecutionErrorServiceClient.GetOperation", + extra={ + "serviceName": "google.cloud.chronicle.v1.RuleExecutionErrorService", + "rpcName": "GetOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + RuleExecutionErrorServiceRestTransport._GetOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.Operation() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_get_operation(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.chronicle_v1.RuleExecutionErrorServiceAsyncClient.GetOperation", + extra={ + "serviceName": "google.cloud.chronicle.v1.RuleExecutionErrorService", + "rpcName": "GetOperation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations( + _BaseRuleExecutionErrorServiceRestTransport._BaseListOperations, + RuleExecutionErrorServiceRestStub, + ): + def __hash__(self): + return hash("RuleExecutionErrorServiceRestTransport.ListOperations") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.ListOperationsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.ListOperationsResponse: Response from ListOperations method. + """ + + http_options = _BaseRuleExecutionErrorServiceRestTransport._BaseListOperations._get_http_options() + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + transcoded_request = _BaseRuleExecutionErrorServiceRestTransport._BaseListOperations._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseRuleExecutionErrorServiceRestTransport._BaseListOperations._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.chronicle_v1.RuleExecutionErrorServiceClient.ListOperations", + extra={ + "serviceName": "google.cloud.chronicle.v1.RuleExecutionErrorService", + "rpcName": "ListOperations", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + RuleExecutionErrorServiceRestTransport._ListOperations._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_list_operations(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.chronicle_v1.RuleExecutionErrorServiceAsyncClient.ListOperations", + extra={ + "serviceName": "google.cloud.chronicle.v1.RuleExecutionErrorService", + "rpcName": "ListOperations", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("RuleExecutionErrorServiceRestTransport",) diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/transports/rest_base.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/transports/rest_base.py new file mode 100644 index 000000000000..5682fe7b9304 --- /dev/null +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_execution_error_service/transports/rest_base.py @@ -0,0 +1,245 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format + +from google.cloud.chronicle_v1.types import rule_execution_error + +from .base import DEFAULT_CLIENT_INFO, RuleExecutionErrorServiceTransport + + +class _BaseRuleExecutionErrorServiceRestTransport(RuleExecutionErrorServiceTransport): + """Base REST backend transport for RuleExecutionErrorService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "chronicle.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'chronicle.googleapis.com'). + credentials (Optional[Any]): 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. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseListRuleExecutionErrors: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=projects/*/locations/*/instances/*}/ruleExecutionErrors", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = rule_execution_error.ListRuleExecutionErrorsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseRuleExecutionErrorServiceRestTransport._BaseListRuleExecutionErrors._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseCancelOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{name=projects/*/locations/*/instances/*/operations/*}:cancel", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + body = json.dumps(transcoded_request["body"]) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + class _BaseDeleteOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/v1/{name=projects/*/locations/*/instances/*/operations/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + class _BaseGetOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=projects/*/locations/*/instances/*/operations/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + class _BaseListOperations: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=projects/*/locations/*/instances/*}/operations", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + +__all__ = ("_BaseRuleExecutionErrorServiceRestTransport",) diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_service/async_client.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_service/async_client.py index 33b8029eb468..d7944bf2de99 100644 --- a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_service/async_client.py +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_service/async_client.py @@ -85,6 +85,8 @@ class RuleServiceAsyncClient: parse_data_access_scope_path = staticmethod( RuleServiceClient.parse_data_access_scope_path ) + instance_path = staticmethod(RuleServiceClient.instance_path) + parse_instance_path = staticmethod(RuleServiceClient.parse_instance_path) reference_list_path = staticmethod(RuleServiceClient.reference_list_path) parse_reference_list_path = staticmethod( RuleServiceClient.parse_reference_list_path @@ -893,6 +895,129 @@ async def sample_delete_rule(): metadata=metadata, ) + async def verify_rule_text( + self, + request: Optional[Union[rule.VerifyRuleTextRequest, dict]] = None, + *, + instance: Optional[str] = None, + rule_text: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> rule.VerifyRuleTextResponse: + r"""Verifies the given rule text. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import chronicle_v1 + + async def sample_verify_rule_text(): + # Create a client + client = chronicle_v1.RuleServiceAsyncClient() + + # Initialize request argument(s) + request = chronicle_v1.VerifyRuleTextRequest( + instance="instance_value", + rule_text="rule_text_value", + ) + + # Make the request + response = await client.verify_rule_text(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.chronicle_v1.types.VerifyRuleTextRequest, dict]]): + The request object. Request message for VerifyRuleText + method. + instance (:class:`str`): + Required. The name of the parent resource, which is the + SecOps instance associated with the request. Format: + ``projects/{project}/locations/{location}/instances/{instance}`` + + This corresponds to the ``instance`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + rule_text (:class:`str`): + Required. The rule text to verify as + a UTF-8 string. + + This corresponds to the ``rule_text`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.chronicle_v1.types.VerifyRuleTextResponse: + Response message for VerifyRuleText + method. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [instance, rule_text] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, rule.VerifyRuleTextRequest): + request = rule.VerifyRuleTextRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if instance is not None: + request.instance = instance + if rule_text is not None: + request.rule_text = rule_text + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.verify_rule_text + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("instance", request.instance),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + async def list_rule_revisions( self, request: Optional[Union[rule.ListRuleRevisionsRequest, dict]] = None, diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_service/client.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_service/client.py index 6f51d7f28202..b04986aceae3 100644 --- a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_service/client.py +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_service/client.py @@ -258,6 +258,28 @@ def parse_data_access_scope_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def instance_path( + project: str, + location: str, + instance: str, + ) -> str: + """Returns a fully-qualified instance string.""" + return "projects/{project}/locations/{location}/instances/{instance}".format( + project=project, + location=location, + instance=instance, + ) + + @staticmethod + def parse_instance_path(path: str) -> Dict[str, str]: + """Parses a instance path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/instances/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def reference_list_path( project: str, @@ -1401,6 +1423,126 @@ def sample_delete_rule(): metadata=metadata, ) + def verify_rule_text( + self, + request: Optional[Union[rule.VerifyRuleTextRequest, dict]] = None, + *, + instance: Optional[str] = None, + rule_text: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> rule.VerifyRuleTextResponse: + r"""Verifies the given rule text. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import chronicle_v1 + + def sample_verify_rule_text(): + # Create a client + client = chronicle_v1.RuleServiceClient() + + # Initialize request argument(s) + request = chronicle_v1.VerifyRuleTextRequest( + instance="instance_value", + rule_text="rule_text_value", + ) + + # Make the request + response = client.verify_rule_text(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.chronicle_v1.types.VerifyRuleTextRequest, dict]): + The request object. Request message for VerifyRuleText + method. + instance (str): + Required. The name of the parent resource, which is the + SecOps instance associated with the request. Format: + ``projects/{project}/locations/{location}/instances/{instance}`` + + This corresponds to the ``instance`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + rule_text (str): + Required. The rule text to verify as + a UTF-8 string. + + This corresponds to the ``rule_text`` 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.chronicle_v1.types.VerifyRuleTextResponse: + Response message for VerifyRuleText + method. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [instance, rule_text] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, rule.VerifyRuleTextRequest): + request = rule.VerifyRuleTextRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if instance is not None: + request.instance = instance + if rule_text is not None: + request.rule_text = rule_text + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.verify_rule_text] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("instance", request.instance),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + def list_rule_revisions( self, request: Optional[Union[rule.ListRuleRevisionsRequest, dict]] = None, diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_service/transports/base.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_service/transports/base.py index afeb313552d8..f157c751ee7c 100644 --- a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_service/transports/base.py +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_service/transports/base.py @@ -42,7 +42,11 @@ class RuleServiceTransport(abc.ABC): """Abstract transport class for RuleService.""" - AUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) + AUTH_SCOPES = ( + "https://www.googleapis.com/auth/chronicle", + "https://www.googleapis.com/auth/chronicle.readonly", + "https://www.googleapis.com/auth/cloud-platform", + ) DEFAULT_HOST: str = "chronicle.googleapis.com" @@ -188,6 +192,20 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), + self.verify_rule_text: gapic_v1.method.wrap_method( + self.verify_rule_text, + default_retry=retries.Retry( + initial=1.0, + maximum=60.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), self.list_rule_revisions: gapic_v1.method.wrap_method( self.list_rule_revisions, default_retry=retries.Retry( @@ -343,6 +361,15 @@ def delete_rule( ]: raise NotImplementedError() + @property + def verify_rule_text( + self, + ) -> Callable[ + [rule.VerifyRuleTextRequest], + Union[rule.VerifyRuleTextResponse, Awaitable[rule.VerifyRuleTextResponse]], + ]: + raise NotImplementedError() + @property def list_rule_revisions( self, diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_service/transports/grpc.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_service/transports/grpc.py index 039364094a14..04a399a5bb83 100644 --- a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_service/transports/grpc.py +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_service/transports/grpc.py @@ -465,6 +465,32 @@ def delete_rule(self) -> Callable[[rule.DeleteRuleRequest], empty_pb2.Empty]: ) return self._stubs["delete_rule"] + @property + def verify_rule_text( + self, + ) -> Callable[[rule.VerifyRuleTextRequest], rule.VerifyRuleTextResponse]: + r"""Return a callable for the verify rule text method over gRPC. + + Verifies the given rule text. + + Returns: + Callable[[~.VerifyRuleTextRequest], + ~.VerifyRuleTextResponse]: + 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 "verify_rule_text" not in self._stubs: + self._stubs["verify_rule_text"] = self._logged_channel.unary_unary( + "/google.cloud.chronicle.v1.RuleService/VerifyRuleText", + request_serializer=rule.VerifyRuleTextRequest.serialize, + response_deserializer=rule.VerifyRuleTextResponse.deserialize, + ) + return self._stubs["verify_rule_text"] + @property def list_rule_revisions( self, diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_service/transports/grpc_asyncio.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_service/transports/grpc_asyncio.py index baf85649aa48..c46853a80248 100644 --- a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_service/transports/grpc_asyncio.py +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_service/transports/grpc_asyncio.py @@ -481,6 +481,32 @@ def delete_rule( ) return self._stubs["delete_rule"] + @property + def verify_rule_text( + self, + ) -> Callable[[rule.VerifyRuleTextRequest], Awaitable[rule.VerifyRuleTextResponse]]: + r"""Return a callable for the verify rule text method over gRPC. + + Verifies the given rule text. + + Returns: + Callable[[~.VerifyRuleTextRequest], + Awaitable[~.VerifyRuleTextResponse]]: + 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 "verify_rule_text" not in self._stubs: + self._stubs["verify_rule_text"] = self._logged_channel.unary_unary( + "/google.cloud.chronicle.v1.RuleService/VerifyRuleText", + request_serializer=rule.VerifyRuleTextRequest.serialize, + response_deserializer=rule.VerifyRuleTextResponse.deserialize, + ) + return self._stubs["verify_rule_text"] + @property def list_rule_revisions( self, @@ -717,6 +743,20 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), + self.verify_rule_text: self._wrap_method( + self.verify_rule_text, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=60.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), self.list_rule_revisions: self._wrap_method( self.list_rule_revisions, default_retry=retries.AsyncRetry( diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_service/transports/rest.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_service/transports/rest.py index 208b71ec87f6..7210f17aee4d 100644 --- a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_service/transports/rest.py +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_service/transports/rest.py @@ -167,6 +167,14 @@ def post_update_rule_deployment(self, response): logging.log(f"Received response: {response}") return response + def pre_verify_rule_text(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_verify_rule_text(self, response): + logging.log(f"Received response: {response}") + return response + transport = RuleServiceRestTransport(interceptor=MyCustomRuleServiceInterceptor()) client = RuleServiceClient(transport=transport) @@ -683,6 +691,52 @@ def post_update_rule_deployment_with_metadata( """ return response, metadata + def pre_verify_rule_text( + self, + request: rule.VerifyRuleTextRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[rule.VerifyRuleTextRequest, Sequence[Tuple[str, Union[str, bytes]]]]: + """Pre-rpc interceptor for verify_rule_text + + Override in a subclass to manipulate the request or metadata + before they are sent to the RuleService server. + """ + return request, metadata + + def post_verify_rule_text( + self, response: rule.VerifyRuleTextResponse + ) -> rule.VerifyRuleTextResponse: + """Post-rpc interceptor for verify_rule_text + + DEPRECATED. Please use the `post_verify_rule_text_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the RuleService server but before + it is returned to user code. This `post_verify_rule_text` interceptor runs + before the `post_verify_rule_text_with_metadata` interceptor. + """ + return response + + def post_verify_rule_text_with_metadata( + self, + response: rule.VerifyRuleTextResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[rule.VerifyRuleTextResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for verify_rule_text + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the RuleService server but before it is returned to user code. + + We recommend only using this `post_verify_rule_text_with_metadata` + interceptor in new development instead of the `post_verify_rule_text` interceptor. + When both interceptors are used, this `post_verify_rule_text_with_metadata` interceptor runs after the + `post_verify_rule_text` interceptor. The (possibly modified) response returned by + `post_verify_rule_text` will be passed to + `post_verify_rule_text_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -2702,6 +2756,161 @@ def __call__( ) return resp + class _VerifyRuleText( + _BaseRuleServiceRestTransport._BaseVerifyRuleText, RuleServiceRestStub + ): + def __hash__(self): + return hash("RuleServiceRestTransport.VerifyRuleText") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: rule.VerifyRuleTextRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> rule.VerifyRuleTextResponse: + r"""Call the verify rule text method over HTTP. + + Args: + request (~.rule.VerifyRuleTextRequest): + The request object. Request message for VerifyRuleText + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.rule.VerifyRuleTextResponse: + Response message for VerifyRuleText + method. + + """ + + http_options = ( + _BaseRuleServiceRestTransport._BaseVerifyRuleText._get_http_options() + ) + + request, metadata = self._interceptor.pre_verify_rule_text( + request, metadata + ) + transcoded_request = _BaseRuleServiceRestTransport._BaseVerifyRuleText._get_transcoded_request( + http_options, request + ) + + body = _BaseRuleServiceRestTransport._BaseVerifyRuleText._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseRuleServiceRestTransport._BaseVerifyRuleText._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.chronicle_v1.RuleServiceClient.VerifyRuleText", + extra={ + "serviceName": "google.cloud.chronicle.v1.RuleService", + "rpcName": "VerifyRuleText", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = RuleServiceRestTransport._VerifyRuleText._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = rule.VerifyRuleTextResponse() + pb_resp = rule.VerifyRuleTextResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_verify_rule_text(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_verify_rule_text_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = rule.VerifyRuleTextResponse.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.chronicle_v1.RuleServiceClient.verify_rule_text", + extra={ + "serviceName": "google.cloud.chronicle.v1.RuleService", + "rpcName": "VerifyRuleText", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + @property def create_retrohunt( self, @@ -2786,6 +2995,14 @@ def update_rule_deployment( # In C++ this would require a dynamic_cast return self._UpdateRuleDeployment(self._session, self._host, self._interceptor) # type: ignore + @property + def verify_rule_text( + self, + ) -> Callable[[rule.VerifyRuleTextRequest], rule.VerifyRuleTextResponse]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._VerifyRuleText(self._session, self._host, self._interceptor) # type: ignore + @property def cancel_operation(self): return self._CancelOperation(self._session, self._host, self._interceptor) # type: ignore diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_service/transports/rest_base.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_service/transports/rest_base.py index c5f5e9b0ff63..a95e20a79bb8 100644 --- a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_service/transports/rest_base.py +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/services/rule_service/transports/rest_base.py @@ -696,6 +696,63 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params + class _BaseVerifyRuleText: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{instance=projects/*/locations/*/instances/*}:verifyRuleText", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = rule.VerifyRuleTextRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseRuleServiceRestTransport._BaseVerifyRuleText._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + class _BaseCancelOperation: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/types/__init__.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/types/__init__.py index dc4642a9164d..603d579ff47c 100644 --- a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/types/__init__.py +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/types/__init__.py @@ -171,11 +171,14 @@ ListReferenceListsResponse, ReferenceList, ReferenceListEntry, + ReferenceListError, ReferenceListScope, ReferenceListSyntaxType, ReferenceListView, ScopeInfo, UpdateReferenceListRequest, + VerifyReferenceListRequest, + VerifyReferenceListResponse, ) from .rule import ( CompilationDiagnostic, @@ -205,6 +208,13 @@ Severity, UpdateRuleDeploymentRequest, UpdateRuleRequest, + VerifyRuleTextRequest, + VerifyRuleTextResponse, +) +from .rule_execution_error import ( + ListRuleExecutionErrorsRequest, + ListRuleExecutionErrorsResponse, + RuleExecutionError, ) __all__ = ( @@ -345,9 +355,12 @@ "ListReferenceListsResponse", "ReferenceList", "ReferenceListEntry", + "ReferenceListError", "ReferenceListScope", "ScopeInfo", "UpdateReferenceListRequest", + "VerifyReferenceListRequest", + "VerifyReferenceListResponse", "ReferenceListSyntaxType", "ReferenceListView", "CompilationDiagnostic", @@ -374,7 +387,12 @@ "Severity", "UpdateRuleDeploymentRequest", "UpdateRuleRequest", + "VerifyRuleTextRequest", + "VerifyRuleTextResponse", "RuleType", "RuleView", "RunFrequency", + "ListRuleExecutionErrorsRequest", + "ListRuleExecutionErrorsResponse", + "RuleExecutionError", ) diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/types/reference_list.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/types/reference_list.py index 3e4e377898a0..aa210783382d 100644 --- a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/types/reference_list.py +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/types/reference_list.py @@ -33,8 +33,11 @@ "ListReferenceListsResponse", "CreateReferenceListRequest", "UpdateReferenceListRequest", + "VerifyReferenceListRequest", + "VerifyReferenceListResponse", "ReferenceList", "ReferenceListEntry", + "ReferenceListError", }, ) @@ -282,6 +285,60 @@ class UpdateReferenceListRequest(proto.Message): ) +class VerifyReferenceListRequest(proto.Message): + r"""VerifyReferenceList request message. + + Attributes: + instance (str): + Required. The name of the parent resource, which is the + SecOps instance associated with the request. Format: + ``projects/{project}/locations/{location}/instances/{instance}`` + syntax_type (google.cloud.chronicle_v1.types.ReferenceListSyntaxType): + Required. Type (format) of list lines. + entries (MutableSequence[google.cloud.chronicle_v1.types.ReferenceListEntry]): + Required. The entries of the reference list. + Each line may be either an item in the list or a + comment. + """ + + instance: str = proto.Field( + proto.STRING, + number=1, + ) + syntax_type: "ReferenceListSyntaxType" = proto.Field( + proto.ENUM, + number=2, + enum="ReferenceListSyntaxType", + ) + entries: MutableSequence["ReferenceListEntry"] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message="ReferenceListEntry", + ) + + +class VerifyReferenceListResponse(proto.Message): + r"""VerifyListResponse response message. + + Attributes: + success (bool): + Validity of list - true if no errors found. + errors (MutableSequence[google.cloud.chronicle_v1.types.ReferenceListError]): + Line-level errors causing the list to be + invalid. + """ + + success: bool = proto.Field( + proto.BOOL, + number=1, + ) + errors: MutableSequence["ReferenceListError"] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="ReferenceListError", + ) + + class ReferenceList(proto.Message): r"""A reference list. Reference lists are user-defined lists of values which users can @@ -382,4 +439,25 @@ class ReferenceListEntry(proto.Message): ) +class ReferenceListError(proto.Message): + r"""The error generated when verifying the reference list. + + Attributes: + line_number (int): + 1-indexed line number where the error occurs. + General list errors are indexed at -1. + error_message (str): + Message explaining why the line is invalid. + """ + + line_number: int = proto.Field( + proto.INT32, + number=1, + ) + error_message: str = proto.Field( + proto.STRING, + number=2, + ) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/types/rule.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/types/rule.py index 6d1f5dd98553..0bce542dcd09 100644 --- a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/types/rule.py +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/types/rule.py @@ -37,6 +37,8 @@ "ListRulesResponse", "UpdateRuleRequest", "DeleteRuleRequest", + "VerifyRuleTextRequest", + "VerifyRuleTextResponse", "ListRuleRevisionsRequest", "ListRuleRevisionsResponse", "CreateRetrohuntRequest", @@ -692,6 +694,55 @@ class DeleteRuleRequest(proto.Message): ) +class VerifyRuleTextRequest(proto.Message): + r"""Request message for VerifyRuleText method. + + Attributes: + instance (str): + Required. The name of the parent resource, which is the + SecOps instance associated with the request. Format: + ``projects/{project}/locations/{location}/instances/{instance}`` + rule_text (str): + Required. The rule text to verify as a UTF-8 + string. + """ + + instance: str = proto.Field( + proto.STRING, + number=1, + ) + rule_text: str = proto.Field( + proto.STRING, + number=2, + ) + + +class VerifyRuleTextResponse(proto.Message): + r"""Response message for VerifyRuleText method. + + Attributes: + success (bool): + Whether or not the rule text was successfully + verified. + compilation_diagnostics (MutableSequence[google.cloud.chronicle_v1.types.CompilationDiagnostic]): + A list of a rule's corresponding compilation + diagnostic messages such as compilation errors + and compilation warnings. + """ + + success: bool = proto.Field( + proto.BOOL, + number=1, + ) + compilation_diagnostics: MutableSequence["CompilationDiagnostic"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=3, + message="CompilationDiagnostic", + ) + ) + + class ListRuleRevisionsRequest(proto.Message): r"""Request message for ListRuleRevisions method. diff --git a/packages/google-cloud-chronicle/google/cloud/chronicle_v1/types/rule_execution_error.py b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/types/rule_execution_error.py new file mode 100644 index 000000000000..c78531a8848e --- /dev/null +++ b/packages/google-cloud-chronicle/google/cloud/chronicle_v1/types/rule_execution_error.py @@ -0,0 +1,192 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import google.rpc.status_pb2 as status_pb2 # type: ignore +import google.type.interval_pb2 as interval_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.chronicle.v1", + manifest={ + "ListRuleExecutionErrorsRequest", + "ListRuleExecutionErrorsResponse", + "RuleExecutionError", + }, +) + + +class ListRuleExecutionErrorsRequest(proto.Message): + r"""Request message for ListRuleExecutionErrors. + + Attributes: + parent (str): + Required. The instance to list rule execution + errors from. Format: + + projects/{project}/locations/{location}/instances/{instance} + page_size (int): + The maximum number of rule execution errors + to return. The service may return fewer than + this value. If unspecified, at most 1000 rule + execution errors will be returned. The maximum + value is 10000; values above 10000 will be + coerced to 10000. + page_token (str): + A page token, received from a previous + ``ListRuleExecutionErrors`` call. Provide this to retrieve + the subsequent page. + + When paginating, all other parameters provided to + ``ListRuleExecutionErrors`` must match the call that + provided the page token. + filter (str): + A filter that can be used to retrieve specific rule + execution errors. Only the following filters are allowed: + + :: + + rule = "{Rule.name}" + curated_rule = "{CuratedRule.name}" + + The value for rule or curated_rule must be a valid rule + resource name or a valid curated rule resource name + specified in quotes. + + For 'rule', an optional 'revision_id' can be specified which + can be used to fetch errors for a given revision of the + rule. A '-' is also allowed to fetch errors across all + revisions of the rule. If unspecified, only errors + corresponding to the most recent revision of the rule will + be returned. So these variations are all allowed: + + :: + + rule = "{Rule.name}" + rule = "{Rule.name}@{Rule.revision_id}" + rule = "{Rule.name}@-" + + Revision IDs are not supported for curated rules. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + + +class ListRuleExecutionErrorsResponse(proto.Message): + r"""Response message for ListRuleExecutionErrors. + + Attributes: + rule_execution_errors (MutableSequence[google.cloud.chronicle_v1.types.RuleExecutionError]): + List of rule execution errors. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + """ + + @property + def raw_page(self): + return self + + rule_execution_errors: MutableSequence["RuleExecutionError"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="RuleExecutionError", + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class RuleExecutionError(proto.Message): + r"""The RuleExecutionError resource represents an error generated + from running/deploying a rule. + + 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: + rule (str): + Output only. The resource name of the rule + that generated the rule execution error. + + This field is a member of `oneof`_ ``source``. + curated_rule (str): + Output only. The resource name of the curated + rule that generated the rule execution error. + + This field is a member of `oneof`_ ``source``. + name (str): + Output only. The resource name of the rule execution error. + Format: + projects/{project}/locations/{location}/instances/{instance}/ruleExecutionErrors/{rule_execution_error} + error (google.rpc.status_pb2.Status): + Output only. The error status corresponding + with the rule execution error. + time_range (google.type.interval_pb2.Interval): + Output only. The event time range that the + rule execution error corresponds with. + """ + + rule: str = proto.Field( + proto.STRING, + number=4, + oneof="source", + ) + curated_rule: str = proto.Field( + proto.STRING, + number=5, + oneof="source", + ) + name: str = proto.Field( + proto.STRING, + number=1, + ) + error: status_pb2.Status = proto.Field( + proto.MESSAGE, + number=2, + message=status_pb2.Status, + ) + time_range: interval_pb2.Interval = proto.Field( + proto.MESSAGE, + number=3, + message=interval_pb2.Interval, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-chronicle/samples/generated_samples/chronicle_v1_generated_reference_list_service_verify_reference_list_async.py b/packages/google-cloud-chronicle/samples/generated_samples/chronicle_v1_generated_reference_list_service_verify_reference_list_async.py new file mode 100644 index 000000000000..48577e71ce55 --- /dev/null +++ b/packages/google-cloud-chronicle/samples/generated_samples/chronicle_v1_generated_reference_list_service_verify_reference_list_async.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for VerifyReferenceList +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-chronicle + + +# [START chronicle_v1_generated_ReferenceListService_VerifyReferenceList_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import chronicle_v1 + + +async def sample_verify_reference_list(): + # Create a client + client = chronicle_v1.ReferenceListServiceAsyncClient() + + # Initialize request argument(s) + entries = chronicle_v1.ReferenceListEntry() + entries.value = "value_value" + + request = chronicle_v1.VerifyReferenceListRequest( + instance="instance_value", + syntax_type="REFERENCE_LIST_SYNTAX_TYPE_CIDR", + entries=entries, + ) + + # Make the request + response = await client.verify_reference_list(request=request) + + # Handle the response + print(response) + + +# [END chronicle_v1_generated_ReferenceListService_VerifyReferenceList_async] diff --git a/packages/google-cloud-chronicle/samples/generated_samples/chronicle_v1_generated_reference_list_service_verify_reference_list_sync.py b/packages/google-cloud-chronicle/samples/generated_samples/chronicle_v1_generated_reference_list_service_verify_reference_list_sync.py new file mode 100644 index 000000000000..10bd54548a91 --- /dev/null +++ b/packages/google-cloud-chronicle/samples/generated_samples/chronicle_v1_generated_reference_list_service_verify_reference_list_sync.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for VerifyReferenceList +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-chronicle + + +# [START chronicle_v1_generated_ReferenceListService_VerifyReferenceList_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import chronicle_v1 + + +def sample_verify_reference_list(): + # Create a client + client = chronicle_v1.ReferenceListServiceClient() + + # Initialize request argument(s) + entries = chronicle_v1.ReferenceListEntry() + entries.value = "value_value" + + request = chronicle_v1.VerifyReferenceListRequest( + instance="instance_value", + syntax_type="REFERENCE_LIST_SYNTAX_TYPE_CIDR", + entries=entries, + ) + + # Make the request + response = client.verify_reference_list(request=request) + + # Handle the response + print(response) + + +# [END chronicle_v1_generated_ReferenceListService_VerifyReferenceList_sync] diff --git a/packages/google-cloud-chronicle/samples/generated_samples/chronicle_v1_generated_rule_execution_error_service_list_rule_execution_errors_async.py b/packages/google-cloud-chronicle/samples/generated_samples/chronicle_v1_generated_rule_execution_error_service_list_rule_execution_errors_async.py new file mode 100644 index 000000000000..e06033573918 --- /dev/null +++ b/packages/google-cloud-chronicle/samples/generated_samples/chronicle_v1_generated_rule_execution_error_service_list_rule_execution_errors_async.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListRuleExecutionErrors +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-chronicle + + +# [START chronicle_v1_generated_RuleExecutionErrorService_ListRuleExecutionErrors_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import chronicle_v1 + + +async def sample_list_rule_execution_errors(): + # Create a client + client = chronicle_v1.RuleExecutionErrorServiceAsyncClient() + + # Initialize request argument(s) + request = chronicle_v1.ListRuleExecutionErrorsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_rule_execution_errors(request=request) + + # Handle the response + async for response in page_result: + print(response) + + +# [END chronicle_v1_generated_RuleExecutionErrorService_ListRuleExecutionErrors_async] diff --git a/packages/google-cloud-chronicle/samples/generated_samples/chronicle_v1_generated_rule_execution_error_service_list_rule_execution_errors_sync.py b/packages/google-cloud-chronicle/samples/generated_samples/chronicle_v1_generated_rule_execution_error_service_list_rule_execution_errors_sync.py new file mode 100644 index 000000000000..825134d19481 --- /dev/null +++ b/packages/google-cloud-chronicle/samples/generated_samples/chronicle_v1_generated_rule_execution_error_service_list_rule_execution_errors_sync.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListRuleExecutionErrors +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-chronicle + + +# [START chronicle_v1_generated_RuleExecutionErrorService_ListRuleExecutionErrors_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import chronicle_v1 + + +def sample_list_rule_execution_errors(): + # Create a client + client = chronicle_v1.RuleExecutionErrorServiceClient() + + # Initialize request argument(s) + request = chronicle_v1.ListRuleExecutionErrorsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_rule_execution_errors(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END chronicle_v1_generated_RuleExecutionErrorService_ListRuleExecutionErrors_sync] diff --git a/packages/google-cloud-chronicle/samples/generated_samples/chronicle_v1_generated_rule_service_verify_rule_text_async.py b/packages/google-cloud-chronicle/samples/generated_samples/chronicle_v1_generated_rule_service_verify_rule_text_async.py new file mode 100644 index 000000000000..99d57fac4045 --- /dev/null +++ b/packages/google-cloud-chronicle/samples/generated_samples/chronicle_v1_generated_rule_service_verify_rule_text_async.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for VerifyRuleText +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-chronicle + + +# [START chronicle_v1_generated_RuleService_VerifyRuleText_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import chronicle_v1 + + +async def sample_verify_rule_text(): + # Create a client + client = chronicle_v1.RuleServiceAsyncClient() + + # Initialize request argument(s) + request = chronicle_v1.VerifyRuleTextRequest( + instance="instance_value", + rule_text="rule_text_value", + ) + + # Make the request + response = await client.verify_rule_text(request=request) + + # Handle the response + print(response) + + +# [END chronicle_v1_generated_RuleService_VerifyRuleText_async] diff --git a/packages/google-cloud-chronicle/samples/generated_samples/chronicle_v1_generated_rule_service_verify_rule_text_sync.py b/packages/google-cloud-chronicle/samples/generated_samples/chronicle_v1_generated_rule_service_verify_rule_text_sync.py new file mode 100644 index 000000000000..d862d419908e --- /dev/null +++ b/packages/google-cloud-chronicle/samples/generated_samples/chronicle_v1_generated_rule_service_verify_rule_text_sync.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for VerifyRuleText +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-chronicle + + +# [START chronicle_v1_generated_RuleService_VerifyRuleText_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import chronicle_v1 + + +def sample_verify_rule_text(): + # Create a client + client = chronicle_v1.RuleServiceClient() + + # Initialize request argument(s) + request = chronicle_v1.VerifyRuleTextRequest( + instance="instance_value", + rule_text="rule_text_value", + ) + + # Make the request + response = client.verify_rule_text(request=request) + + # Handle the response + print(response) + + +# [END chronicle_v1_generated_RuleService_VerifyRuleText_sync] diff --git a/packages/google-cloud-chronicle/samples/generated_samples/snippet_metadata_google.cloud.chronicle.v1.json b/packages/google-cloud-chronicle/samples/generated_samples/snippet_metadata_google.cloud.chronicle.v1.json index 7ff526195bf3..4b1a6b17c619 100644 --- a/packages/google-cloud-chronicle/samples/generated_samples/snippet_metadata_google.cloud.chronicle.v1.json +++ b/packages/google-cloud-chronicle/samples/generated_samples/snippet_metadata_google.cloud.chronicle.v1.json @@ -9440,6 +9440,320 @@ ], "title": "chronicle_v1_generated_reference_list_service_update_reference_list_sync.py" }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.chronicle_v1.ReferenceListServiceAsyncClient", + "shortName": "ReferenceListServiceAsyncClient" + }, + "fullName": "google.cloud.chronicle_v1.ReferenceListServiceAsyncClient.verify_reference_list", + "method": { + "fullName": "google.cloud.chronicle.v1.ReferenceListService.VerifyReferenceList", + "service": { + "fullName": "google.cloud.chronicle.v1.ReferenceListService", + "shortName": "ReferenceListService" + }, + "shortName": "VerifyReferenceList" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.chronicle_v1.types.VerifyReferenceListRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.chronicle_v1.types.VerifyReferenceListResponse", + "shortName": "verify_reference_list" + }, + "description": "Sample for VerifyReferenceList", + "file": "chronicle_v1_generated_reference_list_service_verify_reference_list_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "chronicle_v1_generated_ReferenceListService_VerifyReferenceList_async", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "chronicle_v1_generated_reference_list_service_verify_reference_list_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.chronicle_v1.ReferenceListServiceClient", + "shortName": "ReferenceListServiceClient" + }, + "fullName": "google.cloud.chronicle_v1.ReferenceListServiceClient.verify_reference_list", + "method": { + "fullName": "google.cloud.chronicle.v1.ReferenceListService.VerifyReferenceList", + "service": { + "fullName": "google.cloud.chronicle.v1.ReferenceListService", + "shortName": "ReferenceListService" + }, + "shortName": "VerifyReferenceList" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.chronicle_v1.types.VerifyReferenceListRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.chronicle_v1.types.VerifyReferenceListResponse", + "shortName": "verify_reference_list" + }, + "description": "Sample for VerifyReferenceList", + "file": "chronicle_v1_generated_reference_list_service_verify_reference_list_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "chronicle_v1_generated_ReferenceListService_VerifyReferenceList_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "chronicle_v1_generated_reference_list_service_verify_reference_list_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.chronicle_v1.RuleExecutionErrorServiceAsyncClient", + "shortName": "RuleExecutionErrorServiceAsyncClient" + }, + "fullName": "google.cloud.chronicle_v1.RuleExecutionErrorServiceAsyncClient.list_rule_execution_errors", + "method": { + "fullName": "google.cloud.chronicle.v1.RuleExecutionErrorService.ListRuleExecutionErrors", + "service": { + "fullName": "google.cloud.chronicle.v1.RuleExecutionErrorService", + "shortName": "RuleExecutionErrorService" + }, + "shortName": "ListRuleExecutionErrors" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.chronicle_v1.types.ListRuleExecutionErrorsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.chronicle_v1.services.rule_execution_error_service.pagers.ListRuleExecutionErrorsAsyncPager", + "shortName": "list_rule_execution_errors" + }, + "description": "Sample for ListRuleExecutionErrors", + "file": "chronicle_v1_generated_rule_execution_error_service_list_rule_execution_errors_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "chronicle_v1_generated_RuleExecutionErrorService_ListRuleExecutionErrors_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "chronicle_v1_generated_rule_execution_error_service_list_rule_execution_errors_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.chronicle_v1.RuleExecutionErrorServiceClient", + "shortName": "RuleExecutionErrorServiceClient" + }, + "fullName": "google.cloud.chronicle_v1.RuleExecutionErrorServiceClient.list_rule_execution_errors", + "method": { + "fullName": "google.cloud.chronicle.v1.RuleExecutionErrorService.ListRuleExecutionErrors", + "service": { + "fullName": "google.cloud.chronicle.v1.RuleExecutionErrorService", + "shortName": "RuleExecutionErrorService" + }, + "shortName": "ListRuleExecutionErrors" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.chronicle_v1.types.ListRuleExecutionErrorsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.chronicle_v1.services.rule_execution_error_service.pagers.ListRuleExecutionErrorsPager", + "shortName": "list_rule_execution_errors" + }, + "description": "Sample for ListRuleExecutionErrors", + "file": "chronicle_v1_generated_rule_execution_error_service_list_rule_execution_errors_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "chronicle_v1_generated_RuleExecutionErrorService_ListRuleExecutionErrors_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "chronicle_v1_generated_rule_execution_error_service_list_rule_execution_errors_sync.py" + }, { "canonical": true, "clientMethod": { @@ -11397,6 +11711,175 @@ } ], "title": "chronicle_v1_generated_rule_service_update_rule_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.chronicle_v1.RuleServiceAsyncClient", + "shortName": "RuleServiceAsyncClient" + }, + "fullName": "google.cloud.chronicle_v1.RuleServiceAsyncClient.verify_rule_text", + "method": { + "fullName": "google.cloud.chronicle.v1.RuleService.VerifyRuleText", + "service": { + "fullName": "google.cloud.chronicle.v1.RuleService", + "shortName": "RuleService" + }, + "shortName": "VerifyRuleText" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.chronicle_v1.types.VerifyRuleTextRequest" + }, + { + "name": "instance", + "type": "str" + }, + { + "name": "rule_text", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.chronicle_v1.types.VerifyRuleTextResponse", + "shortName": "verify_rule_text" + }, + "description": "Sample for VerifyRuleText", + "file": "chronicle_v1_generated_rule_service_verify_rule_text_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "chronicle_v1_generated_RuleService_VerifyRuleText_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "chronicle_v1_generated_rule_service_verify_rule_text_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.chronicle_v1.RuleServiceClient", + "shortName": "RuleServiceClient" + }, + "fullName": "google.cloud.chronicle_v1.RuleServiceClient.verify_rule_text", + "method": { + "fullName": "google.cloud.chronicle.v1.RuleService.VerifyRuleText", + "service": { + "fullName": "google.cloud.chronicle.v1.RuleService", + "shortName": "RuleService" + }, + "shortName": "VerifyRuleText" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.chronicle_v1.types.VerifyRuleTextRequest" + }, + { + "name": "instance", + "type": "str" + }, + { + "name": "rule_text", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.chronicle_v1.types.VerifyRuleTextResponse", + "shortName": "verify_rule_text" + }, + "description": "Sample for VerifyRuleText", + "file": "chronicle_v1_generated_rule_service_verify_rule_text_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "chronicle_v1_generated_RuleService_VerifyRuleText_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "chronicle_v1_generated_rule_service_verify_rule_text_sync.py" } ] } diff --git a/packages/google-cloud-chronicle/tests/unit/gapic/chronicle_v1/test_reference_list_service.py b/packages/google-cloud-chronicle/tests/unit/gapic/chronicle_v1/test_reference_list_service.py index ab8bd59e5917..e81b69811745 100644 --- a/packages/google-cloud-chronicle/tests/unit/gapic/chronicle_v1/test_reference_list_service.py +++ b/packages/google-cloud-chronicle/tests/unit/gapic/chronicle_v1/test_reference_list_service.py @@ -1376,7 +1376,11 @@ def test_reference_list_service_client_create_channel_credentials_file( credentials=file_creds, credentials_file=None, quota_project_id=None, - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + default_scopes=( + "https://www.googleapis.com/auth/chronicle", + "https://www.googleapis.com/auth/chronicle.readonly", + "https://www.googleapis.com/auth/cloud-platform", + ), scopes=None, default_host="chronicle.googleapis.com", ssl_credentials=None, @@ -3069,6 +3073,265 @@ async def test_update_reference_list_flattened_error_async(): ) +@pytest.mark.parametrize( + "request_type", + [ + reference_list.VerifyReferenceListRequest(), + {}, + ], +) +def test_verify_reference_list(request_type, transport: str = "grpc"): + client = ReferenceListServiceClient( + 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.verify_reference_list), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = reference_list.VerifyReferenceListResponse( + success=True, + ) + response = client.verify_reference_list(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = reference_list.VerifyReferenceListRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, reference_list.VerifyReferenceListResponse) + assert response.success is True + + +def test_verify_reference_list_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = ReferenceListServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = reference_list.VerifyReferenceListRequest( + instance="instance_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.verify_reference_list), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.verify_reference_list(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = reference_list.VerifyReferenceListRequest( + instance="instance_value", + ) + assert args[0] == request_msg + + +def test_verify_reference_list_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ReferenceListServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.verify_reference_list + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.verify_reference_list] = ( + mock_rpc + ) + request = {} + client.verify_reference_list(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.verify_reference_list(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_verify_reference_list_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = ReferenceListServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.verify_reference_list + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.verify_reference_list + ] = mock_rpc + + request = {} + await client.verify_reference_list(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.verify_reference_list(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + reference_list.VerifyReferenceListRequest(), + {}, + ], +) +async def test_verify_reference_list_async( + request_type, transport: str = "grpc_asyncio" +): + client = ReferenceListServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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.verify_reference_list), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + reference_list.VerifyReferenceListResponse( + success=True, + ) + ) + response = await client.verify_reference_list(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = reference_list.VerifyReferenceListRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, reference_list.VerifyReferenceListResponse) + assert response.success is True + + +def test_verify_reference_list_field_headers(): + client = ReferenceListServiceClient( + 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 = reference_list.VerifyReferenceListRequest() + + request.instance = "instance_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.verify_reference_list), "__call__" + ) as call: + call.return_value = reference_list.VerifyReferenceListResponse() + client.verify_reference_list(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", + "instance=instance_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_verify_reference_list_field_headers_async(): + client = ReferenceListServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = reference_list.VerifyReferenceListRequest() + + request.instance = "instance_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.verify_reference_list), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + reference_list.VerifyReferenceListResponse() + ) + await client.verify_reference_list(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", + "instance=instance_value", + ) in kw["metadata"] + + def test_get_reference_list_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -3922,42 +4185,177 @@ def test_update_reference_list_rest_flattened_error(transport: str = "rest"): ) -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.ReferenceListServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): +def test_verify_reference_list_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = ReferenceListServiceClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport="rest", ) - # It is an error to provide a credentials file and a transport instance. - transport = transports.ReferenceListServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = ReferenceListServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.verify_reference_list + in client._transport._wrapped_methods ) - # It is an error to provide an api_key and a transport instance. - transport = transports.ReferenceListServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = ReferenceListServiceClient( - client_options=options, - transport=transport, + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.verify_reference_list] = ( + mock_rpc ) - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" + request = {} + client.verify_reference_list(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.verify_reference_list(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_verify_reference_list_rest_required_fields( + request_type=reference_list.VerifyReferenceListRequest, +): + transport_class = transports.ReferenceListServiceRestTransport + + request_init = {} + request_init["instance"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).verify_reference_list._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["instance"] = "instance_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).verify_reference_list._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "instance" in jsonified_request + assert jsonified_request["instance"] == "instance_value" + + client = ReferenceListServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = reference_list.VerifyReferenceListResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = reference_list.VerifyReferenceListResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.verify_reference_list(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_verify_reference_list_rest_unset_required_fields(): + transport = transports.ReferenceListServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.verify_reference_list._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "instance", + "syntaxType", + "entries", + ) + ) + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ReferenceListServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ReferenceListServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ReferenceListServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ReferenceListServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ReferenceListServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ReferenceListServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" with pytest.raises(ValueError): client = ReferenceListServiceClient( client_options=options, credentials=ga_credentials.AnonymousCredentials() @@ -4116,6 +4514,28 @@ def test_update_reference_list_empty_call_grpc(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_verify_reference_list_empty_call_grpc(): + client = ReferenceListServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.verify_reference_list), "__call__" + ) as call: + call.return_value = reference_list.VerifyReferenceListResponse() + client.verify_reference_list(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = reference_list.VerifyReferenceListRequest() + assert args[0] == request_msg + + def test_transport_kind_grpc_asyncio(): transport = ReferenceListServiceAsyncClient.get_transport_class("grpc_asyncio")( credentials=async_anonymous_credentials() @@ -4257,6 +4677,34 @@ async def test_update_reference_list_empty_call_grpc_asyncio(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_verify_reference_list_empty_call_grpc_asyncio(): + client = ReferenceListServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.verify_reference_list), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + reference_list.VerifyReferenceListResponse( + success=True, + ) + ) + await client.verify_reference_list(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = reference_list.VerifyReferenceListRequest() + assert args[0] == request_msg + + def test_transport_kind_rest(): transport = ReferenceListServiceClient.get_transport_class("rest")( credentials=ga_credentials.AnonymousCredentials() @@ -5018,6 +5466,142 @@ def test_update_reference_list_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() +def test_verify_reference_list_rest_bad_request( + request_type=reference_list.VerifyReferenceListRequest, +): + client = ReferenceListServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"instance": "projects/sample1/locations/sample2/instances/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.verify_reference_list(request) + + +@pytest.mark.parametrize( + "request_type", + [ + reference_list.VerifyReferenceListRequest, + dict, + ], +) +def test_verify_reference_list_rest_call_success(request_type): + client = ReferenceListServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"instance": "projects/sample1/locations/sample2/instances/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = reference_list.VerifyReferenceListResponse( + success=True, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = reference_list.VerifyReferenceListResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.verify_reference_list(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, reference_list.VerifyReferenceListResponse) + assert response.success is True + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_verify_reference_list_rest_interceptors(null_interceptor): + transport = transports.ReferenceListServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ReferenceListServiceRestInterceptor(), + ) + client = ReferenceListServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.ReferenceListServiceRestInterceptor, "post_verify_reference_list" + ) as post, + mock.patch.object( + transports.ReferenceListServiceRestInterceptor, + "post_verify_reference_list_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.ReferenceListServiceRestInterceptor, "pre_verify_reference_list" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = reference_list.VerifyReferenceListRequest.pb( + reference_list.VerifyReferenceListRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = reference_list.VerifyReferenceListResponse.to_json( + reference_list.VerifyReferenceListResponse() + ) + req.return_value.content = return_value + + request = reference_list.VerifyReferenceListRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = reference_list.VerifyReferenceListResponse() + post_with_metadata.return_value = ( + reference_list.VerifyReferenceListResponse(), + metadata, + ) + + client.verify_reference_list( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + def test_cancel_operation_rest_bad_request( request_type=operations_pb2.CancelOperationRequest, ): @@ -5376,6 +5960,27 @@ def test_update_reference_list_empty_call_rest(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_verify_reference_list_empty_call_rest(): + client = ReferenceListServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.verify_reference_list), "__call__" + ) as call: + client.verify_reference_list(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = reference_list.VerifyReferenceListRequest() + assert args[0] == request_msg + + def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = ReferenceListServiceClient( @@ -5413,6 +6018,7 @@ def test_reference_list_service_base_transport(): "list_reference_lists", "create_reference_list", "update_reference_list", + "verify_reference_list", "get_operation", "cancel_operation", "delete_operation", @@ -5453,7 +6059,11 @@ def test_reference_list_service_base_transport_with_credentials_file(): load_creds.assert_called_once_with( "credentials.json", scopes=None, - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + default_scopes=( + "https://www.googleapis.com/auth/chronicle", + "https://www.googleapis.com/auth/chronicle.readonly", + "https://www.googleapis.com/auth/cloud-platform", + ), quota_project_id="octopus", ) @@ -5479,7 +6089,11 @@ def test_reference_list_service_auth_adc(): ReferenceListServiceClient() adc.assert_called_once_with( scopes=None, - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + default_scopes=( + "https://www.googleapis.com/auth/chronicle", + "https://www.googleapis.com/auth/chronicle.readonly", + "https://www.googleapis.com/auth/cloud-platform", + ), quota_project_id=None, ) @@ -5499,7 +6113,11 @@ def test_reference_list_service_transport_auth_adc(transport_class): 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",), + default_scopes=( + "https://www.googleapis.com/auth/chronicle", + "https://www.googleapis.com/auth/chronicle.readonly", + "https://www.googleapis.com/auth/cloud-platform", + ), quota_project_id="octopus", ) @@ -5552,7 +6170,11 @@ def test_reference_list_service_transport_create_channel(transport_class, grpc_h credentials=creds, credentials_file=None, quota_project_id="octopus", - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + default_scopes=( + "https://www.googleapis.com/auth/chronicle", + "https://www.googleapis.com/auth/chronicle.readonly", + "https://www.googleapis.com/auth/cloud-platform", + ), scopes=["1", "2"], default_host="chronicle.googleapis.com", ssl_credentials=None, @@ -5696,6 +6318,9 @@ def test_reference_list_service_client_transport_session_collision(transport_nam session1 = client1.transport.update_reference_list._session session2 = client2.transport.update_reference_list._session assert session1 != session2 + session1 = client1.transport.verify_reference_list._session + session2 = client2.transport.verify_reference_list._session + assert session1 != session2 def test_reference_list_service_grpc_transport_channel(): @@ -5825,11 +6450,37 @@ def test_reference_list_service_transport_channel_mtls_with_adc(transport_class) assert transport.grpc_channel == mock_grpc_channel -def test_reference_list_path(): +def test_instance_path(): project = "squid" location = "clam" instance = "whelk" - reference_list = "octopus" + expected = "projects/{project}/locations/{location}/instances/{instance}".format( + project=project, + location=location, + instance=instance, + ) + actual = ReferenceListServiceClient.instance_path(project, location, instance) + assert expected == actual + + +def test_parse_instance_path(): + expected = { + "project": "octopus", + "location": "oyster", + "instance": "nudibranch", + } + path = ReferenceListServiceClient.instance_path(**expected) + + # Check that the path construction is reversible. + actual = ReferenceListServiceClient.parse_instance_path(path) + assert expected == actual + + +def test_reference_list_path(): + project = "cuttlefish" + location = "mussel" + instance = "winkle" + reference_list = "nautilus" expected = "projects/{project}/locations/{location}/instances/{instance}/referenceLists/{reference_list}".format( project=project, location=location, @@ -5844,10 +6495,10 @@ def test_reference_list_path(): def test_parse_reference_list_path(): expected = { - "project": "oyster", - "location": "nudibranch", - "instance": "cuttlefish", - "reference_list": "mussel", + "project": "scallop", + "location": "abalone", + "instance": "squid", + "reference_list": "clam", } path = ReferenceListServiceClient.reference_list_path(**expected) @@ -5857,7 +6508,7 @@ def test_parse_reference_list_path(): def test_common_billing_account_path(): - billing_account = "winkle" + billing_account = "whelk" expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -5867,7 +6518,7 @@ def test_common_billing_account_path(): def test_parse_common_billing_account_path(): expected = { - "billing_account": "nautilus", + "billing_account": "octopus", } path = ReferenceListServiceClient.common_billing_account_path(**expected) @@ -5877,7 +6528,7 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): - folder = "scallop" + folder = "oyster" expected = "folders/{folder}".format( folder=folder, ) @@ -5887,7 +6538,7 @@ def test_common_folder_path(): def test_parse_common_folder_path(): expected = { - "folder": "abalone", + "folder": "nudibranch", } path = ReferenceListServiceClient.common_folder_path(**expected) @@ -5897,7 +6548,7 @@ def test_parse_common_folder_path(): def test_common_organization_path(): - organization = "squid" + organization = "cuttlefish" expected = "organizations/{organization}".format( organization=organization, ) @@ -5907,7 +6558,7 @@ def test_common_organization_path(): def test_parse_common_organization_path(): expected = { - "organization": "clam", + "organization": "mussel", } path = ReferenceListServiceClient.common_organization_path(**expected) @@ -5917,7 +6568,7 @@ def test_parse_common_organization_path(): def test_common_project_path(): - project = "whelk" + project = "winkle" expected = "projects/{project}".format( project=project, ) @@ -5927,7 +6578,7 @@ def test_common_project_path(): def test_parse_common_project_path(): expected = { - "project": "octopus", + "project": "nautilus", } path = ReferenceListServiceClient.common_project_path(**expected) @@ -5937,8 +6588,8 @@ def test_parse_common_project_path(): def test_common_location_path(): - project = "oyster" - location = "nudibranch" + project = "scallop" + location = "abalone" expected = "projects/{project}/locations/{location}".format( project=project, location=location, @@ -5949,8 +6600,8 @@ def test_common_location_path(): def test_parse_common_location_path(): expected = { - "project": "cuttlefish", - "location": "mussel", + "project": "squid", + "location": "clam", } path = ReferenceListServiceClient.common_location_path(**expected) diff --git a/packages/google-cloud-chronicle/tests/unit/gapic/chronicle_v1/test_rule_execution_error_service.py b/packages/google-cloud-chronicle/tests/unit/gapic/chronicle_v1/test_rule_execution_error_service.py new file mode 100644 index 000000000000..f1027b35867d --- /dev/null +++ b/packages/google-cloud-chronicle/tests/unit/gapic/chronicle_v1/test_rule_execution_error_service.py @@ -0,0 +1,4317 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 asyncio +import json +import math +import os +from collections.abc import AsyncIterable, Iterable, Mapping, Sequence +from unittest import mock +from unittest.mock import AsyncMock + +import grpc +import pytest +from google.api_core import api_core_version +from google.protobuf import json_format +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +import google.auth +from google.api_core import ( + client_options, + gapic_v1, + grpc_helpers, + grpc_helpers_async, + path_template, +) +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account + +from google.cloud.chronicle_v1.services.rule_execution_error_service import ( + RuleExecutionErrorServiceAsyncClient, + RuleExecutionErrorServiceClient, + pagers, + transports, +) +from google.cloud.chronicle_v1.types import rule_execution_error + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + +# 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 + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +@pytest.fixture(autouse=True) +def set_event_loop(): + try: + asyncio.get_running_loop() + yield + except RuntimeError: + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + try: + yield + finally: + loop.close() + asyncio.set_event_loop(None) + + +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" + custom_endpoint = ".custom" + + assert RuleExecutionErrorServiceClient._get_default_mtls_endpoint(None) is None + assert ( + RuleExecutionErrorServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + RuleExecutionErrorServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + RuleExecutionErrorServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + RuleExecutionErrorServiceClient._get_default_mtls_endpoint( + sandbox_mtls_endpoint + ) + == sandbox_mtls_endpoint + ) + assert ( + RuleExecutionErrorServiceClient._get_default_mtls_endpoint(non_googleapi) + == non_googleapi + ) + assert ( + RuleExecutionErrorServiceClient._get_default_mtls_endpoint(custom_endpoint) + == custom_endpoint + ) + + +def test__read_environment_variables(): + assert RuleExecutionErrorServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert RuleExecutionErrorServiceClient._read_environment_variables() == ( + True, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert RuleExecutionErrorServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with pytest.raises(ValueError) as excinfo: + RuleExecutionErrorServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + else: + assert RuleExecutionErrorServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert RuleExecutionErrorServiceClient._read_environment_variables() == ( + False, + "never", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert RuleExecutionErrorServiceClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert RuleExecutionErrorServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + RuleExecutionErrorServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert RuleExecutionErrorServiceClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test_use_client_cert_effective(): + # Test case 1: Test when `should_use_client_cert` returns True. + # We mock the `should_use_client_cert` function to simulate a scenario where + # the google-auth library supports automatic mTLS and determines that a + # client certificate should be used. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch( + "google.auth.transport.mtls.should_use_client_cert", return_value=True + ): + assert RuleExecutionErrorServiceClient._use_client_cert_effective() is True + + # Test case 2: Test when `should_use_client_cert` returns False. + # We mock the `should_use_client_cert` function to simulate a scenario where + # the google-auth library supports automatic mTLS and determines that a + # client certificate should NOT be used. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch( + "google.auth.transport.mtls.should_use_client_cert", return_value=False + ): + assert RuleExecutionErrorServiceClient._use_client_cert_effective() is False + + # Test case 3: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "true". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert RuleExecutionErrorServiceClient._use_client_cert_effective() is True + + # Test case 4: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "false". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"} + ): + assert RuleExecutionErrorServiceClient._use_client_cert_effective() is False + + # Test case 5: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "True". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "True"}): + assert RuleExecutionErrorServiceClient._use_client_cert_effective() is True + + # Test case 6: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "False". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "False"} + ): + assert RuleExecutionErrorServiceClient._use_client_cert_effective() is False + + # Test case 7: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "TRUE". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "TRUE"}): + assert RuleExecutionErrorServiceClient._use_client_cert_effective() is True + + # Test case 8: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "FALSE". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "FALSE"} + ): + assert RuleExecutionErrorServiceClient._use_client_cert_effective() is False + + # Test case 9: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not set. + # In this case, the method should return False, which is the default value. + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, clear=True): + assert RuleExecutionErrorServiceClient._use_client_cert_effective() is False + + # Test case 10: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value. + # The method should raise a ValueError as the environment variable must be either + # "true" or "false". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"} + ): + with pytest.raises(ValueError): + RuleExecutionErrorServiceClient._use_client_cert_effective() + + # Test case 11: Test when `should_use_client_cert` is available and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value. + # The method should return False as the environment variable is set to an invalid value. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"} + ): + assert RuleExecutionErrorServiceClient._use_client_cert_effective() is False + + # Test case 12: Test when `should_use_client_cert` is available and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is unset. Also, + # the GOOGLE_API_CONFIG environment variable is unset. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": ""}): + with mock.patch.dict(os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": ""}): + assert ( + RuleExecutionErrorServiceClient._use_client_cert_effective() + is False + ) + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert RuleExecutionErrorServiceClient._get_client_cert_source(None, False) is None + assert ( + RuleExecutionErrorServiceClient._get_client_cert_source( + mock_provided_cert_source, False + ) + is None + ) + assert ( + RuleExecutionErrorServiceClient._get_client_cert_source( + mock_provided_cert_source, True + ) + == mock_provided_cert_source + ) + + 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_default_cert_source, + ): + assert ( + RuleExecutionErrorServiceClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + RuleExecutionErrorServiceClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + RuleExecutionErrorServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(RuleExecutionErrorServiceClient), +) +@mock.patch.object( + RuleExecutionErrorServiceAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(RuleExecutionErrorServiceAsyncClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = RuleExecutionErrorServiceClient._DEFAULT_UNIVERSE + default_endpoint = ( + RuleExecutionErrorServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + ) + mock_universe = "bar.com" + mock_endpoint = RuleExecutionErrorServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + RuleExecutionErrorServiceClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + RuleExecutionErrorServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == RuleExecutionErrorServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + RuleExecutionErrorServiceClient._get_api_endpoint( + None, None, default_universe, "auto" + ) + == default_endpoint + ) + assert ( + RuleExecutionErrorServiceClient._get_api_endpoint( + None, None, default_universe, "always" + ) + == RuleExecutionErrorServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + RuleExecutionErrorServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == RuleExecutionErrorServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + RuleExecutionErrorServiceClient._get_api_endpoint( + None, None, mock_universe, "never" + ) + == mock_endpoint + ) + assert ( + RuleExecutionErrorServiceClient._get_api_endpoint( + None, None, default_universe, "never" + ) + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + RuleExecutionErrorServiceClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + RuleExecutionErrorServiceClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + RuleExecutionErrorServiceClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert ( + RuleExecutionErrorServiceClient._get_universe_domain(None, None) + == RuleExecutionErrorServiceClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + RuleExecutionErrorServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = RuleExecutionErrorServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = RuleExecutionErrorServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (RuleExecutionErrorServiceClient, "grpc"), + (RuleExecutionErrorServiceAsyncClient, "grpc_asyncio"), + (RuleExecutionErrorServiceClient, "rest"), + ], +) +def test_rule_execution_error_service_client_from_service_account_info( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "chronicle.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://chronicle.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.RuleExecutionErrorServiceGrpcTransport, "grpc"), + (transports.RuleExecutionErrorServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.RuleExecutionErrorServiceRestTransport, "rest"), + ], +) +def test_rule_execution_error_service_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (RuleExecutionErrorServiceClient, "grpc"), + (RuleExecutionErrorServiceAsyncClient, "grpc_asyncio"), + (RuleExecutionErrorServiceClient, "rest"), + ], +) +def test_rule_execution_error_service_client_from_service_account_file( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "chronicle.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://chronicle.googleapis.com" + ) + + +def test_rule_execution_error_service_client_get_transport_class(): + transport = RuleExecutionErrorServiceClient.get_transport_class() + available_transports = [ + transports.RuleExecutionErrorServiceGrpcTransport, + transports.RuleExecutionErrorServiceRestTransport, + ] + assert transport in available_transports + + transport = RuleExecutionErrorServiceClient.get_transport_class("grpc") + assert transport == transports.RuleExecutionErrorServiceGrpcTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + RuleExecutionErrorServiceClient, + transports.RuleExecutionErrorServiceGrpcTransport, + "grpc", + ), + ( + RuleExecutionErrorServiceAsyncClient, + transports.RuleExecutionErrorServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ( + RuleExecutionErrorServiceClient, + transports.RuleExecutionErrorServiceRestTransport, + "rest", + ), + ], +) +@mock.patch.object( + RuleExecutionErrorServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(RuleExecutionErrorServiceClient), +) +@mock.patch.object( + RuleExecutionErrorServiceAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(RuleExecutionErrorServiceAsyncClient), +) +def test_rule_execution_error_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( + RuleExecutionErrorServiceClient, "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( + RuleExecutionErrorServiceClient, "get_transport_class" + ) as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # 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_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + RuleExecutionErrorServiceClient, + transports.RuleExecutionErrorServiceGrpcTransport, + "grpc", + "true", + ), + ( + RuleExecutionErrorServiceAsyncClient, + transports.RuleExecutionErrorServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + ( + RuleExecutionErrorServiceClient, + transports.RuleExecutionErrorServiceGrpcTransport, + "grpc", + "false", + ), + ( + RuleExecutionErrorServiceAsyncClient, + transports.RuleExecutionErrorServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + ( + RuleExecutionErrorServiceClient, + transports.RuleExecutionErrorServiceRestTransport, + "rest", + "true", + ), + ( + RuleExecutionErrorServiceClient, + transports.RuleExecutionErrorServiceRestTransport, + "rest", + "false", + ), + ], +) +@mock.patch.object( + RuleExecutionErrorServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(RuleExecutionErrorServiceClient), +) +@mock.patch.object( + RuleExecutionErrorServiceAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(RuleExecutionErrorServiceAsyncClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_rule_execution_error_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_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class", + [RuleExecutionErrorServiceClient, RuleExecutionErrorServiceAsyncClient], +) +@mock.patch.object( + RuleExecutionErrorServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(RuleExecutionErrorServiceClient), +) +@mock.patch.object( + RuleExecutionErrorServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(RuleExecutionErrorServiceAsyncClient), +) +def test_rule_execution_error_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_CLIENT_CERTIFICATE is "Unsupported". + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + 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 cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset. + test_cases = [ + ( + # With workloads present in config, mTLS is enabled. + { + "version": 1, + "cert_configs": { + "workload": { + "cert_path": "path/to/cert/file", + "key_path": "path/to/key/file", + } + }, + }, + mock_client_cert_source, + ), + ( + # With workloads not present in config, mTLS is disabled. + { + "version": 1, + "cert_configs": {}, + }, + None, + ), + ] + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + for config_data, expected_cert_source in test_cases: + env = os.environ.copy() + env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", None) + with mock.patch.dict(os.environ, env, clear=True): + config_filename = "mock_certificate_config.json" + config_file_content = json.dumps(config_data) + m = mock.mock_open(read_data=config_file_content) + with mock.patch("builtins.open", m): + with mock.patch.dict( + os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename} + ): + 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 expected_cert_source + + # Test cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset(empty). + test_cases = [ + ( + # With workloads present in config, mTLS is enabled. + { + "version": 1, + "cert_configs": { + "workload": { + "cert_path": "path/to/cert/file", + "key_path": "path/to/key/file", + } + }, + }, + mock_client_cert_source, + ), + ( + # With workloads not present in config, mTLS is disabled. + { + "version": 1, + "cert_configs": {}, + }, + None, + ), + ] + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + for config_data, expected_cert_source in test_cases: + env = os.environ.copy() + env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", "") + with mock.patch.dict(os.environ, env, clear=True): + config_filename = "mock_certificate_config.json" + config_file_content = json.dumps(config_data) + m = mock.mock_open(read_data=config_file_content) + with mock.patch("builtins.open", m): + with mock.patch.dict( + os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename} + ): + 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 expected_cert_source + + # 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 + + # 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) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + +@pytest.mark.parametrize( + "client_class", + [RuleExecutionErrorServiceClient, RuleExecutionErrorServiceAsyncClient], +) +@mock.patch.object( + RuleExecutionErrorServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(RuleExecutionErrorServiceClient), +) +@mock.patch.object( + RuleExecutionErrorServiceAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(RuleExecutionErrorServiceAsyncClient), +) +def test_rule_execution_error_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = RuleExecutionErrorServiceClient._DEFAULT_UNIVERSE + default_endpoint = ( + RuleExecutionErrorServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + ) + mock_universe = "bar.com" + mock_endpoint = RuleExecutionErrorServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + RuleExecutionErrorServiceClient, + transports.RuleExecutionErrorServiceGrpcTransport, + "grpc", + ), + ( + RuleExecutionErrorServiceAsyncClient, + transports.RuleExecutionErrorServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ( + RuleExecutionErrorServiceClient, + transports.RuleExecutionErrorServiceRestTransport, + "rest", + ), + ], +) +def test_rule_execution_error_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_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + RuleExecutionErrorServiceClient, + transports.RuleExecutionErrorServiceGrpcTransport, + "grpc", + grpc_helpers, + ), + ( + RuleExecutionErrorServiceAsyncClient, + transports.RuleExecutionErrorServiceGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + ( + RuleExecutionErrorServiceClient, + transports.RuleExecutionErrorServiceRestTransport, + "rest", + None, + ), + ], +) +def test_rule_execution_error_service_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_rule_execution_error_service_client_client_options_from_dict(): + with mock.patch( + "google.cloud.chronicle_v1.services.rule_execution_error_service.transports.RuleExecutionErrorServiceGrpcTransport.__init__" + ) as grpc_transport: + grpc_transport.return_value = None + client = RuleExecutionErrorServiceClient( + client_options={"api_endpoint": "squid.clam.whelk"} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + RuleExecutionErrorServiceClient, + transports.RuleExecutionErrorServiceGrpcTransport, + "grpc", + grpc_helpers, + ), + ( + RuleExecutionErrorServiceAsyncClient, + transports.RuleExecutionErrorServiceGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + ], +) +def test_rule_execution_error_service_client_create_channel_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # test that the credentials from file are saved and used as the credentials. + with ( + mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, + mock.patch.object(google.auth, "default", autospec=True) as adc, + mock.patch.object(grpc_helpers, "create_channel") as create_channel, + ): + creds = ga_credentials.AnonymousCredentials() + file_creds = ga_credentials.AnonymousCredentials() + load_creds.return_value = (file_creds, None) + adc.return_value = (creds, None) + client = client_class(client_options=options, transport=transport_name) + create_channel.assert_called_with( + "chronicle.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + "https://www.googleapis.com/auth/chronicle", + "https://www.googleapis.com/auth/chronicle.readonly", + "https://www.googleapis.com/auth/cloud-platform", + ), + scopes=None, + default_host="chronicle.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "request_type", + [ + rule_execution_error.ListRuleExecutionErrorsRequest(), + {}, + ], +) +def test_list_rule_execution_errors(request_type, transport: str = "grpc"): + client = RuleExecutionErrorServiceClient( + 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_rule_execution_errors), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = rule_execution_error.ListRuleExecutionErrorsResponse( + next_page_token="next_page_token_value", + ) + response = client.list_rule_execution_errors(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = rule_execution_error.ListRuleExecutionErrorsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListRuleExecutionErrorsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_rule_execution_errors_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = rule_execution_error.ListRuleExecutionErrorsRequest( + parent="parent_value", + page_token="page_token_value", + filter="filter_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_rule_execution_errors), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.list_rule_execution_errors(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = rule_execution_error.ListRuleExecutionErrorsRequest( + parent="parent_value", + page_token="page_token_value", + filter="filter_value", + ) + assert args[0] == request_msg + + +def test_list_rule_execution_errors_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_rule_execution_errors + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_rule_execution_errors + ] = mock_rpc + request = {} + client.list_rule_execution_errors(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_rule_execution_errors(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_list_rule_execution_errors_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = RuleExecutionErrorServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.list_rule_execution_errors + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.list_rule_execution_errors + ] = mock_rpc + + request = {} + await client.list_rule_execution_errors(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.list_rule_execution_errors(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + rule_execution_error.ListRuleExecutionErrorsRequest(), + {}, + ], +) +async def test_list_rule_execution_errors_async( + request_type, transport: str = "grpc_asyncio" +): + client = RuleExecutionErrorServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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_rule_execution_errors), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + rule_execution_error.ListRuleExecutionErrorsResponse( + next_page_token="next_page_token_value", + ) + ) + response = await client.list_rule_execution_errors(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = rule_execution_error.ListRuleExecutionErrorsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListRuleExecutionErrorsAsyncPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_rule_execution_errors_field_headers(): + client = RuleExecutionErrorServiceClient( + 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 = rule_execution_error.ListRuleExecutionErrorsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_rule_execution_errors), "__call__" + ) as call: + call.return_value = rule_execution_error.ListRuleExecutionErrorsResponse() + client.list_rule_execution_errors(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_rule_execution_errors_field_headers_async(): + client = RuleExecutionErrorServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = rule_execution_error.ListRuleExecutionErrorsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_rule_execution_errors), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + rule_execution_error.ListRuleExecutionErrorsResponse() + ) + await client.list_rule_execution_errors(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_rule_execution_errors_flattened(): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_rule_execution_errors), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = rule_execution_error.ListRuleExecutionErrorsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_rule_execution_errors( + 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_rule_execution_errors_flattened_error(): + client = RuleExecutionErrorServiceClient( + 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_rule_execution_errors( + rule_execution_error.ListRuleExecutionErrorsRequest(), + parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_list_rule_execution_errors_flattened_async(): + client = RuleExecutionErrorServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_rule_execution_errors), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = rule_execution_error.ListRuleExecutionErrorsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + rule_execution_error.ListRuleExecutionErrorsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_rule_execution_errors( + 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_rule_execution_errors_flattened_error_async(): + client = RuleExecutionErrorServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_rule_execution_errors( + rule_execution_error.ListRuleExecutionErrorsRequest(), + parent="parent_value", + ) + + +def test_list_rule_execution_errors_pager(transport_name: str = "grpc"): + client = RuleExecutionErrorServiceClient( + 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_rule_execution_errors), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + rule_execution_error.ListRuleExecutionErrorsResponse( + rule_execution_errors=[ + rule_execution_error.RuleExecutionError(), + rule_execution_error.RuleExecutionError(), + rule_execution_error.RuleExecutionError(), + ], + next_page_token="abc", + ), + rule_execution_error.ListRuleExecutionErrorsResponse( + rule_execution_errors=[], + next_page_token="def", + ), + rule_execution_error.ListRuleExecutionErrorsResponse( + rule_execution_errors=[ + rule_execution_error.RuleExecutionError(), + ], + next_page_token="ghi", + ), + rule_execution_error.ListRuleExecutionErrorsResponse( + rule_execution_errors=[ + rule_execution_error.RuleExecutionError(), + rule_execution_error.RuleExecutionError(), + ], + ), + RuntimeError, + ) + + expected_metadata = () + retry = retries.Retry() + timeout = 5 + expected_metadata = tuple(expected_metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_rule_execution_errors( + request={}, retry=retry, timeout=timeout + ) + + assert pager._metadata == expected_metadata + assert pager._retry == retry + assert pager._timeout == timeout + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, rule_execution_error.RuleExecutionError) for i in results + ) + + +def test_list_rule_execution_errors_pages(transport_name: str = "grpc"): + client = RuleExecutionErrorServiceClient( + 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_rule_execution_errors), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + rule_execution_error.ListRuleExecutionErrorsResponse( + rule_execution_errors=[ + rule_execution_error.RuleExecutionError(), + rule_execution_error.RuleExecutionError(), + rule_execution_error.RuleExecutionError(), + ], + next_page_token="abc", + ), + rule_execution_error.ListRuleExecutionErrorsResponse( + rule_execution_errors=[], + next_page_token="def", + ), + rule_execution_error.ListRuleExecutionErrorsResponse( + rule_execution_errors=[ + rule_execution_error.RuleExecutionError(), + ], + next_page_token="ghi", + ), + rule_execution_error.ListRuleExecutionErrorsResponse( + rule_execution_errors=[ + rule_execution_error.RuleExecutionError(), + rule_execution_error.RuleExecutionError(), + ], + ), + RuntimeError, + ) + pages = list(client.list_rule_execution_errors(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_rule_execution_errors_async_pager(): + client = RuleExecutionErrorServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_rule_execution_errors), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + rule_execution_error.ListRuleExecutionErrorsResponse( + rule_execution_errors=[ + rule_execution_error.RuleExecutionError(), + rule_execution_error.RuleExecutionError(), + rule_execution_error.RuleExecutionError(), + ], + next_page_token="abc", + ), + rule_execution_error.ListRuleExecutionErrorsResponse( + rule_execution_errors=[], + next_page_token="def", + ), + rule_execution_error.ListRuleExecutionErrorsResponse( + rule_execution_errors=[ + rule_execution_error.RuleExecutionError(), + ], + next_page_token="ghi", + ), + rule_execution_error.ListRuleExecutionErrorsResponse( + rule_execution_errors=[ + rule_execution_error.RuleExecutionError(), + rule_execution_error.RuleExecutionError(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_rule_execution_errors( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all( + isinstance(i, rule_execution_error.RuleExecutionError) for i in responses + ) + + +@pytest.mark.asyncio +async def test_list_rule_execution_errors_async_pages(): + client = RuleExecutionErrorServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_rule_execution_errors), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + rule_execution_error.ListRuleExecutionErrorsResponse( + rule_execution_errors=[ + rule_execution_error.RuleExecutionError(), + rule_execution_error.RuleExecutionError(), + rule_execution_error.RuleExecutionError(), + ], + next_page_token="abc", + ), + rule_execution_error.ListRuleExecutionErrorsResponse( + rule_execution_errors=[], + next_page_token="def", + ), + rule_execution_error.ListRuleExecutionErrorsResponse( + rule_execution_errors=[ + rule_execution_error.RuleExecutionError(), + ], + next_page_token="ghi", + ), + rule_execution_error.ListRuleExecutionErrorsResponse( + rule_execution_errors=[ + rule_execution_error.RuleExecutionError(), + rule_execution_error.RuleExecutionError(), + ], + ), + RuntimeError, + ) + pages = [] + async for page_ in (await client.list_rule_execution_errors(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_list_rule_execution_errors_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_rule_execution_errors + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_rule_execution_errors + ] = mock_rpc + + request = {} + client.list_rule_execution_errors(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_rule_execution_errors(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_rule_execution_errors_rest_required_fields( + request_type=rule_execution_error.ListRuleExecutionErrorsRequest, +): + transport_class = transports.RuleExecutionErrorServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_rule_execution_errors._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_rule_execution_errors._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = rule_execution_error.ListRuleExecutionErrorsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = rule_execution_error.ListRuleExecutionErrorsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_rule_execution_errors(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_list_rule_execution_errors_rest_unset_required_fields(): + transport = transports.RuleExecutionErrorServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_rule_execution_errors._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +def test_list_rule_execution_errors_rest_flattened(): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = rule_execution_error.ListRuleExecutionErrorsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = { + "parent": "projects/sample1/locations/sample2/instances/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = rule_execution_error.ListRuleExecutionErrorsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_rule_execution_errors(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/locations/*/instances/*}/ruleExecutionErrors" + % client.transport._host, + args[1], + ) + + +def test_list_rule_execution_errors_rest_flattened_error(transport: str = "rest"): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_rule_execution_errors( + rule_execution_error.ListRuleExecutionErrorsRequest(), + parent="parent_value", + ) + + +def test_list_rule_execution_errors_rest_pager(transport: str = "rest"): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + rule_execution_error.ListRuleExecutionErrorsResponse( + rule_execution_errors=[ + rule_execution_error.RuleExecutionError(), + rule_execution_error.RuleExecutionError(), + rule_execution_error.RuleExecutionError(), + ], + next_page_token="abc", + ), + rule_execution_error.ListRuleExecutionErrorsResponse( + rule_execution_errors=[], + next_page_token="def", + ), + rule_execution_error.ListRuleExecutionErrorsResponse( + rule_execution_errors=[ + rule_execution_error.RuleExecutionError(), + ], + next_page_token="ghi", + ), + rule_execution_error.ListRuleExecutionErrorsResponse( + rule_execution_errors=[ + rule_execution_error.RuleExecutionError(), + rule_execution_error.RuleExecutionError(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + rule_execution_error.ListRuleExecutionErrorsResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = { + "parent": "projects/sample1/locations/sample2/instances/sample3" + } + + pager = client.list_rule_execution_errors(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, rule_execution_error.RuleExecutionError) for i in results + ) + + pages = list(client.list_rule_execution_errors(request=sample_request).pages) + 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.RuleExecutionErrorServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.RuleExecutionErrorServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = RuleExecutionErrorServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.RuleExecutionErrorServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = RuleExecutionErrorServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = RuleExecutionErrorServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.RuleExecutionErrorServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = RuleExecutionErrorServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.RuleExecutionErrorServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = RuleExecutionErrorServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.RuleExecutionErrorServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.RuleExecutionErrorServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.RuleExecutionErrorServiceGrpcTransport, + transports.RuleExecutionErrorServiceGrpcAsyncIOTransport, + transports.RuleExecutionErrorServiceRestTransport, + ], +) +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_kind_grpc(): + transport = RuleExecutionErrorServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_rule_execution_errors_empty_call_grpc(): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_rule_execution_errors), "__call__" + ) as call: + call.return_value = rule_execution_error.ListRuleExecutionErrorsResponse() + client.list_rule_execution_errors(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = rule_execution_error.ListRuleExecutionErrorsRequest() + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = RuleExecutionErrorServiceAsyncClient.get_transport_class( + "grpc_asyncio" + )(credentials=async_anonymous_credentials()) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = RuleExecutionErrorServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_rule_execution_errors_empty_call_grpc_asyncio(): + client = RuleExecutionErrorServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_rule_execution_errors), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + rule_execution_error.ListRuleExecutionErrorsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_rule_execution_errors(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = rule_execution_error.ListRuleExecutionErrorsRequest() + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = RuleExecutionErrorServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_list_rule_execution_errors_rest_bad_request( + request_type=rule_execution_error.ListRuleExecutionErrorsRequest, +): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2/instances/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_rule_execution_errors(request) + + +@pytest.mark.parametrize( + "request_type", + [ + rule_execution_error.ListRuleExecutionErrorsRequest, + dict, + ], +) +def test_list_rule_execution_errors_rest_call_success(request_type): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2/instances/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = rule_execution_error.ListRuleExecutionErrorsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = rule_execution_error.ListRuleExecutionErrorsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_rule_execution_errors(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListRuleExecutionErrorsPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_rule_execution_errors_rest_interceptors(null_interceptor): + transport = transports.RuleExecutionErrorServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.RuleExecutionErrorServiceRestInterceptor(), + ) + client = RuleExecutionErrorServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.RuleExecutionErrorServiceRestInterceptor, + "post_list_rule_execution_errors", + ) as post, + mock.patch.object( + transports.RuleExecutionErrorServiceRestInterceptor, + "post_list_rule_execution_errors_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.RuleExecutionErrorServiceRestInterceptor, + "pre_list_rule_execution_errors", + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = rule_execution_error.ListRuleExecutionErrorsRequest.pb( + rule_execution_error.ListRuleExecutionErrorsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = rule_execution_error.ListRuleExecutionErrorsResponse.to_json( + rule_execution_error.ListRuleExecutionErrorsResponse() + ) + req.return_value.content = return_value + + request = rule_execution_error.ListRuleExecutionErrorsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = rule_execution_error.ListRuleExecutionErrorsResponse() + post_with_metadata.return_value = ( + rule_execution_error.ListRuleExecutionErrorsResponse(), + metadata, + ) + + client.list_rule_execution_errors( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_cancel_operation_rest_bad_request( + request_type=operations_pb2.CancelOperationRequest, +): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + { + "name": "projects/sample1/locations/sample2/instances/sample3/operations/sample4" + }, + request, + ) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.cancel_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.CancelOperationRequest, + dict, + ], +) +def test_cancel_operation_rest(request_type): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = { + "name": "projects/sample1/locations/sample2/instances/sample3/operations/sample4" + } + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = "{}" + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.cancel_operation(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_operation_rest_bad_request( + request_type=operations_pb2.DeleteOperationRequest, +): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + { + "name": "projects/sample1/locations/sample2/instances/sample3/operations/sample4" + }, + request, + ) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.delete_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.DeleteOperationRequest, + dict, + ], +) +def test_delete_operation_rest(request_type): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = { + "name": "projects/sample1/locations/sample2/instances/sample3/operations/sample4" + } + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = "{}" + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.delete_operation(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_get_operation_rest_bad_request( + request_type=operations_pb2.GetOperationRequest, +): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + { + "name": "projects/sample1/locations/sample2/instances/sample3/operations/sample4" + }, + request, + ) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = { + "name": "projects/sample1/locations/sample2/instances/sample3/operations/sample4" + } + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_list_operations_rest_bad_request( + request_type=operations_pb2.ListOperationsRequest, +): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "projects/sample1/locations/sample2/instances/sample3"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_operations(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.ListOperationsRequest, + dict, + ], +) +def test_list_operations_rest(request_type): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "projects/sample1/locations/sample2/instances/sample3"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.ListOperationsResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_initialize_client_w_rest(): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_rule_execution_errors_empty_call_rest(): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_rule_execution_errors), "__call__" + ) as call: + client.list_rule_execution_errors(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = rule_execution_error.ListRuleExecutionErrorsRequest() + assert args[0] == request_msg + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.RuleExecutionErrorServiceGrpcTransport, + ) + + +def test_rule_execution_error_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.RuleExecutionErrorServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_rule_execution_error_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.cloud.chronicle_v1.services.rule_execution_error_service.transports.RuleExecutionErrorServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.RuleExecutionErrorServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "list_rule_execution_errors", + "get_operation", + "cancel_operation", + "delete_operation", + "list_operations", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_rule_execution_error_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.chronicle_v1.services.rule_execution_error_service.transports.RuleExecutionErrorServiceTransport._prep_wrapped_messages" + ) as Transport, + ): + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.RuleExecutionErrorServiceTransport( + 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/chronicle", + "https://www.googleapis.com/auth/chronicle.readonly", + "https://www.googleapis.com/auth/cloud-platform", + ), + quota_project_id="octopus", + ) + + +def test_rule_execution_error_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.chronicle_v1.services.rule_execution_error_service.transports.RuleExecutionErrorServiceTransport._prep_wrapped_messages" + ) as Transport, + ): + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.RuleExecutionErrorServiceTransport() + adc.assert_called_once() + + +def test_rule_execution_error_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) + RuleExecutionErrorServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + "https://www.googleapis.com/auth/chronicle", + "https://www.googleapis.com/auth/chronicle.readonly", + "https://www.googleapis.com/auth/cloud-platform", + ), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.RuleExecutionErrorServiceGrpcTransport, + transports.RuleExecutionErrorServiceGrpcAsyncIOTransport, + ], +) +def test_rule_execution_error_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/chronicle", + "https://www.googleapis.com/auth/chronicle.readonly", + "https://www.googleapis.com/auth/cloud-platform", + ), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.RuleExecutionErrorServiceGrpcTransport, + transports.RuleExecutionErrorServiceGrpcAsyncIOTransport, + transports.RuleExecutionErrorServiceRestTransport, + ], +) +def test_rule_execution_error_service_transport_auth_gdch_credentials(transport_class): + host = "https://language.com" + api_audience_tests = [None, "https://language2.com"] + api_audience_expect = [host, "https://language2.com"] + for t, e in zip(api_audience_tests, api_audience_expect): + with mock.patch.object(google.auth, "default", autospec=True) as adc: + gdch_mock = mock.MagicMock() + type(gdch_mock).with_gdch_audience = mock.PropertyMock( + return_value=gdch_mock + ) + adc.return_value = (gdch_mock, None) + transport_class(host=host, api_audience=t) + gdch_mock.with_gdch_audience.assert_called_once_with(e) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.RuleExecutionErrorServiceGrpcTransport, grpc_helpers), + (transports.RuleExecutionErrorServiceGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +def test_rule_execution_error_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( + "chronicle.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + "https://www.googleapis.com/auth/chronicle", + "https://www.googleapis.com/auth/chronicle.readonly", + "https://www.googleapis.com/auth/cloud-platform", + ), + scopes=["1", "2"], + default_host="chronicle.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.RuleExecutionErrorServiceGrpcTransport, + transports.RuleExecutionErrorServiceGrpcAsyncIOTransport, + ], +) +def test_rule_execution_error_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_rule_execution_error_service_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.RuleExecutionErrorServiceRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_rule_execution_error_service_host_no_port(transport_name): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="chronicle.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "chronicle.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://chronicle.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_rule_execution_error_service_host_with_port(transport_name): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="chronicle.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "chronicle.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://chronicle.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_rule_execution_error_service_client_transport_session_collision( + transport_name, +): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = RuleExecutionErrorServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = RuleExecutionErrorServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.list_rule_execution_errors._session + session2 = client2.transport.list_rule_execution_errors._session + assert session1 != session2 + + +def test_rule_execution_error_service_grpc_transport_channel(): + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.RuleExecutionErrorServiceGrpcTransport( + 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_rule_execution_error_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.RuleExecutionErrorServiceGrpcAsyncIOTransport( + 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.filterwarnings("ignore::FutureWarning") +@pytest.mark.parametrize( + "transport_class", + [ + transports.RuleExecutionErrorServiceGrpcTransport, + transports.RuleExecutionErrorServiceGrpcAsyncIOTransport, + ], +) +def test_rule_execution_error_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.RuleExecutionErrorServiceGrpcTransport, + transports.RuleExecutionErrorServiceGrpcAsyncIOTransport, + ], +) +def test_rule_execution_error_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_curated_rule_path(): + project = "squid" + location = "clam" + instance = "whelk" + curatedRule = "octopus" + expected = "projects/{project}/locations/{location}/instances/{instance}/curatedRules/{curatedRule}".format( + project=project, + location=location, + instance=instance, + curatedRule=curatedRule, + ) + actual = RuleExecutionErrorServiceClient.curated_rule_path( + project, location, instance, curatedRule + ) + assert expected == actual + + +def test_parse_curated_rule_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + "instance": "cuttlefish", + "curatedRule": "mussel", + } + path = RuleExecutionErrorServiceClient.curated_rule_path(**expected) + + # Check that the path construction is reversible. + actual = RuleExecutionErrorServiceClient.parse_curated_rule_path(path) + assert expected == actual + + +def test_rule_path(): + project = "winkle" + location = "nautilus" + instance = "scallop" + rule = "abalone" + expected = "projects/{project}/locations/{location}/instances/{instance}/rules/{rule}".format( + project=project, + location=location, + instance=instance, + rule=rule, + ) + actual = RuleExecutionErrorServiceClient.rule_path( + project, location, instance, rule + ) + assert expected == actual + + +def test_parse_rule_path(): + expected = { + "project": "squid", + "location": "clam", + "instance": "whelk", + "rule": "octopus", + } + path = RuleExecutionErrorServiceClient.rule_path(**expected) + + # Check that the path construction is reversible. + actual = RuleExecutionErrorServiceClient.parse_rule_path(path) + assert expected == actual + + +def test_rule_execution_error_path(): + project = "oyster" + location = "nudibranch" + instance = "cuttlefish" + rule_execution_error = "mussel" + expected = "projects/{project}/locations/{location}/instances/{instance}/ruleExecutionErrors/{rule_execution_error}".format( + project=project, + location=location, + instance=instance, + rule_execution_error=rule_execution_error, + ) + actual = RuleExecutionErrorServiceClient.rule_execution_error_path( + project, location, instance, rule_execution_error + ) + assert expected == actual + + +def test_parse_rule_execution_error_path(): + expected = { + "project": "winkle", + "location": "nautilus", + "instance": "scallop", + "rule_execution_error": "abalone", + } + path = RuleExecutionErrorServiceClient.rule_execution_error_path(**expected) + + # Check that the path construction is reversible. + actual = RuleExecutionErrorServiceClient.parse_rule_execution_error_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "squid" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = RuleExecutionErrorServiceClient.common_billing_account_path( + billing_account + ) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "clam", + } + path = RuleExecutionErrorServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = RuleExecutionErrorServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "whelk" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = RuleExecutionErrorServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "octopus", + } + path = RuleExecutionErrorServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = RuleExecutionErrorServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "oyster" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = RuleExecutionErrorServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nudibranch", + } + path = RuleExecutionErrorServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = RuleExecutionErrorServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "cuttlefish" + expected = "projects/{project}".format( + project=project, + ) + actual = RuleExecutionErrorServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "mussel", + } + path = RuleExecutionErrorServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = RuleExecutionErrorServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "winkle" + location = "nautilus" + expected = "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + actual = RuleExecutionErrorServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "scallop", + "location": "abalone", + } + path = RuleExecutionErrorServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = RuleExecutionErrorServiceClient.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.RuleExecutionErrorServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.RuleExecutionErrorServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = RuleExecutionErrorServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_delete_operation(transport: str = "grpc"): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.DeleteOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_operation_async(transport: str = "grpc_asyncio"): + client = RuleExecutionErrorServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.DeleteOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_operation_field_headers(): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.DeleteOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + call.return_value = None + + client.delete_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_delete_operation_field_headers_async(): + client = RuleExecutionErrorServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.DeleteOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_delete_operation_from_dict(): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + + response = client.delete_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_delete_operation_from_dict_async(): + client = RuleExecutionErrorServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_delete_operation_flattened(): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + + client.delete_operation() + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == operations_pb2.DeleteOperationRequest() + + +@pytest.mark.asyncio +async def test_delete_operation_flattened_async(): + client = RuleExecutionErrorServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_operation() + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == operations_pb2.DeleteOperationRequest() + + +def test_cancel_operation(transport: str = "grpc"): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.CancelOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.cancel_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_cancel_operation_async(transport: str = "grpc_asyncio"): + client = RuleExecutionErrorServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.CancelOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.cancel_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +def test_cancel_operation_field_headers(): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.CancelOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + call.return_value = None + + client.cancel_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_cancel_operation_field_headers_async(): + client = RuleExecutionErrorServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.CancelOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.cancel_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_cancel_operation_from_dict(): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + + response = client.cancel_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_cancel_operation_from_dict_async(): + client = RuleExecutionErrorServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.cancel_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_cancel_operation_flattened(): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + + client.cancel_operation() + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == operations_pb2.CancelOperationRequest() + + +@pytest.mark.asyncio +async def test_cancel_operation_flattened_async(): + client = RuleExecutionErrorServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.cancel_operation() + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == operations_pb2.CancelOperationRequest() + + +def test_get_operation(transport: str = "grpc"): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc_asyncio"): + client = RuleExecutionErrorServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_get_operation_field_headers(): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = RuleExecutionErrorServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_get_operation_from_dict(): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = RuleExecutionErrorServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_get_operation_flattened(): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + client.get_operation() + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == operations_pb2.GetOperationRequest() + + +@pytest.mark.asyncio +async def test_get_operation_flattened_async(): + client = RuleExecutionErrorServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation() + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == operations_pb2.GetOperationRequest() + + +def test_list_operations(transport: str = "grpc"): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc_asyncio"): + client = RuleExecutionErrorServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_list_operations_field_headers(): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = RuleExecutionErrorServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_list_operations_from_dict(): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = RuleExecutionErrorServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations_flattened(): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations() + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == operations_pb2.ListOperationsRequest() + + +@pytest.mark.asyncio +async def test_list_operations_flattened_async(): + client = RuleExecutionErrorServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations() + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == operations_pb2.ListOperationsRequest() + + +def test_transport_close_grpc(): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +@pytest.mark.asyncio +async def test_transport_close_grpc_asyncio(): + client = RuleExecutionErrorServiceAsyncClient( + credentials=async_anonymous_credentials(), 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_rest(): + client = RuleExecutionErrorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + "grpc", + ] + for transport in transports: + client = RuleExecutionErrorServiceClient( + 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", + [ + ( + RuleExecutionErrorServiceClient, + transports.RuleExecutionErrorServiceGrpcTransport, + ), + ( + RuleExecutionErrorServiceAsyncClient, + transports.RuleExecutionErrorServiceGrpcAsyncIOTransport, + ), + ], +) +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_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/packages/google-cloud-chronicle/tests/unit/gapic/chronicle_v1/test_rule_service.py b/packages/google-cloud-chronicle/tests/unit/gapic/chronicle_v1/test_rule_service.py index 699fba4cebd9..f5dda5f4378f 100644 --- a/packages/google-cloud-chronicle/tests/unit/gapic/chronicle_v1/test_rule_service.py +++ b/packages/google-cloud-chronicle/tests/unit/gapic/chronicle_v1/test_rule_service.py @@ -1283,7 +1283,11 @@ def test_rule_service_client_create_channel_credentials_file( credentials=file_creds, credentials_file=None, quota_project_id=None, - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + default_scopes=( + "https://www.googleapis.com/auth/chronicle", + "https://www.googleapis.com/auth/chronicle.readonly", + "https://www.googleapis.com/auth/cloud-platform", + ), scopes=None, default_host="chronicle.googleapis.com", ssl_credentials=None, @@ -3228,6 +3232,344 @@ async def test_delete_rule_flattened_error_async(): ) +@pytest.mark.parametrize( + "request_type", + [ + rule.VerifyRuleTextRequest(), + {}, + ], +) +def test_verify_rule_text(request_type, transport: str = "grpc"): + client = RuleServiceClient( + 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.verify_rule_text), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = rule.VerifyRuleTextResponse( + success=True, + ) + response = client.verify_rule_text(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = rule.VerifyRuleTextRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, rule.VerifyRuleTextResponse) + assert response.success is True + + +def test_verify_rule_text_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = RuleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = rule.VerifyRuleTextRequest( + instance="instance_value", + rule_text="rule_text_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.verify_rule_text), "__call__") as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.verify_rule_text(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = rule.VerifyRuleTextRequest( + instance="instance_value", + rule_text="rule_text_value", + ) + assert args[0] == request_msg + + +def test_verify_rule_text_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = RuleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.verify_rule_text in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.verify_rule_text] = ( + mock_rpc + ) + request = {} + client.verify_rule_text(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.verify_rule_text(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_verify_rule_text_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = RuleServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.verify_rule_text + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.verify_rule_text + ] = mock_rpc + + request = {} + await client.verify_rule_text(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.verify_rule_text(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + rule.VerifyRuleTextRequest(), + {}, + ], +) +async def test_verify_rule_text_async(request_type, transport: str = "grpc_asyncio"): + client = RuleServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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.verify_rule_text), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + rule.VerifyRuleTextResponse( + success=True, + ) + ) + response = await client.verify_rule_text(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = rule.VerifyRuleTextRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, rule.VerifyRuleTextResponse) + assert response.success is True + + +def test_verify_rule_text_field_headers(): + client = RuleServiceClient( + 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 = rule.VerifyRuleTextRequest() + + request.instance = "instance_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.verify_rule_text), "__call__") as call: + call.return_value = rule.VerifyRuleTextResponse() + client.verify_rule_text(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", + "instance=instance_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_verify_rule_text_field_headers_async(): + client = RuleServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = rule.VerifyRuleTextRequest() + + request.instance = "instance_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.verify_rule_text), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + rule.VerifyRuleTextResponse() + ) + await client.verify_rule_text(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", + "instance=instance_value", + ) in kw["metadata"] + + +def test_verify_rule_text_flattened(): + client = RuleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.verify_rule_text), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = rule.VerifyRuleTextResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.verify_rule_text( + instance="instance_value", + rule_text="rule_text_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].instance + mock_val = "instance_value" + assert arg == mock_val + arg = args[0].rule_text + mock_val = "rule_text_value" + assert arg == mock_val + + +def test_verify_rule_text_flattened_error(): + client = RuleServiceClient( + 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.verify_rule_text( + rule.VerifyRuleTextRequest(), + instance="instance_value", + rule_text="rule_text_value", + ) + + +@pytest.mark.asyncio +async def test_verify_rule_text_flattened_async(): + client = RuleServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.verify_rule_text), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = rule.VerifyRuleTextResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + rule.VerifyRuleTextResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.verify_rule_text( + instance="instance_value", + rule_text="rule_text_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].instance + mock_val = "instance_value" + assert arg == mock_val + arg = args[0].rule_text + mock_val = "rule_text_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_verify_rule_text_flattened_error_async(): + client = RuleServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.verify_rule_text( + rule.VerifyRuleTextRequest(), + instance="instance_value", + rule_text="rule_text_value", + ) + + @pytest.mark.parametrize( "request_type", [ @@ -7119,8 +7461,187 @@ def test_delete_rule_rest_required_fields(request_type=rule.DeleteRuleRequest): jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = RuleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = None + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "delete", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.delete_rule(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_delete_rule_rest_unset_required_fields(): + transport = transports.RuleServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.delete_rule._get_unset_required_fields({}) + assert set(unset_fields) == (set(("force",)) & set(("name",))) + + +def test_delete_rule_rest_flattened(): + client = RuleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/instances/sample3/rules/sample4" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.delete_rule(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/locations/*/instances/*/rules/*}" + % client.transport._host, + args[1], + ) + + +def test_delete_rule_rest_flattened_error(transport: str = "rest"): + client = RuleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_rule( + rule.DeleteRuleRequest(), + name="name_value", + ) + + +def test_verify_rule_text_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = RuleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.verify_rule_text in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.verify_rule_text] = ( + mock_rpc + ) + + request = {} + client.verify_rule_text(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.verify_rule_text(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_verify_rule_text_rest_required_fields(request_type=rule.VerifyRuleTextRequest): + transport_class = transports.RuleServiceRestTransport + + request_init = {} + request_init["instance"] = "" + request_init["rule_text"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).verify_rule_text._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["instance"] = "instance_value" + jsonified_request["ruleText"] = "rule_text_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).verify_rule_text._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "instance" in jsonified_request + assert jsonified_request["instance"] == "instance_value" + assert "ruleText" in jsonified_request + assert jsonified_request["ruleText"] == "rule_text_value" client = RuleServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -7129,7 +7650,7 @@ def test_delete_rule_rest_required_fields(request_type=rule.DeleteRuleRequest): request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = None + return_value = rule.VerifyRuleTextResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -7141,36 +7662,48 @@ def test_delete_rule_rest_required_fields(request_type=rule.DeleteRuleRequest): pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "delete", + "method": "post", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - json_return_value = "" + + # Convert return value to protobuf type + return_value = rule.VerifyRuleTextResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_rule(request) + response = client.verify_rule_text(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert sorted(expected_params) == sorted(actual_params) -def test_delete_rule_rest_unset_required_fields(): +def test_verify_rule_text_rest_unset_required_fields(): transport = transports.RuleServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.delete_rule._get_unset_required_fields({}) - assert set(unset_fields) == (set(("force",)) & set(("name",))) + unset_fields = transport.verify_rule_text._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "instance", + "ruleText", + ) + ) + ) -def test_delete_rule_rest_flattened(): +def test_verify_rule_text_rest_flattened(): client = RuleServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -7179,41 +7712,44 @@ def test_delete_rule_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = None + return_value = rule.VerifyRuleTextResponse() # get arguments that satisfy an http rule for this method sample_request = { - "name": "projects/sample1/locations/sample2/instances/sample3/rules/sample4" + "instance": "projects/sample1/locations/sample2/instances/sample3" } # get truthy value for each flattened field mock_args = dict( - name="name_value", + instance="instance_value", + rule_text="rule_text_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - json_return_value = "" + # Convert return value to protobuf type + return_value = rule.VerifyRuleTextResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_rule(**mock_args) + client.verify_rule_text(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/locations/*/instances/*/rules/*}" + "%s/v1/{instance=projects/*/locations/*/instances/*}:verifyRuleText" % client.transport._host, args[1], ) -def test_delete_rule_rest_flattened_error(transport: str = "rest"): +def test_verify_rule_text_rest_flattened_error(transport: str = "rest"): client = RuleServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -7222,9 +7758,10 @@ def test_delete_rule_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.delete_rule( - rule.DeleteRuleRequest(), - name="name_value", + client.verify_rule_text( + rule.VerifyRuleTextRequest(), + instance="instance_value", + rule_text="rule_text_value", ) @@ -8970,6 +9507,26 @@ def test_delete_rule_empty_call_grpc(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_verify_rule_text_empty_call_grpc(): + client = RuleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.verify_rule_text), "__call__") as call: + call.return_value = rule.VerifyRuleTextResponse() + client.verify_rule_text(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = rule.VerifyRuleTextRequest() + assert args[0] == request_msg + + # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. def test_list_rule_revisions_empty_call_grpc(): @@ -9291,6 +9848,32 @@ async def test_delete_rule_empty_call_grpc_asyncio(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_verify_rule_text_empty_call_grpc_asyncio(): + client = RuleServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.verify_rule_text), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + rule.VerifyRuleTextResponse( + success=True, + ) + ) + await client.verify_rule_text(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = rule.VerifyRuleTextRequest() + assert args[0] == request_msg + + # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @pytest.mark.asyncio @@ -10390,6 +10973,134 @@ def test_delete_rule_rest_interceptors(null_interceptor): pre.assert_called_once() +def test_verify_rule_text_rest_bad_request(request_type=rule.VerifyRuleTextRequest): + client = RuleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"instance": "projects/sample1/locations/sample2/instances/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.verify_rule_text(request) + + +@pytest.mark.parametrize( + "request_type", + [ + rule.VerifyRuleTextRequest, + dict, + ], +) +def test_verify_rule_text_rest_call_success(request_type): + client = RuleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"instance": "projects/sample1/locations/sample2/instances/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = rule.VerifyRuleTextResponse( + success=True, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = rule.VerifyRuleTextResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.verify_rule_text(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, rule.VerifyRuleTextResponse) + assert response.success is True + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_verify_rule_text_rest_interceptors(null_interceptor): + transport = transports.RuleServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.RuleServiceRestInterceptor(), + ) + client = RuleServiceClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.RuleServiceRestInterceptor, "post_verify_rule_text" + ) as post, + mock.patch.object( + transports.RuleServiceRestInterceptor, "post_verify_rule_text_with_metadata" + ) as post_with_metadata, + mock.patch.object( + transports.RuleServiceRestInterceptor, "pre_verify_rule_text" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = rule.VerifyRuleTextRequest.pb(rule.VerifyRuleTextRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = rule.VerifyRuleTextResponse.to_json( + rule.VerifyRuleTextResponse() + ) + req.return_value.content = return_value + + request = rule.VerifyRuleTextRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = rule.VerifyRuleTextResponse() + post_with_metadata.return_value = rule.VerifyRuleTextResponse(), metadata + + client.verify_rule_text( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + def test_list_rule_revisions_rest_bad_request( request_type=rule.ListRuleRevisionsRequest, ): @@ -11878,6 +12589,25 @@ def test_delete_rule_empty_call_rest(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_verify_rule_text_empty_call_rest(): + client = RuleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.verify_rule_text), "__call__") as call: + client.verify_rule_text(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = rule.VerifyRuleTextRequest() + assert args[0] == request_msg + + # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. def test_list_rule_revisions_empty_call_rest(): @@ -12074,6 +12804,7 @@ def test_rule_service_base_transport(): "list_rules", "update_rule", "delete_rule", + "verify_rule_text", "list_rule_revisions", "create_retrohunt", "get_retrohunt", @@ -12126,7 +12857,11 @@ def test_rule_service_base_transport_with_credentials_file(): load_creds.assert_called_once_with( "credentials.json", scopes=None, - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + default_scopes=( + "https://www.googleapis.com/auth/chronicle", + "https://www.googleapis.com/auth/chronicle.readonly", + "https://www.googleapis.com/auth/cloud-platform", + ), quota_project_id="octopus", ) @@ -12152,7 +12887,11 @@ def test_rule_service_auth_adc(): RuleServiceClient() adc.assert_called_once_with( scopes=None, - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + default_scopes=( + "https://www.googleapis.com/auth/chronicle", + "https://www.googleapis.com/auth/chronicle.readonly", + "https://www.googleapis.com/auth/cloud-platform", + ), quota_project_id=None, ) @@ -12172,7 +12911,11 @@ def test_rule_service_transport_auth_adc(transport_class): 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",), + default_scopes=( + "https://www.googleapis.com/auth/chronicle", + "https://www.googleapis.com/auth/chronicle.readonly", + "https://www.googleapis.com/auth/cloud-platform", + ), quota_project_id="octopus", ) @@ -12225,7 +12968,11 @@ def test_rule_service_transport_create_channel(transport_class, grpc_helpers): credentials=creds, credentials_file=None, quota_project_id="octopus", - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + default_scopes=( + "https://www.googleapis.com/auth/chronicle", + "https://www.googleapis.com/auth/chronicle.readonly", + "https://www.googleapis.com/auth/cloud-platform", + ), scopes=["1", "2"], default_host="chronicle.googleapis.com", ssl_credentials=None, @@ -12367,6 +13114,9 @@ def test_rule_service_client_transport_session_collision(transport_name): session1 = client1.transport.delete_rule._session session2 = client2.transport.delete_rule._session assert session1 != session2 + session1 = client1.transport.verify_rule_text._session + session2 = client2.transport.verify_rule_text._session + assert session1 != session2 session1 = client1.transport.list_rule_revisions._session session2 = client2.transport.list_rule_revisions._session assert session1 != session2 @@ -12574,11 +13324,37 @@ def test_parse_data_access_scope_path(): assert expected == actual -def test_reference_list_path(): +def test_instance_path(): project = "winkle" location = "nautilus" instance = "scallop" - reference_list = "abalone" + expected = "projects/{project}/locations/{location}/instances/{instance}".format( + project=project, + location=location, + instance=instance, + ) + actual = RuleServiceClient.instance_path(project, location, instance) + assert expected == actual + + +def test_parse_instance_path(): + expected = { + "project": "abalone", + "location": "squid", + "instance": "clam", + } + path = RuleServiceClient.instance_path(**expected) + + # Check that the path construction is reversible. + actual = RuleServiceClient.parse_instance_path(path) + assert expected == actual + + +def test_reference_list_path(): + project = "whelk" + location = "octopus" + instance = "oyster" + reference_list = "nudibranch" expected = "projects/{project}/locations/{location}/instances/{instance}/referenceLists/{reference_list}".format( project=project, location=location, @@ -12593,10 +13369,10 @@ def test_reference_list_path(): def test_parse_reference_list_path(): expected = { - "project": "squid", - "location": "clam", - "instance": "whelk", - "reference_list": "octopus", + "project": "cuttlefish", + "location": "mussel", + "instance": "winkle", + "reference_list": "nautilus", } path = RuleServiceClient.reference_list_path(**expected) @@ -12606,11 +13382,11 @@ def test_parse_reference_list_path(): def test_retrohunt_path(): - project = "oyster" - location = "nudibranch" - instance = "cuttlefish" - rule = "mussel" - retrohunt = "winkle" + project = "scallop" + location = "abalone" + instance = "squid" + rule = "clam" + retrohunt = "whelk" expected = "projects/{project}/locations/{location}/instances/{instance}/rules/{rule}/retrohunts/{retrohunt}".format( project=project, location=location, @@ -12626,11 +13402,11 @@ def test_retrohunt_path(): def test_parse_retrohunt_path(): expected = { - "project": "nautilus", - "location": "scallop", - "instance": "abalone", - "rule": "squid", - "retrohunt": "clam", + "project": "octopus", + "location": "oyster", + "instance": "nudibranch", + "rule": "cuttlefish", + "retrohunt": "mussel", } path = RuleServiceClient.retrohunt_path(**expected) @@ -12640,10 +13416,10 @@ def test_parse_retrohunt_path(): def test_rule_path(): - project = "whelk" - location = "octopus" - instance = "oyster" - rule = "nudibranch" + project = "winkle" + location = "nautilus" + instance = "scallop" + rule = "abalone" expected = "projects/{project}/locations/{location}/instances/{instance}/rules/{rule}".format( project=project, location=location, @@ -12656,10 +13432,10 @@ def test_rule_path(): def test_parse_rule_path(): expected = { - "project": "cuttlefish", - "location": "mussel", - "instance": "winkle", - "rule": "nautilus", + "project": "squid", + "location": "clam", + "instance": "whelk", + "rule": "octopus", } path = RuleServiceClient.rule_path(**expected) @@ -12669,10 +13445,10 @@ def test_parse_rule_path(): def test_rule_deployment_path(): - project = "scallop" - location = "abalone" - instance = "squid" - rule = "clam" + project = "oyster" + location = "nudibranch" + instance = "cuttlefish" + rule = "mussel" expected = "projects/{project}/locations/{location}/instances/{instance}/rules/{rule}/deployment".format( project=project, location=location, @@ -12685,10 +13461,10 @@ def test_rule_deployment_path(): def test_parse_rule_deployment_path(): expected = { - "project": "whelk", - "location": "octopus", - "instance": "oyster", - "rule": "nudibranch", + "project": "winkle", + "location": "nautilus", + "instance": "scallop", + "rule": "abalone", } path = RuleServiceClient.rule_deployment_path(**expected) @@ -12698,7 +13474,7 @@ def test_parse_rule_deployment_path(): def test_common_billing_account_path(): - billing_account = "cuttlefish" + billing_account = "squid" expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -12708,7 +13484,7 @@ def test_common_billing_account_path(): def test_parse_common_billing_account_path(): expected = { - "billing_account": "mussel", + "billing_account": "clam", } path = RuleServiceClient.common_billing_account_path(**expected) @@ -12718,7 +13494,7 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): - folder = "winkle" + folder = "whelk" expected = "folders/{folder}".format( folder=folder, ) @@ -12728,7 +13504,7 @@ def test_common_folder_path(): def test_parse_common_folder_path(): expected = { - "folder": "nautilus", + "folder": "octopus", } path = RuleServiceClient.common_folder_path(**expected) @@ -12738,7 +13514,7 @@ def test_parse_common_folder_path(): def test_common_organization_path(): - organization = "scallop" + organization = "oyster" expected = "organizations/{organization}".format( organization=organization, ) @@ -12748,7 +13524,7 @@ def test_common_organization_path(): def test_parse_common_organization_path(): expected = { - "organization": "abalone", + "organization": "nudibranch", } path = RuleServiceClient.common_organization_path(**expected) @@ -12758,7 +13534,7 @@ def test_parse_common_organization_path(): def test_common_project_path(): - project = "squid" + project = "cuttlefish" expected = "projects/{project}".format( project=project, ) @@ -12768,7 +13544,7 @@ def test_common_project_path(): def test_parse_common_project_path(): expected = { - "project": "clam", + "project": "mussel", } path = RuleServiceClient.common_project_path(**expected) @@ -12778,8 +13554,8 @@ def test_parse_common_project_path(): def test_common_location_path(): - project = "whelk" - location = "octopus" + project = "winkle" + location = "nautilus" expected = "projects/{project}/locations/{location}".format( project=project, location=location, @@ -12790,8 +13566,8 @@ def test_common_location_path(): def test_parse_common_location_path(): expected = { - "project": "oyster", - "location": "nudibranch", + "project": "scallop", + "location": "abalone", } path = RuleServiceClient.common_location_path(**expected) diff --git a/packages/google-cloud-dataform/google/cloud/dataform/__init__.py b/packages/google-cloud-dataform/google/cloud/dataform/__init__.py index a4034c27c505..289cec26608a 100644 --- a/packages/google-cloud-dataform/google/cloud/dataform/__init__.py +++ b/packages/google-cloud-dataform/google/cloud/dataform/__init__.py @@ -48,12 +48,19 @@ CreateWorkspaceRequest, DataEncryptionState, DeleteFolderRequest, + DeleteFolderTreeMetadata, + DeleteFolderTreeRequest, DeleteReleaseConfigRequest, + DeleteRepositoryLongRunningMetadata, + DeleteRepositoryLongRunningRequest, + DeleteRepositoryLongRunningResponse, DeleteRepositoryRequest, DeleteTeamFolderRequest, + DeleteTeamFolderTreeRequest, DeleteWorkflowConfigRequest, DeleteWorkflowInvocationRequest, DeleteWorkspaceRequest, + DirectoryContentsView, DirectoryEntry, DirectorySearchResult, FetchFileDiffRequest, @@ -67,6 +74,7 @@ FetchRepositoryHistoryRequest, FetchRepositoryHistoryResponse, FileSearchResult, + FilesystemEntryMetadata, Folder, GetCompilationResultRequest, GetConfigRequest, @@ -184,9 +192,15 @@ "CreateWorkspaceRequest", "DataEncryptionState", "DeleteFolderRequest", + "DeleteFolderTreeMetadata", + "DeleteFolderTreeRequest", "DeleteReleaseConfigRequest", + "DeleteRepositoryLongRunningMetadata", + "DeleteRepositoryLongRunningRequest", + "DeleteRepositoryLongRunningResponse", "DeleteRepositoryRequest", "DeleteTeamFolderRequest", + "DeleteTeamFolderTreeRequest", "DeleteWorkflowConfigRequest", "DeleteWorkflowInvocationRequest", "DeleteWorkspaceRequest", @@ -203,6 +217,7 @@ "FetchRepositoryHistoryRequest", "FetchRepositoryHistoryResponse", "FileSearchResult", + "FilesystemEntryMetadata", "Folder", "GetCompilationResultRequest", "GetConfigRequest", @@ -290,4 +305,5 @@ "Workspace", "WriteFileRequest", "WriteFileResponse", + "DirectoryContentsView", ) diff --git a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/__init__.py b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/__init__.py index 097c288f8006..8df970ab4a9b 100644 --- a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/__init__.py +++ b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/__init__.py @@ -50,12 +50,19 @@ CreateWorkspaceRequest, DataEncryptionState, DeleteFolderRequest, + DeleteFolderTreeMetadata, + DeleteFolderTreeRequest, DeleteReleaseConfigRequest, + DeleteRepositoryLongRunningMetadata, + DeleteRepositoryLongRunningRequest, + DeleteRepositoryLongRunningResponse, DeleteRepositoryRequest, DeleteTeamFolderRequest, + DeleteTeamFolderTreeRequest, DeleteWorkflowConfigRequest, DeleteWorkflowInvocationRequest, DeleteWorkspaceRequest, + DirectoryContentsView, DirectoryEntry, DirectorySearchResult, FetchFileDiffRequest, @@ -69,6 +76,7 @@ FetchRepositoryHistoryRequest, FetchRepositoryHistoryResponse, FileSearchResult, + FilesystemEntryMetadata, Folder, GetCompilationResultRequest, GetConfigRequest, @@ -269,12 +277,19 @@ def _get_version(dependency_name): "DataEncryptionState", "DataformClient", "DeleteFolderRequest", + "DeleteFolderTreeMetadata", + "DeleteFolderTreeRequest", "DeleteReleaseConfigRequest", + "DeleteRepositoryLongRunningMetadata", + "DeleteRepositoryLongRunningRequest", + "DeleteRepositoryLongRunningResponse", "DeleteRepositoryRequest", "DeleteTeamFolderRequest", + "DeleteTeamFolderTreeRequest", "DeleteWorkflowConfigRequest", "DeleteWorkflowInvocationRequest", "DeleteWorkspaceRequest", + "DirectoryContentsView", "DirectoryEntry", "DirectorySearchResult", "FetchFileDiffRequest", @@ -288,6 +303,7 @@ def _get_version(dependency_name): "FetchRepositoryHistoryRequest", "FetchRepositoryHistoryResponse", "FileSearchResult", + "FilesystemEntryMetadata", "Folder", "GetCompilationResultRequest", "GetConfigRequest", diff --git a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/gapic_metadata.json b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/gapic_metadata.json index 96580a73896c..d8e4662ff81a 100644 --- a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/gapic_metadata.json +++ b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/gapic_metadata.json @@ -75,6 +75,11 @@ "delete_folder" ] }, + "DeleteFolderTree": { + "methods": [ + "delete_folder_tree" + ] + }, "DeleteReleaseConfig": { "methods": [ "delete_release_config" @@ -85,11 +90,21 @@ "delete_repository" ] }, + "DeleteRepositoryLongRunning": { + "methods": [ + "delete_repository_long_running" + ] + }, "DeleteTeamFolder": { "methods": [ "delete_team_folder" ] }, + "DeleteTeamFolderTree": { + "methods": [ + "delete_team_folder_tree" + ] + }, "DeleteWorkflowConfig": { "methods": [ "delete_workflow_config" @@ -435,6 +450,11 @@ "delete_folder" ] }, + "DeleteFolderTree": { + "methods": [ + "delete_folder_tree" + ] + }, "DeleteReleaseConfig": { "methods": [ "delete_release_config" @@ -445,11 +465,21 @@ "delete_repository" ] }, + "DeleteRepositoryLongRunning": { + "methods": [ + "delete_repository_long_running" + ] + }, "DeleteTeamFolder": { "methods": [ "delete_team_folder" ] }, + "DeleteTeamFolderTree": { + "methods": [ + "delete_team_folder_tree" + ] + }, "DeleteWorkflowConfig": { "methods": [ "delete_workflow_config" @@ -795,6 +825,11 @@ "delete_folder" ] }, + "DeleteFolderTree": { + "methods": [ + "delete_folder_tree" + ] + }, "DeleteReleaseConfig": { "methods": [ "delete_release_config" @@ -805,11 +840,21 @@ "delete_repository" ] }, + "DeleteRepositoryLongRunning": { + "methods": [ + "delete_repository_long_running" + ] + }, "DeleteTeamFolder": { "methods": [ "delete_team_folder" ] }, + "DeleteTeamFolderTree": { + "methods": [ + "delete_team_folder_tree" + ] + }, "DeleteWorkflowConfig": { "methods": [ "delete_workflow_config" diff --git a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/async_client.py b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/async_client.py index 190f9add2f42..9c8047638a99 100644 --- a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/async_client.py +++ b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/async_client.py @@ -104,6 +104,10 @@ class DataformAsyncClient: ) folder_path = staticmethod(DataformClient.folder_path) parse_folder_path = staticmethod(DataformClient.parse_folder_path) + git_repository_link_path = staticmethod(DataformClient.git_repository_link_path) + parse_git_repository_link_path = staticmethod( + DataformClient.parse_git_repository_link_path + ) notebook_runtime_template_path = staticmethod( DataformClient.notebook_runtime_template_path ) @@ -803,6 +807,157 @@ async def sample_delete_team_folder(): metadata=metadata, ) + async def delete_team_folder_tree( + self, + request: Optional[Union[dataform.DeleteTeamFolderTreeRequest, dict]] = None, + *, + name: Optional[str] = None, + force: Optional[bool] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""Deletes a TeamFolder with its contents (Folders, + Repositories, Workspaces, ReleaseConfigs, and + WorkflowConfigs). + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dataform_v1beta1 + + async def sample_delete_team_folder_tree(): + # Create a client + client = dataform_v1beta1.DataformAsyncClient() + + # Initialize request argument(s) + request = dataform_v1beta1.DeleteTeamFolderTreeRequest( + name="name_value", + ) + + # Make the request + operation = await client.delete_team_folder_tree(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.dataform_v1beta1.types.DeleteTeamFolderTreeRequest, dict]]): + The request object. ``DeleteTeamFolderTree`` request message. + name (:class:`str`): + Required. The TeamFolder's name. Format: + projects/{project}/locations/{location}/teamFolders/{team_folder} + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + force (:class:`bool`): + Optional. If ``false`` (default): The operation will + fail if any Repository within the folder hierarchy has + associated Release Configs or Workflow Configs. + + If ``true``: The operation will attempt to delete + everything, including any Release Configs and Workflow + Configs linked to Repositories within the folder + hierarchy. This permanently removes schedules and + resources. + + This corresponds to the ``force`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name, force] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, dataform.DeleteTeamFolderTreeRequest): + request = dataform.DeleteTeamFolderTreeRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + if force is not None: + request.force = force + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.delete_team_folder_tree + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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, + empty_pb2.Empty, + metadata_type=dataform.DeleteFolderTreeMetadata, + ) + + # Done; return the response. + return response + async def query_team_folder_contents( self, request: Optional[Union[dataform.QueryTeamFolderContentsRequest, dict]] = None, @@ -845,8 +1000,9 @@ async def sample_query_team_folder_contents(): request (Optional[Union[google.cloud.dataform_v1beta1.types.QueryTeamFolderContentsRequest, dict]]): The request object. ``QueryTeamFolderContents`` request message. team_folder (:class:`str`): - Required. Name of the team_folder whose contents to - list. Format: ``projects/*/locations/*/teamFolders/*``. + Required. Resource name of the TeamFolder to list + contents for. Format: + ``projects/*/locations/*/teamFolders/*``. This corresponds to the ``team_folder`` field on the ``request`` instance; if ``request`` is provided, this @@ -1487,6 +1643,158 @@ async def sample_delete_folder(): metadata=metadata, ) + async def delete_folder_tree( + self, + request: Optional[Union[dataform.DeleteFolderTreeRequest, dict]] = None, + *, + name: Optional[str] = None, + force: Optional[bool] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""Deletes a Folder with its contents (Folders, + Repositories, Workspaces, ReleaseConfigs, and + WorkflowConfigs). + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dataform_v1beta1 + + async def sample_delete_folder_tree(): + # Create a client + client = dataform_v1beta1.DataformAsyncClient() + + # Initialize request argument(s) + request = dataform_v1beta1.DeleteFolderTreeRequest( + name="name_value", + ) + + # Make the request + operation = await client.delete_folder_tree(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.dataform_v1beta1.types.DeleteFolderTreeRequest, dict]]): + The request object. ``DeleteFolderTree`` request message. + name (:class:`str`): + Required. The Folder's name. + Format: + projects/{project}/locations/{location}/folders/{folder} + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + force (:class:`bool`): + Optional. If ``false`` (default): The operation will + fail if any Repository within the folder hierarchy has + associated Release Configs or Workflow Configs. + + If ``true``: The operation will attempt to delete + everything, including any Release Configs and Workflow + Configs linked to Repositories within the folder + hierarchy. This permanently removes schedules and + resources. + + This corresponds to the ``force`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name, force] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, dataform.DeleteFolderTreeRequest): + request = dataform.DeleteFolderTreeRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + if force is not None: + request.force = force + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.delete_folder_tree + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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, + empty_pb2.Empty, + metadata_type=dataform.DeleteFolderTreeMetadata, + ) + + # Done; return the response. + return response + async def query_folder_contents( self, request: Optional[Union[dataform.QueryFolderContentsRequest, dict]] = None, @@ -1529,8 +1837,8 @@ async def sample_query_folder_contents(): request (Optional[Union[google.cloud.dataform_v1beta1.types.QueryFolderContentsRequest, dict]]): The request object. ``QueryFolderContents`` request message. folder (:class:`str`): - Required. Name of the folder whose contents to list. - Format: projects/*/locations/*/folders/\* + Required. Resource name of the Folder to list contents + for. Format: projects/*/locations/*/folders/\* This corresponds to the ``folder`` field on the ``request`` instance; if ``request`` is provided, this @@ -1656,8 +1964,8 @@ async def sample_query_user_root_contents(): request (Optional[Union[google.cloud.dataform_v1beta1.types.QueryUserRootContentsRequest, dict]]): The request object. ``QueryUserRootContents`` request message. location (:class:`str`): - Required. Location of the user root folder whose - contents to list. Format: projects/*/locations/* + Required. Location of the user root folder to list + contents for. Format: projects/*/locations/* This corresponds to the ``location`` field on the ``request`` instance; if ``request`` is provided, this @@ -2469,6 +2777,149 @@ async def sample_delete_repository(): metadata=metadata, ) + async def delete_repository_long_running( + self, + request: Optional[ + Union[dataform.DeleteRepositoryLongRunningRequest, dict] + ] = None, + *, + name: Optional[str] = None, + force: Optional[bool] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""Deletes a single repository asynchronously. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dataform_v1beta1 + + async def sample_delete_repository_long_running(): + # Create a client + client = dataform_v1beta1.DataformAsyncClient() + + # Initialize request argument(s) + request = dataform_v1beta1.DeleteRepositoryLongRunningRequest( + name="name_value", + ) + + # Make the request + operation = await client.delete_repository_long_running(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.dataform_v1beta1.types.DeleteRepositoryLongRunningRequest, dict]]): + The request object. ``DeleteRepositoryLongRunning`` request message. + name (:class:`str`): + Required. The repository's name. + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + force (:class:`bool`): + Optional. If set to true, child resources of this + repository (compilation results and workflow + invocations) will also be deleted. Otherwise, the + request will only succeed if the repository has no child + resources. + + **Note:** *This flag doesn't support deletion of + workspaces, release configs or workflow configs. If any + of such resources exists in the repository, the request + will fail.* + + This corresponds to the ``force`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + 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.dataform_v1beta1.types.DeleteRepositoryLongRunningResponse` + DeleteRepositoryLongRunning response message. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name, force] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, dataform.DeleteRepositoryLongRunningRequest): + request = dataform.DeleteRepositoryLongRunningRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + if force is not None: + request.force = force + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.delete_repository_long_running + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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, + dataform.DeleteRepositoryLongRunningResponse, + metadata_type=dataform.DeleteRepositoryLongRunningMetadata, + ) + + # Done; return the response. + return response + async def move_repository( self, request: Optional[Union[dataform.MoveRepositoryRequest, dict]] = None, diff --git a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/client.py b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/client.py index 191507732997..3338406c3ca9 100644 --- a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/client.py +++ b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/client.py @@ -358,6 +358,30 @@ def parse_folder_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def git_repository_link_path( + project: str, + location: str, + connection: str, + git_repository_link: str, + ) -> str: + """Returns a fully-qualified git_repository_link string.""" + return "projects/{project}/locations/{location}/connections/{connection}/gitRepositoryLinks/{git_repository_link}".format( + project=project, + location=location, + connection=connection, + git_repository_link=git_repository_link, + ) + + @staticmethod + def parse_git_repository_link_path(path: str) -> Dict[str, str]: + """Parses a git_repository_link path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/connections/(?P.+?)/gitRepositoryLinks/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def notebook_runtime_template_path( project: str, @@ -1477,6 +1501,154 @@ def sample_delete_team_folder(): metadata=metadata, ) + def delete_team_folder_tree( + self, + request: Optional[Union[dataform.DeleteTeamFolderTreeRequest, dict]] = None, + *, + name: Optional[str] = None, + force: Optional[bool] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Deletes a TeamFolder with its contents (Folders, + Repositories, Workspaces, ReleaseConfigs, and + WorkflowConfigs). + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dataform_v1beta1 + + def sample_delete_team_folder_tree(): + # Create a client + client = dataform_v1beta1.DataformClient() + + # Initialize request argument(s) + request = dataform_v1beta1.DeleteTeamFolderTreeRequest( + name="name_value", + ) + + # Make the request + operation = client.delete_team_folder_tree(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.dataform_v1beta1.types.DeleteTeamFolderTreeRequest, dict]): + The request object. ``DeleteTeamFolderTree`` request message. + name (str): + Required. The TeamFolder's name. Format: + projects/{project}/locations/{location}/teamFolders/{team_folder} + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + force (bool): + Optional. If ``false`` (default): The operation will + fail if any Repository within the folder hierarchy has + associated Release Configs or Workflow Configs. + + If ``true``: The operation will attempt to delete + everything, including any Release Configs and Workflow + Configs linked to Repositories within the folder + hierarchy. This permanently removes schedules and + resources. + + This corresponds to the ``force`` 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name, force] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, dataform.DeleteTeamFolderTreeRequest): + request = dataform.DeleteTeamFolderTreeRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + if force is not None: + request.force = force + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.delete_team_folder_tree] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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, + empty_pb2.Empty, + metadata_type=dataform.DeleteFolderTreeMetadata, + ) + + # Done; return the response. + return response + def query_team_folder_contents( self, request: Optional[Union[dataform.QueryTeamFolderContentsRequest, dict]] = None, @@ -1519,8 +1691,9 @@ def sample_query_team_folder_contents(): request (Union[google.cloud.dataform_v1beta1.types.QueryTeamFolderContentsRequest, dict]): The request object. ``QueryTeamFolderContents`` request message. team_folder (str): - Required. Name of the team_folder whose contents to - list. Format: ``projects/*/locations/*/teamFolders/*``. + Required. Resource name of the TeamFolder to list + contents for. Format: + ``projects/*/locations/*/teamFolders/*``. This corresponds to the ``team_folder`` field on the ``request`` instance; if ``request`` is provided, this @@ -2146,6 +2319,155 @@ def sample_delete_folder(): metadata=metadata, ) + def delete_folder_tree( + self, + request: Optional[Union[dataform.DeleteFolderTreeRequest, dict]] = None, + *, + name: Optional[str] = None, + force: Optional[bool] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Deletes a Folder with its contents (Folders, + Repositories, Workspaces, ReleaseConfigs, and + WorkflowConfigs). + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dataform_v1beta1 + + def sample_delete_folder_tree(): + # Create a client + client = dataform_v1beta1.DataformClient() + + # Initialize request argument(s) + request = dataform_v1beta1.DeleteFolderTreeRequest( + name="name_value", + ) + + # Make the request + operation = client.delete_folder_tree(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.dataform_v1beta1.types.DeleteFolderTreeRequest, dict]): + The request object. ``DeleteFolderTree`` request message. + name (str): + Required. The Folder's name. + Format: + projects/{project}/locations/{location}/folders/{folder} + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + force (bool): + Optional. If ``false`` (default): The operation will + fail if any Repository within the folder hierarchy has + associated Release Configs or Workflow Configs. + + If ``true``: The operation will attempt to delete + everything, including any Release Configs and Workflow + Configs linked to Repositories within the folder + hierarchy. This permanently removes schedules and + resources. + + This corresponds to the ``force`` 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name, force] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, dataform.DeleteFolderTreeRequest): + request = dataform.DeleteFolderTreeRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + if force is not None: + request.force = force + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.delete_folder_tree] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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, + empty_pb2.Empty, + metadata_type=dataform.DeleteFolderTreeMetadata, + ) + + # Done; return the response. + return response + def query_folder_contents( self, request: Optional[Union[dataform.QueryFolderContentsRequest, dict]] = None, @@ -2188,8 +2510,8 @@ def sample_query_folder_contents(): request (Union[google.cloud.dataform_v1beta1.types.QueryFolderContentsRequest, dict]): The request object. ``QueryFolderContents`` request message. folder (str): - Required. Name of the folder whose contents to list. - Format: projects/*/locations/*/folders/\* + Required. Resource name of the Folder to list contents + for. Format: projects/*/locations/*/folders/\* This corresponds to the ``folder`` field on the ``request`` instance; if ``request`` is provided, this @@ -2312,8 +2634,8 @@ def sample_query_user_root_contents(): request (Union[google.cloud.dataform_v1beta1.types.QueryUserRootContentsRequest, dict]): The request object. ``QueryUserRootContents`` request message. location (str): - Required. Location of the user root folder whose - contents to list. Format: projects/*/locations/* + Required. Location of the user root folder to list + contents for. Format: projects/*/locations/* This corresponds to the ``location`` field on the ``request`` instance; if ``request`` is provided, this @@ -3104,6 +3426,148 @@ def sample_delete_repository(): metadata=metadata, ) + def delete_repository_long_running( + self, + request: Optional[ + Union[dataform.DeleteRepositoryLongRunningRequest, dict] + ] = None, + *, + name: Optional[str] = None, + force: Optional[bool] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Deletes a single repository asynchronously. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dataform_v1beta1 + + def sample_delete_repository_long_running(): + # Create a client + client = dataform_v1beta1.DataformClient() + + # Initialize request argument(s) + request = dataform_v1beta1.DeleteRepositoryLongRunningRequest( + name="name_value", + ) + + # Make the request + operation = client.delete_repository_long_running(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.dataform_v1beta1.types.DeleteRepositoryLongRunningRequest, dict]): + The request object. ``DeleteRepositoryLongRunning`` request message. + name (str): + Required. The repository's name. + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + force (bool): + Optional. If set to true, child resources of this + repository (compilation results and workflow + invocations) will also be deleted. Otherwise, the + request will only succeed if the repository has no child + resources. + + **Note:** *This flag doesn't support deletion of + workspaces, release configs or workflow configs. If any + of such resources exists in the repository, the request + will fail.* + + This corresponds to the ``force`` 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.dataform_v1beta1.types.DeleteRepositoryLongRunningResponse` + DeleteRepositoryLongRunning response message. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name, force] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, dataform.DeleteRepositoryLongRunningRequest): + request = dataform.DeleteRepositoryLongRunningRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + if force is not None: + request.force = force + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.delete_repository_long_running + ] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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, + dataform.DeleteRepositoryLongRunningResponse, + metadata_type=dataform.DeleteRepositoryLongRunningMetadata, + ) + + # Done; return the response. + return response + def move_repository( self, request: Optional[Union[dataform.MoveRepositoryRequest, dict]] = None, diff --git a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/transports/base.py b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/transports/base.py index 800ce86e7956..544e265d0177 100644 --- a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/transports/base.py +++ b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/transports/base.py @@ -174,6 +174,11 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.delete_team_folder_tree: gapic_v1.method.wrap_method( + self.delete_team_folder_tree, + default_timeout=None, + client_info=client_info, + ), self.query_team_folder_contents: gapic_v1.method.wrap_method( self.query_team_folder_contents, default_timeout=None, @@ -204,6 +209,11 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.delete_folder_tree: gapic_v1.method.wrap_method( + self.delete_folder_tree, + default_timeout=None, + client_info=client_info, + ), self.query_folder_contents: gapic_v1.method.wrap_method( self.query_folder_contents, default_timeout=None, @@ -244,6 +254,11 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.delete_repository_long_running: gapic_v1.method.wrap_method( + self.delete_repository_long_running, + default_timeout=None, + client_info=client_info, + ), self.move_repository: gapic_v1.method.wrap_method( self.move_repository, default_timeout=None, @@ -591,6 +606,15 @@ def delete_team_folder( ]: raise NotImplementedError() + @property + def delete_team_folder_tree( + self, + ) -> Callable[ + [dataform.DeleteTeamFolderTreeRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + @property def query_team_folder_contents( self, @@ -650,6 +674,15 @@ def delete_folder( ]: raise NotImplementedError() + @property + def delete_folder_tree( + self, + ) -> Callable[ + [dataform.DeleteFolderTreeRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + @property def query_folder_contents( self, @@ -731,6 +764,15 @@ def delete_repository( ]: raise NotImplementedError() + @property + def delete_repository_long_running( + self, + ) -> Callable[ + [dataform.DeleteRepositoryLongRunningRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + @property def move_repository( self, diff --git a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/transports/grpc.py b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/transports/grpc.py index a1d93fa743bc..bcc1e3f40018 100644 --- a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/transports/grpc.py +++ b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/transports/grpc.py @@ -457,6 +457,34 @@ def delete_team_folder( ) return self._stubs["delete_team_folder"] + @property + def delete_team_folder_tree( + self, + ) -> Callable[[dataform.DeleteTeamFolderTreeRequest], operations_pb2.Operation]: + r"""Return a callable for the delete team folder tree method over gRPC. + + Deletes a TeamFolder with its contents (Folders, + Repositories, Workspaces, ReleaseConfigs, and + WorkflowConfigs). + + Returns: + Callable[[~.DeleteTeamFolderTreeRequest], + ~.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 "delete_team_folder_tree" not in self._stubs: + self._stubs["delete_team_folder_tree"] = self._logged_channel.unary_unary( + "/google.cloud.dataform.v1beta1.Dataform/DeleteTeamFolderTree", + request_serializer=dataform.DeleteTeamFolderTreeRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["delete_team_folder_tree"] + @property def query_team_folder_contents( self, @@ -619,6 +647,34 @@ def delete_folder( ) return self._stubs["delete_folder"] + @property + def delete_folder_tree( + self, + ) -> Callable[[dataform.DeleteFolderTreeRequest], operations_pb2.Operation]: + r"""Return a callable for the delete folder tree method over gRPC. + + Deletes a Folder with its contents (Folders, + Repositories, Workspaces, ReleaseConfigs, and + WorkflowConfigs). + + Returns: + Callable[[~.DeleteFolderTreeRequest], + ~.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 "delete_folder_tree" not in self._stubs: + self._stubs["delete_folder_tree"] = self._logged_channel.unary_unary( + "/google.cloud.dataform.v1beta1.Dataform/DeleteFolderTree", + request_serializer=dataform.DeleteFolderTreeRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["delete_folder_tree"] + @property def query_folder_contents( self, @@ -848,6 +904,36 @@ def delete_repository( ) return self._stubs["delete_repository"] + @property + def delete_repository_long_running( + self, + ) -> Callable[ + [dataform.DeleteRepositoryLongRunningRequest], operations_pb2.Operation + ]: + r"""Return a callable for the delete repository long running method over gRPC. + + Deletes a single repository asynchronously. + + Returns: + Callable[[~.DeleteRepositoryLongRunningRequest], + ~.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 "delete_repository_long_running" not in self._stubs: + self._stubs["delete_repository_long_running"] = ( + self._logged_channel.unary_unary( + "/google.cloud.dataform.v1beta1.Dataform/DeleteRepositoryLongRunning", + request_serializer=dataform.DeleteRepositoryLongRunningRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + ) + return self._stubs["delete_repository_long_running"] + @property def move_repository( self, diff --git a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/transports/grpc_asyncio.py b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/transports/grpc_asyncio.py index 6878f533767a..31a0d441aa01 100644 --- a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/transports/grpc_asyncio.py +++ b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/transports/grpc_asyncio.py @@ -465,6 +465,36 @@ def delete_team_folder( ) return self._stubs["delete_team_folder"] + @property + def delete_team_folder_tree( + self, + ) -> Callable[ + [dataform.DeleteTeamFolderTreeRequest], Awaitable[operations_pb2.Operation] + ]: + r"""Return a callable for the delete team folder tree method over gRPC. + + Deletes a TeamFolder with its contents (Folders, + Repositories, Workspaces, ReleaseConfigs, and + WorkflowConfigs). + + Returns: + Callable[[~.DeleteTeamFolderTreeRequest], + 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 "delete_team_folder_tree" not in self._stubs: + self._stubs["delete_team_folder_tree"] = self._logged_channel.unary_unary( + "/google.cloud.dataform.v1beta1.Dataform/DeleteTeamFolderTree", + request_serializer=dataform.DeleteTeamFolderTreeRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["delete_team_folder_tree"] + @property def query_team_folder_contents( self, @@ -630,6 +660,36 @@ def delete_folder( ) return self._stubs["delete_folder"] + @property + def delete_folder_tree( + self, + ) -> Callable[ + [dataform.DeleteFolderTreeRequest], Awaitable[operations_pb2.Operation] + ]: + r"""Return a callable for the delete folder tree method over gRPC. + + Deletes a Folder with its contents (Folders, + Repositories, Workspaces, ReleaseConfigs, and + WorkflowConfigs). + + Returns: + Callable[[~.DeleteFolderTreeRequest], + 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 "delete_folder_tree" not in self._stubs: + self._stubs["delete_folder_tree"] = self._logged_channel.unary_unary( + "/google.cloud.dataform.v1beta1.Dataform/DeleteFolderTree", + request_serializer=dataform.DeleteFolderTreeRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["delete_folder_tree"] + @property def query_folder_contents( self, @@ -861,6 +921,37 @@ def delete_repository( ) return self._stubs["delete_repository"] + @property + def delete_repository_long_running( + self, + ) -> Callable[ + [dataform.DeleteRepositoryLongRunningRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the delete repository long running method over gRPC. + + Deletes a single repository asynchronously. + + Returns: + Callable[[~.DeleteRepositoryLongRunningRequest], + 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 "delete_repository_long_running" not in self._stubs: + self._stubs["delete_repository_long_running"] = ( + self._logged_channel.unary_unary( + "/google.cloud.dataform.v1beta1.Dataform/DeleteRepositoryLongRunning", + request_serializer=dataform.DeleteRepositoryLongRunningRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + ) + return self._stubs["delete_repository_long_running"] + @property def move_repository( self, @@ -2432,6 +2523,11 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.delete_team_folder_tree: self._wrap_method( + self.delete_team_folder_tree, + default_timeout=None, + client_info=client_info, + ), self.query_team_folder_contents: self._wrap_method( self.query_team_folder_contents, default_timeout=None, @@ -2462,6 +2558,11 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.delete_folder_tree: self._wrap_method( + self.delete_folder_tree, + default_timeout=None, + client_info=client_info, + ), self.query_folder_contents: self._wrap_method( self.query_folder_contents, default_timeout=None, @@ -2502,6 +2603,11 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.delete_repository_long_running: self._wrap_method( + self.delete_repository_long_running, + default_timeout=None, + client_info=client_info, + ), self.move_repository: self._wrap_method( self.move_repository, default_timeout=None, diff --git a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/transports/rest.py b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/transports/rest.py index d6053a59f80e..a46a32fc09aa 100644 --- a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/transports/rest.py +++ b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/transports/rest.py @@ -181,6 +181,14 @@ def pre_delete_folder(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata + def pre_delete_folder_tree(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_delete_folder_tree(self, response): + logging.log(f"Received response: {response}") + return response + def pre_delete_release_config(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -189,10 +197,26 @@ def pre_delete_repository(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata + def pre_delete_repository_long_running(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_delete_repository_long_running(self, response): + logging.log(f"Received response: {response}") + return response + def pre_delete_team_folder(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata + def pre_delete_team_folder_tree(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_delete_team_folder_tree(self, response): + logging.log(f"Received response: {response}") + return response + def pre_delete_workflow_config(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -1223,6 +1247,54 @@ def pre_delete_folder( """ return request, metadata + def pre_delete_folder_tree( + self, + request: dataform.DeleteFolderTreeRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + dataform.DeleteFolderTreeRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for delete_folder_tree + + Override in a subclass to manipulate the request or metadata + before they are sent to the Dataform server. + """ + return request, metadata + + def post_delete_folder_tree( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for delete_folder_tree + + DEPRECATED. Please use the `post_delete_folder_tree_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the Dataform server but before + it is returned to user code. This `post_delete_folder_tree` interceptor runs + before the `post_delete_folder_tree_with_metadata` interceptor. + """ + return response + + def post_delete_folder_tree_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_folder_tree + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_delete_folder_tree_with_metadata` + interceptor in new development instead of the `post_delete_folder_tree` interceptor. + When both interceptors are used, this `post_delete_folder_tree_with_metadata` interceptor runs after the + `post_delete_folder_tree` interceptor. The (possibly modified) response returned by + `post_delete_folder_tree` will be passed to + `post_delete_folder_tree_with_metadata`. + """ + return response, metadata + def pre_delete_release_config( self, request: dataform.DeleteReleaseConfigRequest, @@ -1251,6 +1323,55 @@ def pre_delete_repository( """ return request, metadata + def pre_delete_repository_long_running( + self, + request: dataform.DeleteRepositoryLongRunningRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + dataform.DeleteRepositoryLongRunningRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for delete_repository_long_running + + Override in a subclass to manipulate the request or metadata + before they are sent to the Dataform server. + """ + return request, metadata + + def post_delete_repository_long_running( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for delete_repository_long_running + + DEPRECATED. Please use the `post_delete_repository_long_running_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the Dataform server but before + it is returned to user code. This `post_delete_repository_long_running` interceptor runs + before the `post_delete_repository_long_running_with_metadata` interceptor. + """ + return response + + def post_delete_repository_long_running_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_repository_long_running + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_delete_repository_long_running_with_metadata` + interceptor in new development instead of the `post_delete_repository_long_running` interceptor. + When both interceptors are used, this `post_delete_repository_long_running_with_metadata` interceptor runs after the + `post_delete_repository_long_running` interceptor. The (possibly modified) response returned by + `post_delete_repository_long_running` will be passed to + `post_delete_repository_long_running_with_metadata`. + """ + return response, metadata + def pre_delete_team_folder( self, request: dataform.DeleteTeamFolderRequest, @@ -1265,6 +1386,54 @@ def pre_delete_team_folder( """ return request, metadata + def pre_delete_team_folder_tree( + self, + request: dataform.DeleteTeamFolderTreeRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + dataform.DeleteTeamFolderTreeRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for delete_team_folder_tree + + Override in a subclass to manipulate the request or metadata + before they are sent to the Dataform server. + """ + return request, metadata + + def post_delete_team_folder_tree( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for delete_team_folder_tree + + DEPRECATED. Please use the `post_delete_team_folder_tree_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the Dataform server but before + it is returned to user code. This `post_delete_team_folder_tree` interceptor runs + before the `post_delete_team_folder_tree_with_metadata` interceptor. + """ + return response + + def post_delete_team_folder_tree_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_team_folder_tree + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_delete_team_folder_tree_with_metadata` + interceptor in new development instead of the `post_delete_team_folder_tree` interceptor. + When both interceptors are used, this `post_delete_team_folder_tree_with_metadata` interceptor runs after the + `post_delete_team_folder_tree` interceptor. The (possibly modified) response returned by + `post_delete_team_folder_tree` will be passed to + `post_delete_team_folder_tree_with_metadata`. + """ + return response, metadata + def pre_delete_workflow_config( self, request: dataform.DeleteWorkflowConfigRequest, @@ -5903,24 +6072,431 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.dataform_v1beta1.DataformClient.CreateWorkspace", + f"Sending request for google.cloud.dataform_v1beta1.DataformClient.CreateWorkspace", + extra={ + "serviceName": "google.cloud.dataform.v1beta1.Dataform", + "rpcName": "CreateWorkspace", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = DataformRestTransport._CreateWorkspace._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = dataform.Workspace() + pb_resp = dataform.Workspace.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_create_workspace(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_workspace_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = dataform.Workspace.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.dataform_v1beta1.DataformClient.create_workspace", + extra={ + "serviceName": "google.cloud.dataform.v1beta1.Dataform", + "rpcName": "CreateWorkspace", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _DeleteFolder(_BaseDataformRestTransport._BaseDeleteFolder, DataformRestStub): + def __hash__(self): + return hash("DataformRestTransport.DeleteFolder") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: dataform.DeleteFolderRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + r"""Call the delete folder method over HTTP. + + Args: + request (~.dataform.DeleteFolderRequest): + The request object. ``DeleteFolder`` request message. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + + http_options = ( + _BaseDataformRestTransport._BaseDeleteFolder._get_http_options() + ) + + request, metadata = self._interceptor.pre_delete_folder(request, metadata) + transcoded_request = ( + _BaseDataformRestTransport._BaseDeleteFolder._get_transcoded_request( + http_options, request + ) + ) + + # Jsonify the query params + query_params = ( + _BaseDataformRestTransport._BaseDeleteFolder._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.dataform_v1beta1.DataformClient.DeleteFolder", + extra={ + "serviceName": "google.cloud.dataform.v1beta1.Dataform", + "rpcName": "DeleteFolder", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = DataformRestTransport._DeleteFolder._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + class _DeleteFolderTree( + _BaseDataformRestTransport._BaseDeleteFolderTree, DataformRestStub + ): + def __hash__(self): + return hash("DataformRestTransport.DeleteFolderTree") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: dataform.DeleteFolderTreeRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the delete folder tree method over HTTP. + + Args: + request (~.dataform.DeleteFolderTreeRequest): + The request object. ``DeleteFolderTree`` request message. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = ( + _BaseDataformRestTransport._BaseDeleteFolderTree._get_http_options() + ) + + request, metadata = self._interceptor.pre_delete_folder_tree( + request, metadata + ) + transcoded_request = _BaseDataformRestTransport._BaseDeleteFolderTree._get_transcoded_request( + http_options, request + ) + + body = ( + _BaseDataformRestTransport._BaseDeleteFolderTree._get_request_body_json( + transcoded_request + ) + ) + + # Jsonify the query params + query_params = ( + _BaseDataformRestTransport._BaseDeleteFolderTree._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.dataform_v1beta1.DataformClient.DeleteFolderTree", + extra={ + "serviceName": "google.cloud.dataform.v1beta1.Dataform", + "rpcName": "DeleteFolderTree", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = DataformRestTransport._DeleteFolderTree._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_delete_folder_tree(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_folder_tree_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.dataform_v1beta1.DataformClient.delete_folder_tree", + extra={ + "serviceName": "google.cloud.dataform.v1beta1.Dataform", + "rpcName": "DeleteFolderTree", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _DeleteReleaseConfig( + _BaseDataformRestTransport._BaseDeleteReleaseConfig, DataformRestStub + ): + def __hash__(self): + return hash("DataformRestTransport.DeleteReleaseConfig") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: dataform.DeleteReleaseConfigRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + r"""Call the delete release config method over HTTP. + + Args: + request (~.dataform.DeleteReleaseConfigRequest): + The request object. ``DeleteReleaseConfig`` request message. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + + http_options = ( + _BaseDataformRestTransport._BaseDeleteReleaseConfig._get_http_options() + ) + + request, metadata = self._interceptor.pre_delete_release_config( + request, metadata + ) + transcoded_request = _BaseDataformRestTransport._BaseDeleteReleaseConfig._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseDataformRestTransport._BaseDeleteReleaseConfig._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.dataform_v1beta1.DataformClient.DeleteReleaseConfig", extra={ "serviceName": "google.cloud.dataform.v1beta1.Dataform", - "rpcName": "CreateWorkspace", + "rpcName": "DeleteReleaseConfig", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = DataformRestTransport._CreateWorkspace._get_response( + response = DataformRestTransport._DeleteReleaseConfig._get_response( self._host, metadata, query_params, self._session, timeout, transcoded_request, - body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -5928,43 +6504,11 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) - # Return the response - resp = dataform.Workspace() - pb_resp = dataform.Workspace.pb(resp) - - json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - - resp = self._interceptor.post_create_workspace(resp) - response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_create_workspace_with_metadata( - resp, response_metadata - ) - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - logging.DEBUG - ): # pragma: NO COVER - try: - response_payload = dataform.Workspace.to_json(response) - except: - response_payload = None - http_response = { - "payload": response_payload, - "headers": dict(response.headers), - "status": response.status_code, - } - _LOGGER.debug( - "Received response for google.cloud.dataform_v1beta1.DataformClient.create_workspace", - extra={ - "serviceName": "google.cloud.dataform.v1beta1.Dataform", - "rpcName": "CreateWorkspace", - "metadata": http_response["headers"], - "httpResponse": http_response, - }, - ) - return resp - - class _DeleteFolder(_BaseDataformRestTransport._BaseDeleteFolder, DataformRestStub): + class _DeleteRepository( + _BaseDataformRestTransport._BaseDeleteRepository, DataformRestStub + ): def __hash__(self): - return hash("DataformRestTransport.DeleteFolder") + return hash("DataformRestTransport.DeleteRepository") @staticmethod def _get_response( @@ -5990,17 +6534,17 @@ def _get_response( def __call__( self, - request: dataform.DeleteFolderRequest, + request: dataform.DeleteRepositoryRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ): - r"""Call the delete folder method over HTTP. + r"""Call the delete repository method over HTTP. Args: - request (~.dataform.DeleteFolderRequest): - The request object. ``DeleteFolder`` request message. + request (~.dataform.DeleteRepositoryRequest): + The request object. ``DeleteRepository`` request message. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -6011,19 +6555,19 @@ def __call__( """ http_options = ( - _BaseDataformRestTransport._BaseDeleteFolder._get_http_options() + _BaseDataformRestTransport._BaseDeleteRepository._get_http_options() ) - request, metadata = self._interceptor.pre_delete_folder(request, metadata) - transcoded_request = ( - _BaseDataformRestTransport._BaseDeleteFolder._get_transcoded_request( - http_options, request - ) + request, metadata = self._interceptor.pre_delete_repository( + request, metadata + ) + transcoded_request = _BaseDataformRestTransport._BaseDeleteRepository._get_transcoded_request( + http_options, request ) # Jsonify the query params query_params = ( - _BaseDataformRestTransport._BaseDeleteFolder._get_query_params_json( + _BaseDataformRestTransport._BaseDeleteRepository._get_query_params_json( transcoded_request ) ) @@ -6046,17 +6590,17 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.dataform_v1beta1.DataformClient.DeleteFolder", + f"Sending request for google.cloud.dataform_v1beta1.DataformClient.DeleteRepository", extra={ "serviceName": "google.cloud.dataform.v1beta1.Dataform", - "rpcName": "DeleteFolder", + "rpcName": "DeleteRepository", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = DataformRestTransport._DeleteFolder._get_response( + response = DataformRestTransport._DeleteRepository._get_response( self._host, metadata, query_params, @@ -6070,11 +6614,11 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) - class _DeleteReleaseConfig( - _BaseDataformRestTransport._BaseDeleteReleaseConfig, DataformRestStub + class _DeleteRepositoryLongRunning( + _BaseDataformRestTransport._BaseDeleteRepositoryLongRunning, DataformRestStub ): def __hash__(self): - return hash("DataformRestTransport.DeleteReleaseConfig") + return hash("DataformRestTransport.DeleteRepositoryLongRunning") @staticmethod def _get_response( @@ -6095,44 +6639,55 @@ def _get_response( timeout=timeout, headers=headers, params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, ) return response def __call__( self, - request: dataform.DeleteReleaseConfigRequest, + request: dataform.DeleteRepositoryLongRunningRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ): - r"""Call the delete release config method over HTTP. + ) -> operations_pb2.Operation: + r"""Call the delete repository long + running method over HTTP. + + Args: + request (~.dataform.DeleteRepositoryLongRunningRequest): + The request object. ``DeleteRepositoryLongRunning`` request message. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. - Args: - request (~.dataform.DeleteReleaseConfigRequest): - The request object. ``DeleteReleaseConfig`` request message. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. """ - http_options = ( - _BaseDataformRestTransport._BaseDeleteReleaseConfig._get_http_options() - ) + http_options = _BaseDataformRestTransport._BaseDeleteRepositoryLongRunning._get_http_options() - request, metadata = self._interceptor.pre_delete_release_config( + request, metadata = self._interceptor.pre_delete_repository_long_running( request, metadata ) - transcoded_request = _BaseDataformRestTransport._BaseDeleteReleaseConfig._get_transcoded_request( + transcoded_request = _BaseDataformRestTransport._BaseDeleteRepositoryLongRunning._get_transcoded_request( http_options, request ) + body = _BaseDataformRestTransport._BaseDeleteRepositoryLongRunning._get_request_body_json( + transcoded_request + ) + # Jsonify the query params - query_params = _BaseDataformRestTransport._BaseDeleteReleaseConfig._get_query_params_json( + query_params = _BaseDataformRestTransport._BaseDeleteRepositoryLongRunning._get_query_params_json( transcoded_request ) @@ -6154,23 +6709,24 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.dataform_v1beta1.DataformClient.DeleteReleaseConfig", + f"Sending request for google.cloud.dataform_v1beta1.DataformClient.DeleteRepositoryLongRunning", extra={ "serviceName": "google.cloud.dataform.v1beta1.Dataform", - "rpcName": "DeleteReleaseConfig", + "rpcName": "DeleteRepositoryLongRunning", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = DataformRestTransport._DeleteReleaseConfig._get_response( + response = DataformRestTransport._DeleteRepositoryLongRunning._get_response( self._host, metadata, query_params, self._session, timeout, transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -6178,11 +6734,45 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) - class _DeleteRepository( - _BaseDataformRestTransport._BaseDeleteRepository, DataformRestStub + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_delete_repository_long_running(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = ( + self._interceptor.post_delete_repository_long_running_with_metadata( + resp, response_metadata + ) + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.dataform_v1beta1.DataformClient.delete_repository_long_running", + extra={ + "serviceName": "google.cloud.dataform.v1beta1.Dataform", + "rpcName": "DeleteRepositoryLongRunning", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _DeleteTeamFolder( + _BaseDataformRestTransport._BaseDeleteTeamFolder, DataformRestStub ): def __hash__(self): - return hash("DataformRestTransport.DeleteRepository") + return hash("DataformRestTransport.DeleteTeamFolder") @staticmethod def _get_response( @@ -6208,17 +6798,17 @@ def _get_response( def __call__( self, - request: dataform.DeleteRepositoryRequest, + request: dataform.DeleteTeamFolderRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ): - r"""Call the delete repository method over HTTP. + r"""Call the delete team folder method over HTTP. Args: - request (~.dataform.DeleteRepositoryRequest): - The request object. ``DeleteRepository`` request message. + request (~.dataform.DeleteTeamFolderRequest): + The request object. ``DeleteTeamFolder`` request message. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -6229,19 +6819,19 @@ def __call__( """ http_options = ( - _BaseDataformRestTransport._BaseDeleteRepository._get_http_options() + _BaseDataformRestTransport._BaseDeleteTeamFolder._get_http_options() ) - request, metadata = self._interceptor.pre_delete_repository( + request, metadata = self._interceptor.pre_delete_team_folder( request, metadata ) - transcoded_request = _BaseDataformRestTransport._BaseDeleteRepository._get_transcoded_request( + transcoded_request = _BaseDataformRestTransport._BaseDeleteTeamFolder._get_transcoded_request( http_options, request ) # Jsonify the query params query_params = ( - _BaseDataformRestTransport._BaseDeleteRepository._get_query_params_json( + _BaseDataformRestTransport._BaseDeleteTeamFolder._get_query_params_json( transcoded_request ) ) @@ -6264,17 +6854,17 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.dataform_v1beta1.DataformClient.DeleteRepository", + f"Sending request for google.cloud.dataform_v1beta1.DataformClient.DeleteTeamFolder", extra={ "serviceName": "google.cloud.dataform.v1beta1.Dataform", - "rpcName": "DeleteRepository", + "rpcName": "DeleteTeamFolder", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = DataformRestTransport._DeleteRepository._get_response( + response = DataformRestTransport._DeleteTeamFolder._get_response( self._host, metadata, query_params, @@ -6288,11 +6878,11 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) - class _DeleteTeamFolder( - _BaseDataformRestTransport._BaseDeleteTeamFolder, DataformRestStub + class _DeleteTeamFolderTree( + _BaseDataformRestTransport._BaseDeleteTeamFolderTree, DataformRestStub ): def __hash__(self): - return hash("DataformRestTransport.DeleteTeamFolder") + return hash("DataformRestTransport.DeleteTeamFolderTree") @staticmethod def _get_response( @@ -6313,22 +6903,23 @@ def _get_response( timeout=timeout, headers=headers, params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, ) return response def __call__( self, - request: dataform.DeleteTeamFolderRequest, + request: dataform.DeleteTeamFolderTreeRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ): - r"""Call the delete team folder method over HTTP. + ) -> operations_pb2.Operation: + r"""Call the delete team folder tree method over HTTP. Args: - request (~.dataform.DeleteTeamFolderRequest): - The request object. ``DeleteTeamFolder`` request message. + request (~.dataform.DeleteTeamFolderTreeRequest): + The request object. ``DeleteTeamFolderTree`` request message. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -6336,24 +6927,33 @@ def __call__( sent along with the request as metadata. Normally, each value must be of type `str`, but for metadata keys ending with the suffix `-bin`, the corresponding values must be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + """ http_options = ( - _BaseDataformRestTransport._BaseDeleteTeamFolder._get_http_options() + _BaseDataformRestTransport._BaseDeleteTeamFolderTree._get_http_options() ) - request, metadata = self._interceptor.pre_delete_team_folder( + request, metadata = self._interceptor.pre_delete_team_folder_tree( request, metadata ) - transcoded_request = _BaseDataformRestTransport._BaseDeleteTeamFolder._get_transcoded_request( + transcoded_request = _BaseDataformRestTransport._BaseDeleteTeamFolderTree._get_transcoded_request( http_options, request ) + body = _BaseDataformRestTransport._BaseDeleteTeamFolderTree._get_request_body_json( + transcoded_request + ) + # Jsonify the query params - query_params = ( - _BaseDataformRestTransport._BaseDeleteTeamFolder._get_query_params_json( - transcoded_request - ) + query_params = _BaseDataformRestTransport._BaseDeleteTeamFolderTree._get_query_params_json( + transcoded_request ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( @@ -6374,23 +6974,24 @@ def __call__( "headers": dict(metadata), } _LOGGER.debug( - f"Sending request for google.cloud.dataform_v1beta1.DataformClient.DeleteTeamFolder", + f"Sending request for google.cloud.dataform_v1beta1.DataformClient.DeleteTeamFolderTree", extra={ "serviceName": "google.cloud.dataform.v1beta1.Dataform", - "rpcName": "DeleteTeamFolder", + "rpcName": "DeleteTeamFolderTree", "httpRequest": http_request, "metadata": http_request["headers"], }, ) # Send the request - response = DataformRestTransport._DeleteTeamFolder._get_response( + response = DataformRestTransport._DeleteTeamFolderTree._get_response( self._host, metadata, query_params, self._session, timeout, transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -6398,6 +6999,38 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_delete_team_folder_tree(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_team_folder_tree_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.dataform_v1beta1.DataformClient.delete_team_folder_tree", + extra={ + "serviceName": "google.cloud.dataform.v1beta1.Dataform", + "rpcName": "DeleteTeamFolderTree", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + class _DeleteWorkflowConfig( _BaseDataformRestTransport._BaseDeleteWorkflowConfig, DataformRestStub ): @@ -14841,6 +15474,14 @@ def delete_folder( # In C++ this would require a dynamic_cast return self._DeleteFolder(self._session, self._host, self._interceptor) # type: ignore + @property + def delete_folder_tree( + self, + ) -> Callable[[dataform.DeleteFolderTreeRequest], operations_pb2.Operation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteFolderTree(self._session, self._host, self._interceptor) # type: ignore + @property def delete_release_config( self, @@ -14857,6 +15498,18 @@ def delete_repository( # In C++ this would require a dynamic_cast return self._DeleteRepository(self._session, self._host, self._interceptor) # type: ignore + @property + def delete_repository_long_running( + self, + ) -> Callable[ + [dataform.DeleteRepositoryLongRunningRequest], operations_pb2.Operation + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteRepositoryLongRunning( + self._session, self._host, self._interceptor + ) # type: ignore + @property def delete_team_folder( self, @@ -14865,6 +15518,14 @@ def delete_team_folder( # In C++ this would require a dynamic_cast return self._DeleteTeamFolder(self._session, self._host, self._interceptor) # type: ignore + @property + def delete_team_folder_tree( + self, + ) -> Callable[[dataform.DeleteTeamFolderTreeRequest], operations_pb2.Operation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteTeamFolderTree(self._session, self._host, self._interceptor) # type: ignore + @property def delete_workflow_config( self, diff --git a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/transports/rest_base.py b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/transports/rest_base.py index 9687f003a08d..7cd3c2ac7513 100644 --- a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/transports/rest_base.py +++ b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/transports/rest_base.py @@ -825,6 +825,63 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params + class _BaseDeleteFolderTree: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1beta1/{name=projects/*/locations/*/folders/*}:deleteTree", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = dataform.DeleteFolderTreeRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDataformRestTransport._BaseDeleteFolderTree._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + class _BaseDeleteReleaseConfig: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -919,6 +976,63 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params + class _BaseDeleteRepositoryLongRunning: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1beta1/{name=projects/*/locations/*/repositories/*}:deleteLongRunning", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = dataform.DeleteRepositoryLongRunningRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDataformRestTransport._BaseDeleteRepositoryLongRunning._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + class _BaseDeleteTeamFolder: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -966,6 +1080,63 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params + class _BaseDeleteTeamFolderTree: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1beta1/{name=projects/*/locations/*/teamFolders/*}:deleteTree", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = dataform.DeleteTeamFolderTreeRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDataformRestTransport._BaseDeleteTeamFolderTree._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + class _BaseDeleteWorkflowConfig: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") diff --git a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/types/__init__.py b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/types/__init__.py index b77bf48171cc..033c4e8d2b46 100644 --- a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/types/__init__.py +++ b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/types/__init__.py @@ -39,12 +39,19 @@ CreateWorkspaceRequest, DataEncryptionState, DeleteFolderRequest, + DeleteFolderTreeMetadata, + DeleteFolderTreeRequest, DeleteReleaseConfigRequest, + DeleteRepositoryLongRunningMetadata, + DeleteRepositoryLongRunningRequest, + DeleteRepositoryLongRunningResponse, DeleteRepositoryRequest, DeleteTeamFolderRequest, + DeleteTeamFolderTreeRequest, DeleteWorkflowConfigRequest, DeleteWorkflowInvocationRequest, DeleteWorkspaceRequest, + DirectoryContentsView, DirectoryEntry, DirectorySearchResult, FetchFileDiffRequest, @@ -58,6 +65,7 @@ FetchRepositoryHistoryRequest, FetchRepositoryHistoryResponse, FileSearchResult, + FilesystemEntryMetadata, Folder, GetCompilationResultRequest, GetConfigRequest, @@ -173,9 +181,15 @@ "CreateWorkspaceRequest", "DataEncryptionState", "DeleteFolderRequest", + "DeleteFolderTreeMetadata", + "DeleteFolderTreeRequest", "DeleteReleaseConfigRequest", + "DeleteRepositoryLongRunningMetadata", + "DeleteRepositoryLongRunningRequest", + "DeleteRepositoryLongRunningResponse", "DeleteRepositoryRequest", "DeleteTeamFolderRequest", + "DeleteTeamFolderTreeRequest", "DeleteWorkflowConfigRequest", "DeleteWorkflowInvocationRequest", "DeleteWorkspaceRequest", @@ -192,6 +206,7 @@ "FetchRepositoryHistoryRequest", "FetchRepositoryHistoryResponse", "FileSearchResult", + "FilesystemEntryMetadata", "Folder", "GetCompilationResultRequest", "GetConfigRequest", @@ -279,4 +294,5 @@ "Workspace", "WriteFileRequest", "WriteFileResponse", + "DirectoryContentsView", ) diff --git a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/types/dataform.py b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/types/dataform.py index 9b017c47f7cc..3d80c9fac09a 100644 --- a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/types/dataform.py +++ b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/types/dataform.py @@ -26,6 +26,7 @@ __protobuf__ = proto.module( package="google.cloud.dataform.v1beta1", manifest={ + "DirectoryContentsView", "DataEncryptionState", "Repository", "PrivateResourceMetadata", @@ -36,6 +37,8 @@ "CreateRepositoryRequest", "UpdateRepositoryRequest", "DeleteRepositoryRequest", + "DeleteRepositoryLongRunningResponse", + "DeleteRepositoryLongRunningRequest", "CommitRepositoryChangesRequest", "CommitRepositoryChangesResponse", "ReadRepositoryFileRequest", @@ -74,6 +77,7 @@ "QueryDirectoryContentsRequest", "QueryDirectoryContentsResponse", "DirectoryEntry", + "FilesystemEntryMetadata", "SearchFilesRequest", "SearchFilesResponse", "SearchResult", @@ -142,6 +146,9 @@ "GetFolderRequest", "UpdateFolderRequest", "DeleteFolderRequest", + "DeleteFolderTreeRequest", + "DeleteTeamFolderTreeRequest", + "DeleteFolderTreeMetadata", "QueryFolderContentsRequest", "QueryFolderContentsResponse", "QueryUserRootContentsRequest", @@ -157,10 +164,33 @@ "SearchTeamFoldersResponse", "MoveFolderMetadata", "MoveRepositoryMetadata", + "DeleteRepositoryLongRunningMetadata", }, ) +class DirectoryContentsView(proto.Enum): + r"""Represents the level of detail to return for directory + contents. + + Values: + DIRECTORY_CONTENTS_VIEW_UNSPECIFIED (0): + The default unset value. Defaults to + DIRECTORY_CONTENTS_VIEW_BASIC. + DIRECTORY_CONTENTS_VIEW_BASIC (1): + Includes only the file or directory name. + This is the default behavior. + DIRECTORY_CONTENTS_VIEW_METADATA (2): + Includes all metadata for each file or + directory. Currently not supported by + CMEK-protected workspaces. + """ + + DIRECTORY_CONTENTS_VIEW_UNSPECIFIED = 0 + DIRECTORY_CONTENTS_VIEW_BASIC = 1 + DIRECTORY_CONTENTS_VIEW_METADATA = 2 + + class DataEncryptionState(proto.Message): r"""Describes encryption state of a resource. @@ -259,12 +289,18 @@ class Repository(proto.Message): class GitRemoteSettings(proto.Message): r"""Controls Git remote configuration for a repository. + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + Attributes: url (str): Required. The Git remote's URL. default_branch (str): - Required. The Git remote's default branch - name. + Optional. The Git remote's default branch name. If not set, + ``main`` will be used. + effective_default_branch (str): + Output only. The Git remote's effective default branch name. + This is the default branch name of the Git remote if it is + set, otherwise it is ``main``. authentication_token_secret_version (str): Optional. The name of the Secret Manager secret version to use as an authentication token for Git operations. Must be @@ -272,6 +308,12 @@ class GitRemoteSettings(proto.Message): ssh_authentication_config (google.cloud.dataform_v1beta1.types.Repository.GitRemoteSettings.SshAuthenticationConfig): Optional. Authentication fields for remote uris using SSH protocol. + git_repository_link (str): + Optional. Resource name for the ``GitRepositoryLink`` used + for machine credentials. Must be in the format + ``projects/*/locations/*/connections/*/gitRepositoryLinks/*`` + + This field is a member of `oneof`_ ``_git_repository_link``. token_status (google.cloud.dataform_v1beta1.types.Repository.GitRemoteSettings.TokenStatus): Output only. Deprecated: The field does not contain any token status information. Instead @@ -332,6 +374,10 @@ class SshAuthenticationConfig(proto.Message): proto.STRING, number=2, ) + effective_default_branch: str = proto.Field( + proto.STRING, + number=9, + ) authentication_token_secret_version: str = proto.Field( proto.STRING, number=3, @@ -341,6 +387,11 @@ class SshAuthenticationConfig(proto.Message): number=5, message="Repository.GitRemoteSettings.SshAuthenticationConfig", ) + git_repository_link: str = proto.Field( + proto.STRING, + number=7, + optional=True, + ) token_status: "Repository.GitRemoteSettings.TokenStatus" = proto.Field( proto.ENUM, number=4, @@ -674,6 +725,37 @@ class DeleteRepositoryRequest(proto.Message): ) +class DeleteRepositoryLongRunningResponse(proto.Message): + r"""``DeleteRepositoryLongRunning`` response message.""" + + +class DeleteRepositoryLongRunningRequest(proto.Message): + r"""``DeleteRepositoryLongRunning`` request message. + + Attributes: + name (str): + Required. The repository's name. + force (bool): + Optional. If set to true, child resources of this repository + (compilation results and workflow invocations) will also be + deleted. Otherwise, the request will only succeed if the + repository has no child resources. + + **Note:** *This flag doesn't support deletion of workspaces, + release configs or workflow configs. If any of such + resources exists in the repository, the request will fail.* + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + force: bool = proto.Field( + proto.BOOL, + number=2, + ) + + class CommitRepositoryChangesRequest(proto.Message): r"""``CommitRepositoryChanges`` request message. @@ -1064,12 +1146,16 @@ class TokenStatus(proto.Enum): VALID (3): The token was used successfully to authenticate against the Git remote. + PERMISSION_DENIED (4): + The token is not accessible due to permission + issues. """ TOKEN_STATUS_UNSPECIFIED = 0 NOT_FOUND = 1 INVALID = 2 VALID = 3 + PERMISSION_DENIED = 4 token_status: TokenStatus = proto.Field( proto.ENUM, @@ -1651,6 +1737,12 @@ class QueryDirectoryContentsRequest(proto.Message): ``QueryDirectoryContents``, with the exception of ``page_size``, must match the call that provided the page token. + view (google.cloud.dataform_v1beta1.types.DirectoryContentsView): + Optional. Specifies the metadata to return for each + directory entry. If unspecified, the default is + ``DIRECTORY_CONTENTS_VIEW_BASIC``. Currently the + ``DIRECTORY_CONTENTS_VIEW_METADATA`` view is not supported + by CMEK-protected workspaces. """ workspace: str = proto.Field( @@ -1669,6 +1761,11 @@ class QueryDirectoryContentsRequest(proto.Message): proto.STRING, number=4, ) + view: "DirectoryContentsView" = proto.Field( + proto.ENUM, + number=5, + enum="DirectoryContentsView", + ) class QueryDirectoryContentsResponse(proto.Message): @@ -1710,13 +1807,19 @@ class DirectoryEntry(proto.Message): Attributes: file (str): - A file in the directory. + A file in the directory. The path is returned + including the full folder structure from the + root. This field is a member of `oneof`_ ``entry``. directory (str): - A child directory in the directory. + A child directory in the directory. The path + is returned including the full folder structure + from the root. This field is a member of `oneof`_ ``entry``. + metadata (google.cloud.dataform_v1beta1.types.FilesystemEntryMetadata): + Entry with metadata. """ file: str = proto.Field( @@ -1729,6 +1832,34 @@ class DirectoryEntry(proto.Message): number=2, oneof="entry", ) + metadata: "FilesystemEntryMetadata" = proto.Field( + proto.MESSAGE, + number=3, + message="FilesystemEntryMetadata", + ) + + +class FilesystemEntryMetadata(proto.Message): + r"""Represents metadata for a single entry in a filesystem. + + Attributes: + size_bytes (int): + Output only. Provides the size of the entry + in bytes. For directories, this will be 0. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Represents the time of the last + modification of the entry. + """ + + size_bytes: int = proto.Field( + proto.INT64, + number=1, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) class SearchFilesRequest(proto.Message): @@ -4451,11 +4582,11 @@ class NotebookAction(proto.Message): Output only. The code contents of a Notebook to be run. job_id (str): - Output only. The ID of the Vertex job that - executed the notebook in contents and also the - ID used for the outputs created in Google Cloud - Storage buckets. Only set once the job has - started to run. + Output only. The ID of the Gemini Enterprise + Agent Platform job that executed the notebook in + contents and also the ID used for the outputs + created in Google Cloud Storage buckets. Only + set once the job has started to run. """ contents: str = proto.Field( @@ -4849,9 +4980,8 @@ class Folder(proto.Message): name. This should take the format: projects/{project}/locations/{location}/folders/{folder}, projects/{project}/locations/{location}/teamFolders/{teamFolder}, - or just projects/{project}/locations/{location} - if this is a root Folder. This field can only be - updated through MoveFolder. + or just "" if this is a root Folder. This field + can only be updated through MoveFolder. team_folder_name (str): Output only. The resource name of the TeamFolder that this Folder is associated with. @@ -4928,9 +5058,11 @@ class CreateFolderRequest(proto.Message): folder (google.cloud.dataform_v1beta1.types.Folder): Required. The Folder to create. folder_id (str): - The ID to use for the Folder, which will - become the final component of the Folder's - resource name. + Deprecated: This field is not used. The + resource name is generated automatically. + The ID to use for the Folder, which will become + the final component of the Folder's resource + name. """ parent: str = proto.Field( @@ -5032,13 +5164,140 @@ class DeleteFolderRequest(proto.Message): ) +class DeleteFolderTreeRequest(proto.Message): + r"""``DeleteFolderTree`` request message. + + Attributes: + name (str): + Required. The Folder's name. + Format: + projects/{project}/locations/{location}/folders/{folder} + force (bool): + Optional. If ``false`` (default): The operation will fail if + any Repository within the folder hierarchy has associated + Release Configs or Workflow Configs. + + If ``true``: The operation will attempt to delete + everything, including any Release Configs and Workflow + Configs linked to Repositories within the folder hierarchy. + This permanently removes schedules and resources. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + force: bool = proto.Field( + proto.BOOL, + number=2, + ) + + +class DeleteTeamFolderTreeRequest(proto.Message): + r"""``DeleteTeamFolderTree`` request message. + + Attributes: + name (str): + Required. The TeamFolder's name. Format: + projects/{project}/locations/{location}/teamFolders/{team_folder} + force (bool): + Optional. If ``false`` (default): The operation will fail if + any Repository within the folder hierarchy has associated + Release Configs or Workflow Configs. + + If ``true``: The operation will attempt to delete + everything, including any Release Configs and Workflow + Configs linked to Repositories within the folder hierarchy. + This permanently removes schedules and resources. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + force: bool = proto.Field( + proto.BOOL, + number=2, + ) + + +class DeleteFolderTreeMetadata(proto.Message): + r"""Contains metadata about the progress of the DeleteFolderTree + Long-running operations. + + Attributes: + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time the operation was + created. + end_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time the operation finished + running. + target (str): + Output only. Resource name of the target of the operation. + Format: + projects/{project}/locations/{location}/folders/{folder} or + projects/{project}/locations/{location}/teamFolders/{team_folder} + state (google.cloud.dataform_v1beta1.types.DeleteFolderTreeMetadata.State): + Output only. The state of the operation. + percent_complete (int): + Output only. Percent complete of the operation [0, 100]. + """ + + class State(proto.Enum): + r"""Different states of the DeleteFolderTree operation. + + Values: + STATE_UNSPECIFIED (0): + The state is unspecified. + INITIALIZED (1): + The operation was initialized and recorded by + the server, but not yet started. + IN_PROGRESS (2): + The operation is in progress. + SUCCEEDED (3): + The operation has completed successfully. + FAILED (4): + The operation has failed. + """ + + STATE_UNSPECIFIED = 0 + INITIALIZED = 1 + IN_PROGRESS = 2 + SUCCEEDED = 3 + FAILED = 4 + + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + end_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + target: str = proto.Field( + proto.STRING, + number=3, + ) + state: State = proto.Field( + proto.ENUM, + number=4, + enum=State, + ) + percent_complete: int = proto.Field( + proto.INT32, + number=5, + ) + + class QueryFolderContentsRequest(proto.Message): r"""``QueryFolderContents`` request message. Attributes: folder (str): - Required. Name of the folder whose contents to list. Format: - projects/*/locations/*/folders/\* + Required. Resource name of the Folder to list contents for. + Format: projects/*/locations/*/folders/\* page_size (int): Optional. Maximum number of paths to return. The server may return fewer items than @@ -5159,8 +5418,8 @@ class QueryUserRootContentsRequest(proto.Message): Attributes: location (str): - Required. Location of the user root folder whose contents to - list. Format: projects/*/locations/* + Required. Location of the user root folder to list contents + for. Format: projects/*/locations/* page_size (int): Optional. Maximum number of paths to return. The server may return fewer items than @@ -5351,6 +5610,8 @@ class CreateTeamFolderRequest(proto.Message): team_folder (google.cloud.dataform_v1beta1.types.TeamFolder): Required. The TeamFolder to create. team_folder_id (str): + Deprecated: This field is not used. The + resource name is generated automatically. The ID to use for the TeamFolder, which will become the final component of the TeamFolder's resource name. @@ -5428,8 +5689,8 @@ class QueryTeamFolderContentsRequest(proto.Message): Attributes: team_folder (str): - Required. Name of the team_folder whose contents to list. - Format: ``projects/*/locations/*/teamFolders/*``. + Required. Resource name of the TeamFolder to list contents + for. Format: ``projects/*/locations/*/teamFolders/*``. page_size (int): Optional. Maximum number of paths to return. The server may return fewer items than @@ -5553,10 +5814,10 @@ class SearchTeamFoldersRequest(proto.Message): Required. Location in which to query TeamFolders. Format: ``projects/*/locations/*``. page_size (int): - Optional. Maximum number of TeamFolders to - return. The server may return fewer items than - requested. If unspecified, the server will pick - an appropriate default. + Optional. Maximum number of ``TeamFolders`` to return. The + server may return fewer items than requested. If + unspecified, the server will pick a default of ``page_size`` + = 50. page_token (str): Optional. Page token received from a previous ``SearchTeamFolders`` call. Provide this to retrieve the @@ -5788,4 +6049,85 @@ class State(proto.Enum): ) +class DeleteRepositoryLongRunningMetadata(proto.Message): + r"""Represents metadata about the progress of the + DeleteRepository long-running operation. + + Attributes: + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time the operation was + created. + end_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time the operation finished + running. + target (str): + Output only. Server-defined resource path for + the target of the operation. Format: + projects/{project}/locations/{location}/repositories/{repository} + state (google.cloud.dataform_v1beta1.types.DeleteRepositoryLongRunningMetadata.State): + Output only. The state of the operation. + percent_complete (int): + Output only. Percent complete of the operation [0, 100]. + child_resources_count (int): + Output only. The total number of child + resources (Compilation Results, Workflow + Executions) that will be deleted. + remaining_child_resources_count (int): + Output only. The remaining number of child + resources to be deleted. + """ + + class State(proto.Enum): + r"""Different states of the DeleteRepositoryLongRunning + operation. + + Values: + STATE_UNSPECIFIED (0): + The state is unspecified. + RUNNING (1): + The operation is running. + SUCCEEDED (2): + The operation has completed successfully. + FAILED (3): + The operation has failed. + """ + + STATE_UNSPECIFIED = 0 + RUNNING = 1 + SUCCEEDED = 2 + FAILED = 3 + + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + end_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + target: str = proto.Field( + proto.STRING, + number=3, + ) + state: State = proto.Field( + proto.ENUM, + number=4, + enum=State, + ) + percent_complete: int = proto.Field( + proto.INT32, + number=5, + ) + child_resources_count: int = proto.Field( + proto.INT64, + number=6, + ) + remaining_child_resources_count: int = proto.Field( + proto.INT64, + number=7, + ) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_type_async.py b/packages/google-cloud-dataform/samples/generated_samples/dataform_v1beta1_generated_dataform_delete_folder_tree_async.py similarity index 71% rename from packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_type_async.py rename to packages/google-cloud-dataform/samples/generated_samples/dataform_v1beta1_generated_dataform_delete_folder_tree_async.py index 347daf35a32a..1cbd1220f6e8 100644 --- a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_deployment_type_async.py +++ b/packages/google-cloud-dataform/samples/generated_samples/dataform_v1beta1_generated_dataform_delete_folder_tree_async.py @@ -15,15 +15,15 @@ # # Generated code. DO NOT EDIT! # -# Snippet for GetGoldengateDeploymentType +# Snippet for DeleteFolderTree # NOTE: This snippet has been automatically generated for illustrative purposes only. # It may require modifications to work in your environment. # To install the latest published package dependency, execute the following: -# python3 -m pip install google-cloud-oracledatabase +# python3 -m pip install google-cloud-dataform -# [START oracledatabase_v1_generated_OracleDatabase_GetGoldengateDeploymentType_async] +# [START dataform_v1beta1_generated_Dataform_DeleteFolderTree_async] # This snippet has been automatically generated and should be regarded as a # code template only. # It will require modifications to work: @@ -31,23 +31,27 @@ # - It may require specifying regional endpoints when creating the service # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.cloud import oracledatabase_v1 +from google.cloud import dataform_v1beta1 -async def sample_get_goldengate_deployment_type(): +async def sample_delete_folder_tree(): # Create a client - client = oracledatabase_v1.OracleDatabaseAsyncClient() + client = dataform_v1beta1.DataformAsyncClient() # Initialize request argument(s) - request = oracledatabase_v1.GetGoldengateDeploymentTypeRequest( + request = dataform_v1beta1.DeleteFolderTreeRequest( name="name_value", ) # Make the request - response = await client.get_goldengate_deployment_type(request=request) + operation = await client.delete_folder_tree(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() # Handle the response print(response) -# [END oracledatabase_v1_generated_OracleDatabase_GetGoldengateDeploymentType_async] +# [END dataform_v1beta1_generated_Dataform_DeleteFolderTree_async] diff --git a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_connection_type_sync.py b/packages/google-cloud-dataform/samples/generated_samples/dataform_v1beta1_generated_dataform_delete_folder_tree_sync.py similarity index 72% rename from packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_connection_type_sync.py rename to packages/google-cloud-dataform/samples/generated_samples/dataform_v1beta1_generated_dataform_delete_folder_tree_sync.py index efb71477e349..2de2b44484f8 100644 --- a/packages/google-cloud-oracledatabase/samples/generated_samples/oracledatabase_v1_generated_oracle_database_get_goldengate_connection_type_sync.py +++ b/packages/google-cloud-dataform/samples/generated_samples/dataform_v1beta1_generated_dataform_delete_folder_tree_sync.py @@ -15,15 +15,15 @@ # # Generated code. DO NOT EDIT! # -# Snippet for GetGoldengateConnectionType +# Snippet for DeleteFolderTree # NOTE: This snippet has been automatically generated for illustrative purposes only. # It may require modifications to work in your environment. # To install the latest published package dependency, execute the following: -# python3 -m pip install google-cloud-oracledatabase +# python3 -m pip install google-cloud-dataform -# [START oracledatabase_v1_generated_OracleDatabase_GetGoldengateConnectionType_sync] +# [START dataform_v1beta1_generated_Dataform_DeleteFolderTree_sync] # This snippet has been automatically generated and should be regarded as a # code template only. # It will require modifications to work: @@ -31,23 +31,27 @@ # - It may require specifying regional endpoints when creating the service # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.cloud import oracledatabase_v1 +from google.cloud import dataform_v1beta1 -def sample_get_goldengate_connection_type(): +def sample_delete_folder_tree(): # Create a client - client = oracledatabase_v1.OracleDatabaseClient() + client = dataform_v1beta1.DataformClient() # Initialize request argument(s) - request = oracledatabase_v1.GetGoldengateConnectionTypeRequest( + request = dataform_v1beta1.DeleteFolderTreeRequest( name="name_value", ) # Make the request - response = client.get_goldengate_connection_type(request=request) + operation = client.delete_folder_tree(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() # Handle the response print(response) -# [END oracledatabase_v1_generated_OracleDatabase_GetGoldengateConnectionType_sync] +# [END dataform_v1beta1_generated_Dataform_DeleteFolderTree_sync] diff --git a/packages/google-cloud-dataform/samples/generated_samples/dataform_v1beta1_generated_dataform_delete_repository_long_running_async.py b/packages/google-cloud-dataform/samples/generated_samples/dataform_v1beta1_generated_dataform_delete_repository_long_running_async.py new file mode 100644 index 000000000000..6d48ab175e47 --- /dev/null +++ b/packages/google-cloud-dataform/samples/generated_samples/dataform_v1beta1_generated_dataform_delete_repository_long_running_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteRepositoryLongRunning +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dataform + + +# [START dataform_v1beta1_generated_Dataform_DeleteRepositoryLongRunning_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dataform_v1beta1 + + +async def sample_delete_repository_long_running(): + # Create a client + client = dataform_v1beta1.DataformAsyncClient() + + # Initialize request argument(s) + request = dataform_v1beta1.DeleteRepositoryLongRunningRequest( + name="name_value", + ) + + # Make the request + operation = await client.delete_repository_long_running(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + +# [END dataform_v1beta1_generated_Dataform_DeleteRepositoryLongRunning_async] diff --git a/packages/google-cloud-dataform/samples/generated_samples/dataform_v1beta1_generated_dataform_delete_repository_long_running_sync.py b/packages/google-cloud-dataform/samples/generated_samples/dataform_v1beta1_generated_dataform_delete_repository_long_running_sync.py new file mode 100644 index 000000000000..7741bdf422da --- /dev/null +++ b/packages/google-cloud-dataform/samples/generated_samples/dataform_v1beta1_generated_dataform_delete_repository_long_running_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteRepositoryLongRunning +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dataform + + +# [START dataform_v1beta1_generated_Dataform_DeleteRepositoryLongRunning_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dataform_v1beta1 + + +def sample_delete_repository_long_running(): + # Create a client + client = dataform_v1beta1.DataformClient() + + # Initialize request argument(s) + request = dataform_v1beta1.DeleteRepositoryLongRunningRequest( + name="name_value", + ) + + # Make the request + operation = client.delete_repository_long_running(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + +# [END dataform_v1beta1_generated_Dataform_DeleteRepositoryLongRunning_sync] diff --git a/packages/google-cloud-dataform/samples/generated_samples/dataform_v1beta1_generated_dataform_delete_team_folder_tree_async.py b/packages/google-cloud-dataform/samples/generated_samples/dataform_v1beta1_generated_dataform_delete_team_folder_tree_async.py new file mode 100644 index 000000000000..7cb1c5204bca --- /dev/null +++ b/packages/google-cloud-dataform/samples/generated_samples/dataform_v1beta1_generated_dataform_delete_team_folder_tree_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteTeamFolderTree +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dataform + + +# [START dataform_v1beta1_generated_Dataform_DeleteTeamFolderTree_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dataform_v1beta1 + + +async def sample_delete_team_folder_tree(): + # Create a client + client = dataform_v1beta1.DataformAsyncClient() + + # Initialize request argument(s) + request = dataform_v1beta1.DeleteTeamFolderTreeRequest( + name="name_value", + ) + + # Make the request + operation = await client.delete_team_folder_tree(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + + +# [END dataform_v1beta1_generated_Dataform_DeleteTeamFolderTree_async] diff --git a/packages/google-cloud-dataform/samples/generated_samples/dataform_v1beta1_generated_dataform_delete_team_folder_tree_sync.py b/packages/google-cloud-dataform/samples/generated_samples/dataform_v1beta1_generated_dataform_delete_team_folder_tree_sync.py new file mode 100644 index 000000000000..536f9324d21f --- /dev/null +++ b/packages/google-cloud-dataform/samples/generated_samples/dataform_v1beta1_generated_dataform_delete_team_folder_tree_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteTeamFolderTree +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dataform + + +# [START dataform_v1beta1_generated_Dataform_DeleteTeamFolderTree_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dataform_v1beta1 + + +def sample_delete_team_folder_tree(): + # Create a client + client = dataform_v1beta1.DataformClient() + + # Initialize request argument(s) + request = dataform_v1beta1.DeleteTeamFolderTreeRequest( + name="name_value", + ) + + # Make the request + operation = client.delete_team_folder_tree(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + +# [END dataform_v1beta1_generated_Dataform_DeleteTeamFolderTree_sync] diff --git a/packages/google-cloud-dataform/samples/generated_samples/snippet_metadata_google.cloud.dataform.v1beta1.json b/packages/google-cloud-dataform/samples/generated_samples/snippet_metadata_google.cloud.dataform.v1beta1.json index 1bfc0730dacd..617b15c45dea 100644 --- a/packages/google-cloud-dataform/samples/generated_samples/snippet_metadata_google.cloud.dataform.v1beta1.json +++ b/packages/google-cloud-dataform/samples/generated_samples/snippet_metadata_google.cloud.dataform.v1beta1.json @@ -2007,6 +2007,175 @@ ], "title": "dataform_v1beta1_generated_dataform_create_workspace_sync.py" }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.dataform_v1beta1.DataformAsyncClient", + "shortName": "DataformAsyncClient" + }, + "fullName": "google.cloud.dataform_v1beta1.DataformAsyncClient.delete_folder_tree", + "method": { + "fullName": "google.cloud.dataform.v1beta1.Dataform.DeleteFolderTree", + "service": { + "fullName": "google.cloud.dataform.v1beta1.Dataform", + "shortName": "Dataform" + }, + "shortName": "DeleteFolderTree" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dataform_v1beta1.types.DeleteFolderTreeRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "force", + "type": "bool" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "delete_folder_tree" + }, + "description": "Sample for DeleteFolderTree", + "file": "dataform_v1beta1_generated_dataform_delete_folder_tree_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dataform_v1beta1_generated_Dataform_DeleteFolderTree_async", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dataform_v1beta1_generated_dataform_delete_folder_tree_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.dataform_v1beta1.DataformClient", + "shortName": "DataformClient" + }, + "fullName": "google.cloud.dataform_v1beta1.DataformClient.delete_folder_tree", + "method": { + "fullName": "google.cloud.dataform.v1beta1.Dataform.DeleteFolderTree", + "service": { + "fullName": "google.cloud.dataform.v1beta1.Dataform", + "shortName": "Dataform" + }, + "shortName": "DeleteFolderTree" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dataform_v1beta1.types.DeleteFolderTreeRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "force", + "type": "bool" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "delete_folder_tree" + }, + "description": "Sample for DeleteFolderTree", + "file": "dataform_v1beta1_generated_dataform_delete_folder_tree_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dataform_v1beta1_generated_Dataform_DeleteFolderTree_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dataform_v1beta1_generated_dataform_delete_folder_tree_sync.py" + }, { "canonical": true, "clientMethod": { @@ -2317,6 +2486,175 @@ ], "title": "dataform_v1beta1_generated_dataform_delete_release_config_sync.py" }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.dataform_v1beta1.DataformAsyncClient", + "shortName": "DataformAsyncClient" + }, + "fullName": "google.cloud.dataform_v1beta1.DataformAsyncClient.delete_repository_long_running", + "method": { + "fullName": "google.cloud.dataform.v1beta1.Dataform.DeleteRepositoryLongRunning", + "service": { + "fullName": "google.cloud.dataform.v1beta1.Dataform", + "shortName": "Dataform" + }, + "shortName": "DeleteRepositoryLongRunning" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dataform_v1beta1.types.DeleteRepositoryLongRunningRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "force", + "type": "bool" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "delete_repository_long_running" + }, + "description": "Sample for DeleteRepositoryLongRunning", + "file": "dataform_v1beta1_generated_dataform_delete_repository_long_running_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dataform_v1beta1_generated_Dataform_DeleteRepositoryLongRunning_async", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dataform_v1beta1_generated_dataform_delete_repository_long_running_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.dataform_v1beta1.DataformClient", + "shortName": "DataformClient" + }, + "fullName": "google.cloud.dataform_v1beta1.DataformClient.delete_repository_long_running", + "method": { + "fullName": "google.cloud.dataform.v1beta1.Dataform.DeleteRepositoryLongRunning", + "service": { + "fullName": "google.cloud.dataform.v1beta1.Dataform", + "shortName": "Dataform" + }, + "shortName": "DeleteRepositoryLongRunning" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dataform_v1beta1.types.DeleteRepositoryLongRunningRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "force", + "type": "bool" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "delete_repository_long_running" + }, + "description": "Sample for DeleteRepositoryLongRunning", + "file": "dataform_v1beta1_generated_dataform_delete_repository_long_running_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dataform_v1beta1_generated_Dataform_DeleteRepositoryLongRunning_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dataform_v1beta1_generated_dataform_delete_repository_long_running_sync.py" + }, { "canonical": true, "clientMethod": { @@ -2472,6 +2810,175 @@ ], "title": "dataform_v1beta1_generated_dataform_delete_repository_sync.py" }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.dataform_v1beta1.DataformAsyncClient", + "shortName": "DataformAsyncClient" + }, + "fullName": "google.cloud.dataform_v1beta1.DataformAsyncClient.delete_team_folder_tree", + "method": { + "fullName": "google.cloud.dataform.v1beta1.Dataform.DeleteTeamFolderTree", + "service": { + "fullName": "google.cloud.dataform.v1beta1.Dataform", + "shortName": "Dataform" + }, + "shortName": "DeleteTeamFolderTree" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dataform_v1beta1.types.DeleteTeamFolderTreeRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "force", + "type": "bool" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "delete_team_folder_tree" + }, + "description": "Sample for DeleteTeamFolderTree", + "file": "dataform_v1beta1_generated_dataform_delete_team_folder_tree_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dataform_v1beta1_generated_Dataform_DeleteTeamFolderTree_async", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dataform_v1beta1_generated_dataform_delete_team_folder_tree_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.dataform_v1beta1.DataformClient", + "shortName": "DataformClient" + }, + "fullName": "google.cloud.dataform_v1beta1.DataformClient.delete_team_folder_tree", + "method": { + "fullName": "google.cloud.dataform.v1beta1.Dataform.DeleteTeamFolderTree", + "service": { + "fullName": "google.cloud.dataform.v1beta1.Dataform", + "shortName": "Dataform" + }, + "shortName": "DeleteTeamFolderTree" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dataform_v1beta1.types.DeleteTeamFolderTreeRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "force", + "type": "bool" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "delete_team_folder_tree" + }, + "description": "Sample for DeleteTeamFolderTree", + "file": "dataform_v1beta1_generated_dataform_delete_team_folder_tree_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dataform_v1beta1_generated_Dataform_DeleteTeamFolderTree_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dataform_v1beta1_generated_dataform_delete_team_folder_tree_sync.py" + }, { "canonical": true, "clientMethod": { diff --git a/packages/google-cloud-dataform/tests/unit/gapic/dataform_v1beta1/test_dataform.py b/packages/google-cloud-dataform/tests/unit/gapic/dataform_v1beta1/test_dataform.py index cd9519c1fa14..c3d36adbebbd 100644 --- a/packages/google-cloud-dataform/tests/unit/gapic/dataform_v1beta1/test_dataform.py +++ b/packages/google-cloud-dataform/tests/unit/gapic/dataform_v1beta1/test_dataform.py @@ -2668,6 +2668,365 @@ async def test_delete_team_folder_flattened_error_async(): ) +@pytest.mark.parametrize( + "request_type", + [ + dataform.DeleteTeamFolderTreeRequest(), + {}, + ], +) +def test_delete_team_folder_tree(request_type, transport: str = "grpc"): + client = DataformClient( + 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_team_folder_tree), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.delete_team_folder_tree(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = dataform.DeleteTeamFolderTreeRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_delete_team_folder_tree_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = dataform.DeleteTeamFolderTreeRequest( + name="name_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_team_folder_tree), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.delete_team_folder_tree(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = dataform.DeleteTeamFolderTreeRequest( + name="name_value", + ) + assert args[0] == request_msg + + +def test_delete_team_folder_tree_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.delete_team_folder_tree + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.delete_team_folder_tree + ] = mock_rpc + request = {} + client.delete_team_folder_tree(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_team_folder_tree(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_delete_team_folder_tree_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = DataformAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.delete_team_folder_tree + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.delete_team_folder_tree + ] = mock_rpc + + request = {} + await client.delete_team_folder_tree(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + await client.delete_team_folder_tree(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + dataform.DeleteTeamFolderTreeRequest(), + {}, + ], +) +async def test_delete_team_folder_tree_async( + request_type, transport: str = "grpc_asyncio" +): + client = DataformAsyncClient( + credentials=async_anonymous_credentials(), + 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_team_folder_tree), "__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.delete_team_folder_tree(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = dataform.DeleteTeamFolderTreeRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_delete_team_folder_tree_field_headers(): + client = DataformClient( + 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 = dataform.DeleteTeamFolderTreeRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_team_folder_tree), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_team_folder_tree(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_team_folder_tree_field_headers_async(): + client = DataformAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = dataform.DeleteTeamFolderTreeRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_team_folder_tree), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.delete_team_folder_tree(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_team_folder_tree_flattened(): + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_team_folder_tree), "__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.delete_team_folder_tree( + name="name_value", + force=True, + ) + + # 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 + arg = args[0].force + mock_val = True + assert arg == mock_val + + +def test_delete_team_folder_tree_flattened_error(): + client = DataformClient( + 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_team_folder_tree( + dataform.DeleteTeamFolderTreeRequest(), + name="name_value", + force=True, + ) + + +@pytest.mark.asyncio +async def test_delete_team_folder_tree_flattened_async(): + client = DataformAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_team_folder_tree), "__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.delete_team_folder_tree( + name="name_value", + force=True, + ) + + # 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 + arg = args[0].force + mock_val = True + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_delete_team_folder_tree_flattened_error_async(): + client = DataformAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_team_folder_tree( + dataform.DeleteTeamFolderTreeRequest(), + name="name_value", + force=True, + ) + + @pytest.mark.parametrize( "request_type", [ @@ -5043,6 +5402,362 @@ async def test_delete_folder_flattened_error_async(): ) +@pytest.mark.parametrize( + "request_type", + [ + dataform.DeleteFolderTreeRequest(), + {}, + ], +) +def test_delete_folder_tree(request_type, transport: str = "grpc"): + client = DataformClient( + 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_folder_tree), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.delete_folder_tree(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = dataform.DeleteFolderTreeRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_delete_folder_tree_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = dataform.DeleteFolderTreeRequest( + name="name_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_folder_tree), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.delete_folder_tree(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = dataform.DeleteFolderTreeRequest( + name="name_value", + ) + assert args[0] == request_msg + + +def test_delete_folder_tree_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.delete_folder_tree in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.delete_folder_tree] = ( + mock_rpc + ) + request = {} + client.delete_folder_tree(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_folder_tree(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_delete_folder_tree_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = DataformAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.delete_folder_tree + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.delete_folder_tree + ] = mock_rpc + + request = {} + await client.delete_folder_tree(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + await client.delete_folder_tree(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + dataform.DeleteFolderTreeRequest(), + {}, + ], +) +async def test_delete_folder_tree_async(request_type, transport: str = "grpc_asyncio"): + client = DataformAsyncClient( + credentials=async_anonymous_credentials(), + 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_folder_tree), "__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.delete_folder_tree(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = dataform.DeleteFolderTreeRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_delete_folder_tree_field_headers(): + client = DataformClient( + 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 = dataform.DeleteFolderTreeRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_folder_tree), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_folder_tree(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_folder_tree_field_headers_async(): + client = DataformAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = dataform.DeleteFolderTreeRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_folder_tree), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.delete_folder_tree(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_folder_tree_flattened(): + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_folder_tree), "__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.delete_folder_tree( + name="name_value", + force=True, + ) + + # 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 + arg = args[0].force + mock_val = True + assert arg == mock_val + + +def test_delete_folder_tree_flattened_error(): + client = DataformClient( + 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_folder_tree( + dataform.DeleteFolderTreeRequest(), + name="name_value", + force=True, + ) + + +@pytest.mark.asyncio +async def test_delete_folder_tree_flattened_async(): + client = DataformAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_folder_tree), "__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.delete_folder_tree( + name="name_value", + force=True, + ) + + # 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 + arg = args[0].force + mock_val = True + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_delete_folder_tree_flattened_error_async(): + client = DataformAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_folder_tree( + dataform.DeleteFolderTreeRequest(), + name="name_value", + force=True, + ) + + @pytest.mark.parametrize( "request_type", [ @@ -8505,6 +9220,365 @@ async def test_delete_repository_flattened_error_async(): ) +@pytest.mark.parametrize( + "request_type", + [ + dataform.DeleteRepositoryLongRunningRequest(), + {}, + ], +) +def test_delete_repository_long_running(request_type, transport: str = "grpc"): + client = DataformClient( + 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_repository_long_running), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.delete_repository_long_running(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = dataform.DeleteRepositoryLongRunningRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_delete_repository_long_running_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = dataform.DeleteRepositoryLongRunningRequest( + name="name_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_repository_long_running), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.delete_repository_long_running(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = dataform.DeleteRepositoryLongRunningRequest( + name="name_value", + ) + assert args[0] == request_msg + + +def test_delete_repository_long_running_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.delete_repository_long_running + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.delete_repository_long_running + ] = mock_rpc + request = {} + client.delete_repository_long_running(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_repository_long_running(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_delete_repository_long_running_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = DataformAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.delete_repository_long_running + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.delete_repository_long_running + ] = mock_rpc + + request = {} + await client.delete_repository_long_running(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + await client.delete_repository_long_running(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "request_type", + [ + dataform.DeleteRepositoryLongRunningRequest(), + {}, + ], +) +async def test_delete_repository_long_running_async( + request_type, transport: str = "grpc_asyncio" +): + client = DataformAsyncClient( + credentials=async_anonymous_credentials(), + 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_repository_long_running), "__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.delete_repository_long_running(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = dataform.DeleteRepositoryLongRunningRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_delete_repository_long_running_field_headers(): + client = DataformClient( + 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 = dataform.DeleteRepositoryLongRunningRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_repository_long_running), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_repository_long_running(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_repository_long_running_field_headers_async(): + client = DataformAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = dataform.DeleteRepositoryLongRunningRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_repository_long_running), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.delete_repository_long_running(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_repository_long_running_flattened(): + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_repository_long_running), "__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.delete_repository_long_running( + name="name_value", + force=True, + ) + + # 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 + arg = args[0].force + mock_val = True + assert arg == mock_val + + +def test_delete_repository_long_running_flattened_error(): + client = DataformClient( + 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_repository_long_running( + dataform.DeleteRepositoryLongRunningRequest(), + name="name_value", + force=True, + ) + + +@pytest.mark.asyncio +async def test_delete_repository_long_running_flattened_async(): + client = DataformAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_repository_long_running), "__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.delete_repository_long_running( + name="name_value", + force=True, + ) + + # 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 + arg = args[0].force + mock_val = True + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_delete_repository_long_running_flattened_error_async(): + client = DataformAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_repository_long_running( + dataform.DeleteRepositoryLongRunningRequest(), + name="name_value", + force=True, + ) + + @pytest.mark.parametrize( "request_type", [ @@ -27304,6 +28378,193 @@ def test_delete_team_folder_rest_flattened_error(transport: str = "rest"): ) +def test_delete_team_folder_tree_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.delete_team_folder_tree + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.delete_team_folder_tree + ] = mock_rpc + + request = {} + client.delete_team_folder_tree(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_team_folder_tree(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_delete_team_folder_tree_rest_required_fields( + request_type=dataform.DeleteTeamFolderTreeRequest, +): + transport_class = transports.DataformRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_team_folder_tree._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_team_folder_tree._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.delete_team_folder_tree(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_delete_team_folder_tree_rest_unset_required_fields(): + transport = transports.DataformRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.delete_team_folder_tree._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_delete_team_folder_tree_rest_flattened(): + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/teamFolders/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + force=True, + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.delete_team_folder_tree(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1beta1/{name=projects/*/locations/*/teamFolders/*}:deleteTree" + % client.transport._host, + args[1], + ) + + +def test_delete_team_folder_tree_rest_flattened_error(transport: str = "rest"): + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_team_folder_tree( + dataform.DeleteTeamFolderTreeRequest(), + name="name_value", + force=True, + ) + + def test_query_team_folder_contents_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -28501,6 +29762,190 @@ def test_delete_folder_rest_flattened_error(transport: str = "rest"): ) +def test_delete_folder_tree_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.delete_folder_tree in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.delete_folder_tree] = ( + mock_rpc + ) + + request = {} + client.delete_folder_tree(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_folder_tree(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_delete_folder_tree_rest_required_fields( + request_type=dataform.DeleteFolderTreeRequest, +): + transport_class = transports.DataformRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_folder_tree._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_folder_tree._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.delete_folder_tree(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_delete_folder_tree_rest_unset_required_fields(): + transport = transports.DataformRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.delete_folder_tree._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_delete_folder_tree_rest_flattened(): + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "projects/sample1/locations/sample2/folders/sample3"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + force=True, + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.delete_folder_tree(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1beta1/{name=projects/*/locations/*/folders/*}:deleteTree" + % client.transport._host, + args[1], + ) + + +def test_delete_folder_tree_rest_flattened_error(transport: str = "rest"): + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_folder_tree( + dataform.DeleteFolderTreeRequest(), + name="name_value", + force=True, + ) + + def test_query_folder_contents_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -30231,6 +31676,195 @@ def test_delete_repository_rest_flattened_error(transport: str = "rest"): ) +def test_delete_repository_long_running_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.delete_repository_long_running + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.delete_repository_long_running + ] = mock_rpc + + request = {} + client.delete_repository_long_running(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.delete_repository_long_running(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_delete_repository_long_running_rest_required_fields( + request_type=dataform.DeleteRepositoryLongRunningRequest, +): + transport_class = transports.DataformRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_repository_long_running._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_repository_long_running._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.delete_repository_long_running(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_delete_repository_long_running_rest_unset_required_fields(): + transport = transports.DataformRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.delete_repository_long_running._get_unset_required_fields( + {} + ) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_delete_repository_long_running_rest_flattened(): + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/repositories/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + force=True, + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.delete_repository_long_running(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1beta1/{name=projects/*/locations/*/repositories/*}:deleteLongRunning" + % client.transport._host, + args[1], + ) + + +def test_delete_repository_long_running_rest_flattened_error(transport: str = "rest"): + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_repository_long_running( + dataform.DeleteRepositoryLongRunningRequest(), + name="name_value", + force=True, + ) + + def test_move_repository_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -33319,6 +34953,7 @@ def test_query_directory_contents_rest_required_fields( "page_size", "page_token", "path", + "view", ) ) jsonified_request.update(unset_fields) @@ -33381,6 +35016,7 @@ def test_query_directory_contents_rest_unset_required_fields(): "pageSize", "pageToken", "path", + "view", ) ) & set(("workspace",)) @@ -39692,6 +41328,28 @@ def test_delete_team_folder_empty_call_grpc(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_team_folder_tree_empty_call_grpc(): + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_team_folder_tree), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_team_folder_tree(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = dataform.DeleteTeamFolderTreeRequest() + assert args[0] == request_msg + + # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. def test_query_team_folder_contents_empty_call_grpc(): @@ -39816,6 +41474,28 @@ def test_delete_folder_empty_call_grpc(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_folder_tree_empty_call_grpc(): + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_folder_tree), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_folder_tree(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = dataform.DeleteFolderTreeRequest() + assert args[0] == request_msg + + # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. def test_query_folder_contents_empty_call_grpc(): @@ -39988,6 +41668,28 @@ def test_delete_repository_empty_call_grpc(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_repository_long_running_empty_call_grpc(): + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_repository_long_running), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_repository_long_running(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = dataform.DeleteRepositoryLongRunningRequest() + assert args[0] == request_msg + + # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. def test_move_repository_empty_call_grpc(): @@ -41243,6 +42945,32 @@ async def test_delete_team_folder_empty_call_grpc_asyncio(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_team_folder_tree_empty_call_grpc_asyncio(): + client = DataformAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_team_folder_tree), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.delete_team_folder_tree(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = dataform.DeleteTeamFolderTreeRequest() + assert args[0] == request_msg + + # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @pytest.mark.asyncio @@ -41414,6 +43142,32 @@ async def test_delete_folder_empty_call_grpc_asyncio(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_folder_tree_empty_call_grpc_asyncio(): + client = DataformAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_folder_tree), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.delete_folder_tree(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = dataform.DeleteFolderTreeRequest() + assert args[0] == request_msg + + # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @pytest.mark.asyncio @@ -41653,6 +43407,32 @@ async def test_delete_repository_empty_call_grpc_asyncio(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_repository_long_running_empty_call_grpc_asyncio(): + client = DataformAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_repository_long_running), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.delete_repository_long_running(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = dataform.DeleteRepositoryLongRunningRequest() + assert args[0] == request_msg + + # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @pytest.mark.asyncio @@ -43785,6 +45565,130 @@ def test_delete_team_folder_rest_interceptors(null_interceptor): pre.assert_called_once() +def test_delete_team_folder_tree_rest_bad_request( + request_type=dataform.DeleteTeamFolderTreeRequest, +): + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/locations/sample2/teamFolders/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.delete_team_folder_tree(request) + + +@pytest.mark.parametrize( + "request_type", + [ + dataform.DeleteTeamFolderTreeRequest, + dict, + ], +) +def test_delete_team_folder_tree_rest_call_success(request_type): + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/locations/sample2/teamFolders/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.delete_team_folder_tree(request) + + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_team_folder_tree_rest_interceptors(null_interceptor): + transport = transports.DataformRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.DataformRestInterceptor(), + ) + client = DataformClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), + mock.patch.object( + transports.DataformRestInterceptor, "post_delete_team_folder_tree" + ) as post, + mock.patch.object( + transports.DataformRestInterceptor, + "post_delete_team_folder_tree_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.DataformRestInterceptor, "pre_delete_team_folder_tree" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = dataform.DeleteTeamFolderTreeRequest.pb( + dataform.DeleteTeamFolderTreeRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value + + request = dataform.DeleteTeamFolderTreeRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata + + client.delete_team_folder_tree( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + def test_query_team_folder_contents_rest_bad_request( request_type=dataform.QueryTeamFolderContentsRequest, ): @@ -44715,6 +46619,129 @@ def test_delete_folder_rest_interceptors(null_interceptor): pre.assert_called_once() +def test_delete_folder_tree_rest_bad_request( + request_type=dataform.DeleteFolderTreeRequest, +): + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/locations/sample2/folders/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.delete_folder_tree(request) + + +@pytest.mark.parametrize( + "request_type", + [ + dataform.DeleteFolderTreeRequest, + dict, + ], +) +def test_delete_folder_tree_rest_call_success(request_type): + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/locations/sample2/folders/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.delete_folder_tree(request) + + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_folder_tree_rest_interceptors(null_interceptor): + transport = transports.DataformRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.DataformRestInterceptor(), + ) + client = DataformClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), + mock.patch.object( + transports.DataformRestInterceptor, "post_delete_folder_tree" + ) as post, + mock.patch.object( + transports.DataformRestInterceptor, "post_delete_folder_tree_with_metadata" + ) as post_with_metadata, + mock.patch.object( + transports.DataformRestInterceptor, "pre_delete_folder_tree" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = dataform.DeleteFolderTreeRequest.pb( + dataform.DeleteFolderTreeRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value + + request = dataform.DeleteFolderTreeRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata + + client.delete_folder_tree( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + def test_query_folder_contents_rest_bad_request( request_type=dataform.QueryFolderContentsRequest, ): @@ -45424,11 +47451,13 @@ def test_create_repository_rest_call_success(request_type): "git_remote_settings": { "url": "url_value", "default_branch": "default_branch_value", + "effective_default_branch": "effective_default_branch_value", "authentication_token_secret_version": "authentication_token_secret_version_value", "ssh_authentication_config": { "user_private_key_secret_version": "user_private_key_secret_version_value", "host_public_key": "host_public_key_value", }, + "git_repository_link": "git_repository_link_value", "token_status": 1, }, "npmrc_environment_variables_secret_version": "npmrc_environment_variables_secret_version_value", @@ -45675,11 +47704,13 @@ def test_update_repository_rest_call_success(request_type): "git_remote_settings": { "url": "url_value", "default_branch": "default_branch_value", + "effective_default_branch": "effective_default_branch_value", "authentication_token_secret_version": "authentication_token_secret_version_value", "ssh_authentication_config": { "user_private_key_secret_version": "user_private_key_secret_version_value", "host_public_key": "host_public_key_value", }, + "git_repository_link": "git_repository_link_value", "token_status": 1, }, "npmrc_environment_variables_secret_version": "npmrc_environment_variables_secret_version_value", @@ -45977,6 +48008,130 @@ def test_delete_repository_rest_interceptors(null_interceptor): pre.assert_called_once() +def test_delete_repository_long_running_rest_bad_request( + request_type=dataform.DeleteRepositoryLongRunningRequest, +): + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/locations/sample2/repositories/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.delete_repository_long_running(request) + + +@pytest.mark.parametrize( + "request_type", + [ + dataform.DeleteRepositoryLongRunningRequest, + dict, + ], +) +def test_delete_repository_long_running_rest_call_success(request_type): + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/locations/sample2/repositories/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.delete_repository_long_running(request) + + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_repository_long_running_rest_interceptors(null_interceptor): + transport = transports.DataformRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.DataformRestInterceptor(), + ) + client = DataformClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object(operation.Operation, "_set_result_from_operation"), + mock.patch.object( + transports.DataformRestInterceptor, "post_delete_repository_long_running" + ) as post, + mock.patch.object( + transports.DataformRestInterceptor, + "post_delete_repository_long_running_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.DataformRestInterceptor, "pre_delete_repository_long_running" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = dataform.DeleteRepositoryLongRunningRequest.pb( + dataform.DeleteRepositoryLongRunningRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value + + request = dataform.DeleteRepositoryLongRunningRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata + + client.delete_repository_long_running( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + def test_move_repository_rest_bad_request(request_type=dataform.MoveRepositoryRequest): client = DataformClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" @@ -54225,6 +56380,27 @@ def test_delete_team_folder_empty_call_rest(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_team_folder_tree_empty_call_rest(): + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_team_folder_tree), "__call__" + ) as call: + client.delete_team_folder_tree(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = dataform.DeleteTeamFolderTreeRequest() + assert args[0] == request_msg + + # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. def test_query_team_folder_contents_empty_call_rest(): @@ -54343,6 +56519,27 @@ def test_delete_folder_empty_call_rest(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_folder_tree_empty_call_rest(): + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_folder_tree), "__call__" + ) as call: + client.delete_folder_tree(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = dataform.DeleteFolderTreeRequest() + assert args[0] == request_msg + + # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. def test_query_folder_contents_empty_call_rest(): @@ -54507,6 +56704,27 @@ def test_delete_repository_empty_call_rest(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_repository_long_running_empty_call_rest(): + client = DataformClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_repository_long_running), "__call__" + ) as call: + client.delete_repository_long_running(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = dataform.DeleteRepositoryLongRunningRequest() + assert args[0] == request_msg + + # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. def test_move_repository_empty_call_rest(): @@ -55634,12 +57852,14 @@ def test_dataform_base_transport(): "create_team_folder", "update_team_folder", "delete_team_folder", + "delete_team_folder_tree", "query_team_folder_contents", "search_team_folders", "get_folder", "create_folder", "update_folder", "delete_folder", + "delete_folder_tree", "query_folder_contents", "query_user_root_contents", "move_folder", @@ -55648,6 +57868,7 @@ def test_dataform_base_transport(): "create_repository", "update_repository", "delete_repository", + "delete_repository_long_running", "move_repository", "commit_repository_changes", "read_repository_file", @@ -55998,6 +58219,9 @@ def test_dataform_client_transport_session_collision(transport_name): session1 = client1.transport.delete_team_folder._session session2 = client2.transport.delete_team_folder._session assert session1 != session2 + session1 = client1.transport.delete_team_folder_tree._session + session2 = client2.transport.delete_team_folder_tree._session + assert session1 != session2 session1 = client1.transport.query_team_folder_contents._session session2 = client2.transport.query_team_folder_contents._session assert session1 != session2 @@ -56016,6 +58240,9 @@ def test_dataform_client_transport_session_collision(transport_name): session1 = client1.transport.delete_folder._session session2 = client2.transport.delete_folder._session assert session1 != session2 + session1 = client1.transport.delete_folder_tree._session + session2 = client2.transport.delete_folder_tree._session + assert session1 != session2 session1 = client1.transport.query_folder_contents._session session2 = client2.transport.query_folder_contents._session assert session1 != session2 @@ -56040,6 +58267,9 @@ def test_dataform_client_transport_session_collision(transport_name): session1 = client1.transport.delete_repository._session session2 = client2.transport.delete_repository._session assert session1 != session2 + session1 = client1.transport.delete_repository_long_running._session + session2 = client2.transport.delete_repository_long_running._session + assert session1 != session2 session1 = client1.transport.move_repository._session session2 = client2.transport.move_repository._session assert session1 != session2 @@ -56497,10 +58727,41 @@ def test_parse_folder_path(): assert expected == actual -def test_notebook_runtime_template_path(): +def test_git_repository_link_path(): project = "squid" location = "clam" - notebook_runtime_template = "whelk" + connection = "whelk" + git_repository_link = "octopus" + expected = "projects/{project}/locations/{location}/connections/{connection}/gitRepositoryLinks/{git_repository_link}".format( + project=project, + location=location, + connection=connection, + git_repository_link=git_repository_link, + ) + actual = DataformClient.git_repository_link_path( + project, location, connection, git_repository_link + ) + assert expected == actual + + +def test_parse_git_repository_link_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + "connection": "cuttlefish", + "git_repository_link": "mussel", + } + path = DataformClient.git_repository_link_path(**expected) + + # Check that the path construction is reversible. + actual = DataformClient.parse_git_repository_link_path(path) + assert expected == actual + + +def test_notebook_runtime_template_path(): + project = "winkle" + location = "nautilus" + notebook_runtime_template = "scallop" expected = "projects/{project}/locations/{location}/notebookRuntimeTemplates/{notebook_runtime_template}".format( project=project, location=location, @@ -56514,9 +58775,9 @@ def test_notebook_runtime_template_path(): def test_parse_notebook_runtime_template_path(): expected = { - "project": "octopus", - "location": "oyster", - "notebook_runtime_template": "nudibranch", + "project": "abalone", + "location": "squid", + "notebook_runtime_template": "clam", } path = DataformClient.notebook_runtime_template_path(**expected) @@ -56526,10 +58787,10 @@ def test_parse_notebook_runtime_template_path(): def test_release_config_path(): - project = "cuttlefish" - location = "mussel" - repository = "winkle" - release_config = "nautilus" + project = "whelk" + location = "octopus" + repository = "oyster" + release_config = "nudibranch" expected = "projects/{project}/locations/{location}/repositories/{repository}/releaseConfigs/{release_config}".format( project=project, location=location, @@ -56544,10 +58805,10 @@ def test_release_config_path(): def test_parse_release_config_path(): expected = { - "project": "scallop", - "location": "abalone", - "repository": "squid", - "release_config": "clam", + "project": "cuttlefish", + "location": "mussel", + "repository": "winkle", + "release_config": "nautilus", } path = DataformClient.release_config_path(**expected) @@ -56557,9 +58818,9 @@ def test_parse_release_config_path(): def test_repository_path(): - project = "whelk" - location = "octopus" - repository = "oyster" + project = "scallop" + location = "abalone" + repository = "squid" expected = ( "projects/{project}/locations/{location}/repositories/{repository}".format( project=project, @@ -56573,9 +58834,9 @@ def test_repository_path(): def test_parse_repository_path(): expected = { - "project": "nudibranch", - "location": "cuttlefish", - "repository": "mussel", + "project": "clam", + "location": "whelk", + "repository": "octopus", } path = DataformClient.repository_path(**expected) @@ -56585,9 +58846,9 @@ def test_parse_repository_path(): def test_secret_version_path(): - project = "winkle" - secret = "nautilus" - version = "scallop" + project = "oyster" + secret = "nudibranch" + version = "cuttlefish" expected = "projects/{project}/secrets/{secret}/versions/{version}".format( project=project, secret=secret, @@ -56599,9 +58860,9 @@ def test_secret_version_path(): def test_parse_secret_version_path(): expected = { - "project": "abalone", - "secret": "squid", - "version": "clam", + "project": "mussel", + "secret": "winkle", + "version": "nautilus", } path = DataformClient.secret_version_path(**expected) @@ -56611,9 +58872,9 @@ def test_parse_secret_version_path(): def test_team_folder_path(): - project = "whelk" - location = "octopus" - team_folder = "oyster" + project = "scallop" + location = "abalone" + team_folder = "squid" expected = ( "projects/{project}/locations/{location}/teamFolders/{team_folder}".format( project=project, @@ -56627,9 +58888,9 @@ def test_team_folder_path(): def test_parse_team_folder_path(): expected = { - "project": "nudibranch", - "location": "cuttlefish", - "team_folder": "mussel", + "project": "clam", + "location": "whelk", + "team_folder": "octopus", } path = DataformClient.team_folder_path(**expected) @@ -56639,10 +58900,10 @@ def test_parse_team_folder_path(): def test_workflow_config_path(): - project = "winkle" - location = "nautilus" - repository = "scallop" - workflow_config = "abalone" + project = "oyster" + location = "nudibranch" + repository = "cuttlefish" + workflow_config = "mussel" expected = "projects/{project}/locations/{location}/repositories/{repository}/workflowConfigs/{workflow_config}".format( project=project, location=location, @@ -56657,10 +58918,10 @@ def test_workflow_config_path(): def test_parse_workflow_config_path(): expected = { - "project": "squid", - "location": "clam", - "repository": "whelk", - "workflow_config": "octopus", + "project": "winkle", + "location": "nautilus", + "repository": "scallop", + "workflow_config": "abalone", } path = DataformClient.workflow_config_path(**expected) @@ -56670,10 +58931,10 @@ def test_parse_workflow_config_path(): def test_workflow_invocation_path(): - project = "oyster" - location = "nudibranch" - repository = "cuttlefish" - workflow_invocation = "mussel" + project = "squid" + location = "clam" + repository = "whelk" + workflow_invocation = "octopus" expected = "projects/{project}/locations/{location}/repositories/{repository}/workflowInvocations/{workflow_invocation}".format( project=project, location=location, @@ -56688,10 +58949,10 @@ def test_workflow_invocation_path(): def test_parse_workflow_invocation_path(): expected = { - "project": "winkle", - "location": "nautilus", - "repository": "scallop", - "workflow_invocation": "abalone", + "project": "oyster", + "location": "nudibranch", + "repository": "cuttlefish", + "workflow_invocation": "mussel", } path = DataformClient.workflow_invocation_path(**expected) @@ -56701,10 +58962,10 @@ def test_parse_workflow_invocation_path(): def test_workspace_path(): - project = "squid" - location = "clam" - repository = "whelk" - workspace = "octopus" + project = "winkle" + location = "nautilus" + repository = "scallop" + workspace = "abalone" expected = "projects/{project}/locations/{location}/repositories/{repository}/workspaces/{workspace}".format( project=project, location=location, @@ -56717,10 +58978,10 @@ def test_workspace_path(): def test_parse_workspace_path(): expected = { - "project": "oyster", - "location": "nudibranch", - "repository": "cuttlefish", - "workspace": "mussel", + "project": "squid", + "location": "clam", + "repository": "whelk", + "workspace": "octopus", } path = DataformClient.workspace_path(**expected) @@ -56730,7 +58991,7 @@ def test_parse_workspace_path(): def test_common_billing_account_path(): - billing_account = "winkle" + billing_account = "oyster" expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -56740,7 +59001,7 @@ def test_common_billing_account_path(): def test_parse_common_billing_account_path(): expected = { - "billing_account": "nautilus", + "billing_account": "nudibranch", } path = DataformClient.common_billing_account_path(**expected) @@ -56750,7 +59011,7 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): - folder = "scallop" + folder = "cuttlefish" expected = "folders/{folder}".format( folder=folder, ) @@ -56760,7 +59021,7 @@ def test_common_folder_path(): def test_parse_common_folder_path(): expected = { - "folder": "abalone", + "folder": "mussel", } path = DataformClient.common_folder_path(**expected) @@ -56770,7 +59031,7 @@ def test_parse_common_folder_path(): def test_common_organization_path(): - organization = "squid" + organization = "winkle" expected = "organizations/{organization}".format( organization=organization, ) @@ -56780,7 +59041,7 @@ def test_common_organization_path(): def test_parse_common_organization_path(): expected = { - "organization": "clam", + "organization": "nautilus", } path = DataformClient.common_organization_path(**expected) @@ -56790,7 +59051,7 @@ def test_parse_common_organization_path(): def test_common_project_path(): - project = "whelk" + project = "scallop" expected = "projects/{project}".format( project=project, ) @@ -56800,7 +59061,7 @@ def test_common_project_path(): def test_parse_common_project_path(): expected = { - "project": "octopus", + "project": "abalone", } path = DataformClient.common_project_path(**expected) @@ -56810,8 +59071,8 @@ def test_parse_common_project_path(): def test_common_location_path(): - project = "oyster" - location = "nudibranch" + project = "squid" + location = "clam" expected = "projects/{project}/locations/{location}".format( project=project, location=location, @@ -56822,8 +59083,8 @@ def test_common_location_path(): def test_parse_common_location_path(): expected = { - "project": "cuttlefish", - "location": "mussel", + "project": "whelk", + "location": "octopus", } path = DataformClient.common_location_path(**expected) diff --git a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/types/clusters.py b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/types/clusters.py index a2e81a7ab472..8aff97ba7039 100644 --- a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/types/clusters.py +++ b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/types/clusters.py @@ -702,7 +702,12 @@ class GceClusterConfig(proto.Message): confidential_instance_config (google.cloud.dataproc_v1.types.ConfidentialInstanceConfig): Optional. Confidential Instance Config for clusters using `Confidential - VMs `__. + VMs `__. + resource_manager_tags (MutableMapping[str, str]): + Optional. [Resource manager tags] + (https://cloud.google.com/resource-manager/docs/tags/tags-creating-and-managing) + to add to all instances (see [Use secure tags] + (https://cloud.google.com/dataproc/docs/guides/use-secure-tags)). """ class PrivateIpv6GoogleAccess(proto.Enum): @@ -795,6 +800,11 @@ class PrivateIpv6GoogleAccess(proto.Enum): number=15, message="ConfidentialInstanceConfig", ) + resource_manager_tags: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=16, + ) class NodeGroupAffinity(proto.Message): @@ -866,18 +876,52 @@ class ShieldedInstanceConfig(proto.Message): class ConfidentialInstanceConfig(proto.Message): r"""Confidential Instance Config for clusters using `Confidential - VMs `__ + VMs `__ Attributes: enable_confidential_compute (bool): - Optional. Defines whether the instance should - have confidential compute enabled. + Optional. Deprecated: Use 'confidential_instance_type' + instead. Defines whether the instance should have + confidential compute enabled. + confidential_instance_type (google.cloud.dataproc_v1.types.ConfidentialInstanceConfig.ConfidentialInstanceType): + Optional. Defines the type of Confidential + Compute technology to use. """ + class ConfidentialInstanceType(proto.Enum): + r"""The type of Confidential Compute technology as per `Confidential + Computing + types `__. + New values may be added in the future. + + Values: + CONFIDENTIAL_INSTANCE_TYPE_UNSPECIFIED (0): + Confidential Instance Type is not specified. + SEV (1): + `AMD Secure Encrypted + Virtualization `__ + SEV_SNP (2): + `AMD Secure Encrypted Virtualization-Secure Nested + Paging `__ + TDX (3): + `Intel Trust Domain + Extensions `__ + """ + + CONFIDENTIAL_INSTANCE_TYPE_UNSPECIFIED = 0 + SEV = 1 + SEV_SNP = 2 + TDX = 3 + enable_confidential_compute: bool = proto.Field( proto.BOOL, number=1, ) + confidential_instance_type: ConfidentialInstanceType = proto.Field( + proto.ENUM, + number=2, + enum=ConfidentialInstanceType, + ) class InstanceGroupConfig(proto.Message): diff --git a/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_cluster_controller.py b/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_cluster_controller.py index c86e8b888fb4..026ebf0a39ed 100644 --- a/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_cluster_controller.py +++ b/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_cluster_controller.py @@ -6394,7 +6394,11 @@ def test_create_cluster_rest_call_success(request_type): "enable_vtpm": True, "enable_integrity_monitoring": True, }, - "confidential_instance_config": {"enable_confidential_compute": True}, + "confidential_instance_config": { + "enable_confidential_compute": True, + "confidential_instance_type": 1, + }, + "resource_manager_tags": {}, }, "master_config": { "num_instances": 1399, @@ -6814,7 +6818,11 @@ def test_update_cluster_rest_call_success(request_type): "enable_vtpm": True, "enable_integrity_monitoring": True, }, - "confidential_instance_config": {"enable_confidential_compute": True}, + "confidential_instance_config": { + "enable_confidential_compute": True, + "confidential_instance_type": 1, + }, + "resource_manager_tags": {}, }, "master_config": { "num_instances": 1399, diff --git a/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_workflow_template_service.py b/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_workflow_template_service.py index 11a8cfd67cd7..eba33660ce14 100644 --- a/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_workflow_template_service.py +++ b/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_workflow_template_service.py @@ -6030,8 +6030,10 @@ def test_create_workflow_template_rest_call_success(request_type): "enable_integrity_monitoring": True, }, "confidential_instance_config": { - "enable_confidential_compute": True + "enable_confidential_compute": True, + "confidential_instance_type": 1, }, + "resource_manager_tags": {}, }, "master_config": { "num_instances": 1399, @@ -6826,8 +6828,10 @@ def test_instantiate_inline_workflow_template_rest_call_success(request_type): "enable_integrity_monitoring": True, }, "confidential_instance_config": { - "enable_confidential_compute": True + "enable_confidential_compute": True, + "confidential_instance_type": 1, }, + "resource_manager_tags": {}, }, "master_config": { "num_instances": 1399, @@ -7340,8 +7344,10 @@ def test_update_workflow_template_rest_call_success(request_type): "enable_integrity_monitoring": True, }, "confidential_instance_config": { - "enable_confidential_compute": True + "enable_confidential_compute": True, + "confidential_instance_type": 1, }, + "resource_manager_tags": {}, }, "master_config": { "num_instances": 1399, diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/audio_config.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/audio_config.py index 4d5dfbd4f430..eb00038d3dea 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/audio_config.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/audio_config.py @@ -180,7 +180,7 @@ class OutputAudioEncoding(proto.Enum): PCM). Audio content returned as LINEAR16 also contains a WAV header. LINT: LEGACY_NAMES OUTPUT_AUDIO_ENCODING_MP3 (2): - MP3 audio at 32kbps. + MP3 audio at 64kbps. OUTPUT_AUDIO_ENCODING_MP3_64_KBPS (4): MP3 audio at 64kbps. LINT: LEGACY_NAMES OUTPUT_AUDIO_ENCODING_OGG_OPUS (3): diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/session.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/session.py index a44003874b97..6f133f02b7be 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/session.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/session.py @@ -89,6 +89,14 @@ class DetectIntentResponseView(proto.Enum): ----------------------------------------------- [QueryResult.diagnostic_info][google.cloud.dialogflow.cx.v3.QueryResult.diagnostic_info] + + - [QueryResult.generative_info][] + - + + [QueryResult.trace_blocks][google.cloud.dialogflow.cx.v3.QueryResult.trace_blocks] + ---------------------------------------------------------------------------------- + + [QueryResult.data_store_connection_signals][google.cloud.dialogflow.cx.v3.QueryResult.data_store_connection_signals] DETECT_INTENT_RESPONSE_VIEW_DEFAULT (3): Default response view omits the following fields: ------------------------------------------------- diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/audio_config.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/audio_config.py index 3fbeab092ae2..d661baaaec4e 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/audio_config.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/audio_config.py @@ -181,7 +181,7 @@ class OutputAudioEncoding(proto.Enum): PCM). Audio content returned as LINEAR16 also contains a WAV header. LINT: LEGACY_NAMES OUTPUT_AUDIO_ENCODING_MP3 (2): - MP3 audio at 32kbps. + MP3 audio at 64kbps. OUTPUT_AUDIO_ENCODING_MP3_64_KBPS (4): MP3 audio at 64kbps. LINT: LEGACY_NAMES OUTPUT_AUDIO_ENCODING_OGG_OPUS (3): diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/session.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/session.py index 491400ec6cd8..7f2626baed6b 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/session.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/session.py @@ -95,6 +95,12 @@ class DetectIntentResponseView(proto.Enum): --------------------------------------------------------------------------------------------- [QueryResult.generative_info][google.cloud.dialogflow.cx.v3beta1.QueryResult.generative_info] + --------------------------------------------------------------------------------------------- + + [QueryResult.trace_blocks][google.cloud.dialogflow.cx.v3beta1.QueryResult.trace_blocks] + --------------------------------------------------------------------------------------- + + [QueryResult.data_store_connection_signals][google.cloud.dialogflow.cx.v3beta1.QueryResult.data_store_connection_signals] DETECT_INTENT_RESPONSE_VIEW_DEFAULT (3): Default response view omits the following fields: ------------------------------------------------- diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow/__init__.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow/__init__.py index bdb578d75596..40ece2da8fa7 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow/__init__.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow/__init__.py @@ -251,6 +251,7 @@ NotificationConfig, SetSuggestionFeatureConfigOperationMetadata, SetSuggestionFeatureConfigRequest, + SipConfig, SuggestionFeature, UpdateConversationProfileRequest, ) @@ -646,6 +647,7 @@ "NotificationConfig", "SetSuggestionFeatureConfigOperationMetadata", "SetSuggestionFeatureConfigRequest", + "SipConfig", "SuggestionFeature", "UpdateConversationProfileRequest", "CreateDocumentRequest", diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/__init__.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/__init__.py index 87ed765ed6cc..a41a2bc327c8 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/__init__.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/__init__.py @@ -196,6 +196,7 @@ NotificationConfig, SetSuggestionFeatureConfigOperationMetadata, SetSuggestionFeatureConfigRequest, + SipConfig, SuggestionFeature, UpdateConversationProfileRequest, ) @@ -787,6 +788,7 @@ def _get_version(dependency_name): "SetAgentRequest", "SetSuggestionFeatureConfigOperationMetadata", "SetSuggestionFeatureConfigRequest", + "SipConfig", "SipTrunk", "SipTrunksClient", "SmartReplyAnswer", diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/participants/async_client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/participants/async_client.py index 5357f1250f09..443202bb9a83 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/participants/async_client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/participants/async_client.py @@ -1083,8 +1083,14 @@ def request_generator(): 1. If the input was set to streaming audio, the first one or more messages contain recognition_result. Each recognition_result represents a more complete - transcript of what the user said. The last - recognition_result has is_final set to true. + transcript of what the user said. When a user + speaks multiple sentences, the API will emit + multiple messages where is_final = true. Each time + the system detects a distinct pause or completed + thought, it locks in that segment, marks it + is_final = true, and then immediately starts a new + recognition cycle for the next sentence on the + same stream. 2. In virtual agent stage: if enable_partial_automated_agent_reply is true, the diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/participants/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/participants/client.py index 40216fc5549c..41efcc61905b 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/participants/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/participants/client.py @@ -1696,8 +1696,14 @@ def request_generator(): 1. If the input was set to streaming audio, the first one or more messages contain recognition_result. Each recognition_result represents a more complete - transcript of what the user said. The last - recognition_result has is_final set to true. + transcript of what the user said. When a user + speaks multiple sentences, the API will emit + multiple messages where is_final = true. Each time + the system detects a distinct pause or completed + thought, it locks in that segment, marks it + is_final = true, and then immediately starts a new + recognition cycle for the next sentence on the + same stream. 2. In virtual agent stage: if enable_partial_automated_agent_reply is true, the diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/types/__init__.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/types/__init__.py index 8ecbf73c0ec5..d8afdacb24cb 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/types/__init__.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/types/__init__.py @@ -154,6 +154,7 @@ NotificationConfig, SetSuggestionFeatureConfigOperationMetadata, SetSuggestionFeatureConfigRequest, + SipConfig, SuggestionFeature, UpdateConversationProfileRequest, ) @@ -513,6 +514,7 @@ "NotificationConfig", "SetSuggestionFeatureConfigOperationMetadata", "SetSuggestionFeatureConfigRequest", + "SipConfig", "SuggestionFeature", "UpdateConversationProfileRequest", "CreateDocumentRequest", diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/types/audio_config.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/types/audio_config.py index c7561873924f..0e455b9dc087 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/types/audio_config.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/types/audio_config.py @@ -253,7 +253,7 @@ class OutputAudioEncoding(proto.Enum): samples (Linear PCM). Audio content returned as LINEAR16 also contains a WAV header. OUTPUT_AUDIO_ENCODING_MP3 (2): - MP3 audio at 32kbps. + MP3 audio at 64kbps. OUTPUT_AUDIO_ENCODING_MP3_64_KBPS (4): MP3 audio at 64kbps. OUTPUT_AUDIO_ENCODING_OGG_OPUS (3): diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/types/ces_app.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/types/ces_app.py index cd0c38b5d7b8..7d49510c941b 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/types/ces_app.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/types/ces_app.py @@ -32,6 +32,8 @@ class CesAppSpec(proto.Message): r"""Spec of CES app that the generator can choose from. + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + Attributes: ces_app (str): Optional. Format: @@ -39,6 +41,20 @@ class CesAppSpec(proto.Message): confirmation_requirement (google.cloud.dialogflow_v2.types.Tool.ConfirmationRequirement): Optional. Indicates whether the app requires human confirmation. + proactive_enabled (bool): + Optional. Only applicable for CompanionAgent. Indicates + whether the ces app is enabled in proactive mode. At least + one of ``proactive_enabled`` or ``reactive_enabled`` should + be true; otherwise, the ces app will be ignored. + + This field is a member of `oneof`_ ``_proactive_enabled``. + reactive_enabled (bool): + Optional. Only applicable for CompanionAgent. Indicates + whether the ces app is enabled in reactive mode. At least + one of ``proactive_enabled`` or ``reactive_enabled`` should + be true; otherwise, the ces app will be ignored. + + This field is a member of `oneof`_ ``_reactive_enabled``. """ ces_app: str = proto.Field( @@ -50,6 +66,16 @@ class CesAppSpec(proto.Message): number=2, enum=tool.Tool.ConfirmationRequirement, ) + proactive_enabled: bool = proto.Field( + proto.BOOL, + number=3, + optional=True, + ) + reactive_enabled: bool = proto.Field( + proto.BOOL, + number=4, + optional=True, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/types/conversation.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/types/conversation.py index dc86d778d8e3..5be10d3de70f 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/types/conversation.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/types/conversation.py @@ -1700,12 +1700,18 @@ class AnswerType(proto.Enum): The answer is from generative model. INTENT (3): The answer is from intent matching. + PLAYBOOK (4): + The answer is from Playbook. + EVENT (5): + The answer is from event. """ ANSWER_TYPE_UNSPECIFIED = 0 FAQ = 1 GENERATIVE = 2 INTENT = 3 + PLAYBOOK = 4 + EVENT = 5 class AnswerSource(proto.Message): r"""The sources of the answers. diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/types/conversation_profile.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/types/conversation_profile.py index a381b3dec71a..35cd96880a36 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/types/conversation_profile.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/types/conversation_profile.py @@ -39,6 +39,7 @@ "HumanAgentHandoffConfig", "NotificationConfig", "LoggingConfig", + "SipConfig", "SuggestionFeature", "SetSuggestionFeatureConfigRequest", "ClearSuggestionFeatureConfigRequest", @@ -107,6 +108,8 @@ class ConversationProfile(proto.Message): languages. This should be a `BCP-47 `__ language tag. Example: "en-US". + sip_config (google.cloud.dialogflow_v2.types.SipConfig): + Optional. Configuration for SIP connections. time_zone (str): The time zone of this conversational profile from the `time zone database `__, e.g., @@ -187,6 +190,11 @@ class ConversationProfile(proto.Message): proto.STRING, number=10, ) + sip_config: "SipConfig" = proto.Field( + proto.MESSAGE, + number=16, + message="SipConfig", + ) time_zone: str = proto.Field( proto.STRING, number=14, @@ -472,6 +480,20 @@ class SuggestionFeatureConfig(proto.Message): rai_settings (google.cloud.dialogflow_v2.types.RaiSettings): Optional. Settings for Responsible AI checks. Supported features: KNOWLEDGE_ASSIST + suggestion_trigger_event (google.cloud.dialogflow_v2.types.TriggerEvent): + Optional. The trigger event for suggestion. If unspecified, + it will be ``CUSTOMER_MESSAGE``. Supported features: + KNOWLEDGE_ASSIST For KNOWLEDGE_ASSIST, these four trigger + events are supported: + + 1. TRIGGER_EVENT_UNSPECIFIED + 2. END_OF_UTTERANCE + 3. CUSTOMER_MESSAGE + 4. AGENT_MESSAGE + disable_query_search_context (bool): + Optional. If true, disable appending available search + context to the search query. Supported features: + KNOWLEDGE_ASSIST suggestion_trigger_settings (google.cloud.dialogflow_v2.types.HumanAgentAssistantConfig.SuggestionTriggerSettings): Settings of suggestion trigger. @@ -519,6 +541,15 @@ class SuggestionFeatureConfig(proto.Message): number=19, message=generator.RaiSettings, ) + suggestion_trigger_event: generator.TriggerEvent = proto.Field( + proto.ENUM, + number=20, + enum=generator.TriggerEvent, + ) + disable_query_search_context: bool = proto.Field( + proto.BOOL, + number=21, + ) suggestion_trigger_settings: "HumanAgentAssistantConfig.SuggestionTriggerSettings" = proto.Field( proto.MESSAGE, number=10, @@ -1215,6 +1246,67 @@ class LoggingConfig(proto.Message): ) +class SipConfig(proto.Message): + r"""Defines the SIP configuration. + + Attributes: + create_conversation_on_the_fly (bool): + Asks Dialogflow Telephony to create the + conversation provided in the SIP header on the + fly when the call comes in. + inactive_start (bool): + Starts the conversation with inactive SDP + directives + max_audio_recording_duration (google.protobuf.duration_pb2.Duration): + Max duration for audio recording. + Overrides the default value of 15 min. + Max value is 8 hours. + allow_virtual_agent_interaction (bool): + Allows interactions with a Dialogflow virtual + agent even if the call is connected for SIPREC + purposes. + keep_conversation_running (bool): + Keeps the conversation running even if the + call is disconnected. + copy_inbound_call_leg_headers (MutableSequence[str]): + List of inbound call leg headers to be copied + to outbound call legs created later. + ignore_reinvite_media_direction (bool): + Ignores any media direction in the reINVITE + SDP offer. Reuse the previous media direction. + """ + + create_conversation_on_the_fly: bool = proto.Field( + proto.BOOL, + number=1, + ) + inactive_start: bool = proto.Field( + proto.BOOL, + number=3, + ) + max_audio_recording_duration: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=4, + message=duration_pb2.Duration, + ) + allow_virtual_agent_interaction: bool = proto.Field( + proto.BOOL, + number=5, + ) + keep_conversation_running: bool = proto.Field( + proto.BOOL, + number=6, + ) + copy_inbound_call_leg_headers: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=8, + ) + ignore_reinvite_media_direction: bool = proto.Field( + proto.BOOL, + number=9, + ) + + class SuggestionFeature(proto.Message): r"""The type of Human Agent Assistant API suggestion to perform, and the maximum number of results to return for that type. Multiple diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/types/participant.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/types/participant.py index 139aa5bfed9c..56f9fe9491fd 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/types/participant.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/types/participant.py @@ -148,9 +148,9 @@ class Participant(proto.Message): participant. 2. If you set this field in - [AnalyzeContent][google.cloud.dialogflow.v2.AnalyzeContentRequest.participant] - or - [StreamingAnalyzeContent][google.cloud.dialogflow.v2.StreamingAnalyzeContentRequest.participant], + [AnalyzeContent][google.cloud.dialogflow.v2.AnalyzeContentRequest.obfuscated_external_user_id] + or [StreamingAnalyzeContent] + [google.cloud.dialogflow.v2.StreamingAnalyzeContentRequest.obfuscated_external_user_id], Dialogflow will update [Participant.obfuscated_external_user_id][google.cloud.dialogflow.v2.Participant.obfuscated_external_user_id]. @@ -163,6 +163,12 @@ class Participant(proto.Message): purposes. For example, Dialogflow determines whether a user in one conversation returned in a later conversation. + Additionally, to link an escalated Virtual Agent + conversation with its corresponding Agent Assist + conversation for analytics, this field in Agent Assist + conversations should be populated to indicate the user id of + the ``END_USER`` participant in the escalated conversation. + Note: - Please never pass raw user ids to Dialogflow. Always @@ -930,8 +936,12 @@ class StreamingAnalyzeContentResponse(proto.Message): 1. If the input was set to streaming audio, the first one or more messages contain ``recognition_result``. Each ``recognition_result`` represents a more complete transcript of - what the user said. The last ``recognition_result`` has - ``is_final`` set to ``true``. + what the user said. When a user speaks multiple sentences, the + API will emit multiple messages where ``is_final = true``. Each + time the system detects a distinct pause or completed thought, it + locks in that segment, marks it ``is_final = true``, and then + immediately starts a new recognition cycle for the next sentence + on the same stream. 2. In virtual agent stage: if ``enable_partial_automated_agent_reply`` is true, the following N @@ -2028,6 +2038,11 @@ class SuggestKnowledgeAssistResponse(proto.Message): [SuggestKnowledgeAssistRequest.context_size][google.cloud.dialogflow.v2.SuggestKnowledgeAssistRequest.context_size] field in the request if there are fewer messages in the conversation. + additional_suggested_query_results (MutableSequence[google.cloud.dialogflow_v2.types.KnowledgeAssistAnswer.AdditionalSuggestedQueryResult]): + Optional. The list of additional suggested + queries based on the context. This is used for + the cases when we want to generate multiple + queries for a single request. """ knowledge_assist_answer: "KnowledgeAssistAnswer" = proto.Field( @@ -2043,6 +2058,13 @@ class SuggestKnowledgeAssistResponse(proto.Message): proto.INT32, number=3, ) + additional_suggested_query_results: MutableSequence[ + "KnowledgeAssistAnswer.AdditionalSuggestedQueryResult" + ] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message="KnowledgeAssistAnswer.AdditionalSuggestedQueryResult", + ) class IngestedContextReferenceDebugInfo(proto.Message): @@ -2205,6 +2227,10 @@ class KnowledgeAssistDebugInfo(proto.Message): search knowledge. service_latency (google.cloud.dialogflow_v2.types.ServiceLatency): The latency of the service. + query_generation_debug_info (google.cloud.dialogflow_v2.types.KnowledgeAssistDebugInfo.QueryGenerationDebugInfo): + Token usage metadata for query generation. + ces_debug_info (google.protobuf.struct_pb2.Struct): + Debug information from CES runtime API. """ class QueryGenerationFailureReason(proto.Enum): @@ -2411,6 +2437,33 @@ class KnowledgeAssistBehavior(proto.Message): number=18, ) + class QueryGenerationDebugInfo(proto.Message): + r"""Token usage metadata for query generation. + + Attributes: + prompt_token_count (int): + The total number of tokens in the prompt. + candidates_token_count (int): + The total number of tokens in the generated + candidates. + total_token_count (int): + The total number of tokens for the entire + request. + """ + + prompt_token_count: int = proto.Field( + proto.INT32, + number=1, + ) + candidates_token_count: int = proto.Field( + proto.INT32, + number=2, + ) + total_token_count: int = proto.Field( + proto.INT32, + number=3, + ) + query_generation_failure_reason: QueryGenerationFailureReason = proto.Field( proto.ENUM, number=1, @@ -2443,6 +2496,16 @@ class KnowledgeAssistBehavior(proto.Message): number=6, message="ServiceLatency", ) + query_generation_debug_info: QueryGenerationDebugInfo = proto.Field( + proto.MESSAGE, + number=7, + message=QueryGenerationDebugInfo, + ) + ces_debug_info: struct_pb2.Struct = proto.Field( + proto.MESSAGE, + number=8, + message=struct_pb2.Struct, + ) class KnowledgeAssistAnswer(proto.Message): @@ -2471,12 +2534,66 @@ class SuggestedQuery(proto.Message): Attributes: query_text (str): Suggested query text. + search_contexts (MutableSequence[google.cloud.dialogflow_v2.types.KnowledgeAssistAnswer.SuggestedQuery.SearchContext]): + Optional. The search contexts for the query. """ + class SearchContext(proto.Message): + r"""Search context is information useful for knowledge search that helps + enrich the query. Example: search_context { key: "application name" + value: "DesignApp" } + + Attributes: + key (str): + Optional. The key of the search context, e.g. + "application name". + value (str): + Optional. The value of the search context, + e.g. "DesignApp". + """ + + key: str = proto.Field( + proto.STRING, + number=1, + ) + value: str = proto.Field( + proto.STRING, + number=2, + ) + query_text: str = proto.Field( proto.STRING, number=1, ) + search_contexts: MutableSequence[ + "KnowledgeAssistAnswer.SuggestedQuery.SearchContext" + ] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message="KnowledgeAssistAnswer.SuggestedQuery.SearchContext", + ) + + class AdditionalSuggestedQueryResult(proto.Message): + r"""Represents a single suggested query result. + + Attributes: + suggested_query (google.cloud.dialogflow_v2.types.KnowledgeAssistAnswer.SuggestedQuery): + Output only. The suggested query based on the + context. + answer_record (str): + Output only. The name of the answer record. Format: + ``projects//locations//answerRecords/`` + """ + + suggested_query: "KnowledgeAssistAnswer.SuggestedQuery" = proto.Field( + proto.MESSAGE, + number=1, + message="KnowledgeAssistAnswer.SuggestedQuery", + ) + answer_record: str = proto.Field( + proto.STRING, + number=5, + ) class KnowledgeAnswer(proto.Message): r"""Represents an answer from Knowledge. Currently supports FAQ @@ -2500,6 +2617,16 @@ class KnowledgeAnswer(proto.Message): generative_source (google.cloud.dialogflow_v2.types.KnowledgeAssistAnswer.KnowledgeAnswer.GenerativeSource): Populated if the prediction was Generative. + This field is a member of `oneof`_ ``source``. + playbook_source (google.cloud.dialogflow_v2.types.KnowledgeAssistAnswer.KnowledgeAnswer.GenerativeSource): + Populated if the prediction was from + Playbook. + + This field is a member of `oneof`_ ``source``. + event_source (google.cloud.dialogflow_v2.types.KnowledgeAssistAnswer.KnowledgeAnswer.EventSource): + Populated if the prediction was from an + event. + This field is a member of `oneof`_ ``source``. """ @@ -2565,6 +2692,28 @@ class Snippet(proto.Message): message="KnowledgeAssistAnswer.KnowledgeAnswer.GenerativeSource.Snippet", ) + class EventSource(proto.Message): + r"""Details about source of Event answer. + + Attributes: + event (str): + Name of the triggered event. + snippets (google.cloud.dialogflow_v2.types.KnowledgeAssistAnswer.KnowledgeAnswer.GenerativeSource): + Sources used in event fulfillment. + """ + + event: str = proto.Field( + proto.STRING, + number=1, + ) + snippets: "KnowledgeAssistAnswer.KnowledgeAnswer.GenerativeSource" = ( + proto.Field( + proto.MESSAGE, + number=2, + message="KnowledgeAssistAnswer.KnowledgeAnswer.GenerativeSource", + ) + ) + answer_text: str = proto.Field( proto.STRING, number=1, @@ -2583,6 +2732,20 @@ class Snippet(proto.Message): message="KnowledgeAssistAnswer.KnowledgeAnswer.GenerativeSource", ) ) + playbook_source: "KnowledgeAssistAnswer.KnowledgeAnswer.GenerativeSource" = ( + proto.Field( + proto.MESSAGE, + number=7, + oneof="source", + message="KnowledgeAssistAnswer.KnowledgeAnswer.GenerativeSource", + ) + ) + event_source: "KnowledgeAssistAnswer.KnowledgeAnswer.EventSource" = proto.Field( + proto.MESSAGE, + number=8, + oneof="source", + message="KnowledgeAssistAnswer.KnowledgeAnswer.EventSource", + ) suggested_query: SuggestedQuery = proto.Field( proto.MESSAGE, diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/types/session.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/types/session.py index 70a7f86252c7..eb576456d28c 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/types/session.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/types/session.py @@ -953,20 +953,23 @@ class StreamingRecognitionResult(proto.Message): finalized transcript values received for the series of results. In the following example, single utterance is enabled. In the case - where single utterance is not enabled, result 7 would not occur. + where single utterance is not enabled, result 8 would not occur. :: - Num | transcript | message_type | is_final - --- | ----------------------- | ----------------------- | -------- - 1 | "tube" | TRANSCRIPT | false - 2 | "to be a" | TRANSCRIPT | false - 3 | "to be" | TRANSCRIPT | false - 4 | "to be or not to be" | TRANSCRIPT | true - 5 | "that's" | TRANSCRIPT | false - 6 | "that is | TRANSCRIPT | false - 7 | unset | END_OF_SINGLE_UTTERANCE | unset - 8 | " that is the question" | TRANSCRIPT | true + Num | transcript | message_type | is_final + --- | ------------------------ | ----------------------- | -------- + 1 | "tube" | TRANSCRIPT | false + 2 | "to be a" | TRANSCRIPT | false + 3 | "to be" | TRANSCRIPT | false + 4 | "to be or not to be" | TRANSCRIPT | true + 5 | "that's" | TRANSCRIPT | false + 6 | "that is | TRANSCRIPT | false + 7 | " that is the question" | TRANSCRIPT | true + 8 | unset | END_OF_SINGLE_UTTERANCE | unset + 9 | ". Whether 'tis nobler" | TRANSCRIPT | true + 10 | " in the mind" | TRANSCRIPT | false + 11 | " in the mind to suffer" | TRANSCRIPT | true Concatenating the finalized transcripts with ``is_final`` set to true, the complete utterance becomes "to be or not to be that is the diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/__init__.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/__init__.py index 348927177b65..677d45994ed6 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/__init__.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/__init__.py @@ -155,6 +155,7 @@ NotificationConfig, SetSuggestionFeatureConfigOperationMetadata, SetSuggestionFeatureConfigRequest, + SipConfig, UpdateConversationProfileRequest, ) from .types.document import ( @@ -748,6 +749,7 @@ def _get_version(dependency_name): "SetAgentRequest", "SetSuggestionFeatureConfigOperationMetadata", "SetSuggestionFeatureConfigRequest", + "SipConfig", "SipTrunk", "SipTrunksClient", "SmartReplyAnswer", diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversation_profiles/async_client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversation_profiles/async_client.py index 6f45169ecb37..3c42b86c7482 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversation_profiles/async_client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversation_profiles/async_client.py @@ -91,12 +91,6 @@ class ConversationProfilesAsyncClient: agent_path = staticmethod(ConversationProfilesClient.agent_path) parse_agent_path = staticmethod(ConversationProfilesClient.parse_agent_path) - conversation_model_path = staticmethod( - ConversationProfilesClient.conversation_model_path - ) - parse_conversation_model_path = staticmethod( - ConversationProfilesClient.parse_conversation_model_path - ) conversation_profile_path = staticmethod( ConversationProfilesClient.conversation_profile_path ) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversation_profiles/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversation_profiles/client.py index 2d0559befcb4..19b1f5fd9781 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversation_profiles/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversation_profiles/client.py @@ -257,28 +257,6 @@ def parse_agent_path(path: str) -> Dict[str, str]: m = re.match(r"^projects/(?P.+?)/agent$", path) return m.groupdict() if m else {} - @staticmethod - def conversation_model_path( - project: str, - location: str, - conversation_model: str, - ) -> str: - """Returns a fully-qualified conversation_model string.""" - return "projects/{project}/locations/{location}/conversationModels/{conversation_model}".format( - project=project, - location=location, - conversation_model=conversation_model, - ) - - @staticmethod - def parse_conversation_model_path(path: str) -> Dict[str, str]: - """Parses a conversation_model path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)/conversationModels/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - @staticmethod def conversation_profile_path( project: str, diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversations/async_client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversations/async_client.py index 94b91994a310..1fda16f92477 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversations/async_client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversations/async_client.py @@ -97,10 +97,6 @@ class ConversationsAsyncClient: parse_ces_tool_path = staticmethod(ConversationsClient.parse_ces_tool_path) conversation_path = staticmethod(ConversationsClient.conversation_path) parse_conversation_path = staticmethod(ConversationsClient.parse_conversation_path) - conversation_model_path = staticmethod(ConversationsClient.conversation_model_path) - parse_conversation_model_path = staticmethod( - ConversationsClient.parse_conversation_model_path - ) conversation_profile_path = staticmethod( ConversationsClient.conversation_profile_path ) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversations/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversations/client.py index 26338abd2790..b6afb1fb0531 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversations/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversations/client.py @@ -337,28 +337,6 @@ def parse_conversation_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} - @staticmethod - def conversation_model_path( - project: str, - location: str, - conversation_model: str, - ) -> str: - """Returns a fully-qualified conversation_model string.""" - return "projects/{project}/locations/{location}/conversationModels/{conversation_model}".format( - project=project, - location=location, - conversation_model=conversation_model, - ) - - @staticmethod - def parse_conversation_model_path(path: str) -> Dict[str, str]: - """Parses a conversation_model path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)/conversationModels/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - @staticmethod def conversation_profile_path( project: str, diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/async_client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/async_client.py index 487652cc40cd..2bc6844d9aab 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/async_client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/async_client.py @@ -1084,8 +1084,14 @@ def request_generator(): 1. If the input was set to streaming audio, the first one or more messages contain recognition_result. Each recognition_result represents a more complete - transcript of what the user said. The last - recognition_result has is_final set to true. + transcript of what the user said. When a user + speaks multiple sentences, the API will emit + multiple messages where is_final = true. Each time + the system detects a distinct pause or completed + thought, it locks in that segment, marks it + is_final = true, and then immediately starts a new + recognition cycle for the next sentence on the + same stream. 2. In virtual agent stage: if enable_partial_automated_agent_reply is true, the diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/client.py index 2f312a715d16..48932a52d078 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/client.py @@ -1716,8 +1716,14 @@ def request_generator(): 1. If the input was set to streaming audio, the first one or more messages contain recognition_result. Each recognition_result represents a more complete - transcript of what the user said. The last - recognition_result has is_final set to true. + transcript of what the user said. When a user + speaks multiple sentences, the API will emit + multiple messages where is_final = true. Each time + the system detects a distinct pause or completed + thought, it locks in that segment, marks it + is_final = true, and then immediately starts a new + recognition cycle for the next sentence on the + same stream. 2. In virtual agent stage: if enable_partial_automated_agent_reply is true, the diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/__init__.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/__init__.py index 4f2e47e121b6..2ac08d2586ab 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/__init__.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/__init__.py @@ -120,6 +120,7 @@ NotificationConfig, SetSuggestionFeatureConfigOperationMetadata, SetSuggestionFeatureConfigRequest, + SipConfig, UpdateConversationProfileRequest, ) from .document import ( @@ -468,6 +469,7 @@ "NotificationConfig", "SetSuggestionFeatureConfigOperationMetadata", "SetSuggestionFeatureConfigRequest", + "SipConfig", "UpdateConversationProfileRequest", "CreateDocumentRequest", "DeleteDocumentRequest", diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/audio_config.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/audio_config.py index 78b398238e49..84d54b30c9d1 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/audio_config.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/audio_config.py @@ -256,7 +256,7 @@ class OutputAudioEncoding(proto.Enum): samples (Linear PCM). Audio content returned as LINEAR16 also contains a WAV header. OUTPUT_AUDIO_ENCODING_MP3 (2): - MP3 audio at 32kbps. + MP3 audio at 64kbps. OUTPUT_AUDIO_ENCODING_MP3_64_KBPS (4): MP3 audio at 64kbps. OUTPUT_AUDIO_ENCODING_OGG_OPUS (3): diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/ces_app.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/ces_app.py index a808025e9572..fcc18599e199 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/ces_app.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/ces_app.py @@ -32,6 +32,8 @@ class CesAppSpec(proto.Message): r"""Spec of CES app that the generator can choose from. + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + Attributes: ces_app (str): Optional. Format: @@ -39,6 +41,20 @@ class CesAppSpec(proto.Message): confirmation_requirement (google.cloud.dialogflow_v2beta1.types.Tool.ConfirmationRequirement): Optional. Indicates whether the app requires human confirmation. + proactive_enabled (bool): + Optional. Only applicable for CompanionAgent. Indicates + whether the ces app is enabled in proactive mode. At least + one of ``proactive_enabled`` or ``reactive_enabled`` should + be true; otherwise, the ces app will be ignored. + + This field is a member of `oneof`_ ``_proactive_enabled``. + reactive_enabled (bool): + Optional. Only applicable for CompanionAgent. Indicates + whether the ces app is enabled in reactive mode. At least + one of ``proactive_enabled`` or ``reactive_enabled`` should + be true; otherwise, the ces app will be ignored. + + This field is a member of `oneof`_ ``_reactive_enabled``. """ ces_app: str = proto.Field( @@ -50,6 +66,16 @@ class CesAppSpec(proto.Message): number=2, enum=tool.Tool.ConfirmationRequirement, ) + proactive_enabled: bool = proto.Field( + proto.BOOL, + number=3, + optional=True, + ) + reactive_enabled: bool = proto.Field( + proto.BOOL, + number=4, + optional=True, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/conversation.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/conversation.py index 1829f5f34195..e55fbb023042 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/conversation.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/conversation.py @@ -1771,12 +1771,18 @@ class AnswerType(proto.Enum): The answer is from generative model. INTENT (3): The answer is from intent matching. + PLAYBOOK (4): + The answer is from Playbook. + EVENT (5): + The answer is from event. """ ANSWER_TYPE_UNSPECIFIED = 0 FAQ = 1 GENERATIVE = 2 INTENT = 3 + PLAYBOOK = 4 + EVENT = 5 class AnswerSource(proto.Message): r"""The sources of the answers. diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/conversation_profile.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/conversation_profile.py index 86bc6437d975..582b2ff40abd 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/conversation_profile.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/conversation_profile.py @@ -33,6 +33,7 @@ "HumanAgentHandoffConfig", "NotificationConfig", "LoggingConfig", + "SipConfig", "ListConversationProfilesRequest", "ListConversationProfilesResponse", "GetConversationProfileRequest", @@ -110,6 +111,8 @@ class ConversationProfile(proto.Message): languages. This should be a `BCP-47 `__ language tag. Example: "en-US". + sip_config (google.cloud.dialogflow_v2beta1.types.SipConfig): + Optional. Configuration for SIP connections. time_zone (str): The time zone of this conversational profile from the `time zone database `__, e.g., @@ -194,6 +197,11 @@ class ConversationProfile(proto.Message): proto.STRING, number=10, ) + sip_config: "SipConfig" = proto.Field( + proto.MESSAGE, + number=16, + message="SipConfig", + ) time_zone: str = proto.Field( proto.STRING, number=14, @@ -214,7 +222,8 @@ class AutomatedAgentConfig(proto.Message): Attributes: agent (str): - Required. ID of the Dialogflow agent environment to use. + Required. The resource name of the Dialogflow agent + environment to use. This project needs to either be the same project as the conversation or you need to grant @@ -335,6 +344,20 @@ class SuggestionFeatureConfig(proto.Message): rai_settings (google.cloud.dialogflow_v2beta1.types.RaiSettings): Optional. Settings for Responsible AI checks. Supported features: KNOWLEDGE_ASSIST + suggestion_trigger_event (google.cloud.dialogflow_v2beta1.types.TriggerEvent): + Optional. The trigger event for suggestion. If unspecified, + it will be ``CUSTOMER_MESSAGE``. Supported features: + KNOWLEDGE_ASSIST For KNOWLEDGE_ASSIST, these four trigger + events are supported: + + 1. TRIGGER_EVENT_UNSPECIFIED + 2. END_OF_UTTERANCE + 3. CUSTOMER_MESSAGE + 4. AGENT_MESSAGE + disable_query_search_context (bool): + Optional. If true, disable appending available search + context to the search query. Supported features: + KNOWLEDGE_ASSIST suggestion_trigger_settings (google.cloud.dialogflow_v2beta1.types.HumanAgentAssistantConfig.SuggestionTriggerSettings): Settings of suggestion trigger. @@ -342,8 +365,6 @@ class SuggestionFeatureConfig(proto.Message): DIALOGFLOW_ASSIST will use this field. query_config (google.cloud.dialogflow_v2beta1.types.HumanAgentAssistantConfig.SuggestionQueryConfig): Configs of query. - conversation_model_config (google.cloud.dialogflow_v2beta1.types.HumanAgentAssistantConfig.ConversationModelConfig): - Configs of custom conversation model. conversation_process_config (google.cloud.dialogflow_v2beta1.types.HumanAgentAssistantConfig.ConversationProcessConfig): Configs for processing conversation. """ @@ -382,6 +403,15 @@ class SuggestionFeatureConfig(proto.Message): number=19, message=generator.RaiSettings, ) + suggestion_trigger_event: generator.TriggerEvent = proto.Field( + proto.ENUM, + number=20, + enum=generator.TriggerEvent, + ) + disable_query_search_context: bool = proto.Field( + proto.BOOL, + number=21, + ) suggestion_trigger_settings: "HumanAgentAssistantConfig.SuggestionTriggerSettings" = proto.Field( proto.MESSAGE, number=10, @@ -392,11 +422,6 @@ class SuggestionFeatureConfig(proto.Message): number=6, message="HumanAgentAssistantConfig.SuggestionQueryConfig", ) - conversation_model_config: "HumanAgentAssistantConfig.ConversationModelConfig" = proto.Field( - proto.MESSAGE, - number=7, - message="HumanAgentAssistantConfig.ConversationModelConfig", - ) conversation_process_config: "HumanAgentAssistantConfig.ConversationProcessConfig" = proto.Field( proto.MESSAGE, number=8, @@ -769,40 +794,6 @@ class SectionType(proto.Enum): number=9, ) - class ConversationModelConfig(proto.Message): - r"""Custom conversation models used in agent assist feature. - - Supported feature: ARTICLE_SUGGESTION, SMART_COMPOSE, SMART_REPLY, - CONVERSATION_SUMMARIZATION. - - Attributes: - model (str): - Conversation model resource name. Format: - ``projects//conversationModels/``. - baseline_model_version (str): - Version of current baseline model. It will be ignored if - [model][google.cloud.dialogflow.v2beta1.HumanAgentAssistantConfig.ConversationModelConfig.model] - is set. Valid versions are: - - - Article Suggestion baseline model: - - - 0.9 - - 1.0 (default) - - - Summarization baseline model: - - - 1.0 - """ - - model: str = proto.Field( - proto.STRING, - number=1, - ) - baseline_model_version: str = proto.Field( - proto.STRING, - number=8, - ) - class ConversationProcessConfig(proto.Message): r"""Config to process conversation. @@ -1078,6 +1069,67 @@ class LoggingConfig(proto.Message): ) +class SipConfig(proto.Message): + r"""Defines the SIP configuration. + + Attributes: + create_conversation_on_the_fly (bool): + Asks Dialogflow Telephony to create the + conversation provided in the SIP header on the + fly when the call comes in. + inactive_start (bool): + Starts the conversation with inactive SDP + directives + max_audio_recording_duration (google.protobuf.duration_pb2.Duration): + Max duration for audio recording. + Overrides the default value of 15 min. + Max value is 8 hours. + allow_virtual_agent_interaction (bool): + Allows interactions with a Dialogflow virtual + agent even if the call is connected for SIPREC + purposes. + keep_conversation_running (bool): + Keeps the conversation running even if the + call is disconnected. + copy_inbound_call_leg_headers (MutableSequence[str]): + List of inbound call leg headers to be copied + to outbound call legs created later. + ignore_reinvite_media_direction (bool): + Ignores any media direction in the reINVITE + SDP offer. Reuse the previous media direction. + """ + + create_conversation_on_the_fly: bool = proto.Field( + proto.BOOL, + number=1, + ) + inactive_start: bool = proto.Field( + proto.BOOL, + number=3, + ) + max_audio_recording_duration: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=4, + message=duration_pb2.Duration, + ) + allow_virtual_agent_interaction: bool = proto.Field( + proto.BOOL, + number=5, + ) + keep_conversation_running: bool = proto.Field( + proto.BOOL, + number=6, + ) + copy_inbound_call_leg_headers: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=8, + ) + ignore_reinvite_media_direction: bool = proto.Field( + proto.BOOL, + number=9, + ) + + class ListConversationProfilesRequest(proto.Message): r"""The request message for [ConversationProfiles.ListConversationProfiles][google.cloud.dialogflow.v2beta1.ConversationProfiles.ListConversationProfiles]. diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/participant.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/participant.py index ae291df18bc9..f390755708ef 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/participant.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/participant.py @@ -154,8 +154,8 @@ class Participant(proto.Message): 2. If you set this field in [AnalyzeContent][google.cloud.dialogflow.v2beta1.AnalyzeContentRequest.obfuscated_external_user_id] - or - [StreamingAnalyzeContent][google.cloud.dialogflow.v2beta1.StreamingAnalyzeContentRequest.obfuscated_external_user_id], + or [StreamingAnalyzeContent] + [google.cloud.dialogflow.v2beta1.StreamingAnalyzeContentRequest.obfuscated_external_user_id], Dialogflow will update [Participant.obfuscated_external_user_id][google.cloud.dialogflow.v2beta1.Participant.obfuscated_external_user_id]. @@ -169,6 +169,12 @@ class Participant(proto.Message): it to provide personalized smart reply suggestions for this user. + Additionally, to link an escalated Virtual Agent + conversation with its corresponding Agent Assist + conversation for analytics, this field in Agent Assist + conversations should be populated to indicate the user id of + the ``END_USER`` participant in the escalated conversation. + Note: - Please never pass raw user ids to Dialogflow. Always @@ -1443,8 +1449,12 @@ class StreamingAnalyzeContentResponse(proto.Message): 1. If the input was set to streaming audio, the first one or more messages contain ``recognition_result``. Each ``recognition_result`` represents a more complete transcript of - what the user said. The last ``recognition_result`` has - ``is_final`` set to ``true``. + what the user said. When a user speaks multiple sentences, the + API will emit multiple messages where ``is_final = true``. Each + time the system detects a distinct pause or completed thought, it + locks in that segment, marks it ``is_final = true``, and then + immediately starts a new recognition cycle for the next sentence + on the same stream. 2. In virtual agent stage: if ``enable_partial_automated_agent_reply`` is true, the following N @@ -2897,6 +2907,11 @@ class SuggestKnowledgeAssistResponse(proto.Message): [SuggestKnowledgeAssistRequest.context_size][google.cloud.dialogflow.v2beta1.SuggestKnowledgeAssistRequest.context_size] field in the request if there are fewer messages in the conversation. + additional_suggested_query_results (MutableSequence[google.cloud.dialogflow_v2beta1.types.KnowledgeAssistAnswer.AdditionalSuggestedQueryResult]): + Optional. The list of additional suggested + queries based on the context. This is used for + the cases when we want to generate multiple + queries for a single request. """ knowledge_assist_answer: "KnowledgeAssistAnswer" = proto.Field( @@ -2912,6 +2927,13 @@ class SuggestKnowledgeAssistResponse(proto.Message): proto.INT32, number=3, ) + additional_suggested_query_results: MutableSequence[ + "KnowledgeAssistAnswer.AdditionalSuggestedQueryResult" + ] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message="KnowledgeAssistAnswer.AdditionalSuggestedQueryResult", + ) class IngestedContextReferenceDebugInfo(proto.Message): @@ -3074,6 +3096,10 @@ class KnowledgeAssistDebugInfo(proto.Message): search knowledge. service_latency (google.cloud.dialogflow_v2beta1.types.ServiceLatency): The latency of the service. + query_generation_debug_info (google.cloud.dialogflow_v2beta1.types.KnowledgeAssistDebugInfo.QueryGenerationDebugInfo): + Token usage metadata for query generation. + ces_debug_info (google.protobuf.struct_pb2.Struct): + Debug information from CES runtime API. """ class QueryGenerationFailureReason(proto.Enum): @@ -3280,6 +3306,33 @@ class KnowledgeAssistBehavior(proto.Message): number=18, ) + class QueryGenerationDebugInfo(proto.Message): + r"""Token usage metadata for query generation. + + Attributes: + prompt_token_count (int): + The total number of tokens in the prompt. + candidates_token_count (int): + The total number of tokens in the generated + candidates. + total_token_count (int): + The total number of tokens for the entire + request. + """ + + prompt_token_count: int = proto.Field( + proto.INT32, + number=1, + ) + candidates_token_count: int = proto.Field( + proto.INT32, + number=2, + ) + total_token_count: int = proto.Field( + proto.INT32, + number=3, + ) + query_generation_failure_reason: QueryGenerationFailureReason = proto.Field( proto.ENUM, number=1, @@ -3312,6 +3365,16 @@ class KnowledgeAssistBehavior(proto.Message): number=6, message="ServiceLatency", ) + query_generation_debug_info: QueryGenerationDebugInfo = proto.Field( + proto.MESSAGE, + number=7, + message=QueryGenerationDebugInfo, + ) + ces_debug_info: struct_pb2.Struct = proto.Field( + proto.MESSAGE, + number=8, + message=struct_pb2.Struct, + ) class KnowledgeAssistAnswer(proto.Message): @@ -3340,12 +3403,66 @@ class SuggestedQuery(proto.Message): Attributes: query_text (str): Suggested query text. + search_contexts (MutableSequence[google.cloud.dialogflow_v2beta1.types.KnowledgeAssistAnswer.SuggestedQuery.SearchContext]): + Optional. The search contexts for the query. """ + class SearchContext(proto.Message): + r"""Search context is information useful for knowledge search that helps + enrich the query. Example: search_context { key: "application name" + value: "DesignApp" } + + Attributes: + key (str): + Optional. The key of the search context, e.g. + "application name". + value (str): + Optional. The value of the search context, + e.g. "DesignApp". + """ + + key: str = proto.Field( + proto.STRING, + number=1, + ) + value: str = proto.Field( + proto.STRING, + number=2, + ) + query_text: str = proto.Field( proto.STRING, number=1, ) + search_contexts: MutableSequence[ + "KnowledgeAssistAnswer.SuggestedQuery.SearchContext" + ] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message="KnowledgeAssistAnswer.SuggestedQuery.SearchContext", + ) + + class AdditionalSuggestedQueryResult(proto.Message): + r"""Represents a single suggested query result. + + Attributes: + suggested_query (google.cloud.dialogflow_v2beta1.types.KnowledgeAssistAnswer.SuggestedQuery): + Output only. The suggested query based on the + context. + answer_record (str): + Output only. The name of the answer record. Format: + ``projects//locations//answerRecords/`` + """ + + suggested_query: "KnowledgeAssistAnswer.SuggestedQuery" = proto.Field( + proto.MESSAGE, + number=1, + message="KnowledgeAssistAnswer.SuggestedQuery", + ) + answer_record: str = proto.Field( + proto.STRING, + number=5, + ) class KnowledgeAnswer(proto.Message): r"""Represents an answer from Knowledge. Currently supports FAQ @@ -3369,6 +3486,16 @@ class KnowledgeAnswer(proto.Message): generative_source (google.cloud.dialogflow_v2beta1.types.KnowledgeAssistAnswer.KnowledgeAnswer.GenerativeSource): Populated if the prediction was Generative. + This field is a member of `oneof`_ ``source``. + playbook_source (google.cloud.dialogflow_v2beta1.types.KnowledgeAssistAnswer.KnowledgeAnswer.GenerativeSource): + Populated if the prediction was from + Playbook. + + This field is a member of `oneof`_ ``source``. + event_source (google.cloud.dialogflow_v2beta1.types.KnowledgeAssistAnswer.KnowledgeAnswer.EventSource): + Populated if the prediction was from an + event. + This field is a member of `oneof`_ ``source``. """ @@ -3434,6 +3561,28 @@ class Snippet(proto.Message): message="KnowledgeAssistAnswer.KnowledgeAnswer.GenerativeSource.Snippet", ) + class EventSource(proto.Message): + r"""Details about source of Event answer. + + Attributes: + event (str): + Name of the triggered event. + snippets (google.cloud.dialogflow_v2beta1.types.KnowledgeAssistAnswer.KnowledgeAnswer.GenerativeSource): + Sources used in event fulfillment. + """ + + event: str = proto.Field( + proto.STRING, + number=1, + ) + snippets: "KnowledgeAssistAnswer.KnowledgeAnswer.GenerativeSource" = ( + proto.Field( + proto.MESSAGE, + number=2, + message="KnowledgeAssistAnswer.KnowledgeAnswer.GenerativeSource", + ) + ) + answer_text: str = proto.Field( proto.STRING, number=1, @@ -3452,6 +3601,20 @@ class Snippet(proto.Message): message="KnowledgeAssistAnswer.KnowledgeAnswer.GenerativeSource", ) ) + playbook_source: "KnowledgeAssistAnswer.KnowledgeAnswer.GenerativeSource" = ( + proto.Field( + proto.MESSAGE, + number=7, + oneof="source", + message="KnowledgeAssistAnswer.KnowledgeAnswer.GenerativeSource", + ) + ) + event_source: "KnowledgeAssistAnswer.KnowledgeAnswer.EventSource" = proto.Field( + proto.MESSAGE, + number=8, + oneof="source", + message="KnowledgeAssistAnswer.KnowledgeAnswer.EventSource", + ) suggested_query: SuggestedQuery = proto.Field( proto.MESSAGE, @@ -3622,8 +3785,55 @@ class TurnInput(proto.Message): virtual_agent_parameters (google.protobuf.struct_pb2.Struct): Optional. Parameters to be passed to the virtual agent. + tool_responses (google.cloud.dialogflow_v2beta1.types.BidiStreamingAnalyzeContentRequest.TurnInput.ToolResponses): + Optional. The tool responses from the client. """ + class ToolResponse(proto.Message): + r"""The execution result of a specific tool from the client. + + Attributes: + id (str): + Required. The matching ID of the tool call + the response is for. + tool (str): + Required. The identifier of the tool that got + executed. + response (google.protobuf.struct_pb2.Struct): + Optional. The tool execution result in JSON + object format. + """ + + id: str = proto.Field( + proto.STRING, + number=1, + ) + tool: str = proto.Field( + proto.STRING, + number=2, + ) + response: struct_pb2.Struct = proto.Field( + proto.MESSAGE, + number=3, + message=struct_pb2.Struct, + ) + + class ToolResponses(proto.Message): + r"""The tool responses from the client. + + Attributes: + tool_responses (MutableSequence[google.cloud.dialogflow_v2beta1.types.BidiStreamingAnalyzeContentRequest.TurnInput.ToolResponse]): + Optional. The list of tool responses. + """ + + tool_responses: MutableSequence[ + "BidiStreamingAnalyzeContentRequest.TurnInput.ToolResponse" + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="BidiStreamingAnalyzeContentRequest.TurnInput.ToolResponse", + ) + text: str = proto.Field( proto.STRING, number=1, @@ -3644,6 +3854,13 @@ class TurnInput(proto.Message): number=4, message=struct_pb2.Struct, ) + tool_responses: "BidiStreamingAnalyzeContentRequest.TurnInput.ToolResponses" = ( + proto.Field( + proto.MESSAGE, + number=5, + message="BidiStreamingAnalyzeContentRequest.TurnInput.ToolResponses", + ) + ) class Input(proto.Message): r"""Input for the conversation. @@ -3733,6 +3950,10 @@ class BidiStreamingAnalyzeContentResponse(proto.Message): turn_complete (google.cloud.dialogflow_v2beta1.types.BidiStreamingAnalyzeContentResponse.TurnComplete): Indicate that the turn is complete. + This field is a member of `oneof`_ ``response``. + tool_calls (google.cloud.dialogflow_v2beta1.types.BidiStreamingAnalyzeContentResponse.ToolCalls): + The tool calls from the server. + This field is a member of `oneof`_ ``response``. """ @@ -3742,6 +3963,49 @@ class BargeInSignal(proto.Message): class TurnComplete(proto.Message): r"""Indicate that the turn is complete.""" + class ToolCall(proto.Message): + r"""Request for the client to execute the specified tool. + + Attributes: + id (str): + The unique identifier of the tool call. + tool (str): + The identifier of the tool to execute. + args (google.protobuf.struct_pb2.Struct): + The input parameters and values for the tool + in JSON object format. + """ + + id: str = proto.Field( + proto.STRING, + number=1, + ) + tool: str = proto.Field( + proto.STRING, + number=2, + ) + args: struct_pb2.Struct = proto.Field( + proto.MESSAGE, + number=3, + message=struct_pb2.Struct, + ) + + class ToolCalls(proto.Message): + r"""The tool calls from the server. + + Attributes: + tool_calls (MutableSequence[google.cloud.dialogflow_v2beta1.types.BidiStreamingAnalyzeContentResponse.ToolCall]): + The list of tool calls. + """ + + tool_calls: MutableSequence["BidiStreamingAnalyzeContentResponse.ToolCall"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=1, + message="BidiStreamingAnalyzeContentResponse.ToolCall", + ) + ) + recognition_result: session.StreamingRecognitionResult = proto.Field( proto.MESSAGE, number=1, @@ -3766,6 +4030,12 @@ class TurnComplete(proto.Message): oneof="response", message=TurnComplete, ) + tool_calls: ToolCalls = proto.Field( + proto.MESSAGE, + number=5, + oneof="response", + message=ToolCalls, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/session.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/session.py index bc8249911dec..f70d908473bd 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/session.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/session.py @@ -1133,20 +1133,23 @@ class StreamingRecognitionResult(proto.Message): finalized transcript values received for the series of results. In the following example, single utterance is enabled. In the case - where single utterance is not enabled, result 7 would not occur. + where single utterance is not enabled, result 8 would not occur. :: - Num | transcript | message_type | is_final - --- | ----------------------- | ----------------------- | -------- - 1 | "tube" | TRANSCRIPT | false - 2 | "to be a" | TRANSCRIPT | false - 3 | "to be" | TRANSCRIPT | false - 4 | "to be or not to be" | TRANSCRIPT | true - 5 | "that's" | TRANSCRIPT | false - 6 | "that is | TRANSCRIPT | false - 7 | unset | END_OF_SINGLE_UTTERANCE | unset - 8 | " that is the question" | TRANSCRIPT | true + Num | transcript | message_type | is_final + --- | ------------------------ | ----------------------- | -------- + 1 | "tube" | TRANSCRIPT | false + 2 | "to be a" | TRANSCRIPT | false + 3 | "to be" | TRANSCRIPT | false + 4 | "to be or not to be" | TRANSCRIPT | true + 5 | "that's" | TRANSCRIPT | false + 6 | "that is | TRANSCRIPT | false + 7 | " that is the question" | TRANSCRIPT | true + 8 | unset | END_OF_SINGLE_UTTERANCE | unset + 9 | ". Whether 'tis nobler" | TRANSCRIPT | true + 10 | " in the mind" | TRANSCRIPT | false + 11 | " in the mind to suffer" | TRANSCRIPT | true Concatenating the finalized transcripts with ``is_final`` set to true, the complete utterance becomes "to be or not to be that is the diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_conversation_profiles.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_conversation_profiles.py index 8fcb9d5ff37e..84ce6f6f8f40 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_conversation_profiles.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_conversation_profiles.py @@ -6427,6 +6427,8 @@ def test_create_conversation_profile_rest_call_success(request_type): {"category": 1, "sensitivity_level": 1} ] }, + "suggestion_trigger_event": 1, + "disable_query_search_context": True, "suggestion_trigger_settings": { "no_smalltalk": True, "only_end_user": True, @@ -6500,6 +6502,18 @@ def test_create_conversation_profile_rest_call_success(request_type): "use_timeout_based_endpointing": True, }, "language_code": "language_code_value", + "sip_config": { + "create_conversation_on_the_fly": True, + "inactive_start": True, + "max_audio_recording_duration": {}, + "allow_virtual_agent_interaction": True, + "keep_conversation_running": True, + "copy_inbound_call_leg_headers": [ + "copy_inbound_call_leg_headers_value1", + "copy_inbound_call_leg_headers_value2", + ], + "ignore_reinvite_media_direction": True, + }, "time_zone": "time_zone_value", "security_settings": "security_settings_value", "tts_config": { @@ -6771,6 +6785,8 @@ def test_update_conversation_profile_rest_call_success(request_type): {"category": 1, "sensitivity_level": 1} ] }, + "suggestion_trigger_event": 1, + "disable_query_search_context": True, "suggestion_trigger_settings": { "no_smalltalk": True, "only_end_user": True, @@ -6844,6 +6860,18 @@ def test_update_conversation_profile_rest_call_success(request_type): "use_timeout_based_endpointing": True, }, "language_code": "language_code_value", + "sip_config": { + "create_conversation_on_the_fly": True, + "inactive_start": True, + "max_audio_recording_duration": {}, + "allow_virtual_agent_interaction": True, + "keep_conversation_running": True, + "copy_inbound_call_leg_headers": [ + "copy_inbound_call_leg_headers_value1", + "copy_inbound_call_leg_headers_value2", + ], + "ignore_reinvite_media_direction": True, + }, "time_zone": "time_zone_value", "security_settings": "security_settings_value", "tts_config": { diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_conversations.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_conversations.py index b310d6344eec..92a163cf1646 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_conversations.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_conversations.py @@ -8173,6 +8173,8 @@ def test_create_conversation_rest_call_success(request_type): {"category": 1, "sensitivity_level": 1} ] }, + "suggestion_trigger_event": 1, + "disable_query_search_context": True, "suggestion_trigger_settings": { "no_smalltalk": True, "only_end_user": True, @@ -8251,6 +8253,18 @@ def test_create_conversation_rest_call_success(request_type): "use_timeout_based_endpointing": True, }, "language_code": "language_code_value", + "sip_config": { + "create_conversation_on_the_fly": True, + "inactive_start": True, + "max_audio_recording_duration": {}, + "allow_virtual_agent_interaction": True, + "keep_conversation_running": True, + "copy_inbound_call_leg_headers": [ + "copy_inbound_call_leg_headers_value1", + "copy_inbound_call_leg_headers_value2", + ], + "ignore_reinvite_media_direction": True, + }, "time_zone": "time_zone_value", "security_settings": "security_settings_value", "tts_config": { diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_generator_evaluations.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_generator_evaluations.py index 7acad967389f..34f5193451c2 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_generator_evaluations.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_generator_evaluations.py @@ -4387,7 +4387,12 @@ def test_create_generator_evaluation_rest_call_success(request_type): {"ces_tool": "ces_tool_value", "confirmation_requirement": 1} ], "ces_app_specs": [ - {"ces_app": "ces_app_value", "confirmation_requirement": 1} + { + "ces_app": "ces_app_value", + "confirmation_requirement": 1, + "proactive_enabled": True, + "reactive_enabled": True, + } ], }, "summarization_metrics": { diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_generators.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_generators.py index cea141ce8c18..16f56aa5c772 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_generators.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_generators.py @@ -4692,7 +4692,14 @@ def test_create_generator_rest_call_success(request_type): "ces_tool_specs": [ {"ces_tool": "ces_tool_value", "confirmation_requirement": 1} ], - "ces_app_specs": [{"ces_app": "ces_app_value", "confirmation_requirement": 1}], + "ces_app_specs": [ + { + "ces_app": "ces_app_value", + "confirmation_requirement": 1, + "proactive_enabled": True, + "reactive_enabled": True, + } + ], } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -5414,7 +5421,14 @@ def test_update_generator_rest_call_success(request_type): "ces_tool_specs": [ {"ces_tool": "ces_tool_value", "confirmation_requirement": 1} ], - "ces_app_specs": [{"ces_app": "ces_app_value", "confirmation_requirement": 1}], + "ces_app_specs": [ + { + "ces_app": "ces_app_value", + "confirmation_requirement": 1, + "proactive_enabled": True, + "reactive_enabled": True, + } + ], } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_conversation_profiles.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_conversation_profiles.py index b29df5e84d29..3ede2db70088 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_conversation_profiles.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_conversation_profiles.py @@ -6453,6 +6453,8 @@ def test_create_conversation_profile_rest_call_success(request_type): {"category": 1, "sensitivity_level": 1} ] }, + "suggestion_trigger_event": 1, + "disable_query_search_context": True, "suggestion_trigger_settings": { "no_small_talk": True, "only_end_user": True, @@ -6481,10 +6483,6 @@ def test_create_conversation_profile_rest_call_success(request_type): "sections": {"section_types": [1]}, "context_size": 1311, }, - "conversation_model_config": { - "model": "model_value", - "baseline_model_version": "baseline_model_version_value", - }, "conversation_process_config": {"recent_sentences_count": 2352}, } ], @@ -6526,6 +6524,18 @@ def test_create_conversation_profile_rest_call_success(request_type): "use_timeout_based_endpointing": True, }, "language_code": "language_code_value", + "sip_config": { + "create_conversation_on_the_fly": True, + "inactive_start": True, + "max_audio_recording_duration": {}, + "allow_virtual_agent_interaction": True, + "keep_conversation_running": True, + "copy_inbound_call_leg_headers": [ + "copy_inbound_call_leg_headers_value1", + "copy_inbound_call_leg_headers_value2", + ], + "ignore_reinvite_media_direction": True, + }, "time_zone": "time_zone_value", "security_settings": "security_settings_value", "tts_config": { @@ -6800,6 +6810,8 @@ def test_update_conversation_profile_rest_call_success(request_type): {"category": 1, "sensitivity_level": 1} ] }, + "suggestion_trigger_event": 1, + "disable_query_search_context": True, "suggestion_trigger_settings": { "no_small_talk": True, "only_end_user": True, @@ -6828,10 +6840,6 @@ def test_update_conversation_profile_rest_call_success(request_type): "sections": {"section_types": [1]}, "context_size": 1311, }, - "conversation_model_config": { - "model": "model_value", - "baseline_model_version": "baseline_model_version_value", - }, "conversation_process_config": {"recent_sentences_count": 2352}, } ], @@ -6873,6 +6881,18 @@ def test_update_conversation_profile_rest_call_success(request_type): "use_timeout_based_endpointing": True, }, "language_code": "language_code_value", + "sip_config": { + "create_conversation_on_the_fly": True, + "inactive_start": True, + "max_audio_recording_duration": {}, + "allow_virtual_agent_interaction": True, + "keep_conversation_running": True, + "copy_inbound_call_leg_headers": [ + "copy_inbound_call_leg_headers_value1", + "copy_inbound_call_leg_headers_value2", + ], + "ignore_reinvite_media_direction": True, + }, "time_zone": "time_zone_value", "security_settings": "security_settings_value", "tts_config": { @@ -8460,37 +8480,9 @@ def test_parse_agent_path(): assert expected == actual -def test_conversation_model_path(): - project = "whelk" - location = "octopus" - conversation_model = "oyster" - expected = "projects/{project}/locations/{location}/conversationModels/{conversation_model}".format( - project=project, - location=location, - conversation_model=conversation_model, - ) - actual = ConversationProfilesClient.conversation_model_path( - project, location, conversation_model - ) - assert expected == actual - - -def test_parse_conversation_model_path(): - expected = { - "project": "nudibranch", - "location": "cuttlefish", - "conversation_model": "mussel", - } - path = ConversationProfilesClient.conversation_model_path(**expected) - - # Check that the path construction is reversible. - actual = ConversationProfilesClient.parse_conversation_model_path(path) - assert expected == actual - - def test_conversation_profile_path(): - project = "winkle" - conversation_profile = "nautilus" + project = "whelk" + conversation_profile = "octopus" expected = "projects/{project}/conversationProfiles/{conversation_profile}".format( project=project, conversation_profile=conversation_profile, @@ -8503,8 +8495,8 @@ def test_conversation_profile_path(): def test_parse_conversation_profile_path(): expected = { - "project": "scallop", - "conversation_profile": "abalone", + "project": "oyster", + "conversation_profile": "nudibranch", } path = ConversationProfilesClient.conversation_profile_path(**expected) @@ -8514,9 +8506,9 @@ def test_parse_conversation_profile_path(): def test_cx_security_settings_path(): - project = "squid" - location = "clam" - security_settings = "whelk" + project = "cuttlefish" + location = "mussel" + security_settings = "winkle" expected = "projects/{project}/locations/{location}/securitySettings/{security_settings}".format( project=project, location=location, @@ -8530,9 +8522,9 @@ def test_cx_security_settings_path(): def test_parse_cx_security_settings_path(): expected = { - "project": "octopus", - "location": "oyster", - "security_settings": "nudibranch", + "project": "nautilus", + "location": "scallop", + "security_settings": "abalone", } path = ConversationProfilesClient.cx_security_settings_path(**expected) @@ -8542,9 +8534,9 @@ def test_parse_cx_security_settings_path(): def test_document_path(): - project = "cuttlefish" - knowledge_base = "mussel" - document = "winkle" + project = "squid" + knowledge_base = "clam" + document = "whelk" expected = "projects/{project}/knowledgeBases/{knowledge_base}/documents/{document}".format( project=project, knowledge_base=knowledge_base, @@ -8556,9 +8548,9 @@ def test_document_path(): def test_parse_document_path(): expected = { - "project": "nautilus", - "knowledge_base": "scallop", - "document": "abalone", + "project": "octopus", + "knowledge_base": "oyster", + "document": "nudibranch", } path = ConversationProfilesClient.document_path(**expected) @@ -8568,9 +8560,9 @@ def test_parse_document_path(): def test_generator_path(): - project = "squid" - location = "clam" - generator = "whelk" + project = "cuttlefish" + location = "mussel" + generator = "winkle" expected = "projects/{project}/locations/{location}/generators/{generator}".format( project=project, location=location, @@ -8582,9 +8574,9 @@ def test_generator_path(): def test_parse_generator_path(): expected = { - "project": "octopus", - "location": "oyster", - "generator": "nudibranch", + "project": "nautilus", + "location": "scallop", + "generator": "abalone", } path = ConversationProfilesClient.generator_path(**expected) @@ -8594,8 +8586,8 @@ def test_parse_generator_path(): def test_knowledge_base_path(): - project = "cuttlefish" - knowledge_base = "mussel" + project = "squid" + knowledge_base = "clam" expected = "projects/{project}/knowledgeBases/{knowledge_base}".format( project=project, knowledge_base=knowledge_base, @@ -8606,8 +8598,8 @@ def test_knowledge_base_path(): def test_parse_knowledge_base_path(): expected = { - "project": "winkle", - "knowledge_base": "nautilus", + "project": "whelk", + "knowledge_base": "octopus", } path = ConversationProfilesClient.knowledge_base_path(**expected) @@ -8617,9 +8609,9 @@ def test_parse_knowledge_base_path(): def test_phrase_set_path(): - project = "scallop" - location = "abalone" - phrase_set = "squid" + project = "oyster" + location = "nudibranch" + phrase_set = "cuttlefish" expected = "projects/{project}/locations/{location}/phraseSets/{phrase_set}".format( project=project, location=location, @@ -8631,9 +8623,9 @@ def test_phrase_set_path(): def test_parse_phrase_set_path(): expected = { - "project": "clam", - "location": "whelk", - "phrase_set": "octopus", + "project": "mussel", + "location": "winkle", + "phrase_set": "nautilus", } path = ConversationProfilesClient.phrase_set_path(**expected) @@ -8643,7 +8635,7 @@ def test_parse_phrase_set_path(): def test_common_billing_account_path(): - billing_account = "oyster" + billing_account = "scallop" expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -8653,7 +8645,7 @@ def test_common_billing_account_path(): def test_parse_common_billing_account_path(): expected = { - "billing_account": "nudibranch", + "billing_account": "abalone", } path = ConversationProfilesClient.common_billing_account_path(**expected) @@ -8663,7 +8655,7 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): - folder = "cuttlefish" + folder = "squid" expected = "folders/{folder}".format( folder=folder, ) @@ -8673,7 +8665,7 @@ def test_common_folder_path(): def test_parse_common_folder_path(): expected = { - "folder": "mussel", + "folder": "clam", } path = ConversationProfilesClient.common_folder_path(**expected) @@ -8683,7 +8675,7 @@ def test_parse_common_folder_path(): def test_common_organization_path(): - organization = "winkle" + organization = "whelk" expected = "organizations/{organization}".format( organization=organization, ) @@ -8693,7 +8685,7 @@ def test_common_organization_path(): def test_parse_common_organization_path(): expected = { - "organization": "nautilus", + "organization": "octopus", } path = ConversationProfilesClient.common_organization_path(**expected) @@ -8703,7 +8695,7 @@ def test_parse_common_organization_path(): def test_common_project_path(): - project = "scallop" + project = "oyster" expected = "projects/{project}".format( project=project, ) @@ -8713,7 +8705,7 @@ def test_common_project_path(): def test_parse_common_project_path(): expected = { - "project": "abalone", + "project": "nudibranch", } path = ConversationProfilesClient.common_project_path(**expected) @@ -8723,8 +8715,8 @@ def test_parse_common_project_path(): def test_common_location_path(): - project = "squid" - location = "clam" + project = "cuttlefish" + location = "mussel" expected = "projects/{project}/locations/{location}".format( project=project, location=location, @@ -8735,8 +8727,8 @@ def test_common_location_path(): def test_parse_common_location_path(): expected = { - "project": "whelk", - "location": "octopus", + "project": "winkle", + "location": "nautilus", } path = ConversationProfilesClient.common_location_path(**expected) diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_conversations.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_conversations.py index ffb3f09588bb..c5ac9023248c 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_conversations.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_conversations.py @@ -8769,6 +8769,8 @@ def test_create_conversation_rest_call_success(request_type): {"category": 1, "sensitivity_level": 1} ] }, + "suggestion_trigger_event": 1, + "disable_query_search_context": True, "suggestion_trigger_settings": { "no_small_talk": True, "only_end_user": True, @@ -8800,10 +8802,6 @@ def test_create_conversation_rest_call_success(request_type): "sections": {"section_types": [1]}, "context_size": 1311, }, - "conversation_model_config": { - "model": "model_value", - "baseline_model_version": "baseline_model_version_value", - }, "conversation_process_config": { "recent_sentences_count": 2352 }, @@ -8847,6 +8845,18 @@ def test_create_conversation_rest_call_success(request_type): "use_timeout_based_endpointing": True, }, "language_code": "language_code_value", + "sip_config": { + "create_conversation_on_the_fly": True, + "inactive_start": True, + "max_audio_recording_duration": {}, + "allow_virtual_agent_interaction": True, + "keep_conversation_running": True, + "copy_inbound_call_leg_headers": [ + "copy_inbound_call_leg_headers_value1", + "copy_inbound_call_leg_headers_value2", + ], + "ignore_reinvite_media_direction": True, + }, "time_zone": "time_zone_value", "security_settings": "security_settings_value", "tts_config": { @@ -11719,37 +11729,9 @@ def test_parse_conversation_path(): assert expected == actual -def test_conversation_model_path(): - project = "squid" - location = "clam" - conversation_model = "whelk" - expected = "projects/{project}/locations/{location}/conversationModels/{conversation_model}".format( - project=project, - location=location, - conversation_model=conversation_model, - ) - actual = ConversationsClient.conversation_model_path( - project, location, conversation_model - ) - assert expected == actual - - -def test_parse_conversation_model_path(): - expected = { - "project": "octopus", - "location": "oyster", - "conversation_model": "nudibranch", - } - path = ConversationsClient.conversation_model_path(**expected) - - # Check that the path construction is reversible. - actual = ConversationsClient.parse_conversation_model_path(path) - assert expected == actual - - def test_conversation_profile_path(): - project = "cuttlefish" - conversation_profile = "mussel" + project = "squid" + conversation_profile = "clam" expected = "projects/{project}/conversationProfiles/{conversation_profile}".format( project=project, conversation_profile=conversation_profile, @@ -11762,8 +11744,8 @@ def test_conversation_profile_path(): def test_parse_conversation_profile_path(): expected = { - "project": "winkle", - "conversation_profile": "nautilus", + "project": "whelk", + "conversation_profile": "octopus", } path = ConversationsClient.conversation_profile_path(**expected) @@ -11773,9 +11755,9 @@ def test_parse_conversation_profile_path(): def test_cx_security_settings_path(): - project = "scallop" - location = "abalone" - security_settings = "squid" + project = "oyster" + location = "nudibranch" + security_settings = "cuttlefish" expected = "projects/{project}/locations/{location}/securitySettings/{security_settings}".format( project=project, location=location, @@ -11789,9 +11771,9 @@ def test_cx_security_settings_path(): def test_parse_cx_security_settings_path(): expected = { - "project": "clam", - "location": "whelk", - "security_settings": "octopus", + "project": "mussel", + "location": "winkle", + "security_settings": "nautilus", } path = ConversationsClient.cx_security_settings_path(**expected) @@ -11801,10 +11783,10 @@ def test_parse_cx_security_settings_path(): def test_data_store_path(): - project = "oyster" - location = "nudibranch" - collection = "cuttlefish" - data_store = "mussel" + project = "scallop" + location = "abalone" + collection = "squid" + data_store = "clam" expected = "projects/{project}/locations/{location}/collections/{collection}/dataStores/{data_store}".format( project=project, location=location, @@ -11819,10 +11801,10 @@ def test_data_store_path(): def test_parse_data_store_path(): expected = { - "project": "winkle", - "location": "nautilus", - "collection": "scallop", - "data_store": "abalone", + "project": "whelk", + "location": "octopus", + "collection": "oyster", + "data_store": "nudibranch", } path = ConversationsClient.data_store_path(**expected) @@ -11832,9 +11814,9 @@ def test_parse_data_store_path(): def test_document_path(): - project = "squid" - knowledge_base = "clam" - document = "whelk" + project = "cuttlefish" + knowledge_base = "mussel" + document = "winkle" expected = "projects/{project}/knowledgeBases/{knowledge_base}/documents/{document}".format( project=project, knowledge_base=knowledge_base, @@ -11846,9 +11828,9 @@ def test_document_path(): def test_parse_document_path(): expected = { - "project": "octopus", - "knowledge_base": "oyster", - "document": "nudibranch", + "project": "nautilus", + "knowledge_base": "scallop", + "document": "abalone", } path = ConversationsClient.document_path(**expected) @@ -11858,9 +11840,9 @@ def test_parse_document_path(): def test_generator_path(): - project = "cuttlefish" - location = "mussel" - generator = "winkle" + project = "squid" + location = "clam" + generator = "whelk" expected = "projects/{project}/locations/{location}/generators/{generator}".format( project=project, location=location, @@ -11872,9 +11854,9 @@ def test_generator_path(): def test_parse_generator_path(): expected = { - "project": "nautilus", - "location": "scallop", - "generator": "abalone", + "project": "octopus", + "location": "oyster", + "generator": "nudibranch", } path = ConversationsClient.generator_path(**expected) @@ -11884,8 +11866,8 @@ def test_parse_generator_path(): def test_knowledge_base_path(): - project = "squid" - knowledge_base = "clam" + project = "cuttlefish" + knowledge_base = "mussel" expected = "projects/{project}/knowledgeBases/{knowledge_base}".format( project=project, knowledge_base=knowledge_base, @@ -11896,8 +11878,8 @@ def test_knowledge_base_path(): def test_parse_knowledge_base_path(): expected = { - "project": "whelk", - "knowledge_base": "octopus", + "project": "winkle", + "knowledge_base": "nautilus", } path = ConversationsClient.knowledge_base_path(**expected) @@ -11907,9 +11889,9 @@ def test_parse_knowledge_base_path(): def test_message_path(): - project = "oyster" - conversation = "nudibranch" - message = "cuttlefish" + project = "scallop" + conversation = "abalone" + message = "squid" expected = ( "projects/{project}/conversations/{conversation}/messages/{message}".format( project=project, @@ -11923,9 +11905,9 @@ def test_message_path(): def test_parse_message_path(): expected = { - "project": "mussel", - "conversation": "winkle", - "message": "nautilus", + "project": "clam", + "conversation": "whelk", + "message": "octopus", } path = ConversationsClient.message_path(**expected) @@ -11935,9 +11917,9 @@ def test_parse_message_path(): def test_phrase_set_path(): - project = "scallop" - location = "abalone" - phrase_set = "squid" + project = "oyster" + location = "nudibranch" + phrase_set = "cuttlefish" expected = "projects/{project}/locations/{location}/phraseSets/{phrase_set}".format( project=project, location=location, @@ -11949,9 +11931,9 @@ def test_phrase_set_path(): def test_parse_phrase_set_path(): expected = { - "project": "clam", - "location": "whelk", - "phrase_set": "octopus", + "project": "mussel", + "location": "winkle", + "phrase_set": "nautilus", } path = ConversationsClient.phrase_set_path(**expected) @@ -11961,9 +11943,9 @@ def test_parse_phrase_set_path(): def test_tool_path(): - project = "oyster" - location = "nudibranch" - tool = "cuttlefish" + project = "scallop" + location = "abalone" + tool = "squid" expected = "projects/{project}/locations/{location}/tools/{tool}".format( project=project, location=location, @@ -11975,9 +11957,9 @@ def test_tool_path(): def test_parse_tool_path(): expected = { - "project": "mussel", - "location": "winkle", - "tool": "nautilus", + "project": "clam", + "location": "whelk", + "tool": "octopus", } path = ConversationsClient.tool_path(**expected) @@ -11987,10 +11969,10 @@ def test_parse_tool_path(): def test_toolset_path(): - project = "scallop" - location = "abalone" - app = "squid" - toolset = "clam" + project = "oyster" + location = "nudibranch" + app = "cuttlefish" + toolset = "mussel" expected = ( "projects/{project}/locations/{location}/apps/{app}/toolsets/{toolset}".format( project=project, @@ -12005,10 +11987,10 @@ def test_toolset_path(): def test_parse_toolset_path(): expected = { - "project": "whelk", - "location": "octopus", - "app": "oyster", - "toolset": "nudibranch", + "project": "winkle", + "location": "nautilus", + "app": "scallop", + "toolset": "abalone", } path = ConversationsClient.toolset_path(**expected) @@ -12018,7 +12000,7 @@ def test_parse_toolset_path(): def test_common_billing_account_path(): - billing_account = "cuttlefish" + billing_account = "squid" expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -12028,7 +12010,7 @@ def test_common_billing_account_path(): def test_parse_common_billing_account_path(): expected = { - "billing_account": "mussel", + "billing_account": "clam", } path = ConversationsClient.common_billing_account_path(**expected) @@ -12038,7 +12020,7 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): - folder = "winkle" + folder = "whelk" expected = "folders/{folder}".format( folder=folder, ) @@ -12048,7 +12030,7 @@ def test_common_folder_path(): def test_parse_common_folder_path(): expected = { - "folder": "nautilus", + "folder": "octopus", } path = ConversationsClient.common_folder_path(**expected) @@ -12058,7 +12040,7 @@ def test_parse_common_folder_path(): def test_common_organization_path(): - organization = "scallop" + organization = "oyster" expected = "organizations/{organization}".format( organization=organization, ) @@ -12068,7 +12050,7 @@ def test_common_organization_path(): def test_parse_common_organization_path(): expected = { - "organization": "abalone", + "organization": "nudibranch", } path = ConversationsClient.common_organization_path(**expected) @@ -12078,7 +12060,7 @@ def test_parse_common_organization_path(): def test_common_project_path(): - project = "squid" + project = "cuttlefish" expected = "projects/{project}".format( project=project, ) @@ -12088,7 +12070,7 @@ def test_common_project_path(): def test_parse_common_project_path(): expected = { - "project": "clam", + "project": "mussel", } path = ConversationsClient.common_project_path(**expected) @@ -12098,8 +12080,8 @@ def test_parse_common_project_path(): def test_common_location_path(): - project = "whelk" - location = "octopus" + project = "winkle" + location = "nautilus" expected = "projects/{project}/locations/{location}".format( project=project, location=location, @@ -12110,8 +12092,8 @@ def test_common_location_path(): def test_parse_common_location_path(): expected = { - "project": "oyster", - "location": "nudibranch", + "project": "scallop", + "location": "abalone", } path = ConversationsClient.common_location_path(**expected) diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_generator_evaluations.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_generator_evaluations.py index da302d150b96..5b2357794325 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_generator_evaluations.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_generator_evaluations.py @@ -4387,7 +4387,12 @@ def test_create_generator_evaluation_rest_call_success(request_type): {"ces_tool": "ces_tool_value", "confirmation_requirement": 1} ], "ces_app_specs": [ - {"ces_app": "ces_app_value", "confirmation_requirement": 1} + { + "ces_app": "ces_app_value", + "confirmation_requirement": 1, + "proactive_enabled": True, + "reactive_enabled": True, + } ], }, "summarization_metrics": { diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_generators.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_generators.py index 7a52a6dd9119..01dff22d1b68 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_generators.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_generators.py @@ -4696,7 +4696,14 @@ def test_create_generator_rest_call_success(request_type): "ces_tool_specs": [ {"ces_tool": "ces_tool_value", "confirmation_requirement": 1} ], - "ces_app_specs": [{"ces_app": "ces_app_value", "confirmation_requirement": 1}], + "ces_app_specs": [ + { + "ces_app": "ces_app_value", + "confirmation_requirement": 1, + "proactive_enabled": True, + "reactive_enabled": True, + } + ], } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -5418,7 +5425,14 @@ def test_update_generator_rest_call_success(request_type): "ces_tool_specs": [ {"ces_tool": "ces_tool_value", "confirmation_requirement": 1} ], - "ces_app_specs": [{"ces_app": "ces_app_value", "confirmation_requirement": 1}], + "ces_app_specs": [ + { + "ces_app": "ces_app_value", + "confirmation_requirement": 1, + "proactive_enabled": True, + "reactive_enabled": True, + } + ], } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency diff --git a/packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/acl_config_service.rst b/packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/acl_config_service.rst new file mode 100644 index 000000000000..80fb59f726db --- /dev/null +++ b/packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/acl_config_service.rst @@ -0,0 +1,6 @@ +AclConfigService +---------------------------------- + +.. automodule:: google.cloud.discoveryengine_v1beta.services.acl_config_service + :members: + :inherited-members: diff --git a/packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/assistant_service.rst b/packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/assistant_service.rst new file mode 100644 index 000000000000..e617f2cf2bff --- /dev/null +++ b/packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/assistant_service.rst @@ -0,0 +1,10 @@ +AssistantService +---------------------------------- + +.. automodule:: google.cloud.discoveryengine_v1beta.services.assistant_service + :members: + :inherited-members: + +.. automodule:: google.cloud.discoveryengine_v1beta.services.assistant_service.pagers + :members: + :inherited-members: diff --git a/packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/cmek_config_service.rst b/packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/cmek_config_service.rst new file mode 100644 index 000000000000..6085286a93cb --- /dev/null +++ b/packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/cmek_config_service.rst @@ -0,0 +1,6 @@ +CmekConfigService +----------------------------------- + +.. automodule:: google.cloud.discoveryengine_v1beta.services.cmek_config_service + :members: + :inherited-members: diff --git a/packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/identity_mapping_store_service.rst b/packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/identity_mapping_store_service.rst new file mode 100644 index 000000000000..8bd083af7104 --- /dev/null +++ b/packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/identity_mapping_store_service.rst @@ -0,0 +1,10 @@ +IdentityMappingStoreService +--------------------------------------------- + +.. automodule:: google.cloud.discoveryengine_v1beta.services.identity_mapping_store_service + :members: + :inherited-members: + +.. automodule:: google.cloud.discoveryengine_v1beta.services.identity_mapping_store_service.pagers + :members: + :inherited-members: diff --git a/packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/license_config_service.rst b/packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/license_config_service.rst new file mode 100644 index 000000000000..2a63b2ae18be --- /dev/null +++ b/packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/license_config_service.rst @@ -0,0 +1,10 @@ +LicenseConfigService +-------------------------------------- + +.. automodule:: google.cloud.discoveryengine_v1beta.services.license_config_service + :members: + :inherited-members: + +.. automodule:: google.cloud.discoveryengine_v1beta.services.license_config_service.pagers + :members: + :inherited-members: diff --git a/packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/services_.rst b/packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/services_.rst index 82a6c914645c..b4a2af983c26 100644 --- a/packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/services_.rst +++ b/packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/services_.rst @@ -3,6 +3,9 @@ Services for Google Cloud Discoveryengine v1beta API .. toctree:: :maxdepth: 2 + acl_config_service + assistant_service + cmek_config_service completion_service control_service conversational_search_service @@ -11,6 +14,8 @@ Services for Google Cloud Discoveryengine v1beta API engine_service evaluation_service grounded_generation_service + identity_mapping_store_service + license_config_service project_service rank_service recommendation_service @@ -23,3 +28,5 @@ Services for Google Cloud Discoveryengine v1beta API session_service site_search_engine_service user_event_service + user_license_service + user_store_service diff --git a/packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/user_license_service.rst b/packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/user_license_service.rst new file mode 100644 index 000000000000..e38ec518bb9b --- /dev/null +++ b/packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/user_license_service.rst @@ -0,0 +1,10 @@ +UserLicenseService +------------------------------------ + +.. automodule:: google.cloud.discoveryengine_v1beta.services.user_license_service + :members: + :inherited-members: + +.. automodule:: google.cloud.discoveryengine_v1beta.services.user_license_service.pagers + :members: + :inherited-members: diff --git a/packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/user_store_service.rst b/packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/user_store_service.rst new file mode 100644 index 000000000000..158a414acac0 --- /dev/null +++ b/packages/google-cloud-discoveryengine/docs/discoveryengine_v1beta/user_store_service.rst @@ -0,0 +1,6 @@ +UserStoreService +---------------------------------- + +.. automodule:: google.cloud.discoveryengine_v1beta.services.user_store_service + :members: + :inherited-members: diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine/__init__.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine/__init__.py index 0f1477713e9c..b1096f22b83b 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine/__init__.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine/__init__.py @@ -18,6 +18,24 @@ __version__ = package_version.__version__ +from google.cloud.discoveryengine_v1beta.services.acl_config_service.async_client import ( + AclConfigServiceAsyncClient, +) +from google.cloud.discoveryengine_v1beta.services.acl_config_service.client import ( + AclConfigServiceClient, +) +from google.cloud.discoveryengine_v1beta.services.assistant_service.async_client import ( + AssistantServiceAsyncClient, +) +from google.cloud.discoveryengine_v1beta.services.assistant_service.client import ( + AssistantServiceClient, +) +from google.cloud.discoveryengine_v1beta.services.cmek_config_service.async_client import ( + CmekConfigServiceAsyncClient, +) +from google.cloud.discoveryengine_v1beta.services.cmek_config_service.client import ( + CmekConfigServiceClient, +) from google.cloud.discoveryengine_v1beta.services.completion_service.async_client import ( CompletionServiceAsyncClient, ) @@ -66,6 +84,18 @@ from google.cloud.discoveryengine_v1beta.services.grounded_generation_service.client import ( GroundedGenerationServiceClient, ) +from google.cloud.discoveryengine_v1beta.services.identity_mapping_store_service.async_client import ( + IdentityMappingStoreServiceAsyncClient, +) +from google.cloud.discoveryengine_v1beta.services.identity_mapping_store_service.client import ( + IdentityMappingStoreServiceClient, +) +from google.cloud.discoveryengine_v1beta.services.license_config_service.async_client import ( + LicenseConfigServiceAsyncClient, +) +from google.cloud.discoveryengine_v1beta.services.license_config_service.client import ( + LicenseConfigServiceClient, +) from google.cloud.discoveryengine_v1beta.services.project_service.async_client import ( ProjectServiceAsyncClient, ) @@ -138,18 +168,72 @@ from google.cloud.discoveryengine_v1beta.services.user_event_service.client import ( UserEventServiceClient, ) +from google.cloud.discoveryengine_v1beta.services.user_license_service.async_client import ( + UserLicenseServiceAsyncClient, +) +from google.cloud.discoveryengine_v1beta.services.user_license_service.client import ( + UserLicenseServiceClient, +) +from google.cloud.discoveryengine_v1beta.services.user_store_service.async_client import ( + UserStoreServiceAsyncClient, +) +from google.cloud.discoveryengine_v1beta.services.user_store_service.client import ( + UserStoreServiceClient, +) +from google.cloud.discoveryengine_v1beta.types.acl_config import AclConfig +from google.cloud.discoveryengine_v1beta.types.acl_config_service import ( + GetAclConfigRequest, + UpdateAclConfigRequest, +) +from google.cloud.discoveryengine_v1beta.types.agent_gateway_setting import ( + AgentGatewaySetting, +) from google.cloud.discoveryengine_v1beta.types.answer import Answer +from google.cloud.discoveryengine_v1beta.types.assist_answer import ( + AssistAnswer, + AssistantContent, + AssistantGroundedContent, +) +from google.cloud.discoveryengine_v1beta.types.assistant import Assistant +from google.cloud.discoveryengine_v1beta.types.assistant_service import ( + AssistUserMetadata, + CreateAssistantRequest, + DeleteAssistantRequest, + GetAssistantRequest, + ListAssistantsRequest, + ListAssistantsResponse, + StreamAssistRequest, + StreamAssistResponse, + UpdateAssistantRequest, +) from google.cloud.discoveryengine_v1beta.types.chunk import Chunk +from google.cloud.discoveryengine_v1beta.types.cmek_config_service import ( + CmekConfig, + DeleteCmekConfigMetadata, + DeleteCmekConfigRequest, + GetCmekConfigRequest, + ListCmekConfigsRequest, + ListCmekConfigsResponse, + SingleRegionKey, + UpdateCmekConfigMetadata, + UpdateCmekConfigRequest, +) from google.cloud.discoveryengine_v1beta.types.common import ( CustomAttribute, DoubleList, EmbeddingConfig, + HealthcareFhirConfig, + IdpConfig, IndustryVertical, Interval, + Principal, SearchAddOn, + SearchLinkPromotion, SearchTier, SearchUseCase, SolutionType, + SubscriptionTerm, + SubscriptionTier, UserInfo, ) from google.cloud.discoveryengine_v1beta.types.completion import ( @@ -161,6 +245,8 @@ AdvancedCompleteQueryResponse, CompleteQueryRequest, CompleteQueryResponse, + RemoveSuggestionRequest, + RemoveSuggestionResponse, ) from google.cloud.discoveryengine_v1beta.types.control import Condition, Control from google.cloud.discoveryengine_v1beta.types.control_service import ( @@ -201,6 +287,7 @@ CustomTuningModel, ) from google.cloud.discoveryengine_v1beta.types.data_store import ( + AdvancedSiteSearchConfig, DataStore, LanguageInfo, NaturalLanguageQueryUnderstandingConfig, @@ -259,10 +346,13 @@ ListEvaluationsRequest, ListEvaluationsResponse, ) +from google.cloud.discoveryengine_v1beta.types.feedback import Feedback from google.cloud.discoveryengine_v1beta.types.grounded_generation_service import ( CheckGroundingRequest, CheckGroundingResponse, CheckGroundingSpec, + Citation, + CitationMetadata, GenerateGroundedContentRequest, GenerateGroundedContentResponse, GroundedGenerationContent, @@ -272,6 +362,24 @@ GroundingConfig, GroundingFact, ) +from google.cloud.discoveryengine_v1beta.types.identity_mapping_store import ( + IdentityMappingEntry, + IdentityMappingStore, +) +from google.cloud.discoveryengine_v1beta.types.identity_mapping_store_service import ( + CreateIdentityMappingStoreRequest, + DeleteIdentityMappingStoreMetadata, + DeleteIdentityMappingStoreRequest, + GetIdentityMappingStoreRequest, + IdentityMappingEntryOperationMetadata, + ImportIdentityMappingsRequest, + ImportIdentityMappingsResponse, + ListIdentityMappingsRequest, + ListIdentityMappingsResponse, + ListIdentityMappingStoresRequest, + ListIdentityMappingStoresResponse, + PurgeIdentityMappingsRequest, +) from google.cloud.discoveryengine_v1beta.types.import_config import ( AlloyDbSource, BigQuerySource, @@ -299,6 +407,19 @@ ImportUserEventsResponse, SpannerSource, ) +from google.cloud.discoveryengine_v1beta.types.license_config import LicenseConfig +from google.cloud.discoveryengine_v1beta.types.license_config_service import ( + CreateLicenseConfigRequest, + DistributeLicenseConfigRequest, + DistributeLicenseConfigResponse, + GetLicenseConfigRequest, + ListLicenseConfigsRequest, + ListLicenseConfigsResponse, + RetractLicenseConfigRequest, + RetractLicenseConfigResponse, + UpdateLicenseConfigRequest, +) +from google.cloud.discoveryengine_v1beta.types.logging import ObservabilityConfig from google.cloud.discoveryengine_v1beta.types.project import Project from google.cloud.discoveryengine_v1beta.types.project_service import ( ProvisionProjectMetadata, @@ -328,6 +449,7 @@ RecommendRequest, RecommendResponse, ) +from google.cloud.discoveryengine_v1beta.types.safety import HarmCategory, SafetyRating from google.cloud.discoveryengine_v1beta.types.sample_query import SampleQuery from google.cloud.discoveryengine_v1beta.types.sample_query_service import ( CreateSampleQueryRequest, @@ -369,8 +491,13 @@ TrainCustomModelRequest, TrainCustomModelResponse, ) -from google.cloud.discoveryengine_v1beta.types.serving_config import ServingConfig +from google.cloud.discoveryengine_v1beta.types.serving_config import ( + AnswerGenerationSpec, + ServingConfig, +) from google.cloud.discoveryengine_v1beta.types.serving_config_service import ( + CreateServingConfigRequest, + DeleteServingConfigRequest, GetServingConfigRequest, ListServingConfigsRequest, ListServingConfigsResponse, @@ -432,8 +559,32 @@ CollectUserEventRequest, WriteUserEventRequest, ) +from google.cloud.discoveryengine_v1beta.types.user_license import ( + LicenseConfigUsageStats, + UserLicense, +) +from google.cloud.discoveryengine_v1beta.types.user_license_service import ( + BatchUpdateUserLicensesMetadata, + BatchUpdateUserLicensesRequest, + BatchUpdateUserLicensesResponse, + ListLicenseConfigsUsageStatsRequest, + ListLicenseConfigsUsageStatsResponse, + ListUserLicensesRequest, + ListUserLicensesResponse, +) +from google.cloud.discoveryengine_v1beta.types.user_store import UserStore +from google.cloud.discoveryengine_v1beta.types.user_store_service import ( + GetUserStoreRequest, + UpdateUserStoreRequest, +) __all__ = ( + "AclConfigServiceClient", + "AclConfigServiceAsyncClient", + "AssistantServiceClient", + "AssistantServiceAsyncClient", + "CmekConfigServiceClient", + "CmekConfigServiceAsyncClient", "CompletionServiceClient", "CompletionServiceAsyncClient", "ControlServiceClient", @@ -450,6 +601,10 @@ "EvaluationServiceAsyncClient", "GroundedGenerationServiceClient", "GroundedGenerationServiceAsyncClient", + "IdentityMappingStoreServiceClient", + "IdentityMappingStoreServiceAsyncClient", + "LicenseConfigServiceClient", + "LicenseConfigServiceAsyncClient", "ProjectServiceClient", "ProjectServiceAsyncClient", "RankServiceClient", @@ -474,24 +629,62 @@ "SiteSearchEngineServiceAsyncClient", "UserEventServiceClient", "UserEventServiceAsyncClient", + "UserLicenseServiceClient", + "UserLicenseServiceAsyncClient", + "UserStoreServiceClient", + "UserStoreServiceAsyncClient", + "AclConfig", + "GetAclConfigRequest", + "UpdateAclConfigRequest", + "AgentGatewaySetting", "Answer", + "AssistAnswer", + "AssistantContent", + "AssistantGroundedContent", + "Assistant", + "AssistUserMetadata", + "CreateAssistantRequest", + "DeleteAssistantRequest", + "GetAssistantRequest", + "ListAssistantsRequest", + "ListAssistantsResponse", + "StreamAssistRequest", + "StreamAssistResponse", + "UpdateAssistantRequest", "Chunk", + "CmekConfig", + "DeleteCmekConfigMetadata", + "DeleteCmekConfigRequest", + "GetCmekConfigRequest", + "ListCmekConfigsRequest", + "ListCmekConfigsResponse", + "SingleRegionKey", + "UpdateCmekConfigMetadata", + "UpdateCmekConfigRequest", "CustomAttribute", "DoubleList", "EmbeddingConfig", + "HealthcareFhirConfig", + "IdpConfig", "Interval", + "Principal", + "SearchLinkPromotion", "UserInfo", "IndustryVertical", "SearchAddOn", "SearchTier", "SearchUseCase", "SolutionType", + "SubscriptionTerm", + "SubscriptionTier", "CompletionSuggestion", "SuggestionDenyListEntry", "AdvancedCompleteQueryRequest", "AdvancedCompleteQueryResponse", "CompleteQueryRequest", "CompleteQueryResponse", + "RemoveSuggestionRequest", + "RemoveSuggestionResponse", "Condition", "Control", "CreateControlRequest", @@ -523,6 +716,7 @@ "UpdateConversationRequest", "UpdateSessionRequest", "CustomTuningModel", + "AdvancedSiteSearchConfig", "DataStore", "LanguageInfo", "NaturalLanguageQueryUnderstandingConfig", @@ -568,15 +762,32 @@ "ListEvaluationResultsResponse", "ListEvaluationsRequest", "ListEvaluationsResponse", + "Feedback", "CheckGroundingRequest", "CheckGroundingResponse", "CheckGroundingSpec", + "Citation", + "CitationMetadata", "GenerateGroundedContentRequest", "GenerateGroundedContentResponse", "GroundedGenerationContent", "FactChunk", "GroundingConfig", "GroundingFact", + "IdentityMappingEntry", + "IdentityMappingStore", + "CreateIdentityMappingStoreRequest", + "DeleteIdentityMappingStoreMetadata", + "DeleteIdentityMappingStoreRequest", + "GetIdentityMappingStoreRequest", + "IdentityMappingEntryOperationMetadata", + "ImportIdentityMappingsRequest", + "ImportIdentityMappingsResponse", + "ListIdentityMappingsRequest", + "ListIdentityMappingsResponse", + "ListIdentityMappingStoresRequest", + "ListIdentityMappingStoresResponse", + "PurgeIdentityMappingsRequest", "AlloyDbSource", "BigQuerySource", "BigtableOptions", @@ -602,6 +813,17 @@ "ImportUserEventsRequest", "ImportUserEventsResponse", "SpannerSource", + "LicenseConfig", + "CreateLicenseConfigRequest", + "DistributeLicenseConfigRequest", + "DistributeLicenseConfigResponse", + "GetLicenseConfigRequest", + "ListLicenseConfigsRequest", + "ListLicenseConfigsResponse", + "RetractLicenseConfigRequest", + "RetractLicenseConfigResponse", + "UpdateLicenseConfigRequest", + "ObservabilityConfig", "Project", "ProvisionProjectMetadata", "ProvisionProjectRequest", @@ -623,6 +845,8 @@ "RankResponse", "RecommendRequest", "RecommendResponse", + "SafetyRating", + "HarmCategory", "SampleQuery", "CreateSampleQueryRequest", "DeleteSampleQueryRequest", @@ -654,7 +878,10 @@ "TrainCustomModelMetadata", "TrainCustomModelRequest", "TrainCustomModelResponse", + "AnswerGenerationSpec", "ServingConfig", + "CreateServingConfigRequest", + "DeleteServingConfigRequest", "GetServingConfigRequest", "ListServingConfigsRequest", "ListServingConfigsResponse", @@ -708,4 +935,16 @@ "UserEvent", "CollectUserEventRequest", "WriteUserEventRequest", + "LicenseConfigUsageStats", + "UserLicense", + "BatchUpdateUserLicensesMetadata", + "BatchUpdateUserLicensesRequest", + "BatchUpdateUserLicensesResponse", + "ListLicenseConfigsUsageStatsRequest", + "ListLicenseConfigsUsageStatsResponse", + "ListUserLicensesRequest", + "ListUserLicensesResponse", + "UserStore", + "GetUserStoreRequest", + "UpdateUserStoreRequest", ) diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/__init__.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/__init__.py index 33ec2f3deebb..2da7de3c92ab 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/__init__.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/__init__.py @@ -23,6 +23,18 @@ from importlib import metadata +from .services.acl_config_service import ( + AclConfigServiceAsyncClient, + AclConfigServiceClient, +) +from .services.assistant_service import ( + AssistantServiceAsyncClient, + AssistantServiceClient, +) +from .services.cmek_config_service import ( + CmekConfigServiceAsyncClient, + CmekConfigServiceClient, +) from .services.completion_service import ( CompletionServiceAsyncClient, CompletionServiceClient, @@ -46,6 +58,14 @@ GroundedGenerationServiceAsyncClient, GroundedGenerationServiceClient, ) +from .services.identity_mapping_store_service import ( + IdentityMappingStoreServiceAsyncClient, + IdentityMappingStoreServiceClient, +) +from .services.license_config_service import ( + LicenseConfigServiceAsyncClient, + LicenseConfigServiceClient, +) from .services.project_service import ProjectServiceAsyncClient, ProjectServiceClient from .services.rank_service import RankServiceAsyncClient, RankServiceClient from .services.recommendation_service import ( @@ -79,18 +99,63 @@ UserEventServiceAsyncClient, UserEventServiceClient, ) +from .services.user_license_service import ( + UserLicenseServiceAsyncClient, + UserLicenseServiceClient, +) +from .services.user_store_service import ( + UserStoreServiceAsyncClient, + UserStoreServiceClient, +) +from .types.acl_config import AclConfig +from .types.acl_config_service import GetAclConfigRequest, UpdateAclConfigRequest +from .types.agent_gateway_setting import AgentGatewaySetting from .types.answer import Answer +from .types.assist_answer import ( + AssistAnswer, + AssistantContent, + AssistantGroundedContent, +) +from .types.assistant import Assistant +from .types.assistant_service import ( + AssistUserMetadata, + CreateAssistantRequest, + DeleteAssistantRequest, + GetAssistantRequest, + ListAssistantsRequest, + ListAssistantsResponse, + StreamAssistRequest, + StreamAssistResponse, + UpdateAssistantRequest, +) from .types.chunk import Chunk +from .types.cmek_config_service import ( + CmekConfig, + DeleteCmekConfigMetadata, + DeleteCmekConfigRequest, + GetCmekConfigRequest, + ListCmekConfigsRequest, + ListCmekConfigsResponse, + SingleRegionKey, + UpdateCmekConfigMetadata, + UpdateCmekConfigRequest, +) from .types.common import ( CustomAttribute, DoubleList, EmbeddingConfig, + HealthcareFhirConfig, + IdpConfig, IndustryVertical, Interval, + Principal, SearchAddOn, + SearchLinkPromotion, SearchTier, SearchUseCase, SolutionType, + SubscriptionTerm, + SubscriptionTier, UserInfo, ) from .types.completion import CompletionSuggestion, SuggestionDenyListEntry @@ -99,6 +164,8 @@ AdvancedCompleteQueryResponse, CompleteQueryRequest, CompleteQueryResponse, + RemoveSuggestionRequest, + RemoveSuggestionResponse, ) from .types.control import Condition, Control from .types.control_service import ( @@ -137,6 +204,7 @@ ) from .types.custom_tuning_model import CustomTuningModel from .types.data_store import ( + AdvancedSiteSearchConfig, DataStore, LanguageInfo, NaturalLanguageQueryUnderstandingConfig, @@ -190,15 +258,33 @@ ListEvaluationsRequest, ListEvaluationsResponse, ) +from .types.feedback import Feedback from .types.grounded_generation_service import ( CheckGroundingRequest, CheckGroundingResponse, CheckGroundingSpec, + Citation, + CitationMetadata, GenerateGroundedContentRequest, GenerateGroundedContentResponse, GroundedGenerationContent, ) from .types.grounding import FactChunk, GroundingConfig, GroundingFact +from .types.identity_mapping_store import IdentityMappingEntry, IdentityMappingStore +from .types.identity_mapping_store_service import ( + CreateIdentityMappingStoreRequest, + DeleteIdentityMappingStoreMetadata, + DeleteIdentityMappingStoreRequest, + GetIdentityMappingStoreRequest, + IdentityMappingEntryOperationMetadata, + ImportIdentityMappingsRequest, + ImportIdentityMappingsResponse, + ListIdentityMappingsRequest, + ListIdentityMappingsResponse, + ListIdentityMappingStoresRequest, + ListIdentityMappingStoresResponse, + PurgeIdentityMappingsRequest, +) from .types.import_config import ( AlloyDbSource, BigQuerySource, @@ -226,6 +312,19 @@ ImportUserEventsResponse, SpannerSource, ) +from .types.license_config import LicenseConfig +from .types.license_config_service import ( + CreateLicenseConfigRequest, + DistributeLicenseConfigRequest, + DistributeLicenseConfigResponse, + GetLicenseConfigRequest, + ListLicenseConfigsRequest, + ListLicenseConfigsResponse, + RetractLicenseConfigRequest, + RetractLicenseConfigResponse, + UpdateLicenseConfigRequest, +) +from .types.logging import ObservabilityConfig from .types.project import Project from .types.project_service import ProvisionProjectMetadata, ProvisionProjectRequest from .types.purge_config import ( @@ -245,6 +344,7 @@ ) from .types.rank_service import RankingRecord, RankRequest, RankResponse from .types.recommendation_service import RecommendRequest, RecommendResponse +from .types.safety import HarmCategory, SafetyRating from .types.sample_query import SampleQuery from .types.sample_query_service import ( CreateSampleQueryRequest, @@ -283,8 +383,10 @@ TrainCustomModelRequest, TrainCustomModelResponse, ) -from .types.serving_config import ServingConfig +from .types.serving_config import AnswerGenerationSpec, ServingConfig from .types.serving_config_service import ( + CreateServingConfigRequest, + DeleteServingConfigRequest, GetServingConfigRequest, ListServingConfigsRequest, ListServingConfigsResponse, @@ -343,6 +445,18 @@ UserEvent, ) from .types.user_event_service import CollectUserEventRequest, WriteUserEventRequest +from .types.user_license import LicenseConfigUsageStats, UserLicense +from .types.user_license_service import ( + BatchUpdateUserLicensesMetadata, + BatchUpdateUserLicensesRequest, + BatchUpdateUserLicensesResponse, + ListLicenseConfigsUsageStatsRequest, + ListLicenseConfigsUsageStatsResponse, + ListUserLicensesRequest, + ListUserLicensesResponse, +) +from .types.user_store import UserStore +from .types.user_store_service import GetUserStoreRequest, UpdateUserStoreRequest if hasattr(api_core, "check_python_version") and hasattr( api_core, "check_dependency_versions" @@ -428,6 +542,9 @@ def _get_version(dependency_name): ) __all__ = ( + "AclConfigServiceAsyncClient", + "AssistantServiceAsyncClient", + "CmekConfigServiceAsyncClient", "CompletionServiceAsyncClient", "ControlServiceAsyncClient", "ConversationalSearchServiceAsyncClient", @@ -436,6 +553,8 @@ def _get_version(dependency_name): "EngineServiceAsyncClient", "EvaluationServiceAsyncClient", "GroundedGenerationServiceAsyncClient", + "IdentityMappingStoreServiceAsyncClient", + "LicenseConfigServiceAsyncClient", "ProjectServiceAsyncClient", "RankServiceAsyncClient", "RecommendationServiceAsyncClient", @@ -448,17 +567,33 @@ def _get_version(dependency_name): "SessionServiceAsyncClient", "SiteSearchEngineServiceAsyncClient", "UserEventServiceAsyncClient", + "UserLicenseServiceAsyncClient", + "UserStoreServiceAsyncClient", + "AclConfig", + "AclConfigServiceClient", "AdvancedCompleteQueryRequest", "AdvancedCompleteQueryResponse", + "AdvancedSiteSearchConfig", + "AgentGatewaySetting", "AlloyDbSource", "Answer", + "AnswerGenerationSpec", "AnswerQueryRequest", "AnswerQueryResponse", + "AssistAnswer", + "AssistUserMetadata", + "Assistant", + "AssistantContent", + "AssistantGroundedContent", + "AssistantServiceClient", "BatchCreateTargetSiteMetadata", "BatchCreateTargetSitesRequest", "BatchCreateTargetSitesResponse", "BatchGetDocumentsMetadataRequest", "BatchGetDocumentsMetadataResponse", + "BatchUpdateUserLicensesMetadata", + "BatchUpdateUserLicensesRequest", + "BatchUpdateUserLicensesResponse", "BatchVerifyTargetSitesMetadata", "BatchVerifyTargetSitesRequest", "BatchVerifyTargetSitesResponse", @@ -469,7 +604,11 @@ def _get_version(dependency_name): "CheckGroundingResponse", "CheckGroundingSpec", "Chunk", + "Citation", + "CitationMetadata", "CloudSqlSource", + "CmekConfig", + "CmekConfigServiceClient", "CollectUserEventRequest", "CompleteQueryRequest", "CompleteQueryResponse", @@ -485,6 +624,7 @@ def _get_version(dependency_name): "ConversationalSearchServiceClient", "ConverseConversationRequest", "ConverseConversationResponse", + "CreateAssistantRequest", "CreateControlRequest", "CreateConversationRequest", "CreateDataStoreMetadata", @@ -494,10 +634,13 @@ def _get_version(dependency_name): "CreateEngineRequest", "CreateEvaluationMetadata", "CreateEvaluationRequest", + "CreateIdentityMappingStoreRequest", + "CreateLicenseConfigRequest", "CreateSampleQueryRequest", "CreateSampleQuerySetRequest", "CreateSchemaMetadata", "CreateSchemaRequest", + "CreateServingConfigRequest", "CreateSessionRequest", "CreateSitemapMetadata", "CreateSitemapRequest", @@ -507,6 +650,9 @@ def _get_version(dependency_name): "CustomTuningModel", "DataStore", "DataStoreServiceClient", + "DeleteAssistantRequest", + "DeleteCmekConfigMetadata", + "DeleteCmekConfigRequest", "DeleteControlRequest", "DeleteConversationRequest", "DeleteDataStoreMetadata", @@ -514,10 +660,13 @@ def _get_version(dependency_name): "DeleteDocumentRequest", "DeleteEngineMetadata", "DeleteEngineRequest", + "DeleteIdentityMappingStoreMetadata", + "DeleteIdentityMappingStoreRequest", "DeleteSampleQueryRequest", "DeleteSampleQuerySetRequest", "DeleteSchemaMetadata", "DeleteSchemaRequest", + "DeleteServingConfigRequest", "DeleteSessionRequest", "DeleteSitemapMetadata", "DeleteSitemapRequest", @@ -526,6 +675,8 @@ def _get_version(dependency_name): "DisableAdvancedSiteSearchMetadata", "DisableAdvancedSiteSearchRequest", "DisableAdvancedSiteSearchResponse", + "DistributeLicenseConfigRequest", + "DistributeLicenseConfigResponse", "Document", "DocumentInfo", "DocumentProcessingConfig", @@ -540,6 +691,7 @@ def _get_version(dependency_name): "Evaluation", "EvaluationServiceClient", "FactChunk", + "Feedback", "FetchDomainVerificationStatusRequest", "FetchDomainVerificationStatusResponse", "FetchSitemapsRequest", @@ -549,13 +701,18 @@ def _get_version(dependency_name): "GcsSource", "GenerateGroundedContentRequest", "GenerateGroundedContentResponse", + "GetAclConfigRequest", "GetAnswerRequest", + "GetAssistantRequest", + "GetCmekConfigRequest", "GetControlRequest", "GetConversationRequest", "GetDataStoreRequest", "GetDocumentRequest", "GetEngineRequest", "GetEvaluationRequest", + "GetIdentityMappingStoreRequest", + "GetLicenseConfigRequest", "GetSampleQueryRequest", "GetSampleQuerySetRequest", "GetSchemaRequest", @@ -563,10 +720,18 @@ def _get_version(dependency_name): "GetSessionRequest", "GetSiteSearchEngineRequest", "GetTargetSiteRequest", + "GetUserStoreRequest", "GroundedGenerationContent", "GroundedGenerationServiceClient", "GroundingConfig", "GroundingFact", + "HarmCategory", + "HealthcareFhirConfig", + "IdentityMappingEntry", + "IdentityMappingEntryOperationMetadata", + "IdentityMappingStore", + "IdentityMappingStoreServiceClient", + "IdpConfig", "ImportCompletionSuggestionsMetadata", "ImportCompletionSuggestionsRequest", "ImportCompletionSuggestionsResponse", @@ -574,6 +739,8 @@ def _get_version(dependency_name): "ImportDocumentsRequest", "ImportDocumentsResponse", "ImportErrorConfig", + "ImportIdentityMappingsRequest", + "ImportIdentityMappingsResponse", "ImportSampleQueriesMetadata", "ImportSampleQueriesRequest", "ImportSampleQueriesResponse", @@ -586,6 +753,13 @@ def _get_version(dependency_name): "IndustryVertical", "Interval", "LanguageInfo", + "LicenseConfig", + "LicenseConfigServiceClient", + "LicenseConfigUsageStats", + "ListAssistantsRequest", + "ListAssistantsResponse", + "ListCmekConfigsRequest", + "ListCmekConfigsResponse", "ListControlsRequest", "ListControlsResponse", "ListConversationsRequest", @@ -602,6 +776,14 @@ def _get_version(dependency_name): "ListEvaluationResultsResponse", "ListEvaluationsRequest", "ListEvaluationsResponse", + "ListIdentityMappingStoresRequest", + "ListIdentityMappingStoresResponse", + "ListIdentityMappingsRequest", + "ListIdentityMappingsResponse", + "ListLicenseConfigsRequest", + "ListLicenseConfigsResponse", + "ListLicenseConfigsUsageStatsRequest", + "ListLicenseConfigsUsageStatsResponse", "ListSampleQueriesRequest", "ListSampleQueriesResponse", "ListSampleQuerySetsRequest", @@ -614,11 +796,15 @@ def _get_version(dependency_name): "ListSessionsResponse", "ListTargetSitesRequest", "ListTargetSitesResponse", + "ListUserLicensesRequest", + "ListUserLicensesResponse", "MediaInfo", "NaturalLanguageQueryUnderstandingConfig", + "ObservabilityConfig", "PageInfo", "PanelInfo", "PauseEngineRequest", + "Principal", "Project", "ProjectServiceClient", "ProvisionProjectMetadata", @@ -630,6 +816,7 @@ def _get_version(dependency_name): "PurgeDocumentsRequest", "PurgeDocumentsResponse", "PurgeErrorConfig", + "PurgeIdentityMappingsRequest", "PurgeSuggestionDenyListEntriesMetadata", "PurgeSuggestionDenyListEntriesRequest", "PurgeSuggestionDenyListEntriesResponse", @@ -648,8 +835,13 @@ def _get_version(dependency_name): "RecrawlUrisMetadata", "RecrawlUrisRequest", "RecrawlUrisResponse", + "RemoveSuggestionRequest", + "RemoveSuggestionResponse", "Reply", "ResumeEngineRequest", + "RetractLicenseConfigRequest", + "RetractLicenseConfigResponse", + "SafetyRating", "SampleQuery", "SampleQueryServiceClient", "SampleQuerySet", @@ -658,6 +850,7 @@ def _get_version(dependency_name): "SchemaServiceClient", "SearchAddOn", "SearchInfo", + "SearchLinkPromotion", "SearchRequest", "SearchResponse", "SearchServiceClient", @@ -668,12 +861,17 @@ def _get_version(dependency_name): "ServingConfigServiceClient", "Session", "SessionServiceClient", + "SingleRegionKey", "SiteSearchEngine", "SiteSearchEngineServiceClient", "SiteVerificationInfo", "Sitemap", "SolutionType", "SpannerSource", + "StreamAssistRequest", + "StreamAssistResponse", + "SubscriptionTerm", + "SubscriptionTier", "SuggestionDenyListEntry", "TargetSite", "TextInput", @@ -684,11 +882,16 @@ def _get_version(dependency_name): "TuneEngineMetadata", "TuneEngineRequest", "TuneEngineResponse", + "UpdateAclConfigRequest", + "UpdateAssistantRequest", + "UpdateCmekConfigMetadata", + "UpdateCmekConfigRequest", "UpdateControlRequest", "UpdateConversationRequest", "UpdateDataStoreRequest", "UpdateDocumentRequest", "UpdateEngineRequest", + "UpdateLicenseConfigRequest", "UpdateSampleQueryRequest", "UpdateSampleQuerySetRequest", "UpdateSchemaMetadata", @@ -697,9 +900,14 @@ def _get_version(dependency_name): "UpdateSessionRequest", "UpdateTargetSiteMetadata", "UpdateTargetSiteRequest", + "UpdateUserStoreRequest", "UserEvent", "UserEventServiceClient", "UserInfo", + "UserLicense", + "UserLicenseServiceClient", + "UserStore", + "UserStoreServiceClient", "WorkspaceConfig", "WriteUserEventRequest", ) diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/gapic_metadata.json b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/gapic_metadata.json index 0aa1292af549..d1b856cd2f8a 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/gapic_metadata.json +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/gapic_metadata.json @@ -5,6 +5,243 @@ "protoPackage": "google.cloud.discoveryengine.v1beta", "schema": "1.0", "services": { + "AclConfigService": { + "clients": { + "grpc": { + "libraryClient": "AclConfigServiceClient", + "rpcs": { + "GetAclConfig": { + "methods": [ + "get_acl_config" + ] + }, + "UpdateAclConfig": { + "methods": [ + "update_acl_config" + ] + } + } + }, + "grpc-async": { + "libraryClient": "AclConfigServiceAsyncClient", + "rpcs": { + "GetAclConfig": { + "methods": [ + "get_acl_config" + ] + }, + "UpdateAclConfig": { + "methods": [ + "update_acl_config" + ] + } + } + }, + "rest": { + "libraryClient": "AclConfigServiceClient", + "rpcs": { + "GetAclConfig": { + "methods": [ + "get_acl_config" + ] + }, + "UpdateAclConfig": { + "methods": [ + "update_acl_config" + ] + } + } + } + } + }, + "AssistantService": { + "clients": { + "grpc": { + "libraryClient": "AssistantServiceClient", + "rpcs": { + "CreateAssistant": { + "methods": [ + "create_assistant" + ] + }, + "DeleteAssistant": { + "methods": [ + "delete_assistant" + ] + }, + "GetAssistant": { + "methods": [ + "get_assistant" + ] + }, + "ListAssistants": { + "methods": [ + "list_assistants" + ] + }, + "StreamAssist": { + "methods": [ + "stream_assist" + ] + }, + "UpdateAssistant": { + "methods": [ + "update_assistant" + ] + } + } + }, + "grpc-async": { + "libraryClient": "AssistantServiceAsyncClient", + "rpcs": { + "CreateAssistant": { + "methods": [ + "create_assistant" + ] + }, + "DeleteAssistant": { + "methods": [ + "delete_assistant" + ] + }, + "GetAssistant": { + "methods": [ + "get_assistant" + ] + }, + "ListAssistants": { + "methods": [ + "list_assistants" + ] + }, + "StreamAssist": { + "methods": [ + "stream_assist" + ] + }, + "UpdateAssistant": { + "methods": [ + "update_assistant" + ] + } + } + }, + "rest": { + "libraryClient": "AssistantServiceClient", + "rpcs": { + "CreateAssistant": { + "methods": [ + "create_assistant" + ] + }, + "DeleteAssistant": { + "methods": [ + "delete_assistant" + ] + }, + "GetAssistant": { + "methods": [ + "get_assistant" + ] + }, + "ListAssistants": { + "methods": [ + "list_assistants" + ] + }, + "StreamAssist": { + "methods": [ + "stream_assist" + ] + }, + "UpdateAssistant": { + "methods": [ + "update_assistant" + ] + } + } + } + } + }, + "CmekConfigService": { + "clients": { + "grpc": { + "libraryClient": "CmekConfigServiceClient", + "rpcs": { + "DeleteCmekConfig": { + "methods": [ + "delete_cmek_config" + ] + }, + "GetCmekConfig": { + "methods": [ + "get_cmek_config" + ] + }, + "ListCmekConfigs": { + "methods": [ + "list_cmek_configs" + ] + }, + "UpdateCmekConfig": { + "methods": [ + "update_cmek_config" + ] + } + } + }, + "grpc-async": { + "libraryClient": "CmekConfigServiceAsyncClient", + "rpcs": { + "DeleteCmekConfig": { + "methods": [ + "delete_cmek_config" + ] + }, + "GetCmekConfig": { + "methods": [ + "get_cmek_config" + ] + }, + "ListCmekConfigs": { + "methods": [ + "list_cmek_configs" + ] + }, + "UpdateCmekConfig": { + "methods": [ + "update_cmek_config" + ] + } + } + }, + "rest": { + "libraryClient": "CmekConfigServiceClient", + "rpcs": { + "DeleteCmekConfig": { + "methods": [ + "delete_cmek_config" + ] + }, + "GetCmekConfig": { + "methods": [ + "get_cmek_config" + ] + }, + "ListCmekConfigs": { + "methods": [ + "list_cmek_configs" + ] + }, + "UpdateCmekConfig": { + "methods": [ + "update_cmek_config" + ] + } + } + } + } + }, "CompletionService": { "clients": { "grpc": { @@ -39,6 +276,11 @@ "methods": [ "purge_suggestion_deny_list_entries" ] + }, + "RemoveSuggestion": { + "methods": [ + "remove_suggestion" + ] } } }, @@ -74,6 +316,11 @@ "methods": [ "purge_suggestion_deny_list_entries" ] + }, + "RemoveSuggestion": { + "methods": [ + "remove_suggestion" + ] } } }, @@ -109,6 +356,11 @@ "methods": [ "purge_suggestion_deny_list_entries" ] + }, + "RemoveSuggestion": { + "methods": [ + "remove_suggestion" + ] } } } @@ -268,6 +520,11 @@ "list_sessions" ] }, + "StreamAnswerQuery": { + "methods": [ + "stream_answer_query" + ] + }, "UpdateConversation": { "methods": [ "update_conversation" @@ -338,6 +595,11 @@ "list_sessions" ] }, + "StreamAnswerQuery": { + "methods": [ + "stream_answer_query" + ] + }, "UpdateConversation": { "methods": [ "update_conversation" @@ -408,6 +670,11 @@ "list_sessions" ] }, + "StreamAnswerQuery": { + "methods": [ + "stream_answer_query" + ] + }, "UpdateConversation": { "methods": [ "update_conversation" @@ -675,6 +942,11 @@ "get_engine" ] }, + "GetIamPolicy": { + "methods": [ + "get_iam_policy" + ] + }, "ListEngines": { "methods": [ "list_engines" @@ -690,6 +962,11 @@ "resume_engine" ] }, + "SetIamPolicy": { + "methods": [ + "set_iam_policy" + ] + }, "TuneEngine": { "methods": [ "tune_engine" @@ -720,6 +997,11 @@ "get_engine" ] }, + "GetIamPolicy": { + "methods": [ + "get_iam_policy" + ] + }, "ListEngines": { "methods": [ "list_engines" @@ -735,6 +1017,11 @@ "resume_engine" ] }, + "SetIamPolicy": { + "methods": [ + "set_iam_policy" + ] + }, "TuneEngine": { "methods": [ "tune_engine" @@ -765,6 +1052,11 @@ "get_engine" ] }, + "GetIamPolicy": { + "methods": [ + "get_iam_policy" + ] + }, "ListEngines": { "methods": [ "list_engines" @@ -780,6 +1072,11 @@ "resume_engine" ] }, + "SetIamPolicy": { + "methods": [ + "set_iam_policy" + ] + }, "TuneEngine": { "methods": [ "tune_engine" @@ -937,6 +1234,239 @@ } } }, + "IdentityMappingStoreService": { + "clients": { + "grpc": { + "libraryClient": "IdentityMappingStoreServiceClient", + "rpcs": { + "CreateIdentityMappingStore": { + "methods": [ + "create_identity_mapping_store" + ] + }, + "DeleteIdentityMappingStore": { + "methods": [ + "delete_identity_mapping_store" + ] + }, + "GetIdentityMappingStore": { + "methods": [ + "get_identity_mapping_store" + ] + }, + "ImportIdentityMappings": { + "methods": [ + "import_identity_mappings" + ] + }, + "ListIdentityMappingStores": { + "methods": [ + "list_identity_mapping_stores" + ] + }, + "ListIdentityMappings": { + "methods": [ + "list_identity_mappings" + ] + }, + "PurgeIdentityMappings": { + "methods": [ + "purge_identity_mappings" + ] + } + } + }, + "grpc-async": { + "libraryClient": "IdentityMappingStoreServiceAsyncClient", + "rpcs": { + "CreateIdentityMappingStore": { + "methods": [ + "create_identity_mapping_store" + ] + }, + "DeleteIdentityMappingStore": { + "methods": [ + "delete_identity_mapping_store" + ] + }, + "GetIdentityMappingStore": { + "methods": [ + "get_identity_mapping_store" + ] + }, + "ImportIdentityMappings": { + "methods": [ + "import_identity_mappings" + ] + }, + "ListIdentityMappingStores": { + "methods": [ + "list_identity_mapping_stores" + ] + }, + "ListIdentityMappings": { + "methods": [ + "list_identity_mappings" + ] + }, + "PurgeIdentityMappings": { + "methods": [ + "purge_identity_mappings" + ] + } + } + }, + "rest": { + "libraryClient": "IdentityMappingStoreServiceClient", + "rpcs": { + "CreateIdentityMappingStore": { + "methods": [ + "create_identity_mapping_store" + ] + }, + "DeleteIdentityMappingStore": { + "methods": [ + "delete_identity_mapping_store" + ] + }, + "GetIdentityMappingStore": { + "methods": [ + "get_identity_mapping_store" + ] + }, + "ImportIdentityMappings": { + "methods": [ + "import_identity_mappings" + ] + }, + "ListIdentityMappingStores": { + "methods": [ + "list_identity_mapping_stores" + ] + }, + "ListIdentityMappings": { + "methods": [ + "list_identity_mappings" + ] + }, + "PurgeIdentityMappings": { + "methods": [ + "purge_identity_mappings" + ] + } + } + } + } + }, + "LicenseConfigService": { + "clients": { + "grpc": { + "libraryClient": "LicenseConfigServiceClient", + "rpcs": { + "CreateLicenseConfig": { + "methods": [ + "create_license_config" + ] + }, + "DistributeLicenseConfig": { + "methods": [ + "distribute_license_config" + ] + }, + "GetLicenseConfig": { + "methods": [ + "get_license_config" + ] + }, + "ListLicenseConfigs": { + "methods": [ + "list_license_configs" + ] + }, + "RetractLicenseConfig": { + "methods": [ + "retract_license_config" + ] + }, + "UpdateLicenseConfig": { + "methods": [ + "update_license_config" + ] + } + } + }, + "grpc-async": { + "libraryClient": "LicenseConfigServiceAsyncClient", + "rpcs": { + "CreateLicenseConfig": { + "methods": [ + "create_license_config" + ] + }, + "DistributeLicenseConfig": { + "methods": [ + "distribute_license_config" + ] + }, + "GetLicenseConfig": { + "methods": [ + "get_license_config" + ] + }, + "ListLicenseConfigs": { + "methods": [ + "list_license_configs" + ] + }, + "RetractLicenseConfig": { + "methods": [ + "retract_license_config" + ] + }, + "UpdateLicenseConfig": { + "methods": [ + "update_license_config" + ] + } + } + }, + "rest": { + "libraryClient": "LicenseConfigServiceClient", + "rpcs": { + "CreateLicenseConfig": { + "methods": [ + "create_license_config" + ] + }, + "DistributeLicenseConfig": { + "methods": [ + "distribute_license_config" + ] + }, + "GetLicenseConfig": { + "methods": [ + "get_license_config" + ] + }, + "ListLicenseConfigs": { + "methods": [ + "list_license_configs" + ] + }, + "RetractLicenseConfig": { + "methods": [ + "retract_license_config" + ] + }, + "UpdateLicenseConfig": { + "methods": [ + "update_license_config" + ] + } + } + } + } + }, "ProjectService": { "clients": { "grpc": { @@ -1439,6 +1969,16 @@ "grpc": { "libraryClient": "ServingConfigServiceClient", "rpcs": { + "CreateServingConfig": { + "methods": [ + "create_serving_config" + ] + }, + "DeleteServingConfig": { + "methods": [ + "delete_serving_config" + ] + }, "GetServingConfig": { "methods": [ "get_serving_config" @@ -1459,6 +1999,16 @@ "grpc-async": { "libraryClient": "ServingConfigServiceAsyncClient", "rpcs": { + "CreateServingConfig": { + "methods": [ + "create_serving_config" + ] + }, + "DeleteServingConfig": { + "methods": [ + "delete_serving_config" + ] + }, "GetServingConfig": { "methods": [ "get_serving_config" @@ -1479,6 +2029,16 @@ "rest": { "libraryClient": "ServingConfigServiceClient", "rpcs": { + "CreateServingConfig": { + "methods": [ + "create_serving_config" + ] + }, + "DeleteServingConfig": { + "methods": [ + "delete_serving_config" + ] + }, "GetServingConfig": { "methods": [ "get_serving_config" @@ -1914,6 +2474,119 @@ } } } + }, + "UserLicenseService": { + "clients": { + "grpc": { + "libraryClient": "UserLicenseServiceClient", + "rpcs": { + "BatchUpdateUserLicenses": { + "methods": [ + "batch_update_user_licenses" + ] + }, + "ListLicenseConfigsUsageStats": { + "methods": [ + "list_license_configs_usage_stats" + ] + }, + "ListUserLicenses": { + "methods": [ + "list_user_licenses" + ] + } + } + }, + "grpc-async": { + "libraryClient": "UserLicenseServiceAsyncClient", + "rpcs": { + "BatchUpdateUserLicenses": { + "methods": [ + "batch_update_user_licenses" + ] + }, + "ListLicenseConfigsUsageStats": { + "methods": [ + "list_license_configs_usage_stats" + ] + }, + "ListUserLicenses": { + "methods": [ + "list_user_licenses" + ] + } + } + }, + "rest": { + "libraryClient": "UserLicenseServiceClient", + "rpcs": { + "BatchUpdateUserLicenses": { + "methods": [ + "batch_update_user_licenses" + ] + }, + "ListLicenseConfigsUsageStats": { + "methods": [ + "list_license_configs_usage_stats" + ] + }, + "ListUserLicenses": { + "methods": [ + "list_user_licenses" + ] + } + } + } + } + }, + "UserStoreService": { + "clients": { + "grpc": { + "libraryClient": "UserStoreServiceClient", + "rpcs": { + "GetUserStore": { + "methods": [ + "get_user_store" + ] + }, + "UpdateUserStore": { + "methods": [ + "update_user_store" + ] + } + } + }, + "grpc-async": { + "libraryClient": "UserStoreServiceAsyncClient", + "rpcs": { + "GetUserStore": { + "methods": [ + "get_user_store" + ] + }, + "UpdateUserStore": { + "methods": [ + "update_user_store" + ] + } + } + }, + "rest": { + "libraryClient": "UserStoreServiceClient", + "rpcs": { + "GetUserStore": { + "methods": [ + "get_user_store" + ] + }, + "UpdateUserStore": { + "methods": [ + "update_user_store" + ] + } + } + } + } } } } diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/__init__.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/__init__.py new file mode 100644 index 000000000000..1f391c0152a8 --- /dev/null +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .async_client import AclConfigServiceAsyncClient +from .client import AclConfigServiceClient + +__all__ = ( + "AclConfigServiceClient", + "AclConfigServiceAsyncClient", +) diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/async_client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/async_client.py new file mode 100644 index 000000000000..a86139088ef3 --- /dev/null +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/async_client.py @@ -0,0 +1,702 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 logging as std_logging +import re +from collections import OrderedDict +from typing import ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, +) + +import google.protobuf +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.api_core.client_options import ClientOptions +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.discoveryengine_v1beta import gapic_version as package_version + +try: + OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore + +from google.cloud.discoveryengine_v1beta.types import ( + acl_config, + acl_config_service, + common, +) + +from .client import AclConfigServiceClient +from .transports.base import DEFAULT_CLIENT_INFO, AclConfigServiceTransport +from .transports.grpc_asyncio import AclConfigServiceGrpcAsyncIOTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class AclConfigServiceAsyncClient: + """Service for managing Acl Configuration.""" + + _client: AclConfigServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = AclConfigServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = AclConfigServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = AclConfigServiceClient._DEFAULT_ENDPOINT_TEMPLATE + _DEFAULT_UNIVERSE = AclConfigServiceClient._DEFAULT_UNIVERSE + + acl_config_path = staticmethod(AclConfigServiceClient.acl_config_path) + parse_acl_config_path = staticmethod(AclConfigServiceClient.parse_acl_config_path) + common_billing_account_path = staticmethod( + AclConfigServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AclConfigServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(AclConfigServiceClient.common_folder_path) + parse_common_folder_path = staticmethod( + AclConfigServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + AclConfigServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + AclConfigServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod(AclConfigServiceClient.common_project_path) + parse_common_project_path = staticmethod( + AclConfigServiceClient.parse_common_project_path + ) + common_location_path = staticmethod(AclConfigServiceClient.common_location_path) + parse_common_location_path = staticmethod( + AclConfigServiceClient.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: + AclConfigServiceAsyncClient: The constructed client. + """ + sa_info_func = ( + AclConfigServiceClient.from_service_account_info.__func__ # type: ignore + ) + return sa_info_func(AclConfigServiceAsyncClient, info, *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: + AclConfigServiceAsyncClient: The constructed client. + """ + sa_file_func = ( + AclConfigServiceClient.from_service_account_file.__func__ # type: ignore + ) + return sa_file_func(AclConfigServiceAsyncClient, filename, *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 variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AclConfigServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> AclConfigServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AclConfigServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self) -> str: + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = AclConfigServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, AclConfigServiceTransport, Callable[..., AclConfigServiceTransport] + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the acl config service async 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 (Optional[Union[str,AclConfigServiceTransport,Callable[..., AclConfigServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AclConfigServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "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). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS 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. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + 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. + """ + self._client = AclConfigServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.cloud.discoveryengine_v1beta.AclConfigServiceAsyncClient`.", + extra={ + "serviceName": "google.cloud.discoveryengine.v1beta.AclConfigService", + "universeDomain": getattr( + self._client._transport._credentials, "universe_domain", "" + ), + "credentialsType": f"{type(self._client._transport._credentials).__module__}.{type(self._client._transport._credentials).__qualname__}", + "credentialsInfo": getattr( + self.transport._credentials, "get_cred_info", lambda: None + )(), + } + if hasattr(self._client._transport, "_credentials") + else { + "serviceName": "google.cloud.discoveryengine.v1beta.AclConfigService", + "credentialsType": None, + }, + ) + + async def update_acl_config( + self, + request: Optional[ + Union[acl_config_service.UpdateAclConfigRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> acl_config.AclConfig: + r"""Default ACL configuration for use in a location of a + customer's project. Updates will only reflect to new + data stores. Existing data stores will still use the old + value. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import discoveryengine_v1beta + + async def sample_update_acl_config(): + # Create a client + client = discoveryengine_v1beta.AclConfigServiceAsyncClient() + + # Initialize request argument(s) + request = discoveryengine_v1beta.UpdateAclConfigRequest( + ) + + # Make the request + response = await client.update_acl_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.discoveryengine_v1beta.types.UpdateAclConfigRequest, dict]]): + The request object. Request message for UpdateAclConfig + method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.discoveryengine_v1beta.types.AclConfig: + Access Control Configuration. + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, acl_config_service.UpdateAclConfigRequest): + request = acl_config_service.UpdateAclConfigRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.update_acl_config + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("acl_config.name", request.acl_config.name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_acl_config( + self, + request: Optional[Union[acl_config_service.GetAclConfigRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> acl_config.AclConfig: + r"""Gets the + [AclConfig][google.cloud.discoveryengine.v1beta.AclConfig]. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import discoveryengine_v1beta + + async def sample_get_acl_config(): + # Create a client + client = discoveryengine_v1beta.AclConfigServiceAsyncClient() + + # Initialize request argument(s) + request = discoveryengine_v1beta.GetAclConfigRequest( + name="name_value", + ) + + # Make the request + response = await client.get_acl_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.discoveryengine_v1beta.types.GetAclConfigRequest, dict]]): + The request object. Request message for + GetAclConfigRequest method. + name (:class:`str`): + Required. Resource name of + [AclConfig][google.cloud.discoveryengine.v1beta.AclConfig], + such as ``projects/*/locations/*/aclConfig``. + + If the caller does not have permission to access the + [AclConfig][google.cloud.discoveryengine.v1beta.AclConfig], + regardless of whether or not it exists, a + PERMISSION_DENIED 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_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.discoveryengine_v1beta.types.AclConfig: + Access Control Configuration. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, acl_config_service.GetAclConfigRequest): + request = acl_config_service.GetAclConfigRequest(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._client._transport._wrapped_methods[ + self._client._transport.get_acl_config + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[Union[operations_pb2.ListOperationsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if request is None: + request_pb = operations_pb2.ListOperationsRequest() + elif isinstance(request, dict): + request_pb = operations_pb2.ListOperationsRequest(**request) + else: + request_pb = request + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.list_operations] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request_pb.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request_pb, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[Union[operations_pb2.GetOperationRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if request is None: + request_pb = operations_pb2.GetOperationRequest() + elif isinstance(request, dict): + request_pb = operations_pb2.GetOperationRequest(**request) + else: + request_pb = request + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request_pb.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request_pb, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def cancel_operation( + self, + request: Optional[Union[operations_pb2.CancelOperationRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Starts asynchronous cancellation on a long-running operation. + + The server makes a best effort to cancel the operation, but success + is not guaranteed. If the server doesn't support this method, it returns + `google.rpc.Code.UNIMPLEMENTED`. + + Args: + request (:class:`~.operations_pb2.CancelOperationRequest`): + The request object. Request message for + `CancelOperation` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + None + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if request is None: + request_pb = operations_pb2.CancelOperationRequest() + elif isinstance(request, dict): + request_pb = operations_pb2.CancelOperationRequest(**request) + else: + request_pb = request + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.cancel_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request_pb.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request_pb, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def __aenter__(self) -> "AclConfigServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AclConfigServiceAsyncClient",) diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/client.py new file mode 100644 index 000000000000..62f9d96893d3 --- /dev/null +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/client.py @@ -0,0 +1,1143 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 json +import logging as std_logging +import os +import re +import warnings +from collections import OrderedDict +from http import HTTPStatus +from typing import ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) + +import google.protobuf +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.discoveryengine_v1beta import gapic_version as package_version + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore + +from google.cloud.discoveryengine_v1beta.types import ( + acl_config, + acl_config_service, + common, +) + +from .transports.base import DEFAULT_CLIENT_INFO, AclConfigServiceTransport +from .transports.grpc import AclConfigServiceGrpcTransport +from .transports.grpc_asyncio import AclConfigServiceGrpcAsyncIOTransport +from .transports.rest import AclConfigServiceRestTransport + + +class AclConfigServiceClientMeta(type): + """Metaclass for the AclConfigService 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[AclConfigServiceTransport]] + _transport_registry["grpc"] = AclConfigServiceGrpcTransport + _transport_registry["grpc_asyncio"] = AclConfigServiceGrpcAsyncIOTransport + _transport_registry["rest"] = AclConfigServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AclConfigServiceTransport]: + """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 AclConfigServiceClient(metaclass=AclConfigServiceClientMeta): + """Service for managing Acl Configuration.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint) -> Optional[str]: + """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: + Optional[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) + if m is None: + # Could not parse api_endpoint; return as-is. + return 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") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "discoveryengine.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "discoveryengine.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @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: + AclConfigServiceClient: 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: + AclConfigServiceClient: 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) -> AclConfigServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AclConfigServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def acl_config_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified acl_config string.""" + return "projects/{project}/locations/{location}/aclConfig".format( + project=project, + location=location, + ) + + @staticmethod + def parse_acl_config_path(path: str) -> Dict[str, str]: + """Parses a acl_config path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/aclConfig$", 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 + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = AclConfigServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + 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: + 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 + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = AclConfigServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ) -> str: + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = AclConfigServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = AclConfigServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = AclConfigServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], universe_domain_env: Optional[str] + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = AclConfigServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self) -> str: + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, AclConfigServiceTransport, Callable[..., AclConfigServiceTransport] + ] + ] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the acl config 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 (Optional[Union[str,AclConfigServiceTransport,Callable[..., AclConfigServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AclConfigServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "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). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS 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. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + 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. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict(self._client_options) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr(self._client_options, "universe_domain", None) + + self._use_client_cert, self._use_mtls_endpoint, self._universe_domain_env = ( + AclConfigServiceClient._read_environment_variables() + ) + self._client_cert_source = AclConfigServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = AclConfigServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint: str = "" # updated below, depending on `transport` + + # Initialize the universe domain validation. + self._is_universe_domain_valid = False + + if CLIENT_LOGGING_SUPPORTED: # pragma: NO COVER + # Setup logging. + client_logging.initialize_logging() + + api_key_value = getattr(self._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. + transport_provided = isinstance(transport, AclConfigServiceTransport) + if transport_provided: + # transport is a AclConfigServiceTransport instance. + if credentials or self._client_options.credentials_file or api_key_value: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes directly." + ) + self._transport = cast(AclConfigServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AclConfigServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + 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_init: Union[ + Type[AclConfigServiceTransport], + Callable[..., AclConfigServiceTransport], + ] = ( + AclConfigServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., AclConfigServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + api_audience=self._client_options.api_audience, + ) + + if "async" not in str(self._transport): + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.cloud.discoveryengine_v1beta.AclConfigServiceClient`.", + extra={ + "serviceName": "google.cloud.discoveryengine.v1beta.AclConfigService", + "universeDomain": getattr( + self._transport._credentials, "universe_domain", "" + ), + "credentialsType": f"{type(self._transport._credentials).__module__}.{type(self._transport._credentials).__qualname__}", + "credentialsInfo": getattr( + self.transport._credentials, "get_cred_info", lambda: None + )(), + } + if hasattr(self._transport, "_credentials") + else { + "serviceName": "google.cloud.discoveryengine.v1beta.AclConfigService", + "credentialsType": None, + }, + ) + + def update_acl_config( + self, + request: Optional[ + Union[acl_config_service.UpdateAclConfigRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> acl_config.AclConfig: + r"""Default ACL configuration for use in a location of a + customer's project. Updates will only reflect to new + data stores. Existing data stores will still use the old + value. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import discoveryengine_v1beta + + def sample_update_acl_config(): + # Create a client + client = discoveryengine_v1beta.AclConfigServiceClient() + + # Initialize request argument(s) + request = discoveryengine_v1beta.UpdateAclConfigRequest( + ) + + # Make the request + response = client.update_acl_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.discoveryengine_v1beta.types.UpdateAclConfigRequest, dict]): + The request object. Request message for UpdateAclConfig + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.discoveryengine_v1beta.types.AclConfig: + Access Control Configuration. + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, acl_config_service.UpdateAclConfigRequest): + request = acl_config_service.UpdateAclConfigRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_acl_config] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("acl_config.name", request.acl_config.name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_acl_config( + self, + request: Optional[Union[acl_config_service.GetAclConfigRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> acl_config.AclConfig: + r"""Gets the + [AclConfig][google.cloud.discoveryengine.v1beta.AclConfig]. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import discoveryengine_v1beta + + def sample_get_acl_config(): + # Create a client + client = discoveryengine_v1beta.AclConfigServiceClient() + + # Initialize request argument(s) + request = discoveryengine_v1beta.GetAclConfigRequest( + name="name_value", + ) + + # Make the request + response = client.get_acl_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.discoveryengine_v1beta.types.GetAclConfigRequest, dict]): + The request object. Request message for + GetAclConfigRequest method. + name (str): + Required. Resource name of + [AclConfig][google.cloud.discoveryengine.v1beta.AclConfig], + such as ``projects/*/locations/*/aclConfig``. + + If the caller does not have permission to access the + [AclConfig][google.cloud.discoveryengine.v1beta.AclConfig], + regardless of whether or not it exists, a + PERMISSION_DENIED 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.discoveryengine_v1beta.types.AclConfig: + Access Control Configuration. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, acl_config_service.GetAclConfigRequest): + request = acl_config_service.GetAclConfigRequest(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_acl_config] + + # 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),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AclConfigServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + def list_operations( + self, + request: Optional[Union[operations_pb2.ListOperationsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if request is None: + request_pb = operations_pb2.ListOperationsRequest() + elif isinstance(request, dict): + request_pb = operations_pb2.ListOperationsRequest(**request) + else: + request_pb = request + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_operations] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request_pb.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request_pb, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + def get_operation( + self, + request: Optional[Union[operations_pb2.GetOperationRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if request is None: + request_pb = operations_pb2.GetOperationRequest() + elif isinstance(request, dict): + request_pb = operations_pb2.GetOperationRequest(**request) + else: + request_pb = request + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request_pb.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request_pb, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + def cancel_operation( + self, + request: Optional[Union[operations_pb2.CancelOperationRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Starts asynchronous cancellation on a long-running operation. + + The server makes a best effort to cancel the operation, but success + is not guaranteed. If the server doesn't support this method, it returns + `google.rpc.Code.UNIMPLEMENTED`. + + Args: + request (:class:`~.operations_pb2.CancelOperationRequest`): + The request object. Request message for + `CancelOperation` 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + None + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if request is None: + request_pb = operations_pb2.CancelOperationRequest() + elif isinstance(request, dict): + request_pb = operations_pb2.CancelOperationRequest(**request) + else: + request_pb = request + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.cancel_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request_pb.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + rpc( + request_pb, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AclConfigServiceClient",) diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/transports/README.rst b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/transports/README.rst new file mode 100644 index 000000000000..27930d4db5ee --- /dev/null +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/transports/README.rst @@ -0,0 +1,10 @@ + +transport inheritance structure +_______________________________ + +``AclConfigServiceTransport`` is the ABC for all transports. + +- public child ``AclConfigServiceGrpcTransport`` for sync gRPC transport (defined in ``grpc.py``). +- public child ``AclConfigServiceGrpcAsyncIOTransport`` for async gRPC transport (defined in ``grpc_asyncio.py``). +- private child ``_BaseAclConfigServiceRestTransport`` for base REST transport with inner classes ``_BaseMETHOD`` (defined in ``rest_base.py``). +- public child ``AclConfigServiceRestTransport`` for sync REST transport with inner classes ``METHOD`` derived from the parent's corresponding ``_BaseMETHOD`` classes (defined in ``rest.py``). diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/transports/__init__.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/transports/__init__.py new file mode 100644 index 000000000000..87322302a120 --- /dev/null +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/transports/__init__.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 AclConfigServiceTransport +from .grpc import AclConfigServiceGrpcTransport +from .grpc_asyncio import AclConfigServiceGrpcAsyncIOTransport +from .rest import AclConfigServiceRestInterceptor, AclConfigServiceRestTransport + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[AclConfigServiceTransport]] +_transport_registry["grpc"] = AclConfigServiceGrpcTransport +_transport_registry["grpc_asyncio"] = AclConfigServiceGrpcAsyncIOTransport +_transport_registry["rest"] = AclConfigServiceRestTransport + +__all__ = ( + "AclConfigServiceTransport", + "AclConfigServiceGrpcTransport", + "AclConfigServiceGrpcAsyncIOTransport", + "AclConfigServiceRestTransport", + "AclConfigServiceRestInterceptor", +) diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/transports/base.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/transports/base.py new file mode 100644 index 000000000000..f62efa912d73 --- /dev/null +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/transports/base.py @@ -0,0 +1,240 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union + +import google.api_core +import google.auth # type: ignore +import google.protobuf +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.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.discoveryengine_v1beta import gapic_version as package_version +from google.cloud.discoveryengine_v1beta.types import acl_config, acl_config_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AclConfigServiceTransport(abc.ABC): + """Abstract transport class for AclConfigService.""" + + AUTH_SCOPES = ( + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/discoveryengine.readwrite", + "https://www.googleapis.com/auth/discoveryengine.serving.readwrite", + ) + + DEFAULT_HOST: str = "discoveryengine.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'discoveryengine.googleapis.com'). + 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]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + 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. + api_audience (Optional[str]): The intended audience for the API calls + to the service that will be set when using certain 3rd party + authentication flows. Audience is typically a resource identifier. + If not set, the host value will be used as a default. + """ + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # 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=scopes, + quota_project_id=quota_project_id, + default_scopes=self.AUTH_SCOPES, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + scopes=scopes, + quota_project_id=quota_project_id, + default_scopes=self.AUTH_SCOPES, + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr(service_account.Credentials, "with_always_use_jwt_access") + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + self._wrapped_methods: Dict[Callable, Callable] = {} + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.update_acl_config: gapic_v1.method.wrap_method( + self.update_acl_config, + default_timeout=None, + client_info=client_info, + ), + self.get_acl_config: gapic_v1.method.wrap_method( + self.get_acl_config, + default_timeout=None, + client_info=client_info, + ), + self.cancel_operation: gapic_v1.method.wrap_method( + self.cancel_operation, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: gapic_v1.method.wrap_method( + self.get_operation, + default_timeout=None, + client_info=client_info, + ), + self.list_operations: gapic_v1.method.wrap_method( + self.list_operations, + 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 update_acl_config( + self, + ) -> Callable[ + [acl_config_service.UpdateAclConfigRequest], + Union[acl_config.AclConfig, Awaitable[acl_config.AclConfig]], + ]: + raise NotImplementedError() + + @property + def get_acl_config( + self, + ) -> Callable[ + [acl_config_service.GetAclConfigRequest], + Union[acl_config.AclConfig, Awaitable[acl_config.AclConfig]], + ]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[ + operations_pb2.ListOperationsResponse, + Awaitable[operations_pb2.ListOperationsResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def cancel_operation( + self, + ) -> Callable[ + [operations_pb2.CancelOperationRequest], + None, + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AclConfigServiceTransport",) diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/transports/grpc.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/transports/grpc.py new file mode 100644 index 000000000000..f3649970e6ae --- /dev/null +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/transports/grpc.py @@ -0,0 +1,447 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 json +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +import google.auth # type: ignore +import google.protobuf.message +import grpc # type: ignore +import proto # type: ignore +from google.api_core import gapic_v1, grpc_helpers +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson + +from google.cloud.discoveryengine_v1beta.types import acl_config, acl_config_service + +from .base import DEFAULT_CLIENT_INFO, AclConfigServiceTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor(grpc.UnaryUnaryClientInterceptor): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = f"{type(request).__name__}: {pickle.dumps(request)!r}" + + request_metadata = { + key: value.decode("utf-8") if isinstance(value, bytes) else value + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.cloud.discoveryengine.v1beta.AclConfigService", + "rpcName": str(client_call_details.method), + "request": grpc_request, + "metadata": grpc_request["metadata"], + }, + ) + response = continuation(client_call_details, request) + if logging_enabled: # pragma: NO COVER + response_metadata = response.trailing_metadata() + # Convert gRPC metadata `` to list of tuples + metadata = ( + dict([(k, str(v)) for k, v in response_metadata]) + if response_metadata + else None + ) + result = response.result() + if isinstance(result, proto.Message): + response_payload = type(result).to_json(result) + elif isinstance(result, google.protobuf.message.Message): + response_payload = MessageToJson(result) + else: + response_payload = f"{type(result).__name__}: {pickle.dumps(result)!r}" + grpc_response = { + "payload": response_payload, + "metadata": metadata, + "status": "OK", + } + _LOGGER.debug( + f"Received response for {client_call_details.method}.", + extra={ + "serviceName": "google.cloud.discoveryengine.v1beta.AclConfigService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AclConfigServiceGrpcTransport(AclConfigServiceTransport): + """gRPC backend transport for AclConfigService. + + Service for managing Acl 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 = "discoveryengine.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'discoveryengine.googleapis.com'). + 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 a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + 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 a ``channel`` instance 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 a ``channel`` instance 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. + api_audience (Optional[str]): The intended audience for the API calls + to the service that will be set when using certain 3rd party + authentication flows. Audience is typically a resource identifier. + If not set, the host value will be used as a default. + + 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 isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + self._interceptor = _LoggingClientInterceptor() + self._logged_channel = grpc.intercept_channel( + self._grpc_channel, self._interceptor + ) + + # Wrap messages. This must be done after self._logged_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "discoveryengine.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + 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 update_acl_config( + self, + ) -> Callable[[acl_config_service.UpdateAclConfigRequest], acl_config.AclConfig]: + r"""Return a callable for the update acl config method over gRPC. + + Default ACL configuration for use in a location of a + customer's project. Updates will only reflect to new + data stores. Existing data stores will still use the old + value. + + Returns: + Callable[[~.UpdateAclConfigRequest], + ~.AclConfig]: + 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_acl_config" not in self._stubs: + self._stubs["update_acl_config"] = self._logged_channel.unary_unary( + "/google.cloud.discoveryengine.v1beta.AclConfigService/UpdateAclConfig", + request_serializer=acl_config_service.UpdateAclConfigRequest.serialize, + response_deserializer=acl_config.AclConfig.deserialize, + ) + return self._stubs["update_acl_config"] + + @property + def get_acl_config( + self, + ) -> Callable[[acl_config_service.GetAclConfigRequest], acl_config.AclConfig]: + r"""Return a callable for the get acl config method over gRPC. + + Gets the + [AclConfig][google.cloud.discoveryengine.v1beta.AclConfig]. + + Returns: + Callable[[~.GetAclConfigRequest], + ~.AclConfig]: + 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_acl_config" not in self._stubs: + self._stubs["get_acl_config"] = self._logged_channel.unary_unary( + "/google.cloud.discoveryengine.v1beta.AclConfigService/GetAclConfig", + request_serializer=acl_config_service.GetAclConfigRequest.serialize, + response_deserializer=acl_config.AclConfig.deserialize, + ) + return self._stubs["get_acl_config"] + + def close(self): + self._logged_channel.close() + + @property + def cancel_operation( + self, + ) -> Callable[[operations_pb2.CancelOperationRequest], None]: + r"""Return a callable for the cancel_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "cancel_operation" not in self._stubs: + self._stubs["cancel_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/CancelOperation", + request_serializer=operations_pb2.CancelOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["cancel_operation"] + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_operation" not in self._stubs: + self._stubs["get_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse + ]: + r"""Return a callable for the list_operations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_operations" not in self._stubs: + self._stubs["list_operations"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("AclConfigServiceGrpcTransport",) diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/transports/grpc_asyncio.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/transports/grpc_asyncio.py new file mode 100644 index 000000000000..28f53fceab7c --- /dev/null +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/transports/grpc_asyncio.py @@ -0,0 +1,494 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 inspect +import json +import logging as std_logging +import pickle +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +import google.protobuf.message +import grpc # type: ignore +import proto # type: ignore +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, grpc_helpers_async +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +from grpc.experimental import aio # type: ignore + +from google.cloud.discoveryengine_v1beta.types import acl_config, acl_config_service + +from .base import DEFAULT_CLIENT_INFO, AclConfigServiceTransport +from .grpc import AclConfigServiceGrpcTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientAIOInterceptor( + grpc.aio.UnaryUnaryClientInterceptor +): # pragma: NO COVER + async def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = f"{type(request).__name__}: {pickle.dumps(request)!r}" + + request_metadata = { + key: value.decode("utf-8") if isinstance(value, bytes) else value + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.cloud.discoveryengine.v1beta.AclConfigService", + "rpcName": str(client_call_details.method), + "request": grpc_request, + "metadata": grpc_request["metadata"], + }, + ) + response = await continuation(client_call_details, request) + if logging_enabled: # pragma: NO COVER + response_metadata = await response.trailing_metadata() + # Convert gRPC metadata `` to list of tuples + metadata = ( + dict([(k, str(v)) for k, v in response_metadata]) + if response_metadata + else None + ) + result = await response + if isinstance(result, proto.Message): + response_payload = type(result).to_json(result) + elif isinstance(result, google.protobuf.message.Message): + response_payload = MessageToJson(result) + else: + response_payload = f"{type(result).__name__}: {pickle.dumps(result)!r}" + grpc_response = { + "payload": response_payload, + "metadata": metadata, + "status": "OK", + } + _LOGGER.debug( + f"Received response to rpc {client_call_details.method}.", + extra={ + "serviceName": "google.cloud.discoveryengine.v1beta.AclConfigService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AclConfigServiceGrpcAsyncIOTransport(AclConfigServiceTransport): + """gRPC AsyncIO backend transport for AclConfigService. + + Service for managing Acl 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 = "discoveryengine.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + 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 = "discoveryengine.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[Union[aio.Channel, Callable[..., aio.Channel]]] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'discoveryengine.googleapis.com'). + 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 a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + 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[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + 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 a ``channel`` instance 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 a ``channel`` instance 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. + api_audience (Optional[str]): The intended audience for the API calls + to the service that will be set when using certain 3rd party + authentication flows. Audience is typically a resource identifier. + If not set, the host value will be used as a default. + + 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 isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + self._interceptor = _LoggingClientAIOInterceptor() + self._grpc_channel._unary_unary_interceptors.append(self._interceptor) + self._logged_channel = self._grpc_channel + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) + # Wrap messages. This must be done after self._logged_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 update_acl_config( + self, + ) -> Callable[ + [acl_config_service.UpdateAclConfigRequest], Awaitable[acl_config.AclConfig] + ]: + r"""Return a callable for the update acl config method over gRPC. + + Default ACL configuration for use in a location of a + customer's project. Updates will only reflect to new + data stores. Existing data stores will still use the old + value. + + Returns: + Callable[[~.UpdateAclConfigRequest], + Awaitable[~.AclConfig]]: + 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_acl_config" not in self._stubs: + self._stubs["update_acl_config"] = self._logged_channel.unary_unary( + "/google.cloud.discoveryengine.v1beta.AclConfigService/UpdateAclConfig", + request_serializer=acl_config_service.UpdateAclConfigRequest.serialize, + response_deserializer=acl_config.AclConfig.deserialize, + ) + return self._stubs["update_acl_config"] + + @property + def get_acl_config( + self, + ) -> Callable[ + [acl_config_service.GetAclConfigRequest], Awaitable[acl_config.AclConfig] + ]: + r"""Return a callable for the get acl config method over gRPC. + + Gets the + [AclConfig][google.cloud.discoveryengine.v1beta.AclConfig]. + + Returns: + Callable[[~.GetAclConfigRequest], + Awaitable[~.AclConfig]]: + 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_acl_config" not in self._stubs: + self._stubs["get_acl_config"] = self._logged_channel.unary_unary( + "/google.cloud.discoveryengine.v1beta.AclConfigService/GetAclConfig", + request_serializer=acl_config_service.GetAclConfigRequest.serialize, + response_deserializer=acl_config.AclConfig.deserialize, + ) + return self._stubs["get_acl_config"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.update_acl_config: self._wrap_method( + self.update_acl_config, + default_timeout=None, + client_info=client_info, + ), + self.get_acl_config: self._wrap_method( + self.get_acl_config, + default_timeout=None, + client_info=client_info, + ), + self.cancel_operation: self._wrap_method( + self.cancel_operation, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: self._wrap_method( + self.get_operation, + default_timeout=None, + client_info=client_info, + ), + self.list_operations: self._wrap_method( + self.list_operations, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + @property + def cancel_operation( + self, + ) -> Callable[[operations_pb2.CancelOperationRequest], None]: + r"""Return a callable for the cancel_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "cancel_operation" not in self._stubs: + self._stubs["cancel_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/CancelOperation", + request_serializer=operations_pb2.CancelOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["cancel_operation"] + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_operation" not in self._stubs: + self._stubs["get_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse + ]: + r"""Return a callable for the list_operations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_operations" not in self._stubs: + self._stubs["list_operations"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ("AclConfigServiceGrpcAsyncIOTransport",) diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/transports/rest.py new file mode 100644 index 000000000000..4c90dd2644fc --- /dev/null +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/transports/rest.py @@ -0,0 +1,1081 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +import warnings +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +import google.protobuf +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.cloud.discoveryengine_v1beta.types import acl_config, acl_config_service + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseAclConfigServiceRestTransport + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AclConfigServiceRestInterceptor: + """Interceptor for AclConfigService. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the AclConfigServiceRestTransport. + + .. code-block:: python + class MyCustomAclConfigServiceInterceptor(AclConfigServiceRestInterceptor): + def pre_get_acl_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_acl_config(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_acl_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_acl_config(self, response): + logging.log(f"Received response: {response}") + return response + + transport = AclConfigServiceRestTransport(interceptor=MyCustomAclConfigServiceInterceptor()) + client = AclConfigServiceClient(transport=transport) + + + """ + + def pre_get_acl_config( + self, + request: acl_config_service.GetAclConfigRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + acl_config_service.GetAclConfigRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_acl_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the AclConfigService server. + """ + return request, metadata + + def post_get_acl_config( + self, response: acl_config.AclConfig + ) -> acl_config.AclConfig: + """Post-rpc interceptor for get_acl_config + + DEPRECATED. Please use the `post_get_acl_config_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the AclConfigService server but before + it is returned to user code. This `post_get_acl_config` interceptor runs + before the `post_get_acl_config_with_metadata` interceptor. + """ + return response + + def post_get_acl_config_with_metadata( + self, + response: acl_config.AclConfig, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[acl_config.AclConfig, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_acl_config + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the AclConfigService server but before it is returned to user code. + + We recommend only using this `post_get_acl_config_with_metadata` + interceptor in new development instead of the `post_get_acl_config` interceptor. + When both interceptors are used, this `post_get_acl_config_with_metadata` interceptor runs after the + `post_get_acl_config` interceptor. The (possibly modified) response returned by + `post_get_acl_config` will be passed to + `post_get_acl_config_with_metadata`. + """ + return response, metadata + + def pre_update_acl_config( + self, + request: acl_config_service.UpdateAclConfigRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + acl_config_service.UpdateAclConfigRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for update_acl_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the AclConfigService server. + """ + return request, metadata + + def post_update_acl_config( + self, response: acl_config.AclConfig + ) -> acl_config.AclConfig: + """Post-rpc interceptor for update_acl_config + + DEPRECATED. Please use the `post_update_acl_config_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the AclConfigService server but before + it is returned to user code. This `post_update_acl_config` interceptor runs + before the `post_update_acl_config_with_metadata` interceptor. + """ + return response + + def post_update_acl_config_with_metadata( + self, + response: acl_config.AclConfig, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[acl_config.AclConfig, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_acl_config + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the AclConfigService server but before it is returned to user code. + + We recommend only using this `post_update_acl_config_with_metadata` + interceptor in new development instead of the `post_update_acl_config` interceptor. + When both interceptors are used, this `post_update_acl_config_with_metadata` interceptor runs after the + `post_update_acl_config` interceptor. The (possibly modified) response returned by + `post_update_acl_config` will be passed to + `post_update_acl_config_with_metadata`. + """ + return response, metadata + + def pre_cancel_operation( + self, + request: operations_pb2.CancelOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.CancelOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for cancel_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the AclConfigService server. + """ + return request, metadata + + def post_cancel_operation(self, response: None) -> None: + """Post-rpc interceptor for cancel_operation + + Override in a subclass to manipulate the response + after it is returned by the AclConfigService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the AclConfigService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the AclConfigService server but before + it is returned to user code. + """ + return response + + def pre_list_operations( + self, + request: operations_pb2.ListOperationsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.ListOperationsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the AclConfigService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the AclConfigService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class AclConfigServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: AclConfigServiceRestInterceptor + + +class AclConfigServiceRestTransport(_BaseAclConfigServiceRestTransport): + """REST backend synchronous transport for AclConfigService. + + Service for managing Acl 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 JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "discoveryengine.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[AclConfigServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'discoveryengine.googleapis.com'). + 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]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. This argument will be + removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + interceptor (Optional[AclConfigServiceRestInterceptor]): Interceptor used + to manipulate requests, request metadata, and responses. + api_audience (Optional[str]): The intended audience for the API calls + to the service that will be set when using certain 3rd party + authentication flows. Audience is typically a resource identifier. + If not set, the host value will be used as a default. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or AclConfigServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _GetAclConfig( + _BaseAclConfigServiceRestTransport._BaseGetAclConfig, AclConfigServiceRestStub + ): + def __hash__(self): + return hash("AclConfigServiceRestTransport.GetAclConfig") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: acl_config_service.GetAclConfigRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> acl_config.AclConfig: + r"""Call the get acl config method over HTTP. + + Args: + request (~.acl_config_service.GetAclConfigRequest): + The request object. Request message for + GetAclConfigRequest 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.acl_config.AclConfig: + Access Control Configuration. + """ + + http_options = ( + _BaseAclConfigServiceRestTransport._BaseGetAclConfig._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_acl_config(request, metadata) + transcoded_request = _BaseAclConfigServiceRestTransport._BaseGetAclConfig._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseAclConfigServiceRestTransport._BaseGetAclConfig._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.discoveryengine_v1beta.AclConfigServiceClient.GetAclConfig", + extra={ + "serviceName": "google.cloud.discoveryengine.v1beta.AclConfigService", + "rpcName": "GetAclConfig", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = AclConfigServiceRestTransport._GetAclConfig._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = acl_config.AclConfig() + pb_resp = acl_config.AclConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_acl_config(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_acl_config_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = acl_config.AclConfig.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.discoveryengine_v1beta.AclConfigServiceClient.get_acl_config", + extra={ + "serviceName": "google.cloud.discoveryengine.v1beta.AclConfigService", + "rpcName": "GetAclConfig", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _UpdateAclConfig( + _BaseAclConfigServiceRestTransport._BaseUpdateAclConfig, + AclConfigServiceRestStub, + ): + def __hash__(self): + return hash("AclConfigServiceRestTransport.UpdateAclConfig") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: acl_config_service.UpdateAclConfigRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> acl_config.AclConfig: + r"""Call the update acl config method over HTTP. + + Args: + request (~.acl_config_service.UpdateAclConfigRequest): + The request object. Request message for UpdateAclConfig + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.acl_config.AclConfig: + Access Control Configuration. + """ + + http_options = _BaseAclConfigServiceRestTransport._BaseUpdateAclConfig._get_http_options() + + request, metadata = self._interceptor.pre_update_acl_config( + request, metadata + ) + transcoded_request = _BaseAclConfigServiceRestTransport._BaseUpdateAclConfig._get_transcoded_request( + http_options, request + ) + + body = _BaseAclConfigServiceRestTransport._BaseUpdateAclConfig._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseAclConfigServiceRestTransport._BaseUpdateAclConfig._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.discoveryengine_v1beta.AclConfigServiceClient.UpdateAclConfig", + extra={ + "serviceName": "google.cloud.discoveryengine.v1beta.AclConfigService", + "rpcName": "UpdateAclConfig", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = AclConfigServiceRestTransport._UpdateAclConfig._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = acl_config.AclConfig() + pb_resp = acl_config.AclConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_update_acl_config(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_acl_config_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = acl_config.AclConfig.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.discoveryengine_v1beta.AclConfigServiceClient.update_acl_config", + extra={ + "serviceName": "google.cloud.discoveryengine.v1beta.AclConfigService", + "rpcName": "UpdateAclConfig", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def get_acl_config( + self, + ) -> Callable[[acl_config_service.GetAclConfigRequest], acl_config.AclConfig]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetAclConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_acl_config( + self, + ) -> Callable[[acl_config_service.UpdateAclConfigRequest], acl_config.AclConfig]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateAclConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def cancel_operation(self): + return self._CancelOperation(self._session, self._host, self._interceptor) # type: ignore + + class _CancelOperation( + _BaseAclConfigServiceRestTransport._BaseCancelOperation, + AclConfigServiceRestStub, + ): + def __hash__(self): + return hash("AclConfigServiceRestTransport.CancelOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: operations_pb2.CancelOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Call the cancel operation method over HTTP. + + Args: + request (operations_pb2.CancelOperationRequest): + The request object for CancelOperation 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + + http_options = _BaseAclConfigServiceRestTransport._BaseCancelOperation._get_http_options() + + request, metadata = self._interceptor.pre_cancel_operation( + request, metadata + ) + transcoded_request = _BaseAclConfigServiceRestTransport._BaseCancelOperation._get_transcoded_request( + http_options, request + ) + + body = _BaseAclConfigServiceRestTransport._BaseCancelOperation._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseAclConfigServiceRestTransport._BaseCancelOperation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.discoveryengine_v1beta.AclConfigServiceClient.CancelOperation", + extra={ + "serviceName": "google.cloud.discoveryengine.v1beta.AclConfigService", + "rpcName": "CancelOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = AclConfigServiceRestTransport._CancelOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + return self._interceptor.post_cancel_operation(None) + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation( + _BaseAclConfigServiceRestTransport._BaseGetOperation, AclConfigServiceRestStub + ): + def __hash__(self): + return hash("AclConfigServiceRestTransport.GetOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options = ( + _BaseAclConfigServiceRestTransport._BaseGetOperation._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + transcoded_request = _BaseAclConfigServiceRestTransport._BaseGetOperation._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseAclConfigServiceRestTransport._BaseGetOperation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.discoveryengine_v1beta.AclConfigServiceClient.GetOperation", + extra={ + "serviceName": "google.cloud.discoveryengine.v1beta.AclConfigService", + "rpcName": "GetOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = AclConfigServiceRestTransport._GetOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.Operation() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_get_operation(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.discoveryengine_v1beta.AclConfigServiceAsyncClient.GetOperation", + extra={ + "serviceName": "google.cloud.discoveryengine.v1beta.AclConfigService", + "rpcName": "GetOperation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations( + _BaseAclConfigServiceRestTransport._BaseListOperations, AclConfigServiceRestStub + ): + def __hash__(self): + return hash("AclConfigServiceRestTransport.ListOperations") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.ListOperationsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.ListOperationsResponse: Response from ListOperations method. + """ + + http_options = _BaseAclConfigServiceRestTransport._BaseListOperations._get_http_options() + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + transcoded_request = _BaseAclConfigServiceRestTransport._BaseListOperations._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseAclConfigServiceRestTransport._BaseListOperations._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.discoveryengine_v1beta.AclConfigServiceClient.ListOperations", + extra={ + "serviceName": "google.cloud.discoveryengine.v1beta.AclConfigService", + "rpcName": "ListOperations", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = AclConfigServiceRestTransport._ListOperations._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_list_operations(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.discoveryengine_v1beta.AclConfigServiceAsyncClient.ListOperations", + extra={ + "serviceName": "google.cloud.discoveryengine.v1beta.AclConfigService", + "rpcName": "ListOperations", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("AclConfigServiceRestTransport",) diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/transports/rest_base.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/transports/rest_base.py new file mode 100644 index 000000000000..3477ffd57809 --- /dev/null +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/acl_config_service/transports/rest_base.py @@ -0,0 +1,407 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format + +from google.cloud.discoveryengine_v1beta.types import acl_config, acl_config_service + +from .base import DEFAULT_CLIENT_INFO, AclConfigServiceTransport + + +class _BaseAclConfigServiceRestTransport(AclConfigServiceTransport): + """Base REST backend transport for AclConfigService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "discoveryengine.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'discoveryengine.googleapis.com'). + credentials (Optional[Any]): 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. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetAclConfig: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/aclConfig}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = acl_config_service.GetAclConfigRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAclConfigServiceRestTransport._BaseGetAclConfig._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateAclConfig: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v1beta/{acl_config.name=projects/*/locations/*/aclConfig}", + "body": "acl_config", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = acl_config_service.UpdateAclConfigRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAclConfigServiceRestTransport._BaseUpdateAclConfig._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseCancelOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1beta/{name=projects/*/locations/*/collections/*/dataStores/*/branches/*/operations/*}:cancel", + "body": "*", + }, + { + "method": "post", + "uri": "/v1beta/{name=projects/*/locations/*/dataStores/*/branches/*/operations/*}:cancel", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + body = json.dumps(transcoded_request["body"]) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + class _BaseGetOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/collections/*/dataConnector/operations/*}", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/collections/*/dataStores/*/branches/*/operations/*}", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/collections/*/dataStores/*/models/*/operations/*}", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/collections/*/dataStores/*/operations/*}", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/collections/*/dataStores/*/schemas/*/operations/*}", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/collections/*/dataStores/*/siteSearchEngine/operations/*}", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/collections/*/dataStores/*/siteSearchEngine/targetSites/operations/*}", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/collections/*/engines/*/assistants/*/agents/*/operations/*}", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/collections/*/engines/*/operations/*}", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/collections/*/operations/*}", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/dataStores/*/branches/*/operations/*}", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/dataStores/*/models/*/operations/*}", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/dataStores/*/operations/*}", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/evaluations/*/operations/*}", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/identityMappingStores/*/operations/*}", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/operations/*}", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/sampleQuerySets/*/operations/*}", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/operations/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + class _BaseListOperations: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/collections/*/dataConnector}/operations", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/collections/*/dataStores/*/branches/*}/operations", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/collections/*/dataStores/*/models/*}/operations", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/collections/*/dataStores/*/schemas/*}/operations", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/collections/*/dataStores/*/siteSearchEngine/targetSites}/operations", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/collections/*/dataStores/*/siteSearchEngine}/operations", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/collections/*/dataStores/*}/operations", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/collections/*/engines/*}/operations", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/collections/*}/operations", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/dataStores/*/branches/*}/operations", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/dataStores/*/models/*}/operations", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/dataStores/*}/operations", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/identityMappingStores/*}/operations", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*}/operations", + }, + { + "method": "get", + "uri": "/v1beta/{name=projects/*}/operations", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + +__all__ = ("_BaseAclConfigServiceRestTransport",) diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/assistant_service/__init__.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/assistant_service/__init__.py new file mode 100644 index 000000000000..e85f773562fa --- /dev/null +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/assistant_service/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .async_client import AssistantServiceAsyncClient +from .client import AssistantServiceClient + +__all__ = ( + "AssistantServiceClient", + "AssistantServiceAsyncClient", +) diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/assistant_service/async_client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/assistant_service/async_client.py new file mode 100644 index 000000000000..b7417aa3285e --- /dev/null +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/assistant_service/async_client.py @@ -0,0 +1,1194 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 logging as std_logging +import re +from collections import OrderedDict +from typing import ( + AsyncIterable, + Awaitable, + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, +) + +import google.protobuf +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.api_core.client_options import ClientOptions +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.discoveryengine_v1beta import gapic_version as package_version + +try: + OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +import google.protobuf.field_mask_pb2 as field_mask_pb2 # type: ignore +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore + +from google.cloud.discoveryengine_v1beta.services.assistant_service import pagers +from google.cloud.discoveryengine_v1beta.types import ( + assist_answer, + assistant, + assistant_service, +) +from google.cloud.discoveryengine_v1beta.types import assistant as gcd_assistant + +from .client import AssistantServiceClient +from .transports.base import DEFAULT_CLIENT_INFO, AssistantServiceTransport +from .transports.grpc_asyncio import AssistantServiceGrpcAsyncIOTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class AssistantServiceAsyncClient: + """Service for managing Assistant configuration and assisting + users. + """ + + _client: AssistantServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = AssistantServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = AssistantServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = AssistantServiceClient._DEFAULT_ENDPOINT_TEMPLATE + _DEFAULT_UNIVERSE = AssistantServiceClient._DEFAULT_UNIVERSE + + assist_answer_path = staticmethod(AssistantServiceClient.assist_answer_path) + parse_assist_answer_path = staticmethod( + AssistantServiceClient.parse_assist_answer_path + ) + assistant_path = staticmethod(AssistantServiceClient.assistant_path) + parse_assistant_path = staticmethod(AssistantServiceClient.parse_assistant_path) + data_store_path = staticmethod(AssistantServiceClient.data_store_path) + parse_data_store_path = staticmethod(AssistantServiceClient.parse_data_store_path) + document_path = staticmethod(AssistantServiceClient.document_path) + parse_document_path = staticmethod(AssistantServiceClient.parse_document_path) + engine_path = staticmethod(AssistantServiceClient.engine_path) + parse_engine_path = staticmethod(AssistantServiceClient.parse_engine_path) + session_path = staticmethod(AssistantServiceClient.session_path) + parse_session_path = staticmethod(AssistantServiceClient.parse_session_path) + template_path = staticmethod(AssistantServiceClient.template_path) + parse_template_path = staticmethod(AssistantServiceClient.parse_template_path) + common_billing_account_path = staticmethod( + AssistantServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AssistantServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(AssistantServiceClient.common_folder_path) + parse_common_folder_path = staticmethod( + AssistantServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + AssistantServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + AssistantServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod(AssistantServiceClient.common_project_path) + parse_common_project_path = staticmethod( + AssistantServiceClient.parse_common_project_path + ) + common_location_path = staticmethod(AssistantServiceClient.common_location_path) + parse_common_location_path = staticmethod( + AssistantServiceClient.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: + AssistantServiceAsyncClient: The constructed client. + """ + sa_info_func = ( + AssistantServiceClient.from_service_account_info.__func__ # type: ignore + ) + return sa_info_func(AssistantServiceAsyncClient, info, *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: + AssistantServiceAsyncClient: The constructed client. + """ + sa_file_func = ( + AssistantServiceClient.from_service_account_file.__func__ # type: ignore + ) + return sa_file_func(AssistantServiceAsyncClient, filename, *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 variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AssistantServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> AssistantServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AssistantServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self) -> str: + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = AssistantServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, AssistantServiceTransport, Callable[..., AssistantServiceTransport] + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the assistant service async 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 (Optional[Union[str,AssistantServiceTransport,Callable[..., AssistantServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AssistantServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "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). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS 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. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + 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. + """ + self._client = AssistantServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.cloud.discoveryengine_v1beta.AssistantServiceAsyncClient`.", + extra={ + "serviceName": "google.cloud.discoveryengine.v1beta.AssistantService", + "universeDomain": getattr( + self._client._transport._credentials, "universe_domain", "" + ), + "credentialsType": f"{type(self._client._transport._credentials).__module__}.{type(self._client._transport._credentials).__qualname__}", + "credentialsInfo": getattr( + self.transport._credentials, "get_cred_info", lambda: None + )(), + } + if hasattr(self._client._transport, "_credentials") + else { + "serviceName": "google.cloud.discoveryengine.v1beta.AssistantService", + "credentialsType": None, + }, + ) + + def stream_assist( + self, + request: Optional[Union[assistant_service.StreamAssistRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> Awaitable[AsyncIterable[assistant_service.StreamAssistResponse]]: + r"""Assists the user with a query in a streaming fashion. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import discoveryengine_v1beta + + async def sample_stream_assist(): + # Create a client + client = discoveryengine_v1beta.AssistantServiceAsyncClient() + + # Initialize request argument(s) + request = discoveryengine_v1beta.StreamAssistRequest( + name="name_value", + ) + + # Make the request + stream = await client.stream_assist(request=request) + + # Handle the response + async for response in stream: + print(response) + + Args: + request (Optional[Union[google.cloud.discoveryengine_v1beta.types.StreamAssistRequest, dict]]): + The request object. Request for the + [AssistantService.StreamAssist][google.cloud.discoveryengine.v1beta.AssistantService.StreamAssist] + method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + AsyncIterable[google.cloud.discoveryengine_v1beta.types.StreamAssistResponse]: + Response for the + [AssistantService.StreamAssist][google.cloud.discoveryengine.v1beta.AssistantService.StreamAssist] + method. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, assistant_service.StreamAssistRequest): + request = assistant_service.StreamAssistRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.stream_assist + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def create_assistant( + self, + request: Optional[Union[assistant_service.CreateAssistantRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> assistant.Assistant: + r"""Creates an + [Assistant][google.cloud.discoveryengine.v1beta.Assistant]. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import discoveryengine_v1beta + + async def sample_create_assistant(): + # Create a client + client = discoveryengine_v1beta.AssistantServiceAsyncClient() + + # Initialize request argument(s) + assistant = discoveryengine_v1beta.Assistant() + assistant.display_name = "display_name_value" + + request = discoveryengine_v1beta.CreateAssistantRequest( + parent="parent_value", + assistant=assistant, + assistant_id="assistant_id_value", + ) + + # Make the request + response = await client.create_assistant(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.discoveryengine_v1beta.types.CreateAssistantRequest, dict]]): + The request object. Request for the + [AssistantService.CreateAssistant][google.cloud.discoveryengine.v1beta.AssistantService.CreateAssistant] + method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.discoveryengine_v1beta.types.Assistant: + Discovery Engine Assistant resource. + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, assistant_service.CreateAssistantRequest): + request = assistant_service.CreateAssistantRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.create_assistant + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_assistant( + self, + request: Optional[Union[assistant_service.DeleteAssistantRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Deletes an + [Assistant][google.cloud.discoveryengine.v1beta.Assistant]. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import discoveryengine_v1beta + + async def sample_delete_assistant(): + # Create a client + client = discoveryengine_v1beta.AssistantServiceAsyncClient() + + # Initialize request argument(s) + request = discoveryengine_v1beta.DeleteAssistantRequest( + name="name_value", + ) + + # Make the request + await client.delete_assistant(request=request) + + Args: + request (Optional[Union[google.cloud.discoveryengine_v1beta.types.DeleteAssistantRequest, dict]]): + The request object. Request message for the + [AssistantService.DeleteAssistant][google.cloud.discoveryengine.v1beta.AssistantService.DeleteAssistant] + method. + name (:class:`str`): + Required. Resource name of + [Assistant][google.cloud.discoveryengine.v1beta.Assistant]. + Format: + ``projects/{project}/locations/{location}/collections/{collection}/engines/{engine}/assistants/{assistant}`` + + If the caller does not have permission to delete the + [Assistant][google.cloud.discoveryengine.v1beta.Assistant], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + If the + [Assistant][google.cloud.discoveryengine.v1beta.Assistant] + to delete 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_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, assistant_service.DeleteAssistantRequest): + request = assistant_service.DeleteAssistantRequest(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._client._transport._wrapped_methods[ + self._client._transport.delete_assistant + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def update_assistant( + self, + request: Optional[Union[assistant_service.UpdateAssistantRequest, dict]] = None, + *, + assistant: Optional[gcd_assistant.Assistant] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> gcd_assistant.Assistant: + r"""Updates an + [Assistant][google.cloud.discoveryengine.v1beta.Assistant] + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import discoveryengine_v1beta + + async def sample_update_assistant(): + # Create a client + client = discoveryengine_v1beta.AssistantServiceAsyncClient() + + # Initialize request argument(s) + assistant = discoveryengine_v1beta.Assistant() + assistant.display_name = "display_name_value" + + request = discoveryengine_v1beta.UpdateAssistantRequest( + assistant=assistant, + ) + + # Make the request + response = await client.update_assistant(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.discoveryengine_v1beta.types.UpdateAssistantRequest, dict]]): + The request object. Request message for the + [AssistantService.UpdateAssistant][google.cloud.discoveryengine.v1beta.AssistantService.UpdateAssistant] + method. + assistant (:class:`google.cloud.discoveryengine_v1beta.types.Assistant`): + Required. The + [Assistant][google.cloud.discoveryengine.v1beta.Assistant] + to update. + + The + [Assistant][google.cloud.discoveryengine.v1beta.Assistant]'s + ``name`` field is used to identify the + [Assistant][google.cloud.discoveryengine.v1beta.Assistant] + to update. Format: + ``projects/{project}/locations/{location}/collections/{collection}/engines/{engine}/assistants/{assistant}`` + + If the caller does not have permission to update the + [Assistant][google.cloud.discoveryengine.v1beta.Assistant], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + If the + [Assistant][google.cloud.discoveryengine.v1beta.Assistant] + to update does not exist, a NOT_FOUND error is returned. + + This corresponds to the ``assistant`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + The list of fields to update. + 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_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.discoveryengine_v1beta.types.Assistant: + Discovery Engine Assistant resource. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [assistant, update_mask] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, assistant_service.UpdateAssistantRequest): + request = assistant_service.UpdateAssistantRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if assistant is not None: + request.assistant = assistant + 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._client._transport._wrapped_methods[ + self._client._transport.update_assistant + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("assistant.name", request.assistant.name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_assistant( + self, + request: Optional[Union[assistant_service.GetAssistantRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> assistant.Assistant: + r"""Gets an + [Assistant][google.cloud.discoveryengine.v1beta.Assistant]. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import discoveryengine_v1beta + + async def sample_get_assistant(): + # Create a client + client = discoveryengine_v1beta.AssistantServiceAsyncClient() + + # Initialize request argument(s) + request = discoveryengine_v1beta.GetAssistantRequest( + name="name_value", + ) + + # Make the request + response = await client.get_assistant(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.discoveryengine_v1beta.types.GetAssistantRequest, dict]]): + The request object. Request message for the + [AssistantService.GetAssistant][google.cloud.discoveryengine.v1beta.AssistantService.GetAssistant] + method. + name (:class:`str`): + Required. Resource name of + [Assistant][google.cloud.discoveryengine.v1beta.Assistant]. + Format: + ``projects/{project}/locations/{location}/collections/{collection}/engines/{engine}/assistants/{assistant}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.discoveryengine_v1beta.types.Assistant: + Discovery Engine Assistant resource. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, assistant_service.GetAssistantRequest): + request = assistant_service.GetAssistantRequest(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._client._transport._wrapped_methods[ + self._client._transport.get_assistant + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_assistants( + self, + request: Optional[Union[assistant_service.ListAssistantsRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListAssistantsAsyncPager: + r"""Lists all + [Assistant][google.cloud.discoveryengine.v1beta.Assistant]s + under an [Engine][google.cloud.discoveryengine.v1beta.Engine]. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import discoveryengine_v1beta + + async def sample_list_assistants(): + # Create a client + client = discoveryengine_v1beta.AssistantServiceAsyncClient() + + # Initialize request argument(s) + request = discoveryengine_v1beta.ListAssistantsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_assistants(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.discoveryengine_v1beta.types.ListAssistantsRequest, dict]]): + The request object. Request message for the + [AssistantService.ListAssistants][google.cloud.discoveryengine.v1beta.AssistantService.ListAssistants] + method. + parent (:class:`str`): + Required. The parent resource name. Format: + ``projects/{project}/locations/{location}/collections/{collection}/engines/{engine}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.discoveryengine_v1beta.services.assistant_service.pagers.ListAssistantsAsyncPager: + Response message for the + [AssistantService.ListAssistants][google.cloud.discoveryengine.v1beta.AssistantService.ListAssistants] + method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, assistant_service.ListAssistantsRequest): + request = assistant_service.ListAssistantsRequest(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._client._transport._wrapped_methods[ + self._client._transport.list_assistants + ] + + # 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),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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.ListAssistantsAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[Union[operations_pb2.ListOperationsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if request is None: + request_pb = operations_pb2.ListOperationsRequest() + elif isinstance(request, dict): + request_pb = operations_pb2.ListOperationsRequest(**request) + else: + request_pb = request + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.list_operations] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request_pb.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request_pb, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[Union[operations_pb2.GetOperationRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if request is None: + request_pb = operations_pb2.GetOperationRequest() + elif isinstance(request, dict): + request_pb = operations_pb2.GetOperationRequest(**request) + else: + request_pb = request + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request_pb.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request_pb, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def cancel_operation( + self, + request: Optional[Union[operations_pb2.CancelOperationRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Starts asynchronous cancellation on a long-running operation. + + The server makes a best effort to cancel the operation, but success + is not guaranteed. If the server doesn't support this method, it returns + `google.rpc.Code.UNIMPLEMENTED`. + + Args: + request (:class:`~.operations_pb2.CancelOperationRequest`): + The request object. Request message for + `CancelOperation` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + None + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if request is None: + request_pb = operations_pb2.CancelOperationRequest() + elif isinstance(request, dict): + request_pb = operations_pb2.CancelOperationRequest(**request) + else: + request_pb = request + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.cancel_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request_pb.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request_pb, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def __aenter__(self) -> "AssistantServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AssistantServiceAsyncClient",) diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/assistant_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/assistant_service/client.py new file mode 100644 index 000000000000..e192f65bff8a --- /dev/null +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/assistant_service/client.py @@ -0,0 +1,1762 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 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 json +import logging as std_logging +import os +import re +import warnings +from collections import OrderedDict +from http import HTTPStatus +from typing import ( + Callable, + Dict, + Iterable, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) + +import google.protobuf +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.discoveryengine_v1beta import gapic_version as package_version + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + +import google.protobuf.field_mask_pb2 as field_mask_pb2 # type: ignore +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore + +from google.cloud.discoveryengine_v1beta.services.assistant_service import pagers +from google.cloud.discoveryengine_v1beta.types import ( + assist_answer, + assistant, + assistant_service, +) +from google.cloud.discoveryengine_v1beta.types import assistant as gcd_assistant + +from .transports.base import DEFAULT_CLIENT_INFO, AssistantServiceTransport +from .transports.grpc import AssistantServiceGrpcTransport +from .transports.grpc_asyncio import AssistantServiceGrpcAsyncIOTransport +from .transports.rest import AssistantServiceRestTransport + + +class AssistantServiceClientMeta(type): + """Metaclass for the AssistantService 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[AssistantServiceTransport]] + _transport_registry["grpc"] = AssistantServiceGrpcTransport + _transport_registry["grpc_asyncio"] = AssistantServiceGrpcAsyncIOTransport + _transport_registry["rest"] = AssistantServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AssistantServiceTransport]: + """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 AssistantServiceClient(metaclass=AssistantServiceClientMeta): + """Service for managing Assistant configuration and assisting + users. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint) -> Optional[str]: + """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: + Optional[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) + if m is None: + # Could not parse api_endpoint; return as-is. + return 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") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "discoveryengine.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "discoveryengine.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @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: + AssistantServiceClient: 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: + AssistantServiceClient: 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) -> AssistantServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AssistantServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def assist_answer_path( + project: str, + location: str, + collection: str, + engine: str, + session: str, + assist_answer: str, + ) -> str: + """Returns a fully-qualified assist_answer string.""" + return "projects/{project}/locations/{location}/collections/{collection}/engines/{engine}/sessions/{session}/assistAnswers/{assist_answer}".format( + project=project, + location=location, + collection=collection, + engine=engine, + session=session, + assist_answer=assist_answer, + ) + + @staticmethod + def parse_assist_answer_path(path: str) -> Dict[str, str]: + """Parses a assist_answer path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/collections/(?P.+?)/engines/(?P.+?)/sessions/(?P.+?)/assistAnswers/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def assistant_path( + project: str, + location: str, + collection: str, + engine: str, + assistant: str, + ) -> str: + """Returns a fully-qualified assistant string.""" + return "projects/{project}/locations/{location}/collections/{collection}/engines/{engine}/assistants/{assistant}".format( + project=project, + location=location, + collection=collection, + engine=engine, + assistant=assistant, + ) + + @staticmethod + def parse_assistant_path(path: str) -> Dict[str, str]: + """Parses a assistant path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/collections/(?P.+?)/engines/(?P.+?)/assistants/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def data_store_path( + project: str, + location: str, + data_store: str, + ) -> str: + """Returns a fully-qualified data_store string.""" + return "projects/{project}/locations/{location}/dataStores/{data_store}".format( + project=project, + location=location, + data_store=data_store, + ) + + @staticmethod + def parse_data_store_path(path: str) -> Dict[str, str]: + """Parses a data_store path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/dataStores/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def document_path( + project: str, + location: str, + data_store: str, + branch: str, + document: str, + ) -> str: + """Returns a fully-qualified document string.""" + return "projects/{project}/locations/{location}/dataStores/{data_store}/branches/{branch}/documents/{document}".format( + project=project, + location=location, + data_store=data_store, + branch=branch, + document=document, + ) + + @staticmethod + def parse_document_path(path: str) -> Dict[str, str]: + """Parses a document path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/dataStores/(?P.+?)/branches/(?P.+?)/documents/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def engine_path( + project: str, + location: str, + collection: str, + engine: str, + ) -> str: + """Returns a fully-qualified engine string.""" + return "projects/{project}/locations/{location}/collections/{collection}/engines/{engine}".format( + project=project, + location=location, + collection=collection, + engine=engine, + ) + + @staticmethod + def parse_engine_path(path: str) -> Dict[str, str]: + """Parses a engine path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/collections/(?P.+?)/engines/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def session_path( + project: str, + location: str, + data_store: str, + session: str, + ) -> str: + """Returns a fully-qualified session string.""" + return "projects/{project}/locations/{location}/dataStores/{data_store}/sessions/{session}".format( + project=project, + location=location, + data_store=data_store, + session=session, + ) + + @staticmethod + def parse_session_path(path: str) -> Dict[str, str]: + """Parses a session path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/dataStores/(?P.+?)/sessions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def template_path( + project: str, + location: str, + template: str, + ) -> str: + """Returns a fully-qualified template string.""" + return "projects/{project}/locations/{location}/templates/{template}".format( + project=project, + location=location, + template=template, + ) + + @staticmethod + def parse_template_path(path: str) -> Dict[str, str]: + """Parses a template path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/templates/(?P